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

[Xen-devel] [RFC Patch v2 03/16] block-remus: introduce a interface to allow the user specify which mode the backup end uses



block-remus can be used for remus and colo, so we should introduce a way to
tell block-remus which mode it should use:
    write mode to /var/run/tap/remus_xxx(control file):
    1. 'r': remus
    2. 'c': colo
The mode should be writen to control file before we write any other command
to control file.

The master side will write TDREMUS_COLO to slaver side to tell it use colo
mode.

Signed-off-by: Ye Wei <wei.ye1987@xxxxxxxxx>
Signed-off-by: Jiang Yunhong <yunhong.jiang@xxxxxxxxx>
Signed-off-by: Wen Congyang <wency@xxxxxxxxxxxxxx>
---
 tools/blktap2/drivers/block-remus.c |   49 +++++++++++++++++++++++++++++++++++
 tools/python/xen/remus/device.py    |    8 +++++
 tools/remus/remus                   |    1 +
 3 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/tools/blktap2/drivers/block-remus.c 
b/tools/blktap2/drivers/block-remus.c
index bced0e9..a85f5a0 100644
--- a/tools/blktap2/drivers/block-remus.c
+++ b/tools/blktap2/drivers/block-remus.c
@@ -188,6 +188,9 @@ struct tdremus_state {
        /* mode methods */
        enum tdremus_mode mode;
        int (*queue_flush)(td_driver_t *driver);
+
+       /* init data */
+       int init_state; /* 0: init, 1: remus, 2: colo */
 };
 
 typedef struct tdremus_wire {
@@ -201,6 +204,7 @@ typedef struct tdremus_wire {
 #define TDREMUS_WRITE "wreq"
 #define TDREMUS_SUBMIT "sreq"
 #define TDREMUS_COMMIT "creq"
+#define TDREMUS_COLO "colo"
 #define TDREMUS_DONE "done"
 #define TDREMUS_FAIL "fail"
 
@@ -786,6 +790,33 @@ static int primary_do_connect(struct tdremus_state *state)
        return 0;
 }
 
+static void read_state(struct tdremus_state *s)
+{
+       int rc;
+       char state;
+
+       rc = read(s->ctl_fd.fd, &state, 1);
+       if (rc <= 0)
+               return;
+
+       if (state == 'r') {
+               s->init_state = 1;
+       } else if (state == 'c') {
+               s->init_state = 2;
+       } else {
+               RPRINTF("read unknown state: %d, use remus\n", (int)state);
+               s->init_state = 1;
+       }
+}
+
+static void start_remus(struct tdremus_state *s)
+{
+       if (mwrite(s->stream_fd.fd, TDREMUS_COLO, strlen(TDREMUS_COLO)) < 0) {
+               RPRINTF("error start colo mode");
+               exit(1);
+       }
+}
+
 static int primary_blocking_connect(struct tdremus_state *state)
 {
        int fd;
@@ -835,6 +866,18 @@ static int primary_blocking_connect(struct tdremus_state 
*state)
 
        state->stream_fd.fd = fd;
        state->stream_fd.id = id;
+
+       /* The user runs the remus command after we try to connect backup end */
+       if (!state->init_state)
+               read_state(state);
+
+       if (!state->init_state) {
+               RPRINTF("read state failed, try to use remus\n");
+               state->init_state = 1;
+       }
+
+       if (state->init_state == 2)
+               start_remus(state);
        return 0;
 }
 
@@ -1424,6 +1467,8 @@ static void remus_server_event(event_id_t id, char mode, 
void *private)
                server_do_sreq(driver);
        else if (!strcmp(req, TDREMUS_COMMIT))
                server_do_creq(driver);
+       else if (!strcmp(req, TDREMUS_COLO))
+               switch_mode(driver, mode_colo);
        else
                RPRINTF("unknown request received: %s\n", req);
 
@@ -1624,6 +1669,10 @@ static void ctl_request(event_id_t id, char mode, void 
*private)
        int rc;
 
        // RPRINTF("data waiting on control fifo\n");
+       if (!s->init_state) {
+               read_state(s);
+               return;
+       }
 
        if (!(rc = read(s->ctl_fd.fd, msg, sizeof(msg) - 1 /* append nul */))) {
                RPRINTF("0-byte read received, reopening FIFO\n");
diff --git a/tools/python/xen/remus/device.py b/tools/python/xen/remus/device.py
index 970e1ea..bbb1cd8 100644
--- a/tools/python/xen/remus/device.py
+++ b/tools/python/xen/remus/device.py
@@ -12,6 +12,10 @@ class BufferedNICException(Exception): pass
 class CheckpointedDevice(object):
     'Base class for buffered devices'
 
+    def init(self, mode):
+        'init device state, only called once'
+        pass
+
     def postsuspend(self):
         'called after guest has suspended'
         pass
@@ -79,6 +83,10 @@ class ReplicatedDisk(CheckpointedDevice):
     def __del__(self):
         self.uninstall()
 
+    def init(self, mode):
+        if self.ctlfd:
+            os.write(self.ctlfd.fileno(), mode)
+
     def uninstall(self):
         if self.ctlfd:
             self.ctlfd.close()
diff --git a/tools/remus/remus b/tools/remus/remus
index 38f0365..d5178cd 100644
--- a/tools/remus/remus
+++ b/tools/remus/remus
@@ -124,6 +124,7 @@ def run(cfg):
         for disk in dom.disks:
             try:
                 bufs.append(ReplicatedDisk(disk))
+                disk.init('r')
             except ReplicatedDiskException, e:
                 print e
                 continue
-- 
1.7.4


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