예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
/* 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;
}
예제 #4
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;
}