[Drbd-dev] [PATCH] drbd: standardize kthread/workqueue thread naming to include drbd minor number

Eric Wheeler drbd-dev at lists.ewheeler.net
Tue Jan 16 00:52:15 CET 2018


From: Eric Wheeler <git at 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 <drbd at 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



More information about the drbd-dev mailing list