hammer2 - kernel cluster messaging support API 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  *                              CONN 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  * Upon connecting and after authentication, a LNK_CONN transaction is opened
62  * on circuit 0 by both ends.  This configures and enables the SPAN protocol.
63  * The LNK_CONN transaction remains open for the life of the connection.
64  *
65  *                              SPAN PROTOCOL
66  *
67  * Once enabled, termini transmits a representitive LNK_SPAN out all
68  * available connections advertising what it is.  Nodes maintaing multiple
69  * connections will relay received LNK_SPANs out available connections
70  * with some filtering based on the CONN configuration.  A distance metric
71  * and per-node random value (rnss) is aggregated.
72  *
73  * Since LNK_SPANs can rapidly multiply in a complex graph, not all incoming
74  * LNK_SPANs will be relayed.  Only the top N over all collect LNK_SPANs for
75  * any given advertisement are relayed.
76  *
77  * It is possible to code the SPANning tree algorithm to guarantee that
78  * symmetrical spans will be generated after stabilization.  The RNSS field
79  * is used to help distinguish and reduce paths in complex graphs when
80  * symmetric spans are desired.  We always generate RNSS but we currently do
81  * not implement symmetrical SPAN guarantees.
82  *
83  *                              CIRC PROTOCOL
84  *
85  * We aren't done yet.  Before transactions can be relayed, symmetric paths
86  * must be formed via the LNK_CIRC protocol.  The LNK_CIRC protocol
87  * establishes a virtual circuit from any node to any other node, creating
88  * a circuit id which is stored in dmsg_hdr.circuit.  Messages received on
89  * one side or forwarded to the other.  Forwarded messages bypass normal
90  * state tracking.
91  *
92  * A virtual circuit is forged by working the propogated SPANs backwards.
93  * Each node in the graph helps propagate the virtual circuit by attach the
94  * LNK_CIRC transaction it receives to a LNK_CIRC transaction it initiates
95  * out the other interface.
96  *
97  * Since SPANs are link-state transactions any change in related span(s)
98  * will also force-terminate VC's using those spans.
99  *
100  *                      MESSAGE TRANSACTIONAL STATES
101  *
102  * Message state is handled by the CREATE, DELETE, REPLY, and ABORT
103  * flags.  Message state is typically recorded at the end points and
104  * at each hop until a DELETE is received from both sides.
105  *
106  * One-way messages such as those used by spanning tree commands are not
107  * recorded.  These are sent without the CREATE, DELETE, or ABORT flags set.
108  * ABORT is not supported for one-off messages.  The REPLY bit can be used
109  * to distinguish between command and status if desired.
110  *
111  * Persistent-state messages are messages which require a reply to be
112  * returned.  These messages can also consist of multiple message elements
113  * for the command or reply or both (or neither).  The command message
114  * sequence sets CREATE on the first message and DELETE on the last message.
115  * A single message command sets both (CREATE|DELETE).  The reply message
116  * sequence works the same way but of course also sets the REPLY bit.
117  *
118  * Persistent-state messages can be aborted by sending a message element
119  * with the ABORT flag set.  This flag can be combined with either or both
120  * the CREATE and DELETE flags.  When combined with the CREATE flag the
121  * command is treated as non-blocking but still executes.  Whem combined
122  * with the DELETE flag no additional message elements are required.
123  *
124  * ABORT SPECIAL CASE - Mid-stream aborts.  A mid-stream abort can be sent
125  * when supported by the sender by sending an ABORT message with neither
126  * CREATE or DELETE set.  This effectively turns the message into a
127  * non-blocking message (but depending on what is being represented can also
128  * cut short prior data elements in the stream).
129  *
130  * ABORT SPECIAL CASE - Abort-after-DELETE.  Persistent messages have to be
131  * abortable if the stream/pipe/whatever is lost.  In this situation any
132  * forwarding relay needs to unconditionally abort commands and replies that
133  * are still active.  This is done by sending an ABORT|DELETE even in
134  * situations where a DELETE has already been sent in that direction.  This
135  * is done, for example, when links are in a half-closed state.  In this
136  * situation it is possible for the abort request to race a transition to the
137  * fully closed state.  ABORT|DELETE messages which race the fully closed
138  * state are expected to be discarded by the other end.
139  *
140  * --
141  *
142  * All base and extended message headers are 64-byte aligned, and all
143  * transports must support extended message headers up to DMSG_HDR_MAX.
144  * Currently we allow extended message headers up to 2048 bytes.  Note
145  * that the extended header size is encoded in the 'cmd' field of the header.
146  *
147  * Any in-band data is padded to a 64-byte alignment and placed directly
148  * after the extended header (after the higher-level cmd/rep structure).
149  * The actual unaligned size of the in-band data is encoded in the aux_bytes
150  * field in this case.  Maximum data sizes are negotiated during registration.
151  *
152  * Auxillary data can be in-band or out-of-band.  In-band data sets aux_descr
153  * equal to 0.  Any out-of-band data must be negotiated by the SPAN protocol.
154  *
155  * Auxillary data, whether in-band or out-of-band, must be at-least 64-byte
156  * aligned.  The aux_bytes field contains the actual byte-granular length
157  * and not the aligned length.
158  *
159  * hdr_crc is calculated over the entire, ALIGNED extended header.  For
160  * the purposes of calculating the crc, the hdr_crc field is 0.  That is,
161  * if calculating the crc in HW a 32-bit '0' must be inserted in place of
162  * the hdr_crc field when reading the entire header and compared at the
163  * end (but the actual hdr_crc must be left intact in memory).  A simple
164  * counter to replace the field going into the CRC generator does the job
165  * in HW.  The CRC endian is based on the magic number field and may have
166  * to be byte-swapped, too (which is also easy to do in HW).
167  *
168  * aux_crc is calculated over the entire, ALIGNED auxillary data.
169  *
170  *                      SHARED MEMORY IMPLEMENTATIONS
171  *
172  * Shared-memory implementations typically use a pipe to transmit the extended
173  * message header and shared memory to store any auxilary data.  Auxillary
174  * data in one-way (non-transactional) messages is typically required to be
175  * inline.  CRCs are still recommended and required at the beginning, but
176  * may be negotiated away later.
177  */
178 struct dmsg_hdr {
179         uint16_t        magic;          /* 00 sanity, synchro, endian */
180         uint16_t        reserved02;     /* 02 */
181         uint32_t        salt;           /* 04 random salt helps w/crypto */
182
183         uint64_t        msgid;          /* 08 message transaction id */
184         uint64_t        circuit;        /* 10 circuit id or 0   */
185         uint64_t        reserved18;     /* 18 */
186
187         uint32_t        cmd;            /* 20 flags | cmd | hdr_size / ALIGN */
188         uint32_t        aux_crc;        /* 24 auxillary data crc */
189         uint32_t        aux_bytes;      /* 28 auxillary data length (bytes) */
190         uint32_t        error;          /* 2C error code or 0 */
191         uint64_t        aux_descr;      /* 30 negotiated OOB data descr */
192         uint32_t        reserved38;     /* 38 */
193         uint32_t        hdr_crc;        /* 3C (aligned) extended header crc */
194 };
195
196 typedef struct dmsg_hdr dmsg_hdr_t;
197
198 #define DMSG_HDR_MAGIC          0x4832
199 #define DMSG_HDR_MAGIC_REV      0x3248
200 #define DMSG_HDR_CRCOFF         offsetof(dmsg_hdr_t, salt)
201 #define DMSG_HDR_CRCBYTES       (sizeof(dmsg_hdr_t) - DMSG_HDR_CRCOFF)
202
203 /*
204  * Administrative protocol limits.
205  */
206 #define DMSG_HDR_MAX            2048    /* <= 65535 */
207 #define DMSG_AUX_MAX            65536   /* <= 1MB */
208 #define DMSG_BUF_SIZE           (DMSG_HDR_MAX * 4)
209 #define DMSG_BUF_MASK           (DMSG_BUF_SIZE - 1)
210
211 /*
212  * The message (cmd) field also encodes various flags and the total size
213  * of the message header.  This allows the protocol processors to validate
214  * persistency and structural settings for every command simply by
215  * switch()ing on the (cmd) field.
216  */
217 #define DMSGF_CREATE            0x80000000U     /* msg start */
218 #define DMSGF_DELETE            0x40000000U     /* msg end */
219 #define DMSGF_REPLY             0x20000000U     /* reply path */
220 #define DMSGF_ABORT             0x10000000U     /* abort req */
221 #define DMSGF_AUXOOB            0x08000000U     /* aux-data is OOB */
222 #define DMSGF_FLAG2             0x04000000U
223 #define DMSGF_FLAG1             0x02000000U
224 #define DMSGF_FLAG0             0x01000000U
225
226 #define DMSGF_FLAGS             0xFF000000U     /* all flags */
227 #define DMSGF_PROTOS            0x00F00000U     /* all protos */
228 #define DMSGF_CMDS              0x000FFF00U     /* all cmds */
229 #define DMSGF_SIZE              0x000000FFU     /* N*32 */
230
231 #define DMSGF_CMDSWMASK         (DMSGF_CMDS |   \
232                                          DMSGF_SIZE |   \
233                                          DMSGF_PROTOS | \
234                                          DMSGF_REPLY)
235
236 #define DMSGF_BASECMDMASK       (DMSGF_CMDS |   \
237                                          DMSGF_SIZE |   \
238                                          DMSGF_PROTOS)
239
240 #define DMSGF_TRANSMASK         (DMSGF_CMDS |   \
241                                          DMSGF_SIZE |   \
242                                          DMSGF_PROTOS | \
243                                          DMSGF_REPLY |  \
244                                          DMSGF_CREATE | \
245                                          DMSGF_DELETE)
246
247 #define DMSG_PROTO_LNK          0x00000000U
248 #define DMSG_PROTO_DBG          0x00100000U
249 #define DMSG_PROTO_DOM          0x00200000U
250 #define DMSG_PROTO_CAC          0x00300000U
251 #define DMSG_PROTO_QRM          0x00400000U
252 #define DMSG_PROTO_BLK          0x00500000U
253 #define DMSG_PROTO_VOP          0x00600000U
254
255 /*
256  * Message command constructors, sans flags
257  */
258 #define DMSG_ALIGN              64
259 #define DMSG_ALIGNMASK          (DMSG_ALIGN - 1)
260 #define DMSG_DOALIGN(bytes)     (((bytes) + DMSG_ALIGNMASK) &           \
261                                  ~DMSG_ALIGNMASK)
262
263 #define DMSG_HDR_ENCODE(elm)    (((uint32_t)sizeof(struct elm) +        \
264                                   DMSG_ALIGNMASK) /                     \
265                                  DMSG_ALIGN)
266
267 #define DMSG_LNK(cmd, elm)      (DMSG_PROTO_LNK |                       \
268                                          ((cmd) << 8) |                 \
269                                          DMSG_HDR_ENCODE(elm))
270
271 #define DMSG_DBG(cmd, elm)      (DMSG_PROTO_DBG |                       \
272                                          ((cmd) << 8) |                 \
273                                          DMSG_HDR_ENCODE(elm))
274
275 #define DMSG_DOM(cmd, elm)      (DMSG_PROTO_DOM |                       \
276                                          ((cmd) << 8) |                 \
277                                          DMSG_HDR_ENCODE(elm))
278
279 #define DMSG_CAC(cmd, elm)      (DMSG_PROTO_CAC |                       \
280                                          ((cmd) << 8) |                 \
281                                          DMSG_HDR_ENCODE(elm))
282
283 #define DMSG_QRM(cmd, elm)      (DMSG_PROTO_QRM |                       \
284                                          ((cmd) << 8) |                 \
285                                          DMSG_HDR_ENCODE(elm))
286
287 #define DMSG_BLK(cmd, elm)      (DMSG_PROTO_BLK |                       \
288                                          ((cmd) << 8) |                 \
289                                          DMSG_HDR_ENCODE(elm))
290
291 #define DMSG_VOP(cmd, elm)      (DMSG_PROTO_VOP |                       \
292                                          ((cmd) << 8) |                 \
293                                          DMSG_HDR_ENCODE(elm))
294
295 /*
296  * Link layer ops basically talk to just the other side of a direct
297  * connection.
298  *
299  * LNK_PAD      - One-way message on circuit 0, ignored by target.  Used to
300  *                pad message buffers on shared-memory transports.  Not
301  *                typically used with TCP.
302  *
303  * LNK_PING     - One-way message on circuit-0, keep-alive, run by both sides
304  *                typically 1/sec on idle link, link is lost after 10 seconds
305  *                of inactivity.
306  *
307  * LNK_AUTH     - Authenticate the connection, negotiate administrative
308  *                rights & encryption, protocol class, etc.  Only PAD and
309  *                AUTH messages (not even PING) are accepted until
310  *                authentication is complete.  This message also identifies
311  *                the host.
312  *
313  * LNK_CONN     - Enable the SPAN protocol on circuit-0, possibly also
314  *                installing a PFS filter (by cluster id, unique id, and/or
315  *                wildcarded name).
316  *
317  * LNK_SPAN     - A SPAN transaction on circuit-0 enables messages to be
318  *                relayed to/from a particular cluster node.  SPANs are
319  *                received, sorted, aggregated, filtered, and retransmitted
320  *                back out across all applicable connections.
321  *
322  *                The leaf protocol also uses this to make a PFS available
323  *                to the cluster (e.g. on-mount).
324  *
325  * LNK_CIRC     - a CIRC transaction establishes a circuit from source to
326  *                target by creating pairs of open transactions across each
327  *                hop.
328  *
329  * LNK_VOLCONF  - Volume header configuration change.  All hammer2
330  *                connections (hammer2 connect ...) stored in the volume
331  *                header are spammed on circuit 0 to the hammer2
332  *                service daemon, and any live configuration change
333  *                thereafter.
334  */
335 #define DMSG_LNK_PAD            DMSG_LNK(0x000, dmsg_hdr)
336 #define DMSG_LNK_PING           DMSG_LNK(0x001, dmsg_hdr)
337 #define DMSG_LNK_AUTH           DMSG_LNK(0x010, dmsg_lnk_auth)
338 #define DMSG_LNK_CONN           DMSG_LNK(0x011, dmsg_lnk_conn)
339 #define DMSG_LNK_SPAN           DMSG_LNK(0x012, dmsg_lnk_span)
340 #define DMSG_LNK_CIRC           DMSG_LNK(0x013, dmsg_lnk_circ)
341 #define DMSG_LNK_VOLCONF        DMSG_LNK(0x020, dmsg_lnk_volconf)
342 #define DMSG_LNK_ERROR          DMSG_LNK(0xFFF, dmsg_hdr)
343
344 /*
345  * LNK_AUTH - Authentication (often omitted)
346  */
347 struct dmsg_lnk_auth {
348         dmsg_hdr_t      head;
349         char            dummy[64];
350 };
351
352 /*
353  * LNK_CONN - Register connection info for SPAN protocol
354  *            (transaction, left open, circuit 0 only).
355  *
356  * LNK_CONN identifies a streaming connection into the cluster and serves
357  * to identify, enable, and specify filters for the SPAN protocol.
358  *
359  * peer_mask serves to filter the SPANs we receive by peer_type.  A cluster
360  * controller typically sets this to (uint64_t)-1, indicating that it wants
361  * everything.  A block devfs interface might set it to 1 << DMSG_PEER_DISK,
362  * and a hammer2 mount might set it to 1 << DMSG_PEER_HAMMER2.
363  *
364  * mediaid allows multiple (e.g. HAMMER2) connections belonging to the same
365  * media to transmit duplicative LNK_VOLCONF updates without causing
366  * confusion in the cluster controller.
367  *
368  * pfs_clid, pfs_fsid, pfs_type, and label are peer-specific and must be
369  * left empty (zero-fill) if not supported by a particular peer.
370  *
371  * DMSG_PEER_CLUSTER            filter: none
372  * DMSG_PEER_BLOCK              filter: label
373  * DMSG_PEER_HAMMER2            filter: pfs_clid if not empty, and label
374  */
375 struct dmsg_lnk_conn {
376         dmsg_hdr_t      head;
377         uuid_t          mediaid;        /* media configuration id */
378         uuid_t          pfs_clid;       /* rendezvous pfs uuid */
379         uuid_t          pfs_fsid;       /* unique pfs uuid */
380         uint64_t        peer_mask;      /* PEER mask for SPAN filtering */
381         uint8_t         peer_type;      /* see DMSG_PEER_xxx */
382         uint8_t         pfs_type;       /* pfs type */
383         uint16_t        proto_version;  /* high level protocol support */
384         uint32_t        status;         /* status flags */
385         uint32_t        rnss;           /* node's generated rnss */
386         uint8_t         reserved02[8];
387         uint32_t        reserved03[12];
388         uint64_t        pfs_mask;       /* PFS mask for SPAN filtering */
389         char            cl_label[128];  /* cluster label (for PEER_BLOCK) */
390         char            fs_label[128];  /* PFS label (for PEER_HAMMER2) */
391 };
392
393 typedef struct dmsg_lnk_conn dmsg_lnk_conn_t;
394
395 #define DMSG_PFSTYPE_NONE       0
396 #define DMSG_PFSTYPE_ADMIN      1
397 #define DMSG_PFSTYPE_CLIENT     2
398 #define DMSG_PFSTYPE_CACHE      3
399 #define DMSG_PFSTYPE_COPY       4
400 #define DMSG_PFSTYPE_SLAVE      5
401 #define DMSG_PFSTYPE_SOFT_SLAVE 6
402 #define DMSG_PFSTYPE_SOFT_MASTER 7
403 #define DMSG_PFSTYPE_MASTER     8
404 #define DMSG_PFSTYPE_SERVER     9
405 #define DMSG_PFSTYPE_MAX        10      /* 0-9 */
406
407 #define DMSG_PEER_NONE          0
408 #define DMSG_PEER_CLUSTER       1       /* a cluster controller */
409 #define DMSG_PEER_BLOCK         2       /* block devices */
410 #define DMSG_PEER_HAMMER2       3       /* hammer2-mounted volumes */
411
412 /*
413  * Structures embedded in LNK_SPAN
414  */
415 struct dmsg_media_block {
416         uint64_t        bytes;          /* media size in bytes */
417         uint32_t        blksize;        /* media block size */
418 };
419
420 typedef struct dmsg_media_block dmsg_media_block_t;
421
422 /*
423  * LNK_SPAN - Initiate or relay a SPAN
424  *            (transaction, left open, circuit 0 only)
425  *
426  * This message registers an end-point with the other end of the connection,
427  * telling the other end who we are and what we can provide or intend to
428  * consume.  Multiple registrations can be maintained as open transactions
429  * with each one specifying a unique end-point.
430  *
431  * Registrations are sent from {source}=S {1...n} to {target}=0 and maintained
432  * as open transactions.  Registrations are also received and maintains as
433  * open transactions, creating a matrix of linkid's.
434  *
435  * While these transactions are open additional transactions can be executed
436  * between any two linkid's {source}=S (registrations we sent) to {target}=T
437  * (registrations we received).
438  *
439  * Closure of any registration transaction will automatically abort any open
440  * transactions using the related linkids.  Closure can be initiated
441  * voluntarily from either side with either end issuing a DELETE, or they
442  * can be ABORTed.
443  *
444  * Status updates are performed via the open transaction.
445  *
446  * --
447  *
448  * A registration identifies a node and its various PFS parameters including
449  * the PFS_TYPE.  For example, a diskless HAMMER2 client typically identifies
450  * itself as PFSTYPE_CLIENT.
451  *
452  * Any node may serve as a cluster controller, aggregating and passing
453  * on received registrations, but end-points do not have to implement this
454  * ability.  Most end-points typically implement a single client-style or
455  * server-style PFS_TYPE and rendezvous at a cluster controller.
456  *
457  * The cluster controller does not aggregate/pass-on all received
458  * registrations.  It typically filters what gets passed on based on what it
459  * receives, passing on only the best candidates.
460  *
461  * If a symmetric spanning tree is desired additional candidates whos
462  * {dist, rnss} fields match the last best candidate must also be propagated.
463  * This feature is not currently enabled.
464  *
465  * STATUS UPDATES: Status updates use the same structure but typically
466  *                 only contain incremental changes to e.g. pfs_type, with
467  *                 a text description sent as out-of-band data.
468  */
469 struct dmsg_lnk_span {
470         dmsg_hdr_t      head;
471         uuid_t          pfs_clid;       /* rendezvous pfs uuid */
472         uuid_t          pfs_fsid;       /* unique pfs id (differentiate node) */
473         uint8_t         pfs_type;       /* PFS type */
474         uint8_t         peer_type;      /* PEER type */
475         uint16_t        proto_version;  /* high level protocol support */
476         uint32_t        status;         /* status flags */
477         uint8_t         reserved02[8];
478         uint32_t        dist;           /* span distance */
479         uint32_t        rnss;           /* random number sub-sort */
480         union {
481                 uint32_t        reserved03[14];
482                 dmsg_media_block_t block;
483         } media;
484
485         /*
486          * NOTE: for PEER_HAMMER2 cl_label is typically empty and fs_label
487          *       is the superroot directory name.
488          *
489          *       for PEER_BLOCK cl_label is typically host/device and
490          *       fs_label is typically the serial number string.
491          */
492         char            cl_label[128];  /* cluster label */
493         char            fs_label[128];  /* PFS label */
494 };
495
496 typedef struct dmsg_lnk_span dmsg_lnk_span_t;
497
498 #define DMSG_SPAN_PROTO_1       1
499
500 /*
501  * LNK_CIRC - Establish a circuit
502  *            (transaction, left open, circuit 0 only)
503  *
504  * Establish a circuit to the specified target.  The msgid for the open
505  * transaction is used to transit messages in both directions.
506  *
507  * For circuit establishment the receiving entity looks up the outgoing
508  * relayed SPAN on the incoming iocom based on the target field and then
509  * creates peer circuit on the interface the SPAN originally came in on.
510  * Messages received on one side or forwarded to the other side and vise-versa.
511  * Any link state loss causes all related circuits to be lost.
512  */
513 struct dmsg_lnk_circ {
514         dmsg_hdr_t      head;
515         uint64_t        reserved01;
516         uint64_t        target;
517 };
518
519 typedef struct dmsg_lnk_circ dmsg_lnk_circ_t;
520
521 /*
522  * LNK_VOLCONF
523  *
524  * All HAMMER2 directories directly under the super-root on your local
525  * media can be mounted separately, even if they share the same physical
526  * device.
527  *
528  * When you do a HAMMER2 mount you are effectively tying into a HAMMER2
529  * cluster via local media.  The local media does not have to participate
530  * in the cluster, other than to provide the dmsg_vol_data[] array and
531  * root inode for the mount.
532  *
533  * This is important: The mount device path you specify serves to bootstrap
534  * your entry into the cluster, but your mount will make active connections
535  * to ALL copy elements in the dmsg_vol_data[] array which match the
536  * PFSID of the directory in the super-root that you specified.  The local
537  * media path does not have to be mentioned in this array but becomes part
538  * of the cluster based on its type and access rights.  ALL ELEMENTS ARE
539  * TREATED ACCORDING TO TYPE NO MATTER WHICH ONE YOU MOUNT FROM.
540  *
541  * The actual cluster may be far larger than the elements you list in the
542  * dmsg_vol_data[] array.  You list only the elements you wish to
543  * directly connect to and you are able to access the rest of the cluster
544  * indirectly through those connections.
545  *
546  * This structure must be exactly 128 bytes long.
547  *
548  * WARNING!  dmsg_vol_data is embedded in the hammer2 media volume header
549  */
550 struct dmsg_vol_data {
551         uint8_t copyid;         /* 00    copyid 0-255 (must match slot) */
552         uint8_t inprog;         /* 01    operation in progress, or 0 */
553         uint8_t chain_to;       /* 02    operation chaining to, or 0 */
554         uint8_t chain_from;     /* 03    operation chaining from, or 0 */
555         uint16_t flags;         /* 04-05 flags field */
556         uint8_t error;          /* 06    last operational error */
557         uint8_t priority;       /* 07    priority and round-robin flag */
558         uint8_t remote_pfs_type;/* 08    probed direct remote PFS type */
559         uint8_t reserved08[23]; /* 09-1F */
560         uuid_t  pfs_clid;       /* 20-2F copy target must match this uuid */
561         uint8_t label[16];      /* 30-3F import/export label */
562         uint8_t path[64];       /* 40-7F target specification string or key */
563 };
564
565 typedef struct dmsg_vol_data dmsg_vol_data_t;
566
567 #define DMSG_VOLF_ENABLED       0x0001
568 #define DMSG_VOLF_INPROG        0x0002
569 #define DMSG_VOLF_CONN_RR       0x80    /* round-robin at same priority */
570 #define DMSG_VOLF_CONN_EF       0x40    /* media errors flagged */
571 #define DMSG_VOLF_CONN_PRI      0x0F    /* select priority 0-15 (15=best) */
572
573 #define DMSG_COPYID_COUNT       256     /* WARNING! embedded in hammer2 vol */
574
575 struct dmsg_lnk_volconf {
576         dmsg_hdr_t              head;
577         dmsg_vol_data_t         copy;   /* copy spec */
578         int32_t                 index;
579         int32_t                 unused01;
580         uuid_t                  mediaid;
581         int64_t                 reserved02[32];
582 };
583
584 typedef struct dmsg_lnk_volconf dmsg_lnk_volconf_t;
585
586 /*
587  * Debug layer ops operate on any link
588  *
589  * SHELL        - Persist stream, access the debug shell on the target
590  *                registration.  Multiple shells can be operational.
591  */
592 #define DMSG_DBG_SHELL          DMSG_DBG(0x001, dmsg_dbg_shell)
593
594 struct dmsg_dbg_shell {
595         dmsg_hdr_t      head;
596 };
597 typedef struct dmsg_dbg_shell dmsg_dbg_shell_t;
598
599 /*
600  * Domain layer ops operate on any link, link-0 may be used when the
601  * directory connected target is the desired registration.
602  *
603  * (nothing defined)
604  */
605
606 /*
607  * Cache layer ops operate on any link, link-0 may be used when the
608  * directly connected target is the desired registration.
609  *
610  * LOCK         - Persist state, blockable, abortable.
611  *
612  *                Obtain cache state (MODIFIED, EXCLUSIVE, SHARED, or INVAL)
613  *                in any of three domains (TREE, INUM, ATTR, DIRENT) for a
614  *                particular key relative to cache state already owned.
615  *
616  *                TREE - Effects entire sub-tree at the specified element
617  *                       and will cause existing cache state owned by
618  *                       other nodes to be adjusted such that the request
619  *                       can be granted.
620  *
621  *                INUM - Only effects inode creation/deletion of an existing
622  *                       element or a new element, by inumber and/or name.
623  *                       typically can be held for very long periods of time
624  *                       (think the vnode cache), directly relates to
625  *                       hammer2_chain structures representing inodes.
626  *
627  *                ATTR - Only effects an inode's attributes, such as
628  *                       ownership, modes, etc.  Used for lookups, chdir,
629  *                       open, etc.  mtime has no affect.
630  *
631  *                DIRENT - Only affects an inode's attributes plus the
632  *                       attributes or names related to any directory entry
633  *                       directly under this inode (non-recursively).  Can
634  *                       be retained for medium periods of time when doing
635  *                       directory scans.
636  *
637  *                This function may block and can be aborted.  You may be
638  *                granted cache state that is more broad than the state you
639  *                requested (e.g. a different set of domains and/or an element
640  *                at a higher layer in the tree).  When quorum operations
641  *                are used you may have to reconcile these grants to the
642  *                lowest common denominator.
643  *
644  *                In order to grant your request either you or the target
645  *                (or both) may have to obtain a quorum agreement.  Deadlock
646  *                resolution may be required.  When doing it yourself you
647  *                will typically maintain an active message to each master
648  *                node in the system.  You can only grant the cache state
649  *                when a quorum of nodes agree.
650  *
651  *                The cache state includes transaction id information which
652  *                can be used to resolve data requests.
653  */
654 #define DMSG_CAC_LOCK           DMSG_CAC(0x001, dmsg_cac_lock)
655
656 /*
657  * Quorum layer ops operate on any link, link-0 may be used when the
658  * directly connected target is the desired registration.
659  *
660  * COMMIT       - Persist state, blockable, abortable
661  *
662  *                Issue a COMMIT in two phases.  A quorum must acknowledge
663  *                the operation to proceed to phase-2.  Message-update to
664  *                proceed to phase-2.
665  */
666 #define DMSG_QRM_COMMIT         DMSG_QRM(0x001, dmsg_qrm_commit)
667
668 /*
669  * DMSG_PROTO_BLK Protocol
670  *
671  * BLK_OPEN     - Open device.  This transaction must be left open for the
672  *                duration and the returned keyid passed in all associated
673  *                BLK commands.
674  *
675  * BLK_READ     - Strategy read
676  *
677  * BLK_WRITE    - Strategy write
678  *
679  * BLK_FLUSH    - Strategy flush
680  */
681 #define DMSG_BLK_OPEN           DMSG_BLK(0x001, dmsg_blk_open)
682 #define DMSG_BLK_READ           DMSG_BLK(0x002, dmsg_blk_read)
683 #define DMSG_BLK_WRITE          DMSG_BLK(0x003, dmsg_blk_write)
684 #define DMSG_BLK_FLUSH          DMSG_BLK(0x004, dmsg_blk_flush)
685 #define DMSG_BLK_FREEBLKS       DMSG_BLK(0x005, dmsg_blk_freeblks)
686 #define DMSG_BLK_ERROR          DMSG_BLK(0xFFF, dmsg_blk_error)
687
688 struct dmsg_blk_open {
689         dmsg_hdr_t      head;
690         uint32_t        modes;
691         uint32_t        reserved01;
692 };
693
694 #define DMSG_BLKOPEN_RD         0x0001
695 #define DMSG_BLKOPEN_WR         0x0002
696
697 /*
698  * DMSG_LNK_ERROR is returned for simple results,
699  * DMSG_BLK_ERROR is returned for extended results.
700  */
701 struct dmsg_blk_error {
702         dmsg_hdr_t      head;
703         uint64_t        keyid;
704         uint32_t        resid;
705         uint32_t        reserved02;
706         char            buf[64];
707 };
708
709 struct dmsg_blk_read {
710         dmsg_hdr_t      head;
711         uint64_t        keyid;
712         uint64_t        offset;
713         uint32_t        bytes;
714         uint32_t        flags;
715         uint32_t        reserved01;
716         uint32_t        reserved02;
717 };
718
719 struct dmsg_blk_write {
720         dmsg_hdr_t      head;
721         uint64_t        keyid;
722         uint64_t        offset;
723         uint32_t        bytes;
724         uint32_t        flags;
725         uint32_t        reserved01;
726         uint32_t        reserved02;
727 };
728
729 struct dmsg_blk_flush {
730         dmsg_hdr_t      head;
731         uint64_t        keyid;
732         uint64_t        offset;
733         uint32_t        bytes;
734         uint32_t        flags;
735         uint32_t        reserved01;
736         uint32_t        reserved02;
737 };
738
739 struct dmsg_blk_freeblks {
740         dmsg_hdr_t      head;
741         uint64_t        keyid;
742         uint64_t        offset;
743         uint32_t        bytes;
744         uint32_t        flags;
745         uint32_t        reserved01;
746         uint32_t        reserved02;
747 };
748
749 typedef struct dmsg_blk_open            dmsg_blk_open_t;
750 typedef struct dmsg_blk_read            dmsg_blk_read_t;
751 typedef struct dmsg_blk_write           dmsg_blk_write_t;
752 typedef struct dmsg_blk_flush           dmsg_blk_flush_t;
753 typedef struct dmsg_blk_freeblks        dmsg_blk_freeblks_t;
754 typedef struct dmsg_blk_error           dmsg_blk_error_t;
755
756 /*
757  * NOTE!!!! ALL EXTENDED HEADER STRUCTURES MUST BE 64-BYTE ALIGNED!!!
758  *
759  * General message errors
760  *
761  *      0x00 - 0x1F     Local iocomm errors
762  *      0x20 - 0x2F     Global errors
763  */
764 #define DMSG_ERR_NOSUPP         0x20
765 #define DMSG_ERR_LOSTLINK       0x21
766
767 union dmsg_any {
768         char                    buf[DMSG_HDR_MAX];
769         dmsg_hdr_t              head;
770
771         dmsg_lnk_conn_t         lnk_conn;
772         dmsg_lnk_span_t         lnk_span;
773         dmsg_lnk_circ_t         lnk_circ;
774         dmsg_lnk_volconf_t      lnk_volconf;
775
776         dmsg_blk_open_t         blk_open;
777         dmsg_blk_error_t        blk_error;
778         dmsg_blk_read_t         blk_read;
779         dmsg_blk_write_t        blk_write;
780         dmsg_blk_flush_t        blk_flush;
781         dmsg_blk_freeblks_t     blk_freeblks;
782 };
783
784 typedef union dmsg_any dmsg_any_t;
785
786 /*
787  * Kernel iocom structures and prototypes for kern/kern_dmsg.c
788  */
789 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
790
791 struct hammer2_pfsmount;
792 struct kdmsg_iocom;
793 struct kdmsg_state;
794 struct kdmsg_msg;
795
796 /*
797  * msg_ctl flags (atomic)
798  */
799 #define KDMSG_CLUSTERCTL_KILL           0x00000001
800 #define KDMSG_CLUSTERCTL_KILLRX         0x00000002 /* staged helper exit */
801 #define KDMSG_CLUSTERCTL_KILLTX         0x00000004 /* staged helper exit */
802 #define KDMSG_CLUSTERCTL_SLEEPING       0x00000008 /* interlocked w/msglk */
803
804 /*
805  * When the KDMSG_IOCOMF_AUTOCIRC flag is set the kdmsg code in
806  * the kernel automatically tries to forge a virtual circuit for
807  * any active SPAN state received.
808  *
809  * This is only done when the received SPANs are significantly filtered
810  * by the transmitted LNK_CONN.  That is, it is done only by clients who
811  * connect to specific services over the cluster.
812  */
813 struct kdmsg_circuit {
814         TAILQ_ENTRY(kdmsg_circuit) entry;
815         struct kdmsg_iocom      *iocom;
816         struct kdmsg_state      *span_state;
817         struct kdmsg_state      *circ_state;
818         int                     recorded;       /* used by shim */
819         int                     weight;
820 };
821
822 typedef struct kdmsg_circuit kdmsg_circuit_t;
823
824 /*
825  * Transactional state structure, representing an open transaction.  The
826  * transaction might represent a cache state (and thus have a chain
827  * association), or a VOP op, LNK_SPAN, or other things.
828  */
829 struct kdmsg_state {
830         RB_ENTRY(kdmsg_state) rbnode;           /* indexed by msgid */
831         struct kdmsg_iocom *iocom;
832         uint64_t        circuit;
833         uint32_t        icmd;                   /* record cmd creating state */
834         uint32_t        txcmd;                  /* mostly for CMDF flags */
835         uint32_t        rxcmd;                  /* mostly for CMDF flags */
836         uint64_t        msgid;                  /* {circuit,msgid} uniq */
837         int             flags;
838         int             error;
839         void            *chain;                 /* (caller's state) */
840         struct kdmsg_msg *msg;
841         int (*func)(struct kdmsg_state *, struct kdmsg_msg *);
842         union {
843                 void *any;
844                 struct hammer2_pfsmount *pmp;
845                 struct kdmsg_circuit *circ;
846         } any;
847 };
848
849 #define KDMSG_STATE_INSERTED    0x0001
850 #define KDMSG_STATE_DYNAMIC     0x0002
851 #define KDMSG_STATE_DELPEND     0x0004          /* transmit delete pending */
852
853 struct kdmsg_msg {
854         TAILQ_ENTRY(kdmsg_msg) qentry;          /* serialized queue */
855         struct kdmsg_iocom *iocom;
856         struct kdmsg_state *state;
857         size_t          hdr_size;
858         size_t          aux_size;
859         char            *aux_data;
860         int             flags;
861         dmsg_any_t      any;
862 };
863
864 #define KDMSG_FLAG_AUXALLOC     0x0001
865
866 typedef struct kdmsg_link kdmsg_link_t;
867 typedef struct kdmsg_state kdmsg_state_t;
868 typedef struct kdmsg_msg kdmsg_msg_t;
869
870 struct kdmsg_state_tree;
871 RB_HEAD(kdmsg_state_tree, kdmsg_state);
872 int kdmsg_state_cmp(kdmsg_state_t *state1, kdmsg_state_t *state2);
873 RB_PROTOTYPE(kdmsg_state_tree, kdmsg_state, rbnode, kdmsg_state_cmp);
874
875 /*
876  * Structure embedded in e.g. mount, master control structure for
877  * DMSG stream handling.
878  */
879 struct kdmsg_iocom {
880         struct malloc_type      *mmsg;
881         struct file             *msg_fp;        /* cluster pipe->userland */
882         thread_t                msgrd_td;       /* cluster thread */
883         thread_t                msgwr_td;       /* cluster thread */
884         int                     msg_ctl;        /* wakeup flags */
885         int                     msg_seq;        /* cluster msg sequence id */
886         uint32_t                flags;
887         struct lock             msglk;          /* lockmgr lock */
888         TAILQ_HEAD(, kdmsg_msg) msgq;           /* transmit queue */
889         void                    *handle;
890         void                    (*auto_callback)(kdmsg_msg_t *);
891         int                     (*rcvmsg)(kdmsg_msg_t *);
892         void                    (*exit_func)(struct kdmsg_iocom *);
893         struct kdmsg_state      *conn_state;    /* active LNK_CONN state */
894         struct kdmsg_state      *freerd_state;  /* allocation cache */
895         struct kdmsg_state      *freewr_state;  /* allocation cache */
896         struct kdmsg_state_tree staterd_tree;   /* active messages */
897         struct kdmsg_state_tree statewr_tree;   /* active messages */
898         dmsg_lnk_conn_t         auto_lnk_conn;
899         dmsg_lnk_span_t         auto_lnk_span;
900 };
901
902 typedef struct kdmsg_iocom      kdmsg_iocom_t;
903
904 #define KDMSG_IOCOMF_AUTOCONN   0x0001  /* handle received LNK_CONN */
905 #define KDMSG_IOCOMF_AUTOSPAN   0x0002  /* handle received LNK_SPAN */
906 #define KDMSG_IOCOMF_AUTOCIRC   0x0004  /* handle received LNK_CIRC */
907 #define KDMSG_IOCOMF_AUTOFORGE  0x0008  /* auto initiate LNK_CIRC */
908
909 #define KDMSG_IOCOMF_AUTOANY    (KDMSG_IOCOMF_AUTOCONN |        \
910                                  KDMSG_IOCOMF_AUTOSPAN |        \
911                                  KDMSG_IOCOMF_AUTOCIRC)
912
913 uint32_t kdmsg_icrc32(const void *buf, size_t size);
914 uint32_t kdmsg_icrc32c(const void *buf, size_t size, uint32_t crc);
915
916 /*
917  * kern_dmsg.c
918  */
919 void kdmsg_iocom_init(kdmsg_iocom_t *iocom, void *handle, u_int32_t flags,
920                         struct malloc_type *mmsg,
921                         int (*rcvmsg)(kdmsg_msg_t *msg));
922 void kdmsg_iocom_reconnect(kdmsg_iocom_t *iocom, struct file *fp,
923                         const char *subsysname);
924 void kdmsg_iocom_autoinitiate(kdmsg_iocom_t *iocom,
925                         void (*conn_callback)(kdmsg_msg_t *msg));
926 void kdmsg_iocom_uninit(kdmsg_iocom_t *iocom);
927 void kdmsg_drain_msgq(kdmsg_iocom_t *iocom);
928
929 int kdmsg_state_msgrx(kdmsg_msg_t *msg);
930 int kdmsg_state_msgtx(kdmsg_msg_t *msg);
931 void kdmsg_state_cleanuprx(kdmsg_msg_t *msg);
932 void kdmsg_state_cleanuptx(kdmsg_msg_t *msg);
933 int kdmsg_msg_execute(kdmsg_msg_t *msg);
934 void kdmsg_state_free(kdmsg_state_t *state);
935 void kdmsg_msg_free(kdmsg_msg_t *msg);
936 kdmsg_msg_t *kdmsg_msg_alloc(kdmsg_iocom_t *iocom, uint64_t circuit,
937                                 uint32_t cmd,
938                                 int (*func)(kdmsg_state_t *, kdmsg_msg_t *),
939                                 void *data);
940 void kdmsg_msg_write(kdmsg_msg_t *msg);
941 void kdmsg_msg_reply(kdmsg_msg_t *msg, uint32_t error);
942 void kdmsg_msg_result(kdmsg_msg_t *msg, uint32_t error);
943 void kdmsg_state_reply(kdmsg_state_t *state, uint32_t error);
944 void kdmsg_state_result(kdmsg_state_t *state, uint32_t error);
945
946 #endif
947
948 #endif