ia64/xen-unstable
changeset 6655:275e28658c66
Update consoled to use xs_get_domain_path and cleanup domain tracking code.
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 Sep 06 13:43:28 2005 +0000 (2005-09-06) |
parents | aeaa3c83f6e5 |
children | d6d77aa96aa1 |
files | tools/console/daemon/io.c tools/console/daemon/utils.c tools/console/daemon/utils.h tools/python/xen/xend/XendDomainInfo.py |
line diff
1.1 --- a/tools/console/daemon/io.c Mon Sep 05 20:05:58 2005 +0000 1.2 +++ b/tools/console/daemon/io.c Tue Sep 06 13:43:28 2005 +0000 1.3 @@ -43,6 +43,9 @@ 1.4 #define MAX(a, b) (((a) > (b)) ? (a) : (b)) 1.5 #define MIN(a, b) (((a) < (b)) ? (a) : (b)) 1.6 1.7 +/* Each 10 bits takes ~ 3 digits, plus one, plus one for nul terminator. */ 1.8 +#define MAX_STRLEN(x) ((sizeof(x) * CHAR_BIT + CHAR_BIT-1) / 10 * 3 + 2) 1.9 + 1.10 struct buffer 1.11 { 1.12 char *data; 1.13 @@ -58,9 +61,9 @@ struct domain 1.14 bool is_dead; 1.15 struct buffer buffer; 1.16 struct domain *next; 1.17 - unsigned long mfn; 1.18 + char *conspath; 1.19 + int ring_ref; 1.20 int local_port; 1.21 - int remote_port; 1.22 char *page; 1.23 int evtchn_fd; 1.24 }; 1.25 @@ -212,57 +215,68 @@ int xs_gather(struct xs_handle *xs, cons 1.26 1.27 static int domain_create_ring(struct domain *dom) 1.28 { 1.29 - char *dompath; 1.30 - int err; 1.31 + int err, local_port, ring_ref; 1.32 1.33 - dompath = xs_get_domain_path(xs, dom->domid); 1.34 - if (!dompath) 1.35 - return ENOENT; 1.36 - 1.37 - err = xs_gather(xs, dompath, 1.38 - "console_mfn", "%li", &dom->mfn, 1.39 - "console_channel/port1", "%i", &dom->local_port, 1.40 - "console_channel/port2", "%i", &dom->remote_port, 1.41 + err = xs_gather(xs, dom->conspath, 1.42 + "ring-ref", "%u", &ring_ref, 1.43 + "console_channel/port1", "%i", &local_port, 1.44 NULL); 1.45 if (err) 1.46 goto out; 1.47 1.48 - if (dom->page == NULL) { 1.49 + if (ring_ref != dom->ring_ref) { 1.50 + if (dom->page) 1.51 + munmap(dom->page, getpagesize()); 1.52 dom->page = xc_map_foreign_range(xc, dom->domid, getpagesize(), 1.53 PROT_READ|PROT_WRITE, 1.54 - dom->mfn); 1.55 + (unsigned long)ring_ref); 1.56 if (dom->page == NULL) { 1.57 err = EINVAL; 1.58 goto out; 1.59 } 1.60 + dom->ring_ref = ring_ref; 1.61 } 1.62 1.63 - if (dom->evtchn_fd == -1) { 1.64 + if (local_port != dom->local_port) { 1.65 + dom->local_port = -1; 1.66 + if (dom->evtchn_fd != -1) 1.67 + close(dom->evtchn_fd); 1.68 /* Opening evtchn independently for each console is a bit 1.69 * wastefule, but that's how the code is structured... */ 1.70 - err = open("/dev/xen/evtchn", O_RDWR); 1.71 - if (err == -1) { 1.72 + dom->evtchn_fd = open("/dev/xen/evtchn", O_RDWR); 1.73 + if (dom->evtchn_fd == -1) { 1.74 err = errno; 1.75 goto out; 1.76 } 1.77 - dom->evtchn_fd = err; 1.78 1.79 - if (ioctl(dom->evtchn_fd, EVENTCHN_BIND, 1.80 - dom->local_port) == -1) { 1.81 + if (ioctl(dom->evtchn_fd, EVENTCHN_BIND, local_port) == -1) { 1.82 err = errno; 1.83 - munmap(dom->page, getpagesize()); 1.84 - dom->page = NULL; 1.85 close(dom->evtchn_fd); 1.86 dom->evtchn_fd = -1; 1.87 goto out; 1.88 } 1.89 + dom->local_port = local_port; 1.90 } 1.91 1.92 out: 1.93 - free(dompath); 1.94 return err; 1.95 } 1.96 1.97 +static bool watch_domain(struct domain *dom, bool watch) 1.98 +{ 1.99 + char domid_str[3 + MAX_STRLEN(dom->domid)]; 1.100 + bool success; 1.101 + 1.102 + sprintf(domid_str, "dom%u", dom->domid); 1.103 + if (watch) 1.104 + success = xs_watch(xs, dom->conspath, domid_str); 1.105 + else 1.106 + success = xs_unwatch(xs, dom->conspath, domid_str); 1.107 + if (success) 1.108 + domain_create_ring(dom); 1.109 + return success; 1.110 +} 1.111 + 1.112 static struct domain *create_domain(int domid) 1.113 { 1.114 struct domain *dom; 1.115 @@ -283,14 +297,36 @@ static struct domain *create_domain(int 1.116 dom->buffer.max_capacity = 0; 1.117 dom->next = NULL; 1.118 1.119 + dom->ring_ref = -1; 1.120 + dom->local_port = -1; 1.121 dom->page = NULL; 1.122 dom->evtchn_fd = -1; 1.123 1.124 - domain_create_ring(dom); 1.125 + dom->conspath = NULL; 1.126 + 1.127 + dom->conspath = xs_get_domain_path(xs, dom->domid); 1.128 + if (dom->conspath == NULL) 1.129 + goto out; 1.130 + dom->conspath = realloc(dom->conspath, strlen(dom->conspath) + 1.131 + strlen("/console") + 1); 1.132 + if (dom->conspath == NULL) 1.133 + goto out; 1.134 + strcat(dom->conspath, "/console"); 1.135 + 1.136 + if (!watch_domain(dom, true)) 1.137 + goto out; 1.138 + 1.139 + dom->next = dom_head; 1.140 + dom_head = dom; 1.141 1.142 dolog(LOG_DEBUG, "New domain %d", domid); 1.143 1.144 return dom; 1.145 + out: 1.146 + if (dom->conspath) 1.147 + free(dom->conspath); 1.148 + free(dom); 1.149 + return NULL; 1.150 } 1.151 1.152 static struct domain *lookup_domain(int domid) 1.153 @@ -300,14 +336,7 @@ static struct domain *lookup_domain(int 1.154 for (dom = dom_head; dom; dom = dom->next) 1.155 if (dom->domid == domid) 1.156 return dom; 1.157 - 1.158 - dom = create_domain(domid); 1.159 - if (!dom) 1.160 - return NULL; 1.161 - dom->next = dom_head; 1.162 - dom_head = dom; 1.163 - 1.164 - return dom; 1.165 + return NULL; 1.166 } 1.167 1.168 static void remove_domain(struct domain *dom) 1.169 @@ -317,34 +346,39 @@ static void remove_domain(struct domain 1.170 dolog(LOG_DEBUG, "Removing domain-%d", dom->domid); 1.171 1.172 for (pp = &dom_head; *pp; pp = &(*pp)->next) { 1.173 - struct domain *d = *pp; 1.174 - 1.175 - if (dom->domid == d->domid) { 1.176 - *pp = d->next; 1.177 - if (d->buffer.data) 1.178 - free(d->buffer.data); 1.179 - if (d->page) 1.180 - munmap(d->page, getpagesize()); 1.181 - if (d->evtchn_fd != -1) 1.182 - close(d->evtchn_fd); 1.183 - if (d->tty_fd != -1) 1.184 - close(d->tty_fd); 1.185 - free(d); 1.186 + if (dom == *pp) { 1.187 + *pp = dom->next; 1.188 + free(dom); 1.189 break; 1.190 } 1.191 } 1.192 } 1.193 1.194 -static void remove_dead_domains(struct domain *dom) 1.195 +static void cleanup_domain(struct domain *d) 1.196 { 1.197 - struct domain *n; 1.198 + if (!buffer_empty(&d->buffer)) 1.199 + return; 1.200 1.201 - while (dom != NULL) { 1.202 - n = dom->next; 1.203 - if (dom->is_dead) 1.204 - remove_domain(dom); 1.205 - dom = n; 1.206 - } 1.207 + if (d->buffer.data) 1.208 + free(d->buffer.data); 1.209 + d->buffer.data = NULL; 1.210 + if (d->tty_fd != -1) 1.211 + close(d->tty_fd); 1.212 + d->tty_fd = -1; 1.213 + remove_domain(d); 1.214 +} 1.215 + 1.216 +static void shutdown_domain(struct domain *d) 1.217 +{ 1.218 + d->is_dead = true; 1.219 + watch_domain(d, false); 1.220 + if (d->page) 1.221 + munmap(d->page, getpagesize()); 1.222 + d->page = NULL; 1.223 + if (d->evtchn_fd != -1) 1.224 + close(d->evtchn_fd); 1.225 + d->evtchn_fd = -1; 1.226 + cleanup_domain(d); 1.227 } 1.228 1.229 void enum_domains(void) 1.230 @@ -355,8 +389,13 @@ void enum_domains(void) 1.231 1.232 while (xc_domain_getinfo(xc, domid, 1, &dominfo) == 1) { 1.233 dom = lookup_domain(dominfo.domid); 1.234 - if (dominfo.dying || dominfo.crashed || dominfo.shutdown) 1.235 - dom->is_dead = true; 1.236 + if (dominfo.dying || dominfo.crashed || dominfo.shutdown) { 1.237 + if (dom) 1.238 + shutdown_domain(dom); 1.239 + } else { 1.240 + if (dom == NULL) 1.241 + create_domain(dominfo.domid); 1.242 + } 1.243 domid = dominfo.domid + 1; 1.244 } 1.245 } 1.246 @@ -377,7 +416,7 @@ static void handle_tty_read(struct domai 1.247 if (domain_is_valid(dom->domid)) { 1.248 dom->tty_fd = domain_create_tty(dom); 1.249 } else { 1.250 - dom->is_dead = true; 1.251 + shutdown_domain(dom); 1.252 } 1.253 } else if (domain_is_valid(dom->domid)) { 1.254 for (i = 0; i < len; i++) { 1.255 @@ -388,7 +427,7 @@ static void handle_tty_read(struct domai 1.256 } else { 1.257 close(dom->tty_fd); 1.258 dom->tty_fd = -1; 1.259 - dom->is_dead = true; 1.260 + shutdown_domain(dom); 1.261 } 1.262 } 1.263 1.264 @@ -404,7 +443,7 @@ static void handle_tty_write(struct doma 1.265 if (domain_is_valid(dom->domid)) { 1.266 dom->tty_fd = domain_create_tty(dom); 1.267 } else { 1.268 - dom->is_dead = true; 1.269 + shutdown_domain(dom); 1.270 } 1.271 } else { 1.272 buffer_advance(&dom->buffer, len); 1.273 @@ -445,12 +484,13 @@ static void handle_xs(int fd) 1.274 if (!vec) 1.275 return; 1.276 1.277 - if (sscanf(vec[0], "/console/%d", &domid) == 1) { 1.278 + if (!strcmp(vec[1], "introduceDomain")) 1.279 + enum_domains(); 1.280 + else if (sscanf(vec[1], "dom%u", &domid) == 1) { 1.281 dom = lookup_domain(domid); 1.282 - if (dom && (dom->evtchn_fd == -1 || dom->page == NULL)) 1.283 + if (dom->is_dead == false) 1.284 domain_create_ring(dom); 1.285 } 1.286 - enum_domains(); 1.287 1.288 xs_acknowledge_watch(xs, vec[1]); 1.289 free(vec); 1.290 @@ -462,7 +502,7 @@ void handle_io(void) 1.291 int ret; 1.292 1.293 do { 1.294 - struct domain *d; 1.295 + struct domain *d, *n; 1.296 struct timeval tv = { 100, 0 }; 1.297 int max_fd = -1; 1.298 1.299 @@ -476,18 +516,19 @@ void handle_io(void) 1.300 max_fd = MAX(xs_fileno(xs), max_fd); 1.301 1.302 for (d = dom_head; d; d = d->next) { 1.303 - if (d->tty_fd != -1) { 1.304 - FD_SET(d->tty_fd, &readfds); 1.305 - } 1.306 - if (d->evtchn_fd != -1) 1.307 + if (d->evtchn_fd != -1) { 1.308 FD_SET(d->evtchn_fd, &readfds); 1.309 - 1.310 - if (d->tty_fd != -1 && !buffer_empty(&d->buffer)) { 1.311 - FD_SET(d->tty_fd, &writefds); 1.312 + max_fd = MAX(d->evtchn_fd, max_fd); 1.313 } 1.314 1.315 - max_fd = MAX(d->tty_fd, max_fd); 1.316 - max_fd = MAX(d->evtchn_fd, max_fd); 1.317 + if (d->tty_fd != -1) { 1.318 + if (!d->is_dead) 1.319 + FD_SET(d->tty_fd, &readfds); 1.320 + 1.321 + if (!buffer_empty(&d->buffer)) 1.322 + FD_SET(d->tty_fd, &writefds); 1.323 + max_fd = MAX(d->tty_fd, max_fd); 1.324 + } 1.325 } 1.326 1.327 ret = select(max_fd + 1, &readfds, &writefds, 0, &tv); 1.328 @@ -498,21 +539,22 @@ void handle_io(void) 1.329 if (FD_ISSET(xcs_data_fd, &readfds)) 1.330 handle_xcs_msg(xcs_data_fd); 1.331 1.332 - for (d = dom_head; d; d = d->next) { 1.333 - if (d->is_dead || d->tty_fd == -1 || 1.334 - d->evtchn_fd == -1) 1.335 - continue; 1.336 - 1.337 - if (FD_ISSET(d->tty_fd, &readfds)) 1.338 - handle_tty_read(d); 1.339 - 1.340 - if (FD_ISSET(d->evtchn_fd, &readfds)) 1.341 + for (d = dom_head; d; d = n) { 1.342 + n = d->next; 1.343 + if (d->evtchn_fd != -1 && 1.344 + FD_ISSET(d->evtchn_fd, &readfds)) 1.345 handle_ring_read(d); 1.346 1.347 - if (FD_ISSET(d->tty_fd, &writefds)) 1.348 - handle_tty_write(d); 1.349 + if (d->tty_fd != -1) { 1.350 + if (FD_ISSET(d->tty_fd, &readfds)) 1.351 + handle_tty_read(d); 1.352 + 1.353 + if (FD_ISSET(d->tty_fd, &writefds)) 1.354 + handle_tty_write(d); 1.355 + 1.356 + if (d->is_dead) 1.357 + cleanup_domain(d); 1.358 + } 1.359 } 1.360 - 1.361 - remove_dead_domains(dom_head); 1.362 } while (ret > -1); 1.363 }
2.1 --- a/tools/console/daemon/utils.c Mon Sep 05 20:05:58 2005 +0000 2.2 +++ b/tools/console/daemon/utils.c Tue Sep 06 13:43:28 2005 +0000 2.3 @@ -233,7 +233,7 @@ bool xen_setup(void) 2.4 goto out_close_data; 2.5 } 2.6 2.7 - if (!xs_watch(xs, "@introduceDomain", "console")) { 2.8 + if (!xs_watch(xs, "@introduceDomain", "introduceDomain")) { 2.9 dolog(LOG_ERR, "xenstore watch on @introduceDomain fails."); 2.10 goto out_close_data; 2.11 }
3.1 --- a/tools/console/daemon/utils.h Mon Sep 05 20:05:58 2005 +0000 3.2 +++ b/tools/console/daemon/utils.h Tue Sep 06 13:43:28 2005 +0000 3.3 @@ -39,7 +39,11 @@ extern struct xs_handle *xs; 3.4 extern int xc; 3.5 3.6 #if 1 3.7 -#define dolog(val, fmt, ...) syslog(val, fmt, ## __VA_ARGS__) 3.8 +#define dolog(val, fmt, ...) do { \ 3.9 + if ((val) == LOG_ERR) \ 3.10 + fprintf(stderr, fmt "\n", ## __VA_ARGS__); \ 3.11 + syslog(val, fmt, ## __VA_ARGS__); \ 3.12 +} while (/* CONSTCOND */0) 3.13 #else 3.14 #define dolog(val, fmt, ...) fprintf(stderr, fmt "\n", ## __VA_ARGS__) 3.15 #endif
4.1 --- a/tools/python/xen/xend/XendDomainInfo.py Mon Sep 05 20:05:58 2005 +0000 4.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Tue Sep 06 13:43:28 2005 +0000 4.3 @@ -231,7 +231,7 @@ class XendDomainInfo: 4.4 DBVar('start_time', ty='float'), 4.5 DBVar('state', ty='str'), 4.6 DBVar('store_mfn', ty='long'), 4.7 - DBVar('console_mfn', ty='long'), 4.8 + DBVar('console_mfn', ty='long', path="console/ring-ref"), 4.9 DBVar('restart_mode', ty='str'), 4.10 DBVar('restart_state', ty='str'), 4.11 DBVar('restart_time', ty='float'), 4.12 @@ -302,7 +302,7 @@ class XendDomainInfo: 4.13 self.store_channel.saveToDB(self.db.addChild("store_channel"), 4.14 save=save) 4.15 if self.console_channel: 4.16 - self.console_channel.saveToDB(self.db.addChild("console_channel"), 4.17 + self.console_channel.saveToDB(self.db.addChild("console/console_channel"), 4.18 save=save) 4.19 if self.image: 4.20 self.image.exportToDB(save=save, sync=sync) 4.21 @@ -886,7 +886,7 @@ class XendDomainInfo: 4.22 """ 4.23 self.channel = self.openChannel("channel", 0, 1) 4.24 self.store_channel = self.eventChannel("store_channel") 4.25 - self.console_channel = self.eventChannel("console_channel") 4.26 + self.console_channel = self.eventChannel("console/console_channel") 4.27 4.28 def create_configured_devices(self): 4.29 devices = sxp.children(self.config, 'device')