Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003    drbd_proc.c
0004 
0005    This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
0006 
0007    Copyright (C) 2001-2008, LINBIT Information Technologies GmbH.
0008    Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>.
0009    Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
0010 
0011 
0012  */
0013 
0014 #include <linux/module.h>
0015 
0016 #include <linux/uaccess.h>
0017 #include <linux/fs.h>
0018 #include <linux/file.h>
0019 #include <linux/proc_fs.h>
0020 #include <linux/seq_file.h>
0021 #include <linux/drbd.h>
0022 #include "drbd_int.h"
0023 
0024 struct proc_dir_entry *drbd_proc;
0025 
0026 static void seq_printf_with_thousands_grouping(struct seq_file *seq, long v)
0027 {
0028     /* v is in kB/sec. We don't expect TiByte/sec yet. */
0029     if (unlikely(v >= 1000000)) {
0030         /* cool: > GiByte/s */
0031         seq_printf(seq, "%ld,", v / 1000000);
0032         v %= 1000000;
0033         seq_printf(seq, "%03ld,%03ld", v/1000, v % 1000);
0034     } else if (likely(v >= 1000))
0035         seq_printf(seq, "%ld,%03ld", v/1000, v % 1000);
0036     else
0037         seq_printf(seq, "%ld", v);
0038 }
0039 
0040 static void drbd_get_syncer_progress(struct drbd_device *device,
0041         union drbd_dev_state state, unsigned long *rs_total,
0042         unsigned long *bits_left, unsigned int *per_mil_done)
0043 {
0044     /* this is to break it at compile time when we change that, in case we
0045      * want to support more than (1<<32) bits on a 32bit arch. */
0046     typecheck(unsigned long, device->rs_total);
0047     *rs_total = device->rs_total;
0048 
0049     /* note: both rs_total and rs_left are in bits, i.e. in
0050      * units of BM_BLOCK_SIZE.
0051      * for the percentage, we don't care. */
0052 
0053     if (state.conn == C_VERIFY_S || state.conn == C_VERIFY_T)
0054         *bits_left = device->ov_left;
0055     else
0056         *bits_left = drbd_bm_total_weight(device) - device->rs_failed;
0057     /* >> 10 to prevent overflow,
0058      * +1 to prevent division by zero */
0059     if (*bits_left > *rs_total) {
0060         /* D'oh. Maybe a logic bug somewhere.  More likely just a race
0061          * between state change and reset of rs_total.
0062          */
0063         *bits_left = *rs_total;
0064         *per_mil_done = *rs_total ? 0 : 1000;
0065     } else {
0066         /* Make sure the division happens in long context.
0067          * We allow up to one petabyte storage right now,
0068          * at a granularity of 4k per bit that is 2**38 bits.
0069          * After shift right and multiplication by 1000,
0070          * this should still fit easily into a 32bit long,
0071          * so we don't need a 64bit division on 32bit arch.
0072          * Note: currently we don't support such large bitmaps on 32bit
0073          * arch anyways, but no harm done to be prepared for it here.
0074          */
0075         unsigned int shift = *rs_total > UINT_MAX ? 16 : 10;
0076         unsigned long left = *bits_left >> shift;
0077         unsigned long total = 1UL + (*rs_total >> shift);
0078         unsigned long tmp = 1000UL - left * 1000UL/total;
0079         *per_mil_done = tmp;
0080     }
0081 }
0082 
0083 
0084 /*lge
0085  * progress bars shamelessly adapted from driver/md/md.c
0086  * output looks like
0087  *  [=====>..............] 33.5% (23456/123456)
0088  *  finish: 2:20:20 speed: 6,345 (6,456) K/sec
0089  */
0090 static void drbd_syncer_progress(struct drbd_device *device, struct seq_file *seq,
0091         union drbd_dev_state state)
0092 {
0093     unsigned long db, dt, dbdt, rt, rs_total, rs_left;
0094     unsigned int res;
0095     int i, x, y;
0096     int stalled = 0;
0097 
0098     drbd_get_syncer_progress(device, state, &rs_total, &rs_left, &res);
0099 
0100     x = res/50;
0101     y = 20-x;
0102     seq_puts(seq, "\t[");
0103     for (i = 1; i < x; i++)
0104         seq_putc(seq, '=');
0105     seq_putc(seq, '>');
0106     for (i = 0; i < y; i++)
0107         seq_putc(seq, '.');
0108     seq_puts(seq, "] ");
0109 
0110     if (state.conn == C_VERIFY_S || state.conn == C_VERIFY_T)
0111         seq_puts(seq, "verified:");
0112     else
0113         seq_puts(seq, "sync'ed:");
0114     seq_printf(seq, "%3u.%u%% ", res / 10, res % 10);
0115 
0116     /* if more than a few GB, display in MB */
0117     if (rs_total > (4UL << (30 - BM_BLOCK_SHIFT)))
0118         seq_printf(seq, "(%lu/%lu)M",
0119                 (unsigned long) Bit2KB(rs_left >> 10),
0120                 (unsigned long) Bit2KB(rs_total >> 10));
0121     else
0122         seq_printf(seq, "(%lu/%lu)K",
0123                 (unsigned long) Bit2KB(rs_left),
0124                 (unsigned long) Bit2KB(rs_total));
0125 
0126     seq_puts(seq, "\n\t");
0127 
0128     /* see drivers/md/md.c
0129      * We do not want to overflow, so the order of operands and
0130      * the * 100 / 100 trick are important. We do a +1 to be
0131      * safe against division by zero. We only estimate anyway.
0132      *
0133      * dt: time from mark until now
0134      * db: blocks written from mark until now
0135      * rt: remaining time
0136      */
0137     /* Rolling marks. last_mark+1 may just now be modified.  last_mark+2 is
0138      * at least (DRBD_SYNC_MARKS-2)*DRBD_SYNC_MARK_STEP old, and has at
0139      * least DRBD_SYNC_MARK_STEP time before it will be modified. */
0140     /* ------------------------ ~18s average ------------------------ */
0141     i = (device->rs_last_mark + 2) % DRBD_SYNC_MARKS;
0142     dt = (jiffies - device->rs_mark_time[i]) / HZ;
0143     if (dt > 180)
0144         stalled = 1;
0145 
0146     if (!dt)
0147         dt++;
0148     db = device->rs_mark_left[i] - rs_left;
0149     rt = (dt * (rs_left / (db/100+1)))/100; /* seconds */
0150 
0151     seq_printf(seq, "finish: %lu:%02lu:%02lu",
0152         rt / 3600, (rt % 3600) / 60, rt % 60);
0153 
0154     dbdt = Bit2KB(db/dt);
0155     seq_puts(seq, " speed: ");
0156     seq_printf_with_thousands_grouping(seq, dbdt);
0157     seq_puts(seq, " (");
0158     /* ------------------------- ~3s average ------------------------ */
0159     if (drbd_proc_details >= 1) {
0160         /* this is what drbd_rs_should_slow_down() uses */
0161         i = (device->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS;
0162         dt = (jiffies - device->rs_mark_time[i]) / HZ;
0163         if (!dt)
0164             dt++;
0165         db = device->rs_mark_left[i] - rs_left;
0166         dbdt = Bit2KB(db/dt);
0167         seq_printf_with_thousands_grouping(seq, dbdt);
0168         seq_puts(seq, " -- ");
0169     }
0170 
0171     /* --------------------- long term average ---------------------- */
0172     /* mean speed since syncer started
0173      * we do account for PausedSync periods */
0174     dt = (jiffies - device->rs_start - device->rs_paused) / HZ;
0175     if (dt == 0)
0176         dt = 1;
0177     db = rs_total - rs_left;
0178     dbdt = Bit2KB(db/dt);
0179     seq_printf_with_thousands_grouping(seq, dbdt);
0180     seq_putc(seq, ')');
0181 
0182     if (state.conn == C_SYNC_TARGET ||
0183         state.conn == C_VERIFY_S) {
0184         seq_puts(seq, " want: ");
0185         seq_printf_with_thousands_grouping(seq, device->c_sync_rate);
0186     }
0187     seq_printf(seq, " K/sec%s\n", stalled ? " (stalled)" : "");
0188 
0189     if (drbd_proc_details >= 1) {
0190         /* 64 bit:
0191          * we convert to sectors in the display below. */
0192         unsigned long bm_bits = drbd_bm_bits(device);
0193         unsigned long bit_pos;
0194         unsigned long long stop_sector = 0;
0195         if (state.conn == C_VERIFY_S ||
0196             state.conn == C_VERIFY_T) {
0197             bit_pos = bm_bits - device->ov_left;
0198             if (verify_can_do_stop_sector(device))
0199                 stop_sector = device->ov_stop_sector;
0200         } else
0201             bit_pos = device->bm_resync_fo;
0202         /* Total sectors may be slightly off for oddly
0203          * sized devices. So what. */
0204         seq_printf(seq,
0205             "\t%3d%% sector pos: %llu/%llu",
0206             (int)(bit_pos / (bm_bits/100+1)),
0207             (unsigned long long)bit_pos * BM_SECT_PER_BIT,
0208             (unsigned long long)bm_bits * BM_SECT_PER_BIT);
0209         if (stop_sector != 0 && stop_sector != ULLONG_MAX)
0210             seq_printf(seq, " stop sector: %llu", stop_sector);
0211         seq_putc(seq, '\n');
0212     }
0213 }
0214 
0215 int drbd_seq_show(struct seq_file *seq, void *v)
0216 {
0217     int i, prev_i = -1;
0218     const char *sn;
0219     struct drbd_device *device;
0220     struct net_conf *nc;
0221     union drbd_dev_state state;
0222     char wp;
0223 
0224     static char write_ordering_chars[] = {
0225         [WO_NONE] = 'n',
0226         [WO_DRAIN_IO] = 'd',
0227         [WO_BDEV_FLUSH] = 'f',
0228     };
0229 
0230     seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n",
0231            API_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX, drbd_buildtag());
0232 
0233     /*
0234       cs .. connection state
0235       ro .. node role (local/remote)
0236       ds .. disk state (local/remote)
0237          protocol
0238          various flags
0239       ns .. network send
0240       nr .. network receive
0241       dw .. disk write
0242       dr .. disk read
0243       al .. activity log write count
0244       bm .. bitmap update write count
0245       pe .. pending (waiting for ack or data reply)
0246       ua .. unack'd (still need to send ack or data reply)
0247       ap .. application requests accepted, but not yet completed
0248       ep .. number of epochs currently "on the fly", P_BARRIER_ACK pending
0249       wo .. write ordering mode currently in use
0250      oos .. known out-of-sync kB
0251     */
0252 
0253     rcu_read_lock();
0254     idr_for_each_entry(&drbd_devices, device, i) {
0255         if (prev_i != i - 1)
0256             seq_putc(seq, '\n');
0257         prev_i = i;
0258 
0259         state = device->state;
0260         sn = drbd_conn_str(state.conn);
0261 
0262         if (state.conn == C_STANDALONE &&
0263             state.disk == D_DISKLESS &&
0264             state.role == R_SECONDARY) {
0265             seq_printf(seq, "%2d: cs:Unconfigured\n", i);
0266         } else {
0267             /* reset device->congestion_reason */
0268 
0269             nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
0270             wp = nc ? nc->wire_protocol - DRBD_PROT_A + 'A' : ' ';
0271             seq_printf(seq,
0272                "%2d: cs:%s ro:%s/%s ds:%s/%s %c %c%c%c%c%c%c\n"
0273                "    ns:%u nr:%u dw:%u dr:%u al:%u bm:%u "
0274                "lo:%d pe:%d ua:%d ap:%d ep:%d wo:%c",
0275                i, sn,
0276                drbd_role_str(state.role),
0277                drbd_role_str(state.peer),
0278                drbd_disk_str(state.disk),
0279                drbd_disk_str(state.pdsk),
0280                wp,
0281                drbd_suspended(device) ? 's' : 'r',
0282                state.aftr_isp ? 'a' : '-',
0283                state.peer_isp ? 'p' : '-',
0284                state.user_isp ? 'u' : '-',
0285                device->congestion_reason ?: '-',
0286                test_bit(AL_SUSPENDED, &device->flags) ? 's' : '-',
0287                device->send_cnt/2,
0288                device->recv_cnt/2,
0289                device->writ_cnt/2,
0290                device->read_cnt/2,
0291                device->al_writ_cnt,
0292                device->bm_writ_cnt,
0293                atomic_read(&device->local_cnt),
0294                atomic_read(&device->ap_pending_cnt) +
0295                atomic_read(&device->rs_pending_cnt),
0296                atomic_read(&device->unacked_cnt),
0297                atomic_read(&device->ap_bio_cnt),
0298                first_peer_device(device)->connection->epochs,
0299                write_ordering_chars[device->resource->write_ordering]
0300             );
0301             seq_printf(seq, " oos:%llu\n",
0302                    Bit2KB((unsigned long long)
0303                        drbd_bm_total_weight(device)));
0304         }
0305         if (state.conn == C_SYNC_SOURCE ||
0306             state.conn == C_SYNC_TARGET ||
0307             state.conn == C_VERIFY_S ||
0308             state.conn == C_VERIFY_T)
0309             drbd_syncer_progress(device, seq, state);
0310 
0311         if (drbd_proc_details >= 1 && get_ldev_if_state(device, D_FAILED)) {
0312             lc_seq_printf_stats(seq, device->resync);
0313             lc_seq_printf_stats(seq, device->act_log);
0314             put_ldev(device);
0315         }
0316 
0317         if (drbd_proc_details >= 2)
0318             seq_printf(seq, "\tblocked on activity log: %d\n", atomic_read(&device->ap_actlog_cnt));
0319     }
0320     rcu_read_unlock();
0321 
0322     return 0;
0323 }