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

[Xen-changelog] Make xenstored listen to domain exception virqs.



# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID d6d77aa96aa1465d287069e809b489a569a9b3fb
# Parent  275e28658c66b4327cded36dd86a20e81399efa0
Make xenstored listen to domain exception virqs.
The virq triggers a scan for domains which have gone away, and then
removes those domains.
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>

diff -r 275e28658c66 -r d6d77aa96aa1 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Tue Sep  6 13:43:28 2005
+++ b/tools/xenstore/xenstored_core.c   Tue Sep  6 16:59:14 2005
@@ -49,6 +49,9 @@
 #include "xenstored_watch.h"
 #include "xenstored_transaction.h"
 #include "xenstored_domain.h"
+#include "xenctrl.h"
+#include "xen/io/domain_controller.h"
+#include "xcs_proto.h"
 
 static bool verbose;
 LIST_HEAD(connections);
@@ -322,7 +325,7 @@
 }
 
 static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock,
-                         int event_fd)
+                         int event_fd, int xcs_fd)
 {
        struct connection *i;
        int max;
@@ -337,6 +340,9 @@
        FD_SET(event_fd, inset);
        if (event_fd > max)
                max = event_fd;
+       FD_SET(xcs_fd, inset);
+       if (xcs_fd > max)
+               max = xcs_fd;
        list_for_each_entry(i, &connections, list) {
                if (i->domain)
                        continue;
@@ -1636,6 +1642,125 @@
        umask(0);
 }
 
+static int open_domain_socket(const char *path)
+{
+       struct sockaddr_un addr;
+       int sock;
+       size_t addr_len;
+
+       if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
+               goto out;
+       }
+
+       addr.sun_family = AF_UNIX;
+       strcpy(addr.sun_path, path);
+       addr_len = sizeof(addr.sun_family) + strlen(XCS_SUN_PATH) + 1;
+
+       if (connect(sock, (struct sockaddr *)&addr, addr_len) == -1) {
+               goto out_close_sock;
+       }
+
+       return sock;
+
+ out_close_sock:
+       close(sock);
+ out:
+       return -1;
+}
+
+bool _read_write_sync(int fd, void *data, size_t size, bool do_read)
+{
+       size_t offset = 0;
+       ssize_t len;
+
+       while (offset < size) {
+               if (do_read) {
+                       len = read(fd, data + offset, size - offset);
+               } else {
+                       len = write(fd, data + offset, size - offset);
+               }
+
+               if (len < 1) {
+                       if (len == -1 && (errno == EAGAIN || errno == EINTR)) {
+                               continue;
+                       } else {
+                               return false;
+                       }
+               } else {
+                       offset += len;
+               }
+       }
+
+       return true;
+}
+
+#define read_sync(fd, buffer, size) _read_write_sync(fd, buffer, size, true)
+#define write_sync(fd, buffer, size) _read_write_sync(fd, buffer, size, false)
+
+/* synchronized send/recv strictly for setting up xcs */
+/* always use asychronize callbacks any other time */
+static bool xcs_send_recv(int fd, xcs_msg_t *msg)
+{
+       bool ret = false;
+
+       if (!write_sync(fd, msg, sizeof(*msg))) {
+               eprintf("Write failed at %s:%s():L%d?  Possible bug.",
+                       __FILE__, __FUNCTION__, __LINE__);
+               goto out;
+       }
+
+       if (!read_sync(fd, msg, sizeof(*msg))) {
+               eprintf("Read failed at %s:%s():L%d?  Possible bug.",
+                       __FILE__, __FUNCTION__, __LINE__);
+               goto out;
+       }
+
+       ret = true;
+
+ out:
+       return ret;
+}
+
+static void handle_xcs(int xcs_fd)
+{
+       xcs_msg_t msg;
+
+       if (!read_sync(xcs_fd, &msg, sizeof(msg)))
+               barf_perror("read from xcs failed!");
+
+       domain_cleanup();
+}
+
+static int xcs_init(void)
+{
+       int ctrl_fd, data_fd;
+       xcs_msg_t msg;
+
+       ctrl_fd = open_domain_socket(XCS_SUN_PATH);
+       if (ctrl_fd == -1)
+               barf_perror("Failed to contact xcs.  Is it running?");
+
+       data_fd = open_domain_socket(XCS_SUN_PATH);
+       if (data_fd == -1)
+               barf_perror("Failed to contact xcs.  Is it running?");
+       
+       memset(&msg, 0, sizeof(msg));
+       msg.type = XCS_CONNECT_CTRL;
+       if (!xcs_send_recv(ctrl_fd, &msg) || msg.result != XCS_RSLT_OK)
+               barf_perror("xcs control connect failed.");
+
+       msg.type = XCS_CONNECT_DATA;
+       if (!xcs_send_recv(data_fd, &msg) || msg.result != XCS_RSLT_OK)
+               barf_perror("xcs data connect failed.");
+
+       msg.type = XCS_VIRQ_BIND;
+       msg.u.virq.virq = VIRQ_DOM_EXC;
+       if (!xcs_send_recv(ctrl_fd, &msg) || msg.result != XCS_RSLT_OK)
+               barf_perror("xcs virq bind failed.");
+
+       return data_fd;
+}
+
 
 static struct option options[] = {
        { "pid-file", 1, NULL, 'F' },
@@ -1647,7 +1772,7 @@
 
 int main(int argc, char *argv[])
 {
-       int opt, *sock, *ro_sock, event_fd, max;
+       int opt, *sock, *ro_sock, event_fd, xcs_fd, max;
        struct sockaddr_un addr;
        fd_set inset, outset;
        bool dofork = true;
@@ -1731,6 +1856,9 @@
        /* Listen to hypervisor. */
        event_fd = domain_init();
 
+       /* Listen to hypervisor - more. */
+       xcs_fd = xcs_init();
+
        /* Restore existing connections. */
        restore_existing_connections();
 
@@ -1751,7 +1879,8 @@
 #endif
 
        /* Get ready to listen to the tools. */
-       max = initialize_set(&inset, &outset, *sock, *ro_sock, event_fd);
+       max = initialize_set(&inset, &outset, *sock, *ro_sock, event_fd,
+                            xcs_fd);
 
        /* Main loop. */
        /* FIXME: Rewrite so noone can starve. */
@@ -1781,6 +1910,9 @@
 
                if (FD_ISSET(event_fd, &inset))
                        handle_event(event_fd);
+
+               if (FD_ISSET(xcs_fd, &inset))
+                       handle_xcs(xcs_fd);
 
                list_for_each_entry(i, &connections, list) {
                        if (i->domain)
@@ -1824,6 +1956,7 @@
                /* If transactions ended, we might be able to do more work. */
                unblock_connections();
 
-               max = initialize_set(&inset, &outset, *sock,*ro_sock,event_fd);
-       }
-}
+               max = initialize_set(&inset, &outset, *sock, *ro_sock,
+                                    event_fd, xcs_fd);
+       }
+}
diff -r 275e28658c66 -r d6d77aa96aa1 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Tue Sep  6 13:43:28 2005
+++ b/tools/xenstore/xenstored_domain.c Tue Sep  6 16:59:14 2005
@@ -363,6 +363,21 @@
        send_ack(conn, XS_RELEASE);
 }
 
+void domain_cleanup(void)
+{
+       xc_dominfo_t dominfo;
+       struct domain *domain, *tmp;
+
+       list_for_each_entry_safe(domain, tmp, &domains, list) {
+               if (xc_domain_getinfo(*xc_handle, domain->domid, 1,
+                                     &dominfo) == 1 &&
+                   dominfo.domid == domain->domid &&
+                   !dominfo.dying && !dominfo.crashed && !dominfo.shutdown)
+                       continue;
+               talloc_free(domain->conn);
+       }
+}
+
 void do_get_domain_path(struct connection *conn, const char *domid_str)
 {
        struct domain *domain;
diff -r 275e28658c66 -r d6d77aa96aa1 tools/xenstore/xenstored_domain.h
--- a/tools/xenstore/xenstored_domain.h Tue Sep  6 13:43:28 2005
+++ b/tools/xenstore/xenstored_domain.h Tue Sep  6 16:59:14 2005
@@ -28,6 +28,10 @@
 /* domid */
 void do_release(struct connection *conn, const char *domid_str);
 
+/* Enumerate domains and release connections for non-existant or dying
+ * domains. */
+void domain_cleanup(void);
+
 /* domid */
 void do_get_domain_path(struct connection *conn, const char *domid_str);
 

_______________________________________________
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®.