1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef MEMORY_DATA_PLUGIN_H 17 #define MEMORY_DATA_PLUGIN_H 18 19 #include <algorithm> 20 #include <dirent.h> 21 #include <fcntl.h> 22 #include <inttypes.h> 23 #include <iomanip> 24 #include <string> 25 #include <sys/stat.h> 26 #include <sys/types.h> 27 #include <unistd.h> 28 #include <unordered_map> 29 #include <utility> 30 31 #include "logging.h" 32 #include "memory_plugin_config.pb.h" 33 #include "memory_plugin_result.pb.h" 34 #include "smaps_stats.h" 35 36 struct Proto2StrMapping { 37 int protobufid; 38 const char* procstr; 39 }; 40 41 constexpr Proto2StrMapping meminfoMapping[] = { 42 {SysMeminfoType::MEMINFO_UNSPECIFIED, "MemUnspecified"}, 43 {SysMeminfoType::MEMINFO_MEM_TOTAL, "MemTotal"}, 44 {SysMeminfoType::MEMINFO_MEM_FREE, "MemFree"}, 45 {SysMeminfoType::MEMINFO_MEM_AVAILABLE, "MemAvailable"}, 46 {SysMeminfoType::MEMINFO_BUFFERS, "Buffers"}, 47 {SysMeminfoType::MEMINFO_CACHED, "Cached"}, 48 {SysMeminfoType::MEMINFO_SWAP_CACHED, "SwapCached"}, 49 {SysMeminfoType::MEMINFO_ACTIVE, "Active"}, 50 {SysMeminfoType::MEMINFO_INACTIVE, "Inactive"}, 51 {SysMeminfoType::MEMINFO_ACTIVE_ANON, "Active(anon)"}, 52 {SysMeminfoType::MEMINFO_INACTIVE_ANON, "Inactive(anon)"}, 53 {SysMeminfoType::MEMINFO_ACTIVE_FILE, "Active(file)"}, 54 {SysMeminfoType::MEMINFO_INACTIVE_FILE, "Inactive(file)"}, 55 {SysMeminfoType::MEMINFO_UNEVICTABLE, "Unevictable"}, 56 {SysMeminfoType::MEMINFO_MLOCKED, "Mlocked"}, 57 {SysMeminfoType::MEMINFO_SWAP_TOTAL, "SwapTotal"}, 58 {SysMeminfoType::MEMINFO_SWAP_FREE, "SwapFree"}, 59 {SysMeminfoType::MEMINFO_DIRTY, "Dirty"}, 60 {SysMeminfoType::MEMINFO_WRITEBACK, "Writeback"}, 61 {SysMeminfoType::MEMINFO_ANON_PAGES, "AnonPages"}, 62 {SysMeminfoType::MEMINFO_MAPPED, "Mapped"}, 63 {SysMeminfoType::MEMINFO_SHMEM, "Shmem"}, 64 {SysMeminfoType::MEMINFO_SLAB, "Slab"}, 65 {SysMeminfoType::MEMINFO_SLAB_RECLAIMABLE, "SReclaimable"}, 66 {SysMeminfoType::MEMINFO_SLAB_UNRECLAIMABLE, "SUnreclaim"}, 67 {SysMeminfoType::MEMINFO_KERNEL_STACK, "KernelStack"}, 68 {SysMeminfoType::MEMINFO_PAGE_TABLES, "PageTables"}, 69 {SysMeminfoType::MEMINFO_COMMIT_LIMIT, "CommitLimit"}, 70 {SysMeminfoType::MEMINFO_COMMITED_AS, "Committed_AS"}, 71 {SysMeminfoType::MEMINFO_VMALLOC_TOTAL, "VmallocTotal"}, 72 {SysMeminfoType::MEMINFO_VMALLOC_USED, "VmallocUsed"}, 73 {SysMeminfoType::MEMINFO_VMALLOC_CHUNK, "VmallocChunk"}, 74 {SysMeminfoType::MEMINFO_CMA_TOTAL, "CmaTotal"}, 75 {SysMeminfoType::MEMINFO_CMA_FREE, "CmaFree"}, 76 }; 77 78 constexpr Proto2StrMapping vmeminfoMapping[] = { 79 {SysVMeminfoType::VMEMINFO_UNSPECIFIED, "unspecified"}, 80 {SysVMeminfoType::VMEMINFO_NR_FREE_PAGES, "nr_free_pages"}, 81 {SysVMeminfoType::VMEMINFO_NR_ALLOC_BATCH, "nr_alloc_batch"}, 82 {SysVMeminfoType::VMEMINFO_NR_INACTIVE_ANON, "nr_inactive_anon"}, 83 {SysVMeminfoType::VMEMINFO_NR_ACTIVE_ANON, "nr_active_anon"}, 84 {SysVMeminfoType::VMEMINFO_NR_INACTIVE_FILE, "nr_inactive_file"}, 85 {SysVMeminfoType::VMEMINFO_NR_ACTIVE_FILE, "nr_active_file"}, 86 {SysVMeminfoType::VMEMINFO_NR_UNEVICTABLE, "nr_unevictable"}, 87 {SysVMeminfoType::VMEMINFO_NR_MLOCK, "nr_mlock"}, 88 {SysVMeminfoType::VMEMINFO_NR_ANON_PAGES, "nr_anon_pages"}, 89 {SysVMeminfoType::VMEMINFO_NR_MAPPED, "nr_mapped"}, 90 {SysVMeminfoType::VMEMINFO_NR_FILE_PAGES, "nr_file_pages"}, 91 {SysVMeminfoType::VMEMINFO_NR_DIRTY, "nr_dirty"}, 92 {SysVMeminfoType::VMEMINFO_NR_WRITEBACK, "nr_writeback"}, 93 {SysVMeminfoType::VMEMINFO_NR_SLAB_RECLAIMABLE, "nr_slab_reclaimable"}, 94 {SysVMeminfoType::VMEMINFO_NR_SLAB_UNRECLAIMABLE, "nr_slab_unreclaimable"}, 95 {SysVMeminfoType::VMEMINFO_NR_PAGE_TABLE_PAGES, "nr_page_table_pages"}, 96 {SysVMeminfoType::VMEMINFO_NR_KERNEL_STACK, "nr_kernel_stack"}, 97 {SysVMeminfoType::VMEMINFO_NR_OVERHEAD, "nr_overhead"}, 98 {SysVMeminfoType::VMEMINFO_NR_UNSTABLE, "nr_unstable"}, 99 {SysVMeminfoType::VMEMINFO_NR_BOUNCE, "nr_bounce"}, 100 {SysVMeminfoType::VMEMINFO_NR_VMSCAN_WRITE, "nr_vmscan_write"}, 101 {SysVMeminfoType::VMEMINFO_NR_VMSCAN_IMMEDIATE_RECLAIM, "nr_vmscan_immediate_reclaim"}, 102 {SysVMeminfoType::VMEMINFO_NR_WRITEBACK_TEMP, "nr_writeback_temp"}, 103 {SysVMeminfoType::VMEMINFO_NR_ISOLATED_ANON, "nr_isolated_anon"}, 104 {SysVMeminfoType::VMEMINFO_NR_ISOLATED_FILE, "nr_isolated_file"}, 105 {SysVMeminfoType::VMEMINFO_NR_SHMEM, "nr_shmem"}, 106 {SysVMeminfoType::VMEMINFO_NR_DIRTIED, "nr_dirtied"}, 107 {SysVMeminfoType::VMEMINFO_NR_WRITTEN, "nr_written"}, 108 {SysVMeminfoType::VMEMINFO_NR_PAGES_SCANNED, "nr_pages_scanned"}, 109 {SysVMeminfoType::VMEMINFO_WORKINGSET_REFAULT, "workingset_refault"}, 110 {SysVMeminfoType::VMEMINFO_WORKINGSET_ACTIVATE, "workingset_activate"}, 111 {SysVMeminfoType::VMEMINFO_WORKINGSET_NODERECLAIM, "workingset_nodereclaim"}, 112 {SysVMeminfoType::VMEMINFO_NR_ANON_TRANSPARENT_HUGEPAGES, "nr_anon_transparent_hugepages"}, 113 {SysVMeminfoType::VMEMINFO_NR_FREE_CMA, "nr_free_cma"}, 114 {SysVMeminfoType::VMEMINFO_NR_SWAPCACHE, "nr_swapcache"}, 115 {SysVMeminfoType::VMEMINFO_NR_DIRTY_THRESHOLD, "nr_dirty_threshold"}, 116 {SysVMeminfoType::VMEMINFO_NR_DIRTY_BACKGROUND_THRESHOLD, "nr_dirty_background_threshold"}, 117 {SysVMeminfoType::VMEMINFO_PGPGIN, "pgpgin"}, 118 {SysVMeminfoType::VMEMINFO_PGPGOUT, "pgpgout"}, 119 {SysVMeminfoType::VMEMINFO_PGPGOUTCLEAN, "pgpgoutclean"}, 120 {SysVMeminfoType::VMEMINFO_PSWPIN, "pswpin"}, 121 {SysVMeminfoType::VMEMINFO_PSWPOUT, "pswpou"}, 122 {SysVMeminfoType::VMEMINFO_PGALLOC_DMA, "pgalloc_dma"}, 123 {SysVMeminfoType::VMEMINFO_PGALLOC_NORMAL, "pgalloc_normal"}, 124 {SysVMeminfoType::VMEMINFO_PGALLOC_MOVABLE, "pgalloc_movable"}, 125 {SysVMeminfoType::VMEMINFO_PGFREE, "pgfree"}, 126 {SysVMeminfoType::VMEMINFO_PGACTIVATE, "pgactivate"}, 127 {SysVMeminfoType::VMEMINFO_PGDEACTIVATE, "pgdeactivate"}, 128 {SysVMeminfoType::VMEMINFO_PGFAULT, "pgfault"}, 129 {SysVMeminfoType::VMEMINFO_PGMAJFAULT, "pgmajfault"}, 130 {SysVMeminfoType::VMEMINFO_PGREFILL_DMA, "pgrefill_dma"}, 131 {SysVMeminfoType::VMEMINFO_PGREFILL_NORMAL, "pgrefill_normal"}, 132 {SysVMeminfoType::VMEMINFO_PGREFILL_MOVABLE, "pgrefill_movable"}, 133 {SysVMeminfoType::VMEMINFO_PGSTEAL_KSWAPD_DMA, "pgsteal_kswapd_dma"}, 134 {SysVMeminfoType::VMEMINFO_PGSTEAL_KSWAPD_NORMAL, "pgsteal_kswapd_normal"}, 135 {SysVMeminfoType::VMEMINFO_PGSTEAL_KSWAPD_MOVABLE, "pgsteal_kswapd_movable"}, 136 {SysVMeminfoType::VMEMINFO_PGSTEAL_DIRECT_DMA, "pgsteal_direct_dma"}, 137 {SysVMeminfoType::VMEMINFO_PGSTEAL_DIRECT_NORMAL, "pgsteal_direct_normal"}, 138 {SysVMeminfoType::VMEMINFO_PGSTEAL_DIRECT_MOVABLE, "pgsteal_direct_movable"}, 139 {SysVMeminfoType::VMEMINFO_PGSCAN_KSWAPD_DMA, "pgscan_kswapd_dma"}, 140 {SysVMeminfoType::VMEMINFO_PGSCAN_KSWAPD_NORMAL, "pgscan_kswapd_normal"}, 141 {SysVMeminfoType::VMEMINFO_PGSCAN_KSWAPD_MOVABLE, "pgscan_kswapd_movable"}, 142 {SysVMeminfoType::VMEMINFO_PGSCAN_DIRECT_DMA, "pgscan_direct_dma"}, 143 {SysVMeminfoType::VMEMINFO_PGSCAN_DIRECT_NORMAL, "pgscan_direct_normal"}, 144 {SysVMeminfoType::VMEMINFO_PGSCAN_DIRECT_MOVABLE, "pgscan_direct_movable"}, 145 {SysVMeminfoType::VMEMINFO_PGSCAN_DIRECT_THROTTLE, "pgscan_direct_throttle"}, 146 {SysVMeminfoType::VMEMINFO_PGINODESTEAL, "pginodesteal"}, 147 {SysVMeminfoType::VMEMINFO_SLABS_SCANNED, "slabs_scanned"}, 148 {SysVMeminfoType::VMEMINFO_KSWAPD_INODESTEAL, "kswapd_inodesteal"}, 149 {SysVMeminfoType::VMEMINFO_KSWAPD_LOW_WMARK_HIT_QUICKLY, "kswapd_low_wmark_hit_quickly"}, 150 {SysVMeminfoType::VMEMINFO_KSWAPD_HIGH_WMARK_HIT_QUICKLY, "kswapd_high_wmark_hit_quickly"}, 151 {SysVMeminfoType::VMEMINFO_PAGEOUTRUN, "pageoutrun"}, 152 {SysVMeminfoType::VMEMINFO_ALLOCSTALL, "allocstall"}, 153 {SysVMeminfoType::VMEMINFO_PGROTATED, "pgrotated"}, 154 {SysVMeminfoType::VMEMINFO_DROP_PAGECACHE, "drop_pagecache"}, 155 {SysVMeminfoType::VMEMINFO_DROP_SLAB, "drop_slab"}, 156 {SysVMeminfoType::VMEMINFO_PGMIGRATE_SUCCESS, "pgmigrate_success"}, 157 {SysVMeminfoType::VMEMINFO_PGMIGRATE_FAIL, "pgmigrate_fail"}, 158 {SysVMeminfoType::VMEMINFO_COMPACT_MIGRATE_SCANNED, "compact_migrate_scanned"}, 159 {SysVMeminfoType::VMEMINFO_COMPACT_FREE_SCANNED, "compact_free_scanned"}, 160 {SysVMeminfoType::VMEMINFO_COMPACT_ISOLATED, "compact_isolated"}, 161 {SysVMeminfoType::VMEMINFO_COMPACT_STALL, "compact_stall"}, 162 {SysVMeminfoType::VMEMINFO_COMPACT_FAIL, "compact_fail"}, 163 {SysVMeminfoType::VMEMINFO_COMPACT_SUCCESS, "compact_success"}, 164 {SysVMeminfoType::VMEMINFO_COMPACT_DAEMON_WAKE, "compact_daemon_wake"}, 165 {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_CULLED, "unevictable_pgs_culled"}, 166 {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_SCANNED, "unevictable_pgs_scanned"}, 167 {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_RESCUED, "unevictable_pgs_rescued"}, 168 {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_MLOCKED, "unevictable_pgs_mlocked"}, 169 {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_MUNLOCKED, "unevictable_pgs_munlocked"}, 170 {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_CLEARED, "unevictable_pgs_cleared"}, 171 {SysVMeminfoType::VMEMINFO_UNEVICTABLE_PGS_STRANDED, "unevictable_pgs_stranded"}, 172 {SysVMeminfoType::VMEMINFO_NR_ZSPAGES, "nr_zspages"}, 173 {SysVMeminfoType::VMEMINFO_NR_ION_HEAP, "nr_ion_heap"}, 174 {SysVMeminfoType::VMEMINFO_NR_GPU_HEAP, "nr_gpu_heap"}, 175 {SysVMeminfoType::VMEMINFO_ALLOCSTALL_DMA, "allocstall_dma"}, 176 {SysVMeminfoType::VMEMINFO_ALLOCSTALL_MOVABLE, "allocstall_movable"}, 177 {SysVMeminfoType::VMEMINFO_ALLOCSTALL_NORMAL, "allocstall_normal"}, 178 {SysVMeminfoType::VMEMINFO_COMPACT_DAEMON_FREE_SCANNED, "compact_daemon_free_scanned"}, 179 {SysVMeminfoType::VMEMINFO_COMPACT_DAEMON_MIGRATE_SCANNED, "compact_daemon_migrate_scanned"}, 180 {SysVMeminfoType::VMEMINFO_NR_FASTRPC, "nr_fastrpc"}, 181 {SysVMeminfoType::VMEMINFO_NR_INDIRECTLY_RECLAIMABLE, "nr_indirectly_reclaimable"}, 182 {SysVMeminfoType::VMEMINFO_NR_ION_HEAP_POOL, "nr_ion_heap_pool"}, 183 {SysVMeminfoType::VMEMINFO_NR_KERNEL_MISC_RECLAIMABLE, "nr_kernel_misc_reclaimable"}, 184 {SysVMeminfoType::VMEMINFO_NR_SHADOW_CALL_STACK_BYTES, "nr_shadow_call_stack_bytes"}, 185 {SysVMeminfoType::VMEMINFO_NR_SHMEM_HUGEPAGES, "nr_shmem_hugepages"}, 186 {SysVMeminfoType::VMEMINFO_NR_SHMEM_PMDMAPPED, "nr_shmem_pmdmapped"}, 187 {SysVMeminfoType::VMEMINFO_NR_UNRECLAIMABLE_PAGES, "nr_unreclaimable_pages"}, 188 {SysVMeminfoType::VMEMINFO_NR_ZONE_ACTIVE_ANON, "nr_zone_active_anon"}, 189 {SysVMeminfoType::VMEMINFO_NR_ZONE_ACTIVE_FILE, "nr_zone_active_file"}, 190 {SysVMeminfoType::VMEMINFO_NR_ZONE_INACTIVE_ANON, "nr_zone_inactive_anon"}, 191 {SysVMeminfoType::VMEMINFO_NR_ZONE_INACTIVE_FILE, "nr_zone_inactive_file"}, 192 {SysVMeminfoType::VMEMINFO_NR_ZONE_UNEVICTABLE, "nr_zone_unevictable"}, 193 {SysVMeminfoType::VMEMINFO_NR_ZONE_WRITE_PENDING, "nr_zone_write_pending"}, 194 {SysVMeminfoType::VMEMINFO_OOM_KILL, "oom_kill"}, 195 {SysVMeminfoType::VMEMINFO_PGLAZYFREE, "pglazyfree"}, 196 {SysVMeminfoType::VMEMINFO_PGLAZYFREED, "pglazyfreed"}, 197 {SysVMeminfoType::VMEMINFO_PGREFILL, "pgrefill"}, 198 {SysVMeminfoType::VMEMINFO_PGSCAN_DIRECT, "pgscan_direct"}, 199 {SysVMeminfoType::VMEMINFO_PGSCAN_KSWAPD, "pgscan_kswapd"}, 200 {SysVMeminfoType::VMEMINFO_PGSKIP_DMA, "pgskip_dma"}, 201 {SysVMeminfoType::VMEMINFO_PGSKIP_MOVABLE, "pgskip_movable"}, 202 {SysVMeminfoType::VMEMINFO_PGSKIP_NORMAL, "pgskip_normal"}, 203 {SysVMeminfoType::VMEMINFO_PGSTEAL_DIRECT, "pgsteal_direct"}, 204 {SysVMeminfoType::VMEMINFO_PGSTEAL_KSWAPD, "pgsteal_kswapd"}, 205 {SysVMeminfoType::VMEMINFO_SWAP_RA, "swap_ra"}, 206 {SysVMeminfoType::VMEMINFO_SWAP_RA_HIT, "swap_ra_hit"}, 207 {SysVMeminfoType::VMEMINFO_WORKINGSET_RESTORE, "workingset_restore"}, 208 }; 209 210 struct ProcStatusMapping { 211 int procid; 212 const char* procstr; 213 }; 214 215 enum StatusType { 216 PRO_TGID = 1, 217 PRO_NAME, 218 PRO_VMSIZE, 219 PRO_VMRSS, 220 PRO_RSSANON, 221 PRO_RSSFILE, 222 PRO_RSSSHMEM, 223 PRO_VMSWAP, 224 PRO_VMLCK, 225 PRO_VMHWM, 226 }; 227 228 constexpr ProcStatusMapping procStatusMapping[] = { 229 {StatusType::PRO_TGID, "Tgid"}, {StatusType::PRO_NAME, "Name"}, {StatusType::PRO_VMSIZE, "VmSize"}, 230 {StatusType::PRO_VMRSS, "VmRSS"}, {StatusType::PRO_RSSANON, "RssAnon"}, {StatusType::PRO_RSSFILE, "RssFile"}, 231 {StatusType::PRO_RSSSHMEM, "RssShmem"}, {StatusType::PRO_VMSWAP, "VmSwap"}, {StatusType::PRO_VMLCK, "VmLck"}, 232 {StatusType::PRO_VMHWM, "VmHWM"}, 233 }; 234 235 enum ErrorType { 236 RET_NULL_ADDR, 237 RET_IVALID_PID, 238 RET_TGID_VALUE_NULL, 239 RET_FAIL = -1, 240 RET_SUCC = 0, 241 }; 242 243 enum FileType { 244 FILE_STATUS = 0, 245 FILE_OOM, 246 FILE_SMAPS, 247 }; 248 249 struct ProcfdMapping { 250 int procid; 251 const char* file; 252 }; 253 254 constexpr ProcfdMapping procfdMapping[] = { 255 {FileType::FILE_STATUS, "status"}, 256 {FileType::FILE_OOM, "oom_score_adj"}, 257 {FileType::FILE_SMAPS, "smaps"}, 258 }; 259 260 class MemoryDataPlugin { 261 public: 262 MemoryDataPlugin(); 263 ~MemoryDataPlugin(); 264 int Start(const uint8_t* configData, uint32_t configSize); 265 int Report(uint8_t* configData, uint32_t configSize); 266 int Stop(); SetPath(char * path)267 void SetPath(char* path) 268 { 269 testpath_ = path; 270 }; 271 void WriteProcesseList(MemoryData& data); 272 void WriteProcinfoByPidfds(ProcessMemoryInfo* processinfo, int32_t pid); 273 DIR* OpenDestDir(const char* dirPath); 274 int32_t GetValidPid(DIR* dirp); 275 // for test change static 276 int ParseNumber(std::string line); 277 278 private: 279 /* data */ 280 MemoryConfig protoConfig_; 281 282 std::unique_ptr<uint8_t[]> buffer_; 283 284 int meminfoFd_; 285 int vmstatFd_; 286 std::map<std::string, int> meminfoCounters_; 287 std::map<std::string, int> vmstatCounters_; 288 289 void InitProto2StrVector(); 290 std::vector<const char*> meminfoStrList_; 291 std::vector<const char*> vmstatStrList_; 292 // SmapsStats * 293 void WriteVmstat(MemoryData& data); 294 void WriteMeminfo(MemoryData& data); 295 296 std::unordered_map<int32_t, std::vector<int>> pidFds_; 297 std::vector<int32_t> seenPids_; 298 char* testpath_; 299 int32_t err_; 300 int32_t ReadFile(int fd); 301 std::vector<int> OpenProcPidFiles(int32_t pid); 302 int32_t ReadProcPidFile(int32_t pid, const char* pFileName); 303 void WriteProcessInfo(MemoryData& data, int32_t pid); 304 void SetEmptyProcessInfo(ProcessMemoryInfo* processinfo); 305 void WriteOomInfo(ProcessMemoryInfo* processinfo, int32_t pid); 306 void WriteProcess(ProcessMemoryInfo* processinfo, const char* pFile, uint32_t fileLen, int32_t pid); 307 void WriteAppsummary(ProcessMemoryInfo* processinfo, SmapsStats& smapInfo); 308 void SetProcessInfo(ProcessMemoryInfo* processinfo, int key, const char* word); 309 bool StringToUll(const char* word, uint64_t& value); 310 311 bool BufnCmp(const char* src, int srcLen, const char* key, int keyLen); 312 bool addPidBySort(int32_t pid); 313 int GetProcStatusId(const char* src, int srcLen); 314 315 bool ParseMemInfo(const char* data, ProcessMemoryInfo* memoryInfo); 316 bool GetMemInfoByMemoryService(uint32_t pid, ProcessMemoryInfo* memoryInfo); 317 int InitMemVmemFd(); 318 }; 319 320 #endif 321