#define NONE inc_and_ret_none()
+#define PL_INSECURE_BCAPS (vc_get_insecurebcaps() | (1 << VC_CAP_NET_BIND_SERVICE))
+
/*
* context create
*/
if (!PyArg_ParseTuple(args, "I|K", &ctx, &bcaps))
return NULL;
- bcaps |= ~(vc_get_insecurebcaps() | (1 << VC_CAP_NET_BIND_SERVICE));
+ bcaps |= ~PL_INSECURE_BCAPS;
if ((ctx_is_new = pl_chcontext(ctx, bcaps, 0)) < 0)
return PyErr_SetFromErrno(PyExc_OSError);
static PyObject *
vserver_set_rlimit(PyObject *self, PyObject *args) {
struct vc_rlimit limits;
- struct rlimit lim;
+ struct vc_rlimit_mask mask;
+ uint32_t bitmask;
xid_t xid;
- int resource, lresource;
+ int resource;
PyObject *ret;
limits.min = VC_LIM_KEEP;
if (!PyArg_ParseTuple(args, "IiLLL", &xid, &resource, &limits.hard, &limits.soft, &limits.min))
return NULL;
- lresource = resource;
- switch (resource) {
- case VC_VLIMIT_NSOCK:
- case VC_VLIMIT_ANON:
- case VC_VLIMIT_SHMEM:
- goto do_vc_set_rlimit;
- case VC_VLIMIT_OPENFD:
- lresource = RLIMIT_NOFILE;
- break;
- default:
- break;
- }
-
- getrlimit(lresource,&lim);
- if (adjust_lim(&limits,&lim)) {
- setrlimit(lresource, &lim);
- }
-
- do_vc_set_rlimit:
errno = 0;
- if (vc_set_rlimit(xid, resource, &limits)==-1)
+
+ if (vc_get_rlimit_mask(xid, &mask)==-1) {
ret = PyErr_SetFromErrno(PyExc_OSError);
- else
- ret = __vserver_get_rlimit(xid, resource);
+ } else {
+ bitmask = (1<<resource);
+ if ((mask.min|mask.soft|mask.hard) & bitmask)
+ if (vc_set_rlimit(xid, resource, &limits)==-1)
+ ret = PyErr_SetFromErrno(PyExc_OSError);
+ else
+ ret = __vserver_get_rlimit(xid, resource);
+ }
return ret;
}
vserver_setsched(PyObject *self, PyObject *args)
{
xid_t ctx;
+ uint32_t cpu_min;
uint32_t cpu_share;
- uint32_t cpu_sched_flags = VC_VXF_SCHED_FLAGS;
- if (!PyArg_ParseTuple(args, "II|I", &ctx, &cpu_share, &cpu_sched_flags))
+ if (!PyArg_ParseTuple(args, "II|I", &ctx, &cpu_min, &cpu_share))
return NULL;
/* ESRCH indicates that there are no processes in the context */
- if (pl_setsched(ctx, cpu_share, cpu_sched_flags) &&
+ if (pl_setsched(ctx, cpu_min, cpu_share) &&
errno != ESRCH)
return PyErr_SetFromErrno(PyExc_OSError);
if (!PyArg_ParseTuple(args, "IK", &ctx, &caps.bcaps))
return NULL;
- caps.bmask = vc_get_insecurebcaps();
+ caps.bmask = PL_INSECURE_BCAPS;
caps.cmask = caps.ccaps = 0;
if (vc_set_ccaps(ctx, &caps) == -1 && errno != ESRCH)
return PyErr_SetFromErrno(PyExc_OSError);
return NULL;
if (vc_get_ccaps(ctx, &caps) == -1) {
- if (errno != -ESRCH)
+ if (errno != ESRCH)
return PyErr_SetFromErrno(PyExc_OSError);
else
caps.bcaps = 0;
}
- return Py_BuildValue("K", caps.bcaps & vc_get_insecurebcaps());
+ return Py_BuildValue("K", caps.bcaps & PL_INSECURE_BCAPS);
}
static PyObject *
addr->vna_prefix = 64;
break;
default:
- errno = -EINVAL;
+ errno = EINVAL;
return -1;
}
static PyObject *
vserver_net_add(PyObject *self, PyObject *args)
{
- struct vc_net_addr addr;
+ struct vc_net_addr addr = { .vna_type = 0 };
nid_t nid;
const char *ip;
if (!PyArg_ParseTuple(args, "Is", &nid, &ip))
return NULL;
- if (convert_address(ip, &addr) == -1)
- return PyErr_Format(PyExc_ValueError, "%s is not a valid IP address", ip);
+ /* Optimize standard case, which also needs to be handled differently */
+ if (strcmp(ip, "0.0.0.0") == 0) {
+ addr.vna_type = VC_NXA_TYPE_MASK | VC_NXA_TYPE_IPV4;
+ addr.vna_flags = 0;
+ addr.vna_prefix = 0;
+ addr.vna_parent = 0;
+ addr.vna_v4_mask.s_addr = 0;
+ addr.vna_v4_ip.s_addr = 0;
+ }
+ else {
+ if (convert_address(ip, &addr) == -1)
+ return PyErr_Format(PyExc_ValueError, "%s is not a valid IP address", ip);
- switch (get_mask(&addr)) {
- case -1:
- return PyErr_SetFromErrno(PyExc_OSError);
- case 0:
- /* XXX error here? */
- break;
+ switch (get_mask(&addr)) {
+ case -1:
+ return PyErr_SetFromErrno(PyExc_OSError);
+ case 0:
+ /* XXX error here? */
+ break;
+ }
+ addr.vna_type |= VC_NXA_TYPE_ADDR;
}
- addr.vna_type |= VC_NXA_TYPE_ADDR;
if (vc_net_add(nid, &addr) == -1 && errno != ESRCH)
return PyErr_SetFromErrno(PyExc_OSError);
if (strcmp(ip, "all") == 0)
addr.vna_type = VC_NXA_TYPE_ANY;
else if (strcmp(ip, "all4") == 0)
- addr.vna_type = VC_NXA_TYPE_IPV6 | VC_NXA_TYPE_ANY;
+ addr.vna_type = VC_NXA_TYPE_IPV4 | VC_NXA_TYPE_ANY;
else if (strcmp(ip, "all6") == 0)
addr.vna_type = VC_NXA_TYPE_IPV6 | VC_NXA_TYPE_ANY;
else {
if (convert_address(ip, &addr) == -1)
return PyErr_Format(PyExc_ValueError, "%s is not a valid IP address", ip);
- addr.vna_type |= VC_NXA_TYPE_ADDR;
- }
- switch (get_mask(&addr)) {
- case -1:
- return PyErr_SetFromErrno(PyExc_OSError);
+ switch (get_mask(&addr)) {
+ case -1:
+ return PyErr_SetFromErrno(PyExc_OSError);
+ }
+
+ addr.vna_type |= VC_NXA_TYPE_ADDR;
}
if (vc_net_remove(nid, &addr) == -1 && errno != ESRCH)
if (secure_chdir(&dirs, guest, target) == -1)
goto out;
- if (mount(source, ".", type, flags, data) == -1)
+ if (mount(source, ".", type, flags, data) == -1 && errno != EBUSY)
goto out;
restore_dirs(&dirs);
return NONE;
}
+static PyObject *
+vserver_set_name(PyObject *self, PyObject *args)
+{
+ xid_t ctx, slice_id;
+ PyObject *ret;
+
+ if (!PyArg_ParseTuple(args, "II", &ctx, &slice_id))
+ return NULL;
+
+ if (vc_set_vhi_name(ctx, vcVHI_CONTEXT, (char *)&slice_id, sizeof(slice_id)) != 0 && errno != ESRCH) {
+ return PyErr_SetFromErrno(PyExc_OSError);
+ } else {
+ return NONE;
+ }
+}
+
+static PyObject *
+vserver_get_name(PyObject *self, PyObject *args)
+{
+ xid_t ctx, slice_id;
+ PyObject *ret;
+
+ if (!PyArg_ParseTuple(args, "I", &ctx))
+ return NULL;
+
+ if (vc_get_vhi_name(ctx, vcVHI_CONTEXT, (char *)&slice_id, sizeof(slice_id)) != 0) {
+ ret = PyErr_SetFromErrno(PyExc_OSError);
+ } else {
+ ret = Py_BuildValue("i", slice_id);
+ }
+ return ret;
+}
+
static PyMethodDef methods[] = {
{ "chcontext", vserver_chcontext, METH_VARARGS,
"chcontext to vserver with provided flags" },
"Perform the umount2() system call" },
{ "setrunlevel", vserver_set_runlevel, METH_VARARGS,
"Set the runlevel in utmp" },
+ { "setname", vserver_set_name, METH_VARARGS,
+ "Set the vcVHI_CONTEXT for a xid." },
+ { "getname", vserver_get_name, METH_VARARGS,
+ "Get the vcVHI_CONTEXT for a xid." },
{ NULL, NULL, 0, NULL }
};
PyModule_AddIntConstant(mod, "VLIMIT_ANON", (int)VC_VLIMIT_ANON);
PyModule_AddIntConstant(mod, "VLIMIT_SHMEM", (int)VC_VLIMIT_SHMEM);
- /* scheduler flags */
- PyModule_AddIntConstant(mod,
- "VS_SCHED_CPU_GUARANTEED",
- VS_SCHED_CPU_GUARANTEED);
}