]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: add sample-fdisk-mkpart-fullspec
authorKarel Zak <kzak@redhat.com>
Tue, 11 Jul 2017 11:00:46 +0000 (13:00 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 11 Jul 2017 11:00:46 +0000 (13:00 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
libfdisk/samples/Makemodule.am
libfdisk/samples/mkpart-fullspec.c [new file with mode: 0644]
libfdisk/samples/mkpart.c

index d7c0cfa78833b9db2c9aa5247bceaf202bc559bb..b67b12183ad00c11dcc011e3300b7bd692f1a039 100644 (file)
@@ -1,6 +1,7 @@
 
 check_PROGRAMS += \
-       sample-fdisk-mkpart
+       sample-fdisk-mkpart \
+       sample-fdisk-mkpart-fullspec
 
 sample_fdisk_cflags = $(AM_CFLAGS) $(NO_UNUSED_WARN_CFLAGS) \
                       -I$(ul_libfdisk_incdir)
@@ -9,3 +10,7 @@ sample_fdisk_ldadd = $(LDADD) libfdisk.la
 sample_fdisk_mkpart_SOURCES = libfdisk/samples/mkpart.c
 sample_fdisk_mkpart_LDADD = $(sample_fdisk_ldadd) libcommon.la
 sample_fdisk_mkpart_CFLAGS = $(sample_fdisk_cflags)
+
+sample_fdisk_mkpart_fullspec_SOURCES = libfdisk/samples/mkpart-fullspec.c
+sample_fdisk_mkpart_fullspec_LDADD = $(sample_fdisk_ldadd) libcommon.la
+sample_fdisk_mkpart_fullspec_CFLAGS = $(sample_fdisk_cflags)
diff --git a/libfdisk/samples/mkpart-fullspec.c b/libfdisk/samples/mkpart-fullspec.c
new file mode 100644 (file)
index 0000000..e566ced
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2017 Karel Zak <kzak@redhat.com>
+ *
+ * This file may be redistributed under the terms of the
+ * GNU Lesser General Public License.
+ *
+ *
+ * Libfdisk sample to create partitions by specify all required partition
+ * properties (partno, start and size). The defauls is only partition type
+ * (except MBR where 4th partition is extended).
+ */
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <getopt.h>
+
+#include "c.h"
+#include "nls.h"
+#include "strutils.h"
+#include "xalloc.h"
+
+#include "libfdisk.h"
+
+static int ask_callback(struct fdisk_context *cxt __attribute__((__unused__)),
+                       struct fdisk_ask *ask,
+                       void *data)
+{
+       switch(fdisk_ask_get_type(ask)) {
+       case FDISK_ASKTYPE_INFO:
+               fputs(fdisk_ask_print_get_mesg(ask), stdout);
+               fputc('\n', stdout);
+               break;
+       case FDISK_ASKTYPE_WARNX:
+               fflush(stdout);
+               fputs(fdisk_ask_print_get_mesg(ask), stderr);
+               fputc('\n', stderr);
+               break;
+       case FDISK_ASKTYPE_WARN:
+               fflush(stdout);
+               fputs(fdisk_ask_print_get_mesg(ask), stderr);
+               errno = fdisk_ask_print_get_errno(ask);
+               fprintf(stderr, ": %m\n");
+               break;
+       default:
+               break;
+       }
+       return 0;
+}
+
+int main(int argc, char *argv[])
+{
+       struct fdisk_context *cxt;
+       struct fdisk_partition *pa;
+       const char *label = NULL, *device = NULL;
+       int c;
+
+       static const struct option longopts[] = {
+               { "label",  required_argument, NULL, 'x' },
+               { "device", required_argument, NULL, 'd' },
+               { "help",   no_argument, NULL, 'h' },
+               { NULL, 0, NULL, 0 },
+       };
+
+       setlocale(LC_ALL, "");  /* just to have enable UTF8 chars */
+
+       fdisk_init_debug(0);
+
+       while((c = getopt_long(argc, argv, "x:d:h", longopts, NULL)) != -1) {
+               switch(c) {
+               case 'x':
+                       label = optarg;
+                       break;
+               case 'd':
+                       device = optarg;
+                       break;
+               case 'h':
+                       printf("%s [options] <partno,start,size> ...", program_invocation_short_name);
+                       fputs(USAGE_SEPARATOR, stdout);
+                       puts("Make disklabel and partitions.");
+                       puts(" <partno>                     number from 1..n (4th is extended for MBR)");
+                       puts(" <start>                      partition start offset in sectors");
+                       puts(" <size>                       partition size in sectors");
+                       fputs(USAGE_OPTIONS, stdout);
+                       puts(" -x, --label <dos,gpt,...>    disk label type (default MBR)");
+                       puts(" -d, --device <path>          block device");
+                       puts(" -h, --help                   this help");
+                       fputs(USAGE_SEPARATOR, stdout);
+                       return EXIT_SUCCESS;
+               }
+       }
+
+       if (!device)
+               errx(EXIT_FAILURE, "no device specified");
+       if (!label)
+               label = "dos";
+
+       cxt = fdisk_new_context();
+       if (!cxt)
+               err_oom();
+       fdisk_set_ask(cxt, ask_callback, NULL);
+
+       pa = fdisk_new_partition();
+       if (!pa)
+               err_oom();
+
+       if (fdisk_assign_device(cxt, device, 0))
+               err(EXIT_FAILURE, "failed to assign device");
+       if (fdisk_create_disklabel(cxt, "dos"))
+               err(EXIT_FAILURE, "failed to create disk label");
+
+       while (optind < argc) {
+               int rc;
+               unsigned int partno = 0;
+               uint64_t start = 0, size = 0;
+               const char *str = argv[optind];
+
+               if (sscanf(str, "%u,%ju,%ju", &partno, &start, &size) != 3)
+                       errx(EXIT_FAILURE, "faild to parse %s", str);
+
+               /* disable defaults */
+               fdisk_partition_partno_follow_default(pa, 0);
+               fdisk_partition_end_follow_default(pa, 0);
+
+               /* set all */
+               fdisk_partition_set_partno(pa, partno - 1);     /* library uses 0..n */
+               fdisk_partition_set_start(pa, start);
+               fdisk_partition_set_size(pa, size);
+
+               fprintf(stderr, "Requested partition: <partno=%zu,start=%ju,size=%ju>\n",
+                               fdisk_partition_get_partno(pa),
+                               fdisk_partition_get_start(pa),
+                               fdisk_partition_get_size(pa));
+
+               if (fdisk_is_label(cxt, DOS)) {
+                       /* Make sure last primary partition is extended if user
+                        * wants more than 4 partitions.
+                        */
+                       if (partno == 4 && optind + 1 < argc) {
+                               struct fdisk_parttype *type =
+                                       fdisk_label_parse_parttype(
+                                                       fdisk_get_label(cxt, NULL), "05");
+                               if (!type)
+                                       err_oom();
+                               fdisk_partition_set_type(pa, type);
+                               fdisk_unref_parttype(type);
+                       }
+               }
+
+               rc = fdisk_add_partition(cxt, pa, NULL);
+               if (rc) {
+                       errno = -rc;
+                       err(EXIT_FAILURE, "failed to add #%d partition", partno);
+               }
+
+               fdisk_reset_partition(pa);
+               optind++;
+       }
+
+       if (fdisk_write_disklabel(cxt))
+               err(EXIT_FAILURE, "failed to write disk label");
+
+       fdisk_deassign_device(cxt, 1);
+       fdisk_unref_context(cxt);
+       fdisk_unref_partition(pa);
+
+       return EXIT_SUCCESS;
+}
index 4ca3ed35db2ce96cf143602977e2461044b5f83c..44a97d6fd41e98e2d1137d983aa9348428b3c081 100644 (file)
@@ -3,7 +3,24 @@
  *
  * This file may be redistributed under the terms of the
  * GNU Lesser General Public License.
- */
+ *
+ *
+ * Libfdisk sample to create partitions by specify size, for example:
+ *
+ *     mkpart --label dos --device /dev/sdc 2M 2M 2M 10M 1M -
+ *
+  * creates 6 partitions:
+  *    - 3 primary  (3x 2M)
+  *    - 1 extended (1x 10M)
+  *    - 2 logical  (1x 1M, 1x remaining-space-in-extended-partition)
+  *
+  * Notes:
+  *     The sample specifies size and partno for MBR, and size only for another
+  *     labels (e.g. GPT).
+  *
+  *     The Ask-API does not use anything else than warning/info. The
+  *     partitionning has to be done non-interactive.
+  */
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>