[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Use watch to detect new domains and avoid polling for dead domains.



# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID 9225c3f597db755f448429a270200c0d2c7a5a78
# Parent  946ea528fc79ffb4e11a1c7f0107edabdb4849d8
Use watch to detect new domains and avoid polling for dead domains.
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>

diff -r 946ea528fc79 -r 9225c3f597db tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Tue Aug 30 20:01:23 2005
+++ b/tools/console/daemon/io.c Tue Aug 30 20:02:59 2005
@@ -215,9 +215,6 @@
        char *dompath, *path;
        int err;
 
-       dom->page = NULL;
-       dom->evtchn_fd = -1;
-
        asprintf(&path, "/console/%d/domain", dom->domid);
        dompath = xs_read(xs, path, NULL);
        free(path);
@@ -232,28 +229,35 @@
        if (err)
                goto out;
 
-       dom->page = xc_map_foreign_range(xc, dom->domid, getpagesize(),
-                                        PROT_READ|PROT_WRITE, dom->mfn);
        if (dom->page == NULL) {
-               err = EINVAL;
-               goto out;
-       }
-
-       /* Opening evtchn independently for each console is a bit
-        * wastefule, but that's how the code is structured... */
-       err = open("/dev/xen/evtchn", O_RDWR);
-       if (err == -1) {
-               err = errno;
-               goto out;
-       }
-       dom->evtchn_fd = err;
-
-       if (ioctl(dom->evtchn_fd, EVENTCHN_BIND, dom->local_port) == -1) {
-               err = errno;
-               munmap(dom->page, getpagesize());
-               close(dom->evtchn_fd);
-               dom->evtchn_fd = -1;
-               goto out;
+               dom->page = xc_map_foreign_range(xc, dom->domid, getpagesize(),
+                                                PROT_READ|PROT_WRITE,
+                                                dom->mfn);
+               if (dom->page == NULL) {
+                       err = EINVAL;
+                       goto out;
+               }
+       }
+
+       if (dom->evtchn_fd == -1) {
+               /* Opening evtchn independently for each console is a bit
+                * wastefule, but that's how the code is structured... */
+               err = open("/dev/xen/evtchn", O_RDWR);
+               if (err == -1) {
+                       err = errno;
+                       goto out;
+               }
+               dom->evtchn_fd = err;
+ 
+               if (ioctl(dom->evtchn_fd, EVENTCHN_BIND,
+                         dom->local_port) == -1) {
+                       err = errno;
+                       munmap(dom->page, getpagesize());
+                       dom->page = NULL;
+                       close(dom->evtchn_fd);
+                       dom->evtchn_fd = -1;
+                       goto out;
+               }
        }
 
  out:
@@ -281,6 +285,9 @@
        dom->buffer.max_capacity = 0;
        dom->next = NULL;
 
+       dom->page = NULL;
+       dom->evtchn_fd = -1;
+
        domain_create_ring(dom);
 
        dolog(LOG_DEBUG, "New domain %d", domid);
@@ -290,22 +297,19 @@
 
 static struct domain *lookup_domain(int domid)
 {
-       struct domain **pp;
-
-       for (pp = &dom_head; *pp; pp = &(*pp)->next) {
-               struct domain *dom = *pp;
-
-               if (dom->domid == domid) {
+       struct domain *dom;
+
+       for (dom = dom_head; dom; dom = dom->next)
+               if (dom->domid == domid)
                        return dom;
-               } else if (dom->domid > domid) {
-                       *pp = create_domain(domid);
-                       (*pp)->next = dom;
-                       return *pp;
-               }
-       }
-
-       *pp = create_domain(domid);
-       return *pp;
+
+       dom = create_domain(domid);
+       if (!dom)
+               return NULL;
+       dom->next = dom_head;
+       dom_head = dom;
+
+       return dom;
 }
 
 static void remove_domain(struct domain *dom)
@@ -345,6 +349,20 @@
        }
 }
 
+void enum_domains(void)
+{
+       int domid = 1;
+       xc_dominfo_t dominfo;
+       struct domain *dom;
+
+       while (xc_domain_getinfo(xc, domid, 1, &dominfo) == 1) {
+               dom = lookup_domain(dominfo.domid);
+               if (dominfo.dying || dominfo.crashed || dominfo.shutdown)
+                       dom->is_dead = true;
+               domid = dominfo.domid + 1;
+       }
+}
+
 static void handle_tty_read(struct domain *dom)
 {
        ssize_t len;
@@ -415,20 +433,28 @@
                dolog(LOG_ERR, "read from xcs failed! %m");
                exit(1);
        }
-}
-
-static void enum_domains(void)
-{
-       int domid = 0;
-       xc_dominfo_t dominfo;
+
+       enum_domains();
+}
+
+static void handle_xs(int fd)
+{
+       char **vec;
+       int domid;
        struct domain *dom;
 
-       while (xc_domain_getinfo(xc, domid, 1, &dominfo) == 1) {
-               dom = lookup_domain(dominfo.domid);
-               if (dominfo.dying || dominfo.crashed || dominfo.shutdown)
-                       dom->is_dead = true;
-               domid = dominfo.domid + 1;
-       }
+       vec = xs_read_watch(xs);
+       if (!vec)
+               return;
+
+       if (sscanf(vec[0], "/console/%d", &domid) == 1) {
+               dom = lookup_domain(domid);
+               if (dom && (dom->evtchn_fd == -1 || dom->page == NULL))
+                       domain_create_ring(dom);
+       }
+
+       xs_acknowledge_watch(xs, vec[1]);
+       free(vec);
 }
 
 void handle_io(void)
@@ -438,7 +464,7 @@
 
        do {
                struct domain *d;
-               struct timeval tv = { 1, 0 };
+               struct timeval tv = { 100, 0 };
                int max_fd = -1;
 
                FD_ZERO(&readfds);
@@ -446,6 +472,9 @@
 
                FD_SET(xcs_data_fd, &readfds);
                max_fd = MAX(xcs_data_fd, max_fd);
+
+               FD_SET(xs_fileno(xs), &readfds);
+               max_fd = MAX(xs_fileno(xs), max_fd);
 
                for (d = dom_head; d; d = d->next) {
                        if (d->tty_fd != -1) {
@@ -463,7 +492,9 @@
                }
 
                ret = select(max_fd + 1, &readfds, &writefds, 0, &tv);
-               enum_domains();
+
+               if (FD_ISSET(xs_fileno(xs), &readfds))
+                       handle_xs(xs_fileno(xs));
 
                if (FD_ISSET(xcs_data_fd, &readfds))
                        handle_xcs_msg(xcs_data_fd);
diff -r 946ea528fc79 -r 9225c3f597db tools/console/daemon/io.h
--- a/tools/console/daemon/io.h Tue Aug 30 20:01:23 2005
+++ b/tools/console/daemon/io.h Tue Aug 30 20:02:59 2005
@@ -21,6 +21,7 @@
 #ifndef CONSOLED_IO_H
 #define CONSOLED_IO_H
 
+void enum_domains(void);
 void handle_io(void);
 
 #endif
diff -r 946ea528fc79 -r 9225c3f597db tools/console/daemon/main.c
--- a/tools/console/daemon/main.c       Tue Aug 30 20:01:23 2005
+++ b/tools/console/daemon/main.c       Tue Aug 30 20:02:59 2005
@@ -85,6 +85,8 @@
 
        xen_setup();
 
+       enum_domains();
+
        handle_io();
 
        closelog();
diff -r 946ea528fc79 -r 9225c3f597db tools/console/daemon/utils.c
--- a/tools/console/daemon/utils.c      Tue Aug 30 20:01:23 2005
+++ b/tools/console/daemon/utils.c      Tue Aug 30 20:02:59 2005
@@ -232,11 +232,16 @@
                dolog(LOG_ERR, "xcs virq bind failed.  Possible bug.");
                goto out_close_data;
        }
-       
+
+       if (!xs_watch(xs, "/console", "console")) {
+               dolog(LOG_ERR, "xenstore watch on /console failes.");
+               goto out_close_data;
+       }
+
        return true;
 
  out_close_data:
-       close(xcs_ctrl_fd);
+       close(xcs_data_fd);
        xcs_data_fd = -1;
  out_close_ctrl:
        close(xcs_ctrl_fd);

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.