[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 08 of 15 v4] blktap3/libblktapctl: Introduce tapdisk spawn functionality



This patch imports file control/tap-ctl-spawn.c from the existing blktap2
implementation, with most changes coming from blktap2 living in github.
Function tap-ctl-spawn is used for spawning a new tapdisk process in order to
serve a new virtual block device.

Signed-off-by: Thanos Makatos <thanos.makatos@xxxxxxxxxx>

---
Changed since v2:
  * Use "tapdisk3" instead of "tapdisk2" in getenv and printf's.
  * Define tapdisk binary name and tapdisk binary location inside the source
    file as it doesn't need to be configurable.

Changed since v3:
  * Don't specify the path to the tapdisk binary, just use whatever is
    available in $PATH.
  * Print error message instead of error code in tap_ctl_wait.

diff --git a/tools/blktap2/control/tap-ctl-spawn.c 
b/tools/blktap3/control/tap-ctl-spawn.c
copy from tools/blktap2/control/tap-ctl-spawn.c
copy to tools/blktap3/control/tap-ctl-spawn.c
--- a/tools/blktap2/control/tap-ctl-spawn.c
+++ b/tools/blktap3/control/tap-ctl-spawn.c
@@ -31,15 +31,18 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
+#include <signal.h>
 #include <sys/wait.h>
 
 #include "tap-ctl.h"
-#include "blktap2.h"
+#include "blktap3.h"
+
+#define TAPDISK_EXEC "tapdisk"
 
 static pid_t
 __tap_ctl_spawn(int *readfd)
 {
-       int err, child, channel[2];
+       int child, channel[2];
        char *tapdisk;
 
        if (pipe(channel)) {
@@ -71,14 +74,17 @@ static pid_t
        close(channel[0]);
        close(channel[1]);
 
-       tapdisk = getenv("TAPDISK2");
+       tapdisk = getenv("TAPDISK");
        if (!tapdisk)
-               tapdisk = "tapdisk2";
+               tapdisk = getenv("TAPDISK3"); /* FIXME */
 
-       execlp(tapdisk, tapdisk, NULL);
+       if (tapdisk) {
+               execlp(tapdisk, tapdisk, NULL);
+               exit(errno);
+       }
 
-       EPRINTF("exec failed\n");
-       exit(1);
+       execlp(TAPDISK_EXEC, TAPDISK_EXEC, NULL);
+       exit(errno);
 }
 
 pid_t
@@ -90,7 +96,7 @@ tap_ctl_get_pid(const int id)
        memset(&message, 0, sizeof(message));
        message.type = TAPDISK_MESSAGE_PID;
 
-       err = tap_ctl_connect_send_and_receive(id, &message, 2);
+       err = tap_ctl_connect_send_and_receive(id, &message, NULL);
        if (err)
                return err;
 
@@ -105,24 +111,30 @@ tap_ctl_wait(pid_t child)
 
        pid = waitpid(child, &status, 0);
        if (pid < 0) {
-               EPRINTF("wait(%d) failed, err %d\n", child, errno);
+               EPRINTF("wait(%d) failed: %s\n", child, strerror(errno));
                return -errno;
        }
 
        if (WIFEXITED(status)) {
                int code = WEXITSTATUS(status);
                if (code)
-                       EPRINTF("tapdisk2[%d] failed, status %d\n", child, 
code);
+                       EPRINTF("tapdisk3[%d] failed: %s\n", child, 
strerror(code));
                return -code;
        }
 
        if (WIFSIGNALED(status)) {
                int signo = WTERMSIG(status);
-               EPRINTF("tapdisk2[%d] killed by signal %d\n", child, signo);
+               EPRINTF("tapdisk3[%d] killed by signal %d\n", child, signo);
+               if (signo == SIGUSR1)
+                       /* NB. there's a race between tapdisk's
+                        * sigaction init and xen-bugtool shooting
+                        * debug signals. If killed by something as
+                        * innocuous as USR1, then retry. */
+                       return -EAGAIN;
                return -EINTR;
        }
 
-       EPRINTF("tapdisk2[%d]: unexpected status %#x\n", child, status);
+       EPRINTF("tapdisk3[%d]: unexpected status %#x\n", child, status);
        return -EAGAIN;
 }
 
@@ -139,8 +151,8 @@ tap_ctl_get_child_id(int readfd)
        }
 
        errno = 0;
-       if (fscanf(f, BLKTAP2_CONTROL_DIR"/"
-                  BLKTAP2_CONTROL_SOCKET"%d", &id) != 1) {
+       if (fscanf(f, BLKTAP3_CONTROL_DIR "/"
+                          BLKTAP3_CONTROL_SOCKET "%d", &id) != 1) {
                errno = (errno ? : EINVAL);
                EPRINTF("parsing id failed: %d\n", errno);
                id = -1;
@@ -158,13 +170,17 @@ tap_ctl_spawn(void)
 
        readfd = -1;
 
+  again:
        child = __tap_ctl_spawn(&readfd);
        if (child < 0)
                return child;
 
        err = tap_ctl_wait(child);
-       if (err)
+       if (err) {
+               if (err == -EAGAIN)
+                       goto again;
                return err;
+       }
 
        id = tap_ctl_get_child_id(readfd);
        if (id < 0)

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.