[lvm-devel] LVM2 ./WHATS_NEW_DM libdm/libdm-common.c
agk at sourceware.org
agk at sourceware.org
Fri Sep 25 18:08:05 UTC 2009
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: agk at sourceware.org 2009-09-25 18:08:04
Modified files:
. : WHATS_NEW_DM
libdm : libdm-common.c
Log message:
Handle any path supplied to dm_task_set_name() by looking up in /dev/mapper.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW_DM.diff?cvsroot=lvm2&r1=1.300&r2=1.301
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdm-common.c.diff?cvsroot=lvm2&r1=1.81&r2=1.82
--- LVM2/WHATS_NEW_DM 2009/09/15 13:54:29 1.300
+++ LVM2/WHATS_NEW_DM 2009/09/25 18:08:04 1.301
@@ -1,5 +1,6 @@
Version 1.02.38 -
=====================================
+ Handle any path supplied to dm_task_set_name() by looking up in /dev/mapper.
Version 1.02.37 - 15th September 2009
=====================================
--- LVM2/libdm/libdm-common.c 2009/09/15 11:41:39 1.81
+++ LVM2/libdm/libdm-common.c 2009/09/25 18:08:04 1.82
@@ -23,6 +23,7 @@
#include <sys/param.h>
#include <sys/ioctl.h>
#include <fcntl.h>
+#include <dirent.h>
#ifdef UDEV_SYNC_SUPPORT
# include <sys/types.h>
@@ -183,9 +184,54 @@
return dmt;
}
+/*
+ * Find the name associated with a given device number by scanning _dm_dir.
+ */
+static char *_translate_name(dev_t st_rdev, const char *devname)
+{
+ const char *name;
+ char path[PATH_MAX];
+ struct dirent *dirent;
+ DIR *d;
+ struct stat buf;
+ char *new_name = NULL;
+
+ if (!(d = opendir(_dm_dir))) {
+ log_sys_error("opendir", _dm_dir);
+ return NULL;
+ }
+
+ while ((dirent = readdir(d))) {
+ name = dirent->d_name;
+
+ if (!strcmp(name, ".") || !strcmp(name, ".."))
+ continue;
+
+ if (dm_snprintf(path, sizeof(path), "%s/%s", _dm_dir,
+ name) == -1) {
+ log_error("Couldn't create path for %s", name);
+ continue;
+ }
+
+ if (stat(path, &buf))
+ continue;
+
+ if (buf.st_rdev == st_rdev) {
+ new_name = dm_strdup(name);
+ break;
+ }
+ }
+
+ if (closedir(d))
+ log_sys_error("closedir", _dm_dir);
+
+ return new_name;
+}
+
int dm_task_set_name(struct dm_task *dmt, const char *name)
{
char *pos;
+ char *new_name = NULL;
char path[PATH_MAX];
struct stat st1, st2;
@@ -194,8 +240,8 @@
dmt->dev_name = NULL;
}
- /* If path was supplied, remove it if it points to the same device
- * as its last component.
+ /*
+ * Path supplied for existing device?
*/
if ((pos = strrchr(name, '/'))) {
if (dmt->type == DM_DEVICE_CREATE) {
@@ -203,23 +249,38 @@
return 0;
}
+ if (stat(name, &st1)) {
+ log_error("Device %s not found", name);
+ return 0;
+ }
+
+ /*
+ * If supplied path points to same device as last component
+ * under /dev/mapper, use that name directly. Otherwise call
+ * _translate_name() to scan _dm_dir for a match.
+ */
snprintf(path, sizeof(path), "%s/%s", _dm_dir, pos + 1);
- if (stat(name, &st1) || stat(path, &st2) ||
- !(st1.st_dev == st2.st_dev)) {
+ if (!stat(path, &st2) && (st1.st_rdev == st2.st_rdev))
+ name = pos + 1;
+ else if ((new_name = _translate_name(st1.st_rdev, pos + 1)))
+ name = new_name;
+ else {
log_error("Device %s not found", name);
return 0;
}
-
- name = pos + 1;
}
if (strlen(name) >= DM_NAME_LEN) {
log_error("Name \"%s\" too long", name);
+ if (new_name)
+ dm_free(new_name);
return 0;
}
- if (!(dmt->dev_name = dm_strdup(name))) {
+ if (new_name)
+ dmt->dev_name = new_name;
+ else if (!(dmt->dev_name = dm_strdup(name))) {
log_error("dm_task_set_name: strdup(%s) failed", name);
return 0;
}
More information about the lvm-devel
mailing list