system/core
修訂 | 098323ba5bf4f5e585337369146fd52f032baeec (tree) |
---|---|
時間 | 2019-04-03 14:31:57 |
作者 | Yifan Hong <elsk@goog...> |
Commiter | Yifan Hong |
libprocessgroup: Add libcgrouprc
This module is an LL-NDK library that can be loaded by
modules that link to libprocessgroup (which is in VNDK).
This module defines APIs that reads cgroups.rc file
programatically. Internally, it uses libcgrouprc_format to
do so.
Test: builds
Bug: 123664216
Change-Id: I9c13c0528461758154e23cbab3a94ade7fb351ee
Merged-In: I9c13c0528461758154e23cbab3a94ade7fb351ee
@@ -0,0 +1,52 @@ | ||
1 | +// Copyright (C) 2019 The Android Open Source Project | |
2 | +// | |
3 | +// Licensed under the Apache License, Version 2.0 (the "License"); | |
4 | +// you may not use this file except in compliance with the License. | |
5 | +// You may obtain a copy of the License at | |
6 | +// | |
7 | +// http://www.apache.org/licenses/LICENSE-2.0 | |
8 | +// | |
9 | +// Unless required by applicable law or agreed to in writing, software | |
10 | +// distributed under the License is distributed on an "AS IS" BASIS, | |
11 | +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 | +// See the License for the specific language governing permissions and | |
13 | +// limitations under the License. | |
14 | + | |
15 | +cc_library_shared { | |
16 | + name: "libcgrouprc", | |
17 | + host_supported: true, | |
18 | + recovery_available: true, | |
19 | + srcs: [ | |
20 | + "cgroup_controller.cpp", | |
21 | + "cgroup_file.cpp", | |
22 | + ], | |
23 | + cflags: [ | |
24 | + "-Wall", | |
25 | + "-Werror", | |
26 | + ], | |
27 | + export_include_dirs: [ | |
28 | + "include", | |
29 | + ], | |
30 | + header_libs: [ | |
31 | + "libprocessgroup_headers", | |
32 | + ], | |
33 | + shared_libs: [ | |
34 | + "libbase", | |
35 | + ], | |
36 | + static_libs: [ | |
37 | + "libcgrouprc_format", | |
38 | + ], | |
39 | + stubs: { | |
40 | + symbol_file: "libcgrouprc.map.txt", | |
41 | + versions: ["29"], | |
42 | + }, | |
43 | + version_script: "libcgrouprc.map.txt", | |
44 | +} | |
45 | + | |
46 | +llndk_library { | |
47 | + name: "libcgrouprc", | |
48 | + symbol_file: "libcgrouprc.map.txt", | |
49 | + export_include_dirs: [ | |
50 | + "include", | |
51 | + ], | |
52 | +} |
@@ -0,0 +1,38 @@ | ||
1 | +/* | |
2 | + * Copyright (C) 2019 The Android Open Source Project | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | + | |
17 | +#include <android-base/logging.h> | |
18 | +#include <android/cgrouprc.h> | |
19 | + | |
20 | +#include "cgrouprc_internal.h" | |
21 | + | |
22 | +// All ACgroupController_* functions implicitly convert the pointer back | |
23 | +// to the original CgroupController pointer before invoking the member functions. | |
24 | + | |
25 | +uint32_t ACgroupController_getVersion(const ACgroupController* controller) { | |
26 | + CHECK(controller != nullptr); | |
27 | + return controller->version(); | |
28 | +} | |
29 | + | |
30 | +const char* ACgroupController_getName(const ACgroupController* controller) { | |
31 | + CHECK(controller != nullptr); | |
32 | + return controller->name(); | |
33 | +} | |
34 | + | |
35 | +const char* ACgroupController_getPath(const ACgroupController* controller) { | |
36 | + CHECK(controller != nullptr); | |
37 | + return controller->path(); | |
38 | +} |
@@ -0,0 +1,106 @@ | ||
1 | +/* | |
2 | + * Copyright (C) 2019 The Android Open Source Project | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | + | |
17 | +#include <sys/mman.h> | |
18 | +#include <sys/stat.h> | |
19 | + | |
20 | +#include <memory> | |
21 | + | |
22 | +#include <android-base/logging.h> | |
23 | +#include <android-base/stringprintf.h> | |
24 | +#include <android-base/unique_fd.h> | |
25 | +#include <android/cgrouprc.h> | |
26 | +#include <processgroup/processgroup.h> | |
27 | + | |
28 | +#include "cgrouprc_internal.h" | |
29 | + | |
30 | +using android::base::StringPrintf; | |
31 | +using android::base::unique_fd; | |
32 | + | |
33 | +using android::cgrouprc::format::CgroupController; | |
34 | +using android::cgrouprc::format::CgroupFile; | |
35 | + | |
36 | +static CgroupFile* LoadRcFile() { | |
37 | + struct stat sb; | |
38 | + | |
39 | + unique_fd fd(TEMP_FAILURE_RETRY(open(CGROUPS_RC_PATH, O_RDONLY | O_CLOEXEC))); | |
40 | + if (fd < 0) { | |
41 | + PLOG(ERROR) << "open() failed for " << CGROUPS_RC_PATH; | |
42 | + return nullptr; | |
43 | + } | |
44 | + | |
45 | + if (fstat(fd, &sb) < 0) { | |
46 | + PLOG(ERROR) << "fstat() failed for " << CGROUPS_RC_PATH; | |
47 | + return nullptr; | |
48 | + } | |
49 | + | |
50 | + size_t file_size = sb.st_size; | |
51 | + if (file_size < sizeof(CgroupFile)) { | |
52 | + LOG(ERROR) << "Invalid file format " << CGROUPS_RC_PATH; | |
53 | + return nullptr; | |
54 | + } | |
55 | + | |
56 | + CgroupFile* file_data = (CgroupFile*)mmap(nullptr, file_size, PROT_READ, MAP_SHARED, fd, 0); | |
57 | + if (file_data == MAP_FAILED) { | |
58 | + PLOG(ERROR) << "Failed to mmap " << CGROUPS_RC_PATH; | |
59 | + return nullptr; | |
60 | + } | |
61 | + | |
62 | + if (file_data->version_ != CgroupFile::FILE_CURR_VERSION) { | |
63 | + LOG(ERROR) << CGROUPS_RC_PATH << " file version mismatch"; | |
64 | + munmap(file_data, file_size); | |
65 | + return nullptr; | |
66 | + } | |
67 | + | |
68 | + auto expected = sizeof(CgroupFile) + file_data->controller_count_ * sizeof(CgroupController); | |
69 | + if (file_size != expected) { | |
70 | + LOG(ERROR) << CGROUPS_RC_PATH << " file has invalid size, expected " << expected | |
71 | + << ", actual " << file_size; | |
72 | + munmap(file_data, file_size); | |
73 | + return nullptr; | |
74 | + } | |
75 | + | |
76 | + return file_data; | |
77 | +} | |
78 | + | |
79 | +static CgroupFile* GetInstance() { | |
80 | + // Deliberately leak this object (not munmap) to avoid a race between destruction on | |
81 | + // process exit and concurrent access from another thread. | |
82 | + static auto* file = LoadRcFile(); | |
83 | + return file; | |
84 | +} | |
85 | + | |
86 | +uint32_t ACgroupFile_getVersion() { | |
87 | + auto file = GetInstance(); | |
88 | + if (file == nullptr) return 0; | |
89 | + return file->version_; | |
90 | +} | |
91 | + | |
92 | +uint32_t ACgroupFile_getControllerCount() { | |
93 | + auto file = GetInstance(); | |
94 | + if (file == nullptr) return 0; | |
95 | + return file->controller_count_; | |
96 | +} | |
97 | + | |
98 | +const ACgroupController* ACgroupFile_getController(uint32_t index) { | |
99 | + auto file = GetInstance(); | |
100 | + if (file == nullptr) return nullptr; | |
101 | + CHECK(index < file->controller_count_); | |
102 | + // Although the object is not actually an ACgroupController object, all ACgroupController_* | |
103 | + // functions implicitly convert ACgroupController* back to CgroupController* before invoking | |
104 | + // member functions. | |
105 | + return static_cast<ACgroupController*>(&file->controllers_[index]); | |
106 | +} |
@@ -0,0 +1,24 @@ | ||
1 | +/* | |
2 | + * Copyright (C) 2019 The Android Open Source Project | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | + | |
17 | +#pragma once | |
18 | + | |
19 | +#include <android/cgrouprc.h> | |
20 | + | |
21 | +#include <processgroup/format/cgroup_controller.h> | |
22 | +#include <processgroup/format/cgroup_file.h> | |
23 | + | |
24 | +struct ACgroupController : android::cgrouprc::format::CgroupController {}; |
@@ -0,0 +1,84 @@ | ||
1 | +/* | |
2 | + * Copyright (C) 2019 The Android Open Source Project | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | + | |
17 | +#pragma once | |
18 | + | |
19 | +#include <stdint.h> | |
20 | + | |
21 | +__BEGIN_DECLS | |
22 | + | |
23 | +// For host builds, __INTRODUCED_IN is not defined. | |
24 | +#ifndef __INTRODUCED_IN | |
25 | +#define __INTRODUCED_IN(x) | |
26 | +#endif | |
27 | + | |
28 | +struct ACgroupController; | |
29 | +typedef struct ACgroupController ACgroupController; | |
30 | + | |
31 | +#if __ANDROID_API__ >= __ANDROID_API_Q__ | |
32 | + | |
33 | +// ACgroupFile | |
34 | + | |
35 | +/** | |
36 | + * Returns file version. See android::cgrouprc::format::CgroupFile for a list of valid versions | |
37 | + * for the file. | |
38 | + * If ACgroupFile_init() isn't called, initialization will be done first. | |
39 | + * If initialization failed, return 0. | |
40 | + */ | |
41 | +__attribute__((warn_unused_result)) uint32_t ACgroupFile_getVersion() __INTRODUCED_IN(29); | |
42 | + | |
43 | +/** | |
44 | + * Returns the number of controllers. | |
45 | + * If ACgroupFile_init() isn't called, initialization will be done first. | |
46 | + * If initialization failed, return 0. | |
47 | + */ | |
48 | +__attribute__((warn_unused_result)) uint32_t ACgroupFile_getControllerCount() __INTRODUCED_IN(29); | |
49 | + | |
50 | +/** | |
51 | + * Returns the controller at the given index. | |
52 | + * Returnss nullptr if the given index exceeds getControllerCount(). | |
53 | + * If ACgroupFile_init() isn't called, initialization will be done first. | |
54 | + * If initialization failed, return 0. | |
55 | + */ | |
56 | +__attribute__((warn_unused_result)) const ACgroupController* ACgroupFile_getController( | |
57 | + uint32_t index) __INTRODUCED_IN(29); | |
58 | + | |
59 | +// ACgroupController | |
60 | + | |
61 | +/** | |
62 | + * Returns the version of the given controller. | |
63 | + * If the given controller is null, return 0. | |
64 | + */ | |
65 | +__attribute__((warn_unused_result)) uint32_t ACgroupController_getVersion(const ACgroupController*) | |
66 | + __INTRODUCED_IN(29); | |
67 | + | |
68 | +/** | |
69 | + * Returns the name of the given controller. | |
70 | + * If the given controller is null, return nullptr. | |
71 | + */ | |
72 | +__attribute__((warn_unused_result)) const char* ACgroupController_getName(const ACgroupController*) | |
73 | + __INTRODUCED_IN(29); | |
74 | + | |
75 | +/** | |
76 | + * Returns the path of the given controller. | |
77 | + * If the given controller is null, return nullptr. | |
78 | + */ | |
79 | +__attribute__((warn_unused_result)) const char* ACgroupController_getPath(const ACgroupController*) | |
80 | + __INTRODUCED_IN(29); | |
81 | + | |
82 | +__END_DECLS | |
83 | + | |
84 | +#endif |
@@ -0,0 +1,11 @@ | ||
1 | +LIBCGROUPRC { # introduced=29 | |
2 | + global: | |
3 | + ACgroupFile_getVersion; | |
4 | + ACgroupFile_getControllerCount; | |
5 | + ACgroupFile_getController; | |
6 | + ACgroupController_getVersion; | |
7 | + ACgroupController_getName; | |
8 | + ACgroupController_getPath; | |
9 | + local: | |
10 | + *; | |
11 | +}; |