]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: properly implement read-only mode
authorKarel Zak <kzak@redhat.com>
Fri, 21 Mar 2014 13:04:59 +0000 (14:04 +0100)
committerKarel Zak <kzak@redhat.com>
Fri, 21 Mar 2014 13:04:59 +0000 (14:04 +0100)
Don't use fallback to read-only mode in fdisk_context_assign_device(),
it's application responsibility open the device in the right mode.

The commands fdisk and cfdisk check (and report) read-only mode now.

Reported-by: Maciej MaƂecki <me@mmalecki.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
disk-utils/cfdisk.c
disk-utils/fdisk-menu.c
disk-utils/fdisk.c
libfdisk/src/context.c
libfdisk/src/fdiskP.h
libfdisk/src/label.c
libfdisk/src/libfdisk.h

index 6a07ced251ef4438a5bd13fef72a24f0da402117..651c45b858db7e6110a6d054d44be0715e845b4d 100644 (file)
@@ -1525,6 +1525,10 @@ static int main_menu_ignore_keys(struct cfdisk *cf, char *ignore,
                    !fdisk_is_disklabel(cf->cxt, SGI))
                        ignore[i++] = 'b';
        }
+
+
+       if (fdisk_context_is_readonly(cf->cxt))
+               ignore[i++] = 'W';
        return i;
 }
 
@@ -1643,7 +1647,14 @@ static int main_menu_action(struct cfdisk *cf, int key)
        case 'W': /* Write */
        {
                char buf[64] = { 0 };
-               int rc = ui_get_string(cf,
+               int rc;
+
+               if (fdisk_context_is_readonly(cf->cxt)) {
+                       ui_warnx(_("Device open in read-only mode"));
+                       break;
+               }
+
+               rc = ui_get_string(cf,
                          _("Are you sure you want to write the partition "
                            "table to disk? "),
                          _("Type \"yes\" or \"no\" or press ESC to left dialog."),
@@ -1709,6 +1720,9 @@ static int ui_run(struct cfdisk *cf)
        if (rc)
                return rc;
 
+       if (fdisk_context_is_readonly(cf->cxt))
+               ui_warnx(_("Device open in read-only mode."));
+
        do {
                int rc = 0, key = getch();
 
@@ -1835,7 +1849,10 @@ int main(int argc, char *argv[])
        if (optind == argc)
                usage(stderr);
 
-       if (fdisk_context_assign_device(cf->cxt, argv[optind], 0) != 0)
+       rc = fdisk_context_assign_device(cf->cxt, argv[optind], 0);
+       if (rc == -EACCES)
+               rc = fdisk_context_assign_device(cf->cxt, argv[optind], 1);
+       if (rc != 0)
                err(EXIT_FAILURE, _("cannot open %s"), argv[optind]);
 
        /* Don't use err(), warn() from this point */
index 822761568168c3086e9cd884cf7c5f4dfe17bc9b..bdaa7347552aa0bbe5541c5128ebc278fca70a70 100644 (file)
@@ -447,6 +447,10 @@ static int generic_menu_cb(struct fdisk_context **cxt0,
                list_disklabel(cxt);
                break;
        case 'w':
+               if (fdisk_context_is_readonly(cxt)) {
+                       fdisk_warnx(cxt, _("Device open in read-only mode."));
+                       break;
+               }
                rc = fdisk_write_disklabel(cxt);
                if (rc)
                        err(EXIT_FAILURE, _("failed to write disklabel"));
index fa7f248cc36c74a5cc7f05f158ae7136264a99a7..bfe3fe3b5b7daa0ac64dc6ad2e1781fb9046756a 100644 (file)
@@ -778,7 +778,7 @@ enum {
 
 int main(int argc, char **argv)
 {
-       int i, c, act = ACT_FDISK;
+       int rc, i, c, act = ACT_FDISK;
        int colormode = UL_COLORMODE_UNDEF;
        struct fdisk_context *cxt;
 
@@ -920,7 +920,13 @@ int main(int argc, char **argv)
                fdisk_info(cxt, _("Changes will remain in memory only, until you decide to write them.\n"
                                  "Be careful before using the write command.\n"));
 
-               if (fdisk_context_assign_device(cxt, argv[optind], 0) != 0)
+               rc = fdisk_context_assign_device(cxt, argv[optind], 0);
+               if (rc == -EACCES) {
+                       rc = fdisk_context_assign_device(cxt, argv[optind], 1);
+                       if (rc == 0)
+                               fdisk_warnx(cxt, _("Device open in read-only mode."));
+               }
+               if (rc)
                        err(EXIT_FAILURE, _("cannot open %s"), argv[optind]);
 
                fflush(stdout);
index 7d7b0c66899af0858b056e2f34a306f943e05ed2..ec0b6d84ffa7ea4e2f86e41031a92f38025921b1 100644 (file)
@@ -260,12 +260,11 @@ int fdisk_context_assign_device(struct fdisk_context *cxt,
 
        reset_context(cxt);
 
-       if (readonly == 1 || (fd = open(fname, O_RDWR|O_CLOEXEC)) < 0) {
-               if ((fd = open(fname, O_RDONLY|O_CLOEXEC)) < 0)
-                       return -errno;
-               readonly = 1;
-       }
+       fd = open(fname, (readonly ? O_RDONLY : O_RDWR ) | O_CLOEXEC);
+       if (fd < 0)
+               return -errno;
 
+       cxt->readonly = readonly;
        cxt->dev_fd = fd;
        cxt->dev_path = strdup(fname);
        if (!cxt->dev_path)
@@ -315,6 +314,12 @@ int fdisk_context_deassign_device(struct fdisk_context *cxt)
        return 0;
 }
 
+int fdisk_context_is_readonly(struct fdisk_context *cxt)
+{
+       assert(cxt);
+       return cxt->readonly;
+}
+
 /**
  * fdisk_free_context:
  * @cxt: fdisk context
index b5880df701a795aa4b44653b6358f97267a0fe91..cb3c2b27cdb24c0c10fb0c6ffd712fdea6c556b2 100644 (file)
@@ -346,7 +346,8 @@ struct fdisk_context {
        unsigned long sector_size;      /* logical size */
        unsigned long alignment_offset;
 
-       unsigned int display_in_cyl_units : 1,  /* for obscure labels */
+       unsigned int readonly : 1,              /* don't write to the device */
+                    display_in_cyl_units : 1,  /* for obscure labels */
                     display_details : 1,       /* expert display mode */
                     listonly : 1;              /* list partition, nothing else */
 
index 36008997230ef99513d9ac9ec548cf17c1d62ade..9c6fcc5b38bd64f33effdc7553c4f8aaac82fca3 100644 (file)
@@ -75,11 +75,10 @@ int fdisk_dev_is_disklabel(struct fdisk_context *cxt, enum fdisk_labeltype l)
  */
 int fdisk_write_disklabel(struct fdisk_context *cxt)
 {
-       if (!cxt || !cxt->label)
+       if (!cxt || !cxt->label || cxt->readonly)
                return -EINVAL;
        if (!cxt->label->op->write)
                return -ENOSYS;
-
        return cxt->label->op->write(cxt);
 }
 
index 3a173e39076a2e71641673b852572759e98b86fe..ed48da793e6d9764118783eeb14b894eb2aa7d2b 100644 (file)
@@ -78,6 +78,7 @@ extern int fdisk_context_set_ask(struct fdisk_context *cxt,
                        int (*ask_cb)(struct fdisk_context *, struct fdisk_ask *, void *),
                        void *data);
 
+extern int fdisk_context_is_readonly(struct fdisk_context *cxt);
 extern int fdisk_context_assign_device(struct fdisk_context *cxt,
                                const char *fname, int readonly);
 extern int fdisk_context_deassign_device(struct fdisk_context *cxt);