mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 03:27:30 -04:00
drbd: replace genl_magic with explicit netlink serialization
Replace the genl_magic multi-include macro system with explicit serialization and parsing. The *_gen files were initially produced from a YNL spec via a customized ynl-gen-c, but the DRBD netlink family is effectively frozen, so the generator is kept unmodified. All new functionality will land in a separate, properly-designed family. Carry the resulting code as ordinary in-tree source rather than landing the spec and generator changes that produced it. The bulk of the changes are mechanical renames to fit the YNL naming conventions: - Handler functions: drbd_adm_* -> drbd_nl_*_doit/dumpit - GENL_MAGIC_VERSION -> DRBD_FAMILY_VERSION - GENL_MAGIC_FAMILY_HDRSZ -> sizeof(struct drbd_genlmsghdr) - drbd_genl_family -> drbd_nl_family - Attribute IDs: T_* -> DRBD_A_* Remove the nested_attr_tb static global buffer and move to a per-call allocation approach: each deserialization manages its own nested attribute table. This will be needed anyway when we eventually move to parallel_ops, and it's actually simpler this way, so make the move now. Replace the functionality of the "sensitive" flag: this was only used by a single field (shared_secret); open-code redaction logic for that locally. Also replace the "invariant" flag: this only had a couple of users, and those basically never change. Hard code the check directly inline. The genl_family struct itself is defined manually in drbd_nl.c. Also replace a couple of drbd-specific wrappers (nla_put_u64_0pad, drbd_nla_find_nested) with standard kernel functions while we're at it. Finally, completely remove the genl_magic system; DRBD was its only user. Signed-off-by: Christoph Böhmwalder <christoph.boehmwalder@linbit.com> Acked-by: Jakub Kicinski <kuba@kernel.org> Link: https://patch.msgid.link/20260506124541.1951772-3-christoph.boehmwalder@linbit.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
committed by
Jens Axboe
parent
a54f499838
commit
8098eeb693
@@ -3,6 +3,7 @@ drbd-y := drbd_buildtag.o drbd_bitmap.o drbd_proc.o
|
||||
drbd-y += drbd_worker.o drbd_receiver.o drbd_req.o drbd_actlog.o
|
||||
drbd-y += drbd_main.o drbd_strings.o drbd_nl.o
|
||||
drbd-y += drbd_interval.o drbd_state.o
|
||||
drbd-y += drbd_nl_gen.o
|
||||
drbd-$(CONFIG_DEBUG_FS) += drbd_debugfs.o
|
||||
|
||||
obj-$(CONFIG_BLK_DEV_DRBD) += drbd.o
|
||||
|
||||
@@ -844,7 +844,7 @@ static int drbd_version_show(struct seq_file *m, void *ignored)
|
||||
{
|
||||
seq_printf(m, "# %s\n", drbd_buildtag());
|
||||
seq_printf(m, "VERSION=%s\n", REL_VERSION);
|
||||
seq_printf(m, "API_VERSION=%u\n", GENL_MAGIC_VERSION);
|
||||
seq_printf(m, "API_VERSION=%u\n", DRBD_FAMILY_VERSION);
|
||||
seq_printf(m, "PRO_VERSION_MIN=%u\n", PRO_VERSION_MIN);
|
||||
seq_printf(m, "PRO_VERSION_MAX=%u\n", PRO_VERSION_MAX);
|
||||
return 0;
|
||||
|
||||
@@ -32,14 +32,16 @@
|
||||
#include <net/tcp.h>
|
||||
#include <linux/lru_cache.h>
|
||||
#include <linux/prefetch.h>
|
||||
#include <linux/drbd_genl_api.h>
|
||||
#include <linux/drbd.h>
|
||||
#include "drbd_config.h"
|
||||
#include "drbd_nl_gen.h"
|
||||
#include "drbd_strings.h"
|
||||
#include "drbd_state.h"
|
||||
#include "drbd_protocol.h"
|
||||
#include "drbd_polymorph_printk.h"
|
||||
|
||||
extern struct genl_family drbd_nl_family;
|
||||
|
||||
/* shared module parameters, defined in drbd_main.c */
|
||||
#ifdef CONFIG_DRBD_FAULT_INJECTION
|
||||
extern int drbd_enable_faults;
|
||||
|
||||
@@ -2324,7 +2324,7 @@ static void drbd_cleanup(void)
|
||||
if (retry.wq)
|
||||
destroy_workqueue(retry.wq);
|
||||
|
||||
drbd_genl_unregister();
|
||||
genl_unregister_family(&drbd_nl_family);
|
||||
|
||||
idr_for_each_entry(&drbd_devices, device, i)
|
||||
drbd_delete_device(device);
|
||||
@@ -2846,7 +2846,7 @@ static int __init drbd_init(void)
|
||||
mutex_init(&resources_mutex);
|
||||
INIT_LIST_HEAD(&drbd_resources);
|
||||
|
||||
err = drbd_genl_register();
|
||||
err = genl_register_family(&drbd_nl_family);
|
||||
if (err) {
|
||||
pr_err("unable to register generic netlink family\n");
|
||||
goto fail;
|
||||
@@ -2876,7 +2876,7 @@ static int __init drbd_init(void)
|
||||
|
||||
pr_info("initialized. "
|
||||
"Version: " REL_VERSION " (api:%d/proto:%d-%d)\n",
|
||||
GENL_MAGIC_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX);
|
||||
DRBD_FAMILY_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX);
|
||||
pr_info("%s\n", drbd_buildtag());
|
||||
pr_info("registered as block device major %d\n", DRBD_MAJOR);
|
||||
return 0; /* Success! */
|
||||
|
||||
@@ -31,59 +31,13 @@
|
||||
|
||||
#include <net/genetlink.h>
|
||||
|
||||
/* .doit */
|
||||
// int drbd_adm_create_resource(struct sk_buff *skb, struct genl_info *info);
|
||||
// int drbd_adm_delete_resource(struct sk_buff *skb, struct genl_info *info);
|
||||
#include "drbd_nl_gen.h"
|
||||
|
||||
int drbd_adm_new_minor(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_del_minor(struct sk_buff *skb, struct genl_info *info);
|
||||
|
||||
int drbd_adm_new_resource(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_del_resource(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_down(struct sk_buff *skb, struct genl_info *info);
|
||||
|
||||
int drbd_adm_set_role(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_detach(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_start_ov(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_disconnect(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_invalidate(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_invalidate_peer(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_pause_sync(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_resume_sync(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_suspend_io(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_resume_io(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_outdate(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_get_status(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_adm_get_timeout_type(struct sk_buff *skb, struct genl_info *info);
|
||||
/* .dumpit */
|
||||
int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb);
|
||||
int drbd_adm_dump_resources(struct sk_buff *skb, struct netlink_callback *cb);
|
||||
int drbd_adm_dump_devices(struct sk_buff *skb, struct netlink_callback *cb);
|
||||
int drbd_adm_dump_devices_done(struct netlink_callback *cb);
|
||||
int drbd_adm_dump_connections(struct sk_buff *skb, struct netlink_callback *cb);
|
||||
int drbd_adm_dump_connections_done(struct netlink_callback *cb);
|
||||
int drbd_adm_dump_peer_devices(struct sk_buff *skb, struct netlink_callback *cb);
|
||||
int drbd_adm_dump_peer_devices_done(struct netlink_callback *cb);
|
||||
int drbd_adm_get_initial_state(struct sk_buff *skb, struct netlink_callback *cb);
|
||||
|
||||
#include <linux/drbd_genl_api.h>
|
||||
|
||||
static int drbd_pre_doit(const struct genl_split_ops *ops,
|
||||
struct sk_buff *skb, struct genl_info *info);
|
||||
static void drbd_post_doit(const struct genl_split_ops *ops,
|
||||
struct sk_buff *skb, struct genl_info *info);
|
||||
|
||||
#define GENL_MAGIC_FAMILY_PRE_DOIT drbd_pre_doit
|
||||
#define GENL_MAGIC_FAMILY_POST_DOIT drbd_post_doit
|
||||
|
||||
#include <linux/genl_magic_func.h>
|
||||
static int drbd_genl_multicast_events(struct sk_buff *skb, gfp_t flags)
|
||||
{
|
||||
return genlmsg_multicast(&drbd_nl_family, skb, 0,
|
||||
DRBD_NLGRP_EVENTS, flags);
|
||||
}
|
||||
|
||||
static atomic_t drbd_genl_seq = ATOMIC_INIT(2); /* two. */
|
||||
static atomic_t notify_genl_seq = ATOMIC_INIT(2); /* two. */
|
||||
@@ -114,7 +68,7 @@ static int drbd_msg_put_info(struct sk_buff *skb, const char *info)
|
||||
if (!nla)
|
||||
return err;
|
||||
|
||||
err = nla_put_string(skb, T_info_text, info);
|
||||
err = nla_put_string(skb, DRBD_A_DRBD_CFG_REPLY_INFO_TEXT, info);
|
||||
if (err) {
|
||||
nla_nest_cancel(skb, nla);
|
||||
return err;
|
||||
@@ -135,7 +89,7 @@ static int drbd_msg_sprintf_info(struct sk_buff *skb, const char *fmt, ...)
|
||||
if (!nla)
|
||||
return err;
|
||||
|
||||
txt = nla_reserve(skb, T_info_text, 256);
|
||||
txt = nla_reserve(skb, DRBD_A_DRBD_CFG_REPLY_INFO_TEXT, 256);
|
||||
if (!txt) {
|
||||
nla_nest_cancel(skb, nla);
|
||||
return err;
|
||||
@@ -187,6 +141,15 @@ static const unsigned int drbd_genl_cmd_flags[] = {
|
||||
[DRBD_ADM_DOWN] = DRBD_ADM_NEED_RESOURCE,
|
||||
};
|
||||
|
||||
/* Detect attempts to change invariant attributes in a _change_ handler. */
|
||||
#define has_invariant(ntb, attr) \
|
||||
({ \
|
||||
bool __found = !!(ntb)[attr]; \
|
||||
if (__found) \
|
||||
pr_info("must not change invariant attr: %s\n", #attr); \
|
||||
__found; \
|
||||
})
|
||||
|
||||
/*
|
||||
* At this point, we still rely on the global genl_lock().
|
||||
* If we want to avoid that, and allow "genl_family.parallel_ops", we may need
|
||||
@@ -210,7 +173,7 @@ static int drbd_adm_prepare(struct drbd_config_context *adm_ctx,
|
||||
}
|
||||
|
||||
adm_ctx->reply_dh = genlmsg_put_reply(adm_ctx->reply_skb,
|
||||
info, &drbd_genl_family, 0, cmd);
|
||||
info, &drbd_nl_family, 0, cmd);
|
||||
/* put of a few bytes into a fresh skb of >= 4k will always succeed.
|
||||
* but anyways */
|
||||
if (!adm_ctx->reply_dh) {
|
||||
@@ -223,9 +186,11 @@ static int drbd_adm_prepare(struct drbd_config_context *adm_ctx,
|
||||
|
||||
adm_ctx->volume = VOLUME_UNSPECIFIED;
|
||||
if (info->attrs[DRBD_NLA_CFG_CONTEXT]) {
|
||||
struct nlattr **ntb;
|
||||
struct nlattr *nla;
|
||||
/* parse and validate only */
|
||||
err = drbd_cfg_context_from_attrs(NULL, info);
|
||||
|
||||
/* parse and validate, get nested attribute table */
|
||||
err = drbd_cfg_context_ntb_from_attrs(&ntb, info);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
@@ -234,18 +199,21 @@ static int drbd_adm_prepare(struct drbd_config_context *adm_ctx,
|
||||
err = nla_put_nohdr(adm_ctx->reply_skb,
|
||||
info->attrs[DRBD_NLA_CFG_CONTEXT]->nla_len,
|
||||
info->attrs[DRBD_NLA_CFG_CONTEXT]);
|
||||
if (err)
|
||||
if (err) {
|
||||
kfree(ntb);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* and assign stuff to the adm_ctx */
|
||||
nla = nested_attr_tb[T_ctx_volume];
|
||||
nla = ntb[DRBD_A_DRBD_CFG_CONTEXT_CTX_VOLUME];
|
||||
if (nla)
|
||||
adm_ctx->volume = nla_get_u32(nla);
|
||||
nla = nested_attr_tb[T_ctx_resource_name];
|
||||
nla = ntb[DRBD_A_DRBD_CFG_CONTEXT_CTX_RESOURCE_NAME];
|
||||
if (nla)
|
||||
adm_ctx->resource_name = nla_data(nla);
|
||||
adm_ctx->my_addr = nested_attr_tb[T_ctx_my_addr];
|
||||
adm_ctx->peer_addr = nested_attr_tb[T_ctx_peer_addr];
|
||||
adm_ctx->my_addr = ntb[DRBD_A_DRBD_CFG_CONTEXT_CTX_MY_ADDR];
|
||||
adm_ctx->peer_addr = ntb[DRBD_A_DRBD_CFG_CONTEXT_CTX_PEER_ADDR];
|
||||
kfree(ntb);
|
||||
if ((adm_ctx->my_addr &&
|
||||
nla_len(adm_ctx->my_addr) > sizeof(adm_ctx->connection->my_addr)) ||
|
||||
(adm_ctx->peer_addr &&
|
||||
@@ -259,7 +227,7 @@ static int drbd_adm_prepare(struct drbd_config_context *adm_ctx,
|
||||
adm_ctx->device = minor_to_device(d_in->minor);
|
||||
|
||||
/* We are protected by the global genl_lock().
|
||||
* But we may explicitly drop it/retake it in drbd_adm_set_role(),
|
||||
* But we may explicitly drop it/retake it in drbd_nl_set_role(),
|
||||
* so make sure this object stays around. */
|
||||
if (adm_ctx->device)
|
||||
kref_get(&adm_ctx->device->kref);
|
||||
@@ -334,8 +302,8 @@ static int drbd_adm_prepare(struct drbd_config_context *adm_ctx,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int drbd_pre_doit(const struct genl_split_ops *ops,
|
||||
struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_pre_doit(const struct genl_split_ops *ops,
|
||||
struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx;
|
||||
u8 cmd = info->genlhdr->cmd;
|
||||
@@ -362,8 +330,8 @@ static int drbd_pre_doit(const struct genl_split_ops *ops,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void drbd_post_doit(const struct genl_split_ops *ops,
|
||||
struct sk_buff *skb, struct genl_info *info)
|
||||
void drbd_post_doit(const struct genl_split_ops *ops,
|
||||
struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
|
||||
@@ -828,7 +796,7 @@ static const char *from_attrs_err_to_txt(int err)
|
||||
"invalid attribute value";
|
||||
}
|
||||
|
||||
int drbd_adm_set_role(struct sk_buff *skb, struct genl_info *info)
|
||||
static int drbd_nl_set_role(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
struct set_role_parms parms;
|
||||
@@ -868,6 +836,16 @@ int drbd_adm_set_role(struct sk_buff *skb, struct genl_info *info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drbd_nl_primary_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
return drbd_nl_set_role(skb, info);
|
||||
}
|
||||
|
||||
int drbd_nl_secondary_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
return drbd_nl_set_role(skb, info);
|
||||
}
|
||||
|
||||
/* Initializes the md.*_offset members, so we are able to find
|
||||
* the on disk meta data.
|
||||
*
|
||||
@@ -962,7 +940,7 @@ char *ppsize(char *buf, unsigned long long size)
|
||||
* peer may not initiate a resize.
|
||||
*/
|
||||
/* Note these are not to be confused with
|
||||
* drbd_adm_suspend_io/drbd_adm_resume_io,
|
||||
* drbd_nl_suspend_io_doit/drbd_nl_resume_io_doit,
|
||||
* which are (sub) state changes triggered by admin (drbdsetup),
|
||||
* and can be long lived.
|
||||
* This changes an device->flag, is triggered by drbd internals,
|
||||
@@ -1574,13 +1552,14 @@ static int disk_opts_check_al_size(struct drbd_device *device, struct disk_conf
|
||||
return err;
|
||||
}
|
||||
|
||||
int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_chg_disk_opts_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
enum drbd_ret_code retcode;
|
||||
struct drbd_device *device;
|
||||
struct disk_conf *new_disk_conf, *old_disk_conf;
|
||||
struct fifo_buffer *old_plan = NULL, *new_plan = NULL;
|
||||
struct nlattr **ntb;
|
||||
int err;
|
||||
unsigned int fifo_size;
|
||||
|
||||
@@ -1612,13 +1591,29 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
|
||||
if (should_set_defaults(info))
|
||||
set_disk_conf_defaults(new_disk_conf);
|
||||
|
||||
err = disk_conf_from_attrs_for_change(new_disk_conf, info);
|
||||
err = disk_conf_from_attrs(new_disk_conf, info);
|
||||
if (err && err != -ENOMSG) {
|
||||
retcode = ERR_MANDATORY_TAG;
|
||||
drbd_msg_put_info(adm_ctx->reply_skb, from_attrs_err_to_txt(err));
|
||||
goto fail_unlock;
|
||||
}
|
||||
|
||||
err = disk_conf_ntb_from_attrs(&ntb, info);
|
||||
if (!err) {
|
||||
if (has_invariant(ntb, DRBD_A_DISK_CONF_BACKING_DEV) ||
|
||||
has_invariant(ntb, DRBD_A_DISK_CONF_META_DEV) ||
|
||||
has_invariant(ntb, DRBD_A_DISK_CONF_META_DEV_IDX) ||
|
||||
has_invariant(ntb, DRBD_A_DISK_CONF_DISK_SIZE) ||
|
||||
has_invariant(ntb, DRBD_A_DISK_CONF_MAX_BIO_BVECS)) {
|
||||
retcode = ERR_MANDATORY_TAG;
|
||||
drbd_msg_put_info(adm_ctx->reply_skb,
|
||||
"cannot change invariant setting");
|
||||
kfree(ntb);
|
||||
goto fail_unlock;
|
||||
}
|
||||
kfree(ntb);
|
||||
}
|
||||
|
||||
if (!expect(device, new_disk_conf->resync_rate >= 1))
|
||||
new_disk_conf->resync_rate = 1;
|
||||
|
||||
@@ -1796,7 +1791,7 @@ void drbd_backing_dev_free(struct drbd_device *device, struct drbd_backing_dev *
|
||||
kfree(ldev);
|
||||
}
|
||||
|
||||
int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_attach_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
struct drbd_device *device;
|
||||
@@ -2236,7 +2231,7 @@ static int adm_detach(struct drbd_device *device, int force)
|
||||
* Then we transition to D_DISKLESS, and wait for put_ldev() to return all
|
||||
* internal references as well.
|
||||
* Only then we have finally detached. */
|
||||
int drbd_adm_detach(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_detach_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
enum drbd_ret_code retcode;
|
||||
@@ -2434,12 +2429,13 @@ static void free_crypto(struct crypto *crypto)
|
||||
crypto_free_shash(crypto->verify_tfm);
|
||||
}
|
||||
|
||||
int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_chg_net_opts_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
enum drbd_ret_code retcode;
|
||||
struct drbd_connection *connection;
|
||||
struct net_conf *old_net_conf, *new_net_conf = NULL;
|
||||
struct nlattr **ntb;
|
||||
int err;
|
||||
int ovr; /* online verify running */
|
||||
int rsr; /* re-sync running */
|
||||
@@ -2476,13 +2472,26 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
|
||||
if (should_set_defaults(info))
|
||||
set_net_conf_defaults(new_net_conf);
|
||||
|
||||
err = net_conf_from_attrs_for_change(new_net_conf, info);
|
||||
err = net_conf_from_attrs(new_net_conf, info);
|
||||
if (err && err != -ENOMSG) {
|
||||
retcode = ERR_MANDATORY_TAG;
|
||||
drbd_msg_put_info(adm_ctx->reply_skb, from_attrs_err_to_txt(err));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
err = net_conf_ntb_from_attrs(&ntb, info);
|
||||
if (!err) {
|
||||
if (has_invariant(ntb, DRBD_A_NET_CONF_DISCARD_MY_DATA) ||
|
||||
has_invariant(ntb, DRBD_A_NET_CONF_TENTATIVE)) {
|
||||
retcode = ERR_MANDATORY_TAG;
|
||||
drbd_msg_put_info(adm_ctx->reply_skb,
|
||||
"cannot change invariant setting");
|
||||
kfree(ntb);
|
||||
goto fail;
|
||||
}
|
||||
kfree(ntb);
|
||||
}
|
||||
|
||||
retcode = check_net_options(connection, new_net_conf);
|
||||
if (retcode != NO_ERROR)
|
||||
goto fail;
|
||||
@@ -2575,7 +2584,7 @@ static void peer_device_to_info(struct peer_device_info *info,
|
||||
info->peer_resync_susp_dependency = device->state.aftr_isp;
|
||||
}
|
||||
|
||||
int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_connect_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct connection_info connection_info;
|
||||
enum drbd_notification_type flags;
|
||||
@@ -2790,7 +2799,7 @@ static enum drbd_state_rv conn_try_disconnect(struct drbd_connection *connection
|
||||
return rv;
|
||||
}
|
||||
|
||||
int drbd_adm_disconnect(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_disconnect_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
struct disconnect_parms parms;
|
||||
@@ -2845,7 +2854,7 @@ void resync_after_online_grow(struct drbd_device *device)
|
||||
_drbd_request_state(device, NS(conn, C_WF_SYNC_UUID), CS_VERBOSE + CS_SERIALIZE);
|
||||
}
|
||||
|
||||
int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_resize_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
struct disk_conf *old_disk_conf, *new_disk_conf = NULL;
|
||||
@@ -2981,7 +2990,7 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_resource_opts_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
enum drbd_ret_code retcode;
|
||||
@@ -3019,7 +3028,7 @@ int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drbd_adm_invalidate(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_invalidate_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
struct drbd_device *device;
|
||||
@@ -3097,7 +3106,7 @@ static int drbd_bmio_set_susp_al(struct drbd_device *device,
|
||||
return rv;
|
||||
}
|
||||
|
||||
int drbd_adm_invalidate_peer(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_inval_peer_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
int retcode; /* drbd_ret_code, drbd_state_rv */
|
||||
@@ -3148,7 +3157,7 @@ int drbd_adm_invalidate_peer(struct sk_buff *skb, struct genl_info *info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drbd_adm_pause_sync(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_pause_sync_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
enum drbd_ret_code retcode;
|
||||
@@ -3168,7 +3177,7 @@ int drbd_adm_pause_sync(struct sk_buff *skb, struct genl_info *info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drbd_adm_resume_sync(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_resume_sync_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
union drbd_dev_state s;
|
||||
@@ -3196,12 +3205,12 @@ int drbd_adm_resume_sync(struct sk_buff *skb, struct genl_info *info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drbd_adm_suspend_io(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_suspend_io_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
return drbd_adm_simple_request_state(skb, info, NS(susp, 1));
|
||||
}
|
||||
|
||||
int drbd_adm_resume_io(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_resume_io_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
struct drbd_device *device;
|
||||
@@ -3257,7 +3266,7 @@ int drbd_adm_resume_io(struct sk_buff *skb, struct genl_info *info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drbd_adm_outdate(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_outdate_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
return drbd_adm_simple_request_state(skb, info, NS(disk, D_OUTDATED));
|
||||
}
|
||||
@@ -3272,16 +3281,20 @@ static int nla_put_drbd_cfg_context(struct sk_buff *skb,
|
||||
if (!nla)
|
||||
goto nla_put_failure;
|
||||
if (device &&
|
||||
nla_put_u32(skb, T_ctx_volume, device->vnr))
|
||||
nla_put_u32(skb, DRBD_A_DRBD_CFG_CONTEXT_CTX_VOLUME, device->vnr))
|
||||
goto nla_put_failure;
|
||||
if (nla_put_string(skb, T_ctx_resource_name, resource->name))
|
||||
if (nla_put_string(skb, DRBD_A_DRBD_CFG_CONTEXT_CTX_RESOURCE_NAME, resource->name))
|
||||
goto nla_put_failure;
|
||||
if (connection) {
|
||||
if (connection->my_addr_len &&
|
||||
nla_put(skb, T_ctx_my_addr, connection->my_addr_len, &connection->my_addr))
|
||||
nla_put(skb, DRBD_A_DRBD_CFG_CONTEXT_CTX_MY_ADDR,
|
||||
connection->my_addr_len,
|
||||
&connection->my_addr))
|
||||
goto nla_put_failure;
|
||||
if (connection->peer_addr_len &&
|
||||
nla_put(skb, T_ctx_peer_addr, connection->peer_addr_len, &connection->peer_addr))
|
||||
nla_put(skb, DRBD_A_DRBD_CFG_CONTEXT_CTX_PEER_ADDR,
|
||||
connection->peer_addr_len,
|
||||
&connection->peer_addr))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
nla_nest_end(skb, nla);
|
||||
@@ -3300,7 +3313,7 @@ static int nla_put_drbd_cfg_context(struct sk_buff *skb,
|
||||
*/
|
||||
static struct nlattr *find_cfg_context_attr(const struct nlmsghdr *nlh, int attr)
|
||||
{
|
||||
const unsigned hdrlen = GENL_HDRLEN + GENL_MAGIC_FAMILY_HDRSZ;
|
||||
const unsigned int hdrlen = GENL_HDRLEN + sizeof(struct drbd_genlmsghdr);
|
||||
struct nlattr *nla;
|
||||
|
||||
nla = nla_find(nlmsg_attrdata(nlh, hdrlen), nlmsg_attrlen(nlh, hdrlen),
|
||||
@@ -3312,7 +3325,7 @@ static struct nlattr *find_cfg_context_attr(const struct nlmsghdr *nlh, int attr
|
||||
|
||||
static void resource_to_info(struct resource_info *, struct drbd_resource *);
|
||||
|
||||
int drbd_adm_dump_resources(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
int drbd_nl_get_resources_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
{
|
||||
struct drbd_genlmsghdr *dh;
|
||||
struct drbd_resource *resource;
|
||||
@@ -3340,7 +3353,7 @@ int drbd_adm_dump_resources(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
|
||||
put_result:
|
||||
dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq, &drbd_genl_family,
|
||||
cb->nlh->nlmsg_seq, &drbd_nl_family,
|
||||
NLM_F_MULTI, DRBD_ADM_GET_RESOURCES);
|
||||
err = -ENOMEM;
|
||||
if (!dh)
|
||||
@@ -3350,15 +3363,15 @@ int drbd_adm_dump_resources(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
err = nla_put_drbd_cfg_context(skb, resource, NULL, NULL);
|
||||
if (err)
|
||||
goto out;
|
||||
err = res_opts_to_skb(skb, &resource->res_opts, !capable(CAP_SYS_ADMIN));
|
||||
err = res_opts_to_skb(skb, &resource->res_opts);
|
||||
if (err)
|
||||
goto out;
|
||||
resource_to_info(&resource_info, resource);
|
||||
err = resource_info_to_skb(skb, &resource_info, !capable(CAP_SYS_ADMIN));
|
||||
err = resource_info_to_skb(skb, &resource_info);
|
||||
if (err)
|
||||
goto out;
|
||||
resource_statistics.res_stat_write_ordering = resource->write_ordering;
|
||||
err = resource_statistics_to_skb(skb, &resource_statistics, !capable(CAP_SYS_ADMIN));
|
||||
err = resource_statistics_to_skb(skb, &resource_statistics);
|
||||
if (err)
|
||||
goto out;
|
||||
cb->args[0] = (long)resource;
|
||||
@@ -3423,7 +3436,7 @@ int drbd_adm_dump_devices_done(struct netlink_callback *cb) {
|
||||
|
||||
static void device_to_info(struct device_info *, struct drbd_device *);
|
||||
|
||||
int drbd_adm_dump_devices(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
int drbd_nl_get_devices_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
{
|
||||
struct nlattr *resource_filter;
|
||||
struct drbd_resource *resource;
|
||||
@@ -3436,7 +3449,8 @@ int drbd_adm_dump_devices(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
|
||||
resource = (struct drbd_resource *)cb->args[0];
|
||||
if (!cb->args[0] && !cb->args[1]) {
|
||||
resource_filter = find_cfg_context_attr(cb->nlh, T_ctx_resource_name);
|
||||
resource_filter = find_cfg_context_attr(cb->nlh,
|
||||
DRBD_A_DRBD_CFG_CONTEXT_CTX_RESOURCE_NAME);
|
||||
if (resource_filter) {
|
||||
retcode = ERR_RES_NOT_KNOWN;
|
||||
resource = drbd_find_resource(nla_data(resource_filter));
|
||||
@@ -3465,7 +3479,7 @@ int drbd_adm_dump_devices(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
|
||||
put_result:
|
||||
dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq, &drbd_genl_family,
|
||||
cb->nlh->nlmsg_seq, &drbd_nl_family,
|
||||
NLM_F_MULTI, DRBD_ADM_GET_DEVICES);
|
||||
err = -ENOMEM;
|
||||
if (!dh)
|
||||
@@ -3481,18 +3495,18 @@ int drbd_adm_dump_devices(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
struct disk_conf *disk_conf =
|
||||
rcu_dereference(device->ldev->disk_conf);
|
||||
|
||||
err = disk_conf_to_skb(skb, disk_conf, !capable(CAP_SYS_ADMIN));
|
||||
err = disk_conf_to_skb(skb, disk_conf);
|
||||
put_ldev(device);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
device_to_info(&device_info, device);
|
||||
err = device_info_to_skb(skb, &device_info, !capable(CAP_SYS_ADMIN));
|
||||
err = device_info_to_skb(skb, &device_info);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
device_to_statistics(&device_statistics, device);
|
||||
err = device_statistics_to_skb(skb, &device_statistics, !capable(CAP_SYS_ADMIN));
|
||||
err = device_statistics_to_skb(skb, &device_statistics);
|
||||
if (err)
|
||||
goto out;
|
||||
cb->args[1] = minor + 1;
|
||||
@@ -3514,7 +3528,7 @@ int drbd_adm_dump_connections_done(struct netlink_callback *cb)
|
||||
|
||||
enum { SINGLE_RESOURCE, ITERATE_RESOURCES };
|
||||
|
||||
int drbd_adm_dump_connections(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
int drbd_nl_get_connections_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
{
|
||||
struct nlattr *resource_filter;
|
||||
struct drbd_resource *resource = NULL, *next_resource;
|
||||
@@ -3527,7 +3541,8 @@ int drbd_adm_dump_connections(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
rcu_read_lock();
|
||||
resource = (struct drbd_resource *)cb->args[0];
|
||||
if (!cb->args[0]) {
|
||||
resource_filter = find_cfg_context_attr(cb->nlh, T_ctx_resource_name);
|
||||
resource_filter = find_cfg_context_attr(cb->nlh,
|
||||
DRBD_A_DRBD_CFG_CONTEXT_CTX_RESOURCE_NAME);
|
||||
if (resource_filter) {
|
||||
retcode = ERR_RES_NOT_KNOWN;
|
||||
resource = drbd_find_resource(nla_data(resource_filter));
|
||||
@@ -3591,7 +3606,7 @@ int drbd_adm_dump_connections(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
|
||||
put_result:
|
||||
dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq, &drbd_genl_family,
|
||||
cb->nlh->nlmsg_seq, &drbd_nl_family,
|
||||
NLM_F_MULTI, DRBD_ADM_GET_CONNECTIONS);
|
||||
err = -ENOMEM;
|
||||
if (!dh)
|
||||
@@ -3606,16 +3621,16 @@ int drbd_adm_dump_connections(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
goto out;
|
||||
net_conf = rcu_dereference(connection->net_conf);
|
||||
if (net_conf) {
|
||||
err = net_conf_to_skb(skb, net_conf, !capable(CAP_SYS_ADMIN));
|
||||
err = net_conf_to_skb(skb, net_conf);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
connection_to_info(&connection_info, connection);
|
||||
err = connection_info_to_skb(skb, &connection_info, !capable(CAP_SYS_ADMIN));
|
||||
err = connection_info_to_skb(skb, &connection_info);
|
||||
if (err)
|
||||
goto out;
|
||||
connection_statistics.conn_congested = test_bit(NET_CONGESTED, &connection->flags);
|
||||
err = connection_statistics_to_skb(skb, &connection_statistics, !capable(CAP_SYS_ADMIN));
|
||||
err = connection_statistics_to_skb(skb, &connection_statistics);
|
||||
if (err)
|
||||
goto out;
|
||||
cb->args[2] = (long)connection;
|
||||
@@ -3676,7 +3691,7 @@ int drbd_adm_dump_peer_devices_done(struct netlink_callback *cb)
|
||||
return put_resource_in_arg0(cb, 9);
|
||||
}
|
||||
|
||||
int drbd_adm_dump_peer_devices(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
int drbd_nl_get_peer_devices_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
{
|
||||
struct nlattr *resource_filter;
|
||||
struct drbd_resource *resource;
|
||||
@@ -3688,7 +3703,8 @@ int drbd_adm_dump_peer_devices(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
|
||||
resource = (struct drbd_resource *)cb->args[0];
|
||||
if (!cb->args[0] && !cb->args[1]) {
|
||||
resource_filter = find_cfg_context_attr(cb->nlh, T_ctx_resource_name);
|
||||
resource_filter = find_cfg_context_attr(cb->nlh,
|
||||
DRBD_A_DRBD_CFG_CONTEXT_CTX_RESOURCE_NAME);
|
||||
if (resource_filter) {
|
||||
retcode = ERR_RES_NOT_KNOWN;
|
||||
resource = drbd_find_resource(nla_data(resource_filter));
|
||||
@@ -3735,7 +3751,7 @@ int drbd_adm_dump_peer_devices(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
|
||||
put_result:
|
||||
dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq, &drbd_genl_family,
|
||||
cb->nlh->nlmsg_seq, &drbd_nl_family,
|
||||
NLM_F_MULTI, DRBD_ADM_GET_PEER_DEVICES);
|
||||
err = -ENOMEM;
|
||||
if (!dh)
|
||||
@@ -3751,11 +3767,11 @@ int drbd_adm_dump_peer_devices(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
if (err)
|
||||
goto out;
|
||||
peer_device_to_info(&peer_device_info, peer_device);
|
||||
err = peer_device_info_to_skb(skb, &peer_device_info, !capable(CAP_SYS_ADMIN));
|
||||
err = peer_device_info_to_skb(skb, &peer_device_info);
|
||||
if (err)
|
||||
goto out;
|
||||
peer_device_to_statistics(&peer_device_statistics, peer_device);
|
||||
err = peer_device_statistics_to_skb(skb, &peer_device_statistics, !capable(CAP_SYS_ADMIN));
|
||||
err = peer_device_statistics_to_skb(skb, &peer_device_statistics);
|
||||
if (err)
|
||||
goto out;
|
||||
cb->args[1] = minor;
|
||||
@@ -3795,11 +3811,11 @@ static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device,
|
||||
/* If sib != NULL, this is drbd_bcast_event, which anyone can listen
|
||||
* to. So we better exclude_sensitive information.
|
||||
*
|
||||
* If sib == NULL, this is drbd_adm_get_status, executed synchronously
|
||||
* If sib == NULL, this is drbd_nl_get_status_doit, executed synchronously
|
||||
* in the context of the requesting user process. Exclude sensitive
|
||||
* information, unless current has superuser.
|
||||
*
|
||||
* NOTE: for drbd_adm_get_status_all(), this is a netlink dump, and
|
||||
* NOTE: for drbd_nl_get_status_dumpit(), this is a netlink dump, and
|
||||
* relies on the current implementation of netlink_dump(), which
|
||||
* executes the dump callback successively from netlink_recvmsg(),
|
||||
* always in the context of the receiving process */
|
||||
@@ -3812,7 +3828,7 @@ static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device,
|
||||
if (nla_put_drbd_cfg_context(skb, resource, the_only_connection(resource), device))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (res_opts_to_skb(skb, &device->resource->res_opts, exclude_sensitive))
|
||||
if (res_opts_to_skb(skb, &device->resource->res_opts))
|
||||
goto nla_put_failure;
|
||||
|
||||
rcu_read_lock();
|
||||
@@ -3820,14 +3836,24 @@ static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device,
|
||||
struct disk_conf *disk_conf;
|
||||
|
||||
disk_conf = rcu_dereference(device->ldev->disk_conf);
|
||||
err = disk_conf_to_skb(skb, disk_conf, exclude_sensitive);
|
||||
err = disk_conf_to_skb(skb, disk_conf);
|
||||
}
|
||||
if (!err) {
|
||||
struct net_conf *nc;
|
||||
|
||||
nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
|
||||
if (nc)
|
||||
err = net_conf_to_skb(skb, nc, exclude_sensitive);
|
||||
if (nc) {
|
||||
if (exclude_sensitive) {
|
||||
struct net_conf nc_clean = *nc;
|
||||
|
||||
memset(nc_clean.shared_secret, 0,
|
||||
sizeof(nc_clean.shared_secret));
|
||||
nc_clean.shared_secret_len = 0;
|
||||
err = net_conf_to_skb(skb, &nc_clean);
|
||||
} else {
|
||||
err = net_conf_to_skb(skb, nc);
|
||||
}
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
if (err)
|
||||
@@ -3836,42 +3862,57 @@ static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device,
|
||||
nla = nla_nest_start_noflag(skb, DRBD_NLA_STATE_INFO);
|
||||
if (!nla)
|
||||
goto nla_put_failure;
|
||||
if (nla_put_u32(skb, T_sib_reason, sib ? sib->sib_reason : SIB_GET_STATUS_REPLY) ||
|
||||
nla_put_u32(skb, T_current_state, device->state.i) ||
|
||||
nla_put_u64_0pad(skb, T_ed_uuid, device->ed_uuid) ||
|
||||
nla_put_u64_0pad(skb, T_capacity, get_capacity(device->vdisk)) ||
|
||||
nla_put_u64_0pad(skb, T_send_cnt, device->send_cnt) ||
|
||||
nla_put_u64_0pad(skb, T_recv_cnt, device->recv_cnt) ||
|
||||
nla_put_u64_0pad(skb, T_read_cnt, device->read_cnt) ||
|
||||
nla_put_u64_0pad(skb, T_writ_cnt, device->writ_cnt) ||
|
||||
nla_put_u64_0pad(skb, T_al_writ_cnt, device->al_writ_cnt) ||
|
||||
nla_put_u64_0pad(skb, T_bm_writ_cnt, device->bm_writ_cnt) ||
|
||||
nla_put_u32(skb, T_ap_bio_cnt, atomic_read(&device->ap_bio_cnt)) ||
|
||||
nla_put_u32(skb, T_ap_pending_cnt, atomic_read(&device->ap_pending_cnt)) ||
|
||||
nla_put_u32(skb, T_rs_pending_cnt, atomic_read(&device->rs_pending_cnt)))
|
||||
if (nla_put_u32(skb, DRBD_A_STATE_INFO_SIB_REASON,
|
||||
sib ? sib->sib_reason : SIB_GET_STATUS_REPLY) ||
|
||||
nla_put_u32(skb, DRBD_A_STATE_INFO_CURRENT_STATE,
|
||||
device->state.i) ||
|
||||
nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_ED_UUID,
|
||||
device->ed_uuid, 0) ||
|
||||
nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_CAPACITY,
|
||||
get_capacity(device->vdisk), 0) ||
|
||||
nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_SEND_CNT,
|
||||
device->send_cnt, 0) ||
|
||||
nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_RECV_CNT,
|
||||
device->recv_cnt, 0) ||
|
||||
nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_READ_CNT,
|
||||
device->read_cnt, 0) ||
|
||||
nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_WRIT_CNT,
|
||||
device->writ_cnt, 0) ||
|
||||
nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_AL_WRIT_CNT,
|
||||
device->al_writ_cnt, 0) ||
|
||||
nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_BM_WRIT_CNT,
|
||||
device->bm_writ_cnt, 0) ||
|
||||
nla_put_u32(skb, DRBD_A_STATE_INFO_AP_BIO_CNT,
|
||||
atomic_read(&device->ap_bio_cnt)) ||
|
||||
nla_put_u32(skb, DRBD_A_STATE_INFO_AP_PENDING_CNT,
|
||||
atomic_read(&device->ap_pending_cnt)) ||
|
||||
nla_put_u32(skb, DRBD_A_STATE_INFO_RS_PENDING_CNT,
|
||||
atomic_read(&device->rs_pending_cnt)))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (got_ldev) {
|
||||
int err;
|
||||
|
||||
spin_lock_irq(&device->ldev->md.uuid_lock);
|
||||
err = nla_put(skb, T_uuids, sizeof(si->uuids), device->ldev->md.uuid);
|
||||
err = nla_put(skb, DRBD_A_STATE_INFO_UUIDS,
|
||||
sizeof(si->uuids),
|
||||
device->ldev->md.uuid);
|
||||
spin_unlock_irq(&device->ldev->md.uuid_lock);
|
||||
|
||||
if (err)
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nla_put_u32(skb, T_disk_flags, device->ldev->md.flags) ||
|
||||
nla_put_u64_0pad(skb, T_bits_total, drbd_bm_bits(device)) ||
|
||||
nla_put_u64_0pad(skb, T_bits_oos,
|
||||
drbd_bm_total_weight(device)))
|
||||
if (nla_put_u32(skb, DRBD_A_STATE_INFO_DISK_FLAGS, device->ldev->md.flags) ||
|
||||
nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_BITS_TOTAL, drbd_bm_bits(device), 0) ||
|
||||
nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_BITS_OOS,
|
||||
drbd_bm_total_weight(device), 0))
|
||||
goto nla_put_failure;
|
||||
if (C_SYNC_SOURCE <= device->state.conn &&
|
||||
C_PAUSED_SYNC_T >= device->state.conn) {
|
||||
if (nla_put_u64_0pad(skb, T_bits_rs_total,
|
||||
device->rs_total) ||
|
||||
nla_put_u64_0pad(skb, T_bits_rs_failed,
|
||||
device->rs_failed))
|
||||
if (nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_BITS_RS_TOTAL,
|
||||
device->rs_total, 0) ||
|
||||
nla_put_u64_64bit(skb, DRBD_A_STATE_INFO_BITS_RS_FAILED,
|
||||
device->rs_failed, 0))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
}
|
||||
@@ -3882,17 +3923,17 @@ static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device,
|
||||
case SIB_GET_STATUS_REPLY:
|
||||
break;
|
||||
case SIB_STATE_CHANGE:
|
||||
if (nla_put_u32(skb, T_prev_state, sib->os.i) ||
|
||||
nla_put_u32(skb, T_new_state, sib->ns.i))
|
||||
if (nla_put_u32(skb, DRBD_A_STATE_INFO_PREV_STATE, sib->os.i) ||
|
||||
nla_put_u32(skb, DRBD_A_STATE_INFO_NEW_STATE, sib->ns.i))
|
||||
goto nla_put_failure;
|
||||
break;
|
||||
case SIB_HELPER_POST:
|
||||
if (nla_put_u32(skb, T_helper_exit_code,
|
||||
if (nla_put_u32(skb, DRBD_A_STATE_INFO_HELPER_EXIT_CODE,
|
||||
sib->helper_exit_code))
|
||||
goto nla_put_failure;
|
||||
fallthrough;
|
||||
case SIB_HELPER_PRE:
|
||||
if (nla_put_string(skb, T_helper, sib->helper_name))
|
||||
if (nla_put_string(skb, DRBD_A_STATE_INFO_HELPER, sib->helper_name))
|
||||
goto nla_put_failure;
|
||||
break;
|
||||
}
|
||||
@@ -3907,7 +3948,7 @@ static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device,
|
||||
return err;
|
||||
}
|
||||
|
||||
int drbd_adm_get_status(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_get_status_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
enum drbd_ret_code retcode;
|
||||
@@ -3997,7 +4038,7 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
}
|
||||
|
||||
dh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq, &drbd_genl_family,
|
||||
cb->nlh->nlmsg_seq, &drbd_nl_family,
|
||||
NLM_F_MULTI, DRBD_ADM_GET_STATUS);
|
||||
if (!dh)
|
||||
goto out;
|
||||
@@ -4017,7 +4058,7 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
struct net_conf *nc;
|
||||
|
||||
nc = rcu_dereference(connection->net_conf);
|
||||
if (nc && net_conf_to_skb(skb, nc, 1) != 0)
|
||||
if (nc && net_conf_to_skb(skb, nc) != 0)
|
||||
goto cancel;
|
||||
}
|
||||
goto done;
|
||||
@@ -4059,9 +4100,9 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
*
|
||||
* Once things are setup properly, we call into get_one_status().
|
||||
*/
|
||||
int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
int drbd_nl_get_status_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
{
|
||||
const unsigned hdrlen = GENL_HDRLEN + GENL_MAGIC_FAMILY_HDRSZ;
|
||||
const unsigned int hdrlen = GENL_HDRLEN + sizeof(struct drbd_genlmsghdr);
|
||||
struct nlattr *nla;
|
||||
const char *resource_name;
|
||||
struct drbd_resource *resource;
|
||||
@@ -4084,7 +4125,7 @@ int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
/* No explicit context given. Dump all. */
|
||||
if (!nla)
|
||||
goto dump;
|
||||
nla = nla_find_nested(nla, T_ctx_resource_name);
|
||||
nla = nla_find_nested(nla, DRBD_A_DRBD_CFG_CONTEXT_CTX_RESOURCE_NAME);
|
||||
/* context given, but no name present? */
|
||||
if (!nla)
|
||||
return -EINVAL;
|
||||
@@ -4107,7 +4148,7 @@ int drbd_adm_get_status_all(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
return get_one_status(skb, cb);
|
||||
}
|
||||
|
||||
int drbd_adm_get_timeout_type(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_get_timeout_type_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
enum drbd_ret_code retcode;
|
||||
@@ -4125,7 +4166,7 @@ int drbd_adm_get_timeout_type(struct sk_buff *skb, struct genl_info *info)
|
||||
test_bit(USE_DEGR_WFC_T, &adm_ctx->device->flags) ? UT_DEGRADED :
|
||||
UT_DEFAULT;
|
||||
|
||||
err = timeout_parms_to_priv_skb(adm_ctx->reply_skb, &tp);
|
||||
err = timeout_parms_to_skb(adm_ctx->reply_skb, &tp);
|
||||
if (err) {
|
||||
nlmsg_free(adm_ctx->reply_skb);
|
||||
adm_ctx->reply_skb = NULL;
|
||||
@@ -4136,7 +4177,7 @@ int drbd_adm_get_timeout_type(struct sk_buff *skb, struct genl_info *info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drbd_adm_start_ov(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_start_ov_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
struct drbd_device *device;
|
||||
@@ -4182,7 +4223,7 @@ int drbd_adm_start_ov(struct sk_buff *skb, struct genl_info *info)
|
||||
}
|
||||
|
||||
|
||||
int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_new_c_uuid_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
struct drbd_device *device;
|
||||
@@ -4285,7 +4326,7 @@ static void resource_to_info(struct resource_info *info,
|
||||
info->res_susp_fen = resource->susp_fen;
|
||||
}
|
||||
|
||||
int drbd_adm_new_resource(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_new_resource_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_connection *connection;
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
@@ -4348,7 +4389,7 @@ static void device_to_info(struct device_info *info,
|
||||
}
|
||||
|
||||
|
||||
int drbd_adm_new_minor(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_new_minor_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
struct drbd_genlmsghdr *dh = genl_info_userhdr(info);
|
||||
@@ -4455,7 +4496,7 @@ static enum drbd_ret_code adm_del_minor(struct drbd_device *device)
|
||||
return ERR_MINOR_CONFIGURED;
|
||||
}
|
||||
|
||||
int drbd_adm_del_minor(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_del_minor_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
enum drbd_ret_code retcode;
|
||||
@@ -4504,7 +4545,7 @@ static int adm_del_resource(struct drbd_resource *resource)
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_down_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
struct drbd_resource *resource;
|
||||
@@ -4567,7 +4608,7 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drbd_adm_del_resource(struct sk_buff *skb, struct genl_info *info)
|
||||
int drbd_nl_del_resource_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct drbd_config_context *adm_ctx = info->user_ptr[0];
|
||||
struct drbd_resource *resource;
|
||||
@@ -4601,7 +4642,7 @@ void drbd_bcast_event(struct drbd_device *device, const struct sib_info *sib)
|
||||
goto failed;
|
||||
|
||||
err = -EMSGSIZE;
|
||||
d_out = genlmsg_put(msg, 0, seq, &drbd_genl_family, 0, DRBD_EVENT);
|
||||
d_out = genlmsg_put(msg, 0, seq, &drbd_nl_family, 0, DRBD_ADM_EVENT);
|
||||
if (!d_out) /* cannot happen, but anyways. */
|
||||
goto nla_put_failure;
|
||||
d_out->minor = device_to_minor(device);
|
||||
@@ -4632,7 +4673,7 @@ static int nla_put_notification_header(struct sk_buff *msg,
|
||||
.nh_type = type,
|
||||
};
|
||||
|
||||
return drbd_notification_header_to_skb(msg, &nh, true);
|
||||
return drbd_notification_header_to_skb(msg, &nh);
|
||||
}
|
||||
|
||||
int notify_resource_state(struct sk_buff *skb,
|
||||
@@ -4656,7 +4697,7 @@ int notify_resource_state(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
err = -EMSGSIZE;
|
||||
dh = genlmsg_put(skb, 0, seq, &drbd_genl_family, 0, DRBD_RESOURCE_STATE);
|
||||
dh = genlmsg_put(skb, 0, seq, &drbd_nl_family, 0, DRBD_ADM_RESOURCE_STATE);
|
||||
if (!dh)
|
||||
goto nla_put_failure;
|
||||
dh->minor = -1U;
|
||||
@@ -4664,10 +4705,10 @@ int notify_resource_state(struct sk_buff *skb,
|
||||
if (nla_put_drbd_cfg_context(skb, resource, NULL, NULL) ||
|
||||
nla_put_notification_header(skb, type) ||
|
||||
((type & ~NOTIFY_FLAGS) != NOTIFY_DESTROY &&
|
||||
resource_info_to_skb(skb, resource_info, true)))
|
||||
resource_info_to_skb(skb, resource_info)))
|
||||
goto nla_put_failure;
|
||||
resource_statistics.res_stat_write_ordering = resource->write_ordering;
|
||||
err = resource_statistics_to_skb(skb, &resource_statistics, !capable(CAP_SYS_ADMIN));
|
||||
err = resource_statistics_to_skb(skb, &resource_statistics);
|
||||
if (err)
|
||||
goto nla_put_failure;
|
||||
genlmsg_end(skb, dh);
|
||||
@@ -4708,7 +4749,7 @@ int notify_device_state(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
err = -EMSGSIZE;
|
||||
dh = genlmsg_put(skb, 0, seq, &drbd_genl_family, 0, DRBD_DEVICE_STATE);
|
||||
dh = genlmsg_put(skb, 0, seq, &drbd_nl_family, 0, DRBD_ADM_DEVICE_STATE);
|
||||
if (!dh)
|
||||
goto nla_put_failure;
|
||||
dh->minor = device->minor;
|
||||
@@ -4716,10 +4757,10 @@ int notify_device_state(struct sk_buff *skb,
|
||||
if (nla_put_drbd_cfg_context(skb, device->resource, NULL, device) ||
|
||||
nla_put_notification_header(skb, type) ||
|
||||
((type & ~NOTIFY_FLAGS) != NOTIFY_DESTROY &&
|
||||
device_info_to_skb(skb, device_info, true)))
|
||||
device_info_to_skb(skb, device_info)))
|
||||
goto nla_put_failure;
|
||||
device_to_statistics(&device_statistics, device);
|
||||
device_statistics_to_skb(skb, &device_statistics, !capable(CAP_SYS_ADMIN));
|
||||
device_statistics_to_skb(skb, &device_statistics);
|
||||
genlmsg_end(skb, dh);
|
||||
if (multicast) {
|
||||
err = drbd_genl_multicast_events(skb, GFP_NOWAIT);
|
||||
@@ -4758,7 +4799,7 @@ int notify_connection_state(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
err = -EMSGSIZE;
|
||||
dh = genlmsg_put(skb, 0, seq, &drbd_genl_family, 0, DRBD_CONNECTION_STATE);
|
||||
dh = genlmsg_put(skb, 0, seq, &drbd_nl_family, 0, DRBD_ADM_CONNECTION_STATE);
|
||||
if (!dh)
|
||||
goto nla_put_failure;
|
||||
dh->minor = -1U;
|
||||
@@ -4766,10 +4807,10 @@ int notify_connection_state(struct sk_buff *skb,
|
||||
if (nla_put_drbd_cfg_context(skb, connection->resource, connection, NULL) ||
|
||||
nla_put_notification_header(skb, type) ||
|
||||
((type & ~NOTIFY_FLAGS) != NOTIFY_DESTROY &&
|
||||
connection_info_to_skb(skb, connection_info, true)))
|
||||
connection_info_to_skb(skb, connection_info)))
|
||||
goto nla_put_failure;
|
||||
connection_statistics.conn_congested = test_bit(NET_CONGESTED, &connection->flags);
|
||||
connection_statistics_to_skb(skb, &connection_statistics, !capable(CAP_SYS_ADMIN));
|
||||
connection_statistics_to_skb(skb, &connection_statistics);
|
||||
genlmsg_end(skb, dh);
|
||||
if (multicast) {
|
||||
err = drbd_genl_multicast_events(skb, GFP_NOWAIT);
|
||||
@@ -4809,7 +4850,7 @@ int notify_peer_device_state(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
err = -EMSGSIZE;
|
||||
dh = genlmsg_put(skb, 0, seq, &drbd_genl_family, 0, DRBD_PEER_DEVICE_STATE);
|
||||
dh = genlmsg_put(skb, 0, seq, &drbd_nl_family, 0, DRBD_ADM_PEER_DEVICE_STATE);
|
||||
if (!dh)
|
||||
goto nla_put_failure;
|
||||
dh->minor = -1U;
|
||||
@@ -4817,10 +4858,10 @@ int notify_peer_device_state(struct sk_buff *skb,
|
||||
if (nla_put_drbd_cfg_context(skb, resource, peer_device->connection, peer_device->device) ||
|
||||
nla_put_notification_header(skb, type) ||
|
||||
((type & ~NOTIFY_FLAGS) != NOTIFY_DESTROY &&
|
||||
peer_device_info_to_skb(skb, peer_device_info, true)))
|
||||
peer_device_info_to_skb(skb, peer_device_info)))
|
||||
goto nla_put_failure;
|
||||
peer_device_to_statistics(&peer_device_statistics, peer_device);
|
||||
peer_device_statistics_to_skb(skb, &peer_device_statistics, !capable(CAP_SYS_ADMIN));
|
||||
peer_device_statistics_to_skb(skb, &peer_device_statistics);
|
||||
genlmsg_end(skb, dh);
|
||||
if (multicast) {
|
||||
err = drbd_genl_multicast_events(skb, GFP_NOWAIT);
|
||||
@@ -4859,7 +4900,7 @@ void notify_helper(enum drbd_notification_type type,
|
||||
goto fail;
|
||||
|
||||
err = -EMSGSIZE;
|
||||
dh = genlmsg_put(skb, 0, seq, &drbd_genl_family, 0, DRBD_HELPER);
|
||||
dh = genlmsg_put(skb, 0, seq, &drbd_nl_family, 0, DRBD_ADM_HELPER);
|
||||
if (!dh)
|
||||
goto fail;
|
||||
dh->minor = device ? device->minor : -1;
|
||||
@@ -4867,7 +4908,7 @@ void notify_helper(enum drbd_notification_type type,
|
||||
mutex_lock(¬ification_mutex);
|
||||
if (nla_put_drbd_cfg_context(skb, resource, connection, device) ||
|
||||
nla_put_notification_header(skb, type) ||
|
||||
drbd_helper_info_to_skb(skb, &helper_info, true))
|
||||
drbd_helper_info_to_skb(skb, &helper_info))
|
||||
goto unlock_fail;
|
||||
genlmsg_end(skb, dh);
|
||||
err = drbd_genl_multicast_events(skb, GFP_NOWAIT);
|
||||
@@ -4892,7 +4933,7 @@ static int notify_initial_state_done(struct sk_buff *skb, unsigned int seq)
|
||||
int err;
|
||||
|
||||
err = -EMSGSIZE;
|
||||
dh = genlmsg_put(skb, 0, seq, &drbd_genl_family, 0, DRBD_INITIAL_STATE_DONE);
|
||||
dh = genlmsg_put(skb, 0, seq, &drbd_nl_family, 0, DRBD_ADM_INITIAL_STATE_DONE);
|
||||
if (!dh)
|
||||
goto nla_put_failure;
|
||||
dh->minor = -1U;
|
||||
@@ -4987,7 +5028,7 @@ static int get_initial_state(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
return skb->len;
|
||||
}
|
||||
|
||||
int drbd_adm_get_initial_state(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
int drbd_nl_get_initial_state_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
{
|
||||
struct drbd_resource *resource;
|
||||
LIST_HEAD(head);
|
||||
@@ -5035,3 +5076,20 @@ int drbd_adm_get_initial_state(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
cb->args[2] = cb->nlh->nlmsg_seq;
|
||||
return get_initial_state(skb, cb);
|
||||
}
|
||||
|
||||
static const struct genl_multicast_group drbd_nl_mcgrps[] = {
|
||||
[DRBD_NLGRP_EVENTS] = { .name = "events", },
|
||||
};
|
||||
|
||||
struct genl_family drbd_nl_family __ro_after_init = {
|
||||
.name = "drbd",
|
||||
.version = DRBD_FAMILY_VERSION,
|
||||
.hdrsize = NLA_ALIGN(sizeof(struct drbd_genlmsghdr)),
|
||||
.split_ops = drbd_nl_ops,
|
||||
.n_split_ops = ARRAY_SIZE(drbd_nl_ops),
|
||||
.mcgrps = drbd_nl_mcgrps,
|
||||
.n_mcgrps = ARRAY_SIZE(drbd_nl_mcgrps),
|
||||
.resv_start_op = 42,
|
||||
.module = THIS_MODULE,
|
||||
.netnsok = true,
|
||||
};
|
||||
|
||||
2606
drivers/block/drbd/drbd_nl_gen.c
Normal file
2606
drivers/block/drbd/drbd_nl_gen.c
Normal file
File diff suppressed because it is too large
Load Diff
395
drivers/block/drbd/drbd_nl_gen.h
Normal file
395
drivers/block/drbd/drbd_nl_gen.h
Normal file
@@ -0,0 +1,395 @@
|
||||
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
|
||||
|
||||
#ifndef _LINUX_DRBD_GEN_H
|
||||
#define _LINUX_DRBD_GEN_H
|
||||
|
||||
#include <net/netlink.h>
|
||||
#include <net/genetlink.h>
|
||||
|
||||
#include <uapi/linux/drbd_genl.h>
|
||||
#include <linux/drbd.h>
|
||||
#include <linux/drbd_limits.h>
|
||||
|
||||
/* Common nested types */
|
||||
extern const struct nla_policy drbd_connection_info_nl_policy[DRBD_A_CONNECTION_INFO_CONN_ROLE + 1];
|
||||
extern const struct nla_policy drbd_connection_statistics_nl_policy[DRBD_A_CONNECTION_STATISTICS_CONN_CONGESTED + 1];
|
||||
extern const struct nla_policy drbd_detach_parms_nl_policy[DRBD_A_DETACH_PARMS_FORCE_DETACH + 1];
|
||||
extern const struct nla_policy drbd_device_info_nl_policy[DRBD_A_DEVICE_INFO_DEV_DISK_STATE + 1];
|
||||
extern const struct nla_policy drbd_device_statistics_nl_policy[DRBD_A_DEVICE_STATISTICS_HISTORY_UUIDS + 1];
|
||||
extern const struct nla_policy drbd_disconnect_parms_nl_policy[DRBD_A_DISCONNECT_PARMS_FORCE_DISCONNECT + 1];
|
||||
extern const struct nla_policy drbd_disk_conf_nl_policy[DRBD_A_DISK_CONF_DISABLE_WRITE_SAME + 1];
|
||||
extern const struct nla_policy drbd_drbd_cfg_context_nl_policy[DRBD_A_DRBD_CFG_CONTEXT_CTX_PEER_ADDR + 1];
|
||||
extern const struct nla_policy drbd_net_conf_nl_policy[DRBD_A_NET_CONF_SOCK_CHECK_TIMEO + 1];
|
||||
extern const struct nla_policy drbd_new_c_uuid_parms_nl_policy[DRBD_A_NEW_C_UUID_PARMS_CLEAR_BM + 1];
|
||||
extern const struct nla_policy drbd_peer_device_info_nl_policy[DRBD_A_PEER_DEVICE_INFO_PEER_RESYNC_SUSP_DEPENDENCY + 1];
|
||||
extern const struct nla_policy drbd_peer_device_statistics_nl_policy[DRBD_A_PEER_DEVICE_STATISTICS_PEER_DEV_FLAGS + 1];
|
||||
extern const struct nla_policy drbd_res_opts_nl_policy[DRBD_A_RES_OPTS_ON_NO_DATA + 1];
|
||||
extern const struct nla_policy drbd_resize_parms_nl_policy[DRBD_A_RESIZE_PARMS_AL_STRIPE_SIZE + 1];
|
||||
extern const struct nla_policy drbd_resource_info_nl_policy[DRBD_A_RESOURCE_INFO_RES_SUSP_FEN + 1];
|
||||
extern const struct nla_policy drbd_resource_statistics_nl_policy[DRBD_A_RESOURCE_STATISTICS_RES_STAT_WRITE_ORDERING + 1];
|
||||
extern const struct nla_policy drbd_set_role_parms_nl_policy[DRBD_A_SET_ROLE_PARMS_ASSUME_UPTODATE + 1];
|
||||
extern const struct nla_policy drbd_start_ov_parms_nl_policy[DRBD_A_START_OV_PARMS_OV_STOP_SECTOR + 1];
|
||||
|
||||
/* Ops table for drbd */
|
||||
extern const struct genl_split_ops drbd_nl_ops[32];
|
||||
|
||||
int drbd_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
|
||||
struct genl_info *info);
|
||||
void
|
||||
drbd_post_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
|
||||
struct genl_info *info);
|
||||
int drbd_adm_dump_devices_done(struct netlink_callback *cb);
|
||||
int drbd_adm_dump_connections_done(struct netlink_callback *cb);
|
||||
int drbd_adm_dump_peer_devices_done(struct netlink_callback *cb);
|
||||
|
||||
int drbd_nl_get_status_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_get_status_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
|
||||
int drbd_nl_new_minor_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_del_minor_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_new_resource_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_del_resource_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_resource_opts_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_connect_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_disconnect_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_attach_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_resize_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_primary_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_secondary_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_new_c_uuid_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_start_ov_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_detach_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_invalidate_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_inval_peer_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_pause_sync_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_resume_sync_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_suspend_io_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_resume_io_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_outdate_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_get_timeout_type_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_down_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_chg_disk_opts_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_chg_net_opts_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int drbd_nl_get_resources_dumpit(struct sk_buff *skb,
|
||||
struct netlink_callback *cb);
|
||||
int drbd_nl_get_devices_dumpit(struct sk_buff *skb,
|
||||
struct netlink_callback *cb);
|
||||
int drbd_nl_get_connections_dumpit(struct sk_buff *skb,
|
||||
struct netlink_callback *cb);
|
||||
int drbd_nl_get_peer_devices_dumpit(struct sk_buff *skb,
|
||||
struct netlink_callback *cb);
|
||||
int drbd_nl_get_initial_state_dumpit(struct sk_buff *skb,
|
||||
struct netlink_callback *cb);
|
||||
|
||||
enum {
|
||||
DRBD_NLGRP_EVENTS,
|
||||
};
|
||||
|
||||
struct drbd_cfg_reply {
|
||||
char info_text[0];
|
||||
__u32 info_text_len;
|
||||
};
|
||||
|
||||
struct drbd_cfg_context {
|
||||
__u32 ctx_volume;
|
||||
char ctx_resource_name[128];
|
||||
__u32 ctx_resource_name_len;
|
||||
char ctx_my_addr[128];
|
||||
__u32 ctx_my_addr_len;
|
||||
char ctx_peer_addr[128];
|
||||
__u32 ctx_peer_addr_len;
|
||||
};
|
||||
|
||||
struct disk_conf {
|
||||
char backing_dev[128];
|
||||
__u32 backing_dev_len;
|
||||
char meta_dev[128];
|
||||
__u32 meta_dev_len;
|
||||
__s32 meta_dev_idx;
|
||||
__u64 disk_size;
|
||||
__u32 max_bio_bvecs;
|
||||
__u32 on_io_error;
|
||||
__u32 fencing;
|
||||
__u32 resync_rate;
|
||||
__s32 resync_after;
|
||||
__u32 al_extents;
|
||||
__u32 c_plan_ahead;
|
||||
__u32 c_delay_target;
|
||||
__u32 c_fill_target;
|
||||
__u32 c_max_rate;
|
||||
__u32 c_min_rate;
|
||||
unsigned char disk_barrier;
|
||||
unsigned char disk_flushes;
|
||||
unsigned char disk_drain;
|
||||
unsigned char md_flushes;
|
||||
__u32 disk_timeout;
|
||||
__u32 read_balancing;
|
||||
unsigned char al_updates;
|
||||
unsigned char discard_zeroes_if_aligned;
|
||||
__u32 rs_discard_granularity;
|
||||
unsigned char disable_write_same;
|
||||
};
|
||||
|
||||
struct res_opts {
|
||||
char cpu_mask[DRBD_CPU_MASK_SIZE];
|
||||
__u32 cpu_mask_len;
|
||||
__u32 on_no_data;
|
||||
};
|
||||
|
||||
struct net_conf {
|
||||
char shared_secret[SHARED_SECRET_MAX];
|
||||
__u32 shared_secret_len;
|
||||
char cram_hmac_alg[SHARED_SECRET_MAX];
|
||||
__u32 cram_hmac_alg_len;
|
||||
char integrity_alg[SHARED_SECRET_MAX];
|
||||
__u32 integrity_alg_len;
|
||||
char verify_alg[SHARED_SECRET_MAX];
|
||||
__u32 verify_alg_len;
|
||||
char csums_alg[SHARED_SECRET_MAX];
|
||||
__u32 csums_alg_len;
|
||||
__u32 wire_protocol;
|
||||
__u32 connect_int;
|
||||
__u32 timeout;
|
||||
__u32 ping_int;
|
||||
__u32 ping_timeo;
|
||||
__u32 sndbuf_size;
|
||||
__u32 rcvbuf_size;
|
||||
__u32 ko_count;
|
||||
__u32 max_buffers;
|
||||
__u32 max_epoch_size;
|
||||
__u32 unplug_watermark;
|
||||
__u32 after_sb_0p;
|
||||
__u32 after_sb_1p;
|
||||
__u32 after_sb_2p;
|
||||
__u32 rr_conflict;
|
||||
__u32 on_congestion;
|
||||
__u32 cong_fill;
|
||||
__u32 cong_extents;
|
||||
unsigned char two_primaries;
|
||||
unsigned char discard_my_data;
|
||||
unsigned char tcp_cork;
|
||||
unsigned char always_asbp;
|
||||
unsigned char tentative;
|
||||
unsigned char use_rle;
|
||||
unsigned char csums_after_crash_only;
|
||||
__u32 sock_check_timeo;
|
||||
};
|
||||
|
||||
struct set_role_parms {
|
||||
unsigned char assume_uptodate;
|
||||
};
|
||||
|
||||
struct resize_parms {
|
||||
__u64 resize_size;
|
||||
unsigned char resize_force;
|
||||
unsigned char no_resync;
|
||||
__u32 al_stripes;
|
||||
__u32 al_stripe_size;
|
||||
};
|
||||
|
||||
struct state_info {
|
||||
__u32 sib_reason;
|
||||
__u32 current_state;
|
||||
__u64 capacity;
|
||||
__u64 ed_uuid;
|
||||
__u32 prev_state;
|
||||
__u32 new_state;
|
||||
char uuids[DRBD_NL_UUIDS_SIZE];
|
||||
__u32 uuids_len;
|
||||
__u32 disk_flags;
|
||||
__u64 bits_total;
|
||||
__u64 bits_oos;
|
||||
__u64 bits_rs_total;
|
||||
__u64 bits_rs_failed;
|
||||
char helper[32];
|
||||
__u32 helper_len;
|
||||
__u32 helper_exit_code;
|
||||
__u64 send_cnt;
|
||||
__u64 recv_cnt;
|
||||
__u64 read_cnt;
|
||||
__u64 writ_cnt;
|
||||
__u64 al_writ_cnt;
|
||||
__u64 bm_writ_cnt;
|
||||
__u32 ap_bio_cnt;
|
||||
__u32 ap_pending_cnt;
|
||||
__u32 rs_pending_cnt;
|
||||
};
|
||||
|
||||
struct start_ov_parms {
|
||||
__u64 ov_start_sector;
|
||||
__u64 ov_stop_sector;
|
||||
};
|
||||
|
||||
struct new_c_uuid_parms {
|
||||
unsigned char clear_bm;
|
||||
};
|
||||
|
||||
struct timeout_parms {
|
||||
__u32 timeout_type;
|
||||
};
|
||||
|
||||
struct disconnect_parms {
|
||||
unsigned char force_disconnect;
|
||||
};
|
||||
|
||||
struct detach_parms {
|
||||
unsigned char force_detach;
|
||||
};
|
||||
|
||||
struct resource_info {
|
||||
__u32 res_role;
|
||||
unsigned char res_susp;
|
||||
unsigned char res_susp_nod;
|
||||
unsigned char res_susp_fen;
|
||||
};
|
||||
|
||||
struct device_info {
|
||||
__u32 dev_disk_state;
|
||||
};
|
||||
|
||||
struct connection_info {
|
||||
__u32 conn_connection_state;
|
||||
__u32 conn_role;
|
||||
};
|
||||
|
||||
struct peer_device_info {
|
||||
__u32 peer_repl_state;
|
||||
__u32 peer_disk_state;
|
||||
__u32 peer_resync_susp_user;
|
||||
__u32 peer_resync_susp_peer;
|
||||
__u32 peer_resync_susp_dependency;
|
||||
};
|
||||
|
||||
struct resource_statistics {
|
||||
__u32 res_stat_write_ordering;
|
||||
};
|
||||
|
||||
struct device_statistics {
|
||||
__u64 dev_size;
|
||||
__u64 dev_read;
|
||||
__u64 dev_write;
|
||||
__u64 dev_al_writes;
|
||||
__u64 dev_bm_writes;
|
||||
__u32 dev_upper_pending;
|
||||
__u32 dev_lower_pending;
|
||||
unsigned char dev_upper_blocked;
|
||||
unsigned char dev_lower_blocked;
|
||||
unsigned char dev_al_suspended;
|
||||
__u64 dev_exposed_data_uuid;
|
||||
__u64 dev_current_uuid;
|
||||
__u32 dev_disk_flags;
|
||||
char history_uuids[DRBD_NL_HISTORY_UUIDS_SIZE];
|
||||
__u32 history_uuids_len;
|
||||
};
|
||||
|
||||
struct connection_statistics {
|
||||
unsigned char conn_congested;
|
||||
};
|
||||
|
||||
struct peer_device_statistics {
|
||||
__u64 peer_dev_received;
|
||||
__u64 peer_dev_sent;
|
||||
__u32 peer_dev_pending;
|
||||
__u32 peer_dev_unacked;
|
||||
__u64 peer_dev_out_of_sync;
|
||||
__u64 peer_dev_resync_failed;
|
||||
__u64 peer_dev_bitmap_uuid;
|
||||
__u32 peer_dev_flags;
|
||||
};
|
||||
|
||||
struct drbd_notification_header {
|
||||
__u32 nh_type;
|
||||
};
|
||||
|
||||
struct drbd_helper_info {
|
||||
char helper_name[32];
|
||||
__u32 helper_name_len;
|
||||
__u32 helper_status;
|
||||
};
|
||||
|
||||
int drbd_cfg_reply_to_skb(struct sk_buff *skb, struct drbd_cfg_reply *s);
|
||||
|
||||
int drbd_cfg_context_from_attrs(struct drbd_cfg_context *s, struct genl_info *info);
|
||||
int drbd_cfg_context_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
|
||||
int drbd_cfg_context_to_skb(struct sk_buff *skb, struct drbd_cfg_context *s);
|
||||
|
||||
int disk_conf_from_attrs(struct disk_conf *s, struct genl_info *info);
|
||||
int disk_conf_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
|
||||
int disk_conf_to_skb(struct sk_buff *skb, struct disk_conf *s);
|
||||
void set_disk_conf_defaults(struct disk_conf *x);
|
||||
|
||||
int res_opts_from_attrs(struct res_opts *s, struct genl_info *info);
|
||||
int res_opts_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
|
||||
int res_opts_to_skb(struct sk_buff *skb, struct res_opts *s);
|
||||
void set_res_opts_defaults(struct res_opts *x);
|
||||
|
||||
int net_conf_from_attrs(struct net_conf *s, struct genl_info *info);
|
||||
int net_conf_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
|
||||
int net_conf_to_skb(struct sk_buff *skb, struct net_conf *s);
|
||||
void set_net_conf_defaults(struct net_conf *x);
|
||||
|
||||
int set_role_parms_from_attrs(struct set_role_parms *s, struct genl_info *info);
|
||||
int set_role_parms_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
|
||||
int set_role_parms_to_skb(struct sk_buff *skb, struct set_role_parms *s);
|
||||
|
||||
int resize_parms_from_attrs(struct resize_parms *s, struct genl_info *info);
|
||||
int resize_parms_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
|
||||
int resize_parms_to_skb(struct sk_buff *skb, struct resize_parms *s);
|
||||
void set_resize_parms_defaults(struct resize_parms *x);
|
||||
|
||||
int state_info_to_skb(struct sk_buff *skb, struct state_info *s);
|
||||
|
||||
int start_ov_parms_from_attrs(struct start_ov_parms *s, struct genl_info *info);
|
||||
int start_ov_parms_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
|
||||
int start_ov_parms_to_skb(struct sk_buff *skb, struct start_ov_parms *s);
|
||||
|
||||
int new_c_uuid_parms_from_attrs(struct new_c_uuid_parms *s, struct genl_info *info);
|
||||
int new_c_uuid_parms_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
|
||||
int new_c_uuid_parms_to_skb(struct sk_buff *skb, struct new_c_uuid_parms *s);
|
||||
|
||||
int timeout_parms_to_skb(struct sk_buff *skb, struct timeout_parms *s);
|
||||
|
||||
int disconnect_parms_from_attrs(struct disconnect_parms *s, struct genl_info *info);
|
||||
int disconnect_parms_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
|
||||
int disconnect_parms_to_skb(struct sk_buff *skb, struct disconnect_parms *s);
|
||||
|
||||
int detach_parms_from_attrs(struct detach_parms *s, struct genl_info *info);
|
||||
int detach_parms_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
|
||||
int detach_parms_to_skb(struct sk_buff *skb, struct detach_parms *s);
|
||||
|
||||
int resource_info_from_attrs(struct resource_info *s, struct genl_info *info);
|
||||
int resource_info_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
|
||||
int resource_info_to_skb(struct sk_buff *skb, struct resource_info *s);
|
||||
|
||||
int device_info_from_attrs(struct device_info *s, struct genl_info *info);
|
||||
int device_info_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
|
||||
int device_info_to_skb(struct sk_buff *skb, struct device_info *s);
|
||||
|
||||
int connection_info_from_attrs(struct connection_info *s, struct genl_info *info);
|
||||
int connection_info_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
|
||||
int connection_info_to_skb(struct sk_buff *skb, struct connection_info *s);
|
||||
|
||||
int peer_device_info_from_attrs(struct peer_device_info *s, struct genl_info *info);
|
||||
int peer_device_info_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
|
||||
int peer_device_info_to_skb(struct sk_buff *skb, struct peer_device_info *s);
|
||||
|
||||
int resource_statistics_from_attrs(struct resource_statistics *s, struct genl_info *info);
|
||||
int resource_statistics_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
|
||||
int resource_statistics_to_skb(struct sk_buff *skb, struct resource_statistics *s);
|
||||
|
||||
int device_statistics_from_attrs(struct device_statistics *s, struct genl_info *info);
|
||||
int device_statistics_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
|
||||
int device_statistics_to_skb(struct sk_buff *skb, struct device_statistics *s);
|
||||
|
||||
int connection_statistics_from_attrs(struct connection_statistics *s, struct genl_info *info);
|
||||
int connection_statistics_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
|
||||
int connection_statistics_to_skb(struct sk_buff *skb, struct connection_statistics *s);
|
||||
|
||||
int peer_device_statistics_from_attrs(struct peer_device_statistics *s, struct genl_info *info);
|
||||
int peer_device_statistics_ntb_from_attrs(struct nlattr ***ret_nested_attribute_table, struct genl_info *info);
|
||||
int peer_device_statistics_to_skb(struct sk_buff *skb, struct peer_device_statistics *s);
|
||||
|
||||
int drbd_notification_header_to_skb(struct sk_buff *skb, struct drbd_notification_header *s);
|
||||
|
||||
int drbd_helper_info_to_skb(struct sk_buff *skb, struct drbd_helper_info *s);
|
||||
|
||||
#endif /* _LINUX_DRBD_GEN_H */
|
||||
@@ -228,7 +228,7 @@ int drbd_seq_show(struct seq_file *seq, void *v)
|
||||
};
|
||||
|
||||
seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n",
|
||||
GENL_MAGIC_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX, drbd_buildtag());
|
||||
DRBD_FAMILY_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX, drbd_buildtag());
|
||||
|
||||
/*
|
||||
cs .. connection state
|
||||
|
||||
Reference in New Issue
Block a user