Move devpath scan to separate file.
authorMilan Broz <gmazyland@gmail.com>
Tue, 24 May 2011 11:19:00 +0000 (11:19 +0000)
committerMilan Broz <gmazyland@gmail.com>
Tue, 24 May 2011 11:19:00 +0000 (11:19 +0000)
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@529 36d66b0a-2a48-0410-832c-cd162a569da5

lib/Makefile.am
lib/internal.h
lib/libdevmapper.c
lib/utils.c
lib/utils_devpath.c [new file with mode: 0644]

index d325ad0..d59f0be 100644 (file)
@@ -52,6 +52,7 @@ libcryptsetup_la_SOURCES = \
        utils_debug.c                           \
        utils_loop.c                            \
        utils_loop.h                            \
+       utils_devpath.c                         \
        libdevmapper.c                          \
        volumekey.c                             \
        random.c                                \
index 821c383..04a5e67 100644 (file)
@@ -90,8 +90,13 @@ int dm_suspend_and_wipe_key(const char *name);
 int dm_resume_and_reinstate_key(const char *name,
                                size_t key_size,
                                const char *key);
+char *dm_device_path(const char *dev_id);
+int dm_is_dm_device(int major);
+
+char *crypt_lookup_dev(const char *dev_id);
 
 int sector_size_for_device(const char *device);
+int device_read_ahead(const char *dev, uint32_t *read_ahead);
 ssize_t write_blockwise(int fd, void *buf, size_t count);
 ssize_t read_blockwise(int fd, void *_buf, size_t count);
 ssize_t write_lseek_blockwise(int fd, char *buf, size_t count, off_t offset);
index 8e58860..0fa03c6 100644 (file)
@@ -19,8 +19,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <sys/ioctl.h>
-#include <sys/stat.h>
 #include <stdio.h>
 #include <dirent.h>
 #include <errno.h>
@@ -32,7 +30,6 @@
 #include "internal.h"
 #include "luks.h"
 
-#define DEVICE_DIR             "/dev"
 #define DM_UUID_LEN            129
 #define DM_UUID_PREFIX         "CRYPT-"
 #define DM_UUID_PREFIX_LEN     6
@@ -208,90 +205,8 @@ void dm_exit(void)
        }
 }
 
-static char *__lookup_dev(char *path, dev_t dev, int dir_level, const int max_level)
-{
-       struct dirent *entry;
-       struct stat st;
-       char *ptr;
-       char *result = NULL;
-       DIR *dir;
-       int space;
-
-       /* Ignore strange nested directories */
-       if (dir_level > max_level)
-               return NULL;
-
-       path[PATH_MAX - 1] = '\0';
-       ptr = path + strlen(path);
-       *ptr++ = '/';
-       *ptr = '\0';
-       space = PATH_MAX - (ptr - path);
-
-       dir = opendir(path);
-       if (!dir)
-               return NULL;
-
-       while((entry = readdir(dir))) {
-               if (entry->d_name[0] == '.' ||
-                   !strncmp(entry->d_name, "..", 2))
-                       continue;
-
-               strncpy(ptr, entry->d_name, space);
-               if (stat(path, &st) < 0)
-                       continue;
-
-               if (S_ISDIR(st.st_mode)) {
-                       result = __lookup_dev(path, dev, dir_level + 1, max_level);
-                       if (result)
-                               break;
-               } else if (S_ISBLK(st.st_mode)) {
-                       /* workaround: ignore dm-X devices, these are internal kernel names */
-                       if (dir_level == 0 && !strncmp(entry->d_name, "dm-", 3))
-                               continue;
-                       if (st.st_rdev == dev) {
-                               result = strdup(path);
-                               break;
-                       }
-               }
-       }
-
-       closedir(dir);
-       return result;
-}
-
-static char *lookup_dev_old(const char *dev_id)
-{
-       uint32_t major, minor;
-       dev_t dev;
-       char *result = NULL, buf[PATH_MAX + 1];
-
-       if (sscanf(dev_id, "%" PRIu32 ":%" PRIu32, &major, &minor) != 2)
-               return NULL;
-
-       dev = makedev(major, minor);
-       strncpy(buf, DEVICE_DIR, PATH_MAX);
-       buf[PATH_MAX] = '\0';
-
-       /* First try low level device */
-       if ((result = __lookup_dev(buf, dev, 0, 0)))
-               return result;
-
-       /* If it is dm, try DM dir  */
-       if (dm_is_dm_major(major)) {
-               strncpy(buf, dm_dir(), PATH_MAX);
-               if ((result = __lookup_dev(buf, dev, 0, 0)))
-                       return result;
-       }
-
-       strncpy(buf, DEVICE_DIR, PATH_MAX);
-       result = __lookup_dev(buf, dev, 0, 4);
-
-       /* If not found, return NULL */
-       return result;
-}
-
 /* Return path to DM device */
-static char *dm_device_path(const char *dev_id)
+char *dm_device_path(const char *dev_id)
 {
        int major, minor;
        struct dm_task *dmt;
@@ -319,54 +234,6 @@ static char *dm_device_path(const char *dev_id)
        return strdup(path);
 }
 
-static char *lookup_dev(const char *dev_id)
-{
-       char link[PATH_MAX], path[PATH_MAX], *devname;
-       struct stat st;
-       ssize_t len;
-
-       if (snprintf(path, sizeof(path), "/sys/dev/block/%s", dev_id) < 0)
-               return NULL;
-
-       len = readlink(path, link, sizeof(link));
-       if (len < 0) {
-               if (stat("/sys/dev/block", &st) < 0)
-                       return lookup_dev_old(dev_id);
-               return NULL;
-       }
-
-       link[len] = '\0';
-       devname = strrchr(link, '/');
-       if (!devname)
-               return NULL;
-       devname++;
-
-       if (!strncmp(devname, "dm-", 3))
-               return dm_device_path(dev_id);
-
-       if (snprintf(path, sizeof(path), "/dev/%s", devname) < 0)
-               return NULL;
-
-       return strdup(path);
-}
-
-static int _dev_read_ahead(const char *dev, uint32_t *read_ahead)
-{
-       int fd, r = 0;
-       long read_ahead_long;
-
-       if ((fd = open(dev, O_RDONLY)) < 0)
-               return 0;
-
-       r = ioctl(fd, BLKRAGET, &read_ahead_long) ? 0 : 1;
-       close(fd);
-
-       if (r)
-               *read_ahead = (uint32_t) read_ahead_long;
-
-       return r;
-}
-
 static void hex_key(char *hexkey, size_t key_size, const char *key)
 {
        unsigned i;
@@ -593,7 +460,7 @@ int dm_create_device(const char *name,
                goto out_no_removal;
 
 #ifdef DM_READ_AHEAD_MINIMUM_FLAG
-       if (_dev_read_ahead(device, &read_ahead) &&
+       if (device_read_ahead(device, &read_ahead) &&
            !dm_task_set_read_ahead(dmt, read_ahead, DM_READ_AHEAD_MINIMUM_FLAG))
                goto out_no_removal;
 #endif
@@ -757,7 +624,7 @@ int dm_query_device(const char *name,
        /* device */
        rdevice = strsep(&params, " ");
        if (device)
-               *device = lookup_dev(rdevice);
+               *device = crypt_lookup_dev(rdevice);
 
        /*offset */
        if (!params)
@@ -891,3 +758,8 @@ const char *dm_get_dir(void)
 {
        return dm_dir();
 }
+
+int dm_is_dm_device(int major)
+{
+       return dm_is_dm_major((uint32_t)major);
+}
index 6339c9c..9c555d1 100644 (file)
@@ -108,6 +108,24 @@ static void *aligned_malloc(void **base, int size, int alignment)
        return ptr;
 #endif
 }
+
+int device_read_ahead(const char *dev, uint32_t *read_ahead)
+{
+       int fd, r = 0;
+       long read_ahead_long;
+
+       if ((fd = open(dev, O_RDONLY)) < 0)
+               return 0;
+
+       r = ioctl(fd, BLKRAGET, &read_ahead_long) ? 0 : 1;
+       close(fd);
+
+       if (r)
+               *read_ahead = (uint32_t) read_ahead_long;
+
+       return r;
+}
+
 static int sector_size(int fd) 
 {
        int bsize;
diff --git a/lib/utils_devpath.c b/lib/utils_devpath.c
new file mode 100644 (file)
index 0000000..f397f7c
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * devname - search for device name
+ *
+ * Copyright (C) 2004, Christophe Saout <christophe@saout.de>
+ * Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
+ * Copyright (C) 2009-2011, Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include "internal.h"
+
+#define DEVICE_DIR     "/dev"
+
+static char *__lookup_dev(char *path, dev_t dev, int dir_level, const int max_level)
+{
+       struct dirent *entry;
+       struct stat st;
+       char *ptr;
+       char *result = NULL;
+       DIR *dir;
+       int space;
+
+       /* Ignore strange nested directories */
+       if (dir_level > max_level)
+               return NULL;
+
+       path[PATH_MAX - 1] = '\0';
+       ptr = path + strlen(path);
+       *ptr++ = '/';
+       *ptr = '\0';
+       space = PATH_MAX - (ptr - path);
+
+       dir = opendir(path);
+       if (!dir)
+               return NULL;
+
+       while((entry = readdir(dir))) {
+               if (entry->d_name[0] == '.' ||
+                   !strncmp(entry->d_name, "..", 2))
+                       continue;
+
+               strncpy(ptr, entry->d_name, space);
+               if (stat(path, &st) < 0)
+                       continue;
+
+               if (S_ISDIR(st.st_mode)) {
+                       result = __lookup_dev(path, dev, dir_level + 1, max_level);
+                       if (result)
+                               break;
+               } else if (S_ISBLK(st.st_mode)) {
+                       /* workaround: ignore dm-X devices, these are internal kernel names */
+                       if (dir_level == 0 && !strncmp(entry->d_name, "dm-", 3))
+                               continue;
+                       if (st.st_rdev == dev) {
+                               result = strdup(path);
+                               break;
+                       }
+               }
+       }
+
+       closedir(dir);
+       return result;
+}
+
+static char *lookup_dev_old(const char *dev_id)
+{
+       int major, minor;
+       dev_t dev;
+       char *result = NULL, buf[PATH_MAX + 1];
+
+       if (sscanf(dev_id, "%d:%d", &major, &minor) != 2)
+               return NULL;
+
+       dev = makedev(major, minor);
+       strncpy(buf, DEVICE_DIR, PATH_MAX);
+       buf[PATH_MAX] = '\0';
+
+       /* First try low level device */
+       if ((result = __lookup_dev(buf, dev, 0, 0)))
+               return result;
+
+       /* If it is dm, try DM dir  */
+       if (dm_is_dm_device(major)) {
+               strncpy(buf, dm_get_dir(), PATH_MAX);
+               if ((result = __lookup_dev(buf, dev, 0, 0)))
+                       return result;
+       }
+
+       strncpy(buf, DEVICE_DIR, PATH_MAX);
+       result = __lookup_dev(buf, dev, 0, 4);
+
+       /* If not found, return NULL */
+       return result;
+}
+
+char *crypt_lookup_dev(const char *dev_id)
+{
+       char link[PATH_MAX], path[PATH_MAX], *devname;
+       struct stat st;
+       ssize_t len;
+
+       if (snprintf(path, sizeof(path), "/sys/dev/block/%s", dev_id) < 0)
+               return NULL;
+
+       len = readlink(path, link, sizeof(link));
+       if (len < 0) {
+               if (stat("/sys/dev/block", &st) < 0)
+                       return lookup_dev_old(dev_id);
+               return NULL;
+       }
+
+       link[len] = '\0';
+       devname = strrchr(link, '/');
+       if (!devname)
+               return NULL;
+       devname++;
+
+       if (!strncmp(devname, "dm-", 3))
+               return dm_device_path(dev_id);
+
+       if (snprintf(path, sizeof(path), "/dev/%s", devname) < 0)
+               return NULL;
+
+       return strdup(path);
+}