Use watch to detect new domains and avoid polling for dead domains.

Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
This commit is contained in:
cl349@firebug.cl.cam.ac.uk committed 2005-08-30 20:02:59 +00:00
1 parent 7af47820e8
commit af2f00c972
4 files changed
+86 -47

No files matched your search

+76 -45
View File
@@ -215,9 +215,6 @@ static int domain_create_ring(struct domain *dom)
char *dompath, *path;
int err;
dom->page = NULL;
dom->evtchn_fd = -1;
asprintf(&path, "/console/%d/domain", dom->domid);
dompath = xs_read(xs, path, NULL);
free(path);
@@ -232,28 +229,35 @@ static int domain_create_ring(struct domain *dom)
if (err)
goto out;
dom->page = xc_map_foreign_range(xc, dom->domid, getpagesize(),
PROT_READ|PROT_WRITE, dom->mfn);
if (dom->page == NULL) {
err = EINVAL;
goto out;
dom->page = xc_map_foreign_range(xc, dom->domid, getpagesize(),
PROT_READ|PROT_WRITE,
dom->mfn);
if (dom->page == NULL) {
err = EINVAL;
goto out;
}
}
/* Opening evtchn independently for each console is a bit
* wastefule, but that's how the code is structured... */
err = open("/dev/xen/evtchn", O_RDWR);
if (err == -1) {
err = errno;
goto out;
}
dom->evtchn_fd = err;
if (ioctl(dom->evtchn_fd, EVENTCHN_BIND, dom->local_port) == -1) {
err = errno;
munmap(dom->page, getpagesize());
close(dom->evtchn_fd);
dom->evtchn_fd = -1;
goto out;
if (dom->evtchn_fd == -1) {
/* Opening evtchn independently for each console is a bit
* wastefule, but that's how the code is structured... */
err = open("/dev/xen/evtchn", O_RDWR);
if (err == -1) {
err = errno;
goto out;
}
dom->evtchn_fd = err;
if (ioctl(dom->evtchn_fd, EVENTCHN_BIND,
dom->local_port) == -1) {
err = errno;
munmap(dom->page, getpagesize());
dom->page = NULL;
close(dom->evtchn_fd);
dom->evtchn_fd = -1;
goto out;
}
}
out:
@@ -281,6 +285,9 @@ static struct domain *create_domain(int domid)
dom->buffer.max_capacity = 0;
dom->next = NULL;
dom->page = NULL;
dom->evtchn_fd = -1;
domain_create_ring(dom);
dolog(LOG_DEBUG, "New domain %d", domid);
@@ -290,22 +297,19 @@ static struct domain *create_domain(int domid)
static struct domain *lookup_domain(int domid)
{
struct domain **pp;
struct domain *dom;
for (pp = &dom_head; *pp; pp = &(*pp)->next) {
struct domain *dom = *pp;
if (dom->domid == domid) {
for (dom = dom_head; dom; dom = dom->next)
if (dom->domid == domid)
return dom;
} else if (dom->domid > domid) {
*pp = create_domain(domid);
(*pp)->next = dom;
return *pp;
}
}
*pp = create_domain(domid);
return *pp;
dom = create_domain(domid);
if (!dom)
return NULL;
dom->next = dom_head;
dom_head = dom;
return dom;
}
static void remove_domain(struct domain *dom)
@@ -345,6 +349,20 @@ static void remove_dead_domains(struct domain *dom)
}
}
void enum_domains(void)
{
int domid = 1;
xc_dominfo_t dominfo;
struct domain *dom;
while (xc_domain_getinfo(xc, domid, 1, &dominfo) == 1) {
dom = lookup_domain(dominfo.domid);
if (dominfo.dying || dominfo.crashed || dominfo.shutdown)
dom->is_dead = true;
domid = dominfo.domid + 1;
}
}
static void handle_tty_read(struct domain *dom)
{
ssize_t len;
@@ -415,20 +433,28 @@ static void handle_xcs_msg(int fd)
dolog(LOG_ERR, "read from xcs failed! %m");
exit(1);
}
enum_domains();
}
static void enum_domains(void)
static void handle_xs(int fd)
{
int domid = 0;
xc_dominfo_t dominfo;
char **vec;
int domid;
struct domain *dom;
while (xc_domain_getinfo(xc, domid, 1, &dominfo) == 1) {
dom = lookup_domain(dominfo.domid);
if (dominfo.dying || dominfo.crashed || dominfo.shutdown)
dom->is_dead = true;
domid = dominfo.domid + 1;
vec = xs_read_watch(xs);
if (!vec)
return;
if (sscanf(vec[0], "/console/%d", &domid) == 1) {
dom = lookup_domain(domid);
if (dom && (dom->evtchn_fd == -1 || dom->page == NULL))
domain_create_ring(dom);
}
xs_acknowledge_watch(xs, vec[1]);
free(vec);
}
void handle_io(void)
@@ -438,7 +464,7 @@ void handle_io(void)
do {
struct domain *d;
struct timeval tv = { 1, 0 };
struct timeval tv = { 100, 0 };
int max_fd = -1;
FD_ZERO(&readfds);
@@ -447,6 +473,9 @@ void handle_io(void)
FD_SET(xcs_data_fd, &readfds);
max_fd = MAX(xcs_data_fd, max_fd);
FD_SET(xs_fileno(xs), &readfds);
max_fd = MAX(xs_fileno(xs), max_fd);
for (d = dom_head; d; d = d->next) {
if (d->tty_fd != -1) {
FD_SET(d->tty_fd, &readfds);
@@ -463,7 +492,9 @@ void handle_io(void)
}
ret = select(max_fd + 1, &readfds, &writefds, 0, &tv);
enum_domains();
if (FD_ISSET(xs_fileno(xs), &readfds))
handle_xs(xs_fileno(xs));
if (FD_ISSET(xcs_data_fd, &readfds))
handle_xcs_msg(xcs_data_fd);
+1
View File
@@ -21,6 +21,7 @@
#ifndef CONSOLED_IO_H
#define CONSOLED_IO_H
void enum_domains(void);
void handle_io(void);
#endif
+2
View File
@@ -85,6 +85,8 @@ int main(int argc, char **argv)
xen_setup();
enum_domains();
handle_io();
closelog();
+7 -2
View File
@@ -232,11 +232,16 @@ bool xen_setup(void)
dolog(LOG_ERR, "xcs virq bind failed. Possible bug.");
goto out_close_data;
}
if (!xs_watch(xs, "/console", "console")) {
dolog(LOG_ERR, "xenstore watch on /console failes.");
goto out_close_data;
}
return true;
out_close_data:
close(xcs_ctrl_fd);
close(xcs_data_fd);
xcs_data_fd = -1;
out_close_ctrl:
close(xcs_ctrl_fd);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.