diff options
Diffstat (limited to '')
-rw-r--r-- | collectors/diskspace.plugin/Makefile.am | 8 | ||||
-rw-r--r-- | collectors/diskspace.plugin/metadata.yaml | 139 | ||||
l--------- | src/collectors/diskspace.plugin/README.md (renamed from collectors/diskspace.plugin/README.md) | 0 | ||||
-rw-r--r-- | src/collectors/diskspace.plugin/integrations/disk_space.md (renamed from collectors/diskspace.plugin/integrations/disk_space.md) | 14 | ||||
-rw-r--r-- | src/collectors/diskspace.plugin/plugin_diskspace.c (renamed from collectors/diskspace.plugin/plugin_diskspace.c) | 291 |
5 files changed, 141 insertions, 311 deletions
diff --git a/collectors/diskspace.plugin/Makefile.am b/collectors/diskspace.plugin/Makefile.am deleted file mode 100644 index 161784b8f..000000000 --- a/collectors/diskspace.plugin/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later - -AUTOMAKE_OPTIONS = subdir-objects -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in - -dist_noinst_DATA = \ - README.md \ - $(NULL) diff --git a/collectors/diskspace.plugin/metadata.yaml b/collectors/diskspace.plugin/metadata.yaml deleted file mode 100644 index cb45edf34..000000000 --- a/collectors/diskspace.plugin/metadata.yaml +++ /dev/null @@ -1,139 +0,0 @@ -plugin_name: diskspace.plugin -modules: - - meta: - plugin_name: diskspace.plugin - module_name: diskspace.plugin - monitored_instance: - name: Disk space - link: "" - categories: - - data-collection.linux-systems - icon_filename: "hard-drive.svg" - related_resources: - integrations: - list: - - plugin_name: ebpf.plugin - module_name: disk - info_provided_to_referring_integrations: - description: "" - keywords: - - disk - - I/O - - space - - inode - most_popular: false - overview: - data_collection: - metrics_description: "Monitor Disk space metrics for proficient storage management. Keep track of usage, free space, and error rates to prevent disk space issues." - method_description: "" - supported_platforms: - include: [] - exclude: [] - multi_instance: true - additional_permissions: - description: "" - default_behavior: - auto_detection: - description: "The plugin reads data from `/proc/self/mountinfo` and `/proc/diskstats file`." - limits: - description: "" - performance_impact: - description: "" - setup: - prerequisites: - list: [] - configuration: - file: - name: "netdata.conf" - section_name: "[plugin:proc:diskspace]" - description: "This is netdata main configuration file" - options: - description: "You can also specify per mount point `[plugin:proc:diskspace:mountpoint]`" - folding: - title: "Config options" - enabled: true - list: - - name: update every - description: Data collection frequency. - default_value: 1 - required: false - - name: remove charts of unmounted disks - description: Remove chart when a device is unmounted on host. - default_value: yes - required: false - - name: check for new mount points every - description: Parse proc files frequency. - default_value: 15 - required: false - - name: exclude space metrics on paths - description: Do not show metrics (charts) for listed paths. This option accepts netdata simple pattern. - default_value: /proc/* /sys/* /var/run/user/* /run/user/* /snap/* /var/lib/docker/* - required: false - - name: exclude space metrics on filesystems - description: Do not show metrics (charts) for listed filesystems. This option accepts netdata simple pattern. - default_value: "*gvfs *gluster* *s3fs *ipfs *davfs2 *httpfs *sshfs *gdfs *moosefs fusectl autofs" - required: false - - name: exclude inode metrics on filesystems - description: Do not show metrics (charts) for listed filesystems. This option accepts netdata simple pattern. - default_value: msdosfs msdos vfat overlayfs aufs* *unionfs - required: false - - name: space usage for all disks - description: Define if plugin will show metrics for space usage. When value is set to `auto` plugin will try to access information to display if filesystem or path was not discarded with previous option. - default_value: auto - required: false - - name: inodes usage for all disks - description: Define if plugin will show metrics for inode usage. When value is set to `auto` plugin will try to access information to display if filesystem or path was not discarded with previous option. - default_value: auto - required: false - examples: - folding: - enabled: true - title: "" - list: [] - troubleshooting: - problems: - list: [] - alerts: - - name: disk_space_usage - link: https://github.com/netdata/netdata/blob/master/health/health.d/disks.conf - metric: disk.space - info: disk ${label:mount_point} space utilization - os: "linux freebsd" - - name: disk_inode_usage - link: https://github.com/netdata/netdata/blob/master/health/health.d/disks.conf - metric: disk.inodes - info: disk ${label:mount_point} inode utilization - os: "linux freebsd" - metrics: - folding: - title: Metrics - enabled: false - description: "" - availability: [] - scopes: - - name: mount point - description: "" - labels: - - name: mount_point - description: Path used to mount a filesystem - - name: filesystem - description: The filesystem used to format a partition. - - name: mount_root - description: Root directory where mount points are present. - metrics: - - name: disk.space - description: Disk Space Usage - unit: "GiB" - chart_type: stacked - dimensions: - - name: avail - - name: used - - name: reserved_for_root - - name: disk.inodes - description: Disk Files (inodes) Usage - unit: "inodes" - chart_type: stacked - dimensions: - - name: avail - - name: used - - name: reserved_for_root diff --git a/collectors/diskspace.plugin/README.md b/src/collectors/diskspace.plugin/README.md index c9f4e1c5e..c9f4e1c5e 120000 --- a/collectors/diskspace.plugin/README.md +++ b/src/collectors/diskspace.plugin/README.md diff --git a/collectors/diskspace.plugin/integrations/disk_space.md b/src/collectors/diskspace.plugin/integrations/disk_space.md index 1c937ed7f..61015120d 100644 --- a/collectors/diskspace.plugin/integrations/disk_space.md +++ b/src/collectors/diskspace.plugin/integrations/disk_space.md @@ -1,9 +1,9 @@ <!--startmeta -custom_edit_url: "https://github.com/netdata/netdata/edit/master/collectors/diskspace.plugin/README.md" -meta_yaml: "https://github.com/netdata/netdata/edit/master/collectors/diskspace.plugin/metadata.yaml" +custom_edit_url: "https://github.com/netdata/netdata/edit/master/src/collectors/diskspace.plugin/README.md" +meta_yaml: "https://github.com/netdata/netdata/edit/master/src/collectors/diskspace.plugin/metadata.yaml" sidebar_label: "Disk space" learn_status: "Published" -learn_rel_path: "Data Collection/Linux Systems" +learn_rel_path: "Collecting Metrics/Linux Systems" most_popular: False message: "DO NOT EDIT THIS FILE DIRECTLY, IT IS GENERATED BY THE COLLECTOR'S metadata.yaml FILE" endmeta--> @@ -81,8 +81,8 @@ The following alerts are available: | Alert name | On metric | Description | |:------------|:----------|:------------| -| [ disk_space_usage ](https://github.com/netdata/netdata/blob/master/health/health.d/disks.conf) | disk.space | disk ${label:mount_point} space utilization | -| [ disk_inode_usage ](https://github.com/netdata/netdata/blob/master/health/health.d/disks.conf) | disk.inodes | disk ${label:mount_point} inode utilization | +| [ disk_space_usage ](https://github.com/netdata/netdata/blob/master/src/health/health.d/disks.conf) | disk.space | disk ${label:mount_point} space utilization | +| [ disk_inode_usage ](https://github.com/netdata/netdata/blob/master/src/health/health.d/disks.conf) | disk.inodes | disk ${label:mount_point} inode utilization | ## Setup @@ -109,7 +109,7 @@ The file format is a modified INI syntax. The general structure is: option3 = some third value ``` You can edit the configuration file using the `edit-config` script from the -Netdata [config directory](https://github.com/netdata/netdata/blob/master/docs/configure/nodes.md#the-netdata-config-directory). +Netdata [config directory](/docs/netdata-agent/configuration/README.md#the-netdata-config-directory). ```bash cd /etc/netdata 2>/dev/null || cd /opt/netdata/etc/netdata @@ -119,7 +119,7 @@ sudo ./edit-config netdata.conf You can also specify per mount point `[plugin:proc:diskspace:mountpoint]` -<details><summary>Config options</summary> +<details open><summary>Config options</summary> | Name | Description | Default | Required | |:----|:-----------|:-------|:--------:| diff --git a/collectors/diskspace.plugin/plugin_diskspace.c b/src/collectors/diskspace.plugin/plugin_diskspace.c index 94257810c..10e07586c 100644 --- a/collectors/diskspace.plugin/plugin_diskspace.c +++ b/src/collectors/diskspace.plugin/plugin_diskspace.c @@ -14,7 +14,7 @@ #define MAX_STAT_USEC 10000LU #define SLOW_UPDATE_EVERY 5 -static netdata_thread_t *diskspace_slow_thread = NULL; +static ND_THREAD *diskspace_slow_thread = NULL; static struct mountinfo *disk_mountinfo_root = NULL; static int check_for_new_mountpoints_every = 15; @@ -40,11 +40,10 @@ static inline void mountinfo_reload(int force) { struct mount_point_metadata { int do_space; int do_inodes; - int shown_error; - int updated; - int slow; - bool function_ready; + bool shown_error; + bool updated; + bool slow; STRING *filesystem; STRING *mountroot; @@ -68,54 +67,51 @@ static DICTIONARY *dict_mountpoints = NULL; #define rrdset_obsolete_and_pointer_null(st) do { if(st) { rrdset_is_obsolete___safe_from_collector_thread(st); (st) = NULL; } } while(st) -int mount_point_cleanup(const char *name, void *entry, int slow) { - (void)name; - - struct mount_point_metadata *mp = (struct mount_point_metadata *)entry; - if(!mp) return 0; - - if (slow != mp->slow) - return 0; +static void mount_points_cleanup(bool slow) { + struct mount_point_metadata *mp; + dfe_start_write(dict_mountpoints, mp) { + if(mp->slow != slow) continue; - if(likely(mp->updated)) { - mp->updated = 0; - return 0; + if(mp->updated) + mp->updated = false; + else if(cleanup_mount_points) + dictionary_del(dict_mountpoints, mp_dfe.name); } + dfe_done(mp); - if(likely(cleanup_mount_points && mp->collected)) { - mp->function_ready = false; - mp->collected = 0; - mp->updated = 0; - mp->shown_error = 0; + dictionary_garbage_collect(dict_mountpoints); +} - string_freez(mp->filesystem); - string_freez(mp->mountroot); +void mountpoint_delete_cb(const DICTIONARY_ITEM *item __maybe_unused, void *entry, void *data __maybe_unused) { + struct mount_point_metadata *mp = (struct mount_point_metadata *)entry; - rrdset_obsolete_and_pointer_null(mp->st_space); - rrdset_obsolete_and_pointer_null(mp->st_inodes); + mp->collected = 0; + mp->updated = false; + mp->shown_error = false; - mp->rd_space_avail = NULL; - mp->rd_space_used = NULL; - mp->rd_space_reserved = NULL; + string_freez(mp->filesystem); + mp->filesystem = NULL; - mp->rd_inodes_avail = NULL; - mp->rd_inodes_used = NULL; - mp->rd_inodes_reserved = NULL; - } + string_freez(mp->mountroot); + mp->mountroot = NULL; - return 0; -} + rrdset_obsolete_and_pointer_null(mp->st_space); + rrdset_obsolete_and_pointer_null(mp->st_inodes); -int mount_point_cleanup_cb(const DICTIONARY_ITEM *item, void *entry, void *data __maybe_unused) { - const char *name = dictionary_acquired_item_name(item); + mp->rd_space_avail = NULL; + mp->rd_space_used = NULL; + mp->rd_space_reserved = NULL; - return mount_point_cleanup(name, (struct mount_point_metadata *)entry, 0); + mp->rd_inodes_avail = NULL; + mp->rd_inodes_used = NULL; + mp->rd_inodes_reserved = NULL; } // a copy of basic mountinfo fields struct basic_mountinfo { char *persistent_id; char *root; + char *mount_point_stat_path; char *mount_point; char *filesystem; @@ -128,12 +124,13 @@ static netdata_mutex_t slow_mountinfo_mutex; static struct basic_mountinfo *basic_mountinfo_create_and_copy(struct mountinfo* mi) { struct basic_mountinfo *bmi = callocz(1, sizeof(struct basic_mountinfo)); - + if (mi) { bmi->persistent_id = strdupz(mi->persistent_id); - bmi->root = strdupz(mi->root); - bmi->mount_point = strdupz(mi->mount_point); - bmi->filesystem = strdupz(mi->filesystem); + bmi->root = strdupz(mi->root); + bmi->mount_point_stat_path = strdupz(mi->mount_point_stat_path); + bmi->mount_point = strdupz(mi->mount_point); + bmi->filesystem = strdupz(mi->filesystem); } return bmi; @@ -148,19 +145,20 @@ static void add_basic_mountinfo(struct basic_mountinfo **root, struct mountinfo bmi->next = *root; *root = bmi; -}; +} static void free_basic_mountinfo(struct basic_mountinfo *bmi) { if (bmi) { freez(bmi->persistent_id); freez(bmi->root); + freez(bmi->mount_point_stat_path); freez(bmi->mount_point); freez(bmi->filesystem); freez(bmi); } -}; +} static void free_basic_mountinfo_list(struct basic_mountinfo *root) { @@ -217,9 +215,7 @@ static void calculate_values_and_show_charts( int rendered = 0; - if(m->do_space == CONFIG_BOOLEAN_YES || (m->do_space == CONFIG_BOOLEAN_AUTO && - (bavail || breserved_root || bused || - netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) { + if (m->do_space == CONFIG_BOOLEAN_YES || m->do_space == CONFIG_BOOLEAN_AUTO) { if(unlikely(!m->st_space) || m->st_space->update_every != update_every) { m->do_space = CONFIG_BOOLEAN_YES; m->st_space = rrdset_find_active_bytype_localhost("disk_space", disk); @@ -257,9 +253,7 @@ static void calculate_values_and_show_charts( rendered++; } - if(m->do_inodes == CONFIG_BOOLEAN_YES || (m->do_inodes == CONFIG_BOOLEAN_AUTO && - (favail || freserved_root || fused || - netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) { + if (m->do_inodes == CONFIG_BOOLEAN_YES || m->do_inodes == CONFIG_BOOLEAN_AUTO) { if(unlikely(!m->st_inodes) || m->st_inodes->update_every != update_every) { m->do_inodes = CONFIG_BOOLEAN_YES; m->st_inodes = rrdset_find_active_bytype_localhost("disk_inodes", disk); @@ -297,8 +291,6 @@ static void calculate_values_and_show_charts( rendered++; } - m->function_ready = rendered > 0; - if(likely(rendered)) m->collected++; } @@ -341,11 +333,12 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) { true); dict_mountpoints = dictionary_create_advanced(DICT_OPTION_NONE, &dictionary_stats_category_collectors, 0); + dictionary_register_delete_callback(dict_mountpoints, mountpoint_delete_cb, NULL); } - struct mount_point_metadata *m = dictionary_get(dict_mountpoints, mi->mount_point); - if(unlikely(!m)) { - int slow = 0; + const DICTIONARY_ITEM *item = dictionary_get_and_acquire_item(dict_mountpoints, mi->mount_point); + if(unlikely(!item)) { + bool slow = false; int def_space = config_get_boolean_ondemand(CONFIG_SECTION_DISKSPACE, "space usage for all disks", CONFIG_BOOLEAN_AUTO); int def_inodes = config_get_boolean_ondemand(CONFIG_SECTION_DISKSPACE, "inodes usage for all disks", CONFIG_BOOLEAN_AUTO); @@ -369,9 +362,9 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) { usec_t start_time = now_monotonic_high_precision_usec(); struct stat bs; - if(stat(mi->mount_point, &bs) == -1) { + if(stat(mi->mount_point_stat_path, &bs) == -1) { collector_error("DISKSPACE: Cannot stat() mount point '%s' (disk '%s', filesystem '%s', root '%s')." - , mi->mount_point + , mi->mount_point_stat_path , disk , mi->filesystem?mi->filesystem:"" , mi->root?mi->root:"" @@ -382,7 +375,7 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) { else { if((bs.st_mode & S_IFMT) != S_IFDIR) { collector_error("DISKSPACE: Mount point '%s' (disk '%s', filesystem '%s', root '%s') is not a directory." - , mi->mount_point + , mi->mount_point_stat_path , disk , mi->filesystem?mi->filesystem:"" , mi->root?mi->root:"" @@ -393,7 +386,7 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) { } if ((now_monotonic_high_precision_usec() - start_time) > slow_timeout) - slow = 1; + slow = true; } char var_name[4096 + 1]; @@ -408,76 +401,76 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) { do_inodes = config_get_boolean_ondemand(var_name, "inodes usage", def_inodes); struct mount_point_metadata mp = { - .do_space = do_space, - .do_inodes = do_inodes, - .shown_error = 0, - .updated = 0, - .slow = 0, - - .collected = 0, - - .st_space = NULL, - .rd_space_avail = NULL, - .rd_space_used = NULL, - .rd_space_reserved = NULL, - - .st_inodes = NULL, - .rd_inodes_avail = NULL, - .rd_inodes_used = NULL, - .rd_inodes_reserved = NULL + .do_space = do_space, + .do_inodes = do_inodes, + .shown_error = false, + .updated = false, + .slow = slow, + + .collected = 0, + .filesystem = string_strdupz(mi->filesystem), + .mountroot = string_strdupz(mi->root), + .chart_labels = rrdlabels_create(), + + .st_space = NULL, + .rd_space_avail = NULL, + .rd_space_used = NULL, + .rd_space_reserved = NULL, + + .st_inodes = NULL, + .rd_inodes_avail = NULL, + .rd_inodes_used = NULL, + .rd_inodes_reserved = NULL }; - mp.filesystem = string_strdupz(mi->filesystem); - mp.mountroot = string_strdupz(mi->root); - - mp.chart_labels = rrdlabels_create(); rrdlabels_add(mp.chart_labels, "mount_point", mi->mount_point, RRDLABEL_SRC_AUTO); rrdlabels_add(mp.chart_labels, "filesystem", mi->filesystem, RRDLABEL_SRC_AUTO); rrdlabels_add(mp.chart_labels, "mount_root", mi->root, RRDLABEL_SRC_AUTO); - m = dictionary_set(dict_mountpoints, mi->mount_point, &mp, sizeof(struct mount_point_metadata)); - - m->slow = slow; + item = dictionary_set_and_acquire_item(dict_mountpoints, mi->mount_point, &mp, sizeof(struct mount_point_metadata)); } + struct mount_point_metadata *m = dictionary_acquired_item_value(item); if (m->slow) { add_basic_mountinfo(&slow_mountinfo_tmp_root, mi); - return; + goto cleanup; } - m->updated = 1; + m->updated = true; - if(unlikely(m->do_space == CONFIG_BOOLEAN_NO && m->do_inodes == CONFIG_BOOLEAN_NO)) - return; + if(unlikely(m->do_space == CONFIG_BOOLEAN_NO && m->do_inodes == CONFIG_BOOLEAN_NO)) { + goto cleanup; + } if (unlikely( mi->flags & MOUNTINFO_READONLY && !(mi->flags & MOUNTINFO_IS_IN_SYSD_PROTECTED_LIST) && !m->collected && m->do_space != CONFIG_BOOLEAN_YES && - m->do_inodes != CONFIG_BOOLEAN_YES)) - return; + m->do_inodes != CONFIG_BOOLEAN_YES)) { + goto cleanup; + } usec_t start_time = now_monotonic_high_precision_usec(); struct statvfs buff_statvfs; - if (statvfs(mi->mount_point, &buff_statvfs) < 0) { + if (statvfs(mi->mount_point_stat_path, &buff_statvfs) < 0) { if(!m->shown_error) { collector_error("DISKSPACE: failed to statvfs() mount point '%s' (disk '%s', filesystem '%s', root '%s')" - , mi->mount_point + , mi->mount_point_stat_path , disk , mi->filesystem?mi->filesystem:"" , mi->root?mi->root:"" ); - m->shown_error = 1; + m->shown_error = true; } - return; + goto cleanup; } if ((now_monotonic_high_precision_usec() - start_time) > slow_timeout) - m->slow = 1; + m->slow = true; - m->shown_error = 0; + m->shown_error = false; struct basic_mountinfo bmi; bmi.mount_point = mi->mount_point; @@ -486,34 +479,42 @@ static inline void do_disk_space_stats(struct mountinfo *mi, int update_every) { bmi.root = mi->root; calculate_values_and_show_charts(&bmi, m, &buff_statvfs, update_every); + +cleanup: + dictionary_acquired_item_release(dict_mountpoints, item); } static inline void do_slow_disk_space_stats(struct basic_mountinfo *mi, int update_every) { - struct mount_point_metadata *m = dictionary_get(dict_mountpoints, mi->mount_point); + const DICTIONARY_ITEM *item = dictionary_get_and_acquire_item(dict_mountpoints, mi->mount_point); + if(!item) return; - m->updated = 1; + struct mount_point_metadata *m = dictionary_acquired_item_value(item); + m->updated = true; struct statvfs buff_statvfs; - if (statvfs(mi->mount_point, &buff_statvfs) < 0) { + if (statvfs(mi->mount_point_stat_path, &buff_statvfs) < 0) { if(!m->shown_error) { collector_error("DISKSPACE: failed to statvfs() mount point '%s' (disk '%s', filesystem '%s', root '%s')" - , mi->mount_point + , mi->mount_point_stat_path , mi->persistent_id , mi->filesystem?mi->filesystem:"" , mi->root?mi->root:"" ); - m->shown_error = 1; + m->shown_error = true; } - return; + goto cleanup; } - m->shown_error = 0; + m->shown_error = false; calculate_values_and_show_charts(mi, m, &buff_statvfs, update_every); + +cleanup: + dictionary_acquired_item_release(dict_mountpoints, item); } -static void diskspace_slow_worker_cleanup(void *ptr) -{ - UNUSED(ptr); +static void diskspace_slow_worker_cleanup(void *pptr) { + struct slow_worker_data *data = CLEANUP_FUNCTION_GET_PTR(pptr); + if(data) return; collector_info("cleaning up..."); @@ -524,14 +525,14 @@ static void diskspace_slow_worker_cleanup(void *ptr) #define WORKER_JOB_SLOW_CLEANUP 1 struct slow_worker_data { - netdata_thread_t *slow_thread; int update_every; }; void *diskspace_slow_worker(void *ptr) { struct slow_worker_data *data = (struct slow_worker_data *)ptr; - + CLEANUP_FUNCTION_REGISTER(diskspace_slow_worker_cleanup) cleanup_ptr = data; + worker_register("DISKSPACE_SLOW"); worker_register_job_name(WORKER_JOB_SLOW_MOUNTPOINT, "mountpoint"); worker_register_job_name(WORKER_JOB_SLOW_CLEANUP, "cleanup"); @@ -540,8 +541,6 @@ void *diskspace_slow_worker(void *ptr) int slow_update_every = data->update_every > SLOW_UPDATE_EVERY ? data->update_every : SLOW_UPDATE_EVERY; - netdata_thread_cleanup_push(diskspace_slow_worker_cleanup, data->slow_thread); - usec_t step = slow_update_every * USEC_PER_SEC; usec_t real_step = USEC_PER_SEC; heartbeat_t hb; @@ -584,13 +583,9 @@ void *diskspace_slow_worker(void *ptr) if(unlikely(!service_running(SERVICE_COLLECTORS))) break; - worker_is_busy(WORKER_JOB_SLOW_CLEANUP); - - for(bmi = slow_mountinfo_root; bmi; bmi = bmi->next) { - struct mount_point_metadata *m = dictionary_get(dict_mountpoints, bmi->mount_point); - - if (m) - mount_point_cleanup(bmi->mount_point, m, 1); + if(dict_mountpoints) { + worker_is_busy(WORKER_JOB_SLOW_CLEANUP); + mount_points_cleanup(true); } usec_t dt = now_monotonic_high_precision_usec() - start_time; @@ -602,26 +597,24 @@ void *diskspace_slow_worker(void *ptr) } } - netdata_thread_cleanup_pop(1); - free_basic_mountinfo_list(slow_mountinfo_root); return NULL; } -static void diskspace_main_cleanup(void *ptr) { - rrd_collector_finished(); - worker_unregister(); +static void diskspace_main_cleanup(void *pptr) { + struct netdata_static_thread *static_thread = CLEANUP_FUNCTION_GET_PTR(pptr); + if(!static_thread) return; - struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr; static_thread->enabled = NETDATA_MAIN_THREAD_EXITING; collector_info("cleaning up..."); - if (diskspace_slow_thread) { - netdata_thread_join(*diskspace_slow_thread, NULL); - freez(diskspace_slow_thread); - } + rrd_collector_finished(); + worker_unregister(); + + if (diskspace_slow_thread) + nd_thread_join(diskspace_slow_thread); free_basic_mountinfo_list(slow_mountinfo_tmp_root); @@ -636,12 +629,8 @@ static void diskspace_main_cleanup(void *ptr) { #error WORKER_UTILIZATION_MAX_JOB_TYPES has to be at least 3 #endif -int diskspace_function_mount_points(BUFFER *wb, int timeout __maybe_unused, const char *function __maybe_unused, - void *collector_data __maybe_unused, - rrd_function_result_callback_t result_cb, void *result_cb_data, - rrd_function_is_cancelled_cb_t is_cancelled_cb, void *is_cancelled_cb_data, - rrd_function_register_canceller_cb_t register_canceller_cb __maybe_unused, - void *register_canceller_cb_data __maybe_unused) { +int diskspace_function_mount_points(BUFFER *wb, const char *function __maybe_unused) { + netdata_mutex_lock(&slow_mountinfo_mutex); buffer_flush(wb); wb->content_type = CT_APPLICATION_JSON; @@ -651,6 +640,7 @@ int diskspace_function_mount_points(BUFFER *wb, int timeout __maybe_unused, cons buffer_json_member_add_uint64(wb, "status", HTTP_RESP_OK); buffer_json_member_add_string(wb, "type", "table"); buffer_json_member_add_time_t(wb, "update_every", 1); + buffer_json_member_add_boolean(wb, "has_history", false); buffer_json_member_add_string(wb, "help", RRDFUNCTIONS_DISKSPACE_HELP); buffer_json_member_add_array(wb, "data"); @@ -665,8 +655,8 @@ int diskspace_function_mount_points(BUFFER *wb, int timeout __maybe_unused, cons double max_inodes_reserved = 0.0; struct mount_point_metadata *mp; - dfe_start_write(dict_mountpoints, mp) { - if (!mp->function_ready) + dfe_start_read(dict_mountpoints, mp) { + if (!mp->collected) continue; buffer_json_add_array_item_array(wb); @@ -846,28 +836,22 @@ int diskspace_function_mount_points(BUFFER *wb, int timeout __maybe_unused, cons buffer_json_member_add_time_t(wb, "expires", now_realtime_sec() + 1); buffer_json_finalize(wb); - int response = HTTP_RESP_OK; - if(is_cancelled_cb && is_cancelled_cb(is_cancelled_cb_data)) { - buffer_flush(wb); - response = HTTP_RESP_CLIENT_CLOSED_REQUEST; - } - - if(result_cb) - result_cb(wb, response, result_cb_data); - - return response; + netdata_mutex_unlock(&slow_mountinfo_mutex); + return HTTP_RESP_OK; } void *diskspace_main(void *ptr) { + CLEANUP_FUNCTION_REGISTER(diskspace_main_cleanup) cleanup_ptr = ptr; + worker_register("DISKSPACE"); worker_register_job_name(WORKER_JOB_MOUNTINFO, "mountinfo"); worker_register_job_name(WORKER_JOB_MOUNTPOINT, "mountpoint"); worker_register_job_name(WORKER_JOB_CLEANUP, "cleanup"); - rrd_collector_started(); - rrd_function_add(localhost, NULL, "mount-points", 10, RRDFUNCTIONS_DISKSPACE_HELP, true, diskspace_function_mount_points, NULL); - - netdata_thread_cleanup_push(diskspace_main_cleanup, ptr); + rrd_function_add_inline(localhost, NULL, "mount-points", 10, + RRDFUNCTIONS_PRIORITY_DEFAULT, RRDFUNCTIONS_DISKSPACE_HELP, + "top", HTTP_ACCESS_ANONYMOUS_DATA, + diskspace_function_mount_points); cleanup_mount_points = config_get_boolean(CONFIG_SECTION_DISKSPACE, "remove charts of unmounted disks" , cleanup_mount_points); @@ -881,12 +865,9 @@ void *diskspace_main(void *ptr) { netdata_mutex_init(&slow_mountinfo_mutex); - diskspace_slow_thread = mallocz(sizeof(netdata_thread_t)); - - struct slow_worker_data slow_worker_data = {.slow_thread = diskspace_slow_thread, .update_every = update_every}; + struct slow_worker_data slow_worker_data = { .update_every = update_every }; - netdata_thread_create( - diskspace_slow_thread, + diskspace_slow_thread = nd_thread_create( "P[diskspace slow]", NETDATA_THREAD_OPTION_JOINABLE, diskspace_slow_worker, @@ -934,12 +915,8 @@ void *diskspace_main(void *ptr) { if(dict_mountpoints) { worker_is_busy(WORKER_JOB_CLEANUP); - dictionary_walkthrough_read(dict_mountpoints, mount_point_cleanup_cb, NULL); + mount_points_cleanup(false); } - } - worker_unregister(); - - netdata_thread_cleanup_pop(1); return NULL; } |