]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
sfdisk: add --verify
authorKarel Zak <kzak@redhat.com>
Thu, 11 Sep 2014 13:28:15 +0000 (15:28 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 7 Oct 2014 12:55:31 +0000 (14:55 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
disk-utils/fdisk-list.c
disk-utils/fdisk-list.h
disk-utils/fdisk.c
disk-utils/sfdisk.c

index 3d26f8b7a6196af317f7b1636412ec7449ed11f3..708e6939a94678f4f5eb81a551488258052f66e2 100644 (file)
@@ -220,7 +220,7 @@ char *next_proc_partition(FILE **f)
        return NULL;
 }
 
-int print_device_pt(struct fdisk_context *cxt, char *device, int warnme)
+int print_device_pt(struct fdisk_context *cxt, char *device, int warnme, int verify)
 {
        if (fdisk_assign_device(cxt, device, 1) != 0) { /* read-only */
                if (warnme || errno == EACCES)
@@ -230,14 +230,16 @@ int print_device_pt(struct fdisk_context *cxt, char *device, int warnme)
 
        list_disk_geometry(cxt);
 
-       if (fdisk_has_label(cxt))
+       if (fdisk_has_label(cxt)) {
                list_disklabel(cxt);
-
+               if (verify)
+                       fdisk_verify_disklabel(cxt);
+       }
        fdisk_deassign_device(cxt, 1);
        return 0;
 }
 
-void print_all_devices_pt(struct fdisk_context *cxt)
+void print_all_devices_pt(struct fdisk_context *cxt, int verify)
 {
        FILE *f = NULL;
        int ct = 0;
@@ -246,7 +248,7 @@ void print_all_devices_pt(struct fdisk_context *cxt)
        while ((dev = next_proc_partition(&f))) {
                if (ct)
                        fputs("\n\n", stdout);
-               if (print_device_pt(cxt, dev, 0) == 0)
+               if (print_device_pt(cxt, dev, 0, verify) == 0)
                        ct++;
                free(dev);
        }
index dc61c587106dc45717d4edd69aac9ab9d985919c..0a6ff734c91ab981bb8a9fb06d129bebecec47a2 100644 (file)
@@ -5,7 +5,7 @@ extern void list_disklabel(struct fdisk_context *cxt);
 extern void list_disk_geometry(struct fdisk_context *cxt);
 
 extern char *next_proc_partition(FILE **f);
-extern int print_device_pt(struct fdisk_context *cxt, char *device, int warnme);
-extern void print_all_devices_pt(struct fdisk_context *cxt);
+extern int print_device_pt(struct fdisk_context *cxt, char *device, int warnme, int verify);
+extern void print_all_devices_pt(struct fdisk_context *cxt, int verify);
 
 #endif /* UTIL_LINUX_FDISK_LIST_H */
index ab483030257bee7913b22099a0c45eb42b22256d..b7063b81d6eeac6e925a634127e16677c73a5953 100644 (file)
@@ -804,9 +804,9 @@ int main(int argc, char **argv)
                if (argc > optind) {
                        int k;
                        for (k = optind; k < argc; k++)
-                               print_device_pt(cxt, argv[k], 1);
+                               print_device_pt(cxt, argv[k], 1, 0);
                } else
-                       print_all_devices_pt(cxt);
+                       print_all_devices_pt(cxt, 0);
                break;
 
        case ACT_SHOWSIZE:
index f650ddac3a162f68e4b9ed55f554353065e21879..b4ac71ed78846b6f22d8dd655534363334ca4795 100644 (file)
@@ -59,8 +59,7 @@ UL_DEBUG_DEFINE_MASKANEMS(sfdisk) = UL_DEBUG_EMPTY_MASKNAMES;
 #define ON_DBG(m, x)    __UL_DBG_CALL(sfdisk, SFDISKPROG_DEBUG_, m, x)
 
 enum {
-       ACT_FDISK = 0,          /* default */
-
+       ACT_FDISK = 1,
        ACT_ACTIVATE,
        ACT_CHANGE_ID,
        ACT_DUMP,
@@ -76,6 +75,8 @@ struct sfdisk {
        const char      *label;         /* --label <label> */
 
        struct fdisk_context    *cxt;   /* libfdisk context */
+
+       unsigned int verify : 1;        /* call fdisk_verify_disklabel() */
 };
 
 
@@ -198,11 +199,11 @@ static int command_list_partitions(struct sfdisk *sf, int argc, char **argv)
                for (i = 0; i < argc; i++) {
                        if (ct)
                                fputs("\n\n", stdout);
-                       if (print_device_pt(sf->cxt, argv[i], 0) == 0)
+                       if (print_device_pt(sf->cxt, argv[i], 0, sf->verify) == 0)
                                ct++;
                }
        } else
-               print_all_devices_pt(sf->cxt);
+               print_all_devices_pt(sf->cxt, sf->verify);
 
        return 0;
 }
@@ -241,6 +242,62 @@ static int command_list_types(struct sfdisk *sf)
        return 0;
 }
 
+static int verify_device(struct sfdisk *sf, const char *devname)
+{
+       int rc = 1;
+
+       fdisk_enable_listonly(sf->cxt, 1);
+
+       if (fdisk_assign_device(sf->cxt, devname, 1)) {
+               warn(_("cannot open: %s"), devname);
+               return 1;
+       }
+
+       color_scheme_enable("header", UL_COLOR_BOLD);
+       fdisk_info(sf->cxt, "%s:", devname);
+       color_disable();
+
+       if (!fdisk_has_label(sf->cxt))
+               fdisk_info(sf->cxt, _("unrecognized partition table type"));
+       else
+               rc = fdisk_verify_disklabel(sf->cxt);
+
+       fdisk_deassign_device(sf->cxt, 1);
+       return rc;
+}
+
+/*
+ * sfdisk --verify [<device ..]
+ */
+static int command_verify(struct sfdisk *sf, int argc, char **argv)
+{
+       int nfails = 0, ct = 0;
+
+       if (argc) {
+               int i;
+               for (i = 0; i < argc; i++) {
+                       if (i)
+                               fdisk_info(sf->cxt, " ");
+                       if (verify_device(sf, argv[i]) < 0)
+                               nfails++;
+               }
+       } else {
+               FILE *f = NULL;
+               char *dev;
+
+               while ((dev = next_proc_partition(&f))) {
+                       if (ct)
+                               fdisk_info(sf->cxt, " ");
+                       if (verify_device(sf, dev) < 0)
+                               nfails++;
+                       free(dev);
+                       ct++;
+               }
+       }
+
+       return nfails;
+}
+
 static int get_size(const char *dev, int silent, uintmax_t *sz)
 {
        int fd, rc = 0;
@@ -707,9 +764,9 @@ static void __attribute__ ((__noreturn__)) usage(FILE *out)
        fputs(_(" -N, --partno <num>   specify partition number\n"), out);
        fputs(_(" -s, --show-size      list the size of all or specified device\n"), out);
        fputs(_(" -T, --list-types     print the recognized types (see -X)\n"), out);
+       fputs(_(" -V, --verify         test whether partitions seem correct\n"), out);
        fputs(_(" -X, --label <name>   specify label type (dos, gpt, ...)\n"), out);
 
-
        fputs(USAGE_SEPARATOR, out);
        fputs(USAGE_HELP, out);
        fputs(USAGE_VERSION, out);
@@ -724,20 +781,20 @@ int main(int argc, char *argv[])
 {
        int rc = -EINVAL, c;
        struct sfdisk _sf = {
-               .act = 0,
                .partno = -1
        }, *sf = &_sf;
 
        static const struct option longopts[] = {
                { "activate",no_argument,       NULL, 'a' },
-               { "list",    no_argument,       NULL, 'l' },
                { "dump",    no_argument,       NULL, 'd' },
                { "help",    no_argument,       NULL, 'h' },
-               { "show-size", no_argument,     NULL, 's' },
-               { "partno",  required_argument, NULL, 'N' },
                { "label",   required_argument, NULL, 'X' },
-               { "version", no_argument,       NULL, 'v' },
+               { "list",    no_argument,       NULL, 'l' },
                { "list-types", no_argument,    NULL, 'T' },
+               { "partno",  required_argument, NULL, 'N' },
+               { "show-size", no_argument,     NULL, 's' },
+               { "verify",  no_argument,       NULL, 'V' },
+               { "version", no_argument,       NULL, 'v' },
                { NULL, 0, 0, 0 },
        };
 
@@ -746,7 +803,7 @@ int main(int argc, char *argv[])
        textdomain(PACKAGE);
        atexit(close_stdout);
 
-       while ((c = getopt_long(argc, argv, "adhlN:sTvX:", longopts, NULL)) != -1) {
+       while ((c = getopt_long(argc, argv, "adhlN:sTvVX:", longopts, NULL)) != -1) {
                switch(c) {
                case 'a':
                        sf->act = ACT_ACTIVATE;
@@ -776,6 +833,9 @@ int main(int argc, char *argv[])
                        printf(_("%s from %s\n"), program_invocation_short_name,
                                                  PACKAGE_STRING);
                        return EXIT_SUCCESS;
+               case 'V':
+                       sf->verify = 1;
+                       break;
                default:
                        usage(stderr);
                }
@@ -783,6 +843,11 @@ int main(int argc, char *argv[])
 
        sfdisk_init(sf);
 
+       if (sf->verify && !sf->act)
+               sf->act = ACT_VERIFY;   /* --verify make be used with --list too */
+       else if (!sf->act)
+               sf->act = ACT_FDISK;    /* default */
+
        switch (sf->act) {
        case ACT_ACTIVATE:
                rc = command_activate(sf, argc - optind, argv + optind);
@@ -807,6 +872,10 @@ int main(int argc, char *argv[])
        case ACT_SHOW_SIZE:
                rc = command_show_size(sf, argc - optind, argv + optind);
                break;
+
+       case ACT_VERIFY:
+               rc = command_verify(sf, argc - optind, argv + optind);
+               break;
        }
 
        sfdisk_deinit(sf);