xenstore: add XS_RESUME command; export it to xend.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Fri, 19 Jan 2007 15:28:34 +0000 (15:28 +0000)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Fri, 19 Jan 2007 15:28:34 +0000 (15:28 +0000)
This clears the shutdown flag for a domain in xenstore, allowing
subsequent shutdowns of the same domain to fire the appropriate
watches.

Signed-off-by: Brendan Cully <brendan@cs.ubc.ca>
tools/python/xen/lowlevel/xs/xs.c
tools/python/xen/xend/XendDomainInfo.py
tools/python/xen/xend/xenstore/xsutil.py
tools/xenstore/xenstored_core.c
tools/xenstore/xenstored_domain.c
tools/xenstore/xenstored_domain.h
tools/xenstore/xs.c
tools/xenstore/xs.h

index 4ab8c2f0111541ab73bca8ea9771b65d98a63ace..45cbf773d91c8996f59736f58925c3d83dcc9dc8 100644 (file)
@@ -618,6 +618,33 @@ static PyObject *xspy_introduce_domain(XsHandle *self, PyObject *args)
     return none(result);
 }
 
+#define xspy_resume_domain_doc "\n"                                \
+       "Tell xenstore to clear its shutdown flag for a domain.\n" \
+       "This ensures that a subsequent shutdown will fire the\n"  \
+       "appropriate watches.\n"                                   \
+       " dom [int]: domain id\n"                                  \
+        "\n"                                                      \
+        "Returns None on success.\n"                              \
+        "Raises xen.lowlevel.xs.Error on error.\n"
+
+static PyObject *xspy_resume_domain(XsHandle *self, PyObject *args)
+{
+    uint32_t dom;
+
+    struct xs_handle *xh = xshandle(self);
+    bool result = 0;
+
+    if (!xh)
+        return NULL;
+    if (!PyArg_ParseTuple(args, "i", &dom))
+        return NULL;
+
+    Py_BEGIN_ALLOW_THREADS
+    result = xs_resume_domain(xh, dom);
+    Py_END_ALLOW_THREADS
+
+    return none(result);
+}
 
 #define xspy_release_domain_doc "\n"                                   \
        "Tell xenstore to release its channel to a domain.\n"           \
@@ -789,6 +816,7 @@ static PyMethodDef xshandle_methods[] = {
     XSPY_METH(transaction_start, METH_NOARGS),
     XSPY_METH(transaction_end,   METH_VARARGS | METH_KEYWORDS),
     XSPY_METH(introduce_domain,  METH_VARARGS),
+    XSPY_METH(resume_domain,     METH_VARARGS),
     XSPY_METH(release_domain,    METH_VARARGS),
     XSPY_METH(close,             METH_NOARGS),
     XSPY_METH(get_domain_path,   METH_VARARGS),
index 087ff0e5aaa47f4909365c26a4e46af7fb959e52..f56f00c9bcb34a2da316dac10fce76c6e138c6c9 100644 (file)
@@ -45,7 +45,7 @@ from xen.xend.XendBootloader import bootloader
 from xen.xend.XendError import XendError, VmError
 from xen.xend.XendDevices import XendDevices
 from xen.xend.xenstore.xstransact import xstransact, complete
-from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain
+from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain, ResumeDomain
 from xen.xend.xenstore.xswatch import xswatch
 from xen.xend.XendConstants import *
 from xen.xend.XendAPIConstants import *
@@ -1545,6 +1545,7 @@ class XendDomainInfo:
         try:
             if self.domid is not None:
                 xc.domain_resume(self.domid)
+                ResumeDomain(self.domid)
         except:
             log.exception("XendDomainInfo.resume: xc.domain_resume failed on domain %s." % (str(self.domid)))
 
index 1b94f7e1a059615486e29d28f79b33f9f58afb71..7ef00c22264ddb57fa5aa53ff45796be5f8dd333 100644 (file)
@@ -24,3 +24,6 @@ def IntroduceDomain(domid, page, port):
 
 def GetDomainPath(domid):
     return xshandle().get_domain_path(domid)
+
+def ResumeDomain(domid):
+    return xshandle().resume_domain(domid)
index 5ac4dd3b0f12627579e9f8a84f028e9f563d77d9..461395832a956d521266e284be45743c23959b0e 100644 (file)
@@ -164,6 +164,7 @@ static char *sockmsg_string(enum xsd_sockmsg_type type)
        case XS_WATCH_EVENT: return "WATCH_EVENT";
        case XS_ERROR: return "ERROR";
        case XS_IS_DOMAIN_INTRODUCED: return "XS_IS_DOMAIN_INTRODUCED";
+       case XS_RESUME: return "RESUME";
        default:
                return "**UNKNOWN**";
        }
@@ -1267,6 +1268,10 @@ static void process_message(struct connection *conn, struct buffered_data *in)
                do_get_domain_path(conn, onearg(in));
                break;
 
+       case XS_RESUME:
+               do_resume(conn, onearg(in));
+               break;
+
        default:
                eprintf("Client unknown operation %i", in->hdr.msg.type);
                send_error(conn, ENOSYS);
index 75ff6e96d8939892facb0fa32388f9e7ed477773..115a1f75dae93780c3f38ac7eba556e9c37f969f 100644 (file)
@@ -395,6 +395,43 @@ void do_release(struct connection *conn, const char *domid_str)
        send_ack(conn, XS_RELEASE);
 }
 
+void do_resume(struct connection *conn, const char *domid_str)
+{
+       struct domain *domain;
+       unsigned int domid;
+
+       if (!domid_str) {
+               send_error(conn, EINVAL);
+               return;
+       }
+
+       domid = atoi(domid_str);
+       if (!domid) {
+               send_error(conn, EINVAL);
+               return;
+       }
+
+       if (conn->id != 0) {
+               send_error(conn, EACCES);
+               return;
+       }
+
+       domain = find_domain_by_domid(domid);
+       if (!domain) {
+               send_error(conn, ENOENT);
+               return;
+       }
+
+       if (!domain->conn) {
+               send_error(conn, EINVAL);
+               return;
+       }
+
+       domain->shutdown = 0;
+       
+       send_ack(conn, XS_RESUME);
+}
+
 void do_get_domain_path(struct connection *conn, const char *domid_str)
 {
        char *path;
index 4acf61bbacc4deabbd77a1e36bf1d6ed74f4510a..d1ad774148a380feee61ca9d986e7ac13819bbac 100644 (file)
@@ -31,6 +31,9 @@ void do_is_domain_introduced(struct connection *conn, const char *domid_str);
 /* domid */
 void do_release(struct connection *conn, const char *domid_str);
 
+/* domid */
+void do_resume(struct connection *conn, const char *domid_str);
+
 /* domid */
 void do_get_domain_path(struct connection *conn, const char *domid_str);
 
index 44c1baaf48ec6aa997ea0630fd70bf184e893f66..370815de04c111c5379ba2dbcd98e170e841c165 100644 (file)
@@ -719,6 +719,12 @@ bool xs_release_domain(struct xs_handle *h, unsigned int domid)
        return xs_bool(single_with_domid(h, XS_RELEASE, domid));
 }
 
+/* clear the shutdown bit for the given domain */
+bool xs_resume_domain(struct xs_handle *h, unsigned int domid)
+{
+       return xs_bool(single_with_domid(h, XS_RESUME, domid));
+}
+
 char *xs_get_domain_path(struct xs_handle *h, unsigned int domid)
 {
        char domid_str[MAX_STRLEN(domid)];
index cabf9d0711c8cc0ff4388a6d521ce9f44de02aa3..050dc01e2b7b875e4f37a1b429d9525a60d078b0 100644 (file)
@@ -133,6 +133,11 @@ bool xs_introduce_domain(struct xs_handle *h,
                         unsigned int domid,
                         unsigned long mfn,
                          unsigned int eventchn); 
+/* Resume a domain.
+ * Clear the shutdown flag for this domain in the store.
+ */
+bool xs_resume_domain(struct xs_handle *h, unsigned int domid);
+
 /* Release a domain.
  * Tells the store domain to release the memory page to the domain.
  */