| 1 |
|
| 2 | #ifndef __DRBD_PROTOCOL_H
|
| 3 | #define __DRBD_PROTOCOL_H
|
| 4 |
|
| 5 | enum drbd_packet {
|
| 6 |
|
| 7 | P_DATA = 0x00,
|
| 8 | P_DATA_REPLY = 0x01,
|
| 9 | P_RS_DATA_REPLY = 0x02,
|
| 10 | P_BARRIER = 0x03,
|
| 11 | P_BITMAP = 0x04,
|
| 12 | P_BECOME_SYNC_TARGET = 0x05,
|
| 13 | P_BECOME_SYNC_SOURCE = 0x06,
|
| 14 | P_UNPLUG_REMOTE = 0x07,
|
| 15 | P_DATA_REQUEST = 0x08,
|
| 16 | P_RS_DATA_REQUEST = 0x09,
|
| 17 | P_SYNC_PARAM = 0x0a,
|
| 18 | P_PROTOCOL = 0x0b,
|
| 19 | P_UUIDS = 0x0c,
|
| 20 | P_SIZES = 0x0d,
|
| 21 | P_STATE = 0x0e,
|
| 22 | P_SYNC_UUID = 0x0f,
|
| 23 | P_AUTH_CHALLENGE = 0x10,
|
| 24 | P_AUTH_RESPONSE = 0x11,
|
| 25 | P_STATE_CHG_REQ = 0x12,
|
| 26 |
|
| 27 |
|
| 28 | P_PING = 0x13,
|
| 29 | P_PING_ACK = 0x14,
|
| 30 | P_RECV_ACK = 0x15,
|
| 31 | P_WRITE_ACK = 0x16,
|
| 32 | P_RS_WRITE_ACK = 0x17,
|
| 33 | P_SUPERSEDED = 0x18,
|
| 34 | P_NEG_ACK = 0x19,
|
| 35 | P_NEG_DREPLY = 0x1a,
|
| 36 | P_NEG_RS_DREPLY = 0x1b,
|
| 37 | P_BARRIER_ACK = 0x1c,
|
| 38 | P_STATE_CHG_REPLY = 0x1d,
|
| 39 |
|
| 40 |
|
| 41 |
|
| 42 | P_OV_REQUEST = 0x1e,
|
| 43 | P_OV_REPLY = 0x1f,
|
| 44 | P_OV_RESULT = 0x20,
|
| 45 | P_CSUM_RS_REQUEST = 0x21,
|
| 46 | P_RS_IS_IN_SYNC = 0x22,
|
| 47 | P_SYNC_PARAM89 = 0x23,
|
| 48 | P_COMPRESSED_BITMAP = 0x24,
|
| 49 |
|
| 50 |
|
| 51 | P_DELAY_PROBE = 0x27,
|
| 52 | P_OUT_OF_SYNC = 0x28,
|
| 53 | P_RS_CANCEL = 0x29,
|
| 54 | P_CONN_ST_CHG_REQ = 0x2a,
|
| 55 | P_CONN_ST_CHG_REPLY = 0x2b,
|
| 56 | P_RETRY_WRITE = 0x2c,
|
| 57 | P_PROTOCOL_UPDATE = 0x2d,
|
| 58 |
|
| 59 |
|
| 60 | |
| 61 | * which is why I chose TRIM here, to disambiguate.
|
| 62 | P_TRIM = 0x31,
|
| 63 |
|
| 64 |
|
| 65 | P_RS_THIN_REQ = 0x32,
|
| 66 | P_RS_DEALLOCATED = 0x33,
|
| 67 |
|
| 68 | |
| 69 | * On a receiving side without REQ_WRITE_SAME,
|
| 70 | * we may fall back to an opencoded loop instead.
|
| 71 | P_WSAME = 0x34,
|
| 72 |
|
| 73 |
|
| 74 | P_ZEROES = 0x36,
|
| 75 |
|
| 76 |
|
| 77 |
|
| 78 | P_MAY_IGNORE = 0x100,
|
| 79 | P_MAX_OPT_CMD = 0x101,
|
| 80 |
|
| 81 |
|
| 82 |
|
| 83 | P_INITIAL_META = 0xfff1,
|
| 84 | P_INITIAL_DATA = 0xfff2,
|
| 85 |
|
| 86 | P_CONNECTION_FEATURES = 0xfffe
|
| 87 | };
|
| 88 |
|
| 89 | #ifndef __packed
|
| 90 | #define __packed __attribute__((packed))
|
| 91 | #endif
|
| 92 |
|
| 93 | |
| 94 | * The byteorder is the network byte order.
|
| 95 | * (except block_id and barrier fields.
|
| 96 | * these are pointers to local structs
|
| 97 | * and have no relevance for the partner,
|
| 98 | * which just echoes them as received.)
|
| 99 | *
|
| 100 | * NOTE that the payload starts at a long aligned offset,
|
| 101 | * regardless of 32 or 64 bit arch!
|
| 102 |
|
| 103 | struct p_header80 {
|
| 104 | u32 magic;
|
| 105 | u16 command;
|
| 106 | u16 length;
|
| 107 | } __packed;
|
| 108 |
|
| 109 |
|
| 110 | struct p_header95 {
|
| 111 | u16 magic;
|
| 112 | u16 command;
|
| 113 | u32 length;
|
| 114 | } __packed;
|
| 115 |
|
| 116 | struct p_header100 {
|
| 117 | u32 magic;
|
| 118 | u16 volume;
|
| 119 | u16 command;
|
| 120 | u32 length;
|
| 121 | u32 pad;
|
| 122 | } __packed;
|
| 123 |
|
| 124 | |
| 125 | * New defines may only be introduced together with protocol version bump or
|
| 126 | * new protocol feature flags.
|
| 127 |
|
| 128 | #define DP_HARDBARRIER 1
|
| 129 | #define DP_RW_SYNC 2
|
| 130 | #define DP_MAY_SET_IN_SYNC 4
|
| 131 | #define DP_UNPLUG 8
|
| 132 | #define DP_FUA 16
|
| 133 | #define DP_FLUSH 32
|
| 134 | #define DP_DISCARD 64
|
| 135 | #define DP_SEND_RECEIVE_ACK 128
|
| 136 | #define DP_SEND_WRITE_ACK 256
|
| 137 | #define DP_WSAME 512
|
| 138 | #define DP_ZEROES 1024
|
| 139 |
|
| 140 | |
| 141 | * REQ_OP_WRITE_ZEROES: DP_DISCARD | DP_ZEROES
|
| 142 | * REQ_OP_WRITE_ZEROES + REQ_NOUNMAP: DP_ZEROES
|
| 143 |
|
| 144 |
|
| 145 | struct p_data {
|
| 146 | u64 sector;
|
| 147 | u64 block_id;
|
| 148 | u32 seq_num;
|
| 149 | u32 dp_flags;
|
| 150 | } __packed;
|
| 151 |
|
| 152 | struct p_trim {
|
| 153 | struct p_data p_data;
|
| 154 | u32 size;
|
| 155 | } __packed;
|
| 156 |
|
| 157 | struct p_wsame {
|
| 158 | struct p_data p_data;
|
| 159 | u32 size;
|
| 160 | } __packed;
|
| 161 |
|
| 162 | |
| 163 | * commands which share a struct:
|
| 164 | * p_block_ack:
|
| 165 | * P_RECV_ACK (proto B), P_WRITE_ACK (proto C),
|
| 166 | * P_SUPERSEDED (proto C, two-primaries conflict detection)
|
| 167 | * p_block_req:
|
| 168 | * P_DATA_REQUEST, P_RS_DATA_REQUEST
|
| 169 |
|
| 170 | struct p_block_ack {
|
| 171 | u64 sector;
|
| 172 | u64 block_id;
|
| 173 | u32 blksize;
|
| 174 | u32 seq_num;
|
| 175 | } __packed;
|
| 176 |
|
| 177 | struct p_block_req {
|
| 178 | u64 sector;
|
| 179 | u64 block_id;
|
| 180 | u32 blksize;
|
| 181 | u32 pad;
|
| 182 | } __packed;
|
| 183 |
|
| 184 | |
| 185 | * commands with their own struct for additional fields:
|
| 186 | * P_CONNECTION_FEATURES
|
| 187 | * P_BARRIER
|
| 188 | * P_BARRIER_ACK
|
| 189 | * P_SYNC_PARAM
|
| 190 | * ReportParams
|
| 191 |
|
| 192 |
|
| 193 |
|
| 194 | #define DRBD_FF_TRIM 1
|
| 195 |
|
| 196 | |
| 197 | * instead of fully allocate a supposedly thin volume on initial resync
|
| 198 | #define DRBD_FF_THIN_RESYNC 2
|
| 199 |
|
| 200 | |
| 201 | * Note: this flag is overloaded,
|
| 202 | * its presence also
|
| 203 | * - indicates support for 128 MiB "batch bios",
|
| 204 | * max discard size of 128 MiB
|
| 205 | * instead of 4M before that.
|
| 206 | * - indicates that we exchange additional settings in p_sizes
|
| 207 | * drbd_send_sizes()/receive_sizes()
|
| 208 |
|
| 209 | #define DRBD_FF_WSAME 4
|
| 210 |
|
| 211 | |
| 212 | *
|
| 213 | * We used to map that to "discard" on the sending side, and if we cannot
|
| 214 | * guarantee that discard zeroes data, the receiving side would map discard
|
| 215 | * back to zero-out.
|
| 216 | *
|
| 217 | * With the introduction of REQ_OP_WRITE_ZEROES,
|
| 218 | * we started to use that for both WRITE_ZEROES and DISCARDS,
|
| 219 | * hoping that WRITE_ZEROES would "do what we want",
|
| 220 | * UNMAP if possible, zero-out the rest.
|
| 221 | *
|
| 222 | * The example scenario is some LVM "thin" backend.
|
| 223 | *
|
| 224 | * While an un-allocated block on dm-thin reads as zeroes, on a dm-thin
|
| 225 | * with "skip_block_zeroing=true", after a partial block write allocated
|
| 226 | * that block, that same block may well map "undefined old garbage" from
|
| 227 | * the backends on LBAs that have not yet been written to.
|
| 228 | *
|
| 229 | * If we cannot distinguish between zero-out and discard on the receiving
|
| 230 | * side, to avoid "undefined old garbage" to pop up randomly at later times
|
| 231 | * on supposedly zero-initialized blocks, we'd need to map all discards to
|
| 232 | * zero-out on the receiving side. But that would potentially do a full
|
| 233 | * alloc on thinly provisioned backends, even when the expectation was to
|
| 234 | * unmap/trim/discard/de-allocate.
|
| 235 | *
|
| 236 | * We need to distinguish on the protocol level, whether we need to guarantee
|
| 237 | * zeroes (and thus use zero-out, potentially doing the mentioned full-alloc),
|
| 238 | * or if we want to put the emphasis on discard, and only do a "best effort
|
| 239 | * zeroing" (by "discarding" blocks aligned to discard-granularity, and zeroing
|
| 240 | * only potential unaligned head and tail clippings), to at least *try* to
|
| 241 | * avoid "false positives" in an online-verify later, hoping that someone
|
| 242 | * set skip_block_zeroing=false.
|
| 243 |
|
| 244 | #define DRBD_FF_WZEROES 8
|
| 245 |
|
| 246 |
|
| 247 | struct p_connection_features {
|
| 248 | u32 protocol_min;
|
| 249 | u32 feature_flags;
|
| 250 | u32 protocol_max;
|
| 251 |
|
| 252 | |
| 253 | * for now, feature_flags and the reserved array shall be zero.
|
| 254 |
|
| 255 |
|
| 256 | u32 _pad;
|
| 257 | u64 reserved[7];
|
| 258 | } __packed;
|
| 259 |
|
| 260 | struct p_barrier {
|
| 261 | u32 barrier;
|
| 262 | u32 pad;
|
| 263 | } __packed;
|
| 264 |
|
| 265 | struct p_barrier_ack {
|
| 266 | u32 barrier;
|
| 267 | u32 set_size;
|
| 268 | } __packed;
|
| 269 |
|
| 270 | struct p_rs_param {
|
| 271 | u32 resync_rate;
|
| 272 |
|
| 273 |
|
| 274 | char verify_alg[];
|
| 275 | } __packed;
|
| 276 |
|
| 277 | struct p_rs_param_89 {
|
| 278 | u32 resync_rate;
|
| 279 |
|
| 280 | char verify_alg[SHARED_SECRET_MAX];
|
| 281 | char csums_alg[SHARED_SECRET_MAX];
|
| 282 | } __packed;
|
| 283 |
|
| 284 | struct p_rs_param_95 {
|
| 285 | u32 resync_rate;
|
| 286 | struct_group(algs,
|
| 287 | char verify_alg[SHARED_SECRET_MAX];
|
| 288 | char csums_alg[SHARED_SECRET_MAX];
|
| 289 | );
|
| 290 | u32 c_plan_ahead;
|
| 291 | u32 c_delay_target;
|
| 292 | u32 c_fill_target;
|
| 293 | u32 c_max_rate;
|
| 294 | } __packed;
|
| 295 |
|
| 296 | enum drbd_conn_flags {
|
| 297 | CF_DISCARD_MY_DATA = 1,
|
| 298 | CF_DRY_RUN = 2,
|
| 299 | };
|
| 300 |
|
| 301 | struct p_protocol {
|
| 302 | u32 protocol;
|
| 303 | u32 after_sb_0p;
|
| 304 | u32 after_sb_1p;
|
| 305 | u32 after_sb_2p;
|
| 306 | u32 conn_flags;
|
| 307 | u32 two_primaries;
|
| 308 |
|
| 309 |
|
| 310 | char integrity_alg[];
|
| 311 |
|
| 312 | } __packed;
|
| 313 |
|
| 314 | struct p_uuids {
|
| 315 | u64 uuid[UI_EXTENDED_SIZE];
|
| 316 | } __packed;
|
| 317 |
|
| 318 | struct p_rs_uuid {
|
| 319 | u64 uuid;
|
| 320 | } __packed;
|
| 321 |
|
| 322 | |
| 323 | * see also struct queue_limits, as of late 2015
|
| 324 | struct o_qlim {
|
| 325 |
|
| 326 | u32 physical_block_size;
|
| 327 |
|
| 328 | |
| 329 | * but I'd have to put in padding anyways.
|
| 330 | u32 logical_block_size;
|
| 331 |
|
| 332 | |
| 333 | * which may be translated to several bio on the receiving side.
|
| 334 | * We don't need to communicate chunk/boundary/segment ... limits.
|
| 335 |
|
| 336 |
|
| 337 |
|
| 338 | u32 alignment_offset;
|
| 339 | u32 io_min;
|
| 340 | u32 io_opt;
|
| 341 |
|
| 342 | |
| 343 | * but let's not get ahead of ourselves.
|
| 344 |
|
| 345 | |
| 346 | * Receiving side uses "blkdev_issue_discard()", no need to communicate
|
| 347 | * more specifics. If the backend cannot do discards, the DRBD peer
|
| 348 | * may fall back to blkdev_issue_zeroout().
|
| 349 |
|
| 350 | u8 discard_enabled;
|
| 351 | u8 discard_zeroes_data;
|
| 352 | u8 write_same_capable;
|
| 353 | u8 _pad;
|
| 354 | } __packed;
|
| 355 |
|
| 356 | struct p_sizes {
|
| 357 | u64 d_size;
|
| 358 | u64 u_size;
|
| 359 | u64 c_size;
|
| 360 | u32 max_bio_size;
|
| 361 | u16 queue_order_type;
|
| 362 | u16 dds_flags;
|
| 363 |
|
| 364 |
|
| 365 | struct o_qlim qlim[];
|
| 366 | } __packed;
|
| 367 |
|
| 368 | struct p_state {
|
| 369 | u32 state;
|
| 370 | } __packed;
|
| 371 |
|
| 372 | struct p_req_state {
|
| 373 | u32 mask;
|
| 374 | u32 val;
|
| 375 | } __packed;
|
| 376 |
|
| 377 | struct p_req_state_reply {
|
| 378 | u32 retcode;
|
| 379 | } __packed;
|
| 380 |
|
| 381 | struct p_drbd06_param {
|
| 382 | u64 size;
|
| 383 | u32 state;
|
| 384 | u32 blksize;
|
| 385 | u32 protocol;
|
| 386 | u32 version;
|
| 387 | u32 gen_cnt[5];
|
| 388 | u32 bit_map_gen[5];
|
| 389 | } __packed;
|
| 390 |
|
| 391 | struct p_block_desc {
|
| 392 | u64 sector;
|
| 393 | u32 blksize;
|
| 394 | u32 pad;
|
| 395 | } __packed;
|
| 396 |
|
| 397 | |
| 398 | * Bump proto version when changing this.
|
| 399 | enum drbd_bitmap_code {
|
| 400 | |
| 401 | * and other bit variants had been defined during
|
| 402 | * algorithm evaluation.
|
| 403 | RLE_VLI_Bits = 2,
|
| 404 | };
|
| 405 |
|
| 406 | struct p_compressed_bm {
|
| 407 | |
| 408 | * (encoding & 0x80): polarity (set/unset) of first runlength
|
| 409 | * ((encoding >> 4) & 0x07): pad_bits, number of trailing zero bits
|
| 410 | * used to pad up to head.length bytes
|
| 411 |
|
| 412 | u8 encoding;
|
| 413 |
|
| 414 | u8 code[];
|
| 415 | } __packed;
|
| 416 |
|
| 417 | struct p_delay_probe93 {
|
| 418 | u32 seq_num;
|
| 419 | u32 offset;
|
| 420 | } __packed;
|
| 421 |
|
| 422 | |
| 423 | * Bitmap packets need to fit within a single page on the sender and receiver,
|
| 424 | * so we are limited to 4 KiB (and not to PAGE_SIZE, which can be bigger).
|
| 425 |
|
| 426 | #define DRBD_SOCKET_BUFFER_SIZE 4096
|
| 427 |
|
| 428 | #endif
|