auto-detection of partitions based on /sys/dev/block/MAJOR:MINOR/partition #259, #258
Costa Tsaousis (ktsaou) committed
Apr 20, 2016 at 02:54 UTC
acdf32e652fac961e571d494376be06f0d9db1f0
1 file changed
+80
-2
src/proc_diskstats.c
+80
-2
@@ -4,6 +4,9 @@
4
#include <stdio.h>
5
#include <stdlib.h>
6
#include <string.h>
7
+#include <sys/types.h>
8
+#include <sys/stat.h>
9
+#include <fcntl.h>
10
11
#include "common.h"
12
#include "log.h"
@@ -14,6 +17,73 @@
17
18
#define RRD_TYPE_DISK "disk"
19
20
+struct disk {
21
+ unsigned long major;
22
+ unsigned long minor;
23
+ int partition_id; // -1 = this is not a partition
24
+ struct disk *next;
25
+} *disk_root = NULL;
26
+
27
+struct disk *get_disk(unsigned long major, unsigned long minor) {
28
+ static char path_find_block_device_partition[FILENAME_MAX + 1] = "";
29
+ struct disk *d;
30
+
31
+ // search for it in our RAM list.
32
+ // this is sequential, but since we just walk through
33
+ // and the number of disks / partitions in a system
34
+ // should not be that many, it should be acceptable
35
+ for(d = disk_root; d ; d = d->next)
36
+ if(unlikely(d->major == major && d->minor == minor))
37
+ break;
38
+
39
+ // if we found it, return it
40
+ if(likely(d))
41
+ return d;
42
+
43
+ if(unlikely(!path_find_block_device_partition[0])) {
44
+ char filename[FILENAME_MAX + 1];
45
+ snprintf(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/sys/dev/block/%lu:%lu/partition");
46
+ snprintf(path_find_block_device_partition, FILENAME_MAX, "%s", config_get("plugin:proc:/proc/diskstats", "path to get block device partition", filename));
47
+ }
48
+
49
+ // not found
50
+ // create a new disk structure
51
+ d = (struct disk *)malloc(sizeof(struct disk));
52
+ if(!d) fatal("Cannot allocate memory for struct disk in proc_diskstats.");
53
+
54
+ d->major = major;
55
+ d->minor = minor;
56
+ d->partition_id = -1;
57
+ d->next = NULL;
58
+
59
+ // append it to the list
60
+ if(!disk_root)
61
+ disk_root = d;
62
+ else {
63
+ struct disk *last;
64
+ for(last = disk_root; last->next ;last = last->next);
65
+ last->next = d;
66
+ }
67
+
68
+ // find if it is a partition
69
+ // by reading /sys/dev/block/MAJOR:MINOR/partition
70
+ char buffer[FILENAME_MAX + 1];
71
+ snprintf(buffer, FILENAME_MAX, path_find_block_device_partition, major, minor);
72
+
73
+ int fd = open(buffer, O_RDONLY, 0666);
74
+ if(likely(fd != -1)) {
75
+ // we opened it
76
+ int bytes = read(fd, buffer, FILENAME_MAX);
77
+ close(fd);
78
+
79
+ if(bytes > 0)
80
+ d->partition_id = strtoul(buffer, NULL, 10);
81
+ }
82
+ // if the /partition file does not exist, it is a disk, not a partition
83
+
84
+ return d;
85
+}
86
+
87
int do_proc_diskstats(int update_every, unsigned long long dt) {
88
static procfile *ff = NULL;
89
static char path_to_get_hw_sector_size[FILENAME_MAX + 1] = "";
@@ -40,7 +110,7 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
110
if(!path_to_get_hw_sector_size[0]) {
111
char filename[FILENAME_MAX + 1];
112
snprintf(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/sys/block/%s/queue/hw_sector_size");
43
- snprintf(path_to_get_hw_sector_size, FILENAME_MAX, "%s%s", global_host_prefix, config_get("plugin:proc:/proc/diskstats", "path to get h/w sector size", filename));
113
+ snprintf(path_to_get_hw_sector_size, FILENAME_MAX, "%s", config_get("plugin:proc:/proc/diskstats", "path to get h/w sector size", filename));
114
}
115
116
ff = procfile_readall(ff);
@@ -107,13 +177,19 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
177
// I/O completion time and the backlog that may be accumulating.
178
backlog_ms = strtoull(procfile_lineword(ff, l, 13), NULL, 10); // rq_ticks
179
110
-
180
int def_enabled = 0;
181
182
// remove slashes from disk names
183
char *s;
184
for(s = disk; *s ;s++) if(*s == '/') *s = '_';
185
186
+ struct disk *d = get_disk(major, minor);
187
+ if(d->partition_id == -1)
188
+ def_enabled = enable_new_disks;
189
+ else
190
+ def_enabled = 0;
191
+
192
+/*
193
switch(major) {
194
case 9: // MDs
195
case 43: // network block
@@ -196,6 +272,7 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
272
case 135: // scsi
273
case 153: // raid
274
case 202: // xen
275
+ case 254: // virtio3
276
case 256: // flash
277
case 257: // flash
278
case 259: // nvme0n1 issue #119
@@ -232,6 +309,7 @@ int do_proc_diskstats(int update_every, unsigned long long dt) {
309
def_enabled = 0;
310
break;
311
}
312
+*/
313
314
int ddo_io = do_io, ddo_ops = do_ops, ddo_mops = do_mops, ddo_iotime = do_iotime, ddo_qops = do_qops, ddo_util = do_util, ddo_backlog = do_backlog;
315