Пример #1
0
virCapsPtr
virBhyveCapsBuild(void)
{
    virCapsPtr caps;
    virCapsGuestPtr guest;

    if ((caps = virCapabilitiesNew(virArchFromHost(),
                                   false, false)) == NULL)
        return NULL;

    if ((guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM,
                                         VIR_ARCH_X86_64,
                                         "bhyve",
                                         NULL, 0, NULL)) == NULL)
        goto error;

    if (virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_BHYVE,
                                      NULL, NULL, 0, NULL) == NULL)
        goto error;

    if (virBhyveCapsInitCPU(caps, virArchFromHost()) < 0)
        VIR_WARN("Failed to get host CPU: %s", virGetLastErrorMessage());

    return caps;

 error:
    virObjectUnref(caps);
    return NULL;
}
Пример #2
0
static int xenParseCmdline(virConfPtr conf, char **r_cmdline)
{
    char *cmdline = NULL;
    const char *root, *extra, *buf;

    if (xenConfigGetString(conf, "cmdline", &buf, NULL) < 0)
        return -1;

    if (xenConfigGetString(conf, "root", &root, NULL) < 0)
        return -1;

    if (xenConfigGetString(conf, "extra", &extra, NULL) < 0)
        return -1;

    if (buf) {
        if (VIR_STRDUP(cmdline, buf) < 0)
            return -1;
        if (root || extra)
            VIR_WARN("ignoring root= and extra= in favour of cmdline=");
    } else {
        if (root && extra) {
            if (virAsprintf(&cmdline, "root=%s %s", root, extra) < 0)
                return -1;
        } else if (root) {
            if (virAsprintf(&cmdline, "root=%s", root) < 0)
                return -1;
        } else if (extra) {
            if (VIR_STRDUP(cmdline, extra) < 0)
                return -1;
        }
    }

    *r_cmdline = cmdline;
    return 0;
}
Пример #3
0
void virEventPollUpdateTimeout(int timer, int frequency)
{
    unsigned long long now;
    int i;
    PROBE(EVENT_POLL_UPDATE_TIMEOUT,
          "timer=%d frequency=%d",
          timer, frequency);

    if (timer <= 0) {
        VIR_WARN("Ignoring invalid update timer %d", timer);
        return;
    }

    if (virTimeMillisNow(&now) < 0) {
        return;
    }

    virMutexLock(&eventLoop.lock);
    for (i = 0 ; i < eventLoop.timeoutsCount ; i++) {
        if (eventLoop.timeouts[i].timer == timer) {
            eventLoop.timeouts[i].frequency = frequency;
            eventLoop.timeouts[i].expiresAt =
                frequency >= 0 ? frequency + now : 0;
            virEventPollInterruptLocked();
            break;
        }
    }
    virMutexUnlock(&eventLoop.lock);
}
Пример #4
0
/*
 * Unregister a callback for a timer
 * NB, it *must* be safe to call this from within a callback
 * For this reason we only ever set a flag in the existing list.
 * Actual deletion will be done out-of-band
 */
int virEventPollRemoveTimeout(int timer)
{
    size_t i;
    PROBE(EVENT_POLL_REMOVE_TIMEOUT,
          "timer=%d",
          timer);

    if (timer <= 0) {
        VIR_WARN("Ignoring invalid remove timer %d", timer);
        return -1;
    }

    virMutexLock(&eventLoop.lock);
    for (i = 0; i < eventLoop.timeoutsCount; i++) {
        if (eventLoop.timeouts[i].deleted)
            continue;

        if (eventLoop.timeouts[i].timer == timer) {
            eventLoop.timeouts[i].deleted = 1;
            virEventPollInterruptLocked();
            virMutexUnlock(&eventLoop.lock);
            return 0;
        }
    }
    virMutexUnlock(&eventLoop.lock);
    return -1;
}
Пример #5
0
/**
 * virStorageBackendZFSVolModeNeeded:
 *
 * Checks if it's necessary to specify 'volmode' (i.e. that
 * we're working with BSD ZFS implementation).
 *
 * Returns 1 if 'volmode' is need, 0 if not needed, -1 on error
 */
static int
virStorageBackendZFSVolModeNeeded(void)
{
    virCommandPtr cmd = NULL;
    int ret = -1, exit_code = -1;
    char *error = NULL;

    /* 'zfs get' without arguments prints out
     * usage information to stderr, including
     * list of supported options, and exits with
     * exit code 2
     */
    cmd = virCommandNewArgList(ZFS, "get", NULL);
    virCommandAddEnvString(cmd, "LC_ALL=C");
    virCommandSetErrorBuffer(cmd, &error);

    ret = virCommandRun(cmd, &exit_code);
    if ((ret < 0) || (exit_code != 2)) {
        VIR_WARN("Command 'zfs get' either failed "
                 "to run or exited with unexpected status");
        goto cleanup;
    }

    if (strstr(error, " volmode "))
        ret = 1;
    else
        ret = 0;

 cleanup:
    virCommandFree(cmd);
    VIR_FREE(error);
    return ret;
}
Пример #6
0
static int
qemuAgentIOProcessEvent(qemuAgentPtr mon,
                        virJSONValuePtr obj)
{
    const char *type;
    VIR_DEBUG("mon=%p obj=%p", mon, obj);

    type = virJSONValueObjectGetString(obj, "event");
    if (!type) {
        VIR_WARN("missing event type in message");
        errno = EINVAL;
        return -1;
    }

/*
    for (i = 0; i < ARRAY_CARDINALITY(eventHandlers); i++) {
        if (STREQ(eventHandlers[i].type, type)) {
            virJSONValuePtr data = virJSONValueObjectGet(obj, "data");
            VIR_DEBUG("handle %s handler=%p data=%p", type,
                      eventHandlers[i].handler, data);
            (eventHandlers[i].handler)(mon, data);
            break;
        }
    }
*/
    return 0;
}
Пример #7
0
/**
 * virArchFromHost:
 *
 * Return the host architecture. Prefer this to the
 * uname 'machine' field, since this will canonicalize
 * architecture names like 'amd64' into 'x86_64'.
 */
virArch virArchFromHost(void)
{
    struct utsname ut;
    virArch arch;

    uname(&ut);

    /* Some special cases we need to handle first
     * for non-canonical names */
    if (strlen(ut.machine) == 4 &&
        ut.machine[0] == 'i' &&
        ut.machine[2] == '8' &&
        ut.machine[3] == '6' &&
        ut.machine[4] == '\0') {
        arch = VIR_ARCH_I686;
    } else if (STREQ(ut.machine, "amd64")) {
        arch = VIR_ARCH_X86_64;
    } else {
        /* Otherwise assume the canonical name */
        if ((arch = virArchFromString(ut.machine)) == VIR_ARCH_NONE) {
            VIR_WARN("Unknown host arch %s, report to [email protected]",
                     ut.machine);
        }
    }

    VIR_DEBUG("Mapped %s to %d (%s)",
              ut.machine, arch, virArchToString(arch));

    return arch;
}
Пример #8
0
virSecurityManagerPtr
virSecurityManagerNew(const char *name,
                      const char *virtDriver,
                      unsigned int flags)
{
    virSecurityDriverPtr drv = virSecurityDriverLookup(name, virtDriver);
    if (!drv)
        return NULL;

    /* driver "none" needs some special handling of *Confined bools */
    if (STREQ(drv->name, "none")) {
        if (flags & VIR_SECURITY_MANAGER_REQUIRE_CONFINED) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Security driver \"none\" cannot create confined guests"));
            return NULL;
        }

        if (flags & VIR_SECURITY_MANAGER_DEFAULT_CONFINED) {
            if (name != NULL) {
                VIR_WARN("Configured security driver \"none\" disables default"
                         " policy to create confined guests");
            } else {
                VIR_DEBUG("Auto-probed security driver is \"none\";"
                          " confined guests will not be created");
            }
            flags &= ~VIR_SECURITY_MANAGER_DEFAULT_CONFINED;
        }
    }

    return virSecurityManagerNewDriver(drv,
                                       virtDriver,
                                       flags);
}
Пример #9
0
/**
 * virRandomBits:
 * @nbits: Number of bits of randommess required
 *
 * Generate an evenly distributed random number between [0,2^nbits), where
 * @nbits must be in the range (0,64].
 *
 * Return: a random number with @nbits entropy
 */
uint64_t virRandomBits(int nbits)
{
    uint64_t ret = 0;
    int32_t bits;

    if (virRandomInitialize() < 0) {
        /* You're already hosed, so this particular non-random value
         * isn't any worse.  */
        VIR_WARN("random number generation is broken");
        return 0;
    }

    virMutexLock(&randomLock);

    while (nbits > RANDOM_BITS_PER_ITER) {
        random_r(&randomData, &bits);
        ret = (ret << RANDOM_BITS_PER_ITER) | (bits & RANDOM_BITS_MASK);
        nbits -= RANDOM_BITS_PER_ITER;
    }

    random_r(&randomData, &bits);
    ret = (ret << nbits) | (bits & ((1 << nbits) - 1));

    virMutexUnlock(&randomLock);
    return ret;
}
Пример #10
0
void
qemuSecurityRestoreAllLabel(virQEMUDriverPtr driver,
                            virDomainObjPtr vm,
                            bool migrated)
{
    qemuDomainObjPrivatePtr priv = vm->privateData;
    bool transactionStarted = false;

    /* In contrast to qemuSecuritySetAllLabel, do not use vm->pid
     * here. This function is called from qemuProcessStop() which
     * is meant to do cleanup after qemu process died. The
     * domain's namespace is gone as qemu was the only process
     * running there. We would not succeed in entering the
     * namespace then. */
    if (virSecurityManagerTransactionStart(driver->securityManager) >= 0)
        transactionStarted = true;

    virSecurityManagerRestoreAllLabel(driver->securityManager,
                                      vm->def,
                                      migrated,
                                      priv->chardevStdioLogd);

    if (transactionStarted &&
        virSecurityManagerTransactionCommit(driver->securityManager, -1) < 0)
        VIR_WARN("Unable to run security manager transaction");

    virSecurityManagerTransactionAbort(driver->securityManager);
}
Пример #11
0
static void
virNetworkEventDispatchDefaultFunc(virConnectPtr conn,
                                   virObjectEventPtr event,
                                   virConnectObjectEventGenericCallback cb,
                                   void *cbopaque)
{
    virNetworkPtr net = virGetNetwork(conn, event->meta.name, event->meta.uuid);
    if (!net)
        return;

    switch ((virNetworkEventID)event->eventID) {
    case VIR_NETWORK_EVENT_ID_LIFECYCLE:
        {
            virNetworkEventLifecyclePtr networkLifecycleEvent;

            networkLifecycleEvent = (virNetworkEventLifecyclePtr)event;
            ((virConnectNetworkEventLifecycleCallback)cb)(conn, net,
                                                          networkLifecycleEvent->type,
                                                          networkLifecycleEvent->detail,
                                                          cbopaque);
            goto cleanup;
        }

    case VIR_NETWORK_EVENT_ID_LAST:
        break;
    }
    VIR_WARN("Unexpected event ID %d", event->eventID);

 cleanup:
    virNetworkFree(net);
}
Пример #12
0
static virCPUCompareResult
virCPUppc64Compare(virCPUDefPtr host,
                   virCPUDefPtr cpu,
                   bool failIncompatible)
{
    virCPUCompareResult ret;
    char *message = NULL;

    if (!host || !host->model) {
        if (failIncompatible) {
            virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s",
                           _("unknown host CPU"));
        } else {
            VIR_WARN("unknown host CPU");
            ret = VIR_CPU_COMPARE_INCOMPATIBLE;
        }
        return -1;
    }

    ret = ppc64Compute(host, cpu, NULL, &message);

    if (failIncompatible && ret == VIR_CPU_COMPARE_INCOMPATIBLE) {
        ret = VIR_CPU_COMPARE_ERROR;
        if (message) {
            virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s", message);
        } else {
            virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL);
        }
    }
    VIR_FREE(message);

    return ret;
}
Пример #13
0
/*
 * Unregister a callback from a file handle
 * NB, it *must* be safe to call this from within a callback
 * For this reason we only ever set a flag in the existing list.
 * Actual deletion will be done out-of-band
 */
int virEventPollRemoveHandle(int watch)
{
    size_t i;
    PROBE(EVENT_POLL_REMOVE_HANDLE,
          "watch=%d",
          watch);

    if (watch <= 0) {
        VIR_WARN("Ignoring invalid remove watch %d", watch);
        return -1;
    }

    virMutexLock(&eventLoop.lock);
    for (i = 0; i < eventLoop.handlesCount; i++) {
        if (eventLoop.handles[i].deleted)
            continue;

        if (eventLoop.handles[i].watch == watch) {
            EVENT_DEBUG("mark delete %zu %d", i, eventLoop.handles[i].fd);
            eventLoop.handles[i].deleted = 1;
            virEventPollInterruptLocked();
            virMutexUnlock(&eventLoop.lock);
            return 0;
        }
    }
    virMutexUnlock(&eventLoop.lock);
    return -1;
}
Пример #14
0
/**
 * virHookCheck:
 * @driver: the driver name "daemon", "qemu", "lxc"...
 *
 * Check is there is an installed hook for the given driver, if this
 * is the case register it. Then subsequent calls to virHookCall
 * will call the hook if found.
 *
 * Returns 1 if found, 0 if not found, and -1 in case of error
 */
static int
virHookCheck(int no, const char *driver) {
    char *path;
    int ret;

    if (driver == NULL) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Invalid hook name for #%d"), no);
        return -1;
    }

    ret = virBuildPath(&path, LIBVIRT_HOOK_DIR, driver);
    if ((ret < 0) || (path == NULL)) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to build path for %s hook"),
                       driver);
        return -1;
    }

    if (!virFileExists(path)) {
        ret = 0;
        VIR_DEBUG("No hook script %s", path);
    } else if (!virFileIsExecutable(path)) {
        ret = 0;
        VIR_WARN("Non-executable hook script %s", path);
    } else {
        ret = 1;
        VIR_DEBUG("Found hook script %s", path);
    }

    VIR_FREE(path);
    return ret;
}
Пример #15
0
void virNetClientIncomingEvent(virNetSocketPtr sock,
                               int events,
                               void *opaque)
{
    virNetClientPtr client = opaque;

    virNetClientLock(client);

    if (!client->sock)
        goto done;

    /* This should be impossible, but it doesn't hurt to check */
    if (client->waitDispatch)
        goto done;

    VIR_DEBUG("Event fired %p %d", sock, events);

    if (events & (VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR)) {
        VIR_DEBUG("%s : VIR_EVENT_HANDLE_HANGUP or "
                  "VIR_EVENT_HANDLE_ERROR encountered", __FUNCTION__);
        virNetSocketRemoveIOCallback(sock);
        goto done;
    }

    if (virNetClientIOHandleInput(client) < 0) {
        VIR_WARN("Something went wrong during async message processing");
        virNetSocketRemoveIOCallback(sock);
    }

done:
    virNetClientUnlock(client);
}
Пример #16
0
/*
 * Call after adding all arguments and environment settings, but before
 * Run/RunAsync, to immediately output the environment and arguments of
 * cmd to logfd.  If virCommandRun cannot succeed (because of an
 * out-of-memory condition while building cmd), nothing will be logged.
 */
void
virCommandWriteArgLog(virCommandPtr cmd, int logfd)
{
    int ioError = 0;
    size_t i;

    /* Any errors will be reported later by virCommandRun, which means
     * no command will be run, so there is nothing to log. */
    if (!cmd || cmd->has_error)
        return;

    for (i = 0 ; i < cmd->nenv ; i++) {
        if (safewrite(logfd, cmd->env[i], strlen(cmd->env[i])) < 0)
            ioError = errno;
        if (safewrite(logfd, " ", 1) < 0)
            ioError = errno;
    }
    for (i = 0 ; i < cmd->nargs ; i++) {
        if (safewrite(logfd, cmd->args[i], strlen(cmd->args[i])) < 0)
            ioError = errno;
        if (safewrite(logfd, i == cmd->nargs - 1 ? "\n" : " ", 1) < 0)
            ioError = errno;
    }

    if (ioError) {
        char ebuf[1024];
        VIR_WARN("Unable to write command %s args to logfile: %s",
                 cmd->args[0], virStrerror(ioError, ebuf, sizeof ebuf));
    }
}
Пример #17
0
static void
virKeepAliveTimer(int timer ATTRIBUTE_UNUSED, void *opaque)
{
    virKeepAlivePtr ka = opaque;
    virNetMessagePtr msg = NULL;
    bool dead;
    void *client;

    virObjectLock(ka);

    client = ka->client;
    dead = virKeepAliveTimerInternal(ka, &msg);

    if (!dead && !msg)
        goto cleanup;

    virObjectRef(ka);
    virObjectUnlock(ka);

    if (dead) {
        ka->deadCB(client);
    } else if (ka->sendCB(client, msg) < 0) {
        VIR_WARN("Failed to send keepalive request to client %p", client);
        virNetMessageFree(msg);
    }

    virObjectLock(ka);
    virObjectUnref(ka);

 cleanup:
    virObjectUnlock(ka);
}
Пример #18
0
/**
 * virEventRegisterImpl:
 * @addHandle: the callback to add fd handles
 * @updateHandle: the callback to update fd handles
 * @removeHandle: the callback to remove fd handles
 * @addTimeout: the callback to add a timeout
 * @updateTimeout: the callback to update a timeout
 * @removeTimeout: the callback to remove a timeout
 *
 * Registers an event implementation, to allow integration
 * with an external event loop. Applications would use this
 * to integrate with the libglib2 event loop, or libevent
 * or the QT event loop.
 *
 * For proper event handling, it is important that the event implementation
 * is registered before a connection to the Hypervisor is opened.
 *
 * Use of the virEventAddHandle() and similar APIs require that the
 * corresponding handler is registered.  Use of the
 * virConnectDomainEventRegisterAny() and similar APIs requires that
 * the three timeout handlers are registered.  Likewise, the three
 * timeout handlers must be registered if the remote server has been
 * configured to send keepalive messages, or if the client intends
 * to call virConnectSetKeepAlive(), to avoid either side from
 * unexpectedly closing the connection due to inactivity.
 *
 * If an application does not need to integrate with an
 * existing event loop implementation, then the
 * virEventRegisterDefaultImpl() method can be used to setup
 * the generic libvirt implementation.
 *
 * Once registered, the event loop implementation cannot be
 * changed, and must be run continuously. Note that callbacks
 * may remain registered for a short time even after calling
 * virConnectClose on all open connections, so it is not safe
 * to stop running the event loop immediately after closing
 * the connection.
 */
void virEventRegisterImpl(virEventAddHandleFunc addHandle,
                          virEventUpdateHandleFunc updateHandle,
                          virEventRemoveHandleFunc removeHandle,
                          virEventAddTimeoutFunc addTimeout,
                          virEventUpdateTimeoutFunc updateTimeout,
                          virEventRemoveTimeoutFunc removeTimeout)
{
    VIR_DEBUG("addHandle=%p updateHandle=%p removeHandle=%p "
              "addTimeout=%p updateTimeout=%p removeTimeout=%p",
              addHandle, updateHandle, removeHandle,
              addTimeout, updateTimeout, removeTimeout);

    if (addHandleImpl || updateHandleImpl || removeHandleImpl ||
        addTimeoutImpl || updateTimeoutImpl || removeTimeoutImpl) {
        VIR_WARN("Ignoring attempt to replace registered event loop");
        return;
    }

    addHandleImpl = addHandle;
    updateHandleImpl = updateHandle;
    removeHandleImpl = removeHandle;
    addTimeoutImpl = addTimeout;
    updateTimeoutImpl = updateTimeout;
    removeTimeoutImpl = removeTimeout;
}
Пример #19
0
static int
esxConnectListStoragePools(virConnectPtr conn, char **const names,
                           const int maxnames)
{
    bool success = false;
    esxPrivate *priv = conn->privateData;
    esxVI_String *propertyNameList = NULL;
    esxVI_DynamicProperty *dynamicProperty = NULL;
    esxVI_ObjectContent *datastoreList = NULL;
    esxVI_ObjectContent *datastore = NULL;
    int count = 0;
    size_t i;

    if (maxnames == 0)
        return 0;

    if (esxVI_String_AppendValueToList(&propertyNameList,
                                       "summary.name") < 0 ||
        esxVI_LookupDatastoreList(priv->primary, propertyNameList,
                                  &datastoreList) < 0) {
        goto cleanup;
    }

    for (datastore = datastoreList; datastore;
         datastore = datastore->_next) {
        for (dynamicProperty = datastore->propSet; dynamicProperty;
             dynamicProperty = dynamicProperty->_next) {
            if (STREQ(dynamicProperty->name, "summary.name")) {
                if (esxVI_AnyType_ExpectType(dynamicProperty->val,
                                             esxVI_Type_String) < 0) {
                    goto cleanup;
                }

                if (VIR_STRDUP(names[count], dynamicProperty->val->string) < 0)
                    goto cleanup;

                ++count;
                break;
            } else {
                VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
            }
        }
    }

    success = true;

 cleanup:
    if (! success) {
        for (i = 0; i < count; ++i)
            VIR_FREE(names[i]);

        count = -1;
    }

    esxVI_String_Free(&propertyNameList);
    esxVI_ObjectContent_Free(&datastoreList);

    return count;
}
static int
CVE_2013_6456_libvirt1_1_0_lxcDomainDetachDeviceHostdevMiscLive(virDomainObjPtr vm,
                                     virDomainDeviceDefPtr dev)
{
    virLXCDomainObjPrivatePtr priv = vm->privateData;
    virDomainHostdevDefPtr def = NULL;
    int i, ret = -1;
    char *dst = NULL;

    if (!priv->initpid) {
        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                       _("Cannot attach disk until init PID is known"));
        goto cleanup;
    }

    if ((i = virDomainHostdevFind(vm->def,
                                  dev->data.hostdev,
                                  &def)) < 0) {
        virReportError(VIR_ERR_OPERATION_FAILED,
                       _("hostdev %s not found"),
                       dev->data.hostdev->source.caps.u.misc.chardev);
        goto cleanup;
    }

    if (virAsprintf(&dst, "/proc/%llu/root/%s",
                    (unsigned long long)priv->initpid,
                    def->source.caps.u.misc.chardev) < 0) {
        virReportOOMError();
        goto cleanup;
    }

    if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES)) {
        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                       _("devices cgroup isn't mounted"));
        goto cleanup;
    }

    VIR_DEBUG("Unlinking %s", dst);
    if (unlink(dst) < 0 && errno != ENOENT) {
        virDomainAuditHostdev(vm, def, "detach", false);
        virReportSystemError(errno,
                             _("Unable to remove device %s"), dst);
        goto cleanup;
    }
    virDomainAuditHostdev(vm, def, "detach", true);

    if (virCgroupDenyDevicePath(priv->cgroup, def->source.caps.u.misc.chardev, VIR_CGROUP_DEVICE_RWM) != 0)
        VIR_WARN("cannot deny device %s for domain %s",
                 def->source.caps.u.misc.chardev, vm->def->name);

    virDomainHostdevRemove(vm->def, i);
    virDomainHostdevDefFree(def);

    ret = 0;

cleanup:
    VIR_FREE(dst);
    return ret;
}
Пример #21
0
/*
 * This tests sanity checking of our own certificates
 *
 * This code is done when libvirtd starts up, or before
 * a libvirt client connects. The test is ensuring that
 * the creation of virNetTLSContextPtr fails if we
 * give bogus certs, or succeeds for good certs
 */
static int testTLSContextInit(const void *opaque)
{
    struct testTLSContextData *data = (struct testTLSContextData *)opaque;
    virNetTLSContextPtr ctxt = NULL;
    int ret = -1;

    if (data->isServer) {
        ctxt = virNetTLSContextNewServer(data->cacrt,
                                         NULL,
                                         data->crt,
                                         KEYFILE,
                                         NULL,
                                         "NORMAL",
                                         true,
                                         true);
    } else {
        ctxt = virNetTLSContextNewClient(data->cacrt,
                                         NULL,
                                         data->crt,
                                         KEYFILE,
                                         "NORMAL",
                                         true,
                                         true);
    }

    if (ctxt) {
        if (data->expectFail) {
            VIR_WARN("Expected failure %s against %s",
                     data->cacrt, data->crt);
            goto cleanup;
        }
    } else {
        if (!data->expectFail) {
            VIR_WARN("Unexpected failure %s against %s",
                     data->cacrt, data->crt);
            goto cleanup;
        }
        VIR_DEBUG("Got error %s", virGetLastErrorMessage());
    }

    ret = 0;

 cleanup:
    virObjectUnref(ctxt);
    return ret;
}
Пример #22
0
/* XXX add an incremental streaming parser - yajl trivially supports it */
virJSONValuePtr virJSONValueFromString(const char *jsonstring)
{
    yajl_handle hand;
    virJSONParser parser = { NULL, NULL, 0 };
    virJSONValuePtr ret = NULL;
# ifndef HAVE_YAJL2
    yajl_parser_config cfg = { 1, 1 };
# endif

    VIR_DEBUG("string=%s", jsonstring);

# ifdef HAVE_YAJL2
    hand = yajl_alloc(&parserCallbacks, NULL, &parser);
    if (hand) {
        yajl_config(hand, yajl_allow_comments, 1);
        yajl_config(hand, yajl_dont_validate_strings, 0);
    }
# else
    hand = yajl_alloc(&parserCallbacks, &cfg, NULL, &parser);
# endif
    if (!hand) {
        virJSONError(VIR_ERR_INTERNAL_ERROR, "%s",
                     _("Unable to create JSON parser"));
        goto cleanup;
    }

    if (yajl_parse(hand,
                   (const unsigned char *)jsonstring,
                   strlen(jsonstring)) != yajl_status_ok) {
        unsigned char *errstr = yajl_get_error(hand, 1,
                                               (const unsigned char*)jsonstring,
                                               strlen(jsonstring));

        virJSONError(VIR_ERR_INTERNAL_ERROR,
                     _("cannot parse json %s: %s"),
                     jsonstring, (const char*) errstr);
        VIR_FREE(errstr);
        virJSONValueFree(parser.head);
        goto cleanup;
    }

    ret = parser.head;

cleanup:
    yajl_free(hand);

    if (parser.nstate) {
        int i;
        VIR_WARN("cleanup state %d", parser.nstate);
        for (i = 0 ; i < parser.nstate ; i++) {
            VIR_FREE(parser.state[i].key);
        }
    }

    VIR_DEBUG("result=%p", parser.head);

    return ret;
}
Пример #23
0
int
virNumaGetNodeCPUs(int node,
                   virBitmapPtr *cpus)
{
    unsigned long *mask = NULL;
    unsigned long *allonesmask = NULL;
    virBitmapPtr cpumap = NULL;
    int ncpus = 0;
    int max_n_cpus = virNumaGetMaxCPUs();
    int mask_n_bytes = max_n_cpus / 8;
    size_t i;
    int ret = -1;

    *cpus = NULL;

    if (VIR_ALLOC_N(mask, mask_n_bytes / sizeof(*mask)) < 0)
        goto cleanup;

    if (VIR_ALLOC_N(allonesmask, mask_n_bytes / sizeof(*mask)) < 0)
        goto cleanup;

    memset(allonesmask, 0xff, mask_n_bytes);

    /* The first time this returns -1, ENOENT if node doesn't exist... */
    if (numa_node_to_cpus(node, mask, mask_n_bytes) < 0) {
        VIR_WARN("NUMA topology for cell %d is not available, ignoring", node);
        ret = -2;
        goto cleanup;
    }

    /* second, third... times it returns an all-1's mask */
    if (memcmp(mask, allonesmask, mask_n_bytes) == 0) {
        VIR_DEBUG("NUMA topology for cell %d is invalid, ignoring", node);
        ret = -2;
        goto cleanup;
    }

    if (!(cpumap = virBitmapNew(max_n_cpus)))
        goto cleanup;

    for (i = 0; i < max_n_cpus; i++) {
        if (MASK_CPU_ISSET(mask, i)) {
            ignore_value(virBitmapSetBit(cpumap, i));
            ncpus++;
        }
    }

    *cpus = cpumap;
    cpumap = NULL;
    ret = ncpus;

cleanup:
    VIR_FREE(mask);
    VIR_FREE(allonesmask);
    virBitmapFree(cpumap);

    return ret;
}
Пример #24
0
static virNetMessagePtr
virKeepAliveMessage(virKeepAlivePtr ka, int proc)
{
    virNetMessagePtr msg;
    const char *procstr = NULL;

    switch (proc) {
    case KEEPALIVE_PROC_PING:
        procstr = "request";
        break;
    case KEEPALIVE_PROC_PONG:
        procstr = "response";
        break;
    default:
        VIR_WARN("Refusing to send unknown keepalive message: %d", proc);
        return NULL;
    }

    if (!(msg = virNetMessageNew(false)))
        goto error;

    msg->header.prog = KEEPALIVE_PROGRAM;
    msg->header.vers = KEEPALIVE_PROTOCOL_VERSION;
    msg->header.type = VIR_NET_MESSAGE;
    msg->header.proc = proc;

    if (virNetMessageEncodeHeader(msg) < 0 ||
        virNetMessageEncodePayloadEmpty(msg) < 0) {
        virNetMessageFree(msg);
        goto error;
    }

    VIR_DEBUG("Sending keepalive %s to client %p", procstr, ka->client);
    PROBE(RPC_KEEPALIVE_SEND,
          "ka=%p client=%p prog=%d vers=%d proc=%d",
          ka, ka->client, msg->header.prog, msg->header.vers, msg->header.proc);

    return msg;

error:
    VIR_WARN("Failed to generate keepalive %s", procstr);
    VIR_FREE(msg);
    return NULL;
}
Пример #25
0
static virDomainNetDefPtr
lxcCreateNetDef(const char *type,
                const char *linkdev,
                const char *mac,
                const char *flag,
                const char *macvlanmode,
                const char *name)
{
    virDomainNetDefPtr net = NULL;
    virMacAddr macAddr;

    if (VIR_ALLOC(net) < 0)
        goto error;

    if (STREQ_NULLABLE(flag, "up"))
        net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_UP;
    else
        net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN;

    if (VIR_STRDUP(net->ifname_guest, name) < 0)
        goto error;

    if (mac && virMacAddrParse(mac, &macAddr) == 0)
        net->mac = macAddr;

    if (STREQ(type, "veth")) {
        if (!linkdev)
            goto error;

        net->type = VIR_DOMAIN_NET_TYPE_BRIDGE;

        if (VIR_STRDUP(net->data.bridge.brname, linkdev) < 0)
            goto error;

    } else if (STREQ(type, "macvlan")) {
        net->type = VIR_DOMAIN_NET_TYPE_DIRECT;

        if (!linkdev || VIR_STRDUP(net->data.direct.linkdev, linkdev) < 0)
            goto error;

        if (!macvlanmode || STREQ(macvlanmode, "private"))
            net->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_PRIVATE;
        else if (STREQ(macvlanmode, "vepa"))
            net->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_VEPA;
        else if (STREQ(macvlanmode, "bridge"))
            net->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_BRIDGE;
        else
            VIR_WARN("Unknown macvlan type: %s", macvlanmode);
    }

    return net;

 error:
    virDomainNetDefFree(net);
    return NULL;
}
Пример #26
0
/**
 * virLogSetDefaultPriority:
 * @priority: the default priority level
 *
 * Set the default priority level, i.e. any logged data of a priority
 * equal or superior to this level will be logged, unless a specific rule
 * was defined for the log category of the message.
 *
 * Returns 0 if successful, -1 in case of error.
 */
int virLogSetDefaultPriority(int priority) {
    if ((priority < VIR_LOG_DEBUG) || (priority > VIR_LOG_ERROR)) {
        VIR_WARN("Ignoring invalid log level setting.");
        return -1;
    }
    if (!virLogInitialized)
        virLogStartup();
    virLogDefaultPriority = priority;
    return 0;
}
Пример #27
0
static int lxcSetupLoopDevice(virDomainFSDefPtr fs)
{
    int lofd = -1;
    int fsfd = -1;
    struct loop_info64 lo;
    char *loname = NULL;
    int ret = -1;

    if ((lofd = lxcGetLoopFD(&loname)) < 0)
        return -1;

    memset(&lo, 0, sizeof(lo));
    lo.lo_flags = LO_FLAGS_AUTOCLEAR;

    if ((fsfd = open(fs->src, O_RDWR)) < 0) {
        virReportSystemError(errno,
                             _("Unable to open %s"), fs->src);
        goto cleanup;
    }

    if (ioctl(lofd, LOOP_SET_FD, fsfd) < 0) {
        virReportSystemError(errno,
                             _("Unable to attach %s to loop device"),
                             fs->src);
        goto cleanup;
    }

    if (ioctl(lofd, LOOP_SET_STATUS64, &lo) < 0) {
        virReportSystemError(errno, "%s",
                             _("Unable to mark loop device as autoclear"));

        if (ioctl(lofd, LOOP_CLR_FD, 0) < 0)
            VIR_WARN("Unable to detach %s from loop device", fs->src);
        goto cleanup;
    }

    VIR_DEBUG("Attached loop device  %s %d to %s", fs->src, lofd, loname);
    /*
     * We now change it into a block device type, so that
     * the rest of container setup 'just works'
     */
    fs->type = VIR_DOMAIN_FS_TYPE_BLOCK;
    VIR_FREE(fs->src);
    fs->src = loname;
    loname = NULL;

    ret = 0;

cleanup:
    VIR_FREE(loname);
    VIR_FORCE_CLOSE(fsfd);
    if (ret == -1)
        VIR_FORCE_CLOSE(lofd);
    return lofd;
}
Пример #28
0
static void virLXCProcessMonitorInitNotify(virLXCMonitorPtr mon ATTRIBUTE_UNUSED,
                                           pid_t initpid,
                                           virDomainObjPtr vm)
{
    virLXCDomainObjPrivatePtr priv = vm->privateData;
    priv->initpid = initpid;
    virDomainAuditInit(vm, initpid);

    if (virDomainSaveStatus(lxc_driver->caps, lxc_driver->stateDir, vm) < 0)
        VIR_WARN("Cannot update XML with PID for LXC %s", vm->def->name);
}
Пример #29
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;
}
Пример #30
0
void *
virDriverLoadModule(const char *name)
{
    const char *moddir = getenv("LIBVIRT_DRIVER_DIR");
    char *modfile = NULL, *regfunc = NULL;
    void *handle = NULL;
    int (*regsym)(void);

    if (moddir == NULL)
        moddir = DEFAULT_DRIVER_DIR;

    VIR_DEBUG("Module load %s", name);

    if (virAsprintf(&modfile, "%s/libvirt_driver_%s.so", moddir, name) < 0)
        return NULL;

    if (access(modfile, R_OK) < 0) {
        VIR_WARN("Module %s not accessible", modfile);
        goto cleanup;
    }

    handle = dlopen(modfile, RTLD_NOW | RTLD_LOCAL);
    if (!handle) {
        VIR_ERROR(_("failed to load module %s %s"), modfile, dlerror());
        goto cleanup;
    }

    if (virAsprintf(&regfunc, "%sRegister", name) < 0) {
        goto cleanup;
    }

    regsym = dlsym(handle, regfunc);
    if (!regsym) {
        VIR_ERROR(_("Missing module registration symbol %s"), regfunc);
        goto cleanup;
    }

    if ((*regsym)() < 0) {
        VIR_ERROR(_("Failed module registration %s"), regfunc);
        goto cleanup;
    }

    VIR_FREE(modfile);
    VIR_FREE(regfunc);
    return handle;

cleanup:
    VIR_FREE(modfile);
    VIR_FREE(regfunc);
    if (handle)
        dlclose(handle);
    return NULL;
}