Allocate free loop devices instead of using hardcoded.
authorMilan Broz <gmazyland@gmail.com>
Thu, 10 Mar 2011 20:18:40 +0000 (20:18 +0000)
committerMilan Broz <gmazyland@gmail.com>
Thu, 10 Mar 2011 20:18:40 +0000 (20:18 +0000)
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@438 36d66b0a-2a48-0410-832c-cd162a569da5

tests/api-test.c
tests/compat-test
tests/loopaes-test
tests/mode-test

index cf9ff1d..7ae4a49 100644 (file)
 #include <assert.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
+#include <linux/loop.h>
 
 #include "libcryptsetup.h"
 
 #define DMDIR "/dev/mapper/"
 
-#define DEVICE_1 "/dev/loop5"
 #define DEVICE_1_UUID "28632274-8c8a-493f-835b-da802e1c576b"
-#define DEVICE_2 "/dev/loop6"
 #define DEVICE_EMPTY_name "crypt_zero"
 #define DEVICE_EMPTY DMDIR DEVICE_EMPTY_name
 #define DEVICE_ERROR_name "crypt_error"
@@ -63,6 +62,9 @@ static int _verbose = 1;
 static char global_log[4096];
 static int global_lines = 0;
 
+static char *DEVICE_1 = NULL;
+static char *DEVICE_2 = NULL;
+
 // Helpers
 static int _prepare_keyfile(const char *name, const char *passphrase)
 {
@@ -84,6 +86,33 @@ static void _remove_keyfiles(void)
        remove(KEYFILE2);
 }
 
+char *_get_loop_device(void)
+{
+       char dev[20];
+       int i, loop_fd;
+       struct stat st;
+       struct loop_info64 lo64 = {0};
+
+       for ( i = 0; i < 256; i++ ) {
+               sprintf ( dev, "/dev/loop%d", i );
+               if ( stat ( dev, &st ) || !S_ISBLK ( st.st_mode ) )
+                       goto bad;
+
+               loop_fd = open ( dev, O_RDONLY );
+               if ( loop_fd < 0 )
+                       goto bad;
+
+               if ( ioctl ( loop_fd, LOOP_GET_STATUS64, &lo64 ) && errno == ENXIO ) {
+                       close ( loop_fd );
+                       return strdup ( dev );
+               }
+               close ( loop_fd );
+       }
+bad:
+       printf("Cannot find free loop device.\n");
+       return NULL;
+}
+
 // Decode key from its hex representation
 static int crypt_decode_key(char *key, char *hex, unsigned int size)
 {
@@ -146,6 +175,7 @@ static struct interface_callbacks cmd_icb = {
 static void _cleanup(void)
 {
        struct stat st;
+       char tmp[256];
 
        //_system("udevadm settle", 0);
 
@@ -161,29 +191,46 @@ static void _cleanup(void)
        if (!stat(DEVICE_ERROR, &st))
                _system("dmsetup remove " DEVICE_ERROR_name, 0);
 
-       if (!strncmp("/dev/loop", DEVICE_1, 9))
-               _system("losetup -d " DEVICE_1, 0);
+       // FIXME: use internel loop lib when available
+       if (DEVICE_1 && !strncmp("/dev/loop", DEVICE_1, 9)) {
+               snprintf(tmp, sizeof(tmp), "losetup -d %s", DEVICE_1);
+               _system(tmp, 0);
+       }
 
-       if (!strncmp("/dev/loop", DEVICE_2, 9))
-               _system("losetup -d " DEVICE_2, 0);
+       if (DEVICE_2 && !strncmp("/dev/loop", DEVICE_2, 9)) {
+               snprintf(tmp, sizeof(tmp), "losetup -d %s", DEVICE_2);
+               _system(tmp, 0);
+       }
 
        _system("rm -f " IMAGE_EMPTY, 0);
        _remove_keyfiles();
 }
 
-static void _setup(void)
+static int _setup(void)
 {
+       char tmp[256];
+
        _system("dmsetup create " DEVICE_EMPTY_name " --table \"0 10000 zero\"", 1);
        _system("dmsetup create " DEVICE_ERROR_name " --table \"0 10000 error\"", 1);
+       if (!DEVICE_1)
+               DEVICE_1 = _get_loop_device();
+       if (!DEVICE_1)
+               return 1;
        if (!strncmp("/dev/loop", DEVICE_1, 9)) {
                _system(" [ ! -e " IMAGE1 " ] && bzip2 -dk " IMAGE1 ".bz2", 1);
-               _system("losetup " DEVICE_1 " " IMAGE1, 1);
+               snprintf(tmp, sizeof(tmp), "losetup %s %s", DEVICE_1, IMAGE1);
+               _system(tmp, 1);
        }
+       if (!DEVICE_2)
+               DEVICE_2 = _get_loop_device();
+       if (!DEVICE_2)
+               return 1;
        if (!strncmp("/dev/loop", DEVICE_2, 9)) {
                _system("dd if=/dev/zero of=" IMAGE_EMPTY " bs=1M count=4", 1);
-               _system("losetup " DEVICE_2 " " IMAGE_EMPTY, 1);
+               snprintf(tmp, sizeof(tmp), "losetup %s %s", DEVICE_2, IMAGE_EMPTY);
+               _system(tmp, 1);
        }
-
+       return 0;
 }
 
 void check_ok(int status, int line, const char *func)
@@ -824,6 +871,7 @@ static void AddDeviceLuks(void)
 static void UseTempVolumes(void)
 {
        struct crypt_device *cd;
+       char tmp[256];
 
        // Tepmporary device without keyslot but with on-disk LUKS header
        OK_(crypt_init(&cd, DEVICE_2));
@@ -842,19 +890,21 @@ static void UseTempVolumes(void)
 
        // Dirty checks: device without UUID
        // we should be able to remove it but not manuipulate with it
-       _system("dmsetup create " CDEVICE_2 " --table \""
+       snprintf(tmp, sizeof(tmp), "dmsetup create %s --table \""
                "0 100 crypt aes-cbc-essiv:sha256 deadbabedeadbabedeadbabedeadbabe 0 "
-               DEVICE_2 " 2048\"", 1);
+               "%s 2048\"", CDEVICE_2, DEVICE_2);
+       _system(tmp, 1);
        OK_(crypt_init_by_name(&cd, CDEVICE_2));
        OK_(crypt_deactivate(cd, CDEVICE_2));
        FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_2, NULL, 0, 0), "No known device type");
        crypt_free(cd);
 
        // Dirty checks: device with UUID but LUKS header key fingerprint must fail)
-       _system("dmsetup create " CDEVICE_2 " --table \""
+       snprintf(tmp, sizeof(tmp), "dmsetup create %s --table \""
                "0 100 crypt aes-cbc-essiv:sha256 deadbabedeadbabedeadbabedeadbabe 0 "
-               DEVICE_2 " 2048\" "
-               "-u CRYPT-LUKS1-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-ctest1", 1);
+               "%s 2048\" -u CRYPT-LUKS1-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-ctest1",
+                CDEVICE_2, DEVICE_2);
+       _system(tmp, 1);
        OK_(crypt_init_by_name(&cd, CDEVICE_2));
        OK_(crypt_deactivate(cd, CDEVICE_2));
        FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_2, NULL, 0, 0), "wrong volume key");
@@ -924,7 +974,8 @@ int main (int argc, char *argv[])
        }
 
        _cleanup();
-       _setup();
+       if (_setup())
+               goto out;
 
        crypt_set_debug_level(_debug ? CRYPT_DEBUG_ALL : CRYPT_DEBUG_NONE);
 
@@ -946,7 +997,7 @@ int main (int argc, char *argv[])
        RUN_(UseTempVolumes, "Format and use temporary encrypted device");
 
        RUN_(CallbacksTest, "API callbacks test");
-
+out:
        _cleanup();
        return 0;
 }
index 12e7f19..1a86a8f 100755 (executable)
@@ -2,7 +2,6 @@
 
 CRYPTSETUP=../src/cryptsetup
 
-LOOPDEV=/dev/loop5
 DEV_NAME=dummy
 DEV_NAME2=dummy2
 ORIG_IMG=luks-test-orig
@@ -21,6 +20,8 @@ KEY_MATERIAL1_EXT="S69632-133632"
 
 TEST_UUID="12345678-1234-1234-1234-123456789abc"
 
+LOOPDEV=$(losetup -f 2>/dev/null)
+
 function remove_mapping()
 {
        [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2
@@ -36,6 +37,12 @@ function fail()
        exit 2
 }
 
+function skip()
+{
+       [ -n "$1" ] && echo "$1"
+       exit 0
+}
+
 function prepare()
 {
        [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME
@@ -85,10 +92,8 @@ function check_exists()
        check $1
 }
 
-if [ $(id -u) != 0 ]; then
-       echo "WARNING: You must be root to run this test, test skipped."
-       exit 0
-fi
+[ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped."
+[ -z "$LOOPDEV" ] && skip "Cannot find free loop device, test skipped."
 
 # LUKS tests
 
index d7e2a97..5a4c54d 100755 (executable)
@@ -5,7 +5,6 @@ CRYPTSETUP=../src/cryptsetup
 # try to validate using loop-aes losetup/kernel if available
 LOSETUP_AES=/losetup-aes
 
-LOOPDEV=/dev/loop5
 LOOP_DD_PARAM="bs=1k count=10000"
 EXPSUM="31e00e0e4c233c89051cd748122fde2c98db0121ca09ba93a3820817ea037bc5"
 DEV_NAME=dummy
@@ -13,6 +12,7 @@ IMG=loopaes.img
 KEYv1=key_v1
 KEYv2=key_v2
 KEYv3=key_v3
+LOOPDEV=$(losetup -f 2>/dev/null)
 
 function dmremove() { # device
         udevadm settle 2>/dev/null 2>&1
@@ -112,6 +112,7 @@ function check_version()
 }
 
 [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped."
+[ -z "$LOOPDEV" ] && skip "Cannot find free loop device, test skipped."
 which uuencode >/dev/null || skip "WARNING: test require uuencode binary, test skipped."
 check_version || skip "Probably old kernel, test skipped."
 
index a94876d..7ed6bf5 100755 (executable)
@@ -4,7 +4,6 @@
 #
 CRYPTSETUP=../src/cryptsetup
 DEV_NAME=dmc_test
-LOOPDEV=/dev/loop5
 HEADER_IMG=mode-test.img
 PASSWORD=3xrododenron
 
@@ -13,6 +12,8 @@ CIPHERS="aes twofish serpent"
 MODES="cbc lrw xts"
 IVMODES="null benbi plain plain64 essiv:sha256"
 
+LOOPDEV=$(losetup -f 2>/dev/null)
+
 dmremove() { # device
        udevadm settle 2>/dev/null 2>&1
        dmsetup remove $1 2>/dev/null 2>&1
@@ -35,6 +36,12 @@ fail()
        exit 100
 }
 
+skip()
+{
+       [ -n "$1" ] && echo "$1"
+       exit 0
+}
+
 add_device() {
        dd if=/dev/zero of=$HEADER_IMG bs=1M count=6 >/dev/null 2>&1
        sync
@@ -117,10 +124,8 @@ dmcrypt()
        echo
 }
 
-if [ $(id -u) != 0 ]; then
-       echo "WARNING: You must be root to run this test, test skipped."
-       exit 0
-fi
+[ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped."
+[ -z "$LOOPDEV" ] && skip "Cannot find free loop device, test skipped."
 
 add_device