+Mon Nov 03 12:37:00 CET 2008 Chris Lalancette <clalance@redhat.com>
+ * src/storage_backend.c src/storage_backend.h
+ src/storage_backend_disk.c src/storage_backend_iscsi.c
+ src/storage_driver.c: Give iSCSI and disk storage backend drivers the
+ ability to resolve any kind of volume path to the pool target volume
+ path. For instance, if the pool was defined with a
+ <target><path>/dev/disk/by-id</path></target> section, and one of the
+ volumes is /dev/disk/by-id/scsi-S_beaf11, then you would be able to
+ call virStorageVolLookupByPath("/dev/sdc"), and get the correct volume
+ back.
+
Fri Oct 31 14:55:46 CET 2008 Daniel Veillard <veillard@redhat.com>
* python/virConnect.py: needed for events from the python bindings
char *
virStorageBackendStablePath(virConnectPtr conn,
virStoragePoolObjPtr pool,
- char *devpath)
+ const char *devpath)
{
DIR *dh;
struct dirent *dent;
+ char *stablepath;
/* Short circuit if pool has no target, or if its /dev */
if (pool->def->target.path == NULL ||
STREQ(pool->def->target.path, "/dev") ||
STREQ(pool->def->target.path, "/dev/"))
- return devpath;
+ goto ret_strdup;
/* The pool is pointing somewhere like /dev/disk/by-path
* or /dev/disk/by-id, so we need to check all symlinks in
}
while ((dent = readdir(dh)) != NULL) {
- char *stablepath;
if (dent->d_name[0] == '.')
continue;
closedir(dh);
+ ret_strdup:
/* Couldn't find any matching stable link so give back
* the original non-stable dev path
*/
- return devpath;
+
+ stablepath = strdup(devpath);
+
+ if (stablepath == NULL)
+ virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("dup path"));
+
+ return stablepath;
}
VIR_STORAGE_BACKEND_POOL_SOURCE_DIR = (1<<2),
VIR_STORAGE_BACKEND_POOL_SOURCE_ADAPTER = (1<<3),
VIR_STORAGE_BACKEND_POOL_SOURCE_NAME = (1<<4),
+ VIR_STORAGE_BACKEND_POOL_STABLE_PATH = (1<<5),
};
enum partTableType {
char *virStorageBackendStablePath(virConnectPtr conn,
virStoragePoolObjPtr pool,
- char *devpath);
+ const char *devpath);
typedef int (*virStorageBackendListVolRegexFunc)(virConnectPtr conn,
virStoragePoolObjPtr pool,
devpath)) == NULL)
return -1;
- if (devpath != vol->target.path)
- VIR_FREE(devpath);
+ VIR_FREE(devpath);
}
if (vol->key == NULL) {
.deleteVol = virStorageBackendDiskDeleteVol,
.poolOptions = {
- .flags = (VIR_STORAGE_BACKEND_POOL_SOURCE_DEVICE),
+ .flags = (VIR_STORAGE_BACKEND_POOL_SOURCE_DEVICE|
+ VIR_STORAGE_BACKEND_POOL_STABLE_PATH),
.defaultFormat = VIR_STORAGE_POOL_DISK_UNKNOWN,
.formatFromString = virStorageBackendPartTableTypeFromString,
.formatToString = virStorageBackendPartTableTypeToString,
devpath)) == NULL)
goto cleanup;
- if (devpath != vol->target.path)
- VIR_FREE(devpath);
+ VIR_FREE(devpath);
if (virStorageBackendUpdateVolInfoFD(conn, vol, fd, 1) < 0)
goto cleanup;
.poolOptions = {
.flags = (VIR_STORAGE_BACKEND_POOL_SOURCE_HOST |
- VIR_STORAGE_BACKEND_POOL_SOURCE_DEVICE)
+ VIR_STORAGE_BACKEND_POOL_SOURCE_DEVICE |
+ VIR_STORAGE_BACKEND_POOL_STABLE_PATH)
},
.volType = VIR_STORAGE_VOL_BLOCK,
for (i = 0 ; i < driver->pools.count ; i++) {
if (virStoragePoolObjIsActive(driver->pools.objs[i])) {
- virStorageVolDefPtr vol =
- virStorageVolDefFindByPath(driver->pools.objs[i], path);
+ virStorageVolDefPtr vol;
+ virStorageBackendPoolOptionsPtr options;
+
+ options = virStorageBackendPoolOptionsForType(driver->pools.objs[i]->def->type);
+ if (options == NULL)
+ continue;
+
+ if (options->flags & VIR_STORAGE_BACKEND_POOL_STABLE_PATH) {
+ const char *stable_path;
+
+ stable_path = virStorageBackendStablePath(conn,
+ driver->pools.objs[i],
+ path);
+ /*
+ * virStorageBackendStablePath already does
+ * virStorageReportError if it fails; we just need to keep
+ * propagating the return code
+ */
+ if (stable_path == NULL)
+ return NULL;
+
+ vol = virStorageVolDefFindByPath(driver->pools.objs[i],
+ stable_path);
+ VIR_FREE(stable_path);
+ }
+ else
+ vol = virStorageVolDefFindByPath(driver->pools.objs[i], path);
+
if (vol)
return virGetStorageVol(conn,