Hi all, I'm looking for a user-friendly way to manage automated fsck of encrypted loop devices during boot. The current way of managing fscks (losetup -F, fsck, losetup -d, mount) has one big downside from a usability perspective: It requires the user to enter the passphrase twice each time the system boots. Today I thought of something else that could work, I'm attaching a quick proof-of-concept patch to describe it. The idea is that we could do losetup -F, fsck, leave the loop device allocated and have mount later re-use the loop device. It would require no changes apart from an optional init script to take care of the fsck. What do you think about this approach? cheers, Max -- PS: If you are interested, this is one of the last points I want to solve before integrating loop-AES support into a release version of Debian installer -- wiki.debian.org/DebianInstaller/PartmanCrypto The show-stopper bug mentioned is the lack of automated fsck.
--- 2.12r/mount/mount.c~ 2006-04-08 16:36:47.000000000 +0200 +++ 2.12r/mount/mount.c 2006-04-08 16:34:19.000000000 +0200 @@ -682,6 +682,10 @@ if (fake) { if (verbose) printf(_("mount: skipping the setup of a loop device\n")); + } else if (*loopdev && is_loop_in_use(*loopdev)) { + if (verbose) + printf(_("mount: skipping the setup of a loop device\n")); + *spec = *loopdev; } else { int loopro = (*flags & MS_RDONLY); --- 2.12r/mount/lomount.h~ 2006-04-08 16:36:47.000000000 +0200 +++ 2.12r/mount/lomount.h 2006-04-08 16:24:22.000000000 +0200 @@ -2,6 +2,7 @@ extern int set_loop(const char *, const char *, int *, const char **, unsigned int *); extern int del_loop(const char *); extern int is_loop_device(const char *); +extern int is_loop_in_use(const char *); extern char * find_unused_loop_device(void); extern char *passFDnumber; --- 2.12r/mount/lomount.c~ 2006-04-08 16:36:47.000000000 +0200 +++ 2.12r/mount/lomount.c 2006-04-08 16:25:32.000000000 +0200 @@ -202,6 +202,22 @@ return 0; } +int is_loop_in_use(const char *dev) +{ + int fd; + int ret = 0; + struct stat statbuf; + if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) { + fd = open (dev, O_RDONLY); + if (fd >= 0) { + if (is_unused_loop_device(fd) == 0) + ret = 1; /* in use */ + close(fd); + } + } + return ret; +} + static int rd_wr_retry(int fd, char *buf, int cnt, int w) { int x, y, z;
#!/bin/sh list_fsck_loops () { egrep -v '^#' /etc/fstab | while read dev mnt fstype opts freq passno; do fsck=yes loopdev= for opt in $(IFS=, && echo $opts); do case $opt in noauto|sw) fsck=no ;; loop=/dev/loop*) loopdev=${opt#loop=} ;; esac done if [ -z "$loopdev" ] || [ "$fsck" = no ]; then continue fi echo $loopdev done } for dev in $(list_fsck_loops); do echo /sbin/losetup -F $dev echo distro_specific_fsck_foo $dev done