Move meminfo-writer to linux-utils repo

It is common for both dom0 and VM, and also quite linux-specific
(other OSes will need other implementation). So move to linux-specific
repo (not dom0-specific).
This commit is contained in:
Marek Marczykowski-Górecki 2014-01-05 05:36:50 +01:00
parent 994e963ab8
commit bba989e0a6
4 changed files with 1 additions and 196 deletions

View File

@ -1,12 +0,0 @@
[Unit]
Description=Qubes memory information reporter
After=qubes-core.service
[Service]
Type=simple
ExecStart=/usr/lib/qubes/meminfo-writer 30000 100000
StandardOutput=syslog
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target

View File

@ -1,7 +1,4 @@
all: meminfo-writer
meminfo-writer: meminfo-writer.o
$(CC) -g -o meminfo-writer meminfo-writer.o -lxenstore
all:
clean:
rm -f *.pyo

View File

@ -1,176 +0,0 @@
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <xs.h>
#include <syslog.h>
#include <string.h>
#include <signal.h>
unsigned long prev_used_mem;
int used_mem_change_threshold;
int delay;
int usr1_received;
char *parse(char *buf)
{
char *ptr = buf;
char name[256];
static char outbuf[4096];
int val;
int len;
int MemTotal = 0, MemFree = 0, Buffers = 0, Cached = 0, SwapTotal =
0, SwapFree = 0;
unsigned long long key;
long used_mem, used_mem_diff;
int nitems = 0;
while (nitems != 6) {
sscanf(ptr, "%s %d kB\n%n", name, &val, &len);
key = *(unsigned long long *) ptr;
if (key == *(unsigned long long *) "MemTotal:") {
MemTotal = val;
nitems++;
} else if (key == *(unsigned long long *) "MemFree:") {
MemFree = val;
nitems++;
} else if (key == *(unsigned long long *) "Buffers:") {
Buffers = val;
nitems++;
} else if (key == *(unsigned long long *) "Cached: ") {
Cached = val;
nitems++;
} else if (key == *(unsigned long long *) "SwapTotal:") {
SwapTotal = val;
nitems++;
} else if (key == *(unsigned long long *) "SwapFree:") {
SwapFree = val;
nitems++;
}
ptr += len;
}
used_mem =
MemTotal - Buffers - Cached - MemFree + SwapTotal - SwapFree;
if (used_mem < 0)
return NULL;
used_mem_diff = used_mem - prev_used_mem;
if (used_mem_diff < 0)
used_mem_diff = -used_mem_diff;
if (used_mem_diff > used_mem_change_threshold
|| (used_mem > prev_used_mem && used_mem * 13 / 10 > MemTotal
&& used_mem_diff > used_mem_change_threshold/2)) {
prev_used_mem = used_mem;
sprintf(outbuf,
"MemTotal: %d kB\nMemFree: %d kB\nBuffers: %d kB\nCached: %d kB\n"
"SwapTotal: %d kB\nSwapFree: %d kB\n", MemTotal,
MemFree, Buffers, Cached, SwapTotal, SwapFree);
return outbuf;
}
return NULL;
}
void usage()
{
fprintf(stderr,
"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);
}
void send_to_qmemman(struct xs_handle *xs, char *data)
{
if (!xs_write(xs, XBT_NULL, "memory/meminfo", data, strlen(data))) {
syslog(LOG_DAEMON | LOG_ERR, "error writing xenstore ?");
exit(1);
}
}
void usr1_handler(int sig) {
usr1_received = 1;
}
int main(int argc, char **argv)
{
char buf[4096];
int n;
char *meminfo_data;
int fd;
struct xs_handle *xs;
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");
exit(1);
}
xs = xs_domain_open();
if (!xs) {
perror("xs_domain_open");
exit(1);
}
if (argc == 3) {
/* if not waiting for signal, fork after first info written to xenstore */
n = pread(fd, buf, sizeof(buf), 0);
buf[n] = 0;
meminfo_data = parse(buf);
if (meminfo_data)
send_to_qmemman(xs, meminfo_data);
if (fork() > 0)
exit(0);
}
for (;;) {
n = pread(fd, buf, sizeof(buf), 0);
buf[n] = 0;
meminfo_data = parse(buf);
if (meminfo_data)
send_to_qmemman(xs, meminfo_data);
usleep(delay);
}
}

View File

@ -88,7 +88,6 @@ mkdir -p $RPM_BUILD_ROOT/usr/lib/systemd/system
cp linux/systemd/qubes-block-cleaner.service $RPM_BUILD_ROOT%{_unitdir}
cp linux/systemd/qubes-core.service $RPM_BUILD_ROOT%{_unitdir}
cp linux/systemd/qubes-setupdvm.service $RPM_BUILD_ROOT%{_unitdir}
cp linux/systemd/qubes-meminfo-writer.service $RPM_BUILD_ROOT%{_unitdir}
cp linux/systemd/qubes-netvm.service $RPM_BUILD_ROOT%{_unitdir}
cp linux/systemd/qubes-qmemman.service $RPM_BUILD_ROOT%{_unitdir}
cp linux/systemd/qubes-vm@.service $RPM_BUILD_ROOT%{_unitdir}
@ -132,7 +131,6 @@ cp linux/aux-tools/startup-dvm.sh $RPM_BUILD_ROOT/usr/lib/qubes
cp linux/aux-tools/startup-misc.sh $RPM_BUILD_ROOT/usr/lib/qubes
cp linux/aux-tools/prepare-volatile-img.sh $RPM_BUILD_ROOT/usr/lib/qubes
cp qmemman/server.py $RPM_BUILD_ROOT/usr/lib/qubes/qmemman_daemon.py
cp qmemman/meminfo-writer $RPM_BUILD_ROOT/usr/lib/qubes/
cp qubes-rpc/qubes-notify-tools $RPM_BUILD_ROOT/usr/lib/qubes/
cp qubes-rpc/qubes-notify-updates $RPM_BUILD_ROOT/usr/lib/qubes/
cp linux/aux-tools/vusb-ctl.py $RPM_BUILD_ROOT/usr/lib/qubes/
@ -287,7 +285,6 @@ fi
/usr/lib/qubes/unbind-pci-device.sh
/usr/lib/qubes/cleanup-dispvms
/usr/lib/qubes/qmemman_daemon.py*
/usr/lib/qubes/meminfo-writer
/usr/lib/qubes/qfile-daemon-dvm*
/usr/lib/qubes/qubes-notify-tools
/usr/lib/qubes/qubes-notify-updates
@ -302,7 +299,6 @@ fi
%{_unitdir}/qubes-block-cleaner.service
%{_unitdir}/qubes-core.service
%{_unitdir}/qubes-setupdvm.service
%{_unitdir}/qubes-meminfo-writer.service
%{_unitdir}/qubes-netvm.service
%{_unitdir}/qubes-qmemman.service
%{_unitdir}/qubes-vm@.service