From: Eric Wheeler <g...@linux.ewheeler.net> For DRBD resources with long names that start with the same prefix, it was difficult to find all process pids for that minor since names are truncated to the task_struct's comm field (16 bytes).
This patch names all processes associated with a DRBD device as drbdN_* where N is the DRBD minor in the same ways that the drbdN_submit workqueue is named. Userspace tools can then lookup the name=>minor=>pid mapping and for all pids and use tools like chrt, ioprio, nice, add pids to cgroups, or for other useful purpose. Signed-off-by: Eric Wheeler <d...@linux.ewheeler.net> --- drivers/block/drbd/drbd_main.c | 31 +++++++++++++++++++++++++++++-- drivers/block/drbd/drbd_receiver.c | 19 +++++++++++++++++-- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 8cb3791..c5444b3 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -330,7 +330,21 @@ static int drbd_thread_setup(void *arg) unsigned long flags; int retval; - snprintf(current->comm, sizeof(current->comm), "drbd_%c_%s", + int i, minor = -1; + struct drbd_device *device; + + idr_for_each_entry(&resource->devices, device, i) { + if (minor >= 0 && minor != device->minor) + pr_err("drbd: %s(%s): minor is different. was %d is now %d\n", + __func__, + resource->name, + minor, device->minor); + + minor = device->minor; + } + + snprintf(current->comm, sizeof(current->comm), "drbd%d_%c_%s", + minor, thi->name[0], resource->name); @@ -389,6 +403,8 @@ int drbd_thread_start(struct drbd_thread *thi) { struct drbd_resource *resource = thi->resource; struct task_struct *nt; + struct drbd_device *device; + int i, minor = -1; unsigned long flags; /* is used from state engine doing drbd_thread_stop_nowait, @@ -417,8 +433,19 @@ int drbd_thread_start(struct drbd_thread *thi) spin_unlock_irqrestore(&thi->t_lock, flags); flush_signals(current); /* otherw. may get -ERESTARTNOINTR */ + idr_for_each_entry(&resource->devices, device, i) { + if (minor >= 0 && minor != device->minor) + pr_err("drbd: drbd_thread_start(%s, %s): minor is different. was %d is now %d\n", + thi->name, + thi->resource->name, + minor, device->minor); + + minor = device->minor; + } + nt = kthread_create(drbd_thread_setup, (void *) thi, - "drbd_%c_%s", thi->name[0], thi->resource->name); + "drbd%d_%c_%s", + minor, thi->name[0], thi->resource->name); if (IS_ERR(nt)) { drbd_err(resource, "Couldn't start thread\n"); diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 796eaf3..62a902f 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -934,7 +934,7 @@ static int conn_connect(struct drbd_connection *connection) struct drbd_socket sock, msock; struct drbd_peer_device *peer_device; struct net_conf *nc; - int vnr, timeout, h; + int vnr, timeout, h, i, minor = -1; bool discard_my_data, ok; enum drbd_state_rv rv; struct accept_wait_data ad = { @@ -1132,10 +1132,25 @@ static int conn_connect(struct drbd_connection *connection) } drbd_thread_start(&connection->ack_receiver); + + if (connection->resource) { + struct drbd_device *device; + + idr_for_each_entry(&connection->resource->devices, device, i) { + if (minor >= 0 && minor != device->minor) + pr_err("drbd: conn_connect(%s): minor is different. was %d is now %d\n", + connection->resource->name, + minor, device->minor); + + minor = device->minor; + } + } /* opencoded create_singlethread_workqueue(), * to be able to use format string arguments */ connection->ack_sender = - alloc_ordered_workqueue("drbd_as_%s", WQ_MEM_RECLAIM, connection->resource->name); + alloc_ordered_workqueue("drbd%d_as_%s", + WQ_MEM_RECLAIM, minor, connection->resource->name); + if (!connection->ack_sender) { drbd_err(connection, "Failed to create workqueue ack_sender\n"); return 0; -- 1.8.3.1