Check device names in diskstats plugin (#10843)
Vladimir Kobal committed
Mar 24, 2021 at 11:23 UTC
1fc4dbbbc8948bbba63a98f30119f99331e97df8
3 files changed
+31
-16
collectors/proc.plugin/proc_diskstats.c
+11
-12
@@ -17,6 +17,7 @@
17
static struct disk {
18
char *disk; // the name of the disk (sda, sdb, etc, after being looked up)
19
char *device; // the device of the disk (before being looked up)
20
+ uint32_t hash;
21
unsigned long major;
22
unsigned long minor;
23
int sector_size;
@@ -393,7 +394,7 @@ static inline int get_disk_name_from_path(const char *path, char *result, size_t
394
continue;
395
}
396
396
- if(major(sb.st_rdev) != major || minor(sb.st_rdev) != minor) {
397
+ if(major(sb.st_rdev) != major || minor(sb.st_rdev) != minor || strcmp(basename(filename), disk)) {
398
//info("DEVICE-MAPPER ('%s', %lu:%lu): filename '%s' does not match %lu:%lu.", disk, major, minor, filename, (unsigned long)major(sb.st_rdev), (unsigned long)minor(sb.st_rdev));
399
continue;
400
}
@@ -547,13 +548,17 @@ static struct disk *get_disk(unsigned long major, unsigned long minor, char *dis
548
549
struct disk *d;
550
551
+ uint32_t hash = simple_hash(disk);
552
+
553
// search for it in our RAM list.
554
// this is sequential, but since we just walk through
555
// and the number of disks / partitions in a system
556
// should not be that many, it should be acceptable
554
- for(d = disk_root; d ; d = d->next)
555
- if(unlikely(d->major == major && d->minor == minor))
557
+ for(d = disk_root; d ; d = d->next){
558
+ if (unlikely(
559
+ d->major == major && d->minor == minor && d->hash == hash && !strcmp(d->device, disk)))
560
return d;
561
+ }
562
563
// not found
564
// create a new disk structure
@@ -561,6 +566,7 @@ static struct disk *get_disk(unsigned long major, unsigned long minor, char *dis
566
567
d->disk = get_disk_name(major, minor, disk);
568
d->device = strdupz(disk);
569
+ d->hash = simple_hash(d->device);
570
d->major = major;
571
d->minor = minor;
572
d->type = DISK_TYPE_UNKNOWN; // Default type. Changed later if not correct.
@@ -627,12 +633,12 @@ static struct disk *get_disk(unsigned long major, unsigned long minor, char *dis
633
// check if we can find its mount point
634
635
// mountinfo_find() can be called with NULL disk_mountinfo_root
630
- struct mountinfo *mi = mountinfo_find(disk_mountinfo_root, d->major, d->minor);
636
+ struct mountinfo *mi = mountinfo_find(disk_mountinfo_root, d->major, d->minor, d->device);
637
if(unlikely(!mi)) {
638
// mountinfo_free_all can be called with NULL
639
mountinfo_free_all(disk_mountinfo_root);
640
disk_mountinfo_root = mountinfo_read(0);
635
- mi = mountinfo_find(disk_mountinfo_root, d->major, d->minor);
641
+ mi = mountinfo_find(disk_mountinfo_root, d->major, d->minor, d->device);
642
}
643
644
if(unlikely(mi))
@@ -945,13 +951,6 @@ int do_proc_diskstats(int update_every, usec_t dt) {
951
// I/O completion time and the backlog that may be accumulating.
952
backlog_ms = str2ull(procfile_lineword(ff, l, 13)); // rq_ticks
953
948
-
949
- // --------------------------------------------------------------------------
950
- // remove slashes from disk names
951
- char *s;
952
- for(s = disk; *s ;s++)
953
- if(*s == '/') *s = '_';
954
-
954
// --------------------------------------------------------------------------
955
// get a disk structure for the disk
956
collectors/proc.plugin/proc_self_mountinfo.c
+15
-2
@@ -47,11 +47,17 @@
47
48
// find the mount info with the given major:minor
49
// in the supplied linked list of mountinfo structures
50
-struct mountinfo *mountinfo_find(struct mountinfo *root, unsigned long major, unsigned long minor) {
50
+struct mountinfo *mountinfo_find(struct mountinfo *root, unsigned long major, unsigned long minor, char *device) {
51
struct mountinfo *mi;
52
53
+ uint32_t hash = simple_hash(device);
54
+
55
for(mi = root; mi ; mi = mi->next)
54
- if(unlikely(mi->major == major && mi->minor == minor))
56
+ if (unlikely(
57
+ mi->major == major &&
58
+ mi->minor == minor &&
59
+ mi->mount_source_name_hash == hash &&
60
+ !strcmp(mi->mount_source_name, device)))
61
return mi;
62
63
return NULL;
@@ -120,6 +126,7 @@ static void mountinfo_free(struct mountinfo *mi) {
126
*/
127
freez(mi->filesystem);
128
freez(mi->mount_source);
129
+ freez(mi->mount_source_name);
130
freez(mi->super_options);
131
freez(mi);
132
}
@@ -273,6 +280,9 @@ struct mountinfo *mountinfo_read(int do_statvfs) {
280
mi->mount_source = strdupz_decoding_octal(procfile_lineword(ff, l, w)); w++;
281
mi->mount_source_hash = simple_hash(mi->mount_source);
282
283
+ mi->mount_source_name = strdupz(basename(mi->mount_source));
284
+ mi->mount_source_name_hash = simple_hash(mi->mount_source_name);
285
+
286
mi->super_options = strdupz(procfile_lineword(ff, l, w)); w++;
287
288
if(unlikely(is_read_only(mi->super_options)))
@@ -316,6 +326,9 @@ struct mountinfo *mountinfo_read(int do_statvfs) {
326
mi->mount_source = NULL;
327
mi->mount_source_hash = 0;
328
329
+ mi->mount_source_name = NULL;
330
+ mi->mount_source_name_hash = 0;
331
+
332
mi->super_options = NULL;
333
334
mi->st_dev = 0;
collectors/proc.plugin/proc_self_mountinfo.h
+5
-2
@@ -38,6 +38,9 @@ struct mountinfo {
38
char *mount_source; // mount source: filesystem-specific information or "none".
39
uint32_t mount_source_hash;
40
41
+ char *mount_source_name;
42
+ uint32_t mount_source_name_hash;
43
+
44
char *super_options; // super options: per-superblock options.
45
46
uint32_t flags;
@@ -47,11 +50,11 @@ struct mountinfo {
50
struct mountinfo *next;
51
};
52
50
-extern struct mountinfo *mountinfo_find(struct mountinfo *root, unsigned long major, unsigned long minor);
53
+extern struct mountinfo *mountinfo_find(struct mountinfo *root, unsigned long major, unsigned long minor, char *device);
54
extern struct mountinfo *mountinfo_find_by_filesystem_mount_source(struct mountinfo *root, const char *filesystem, const char *mount_source);
55
extern struct mountinfo *mountinfo_find_by_filesystem_super_option(struct mountinfo *root, const char *filesystem, const char *super_options);
56
57
extern void mountinfo_free_all(struct mountinfo *mi);
58
extern struct mountinfo *mountinfo_read(int do_statvfs);
59
57
-#endif /* NETDATA_PROC_SELF_MOUNTINFO_H */
\ No newline at end of file
60
+#endif /* NETDATA_PROC_SELF_MOUNTINFO_H */