ia64/xen-unstable
changeset 6656:d6d77aa96aa1
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@cl.cam.ac.uk>
The virq triggers a scan for domains which have gone away, and then
removes those domains.
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author | cl349@firebug.cl.cam.ac.uk |
---|---|
date | Tue Sep 06 16:59:14 2005 +0000 (2005-09-06) |
parents | 275e28658c66 |
children | d4d69c509371 |
files | tools/xenstore/xenstored_core.c tools/xenstore/xenstored_domain.c tools/xenstore/xenstored_domain.h |
line diff
1.1 --- a/tools/xenstore/xenstored_core.c Tue Sep 06 13:43:28 2005 +0000 1.2 +++ b/tools/xenstore/xenstored_core.c Tue Sep 06 16:59:14 2005 +0000 1.3 @@ -49,6 +49,9 @@ 1.4 #include "xenstored_watch.h" 1.5 #include "xenstored_transaction.h" 1.6 #include "xenstored_domain.h" 1.7 +#include "xenctrl.h" 1.8 +#include "xen/io/domain_controller.h" 1.9 +#include "xcs_proto.h" 1.10 1.11 static bool verbose; 1.12 LIST_HEAD(connections); 1.13 @@ -322,7 +325,7 @@ static int destroy_conn(void *_conn) 1.14 } 1.15 1.16 static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock, 1.17 - int event_fd) 1.18 + int event_fd, int xcs_fd) 1.19 { 1.20 struct connection *i; 1.21 int max; 1.22 @@ -337,6 +340,9 @@ static int initialize_set(fd_set *inset, 1.23 FD_SET(event_fd, inset); 1.24 if (event_fd > max) 1.25 max = event_fd; 1.26 + FD_SET(xcs_fd, inset); 1.27 + if (xcs_fd > max) 1.28 + max = xcs_fd; 1.29 list_for_each_entry(i, &connections, list) { 1.30 if (i->domain) 1.31 continue; 1.32 @@ -1636,6 +1642,125 @@ static void daemonize(void) 1.33 umask(0); 1.34 } 1.35 1.36 +static int open_domain_socket(const char *path) 1.37 +{ 1.38 + struct sockaddr_un addr; 1.39 + int sock; 1.40 + size_t addr_len; 1.41 + 1.42 + if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) { 1.43 + goto out; 1.44 + } 1.45 + 1.46 + addr.sun_family = AF_UNIX; 1.47 + strcpy(addr.sun_path, path); 1.48 + addr_len = sizeof(addr.sun_family) + strlen(XCS_SUN_PATH) + 1; 1.49 + 1.50 + if (connect(sock, (struct sockaddr *)&addr, addr_len) == -1) { 1.51 + goto out_close_sock; 1.52 + } 1.53 + 1.54 + return sock; 1.55 + 1.56 + out_close_sock: 1.57 + close(sock); 1.58 + out: 1.59 + return -1; 1.60 +} 1.61 + 1.62 +bool _read_write_sync(int fd, void *data, size_t size, bool do_read) 1.63 +{ 1.64 + size_t offset = 0; 1.65 + ssize_t len; 1.66 + 1.67 + while (offset < size) { 1.68 + if (do_read) { 1.69 + len = read(fd, data + offset, size - offset); 1.70 + } else { 1.71 + len = write(fd, data + offset, size - offset); 1.72 + } 1.73 + 1.74 + if (len < 1) { 1.75 + if (len == -1 && (errno == EAGAIN || errno == EINTR)) { 1.76 + continue; 1.77 + } else { 1.78 + return false; 1.79 + } 1.80 + } else { 1.81 + offset += len; 1.82 + } 1.83 + } 1.84 + 1.85 + return true; 1.86 +} 1.87 + 1.88 +#define read_sync(fd, buffer, size) _read_write_sync(fd, buffer, size, true) 1.89 +#define write_sync(fd, buffer, size) _read_write_sync(fd, buffer, size, false) 1.90 + 1.91 +/* synchronized send/recv strictly for setting up xcs */ 1.92 +/* always use asychronize callbacks any other time */ 1.93 +static bool xcs_send_recv(int fd, xcs_msg_t *msg) 1.94 +{ 1.95 + bool ret = false; 1.96 + 1.97 + if (!write_sync(fd, msg, sizeof(*msg))) { 1.98 + eprintf("Write failed at %s:%s():L%d? Possible bug.", 1.99 + __FILE__, __FUNCTION__, __LINE__); 1.100 + goto out; 1.101 + } 1.102 + 1.103 + if (!read_sync(fd, msg, sizeof(*msg))) { 1.104 + eprintf("Read failed at %s:%s():L%d? Possible bug.", 1.105 + __FILE__, __FUNCTION__, __LINE__); 1.106 + goto out; 1.107 + } 1.108 + 1.109 + ret = true; 1.110 + 1.111 + out: 1.112 + return ret; 1.113 +} 1.114 + 1.115 +static void handle_xcs(int xcs_fd) 1.116 +{ 1.117 + xcs_msg_t msg; 1.118 + 1.119 + if (!read_sync(xcs_fd, &msg, sizeof(msg))) 1.120 + barf_perror("read from xcs failed!"); 1.121 + 1.122 + domain_cleanup(); 1.123 +} 1.124 + 1.125 +static int xcs_init(void) 1.126 +{ 1.127 + int ctrl_fd, data_fd; 1.128 + xcs_msg_t msg; 1.129 + 1.130 + ctrl_fd = open_domain_socket(XCS_SUN_PATH); 1.131 + if (ctrl_fd == -1) 1.132 + barf_perror("Failed to contact xcs. Is it running?"); 1.133 + 1.134 + data_fd = open_domain_socket(XCS_SUN_PATH); 1.135 + if (data_fd == -1) 1.136 + barf_perror("Failed to contact xcs. Is it running?"); 1.137 + 1.138 + memset(&msg, 0, sizeof(msg)); 1.139 + msg.type = XCS_CONNECT_CTRL; 1.140 + if (!xcs_send_recv(ctrl_fd, &msg) || msg.result != XCS_RSLT_OK) 1.141 + barf_perror("xcs control connect failed."); 1.142 + 1.143 + msg.type = XCS_CONNECT_DATA; 1.144 + if (!xcs_send_recv(data_fd, &msg) || msg.result != XCS_RSLT_OK) 1.145 + barf_perror("xcs data connect failed."); 1.146 + 1.147 + msg.type = XCS_VIRQ_BIND; 1.148 + msg.u.virq.virq = VIRQ_DOM_EXC; 1.149 + if (!xcs_send_recv(ctrl_fd, &msg) || msg.result != XCS_RSLT_OK) 1.150 + barf_perror("xcs virq bind failed."); 1.151 + 1.152 + return data_fd; 1.153 +} 1.154 + 1.155 1.156 static struct option options[] = { 1.157 { "pid-file", 1, NULL, 'F' }, 1.158 @@ -1647,7 +1772,7 @@ static struct option options[] = { 1.159 1.160 int main(int argc, char *argv[]) 1.161 { 1.162 - int opt, *sock, *ro_sock, event_fd, max; 1.163 + int opt, *sock, *ro_sock, event_fd, xcs_fd, max; 1.164 struct sockaddr_un addr; 1.165 fd_set inset, outset; 1.166 bool dofork = true; 1.167 @@ -1731,6 +1856,9 @@ int main(int argc, char *argv[]) 1.168 /* Listen to hypervisor. */ 1.169 event_fd = domain_init(); 1.170 1.171 + /* Listen to hypervisor - more. */ 1.172 + xcs_fd = xcs_init(); 1.173 + 1.174 /* Restore existing connections. */ 1.175 restore_existing_connections(); 1.176 1.177 @@ -1751,7 +1879,8 @@ int main(int argc, char *argv[]) 1.178 #endif 1.179 1.180 /* Get ready to listen to the tools. */ 1.181 - max = initialize_set(&inset, &outset, *sock, *ro_sock, event_fd); 1.182 + max = initialize_set(&inset, &outset, *sock, *ro_sock, event_fd, 1.183 + xcs_fd); 1.184 1.185 /* Main loop. */ 1.186 /* FIXME: Rewrite so noone can starve. */ 1.187 @@ -1782,6 +1911,9 @@ int main(int argc, char *argv[]) 1.188 if (FD_ISSET(event_fd, &inset)) 1.189 handle_event(event_fd); 1.190 1.191 + if (FD_ISSET(xcs_fd, &inset)) 1.192 + handle_xcs(xcs_fd); 1.193 + 1.194 list_for_each_entry(i, &connections, list) { 1.195 if (i->domain) 1.196 continue; 1.197 @@ -1824,6 +1956,7 @@ int main(int argc, char *argv[]) 1.198 /* If transactions ended, we might be able to do more work. */ 1.199 unblock_connections(); 1.200 1.201 - max = initialize_set(&inset, &outset, *sock,*ro_sock,event_fd); 1.202 + max = initialize_set(&inset, &outset, *sock, *ro_sock, 1.203 + event_fd, xcs_fd); 1.204 } 1.205 }
2.1 --- a/tools/xenstore/xenstored_domain.c Tue Sep 06 13:43:28 2005 +0000 2.2 +++ b/tools/xenstore/xenstored_domain.c Tue Sep 06 16:59:14 2005 +0000 2.3 @@ -363,6 +363,21 @@ void do_release(struct connection *conn, 2.4 send_ack(conn, XS_RELEASE); 2.5 } 2.6 2.7 +void domain_cleanup(void) 2.8 +{ 2.9 + xc_dominfo_t dominfo; 2.10 + struct domain *domain, *tmp; 2.11 + 2.12 + list_for_each_entry_safe(domain, tmp, &domains, list) { 2.13 + if (xc_domain_getinfo(*xc_handle, domain->domid, 1, 2.14 + &dominfo) == 1 && 2.15 + dominfo.domid == domain->domid && 2.16 + !dominfo.dying && !dominfo.crashed && !dominfo.shutdown) 2.17 + continue; 2.18 + talloc_free(domain->conn); 2.19 + } 2.20 +} 2.21 + 2.22 void do_get_domain_path(struct connection *conn, const char *domid_str) 2.23 { 2.24 struct domain *domain;
3.1 --- a/tools/xenstore/xenstored_domain.h Tue Sep 06 13:43:28 2005 +0000 3.2 +++ b/tools/xenstore/xenstored_domain.h Tue Sep 06 16:59:14 2005 +0000 3.3 @@ -28,6 +28,10 @@ void do_introduce(struct connection *con 3.4 /* domid */ 3.5 void do_release(struct connection *conn, const char *domid_str); 3.6 3.7 +/* Enumerate domains and release connections for non-existant or dying 3.8 + * domains. */ 3.9 +void domain_cleanup(void); 3.10 + 3.11 /* domid */ 3.12 void do_get_domain_path(struct connection *conn, const char *domid_str); 3.13