Use loop functions even in api test.
authorMilan Broz <gmazyland@gmail.com>
Sat, 12 Mar 2011 22:29:14 +0000 (22:29 +0000)
committerMilan Broz <gmazyland@gmail.com>
Sat, 12 Mar 2011 22:29:14 +0000 (22:29 +0000)
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@448 36d66b0a-2a48-0410-832c-cd162a569da5

lib/setup.c
lib/utils_loop.c
lib/utils_loop.h
tests/Makefile.am
tests/api-test.c

index 33c17fe..8862fea 100644 (file)
@@ -991,7 +991,7 @@ int crypt_init(struct crypt_device **cd, const char *device)
                        }
 
                        /* Keep the loop open, dettached on last close. */
-                       h->loop_fd = crypt_loop_attach(h->device, device, 0, &readonly);
+                       h->loop_fd = crypt_loop_attach(h->device, device, 0, 1, &readonly);
                        if (h->loop_fd == -1) {
                                log_err(NULL, _("Attaching loopback device failed "
                                        "(loop device with autoclear flag is required).\n"));
index cbaef4b..d628470 100644 (file)
@@ -35,7 +35,7 @@ char *crypt_loop_get_device(void)
        struct stat st;
        struct loop_info64 lo64 = {0};
 
-       for(i = 0; i < 256; i++) {
+       for (i = 0; i < 256; i++) {
                sprintf(dev, "/dev/loop%d", i);
                if (stat(dev, &st) || !S_ISBLK(st.st_mode))
                        return NULL;
@@ -44,7 +44,8 @@ char *crypt_loop_get_device(void)
                if (loop_fd < 0)
                        return NULL;
 
-               if(ioctl(loop_fd, LOOP_GET_STATUS64, &lo64) && errno == ENXIO) {
+               if (ioctl(loop_fd, LOOP_GET_STATUS64, &lo64) &&
+                   errno == ENXIO) {
                        close(loop_fd);
                        return strdup(dev);
                }
@@ -54,8 +55,8 @@ char *crypt_loop_get_device(void)
        return NULL;
 }
 
-int crypt_loop_attach(const char *loop, const char *file,
-                     int offset, int *readonly)
+int crypt_loop_attach(const char *loop, const char *file, int offset,
+                     int autoclear, int *readonly)
 {
        struct loop_info64 lo64 = {0};
        int loop_fd = -1, file_fd = -1, r = 1;
@@ -74,7 +75,8 @@ int crypt_loop_attach(const char *loop, const char *file,
 
        strncpy((char*)lo64.lo_file_name, file, LO_NAME_SIZE);
        lo64.lo_offset = offset;
-       lo64.lo_flags |= LO_FLAGS_AUTOCLEAR;
+       if (autoclear)
+               lo64.lo_flags |= LO_FLAGS_AUTOCLEAR;
 
        if (ioctl(loop_fd, LOOP_SET_FD, file_fd) < 0)
                goto out;
@@ -85,11 +87,13 @@ int crypt_loop_attach(const char *loop, const char *file,
        }
 
        /* Verify that autoclear is really set */
-       memset(&lo64, 0, sizeof(lo64));
-       if (ioctl(loop_fd, LOOP_GET_STATUS64, &lo64) < 0 ||
-           !(lo64.lo_flags & LO_FLAGS_AUTOCLEAR)) {
+       if (autoclear) {
+               memset(&lo64, 0, sizeof(lo64));
+               if (ioctl(loop_fd, LOOP_GET_STATUS64, &lo64) < 0 ||
+                  !(lo64.lo_flags & LO_FLAGS_AUTOCLEAR)) {
                (void)ioctl(loop_fd, LOOP_CLR_FD, 0);
-               goto out;
+                       goto out;
+               }
        }
 
        r = 0;
@@ -101,6 +105,21 @@ out:
        return r ? -1 : loop_fd;
 }
 
+int crypt_loop_detach(const char *loop)
+{
+       int loop_fd = -1, r = 1;
+
+       loop_fd = open(loop, O_RDONLY);
+       if (loop_fd < 0)
+                return 1;
+
+       if (!ioctl(loop_fd, LOOP_CLR_FD, 0))
+               r = 0;
+
+       close(loop_fd);
+       return r;
+}
+
 char *crypt_loop_backing_file(const char *loop)
 {
        struct loop_info64 lo64 = {0};
@@ -127,6 +146,9 @@ int crypt_loop_device(const char *loop)
 {
        struct stat st;
 
+       if (!loop)
+               return 0;
+
        if (stat(loop, &st) || !S_ISBLK(st.st_mode) ||
            major(st.st_rdev) != LOOP_DEV_MAJOR)
                return 0;
index 9b97a3e..0deca04 100644 (file)
@@ -12,6 +12,8 @@
 char *crypt_loop_get_device(void);
 char *crypt_loop_backing_file(const char *loop);
 int crypt_loop_device(const char *loop);
-int crypt_loop_attach(const char *loop, const char *file, int offset, int *readonly);
+int crypt_loop_attach(const char *loop, const char *file, int offset,
+                     int autoclear, int *readonly);
+int crypt_loop_detach(const char *loop);
 
-#endif /* _UTILS_CRYPT_H */
+#endif /* _UTILS_LOOP_H */
index 66317a2..2fc7f98 100644 (file)
@@ -6,7 +6,7 @@ EXTRA_DIST = compatimage.img.bz2 \
 differ_SOURCES = differ.c
 differ_CFLAGS = -Wall -O2
 
-api_test_SOURCES = api-test.c
+api_test_SOURCES = api-test.c $(top_srcdir)/lib/utils_loop.c
 api_test_LDADD = ../lib/libcryptsetup.la
 api_test_LDFLAGS = -static
 api_test_CFLAGS = -g -Wall -O0 -I$(top_srcdir)/lib/
index 7ae4a49..d5954bd 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/loop.h>
 
 #include "libcryptsetup.h"
+#include "utils_loop.h"
 
 #define DMDIR "/dev/mapper/"
 
@@ -86,33 +87,6 @@ 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)
 {
@@ -175,7 +149,6 @@ static struct interface_callbacks cmd_icb = {
 static void _cleanup(void)
 {
        struct stat st;
-       char tmp[256];
 
        //_system("udevadm settle", 0);
 
@@ -191,16 +164,11 @@ static void _cleanup(void)
        if (!stat(DEVICE_ERROR, &st))
                _system("dmsetup remove " DEVICE_ERROR_name, 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 (crypt_loop_device(DEVICE_1))
+               crypt_loop_detach(DEVICE_1);
 
-       if (DEVICE_2 && !strncmp("/dev/loop", DEVICE_2, 9)) {
-               snprintf(tmp, sizeof(tmp), "losetup -d %s", DEVICE_2);
-               _system(tmp, 0);
-       }
+       if (crypt_loop_device(DEVICE_2))
+               crypt_loop_detach(DEVICE_2);
 
        _system("rm -f " IMAGE_EMPTY, 0);
        _remove_keyfiles();
@@ -208,27 +176,31 @@ static void _cleanup(void)
 
 static int _setup(void)
 {
-       char tmp[256];
+       int fd, ro = 0;
 
        _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)
+               DEVICE_1 = crypt_loop_get_device();
+       if (!DEVICE_1) {
+               printf("Cannot find free loop device.\n");
                return 1;
-       if (!strncmp("/dev/loop", DEVICE_1, 9)) {
+       }
+       if (crypt_loop_device(DEVICE_1)) {
                _system(" [ ! -e " IMAGE1 " ] && bzip2 -dk " IMAGE1 ".bz2", 1);
-               snprintf(tmp, sizeof(tmp), "losetup %s %s", DEVICE_1, IMAGE1);
-               _system(tmp, 1);
+               fd = crypt_loop_attach(DEVICE_1, IMAGE1, 0, 0, &ro);
+               close(fd);
        }
        if (!DEVICE_2)
-               DEVICE_2 = _get_loop_device();
-       if (!DEVICE_2)
+               DEVICE_2 = crypt_loop_get_device();
+       if (!DEVICE_2) {
+               printf("Cannot find free loop device.\n");
                return 1;
-       if (!strncmp("/dev/loop", DEVICE_2, 9)) {
+       }
+       if (crypt_loop_device(DEVICE_2)) {
                _system("dd if=/dev/zero of=" IMAGE_EMPTY " bs=1M count=4", 1);
-               snprintf(tmp, sizeof(tmp), "losetup %s %s", DEVICE_2, IMAGE_EMPTY);
-               _system(tmp, 1);
+               fd = crypt_loop_attach(DEVICE_2, IMAGE_EMPTY, 0, 0, &ro);
+               close(fd);
        }
        return 0;
 }