summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Kobal <vlad@prokk.net>2021-03-24 11:23:31 +0200
committerGitHub <noreply@github.com>2021-03-24 11:23:31 +0200
commit1fc4dbbbc8948bbba63a98f30119f99331e97df8 (patch)
tree95a59afd67e82766f9e9dbd44e77cfa880d7d312
parenta66e9ef6a7e99eb968a76074fd827b3da6d55da4 (diff)
Check device names in diskstats plugin (#10843)
-rw-r--r--collectors/proc.plugin/proc_diskstats.c23
-rw-r--r--collectors/proc.plugin/proc_self_mountinfo.c17
-rw-r--r--collectors/proc.plugin/proc_self_mountinfo.h7
3 files changed, 31 insertions, 16 deletions
diff --git a/collectors/proc.plugin/proc_diskstats.c b/collectors/proc.plugin/proc_diskstats.c
index 22224df8f4..b5d02f329d 100644
--- a/collectors/proc.plugin/proc_diskstats.c
+++ b/collectors/proc.plugin/proc_diskstats.c
@@ -17,6 +17,7 @@
static struct disk {
char *disk; // the name of the disk (sda, sdb, etc, after being looked up)
char *device; // the device of the disk (before being looked up)
+ uint32_t hash;
unsigned long major;
unsigned long minor;
int sector_size;
@@ -393,7 +394,7 @@ static inline int get_disk_name_from_path(const char *path, char *result, size_t
continue;
}
- if(major(sb.st_rdev) != major || minor(sb.st_rdev) != minor) {
+ if(major(sb.st_rdev) != major || minor(sb.st_rdev) != minor || strcmp(basename(filename), disk)) {
//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));
continue;
}
@@ -547,13 +548,17 @@ static struct disk *get_disk(unsigned long major, unsigned long minor, char *dis
struct disk *d;
+ uint32_t hash = simple_hash(disk);
+
// search for it in our RAM list.
// this is sequential, but since we just walk through
// and the number of disks / partitions in a system
// should not be that many, it should be acceptable
- for(d = disk_root; d ; d = d->next)
- if(unlikely(d->major == major && d->minor == minor))
+ for(d = disk_root; d ; d = d->next){
+ if (unlikely(
+ d->major == major && d->minor == minor && d->hash == hash && !strcmp(d->device, disk)))
return d;
+ }
// not found
// create a new disk structure
@@ -561,6 +566,7 @@ static struct disk *get_disk(unsigned long major, unsigned long minor, char *dis
d->disk = get_disk_name(major, minor, disk);
d->device = strdupz(disk);
+ d->hash = simple_hash(d->device);
d->major = major;
d->minor = minor;
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
// check if we can find its mount point
// mountinfo_find() can be called with NULL disk_mountinfo_root
- struct mountinfo *mi = mountinfo_find(disk_mountinfo_root, d->major, d->minor);
+ struct mountinfo *mi = mountinfo_find(disk_mountinfo_root, d->major, d->minor, d->device);
if(unlikely(!mi)) {
// mountinfo_free_all can be called with NULL
mountinfo_free_all(disk_mountinfo_root);
disk_mountinfo_root = mountinfo_read(0);
- mi = mountinfo_find(disk_mountinfo_root, d->major, d->minor);
+ mi = mountinfo_find(disk_mountinfo_root, d->major, d->minor, d->device);
}
if(unlikely(mi))
@@ -945,13 +951,6 @@ int do_proc_diskstats(int update_every, usec_t dt) {
// I/O completion time and the backlog that may be accumulating.
backlog_ms = str2ull(procfile_lineword(ff, l, 13)); // rq_ticks
-
- // --------------------------------------------------------------------------
- // remove slashes from disk names
- char *s;
- for(s = disk; *s ;s++)
- if(*s == '/') *s = '_';
-
// --------------------------------------------------------------------------
// get a disk structure for the disk
diff --git a/collectors/proc.plugin/proc_self_mountinfo.c b/collectors/proc.plugin/proc_self_mountinfo.c
index 3f17ccce24..ca00f8a89f 100644
--- a/collectors/proc.plugin/proc_self_mountinfo.c
+++ b/collectors/proc.plugin/proc_self_mountinfo.c
@@ -47,11 +47,17 @@
// find the mount info with the given major:minor
// in the supplied linked list of mountinfo structures
-struct mountinfo *mountinfo_find(struct mountinfo *root, unsigned long major, unsigned long minor) {
+struct mountinfo *mountinfo_find(struct mountinfo *root, unsigned long major, unsigned long minor, char *device) {
struct mountinfo *mi;
+ uint32_t hash = simple_hash(device);
+
for(mi = root; mi ; mi = mi->next)
- if(unlikely(mi->major == major && mi->minor == minor))
+ if (unlikely(
+ mi->major == major &&
+ mi->minor == minor &&
+ mi->mount_source_name_hash == hash &&
+ !strcmp(mi->mount_source_name, device)))
return mi;
return NULL;
@@ -120,6 +126,7 @@ static void mountinfo_free(struct mountinfo *mi) {
*/
freez(mi->filesystem);
freez(mi->mount_source);
+ freez(mi->mount_source_name);
freez(mi->super_options);
freez(mi);
}
@@ -273,6 +280,9 @@ struct mountinfo *mountinfo_read(int do_statvfs) {
mi->mount_source = strdupz_decoding_octal(procfile_lineword(ff, l, w)); w++;
mi->mount_source_hash = simple_hash(mi->mount_source);
+ mi->mount_source_name = strdupz(basename(mi->mount_source));
+ mi->mount_source_name_hash = simple_hash(mi->mount_source_name);
+
mi->super_options = strdupz(procfile_lineword(ff, l, w)); w++;
if(unlikely(is_read_only(mi->super_options)))
@@ -316,6 +326,9 @@ struct mountinfo *mountinfo_read(int do_statvfs) {
mi->mount_source = NULL;
mi->mount_source_hash = 0;
+ mi->mount_source_name = NULL;
+ mi->mount_source_name_hash = 0;
+
mi->super_options = NULL;
mi->st_dev = 0;
diff --git a/collectors/proc.plugin/proc_self_mountinfo.h b/collectors/proc.plugin/proc_self_mountinfo.h
index 15d63c7868..92918a73de 100644
--- a/collectors/proc.plugin/proc_self_mountinfo.h
+++ b/collectors/proc.plugin/proc_self_mountinfo.h
@@ -38,6 +38,9 @@ struct mountinfo {
char *mount_source; // mount source: filesystem-specific information or "none".
uint32_t mount_source_hash;
+ char *mount_source_name;
+ uint32_t mount_source_name_hash;
+
char *super_options; // super options: per-superblock options.
uint32_t flags;
@@ -47,11 +50,11 @@ struct mountinfo {
struct mountinfo *next;
};
-extern struct mountinfo *mountinfo_find(struct mountinfo *root, unsigned long major, unsigned long minor);
+extern struct mountinfo *mountinfo_find(struct mountinfo *root, unsigned long major, unsigned long minor, char *device);
extern struct mountinfo *mountinfo_find_by_filesystem_mount_source(struct mountinfo *root, const char *filesystem, const char *mount_source);
extern struct mountinfo *mountinfo_find_by_filesystem_super_option(struct mountinfo *root, const char *filesystem, const char *super_options);
extern void mountinfo_free_all(struct mountinfo *mi);
extern struct mountinfo *mountinfo_read(int do_statvfs);
-#endif /* NETDATA_PROC_SELF_MOUNTINFO_H */ \ No newline at end of file
+#endif /* NETDATA_PROC_SELF_MOUNTINFO_H */