Subject: xenpaging: add signal handling Leave paging loop if xenpaging gets a signal. Remove paging file on exit. Signed-off-by: Olaf Hering --- v2: unlink pagefile in signal handler to avoid stale pagefiles if xenpaging is stuck in some loop tools/xenpaging/xenpaging.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) --- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c +++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -40,6 +41,14 @@ #define DPRINTF(...) ((void)0) #endif +static char filename[80]; +static int interrupted; +static void close_handler(int sig) +{ + interrupted = sig; + if ( filename[0] ) + unlink(filename); +} static void *init_page(void) { @@ -244,7 +253,6 @@ int xenpaging_teardown(xenpaging_t *pagi if ( rc != 0 ) { ERROR("Error tearing down domain paging in xen"); - goto err; } /* Unbind VIRQ */ @@ -252,7 +260,6 @@ int xenpaging_teardown(xenpaging_t *pagi if ( rc != 0 ) { ERROR("Error unbinding event port"); - goto err; } paging->mem_event.port = -1; @@ -261,7 +268,6 @@ int xenpaging_teardown(xenpaging_t *pagi if ( rc != 0 ) { ERROR("Error closing event channel"); - goto err; } paging->mem_event.xce_handle = -1; @@ -270,7 +276,6 @@ int xenpaging_teardown(xenpaging_t *pagi if ( rc != 0 ) { ERROR("Error closing connection to xen"); - goto err; } paging->xc_handle = -1; @@ -375,7 +380,7 @@ int xenpaging_evict_page(xenpaging_t *pa return ret; } -int xenpaging_resume_page(xenpaging_t *paging, mem_event_response_t *rsp) +static int xenpaging_resume_page(xenpaging_t *paging, mem_event_response_t *rsp) { int ret; @@ -455,6 +460,11 @@ static int evict_victim(xenpaging_t *pag goto out; } + if ( interrupted ) + { + ret = -EINTR; + goto out; + } ret = xc_mem_paging_nominate(paging->xc_handle, paging->mem_event.domain_id, victim->gfn); if ( ret == 0 ) @@ -479,6 +489,7 @@ static int evict_victim(xenpaging_t *pag int main(int argc, char *argv[]) { + struct sigaction act; domid_t domain_id; int num_pages; xenpaging_t *paging; @@ -491,7 +502,6 @@ int main(int argc, char *argv[]) int open_flags = O_CREAT | O_TRUNC | O_RDWR; mode_t open_mode = S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH; - char filename[80]; int fd; if ( argc != 3 ) @@ -513,7 +523,7 @@ int main(int argc, char *argv[]) if ( paging == NULL ) { ERROR("Error initialising paging"); - goto out; + return 1; } /* Open file */ @@ -522,9 +532,18 @@ int main(int argc, char *argv[]) if ( fd < 0 ) { perror("failed to open file"); - return -1; + return 2; } + /* ensure that if we get a signal, we'll do cleanup, then exit */ + act.sa_handler = close_handler; + act.sa_flags = 0; + sigemptyset(&act.sa_mask); + sigaction(SIGHUP, &act, NULL); + sigaction(SIGTERM, &act, NULL); + sigaction(SIGINT, &act, NULL); + sigaction(SIGALRM, &act, NULL); + /* Evict pages */ memset(victims, 0, sizeof(xenpaging_victim_t) * num_pages); for ( i = 0; i < num_pages; i++ ) @@ -532,6 +551,8 @@ int main(int argc, char *argv[]) rc = evict_victim(paging, domain_id, &victims[i], fd, i); if ( rc == -ENOSPC ) break; + if ( rc == -EINTR ) + break; if ( i % 100 == 0 ) DPRINTF("%d pages evicted\n", i); } @@ -539,7 +560,7 @@ int main(int argc, char *argv[]) DPRINTF("pages evicted\n"); /* Swap pages in and out */ - while ( 1 ) + while ( !interrupted ) { /* Wait for Xen to signal that a page needs paged in */ rc = xc_wait_for_event_or_timeout(paging->mem_event.xce_handle, 100); @@ -630,8 +651,10 @@ int main(int argc, char *argv[]) } } } + DPRINTF("xenpaging got signal %d\n", interrupted); out: + close(fd); free(victims); /* Tear down domain paging */ @@ -642,6 +665,7 @@ int main(int argc, char *argv[]) if ( rc == 0 ) rc = rc1; + DPRINTF("xenpaging exit code %d\n", rc); return rc; }