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 | |
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>
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | disk-utils/Makemodule.am | 9 | ||||
-rw-r--r-- | disk-utils/partx.h | 31 | ||||
-rw-r--r-- | disk-utils/resizepart.8 | 38 | ||||
-rw-r--r-- | disk-utils/resizepart.c | 109 |
5 files changed, 186 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore index d63e0e065..fbc563632 100644 --- a/.gitignore +++ b/.gitignore @@ -135,6 +135,7 @@ tests/run.sh.trs /readprofile /rename /renice +/resizepart /rev /rtcwake /sample-mkfs diff --git a/disk-utils/Makemodule.am b/disk-utils/Makemodule.am index 830e8f72f..f2360bf3b 100644 --- a/disk-utils/Makemodule.am +++ b/disk-utils/Makemodule.am @@ -113,13 +113,13 @@ endif # LINUX if BUILD_PARTX -usrsbin_exec_PROGRAMS += partx addpart delpart +usrsbin_exec_PROGRAMS += partx addpart delpart resizepart dist_man_MANS += \ disk-utils/addpart.8 \ disk-utils/delpart.8 \ + disk-utils/resizepart.8 \ disk-utils/partx.8 - addpart_SOURCES = \ disk-utils/addpart.c \ disk-utils/partx.h @@ -130,6 +130,11 @@ delpart_SOURCES = \ disk-utils/partx.h delpart_LDADD = $(LDADD) libcommon.la +resizepart_SOURCES = \ + disk-utils/resizepart.c \ + disk-utils/partx.h +resizepart_LDADD = $(LDADD) libcommon.la + partx_SOURCES = \ disk-utils/partx.c \ disk-utils/partx.h diff --git a/disk-utils/partx.h b/disk-utils/partx.h index ed0fd0aa4..254cd85cc 100644 --- a/disk-utils/partx.h +++ b/disk-utils/partx.h @@ -4,6 +4,18 @@ #include <sys/ioctl.h> #include <linux/blkpg.h> +#ifndef BLKPG_ADD_PARTITION +# define BLKPG_ADD_PARTITION 1 +#endif + +#ifndef BLKPG_DEL_PARTITION +# define BLKPG_DEL_PARTITION 2 +#endif + +#ifndef BLKPG_RESIZE_PARTITION +# define BLKPG_RESIZE_PARTITION 3 /* since Linux 3.6 */ +#endif + static inline int partx_del_partition(int fd, unsigned int partno) { struct blkpg_ioctl_arg a; @@ -41,4 +53,23 @@ static inline int partx_add_partition(int fd, int partno, return ioctl(fd, BLKPG, &a); } +static inline int partx_resize_partition(int fd, int partno, + uint64_t start, uint64_t size) +{ + struct blkpg_ioctl_arg a; + struct blkpg_partition p; + + p.pno = partno; + p.start = start << 9; + p.length = size << 9; + p.devname[0] = 0; + p.volname[0] = 0; + a.op = BLKPG_RESIZE_PARTITION; + a.flags = 0; + a.datalen = sizeof(p); + a.data = &p; + + return ioctl(fd, BLKPG, &a); +} + #endif /* UTIL_LINUX_PARTX_H */ diff --git a/disk-utils/resizepart.8 b/disk-utils/resizepart.8 new file mode 100644 index 000000000..c009cc304 --- /dev/null +++ b/disk-utils/resizepart.8 @@ -0,0 +1,38 @@ +.\" resizepart.8 -- +.\" Copyright 2012 Vivek Goyal <vgoyal@redhat.com> +.\" Copyright 2012 Red Hat, Inc. +.\" May be distributed under the GNU General Public License +.TH RESIZEPART 8 "February 2012" "util-linux" "System Administration" +.SH NAME +resizepart \- +simple wrapper around the "resize partition" ioctl +.SH SYNOPSIS +.B resizepart +.I device partition length +.SH DESCRIPTION +.B resizepart +is a program that informs the Linux kernel of new partition size. + +This command doesn't manipulate partitions on hard drive. + +.SH PARAMETERS +.TP +.I device +Specify the disk device. +.TP +.I partition +Specify the partition number. +.TP +.I length +Specify the length of the partition (in 512-byte sectors). + +.SH SEE ALSO +.BR addpart (8), +.BR delpart (8), +.BR fdisk (8), +.BR parted (8), +.BR partprobe (8), +.BR partx (8) +.SH AVAILABILITY +The resizepart command is part of the util-linux package and is available from +ftp://ftp.kernel.org/pub/linux/utils/util-linux/. 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; +} |