From dd77b90d427f9be31805d9331d3ad18e32d2a2b0 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Mon, 26 Dec 2011 23:29:07 +0100 Subject: [PATCH] vm: force meminfo-writer to wait for the first user process (#392) meminfo-writer will wait for SIGUSR1 - send by qrexec-agent on the first qvm-run from dom0. --- appvm/qubes_core_appvm | 2 +- common/meminfo-writer.c | 48 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/appvm/qubes_core_appvm b/appvm/qubes_core_appvm index 085b544..9e0d68c 100755 --- a/appvm/qubes_core_appvm +++ b/appvm/qubes_core_appvm @@ -64,7 +64,7 @@ start() if [ "$start_meminfo_writer" != "0" ]; then MEM_CHANGE_THRESHOLD_KB=30000 MEMINFO_DELAY_USEC=100000 - /usr/lib/qubes/meminfo-writer $MEM_CHANGE_THRESHOLD_KB $MEMINFO_DELAY_USEC & + /usr/lib/qubes/meminfo-writer $MEM_CHANGE_THRESHOLD_KB $MEMINFO_DELAY_USEC /var/run/meminfo-writer.pid fi success diff --git a/common/meminfo-writer.c b/common/meminfo-writer.c index 49c8b6a..c9e1059 100644 --- a/common/meminfo-writer.c +++ b/common/meminfo-writer.c @@ -5,10 +5,12 @@ #include #include #include +#include unsigned long prev_used_mem; int used_mem_change_threshold; int delay; +int usr1_received; char *parse(char *buf) { @@ -73,7 +75,10 @@ char *parse(char *buf) void usage() { fprintf(stderr, - "usage: meminfo_writer threshold_in_kb delay_in_us\n"); + "usage: meminfo_writer threshold_in_kb delay_in_us [pidfile]\n"); + fprintf(stderr, " When pidfile set, meminfo-writer will:\n"); + fprintf(stderr, " - fork into background\n"); + fprintf(stderr, " - wait for SIGURS1 (in background) before starting main work\n"); exit(1); } @@ -85,6 +90,10 @@ void send_to_qmemman(struct xs_handle *xs, char *data) } } +void usr1_handler(int sig) { + usr1_received = 1; +} + int main(int argc, char **argv) { char buf[4096]; @@ -93,13 +102,48 @@ int main(int argc, char **argv) int fd; struct xs_handle *xs; - if (argc != 3) + if (argc != 3 && argc != 4) usage(); used_mem_change_threshold = atoi(argv[1]); delay = atoi(argv[2]); if (!used_mem_change_threshold || !delay) usage(); + if (argc == 4) { + pid_t pid; + sigset_t mask, oldmask; + + switch (pid = fork()) { + case -1: + perror("fork"); + exit(1); + case 0: + sigemptyset (&mask); + sigaddset (&mask, SIGUSR1); + /* Wait for a signal to arrive. */ + sigprocmask (SIG_BLOCK, &mask, &oldmask); + usr1_received = 0; + signal(SIGUSR1, usr1_handler); + while (!usr1_received) + sigsuspend (&oldmask); + sigprocmask (SIG_UNBLOCK, &mask, NULL); + break; + default: + fd = open(argv[3], O_CREAT | O_TRUNC | O_WRONLY, 0666); + if (fd < 0) { + perror("open pidfile"); + exit(1); + } + n = sprintf(buf, "%d\n", pid); + if (write(fd, buf, n) != n) { + perror("write pid"); + exit(1); + } + close(fd); + exit(0); + } + } + fd = open("/proc/meminfo", O_RDONLY); if (fd < 0) { perror("open meminfo");