]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
sfdisk: add --label-nested for hybrid GPT
authorKarel Zak <kzak@redhat.com>
Mon, 6 Oct 2014 12:53:25 +0000 (14:53 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 7 Oct 2014 12:55:33 +0000 (14:55 +0200)
regular disk label:
# sfdisk --list /dev/sdb
..
Disklabel type: gpt
Disk identifier: 9DF9A9F1-0654-4E7A-9A5E-36E66D60FD79

Device     Start    End Sectors Size Type
/dev/sdb1   2048  22527   20480  10M Linux filesystem
/dev/sdb2  22528  43007   20480  10M Linux swap
/dev/sdb3  43008 204766  161759  79M Linux filesystem

nested (PMBR):
# sfdisk --list --label-nested dos /dev/sdb
...
Disklabel type: dos
Disk identifier: 0x00000000

Device     Boot Start    End Sectors  Size Id Type
/dev/sdb1           1 204799  204799  100M ee GPT

and for example:
        # sfdisk --label-nested dos /dev/sdb <<EOF
        1, 2047, ee
        , 10M, L
        , 10M, S
        ,,

creates hybrid GPT (PMBR partitions point to the same location as GPT)

Signed-off-by: Karel Zak <kzak@redhat.com>
disk-utils/sfdisk.8
disk-utils/sfdisk.c

index 226fa34214a1e7d8c480d0a4abcfa88a90bf2a9d..8f905174f95d71f6b64f992b9cf424b6b772cfd3 100644 (file)
@@ -147,6 +147,10 @@ Specify disk label type (e.g. dos, gpt, ...). If no label specified then sfdisk
 defaults to an existing label. If there is no label on the device than defaults
 to "dos".
 .TP
+.BR \-Y , " \-\-label-nested \fItype\fR
+Force sfdisk to edit nested disk label. The primary disk label has to already exist.
+This option allows to edit for example hybrid/protective MBR on devices with GPT.
+.TP
 .BR \-h , " \-\-help"
 Display help text and exit.
 .TP
index 7a5e8be8d0b79a29ffdea6d7f95939854e7a9a65..faaaf3feda66a9365931bace4312083d52346de2 100644 (file)
@@ -79,6 +79,7 @@ struct sfdisk {
        int             act;            /* action */
        int             partno;         /* -N <partno>, default -1 */
        const char      *label;         /* --label <label> */
+       const char      *label_nested;  /* --label-nested <label> */
        const char      *backup_file;   /* -O <path> */
 
        struct fdisk_context    *cxt;   /* libfdisk context */
@@ -189,15 +190,31 @@ static void sfdisk_init(struct sfdisk *sf)
        if (!sf->cxt)
                err(EXIT_FAILURE, _("failed to allocate libfdisk context"));
        fdisk_set_ask(sf->cxt, ask_callback, (void *) sf);
+
+       if (sf->label_nested) {
+               struct fdisk_context *x = fdisk_new_nested_context(sf->cxt,
+                                                       sf->label_nested);
+               if (!x)
+                       err(EXIT_FAILURE, _("failed to allocate nested libfdisk context"));
+               /* the original context is available by fdisk_get_parent() */
+               sf->cxt = x;
+       }
 }
 
 static int sfdisk_deinit(struct sfdisk *sf)
 {
+       struct fdisk_context *parent;
        int rc;
 
        assert(sf);
        assert(sf->cxt);
 
+       parent = fdisk_get_parent(sf->cxt);
+       if (parent) {
+               fdisk_unref_context(sf->cxt);
+               sf->cxt = parent;
+       }
+
        fdisk_unref_context(sf->cxt);
        memset(sf, 0, sizeof(*sf));
 
@@ -1315,6 +1332,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE *out)
        fputs(_(" -O, --backup-file <path>  override default backout file name\n"), out);
        fputs(_(" -N, --partno <num>        specify partition number\n"), out);
        fputs(_(" -X, --label <name>        specify label type (dos, gpt, ...)\n"), out);
+       fputs(_(" -Y, --label-nested <name> specify nested label type (dos, bsd)\n"), out);
        fputs(_(" -q, --quiet               suppress extra info messages\n"), out);
        fputs(_(" -n, --no-act              do everything except write to device\n"), out);
        fputs(_("     --no-reread           do not check whether the device is in use\n"), out);
@@ -1361,6 +1379,7 @@ int main(int argc, char *argv[])
                { "help",    no_argument,       NULL, 'h' },
                { "force",   no_argument,       NULL, 'f' },
                { "label",   required_argument, NULL, 'X' },
+               { "label-nested", required_argument, NULL, 'Y' },
                { "list",    no_argument,       NULL, 'l' },
                { "list-types", no_argument,    NULL, 'T' },
                { "no-act",  no_argument,       NULL, 'n' },
@@ -1393,7 +1412,7 @@ int main(int argc, char *argv[])
        textdomain(PACKAGE);
        atexit(close_stdout);
 
-       while ((c = getopt_long(argc, argv, "aAbcdfghlLo:O:nN:qsTu:vVX:",
+       while ((c = getopt_long(argc, argv, "aAbcdfghlLo:O:nN:qsTu:vVX:Y:",
                                        longopts, &longidx)) != -1) {
                switch(c) {
                case 'a':
@@ -1471,6 +1490,9 @@ int main(int argc, char *argv[])
                case 'X':
                        sf->label = optarg;
                        break;
+               case 'Y':
+                       sf->label_nested = optarg;
+                       break;
 
                case OPT_PARTUUID:
                        sf->act = ACT_PARTUUID;