]> git.wh0rd.org - dump.git/commitdiff
Made dump understand the LABEL= and UUID= notations.
authorStelian Pop <stelian@popies.net>
Sun, 20 Aug 2000 19:41:23 +0000 (19:41 +0000)
committerStelian Pop <stelian@popies.net>
Sun, 20 Aug 2000 19:41:23 +0000 (19:41 +0000)
CHANGES
compat/include/bylabel.h [new file with mode: 0644]
compat/lib/Makefile.in
compat/lib/bylabel.c [new file with mode: 0644]
compat/lib/fstab.c
dump.spec
dump/main.c

diff --git a/CHANGES b/CHANGES
index ae7b4380a6a6217c02870dd0136fbccd0ae0a767..b9db81c8acb2a95f5bed3eef2b183cc587043221 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,4 @@
-$Id: CHANGES,v 1.76 2000/08/20 16:34:00 stelian Exp $
+$Id: CHANGES,v 1.77 2000/08/20 19:41:23 stelian Exp $
 
 Changes between versions 0.4b17 and 0.4b19 (released ?????????????)
 ===================================================================
 
 Changes between versions 0.4b17 and 0.4b19 (released ?????????????)
 ===================================================================
@@ -37,6 +37,12 @@ Changes between versions 0.4b17 and 0.4b19 (released ?????????????)
        before checking for libreadline, because we need this
        library in order to compile the readline support.
 
        before checking for libreadline, because we need this
        library in order to compile the readline support.
 
+9.     Made dump understand the LABEL= and UUID= notation
+       both in /etc/fstab and on the command line. Note that
+       you will need the /proc filesystem in order to use
+       these notations. Thanks to Erik Troan <ewt@redhat.com> 
+       for providing the patch.
+
 Changes between versions 0.4b17 and 0.4b18 (released June 30, 2000)
 ===================================================================
 
 Changes between versions 0.4b17 and 0.4b18 (released June 30, 2000)
 ===================================================================
 
diff --git a/compat/include/bylabel.h b/compat/include/bylabel.h
new file mode 100644 (file)
index 0000000..00ed284
--- /dev/null
@@ -0,0 +1 @@
+const char * get_device_name(const char * item);
index fe6547d78ecce99e58cb713b8a4c61df41d88240..42239c96a767a2d58c6f8259adf2ba410ed0f5e9 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile.in,v 1.3 1999/10/11 13:31:10 stelian Exp $
+# $Id: Makefile.in,v 1.4 2000/08/20 19:41:24 stelian Exp $
 
 top_srcdir=    @top_srcdir@
 srcdir=                @srcdir@
 
 top_srcdir=    @top_srcdir@
 srcdir=                @srcdir@
@@ -7,8 +7,8 @@ srcdir=         @srcdir@
 
 INC=           -I$(top_srcdir)/compat/include
 CFLAGS=                @CCOPTS@ -pipe $(OPT) $(GINC) $(INC) $(DEFS)
 
 INC=           -I$(top_srcdir)/compat/include
 CFLAGS=                @CCOPTS@ -pipe $(OPT) $(GINC) $(INC) $(DEFS)
-SRCS=          compaterr.c fstab.c compatglob.c
-OBJS=          compaterr.o fstab.o compatglob.o
+SRCS=          compaterr.c fstab.c compatglob.c bylabel.c
+OBJS=          compaterr.o fstab.o compatglob.o bylabel.o
 LIB=           libcompat.a
 
 all::          $(LIB)
 LIB=           libcompat.a
 
 all::          $(LIB)
diff --git a/compat/lib/bylabel.c b/compat/lib/bylabel.c
new file mode 100644 (file)
index 0000000..9cdd0e5
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * mount_by_label.c - aeb
+ *
+ * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
+ * - added Native Language Support
+ * 2000-01-20 James Antill <james@and.org>
+ * - Added error message if /proc/partitions cannot be opened
+ * 2000-05-09 Erik Troan <ewt@redhat.com>
+ * - Added cache for UUID and disk labels
+ * Wed Aug 16 2000 Erik Troan <ewt@redhat.com>
+ * - Ported to dump/restore
+ */
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <linux/ext2_fs.h>
+#include <ext2fs/ext2fs.h>
+#include "bylabel.h"
+
+#define PROC_PARTITIONS "/proc/partitions"
+#define DEVLABELDIR    "/dev"
+
+void msg __P((const char *fmt, ...));
+
+static struct uuidCache_s {
+       struct uuidCache_s *next;
+       char uuid[16];
+       char *label;
+       char *device;
+} *uuidCache = NULL;
+
+/* for now, only ext2 is supported */
+static int
+get_label_uuid(const char *device, char **label, char *uuid) {
+
+       /* start with a test for ext2, taken from mount_guess_fstype */
+       /* should merge these later */
+       int fd;
+       struct ext2_super_block e2sb;
+
+       fd = open(device, O_RDONLY);
+       if (fd < 0)
+               return 1;
+
+       if (lseek(fd, 1024, SEEK_SET) != 1024
+           || read(fd, (char *) &e2sb, sizeof(e2sb)) != sizeof(e2sb)
+           || (e2sb.s_magic != EXT2_SUPER_MAGIC)) {
+               close(fd);
+               return 1;
+       }
+
+       close(fd);
+
+       /* superblock is ext2 - now what is its label? */
+       memcpy(uuid, e2sb.s_uuid, sizeof(e2sb.s_uuid));
+       *label = strdup(e2sb.s_volume_name);
+
+       return 0;
+}
+
+static void
+uuidcache_addentry(char *device, char *label, char *uuid) {
+       struct uuidCache_s *last;
+
+       if (!uuidCache) {
+               last = uuidCache = malloc(sizeof(*uuidCache));
+       } else {
+               for (last = uuidCache; last->next; last = last->next) ;
+               last->next = malloc(sizeof(*uuidCache));
+               last = last->next;
+       }
+       last->next = NULL;
+       last->device = device;
+       last->label = label;
+       memcpy(last->uuid, uuid, sizeof(last->uuid));
+}
+
+static void
+uuidcache_init(void) {
+       char line[100];
+       char *s;
+       int ma, mi, sz;
+       static char ptname[100];
+       FILE *procpt;
+       char uuid[16], *label;
+       char device[110];
+       int firstPass;
+       int handleOnFirst;
+
+       if (uuidCache)
+               return;
+
+       procpt = fopen(PROC_PARTITIONS, "r");
+       if (!procpt)
+               return;
+
+       for (firstPass = 1; firstPass >= 0; firstPass--) {
+           fseek(procpt, 0, SEEK_SET);
+
+           while (fgets(line, sizeof(line), procpt)) {
+               if (sscanf (line, " %d %d %d %[^\n ]",
+                           &ma, &mi, &sz, ptname) != 4)
+                       continue;
+
+               /* skip extended partitions (heuristic: size 1) */
+               if (sz == 1)
+                       continue;
+
+               /* look only at md devices on first pass */
+               handleOnFirst = !strncmp(ptname, "md", 2);
+               if (firstPass != handleOnFirst)
+                       continue;
+
+               /* skip entire disk (minor 0, 64, ... on ide;
+                  0, 16, ... on sd) */
+               /* heuristic: partition name ends in a digit */
+
+               for(s = ptname; *s; s++);
+               if (isdigit(s[-1])) {
+               /*
+                * Note: this is a heuristic only - there is no reason
+                * why these devices should live in /dev.
+                * Perhaps this directory should be specifiable by option.
+                * One might for example have /devlabel with links to /dev
+                * for the devices that may be accessed in this way.
+                * (This is useful, if the cdrom on /dev/hdc must not
+                * be accessed.)
+                */
+                       sprintf(device, "%s/%s", DEVLABELDIR, ptname);
+                       if (!get_label_uuid(device, &label, uuid))
+                               uuidcache_addentry(strdup(device), label, uuid);
+               }
+           }
+       }
+
+       fclose(procpt);
+}
+
+#define UUID   1
+#define VOL    2
+
+static char *
+get_spec_by_x(int n, const char *t) {
+       struct uuidCache_s *uc;
+
+       uuidcache_init();
+       uc = uuidCache;
+
+       while(uc) {
+               switch (n) {
+               case UUID:
+                       if (!memcmp(t, uc->uuid, sizeof(uc->uuid)))
+                               return strdup(uc->device);
+                       break;
+               case VOL:
+                       if (!strcmp(t, uc->label))
+                               return strdup(uc->device);
+                       break;
+               }
+               uc = uc->next;
+       }
+       return NULL;
+}
+
+static u_char
+fromhex(char c) {
+       if (isdigit(c))
+               return (c - '0');
+       else if (islower(c))
+               return (c - 'a' + 10);
+       else
+               return (c - 'A' + 10);
+}
+
+static char *
+get_spec_by_uuid(const char *s) {
+       u_char uuid[16];
+       int i;
+
+       if (strlen(s) != 36 ||
+           s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-')
+               goto bad_uuid;
+       for (i=0; i<16; i++) {
+           if (*s == '-') s++;
+           if (!isxdigit(s[0]) || !isxdigit(s[1]))
+                   goto bad_uuid;
+           uuid[i] = ((fromhex(s[0])<<4) | fromhex(s[1]));
+           s += 2;
+       }
+       return get_spec_by_x(UUID, uuid);
+
+ bad_uuid:
+       msg("mount: bad UUID\n");
+       return NULL;            /* just for gcc */
+}
+
+static char *
+get_spec_by_volume_label(const char *s) {
+       return get_spec_by_x(VOL, s);
+}
+
+const char * 
+get_device_name(const char * item) {
+       const char * rc;
+
+       if (!strncmp(item, "UUID=", 5)) {
+               rc = get_spec_by_uuid(item+5);
+       } 
+       else
+               if (!strncmp(item, "LABEL=", 6)) {
+                       rc = get_spec_by_volume_label(item+6);
+               }
+               else {
+                       rc = item;
+               }
+
+       return rc;
+}
index 088645e6d3d0540d7401cf859e2127cea1473793..b3a21f0c66c074d78e87c158cfdb53f40896f0a2 100644 (file)
@@ -40,7 +40,7 @@
 
 #ifndef lint
 static const char rcsid[] =
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: fstab.c,v 1.6 2000/01/21 10:17:41 stelian Exp $";
+       "$Id: fstab.c,v 1.7 2000/08/20 19:41:24 stelian Exp $";
 #endif /* not lint */
 
 #include <errno.h>
 #endif /* not lint */
 
 #include <errno.h>
@@ -50,6 +50,7 @@ static const char rcsid[] =
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <bylabel.h>
 
 static FILE *_fs_fp;
 static struct fstab _fs_fstab;
 
 static FILE *_fs_fp;
 static struct fstab _fs_fstab;
@@ -57,6 +58,8 @@ static struct fstab _fs_fstab;
 static void error __P((int));
 static int fstabscan __P((void));
 
 static void error __P((int));
 static int fstabscan __P((void));
 
+void msg __P((const char *fmt, ...));
+
 static
 int fstabscan(void)
 {
 static
 int fstabscan(void)
 {
@@ -65,12 +68,18 @@ int fstabscan(void)
        int typexx;
 #define        MAXLINELENGTH   1024
        char subline[MAXLINELENGTH];
        int typexx;
 #define        MAXLINELENGTH   1024
        char subline[MAXLINELENGTH];
+       char *device_name;
 
        for (;;) {
                if (!(mnt = getmntent(_fs_fp)))
                        return 0;
 
 
        for (;;) {
                if (!(mnt = getmntent(_fs_fp)))
                        return 0;
 
-               _fs_fstab.fs_spec = mnt->mnt_fsname;
+               device_name = get_device_name(mnt->mnt_fsname);
+               if (!device_name) {
+                       msg("Warning: unable to translate %s\n", mnt->mnt_fsname);
+                       continue;
+               }
+               _fs_fstab.fs_spec = device_name;
                _fs_fstab.fs_file = mnt->mnt_dir;
                _fs_fstab.fs_vfstype = mnt->mnt_type;
                _fs_fstab.fs_mntops = mnt->mnt_opts;
                _fs_fstab.fs_file = mnt->mnt_dir;
                _fs_fstab.fs_vfstype = mnt->mnt_type;
                _fs_fstab.fs_mntops = mnt->mnt_opts;
index c21fa8befbefed1de88989eea5ccab397174a1b3..ea64c22b628eb2f453c17110215fe94bce318821 100644 (file)
--- a/dump.spec
+++ b/dump.spec
@@ -34,7 +34,7 @@ like dump (a filesystem backup program), restore (a program for
 restoring files from a backup) and tar (an archiving program).
 
 %package -n dump-static
 restoring files from a backup) and tar (an archiving program).
 
 %package -n dump-static
-Summary: Programs for backing up and restoring filesystems.
+Summary: Statically linked versions of dump and restore.
 Group: Applications/Archiving
 
 %description -n dump-static
 Group: Applications/Archiving
 
 %description -n dump-static
index c2e4eaf329c94e77e671c50915ec4e027313d792..43c31168f070429dbb8f7a3d7830c15d6ec20e7b 100644 (file)
@@ -40,7 +40,7 @@
 
 #ifndef lint
 static const char rcsid[] =
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: main.c,v 1.23 2000/08/19 23:48:10 stelian Exp $";
+       "$Id: main.c,v 1.24 2000/08/20 19:41:50 stelian Exp $";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -79,6 +79,7 @@ static const char rcsid[] =
 
 #include "dump.h"
 #include "pathnames.h"
 
 #include "dump.h"
 #include "pathnames.h"
+#include "bylabel.h"
 
 #ifndef SBOFF
 #define SBOFF (SBLOCK * DEV_BSIZE)
 
 #ifndef SBOFF
 #define SBOFF (SBLOCK * DEV_BSIZE)
@@ -126,6 +127,7 @@ main(int argc, char *argv[])
 #endif
        time_t tnow;
        char labelstr[LBLSIZE];
 #endif
        time_t tnow;
        char labelstr[LBLSIZE];
+       char *diskparam;
 
        spcl.c_date = 0;
 #ifdef __linux__
 
        spcl.c_date = 0;
 #ifdef __linux__
@@ -287,9 +289,9 @@ main(int argc, char *argv[])
                (void)fprintf(stderr, "Must specify disk or filesystem\n");
                exit(X_STARTUP);
        }
                (void)fprintf(stderr, "Must specify disk or filesystem\n");
                exit(X_STARTUP);
        }
-       disk = *argv++;
-       if (strlen(disk) >= MAXPATHLEN) {
-               (void)fprintf(stderr, "Disk or filesystem name too long: %s\n", disk);
+       diskparam = *argv++;
+       if (strlen(diskparam) >= MAXPATHLEN) {
+               (void)fprintf(stderr, "Disk or filesystem name too long: %s\n", diskparam);
                exit(X_STARTUP);
        }
        argc--;
                exit(X_STARTUP);
        }
        argc--;
@@ -363,6 +365,14 @@ main(int argc, char *argv[])
                signal(SIGINT, SIG_IGN);
        set_operators();        /* /etc/group snarfed */
        getfstab();             /* /etc/fstab snarfed */
                signal(SIGINT, SIG_IGN);
        set_operators();        /* /etc/group snarfed */
        getfstab();             /* /etc/fstab snarfed */
+
+       disk = get_device_name(diskparam);
+       if (!disk) {            /* null means the disk is some form
+                                  of LABEL= or UID= but it was not
+                                  found */
+               msg("Cannot find a disk having %s\n", diskparam);
+               exit(X_STARTUP);
+       }
        /*
         *      disk may end in / and this can confuse
         *      fstabsearch.
        /*
         *      disk may end in / and this can confuse
         *      fstabsearch.
@@ -421,7 +431,6 @@ main(int argc, char *argv[])
                        exit(X_STARTUP);
                }
        }
                        exit(X_STARTUP);
                }
        }
-
        spcl.c_dev[NAMELEN-1]='\0';
        spcl.c_filesys[NAMELEN-1]='\0';
        (void)strncpy(spcl.c_label, labelstr, sizeof(spcl.c_label) - 1);
        spcl.c_dev[NAMELEN-1]='\0';
        spcl.c_filesys[NAMELEN-1]='\0';
        (void)strncpy(spcl.c_label, labelstr, sizeof(spcl.c_label) - 1);