Hi Jari,

some of our users [in Debian] are starting to expect new 
options that have been added to losetup in util-linux-ng to
work with the loop-AES version of losetup as well.

This is starting to cause other packages and scripts to
break when users use loop-AES patched losetup. In particular,
someone reported to me that -f ("show next free loop") is
expected by a package in Debian and missing in loop-AES.

As a sort of stopgap measure I've written the attached patch
adding support for a limited version of option -f that just
allows to print the next free loop device.

As hpa pointed out in a discussion on the util-linux-ng list [1],
use of the -f option is inherently racy, which is why another 
way of calling losetup has been added (losetup -s -f <device>)
to find a free loop and set it up in one step.

So, the support this patch adds is imperfect, but provides at
least some rudimentary compatibility for users.

[1] http://thread.gmane.org/gmane.linux.utilities.util-linux-ng/241

        Max
diff -urNad trunk~/mount/lomount.c trunk/mount/lomount.c
--- trunk~/mount/lomount.c	2008-08-19 20:19:35.000000000 +0200
+++ trunk/mount/lomount.c	2008-08-19 20:19:53.000000000 +0200
@@ -163,7 +163,6 @@
 
 #define SIZE(a) (sizeof(a)/sizeof(a[0]))
 
-#if !defined(MAIN)
 char *
 find_unused_loop_device (void) {
 	/* Just creating a device, say in /tmp, is probably a bad idea -
@@ -205,6 +204,7 @@
 	return 0;
 }
 
+#if !defined(MAIN)
 int is_loop_active(const char *dev, const char *backdev)
 {
 	int fd;
@@ -1081,12 +1081,13 @@
   %s -F [options] loop_device [file]   # setup, read /etc/fstab\n\
   %s loop_device                       # give info\n\
   %s -a                                # give info of all loops\n\
+  %s -f                                # show next free loop device\n\
   %s -d loop_device                    # delete\n\
   %s -R loop_device                    # resize\n\
 options:  -e encryption  -o offset  -s sizelimit  -p passwdfd  -T  -S pseed\n\
           -H phash  -I loinit  -K gpgkey  -G gpghome  -C itercountk  -v  -r\n\
           -P cleartextkey\n"),
-		progname, progname, progname, progname, progname, progname);
+		progname, progname, progname, progname, progname, progname, progname);
 	exit(1);
 }
 
@@ -1252,7 +1253,8 @@
 int
 main(int argc, char **argv) {
 	char *partitionName = NULL;
-	int delete,c,option_a=0,option_F=0,option_R=0,setup_o=0;
+	char *device = NULL;
+	int delete,find,c,option_a=0,option_F=0,option_R=0,setup_o=0;
 	int res = 0;
 	int ro = 0;
 
@@ -1260,9 +1262,9 @@
 	bindtextdomain(PACKAGE, LOCALEDIR);
 	textdomain(PACKAGE);
 
-	delete = 0;
+	delete = find = 0;
 	progname = argv[0];
-	while ((c = getopt(argc,argv,"aC:de:FG:H:I:K:o:p:P:rRs:S:Tv")) != -1) {
+	while ((c = getopt(argc,argv,"aC:de:fFG:H:I:K:o:p:P:rRs:S:Tv")) != -1) {
 		switch (c) {
 		case 'a':		/* show status of all loops */
 			option_a = 1;
@@ -1278,6 +1280,9 @@
 			loopEncryptionType = optarg;
 			setup_o = 1;
 			break;
+		case 'f':		/* find free loop */
+			find = 1;
+			break;
 		case 'F':		/* read loop related options from /etc/fstab */
 			option_F = 1;
 			setup_o = 1;
@@ -1336,12 +1341,22 @@
 			usage();
 		}
 	}
-	if (option_a + delete + option_R + setup_o > 1) usage();
+	if (option_a + delete + option_R + setup_o + find > 1) usage();
 	if (option_a) {
 		/* show all loops */
 		if (argc != optind) usage();
 		show_all_loops();
 		res = 0;
+	} else if (find) {
+		if (argc != optind)
+			usage();
+		device = find_unused_loop_device();
+		if (device == NULL)
+			return -1;
+		if (verbose)
+			printf("Loop device is %s\n", device);
+		printf("%s\n", device);
+		res = 0;
 	} else if (delete) {
 		/* delete loop */
 		if (argc != optind+1) usage();
diff -urNad trunk~/mount/losetup.8 trunk/mount/losetup.8
--- trunk~/mount/losetup.8	2008-08-19 20:19:35.000000000 +0200
+++ trunk/mount/losetup.8	2008-08-19 20:19:35.000000000 +0200
@@ -21,6 +21,8 @@
 .br
 .B losetup -a
 .br
+.B losetup -f
+.br
 .B losetup
 .B \-R
 .I loop_device
@@ -64,6 +66,8 @@
 configuration or corresponding modules have been loaded to kernel.
 .PD
 .RE
+.IP "\fB\-f\fP"
+Find and show next unused loop device.
 .IP "\fB\-F\fP"
 Reads and uses mount options from /etc/fstab that match specified loop
 device, including offset= sizelimit= encryption= pseed= phash= loinit=

Reply via email to