drbd_proc.c revision 81a5d60ecfe1d94627abb54810445f0fd5892f42
1b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/* 2b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner drbd_proc.c 3b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 4b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner This file is part of DRBD by Philipp Reisner and Lars Ellenberg. 5b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 6b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. 7b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner Copyright (C) 1999-2008, Philipp Reisner <philipp.reisner@linbit.com>. 8b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner Copyright (C) 2002-2008, Lars Ellenberg <lars.ellenberg@linbit.com>. 9b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 10b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner drbd is free software; you can redistribute it and/or modify 11b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner it under the terms of the GNU General Public License as published by 12b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner the Free Software Foundation; either version 2, or (at your option) 13b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner any later version. 14b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 15b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner drbd is distributed in the hope that it will be useful, 16b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner but WITHOUT ANY WARRANTY; without even the implied warranty of 17b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner GNU General Public License for more details. 19b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 20b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner You should have received a copy of the GNU General Public License 21b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner along with drbd; see the file COPYING. If not, write to 22b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 23b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 24b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner */ 25b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 26b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/module.h> 27b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 28b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <asm/uaccess.h> 29b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/fs.h> 30b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/file.h> 31b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/proc_fs.h> 32b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/seq_file.h> 33b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include <linux/drbd.h> 34b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner#include "drbd_int.h" 35b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 36b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_proc_open(struct inode *inode, struct file *file); 373da127fa887e5187ede702b835770634d705f8b2Lars Ellenbergstatic int drbd_proc_release(struct inode *inode, struct file *file); 38b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 39b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 40b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstruct proc_dir_entry *drbd_proc; 417d4e9d0962cd0f6a30b01e256756dd10606dab30Emese Revfyconst struct file_operations drbd_proc_fops = { 42b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner .owner = THIS_MODULE, 43b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner .open = drbd_proc_open, 44b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner .read = seq_read, 45b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner .llseek = seq_lseek, 463da127fa887e5187ede702b835770634d705f8b2Lars Ellenberg .release = drbd_proc_release, 47b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner}; 48b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 49439d595379f87ec95249da21122eb085866f8ba9Lars Ellenbergvoid seq_printf_with_thousands_grouping(struct seq_file *seq, long v) 50439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg{ 51439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg /* v is in kB/sec. We don't expect TiByte/sec yet. */ 52439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg if (unlikely(v >= 1000000)) { 53439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg /* cool: > GiByte/s */ 54439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg seq_printf(seq, "%ld,", v / 1000000); 55439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg v /= 1000000; 56439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg seq_printf(seq, "%03ld,%03ld", v/1000, v % 1000); 57439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg } else if (likely(v >= 1000)) 58439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg seq_printf(seq, "%ld,%03ld", v/1000, v % 1000); 59439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg else 60439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg seq_printf(seq, "%ld", v); 61439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg} 62b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 63b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/*lge 64b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * progress bars shamelessly adapted from driver/md/md.c 65b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * output looks like 66b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * [=====>..............] 33.5% (23456/123456) 67b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * finish: 2:20:20 speed: 6,345 (6,456) K/sec 68b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner */ 69b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq) 70b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{ 71b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner unsigned long db, dt, dbdt, rt, rs_left; 72b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner unsigned int res; 73b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner int i, x, y; 741d7734a0df02ff5068ff8baa1447c7baee601db1Lars Ellenberg int stalled = 0; 75b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 76b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner drbd_get_syncer_progress(mdev, &rs_left, &res); 77b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 78b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner x = res/50; 79b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner y = 20-x; 80b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, "\t["); 81b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner for (i = 1; i < x; i++) 82b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, "="); 83b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, ">"); 84b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner for (i = 0; i < y; i++) 85b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, "."); 86b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, "] "); 87b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 885f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg if (mdev->state.conn == C_VERIFY_S || mdev->state.conn == C_VERIFY_T) 895f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg seq_printf(seq, "verified:"); 905f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg else 915f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg seq_printf(seq, "sync'ed:"); 925f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg seq_printf(seq, "%3u.%u%% ", res / 10, res % 10); 935f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg 944b0715f09655e76ca24c35a9e25e7c464c2f7346Lars Ellenberg /* if more than a few GB, display in MB */ 954b0715f09655e76ca24c35a9e25e7c464c2f7346Lars Ellenberg if (mdev->rs_total > (4UL << (30 - BM_BLOCK_SHIFT))) 964b0715f09655e76ca24c35a9e25e7c464c2f7346Lars Ellenberg seq_printf(seq, "(%lu/%lu)M", 97b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner (unsigned long) Bit2KB(rs_left >> 10), 98b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner (unsigned long) Bit2KB(mdev->rs_total >> 10)); 99b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner else 100e7f52dfb4f378ea1bbfd4476f4e8ba42f5fb332cLars Ellenberg seq_printf(seq, "(%lu/%lu)K\n\t", 101b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner (unsigned long) Bit2KB(rs_left), 102b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner (unsigned long) Bit2KB(mdev->rs_total)); 103b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 104b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner /* see drivers/md/md.c 105b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * We do not want to overflow, so the order of operands and 106b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * the * 100 / 100 trick are important. We do a +1 to be 107b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * safe against division by zero. We only estimate anyway. 108b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * 109b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * dt: time from mark until now 110b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * db: blocks written from mark until now 111b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * rt: remaining time 112b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner */ 1131d7734a0df02ff5068ff8baa1447c7baee601db1Lars Ellenberg /* Rolling marks. last_mark+1 may just now be modified. last_mark+2 is 1141d7734a0df02ff5068ff8baa1447c7baee601db1Lars Ellenberg * at least (DRBD_SYNC_MARKS-2)*DRBD_SYNC_MARK_STEP old, and has at 1151d7734a0df02ff5068ff8baa1447c7baee601db1Lars Ellenberg * least DRBD_SYNC_MARK_STEP time before it will be modified. */ 116439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg /* ------------------------ ~18s average ------------------------ */ 1171d7734a0df02ff5068ff8baa1447c7baee601db1Lars Ellenberg i = (mdev->rs_last_mark + 2) % DRBD_SYNC_MARKS; 1181d7734a0df02ff5068ff8baa1447c7baee601db1Lars Ellenberg dt = (jiffies - mdev->rs_mark_time[i]) / HZ; 1191d7734a0df02ff5068ff8baa1447c7baee601db1Lars Ellenberg if (dt > (DRBD_SYNC_MARK_STEP * DRBD_SYNC_MARKS)) 1201d7734a0df02ff5068ff8baa1447c7baee601db1Lars Ellenberg stalled = 1; 121b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 122b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner if (!dt) 123b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner dt++; 1241d7734a0df02ff5068ff8baa1447c7baee601db1Lars Ellenberg db = mdev->rs_mark_left[i] - rs_left; 125b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner rt = (dt * (rs_left / (db/100+1)))/100; /* seconds */ 126b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 127b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, "finish: %lu:%02lu:%02lu", 128b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner rt / 3600, (rt % 3600) / 60, rt % 60); 129b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 130b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner dbdt = Bit2KB(db/dt); 131439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg seq_printf(seq, " speed: "); 132439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg seq_printf_with_thousands_grouping(seq, dbdt); 133439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg seq_printf(seq, " ("); 134439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg /* ------------------------- ~3s average ------------------------ */ 135439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg if (proc_details >= 1) { 136439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg /* this is what drbd_rs_should_slow_down() uses */ 137439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg i = (mdev->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS; 138439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg dt = (jiffies - mdev->rs_mark_time[i]) / HZ; 139439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg if (!dt) 140439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg dt++; 141439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg db = mdev->rs_mark_left[i] - rs_left; 142439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg dbdt = Bit2KB(db/dt); 143439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg seq_printf_with_thousands_grouping(seq, dbdt); 144439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg seq_printf(seq, " -- "); 145439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg } 146b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 147439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg /* --------------------- long term average ---------------------- */ 148b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner /* mean speed since syncer started 149b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * we do account for PausedSync periods */ 150b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner dt = (jiffies - mdev->rs_start - mdev->rs_paused) / HZ; 1512265769531afe267f864111c103b04b4427720b6Dan Carpenter if (dt == 0) 152b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner dt = 1; 153b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner db = mdev->rs_total - rs_left; 154b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner dbdt = Bit2KB(db/dt); 155439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg seq_printf_with_thousands_grouping(seq, dbdt); 156439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg seq_printf(seq, ")"); 157b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 1582649f0809f55e4df98c333a2b85c6fc8fee04804Lars Ellenberg if (mdev->state.conn == C_SYNC_TARGET || 1592649f0809f55e4df98c333a2b85c6fc8fee04804Lars Ellenberg mdev->state.conn == C_VERIFY_S) { 1605f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg seq_printf(seq, " want: "); 1615f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg seq_printf_with_thousands_grouping(seq, mdev->c_sync_rate); 1621d7734a0df02ff5068ff8baa1447c7baee601db1Lars Ellenberg } 1631d7734a0df02ff5068ff8baa1447c7baee601db1Lars Ellenberg seq_printf(seq, " K/sec%s\n", stalled ? " (stalled)" : ""); 1645f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg 1655f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg if (proc_details >= 1) { 1665f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg /* 64 bit: 1675f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg * we convert to sectors in the display below. */ 1684896e8c1b8fb7e46a65a6676e271fc047a260a3eLars Ellenberg unsigned long bm_bits = drbd_bm_bits(mdev); 1694896e8c1b8fb7e46a65a6676e271fc047a260a3eLars Ellenberg unsigned long bit_pos; 1705f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg if (mdev->state.conn == C_VERIFY_S || 1715f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg mdev->state.conn == C_VERIFY_T) 1725f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg bit_pos = bm_bits - mdev->ov_left; 1735f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg else 1745f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg bit_pos = mdev->bm_resync_fo; 1755f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg /* Total sectors may be slightly off for oddly 1765f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg * sized devices. So what. */ 1775f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg seq_printf(seq, 1785f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg "\t%3d%% sector pos: %llu/%llu\n", 1795f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg (int)(bit_pos / (bm_bits/100+1)), 1804896e8c1b8fb7e46a65a6676e271fc047a260a3eLars Ellenberg (unsigned long long)bit_pos * BM_SECT_PER_BIT, 1814896e8c1b8fb7e46a65a6676e271fc047a260a3eLars Ellenberg (unsigned long long)bm_bits * BM_SECT_PER_BIT); 1825f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg } 183b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner} 184b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 185b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic void resync_dump_detail(struct seq_file *seq, struct lc_element *e) 186b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{ 187b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner struct bm_extent *bme = lc_entry(e, struct bm_extent, lce); 188b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 189b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, "%5d %s %s\n", bme->rs_left, 190b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner bme->flags & BME_NO_WRITES ? "NO_WRITES" : "---------", 191b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner bme->flags & BME_LOCKED ? "LOCKED" : "------" 192b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner ); 193b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner} 194b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 195b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_seq_show(struct seq_file *seq, void *v) 196b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{ 19781a5d60ecfe1d94627abb54810445f0fd5892f42Philipp Reisner int i, prev_i = -1; 198b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner const char *sn; 199b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner struct drbd_conf *mdev; 200b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 201b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner static char write_ordering_chars[] = { 202b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner [WO_none] = 'n', 203b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner [WO_drain_io] = 'd', 204b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner [WO_bdev_flush] = 'f', 205b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner }; 206b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 207b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n", 208b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner API_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX, drbd_buildtag()); 209b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 210b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner /* 211b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner cs .. connection state 212b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner ro .. node role (local/remote) 213b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner ds .. disk state (local/remote) 214b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner protocol 215b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner various flags 216b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner ns .. network send 217b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner nr .. network receive 218b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner dw .. disk write 219b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner dr .. disk read 220b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner al .. activity log write count 221b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner bm .. bitmap update write count 222b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner pe .. pending (waiting for ack or data reply) 223b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner ua .. unack'd (still need to send ack or data reply) 224b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner ap .. application requests accepted, but not yet completed 225b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner ep .. number of epochs currently "on the fly", P_BARRIER_ACK pending 226b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner wo .. write ordering mode currently in use 227b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner oos .. known out-of-sync kB 228b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner */ 229b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 23081a5d60ecfe1d94627abb54810445f0fd5892f42Philipp Reisner idr_for_each_entry(&minors, mdev, i) { 23181a5d60ecfe1d94627abb54810445f0fd5892f42Philipp Reisner if (prev_i != i - 1) 232b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, "\n"); 23381a5d60ecfe1d94627abb54810445f0fd5892f42Philipp Reisner prev_i = i; 234b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 235b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner sn = drbd_conn_str(mdev->state.conn); 236b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 237b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner if (mdev->state.conn == C_STANDALONE && 238b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner mdev->state.disk == D_DISKLESS && 239b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner mdev->state.role == R_SECONDARY) { 240b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, "%2d: cs:Unconfigured\n", i); 241b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner } else { 242b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, 2430778286a133d2d3f81861a4e5db308e359583006Philipp Reisner "%2d: cs:%s ro:%s/%s ds:%s/%s %c %c%c%c%c%c%c\n" 244b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner " ns:%u nr:%u dw:%u dr:%u al:%u bm:%u " 245b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner "lo:%d pe:%d ua:%d ap:%d ep:%d wo:%c", 246b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner i, sn, 247b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner drbd_role_str(mdev->state.role), 248b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner drbd_role_str(mdev->state.peer), 249b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner drbd_disk_str(mdev->state.disk), 250b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner drbd_disk_str(mdev->state.pdsk), 25189e58e755e37137135c28a90c93be1b28faff485Philipp Reisner (mdev->tconn->net_conf == NULL ? ' ' : 25289e58e755e37137135c28a90c93be1b28faff485Philipp Reisner (mdev->tconn->net_conf->wire_protocol - DRBD_PROT_A+'A')), 253fb22c402ffdf61dd121795b5809de587185d5240Philipp Reisner is_susp(mdev->state) ? 's' : 'r', 254b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner mdev->state.aftr_isp ? 'a' : '-', 255b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner mdev->state.peer_isp ? 'p' : '-', 256b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner mdev->state.user_isp ? 'u' : '-', 257b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner mdev->congestion_reason ?: '-', 2580778286a133d2d3f81861a4e5db308e359583006Philipp Reisner test_bit(AL_SUSPENDED, &mdev->flags) ? 's' : '-', 259b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner mdev->send_cnt/2, 260b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner mdev->recv_cnt/2, 261b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner mdev->writ_cnt/2, 262b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner mdev->read_cnt/2, 263b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner mdev->al_writ_cnt, 264b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner mdev->bm_writ_cnt, 265b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner atomic_read(&mdev->local_cnt), 266b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner atomic_read(&mdev->ap_pending_cnt) + 267b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner atomic_read(&mdev->rs_pending_cnt), 268b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner atomic_read(&mdev->unacked_cnt), 269b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner atomic_read(&mdev->ap_bio_cnt), 270b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner mdev->epochs, 271b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner write_ordering_chars[mdev->write_ordering] 272b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner ); 27318edc0b9d7dac2f74117a0bdb98f2e705eb74d82Lars Ellenberg seq_printf(seq, " oos:%llu\n", 27418edc0b9d7dac2f74117a0bdb98f2e705eb74d82Lars Ellenberg Bit2KB((unsigned long long) 27518edc0b9d7dac2f74117a0bdb98f2e705eb74d82Lars Ellenberg drbd_bm_total_weight(mdev))); 276b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner } 277b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner if (mdev->state.conn == C_SYNC_SOURCE || 278439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg mdev->state.conn == C_SYNC_TARGET || 279439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg mdev->state.conn == C_VERIFY_S || 280439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg mdev->state.conn == C_VERIFY_T) 281b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner drbd_syncer_progress(mdev, seq); 282b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 283b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner if (proc_details >= 1 && get_ldev_if_state(mdev, D_FAILED)) { 284b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner lc_seq_printf_stats(seq, mdev->resync); 285b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner lc_seq_printf_stats(seq, mdev->act_log); 286b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner put_ldev(mdev); 287b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner } 288b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 289b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner if (proc_details >= 2) { 290b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner if (mdev->resync) { 291b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner lc_seq_dump_details(seq, mdev->resync, "rs_left", 292b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner resync_dump_detail); 293b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner } 294b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner } 295b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner } 296b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 297b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner return 0; 298b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner} 299b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 300b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_proc_open(struct inode *inode, struct file *file) 301b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{ 3023da127fa887e5187ede702b835770634d705f8b2Lars Ellenberg if (try_module_get(THIS_MODULE)) 3033da127fa887e5187ede702b835770634d705f8b2Lars Ellenberg return single_open(file, drbd_seq_show, PDE(inode)->data); 3043da127fa887e5187ede702b835770634d705f8b2Lars Ellenberg return -ENODEV; 3053da127fa887e5187ede702b835770634d705f8b2Lars Ellenberg} 3063da127fa887e5187ede702b835770634d705f8b2Lars Ellenberg 3073da127fa887e5187ede702b835770634d705f8b2Lars Ellenbergstatic int drbd_proc_release(struct inode *inode, struct file *file) 3083da127fa887e5187ede702b835770634d705f8b2Lars Ellenberg{ 3093da127fa887e5187ede702b835770634d705f8b2Lars Ellenberg module_put(THIS_MODULE); 3103da127fa887e5187ede702b835770634d705f8b2Lars Ellenberg return single_release(inode, file); 311b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner} 312b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 313b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/* PROC FS stuff end */ 314