static int mymain(void) { int ret = 0; char *filedata = NULL; char *filename = NULL; size_t i; size_t *params = NULL; if (virAsprintf(&filename, "%s/../daemon/libvirtd.conf", abs_srcdir) < 0) { perror("Format filename"); return EXIT_FAILURE; } if (virFileReadAll(filename, 1024*1024, &filedata) < 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, "Cannot load %s for testing: %s", filename, err->message); ret = -1; goto cleanup; } if (uncomment_all_params(filedata, ¶ms) < 0){ perror("Find params"); ret = -1; goto cleanup; } VIR_DEBUG("Initial config [%s]", filedata); for (i = 0 ; params[i] != 0 ; i++) { const struct testCorruptData data = { params, filedata, filename, i }; if (virtTestRun("Test corruption", 1, testCorrupt, &data) < 0) ret = -1; } cleanup: VIR_FREE(filename); VIR_FREE(filedata); VIR_FREE(params); return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE; }
static int virNetDevIPGetAcceptRA(const char *ifname) { char *path = NULL; char *buf = NULL; char *suffix; int accept_ra = -1; if (virAsprintf(&path, "/proc/sys/net/ipv6/conf/%s/accept_ra", ifname ? ifname : "all") < 0) goto cleanup; if ((virFileReadAll(path, 512, &buf) < 0) || (virStrToLong_i(buf, &suffix, 10, &accept_ra) < 0)) goto cleanup; cleanup: VIR_FREE(path); VIR_FREE(buf); return accept_ra; }
/** * virConfReadFile: * @filename: the path to the configuration file. * @flags: combination of virConfFlag(s) * * Reads a configuration file. * * Returns a handle to lookup settings or NULL if it failed to * read or parse the file, use virConfFree() to free the data. */ virConfPtr virConfReadFile(const char *filename, unsigned int flags) { char *content; int len; virConfPtr conf; if (filename == NULL) { virConfError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__); return NULL; } if ((len = virFileReadAll(filename, MAX_CONFIG_FILE_SIZE, &content)) < 0) { return NULL; } conf = virConfParse(filename, content, len, flags); VIR_FREE(content); return conf; }
/* * Linux maintains cpu bit map under cpu/online. For example, if * cpuid=5's flag is not set and max cpu is 7, the map file shows * 0-4,6-7. This function parses it and returns cpumap. */ static virBitmapPtr linuxParseCPUmap(int max_cpuid, const char *path) { virBitmapPtr map = NULL; char *str = NULL; if (virFileReadAll(path, 5 * VIR_DOMAIN_CPUMASK_LEN, &str) < 0) { virReportOOMError(); goto error; } if (virBitmapParse(str, 0, &map, max_cpuid) < 0) goto error; VIR_FREE(str); return map; error: VIR_FREE(str); virBitmapFree(map); return NULL; }
static int test_virCapabilitiesFormat(const void *opaque) { struct virCapabilitiesFormatData *data = (struct virCapabilitiesFormatData *) opaque; virCapsPtr caps = NULL; char *capsXML = NULL; char *capsFromFile = NULL; char *path = NULL; int ret = -1; if (!(caps = buildVirCapabilities(data->max_cells, data->max_cpus_in_cell, data->max_mem_in_cell))) goto cleanup; if (!(capsXML = virCapabilitiesFormatXML(caps))) goto cleanup; if (virAsprintf(&path, "%s/vircaps2xmldata/vircaps-%s.xml", abs_srcdir, data->filename) < 0) goto cleanup; if (virFileReadAll(path, 8192, &capsFromFile) < 0) goto cleanup; if (STRNEQ(capsXML, capsFromFile)) { virtTestDifference(stderr, capsFromFile, capsXML); goto cleanup; } ret = 0; cleanup: VIR_FREE(path); VIR_FREE(capsFromFile); VIR_FREE(capsXML); virObjectUnref(caps); return ret; }
/* * profile_status_file returns '-1' on error, '0' if file on disk is in * complain mode and '1' if file on disk is in enforcing mode */ static int profile_status_file(const char *str) { char *profile = NULL; char *content = NULL; char *tmp = NULL; int rc = -1; int len; if (virAsprintf(&profile, "%s/%s", APPARMOR_DIR "/libvirt", str) == -1) return rc; if (!virFileExists(profile)) goto failed; if ((len = virFileReadAll(profile, MAX_FILE_LEN, &content)) < 0) { virReportSystemError(errno, _("Failed to read \'%s\'"), profile); goto failed; } /* create string that is ' <str> flags=(complain)\0' */ if (virAsprintf(&tmp, " %s flags=(complain)", str) == -1) goto failed; if (strstr(content, tmp) != NULL) rc = 0; else rc = 1; failed: VIR_FREE(tmp); VIR_FREE(profile); VIR_FREE(content); return rc; }
static bool cmdVolCreate(vshControl *ctl, const vshCmd *cmd) { virStoragePoolPtr pool; virStorageVolPtr vol; const char *from = NULL; bool ret = false; unsigned int flags = 0; char *buffer = NULL; if (vshCommandOptBool(cmd, "prealloc-metadata")) flags |= VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA; if (!(pool = vshCommandOptPool(ctl, cmd, "pool", NULL))) return false; if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0) goto cleanup; if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0) { vshSaveLibvirtError(); goto cleanup; } if ((vol = virStorageVolCreateXML(pool, buffer, flags))) { vshPrint(ctl, _("Vol %s created from %s\n"), virStorageVolGetName(vol), from); virStorageVolFree(vol); ret = true; } else { vshError(ctl, _("Failed to create vol from %s"), from); } cleanup: VIR_FREE(buffer); virStoragePoolFree(pool); return ret; }
/* * Linux maintains cpu bit map. For example, if cpuid=5's flag is not set * and max cpu is 7. The map file shows 0-4,6-7. This function parses * it and returns cpumap. */ static char * linuxParseCPUmap(int *max_cpuid, const char *path) { char *map = NULL; char *str = NULL; int max_id = 0, i; if (virFileReadAll(path, 5 * VIR_DOMAIN_CPUMASK_LEN, &str) < 0) { virReportOOMError(); goto error; } if (VIR_ALLOC_N(map, VIR_DOMAIN_CPUMASK_LEN) < 0) { virReportOOMError(); goto error; } if (virDomainCpuSetParse(str, 0, map, VIR_DOMAIN_CPUMASK_LEN) < 0) { goto error; } for (i = 0; i < VIR_DOMAIN_CPUMASK_LEN; i++) { if (map[i]) { max_id = i; } } *max_cpuid = max_id; VIR_FREE(str); return map; error: VIR_FREE(str); VIR_FREE(map); return NULL; }
int virNumaSetPagePoolSize(int node, unsigned int page_size, unsigned long long page_count, bool add) { int ret = -1; char *nr_path = NULL, *nr_buf = NULL; char *end; unsigned long long nr_count; if (page_size == virGetSystemPageSizeKB()) { /* Special case as kernel handles system pages * differently to huge pages. */ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", _("system pages pool can't be modified")); goto cleanup; } if (virNumaGetHugePageInfoPath(&nr_path, node, page_size, "nr_hugepages") < 0) goto cleanup; /* Firstly check, if there's anything for us to do */ if (virFileReadAll(nr_path, 1024, &nr_buf) < 0) goto cleanup; if (virStrToLong_ull(nr_buf, &end, 10, &nr_count) < 0 || *end != '\n') { virReportError(VIR_ERR_OPERATION_FAILED, _("invalid number '%s' in '%s'"), nr_buf, nr_path); goto cleanup; } if (add) { if (!page_count) { VIR_DEBUG("Nothing left to do: add = true page_count = 0"); ret = 0; goto cleanup; } page_count += nr_count; } else { if (nr_count == page_count) { VIR_DEBUG("Nothing left to do: nr_count = page_count = %llu", page_count); ret = 0; goto cleanup; } } /* Okay, page pool adjustment must be done in two steps. In * first we write the desired number into nr_hugepages file. * Kernel then starts to allocate the pages (return from * write should be postponed until the kernel is finished). * However, kernel may have not been successful and reserved * all the pages we wanted. So do the second read to check. */ VIR_FREE(nr_buf); if (virAsprintf(&nr_buf, "%llu", page_count) < 0) goto cleanup; if (virFileWriteStr(nr_path, nr_buf, 0) < 0) { virReportSystemError(errno, _("Unable to write to: %s"), nr_path); goto cleanup; } /* And now do the check. */ VIR_FREE(nr_buf); if (virFileReadAll(nr_path, 1024, &nr_buf) < 0) goto cleanup; if (virStrToLong_ull(nr_buf, &end, 10, &nr_count) < 0 || *end != '\n') { virReportError(VIR_ERR_OPERATION_FAILED, _("invalid number '%s' in '%s'"), nr_buf, nr_path); goto cleanup; } if (nr_count != page_count) { virReportError(VIR_ERR_OPERATION_FAILED, _("Unable to allocate %llu pages. Allocated only %llu"), page_count, nr_count); goto cleanup; } ret = 0; cleanup: VIR_FREE(nr_buf); VIR_FREE(nr_path); return ret; }
int vmwareLoadDomains(struct vmware_driver *driver) { virDomainDefPtr vmdef = NULL; virDomainObjPtr vm = NULL; char *vmxPath = NULL; char *vmx = NULL; vmwareDomainPtr pDomain; char *directoryName = NULL; char *fileName = NULL; int ret = -1; virVMXContext ctx; char *outbuf = NULL; char *str; char *saveptr = NULL; virCommandPtr cmd; ctx.parseFileName = vmwareCopyVMXFileName; cmd = virCommandNewArgList(VMRUN, "-T", driver->type == TYPE_PLAYER ? "player" : "ws", "list", NULL); virCommandSetOutputBuffer(cmd, &outbuf); if (virCommandRun(cmd, NULL) < 0) goto cleanup; for (str = outbuf; (vmxPath = strtok_r(str, "\n", &saveptr)) != NULL; str = NULL) { if (vmxPath[0] != '/') continue; if (virFileReadAll(vmxPath, 10000, &vmx) < 0) goto cleanup; if ((vmdef = virVMXParseConfig(&ctx, driver->xmlopt, vmx)) == NULL) { goto cleanup; } if (!(vm = virDomainObjListAdd(driver->domains, vmdef, driver->xmlopt, 0, NULL))) goto cleanup; pDomain = vm->privateData; if (VIR_STRDUP(pDomain->vmxPath, vmxPath) < 0) goto cleanup; vmwareDomainConfigDisplay(pDomain, vmdef); if ((vm->def->id = vmwareExtractPid(vmxPath)) < 0) goto cleanup; /* vmrun list only reports running vms */ virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_UNKNOWN); vm->persistent = 1; virObjectUnlock(vm); vmdef = NULL; vm = NULL; } ret = 0; cleanup: virCommandFree(cmd); VIR_FREE(outbuf); virDomainDefFree(vmdef); VIR_FREE(directoryName); VIR_FREE(fileName); VIR_FREE(vmx); virObjectUnref(vm); return ret; }
/* XXX: This function can be a lot more exhaustive, there are certainly * other scenarios where we can ruin host network connectivity. * XXX: Using a proper library is preferred over parsing /proc */ int networkCheckRouteCollision(virNetworkDefPtr def) { int ret = 0, len; char *cur, *buf = NULL; /* allow for up to 100000 routes (each line is 128 bytes) */ enum {MAX_ROUTE_SIZE = 128*100000}; /* Read whole routing table into memory */ if ((len = virFileReadAll(PROC_NET_ROUTE, MAX_ROUTE_SIZE, &buf)) < 0) goto out; /* Dropping the last character shouldn't hurt */ if (len > 0) buf[len-1] = '\0'; VIR_DEBUG("%s output:\n%s", PROC_NET_ROUTE, buf); if (!STRPREFIX(buf, "Iface")) goto out; /* First line is just headings, skip it */ cur = strchr(buf, '\n'); if (cur) cur++; while (cur) { char iface[17], dest[128], mask[128]; unsigned int addr_val, mask_val; virNetworkIpDefPtr ipdef; int num; size_t i; /* NUL-terminate the line, so sscanf doesn't go beyond a newline. */ char *nl = strchr(cur, '\n'); if (nl) *nl++ = '\0'; num = sscanf(cur, "%16s %127s %*s %*s %*s %*s %*s %127s", iface, dest, mask); cur = nl; if (num != 3) { VIR_DEBUG("Failed to parse %s", PROC_NET_ROUTE); continue; } if (virStrToLong_ui(dest, NULL, 16, &addr_val) < 0) { VIR_DEBUG("Failed to convert network address %s to uint", dest); continue; } if (virStrToLong_ui(mask, NULL, 16, &mask_val) < 0) { VIR_DEBUG("Failed to convert network mask %s to uint", mask); continue; } addr_val &= mask_val; for (i = 0; (ipdef = virNetworkDefGetIpByIndex(def, AF_INET, i)); i++) { unsigned int net_dest; virSocketAddr netmask; if (virNetworkIpDefNetmask(ipdef, &netmask) < 0) { VIR_WARN("Failed to get netmask of '%s'", def->bridge); continue; } net_dest = (ipdef->address.data.inet4.sin_addr.s_addr & netmask.data.inet4.sin_addr.s_addr); if ((net_dest == addr_val) && (netmask.data.inet4.sin_addr.s_addr == mask_val)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Network is already in use by interface %s"), iface); ret = -1; goto out; } } } out: VIR_FREE(buf); return ret; }
static int testExecRestart(const void *opaque) { int ret = -1; virNetServerPtr srv = NULL; const struct testExecRestartData *data = opaque; char *infile = NULL, *outfile = NULL; char *injsonstr = NULL, *outjsonstr = NULL; virJSONValuePtr injson = NULL, outjson = NULL; int fdclient[2] = { -1, -1 }, fdserver[2] = { -1, -1 }; if (socketpair(PF_UNIX, SOCK_STREAM, 0, fdclient) < 0) { virReportSystemError(errno, "%s", "Cannot create socket pair"); goto cleanup; } if (socketpair(PF_UNIX, SOCK_STREAM, 0, fdserver) < 0) { virReportSystemError(errno, "%s", "Cannot create socket pair"); goto cleanup; } /* We're blindly assuming the test case isn't using * fds 100->103 for something else, which is probably * fairly reasonable in general */ dup2(fdserver[0], 100); dup2(fdserver[1], 101); dup2(fdclient[0], 102); dup2(fdclient[1], 103); if (virAsprintf(&infile, "%s/virnetserverdata/input-data-%s.json", abs_srcdir, data->jsonfile) < 0) goto cleanup; if (virAsprintf(&outfile, "%s/virnetserverdata/output-data-%s.json", abs_srcdir, data->jsonfile) < 0) goto cleanup; if (virFileReadAll(infile, 8192, &injsonstr) < 0) goto cleanup; if (!(injson = virJSONValueFromString(injsonstr))) goto cleanup; if (!(srv = virNetServerNewPostExecRestart(injson, NULL, NULL, NULL, NULL, NULL))) goto cleanup; if (!(outjson = virNetServerPreExecRestart(srv))) goto cleanup; if (!(outjsonstr = virJSONValueToString(outjson, true))) goto cleanup; if (virtTestCompareToFile(outjsonstr, outfile) < 0) goto fail; ret = 0; cleanup: if (ret < 0) { virErrorPtr err = virGetLastError(); /* Rather be safe, we have lot of missing errors */ if (err) fprintf(stderr, "%s\n", err->message); else fprintf(stderr, "%s\n", "Unknown error"); } fail: VIR_FREE(infile); VIR_FREE(outfile); VIR_FREE(injsonstr); VIR_FREE(outjsonstr); virJSONValueFree(injson); virJSONValueFree(outjson); virObjectUnref(srv); VIR_FORCE_CLOSE(fdserver[0]); VIR_FORCE_CLOSE(fdserver[1]); VIR_FORCE_CLOSE(fdclient[0]); VIR_FORCE_CLOSE(fdclient[1]); return ret; }
static int parallelsGetBridgedNetInfo(virNetworkDefPtr def, virJSONValuePtr jobj) { const char *ifname; char *bridgeLink = NULL; char *bridgePath = NULL; char *bridgeAddressPath = NULL; char *bridgeAddress = NULL; int len = 0; int ret = -1; if (!(ifname = virJSONValueObjectGetString(jobj, "Bound To"))) { parallelsParseError(); goto cleanup; } if (virAsprintf(&bridgeLink, "%s/%s/brport/bridge", SYSFS_NET_DIR, ifname) < 0) { virReportOOMError(); goto cleanup; } if (virFileResolveLink(bridgeLink, &bridgePath) < 0) { virReportSystemError(errno, _("cannot read link '%s'"), bridgeLink); goto cleanup; } if (!(def->bridge = strdup(basename(bridgePath)))) { virReportOOMError(); goto cleanup; } if (virAsprintf(&bridgeAddressPath, "%s/%s/brport/bridge/address", SYSFS_NET_DIR, ifname) < 0) { virReportOOMError(); goto cleanup; } if ((len = virFileReadAll(bridgeAddressPath, 18, &bridgeAddress)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Error reading file '%s'"), bridgeAddressPath); goto cleanup; } if (len < VIR_MAC_STRING_BUFLEN) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Error reading MAC from '%s'"), bridgeAddressPath); } bridgeAddress[VIR_MAC_STRING_BUFLEN - 1] = '\0'; if (virMacAddrParse(bridgeAddress, &def->mac) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Can't parse MAC '%s'"), bridgeAddress); goto cleanup; } def->mac_specified = 1; ret = 0; cleanup: VIR_FREE(bridgeLink); VIR_FREE(bridgePath); VIR_FREE(bridgeAddress); VIR_FREE(bridgeAddressPath); return ret; }
static int virPerfRdtEnable(virPerfEventPtr event, pid_t pid) { struct perf_event_attr rdt_attr; char *buf = NULL; char *tmp = NULL; unsigned int event_type, scale; if (virFileReadAll("/sys/devices/intel_cqm/type", 10, &buf) < 0) goto error; if ((tmp = strchr(buf, '\n'))) *tmp = '\0'; if (virStrToLong_ui(buf, NULL, 10, &event_type) < 0) { virReportSystemError(errno, "%s", _("failed to get rdt event type")); goto error; } VIR_FREE(buf); memset(&rdt_attr, 0, sizeof(rdt_attr)); rdt_attr.size = sizeof(rdt_attr); rdt_attr.type = event_type; rdt_attr.inherit = 1; rdt_attr.disabled = 1; rdt_attr.enable_on_exec = 0; switch (event->type) { case VIR_PERF_EVENT_CMT: if (virFileReadAll("/sys/devices/intel_cqm/events/llc_occupancy.scale", 10, &buf) < 0) goto error; if (virStrToLong_ui(buf, NULL, 10, &scale) < 0) { virReportSystemError(errno, "%s", _("failed to get cmt scaling factor")); goto error; } event->efields.cmt.scale = scale; rdt_attr.config = 1; break; case VIR_PERF_EVENT_MBMT: rdt_attr.config = 2; break; case VIR_PERF_EVENT_MBML: rdt_attr.config = 3; break; } event->fd = syscall(__NR_perf_event_open, &rdt_attr, pid, -1, -1, 0); if (event->fd < 0) { virReportSystemError(errno, _("Unable to open perf type=%d for pid=%d"), event_type, pid); goto error; } if (ioctl(event->fd, PERF_EVENT_IOC_ENABLE) < 0) { virReportSystemError(errno, _("Unable to enable perf event for %s"), virPerfEventTypeToString(event->type)); goto error; } event->enabled = true; return 0; error: VIR_FORCE_CLOSE(event->fd); VIR_FREE(buf); return -1; }
virSCSIDevicePtr virSCSIDeviceNew(const char *adapter, unsigned int bus, unsigned int target, unsigned int unit, bool readonly) { virSCSIDevicePtr dev, ret = NULL; char *sg = NULL; char *vendor_path = NULL; char *model_path = NULL; char *vendor = NULL; char *model = NULL; if (VIR_ALLOC(dev) < 0) return NULL; dev->bus = bus; dev->target = target; dev->unit = unit; dev->readonly = readonly; if (!(sg = virSCSIDeviceGetSgName(adapter, bus, target, unit))) goto cleanup; if (virSCSIDeviceGetAdapterId(adapter, &dev->adapter) < 0) goto cleanup; if (virAsprintf(&dev->name, "%d:%d:%d:%d", dev->adapter, dev->bus, dev->target, dev->unit) < 0 || virAsprintf(&dev->sg_path, "/dev/%s", sg) < 0) goto cleanup; if (access(dev->sg_path, F_OK) != 0) { virReportSystemError(errno, _("SCSI device '%s': could not access %s"), dev->name, dev->sg_path); goto cleanup; } if (virAsprintf(&vendor_path, SYSFS_SCSI_DEVICES "/%s/vendor", dev->name) < 0 || virAsprintf(&model_path, SYSFS_SCSI_DEVICES "/%s/model", dev->name) < 0) goto cleanup; if (virFileReadAll(vendor_path, 1024, &vendor) < 0) goto cleanup; if (virFileReadAll(model_path, 1024, &model) < 0) goto cleanup; virTrimSpaces(vendor, NULL); virTrimSpaces(model, NULL); if (virAsprintf(&dev->id, "%s:%s", vendor, model) < 0) goto cleanup; ret = dev; cleanup: VIR_FREE(sg); VIR_FREE(vendor); VIR_FREE(model); VIR_FREE(vendor_path); VIR_FREE(model_path); if (!ret) virSCSIDeviceFree(dev); return ret; }
virSCSIDevicePtr virSCSIDeviceNew(const char *sysfs_prefix, const char *adapter, unsigned int bus, unsigned int target, unsigned long long unit, bool readonly, bool shareable) { virSCSIDevicePtr dev, ret = NULL; char *sg = NULL; char *vendor_path = NULL; char *model_path = NULL; char *vendor = NULL; char *model = NULL; const char *prefix = sysfs_prefix ? sysfs_prefix : SYSFS_SCSI_DEVICES; if (VIR_ALLOC(dev) < 0) return NULL; dev->bus = bus; dev->target = target; dev->unit = unit; dev->readonly = readonly; dev->shareable = shareable; if (!(sg = virSCSIDeviceGetSgName(prefix, adapter, bus, target, unit))) goto cleanup; if (virSCSIDeviceGetAdapterId(adapter, &dev->adapter) < 0) goto cleanup; if (virAsprintf(&dev->name, "%d:%u:%u:%llu", dev->adapter, dev->bus, dev->target, dev->unit) < 0 || virAsprintf(&dev->sg_path, "%s/%s", sysfs_prefix ? sysfs_prefix : "/dev", sg) < 0) goto cleanup; if (!virFileExists(dev->sg_path)) { virReportSystemError(errno, _("SCSI device '%s': could not access %s"), dev->name, dev->sg_path); goto cleanup; } if (virAsprintf(&vendor_path, "%s/%s/vendor", prefix, dev->name) < 0 || virAsprintf(&model_path, "%s/%s/model", prefix, dev->name) < 0) goto cleanup; if (virFileReadAll(vendor_path, 1024, &vendor) < 0) goto cleanup; if (virFileReadAll(model_path, 1024, &model) < 0) goto cleanup; virTrimSpaces(vendor, NULL); virTrimSpaces(model, NULL); if (virAsprintf(&dev->id, "%s:%s", vendor, model) < 0) goto cleanup; ret = dev; cleanup: VIR_FREE(sg); VIR_FREE(vendor); VIR_FREE(model); VIR_FREE(vendor_path); VIR_FREE(model_path); if (!ret) virSCSIDeviceFree(dev); return ret; }