Hello,
The newer version of iscsi-initiator-utils (6.2.0.865-0.2),
available in the f8-updates repository, is required as part of the fix
for a hang when doing iscsi logout (the other fix is in the 2.6.25
kernel). Unfortunately, this version also changes the output of the
iscsiadm -m session -P 3 command; this output was being used to gather
the scsi devices available in a pool and present them as volumes.
Consequently, when starting an iSCSI pool on a machine with these newer
versions of the iscsi tools, the pool will be successfully created but
you won't be able to see any of the LUNs presented.
The attached patch *lessens* our dependency on the iscsiadm output by
using sysfs to gather the /dev devices. Note that this patch is not to
be applied; I'm just putting it out there so people can take a look at
it. DanB has suggested getting rid of our dependency on the iscsiadm
output altogether is the way to go, and I agree with him there; this is
mostly just a short-term solution, to possibly base future work on.
Chris Lalancette
--- libvirt-0.4.0/src/storage_backend_iscsi.c.orig 2008-02-22 15:56:03.000000000 -0500
+++ libvirt-0.4.0/src/storage_backend_iscsi.c 2008-02-22 15:57:38.000000000 -0500
@@ -161,24 +161,59 @@ static int virStorageBackendISCSIConnect
static int virStorageBackendISCSIMakeLUN(virConnectPtr conn,
virStoragePoolObjPtr pool,
char **const groups,
- void *data ATTRIBUTE_UNUSED)
+ void *data)
{
virStorageVolDefPtr vol;
int fd = -1;
- char scsiid[100];
- char *dev = groups[4];
+ unsigned int channel;
+ char lunid[100];
int opentries = 0;
char *devpath = NULL;
+ char *session = (char *) data;
+ char sysfs_path[PATH_MAX];
+ char *dev = NULL;
+ DIR *sysdir;
+ struct dirent *block_dirent;
+ struct stat sbuf;
+ int len;
+
+ channel = strtoul(groups[1],NULL,10);
+
+ snprintf(sysfs_path, PATH_MAX, "/sys/class/iscsi_session/session%s/device/target%s:%.1d:%s/%s:%.1d:%s:%s/block",session,groups[0],channel,groups[2],groups[0],channel,groups[2],groups[3]);
+
+ if (stat(sysfs_path, &sbuf) < 0) {
+ // OK, block path in subdir didn't exist. This is probably the 0'th
+ // LUN that isn't really a block device. Just return 0 so we go on
+ return 0;
+ }
+ sysdir = opendir(sysfs_path);
+ if (sysdir == NULL) {
+ // we failed for some reason; return an error
+ return -1;
+ }
+ while ( (block_dirent = readdir(sysdir)) != NULL) {
+ len = strlen(block_dirent->d_name);
+ if ((len == 1 && block_dirent->d_name[0] == '.') ||
+ (len == 2 && block_dirent->d_name[0] == '.' && block_dirent->d_name[1] == '.')) {
+ // the . and .. directories; just skip them
+ continue;
+ }
+ // OK, not . or ..; must be our block device
+ dev = strdup(block_dirent->d_name);
+ break;
+ }
+ closedir(sysdir);
+
+ // FIXME: if dev is still NULL, it is an error here
- snprintf(scsiid, sizeof(scsiid)-1, "%s:%s:%s:%s",
- groups[0], groups[1], groups[2], groups[3]);
+ snprintf(lunid, sizeof(lunid)-1, "lun-%s", groups[3]);
if ((vol = calloc(1, sizeof(virStorageVolDef))) == NULL) {
virStorageReportError(conn, VIR_ERR_NO_MEMORY, "volume");
return -1;
}
- if ((vol->name = strdup(scsiid)) == NULL) {
+ if ((vol->name = strdup(lunid)) == NULL) {
virStorageReportError(conn, VIR_ERR_NO_MEMORY, "name");
goto cleanup;
}
@@ -189,6 +224,8 @@ static int virStorageBackendISCSIMakeLUN
}
strcpy(devpath, "/dev/");
strcat(devpath, dev);
+ free(dev);
+ dev = NULL;
/* It can take a little while between logging into the ISCSI
* server and udev creating the /dev nodes, so if we get ENOENT
* we must retry a few times - they should eventually appear.
@@ -248,6 +285,7 @@ static int virStorageBackendISCSIMakeLUN
if (fd != -1) close(fd);
free(devpath);
virStorageVolDefFree(vol);
+ free(dev);
return -1;
}
@@ -273,11 +311,10 @@ static int virStorageBackendISCSIFindLUN
* Need 2 regex to match alternating lines
*/
const char *regexes[] = {
- "^\\s*scsi(\\S+)\\s+Channel\\s+(\\S+)\\s+Id\\s+(\\S+)\\s+Lun:\\s+(\\S+)\\s*$",
- "^\\s*Attached\\s+scsi\\s+disk\\s+(\\S+)\\s+State:\\s+running\\s*$"
+ "^\\s*scsi(\\S+)\\s+Channel\\s+(\\S+)\\s+Id\\s+(\\S+)\\s+Lun:\\s+(\\S+)\\s*$"
};
int vars[] = {
- 4, 1
+ 4
};
const char *prog[] = {
ISCSIADM, "--mode", "session", "-r", session, "-P", "3", NULL,
@@ -285,11 +322,11 @@ static int virStorageBackendISCSIFindLUN
return virStorageBackendRunProgRegex(conn, pool,
prog,
- 2,
+ 1,
regexes,
vars,
virStorageBackendISCSIMakeLUN,
- NULL);
+ (void *)session);
}
--
Libvir-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/libvir-list