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

Commit 1614fd8d authored by Elliott Hughes's avatar Elliott Hughes
Browse files

Switch libprocessgroup to libbase logging.

This lets us see what's going on in init.

Bug: http://b/29751426
Change-Id: I73432dc7608ca0dc8e421a2f3a750b37c6743f62
parent fa027005
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -3,7 +3,7 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := processgroup.cpp
LOCAL_SRC_FILES := processgroup.cpp
LOCAL_MODULE := libprocessgroup
LOCAL_MODULE := libprocessgroup
LOCAL_STATIC_LIBRARIES := liblog
LOCAL_STATIC_LIBRARIES := libbase
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
LOCAL_CFLAGS := -Wall -Werror
LOCAL_CFLAGS := -Wall -Werror
@@ -12,7 +12,7 @@ include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := processgroup.cpp
LOCAL_SRC_FILES := processgroup.cpp
LOCAL_MODULE := libprocessgroup
LOCAL_MODULE := libprocessgroup
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_SHARED_LIBRARIES := libbase
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
LOCAL_CFLAGS := -Wall -Werror
LOCAL_CFLAGS := -Wall -Werror
+42 −56
Original line number Original line Diff line number Diff line
@@ -32,7 +32,7 @@
#include <memory>
#include <memory>
#include <mutex>
#include <mutex>


#include <log/log.h>
#include <android-base/logging.h>
#include <private/android_filesystem_config.h>
#include <private/android_filesystem_config.h>


#include <processgroup/processgroup.h>
#include <processgroup/processgroup.h>
@@ -112,7 +112,7 @@ static int initCtx(uid_t uid, int pid, struct ctx *ctx)
    int fd = open(path, O_RDONLY);
    int fd = open(path, O_RDONLY);
    if (fd < 0) {
    if (fd < 0) {
        ret = -errno;
        ret = -errno;
        SLOGW("failed to open %s: %s", path, strerror(errno));
        PLOG(WARNING) << "failed to open " << path;
        return ret;
        return ret;
    }
    }


@@ -121,7 +121,7 @@ static int initCtx(uid_t uid, int pid, struct ctx *ctx)
    ctx->buf_len = 0;
    ctx->buf_len = 0;
    ctx->initialized = true;
    ctx->initialized = true;


    SLOGV("Initialized context for %s", path);
    LOG(VERBOSE) << "Initialized context for " << path;


    return 0;
    return 0;
}
}
@@ -141,7 +141,7 @@ static int refillBuffer(struct ctx *ctx)


    ctx->buf_len += ret;
    ctx->buf_len += ret;
    ctx->buf[ctx->buf_len] = 0;
    ctx->buf[ctx->buf_len] = 0;
    SLOGV("Read %zd to buffer: %s", ret, ctx->buf);
    LOG(VERBOSE) << "Read " << ret << " to buffer: " << ctx->buf;


    assert(ctx->buf_len <= sizeof(ctx->buf));
    assert(ctx->buf_len <= sizeof(ctx->buf));


@@ -217,19 +217,19 @@ static void removeUidProcessGroups(const char *uid_path)
            }
            }


            snprintf(path, sizeof(path), "%s/%s", uid_path, dir->d_name);
            snprintf(path, sizeof(path), "%s/%s", uid_path, dir->d_name);
            SLOGV("removing %s\n", path);
            LOG(VERBOSE) << "removing " << path;
            rmdir(path);
            if (rmdir(path) == -1) PLOG(WARNING) << "failed to remove " << path;
        }
        }
    }
    }
}
}


void removeAllProcessGroups()
void removeAllProcessGroups()
{
{
    SLOGV("removeAllProcessGroups()");
    LOG(VERBOSE) << "removeAllProcessGroups()";
    const char* cgroup_root_path = getCgroupRootPath();
    const char* cgroup_root_path = getCgroupRootPath();
    std::unique_ptr<DIR, decltype(&closedir)> root(opendir(cgroup_root_path), closedir);
    std::unique_ptr<DIR, decltype(&closedir)> root(opendir(cgroup_root_path), closedir);
    if (root == NULL) {
    if (root == NULL) {
        SLOGE("failed to open %s: %s", cgroup_root_path, strerror(errno));
        PLOG(ERROR) << "failed to open " << cgroup_root_path;
    } else {
    } else {
        struct dirent cur;
        struct dirent cur;
        struct dirent *dir;
        struct dirent *dir;
@@ -245,8 +245,8 @@ void removeAllProcessGroups()


            snprintf(path, sizeof(path), "%s/%s", cgroup_root_path, dir->d_name);
            snprintf(path, sizeof(path), "%s/%s", cgroup_root_path, dir->d_name);
            removeUidProcessGroups(path);
            removeUidProcessGroups(path);
            SLOGV("removing %s\n", path);
            LOG(VERBOSE) << "removing " << path;
            rmdir(path);
            if (rmdir(path) == -1) PLOG(WARNING) << "failed to remove " << path;
        }
        }
    }
    }
}
}
@@ -264,19 +264,13 @@ static int killProcessGroupOnce(uid_t uid, int initialPid, int signal)
        if (pid == 0) {
        if (pid == 0) {
            // Should never happen...  but if it does, trying to kill this
            // Should never happen...  but if it does, trying to kill this
            // will boomerang right back and kill us!  Let's not let that happen.
            // will boomerang right back and kill us!  Let's not let that happen.
            SLOGW("Yikes, we've been told to kill pid 0!  How about we don't do that.");
            LOG(WARNING) << "Yikes, we've been told to kill pid 0!  How about we don't do that?";
            continue;
            continue;
        }
        }
        if (pid != initialPid) {
        LOG(VERBOSE) << "Killing pid " << pid << " in uid " << uid
            // We want to be noisy about killing processes so we can understand
                     << " as part of process group " << initialPid;
            // what is going on in the log; however, don't be noisy about the base
        if (kill(pid, signal) == -1) {
            // process, since that it something we always kill, and we have already
            PLOG(WARNING) << "kill(" << pid << ", " << signal << ") failed";
            // logged elsewhere about killing it.
            SLOGI("Killing pid %d in uid %d as part of process group %d", pid, uid, initialPid);
        }
        int ret = kill(pid, signal);
        if (ret == -1) {
            SLOGW("failed to kill pid %d: %s", pid, strerror(errno));
        }
        }
    }
    }


@@ -294,21 +288,22 @@ int killProcessGroup(uid_t uid, int initialPid, int signal)
    int retry = 40;
    int retry = 40;
    int processes;
    int processes;
    while ((processes = killProcessGroupOnce(uid, initialPid, signal)) > 0) {
    while ((processes = killProcessGroupOnce(uid, initialPid, signal)) > 0) {
        SLOGV("killed %d processes for processgroup %d\n", processes, initialPid);
        LOG(VERBOSE) << "killed " << processes << " processes for processgroup " << initialPid;
        if (retry > 0) {
        if (retry > 0) {
            usleep(5 * 1000); // 5ms
            usleep(5 * 1000); // 5ms
            --retry;
            --retry;
        } else {
        } else {
            SLOGE("failed to kill %d processes for processgroup %d\n", processes, initialPid);
            LOG(ERROR) << "failed to kill " << processes << " processes for processgroup "
                       << initialPid;
            break;
            break;
        }
        }
    }
    }


    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
    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,
    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
          static_cast<int>(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()),
    LOG(VERBOSE) << "Killed process group uid " << uid << " pid " << initialPid << " in "
          processes);
                 << static_cast<int>(ms) << "ms, " << processes << " procs remain";


    if (processes == 0) {
    if (processes == 0) {
        return removeProcessGroup(uid, initialPid);
        return removeProcessGroup(uid, initialPid);
@@ -317,67 +312,58 @@ int killProcessGroup(uid_t uid, int initialPid, int signal)
    }
    }
}
}


static int mkdirAndChown(const char *path, mode_t mode, uid_t uid, gid_t gid)
static bool mkdirAndChown(const char *path, mode_t mode, uid_t uid, gid_t gid)
{
{
    int ret;
    if (mkdir(path, mode) == -1 && errno != EEXIST) {

        return false;
    ret = mkdir(path, mode);
    if (ret < 0 && errno != EEXIST) {
        return -errno;
    }
    }


    ret = chown(path, uid, gid);
    if (chown(path, uid, gid) == -1) {
    if (ret < 0) {
        int saved_errno = errno;
        ret = -errno;
        rmdir(path);
        rmdir(path);
        return ret;
        errno = saved_errno;
        return false;
    }
    }


    return 0;
    return true;
}
}


int createProcessGroup(uid_t uid, int initialPid)
int createProcessGroup(uid_t uid, int initialPid)
{
{
    char path[PROCESSGROUP_MAX_PATH_LEN] = {0};
    char path[PROCESSGROUP_MAX_PATH_LEN] = {0};
    int ret;


    convertUidToPath(path, sizeof(path), uid);
    convertUidToPath(path, sizeof(path), uid);


    ret = mkdirAndChown(path, 0750, AID_SYSTEM, AID_SYSTEM);
    if (!mkdirAndChown(path, 0750, AID_SYSTEM, AID_SYSTEM)) {
    if (ret < 0) {
        PLOG(ERROR) << "failed to make and chown " << path;
        SLOGE("failed to make and chown %s: %s", path, strerror(-ret));
        return -errno;
        return ret;
    }
    }


    convertUidPidToPath(path, sizeof(path), uid, initialPid);
    convertUidPidToPath(path, sizeof(path), uid, initialPid);


    ret = mkdirAndChown(path, 0750, AID_SYSTEM, AID_SYSTEM);
    if (!mkdirAndChown(path, 0750, AID_SYSTEM, AID_SYSTEM)) {
    if (ret < 0) {
        PLOG(ERROR) << "failed to make and chown " << path;
        SLOGE("failed to make and chown %s: %s", path, strerror(-ret));
        return -errno;
        return ret;
    }
    }


    strlcat(path, PROCESSGROUP_CGROUP_PROCS_FILE, sizeof(path));
    strlcat(path, PROCESSGROUP_CGROUP_PROCS_FILE, sizeof(path));


    int fd = open(path, O_WRONLY);
    int fd = open(path, O_WRONLY);
    if (fd < 0) {
    if (fd == -1) {
        ret = -errno;
        int ret = -errno;
        SLOGE("failed to open %s: %s", path, strerror(errno));
        PLOG(ERROR) << "failed to open " << path;
        return ret;
        return ret;
    }
    }


    char pid[PROCESSGROUP_MAX_PID_LEN + 1] = {0};
    char pid[PROCESSGROUP_MAX_PID_LEN + 1] = {0};
    int len = snprintf(pid, sizeof(pid), "%d", initialPid);
    int len = snprintf(pid, sizeof(pid), "%d", initialPid);


    ret = write(fd, pid, len);
    int ret = 0;
    if (ret < 0) {
    if (write(fd, pid, len) < 0) {
        ret = -errno;
        ret = -errno;
        SLOGE("failed to write '%s' to %s: %s", pid, path, strerror(errno));
        PLOG(ERROR) << "failed to write '" << pid << "' to " << path;
    } else {
        ret = 0;
    }
    }


    close(fd);
    close(fd);
    return ret;
    return ret;
}
}