/** * virTypedParamsAddLLong: * @params: pointer to the array of typed parameters * @nparams: number of parameters in the @params array * @maxparams: maximum number of parameters that can be stored in @params * array without allocating more memory * @name: name of the parameter to find * @value: the value to store into the new parameter * * Adds new parameter called @name with long long int type and sets its value * to @value. If @params array points to NULL or to a space that is not large * enough to accommodate the new parameter (@maxparams < @nparams + 1), the * function allocates more space for it and updates @maxparams. On success, * @nparams is incremented by one. The function fails with VIR_ERR_INVALID_ARG * error if the parameter already exists in @params. * * Returns 0 on success, -1 on error. */ int virTypedParamsAddLLong(virTypedParameterPtr *params, int *nparams, int *maxparams, const char *name, long long value) { size_t max = *maxparams; size_t n = *nparams; virResetLastError(); if (VIR_RESIZE_N(*params, max, n, 1) < 0) goto error; *maxparams = max; if (virTypedParameterAssign(*params + n, name, VIR_TYPED_PARAM_LLONG, value) < 0) goto error; *nparams += 1; return 0; error: virDispatchError(NULL); return -1; }
/** * virTypedParamsFilter: * @params: array of typed parameters * @nparams: number of parameters in the @params array * @name: name of the parameter to find * @ret: pointer to the returned array * * Filters @params retaining only the parameters named @name in the * resulting array @ret. Caller should free the @ret array but not * the items since they are pointing to the @params elements. * * Returns amount of elements in @ret on success, -1 on error. */ int virTypedParamsFilter(virTypedParameterPtr params, int nparams, const char *name, virTypedParameterPtr **ret) { size_t i, alloc = 0, n = 0; virCheckNonNullArgGoto(params, error); virCheckNonNullArgGoto(name, error); virCheckNonNullArgGoto(ret, error); *ret = NULL; for (i = 0; i < nparams; i++) { if (STREQ(params[i].field, name)) { if (VIR_RESIZE_N(*ret, alloc, n, 1) < 0) goto error; (*ret)[n] = ¶ms[i]; n++; } } return n; error: return -1; }
/* * Add a NULL terminated list of args */ void virCommandAddArgList(virCommandPtr cmd, ...) { va_list list; int narg = 0; if (!cmd || cmd->has_error) return; va_start(list, cmd); while (va_arg(list, const char *) != NULL) narg++; va_end(list); /* narg plus trailing NULL. */ if (VIR_RESIZE_N(cmd->args, cmd->maxargs, cmd->nargs, narg + 1) < 0) { cmd->has_error = ENOMEM; return; } va_start(list, cmd); while (1) { char *arg = va_arg(list, char *); if (!arg) break; arg = strdup(arg); if (!arg) { cmd->has_error = ENOMEM; va_end(list); return; } cmd->args[cmd->nargs++] = arg; } va_end(list); }
/** * virCapabilitiesAddGuestFeature: * @guest: guest to associate feature with * @name: name of feature ('pae', 'acpi', 'apic') * @defaultOn: non-zero if it defaults to on * @toggle: non-zero if its state can be toggled * * Registers a feature for a guest domain */ virCapsGuestFeaturePtr virCapabilitiesAddGuestFeature(virCapsGuestPtr guest, const char *name, int defaultOn, int toggle) { virCapsGuestFeaturePtr feature; if (VIR_ALLOC(feature) < 0) goto no_memory; if ((feature->name = strdup(name)) == NULL) goto no_memory; feature->defaultOn = defaultOn; feature->toggle = toggle; if (VIR_RESIZE_N(guest->features, guest->nfeatures_max, guest->nfeatures, 1) < 0) goto no_memory; guest->features[guest->nfeatures++] = feature; return feature; no_memory: virCapabilitiesFreeGuestFeature(feature); return NULL; }
/** * virCapabilitiesAddHostNUMACell: * @caps: capabilities to extend * @num: ID number of NUMA cell * @mem: Total size of memory in the NUMA node (in KiB) * @ncpus: number of CPUs in cell * @cpus: array of CPU definition structures, the pointer is stolen * @nsiblings: number of sibling NUMA nodes * @siblings: info on sibling NUMA nodes * @npageinfo: number of pages at node @num * @pageinfo: info on each single memory page * * Registers a new NUMA cell for a host, passing in a * array of CPU IDs belonging to the cell */ int virCapabilitiesAddHostNUMACell(virCapsPtr caps, int num, unsigned long long mem, int ncpus, virCapsHostNUMACellCPUPtr cpus, int nsiblings, virCapsHostNUMACellSiblingInfoPtr siblings, int npageinfo, virCapsHostNUMACellPageInfoPtr pageinfo) { virCapsHostNUMACellPtr cell; if (VIR_RESIZE_N(caps->host.numaCell, caps->host.nnumaCell_max, caps->host.nnumaCell, 1) < 0) return -1; if (VIR_ALLOC(cell) < 0) return -1; cell->num = num; cell->mem = mem; cell->ncpus = ncpus; cell->cpus = cpus; cell->nsiblings = nsiblings; cell->siblings = siblings; cell->npageinfo = npageinfo; cell->pageinfo = pageinfo; caps->host.numaCell[caps->host.nnumaCell++] = cell; return 0; }
int virCPUDefAddFeature(virCPUDefPtr def, const char *name, int policy) { int i; for (i = 0 ; i < def->nfeatures ; i++) { if (STREQ(name, def->features[i].name)) { virCPUReportError(VIR_ERR_INTERNAL_ERROR, _("CPU feature `%s' specified more than once"), name); return -1; } } if (VIR_RESIZE_N(def->features, def->nfeatures_max, def->nfeatures, 1) < 0) goto no_memory; if (def->type == VIR_CPU_TYPE_HOST) policy = -1; if (!(def->features[def->nfeatures].name = strdup(name))) goto no_memory; def->features[def->nfeatures].policy = policy; def->nfeatures++; return 0; no_memory: virReportOOMError(); return -1; }
/** * virTypedParamsAddString: * @params: pointer to the array of typed parameters * @nparams: number of parameters in the @params array * @maxparams: maximum number of parameters that can be stored in @params * array without allocating more memory * @name: name of the parameter to find * @value: the value to store into the new parameter * * Adds new parameter called @name with char * type and sets its value to * @value. The function creates its own copy of @value string, which needs to * be freed using virTypedParamsFree or virTypedParamsClear. If @params array * points to NULL or to a space that is not large enough to accommodate the * new parameter (@maxparams < @nparams + 1), the function allocates more * space for it and updates @maxparams. On success, @nparams is incremented * by one. The function fails with VIR_ERR_INVALID_ARG error if the parameter * already exists in @params. * * Returns 0 on success, -1 on error. */ int virTypedParamsAddString(virTypedParameterPtr *params, int *nparams, int *maxparams, const char *name, const char *value) { char *str = NULL; size_t max = *maxparams; size_t n = *nparams; virResetLastError(); if (VIR_RESIZE_N(*params, max, n, 1) < 0) goto error; *maxparams = max; if (VIR_STRDUP(str, value) < 0) goto error; if (virTypedParameterAssign(*params + n, name, VIR_TYPED_PARAM_STRING, str) < 0) { VIR_FREE(str); goto error; } *nparams += 1; return 0; error: virDispatchError(NULL); return -1; }
/* * Add a NULL terminated list of args */ void virCommandAddArgSet(virCommandPtr cmd, const char *const*vals) { int narg = 0; if (!cmd || cmd->has_error) return; if (vals[0] == NULL) { cmd->has_error = EINVAL; return; } while (vals[narg] != NULL) narg++; /* narg plus trailing NULL. */ if (VIR_RESIZE_N(cmd->args, cmd->maxargs, cmd->nargs, narg + 1) < 0) { cmd->has_error = ENOMEM; return; } narg = 0; while (vals[narg] != NULL) { char *arg = strdup(vals[narg++]); if (!arg) { cmd->has_error = ENOMEM; return; } cmd->args[cmd->nargs++] = arg; } }
/** * virTypedParamsAddFromString: * @params: pointer to the array of typed parameters * @nparams: number of parameters in the @params array * @maxparams: maximum number of parameters that can be stored in @params * array without allocating more memory * @name: name of the parameter to find * @type: type of the parameter * @value: the value to store into the new parameter encoded as a string * * Adds new parameter called @name with the requested @type and parses its * value from the @value string. If the requested type is string, the function * creates its own copy of the @value string, which needs to be freed using * virTypedParamsFree or virTypedParamsClear. If @params array points to NULL * or to a space that is not large enough to accommodate the new parameter * (@maxparams < @nparams + 1), the function allocates more space for it and * updates @maxparams. On success, @nparams is incremented by one. The * function fails with VIR_ERR_INVALID_ARG error if the parameter already * exists in @params. * * Returns 0 on success, -1 on error. */ int virTypedParamsAddFromString(virTypedParameterPtr *params, int *nparams, int *maxparams, const char *name, int type, const char *value) { size_t max = *maxparams; size_t n = *nparams; virResetLastError(); if (VIR_RESIZE_N(*params, max, n, 1) < 0) goto error; *maxparams = max; if (virTypedParameterAssignFromStr(*params + n, name, type, value) < 0) goto error; *nparams += 1; return 0; error: virDispatchError(NULL); return -1; }
/** * virCapabilitiesAddHostNUMACell: * @caps: capabilities to extend * @num: ID number of NUMA cell * @ncpus: number of CPUs in cell * @mem: Total size of memory in the NUMA node (in KiB) * @cpus: array of CPU definition structures, the pointer is stolen * * Registers a new NUMA cell for a host, passing in a * array of CPU IDs belonging to the cell */ int virCapabilitiesAddHostNUMACell(virCapsPtr caps, int num, int ncpus, unsigned long long mem, virCapsHostNUMACellCPUPtr cpus) { virCapsHostNUMACellPtr cell; if (VIR_RESIZE_N(caps->host.numaCell, caps->host.nnumaCell_max, caps->host.nnumaCell, 1) < 0) return -1; if (VIR_ALLOC(cell) < 0) return -1; cell->ncpus = ncpus; cell->num = num; cell->mem = mem; cell->cpus = cpus; caps->host.numaCell[caps->host.nnumaCell++] = cell; return 0; }
/* * Add a command line argument created by a printf-style format */ void virCommandAddArgFormat(virCommandPtr cmd, const char *format, ...) { char *arg; va_list list; if (!cmd || cmd->has_error) return; va_start(list, format); if (virVasprintf(&arg, format, list) < 0) { cmd->has_error = ENOMEM; va_end(list); return; } va_end(list); /* Arg plus trailing NULL. */ if (VIR_RESIZE_N(cmd->args, cmd->maxargs, cmd->nargs, 1 + 1) < 0) { VIR_FREE(arg); cmd->has_error = ENOMEM; return; } cmd->args[cmd->nargs++] = arg; }
/** * virCapabilitiesAddGuestDomain: * @guest: guest to support * @hvtype: hypervisor type ('xen', 'qemu', 'kvm') * @emulator: specialized device emulator for domain * @loader: specialized BIOS loader for domain * @nmachines: number of machine variants for emulator * @machines: specialized machine variants for emulator * * Registers a virtual domain capable of running a * guest operating system */ virCapsGuestDomainPtr virCapabilitiesAddGuestDomain(virCapsGuestPtr guest, const char *hvtype, const char *emulator, const char *loader, int nmachines, virCapsGuestMachinePtr *machines) { virCapsGuestDomainPtr dom; if (VIR_ALLOC(dom) < 0) goto error; if (VIR_STRDUP(dom->type, hvtype) < 0 || VIR_STRDUP(dom->info.emulator, emulator) < 0 || VIR_STRDUP(dom->info.loader, loader) < 0) goto error; if (VIR_RESIZE_N(guest->arch.domains, guest->arch.ndomains_max, guest->arch.ndomains, 1) < 0) goto error; guest->arch.domains[guest->arch.ndomains] = dom; guest->arch.ndomains++; if (nmachines) { dom->info.nmachines = nmachines; dom->info.machines = machines; } return dom; error: virCapabilitiesFreeGuestDomain(dom); return NULL; }
/** * virCapabilitiesAddHostNUMACell: * @caps: capabilities to extend * @num: ID number of NUMA cell * @ncpus: number of CPUs in cell * @cpus: array of CPU ID numbers for cell * * Registers a new NUMA cell for a host, passing in a * array of CPU IDs belonging to the cell */ int virCapabilitiesAddHostNUMACell(virCapsPtr caps, int num, int ncpus, const int *cpus) { virCapsHostNUMACellPtr cell; if (VIR_RESIZE_N(caps->host.numaCell, caps->host.nnumaCell_max, caps->host.nnumaCell, 1) < 0) return -1; if (VIR_ALLOC(cell) < 0) return -1; if (VIR_ALLOC_N(cell->cpus, ncpus) < 0) { VIR_FREE(cell); return -1; } memcpy(cell->cpus, cpus, ncpus * sizeof(*cpus)); cell->ncpus = ncpus; cell->num = num; caps->host.numaCell[caps->host.nnumaCell++] = cell; return 0; }
/** * virNetlinkEventAddClient: * * @handleCB: callback to invoke when an event occurs * @removeCB: callback to invoke when removing a client * @opaque: user data to pass to callback * @macaddr: macaddr to store with the data. Used to identify callers. * May be null. * * register a callback for handling of netlink messages. The * registered function receives the entire netlink message and * may choose to act upon it. * * Returns -1 if the file handle cannot be registered, number of * monitor upon success. */ int virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB, virNetlinkEventRemoveCallback removeCB, void *opaque, const unsigned char *macaddr) { int i, r, ret = -1; virNetlinkEventSrvPrivatePtr srv = server; if (handleCB == NULL) { netlinkError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid NULL callback provided")); return -1; } virNetlinkEventServerLock(srv); VIR_DEBUG("adding client: %d.", nextWatch); r = 0; /* first try to re-use deleted free slots */ for (i = 0; i < srv->handlesCount; i++) { if (srv->handles[i].deleted == VIR_NETLINK_HANDLE_DELETED) { r = i; goto addentry; } } /* Resize the eventLoop array if needed */ if (srv->handlesCount == srv->handlesAlloc) { VIR_DEBUG("Used %zu handle slots, adding at least %d more", srv->handlesAlloc, NETLINK_EVENT_ALLOC_EXTENT); if (VIR_RESIZE_N(srv->handles, srv->handlesAlloc, srv->handlesCount, NETLINK_EVENT_ALLOC_EXTENT) < 0) { virReportOOMError(); goto error; } } r = srv->handlesCount++; addentry: srv->handles[r].watch = nextWatch; srv->handles[r].handleCB = handleCB; srv->handles[r].removeCB = removeCB; srv->handles[r].opaque = opaque; srv->handles[r].deleted = VIR_NETLINK_HANDLE_VALID; if (macaddr) memcpy(srv->handles[r].macaddr, macaddr, VIR_MAC_BUFLEN); else memset(srv->handles[r].macaddr, 0, VIR_MAC_BUFLEN); VIR_DEBUG("added client to loop slot: %d. with macaddr ptr=%p", r, macaddr); ret = nextWatch++; error: virNetlinkEventServerUnlock(srv); return ret; }
/** * virNetlinkEventAddClient: * * @handleCB: callback to invoke when an event occurs * @removeCB: callback to invoke when removing a client * @opaque: user data to pass to callback * @macaddr: macaddr to store with the data. Used to identify callers. * May be null. * @protocol: netlink protocol * * register a callback for handling of netlink messages. The * registered function receives the entire netlink message and * may choose to act upon it. * * Returns -1 if the file handle cannot be registered, number of * monitor upon success. */ int virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB, virNetlinkEventRemoveCallback removeCB, void *opaque, const virMacAddrPtr macaddr, unsigned int protocol) { int i, r, ret = -1; virNetlinkEventSrvPrivatePtr srv = NULL; if (protocol >= MAX_LINKS) return -EINVAL; srv = server[protocol]; if (handleCB == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid NULL callback provided")); return -1; } virNetlinkEventServerLock(srv); VIR_DEBUG("adding client: %d.", nextWatch); r = 0; /* first try to re-use deleted free slots */ for (i = 0; i < srv->handlesCount; i++) { if (srv->handles[i].deleted == VIR_NETLINK_HANDLE_DELETED) { r = i; goto addentry; } } /* Resize the eventLoop array if needed */ if (srv->handlesCount == srv->handlesAlloc) { VIR_DEBUG("Used %zu handle slots, adding at least %d more", srv->handlesAlloc, NETLINK_EVENT_ALLOC_EXTENT); if (VIR_RESIZE_N(srv->handles, srv->handlesAlloc, srv->handlesCount, NETLINK_EVENT_ALLOC_EXTENT) < 0) { virReportOOMError(); goto error; } } r = srv->handlesCount++; addentry: srv->handles[r].watch = nextWatch; srv->handles[r].handleCB = handleCB; srv->handles[r].removeCB = removeCB; srv->handles[r].opaque = opaque; srv->handles[r].deleted = VIR_NETLINK_HANDLE_VALID; if (macaddr) virMacAddrSet(&srv->handles[r].macaddr, macaddr); else virMacAddrSetRaw(&srv->handles[r].macaddr, (unsigned char[VIR_MAC_BUFLEN]){0,0,0,0,0,0});
int virDomainCapsCPUModelsAddSteal(virDomainCapsCPUModelsPtr cpuModels, char **name, virDomainCapsCPUUsable usable) { if (VIR_RESIZE_N(cpuModels->models, cpuModels->nmodels_max, cpuModels->nmodels, 1) < 0) return -1; cpuModels->models[cpuModels->nmodels].usable = usable; VIR_STEAL_PTR(cpuModels->models[cpuModels->nmodels].name, *name); cpuModels->nmodels++; return 0; }
/** * virCapabilitiesAddHostFeature: * @caps: capabilities to extend * @name: name of new feature * * Registers a new host CPU feature, eg 'pae', or 'vmx' */ int virCapabilitiesAddHostFeature(virCapsPtr caps, const char *name) { if (VIR_RESIZE_N(caps->host.features, caps->host.nfeatures_max, caps->host.nfeatures, 1) < 0) return -1; if (VIR_STRDUP(caps->host.features[caps->host.nfeatures], name) < 0) return -1; caps->host.nfeatures++; return 0; }
/** * virCapabilitiesAddHostFeature: * @caps: capabilities to extend * @name: name of new feature * * Registers a new host CPU feature, eg 'pae', or 'vmx' */ int virCapabilitiesAddHostFeature(virCapsPtr caps, const char *name) { if (VIR_RESIZE_N(caps->host.features, caps->host.nfeatures_max, caps->host.nfeatures, 1) < 0) return -1; if ((caps->host.features[caps->host.nfeatures] = strdup(name)) == NULL) return -1; caps->host.nfeatures++; return 0; }
/** * virCapabilitiesAddHostMigrateTransport: * @caps: capabilities to extend * @name: name of migration transport * * Registers a new domain migration transport URI */ int virCapabilitiesAddHostMigrateTransport(virCapsPtr caps, const char *name) { if (VIR_RESIZE_N(caps->host.migrateTrans, caps->host.nmigrateTrans_max, caps->host.nmigrateTrans, 1) < 0) return -1; if ((caps->host.migrateTrans[caps->host.nmigrateTrans] = strdup(name)) == NULL) return -1; caps->host.nmigrateTrans++; return 0; }
/** * virBitmapExpand: * @map: Pointer to bitmap * @b: bit position to include in bitmap * * Resizes the bitmap so that bit @b will fit into it. This shall be called only * if @b would not fit into the map. * * Returns 0 on success, -1 on error. */ static int virBitmapExpand(virBitmapPtr map, size_t b) { size_t new_len = VIR_DIV_UP(b, VIR_BITMAP_BITS_PER_UNIT); /* resize the memory if necessary */ if (map->map_len < new_len) { if (VIR_RESIZE_N(map->map, map->map_alloc, map->map_len, new_len - map->map_len) < 0) return -1; } map->max_bit = b + 1; map->map_len = new_len; return 0; }
/** * virCapabilitiesAddGuest: * @caps: capabilities to extend * @ostype: guest operating system type ('hvm' or 'xen') * @arch: guest CPU architecture ('i686', or 'x86_64', etc) * @wordsize: number of bits in CPU word * @emulator: path to default device emulator for arch/ostype * @loader: path to default BIOS loader for arch/ostype * @nmachines: number of machine variants for emulator * @machines: machine variants for emulator ('pc', or 'isapc', etc) * * Registers a new guest operating system. This should be * followed by registration of at least one domain for * running the guest */ virCapsGuestPtr virCapabilitiesAddGuest(virCapsPtr caps, const char *ostype, const char *arch, int wordsize, const char *emulator, const char *loader, int nmachines, virCapsGuestMachinePtr *machines) { virCapsGuestPtr guest; if (VIR_ALLOC(guest) < 0) goto no_memory; if ((guest->ostype = strdup(ostype)) == NULL) goto no_memory; if ((guest->arch.name = strdup(arch)) == NULL) goto no_memory; guest->arch.wordsize = wordsize; if (emulator && (guest->arch.defaultInfo.emulator = strdup(emulator)) == NULL) goto no_memory; if (loader && (guest->arch.defaultInfo.loader = strdup(loader)) == NULL) goto no_memory; if (VIR_RESIZE_N(caps->guests, caps->nguests_max, caps->nguests, 1) < 0) goto no_memory; caps->guests[caps->nguests++] = guest; if (nmachines) { guest->arch.defaultInfo.nmachines = nmachines; guest->arch.defaultInfo.machines = machines; } return guest; no_memory: virCapabilitiesFreeGuest(guest); return NULL; }
/* * Convert a buffer containing preformatted name=value into an * environment variable of the child. * Correctly transfers memory errors or contents from buf to cmd. */ void virCommandAddEnvBuffer(virCommandPtr cmd, virBufferPtr buf) { if (!cmd || cmd->has_error) { virBufferFreeAndReset(buf); return; } /* env plus trailing NULL. */ if (virBufferError(buf) || VIR_RESIZE_N(cmd->env, cmd->maxenv, cmd->nenv, 1 + 1) < 0) { cmd->has_error = ENOMEM; virBufferFreeAndReset(buf); return; } cmd->env[cmd->nenv++] = virBufferContentAndReset(buf); }
/* * Convert a buffer into a command line argument to the child. * Correctly transfers memory errors or contents from buf to cmd. */ void virCommandAddArgBuffer(virCommandPtr cmd, virBufferPtr buf) { if (!cmd || cmd->has_error) { virBufferFreeAndReset(buf); return; } /* Arg plus trailing NULL. */ if (virBufferError(buf) || VIR_RESIZE_N(cmd->args, cmd->maxargs, cmd->nargs, 1 + 1) < 0) { cmd->has_error = ENOMEM; virBufferFreeAndReset(buf); return; } cmd->args[cmd->nargs++] = virBufferContentAndReset(buf); }
/* * Register a callback for a timer event * NB, it *must* be safe to call this from within a callback * For this reason we only ever append to existing list. */ int virEventPollAddTimeout(int frequency, virEventTimeoutCallback cb, void *opaque, virFreeCallback ff) { unsigned long long now; int ret; if (virTimeMillisNow(&now) < 0) { return -1; } virMutexLock(&eventLoop.lock); if (eventLoop.timeoutsCount == eventLoop.timeoutsAlloc) { EVENT_DEBUG("Used %zu timeout slots, adding at least %d more", eventLoop.timeoutsAlloc, EVENT_ALLOC_EXTENT); if (VIR_RESIZE_N(eventLoop.timeouts, eventLoop.timeoutsAlloc, eventLoop.timeoutsCount, EVENT_ALLOC_EXTENT) < 0) { virMutexUnlock(&eventLoop.lock); return -1; } } eventLoop.timeouts[eventLoop.timeoutsCount].timer = nextTimer++; eventLoop.timeouts[eventLoop.timeoutsCount].frequency = frequency; eventLoop.timeouts[eventLoop.timeoutsCount].cb = cb; eventLoop.timeouts[eventLoop.timeoutsCount].ff = ff; eventLoop.timeouts[eventLoop.timeoutsCount].opaque = opaque; eventLoop.timeouts[eventLoop.timeoutsCount].deleted = 0; eventLoop.timeouts[eventLoop.timeoutsCount].expiresAt = frequency >= 0 ? frequency + now : 0; eventLoop.timeoutsCount++; ret = nextTimer-1; virEventPollInterruptLocked(); PROBE(EVENT_POLL_ADD_TIMEOUT, "timer=%d frequency=%d cb=%p opaque=%p ff=%p", ret, frequency, cb, opaque, ff); virMutexUnlock(&eventLoop.lock); return ret; }
/* * Set LC_ALL to C, and propagate other essential environment * variables from the parent process. */ void virCommandAddEnvPassCommon(virCommandPtr cmd) { if (!cmd || cmd->has_error) return; /* Attempt to Pre-allocate; allocation failure will be detected * later during virCommandAdd*. */ ignore_value(VIR_RESIZE_N(cmd->env, cmd->maxenv, cmd->nenv, 9)); virCommandAddEnvPair(cmd, "LC_ALL", "C"); virCommandAddEnvPass(cmd, "LD_PRELOAD"); virCommandAddEnvPass(cmd, "LD_LIBRARY_PATH"); virCommandAddEnvPass(cmd, "PATH"); virCommandAddEnvPass(cmd, "HOME"); virCommandAddEnvPass(cmd, "USER"); virCommandAddEnvPass(cmd, "LOGNAME"); virCommandAddEnvPass(cmd, "TMPDIR"); }
/** * virCapabilitiesAddGuestDomain: * @guest: guest to support * @hvtype: hypervisor type ('xen', 'qemu', 'kvm') * @emulator: specialized device emulator for domain * @loader: specialized BIOS loader for domain * @nmachines: number of machine variants for emulator * @machines: specialized machine variants for emulator * * Registers a virtual domain capable of running a * guest operating system */ virCapsGuestDomainPtr virCapabilitiesAddGuestDomain(virCapsGuestPtr guest, const char *hvtype, const char *emulator, const char *loader, int nmachines, virCapsGuestMachinePtr *machines) { virCapsGuestDomainPtr dom; if (VIR_ALLOC(dom) < 0) goto no_memory; if ((dom->type = strdup(hvtype)) == NULL) goto no_memory; if (emulator && (dom->info.emulator = strdup(emulator)) == NULL) goto no_memory; if (loader && (dom->info.loader = strdup(loader)) == NULL) goto no_memory; if (VIR_RESIZE_N(guest->arch.domains, guest->arch.ndomains_max, guest->arch.ndomains, 1) < 0) goto no_memory; guest->arch.domains[guest->arch.ndomains] = dom; guest->arch.ndomains++; if (nmachines) { dom->info.nmachines = nmachines; dom->info.machines = machines; } return dom; no_memory: virCapabilitiesFreeGuestDomain(dom); return NULL; }
/** * virCapabilitiesAddGuest: * @caps: capabilities to extend * @ostype: guest operating system type ('hvm' or 'xen') * @arch: guest CPU architecture * @wordsize: number of bits in CPU word * @emulator: path to default device emulator for arch/ostype * @loader: path to default BIOS loader for arch/ostype * @nmachines: number of machine variants for emulator * @machines: machine variants for emulator ('pc', or 'isapc', etc) * * Registers a new guest operating system. This should be * followed by registration of at least one domain for * running the guest */ virCapsGuestPtr virCapabilitiesAddGuest(virCapsPtr caps, const char *ostype, virArch arch, const char *emulator, const char *loader, int nmachines, virCapsGuestMachinePtr *machines) { virCapsGuestPtr guest; if (VIR_ALLOC(guest) < 0) goto error; if (VIR_STRDUP(guest->ostype, ostype) < 0) goto error; guest->arch.id = arch; guest->arch.wordsize = virArchGetWordSize(arch); if (VIR_STRDUP(guest->arch.defaultInfo.emulator, emulator) < 0 || VIR_STRDUP(guest->arch.defaultInfo.loader, loader) < 0) goto error; if (VIR_RESIZE_N(caps->guests, caps->nguests_max, caps->nguests, 1) < 0) goto error; caps->guests[caps->nguests++] = guest; if (nmachines) { guest->arch.defaultInfo.nmachines = nmachines; guest->arch.defaultInfo.machines = machines; } return guest; error: virCapabilitiesFreeGuest(guest); return NULL; }
/* * Add an environment variable to the child * using separate name & value strings */ void virCommandAddEnvPair(virCommandPtr cmd, const char *name, const char *value) { char *env; if (!cmd || cmd->has_error) return; if (virAsprintf(&env, "%s=%s", name, value ? value : "") < 0) { cmd->has_error = ENOMEM; return; } /* env plus trailing NULL */ if (VIR_RESIZE_N(cmd->env, cmd->maxenv, cmd->nenv, 1 + 1) < 0) { VIR_FREE(env); cmd->has_error = ENOMEM; return; } cmd->env[cmd->nenv++] = env; }
/* * Add a command line argument to the child */ void virCommandAddArg(virCommandPtr cmd, const char *val) { char *arg; if (!cmd || cmd->has_error) return; if (!(arg = strdup(val))) { cmd->has_error = ENOMEM; return; } /* Arg plus trailing NULL. */ if (VIR_RESIZE_N(cmd->args, cmd->maxargs, cmd->nargs, 1 + 1) < 0) { VIR_FREE(arg); cmd->has_error = ENOMEM; return; } cmd->args[cmd->nargs++] = arg; }
/* * Add an environment variable to the child * using a preformatted env string FOO=BAR */ void virCommandAddEnvString(virCommandPtr cmd, const char *str) { char *env; if (!cmd || cmd->has_error) return; if (!(env = strdup(str))) { cmd->has_error = ENOMEM; return; } /* env plus trailing NULL */ if (VIR_RESIZE_N(cmd->env, cmd->maxenv, cmd->nenv, 1 + 1) < 0) { VIR_FREE(env); cmd->has_error = ENOMEM; return; } cmd->env[cmd->nenv++] = env; }