mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Move devpath scan to separate file.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@529 36d66b0a-2a48-0410-832c-cd162a569da5
This commit is contained in:
@@ -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 \
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(¶ms, " ");
|
||||
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);
|
||||
}
|
||||
|
||||
18
lib/utils.c
18
lib/utils.c
@@ -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;
|
||||
|
||||
142
lib/utils_devpath.c
Normal file
142
lib/utils_devpath.c
Normal file
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user