From d2a87252176508d908ee7d071d5e335ec38f8adc Mon Sep 17 00:00:00 2001 From: qubesuser Date: Sat, 10 Oct 2015 00:47:10 +0200 Subject: [PATCH] Report Xen balloon current size instead of Linux total memory This results in qmemman knowing about the memory map overhead and properly sizing VMs. (cherry picked from commit 2d871075cc69b63e27e87db44fb5a612478e4edc) --- qmemman/meminfo-writer.c | 90 ++++++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 27 deletions(-) diff --git a/qmemman/meminfo-writer.c b/qmemman/meminfo-writer.c index 249c820..ee9119b 100644 --- a/qmemman/meminfo-writer.c +++ b/qmemman/meminfo-writer.c @@ -16,9 +16,9 @@ int used_mem_change_threshold; int delay; int usr1_received; -const char *parse(const char *buf) +const char *parse(const char *meminfo_buf, const char* dom_current_buf) { - const char *ptr = buf; + const char *ptr = meminfo_buf; static char outbuf[4096]; int val; int len; @@ -59,6 +59,12 @@ const char *parse(const char *buf) ptr += len; } + if(dom_current_buf) { + int DomTotal = strtol(dom_current_buf, 0, 10); + if(DomTotal) + MemTotal = DomTotal; + } + used_mem = MemTotal - Buffers - Cached - MemFree + SwapTotal - SwapFree; if (used_mem < 0) @@ -103,13 +109,50 @@ void usr1_handler(int sig __attribute__((__unused__))) { usr1_received = 1; } +static inline void pread0_string(int fd, char* buf, size_t buf_size) +{ + int n = pread(fd, buf, buf_size - 1, 0); + if (n < 0) { + perror("pread"); + exit(1); + } + buf[n] = 0; +} + +static void update(struct xs_handle *xs, int meminfo_fd, int dom_current_fd) +{ + char dom_current_buf[32]; + char dom_current_buf2[32]; + char meminfo_buf[4096]; + const char *meminfo_data; + + pread0_string(dom_current_fd, dom_current_buf, sizeof(dom_current_buf)); + + /* check until the dom current reading is stable to avoid races */ + for(;;) { + pread0_string(meminfo_fd, meminfo_buf, sizeof(meminfo_buf)); + pread0_string(dom_current_fd, dom_current_buf2, sizeof(dom_current_buf2)); + + if(!strcmp(dom_current_buf, dom_current_buf2)) + break; + + pread0_string(meminfo_fd, meminfo_buf, sizeof(meminfo_buf)); + pread0_string(dom_current_fd, dom_current_buf, sizeof(dom_current_buf)); + + if(!strcmp(dom_current_buf, dom_current_buf2)) + break; + } + + meminfo_data = parse(meminfo_buf, dom_current_buf); + if (meminfo_data) + send_to_qmemman(xs, meminfo_data); +} + int main(int argc, char **argv) { - char buf[4096]; - int n; - const char *meminfo_data; - int fd; + int meminfo_fd, dom_current_fd; struct xs_handle *xs; + int n; if (argc != 3 && argc != 4) usage(); @@ -121,6 +164,8 @@ int main(int argc, char **argv) if (argc == 4) { pid_t pid; sigset_t mask, oldmask; + int fd; + char buf[32]; switch (pid = fork()) { case -1: @@ -155,9 +200,14 @@ int main(int argc, char **argv) } } - fd = open("/proc/meminfo", O_RDONLY); - if (fd < 0) { - perror("open meminfo"); + meminfo_fd = open("/proc/meminfo", O_RDONLY); + if (meminfo_fd < 0) { + perror("open /proc/meminfo"); + exit(1); + } + dom_current_fd = open("/sys/devices/system/xen_memory/xen_memory0/info/current_kb", O_RDONLY); + if (dom_current_fd < 0) { + perror("open /sys/devices/system/xen_memory/xen_memory0/info/current_kb"); exit(1); } xs = xs_domain_open(); @@ -167,15 +217,8 @@ int main(int argc, char **argv) } if (argc == 3) { /* if not waiting for signal, fork after first info written to xenstore */ - n = pread(fd, buf, sizeof(buf)-1, 0); - if (n < 0) { - perror("pread"); - exit(1); - } - buf[n] = 0; - meminfo_data = parse(buf); - if (meminfo_data) - send_to_qmemman(xs, meminfo_data); + update(xs, meminfo_fd, dom_current_fd); + n = fork(); if (n < 0) { perror("fork"); @@ -187,15 +230,8 @@ int main(int argc, char **argv) } for (;;) { - n = pread(fd, buf, sizeof(buf)-1, 0); - if (n < 0) { - perror("pread"); - exit(1); - } - buf[n] = 0; - meminfo_data = parse(buf); - if (meminfo_data) - send_to_qmemman(xs, meminfo_data); + update(xs, meminfo_fd, dom_current_fd); usleep(delay); } } +