int virDomainCCWAddressAssign(virDomainDeviceInfoPtr dev, virDomainCCWAddressSetPtr addrs, bool autoassign) { int ret = -1; char *addr = NULL; if (dev->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) return 0; if (!autoassign && dev->addr.ccw.assigned) { if (!(addr = virDomainCCWAddressAsString(&dev->addr.ccw))) goto cleanup; if (virHashLookup(addrs->defined, addr)) { virReportError(VIR_ERR_XML_ERROR, _("The CCW devno '%s' is in use already "), addr); goto cleanup; } } else if (autoassign && !dev->addr.ccw.assigned) { if (!(addr = virDomainCCWAddressAsString(&addrs->next))) goto cleanup; while (virHashLookup(addrs->defined, addr)) { if (virDomainCCWAddressIncrement(&addrs->next) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("There are no more free CCW devnos.")); goto cleanup; } VIR_FREE(addr); if (!(addr = virDomainCCWAddressAsString(&addrs->next))) goto cleanup; } dev->addr.ccw = addrs->next; dev->addr.ccw.assigned = true; } else { return 0; } if (virHashAddEntry(addrs->defined, addr, addr) < 0) goto cleanup; else addr = NULL; /* memory will be freed by hash table */ ret = 0; cleanup: VIR_FREE(addr); return ret; }
int virNWFilterTerminateLearnReq(const char *ifname) { int rc = -1; int ifindex; virNWFilterIPAddrLearnReqPtr req; /* It's possible that it's already been removed as a result of * virNWFilterDeregisterLearnReq during learnIPAddressThread() exit */ if (virNetDevExists(ifname) != 1) { virResetLastError(); return 0; } if (virNetDevGetIndex(ifname, &ifindex) < 0) { virResetLastError(); return rc; } IFINDEX2STR(ifindex_str, ifindex); virMutexLock(&pendingLearnReqLock); req = virHashLookup(pendingLearnReq, ifindex_str); if (req) { rc = 0; req->terminate = true; } virMutexUnlock(&pendingLearnReqLock); return rc; }
/* Add an IP address to the list of IP addresses an interface is * known to use. This function feeds the per-interface cache that * is used to instantiate filters with variable '$IP'. * * @ifname: The name of the (tap) interface * @addr: An IPv4 address in dotted decimal format that the (tap) * interface is known to use. * * This function returns 0 on success, -1 otherwise */ int virNWFilterIPAddrMapAddIPAddr(const char *ifname, char *addr) { int ret = -1; virNWFilterVarValuePtr val; virMutexLock(&ipAddressMapLock); val = virHashLookup(ipAddressMap->hashTable, ifname); if (!val) { val = virNWFilterVarValueCreateSimple(addr); if (!val) { virReportOOMError(); goto cleanup; } ret = virNWFilterHashTablePut(ipAddressMap, ifname, val, 1); goto cleanup; } else { if (virNWFilterVarValueAddValue(val, addr) < 0) goto cleanup; } ret = 0; cleanup: virMutexUnlock(&ipAddressMapLock); return ret; }
/* Delete all or a specific IP address from an interface. After this * call either all or the given IP address will not be associated * with the interface anymore. * * @ifname: The name of the (tap) interface * @addr: An IPv4 address in dotted decimal format that the (tap) * interface is not using anymore; provide NULL to remove all IP * addresses associated with the given interface * * This function returns the number of IP addresses that are still * known to be associated with this interface, in case of an error * -1 is returned. Error conditions are: * - IP addresses is not known to be associated with the interface */ int virNWFilterIPAddrMapDelIPAddr(const char *ifname, const char *ipaddr) { int ret = -1; virNWFilterVarValuePtr val = NULL; virMutexLock(&ipAddressMapLock); if (ipaddr != NULL) { val = virHashLookup(ipAddressMap->hashTable, ifname); if (val) { if (virNWFilterVarValueGetCardinality(val) == 1 && STREQ(ipaddr, virNWFilterVarValueGetNthValue(val, 0))) goto remove_entry; virNWFilterVarValueDelValue(val, ipaddr); ret = virNWFilterVarValueGetCardinality(val); } } else { remove_entry: /* remove whole entry */ val = virNWFilterHashTableRemoveEntry(ipAddressMap, ifname); virNWFilterVarValueFree(val); ret = 0; } virMutexUnlock(&ipAddressMapLock); return ret; }
static int qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig, virQEMUDriverPtr driver, virDomainObjPtr vm) { qemuDomainObjPrivatePtr priv = vm->privateData; virHashTablePtr stats = NULL; size_t i; int ret = -1, rc; /* It is not a bug if there already is a NBD data */ qemuMigrationCookieNBDFree(mig->nbd); if (VIR_ALLOC(mig->nbd) < 0) return -1; if (vm->def->ndisks && VIR_ALLOC_N(mig->nbd->disks, vm->def->ndisks) < 0) return -1; mig->nbd->ndisks = 0; for (i = 0; i < vm->def->ndisks; i++) { virDomainDiskDefPtr disk = vm->def->disks[i]; qemuBlockStats *entry; if (!stats) { if (!(stats = virHashCreate(10, virHashValueFree))) goto cleanup; if (qemuDomainObjEnterMonitorAsync(driver, vm, priv->job.asyncJob) < 0) goto cleanup; rc = qemuMonitorBlockStatsUpdateCapacity(priv->mon, stats, false); if (qemuDomainObjExitMonitor(driver, vm) < 0) goto cleanup; if (rc < 0) goto cleanup; } if (!disk->info.alias || !(entry = virHashLookup(stats, disk->info.alias))) continue; if (VIR_STRDUP(mig->nbd->disks[mig->nbd->ndisks].target, disk->dst) < 0) goto cleanup; mig->nbd->disks[mig->nbd->ndisks].capacity = entry->capacity; mig->nbd->ndisks++; } mig->nbd->port = priv->nbdPort; mig->flags |= QEMU_MIGRATION_COOKIE_NBD; ret = 0; cleanup: virHashFree(stats); return ret; }
static virConnectPtr virLXCProcessAutoDestroyGetConn(virLXCDriverPtr driver, virDomainObjPtr vm) { char uuidstr[VIR_UUID_STRING_BUFLEN]; virUUIDFormat(vm->def->uuid, uuidstr); VIR_DEBUG("vm=%s uuid=%s", vm->def->name, uuidstr); return virHashLookup(driver->autodestroy, uuidstr); }
/* * Test whether the iterator entry points to a distinguished set of entries * that have not been seen before at one of the previous iterations. * * The point of this function is to eliminate duplicates. * Example with two lists: * * list1 = [1,2,1] * list2 = [1,3,1] * * The 1st iteration would take the 1st items of each list -> 1,1 * The 2nd iteration would take the 2nd items of each list -> 2,3 * The 3rd iteration would take the 3rd items of each list -> 1,1 but * skip them since this pair has already been encountered in the 1st iteration */ static bool virNWFilterVarCombIterEntryAreUniqueEntries(virNWFilterVarCombIterEntryPtr cie, virNWFilterHashTablePtr hash) { size_t i, j; virNWFilterVarValuePtr varValue, tmp; const char *value; varValue = virHashLookup(hash->hashTable, cie->varNames[0]); if (!varValue) { /* caller's error */ VIR_ERROR(_("hash lookup resulted in NULL pointer")); return true; } value = virNWFilterVarValueGetNthValue(varValue, cie->curValue); if (!value) { VIR_ERROR(_("Lookup of value at index %u resulted in a NULL " "pointer"), cie->curValue); return true; } for (i = 0; i < cie->curValue; i++) { if (STREQ(value, virNWFilterVarValueGetNthValue(varValue, i))) { bool isSame = true; for (j = 1; j < cie->nVarNames; j++) { tmp = virHashLookup(hash->hashTable, cie->varNames[j]); if (!tmp) { /* should never occur to step on a NULL here */ return true; } if (!STREQ(virNWFilterVarValueGetNthValue(tmp, cie->curValue), virNWFilterVarValueGetNthValue(tmp, i))) { isSame = false; break; } } if (isSame) return false; } } return true; }
static virCPUCompareResult genericCompare(virCPUDefPtr host, virCPUDefPtr cpu, bool failIncompatible) { virHashTablePtr hash = NULL; virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR; size_t i; unsigned int reqfeatures; if ((cpu->arch != VIR_ARCH_NONE && host->arch != cpu->arch) || STRNEQ(host->model, cpu->model)) { ret = VIR_CPU_COMPARE_INCOMPATIBLE; goto cleanup; } if ((hash = genericHashFeatures(host)) == NULL) goto cleanup; reqfeatures = 0; for (i = 0; i < cpu->nfeatures; i++) { void *hval = virHashLookup(hash, cpu->features[i].name); if (hval) { if (cpu->type == VIR_CPU_TYPE_GUEST && cpu->features[i].policy == VIR_CPU_FEATURE_FORBID) { ret = VIR_CPU_COMPARE_INCOMPATIBLE; goto cleanup; } reqfeatures++; } else if (cpu->type == VIR_CPU_TYPE_HOST || cpu->features[i].policy == VIR_CPU_FEATURE_REQUIRE) { ret = VIR_CPU_COMPARE_INCOMPATIBLE; goto cleanup; } } if (host->nfeatures > reqfeatures) { if (cpu->type == VIR_CPU_TYPE_GUEST && cpu->match == VIR_CPU_MATCH_STRICT) ret = VIR_CPU_COMPARE_INCOMPATIBLE; else ret = VIR_CPU_COMPARE_SUPERSET; } else { ret = VIR_CPU_COMPARE_IDENTICAL; } cleanup: virHashFree(hash); if (failIncompatible && ret == VIR_CPU_COMPARE_INCOMPATIBLE) { ret = VIR_CPU_COMPARE_ERROR; virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL); } return ret; }
/** * virSecretObjFindByUUIDLocked: * @secrets: list of secret objects * @uuid: secret uuid to find * * This functions requires @secrets to be locked already! * * Returns: not locked, but ref'd secret object. */ virSecretObjPtr virSecretObjListFindByUUIDLocked(virSecretObjListPtr secrets, const unsigned char *uuid) { char uuidstr[VIR_UUID_STRING_BUFLEN]; virUUIDFormat(uuid, uuidstr); return virObjectRef(virHashLookup(secrets->objs, uuidstr)); }
/** * virHashSteal: * @table: the hash table * @name: the name of the userdata * * Find the userdata specified by @name * and remove it from the hash without freeing it. * * Returns the a pointer to the userdata */ void *virHashSteal(virHashTablePtr table, const void *name) { void *data = virHashLookup(table, name); if (data) { virHashDataFree dataFree = table->dataFree; table->dataFree = NULL; virHashRemoveEntry(table, name); table->dataFree = dataFree; } return data; }
static virCPUCompareResult genericCompare(virCPUDefPtr host, virCPUDefPtr cpu) { virHashTablePtr hash; virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR; unsigned int i; unsigned int reqfeatures; if ((cpu->arch && STRNEQ(host->arch, cpu->arch)) || STRNEQ(host->model, cpu->model)) return VIR_CPU_COMPARE_INCOMPATIBLE; if ((hash = genericHashFeatures(host)) == NULL) { virReportOOMError(); goto cleanup; } reqfeatures = 0; for (i = 0; i < cpu->nfeatures; i++) { void *hval = virHashLookup(hash, cpu->features[i].name); if (hval) { if (cpu->type == VIR_CPU_TYPE_GUEST && cpu->features[i].policy == VIR_CPU_FEATURE_FORBID) { ret = VIR_CPU_COMPARE_INCOMPATIBLE; goto cleanup; } reqfeatures++; } else { if (cpu->type == VIR_CPU_TYPE_HOST || cpu->features[i].policy == VIR_CPU_FEATURE_REQUIRE) { ret = VIR_CPU_COMPARE_INCOMPATIBLE; goto cleanup; } } } if (host->nfeatures > reqfeatures) { if (cpu->type == VIR_CPU_TYPE_GUEST && cpu->match == VIR_CPU_MATCH_STRICT) ret = VIR_CPU_COMPARE_INCOMPATIBLE; else ret = VIR_CPU_COMPARE_SUPERSET; } else ret = VIR_CPU_COMPARE_IDENTICAL; cleanup: virHashFree(hash); return ret; }
int virCloseCallbacksSet(virCloseCallbacksPtr closeCallbacks, virDomainObjPtr vm, virConnectPtr conn, virCloseCallback cb) { char uuidstr[VIR_UUID_STRING_BUFLEN]; virDriverCloseDefPtr closeDef; int ret = -1; virUUIDFormat(vm->def->uuid, uuidstr); VIR_DEBUG("vm=%s, uuid=%s, conn=%p, cb=%p", vm->def->name, uuidstr, conn, cb); virObjectLock(closeCallbacks); closeDef = virHashLookup(closeCallbacks->list, uuidstr); if (closeDef) { if (closeDef->conn != conn) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Close callback for domain %s already registered" " with another connection %p"), vm->def->name, closeDef->conn); goto cleanup; } if (closeDef->cb && closeDef->cb != cb) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Another close callback is already defined for" " domain %s"), vm->def->name); goto cleanup; } closeDef->cb = cb; } else { if (VIR_ALLOC(closeDef) < 0) goto cleanup; closeDef->conn = conn; closeDef->cb = cb; if (virHashAddEntry(closeCallbacks->list, uuidstr, closeDef) < 0) { VIR_FREE(closeDef); goto cleanup; } virObjectRef(vm); } virObjectRef(closeCallbacks); ret = 0; cleanup: virObjectUnlock(closeCallbacks); return ret; }
/* Get the list of IP addresses known to be in use by an interface * * This function returns NULL in case no IP address is known to be * associated with the interface, a virNWFilterVarValuePtr otherwise * that then can contain one or multiple entries. */ virNWFilterVarValuePtr virNWFilterIPAddrMapGetIPAddr(const char *ifname) { virNWFilterVarValuePtr res; virMutexLock(&ipAddressMapLock); res = virHashLookup(ipAddressMap->hashTable, ifname); virMutexUnlock(&ipAddressMapLock); return res; }
static int virNWFilterVarCombIterAddVariable(virNWFilterVarCombIterEntryPtr cie, virNWFilterHashTablePtr hash, const virNWFilterVarAccess *varAccess) { virNWFilterVarValuePtr varValue; unsigned int maxValue = 0, minValue = 0; const char *varName = virNWFilterVarAccessGetVarName(varAccess); varValue = virHashLookup(hash->hashTable, varName); if (varValue == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not find value for variable '%s'"), varName); return -1; } switch (virNWFilterVarAccessGetType(varAccess)) { case VIR_NWFILTER_VAR_ACCESS_ELEMENT: maxValue = virNWFilterVarAccessGetIndex(varAccess); minValue = maxValue; break; case VIR_NWFILTER_VAR_ACCESS_ITERATOR: maxValue = virNWFilterVarValueGetCardinality(varValue) - 1; minValue = 0; break; case VIR_NWFILTER_VAR_ACCESS_LAST: return -1; } if (cie->nVarNames == 0) { cie->maxValue = maxValue; cie->minValue = minValue; cie->curValue = minValue; } else { if (cie->maxValue != maxValue) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Cardinality of list items must be " "the same for processing them in " "parallel")); return -1; } } if (VIR_EXPAND_N(cie->varNames, cie->nVarNames, 1) < 0) return -1; cie->varNames[cie->nVarNames - 1] = varName; return 0; }
int virNWFilterLockIface(const char *ifname) { virNWFilterIfaceLockPtr ifaceLock; virMutexLock(&ifaceMapLock); ifaceLock = virHashLookup(ifaceLockMap, ifname); if (!ifaceLock) { if (VIR_ALLOC(ifaceLock) < 0) { virReportOOMError(); goto err_exit; } if (virMutexInitRecursive(&ifaceLock->lock) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("mutex initialization failed")); VIR_FREE(ifaceLock); goto err_exit; } if (virStrcpyStatic(ifaceLock->ifname, ifname) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("interface name %s does not fit into " "buffer "), ifaceLock->ifname); VIR_FREE(ifaceLock); goto err_exit; } while (virHashAddEntry(ifaceLockMap, ifname, ifaceLock)) { VIR_FREE(ifaceLock); goto err_exit; } ifaceLock->refctr = 0; } ifaceLock->refctr++; virMutexUnlock(&ifaceMapLock); virMutexLock(&ifaceLock->lock); return 0; err_exit: virMutexUnlock(&ifaceMapLock); return -1; }
/* * Make necessary checks for the need to check and for the current setting * of the 'unpriv_sgio' value for the device_path passed. * * Returns: * 0 - Success * -1 - Some failure which would already have been messaged * -2 - Mismatch with the "shared" sgio setting - needs to be messaged * by caller since it has context of which type of disk resource is * being used and in the future the hostdev information. */ static int qemuCheckUnprivSGIO(virHashTablePtr sharedDevices, const char *device_path, int sgio) { char *sysfs_path = NULL; char *key = NULL; int val; int ret = -1; if (!(sysfs_path = virGetUnprivSGIOSysfsPath(device_path, NULL))) goto cleanup; /* It can't be conflict if unpriv_sgio is not supported by kernel. */ if (!virFileExists(sysfs_path)) { ret = 0; goto cleanup; } if (!(key = qemuGetSharedDeviceKey(device_path))) goto cleanup; /* It can't be conflict if no other domain is sharing it. */ if (!(virHashLookup(sharedDevices, key))) { ret = 0; goto cleanup; } if (virGetDeviceUnprivSGIO(device_path, NULL, &val) < 0) goto cleanup; /* Error message on failure needs to be handled in caller * since there is more specific knowledge of device */ if (!((val == 0 && (sgio == VIR_DOMAIN_DEVICE_SGIO_FILTERED || sgio == VIR_DOMAIN_DEVICE_SGIO_DEFAULT)) || (val == 1 && sgio == VIR_DOMAIN_DEVICE_SGIO_UNFILTERED))) { ret = -2; goto cleanup; } ret = 0; cleanup: VIR_FREE(sysfs_path); VIR_FREE(key); return ret; }
virNWFilterIPAddrLearnReqPtr virNWFilterLookupLearnReq(int ifindex) { void *res; IFINDEX2STR(ifindex_str, ifindex); virMutexLock(&pendingLearnReqLock); res = virHashLookup(pendingLearnReq, ifindex_str); virMutexUnlock(&pendingLearnReqLock); return res; }
static int virNWFilterRegisterLearnReq(virNWFilterIPAddrLearnReqPtr req) { int res = -1; IFINDEX2STR(ifindex_str, req->ifindex); virMutexLock(&pendingLearnReqLock); if (!virHashLookup(pendingLearnReq, ifindex_str)) res = virHashAddEntry(pendingLearnReq, ifindex_str, req); virMutexUnlock(&pendingLearnReqLock); return res; }
void virNWFilterUnlockIface(const char *ifname) { virNWFilterIfaceLockPtr ifaceLock; virMutexLock(&ifaceMapLock); ifaceLock = virHashLookup(ifaceLockMap, ifname); if (ifaceLock) { virMutexUnlock(&ifaceLock->lock); ifaceLock->refctr--; if (ifaceLock->refctr == 0) virHashRemoveEntry(ifaceLockMap, ifname); } virMutexUnlock(&ifaceMapLock); }
static virHashTablePtr testHashInit(int size) { virHashTablePtr hash; ssize_t i; if (!(hash = virHashCreate(size, NULL))) return NULL; /* entires are added in reverse order so that they will be linked in * collision list in the same order as in the uuids array */ for (i = ARRAY_CARDINALITY(uuids) - 1; i >= 0; i--) { ssize_t oldsize = virHashTableSize(hash); if (virHashAddEntry(hash, uuids[i], (void *) uuids[i]) < 0) { virHashFree(hash); return NULL; } if (virHashTableSize(hash) != oldsize && virTestGetDebug()) { VIR_WARN("hash grown from %zd to %zd", (size_t)oldsize, (size_t)virHashTableSize(hash)); } } for (i = 0; i < ARRAY_CARDINALITY(uuids); i++) { if (!virHashLookup(hash, uuids[i])) { if (virTestGetVerbose()) { VIR_WARN("\nentry \"%s\" could not be found\n", uuids[i]); } virHashFree(hash); return NULL; } } if (size && size != virHashTableSize(hash) && virTestGetDebug()) fprintf(stderr, "\n"); return hash; }
static int xenInotifyXenCacheLookup(virConnectPtr conn, const char *filename, char **name, unsigned char *uuid) { xenUnifiedPrivatePtr priv = conn->privateData; xenXMConfCachePtr entry; if (!(entry = virHashLookup(priv->configCache, filename))) { VIR_DEBUG("No config found for %s", filename); return -1; } memcpy(uuid, entry->def->uuid, VIR_UUID_BUFLEN); if (VIR_STRDUP(*name, entry->def->name) < 0) { VIR_DEBUG("Error getting dom from def"); return -1; } return 0; }
virConnectPtr virCloseCallbacksGetConn(virCloseCallbacksPtr closeCallbacks, virDomainObjPtr vm) { char uuidstr[VIR_UUID_STRING_BUFLEN]; virDriverCloseDefPtr closeDef; virConnectPtr conn = NULL; virUUIDFormat(vm->def->uuid, uuidstr); VIR_DEBUG("vm=%s, uuid=%s", vm->def->name, uuidstr); virObjectLock(closeCallbacks); closeDef = virHashLookup(closeCallbacks->list, uuidstr); if (closeDef) conn = closeDef->conn; virObjectUnlock(closeCallbacks); VIR_DEBUG("conn=%p", conn); return conn; }
virDomainSnapshotObjPtr virDomainSnapshotAssignDef(virDomainSnapshotObjListPtr snapshots, const virDomainSnapshotDefPtr def) { virDomainSnapshotObjPtr snap; if (virHashLookup(snapshots->objs, def->name) != NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("unexpected domain snapshot %s already exists"), def->name); return NULL; } if (!(snap = virDomainSnapshotObjNew())) return NULL; snap->def = def; if (virHashAddEntry(snapshots->objs, snap->def->name, snap) < 0) { VIR_FREE(snap); return NULL; } return snap; }
static int testSetOneParameter(virNWFilterHashTablePtr vars, const char *name, const char *value) { int ret = -1; virNWFilterVarValuePtr val; if ((val = virHashLookup(vars->hashTable, name)) == NULL) { val = virNWFilterVarValueCreateSimpleCopyValue(value); if (!val) goto cleanup; if (virNWFilterHashTablePut(vars, name, val) < 0) { virNWFilterVarValueFree(val); goto cleanup; } } else { if (virNWFilterVarValueAddValueCopy(val, value) < 0) goto cleanup; } ret = 0; cleanup: return ret; }
int virCloseCallbacksUnset(virCloseCallbacksPtr closeCallbacks, virDomainObjPtr vm, virCloseCallback cb) { char uuidstr[VIR_UUID_STRING_BUFLEN]; virDriverCloseDefPtr closeDef; int ret = -1; virUUIDFormat(vm->def->uuid, uuidstr); VIR_DEBUG("vm=%s, uuid=%s, cb=%p", vm->def->name, uuidstr, cb); virObjectLock(closeCallbacks); closeDef = virHashLookup(closeCallbacks->list, uuidstr); if (!closeDef) goto cleanup; if (closeDef->cb && closeDef->cb != cb) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Trying to remove mismatching close callback for" " domain %s"), vm->def->name); goto cleanup; } if (virHashRemoveEntry(closeCallbacks->list, uuidstr) < 0) goto cleanup; virObjectUnref(vm); ret = 0; cleanup: virObjectUnlock(closeCallbacks); if (!ret) virObjectUnref(closeCallbacks); return ret; }
static int testQEMUSchemaValidateObjectMember(const char *key, virJSONValuePtr value, void *opaque) { struct testQEMUSchemaValidateObjectMemberData *data = opaque; virJSONValuePtr keymember = NULL; const char *keytype; virJSONValuePtr keyschema = NULL; int ret = -1; virBufferStrcat(data->debug, key, ": ", NULL); /* lookup 'member' entry for key */ if (!(keymember = testQEMUSchemaStealObjectMemberByName(key, data->rootmembers))) { virBufferAddLit(data->debug, "ERROR: attribute not in schema"); goto cleanup; } /* lookup schema entry for keytype */ if (!(keytype = virJSONValueObjectGetString(keymember, "type")) || !(keyschema = virHashLookup(data->schema, keytype))) { virBufferAsprintf(data->debug, "ERROR: can't find schema for type '%s'", NULLSTR(keytype)); ret = -2; goto cleanup; } /* recurse */ ret = testQEMUSchemaValidateRecurse(value, keyschema, data->schema, data->debug); cleanup: virBufferAddLit(data->debug, "\n"); virJSONValueFree(keymember); return ret; }
virCloseCallback virCloseCallbacksGet(virCloseCallbacksPtr closeCallbacks, virDomainObjPtr vm, virConnectPtr conn) { char uuidstr[VIR_UUID_STRING_BUFLEN]; virDriverCloseDefPtr closeDef; virCloseCallback cb = NULL; virUUIDFormat(vm->def->uuid, uuidstr); VIR_DEBUG("vm=%s, uuid=%s, conn=%p", vm->def->name, uuidstr, conn); virObjectLock(closeCallbacks); closeDef = virHashLookup(closeCallbacks->list, uuidstr); if (closeDef && (!conn || closeDef->conn == conn)) cb = closeDef->cb; virObjectUnlock(closeCallbacks); VIR_DEBUG("cb=%p", cb); return cb; }
/** * virNWFilterInstantiate: * @conn: pointer to virConnect object * @techdriver: The driver to use for instantiation * @filter: The filter to instantiate * @ifname: The name of the interface to apply the rules to * @vars: A map holding variable names and values used for instantiating * the filter and its subfilters. * @forceWithPendingReq: Ignore the check whether a pending learn request * is active; 'true' only when the rules are applied late * * Returns 0 on success, a value otherwise. * * Instantiate a filter by instantiating the filter itself along with * all its subfilters in a depth-first traversal of the tree of referenced * filters. The name of the interface to which the rules belong must be * provided. Apply the values of variables as needed. * * Call this function while holding the NWFilter filter update lock */ static int virNWFilterInstantiate(virConnectPtr conn, virNWFilterTechDriverPtr techdriver, enum virDomainNetType nettype, virNWFilterDefPtr filter, const char *ifname, int ifindex, const char *linkdev, virNWFilterHashTablePtr vars, enum instCase useNewFilter, bool *foundNewFilter, bool teardownOld, const unsigned char *macaddr, virNWFilterDriverStatePtr driver, bool forceWithPendingReq) { int rc; int j, nptrs; int nEntries = 0; virNWFilterRuleInstPtr *insts = NULL; void **ptrs = NULL; int instantiate = 1; virNWFilterHashTablePtr missing_vars = virNWFilterHashTableCreate(0); if (!missing_vars) { virReportOOMError(); rc = 1; goto err_exit; } rc = virNWFilterDetermineMissingVarsRec(conn, filter, vars, missing_vars, useNewFilter, driver); if (rc) goto err_exit; if (virHashSize(missing_vars->hashTable) == 1) { if (virHashLookup(missing_vars->hashTable, NWFILTER_STD_VAR_IP) != NULL) { if (virNWFilterLookupLearnReq(ifindex) == NULL) { rc = virNWFilterLearnIPAddress(techdriver, ifname, ifindex, linkdev, nettype, macaddr, filter->name, vars, driver, DETECT_DHCP|DETECT_STATIC); } goto err_exit; } rc = 1; goto err_exit; } else if (virHashSize(missing_vars->hashTable) > 1) { rc = 1; goto err_exit; } else if (!forceWithPendingReq && virNWFilterLookupLearnReq(ifindex) != NULL) { goto err_exit; } rc = _virNWFilterInstantiateRec(conn, techdriver, nettype, filter, ifname, vars, &nEntries, &insts, useNewFilter, foundNewFilter, driver); if (rc) goto err_exit; switch (useNewFilter) { case INSTANTIATE_FOLLOW_NEWFILTER: instantiate = *foundNewFilter; break; case INSTANTIATE_ALWAYS: instantiate = 1; break; } if (instantiate) { rc = virNWFilterRuleInstancesToArray(nEntries, insts, &ptrs, &nptrs); if (rc) goto err_exit; if (virNWFilterLockIface(ifname)) goto err_exit; rc = techdriver->applyNewRules(conn, ifname, nptrs, ptrs); if (teardownOld && rc == 0) techdriver->tearOldRules(conn, ifname); if (rc == 0 && ifaceCheck(false, ifname, NULL, ifindex)) { /* interface changed/disppeared */ techdriver->allTeardown(ifname); rc = 1; } virNWFilterUnlockIface(ifname); } err_exit: for (j = 0; j < nEntries; j++) virNWFilterRuleInstFree(insts[j]); VIR_FREE(insts); VIR_FREE(ptrs); virNWFilterHashTableFree(missing_vars); return rc; }
const char * virNWFilterVarCombIterGetVarValue(virNWFilterVarCombIterPtr ci, const virNWFilterVarAccess *vap) { size_t i; unsigned int iterId; bool found = false; const char *res = NULL; virNWFilterVarValuePtr value; int iterIndex = -1; const char *varName = virNWFilterVarAccessGetVarName(vap); switch (virNWFilterVarAccessGetType(vap)) { case VIR_NWFILTER_VAR_ACCESS_ITERATOR: iterId = virNWFilterVarAccessGetIterId(vap); iterIndex = virNWFilterVarCombIterGetIndexByIterId(ci, iterId); if (iterIndex < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not get iterator index for " "iterator ID %u"), iterId); return NULL; } break; case VIR_NWFILTER_VAR_ACCESS_ELEMENT: iterId = virNWFilterVarAccessGetIntIterId(vap); iterIndex = virNWFilterVarCombIterGetIndexByIterId(ci, iterId); if (iterIndex < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not get iterator index for " "(internal) iterator ID %u"), iterId); return NULL; } break; case VIR_NWFILTER_VAR_ACCESS_LAST: return NULL; } for (i = 0; i < ci->iter[iterIndex].nVarNames; i++) { if (STREQ(ci->iter[iterIndex].varNames[i], varName)) { found = true; break; } } if (!found) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not find variable '%s' in iterator"), varName); return NULL; } value = virHashLookup(ci->hashTable->hashTable, varName); if (!value) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not find value for variable '%s'"), varName); return NULL; } res = virNWFilterVarValueGetNthValue(value, ci->iter[iterIndex].curValue); if (!res) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not get nth (%u) value of " "variable '%s'"), ci->iter[iterIndex].curValue, varName); return NULL; } return res; }
static virCPUDefPtr genericBaseline(virCPUDefPtr *cpus, unsigned int ncpus, const char **models, unsigned int nmodels, unsigned int flags) { virCPUDefPtr cpu = NULL; virCPUFeatureDefPtr features = NULL; unsigned int nfeatures; unsigned int count; size_t i, j; virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES | VIR_CONNECT_BASELINE_CPU_MIGRATABLE, NULL); if (!cpuModelIsAllowed(cpus[0]->model, models, nmodels)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("CPU model %s is not supported by hypervisor"), cpus[0]->model); goto error; } if (VIR_ALLOC(cpu) < 0 || VIR_STRDUP(cpu->model, cpus[0]->model) < 0 || VIR_ALLOC_N(features, cpus[0]->nfeatures) < 0) goto error; cpu->arch = cpus[0]->arch; cpu->type = VIR_CPU_TYPE_HOST; count = nfeatures = cpus[0]->nfeatures; for (i = 0; i < nfeatures; i++) features[i].name = cpus[0]->features[i].name; for (i = 1; i < ncpus; i++) { virHashTablePtr hash; if (cpu->arch != cpus[i]->arch) { virReportError(VIR_ERR_INTERNAL_ERROR, _("CPUs have incompatible architectures: '%s' != '%s'"), virArchToString(cpu->arch), virArchToString(cpus[i]->arch)); goto error; } if (STRNEQ(cpu->model, cpus[i]->model)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("CPU models don't match: '%s' != '%s'"), cpu->model, cpus[i]->model); goto error; } if (!(hash = genericHashFeatures(cpus[i]))) goto error; for (j = 0; j < nfeatures; j++) { if (features[j].name && !virHashLookup(hash, features[j].name)) { features[j].name = NULL; count--; } } virHashFree(hash); } if (VIR_ALLOC_N(cpu->features, count) < 0) goto error; cpu->nfeatures = count; j = 0; for (i = 0; i < nfeatures; i++) { if (!features[i].name) continue; if (VIR_STRDUP(cpu->features[j++].name, features[i].name) < 0) goto error; } cleanup: VIR_FREE(features); return cpu; error: virCPUDefFree(cpu); cpu = NULL; goto cleanup; }