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

[Xen-devel] [PATCH 02 of 15 v4] blktap3/libblktapctl: Introduce tapdisk message types and structures



This patch introduces function prototypes and structures that are implemented
by libblktapctl (the library that allows libxl, tap-ctl, and the tapback daemon
to manage a running tapdisk process). This file is based on the existing
blktap2 file, with some changes coming from blktap2 living in github (the STATS
message, support for mirroring).

tapdisk_message_name is now neater and uses a look up table instead of a big
switch.

blktap3 introduces the following messages:
        - DISK_INFO: used by the tapback daemon to communicate to blkfront via
      XenStore the number of sectors and the sector size so that it can create
      the virtual block device.
        - XENBLKIF_CONNECT/DISCONNECT: used by the tapback daemon to instruct a
          running tapdisk process to connect to the ring. The
          tapdisk_message_blkif structure is used to convey such messages.

Signed-off-by: Thanos Makatos <thanos.makatos@xxxxxxxxxx>

---
Changed since v2:
  * Include TAPDISK_MESSAGE_MAX in the enum.
  * Updated comment regarding the proto member in struct tapdisk_message
    blkif.
  * Rearranged enum tapdisk_message_id in such a way that messages requiring a
    response belong to a "group". Introduce self-explanatory function
    tapdisk_message_is_rsp_paired.

Changed since v3:
  * Use the correct name for the back-end daemon in the description of this
    patch (tapback instead of the obsolete xenio).
  * Removed erroneous statement in the patch description stating that
    attach/detach is obsolete.

diff --git a/tools/blktap2/include/tapdisk-message.h 
b/tools/blktap3/include/tapdisk-message.h
copy from tools/blktap2/include/tapdisk-message.h
copy to tools/blktap3/include/tapdisk-message.h
--- a/tools/blktap2/include/tapdisk-message.h
+++ b/tools/blktap3/include/tapdisk-message.h
@@ -36,29 +36,35 @@
 #define TAPDISK_MESSAGE_MAX_MINORS \
        ((TAPDISK_MESSAGE_MAX_PATH_LENGTH / sizeof(int)) - 1)
 
-#define TAPDISK_MESSAGE_FLAG_SHARED      0x01
-#define TAPDISK_MESSAGE_FLAG_RDONLY      0x02
-#define TAPDISK_MESSAGE_FLAG_ADD_CACHE   0x04
-#define TAPDISK_MESSAGE_FLAG_VHD_INDEX   0x08
-#define TAPDISK_MESSAGE_FLAG_LOG_DIRTY   0x10
+#define TAPDISK_MESSAGE_FLAG_SHARED      0x001
+#define TAPDISK_MESSAGE_FLAG_RDONLY      0x002
+#define TAPDISK_MESSAGE_FLAG_ADD_CACHE   0x004
+#define TAPDISK_MESSAGE_FLAG_VHD_INDEX   0x008
+#define TAPDISK_MESSAGE_FLAG_LOG_DIRTY   0x010
+#define TAPDISK_MESSAGE_FLAG_ADD_LCACHE  0x020
+#define TAPDISK_MESSAGE_FLAG_REUSE_PRT   0x040
+#define TAPDISK_MESSAGE_FLAG_SECONDARY   0x080
+#define TAPDISK_MESSAGE_FLAG_STANDBY     0x100
 
 typedef struct tapdisk_message           tapdisk_message_t;
-typedef uint8_t                          tapdisk_message_flag_t;
+typedef uint32_t                         tapdisk_message_flag_t;
 typedef struct tapdisk_message_image     tapdisk_message_image_t;
 typedef struct tapdisk_message_params    tapdisk_message_params_t;
 typedef struct tapdisk_message_string    tapdisk_message_string_t;
 typedef struct tapdisk_message_response  tapdisk_message_response_t;
 typedef struct tapdisk_message_minors    tapdisk_message_minors_t;
 typedef struct tapdisk_message_list      tapdisk_message_list_t;
+typedef struct tapdisk_message_stat      tapdisk_message_stat_t;
+typedef struct tapdisk_message_blkif     tapdisk_message_blkif_t;
 
 struct tapdisk_message_params {
        tapdisk_message_flag_t           flags;
 
-       uint8_t                          storage;
        uint32_t                         devnum;
        uint32_t                         domid;
-       uint16_t                         path_len;
        char                             path[TAPDISK_MESSAGE_MAX_PATH_LENGTH];
+       uint32_t                         prt_devnum;
+       char                             
secondary[TAPDISK_MESSAGE_MAX_PATH_LENGTH];
 };
 
 struct tapdisk_message_image {
@@ -88,6 +94,55 @@ struct tapdisk_message_list {
        char                             path[TAPDISK_MESSAGE_MAX_PATH_LENGTH];
 };
 
+struct tapdisk_message_stat {
+       uint16_t type;
+       uint16_t cookie;
+       size_t length;
+};
+
+/**
+ * Tapdisk message containing all the necessary information required for the
+ * tapdisk to connect to a guest's blkfront.
+ */
+struct tapdisk_message_blkif {
+       /**
+        * The domain ID of the guest to connect to.
+        */
+       uint32_t domid;
+
+       /**
+        * The device ID of the virtual block device.
+        */
+       uint32_t devid;
+
+       /**
+        * Grant references for the shared ring.
+        * TODO Why 8 specifically?
+        */
+       uint32_t gref[8];
+
+       /**
+        * Number of pages in the ring, expressed as a page order.
+        */
+       uint32_t order;
+
+       /**
+        * Protocol to use: native, 32 bit, or 64 bit. Used for supporting a
+        * 32-bit domU talking to a 64-bit dom0/domU and vice versa.
+        */
+       uint32_t proto;
+
+       /**
+        * TODO Page pool? Can be NULL.
+        */
+       char pool[TAPDISK_MESSAGE_STRING_LENGTH];
+
+       /**
+        * The event channel port.
+        */
+       uint32_t port;
+};
+
 struct tapdisk_message {
        uint16_t                         type;
        uint16_t                         cookie;
@@ -100,13 +155,30 @@ struct tapdisk_message {
                tapdisk_message_minors_t minors;
                tapdisk_message_response_t response;
                tapdisk_message_list_t   list;
+               tapdisk_message_stat_t   info;
+               tapdisk_message_blkif_t  blkif;
        } u;
 };
 
-enum tapdisk_message_id {
+/**
+ * Messages that are paired with a response (e.g. TAPDISK_MESSAGE_FOO goes
+ * hand in hand with message TAPDISK_MESSAGE_FOO_RSP) should be placed within
+ * a contiguous range in the enum in order to be able to easily identify
+ * whether a given message requires a response. Also, a message's response
+ * must follow the message in the enum so that their values differ by 1.
+ */
+typedef enum tapdisk_message_id {
+       /*
+        * TODO Why start from 1 and not from 0?
+        */
        TAPDISK_MESSAGE_ERROR = 1,
        TAPDISK_MESSAGE_RUNTIME_ERROR,
-       TAPDISK_MESSAGE_PID,
+
+       /*
+        * Begin of messages paired with a response.
+        */
+       TAPDISK_MESSAGE_REQS_RSP_START, /* not an actual message */
+       TAPDISK_MESSAGE_PID = TAPDISK_MESSAGE_REQS_RSP_START, 
        TAPDISK_MESSAGE_PID_RSP,
        TAPDISK_MESSAGE_ATTACH,
        TAPDISK_MESSAGE_ATTACH_RSP,
@@ -120,84 +192,94 @@ enum tapdisk_message_id {
        TAPDISK_MESSAGE_CLOSE_RSP,
        TAPDISK_MESSAGE_DETACH,
        TAPDISK_MESSAGE_DETACH_RSP,
-       TAPDISK_MESSAGE_LIST_MINORS,
-       TAPDISK_MESSAGE_LIST_MINORS_RSP,
+       TAPDISK_MESSAGE_LIST_MINORS,            /* TODO still valid? */
+       TAPDISK_MESSAGE_LIST_MINORS_RSP,        /* TODO still valid? */
        TAPDISK_MESSAGE_LIST,
        TAPDISK_MESSAGE_LIST_RSP,
-       TAPDISK_MESSAGE_FORCE_SHUTDOWN,
+       TAPDISK_MESSAGE_STATS,
+       TAPDISK_MESSAGE_STATS_RSP,
+       TAPDISK_MESSAGE_DISK_INFO,
+       TAPDISK_MESSAGE_DISK_INFO_RSP,
+       TAPDISK_MESSAGE_XENBLKIF_CONNECT,
+       TAPDISK_MESSAGE_XENBLKIF_CONNECT_RSP,
+       TAPDISK_MESSAGE_XENBLKIF_DISCONNECT,
+       TAPDISK_MESSAGE_XENBLKIF_DISCONNECT_RSP,
+       TAPDISK_MESSAGE_REQS_RSP_END = TAPDISK_MESSAGE_XENBLKIF_DISCONNECT_RSP,
+       /*
+        * End of messages requiring a response.
+        */
+
+       TAPDISK_MESSAGE_FORCE_SHUTDOWN,    
        TAPDISK_MESSAGE_EXIT,
-};
+       TAPDISK_MESSAGE_MAX
+} td_msg_id_t;
 
-static inline char *
-tapdisk_message_name(enum tapdisk_message_id id)
-{
-       switch (id) {
-       case TAPDISK_MESSAGE_ERROR:
-               return "error";
+/**
+ * Tells whether a request message is paired with a reply message or vice
+ * versa.
+ *
+ * @param id the message ID
+ * @returns 1 if the request message is paired with a response (or vice versa),
+ * 0 otherwise
+ */
+static inline int tapdisk_message_is_rsp_paired(const td_msg_id_t id) {
+    return id >= TAPDISK_MESSAGE_REQS_RSP_START
+        && id <= TAPDISK_MESSAGE_REQS_RSP_END;
+}
 
-       case TAPDISK_MESSAGE_PID:
-               return "pid";
+/**
+ * Retrieves a message's human-readable representation.
+ *
+ * @param id the message ID to translate
+ * @return the name of the message
+ *
+ * @note If the message type is unknown the function simply returns 'unknown',
+ * so the information regarding the erroneous message type is lost. We could
+ * include the number of the message in the returned string but we would then
+ * have to allocate it, forcing the user to release each string this function
+ * would return, something that users of this function would probably forget
+ * to do.
+ */
+static inline char const *
+tapdisk_message_name(const td_msg_id_t id) {
+       static char const *msg_names[TAPDISK_MESSAGE_MAX] = {
+               [TAPDISK_MESSAGE_ERROR] = "error",
+               [TAPDISK_MESSAGE_RUNTIME_ERROR] = "runtime error",
+               [TAPDISK_MESSAGE_PID] = "pid",
+               [TAPDISK_MESSAGE_PID_RSP] = "pid response",
+               [TAPDISK_MESSAGE_OPEN] = "open",
+               [TAPDISK_MESSAGE_OPEN_RSP] = "open response",
+               [TAPDISK_MESSAGE_PAUSE] = "pause",
+               [TAPDISK_MESSAGE_PAUSE_RSP] = "pause response",
+               [TAPDISK_MESSAGE_RESUME] = "resume",
+               [TAPDISK_MESSAGE_RESUME_RSP] = "resume response",
+               [TAPDISK_MESSAGE_CLOSE] = "close",
+               [TAPDISK_MESSAGE_FORCE_SHUTDOWN] = "force shutdown",
+               [TAPDISK_MESSAGE_CLOSE_RSP] = "close response",
+               [TAPDISK_MESSAGE_ATTACH] = "attach",
+               [TAPDISK_MESSAGE_ATTACH_RSP] = "attach response",
+               [TAPDISK_MESSAGE_DETACH] = "detach",
+               [TAPDISK_MESSAGE_DETACH_RSP] = "detach response",
+               [TAPDISK_MESSAGE_LIST_MINORS] = "list minors",
+               [TAPDISK_MESSAGE_LIST_MINORS_RSP] = "list minors response",
+               [TAPDISK_MESSAGE_LIST] = "list",
+               [TAPDISK_MESSAGE_LIST_RSP] = "list response",
+               [TAPDISK_MESSAGE_STATS] = "stats",
+               [TAPDISK_MESSAGE_STATS_RSP] = "stats response",
+               [TAPDISK_MESSAGE_DISK_INFO] = "disk info",
+               [TAPDISK_MESSAGE_DISK_INFO_RSP] = "disk info response",
+               [TAPDISK_MESSAGE_XENBLKIF_CONNECT] = "blkif connect",
+               [TAPDISK_MESSAGE_XENBLKIF_CONNECT_RSP] = "blkif connect 
response",
+               [TAPDISK_MESSAGE_XENBLKIF_DISCONNECT] = "blkif disconnect",
+               [TAPDISK_MESSAGE_XENBLKIF_DISCONNECT_RSP]
+                       = "blkif disconnect response",
+               [TAPDISK_MESSAGE_EXIT] = "exit"
+       };
 
-       case TAPDISK_MESSAGE_PID_RSP:
-               return "pid response";
-
-       case TAPDISK_MESSAGE_OPEN:
-               return "open";
-
-       case TAPDISK_MESSAGE_OPEN_RSP:
-               return "open response";
-
-       case TAPDISK_MESSAGE_PAUSE:
-               return "pause";
-
-       case TAPDISK_MESSAGE_PAUSE_RSP:
-               return "pause response";
-
-       case TAPDISK_MESSAGE_RESUME:
-               return "resume";
-
-       case TAPDISK_MESSAGE_RESUME_RSP:
-               return "resume response";
-
-       case TAPDISK_MESSAGE_CLOSE:
-               return "close";
-
-       case TAPDISK_MESSAGE_FORCE_SHUTDOWN:
-               return "force shutdown";
-
-       case TAPDISK_MESSAGE_CLOSE_RSP:
-               return "close response";
-
-       case TAPDISK_MESSAGE_ATTACH:
-               return "attach";
-
-       case TAPDISK_MESSAGE_ATTACH_RSP:
-               return "attach response";
-
-       case TAPDISK_MESSAGE_DETACH:
-               return "detach";
-
-       case TAPDISK_MESSAGE_DETACH_RSP:
-               return "detach response";
-
-       case TAPDISK_MESSAGE_LIST_MINORS:
-               return "list minors";
-
-       case TAPDISK_MESSAGE_LIST_MINORS_RSP:
-               return "list minors response";
-
-       case TAPDISK_MESSAGE_LIST:
-               return "list";
-
-       case TAPDISK_MESSAGE_LIST_RSP:
-               return "list response";
-
-       case TAPDISK_MESSAGE_EXIT:
-               return "exit";
-
-       default:
+       if (id < 1 || id >= TAPDISK_MESSAGE_MAX) {
                return "unknown";
        }
+       return msg_names[id];
 }
 
-#endif
+#endif /* _TAPDISK_MESSAGE_H_ */

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