summaryrefslogtreecommitdiffstats
path: root/disk-utils/resizepart.c
diff options
context:
space:
mode:
authorKarel Zak2012-08-13 22:10:14 +0200
committerKarel Zak2012-08-13 22:10:14 +0200
commit8863a802eb9282d436cfb30ce69fb07f5ffb47b3 (patch)
tree3c39f653dff8dab4b361ed411e1cc28ad4d3ea4a /disk-utils/resizepart.c
parentlib/sysfs; add sysfs_partno_to_devno() (diff)
downloadkernel-qcow2-util-linux-8863a802eb9282d436cfb30ce69fb07f5ffb47b3.tar.gz
kernel-qcow2-util-linux-8863a802eb9282d436cfb30ce69fb07f5ffb47b3.tar.xz
kernel-qcow2-util-linux-8863a802eb9282d436cfb30ce69fb07f5ffb47b3.zip
resizepart: add new command
This is a simple wrapper for BLKPG_RESIZE_PARTITION (since kernel 3.6). Co-Author: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'disk-utils/resizepart.c')
-rw-r--r--disk-utils/resizepart.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/disk-utils/resizepart.c b/disk-utils/resizepart.c
new file mode 100644
index 000000000..ad8a7b606
--- /dev/null
+++ b/disk-utils/resizepart.c
@@ -0,0 +1,109 @@
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "c.h"
+#include "nls.h"
+#include "partx.h"
+#include "sysfs.h"
+#include "strutils.h"
+
+static void __attribute__ ((__noreturn__)) usage(FILE * out)
+{
+ fputs(USAGE_HEADER, out);
+ fprintf(out, _(" %s <disk device> <partition number> <length>\n"),
+ program_invocation_short_name);
+ fputs(USAGE_OPTIONS, out);
+ fputs(USAGE_HELP, out);
+ fputs(USAGE_VERSION, out);
+ fprintf(out, USAGE_MAN_TAIL("resizepart(8)"));
+ exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
+}
+
+static int get_partition_start(int fd, int partno, uint64_t *start)
+{
+ struct stat st;
+ struct sysfs_cxt disk = UL_SYSFSCXT_EMPTY,
+ part = UL_SYSFSCXT_EMPTY;
+ dev_t devno = 0;
+ int rc = -1;
+
+ /*
+ * wholedisk
+ */
+ if (fstat(fd, &st) || !S_ISBLK(st.st_mode))
+ goto done;
+ devno = st.st_rdev;
+ if (sysfs_init(&disk, devno, NULL))
+ goto done;
+ /*
+ * partition
+ */
+ devno = sysfs_partno_to_devno(&disk, partno);
+ if (!devno)
+ goto done;
+ if (sysfs_init(&part, devno, &disk))
+ goto done;
+ if (sysfs_read_u64(&part, "start", start))
+ goto done;
+
+ rc = 0;
+done:
+ sysfs_deinit(&part);
+ sysfs_deinit(&disk);
+ return rc;
+}
+
+int main(int argc, char **argv)
+{
+ int c, fd, partno;
+ const char *wholedisk;
+ uint64_t start;
+
+ static const struct option longopts[] = {
+ {"help", no_argument, 0, 'h'},
+ {"version", no_argument, 0, 'V'},
+ {NULL, no_argument, 0, '0'},
+ };
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ while ((c = getopt_long(argc, argv, "Vh", longopts, NULL)) != -1)
+ switch (c) {
+ case 'V':
+ printf(UTIL_LINUX_VERSION);
+ return EXIT_SUCCESS;
+ case 'h':
+ usage(stdout);
+ default:
+ usage(stderr);
+ }
+
+ if (argc != 4)
+ usage(stderr);
+
+ wholedisk = argv[1];
+ partno = strtou32_or_err(argv[2], _("invalid partition number argument"));
+
+ if ((fd = open(wholedisk, O_RDONLY)) < 0)
+ err(EXIT_FAILURE, _("cannot open %s"), wholedisk);
+
+ if (get_partition_start(fd, partno, &start))
+ err(EXIT_FAILURE, _("%s: failed to get start of the partition number %s"),
+ wholedisk, argv[2]);
+
+ fprintf(stderr, "KZAK: %d, start=%jd\n", partno, start);
+ exit(1);
+
+ if (partx_resize_partition(fd, partno, start,
+ strtou64_or_err(argv[3], _("invalid length argument"))))
+ err(EXIT_FAILURE, _("failed to resize partition"));
+
+ return 0;
+}