bug-tar
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug-tar] Suggested patch to 1.14. Problem with --listed-incremental and


From: rbrown64
Subject: [Bug-tar] Suggested patch to 1.14. Problem with --listed-incremental and --one-file-system
Date: Tue, 20 Jul 2004 20:06:43 +1000

tar 1.12 and earlier would (incorrectly) keep the listed incremental output
file on error or EOF
writing the tar file. The enclosed patch will write a listed incremental
output file that contains only
those directories completely processed on error or EOF.
We need two DDS tapes for a complete backup. With this varient should be
able to complete a listed
incremental after a tape full on the first tape - which is what I thought
was happening with 1.12 tar.

I had also though that the order of directories on the command line (with
--one-file-system) would reflect
the ordering on the tape. With --listed-incremental --one-file-system
providing a list of mount points starting
with the root directory only backed up the root directory and filesystems
whose mount points weren't on the
root partition. Reversing the order of mount points so that filesystems
preceded the filesystems they were mounted
on backed up everything as expected.

ie
-l / /usr /devel /var/sys /var /var/home /var/home/rdb /var/apps  /var/www
# Only got stuff mounted under /var
-l /usr /devel /var/sys /var/home/rdb /var/home /var/apps  /var/www /var /
#  got everything expected


I think I'm not copyright assigned for tar, though my corporate assignment
should cover it, so
I'd only need to provide a personal one if this is useful.

      2004-07-20  Rodney Brown <address@hidden>

      * common.h (write_directory_file): Add bool argument.
      * create.c (create_archive): Set directory written for the directory
      after all contents are archived for listed incrementals.
      * incremen.c (struct directory): Add written field.
      (set_directory_written): New function.
      (write_written_directory_file_entry): New function.
      (write_directory_file): Add only_written argument, used to choose
      write_written_directory_file_entry.
      * misc.c (write_fatal_details): Call write_directory_file for
      listed incrementals.
--- common.h.orig Mon May 10 21:49:08 2004
+++ common.h      Tue Jul 13 15:08:02 2004
@@ -439,7 +439,7 @@ void delete_archive_members (void);

 char *get_directory_contents (char *, dev_t);
 void read_directory_file (void);
-void write_directory_file (void);
+void write_directory_file (bool);
 void gnu_restore (char const *);

 /* Module list.c.  */
--- create.c.orig Mon Apr 26 19:17:20 2004
+++ create.c      Tue Jul 13 15:08:02 2004
@@ -1093,22 +1093,26 @@ create_archive (void)
            buffer[plen++] = '/';
          q = gnu_list_name->dir_contents;
          if (q)
-           while (*q)
-           {
-             size_t qlen = strlen (q);
-             if (*q == 'Y')
-               {
-                 if (buffer_size < plen + qlen)
-                 {
-                   while ((buffer_size *=2 ) < plen + qlen)
-                     continue;
-                   buffer = xrealloc (buffer, buffer_size);
-                 }
-                 strcpy (buffer + plen, q + 1);
-                 dump_file (buffer, -1, (dev_t) 0);
-               }
-             q += qlen + 1;
-           }
+           {
+           while (*q)
+             {
+               size_t qlen = strlen (q);
+               if (*q == 'Y')
+                 {
+                 if (buffer_size < plen + qlen)
+                   {
+                     while ((buffer_size *=2 ) < plen + qlen)
+                       continue;
+                     buffer = xrealloc (buffer, buffer_size);
+                   }
+                 strcpy (buffer + plen, q + 1);
+                 dump_file (buffer, -1, (dev_t) 0);
+                 }
+               q += qlen + 1;
+             }
+           if (listed_incremental_option)
+             set_directory_written (gnu_list_name->name);
+           }
        }
       free (buffer);
     }
@@ -1123,7 +1127,7 @@ create_archive (void)
   close_archive ();

   if (listed_incremental_option)
-    write_directory_file ();
+    write_directory_file (false);
 }


--- incremen.c.orig     Mon Apr  5 17:23:51 2004
+++ incremen.c    Tue Jul 13 15:08:02 2004
@@ -39,6 +39,7 @@ struct directory
     enum children children;
     bool nfs;
     bool found;
+    bool written;
     char name[1];            /* path name of directory */
   };

@@ -84,6 +85,7 @@ note_directory (char const *name, dev_t
   directory->children = CHANGED_CHILDREN;
   directory->nfs = nfs;
   directory->found = found;
+  directory->written = false;
   strcpy (directory->name, name);

   if (! ((directory_table
@@ -110,6 +112,26 @@ find_directory (char *name)
     }
 }

+/* Set written flag in directory entry for a given path NAME.  */
+void
+set_directory_written (char *name)
+{
+  size_t len = strlen(name);
+  char *search_name = alloca (len + 2);
+  struct directory *directory;
+  int offset = !ISSLASH(name[0]);
+
+  if (offset)
+      search_name[0] = '/';
+  strcpy(search_name + offset, name);
+  offset = strlen(search_name);
+  if (offset && ISSLASH(search_name[offset - 1]))
+    search_name[offset - 1] = 0;
+  directory = find_directory (search_name);
+  if (directory)
+    directory->written = true;
+}
+
 static int
 compare_dirents (const void *first, const void *second)
 {
@@ -434,8 +456,31 @@ write_directory_file_entry (void *entry,
   return ! ferror (fp);
 }

+static bool
+write_written_directory_file_entry (void *entry, void *data)
+{
+  struct directory const *directory = entry;
+  FILE *fp = data;
+
+  if (directory->found && directory->written)
+    {
+      int e;
+      char *str = quote_copy_string (directory->name);
+      fprintf (fp, "+%lu %lu %s\n" + ! directory->nfs,
+            (unsigned long) directory->device_number,
+            (unsigned long) directory->inode_number,
+            str ? str : directory->name);
+      e = errno;
+      if (str)
+     free (str);
+      errno = e;
+    }
+
+  return ! ferror (fp);
+}
+
 void
-write_directory_file (void)
+write_directory_file (bool only_written)
 {
   FILE *fp = listed_incremental_stream;

@@ -449,7 +494,13 @@ write_directory_file (void)

   fprintf (fp, "%lu\n", (unsigned long) start_time);
   if (! ferror (fp) && directory_table)
-    hash_do_for_each (directory_table, write_directory_file_entry, fp);
+    {
+      if (only_written)
+     hash_do_for_each (directory_table, write_written_directory_file_entry,
+                   fp);
+      else
+     hash_do_for_each (directory_table, write_directory_file_entry, fp);
+    }
   if (ferror (fp))
     write_error (listed_incremental_option);
   if (fclose (fp) != 0)
--- misc.c.orig   Mon Apr  5 17:23:51 2004
+++ misc.c  Tue Jul 13 16:32:47 2004
@@ -893,6 +893,8 @@ void
 write_fatal_details (char const *name, ssize_t status, size_t size)
 {
   write_error_details (name, status, size);
+  if (listed_incremental_option)
+     write_directory_file (true);
   fatal_exit ();
 }






reply via email to

[Prev in Thread] Current Thread [Next in Thread]