Merge "snapshotctl: Add a test-blank-ota command for development."
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 76ef9e4..7189a71 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -754,10 +754,11 @@
}
#ifdef NO_SKIP_MOUNT
-bool SkipMountingPartitions(Fstab*, bool) {
- return true;
-}
+static constexpr bool kNoSkipMount = true;
#else
+static constexpr bool kNoSkipMount = false;
+#endif
+
// For GSI to skip mounting /product and /system_ext, until there are well-defined interfaces
// between them and /system. Otherwise, the GSI flashed on /system might not be able to work with
// device-specific /product and /system_ext. skip_mount.cfg belongs to system_ext partition because
@@ -765,17 +766,24 @@
// /system/system_ext because GSI is a single system.img that includes the contents of system_ext
// partition and product partition under /system/system_ext and /system/product, respectively.
bool SkipMountingPartitions(Fstab* fstab, bool verbose) {
- static constexpr char kSkipMountConfig[] = "/system/system_ext/etc/init/config/skip_mount.cfg";
-
- std::string skip_config;
- auto save_errno = errno;
- if (!ReadFileToString(kSkipMountConfig, &skip_config)) {
- errno = save_errno; // missing file is expected
+ if (kNoSkipMount) {
return true;
}
+ static constexpr char kSkipMountConfig[] = "/system/system_ext/etc/init/config/skip_mount.cfg";
+
+ std::string skip_mount_config;
+ auto save_errno = errno;
+ if (!ReadFileToString(kSkipMountConfig, &skip_mount_config)) {
+ errno = save_errno; // missing file is expected
+ return true;
+ }
+ return SkipMountWithConfig(skip_mount_config, fstab, verbose);
+}
+
+bool SkipMountWithConfig(const std::string& skip_mount_config, Fstab* fstab, bool verbose) {
std::vector<std::string> skip_mount_patterns;
- for (const auto& line : Split(skip_config, "\n")) {
+ for (const auto& line : Split(skip_mount_config, "\n")) {
if (line.empty() || StartsWith(line, "#")) {
continue;
}
@@ -801,7 +809,6 @@
fstab->erase(remove_from, fstab->end());
return true;
}
-#endif
// Loads the fstab file and combines with fstab entries passed in from device tree.
bool ReadDefaultFstab(Fstab* fstab) {
diff --git a/fs_mgr/fuzz/fs_mgr_fstab_fuzzer.cpp b/fs_mgr/fuzz/fs_mgr_fstab_fuzzer.cpp
index 6a8a191..b5fdad4 100644
--- a/fs_mgr/fuzz/fs_mgr_fstab_fuzzer.cpp
+++ b/fs_mgr/fuzz/fs_mgr_fstab_fuzzer.cpp
@@ -14,13 +14,27 @@
// limitations under the License.
//
-#include <cstdio>
+#include <string>
+#include <vector>
#include <fstab/fstab.h>
+#include <fuzzer/FuzzedDataProvider.h>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- std::string make_fstab_str(reinterpret_cast<const char*>(data), size);
+ FuzzedDataProvider fdp(data, size);
+
+ std::string make_fstab_str = fdp.ConsumeRandomLengthString();
+ std::string dsu_slot = fdp.ConsumeRandomLengthString(30);
+ std::vector<std::string> dsu_partitions = {
+ fdp.ConsumeRandomLengthString(30),
+ fdp.ConsumeRandomLengthString(30),
+ };
+ std::string skip_mount_config = fdp.ConsumeRemainingBytesAsString();
+
android::fs_mgr::Fstab fstab;
android::fs_mgr::ParseFstabFromString(make_fstab_str, /* proc_mounts = */ false, &fstab);
+ android::fs_mgr::TransformFstabForDsu(&fstab, dsu_slot, dsu_partitions);
+ android::fs_mgr::SkipMountWithConfig(skip_mount_config, &fstab, /* verbose = */ false);
+
return 0;
}
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h
index 689d18b..124f070 100644
--- a/fs_mgr/include_fstab/fstab/fstab.h
+++ b/fs_mgr/include_fstab/fstab/fstab.h
@@ -97,6 +97,8 @@
bool ParseFstabFromString(const std::string& fstab_str, bool proc_mounts, Fstab* fstab_out);
// Exported for testability. Regular users should use ReadDefaultFstab().
std::string GetFstabPath();
+// Exported for testability.
+bool SkipMountWithConfig(const std::string& skip_config, Fstab* fstab, bool verbose);
bool ReadFstabFromFile(const std::string& path, Fstab* fstab);
bool ReadFstabFromDt(Fstab* fstab, bool verbose = true);
diff --git a/init/init.cpp b/init/init.cpp
index 837d955..4ca351c 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -662,6 +662,10 @@
}
static Result<void> SetupCgroupsAction(const BuiltinArguments&) {
+ if (!CgroupsAvailable()) {
+ LOG(INFO) << "Cgroups support in kernel is not enabled";
+ return {};
+ }
// Have to create <CGROUPS_RC_DIR> using make_dir function
// for appropriate sepolicy to be set for it
make_dir(android::base::Dirname(CGROUPS_RC_PATH), 0711);
diff --git a/init/service.cpp b/init/service.cpp
index 26b3b42..6a9343d 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -692,24 +692,28 @@
start_order_ = next_start_order_++;
process_cgroup_empty_ = false;
- bool use_memcg = swappiness_ != -1 || soft_limit_in_bytes_ != -1 || limit_in_bytes_ != -1 ||
- limit_percent_ != -1 || !limit_property_.empty();
- errno = -createProcessGroup(proc_attr_.uid, pid_, use_memcg);
- if (errno != 0) {
- if (char byte = 0; write((*pipefd)[1], &byte, 1) < 0) {
- return ErrnoError() << "sending notification failed";
+ if (CgroupsAvailable()) {
+ bool use_memcg = swappiness_ != -1 || soft_limit_in_bytes_ != -1 || limit_in_bytes_ != -1 ||
+ limit_percent_ != -1 || !limit_property_.empty();
+ errno = -createProcessGroup(proc_attr_.uid, pid_, use_memcg);
+ if (errno != 0) {
+ if (char byte = 0; write((*pipefd)[1], &byte, 1) < 0) {
+ return ErrnoError() << "sending notification failed";
+ }
+ return Error() << "createProcessGroup(" << proc_attr_.uid << ", " << pid_
+ << ") failed for service '" << name_ << "'";
}
- return Error() << "createProcessGroup(" << proc_attr_.uid << ", " << pid_
- << ") failed for service '" << name_ << "'";
- }
- // When the blkio controller is mounted in the v1 hierarchy, NormalIoPriority is
- // the default (/dev/blkio). When the blkio controller is mounted in the v2 hierarchy, the
- // NormalIoPriority profile has to be applied explicitly.
- SetProcessProfiles(proc_attr_.uid, pid_, {"NormalIoPriority"});
+ // When the blkio controller is mounted in the v1 hierarchy, NormalIoPriority is
+ // the default (/dev/blkio). When the blkio controller is mounted in the v2 hierarchy, the
+ // NormalIoPriority profile has to be applied explicitly.
+ SetProcessProfiles(proc_attr_.uid, pid_, {"NormalIoPriority"});
- if (use_memcg) {
- ConfigureMemcg();
+ if (use_memcg) {
+ ConfigureMemcg();
+ }
+ } else {
+ process_cgroup_empty_ = true;
}
if (oom_score_adjust_ != DEFAULT_OOM_SCORE_ADJUST) {
diff --git a/init/service_utils.cpp b/init/service_utils.cpp
index d19f5ee..a14969e 100644
--- a/init/service_utils.cpp
+++ b/init/service_utils.cpp
@@ -280,6 +280,15 @@
}
Result<void> WritePidToFiles(std::vector<std::string>* files) {
+ if (files->empty()) {
+ // No files to write pid to, exit early.
+ return {};
+ }
+
+ if (!CgroupsAvailable()) {
+ return Error() << "cgroups are not available";
+ }
+
// See if there were "writepid" instructions to write to files under cpuset path.
std::string cpuset_path;
if (CgroupGetControllerPath("cpuset", &cpuset_path)) {
diff --git a/libprocessgroup/include/processgroup/processgroup.h b/libprocessgroup/include/processgroup/processgroup.h
index 45a723f..9b2d775 100644
--- a/libprocessgroup/include/processgroup/processgroup.h
+++ b/libprocessgroup/include/processgroup/processgroup.h
@@ -28,6 +28,7 @@
static constexpr const char* CGROUPV2_CONTROLLER_NAME = "cgroup2";
+bool CgroupsAvailable();
bool CgroupGetControllerPath(const std::string& cgroup_name, std::string* path);
bool CgroupGetControllerFromPath(const std::string& path, std::string* cgroup_name);
bool CgroupGetAttributePath(const std::string& attr_name, std::string* path);
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index bdda102..3fac373 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -55,6 +55,11 @@
#define PROCESSGROUP_CGROUP_PROCS_FILE "/cgroup.procs"
+bool CgroupsAvailable() {
+ static bool cgroups_available = access("/proc/cgroups", F_OK) == 0;
+ return cgroups_available;
+}
+
bool CgroupGetControllerPath(const std::string& cgroup_name, std::string* path) {
auto controller = CgroupMap::GetInstance().FindController(cgroup_name);