WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] blktap: Automatically start tapdisk-ioemu on demand

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] blktap: Automatically start tapdisk-ioemu on demand
From: Kevin Wolf <kwolf@xxxxxxx>
Date: Tue, 22 Apr 2008 15:24:48 +0200
Delivery-date: Tue, 22 Apr 2008 06:30:32 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Thunderbird 1.5.0.8 (X11/20060911)
When a domain wants to use a tap:ioemu disk but has no device model,
start a tapdisk-ioemu instance as provider. Also, move the creation and
removal of communication pipes to xend so that qemu-dm doesn't need the
unwanted SIGHUP handler anymore.

Signed-off-by: Kevin Wolf <kwolf@xxxxxxx>

diff -r 08e010c3f251 tools/blktap/drivers/blktapctrl.c
--- a/tools/blktap/drivers/blktapctrl.c Tue Apr 15 16:39:00 2008 +0100
+++ b/tools/blktap/drivers/blktapctrl.c Tue Apr 22 15:20:09 2008 +0200
@@ -474,9 +474,8 @@ static int read_msg(int fd, int msgtype,
 
 }
 
-int launch_tapdisk(char *wrctldev, char *rdctldev)
-{
-       char *argv[] = { "tapdisk", wrctldev, rdctldev, NULL };
+static int launch_tapdisk_provider(char **argv)
+{
        pid_t child;
        
        if ((child = fork()) < 0)
@@ -490,7 +489,9 @@ int launch_tapdisk(char *wrctldev, char 
                            i != STDERR_FILENO)
                                close(i);
 
-               execvp("tapdisk", argv);
+               execvp(argv[0], argv);
+               DPRINTF("execvp failed: %d (%s)\n", errno, strerror(errno));
+               DPRINTF("PATH = %s\n", getenv("PATH"));
                _exit(1);
        } else {
                pid_t got;
@@ -498,28 +499,78 @@ int launch_tapdisk(char *wrctldev, char 
                        got = waitpid(child, NULL, 0);
                } while (got != child);
        }
+       return child;
+}
+
+static int launch_tapdisk(char *wrctldev, char *rdctldev)
+{
+       char *argv[] = { "tapdisk", wrctldev, rdctldev, NULL };
+
+       if (launch_tapdisk_provider(argv) < 0)
+               return -1;
+
        return 0;
 }
 
-/* Connect to qemu-dm */
-static int connect_qemu(blkif_t *blkif)
+static int launch_tapdisk_ioemu(void)
+{
+       char *argv[] = { "tapdisk-ioemu", NULL };
+       return launch_tapdisk_provider(argv);
+}
+
+/* 
+ * Connect to an ioemu based disk provider (qemu-dm or tapdisk-ioemu)
+ *
+ * If the domain has a device model, connect to qemu-dm through the
+ * domain specific pipe. Otherwise use a single tapdisk-ioemu instance
+ * which is represented by domid 0 and provides access for Dom0 and
+ * all DomUs without device model.
+ */
+static int connect_qemu(blkif_t *blkif, int domid)
 {
        char *rdctldev, *wrctldev;
-       
-       if (asprintf(&rdctldev, BLKTAP_CTRL_DIR "/qemu-read-%d", 
-                       blkif->domid) < 0)
-               return -1;
-
-       if (asprintf(&wrctldev, BLKTAP_CTRL_DIR "/qemu-write-%d", 
-                       blkif->domid) < 0) {
+
+       static int tapdisk_ioemu_pid = 0;
+       static int dom0_readfd = 0;
+       static int dom0_writefd = 0;
+       
+       if (asprintf(&rdctldev, BLKTAP_CTRL_DIR "/qemu-read-%d", domid) < 0)
+               return -1;
+
+       if (asprintf(&wrctldev, BLKTAP_CTRL_DIR "/qemu-write-%d", domid) < 0) {
                free(rdctldev);
                return -1;
        }
 
        DPRINTF("Using qemu blktap pipe: %s\n", rdctldev);
        
-       blkif->fds[READ] = open_ctrl_socket(wrctldev);
-       blkif->fds[WRITE] = open_ctrl_socket(rdctldev);
+       if (domid == 0) {
+               /*
+                * tapdisk-ioemu exits as soon as the last image is 
+                * disconnected. Check if it is still running.
+                */
+               if (tapdisk_ioemu_pid == 0 || kill(tapdisk_ioemu_pid, 0)) {
+                       /* No device model and tapdisk-ioemu doesn't run yet */
+                       DPRINTF("Launching tapdisk-ioemu\n");
+                       tapdisk_ioemu_pid = launch_tapdisk_ioemu();
+                       
+                       dom0_readfd = open_ctrl_socket(wrctldev);
+                       dom0_writefd = open_ctrl_socket(rdctldev);
+               }
+
+               DPRINTF("Using tapdisk-ioemu connection\n");
+               blkif->fds[READ] = dom0_readfd;
+               blkif->fds[WRITE] = dom0_writefd;
+       } else if (access(rdctldev, R_OK | W_OK) == 0) {
+               /* Use existing pipe to the device model */
+               DPRINTF("Using qemu-dm connection\n");
+               blkif->fds[READ] = open_ctrl_socket(wrctldev);
+               blkif->fds[WRITE] = open_ctrl_socket(rdctldev);
+       } else {
+               /* No device model => try with tapdisk-ioemu */
+               DPRINTF("No device model\n");
+               connect_qemu(blkif, 0);
+       }
        
        free(rdctldev);
        free(wrctldev);
@@ -599,7 +650,7 @@ int blktapctrl_new_blkif(blkif_t *blkif)
 
                if (!exist) {
                        if (type == DISK_TYPE_IOEMU) {
-                               if (connect_qemu(blkif))
+                               if (connect_qemu(blkif, blkif->domid))
                                        goto fail;
                        } else {
                                if (connect_tapdisk(blkif, minor))
diff -r 08e010c3f251 tools/blktap/drivers/tapdisk.h
--- a/tools/blktap/drivers/tapdisk.h    Tue Apr 15 16:39:00 2008 +0100
+++ b/tools/blktap/drivers/tapdisk.h    Tue Apr 22 15:20:09 2008 +0200
@@ -235,7 +235,7 @@ static disk_info_t ioemu_disk = {
        DISK_TYPE_IOEMU,
        "ioemu disk",
        "ioemu",
-       0,
+       1,
 #ifdef TAPDISK
        NULL
 #endif
diff -r 08e010c3f251 tools/ioemu/Makefile
--- a/tools/ioemu/Makefile      Tue Apr 15 16:39:00 2008 +0100
+++ b/tools/ioemu/Makefile      Tue Apr 22 15:20:09 2008 +0200
@@ -87,7 +87,7 @@ endif
 
 install: all $(if $(BUILD_DOCS),install-doc)
        mkdir -p "$(DESTDIR)$(bindir)"
-       $(INSTALL) -m 755 -s $(TOOLS) "$(DESTDIR)$(prefix)/sbin"
+       $(INSTALL) -m 755 -s $(TOOLS) "$(DESTDIR)$(SBINDIR)"
 #      mkdir -p "$(DESTDIR)$(datadir)"
 #      for x in bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \
 #              video.x openbios-sparc32 linux_boot.bin pxe-ne2k_pci.bin \
diff -r 08e010c3f251 tools/ioemu/hw/xen_blktap.c
--- a/tools/ioemu/hw/xen_blktap.c       Tue Apr 15 16:39:00 2008 +0100
+++ b/tools/ioemu/hw/xen_blktap.c       Tue Apr 22 15:20:09 2008 +0200
@@ -581,17 +581,13 @@ static void handle_blktap_ctrlmsg(void* 
  */
 static int open_ctrl_socket(char *devname)
 {
-       int ret;
        int ipc_fd;
 
        if (mkdir(BLKTAP_CTRL_DIR, 0755) == 0)
                DPRINTF("Created %s directory\n", BLKTAP_CTRL_DIR);
 
-       ret = mkfifo(devname,S_IRWXU|S_IRWXG|S_IRWXO);
-       if ( (ret != 0) && (errno != EEXIST) ) {
-               DPRINTF("ERROR: pipe failed (%d)\n", errno);
+       if (access(devname, R_OK | W_OK))
                return -1;
-       }
 
        ipc_fd = open(devname,O_RDWR|O_NONBLOCK);
 
@@ -601,42 +597,6 @@ static int open_ctrl_socket(char *devnam
        }
 
        return ipc_fd;
-}
-
-/**
- * Unmaps all disks and closes their pipes
- */
-void shutdown_blktap(void)
-{
-       fd_list_entry_t *ptr;
-       struct td_state *s;
-       char *devname;
-
-       DPRINTF("Shutdown blktap\n");
-
-       /* Unmap all disks */
-       ptr = fd_start;
-       while (ptr != NULL) {
-               s = ptr->s;
-               unmap_disk(s);
-               close(ptr->tap_fd);
-               ptr = ptr->next;
-       }
-
-       /* Delete control pipes */
-       if (asprintf(&devname, BLKTAP_CTRL_DIR "/qemu-read-%d", domid) >= 0) {
-               DPRINTF("Delete %s\n", devname);
-               if (unlink(devname))
-                       DPRINTF("Could not delete: %s\n", strerror(errno));
-               free(devname);
-       }
-       
-       if (asprintf(&devname, BLKTAP_CTRL_DIR "/qemu-write-%d", domid) >= 0) { 
-               DPRINTF("Delete %s\n", devname);
-               if (unlink(devname))
-                       DPRINTF("Could not delete: %s\n", strerror(errno));
-               free(devname);
-       }
 }
 
 /**
@@ -679,8 +639,5 @@ int init_blktap(void)
        /* Attach a handler to the read pipe (called from qemu main loop) */
        qemu_set_fd_handler2(read_fd, NULL, &handle_blktap_ctrlmsg, NULL, NULL);
 
-       /* Register handler to clean up when the domain is destroyed */
-       atexit(&shutdown_blktap);
-
        return 0;
 }
diff -r 08e010c3f251 tools/ioemu/tapdisk-ioemu.c
--- a/tools/ioemu/tapdisk-ioemu.c       Tue Apr 15 16:39:00 2008 +0100
+++ b/tools/ioemu/tapdisk-ioemu.c       Tue Apr 22 15:20:09 2008 +0200
@@ -4,6 +4,7 @@
 #include <string.h>
 #include <stdint.h>
 #include <signal.h>
+#include <unistd.h>
 #include <sys/time.h>
 
 #include <assert.h>
@@ -15,6 +16,8 @@ extern void bdrv_init(void);
 
 extern void *qemu_mallocz(size_t size);
 extern void qemu_free(void *ptr);
+
+extern void *fd_start;
 
 int domid = 0;
 FILE* logfile;
@@ -95,12 +98,17 @@ int main(void)
     int max_fd;
     fd_set rfds;
     struct timeval tv;
+    void *old_fd_start = NULL;
 
     logfile = stderr;
     
     bdrv_init();
     qemu_aio_init();
     init_blktap();
+
+    /* Daemonize */
+    if (fork() != 0)
+       exit(0);
    
     /* 
      * Main loop: Pass events to the corrsponding handlers and check for
@@ -137,6 +145,12 @@ int main(void)
             } else 
                 pioh = &ioh->next;
         }
+
+        /* Exit when the last image has been closed */
+        if (old_fd_start != NULL && fd_start == NULL)
+            exit(0);
+
+        old_fd_start = fd_start;
     }
     return 0;
 }
diff -r 08e010c3f251 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Tue Apr 15 16:39:00 2008 +0100
+++ b/tools/ioemu/vl.c  Tue Apr 22 15:20:09 2008 +0200
@@ -6276,12 +6276,6 @@ void qemu_system_powerdown_request(void)
     powerdown_requested = 1;
     if (cpu_single_env)
         cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
-}
-
-static void qemu_sighup_handler(int signal)
-{
-    fprintf(stderr, "Received SIGHUP, terminating.\n");
-    exit(0);
 }
 
 void main_loop_wait(int timeout)
@@ -7979,7 +7973,7 @@ int main(int argc, char **argv)
 
 #ifndef CONFIG_STUBDOM
     /* Unblock SIGTERM and SIGHUP, which may have been blocked by the caller */
-    signal(SIGHUP, qemu_sighup_handler);
+    signal(SIGHUP, SIG_DFL);
     sigemptyset(&set);
     sigaddset(&set, SIGTERM);
     sigaddset(&set, SIGHUP);
diff -r 08e010c3f251 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Tue Apr 15 16:39:00 2008 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py   Tue Apr 22 15:20:09 2008 +0200
@@ -1837,6 +1837,9 @@ class XendDomainInfo:
 
         @raise: VmError for invalid devices
         """
+        if self.image:
+            self.image.prepareEnvironment()
+
         ordered_refs = self.info.ordered_device_refs()
         for dev_uuid in ordered_refs:
             devclass, config = self.info['devices'][dev_uuid]
diff -r 08e010c3f251 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Tue Apr 15 16:39:00 2008 +0100
+++ b/tools/python/xen/xend/image.py    Tue Apr 22 15:20:09 2008 +0200
@@ -184,6 +184,30 @@ class ImageHandler:
     def buildDomain(self):
         """Build the domain. Define in subclass."""
         raise NotImplementedError()
+
+    def prepareEnvironment(self):
+        """Prepare the environment for the execution of the domain. This
+        method is called before any devices are set up."""
+        
+        domid = self.vm.getDomid()
+       
+        # Delete left-over pipes
+        try:
+            os.unlink('/var/run/tap/qemu-read-%d' % domid)
+            os.unlink('/var/run/tap/qemu-write-%d' % domid)
+        except:
+            pass
+
+        # No device model, don't create pipes
+        if self.device_model is None:
+            return
+
+        # If we use a device model, the pipes for communication between
+        # blktapctrl and ioemu must be present before the devices are 
+        # created (blktapctrl must access them for new block devices)
+        os.mkfifo('/var/run/tap/qemu-read-%d' % domid, 0600)
+        os.mkfifo('/var/run/tap/qemu-write-%d' % domid, 0600)
+        
 
     # Return a list of cmd line args to the device models based on the
     # xm config file
@@ -411,6 +435,12 @@ class ImageHandler:
             self.pid = None
             state = xstransact.Remove("/local/domain/0/device-model/%i"
                                       % self.vm.getDomid())
+            
+            try:
+                os.unlink('/var/run/tap/qemu-read-%d' % self.vm.getDomid())
+                os.unlink('/var/run/tap/qemu-write-%d' % self.vm.getDomid())
+            except:
+                pass
 
 
 class LinuxImageHandler(ImageHandler):
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] blktap: Automatically start tapdisk-ioemu on demand, Kevin Wolf <=