]> git.wh0rd.org - dump.git/commitdiff
Multifile option to dump.
authorStelian Pop <stelian@popies.net>
Tue, 10 Apr 2001 13:42:21 +0000 (13:42 +0000)
committerStelian Pop <stelian@popies.net>
Tue, 10 Apr 2001 13:42:21 +0000 (13:42 +0000)
CHANGES
TODO
dump/dump.8.in
dump/dump.h
dump/main.c
dump/traverse.c

diff --git a/CHANGES b/CHANGES
index 01d6b6736ebe5e707f5626fea8f7abd632266873..06f3d98d2a3a9f7675e5c0c021ee468f3d9749a8 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,4 @@
-$Id: CHANGES,v 1.109 2001/04/10 12:46:53 stelian Exp $
+$Id: CHANGES,v 1.110 2001/04/10 13:42:21 stelian Exp $
 
 Changes between versions 0.4b21 and 0.4b22 (released ????????????????)
 ======================================================================
@@ -42,6 +42,10 @@ Changes between versions 0.4b21 and 0.4b22 (released ????????????????)
        large backups, saves the tapes and the drive's head. Use
        --enable-qfa option of configure to compile in the QFA support.
 
+8.     Added the possibility to dump several files and directories
+       in a single invocation of dump. Thanks to Uwe Gohlke 
+       <uwe@ugsoft.de> for implementing this option.
+
 Changes between versions 0.4b20 and 0.4b21 (released January 13, 2001)
 ======================================================================
 
diff --git a/TODO b/TODO
index f39c442fe8d65a15db0e4820620bfd8a0ac1ab39..bddf3c9402e65f4f24f2f6d3dc62f8880cae6848 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-$Id: TODO,v 1.17 2001/02/16 14:16:54 stelian Exp $
+$Id: TODO,v 1.18 2001/04/10 13:42:21 stelian Exp $
 
 Need to verify:
 ---------------
@@ -13,45 +13,39 @@ Urgent items (for the next stable version):
 All others:
 -----------
 
-1.     Make dump able to backup several directories and/or files in one
-       invocation, like the SunOS version.
+1.     More documentation? Examples, crontab?
 
-2.     More documentation? Examples, crontab?
-
-3.     Explore and correct dump problems on active filesystems 
+2.     Explore and correct dump problems on active filesystems 
        (lseek/read negative count) (This should be OK as of 0.4b14.
        Unfortunately, this seems to continue for a very few users).
 
-4.     Reimplement the ext2 specific code in a "backend" and
+3.     Reimplement the ext2 specific code in a "backend" and
        make the dump code more generic. This would allow creation
        of other backends for other filesystems. Implementing a 
        (v)fat backend should be quite easy, as for BSD ffs (we
        already have the code for this). The BSD code in traverse.c
        (all those #ifdef _BSD) should go into the ffs backend.
 
-5.     Implement a DEBUG option which doesn't fork on each tape, making
+4.     Implement a DEBUG option which doesn't fork on each tape, making
        it able to debug dump with gdb.
 
-6.     Add a compression mode using zlib on each file (see
-       http://www.cdrom.com/pub/infozip/zlib).
+5.     Extend the compression patch to use bzip2.
 
-7.     Make a bootable dump tape? I don't know if it is possible...
+6.     Make a bootable dump tape? I don't know if it is possible...
 
-8.     From Kjetil Torgrim Homme <kjetilho@ifi.uio.no>:
+7.     From Kjetil Torgrim Homme <kjetilho@ifi.uio.no>:
          a archive_file
             Archive file. Archive a dump table-of-contents  in
             the   specified   archive_file   to   be  used  by
             ufsrestore(1M) to determine whether a file  is  in
             the dump file that is being restored.
 
-9.     Modify (or get rid of) rmt in order to work with non Linux
+8.     Modify (or get rid of) rmt in order to work with non Linux
        systems (limited succes has been reported). A good version 
        of rmt to be looked at is part of star 
        http://www.fokus.gmd.de/research/cc/glone/employees/joerg.schilling/private/star.html
 
-10.    Rework the makefiles, actually --prefix doesn't work in
-       configure. Maybe use automake in the same step ?
-
-11.    EA/ACL support in dump (requested by Michael Ju. Tokarev 
+9.     EA/ACL support in dump (requested by Michael Ju. Tokarev 
        <mjt@tls.msk.ru>.
 
+10.    Better readline completition in restore (escape spaces etc).
index e16204696be9b56b3435ea5f929f62d6db6ad372..5d16fc77d53182fc3d6152c1b85cea63ecf0ecce 100644 (file)
@@ -30,7 +30,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\"    $Id: dump.8.in,v 1.25 2001/04/10 12:46:53 stelian Exp $
+.\"    $Id: dump.8.in,v 1.26 2001/04/10 13:42:22 stelian Exp $
 .\"
 .Dd __DATE__
 .Dt DUMP 8
@@ -53,7 +53,7 @@
 .Op Fl s Ar feet
 .Op Fl T Ar date
 .Op Fl z Ar compression level
-.Ar file-to-dump
+.Ar files-to-dump
 .Nm dump
 .Op Fl W Li \&| Fl w
 .Pp
@@ -84,15 +84,17 @@ tape size, density and/or block count options below.
 By default, the same output file name is used for each volume
 after prompting the operator to change media.
 .Pp
-.Ar file-to-dump
+.Ar files-to-dump
 is either a mountpoint of a filesystem
-or a directory to be backed up as a subset of a filesystem.
+or a list of files and directories to be backed up as a subset of a 
+filesystem.
 In the former case, either the path to a mounted filesystem
 or the device of an unmounted filesystem can be used.
 In the latter case, certain restrictions are placed on the backup:
 .Fl u
-is not allowed and the only dump level that is supported is
-.Fl 0 .
+is not allowed, the only dump level that is supported is
+.Fl 0 
+and all the files and directories must reside on the same filesystem.
 .Pp
 The following options are supported by
 .Nm Ns :
index 8235858b0bc916b4ee03dbecb9c91a84381d2abe..b43beb7191ad47f94125535e2b73023d46e11f9b 100644 (file)
@@ -5,7 +5,7 @@
  *     Stelian Pop <pop@noos.fr>, 1999-2000
  *     Stelian Pop <pop@noos.fr> - AlcĂ´ve <www.alcove.fr>, 2000
  *
- *     $Id: dump.h,v 1.23 2001/04/10 12:46:53 stelian Exp $
+ *     $Id: dump.h,v 1.24 2001/04/10 13:42:22 stelian Exp $
  */
 
 /*-
@@ -141,6 +141,7 @@ long        blockest __P((struct dinode const *dp));
 int    mapfiles __P((dump_ino_t maxino, long *tapesize));
 #ifdef __linux__
 int    mapfilesfromdir __P((dump_ino_t maxino, long *tapesize, char *directory));
+int    maponefile __P((dump_ino_t maxino, long *tapesize, char *directory));
 #endif
 int    mapdirs __P((dump_ino_t maxino, long *tapesize));
 
index 272d5978a29bd7adc631f902195f0fb8467e91cc..3f114c9e921ada33c97ab6ab10f1685f46abb649 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: main.c,v 1.42 2001/04/10 12:46:53 stelian Exp $";
+       "$Id: main.c,v 1.43 2001/04/10 13:42:22 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -124,6 +124,8 @@ main(int argc, char *argv[])
        register int ch;
        int i, anydirskipped, bflag = 0, Tflag = 0, honorlevel = 1;
        dump_ino_t maxino;
+       struct stat statbuf;
+       dev_t filedev;
 #ifdef __linux__
        errcode_t retval;
        char directory[MAXPATHLEN];
@@ -197,6 +199,7 @@ main(int argc, char *argv[])
                        if (ntrec > maxbsize/1024) {
                                msg("Please choose a blocksize <= %dkB\n",
                                        maxbsize/1024);
+                               msg("The ENTIRE dump is aborted.\n");
                                exit(X_STARTUP);
                        }
                        bflag = 1;
@@ -217,12 +220,14 @@ main(int argc, char *argv[])
                                        /* 04-Feb-00 ILC */
                case 'e':               /* exclude an inode */
                        if (iexclude_num == IEXCLUDE_MAXNUM) {
-                               (void)fprintf(stderr, "Too many -e options\n");
+                               msg("Too many -e options\n");
+                               msg("The ENTIRE dump is aborted.\n");
                                exit(X_STARTUP);
                        }
                        iexclude_list[iexclude_num++] = numarg("inode to exclude",0L,0L);
                        if (iexclude_list[iexclude_num-1] <= ROOTINO) {
-                               (void)fprintf(stderr, "Cannot exclude inode %ld\n", (long)iexclude_list[iexclude_num-1]);
+                               msg("Cannot exclude inode %ld\n", (long)iexclude_list[iexclude_num-1]);
+                               msg("The ENTIRE dump is aborted.\n");
                                exit(X_STARTUP);
                        }
                        msg("Added %d to exclude list\n",
@@ -291,8 +296,8 @@ main(int argc, char *argv[])
                case 'T':               /* time of last dump */
                        spcl.c_ddate = unctime(optarg);
                        if (spcl.c_ddate < 0) {
-                               (void)fprintf(stderr, "bad time \"%s\"\n",
-                                   optarg);
+                               msg("bad time \"%s\"\n", optarg);
+                               msg("The ENTIRE dump is aborted.\n");
                                exit(X_STARTUP);
                        }
                        Tflag = 1;
@@ -322,26 +327,20 @@ main(int argc, char *argv[])
        argv += optind;
 
        if (argc < 1) {
-               (void)fprintf(stderr, "Must specify disk or filesystem\n");
+               msg("Must specify disk or filesystem\n");
+               msg("The ENTIRE dump is aborted.\n");
                exit(X_STARTUP);
        }
        diskparam = *argv++;
        if (strlen(diskparam) >= MAXPATHLEN) {
-               (void)fprintf(stderr, "Disk or filesystem name too long: %s\n", 
-                             diskparam);
+               msg("Disk or filesystem name too long: %s\n", diskparam);
+               msg("The ENTIRE dump is aborted.\n");
                exit(X_STARTUP);
        }
        argc--;
-       if (argc >= 1) {
-               (void)fprintf(stderr, "Unknown arguments to dump:");
-               while (argc--)
-                       (void)fprintf(stderr, " %s", *argv++);
-               (void)fprintf(stderr, "\n");
-               exit(X_STARTUP);
-       }
        if (Tflag && uflag) {
-               (void)fprintf(stderr,
-                   "You cannot use the T and u flags together.\n");
+               msg("You cannot use the T and u flags together.\n");
+               msg("The ENTIRE dump is aborted.\n");
                exit(X_STARTUP);
        }
        if (strcmp(tapeprefix, "-") == 0) {
@@ -374,13 +373,15 @@ main(int argc, char *argv[])
                *tapeprefix++ = '\0';
 #ifdef RDUMP
                if (index(tapeprefix, '\n')) {
-                   (void)fprintf(stderr, "invalid characters in tape\n");
-                   exit(X_STARTUP);
+                       msg("invalid characters in tape\n");
+                       msg("The ENTIRE dump is aborted.\n");
+                       exit(X_STARTUP);
                }
                if (rmthost(host) == 0)
                        exit(X_STARTUP);
 #else
-               (void)fprintf(stderr, "remote dump not enabled\n");
+               msg("remote dump not enabled\n");
+               msg("The ENTIRE dump is aborted.\n");
                exit(X_STARTUP);
 #endif
        }
@@ -416,6 +417,7 @@ main(int argc, char *argv[])
                                   of LABEL= or UID= but it was not
                                   found */
                msg("Cannot find a disk having %s\n", diskparam);
+               msg("The ENTIRE dump is aborted.\n");
                exit(X_STARTUP);
        }
        /*
@@ -425,6 +427,16 @@ main(int argc, char *argv[])
         *      the file system name with or without the leading '/'.
         */
        if ((dt = fstabsearch(disk)) != NULL) {
+               /* if found then only one parameter (i.e. partition)
+                * is allowed */
+               if (argc >= 1) {
+                       (void)fprintf(stderr, "Unknown arguments to dump:");
+                       while (argc--)
+                               (void)fprintf(stderr, " %s", *argv++);
+                       (void)fprintf(stderr, "\n");
+                       msg("The ENTIRE dump is aborted.\n");
+                       exit(X_STARTUP);
+               }
                disk = rawname(dt->fs_spec);
                (void)strncpy(spcl.c_dev, dt->fs_spec, NAMELEN);
                (void)strncpy(spcl.c_filesys, dt->fs_file, NAMELEN);
@@ -470,11 +482,13 @@ main(int argc, char *argv[])
 
        if (directory[0] != 0) {
                if (level != '0') {
-                       (void)fprintf(stderr, "Only level 0 dumps are allowed on a subdirectory\n");
+                       msg("Only level 0 dumps are allowed on a subdirectory\n");
+                       msg("The ENTIRE dump is aborted.\n");
                        exit(X_STARTUP);
                }
                if (uflag) {
-                       (void)fprintf(stderr, "You can't update the dumpdates file when dumping a subdirectory\n");
+                       msg("You can't update the dumpdates file when dumping a subdirectory\n");
+                       msg("The ENTIRE dump is aborted.\n");
                        exit(X_STARTUP);
                }
        }
@@ -519,16 +533,19 @@ main(int argc, char *argv[])
        if (retval) {
                com_err(disk, retval, "while opening filesystem");
                if (retval == EXT2_ET_REV_TOO_HIGH)
-                       printf ("Get a newer version of dump!\n");
+                       msg("Get a newer version of dump!\n");
+               msg("The ENTIRE dump is aborted.\n");
                exit(X_STARTUP);
        }
        if (fs->super->s_rev_level > DUMP_CURRENT_REV) {
                com_err(disk, retval, "while opening filesystem");
-               printf ("Get a newer version of dump!\n");
+               msg("Get a newer version of dump!\n");
+               msg("The ENTIRE dump is aborted.\n");
                exit(X_STARTUP);
        }
        if ((diskfd = open(disk, O_RDONLY)) < 0) {
                msg("Cannot open %s\n", disk);
+               msg("The ENTIRE dump is aborted.\n");
                exit(X_STARTUP);
        }
        /* if no user label specified, use ext2 filesystem label if available */
@@ -556,6 +573,7 @@ main(int argc, char *argv[])
 #else  /* __linux __*/
        if ((diskfd = open(disk, O_RDONLY)) < 0) {
                msg("Cannot open %s\n", disk);
+               msg("The ENTIRE dump is aborted.\n");
                exit(X_STARTUP);
        }
        sync();
@@ -600,8 +618,51 @@ main(int argc, char *argv[])
 #ifdef __linux__
        if (directory[0] == 0)
                anydirskipped = mapfiles(maxino, &tapesize);
-       else
-               anydirskipped = mapfilesfromdir(maxino, &tapesize, directory);
+       else {
+               if (stat(pathname, &statbuf) == -1) {
+                       msg("File cannot be accessed (%s).\n", pathname);
+                       msg("The ENTIRE dump is aborted.\n");
+                       exit(X_STARTUP);
+               }
+               filedev = statbuf.st_dev;
+               if (!(statbuf.st_mode & S_IFDIR))       /* is a file */
+                       anydirskipped = maponefile(maxino, &tapesize, 
+                                                  directory);
+               else
+                       anydirskipped = mapfilesfromdir(maxino, &tapesize, 
+                                                       directory);
+       }
+       while (argc--) {
+               int anydirskipped2;
+               char *p = *argv;
+               /* check if file is available */
+               if (stat(p, &statbuf) == -1) {
+                       msg("File cannot be accessed (%s).\n", p);
+                       msg("The ENTIRE dump is aborted.\n");
+                       exit(X_STARTUP);
+               }
+               /* check if file is on same unix partiton as the first 
+                * argument */
+               if (statbuf.st_dev != filedev) {
+                       msg("Files are not on same file system (%s).\n", p);
+                       msg("The ENTIRE dump is aborted.\n");
+                       exit(X_STARTUP);
+               }
+               /* check if file is a directory */
+               if (!(statbuf.st_mode & S_IFDIR))
+                       anydirskipped2 = maponefile(maxino, &tapesize, 
+                                                   p+strlen(dt->fs_file));
+               else
+                       /* read directory inodes.
+                        * NOTE: nested directories are not recognized 
+                        * so inodes may be umped twice!
+                        */
+                       anydirskipped2 = mapfilesfromdir(maxino, &tapesize, 
+                                                        p+strlen(dt->fs_file));
+               if (!anydirskipped)
+                       anydirskipped = anydirskipped2;
+               argv++;
+       }               
 #else
        anydirskipped = mapfiles(maxino, &tapesize);
 #endif
index c4e1e9ab0dde48fe1ab28bb3d7aa1dfd46f3b47b..0ea5b96f7b355255844bc5f85672543ed2c25f15 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: traverse.c,v 1.31 2001/03/28 12:59:48 stelian Exp $";
+       "$Id: traverse.c,v 1.32 2001/04/10 13:42:22 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -369,6 +369,54 @@ mapfiles(dump_ino_t maxino, long *tapesize)
 }
 #endif /* __linux__ */
 
+#ifdef __linux__
+int
+maponefile(dump_ino_t maxino, long *tapesize, char *directory)
+{
+       errcode_t retval;
+       ext2_ino_t dir_ino;
+       char dir_name [MAXPATHLEN];
+       int i, anydirskipped = 0;
+
+       /*
+        * Mark every directory in the path as being dumped
+        */
+       for (i = 0; i < strlen (directory); i++) {
+               if (directory[i] == '/') {
+                       strncpy (dir_name, directory, i);
+                       dir_name[i] = '\0';
+                       retval = ext2fs_namei(fs, ROOTINO, ROOTINO, 
+                                             dir_name, &dir_ino);
+                       if (retval) {
+                               com_err(disk, retval, 
+                                       "while translating %s", dir_name);
+                               exit(X_ABORT);
+                       }
+                       mapfileino((dump_ino_t) dir_ino, 0,
+                                  tapesize, &anydirskipped);
+               }
+       }
+       /*
+        * Mark the final directory
+        */
+       retval = ext2fs_namei(fs, ROOTINO, ROOTINO, directory, &dir_ino);
+       if (retval) {
+               com_err(disk, retval, "while translating %s", directory);
+               exit(X_ABORT);
+       }
+       mapfileino((dump_ino_t)dir_ino, 0, tapesize, &anydirskipped);
+
+       mapfileino(ROOTINO, 0, tapesize, &anydirskipped);
+
+       /*
+        * Restore gets very upset if the root is not dumped,
+        * so ensure that it always is dumped.
+        */
+       SETINO(ROOTINO, dumpdirmap);
+       return anydirskipped;
+}
+#endif /* __linux__ */
+
 #ifdef __linux__
 struct mapfile_context {
        long *tapesize;