|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 07 of 13 v6] 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.5.
Signed-off-by: Thanos Makatos <thanos.makatos@xxxxxxxxxx>
---
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.
Changed since v3:
* Removed wrong way of checking for errors in order to provide more verbose
logging, as not all messages contain an error field.
Changed since v4:
* Removed printing the message cookie in debug messages.
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,47 +30,37 @@
#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) {
if (errno == EINTR)
continue;
break;
}
else if (FD_ISSET(fd, &readfds)) {
- ret = read(fd, message + offset, len - offset);
+ ret = read(fd, buf + offset, size - offset);
if (ret <= 0) {
if (errno == EINTR)
continue;
@@ -81,36 +71,26 @@ 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);
+ DBG("sending '%s' message\n",
+ tapdisk_message_name(message->type));
while (offset < len) {
FD_ZERO(&writefds);
@@ -119,7 +99,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) {
if (errno == EINTR)
continue;
@@ -146,9 +126,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) {
@@ -159,12 +145,27 @@ 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
+ err = 0;
+ }
+
+ return err;
}
char *
@@ -173,7 +174,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;
@@ -234,7 +235,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;
@@ -247,3 +249,19 @@ 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\n", tapdisk_message_name(message->type));
+
+ return 0;
+}
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |