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