From 17e5613e13c5a2fae5cd3a45016a72e61f5d6000 Mon Sep 17 00:00:00 2001 From: ChenJie Date: Fri, 11 Feb 2022 10:59:55 +0800 Subject: [PATCH 1/2] add interfaces for killer Signed-off-by: ChenJie --- common/include/kernel_interface.h | 15 +++ common/src/kernel_interface.cpp | 97 ++++++++++++++++++- test/unittest/phone/kernel_interface_test.cpp | 34 +++++++ 3 files changed, 145 insertions(+), 1 deletion(-) diff --git a/common/include/kernel_interface.h b/common/include/kernel_interface.h index 31979d2..7dc24f8 100644 --- a/common/include/kernel_interface.h +++ b/common/include/kernel_interface.h @@ -26,6 +26,16 @@ namespace OHOS { namespace Memory { + +struct ProcInfo { + int tgid; + int pid; + int pidfd; + int size; + std::string name; + std::string status; +}; + class KernelInterface { DECLARE_SINGLE_INSTANCE(KernelInterface); @@ -54,7 +64,12 @@ public: std::string JoinPath(const std::string& prefixPath, const std::string& subPath); std::string JoinPath(const std::string& prefixPath, const std::string& midPath, const std::string& subPath); + bool GetPidProcInfo(struct ProcInfo &procInfo); + int GetCurrentBuffer(); + int KillOneProcessByPid(int pid); + static const std::string MEMCG_BASE_PATH; + static const std::string CURRENT_BUFFER_PATH; static constexpr mode_t FILE_MODE_664 = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH; // -rw-rw-r-- static constexpr mode_t FILE_MODE_644 = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // -rw-r--r-- static constexpr mode_t FILE_MODE_660 = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; diff --git a/common/src/kernel_interface.cpp b/common/src/kernel_interface.cpp index bdf58d6..1df9d27 100644 --- a/common/src/kernel_interface.cpp +++ b/common/src/kernel_interface.cpp @@ -25,6 +25,9 @@ #include +#include +#include + namespace OHOS { namespace Memory { namespace { @@ -34,10 +37,12 @@ const std::string TAG = "KernelInterface"; IMPLEMENT_SINGLE_INSTANCE(KernelInterface); const std::string KernelInterface::MEMCG_BASE_PATH = "/dev/memcg"; +const std::string KernelInterface::CURRENT_BUFFER_PATH = "/dev/memcg/memory.zswapd_pressure_show"; + bool KernelInterface::EchoToPath(const char* path, const char* content) { - uint32_t fd = open(path, O_RDWR, 0666); + int fd = open(path, O_RDWR, 0666); if (fd == -1) { HILOGE("echo %{public}s > %{public}s failed: file is not open", content, path); return false; @@ -253,5 +258,95 @@ std::string KernelInterface::JoinPath(const std::string& prefixPath, const std:: { return JoinPath(JoinPath(prefixPath, midPath), subPath); } + +bool KernelInterface::GetPidProcInfo(struct ProcInfo &procInfo) +{ + HILOGD("called!"); + + std::string statPath = JoinPath("/proc/", std::to_string(procInfo.pid), "/stat"); + HILOGD("statPath=%{public}s", statPath.c_str()); + + // format like: + // 1 (init) S 0 0 0 0 -1 4210944 1 ... + std::string stat, statm, statPid, vss, rss; + if (!ReadFromFile(statPath, stat)) { + return false; + } + HILOGD("stat = [%{public}s]", stat.c_str()); + std::istringstream isStat(stat); + isStat >> statPid >> procInfo.name >> procInfo.status; + HILOGD("pid=[%{public}d], name=[%{public}s], status=[%{public}s]", + procInfo.pid, procInfo.name.c_str(), procInfo.status.c_str()); + + if (statPid != std::to_string(procInfo.pid)) { + return false; + } + + std::string statmPath = JoinPath("/proc/", std::to_string(procInfo.pid), "/statm"); + HILOGD("statmPath=%{public}s", statmPath.c_str()); + // format like: + // 640 472 369 38 0 115 0 + if (!ReadFromFile(statmPath, statm)) { + return false; + } + HILOGD("statm = [%{public}s]", statm.c_str()); + std::istringstream isStatm(statm); + isStatm >> vss >> rss; // pages + HILOGD("vss=[%{public}s], rss=[%{public}s]", vss.c_str(), rss.c_str()); + + procInfo.size = atoi(rss.c_str()) * 4; + HILOGI("GetProcInfo success: name is %{public}s, status is %{public}s, size = %{public}d", + procInfo.name.c_str(), procInfo.status.c_str(), procInfo.size); + return true; +} + +int KernelInterface::GetCurrentBuffer() +{ + HILOGD("called!"); + std::string content, buffer, size, buffer_; + + if (!ReadFromFile(CURRENT_BUFFER_PATH, content)) { + HILOGE("read %{public}s failed, return max value", CURRENT_BUFFER_PATH.c_str()); + return 300 * 1024; + } + HILOGI("read %{public}s success, content=[%{public}s]", CURRENT_BUFFER_PATH.c_str(), content.c_str()); + + std::istringstream is(content); + is >> buffer >> size >> buffer_; + + HILOGI("GetCurrentBuffer success: %{public}s MB", buffer_.c_str()); + return atoi(buffer_.c_str()) * 1024; +} + +int KernelInterface::KillOneProcessByPid(int pid) +{ + HILOGD("called! pid=%{public}d", pid); + struct ProcInfo procInfo; + int freedBuffer = 0; + procInfo.pid = pid; + + if (!GetPidProcInfo(procInfo)) { + HILOGE("GetPidProcInfo fail !!!"); + goto out; + } + + if (procInfo.status == "D") { + HILOGE("Task %{public}s is at D status!", procInfo.name.c_str()); + goto out; + } + + if (kill(pid, SIGKILL)) { + HILOGE("Kill %{public}s errno=%{public}d!", procInfo.name.c_str(), errno); + } + HILOGE("%{public}s has been Killed ! (pid=%{public}d, freedSize=%{public}d KB)", + procInfo.name.c_str(), procInfo.pid, procInfo.size); + + freedBuffer = procInfo.size; +out: + return freedBuffer; +} + + + } // namespace Memory } // namespace OHOS diff --git a/test/unittest/phone/kernel_interface_test.cpp b/test/unittest/phone/kernel_interface_test.cpp index b1920ea..7077376 100644 --- a/test/unittest/phone/kernel_interface_test.cpp +++ b/test/unittest/phone/kernel_interface_test.cpp @@ -57,5 +57,39 @@ HWTEST_F(MemMgrTest, EchoToPath_InvalidPath, TestSize.Level1) bool ret = KernelInterface::GetInstance().EchoToPath("", ""); EXPECT_EQ(ret, false); } + +HWTEST_F(MemMgrTest, GetPidProcInfoTest, TestSize.Level1) +{ + ProcInfo procInfo; + procInfo.pid = 1; + bool ret = KernelInterface::GetInstance().GetPidProcInfo(procInfo); + printf("pid=[%d], name=[%s], status=[%s], size=[%d KB]\n", + procInfo.pid, procInfo.name.c_str(), procInfo.status.c_str(), procInfo.size); + + EXPECT_EQ(ret, true); +} + +HWTEST_F(MemMgrTest, GetCurrentBufferTest, TestSize.Level1) +{ + int buffer = KernelInterface::GetInstance().GetCurrentBuffer(); + printf("buffer=%d", buffer); + EXPECT_GT(buffer, 0); +} + +HWTEST_F(MemMgrTest, KillOneProcessByPidTest, TestSize.Level1) +{ + int pid = -1; + printf("please input pid to kill\n"); + scanf("%d", &pid); + ProcInfo procInfo; + procInfo.pid = pid; + bool ret = KernelInterface::GetInstance().GetPidProcInfo(procInfo); + EXPECT_EQ(ret, true); + + int killedSize = KernelInterface::GetInstance().KillOneProcessByPid(pid); + printf("killedSize=%d", killedSize); + EXPECT_EQ(killedSize, procInfo.size); +} + } } -- Gitee From 209b78a71133630e7f84a9618d54ff896fc1ff9b Mon Sep 17 00:00:00 2001 From: ChenJie Date: Fri, 11 Feb 2022 11:19:01 +0800 Subject: [PATCH 2/2] modify CodeCheck problems Signed-off-by: ChenJie --- common/include/kernel_interface.h | 3 +++ common/src/kernel_interface.cpp | 12 ++++-------- test/unittest/phone/kernel_interface_test.cpp | 2 -- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/common/include/kernel_interface.h b/common/include/kernel_interface.h index 7dc24f8..88e0cb8 100644 --- a/common/include/kernel_interface.h +++ b/common/include/kernel_interface.h @@ -26,6 +26,9 @@ namespace OHOS { namespace Memory { +#define PAGE_TO_KB 4 +#define KB_PER_MB 1024 +#define MAX_BUFFER_KB (300 * KB_PER_MB) struct ProcInfo { int tgid; diff --git a/common/src/kernel_interface.cpp b/common/src/kernel_interface.cpp index 1df9d27..f28c3aa 100644 --- a/common/src/kernel_interface.cpp +++ b/common/src/kernel_interface.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include namespace OHOS { namespace Memory { @@ -39,7 +39,6 @@ IMPLEMENT_SINGLE_INSTANCE(KernelInterface); const std::string KernelInterface::MEMCG_BASE_PATH = "/dev/memcg"; const std::string KernelInterface::CURRENT_BUFFER_PATH = "/dev/memcg/memory.zswapd_pressure_show"; - bool KernelInterface::EchoToPath(const char* path, const char* content) { int fd = open(path, O_RDWR, 0666); @@ -294,7 +293,7 @@ bool KernelInterface::GetPidProcInfo(struct ProcInfo &procInfo) isStatm >> vss >> rss; // pages HILOGD("vss=[%{public}s], rss=[%{public}s]", vss.c_str(), rss.c_str()); - procInfo.size = atoi(rss.c_str()) * 4; + procInfo.size = atoi(rss.c_str()) * PAGE_TO_KB; HILOGI("GetProcInfo success: name is %{public}s, status is %{public}s, size = %{public}d", procInfo.name.c_str(), procInfo.status.c_str(), procInfo.size); return true; @@ -307,7 +306,7 @@ int KernelInterface::GetCurrentBuffer() if (!ReadFromFile(CURRENT_BUFFER_PATH, content)) { HILOGE("read %{public}s failed, return max value", CURRENT_BUFFER_PATH.c_str()); - return 300 * 1024; + return MAX_BUFFER_KB; } HILOGI("read %{public}s success, content=[%{public}s]", CURRENT_BUFFER_PATH.c_str(), content.c_str()); @@ -315,7 +314,7 @@ int KernelInterface::GetCurrentBuffer() is >> buffer >> size >> buffer_; HILOGI("GetCurrentBuffer success: %{public}s MB", buffer_.c_str()); - return atoi(buffer_.c_str()) * 1024; + return atoi(buffer_.c_str()) * KB_PER_MB; } int KernelInterface::KillOneProcessByPid(int pid) @@ -345,8 +344,5 @@ int KernelInterface::KillOneProcessByPid(int pid) out: return freedBuffer; } - - - } // namespace Memory } // namespace OHOS diff --git a/test/unittest/phone/kernel_interface_test.cpp b/test/unittest/phone/kernel_interface_test.cpp index 7077376..6357480 100644 --- a/test/unittest/phone/kernel_interface_test.cpp +++ b/test/unittest/phone/kernel_interface_test.cpp @@ -65,7 +65,6 @@ HWTEST_F(MemMgrTest, GetPidProcInfoTest, TestSize.Level1) bool ret = KernelInterface::GetInstance().GetPidProcInfo(procInfo); printf("pid=[%d], name=[%s], status=[%s], size=[%d KB]\n", procInfo.pid, procInfo.name.c_str(), procInfo.status.c_str(), procInfo.size); - EXPECT_EQ(ret, true); } @@ -90,6 +89,5 @@ HWTEST_F(MemMgrTest, KillOneProcessByPidTest, TestSize.Level1) printf("killedSize=%d", killedSize); EXPECT_EQ(killedSize, procInfo.size); } - } } -- Gitee