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.
This commit is contained in:
parent
0cab96ad6d
commit
b8b5cf0a17
@ -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
|
||||
|
@ -5,10 +5,12 @@
|
||||
#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)
|
||||
{
|
||||
@ -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");
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#define QREXEC_AGENT_TRIGGER_PATH "/var/run/qubes/qrexec_agent"
|
||||
#define QREXEC_AGENT_FDPASS_PATH "/var/run/qubes/qrexec_agent_fdpass"
|
||||
#define MEMINFO_WRITER_PIDFILE "/var/run/meminfo-writer.pid"
|
||||
|
||||
enum {
|
||||
MSG_CLIENT_TO_SERVER_EXEC_CMDLINE = 0x100,
|
||||
|
@ -70,6 +70,8 @@ struct _client_info client_info[MAX_FDS];
|
||||
int trigger_fd;
|
||||
int passfd_socket;
|
||||
|
||||
int meminfo_write_started = 0;
|
||||
|
||||
void init()
|
||||
{
|
||||
peer_server_init(REXEC_PORT);
|
||||
@ -81,6 +83,29 @@ void init()
|
||||
open(QREXEC_AGENT_TRIGGER_PATH, O_RDONLY | O_NONBLOCK);
|
||||
}
|
||||
|
||||
void wake_meminfo_writer() {
|
||||
FILE *f;
|
||||
pid_t pid;
|
||||
|
||||
if (meminfo_write_started)
|
||||
/* wake meminfo-writer only once */
|
||||
return;
|
||||
|
||||
f = fopen(MEMINFO_WRITER_PIDFILE, "r");
|
||||
if (f == NULL) {
|
||||
/* no meminfo-writer found, ignoring */
|
||||
return;
|
||||
}
|
||||
if (fscanf(f, "%d", &pid) < 1) {
|
||||
/* no meminfo-writer found, ignoring */
|
||||
return;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
kill(pid, SIGUSR1);
|
||||
meminfo_write_started = 1;
|
||||
}
|
||||
|
||||
void no_colon_in_cmd()
|
||||
{
|
||||
fprintf(stderr,
|
||||
@ -330,9 +355,11 @@ void handle_server_data()
|
||||
handle_connect_existing(s_hdr.client_id, s_hdr.len);
|
||||
break;
|
||||
case MSG_SERVER_TO_AGENT_EXEC_CMDLINE:
|
||||
wake_meminfo_writer();
|
||||
handle_exec(s_hdr.client_id, s_hdr.len);
|
||||
break;
|
||||
case MSG_SERVER_TO_AGENT_JUST_EXEC:
|
||||
wake_meminfo_writer();
|
||||
handle_just_exec(s_hdr.client_id, s_hdr.len);
|
||||
break;
|
||||
case MSG_SERVER_TO_AGENT_INPUT:
|
||||
|
Loading…
Reference in New Issue
Block a user