mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 18:21:39 +01:00
Carve out all libxenlight related sources and move them to tools/libs/light in order to use the generic library build environment. The closely related sources for libxl-save-helper and the libxl test environment are being moved, too. Signed-off-by: Juergen Gross <jgross@suse.com> Acked-by: Wei Liu <wl@xen.org>
453 lines
10 KiB
C
453 lines
10 KiB
C
/*
|
|
* Copyright 2009-2017 Citrix Ltd and other contributors
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published
|
|
* by the Free Software Foundation; version 2.1 only. with the special
|
|
* exception on linking described in file LICENSE.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*/
|
|
|
|
#include "libxl_osdeps.h"
|
|
|
|
#include "libxl_internal.h"
|
|
|
|
/* Returns:
|
|
* 0 - success
|
|
* ERROR_FAIL + errno == ENOENT - no entry found
|
|
* ERROR_$FOO + errno != ENOENT - other failure
|
|
*/
|
|
static int cpupool_info(libxl__gc *gc,
|
|
libxl_cpupoolinfo *info,
|
|
uint32_t poolid,
|
|
bool exact /* exactly poolid or >= poolid */)
|
|
{
|
|
xc_cpupoolinfo_t *xcinfo;
|
|
int rc = ERROR_FAIL;
|
|
|
|
xcinfo = xc_cpupool_getinfo(CTX->xch, poolid);
|
|
if (xcinfo == NULL)
|
|
{
|
|
if (exact || errno != ENOENT)
|
|
LOGE(ERROR, "failed to get info for cpupool%d", poolid);
|
|
return ERROR_FAIL;
|
|
}
|
|
|
|
if (exact && xcinfo->cpupool_id != poolid)
|
|
{
|
|
LOG(ERROR, "got info for cpupool%d, wanted cpupool%d\n",
|
|
xcinfo->cpupool_id, poolid);
|
|
goto out;
|
|
}
|
|
|
|
info->poolid = xcinfo->cpupool_id;
|
|
info->pool_name = libxl_cpupoolid_to_name(CTX, info->poolid);
|
|
if (!info->pool_name) {
|
|
rc = ERROR_FAIL;
|
|
goto out;
|
|
}
|
|
info->sched = xcinfo->sched_id;
|
|
info->n_dom = xcinfo->n_dom;
|
|
rc = libxl_cpu_bitmap_alloc(CTX, &info->cpumap, 0);
|
|
if (rc)
|
|
goto out;
|
|
|
|
memcpy(info->cpumap.map, xcinfo->cpumap, info->cpumap.size);
|
|
|
|
rc = 0;
|
|
out:
|
|
xc_cpupool_infofree(CTX->xch, xcinfo);
|
|
return rc;
|
|
}
|
|
|
|
int libxl_cpupool_info(libxl_ctx *ctx,
|
|
libxl_cpupoolinfo *info, uint32_t poolid)
|
|
{
|
|
GC_INIT(ctx);
|
|
int rc = cpupool_info(gc, info, poolid, true);
|
|
GC_FREE;
|
|
return rc;
|
|
}
|
|
|
|
libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx *ctx, int *nb_pool_out)
|
|
{
|
|
GC_INIT(ctx);
|
|
libxl_cpupoolinfo info, *ptr;
|
|
|
|
int i;
|
|
uint32_t poolid;
|
|
|
|
ptr = NULL;
|
|
|
|
poolid = 0;
|
|
for (i = 0;; i++) {
|
|
libxl_cpupoolinfo_init(&info);
|
|
if (cpupool_info(gc, &info, poolid, false)) {
|
|
libxl_cpupoolinfo_dispose(&info);
|
|
if (errno != ENOENT) goto out;
|
|
break;
|
|
}
|
|
|
|
ptr = libxl__realloc(NOGC, ptr, (i+1) * sizeof(libxl_cpupoolinfo));
|
|
ptr[i] = info;
|
|
poolid = info.poolid + 1;
|
|
/* Don't dispose of info because it will be returned to caller */
|
|
}
|
|
|
|
*nb_pool_out = i;
|
|
|
|
GC_FREE;
|
|
return ptr;
|
|
|
|
out:
|
|
libxl_cpupoolinfo_list_free(ptr, i);
|
|
*nb_pool_out = 0;
|
|
GC_FREE;
|
|
return NULL;
|
|
}
|
|
|
|
int libxl_get_freecpus(libxl_ctx *ctx, libxl_bitmap *cpumap)
|
|
{
|
|
int ncpus;
|
|
|
|
ncpus = libxl_get_max_cpus(ctx);
|
|
if (ncpus < 0)
|
|
return ncpus;
|
|
|
|
cpumap->map = xc_cpupool_freeinfo(ctx->xch);
|
|
if (cpumap->map == NULL)
|
|
return ERROR_FAIL;
|
|
|
|
cpumap->size = (ncpus + 7) / 8;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int libxl_cpupool_create(libxl_ctx *ctx, const char *name,
|
|
libxl_scheduler sched,
|
|
libxl_bitmap cpumap, libxl_uuid *uuid,
|
|
uint32_t *poolid)
|
|
{
|
|
GC_INIT(ctx);
|
|
int rc;
|
|
int i;
|
|
xs_transaction_t t;
|
|
char *uuid_string;
|
|
uint32_t xcpoolid;
|
|
|
|
/* Accept '0' as 'any poolid' for backwards compatibility */
|
|
if ( *poolid == LIBXL_CPUPOOL_POOLID_ANY
|
|
|| *poolid == 0 )
|
|
xcpoolid = XC_CPUPOOL_POOLID_ANY;
|
|
else
|
|
xcpoolid = *poolid;
|
|
|
|
uuid_string = libxl__uuid2string(gc, *uuid);
|
|
if (!uuid_string) {
|
|
GC_FREE;
|
|
return ERROR_NOMEM;
|
|
}
|
|
|
|
rc = xc_cpupool_create(ctx->xch, &xcpoolid, sched);
|
|
if (rc) {
|
|
LOGEV(ERROR, rc, "Could not create cpupool");
|
|
GC_FREE;
|
|
return ERROR_FAIL;
|
|
}
|
|
*poolid = xcpoolid;
|
|
|
|
libxl_for_each_bit(i, cpumap)
|
|
if (libxl_bitmap_test(&cpumap, i)) {
|
|
rc = xc_cpupool_addcpu(ctx->xch, *poolid, i);
|
|
if (rc) {
|
|
LOGEV(ERROR, rc, "Error moving cpu to cpupool");
|
|
libxl_cpupool_destroy(ctx, *poolid);
|
|
GC_FREE;
|
|
return ERROR_FAIL;
|
|
}
|
|
}
|
|
|
|
for (;;) {
|
|
t = xs_transaction_start(ctx->xsh);
|
|
|
|
xs_mkdir(ctx->xsh, t, GCSPRINTF("/local/pool/%d", *poolid));
|
|
libxl__xs_printf(gc, t,
|
|
GCSPRINTF("/local/pool/%d/uuid", *poolid),
|
|
"%s", uuid_string);
|
|
libxl__xs_printf(gc, t,
|
|
GCSPRINTF("/local/pool/%d/name", *poolid),
|
|
"%s", name);
|
|
|
|
if (xs_transaction_end(ctx->xsh, t, 0) || (errno != EAGAIN)) {
|
|
GC_FREE;
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
int libxl_cpupool_destroy(libxl_ctx *ctx, uint32_t poolid)
|
|
{
|
|
GC_INIT(ctx);
|
|
int rc, i;
|
|
xc_cpupoolinfo_t *info;
|
|
xs_transaction_t t;
|
|
libxl_bitmap cpumap;
|
|
|
|
info = xc_cpupool_getinfo(ctx->xch, poolid);
|
|
if (info == NULL) {
|
|
GC_FREE;
|
|
return ERROR_NOMEM;
|
|
}
|
|
|
|
rc = ERROR_INVAL;
|
|
if ((info->cpupool_id != poolid) || (info->n_dom))
|
|
goto out;
|
|
|
|
rc = libxl_cpu_bitmap_alloc(ctx, &cpumap, 0);
|
|
if (rc)
|
|
goto out;
|
|
|
|
memcpy(cpumap.map, info->cpumap, cpumap.size);
|
|
libxl_for_each_bit(i, cpumap)
|
|
if (libxl_bitmap_test(&cpumap, i)) {
|
|
rc = xc_cpupool_removecpu(ctx->xch, poolid, i);
|
|
if (rc) {
|
|
LOGEV(ERROR, rc, "Error removing cpu from cpupool");
|
|
rc = ERROR_FAIL;
|
|
goto out1;
|
|
}
|
|
}
|
|
|
|
rc = xc_cpupool_destroy(ctx->xch, poolid);
|
|
if (rc) {
|
|
LOGEV(ERROR, rc, "Could not destroy cpupool");
|
|
rc = ERROR_FAIL;
|
|
goto out1;
|
|
}
|
|
|
|
for (;;) {
|
|
t = xs_transaction_start(ctx->xsh);
|
|
|
|
xs_rm(ctx->xsh, XBT_NULL, GCSPRINTF("/local/pool/%d", poolid));
|
|
|
|
if (xs_transaction_end(ctx->xsh, t, 0) || (errno != EAGAIN))
|
|
break;
|
|
}
|
|
|
|
rc = 0;
|
|
|
|
out1:
|
|
libxl_bitmap_dispose(&cpumap);
|
|
out:
|
|
xc_cpupool_infofree(ctx->xch, info);
|
|
GC_FREE;
|
|
|
|
return rc;
|
|
}
|
|
|
|
int libxl_cpupool_rename(libxl_ctx *ctx, const char *name, uint32_t poolid)
|
|
{
|
|
GC_INIT(ctx);
|
|
xs_transaction_t t;
|
|
xc_cpupoolinfo_t *info;
|
|
int rc;
|
|
|
|
info = xc_cpupool_getinfo(ctx->xch, poolid);
|
|
if (info == NULL) {
|
|
GC_FREE;
|
|
return ERROR_NOMEM;
|
|
}
|
|
|
|
rc = ERROR_INVAL;
|
|
if (info->cpupool_id != poolid)
|
|
goto out;
|
|
|
|
rc = 0;
|
|
|
|
for (;;) {
|
|
t = xs_transaction_start(ctx->xsh);
|
|
|
|
libxl__xs_printf(gc, t,
|
|
GCSPRINTF("/local/pool/%d/name", poolid),
|
|
"%s", name);
|
|
|
|
if (xs_transaction_end(ctx->xsh, t, 0))
|
|
break;
|
|
|
|
if (errno == EAGAIN)
|
|
continue;
|
|
|
|
rc = ERROR_FAIL;
|
|
break;
|
|
}
|
|
|
|
out:
|
|
xc_cpupool_infofree(ctx->xch, info);
|
|
GC_FREE;
|
|
|
|
return rc;
|
|
}
|
|
|
|
int libxl_cpupool_cpuadd(libxl_ctx *ctx, uint32_t poolid, int cpu)
|
|
{
|
|
GC_INIT(ctx);
|
|
int rc = 0;
|
|
|
|
rc = xc_cpupool_addcpu(ctx->xch, poolid, cpu);
|
|
if (rc) {
|
|
LOGE(ERROR, "Error moving cpu %d to cpupool", cpu);
|
|
rc = ERROR_FAIL;
|
|
}
|
|
|
|
GC_FREE;
|
|
return rc;
|
|
}
|
|
|
|
int libxl_cpupool_cpuadd_cpumap(libxl_ctx *ctx, uint32_t poolid,
|
|
const libxl_bitmap *cpumap)
|
|
{
|
|
int c, ncpus = 0, rc = 0;
|
|
|
|
libxl_for_each_set_bit(c, *cpumap) {
|
|
if (!libxl_cpupool_cpuadd(ctx, poolid, c))
|
|
ncpus++;
|
|
}
|
|
|
|
if (ncpus != libxl_bitmap_count_set(cpumap))
|
|
rc = ERROR_FAIL;
|
|
|
|
return rc;
|
|
}
|
|
|
|
int libxl_cpupool_cpuadd_node(libxl_ctx *ctx, uint32_t poolid, int node, int *cpus)
|
|
{
|
|
int rc = 0;
|
|
int cpu, nr;
|
|
libxl_bitmap freemap;
|
|
libxl_cputopology *topology;
|
|
|
|
if (libxl_get_freecpus(ctx, &freemap)) {
|
|
return ERROR_FAIL;
|
|
}
|
|
|
|
topology = libxl_get_cpu_topology(ctx, &nr);
|
|
if (!topology) {
|
|
rc = ERROR_FAIL;
|
|
goto out;
|
|
}
|
|
|
|
*cpus = 0;
|
|
for (cpu = 0; cpu < nr; cpu++) {
|
|
if (libxl_bitmap_test(&freemap, cpu) && (topology[cpu].node == node) &&
|
|
!libxl_cpupool_cpuadd(ctx, poolid, cpu)) {
|
|
(*cpus)++;
|
|
}
|
|
libxl_cputopology_dispose(&topology[cpu]);
|
|
}
|
|
|
|
free(topology);
|
|
out:
|
|
libxl_bitmap_dispose(&freemap);
|
|
return rc;
|
|
}
|
|
|
|
int libxl_cpupool_cpuremove(libxl_ctx *ctx, uint32_t poolid, int cpu)
|
|
{
|
|
GC_INIT(ctx);
|
|
int rc = 0;
|
|
|
|
rc = xc_cpupool_removecpu(ctx->xch, poolid, cpu);
|
|
if (rc) {
|
|
LOGE(ERROR, "Error removing cpu %d from cpupool", cpu);
|
|
rc = ERROR_FAIL;
|
|
}
|
|
|
|
GC_FREE;
|
|
return rc;
|
|
}
|
|
|
|
int libxl_cpupool_cpuremove_cpumap(libxl_ctx *ctx, uint32_t poolid,
|
|
const libxl_bitmap *cpumap)
|
|
{
|
|
int c, ncpus = 0, rc = 0;
|
|
|
|
libxl_for_each_set_bit(c, *cpumap) {
|
|
if (!libxl_cpupool_cpuremove(ctx, poolid, c))
|
|
ncpus++;
|
|
}
|
|
|
|
if (ncpus != libxl_bitmap_count_set(cpumap))
|
|
rc = ERROR_FAIL;
|
|
|
|
return rc;
|
|
}
|
|
|
|
int libxl_cpupool_cpuremove_node(libxl_ctx *ctx, uint32_t poolid, int node, int *cpus)
|
|
{
|
|
int ret = 0;
|
|
int n_pools;
|
|
int p;
|
|
int cpu, nr_cpus;
|
|
libxl_cputopology *topology;
|
|
libxl_cpupoolinfo *poolinfo;
|
|
|
|
poolinfo = libxl_list_cpupool(ctx, &n_pools);
|
|
if (!poolinfo) {
|
|
return ERROR_NOMEM;
|
|
}
|
|
|
|
topology = libxl_get_cpu_topology(ctx, &nr_cpus);
|
|
if (!topology) {
|
|
ret = ERROR_FAIL;
|
|
goto out;
|
|
}
|
|
|
|
*cpus = 0;
|
|
for (p = 0; p < n_pools; p++) {
|
|
if (poolinfo[p].poolid == poolid) {
|
|
for (cpu = 0; cpu < nr_cpus; cpu++) {
|
|
if ((topology[cpu].node == node) &&
|
|
libxl_bitmap_test(&poolinfo[p].cpumap, cpu) &&
|
|
!libxl_cpupool_cpuremove(ctx, poolid, cpu)) {
|
|
(*cpus)++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
libxl_cputopology_list_free(topology, nr_cpus);
|
|
|
|
out:
|
|
libxl_cpupoolinfo_list_free(poolinfo, n_pools);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int libxl_cpupool_movedomain(libxl_ctx *ctx, uint32_t poolid, uint32_t domid)
|
|
{
|
|
GC_INIT(ctx);
|
|
int rc;
|
|
|
|
rc = xc_cpupool_movedomain(ctx->xch, poolid, domid);
|
|
if (rc) {
|
|
LOGEVD(ERROR, rc, domid, "Error moving domain to cpupool");
|
|
GC_FREE;
|
|
return ERROR_FAIL;
|
|
}
|
|
|
|
GC_FREE;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Local variables:
|
|
* mode: C
|
|
* c-basic-offset: 4
|
|
* indent-tabs-mode: nil
|
|
* End:
|
|
*/
|