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

Commit ebd6a646 authored by Tom Marshall's avatar Tom Marshall Committed by android-build-merger
Browse files

Merge "init: Run restorecon_recursive asynchronously" am: ad4aa9e1

am: 0329b8d0

Change-Id: I1cd56fc9521451742b04d7f56bc0b657a0672314
parents 2bb1e712 0329b8d0
Loading
Loading
Loading
Loading
+81 −7
Original line number Original line Diff line number Diff line
@@ -39,6 +39,7 @@
#include <sys/_system_properties.h>
#include <sys/_system_properties.h>


#include <memory>
#include <memory>
#include <queue>
#include <vector>
#include <vector>


#include <android-base/file.h>
#include <android-base/file.h>
@@ -162,7 +163,7 @@ bool is_legal_property_name(const std::string& name) {
    return true;
    return true;
}
}


uint32_t property_set(const std::string& name, const std::string& value) {
static uint32_t PropertySetImpl(const std::string& name, const std::string& value) {
    size_t valuelen = value.size();
    size_t valuelen = value.size();


    if (!is_legal_property_name(name)) {
    if (!is_legal_property_name(name)) {
@@ -176,12 +177,6 @@ uint32_t property_set(const std::string& name, const std::string& value) {
        return PROP_ERROR_INVALID_VALUE;
        return PROP_ERROR_INVALID_VALUE;
    }
    }


    if (name == "selinux.restorecon_recursive" && valuelen > 0) {
        if (selinux_android_restorecon(value.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE) != 0) {
            LOG(ERROR) << "Failed to restorecon_recursive " << value;
        }
    }

    prop_info* pi = (prop_info*) __system_property_find(name.c_str());
    prop_info* pi = (prop_info*) __system_property_find(name.c_str());
    if (pi != nullptr) {
    if (pi != nullptr) {
        // ro.* properties are actually "write-once".
        // ro.* properties are actually "write-once".
@@ -210,6 +205,85 @@ uint32_t property_set(const std::string& name, const std::string& value) {
    return PROP_SUCCESS;
    return PROP_SUCCESS;
}
}


typedef int (*PropertyAsyncFunc)(const std::string&, const std::string&);

struct PropertyChildInfo {
    pid_t pid;
    PropertyAsyncFunc func;
    std::string name;
    std::string value;
};

static std::queue<PropertyChildInfo> property_children;

static void PropertyChildLaunch() {
    auto& info = property_children.front();
    pid_t pid = fork();
    if (pid < 0) {
        LOG(ERROR) << "Failed to fork for property_set_async";
        while (!property_children.empty()) {
            property_children.pop();
        }
        return;
    }
    if (pid != 0) {
        info.pid = pid;
    } else {
        if (info.func(info.name, info.value) != 0) {
            LOG(ERROR) << "property_set_async(\"" << info.name << "\", \"" << info.value
                       << "\") failed";
        }
        exit(0);
    }
}

bool PropertyChildReap(pid_t pid) {
    if (property_children.empty()) {
        return false;
    }
    auto& info = property_children.front();
    if (info.pid != pid) {
        return false;
    }
    if (PropertySetImpl(info.name, info.value) != PROP_SUCCESS) {
        LOG(ERROR) << "Failed to set async property " << info.name;
    }
    property_children.pop();
    if (!property_children.empty()) {
        PropertyChildLaunch();
    }
    return true;
}

static uint32_t PropertySetAsync(const std::string& name, const std::string& value,
                                 PropertyAsyncFunc func) {
    if (value.empty()) {
        return PropertySetImpl(name, value);
    }

    PropertyChildInfo info;
    info.func = func;
    info.name = name;
    info.value = value;
    property_children.push(info);
    if (property_children.size() == 1) {
        PropertyChildLaunch();
    }
    return PROP_SUCCESS;
}

static int RestoreconRecursiveAsync(const std::string& name, const std::string& value) {
    return selinux_android_restorecon(value.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE);
}

uint32_t property_set(const std::string& name, const std::string& value) {
    if (name == "selinux.restorecon_recursive") {
        return PropertySetAsync(name, value, RestoreconRecursiveAsync);
    }

    return PropertySetImpl(name, value);
}

class SocketConnection {
class SocketConnection {
 public:
 public:
  SocketConnection(int socket, const struct ucred& cred)
  SocketConnection(int socket, const struct ucred& cred)
+2 −0
Original line number Original line Diff line number Diff line
@@ -26,6 +26,8 @@ struct property_audit_data {
    const char* name;
    const char* name;
};
};


extern bool PropertyChildReap(pid_t pid);

void property_init(void);
void property_init(void);
void property_load_boot_defaults(void);
void property_load_boot_defaults(void);
void load_persist_props(void);
void load_persist_props(void);
+2 −0
Original line number Original line Diff line number Diff line
@@ -1085,6 +1085,8 @@ bool ServiceManager::ReapOneProcess() {
    } else if (pid == -1) {
    } else if (pid == -1) {
        PLOG(ERROR) << "waitpid failed";
        PLOG(ERROR) << "waitpid failed";
        return false;
        return false;
    } else if (PropertyChildReap(pid)) {
        return true;
    }
    }


    Service* svc = FindServiceByPid(pid);
    Service* svc = FindServiceByPid(pid);