| 1 | #include "plugin_proc.h" |
| 2 | |
| 3 | static int is_dir_mounted(const char *path) { |
| 4 | struct stat stat_buf, parent_stat_buf; |
| 5 | char parent_path[PATH_MAX]; |
| 6 | |
| 7 | if (stat(path, &stat_buf) == -1) { |
| 8 | return -1; |
| 9 | } |
| 10 | |
| 11 | snprintfz(parent_path, sizeof(parent_path), "%s/..", path); |
| 12 | if (stat(parent_path, &parent_stat_buf) == -1) { |
| 13 | return -1; |
| 14 | } |
| 15 | |
| 16 | return stat_buf.st_dev != parent_stat_buf.st_dev; |
| 17 | } |
| 18 | |
| 19 | int do_run_reboot_required(int update_every, usec_t dt) { |
| 20 | (void)dt; |
| 21 | |
| 22 | static char *signal_file_path = NULL; |
| 23 | static RRDSET *st = NULL; |
| 24 | static RRDDIM *rd_required = NULL; |
| 25 | static RRDDIM *rd_not_required = NULL; |
| 26 | |
| 27 | if (!signal_file_path) { |
| 28 | char filename[FILENAME_MAX + 1]; |
| 29 | snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/var/run"); |
| 30 | |
| 31 | // Disable monitoring if running inside a container and the directory is not mounted from the host |
| 32 | if (getenv("NETDATA_LISTENER_PORT") != NULL) { |
| 33 | if (!netdata_configured_host_prefix || !*netdata_configured_host_prefix || is_dir_mounted(filename) != 1) { |
| 34 | return 1; |
| 35 | } |
| 36 | } else if (access("/usr/bin/dpkg", X_OK) != 0) { |
| 37 | // reboot-required only used by Debian-based systems |
| 38 | return 1; |
| 39 | } |
| 40 | |
| 41 | snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/var/run/reboot-required"); |
| 42 | signal_file_path = strdupz(filename); |
| 43 | } |
| 44 | |
| 45 | if (unlikely(!st)) { |
| 46 | st = rrdset_create_localhost( |
| 47 | "system", |
| 48 | "post_update_reboot_status", |
| 49 | NULL, |
| 50 | "uptime", |
| 51 | NULL, |
| 52 | "Post-Update Reboot Status", |
| 53 | "status", |
| 54 | PLUGIN_PROC_NAME, |
| 55 | "/run/reboot_required", |
| 56 | NETDATA_CHART_PRIO_SYSTEM_REBOOT_REQUIRED, |
| 57 | update_every, |
| 58 | RRDSET_TYPE_LINE); |
| 59 | |
| 60 | rd_not_required = rrddim_add(st, "not_required", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); |
| 61 | rd_required = rrddim_add(st, "required", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE); |
| 62 | } |
| 63 | |
| 64 | struct stat buf; |
| 65 | bool exists = (stat(signal_file_path, &buf) == 0); |
| 66 | |
| 67 | rrddim_set_by_pointer(st, rd_not_required, exists ? 0 : 1); |
| 68 | rrddim_set_by_pointer(st, rd_required, exists ? 1 : 0); |
| 69 | rrdset_done(st); |
| 70 | |
| 71 | return 0; |
| 72 | } |