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

Commit c39a5082 authored by Tom Cherry's avatar Tom Cherry Committed by android-build-merger
Browse files

Merge "init: support setting rlimits per service"

am: 459aa1ca

Change-Id: I4ef5abc3371ce52783bfb14669bcffe33febb73e
parents 849b4817 459aa1ca
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ cc_library_static {
        "security.cpp",
        "selinux.cpp",
        "service.cpp",
        "rlimit_parser.cpp",
        "tokenizer.cpp",
        "uevent_listener.cpp",
        "ueventd_parser.cpp",
@@ -163,6 +164,7 @@ cc_test {
        "init_test.cpp",
        "property_service_test.cpp",
        "result_test.cpp",
        "rlimit_parser_test.cpp",
        "service_test.cpp",
        "ueventd_test.cpp",
        "util_test.cpp",
+11 −1
Original line number Diff line number Diff line
@@ -216,6 +216,12 @@ runs the service.
  http://man7.org/linux/man-pages/man7/capabilities.7.html for a list of Linux
  capabilities.

`setrlimit <resource> <cur> <max>`
> This applies the given rlimit to the service. rlimits are inherited by child
  processes, so this effectively applies the given rlimit to the process tree
  started by this service.
  It is parsed similarly to the setrlimit command specified below.

`seclabel <seclabel>`
> Change to 'seclabel' before exec'ing this service.
  Primarily for use by services run from the rootfs, e.g. ueventd, adbd.
@@ -455,7 +461,11 @@ Commands
  within _value_.

`setrlimit <resource> <cur> <max>`
> Set the rlimit for a resource.
> Set the rlimit for a resource. This applies to all processes launched after
  the limit is set. It is intended to be set early in init and applied globally.
  _resource_ is best specified using its text representation ('cpu', 'rtio', etc
  or 'RLIM_CPU', 'RLIM_RTIO', etc). It also may be specified as the int value
  that the resource enum corresponds to.

`start <service>`
> Start a service running if it is not already running.
+4 −13
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@
#include "parser.h"
#include "property_service.h"
#include "reboot.h"
#include "rlimit_parser.h"
#include "service.h"
#include "signal_handler.h"
#include "util.h"
@@ -582,20 +583,10 @@ static Result<Success> do_setprop(const std::vector<std::string>& args) {
}

static Result<Success> do_setrlimit(const std::vector<std::string>& args) {
    int resource;
    if (!android::base::ParseInt(args[1], &resource)) {
        return Error() << "unable to parse resource, " << args[1];
    }

    struct rlimit limit;
    if (!android::base::ParseUint(args[2], &limit.rlim_cur)) {
        return Error() << "unable to parse rlim_cur, " << args[2];
    }
    if (!android::base::ParseUint(args[3], &limit.rlim_max)) {
        return Error() << "unable to parse rlim_max, " << args[3];
    }
    auto rlimit = ParseRlimit(args);
    if (!rlimit) return rlimit.error();

    if (setrlimit(resource, &limit) == -1) {
    if (setrlimit(rlimit->first, &rlimit->second) == -1) {
        return ErrnoError() << "setrlimit failed";
    }
    return Success();

init/rlimit_parser.cpp

0 → 100644
+78 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.
 */

#include "rlimit_parser.h"

#include <android-base/parseint.h>
#include <android-base/strings.h>

using android::base::EqualsIgnoreCase;
using android::base::ParseInt;
using android::base::ParseUint;
using android::base::StartsWith;

namespace android {
namespace init {

// Builtins and service definitions both have their arguments start at 1 and finish at 3.
Result<std::pair<int, rlimit>> ParseRlimit(const std::vector<std::string>& args) {
    static const std::vector<std::pair<const char*, int>> text_to_resources = {
        {"cpu", 0},       {"fsize", 1}, {"data", 2},    {"stack", 3},
        {"core", 4},      {"rss", 5},   {"nproc", 6},   {"nofile", 7},
        {"memlock", 8},   {"as", 9},    {"locks", 10},  {"sigpending", 11},
        {"msgqueue", 12}, {"nice", 13}, {"rtprio", 14}, {"rttime", 15},
    };

    int resource;

    if (ParseInt(args[1], &resource)) {
        if (resource >= RLIM_NLIMITS) {
            return Error() << "Resource '" << args[1] << "' over the maximum resource value '"
                           << RLIM_NLIMITS << "'";
        } else if (resource < 0) {
            return Error() << "Resource '" << args[1] << "' below the minimum resource value '0'";
        }
    } else {
        std::string resource_string;
        if (StartsWith(args[1], "RLIM_")) {
            resource_string = args[1].substr(5);
        } else {
            resource_string = args[1];
        }

        auto it = std::find_if(text_to_resources.begin(), text_to_resources.end(),
                               [&resource_string](const auto& entry) {
                                   return EqualsIgnoreCase(resource_string, entry.first);
                               });
        if (it == text_to_resources.end()) {
            return Error() << "Could not parse resource '" << args[1] << "'";
        }

        resource = it->second;
    }

    rlimit limit;
    if (!ParseUint(args[2], &limit.rlim_cur)) {
        return Error() << "Could not parse soft limit '" << args[2] << "'";
    }
    if (!ParseUint(args[3], &limit.rlim_max)) {
        return Error() << "Could not parse hard limit '" << args[3] << "'";
    }
    return {resource, limit};
}

}  // namespace init
}  // namespace android

init/rlimit_parser.h

0 → 100644
+35 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.
 */

#ifndef _INIT_RLIMIT_PARSER_H
#define _INIT_RLIMIT_PARSER_H

#include <sys/resource.h>

#include <string>
#include <vector>

#include "result.h"

namespace android {
namespace init {

Result<std::pair<int, rlimit>> ParseRlimit(const std::vector<std::string>& args);

}  // namespace init
}  // namespace android

#endif
Loading