diff --git a/src/storage_backend_iscsi.c b/src/storage_backend_iscsi.c index b516add..3f2a79d 100644 --- a/src/storage_backend_iscsi.c +++ b/src/storage_backend_iscsi.c @@ -39,6 +39,10 @@ #include "storage_backend_iscsi.h" #include "util.h" #include "memory.h" +#include +#include +#include +#include #define VIR_FROM_THIS VIR_FROM_STORAGE @@ -159,13 +163,57 @@ virStorageBackendISCSIConnection(virConnectPtr conn, const char *portal, const char *action) { - const char *const cmdargv[] = { - ISCSIADM, "--mode", "node", "--portal", portal, - "--targetname", pool->def->source.devices[0].path, action, NULL - }; - - if (virRun(conn, cmdargv, NULL) < 0) - return -1; + DIR *dir; + struct dirent *entry; + + + if (pool->def->source.initiator[0].iqnname != NULL) { + int i = 0; + while(pool->def->source.initiator[i].iqnname != NULL){ + if (!(dir = opendir(IFACES_DIR))) { + if (errno == ENOENT) + return 0; + virReportSystemError(conn, errno, _("Failed to open dir '%s'"), + IFACES_DIR); + return -1; + } + while ((entry = readdir(dir))) { + FILE *fp; + char path[PATH_MAX]; + + if (entry->d_name[0] == '.') + continue; + + sprintf(path,"%s", IFACES_DIR); + strcat(path,(const char *)entry->d_name); + + if ((fp = fopen(path, "r"))){ + char buff[256]; + while (fp != NULL && fgets(buff, sizeof(buff), fp) != NULL) { + if (strstr(buff, pool->def->source.initiator[i].iqnname) != NULL) { + const char *const cmdargv[] = { + ISCSIADM, "--mode", "node", "--portal", portal, + "--targetname", pool->def->source.devices[0].path, "-I", entry->d_name, action, NULL + }; + + if (virRun(conn, cmdargv, NULL) < 0) + return -1; + } + } + } + fclose(fp); + } + i++; + } + } + else{ + const char *const cmdargv[] = { + ISCSIADM, "--mode", "node", "--portal", portal, + "--targetname", pool->def->source.devices[0].path, action, NULL + }; + if (virRun(conn, cmdargv, NULL) < 0) + return -1; + } return 0; } diff --git a/src/storage_backend_iscsi.h b/src/storage_backend_iscsi.h index 665ed13..14c2c5c 100644 --- a/src/storage_backend_iscsi.h +++ b/src/storage_backend_iscsi.h @@ -25,7 +25,7 @@ #define __VIR_STORAGE_BACKEND_ISCSI_H__ #include "storage_backend.h" - extern virStorageBackend virStorageBackendISCSI; +#define IFACES_DIR "/var/lib/iscsi/ifaces/" #endif /* __VIR_STORAGE_BACKEND_ISCSI_H__ */ diff --git a/src/storage_conf.c b/src/storage_conf.c index 788de15..0f2ace9 100644 --- a/src/storage_conf.c +++ b/src/storage_conf.c @@ -106,12 +106,13 @@ struct _virStorageVolOptions { /* Flags to indicate mandatory components in the pool source */ enum { - VIR_STORAGE_POOL_SOURCE_HOST = (1<<0), - VIR_STORAGE_POOL_SOURCE_DEVICE = (1<<1), - VIR_STORAGE_POOL_SOURCE_DIR = (1<<2), - VIR_STORAGE_POOL_SOURCE_ADAPTER = (1<<3), - VIR_STORAGE_POOL_SOURCE_NAME = (1<<4), -}; + VIR_STORAGE_POOL_SOURCE_HOST = (1<<0), + VIR_STORAGE_POOL_SOURCE_DEVICE = (1<<1), + VIR_STORAGE_POOL_SOURCE_DIR = (1<<2), + VIR_STORAGE_POOL_SOURCE_ADAPTER = (1<<3), + VIR_STORAGE_POOL_SOURCE_NAME = (1<<4), + VIR_STORAGE_POOL_SOURCE_INITIATOR_IQN = (1<<5), + }; @@ -179,7 +180,8 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { { .poolType = VIR_STORAGE_POOL_ISCSI, .poolOptions = { .flags = (VIR_STORAGE_POOL_SOURCE_HOST | - VIR_STORAGE_POOL_SOURCE_DEVICE), + VIR_STORAGE_POOL_SOURCE_DEVICE | + VIR_STORAGE_POOL_SOURCE_INITIATOR_IQN), }, .volOptions = { .formatToString = virStoragePoolFormatDiskTypeToString, @@ -532,6 +534,34 @@ virStoragePoolDefParseXML(virConnectPtr conn, goto cleanup; } } + + if(options->flags & VIR_STORAGE_POOL_SOURCE_INITIATOR_IQN) { + xmlNodePtr *nodeset = NULL; + int niqn, i; + + if((niqn = virXPathNodeSet(conn, "./initiator/iqnname", ctxt, &nodeset)) < 0) { + virStorageReportError(conn, VIR_ERR_XML_ERROR, + "%s", _("cannot extract storage pool source devices")); + goto cleanup; + } + if (VIR_ALLOC_N(ret->source.initiator, niqn) < 0) { + VIR_FREE(nodeset); + virReportOOMError(conn); + goto cleanup; + } + for (i = 0 ; i < niqn ; i++) { + xmlChar *name = xmlGetProp(nodeset[i], BAD_CAST "name"); + if (name == NULL) { + VIR_FREE(nodeset); + virStorageReportError(conn, VIR_ERR_XML_ERROR, + "%s", _("missing storage pool source device path")); + goto cleanup; + } + ret->source.initiator[i].iqnname = (char *)name; + } + VIR_FREE(nodeset); + } + if (options->flags & VIR_STORAGE_POOL_SOURCE_DEVICE) { xmlNodePtr *nodeset = NULL; int nsource, i; diff --git a/src/storage_conf.h b/src/storage_conf.h index 9fedb12..c77d6ae 100644 --- a/src/storage_conf.h +++ b/src/storage_conf.h @@ -182,6 +182,13 @@ struct _virStoragePoolSourceDeviceExtent { int type; /* free space type */ }; +typedef struct _virStoragePoolSourceInitiatorAttr virStoragePoolSourceInitiatorAttr; +typedef virStoragePoolSourceInitiatorAttr *virStoragePoolSourceInitiatorAttrPtr; +struct _virStoragePoolSourceInitiatorAttr { + /* Initiator iqn name */ + char *iqnname; +}; + /* * Pools can be backed by one or more devices, and some * allow us to track free space on underlying devices. @@ -223,6 +230,9 @@ struct _virStoragePoolSource { /* Or a name */ char *name; + /* One or more initiator names */ + virStoragePoolSourceInitiatorAttrPtr initiator; + int authType; /* virStoragePoolAuthType */ union { virStoragePoolAuthChap chap;