diff --git a/src/detection/memory/memory_linux.c b/src/detection/memory/memory_linux.c index 74d20a031..fea8c2cf1 100644 --- a/src/detection/memory/memory_linux.c +++ b/src/detection/memory/memory_linux.c @@ -1,8 +1,5 @@ #include "memory.h" #include "common/io.h" -#include "common/mallocHelper.h" - -#include const char* ffDetectMemory(FFMemoryResult* ram) { char buf[PROC_FILE_BUFFSIZ]; @@ -21,34 +18,34 @@ const char* ffDetectMemory(FFMemoryResult* ram) { sReclaimable = 0; char* token = NULL; - if ((token = strstr(buf, "MemTotal:")) != NULL) { + if ((token = memmem(buf, (size_t) nRead, "MemTotal:", strlen("MemTotal:"))) != NULL) { memTotal = strtoul(token + strlen("MemTotal:"), NULL, 10); } else { return "MemTotal not found in /proc/meminfo"; } - if ((token = strstr(buf, "MemAvailable:")) != NULL) { + if ((token = memmem(buf, (size_t) nRead, "MemAvailable:", strlen("MemAvailable:"))) != NULL) { memAvailable = strtoul(token + strlen("MemAvailable:"), NULL, 10); } - if (memAvailable == 0 || memAvailable >= memTotal) // MemAvailable can be unreasonable. #1988 - { - if ((token = strstr(buf, "MemFree:")) != NULL) { + + if (memAvailable == 0 || memAvailable >= memTotal) { // MemAvailable can be unreasonable. #1988 + if ((token = memmem(buf, (size_t) nRead, "MemFree:", strlen("MemFree:"))) != NULL) { memFree = strtoul(token + strlen("MemFree:"), NULL, 10); } - if ((token = strstr(buf, "Buffers:")) != NULL) { + if ((token = memmem(buf, (size_t) nRead, "Buffers:", strlen("Buffers:"))) != NULL) { buffers = strtoul(token + strlen("Buffers:"), NULL, 10); } - if ((token = strstr(buf, "Cached:")) != NULL) { + if ((token = memmem(buf, (size_t) nRead, "Cached:", strlen("Cached:"))) != NULL) { cached = strtoul(token + strlen("Cached:"), NULL, 10); } - if ((token = strstr(buf, "Shmem:")) != NULL) { + if ((token = memmem(buf, (size_t) nRead, "Shmem:", strlen("Shmem:"))) != NULL) { shmem = strtoul(token + strlen("Shmem:"), NULL, 10); } - if ((token = strstr(buf, "SReclaimable:")) != NULL) { + if ((token = memmem(buf, (size_t) nRead, "SReclaimable:", strlen("SReclaimable:"))) != NULL) { sReclaimable = strtoul(token + strlen("SReclaimable:"), NULL, 10); } @@ -58,5 +55,47 @@ const char* ffDetectMemory(FFMemoryResult* ram) { ram->bytesTotal = memTotal * 1024lu; ram->bytesUsed = (memTotal - memAvailable) * 1024lu; + uint64_t arcSize = 0; + nRead = ffReadFileData("/proc/spl/kstat/zfs/arcstats", ARRAY_SIZE(buf) - 1, buf); + if (nRead > 0) { + buf[nRead] = '\0'; + // 24 1 0x01 148 40256 2053603602 851614020716 + // name type data + // hits 4 752 + + // Skip first line + const char* p = memchr(buf, '\n', (size_t) nRead); + if (__builtin_expect(p != NULL, true)) { + ++p; + nRead -= (p - buf); + assert(nRead > 0); + + // Find line offset of data + const char* pData = memmem(p, (size_t) nRead, "data\n", strlen("data\n")); + if (__builtin_expect(pData != NULL, true)) { + uint32_t dataOffset = (uint32_t) (pData - p); + p += dataOffset + strlen("data\n"); + nRead -= (ssize_t) (dataOffset + strlen("data\n")); + assert(nRead > 0); + + if ((token = memmem(p, (size_t) nRead, "\nsize ", strlen("\nsize "))) != NULL) { + arcSize = strtoul(token + 1 + dataOffset, NULL, 10); + if (arcSize > 0) { + uint64_t arcMin = 0; + if ((token = memmem(p, (size_t) nRead, "\nc_min ", strlen("\nc_min "))) != NULL) { + arcMin = strtoul(token + 1 + dataOffset, NULL, 10); + if (arcSize > arcMin) { + arcSize -= arcMin; + if (ram->bytesUsed > arcSize) { + ram->bytesUsed -= arcSize; + } + } + } + } + } + } + } + } + return NULL; }