.gear/rules | 3 + .gear/tags/list | 2 + drbd-headers.tar | Bin 0 -> 112640 bytes drbd-utils.spec | 285 +++++++++++++++++++++++++++++++++++++++++++ drbd.service | 19 +++ scripts/drbd | 8 +- scripts/drbd-service-shim.sh | 7 +- scripts/drbddisk | 2 +- scripts/drbdupper | 2 +- scripts/global_common.conf | 2 +- user/shared/drbd_buildtag.sh | 2 +- 11 files changed, 321 insertions(+), 11 deletions(-) diff --git a/.gear/rules b/.gear/rules new file mode 100644 index 00000000..57704aa7 --- /dev/null +++ b/.gear/rules @@ -0,0 +1,3 @@ +tar: v@version@:. +tar: upstream/drbd-headers:. name=@name@-headers-@version@ base= +diff: v@version@:. . diff --git a/.gear/tags/list b/.gear/tags/list new file mode 100644 index 00000000..80900a85 --- /dev/null +++ b/.gear/tags/list @@ -0,0 +1,2 @@ +a805c72719c2d8ebf7b5954e6e57d748bc843455 upstream/drbd-headers +c331d6627ad1af44c4d2ec17b0ff6d5f8ba0e833 v9.24.0 diff --git a/drbd-headers.tar b/drbd-headers.tar new file mode 100644 index 00000000..89913da5 --- /dev/null +++ b/drbd-headers.tar @@ -0,0 +1,3120 @@ +drbd-headers/0000775000077500007750000000000013070663767012451 5ustar shrekshrekdrbd-headers/drbd_strings.c0000644000077500007750000002140713070663767015303 0ustar shrekshrek/* + drbd.h + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2003-2008, LINBIT Information Technologies GmbH. + Copyright (C) 2003-2008, Philipp Reisner . + Copyright (C) 2003-2008, Lars Ellenberg . + + drbd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + drbd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include "drbd_strings.h" +#include "drbd_protocol.h" + +static const char * const __conn_state_names[] = { + [C_STANDALONE] = "StandAlone", + [C_DISCONNECTING] = "Disconnecting", + [C_UNCONNECTED] = "Unconnected", + [C_TIMEOUT] = "Timeout", + [C_BROKEN_PIPE] = "BrokenPipe", + [C_NETWORK_FAILURE] = "NetworkFailure", + [C_PROTOCOL_ERROR] = "ProtocolError", + [C_TEAR_DOWN] = "TearDown", + [C_CONNECTING] = "Connecting", + [C_CONNECTED] = "Connected", +}; + +struct state_names drbd_conn_state_names = { + .names = __conn_state_names, + .size = sizeof __conn_state_names / sizeof __conn_state_names[0], +}; + +static const char * const __repl_state_names[] = { + [L_OFF] = "Off", + [L_ESTABLISHED] = "Established", + [L_STARTING_SYNC_S] = "StartingSyncS", + [L_STARTING_SYNC_T] = "StartingSyncT", + [L_WF_BITMAP_S] = "WFBitMapS", + [L_WF_BITMAP_T] = "WFBitMapT", + [L_WF_SYNC_UUID] = "WFSyncUUID", + [L_SYNC_SOURCE] = "SyncSource", + [L_SYNC_TARGET] = "SyncTarget", + [L_VERIFY_S] = "VerifyS", + [L_VERIFY_T] = "VerifyT", + [L_PAUSED_SYNC_S] = "PausedSyncS", + [L_PAUSED_SYNC_T] = "PausedSyncT", + [L_AHEAD] = "Ahead", + [L_BEHIND] = "Behind", +}; + +struct state_names drbd_repl_state_names = { + .names = __repl_state_names, + .size = sizeof __repl_state_names / sizeof __repl_state_names[0], +}; + +static const char * const __role_state_names[] = { + [R_UNKNOWN] = "Unknown", + [R_PRIMARY] = "Primary", + [R_SECONDARY] = "Secondary", +}; + +struct state_names drbd_role_state_names = { + .names = __role_state_names, + .size = sizeof __role_state_names / sizeof __role_state_names[0], +}; + +static const char * const __disk_state_names[] = { + [D_DISKLESS] = "Diskless", + [D_ATTACHING] = "Attaching", + [D_DETACHING] = "Detaching", + [D_FAILED] = "Failed", + [D_NEGOTIATING] = "Negotiating", + [D_INCONSISTENT] = "Inconsistent", + [D_OUTDATED] = "Outdated", + [D_UNKNOWN] = "DUnknown", + [D_CONSISTENT] = "Consistent", + [D_UP_TO_DATE] = "UpToDate", +}; + +struct state_names drbd_disk_state_names = { + .names = __disk_state_names, + .size = sizeof __disk_state_names / sizeof __disk_state_names[0], +}; + +static const char * const __error_messages[] = { + [-SS_TWO_PRIMARIES] = "Multiple primaries not allowed by config", + [-SS_NO_UP_TO_DATE_DISK] = "Need access to UpToDate data", + [-SS_NO_LOCAL_DISK] = "Can not resync without local disk", + [-SS_NO_REMOTE_DISK] = "Can not resync without remote disk", + [-SS_CONNECTED_OUTDATES] = "Refusing to be Outdated while Connected", + [-SS_PRIMARY_NOP] = "Refusing to be Primary while peer is not outdated", + [-SS_RESYNC_RUNNING] = "Can not start OV/resync since it is already active", + [-SS_ALREADY_STANDALONE] = "Can not disconnect a StandAlone device", + [-SS_CW_FAILED_BY_PEER] = "State change was refused by peer node", + [-SS_IS_DISKLESS] = "Device is diskless, the requested operation requires a disk", + [-SS_DEVICE_IN_USE] = "Device is held open by someone", + [-SS_NO_NET_CONFIG] = "Have no net/connection configuration", + [-SS_NO_VERIFY_ALG] = "Need a verify algorithm to start online verify", + [-SS_NEED_CONNECTION] = "Need a connection to start verify or resync", + [-SS_NOT_SUPPORTED] = "Peer does not support protocol", + [-SS_LOWER_THAN_OUTDATED] = "Disk state is lower than outdated", + [-SS_IN_TRANSIENT_STATE] = "In transient state, retry after next state change", + [-SS_CONCURRENT_ST_CHG] = "Concurrent state changes detected and aborted", + [-SS_O_VOL_PEER_PRI] = "Other vol primary on peer not allowed by config", + [-SS_PRIMARY_READER] = "Peer may not become primary while device is opened read-only", + [-SS_INTERRUPTED] = "Interrupted state change", + [-SS_TIMEOUT] = "Timeout in operation", + [-SS_WEAKLY_CONNECTED] = "Primary nodes must be strongly connected among each other", +}; + +struct state_names drbd_error_messages = { + .names = __error_messages, + .size = sizeof __error_messages / sizeof __error_messages[0], +}; + +static const char * const __packet_names[] = { + [P_DATA] = "P_DATA", + [P_WSAME] = "P_WSAME", + [P_TRIM] = "P_TRIM", + [P_DATA_REPLY] = "P_DATA_REPLY", + [P_RS_DATA_REPLY] = "P_RS_DATA_REPLY", + [P_BARRIER] = "P_BARRIER", + [P_BITMAP] = "P_BITMAP", + [P_BECOME_SYNC_TARGET] = "P_BECOME_SYNC_TARGET", + [P_BECOME_SYNC_SOURCE] = "P_BECOME_SYNC_SOURCE", + [P_UNPLUG_REMOTE] = "P_UNPLUG_REMOTE", + [P_DATA_REQUEST] = "P_DATA_REQUEST", + [P_RS_DATA_REQUEST] = "P_RS_DATA_REQUEST", + [P_SYNC_PARAM] = "P_SYNC_PARAM", + [P_SYNC_PARAM89] = "P_SYNC_PARAM89", + [P_PROTOCOL] = "P_PROTOCOL", + [P_UUIDS] = "P_UUIDS", + [P_SIZES] = "P_SIZES", + [P_STATE] = "P_STATE", + [P_SYNC_UUID] = "P_SYNC_UUID", + [P_AUTH_CHALLENGE] = "P_AUTH_CHALLENGE", + [P_AUTH_RESPONSE] = "P_AUTH_RESPONSE", + [P_PING] = "P_PING", + [P_PING_ACK] = "P_PING_ACK", + [P_RECV_ACK] = "P_RECV_ACK", + [P_WRITE_ACK] = "P_WRITE_ACK", + [P_RS_WRITE_ACK] = "P_RS_WRITE_ACK", + [P_SUPERSEDED] = "P_SUPERSEDED", + [P_NEG_ACK] = "P_NEG_ACK", + [P_NEG_DREPLY] = "P_NEG_DREPLY", + [P_NEG_RS_DREPLY] = "P_NEG_RS_DREPLY", + [P_BARRIER_ACK] = "P_BARRIER_ACK", + [P_STATE_CHG_REQ] = "P_STATE_CHG_REQ", + [P_STATE_CHG_REPLY] = "P_STATE_CHG_REPLY", + [P_OV_REQUEST] = "P_OV_REQUEST", + [P_OV_REPLY] = "P_OV_REPLY", + [P_OV_RESULT] = "P_OV_RESULT", + [P_CSUM_RS_REQUEST] = "P_CSUM_RS_REQUEST", + [P_RS_IS_IN_SYNC] = "P_RS_IS_IN_SYNC", + [P_COMPRESSED_BITMAP] = "P_COMPRESSED_BITMAP", + [P_DELAY_PROBE] = "P_DELAY_PROBE", + [P_OUT_OF_SYNC] = "P_OUT_OF_SYNC", + [P_RETRY_WRITE] = "P_RETRY_WRITE", + [P_RS_CANCEL] = "P_RS_CANCEL", + [P_CONN_ST_CHG_REQ] = "P_CONN_ST_CHG_REQ", + [P_CONN_ST_CHG_REPLY] = "P_CONN_ST_CHG_REPLY", + [P_RETRY_WRITE] = "P_RETRY_WRITE", + [P_PROTOCOL_UPDATE] = "P_PROTOCOL_UPDATE", + [P_TWOPC_PREPARE] = "P_TWOPC_PREPARE", + [P_TWOPC_ABORT] = "P_TWOPC_ABORT", + [P_DAGTAG] = "P_DAGTAG", + [P_PEER_ACK] = "P_PEER_ACK", + [P_PEERS_IN_SYNC] = "P_PEERS_IN_SYNC", + [P_UUIDS110] = "P_UUIDS110", + [P_PEER_DAGTAG] = "P_PEER_DAGTAG", + [P_CURRENT_UUID] = "P_CURRENT_UUID", + [P_TWOPC_COMMIT] = "P_TWOPC_COMMIT", + [P_TWOPC_YES] = "P_TWOPC_YES", + [P_TWOPC_NO] = "P_TWOPC_NO", + [P_TWOPC_RETRY] = "P_TWOPC_RETRY", + /* enum drbd_packet, but not commands - obsoleted flags: + * P_MAY_IGNORE + * P_MAX_OPT_CMD + */ +}; + +struct state_names drbd_packet_names = { + .names = __packet_names, + .size = sizeof __packet_names / sizeof __packet_names[0], +}; + +const char *drbd_repl_str(enum drbd_repl_state s) +{ + return (s < 0 || s >= drbd_repl_state_names.size || + !drbd_repl_state_names.names[s]) ? + "?" : drbd_repl_state_names.names[s]; +} + +const char *drbd_conn_str(enum drbd_conn_state s) +{ + return (s < 0 || s >= drbd_conn_state_names.size || + !drbd_conn_state_names.names[s]) ? + "?" : drbd_conn_state_names.names[s]; +} + +const char *drbd_role_str(enum drbd_role s) +{ + return (s < 0 || s >= drbd_role_state_names.size || + !drbd_role_state_names.names[s]) ? + "?" : drbd_role_state_names.names[s]; +} + +const char *drbd_disk_str(enum drbd_disk_state s) +{ + return (s < 0 || s >= drbd_disk_state_names.size || + !drbd_disk_state_names.names[s]) ? + "?" : drbd_disk_state_names.names[s]; +} + +const char *drbd_set_st_err_str(enum drbd_state_rv err) +{ + return (-err < 0 || -err >= drbd_error_messages.size || + !drbd_error_messages.names[-err]) ? + "?" : drbd_error_messages.names[-err]; +} + +const char *drbd_packet_name(enum drbd_packet cmd) +{ + /* too big for the array: 0xfffX */ + if (cmd == P_INITIAL_META) + return "InitialMeta"; + if (cmd == P_INITIAL_DATA) + return "InitialData"; + if (cmd == P_CONNECTION_FEATURES) + return "ConnectionFeatures"; + return (cmd < 0 || cmd >= ARRAY_SIZE(__packet_names) || + !__packet_names[cmd]) ? + "?" : __packet_names[cmd]; +} +drbd-headers/linux/0000755000077500007750000000000013070663767013606 5ustar shrekshrekdrbd-headers/linux/genl_magic_func.h0000644000077500007750000002546013070663767017066 0ustar shrekshrek#ifndef GENL_MAGIC_FUNC_H +#define GENL_MAGIC_FUNC_H + +#include + +/* + * Magic: declare tla policy {{{1 + * Magic: declare nested policies + * {{{2 + */ +#undef GENL_mc_group +#define GENL_mc_group(group) + +#undef GENL_notification +#define GENL_notification(op_name, op_num, mcast_group, tla_list) + +#undef GENL_op +#define GENL_op(op_name, op_num, handler, tla_list) + +#undef GENL_struct +#define GENL_struct(tag_name, tag_number, s_name, s_fields) \ + [tag_name] = { .type = NLA_NESTED }, + +static struct nla_policy CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy)[] \ + __attribute__((unused)) = { +#include GENL_MAGIC_INCLUDE_FILE +}; + +#undef GENL_struct +#define GENL_struct(tag_name, tag_number, s_name, s_fields) \ +static struct nla_policy s_name ## _nl_policy[] __read_mostly = \ +{ s_fields }; + +#undef __field +#define __field(attr_nr, attr_flag, name, nla_type, _type, __get, \ + __put, __is_signed) \ + [attr_nr] = { .type = nla_type }, + +#undef __array +#define __array(attr_nr, attr_flag, name, nla_type, _type, maxlen, \ + __get, __put, __is_signed) \ + [attr_nr] = { .type = nla_type, \ + .len = maxlen - (nla_type == NLA_NUL_STRING) }, + +#include GENL_MAGIC_INCLUDE_FILE + +#ifndef __KERNEL__ +#ifndef pr_info +#define pr_info(args...) fprintf(stderr, args); +#endif +#endif + +#ifdef GENL_MAGIC_DEBUG +static void dprint_field(const char *dir, int nla_type, + const char *name, void *valp) +{ + __u64 val = valp ? *(__u32 *)valp : 1; + switch (nla_type) { + case NLA_U8: val = (__u8)val; + case NLA_U16: val = (__u16)val; + case NLA_U32: val = (__u32)val; + pr_info("%s attr %s: %d 0x%08x\n", dir, + name, (int)val, (unsigned)val); + break; + case NLA_U64: + val = *(__u64*)valp; + pr_info("%s attr %s: %lld 0x%08llx\n", dir, + name, (long long)val, (unsigned long long)val); + break; + case NLA_FLAG: + if (val) + pr_info("%s attr %s: set\n", dir, name); + break; + } +} + +static void dprint_array(const char *dir, int nla_type, + const char *name, const char *val, unsigned len) +{ + switch (nla_type) { + case NLA_NUL_STRING: + if (len && val[len-1] == '\0') + len--; + pr_info("%s attr %s: [len:%u] '%s'\n", dir, name, len, val); + break; + default: + /* we can always show 4 byte, + * thats what nlattr are aligned to. */ + pr_info("%s attr %s: [len:%u] %02x%02x%02x%02x ...\n", + dir, name, len, val[0], val[1], val[2], val[3]); + } +} + +#define DPRINT_TLA(a, op, b) pr_info("%s %s %s\n", a, op, b); + +/* Name is a member field name of the struct s. + * If s is NULL (only parsing, no copy requested in *_from_attrs()), + * nla is supposed to point to the attribute containing the information + * corresponding to that struct member. */ +#define DPRINT_FIELD(dir, nla_type, name, s, nla) \ + do { \ + if (s) \ + dprint_field(dir, nla_type, #name, &s->name); \ + else if (nla) \ + dprint_field(dir, nla_type, #name, \ + (nla_type == NLA_FLAG) ? NULL \ + : nla_data(nla)); \ + } while (0) + +#define DPRINT_ARRAY(dir, nla_type, name, s, nla) \ + do { \ + if (s) \ + dprint_array(dir, nla_type, #name, \ + s->name, s->name ## _len); \ + else if (nla) \ + dprint_array(dir, nla_type, #name, \ + nla_data(nla), nla_len(nla)); \ + } while (0) +#else +#define DPRINT_TLA(a, op, b) do {} while (0) +#define DPRINT_FIELD(dir, nla_type, name, s, nla) do {} while (0) +#define DPRINT_ARRAY(dir, nla_type, name, s, nla) do {} while (0) +#endif + +/* + * Magic: provide conversion functions {{{1 + * populate struct from attribute table: + * {{{2 + */ + +/* processing of generic netlink messages is serialized. + * use one static buffer for parsing of nested attributes */ +static struct nlattr *nested_attr_tb[128]; + +#undef GENL_struct +#define GENL_struct(tag_name, tag_number, s_name, s_fields) \ +static int __ ## s_name ## _from_attrs(struct s_name *s, \ + struct genl_info *info, bool exclude_invariants) \ +{ \ + const int maxtype = ARRAY_SIZE(s_name ## _nl_policy)-1; \ + struct nlattr *tla = info->attrs[tag_number]; \ + struct nlattr **ntb = nested_attr_tb; \ + struct nlattr *nla; \ + int err; \ + BUILD_BUG_ON(ARRAY_SIZE(s_name ## _nl_policy) > ARRAY_SIZE(nested_attr_tb)); \ + if (!tla) \ + return -ENOMSG; \ + DPRINT_TLA(#s_name, "<=-", #tag_name); \ + err = drbd_nla_parse_nested(ntb, maxtype, tla, s_name ## _nl_policy); \ + if (err) \ + return err; \ + \ + s_fields \ + return 0; \ +} __attribute__((unused)) \ +static int s_name ## _from_attrs(struct s_name *s, \ + struct genl_info *info) \ +{ \ + return __ ## s_name ## _from_attrs(s, info, false); \ +} __attribute__((unused)) \ +static int s_name ## _from_attrs_for_change(struct s_name *s, \ + struct genl_info *info) \ +{ \ + return __ ## s_name ## _from_attrs(s, info, true); \ +} __attribute__((unused)) \ + +#define __assign(attr_nr, attr_flag, name, nla_type, type, assignment...) \ + nla = ntb[attr_nr]; \ + if (nla) { \ + if (exclude_invariants && !!((attr_flag) & DRBD_F_INVARIANT)) { \ + pr_info("<< must not change invariant attr: %s\n", #name); \ + return -EEXIST; \ + } \ + assignment; \ + } else if (exclude_invariants && !!((attr_flag) & DRBD_F_INVARIANT)) { \ + /* attribute missing from payload, */ \ + /* which was expected */ \ + } else if ((attr_flag) & DRBD_F_REQUIRED) { \ + pr_info("<< missing attr: %s\n", #name); \ + return -ENOMSG; \ + } + +#undef __field +#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \ + __is_signed) \ + __assign(attr_nr, attr_flag, name, nla_type, type, \ + if (s) \ + s->name = __get(nla); \ + DPRINT_FIELD("<<", nla_type, name, s, nla)) + +/* validate_nla() already checked nla_len <= maxlen appropriately. */ +#undef __array +#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \ + __get, __put, __is_signed) \ + __assign(attr_nr, attr_flag, name, nla_type, type, \ + if (s) \ + s->name ## _len = \ + __get(s->name, nla, maxlen); \ + DPRINT_ARRAY("<<", nla_type, name, s, nla)) + +#include GENL_MAGIC_INCLUDE_FILE + +#undef GENL_struct +#define GENL_struct(tag_name, tag_number, s_name, s_fields) + +/* + * Magic: define op number to op name mapping {{{1 + * {{{2 + */ +static const char *CONCAT_(GENL_MAGIC_FAMILY, _genl_cmd_to_str)(__u8 cmd) +__attribute__ ((unused)); +static const char *CONCAT_(GENL_MAGIC_FAMILY, _genl_cmd_to_str)(__u8 cmd) +{ + switch (cmd) { +#undef GENL_op +#define GENL_op(op_name, op_num, handler, tla_list) \ + case op_num: return #op_name; +#include GENL_MAGIC_INCLUDE_FILE + default: + return "unknown"; + } +} + +#ifdef __KERNEL__ +#include +/* + * Magic: define genl_ops {{{1 + * {{{2 + */ + +#undef GENL_op +#define GENL_op(op_name, op_num, handler, tla_list) \ +{ \ + handler \ + .cmd = op_name, \ + .policy = CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy), \ +}, + +#define ZZZ_genl_ops CONCAT_(GENL_MAGIC_FAMILY, _genl_ops) +static struct genl_ops ZZZ_genl_ops[] __read_mostly = { +#include GENL_MAGIC_INCLUDE_FILE +}; + +#undef GENL_op +#define GENL_op(op_name, op_num, handler, tla_list) + +/* + * Define the genl_family, multicast groups, {{{1 + * and provide register/unregister functions. + * {{{2 + */ +#define ZZZ_genl_family CONCAT_(GENL_MAGIC_FAMILY, _genl_family) +static struct genl_family ZZZ_genl_family __read_mostly = { + .id = GENL_ID_GENERATE, + .name = __stringify(GENL_MAGIC_FAMILY), + .version = GENL_MAGIC_VERSION, +#ifdef GENL_MAGIC_FAMILY_HDRSZ + .hdrsize = NLA_ALIGN(GENL_MAGIC_FAMILY_HDRSZ), +#endif + .maxattr = ARRAY_SIZE(drbd_tla_nl_policy)-1, +}; + +/* + * Magic: define multicast groups + * Magic: define multicast group registration helper + */ + +/* COMPAT + * See linux 3.13, + * genetlink: make multicast groups const, prevent abuse + * genetlink: pass family to functions using groups + * genetlink: only pass array to genl_register_family_with_ops() + * which are commits c53ed742..2a94fe48 + */ +#ifdef genl_register_family_with_ops_groups +#include +#else +#include +#endif + +/* + * Magic: provide conversion functions {{{1 + * populate skb from struct. + * {{{2 + */ + +#undef GENL_op +#define GENL_op(op_name, op_num, handler, tla_list) + +#undef GENL_struct +#define GENL_struct(tag_name, tag_number, s_name, s_fields) \ +static int s_name ## _to_skb(struct sk_buff *skb, struct s_name *s, \ + const bool exclude_sensitive) \ +{ \ + struct nlattr *tla = nla_nest_start(skb, tag_number); \ + if (!tla) \ + goto nla_put_failure; \ + DPRINT_TLA(#s_name, "-=>", #tag_name); \ + s_fields \ + nla_nest_end(skb, tla); \ + return 0; \ + \ +nla_put_failure: \ + if (tla) \ + nla_nest_cancel(skb, tla); \ + return -EMSGSIZE; \ +} \ +static inline int s_name ## _to_priv_skb(struct sk_buff *skb, \ + struct s_name *s) \ +{ \ + return s_name ## _to_skb(skb, s, 0); \ +} \ +static inline int s_name ## _to_unpriv_skb(struct sk_buff *skb, \ + struct s_name *s) \ +{ \ + return s_name ## _to_skb(skb, s, 1); \ +} + + +#undef __field +#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \ + __is_signed) \ + if (!exclude_sensitive || !((attr_flag) & DRBD_F_SENSITIVE)) { \ + DPRINT_FIELD(">>", nla_type, name, s, NULL); \ + if (__put(skb, attr_nr, s->name)) \ + goto nla_put_failure; \ + } + +#undef __array +#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \ + __get, __put, __is_signed) \ + if (!exclude_sensitive || !((attr_flag) & DRBD_F_SENSITIVE)) { \ + DPRINT_ARRAY(">>",nla_type, name, s, NULL); \ + if (__put(skb, attr_nr, min_t(int, maxlen, \ + s->name ## _len + (nla_type == NLA_NUL_STRING)),\ + s->name)) \ + goto nla_put_failure; \ + } + +#include GENL_MAGIC_INCLUDE_FILE + + +/* Functions for initializing structs to default values. */ + +#undef __field +#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \ + __is_signed) +#undef __array +#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \ + __get, __put, __is_signed) +#undef __u32_field_def +#define __u32_field_def(attr_nr, attr_flag, name, default) \ + x->name = default; +#undef __s32_field_def +#define __s32_field_def(attr_nr, attr_flag, name, default) \ + x->name = default; +#undef __flg_field_def +#define __flg_field_def(attr_nr, attr_flag, name, default) \ + x->name = default; +#undef __str_field_def +#define __str_field_def(attr_nr, attr_flag, name, maxlen) \ + memset(x->name, 0, sizeof(x->name)); \ + x->name ## _len = 0; +#undef GENL_struct +#define GENL_struct(tag_name, tag_number, s_name, s_fields) \ +static void set_ ## s_name ## _defaults(struct s_name *x) __attribute__((unused)); \ +static void set_ ## s_name ## _defaults(struct s_name *x) { \ +s_fields \ +} + +#include GENL_MAGIC_INCLUDE_FILE + +#endif /* __KERNEL__ */ + +/* }}}1 */ +#endif /* GENL_MAGIC_FUNC_H */ +/* vim: set foldmethod=marker foldlevel=1 nofoldenable : */ +drbd-headers/linux/drbd_limits.h0000644000077500007750000002221613070663767016256 0ustar shrekshrek/* + drbd_limits.h + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. +*/ + +/* + * Our current limitations. + * Some of them are hard limits, + * some of them are arbitrary range limits, that make it easier to provide + * feedback about nonsense settings for certain configurable values. + */ + +#ifndef DRBD_LIMITS_H +#define DRBD_LIMITS_H 1 + +#define DEBUG_RANGE_CHECK 0 + +#define DRBD_MINOR_COUNT_MIN 1 +#define DRBD_MINOR_COUNT_MAX 255 +#define DRBD_MINOR_COUNT_DEF 32 +#define DRBD_MINOR_COUNT_SCALE '1' + +#define DRBD_VOLUME_MAX 65535 + +#define DRBD_DIALOG_REFRESH_MIN 0 +#define DRBD_DIALOG_REFRESH_MAX 600 +#define DRBD_DIALOG_REFRESH_SCALE '1' + +/* valid port number */ +#define DRBD_PORT_MIN 1 +#define DRBD_PORT_MAX 0xffff +#define DRBD_PORT_SCALE '1' + +/* startup { */ + /* if you want more than 3.4 days, disable */ +#define DRBD_WFC_TIMEOUT_MIN 0 +#define DRBD_WFC_TIMEOUT_MAX 300000 +#define DRBD_WFC_TIMEOUT_DEF 0 +#define DRBD_WFC_TIMEOUT_SCALE '1' + +#define DRBD_DEGR_WFC_TIMEOUT_MIN 0 +#define DRBD_DEGR_WFC_TIMEOUT_MAX 300000 +#define DRBD_DEGR_WFC_TIMEOUT_DEF 0 +#define DRBD_DEGR_WFC_TIMEOUT_SCALE '1' + +#define DRBD_OUTDATED_WFC_TIMEOUT_MIN 0 +#define DRBD_OUTDATED_WFC_TIMEOUT_MAX 300000 +#define DRBD_OUTDATED_WFC_TIMEOUT_DEF 0 +#define DRBD_OUTDATED_WFC_TIMEOUT_SCALE '1' +/* }*/ + +/* net { */ + /* timeout, unit centi seconds + * more than one minute timeout is not useful */ +#define DRBD_TIMEOUT_MIN 1 +#define DRBD_TIMEOUT_MAX 600 +#define DRBD_TIMEOUT_DEF 60 /* 6 seconds */ +#define DRBD_TIMEOUT_SCALE '1' + + /* If backing disk takes longer than disk_timeout, mark the disk as failed */ +#define DRBD_DISK_TIMEOUT_MIN 0 /* 0 = disabled */ +#define DRBD_DISK_TIMEOUT_MAX 6000 /* 10 Minutes */ +#define DRBD_DISK_TIMEOUT_DEF 0 /* disabled */ +#define DRBD_DISK_TIMEOUT_SCALE '1' + + /* active connection retries when C_CONNECTING */ +#define DRBD_CONNECT_INT_MIN 1 +#define DRBD_CONNECT_INT_MAX 120 +#define DRBD_CONNECT_INT_DEF 10 /* seconds */ +#define DRBD_CONNECT_INT_SCALE '1' + + /* keep-alive probes when idle */ +#define DRBD_PING_INT_MIN 1 +#define DRBD_PING_INT_MAX 120 +#define DRBD_PING_INT_DEF 10 +#define DRBD_PING_INT_SCALE '1' + + /* timeout for the ping packets.*/ +#define DRBD_PING_TIMEO_MIN 1 +#define DRBD_PING_TIMEO_MAX 300 +#define DRBD_PING_TIMEO_DEF 5 +#define DRBD_PING_TIMEO_SCALE '1' + + /* max number of write requests between write barriers */ +#define DRBD_MAX_EPOCH_SIZE_MIN 1 +#define DRBD_MAX_EPOCH_SIZE_MAX 20000 +#define DRBD_MAX_EPOCH_SIZE_DEF 2048 +#define DRBD_MAX_EPOCH_SIZE_SCALE '1' + + /* I don't think that a tcp send buffer of more than 10M is useful */ +#define DRBD_SNDBUF_SIZE_MIN 0 +#define DRBD_SNDBUF_SIZE_MAX (10<<20) +#define DRBD_SNDBUF_SIZE_DEF 0 +#define DRBD_SNDBUF_SIZE_SCALE '1' + +#define DRBD_RCVBUF_SIZE_MIN 0 +#define DRBD_RCVBUF_SIZE_MAX (10<<20) +#define DRBD_RCVBUF_SIZE_DEF 0 +#define DRBD_RCVBUF_SIZE_SCALE '1' + + /* @4k PageSize -> 128kB - 512MB */ +#define DRBD_MAX_BUFFERS_MIN 32 +#define DRBD_MAX_BUFFERS_MAX 131072 +#define DRBD_MAX_BUFFERS_DEF 2048 +#define DRBD_MAX_BUFFERS_SCALE '1' + + /* @4k PageSize -> 4kB - 512MB */ +#define DRBD_UNPLUG_WATERMARK_MIN 1 +#define DRBD_UNPLUG_WATERMARK_MAX 131072 +#define DRBD_UNPLUG_WATERMARK_DEF (DRBD_MAX_BUFFERS_DEF/16) +#define DRBD_UNPLUG_WATERMARK_SCALE '1' + + /* 0 is disabled. + * 200 should be more than enough even for very short timeouts */ +#define DRBD_KO_COUNT_MIN 0 +#define DRBD_KO_COUNT_MAX 200 +#define DRBD_KO_COUNT_DEF 7 +#define DRBD_KO_COUNT_SCALE '1' +/* } */ + +/* syncer { */ + /* FIXME allow rate to be zero? */ +#define DRBD_RESYNC_RATE_MIN 1 +/* channel bonding 10 GbE, or other hardware */ +#define DRBD_RESYNC_RATE_MAX (4 << 20) +#define DRBD_RESYNC_RATE_DEF 250 +#define DRBD_RESYNC_RATE_SCALE 'k' /* kilobytes */ + + /* less than 67 would hit performance unnecessarily. */ +#define DRBD_AL_EXTENTS_MIN 67 + /* we use u16 as "slot number", (u16)~0 is "FREE". + * If you use >= 292 kB on-disk ring buffer, + * this is the maximum you can use: */ +#define DRBD_AL_EXTENTS_MAX 0xfffe +#define DRBD_AL_EXTENTS_DEF 1237 +#define DRBD_AL_EXTENTS_SCALE '1' + +#define DRBD_MINOR_NUMBER_MIN -1 +#define DRBD_MINOR_NUMBER_MAX ((1 << 20) - 1) +#define DRBD_MINOR_NUMBER_DEF -1 +#define DRBD_MINOR_NUMBER_SCALE '1' + +/* } */ + +/* drbdsetup XY resize -d Z + * you are free to reduce the device size to nothing, if you want to. + * the upper limit with 64bit kernel, enough ram and flexible meta data + * is 1 PiB, currently. */ +/* DRBD_MAX_SECTORS */ +#define DRBD_DISK_SIZE_MIN 0 +#define DRBD_DISK_SIZE_MAX (1 * (2LLU << 40)) +#define DRBD_DISK_SIZE_DEF 0 /* = disabled = no user size... */ +#define DRBD_DISK_SIZE_SCALE 's' /* sectors */ + +#define DRBD_ON_IO_ERROR_DEF EP_DETACH +#define DRBD_FENCING_DEF FP_DONT_CARE +#define DRBD_AFTER_SB_0P_DEF ASB_DISCONNECT +#define DRBD_AFTER_SB_1P_DEF ASB_DISCONNECT +#define DRBD_AFTER_SB_2P_DEF ASB_DISCONNECT +#define DRBD_RR_CONFLICT_DEF ASB_DISCONNECT +#define DRBD_ON_NO_DATA_DEF OND_IO_ERROR +#define DRBD_ON_CONGESTION_DEF OC_BLOCK +#define DRBD_READ_BALANCING_DEF RB_PREFER_LOCAL + +#define DRBD_MAX_BIO_BVECS_MIN 0 +#define DRBD_MAX_BIO_BVECS_MAX 128 +#define DRBD_MAX_BIO_BVECS_DEF 0 +#define DRBD_MAX_BIO_BVECS_SCALE '1' + +#define DRBD_C_PLAN_AHEAD_MIN 0 +#define DRBD_C_PLAN_AHEAD_MAX 300 +#define DRBD_C_PLAN_AHEAD_DEF 20 +#define DRBD_C_PLAN_AHEAD_SCALE '1' + +#define DRBD_C_DELAY_TARGET_MIN 1 +#define DRBD_C_DELAY_TARGET_MAX 100 +#define DRBD_C_DELAY_TARGET_DEF 10 +#define DRBD_C_DELAY_TARGET_SCALE '1' + +#define DRBD_C_FILL_TARGET_MIN 0 +#define DRBD_C_FILL_TARGET_MAX (1<<20) /* 500MByte in sec */ +#define DRBD_C_FILL_TARGET_DEF 100 /* Try to place 50KiB in socket send buffer during resync */ +#define DRBD_C_FILL_TARGET_SCALE 's' /* sectors */ + +#define DRBD_C_MAX_RATE_MIN 250 +#define DRBD_C_MAX_RATE_MAX (4 << 20) +#define DRBD_C_MAX_RATE_DEF 102400 +#define DRBD_C_MAX_RATE_SCALE 'k' /* kilobytes */ + +#define DRBD_C_MIN_RATE_MIN 0 +#define DRBD_C_MIN_RATE_MAX (4 << 20) +#define DRBD_C_MIN_RATE_DEF 250 +#define DRBD_C_MIN_RATE_SCALE 'k' /* kilobytes */ + +#define DRBD_CONG_FILL_MIN 0 +#define DRBD_CONG_FILL_MAX (10<<21) /* 10GByte in sectors */ +#define DRBD_CONG_FILL_DEF 0 +#define DRBD_CONG_FILL_SCALE 's' /* sectors */ + +#define DRBD_CONG_EXTENTS_MIN DRBD_AL_EXTENTS_MIN +#define DRBD_CONG_EXTENTS_MAX DRBD_AL_EXTENTS_MAX +#define DRBD_CONG_EXTENTS_DEF DRBD_AL_EXTENTS_DEF +#define DRBD_CONG_EXTENTS_SCALE DRBD_AL_EXTENTS_SCALE + +#define DRBD_PROTOCOL_DEF DRBD_PROT_C + +#define DRBD_DISK_BARRIER_DEF 0 +#define DRBD_DISK_FLUSHES_DEF 1 +#define DRBD_DISK_DRAIN_DEF 1 +#define DRBD_MD_FLUSHES_DEF 1 +#define DRBD_TCP_CORK_DEF 1 +#define DRBD_AL_UPDATES_DEF 1 +/* We used to ignore the discard_zeroes_data setting. + * To not change established (and expected) behaviour, + * by default assume that, for discard_zeroes_data=0, + * we can make that an effective discard_zeroes_data=1, + * if we only explicitly zero-out unaligned partial chunks. */ +#define DRBD_DISCARD_ZEROES_IF_ALIGNED_DEF 1 + +#define DRBD_ALLOW_TWO_PRIMARIES_DEF 0 +#define DRBD_ALWAYS_ASBP_DEF 0 +#define DRBD_USE_RLE_DEF 1 +#define DRBD_CSUMS_AFTER_CRASH_ONLY_DEF 0 +#define DRBD_AUTO_PROMOTE_DEF 1 + +#define DRBD_MAX_BIO_SIZE_DEF DRBD_MAX_BIO_SIZE +#define DRBD_MAX_BIO_SIZE_MIN (1 << 9) +#define DRBD_MAX_BIO_SIZE_MAX DRBD_MAX_BIO_SIZE +#define DRBD_MAX_BIO_SIZE_SCALE '1' + +#define DRBD_NODE_ID_DEF 0 +#define DRBD_NODE_ID_MIN 0 +#ifndef DRBD_NODE_ID_MAX /* Is also defined in drbd.h */ +#define DRBD_NODE_ID_MAX DRBD_PEERS_MAX +#endif +#define DRBD_NODE_ID_SCALE '1' + +#define DRBD_PEER_ACK_WINDOW_DEF 4096 /* 2 MiByte */ +#define DRBD_PEER_ACK_WINDOW_MIN 2048 /* 1 MiByte */ +#define DRBD_PEER_ACK_WINDOW_MAX 204800 /* 100 MiByte */ +#define DRBD_PEER_ACK_WINDOW_SCALE 's' /* sectors*/ + +#define DRBD_PEER_ACK_DELAY_DEF 100 /* 100ms */ +#define DRBD_PEER_ACK_DELAY_MIN 1 +#define DRBD_PEER_ACK_DELAY_MAX 10000 /* 10 seconds */ +#define DRBD_PEER_ACK_DELAY_SCALE '1' /* milliseconds */ + +/* Two-phase commit timeout (1/10 seconds). */ +#define DRBD_TWOPC_TIMEOUT_MIN 50 +#define DRBD_TWOPC_TIMEOUT_MAX 600 +#define DRBD_TWOPC_TIMEOUT_DEF 300 +#define DRBD_TWOPC_TIMEOUT_SCALE '1' + +#define DRBD_TWOPC_RETRY_TIMEOUT_MIN 1 +#define DRBD_TWOPC_RETRY_TIMEOUT_MAX 50 +#define DRBD_TWOPC_RETRY_TIMEOUT_DEF 1 +#define DRBD_TWOPC_RETRY_TIMEOUT_SCALE '1' + +#define DRBD_SYNC_FROM_NID_DEF -1 +#define DRBD_SYNC_FROM_NID_MIN -1 +#define DRBD_SYNC_FROM_NID_MAX DRBD_PEERS_MAX +#define DRBD_SYNC_FROM_NID_SCALE '1' + +#define DRBD_AL_STRIPES_MIN 1 +#define DRBD_AL_STRIPES_MAX 1024 +#define DRBD_AL_STRIPES_DEF 1 +#define DRBD_AL_STRIPES_SCALE '1' + +#define DRBD_AL_STRIPE_SIZE_MIN 4 +#define DRBD_AL_STRIPE_SIZE_MAX 16777216 +#define DRBD_AL_STRIPE_SIZE_DEF 32 +#define DRBD_AL_STRIPE_SIZE_SCALE 'k' /* kilobytes */ + +#define DRBD_SOCKET_CHECK_TIMEO_MIN 0 +#define DRBD_SOCKET_CHECK_TIMEO_MAX DRBD_PING_TIMEO_MAX +#define DRBD_SOCKET_CHECK_TIMEO_DEF 0 +#define DRBD_SOCKET_CHECK_TIMEO_SCALE '1' + +/* Auto promote timeout (1/10 seconds). */ +#define DRBD_AUTO_PROMOTE_TIMEOUT_MIN 0 +#define DRBD_AUTO_PROMOTE_TIMEOUT_MAX 600 +#define DRBD_AUTO_PROMOTE_TIMEOUT_DEF 20 +#define DRBD_AUTO_PROMOTE_TIMEOUT_SCALE '1' + +#define DRBD_RS_DISCARD_GRANULARITY_MIN 0 +#define DRBD_RS_DISCARD_GRANULARITY_MAX (1<<20) /* 1MiByte */ +#define DRBD_RS_DISCARD_GRANULARITY_DEF 0 /* disabled by default */ +#define DRBD_RS_DISCARD_GRANULARITY_SCALE '1' /* bytes */ + +#endif +drbd-headers/linux/genl_magic_struct.h0000644000077500007750000001673013070663767017457 0ustar shrekshrek#ifndef GENL_MAGIC_STRUCT_H +#define GENL_MAGIC_STRUCT_H + +#ifndef GENL_MAGIC_FAMILY +# error "you need to define GENL_MAGIC_FAMILY before inclusion" +#endif + +#ifndef GENL_MAGIC_VERSION +# error "you need to define GENL_MAGIC_VERSION before inclusion" +#endif + +#ifndef GENL_MAGIC_INCLUDE_FILE +# error "you need to define GENL_MAGIC_INCLUDE_FILE before inclusion" +#endif + +#include +#include +#include + +#define CONCAT__(a,b) a ## b +#define CONCAT_(a,b) CONCAT__(a,b) + +extern int CONCAT_(GENL_MAGIC_FAMILY, _genl_register)(void); +extern void CONCAT_(GENL_MAGIC_FAMILY, _genl_unregister)(void); + +/* + * Extension of genl attribute validation policies {{{2 + */ + +/* + * @DRBD_GENLA_F_MANDATORY: By default, netlink ignores attributes it does not + * know about. This flag can be set in nlattr->nla_type to indicate that this + * attribute must not be ignored. + * + * We check and remove this flag in drbd_nla_check_mandatory() before + * validating the attribute types and lengths via nla_parse_nested(). + */ +#define DRBD_GENLA_F_MANDATORY (1 << 14) + +/* + * Flags specific to drbd and not visible at the netlink layer, used in + * _from_attrs and _to_skb: + * + * @DRBD_F_REQUIRED: Attribute is required; a request without this attribute is + * invalid. + * + * @DRBD_F_SENSITIVE: Attribute includes sensitive information and must not be + * included in unpriviledged get requests or broadcasts. + * + * @DRBD_F_INVARIANT: Attribute is set when an object is initially created, but + * cannot subsequently be changed. + */ +#define DRBD_F_REQUIRED (1 << 0) +#define DRBD_F_SENSITIVE (1 << 1) +#define DRBD_F_INVARIANT (1 << 2) + +#define __nla_type(x) ((__u16)((x) & NLA_TYPE_MASK & ~DRBD_GENLA_F_MANDATORY)) + +/* }}}1 + * MAGIC + * multi-include macro expansion magic starts here + */ + +/* MAGIC helpers {{{2 */ + +/* possible field types */ +#define __flg_field(attr_nr, attr_flag, name) \ + __field(attr_nr, attr_flag, name, NLA_U8, char, \ + nla_get_u8, nla_put_u8, false) +#define __u8_field(attr_nr, attr_flag, name) \ + __field(attr_nr, attr_flag, name, NLA_U8, unsigned char, \ + nla_get_u8, nla_put_u8, false) +#define __u16_field(attr_nr, attr_flag, name) \ + __field(attr_nr, attr_flag, name, NLA_U16, __u16, \ + nla_get_u16, nla_put_u16, false) +#define __u32_field(attr_nr, attr_flag, name) \ + __field(attr_nr, attr_flag, name, NLA_U32, __u32, \ + nla_get_u32, nla_put_u32, false) +#define __s32_field(attr_nr, attr_flag, name) \ + __field(attr_nr, attr_flag, name, NLA_U32, __s32, \ + nla_get_u32, nla_put_u32, true) +#define __u64_field(attr_nr, attr_flag, name) \ + __field(attr_nr, attr_flag, name, NLA_U64, __u64, \ + nla_get_u64, nla_put_u64, false) +#define __str_field(attr_nr, attr_flag, name, maxlen) \ + __array(attr_nr, attr_flag, name, NLA_NUL_STRING, char, maxlen, \ + nla_strlcpy, nla_put, false) +#define __bin_field(attr_nr, attr_flag, name, maxlen) \ + __array(attr_nr, attr_flag, name, NLA_BINARY, char, maxlen, \ + nla_memcpy, nla_put, false) + +/* fields with default values */ +#define __flg_field_def(attr_nr, attr_flag, name, default) \ + __flg_field(attr_nr, attr_flag, name) +#define __u32_field_def(attr_nr, attr_flag, name, default) \ + __u32_field(attr_nr, attr_flag, name) +#define __s32_field_def(attr_nr, attr_flag, name, default) \ + __s32_field(attr_nr, attr_flag, name) +#define __str_field_def(attr_nr, attr_flag, name, maxlen) \ + __str_field(attr_nr, attr_flag, name, maxlen) + +#define GENL_op_init(args...) args +#define GENL_doit(handler) \ + .doit = handler, \ + .flags = GENL_ADMIN_PERM, +#define GENL_dumpit(handler) \ + .dumpit = handler, \ + .flags = GENL_ADMIN_PERM, + +/* }}}1 + * Magic: define the enum symbols for genl_ops + * Magic: define the enum symbols for top level attributes + * Magic: define the enum symbols for nested attributes + * {{{2 + */ + +#undef GENL_struct +#define GENL_struct(tag_name, tag_number, s_name, s_fields) + +#undef GENL_mc_group +#define GENL_mc_group(group) + +#undef GENL_notification +#define GENL_notification(op_name, op_num, mcast_group, tla_list) \ + op_name = op_num, + +#undef GENL_op +#define GENL_op(op_name, op_num, handler, tla_list) \ + op_name = op_num, + +enum { +#include GENL_MAGIC_INCLUDE_FILE +}; + +#undef GENL_notification +#define GENL_notification(op_name, op_num, mcast_group, tla_list) + +#undef GENL_op +#define GENL_op(op_name, op_num, handler, attr_list) + +#undef GENL_struct +#define GENL_struct(tag_name, tag_number, s_name, s_fields) \ + tag_name = tag_number, + +enum { +#include GENL_MAGIC_INCLUDE_FILE +}; + +#undef GENL_struct +#define GENL_struct(tag_name, tag_number, s_name, s_fields) \ +enum { \ + s_fields \ +}; + +#undef __field +#define __field(attr_nr, attr_flag, name, nla_type, type, \ + __get, __put, __is_signed) \ + T_ ## name = (__u16)(attr_nr | ((attr_flag) & DRBD_GENLA_F_MANDATORY)), + +#undef __array +#define __array(attr_nr, attr_flag, name, nla_type, type, \ + maxlen, __get, __put, __is_signed) \ + T_ ## name = (__u16)(attr_nr | ((attr_flag) & DRBD_GENLA_F_MANDATORY)), + +#include GENL_MAGIC_INCLUDE_FILE + +/* }}}1 + * Magic: compile time assert unique numbers for operations + * Magic: -"- unique numbers for top level attributes + * Magic: -"- unique numbers for nested attributes + * {{{2 + */ + +#undef GENL_struct +#define GENL_struct(tag_name, tag_number, s_name, s_fields) + +#undef GENL_op +#define GENL_op(op_name, op_num, handler, attr_list) \ + case op_name: + +#undef GENL_notification +#define GENL_notification(op_name, op_num, mcast_group, tla_list) \ + case op_name: + +static inline void ct_assert_unique_operations(void) +{ + switch (0) { +#include GENL_MAGIC_INCLUDE_FILE + ; + } +} + +#undef GENL_op +#define GENL_op(op_name, op_num, handler, attr_list) + +#undef GENL_notification +#define GENL_notification(op_name, op_num, mcast_group, tla_list) + +#undef GENL_struct +#define GENL_struct(tag_name, tag_number, s_name, s_fields) \ + case tag_number: + +static inline void ct_assert_unique_top_level_attributes(void) +{ + switch (0) { +#include GENL_MAGIC_INCLUDE_FILE + ; + } +} + +#undef GENL_struct +#define GENL_struct(tag_name, tag_number, s_name, s_fields) \ +static inline void ct_assert_unique_ ## s_name ## _attributes(void) \ +{ \ + switch (0) { \ + s_fields \ + ; \ + } \ +} + +#undef __field +#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \ + __is_signed) \ + case attr_nr: + +#undef __array +#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \ + __get, __put, __is_signed) \ + case attr_nr: + +#include GENL_MAGIC_INCLUDE_FILE + +/* }}}1 + * Magic: declare structs + * struct { + * fields + * }; + * {{{2 + */ + +#undef GENL_struct +#define GENL_struct(tag_name, tag_number, s_name, s_fields) \ +struct s_name { s_fields }; + +#undef __field +#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \ + __is_signed) \ + type name; + +#undef __array +#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \ + __get, __put, __is_signed) \ + type name[maxlen]; \ + __u32 name ## _len; + +#include GENL_MAGIC_INCLUDE_FILE + +#undef GENL_struct +#define GENL_struct(tag_name, tag_number, s_name, s_fields) \ +enum { \ + s_fields \ +}; + +#undef __field +#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \ + is_signed) \ + F_ ## name ## _IS_SIGNED = is_signed, + +#undef __array +#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \ + __get, __put, is_signed) \ + F_ ## name ## _IS_SIGNED = is_signed, + +#include GENL_MAGIC_INCLUDE_FILE + +/* }}}1 */ +#endif /* GENL_MAGIC_STRUCT_H */ +/* vim: set foldmethod=marker nofoldenable : */ +drbd-headers/linux/drbd_genl_api.h0000644000077500007750000000234613070663767016535 0ustar shrekshrek#ifndef DRBD_GENL_STRUCT_H +#define DRBD_GENL_STRUCT_H + +/** + * struct drbd_genlmsghdr - DRBD specific header used in NETLINK_GENERIC requests + * @minor: + * For admin requests (user -> kernel): which minor device to operate on. + * For (unicast) replies or informational (broadcast) messages + * (kernel -> user): which minor device the information is about. + * If we do not operate on minors, but on connections or resources, + * the minor value shall be (~0), and the attribute DRBD_NLA_CFG_CONTEXT + * is used instead. + * @flags: possible operation modifiers (relevant only for user->kernel): + * DRBD_GENL_F_SET_DEFAULTS + * @ret_code: kernel->userland unicast cfg reply return code (union with flags); + */ +struct drbd_genlmsghdr { + __u32 minor; + union { + __u32 flags; + __s32 ret_code; + }; +}; + +/* To be used in drbd_genlmsghdr.flags */ +enum { + DRBD_GENL_F_SET_DEFAULTS = 1, +}; + +/* hack around predefined gcc/cpp "linux=1", + * we cannot possibly include <1/drbd_genl.h> */ +#undef linux + +#include +#define GENL_MAGIC_VERSION 2 +#define GENL_MAGIC_FAMILY drbd +#define GENL_MAGIC_FAMILY_HDRSZ sizeof(struct drbd_genlmsghdr) +#define GENL_MAGIC_INCLUDE_FILE +#include + +#endif +drbd-headers/linux/drbd.h0000644000077500007750000002634513070663767014704 0ustar shrekshrek/* + drbd.h + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. + Copyright (C) 2001-2008, Philipp Reisner . + Copyright (C) 2001-2008, Lars Ellenberg . + + drbd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + drbd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +#ifndef DRBD_H +#define DRBD_H + +#include + +#ifdef __KERNEL__ +#include +#include +#else +#include +#include +#include + +/* Although the Linux source code makes a difference between + generic endianness and the bitfields' endianness, there is no + architecture as of Linux-2.6.24-rc4 where the bitfields' endianness + does not match the generic endianness. */ + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define __LITTLE_ENDIAN_BITFIELD +#elif __BYTE_ORDER == __BIG_ENDIAN +#define __BIG_ENDIAN_BITFIELD +#else +# error "sorry, weird endianness on this box" +#endif + +#endif + +enum drbd_io_error_p { + EP_PASS_ON, /* FIXME should the better be named "Ignore"? */ + EP_CALL_HELPER, + EP_DETACH +}; + +enum drbd_fencing_policy { + FP_DONT_CARE = 0, + FP_RESOURCE, + FP_STONITH +}; + +enum drbd_disconnect_p { + DP_RECONNECT, + DP_DROP_NET_CONF, + DP_FREEZE_IO +}; + +enum drbd_after_sb_p { + ASB_DISCONNECT, + ASB_DISCARD_YOUNGER_PRI, + ASB_DISCARD_OLDER_PRI, + ASB_DISCARD_ZERO_CHG, + ASB_DISCARD_LEAST_CHG, + ASB_DISCARD_LOCAL, + ASB_DISCARD_REMOTE, + ASB_CONSENSUS, + ASB_DISCARD_SECONDARY, + ASB_CALL_HELPER, + ASB_VIOLENTLY +}; + +enum drbd_on_no_data { + OND_IO_ERROR, + OND_SUSPEND_IO +}; + +enum drbd_on_congestion { + OC_BLOCK, + OC_PULL_AHEAD, + OC_DISCONNECT, +}; + +enum drbd_read_balancing { + RB_PREFER_LOCAL, + RB_PREFER_REMOTE, + RB_ROUND_ROBIN, + RB_LEAST_PENDING, + RB_CONGESTED_REMOTE, + RB_32K_STRIPING, + RB_64K_STRIPING, + RB_128K_STRIPING, + RB_256K_STRIPING, + RB_512K_STRIPING, + RB_1M_STRIPING, +}; + +/* KEEP the order, do not delete or insert. Only append. */ +enum drbd_ret_code { + ERR_CODE_BASE = 100, + NO_ERROR = 101, + ERR_LOCAL_ADDR = 102, + ERR_PEER_ADDR = 103, + ERR_OPEN_DISK = 104, + ERR_OPEN_MD_DISK = 105, + ERR_DISK_NOT_BDEV = 107, + ERR_MD_NOT_BDEV = 108, + ERR_DISK_TOO_SMALL = 111, + ERR_MD_DISK_TOO_SMALL = 112, + ERR_BDCLAIM_DISK = 114, + ERR_BDCLAIM_MD_DISK = 115, + ERR_MD_IDX_INVALID = 116, + ERR_IO_MD_DISK = 118, + ERR_MD_INVALID = 119, + ERR_AUTH_ALG = 120, + ERR_AUTH_ALG_ND = 121, + ERR_NOMEM = 122, + ERR_DISCARD_IMPOSSIBLE = 123, + ERR_DISK_CONFIGURED = 124, + ERR_NET_CONFIGURED = 125, + ERR_MANDATORY_TAG = 126, + ERR_MINOR_INVALID = 127, + ERR_INTR = 129, /* EINTR */ + ERR_RESIZE_RESYNC = 130, + ERR_NO_PRIMARY = 131, + ERR_RESYNC_AFTER = 132, + ERR_RESYNC_AFTER_CYCLE = 133, + ERR_PAUSE_IS_SET = 134, + ERR_PAUSE_IS_CLEAR = 135, + ERR_PACKET_NR = 137, + ERR_NO_DISK = 138, + ERR_NOT_PROTO_C = 139, + ERR_NOMEM_BITMAP = 140, + ERR_INTEGRITY_ALG = 141, /* DRBD 8.2 only */ + ERR_INTEGRITY_ALG_ND = 142, /* DRBD 8.2 only */ + ERR_CPU_MASK_PARSE = 143, /* DRBD 8.2 only */ + ERR_CSUMS_ALG = 144, /* DRBD 8.2 only */ + ERR_CSUMS_ALG_ND = 145, /* DRBD 8.2 only */ + ERR_VERIFY_ALG = 146, /* DRBD 8.2 only */ + ERR_VERIFY_ALG_ND = 147, /* DRBD 8.2 only */ + ERR_CSUMS_RESYNC_RUNNING= 148, /* DRBD 8.2 only */ + ERR_VERIFY_RUNNING = 149, /* DRBD 8.2 only */ + ERR_DATA_NOT_CURRENT = 150, + ERR_CONNECTED = 151, /* DRBD 8.3 only */ + ERR_PERM = 152, + ERR_NEED_APV_93 = 153, + ERR_STONITH_AND_PROT_A = 154, + ERR_CONG_NOT_PROTO_A = 155, + ERR_PIC_AFTER_DEP = 156, + ERR_PIC_PEER_DEP = 157, + ERR_RES_NOT_KNOWN = 158, + ERR_RES_IN_USE = 159, + ERR_MINOR_CONFIGURED = 160, + ERR_MINOR_OR_VOLUME_EXISTS = 161, + ERR_INVALID_REQUEST = 162, + ERR_NEED_APV_100 = 163, + ERR_NEED_ALLOW_TWO_PRI = 164, + ERR_MD_UNCLEAN = 165, + ERR_MD_LAYOUT_CONNECTED = 166, + ERR_MD_LAYOUT_TOO_BIG = 167, + ERR_MD_LAYOUT_TOO_SMALL = 168, + ERR_MD_LAYOUT_NO_FIT = 169, + ERR_IMPLICIT_SHRINK = 170, + ERR_INVALID_PEER_NODE_ID = 171, + ERR_CREATE_TRANSPORT = 172, + ERR_LOCAL_AND_PEER_ADDR = 173, + + /* insert new ones above this line */ + AFTER_LAST_ERR_CODE +}; + +#define DRBD_PROT_A 1 +#define DRBD_PROT_B 2 +#define DRBD_PROT_C 3 + +enum drbd_role { + R_UNKNOWN = 0, + R_PRIMARY = 1, /* role */ + R_SECONDARY = 2, /* role */ + R_MASK = 3, +}; + +/* The order of these constants is important. + * The lower ones (< C_CONNECTED) indicate + * that there is no socket! + * >= C_CONNECTED ==> There is a socket + */ +enum drbd_conn_state { + C_STANDALONE, + C_DISCONNECTING, /* Temporary state on the way to C_STANDALONE. */ + C_UNCONNECTED, /* >= C_UNCONNECTED -> inc_net() succeeds */ + + /* These temporary states are used on the way + * from C_CONNECTED to C_UNCONNECTED. + * The 'disconnect reason' states + * I do not allow to change between them. */ + C_TIMEOUT, + C_BROKEN_PIPE, + C_NETWORK_FAILURE, + C_PROTOCOL_ERROR, + C_TEAR_DOWN, + + C_CONNECTING, + + C_CONNECTED, /* we have a socket */ + + C_MASK = 31, +}; + +enum drbd_repl_state { + L_NEGOTIATING = C_CONNECTED, /* used for peer_device->negotiation_result only */ + L_OFF = C_CONNECTED, + + L_ESTABLISHED, /* we have introduced each other */ + L_STARTING_SYNC_S, /* starting full sync by admin request. */ + L_STARTING_SYNC_T, /* starting full sync by admin request. */ + L_WF_BITMAP_S, + L_WF_BITMAP_T, + L_WF_SYNC_UUID, + + /* All SyncStates are tested with this comparison + * xx >= L_SYNC_SOURCE && xx <= L_PAUSED_SYNC_T */ + L_SYNC_SOURCE, + L_SYNC_TARGET, + L_VERIFY_S, + L_VERIFY_T, + L_PAUSED_SYNC_S, + L_PAUSED_SYNC_T, + + L_AHEAD, + L_BEHIND, + L_NEG_NO_RESULT = L_BEHIND, /* used for peer_device->negotiation_result only */ +}; + +enum drbd_disk_state { + D_DISKLESS, + D_ATTACHING, /* In the process of reading the meta-data */ + D_DETACHING, /* Added in protocol version 110 */ + D_FAILED, /* Becomes D_DISKLESS as soon as we told it the peer */ + /* when >= D_FAILED it is legal to access device->ldev */ + D_NEGOTIATING, /* Late attaching state, we need to talk to the peer */ + D_INCONSISTENT, + D_OUTDATED, + D_UNKNOWN, /* Only used for the peer, never for myself */ + D_CONSISTENT, /* Might be D_OUTDATED, might be D_UP_TO_DATE ... */ + D_UP_TO_DATE, /* Only this disk state allows applications' IO ! */ + D_MASK = 15 +}; + +union drbd_state { +/* According to gcc's docs is the ... + * The order of allocation of bit-fields within a unit (C90 6.5.2.1, C99 6.7.2.1). + * Determined by ABI. + * pointed out by Maxim Uvarov q + * even though we transmit as "cpu_to_be32(state)", + * the offsets of the bitfields still need to be swapped + * on different endianness. + */ + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned role:2 ; /* 3/4 primary/secondary/unknown */ + unsigned peer:2 ; /* 3/4 primary/secondary/unknown */ + unsigned conn:5 ; /* 17/32 cstates */ + unsigned disk:4 ; /* 8/16 from D_DISKLESS to D_UP_TO_DATE */ + unsigned pdsk:4 ; /* 8/16 from D_DISKLESS to D_UP_TO_DATE */ + unsigned susp:1 ; /* 2/2 IO suspended no/yes (by user) */ + unsigned aftr_isp:1 ; /* isp .. imposed sync pause */ + unsigned peer_isp:1 ; + unsigned user_isp:1 ; + unsigned susp_nod:1 ; /* IO suspended because no data */ + unsigned susp_fen:1 ; /* IO suspended because fence peer handler runs*/ + unsigned _pad:9; /* 0 unused */ +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned _pad:9; + unsigned susp_fen:1 ; + unsigned susp_nod:1 ; + unsigned user_isp:1 ; + unsigned peer_isp:1 ; + unsigned aftr_isp:1 ; /* isp .. imposed sync pause */ + unsigned susp:1 ; /* 2/2 IO suspended no/yes */ + unsigned pdsk:4 ; /* 8/16 from D_DISKLESS to D_UP_TO_DATE */ + unsigned disk:4 ; /* 8/16 from D_DISKLESS to D_UP_TO_DATE */ + unsigned conn:5 ; /* 17/32 cstates */ + unsigned peer:2 ; /* 3/4 primary/secondary/unknown */ + unsigned role:2 ; /* 3/4 primary/secondary/unknown */ +#else +# error "this endianness is not supported" +#endif + }; + unsigned int i; +}; + +enum drbd_state_rv { + SS_CW_NO_NEED = 4, + SS_CW_SUCCESS = 3, + SS_NOTHING_TO_DO = 2, + SS_SUCCESS = 1, + SS_UNKNOWN_ERROR = 0, /* Used to sleep longer in _drbd_request_state */ + SS_TWO_PRIMARIES = -1, + SS_NO_UP_TO_DATE_DISK = -2, + SS_NO_LOCAL_DISK = -4, + SS_NO_REMOTE_DISK = -5, + SS_CONNECTED_OUTDATES = -6, + SS_PRIMARY_NOP = -7, + SS_RESYNC_RUNNING = -8, + SS_ALREADY_STANDALONE = -9, + SS_CW_FAILED_BY_PEER = -10, + SS_IS_DISKLESS = -11, + SS_DEVICE_IN_USE = -12, + SS_NO_NET_CONFIG = -13, + SS_NO_VERIFY_ALG = -14, /* drbd-8.2 only */ + SS_NEED_CONNECTION = -15, + SS_LOWER_THAN_OUTDATED = -16, + SS_NOT_SUPPORTED = -17, + SS_IN_TRANSIENT_STATE = -18, /* Retry after the next state change */ + SS_CONCURRENT_ST_CHG = -19, /* Concurrent cluster side state change! */ + SS_O_VOL_PEER_PRI = -20, + SS_INTERRUPTED = -21, /* interrupted in stable_state_change() */ + SS_PRIMARY_READER = -22, + SS_TIMEOUT = -23, + SS_WEAKLY_CONNECTED = -24, + SS_AFTER_LAST_ERROR = -25, /* Keep this at bottom */ +}; + +#define SHARED_SECRET_MAX 64 + +enum mdf_flag { + MDF_CONSISTENT = 1 << 0, + MDF_PRIMARY_IND = 1 << 1, + MDF_WAS_UP_TO_DATE = 1 << 4, + MDF_CRASHED_PRIMARY = 1 << 6, + MDF_AL_CLEAN = 1 << 7, + MDF_AL_DISABLED = 1 << 8, +}; + +enum mdf_peer_flag { + MDF_PEER_CONNECTED = 1 << 0, + MDF_PEER_OUTDATED = 1 << 1, + MDF_PEER_FENCING = 1 << 2, + MDF_PEER_FULL_SYNC = 1 << 3, + MDF_NODE_EXISTS = 1 << 16, /* */ +}; + +#define DRBD_PEERS_MAX 32 +#define DRBD_NODE_ID_MAX DRBD_PEERS_MAX + +enum drbd_uuid_index { + UI_CURRENT, + UI_BITMAP, + UI_HISTORY_START, + UI_HISTORY_END, + UI_SIZE, /* nl-packet: number of dirty bits */ + UI_FLAGS, /* nl-packet: flags */ + UI_EXTENDED_SIZE /* Everything. */ +}; + +#define HISTORY_UUIDS_V08 (UI_HISTORY_END - UI_HISTORY_START + 1) +#define HISTORY_UUIDS DRBD_PEERS_MAX + +enum drbd_timeout_flag { + UT_DEFAULT = 0, + UT_DEGRADED = 1, + UT_PEER_OUTDATED = 2, +}; + +#define UUID_JUST_CREATED ((__u64)4) +#define UUID_PRIMARY ((__u64)1) + +enum write_ordering_e { + WO_NONE, + WO_DRAIN_IO, + WO_BDEV_FLUSH, + WO_BIO_BARRIER +}; + +enum drbd_notification_type { + NOTIFY_EXISTS, + NOTIFY_CREATE, + NOTIFY_CHANGE, + NOTIFY_DESTROY, + NOTIFY_CALL, + NOTIFY_RESPONSE, + + NOTIFY_CONTINUES = 0x8000, + NOTIFY_FLAGS = NOTIFY_CONTINUES, +}; + +/* These values are part of the ABI! */ +enum drbd_peer_state { + P_INCONSISTENT = 3, + P_OUTDATED = 4, + P_DOWN = 5, + P_PRIMARY = 6, + P_FENCING = 7, +}; + +/* magic numbers used in meta data and network packets */ +#define DRBD_MAGIC 0x83740267 +#define DRBD_MAGIC_BIG 0x835a +#define DRBD_MAGIC_100 0x8620ec20 + +#define DRBD_MD_MAGIC_07 (DRBD_MAGIC+3) +#define DRBD_MD_MAGIC_08 (DRBD_MAGIC+4) +#define DRBD_MD_MAGIC_84_UNCLEAN (DRBD_MAGIC+5) +#define DRBD_MD_MAGIC_09 (DRBD_MAGIC+6) + +/* how I came up with this magic? + * base64 decode "actlog==" ;) */ +#define DRBD_AL_MAGIC 0x69cb65a2 + +/* these are of type "int" */ +#define DRBD_MD_INDEX_INTERNAL -1 +#define DRBD_MD_INDEX_FLEX_EXT -2 +#define DRBD_MD_INDEX_FLEX_INT -3 + +#define DRBD_CPU_MASK_SIZE 32 + +#define DRBD_MAX_BIO_SIZE (1U << 20) + +#endif +drbd-headers/linux/drbd_genl.h0000644000077500007750000005333013070663767015703 0ustar shrekshrek/* + * General overview: + * full generic netlink message: + * |nlmsghdr|genlmsghdr| + * + * payload: + * |optional fixed size family header| + * + * sequence of netlink attributes: + * I chose to have all "top level" attributes NLA_NESTED, + * corresponding to some real struct. + * So we have a sequence of |tla, len| + * + * nested nla sequence: + * may be empty, or contain a sequence of netlink attributes + * representing the struct fields. + * + * The tag number of any field (regardless of containing struct) + * will be available as T_ ## field_name, + * so you cannot have the same field name in two differnt structs. + * + * The tag numbers themselves are per struct, though, + * so should always begin at 1 (not 0, that is the special "NLA_UNSPEC" type, + * which we won't use here). + * The tag numbers are used as index in the respective nla_policy array. + * + * GENL_struct(tag_name, tag_number, struct name, struct fields) - struct and policy + * genl_magic_struct.h + * generates the struct declaration, + * generates an entry in the tla enum, + * genl_magic_func.h + * generates an entry in the static tla policy + * with .type = NLA_NESTED + * generates the static _nl_policy definition, + * and static conversion functions + * + * genl_magic_func.h + * + * GENL_mc_group(group) + * genl_magic_struct.h + * does nothing + * genl_magic_func.h + * defines and registers the mcast group, + * and provides a send helper + * + * GENL_notification(op_name, op_num, mcast_group, tla list) + * These are notifications to userspace. + * + * genl_magic_struct.h + * generates an entry in the genl_ops enum, + * genl_magic_func.h + * does nothing + * + * mcast group: the name of the mcast group this notification should be + * expected on + * tla list: the list of expected top level attributes, + * for documentation and sanity checking. + * + * GENL_op(op_name, op_num, flags and handler, tla list) - "genl operations" + * These are requests from userspace. + * + * _op and _notification share the same "number space", + * op_nr will be assigned to "genlmsghdr->cmd" + * + * genl_magic_struct.h + * generates an entry in the genl_ops enum, + * genl_magic_func.h + * generates an entry in the static genl_ops array, + * and static register/unregister functions to + * genl_register_family_with_ops(). + * + * flags and handler: + * GENL_op_init( .doit = x, .dumpit = y, .flags = something) + * GENL_doit(x) => .dumpit = NULL, .flags = GENL_ADMIN_PERM + * tla list: the list of expected top level attributes, + * for documentation and sanity checking. + */ + +/* + * STRUCTS + */ + +/* this is sent kernel -> userland on various error conditions, and contains + * informational textual info, which is supposedly human readable. + * The computer relevant return code is in the drbd_genlmsghdr. + */ +GENL_struct(DRBD_NLA_CFG_REPLY, 1, drbd_cfg_reply, + /* "arbitrary" size strings, nla_policy.len = 0 */ + __str_field(1, DRBD_GENLA_F_MANDATORY, info_text, 0) +) + +/* Configuration requests typically need a context to operate on. + * Possible keys are device minor (fits in the drbd_genlmsghdr), + * the replication link (aka connection) name, + * and/or the replication group (aka resource) name, + * and the volume id within the resource. */ +GENL_struct(DRBD_NLA_CFG_CONTEXT, 2, drbd_cfg_context, + __u32_field(6, DRBD_GENLA_F_MANDATORY, ctx_peer_node_id) + __u32_field(1, DRBD_GENLA_F_MANDATORY, ctx_volume) + __str_field(2, DRBD_GENLA_F_MANDATORY, ctx_resource_name, 128) + __bin_field(3, DRBD_GENLA_F_MANDATORY, ctx_my_addr, 128) + __bin_field(4, DRBD_GENLA_F_MANDATORY, ctx_peer_addr, 128) + __str_field_def(5, 0, ctx_conn_name, SHARED_SECRET_MAX) +) + +GENL_struct(DRBD_NLA_DISK_CONF, 3, disk_conf, + __str_field(1, DRBD_F_REQUIRED | DRBD_F_INVARIANT, backing_dev, 128) + __str_field(2, DRBD_F_REQUIRED | DRBD_F_INVARIANT, meta_dev, 128) + __s32_field(3, DRBD_F_REQUIRED | DRBD_F_INVARIANT, meta_dev_idx) + + /* use the resize command to try and change the disk_size */ + __u64_field(4, DRBD_GENLA_F_MANDATORY | DRBD_F_INVARIANT, disk_size) + /*__u32_field(5, DRBD_GENLA_F_MANDATORY | DRBD_F_INVARIANT, max_bio_bvecs)*/ + + __u32_field_def(6, DRBD_GENLA_F_MANDATORY, on_io_error, DRBD_ON_IO_ERROR_DEF) + /*__u32_field_def(7, DRBD_GENLA_F_MANDATORY, fencing_policy, DRBD_FENCING_DEF)*/ + + __s32_field_def(9, DRBD_GENLA_F_MANDATORY, resync_after, DRBD_MINOR_NUMBER_DEF) + __u32_field_def(10, DRBD_GENLA_F_MANDATORY, al_extents, DRBD_AL_EXTENTS_DEF) + + __flg_field_def(16, DRBD_GENLA_F_MANDATORY, disk_barrier, DRBD_DISK_BARRIER_DEF) + __flg_field_def(17, DRBD_GENLA_F_MANDATORY, disk_flushes, DRBD_DISK_FLUSHES_DEF) + __flg_field_def(18, DRBD_GENLA_F_MANDATORY, disk_drain, DRBD_DISK_DRAIN_DEF) + __flg_field_def(19, DRBD_GENLA_F_MANDATORY, md_flushes, DRBD_MD_FLUSHES_DEF) + __u32_field_def(20, DRBD_GENLA_F_MANDATORY, disk_timeout, DRBD_DISK_TIMEOUT_DEF) + __u32_field_def(21, DRBD_GENLA_F_MANDATORY, read_balancing, DRBD_READ_BALANCING_DEF) + __u32_field_def(22, DRBD_GENLA_F_MANDATORY, unplug_watermark, DRBD_UNPLUG_WATERMARK_DEF) + __u32_field_def(25, 0 /* OPTIONAL */, rs_discard_granularity, DRBD_RS_DISCARD_GRANULARITY_DEF) + __flg_field_def(23, 0 /* OPTIONAL */, al_updates, DRBD_AL_UPDATES_DEF) + __flg_field_def(24, 0 /* OPTIONAL */, discard_zeroes_if_aligned, DRBD_DISCARD_ZEROES_IF_ALIGNED_DEF) +) + +GENL_struct(DRBD_NLA_RESOURCE_OPTS, 4, res_opts, + __str_field_def(1, DRBD_GENLA_F_MANDATORY, cpu_mask, DRBD_CPU_MASK_SIZE) + __u32_field_def(2, DRBD_GENLA_F_MANDATORY, on_no_data, DRBD_ON_NO_DATA_DEF) + __flg_field_def(3, DRBD_GENLA_F_MANDATORY, auto_promote, DRBD_AUTO_PROMOTE_DEF) + __u32_field(4, DRBD_F_REQUIRED | DRBD_F_INVARIANT, node_id) + __u32_field_def(5, DRBD_GENLA_F_MANDATORY, peer_ack_window, DRBD_PEER_ACK_WINDOW_DEF) + __u32_field_def(6, DRBD_GENLA_F_MANDATORY, twopc_timeout, DRBD_TWOPC_TIMEOUT_DEF) + __u32_field_def(7, DRBD_GENLA_F_MANDATORY, twopc_retry_timeout, DRBD_TWOPC_RETRY_TIMEOUT_DEF) + __u32_field_def(8, 0 /* OPTIONAL */, peer_ack_delay, DRBD_PEER_ACK_DELAY_DEF) + __u32_field_def(9, 0 /* OPTIONAL */, auto_promote_timeout, DRBD_AUTO_PROMOTE_TIMEOUT_DEF) +) + +GENL_struct(DRBD_NLA_NET_CONF, 5, net_conf, + __str_field_def(1, DRBD_GENLA_F_MANDATORY | DRBD_F_SENSITIVE, + shared_secret, SHARED_SECRET_MAX) + __str_field_def(2, DRBD_GENLA_F_MANDATORY, cram_hmac_alg, SHARED_SECRET_MAX) + __str_field_def(3, DRBD_GENLA_F_MANDATORY, integrity_alg, SHARED_SECRET_MAX) + __str_field_def(4, DRBD_GENLA_F_MANDATORY, verify_alg, SHARED_SECRET_MAX) + __str_field_def(5, DRBD_GENLA_F_MANDATORY, csums_alg, SHARED_SECRET_MAX) + __u32_field_def(6, DRBD_GENLA_F_MANDATORY, wire_protocol, DRBD_PROTOCOL_DEF) + __u32_field_def(7, DRBD_GENLA_F_MANDATORY, connect_int, DRBD_CONNECT_INT_DEF) + __u32_field_def(8, DRBD_GENLA_F_MANDATORY, timeout, DRBD_TIMEOUT_DEF) + __u32_field_def(9, DRBD_GENLA_F_MANDATORY, ping_int, DRBD_PING_INT_DEF) + __u32_field_def(10, DRBD_GENLA_F_MANDATORY, ping_timeo, DRBD_PING_TIMEO_DEF) + __u32_field_def(11, DRBD_GENLA_F_MANDATORY, sndbuf_size, DRBD_SNDBUF_SIZE_DEF) + __u32_field_def(12, DRBD_GENLA_F_MANDATORY, rcvbuf_size, DRBD_RCVBUF_SIZE_DEF) + __u32_field_def(13, DRBD_GENLA_F_MANDATORY, ko_count, DRBD_KO_COUNT_DEF) + __u32_field_def(15, DRBD_GENLA_F_MANDATORY, max_epoch_size, DRBD_MAX_EPOCH_SIZE_DEF) + __u32_field_def(17, DRBD_GENLA_F_MANDATORY, after_sb_0p, DRBD_AFTER_SB_0P_DEF) + __u32_field_def(18, DRBD_GENLA_F_MANDATORY, after_sb_1p, DRBD_AFTER_SB_1P_DEF) + __u32_field_def(19, DRBD_GENLA_F_MANDATORY, after_sb_2p, DRBD_AFTER_SB_2P_DEF) + __u32_field_def(20, DRBD_GENLA_F_MANDATORY, rr_conflict, DRBD_RR_CONFLICT_DEF) + __u32_field_def(21, DRBD_GENLA_F_MANDATORY, on_congestion, DRBD_ON_CONGESTION_DEF) + __u32_field_def(22, DRBD_GENLA_F_MANDATORY, cong_fill, DRBD_CONG_FILL_DEF) + __u32_field_def(23, DRBD_GENLA_F_MANDATORY, cong_extents, DRBD_CONG_EXTENTS_DEF) + __flg_field_def(24, DRBD_GENLA_F_MANDATORY, two_primaries, DRBD_ALLOW_TWO_PRIMARIES_DEF) + __flg_field_def(26, DRBD_GENLA_F_MANDATORY, tcp_cork, DRBD_TCP_CORK_DEF) + __flg_field_def(27, DRBD_GENLA_F_MANDATORY, always_asbp, DRBD_ALWAYS_ASBP_DEF) + __flg_field_def(29, DRBD_GENLA_F_MANDATORY, use_rle, DRBD_USE_RLE_DEF) + __u32_field_def(30, DRBD_GENLA_F_MANDATORY, fencing_policy, DRBD_FENCING_DEF) + __str_field_def(31, DRBD_GENLA_F_MANDATORY, name, SHARED_SECRET_MAX) + /* moved into ctx_peer_node_id: __u32_field(32, DRBD_F_REQUIRED | DRBD_F_INVARIANT, peer_node_id) */ + __flg_field_def(33, 0 /* OPTIONAL */, csums_after_crash_only, DRBD_CSUMS_AFTER_CRASH_ONLY_DEF) + __u32_field_def(34, 0 /* OPTIONAL */, sock_check_timeo, DRBD_SOCKET_CHECK_TIMEO_DEF) + __str_field_def(35, DRBD_F_INVARIANT, transport_name, SHARED_SECRET_MAX) + __u32_field_def(36, 0 /* OPTIONAL */, max_buffers, DRBD_MAX_BUFFERS_DEF) +) + +GENL_struct(DRBD_NLA_SET_ROLE_PARMS, 6, set_role_parms, + __flg_field(1, DRBD_GENLA_F_MANDATORY, assume_uptodate) +) + +GENL_struct(DRBD_NLA_RESIZE_PARMS, 7, resize_parms, + __u64_field(1, DRBD_GENLA_F_MANDATORY, resize_size) + __flg_field(2, DRBD_GENLA_F_MANDATORY, resize_force) + __flg_field(3, DRBD_GENLA_F_MANDATORY, no_resync) + __u32_field_def(4, 0 /* OPTIONAL */, al_stripes, DRBD_AL_STRIPES_DEF) + __u32_field_def(5, 0 /* OPTIONAL */, al_stripe_size, DRBD_AL_STRIPE_SIZE_DEF) +) + +GENL_struct(DRBD_NLA_START_OV_PARMS, 9, start_ov_parms, + __u64_field(1, DRBD_GENLA_F_MANDATORY, ov_start_sector) + __u64_field(2, DRBD_GENLA_F_MANDATORY, ov_stop_sector) +) + +GENL_struct(DRBD_NLA_NEW_C_UUID_PARMS, 10, new_c_uuid_parms, + __flg_field(1, DRBD_GENLA_F_MANDATORY, clear_bm) +) + +GENL_struct(DRBD_NLA_TIMEOUT_PARMS, 11, timeout_parms, + __u32_field(1, DRBD_F_REQUIRED, timeout_type) +) + +GENL_struct(DRBD_NLA_DISCONNECT_PARMS, 12, disconnect_parms, + __flg_field(1, DRBD_GENLA_F_MANDATORY, force_disconnect) +) + +GENL_struct(DRBD_NLA_DETACH_PARMS, 13, detach_parms, + __flg_field(1, DRBD_GENLA_F_MANDATORY, force_detach) +) + +GENL_struct(DRBD_NLA_DEVICE_CONF, 14, device_conf, + __u32_field_def(1, DRBD_F_INVARIANT, max_bio_size, DRBD_MAX_BIO_SIZE_DEF) +) + +GENL_struct(DRBD_NLA_RESOURCE_INFO, 15, resource_info, + __u32_field(1, 0, res_role) + __flg_field(2, 0, res_susp) + __flg_field(3, 0, res_susp_nod) + __flg_field(4, 0, res_susp_fen) +) + +GENL_struct(DRBD_NLA_DEVICE_INFO, 16, device_info, + __u32_field(1, 0, dev_disk_state) +) + +GENL_struct(DRBD_NLA_CONNECTION_INFO, 17, connection_info, + __u32_field(1, 0, conn_connection_state) + __u32_field(2, 0, conn_role) +) + +GENL_struct(DRBD_NLA_PEER_DEVICE_INFO, 18, peer_device_info, + __u32_field(1, 0, peer_repl_state) + __u32_field(2, 0, peer_disk_state) + __u32_field(3, 0, peer_resync_susp_user) + __u32_field(4, 0, peer_resync_susp_peer) + __u32_field(5, 0, peer_resync_susp_dependency) +) + +GENL_struct(DRBD_NLA_RESOURCE_STATISTICS, 19, resource_statistics, + __u32_field(1, 0, res_stat_write_ordering) +) + +GENL_struct(DRBD_NLA_DEVICE_STATISTICS, 20, device_statistics, + __u64_field(1, 0, dev_size) /* (sectors) */ + __u64_field(2, 0, dev_read) /* (sectors) */ + __u64_field(3, 0, dev_write) /* (sectors) */ + __u64_field(4, 0, dev_al_writes) /* activity log writes (count) */ + __u64_field(5, 0, dev_bm_writes) /* bitmap writes (count) */ + __u32_field(6, 0, dev_upper_pending) /* application requests in progress */ + __u32_field(7, 0, dev_lower_pending) /* backing device requests in progress */ + __flg_field(8, 0, dev_upper_blocked) + __flg_field(9, 0, dev_lower_blocked) + __flg_field(10, 0, dev_al_suspended) /* activity log suspended */ + __u64_field(11, 0, dev_exposed_data_uuid) + __u64_field(12, 0, dev_current_uuid) + __u32_field(13, 0, dev_disk_flags) + __bin_field(14, 0, history_uuids, HISTORY_UUIDS * sizeof(__u64)) +) + +GENL_struct(DRBD_NLA_CONNECTION_STATISTICS, 21, connection_statistics, + __flg_field(1, 0, conn_congested) +) + +GENL_struct(DRBD_NLA_PEER_DEVICE_STATISTICS, 22, peer_device_statistics, + __u64_field(1, 0, peer_dev_received) /* sectors */ + __u64_field(2, 0, peer_dev_sent) /* sectors */ + __u32_field(3, 0, peer_dev_pending) /* number of requests */ + __u32_field(4, 0, peer_dev_unacked) /* number of requests */ + __u64_field(5, 0, peer_dev_out_of_sync) /* sectors */ + __u64_field(6, 0, peer_dev_resync_failed) /* sectors */ + __u64_field(7, 0, peer_dev_bitmap_uuid) + __u32_field(9, 0, peer_dev_flags) +) + +GENL_struct(DRBD_NLA_NOTIFICATION_HEADER, 23, drbd_notification_header, + __u32_field(1, DRBD_GENLA_F_MANDATORY, nh_type) +) + +GENL_struct(DRBD_NLA_HELPER, 24, drbd_helper_info, + __str_field(1, DRBD_GENLA_F_MANDATORY, helper_name, 32) + __u32_field(2, DRBD_GENLA_F_MANDATORY, helper_status) +) + +GENL_struct(DRBD_NLA_INVALIDATE_PARMS, 25, invalidate_parms, + __s32_field_def(1, DRBD_GENLA_F_MANDATORY, sync_from_peer_node_id, DRBD_SYNC_FROM_NID_DEF) +) + +GENL_struct(DRBD_NLA_FORGET_PEER_PARMS, 26, forget_peer_parms, + __s32_field_def(1, DRBD_GENLA_F_MANDATORY, forget_peer_node_id, DRBD_SYNC_FROM_NID_DEF) +) + +GENL_struct(DRBD_NLA_PEER_DEVICE_OPTS, 27, peer_device_conf, + __u32_field_def(1, DRBD_GENLA_F_MANDATORY, resync_rate, DRBD_RESYNC_RATE_DEF) + __u32_field_def(2, DRBD_GENLA_F_MANDATORY, c_plan_ahead, DRBD_C_PLAN_AHEAD_DEF) + __u32_field_def(3, DRBD_GENLA_F_MANDATORY, c_delay_target, DRBD_C_DELAY_TARGET_DEF) + __u32_field_def(4, DRBD_GENLA_F_MANDATORY, c_fill_target, DRBD_C_FILL_TARGET_DEF) + __u32_field_def(5, DRBD_GENLA_F_MANDATORY, c_max_rate, DRBD_C_MAX_RATE_DEF) + __u32_field_def(6, DRBD_GENLA_F_MANDATORY, c_min_rate, DRBD_C_MIN_RATE_DEF) +) + +GENL_struct(DRBD_NLA_PATH_PARMS, 28, path_parms, + __bin_field(1, DRBD_GENLA_F_MANDATORY, my_addr, 128) + __bin_field(2, DRBD_GENLA_F_MANDATORY, peer_addr, 128) +) + +GENL_struct(DRBD_NLA_CONNECT_PARMS, 29, connect_parms, + __flg_field_def(1, DRBD_GENLA_F_MANDATORY, tentative, 0) + __flg_field_def(2, DRBD_GENLA_F_MANDATORY, discard_my_data, 0) +) + +GENL_struct(DRBD_NLA_PATH_INFO, 30, drbd_path_info, + __flg_field(1, 0, path_established) +) + +/* + * Notifications and commands (genlmsghdr->cmd) + */ +GENL_mc_group(events) + + /* add DRBD minor devices as volumes to resources */ +GENL_op(DRBD_ADM_NEW_MINOR, 5, GENL_doit(drbd_adm_new_minor), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_DEVICE_CONF, DRBD_GENLA_F_MANDATORY)) +GENL_op(DRBD_ADM_DEL_MINOR, 6, GENL_doit(drbd_adm_del_minor), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)) + + /* add or delete resources */ +GENL_op(DRBD_ADM_NEW_RESOURCE, 7, GENL_doit(drbd_adm_new_resource), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)) +GENL_op(DRBD_ADM_DEL_RESOURCE, 8, GENL_doit(drbd_adm_del_resource), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)) + +GENL_op(DRBD_ADM_RESOURCE_OPTS, 9, + GENL_doit(drbd_adm_resource_opts), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_RESOURCE_OPTS, DRBD_GENLA_F_MANDATORY) +) + +GENL_op(DRBD_ADM_NEW_PEER, 44, GENL_doit(drbd_adm_new_peer), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_NET_CONF, DRBD_GENLA_F_MANDATORY) +) + +GENL_op(DRBD_ADM_NEW_PATH, 45, GENL_doit(drbd_adm_new_path), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_PATH_PARMS, DRBD_F_REQUIRED) +) + +GENL_op(DRBD_ADM_DEL_PEER, 46, GENL_doit(drbd_adm_del_peer), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_DISCONNECT_PARMS, DRBD_GENLA_F_MANDATORY) +) + +GENL_op(DRBD_ADM_DEL_PATH, 47, GENL_doit(drbd_adm_del_path), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_PATH_PARMS, DRBD_F_REQUIRED) +) + +GENL_op(DRBD_ADM_CONNECT, 10, GENL_doit(drbd_adm_connect), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_CONNECT_PARMS, DRBD_GENLA_F_MANDATORY) +) + +GENL_op( + DRBD_ADM_CHG_NET_OPTS, 29, + GENL_doit(drbd_adm_net_opts), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_NET_CONF, DRBD_F_REQUIRED) +) + +GENL_op(DRBD_ADM_DISCONNECT, 11, GENL_doit(drbd_adm_disconnect), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_DISCONNECT_PARMS, DRBD_GENLA_F_MANDATORY) +) + +GENL_op(DRBD_ADM_ATTACH, 12, + GENL_doit(drbd_adm_attach), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_DISK_CONF, DRBD_F_REQUIRED) +) + +GENL_op(DRBD_ADM_CHG_DISK_OPTS, 28, + GENL_doit(drbd_adm_disk_opts), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_DISK_OPTS, DRBD_F_REQUIRED) +) + +GENL_op( + DRBD_ADM_RESIZE, 13, + GENL_doit(drbd_adm_resize), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_RESIZE_PARMS, DRBD_GENLA_F_MANDATORY) +) + +GENL_op( + DRBD_ADM_PRIMARY, 14, + GENL_doit(drbd_adm_set_role), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_SET_ROLE_PARMS, DRBD_F_REQUIRED) +) + +GENL_op( + DRBD_ADM_SECONDARY, 15, + GENL_doit(drbd_adm_set_role), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_SET_ROLE_PARMS, DRBD_F_REQUIRED) +) + +GENL_op( + DRBD_ADM_NEW_C_UUID, 16, + GENL_doit(drbd_adm_new_c_uuid), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_NEW_C_UUID_PARMS, DRBD_GENLA_F_MANDATORY) +) + +GENL_op( + DRBD_ADM_START_OV, 17, + GENL_doit(drbd_adm_start_ov), + GENL_tla_expected(DRBD_NLA_START_OV_PARMS, DRBD_GENLA_F_MANDATORY) +) + +GENL_op(DRBD_ADM_DETACH, 18, GENL_doit(drbd_adm_detach), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_DETACH_PARMS, DRBD_GENLA_F_MANDATORY)) + +GENL_op(DRBD_ADM_INVALIDATE, 19, GENL_doit(drbd_adm_invalidate), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_INVALIDATE_PARMS, DRBD_F_REQUIRED)) + +GENL_op(DRBD_ADM_INVAL_PEER, 20, GENL_doit(drbd_adm_invalidate_peer), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)) +GENL_op(DRBD_ADM_PAUSE_SYNC, 21, GENL_doit(drbd_adm_pause_sync), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)) +GENL_op(DRBD_ADM_RESUME_SYNC, 22, GENL_doit(drbd_adm_resume_sync), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)) +GENL_op(DRBD_ADM_SUSPEND_IO, 23, GENL_doit(drbd_adm_suspend_io), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)) +GENL_op(DRBD_ADM_RESUME_IO, 24, GENL_doit(drbd_adm_resume_io), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)) +GENL_op(DRBD_ADM_OUTDATE, 25, GENL_doit(drbd_adm_outdate), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)) +GENL_op(DRBD_ADM_GET_TIMEOUT_TYPE, 26, GENL_doit(drbd_adm_get_timeout_type), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)) +GENL_op(DRBD_ADM_DOWN, 27, GENL_doit(drbd_adm_down), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED)) + +GENL_op(DRBD_ADM_GET_RESOURCES, 30, + GENL_op_init( + .dumpit = drbd_adm_dump_resources, + ), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_GENLA_F_MANDATORY) + GENL_tla_expected(DRBD_NLA_RESOURCE_INFO, DRBD_GENLA_F_MANDATORY) + GENL_tla_expected(DRBD_NLA_RESOURCE_STATISTICS, DRBD_GENLA_F_MANDATORY)) + +GENL_op(DRBD_ADM_GET_DEVICES, 31, + GENL_op_init( + .dumpit = drbd_adm_dump_devices, + .done = drbd_adm_dump_devices_done, + ), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_GENLA_F_MANDATORY) + GENL_tla_expected(DRBD_NLA_DEVICE_INFO, DRBD_GENLA_F_MANDATORY) + GENL_tla_expected(DRBD_NLA_DEVICE_STATISTICS, DRBD_GENLA_F_MANDATORY)) + +GENL_op(DRBD_ADM_GET_CONNECTIONS, 32, + GENL_op_init( + .dumpit = drbd_adm_dump_connections, + .done = drbd_adm_dump_connections_done, + ), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_GENLA_F_MANDATORY) + GENL_tla_expected(DRBD_NLA_CONNECTION_INFO, DRBD_GENLA_F_MANDATORY) + GENL_tla_expected(DRBD_NLA_CONNECTION_STATISTICS, DRBD_GENLA_F_MANDATORY)) + +GENL_op(DRBD_ADM_GET_PEER_DEVICES, 33, + GENL_op_init( + .dumpit = drbd_adm_dump_peer_devices, + .done = drbd_adm_dump_peer_devices_done, + ), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_GENLA_F_MANDATORY) + GENL_tla_expected(DRBD_NLA_PEER_DEVICE_INFO, DRBD_GENLA_F_MANDATORY) + GENL_tla_expected(DRBD_NLA_PEER_DEVICE_STATISTICS, DRBD_GENLA_F_MANDATORY)) + +GENL_notification( + DRBD_RESOURCE_STATE, 34, events, + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_NOTIFICATION_HEADER, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_RESOURCE_INFO, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_RESOURCE_STATISTICS, DRBD_F_REQUIRED)) + +GENL_notification( + DRBD_DEVICE_STATE, 35, events, + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_NOTIFICATION_HEADER, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_DEVICE_INFO, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_DEVICE_STATISTICS, DRBD_F_REQUIRED)) + +GENL_notification( + DRBD_CONNECTION_STATE, 36, events, + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_NOTIFICATION_HEADER, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_PATH_PARMS, DRBD_GENLA_F_MANDATORY) + GENL_tla_expected(DRBD_NLA_CONNECTION_INFO, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_CONNECTION_STATISTICS, DRBD_F_REQUIRED)) + +GENL_notification( + DRBD_PEER_DEVICE_STATE, 37, events, + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_NOTIFICATION_HEADER, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_PEER_DEVICE_INFO, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_PEER_DEVICE_STATISTICS, DRBD_F_REQUIRED)) + +GENL_op( + DRBD_ADM_GET_INITIAL_STATE, 38, + GENL_op_init( + .dumpit = drbd_adm_get_initial_state, + ), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_GENLA_F_MANDATORY)) + +GENL_notification( + DRBD_HELPER, 40, events, + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_HELPER, DRBD_F_REQUIRED)) + +GENL_notification( + DRBD_INITIAL_STATE_DONE, 41, events, + GENL_tla_expected(DRBD_NLA_NOTIFICATION_HEADER, DRBD_F_REQUIRED)) + +GENL_op(DRBD_ADM_FORGET_PEER, 42, GENL_doit(drbd_adm_forget_peer), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_FORGET_PEER_PARMS, DRBD_F_REQUIRED)) + +GENL_op(DRBD_ADM_CHG_PEER_DEVICE_OPTS, 43, + GENL_doit(drbd_adm_peer_device_opts), + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_PEER_DEVICE_OPTS, DRBD_F_REQUIRED)) + +GENL_notification( + DRBD_PATH_STATE, 48, events, + GENL_tla_expected(DRBD_NLA_CFG_CONTEXT, DRBD_F_REQUIRED) + GENL_tla_expected(DRBD_NLA_PATH_INFO, DRBD_F_REQUIRED)) +drbd-headers/drbd_protocol.h0000644000077500007750000003346613070663767015470 0ustar shrekshrek#ifndef __DRBD_PROTOCOL_H +#define __DRBD_PROTOCOL_H + +#ifdef __KERNEL__ +#include +#else +#include +#endif + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif + +enum drbd_packet { + /* receiver (data socket) */ + P_DATA = 0x00, + P_DATA_REPLY = 0x01, /* Response to P_DATA_REQUEST */ + P_RS_DATA_REPLY = 0x02, /* Response to P_RS_DATA_REQUEST */ + P_BARRIER = 0x03, + P_BITMAP = 0x04, + P_BECOME_SYNC_TARGET = 0x05, + P_BECOME_SYNC_SOURCE = 0x06, + P_UNPLUG_REMOTE = 0x07, /* Used at various times to hint the peer */ + P_DATA_REQUEST = 0x08, /* Used to ask for a data block */ + P_RS_DATA_REQUEST = 0x09, /* Used to ask for a data block for resync */ + P_SYNC_PARAM = 0x0a, + P_PROTOCOL = 0x0b, + P_UUIDS = 0x0c, + P_SIZES = 0x0d, + P_STATE = 0x0e, + P_SYNC_UUID = 0x0f, + P_AUTH_CHALLENGE = 0x10, + P_AUTH_RESPONSE = 0x11, + P_STATE_CHG_REQ = 0x12, + + /* asender (meta socket */ + P_PING = 0x13, + P_PING_ACK = 0x14, + P_RECV_ACK = 0x15, /* Used in protocol B */ + P_WRITE_ACK = 0x16, /* Used in protocol C */ + P_RS_WRITE_ACK = 0x17, /* Is a P_WRITE_ACK, additionally call set_in_sync(). */ + P_SUPERSEDED = 0x18, /* Used in proto C, two-primaries conflict detection */ + P_NEG_ACK = 0x19, /* Sent if local disk is unusable */ + P_NEG_DREPLY = 0x1a, /* Local disk is broken... */ + P_NEG_RS_DREPLY = 0x1b, /* Local disk is broken... */ + P_BARRIER_ACK = 0x1c, + P_STATE_CHG_REPLY = 0x1d, + + /* "new" commands, no longer fitting into the ordering scheme above */ + + P_OV_REQUEST = 0x1e, /* data socket */ + P_OV_REPLY = 0x1f, + P_OV_RESULT = 0x20, /* meta socket */ + P_CSUM_RS_REQUEST = 0x21, /* data socket */ + P_RS_IS_IN_SYNC = 0x22, /* meta socket */ + P_SYNC_PARAM89 = 0x23, /* data socket, protocol version 89 replacement for P_SYNC_PARAM */ + P_COMPRESSED_BITMAP = 0x24, /* compressed or otherwise encoded bitmap transfer */ + /* P_CKPT_FENCE_REQ = 0x25, * currently reserved for protocol D */ + /* P_CKPT_DISABLE_REQ = 0x26, * currently reserved for protocol D */ + P_DELAY_PROBE = 0x27, /* is used on BOTH sockets */ + P_OUT_OF_SYNC = 0x28, /* Mark as out of sync (Outrunning), data socket */ + P_RS_CANCEL = 0x29, /* meta: Used to cancel RS_DATA_REQUEST packet by SyncSource */ + P_CONN_ST_CHG_REQ = 0x2a, /* data sock: state change request */ + P_CONN_ST_CHG_REPLY = 0x2b, /* meta sock: state change reply */ + P_RETRY_WRITE = 0x2c, /* Protocol C: retry conflicting write request */ + P_PROTOCOL_UPDATE = 0x2d, /* data sock: is used in established connections */ + P_TWOPC_PREPARE = 0x2e, /* data sock: prepare state change */ + P_TWOPC_ABORT = 0x2f, /* data sock: abort state change */ + + P_DAGTAG = 0x30, /* data sock: set the current dagtag */ + + /* REQ_DISCARD. We used "discard" in different contexts before, + * which is why I chose TRIM here, to disambiguate. */ + P_TRIM = 0x31, + + /* Only use these two if both support FF_THIN_RESYNC */ + P_RS_THIN_REQ = 0x32, /* Request a block for resync or reply P_RS_DEALLOCATED */ + P_RS_DEALLOCATED = 0x33, /* Contains only zeros on sync source node */ + + /* REQ_WRITE_SAME. + * On a receiving side without REQ_WRITE_SAME, + * we may fall back to an opencoded loop instead. */ + P_WSAME = 0x34, + + P_PEER_ACK = 0x40, /* meta sock: tell which nodes have acked a request */ + P_PEERS_IN_SYNC = 0x41, /* data sock: Mark area as in sync */ + + P_UUIDS110 = 0x42, /* data socket */ + P_PEER_DAGTAG = 0x43, /* data socket, used to trigger reconciliation resync */ + P_CURRENT_UUID = 0x44, /* data socket */ + + P_TWOPC_YES = 0x45, /* meta sock: allow two-phase commit */ + P_TWOPC_NO = 0x46, /* meta sock: reject two-phase commit */ + P_TWOPC_COMMIT = 0x47, /* data sock: commit state change */ + P_TWOPC_RETRY = 0x48, /* meta sock: retry two-phase commit */ + + P_MAY_IGNORE = 0x100, /* Flag to test if (cmd > P_MAY_IGNORE) ... */ + + /* special command ids for handshake */ + + P_INITIAL_META = 0xfff1, /* First Packet on the MetaSock */ + P_INITIAL_DATA = 0xfff2, /* First Packet on the Socket */ + + P_CONNECTION_FEATURES = 0xfffe /* FIXED for the next century! */ +}; + +#ifndef __packed +#define __packed __attribute__((packed)) +#endif + +/* This is the layout for a packet on the wire. + * The byteorder is the network byte order. + * (except block_id and barrier fields. + * these are pointers to local structs + * and have no relevance for the partner, + * which just echoes them as received.) + * + * NOTE that the payload starts at a long aligned offset, + * regardless of 32 or 64 bit arch! + */ +struct p_header80 { + uint32_t magic; + uint16_t command; + uint16_t length; /* bytes of data after this header */ +} __packed; + +/* Header for big packets, Used for data packets exceeding 64kB */ +struct p_header95 { + uint16_t magic; /* use DRBD_MAGIC_BIG here */ + uint16_t command; + uint32_t length; +} __packed; + +struct p_header100 { + uint32_t magic; + uint16_t volume; + uint16_t command; + uint32_t length; + uint32_t pad; +} __packed; + +/* These defines must not be changed without changing the protocol version. + * New defines may only be introduced together with protocol version bump or + * new protocol feature flags. + */ +#define DP_HARDBARRIER 1 /* no longer used */ +#define DP_RW_SYNC 2 /* equals REQ_SYNC */ +#define DP_MAY_SET_IN_SYNC 4 +#define DP_UNPLUG 8 /* equals REQ_UNPLUG (compat) */ +#define DP_FUA 16 /* equals REQ_FUA */ +#define DP_FLUSH 32 /* equals REQ_FLUSH */ +#define DP_DISCARD 64 /* equals REQ_DISCARD */ +#define DP_SEND_RECEIVE_ACK 128 /* This is a proto B write request */ +#define DP_SEND_WRITE_ACK 256 /* This is a proto C write request */ +#define DP_WSAME 512 /* equiv. REQ_WRITE_SAME */ + +struct p_data { + uint64_t sector; /* 64 bits sector number */ + uint64_t block_id; /* to identify the request in protocol B&C */ + uint32_t seq_num; + uint32_t dp_flags; +} __packed; + +struct p_trim { + struct p_data p_data; + uint32_t size; /* == bio->bi_size */ +} __packed; + +struct p_wsame { + struct p_data p_data; + uint32_t size; /* == bio->bi_size */ +} __packed; + +/* + * commands which share a struct: + * p_block_ack: + * P_RECV_ACK (proto B), P_WRITE_ACK (proto C), + * P_SUPERSEDED (proto C, two-primaries conflict detection) + * p_block_req: + * P_DATA_REQUEST, P_RS_DATA_REQUEST + */ +struct p_block_ack { + uint64_t sector; + uint64_t block_id; + uint32_t blksize; + uint32_t seq_num; +} __packed; + +struct p_block_req { + uint64_t sector; + uint64_t block_id; + uint32_t blksize; + uint32_t pad; /* to multiple of 8 Byte */ +} __packed; + +/* + * commands with their own struct for additional fields: + * P_CONNECTION_FEATURES + * P_BARRIER + * P_BARRIER_ACK + * P_SYNC_PARAM + * ReportParams + */ + +/* supports TRIM/DISCARD on the "wire" protocol */ +#define DRBD_FF_TRIM 1 + +/* Detect all-zeros during resync, and rather TRIM/UNMAP/DISCARD those blocks + * instead of fully allocate a supposedly thin volume on initial resync */ +#define DRBD_FF_THIN_RESYNC 2 + +/* supports REQ_WRITE_SAME on the "wire" protocol. + * Note: this flag is overloaded, + * its presence also + * - indicates support for 128 MiB "batch bios", + * max discard size of 128 MiB + * instead of 4M before that. + * - indicates that we exchange additional settings in p_sizes + * drbd_send_sizes()/receive_sizes() + */ +#define DRBD_FF_WSAME 4 + +struct p_connection_features { + uint32_t protocol_min; + uint32_t feature_flags; + uint32_t protocol_max; + uint32_t sender_node_id; + uint32_t receiver_node_id; + + /* should be more than enough for future enhancements + * for now, feature_flags and the reserved array shall be zero. + */ + + uint32_t _pad; + uint64_t reserved[6]; +} __packed; + +struct p_barrier { + uint32_t barrier; /* barrier number _handle_ only */ + uint32_t pad; /* to multiple of 8 Byte */ +} __packed; + +struct p_barrier_ack { + uint32_t barrier; + uint32_t set_size; +} __packed; + +struct p_rs_param { + uint32_t resync_rate; + + /* Since protocol version 88 and higher. */ + char verify_alg[0]; +} __packed; + +struct p_rs_param_89 { + uint32_t resync_rate; + /* protocol version 89: */ + char verify_alg[SHARED_SECRET_MAX]; + char csums_alg[SHARED_SECRET_MAX]; +} __packed; + +struct p_rs_param_95 { + uint32_t resync_rate; + char verify_alg[SHARED_SECRET_MAX]; + char csums_alg[SHARED_SECRET_MAX]; + uint32_t c_plan_ahead; + uint32_t c_delay_target; + uint32_t c_fill_target; + uint32_t c_max_rate; +} __packed; + +enum drbd_conn_flags { + CF_DISCARD_MY_DATA = 1, + CF_DRY_RUN = 2, +}; + +struct p_protocol { + uint32_t protocol; + uint32_t after_sb_0p; + uint32_t after_sb_1p; + uint32_t after_sb_2p; + uint32_t conn_flags; + uint32_t two_primaries; + + /* Since protocol version 87 and higher. */ + char integrity_alg[0]; + +} __packed; + +#define UUID_FLAG_DISCARD_MY_DATA 1 +#define UUID_FLAG_CRASHED_PRIMARY 2 +#define UUID_FLAG_INCONSISTENT 4 +#define UUID_FLAG_SKIP_INITIAL_SYNC 8 +#define UUID_FLAG_NEW_DATAGEN 16 +#define UUID_FLAG_STABLE 32 +#define UUID_FLAG_GOT_STABLE 64 /* send UUIDs */ +#define UUID_FLAG_RESYNC 128 /* compare UUIDs and eventually start resync */ +#define UUID_FLAG_RECONNECT 256 +#define UUID_FLAG_DISKLESS_PRIMARY 512 /* Use with UUID_FLAG_RESYNC if a diskless primary is + the reason */ + +struct p_uuids { + uint64_t current_uuid; + uint64_t bitmap_uuid; + uint64_t history_uuids[HISTORY_UUIDS_V08]; + uint64_t dirty_bits; + uint64_t uuid_flags; +} __packed; + +struct p_uuids110 { + uint64_t current_uuid; + uint64_t dirty_bits; + uint64_t uuid_flags; + uint64_t node_mask; /* weak_nodes when UUID_FLAG_NEW_DATAGEN is set ; + authoritative nodes when UUID_FLAG_STABLE not set */ + + uint64_t bitmap_uuids_mask; /* non zero bitmap UUIDS for these nodes */ + uint64_t other_uuids[0]; /* the first hweight(bitmap_uuids_mask) slots carry bitmap uuids. + The node with the lowest node_id first. + The remaining slots carry history uuids */ +} __packed; + +struct p_current_uuid { + uint64_t uuid; + uint64_t weak_nodes; +} __packed; + +struct p_uuid { + uint64_t uuid; +} __packed; + +/* optional queue_limits if (agreed_features & DRBD_FF_WSAME) + * see also struct queue_limits, as of late 2015 */ +struct o_qlim { + /* we don't need it yet, but we may as well communicate it now */ + uint32_t physical_block_size; + + /* so the original in struct queue_limits is unsigned short, + * but I'd have to put in padding anyways. */ + uint32_t logical_block_size; + + /* One incoming bio becomes one DRBD request, + * which may be translated to several bio on the receiving side. + * We don't need to communicate chunk/boundary/segment ... limits. + */ + + /* various IO hints may be useful with "diskless client" setups */ + uint32_t alignment_offset; + uint32_t io_min; + uint32_t io_opt; + + /* We may need to communicate integrity stuff at some point, + * but let's not get ahead of ourselves. */ + + /* Backend discard capabilities. + * Receiving side uses "blkdev_issue_discard()", no need to communicate + * more specifics. If the backend cannot do discards, the DRBD peer + * may fall back to blkdev_issue_zeroout(). + */ + uint8_t discard_enabled; + uint8_t discard_zeroes_data; + uint8_t write_same_capable; + uint8_t _pad; +} __packed; + +struct p_sizes { + uint64_t d_size; /* size of disk */ + uint64_t u_size; /* user requested size */ + uint64_t c_size; /* current exported size */ + uint32_t max_bio_size; /* Maximal size of a BIO */ + uint16_t queue_order_type; /* not yet implemented in DRBD*/ + uint16_t dds_flags; /* use enum dds_flags here. */ + + /* optional queue_limits if (agreed_features & DRBD_FF_WSAME) */ + struct o_qlim qlim[0]; +} __packed; + +struct p_state { + uint32_t state; +} __packed; + +struct p_req_state { + uint32_t mask; + uint32_t val; +} __packed; + +struct p_req_state_reply { + uint32_t retcode; +} __packed; + +struct p_twopc_request { + uint32_t tid; /* transaction identifier */ + uint32_t initiator_node_id; /* initiator of the transaction */ + uint32_t target_node_id; /* target of the transaction (or -1) */ + uint64_t nodes_to_reach; + uint64_t primary_nodes; + uint32_t mask; + uint32_t val; +} __packed; + +struct p_twopc_reply { + uint32_t tid; /* transaction identifier */ + uint32_t initiator_node_id; /* initiator of the transaction */ + uint64_t reachable_nodes; + uint64_t primary_nodes; + uint64_t weak_nodes; +} __packed; + +struct p_drbd06_param { + uint64_t size; + uint32_t state; + uint32_t blksize; + uint32_t protocol; + uint32_t version; + uint32_t gen_cnt[5]; + uint32_t bit_map_gen[5]; +} __packed; + +struct p_block_desc { + uint64_t sector; + uint32_t blksize; + uint32_t pad; /* to multiple of 8 Byte */ +} __packed; + +/* Valid values for the encoding field. + * Bump proto version when changing this. */ +enum drbd_bitmap_code { + /* RLE_VLI_Bytes = 0, + * and other bit variants had been defined during + * algorithm evaluation. */ + RLE_VLI_Bits = 2, +}; + +struct p_compressed_bm { + /* (encoding & 0x0f): actual encoding, see enum drbd_bitmap_code + * (encoding & 0x80): polarity (set/unset) of first runlength + * ((encoding >> 4) & 0x07): pad_bits, number of trailing zero bits + * used to pad up to head.length bytes + */ + uint8_t encoding; + + uint8_t code[0]; +} __packed; + +struct p_delay_probe93 { + uint32_t seq_num; /* sequence number to match the two probe packets */ + uint32_t offset; /* usecs the probe got sent after the reference time point */ +} __packed; + +struct p_dagtag { + uint64_t dagtag; +} __packed; + +struct p_peer_ack { + uint64_t mask; + uint64_t dagtag; +} __packed; + +struct p_peer_block_desc { + uint64_t sector; + uint64_t mask; + uint32_t size; + uint32_t pad; /* to multiple of 8 Byte */ +} __packed; + +struct p_peer_dagtag { + uint64_t dagtag; + uint32_t node_id; +} __packed; + +/* + * Bitmap packets need to fit within a single page on the sender and receiver, + * so we are limited to 4 KiB (and not to PAGE_SIZE, which can be bigger). + */ +#define DRBD_SOCKET_BUFFER_SIZE 4096 + +#endif /* __DRBD_PROTOCOL_H */ +drbd-headers/drbd_transport.h0000644000077500007750000002766113070663767015663 0ustar shrekshrek#ifndef DRBD_TRANSPORT_H +#define DRBD_TRANSPORT_H + +#include +#include +#include +#include + +/* Whenever touch this file in a non-trivial way, increase the + DRBD_TRANSPORT_API_VERSION + So that transport compiled against an older version of this + header will no longer load in a module that assumes a newer + version. */ +#define DRBD_TRANSPORT_API_VERSION 14 + +/* MSG_MSG_DONTROUTE and MSG_PROBE are not used by DRBD. I.e. + we can reuse these flags for our purposes */ +#define CALLER_BUFFER MSG_DONTROUTE +#define GROW_BUFFER MSG_PROBE + +/* + * gfp_mask for allocating memory with no write-out. + * + * When drbd allocates memory on behalf of the peer, we prevent it from causing + * write-out because in a criss-cross setup, the write-out could lead to memory + * pressure on the peer, eventually leading to deadlock. + */ +#define GFP_TRY (__GFP_HIGHMEM | __GFP_NOWARN | __GFP_RECLAIM) + +#define tr_printk(level, transport, fmt, args...) ({ \ + rcu_read_lock(); \ + printk(level "drbd %s %s:%s: " fmt, \ + (transport)->log_prefix, \ + (transport)->class->name, \ + rcu_dereference((transport)->net_conf)->name, \ + ## args); \ + rcu_read_unlock(); \ + }) + +#define tr_err(transport, fmt, args...) \ + tr_printk(KERN_ERR, transport, fmt, ## args) +#define tr_warn(transport, fmt, args...) \ + tr_printk(KERN_WARNING, transport, fmt, ## args) +#define tr_info(transport, fmt, args...) \ + tr_printk(KERN_INFO, transport, fmt, ## args) + +#define TR_ASSERT(x, exp) \ + do { \ + if (!(exp)) \ + tr_err(x, "ASSERTION %s FAILED in %s\n", \ + #exp, __func__); \ + } while (0) + +struct drbd_resource; +struct drbd_connection; +struct drbd_peer_device; + +enum drbd_stream { + DATA_STREAM, + CONTROL_STREAM +}; + +enum drbd_tr_hints { + CORK, + UNCORK, + NODELAY, + NOSPACE, + QUICKACK +}; + +enum { /* bits in the flags word */ + NET_CONGESTED, /* The data socket is congested */ + RESOLVE_CONFLICTS, /* Set on one node, cleared on the peer! */ +}; + +enum drbd_tr_free_op { + CLOSE_CONNECTION, + DESTROY_TRANSPORT +}; + + +/* A transport might wrap its own data structure around this. Having + this base class as its first member. */ +struct drbd_path { + struct sockaddr_storage my_addr; + struct sockaddr_storage peer_addr; + + struct kref kref; + + int my_addr_len; + int peer_addr_len; + bool established; /* updated by the transport */ + + struct list_head list; +}; + +/* Each transport implementation should embed a struct drbd_transport + into it's instance data structure. */ +struct drbd_transport { + struct drbd_transport_ops *ops; + struct drbd_transport_class *class; + + struct list_head paths; + + const char *log_prefix; /* resource name */ + struct net_conf *net_conf; /* content protected by rcu */ + + /* These members are intended to be updated by the transport: */ + unsigned int ko_count; + unsigned long flags; +}; + +struct drbd_transport_stats { + int unread_received; + int unacked_send; + int send_buffer_size; + int send_buffer_used; +}; + +/* argument to ->recv_pages() */ +struct drbd_page_chain_head { + struct page *head; + unsigned int nr_pages; +}; + +struct drbd_transport_ops { + void (*free)(struct drbd_transport *, enum drbd_tr_free_op free_op); + int (*connect)(struct drbd_transport *); + +/** + * recv() - Receive data via the transport + * @transport: The transport to use + * @stream: The stream within the transport to use. Ether DATA_STREAM or CONTROL_STREAM + * @buf: The function will place here the pointer to the data area + * @size: Number of byte to receive + * @msg_flags: Bitmask of CALLER_BUFFER, GROW_BUFFER and MSG_DONTWAIT + * + * recv() returns the requests data in a buffer (owned by the transport). + * You may pass MSG_DONTWAIT as flags. Usually with the next call to recv() + * or recv_pages() on the same stream, the buffer may no longer be accessed + * by the caller. I.e. it is reclaimed by the transport. + * + * If the transport was not capable of fulfilling the complete "wish" of the + * caller (that means it returned a smaller size that size), the caller may + * call recv() again with the flag GROW_BUFFER, and *buf as returned by the + * previous call. + * Note1: This can happen if MSG_DONTWAIT was used, or if a receive timeout + * was we with set_rcvtimeo(). + * Note2: recv() is free to re-locate the buffer in such a call. I.e. to + * modify *buf. Then it copies the content received so far to the new + * memory location. + * + * Last not least the caller may also pass an arbitrary pointer in *buf with + * the CALLER_BUFFER flag. This is expected to be used for small amounts + * of data only + * + * Upon success the function returns the bytes read. Upon error the return + * code is negative. A 0 indicates that the socket was closed by the remote + * side. + */ + int (*recv)(struct drbd_transport *, enum drbd_stream, void **buf, size_t size, int flags); + +/** + * recv_pages() - Receive bulk data via the transport's DATA_STREAM + * @peer_device: Identify the transport and the device + * @page_chain: Here recv_pages() will place the page chain head and length + * @size: Number of bytes to receive + * + * recv_pages() will return the requested amount of data from DATA_STREAM, + * and place it into pages allocated with drbd_alloc_pages(). + * + * Upon success the function returns 0. Upon error the function returns a + * negative value + */ + int (*recv_pages)(struct drbd_transport *, struct drbd_page_chain_head *, size_t size); + + void (*stats)(struct drbd_transport *, struct drbd_transport_stats *stats); + void (*set_rcvtimeo)(struct drbd_transport *, enum drbd_stream, long timeout); + long (*get_rcvtimeo)(struct drbd_transport *, enum drbd_stream); + int (*send_page)(struct drbd_transport *, enum drbd_stream, struct page *, + int offset, size_t size, unsigned msg_flags); + int (*send_zc_bio)(struct drbd_transport *, struct bio *bio); + bool (*stream_ok)(struct drbd_transport *, enum drbd_stream); + bool (*hint)(struct drbd_transport *, enum drbd_stream, enum drbd_tr_hints hint); + void (*debugfs_show)(struct drbd_transport *, struct seq_file *m); + int (*add_path)(struct drbd_transport *, struct drbd_path *path); + int (*remove_path)(struct drbd_transport *, struct drbd_path *path); +}; + +struct drbd_transport_class { + const char *name; + const int instance_size; + const int path_instance_size; + struct module *module; + int (*init)(struct drbd_transport *); + struct list_head list; +}; + + +/* An "abstract base class" for transport implementations. I.e. it + should be embedded into a transport specific representation of a + listening "socket" */ +struct drbd_listener { + struct kref kref; + struct drbd_resource *resource; + struct list_head list; /* link for resource->listeners */ + struct list_head waiters; /* list head for waiter structs*/ + spinlock_t waiters_lock; + int pending_accepts; + struct sockaddr_storage listen_addr; + void (*destroy)(struct drbd_listener *); +}; + +/* This represents a drbd receiver thread that is waiting for an + incoming connection attempt. Again, should be embedded into a + implementation object */ +struct drbd_waiter { + struct drbd_transport *transport; + wait_queue_head_t wait; + struct list_head list; + struct drbd_listener *listener; +}; + +/* drbd_main.c */ +extern void drbd_destroy_path(struct kref *kref); + +/* drbd_transport.c */ +extern int drbd_register_transport_class(struct drbd_transport_class *transport_class, + int api_version, + int drbd_transport_size); +extern void drbd_unregister_transport_class(struct drbd_transport_class *transport_class); +extern struct drbd_transport_class *drbd_get_transport_class(const char *transport_name); +extern void drbd_put_transport_class(struct drbd_transport_class *); +extern void drbd_print_transports_loaded(struct seq_file *seq); + +extern int drbd_get_listener(struct drbd_waiter *waiter, + const struct sockaddr *addr, + int (*create_fn)(struct drbd_transport *, const struct sockaddr *, struct drbd_listener **)); +extern void drbd_put_listener(struct drbd_waiter *waiter); +extern struct drbd_waiter *drbd_find_waiter_by_addr(struct drbd_listener *, struct sockaddr_storage *); +extern bool drbd_stream_send_timed_out(struct drbd_transport *transport, enum drbd_stream stream); +extern bool drbd_should_abort_listening(struct drbd_transport *transport); +extern void drbd_path_event(struct drbd_transport *transport, struct drbd_path *path); + +/* drbd_receiver.c*/ +extern struct page *drbd_alloc_pages(struct drbd_transport *, unsigned int, gfp_t); +extern void drbd_free_pages(struct drbd_transport *transport, struct page *page, int is_net); + +static inline void drbd_alloc_page_chain(struct drbd_transport *t, + struct drbd_page_chain_head *chain, unsigned int nr, gfp_t gfp_flags) +{ + chain->head = drbd_alloc_pages(t, nr, gfp_flags); + chain->nr_pages = chain->head ? nr : 0; +} + +static inline void drbd_free_page_chain(struct drbd_transport *transport, struct drbd_page_chain_head *chain, int is_net) +{ + drbd_free_pages(transport, chain->head, is_net); + chain->head = NULL; + chain->nr_pages = 0; +} + +/* + * Some helper functions to deal with our page chains. + */ +/* Our transports may sometimes need to only partially use a page. + * We need to express that somehow. Use this struct, and "graft" it into + * struct page at page->lru. + * + * According to include/linux/mm.h: + * | A page may be used by anyone else who does a __get_free_page(). + * | In this case, page_count still tracks the references, and should only + * | be used through the normal accessor functions. The top bits of page->flags + * | and page->virtual store page management information, but all other fields + * | are unused and could be used privately, carefully. The management of this + * | page is the responsibility of the one who allocated it, and those who have + * | subsequently been given references to it. + * (we do alloc_page(), that is equivalent). + * + * Red Hat struct page is different from upstream (layout and members) :( + * So I am not too sure about the "all other fields", and it is not as easy to + * find a place where sizeof(struct drbd_page_chain) would fit on all archs and + * distribution-changed layouts. + * + * But (upstream) struct page also says: + * | struct list_head lru; * ... + * | * Can be used as a generic list + * | * by the page owner. + * + * On 32bit, use unsigned short for offset and size, + * to still fit in sizeof(page->lru). + */ + +/* grafted over struct page.lru */ +struct drbd_page_chain { + struct page *next; /* next page in chain, if any */ +#ifdef CONFIG_64BIT + unsigned int offset; /* start offset of data within this page */ + unsigned int size; /* number of data bytes within this page */ +#else +#if PAGE_SIZE > (1U<<16) +#error "won't work." +#endif + unsigned short offset; /* start offset of data within this page */ + unsigned short size; /* number of data bytes within this page */ +#endif +}; + +static inline void dummy_for_buildbug(void) +{ + struct page *dummy; + BUILD_BUG_ON(sizeof(struct drbd_page_chain) > sizeof(dummy->lru)); +} + +#define page_chain_next(page) \ + (((struct drbd_page_chain*)&(page)->lru)->next) +#define page_chain_size(page) \ + (((struct drbd_page_chain*)&(page)->lru)->size) +#define page_chain_offset(page) \ + (((struct drbd_page_chain*)&(page)->lru)->offset) +#define set_page_chain_next(page, v) \ + (((struct drbd_page_chain*)&(page)->lru)->next = (v)) +#define set_page_chain_size(page, v) \ + (((struct drbd_page_chain*)&(page)->lru)->size = (v)) +#define set_page_chain_offset(page, v) \ + (((struct drbd_page_chain*)&(page)->lru)->offset = (v)) +#define set_page_chain_next_offset_size(page, n, o, s) \ + *((struct drbd_page_chain*)&(page)->lru) = \ + ((struct drbd_page_chain) { \ + .next = (n), \ + .offset = (o), \ + .size = (s), \ + }) + +#define page_chain_for_each(page) \ + for (; page && ({ prefetch(page_chain_next(page)); 1; }); \ + page = page_chain_next(page)) +#define page_chain_for_each_safe(page, n) \ + for (; page && ({ n = page_chain_next(page); 1; }); page = n) + +#ifndef SK_CAN_REUSE +/* This constant was introduced by Pavel Emelyanov on + Thu Apr 19 03:39:36 2012 +0000. Before the release of linux-3.5 + commit 4a17fd52 sock: Introduce named constants for sk_reuse */ +#define SK_CAN_REUSE 1 +#endif + +#endif +drbd-headers/drbd_strings.h0000644000077500007750000000136113070663767015305 0ustar shrekshrek#ifndef __DRBD_STRINGS_H +#define __DRBD_STRINGS_H + +struct state_names { + const char * const *names; + unsigned int size; +}; + +extern struct state_names drbd_conn_state_names; +extern struct state_names drbd_repl_state_names; +extern struct state_names drbd_role_state_names; +extern struct state_names drbd_disk_state_names; +extern struct state_names drbd_error_messages; + +enum drbd_packet; + +extern const char *drbd_repl_str(enum drbd_repl_state); +extern const char *drbd_conn_str(enum drbd_conn_state); +extern const char *drbd_role_str(enum drbd_role); +extern const char *drbd_disk_str(enum drbd_disk_state); +extern const char *drbd_set_st_err_str(enum drbd_state_rv); +extern const char *drbd_packet_name(enum drbd_packet); + + +#endif /* __DRBD_STRINGS_H */ +drbd-headers/drbd_meta_data.h0000644000077500007750000000261313070663767015534 0ustar shrekshrek#ifndef DRBD_META_DATA_H +#define DRBD_META_DATA_H + +#ifdef __KERNEL__ +#define be_u64 u64 +#define be_u32 u32 +#define be_s32 s32 +#define be_u16 u16 +#else +#define be_u64 struct { uint64_t be; } +#define be_u32 struct { uint32_t be; } +#define be_s32 struct { int32_t be; } +#define be_u16 struct { uint16_t be; } +#endif + +struct peer_dev_md_on_disk_9 { + be_u64 bitmap_uuid; + be_u64 bitmap_dagtag; + be_u32 flags; + be_s32 bitmap_index; + be_u32 reserved_u32[2]; +} __packed; + +struct meta_data_on_disk_9 { + be_u64 effective_size; /* last agreed size */ + be_u64 current_uuid; + be_u64 reserved_u64[4]; /* to have the magic at the same position as in v07, and v08 */ + be_u64 device_uuid; + be_u32 flags; /* MDF */ + be_u32 magic; + be_u32 md_size_sect; + be_u32 al_offset; /* offset to this block */ + be_u32 al_nr_extents; /* important for restoring the AL */ + be_u32 bm_offset; /* offset to the bitmap, from here */ + be_u32 bm_bytes_per_bit; /* BM_BLOCK_SIZE */ + be_u32 la_peer_max_bio_size; /* last peer max_bio_size */ + be_u32 bm_max_peers; + be_s32 node_id; + + /* see al_tr_number_to_on_disk_sector() */ + be_u32 al_stripes; + be_u32 al_stripe_size_4k; + + be_u32 reserved_u32[2]; + + struct peer_dev_md_on_disk_9 peers[DRBD_PEERS_MAX]; + be_u64 history_uuids[HISTORY_UUIDS]; + + char padding[0] __attribute__((aligned(4096))); +} __packed; + + +#undef be_u64 +#undef be_u32 +#undef be_s32 +#undef be_u16 + +#endif +drbd-headers/.git0000644000077500007750000000004513070663767013232 0ustar shrekshrekgitdir: ../.git/modules/drbd-headers + \ No newline at end of file diff --git a/drbd-utils.spec b/drbd-utils.spec new file mode 100644 index 00000000..98e3634d --- /dev/null +++ b/drbd-utils.spec @@ -0,0 +1,285 @@ +%def_without xen +%define githash c331d6627ad1af44c4d2ec17b0ff6d5f8ba0e833 +%define gitdiff c6e62702d5e4fb2cf6b3fa27e67cb0d4b399a30b +%define _localstatedir %_var +%global optflags_lto %optflags_lto -ffat-lto-objects + +Name: drbd-utils +Version: 9.24.0 +Release: alt1 + +Summary: DRBD user-land tools and scripts +License: GPLv2+ +Group: System/Kernel and hardware + +Url: http://www.drbd.org/ +Source0: %name-%version.tar +Source1: %name-headers-%version.tar +Patch0: %name-%version-%release.patch + +%define check_arches x86_64 %ix86 +%ifarch %check_arches +%def_with check +%else +%def_without check +%endif + + +BuildRequires: docbook-style-xsl flex xsltproc +BuildRequires: gcc-c++ po4a udev libudev-devel libsystemd-devel +BuildRequires: asciidoctor resource-agents +%{?!_without_check:%{?!_disable_check:BuildRequires: /proc clitest}} + +Requires: linux-ha-common + +Conflicts: drbd-tools drbd83-tools +Provides: %name-bash-completion = %EVR +Obsoletes: %name-bash-completion < %EVR + +%description +DRBD refers to block devices designed as a building block to form high +availability (HA) clusters. This is done by mirroring a whole block device +via an assigned network. DRBD can be understood as network based raid-1. + +This packages includes the DRBD administration tools. + +%package xen +Summary: Xen block device management script for DRBD +Group: System/Kernel and hardware +Requires: %name = %version-%release +Requires: xen +BuildArch: noarch + +%description xen +This package contains a Xen block device helper script for DRBD, capable of +promoting and demoting DRBD resources as necessary. + +%package pacemaker +Summary: Pacemaker resource agent for DRBD +Group: System/Kernel and hardware +Requires: %name = %version-%release +Requires: pacemaker +License: GPLv2 +BuildArch: noarch + +%description pacemaker +This package contains the master/slave DRBD resource agent for the +Pacemaker High Availability cluster manager. + +%package rgmanager +Summary: Red Hat Cluster Suite agent for DRBD +Group: System/Kernel and hardware +Requires: %name = %version-%release +BuildArch: noarch + +%description rgmanager +This package contains the DRBD resource agent for the Red Hat Cluster Suite +resource manager. + +%prep +%setup -a1 +tar -xf %SOURCE1 -C drbd-headers +%patch0 -p1 +(echo -e "#define GITHASH \"%githash\""; \ + echo -e "#define GITDIFF \"%gitdiff\"") > user/shared/drbd_buildtag.h +%ifarch %e2k +# lcc 1.25.15 barfs at DrbdRole.cpp:36, DrbdVolume.cpp:748 +sed -i 's,-Wshadow,,' user/drbdmon/Makefile* +%endif + +%build +%autoreconf +%configure \ + %{subst_with xen} \ + --with-udev \ + --with-pacemaker \ + --with-rgmanager \ + --with-heartbeat \ + --with-distro=generic + +# Bug in configure.ac, enabling WITH_DRBDMON anyway: +sed -i "s|WITH_DRBDMON[[:space:]]*=[[:space:]]*no|WITH_DRBDMON = yes|" \ + Makefile user/drbdmon/Makefile documentation/common/Makefile_v9_com +# Bug in compiler option: +sed -i "s|--pedantic-errors|-pedantic-errors|" user/drbdmon/Makefile + +%make_build + +%install +%makeinstall_std + +rm -rf %buildroot%_mandir/ja +rm -f %buildroot/etc/init.d/drbd # NB: _not_ %%_initdir here +pushd scripts +install -pDm644 -t %buildroot%_unitdir *.service +install -pDm644 -t %buildroot%_unitdir *.target +install -pDm755 -t %buildroot/lib/drbd/scripts drbd drbd-service-shim.sh drbd-wait-promotable.sh ocf.ra.wrapper.sh +install -pDm755 drbd %buildroot%_initdir/drbd +popd + +%post +%post_service drbd + +%preun +%preun_service drbd + +%check +make test + +%files +%doc scripts/drbd.conf.example COPYING ChangeLog README.md +%config(noreplace) %_sysconfdir/drbd.conf +%dir %_sysconfdir/drbd.d +%config(noreplace) %_sysconfdir/drbd.d/global_common.conf +%config(noreplace) %_sysconfdir/multipath/conf.d/drbd.conf +%_sysconfdir/ha.d/resource.d/* +%_initdir/drbd +%_unitdir/drbd.service +%_unitdir/drbd-lvchange@.service +%_unitdir/drbd-promote@.service +%_unitdir/drbd-reconfigure-suspend-or-error@.service +%_unitdir/drbd-demote-or-escalate@.service +%_unitdir/drbd-services@.target +%_unitdir/drbd-wait-promotable@.service +%_unitdir/drbd@.service +%_unitdir/drbd@.target +%_unitdir/ocf.ra@.service +%_sbindir/drbdsetup +%_sbindir/drbdadm +%_sbindir/drbdmeta +%_sbindir/drbdmon +%dir /lib/drbd +/lib/drbd/drbdadm-* +/lib/drbd/drbdsetup-* +%dir /lib/drbd/scripts +/lib/drbd/scripts/drbd +/lib/drbd/scripts/drbd-service-shim.sh +/lib/drbd/scripts/drbd-wait-promotable.sh +/lib/drbd/scripts/ocf.ra.wrapper.sh +/lib/udev/rules.d/65-drbd.rules +%exclude /usr/lib/drbd/crm-*fence-peer.sh +%exclude /usr/lib/drbd/stonith_admin-fence-peer.sh +%dir /usr/lib/drbd +/usr/lib/drbd/*.sh +/usr/lib/drbd/rhcs_fence +%dir %_var/lib/drbd +%_man8dir/drbd* +%_man7dir/* +%_man5dir/drbd* +%_sysconfdir/bash_completion.d/* + +%if_with xen +%files xen +%_sysconfdir/xen/scripts/block-drbd +%endif + +%files pacemaker +%dir /usr/lib/ocf/resource.d/linbit +/usr/lib/ocf/resource.d/linbit/drbd +/usr/lib/ocf/resource.d/linbit/drbd.shellfuncs.sh +/usr/lib/ocf/resource.d/linbit/drbd-attr +/usr/lib/drbd/crm-*fence-peer.sh +/usr/lib/drbd/stonith_admin-fence-peer.sh + +%files rgmanager +%_datadir/cluster/drbd.sh +%_datadir/cluster/drbd.metadata + +%changelog +* Thu Jun 15 2023 Andrew A. Vasilyev 9.24.0-alt1 +- 9.24.0 + +* Tue Mar 14 2023 Andrew A. Vasilyev 9.23.1-alt1 +- 9.23.1 + +* Wed Jan 25 2023 Andrew A. Vasilyev 9.23.0-alt1 +- 9.23.0 + +* Wed Sep 21 2022 Andrew A. Vasilyev 9.22.0-alt1 +- 9.22.0 + +* Mon Jul 18 2022 Andrew A. Vasilyev 9.21.4-alt1 +- 9.21.4 + +* Tue Jul 12 2022 Andrew A. Vasilyev 9.21.3-alt1 +- 9.21.3 + +* Wed Jun 08 2022 Andrew A. Vasilyev 9.21.2-alt1 +- 9.21.2 + +* Thu Apr 28 2022 Andrew A. Vasilyev 9.21.1-alt1 +- 9.21.1 + +* Tue Apr 26 2022 Andrew A. Vasilyev 9.21.0-alt1 +- 9.21.0 + +* Mon Jan 31 2022 Andrew A. Vasilyev 9.20.2-alt1 +- 9.20.2 + +* Thu Jan 13 2022 Andrew A. Vasilyev 9.20.0-alt1 +- 9.20.0 + +* Fri Dec 03 2021 Egor Ignatov 9.19.1-alt4 +- drbd.ocf: change type name 'numeric' to 'integer' + +* Mon Nov 29 2021 Andrew A. Vasilyev 9.19.1-alt3 +- add Provides and Obsoletes for bash-completion package + +* Mon Nov 29 2021 Andrew A. Vasilyev 9.19.1-alt2 +- remove journalctl and systemctl direct requirements (closes: #41454) +- move bash completion to main package + +* Mon Nov 22 2021 Andrew A. Vasilyev 9.19.1-alt1 +- 9.19.1 + +* Mon Oct 04 2021 Andrew A. Vasilyev 9.19.0-alt1 +- 9.19.0 +- add %%check for x86_64 and %%ix86 + +* Thu Aug 05 2021 Andrew A. Vasilyev 9.18.2-alt1 +- 9.18.2 + +* Wed Jul 21 2021 Andrew A. Vasilyev 9.18.1-alt1 +- 9.18.1 +- add systemd templates and ocf RA wrapper script + +* Fri Jun 18 2021 Michael Shigorin 9.17.0-alt1.1 +- E2K: ftbfs workaround + +* Thu Apr 29 2021 Andrew A. Vasilyev 9.17.0-alt1 +- 9.17.0 + +* Fri Feb 19 2021 Andrew A. Vasilyev 9.16.0-alt1 +- 9.16.0 + +* Wed Dec 30 2020 Andrew A. Vasilyev 9.15.1-alt1 +- 9.15.1 + +* Thu May 14 2020 Andrew A. Vasilyev 9.13.1-alt1 +- 9.13.1 + +* Mon Apr 20 2020 Andrew A. Vasilyev 9.12.2-alt1 +- 9.12.2 + +* Tue Mar 24 2020 Andrew A. Vasilyev 9.12.1-alt1 +- 9.12.1 + +* Sat Mar 07 2020 Andrew A. Vasilyev 9.12.0-alt1.1 +- Avoid undocumented option form (for lcc on e2k actually) (mike@) +- Minor spec cleanup (mike@) + +* Wed Feb 19 2020 Andrew A. Vasilyev 9.12.0-alt1 +- 9.12.0 + +* Tue Apr 04 2017 Valery Inozemtsev 8.9.6-alt1 +- 8.9.6 + +* Fri May 27 2016 Mikhail Efremov 8.9.0-alt3 +- Disable xen support. + +* Tue Jan 26 2016 Lenar Shakirov 8.9.0-alt2 +- Fixed build (man page packaging) + +* Mon Sep 01 2014 Lenar Shakirov 8.9.0-alt1 +- First build for ALT as separate package "%name" (based on Fedora 8.9.0-8.fc21.src) + diff --git a/drbd.service b/drbd.service new file mode 100644 index 00000000..ddd6c62b --- /dev/null +++ b/drbd.service @@ -0,0 +1,19 @@ +[Unit] +Description=Distributed Replicated Block Device +After=systemd-modules-load.service network.target + +[Service] +Type=oneshot +RemainAfterExit=yes + +# load config +ExecStart=/usr/sbin/drbdadm adjust all +# user interruptible version of wait-connect all +ExecStart=/usr/sbin/drbdadm wait-con-int +# become primary if configured +ExecStart=/usr/sbin/drbdadm sh-b-pri all +# disconnect and detach all resources +ExecStop=/usr/sbin/drbdadm down all + +[Install] +WantedBy=multi-user.target diff --git a/scripts/drbd b/scripts/drbd index fbed28f2..1046fc68 100755 --- a/scripts/drbd +++ b/scripts/drbd @@ -63,8 +63,6 @@ assure_module_is_loaded() echo "Can not load the drbd module."$'\n' exit 5 # LSB for "not installed" } - # tell klogd to reload module symbol information ... - [ -e /var/run/klogd.pid ] && [ -x /sbin/klogd ] && /sbin/klogd -i } drbd_pretty_status() @@ -256,7 +254,7 @@ case "$1" in fi ;; - stop) + condstop|stop) $DRBDADM sh-nop [[ $? = 127 ]] && exit 5 # LSB for "not installed" log_daemon_msg "Stopping all DRBD resources" @@ -315,12 +313,12 @@ case "$1" in run_hook reload log_end_msg 0 ;; - restart|force-reload) + condrestart|restart|force-reload) ( . $0 stop ) ( . $0 start ) ;; *) - echo "Usage: /etc/init.d/drbd {start|stop|status|reload|restart|force-reload}" + echo "Usage: /etc/init.d/drbd {start|condstop|stop|status|reload|condrestart|restart|force-reload}" exit 1 ;; esac diff --git a/scripts/drbd-service-shim.sh b/scripts/drbd-service-shim.sh index 78638746..069b74ea 100755 --- a/scripts/drbd-service-shim.sh +++ b/scripts/drbd-service-shim.sh @@ -7,6 +7,9 @@ # By using this script, we first transition to a general unconfined context, # which allows us calling drbdadm and drbdsetup without these restrictions. +SYSTEMCTL="/bin/systemctl" +JOURNALCTL="/bin/journalctl" + cmd=$1 res=$2 @@ -20,7 +23,7 @@ secondary_check() { 0) # successfully demoted, already secondary anyways, # or module is not even loaded - systemctl reset-failed "drbd-promote@$res.service" + ${SYSTEMCTL} reset-failed "drbd-promote@$res.service" return 0;; # any other special treatment for special exit codes? @@ -63,7 +66,7 @@ secondary*-or-escalate) # to (hopefully) persistent storage, so we at least have some # indication of why we rebooted -- if that turns out to be necessary. echo >&2 "<6>about to demote (or escalate to the FailureAction)" - journalctl --flush --sync + ${JOURNALCTL} --flush --sync secondary_check && exit 0 ex_secondary=$? # if we fail due to timeout, this won't even be reached :-( diff --git a/scripts/drbddisk b/scripts/drbddisk index f9f9822e..25f47f38 100755 --- a/scripts/drbddisk +++ b/scripts/drbddisk @@ -8,7 +8,7 @@ ### DEFAULTFILE="/etc/default/drbd" -DRBDADM="/sbin/drbdadm" +DRBDADM="/usr/sbin/drbdadm" if [ -f $DEFAULTFILE ]; then . $DEFAULTFILE diff --git a/scripts/drbdupper b/scripts/drbdupper index b09c085c..dd874552 100644 --- a/scripts/drbdupper +++ b/scripts/drbdupper @@ -11,7 +11,7 @@ ### DEFAULTFILE="/etc/default/drbd" -DRBDADM="/sbin/drbdadm" +DRBDADM="/usr/sbin/drbdadm" if [ -f $DEFAULTFILE ]; then . $DEFAULTFILE diff --git a/scripts/global_common.conf b/scripts/global_common.conf index fd1c5d15..bf1d8db0 100644 --- a/scripts/global_common.conf +++ b/scripts/global_common.conf @@ -3,7 +3,7 @@ # feature requests visit http://www.linbit.com global { - usage-count yes; + usage-count no; # Decide what kind of udev symlinks you want for "implicit" volumes # (those without explicit volume {} block, implied vnr=0): diff --git a/user/shared/drbd_buildtag.sh b/user/shared/drbd_buildtag.sh index b578ceeb..c2ea581b 100755 --- a/user/shared/drbd_buildtag.sh +++ b/user/shared/drbd_buildtag.sh @@ -33,7 +33,7 @@ drbd_buildtag_c() { echo -e "/* automatically generated. DO NOT EDIT. */" echo -e "#include \"drbd_buildtag.h\"" echo -e "const char *drbd_buildtag(void)\n{" - echo -e "\treturn \"GIT-hash: \" GITHASH GITDIFF" + echo -e "\treturn \"GIT-hash: \" GITHASH \" \" GITDIFF" if [ -z "${WANT_DRBD_REPRODUCIBLE_BUILD}" ] || [ -z "${SOURCE_DATE_EPOCH}" ] ; then buildinfo="build by ${USER}@${HOSTNAME}, $(date "+%F %T")" else \