Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f7e79b99 authored by Collin Mulliner's avatar Collin Mulliner Committed by Elliott Hughes
Browse files

use process groups for processes started by init



Put every service into a process group, kill the process group
and all child processes created within the group when killing the
service. Removed libutil dependency in libprocessgroup.

Bug: 25355957
Change-Id: Ieed60ec41579f638ab9b1e66a7e6330ed578ab05
Signed-off-by: default avatarCollin Mulliner <collinrm@squareup.com>
parent 605628d3
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ LOCAL_SRC_FILES:= \
    service.cpp \
    util.cpp \

LOCAL_STATIC_LIBRARIES := libbase libselinux
LOCAL_STATIC_LIBRARIES := libbase libselinux liblog libprocessgroup
LOCAL_MODULE := libinit
LOCAL_SANITIZE := integer
LOCAL_CLANG := true
@@ -91,7 +91,6 @@ LOCAL_STATIC_LIBRARIES := \
    libcutils \
    libbase \
    libext4_utils_static \
    libutils \
    libc \
    libselinux \
    liblog \
@@ -100,7 +99,8 @@ LOCAL_STATIC_LIBRARIES := \
    libc++_static \
    libdl \
    libsparse_static \
    libz
    libz \
    libprocessgroup

# Create symlinks
LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \
+6 −3
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@
#include <cutils/android_reboot.h>
#include <cutils/sockets.h>

#include <processgroup/processgroup.h>

#include "action.h"
#include "init.h"
#include "init_parser.h"
@@ -97,7 +99,7 @@ bool Service::Reap() {
    if (!(flags_ & SVC_ONESHOT) || (flags_ & SVC_RESTART)) {
        NOTICE("Service '%s' (pid %d) killing any children in process group\n",
               name_.c_str(), pid_);
        kill(-pid_, SIGKILL);
        killProcessGroup(uid_, pid_, SIGKILL);
    }

    // Remove any sockets we may have created.
@@ -490,6 +492,7 @@ bool Service::Start() {
    time_started_ = gettime();
    pid_ = pid;
    flags_ |= SVC_RUNNING;
    createProcessGroup(uid_, pid_);

    if ((flags_ & SVC_EXEC) != 0) {
        INFO("SVC_EXEC pid %d (uid %d gid %d+%zu context %s) started; waiting...\n",
@@ -532,7 +535,7 @@ void Service::Terminate() {
    if (pid_) {
        NOTICE("Sending SIGTERM to service '%s' (pid %d)...\n", name_.c_str(),
               pid_);
        kill(-pid_, SIGTERM);
        killProcessGroup(uid_, pid_, SIGTERM);
        NotifyStateChange("stopping");
    }
}
@@ -583,7 +586,7 @@ void Service::StopOrReset(int how) {

    if (pid_) {
        NOTICE("Service '%s' is being killed...\n", name_.c_str());
        kill(-pid_, SIGKILL);
        killProcessGroup(uid_, pid_, SIGKILL);
        NotifyStateChange("stopping");
    } else {
        NotifyStateChange("stopped");
+10 −1
Original line number Diff line number Diff line
@@ -3,7 +3,16 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := processgroup.cpp
LOCAL_MODULE := libprocessgroup
LOCAL_SHARED_LIBRARIES := liblog libutils
LOCAL_STATIC_LIBRARIES := liblog
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
LOCAL_CFLAGS := -Wall -Werror
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_SRC_FILES := processgroup.cpp
LOCAL_MODULE := libprocessgroup
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
LOCAL_CFLAGS := -Wall -Werror
+12 −12
Original line number Diff line number Diff line
@@ -22,19 +22,18 @@
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <chrono>
#include <memory>

#include <log/log.h>
#include <private/android_filesystem_config.h>

#include <utils/SystemClock.h>

#include <processgroup/processgroup.h>
#include "processgroup_priv.h"

@@ -250,25 +249,26 @@ static int killProcessGroupOnce(uid_t uid, int initialPid, int signal)

int killProcessGroup(uid_t uid, int initialPid, int signal)
{
    int processes;
    const int sleep_us = 5 * 1000;  // 5ms
    int64_t startTime = android::uptimeMillis();
    int retry = 40;
    std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();

    int retry = 40;
    int processes;
    while ((processes = killProcessGroupOnce(uid, initialPid, signal)) > 0) {
        SLOGV("killed %d processes for processgroup %d\n", processes, initialPid);
        if (retry > 0) {
            usleep(sleep_us);
            usleep(5 * 1000); // 5ms
            --retry;
        } else {
            SLOGE("failed to kill %d processes for processgroup %d\n",
                    processes, initialPid);
            SLOGE("failed to kill %d processes for processgroup %d\n", processes, initialPid);
            break;
        }
    }

    SLOGV("Killed process group uid %d pid %d in %" PRId64 "ms, %d procs remain", uid, initialPid,
            android::uptimeMillis()-startTime, processes);
    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();

    SLOGV("Killed process group uid %d pid %d in %dms, %d procs remain", uid, initialPid,
          static_cast<int>(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()),
          processes);

    if (processes == 0) {
        return removeProcessGroup(uid, initialPid);