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; }
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; }
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); }
/* * 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; }
/** * 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; }
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; }
/** * 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; }
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); }
/** * 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; }
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); }
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); }
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; }
/* * 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; }
/** * 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; }
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); }
/* * 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)); } }
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); }
/** * 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; }
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; }
/* * 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; }
/* 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; }
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; }
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; }
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; }
/** * 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; }
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; }
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); }
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; }
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(®func, "%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; }