static int testHashCheckCount(virHashTablePtr hash, size_t count) { ssize_t iter_count = 0; if (virHashSize(hash) != count) { testError("\nhash contains %zu instead of %zu elements\n", (size_t)virHashSize(hash), count); return -1; } iter_count = virHashForEach(hash, testHashCheckForEachCount, NULL); if (count != iter_count) { testError("\nhash claims to have %zu elements but iteration finds %zu\n", count, (size_t)iter_count); return -1; } return 0; }
/** * 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; }
virHashKeyValuePairPtr virHashGetItems(virHashTablePtr table, virHashKeyComparator compar) { ssize_t numElems = virHashSize(table); struct getKeysIter iter = { .arrayIdx = 0, .sortArray = NULL, }; if (numElems < 0) return NULL; if (VIR_ALLOC_N(iter.sortArray, numElems + 1)) { virReportOOMError(); return NULL; } virHashForEach(table, virHashGetKeysIterator, &iter); if (compar) qsort(&iter.sortArray[0], numElems, sizeof(iter.sortArray[0]), (qsort_comp)compar); return iter.sortArray; } struct virHashEqualData { bool equal; const virHashTablePtr table2; virHashValueComparator compar; }; static int virHashEqualSearcher(const void *payload, const void *name, const void *data) { struct virHashEqualData *vhed = (void *)data; const void *value; value = virHashLookup(vhed->table2, name); if (!value || vhed->compar(value, payload) != 0) { /* key is missing in 2nd table or values are different */ vhed->equal = false; /* stop 'iteration' */ return 1; } return 0; } bool virHashEqual(const virHashTablePtr table1, const virHashTablePtr table2, virHashValueComparator compar) { struct virHashEqualData data = { .equal = true, .table2 = table2, .compar = compar, }; if (table1 == table2) return true; if (!table1 || !table2 || virHashSize(table1) != virHashSize(table2)) return false; virHashSearch(table1, virHashEqualSearcher, &data); return data.equal; }