Merge "Fix usage of Read instead of ReadFully."
diff --git a/adb/client/adb_install.cpp b/adb/client/adb_install.cpp
index bd5508c..0d0375d 100644
--- a/adb/client/adb_install.cpp
+++ b/adb/client/adb_install.cpp
@@ -24,12 +24,14 @@
#include <string>
#include <vector>
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+
#include "adb.h"
#include "adb_client.h"
+#include "adb_unique_fd.h"
#include "adb_utils.h"
-#include "android-base/file.h"
-#include "android-base/stringprintf.h"
-#include "android-base/strings.h"
#include "client/file_sync_client.h"
#include "commandline.h"
#include "fastdeploy.h"
@@ -179,8 +181,8 @@
return 1;
}
- int localFd = adb_open(file, O_RDONLY);
- if (localFd < 0) {
+ unique_fd local_fd(adb_open(file, O_RDONLY | O_CLOEXEC));
+ if (local_fd < 0) {
fprintf(stderr, "adb: failed to open %s: %s\n", file, strerror(errno));
return 1;
}
@@ -201,19 +203,15 @@
cmd += " --apex";
}
- int remoteFd = adb_connect(cmd, &error);
- if (remoteFd < 0) {
+ unique_fd remote_fd(adb_connect(cmd, &error));
+ if (remote_fd < 0) {
fprintf(stderr, "adb: connect error for write: %s\n", error.c_str());
- adb_close(localFd);
return 1;
}
char buf[BUFSIZ];
- copy_to_file(localFd, remoteFd);
- read_status_line(remoteFd, buf, sizeof(buf));
-
- adb_close(localFd);
- adb_close(remoteFd);
+ copy_to_file(local_fd.get(), remote_fd.get());
+ read_status_line(remote_fd.get(), buf, sizeof(buf));
if (!strncmp("Success", buf, 7)) {
fputs(buf, stdout);
@@ -410,14 +408,15 @@
// Create install session
std::string error;
- int fd = adb_connect(cmd, &error);
- if (fd < 0) {
- fprintf(stderr, "adb: connect error for create: %s\n", error.c_str());
- return EXIT_FAILURE;
- }
char buf[BUFSIZ];
- read_status_line(fd, buf, sizeof(buf));
- adb_close(fd);
+ {
+ unique_fd fd(adb_connect(cmd, &error));
+ if (fd < 0) {
+ fprintf(stderr, "adb: connect error for create: %s\n", error.c_str());
+ return EXIT_FAILURE;
+ }
+ read_status_line(fd.get(), buf, sizeof(buf));
+ }
int session_id = -1;
if (!strncmp("Success", buf, 7)) {
@@ -450,27 +449,23 @@
install_cmd.c_str(), static_cast<uint64_t>(sb.st_size),
session_id, android::base::Basename(file).c_str());
- int localFd = adb_open(file, O_RDONLY);
- if (localFd < 0) {
+ unique_fd local_fd(adb_open(file, O_RDONLY | O_CLOEXEC));
+ if (local_fd < 0) {
fprintf(stderr, "adb: failed to open %s: %s\n", file, strerror(errno));
success = 0;
goto finalize_session;
}
std::string error;
- int remoteFd = adb_connect(cmd, &error);
- if (remoteFd < 0) {
+ unique_fd remote_fd(adb_connect(cmd, &error));
+ if (remote_fd < 0) {
fprintf(stderr, "adb: connect error for write: %s\n", error.c_str());
- adb_close(localFd);
success = 0;
goto finalize_session;
}
- copy_to_file(localFd, remoteFd);
- read_status_line(remoteFd, buf, sizeof(buf));
-
- adb_close(localFd);
- adb_close(remoteFd);
+ copy_to_file(local_fd.get(), remote_fd.get());
+ read_status_line(remote_fd.get(), buf, sizeof(buf));
if (strncmp("Success", buf, 7)) {
fprintf(stderr, "adb: failed to write %s\n", file);
@@ -484,13 +479,14 @@
// Commit session if we streamed everything okay; otherwise abandon
std::string service = android::base::StringPrintf("%s install-%s %d", install_cmd.c_str(),
success ? "commit" : "abandon", session_id);
- fd = adb_connect(service, &error);
- if (fd < 0) {
- fprintf(stderr, "adb: connect error for finalize: %s\n", error.c_str());
- return EXIT_FAILURE;
+ {
+ unique_fd fd(adb_connect(service, &error));
+ if (fd < 0) {
+ fprintf(stderr, "adb: connect error for finalize: %s\n", error.c_str());
+ return EXIT_FAILURE;
+ }
+ read_status_line(fd.get(), buf, sizeof(buf));
}
- read_status_line(fd, buf, sizeof(buf));
- adb_close(fd);
if (!strncmp("Success", buf, 7)) {
fputs(buf, stdout);
@@ -527,14 +523,15 @@
// Create multi-package install session
std::string error;
- int fd = adb_connect(multi_package_cmd, &error);
- if (fd < 0) {
- fprintf(stderr, "adb: connect error for create multi-package: %s\n", error.c_str());
- return EXIT_FAILURE;
- }
char buf[BUFSIZ];
- read_status_line(fd, buf, sizeof(buf));
- adb_close(fd);
+ {
+ unique_fd fd(adb_connect(multi_package_cmd, &error));
+ if (fd < 0) {
+ fprintf(stderr, "adb: connect error for create multi-package: %s\n", error.c_str());
+ return EXIT_FAILURE;
+ }
+ read_status_line(fd.get(), buf, sizeof(buf));
+ }
int parent_session_id = -1;
if (!strncmp("Success", buf, 7)) {
@@ -566,14 +563,15 @@
std::string cmd = "";
for (int i = first_apk; i < argc; i++) {
// Create individual install session
- fd = adb_connect(individual_cmd, &error);
- if (fd < 0) {
- fprintf(stderr, "adb: connect error for create: %s\n", error.c_str());
- goto finalize_multi_package_session;
- }
char buf[BUFSIZ];
- read_status_line(fd, buf, sizeof(buf));
- adb_close(fd);
+ {
+ unique_fd fd(adb_connect(individual_cmd, &error));
+ if (fd < 0) {
+ fprintf(stderr, "adb: connect error for create: %s\n", error.c_str());
+ goto finalize_multi_package_session;
+ }
+ read_status_line(fd.get(), buf, sizeof(buf));
+ }
int session_id = -1;
if (!strncmp("Success", buf, 7)) {
@@ -605,25 +603,21 @@
install_cmd.c_str(), static_cast<uint64_t>(sb.st_size),
session_id, i, android::base::Basename(file).c_str());
- int localFd = adb_open(file, O_RDONLY);
- if (localFd < 0) {
+ unique_fd local_fd(adb_open(file, O_RDONLY | O_CLOEXEC));
+ if (local_fd < 0) {
fprintf(stderr, "adb: failed to open %s: %s\n", file, strerror(errno));
goto finalize_multi_package_session;
}
std::string error;
- int remoteFd = adb_connect(cmd, &error);
- if (remoteFd < 0) {
+ unique_fd remote_fd(adb_connect(cmd, &error));
+ if (remote_fd < 0) {
fprintf(stderr, "adb: connect error for write: %s\n", error.c_str());
- adb_close(localFd);
goto finalize_multi_package_session;
}
- copy_to_file(localFd, remoteFd);
- read_status_line(remoteFd, buf, sizeof(buf));
-
- adb_close(localFd);
- adb_close(remoteFd);
+ copy_to_file(local_fd.get(), remote_fd.get());
+ read_status_line(remote_fd.get(), buf, sizeof(buf));
if (strncmp("Success", buf, 7)) {
fprintf(stderr, "adb: failed to write %s\n", file);
@@ -636,13 +630,14 @@
cmd = android::base::StringPrintf("%s install-add-session %d%s", install_cmd.c_str(),
parent_session_id, all_session_ids.c_str());
- fd = adb_connect(cmd, &error);
- if (fd < 0) {
- fprintf(stderr, "adb: connect error for create: %s\n", error.c_str());
- goto finalize_multi_package_session;
+ {
+ unique_fd fd(adb_connect(cmd, &error));
+ if (fd < 0) {
+ fprintf(stderr, "adb: connect error for create: %s\n", error.c_str());
+ goto finalize_multi_package_session;
+ }
+ read_status_line(fd.get(), buf, sizeof(buf));
}
- read_status_line(fd, buf, sizeof(buf));
- adb_close(fd);
if (strncmp("Success", buf, 7)) {
fprintf(stderr, "adb: failed to link sessions (%s)\n", cmd.c_str());
@@ -658,13 +653,14 @@
std::string service =
android::base::StringPrintf("%s install-%s %d", install_cmd.c_str(),
success == 0 ? "commit" : "abandon", parent_session_id);
- fd = adb_connect(service, &error);
- if (fd < 0) {
- fprintf(stderr, "adb: connect error for finalize: %s\n", error.c_str());
- return EXIT_FAILURE;
+ {
+ unique_fd fd(adb_connect(service, &error));
+ if (fd < 0) {
+ fprintf(stderr, "adb: connect error for finalize: %s\n", error.c_str());
+ return EXIT_FAILURE;
+ }
+ read_status_line(fd.get(), buf, sizeof(buf));
}
- read_status_line(fd, buf, sizeof(buf));
- adb_close(fd);
if (!strncmp("Success", buf, 7)) {
fputs(buf, stdout);
@@ -681,13 +677,12 @@
service = android::base::StringPrintf("%s install-abandon %d", install_cmd.c_str(),
session_ids[i]);
fprintf(stderr, "Attempting to abandon session ID %d\n", session_ids[i]);
- fd = adb_connect(service, &error);
+ unique_fd fd(adb_connect(service, &error));
if (fd < 0) {
fprintf(stderr, "adb: connect error for finalize: %s\n", error.c_str());
continue;
}
- read_status_line(fd, buf, sizeof(buf));
- adb_close(fd);
+ read_status_line(fd.get(), buf, sizeof(buf));
}
return EXIT_FAILURE;
}
diff --git a/libnativeloader/Android.bp b/libnativeloader/Android.bp
index 17983bc..8903b72 100644
--- a/libnativeloader/Android.bp
+++ b/libnativeloader/Android.bp
@@ -23,4 +23,20 @@
"llndk.libraries.txt",
"vndksp.libraries.txt",
],
+ target: {
+ android: {
+ version_script: "libnativeloader.map.txt",
+ },
+ },
+ stubs: {
+ symbol_file: "libnativeloader.map.txt",
+ versions: ["1"],
+ },
+}
+
+cc_library_headers {
+ name: "libnativeloader-dummy-headers",
+
+ host_supported: true,
+ export_include_dirs: ["include"],
}
diff --git a/libnativeloader/include/nativeloader/dlext_namespaces.h b/libnativeloader/include/nativeloader/dlext_namespaces.h
index 43c9329..ca026b3 100644
--- a/libnativeloader/include/nativeloader/dlext_namespaces.h
+++ b/libnativeloader/include/nativeloader/dlext_namespaces.h
@@ -18,6 +18,7 @@
#define __ANDROID_DLEXT_NAMESPACES_H__
#include <android/dlext.h>
+#include <stdbool.h>
__BEGIN_DECLS
@@ -84,12 +85,9 @@
* If a library or any of its dependencies are outside of the permitted_when_isolated_path
* and search_path, and it is not part of the public namespace dlopen will fail.
*/
-extern struct android_namespace_t* android_create_namespace(const char* name,
- const char* ld_library_path,
- const char* default_library_path,
- uint64_t type,
- const char* permitted_when_isolated_path,
- android_namespace_t* parent);
+extern struct android_namespace_t* android_create_namespace(
+ const char* name, const char* ld_library_path, const char* default_library_path, uint64_t type,
+ const char* permitted_when_isolated_path, struct android_namespace_t* parent);
/*
* Creates a link between namespaces. Every link has list of sonames of
@@ -107,8 +105,8 @@
* step will not go deeper into linked namespaces for this library but
* will do so for DT_NEEDED libraries.
*/
-extern bool android_link_namespaces(android_namespace_t* from,
- android_namespace_t* to,
+extern bool android_link_namespaces(struct android_namespace_t* from,
+ struct android_namespace_t* to,
const char* shared_libs_sonames);
/*
@@ -124,7 +122,7 @@
*/
extern void android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size);
-extern android_namespace_t* android_get_exported_namespace(const char* name);
+extern struct android_namespace_t* android_get_exported_namespace(const char* name);
__END_DECLS
diff --git a/libnativeloader/include/nativeloader/native_loader.h b/libnativeloader/include/nativeloader/native_loader.h
index c1d9d2a..af53dc5 100644
--- a/libnativeloader/include/nativeloader/native_loader.h
+++ b/libnativeloader/include/nativeloader/native_loader.h
@@ -17,14 +17,21 @@
#ifndef NATIVE_LOADER_H_
#define NATIVE_LOADER_H_
-#include "jni.h"
+#include <stdbool.h>
#include <stdint.h>
-#include <string>
+#include "jni.h"
#if defined(__ANDROID__)
#include <android/dlext.h>
#endif
+#ifdef __cplusplus
namespace android {
+extern "C" {
+#endif // __cplusplus
+
+// README: the char** error message parameter being passed
+// to the methods below need to be freed through calling NativeLoaderFreeErrorMessage.
+// It's the caller's responsibility to call that method.
__attribute__((visibility("default")))
void InitializeNativeLoader();
@@ -38,42 +45,39 @@
jstring library_path,
jstring permitted_path);
-__attribute__((visibility("default")))
-void* OpenNativeLibrary(JNIEnv* env,
- int32_t target_sdk_version,
- const char* path,
- jobject class_loader,
- jstring library_path,
- bool* needs_native_bridge,
- std::string* error_msg);
+__attribute__((visibility("default"))) void* OpenNativeLibrary(
+ JNIEnv* env, int32_t target_sdk_version, const char* path, jobject class_loader,
+ jstring library_path, bool* needs_native_bridge, char** error_msg);
__attribute__((visibility("default"))) bool CloseNativeLibrary(void* handle,
const bool needs_native_bridge,
- std::string* error_msg);
+ char** error_msg);
+
+__attribute__((visibility("default"))) void NativeLoaderFreeErrorMessage(char* msg);
#if defined(__ANDROID__)
// Look up linker namespace by class_loader. Returns nullptr if
// there is no namespace associated with the class_loader.
// TODO(b/79940628): move users to FindNativeLoaderNamespaceByClassLoader and remove this function.
-__attribute__((visibility("default")))
-android_namespace_t* FindNamespaceByClassLoader(JNIEnv* env, jobject class_loader);
-// That version works with native bridge namespaces, but requires use of OpenNativeLibrary.
-class NativeLoaderNamespace;
-__attribute__((visibility("default")))
-NativeLoaderNamespace* FindNativeLoaderNamespaceByClassLoader(
+__attribute__((visibility("default"))) struct android_namespace_t* FindNamespaceByClassLoader(
JNIEnv* env, jobject class_loader);
+// That version works with native bridge namespaces, but requires use of OpenNativeLibrary.
+struct NativeLoaderNamespace;
+__attribute__((visibility("default"))) struct NativeLoaderNamespace*
+FindNativeLoaderNamespaceByClassLoader(JNIEnv* env, jobject class_loader);
// Load library. Unlinke OpenNativeLibrary above couldn't create namespace on demand, but does
// not require access to JNIEnv either.
-__attribute__((visibility("default")))
-void* OpenNativeLibrary(NativeLoaderNamespace* ns,
- const char* path,
- bool* needs_native_bridge,
- std::string* error_msg);
+__attribute__((visibility("default"))) void* OpenNativeLibraryInNamespace(
+ struct NativeLoaderNamespace* ns, const char* path, bool* needs_native_bridge,
+ char** error_msg);
#endif
__attribute__((visibility("default")))
void ResetNativeLoader();
-}; // namespace android
+#ifdef __cplusplus
+} // extern "C"
+} // namespace android
+#endif // __cplusplus
#endif // NATIVE_BRIDGE_H_
diff --git a/libnativeloader/libnativeloader.map.txt b/libnativeloader/libnativeloader.map.txt
new file mode 100644
index 0000000..40c30bd
--- /dev/null
+++ b/libnativeloader/libnativeloader.map.txt
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# TODO(b/122710865): Prune these uses once the runtime APEX is complete.
+LIBNATIVELOADER_1 {
+ global:
+ OpenNativeLibrary;
+ InitializeNativeLoader;
+ ResetNativeLoader;
+ CloseNativeLibrary;
+ OpenNativeLibraryInNamespace;
+ FindNamespaceByClassLoader;
+ FindNativeLoaderNamespaceByClassLoader;
+ CreateClassLoaderNamespace;
+ NativeLoaderFreeErrorMessage;
+ local:
+ *;
+};
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index de7ea08..f231afa 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -52,7 +52,7 @@
namespace android {
#if defined(__ANDROID__)
-class NativeLoaderNamespace {
+struct NativeLoaderNamespace {
public:
NativeLoaderNamespace()
: android_ns_(nullptr), native_bridge_ns_(nullptr) { }
@@ -151,14 +151,9 @@
public:
LibraryNamespaces() : initialized_(false) { }
- NativeLoaderNamespace* Create(JNIEnv* env,
- uint32_t target_sdk_version,
- jobject class_loader,
- bool is_shared,
- bool is_for_vendor,
- jstring java_library_path,
- jstring java_permitted_path,
- std::string* error_msg) {
+ NativeLoaderNamespace* Create(JNIEnv* env, uint32_t target_sdk_version, jobject class_loader,
+ bool is_shared, bool is_for_vendor, jstring java_library_path,
+ jstring java_permitted_path, std::string* error_msg) {
std::string library_path; // empty string by default.
if (java_library_path != nullptr) {
@@ -628,13 +623,9 @@
return nullptr;
}
-void* OpenNativeLibrary(JNIEnv* env,
- int32_t target_sdk_version,
- const char* path,
- jobject class_loader,
- jstring library_path,
- bool* needs_native_bridge,
- std::string* error_msg) {
+void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path,
+ jobject class_loader, jstring library_path, bool* needs_native_bridge,
+ char** error_msg) {
#if defined(__ANDROID__)
UNUSED(target_sdk_version);
if (class_loader == nullptr) {
@@ -652,19 +643,16 @@
if ((ns = g_namespaces->FindNamespaceByClassLoader(env, class_loader)) == nullptr) {
// This is the case where the classloader was not created by ApplicationLoaders
// In this case we create an isolated not-shared namespace for it.
- if ((ns = g_namespaces->Create(env,
- target_sdk_version,
- class_loader,
- false /* is_shared */,
- false /* is_for_vendor */,
- library_path,
- nullptr,
- error_msg)) == nullptr) {
+ std::string create_error_msg;
+ if ((ns = g_namespaces->Create(env, target_sdk_version, class_loader, false /* is_shared */,
+ false /* is_for_vendor */, library_path, nullptr,
+ &create_error_msg)) == nullptr) {
+ *error_msg = strdup(create_error_msg.c_str());
return nullptr;
}
}
- return OpenNativeLibrary(ns, path, needs_native_bridge, error_msg);
+ return OpenNativeLibraryInNamespace(ns, path, needs_native_bridge, error_msg);
#else
UNUSED(env, target_sdk_version, class_loader);
@@ -705,35 +693,40 @@
if (handle != nullptr) {
return handle;
}
- *error_msg = NativeBridgeGetError();
+ *error_msg = strdup(NativeBridgeGetError());
} else {
- *error_msg = dlerror();
+ *error_msg = strdup(dlerror());
}
}
return nullptr;
#endif
}
-bool CloseNativeLibrary(void* handle, const bool needs_native_bridge, std::string* error_msg) {
+bool CloseNativeLibrary(void* handle, const bool needs_native_bridge, char** error_msg) {
bool success;
if (needs_native_bridge) {
success = (NativeBridgeUnloadLibrary(handle) == 0);
if (!success) {
- *error_msg = NativeBridgeGetError();
+ *error_msg = strdup(NativeBridgeGetError());
}
} else {
success = (dlclose(handle) == 0);
if (!success) {
- *error_msg = dlerror();
+ *error_msg = strdup(dlerror());
}
}
return success;
}
+void NativeLoaderFreeErrorMessage(char* msg) {
+ // The error messages get allocated through strdup, so we must call free on them.
+ free(msg);
+}
+
#if defined(__ANDROID__)
-void* OpenNativeLibrary(NativeLoaderNamespace* ns, const char* path, bool* needs_native_bridge,
- std::string* error_msg) {
+void* OpenNativeLibraryInNamespace(NativeLoaderNamespace* ns, const char* path,
+ bool* needs_native_bridge, char** error_msg) {
if (ns->is_android_namespace()) {
android_dlextinfo extinfo;
extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
@@ -741,14 +734,14 @@
void* handle = android_dlopen_ext(path, RTLD_NOW, &extinfo);
if (handle == nullptr) {
- *error_msg = dlerror();
+ *error_msg = strdup(dlerror());
}
*needs_native_bridge = false;
return handle;
} else {
void* handle = NativeBridgeLoadLibraryExt(path, RTLD_NOW, ns->get_native_bridge_ns());
if (handle == nullptr) {
- *error_msg = NativeBridgeGetError();
+ *error_msg = strdup(NativeBridgeGetError());
}
*needs_native_bridge = true;
return handle;
diff --git a/libnativeloader/test/Android.bp b/libnativeloader/test/Android.bp
index d528f30..1464e39 100644
--- a/libnativeloader/test/Android.bp
+++ b/libnativeloader/test/Android.bp
@@ -69,3 +69,14 @@
"libbase",
],
}
+
+// Build the test for the C API.
+cc_test {
+ name: "libnativeloader-api-tests",
+ host_supported: true,
+ test_per_src: true,
+ srcs: [
+ "api_test.c",
+ ],
+ header_libs: ["libnativeloader-dummy-headers"],
+}
diff --git a/libnativeloader/test/api_test.c b/libnativeloader/test/api_test.c
new file mode 100644
index 0000000..e7025fd
--- /dev/null
+++ b/libnativeloader/test/api_test.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* The main purpose of this test is to ensure this C header compiles in C, so
+ * that no C++ features inadvertently leak into the C ABI. */
+#include "nativeloader/native_loader.h"
+
+int main(int argc, char** argv) {
+ (void)argc;
+ (void)argv;
+ return 0;
+}
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 7794f81..ca78c38 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -16,6 +16,7 @@
#define LOG_TAG "lowmemorykiller"
+#include <dirent.h>
#include <errno.h>
#include <inttypes.h>
#include <pwd.h>
@@ -28,18 +29,22 @@
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/mman.h>
+#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/sysinfo.h>
+#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <cutils/properties.h>
+#include <cutils/sched_policy.h>
#include <cutils/sockets.h>
#include <lmkd.h>
#include <log/log.h>
#include <log/log_event_list.h>
#include <log/log_time.h>
+#include <system/thread_defs.h>
#ifdef LMKD_LOG_STATS
#include "statslog.h"
@@ -1261,6 +1266,41 @@
return maxprocp;
}
+static void set_process_group_and_prio(int pid, SchedPolicy sp, int prio) {
+ DIR* d;
+ char proc_path[PATH_MAX];
+ struct dirent* de;
+
+ snprintf(proc_path, sizeof(proc_path), "/proc/%d/task", pid);
+ if (!(d = opendir(proc_path))) {
+ ALOGW("Failed to open %s; errno=%d: process pid(%d) might have died", proc_path, errno,
+ pid);
+ return;
+ }
+
+ while ((de = readdir(d))) {
+ int t_pid;
+
+ if (de->d_name[0] == '.') continue;
+ t_pid = atoi(de->d_name);
+
+ if (!t_pid) {
+ ALOGW("Failed to get t_pid for '%s' of pid(%d)", de->d_name, pid);
+ continue;
+ }
+
+ if (setpriority(PRIO_PROCESS, t_pid, prio) && errno != ESRCH) {
+ ALOGW("Unable to raise priority of killing t_pid (%d): errno=%d", t_pid, errno);
+ }
+
+ if (set_cpuset_policy(t_pid, sp)) {
+ ALOGW("Failed to set_cpuset_policy on pid(%d) t_pid(%d) to %d", pid, t_pid, (int)sp);
+ continue;
+ }
+ }
+ closedir(d);
+}
+
static int last_killed_pid = -1;
/* Kill one process specified by procp. Returns the size of the process killed */
@@ -1301,6 +1341,9 @@
/* CAP_KILL required */
r = kill(pid, SIGKILL);
+
+ set_process_group_and_prio(pid, SP_FOREGROUND, ANDROID_PRIORITY_HIGHEST);
+
inc_killcnt(procp->oomadj);
ALOGI("Kill '%s' (%d), uid %d, oom_adj %d to free %ldkB",
taskname, pid, uid, procp->oomadj, tasksize * page_k);