diff options
author | Karel Zak | 2012-08-13 22:10:14 +0200 |
---|---|---|
committer | Karel Zak | 2012-08-13 22:10:14 +0200 |
commit | 8863a802eb9282d436cfb30ce69fb07f5ffb47b3 (patch) | |
tree | 3c39f653dff8dab4b361ed411e1cc28ad4d3ea4a /disk-utils/resizepart.c | |
parent | lib/sysfs; add sysfs_partno_to_devno() (diff) | |
download | kernel-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.c | 109 |
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; +} |