drbd/0014-drbd-include-source-of-state-change-in-log.patch

1481 lines
63 KiB
Diff

From d6bbb1b1635b9912d77d1a26aba3f380a2ed986d Mon Sep 17 00:00:00 2001
From: Joel Colledge <joel.colledge@linbit.com>
Date: Mon, 11 Sep 2023 16:45:27 +0200
Subject: [PATCH 14/20] drbd: include source of state change in log
This is useful for understanding why a state change occurs. In
particular, whether it was triggered by userspace.
---
drbd/drbd_int.h | 10 ++--
drbd/drbd_main.c | 12 ++---
drbd/drbd_nl.c | 103 ++++++++++++++++++++------------------
drbd/drbd_receiver.c | 77 +++++++++++++++-------------
drbd/drbd_req.c | 6 +--
drbd/drbd_sender.c | 25 ++++++----
drbd/drbd_state.c | 116 ++++++++++++++++++++++++-------------------
drbd/drbd_state.h | 40 +++++++++++----
8 files changed, 224 insertions(+), 165 deletions(-)
diff --git a/drbd/drbd_int.h b/drbd/drbd_int.h
index f6e7c3ac2629..b705f26e71a4 100644
--- a/drbd/drbd_int.h
+++ b/drbd/drbd_int.h
@@ -1876,7 +1876,8 @@ extern void drbd_destroy_resource(struct kref *kref);
extern void drbd_destroy_device(struct kref *kref);
-extern int set_resource_options(struct drbd_resource *resource, struct res_opts *res_opts);
+extern int set_resource_options(struct drbd_resource *resource, struct res_opts *res_opts,
+ const char *tag);
extern struct drbd_connection *drbd_create_connection(struct drbd_resource *resource,
struct drbd_transport_class *tc);
extern void drbd_transport_shutdown(struct drbd_connection *connection, enum drbd_tr_free_op op);
@@ -1931,7 +1932,9 @@ extern void resync_after_online_grow(struct drbd_peer_device *);
extern void drbd_reconsider_queue_parameters(struct drbd_device *device,
struct drbd_backing_dev *bdev);
extern bool barrier_pending(struct drbd_resource *resource);
-extern enum drbd_state_rv drbd_set_role(struct drbd_resource *, enum drbd_role, bool, struct sk_buff *);
+extern enum drbd_state_rv
+drbd_set_role(struct drbd_resource *resource, enum drbd_role role, bool force, const char *tag,
+ struct sk_buff *reply_skb);
extern void conn_try_outdate_peer_async(struct drbd_connection *connection);
extern int drbd_maybe_khelper(struct drbd_device *, struct drbd_connection *, char *);
extern int drbd_create_peer_device_default_config(struct drbd_peer_device *peer_device);
@@ -1943,7 +1946,8 @@ extern int drbd_worker(struct drbd_thread *thi);
enum drbd_ret_code drbd_resync_after_valid(struct drbd_device *device, int o_minor);
void drbd_resync_after_changed(struct drbd_device *device);
extern bool drbd_stable_sync_source_present(struct drbd_peer_device *, enum which_state);
-extern void drbd_start_resync(struct drbd_peer_device *, enum drbd_repl_state);
+extern void drbd_start_resync(struct drbd_peer_device *peer_device, enum drbd_repl_state side,
+ const char *tag);
extern void resume_next_sg(struct drbd_device *device);
extern void suspend_other_sg(struct drbd_device *device);
extern void drbd_resync_finished(struct drbd_peer_device *, enum drbd_disk_state);
diff --git a/drbd/drbd_main.c b/drbd/drbd_main.c
index 6bb618909aa0..4b0b967c2c97 100644
--- a/drbd/drbd_main.c
+++ b/drbd/drbd_main.c
@@ -2505,7 +2505,7 @@ static int try_to_promote(struct drbd_device *device, long timeout, bool ndelay)
unsigned long start = jiffies;
long t;
- rv = drbd_set_role(resource, R_PRIMARY, false, NULL);
+ rv = drbd_set_role(resource, R_PRIMARY, false, "auto-promote", NULL);
timeout -= jiffies - start;
if (ndelay || rv >= SS_SUCCESS || timeout <= 0) {
@@ -2854,7 +2854,7 @@ static void drbd_release(struct gendisk *gd, fmode_t mode)
open_rw_cnt == 0 &&
resource->role[NOW] == R_PRIMARY &&
!test_bit(EXPLICIT_PRIMARY, &resource->flags)) {
- rv = drbd_set_role(resource, R_SECONDARY, false, NULL);
+ rv = drbd_set_role(resource, R_SECONDARY, false, "auto-demote", NULL);
if (rv < SS_SUCCESS)
drbd_warn(resource, "Auto-demote failed: %s (%d)\n",
drbd_set_st_err_str(rv), rv);
@@ -2866,7 +2866,7 @@ static void drbd_release(struct gendisk *gd, fmode_t mode)
begin_state_change(resource, &irq_flags, CS_VERBOSE);
resource->fail_io[NEW] = false;
- end_state_change(resource, &irq_flags);
+ end_state_change(resource, &irq_flags, "release");
}
/* if the open counts are 0, we free the whole list, otherwise we remove the specific pid */
@@ -3349,7 +3349,7 @@ static void wake_all_device_misc(struct drbd_resource *resource)
rcu_read_unlock();
}
-int set_resource_options(struct drbd_resource *resource, struct res_opts *res_opts)
+int set_resource_options(struct drbd_resource *resource, struct res_opts *res_opts, const char *tag)
{
struct drbd_connection *connection;
cpumask_var_t new_cpu_mask;
@@ -3414,7 +3414,7 @@ int set_resource_options(struct drbd_resource *resource, struct res_opts *res_op
if (force_state_recalc) {
begin_state_change(resource, &irq_flags, CS_VERBOSE | CS_FORCE_RECALC);
- end_state_change(resource, &irq_flags);
+ end_state_change(resource, &irq_flags, tag);
}
if (wake_device_misc)
@@ -3491,7 +3491,7 @@ struct drbd_resource *drbd_create_resource(const char *name,
}
resource->pp_vacant = page_pool_count;
- if (set_resource_options(resource, res_opts))
+ if (set_resource_options(resource, res_opts, "create-resource"))
goto fail_free_pages;
list_add_tail_rcu(&resource->resources, &drbd_resources);
diff --git a/drbd/drbd_nl.c b/drbd/drbd_nl.c
index cb5cdb184824..b7e9e43312f9 100644
--- a/drbd/drbd_nl.c
+++ b/drbd/drbd_nl.c
@@ -768,7 +768,7 @@ static bool intentional_diskless(struct drbd_resource *resource)
return intentional_diskless;
}
-static bool conn_try_outdate_peer(struct drbd_connection *connection)
+static bool conn_try_outdate_peer(struct drbd_connection *connection, const char *tag)
{
struct drbd_resource *resource = connection->resource;
unsigned long last_reconnect_jif;
@@ -792,7 +792,7 @@ static bool conn_try_outdate_peer(struct drbd_connection *connection)
!(disk_state == D_DISKLESS && intentional_diskless(resource))) {
begin_state_change_locked(resource, CS_VERBOSE | CS_HARD);
__change_io_susp_fencing(connection, false);
- end_state_change_locked(resource);
+ end_state_change_locked(resource, tag);
read_unlock_irq(&resource->state_rwlock);
return false;
}
@@ -862,7 +862,7 @@ static bool conn_try_outdate_peer(struct drbd_connection *connection)
goto abort;
}
- end_state_change(resource, &irq_flags);
+ end_state_change(resource, &irq_flags, tag);
goto out;
abort:
@@ -875,7 +875,7 @@ static int _try_outdate_peer_async(void *data)
{
struct drbd_connection *connection = (struct drbd_connection *)data;
- conn_try_outdate_peer(connection);
+ conn_try_outdate_peer(connection, "outdate-async");
kref_debug_put(&connection->kref_debug, 4);
kref_put(&connection->kref, drbd_destroy_connection);
@@ -1014,7 +1014,8 @@ static bool wait_up_to_date(struct drbd_resource *resource)
}
enum drbd_state_rv
-drbd_set_role(struct drbd_resource *resource, enum drbd_role role, bool force, struct sk_buff *reply_skb)
+drbd_set_role(struct drbd_resource *resource, enum drbd_role role, bool force, const char *tag,
+ struct sk_buff *reply_skb)
{
struct drbd_device *device;
int vnr, try = 0;
@@ -1042,7 +1043,7 @@ retry:
err_str = NULL;
}
rv = stable_state_change(resource,
- change_role(resource, role, flags, &err_str));
+ change_role(resource, role, flags, tag, &err_str));
if (rv == SS_TIMEOUT || rv == SS_CONCURRENT_ST_CHG) {
long timeout = twopc_retry_timeout(resource, try);
@@ -1104,7 +1105,7 @@ retry:
if (device->disk_state[NOW] != D_CONSISTENT)
continue;
- if (conn_try_outdate_peer(connection))
+ if (conn_try_outdate_peer(connection, tag))
fenced_peers = true;
else
any_fencing_failed = true;
@@ -1140,7 +1141,7 @@ retry:
up(&resource->state_sem); /* Allow connect while fencing */
for_each_connection_ref(connection, im, resource) {
- bool outdated_peer = conn_try_outdate_peer(connection);
+ bool outdated_peer = conn_try_outdate_peer(connection, tag);
if (!outdated_peer && force) {
drbd_warn(connection, "Forced into split brain situation!\n");
flags |= CS_FP_LOCAL_UP_TO_DATE;
@@ -1331,7 +1332,9 @@ int drbd_adm_set_role(struct sk_buff *skb, struct genl_info *info)
new_role = info->genlhdr->cmd == DRBD_ADM_PRIMARY ? R_PRIMARY : R_SECONDARY;
rv = drbd_set_role(adm_ctx.resource,
new_role,
- parms.force, adm_ctx.reply_skb);
+ parms.force,
+ new_role == R_PRIMARY ? "primary" : "secondary",
+ adm_ctx.reply_skb);
if (new_role == R_PRIMARY) {
if (rv >= SS_SUCCESS)
@@ -3093,7 +3096,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
drbd_flush_workqueue(&resource->work);
rv = stable_state_change(resource,
- change_disk_state(device, D_ATTACHING, CS_VERBOSE | CS_SERIALIZE, NULL));
+ change_disk_state(device, D_ATTACHING, CS_VERBOSE | CS_SERIALIZE, "attach", NULL));
retcode = (enum drbd_ret_code)rv;
if (rv >= SS_SUCCESS)
update_resource_dagtag(resource, nbc);
@@ -3353,8 +3356,8 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
/* change_disk_state uses disk_state_from_md(device); in case D_NEGOTIATING not
necessary, and falls back to a local state change */
- rv = stable_state_change(resource,
- change_disk_state(device, D_NEGOTIATING, CS_VERBOSE | CS_SERIALIZE, NULL));
+ rv = stable_state_change(resource, change_disk_state(device,
+ D_NEGOTIATING, CS_VERBOSE | CS_SERIALIZE, "attach", NULL));
if (rv < SS_SUCCESS) {
if (rv == SS_CW_FAILED_BY_PEER)
@@ -3385,7 +3388,7 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
force_diskless_dec:
put_ldev(device);
force_diskless:
- change_disk_state(device, D_DISKLESS, CS_HARD, NULL);
+ change_disk_state(device, D_DISKLESS, CS_HARD, "attach", NULL);
fail:
mutex_unlock_cond(&resource->conf_update, &have_conf_update);
drbd_backing_dev_free(device, nbc);
@@ -3406,7 +3409,7 @@ static enum drbd_disk_state get_disk_state(struct drbd_device *device)
}
static int adm_detach(struct drbd_device *device, bool force, bool intentional_diskless,
- struct sk_buff *reply_skb)
+ const char *tag, struct sk_buff *reply_skb)
{
const char *err_str = NULL;
int ret, retcode;
@@ -3414,7 +3417,7 @@ static int adm_detach(struct drbd_device *device, bool force, bool intentional_d
device->device_conf.intentional_diskless = intentional_diskless;
if (force) {
set_bit(FORCE_DETACH, &device->flags);
- change_disk_state(device, D_DETACHING, CS_HARD, NULL);
+ change_disk_state(device, D_DETACHING, CS_HARD, tag, NULL);
retcode = SS_SUCCESS;
goto out;
}
@@ -3422,7 +3425,7 @@ static int adm_detach(struct drbd_device *device, bool force, bool intentional_d
drbd_suspend_io(device, READ_AND_WRITE); /* so no-one is stuck in drbd_al_begin_io */
retcode = stable_state_change(device->resource,
change_disk_state(device, D_DETACHING,
- CS_VERBOSE | CS_WAIT_COMPLETE | CS_SERIALIZE, &err_str));
+ CS_VERBOSE | CS_WAIT_COMPLETE | CS_SERIALIZE, tag, &err_str));
/* D_DETACHING will transition to DISKLESS. */
drbd_resume_io(device);
ret = wait_event_interruptible(device->misc_wait,
@@ -3473,7 +3476,7 @@ int drbd_adm_detach(struct sk_buff *skb, struct genl_info *info)
mutex_lock(&adm_ctx.resource->adm_mutex);
retcode = (enum drbd_ret_code)adm_detach(adm_ctx.device, parms.force_detach,
- parms.intentional_diskless_detach, adm_ctx.reply_skb);
+ parms.intentional_diskless_detach, "detach", adm_ctx.reply_skb);
mutex_unlock(&adm_ctx.resource->adm_mutex);
out:
@@ -4385,7 +4388,7 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
drbd_md_mark_dirty(device);
}
- rv = change_cstate(connection, C_UNCONNECTED, CS_VERBOSE);
+ rv = change_cstate_tag(connection, C_UNCONNECTED, CS_VERBOSE, "connect", NULL);
drbd_adm_finish(&adm_ctx, info, rv);
return 0;
out:
@@ -4535,7 +4538,7 @@ int drbd_open_ro_count(struct drbd_resource *resource)
}
static enum drbd_state_rv conn_try_disconnect(struct drbd_connection *connection, bool force,
- struct sk_buff *reply_skb)
+ const char *tag, struct sk_buff *reply_skb)
{
struct drbd_resource *resource = connection->resource;
enum drbd_conn_state cstate;
@@ -4545,7 +4548,7 @@ static enum drbd_state_rv conn_try_disconnect(struct drbd_connection *connection
long t;
repeat:
- rv = change_cstate_es(connection, C_DISCONNECTING, flags, &err_str);
+ rv = change_cstate_tag(connection, C_DISCONNECTING, flags, tag, &err_str);
switch (rv) {
case SS_CW_FAILED_BY_PEER:
case SS_NEED_CONNECTION:
@@ -4571,7 +4574,7 @@ static enum drbd_state_rv conn_try_disconnect(struct drbd_connection *connection
break;
case SS_IS_DISKLESS:
case SS_LOWER_THAN_OUTDATED:
- rv = change_cstate(connection, C_DISCONNECTING, CS_HARD);
+ rv = change_cstate_tag(connection, C_DISCONNECTING, CS_HARD, tag, NULL);
break;
case SS_NO_QUORUM:
if (!(flags & CS_VERBOSE)) {
@@ -4597,7 +4600,7 @@ static enum drbd_state_rv conn_try_disconnect(struct drbd_connection *connection
/* this can only be called immediately after a successful
* peer_try_disconnect, within the same resource->adm_mutex */
-static void del_connection(struct drbd_connection *connection)
+static void del_connection(struct drbd_connection *connection, const char *tag)
{
struct drbd_resource *resource = connection->resource;
struct drbd_peer_device *peer_device;
@@ -4619,7 +4622,7 @@ static void del_connection(struct drbd_connection *connection)
* after drbd_receiver() returned. Typically, we should be
* C_STANDALONE already, now, and this becomes a no-op.
*/
- rv2 = change_cstate(connection, C_STANDALONE, CS_VERBOSE | CS_HARD);
+ rv2 = change_cstate_tag(connection, C_STANDALONE, CS_VERBOSE | CS_HARD, tag, NULL);
if (rv2 < SS_SUCCESS)
drbd_err(connection,
"unexpected rv2=%d in del_connection()\n",
@@ -4654,6 +4657,7 @@ static int adm_disconnect(struct sk_buff *skb, struct genl_info *info, bool dest
struct drbd_connection *connection;
enum drbd_state_rv rv;
enum drbd_ret_code retcode;
+ const char *tag = destroy ? "del-peer" : "disconnect";
retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_CONNECTION);
if (!adm_ctx.reply_skb)
@@ -4671,10 +4675,10 @@ static int adm_disconnect(struct sk_buff *skb, struct genl_info *info, bool dest
connection = adm_ctx.connection;
mutex_lock(&adm_ctx.resource->adm_mutex);
- rv = conn_try_disconnect(connection, parms.force_disconnect, adm_ctx.reply_skb);
+ rv = conn_try_disconnect(connection, parms.force_disconnect, tag, adm_ctx.reply_skb);
if (rv >= SS_SUCCESS && destroy) {
mutex_lock(&connection->resource->conf_update);
- del_connection(connection);
+ del_connection(connection, tag);
mutex_unlock(&connection->resource->conf_update);
}
if (rv < SS_SUCCESS)
@@ -4721,10 +4725,10 @@ void resync_after_online_grow(struct drbd_peer_device *peer_device)
if (!sync_source && connection->agreed_pro_version < 110) {
stable_change_repl_state(peer_device, L_WF_SYNC_UUID,
- CS_VERBOSE | CS_SERIALIZE);
+ CS_VERBOSE | CS_SERIALIZE, "online-grow");
return;
}
- drbd_start_resync(peer_device, sync_source ? L_SYNC_SOURCE : L_SYNC_TARGET);
+ drbd_start_resync(peer_device, sync_source ? L_SYNC_SOURCE : L_SYNC_TARGET, "online-grow");
}
sector_t drbd_local_max_size(struct drbd_device *device) __must_hold(local)
@@ -4956,7 +4960,7 @@ int drbd_adm_resource_opts(struct sk_buff *skb, struct genl_info *info)
goto fail;
}
- err = set_resource_options(adm_ctx.resource, &res_opts);
+ err = set_resource_options(adm_ctx.resource, &res_opts, "resource-options");
if (err) {
retcode = ERR_INVALID_REQUEST;
if (err == -ENOMEM)
@@ -4976,11 +4980,11 @@ static enum drbd_state_rv invalidate_resync(struct drbd_peer_device *peer_device
drbd_flush_workqueue(&peer_device->connection->sender_work);
- rv = change_repl_state(peer_device, L_STARTING_SYNC_T, CS_SERIALIZE);
+ rv = change_repl_state(peer_device, L_STARTING_SYNC_T, CS_SERIALIZE, "invalidate");
if (rv < SS_SUCCESS && rv != SS_NEED_CONNECTION)
rv = stable_change_repl_state(peer_device, L_STARTING_SYNC_T,
- CS_VERBOSE | CS_SERIALIZE);
+ CS_VERBOSE | CS_SERIALIZE, "invalidate");
wait_event_interruptible(resource->state_wait,
peer_device->repl_state[NOW] != L_STARTING_SYNC_T);
@@ -5005,7 +5009,7 @@ static enum drbd_state_rv invalidate_no_resync(struct drbd_device *device) __mus
}
}
__change_disk_state(device, D_INCONSISTENT);
- rv = end_state_change(resource, &irq_flags);
+ rv = end_state_change(resource, &irq_flags, "invalidate");
if (rv >= SS_SUCCESS) {
drbd_bitmap_io(device, &drbd_bmio_set_all_n_write,
@@ -5080,7 +5084,8 @@ int drbd_adm_invalidate(struct sk_buff *skb, struct genl_info *info)
retcode = invalidate_resync(sync_from_peer_device);
} else {
retcode = change_repl_state(sync_from_peer_device, L_WF_BITMAP_T,
- CS_VERBOSE | CS_CLUSTER_WIDE | CS_WAIT_COMPLETE | CS_SERIALIZE);
+ CS_VERBOSE | CS_CLUSTER_WIDE | CS_WAIT_COMPLETE |
+ CS_SERIALIZE, "invalidate");
}
} else {
int retry = 3;
@@ -5103,7 +5108,8 @@ int drbd_adm_invalidate(struct sk_buff *skb, struct genl_info *info)
}
retcode = change_repl_state(peer_device, L_WF_BITMAP_T,
CS_VERBOSE | CS_CLUSTER_WIDE |
- CS_WAIT_COMPLETE | CS_SERIALIZE);
+ CS_WAIT_COMPLETE | CS_SERIALIZE,
+ "invalidate");
}
if (retcode >= SS_SUCCESS)
goto out;
@@ -5140,13 +5146,15 @@ static int full_sync_from_peer(struct drbd_peer_device *peer_device)
struct drbd_resource *resource = device->resource;
int retcode; /* enum drbd_ret_code rsp. enum drbd_state_rv */
- retcode = stable_change_repl_state(peer_device, L_STARTING_SYNC_S, CS_SERIALIZE);
+ retcode = stable_change_repl_state(peer_device, L_STARTING_SYNC_S, CS_SERIALIZE,
+ "invalidate-remote");
if (retcode < SS_SUCCESS) {
if (retcode == SS_NEED_CONNECTION && resource->role[NOW] == R_PRIMARY) {
/* The peer will get a resync upon connect anyways.
* Just make that into a full resync. */
retcode = change_peer_disk_state(peer_device, D_INCONSISTENT,
- CS_VERBOSE | CS_WAIT_COMPLETE | CS_SERIALIZE);
+ CS_VERBOSE | CS_WAIT_COMPLETE | CS_SERIALIZE,
+ "invalidate-remote");
if (retcode >= SS_SUCCESS) {
if (drbd_bitmap_io(device, &drbd_bmio_set_susp_al,
"set_n_write from invalidate_peer",
@@ -5155,7 +5163,7 @@ static int full_sync_from_peer(struct drbd_peer_device *peer_device)
}
} else {
retcode = stable_change_repl_state(peer_device, L_STARTING_SYNC_S,
- CS_VERBOSE | CS_SERIALIZE);
+ CS_VERBOSE | CS_SERIALIZE, "invalidate-remote");
}
}
@@ -5214,7 +5222,8 @@ int drbd_adm_invalidate_peer(struct sk_buff *skb, struct genl_info *info)
retcode = full_sync_from_peer(peer_device);
} else {
retcode = change_repl_state(peer_device, L_WF_BITMAP_S,
- CS_VERBOSE | CS_CLUSTER_WIDE | CS_WAIT_COMPLETE | CS_SERIALIZE);
+ CS_VERBOSE | CS_CLUSTER_WIDE | CS_WAIT_COMPLETE | CS_SERIALIZE,
+ "invalidate-remote");
}
drbd_resume_io(device);
@@ -5329,7 +5338,7 @@ int drbd_adm_resume_io(struct sk_buff *skb, struct genl_info *info)
__change_io_susp_fencing(connection, false);
__change_io_susp_quorum(resource, false);
- retcode = end_state_change(resource, &irq_flags);
+ retcode = end_state_change(resource, &irq_flags, "resume-io");
drbd_resume_io(device);
mutex_unlock(&adm_ctx.resource->adm_mutex);
drbd_adm_finish(&adm_ctx, info, retcode);
@@ -5348,7 +5357,7 @@ int drbd_adm_outdate(struct sk_buff *skb, struct genl_info *info)
retcode = stable_state_change(adm_ctx.device->resource,
change_disk_state(adm_ctx.device, D_OUTDATED,
- CS_VERBOSE | CS_WAIT_COMPLETE | CS_SERIALIZE, NULL));
+ CS_VERBOSE | CS_WAIT_COMPLETE | CS_SERIALIZE, "outdate", NULL));
mutex_unlock(&adm_ctx.resource->adm_mutex);
drbd_adm_finish(&adm_ctx, info, retcode);
@@ -6010,7 +6019,7 @@ int drbd_adm_start_ov(struct sk_buff *skb, struct genl_info *info)
drbd_suspend_io(device, READ_AND_WRITE);
wait_event(device->misc_wait, !atomic_read(&device->pending_bitmap_work.n));
rv = stable_change_repl_state(peer_device,
- L_VERIFY_S, CS_VERBOSE | CS_WAIT_COMPLETE | CS_SERIALIZE);
+ L_VERIFY_S, CS_VERBOSE | CS_WAIT_COMPLETE | CS_SERIALIZE, "verify");
drbd_resume_io(device);
mutex_unlock(&adm_ctx.resource->adm_mutex);
@@ -6082,7 +6091,7 @@ int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info)
unsigned long irq_flags;
begin_state_change(device->resource, &irq_flags, CS_VERBOSE);
__change_disk_state(device, D_UP_TO_DATE);
- end_state_change(device->resource, &irq_flags);
+ end_state_change(device->resource, &irq_flags, "new-c-uuid");
for_each_peer_device(peer_device, device) {
if (NODE_MASK(peer_device->node_id) & nodes) {
@@ -6122,7 +6131,7 @@ int drbd_adm_new_c_uuid(struct sk_buff *skb, struct genl_info *info)
if (NODE_MASK(peer_device->node_id) & diskful)
__change_peer_disk_state(peer_device, D_UP_TO_DATE);
}
- end_state_change(device->resource, &irq_flags);
+ end_state_change(device->resource, &irq_flags, "new-c-uuid");
}
drbd_md_sync_if_dirty(device);
@@ -6353,7 +6362,7 @@ static enum drbd_ret_code adm_del_minor(struct drbd_device *device)
for_each_peer_device_ref(peer_device, im, device)
stable_change_repl_state(peer_device, L_OFF,
- CS_VERBOSE | CS_WAIT_COMPLETE);
+ CS_VERBOSE | CS_WAIT_COMPLETE, "del-minor");
/* If drbd_ldev_destroy() is pending, wait for it to run before
* unregistering the device. */
@@ -6465,7 +6474,7 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
mutex_lock(&resource->adm_mutex);
set_bit(DOWN_IN_PROGRESS, &resource->flags);
/* demote */
- retcode = drbd_set_role(resource, R_SECONDARY, false, adm_ctx.reply_skb);
+ retcode = drbd_set_role(resource, R_SECONDARY, false, "down", adm_ctx.reply_skb);
if (retcode < SS_SUCCESS) {
opener_info(adm_ctx.resource, adm_ctx.reply_skb, retcode);
goto out;
@@ -6474,10 +6483,10 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
for_each_connection_ref(connection, im, resource) {
retcode = SS_SUCCESS;
if (connection->cstate[NOW] > C_STANDALONE)
- retcode = conn_try_disconnect(connection, 0, adm_ctx.reply_skb);
+ retcode = conn_try_disconnect(connection, 0, "down", adm_ctx.reply_skb);
if (retcode >= SS_SUCCESS) {
mutex_lock(&resource->conf_update);
- del_connection(connection);
+ del_connection(connection, "down");
mutex_unlock(&resource->conf_update);
} else {
kref_debug_put(&connection->kref_debug, 13);
@@ -6491,7 +6500,7 @@ int drbd_adm_down(struct sk_buff *skb, struct genl_info *info)
idr_for_each_entry(&resource->devices, device, i) {
kref_get(&device->kref);
rcu_read_unlock();
- retcode = adm_detach(device, 0, 0, adm_ctx.reply_skb);
+ retcode = adm_detach(device, 0, 0, "down", adm_ctx.reply_skb);
mutex_lock(&resource->conf_update);
ret = adm_del_minor(device);
mutex_unlock(&resource->conf_update);
diff --git a/drbd/drbd_receiver.c b/drbd/drbd_receiver.c
index 223353b1081c..0c3ab0fd486c 100644
--- a/drbd/drbd_receiver.c
+++ b/drbd/drbd_receiver.c
@@ -920,7 +920,7 @@ static void apply_local_state_change(struct drbd_connection *connection, enum ao
resource->role[NEW] = R_SECONDARY;
}
}
- end_state_change(resource, &irq_flags);
+ end_state_change(resource, &irq_flags, "connect-failed");
}
static int connect_work(struct drbd_work *work, int cancel)
@@ -945,8 +945,9 @@ static int connect_work(struct drbd_work *work, int cancel)
rv = SS_CONCURRENT_ST_CHG;
break;
}
- rv = change_cstate(connection, C_CONNECTED, CS_SERIALIZE |
- CS_ALREADY_SERIALIZED | CS_VERBOSE | CS_DONT_RETRY);
+ rv = change_cstate_tag(connection, C_CONNECTED, CS_SERIALIZE |
+ CS_ALREADY_SERIALIZED | CS_VERBOSE | CS_DONT_RETRY,
+ "connected", NULL);
up(&resource->state_sem);
if (rv != SS_PRIMARY_READER)
break;
@@ -1011,7 +1012,8 @@ static bool conn_connect(struct drbd_connection *connection)
start:
have_mutex = false;
clear_bit(DISCONNECT_EXPECTED, &connection->flags);
- if (change_cstate(connection, C_CONNECTING, CS_VERBOSE) < SS_SUCCESS) {
+ if (change_cstate_tag(connection, C_CONNECTING, CS_VERBOSE, "connecting", NULL)
+ < SS_SUCCESS) {
/* We do not have a network config. */
return false;
}
@@ -3697,7 +3699,8 @@ static enum sync_strategy drbd_asb_recover_1p(struct drbd_peer_device *peer_devi
/* drbd_change_state() does not sleep while in SS_IN_TRANSIENT_STATE,
* we might be here in L_OFF which is transient.
* we do not need to wait for the after state change work either. */
- rv2 = change_role(resource, R_SECONDARY, CS_VERBOSE, NULL);
+ rv2 = change_role(resource, R_SECONDARY, CS_VERBOSE,
+ "after-sb-1pri", NULL);
if (rv2 != SS_SUCCESS) {
drbd_maybe_khelper(device, connection, "pri-lost-after-sb");
} else {
@@ -3750,7 +3753,8 @@ static enum sync_strategy drbd_asb_recover_2p(struct drbd_peer_device *peer_devi
/* drbd_change_state() does not sleep while in SS_IN_TRANSIENT_STATE,
* we might be here in L_OFF which is transient.
* we do not need to wait for the after state change work either. */
- rv2 = change_role(device->resource, R_SECONDARY, CS_VERBOSE, NULL);
+ rv2 = change_role(device->resource, R_SECONDARY, CS_VERBOSE,
+ "after-sb-2pri", NULL);
if (rv2 != SS_SUCCESS) {
drbd_maybe_khelper(device, connection, "pri-lost-after-sb");
} else {
@@ -5500,6 +5504,7 @@ static void drbd_resync(struct drbd_peer_device *peer_device,
enum sync_rule rule;
int peer_node_id;
enum drbd_state_rv rv;
+ const char *tag = reason == AFTER_UNSTABLE ? "after-unstable" : "diskless-primary";
strategy = drbd_handshake(peer_device, &rule, &peer_node_id, reason == DISKLESS_PRIMARY);
if (strategy == SPLIT_BRAIN_AUTO_RECOVER && reason == AFTER_UNSTABLE)
@@ -5529,11 +5534,11 @@ static void drbd_resync(struct drbd_peer_device *peer_device,
as well. */
drbd_info(peer_device, "Upgrading local disk to %s after unstable/weak (and no resync).\n",
drbd_disk_str(peer_disk_state));
- change_disk_state(peer_device->device, peer_disk_state, CS_VERBOSE, NULL);
+ change_disk_state(peer_device->device, peer_disk_state, CS_VERBOSE, tag, NULL);
return;
}
- rv = change_repl_state(peer_device, new_repl_state, CS_VERBOSE);
+ rv = change_repl_state(peer_device, new_repl_state, CS_VERBOSE, tag);
if ((rv == SS_NOTHING_TO_DO || rv == SS_RESYNC_RUNNING) &&
(new_repl_state == L_WF_BITMAP_S || new_repl_state == L_WF_BITMAP_T)) {
/* Those events might happen very quickly. In case we are still processing
@@ -5633,7 +5638,7 @@ static int __receive_uuids(struct drbd_peer_device *peer_device, u64 node_mask)
begin_state_change(device->resource, &irq_flags, CS_VERBOSE);
__change_disk_state(device, D_UP_TO_DATE);
__change_peer_disk_state(peer_device, D_UP_TO_DATE);
- end_state_change(device->resource, &irq_flags);
+ end_state_change(device->resource, &irq_flags, "skip-initial-sync");
updated_uuids = 1;
propagate_skip_initial_to_diskless(device);
}
@@ -5668,7 +5673,7 @@ static int __receive_uuids(struct drbd_peer_device *peer_device, u64 node_mask)
if (device->disk_state[NOW] == D_DISKLESS && uuid_match &&
peer_device->disk_state[NOW] == D_CONSISTENT) {
drbd_info(peer_device, "Peer is on same UUID now\n");
- change_peer_disk_state(peer_device, D_UP_TO_DATE, CS_VERBOSE);
+ change_peer_disk_state(peer_device, D_UP_TO_DATE, CS_VERBOSE, "receive-uuids");
}
if (updated_uuids)
@@ -5855,7 +5860,7 @@ static void check_resync_source(struct drbd_device *device, u64 weak_nodes)
return;
abort:
drbd_info(peer_device, "My sync source became a weak node, aborting resync!\n");
- change_repl_state(peer_device, L_ESTABLISHED, CS_VERBOSE);
+ change_repl_state(peer_device, L_ESTABLISHED, CS_VERBOSE, "abort-resync");
drbd_flush_workqueue(&device->resource->work);
wait_event_interruptible(device->misc_wait,
@@ -6091,7 +6096,7 @@ retry:
if (is_connect && connection->agreed_pro_version >= 117)
apply_connect(connection, (flags & CS_PREPARED) && !abort);
- rv = end_state_change(resource, &irq_flags);
+ rv = end_state_change(resource, &irq_flags, "remote");
out:
if ((rv == SS_NO_UP_TO_DATE_DISK && resource->role[NOW] != R_PRIMARY) ||
@@ -6144,7 +6149,7 @@ change_peer_device_state(struct drbd_peer_device *peer_device,
rv = __change_connection_state(connection, mask, val, flags);
if (rv < SS_SUCCESS)
goto fail;
- rv = end_state_change(connection->resource, &irq_flags);
+ rv = end_state_change(connection->resource, &irq_flags, "remote");
out:
return rv;
fail:
@@ -6375,7 +6380,7 @@ far_away_change(struct drbd_connection *connection,
}
/* even if no outdate happens, CS_FORCE_RECALC might be set here */
- return end_state_change(resource, &irq_flags);
+ return end_state_change(resource, &irq_flags, "far-away");
}
static void handle_neighbor_demotion(struct drbd_connection *connection,
@@ -6630,17 +6635,18 @@ cont:
/* peer is secondary */
resync = L_SYNC_SOURCE;
}
- drbd_start_resync(peer_device, resync);
+ drbd_start_resync(peer_device, resync, "resize");
} else {
if (tr->diskful_primary_nodes & NODE_MASK(peer_device->node_id))
- drbd_start_resync(peer_device, L_SYNC_TARGET);
+ drbd_start_resync(peer_device, L_SYNC_TARGET,
+ "resize");
/* else no resync */
}
} else {
if (resource->twopc_parent_nodes & NODE_MASK(peer_device->node_id))
- drbd_start_resync(peer_device, L_SYNC_TARGET);
+ drbd_start_resync(peer_device, L_SYNC_TARGET, "resize");
else if (nodes_to_reach & NODE_MASK(peer_device->node_id))
- drbd_start_resync(peer_device, L_SYNC_SOURCE);
+ drbd_start_resync(peer_device, L_SYNC_SOURCE, "resize");
/* else no resync */
}
}
@@ -7101,7 +7107,7 @@ void drbd_try_to_get_resynced(struct drbd_device *device)
peer_device = best_peer_device;
if (best_strategy == NO_SYNC) {
- change_disk_state(device, D_UP_TO_DATE, CS_VERBOSE, NULL);
+ change_disk_state(device, D_UP_TO_DATE, CS_VERBOSE, "get-resync", NULL);
} else if (peer_device) {
drbd_resync(peer_device, DISKLESS_PRIMARY);
drbd_send_uuids(peer_device, UUID_FLAG_RESYNC | UUID_FLAG_DISKLESS_PRIMARY, 0);
@@ -7225,7 +7231,7 @@ static void diskless_with_peers_different_current_uuids(struct drbd_peer_device
CS_VERBOSE | CS_HARD | CS_FS_IGN_OPENERS);
resource->role[NEW] = R_SECONDARY;
/* resource->fail_io[NEW] gets set via CS_FS_IGN_OPENERS */
- end_state_change(resource, &irq_flags);
+ end_state_change(resource, &irq_flags, "peer-state");
}
set_bit(CONN_HANDSHAKE_RETRY, &connection->flags);
} else if (data_successor && resource->role[NOW] == R_SECONDARY) {
@@ -7278,7 +7284,7 @@ static int receive_state(struct drbd_connection *connection, struct packet_info
if (peer_state.role == R_SECONDARY) {
begin_state_change(resource, &irq_flags, CS_HARD | CS_VERBOSE);
__change_peer_role(connection, R_SECONDARY);
- rv = end_state_change(resource, &irq_flags);
+ rv = end_state_change(resource, &irq_flags, "peer-state");
if (rv < SS_SUCCESS)
goto fail;
}
@@ -7374,7 +7380,7 @@ static int receive_state(struct drbd_connection *connection, struct packet_info
/* Start resync after AHEAD/BEHIND */
if (connection->agreed_pro_version >= 110 &&
peer_state.conn == L_SYNC_SOURCE && old_peer_state.conn == L_BEHIND) {
- drbd_start_resync(peer_device, L_SYNC_TARGET);
+ drbd_start_resync(peer_device, L_SYNC_TARGET, "resync-after-behind");
return 0;
}
@@ -7519,7 +7525,7 @@ static int receive_state(struct drbd_connection *connection, struct packet_info
begin_state_change(resource, &irq_flags, CS_HARD);
__change_cstate(connection, C_PROTOCOL_ERROR);
__change_io_susp_user(resource, false);
- end_state_change(resource, &irq_flags);
+ end_state_change(resource, &irq_flags, "abort-connect");
return -EIO;
}
@@ -7581,7 +7587,7 @@ static int receive_state(struct drbd_connection *connection, struct packet_info
if (repl_state[OLD] < L_ESTABLISHED && repl_state[NEW] >= L_ESTABLISHED)
resource->state_change_flags |= CS_HARD;
- rv = end_state_change(resource, &irq_flags);
+ rv = end_state_change(resource, &irq_flags, "peer-state");
new_repl_state = peer_device->repl_state[NOW];
if (rv < SS_SUCCESS)
@@ -7635,7 +7641,7 @@ static int receive_sync_uuid(struct drbd_connection *connection, struct packet_i
_drbd_uuid_set_bitmap(peer_device, 0UL);
drbd_print_uuids(peer_device, "updated sync uuid");
- drbd_start_resync(peer_device, L_SYNC_TARGET);
+ drbd_start_resync(peer_device, L_SYNC_TARGET, "peer-sync-uuid");
put_ldev(device);
} else
@@ -7935,17 +7941,18 @@ static int receive_bitmap(struct drbd_connection *connection, struct packet_info
/* We have entered drbd_start_resync() since starting the bitmap exchange. */
drbd_warn(peer_device, "Received bitmap more than once; ignoring\n");
} else if (repl_state == L_WF_BITMAP_S) {
- drbd_start_resync(peer_device, L_SYNC_SOURCE);
+ drbd_start_resync(peer_device, L_SYNC_SOURCE, "receive-bitmap");
} else if (repl_state == L_WF_BITMAP_T) {
if (connection->agreed_pro_version < 110) {
enum drbd_state_rv rv;
/* Omit CS_WAIT_COMPLETE and CS_SERIALIZE with this state
* transition to avoid deadlocks. */
- rv = stable_change_repl_state(peer_device, L_WF_SYNC_UUID, CS_VERBOSE);
+ rv = stable_change_repl_state(peer_device, L_WF_SYNC_UUID, CS_VERBOSE,
+ "receive-bitmap");
D_ASSERT(device, rv == SS_SUCCESS);
} else {
- drbd_start_resync(peer_device, L_SYNC_TARGET);
+ drbd_start_resync(peer_device, L_SYNC_TARGET, "receive-bitmap");
}
} else {
/* admin may have requested C_DISCONNECTING,
@@ -8139,7 +8146,7 @@ static int receive_peer_dagtag(struct drbd_connection *connection, struct packet
__change_repl_state(peer_device, new_repl_state);
set_bit(RECONCILIATION_RESYNC, &peer_device->flags);
}
- rv = end_state_change(resource, &irq_flags);
+ rv = end_state_change(resource, &irq_flags, "receive-peer-dagtag");
if (rv == SS_SUCCESS)
drbd_info(connection, "Reconciliation resync because \'%s\' disappeared. (o=%d)\n",
lost_peer->transport.net_conf->name, (int)dagtag_offset);
@@ -8248,7 +8255,8 @@ static int receive_current_uuid(struct drbd_connection *connection, struct packe
if (resource->remote_state_change)
set_bit(OUTDATE_ON_2PC_COMMIT, &device->flags);
else
- change_disk_state(device, D_OUTDATED, CS_VERBOSE, NULL);
+ change_disk_state(device, D_OUTDATED, CS_VERBOSE,
+ "receive-current-uuid", NULL);
}
put_ldev(device);
} else if (device->disk_state[NOW] == D_DISKLESS && resource->role[NOW] == R_PRIMARY) {
@@ -8328,7 +8336,7 @@ static int receive_rs_deallocated(struct drbd_connection *connection, struct pac
static int receive_disconnect(struct drbd_connection *connection, struct packet_info *pi)
{
- change_cstate(connection, C_DISCONNECTING, CS_HARD);
+ change_cstate_tag(connection, C_DISCONNECTING, CS_HARD, "receive-disconnect", NULL);
return 0;
}
@@ -8594,7 +8602,7 @@ static void conn_disconnect(struct drbd_connection *connection)
* Usually we should be in some network failure state already,
* but just in case we are not, we fix it up here.
*/
- change_cstate(connection, C_NETWORK_FAILURE, CS_HARD);
+ change_cstate_tag(connection, C_NETWORK_FAILURE, CS_HARD, "disconnected", NULL);
del_connect_timer(connection);
@@ -8707,10 +8715,11 @@ static void conn_disconnect(struct drbd_connection *connection)
/* drbd_receiver() has to be restarted after it returns */
drbd_thread_restart_nowait(&connection->receiver);
}
- end_state_change(resource, &irq_flags);
+ end_state_change(resource, &irq_flags, "disconnected");
if (oc == C_DISCONNECTING)
- change_cstate(connection, C_STANDALONE, CS_VERBOSE | CS_HARD | CS_LOCAL_ONLY);
+ change_cstate_tag(connection, C_STANDALONE, CS_VERBOSE | CS_HARD | CS_LOCAL_ONLY,
+ "disconnected", NULL);
}
/*
diff --git a/drbd/drbd_req.c b/drbd/drbd_req.c
index af2ae66f51b5..41950e46ec27 100644
--- a/drbd/drbd_req.c
+++ b/drbd/drbd_req.c
@@ -2688,7 +2688,7 @@ void request_timer_fn(struct timer_list *t)
continue;
begin_state_change(resource, &irq_flags, CS_VERBOSE | CS_HARD);
__change_cstate(connection, C_TIMEOUT);
- end_state_change(resource, &irq_flags);
+ end_state_change(resource, &irq_flags, "timeout");
kref_put(&connection->kref, drbd_destroy_connection);
}
@@ -2723,7 +2723,7 @@ void drbd_handle_io_error_(struct drbd_device *device,
if (device->disk_state[NOW] > D_INCONSISTENT) {
begin_state_change_locked(device->resource, CS_HARD);
__change_disk_state(device, D_INCONSISTENT);
- end_state_change_locked(device->resource);
+ end_state_change_locked(device->resource, "local-io-error");
}
break;
}
@@ -2740,7 +2740,7 @@ void drbd_handle_io_error_(struct drbd_device *device,
if (device->disk_state[NOW] > D_FAILED) {
begin_state_change_locked(device->resource, CS_HARD);
__change_disk_state(device, D_FAILED);
- end_state_change_locked(device->resource);
+ end_state_change_locked(device->resource, "local-io-error");
drbd_err(device,
"Local IO failed in %s. Detaching...\n", where);
}
diff --git a/drbd/drbd_sender.c b/drbd/drbd_sender.c
index 93a460dae190..0beeb5f3cb54 100644
--- a/drbd/drbd_sender.c
+++ b/drbd/drbd_sender.c
@@ -472,7 +472,7 @@ int w_resync_timer(struct drbd_work *w, int cancel)
unsigned long irq_flags;
begin_state_change(resource, &irq_flags, 0);
peer_device->resync_active[NEW] = false;
- end_state_change(resource, &irq_flags);
+ end_state_change(resource, &irq_flags, "resync-inactive");
}
break;
}
@@ -1155,7 +1155,7 @@ static void resync_again(struct drbd_device *device, u64 source_m, u64 target_m)
peer_device->resync_again--;
begin_state_change_locked(device->resource, CS_VERBOSE);
__change_repl_state(peer_device, new_repl_state);
- end_state_change_locked(device->resource);
+ end_state_change_locked(device->resource, "resync-again");
}
}
}
@@ -1225,7 +1225,7 @@ found:
}
drbd_send_uuids(peer_device, 0, 0);
- drbd_start_resync(peer_device, L_SYNC_TARGET);
+ drbd_start_resync(peer_device, L_SYNC_TARGET, "resync-from-primary");
}
static void queue_resync_finished(struct drbd_peer_device *peer_device, enum drbd_disk_state new_peer_disk_state)
@@ -1428,7 +1428,7 @@ void drbd_resync_finished(struct drbd_peer_device *peer_device,
}
out_unlock:
- end_state_change_locked(device->resource);
+ end_state_change_locked(device->resource, "resync-finished");
put_ldev(device);
@@ -1920,7 +1920,8 @@ static bool drbd_pause_after(struct drbd_device *device)
if (!__drbd_may_sync_now(other_peer_device))
__change_resync_susp_dependency(other_peer_device, true);
}
- if (end_state_change_locked(other_device->resource) != SS_NOTHING_TO_DO)
+ if (end_state_change_locked(other_device->resource, "resync-after") !=
+ SS_NOTHING_TO_DO)
changed = true;
}
rcu_read_unlock();
@@ -1957,7 +1958,8 @@ static bool drbd_resume_next(struct drbd_device *device)
__drbd_may_sync_now(other_peer_device))
__change_resync_susp_dependency(other_peer_device, false);
}
- if (end_state_change_locked(other_device->resource) != SS_NOTHING_TO_DO)
+ if (end_state_change_locked(other_device->resource, "resync-after") !=
+ SS_NOTHING_TO_DO)
changed = true;
}
rcu_read_unlock();
@@ -2125,7 +2127,7 @@ static void do_start_resync(struct drbd_peer_device *peer_device)
return;
}
- drbd_start_resync(peer_device, peer_device->start_resync_side);
+ drbd_start_resync(peer_device, peer_device->start_resync_side, "postponed-resync");
clear_bit(AHEAD_TO_SYNC_SOURCE, &peer_device->flags);
}
@@ -2149,7 +2151,7 @@ static void handle_congestion(struct drbd_peer_device *peer_device)
else if (on_congestion == OC_DISCONNECT)
__change_cstate(peer_device->connection, C_DISCONNECTING);
}
- end_state_change(resource, &irq_flags);
+ end_state_change(resource, &irq_flags, "congestion");
}
rcu_read_unlock();
@@ -2163,7 +2165,8 @@ static void handle_congestion(struct drbd_peer_device *peer_device)
* This function might bring you directly into one of the
* C_PAUSED_SYNC_* states.
*/
-void drbd_start_resync(struct drbd_peer_device *peer_device, enum drbd_repl_state side)
+void drbd_start_resync(struct drbd_peer_device *peer_device, enum drbd_repl_state side,
+ const char *tag)
{
struct drbd_device *device = peer_device->device;
struct drbd_connection *connection = peer_device->connection;
@@ -2258,7 +2261,7 @@ skip_helper:
init_resync_stable_bits(peer_device);
finished_resync_pdsk = peer_device->resync_finished_pdsk;
peer_device->resync_finished_pdsk = D_UNKNOWN;
- r = end_state_change_locked(device->resource);
+ r = end_state_change_locked(device->resource, tag);
repl_state = peer_device->repl_state[NOW];
if (repl_state < L_ESTABLISHED)
@@ -2339,7 +2342,7 @@ static void go_diskless(struct drbd_device *device)
}
drbd_md_sync_if_dirty(device);
- change_disk_state(device, D_DISKLESS, CS_HARD, NULL);
+ change_disk_state(device, D_DISKLESS, CS_HARD, "go-diskless", NULL);
}
static int do_md_sync(struct drbd_device *device)
diff --git a/drbd/drbd_state.c b/drbd/drbd_state.c
index 23eab7f867aa..22cd134be962 100644
--- a/drbd/drbd_state.c
+++ b/drbd/drbd_state.c
@@ -74,8 +74,8 @@ struct change_disk_state_context {
static bool lost_contact_to_peer_data(enum drbd_disk_state *peer_disk_state);
static bool peer_returns_diskless(struct drbd_peer_device *peer_device,
enum drbd_disk_state os, enum drbd_disk_state ns);
-static void print_state_change(struct drbd_resource *resource, const char *prefix);
-static void finish_state_change(struct drbd_resource *);
+static void print_state_change(struct drbd_resource *resource, const char *prefix, const char *tag);
+static void finish_state_change(struct drbd_resource *, const char *tag);
static int w_after_state_change(struct drbd_work *w, int unused);
static enum drbd_state_rv is_valid_soft_transition(struct drbd_resource *);
static enum drbd_state_rv is_valid_transition(struct drbd_resource *resource);
@@ -774,7 +774,7 @@ static void queue_after_state_change_work(struct drbd_resource *resource,
}
static enum drbd_state_rv ___end_state_change(struct drbd_resource *resource, struct completion *done,
- enum drbd_state_rv rv)
+ enum drbd_state_rv rv, const char *tag)
{
enum chg_state_flags flags = resource->state_change_flags;
struct drbd_connection *connection;
@@ -793,14 +793,14 @@ static enum drbd_state_rv ___end_state_change(struct drbd_resource *resource, st
if (flags & CS_VERBOSE) {
drbd_err(resource, "State change failed: %s (%d)\n",
drbd_set_st_err_str(rv), rv);
- print_state_change(resource, "Failed: ");
+ print_state_change(resource, "Failed: ", tag);
}
goto out;
}
if (flags & CS_PREPARE)
goto out;
- finish_state_change(resource);
+ finish_state_change(resource, tag);
update_members(resource);
/* Check whether we are establishing a connection before applying the change. */
@@ -939,9 +939,9 @@ void begin_state_change_locked(struct drbd_resource *resource, enum chg_state_fl
__begin_state_change(resource);
}
-enum drbd_state_rv end_state_change_locked(struct drbd_resource *resource)
+enum drbd_state_rv end_state_change_locked(struct drbd_resource *resource, const char *tag)
{
- return ___end_state_change(resource, NULL, SS_SUCCESS);
+ return ___end_state_change(resource, NULL, SS_SUCCESS, tag);
}
void begin_state_change(struct drbd_resource *resource, unsigned long *irq_flags, enum chg_state_flags flags)
@@ -952,7 +952,8 @@ void begin_state_change(struct drbd_resource *resource, unsigned long *irq_flags
static enum drbd_state_rv __end_state_change(struct drbd_resource *resource,
unsigned long *irq_flags,
- enum drbd_state_rv rv)
+ enum drbd_state_rv rv,
+ const char *tag)
{
enum chg_state_flags flags = resource->state_change_flags;
struct completion __done, *done = NULL;
@@ -961,26 +962,27 @@ static enum drbd_state_rv __end_state_change(struct drbd_resource *resource,
done = &__done;
init_completion(done);
}
- rv = ___end_state_change(resource, done, rv);
+ rv = ___end_state_change(resource, done, rv, tag);
__state_change_unlock(resource, irq_flags, rv >= SS_SUCCESS ? done : NULL);
return rv;
}
-enum drbd_state_rv end_state_change(struct drbd_resource *resource, unsigned long *irq_flags)
+enum drbd_state_rv end_state_change(struct drbd_resource *resource, unsigned long *irq_flags,
+ const char *tag)
{
- return __end_state_change(resource, irq_flags, SS_SUCCESS);
+ return __end_state_change(resource, irq_flags, SS_SUCCESS, tag);
}
void abort_state_change(struct drbd_resource *resource, unsigned long *irq_flags)
{
resource->state_change_flags &= ~CS_VERBOSE;
- __end_state_change(resource, irq_flags, SS_UNKNOWN_ERROR);
+ __end_state_change(resource, irq_flags, SS_UNKNOWN_ERROR, NULL);
}
void abort_state_change_locked(struct drbd_resource *resource)
{
resource->state_change_flags &= ~CS_VERBOSE;
- ___end_state_change(resource, NULL, SS_UNKNOWN_ERROR);
+ ___end_state_change(resource, NULL, SS_UNKNOWN_ERROR, NULL);
}
static void begin_remote_state_change(struct drbd_resource *resource, unsigned long *irq_flags)
@@ -1159,15 +1161,19 @@ static int scnprintf_io_suspend_flags(char *buffer, size_t size,
return b - buffer;
}
-static void print_state_change(struct drbd_resource *resource, const char *prefix)
+static void print_state_change(struct drbd_resource *resource, const char *prefix, const char *tag)
{
char buffer[150], *b, *end = buffer + sizeof(buffer);
+ char tag_buffer[30] = "";
struct drbd_connection *connection;
struct drbd_device *device;
enum drbd_role *role = resource->role;
bool *fail_io = resource->fail_io;
int vnr;
+ if (tag)
+ scnprintf(tag_buffer, 30, " [%s]", tag);
+
b = buffer;
if (role[OLD] != role[NEW])
b += scnprintf(b, end - b, "role( %s -> %s ) ",
@@ -1186,7 +1192,7 @@ static void print_state_change(struct drbd_resource *resource, const char *prefi
fail_io[NEW] ? "yes" : "no");
if (b != buffer) {
*(b-1) = 0;
- drbd_info(resource, "%s%s\n", prefix, buffer);
+ drbd_info(resource, "%s%s%s\n", prefix, buffer, tag_buffer);
}
for_each_connection(connection, resource) {
@@ -1205,7 +1211,7 @@ static void print_state_change(struct drbd_resource *resource, const char *prefi
if (b != buffer) {
*(b-1) = 0;
- drbd_info(connection, "%s%s\n", prefix, buffer);
+ drbd_info(connection, "%s%s%s\n", prefix, buffer, tag_buffer);
}
}
@@ -1225,7 +1231,7 @@ static void print_state_change(struct drbd_resource *resource, const char *prefi
have_quorum[NEW] ? "yes" : "no");
if (b != buffer) {
*(b-1) = 0;
- drbd_info(device, "%s%s\n", prefix, buffer);
+ drbd_info(device, "%s%s%s\n", prefix, buffer, tag_buffer);
}
for_each_peer_device(peer_device, device) {
@@ -1253,7 +1259,7 @@ static void print_state_change(struct drbd_resource *resource, const char *prefi
if (b != buffer) {
*(b-1) = 0;
- drbd_info(peer_device, "%s%s\n", prefix, buffer);
+ drbd_info(peer_device, "%s%s%s\n", prefix, buffer, tag_buffer);
}
}
}
@@ -2543,7 +2549,7 @@ static bool should_try_become_up_to_date(struct drbd_device *device, enum drbd_d
/**
* finish_state_change - carry out actions triggered by a state change
*/
-static void finish_state_change(struct drbd_resource *resource)
+static void finish_state_change(struct drbd_resource *resource, const char *tag)
{
enum drbd_role *role = resource->role;
struct drbd_device *device;
@@ -2557,7 +2563,7 @@ static void finish_state_change(struct drbd_resource *resource)
bool unfreeze_io = false;
int vnr;
- print_state_change(resource, "");
+ print_state_change(resource, "", tag);
resource_suspended[OLD] = resource_is_suspended(resource, OLD);
resource_suspended[NEW] = resource_is_suspended(resource, NEW);
@@ -3025,7 +3031,7 @@ static void abw_start_sync(struct drbd_device *device,
if (rv) {
drbd_err(device, "Writing the bitmap failed not starting resync.\n");
- stable_change_repl_state(peer_device, L_ESTABLISHED, CS_VERBOSE);
+ stable_change_repl_state(peer_device, L_ESTABLISHED, CS_VERBOSE, "start-sync");
return;
}
@@ -3039,12 +3045,13 @@ static void abw_start_sync(struct drbd_device *device,
rcu_read_unlock();
if (peer_device->connection->agreed_pro_version < 110)
- stable_change_repl_state(peer_device, L_WF_SYNC_UUID, CS_VERBOSE);
+ stable_change_repl_state(peer_device, L_WF_SYNC_UUID, CS_VERBOSE,
+ "start-sync");
else
- drbd_start_resync(peer_device, L_SYNC_TARGET);
+ drbd_start_resync(peer_device, L_SYNC_TARGET, "start-sync");
break;
case L_STARTING_SYNC_S:
- drbd_start_resync(peer_device, L_SYNC_SOURCE);
+ drbd_start_resync(peer_device, L_SYNC_SOURCE, "start-sync");
break;
default:
break;
@@ -3531,7 +3538,7 @@ static void check_may_resume_io_after_fencing(struct drbd_state_change *state_ch
rcu_read_unlock();
begin_state_change(resource, &irq_flags, CS_VERBOSE);
__change_io_susp_fencing(connection, false);
- end_state_change(resource, &irq_flags);
+ end_state_change(resource, &irq_flags, "after-fencing");
}
/* case2: The connection was established again: */
if (all_peer_disks_connected) {
@@ -3543,7 +3550,7 @@ static void check_may_resume_io_after_fencing(struct drbd_state_change *state_ch
rcu_read_unlock();
begin_state_change(resource, &irq_flags, CS_VERBOSE);
__change_io_susp_fencing(connection, false);
- end_state_change(resource, &irq_flags);
+ end_state_change(resource, &irq_flags, "after-fencing");
}
}
@@ -4191,7 +4198,7 @@ static int w_after_state_change(struct drbd_work *w, int unused)
begin_state_change(resource, &irq_flags, CS_VERBOSE);
resource->susp_uuid[NEW] = false;
- end_state_change(resource, &irq_flags);
+ end_state_change(resource, &irq_flags, "susp-uuid");
}
if (try_become_up_to_date)
@@ -4673,7 +4680,7 @@ static void twopc_phase2(struct drbd_resource *resource,
*/
static enum drbd_state_rv
change_cluster_wide_state(bool (*change)(struct change_context *, enum change_phase),
- struct change_context *context)
+ struct change_context *context, const char *tag)
{
struct drbd_resource *resource = context->resource;
unsigned long irq_flags;
@@ -4692,11 +4699,11 @@ change_cluster_wide_state(bool (*change)(struct change_context *, enum change_ph
if (local_state_change(context->flags)) {
/* Not a cluster-wide state change. */
change(context, PH_LOCAL_COMMIT);
- return end_state_change(resource, &irq_flags);
+ return end_state_change(resource, &irq_flags, tag);
} else {
if (!change(context, PH_PREPARE)) {
/* Not a cluster-wide state change. */
- return end_state_change(resource, &irq_flags);
+ return end_state_change(resource, &irq_flags, tag);
}
rv = try_state_change(resource);
if (rv != SS_SUCCESS) {
@@ -4704,7 +4711,7 @@ change_cluster_wide_state(bool (*change)(struct change_context *, enum change_ph
/* abort_state_change(resource, &irq_flags); */
if (rv == SS_NOTHING_TO_DO)
resource->state_change_flags &= ~CS_VERBOSE;
- return __end_state_change(resource, &irq_flags, rv);
+ return __end_state_change(resource, &irq_flags, rv, tag);
}
/* Really a cluster-wide state change. */
}
@@ -4720,12 +4727,12 @@ change_cluster_wide_state(bool (*change)(struct change_context *, enum change_ph
}
if (rv >= SS_SUCCESS)
change(context, PH_84_COMMIT);
- return __end_state_change(resource, &irq_flags, rv);
+ return __end_state_change(resource, &irq_flags, rv, tag);
}
if (!expect(resource, context->flags & CS_SERIALIZE)) {
rv = SS_CW_FAILED_BY_PEER;
- return __end_state_change(resource, &irq_flags, rv);
+ return __end_state_change(resource, &irq_flags, rv, tag);
}
rcu_read_lock();
@@ -4740,7 +4747,7 @@ change_cluster_wide_state(bool (*change)(struct change_context *, enum change_ph
retry:
if (current == resource->worker.task && resource->remote_state_change)
- return __end_state_change(resource, &irq_flags, SS_CONCURRENT_ST_CHG);
+ return __end_state_change(resource, &irq_flags, SS_CONCURRENT_ST_CHG, tag);
complete_remote_state_change(resource, &irq_flags);
start_time = jiffies;
@@ -4756,7 +4763,7 @@ change_cluster_wide_state(bool (*change)(struct change_context *, enum change_ph
connection = drbd_get_connection_by_node_id(resource, context->target_node_id);
if (!connection) {
rv = SS_NEED_CONNECTION;
- return __end_state_change(resource, &irq_flags, rv);
+ return __end_state_change(resource, &irq_flags, rv, tag);
}
kref_debug_get(&connection->kref_debug, 8);
@@ -4768,7 +4775,7 @@ change_cluster_wide_state(bool (*change)(struct change_context *, enum change_ph
kref_debug_put(&connection->kref_debug, 8);
kref_put(&connection->kref, drbd_destroy_connection);
- return __end_state_change(resource, &irq_flags, rv);
+ return __end_state_change(resource, &irq_flags, rv, tag);
}
target_connection = connection;
@@ -4959,7 +4966,7 @@ change_cluster_wide_state(bool (*change)(struct change_context *, enum change_ph
clear_bit(TWOPC_STATE_CHANGE_PENDING, &resource->flags);
if (rv >= SS_SUCCESS) {
change(context, PH_COMMIT);
- rv = end_state_change(resource, &irq_flags);
+ rv = end_state_change(resource, &irq_flags, tag);
if (rv < SS_SUCCESS)
drbd_err(resource, "FATAL: Local commit of already committed %u failed! \n",
request.tid);
@@ -5276,6 +5283,7 @@ static bool do_change_role(struct change_context *context, enum change_phase pha
enum drbd_state_rv change_role(struct drbd_resource *resource,
enum drbd_role role,
enum chg_state_flags flags,
+ const char *tag,
const char **err_str)
{
struct change_context role_context = {
@@ -5310,7 +5318,7 @@ enum drbd_state_rv change_role(struct drbd_resource *resource,
}
role_context.change_local_state_last = true;
}
- rv = change_cluster_wide_state(do_change_role, &role_context);
+ rv = change_cluster_wide_state(do_change_role, &role_context, tag);
out:
if (got_state_sem)
up(&resource->state_sem);
@@ -5330,7 +5338,7 @@ enum drbd_state_rv change_io_susp_user(struct drbd_resource *resource,
begin_state_change(resource, &irq_flags, flags);
__change_io_susp_user(resource, value);
- return end_state_change(resource, &irq_flags);
+ return end_state_change(resource, &irq_flags, value ? "suspend-io" : "resume-io");
}
void __change_io_susp_no_data(struct drbd_resource *resource, bool value)
@@ -5465,7 +5473,7 @@ enum drbd_state_rv twopc_after_lost_peer(struct drbd_resource *resource,
/* The other nodes get the request for an empty state change. I.e. they
will agree to this change request. At commit time we know where to
go from the D_CONSISTENT, since we got the primary mask. */
- return change_cluster_wide_state(do_twopc_after_lost_peer, &context);
+ return change_cluster_wide_state(do_twopc_after_lost_peer, &context, "lost-peer");
}
static bool do_change_disk_state(struct change_context *context, enum change_phase phase)
@@ -5496,6 +5504,7 @@ static bool do_change_disk_state(struct change_context *context, enum change_pha
enum drbd_state_rv change_disk_state(struct drbd_device *device,
enum drbd_disk_state disk_state,
enum chg_state_flags flags,
+ const char *tag,
const char **err_str)
{
struct change_disk_state_context disk_state_context = {
@@ -5513,7 +5522,7 @@ enum drbd_state_rv change_disk_state(struct drbd_device *device,
};
return change_cluster_wide_state(do_change_disk_state,
- &disk_state_context.context);
+ &disk_state_context.context, tag);
}
void __change_cstate(struct drbd_connection *connection, enum drbd_conn_state cstate)
@@ -5683,11 +5692,11 @@ static bool do_change_cstate(struct change_context *context, enum change_phase p
* peer disks depending on the fencing policy. This cannot easily be split
* into two state changes.
*/
-enum drbd_state_rv change_cstate_es(struct drbd_connection *connection,
+enum drbd_state_rv change_cstate_tag(struct drbd_connection *connection,
enum drbd_conn_state cstate,
enum chg_state_flags flags,
- const char **err_str
- )
+ const char *tag,
+ const char **err_str)
{
struct change_cstate_context cstate_context = {
.context = {
@@ -5717,7 +5726,7 @@ enum drbd_state_rv change_cstate_es(struct drbd_connection *connection,
if (!(flags & CS_HARD))
cstate_context.context.flags |= CS_SERIALIZE;
- return change_cluster_wide_state(do_change_cstate, &cstate_context.context);
+ return change_cluster_wide_state(do_change_cstate, &cstate_context.context, tag);
}
void __change_peer_role(struct drbd_connection *connection, enum drbd_role peer_role)
@@ -5759,7 +5768,8 @@ static bool do_change_repl_state(struct change_context *context, enum change_pha
enum drbd_state_rv change_repl_state(struct drbd_peer_device *peer_device,
enum drbd_repl_state new_repl_state,
- enum chg_state_flags flags)
+ enum chg_state_flags flags,
+ const char *tag)
{
struct change_repl_context repl_context = {
.context = {
@@ -5776,15 +5786,16 @@ enum drbd_state_rv change_repl_state(struct drbd_peer_device *peer_device,
if (new_repl_state == L_WF_BITMAP_S || new_repl_state == L_VERIFY_S)
repl_context.context.change_local_state_last = true;
- return change_cluster_wide_state(do_change_repl_state, &repl_context.context);
+ return change_cluster_wide_state(do_change_repl_state, &repl_context.context, tag);
}
enum drbd_state_rv stable_change_repl_state(struct drbd_peer_device *peer_device,
enum drbd_repl_state repl_state,
- enum chg_state_flags flags)
+ enum chg_state_flags flags,
+ const char *tag)
{
return stable_state_change(peer_device->device->resource,
- change_repl_state(peer_device, repl_state, flags));
+ change_repl_state(peer_device, repl_state, flags, tag));
}
void __change_peer_disk_state(struct drbd_peer_device *peer_device, enum drbd_disk_state disk_state)
@@ -5807,14 +5818,15 @@ void __downgrade_peer_disk_states(struct drbd_connection *connection, enum drbd_
enum drbd_state_rv change_peer_disk_state(struct drbd_peer_device *peer_device,
enum drbd_disk_state disk_state,
- enum chg_state_flags flags)
+ enum chg_state_flags flags,
+ const char *tag)
{
struct drbd_resource *resource = peer_device->device->resource;
unsigned long irq_flags;
begin_state_change(resource, &irq_flags, flags);
__change_peer_disk_state(peer_device, disk_state);
- return end_state_change(resource, &irq_flags);
+ return end_state_change(resource, &irq_flags, tag);
}
void __change_resync_susp_user(struct drbd_peer_device *peer_device,
@@ -5832,7 +5844,7 @@ enum drbd_state_rv change_resync_susp_user(struct drbd_peer_device *peer_device,
begin_state_change(resource, &irq_flags, flags);
__change_resync_susp_user(peer_device, value);
- return end_state_change(resource, &irq_flags);
+ return end_state_change(resource, &irq_flags, value ? "pause-sync" : "resume-sync");
}
void __change_resync_susp_peer(struct drbd_peer_device *peer_device,
diff --git a/drbd/drbd_state.h b/drbd/drbd_state.h
index 6942f85123dd..952dea156697 100644
--- a/drbd/drbd_state.h
+++ b/drbd/drbd_state.h
@@ -56,12 +56,13 @@ extern void state_change_lock(struct drbd_resource *, unsigned long *, enum chg_
extern void state_change_unlock(struct drbd_resource *, unsigned long *);
extern void begin_state_change(struct drbd_resource *, unsigned long *, enum chg_state_flags);
-extern enum drbd_state_rv end_state_change(struct drbd_resource *, unsigned long *);
+extern enum drbd_state_rv end_state_change(struct drbd_resource *resource, unsigned long *irq_flags,
+ const char *tag);
extern void abort_state_change(struct drbd_resource *, unsigned long *);
extern void abort_state_change_locked(struct drbd_resource *resource);
extern void begin_state_change_locked(struct drbd_resource *, enum chg_state_flags);
-extern enum drbd_state_rv end_state_change_locked(struct drbd_resource *);
+extern enum drbd_state_rv end_state_change_locked(struct drbd_resource *resource, const char *tag);
extern void clear_remote_state_change(struct drbd_resource *resource);
extern void __clear_remote_state_change(struct drbd_resource *resource);
@@ -89,7 +90,11 @@ extern enum drbd_state_rv nested_twopc_request(struct drbd_resource *res, struct
extern bool drbd_twopc_between_peer_and_me(struct drbd_connection *connection);
extern bool cluster_wide_reply_ready(struct drbd_resource *);
-extern enum drbd_state_rv change_role(struct drbd_resource *, enum drbd_role, enum chg_state_flags, const char **);
+extern enum drbd_state_rv change_role(struct drbd_resource *resource,
+ enum drbd_role role,
+ enum chg_state_flags flags,
+ const char *tag,
+ const char **err_str);
extern void __change_io_susp_user(struct drbd_resource *, bool);
extern enum drbd_state_rv change_io_susp_user(struct drbd_resource *, bool, enum chg_state_flags);
@@ -99,27 +104,44 @@ extern void __change_io_susp_quorum(struct drbd_resource *, bool);
extern void __change_disk_state(struct drbd_device *, enum drbd_disk_state);
extern void __downgrade_disk_states(struct drbd_resource *, enum drbd_disk_state);
-extern enum drbd_state_rv change_disk_state(struct drbd_device *, enum drbd_disk_state, enum chg_state_flags, const char **);
+extern enum drbd_state_rv change_disk_state(struct drbd_device *device,
+ enum drbd_disk_state disk_state,
+ enum chg_state_flags flags,
+ const char *tag,
+ const char **err_str);
extern void __change_cstate(struct drbd_connection *, enum drbd_conn_state);
-extern enum drbd_state_rv change_cstate_es(struct drbd_connection *, enum drbd_conn_state, enum chg_state_flags, const char **);
+extern enum drbd_state_rv change_cstate_tag(struct drbd_connection *connection,
+ enum drbd_conn_state cstate,
+ enum chg_state_flags flags,
+ const char *tag,
+ const char **err_str);
static inline enum drbd_state_rv change_cstate(struct drbd_connection *connection,
enum drbd_conn_state cstate,
enum chg_state_flags flags)
{
- return change_cstate_es(connection, cstate, flags, NULL);
+ return change_cstate_tag(connection, cstate, flags, NULL, NULL);
}
extern void __change_peer_role(struct drbd_connection *, enum drbd_role);
extern void __change_repl_state(struct drbd_peer_device *, enum drbd_repl_state);
-extern enum drbd_state_rv change_repl_state(struct drbd_peer_device *, enum drbd_repl_state, enum chg_state_flags);
-extern enum drbd_state_rv stable_change_repl_state(struct drbd_peer_device *, enum drbd_repl_state, enum chg_state_flags);
+extern enum drbd_state_rv change_repl_state(struct drbd_peer_device *peer_device,
+ enum drbd_repl_state new_repl_state,
+ enum chg_state_flags flags,
+ const char *tag);
+extern enum drbd_state_rv stable_change_repl_state(struct drbd_peer_device *peer_device,
+ enum drbd_repl_state repl_state,
+ enum chg_state_flags flags,
+ const char *tag);
extern void __change_peer_disk_state(struct drbd_peer_device *, enum drbd_disk_state);
extern void __downgrade_peer_disk_states(struct drbd_connection *, enum drbd_disk_state);
extern void __outdate_myself(struct drbd_resource *resource);
-extern enum drbd_state_rv change_peer_disk_state(struct drbd_peer_device *, enum drbd_disk_state, enum chg_state_flags);
+extern enum drbd_state_rv change_peer_disk_state(struct drbd_peer_device *peer_device,
+ enum drbd_disk_state disk_state,
+ enum chg_state_flags flags,
+ const char *tag);
enum drbd_state_rv twopc_after_lost_peer(struct drbd_resource *resource, enum chg_state_flags);
--
2.35.3