kvm__set_dir() called in main() and kvm__get_dir() rely on $HOME. But in some environments (such as starting lkvm through systemd-run), $HOME is undefined. This causes bind() to use a socket path containing "(null)" and this fails. The current code does not check errors returned by realpath(). Symptoms: | bind: No such file or directory | Error: Failed adding socket to epoll | Warning: Failed init: kvm_ipc__init | | Fatal: Initialisation failed This bug was first reported on https://github.com/coreos/rkt/issues/1393 Instead of using "$HOME/.lkvm/" (i.e. "/root/.lkvm/"), this patch uses "/var/lib/lkvm/". This also improve the error reporting by printing the socket filename. Signed-off-by: Alban Crequy <alban.crequy@xxxxxxxxx> --- include/kvm/kvm.h | 5 ++--- kvm-ipc.c | 1 + kvm.c | 26 ++++++++------------------ main.c | 6 +++++- 4 files changed, 16 insertions(+), 22 deletions(-) diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h index 37155db..368f256 100644 --- a/include/kvm/kvm.h +++ b/include/kvm/kvm.h @@ -16,8 +16,7 @@ #define SIGKVMEXIT (SIGRTMIN + 0) #define SIGKVMPAUSE (SIGRTMIN + 1) -#define KVM_PID_FILE_PATH "/.lkvm/" -#define HOME_DIR getenv("HOME") +#define KVM_PID_FILE_PATH "/var/lib/lkvm/" #define KVM_BINARY_NAME "lkvm" #ifndef PAGE_SIZE @@ -70,7 +69,7 @@ struct kvm { int vm_state; }; -void kvm__set_dir(const char *fmt, ...); +int kvm__set_dir(void); const char *kvm__get_dir(void); int kvm__init(struct kvm *kvm); diff --git a/kvm-ipc.c b/kvm-ipc.c index 857b0dc..d94456c 100644 --- a/kvm-ipc.c +++ b/kvm-ipc.c @@ -60,6 +60,7 @@ static int kvm__create_socket(struct kvm *kvm) r = bind(s, (struct sockaddr *)&local, len); if (r < 0) { perror("bind"); + pr_err("Cannot bind on %s", full_name); goto fail; } diff --git a/kvm.c b/kvm.c index 10ed230..482f47b 100644 --- a/kvm.c +++ b/kvm.c @@ -63,31 +63,21 @@ extern struct kvm_ext kvm_req_ext[]; static char kvm_dir[PATH_MAX]; -static int set_dir(const char *fmt, va_list args) +int kvm__set_dir(void) { - char tmp[PATH_MAX]; + int err; - vsnprintf(tmp, sizeof(tmp), fmt, args); - - mkdir(tmp, 0777); - - if (!realpath(tmp, kvm_dir)) - return -errno; + err = mkdir(KVM_PID_FILE_PATH, 0700); + if (err != 0 && errno != EEXIST) { + perror("mkdir " KVM_PID_FILE_PATH); + return 1; + } - strcat(kvm_dir, "/"); + snprintf(kvm_dir, sizeof(kvm_dir), KVM_PID_FILE_PATH); return 0; } -void kvm__set_dir(const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - set_dir(fmt, args); - va_end(args); -} - const char *kvm__get_dir(void) { return kvm_dir; diff --git a/main.c b/main.c index 05bc82c..22cc4e2 100644 --- a/main.c +++ b/main.c @@ -13,7 +13,11 @@ static int handle_kvm_command(int argc, char **argv) int main(int argc, char *argv[]) { - kvm__set_dir("%s/%s", HOME_DIR, KVM_PID_FILE_PATH); + int ret; + + ret = kvm__set_dir(); + if (ret != 0) + return ret; return handle_kvm_command(argc - 1, &argv[1]); } -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html