2 * Copyright (C) 1992 A. V. Le Blanc (LeBlanc@mcc.ac.uk)
3 * Copyright (C) 2012 Davidlohr Bueso <dave@gnu.org>
5 * Copyright (C) 2007-2013 Karel Zak <kzak@redhat.com>
7 * This program is free software. You can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation: either version 1 or
10 * (at your option) any later version.
24 #include <libsmartcols.h>
33 #include "pathnames.h"
34 #include "canonicalize.h"
36 #include "closestream.h"
41 #include "pt-sun.h" /* to toggle flags */
43 #ifdef HAVE_LINUX_COMPILER_H
44 # include <linux/compiler.h>
46 #ifdef HAVE_LINUX_BLKPG_H
47 # include <linux/blkpg.h>
51 * fdisk debug stuff (see fdisk.h and include/debug.h)
53 UL_DEBUG_DEFINE_MASK(fdisk
);
54 UL_DEBUG_DEFINE_MASKNAMES(fdisk
) = UL_DEBUG_EMPTY_MASKNAMES
;
56 static void fdiskprog_init_debug(void)
58 __UL_INIT_DEBUG(fdisk
, FDISKPROG_DEBUG_
, 0, FDISK_DEBUG
);
61 int get_user_reply(struct fdisk_context
*cxt
, const char *prompt
,
62 char *buf
, size_t bufsz
)
68 fputs(prompt
, stdout
);
71 if (!fgets(buf
, bufsz
, stdin
)) {
72 if (fdisk_label_is_changed(fdisk_get_label(cxt
, NULL
))) {
73 fprintf(stderr
, _("\nDo you really want to quit? "));
75 if (fgets(buf
, bufsz
, stdin
) && !rpmatch(buf
))
78 fdisk_unref_context(cxt
);
84 for (p
= buf
; *p
&& !isgraph(*p
); p
++); /* get first non-blank */
87 memmove(buf
, p
, p
- buf
); /* remove blank space */
89 if (sz
&& *(buf
+ sz
- 1) == '\n')
90 *(buf
+ sz
- 1) = '\0';
92 DBG(ASK
, ul_debug("user's reply: >>>%s<<<", buf
));
96 static int ask_menu(struct fdisk_context
*cxt
, struct fdisk_ask
*ask
,
97 char *buf
, size_t bufsz
)
100 const char *q
= fdisk_ask_get_query(ask
);
101 int dft
= fdisk_ask_menu_get_default(ask
);
104 fputs(q
, stdout
); /* print header */
111 const char *name
, *desc
;
114 /* print menu items */
115 while (fdisk_ask_menu_get_item(ask
, i
++, &key
, &name
, &desc
) == 0)
116 fprintf(stdout
, " %c %s (%s)\n", key
, name
, desc
);
119 snprintf(prompt
, sizeof(prompt
), _("Select (default %c): "), dft
);
120 rc
= get_user_reply(cxt
, prompt
, buf
, bufsz
);
124 fdisk_info(cxt
, _("Using default response %c."), dft
);
131 while (fdisk_ask_menu_get_item(ask
, i
++, &key
, NULL
, NULL
) == 0) {
133 fdisk_ask_menu_set_result(ask
, c
);
134 return 0; /* success */
137 fdisk_warnx(cxt
, _("Value out of range."));
144 #define tochar(num) ((int) ('a' + num - 1))
145 static int ask_number(struct fdisk_context
*cxt
,
146 struct fdisk_ask
*ask
,
147 char *buf
, size_t bufsz
)
149 char prompt
[128] = { '\0' };
150 const char *q
= fdisk_ask_get_query(ask
);
151 const char *range
= fdisk_ask_number_get_range(ask
);
153 uint64_t dflt
= fdisk_ask_number_get_default(ask
),
154 low
= fdisk_ask_number_get_low(ask
),
155 high
= fdisk_ask_number_get_high(ask
);
156 int inchar
= fdisk_ask_number_inchars(ask
);
160 DBG(ASK
, ul_debug("asking for number "
161 "['%s', <%ju,%ju>, default=%ju, range: %s]",
162 q
, low
, high
, dflt
, range
));
164 if (range
&& dflt
>= low
&& dflt
<= high
) {
166 snprintf(prompt
, sizeof(prompt
), _("%s (%s, default %c): "),
167 q
, range
, tochar(dflt
));
169 snprintf(prompt
, sizeof(prompt
), _("%s (%s, default %ju): "),
172 } else if (dflt
>= low
&& dflt
<= high
) {
174 snprintf(prompt
, sizeof(prompt
), _("%s (%c-%c, default %c): "),
175 q
, tochar(low
), tochar(high
), tochar(dflt
));
177 snprintf(prompt
, sizeof(prompt
), _("%s (%ju-%ju, default %ju): "),
180 snprintf(prompt
, sizeof(prompt
), _("%s (%c-%c): "),
181 q
, tochar(low
), tochar(high
));
183 snprintf(prompt
, sizeof(prompt
), _("%s (%ju-%ju): "),
187 int rc
= get_user_reply(cxt
, prompt
, buf
, bufsz
);
192 if (!*buf
&& dflt
>= low
&& dflt
<= high
)
193 return fdisk_ask_number_set_result(ask
, dflt
);
195 if (isdigit_string(buf
)) {
199 num
= strtoumax(buf
, &end
, 10);
200 if (errno
|| buf
== end
|| (end
&& *end
))
202 } else if (inchar
&& isalpha(*buf
)) {
203 num
= tolower(*buf
) - 'a' + 1;
207 if (rc
== 0 && num
>= low
&& num
<= high
)
208 return fdisk_ask_number_set_result(ask
, num
);
210 fdisk_warnx(cxt
, _("Value out of range."));
216 static int ask_offset(struct fdisk_context
*cxt
,
217 struct fdisk_ask
*ask
,
218 char *buf
, size_t bufsz
)
220 char prompt
[128] = { '\0' };
221 const char *q
= fdisk_ask_get_query(ask
);
222 const char *range
= fdisk_ask_number_get_range(ask
);
224 uint64_t dflt
= fdisk_ask_number_get_default(ask
),
225 low
= fdisk_ask_number_get_low(ask
),
226 high
= fdisk_ask_number_get_high(ask
),
227 base
= fdisk_ask_number_get_base(ask
);
231 DBG(ASK
, ul_debug("asking for offset ['%s', <%ju,%ju>, base=%ju, default=%ju, range: %s]",
232 q
, low
, high
, base
, dflt
, range
));
234 if (range
&& dflt
>= low
&& dflt
<= high
)
235 snprintf(prompt
, sizeof(prompt
), _("%s (%s, default %ju): "), q
, range
, dflt
);
236 else if (dflt
>= low
&& dflt
<= high
)
237 snprintf(prompt
, sizeof(prompt
), _("%s (%ju-%ju, default %ju): "), q
, low
, high
, dflt
);
239 snprintf(prompt
, sizeof(prompt
), _("%s (%ju-%ju): "), q
, low
, high
);
246 int rc
= get_user_reply(cxt
, prompt
, buf
, bufsz
);
249 if (!*buf
&& dflt
>= low
&& dflt
<= high
)
250 return fdisk_ask_number_set_result(ask
, dflt
);
253 if (*p
== '+' || *p
== '-') {
258 rc
= parse_size(p
, &num
, &pwr
);
261 DBG(ASK
, ul_debug("parsed size: %ju", num
));
263 /* +{size}{K,M,...} specified, the "num" is in bytes */
264 uint64_t unit
= fdisk_ask_number_get_unit(ask
);
265 num
+= unit
/2; /* round */
273 DBG(ASK
, ul_debug("final offset: %ju [sig: %c, power: %d, %s]",
275 sig
? "relative" : "absolute"));
276 if (num
>= low
&& num
<= high
) {
278 fdisk_ask_number_set_relative(ask
, 1);
279 return fdisk_ask_number_set_result(ask
, num
);
281 fdisk_warnx(cxt
, _("Value out of range."));
287 static unsigned int info_count
;
289 static void fputs_info(struct fdisk_ask
*ask
, FILE *out
)
294 msg
= fdisk_ask_print_get_mesg(ask
);
304 int ask_callback(struct fdisk_context
*cxt
, struct fdisk_ask
*ask
,
305 void *data
__attribute__((__unused__
)))
313 if (fdisk_ask_get_type(ask
) != FDISK_ASKTYPE_INFO
)
316 switch(fdisk_ask_get_type(ask
)) {
317 case FDISK_ASKTYPE_MENU
:
318 return ask_menu(cxt
, ask
, buf
, sizeof(buf
));
319 case FDISK_ASKTYPE_NUMBER
:
320 return ask_number(cxt
, ask
, buf
, sizeof(buf
));
321 case FDISK_ASKTYPE_OFFSET
:
322 return ask_offset(cxt
, ask
, buf
, sizeof(buf
));
323 case FDISK_ASKTYPE_INFO
:
324 if (!fdisk_is_listonly(cxt
))
326 fputs_info(ask
, stdout
);
328 case FDISK_ASKTYPE_WARNX
:
329 color_scheme_fenable("warn", UL_COLOR_RED
, stderr
);
330 fputs(fdisk_ask_print_get_mesg(ask
), stderr
);
331 color_fdisable(stderr
);
334 case FDISK_ASKTYPE_WARN
:
335 color_scheme_fenable("warn", UL_COLOR_RED
, stderr
);
336 fputs(fdisk_ask_print_get_mesg(ask
), stderr
);
337 errno
= fdisk_ask_print_get_errno(ask
);
338 fprintf(stderr
, ": %m\n");
339 color_fdisable(stderr
);
341 case FDISK_ASKTYPE_YESNO
:
345 fputs(fdisk_ask_get_query(ask
), stdout
);
346 rc
= get_user_reply(cxt
, _(" [Y]es/[N]o: "), buf
, sizeof(buf
));
350 if (x
== RPMATCH_YES
|| x
== RPMATCH_NO
) {
351 fdisk_ask_yesno_set_result(ask
, x
);
355 DBG(ASK
, ul_debug("yes-no ask: reply '%s' [rc=%d]", buf
, rc
));
357 case FDISK_ASKTYPE_STRING
:
360 snprintf(prmt
, sizeof(prmt
), "%s: ", fdisk_ask_get_query(ask
));
362 rc
= get_user_reply(cxt
, prmt
, buf
, sizeof(buf
));
364 fdisk_ask_string_set_result(ask
, xstrdup(buf
));
365 DBG(ASK
, ul_debug("string ask: reply '%s' [rc=%d]", buf
, rc
));
369 warnx(_("internal error: unsupported dialog type %d"), fdisk_ask_get_type(ask
));
375 struct fdisk_parttype
*ask_partition_type(struct fdisk_context
*cxt
)
378 struct fdisk_label
*lb
;
381 lb
= fdisk_get_label(cxt
, NULL
);
386 q
= fdisk_label_has_code_parttypes(lb
) ?
387 _("Partition type (type L to list all types): ") :
388 _("Hex code (type L to list all codes): ");
391 int rc
= get_user_reply(cxt
, q
, buf
, sizeof(buf
));
396 if (buf
[1] == '\0' && toupper(*buf
) == 'L')
397 list_partition_types(cxt
);
399 return fdisk_label_parse_parttype(lb
, buf
);
405 void list_partition_types(struct fdisk_context
*cxt
)
408 struct fdisk_label
*lb
= fdisk_get_label(cxt
, NULL
);
411 lb
= fdisk_get_label(cxt
, NULL
);
414 ntypes
= fdisk_label_get_nparttypes(lb
);
418 if (fdisk_label_has_code_parttypes(lb
)) {
420 * Prints in 4 columns in format <hex> <name>
422 size_t last
[4], done
= 0, next
= 0, size
;
427 for (i
= 3; i
>= 0; i
--)
428 last
[3 - i
] = done
+= (size
+ i
- done
) / (i
+ 1);
432 #define NAME_WIDTH 15
433 char name
[NAME_WIDTH
* MB_LEN_MAX
];
434 size_t width
= NAME_WIDTH
;
435 const struct fdisk_parttype
*t
= fdisk_label_get_parttype(lb
, next
);
438 if (fdisk_parttype_get_name(t
)) {
439 printf("%c%2x ", i
? ' ' : '\n',
440 fdisk_parttype_get_code(t
));
441 ret
= mbsalign(_(fdisk_parttype_get_name(t
)),
443 &width
, MBS_ALIGN_LEFT
, 0);
445 if (ret
== (size_t)-1 || ret
>= sizeof(name
))
447 _(fdisk_parttype_get_name(t
)));
452 next
= last
[i
++] + done
;
453 if (i
> 3 || next
>= last
[i
]) {
457 } while (done
< last
[0]);
461 * Prints 1 column in format <idx> <name> <typestr>
465 for (i
= 0; i
< ntypes
; i
++) {
466 const struct fdisk_parttype
*t
= fdisk_label_get_parttype(lb
, i
);
467 printf("%3zu %-30s %s\n", i
+ 1,
468 fdisk_parttype_get_name(t
),
469 fdisk_parttype_get_string(t
));
475 void toggle_dos_compatibility_flag(struct fdisk_context
*cxt
)
477 struct fdisk_label
*lb
= fdisk_get_label(cxt
, "dos");
483 flag
= !fdisk_dos_is_compatible(lb
);
484 fdisk_info(cxt
, flag
?
485 _("DOS Compatibility flag is set (DEPRECATED!)") :
486 _("DOS Compatibility flag is not set"));
488 fdisk_dos_enable_compatible(lb
, flag
);
490 if (fdisk_is_label(cxt
, DOS
))
491 fdisk_reset_alignment(cxt
); /* reset the current label */
494 void change_partition_type(struct fdisk_context
*cxt
)
497 struct fdisk_parttype
*t
= NULL
;
498 struct fdisk_partition
*pa
= NULL
;
499 const char *old
= NULL
;
503 if (fdisk_ask_partnum(cxt
, &i
, FALSE
))
506 if (fdisk_get_partition(cxt
, i
, &pa
)) {
507 fdisk_warnx(cxt
, _("Partition %zu does not exist yet!"), i
+ 1);
511 t
= (struct fdisk_parttype
*) fdisk_partition_get_type(pa
);
512 old
= t
? fdisk_parttype_get_name(t
) : _("Unknown");
515 t
= ask_partition_type(cxt
);
518 if (fdisk_set_partition_type(cxt
, i
, t
) == 0)
520 _("Changed type of partition '%s' to '%s'."),
521 old
, t
? fdisk_parttype_get_name(t
) : _("Unknown"));
524 _("Type of partition %zu is unchanged: %s."),
527 fdisk_unref_partition(pa
);
530 static size_t skip_empty(const unsigned char *buf
, size_t i
, size_t sz
)
533 const unsigned char *p0
= buf
+ i
;
535 for (next
= i
+ 16; next
< sz
; next
+= 16) {
536 if (memcmp(p0
, buf
+ next
, 16) != 0)
540 return next
== i
+ 16 ? i
: next
;
543 static void dump_buffer(off_t base
, unsigned char *buf
, size_t sz
, int all
)
545 size_t i
, l
, next
= 0;
549 for (i
= 0, l
= 0; i
< sz
; i
++, l
++) {
551 if (all
== 0 && !next
)
552 next
= skip_empty(buf
, i
, sz
);
553 printf("%08jx ", base
+ i
);
555 printf(" %02x", buf
[i
]);
556 if (l
== 7) /* words separator */
559 fputc('\n', stdout
); /* next line */
572 static void dump_blkdev(struct fdisk_context
*cxt
, const char *name
,
573 uint64_t offset
, size_t size
, int all
)
575 int fd
= fdisk_get_devfd(cxt
);
577 fdisk_info(cxt
, _("\n%s: offset = %ju, size = %zu bytes."),
582 if (lseek(fd
, (off_t
) offset
, SEEK_SET
) == (off_t
) -1)
583 fdisk_warn(cxt
, _("cannot seek"));
585 unsigned char *buf
= xmalloc(size
);
587 if (read_all(fd
, (char *) buf
, size
) != (ssize_t
) size
)
588 fdisk_warn(cxt
, _("cannot read"));
590 dump_buffer(offset
, buf
, size
, all
);
595 void dump_firstsector(struct fdisk_context
*cxt
)
597 int all
= !isatty(STDOUT_FILENO
);
601 dump_blkdev(cxt
, _("First sector"), 0, fdisk_get_sector_size(cxt
), all
);
604 void dump_disklabel(struct fdisk_context
*cxt
)
606 int all
= !isatty(STDOUT_FILENO
);
608 const char *name
= NULL
;
614 while (fdisk_locate_disklabel(cxt
, i
++, &name
, &offset
, &size
) == 0 && size
)
615 dump_blkdev(cxt
, name
, offset
, size
, all
);
618 static fdisk_sector_t
get_dev_blocks(char *dev
)
623 if ((fd
= open(dev
, O_RDONLY
)) < 0)
624 err(EXIT_FAILURE
, _("cannot open %s"), dev
);
625 ret
= blkdev_get_sectors(fd
, (unsigned long long *) &size
);
628 err(EXIT_FAILURE
, _("BLKGETSIZE ioctl failed on %s"), dev
);
632 static void __attribute__ ((__noreturn__
)) usage(FILE *out
)
634 fputs(USAGE_HEADER
, out
);
637 _(" %1$s [options] <disk> change partition table\n"
638 " %1$s [options] -l [<disk>] list partition table(s)\n"),
639 program_invocation_short_name
);
641 fputs(USAGE_SEPARATOR
, out
);
642 fputs(_("Display or manipulate a disk partition table.\n"), out
);
644 fputs(USAGE_OPTIONS
, out
);
645 fputs(_(" -b, --sector-size <size> physical and logical sector size\n"), out
);
646 fputs(_(" -c, --compatibility[=<mode>] mode is 'dos' or 'nondos' (default)\n"), out
);
647 fputs(_(" -L, --color[=<when>] colorize output (auto, always or never)\n"), out
);
649 " %s\n", USAGE_COLORS_DEFAULT
);
650 fputs(_(" -l, --list display partitions end exit\n"), out
);
651 fputs(_(" -o, --output <list> output columns\n"), out
);
652 fputs(_(" -t, --type <type> recognize specified partition table type only\n"), out
);
653 fputs(_(" -u, --units[=<unit>] display units: 'cylinders' or 'sectors' (default)\n"), out
);
654 fputs(_(" -s, --getsz display device size in 512-byte sectors [DEPRECATED]\n"), out
);
655 fputs(_(" --bytes print SIZE in bytes rather than in human readable format\n"), out
);
657 fputs(USAGE_SEPARATOR
, out
);
658 fputs(_(" -C, --cylinders <number> specify the number of cylinders\n"), out
);
659 fputs(_(" -H, --heads <number> specify the number of heads\n"), out
);
660 fputs(_(" -S, --sectors <number> specify the number of sectors per track\n"), out
);
662 fputs(USAGE_SEPARATOR
, out
);
663 fputs(USAGE_HELP
, out
);
664 fputs(USAGE_VERSION
, out
);
666 list_available_columns(out
);
668 fprintf(out
, USAGE_MAN_TAIL("fdisk(8)"));
669 exit(out
== stderr
? EXIT_FAILURE
: EXIT_SUCCESS
);
674 ACT_FDISK
= 0, /* default */
679 int main(int argc
, char **argv
)
681 int rc
, i
, c
, act
= ACT_FDISK
;
682 int colormode
= UL_COLORMODE_UNDEF
;
683 struct fdisk_context
*cxt
;
686 OPT_BYTES
= CHAR_MAX
+ 1
688 static const struct option longopts
[] = {
689 { "bytes", no_argument
, NULL
, OPT_BYTES
},
690 { "color", optional_argument
, NULL
, 'L' },
691 { "compatibility", optional_argument
, NULL
, 'c' },
692 { "cylinders", required_argument
, NULL
, 'C' },
693 { "heads", required_argument
, NULL
, 'H' },
694 { "sectors", required_argument
, NULL
, 'S' },
695 { "getsz", no_argument
, NULL
, 's' },
696 { "help", no_argument
, NULL
, 'h' },
697 { "list", no_argument
, NULL
, 'l' },
698 { "sector-size", required_argument
, NULL
, 'b' },
699 { "type", required_argument
, NULL
, 't' },
700 { "units", optional_argument
, NULL
, 'u' },
701 { "version", no_argument
, NULL
, 'V' },
702 { "output", no_argument
, NULL
, 'o' },
706 setlocale(LC_ALL
, "");
707 bindtextdomain(PACKAGE
, LOCALEDIR
);
709 atexit(close_stdout
);
712 fdiskprog_init_debug();
714 cxt
= fdisk_new_context();
716 err(EXIT_FAILURE
, _("failed to allocate libfdisk context"));
718 fdisk_set_ask(cxt
, ask_callback
, NULL
);
720 while ((c
= getopt_long(argc
, argv
, "b:c::C:hH:lL::o:sS:t:u::vV",
721 longopts
, NULL
)) != -1) {
725 size_t sz
= strtou32_or_err(optarg
,
726 _("invalid sector size argument"));
727 if (sz
!= 512 && sz
!= 1024 && sz
!= 2048 && sz
!= 4096)
729 fdisk_save_user_sector_size(cxt
, sz
, sz
);
733 fdisk_save_user_geometry(cxt
,
734 strtou32_or_err(optarg
,
735 _("invalid cylinders argument")),
740 /* this setting is independent on the current
741 * actively used label
743 char *p
= *optarg
== '=' ? optarg
+ 1 : optarg
;
744 struct fdisk_label
*lb
= fdisk_get_label(cxt
, "dos");
747 err(EXIT_FAILURE
, _("not found DOS label driver"));
748 if (strcmp(p
, "dos") == 0)
749 fdisk_dos_enable_compatible(lb
, TRUE
);
750 else if (strcmp(p
, "nondos") == 0)
751 fdisk_dos_enable_compatible(lb
, FALSE
);
753 warnx(_("unknown compatibility mode '%s'"), p
);
757 /* use default if no optarg specified */
760 fdisk_save_user_geometry(cxt
, 0,
761 strtou32_or_err(optarg
,
762 _("invalid heads argument")),
766 fdisk_save_user_geometry(cxt
, 0, 0,
767 strtou32_or_err(optarg
,
768 _("invalid sectors argument")));
774 colormode
= UL_COLORMODE_AUTO
;
776 colormode
= colormode_or_err(optarg
,
777 _("unsupported color mode"));
787 struct fdisk_label
*lb
= NULL
;
789 while (fdisk_next_label(cxt
, &lb
) == 0)
790 fdisk_label_set_disabled(lb
, 1);
792 lb
= fdisk_get_label(cxt
, optarg
);
794 errx(EXIT_FAILURE
, _("unsupported disklabel: %s"), optarg
);
795 fdisk_label_set_disabled(lb
, 0);
799 if (optarg
&& *optarg
== '=')
801 if (fdisk_set_unit(cxt
, optarg
) != 0)
804 case 'V': /* preferred for util-linux */
805 case 'v': /* for backward compatibility only */
806 printf(UTIL_LINUX_VERSION
);
811 fdisk_set_size_unit(cxt
, FDISK_SIZEUNIT_BYTES
);
818 if (argc
-optind
!= 1 && fdisk_has_user_device_properties(cxt
))
819 warnx(_("The device properties (sector size and geometry) should"
820 " be used with one specified device only."));
822 colors_init(colormode
, "fdisk");
826 fdisk_enable_listonly(cxt
, 1);
827 init_fields(cxt
, outarg
, NULL
);
831 for (k
= optind
; k
< argc
; k
++)
832 print_device_pt(cxt
, argv
[k
], 1, 0);
834 print_all_devices_pt(cxt
, 0);
839 if (argc
- optind
<= 0)
842 for (i
= optind
; i
< argc
; i
++) {
843 uintmax_t blks
= get_dev_blocks(argv
[i
]);
845 if (argc
- optind
== 1)
846 printf("%ju\n", blks
);
848 printf("%s: %ju\n", argv
[i
], blks
);
853 if (argc
-optind
!= 1)
856 /* Here starts interactive mode, use fdisk_{warn,info,..} functions */
857 color_scheme_enable("welcome", UL_COLOR_GREEN
);
858 fdisk_info(cxt
, _("Welcome to fdisk (%s)."), PACKAGE_STRING
);
860 fdisk_info(cxt
, _("Changes will remain in memory only, until you decide to write them.\n"
861 "Be careful before using the write command.\n"));
863 rc
= fdisk_assign_device(cxt
, argv
[optind
], 0);
865 rc
= fdisk_assign_device(cxt
, argv
[optind
], 1);
867 fdisk_warnx(cxt
, _("Device open in read-only mode."));
870 err(EXIT_FAILURE
, _("cannot open %s"), argv
[optind
]);
874 if (!fdisk_has_label(cxt
)) {
875 fdisk_info(cxt
, _("Device does not contain a recognized partition table."));
876 fdisk_create_disklabel(cxt
, NULL
);
878 } else if (fdisk_is_label(cxt
, GPT
) && fdisk_gpt_is_hybrid(cxt
))
880 "A hybrid GPT was detected. You have to sync "
881 "the hybrid MBR manually (expert command 'M')."));
883 init_fields(cxt
, outarg
, NULL
); /* -o <columns> */
886 process_fdisk_menu(&cxt
);
889 fdisk_unref_context(cxt
);