WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] Fix qemu spawn for Solaris

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] Fix qemu spawn for Solaris
From: John Levon <john.levon@xxxxxxx>
Date: Wed, 11 Mar 2009 18:44:45 -0700
Delivery-date: Wed, 11 Mar 2009 18:54:19 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User John Levon <john.levon@xxxxxxx>
# Date 1236822270 25200
# Node ID 93d25b0df1be0abc503ff721e291b6a1553f4da2
# Parent  403118d22a30b83b863609ae4e0a7f694e612e42
Fix qemu spawn for Solaris

On Solaris, xend runs in a 'process contract' such that all children are
killed when the service is restarted.  Spawn qemu processes in a new
contract to avoid this.

Signed-off-by: John Levon <john.levon@xxxxxxx>

diff --git a/tools/python/setup.py b/tools/python/setup.py
--- a/tools/python/setup.py
+++ b/tools/python/setup.py
@@ -38,6 +38,13 @@ scf = Extension("scf",
                libraries          = libraries,
                sources            = [ "xen/lowlevel/scf/scf.c" ])
              
+process = Extension("process",
+               extra_compile_args = extra_compile_args,
+               include_dirs       = include_dirs + [ "xen/lowlevel/process" ],
+               library_dirs       = library_dirs,
+               libraries          = libraries + [ "contract" ],
+               sources            = [ "xen/lowlevel/process/process.c" ])
+
 acm = Extension("acm",
                extra_compile_args = extra_compile_args,
                include_dirs       = include_dirs + [ "xen/lowlevel/acm" ],
@@ -63,6 +70,7 @@ modules = [ xc, xs, ptsname, acm, flask 
 modules = [ xc, xs, ptsname, acm, flask ]
 if os.uname()[0] == 'SunOS':
     modules.append(scf)
+    modules.append(process)
 
 setup(name            = 'xen',
       version         = '3.0',
diff --git a/tools/python/xen/lowlevel/process/process.c 
b/tools/python/xen/lowlevel/process/process.c
new file mode 100644
--- /dev/null
+++ b/tools/python/xen/lowlevel/process/process.c
@@ -0,0 +1,164 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <Python.h>
+
+#include <libcontract.h>
+#include <sys/contract/process.h>
+#include <fcntl.h>
+#include <stdio.h>
+
+/*
+ * On Solaris, xend runs under a contract as an smf(5) service.  As a
+ * result, when spawning long-running children such as a domain's
+ * qemu-dm instantiation, we have to make sure it's in a separate
+ * contract. Before we fork, we must activate a separate process
+ * contract template to place the child processes in a new contract.
+ */
+
+static PyObject *
+pyprocess_activate(PyObject *o, PyObject *args, PyObject *kwargs)
+{
+       static char *kwlist[] = { "name", NULL };
+       char *name = NULL;
+       int flags;
+       int cfd;
+
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", kwlist, &name))
+               return (NULL);
+
+       cfd = open64("/system/contract/process/template", O_RDWR);
+
+       if (cfd == -1)
+               goto err;
+
+       if ((flags = fcntl(cfd, F_GETFD, 0)) == -1)
+               goto err;
+       
+       if (fcntl(cfd, F_SETFD, flags | FD_CLOEXEC) == -1)
+               goto err;
+
+       if (name != NULL)
+               ct_pr_tmpl_set_svc_aux(cfd, name);
+
+       if (ct_tmpl_activate(cfd))
+               goto err;
+
+       return (PyInt_FromLong((long)cfd));
+
+err:
+       if (cfd != -1)
+               close(cfd);
+       PyErr_SetFromErrno(PyExc_OSError);
+       return (NULL);
+}
+
+static PyObject *
+pyprocess_clear(PyObject *o, PyObject *args, PyObject *kwargs)
+{
+       static char *kwlist[] = { "contract", NULL };
+       int cfd;
+
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &cfd))
+               return (NULL);
+
+       if (ct_tmpl_clear(cfd) != 0) {
+               PyErr_SetFromErrno(PyExc_OSError);
+               return (NULL);
+       }
+
+       close(cfd);
+
+       Py_INCREF(Py_None);
+       return (Py_None);
+}
+
+static PyObject *
+pyprocess_abandon_latest(PyObject *o, PyObject *args, PyObject *kwargs)
+{
+       static char *kwlist[] = { NULL };
+       static char path[PATH_MAX];
+       ct_stathdl_t st;
+       ctid_t latest;
+       int cfd;
+
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "", kwlist))
+               return (NULL);
+
+       cfd = open64("/system/contract/process/latest", O_RDONLY);
+       if (cfd == -1)
+               goto err;
+
+       ct_status_read(cfd, CTD_COMMON, &st);
+       latest = ct_status_get_id(st);
+       ct_status_free(st);
+       close(cfd);
+
+       snprintf(path, PATH_MAX, "/system/contract/process/%ld/ctl",
+           (long)latest);
+
+       if ((cfd = open64(path, O_WRONLY)) < 0) 
+               goto err;
+       if (ct_ctl_abandon(cfd))
+               goto err;
+       close(cfd);
+
+       Py_INCREF(Py_None);
+       return (Py_None);
+err:
+       PyErr_SetFromErrno(PyExc_OSError);
+       return (NULL);
+}
+
+PyDoc_STRVAR(pyprocess_activate__doc__,
+    "activate(name)\n"
+    "\n"
+    "Activate a new process contract template. If name is given,\n"
+    "it is used as the template's auxiliary value.\n"
+    "Returns the new contract template.\n");
+ 
+PyDoc_STRVAR(pyprocess_clear__doc__,
+    "clear(contract)\n"
+    "\n"
+    "Clear and close the given contract template.\n");
+
+PyDoc_STRVAR(pyprocess_abandon_latest__doc__,
+    "abandon_latest()\n"
+    "\n"
+    "Abandon the latest contract created by this thread.\n");
+
+static struct PyMethodDef pyprocess_module_methods[] = {
+    { "activate", (PyCFunction) pyprocess_activate,
+      METH_VARARGS|METH_KEYWORDS, pyprocess_activate__doc__ },
+    { "clear", (PyCFunction) pyprocess_clear,
+      METH_VARARGS|METH_KEYWORDS, pyprocess_clear__doc__ },
+    { "abandon_latest", (PyCFunction) pyprocess_abandon_latest,
+      METH_VARARGS|METH_KEYWORDS, pyprocess_abandon_latest__doc__ },
+    { NULL, NULL, 0, NULL }    
+};
+
+PyMODINIT_FUNC
+initprocess(void)
+{
+       Py_InitModule("process", pyprocess_module_methods);
+}
diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py
+++ b/tools/python/xen/xend/image.py
@@ -40,6 +40,7 @@ from xen.xend import XendOptions
 from xen.xend import XendOptions
 from xen.util import oshelp
 from xen.util import utils
+from xen.xend import osdep
 
 xc = xen.lowlevel.xc.xc()
 
@@ -407,9 +408,12 @@ class ImageHandler:
         logfd = os.open(self.logfile, logfile_mode)
         
         sys.stderr.flush()
+        contract = osdep.prefork("%s:%d" %
+                                 (self.vm.getName(), self.vm.getDomid()))
         pid = os.fork()
         if pid == 0: #child
             try:
+                osdep.postfork(contract)
                 os.dup2(null, 0)
                 os.dup2(logfd, 1)
                 os.dup2(logfd, 2)
@@ -426,6 +430,7 @@ class ImageHandler:
             except:
                 os._exit(127)
         else:
+            osdep.postfork(contract, abandon=True)
             self.pid = pid
             os.close(null)
             os.close(logfd)
diff --git a/tools/python/xen/xend/osdep.py b/tools/python/xen/xend/osdep.py
--- a/tools/python/xen/xend/osdep.py
+++ b/tools/python/xen/xend/osdep.py
@@ -290,6 +290,32 @@ _boot_dev = {
     "SunOS": _solaris_boot_dev
 }
 
+def _default_prefork(name):
+    pass
+
+def _default_postfork(ct, abandon=False):
+    pass
+
+# call this for long-running processes that should survive a xend
+# restart
+def _solaris_prefork(name):
+    from xen.lowlevel import process
+    return process.activate(name)
+
+def _solaris_postfork(ct, abandon=False):
+    from xen.lowlevel import process
+    process.clear(ct)
+    if abandon:
+        process.abandon_latest()
+
+_get_prefork = {
+    "SunOS": _solaris_prefork
+}
+
+_get_postfork = {
+    "SunOS": _solaris_postfork
+}
+
 def _get(var, default=None):
     return var.get(os.uname()[0], default)
 
@@ -304,3 +330,5 @@ connection_allowed = _get(_connection_al
 connection_allowed = _get(_connection_allowed, _default_connection_allowed)
 get_boot_dev = _get(_boot_dev, _default_boot_dev)
 do_broadcast = _get(_do_broadcast)
+prefork = _get(_get_prefork, _default_prefork)
+postfork = _get(_get_postfork, _default_postfork)

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] Fix qemu spawn for Solaris, John Levon <=