[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] Re: [Libvir] ISCSI howto, example, etc?



Stefan de Konink wrote:
> I think if you can get iscsi_sysfs.c; get_block_dev_from_lun you have the
> code already to do this all. So basically get openiscsi into a lib with
> helper functions.

OK.  I took a look at this further, and I figured out what is going on here.

The original impetus for me to re-write the code in
virStorageBackendISCSIMakeLUN() was because I thought the open-iscsi people had
changed the output of iscsiadm --mode session -r $session -P 3.  However, that's
not what actually happened.  What actually happened is that the sysfs files that
export this information changed somewhere between 2.6.21 and 2.6.24 (which is
what I was using at the time).  So, the code you point to above in open-iscsi
tools *also* doesn't work.  That code is expecting the block devices to look
like block:sdd, which is what you have in your 2.6.21 kernel; but in later
kernels, it no longer looks like that.

All that being said, the less we have to depend on parsing, and the more we can
poke around sysfs and get values, the better.  So in that sense, the change was
for the better.  I've attached a patch which seems to do the right thing on my
2.6.25 based machine; can you test it on 2.6.21 and see if it works?

Chris Lalancette
Index: src/storage_backend_iscsi.c
===================================================================
RCS file: /data/cvs/libvirt/src/storage_backend_iscsi.c,v
retrieving revision 1.5
diff -u -r1.5 storage_backend_iscsi.c
--- a/src/storage_backend_iscsi.c	10 Apr 2008 16:53:29 -0000	1.5
+++ b/src/storage_backend_iscsi.c	21 May 2008 14:49:14 -0000
@@ -170,7 +170,7 @@
 virStorageBackendISCSIMakeLUN(virConnectPtr conn,
                               virStoragePoolObjPtr pool,
                               char **const groups,
-                              void *data)
+                              void *data ATTRIBUTE_UNUSED)
 {
     virStorageVolDefPtr vol;
     int fd = -1;
@@ -178,13 +178,12 @@
     char lunid[100];
     int opentries = 0;
     char *devpath = NULL;
-    char *session = data;
     char sysfs_path[PATH_MAX];
     char *dev = NULL;
     DIR *sysdir;
     struct dirent *block_dirent;
-    struct stat sbuf;
     int len;
+    int new_style_sysfs;
 
     if ((virStrToLong_ui(groups[0], NULL, 10, &target) < 0) ||
         (virStrToLong_ui(groups[1], NULL, 10, &channel) < 0) ||
@@ -200,26 +199,33 @@
         return 0;
     }
 
-    snprintf(sysfs_path, PATH_MAX,
-             "/sys/class/iscsi_session/session%s/device/"
-             "target%d:%d:%d/%d:%d:%d:%d/block",
-             session, target, channel, id, target, channel, id, lun);
+    /* There are two styles of sysfs paths that we have to worry about; the
+     * old style and the new style.  The old style is of the form:
+     * /sys/bus/scsi/devices/target:channel:id:lun/block:sdd
+     *
+     * while the new style is of the form:
+     * /sys/bus/scsi/devices/target:channel:id:lun/block/sdd
+     */
 
-    if (stat(sysfs_path, &sbuf) < 0) {
-        /* block path in subdir didn't exist; this is unexpected, so fail */
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("Failed to find the sysfs path for %d:%d:%d:%d: %s"),
-                              target, channel, id, lun, strerror(errno));
-        return -1;
-    }
+    /* First try the new style */
+    new_style_sysfs = 1;
+    snprintf(sysfs_path, PATH_MAX, "/sys/bus/scsi/devices/%d:%d:%d:%d/block",
+                target, channel, id, lun);
 
     sysdir = opendir(sysfs_path);
     if (sysdir == NULL) {
-        /* we failed for some reason; return an error */
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                              _("Failed to opendir sysfs path %s: %s"),
-                              sysfs_path, strerror(errno));
-        return -1;
+        /* OK, maybe this is the old style */
+        snprintf(sysfs_path, PATH_MAX, "/sys/bus/scsi/devices/%d:%d:%d:%d",
+                    target, channel, id, lun);
+        sysdir = opendir(sysfs_path);
+        if (sysdir == NULL) {
+            /* OK, wasn't new or old style; something we don't understand */
+            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                                    _("Failed to opendir sysfs path %s: %s"),
+                                    sysfs_path, strerror(errno));
+            return -1;
+        }
+        new_style_sysfs = 0;
     }
 
     while ((block_dirent = readdir(sysdir)) != NULL) {
@@ -229,16 +235,19 @@
             /* the . and .. directories; just skip them */
             continue;
         }
-
-        /* OK, not . or ..; let's see if it is a SCSI device */
-        if (len > 2 &&
+		
+        if (new_style_sysfs && len > 2 &&
             block_dirent->d_name[0] == 's' &&
             block_dirent->d_name[1] == 'd') {
-            /* looks like a scsi device, smells like scsi device; it must be
-               a scsi device */
             dev = strdup(block_dirent->d_name);
             break;
         }
+
+        if (!new_style_sysfs && len > 6 &&
+            strncmp(block_dirent->d_name, "block:", 6) == 0) {
+            dev = strdup(block_dirent->d_name + 6);
+            break;
+        }
     }
     closedir(sysdir);
 

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]