hammer2 - dmsg blockdev work
[dragonfly.git] / sys / sys / dmsg.h
1 /*
2  * Copyright (c) 2011-2012 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@dragonflybsd.org>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34
35 #ifndef _SYS_DMSG_H_
36 #define _SYS_DMSG_H_
37
38 #ifndef _SYS_MALLOC_H_
39 #include <sys/malloc.h>
40 #endif
41 #ifndef _SYS_TREE_H_
42 #include <sys/tree.h>
43 #endif
44 #ifndef _SYS_THREAD_H_
45 #include <sys/thread.h>
46 #endif
47 #ifndef _SYS_UUID_H_
48 #include <sys/uuid.h>
49 #endif
50
51 /*
52  * Mesh network protocol structures.
53  *
54  *                              SPAN PROTOCOL
55  *
56  * The mesh is constructed from point-to-point streaming links with varying
57  * levels of interconnectedness, forming a graph.  Terminii in the graph
58  * are entities such as a HAMMER2 PFS or a network mount or other types
59  * of nodes.
60  *
61  * The spanning tree protocol runs symmetrically on every node. Each node
62  * transmits a representitive LNK_SPAN out all available connections.  Nodes
63  * also receive LNK_SPANs from other nodes (obviously), and must aggregate,
64  * reduce, and relay those LNK_SPANs out all available connections, thus
65  * propagating the spanning tree.  Any connection failure or topology change
66  * causes changes in the LNK_SPAN propagation.
67  *
68  * Each LNK_SPAN or LNK_SPAN relay represents a virtual circuit for routing
69  * purposes.  In addition, each relay is chained in one direction,
70  * representing a 1:N fan-out (i.e. one received LNK_SPAN can be relayed out
71  * multiple connections).  In order to be able to route a message via a
72  * LNK_SPAN over a deterministic route THE MESSAGE CAN ONLY FLOW FROM A
73  * REMOTE NODE TOWARDS OUR NODE (N:1 fan-in).
74  *
75  * This supports the requirement that we have both message serialization
76  * and positive feedback if a topology change breaks the chain of VCs
77  * the message is flowing over.  A remote node sending a message to us
78  * will get positive feedback that the route was broken and can take suitable
79  * action to terminate the transaction with an error.
80  *
81  *                              TRANSACTIONAL REPLIES
82  *
83  * However, when we receive a command message from a remote node and we want
84  * to reply to it, we have a problem.  We want the remote node to have
85  * positive feedback if our reply fails to make it, but if we use a virtual
86  * circuit based on the remote node's LNK_SPAN to us it will be a DIFFERENT
87  * virtual circuit than the one the remote node used to message us.  That's
88  * a problem because it means we have no reliable way to notify the remote
89  * node if we get notified that our reply has failed.
90  *
91  * The solution is to first note the fact that the remote chose an optimal
92  * route to get to us, so the reverse should be true. The reason the VC
93  * might not exist over the same route in the reverse is because there may
94  * be multiple paths available with the same distance metric.
95  *
96  * But this also means that we can adjust the messaging protocols to
97  * propagate a LNK_SPAN from the remote to us WHILE the remote's command
98  * message is being sent to us, and it will not only likely be optimal but
99  * it might also already exist, and it will also guarantee that a reply
100  * failure will propagate back to both sides (because even though each
101  * direction is using a different VC chain, the two chains are still
102  * going along the same path).
103  *
104  * We communicate the return VC by having the relay adjust both the target
105  * and the source fields in the message, rather than just the target, on
106  * each relay.  As of when the message gets to us the 'source' field will
107  * represent the VC for the return direction (and of course also identify
108  * the node the message came from).
109  *
110  * This way both sides get positive feedback if a topology change disrupts
111  * the VC for the transaction.  We also get one additional guarantee, and
112  * that is no spurious messages.  Messages simply die when the VC they are
113  * traveling over is broken, in either direction, simple as that.
114  * It makes managing message transactional states very easy.
115  *
116  *                      MESSAGE TRANSACTIONAL STATES
117  *
118  * Message state is handled by the CREATE, DELETE, REPLY, and ABORT
119  * flags.  Message state is typically recorded at the end points and
120  * at each hop until a DELETE is received from both sides.
121  *
122  * One-way messages such as those used by spanning tree commands are not
123  * recorded.  These are sent without the CREATE, DELETE, or ABORT flags set.
124  * ABORT is not supported for one-off messages.  The REPLY bit can be used
125  * to distinguish between command and status if desired.
126  *
127  * Persistent-state messages are messages which require a reply to be
128  * returned.  These messages can also consist of multiple message elements
129  * for the command or reply or both (or neither).  The command message
130  * sequence sets CREATE on the first message and DELETE on the last message.
131  * A single message command sets both (CREATE|DELETE).  The reply message
132  * sequence works the same way but of course also sets the REPLY bit.
133  *
134  * Persistent-state messages can be aborted by sending a message element
135  * with the ABORT flag set.  This flag can be combined with either or both
136  * the CREATE and DELETE flags.  When combined with the CREATE flag the
137  * command is treated as non-blocking but still executes.  Whem combined
138  * with the DELETE flag no additional message elements are required.
139  *
140  * ABORT SPECIAL CASE - Mid-stream aborts.  A mid-stream abort can be sent
141  * when supported by the sender by sending an ABORT message with neither
142  * CREATE or DELETE set.  This effectively turns the message into a
143  * non-blocking message (but depending on what is being represented can also
144  * cut short prior data elements in the stream).
145  *
146  * ABORT SPECIAL CASE - Abort-after-DELETE.  Persistent messages have to be
147  * abortable if the stream/pipe/whatever is lost.  In this situation any
148  * forwarding relay needs to unconditionally abort commands and replies that
149  * are still active.  This is done by sending an ABORT|DELETE even in
150  * situations where a DELETE has already been sent in that direction.  This
151  * is done, for example, when links are in a half-closed state.  In this
152  * situation it is possible for the abort request to race a transition to the
153  * fully closed state.  ABORT|DELETE messages which race the fully closed
154  * state are expected to be discarded by the other end.
155  *
156  * --
157  *
158  * All base and extended message headers are 64-byte aligned, and all
159  * transports must support extended message headers up to DMSG_HDR_MAX.
160  * Currently we allow extended message headers up to 2048 bytes.  Note
161  * that the extended header size is encoded in the 'cmd' field of the header.
162  *
163  * Any in-band data is padded to a 64-byte alignment and placed directly
164  * after the extended header (after the higher-level cmd/rep structure).
165  * The actual unaligned size of the in-band data is encoded in the aux_bytes
166  * field in this case.  Maximum data sizes are negotiated during registration.
167  *
168  * Auxillary data can be in-band or out-of-band.  In-band data sets aux_descr
169  * equal to 0.  Any out-of-band data must be negotiated by the SPAN protocol.
170  *
171  * Auxillary data, whether in-band or out-of-band, must be at-least 64-byte
172  * aligned.  The aux_bytes field contains the actual byte-granular length
173  * and not the aligned length.
174  *
175  * hdr_crc is calculated over the entire, ALIGNED extended header.  For
176  * the purposes of calculating the crc, the hdr_crc field is 0.  That is,
177  * if calculating the crc in HW a 32-bit '0' must be inserted in place of
178  * the hdr_crc field when reading the entire header and compared at the
179  * end (but the actual hdr_crc must be left intact in memory).  A simple
180  * counter to replace the field going into the CRC generator does the job
181  * in HW.  The CRC endian is based on the magic number field and may have
182  * to be byte-swapped, too (which is also easy to do in HW).
183  *
184  * aux_crc is calculated over the entire, ALIGNED auxillary data.
185  *
186  *                      SHARED MEMORY IMPLEMENTATIONS
187  *
188  * Shared-memory implementations typically use a pipe to transmit the extended
189  * message header and shared memory to store any auxilary data.  Auxillary
190  * data in one-way (non-transactional) messages is typically required to be
191  * inline.  CRCs are still recommended and required at the beginning, but
192  * may be negotiated away later.
193  *
194  *                       MULTI-PATH MESSAGE DUPLICATION
195  *
196  * Redundancy can be negotiated but is not required in the current spec.
197  * Basically you send the same message, with the same msgid, via several
198  * paths to the target.  The msgid is the rendezvous.  The first copy that
199  * makes it to the target is used, the second is ignored.  Similarly for
200  * replies.  This can improve performance during span flapping.  Only
201  * transactional messages will be serialized.  The target might receive
202  * multiple copies of one-way messages in higher protocol layers (potentially
203  * out of order, too).
204  */
205 struct dmsg_hdr {
206         uint16_t        magic;          /* 00 sanity, synchro, endian */
207         uint16_t        reserved02;     /* 02 */
208         uint32_t        salt;           /* 04 random salt helps w/crypto */
209
210         uint64_t        msgid;          /* 08 message transaction id */
211         uint64_t        source;         /* 10 originator or 0   */
212         uint64_t        target;         /* 18 destination or 0  */
213
214         uint32_t        cmd;            /* 20 flags | cmd | hdr_size / ALIGN */
215         uint32_t        aux_crc;        /* 24 auxillary data crc */
216         uint32_t        aux_bytes;      /* 28 auxillary data length (bytes) */
217         uint32_t        error;          /* 2C error code or 0 */
218         uint64_t        aux_descr;      /* 30 negotiated OOB data descr */
219         uint32_t        reserved38;     /* 38 */
220         uint32_t        hdr_crc;        /* 3C (aligned) extended header crc */
221 };
222
223 typedef struct dmsg_hdr dmsg_hdr_t;
224
225 #define DMSG_HDR_MAGIC          0x4832
226 #define DMSG_HDR_MAGIC_REV      0x3248
227 #define DMSG_HDR_CRCOFF         offsetof(dmsg_hdr_t, salt)
228 #define DMSG_HDR_CRCBYTES       (sizeof(dmsg_hdr_t) - DMSG_HDR_CRCOFF)
229
230 /*
231  * Administrative protocol limits.
232  */
233 #define DMSG_HDR_MAX            2048    /* <= 65535 */
234 #define DMSG_AUX_MAX            65536   /* <= 1MB */
235 #define DMSG_BUF_SIZE           (DMSG_HDR_MAX * 4)
236 #define DMSG_BUF_MASK           (DMSG_BUF_SIZE - 1)
237
238 /*
239  * The message (cmd) field also encodes various flags and the total size
240  * of the message header.  This allows the protocol processors to validate
241  * persistency and structural settings for every command simply by
242  * switch()ing on the (cmd) field.
243  */
244 #define DMSGF_CREATE            0x80000000U     /* msg start */
245 #define DMSGF_DELETE            0x40000000U     /* msg end */
246 #define DMSGF_REPLY             0x20000000U     /* reply path */
247 #define DMSGF_ABORT             0x10000000U     /* abort req */
248 #define DMSGF_AUXOOB            0x08000000U     /* aux-data is OOB */
249 #define DMSGF_FLAG2             0x04000000U
250 #define DMSGF_FLAG1             0x02000000U
251 #define DMSGF_FLAG0             0x01000000U
252
253 #define DMSGF_FLAGS             0xFF000000U     /* all flags */
254 #define DMSGF_PROTOS            0x00F00000U     /* all protos */
255 #define DMSGF_CMDS              0x000FFF00U     /* all cmds */
256 #define DMSGF_SIZE              0x000000FFU     /* N*32 */
257
258 #define DMSGF_CMDSWMASK         (DMSGF_CMDS |   \
259                                          DMSGF_SIZE |   \
260                                          DMSGF_PROTOS | \
261                                          DMSGF_REPLY)
262
263 #define DMSGF_BASECMDMASK       (DMSGF_CMDS |   \
264                                          DMSGF_SIZE |   \
265                                          DMSGF_PROTOS)
266
267 #define DMSGF_TRANSMASK         (DMSGF_CMDS |   \
268                                          DMSGF_SIZE |   \
269                                          DMSGF_PROTOS | \
270                                          DMSGF_REPLY |  \
271                                          DMSGF_CREATE | \
272                                          DMSGF_DELETE)
273
274 #define DMSG_PROTO_LNK          0x00000000U
275 #define DMSG_PROTO_DBG          0x00100000U
276 #define DMSG_PROTO_DOM          0x00200000U
277 #define DMSG_PROTO_CAC          0x00300000U
278 #define DMSG_PROTO_QRM          0x00400000U
279 #define DMSG_PROTO_BLK          0x00500000U
280 #define DMSG_PROTO_VOP          0x00600000U
281
282 /*
283  * Message command constructors, sans flags
284  */
285 #define DMSG_ALIGN              64
286 #define DMSG_ALIGNMASK          (DMSG_ALIGN - 1)
287 #define DMSG_DOALIGN(bytes)     (((bytes) + DMSG_ALIGNMASK) &           \
288                                  ~DMSG_ALIGNMASK)
289
290 #define DMSG_HDR_ENCODE(elm)    (((uint32_t)sizeof(struct elm) +        \
291                                   DMSG_ALIGNMASK) /                     \
292                                  DMSG_ALIGN)
293
294 #define DMSG_LNK(cmd, elm)      (DMSG_PROTO_LNK |                       \
295                                          ((cmd) << 8) |                 \
296                                          DMSG_HDR_ENCODE(elm))
297
298 #define DMSG_DBG(cmd, elm)      (DMSG_PROTO_DBG |                       \
299                                          ((cmd) << 8) |                 \
300                                          DMSG_HDR_ENCODE(elm))
301
302 #define DMSG_DOM(cmd, elm)      (DMSG_PROTO_DOM |                       \
303                                          ((cmd) << 8) |                 \
304                                          DMSG_HDR_ENCODE(elm))
305
306 #define DMSG_CAC(cmd, elm)      (DMSG_PROTO_CAC |                       \
307                                          ((cmd) << 8) |                 \
308                                          DMSG_HDR_ENCODE(elm))
309
310 #define DMSG_QRM(cmd, elm)      (DMSG_PROTO_QRM |                       \
311                                          ((cmd) << 8) |                 \
312                                          DMSG_HDR_ENCODE(elm))
313
314 #define DMSG_BLK(cmd, elm)      (DMSG_PROTO_BLK |                       \
315                                          ((cmd) << 8) |                 \
316                                          DMSG_HDR_ENCODE(elm))
317
318 #define DMSG_VOP(cmd, elm)      (DMSG_PROTO_VOP |                       \
319                                          ((cmd) << 8) |                 \
320                                          DMSG_HDR_ENCODE(elm))
321
322 /*
323  * Link layer ops basically talk to just the other side of a direct
324  * connection.
325  *
326  * LNK_PAD      - One-way message on link-0, ignored by target.  Used to
327  *                pad message buffers on shared-memory transports.  Not
328  *                typically used with TCP.
329  *
330  * LNK_PING     - One-way message on link-0, keep-alive, run by both sides
331  *                typically 1/sec on idle link, link is lost after 10 seconds
332  *                of inactivity.
333  *
334  * LNK_AUTH     - Authenticate the connection, negotiate administrative
335  *                rights & encryption, protocol class, etc.  Only PAD and
336  *                AUTH messages (not even PING) are accepted until
337  *                authentication is complete.  This message also identifies
338  *                the host.
339  *
340  * LNK_CONN     - Enable the SPAN protocol on link-0, possibly also installing
341  *                a PFS filter (by cluster id, unique id, and/or wildcarded
342  *                name).
343  *
344  * LNK_SPAN     - A SPAN transaction on link-0 enables messages to be relayed
345  *                to/from a particular cluster node.  SPANs are received,
346  *                sorted, aggregated, and retransmitted back out across all
347  *                applicable connections.
348  *
349  *                The leaf protocol also uses this to make a PFS available
350  *                to the cluster (e.g. on-mount).
351  *
352  * LNK_VOLCONF  - Volume header configuration change.  All hammer2
353  *                connections (hammer2 connect ...) stored in the volume
354  *                header are spammed at the link level to the hammer2
355  *                service daemon, and any live configuration change
356  *                thereafter.
357  */
358 #define DMSG_LNK_PAD            DMSG_LNK(0x000, dmsg_hdr)
359 #define DMSG_LNK_PING           DMSG_LNK(0x001, dmsg_hdr)
360 #define DMSG_LNK_AUTH           DMSG_LNK(0x010, dmsg_lnk_auth)
361 #define DMSG_LNK_CONN           DMSG_LNK(0x011, dmsg_lnk_conn)
362 #define DMSG_LNK_SPAN           DMSG_LNK(0x012, dmsg_lnk_span)
363 #define DMSG_LNK_VOLCONF        DMSG_LNK(0x020, dmsg_lnk_volconf)
364 #define DMSG_LNK_ERROR          DMSG_LNK(0xFFF, dmsg_hdr)
365
366 /*
367  * LNK_CONN - Register connection for SPAN (transaction, left open)
368  *
369  * One LNK_CONN transaction may be opened on a stream connection, registering
370  * the connection with the SPAN subsystem and allowing the subsystem to
371  * accept and relay SPANs to this connection.
372  *
373  * The LNK_CONN message may contain a filter, limiting the desireable SPANs.
374  *
375  * This message contains a lot of the same info that a SPAN message contains,
376  * but is not a SPAN.  That is, without this message the SPAN subprotocol will
377  * not be executed on the connection, nor is this message a promise that the
378  * sending end is a client or node of a cluster.
379  */
380 struct dmsg_lnk_auth {
381         dmsg_hdr_t      head;
382         char            dummy[64];
383 };
384
385 /*
386  * LNK_CONN identifies a streaming connection into the cluster.  The other
387  * fields serve as a filter when supported for a particular peer and are
388  * not necessarily all used.
389  *
390  * peer_mask serves to filter the SPANs we receive by peer.  A cluster
391  * controller typically sets this to (uint64_t)-1, a block devfs
392  * interface might set it to 1 << DMSG_PEER_DISK, and a hammer2
393  * mount might set it to 1 << DMSG_PEER_HAMMER2.
394  *
395  * mediaid allows multiple (e.g. HAMMER2) connections belonging to the same
396  * media, in terms of LNK_VOLCONF updates.
397  *
398  * pfs_clid, pfs_fsid, pfs_type, and label are peer-specific and must be
399  * left empty (zero-fill) if not supported by a particular peer.
400  *
401  * DMSG_PEER_CLUSTER            filter: none
402  * DMSG_PEER_BLOCK              filter: label
403  * DMSG_PEER_HAMMER2            filter: pfs_clid if not empty, and label
404  */
405 struct dmsg_lnk_conn {
406         dmsg_hdr_t      head;
407         uuid_t          mediaid;        /* media configuration id */
408         uuid_t          pfs_clid;       /* rendezvous pfs uuid */
409         uuid_t          pfs_fsid;       /* unique pfs uuid */
410         uint64_t        peer_mask;      /* PEER mask for SPAN filtering */
411         uint8_t         peer_type;      /* see DMSG_PEER_xxx */
412         uint8_t         pfs_type;       /* pfs type */
413         uint16_t        proto_version;  /* high level protocol support */
414         uint32_t        status;         /* status flags */
415         uint8_t         reserved02[8];
416         int32_t         dist;           /* span distance */
417         uint32_t        reserved03[14];
418         char            cl_label[128];  /* cluster label (for PEER_BLOCK) */
419         char            fs_label[128];  /* PFS label (for PEER_HAMMER2) */
420 };
421
422 typedef struct dmsg_lnk_conn dmsg_lnk_conn_t;
423
424 #define DMSG_PFSTYPE_NONE       0
425 #define DMSG_PFSTYPE_ADMIN      1
426 #define DMSG_PFSTYPE_CLIENT     2
427 #define DMSG_PFSTYPE_CACHE      3
428 #define DMSG_PFSTYPE_COPY       4
429 #define DMSG_PFSTYPE_SLAVE      5
430 #define DMSG_PFSTYPE_SOFT_SLAVE 6
431 #define DMSG_PFSTYPE_SOFT_MASTER 7
432 #define DMSG_PFSTYPE_MASTER     8
433 #define DMSG_PFSTYPE_MAX        9       /* 0-8 */
434
435 #define DMSG_PEER_NONE          0
436 #define DMSG_PEER_CLUSTER       1       /* a cluster controller */
437 #define DMSG_PEER_BLOCK         2       /* block devices */
438 #define DMSG_PEER_HAMMER2       3       /* hammer2-mounted volumes */
439
440 /*
441  * LNK_SPAN - Relay a SPAN (transaction, left open)
442  *
443  * This message registers a PFS/PFS_TYPE with the other end of the connection,
444  * telling the other end who we are and what we can provide or what we want
445  * to consume.  Multiple registrations can be maintained as open transactions
446  * with each one specifying a unique {source} linkid.
447  *
448  * Registrations are sent from {source}=S {1...n} to {target}=0 and maintained
449  * as open transactions.  Registrations are also received and maintains as
450  * open transactions, creating a matrix of linkid's.
451  *
452  * While these transactions are open additional transactions can be executed
453  * between any two linkid's {source}=S (registrations we sent) to {target}=T
454  * (registrations we received).
455  *
456  * Closure of any registration transaction will automatically abort any open
457  * transactions using the related linkids.  Closure can be initiated
458  * voluntarily from either side with either end issuing a DELETE, or they
459  * can be ABORTed.
460  *
461  * Status updates are performed via the open transaction.
462  *
463  * --
464  *
465  * A registration identifies a node and its various PFS parameters including
466  * the PFS_TYPE.  For example, a diskless HAMMER2 client typically identifies
467  * itself as PFSTYPE_CLIENT.
468  *
469  * Any node may serve as a cluster controller, aggregating and passing
470  * on received registrations, but end-points do not have to implement this
471  * ability.  Most end-points typically implement a single client-style or
472  * server-style PFS_TYPE and rendezvous at a cluster controller.
473  *
474  * The cluster controller does not aggregate/pass-on all received
475  * registrations.  It typically filters what gets passed on based on
476  * what it receives.
477  *
478  * STATUS UPDATES: Status updates use the same structure but typically
479  *                 only contain incremental changes to pfs_type, with the
480  *                 label field containing a text status.
481  */
482 struct dmsg_lnk_span {
483         dmsg_hdr_t      head;
484         uuid_t          pfs_clid;       /* rendezvous pfs uuid */
485         uuid_t          pfs_fsid;       /* unique pfs uuid */
486         uint8_t         pfs_type;       /* PFS type */
487         uint8_t         peer_type;      /* PEER type */
488         uint16_t        proto_version;  /* high level protocol support */
489         uint32_t        status;         /* status flags */
490         uint8_t         reserved02[8];
491         int32_t         dist;           /* span distance */
492         uint32_t        reserved03[15];
493         char            cl_label[128];  /* cluster label (for PEER_BLOCK) */
494         char            fs_label[128];  /* PFS label (for PEER_HAMMER2) */
495 };
496
497 typedef struct dmsg_lnk_span dmsg_lnk_span_t;
498
499 #define DMSG_SPAN_PROTO_1       1
500
501 /*
502  * LNK_VOLCONF
503  */
504
505 /*
506  * All HAMMER2 directories directly under the super-root on your local
507  * media can be mounted separately, even if they share the same physical
508  * device.
509  *
510  * When you do a HAMMER2 mount you are effectively tying into a HAMMER2
511  * cluster via local media.  The local media does not have to participate
512  * in the cluster, other than to provide the dmsg_vol_data[] array and
513  * root inode for the mount.
514  *
515  * This is important: The mount device path you specify serves to bootstrap
516  * your entry into the cluster, but your mount will make active connections
517  * to ALL copy elements in the dmsg_vol_data[] array which match the
518  * PFSID of the directory in the super-root that you specified.  The local
519  * media path does not have to be mentioned in this array but becomes part
520  * of the cluster based on its type and access rights.  ALL ELEMENTS ARE
521  * TREATED ACCORDING TO TYPE NO MATTER WHICH ONE YOU MOUNT FROM.
522  *
523  * The actual cluster may be far larger than the elements you list in the
524  * dmsg_vol_data[] array.  You list only the elements you wish to
525  * directly connect to and you are able to access the rest of the cluster
526  * indirectly through those connections.
527  *
528  * This structure must be exactly 128 bytes long.
529  *
530  * WARNING!  dmsg_vol_data is embedded in the hammer2 media volume header
531  */
532 struct dmsg_vol_data {
533         uint8_t copyid;         /* 00    copyid 0-255 (must match slot) */
534         uint8_t inprog;         /* 01    operation in progress, or 0 */
535         uint8_t chain_to;       /* 02    operation chaining to, or 0 */
536         uint8_t chain_from;     /* 03    operation chaining from, or 0 */
537         uint16_t flags;         /* 04-05 flags field */
538         uint8_t error;          /* 06    last operational error */
539         uint8_t priority;       /* 07    priority and round-robin flag */
540         uint8_t remote_pfs_type;/* 08    probed direct remote PFS type */
541         uint8_t reserved08[23]; /* 09-1F */
542         uuid_t  pfs_clid;       /* 20-2F copy target must match this uuid */
543         uint8_t label[16];      /* 30-3F import/export label */
544         uint8_t path[64];       /* 40-7F target specification string or key */
545 };
546
547 typedef struct dmsg_vol_data dmsg_vol_data_t;
548
549 #define DMSG_VOLF_ENABLED       0x0001
550 #define DMSG_VOLF_INPROG        0x0002
551 #define DMSG_VOLF_CONN_RR       0x80    /* round-robin at same priority */
552 #define DMSG_VOLF_CONN_EF       0x40    /* media errors flagged */
553 #define DMSG_VOLF_CONN_PRI      0x0F    /* select priority 0-15 (15=best) */
554
555 #define DMSG_COPYID_COUNT       256     /* WARNING! embedded in hammer2 vol */
556
557 struct dmsg_lnk_volconf {
558         dmsg_hdr_t              head;
559         dmsg_vol_data_t         copy;   /* copy spec */
560         int32_t                 index;
561         int32_t                 unused01;
562         uuid_t                  mediaid;
563         int64_t                 reserved02[32];
564 };
565
566 typedef struct dmsg_lnk_volconf dmsg_lnk_volconf_t;
567
568 /*
569  * Debug layer ops operate on any link
570  *
571  * SHELL        - Persist stream, access the debug shell on the target
572  *                registration.  Multiple shells can be operational.
573  */
574 #define DMSG_DBG_SHELL          DMSG_DBG(0x001, dmsg_dbg_shell)
575
576 struct dmsg_dbg_shell {
577         dmsg_hdr_t      head;
578 };
579 typedef struct dmsg_dbg_shell dmsg_dbg_shell_t;
580
581 /*
582  * Domain layer ops operate on any link, link-0 may be used when the
583  * directory connected target is the desired registration.
584  *
585  * (nothing defined)
586  */
587
588 /*
589  * Cache layer ops operate on any link, link-0 may be used when the
590  * directly connected target is the desired registration.
591  *
592  * LOCK         - Persist state, blockable, abortable.
593  *
594  *                Obtain cache state (MODIFIED, EXCLUSIVE, SHARED, or INVAL)
595  *                in any of three domains (TREE, INUM, ATTR, DIRENT) for a
596  *                particular key relative to cache state already owned.
597  *
598  *                TREE - Effects entire sub-tree at the specified element
599  *                       and will cause existing cache state owned by
600  *                       other nodes to be adjusted such that the request
601  *                       can be granted.
602  *
603  *                INUM - Only effects inode creation/deletion of an existing
604  *                       element or a new element, by inumber and/or name.
605  *                       typically can be held for very long periods of time
606  *                       (think the vnode cache), directly relates to
607  *                       hammer2_chain structures representing inodes.
608  *
609  *                ATTR - Only effects an inode's attributes, such as
610  *                       ownership, modes, etc.  Used for lookups, chdir,
611  *                       open, etc.  mtime has no affect.
612  *
613  *                DIRENT - Only affects an inode's attributes plus the
614  *                       attributes or names related to any directory entry
615  *                       directly under this inode (non-recursively).  Can
616  *                       be retained for medium periods of time when doing
617  *                       directory scans.
618  *
619  *                This function may block and can be aborted.  You may be
620  *                granted cache state that is more broad than the state you
621  *                requested (e.g. a different set of domains and/or an element
622  *                at a higher layer in the tree).  When quorum operations
623  *                are used you may have to reconcile these grants to the
624  *                lowest common denominator.
625  *
626  *                In order to grant your request either you or the target
627  *                (or both) may have to obtain a quorum agreement.  Deadlock
628  *                resolution may be required.  When doing it yourself you
629  *                will typically maintain an active message to each master
630  *                node in the system.  You can only grant the cache state
631  *                when a quorum of nodes agree.
632  *
633  *                The cache state includes transaction id information which
634  *                can be used to resolve data requests.
635  */
636 #define DMSG_CAC_LOCK           DMSG_CAC(0x001, dmsg_cac_lock)
637
638 /*
639  * Quorum layer ops operate on any link, link-0 may be used when the
640  * directly connected target is the desired registration.
641  *
642  * COMMIT       - Persist state, blockable, abortable
643  *
644  *                Issue a COMMIT in two phases.  A quorum must acknowledge
645  *                the operation to proceed to phase-2.  Message-update to
646  *                proceed to phase-2.
647  */
648 #define DMSG_QRM_COMMIT         DMSG_QRM(0x001, dmsg_qrm_commit)
649
650 /*
651  * NOTE!!!! ALL EXTENDED HEADER STRUCTURES MUST BE 64-BYTE ALIGNED!!!
652  *
653  * General message errors
654  *
655  *      0x00 - 0x1F     Local iocomm errors
656  *      0x20 - 0x2F     Global errors
657  */
658 #define DMSG_ERR_NOSUPP         0x20
659
660 union dmsg_any {
661         char                    buf[DMSG_HDR_MAX];
662         dmsg_hdr_t              head;
663         dmsg_lnk_span_t         lnk_span;
664         dmsg_lnk_conn_t         lnk_conn;
665         dmsg_lnk_volconf_t      lnk_volconf;
666 };
667
668 typedef union dmsg_any dmsg_any_t;
669
670 /*
671  * Kernel iocom structures and prototypes for kern/kern_dmsg.c
672  */
673 #ifdef _KERNEL
674
675 struct hammer2_pfsmount;
676 struct kdmsg_router;
677 struct kdmsg_iocom;
678 struct kdmsg_state;
679 struct kdmsg_msg;
680
681 /*
682  * Structure used to represent a virtual circuit for a messaging
683  * route.  Typically associated from hammer2_state but the hammer2_pfsmount
684  * structure also has one to represent the point-to-point link.
685  */
686 struct kdmsg_router {
687         struct kdmsg_iocom      *iocom;
688         struct kdmsg_state      *state;         /* received LNK_SPAN state */
689         uint64_t                target;         /* target */
690 };
691
692 typedef struct kdmsg_router kdmsg_router_t;
693
694 /*
695  * msg_ctl flags (atomic)
696  */
697 #define KDMSG_CLUSTERCTL_KILL           0x00000001
698 #define KDMSG_CLUSTERCTL_KILLRX         0x00000002 /* staged helper exit */
699 #define KDMSG_CLUSTERCTL_KILLTX         0x00000004 /* staged helper exit */
700 #define KDMSG_CLUSTERCTL_SLEEPING       0x00000008 /* interlocked w/msglk */
701
702 /*
703  * Transactional state structure, representing an open transaction.  The
704  * transaction might represent a cache state (and thus have a chain
705  * association), or a VOP op, LNK_SPAN, or other things.
706  */
707 struct kdmsg_state {
708         RB_ENTRY(kdmsg_state) rbnode;           /* indexed by msgid */
709         struct kdmsg_router *router;            /* related LNK_SPAN route */
710         uint32_t        txcmd;                  /* mostly for CMDF flags */
711         uint32_t        rxcmd;                  /* mostly for CMDF flags */
712         uint64_t        msgid;                  /* {spanid,msgid} uniq */
713         int             flags;
714         int             error;
715         void            *chain;                 /* (caller's state) */
716         struct kdmsg_msg *msg;
717         int (*func)(struct kdmsg_state *, struct kdmsg_msg *);
718         union {
719                 void *any;
720                 struct hammer2_pfsmount *pmp;
721         } any;
722 };
723
724 #define KDMSG_STATE_INSERTED    0x0001
725 #define KDMSG_STATE_DYNAMIC     0x0002
726 #define KDMSG_STATE_DELPEND     0x0004          /* transmit delete pending */
727
728 struct kdmsg_msg {
729         TAILQ_ENTRY(kdmsg_msg) qentry;          /* serialized queue */
730         struct kdmsg_router *router;
731         struct kdmsg_state *state;
732         size_t          hdr_size;
733         size_t          aux_size;
734         char            *aux_data;
735         dmsg_any_t      any;
736 };
737
738 typedef struct kdmsg_link kdmsg_link_t;
739 typedef struct kdmsg_state kdmsg_state_t;
740 typedef struct kdmsg_msg kdmsg_msg_t;
741
742 struct kdmsg_state_tree;
743 RB_HEAD(kdmsg_state_tree, kdmsg_state);
744 int kdmsg_state_cmp(kdmsg_state_t *state1, kdmsg_state_t *state2);
745 RB_PROTOTYPE(kdmsg_state_tree, kdmsg_state, rbnode, kdmsg_state_cmp);
746
747 /*
748  * Structure embedded in e.g. mount, master control structure for
749  * DMSG stream handling.
750  */
751 struct kdmsg_iocom {
752         struct malloc_type      *mmsg;
753         struct file             *msg_fp;        /* cluster pipe->userland */
754         thread_t                msgrd_td;       /* cluster thread */
755         thread_t                msgwr_td;       /* cluster thread */
756         int                     msg_ctl;        /* wakeup flags */
757         int                     msg_seq;        /* cluster msg sequence id */
758         uint32_t                reserved01;
759         struct lock             msglk;          /* lockmgr lock */
760         TAILQ_HEAD(, kdmsg_msg) msgq;           /* transmit queue */
761         void                    *handle;
762         int                     (*lnk_rcvmsg)(kdmsg_msg_t *msg);
763         int                     (*dbg_rcvmsg)(kdmsg_msg_t *msg);
764         int                     (*misc_rcvmsg)(kdmsg_msg_t *msg);
765         void                    (*exit_func)(struct kdmsg_iocom *);
766         struct kdmsg_state      *conn_state;    /* active LNK_CONN state */
767         struct kdmsg_state      *freerd_state;  /* allocation cache */
768         struct kdmsg_state      *freewr_state;  /* allocation cache */
769         struct kdmsg_state_tree staterd_tree;   /* active messages */
770         struct kdmsg_state_tree statewr_tree;   /* active messages */
771         struct kdmsg_router     router;
772 };
773
774 typedef struct kdmsg_iocom      kdmsg_iocom_t;
775
776 uint32_t kdmsg_icrc32(const void *buf, size_t size);
777 uint32_t kdmsg_icrc32c(const void *buf, size_t size, uint32_t crc);
778
779 /*
780  * kern_dmsg.c
781  */
782 void kdmsg_iocom_init(kdmsg_iocom_t *iocom,
783                         void *handle,
784                         struct malloc_type *mmsg,
785                         int (*lnk_rcvmsg)(kdmsg_msg_t *msg),
786                         int (*dbg_rcvmsg)(kdmsg_msg_t *msg),
787                         int (*misc_rcvmsg)(kdmsg_msg_t *msg));
788 void kdmsg_iocom_reconnect(kdmsg_iocom_t *iocom, struct file *fp,
789                         const char *subsysname);
790 void kdmsg_iocom_uninit(kdmsg_iocom_t *iocom);
791 void kdmsg_drain_msgq(kdmsg_iocom_t *iocom);
792
793 int kdmsg_state_msgrx(kdmsg_msg_t *msg);
794 int kdmsg_state_msgtx(kdmsg_msg_t *msg);
795 void kdmsg_state_cleanuprx(kdmsg_msg_t *msg);
796 void kdmsg_state_cleanuptx(kdmsg_msg_t *msg);
797 int kdmsg_msg_execute(kdmsg_msg_t *msg);
798 void kdmsg_state_free(kdmsg_state_t *state);
799 void kdmsg_msg_free(kdmsg_msg_t *msg);
800 kdmsg_msg_t *kdmsg_msg_alloc(kdmsg_router_t *router, uint32_t cmd,
801                                 int (*func)(kdmsg_state_t *, kdmsg_msg_t *),
802                                 void *data);
803 void kdmsg_msg_write(kdmsg_msg_t *msg);
804 void kdmsg_msg_reply(kdmsg_msg_t *msg, uint32_t error);
805 void kdmsg_msg_result(kdmsg_msg_t *msg, uint32_t error);
806
807 #endif
808
809 #endif