2 * Copyright (C) 2017 Karel Zak <kzak@redhat.com>
4 * This file may be redistributed under the terms of the
5 * GNU Lesser General Public License.
8 * Libfdisk sample to create partitions by specify size, for example:
10 * mkpart --label dos --device /dev/sdc 2M 2M 2M 10M 1M -
12 * creates 6 partitions:
14 * - 1 extended (1x 10M)
15 * - 2 logical (1x 1M, 1x remaining-space-in-extended-partition)
18 * The sample specifies size and partno for MBR, and size only for another
21 * The Ask-API does not use anything else than warning/info. The
22 * partitionning has to be done non-interactive.
28 #include <sys/types.h>
40 static int ask_callback(struct fdisk_context
*cxt
__attribute__((__unused__
)),
41 struct fdisk_ask
*ask
,
44 switch(fdisk_ask_get_type(ask
)) {
45 case FDISK_ASKTYPE_INFO
:
46 fputs(fdisk_ask_print_get_mesg(ask
), stdout
);
49 case FDISK_ASKTYPE_WARNX
:
51 fputs(fdisk_ask_print_get_mesg(ask
), stderr
);
54 case FDISK_ASKTYPE_WARN
:
56 fputs(fdisk_ask_print_get_mesg(ask
), stderr
);
57 errno
= fdisk_ask_print_get_errno(ask
);
58 fprintf(stderr
, ": %m\n");
66 int main(int argc
, char *argv
[])
68 struct fdisk_context
*cxt
;
69 struct fdisk_partition
*pa
;
70 const char *label
= NULL
, *device
= NULL
;
71 int n
= 0, c
, nopartno
= 0;
72 unsigned int sectorsize
;
75 static const struct option longopts
[] = {
76 { "label", required_argument
, NULL
, 'x' },
77 { "device", required_argument
, NULL
, 'd' },
78 { "nopartno", no_argument
, NULL
, 'p' },
79 { "grain", required_argument
, NULL
, 'g' },
80 { "help", no_argument
, NULL
, 'h' },
84 setlocale(LC_ALL
, ""); /* just to have enable UTF8 chars */
88 while((c
= getopt_long(argc
, argv
, "g:x:d:h", longopts
, NULL
)) != -1) {
100 grain
= strtosize_or_err(optarg
, "failed to parse grain");
103 printf("%s [options] <size> ...", program_invocation_short_name
);
104 fputs(USAGE_SEPARATOR
, stdout
);
105 fputs("Make disklabel and partitions.\n", stdout
);
106 fputs(USAGE_OPTIONS
, stdout
);
107 fputs(" -x, --label <dos,gpt,...> disk label type\n", stdout
);
108 fputs(" -d, --device <path> block device\n", stdout
);
109 fputs(" -p, --nopartno don't set partno (use default)\n", stdout
);
110 fputs(" -h, --help this help\n", stdout
);
111 fputs(USAGE_SEPARATOR
, stdout
);
117 errx(EXIT_FAILURE
, "no device specified");
121 cxt
= fdisk_new_context();
124 fdisk_set_ask(cxt
, ask_callback
, NULL
);
127 fdisk_save_user_grain(cxt
, grain
);
129 pa
= fdisk_new_partition();
133 if (fdisk_assign_device(cxt
, device
, 0))
134 err(EXIT_FAILURE
, "failed to assign device");
135 if (fdisk_create_disklabel(cxt
, label
))
136 err(EXIT_FAILURE
, "failed to create disk label");
138 sectorsize
= fdisk_get_sector_size(cxt
);
140 fdisk_disable_dialogs(cxt
, 1);
142 while (optind
< argc
) {
145 const char *str
= argv
[optind
];
148 fdisk_partition_start_follow_default(pa
, 1);
149 fdisk_partition_end_follow_default(pa
, 1);
150 fdisk_partition_partno_follow_default(pa
, 1);
154 size
= strtosize_or_err(argv
[optind
], "failed to parse partition size");
155 fdisk_partition_set_size(pa
, size
/ sectorsize
);
156 fdisk_partition_end_follow_default(pa
, 0);
158 } else if (*str
== '-') {
159 fdisk_partition_end_follow_default(pa
, 1);
162 if (fdisk_is_label(cxt
, DOS
)) {
163 /* For MBR we want to avoid primary/logical dialog.
164 * This is possible by explicitly specified partition
165 * number, <4 means primary, >=4 means logical.
168 fdisk_partition_partno_follow_default(pa
, 0);
169 fdisk_partition_set_partno(pa
, n
);
172 /* Make sure last primary partition is extended if user
173 * wants more than 4 partitions.
175 if (n
== 3 && optind
+ 1 < argc
) {
176 struct fdisk_parttype
*type
=
177 fdisk_label_parse_parttype(
178 fdisk_get_label(cxt
, NULL
), "05");
181 fdisk_partition_set_type(pa
, type
);
182 fdisk_unref_parttype(type
);
186 rc
= fdisk_add_partition(cxt
, pa
, NULL
);
189 errx(EXIT_FAILURE
, "failed to add #%d partition", n
+ 1);
192 fdisk_reset_partition(pa
);
197 if (fdisk_write_disklabel(cxt
))
198 err(EXIT_FAILURE
, "failed to write disk label");
200 fdisk_deassign_device(cxt
, 1);
201 fdisk_unref_context(cxt
);
202 fdisk_unref_partition(pa
);