If it's busy, assume it's already mounted.
[util-vserver-pl.git] / python / vserverimpl.c
index b20725c..98125c9 100644 (file)
@@ -59,6 +59,8 @@ static inline PyObject *inc_and_ret_none(void)
 
 #define NONE  inc_and_ret_none()
 
+#define PL_INSECURE_BCAPS      (vc_get_insecurebcaps() | (1 << VC_CAP_NET_BIND_SERVICE))
+
 /*
  * context create
  */
@@ -71,7 +73,7 @@ vserver_chcontext(PyObject *self, PyObject *args)
 
   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);
@@ -145,9 +147,10 @@ vserver_get_rlimit(PyObject *self, PyObject *args) {
 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;
@@ -157,30 +160,18 @@ vserver_set_rlimit(PyObject *self, PyObject *args) {
   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;
 }
@@ -192,14 +183,14 @@ static PyObject *
 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);
 
@@ -312,7 +303,7 @@ vserver_set_bcaps(PyObject *self, PyObject *args)
   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);
@@ -352,7 +343,7 @@ vserver_get_bcaps(PyObject *self, PyObject *args)
       caps.bcaps = 0;
   }
 
-  return Py_BuildValue("K", caps.bcaps & vc_get_insecurebcaps());
+  return Py_BuildValue("K", caps.bcaps & PL_INSECURE_BCAPS);
 }
 
 static PyObject *
@@ -461,24 +452,35 @@ get_mask(struct vc_net_addr *addr)
 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);
@@ -610,7 +612,7 @@ vserver_mount(PyObject *self, PyObject *args)
 
   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);
 
@@ -740,8 +742,4 @@ initvserverimpl(void)
   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);
 }