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

[Xen-devel] [PATCH 14/17] block-remus: switch to unprotected mode before closing



If the user wants to stop tapdisk2, he will do
the following thing:
1. close the image
2. detach from blktap device

If there is some pending I/O request, close will
fail. But the I/O request is pended in remus until
the connection is established. Introduce a new
callback td_pre_close() to flush these I/O requests.

Signed-off-by: Wen Congyang <wency@xxxxxxxxxxxxxx>
Cc: Shriram Rajagopalan <rshriram@xxxxxxxxx>
---
 tools/blktap2/drivers/block-remus.c       | 14 ++++++++++++++
 tools/blktap2/drivers/block-replication.h |  1 +
 tools/blktap2/drivers/tapdisk-control.c   |  6 ++++++
 tools/blktap2/drivers/tapdisk-interface.c | 18 ++++++++++++++++++
 tools/blktap2/drivers/tapdisk-interface.h |  1 +
 tools/blktap2/drivers/tapdisk-vbd.c       |  9 +++++++++
 tools/blktap2/drivers/tapdisk-vbd.h       |  1 +
 tools/blktap2/drivers/tapdisk.h           |  1 +
 8 files changed, 51 insertions(+)

diff --git a/tools/blktap2/drivers/block-remus.c 
b/tools/blktap2/drivers/block-remus.c
index a2b9f62..09dc46f 100644
--- a/tools/blktap2/drivers/block-remus.c
+++ b/tools/blktap2/drivers/block-remus.c
@@ -752,6 +752,8 @@ static void primary_failed(struct tdremus_state *s, int rc)
        td_replication_connect_kill(&s->t);
        if (rc == ERROR_INTERNAL)
                RPRINTF("switch to unprotected mode due to internal error");
+       if (rc == ERROR_CLOSE)
+               RPRINTF("switch to unprotected mode before closing");
        UNREGISTER_EVENT(s->stream_fd.id);
        switch_mode(s->tdremus_driver, mode_unprotected);
 }
@@ -1500,6 +1502,17 @@ static int tdremus_open(td_driver_t *driver, td_image_t 
*image, td_uuid_t uuid)
        return -EIO;
 }
 
+static int tdremus_pre_close(td_driver_t *driver)
+{
+       struct tdremus_state *s = (struct tdremus_state *)driver->data;
+
+       if (s->mode != mode_primary)
+               return 0;
+
+       primary_failed(s, ERROR_CLOSE);
+       return 0;
+}
+
 static int tdremus_close(td_driver_t *driver)
 {
        struct tdremus_state *s = (struct tdremus_state *)driver->data;
@@ -1533,6 +1546,7 @@ struct tap_disk tapdisk_remus = {
        .td_open            = tdremus_open,
        .td_queue_read      = unprotected_queue_read,
        .td_queue_write     = unprotected_queue_write,
+       .td_pre_close       = tdremus_pre_close,
        .td_close           = tdremus_close,
        .td_get_parent_id   = tdremus_get_parent_id,
        .td_validate_parent = tdremus_validate_parent,
diff --git a/tools/blktap2/drivers/block-replication.h 
b/tools/blktap2/drivers/block-replication.h
index 07fd630..358c08b 100644
--- a/tools/blktap2/drivers/block-replication.h
+++ b/tools/blktap2/drivers/block-replication.h
@@ -49,6 +49,7 @@ enum {
        ERROR_INTERNAL = -1,
        ERROR_CONNECTION = -2,
        ERROR_IO = -3,
+       ERROR_CLOSE = -4,
 };
 
 typedef struct td_replication_connect td_replication_connect_t;
diff --git a/tools/blktap2/drivers/tapdisk-control.c 
b/tools/blktap2/drivers/tapdisk-control.c
index 4e5f748..2fa4cbe 100644
--- a/tools/blktap2/drivers/tapdisk-control.c
+++ b/tools/blktap2/drivers/tapdisk-control.c
@@ -508,6 +508,12 @@ tapdisk_control_close_image(struct 
tapdisk_control_connection *connection,
                goto out;
        }
 
+       /*
+        * Some I/O requests are pended in the driver, and
+        * flush these requests first.
+        */
+       tapdisk_vbd_pre_close_vdi(vbd);
+
        if (!list_empty(&vbd->pending_requests)) {
                err = -EAGAIN;
                goto out;
diff --git a/tools/blktap2/drivers/tapdisk-interface.c 
b/tools/blktap2/drivers/tapdisk-interface.c
index a29de64..ed92e12 100644
--- a/tools/blktap2/drivers/tapdisk-interface.c
+++ b/tools/blktap2/drivers/tapdisk-interface.c
@@ -105,6 +105,24 @@ td_open(td_image_t *image)
 }
 
 int
+td_pre_close(td_image_t *image)
+{
+       td_driver_t *driver;
+
+       driver = image->driver;
+       if (!driver)
+               return -ENODEV;
+
+       if (!driver->ops->td_pre_close)
+               return 0;
+
+       if (driver->refcnt && td_flag_test(driver->state, TD_DRIVER_OPEN))
+               driver->ops->td_pre_close(driver);
+
+       return 0;
+}
+
+int
 td_close(td_image_t *image)
 {
        td_driver_t *driver;
diff --git a/tools/blktap2/drivers/tapdisk-interface.h 
b/tools/blktap2/drivers/tapdisk-interface.h
index adc4376..ba9b3ea 100644
--- a/tools/blktap2/drivers/tapdisk-interface.h
+++ b/tools/blktap2/drivers/tapdisk-interface.h
@@ -34,6 +34,7 @@
 int td_open(td_image_t *);
 int __td_open(td_image_t *, td_disk_info_t *);
 int td_load(td_image_t *);
+int td_pre_close(td_image_t *);
 int td_close(td_image_t *);
 int td_get_parent_id(td_image_t *, td_disk_id_t *);
 int td_validate_parent(td_image_t *, td_image_t *);
diff --git a/tools/blktap2/drivers/tapdisk-vbd.c 
b/tools/blktap2/drivers/tapdisk-vbd.c
index c665f27..aba545b 100644
--- a/tools/blktap2/drivers/tapdisk-vbd.c
+++ b/tools/blktap2/drivers/tapdisk-vbd.c
@@ -180,6 +180,15 @@ tapdisk_vbd_validate_chain(td_vbd_t *vbd)
 }
 
 void
+tapdisk_vbd_pre_close_vdi(td_vbd_t *vbd)
+{
+       td_image_t *image, *tmp;
+
+       tapdisk_vbd_for_each_image(vbd, image, tmp)
+               td_pre_close(image);
+}
+
+void
 tapdisk_vbd_close_vdi(td_vbd_t *vbd)
 {
        td_image_t *image, *tmp;
diff --git a/tools/blktap2/drivers/tapdisk-vbd.h 
b/tools/blktap2/drivers/tapdisk-vbd.h
index be084b2..040f2b8 100644
--- a/tools/blktap2/drivers/tapdisk-vbd.h
+++ b/tools/blktap2/drivers/tapdisk-vbd.h
@@ -181,6 +181,7 @@ void tapdisk_vbd_free_stack(td_vbd_t *);
 int tapdisk_vbd_open_stack(td_vbd_t *, uint16_t, td_flag_t);
 int tapdisk_vbd_open_vdi(td_vbd_t *, const char *,
                         uint16_t, uint16_t, td_flag_t);
+void tapdisk_vbd_pre_close_vdi(td_vbd_t *);
 void tapdisk_vbd_close_vdi(td_vbd_t *);
 
 int tapdisk_vbd_attach(td_vbd_t *, const char *, int);
diff --git a/tools/blktap2/drivers/tapdisk.h b/tools/blktap2/drivers/tapdisk.h
index 3c3b51d..16efd07 100644
--- a/tools/blktap2/drivers/tapdisk.h
+++ b/tools/blktap2/drivers/tapdisk.h
@@ -158,6 +158,7 @@ struct tap_disk {
        td_flag_t                    flags;
        int                          private_data_size;
        int (*td_open)               (td_driver_t *, td_image_t *, td_uuid_t);
+       int (*td_pre_close)          (td_driver_t *);
        int (*td_close)              (td_driver_t *);
        int (*td_get_parent_id)      (td_driver_t *, td_disk_id_t *);
        int (*td_validate_parent)    (td_driver_t *, td_driver_t *, td_flag_t);
-- 
1.9.3


_______________________________________________
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®.