From: Steve Muir Date: Fri, 17 Feb 2006 18:50:56 +0000 (+0000) Subject: Add support for guaranteed CPU shares X-Git-Tag: after-util-vserver-0_30_208-revert~50 X-Git-Url: http://git.onelab.eu/?p=util-vserver.git;a=commitdiff_plain;h=f061f5d3ea230ebc5132315131c00852ffb58269 Add support for guaranteed CPU shares --- diff --git a/lib/planetlab.c b/lib/planetlab.c index 6b5d936..879cb5d 100644 --- a/lib/planetlab.c +++ b/lib/planetlab.c @@ -33,6 +33,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include #include #include @@ -49,11 +50,14 @@ create_context(xid_t ctx, uint32_t flags, uint64_t bcaps, const rspec_t *rspec) struct vc_ctx_flags vc_flags; struct vc_rlimit vc_rlimit; - /* create context info */ + /* + * Create context info - this sets the STATE_SETUP and STATE_INIT flags. + * Don't ever clear the STATE_INIT flag, that makes us the init task. + */ if (vc_ctx_create(ctx) == VC_NOCTX) return -1; - /* set capabilities - these don't take effect until SETUP flags is unset */ + /* set capabilities - these don't take effect until SETUP flag is unset */ vc_caps.bcaps = bcaps; vc_caps.bmask = ~0ULL; /* currently unused */ vc_caps.ccaps = 0; /* don't want any of these */ @@ -61,14 +65,9 @@ create_context(xid_t ctx, uint32_t flags, uint64_t bcaps, const rspec_t *rspec) if (vc_set_ccaps(ctx, &vc_caps)) return -1; - /* ignore all flags except SETUP and scheduler flags */ - vc_flags.mask = VC_VXF_STATE_SETUP | VC_VXF_SCHED_FLAGS; - /* don't let user change scheduler flags */ - vc_flags.flagword = flags & ~VC_VXF_SCHED_FLAGS; /* SETUP not set */ - /* set scheduler parameters */ - vc_flags.flagword |= rspec->cpu_sched_flags; - pl_setsched(ctx, rspec->cpu_share, rspec->cpu_sched_flags); + if (pl_setsched(ctx, rspec->cpu_share, rspec->cpu_sched_flags)) + return -1; /* set resource limits */ vc_rlimit.min = VC_LIM_KEEP; @@ -83,6 +82,9 @@ create_context(xid_t ctx, uint32_t flags, uint64_t bcaps, const rspec_t *rspec) return -1; /* set flags, unset SETUP flag - this allows other processes to migrate */ + vc_flags.mask = VC_VXF_STATE_SETUP | VC_VXF_SCHED_FLAGS; + flags = 0; /* XXX - ignore flags parameter */ + vc_flags.flagword = flags | rspec->cpu_sched_flags; /* SETUP cleared */ if (vc_set_cflags(ctx, &vc_flags)) return -1; @@ -133,10 +135,27 @@ pl_chcontext(xid_t ctx, uint32_t flags, uint64_t bcaps, const rspec_t *rspec) return 0; } +/* it's okay for a syscall to fail because the context doesn't exist */ +#define VC_SYSCALL(x) \ +do \ +{ \ + if (x) \ + return errno == ESRCH ? 0 : -1; \ +} \ +while (0) + + int pl_setsched(xid_t ctx, uint32_t cpu_share, uint32_t cpu_sched_flags) { struct vc_set_sched vc_sched; + struct vc_ctx_flags vc_flags; + + if (cpu_sched_flags & ~VC_VXF_SCHED_FLAGS) + { + errno = EINVAL; + return -1; + } vc_sched.set_mask = (VC_VXSM_FILL_RATE | VC_VXSM_INTERVAL | VC_VXSM_TOKENS | VC_VXSM_TOKENS_MIN | VC_VXSM_TOKENS_MAX); @@ -146,5 +165,18 @@ pl_setsched(xid_t ctx, uint32_t cpu_share, uint32_t cpu_sched_flags) vc_sched.tokens_min = 50; /* need this many tokens to run */ vc_sched.tokens_max = 100; /* max accumulated number of tokens */ - return vc_set_sched(ctx, &vc_sched); + VC_SYSCALL(vc_set_sched(ctx, &vc_sched)); + + /* get current flag values */ + VC_SYSCALL(vc_get_cflags(ctx, &vc_flags)); + + /* the only flag which ever changes is the SCHED_SHARE bit */ + if ((vc_flags.flagword ^ cpu_sched_flags) & VC_VXF_SCHED_SHARE) + { + vc_flags.mask = VC_VXF_SCHED_SHARE; + vc_flags.flagword = cpu_sched_flags & VC_VXF_SCHED_FLAGS; + VC_SYSCALL(vc_set_cflags(ctx, &vc_flags)); + } + + return 0; } diff --git a/python/vserver.py b/python/vserver.py index 8224abd..ee061bb 100644 --- a/python/vserver.py +++ b/python/vserver.py @@ -151,9 +151,13 @@ class VServer: if cpu_share == int(self.config.get("CPULIMIT", -1)): return - - self.__update_config_file(self.config_file, { "CPULIMIT": cpu_share }) + # XXX - don't want to have to deal with nm_ flags here + cpu_guaranteed = int(self.resources.get("nm_sched_flags", + None) == "guaranteed") + cpu_config = { "CPULIMIT": cpu_share, "CPUGUARANTEED": cpu_guaranteed } + self.__update_config_file(self.config_file, cpu_config) if self.vm_running: + # caller must ensure cpu_share is consistent with self.resources vserverimpl.setsched(self.ctx, self.resources) def get_sched(self): diff --git a/python/vserverimpl.c b/python/vserverimpl.c index 6b1284c..fbb94f5 100644 --- a/python/vserverimpl.c +++ b/python/vserverimpl.c @@ -44,27 +44,52 @@ POSSIBILITY OF SUCH DAMAGE. #include "vserver.h" #include "vserver-internal.h" +#define NONE ({ Py_INCREF(Py_None); Py_None; }) + static int get_rspec(PyObject *resources, rspec_t *rspec) { + int result = -1; PyObject *cpu_share; + PyObject *sched_flags = NULL; if (!PyMapping_Check(resources)) { PyErr_SetString(PyExc_TypeError, "invalid rspec"); return -1; } - if ((cpu_share = PyMapping_GetItemString(resources, "nm_cpu_share"))) + + /* get CPU share */ + if (!(cpu_share = PyMapping_GetItemString(resources, "nm_cpu_share"))) + return -1; + if (!PyInt_Check(cpu_share)) { - if (PyInt_Check(cpu_share)) - { - rspec->cpu_share = PyInt_AS_LONG(cpu_share); - return 0; - } PyErr_SetString(PyExc_TypeError, "nm_cpu_share not an integer"); + goto out; + } + rspec->cpu_share = PyInt_AS_LONG(cpu_share); + + /* check whether this share should be guaranteed */ + rspec->cpu_sched_flags = VC_VXF_SCHED_FLAGS; + result = 0; + if ((sched_flags = PyMapping_GetItemString(resources, "nm_sched_flags"))) + { + const char *flagstr; + + if (!(flagstr = PyString_AsString(sched_flags))) + result = -1; + else if (!strcmp(flagstr, "guaranteed")) + rspec->cpu_sched_flags &= ~VC_VXF_SCHED_SHARE; + Py_DECREF(sched_flags); } + else + /* not an error if nm_sched_flags is missing */ + PyErr_Clear(); + + out: + Py_DECREF(cpu_share); - return -1; + return result; } /* @@ -86,7 +111,7 @@ vserver_chcontext(PyObject *self, PyObject *args) if (pl_chcontext(ctx, flags, bcaps, &rspec)) return PyErr_SetFromErrno(PyExc_OSError); - return Py_None; + return NONE; } static PyObject * @@ -103,7 +128,6 @@ vserver_set_rlimit(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, "IiL", &xid, &resource, &limits.hard)) return NULL; - ret = Py_None; if (vc_set_rlimit(xid, resource, &limits)) ret = PyErr_SetFromErrno(PyExc_OSError); else if (vc_get_rlimit(xid, resource, &limits)==-1) @@ -128,7 +152,6 @@ vserver_get_rlimit(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, "Ii", &xid, &resource)) return NULL; - ret = Py_None; if (vc_get_rlimit(xid, resource, &limits)==-1) ret = PyErr_SetFromErrno(PyExc_OSError); else @@ -156,7 +179,7 @@ vserver_setsched(PyObject *self, PyObject *args) errno != ESRCH) return PyErr_SetFromErrno(PyExc_OSError); - return Py_None; + return NONE; } static PyObject * @@ -219,7 +242,7 @@ vserver_set_dlimit(PyObject *self, PyObject *args) vserver(VCMD_set_dlimit, xid, &data)) return PyErr_SetFromErrno(PyExc_OSError); - return Py_None; + return NONE; } static PyObject * @@ -239,7 +262,7 @@ vserver_unset_dlimit(PyObject *self, PyObject *args) if (vserver(VCMD_rem_dlimit, xid, &init) && errno != ESRCH) return PyErr_SetFromErrno(PyExc_OSError); - return Py_None; + return NONE; } static PyObject * @@ -254,7 +277,7 @@ vserver_killall(PyObject *self, PyObject *args) if (vc_ctx_kill(ctx, 0, sig) && errno != ESRCH) return PyErr_SetFromErrno(PyExc_OSError); - return Py_None; + return NONE; } static PyMethodDef methods[] = { diff --git a/util-vserver.spec b/util-vserver.spec index 2699259..65a7eaa 100644 --- a/util-vserver.spec +++ b/util-vserver.spec @@ -17,7 +17,7 @@ %define name util-vserver %define version 0.30.208 -%define release 8%{?pldistro:.%{pldistro}}%{?date:.%{date}} +%define release 9%{?pldistro:.%{pldistro}}%{?date:.%{date}} %define _without_dietlibc 1 %define _without_xalan 1 @@ -384,6 +384,9 @@ done %changelog +* Fri Feb 17 2006 Steve Muir +- add support for setting guaranteed CPU share flag in rspec + * Fri Jan 13 2006 Steve Muir - fix bug in python/vserverimpl.c where attempting to adjust CPU share for a context that didn't exist would cause an error (it should be a diff --git a/util-vserver.spec.in b/util-vserver.spec.in index ce9c031..3f96a47 100644 --- a/util-vserver.spec.in +++ b/util-vserver.spec.in @@ -17,7 +17,7 @@ %define name @PACKAGE@ %define version @VERSION@ -%define release 8%{?pldistro:.%{pldistro}}%{?date:.%{date}} +%define release 9%{?pldistro:.%{pldistro}}%{?date:.%{date}} %define _without_dietlibc 1 %define _without_xalan 1 @@ -384,6 +384,14 @@ done %changelog +* Fri Feb 17 2006 Steve Muir +- add support for setting guaranteed CPU share flag in rspec + +* Fri Jan 13 2006 Steve Muir +- fix bug in python/vserverimpl.c where attempting to adjust CPU share + for a context that didn't exist would cause an error (it should be a + safe no-op) + * Fri Dec 2 2005 Steve Muir - fix bugs in python/vserverimpl.c where exceptions were not raised when they should be and thus occured later at unexpected times