On Tue, Aug 16, 2011 at 09:20:07AM -0400, Davidlohr Bueso wrote: > +static int loopmod_supports_parts(void) > +{ > + int rc, ret = 0; > + FILE *f = fopen("/sys/module/loop/parameters/max_part", "r"); > + > + if (!f) > + return 0; > + rc = fscanf(f, "%d", &ret); > + fclose(f); > + return ret; return rc = 1 ? ret : 0; Right? > +} > + > +static void assoc_loopdev(const char *fname) > +{ [...] > + err(EXIT_FAILURE, "failed to find unused device"); > + printf("Trying to use '%s' for the loop device\n", loopcxt_get_device(&lc)); > + err(EXIT_FAILURE, "failed to set backing file"); > + err(EXIT_FAILURE, "failed to setup device for %s", fname); you forgot _( ) > + if (stat(wholedisk, &x) || !S_ISBLK(x.st_mode) && S_ISREG(x.st_mode)) { || && :-) > + /* not a blkdev, try to associate it to a loop device */ > + if (what == ACT_DELETE) > + errx(EXIT_FAILURE, _("%s: cannot delete partitions"), wholedisk); > + > + if (!loopmod_supports_parts()) > + errx(EXIT_FAILURE, _("%s: does not support loop device partitions"), > + wholedisk); > + assoc_loopdev(wholedisk); > + wholedisk = xstrdup(lc.device); > + } Fixed (see below), applied to may private repository. Thanks. Note that Kay's loopdev changes are in Linus' tree, so we can start to play with that (kernel will not add all partition). Karel >From 0e9381133e2d4a79715d5b9e2326198f8ed72d35 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso <dave@xxxxxxx> Date: Tue, 16 Aug 2011 09:20:07 -0400 Subject: [PATCH] partx: support loop devices Add support for loop devices to add partitions. For now we make use of the max_part parameter from the loop kernel module, otherwise the feature is disabled. Below an example output: root@offbook:~/projects/util-linux/partx# ./partx -a -n 1:5 images-pt/dos+bsd.img root@offbook:~/projects/util-linux/partx# ls /dev/loop0* -ltr brw-rw---- 1 root disk 7, 0 2011-08-15 00:07 /dev/loop0 brw-rw---- 1 root disk 7, 5 2011-08-15 00:07 /dev/loop0p5 brw-rw---- 1 root disk 7, 2 2011-08-15 00:07 /dev/loop0p2 brw-rw---- 1 root disk 7, 1 2011-08-15 00:07 /dev/loop0p1 Signed-off-by: Davidlohr Bueso <dave@xxxxxxx> Signed-off-by: Karel Zak <kzak@xxxxxxxxxx> --- partx/Makefile.am | 2 + partx/partx.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/partx/Makefile.am b/partx/Makefile.am index 6a72942..080bc47 100644 --- a/partx/Makefile.am +++ b/partx/Makefile.am @@ -11,6 +11,8 @@ partx_SOURCES = partx.c partx.h \ $(top_srcdir)/lib/at.c \ $(top_srcdir)/lib/mbsalign.c \ $(top_srcdir)/lib/strutils.c \ + $(top_srcdir)/lib/canonicalize.c \ + $(top_srcdir)/lib/loopdev.c \ $(top_srcdir)/lib/linux_version.c partx_CFLAGS = -I$(ul_libblkid_incdir) diff --git a/partx/partx.c b/partx/partx.c index ca19344..3a9da9e 100644 --- a/partx/partx.c +++ b/partx/partx.c @@ -31,6 +31,7 @@ #include "xalloc.h" #include "partx.h" #include "sysfs.h" +#include "loopdev.h" #include "at.h" /* this is the default upper limit, could be modified by --nr */ @@ -88,7 +89,51 @@ static int columns[__NCOLUMNS], ncolumns; static int verbose; static int partx_flags; +static struct loopdev_cxt lc; +static int loopdev; +/* + * Check if the kernel supports partitioned loop devices. + * In a near future (around linux 3.2, hopefully) this will come + * always out of the box, until then we need to check. + */ +static int loopmod_supports_parts(void) +{ + int rc, ret = 0; + FILE *f = fopen("/sys/module/loop/parameters/max_part", "r"); + + if (!f) + return 0; + rc = fscanf(f, "%d", &ret); + fclose(f); + return rc = 1 ? ret : 0; +} + +static void assoc_loopdev(const char *fname) +{ + int rc; + + loopcxt_init(&lc, 0); + + rc = loopcxt_find_unused(&lc); + if (rc) + err(EXIT_FAILURE, _("%s: failed to find unused loop device"), + fname); + + if (verbose) + printf(_("Trying to use '%s' for the loop device\n"), + loopcxt_get_device(&lc)); + + if (loopcxt_set_backing_file(&lc, fname)) + err(EXIT_FAILURE, _("%s: failed to set backing file"), fname); + + rc = loopcxt_setup_device(&lc); + + if (rc == -EBUSY) + err(EXIT_FAILURE, _("%s: failed to setup loop device"), fname); + + loopdev = 1; +} static inline int get_column_id(int num) { @@ -278,6 +323,7 @@ static int del_parts(int fd, const char *device, dev_t devno, return rc; } + static void add_parts_warnx(const char *device, int first, int last) { if (first == last) @@ -288,7 +334,7 @@ static void add_parts_warnx(const char *device, int first, int last) } static int add_parts(int fd, const char *device, - blkid_partlist ls, int lower, int upper) + blkid_partlist ls, int lower, int upper) { int i, nparts, rc = 0, errfirst = 0, errlast = 0; @@ -338,6 +384,19 @@ static int add_parts(int fd, const char *device, if (errfirst) add_parts_warnx(device, errfirst, errlast); + + /* the kernel adds *all* loopdev partitions, so we should delete + any extra, unwanted ones, when the -n option is passed */ + if (loopdev && (lower || upper)) { + for (i = 0; i < nparts; i++) { + blkid_partition par = blkid_partlist_get_partition(ls, i); + int n = blkid_partition_get_partno(par); + + if (n < lower || n > upper) + partx_del_partition(fd, n); + } + } + return rc; } @@ -799,7 +858,20 @@ int main(int argc, char **argv) if (what == ACT_ADD || what == ACT_DELETE) { struct stat x; - if (stat(wholedisk, &x) || !S_ISBLK(x.st_mode)) + if (stat(wholedisk, &x)) + errx(EXIT_FAILURE, "%s", wholedisk); + + if (S_ISREG(x.st_mode)) { + /* not a blkdev, try to associate it to a loop device */ + if (what == ACT_DELETE) + errx(EXIT_FAILURE, _("%s: cannot delete partitions"), + wholedisk); + if (!loopmod_supports_parts()) + errx(EXIT_FAILURE, _("%s: partitioned loop devices unsupported"), + wholedisk); + assoc_loopdev(wholedisk); + wholedisk = xstrdup(lc.device); + } else if (!S_ISBLK(x.st_mode)) errx(EXIT_FAILURE, _("%s: not a block device"), wholedisk); } if ((fd = open(wholedisk, O_RDONLY)) == -1) @@ -845,6 +917,9 @@ int main(int argc, char **argv) blkid_free_probe(pr); } + if (loopdev) + loopcxt_deinit(&lc); + close(fd); return rc ? EXIT_FAILURE : EXIT_SUCCESS; } -- 1.7.6 -- To unsubscribe from this list: send the line "unsubscribe util-linux" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html