#include <errno.h>
#include <stdint.h>
+#include <stdio.h>
#include <unistd.h>
#include <sys/resource.h>
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 */
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;
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;
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);
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;
}
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):
#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;
}
/*
if (pl_chcontext(ctx, flags, bcaps, &rspec))
return PyErr_SetFromErrno(PyExc_OSError);
- return Py_None;
+ return NONE;
}
static PyObject *
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)
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
errno != ESRCH)
return PyErr_SetFromErrno(PyExc_OSError);
- return Py_None;
+ return NONE;
}
static PyObject *
vserver(VCMD_set_dlimit, xid, &data))
return PyErr_SetFromErrno(PyExc_OSError);
- return Py_None;
+ return NONE;
}
static PyObject *
if (vserver(VCMD_rem_dlimit, xid, &init) && errno != ESRCH)
return PyErr_SetFromErrno(PyExc_OSError);
- return Py_None;
+ return NONE;
}
static PyObject *
if (vc_ctx_kill(ctx, 0, sig) && errno != ESRCH)
return PyErr_SetFromErrno(PyExc_OSError);
- return Py_None;
+ return NONE;
}
static PyMethodDef methods[] = {
%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
%changelog
+* Fri Feb 17 2006 Steve Muir <smuir@cs.princeton.edu>
+- add support for setting guaranteed CPU share flag in rspec
+
* Fri Jan 13 2006 Steve Muir <smuir@cs.princeton.edu>
- 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
%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
%changelog
+* Fri Feb 17 2006 Steve Muir <smuir@cs.princeton.edu>
+- add support for setting guaranteed CPU share flag in rspec
+
+* Fri Jan 13 2006 Steve Muir <smuir@cs.princeton.edu>
+- 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 <smuir@cs.princeton.edu>
- fix bugs in python/vserverimpl.c where exceptions were not raised when
they should be and thus occured later at unexpected times