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
;
72 unsigned int sectorsize
;
74 static const struct option longopts
[] = {
75 { "label", required_argument
, NULL
, 'x' },
76 { "device", required_argument
, NULL
, 'd' },
77 { "help", no_argument
, NULL
, 'h' },
81 setlocale(LC_ALL
, ""); /* just to have enable UTF8 chars */
85 while((c
= getopt_long(argc
, argv
, "x:d:h", longopts
, NULL
)) != -1) {
94 printf("%s [options] <size> ...", program_invocation_short_name
);
95 fputs(USAGE_SEPARATOR
, stdout
);
96 fputs("Make disklabel and partitions.\n", stdout
);
97 fputs(USAGE_OPTIONS
, stdout
);
98 fputs(" -x, --label <dos,gpt,...> disk label type\n", stdout
);
99 fputs(" -d, --device <path> block device\n", stdout
);
100 fputs(" -h, --help this help\n", stdout
);
101 fputs(USAGE_SEPARATOR
, stdout
);
107 errx(EXIT_FAILURE
, "no device specified");
111 cxt
= fdisk_new_context();
114 fdisk_set_ask(cxt
, ask_callback
, NULL
);
116 pa
= fdisk_new_partition();
120 if (fdisk_assign_device(cxt
, device
, 0))
121 err(EXIT_FAILURE
, "failed to assign device");
122 if (fdisk_create_disklabel(cxt
, label
))
123 err(EXIT_FAILURE
, "failed to create disk label");
125 sectorsize
= fdisk_get_sector_size(cxt
);
127 while (optind
< argc
) {
130 const char *str
= argv
[optind
];
133 fdisk_partition_start_follow_default(pa
, 1);
134 fdisk_partition_end_follow_default(pa
, 1);
138 size
= strtosize_or_err(argv
[optind
], "failed to parse partition size");
139 fdisk_partition_set_size(pa
, size
/ sectorsize
);
140 fdisk_partition_end_follow_default(pa
, 0);
142 } else if (*str
== '-') {
143 fdisk_partition_end_follow_default(pa
, 1);
146 if (fdisk_is_label(cxt
, DOS
)) {
147 /* For MBR we want to avoid primary/logical dialog.
148 * This is possible by explicitly specified partition
149 * number, <4 means primary, >=4 means logical.
151 fdisk_partition_partno_follow_default(pa
, 0);
152 fdisk_partition_set_partno(pa
, n
);
154 /* Make sure last primary partition is extended if user
155 * wants more than 4 partitions.
157 if (n
== 3 && optind
+ 1 < argc
) {
158 struct fdisk_parttype
*type
=
159 fdisk_label_parse_parttype(
160 fdisk_get_label(cxt
, NULL
), "05");
163 fdisk_partition_set_type(pa
, type
);
164 fdisk_unref_parttype(type
);
167 fdisk_partition_partno_follow_default(pa
, 1);
170 rc
= fdisk_add_partition(cxt
, pa
, NULL
);
173 errx(EXIT_FAILURE
, "failed to add #%d partition", n
+ 1);
176 fdisk_reset_partition(pa
);
181 if (fdisk_write_disklabel(cxt
))
182 err(EXIT_FAILURE
, "failed to write disk label");
184 fdisk_deassign_device(cxt
, 1);
185 fdisk_unref_context(cxt
);
186 fdisk_unref_partition(pa
);