OSDN Git Service

ChangeLog, Makefile.in, base_device.c, base_device.tst, fsck.c, fsck.h:
authorTheodore Ts'o <tytso@mit.edu>
Sun, 3 Dec 2000 06:33:56 +0000 (06:33 +0000)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 3 Dec 2000 06:33:56 +0000 (06:33 +0000)
  fsck.c (device_already_active): Change to use new version of
   base_device() which now returns dynamically allocated memory.
  base_device.c (base_device): New version moved from fsck.c which now
   understands ugly devfs names.  (Debian bug #65181)
  base_device.tst: Test case for base_device.c

misc/ChangeLog
misc/Makefile.in
misc/base_device.c [new file with mode: 0644]
misc/base_device.tst [new file with mode: 0644]
misc/fsck.c
misc/fsck.h

index a51329a..dcdaaca 100644 (file)
@@ -1,3 +1,14 @@
+2000-12-03    <tytso@snap.thunk.org>
+
+       * fsck.c (device_already_active): Change to use new version of
+               base_device() which now returns dynamically allocated
+               memory.
+
+       * base_device.c (base_device): New version moved from fsck.c which
+               now understands ugly devfs names.  (Debian bug #65181)
+
+       * base_device.tst: Test case for base_device.c
+
 2000-12-02    <tytso@snap.thunk.org>
 
        * fsck.8.in: Add clarification that filesystems with a fs_passno
index a4d0e44..e9897a3 100644 (file)
@@ -29,7 +29,7 @@ DUMPE2FS_OBJS=        dumpe2fs.o
 BADBLOCKS_OBJS=        badblocks.o
 E2LABEL_OBJS=  e2label.o
 E2IMAGE_OBJS=  e2image.o
-FSCK_OBJS=     fsck.o get_device_by_label.o
+FSCK_OBJS=     fsck.o get_device_by_label.o base_device.o
 
 SRCS=  $(srcdir)/tune2fs.c $(srcdir)/mklost+found.c $(srcdir)/mke2fs.c \
                $(srcdir)/chattr.c $(srcdir)/lsattr.c $(srcdir)/dumpe2fs.c \
@@ -61,6 +61,13 @@ e2label: $(E2LABEL_OBJS)
 e2image: $(E2IMAGE_OBJS) $(DEPLIBS)
        $(CC) $(ALL_LDFLAGS) -o e2image $(E2IMAGE_OBJS) $(LIBS)
 
+base_device: base_device.c
+       $(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) $< -DDEBUG -o $@
+
+check:: base_device
+       ./base_device < $(srcdir)/base_device.tst > base_device.out
+       cmp $(srcdir)/base_device.tst base_device.out
+
 mklost+found: $(MKLPF_OBJS)
        $(CC) $(ALL_LDFLAGS) -o mklost+found $(MKLPF_OBJS)
 
@@ -169,7 +176,8 @@ uninstall:
 
 clean:
        $(RM) -f $(SPROGS) $(USPROGS) $(UPROGS) $(UMANPAGES) $(SMANPAGES) \
-               mke2fs.static \#* *.s *.o *.a *~ core
+               base_device base_device.out mke2fs.static \
+               \#* *.s *.o *.a *~ core 
 
 mostlyclean: clean
 distclean: clean
diff --git a/misc/base_device.c b/misc/base_device.c
new file mode 100644 (file)
index 0000000..03008cb
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * base_device.c
+ *
+ * Return the "base device" given a particular device; this is used to
+ * assure that we only fsck one partition on a particular drive at any
+ * one time.  Otherwise, the disk heads will be seeking all over the
+ * place.  If the base device can not be determined, return NULL.
+ * 
+ * The base_device() function returns an allocated string which must
+ * be freed.
+ * 
+ * Written by Theodore Ts'o, <tytso@mit.edu>
+ * 
+ * Copyright (C) 2000 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+#include <stdio.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <ctype.h>
+#include <string.h>
+
+#include "fsck.h"
+
+/*
+ * Required for the uber-silly devfs /dev/ide/host1/bus2/target3/lun3
+ * pathames.
+ */
+static const char *devfs_hier[] = {
+       "host", "bus", "target", "lun", 0
+};
+
+char *base_device(char *device)
+{
+       char *str, *cp;
+       const char **hier, *disk;
+       int len;
+
+       str = malloc(strlen(device)+1);
+       if (!str)
+               return NULL;
+       strcpy(str, device);
+       cp = str;
+
+       /* Skip over /dev/; if it's not present, give up. */
+       if (strncmp(cp, "/dev/", 5) != 0)
+               goto errout;
+       cp += 5;
+
+       /* Skip over /dev/dsk/... */
+       if (strncmp(cp, "dsk/", 4) == 0)
+               cp += 4;
+       
+       /*
+        * For md devices, we treat them all as if they were all
+        * on one disk, since we don't know how to parallelize them.
+        */
+       if (cp[0] == 'm' && cp[1] == 'd') {
+               *(cp+2) = 0;
+               return str;
+       }
+
+       /* Now let's handle /dev/hd* and /dev/sd* devices.... */
+       if ((cp[0] == 'h' || cp[0] == 's') && (cp[1] == 'd')) {
+               cp += 2;
+               /* If there's a single number after /dev/hd, skip it */
+               if (isdigit(*cp))
+                       cp++;
+               /* What follows must be an alpha char, or give up */
+               if (!isalpha(*cp))
+                       goto errout;
+               *(cp + 1) = 0;
+               return str;
+       }
+
+       /* Now let's handle devfs (ugh) names */
+       len = 0;
+       if (strncmp(cp, "ide/", 4) == 0)
+               len = 4;
+       if (strncmp(cp, "scsi/", 5) == 0)
+               len = 5;
+       if (len) {
+               cp += len;
+               /*
+                * Now we proceed down the expected devfs hierarchy.
+                * i.e., .../host1/bus2/target3/lun4/...
+                * If we don't find the expected token, followed by
+                * some number of digits at each level, abort.
+                */
+               for (hier = devfs_hier; *hier; hier++) {
+                       len = strlen(*hier);
+                       if (strncmp(cp, *hier, len) != 0)
+                               goto errout;
+                       cp += len;
+                       while (*cp != '/' && *cp != 0) {
+                               if (!isdigit(*cp))
+                                       goto errout;
+                               cp++;
+                       }
+                       cp++;
+               }
+               *(cp - 1) = 0;
+               return str;
+       }
+
+       /* Now handle devfs /dev/disc or /dev/disk names */
+       disk = 0;
+       if (strncmp(cp, "discs/", 6) == 0)
+               disk = "disc";
+       else if (strncmp(cp, "disks/", 6) == 0)
+               disk = "disk";
+       if (disk) {
+               cp += 6;
+               if (strncmp(cp, disk, 4) != 0)
+                       goto errout;
+               cp += 4;
+               while (*cp != '/' && *cp != 0) {
+                       if (!isdigit(*cp))
+                               goto errout;
+                       cp++;
+               }
+               *cp = 0;
+               return str;
+       }
+
+errout:
+       free(str);
+       return NULL;
+}
+
+#ifdef DEBUG
+
+main(int argc, char** argv)
+{
+       const char *base;
+       char  buf[256], *cp;
+
+       while (1) {
+               if (fgets(buf, sizeof(buf), stdin) == NULL)
+                       break;
+               cp = strchr(buf, '\n');
+               if (cp)
+                       *cp = 0;
+               cp = strchr(buf, '\t');
+               if (cp)
+                       *cp = 0;
+               base = base_device(buf);
+               printf("%s\t%s\n", buf, base ? base : "NONE");
+       }
+       exit(0);
+}
+
+#endif
diff --git a/misc/base_device.tst b/misc/base_device.tst
new file mode 100644 (file)
index 0000000..609a58d
--- /dev/null
@@ -0,0 +1,16 @@
+/dev/hda7      /dev/hda
+/dev/sda1      /dev/sda
+/dev/hda       /dev/hda
+/dev/sda       /dev/sda
+/dev/dsk/hda6  /dev/dsk/hda
+/dev/dsk/sda5  /dev/dsk/sda
+/dev/md4       /dev/md
+/dev/md/4      /dev/md
+/dev/ide/host0/bus1/target2/lun3       /dev/ide/host0/bus1/target2/lun3
+/dev/ide/host0/bus1/target2/lun3/part10        /dev/ide/host0/bus1/target2/lun3
+/dev/ide/host0/bus1/target2/lun3/      /dev/ide/host0/bus1/target2/lun3
+/dev/disks/disk2/part2 /dev/disks/disk2
+/dev/disks/disk2/      /dev/disks/disk2
+/dev/disks/disk2       /dev/disks/disk2
+/dev/discs/disc1/part10        /dev/discs/disc1
+/dev/discs/disc1/      /dev/discs/disc1
index 95a58d8..8fc4610 100644 (file)
@@ -79,55 +79,7 @@ static const char *really_wanted[] = {
        NULL
 };
 
-#ifdef DEV_DSK_DEVICES
-static const char *base_devices[] = {
-       "/dev/dsk/hda",
-       "/dev/dsk/hdb",
-       "/dev/dsk/hdc",
-       "/dev/dsk/hdd",
-       "/dev/dsk/hde",
-       "/dev/dsk/hdf",
-       "/dev/dsk/hdg",
-       "/dev/dsk/hdh",
-       "/dev/dsk/hd1a",
-       "/dev/dsk/hd1b",
-       "/dev/dsk/hd1c",
-       "/dev/dsk/hd1d",
-       "/dev/dsk/sda",
-       "/dev/dsk/sdb",
-       "/dev/dsk/sdc",
-       "/dev/dsk/sdd",
-       "/dev/dsk/sde",
-       "/dev/dsk/sdf",
-       "/dev/dsk/sdg",
-       NULL
-};
-#else
 #define BASE_MD "/dev/md"
-static const char *base_devices[] = {
-       "/dev/hda",
-       "/dev/hdb",
-       "/dev/hdc",
-       "/dev/hdd",
-       "/dev/hde",
-       "/dev/hdf",
-       "/dev/hdg",
-       "/dev/hdh",
-       "/dev/hd1a",
-       "/dev/hd1b",
-       "/dev/hd1c",
-       "/dev/hd1d",
-       "/dev/sda",
-       "/dev/sdb",
-       "/dev/sdc",
-       "/dev/sdd",
-       "/dev/sde",
-       "/dev/sdf",
-       "/dev/sdg",
-       BASE_MD,
-       NULL
-};
-#endif
 
 /*
  * Global variables for options
@@ -213,6 +165,8 @@ static void free_instance(struct fsck_instance *i)
                free(i->prog);
        if (i->device)
                free(i->device);
+       if (i->base_device)
+               free(i->base_device);
        free(i);
        return;
 }
@@ -486,6 +440,7 @@ static int execute(const char *type, char *device, char *mntpt,
        inst->prog = string_copy(prog);
        inst->type = string_copy(type);
        inst->device = string_copy(device);
+       inst->base_device = base_device(device);
        inst->start_time = time(0);
        inst->next = NULL;
 
@@ -723,30 +678,13 @@ static int ignore(struct fs_info *fs)
 }
 
 /*
- * Return the "base device" given a particular device; this is used to
- * assure that we only fsck one partition on a particular drive at any
- * one time.  Otherwise, the disk heads will be seeking all over the
- * place.
- */
-static const char *base_device(char *device)
-{
-       const char **base;
-
-       for (base = base_devices; *base; base++) {
-               if (!strncmp(*base, device, strlen(*base)))
-                       return *base;
-       }
-       return device;
-}
-
-/*
  * Returns TRUE if a partition on the same disk is already being
  * checked.
  */
 static int device_already_active(char *device)
 {
        struct fsck_instance *inst;
-       const char *base = base_device(device);
+       char *base;
 
        if (force_all_parallel)
                return 0;
@@ -759,10 +697,14 @@ static int device_already_active(char *device)
                return 1;
 #endif
 
+       base = base_device(device);
        for (inst = instance_list; inst; inst = inst->next) {
-               if (!strcmp(base, base_device(inst->device)))
+               if (!strcmp(base, inst->base_device)) {
+                       free(base);
                        return 1;
+               }
        }
+       free(base);
        return 0;
 }
 
index 693f9ef..9fdbce4 100644 (file)
@@ -53,8 +53,9 @@ struct fsck_instance {
        char *  prog;
        char *  type;
        char *  device;
+       char *  base_device;
        struct fsck_instance *next;
 };
 
-
+extern char *base_device(char *device);