Use loop functions even in api test.

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@448 36d66b0a-2a48-0410-832c-cd162a569da5
This commit is contained in:
Milan Broz
2011-03-12 22:29:14 +00:00
parent dd9bff8d67
commit 01e03f7002
5 changed files with 57 additions and 61 deletions

View File

@@ -991,7 +991,7 @@ int crypt_init(struct crypt_device **cd, const char *device)
} }
/* Keep the loop open, dettached on last close. */ /* 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) { if (h->loop_fd == -1) {
log_err(NULL, _("Attaching loopback device failed " log_err(NULL, _("Attaching loopback device failed "
"(loop device with autoclear flag is required).\n")); "(loop device with autoclear flag is required).\n"));

View File

@@ -35,7 +35,7 @@ char *crypt_loop_get_device(void)
struct stat st; struct stat st;
struct loop_info64 lo64 = {0}; struct loop_info64 lo64 = {0};
for(i = 0; i < 256; i++) { for (i = 0; i < 256; i++) {
sprintf(dev, "/dev/loop%d", i); sprintf(dev, "/dev/loop%d", i);
if (stat(dev, &st) || !S_ISBLK(st.st_mode)) if (stat(dev, &st) || !S_ISBLK(st.st_mode))
return NULL; return NULL;
@@ -44,7 +44,8 @@ char *crypt_loop_get_device(void)
if (loop_fd < 0) if (loop_fd < 0)
return NULL; 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); close(loop_fd);
return strdup(dev); return strdup(dev);
} }
@@ -54,8 +55,8 @@ char *crypt_loop_get_device(void)
return NULL; return NULL;
} }
int crypt_loop_attach(const char *loop, const char *file, int crypt_loop_attach(const char *loop, const char *file, int offset,
int offset, int *readonly) int autoclear, int *readonly)
{ {
struct loop_info64 lo64 = {0}; struct loop_info64 lo64 = {0};
int loop_fd = -1, file_fd = -1, r = 1; 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); strncpy((char*)lo64.lo_file_name, file, LO_NAME_SIZE);
lo64.lo_offset = offset; 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) if (ioctl(loop_fd, LOOP_SET_FD, file_fd) < 0)
goto out; goto out;
@@ -85,11 +87,13 @@ int crypt_loop_attach(const char *loop, const char *file,
} }
/* Verify that autoclear is really set */ /* Verify that autoclear is really set */
memset(&lo64, 0, sizeof(lo64)); if (autoclear) {
if (ioctl(loop_fd, LOOP_GET_STATUS64, &lo64) < 0 || memset(&lo64, 0, sizeof(lo64));
!(lo64.lo_flags & LO_FLAGS_AUTOCLEAR)) { if (ioctl(loop_fd, LOOP_GET_STATUS64, &lo64) < 0 ||
!(lo64.lo_flags & LO_FLAGS_AUTOCLEAR)) {
(void)ioctl(loop_fd, LOOP_CLR_FD, 0); (void)ioctl(loop_fd, LOOP_CLR_FD, 0);
goto out; goto out;
}
} }
r = 0; r = 0;
@@ -101,6 +105,21 @@ out:
return r ? -1 : loop_fd; 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) char *crypt_loop_backing_file(const char *loop)
{ {
struct loop_info64 lo64 = {0}; struct loop_info64 lo64 = {0};
@@ -127,6 +146,9 @@ int crypt_loop_device(const char *loop)
{ {
struct stat st; struct stat st;
if (!loop)
return 0;
if (stat(loop, &st) || !S_ISBLK(st.st_mode) || if (stat(loop, &st) || !S_ISBLK(st.st_mode) ||
major(st.st_rdev) != LOOP_DEV_MAJOR) major(st.st_rdev) != LOOP_DEV_MAJOR)
return 0; return 0;

View File

@@ -12,6 +12,8 @@
char *crypt_loop_get_device(void); char *crypt_loop_get_device(void);
char *crypt_loop_backing_file(const char *loop); char *crypt_loop_backing_file(const char *loop);
int crypt_loop_device(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 */

View File

@@ -6,7 +6,7 @@ EXTRA_DIST = compatimage.img.bz2 \
differ_SOURCES = differ.c differ_SOURCES = differ.c
differ_CFLAGS = -Wall -O2 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_LDADD = ../lib/libcryptsetup.la
api_test_LDFLAGS = -static api_test_LDFLAGS = -static
api_test_CFLAGS = -g -Wall -O0 -I$(top_srcdir)/lib/ api_test_CFLAGS = -g -Wall -O0 -I$(top_srcdir)/lib/

View File

@@ -30,6 +30,7 @@
#include <linux/loop.h> #include <linux/loop.h>
#include "libcryptsetup.h" #include "libcryptsetup.h"
#include "utils_loop.h"
#define DMDIR "/dev/mapper/" #define DMDIR "/dev/mapper/"
@@ -86,33 +87,6 @@ static void _remove_keyfiles(void)
remove(KEYFILE2); 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 // Decode key from its hex representation
static int crypt_decode_key(char *key, char *hex, unsigned int size) 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) static void _cleanup(void)
{ {
struct stat st; struct stat st;
char tmp[256];
//_system("udevadm settle", 0); //_system("udevadm settle", 0);
@@ -191,16 +164,11 @@ static void _cleanup(void)
if (!stat(DEVICE_ERROR, &st)) if (!stat(DEVICE_ERROR, &st))
_system("dmsetup remove " DEVICE_ERROR_name, 0); _system("dmsetup remove " DEVICE_ERROR_name, 0);
// FIXME: use internel loop lib when available if (crypt_loop_device(DEVICE_1))
if (DEVICE_1 && !strncmp("/dev/loop", DEVICE_1, 9)) { crypt_loop_detach(DEVICE_1);
snprintf(tmp, sizeof(tmp), "losetup -d %s", DEVICE_1);
_system(tmp, 0);
}
if (DEVICE_2 && !strncmp("/dev/loop", DEVICE_2, 9)) { if (crypt_loop_device(DEVICE_2))
snprintf(tmp, sizeof(tmp), "losetup -d %s", DEVICE_2); crypt_loop_detach(DEVICE_2);
_system(tmp, 0);
}
_system("rm -f " IMAGE_EMPTY, 0); _system("rm -f " IMAGE_EMPTY, 0);
_remove_keyfiles(); _remove_keyfiles();
@@ -208,27 +176,31 @@ static void _cleanup(void)
static int _setup(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_EMPTY_name " --table \"0 10000 zero\"", 1);
_system("dmsetup create " DEVICE_ERROR_name " --table \"0 10000 error\"", 1); _system("dmsetup create " DEVICE_ERROR_name " --table \"0 10000 error\"", 1);
if (!DEVICE_1) if (!DEVICE_1)
DEVICE_1 = _get_loop_device(); DEVICE_1 = crypt_loop_get_device();
if (!DEVICE_1) if (!DEVICE_1) {
printf("Cannot find free loop device.\n");
return 1; return 1;
if (!strncmp("/dev/loop", DEVICE_1, 9)) { }
if (crypt_loop_device(DEVICE_1)) {
_system(" [ ! -e " IMAGE1 " ] && bzip2 -dk " IMAGE1 ".bz2", 1); _system(" [ ! -e " IMAGE1 " ] && bzip2 -dk " IMAGE1 ".bz2", 1);
snprintf(tmp, sizeof(tmp), "losetup %s %s", DEVICE_1, IMAGE1); fd = crypt_loop_attach(DEVICE_1, IMAGE1, 0, 0, &ro);
_system(tmp, 1); close(fd);
} }
if (!DEVICE_2) if (!DEVICE_2)
DEVICE_2 = _get_loop_device(); DEVICE_2 = crypt_loop_get_device();
if (!DEVICE_2) if (!DEVICE_2) {
printf("Cannot find free loop device.\n");
return 1; 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); _system("dd if=/dev/zero of=" IMAGE_EMPTY " bs=1M count=4", 1);
snprintf(tmp, sizeof(tmp), "losetup %s %s", DEVICE_2, IMAGE_EMPTY); fd = crypt_loop_attach(DEVICE_2, IMAGE_EMPTY, 0, 0, &ro);
_system(tmp, 1); close(fd);
} }
return 0; return 0;
} }