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>
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')