Add LXC scheduling parameters and support in virsh schedinfo

This commit is contained in:
Dan Smith 2008-10-08 16:28:48 +00:00
parent 6d670a1fc1
commit 6c504d6a7c
6 changed files with 179 additions and 39 deletions

View File

@ -1,3 +1,8 @@
Wed Oct 8 08:29:25 PDT 2008 Dan Smith <danms@us.ibm.com>
* src/cgroup.c src/cgroup.h: Add cpu shares manipulation
* src/lxc_driver.c: Add scheduler parameters interface for cpu shares
* src/virsh.c: Add generic scheduler parameter interface
Wed Oct 8 15:42:44 CEST 2008 Daniel Veillard <veillard@redhat.com> Wed Oct 8 15:42:44 CEST 2008 Daniel Veillard <veillard@redhat.com>
* src/cgroup.c: use safewrite() * src/cgroup.c: use safewrite()

View File

@ -318,12 +318,14 @@ This is roughly equivalent to doing a hibernate on a running computer,
with all the same limitations. Open network connections may be with all the same limitations. Open network connections may be
severed upon restore, as TCP timeouts may have expired. severed upon restore, as TCP timeouts may have expired.
=item B<schedinfo> optional I<--set> B<parameter=value> I<domain-id>
=item B<schedinfo> optional I<--weight> B<number> optional I<--cap> B<number> I<domain-id> =item B<schedinfo> optional I<--weight> B<number> optional I<--cap> B<number> I<domain-id>
Allows to show (and set) the domain scheduler parameters. This is currently Allows to show (and set) the domain scheduler parameters.
only defined for XEN_CREDIT scheduler, and the optional weight and cap
arguments allows to set the associated parameters in that scheduler if B<Note>: The weight and cap parameters are defined only for the
provided. XEN_CREDIT scheduler and are now I<DEPRECATED>.
=item B<setmem> I<domain-id> B<kilobytes> =item B<setmem> I<domain-id> B<kilobytes>

View File

@ -224,26 +224,6 @@ static int virCgroupSetValueU64(virCgroupPtr group,
return rc; return rc;
} }
#if 0
/* This is included for completeness, but not yet used */
static int virCgroupSetValueI64(virCgroupPtr group,
const char *key,
int64_t value)
{
char *strval = NULL;
int rc;
if (asprintf(&strval, "%" PRIi64, value) == -1)
return -ENOMEM;
rc = virCgroupSetValueStr(group, key, strval);
VIR_FREE(strval);
return rc;
}
static int virCgroupGetValueStr(virCgroupPtr group, static int virCgroupGetValueStr(virCgroupPtr group,
const char *key, const char *key,
char **value) char **value)
@ -293,20 +273,21 @@ out:
return rc; return rc;
} }
static int virCgroupGetValueU64(virCgroupPtr group, #if 0
/* This is included for completeness, but not yet used */
static int virCgroupSetValueI64(virCgroupPtr group,
const char *key, const char *key,
uint64_t *value) int64_t value)
{ {
char *strval = NULL; char *strval = NULL;
int rc = 0; int rc;
rc = virCgroupGetValueStr(group, key, &strval); if (asprintf(&strval, "%" PRIi64, value) == -1)
if (rc != 0) return -ENOMEM;
goto out;
rc = virCgroupSetValueStr(group, key, strval);
if (sscanf(strval, "%" SCNu64, value) != 1)
rc = -EINVAL;
out:
VIR_FREE(strval); VIR_FREE(strval);
return rc; return rc;
@ -332,6 +313,25 @@ out:
} }
#endif #endif
static int virCgroupGetValueU64(virCgroupPtr group,
const char *key,
uint64_t *value)
{
char *strval = NULL;
int rc = 0;
rc = virCgroupGetValueStr(group, key, &strval);
if (rc != 0)
goto out;
if (sscanf(strval, "%" SCNu64, value) != 1)
rc = -EINVAL;
out:
VIR_FREE(strval);
return rc;
}
static int _virCgroupInherit(const char *path, static int _virCgroupInherit(const char *path,
const char *key) const char *key)
{ {
@ -760,3 +760,13 @@ out:
return rc; return rc;
} }
int virCgroupSetCpuShares(virCgroupPtr group, unsigned long shares)
{
return virCgroupSetValueU64(group, "cpu.shares", (uint64_t)shares);
}
int virCgroupGetCpuShares(virCgroupPtr group, unsigned long *shares)
{
return virCgroupGetValueU64(group, "cpu.shares", (uint64_t *)shares);
}

View File

@ -36,6 +36,9 @@ int virCgroupAllowDevice(virCgroupPtr group,
int major, int major,
int minor); int minor);
int virCgroupSetCpuShares(virCgroupPtr group, unsigned long shares);
int virCgroupGetCpuShares(virCgroupPtr group, unsigned long *shares);
int virCgroupRemove(virCgroupPtr group); int virCgroupRemove(virCgroupPtr group);
void virCgroupFree(virCgroupPtr *group); void virCgroupFree(virCgroupPtr *group);

View File

@ -35,6 +35,7 @@
#include <unistd.h> #include <unistd.h>
#include <wait.h> #include <wait.h>
#include "internal.h"
#include "lxc_conf.h" #include "lxc_conf.h"
#include "lxc_container.h" #include "lxc_container.h"
#include "lxc_driver.h" #include "lxc_driver.h"
@ -1144,6 +1145,94 @@ static int lxcVersion(virConnectPtr conn, unsigned long *version)
return 0; return 0;
} }
static char *lxcGetSchedulerType(virDomainPtr domain, int *nparams)
{
if (nparams)
*nparams = 1;
return strdup("posix");
}
static int lxcSetSchedulerParameters(virDomainPtr _domain,
virSchedParameterPtr params,
int nparams)
{
int i;
int rc;
virCgroupPtr group;
virDomainObjPtr domain;
if (virCgroupHaveSupport() != 0)
return 0;
domain = virDomainFindByUUID(lxc_driver->domains, _domain->uuid);
if (domain == NULL) {
lxcError(NULL, _domain, VIR_ERR_INTERNAL_ERROR,
_("No such domain %s"), _domain->uuid);
return -EINVAL;
}
rc = virCgroupForDomain(domain->def, "lxc", &group);
if (rc != 0)
return rc;
for (i = 0; i < nparams; i++) {
virSchedParameterPtr param = &params[i];
if (STREQ(param->field, "cpu_shares")) {
rc = virCgroupSetCpuShares(group, params[i].value.ui);
} else {
lxcError(NULL, _domain, VIR_ERR_INVALID_ARG,
_("Invalid parameter `%s'"), param->field);
rc = -ENOENT;
goto out;
}
}
rc = 0;
out:
virCgroupFree(&group);
return rc;
}
static int lxcGetSchedulerParameters(virDomainPtr _domain,
virSchedParameterPtr params,
int *nparams)
{
int rc = 0;
virCgroupPtr group;
virDomainObjPtr domain;
if (virCgroupHaveSupport() != 0)
return 0;
if ((*nparams) != 1) {
lxcError(NULL, _domain, VIR_ERR_INVALID_ARG,
_("Invalid parameter count"));
return -1;
}
domain = virDomainFindByUUID(lxc_driver->domains, _domain->uuid);
if (domain == NULL) {
lxcError(NULL, _domain, VIR_ERR_INTERNAL_ERROR,
_("No such domain %s"), _domain->uuid);
return -ENOENT;
}
rc = virCgroupForDomain(domain->def, "lxc", &group);
if (rc != 0)
return rc;
rc = virCgroupGetCpuShares(group, (unsigned long *)&params[0].value.ul);
strncpy(params[0].field, "cpu_shares", sizeof(params[0].field));
params[0].type = VIR_DOMAIN_SCHED_FIELD_ULLONG;
virCgroupFree(&group);
return rc;
}
/* Function Tables */ /* Function Tables */
static virDriver lxcDriver = { static virDriver lxcDriver = {
VIR_DRV_LXC, /* the number virDrvNo */ VIR_DRV_LXC, /* the number virDrvNo */
@ -1193,9 +1282,9 @@ static virDriver lxcDriver = {
NULL, /* domainDetachDevice */ NULL, /* domainDetachDevice */
NULL, /* domainGetAutostart */ NULL, /* domainGetAutostart */
NULL, /* domainSetAutostart */ NULL, /* domainSetAutostart */
NULL, /* domainGetSchedulerType */ lxcGetSchedulerType, /* domainGetSchedulerType */
NULL, /* domainGetSchedulerParameters */ lxcGetSchedulerParameters, /* domainGetSchedulerParameters */
NULL, /* domainSetSchedulerParameters */ lxcSetSchedulerParameters, /* domainSetSchedulerParameters */
NULL, /* domainMigratePrepare */ NULL, /* domainMigratePrepare */
NULL, /* domainMigratePerform */ NULL, /* domainMigratePerform */
NULL, /* domainMigrateFinish */ NULL, /* domainMigrateFinish */
@ -1207,7 +1296,6 @@ static virDriver lxcDriver = {
NULL, /* getFreeMemory */ NULL, /* getFreeMemory */
}; };
static virStateDriver lxcStateDriver = { static virStateDriver lxcStateDriver = {
.initialize = lxcStartup, .initialize = lxcStartup,
.cleanup = lxcShutdown, .cleanup = lxcShutdown,

View File

@ -1112,6 +1112,7 @@ static const vshCmdInfo info_schedinfo[] = {
static const vshCmdOptDef opts_schedinfo[] = { static const vshCmdOptDef opts_schedinfo[] = {
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")}, {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")},
{"set", VSH_OT_STRING, VSH_OFLAG_NONE, gettext_noop("parameter=value")},
{"weight", VSH_OT_INT, VSH_OFLAG_NONE, gettext_noop("weight for XEN_CREDIT")}, {"weight", VSH_OT_INT, VSH_OFLAG_NONE, gettext_noop("weight for XEN_CREDIT")},
{"cap", VSH_OT_INT, VSH_OFLAG_NONE, gettext_noop("cap for XEN_CREDIT")}, {"cap", VSH_OT_INT, VSH_OFLAG_NONE, gettext_noop("cap for XEN_CREDIT")},
{NULL, 0, 0, NULL} {NULL, 0, 0, NULL}
@ -1121,6 +1122,9 @@ static int
cmdSchedinfo(vshControl *ctl, const vshCmd *cmd) cmdSchedinfo(vshControl *ctl, const vshCmd *cmd)
{ {
char *schedulertype; char *schedulertype;
char *set;
char *param_name = NULL;
long long int param_value = 0;
virDomainPtr dom; virDomainPtr dom;
virSchedParameterPtr params = NULL; virSchedParameterPtr params = NULL;
int i, ret; int i, ret;
@ -1128,6 +1132,7 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd)
int nr_inputparams = 0; int nr_inputparams = 0;
int inputparams = 0; int inputparams = 0;
int weightfound = 0; int weightfound = 0;
int setfound = 0;
int weight = 0; int weight = 0;
int capfound = 0; int capfound = 0;
int cap = 0; int cap = 0;
@ -1141,7 +1146,7 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd)
if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", NULL))) if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", NULL)))
return FALSE; return FALSE;
/* Currently supports Xen Credit only */ /* Deprecated Xen-only options */
if(vshCommandOptBool(cmd, "weight")) { if(vshCommandOptBool(cmd, "weight")) {
weight = vshCommandOptInt(cmd, "weight", &weightfound); weight = vshCommandOptInt(cmd, "weight", &weightfound);
if (!weightfound) { if (!weightfound) {
@ -1162,6 +1167,25 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd)
} }
} }
if(vshCommandOptBool(cmd, "set")) {
set = vshCommandOptString(cmd, "set", &setfound);
if (!setfound) {
vshError(ctl, FALSE, "%s", _("Error getting param"));
goto cleanup;
}
param_name = vshMalloc(ctl, strlen(set) + 1);
if (param_name == NULL)
goto cleanup;
if (sscanf(set, "%[^=]=%i", param_name, &param_value) != 2) {
vshError(ctl, FALSE, "%s", _("Invalid value of param"));
goto cleanup;
}
nr_inputparams++;
}
params = vshMalloc(ctl, sizeof (virSchedParameter) * nr_inputparams); params = vshMalloc(ctl, sizeof (virSchedParameter) * nr_inputparams);
if (params == NULL) { if (params == NULL) {
goto cleanup; goto cleanup;
@ -1180,7 +1204,14 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd)
params[inputparams].value.ui = cap; params[inputparams].value.ui = cap;
inputparams++; inputparams++;
} }
/* End Currently supports Xen Credit only */ /* End Deprecated Xen-only options */
if (setfound) {
strncpy(params[inputparams].field,param_name,sizeof(params[0].field));
params[inputparams].type = VIR_DOMAIN_SCHED_FIELD_LLONG;
params[inputparams].value.l = param_value;
inputparams++;
}
assert (inputparams == nr_inputparams); assert (inputparams == nr_inputparams);
@ -1247,6 +1278,7 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd)
} }
cleanup: cleanup:
free(params); free(params);
free(param_name);
virDomainFree(dom); virDomainFree(dom);
return ret_val; return ret_val;
} }