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 <[email protected]>
---
 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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to