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 all required partition
9 * properties (partno, start and size). The default is only partition type
10 * (except MBR where 4th partition is extended).
16 #include <sys/types.h>
28 static int ask_callback(struct fdisk_context
*cxt
__attribute__((__unused__
)),
29 struct fdisk_ask
*ask
,
32 switch(fdisk_ask_get_type(ask
)) {
33 case FDISK_ASKTYPE_INFO
:
34 fputs(fdisk_ask_print_get_mesg(ask
), stdout
);
37 case FDISK_ASKTYPE_WARNX
:
39 fputs(fdisk_ask_print_get_mesg(ask
), stderr
);
42 case FDISK_ASKTYPE_WARN
:
44 fputs(fdisk_ask_print_get_mesg(ask
), stderr
);
45 errno
= fdisk_ask_print_get_errno(ask
);
46 fprintf(stderr
, ": %m\n");
54 int main(int argc
, char *argv
[])
56 struct fdisk_context
*cxt
;
57 struct fdisk_partition
*pa
;
58 const char *label
= NULL
, *device
= NULL
;
62 static const struct option longopts
[] = {
63 { "label", required_argument
, NULL
, 'x' },
64 { "device", required_argument
, NULL
, 'd' },
65 { "help", no_argument
, NULL
, 'h' },
69 setlocale(LC_ALL
, ""); /* just to have enable UTF8 chars */
73 while((c
= getopt_long(argc
, argv
, "x:d:h", longopts
, NULL
)) != -1) {
82 printf("%s [options] -- <partno,start,size> ...", program_invocation_short_name
);
83 fputs(USAGE_SEPARATOR
, stdout
);
84 puts("Make disklabel and partitions.");
85 puts(" <partno> 1..n (4th is extended for MBR), or '-' for default");
86 puts(" <start> partition start offset in sectors");
87 puts(" <size> partition size in sectors");
88 fputs(USAGE_OPTIONS
, stdout
);
89 puts(" -x, --label <dos,gpt,...> disk label type (default MBR)");
90 puts(" -d, --device <path> block device");
91 puts(" -h, --help this help");
92 fputs(USAGE_SEPARATOR
, stdout
);
98 errx(EXIT_FAILURE
, "no device specified");
102 cxt
= fdisk_new_context();
105 fdisk_set_ask(cxt
, ask_callback
, NULL
);
107 pa
= fdisk_new_partition();
111 if (fdisk_assign_device(cxt
, device
, 0))
112 err(EXIT_FAILURE
, "failed to assign device");
113 if (fdisk_create_disklabel(cxt
, label
))
114 err(EXIT_FAILURE
, "failed to create disk label");
116 fdisk_disable_dialogs(cxt
, 1);
118 while (optind
< argc
) {
120 unsigned int partno
= 0;
121 uint64_t start
= 0, size
= 0;
122 const char *str
= argv
[optind
];
124 fdisk_reset_partition(pa
);
125 fdisk_partition_end_follow_default(pa
, 0);
128 /* partno unspecified */
129 if (sscanf(str
, "-,%"SCNu64
",%"SCNu64
"", &start
, &size
) != 2)
130 errx(EXIT_FAILURE
, "failed to parse %s", str
);
131 fdisk_partition_partno_follow_default(pa
, 1);
132 fdisk_partition_unset_partno(pa
);
134 /* partno specified */
135 if (sscanf(str
, "%u,%"SCNu64
",%"SCNu64
"", &partno
, &start
, &size
) != 3)
136 errx(EXIT_FAILURE
, "failed to parse %s", str
);
138 fdisk_partition_partno_follow_default(pa
, 0);
139 fdisk_partition_set_partno(pa
, partno
- 1); /* library uses 0..n */
142 fdisk_partition_set_start(pa
, start
);
143 fdisk_partition_set_size(pa
, size
);
145 if (fdisk_partition_has_partno(pa
))
146 fprintf(stderr
, "Requested partition: <partno=%zu,start=%ju,size=%ju>\n",
147 fdisk_partition_get_partno(pa
),
148 (uintmax_t) fdisk_partition_get_start(pa
),
149 (uintmax_t) fdisk_partition_get_size(pa
));
151 fprintf(stderr
, "Requested partition: <partno=<default>,start=%ju,size=%ju>\n",
152 (uintmax_t) fdisk_partition_get_start(pa
),
153 (uintmax_t) fdisk_partition_get_size(pa
));
155 if (fdisk_is_label(cxt
, DOS
)) {
156 /* Make sure last primary partition is extended if user
157 * wants more than 4 partitions.
159 if ((partno
== 4 || (n
== 4 && !fdisk_partition_has_partno(pa
)))
160 && optind
+ 1 < argc
) {
161 struct fdisk_parttype
*type
=
162 fdisk_label_parse_parttype(
163 fdisk_get_label(cxt
, NULL
), "05");
166 fdisk_partition_set_type(pa
, type
);
167 fdisk_unref_parttype(type
);
171 rc
= fdisk_add_partition(cxt
, pa
, NULL
);
174 errx(EXIT_FAILURE
, "failed to add #%zu partition",
175 fdisk_partition_has_partno(pa
) ?
176 fdisk_partition_get_partno(pa
) + 1: n
);
179 fdisk_reset_partition(pa
);
184 if (fdisk_write_disklabel(cxt
))
185 err(EXIT_FAILURE
, "failed to write disk label");
187 fdisk_deassign_device(cxt
, 1);
188 fdisk_unref_context(cxt
);
189 fdisk_unref_partition(pa
);