OBJS += hw/vesa.o
OBJS += hw/i8042.o
OBJS += hw/pci-shmem.o
+OBJS += kvm-ipc.o
FLAGS_BFD := $(CFLAGS) -lbfd
has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD))
#include <kvm/builtin-balloon.h>
#include <kvm/parse-options.h>
#include <kvm/kvm.h>
+#include <kvm/kvm-ipc.h>
-static pid_t instance_pid;
+static int instance;
static const char *instance_name;
static u64 inflate;
static u64 deflate;
+struct balloon_cmd {
+ u32 type;
+ u32 len;
+ int amount;
+};
+
static const char * const balloon_usage[] = {
"kvm balloon [-n name] [-p pid] [-i amount] [-d amount]",
NULL
static const struct option balloon_options[] = {
OPT_GROUP("Instance options:"),
OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
- OPT_INTEGER('p', "pid", &instance_pid, "Instance pid"),
OPT_GROUP("Balloon options:"),
OPT_U64('i', "inflate", &inflate, "Amount to inflate"),
OPT_U64('d', "deflate", &deflate, "Amount to deflate"),
int kvm_cmd_balloon(int argc, const char **argv, const char *prefix)
{
- u64 i;
+ struct balloon_cmd cmd;
+ int r;
parse_balloon_options(argc, argv);
kvm_balloon_help();
if (instance_name == NULL &&
- instance_pid == 0)
+ instance == 0)
kvm_balloon_help();
if (instance_name)
- instance_pid = kvm__get_pid_by_instance(instance_name);
+ instance = kvm__get_sock_by_instance(instance_name);
- if (instance_pid <= 0)
+ if (instance <= 0)
die("Failed locating instance");
+ cmd.type = KVM_IPC_BALLOON;
+ cmd.len = sizeof(cmd.amount);
+
if (inflate)
- for (i = 0; i < inflate; i++)
- kill(instance_pid, SIGKVMADDMEM);
+ cmd.amount = inflate;
else if (deflate)
- for (i = 0; i < deflate; i++)
- kill(instance_pid, SIGKVMDELMEM);
+ cmd.amount = -deflate;
else
kvm_balloon_help();
+ r = write(instance, &cmd, sizeof(cmd));
+
+ close(instance);
+
+ if (r < 0)
+ return -1;
+
return 0;
}
#include <kvm/builtin-debug.h>
#include <kvm/kvm.h>
#include <kvm/parse-options.h>
+#include <kvm/kvm-ipc.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
static bool all;
-static pid_t instance_pid;
+static int instance;
static const char *instance_name;
+struct debug_cmd {
+ u32 type;
+ u32 len;
+};
+
static const char * const debug_usage[] = {
- "kvm debug [--all] [-n name] [-p pid]",
+ "kvm debug [--all] [-n name]",
NULL
};
OPT_GROUP("General options:"),
OPT_BOOLEAN('a', "all", &all, "Debug all instances"),
OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
- OPT_INTEGER('p', "pid", &instance_pid, "Instance pid"),
OPT_END()
};
usage_with_options(debug_usage, debug_options);
}
-static int do_debug(const char *name, int pid)
+static int do_debug(const char *name, int sock)
{
- return kill(pid, SIGQUIT);
+ struct debug_cmd cmd = {KVM_IPC_DEBUG, 0};
+ int r;
+
+ r = write(sock, &cmd, sizeof(cmd));
+ if (r < 0)
+ return r;
+
+ return 0;
}
int kvm_cmd_debug(int argc, const char **argv, const char *prefix)
return kvm__enumerate_instances(do_debug);
if (instance_name == NULL &&
- instance_pid == 0)
+ instance == 0)
kvm_debug_help();
if (instance_name)
- instance_pid = kvm__get_pid_by_instance(instance_name);
+ instance = kvm__get_sock_by_instance(instance_name);
- if (instance_pid <= 0)
+ if (instance <= 0)
die("Failed locating instance");
- return kill(instance_pid, SIGQUIT);
+ return do_debug(instance_name, instance);
}
#include <kvm/builtin-list.h>
#include <kvm/kvm.h>
#include <kvm/parse-options.h>
+#include <kvm/kvm-ipc.h>
#include <dirent.h>
#include <stdio.h>
#define PROCESS_NAME "kvm"
+struct pid_cmd {
+ u32 type;
+ u32 len;
+};
+
static bool run;
static bool rootfs;
usage_with_options(list_usage, list_options);
}
-static int print_guest(const char *name, int pid)
+static pid_t get_pid(int sock)
+{
+ struct pid_cmd cmd = {KVM_IPC_PID, 0};
+ int r;
+ pid_t pid;
+
+ r = write(sock, &cmd, sizeof(cmd));
+ if (r < 0)
+ return r;
+
+ r = read(sock, &pid, sizeof(pid));
+ if (r < 0)
+ return r;
+
+ return pid;
+}
+
+static int print_guest(const char *name, int sock)
{
char proc_name[PATH_MAX];
char *comm = NULL;
FILE *fd;
+ pid_t pid = get_pid(sock);
sprintf(proc_name, "/proc/%d/stat", pid);
fd = fopen(proc_name, "r");
if (comm)
free(comm);
- kvm__remove_pidfile(name);
+ kvm__remove_socket(name);
return 0;
}
#include <kvm/builtin-pause.h>
#include <kvm/kvm.h>
#include <kvm/parse-options.h>
+#include <kvm/kvm-ipc.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
+struct pause_cmd {
+ u32 type;
+ u32 len;
+};
+
static bool all;
-static pid_t instance_pid;
+static int instance;
static const char *instance_name;
static const char * const pause_usage[] = {
- "kvm pause [--all] [-n name] [-p pid]",
+ "kvm pause [--all] [-n name]",
NULL
};
OPT_GROUP("General options:"),
OPT_BOOLEAN('a', "all", &all, "Pause all instances"),
OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
- OPT_INTEGER('p', "pid", &instance_pid, "Instance pid"),
OPT_END()
};
usage_with_options(pause_usage, pause_options);
}
-static int do_pause(const char *name, int pid)
+static int do_pause(const char *name, int sock)
{
- return kill(pid, SIGUSR2);
+ struct pause_cmd cmd = {KVM_IPC_PAUSE, 0};
+ int r;
+
+ r = write(sock, &cmd, sizeof(cmd));
+ if (r < 0)
+ return r;
+
+ return 0;
}
int kvm_cmd_pause(int argc, const char **argv, const char *prefix)
return kvm__enumerate_instances(do_pause);
if (instance_name == NULL &&
- instance_pid == 0)
+ instance == 0)
kvm_pause_help();
if (instance_name)
- instance_pid = kvm__get_pid_by_instance(instance_name);
+ instance = kvm__get_sock_by_instance(instance_name);
- if (instance_pid <= 0)
+ if (instance <= 0)
die("Failed locating instance");
- return kill(instance_pid, SIGUSR2);
+ return do_pause(instance_name, instance);
}
#include <kvm/builtin-resume.h>
#include <kvm/kvm.h>
#include <kvm/parse-options.h>
+#include <kvm/kvm-ipc.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
+struct resume_cmd {
+ u32 type;
+ u32 len;
+};
+
static bool all;
-static pid_t instance_pid;
+static int instance;
static const char *instance_name;
static const char * const resume_usage[] = {
- "kvm resume [--all] [-n name] [-p pid]",
+ "kvm resume [--all] [-n name]",
NULL
};
OPT_GROUP("General options:"),
OPT_BOOLEAN('a', "all", &all, "Resume all instances"),
OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
- OPT_INTEGER('p', "pid", &instance_pid, "Instance pid"),
OPT_END()
};
usage_with_options(resume_usage, resume_options);
}
-static int do_resume(const char *name, int pid)
+static int do_resume(const char *name, int sock)
{
- return kill(pid, SIGKVMRESUME);
+ struct resume_cmd cmd = {KVM_IPC_RESUME, 0};
+ int r;
+
+ r = write(sock, &cmd, sizeof(cmd));
+ if (r < 0)
+ return r;
+
+ return 0;
}
int kvm_cmd_resume(int argc, const char **argv, const char *prefix)
return kvm__enumerate_instances(do_resume);
if (instance_name == NULL &&
- instance_pid == 0)
+ instance == 0)
kvm_resume_help();
if (instance_name)
- instance_pid = kvm__get_pid_by_instance(instance_name);
+ instance = kvm__get_sock_by_instance(instance_name);
- if (instance_pid <= 0)
+ if (instance <= 0)
die("Failed locating instance");
- return kill(instance_pid, SIGKVMRESUME);
+ return do_resume(instance_name, instance);
}
#include "kvm/vnc.h"
#include "kvm/guest_compat.h"
#include "kvm/pci-shmem.h"
+#include "kvm/kvm-ipc.h"
#include <linux/types.h>
/* Pause/resume the guest using SIGUSR2 */
static int is_paused;
-static void handle_sigusr2(int sig)
+static void handle_pause(int fd, u32 type, u32 len, u8 *msg)
{
- if (sig == SIGKVMRESUME && is_paused)
+ if (type == KVM_IPC_RESUME && is_paused)
kvm__continue();
- else if (sig == SIGUSR2 && !is_paused)
+ else if (type == KVM_IPC_PAUSE && !is_paused)
kvm__pause();
else
return;
pr_info("Guest %s\n", is_paused ? "paused" : "resumed");
}
-static void handle_sigquit(int sig)
+static void handle_debug(int fd, u32 type, u32 len, u8 *msg)
{
int i;
virtio_console__inject_interrupt(kvm);
}
-static void handle_sigstop(int sig)
+static void handle_stop(int fd, u32 type, u32 len, u8 *msg)
{
kvm_cpu__reboot();
}
void *ret;
signal(SIGALRM, handle_sigalrm);
- signal(SIGQUIT, handle_sigquit);
+ kvm_ipc__register_handler(KVM_IPC_DEBUG, handle_debug);
signal(SIGUSR1, handle_sigusr1);
- signal(SIGUSR2, handle_sigusr2);
- signal(SIGKVMSTOP, handle_sigstop);
- signal(SIGKVMRESUME, handle_sigusr2);
- /* ignore balloon signal by default if not enable balloon optiion */
- signal(SIGKVMADDMEM, SIG_IGN);
- signal(SIGKVMDELMEM, SIG_IGN);
+ kvm_ipc__register_handler(KVM_IPC_PAUSE, handle_pause);
+ kvm_ipc__register_handler(KVM_IPC_RESUME, handle_pause);
+ kvm_ipc__register_handler(KVM_IPC_STOP, handle_stop);
nr_online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
#include <kvm/builtin-stat.h>
#include <kvm/kvm.h>
#include <kvm/parse-options.h>
+#include <kvm/kvm-ipc.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
+struct stat_cmd {
+ u32 type;
+ u32 len;
+};
+
static bool mem;
static bool all;
-static pid_t instance_pid;
+static int instance;
static const char *instance_name;
static const char * const stat_usage[] = {
- "kvm stat [command] [--all] [-n name] [-p pid]",
+ "kvm stat [command] [--all] [-n name]",
NULL
};
OPT_GROUP("Instance options:"),
OPT_BOOLEAN('a', "all", &all, "All instances"),
OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
- OPT_INTEGER('p', "pid", &instance_pid, "Instance pid"),
OPT_END()
};
usage_with_options(stat_usage, stat_options);
}
-static int do_memstat(const char *name, int pid)
+static int do_memstat(const char *name, int sock)
{
+ struct stat_cmd cmd = {KVM_IPC_STAT, 0};
+ int r;
+
printf("Sending memstat command to %s, output should be on the targets' terminal.\n", name);
- return kill(pid, SIGKVMMEMSTAT);
+
+ r = write(sock, &cmd, sizeof(cmd));
+ if (r < 0)
+ return r;
+
+ return 0;
}
int kvm_cmd_stat(int argc, const char **argv, const char *prefix)
return kvm__enumerate_instances(do_memstat);
if (instance_name == NULL &&
- instance_pid == 0)
+ instance == 0)
kvm_stat_help();
if (instance_name)
- instance_pid = kvm__get_pid_by_instance(instance_name);
+ instance = kvm__get_sock_by_instance(instance_name);
- if (instance_pid <= 0)
+ if (instance <= 0)
die("Failed locating instance");
- if (mem) {
- printf("Sending memstat command to designated instance, output should be on the targets' terminal.\n");
-
- return kill(instance_pid, SIGKVMMEMSTAT);
- }
+ if (mem)
+ return do_memstat(instance_name, instance);
return 0;
}
#include <kvm/builtin-stop.h>
#include <kvm/kvm.h>
#include <kvm/parse-options.h>
+#include <kvm/kvm-ipc.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
+struct stop_cmd {
+ u32 type;
+ u32 len;
+};
+
static bool all;
-static pid_t instance_pid;
+static int instance;
static const char *instance_name;
static const char * const stop_usage[] = {
- "kvm stop [--all] [-n name] [-p pid]",
+ "kvm stop [--all] [-n name]",
NULL
};
OPT_GROUP("General options:"),
OPT_BOOLEAN('a', "all", &all, "Stop all instances"),
OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
- OPT_INTEGER('p', "pid", &instance_pid, "Instance pid"),
OPT_END()
};
usage_with_options(stop_usage, stop_options);
}
-static int do_stop(const char *name, int pid)
+static int do_stop(const char *name, int sock)
{
- return kill(pid, SIGKVMSTOP);
+ struct stop_cmd cmd = {KVM_IPC_STOP, 0};
+ int r;
+
+ r = write(sock, &cmd, sizeof(cmd));
+ if (r < 0)
+ return r;
+
+ return 0;
}
int kvm_cmd_stop(int argc, const char **argv, const char *prefix)
return kvm__enumerate_instances(do_stop);
if (instance_name == NULL &&
- instance_pid == 0)
+ instance == 0)
kvm_stop_help();
if (instance_name)
- instance_pid = kvm__get_pid_by_instance(instance_name);
+ instance = kvm__get_sock_by_instance(instance_name);
- if (instance_pid <= 0)
+ if (instance <= 0)
die("Failed locating instance");
- return kill(instance_pid, SIGKVMSTOP);
+ return do_stop(instance_name, instance);
}
--- /dev/null
+#ifndef KVM__IPC_H_
+#define KVM__IPC_H_
+
+#include <linux/types.h>
+
+struct kvm_ipc_msg {
+ u32 type;
+ u32 len;
+ u8 data[];
+};
+
+enum {
+ KVM_IPC_BALLOON = 1,
+ KVM_IPC_DEBUG = 2,
+ KVM_IPC_STAT = 3,
+ KVM_IPC_PAUSE = 4,
+ KVM_IPC_RESUME = 5,
+ KVM_IPC_STOP = 6,
+ KVM_IPC_PID = 7,
+};
+
+int kvm_ipc__register_handler(u32 type, void (*cb)(int fd, u32 type, u32 len, u8 *msg));
+int kvm_ipc__handle(int fd, struct kvm_ipc_msg *msg);
+int kvm_ipc__start(int sock);
+
+#endif
#define SIGKVMEXIT (SIGRTMIN + 0)
#define SIGKVMPAUSE (SIGRTMIN + 1)
-#define SIGKVMADDMEM (SIGRTMIN + 2)
-#define SIGKVMDELMEM (SIGRTMIN + 3)
#define SIGKVMSTOP (SIGRTMIN + 4)
#define SIGKVMRESUME (SIGRTMIN + 5)
-#define SIGKVMMEMSTAT (SIGRTMIN + 6)
#define KVM_PID_FILE_PATH "/.kvm-tools/"
#define HOME_DIR getenv("HOME")
void kvm__pause(void);
void kvm__continue(void);
void kvm__notify_paused(void);
-pid_t kvm__get_pid_by_instance(const char *name);
+int kvm__get_sock_by_instance(const char *name);
int kvm__enumerate_instances(int (*callback)(const char *name, int pid));
-void kvm__remove_pidfile(const char *name);
+void kvm__remove_socket(const char *name);
/*
* Debugging
--- /dev/null
+#include "kvm/kvm-ipc.h"
+#include "kvm/rwsem.h"
+#include "kvm/read-write.h"
+#include "kvm/util.h"
+
+#include <sys/epoll.h>
+#include <sys/un.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#define KVM_IPC_MAX_MSGS 16
+
+static void (*msgs[KVM_IPC_MAX_MSGS])(int fd, u32 type, u32 len, u8 *msg);
+static DECLARE_RWSEM(msgs_rwlock);
+static int epoll_fd, server_fd;
+
+int kvm_ipc__register_handler(u32 type, void (*cb)(int fd, u32 type, u32 len, u8 *msg))
+{
+ if (type >= KVM_IPC_MAX_MSGS)
+ return -ENOSPC;
+
+ down_write(&msgs_rwlock);
+ msgs[type] = cb;
+ up_write(&msgs_rwlock);
+
+ return 0;
+}
+
+int kvm_ipc__handle(int fd, struct kvm_ipc_msg *msg)
+{
+ void (*cb)(int fd, u32 type, u32 len, u8 *msg);
+
+ if (msg->type >= KVM_IPC_MAX_MSGS)
+ return -ENOSPC;
+
+ down_read(&msgs_rwlock);
+ cb = msgs[msg->type];
+ up_read(&msgs_rwlock);
+
+ if (cb == NULL) {
+ pr_warning("No device handles type %u\n", msg->type);
+ return -ENODEV;
+ }
+
+ cb(fd, msg->type, msg->len, msg->data);
+
+ return 0;
+}
+
+static int kvm_ipc__new_conn(int fd)
+{
+ int client;
+ struct epoll_event ev;
+
+ client = accept(fd, NULL, NULL);
+ if (client < 0)
+ return -1;
+
+ ev.events = EPOLLIN | EPOLLRDHUP;
+ ev.data.fd = client;
+ if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client, &ev) < 0) {
+ close(client);
+ return -1;
+ }
+
+ return client;
+}
+
+static void kvm_ipc__close_conn(int fd)
+{
+ epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
+ close(fd);
+}
+
+static void kvm_ipc__new_data(int fd)
+{
+ struct kvm_ipc_msg *msg;
+ u32 n;
+
+ msg = malloc(sizeof(*msg));
+ if (msg == NULL)
+ goto done;
+
+ n = read(fd, msg, sizeof(*msg));
+ if (n != sizeof(*msg))
+ goto done;
+
+ msg = realloc(msg, sizeof(*msg) + msg->len);
+ if (msg == NULL)
+ goto done;
+
+ n = read_in_full(fd, msg->data, msg->len);
+ if (n != msg->len)
+ goto done;
+
+ kvm_ipc__handle(fd, msg);
+
+done:
+ free(msg);
+}
+
+static void *kvm_ipc__thread(void *param)
+{
+ struct epoll_event event;
+
+ for (;;) {
+ int nfds;
+
+ nfds = epoll_wait(epoll_fd, &event, 1, -1);
+ if (nfds > 0) {
+ int fd = event.data.fd;
+
+ if (fd == server_fd) {
+ int client;
+
+ client = kvm_ipc__new_conn(fd);
+ kvm_ipc__new_data(client);
+ } else if (event.events && (EPOLLERR | EPOLLRDHUP | EPOLLHUP)) {
+ kvm_ipc__close_conn(fd);
+ } else {
+ kvm_ipc__new_data(fd);
+ }
+ }
+ }
+
+ return NULL;
+}
+
+int kvm_ipc__start(int sock)
+{
+ pthread_t thread;
+ struct epoll_event ev;
+
+ server_fd = sock;
+
+ epoll_fd = epoll_create(KVM_IPC_MAX_MSGS);
+
+ ev.events = EPOLLIN | EPOLLOUT | EPOLLPRI;
+ ev.data.fd = sock;
+ if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sock, &ev) < 0)
+ die("Failed starting IPC thread");
+
+ if (pthread_create(&thread, NULL, kvm_ipc__thread, NULL) != 0)
+ die("Failed starting IPC thread");
+
+ return 0;
+}
#include "kvm/util.h"
#include "kvm/mutex.h"
#include "kvm/kvm-cpu.h"
+#include "kvm/kvm-ipc.h"
#include <linux/kvm.h>
#include <asm/bootparam.h>
+#include <sys/un.h>
+#include <sys/types.h>
+#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
return kvm;
}
-static void kvm__create_pidfile(struct kvm *kvm)
+static int kvm__create_socket(struct kvm *kvm)
{
- int fd;
- char full_name[PATH_MAX], pid[10];
+ char full_name[PATH_MAX];
+ unsigned int s;
+ struct sockaddr_un local;
+ int len, r;
if (!kvm->name)
- return;
+ return -1;
sprintf(full_name, "%s", kvm__get_dir());
mkdir(full_name, 0777);
- sprintf(full_name, "%s/%s.pid", kvm__get_dir(), kvm->name);
- fd = open(full_name, O_CREAT | O_WRONLY, 0666);
- sprintf(pid, "%u\n", getpid());
- if (write(fd, pid, strlen(pid)) <= 0)
- die("Failed creating PID file");
- close(fd);
+ sprintf(full_name, "%s/%s.sock", kvm__get_dir(), kvm->name);
+ s = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (s < 0)
+ return s;
+ local.sun_family = AF_UNIX;
+ strcpy(local.sun_path, full_name);
+ unlink(local.sun_path);
+ len = strlen(local.sun_path) + sizeof(local.sun_family);
+ r = bind(s, (struct sockaddr *)&local, len);
+ if (r < 0)
+ goto fail;
+
+ r = listen(s, 5);
+ if (r < 0)
+ goto fail;
+
+ return s;
+
+fail:
+ close(s);
+ return -1;
}
-void kvm__remove_pidfile(const char *name)
+void kvm__remove_socket(const char *name)
{
char full_name[PATH_MAX];
- sprintf(full_name, "%s/%s.pid", kvm__get_dir(), name);
+ sprintf(full_name, "%s/%s.sock", kvm__get_dir(), name);
unlink(full_name);
}
-pid_t kvm__get_pid_by_instance(const char *name)
+int kvm__get_sock_by_instance(const char *name)
{
- int fd;
- pid_t pid;
- char pid_str[10], pid_file[PATH_MAX];
+ int s, len, r;
+ char sock_file[PATH_MAX];
+ struct sockaddr_un local;
- sprintf(pid_file, "%s/%s.pid", kvm__get_dir(), name);
- fd = open(pid_file, O_RDONLY);
- if (fd < 0)
- return -1;
+ sprintf(sock_file, "%s/%s.sock", kvm__get_dir(), name);
+ s = socket(AF_UNIX, SOCK_STREAM, 0);
- if (read(fd, pid_str, 10) == 0)
- return -1;
-
- pid = atoi(pid_str);
- if (pid < 0)
- return -1;
+ local.sun_family = AF_UNIX;
+ strcpy(local.sun_path, sock_file);
+ len = strlen(local.sun_path) + sizeof(local.sun_family);
- close(fd);
+ r = connect(s, &local, len);
+ if (r < 0)
+ die("Failed connecting to instance");
- return pid;
+ return s;
}
-int kvm__enumerate_instances(int (*callback)(const char *name, int pid))
+int kvm__enumerate_instances(int (*callback)(const char *name, int fd))
{
char full_name[PATH_MAX];
- int pid;
+ int sock;
DIR *dir;
struct dirent entry, *result;
int ret = 0;
readdir_r(dir, &entry, &result);
if (result == NULL)
break;
- if (entry.d_type == DT_REG) {
- entry.d_name[strlen(entry.d_name)-4] = 0;
- pid = kvm__get_pid_by_instance(entry.d_name);
- ret = callback(entry.d_name, pid);
+ if (entry.d_type == DT_SOCK) {
+ entry.d_name[strlen(entry.d_name)-5] = 0;
+ sock = kvm__get_sock_by_instance(entry.d_name);
+ ret = callback(entry.d_name, sock);
+ close(sock);
if (ret < 0)
break;
}
kvm__stop_timer(kvm);
munmap(kvm->ram_start, kvm->ram_size);
- kvm__remove_pidfile(kvm->name);
+ kvm__remove_socket(kvm->name);
free(kvm);
}
return ret;
}
+static void kvm__pid(int fd, u32 type, u32 len, u8 *msg)
+{
+ pid_t pid = getpid();
+ int r = 0;
+
+ if (type == KVM_IPC_PID)
+ r = write(fd, &pid, sizeof(pid));
+
+ if (r < 0)
+ pr_warning("Failed sending PID");
+}
+
/*
* The following hack should be removed once 'x86: Raise the hard
* VCPU count limit' makes it's way into the mainline.
kvm->name = name;
- kvm__create_pidfile(kvm);
-
+ kvm_ipc__start(kvm__create_socket(kvm));
+ kvm_ipc__register_handler(KVM_IPC_PID, kvm__pid);
return kvm;
}
#include "kvm/threadpool.h"
#include "kvm/guest_compat.h"
#include "kvm/virtio-pci.h"
+#include "kvm/kvm-ipc.h"
#include <linux/virtio_ring.h>
#include <linux/virtio_balloon.h>
return 0;
}
-static int virtio_bln__print_stats(void)
+static void virtio_bln__print_stats(int fd, u32 type, u32 len, u8 *msg)
{
u16 i;
if (virtio_bln__collect_stats() < 0)
- return -EFAULT;
+ return;
printf("\n\n\t*** Guest memory statistics ***\n\n");
for (i = 0; i < bdev.stat_count; i++) {
printf("%llu\n", bdev.stats[i].val);
}
printf("\n");
-
- return 0;
}
-static void handle_sigmem(int sig)
+static void handle_mem(int fd, u32 type, u32 len, u8 *msg)
{
- if (sig == SIGKVMADDMEM) {
- bdev.config.num_pages += 256;
- } else if (sig == SIGKVMDELMEM) {
- if (bdev.config.num_pages < 256)
- return;
+ int mem = *(int *)msg;
- bdev.config.num_pages -= 256;
- } else if (sig == SIGKVMMEMSTAT) {
- virtio_bln__print_stats();
+ if (mem > 0) {
+ bdev.config.num_pages += 256 * mem;
+ } else if (mem < 0) {
+ if (bdev.config.num_pages < (u32)(256 * (-mem)))
+ return;
- return;
+ bdev.config.num_pages += 256 * mem;
}
/* Notify that the configuration space has changed */
void virtio_bln__init(struct kvm *kvm)
{
- signal(SIGKVMADDMEM, handle_sigmem);
- signal(SIGKVMDELMEM, handle_sigmem);
- signal(SIGKVMMEMSTAT, handle_sigmem);
+ kvm_ipc__register_handler(KVM_IPC_BALLOON, handle_mem);
+ kvm_ipc__register_handler(KVM_IPC_STAT, virtio_bln__print_stats);
bdev.stat_waitfd = eventfd(0, 0);
memset(&bdev.config, 0, sizeof(struct virtio_balloon_config));