ia64/xen-unstable
changeset 6502:9225c3f597db
Use watch to detect new domains and avoid polling for dead domains.
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author | cl349@firebug.cl.cam.ac.uk |
---|---|
date | Tue Aug 30 20:02:59 2005 +0000 (2005-08-30) |
parents | 946ea528fc79 |
children | 1fc6473ecc01 |
files | tools/console/daemon/io.c tools/console/daemon/io.h tools/console/daemon/main.c tools/console/daemon/utils.c |
line diff
1.1 --- a/tools/console/daemon/io.c Tue Aug 30 20:01:23 2005 +0000 1.2 +++ b/tools/console/daemon/io.c Tue Aug 30 20:02:59 2005 +0000 1.3 @@ -215,9 +215,6 @@ static int domain_create_ring(struct dom 1.4 char *dompath, *path; 1.5 int err; 1.6 1.7 - dom->page = NULL; 1.8 - dom->evtchn_fd = -1; 1.9 - 1.10 asprintf(&path, "/console/%d/domain", dom->domid); 1.11 dompath = xs_read(xs, path, NULL); 1.12 free(path); 1.13 @@ -232,28 +229,35 @@ static int domain_create_ring(struct dom 1.14 if (err) 1.15 goto out; 1.16 1.17 - dom->page = xc_map_foreign_range(xc, dom->domid, getpagesize(), 1.18 - PROT_READ|PROT_WRITE, dom->mfn); 1.19 if (dom->page == NULL) { 1.20 - err = EINVAL; 1.21 - goto out; 1.22 + dom->page = xc_map_foreign_range(xc, dom->domid, getpagesize(), 1.23 + PROT_READ|PROT_WRITE, 1.24 + dom->mfn); 1.25 + if (dom->page == NULL) { 1.26 + err = EINVAL; 1.27 + goto out; 1.28 + } 1.29 } 1.30 1.31 - /* Opening evtchn independently for each console is a bit 1.32 - * wastefule, but that's how the code is structured... */ 1.33 - err = open("/dev/xen/evtchn", O_RDWR); 1.34 - if (err == -1) { 1.35 - err = errno; 1.36 - goto out; 1.37 - } 1.38 - dom->evtchn_fd = err; 1.39 - 1.40 - if (ioctl(dom->evtchn_fd, EVENTCHN_BIND, dom->local_port) == -1) { 1.41 - err = errno; 1.42 - munmap(dom->page, getpagesize()); 1.43 - close(dom->evtchn_fd); 1.44 - dom->evtchn_fd = -1; 1.45 - goto out; 1.46 + if (dom->evtchn_fd == -1) { 1.47 + /* Opening evtchn independently for each console is a bit 1.48 + * wastefule, but that's how the code is structured... */ 1.49 + err = open("/dev/xen/evtchn", O_RDWR); 1.50 + if (err == -1) { 1.51 + err = errno; 1.52 + goto out; 1.53 + } 1.54 + dom->evtchn_fd = err; 1.55 + 1.56 + if (ioctl(dom->evtchn_fd, EVENTCHN_BIND, 1.57 + dom->local_port) == -1) { 1.58 + err = errno; 1.59 + munmap(dom->page, getpagesize()); 1.60 + dom->page = NULL; 1.61 + close(dom->evtchn_fd); 1.62 + dom->evtchn_fd = -1; 1.63 + goto out; 1.64 + } 1.65 } 1.66 1.67 out: 1.68 @@ -281,6 +285,9 @@ static struct domain *create_domain(int 1.69 dom->buffer.max_capacity = 0; 1.70 dom->next = NULL; 1.71 1.72 + dom->page = NULL; 1.73 + dom->evtchn_fd = -1; 1.74 + 1.75 domain_create_ring(dom); 1.76 1.77 dolog(LOG_DEBUG, "New domain %d", domid); 1.78 @@ -290,22 +297,19 @@ static struct domain *create_domain(int 1.79 1.80 static struct domain *lookup_domain(int domid) 1.81 { 1.82 - struct domain **pp; 1.83 + struct domain *dom; 1.84 1.85 - for (pp = &dom_head; *pp; pp = &(*pp)->next) { 1.86 - struct domain *dom = *pp; 1.87 - 1.88 - if (dom->domid == domid) { 1.89 + for (dom = dom_head; dom; dom = dom->next) 1.90 + if (dom->domid == domid) 1.91 return dom; 1.92 - } else if (dom->domid > domid) { 1.93 - *pp = create_domain(domid); 1.94 - (*pp)->next = dom; 1.95 - return *pp; 1.96 - } 1.97 - } 1.98 1.99 - *pp = create_domain(domid); 1.100 - return *pp; 1.101 + dom = create_domain(domid); 1.102 + if (!dom) 1.103 + return NULL; 1.104 + dom->next = dom_head; 1.105 + dom_head = dom; 1.106 + 1.107 + return dom; 1.108 } 1.109 1.110 static void remove_domain(struct domain *dom) 1.111 @@ -345,6 +349,20 @@ static void remove_dead_domains(struct d 1.112 } 1.113 } 1.114 1.115 +void enum_domains(void) 1.116 +{ 1.117 + int domid = 1; 1.118 + xc_dominfo_t dominfo; 1.119 + struct domain *dom; 1.120 + 1.121 + while (xc_domain_getinfo(xc, domid, 1, &dominfo) == 1) { 1.122 + dom = lookup_domain(dominfo.domid); 1.123 + if (dominfo.dying || dominfo.crashed || dominfo.shutdown) 1.124 + dom->is_dead = true; 1.125 + domid = dominfo.domid + 1; 1.126 + } 1.127 +} 1.128 + 1.129 static void handle_tty_read(struct domain *dom) 1.130 { 1.131 ssize_t len; 1.132 @@ -415,20 +433,28 @@ static void handle_xcs_msg(int fd) 1.133 dolog(LOG_ERR, "read from xcs failed! %m"); 1.134 exit(1); 1.135 } 1.136 + 1.137 + enum_domains(); 1.138 } 1.139 1.140 -static void enum_domains(void) 1.141 +static void handle_xs(int fd) 1.142 { 1.143 - int domid = 0; 1.144 - xc_dominfo_t dominfo; 1.145 + char **vec; 1.146 + int domid; 1.147 struct domain *dom; 1.148 1.149 - while (xc_domain_getinfo(xc, domid, 1, &dominfo) == 1) { 1.150 - dom = lookup_domain(dominfo.domid); 1.151 - if (dominfo.dying || dominfo.crashed || dominfo.shutdown) 1.152 - dom->is_dead = true; 1.153 - domid = dominfo.domid + 1; 1.154 + vec = xs_read_watch(xs); 1.155 + if (!vec) 1.156 + return; 1.157 + 1.158 + if (sscanf(vec[0], "/console/%d", &domid) == 1) { 1.159 + dom = lookup_domain(domid); 1.160 + if (dom && (dom->evtchn_fd == -1 || dom->page == NULL)) 1.161 + domain_create_ring(dom); 1.162 } 1.163 + 1.164 + xs_acknowledge_watch(xs, vec[1]); 1.165 + free(vec); 1.166 } 1.167 1.168 void handle_io(void) 1.169 @@ -438,7 +464,7 @@ void handle_io(void) 1.170 1.171 do { 1.172 struct domain *d; 1.173 - struct timeval tv = { 1, 0 }; 1.174 + struct timeval tv = { 100, 0 }; 1.175 int max_fd = -1; 1.176 1.177 FD_ZERO(&readfds); 1.178 @@ -447,6 +473,9 @@ void handle_io(void) 1.179 FD_SET(xcs_data_fd, &readfds); 1.180 max_fd = MAX(xcs_data_fd, max_fd); 1.181 1.182 + FD_SET(xs_fileno(xs), &readfds); 1.183 + max_fd = MAX(xs_fileno(xs), max_fd); 1.184 + 1.185 for (d = dom_head; d; d = d->next) { 1.186 if (d->tty_fd != -1) { 1.187 FD_SET(d->tty_fd, &readfds); 1.188 @@ -463,7 +492,9 @@ void handle_io(void) 1.189 } 1.190 1.191 ret = select(max_fd + 1, &readfds, &writefds, 0, &tv); 1.192 - enum_domains(); 1.193 + 1.194 + if (FD_ISSET(xs_fileno(xs), &readfds)) 1.195 + handle_xs(xs_fileno(xs)); 1.196 1.197 if (FD_ISSET(xcs_data_fd, &readfds)) 1.198 handle_xcs_msg(xcs_data_fd);
2.1 --- a/tools/console/daemon/io.h Tue Aug 30 20:01:23 2005 +0000 2.2 +++ b/tools/console/daemon/io.h Tue Aug 30 20:02:59 2005 +0000 2.3 @@ -21,6 +21,7 @@ 2.4 #ifndef CONSOLED_IO_H 2.5 #define CONSOLED_IO_H 2.6 2.7 +void enum_domains(void); 2.8 void handle_io(void); 2.9 2.10 #endif
3.1 --- a/tools/console/daemon/main.c Tue Aug 30 20:01:23 2005 +0000 3.2 +++ b/tools/console/daemon/main.c Tue Aug 30 20:02:59 2005 +0000 3.3 @@ -85,6 +85,8 @@ int main(int argc, char **argv) 3.4 3.5 xen_setup(); 3.6 3.7 + enum_domains(); 3.8 + 3.9 handle_io(); 3.10 3.11 closelog();
4.1 --- a/tools/console/daemon/utils.c Tue Aug 30 20:01:23 2005 +0000 4.2 +++ b/tools/console/daemon/utils.c Tue Aug 30 20:02:59 2005 +0000 4.3 @@ -232,11 +232,16 @@ bool xen_setup(void) 4.4 dolog(LOG_ERR, "xcs virq bind failed. Possible bug."); 4.5 goto out_close_data; 4.6 } 4.7 - 4.8 + 4.9 + if (!xs_watch(xs, "/console", "console")) { 4.10 + dolog(LOG_ERR, "xenstore watch on /console failes."); 4.11 + goto out_close_data; 4.12 + } 4.13 + 4.14 return true; 4.15 4.16 out_close_data: 4.17 - close(xcs_ctrl_fd); 4.18 + close(xcs_data_fd); 4.19 xcs_data_fd = -1; 4.20 out_close_ctrl: 4.21 close(xcs_ctrl_fd);