blob: 74ef29247bb5920fe9572807aa0f067b7bbc6fe3 [file] [log] [blame]
Philipp Reisnerb411b362009-09-25 16:07:19 -07001/*
2 drbd_proc.c
3
4 This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
5
6 Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
7 Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
8 Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
9
10 drbd is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 drbd is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with drbd; see the file COPYING. If not, write to
22 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23
24 */
25
Philipp Reisnerb411b362009-09-25 16:07:19 -070026#include <linux/module.h>
27
Fabian Frederick7e5fec32016-06-14 00:26:35 +020028#include <linux/uaccess.h>
Philipp Reisnerb411b362009-09-25 16:07:19 -070029#include <linux/fs.h>
30#include <linux/file.h>
Philipp Reisnerb411b362009-09-25 16:07:19 -070031#include <linux/proc_fs.h>
32#include <linux/seq_file.h>
33#include <linux/drbd.h>
34#include "drbd_int.h"
35
Philipp Reisnerb411b362009-09-25 16:07:19 -070036struct proc_dir_entry *drbd_proc;
Philipp Reisnerb411b362009-09-25 16:07:19 -070037
Rashika Kheriafbe0d912013-12-19 15:04:47 +053038static void seq_printf_with_thousands_grouping(struct seq_file *seq, long v)
Lars Ellenberg439d5952010-11-05 09:52:46 +010039{
40 /* v is in kB/sec. We don't expect TiByte/sec yet. */
41 if (unlikely(v >= 1000000)) {
42 /* cool: > GiByte/s */
43 seq_printf(seq, "%ld,", v / 1000000);
Lars Ellenbergfc251d52011-06-03 21:13:17 +020044 v %= 1000000;
Lars Ellenberg439d5952010-11-05 09:52:46 +010045 seq_printf(seq, "%03ld,%03ld", v/1000, v % 1000);
46 } else if (likely(v >= 1000))
47 seq_printf(seq, "%ld,%03ld", v/1000, v % 1000);
48 else
49 seq_printf(seq, "%ld", v);
50}
Philipp Reisnerb411b362009-09-25 16:07:19 -070051
Lars Ellenberga5655da2014-03-11 13:47:55 +010052static void drbd_get_syncer_progress(struct drbd_device *device,
53 union drbd_dev_state state, unsigned long *rs_total,
54 unsigned long *bits_left, unsigned int *per_mil_done)
55{
56 /* this is to break it at compile time when we change that, in case we
57 * want to support more than (1<<32) bits on a 32bit arch. */
58 typecheck(unsigned long, device->rs_total);
59 *rs_total = device->rs_total;
60
61 /* note: both rs_total and rs_left are in bits, i.e. in
62 * units of BM_BLOCK_SIZE.
63 * for the percentage, we don't care. */
64
65 if (state.conn == C_VERIFY_S || state.conn == C_VERIFY_T)
66 *bits_left = device->ov_left;
67 else
68 *bits_left = drbd_bm_total_weight(device) - device->rs_failed;
69 /* >> 10 to prevent overflow,
70 * +1 to prevent division by zero */
71 if (*bits_left > *rs_total) {
72 /* D'oh. Maybe a logic bug somewhere. More likely just a race
73 * between state change and reset of rs_total.
74 */
75 *bits_left = *rs_total;
76 *per_mil_done = *rs_total ? 0 : 1000;
77 } else {
78 /* Make sure the division happens in long context.
79 * We allow up to one petabyte storage right now,
80 * at a granularity of 4k per bit that is 2**38 bits.
81 * After shift right and multiplication by 1000,
82 * this should still fit easily into a 32bit long,
83 * so we don't need a 64bit division on 32bit arch.
84 * Note: currently we don't support such large bitmaps on 32bit
85 * arch anyways, but no harm done to be prepared for it here.
86 */
87 unsigned int shift = *rs_total > UINT_MAX ? 16 : 10;
88 unsigned long left = *bits_left >> shift;
89 unsigned long total = 1UL + (*rs_total >> shift);
90 unsigned long tmp = 1000UL - left * 1000UL/total;
91 *per_mil_done = tmp;
92 }
93}
94
95
Philipp Reisnerb411b362009-09-25 16:07:19 -070096/*lge
97 * progress bars shamelessly adapted from driver/md/md.c
98 * output looks like
99 * [=====>..............] 33.5% (23456/123456)
100 * finish: 2:20:20 speed: 6,345 (6,456) K/sec
101 */
Lars Ellenberga5655da2014-03-11 13:47:55 +0100102static void drbd_syncer_progress(struct drbd_device *device, struct seq_file *seq,
103 union drbd_dev_state state)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700104{
Lars Ellenberga5655da2014-03-11 13:47:55 +0100105 unsigned long db, dt, dbdt, rt, rs_total, rs_left;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700106 unsigned int res;
107 int i, x, y;
Lars Ellenberg1d7734a2010-08-11 21:21:50 +0200108 int stalled = 0;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700109
Lars Ellenberga5655da2014-03-11 13:47:55 +0100110 drbd_get_syncer_progress(device, state, &rs_total, &rs_left, &res);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700111
112 x = res/50;
113 y = 20-x;
Fabian Frederick7e5fec32016-06-14 00:26:35 +0200114 seq_puts(seq, "\t[");
Philipp Reisnerb411b362009-09-25 16:07:19 -0700115 for (i = 1; i < x; i++)
Fabian Frederick7e5fec32016-06-14 00:26:35 +0200116 seq_putc(seq, '=');
117 seq_putc(seq, '>');
Philipp Reisnerb411b362009-09-25 16:07:19 -0700118 for (i = 0; i < y; i++)
Markus Elfring427fd2b2017-08-29 10:20:42 +0200119 seq_putc(seq, '.');
Fabian Frederick7e5fec32016-06-14 00:26:35 +0200120 seq_puts(seq, "] ");
Philipp Reisnerb411b362009-09-25 16:07:19 -0700121
Lars Ellenberga5655da2014-03-11 13:47:55 +0100122 if (state.conn == C_VERIFY_S || state.conn == C_VERIFY_T)
Fabian Frederick7e5fec32016-06-14 00:26:35 +0200123 seq_puts(seq, "verified:");
Lars Ellenberg5f9915b2010-11-09 14:15:24 +0100124 else
Fabian Frederick7e5fec32016-06-14 00:26:35 +0200125 seq_puts(seq, "sync'ed:");
Lars Ellenberg5f9915b2010-11-09 14:15:24 +0100126 seq_printf(seq, "%3u.%u%% ", res / 10, res % 10);
127
Lars Ellenberg4b0715f2010-12-14 15:13:04 +0100128 /* if more than a few GB, display in MB */
Lars Ellenberga5655da2014-03-11 13:47:55 +0100129 if (rs_total > (4UL << (30 - BM_BLOCK_SHIFT)))
Lars Ellenberg4b0715f2010-12-14 15:13:04 +0100130 seq_printf(seq, "(%lu/%lu)M",
Philipp Reisnerb411b362009-09-25 16:07:19 -0700131 (unsigned long) Bit2KB(rs_left >> 10),
Lars Ellenberga5655da2014-03-11 13:47:55 +0100132 (unsigned long) Bit2KB(rs_total >> 10));
Philipp Reisnerb411b362009-09-25 16:07:19 -0700133 else
Philipp Reisner590001c2014-09-11 14:29:13 +0200134 seq_printf(seq, "(%lu/%lu)K",
Philipp Reisnerb411b362009-09-25 16:07:19 -0700135 (unsigned long) Bit2KB(rs_left),
Lars Ellenberga5655da2014-03-11 13:47:55 +0100136 (unsigned long) Bit2KB(rs_total));
Philipp Reisnerb411b362009-09-25 16:07:19 -0700137
Fabian Frederick7e5fec32016-06-14 00:26:35 +0200138 seq_puts(seq, "\n\t");
Philipp Reisner590001c2014-09-11 14:29:13 +0200139
Philipp Reisnerb411b362009-09-25 16:07:19 -0700140 /* see drivers/md/md.c
141 * We do not want to overflow, so the order of operands and
142 * the * 100 / 100 trick are important. We do a +1 to be
143 * safe against division by zero. We only estimate anyway.
144 *
145 * dt: time from mark until now
146 * db: blocks written from mark until now
147 * rt: remaining time
148 */
Lars Ellenberg1d7734a2010-08-11 21:21:50 +0200149 /* Rolling marks. last_mark+1 may just now be modified. last_mark+2 is
150 * at least (DRBD_SYNC_MARKS-2)*DRBD_SYNC_MARK_STEP old, and has at
151 * least DRBD_SYNC_MARK_STEP time before it will be modified. */
Lars Ellenberg439d5952010-11-05 09:52:46 +0100152 /* ------------------------ ~18s average ------------------------ */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200153 i = (device->rs_last_mark + 2) % DRBD_SYNC_MARKS;
154 dt = (jiffies - device->rs_mark_time[i]) / HZ;
Lars Ellenberg9ae47262014-04-28 18:43:16 +0200155 if (dt > 180)
Lars Ellenberg1d7734a2010-08-11 21:21:50 +0200156 stalled = 1;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700157
158 if (!dt)
159 dt++;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200160 db = device->rs_mark_left[i] - rs_left;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700161 rt = (dt * (rs_left / (db/100+1)))/100; /* seconds */
162
163 seq_printf(seq, "finish: %lu:%02lu:%02lu",
164 rt / 3600, (rt % 3600) / 60, rt % 60);
165
Philipp Reisnerb411b362009-09-25 16:07:19 -0700166 dbdt = Bit2KB(db/dt);
Fabian Frederick7e5fec32016-06-14 00:26:35 +0200167 seq_puts(seq, " speed: ");
Lars Ellenberg439d5952010-11-05 09:52:46 +0100168 seq_printf_with_thousands_grouping(seq, dbdt);
Fabian Frederick7e5fec32016-06-14 00:26:35 +0200169 seq_puts(seq, " (");
Lars Ellenberg439d5952010-11-05 09:52:46 +0100170 /* ------------------------- ~3s average ------------------------ */
Roland Kammerer183ece32017-08-29 10:20:46 +0200171 if (drbd_proc_details >= 1) {
Lars Ellenberg439d5952010-11-05 09:52:46 +0100172 /* this is what drbd_rs_should_slow_down() uses */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200173 i = (device->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS;
174 dt = (jiffies - device->rs_mark_time[i]) / HZ;
Lars Ellenberg439d5952010-11-05 09:52:46 +0100175 if (!dt)
176 dt++;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200177 db = device->rs_mark_left[i] - rs_left;
Lars Ellenberg439d5952010-11-05 09:52:46 +0100178 dbdt = Bit2KB(db/dt);
179 seq_printf_with_thousands_grouping(seq, dbdt);
Fabian Frederick7e5fec32016-06-14 00:26:35 +0200180 seq_puts(seq, " -- ");
Lars Ellenberg439d5952010-11-05 09:52:46 +0100181 }
182
183 /* --------------------- long term average ---------------------- */
Philipp Reisnerb411b362009-09-25 16:07:19 -0700184 /* mean speed since syncer started
185 * we do account for PausedSync periods */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200186 dt = (jiffies - device->rs_start - device->rs_paused) / HZ;
Dan Carpenter22657692010-08-12 00:38:45 +0200187 if (dt == 0)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700188 dt = 1;
Lars Ellenberga5655da2014-03-11 13:47:55 +0100189 db = rs_total - rs_left;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700190 dbdt = Bit2KB(db/dt);
Lars Ellenberg439d5952010-11-05 09:52:46 +0100191 seq_printf_with_thousands_grouping(seq, dbdt);
Fabian Frederick7e5fec32016-06-14 00:26:35 +0200192 seq_putc(seq, ')');
Philipp Reisnerb411b362009-09-25 16:07:19 -0700193
Lars Ellenberga5655da2014-03-11 13:47:55 +0100194 if (state.conn == C_SYNC_TARGET ||
195 state.conn == C_VERIFY_S) {
Fabian Frederick7e5fec32016-06-14 00:26:35 +0200196 seq_puts(seq, " want: ");
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200197 seq_printf_with_thousands_grouping(seq, device->c_sync_rate);
Lars Ellenberg1d7734a2010-08-11 21:21:50 +0200198 }
199 seq_printf(seq, " K/sec%s\n", stalled ? " (stalled)" : "");
Lars Ellenberg5f9915b2010-11-09 14:15:24 +0100200
Roland Kammerer183ece32017-08-29 10:20:46 +0200201 if (drbd_proc_details >= 1) {
Lars Ellenberg5f9915b2010-11-09 14:15:24 +0100202 /* 64 bit:
203 * we convert to sectors in the display below. */
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200204 unsigned long bm_bits = drbd_bm_bits(device);
Lars Ellenberg4896e8c2010-11-11 22:41:04 +0100205 unsigned long bit_pos;
Lars Ellenberg58ffa582012-07-26 14:09:49 +0200206 unsigned long long stop_sector = 0;
Lars Ellenberga5655da2014-03-11 13:47:55 +0100207 if (state.conn == C_VERIFY_S ||
208 state.conn == C_VERIFY_T) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200209 bit_pos = bm_bits - device->ov_left;
210 if (verify_can_do_stop_sector(device))
211 stop_sector = device->ov_stop_sector;
Lars Ellenberg58ffa582012-07-26 14:09:49 +0200212 } else
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200213 bit_pos = device->bm_resync_fo;
Lars Ellenberg5f9915b2010-11-09 14:15:24 +0100214 /* Total sectors may be slightly off for oddly
215 * sized devices. So what. */
216 seq_printf(seq,
Lars Ellenberg58ffa582012-07-26 14:09:49 +0200217 "\t%3d%% sector pos: %llu/%llu",
Lars Ellenberg5f9915b2010-11-09 14:15:24 +0100218 (int)(bit_pos / (bm_bits/100+1)),
Lars Ellenberg4896e8c2010-11-11 22:41:04 +0100219 (unsigned long long)bit_pos * BM_SECT_PER_BIT,
220 (unsigned long long)bm_bits * BM_SECT_PER_BIT);
Lars Ellenberg58ffa582012-07-26 14:09:49 +0200221 if (stop_sector != 0 && stop_sector != ULLONG_MAX)
222 seq_printf(seq, " stop sector: %llu", stop_sector);
Fabian Frederick7e5fec32016-06-14 00:26:35 +0200223 seq_putc(seq, '\n');
Lars Ellenberg5f9915b2010-11-09 14:15:24 +0100224 }
Philipp Reisnerb411b362009-09-25 16:07:19 -0700225}
226
Christoph Hellwig004fd112018-04-11 16:46:11 +0200227int drbd_seq_show(struct seq_file *seq, void *v)
Philipp Reisnerb411b362009-09-25 16:07:19 -0700228{
Philipp Reisner81a5d602011-02-22 19:53:16 -0500229 int i, prev_i = -1;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700230 const char *sn;
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200231 struct drbd_device *device;
Philipp Reisner44ed1672011-04-19 17:10:19 +0200232 struct net_conf *nc;
Lars Ellenberga5655da2014-03-11 13:47:55 +0100233 union drbd_dev_state state;
Philipp Reisner44ed1672011-04-19 17:10:19 +0200234 char wp;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700235
236 static char write_ordering_chars[] = {
Andreas Gruenbacherf6ba8632014-08-13 18:33:55 +0200237 [WO_NONE] = 'n',
238 [WO_DRAIN_IO] = 'd',
239 [WO_BDEV_FLUSH] = 'f',
Philipp Reisnerb411b362009-09-25 16:07:19 -0700240 };
241
242 seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n",
243 API_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX, drbd_buildtag());
244
245 /*
246 cs .. connection state
247 ro .. node role (local/remote)
248 ds .. disk state (local/remote)
249 protocol
250 various flags
251 ns .. network send
252 nr .. network receive
253 dw .. disk write
254 dr .. disk read
255 al .. activity log write count
256 bm .. bitmap update write count
257 pe .. pending (waiting for ack or data reply)
258 ua .. unack'd (still need to send ack or data reply)
259 ap .. application requests accepted, but not yet completed
260 ep .. number of epochs currently "on the fly", P_BARRIER_ACK pending
261 wo .. write ordering mode currently in use
262 oos .. known out-of-sync kB
263 */
264
Philipp Reisnerc141ebd2011-05-05 16:13:10 +0200265 rcu_read_lock();
Andreas Gruenbacher05a10ec2011-06-07 22:54:17 +0200266 idr_for_each_entry(&drbd_devices, device, i) {
Philipp Reisner81a5d602011-02-22 19:53:16 -0500267 if (prev_i != i - 1)
Fabian Frederick7e5fec32016-06-14 00:26:35 +0200268 seq_putc(seq, '\n');
Philipp Reisner81a5d602011-02-22 19:53:16 -0500269 prev_i = i;
Philipp Reisnerb411b362009-09-25 16:07:19 -0700270
Lars Ellenberga5655da2014-03-11 13:47:55 +0100271 state = device->state;
272 sn = drbd_conn_str(state.conn);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700273
Lars Ellenberga5655da2014-03-11 13:47:55 +0100274 if (state.conn == C_STANDALONE &&
275 state.disk == D_DISKLESS &&
276 state.role == R_SECONDARY) {
Philipp Reisnerb411b362009-09-25 16:07:19 -0700277 seq_printf(seq, "%2d: cs:Unconfigured\n", i);
278 } else {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200279 /* reset device->congestion_reason */
Jan Karadc3b17c2017-02-02 15:56:50 +0100280 bdi_rw_congested(device->rq_queue->backing_dev_info);
Lars Ellenberg8a943172012-07-30 09:09:36 +0200281
Andreas Gruenbachera6b32bc2011-05-31 14:33:49 +0200282 nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
Philipp Reisner44ed1672011-04-19 17:10:19 +0200283 wp = nc ? nc->wire_protocol - DRBD_PROT_A + 'A' : ' ';
Philipp Reisnerb411b362009-09-25 16:07:19 -0700284 seq_printf(seq,
Philipp Reisner07782862010-08-31 12:00:50 +0200285 "%2d: cs:%s ro:%s/%s ds:%s/%s %c %c%c%c%c%c%c\n"
Philipp Reisnerb411b362009-09-25 16:07:19 -0700286 " ns:%u nr:%u dw:%u dr:%u al:%u bm:%u "
287 "lo:%d pe:%d ua:%d ap:%d ep:%d wo:%c",
288 i, sn,
Lars Ellenberga5655da2014-03-11 13:47:55 +0100289 drbd_role_str(state.role),
290 drbd_role_str(state.peer),
291 drbd_disk_str(state.disk),
292 drbd_disk_str(state.pdsk),
Philipp Reisner44ed1672011-04-19 17:10:19 +0200293 wp,
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200294 drbd_suspended(device) ? 's' : 'r',
Lars Ellenberga5655da2014-03-11 13:47:55 +0100295 state.aftr_isp ? 'a' : '-',
296 state.peer_isp ? 'p' : '-',
297 state.user_isp ? 'u' : '-',
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200298 device->congestion_reason ?: '-',
299 test_bit(AL_SUSPENDED, &device->flags) ? 's' : '-',
300 device->send_cnt/2,
301 device->recv_cnt/2,
302 device->writ_cnt/2,
303 device->read_cnt/2,
304 device->al_writ_cnt,
305 device->bm_writ_cnt,
306 atomic_read(&device->local_cnt),
307 atomic_read(&device->ap_pending_cnt) +
308 atomic_read(&device->rs_pending_cnt),
309 atomic_read(&device->unacked_cnt),
310 atomic_read(&device->ap_bio_cnt),
Andreas Gruenbachera6b32bc2011-05-31 14:33:49 +0200311 first_peer_device(device)->connection->epochs,
Philipp Reisnere9526582013-11-22 15:53:41 +0100312 write_ordering_chars[device->resource->write_ordering]
Philipp Reisnerb411b362009-09-25 16:07:19 -0700313 );
Lars Ellenberg18edc0b2010-11-09 14:12:10 +0100314 seq_printf(seq, " oos:%llu\n",
315 Bit2KB((unsigned long long)
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200316 drbd_bm_total_weight(device)));
Philipp Reisnerb411b362009-09-25 16:07:19 -0700317 }
Lars Ellenberga5655da2014-03-11 13:47:55 +0100318 if (state.conn == C_SYNC_SOURCE ||
319 state.conn == C_SYNC_TARGET ||
320 state.conn == C_VERIFY_S ||
321 state.conn == C_VERIFY_T)
322 drbd_syncer_progress(device, seq, state);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700323
Roland Kammerer183ece32017-08-29 10:20:46 +0200324 if (drbd_proc_details >= 1 && get_ldev_if_state(device, D_FAILED)) {
Andreas Gruenbacherb30ab792011-07-03 13:26:43 +0200325 lc_seq_printf_stats(seq, device->resync);
326 lc_seq_printf_stats(seq, device->act_log);
327 put_ldev(device);
Philipp Reisnerb411b362009-09-25 16:07:19 -0700328 }
Lars Ellenbergad3fee72013-12-20 11:22:13 +0100329
Roland Kammerer183ece32017-08-29 10:20:46 +0200330 if (drbd_proc_details >= 2)
Lars Ellenbergad3fee72013-12-20 11:22:13 +0100331 seq_printf(seq, "\tblocked on activity log: %d\n", atomic_read(&device->ap_actlog_cnt));
Philipp Reisnerb411b362009-09-25 16:07:19 -0700332 }
Philipp Reisnerc141ebd2011-05-05 16:13:10 +0200333 rcu_read_unlock();
Philipp Reisnerb411b362009-09-25 16:07:19 -0700334
335 return 0;
336}