/* * Check available memory, only warn/reboot if no swap (left). On an * embedded system there may not be a swap, so memory leaks can be quite * nasty. On a "regular" system you do not want to run out of swap. */ static void cb(uev_t *w, void *UNUSED(arg), int UNUSED(events)) { char buf[80]; FILE *fp; meminfo_t meminfo[] = { { "MemTotal:", 0 }, { "MemFree:", 0 }, { "Cached:", 0 }, { "SwapCached:", 0 }, { "SwapTotal:", 0 }, { "SwapFree:", 0 }, { NULL, 0 } }; fp = fopen(PROC_FILE, "r"); if (!fp) { DEBUG("Cannot read %s, maybe /proc is not mounted yet", PROC_FILE); return; } /* * $ cat /proc/meminfo * MemTotal: 8120568 kB * MemFree: 2298932 kB * Cached: 1907240 kB * SwapCached: 0 kB * SwapTotal: 15859708 kB * SwapFree: 15859708 kB */ while (fgets(buf, sizeof(buf), fp)) { int i; for (i = 0; meminfo[i].str; i++) { size_t len = strlen(meminfo[i].str); if (!strncmp(buf, meminfo[i].str, len)) { char *ptr = buf + len + 1; while (isspace(*ptr)) ptr++; sscanf(ptr, "%u kB", &meminfo[i].val); } } } fclose(fp); DEBUG("Total RAM: %u kB, free: %u kB, cached: %u kB, Total Swap: %u kB, free: %u kB, cached: %u kB", meminfo[MEMTOTAL].val, meminfo[MEMFREE].val, meminfo[MEMCACHED].val, meminfo[SWAPTOTAL].val, meminfo[SWAPFREE].val, meminfo[SWAPCACHED].val); /* Enable trigger warnings by default only on systems without swap */ if (meminfo[SWAPTOTAL].val == 0) { double level; uint32_t free = meminfo[MEMFREE].val + meminfo[MEMCACHED].val; uint32_t used = meminfo[MEMTOTAL].val - free; level = (double)used / (double)meminfo[MEMTOTAL].val; DEBUG("RAM usage level %.0f%%, warning: %.0f%%, critical: %.0f%%", level * 100, warning * 100, critical * 100); if (level > warning) { if (level > critical) { ERROR("Memory usage too high, %.2f > %0.2f, rebooting system ...", level, critical); wdt_forced_reboot(w->ctx, getpid(), wdt_plugin_label("meminfo"), WDOG_MEMORY_LEAK); return; } WARN("Memory use very high, %.2f > %0.2f, possible leak!", level, warning); } } }
void reboot_cb(uev_t *w, void *UNUSED(arg), int UNUSED(events)) { wdt_forced_reboot(w->ctx, 1, "init", WDOG_FORCED_RESET); }