[libvirt] [PATCH 0/1] Trigger SCSI scans on pool refresh

This patch is a small piece of code that causes the SCSI midlayer to rescan all targets for new LUs by echoing "- - -" into /sys/class/scsi_host/hostN/scan It does not attempt to cause a LIP to be issued. Dave

The scsi host code does not currently rescan for new LUs when refreshing a pool. This patch causes a scan for new LUs on all targets. It does not cause a LIP. --- src/storage_backend_scsi.c | 77 ++++++++++++++++++++++++++++++++++++++++++++ src/storage_backend_scsi.h | 1 + 2 files changed, 78 insertions(+), 0 deletions(-) diff --git a/src/storage_backend_scsi.c b/src/storage_backend_scsi.c index a962d1c..e30b3ce 100644 --- a/src/storage_backend_scsi.c +++ b/src/storage_backend_scsi.c @@ -480,6 +480,76 @@ out: static int +virStorageBackendSCSIStartPool(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED) +{ + int retval = 0; + + return retval; +} + + +static int +virStorageBackendSCSIStopPool(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED) +{ + int retval = 0; + + return retval; +} + + +static int +virStorageBackendSCSITriggerRescan(virConnectPtr conn, + uint32_t host) +{ + int fd = -1; + int retval = 0; + char *path; + + VIR_DEBUG(_("Triggering rescan of host %d"), host); + + if (virAsprintf(&path, "/sys/class/scsi_host/host%u/scan", host) < 0) { + virReportOOMError(conn); + retval = -1; + goto out; + } + + VIR_DEBUG(_("Scan trigger path is '%s'"), path); + + fd = open(path, O_WRONLY); + + if (fd < 0) { + virReportSystemError(conn, errno, + _("Could not open '%s' to trigger host scan"), + path); + retval = -1; + goto cleanup; + } + + if (write(fd, + LINUX_SYSFS_SCSI_HOST_SCAN_STRING, + sizeof(LINUX_SYSFS_SCSI_HOST_SCAN_STRING)) < 0) { + + virReportSystemError(conn, errno, + _("Write to '%s' to trigger host scan failed"), + path); + retval = -1; + goto cleanup; + } + + goto out; + +cleanup: + VIR_FREE(path); + +out: + VIR_DEBUG(_("Rescan of host %d complete"), host); + return retval; +} + + +static int virStorageBackendSCSIRefreshPool(virConnectPtr conn, virStoragePoolObjPtr pool) { @@ -496,6 +566,11 @@ virStorageBackendSCSIRefreshPool(virConnectPtr conn, VIR_DEBUG(_("Scanning host%u"), host); + if (virStorageBackendSCSITriggerRescan(conn, host) < 0) { + retval = -1; + goto out; + } + virStorageBackendSCSIFindLUs(conn, pool, host); out: @@ -506,5 +581,7 @@ out: virStorageBackend virStorageBackendSCSI = { .type = VIR_STORAGE_POOL_SCSI, + .startPool = virStorageBackendSCSIStartPool, .refreshPool = virStorageBackendSCSIRefreshPool, + .stopPool = virStorageBackendSCSIStopPool, }; diff --git a/src/storage_backend_scsi.h b/src/storage_backend_scsi.h index 808d47b..d130086 100644 --- a/src/storage_backend_scsi.h +++ b/src/storage_backend_scsi.h @@ -28,6 +28,7 @@ #define LINUX_SYSFS_SCSI_HOST_PREFIX "/sys/class/scsi_host" #define LINUX_SYSFS_SCSI_HOST_POSTFIX "device" +#define LINUX_SYSFS_SCSI_HOST_SCAN_STRING "- - -" extern virStorageBackend virStorageBackendSCSI; -- 1.6.0.6

On Fri, Apr 03, 2009 at 04:53:07PM -0400, David Allan wrote:
The scsi host code does not currently rescan for new LUs when refreshing a pool. This patch causes a scan for new LUs on all targets. It does not cause a LIP.
LIP ?
static int +virStorageBackendSCSIStartPool(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED) +{ + int retval = 0; + + return retval; +} + + +static int +virStorageBackendSCSIStopPool(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED) +{ + int retval = 0; + + return retval; +}
Is that really better than suggesting the operation is not supported ? [...]
+ if (virAsprintf(&path, "/sys/class/scsi_host/host%u/scan", host) < 0) { + virReportOOMError(conn); + retval = -1; + goto out; + } + + VIR_DEBUG(_("Scan trigger path is '%s'"), path); + + fd = open(path, O_WRONLY); + + if (fd < 0) { + virReportSystemError(conn, errno, + _("Could not open '%s' to trigger host scan"), + path); + retval = -1; + goto cleanup; + } + + if (write(fd, + LINUX_SYSFS_SCSI_HOST_SCAN_STRING, + sizeof(LINUX_SYSFS_SCSI_HOST_SCAN_STRING)) < 0) { + + virReportSystemError(conn, errno, + _("Write to '%s' to trigger host scan failed"), + path); + retval = -1; + goto cleanup; + } + + goto out;
Seems to me that goto should be suppressed, it just generate a leak of path On the other hand fd is leaked for sure ... This really need some double-checking ;-)
+cleanup: + VIR_FREE(path); + +out: + VIR_DEBUG(_("Rescan of host %d complete"), host); + return retval; +}
Otherwise, sounds fine, as long as this doesn't generate a bus reset. Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Daniel Veillard wrote:
On Fri, Apr 03, 2009 at 04:53:07PM -0400, David Allan wrote:
The scsi host code does not currently rescan for new LUs when refreshing a pool. This patch causes a scan for new LUs on all targets. It does not cause a LIP.
LIP ?
Loop Initialization Primitive, required to discover new targets on fibre channel HBAs. Causing one to be issued is disruptive to IO on the host, so this patch does not do that. It does mean that there is no way through libvirt to discover new targets that have been zoned to the host subsequent to boot.
static int +virStorageBackendSCSIStartPool(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED) +{ + int retval = 0; + + return retval; +} + + +static int +virStorageBackendSCSIStopPool(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED) +{ + int retval = 0; + + return retval; +}
Is that really better than suggesting the operation is not supported ?
These two functions are, of course, not required for this patch. They're there because I had started to implement NPIV support and then thought I should submit this patch before the NPIV patch. I can take them out if you'd like and add them to the subsequent patch where they will have contents.
[...]
+ if (virAsprintf(&path, "/sys/class/scsi_host/host%u/scan", host) < 0) { + virReportOOMError(conn); + retval = -1; + goto out; + } + + VIR_DEBUG(_("Scan trigger path is '%s'"), path); + + fd = open(path, O_WRONLY); + + if (fd < 0) { + virReportSystemError(conn, errno, + _("Could not open '%s' to trigger host scan"), + path); + retval = -1; + goto cleanup; + } + + if (write(fd, + LINUX_SYSFS_SCSI_HOST_SCAN_STRING, + sizeof(LINUX_SYSFS_SCSI_HOST_SCAN_STRING)) < 0) { + + virReportSystemError(conn, errno, + _("Write to '%s' to trigger host scan failed"), + path); + retval = -1; + goto cleanup; + } + + goto out;
Seems to me that goto should be suppressed, it just generate a leak of path On the other hand fd is leaked for sure ... This really need some double-checking ;-)
Ugh, sorry about that. Fixed, thanks.
+cleanup: + VIR_FREE(path); + +out: + VIR_DEBUG(_("Rescan of host %d complete"), host); + return retval; +}
Otherwise, sounds fine, as long as this doesn't generate a bus reset.
It doesn't generate a bus reset. As I mentioned above, this code is not IO disruptive. I haven't decided on what I think is the right way to do scans that are IO disruptive. I've attached a patch with a fix for the leaks. It also adds \n to the scan string. Dave
From 7f2c35b22fbce4ee28d276d870a6eacdfd207c3f Mon Sep 17 00:00:00 2001 From: David Allan <dallan@redhat.com> Date: Mon, 6 Apr 2009 11:16:03 -0400 Subject: [PATCH 2/2] Fix bugs per DV
Removed goto causing fd and memory leak. Added \n to scan string. --- src/storage_backend_scsi.c | 9 +++------ 1 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/storage_backend_scsi.c b/src/storage_backend_scsi.c index e30b3ce..bb945dc 100644 --- a/src/storage_backend_scsi.c +++ b/src/storage_backend_scsi.c @@ -524,7 +524,7 @@ virStorageBackendSCSITriggerRescan(virConnectPtr conn, _("Could not open '%s' to trigger host scan"), path); retval = -1; - goto cleanup; + goto free_path; } if (write(fd, @@ -535,14 +535,11 @@ virStorageBackendSCSITriggerRescan(virConnectPtr conn, _("Write to '%s' to trigger host scan failed"), path); retval = -1; - goto cleanup; } - goto out; - -cleanup: + close(fd); +free_path: VIR_FREE(path); - out: VIR_DEBUG(_("Rescan of host %d complete"), host); return retval; -- 1.6.0.6

On Mon, Apr 06, 2009 at 11:41:48AM -0400, Dave Allan wrote:
static int +virStorageBackendSCSIStartPool(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED) +{ + int retval = 0; + + return retval; +} + + +static int +virStorageBackendSCSIStopPool(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED) +{ + int retval = 0; + + return retval; +}
Is that really better than suggesting the operation is not supported ?
These two functions are, of course, not required for this patch. They're there because I had started to implement NPIV support and then thought I should submit this patch before the NPIV patch. I can take them out if you'd like and add them to the subsequent patch where they will have contents.
Yep, prefer to leave them out if they're unrelated to this patch.
[...]
+ if (virAsprintf(&path, "/sys/class/scsi_host/host%u/scan", host) < 0) { + virReportOOMError(conn); + retval = -1; + goto out; + } + + VIR_DEBUG(_("Scan trigger path is '%s'"), path); + + fd = open(path, O_WRONLY); + + if (fd < 0) { + virReportSystemError(conn, errno, + _("Could not open '%s' to trigger host scan"), + path); + retval = -1; + goto cleanup; + } + + if (write(fd, + LINUX_SYSFS_SCSI_HOST_SCAN_STRING, + sizeof(LINUX_SYSFS_SCSI_HOST_SCAN_STRING)) < 0) { + + virReportSystemError(conn, errno, + _("Write to '%s' to trigger host scan failed"), + path); + retval = -1; + goto cleanup; + } + + goto out;
Seems to me that goto should be suppressed, it just generate a leak of path On the other hand fd is leaked for sure ... This really need some double-checking ;-)
Ugh, sorry about that. Fixed, thanks.
+cleanup: + VIR_FREE(path); + +out: + VIR_DEBUG(_("Rescan of host %d complete"), host); + return retval; +}
Otherwise, sounds fine, as long as this doesn't generate a bus reset.
It doesn't generate a bus reset. As I mentioned above, this code is not IO disruptive. I haven't decided on what I think is the right way to do scans that are IO disruptive.
I've attached a patch with a fix for the leaks. It also adds \n to the scan string.
Dave
From 7f2c35b22fbce4ee28d276d870a6eacdfd207c3f Mon Sep 17 00:00:00 2001 From: David Allan <dallan@redhat.com> Date: Mon, 6 Apr 2009 11:16:03 -0400 Subject: [PATCH 2/2] Fix bugs per DV
Removed goto causing fd and memory leak.
Added \n to scan string. --- src/storage_backend_scsi.c | 9 +++------ 1 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/storage_backend_scsi.c b/src/storage_backend_scsi.c index e30b3ce..bb945dc 100644 --- a/src/storage_backend_scsi.c +++ b/src/storage_backend_scsi.c @@ -524,7 +524,7 @@ virStorageBackendSCSITriggerRescan(virConnectPtr conn, _("Could not open '%s' to trigger host scan"), path); retval = -1; - goto cleanup; + goto free_path; }
if (write(fd, @@ -535,14 +535,11 @@ virStorageBackendSCSITriggerRescan(virConnectPtr conn, _("Write to '%s' to trigger host scan failed"), path); retval = -1; - goto cleanup; }
- goto out; - -cleanup: + close(fd); +free_path: VIR_FREE(path); - out: VIR_DEBUG(_("Rescan of host %d complete"), host); return retval;
ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Tue, Apr 07, 2009 at 10:21:37AM +0100, Daniel P. Berrange wrote:
On Mon, Apr 06, 2009 at 11:41:48AM -0400, Dave Allan wrote:
static int +virStorageBackendSCSIStartPool(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED) +{ + int retval = 0; + + return retval; +} + + +static int +virStorageBackendSCSIStopPool(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED) +{ + int retval = 0; + + return retval; +}
Is that really better than suggesting the operation is not supported ?
These two functions are, of course, not required for this patch. They're there because I had started to implement NPIV support and then thought I should submit this patch before the NPIV patch. I can take them out if you'd like and add them to the subsequent patch where they will have contents.
Yep, prefer to leave them out if they're unrelated to this patch. [...]
ACK
Okay, so I commited a version without virStorageBackendSCSIStartPool and Stop, I also changed the write() call to safewrite() ! thanks ! Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Daniel Veillard wrote:
On Tue, Apr 07, 2009 at 10:21:37AM +0100, Daniel P. Berrange wrote:
On Mon, Apr 06, 2009 at 11:41:48AM -0400, Dave Allan wrote:
static int +virStorageBackendSCSIStartPool(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED) +{ + int retval = 0; + + return retval; +} + + +static int +virStorageBackendSCSIStopPool(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED) +{ + int retval = 0; + + return retval; +} Is that really better than suggesting the operation is not supported ? These two functions are, of course, not required for this patch. They're there because I had started to implement NPIV support and then thought I should submit this patch before the NPIV patch. I can take them out if you'd like and add them to the subsequent patch where they will have contents. Yep, prefer to leave them out if they're unrelated to this patch. [...] ACK
Okay, so I commited a version without virStorageBackendSCSIStartPool and Stop, I also changed the write() call to safewrite() !
Ok, great--thanks! Dave
participants (4)
-
Daniel P. Berrange
-
Daniel Veillard
-
Dave Allan
-
David Allan