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 49fbe0d91ca32243b3471ddd5fc50f954785c71a82Rashika Kheriastatic void 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); 55fc251d5c2466413fdd6851e6c3f63e9851bf9d84Lars 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 63a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenbergstatic void drbd_get_syncer_progress(struct drbd_device *device, 64a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg union drbd_dev_state state, unsigned long *rs_total, 65a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg unsigned long *bits_left, unsigned int *per_mil_done) 66a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg{ 67a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg /* this is to break it at compile time when we change that, in case we 68a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg * want to support more than (1<<32) bits on a 32bit arch. */ 69a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg typecheck(unsigned long, device->rs_total); 70a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg *rs_total = device->rs_total; 71a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg 72a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg /* note: both rs_total and rs_left are in bits, i.e. in 73a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg * units of BM_BLOCK_SIZE. 74a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg * for the percentage, we don't care. */ 75a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg 76a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg if (state.conn == C_VERIFY_S || state.conn == C_VERIFY_T) 77a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg *bits_left = device->ov_left; 78a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg else 79a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg *bits_left = drbd_bm_total_weight(device) - device->rs_failed; 80a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg /* >> 10 to prevent overflow, 81a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg * +1 to prevent division by zero */ 82a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg if (*bits_left > *rs_total) { 83a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg /* D'oh. Maybe a logic bug somewhere. More likely just a race 84a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg * between state change and reset of rs_total. 85a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg */ 86a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg *bits_left = *rs_total; 87a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg *per_mil_done = *rs_total ? 0 : 1000; 88a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg } else { 89a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg /* Make sure the division happens in long context. 90a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg * We allow up to one petabyte storage right now, 91a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg * at a granularity of 4k per bit that is 2**38 bits. 92a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg * After shift right and multiplication by 1000, 93a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg * this should still fit easily into a 32bit long, 94a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg * so we don't need a 64bit division on 32bit arch. 95a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg * Note: currently we don't support such large bitmaps on 32bit 96a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg * arch anyways, but no harm done to be prepared for it here. 97a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg */ 98a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg unsigned int shift = *rs_total > UINT_MAX ? 16 : 10; 99a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg unsigned long left = *bits_left >> shift; 100a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg unsigned long total = 1UL + (*rs_total >> shift); 101a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg unsigned long tmp = 1000UL - left * 1000UL/total; 102a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg *per_mil_done = tmp; 103a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg } 104a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg} 105a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg 106a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg 107b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/*lge 108b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * progress bars shamelessly adapted from driver/md/md.c 109b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * output looks like 110b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * [=====>..............] 33.5% (23456/123456) 111b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * finish: 2:20:20 speed: 6,345 (6,456) K/sec 112b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner */ 113a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenbergstatic void drbd_syncer_progress(struct drbd_device *device, struct seq_file *seq, 114a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg union drbd_dev_state state) 115b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{ 116a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg unsigned long db, dt, dbdt, rt, rs_total, rs_left; 117b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner unsigned int res; 118b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner int i, x, y; 1191d7734a0df02ff5068ff8baa1447c7baee601db1Lars Ellenberg int stalled = 0; 120b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 121a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg drbd_get_syncer_progress(device, state, &rs_total, &rs_left, &res); 122b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 123b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner x = res/50; 124b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner y = 20-x; 125b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, "\t["); 126b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner for (i = 1; i < x; i++) 127b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, "="); 128b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, ">"); 129b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner for (i = 0; i < y; i++) 130b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, "."); 131b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, "] "); 132b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 133a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg if (state.conn == C_VERIFY_S || state.conn == C_VERIFY_T) 1345f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg seq_printf(seq, "verified:"); 1355f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg else 1365f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg seq_printf(seq, "sync'ed:"); 1375f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg seq_printf(seq, "%3u.%u%% ", res / 10, res % 10); 1385f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg 1394b0715f09655e76ca24c35a9e25e7c464c2f7346Lars Ellenberg /* if more than a few GB, display in MB */ 140a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg if (rs_total > (4UL << (30 - BM_BLOCK_SHIFT))) 1414b0715f09655e76ca24c35a9e25e7c464c2f7346Lars Ellenberg seq_printf(seq, "(%lu/%lu)M", 142b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner (unsigned long) Bit2KB(rs_left >> 10), 143a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg (unsigned long) Bit2KB(rs_total >> 10)); 144b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner else 145590001c229e86a0adab4a61a6d668940d7ce5299Philipp Reisner seq_printf(seq, "(%lu/%lu)K", 146b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner (unsigned long) Bit2KB(rs_left), 147a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg (unsigned long) Bit2KB(rs_total)); 148b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 149590001c229e86a0adab4a61a6d668940d7ce5299Philipp Reisner seq_printf(seq, "\n\t"); 150590001c229e86a0adab4a61a6d668940d7ce5299Philipp Reisner 151b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner /* see drivers/md/md.c 152b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * We do not want to overflow, so the order of operands and 153b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * the * 100 / 100 trick are important. We do a +1 to be 154b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * safe against division by zero. We only estimate anyway. 155b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * 156b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * dt: time from mark until now 157b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * db: blocks written from mark until now 158b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * rt: remaining time 159b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner */ 1601d7734a0df02ff5068ff8baa1447c7baee601db1Lars Ellenberg /* Rolling marks. last_mark+1 may just now be modified. last_mark+2 is 1611d7734a0df02ff5068ff8baa1447c7baee601db1Lars Ellenberg * at least (DRBD_SYNC_MARKS-2)*DRBD_SYNC_MARK_STEP old, and has at 1621d7734a0df02ff5068ff8baa1447c7baee601db1Lars Ellenberg * least DRBD_SYNC_MARK_STEP time before it will be modified. */ 163439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg /* ------------------------ ~18s average ------------------------ */ 164b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher i = (device->rs_last_mark + 2) % DRBD_SYNC_MARKS; 165b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher dt = (jiffies - device->rs_mark_time[i]) / HZ; 1669ae472605ad333d4db07da95cc42c68063d2cc0dLars Ellenberg if (dt > 180) 1671d7734a0df02ff5068ff8baa1447c7baee601db1Lars Ellenberg stalled = 1; 168b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 169b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner if (!dt) 170b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner dt++; 171b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher db = device->rs_mark_left[i] - rs_left; 172b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner rt = (dt * (rs_left / (db/100+1)))/100; /* seconds */ 173b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 174b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, "finish: %lu:%02lu:%02lu", 175b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner rt / 3600, (rt % 3600) / 60, rt % 60); 176b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 177b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner dbdt = Bit2KB(db/dt); 178439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg seq_printf(seq, " speed: "); 179439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg seq_printf_with_thousands_grouping(seq, dbdt); 180439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg seq_printf(seq, " ("); 181439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg /* ------------------------- ~3s average ------------------------ */ 182439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg if (proc_details >= 1) { 183439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg /* this is what drbd_rs_should_slow_down() uses */ 184b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher i = (device->rs_last_mark + DRBD_SYNC_MARKS-1) % DRBD_SYNC_MARKS; 185b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher dt = (jiffies - device->rs_mark_time[i]) / HZ; 186439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg if (!dt) 187439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg dt++; 188b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher db = device->rs_mark_left[i] - rs_left; 189439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg dbdt = Bit2KB(db/dt); 190439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg seq_printf_with_thousands_grouping(seq, dbdt); 191439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg seq_printf(seq, " -- "); 192439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg } 193b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 194439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg /* --------------------- long term average ---------------------- */ 195b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner /* mean speed since syncer started 196b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner * we do account for PausedSync periods */ 197b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher dt = (jiffies - device->rs_start - device->rs_paused) / HZ; 1982265769531afe267f864111c103b04b4427720b6Dan Carpenter if (dt == 0) 199b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner dt = 1; 200a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg db = rs_total - rs_left; 201b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner dbdt = Bit2KB(db/dt); 202439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg seq_printf_with_thousands_grouping(seq, dbdt); 203439d595379f87ec95249da21122eb085866f8ba9Lars Ellenberg seq_printf(seq, ")"); 204b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 205a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg if (state.conn == C_SYNC_TARGET || 206a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg state.conn == C_VERIFY_S) { 2075f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg seq_printf(seq, " want: "); 208b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher seq_printf_with_thousands_grouping(seq, device->c_sync_rate); 2091d7734a0df02ff5068ff8baa1447c7baee601db1Lars Ellenberg } 2101d7734a0df02ff5068ff8baa1447c7baee601db1Lars Ellenberg seq_printf(seq, " K/sec%s\n", stalled ? " (stalled)" : ""); 2115f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg 2125f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg if (proc_details >= 1) { 2135f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg /* 64 bit: 2145f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg * we convert to sectors in the display below. */ 215b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher unsigned long bm_bits = drbd_bm_bits(device); 2164896e8c1b8fb7e46a65a6676e271fc047a260a3eLars Ellenberg unsigned long bit_pos; 21758ffa580a748dd16b1e5ab260bea39cdbd1e94efLars Ellenberg unsigned long long stop_sector = 0; 218a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg if (state.conn == C_VERIFY_S || 219a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg state.conn == C_VERIFY_T) { 220b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher bit_pos = bm_bits - device->ov_left; 221b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher if (verify_can_do_stop_sector(device)) 222b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher stop_sector = device->ov_stop_sector; 22358ffa580a748dd16b1e5ab260bea39cdbd1e94efLars Ellenberg } else 224b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher bit_pos = device->bm_resync_fo; 2255f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg /* Total sectors may be slightly off for oddly 2265f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg * sized devices. So what. */ 2275f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg seq_printf(seq, 22858ffa580a748dd16b1e5ab260bea39cdbd1e94efLars Ellenberg "\t%3d%% sector pos: %llu/%llu", 2295f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg (int)(bit_pos / (bm_bits/100+1)), 2304896e8c1b8fb7e46a65a6676e271fc047a260a3eLars Ellenberg (unsigned long long)bit_pos * BM_SECT_PER_BIT, 2314896e8c1b8fb7e46a65a6676e271fc047a260a3eLars Ellenberg (unsigned long long)bm_bits * BM_SECT_PER_BIT); 23258ffa580a748dd16b1e5ab260bea39cdbd1e94efLars Ellenberg if (stop_sector != 0 && stop_sector != ULLONG_MAX) 23358ffa580a748dd16b1e5ab260bea39cdbd1e94efLars Ellenberg seq_printf(seq, " stop sector: %llu", stop_sector); 23458ffa580a748dd16b1e5ab260bea39cdbd1e94efLars Ellenberg seq_printf(seq, "\n"); 2355f9915bbb8e0975ce99f893c29b8e89100b33399Lars Ellenberg } 236b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner} 237b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 238b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_seq_show(struct seq_file *seq, void *v) 239b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{ 24081a5d60ecfe1d94627abb54810445f0fd5892f42Philipp Reisner int i, prev_i = -1; 241b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner const char *sn; 242b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher struct drbd_device *device; 24344ed167da74825bfb7950d45a4f83bce3e84921cPhilipp Reisner struct net_conf *nc; 244a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg union drbd_dev_state state; 24544ed167da74825bfb7950d45a4f83bce3e84921cPhilipp Reisner char wp; 246b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 247b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner static char write_ordering_chars[] = { 248b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner [WO_none] = 'n', 249b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner [WO_drain_io] = 'd', 250b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner [WO_bdev_flush] = 'f', 251b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner }; 252b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 253b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n", 254b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner API_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX, drbd_buildtag()); 255b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 256b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner /* 257b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner cs .. connection state 258b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner ro .. node role (local/remote) 259b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner ds .. disk state (local/remote) 260b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner protocol 261b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner various flags 262b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner ns .. network send 263b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner nr .. network receive 264b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner dw .. disk write 265b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner dr .. disk read 266b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner al .. activity log write count 267b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner bm .. bitmap update write count 268b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner pe .. pending (waiting for ack or data reply) 269b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner ua .. unack'd (still need to send ack or data reply) 270b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner ap .. application requests accepted, but not yet completed 271b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner ep .. number of epochs currently "on the fly", P_BARRIER_ACK pending 272b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner wo .. write ordering mode currently in use 273b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner oos .. known out-of-sync kB 274b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner */ 275b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 276c141ebda031a0550d75634f7c94f7c85c2d5c9f5Philipp Reisner rcu_read_lock(); 27705a10ec7900dbdba008a24bf56b3490c4b568d2cAndreas Gruenbacher idr_for_each_entry(&drbd_devices, device, i) { 27881a5d60ecfe1d94627abb54810445f0fd5892f42Philipp Reisner if (prev_i != i - 1) 279b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, "\n"); 28081a5d60ecfe1d94627abb54810445f0fd5892f42Philipp Reisner prev_i = i; 281b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 282a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg state = device->state; 283a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg sn = drbd_conn_str(state.conn); 284b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 285a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg if (state.conn == C_STANDALONE && 286a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg state.disk == D_DISKLESS && 287a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg state.role == R_SECONDARY) { 288b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, "%2d: cs:Unconfigured\n", i); 289b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner } else { 290b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher /* reset device->congestion_reason */ 291b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher bdi_rw_congested(&device->rq_queue->backing_dev_info); 2928a943170711b7a4d63528ea8eb6a41cc91e79309Lars Ellenberg 293a6b32bc3cebd3fb6848c526763733b9dbc389c02Andreas Gruenbacher nc = rcu_dereference(first_peer_device(device)->connection->net_conf); 29444ed167da74825bfb7950d45a4f83bce3e84921cPhilipp Reisner wp = nc ? nc->wire_protocol - DRBD_PROT_A + 'A' : ' '; 295b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner seq_printf(seq, 2960778286a133d2d3f81861a4e5db308e359583006Philipp Reisner "%2d: cs:%s ro:%s/%s ds:%s/%s %c %c%c%c%c%c%c\n" 297b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner " ns:%u nr:%u dw:%u dr:%u al:%u bm:%u " 298b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner "lo:%d pe:%d ua:%d ap:%d ep:%d wo:%c", 299b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner i, sn, 300a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg drbd_role_str(state.role), 301a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg drbd_role_str(state.peer), 302a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg drbd_disk_str(state.disk), 303a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg drbd_disk_str(state.pdsk), 30444ed167da74825bfb7950d45a4f83bce3e84921cPhilipp Reisner wp, 305b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher drbd_suspended(device) ? 's' : 'r', 306a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg state.aftr_isp ? 'a' : '-', 307a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg state.peer_isp ? 'p' : '-', 308a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg state.user_isp ? 'u' : '-', 309b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher device->congestion_reason ?: '-', 310b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher test_bit(AL_SUSPENDED, &device->flags) ? 's' : '-', 311b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher device->send_cnt/2, 312b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher device->recv_cnt/2, 313b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher device->writ_cnt/2, 314b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher device->read_cnt/2, 315b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher device->al_writ_cnt, 316b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher device->bm_writ_cnt, 317b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher atomic_read(&device->local_cnt), 318b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher atomic_read(&device->ap_pending_cnt) + 319b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher atomic_read(&device->rs_pending_cnt), 320b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher atomic_read(&device->unacked_cnt), 321b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher atomic_read(&device->ap_bio_cnt), 322a6b32bc3cebd3fb6848c526763733b9dbc389c02Andreas Gruenbacher first_peer_device(device)->connection->epochs, 323e952658020c5150ad4987d313e25e8e2fb38d529Philipp Reisner write_ordering_chars[device->resource->write_ordering] 324b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner ); 32518edc0b9d7dac2f74117a0bdb98f2e705eb74d82Lars Ellenberg seq_printf(seq, " oos:%llu\n", 32618edc0b9d7dac2f74117a0bdb98f2e705eb74d82Lars Ellenberg Bit2KB((unsigned long long) 327b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher drbd_bm_total_weight(device))); 328b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner } 329a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg if (state.conn == C_SYNC_SOURCE || 330a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg state.conn == C_SYNC_TARGET || 331a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg state.conn == C_VERIFY_S || 332a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg state.conn == C_VERIFY_T) 333a5655dac75b6c572e1ef430b61ad55245fffd523Lars Ellenberg drbd_syncer_progress(device, seq, state); 334b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher 335b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher if (proc_details >= 1 && get_ldev_if_state(device, D_FAILED)) { 336b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher lc_seq_printf_stats(seq, device->resync); 337b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher lc_seq_printf_stats(seq, device->act_log); 338b30ab7913b0a7b1d3b1091c8cb3abb1a9f1e0824Andreas Gruenbacher put_ldev(device); 339b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner } 340ad3fee790088d36ad862e31535b5b99c25adeef4Lars Ellenberg 341ad3fee790088d36ad862e31535b5b99c25adeef4Lars Ellenberg if (proc_details >= 2) 342ad3fee790088d36ad862e31535b5b99c25adeef4Lars Ellenberg seq_printf(seq, "\tblocked on activity log: %d\n", atomic_read(&device->ap_actlog_cnt)); 343b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner } 344c141ebda031a0550d75634f7c94f7c85c2d5c9f5Philipp Reisner rcu_read_unlock(); 345b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 346b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner return 0; 347b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner} 348b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 349b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisnerstatic int drbd_proc_open(struct inode *inode, struct file *file) 350b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner{ 351193d01532a730a53cbc74462799dbc43968b97fdAlexey Khoroshilov int err; 352193d01532a730a53cbc74462799dbc43968b97fdAlexey Khoroshilov 353193d01532a730a53cbc74462799dbc43968b97fdAlexey Khoroshilov if (try_module_get(THIS_MODULE)) { 354caa3db0e14cc301f07e758f4cadc36d4dead145aAndreas Gruenbacher err = single_open(file, drbd_seq_show, NULL); 355193d01532a730a53cbc74462799dbc43968b97fdAlexey Khoroshilov if (err) 356193d01532a730a53cbc74462799dbc43968b97fdAlexey Khoroshilov module_put(THIS_MODULE); 357193d01532a730a53cbc74462799dbc43968b97fdAlexey Khoroshilov return err; 358193d01532a730a53cbc74462799dbc43968b97fdAlexey Khoroshilov } 3593da127fa887e5187ede702b835770634d705f8b2Lars Ellenberg return -ENODEV; 3603da127fa887e5187ede702b835770634d705f8b2Lars Ellenberg} 3613da127fa887e5187ede702b835770634d705f8b2Lars Ellenberg 3623da127fa887e5187ede702b835770634d705f8b2Lars Ellenbergstatic int drbd_proc_release(struct inode *inode, struct file *file) 3633da127fa887e5187ede702b835770634d705f8b2Lars Ellenberg{ 3643da127fa887e5187ede702b835770634d705f8b2Lars Ellenberg module_put(THIS_MODULE); 3653da127fa887e5187ede702b835770634d705f8b2Lars Ellenberg return single_release(inode, file); 366b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner} 367b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner 368b411b3637fa71fce9cf2acf0639009500f5892fePhilipp Reisner/* PROC FS stuff end */ 369