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

[Xen-devel] [PATCH 7 of 9 RFC v3] blktap3/libblktapctl: Introduce tapdisk message exchange functionality



This patch introduces file conrol/tap-ctl-ipc.c, where the functionality of
talking to a tapdisk process is implemented. This file is imported from the
existing blktap2 implementation, with most changes coming from blktap2 living
in github.

---
Changed since v2:
  * Check for unexpected response in tap_ctl_send_and_receive.
  * If the message has been served but an error occurred, the error in the
    message is returned by the function in order to simplify error
    checking/handling by the caller.

diff --git a/tools/blktap2/control/tap-ctl-ipc.c 
b/tools/blktap3/control/tap-ctl-ipc.c
copy from tools/blktap2/control/tap-ctl-ipc.c
copy to tools/blktap3/control/tap-ctl-ipc.c
--- a/tools/blktap2/control/tap-ctl-ipc.c
+++ b/tools/blktap3/control/tap-ctl-ipc.c
@@ -30,44 +30,34 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
+#include <fcntl.h>
 #include <sys/un.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <assert.h>
 
 #include "tap-ctl.h"
-#include "blktap2.h"
+#include "blktap3.h"
 
 int tap_ctl_debug = 0;
 
 int
-tap_ctl_read_message(int fd, tapdisk_message_t *message, int timeout)
+tap_ctl_read_raw(int fd, void *buf, size_t size, struct timeval *timeout)
 {
        fd_set readfds;
-       int ret, len, offset;
-       struct timeval tv, *t;
+       size_t offset = 0;
+       int ret;
 
-       t      = NULL;
-       offset = 0;
-       len    = sizeof(tapdisk_message_t);
-
-       if (timeout) {
-               tv.tv_sec  = timeout;
-               tv.tv_usec = 0;
-               t = &tv;
-       }
-
-       memset(message, 0, sizeof(tapdisk_message_t));
-
-       while (offset < len) {
+       while (offset < size) {
                FD_ZERO(&readfds);
                FD_SET(fd, &readfds);
 
-               ret = select(fd + 1, &readfds, NULL, NULL, t);
+               ret = select(fd + 1, &readfds, NULL, NULL, timeout);
                if (ret == -1)
                        break;
                else if (FD_ISSET(fd, &readfds)) {
-                       ret = read(fd, message + offset, len - offset);
+                       ret = read(fd, buf + offset, size - offset);
                        if (ret <= 0)
                                break;
                        offset += ret;
@@ -75,34 +65,24 @@ tap_ctl_read_message(int fd, tapdisk_mes
                        break;
        }
 
-       if (offset != len) {
-               EPRINTF("failure reading message\n");
+       if (offset != size) {
+               EPRINTF("failure reading data %zd/%zd\n", offset, size);
                return -EIO;
        }
 
-       DBG("received '%s' message (uuid = %u)\n",
-           tapdisk_message_name(message->type), message->cookie);
-
        return 0;
 }
 
 int
-tap_ctl_write_message(int fd, tapdisk_message_t *message, int timeout)
+tap_ctl_write_message(int fd, tapdisk_message_t * message,
+                                         struct timeval *timeout)
 {
        fd_set writefds;
        int ret, len, offset;
-       struct timeval tv, *t;
 
-       t      = NULL;
        offset = 0;
        len    = sizeof(tapdisk_message_t);
 
-       if (timeout) {
-               tv.tv_sec  = timeout;
-               tv.tv_usec = 0;
-               t = &tv;
-       }
-
        DBG("sending '%s' message (uuid = %u)\n",
            tapdisk_message_name(message->type), message->cookie);
 
@@ -113,7 +93,7 @@ tap_ctl_write_message(int fd, tapdisk_me
                /* we don't bother reinitializing tv. at worst, it will wait a
                 * bit more time than expected. */
 
-               ret = select(fd + 1, NULL, &writefds, NULL, t);
+               ret = select(fd + 1, NULL, &writefds, NULL, timeout);
                if (ret == -1)
                        break;
                else if (FD_ISSET(fd, &writefds)) {
@@ -134,9 +114,15 @@ tap_ctl_write_message(int fd, tapdisk_me
 }
 
 int
-tap_ctl_send_and_receive(int sfd, tapdisk_message_t *message, int timeout)
+tap_ctl_send_and_receive(const int sfd, tapdisk_message_t * const message,
+                                                struct timeval *timeout)
 {
        int err;
+       td_msg_id_t msg_type;
+
+       assert(message);
+
+       msg_type = message->type;
 
        err = tap_ctl_write_message(sfd, message, timeout);
        if (err) {
@@ -147,12 +133,29 @@ tap_ctl_send_and_receive(int sfd, tapdis
 
        err = tap_ctl_read_message(sfd, message, timeout);
        if (err) {
+               /*
+                * TODO If there are messages for which a response is not 
required
+                * and failure to receive a reply is expected, this print is 
bogus.
+                */
                EPRINTF("failed to receive '%s' message\n",
                        tapdisk_message_name(message->type));
                return err;
        }
 
-       return 0;
+       if (tapdisk_message_is_rsp_paired(msg_type)) {
+               if (message->type - msg_type != 1) {
+                       err = EINVAL;
+                       EPRINTF("invalid response '%s' to message '%s'\n",
+                                       tapdisk_message_name(message->type),
+                                       tapdisk_message_name(msg_type));
+               } else if (message->u.response.error) {
+                       err = message->u.response.error;
+                       EPRINTF("failed to serve message '%s': %s\n",
+                                       tapdisk_message_name(msg_type), 
strerror(err));
+               }
+       }
+
+       return err;
 }
 
 char *
@@ -161,7 +164,7 @@ tap_ctl_socket_name(int id)
        char *name;
 
        if (asprintf(&name, "%s/%s%d",
-                    BLKTAP2_CONTROL_DIR, BLKTAP2_CONTROL_SOCKET, id) == -1)
+                                BLKTAP3_CONTROL_DIR, BLKTAP3_CONTROL_SOCKET, 
id) == -1)
                return NULL;
 
        return name;
@@ -222,7 +225,8 @@ tap_ctl_connect_id(int id, int *sfd)
 }
 
 int
-tap_ctl_connect_send_and_receive(int id, tapdisk_message_t *message, int 
timeout)
+tap_ctl_connect_send_and_receive(int id, tapdisk_message_t * message,
+                                                                struct timeval 
*timeout)
 {
        int err, sfd;
 
@@ -235,3 +239,20 @@ tap_ctl_connect_send_and_receive(int id,
        close(sfd);
        return err;
 }
+
+int
+tap_ctl_read_message(int fd, tapdisk_message_t * message,
+                                        struct timeval *timeout)
+{
+       size_t size = sizeof(tapdisk_message_t);
+       int err;
+
+       err = tap_ctl_read_raw(fd, message, size, timeout);
+       if (err)
+               return err;
+
+       DBG("received '%s' message (uuid = %u)\n",
+               tapdisk_message_name(message->type), message->cookie);
+
+       return 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®.