예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
/* 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;
}
예제 #4
0
/* 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;
}
예제 #5
0
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;
}
예제 #6
0
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);
}
예제 #7
0
/*
 * 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;
}
예제 #8
0
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;
}
예제 #9
0
/**
 * 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));
}
예제 #10
0
/**
 * 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;
}
예제 #11
0
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;
}
예제 #12
0
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;
}
예제 #13
0
/* 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;
}
예제 #14
0
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;
}
예제 #15
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;
}
예제 #16
0
파일: qemu_conf.c 프로젝트: Lantame/libvirt
/*
 * 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;
}
예제 #17
0
virNWFilterIPAddrLearnReqPtr
virNWFilterLookupLearnReq(int ifindex)
{
    void *res;
    IFINDEX2STR(ifindex_str, ifindex);

    virMutexLock(&pendingLearnReqLock);

    res = virHashLookup(pendingLearnReq, ifindex_str);

    virMutexUnlock(&pendingLearnReqLock);

    return res;
}
예제 #18
0
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;
}
예제 #19
0
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);
}
예제 #20
0
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;
}
예제 #21
0
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;
}
예제 #22
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;
}
예제 #23
0
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;
}
예제 #24
0
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;
}
예제 #25
0
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;
}
예제 #26
0
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;
}
예제 #27
0
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;
}
예제 #28
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;
}
예제 #29
0
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;
}
예제 #30
0
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;
}