@cryptotaxi247 / netdata-1 / commits / 1fc4dbbbc

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 */