[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 17/29] xl: split out scheduler related code



Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx>
---
 tools/xl/Makefile     |   1 +
 tools/xl/xl_cmdimpl.c | 856 ------------------------------------------------
 tools/xl/xl_sched.c   | 888 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 889 insertions(+), 856 deletions(-)
 create mode 100644 tools/xl/xl_sched.c

diff --git a/tools/xl/Makefile b/tools/xl/Makefile
index 45ddc255f5..8aa294d5a0 100644
--- a/tools/xl/Makefile
+++ b/tools/xl/Makefile
@@ -18,6 +18,7 @@ CFLAGS_XL += -Wshadow
 XL_OBJS = xl.o xl_cmdimpl.o xl_cmdtable.o xl_sxp.o xl_utils.o
 XL_OBJS += xl_tmem.o xl_parse.o xl_cpupool.o xl_flask.o
 XL_OBJS += xl_vtpm.o xl_block.o xl_nic.o xl_usb.o
+XL_OBJS += xl_sched.o
 
 $(XL_OBJS): CFLAGS += $(CFLAGS_libxentoollog)
 $(XL_OBJS): CFLAGS += $(CFLAGS_XL)
diff --git a/tools/xl/xl_cmdimpl.c b/tools/xl/xl_cmdimpl.c
index 386f96b4cc..7d6de3957e 100644
--- a/tools/xl/xl_cmdimpl.c
+++ b/tools/xl/xl_cmdimpl.c
@@ -3757,862 +3757,6 @@ int main_sharing(int argc, char **argv)
     return EXIT_SUCCESS;
 }
 
-static int sched_domain_get(libxl_scheduler sched, int domid,
-                            libxl_domain_sched_params *scinfo)
-{
-    if (libxl_domain_sched_params_get(ctx, domid, scinfo)) {
-        fprintf(stderr, "libxl_domain_sched_params_get failed.\n");
-        return 1;
-    }
-    if (scinfo->sched != sched) {
-        fprintf(stderr, "libxl_domain_sched_params_get returned %s not %s.\n",
-                libxl_scheduler_to_string(scinfo->sched),
-                libxl_scheduler_to_string(sched));
-        return 1;
-    }
-
-    return 0;
-}
-
-static int sched_domain_set(int domid, const libxl_domain_sched_params *scinfo)
-{
-    if (libxl_domain_sched_params_set(ctx, domid, scinfo)) {
-        fprintf(stderr, "libxl_domain_sched_params_set failed.\n");
-        return 1;
-    }
-
-    return 0;
-}
-
-static int sched_vcpu_get(libxl_scheduler sched, int domid,
-                          libxl_vcpu_sched_params *scinfo)
-{
-    int rc;
-
-    rc = libxl_vcpu_sched_params_get(ctx, domid, scinfo);
-    if (rc) {
-        fprintf(stderr, "libxl_vcpu_sched_params_get failed.\n");
-        exit(EXIT_FAILURE);
-    }
-    if (scinfo->sched != sched) {
-        fprintf(stderr, "libxl_vcpu_sched_params_get returned %s not %s.\n",
-                libxl_scheduler_to_string(scinfo->sched),
-                libxl_scheduler_to_string(sched));
-        return 1;
-    }
-
-    return 0;
-}
-
-static int sched_vcpu_get_all(libxl_scheduler sched, int domid,
-                              libxl_vcpu_sched_params *scinfo)
-{
-    int rc;
-
-    rc = libxl_vcpu_sched_params_get_all(ctx, domid, scinfo);
-    if (rc) {
-        fprintf(stderr, "libxl_vcpu_sched_params_get_all failed.\n");
-        exit(EXIT_FAILURE);
-    }
-    if (scinfo->sched != sched) {
-        fprintf(stderr, "libxl_vcpu_sched_params_get_all returned %s not 
%s.\n",
-                libxl_scheduler_to_string(scinfo->sched),
-                libxl_scheduler_to_string(sched));
-        return 1;
-    }
-
-    return 0;
-}
-
-static int sched_vcpu_set(int domid, const libxl_vcpu_sched_params *scinfo)
-{
-    int rc;
-
-    rc = libxl_vcpu_sched_params_set(ctx, domid, scinfo);
-    if (rc) {
-        fprintf(stderr, "libxl_vcpu_sched_params_set failed.\n");
-        exit(EXIT_FAILURE);
-    }
-
-    return 0;
-}
-
-static int sched_vcpu_set_all(int domid, const libxl_vcpu_sched_params *scinfo)
-{
-    int rc;
-
-    rc = libxl_vcpu_sched_params_set_all(ctx, domid, scinfo);
-    if (rc) {
-        fprintf(stderr, "libxl_vcpu_sched_params_set_all failed.\n");
-        exit(EXIT_FAILURE);
-    }
-
-    return 0;
-}
-
-static int sched_credit_params_set(int poolid, libxl_sched_credit_params 
*scinfo)
-{
-    if (libxl_sched_credit_params_set(ctx, poolid, scinfo)) {
-        fprintf(stderr, "libxl_sched_credit_params_set failed.\n");
-        return 1;
-    }
-
-    return 0;
-}
-
-static int sched_credit_params_get(int poolid, libxl_sched_credit_params 
*scinfo)
-{
-    if (libxl_sched_credit_params_get(ctx, poolid, scinfo)) {
-        fprintf(stderr, "libxl_sched_credit_params_get failed.\n");
-        return 1;
-    }
-
-    return 0;
-}
-
-static int sched_credit_domain_output(int domid)
-{
-    char *domname;
-    libxl_domain_sched_params scinfo;
-
-    if (domid < 0) {
-        printf("%-33s %4s %6s %4s\n", "Name", "ID", "Weight", "Cap");
-        return 0;
-    }
-
-    libxl_domain_sched_params_init(&scinfo);
-    if (sched_domain_get(LIBXL_SCHEDULER_CREDIT, domid, &scinfo)) {
-        libxl_domain_sched_params_dispose(&scinfo);
-        return 1;
-    }
-    domname = libxl_domid_to_name(ctx, domid);
-    printf("%-33s %4d %6d %4d\n",
-        domname,
-        domid,
-        scinfo.weight,
-        scinfo.cap);
-    free(domname);
-    libxl_domain_sched_params_dispose(&scinfo);
-    return 0;
-}
-
-static int sched_credit_pool_output(uint32_t poolid)
-{
-    libxl_sched_credit_params scparam;
-    char *poolname;
-
-    poolname = libxl_cpupoolid_to_name(ctx, poolid);
-    if (sched_credit_params_get(poolid, &scparam)) {
-        printf("Cpupool %s: [sched params unavailable]\n",
-               poolname);
-    } else {
-        printf("Cpupool %s: tslice=%dms ratelimit=%dus\n",
-               poolname,
-               scparam.tslice_ms,
-               scparam.ratelimit_us);
-    }
-    free(poolname);
-    return 0;
-}
-
-static int sched_credit2_params_set(int poolid,
-                                    libxl_sched_credit2_params *scinfo)
-{
-    if (libxl_sched_credit2_params_set(ctx, poolid, scinfo)) {
-        fprintf(stderr, "libxl_sched_credit2_params_set failed.\n");
-        return 1;
-    }
-
-    return 0;
-}
-
-static int sched_credit2_params_get(int poolid,
-                                    libxl_sched_credit2_params *scinfo)
-{
-    if (libxl_sched_credit2_params_get(ctx, poolid, scinfo)) {
-        fprintf(stderr, "libxl_sched_credit2_params_get failed.\n");
-        return 1;
-    }
-
-    return 0;
-}
-
-static int sched_credit2_domain_output(int domid)
-{
-    char *domname;
-    libxl_domain_sched_params scinfo;
-
-    if (domid < 0) {
-        printf("%-33s %4s %6s\n", "Name", "ID", "Weight");
-        return 0;
-    }
-
-    libxl_domain_sched_params_init(&scinfo);
-    if (sched_domain_get(LIBXL_SCHEDULER_CREDIT2, domid, &scinfo)) {
-        libxl_domain_sched_params_dispose(&scinfo);
-        return 1;
-    }
-    domname = libxl_domid_to_name(ctx, domid);
-    printf("%-33s %4d %6d\n",
-        domname,
-        domid,
-        scinfo.weight);
-    free(domname);
-    libxl_domain_sched_params_dispose(&scinfo);
-    return 0;
-}
-
-static int sched_credit2_pool_output(uint32_t poolid)
-{
-    libxl_sched_credit2_params scparam;
-    char *poolname = libxl_cpupoolid_to_name(ctx, poolid);
-
-    if (sched_credit2_params_get(poolid, &scparam))
-        printf("Cpupool %s: [sched params unavailable]\n", poolname);
-    else
-        printf("Cpupool %s: ratelimit=%dus\n",
-               poolname, scparam.ratelimit_us);
-
-    free(poolname);
-
-    return 0;
-}
-
-static int sched_rtds_domain_output(
-    int domid)
-{
-    char *domname;
-    libxl_domain_sched_params scinfo;
-
-    if (domid < 0) {
-        printf("%-33s %4s %9s %9s\n", "Name", "ID", "Period", "Budget");
-        return 0;
-    }
-
-    libxl_domain_sched_params_init(&scinfo);
-    if (sched_domain_get(LIBXL_SCHEDULER_RTDS, domid, &scinfo)) {
-        libxl_domain_sched_params_dispose(&scinfo);
-        return 1;
-    }
-
-    domname = libxl_domid_to_name(ctx, domid);
-    printf("%-33s %4d %9d %9d\n",
-        domname,
-        domid,
-        scinfo.period,
-        scinfo.budget);
-    free(domname);
-    libxl_domain_sched_params_dispose(&scinfo);
-    return 0;
-}
-
-static int sched_rtds_vcpu_output(int domid, libxl_vcpu_sched_params *scinfo)
-{
-    char *domname;
-    int rc = 0;
-    int i;
-
-    if (domid < 0) {
-        printf("%-33s %4s %4s %9s %9s\n", "Name", "ID",
-               "VCPU", "Period", "Budget");
-        return 0;
-    }
-
-    rc = sched_vcpu_get(LIBXL_SCHEDULER_RTDS, domid, scinfo);
-    if (rc)
-        return 1;
-
-    domname = libxl_domid_to_name(ctx, domid);
-    for ( i = 0; i < scinfo->num_vcpus; i++ ) {
-        printf("%-33s %4d %4d %9"PRIu32" %9"PRIu32"\n",
-               domname,
-               domid,
-               scinfo->vcpus[i].vcpuid,
-               scinfo->vcpus[i].period,
-               scinfo->vcpus[i].budget);
-    }
-    free(domname);
-    return 0;
-}
-
-static int sched_rtds_vcpu_output_all(int domid,
-                                      libxl_vcpu_sched_params *scinfo)
-{
-    char *domname;
-    int rc = 0;
-    int i;
-
-    if (domid < 0) {
-        printf("%-33s %4s %4s %9s %9s\n", "Name", "ID",
-               "VCPU", "Period", "Budget");
-        return 0;
-    }
-
-    scinfo->num_vcpus = 0;
-    rc = sched_vcpu_get_all(LIBXL_SCHEDULER_RTDS, domid, scinfo);
-    if (rc)
-        return 1;
-
-    domname = libxl_domid_to_name(ctx, domid);
-    for ( i = 0; i < scinfo->num_vcpus; i++ ) {
-        printf("%-33s %4d %4d %9"PRIu32" %9"PRIu32"\n",
-               domname,
-               domid,
-               scinfo->vcpus[i].vcpuid,
-               scinfo->vcpus[i].period,
-               scinfo->vcpus[i].budget);
-    }
-    free(domname);
-    return 0;
-}
-
-static int sched_rtds_pool_output(uint32_t poolid)
-{
-    char *poolname;
-
-    poolname = libxl_cpupoolid_to_name(ctx, poolid);
-    printf("Cpupool %s: sched=RTDS\n", poolname);
-
-    free(poolname);
-    return 0;
-}
-
-static int sched_domain_output(libxl_scheduler sched, int (*output)(int),
-                               int (*pooloutput)(uint32_t), const char 
*cpupool)
-{
-    libxl_dominfo *info;
-    libxl_cpupoolinfo *poolinfo = NULL;
-    uint32_t poolid;
-    int nb_domain, n_pools = 0, i, p;
-    int rc = 0;
-
-    if (cpupool) {
-        if (libxl_cpupool_qualifier_to_cpupoolid(ctx, cpupool, &poolid, NULL) 
||
-            !libxl_cpupoolid_is_valid(ctx, poolid)) {
-            fprintf(stderr, "unknown cpupool \'%s\'\n", cpupool);
-            return 1;
-        }
-    }
-
-    info = libxl_list_domain(ctx, &nb_domain);
-    if (!info) {
-        fprintf(stderr, "libxl_list_domain failed.\n");
-        return 1;
-    }
-    poolinfo = libxl_list_cpupool(ctx, &n_pools);
-    if (!poolinfo) {
-        fprintf(stderr, "error getting cpupool info\n");
-        libxl_dominfo_list_free(info, nb_domain);
-        return 1;
-    }
-
-    for (p = 0; !rc && (p < n_pools); p++) {
-        if ((poolinfo[p].sched != sched) ||
-            (cpupool && (poolid != poolinfo[p].poolid)))
-            continue;
-
-        pooloutput(poolinfo[p].poolid);
-
-        output(-1);
-        for (i = 0; i < nb_domain; i++) {
-            if (info[i].cpupool != poolinfo[p].poolid)
-                continue;
-            rc = output(info[i].domid);
-            if (rc)
-                break;
-        }
-    }
-
-    libxl_cpupoolinfo_list_free(poolinfo, n_pools);
-    libxl_dominfo_list_free(info, nb_domain);
-    return 0;
-}
-
-static int sched_vcpu_output(libxl_scheduler sched,
-                             int (*output)(int, libxl_vcpu_sched_params *),
-                             int (*pooloutput)(uint32_t), const char *cpupool)
-{
-    libxl_dominfo *info;
-    libxl_cpupoolinfo *poolinfo = NULL;
-    uint32_t poolid;
-    int nb_domain, n_pools = 0, i, p;
-    int rc = 0;
-
-    if (cpupool) {
-        if (libxl_cpupool_qualifier_to_cpupoolid(ctx, cpupool, &poolid, NULL)
-            || !libxl_cpupoolid_is_valid(ctx, poolid)) {
-            fprintf(stderr, "unknown cpupool \'%s\'\n", cpupool);
-            return 1;
-        }
-    }
-
-    info = libxl_list_domain(ctx, &nb_domain);
-    if (!info) {
-        fprintf(stderr, "libxl_list_domain failed.\n");
-        return 1;
-    }
-    poolinfo = libxl_list_cpupool(ctx, &n_pools);
-    if (!poolinfo) {
-        fprintf(stderr, "error getting cpupool info\n");
-        libxl_dominfo_list_free(info, nb_domain);
-        return 1;
-    }
-
-    for (p = 0; !rc && (p < n_pools); p++) {
-        if ((poolinfo[p].sched != sched) ||
-            (cpupool && (poolid != poolinfo[p].poolid)))
-            continue;
-
-        pooloutput(poolinfo[p].poolid);
-
-        output(-1, NULL);
-        for (i = 0; i < nb_domain; i++) {
-            libxl_vcpu_sched_params scinfo;
-            if (info[i].cpupool != poolinfo[p].poolid)
-                continue;
-            libxl_vcpu_sched_params_init(&scinfo);
-            rc = output(info[i].domid, &scinfo);
-            libxl_vcpu_sched_params_dispose(&scinfo);
-            if (rc)
-                break;
-        }
-    }
-
-    libxl_cpupoolinfo_list_free(poolinfo, n_pools);
-    libxl_dominfo_list_free(info, nb_domain);
-    return 0;
-}
-
-/*
- * <nothing>             : List all domain params and sched params from all 
pools
- * -d [domid]            : List domain params for domain
- * -d [domid] [params]   : Set domain params for domain
- * -p [pool]             : list all domains and sched params for pool
- * -s                    : List sched params for poolid 0
- * -s [params]           : Set sched params for poolid 0
- * -p [pool] -s          : List sched params for pool
- * -p [pool] -s [params] : Set sched params for pool
- * -p [pool] -d...       : Illegal
- */
-int main_sched_credit(int argc, char **argv)
-{
-    const char *dom = NULL;
-    const char *cpupool = NULL;
-    int weight = 256, cap = 0;
-    int tslice = 0, ratelimit = 0;
-    bool opt_w = false, opt_c = false;
-    bool opt_t = false, opt_r = false;
-    bool opt_s = false;
-    int opt, rc;
-    static struct option opts[] = {
-        {"domain", 1, 0, 'd'},
-        {"weight", 1, 0, 'w'},
-        {"cap", 1, 0, 'c'},
-        {"schedparam", 0, 0, 's'},
-        {"tslice_ms", 1, 0, 't'},
-        {"ratelimit_us", 1, 0, 'r'},
-        {"cpupool", 1, 0, 'p'},
-        COMMON_LONG_OPTS
-    };
-
-    SWITCH_FOREACH_OPT(opt, "d:w:c:p:t:r:s", opts, "sched-credit", 0) {
-    case 'd':
-        dom = optarg;
-        break;
-    case 'w':
-        weight = strtol(optarg, NULL, 10);
-        opt_w = true;
-        break;
-    case 'c':
-        cap = strtol(optarg, NULL, 10);
-        opt_c = true;
-        break;
-    case 't':
-        tslice = strtol(optarg, NULL, 10);
-        opt_t = true;
-        break;
-    case 'r':
-        ratelimit = strtol(optarg, NULL, 10);
-        opt_r = true;
-        break;
-    case 's':
-        opt_s = true;
-        break;
-    case 'p':
-        cpupool = optarg;
-        break;
-    }
-
-    if ((cpupool || opt_s) && (dom || opt_w || opt_c)) {
-        fprintf(stderr, "Specifying a cpupool or schedparam is not "
-                "allowed with domain options.\n");
-        return EXIT_FAILURE;
-    }
-    if (!dom && (opt_w || opt_c)) {
-        fprintf(stderr, "Must specify a domain.\n");
-        return EXIT_FAILURE;
-    }
-    if (!opt_s && (opt_t || opt_r)) {
-        fprintf(stderr, "Must specify schedparam to set schedule "
-                "parameter values.\n");
-        return EXIT_FAILURE;
-    }
-
-    if (opt_s) {
-        libxl_sched_credit_params scparam;
-        uint32_t poolid = 0;
-
-        if (cpupool) {
-            if (libxl_cpupool_qualifier_to_cpupoolid(ctx, cpupool,
-                                                     &poolid, NULL) ||
-                !libxl_cpupoolid_is_valid(ctx, poolid)) {
-                fprintf(stderr, "unknown cpupool \'%s\'\n", cpupool);
-                return EXIT_FAILURE;
-            }
-        }
-
-        if (!opt_t && !opt_r) { /* Output scheduling parameters */
-            if (sched_credit_pool_output(poolid))
-                return EXIT_FAILURE;
-        } else { /* Set scheduling parameters*/
-            if (sched_credit_params_get(poolid, &scparam))
-                return EXIT_FAILURE;
-
-            if (opt_t)
-                scparam.tslice_ms = tslice;
-
-            if (opt_r)
-                scparam.ratelimit_us = ratelimit;
-
-            if (sched_credit_params_set(poolid, &scparam))
-                return EXIT_FAILURE;
-        }
-    } else if (!dom) { /* list all domain's credit scheduler info */
-        if (sched_domain_output(LIBXL_SCHEDULER_CREDIT,
-                                sched_credit_domain_output,
-                                sched_credit_pool_output,
-                                cpupool))
-            return EXIT_FAILURE;
-    } else {
-        uint32_t domid = xfind_domain(dom);
-
-        if (!opt_w && !opt_c) { /* output credit scheduler info */
-            sched_credit_domain_output(-1);
-            if (sched_credit_domain_output(domid))
-                return EXIT_FAILURE;
-        } else { /* set credit scheduler paramaters */
-            libxl_domain_sched_params scinfo;
-            libxl_domain_sched_params_init(&scinfo);
-            scinfo.sched = LIBXL_SCHEDULER_CREDIT;
-            if (opt_w)
-                scinfo.weight = weight;
-            if (opt_c)
-                scinfo.cap = cap;
-            rc = sched_domain_set(domid, &scinfo);
-            libxl_domain_sched_params_dispose(&scinfo);
-            if (rc)
-                return EXIT_FAILURE;
-        }
-    }
-
-    return EXIT_SUCCESS;
-}
-
-int main_sched_credit2(int argc, char **argv)
-{
-    const char *dom = NULL;
-    const char *cpupool = NULL;
-    int ratelimit = 0;
-    int weight = 256;
-    bool opt_s = false;
-    bool opt_r = false;
-    bool opt_w = false;
-    int opt, rc;
-    static struct option opts[] = {
-        {"domain", 1, 0, 'd'},
-        {"weight", 1, 0, 'w'},
-        {"schedparam", 0, 0, 's'},
-        {"ratelimit_us", 1, 0, 'r'},
-        {"cpupool", 1, 0, 'p'},
-        COMMON_LONG_OPTS
-    };
-
-    SWITCH_FOREACH_OPT(opt, "d:w:p:r:s", opts, "sched-credit2", 0) {
-    case 'd':
-        dom = optarg;
-        break;
-    case 'w':
-        weight = strtol(optarg, NULL, 10);
-        opt_w = true;
-        break;
-    case 's':
-        opt_s = true;
-        break;
-    case 'r':
-        ratelimit = strtol(optarg, NULL, 10);
-        opt_r = true;
-        break;
-    case 'p':
-        cpupool = optarg;
-        break;
-    }
-
-    if (cpupool && (dom || opt_w)) {
-        fprintf(stderr, "Specifying a cpupool is not allowed with other "
-                "options.\n");
-        return EXIT_FAILURE;
-    }
-    if (!dom && opt_w) {
-        fprintf(stderr, "Must specify a domain.\n");
-        return EXIT_FAILURE;
-    }
-
-    if (opt_s) {
-        libxl_sched_credit2_params scparam;
-        uint32_t poolid = 0;
-
-        if (cpupool) {
-            if (libxl_cpupool_qualifier_to_cpupoolid(ctx, cpupool,
-                                                     &poolid, NULL) ||
-                !libxl_cpupoolid_is_valid(ctx, poolid)) {
-                fprintf(stderr, "unknown cpupool \'%s\'\n", cpupool);
-                return EXIT_FAILURE;
-            }
-        }
-
-        if (!opt_r) { /* Output scheduling parameters */
-            if (sched_credit2_pool_output(poolid))
-                return EXIT_FAILURE;
-        } else {      /* Set scheduling parameters (so far, just ratelimit) */
-            scparam.ratelimit_us = ratelimit;
-            if (sched_credit2_params_set(poolid, &scparam))
-                return EXIT_FAILURE;
-        }
-    } else if (!dom) { /* list all domain's credit scheduler info */
-        if (sched_domain_output(LIBXL_SCHEDULER_CREDIT2,
-                                sched_credit2_domain_output,
-                                sched_credit2_pool_output,
-                                cpupool))
-            return EXIT_FAILURE;
-    } else {
-        uint32_t domid = xfind_domain(dom);
-
-        if (!opt_w) { /* output credit2 scheduler info */
-            sched_credit2_domain_output(-1);
-            if (sched_credit2_domain_output(domid))
-                return EXIT_FAILURE;
-        } else { /* set credit2 scheduler paramaters */
-            libxl_domain_sched_params scinfo;
-            libxl_domain_sched_params_init(&scinfo);
-            scinfo.sched = LIBXL_SCHEDULER_CREDIT2;
-            if (opt_w)
-                scinfo.weight = weight;
-            rc = sched_domain_set(domid, &scinfo);
-            libxl_domain_sched_params_dispose(&scinfo);
-            if (rc)
-                return EXIT_FAILURE;
-        }
-    }
-
-    return EXIT_SUCCESS;
-}
-
-/*
- * <nothing>            : List all domain paramters and sched params
- * -d [domid]           : List default domain params for domain
- * -d [domid] [params]  : Set domain params for domain
- * -d [domid] -v [vcpuid 1] -v [vcpuid 2] ...  :
- * List per-VCPU params for domain
- * -d [domid] -v all  : List all per-VCPU params for domain
- * -v all  : List all per-VCPU params for all domains
- * -d [domid] -v [vcpuid 1] [params] -v [vcpuid 2] [params] ...  :
- * Set per-VCPU params for domain
- * -d [domid] -v all [params]  : Set all per-VCPU params for domain
- */
-int main_sched_rtds(int argc, char **argv)
-{
-    const char *dom = NULL;
-    const char *cpupool = NULL;
-    int *vcpus = (int *)xmalloc(sizeof(int)); /* IDs of VCPUs that change */
-    int *periods = (int *)xmalloc(sizeof(int)); /* period is in microsecond */
-    int *budgets = (int *)xmalloc(sizeof(int)); /* budget is in microsecond */
-    int v_size = 1; /* size of vcpus array */
-    int p_size = 1; /* size of periods array */
-    int b_size = 1; /* size of budgets array */
-    int v_index = 0; /* index in vcpus array */
-    int p_index =0; /* index in periods array */
-    int b_index =0; /* index for in budgets array */
-    bool opt_p = false;
-    bool opt_b = false;
-    bool opt_v = false;
-    bool opt_all = false; /* output per-dom parameters */
-    int opt, i, rc, r;
-    static struct option opts[] = {
-        {"domain", 1, 0, 'd'},
-        {"period", 1, 0, 'p'},
-        {"budget", 1, 0, 'b'},
-        {"vcpuid",1, 0, 'v'},
-        {"cpupool", 1, 0, 'c'},
-        COMMON_LONG_OPTS
-    };
-
-    SWITCH_FOREACH_OPT(opt, "d:p:b:v:c", opts, "sched-rtds", 0) {
-    case 'd':
-        dom = optarg;
-        break;
-    case 'p':
-        if (p_index >= p_size) {
-            /*
-             * periods array is full
-             * double the array size for new elements
-             */
-            p_size *= 2;
-            periods = xrealloc(periods, p_size);
-        }
-        periods[p_index++] = strtol(optarg, NULL, 10);
-        opt_p = 1;
-        break;
-    case 'b':
-        if (b_index >= b_size) { /* budgets array is full */
-            b_size *= 2;
-            budgets = xrealloc(budgets, b_size);
-        }
-        budgets[b_index++] = strtol(optarg, NULL, 10);
-        opt_b = 1;
-        break;
-    case 'v':
-        if (!strcmp(optarg, "all")) { /* get or set all vcpus of a domain */
-            opt_all = 1;
-            break;
-        }
-        if (v_index >= v_size) { /* vcpus array is full */
-            v_size *= 2;
-            vcpus = xrealloc(vcpus, v_size);
-        }
-        vcpus[v_index++] = strtol(optarg, NULL, 10);
-        opt_v = 1;
-        break;
-    case 'c':
-        cpupool = optarg;
-        break;
-    }
-
-    if (cpupool && (dom || opt_p || opt_b || opt_v || opt_all)) {
-        fprintf(stderr, "Specifying a cpupool is not allowed with "
-                "other options.\n");
-        r = EXIT_FAILURE;
-        goto out;
-    }
-    if (!dom && (opt_p || opt_b || opt_v)) {
-        fprintf(stderr, "Missing parameters.\n");
-        r = EXIT_FAILURE;
-        goto out;
-    }
-    if (dom && !opt_v && !opt_all && (opt_p || opt_b)) {
-        fprintf(stderr, "Must specify VCPU.\n");
-        r = EXIT_FAILURE;
-        goto out;
-    }
-    if (opt_v && opt_all) {
-        fprintf(stderr, "Incorrect VCPU IDs.\n");
-        r = EXIT_FAILURE;
-        goto out;
-    }
-    if (((v_index > b_index) && opt_b) || ((v_index > p_index) && opt_p)
-        || p_index != b_index) {
-        fprintf(stderr, "Incorrect number of period and budget\n");
-        r = EXIT_FAILURE;
-        goto out;
-    }
-
-    if ((!dom) && opt_all) {
-        /* get all domain's per-vcpu rtds scheduler parameters */
-        rc = -sched_vcpu_output(LIBXL_SCHEDULER_RTDS,
-                                sched_rtds_vcpu_output_all,
-                                sched_rtds_pool_output,
-                                cpupool);
-        if (rc) {
-            r = EXIT_FAILURE;
-            goto out;
-        }
-    } else if (!dom && !opt_all) {
-        /* list all domain's default scheduling parameters */
-        rc = -sched_domain_output(LIBXL_SCHEDULER_RTDS,
-                                  sched_rtds_domain_output,
-                                  sched_rtds_pool_output,
-                                  cpupool);
-        if (rc) {
-            r = EXIT_FAILURE;
-            goto out;
-        }
-    } else {
-        uint32_t domid = xfind_domain(dom);
-        if (!opt_v && !opt_all) { /* output default scheduling parameters */
-            sched_rtds_domain_output(-1);
-            rc = -sched_rtds_domain_output(domid);
-            if (rc) {
-                r = EXIT_FAILURE;
-                goto out;
-            }
-        } else if (!opt_p && !opt_b) {
-            /* get per-vcpu rtds scheduling parameters */
-            libxl_vcpu_sched_params scinfo;
-            libxl_vcpu_sched_params_init(&scinfo);
-            sched_rtds_vcpu_output(-1, &scinfo);
-            scinfo.num_vcpus = v_index;
-            if (v_index > 0) {
-                scinfo.vcpus = (libxl_sched_params *)
-                               xmalloc(sizeof(libxl_sched_params) * (v_index));
-                for (i = 0; i < v_index; i++)
-                    scinfo.vcpus[i].vcpuid = vcpus[i];
-                rc = -sched_rtds_vcpu_output(domid, &scinfo);
-            } else /* get params for all vcpus */
-                rc = -sched_rtds_vcpu_output_all(domid, &scinfo);
-            libxl_vcpu_sched_params_dispose(&scinfo);
-            if (rc) {
-                r = EXIT_FAILURE;
-                goto out;
-            }
-    } else if (opt_v || opt_all) {
-            /* set per-vcpu rtds scheduling parameters */
-            libxl_vcpu_sched_params scinfo;
-            libxl_vcpu_sched_params_init(&scinfo);
-            scinfo.sched = LIBXL_SCHEDULER_RTDS;
-            if (v_index > 0) {
-                scinfo.num_vcpus = v_index;
-                scinfo.vcpus = (libxl_sched_params *)
-                               xmalloc(sizeof(libxl_sched_params) * (v_index));
-                for (i = 0; i < v_index; i++) {
-                    scinfo.vcpus[i].vcpuid = vcpus[i];
-                    scinfo.vcpus[i].period = periods[i];
-                    scinfo.vcpus[i].budget = budgets[i];
-                }
-                rc = sched_vcpu_set(domid, &scinfo);
-            } else { /* set params for all vcpus */
-                scinfo.num_vcpus = 1;
-                scinfo.vcpus = (libxl_sched_params *)
-                               xmalloc(sizeof(libxl_sched_params));
-                scinfo.vcpus[0].period = periods[0];
-                scinfo.vcpus[0].budget = budgets[0];
-                rc = sched_vcpu_set_all(domid, &scinfo);
-            }
-
-            libxl_vcpu_sched_params_dispose(&scinfo);
-            if (rc) {
-                r = EXIT_FAILURE;
-                goto out;
-            }
-        }
-    }
-
-    r = EXIT_SUCCESS;
-out:
-    free(vcpus);
-    free(periods);
-    free(budgets);
-    return r;
-}
-
 int main_domid(int argc, char **argv)
 {
     uint32_t domid;
diff --git a/tools/xl/xl_sched.c b/tools/xl/xl_sched.c
new file mode 100644
index 0000000000..50b254da81
--- /dev/null
+++ b/tools/xl/xl_sched.c
@@ -0,0 +1,888 @@
+/*
+ * 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 <inttypes.h>
+#include <stdlib.h>
+
+#include <libxl.h>
+#include <libxl_utils.h>
+#include <libxlutil.h>
+
+#include "xl.h"
+#include "xl_utils.h"
+#include "xl_parse.h"
+
+static int sched_domain_get(libxl_scheduler sched, int domid,
+                            libxl_domain_sched_params *scinfo)
+{
+    if (libxl_domain_sched_params_get(ctx, domid, scinfo)) {
+        fprintf(stderr, "libxl_domain_sched_params_get failed.\n");
+        return 1;
+    }
+    if (scinfo->sched != sched) {
+        fprintf(stderr, "libxl_domain_sched_params_get returned %s not %s.\n",
+                libxl_scheduler_to_string(scinfo->sched),
+                libxl_scheduler_to_string(sched));
+        return 1;
+    }
+
+    return 0;
+}
+
+static int sched_domain_set(int domid, const libxl_domain_sched_params *scinfo)
+{
+    if (libxl_domain_sched_params_set(ctx, domid, scinfo)) {
+        fprintf(stderr, "libxl_domain_sched_params_set failed.\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+static int sched_vcpu_get(libxl_scheduler sched, int domid,
+                          libxl_vcpu_sched_params *scinfo)
+{
+    int rc;
+
+    rc = libxl_vcpu_sched_params_get(ctx, domid, scinfo);
+    if (rc) {
+        fprintf(stderr, "libxl_vcpu_sched_params_get failed.\n");
+        exit(EXIT_FAILURE);
+    }
+    if (scinfo->sched != sched) {
+        fprintf(stderr, "libxl_vcpu_sched_params_get returned %s not %s.\n",
+                libxl_scheduler_to_string(scinfo->sched),
+                libxl_scheduler_to_string(sched));
+        return 1;
+    }
+
+    return 0;
+}
+
+static int sched_vcpu_get_all(libxl_scheduler sched, int domid,
+                              libxl_vcpu_sched_params *scinfo)
+{
+    int rc;
+
+    rc = libxl_vcpu_sched_params_get_all(ctx, domid, scinfo);
+    if (rc) {
+        fprintf(stderr, "libxl_vcpu_sched_params_get_all failed.\n");
+        exit(EXIT_FAILURE);
+    }
+    if (scinfo->sched != sched) {
+        fprintf(stderr, "libxl_vcpu_sched_params_get_all returned %s not 
%s.\n",
+                libxl_scheduler_to_string(scinfo->sched),
+                libxl_scheduler_to_string(sched));
+        return 1;
+    }
+
+    return 0;
+}
+
+static int sched_vcpu_set(int domid, const libxl_vcpu_sched_params *scinfo)
+{
+    int rc;
+
+    rc = libxl_vcpu_sched_params_set(ctx, domid, scinfo);
+    if (rc) {
+        fprintf(stderr, "libxl_vcpu_sched_params_set failed.\n");
+        exit(EXIT_FAILURE);
+    }
+
+    return 0;
+}
+
+static int sched_vcpu_set_all(int domid, const libxl_vcpu_sched_params *scinfo)
+{
+    int rc;
+
+    rc = libxl_vcpu_sched_params_set_all(ctx, domid, scinfo);
+    if (rc) {
+        fprintf(stderr, "libxl_vcpu_sched_params_set_all failed.\n");
+        exit(EXIT_FAILURE);
+    }
+
+    return 0;
+}
+
+static int sched_credit_params_set(int poolid, libxl_sched_credit_params 
*scinfo)
+{
+    if (libxl_sched_credit_params_set(ctx, poolid, scinfo)) {
+        fprintf(stderr, "libxl_sched_credit_params_set failed.\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+static int sched_credit_params_get(int poolid, libxl_sched_credit_params 
*scinfo)
+{
+    if (libxl_sched_credit_params_get(ctx, poolid, scinfo)) {
+        fprintf(stderr, "libxl_sched_credit_params_get failed.\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+static int sched_credit_domain_output(int domid)
+{
+    char *domname;
+    libxl_domain_sched_params scinfo;
+
+    if (domid < 0) {
+        printf("%-33s %4s %6s %4s\n", "Name", "ID", "Weight", "Cap");
+        return 0;
+    }
+
+    libxl_domain_sched_params_init(&scinfo);
+    if (sched_domain_get(LIBXL_SCHEDULER_CREDIT, domid, &scinfo)) {
+        libxl_domain_sched_params_dispose(&scinfo);
+        return 1;
+    }
+    domname = libxl_domid_to_name(ctx, domid);
+    printf("%-33s %4d %6d %4d\n",
+        domname,
+        domid,
+        scinfo.weight,
+        scinfo.cap);
+    free(domname);
+    libxl_domain_sched_params_dispose(&scinfo);
+    return 0;
+}
+
+static int sched_credit_pool_output(uint32_t poolid)
+{
+    libxl_sched_credit_params scparam;
+    char *poolname;
+
+    poolname = libxl_cpupoolid_to_name(ctx, poolid);
+    if (sched_credit_params_get(poolid, &scparam)) {
+        printf("Cpupool %s: [sched params unavailable]\n",
+               poolname);
+    } else {
+        printf("Cpupool %s: tslice=%dms ratelimit=%dus\n",
+               poolname,
+               scparam.tslice_ms,
+               scparam.ratelimit_us);
+    }
+    free(poolname);
+    return 0;
+}
+
+static int sched_credit2_params_set(int poolid,
+                                    libxl_sched_credit2_params *scinfo)
+{
+    if (libxl_sched_credit2_params_set(ctx, poolid, scinfo)) {
+        fprintf(stderr, "libxl_sched_credit2_params_set failed.\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+static int sched_credit2_params_get(int poolid,
+                                    libxl_sched_credit2_params *scinfo)
+{
+    if (libxl_sched_credit2_params_get(ctx, poolid, scinfo)) {
+        fprintf(stderr, "libxl_sched_credit2_params_get failed.\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+static int sched_credit2_domain_output(int domid)
+{
+    char *domname;
+    libxl_domain_sched_params scinfo;
+
+    if (domid < 0) {
+        printf("%-33s %4s %6s\n", "Name", "ID", "Weight");
+        return 0;
+    }
+
+    libxl_domain_sched_params_init(&scinfo);
+    if (sched_domain_get(LIBXL_SCHEDULER_CREDIT2, domid, &scinfo)) {
+        libxl_domain_sched_params_dispose(&scinfo);
+        return 1;
+    }
+    domname = libxl_domid_to_name(ctx, domid);
+    printf("%-33s %4d %6d\n",
+        domname,
+        domid,
+        scinfo.weight);
+    free(domname);
+    libxl_domain_sched_params_dispose(&scinfo);
+    return 0;
+}
+
+static int sched_credit2_pool_output(uint32_t poolid)
+{
+    libxl_sched_credit2_params scparam;
+    char *poolname = libxl_cpupoolid_to_name(ctx, poolid);
+
+    if (sched_credit2_params_get(poolid, &scparam))
+        printf("Cpupool %s: [sched params unavailable]\n", poolname);
+    else
+        printf("Cpupool %s: ratelimit=%dus\n",
+               poolname, scparam.ratelimit_us);
+
+    free(poolname);
+
+    return 0;
+}
+
+static int sched_rtds_domain_output(
+    int domid)
+{
+    char *domname;
+    libxl_domain_sched_params scinfo;
+
+    if (domid < 0) {
+        printf("%-33s %4s %9s %9s\n", "Name", "ID", "Period", "Budget");
+        return 0;
+    }
+
+    libxl_domain_sched_params_init(&scinfo);
+    if (sched_domain_get(LIBXL_SCHEDULER_RTDS, domid, &scinfo)) {
+        libxl_domain_sched_params_dispose(&scinfo);
+        return 1;
+    }
+
+    domname = libxl_domid_to_name(ctx, domid);
+    printf("%-33s %4d %9d %9d\n",
+        domname,
+        domid,
+        scinfo.period,
+        scinfo.budget);
+    free(domname);
+    libxl_domain_sched_params_dispose(&scinfo);
+    return 0;
+}
+
+static int sched_rtds_vcpu_output(int domid, libxl_vcpu_sched_params *scinfo)
+{
+    char *domname;
+    int rc = 0;
+    int i;
+
+    if (domid < 0) {
+        printf("%-33s %4s %4s %9s %9s\n", "Name", "ID",
+               "VCPU", "Period", "Budget");
+        return 0;
+    }
+
+    rc = sched_vcpu_get(LIBXL_SCHEDULER_RTDS, domid, scinfo);
+    if (rc)
+        return 1;
+
+    domname = libxl_domid_to_name(ctx, domid);
+    for ( i = 0; i < scinfo->num_vcpus; i++ ) {
+        printf("%-33s %4d %4d %9"PRIu32" %9"PRIu32"\n",
+               domname,
+               domid,
+               scinfo->vcpus[i].vcpuid,
+               scinfo->vcpus[i].period,
+               scinfo->vcpus[i].budget);
+    }
+    free(domname);
+    return 0;
+}
+
+static int sched_rtds_vcpu_output_all(int domid,
+                                      libxl_vcpu_sched_params *scinfo)
+{
+    char *domname;
+    int rc = 0;
+    int i;
+
+    if (domid < 0) {
+        printf("%-33s %4s %4s %9s %9s\n", "Name", "ID",
+               "VCPU", "Period", "Budget");
+        return 0;
+    }
+
+    scinfo->num_vcpus = 0;
+    rc = sched_vcpu_get_all(LIBXL_SCHEDULER_RTDS, domid, scinfo);
+    if (rc)
+        return 1;
+
+    domname = libxl_domid_to_name(ctx, domid);
+    for ( i = 0; i < scinfo->num_vcpus; i++ ) {
+        printf("%-33s %4d %4d %9"PRIu32" %9"PRIu32"\n",
+               domname,
+               domid,
+               scinfo->vcpus[i].vcpuid,
+               scinfo->vcpus[i].period,
+               scinfo->vcpus[i].budget);
+    }
+    free(domname);
+    return 0;
+}
+
+static int sched_rtds_pool_output(uint32_t poolid)
+{
+    char *poolname;
+
+    poolname = libxl_cpupoolid_to_name(ctx, poolid);
+    printf("Cpupool %s: sched=RTDS\n", poolname);
+
+    free(poolname);
+    return 0;
+}
+
+static int sched_domain_output(libxl_scheduler sched, int (*output)(int),
+                               int (*pooloutput)(uint32_t), const char 
*cpupool)
+{
+    libxl_dominfo *info;
+    libxl_cpupoolinfo *poolinfo = NULL;
+    uint32_t poolid;
+    int nb_domain, n_pools = 0, i, p;
+    int rc = 0;
+
+    if (cpupool) {
+        if (libxl_cpupool_qualifier_to_cpupoolid(ctx, cpupool, &poolid, NULL) 
||
+            !libxl_cpupoolid_is_valid(ctx, poolid)) {
+            fprintf(stderr, "unknown cpupool \'%s\'\n", cpupool);
+            return 1;
+        }
+    }
+
+    info = libxl_list_domain(ctx, &nb_domain);
+    if (!info) {
+        fprintf(stderr, "libxl_list_domain failed.\n");
+        return 1;
+    }
+    poolinfo = libxl_list_cpupool(ctx, &n_pools);
+    if (!poolinfo) {
+        fprintf(stderr, "error getting cpupool info\n");
+        libxl_dominfo_list_free(info, nb_domain);
+        return 1;
+    }
+
+    for (p = 0; !rc && (p < n_pools); p++) {
+        if ((poolinfo[p].sched != sched) ||
+            (cpupool && (poolid != poolinfo[p].poolid)))
+            continue;
+
+        pooloutput(poolinfo[p].poolid);
+
+        output(-1);
+        for (i = 0; i < nb_domain; i++) {
+            if (info[i].cpupool != poolinfo[p].poolid)
+                continue;
+            rc = output(info[i].domid);
+            if (rc)
+                break;
+        }
+    }
+
+    libxl_cpupoolinfo_list_free(poolinfo, n_pools);
+    libxl_dominfo_list_free(info, nb_domain);
+    return 0;
+}
+
+static int sched_vcpu_output(libxl_scheduler sched,
+                             int (*output)(int, libxl_vcpu_sched_params *),
+                             int (*pooloutput)(uint32_t), const char *cpupool)
+{
+    libxl_dominfo *info;
+    libxl_cpupoolinfo *poolinfo = NULL;
+    uint32_t poolid;
+    int nb_domain, n_pools = 0, i, p;
+    int rc = 0;
+
+    if (cpupool) {
+        if (libxl_cpupool_qualifier_to_cpupoolid(ctx, cpupool, &poolid, NULL)
+            || !libxl_cpupoolid_is_valid(ctx, poolid)) {
+            fprintf(stderr, "unknown cpupool \'%s\'\n", cpupool);
+            return 1;
+        }
+    }
+
+    info = libxl_list_domain(ctx, &nb_domain);
+    if (!info) {
+        fprintf(stderr, "libxl_list_domain failed.\n");
+        return 1;
+    }
+    poolinfo = libxl_list_cpupool(ctx, &n_pools);
+    if (!poolinfo) {
+        fprintf(stderr, "error getting cpupool info\n");
+        libxl_dominfo_list_free(info, nb_domain);
+        return 1;
+    }
+
+    for (p = 0; !rc && (p < n_pools); p++) {
+        if ((poolinfo[p].sched != sched) ||
+            (cpupool && (poolid != poolinfo[p].poolid)))
+            continue;
+
+        pooloutput(poolinfo[p].poolid);
+
+        output(-1, NULL);
+        for (i = 0; i < nb_domain; i++) {
+            libxl_vcpu_sched_params scinfo;
+            if (info[i].cpupool != poolinfo[p].poolid)
+                continue;
+            libxl_vcpu_sched_params_init(&scinfo);
+            rc = output(info[i].domid, &scinfo);
+            libxl_vcpu_sched_params_dispose(&scinfo);
+            if (rc)
+                break;
+        }
+    }
+
+    libxl_cpupoolinfo_list_free(poolinfo, n_pools);
+    libxl_dominfo_list_free(info, nb_domain);
+    return 0;
+}
+
+/*
+ * <nothing>             : List all domain params and sched params from all 
pools
+ * -d [domid]            : List domain params for domain
+ * -d [domid] [params]   : Set domain params for domain
+ * -p [pool]             : list all domains and sched params for pool
+ * -s                    : List sched params for poolid 0
+ * -s [params]           : Set sched params for poolid 0
+ * -p [pool] -s          : List sched params for pool
+ * -p [pool] -s [params] : Set sched params for pool
+ * -p [pool] -d...       : Illegal
+ */
+int main_sched_credit(int argc, char **argv)
+{
+    const char *dom = NULL;
+    const char *cpupool = NULL;
+    int weight = 256, cap = 0;
+    int tslice = 0, ratelimit = 0;
+    bool opt_w = false, opt_c = false;
+    bool opt_t = false, opt_r = false;
+    bool opt_s = false;
+    int opt, rc;
+    static struct option opts[] = {
+        {"domain", 1, 0, 'd'},
+        {"weight", 1, 0, 'w'},
+        {"cap", 1, 0, 'c'},
+        {"schedparam", 0, 0, 's'},
+        {"tslice_ms", 1, 0, 't'},
+        {"ratelimit_us", 1, 0, 'r'},
+        {"cpupool", 1, 0, 'p'},
+        COMMON_LONG_OPTS
+    };
+
+    SWITCH_FOREACH_OPT(opt, "d:w:c:p:t:r:s", opts, "sched-credit", 0) {
+    case 'd':
+        dom = optarg;
+        break;
+    case 'w':
+        weight = strtol(optarg, NULL, 10);
+        opt_w = true;
+        break;
+    case 'c':
+        cap = strtol(optarg, NULL, 10);
+        opt_c = true;
+        break;
+    case 't':
+        tslice = strtol(optarg, NULL, 10);
+        opt_t = true;
+        break;
+    case 'r':
+        ratelimit = strtol(optarg, NULL, 10);
+        opt_r = true;
+        break;
+    case 's':
+        opt_s = true;
+        break;
+    case 'p':
+        cpupool = optarg;
+        break;
+    }
+
+    if ((cpupool || opt_s) && (dom || opt_w || opt_c)) {
+        fprintf(stderr, "Specifying a cpupool or schedparam is not "
+                "allowed with domain options.\n");
+        return EXIT_FAILURE;
+    }
+    if (!dom && (opt_w || opt_c)) {
+        fprintf(stderr, "Must specify a domain.\n");
+        return EXIT_FAILURE;
+    }
+    if (!opt_s && (opt_t || opt_r)) {
+        fprintf(stderr, "Must specify schedparam to set schedule "
+                "parameter values.\n");
+        return EXIT_FAILURE;
+    }
+
+    if (opt_s) {
+        libxl_sched_credit_params scparam;
+        uint32_t poolid = 0;
+
+        if (cpupool) {
+            if (libxl_cpupool_qualifier_to_cpupoolid(ctx, cpupool,
+                                                     &poolid, NULL) ||
+                !libxl_cpupoolid_is_valid(ctx, poolid)) {
+                fprintf(stderr, "unknown cpupool \'%s\'\n", cpupool);
+                return EXIT_FAILURE;
+            }
+        }
+
+        if (!opt_t && !opt_r) { /* Output scheduling parameters */
+            if (sched_credit_pool_output(poolid))
+                return EXIT_FAILURE;
+        } else { /* Set scheduling parameters*/
+            if (sched_credit_params_get(poolid, &scparam))
+                return EXIT_FAILURE;
+
+            if (opt_t)
+                scparam.tslice_ms = tslice;
+
+            if (opt_r)
+                scparam.ratelimit_us = ratelimit;
+
+            if (sched_credit_params_set(poolid, &scparam))
+                return EXIT_FAILURE;
+        }
+    } else if (!dom) { /* list all domain's credit scheduler info */
+        if (sched_domain_output(LIBXL_SCHEDULER_CREDIT,
+                                sched_credit_domain_output,
+                                sched_credit_pool_output,
+                                cpupool))
+            return EXIT_FAILURE;
+    } else {
+        uint32_t domid = xfind_domain(dom);
+
+        if (!opt_w && !opt_c) { /* output credit scheduler info */
+            sched_credit_domain_output(-1);
+            if (sched_credit_domain_output(domid))
+                return EXIT_FAILURE;
+        } else { /* set credit scheduler paramaters */
+            libxl_domain_sched_params scinfo;
+            libxl_domain_sched_params_init(&scinfo);
+            scinfo.sched = LIBXL_SCHEDULER_CREDIT;
+            if (opt_w)
+                scinfo.weight = weight;
+            if (opt_c)
+                scinfo.cap = cap;
+            rc = sched_domain_set(domid, &scinfo);
+            libxl_domain_sched_params_dispose(&scinfo);
+            if (rc)
+                return EXIT_FAILURE;
+        }
+    }
+
+    return EXIT_SUCCESS;
+}
+
+int main_sched_credit2(int argc, char **argv)
+{
+    const char *dom = NULL;
+    const char *cpupool = NULL;
+    int ratelimit = 0;
+    int weight = 256;
+    bool opt_s = false;
+    bool opt_r = false;
+    bool opt_w = false;
+    int opt, rc;
+    static struct option opts[] = {
+        {"domain", 1, 0, 'd'},
+        {"weight", 1, 0, 'w'},
+        {"schedparam", 0, 0, 's'},
+        {"ratelimit_us", 1, 0, 'r'},
+        {"cpupool", 1, 0, 'p'},
+        COMMON_LONG_OPTS
+    };
+
+    SWITCH_FOREACH_OPT(opt, "d:w:p:r:s", opts, "sched-credit2", 0) {
+    case 'd':
+        dom = optarg;
+        break;
+    case 'w':
+        weight = strtol(optarg, NULL, 10);
+        opt_w = true;
+        break;
+    case 's':
+        opt_s = true;
+        break;
+    case 'r':
+        ratelimit = strtol(optarg, NULL, 10);
+        opt_r = true;
+        break;
+    case 'p':
+        cpupool = optarg;
+        break;
+    }
+
+    if (cpupool && (dom || opt_w)) {
+        fprintf(stderr, "Specifying a cpupool is not allowed with other "
+                "options.\n");
+        return EXIT_FAILURE;
+    }
+    if (!dom && opt_w) {
+        fprintf(stderr, "Must specify a domain.\n");
+        return EXIT_FAILURE;
+    }
+
+    if (opt_s) {
+        libxl_sched_credit2_params scparam;
+        uint32_t poolid = 0;
+
+        if (cpupool) {
+            if (libxl_cpupool_qualifier_to_cpupoolid(ctx, cpupool,
+                                                     &poolid, NULL) ||
+                !libxl_cpupoolid_is_valid(ctx, poolid)) {
+                fprintf(stderr, "unknown cpupool \'%s\'\n", cpupool);
+                return EXIT_FAILURE;
+            }
+        }
+
+        if (!opt_r) { /* Output scheduling parameters */
+            if (sched_credit2_pool_output(poolid))
+                return EXIT_FAILURE;
+        } else {      /* Set scheduling parameters (so far, just ratelimit) */
+            scparam.ratelimit_us = ratelimit;
+            if (sched_credit2_params_set(poolid, &scparam))
+                return EXIT_FAILURE;
+        }
+    } else if (!dom) { /* list all domain's credit scheduler info */
+        if (sched_domain_output(LIBXL_SCHEDULER_CREDIT2,
+                                sched_credit2_domain_output,
+                                sched_credit2_pool_output,
+                                cpupool))
+            return EXIT_FAILURE;
+    } else {
+        uint32_t domid = xfind_domain(dom);
+
+        if (!opt_w) { /* output credit2 scheduler info */
+            sched_credit2_domain_output(-1);
+            if (sched_credit2_domain_output(domid))
+                return EXIT_FAILURE;
+        } else { /* set credit2 scheduler paramaters */
+            libxl_domain_sched_params scinfo;
+            libxl_domain_sched_params_init(&scinfo);
+            scinfo.sched = LIBXL_SCHEDULER_CREDIT2;
+            if (opt_w)
+                scinfo.weight = weight;
+            rc = sched_domain_set(domid, &scinfo);
+            libxl_domain_sched_params_dispose(&scinfo);
+            if (rc)
+                return EXIT_FAILURE;
+        }
+    }
+
+    return EXIT_SUCCESS;
+}
+
+/*
+ * <nothing>            : List all domain paramters and sched params
+ * -d [domid]           : List default domain params for domain
+ * -d [domid] [params]  : Set domain params for domain
+ * -d [domid] -v [vcpuid 1] -v [vcpuid 2] ...  :
+ * List per-VCPU params for domain
+ * -d [domid] -v all  : List all per-VCPU params for domain
+ * -v all  : List all per-VCPU params for all domains
+ * -d [domid] -v [vcpuid 1] [params] -v [vcpuid 2] [params] ...  :
+ * Set per-VCPU params for domain
+ * -d [domid] -v all [params]  : Set all per-VCPU params for domain
+ */
+int main_sched_rtds(int argc, char **argv)
+{
+    const char *dom = NULL;
+    const char *cpupool = NULL;
+    int *vcpus = (int *)xmalloc(sizeof(int)); /* IDs of VCPUs that change */
+    int *periods = (int *)xmalloc(sizeof(int)); /* period is in microsecond */
+    int *budgets = (int *)xmalloc(sizeof(int)); /* budget is in microsecond */
+    int v_size = 1; /* size of vcpus array */
+    int p_size = 1; /* size of periods array */
+    int b_size = 1; /* size of budgets array */
+    int v_index = 0; /* index in vcpus array */
+    int p_index =0; /* index in periods array */
+    int b_index =0; /* index for in budgets array */
+    bool opt_p = false;
+    bool opt_b = false;
+    bool opt_v = false;
+    bool opt_all = false; /* output per-dom parameters */
+    int opt, i, rc, r;
+    static struct option opts[] = {
+        {"domain", 1, 0, 'd'},
+        {"period", 1, 0, 'p'},
+        {"budget", 1, 0, 'b'},
+        {"vcpuid",1, 0, 'v'},
+        {"cpupool", 1, 0, 'c'},
+        COMMON_LONG_OPTS
+    };
+
+    SWITCH_FOREACH_OPT(opt, "d:p:b:v:c", opts, "sched-rtds", 0) {
+    case 'd':
+        dom = optarg;
+        break;
+    case 'p':
+        if (p_index >= p_size) {
+            /*
+             * periods array is full
+             * double the array size for new elements
+             */
+            p_size *= 2;
+            periods = xrealloc(periods, p_size);
+        }
+        periods[p_index++] = strtol(optarg, NULL, 10);
+        opt_p = 1;
+        break;
+    case 'b':
+        if (b_index >= b_size) { /* budgets array is full */
+            b_size *= 2;
+            budgets = xrealloc(budgets, b_size);
+        }
+        budgets[b_index++] = strtol(optarg, NULL, 10);
+        opt_b = 1;
+        break;
+    case 'v':
+        if (!strcmp(optarg, "all")) { /* get or set all vcpus of a domain */
+            opt_all = 1;
+            break;
+        }
+        if (v_index >= v_size) { /* vcpus array is full */
+            v_size *= 2;
+            vcpus = xrealloc(vcpus, v_size);
+        }
+        vcpus[v_index++] = strtol(optarg, NULL, 10);
+        opt_v = 1;
+        break;
+    case 'c':
+        cpupool = optarg;
+        break;
+    }
+
+    if (cpupool && (dom || opt_p || opt_b || opt_v || opt_all)) {
+        fprintf(stderr, "Specifying a cpupool is not allowed with "
+                "other options.\n");
+        r = EXIT_FAILURE;
+        goto out;
+    }
+    if (!dom && (opt_p || opt_b || opt_v)) {
+        fprintf(stderr, "Missing parameters.\n");
+        r = EXIT_FAILURE;
+        goto out;
+    }
+    if (dom && !opt_v && !opt_all && (opt_p || opt_b)) {
+        fprintf(stderr, "Must specify VCPU.\n");
+        r = EXIT_FAILURE;
+        goto out;
+    }
+    if (opt_v && opt_all) {
+        fprintf(stderr, "Incorrect VCPU IDs.\n");
+        r = EXIT_FAILURE;
+        goto out;
+    }
+    if (((v_index > b_index) && opt_b) || ((v_index > p_index) && opt_p)
+        || p_index != b_index) {
+        fprintf(stderr, "Incorrect number of period and budget\n");
+        r = EXIT_FAILURE;
+        goto out;
+    }
+
+    if ((!dom) && opt_all) {
+        /* get all domain's per-vcpu rtds scheduler parameters */
+        rc = -sched_vcpu_output(LIBXL_SCHEDULER_RTDS,
+                                sched_rtds_vcpu_output_all,
+                                sched_rtds_pool_output,
+                                cpupool);
+        if (rc) {
+            r = EXIT_FAILURE;
+            goto out;
+        }
+    } else if (!dom && !opt_all) {
+        /* list all domain's default scheduling parameters */
+        rc = -sched_domain_output(LIBXL_SCHEDULER_RTDS,
+                                  sched_rtds_domain_output,
+                                  sched_rtds_pool_output,
+                                  cpupool);
+        if (rc) {
+            r = EXIT_FAILURE;
+            goto out;
+        }
+    } else {
+        uint32_t domid = xfind_domain(dom);
+        if (!opt_v && !opt_all) { /* output default scheduling parameters */
+            sched_rtds_domain_output(-1);
+            rc = -sched_rtds_domain_output(domid);
+            if (rc) {
+                r = EXIT_FAILURE;
+                goto out;
+            }
+        } else if (!opt_p && !opt_b) {
+            /* get per-vcpu rtds scheduling parameters */
+            libxl_vcpu_sched_params scinfo;
+            libxl_vcpu_sched_params_init(&scinfo);
+            sched_rtds_vcpu_output(-1, &scinfo);
+            scinfo.num_vcpus = v_index;
+            if (v_index > 0) {
+                scinfo.vcpus = (libxl_sched_params *)
+                               xmalloc(sizeof(libxl_sched_params) * (v_index));
+                for (i = 0; i < v_index; i++)
+                    scinfo.vcpus[i].vcpuid = vcpus[i];
+                rc = -sched_rtds_vcpu_output(domid, &scinfo);
+            } else /* get params for all vcpus */
+                rc = -sched_rtds_vcpu_output_all(domid, &scinfo);
+            libxl_vcpu_sched_params_dispose(&scinfo);
+            if (rc) {
+                r = EXIT_FAILURE;
+                goto out;
+            }
+    } else if (opt_v || opt_all) {
+            /* set per-vcpu rtds scheduling parameters */
+            libxl_vcpu_sched_params scinfo;
+            libxl_vcpu_sched_params_init(&scinfo);
+            scinfo.sched = LIBXL_SCHEDULER_RTDS;
+            if (v_index > 0) {
+                scinfo.num_vcpus = v_index;
+                scinfo.vcpus = (libxl_sched_params *)
+                               xmalloc(sizeof(libxl_sched_params) * (v_index));
+                for (i = 0; i < v_index; i++) {
+                    scinfo.vcpus[i].vcpuid = vcpus[i];
+                    scinfo.vcpus[i].period = periods[i];
+                    scinfo.vcpus[i].budget = budgets[i];
+                }
+                rc = sched_vcpu_set(domid, &scinfo);
+            } else { /* set params for all vcpus */
+                scinfo.num_vcpus = 1;
+                scinfo.vcpus = (libxl_sched_params *)
+                               xmalloc(sizeof(libxl_sched_params));
+                scinfo.vcpus[0].period = periods[0];
+                scinfo.vcpus[0].budget = budgets[0];
+                rc = sched_vcpu_set_all(domid, &scinfo);
+            }
+
+            libxl_vcpu_sched_params_dispose(&scinfo);
+            if (rc) {
+                r = EXIT_FAILURE;
+                goto out;
+            }
+        }
+    }
+
+    r = EXIT_SUCCESS;
+out:
+    free(vcpus);
+    free(periods);
+    free(budgets);
+    return r;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.