static virNodeDeviceDefPtr virNodeDeviceDefParseXML(xmlXPathContextPtr ctxt, int create) { virNodeDeviceDefPtr def; virNodeDevCapsDefPtr *next_cap; xmlNodePtr *nodes; int n, i; if (VIR_ALLOC(def) < 0) { virReportOOMError(); return NULL; } /* Extract device name */ if (create == EXISTING_DEVICE) { def->name = virXPathString("string(./name[1])", ctxt); if (!def->name) { virNodeDeviceReportError(VIR_ERR_NO_NAME, NULL); goto error; } } else { def->name = strdup("new device"); if (!def->name) { virReportOOMError(); goto error; } } /* Extract device parent, if any */ def->parent = virXPathString("string(./parent[1])", ctxt); /* Parse device capabilities */ nodes = NULL; if ((n = virXPathNodeSet("./capability", ctxt, &nodes)) <= 0) { virNodeDeviceReportError(VIR_ERR_INTERNAL_ERROR, _("no device capabilities for '%s'"), def->name); goto error; } next_cap = &def->caps; for (i = 0 ; i < n ; i++) { *next_cap = virNodeDevCapsDefParseXML(ctxt, def, nodes[i], create); if (!*next_cap) { VIR_FREE(nodes); goto error; } next_cap = &(*next_cap)->next; } VIR_FREE(nodes); return def; error: virNodeDeviceDefFree(def); return NULL; }
static int testCompareXMLToXMLFiles(const char *xml) { char *xmlData = NULL; char *actual = NULL; int ret = -1; virNodeDeviceDefPtr dev = NULL; if (virtTestLoadFile(xml, &xmlData) < 0) goto fail; if (!(dev = virNodeDeviceDefParseString(xmlData, EXISTING_DEVICE, NULL))) goto fail; if (!(actual = virNodeDeviceDefFormat(dev))) goto fail; if (STRNEQ(xmlData, actual)) { virtTestDifferenceFull(stderr, xmlData, xml, actual, NULL); goto fail; } ret = 0; fail: VIR_FREE(xmlData); VIR_FREE(actual); virNodeDeviceDefFree(dev); return ret; }
static void virNodeDeviceObjDispose(void *opaque) { virNodeDeviceObjPtr obj = opaque; virNodeDeviceDefFree(obj->def); }
virNodeDevicePtr nodeDeviceCreateXML(virConnectPtr conn, const char *xmlDesc, unsigned int flags) { virNodeDeviceDriverStatePtr driver = conn->nodeDevicePrivateData; virNodeDeviceDefPtr def = NULL; char *wwnn = NULL, *wwpn = NULL; int parent_host = -1; virNodeDevicePtr dev = NULL; const char *virt_type = NULL; virCheckFlags(0, NULL); virt_type = virConnectGetType(conn); nodeDeviceLock(driver); def = virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE, virt_type); if (def == NULL) { goto cleanup; } if (virNodeDeviceCreateXMLEnsureACL(conn, def) < 0) goto cleanup; if (virNodeDeviceGetWWNs(def, &wwnn, &wwpn) == -1) { goto cleanup; } if (virNodeDeviceGetParentHost(&driver->devs, def->name, def->parent, &parent_host) == -1) { goto cleanup; } if (virManageVport(parent_host, wwpn, wwnn, VPORT_CREATE) == -1) { goto cleanup; } dev = find_new_device(conn, wwnn, wwpn); /* We don't check the return value, because one way or another, * we're returning what we get... */ if (dev == NULL) { virReportError(VIR_ERR_NO_NODE_DEVICE, NULL); } cleanup: nodeDeviceUnlock(driver); virNodeDeviceDefFree(def); VIR_FREE(wwnn); VIR_FREE(wwpn); return dev; }
static int testCompareXMLToXMLFiles(const char *xml) { char *xmlData = NULL; char *actual = NULL; int ret = -1; virNodeDeviceDefPtr dev = NULL; virNodeDevCapsDefPtr caps; if (virTestLoadFile(xml, &xmlData) < 0) goto fail; if (!(dev = virNodeDeviceDefParseString(xmlData, EXISTING_DEVICE, NULL))) goto fail; /* Calculate some things that are not read in */ for (caps = dev->caps; caps; caps = caps->next) { virNodeDevCapDataPtr data = &caps->data; if (caps->data.type == VIR_NODE_DEV_CAP_STORAGE) { if (data->storage.flags & VIR_NODE_DEV_CAP_STORAGE_REMOVABLE) { if (data->storage.flags & VIR_NODE_DEV_CAP_STORAGE_REMOVABLE_MEDIA_AVAILABLE) { data->storage.logical_block_size = 2048; data->storage.num_blocks = data->storage.removable_media_size / data->storage.logical_block_size; } } else { data->storage.logical_block_size = 512; data->storage.num_blocks = data->storage.size / data->storage.logical_block_size; } } } if (!(actual = virNodeDeviceDefFormat(dev))) goto fail; if (STRNEQ(xmlData, actual)) { virTestDifferenceFull(stderr, xmlData, xml, actual, NULL); goto fail; } ret = 0; fail: VIR_FREE(xmlData); VIR_FREE(actual); virNodeDeviceDefFree(dev); return ret; }
void virNodeDeviceObjFree(virNodeDeviceObjPtr dev) { if (!dev) return; virNodeDeviceDefFree(dev->def); if (dev->privateFree) (*dev->privateFree)(dev->privateData); virMutexDestroy(&dev->lock); VIR_FREE(dev); }
static virNodeDevicePtr nodeDeviceCreateXML(virConnectPtr conn, const char *xmlDesc, unsigned int flags ATTRIBUTE_UNUSED) { virDeviceMonitorStatePtr driver = conn->devMonPrivateData; virNodeDeviceDefPtr def = NULL; char *wwnn = NULL, *wwpn = NULL; int parent_host = -1; virNodeDevicePtr dev = NULL; nodeDeviceLock(driver); def = virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE); if (def == NULL) { goto cleanup; } if (virNodeDeviceGetWWNs(def, &wwnn, &wwpn) == -1) { goto cleanup; } if (virNodeDeviceGetParentHost(&driver->devs, def->name, def->parent, &parent_host) == -1) { goto cleanup; } if (nodeDeviceVportCreateDelete(parent_host, wwpn, wwnn, VPORT_CREATE) == -1) { goto cleanup; } dev = find_new_device(conn, wwnn, wwpn); /* We don't check the return value, because one way or another, * we're returning what we get... */ if (dev == NULL) { virNodeDeviceReportError(VIR_ERR_NO_NODE_DEVICE, NULL); } cleanup: nodeDeviceUnlock(driver); virNodeDeviceDefFree(def); VIR_FREE(wwnn); VIR_FREE(wwpn); return dev; }
virNodeDevicePtr nodeDeviceCreateXML(virConnectPtr conn, const char *xmlDesc, unsigned int flags) { virNodeDeviceDefPtr def = NULL; char *wwnn = NULL, *wwpn = NULL; int parent_host = -1; virNodeDevicePtr dev = NULL; const char *virt_type = NULL; virCheckFlags(0, NULL); virt_type = virConnectGetType(conn); nodeDeviceLock(); if (!(def = virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE, virt_type))) goto cleanup; if (virNodeDeviceCreateXMLEnsureACL(conn, def) < 0) goto cleanup; if (virNodeDeviceGetWWNs(def, &wwnn, &wwpn) == -1) goto cleanup; if ((parent_host = virNodeDeviceObjGetParentHost(&driver->devs, def, CREATE_DEVICE)) < 0) goto cleanup; if (virVHBAManageVport(parent_host, wwpn, wwnn, VPORT_CREATE) < 0) goto cleanup; dev = nodeDeviceFindNewDevice(conn, wwnn, wwpn); /* We don't check the return value, because one way or another, * we're returning what we get... */ if (dev == NULL) virReportError(VIR_ERR_NO_NODE_DEVICE, _("no node device for '%s' with matching " "wwnn '%s' and wwpn '%s'"), def->name, wwnn, wwpn); cleanup: nodeDeviceUnlock(); virNodeDeviceDefFree(def); VIR_FREE(wwnn); VIR_FREE(wwpn); return dev; }
virNodeDeviceObjPtr virNodeDeviceAssignDef(virNodeDeviceObjListPtr devs, const virNodeDeviceDefPtr def) { virNodeDeviceObjPtr device; if ((device = virNodeDeviceFindByName(devs, def->name))) { virNodeDeviceDefFree(device->def); device->def = def; return device; } if (VIR_ALLOC(device) < 0) { virReportOOMError(); return NULL; } if (virMutexInit(&device->lock) < 0) { virNodeDeviceReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot initialize mutex")); VIR_FREE(device); return NULL; } virNodeDeviceObjLock(device); device->def = def; if (VIR_REALLOC_N(devs->objs, devs->count+1) < 0) { device->def = NULL; virNodeDeviceObjUnlock(device); virNodeDeviceObjFree(device); virReportOOMError(); return NULL; } devs->objs[devs->count++] = device; return device; }
static void dev_create(const char *udi) { LibHalContext *ctx; char *parent_key = NULL; virNodeDeviceObjPtr dev = NULL; virNodeDeviceDefPtr def = NULL; const char *name = hal_name(udi); int rv; char *privData; char *devicePath = NULL; if (VIR_STRDUP(privData, udi) < 0) return; nodeDeviceLock(driverState); ctx = DRV_STATE_HAL_CTX(driverState); if (VIR_ALLOC(def) < 0) goto failure; if (VIR_STRDUP(def->name, name) < 0) goto failure; if (get_str_prop(ctx, udi, "info.parent", &parent_key) == 0) { if (VIR_STRDUP(def->parent, hal_name(parent_key)) < 0) { VIR_FREE(parent_key); goto failure; } VIR_FREE(parent_key); } rv = gather_capabilities(ctx, udi, &def->caps); if (rv != 0) goto failure; if (def->caps == NULL) goto cleanup; /* Some devices don't have a path in sysfs, so ignore failure */ (void)get_str_prop(ctx, udi, "linux.sysfs_path", &devicePath); dev = virNodeDeviceAssignDef(&driverState->devs, def); if (!dev) { VIR_FREE(devicePath); goto failure; } dev->privateData = privData; dev->privateFree = free_udi; dev->def->sysfs_path = devicePath; virNodeDeviceObjUnlock(dev); nodeDeviceUnlock(driverState); return; failure: VIR_DEBUG("FAILED TO ADD dev %s", name); cleanup: VIR_FREE(privData); virNodeDeviceDefFree(def); nodeDeviceUnlock(driverState); }