[libvirt] [PATCH 1/1] Add SCSI pool support.
Daniel P. Berrange
berrange at redhat.com
Mon Mar 30 11:33:47 UTC 2009
On Sat, Mar 28, 2009 at 10:40:48AM -0400, Dave Allan wrote:
> Daniel P. Berrange wrote:
>
> >This unfortauntely does not work on RHEL5, because there are no targetX.X.X
> >links here. Only the LUNs appear in this directory.
> >
> >The location which appears to be present on both old and new kernels is
> >under:
> >
> > /sys/class/scsi_host/host0/device/targetX.X.X
> >
> >This appears to be present for both SCSI and iSCSI hosts.
>
> Unfortunately, that directory isn't present for FC hosts on F10. :(
> I've put together a scan strategy that I think will for for both RHEL5
> and F10 for all transport types. Let me know if it works for you. The
> attached patch should be applied on top of the udev fix I sent
> yesterday. This patch is another one that doesn't read well as a patch,
> but should be pretty straightforward once it's applied.
>
> I have not addressed the question of what device types to allow, because
> I want to think about that one a bit more.
>
> I also took out the unused struct you noticed.
>
> Thanks for all the feedback and testing.
This works now on RHEL-5, F9 and F10.
I still had to disable this code
if (STREQLEN(devpath, vol->target.path, PATH_MAX)) {
VIR_DEBUG(_("No stable path found for '%s' in '%s'"),
devpath, pool->def->target.path);
retval = -1;
goto free_vol;
}
because it breaks pools configured with a target dir of /dev/
And add device_type == 5 to allow CDROMs to work
if (device_type != 0 &&
device_type != 5) {
retval = 0;
goto out;
}
> From c749c3cc3d90cf9ae31db0c68fd41b7ce24c2bf3 Mon Sep 17 00:00:00 2001
> From: David Allan <dallan at redhat.com>
> Date: Fri, 27 Mar 2009 17:48:18 -0400
> Subject: [PATCH 1/1] Changes based on feedback from DanPB
>
> * Fixed LU scan logic so that it now hopefully works for all transport types on both RHEL5 and F10. The preceeding version didn't work on RHEL5.
> * Removed the unused struct from storage_backend_scsi.h
> ---
> src/storage_backend_iscsi.c | 20 ++++++++++----
> src/storage_backend_scsi.c | 61 +++++++++++++++++++-----------------------
> src/storage_backend_scsi.h | 24 +++++------------
> 3 files changed, 49 insertions(+), 56 deletions(-)
>
> diff --git a/src/storage_backend_iscsi.c b/src/storage_backend_iscsi.c
> index 9da7cdc..b516add 100644
> --- a/src/storage_backend_iscsi.c
> +++ b/src/storage_backend_iscsi.c
> @@ -172,23 +172,31 @@ virStorageBackendISCSIConnection(virConnectPtr conn,
>
>
> static int
> -virStorageBackendISCSIFindLUNs(virConnectPtr conn,
> - virStoragePoolObjPtr pool,
> - const char *session)
> +virStorageBackendISCSIFindLUs(virConnectPtr conn,
> + virStoragePoolObjPtr pool,
> + const char *session)
> {
> char sysfs_path[PATH_MAX];
> int retval = 0;
> + uint32_t host;
>
> snprintf(sysfs_path, PATH_MAX,
> "/sys/class/iscsi_session/session%s/device", session);
>
> - if (virStorageBackendSCSIFindTargets(conn, pool, sysfs_path, "target") < 0) {
> + if (virStorageBackendSCSIGetHostNumber(conn, sysfs_path, &host) < 0) {
> virReportSystemError(conn, errno,
> - _("Failed to get target list for path '%s'"),
> + _("Failed to get host number for iSCSI session "
> + "with path '%s'"),
> sysfs_path);
> retval = -1;
> }
>
> + if (virStorageBackendSCSIFindLUs(conn, pool, host) < 0) {
> + virReportSystemError(conn, errno,
> + _("Failed to find LUs on host %u"), host);
> + retval = -1;
> + }
> +
> return retval;
> }
>
> @@ -302,7 +310,7 @@ virStorageBackendISCSIRefreshPool(virConnectPtr conn,
> goto cleanup;
> if (virStorageBackendISCSIRescanLUNs(conn, pool, session) < 0)
> goto cleanup;
> - if (virStorageBackendISCSIFindLUNs(conn, pool, session) < 0)
> + if (virStorageBackendISCSIFindLUs(conn, pool, session) < 0)
> goto cleanup;
> VIR_FREE(session);
>
> diff --git a/src/storage_backend_scsi.c b/src/storage_backend_scsi.c
> index e0ced8f..2c5168a 100644
> --- a/src/storage_backend_scsi.c
> +++ b/src/storage_backend_scsi.c
> @@ -382,68 +382,67 @@ out:
> }
>
>
> -static int
> +int
> virStorageBackendSCSIFindLUs(virConnectPtr conn,
> virStoragePoolObjPtr pool,
> - uint32_t scanhost,
> - uint32_t scanbus,
> - uint32_t scantarget)
> + uint32_t scanhost)
> {
> int retval = 0;
> - uint32_t host, bus, target, lun;
> - char *target_path = NULL;
> - DIR *targetdir = NULL;
> + uint32_t bus, target, lun;
> + char *device_path = NULL;
> + DIR *devicedir = NULL;
> struct dirent *lun_dirent = NULL;
> + char devicepattern[64];
> +
> + VIR_DEBUG(_("Discovering LUs on host %u"), scanhost);
>
> - VIR_DEBUG(_("Discovering LUs on host %u bus %u target %u"),
> - scanhost, scanbus, scantarget);
> + virStorageBackendWaitForDevices(conn);
>
> - if (virAsprintf(&target_path, "/sys/bus/scsi/devices/target%u:%u:%u",
> - scanhost, scanbus, scantarget) < 0) {
> + if (virAsprintf(&device_path, "/sys/bus/scsi/devices") < 0) {
> virReportOOMError(conn);
> goto out;
> }
>
> - targetdir = opendir(target_path);
> + devicedir = opendir(device_path);
>
> - if (targetdir == NULL) {
> + if (devicedir == NULL) {
> virReportSystemError(conn, errno,
> - _("Failed to opendir path '%s'"), target_path);
> + _("Failed to opendir path '%s'"), device_path);
> retval = -1;
> goto out;
> }
>
> - while ((lun_dirent = readdir(targetdir))) {
> - if (sscanf(lun_dirent->d_name, "%u:%u:%u:%u\n",
> - &host, &bus, &target, &lun) != 4) {
> + snprintf(devicepattern, sizeof(devicepattern), "%u:%%u:%%u:%%u\n", scanhost);
> +
> + while ((lun_dirent = readdir(devicedir))) {
> + if (sscanf(lun_dirent->d_name, devicepattern,
> + &bus, &target, &lun) != 3) {
> continue;
> }
>
> VIR_DEBUG(_("Found LU '%s'"), lun_dirent->d_name);
>
> - processLU(conn, pool, host, bus, target, lun);
> + processLU(conn, pool, scanhost, bus, target, lun);
> }
>
> - closedir(targetdir);
> + closedir(devicedir);
>
> out:
> - VIR_FREE(target_path);
> + VIR_FREE(device_path);
> return retval;
> }
>
>
> int
> -virStorageBackendSCSIFindTargets(virConnectPtr conn,
> - virStoragePoolObjPtr pool,
> - const char *sysfs_path,
> - const char *pattern)
> +virStorageBackendSCSIGetHostNumber(virConnectPtr conn,
> + const char *sysfs_path,
> + uint32_t *host)
> {
> int retval = 0;
> - uint32_t host, bus, target;
> DIR *sysdir = NULL;
> struct dirent *dirent = NULL;
>
> - VIR_DEBUG(_("Discovering targets in '%s'"), sysfs_path);
> + VIR_DEBUG(_("Finding host number from '%s'"), sysfs_path);
>
> virStorageBackendWaitForDevices(conn);
>
> @@ -457,14 +456,13 @@ virStorageBackendSCSIFindTargets(virConnectPtr conn,
> }
>
> while ((dirent = readdir(sysdir))) {
> - if (STREQLEN(dirent->d_name, pattern, strlen(pattern))) {
> + if (STREQLEN(dirent->d_name, "target", strlen("target"))) {
> if (sscanf(dirent->d_name,
> - "target%u:%u:%u", &host, &bus, &target) != 3) {
> + "target%u:", host) != 1) {
> VIR_DEBUG(_("Failed to parse target '%s'"), dirent->d_name);
> retval = -1;
> break;
> }
> - virStorageBackendSCSIFindLUs(conn, pool, host, bus, target);
> }
> }
>
> @@ -478,7 +476,6 @@ static int
> virStorageBackendSCSIRefreshPool(virConnectPtr conn,
> virStoragePoolObjPtr pool)
> {
> - char targetN[64];
> int retval = 0;
> uint32_t host;
>
> @@ -492,9 +489,7 @@ virStorageBackendSCSIRefreshPool(virConnectPtr conn,
>
> VIR_DEBUG(_("Scanning host%u"), host);
>
> - snprintf(targetN, sizeof(targetN), "target%u", host);
> -
> - virStorageBackendSCSIFindTargets(conn, pool, "/sys/bus/scsi/devices", targetN);
> + virStorageBackendSCSIFindLUs(conn, pool, host);
>
> out:
> return retval;
> diff --git a/src/storage_backend_scsi.h b/src/storage_backend_scsi.h
> index 678ccd6..d63951d 100644
> --- a/src/storage_backend_scsi.h
> +++ b/src/storage_backend_scsi.h
> @@ -30,25 +30,15 @@
> #define LINUX_SYSFS_SCSI_HOST_PREFIX "/sys/class/scsi_host"
> #define LINUX_SYSFS_SCSI_HOST_POSTFIX "device"
>
> -struct _virDirectoryWalkData {
> - virConnectPtr conn;
> - virStoragePoolObjPtr pool;
> - const char *dir_path;
> - const char *pattern_to_match;
> - size_t expected_matches;
> - virHashTablePtr matches; // will be created by walk function
> - virHashIterator iterator;
> - virHashDeallocator deallocator;
> -};
> -typedef struct _virDirectoryWalkData virDirectoryWalkData;
> -typedef virDirectoryWalkData *virDirectoryWalkDataPtr;
> -
> extern virStorageBackend virStorageBackendSCSI;
>
> int
> -virStorageBackendSCSIFindTargets(virConnectPtr conn,
> - virStoragePoolObjPtr pool,
> - const char *sysfs_path,
> - const char *pattern);
> +virStorageBackendSCSIGetHostNumber(virConnectPtr conn,
> + const char *sysfs_path,
> + uint32_t *host);
> +int
> +virStorageBackendSCSIFindLUs(virConnectPtr conn,
> + virStoragePoolObjPtr pool,
> + uint32_t scanhost);
>
> #endif /* __VIR_STORAGE_BACKEND_SCSI_H__ */
> --
> 1.6.0.6
>
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 :|
More information about the libvir-list
mailing list