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-changelog

[Xen-changelog] [xen-unstable] blktap: Automatically start tapdisk-ioemu

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] blktap: Automatically start tapdisk-ioemu on demand
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 22 Apr 2008 07:10:54 -0700
Delivery-date: Tue, 22 Apr 2008 07:36:52 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1208871573 -3600
# Node ID 451ae3b8e5c82a9954f33c65bd4ba11337287e8d
# Parent  6271ba3bb4b63b10b94301a6e22f421b9b36dfa3
blktap: Automatically start tapdisk-ioemu on demand

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>
---
 tools/blktap/drivers/blktapctrl.c       |   83 +++++++++++++++++++++++++-------
 tools/blktap/drivers/tapdisk.h          |    2 
 tools/ioemu/Makefile                    |    2 
 tools/ioemu/hw/xen_blktap.c             |   45 -----------------
 tools/ioemu/tapdisk-ioemu.c             |   14 +++++
 tools/ioemu/vl.c                        |    8 ---
 tools/python/xen/xend/XendDomainInfo.py |    3 +
 tools/python/xen/xend/image.py          |   30 +++++++++++
 8 files changed, 118 insertions(+), 69 deletions(-)

diff -r 6271ba3bb4b6 -r 451ae3b8e5c8 tools/blktap/drivers/blktapctrl.c
--- a/tools/blktap/drivers/blktapctrl.c Tue Apr 22 14:34:16 2008 +0100
+++ b/tools/blktap/drivers/blktapctrl.c Tue Apr 22 14:39:33 2008 +0100
@@ -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 6271ba3bb4b6 -r 451ae3b8e5c8 tools/blktap/drivers/tapdisk.h
--- a/tools/blktap/drivers/tapdisk.h    Tue Apr 22 14:34:16 2008 +0100
+++ b/tools/blktap/drivers/tapdisk.h    Tue Apr 22 14:39:33 2008 +0100
@@ -235,7 +235,7 @@ static disk_info_t ioemu_disk = {
        DISK_TYPE_IOEMU,
        "ioemu disk",
        "ioemu",
-       0,
+       1,
 #ifdef TAPDISK
        NULL
 #endif
diff -r 6271ba3bb4b6 -r 451ae3b8e5c8 tools/ioemu/Makefile
--- a/tools/ioemu/Makefile      Tue Apr 22 14:34:16 2008 +0100
+++ b/tools/ioemu/Makefile      Tue Apr 22 14:39:33 2008 +0100
@@ -87,7 +87,7 @@ endif
 
 install: all $(if $(BUILD_DOCS),install-doc)
        mkdir -p "$(DESTDIR)$(bindir)"
-       $(INSTALL) -m 755 $(TOOLS) "$(DESTDIR)$(prefix)/sbin"
+       $(INSTALL) -m 755 $(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 6271ba3bb4b6 -r 451ae3b8e5c8 tools/ioemu/hw/xen_blktap.c
--- a/tools/ioemu/hw/xen_blktap.c       Tue Apr 22 14:34:16 2008 +0100
+++ b/tools/ioemu/hw/xen_blktap.c       Tue Apr 22 14:39:33 2008 +0100
@@ -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 6271ba3bb4b6 -r 451ae3b8e5c8 tools/ioemu/tapdisk-ioemu.c
--- a/tools/ioemu/tapdisk-ioemu.c       Tue Apr 22 14:34:16 2008 +0100
+++ b/tools/ioemu/tapdisk-ioemu.c       Tue Apr 22 14:39:33 2008 +0100
@@ -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 6271ba3bb4b6 -r 451ae3b8e5c8 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Tue Apr 22 14:34:16 2008 +0100
+++ b/tools/ioemu/vl.c  Tue Apr 22 14:39:33 2008 +0100
@@ -6273,12 +6273,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)
@@ -7976,7 +7970,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 6271ba3bb4b6 -r 451ae3b8e5c8 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Tue Apr 22 14:34:16 2008 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py   Tue Apr 22 14:39:33 2008 +0100
@@ -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 6271ba3bb4b6 -r 451ae3b8e5c8 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Tue Apr 22 14:34:16 2008 +0100
+++ b/tools/python/xen/xend/image.py    Tue Apr 22 14:39:33 2008 +0100
@@ -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-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>