/* When large numbers of devices are present on the host, it's * possible for udev not to realize that it has work to do before we * get here. We thus keep trying to find the new device we just * created for up to LINUX_NEW_DEVICE_WAIT_TIME. Note that udev's * default settle time is 180 seconds, so once udev realizes that it * has work to do, it might take that long for the udev wait to * return. Thus the total maximum time for this function to return is * the udev settle time plus LINUX_NEW_DEVICE_WAIT_TIME. * * This whole area is a race, but if we retry the udev wait for * LINUX_NEW_DEVICE_WAIT_TIME seconds and there's still no device, * it's probably safe to assume it's not going to appear. */ static virNodeDevicePtr find_new_device(virConnectPtr conn, const char *wwnn, const char *wwpn) { virNodeDevicePtr dev = NULL; time_t start = 0, now = 0; /* The thread that creates the device takes the driver lock, so we * must release it in order to allow the device to be created. * We're not doing anything with the driver pointer at this point, * so it's safe to release it, assuming that the pointer itself * doesn't become invalid. */ nodeDeviceUnlock(); get_time(&start); while ((now - start) < LINUX_NEW_DEVICE_WAIT_TIME) { virFileWaitForDevices(); dev = nodeDeviceLookupSCSIHostByWWN(conn, wwnn, wwpn, 0); if (dev != NULL) break; sleep(5); if (get_time(&now) == -1) break; } nodeDeviceLock(); return dev; }
static int virStorageBackendMpathRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool) { int retval = 0; VIR_DEBUG("conn=%p, pool=%p", conn, pool); pool->def->allocation = pool->def->capacity = pool->def->available = 0; virFileWaitForDevices(); virStorageBackendGetMaps(pool); return retval; }
static int virStorageBackendISCSIGetHostNumber(const char *sysfs_path, uint32_t *host) { int retval = 0; DIR *sysdir = NULL; struct dirent *dirent = NULL; int direrr; VIR_DEBUG("Finding host number from '%s'", sysfs_path); virFileWaitForDevices(); sysdir = opendir(sysfs_path); if (sysdir == NULL) { virReportSystemError(errno, _("Failed to opendir path '%s'"), sysfs_path); retval = -1; goto out; } while ((direrr = virDirRead(sysdir, &dirent, sysfs_path)) > 0) { if (STREQLEN(dirent->d_name, "target", strlen("target"))) { if (sscanf(dirent->d_name, "target%u:", host) != 1) { VIR_DEBUG("Failed to parse target '%s'", dirent->d_name); retval = -1; break; } } } if (direrr < 0) retval = -1; closedir(sysdir); out: return retval; }