]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Add LXC scheduling parameters and support in virsh schedinfo
authorDan Smith <danms@us.ibm.com>
Wed, 8 Oct 2008 16:28:48 +0000 (16:28 +0000)
committerDan Smith <danms@us.ibm.com>
Wed, 8 Oct 2008 16:28:48 +0000 (16:28 +0000)
ChangeLog
docs/virsh.pod
src/cgroup.c
src/cgroup.h
src/lxc_driver.c
src/virsh.c

index 5b1240068c6a268b37bd594898c3fc6f3744a8c2..beee23d4cd66c0185752165296aab641a692cc2b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
        * src/cgroup.c: use safewrite()
index 0715e5c524b7d54b00d22f21b11b8c02f0cdff5a..f59be4511f7682c843efe9ff7387a00834d97b87 100644 (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
 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>
 
-Allows to show (and set) the domain scheduler parameters. This is currently
-only defined for XEN_CREDIT scheduler, and the optional weight and cap
-arguments allows to set the associated parameters in that scheduler if
-provided.
+Allows to show (and set) the domain scheduler parameters.
+
+B<Note>: The weight and cap parameters are defined only for the
+XEN_CREDIT scheduler and are now I<DEPRECATED>.
 
 =item B<setmem> I<domain-id> B<kilobytes>
 
index f1801c89ce1bb05ef3b3cf2213cac8877d33c698..36e2907b035300506067bec74fb1ec9a1df70d6f 100644 (file)
@@ -224,26 +224,6 @@ static int virCgroupSetValueU64(virCgroupPtr group,
     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,
                                 const char *key,
                                 char **value)
@@ -293,9 +273,29 @@ out:
     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,
-                                uint64_t *value)
+                                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 virCgroupGetValueI64(virCgroupPtr group,
+                                const char *key,
+                                int64_t *value)
 {
     char *strval = NULL;
     int rc = 0;
@@ -304,17 +304,18 @@ static int virCgroupGetValueU64(virCgroupPtr group,
     if (rc != 0)
         goto out;
 
-    if (sscanf(strval, "%" SCNu64, value) != 1)
+    if (sscanf(strval, "%" SCNi64, value) != 1)
         rc = -EINVAL;
 out:
     VIR_FREE(strval);
 
     return rc;
 }
+#endif
 
-static int virCgroupGetValueI64(virCgroupPtr group,
+static int virCgroupGetValueU64(virCgroupPtr group,
                                 const char *key,
-                                int64_t *value)
+                                uint64_t *value)
 {
     char *strval = NULL;
     int rc = 0;
@@ -323,14 +324,13 @@ static int virCgroupGetValueI64(virCgroupPtr group,
     if (rc != 0)
         goto out;
 
-    if (sscanf(strval, "%" SCNi64, value) != 1)
+    if (sscanf(strval, "%" SCNu64, value) != 1)
         rc = -EINVAL;
 out:
     VIR_FREE(strval);
 
     return rc;
 }
-#endif
 
 static int _virCgroupInherit(const char *path,
                              const char *key)
@@ -760,3 +760,13 @@ out:
 
     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);
+}
index 7aca3d095e65f9ad9c3bffb14befb05d8d771423..193da63f4e9a8bba6b83ebfced84d0635654fc7e 100644 (file)
@@ -36,6 +36,9 @@ int virCgroupAllowDevice(virCgroupPtr group,
                          int major,
                          int minor);
 
+int virCgroupSetCpuShares(virCgroupPtr group, unsigned long shares);
+int virCgroupGetCpuShares(virCgroupPtr group, unsigned long *shares);
+
 int virCgroupRemove(virCgroupPtr group);
 
 void virCgroupFree(virCgroupPtr *group);
index 64c3d219415b9ca040558a9c9c141792fed31b77..30c3cab06454d8faa442ca117f44489f8122b9d0 100644 (file)
@@ -35,6 +35,7 @@
 #include <unistd.h>
 #include <wait.h>
 
+#include "internal.h"
 #include "lxc_conf.h"
 #include "lxc_container.h"
 #include "lxc_driver.h"
@@ -1144,6 +1145,94 @@ static int lxcVersion(virConnectPtr conn, unsigned long *version)
     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 */
 static virDriver lxcDriver = {
     VIR_DRV_LXC, /* the number virDrvNo */
@@ -1193,9 +1282,9 @@ static virDriver lxcDriver = {
     NULL, /* domainDetachDevice */
     NULL, /* domainGetAutostart */
     NULL, /* domainSetAutostart */
-    NULL, /* domainGetSchedulerType */
-    NULL, /* domainGetSchedulerParameters */
-    NULL, /* domainSetSchedulerParameters */
+    lxcGetSchedulerType, /* domainGetSchedulerType */
+    lxcGetSchedulerParameters, /* domainGetSchedulerParameters */
+    lxcSetSchedulerParameters, /* domainSetSchedulerParameters */
     NULL, /* domainMigratePrepare */
     NULL, /* domainMigratePerform */
     NULL, /* domainMigrateFinish */
@@ -1207,7 +1296,6 @@ static virDriver lxcDriver = {
     NULL, /* getFreeMemory */
 };
 
-
 static virStateDriver lxcStateDriver = {
     .initialize = lxcStartup,
     .cleanup = lxcShutdown,
index 00f928fec5912f186b046758d6b5dc05ed2152e7..eaed61d75969a93045b0131a616626031f7cda55 100644 (file)
@@ -1112,6 +1112,7 @@ static const vshCmdInfo info_schedinfo[] = {
 
 static const vshCmdOptDef opts_schedinfo[] = {
     {"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")},
     {"cap", VSH_OT_INT, VSH_OFLAG_NONE, gettext_noop("cap for XEN_CREDIT")},
     {NULL, 0, 0, NULL}
@@ -1121,6 +1122,9 @@ static int
 cmdSchedinfo(vshControl *ctl, const vshCmd *cmd)
 {
     char *schedulertype;
+    char *set;
+    char *param_name = NULL;
+    long long int param_value = 0;
     virDomainPtr dom;
     virSchedParameterPtr params = NULL;
     int i, ret;
@@ -1128,6 +1132,7 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd)
     int nr_inputparams = 0;
     int inputparams = 0;
     int weightfound = 0;
+    int setfound = 0;
     int weight = 0;
     int capfound = 0;
     int cap = 0;
@@ -1141,7 +1146,7 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd)
     if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", NULL)))
         return FALSE;
 
-    /* Currently supports Xen Credit only */
+    /* Deprecated Xen-only options */
     if(vshCommandOptBool(cmd, "weight")) {
         weight = vshCommandOptInt(cmd, "weight", &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);
     if (params == NULL) {
         goto cleanup;
@@ -1180,7 +1204,14 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd)
          params[inputparams].value.ui = cap;
          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);
 
@@ -1247,6 +1278,7 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd)
     }
  cleanup:
     free(params);
+    free(param_name);
     virDomainFree(dom);
     return ret_val;
 }