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=