提交 5ba2ce65 编写于 作者: J John Ferlan

nodedev: Alter node device deletion logic

Alter the node device deletion logic to make use of the parent field
from the obj->def rather than call virNodeDeviceObjListGetParentHost.
As it turns out the saved @def won't have parent_wwnn/wwpn or
parent_fabric_wwn, so the only logical path would be to call
virNodeDeviceObjListGetParentHostByParent which we can accomplish
directly via virNodeDeviceObjListFindByName.
上级 4860582f
...@@ -594,8 +594,9 @@ nodeDeviceDestroy(virNodeDevicePtr device) ...@@ -594,8 +594,9 @@ nodeDeviceDestroy(virNodeDevicePtr device)
int ret = -1; int ret = -1;
virNodeDeviceObjPtr obj = NULL; virNodeDeviceObjPtr obj = NULL;
virNodeDeviceDefPtr def; virNodeDeviceDefPtr def;
char *parent = NULL;
char *wwnn = NULL, *wwpn = NULL; char *wwnn = NULL, *wwpn = NULL;
int parent_host = -1; unsigned int parent_host;
if (!(obj = nodeDeviceObjFindByName(device->name))) if (!(obj = nodeDeviceObjFindByName(device->name)))
return -1; return -1;
...@@ -609,13 +610,23 @@ nodeDeviceDestroy(virNodeDevicePtr device) ...@@ -609,13 +610,23 @@ nodeDeviceDestroy(virNodeDevicePtr device)
if (virNodeDeviceGetWWNs(def, &wwnn, &wwpn) < 0) if (virNodeDeviceGetWWNs(def, &wwnn, &wwpn) < 0)
goto cleanup; goto cleanup;
/* virNodeDeviceGetParentHost will cause the device object's lock /* Because we're about to release the lock and thus run into a race
* to be taken, so grab the object def which will have the various * possibility (however improbable) with a udevAddOneDevice change
* fields used to search (name, parent, parent_wwnn, parent_wwpn, * event which would essentially free the existing @def (obj->def) and
* or parent_fabric_wwn) and drop the object lock. */ * replace it with something new, we need to grab the parent field
* and then find the parent obj in order to manage the vport */
if (VIR_STRDUP(parent, def->parent) < 0)
goto cleanup;
virNodeDeviceObjEndAPI(&obj); virNodeDeviceObjEndAPI(&obj);
if ((parent_host = virNodeDeviceObjListGetParentHost(driver->devs, def,
EXISTING_DEVICE)) < 0) if (!(obj = virNodeDeviceObjListFindByName(driver->devs, parent))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot find parent '%s' definition"), parent);
goto cleanup;
}
if (virSCSIHostGetNumber(parent, &parent_host) < 0)
goto cleanup; goto cleanup;
if (virVHBAManageVport(parent_host, wwpn, wwnn, VPORT_DELETE) < 0) if (virVHBAManageVport(parent_host, wwpn, wwnn, VPORT_DELETE) < 0)
...@@ -626,6 +637,7 @@ nodeDeviceDestroy(virNodeDevicePtr device) ...@@ -626,6 +637,7 @@ nodeDeviceDestroy(virNodeDevicePtr device)
cleanup: cleanup:
nodeDeviceUnlock(); nodeDeviceUnlock();
virNodeDeviceObjEndAPI(&obj); virNodeDeviceObjEndAPI(&obj);
VIR_FREE(parent);
VIR_FREE(wwnn); VIR_FREE(wwnn);
VIR_FREE(wwpn); VIR_FREE(wwpn);
return ret; return ret;
......
...@@ -5515,8 +5515,9 @@ testNodeDeviceDestroy(virNodeDevicePtr dev) ...@@ -5515,8 +5515,9 @@ testNodeDeviceDestroy(virNodeDevicePtr dev)
int ret = 0; int ret = 0;
testDriverPtr driver = dev->conn->privateData; testDriverPtr driver = dev->conn->privateData;
virNodeDeviceObjPtr obj = NULL; virNodeDeviceObjPtr obj = NULL;
virNodeDeviceObjPtr parentobj = NULL;
virNodeDeviceDefPtr def; virNodeDeviceDefPtr def;
char *parent_name = NULL, *wwnn = NULL, *wwpn = NULL; char *wwnn = NULL, *wwpn = NULL;
virObjectEventPtr event = NULL; virObjectEventPtr event = NULL;
if (!(obj = testNodeDeviceObjFindByName(driver, dev->name))) if (!(obj = testNodeDeviceObjFindByName(driver, dev->name)))
...@@ -5526,22 +5527,22 @@ testNodeDeviceDestroy(virNodeDevicePtr dev) ...@@ -5526,22 +5527,22 @@ testNodeDeviceDestroy(virNodeDevicePtr dev)
if (virNodeDeviceGetWWNs(def, &wwnn, &wwpn) == -1) if (virNodeDeviceGetWWNs(def, &wwnn, &wwpn) == -1)
goto cleanup; goto cleanup;
if (VIR_STRDUP(parent_name, def->parent) < 0) /* Unlike the real code we cannot run into the udevAddOneDevice race
goto cleanup; * which would replace obj->def, so no need to save off the parent,
* but do need to drop the @obj lock so that the FindByName code doesn't
/* virNodeDeviceGetParentHost will cause the device object's lock to be * deadlock on ourselves */
* taken, so we have to dup the parent's name and drop the lock
* before calling it. We don't need the reference to the object
* any more once we have the parent's name. */
virObjectUnlock(obj); virObjectUnlock(obj);
/* We do this just for basic validation, but also avoid finding a /* We do this just for basic validation and throw away the parentobj
* vport capable HBA if for some reason our vHBA doesn't exist */ * since there's no vport_delete to be run */
if (virNodeDeviceObjListGetParentHost(driver->devs, def, if (!(parentobj = virNodeDeviceObjListFindByName(driver->devs,
EXISTING_DEVICE) < 0) { def->parent))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot find parent '%s' definition"), def->parent);
virObjectLock(obj); virObjectLock(obj);
goto cleanup; goto cleanup;
} }
virNodeDeviceObjEndAPI(&parentobj);
event = virNodeDeviceEventLifecycleNew(dev->name, event = virNodeDeviceEventLifecycleNew(dev->name,
VIR_NODE_DEVICE_EVENT_DELETED, VIR_NODE_DEVICE_EVENT_DELETED,
...@@ -5555,7 +5556,6 @@ testNodeDeviceDestroy(virNodeDevicePtr dev) ...@@ -5555,7 +5556,6 @@ testNodeDeviceDestroy(virNodeDevicePtr dev)
cleanup: cleanup:
virNodeDeviceObjEndAPI(&obj); virNodeDeviceObjEndAPI(&obj);
testObjectEventQueue(driver, event); testObjectEventQueue(driver, event);
VIR_FREE(parent_name);
VIR_FREE(wwnn); VIR_FREE(wwnn);
VIR_FREE(wwpn); VIR_FREE(wwpn);
return ret; return ret;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册