]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
resizepart: add new command
authorKarel Zak <kzak@redhat.com>
Mon, 13 Aug 2012 20:10:14 +0000 (22:10 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 13 Aug 2012 20:10:14 +0000 (22:10 +0200)
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>
.gitignore
disk-utils/Makemodule.am
disk-utils/partx.h
disk-utils/resizepart.8 [new file with mode: 0644]
disk-utils/resizepart.c [new file with mode: 0644]

index d63e0e065dba4adbe7310a9c603ca7da2cf3e0ef..fbc563632181fe160fcc724111f9d6ea1b19236b 100644 (file)
@@ -135,6 +135,7 @@ tests/run.sh.trs
 /readprofile
 /rename
 /renice
+/resizepart
 /rev
 /rtcwake
 /sample-mkfs
index 830e8f72fb09ecf4d9bac578a412640720594562..f2360bf3b9968b9f800b286e0224a5fe6d2bfbf0 100644 (file)
@@ -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
index ed0fd0aa422840e679c6851520e1e8c8662f92c1..254cd85cc6538960b0df6945f01904bbc61b1be3 100644 (file)
@@ -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 (file)
index 0000000..c009cc3
--- /dev/null
@@ -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 (file)
index 0000000..ad8a7b6
--- /dev/null
@@ -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;
+}