static int virSecurityManagerCheckModel(virSecurityManagerPtr mgr, char *secmodel) { int ret = -1; size_t i; virSecurityManagerPtr *sec_managers = NULL; if (STREQ_NULLABLE(secmodel, "none")) return 0; if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL) return -1; for (i = 0; sec_managers[i]; i++) { if (STREQ_NULLABLE(secmodel, sec_managers[i]->drv->name)) { ret = 0; goto cleanup; } } virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unable to find security driver for model %s"), secmodel); cleanup: VIR_FREE(sec_managers); return ret; }
static char * getSocketPath(virURIPtr uri) { char *rundir = virGetUserRuntimeDirectory(); char *sock_path = NULL; size_t i = 0; if (!uri) goto cleanup; for (i = 0; i < uri->paramsCount; i++) { virURIParamPtr param = &uri->params[i]; if (STREQ(param->name, "socket")) { VIR_FREE(sock_path); if (VIR_STRDUP(sock_path, param->value) < 0) goto error; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unknown URI parameter '%s'"), param->name); goto error; } } if (!sock_path) { if (STRNEQ(uri->scheme, "libvirtd")) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unsupported URI scheme '%s'"), uri->scheme); goto error; } if (STREQ_NULLABLE(uri->path, "/system")) { if (VIR_STRDUP(sock_path, LIBVIRTD_ADMIN_UNIX_SOCKET) < 0) goto error; } else if (STREQ_NULLABLE(uri->path, "/session")) { if (!rundir || virAsprintf(&sock_path, "%s%s", rundir, LIBVIRTD_ADMIN_SOCK_NAME) < 0) goto error; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid URI path '%s', try '/system'"), uri->path ? uri->path : ""); goto error; } } cleanup: VIR_FREE(rundir); return sock_path; error: VIR_FREE(sock_path); goto cleanup; }
static void virLXCDomainReAttachHostUsbDevices(virLXCDriverPtr driver, const char *name, virDomainHostdevDefPtr *hostdevs, int nhostdevs) { size_t i; for (i = 0; i < nhostdevs; i++) { virDomainHostdevDefPtr hostdev = hostdevs[i]; virUSBDevicePtr usb, tmp; const char *used_by = NULL; if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) continue; if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) continue; if (hostdev->missing) continue; usb = virUSBDeviceNew(hostdev->source.subsys.u.usb.bus, hostdev->source.subsys.u.usb.device, NULL); if (!usb) { VIR_WARN("Unable to reattach USB device %03d.%03d on domain %s", hostdev->source.subsys.u.usb.bus, hostdev->source.subsys.u.usb.device, name); continue; } /* Delete only those USB devices which belongs * to domain @name because virLXCProcessStart() might * have failed because USB device is already taken. * Therefore we want to steal only those devices from * the list which were taken by @name */ tmp = virUSBDeviceListFind(driver->activeUsbHostdevs, usb); virUSBDeviceFree(usb); if (!tmp) { VIR_WARN("Unable to find device %03d.%03d " "in list of active USB devices", hostdev->source.subsys.u.usb.bus, hostdev->source.subsys.u.usb.device); continue; } used_by = virUSBDeviceGetUsedBy(tmp); if (STREQ_NULLABLE(used_by, name)) { VIR_DEBUG("Removing %03d.%03d dom=%s from activeUsbHostdevs", hostdev->source.subsys.u.usb.bus, hostdev->source.subsys.u.usb.device, name); virUSBDeviceListDel(driver->activeUsbHostdevs, tmp); } } }
static int virLockManagerSanlockInquire(virLockManagerPtr lock, char **state, unsigned int flags) { virLockManagerSanlockPrivatePtr priv = lock->privateData; int rv, res_count; virCheckFlags(0, -1); if (!state) { virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); return -1; } VIR_DEBUG("pid=%d", priv->vm_pid); if ((rv = sanlock_inquire(-1, priv->vm_pid, 0, &res_count, state)) < 0) { if (rv <= -200) virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to inquire lock: error %d"), rv); else virReportSystemError(-rv, "%s", _("Failed to inquire lock")); return -1; } if (STREQ_NULLABLE(*state, "")) VIR_FREE(*state); return 0; }
static int testSELinuxCheckLabels(testSELinuxFile *files, size_t nfiles) { size_t i; security_context_t ctx; for (i = 0; i < nfiles; i++) { ctx = NULL; if (getfilecon(files[i].file, &ctx) < 0) { if (errno == ENODATA) { /* nothing to do */ } else if (errno == EOPNOTSUPP) { if (VIR_STRDUP(ctx, "EOPNOTSUPP") < 0) return -1; } else { virReportSystemError(errno, "Cannot read label on %s", files[i].file); return -1; } } if (!STREQ_NULLABLE(files[i].context, ctx)) { virReportError(VIR_ERR_INTERNAL_ERROR, "File %s context '%s' did not match epected '%s'", files[i].file, ctx, files[i].context); VIR_FREE(ctx); return -1; } VIR_FREE(ctx); } return 0; }
bool virNWFilterVarValueEqual(const virNWFilterVarValue *a, const virNWFilterVarValue *b) { unsigned int card; size_t i, j; const char *s; if (!a || !b) return false; card = virNWFilterVarValueGetCardinality(a); if (card != virNWFilterVarValueGetCardinality(b)) return false; /* brute force O(n^2) comparison */ for (i = 0; i < card; i++) { bool eq = false; s = virNWFilterVarValueGetNthValue(a, i); for (j = 0; j < card; j++) { if (STREQ_NULLABLE(s, virNWFilterVarValueGetNthValue(b, j))) { eq = true; break; } } if (!eq) return false; } return true; }
static int testQEMUSchemaValidateBuiltin(virJSONValuePtr obj, virJSONValuePtr root, virBufferPtr debug) { const char *t = virJSONValueObjectGetString(root, "json-type"); const char *s = NULL; bool b = false; int ret = -1; if (STREQ_NULLABLE(t, "value")) { s = "{any}"; ret = 0; goto cleanup; } switch (virJSONValueGetType(obj)) { case VIR_JSON_TYPE_STRING: if (STRNEQ_NULLABLE(t, "string")) goto cleanup; s = virJSONValueGetString(obj); break; case VIR_JSON_TYPE_NUMBER: if (STRNEQ_NULLABLE(t, "int") && STRNEQ_NULLABLE(t, "number")) goto cleanup; s = "{number}"; break; case VIR_JSON_TYPE_BOOLEAN: if (STRNEQ_NULLABLE(t, "boolean")) goto cleanup; virJSONValueGetBoolean(obj, &b); if (b) s = "true"; else s = "false"; break; case VIR_JSON_TYPE_NULL: if (STRNEQ_NULLABLE(t, "null")) goto cleanup; break; case VIR_JSON_TYPE_OBJECT: case VIR_JSON_TYPE_ARRAY: goto cleanup; } ret = 0; cleanup: if (ret == 0) virBufferAsprintf(debug, "'%s': OK", s); else virBufferAsprintf(debug, "ERROR: expected type '%s', actual type %d", t, virJSONValueGetType(obj)); return ret; }
static virDomainNetDefPtr lxcCreateNetDef(const char *type, const char *linkdev, const char *mac, const char *flag, const char *macvlanmode, const char *name) { virDomainNetDefPtr net = NULL; virMacAddr macAddr; if (VIR_ALLOC(net) < 0) goto error; if (STREQ_NULLABLE(flag, "up")) net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_UP; else net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN; if (VIR_STRDUP(net->ifname_guest, name) < 0) goto error; if (mac && virMacAddrParse(mac, &macAddr) == 0) net->mac = macAddr; if (STREQ(type, "veth")) { if (!linkdev) goto error; net->type = VIR_DOMAIN_NET_TYPE_BRIDGE; if (VIR_STRDUP(net->data.bridge.brname, linkdev) < 0) goto error; } else if (STREQ(type, "macvlan")) { net->type = VIR_DOMAIN_NET_TYPE_DIRECT; if (!linkdev || VIR_STRDUP(net->data.direct.linkdev, linkdev) < 0) goto error; if (!macvlanmode || STREQ(macvlanmode, "private")) net->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_PRIVATE; else if (STREQ(macvlanmode, "vepa")) net->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_VEPA; else if (STREQ(macvlanmode, "bridge")) net->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_BRIDGE; else VIR_WARN("Unknown macvlan type: %s", macvlanmode); } return net; error: virDomainNetDefFree(net); return NULL; }
void virSCSIDeviceListDel(virSCSIDeviceListPtr list, virSCSIDevicePtr dev, const char *drvname, const char *domname) { virSCSIDevicePtr tmp = NULL; size_t i; for (i = 0; i < dev->n_used_by; i++) { if (STREQ_NULLABLE(dev->used_by[i]->drvname, drvname) && STREQ_NULLABLE(dev->used_by[i]->domname, domname)) { if (dev->n_used_by > 1) { virSCSIDeviceUsedByInfoFree(dev->used_by[i]); VIR_DELETE_ELEMENT(dev->used_by, i, dev->n_used_by); } else { tmp = virSCSIDeviceListSteal(list, dev); virSCSIDeviceFree(tmp); } break; } } }
static struct cpuArchDriver * cpuGetSubDriverByName(const char *name) { size_t i; for (i = 0; i < ARRAY_CARDINALITY(drivers); i++) { if (STREQ_NULLABLE(name, drivers[i]->name)) return drivers[i]; } virReportError(VIR_ERR_INTERNAL_ERROR, _("CPU driver '%s' does not exist"), name); return NULL; }
/** * virConfSetValue: * @conf: a configuration file handle * @setting: the name of the entry * @value: the new configuration value * * Set (or replace) the value associated to this entry in the configuration * file. The passed in 'value' will be owned by the conf object upon return * of this method, even in case of error. It should not be referenced again * by the caller. * * Returns 0 on success, or -1 on failure. */ int virConfSetValue(virConfPtr conf, const char *setting, virConfValuePtr value) { virConfEntryPtr cur, prev = NULL; if (value && value->type == VIR_CONF_STRING && value->str == NULL) { virConfFreeValue(value); return -1; } cur = conf->entries; while (cur != NULL) { if (STREQ_NULLABLE(cur->name, setting)) break; prev = cur; cur = cur->next; } if (!cur) { if (VIR_ALLOC(cur) < 0) { virConfFreeValue(value); return -1; } cur->comment = NULL; if (VIR_STRDUP(cur->name, setting) < 0) { virConfFreeValue(value); VIR_FREE(cur); return -1; } cur->value = value; if (prev) { cur->next = prev->next; prev->next = cur; } else { cur->next = conf->entries; conf->entries = cur; } } else { virConfFreeValue(cur->value); cur->value = value; } return 0; }
virNWFilterObjPtr virNWFilterObjListFindByName(virNWFilterObjListPtr nwfilters, const char *name) { size_t i; virNWFilterObjPtr obj; virNWFilterDefPtr def; for (i = 0; i < nwfilters->count; i++) { obj = nwfilters->objs[i]; virNWFilterObjLock(obj); def = obj->def; if (STREQ_NULLABLE(def->name, name)) return obj; virNWFilterObjUnlock(obj); } return NULL; }
static virJSONValuePtr testQEMUSchemaStealObjectMemberByName(const char *name, virJSONValuePtr members) { virJSONValuePtr member; virJSONValuePtr ret = NULL; size_t i; for (i = 0; i < virJSONValueArraySize(members); i++) { member = virJSONValueArrayGet(members, i); if (STREQ_NULLABLE(name, virJSONValueObjectGetString(member, "name"))) { ret = virJSONValueArraySteal(members, i); break; } } return ret; }
static virDrvOpenStatus bhyveConnectOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, unsigned int flags) { virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); if (conn->uri == NULL) { if (bhyve_driver == NULL) return VIR_DRV_OPEN_DECLINED; if (!(conn->uri = virURIParse("bhyve:///system"))) return VIR_DRV_OPEN_ERROR; } else { if (!conn->uri->scheme || STRNEQ(conn->uri->scheme, "bhyve")) return VIR_DRV_OPEN_DECLINED; if (conn->uri->server) return VIR_DRV_OPEN_DECLINED; if (!STREQ_NULLABLE(conn->uri->path, "/system")) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unexpected bhyve URI path '%s', try bhyve:///system"), conn->uri->path); return VIR_DRV_OPEN_ERROR; } if (bhyve_driver == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("bhyve state driver is not active")); return VIR_DRV_OPEN_ERROR; } } if (virConnectOpenEnsureACL(conn) < 0) return VIR_DRV_OPEN_ERROR; conn->privateData = bhyve_driver; return VIR_DRV_OPEN_SUCCESS; }
static int virLockManagerSanlockRelease(virLockManagerPtr lock, char **state, unsigned int flags) { virLockManagerSanlockPrivatePtr priv = lock->privateData; int res_count = priv->res_count; int rv; virCheckFlags(0, -1); if (state) { if ((rv = sanlock_inquire(-1, priv->vm_pid, 0, &res_count, state)) < 0) { if (rv <= -200) virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to inquire lock: error %d"), rv); else virReportSystemError(-rv, "%s", _("Failed to inquire lock")); return -1; } if (STREQ_NULLABLE(*state, "")) VIR_FREE(*state); } if ((rv = sanlock_release(-1, priv->vm_pid, 0, res_count, priv->res_args)) < 0) { if (rv <= -200) virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to release lock: error %d"), rv); else virReportSystemError(-rv, "%s", _("Failed to release lock")); return -1; } return 0; }
int virSystemdTerminateMachine(const char *name, const char *drivername, bool privileged) { int ret; DBusConnection *conn; char *machinename = NULL; virError error; memset(&error, 0, sizeof(error)); ret = virDBusIsServiceEnabled("org.freedesktop.machine1"); if (ret < 0) goto cleanup; if ((ret = virDBusIsServiceRegistered("org.freedesktop.systemd1")) < 0) goto cleanup; ret = -1; if (!(conn = virDBusGetSystemBus())) goto cleanup; if (!(machinename = virSystemdMakeMachineName(name, drivername, privileged))) goto cleanup; /* * The systemd DBus API we're invoking has the * following signature * * TerminateMachine(in s name); * * @name a host unique name for the machine. shows up * in 'ps' listing & similar */ VIR_DEBUG("Attempting to terminate machine via systemd"); if (virDBusCallMethod(conn, NULL, &error, "org.freedesktop.machine1", "/org/freedesktop/machine1", "org.freedesktop.machine1.Manager", "TerminateMachine", "s", machinename) < 0) goto cleanup; if (error.code == VIR_ERR_ERROR && !STREQ_NULLABLE("org.freedesktop.machine1.NoSuchMachine", error.str1)) { virReportErrorObject(&error); goto cleanup; } ret = 0; cleanup: virResetError(&error); VIR_FREE(machinename); return ret; }
int virAuthGetConfigFilePathURI(virURIPtr uri, char **path) { int ret = -1; size_t i; const char *authenv = virGetEnvBlockSUID("LIBVIRT_AUTH_FILE"); char *userdir = NULL; *path = NULL; VIR_DEBUG("Determining auth config file path"); if (authenv) { VIR_DEBUG("Using path from env '%s'", authenv); if (VIR_STRDUP(*path, authenv) < 0) goto cleanup; return 0; } if (uri) { for (i = 0; i < uri->paramsCount; i++) { if (STREQ_NULLABLE(uri->params[i].name, "authfile") && uri->params[i].value) { VIR_DEBUG("Using path from URI '%s'", uri->params[i].value); if (VIR_STRDUP(*path, uri->params[i].value) < 0) goto cleanup; return 0; } } } if (!(userdir = virGetUserConfigDirectory())) goto cleanup; if (virAsprintf(path, "%s/auth.conf", userdir) < 0) goto cleanup; VIR_DEBUG("Checking for readability of '%s'", *path); if (access(*path, R_OK) == 0) goto done; VIR_FREE(*path); if (VIR_STRDUP(*path, SYSCONFDIR "/libvirt/auth.conf") < 0) goto cleanup; VIR_DEBUG("Checking for readability of '%s'", *path); if (access(*path, R_OK) == 0) goto done; VIR_FREE(*path); done: ret = 0; VIR_DEBUG("Using auth file '%s'", NULLSTR(*path)); cleanup: VIR_FREE(userdir); return ret; }
int virAuthGetConfigFilePath(virConnectPtr conn, char **path) { int ret = -1; size_t i; const char *authenv = getenv("LIBVIRT_AUTH_FILE"); char *userdir = NULL; *path = NULL; VIR_DEBUG("Determining auth config file path"); if (authenv) { VIR_DEBUG("Using path from env '%s'", authenv); if (!(*path = strdup(authenv))) goto no_memory; return 0; } if (conn && conn->uri) { for (i = 0 ; i < conn->uri->paramsCount ; i++) { if (STREQ_NULLABLE(conn->uri->params[i].name, "authfile") && conn->uri->params[i].value) { VIR_DEBUG("Using path from URI '%s'", conn->uri->params[i].value); if (!(*path = strdup(conn->uri->params[i].value))) goto no_memory; return 0; } } } if (!(userdir = virGetUserConfigDirectory())) goto cleanup; if (virAsprintf(path, "%s/auth.conf", userdir) < 0) goto no_memory; VIR_DEBUG("Checking for readability of '%s'", *path); if (access(*path, R_OK) == 0) goto done; VIR_FREE(*path); if (!(*path = strdup(SYSCONFDIR "/libvirt/auth.conf"))) goto no_memory; VIR_DEBUG("Checking for readability of '%s'", *path); if (access(*path, R_OK) == 0) goto done; VIR_FREE(*path); done: ret = 0; VIR_DEBUG("Using auth file '%s'", NULLSTR(*path)); cleanup: VIR_FREE(userdir); return ret; no_memory: virReportOOMError(); goto cleanup; }
/** * testQEMUSchemaValidateObjectMergeVariant: * * Merges schema of variant @variantname in @root into @root and removes the * 'variants' array from @root. */ static int testQEMUSchemaValidateObjectMergeVariant(virJSONValuePtr root, const char *variantfield, const char *variantname, virHashTablePtr schema, virBufferPtr debug) { size_t i; virJSONValuePtr variants = NULL; virJSONValuePtr variant; virJSONValuePtr variantschema; virJSONValuePtr variantschemamembers; virJSONValuePtr rootmembers; const char *varianttype = NULL; int ret = -1; if (!(variants = virJSONValueObjectStealArray(root, "variants"))) { virBufferAddLit(debug, "ERROR: missing 'variants' in schema\n"); return -2; } for (i = 0; i < virJSONValueArraySize(variants); i++) { variant = virJSONValueArrayGet(variants, i); if (STREQ_NULLABLE(variantname, virJSONValueObjectGetString(variant, "case"))) { varianttype = virJSONValueObjectGetString(variant, "type"); break; } } if (!varianttype) { virBufferAsprintf(debug, "ERROR: variant '%s' for discriminator '%s' not found\n", variantname, variantfield); goto cleanup; } if (!(variantschema = virHashLookup(schema, varianttype)) || !(variantschemamembers = virJSONValueObjectGetArray(variantschema, "members"))) { virBufferAsprintf(debug, "ERROR: missing schema or schema members for variant '%s'(%s)\n", variantname, varianttype); ret = -2; goto cleanup; } rootmembers = virJSONValueObjectGetArray(root, "members"); if (virJSONValueArrayForeachSteal(variantschemamembers, testQEMUSchemaValidateObjectMergeVariantMember, rootmembers) < 0) { ret = -2; goto cleanup; } ret = 0; cleanup: virJSONValueFree(variants); return ret; }
static const char * qemuAgentStringifyErrorClass(const char *klass) { if (STREQ_NULLABLE(klass, "BufferOverrun")) return "Buffer overrun"; else if (STREQ_NULLABLE(klass, "CommandDisabled")) return "The command has been disabled for this instance"; else if (STREQ_NULLABLE(klass, "CommandNotFound")) return "The command has not been found"; else if (STREQ_NULLABLE(klass, "FdNotFound")) return "File descriptor not found"; else if (STREQ_NULLABLE(klass, "InvalidParameter")) return "Invalid parameter"; else if (STREQ_NULLABLE(klass, "InvalidParameterType")) return "Invalid parameter type"; else if (STREQ_NULLABLE(klass, "InvalidParameterValue")) return "Invalid parameter value"; else if (STREQ_NULLABLE(klass, "OpenFileFailed")) return "Cannot open file"; else if (STREQ_NULLABLE(klass, "QgaCommandFailed")) return "Guest agent command failed"; else if (STREQ_NULLABLE(klass, "QMPBadInputObjectMember")) return "Bad QMP input object member"; else if (STREQ_NULLABLE(klass, "QMPExtraInputObjectMember")) return "Unexpected extra object member"; else if (STREQ_NULLABLE(klass, "UndefinedError")) return "An undefined error has occurred"; else if (STREQ_NULLABLE(klass, "Unsupported")) return "this feature or command is not currently supported"; else if (klass) return klass; else return "unknown QEMU command error"; }
void qemuDomainReAttachHostScsiDevices(virQEMUDriverPtr driver, const char *name, virDomainHostdevDefPtr *hostdevs, int nhostdevs) { int i; virObjectLock(driver->activeScsiHostdevs); for (i = 0; i < nhostdevs; i++) { virDomainHostdevDefPtr hostdev = hostdevs[i]; virSCSIDevicePtr scsi, tmp; const char *used_by = NULL; virDomainDeviceDef dev; dev.type = VIR_DOMAIN_DEVICE_HOSTDEV; dev.data.hostdev = hostdev; ignore_value(qemuRemoveSharedDevice(driver, &dev, name)); if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) continue; if (!(scsi = virSCSIDeviceNew(hostdev->source.subsys.u.scsi.adapter, hostdev->source.subsys.u.scsi.bus, hostdev->source.subsys.u.scsi.target, hostdev->source.subsys.u.scsi.unit, hostdev->readonly))) { VIR_WARN("Unable to reattach SCSI device %s:%d:%d:%d on domain %s", hostdev->source.subsys.u.scsi.adapter, hostdev->source.subsys.u.scsi.bus, hostdev->source.subsys.u.scsi.target, hostdev->source.subsys.u.scsi.unit, name); continue; } /* Only delete the devices which are marked as being used by @name, * because qemuProcessStart could fail on the half way. */ tmp = virSCSIDeviceListFind(driver->activeScsiHostdevs, scsi); virSCSIDeviceFree(scsi); if (!tmp) { VIR_WARN("Unable to find device %s:%d:%d:%d " "in list of active SCSI devices", hostdev->source.subsys.u.scsi.adapter, hostdev->source.subsys.u.scsi.bus, hostdev->source.subsys.u.scsi.target, hostdev->source.subsys.u.scsi.unit); continue; } used_by = virSCSIDeviceGetUsedBy(tmp); if (STREQ_NULLABLE(used_by, name)) { VIR_DEBUG("Removing %s:%d:%d:%d dom=%s from activeScsiHostdevs", hostdev->source.subsys.u.scsi.adapter, hostdev->source.subsys.u.scsi.bus, hostdev->source.subsys.u.scsi.target, hostdev->source.subsys.u.scsi.unit, name); virSCSIDeviceListDel(driver->activeScsiHostdevs, tmp); } } virObjectUnlock(driver->activeScsiHostdevs); }
static int xenFormatXLDisk(virConfValuePtr list, virDomainDiskDefPtr disk) { virBuffer buf = VIR_BUFFER_INITIALIZER; virConfValuePtr val, tmp; int format = virDomainDiskGetFormat(disk); const char *driver = virDomainDiskGetDriver(disk); char *target = NULL; /* format */ virBufferAddLit(&buf, "format="); switch (format) { case VIR_STORAGE_FILE_RAW: virBufferAddLit(&buf, "raw,"); break; case VIR_STORAGE_FILE_VHD: virBufferAddLit(&buf, "xvhd,"); break; case VIR_STORAGE_FILE_QCOW: virBufferAddLit(&buf, "qcow,"); break; case VIR_STORAGE_FILE_QCOW2: virBufferAddLit(&buf, "qcow2,"); break; /* set default */ default: virBufferAddLit(&buf, "raw,"); } /* device */ virBufferAsprintf(&buf, "vdev=%s,", disk->dst); /* access */ virBufferAddLit(&buf, "access="); if (disk->src->readonly) virBufferAddLit(&buf, "ro,"); else if (disk->src->shared) virBufferAddLit(&buf, "!,"); else virBufferAddLit(&buf, "rw,"); if (disk->transient) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("transient disks not supported yet")); goto cleanup; } /* backendtype */ virBufferAddLit(&buf, "backendtype="); if (STREQ_NULLABLE(driver, "qemu")) virBufferAddLit(&buf, "qdisk,"); else if (STREQ_NULLABLE(driver, "tap")) virBufferAddLit(&buf, "tap,"); else if (STREQ_NULLABLE(driver, "phy")) virBufferAddLit(&buf, "phy,"); /* devtype */ if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) virBufferAddLit(&buf, "devtype=cdrom,"); /* * target * From $xensrc/docs/misc/xl-disk-configuration.txt: * When this parameter is specified by name, ie with the "target=" * syntax in the configuration file, it consumes the whole rest of the * <diskspec> including trailing whitespaces. Therefore in that case * it must come last. */ if (xenFormatXLDiskSrc(disk->src, &target) < 0) goto cleanup; virBufferAsprintf(&buf, "target=%s", target); if (virBufferCheckError(&buf) < 0) goto cleanup; if (VIR_ALLOC(val) < 0) goto cleanup; val->type = VIR_CONF_STRING; val->str = virBufferContentAndReset(&buf); tmp = list->list; while (tmp && tmp->next) tmp = tmp->next; if (tmp) tmp->next = val; else list->list = val; return 0; cleanup: VIR_FREE(target); virBufferFreeAndReset(&buf); return -1; }
static int xenFormatXLDisk(virConfValuePtr list, virDomainDiskDefPtr disk) { virBuffer buf = VIR_BUFFER_INITIALIZER; virConfValuePtr val, tmp; const char *src = virDomainDiskGetSource(disk); int format = virDomainDiskGetFormat(disk); const char *driver = virDomainDiskGetDriver(disk); /* target */ virBufferAsprintf(&buf, "%s,", src); /* format */ switch (format) { case VIR_STORAGE_FILE_RAW: virBufferAddLit(&buf, "raw,"); break; case VIR_STORAGE_FILE_VHD: virBufferAddLit(&buf, "xvhd,"); break; case VIR_STORAGE_FILE_QCOW: virBufferAddLit(&buf, "qcow,"); break; case VIR_STORAGE_FILE_QCOW2: virBufferAddLit(&buf, "qcow2,"); break; /* set default */ default: virBufferAddLit(&buf, "raw,"); } /* device */ virBufferAdd(&buf, disk->dst, -1); virBufferAddLit(&buf, ","); if (disk->src->readonly) virBufferAddLit(&buf, "r,"); else if (disk->src->shared) virBufferAddLit(&buf, "!,"); else virBufferAddLit(&buf, "w,"); if (disk->transient) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("transient disks not supported yet")); goto cleanup; } if (STREQ_NULLABLE(driver, "qemu")) virBufferAddLit(&buf, "backendtype=qdisk"); else if (STREQ_NULLABLE(driver, "tap")) virBufferAddLit(&buf, "backendtype=tap"); else if (STREQ_NULLABLE(driver, "phy")) virBufferAddLit(&buf, "backendtype=phy"); if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) virBufferAddLit(&buf, ",devtype=cdrom"); if (virBufferCheckError(&buf) < 0) goto cleanup; if (VIR_ALLOC(val) < 0) goto cleanup; val->type = VIR_CONF_STRING; val->str = virBufferContentAndReset(&buf); tmp = list->list; while (tmp && tmp->next) tmp = tmp->next; if (tmp) tmp->next = val; else list->list = val; return 0; cleanup: virBufferFreeAndReset(&buf); return -1; }
static char * getSocketPath(const char *name) { char *rundir = virGetUserRuntimeDirectory(); char *sock_path = NULL; size_t i = 0; virURIPtr uri = NULL; if (name) { if (!(uri = virURIParse(name))) goto error; if (STRNEQ(uri->scheme, "admin") || uri->server || uri->user || uri->fragment) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid connection name '%s'"), name); goto error; } for (i = 0; i < uri->paramsCount; i++) { virURIParamPtr param = &uri->params[i]; if (STREQ(param->name, "socket")) { VIR_FREE(sock_path); if (VIR_STRDUP(sock_path, param->value) < 0) goto error; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unknown URI parameter '%s'"), param->name); goto error; } } } if (!sock_path) { if (!uri || !uri->path || STREQ(uri->path, "/system")) { if (VIR_STRDUP(sock_path, LIBVIRTD_ADMIN_UNIX_SOCKET) < 0) goto error; } else if (STREQ_NULLABLE(uri->path, "/session")) { if (!rundir) goto error; if (virAsprintf(&sock_path, "%s%s", rundir, LIBVIRTD_ADMIN_SOCK_NAME) < 0) goto error; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Invalid URI path '%s'"), uri->path); goto error; } } cleanup: VIR_FREE(rundir); virURIFree(uri); return sock_path; error: VIR_FREE(sock_path); goto cleanup; }
static int xenParseXMDisk(virConfPtr conf, virDomainDefPtr def) { virDomainDiskDefPtr disk = NULL; int hvm = def->os.type == VIR_DOMAIN_OSTYPE_HVM; virConfValuePtr list = virConfGetValue(conf, "disk"); if (list && list->type == VIR_CONF_LIST) { list = list->list; while (list) { char *head; char *offset; char *tmp; const char *src; if ((list->type != VIR_CONF_STRING) || (list->str == NULL)) goto skipdisk; head = list->str; if (!(disk = virDomainDiskDefNew(NULL))) return -1; /* * Disks have 3 components, SOURCE,DEST-DEVICE,MODE * eg, phy:/dev/HostVG/XenGuest1,xvda,w * The SOURCE is usually prefixed with a driver type, * and optionally driver sub-type * The DEST-DEVICE is optionally post-fixed with disk type */ /* Extract the source file path*/ if (!(offset = strchr(head, ','))) goto skipdisk; if (offset == head) { /* No source file given, eg CDROM with no media */ ignore_value(virDomainDiskSetSource(disk, NULL)); } else { if (VIR_STRNDUP(tmp, head, offset - head) < 0) goto cleanup; if (virDomainDiskSetSource(disk, tmp) < 0) { VIR_FREE(tmp); goto cleanup; } VIR_FREE(tmp); } head = offset + 1; /* Remove legacy ioemu: junk */ if (STRPREFIX(head, "ioemu:")) head = head + 6; /* Extract the dest device name */ if (!(offset = strchr(head, ','))) goto skipdisk; if (VIR_ALLOC_N(disk->dst, (offset - head) + 1) < 0) goto cleanup; if (virStrncpy(disk->dst, head, offset - head, (offset - head) + 1) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Dest file %s too big for destination"), head); goto cleanup; } head = offset + 1; /* Extract source driver type */ src = virDomainDiskGetSource(disk); if (src) { size_t len; /* The main type phy:, file:, tap: ... */ if ((tmp = strchr(src, ':')) != NULL) { len = tmp - src; if (VIR_STRNDUP(tmp, src, len) < 0) goto cleanup; if (virDomainDiskSetDriver(disk, tmp) < 0) { VIR_FREE(tmp); goto cleanup; } VIR_FREE(tmp); /* Strip the prefix we found off the source file name */ if (virDomainDiskSetSource(disk, src + len + 1) < 0) goto cleanup; src = virDomainDiskGetSource(disk); } /* And the sub-type for tap:XXX: type */ if (STREQ_NULLABLE(virDomainDiskGetDriver(disk), "tap")) { char *driverType; if (!(tmp = strchr(src, ':'))) goto skipdisk; len = tmp - src; if (VIR_STRNDUP(driverType, src, len) < 0) goto cleanup; if (STREQ(driverType, "aio")) virDomainDiskSetFormat(disk, VIR_STORAGE_FILE_RAW); else virDomainDiskSetFormat(disk, virStorageFileFormatTypeFromString(driverType)); VIR_FREE(driverType); if (virDomainDiskGetFormat(disk) <= 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unknown driver type %s"), src); goto cleanup; } /* Strip the prefix we found off the source file name */ if (virDomainDiskSetSource(disk, src + len + 1) < 0) goto cleanup; src = virDomainDiskGetSource(disk); } } /* No source, or driver name, so fix to phy: */ if (!virDomainDiskGetDriver(disk) && virDomainDiskSetDriver(disk, "phy") < 0) goto cleanup; /* phy: type indicates a block device */ virDomainDiskSetType(disk, STREQ(virDomainDiskGetDriver(disk), "phy") ? VIR_STORAGE_TYPE_BLOCK : VIR_STORAGE_TYPE_FILE); /* Check for a :cdrom/:disk postfix */ disk->device = VIR_DOMAIN_DISK_DEVICE_DISK; if ((tmp = strchr(disk->dst, ':')) != NULL) { if (STREQ(tmp, ":cdrom")) disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM; tmp[0] = '\0'; } if (STRPREFIX(disk->dst, "xvd") || !hvm) { disk->bus = VIR_DOMAIN_DISK_BUS_XEN; } else if (STRPREFIX(disk->dst, "sd")) { disk->bus = VIR_DOMAIN_DISK_BUS_SCSI; } else { disk->bus = VIR_DOMAIN_DISK_BUS_IDE; } if (STREQ(head, "r") || STREQ(head, "ro")) disk->src->readonly = true; else if ((STREQ(head, "w!")) || (STREQ(head, "!"))) disk->src->shared = true; /* Maintain list in sorted order according to target device name */ if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0) goto cleanup; skipdisk: list = list->next; virDomainDiskDefFree(disk); disk = NULL; } } return 0; cleanup: virDomainDiskDefFree(disk); return -1; }
static int testURIParse(const void *args) { int ret = -1; virURIPtr uri = NULL; const struct URIParseData *data = args; char *uristr = NULL; size_t i; if (!(uri = virURIParse(data->uri))) goto cleanup; if (!STREQ(uri->scheme, data->scheme)) { VIR_DEBUG("Expected scheme '%s', actual '%s'", data->scheme, uri->scheme); goto cleanup; } if (!STREQ(uri->server, data->server)) { VIR_DEBUG("Expected server '%s', actual '%s'", data->server, uri->server); goto cleanup; } if (uri->port != data->port) { VIR_DEBUG("Expected port '%d', actual '%d'", data->port, uri->port); goto cleanup; } if (!STREQ_NULLABLE(uri->path, data->path)) { VIR_DEBUG("Expected path '%s', actual '%s'", data->path, uri->path); goto cleanup; } if (!STREQ_NULLABLE(uri->query, data->query)) { VIR_DEBUG("Expected query '%s', actual '%s'", data->query, uri->query); goto cleanup; } if (!STREQ_NULLABLE(uri->fragment, data->fragment)) { VIR_DEBUG("Expected fragment '%s', actual '%s'", data->fragment, uri->fragment); goto cleanup; } for (i = 0; data->params && data->params[i].name && i < uri->paramsCount; i++) { if (!STREQ_NULLABLE(data->params[i].name, uri->params[i].name)) { VIR_DEBUG("Expected param name %zu '%s', actual '%s'", i, data->params[i].name, uri->params[i].name); goto cleanup; } if (!STREQ_NULLABLE(data->params[i].value, uri->params[i].value)) { VIR_DEBUG("Expected param value %zu '%s', actual '%s'", i, data->params[i].value, uri->params[i].value); goto cleanup; } } if (data->params && data->params[i].name) { VIR_DEBUG("Missing parameter %zu %s=%s", i, data->params[i].name, data->params[i].value); goto cleanup; } if (i != uri->paramsCount) { VIR_DEBUG("Unexpected parameter %zu %s=%s", i, uri->params[i].name, uri->params[i].value); goto cleanup; } VIR_FREE(uri->query); uri->query = virURIFormatParams(uri); if (!(uristr = virURIFormat(uri))) goto cleanup; if (!STREQ(uristr, data->uri_out)) { VIR_DEBUG("URI did not roundtrip, expect '%s', actual '%s'", data->uri_out, uristr); goto cleanup; } ret = 0; cleanup: VIR_FREE(uristr); virURIFree(uri); return ret; }