virDomainDefPtr lxcParseConfigString(const char *config, virCapsPtr caps, virDomainXMLOptionPtr xmlopt) { virDomainDefPtr vmdef = NULL; virConfPtr properties = NULL; virConfValuePtr value; if (!(properties = virConfReadMem(config, 0, VIR_CONF_FLAG_LXC_FORMAT))) return NULL; if (!(vmdef = virDomainDefNew())) goto error; if (virUUIDGenerate(vmdef->uuid) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("failed to generate uuid")); goto error; } vmdef->id = -1; virDomainDefSetMemoryTotal(vmdef, 64 * 1024); vmdef->onReboot = VIR_DOMAIN_LIFECYCLE_RESTART; vmdef->onCrash = VIR_DOMAIN_LIFECYCLE_CRASH_DESTROY; vmdef->onPoweroff = VIR_DOMAIN_LIFECYCLE_DESTROY; vmdef->virtType = VIR_DOMAIN_VIRT_LXC; /* Value not handled by the LXC driver, setting to * minimum required to make XML parsing pass */ if (virDomainDefSetVcpusMax(vmdef, 1) < 0) goto error; if (virDomainDefSetVcpus(vmdef, 1) < 0) goto error; vmdef->nfss = 0; vmdef->os.type = VIR_DOMAIN_OSTYPE_EXE; if ((value = virConfGetValue(properties, "lxc.arch")) && value->str) { virArch arch = virArchFromString(value->str); if (arch == VIR_ARCH_NONE && STREQ(value->str, "x86")) arch = VIR_ARCH_I686; else if (arch == VIR_ARCH_NONE && STREQ(value->str, "amd64")) arch = VIR_ARCH_X86_64; vmdef->os.arch = arch; } if (VIR_STRDUP(vmdef->os.init, "/sbin/init") < 0) goto error; if (!(value = virConfGetValue(properties, "lxc.utsname")) || !value->str || (VIR_STRDUP(vmdef->name, value->str) < 0)) goto error; if (!vmdef->name && (VIR_STRDUP(vmdef->name, "unnamed") < 0)) goto error; if (lxcSetRootfs(vmdef, properties) < 0) goto error; /* Look for fstab: we shouldn't have it */ if (virConfGetValue(properties, "lxc.mount")) { virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", _("lxc.mount found, use lxc.mount.entry lines instead")); goto error; } /* Loop over lxc.mount.entry to add filesystem devices for them */ if (virConfWalk(properties, lxcFstabWalkCallback, vmdef) < 0) goto error; /* Network configuration */ if (lxcConvertNetworkSettings(vmdef, properties) < 0) goto error; /* Consoles */ if (lxcCreateConsoles(vmdef, properties) < 0) goto error; /* lxc.id_map */ if (virConfWalk(properties, lxcIdmapWalkCallback, vmdef) < 0) goto error; /* lxc.cgroup.memory.* */ if (lxcSetMemTune(vmdef, properties) < 0) goto error; /* lxc.cgroup.cpu.* */ if (lxcSetCpuTune(vmdef, properties) < 0) goto error; /* lxc.cgroup.cpuset.* */ if (lxcSetCpusetTune(vmdef, properties) < 0) goto error; /* lxc.cgroup.blkio.* */ if (lxcSetBlkioTune(vmdef, properties) < 0) goto error; /* lxc.cap.drop */ lxcSetCapDrop(vmdef, properties); if (virDomainDefPostParse(vmdef, caps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE, xmlopt) < 0) goto cleanup; goto cleanup; error: virDomainDefFree(vmdef); vmdef = NULL; cleanup: virConfFree(properties); return vmdef; }
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; }
/* virNetDevVPortProfileCheckComplete() checks that all attributes * required for the type of virtport are specified. When * generateMissing is true, any missing attribute that can be * autogenerated, will be (instanceid, interfaceid). If virtport == * NULL or virtPortType == NONE, then the result is always 0 * (success). If a required attribute is missing, an error is logged * and -1 is returned. */ int virNetDevVPortProfileCheckComplete(virNetDevVPortProfilePtr virtport, bool generateMissing) { const char *missing = NULL; if (!virtport || virtport->virtPortType == VIR_NETDEV_VPORT_PROFILE_NONE) return 0; switch (virtport->virtPortType) { case VIR_NETDEV_VPORT_PROFILE_8021QBG: if (!virtport->managerID_specified) { missing = "managerid"; } else if (!virtport->typeID_specified) { missing = "typeid"; } else if (!virtport->typeIDVersion_specified) { missing = "typeidversion"; } else if (!virtport->instanceID_specified) { if (generateMissing) { if (virUUIDGenerate(virtport->instanceID) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot generate a random uuid for instanceid")); return -1; } virtport->instanceID_specified = true; } else { missing = "instanceid"; } } break; case VIR_NETDEV_VPORT_PROFILE_8021QBH: if (!virtport->profileID[0]) missing = "profileid"; break; case VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH: /* profileid is optional for openvswitch */ if (!virtport->interfaceID_specified) { if (generateMissing) { if (virUUIDGenerate(virtport->interfaceID) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot generate a random uuid for interfaceid")); return -1; } virtport->interfaceID_specified = true; } else { missing = "interfaceid"; } } break; } if (missing) { virReportError(VIR_ERR_XML_ERROR, _("missing %s in <virtualport type='%s'>"), missing, virNetDevVPortTypeToString(virtport->virtPortType)); return -1; } return 0; }
static virSecretDefPtr secretXMLParseNode(xmlDocPtr xml, xmlNodePtr root) { xmlXPathContextPtr ctxt = NULL; virSecretDefPtr def = NULL, ret = NULL; char *prop = NULL; char *uuidstr = NULL; if (!xmlStrEqual(root->name, BAD_CAST "secret")) { virReportError(VIR_ERR_XML_ERROR, _("unexpected root element <%s>, " "expecting <secret>"), root->name); goto cleanup; } ctxt = xmlXPathNewContext(xml); if (ctxt == NULL) { virReportOOMError(); goto cleanup; } ctxt->node = root; if (VIR_ALLOC(def) < 0) goto cleanup; prop = virXPathString("string(./@ephemeral)", ctxt); if (prop != NULL) { if (STREQ(prop, "yes")) { def->isephemeral = true; } else if (STREQ(prop, "no")) { def->isephemeral = false; } else { virReportError(VIR_ERR_XML_ERROR, "%s", _("invalid value of 'ephemeral'")); goto cleanup; } VIR_FREE(prop); } prop = virXPathString("string(./@private)", ctxt); if (prop != NULL) { if (STREQ(prop, "yes")) { def->isprivate = true; } else if (STREQ(prop, "no")) { def->isprivate = false; } else { virReportError(VIR_ERR_XML_ERROR, "%s", _("invalid value of 'private'")); goto cleanup; } VIR_FREE(prop); } uuidstr = virXPathString("string(./uuid)", ctxt); if (!uuidstr) { if (virUUIDGenerate(def->uuid)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Failed to generate UUID")); goto cleanup; } } else { if (virUUIDParse(uuidstr, def->uuid) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("malformed uuid element")); goto cleanup; } VIR_FREE(uuidstr); } def->description = virXPathString("string(./description)", ctxt); if (virXPathNode("./usage", ctxt) != NULL && virSecretDefParseUsage(ctxt, def) < 0) goto cleanup; ret = def; def = NULL; cleanup: VIR_FREE(prop); VIR_FREE(uuidstr); virSecretDefFree(def); xmlXPathFreeContext(ctxt); 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; }