int libxlDriverNodeGetInfo(libxlDriverPrivatePtr driver, virNodeInfoPtr info) { libxl_physinfo phy_info; virArch hostarch = virArchFromHost(); libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver); int ret = -1; if (libxl_get_physinfo(cfg->ctx, &phy_info)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("libxl_get_physinfo_info failed")); goto cleanup; } if (virStrcpyStatic(info->model, virArchToString(hostarch)) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("machine type %s too big for destination"), virArchToString(hostarch)); goto cleanup; } info->memory = phy_info.total_pages * (cfg->verInfo->pagesize / 1024); info->cpus = phy_info.nr_cpus; info->nodes = phy_info.nr_nodes; info->cores = phy_info.cores_per_socket; info->threads = phy_info.threads_per_core; info->sockets = 1; info->mhz = phy_info.cpu_khz / 1000; ret = 0; cleanup: virObjectUnref(cfg); return ret; }
int nodeGetInfo(virConnectPtr conn ATTRIBUTE_UNUSED, virNodeInfoPtr nodeinfo) { virArch hostarch = virArchFromHost(); if (virStrcpyStatic(nodeinfo->model, virArchToString(hostarch)) == NULL) return -1; #ifdef __linux__ { int ret = -1; FILE *cpuinfo = fopen(CPUINFO_PATH, "r"); if (!cpuinfo) { virReportSystemError(errno, _("cannot open %s"), CPUINFO_PATH); return -1; } ret = linuxNodeInfoCPUPopulate(cpuinfo, SYSFS_SYSTEM_PATH, nodeinfo); if (ret < 0) goto cleanup; /* Convert to KB. */ nodeinfo->memory = physmem_total() / 1024; cleanup: VIR_FORCE_FCLOSE(cpuinfo); return ret; } #else /* XXX Solaris will need an impl later if they port QEMU driver */ virReportError(VIR_ERR_NO_SUPPORT, "%s", _("node info not implemented on this platform")); return -1; #endif }
int virTypedParamsCopy(virTypedParameterPtr *dst, virTypedParameterPtr src, int nparams) { size_t i; *dst = NULL; if (!src || nparams <= 0) return 0; if (VIR_ALLOC_N(*dst, nparams) < 0) return -1; for (i = 0; i < nparams; i++) { ignore_value(virStrcpyStatic((*dst)[i].field, src[i].field)); (*dst)[i].type = src[i].type; if (src[i].type == VIR_TYPED_PARAM_STRING) { if (VIR_STRDUP((*dst)[i].value.s, src[i].value.s) < 0) { virTypedParamsFree(*dst, i - 1); *dst = NULL; return -1; } } else { (*dst)[i].value = src[i].value; } } return 0; }
static int virNetDevBridgeCmd(const char *brname, u_long op, void *arg, size_t argsize) { int s; int ret = -1; struct ifdrv ifd; memset(&ifd, 0, sizeof(ifd)); if ((s = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0) { virReportSystemError(errno, "%s", _("Cannot open network interface control socket")); return -1; } if (virStrcpyStatic(ifd.ifd_name, brname) == NULL) { virReportSystemError(ERANGE, _("Network interface name '%s' is too long"), brname); goto cleanup; } ifd.ifd_cmd = op; ifd.ifd_len = argsize; ifd.ifd_data = arg; ret = ioctl(s, SIOCSDRVSPEC, &ifd); cleanup: VIR_FORCE_CLOSE(s); return ret; }
static int virNetDevSetupControlFull(const char *ifname, struct ifreq *ifr, int domain, int type) { int fd; memset(ifr, 0, sizeof(*ifr)); if (virStrcpyStatic(ifr->ifr_name, ifname) == NULL) { virReportSystemError(ERANGE, _("Network interface name '%s' is too long"), ifname); return -1; } if ((fd = socket(domain, type, 0)) < 0) { virReportSystemError(errno, "%s", _("Cannot open network interface control socket")); return -1; } if (virSetInherit(fd, false) < 0) { virReportSystemError(errno, "%s", _("Cannot set close-on-exec flag for socket")); VIR_FORCE_CLOSE(fd); return -1; } return fd; }
int nodeGetInfo(virConnectPtr conn ATTRIBUTE_UNUSED, virNodeInfoPtr nodeinfo) { struct utsname info; memset(nodeinfo, 0, sizeof(*nodeinfo)); uname(&info); if (virStrcpyStatic(nodeinfo->model, info.machine) == NULL) return -1; #ifdef __linux__ { int ret; FILE *cpuinfo = fopen(CPUINFO_PATH, "r"); if (!cpuinfo) { virReportSystemError(errno, _("cannot open %s"), CPUINFO_PATH); return -1; } ret = linuxNodeInfoCPUPopulate(cpuinfo, nodeinfo); fclose(cpuinfo); if (ret < 0) return -1; /* Convert to KB. */ nodeinfo->memory = physmem_total () / 1024; return ret; } #else /* XXX Solaris will need an impl later if they port QEMU driver */ nodeReportError(VIR_ERR_NO_SUPPORT, "%s", _("node info not implemented on this platform")); return -1; #endif }
/** * virGetStorageVol: * @conn: the hypervisor connection * @pool: pool owning the volume * @name: pointer to the storage vol name * @key: pointer to unique key of the volume * * Lookup if the storage vol is already registered for that connection, * if yes return a new pointer to it, if no allocate a new structure, * and register it in the table. In any case a corresponding call to * virUnrefStorageVol() is needed to not leak data. * * Returns a pointer to the storage vol, or NULL in case of failure */ virStorageVolPtr virGetStorageVol(virConnectPtr conn, const char *pool, const char *name, const char *key) { virStorageVolPtr ret = NULL; if (!VIR_IS_CONNECT(conn)) { virLibConnError(VIR_ERR_INVALID_ARG, _("no connection")); return NULL; } if (name == NULL) { virLibConnError(VIR_ERR_INVALID_ARG, _("missing name")); return NULL; } if (key == NULL) { virLibConnError(VIR_ERR_INVALID_ARG, _("missing key")); return NULL; } virMutexLock(&conn->lock); if (VIR_ALLOC(ret) < 0) { virMutexUnlock(&conn->lock); virReportOOMError(); goto error; } ret->pool = strdup(pool); if (ret->pool == NULL) { virMutexUnlock(&conn->lock); virReportOOMError(); goto error; } ret->name = strdup(name); if (ret->name == NULL) { virMutexUnlock(&conn->lock); virReportOOMError(); goto error; } if (virStrcpyStatic(ret->key, key) == NULL) { virMutexUnlock(&conn->lock); virLibConnError(VIR_ERR_INTERNAL_ERROR, _("Volume key %s too large for destination"), key); goto error; } ret->magic = VIR_STORAGE_VOL_MAGIC; ret->conn = conn; conn->refs++; ret->refs++; virMutexUnlock(&conn->lock); return(ret); error: if (ret != NULL) { VIR_FREE(ret->name); VIR_FREE(ret->pool); VIR_FREE(ret); } return(NULL); }
/* Assign name, type, and the appropriately typed arg to param; in the * case of a string, the caller is assumed to have malloc'd a string, * or can pass NULL to have this function malloc an empty string. * Return 0 on success, -1 after an error message on failure. */ int virTypedParameterAssign(virTypedParameterPtr param, const char *name, int type, ...) { va_list ap; int ret = -1; va_start(ap, type); if (virStrcpyStatic(param->field, name) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Field name '%s' too long"), name); goto cleanup; } param->type = type; switch (type) { case VIR_TYPED_PARAM_INT: param->value.i = va_arg(ap, int); break; case VIR_TYPED_PARAM_UINT: param->value.ui = va_arg(ap, unsigned int); break; case VIR_TYPED_PARAM_LLONG: param->value.l = va_arg(ap, long long int); break; case VIR_TYPED_PARAM_ULLONG: param->value.ul = va_arg(ap, unsigned long long int); break; case VIR_TYPED_PARAM_DOUBLE: param->value.d = va_arg(ap, double); break; case VIR_TYPED_PARAM_BOOLEAN: param->value.b = !!va_arg(ap, int); break; case VIR_TYPED_PARAM_STRING: param->value.s = va_arg(ap, char *); if (!param->value.s && VIR_STRDUP(param->value.s, "") < 0) goto cleanup; break; default: virReportError(VIR_ERR_INTERNAL_ERROR, _("unexpected type %d for field %s"), type, name); goto cleanup; } ret = 0; cleanup: va_end(ap); return ret; }
static int virHostCPUStatsAssign(virNodeCPUStatsPtr param, const char *name, unsigned long long value) { if (virStrcpyStatic(param->field, name) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("kernel cpu time field is too long" " for the destination")); return -1; } param->value = value; return 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; }
static int lxcMonitorServer(const char *sockpath) { int fd; struct sockaddr_un addr; if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { virReportSystemError(errno, _("failed to create server socket '%s'"), sockpath); goto error; } unlink(sockpath); memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; if (virStrcpyStatic(addr.sun_path, sockpath) == NULL) { lxcError(VIR_ERR_INTERNAL_ERROR, _("Socket path %s too long for destination"), sockpath); goto error; } if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { virReportSystemError(errno, _("failed to bind server socket '%s'"), sockpath); goto error; } if (listen(fd, 30 /* backlog */ ) < 0) { virReportSystemError(errno, _("failed to listen server socket %s"), sockpath); goto error; } return fd; error: VIR_FORCE_CLOSE(fd); return -1; }
static int virHostMemGetStatsFreeBSD(virNodeMemoryStatsPtr params, int *nparams) { size_t i, j = 0; unsigned long pagesize = getpagesize() >> 10; long bufpages; size_t bufpages_size = sizeof(bufpages); struct field_sysctl_map { const char *field; const char *sysctl_name; } sysctl_map[] = { {VIR_NODE_MEMORY_STATS_TOTAL, "vm.stats.vm.v_page_count"}, {VIR_NODE_MEMORY_STATS_FREE, "vm.stats.vm.v_free_count"}, {VIR_NODE_MEMORY_STATS_CACHED, "vm.stats.vm.v_cache_count"}, {NULL, NULL} }; if ((*nparams) == 0) { *nparams = BSD_MEMORY_STATS_ALL; return 0; } if ((*nparams) != BSD_MEMORY_STATS_ALL) { virReportInvalidArg(nparams, _("nparams in %s must be %d"), __FUNCTION__, BSD_MEMORY_STATS_ALL); return -1; } for (i = 0; sysctl_map[i].field != NULL; i++) { u_int value; size_t value_size = sizeof(value); virNodeMemoryStatsPtr param; if (sysctlbyname(sysctl_map[i].sysctl_name, &value, &value_size, NULL, 0) < 0) { virReportSystemError(errno, _("sysctl failed for '%s'"), sysctl_map[i].sysctl_name); return -1; } param = ¶ms[j++]; if (virStrcpyStatic(param->field, sysctl_map[i].field) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Field '%s' too long for destination"), sysctl_map[i].field); return -1; } param->value = (unsigned long long)value * pagesize; } { virNodeMemoryStatsPtr param = ¶ms[j++]; if (sysctlbyname("vfs.bufspace", &bufpages, &bufpages_size, NULL, 0) < 0) { virReportSystemError(errno, _("sysctl failed for '%s'"), "vfs.bufspace"); return -1; } if (virStrcpyStatic(param->field, VIR_NODE_MEMORY_STATS_BUFFERS) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Field '%s' too long for destination"), VIR_NODE_MEMORY_STATS_BUFFERS); return -1; } param->value = (unsigned long long)bufpages >> 10; } return 0; }
static int virHostMemGetStatsLinux(FILE *meminfo, int cellNum, virNodeMemoryStatsPtr params, int *nparams) { int ret = -1; size_t i = 0, j = 0, k = 0; int found = 0; int nr_param; char line[1024]; char meminfo_hdr[VIR_NODE_MEMORY_STATS_FIELD_LENGTH]; unsigned long val; struct field_conv { const char *meminfo_hdr; /* meminfo header */ const char *field; /* MemoryStats field name */ } field_conv[] = { {"MemTotal:", VIR_NODE_MEMORY_STATS_TOTAL}, {"MemFree:", VIR_NODE_MEMORY_STATS_FREE}, {"Buffers:", VIR_NODE_MEMORY_STATS_BUFFERS}, {"Cached:", VIR_NODE_MEMORY_STATS_CACHED}, {NULL, NULL} }; if (cellNum == VIR_NODE_MEMORY_STATS_ALL_CELLS) { nr_param = LINUX_NB_MEMORY_STATS_ALL; } else { nr_param = LINUX_NB_MEMORY_STATS_CELL; } if ((*nparams) == 0) { /* Current number of memory stats supported by linux */ *nparams = nr_param; ret = 0; goto cleanup; } if ((*nparams) != nr_param) { virReportInvalidArg(nparams, _("nparams in %s must be %d"), __FUNCTION__, nr_param); goto cleanup; } while (fgets(line, sizeof(line), meminfo) != NULL) { char *buf = line; if (STRPREFIX(buf, "Node ")) { /* * /sys/devices/system/node/nodeX/meminfo format is below. * So, skip prefix "Node XX ". * * Node 0 MemTotal: 8386980 kB * Node 0 MemFree: 5300920 kB * : */ char *p; p = buf; for (i = 0; i < 2; i++) { p = strchr(p, ' '); if (p == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no prefix found")); goto cleanup; } p++; } buf = p; } if (sscanf(buf, "%s %lu kB", meminfo_hdr, &val) < 2) continue; for (j = 0; field_conv[j].meminfo_hdr != NULL; j++) { struct field_conv *convp = &field_conv[j]; if (STREQ(meminfo_hdr, convp->meminfo_hdr)) { virNodeMemoryStatsPtr param = ¶ms[k++]; if (virStrcpyStatic(param->field, convp->field) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Field kernel memory too long for destination")); goto cleanup; } param->value = val; found++; break; } } if (found >= nr_param) break; } if (found == 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no available memory line found")); goto cleanup; } ret = 0; cleanup: return ret; }
/* Validate that PARAMS contains only recognized parameter names with * correct types, and with no duplicates except for parameters * specified with VIR_TYPED_PARAM_MULTIPLE flag in type. * Pass in as many name/type pairs as appropriate, and pass NULL to end * the list of accepted parameters. Return 0 on success, -1 on failure * with error message already issued. */ int virTypedParamsValidate(virTypedParameterPtr params, int nparams, ...) { va_list ap; int ret = -1; size_t i, j; const char *name; int type; size_t nkeys = 0, nkeysalloc = 0; virTypedParameterPtr sorted = NULL, keys = NULL; va_start(ap, nparams); if (VIR_ALLOC_N(sorted, nparams) < 0) goto cleanup; /* Here we intentionally don't copy values */ memcpy(sorted, params, sizeof(*params) * nparams); qsort(sorted, nparams, sizeof(*sorted), virTypedParamsSortName); name = va_arg(ap, const char *); while (name) { type = va_arg(ap, int); if (VIR_RESIZE_N(keys, nkeysalloc, nkeys, 1) < 0) goto cleanup; if (virStrcpyStatic(keys[nkeys].field, name) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Field name '%s' too long"), name); goto cleanup; } keys[nkeys].type = type & ~VIR_TYPED_PARAM_MULTIPLE; /* Value is not used anyway */ keys[nkeys].value.i = type & VIR_TYPED_PARAM_MULTIPLE; nkeys++; name = va_arg(ap, const char *); } qsort(keys, nkeys, sizeof(*keys), virTypedParamsSortName); for (i = 0, j = 0; i < nparams && j < nkeys;) { if (STRNEQ(sorted[i].field, keys[j].field)) { j++; } else { if (i > j && !(keys[j].value.i & VIR_TYPED_PARAM_MULTIPLE)) { virReportError(VIR_ERR_INVALID_ARG, _("parameter '%s' occurs multiple times"), sorted[i].field); goto cleanup; } if (sorted[i].type != keys[j].type) { const char *badtype; badtype = virTypedParameterTypeToString(sorted[i].type); if (!badtype) badtype = virTypedParameterTypeToString(0); virReportError(VIR_ERR_INVALID_ARG, _("invalid type '%s' for parameter '%s', " "expected '%s'"), badtype, sorted[i].field, virTypedParameterTypeToString(keys[j].type)); goto cleanup; } i++; } } if (j == nkeys && i != nparams) { virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, _("parameter '%s' not supported"), sorted[i].field); goto cleanup; } ret = 0; cleanup: va_end(ap); VIR_FREE(sorted); VIR_FREE(keys); return ret; }
virNetDevVPortProfilePtr virNetDevVPortProfileParse(xmlNodePtr node, unsigned int flags) { char *virtPortType; char *virtPortManagerID = NULL; char *virtPortTypeID = NULL; char *virtPortTypeIDVersion = NULL; char *virtPortInstanceID = NULL; char *virtPortProfileID = NULL; char *virtPortInterfaceID = NULL; virNetDevVPortProfilePtr virtPort = NULL; xmlNodePtr cur = node->children; if (VIR_ALLOC(virtPort) < 0) return NULL; if ((virtPortType = virXMLPropString(node, "type")) && (virtPort->virtPortType = virNetDevVPortTypeFromString(virtPortType)) <= 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("unknown virtualport type %s"), virtPortType); goto error; } if ((virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_NONE) && (flags & VIR_VPORT_XML_REQUIRE_TYPE)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("missing required virtualport type")); goto error; } while (cur != NULL) { if (xmlStrEqual(cur->name, BAD_CAST "parameters")) { virtPortManagerID = virXMLPropString(cur, "managerid"); virtPortTypeID = virXMLPropString(cur, "typeid"); virtPortTypeIDVersion = virXMLPropString(cur, "typeidversion"); virtPortInstanceID = virXMLPropString(cur, "instanceid"); virtPortProfileID = virXMLPropString(cur, "profileid"); virtPortInterfaceID = virXMLPropString(cur, "interfaceid"); break; } cur = cur->next; } if (virtPortManagerID) { unsigned int val; if (virStrToLong_ui(virtPortManagerID, NULL, 0, &val)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("cannot parse value of managerid parameter")); goto error; } if (val > 0xff) { virReportError(VIR_ERR_XML_ERROR, "%s", _("value of managerid out of range")); goto error; } virtPort->managerID = (uint8_t)val; virtPort->managerID_specified = true; } if (virtPortTypeID) { unsigned int val; if (virStrToLong_ui(virtPortTypeID, NULL, 0, &val)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("cannot parse value of typeid parameter")); goto error; } if (val > 0xffffff) { virReportError(VIR_ERR_XML_ERROR, "%s", _("value for typeid out of range")); goto error; } virtPort->typeID = (uint32_t)val; virtPort->typeID_specified = true; } if (virtPortTypeIDVersion) { unsigned int val; if (virStrToLong_ui(virtPortTypeIDVersion, NULL, 0, &val)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("cannot parse value of typeidversion parameter")); goto error; } if (val > 0xff) { virReportError(VIR_ERR_XML_ERROR, "%s", _("value of typeidversion out of range")); goto error; } virtPort->typeIDVersion = (uint8_t)val; virtPort->typeIDVersion_specified = true; } if (virtPortInstanceID) { if (virUUIDParse(virtPortInstanceID, virtPort->instanceID) < 0) { virReportError(VIR_ERR_XML_ERROR, "%s", _("cannot parse instanceid parameter as a uuid")); goto error; } virtPort->instanceID_specified = true; } if (virtPortProfileID && !virStrcpyStatic(virtPort->profileID, virtPortProfileID)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("profileid parameter too long")); goto error; } if (virtPortInterfaceID) { if (virUUIDParse(virtPortInterfaceID, virtPort->interfaceID) < 0) { virReportError(VIR_ERR_XML_ERROR, "%s", _("cannot parse interfaceid parameter as a uuid")); goto error; } virtPort->interfaceID_specified = true; } /* generate default instanceID/interfaceID if appropriate */ if (flags & VIR_VPORT_XML_GENERATE_MISSING_DEFAULTS) { if (!virtPort->instanceID_specified && (virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_8021QBG || virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_NONE)) { if (virUUIDGenerate(virtPort->instanceID) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot generate a random uuid for instanceid")); goto error; } virtPort->instanceID_specified = true; } if (!virtPort->interfaceID_specified && (virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH || virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_NONE)) { if (virUUIDGenerate(virtPort->interfaceID) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot generate a random uuid for interfaceid")); goto error; } virtPort->interfaceID_specified = true; } } /* check for required/unsupported attributes */ if ((flags & VIR_VPORT_XML_REQUIRE_ALL_ATTRIBUTES) && (virNetDevVPortProfileCheckComplete(virtPort, false) < 0)) { goto error; } if (virNetDevVPortProfileCheckNoExtras(virtPort) < 0) goto error; cleanup: VIR_FREE(virtPortManagerID); VIR_FREE(virtPortTypeID); VIR_FREE(virtPortTypeIDVersion); VIR_FREE(virtPortInstanceID); VIR_FREE(virtPortProfileID); VIR_FREE(virtPortType); VIR_FREE(virtPortInterfaceID); return virtPort; error: VIR_FREE(virtPort); goto cleanup; }
int linuxNodeGetCPUStats(FILE *procstat, int cpuNum, virNodeCPUStatsPtr params, int *nparams) { int ret = -1; char line[1024]; unsigned long long usr, ni, sys, idle, iowait; unsigned long long irq, softirq, steal, guest, guest_nice; char cpu_header[3 + INT_BUFSIZE_BOUND(cpuNum)]; if ((*nparams) == 0) { /* Current number of cpu stats supported by linux */ *nparams = LINUX_NB_CPU_STATS; ret = 0; goto cleanup; } if ((*nparams) != LINUX_NB_CPU_STATS) { nodeReportError(VIR_ERR_INVALID_ARG, "%s", _("Invalid parameter count")); goto cleanup; } if (cpuNum == VIR_NODE_CPU_STATS_ALL_CPUS) { strcpy(cpu_header, "cpu"); } else { snprintf(cpu_header, sizeof(cpu_header), "cpu%d", cpuNum); } while (fgets(line, sizeof(line), procstat) != NULL) { char *buf = line; if (STRPREFIX(buf, cpu_header)) { /* aka logical CPU time */ int i; if (sscanf(buf, "%*s %llu %llu %llu %llu %llu" // user ~ iowait "%llu %llu %llu %llu %llu", // irq ~ guest_nice &usr, &ni, &sys, &idle, &iowait, &irq, &softirq, &steal, &guest, &guest_nice) < 4) { continue; } for (i = 0; i < *nparams; i++) { virNodeCPUStatsPtr param = ¶ms[i]; switch (i) { case 0: /* fill kernel cpu time here */ if (virStrcpyStatic(param->field, VIR_NODE_CPU_STATS_KERNEL) == NULL) { nodeReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Field kernel cpu time too long for destination")); goto cleanup; } param->value = (sys + irq + softirq) * TICK_TO_NSEC; break; case 1: /* fill user cpu time here */ if (virStrcpyStatic(param->field, VIR_NODE_CPU_STATS_USER) == NULL) { nodeReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Field kernel cpu time too long for destination")); goto cleanup; } param->value = (usr + ni) * TICK_TO_NSEC; break; case 2: /* fill idle cpu time here */ if (virStrcpyStatic(param->field, VIR_NODE_CPU_STATS_IDLE) == NULL) { nodeReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Field kernel cpu time too long for destination")); goto cleanup; } param->value = idle * TICK_TO_NSEC; break; case 3: /* fill iowait cpu time here */ if (virStrcpyStatic(param->field, VIR_NODE_CPU_STATS_IOWAIT) == NULL) { nodeReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Field kernel cpu time too long for destination")); goto cleanup; } param->value = iowait * TICK_TO_NSEC; break; default: break; /* should not hit here */ } } ret = 0; goto cleanup; } } nodeReportError(VIR_ERR_INVALID_ARG, "%s", _("Invalid cpu number")); cleanup: return ret; }
int linuxNodeInfoCPUPopulate(FILE *cpuinfo, const char *sysfs_cpudir, virNodeInfoPtr nodeinfo) { char line[1024]; DIR *cpudir = NULL; struct dirent *cpudirent = NULL; unsigned int cpu; unsigned long core, sock, cur_threads; cpu_set_t core_mask; cpu_set_t socket_mask; int online; nodeinfo->cpus = 0; nodeinfo->mhz = 0; nodeinfo->cores = 0; nodeinfo->nodes = 1; # if HAVE_NUMACTL if (numa_available() >= 0) nodeinfo->nodes = numa_max_node() + 1; # endif if (!virStrcpyStatic(sysfs_path, sysfs_cpudir)) { virReportSystemError(errno, _("cannot copy %s"), sysfs_cpudir); return -1; } /* NB: It is impossible to fill our nodes, since cpuinfo * has no knowledge of NUMA nodes */ /* NOTE: hyperthreads are ignored here; they are parsed out of /sys */ while (fgets(line, sizeof(line), cpuinfo) != NULL) { # if defined(__x86_64__) || \ defined(__amd64__) || \ defined(__i386__) char *buf = line; if (STRPREFIX(buf, "cpu MHz")) { char *p; unsigned int ui; buf += 9; while (*buf && c_isspace(*buf)) buf++; if (*buf != ':' || !buf[1]) { nodeReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("parsing cpuinfo cpu MHz")); return -1; } if (virStrToLong_ui(buf+1, &p, 10, &ui) == 0 /* Accept trailing fractional part. */ && (*p == '\0' || *p == '.' || c_isspace(*p))) nodeinfo->mhz = ui; } # elif defined(__powerpc__) || \ defined(__powerpc64__) char *buf = line; if (STRPREFIX(buf, "clock")) { char *p; unsigned int ui; buf += 5; while (*buf && c_isspace(*buf)) buf++; if (*buf != ':' || !buf[1]) { nodeReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("parsing cpuinfo cpu MHz")); return -1; } if (virStrToLong_ui(buf+1, &p, 10, &ui) == 0 /* Accept trailing fractional part. */ && (*p == '\0' || *p == '.' || c_isspace(*p))) nodeinfo->mhz = ui; /* No other interesting infos are available in /proc/cpuinfo. * However, there is a line identifying processor's version, * identification and machine, but we don't want it to be caught * and parsed in next iteration, because it is not in expected * format and thus lead to error. */ } # else # warning Parser for /proc/cpuinfo needs to be adapted for your architecture # endif } /* OK, we've parsed clock speed out of /proc/cpuinfo. Get the core, socket * thread and topology information from /sys */ cpudir = opendir(sysfs_cpudir); if (cpudir == NULL) { virReportSystemError(errno, _("cannot opendir %s"), sysfs_cpudir); return -1; } CPU_ZERO(&core_mask); CPU_ZERO(&socket_mask); while ((cpudirent = readdir(cpudir))) { if (sscanf(cpudirent->d_name, "cpu%u", &cpu) != 1) continue; online = cpu_online(cpu); if (online < 0) { closedir(cpudir); return -1; } if (!online) continue; nodeinfo->cpus++; /* Parse core */ core = parse_core(cpu); if (!CPU_ISSET(core, &core_mask)) { CPU_SET(core, &core_mask); nodeinfo->cores++; } /* Parse socket */ sock = parse_socket(cpu); if (!CPU_ISSET(sock, &socket_mask)) { CPU_SET(sock, &socket_mask); nodeinfo->sockets++; } cur_threads = count_thread_siblings(cpu); if (cur_threads == 0) { closedir(cpudir); return -1; } if (cur_threads > nodeinfo->threads) nodeinfo->threads = cur_threads; } if (errno) { virReportSystemError(errno, _("problem reading %s"), sysfs_path); closedir(cpudir); return -1; } closedir(cpudir); /* there should always be at least one cpu, socket and one thread */ if (nodeinfo->cpus == 0) { nodeReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no CPUs found")); return -1; } if (nodeinfo->sockets == 0) { nodeReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no sockets found")); return -1; } if (nodeinfo->threads == 0) { nodeReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no threads found")); return -1; } /* nodeinfo->sockets is supposed to be a number of sockets per NUMA node, * however if NUMA nodes are not composed of whole sockets, we just lie * about the number of NUMA nodes and force apps to check capabilities XML * for the actual NUMA topology. */ if (nodeinfo->sockets % nodeinfo->nodes == 0) nodeinfo->sockets /= nodeinfo->nodes; else nodeinfo->nodes = 1; return 0; }
static int qemuAgentOpenUnix(const char *monitor, pid_t cpid, bool *inProgress) { struct sockaddr_un addr; int monfd; int timeout = 3; /* In seconds */ int ret, i = 0; *inProgress = false; if ((monfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { virReportSystemError(errno, "%s", _("failed to create socket")); return -1; } if (virSetNonBlock(monfd) < 0) { virReportSystemError(errno, "%s", _("Unable to put monitor " "into non-blocking mode")); goto error; } if (virSetCloseExec(monfd) < 0) { virReportSystemError(errno, "%s", _("Unable to set monitor " "close-on-exec flag")); goto error; } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; if (virStrcpyStatic(addr.sun_path, monitor) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Agent path %s too big for destination"), monitor); goto error; } do { ret = connect(monfd, (struct sockaddr *) &addr, sizeof(addr)); if (ret == 0) break; if ((errno == ENOENT || errno == ECONNREFUSED) && virProcessKill(cpid, 0) == 0) { /* ENOENT : Socket may not have shown up yet * ECONNREFUSED : Leftover socket hasn't been removed yet */ continue; } if ((errno == EINPROGRESS) || (errno == EAGAIN)) { VIR_DEBUG("Connection attempt continuing in background"); *inProgress = true; ret = 0; break; } virReportSystemError(errno, "%s", _("failed to connect to monitor socket")); goto error; } while ((++i <= timeout*5) && (usleep(.2 * 1000000) <= 0)); if (ret != 0) { virReportSystemError(errno, "%s", _("monitor socket did not show up.")); goto error; } return monfd; error: VIR_FORCE_CLOSE(monfd); return -1; }
int nodeGetInfo(virNodeInfoPtr nodeinfo) { virArch hostarch = virArchFromHost(); memset(nodeinfo, 0, sizeof(*nodeinfo)); if (virStrcpyStatic(nodeinfo->model, virArchToString(hostarch)) == NULL) return -1; #ifdef __linux__ { int ret = -1; FILE *cpuinfo = fopen(CPUINFO_PATH, "r"); if (!cpuinfo) { virReportSystemError(errno, _("cannot open %s"), CPUINFO_PATH); return -1; } ret = linuxNodeInfoCPUPopulate(cpuinfo, SYSFS_SYSTEM_PATH, nodeinfo); if (ret < 0) goto cleanup; /* Convert to KB. */ nodeinfo->memory = physmem_total() / 1024; cleanup: VIR_FORCE_FCLOSE(cpuinfo); return ret; } #elif defined(__FreeBSD__) { nodeinfo->nodes = 1; nodeinfo->sockets = 1; nodeinfo->threads = 1; nodeinfo->cpus = freebsdNodeGetCPUCount(); if (nodeinfo->cpus == -1) return -1; nodeinfo->cores = nodeinfo->cpus; unsigned long cpu_freq; size_t cpu_freq_len = sizeof(cpu_freq); if (sysctlbyname("dev.cpu.0.freq", &cpu_freq, &cpu_freq_len, NULL, 0) < 0) { virReportSystemError(errno, "%s", _("cannot obtain CPU freq")); return -1; } nodeinfo->mhz = cpu_freq; /* get memory information */ int mib[2] = { CTL_HW, HW_PHYSMEM }; unsigned long physmem; size_t len = sizeof(physmem); if (sysctl(mib, 2, &physmem, &len, NULL, 0) == -1) { virReportSystemError(errno, "%s", _("cannot obtain memory size")); return -1; } nodeinfo->memory = (unsigned long)(physmem / 1024); return 0; } #else /* XXX Solaris will need an impl later if they port QEMU driver */ virReportError(VIR_ERR_NO_SUPPORT, "%s", _("node info not implemented on this platform")); return -1; #endif }
int virNetSocketNewListenUNIX(const char *path, mode_t mask, uid_t user, gid_t grp, virNetSocketPtr *retsock) { virSocketAddr addr; mode_t oldmask; int fd; *retsock = NULL; memset(&addr, 0, sizeof(addr)); addr.len = sizeof(addr.data.un); if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { virReportSystemError(errno, "%s", _("Failed to create socket")); goto error; } addr.data.un.sun_family = AF_UNIX; if (virStrcpyStatic(addr.data.un.sun_path, path) == NULL) { virReportSystemError(ENOMEM, _("Path %s too long for unix socket"), path); goto error; } if (addr.data.un.sun_path[0] == '@') addr.data.un.sun_path[0] = '\0'; else unlink(addr.data.un.sun_path); oldmask = umask(~mask); if (bind(fd, &addr.data.sa, addr.len) < 0) { umask(oldmask); virReportSystemError(errno, _("Failed to bind socket to '%s'"), path); goto error; } umask(oldmask); /* chown() doesn't work for abstract sockets but we use them only * if libvirtd runs unprivileged */ if (grp != 0 && chown(path, user, grp)) { virReportSystemError(errno, _("Failed to change ownership of '%s' to %d:%d"), path, (int) user, (int) grp); goto error; } if (!(*retsock = virNetSocketNew(&addr, NULL, false, fd, -1, 0))) goto error; return 0; error: if (path[0] != '@') unlink(path); VIR_FORCE_CLOSE(fd); return -1; }
/* virNetDevVPortProfileMerge() - merge the attributes in mods into * orig. If anything that is set in mods has already been set in orig * *and doesn't match*, log an error and return -1, otherwise return 0. */ static int virNetDevVPortProfileMerge(virNetDevVPortProfilePtr orig, virNetDevVPortProfilePtr mods) { enum virNetDevVPortProfile otype; if (!orig || !mods) return 0; otype = orig->virtPortType; if (mods->virtPortType != VIR_NETDEV_VPORT_PROFILE_NONE) { if (otype != VIR_NETDEV_VPORT_PROFILE_NONE && otype != mods->virtPortType) { virReportError(VIR_ERR_XML_ERROR, _("attempt to merge virtualports " "with mismatched types (%s and %s)"), virNetDevVPortTypeToString(otype), virNetDevVPortTypeToString(mods->virtPortType)); return -1; } otype = orig->virtPortType = mods->virtPortType; } if (mods->managerID_specified && (otype == VIR_NETDEV_VPORT_PROFILE_8021QBG || otype == VIR_NETDEV_VPORT_PROFILE_NONE)) { if (orig->managerID_specified && (orig->managerID != mods->managerID)) { virReportError(VIR_ERR_XML_ERROR, _("attempt to merge virtualports " "with mismatched managerids (%d and %d)"), orig->managerID, mods->managerID); return -1; } orig->managerID = mods->managerID; orig->managerID_specified = true; } if (mods->typeID_specified && (otype == VIR_NETDEV_VPORT_PROFILE_8021QBG || otype == VIR_NETDEV_VPORT_PROFILE_NONE)) { if (orig->typeID_specified && (orig->typeID != mods->typeID)) { virReportError(VIR_ERR_XML_ERROR, _("attempt to merge virtualports " "with mismatched typeids (%d and %d)"), orig->typeID, mods->typeID); return -1; } orig->typeID = mods->typeID; orig->typeID_specified = true; } if (mods->typeIDVersion_specified && (otype == VIR_NETDEV_VPORT_PROFILE_8021QBG || otype == VIR_NETDEV_VPORT_PROFILE_NONE)) { if (orig->typeIDVersion_specified && (orig->typeIDVersion != mods->typeIDVersion)) { virReportError(VIR_ERR_XML_ERROR, _("attempt to merge virtualports with " "mismatched typeidversions (%d and %d)"), orig->typeIDVersion, mods->typeIDVersion); return -1; } orig->typeIDVersion = mods->typeIDVersion; orig->typeIDVersion_specified = true; } if (mods->instanceID_specified && (otype == VIR_NETDEV_VPORT_PROFILE_8021QBG || otype == VIR_NETDEV_VPORT_PROFILE_NONE)) { if (orig->instanceID_specified && memcmp(orig->instanceID, mods->instanceID, sizeof(orig->instanceID))) { char origuuid[VIR_UUID_STRING_BUFLEN]; char modsuuid[VIR_UUID_STRING_BUFLEN]; virReportError(VIR_ERR_XML_ERROR, _("attempt to merge virtualports with " "mismatched instanceids ('%s' and '%s')"), virUUIDFormat(orig->instanceID, origuuid), virUUIDFormat(mods->instanceID, modsuuid)); return -1; } memcpy(orig->instanceID, mods->instanceID, sizeof(orig->instanceID)); orig->instanceID_specified = true; } if (mods->interfaceID_specified && (otype == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH || otype == VIR_NETDEV_VPORT_PROFILE_NONE)) { if (orig->interfaceID_specified && memcmp(orig->interfaceID, mods->interfaceID, sizeof(orig->interfaceID))) { char origuuid[VIR_UUID_STRING_BUFLEN]; char modsuuid[VIR_UUID_STRING_BUFLEN]; virReportError(VIR_ERR_XML_ERROR, _("attempt to merge virtualports with " "mismatched interfaceids ('%s' and '%s')"), virUUIDFormat(orig->interfaceID, origuuid), virUUIDFormat(mods->interfaceID, modsuuid)); return -1; } memcpy(orig->interfaceID, mods->interfaceID, sizeof(orig->interfaceID)); orig->interfaceID_specified = true; } if (mods->profileID[0] && (otype == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH || otype == VIR_NETDEV_VPORT_PROFILE_8021QBH || otype == VIR_NETDEV_VPORT_PROFILE_NONE)) { if (orig->profileID[0] && STRNEQ(orig->profileID, mods->profileID)) { virReportError(VIR_ERR_XML_ERROR, _("attempt to merge virtualports with " "mismatched profileids ('%s' and '%s')"), orig->profileID, mods->profileID); return -1; } if (virStrcpyStatic(orig->profileID, mods->profileID) == NULL) { /* this should never happen - it indicates mods->profileID * isn't properly null terminated. */ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("corrupted profileid string")); return -1; } } return 0; }
static int virLockManagerSanlockSetupLockspace(void) { int fd = -1; struct stat st; int rv; struct sanlk_lockspace ls; char *path = NULL; char *dir = NULL; int retries = LOCKSPACE_RETRIES; if (virAsprintf(&path, "%s/%s", driver->autoDiskLeasePath, VIR_LOCK_MANAGER_SANLOCK_AUTO_DISK_LOCKSPACE) < 0) { virReportOOMError(); goto error; } if (!virStrcpyStatic(ls.name, VIR_LOCK_MANAGER_SANLOCK_AUTO_DISK_LOCKSPACE)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Lockspace path '%s' exceeded %d characters"), VIR_LOCK_MANAGER_SANLOCK_AUTO_DISK_LOCKSPACE, SANLK_PATH_LEN); goto error; } ls.host_id = 0; /* Doesn't matter for initialization */ ls.flags = 0; if (!virStrcpy(ls.host_id_disk.path, path, SANLK_PATH_LEN)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Lockspace path '%s' exceeded %d characters"), path, SANLK_PATH_LEN); goto error; } ls.host_id_disk.offset = 0; /* Stage 1: Ensure the lockspace file exists on disk, has * space allocated for it and is initialized with lease */ if (stat(path, &st) < 0) { int perms = 0600; VIR_DEBUG("Lockspace %s does not yet exist", path); if (!(dir = mdir_name(path))) { virReportOOMError(); goto error; } if (stat(dir, &st) < 0 || !S_ISDIR(st.st_mode)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to create lockspace %s: parent directory" " does not exist or is not a directory"), path); goto error; } if (driver->group != (gid_t) -1) perms |= 0060; if ((fd = open(path, O_WRONLY|O_CREAT|O_EXCL, perms)) < 0) { if (errno != EEXIST) { virReportSystemError(errno, _("Unable to create lockspace %s"), path); goto error; } VIR_DEBUG("Someone else just created lockspace %s", path); } else { /* chown() the path to make sure sanlock can access it */ if ((driver->user != (uid_t) -1 || driver->group != (gid_t) -1) && (fchown(fd, driver->user, driver->group) < 0)) { virReportSystemError(errno, _("cannot chown '%s' to (%u, %u)"), path, (unsigned int) driver->user, (unsigned int) driver->group); goto error_unlink; } if ((rv = sanlock_align(&ls.host_id_disk)) < 0) { if (rv <= -200) virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to query sector size %s: error %d"), path, rv); else virReportSystemError(-rv, _("Unable to query sector size %s"), path); goto error_unlink; } /* * Pre allocate enough data for 1 block of leases at preferred alignment */ if (safezero(fd, 0, rv) < 0) { virReportSystemError(errno, _("Unable to allocate lockspace %s"), path); goto error_unlink; } if (VIR_CLOSE(fd) < 0) { virReportSystemError(errno, _("Unable to save lockspace %s"), path); goto error_unlink; } if ((rv = sanlock_init(&ls, NULL, 0, 0)) < 0) { if (rv <= -200) virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to initialize lockspace %s: error %d"), path, rv); else virReportSystemError(-rv, _("Unable to initialize lockspace %s"), path); goto error_unlink; } VIR_DEBUG("Lockspace %s has been initialized", path); } } else if (S_ISREG(st.st_mode)) { /* okay, the lease file exists. Check the permissions */ if (((driver->user != (uid_t) -1 && driver->user != st.st_uid) || (driver->group != (gid_t) -1 && driver->group != st.st_gid)) && (chown(path, driver->user, driver->group) < 0)) { virReportSystemError(errno, _("cannot chown '%s' to (%u, %u)"), path, (unsigned int) driver->user, (unsigned int) driver->group); goto error; } if ((driver->group != (gid_t) -1 && (st.st_mode & 0060) != 0060) && chmod(path, 0660) < 0) { virReportSystemError(errno, _("cannot chmod '%s' to 0660"), path); goto error; } } ls.host_id = driver->hostID; /* Stage 2: Try to register the lockspace with the daemon. If the lockspace * is already registered, we should get EEXIST back in which case we can * just carry on with life. If EINPROGRESS is returned, we have two options: * either call a sanlock API that blocks us until lockspace changes state, * or we can fallback to polling. */ retry: if ((rv = sanlock_add_lockspace(&ls, 0)) < 0) { if (-rv == EINPROGRESS && --retries) { #ifdef HAVE_SANLOCK_INQ_LOCKSPACE /* we have this function which blocks until lockspace change the * state. It returns 0 if lockspace has been added, -ENOENT if it * hasn't. */ VIR_DEBUG("Inquiring lockspace"); if (sanlock_inq_lockspace(&ls, SANLK_INQ_WAIT) < 0) VIR_DEBUG("Unable to inquire lockspace"); #else /* fall back to polling */ VIR_DEBUG("Sleeping for %dms", LOCKSPACE_SLEEP); usleep(LOCKSPACE_SLEEP * 1000); #endif VIR_DEBUG("Retrying to add lockspace (left %d)", retries); goto retry; } if (-rv != EEXIST) { if (rv <= -200) virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to add lockspace %s: error %d"), path, rv); else virReportSystemError(-rv, _("Unable to add lockspace %s"), path); goto error; } else { VIR_DEBUG("Lockspace %s is already registered", path); } } else { VIR_DEBUG("Lockspace %s has been registered", path); } VIR_FREE(path); VIR_FREE(dir); return 0; error_unlink: unlink(path); error: VIR_FORCE_CLOSE(fd); VIR_FREE(path); VIR_FREE(dir); return -1; }
virNetDevVPortProfilePtr virNetDevVPortProfileParse(xmlNodePtr node) { char *virtPortType; char *virtPortManagerID = NULL; char *virtPortTypeID = NULL; char *virtPortTypeIDVersion = NULL; char *virtPortInstanceID = NULL; char *virtPortProfileID = NULL; char *virtPortInterfaceID = NULL; virNetDevVPortProfilePtr virtPort = NULL; xmlNodePtr cur = node->children; if (VIR_ALLOC(virtPort) < 0) { virReportOOMError(); return NULL; } virtPortType = virXMLPropString(node, "type"); if (!virtPortType) { virReportError(VIR_ERR_XML_ERROR, "%s", _("missing virtualportprofile type")); goto error; } if ((virtPort->virtPortType = virNetDevVPortTypeFromString(virtPortType)) <= 0) { virReportError(VIR_ERR_XML_ERROR, _("unknown virtualportprofile type %s"), virtPortType); goto error; } while (cur != NULL) { if (xmlStrEqual(cur->name, BAD_CAST "parameters")) { virtPortManagerID = virXMLPropString(cur, "managerid"); virtPortTypeID = virXMLPropString(cur, "typeid"); virtPortTypeIDVersion = virXMLPropString(cur, "typeidversion"); virtPortInstanceID = virXMLPropString(cur, "instanceid"); virtPortProfileID = virXMLPropString(cur, "profileid"); virtPortInterfaceID = virXMLPropString(cur, "interfaceid"); break; } cur = cur->next; } switch (virtPort->virtPortType) { case VIR_NETDEV_VPORT_PROFILE_8021QBG: if (virtPortManagerID != NULL && virtPortTypeID != NULL && virtPortTypeIDVersion != NULL) { unsigned int val; if (virStrToLong_ui(virtPortManagerID, NULL, 0, &val)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("cannot parse value of managerid parameter")); goto error; } if (val > 0xff) { virReportError(VIR_ERR_XML_ERROR, "%s", _("value of managerid out of range")); goto error; } virtPort->u.virtPort8021Qbg.managerID = (uint8_t)val; if (virStrToLong_ui(virtPortTypeID, NULL, 0, &val)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("cannot parse value of typeid parameter")); goto error; } if (val > 0xffffff) { virReportError(VIR_ERR_XML_ERROR, "%s", _("value for typeid out of range")); goto error; } virtPort->u.virtPort8021Qbg.typeID = (uint32_t)val; if (virStrToLong_ui(virtPortTypeIDVersion, NULL, 0, &val)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("cannot parse value of typeidversion parameter")); goto error; } if (val > 0xff) { virReportError(VIR_ERR_XML_ERROR, "%s", _("value of typeidversion out of range")); goto error; } virtPort->u.virtPort8021Qbg.typeIDVersion = (uint8_t)val; if (virtPortInstanceID != NULL) { if (virUUIDParse(virtPortInstanceID, virtPort->u.virtPort8021Qbg.instanceID)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("cannot parse instanceid parameter as a uuid")); goto error; } } else { if (virUUIDGenerate(virtPort->u.virtPort8021Qbg.instanceID)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("cannot generate a random uuid for instanceid")); goto error; } } virtPort->virtPortType = VIR_NETDEV_VPORT_PROFILE_8021QBG; } else { virReportError(VIR_ERR_XML_ERROR, "%s", _("a parameter is missing for 802.1Qbg description")); goto error; } break; case VIR_NETDEV_VPORT_PROFILE_8021QBH: if (virtPortProfileID != NULL) { if (virStrcpyStatic(virtPort->u.virtPort8021Qbh.profileID, virtPortProfileID) != NULL) { virtPort->virtPortType = VIR_NETDEV_VPORT_PROFILE_8021QBH; } else { virReportError(VIR_ERR_XML_ERROR, "%s", _("profileid parameter too long")); goto error; } } else { virReportError(VIR_ERR_XML_ERROR, "%s", _("profileid parameter is missing for 802.1Qbh description")); goto error; } break; case VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH: if (virtPortInterfaceID != NULL) { if (virUUIDParse(virtPortInterfaceID, virtPort->u.openvswitch.interfaceID)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("cannot parse interfaceid parameter as a uuid")); goto error; } } else { if (virUUIDGenerate(virtPort->u.openvswitch.interfaceID)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("cannot generate a random uuid for interfaceid")); goto error; } } /* profileid is not mandatory for Open vSwitch */ if (virtPortProfileID != NULL) { if (virStrcpyStatic(virtPort->u.openvswitch.profileID, virtPortProfileID) == NULL) { virReportError(VIR_ERR_XML_ERROR, "%s", _("profileid parameter too long")); goto error; } } else { virtPort->u.openvswitch.profileID[0] = '\0'; } break; default: virReportError(VIR_ERR_XML_ERROR, _("unexpected virtualport type %d"), virtPort->virtPortType); goto error; } cleanup: VIR_FREE(virtPortManagerID); VIR_FREE(virtPortTypeID); VIR_FREE(virtPortTypeIDVersion); VIR_FREE(virtPortInstanceID); VIR_FREE(virtPortProfileID); VIR_FREE(virtPortType); return virtPort; error: VIR_FREE(virtPort); goto cleanup; }
static int virHostCPUGetStatsFreeBSD(int cpuNum, virNodeCPUStatsPtr params, int *nparams) { const char *sysctl_name; long *cpu_times; struct clockinfo clkinfo; size_t i, j, cpu_times_size, clkinfo_size; int cpu_times_num, offset, hz, stathz, ret = -1; struct field_cpu_map { const char *field; int idx[CPUSTATES]; } cpu_map[] = { {VIR_NODE_CPU_STATS_KERNEL, {CP_SYS}}, {VIR_NODE_CPU_STATS_USER, {CP_USER, CP_NICE}}, {VIR_NODE_CPU_STATS_IDLE, {CP_IDLE}}, {VIR_NODE_CPU_STATS_INTR, {CP_INTR}}, {NULL, {0}} }; if ((*nparams) == 0) { *nparams = BSD_CPU_STATS_ALL; return 0; } if ((*nparams) != BSD_CPU_STATS_ALL) { virReportInvalidArg(*nparams, _("nparams in %s must be equal to %d"), __FUNCTION__, BSD_CPU_STATS_ALL); return -1; } clkinfo_size = sizeof(clkinfo); if (sysctlbyname("kern.clockrate", &clkinfo, &clkinfo_size, NULL, 0) < 0) { virReportSystemError(errno, _("sysctl failed for '%s'"), "kern.clockrate"); return -1; } stathz = clkinfo.stathz; hz = clkinfo.hz; if (cpuNum == VIR_NODE_CPU_STATS_ALL_CPUS) { sysctl_name = "kern.cp_time"; cpu_times_num = 1; offset = 0; } else { sysctl_name = "kern.cp_times"; cpu_times_num = virHostCPUGetCountAppleFreeBSD(); if (cpuNum >= cpu_times_num) { virReportInvalidArg(cpuNum, _("Invalid cpuNum in %s"), __FUNCTION__); return -1; } offset = cpu_times_num * CPUSTATES; } cpu_times_size = sizeof(long) * cpu_times_num * CPUSTATES; if (VIR_ALLOC_N(cpu_times, cpu_times_num * CPUSTATES) < 0) goto cleanup; if (sysctlbyname(sysctl_name, cpu_times, &cpu_times_size, NULL, 0) < 0) { virReportSystemError(errno, _("sysctl failed for '%s'"), sysctl_name); goto cleanup; } for (i = 0; cpu_map[i].field != NULL; i++) { virNodeCPUStatsPtr param = ¶ms[i]; if (virStrcpyStatic(param->field, cpu_map[i].field) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Field '%s' too long for destination"), cpu_map[i].field); goto cleanup; } param->value = 0; for (j = 0; j < ARRAY_CARDINALITY(cpu_map[i].idx); j++) param->value += cpu_times[offset + cpu_map[i].idx[j]] * TICK_TO_NSEC; } ret = 0; cleanup: VIR_FREE(cpu_times); return ret; }
/* Assign name, type, and convert the argument from a const string. * In case of a string, the string is copied. * Return 0 on success, -1 after an error message on failure. */ int virTypedParameterAssignFromStr(virTypedParameterPtr param, const char *name, int type, const char *val) { int ret = -1; if (!val) { virReportError(VIR_ERR_INVALID_ARG, _("NULL value for field '%s'"), name); goto cleanup; } if (virStrcpyStatic(param->field, name) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Field name '%s' too long"), name); goto cleanup; } param->type = type; switch (type) { case VIR_TYPED_PARAM_INT: if (virStrToLong_i(val, NULL, 10, ¶m->value.i) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("Invalid value for field '%s': expected int"), name); goto cleanup; } break; case VIR_TYPED_PARAM_UINT: if (virStrToLong_ui(val, NULL, 10, ¶m->value.ui) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("Invalid value for field '%s': " "expected unsigned int"), name); goto cleanup; } break; case VIR_TYPED_PARAM_LLONG: if (virStrToLong_ll(val, NULL, 10, ¶m->value.l) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("Invalid value for field '%s': " "expected long long"), name); goto cleanup; } break; case VIR_TYPED_PARAM_ULLONG: if (virStrToLong_ull(val, NULL, 10, ¶m->value.ul) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("Invalid value for field '%s': " "expected unsigned long long"), name); goto cleanup; } break; case VIR_TYPED_PARAM_DOUBLE: if (virStrToDouble(val, NULL, ¶m->value.d) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("Invalid value for field '%s': " "expected double"), name); goto cleanup; } break; case VIR_TYPED_PARAM_BOOLEAN: if (STRCASEEQ(val, "true") || STREQ(val, "1")) { param->value.b = true; } else if (STRCASEEQ(val, "false") || STREQ(val, "0")) { param->value.b = false; } else { virReportError(VIR_ERR_INVALID_ARG, _("Invalid boolean value for field '%s'"), name); goto cleanup; } break; case VIR_TYPED_PARAM_STRING: if (VIR_STRDUP(param->value.s, val) < 0) goto cleanup; break; default: virReportError(VIR_ERR_INTERNAL_ERROR, _("unexpected type %d for field %s"), type, name); goto cleanup; } ret = 0; cleanup: return ret; }