예제 #1
0
static void
qemuRestoreCgroupState(virDomainObjPtr vm)
{
    char *mem_mask = NULL;
    char *nodeset = NULL;
    int empty = -1;
    qemuDomainObjPrivatePtr priv = vm->privateData;
    size_t i = 0;
    virBitmapPtr all_nodes;
    virCgroupPtr cgroup_temp = NULL;

    if (!virNumaIsAvailable() ||
        !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET))
        return;

    if (!(all_nodes = virNumaGetHostMemoryNodeset()))
        goto error;

    if (!(mem_mask = virBitmapFormat(all_nodes)))
        goto error;

    if ((empty = virCgroupHasEmptyTasks(priv->cgroup,
                                        VIR_CGROUP_CONTROLLER_CPUSET)) <= 0)
        goto error;

    if (virCgroupSetCpusetMems(priv->cgroup, mem_mask) < 0)
        goto error;

    for (i = 0; i < virDomainDefGetVcpusMax(vm->def); i++) {
        virDomainVcpuDefPtr vcpu = virDomainDefGetVcpu(vm->def, i);

        if (!vcpu->online)
            continue;

        if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_VCPU, i,
                               false, &cgroup_temp) < 0 ||
            virCgroupSetCpusetMemoryMigrate(cgroup_temp, true) < 0 ||
            virCgroupGetCpusetMems(cgroup_temp, &nodeset) < 0 ||
            virCgroupSetCpusetMems(cgroup_temp, nodeset) < 0)
            goto cleanup;

        VIR_FREE(nodeset);
        virCgroupFree(&cgroup_temp);
    }

    for (i = 0; i < vm->def->niothreadids; i++) {
        if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_IOTHREAD,
                               vm->def->iothreadids[i]->iothread_id,
                               false, &cgroup_temp) < 0 ||
            virCgroupSetCpusetMemoryMigrate(cgroup_temp, true) < 0 ||
            virCgroupGetCpusetMems(cgroup_temp, &nodeset) < 0 ||
            virCgroupSetCpusetMems(cgroup_temp, nodeset) < 0)
            goto cleanup;

        VIR_FREE(nodeset);
        virCgroupFree(&cgroup_temp);
    }

    if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_EMULATOR, 0,
                           false, &cgroup_temp) < 0 ||
        virCgroupSetCpusetMemoryMigrate(cgroup_temp, true) < 0 ||
        virCgroupGetCpusetMems(cgroup_temp, &nodeset) < 0 ||
        virCgroupSetCpusetMems(cgroup_temp, nodeset) < 0)
        goto cleanup;

 cleanup:
    VIR_FREE(mem_mask);
    VIR_FREE(nodeset);
    virBitmapFree(all_nodes);
    virCgroupFree(&cgroup_temp);
    return;

 error:
    virResetLastError();
    VIR_DEBUG("Couldn't restore cgroups to meaningful state");
    goto cleanup;
}
예제 #2
0
int lxctoolsReadConfig(struct lxc_container* cont, virDomainDefPtr def)
{
    char* item_str = NULL;
    virNodeInfoPtr nodeinfo = NULL;
    lxctoolsConffilePtr conffile = NULL;

    if (VIR_ALLOC(nodeinfo) < 0) {
        goto error;
    }
    
    if (virCapabilitiesGetNodeInfo(nodeinfo) < 0) {
        goto error;
    }
    
    if (VIR_ALLOC(conffile) < 0)
        goto error;

    if (lxctoolsConffileRead(conffile, cont->config_file_name(cont)) < 0) {
        virReportError(VIR_ERR_OPERATION_FAILED, "'%s'", _("failed to read conffile"));
        goto error;
    }
    if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.arch")) == NULL) {
        goto error;
    }
    if (item_str[0] != '\0') {
        if (strcmp(item_str, "x86") == 0 || strcmp(item_str, "i686")  == 0) {
            def->os.arch = VIR_ARCH_I686;
        }
        else if (strcmp(item_str, "x86_64") == 0 || strcmp(item_str, "amd64") == 0) {
            def->os.arch = VIR_ARCH_X86_64;
        } else {
            virReportError(VIR_ERR_OPERATION_FAILED, "Unknown architecture '%s'.", item_str);
            goto error;
        }
    }
    VIR_FREE(item_str);
    item_str = NULL;

    if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.cpuset.cpus")) == NULL){
        goto error;
    }
    if (item_str[0] == '\0') {
        if (virDomainDefSetVcpusMax(def, nodeinfo->cpus, NULL) < 0)
            goto error;
        def->cpumask = virBitmapNew(nodeinfo->cpus);
        virBitmapSetAll(def->cpumask);
    } else {
        int cpunum;
        if ( (cpunum = virBitmapParse(item_str, &def->cpumask, nodeinfo->cpus) ) < 0) {
            goto error;
        }  
        if (virDomainDefSetVcpusMax(def, cpunum, NULL) < 0)
            goto error;
    }

    if (virDomainDefSetVcpus(def, virDomainDefGetVcpusMax(def)) < 0)
        goto error;
   
    VIR_FREE(item_str);
    item_str = NULL;

    if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.cpu.shares")) == NULL) {
        goto error;
    }
    if (item_str[0] != '\0') {
        unsigned long shares;
        sscanf(item_str, "%lu", &shares);
        def->cputune.shares = shares;
        def->cputune.sharesSpecified = true;
    }

    VIR_FREE(item_str);
    item_str = NULL;

    if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.cpu.cfs_period_us")) == NULL) {
        goto error;
    }
    if (item_str[0] != '\0') {
        unsigned long long period;
        sscanf(item_str, "%llu", &period);
        def->cputune.period = period;
    }

    VIR_FREE(item_str);
    item_str = NULL;

    if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.cpu.cfs_quota_us")) == NULL) {
        goto error;
    }
    if (item_str[0] != '\0') {
        long long quota;
        sscanf(item_str, "%llu", &quota);
        def->cputune.quota = quota;
    }

    VIR_FREE(item_str);
    item_str = NULL;


    if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.memory.limit_in_bytes")) == NULL) {
        goto error;
    }
    if (item_str[0] == '\0') {
        virDomainDefSetMemoryTotal(def, nodeinfo->memory);
    } else {
        virDomainDefSetMemoryTotal(def, memToULL(item_str)); 
    }


    def->mem.cur_balloon = virDomainDefGetMemoryTotal(def);
//    def->mem.max_memory = nodeinfo->memory;
//    def->mem.memory_slots = 1; //maybe delete max_memory alltogether

    VIR_FREE(item_str);
    item_str = NULL;
    if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.memory.soft_limit_in_bytes")) == NULL) {
        goto error;
    }
    if (item_str[0] != '\0') {
        def->mem.soft_limit = memToULL(item_str);
    }

    VIR_FREE(item_str);
    item_str = NULL;

    if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.cgroup.cpuset.mems")) == NULL) {
        goto error;
    }
    if (item_str[0] != '\0') {
        virBitmapPtr nodeset;
        if (virBitmapParse(item_str, &nodeset, nodeinfo->nodes) < 0) {
            goto error;
        }  
        if (virDomainNumatuneSet(def->numa,
                             true,
                             VIR_DOMAIN_NUMATUNE_PLACEMENT_DEFAULT,
                             VIR_DOMAIN_NUMATUNE_MEM_STRICT,
                             nodeset) < 0 ) {
            goto error;
        }
    }

    VIR_FREE(item_str);
    item_str = NULL;

    if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.include")) == NULL) {
        goto error;
    }

    //lxc.include is optional!
    if (item_str[0] != '\0') {
        def->metadata = xmlNewNode(NULL, (const xmlChar*) "metadata");
        xmlNewTextChild(def->metadata, NULL, (const xmlChar*) (const xmlChar*)"lxctools:include", (const xmlChar*)item_str);
    }

    VIR_FREE(item_str);
    item_str = NULL;
    if (lxctoolsReadFSConfig(conffile, def) < 0)
        goto error;

    if (lxctoolsReadNetConfig(cont, def) < 0)
        goto error;

    return 0;
 error:
    VIR_FREE(item_str);
    VIR_FREE(nodeinfo);
    return -1;
}