From 01e03f7002ab0f0b8f576e8e4282d9f428ed9c4c Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Sat, 12 Mar 2011 22:29:14 +0000 Subject: [PATCH] Use loop functions even in api test. git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@448 36d66b0a-2a48-0410-832c-cd162a569da5 --- lib/setup.c | 2 +- lib/utils_loop.c | 40 ++++++++++++++++++++++++-------- lib/utils_loop.h | 6 +++-- tests/Makefile.am | 2 +- tests/api-test.c | 68 ++++++++++++++++--------------------------------------- 5 files changed, 57 insertions(+), 61 deletions(-) diff --git a/lib/setup.c b/lib/setup.c index 33c17fe..8862fea 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -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")); diff --git a/lib/utils_loop.c b/lib/utils_loop.c index cbaef4b..d628470 100644 --- a/lib/utils_loop.c +++ b/lib/utils_loop.c @@ -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; diff --git a/lib/utils_loop.h b/lib/utils_loop.h index 9b97a3e..0deca04 100644 --- a/lib/utils_loop.h +++ b/lib/utils_loop.h @@ -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 */ diff --git a/tests/Makefile.am b/tests/Makefile.am index 66317a2..2fc7f98 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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/ diff --git a/tests/api-test.c b/tests/api-test.c index 7ae4a49..d5954bd 100644 --- a/tests/api-test.c +++ b/tests/api-test.c @@ -30,6 +30,7 @@ #include #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; } -- 2.7.4