Merge "liblog: simplify fake_log_device"
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 2dc47bb..7b686f0 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -91,6 +91,7 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
using android::base::Basename;
+using android::base::GetBoolProperty;
using android::base::Realpath;
using android::base::StartsWith;
using android::base::unique_fd;
@@ -1357,14 +1358,33 @@
return ret;
}
+static std::string GetBlockDeviceForMountPoint(const std::string& mount_point) {
+ Fstab mounts;
+ if (!ReadFstabFromFile("/proc/mounts", &mounts)) {
+ LERROR << "Can't read /proc/mounts";
+ return "";
+ }
+ auto entry = GetEntryForMountPoint(&mounts, mount_point);
+ if (entry == nullptr) {
+ LWARNING << mount_point << " is not mounted";
+ return "";
+ }
+ return entry->blk_device;
+}
+
// TODO(b/143970043): return different error codes based on which step failed.
int fs_mgr_remount_userdata_into_checkpointing(Fstab* fstab) {
- auto entry = GetMountedEntryForUserdata(fstab);
- if (entry == nullptr) {
+ std::string block_device = GetBlockDeviceForMountPoint("/data");
+ if (block_device.empty()) {
+ LERROR << "/data is not mounted";
+ return -1;
+ }
+ auto fstab_entry = GetMountedEntryForUserdata(fstab);
+ if (fstab_entry == nullptr) {
LERROR << "Can't find /data in fstab";
return -1;
}
- if (!entry->fs_mgr_flags.checkpoint_blk && !entry->fs_mgr_flags.checkpoint_fs) {
+ if (!fstab_entry->fs_mgr_flags.checkpoint_blk && !fstab_entry->fs_mgr_flags.checkpoint_fs) {
LINFO << "Userdata doesn't support checkpointing. Nothing to do";
return 0;
}
@@ -1373,34 +1393,43 @@
LINFO << "Checkpointing not needed. Don't remount";
return 0;
}
- if (entry->fs_mgr_flags.checkpoint_fs) {
+ bool force_umount_for_f2fs =
+ GetBoolProperty("sys.init.userdata_remount.force_umount_f2fs", false);
+ if (fstab_entry->fs_mgr_flags.checkpoint_fs && !force_umount_for_f2fs) {
// Userdata is f2fs, simply remount it.
- if (!checkpoint_manager.Update(&(*entry))) {
+ if (!checkpoint_manager.Update(fstab_entry)) {
LERROR << "Failed to remount userdata in checkpointing mode";
return -1;
}
- if (mount(entry->blk_device.c_str(), entry->mount_point.c_str(), "none",
- MS_REMOUNT | entry->flags, entry->fs_options.c_str()) != 0) {
+ if (mount(block_device.c_str(), fstab_entry->mount_point.c_str(), "none",
+ MS_REMOUNT | fstab_entry->flags, fstab_entry->fs_options.c_str()) != 0) {
PERROR << "Failed to remount userdata in checkpointing mode";
return -1;
}
} else {
- // STOPSHIP(b/143970043): support remounting for ext4 + metadata encryption.
- if (should_use_metadata_encryption(*entry)) {
- LWARNING << "Remounting into checkpointing is not supported for metadata encrypted "
- << "ext4 userdata. Proceed with caution";
- return 0;
- }
+ LINFO << "Unmounting /data before remounting into checkpointing mode";
if (umount2("/data", UMOUNT_NOFOLLOW) != 0) {
PERROR << "Failed to umount /data";
return -1;
}
DeviceMapper& dm = DeviceMapper::Instance();
- // TODO(b/143970043): need to delete every dm-device under the one userdata is mounted on.
- if (!dm.DeleteDeviceIfExists("bow")) {
- LERROR << "Failed to delete dm-bow";
- return -1;
+ while (dm.IsDmBlockDevice(block_device)) {
+ auto next_device = dm.GetParentBlockDeviceByPath(block_device);
+ auto name = dm.GetDmDeviceNameByPath(block_device);
+ if (!name) {
+ LERROR << "Failed to get dm-name for " << block_device;
+ return -1;
+ }
+ LINFO << "Deleting " << block_device << " named " << *name;
+ if (!dm.DeleteDevice(*name, 3s)) {
+ return -1;
+ }
+ if (!next_device) {
+ LERROR << "Failed to find parent device for " << block_device;
+ }
+ block_device = *next_device;
}
+ LINFO << "Remounting /data";
// TODO(b/143970043): remove this hack after fs_mgr_mount_all is refactored.
int result = fs_mgr_mount_all(fstab, MOUNT_MODE_ONLY_USERDATA);
return result == FS_MGR_MNTALL_FAIL ? -1 : 0;
diff --git a/init/host_init_verifier.cpp b/init/host_init_verifier.cpp
index 3acc3cc..22de846 100644
--- a/init/host_init_verifier.cpp
+++ b/init/host_init_verifier.cpp
@@ -191,7 +191,7 @@
}
auto errors = std::vector<std::string>{};
- ParsePropertyInfoFile(file_contents, property_infos, &errors);
+ ParsePropertyInfoFile(file_contents, true, property_infos, &errors);
for (const auto& error : errors) {
LOG(ERROR) << "Could not read line from '" << filename << "': " << error;
}
diff --git a/init/property_service.cpp b/init/property_service.cpp
index adf8929..5b35ad2 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -925,7 +925,8 @@
}
auto errors = std::vector<std::string>{};
- ParsePropertyInfoFile(file_contents, property_infos, &errors);
+ bool require_prefix_or_exact = SelinuxGetVendorAndroidVersion() >= __ANDROID_API_R__;
+ ParsePropertyInfoFile(file_contents, require_prefix_or_exact, property_infos, &errors);
// Individual parsing errors are reported but do not cause a failed boot, which is what
// returning false would do here.
for (const auto& error : errors) {
diff --git a/property_service/libpropertyinfoserializer/include/property_info_serializer/property_info_serializer.h b/property_service/libpropertyinfoserializer/include/property_info_serializer/property_info_serializer.h
index 439813d..dfb1d11 100644
--- a/property_service/libpropertyinfoserializer/include/property_info_serializer/property_info_serializer.h
+++ b/property_service/libpropertyinfoserializer/include/property_info_serializer/property_info_serializer.h
@@ -14,8 +14,7 @@
// limitations under the License.
//
-#ifndef PROPERTY_INFO_SERIALIZER_H
-#define PROPERTY_INFO_SERIALIZER_H
+#pragma once
#include <string>
#include <vector>
@@ -41,11 +40,9 @@
const std::string& default_context, const std::string& default_type,
std::string* serialized_trie, std::string* error);
-void ParsePropertyInfoFile(const std::string& file_contents,
+void ParsePropertyInfoFile(const std::string& file_contents, bool require_prefix_or_exact,
std::vector<PropertyInfoEntry>* property_infos,
std::vector<std::string>* errors);
} // namespace properties
} // namespace android
-
-#endif
diff --git a/property_service/libpropertyinfoserializer/property_info_file.cpp b/property_service/libpropertyinfoserializer/property_info_file.cpp
index 2cdc62d..771a9ce 100644
--- a/property_service/libpropertyinfoserializer/property_info_file.cpp
+++ b/property_service/libpropertyinfoserializer/property_info_file.cpp
@@ -56,7 +56,8 @@
return false;
}
-bool ParsePropertyInfoLine(const std::string& line, PropertyInfoEntry* out, std::string* error) {
+bool ParsePropertyInfoLine(const std::string& line, bool require_prefix_or_exact,
+ PropertyInfoEntry* out, std::string* error) {
auto tokenizer = SpaceTokenizer(line);
auto property = tokenizer.GetNext();
@@ -72,7 +73,7 @@
}
// It is not an error to not find exact_match or a type, as older files will not contain them.
- auto exact_match = tokenizer.GetNext();
+ auto match_operation = tokenizer.GetNext();
// We reformat type to be space deliminated regardless of the input whitespace for easier storage
// and subsequent parsing.
auto type_strings = std::vector<std::string>{};
@@ -82,18 +83,27 @@
type = tokenizer.GetNext();
}
+ bool exact_match = false;
+ if (match_operation == "exact") {
+ exact_match = true;
+ } else if (match_operation != "prefix" && match_operation != "" && require_prefix_or_exact) {
+ *error = "Match operation '" + match_operation +
+ "' is not valid: must be either 'prefix' or 'exact'";
+ return false;
+ }
+
if (!type_strings.empty() && !IsTypeValid(type_strings)) {
*error = "Type '" + Join(type_strings, " ") + "' is not valid";
return false;
}
- *out = {property, context, Join(type_strings, " "), exact_match == "exact"};
+ *out = {property, context, Join(type_strings, " "), exact_match};
return true;
}
} // namespace
-void ParsePropertyInfoFile(const std::string& file_contents,
+void ParsePropertyInfoFile(const std::string& file_contents, bool require_prefix_or_exact,
std::vector<PropertyInfoEntry>* property_infos,
std::vector<std::string>* errors) {
// Do not clear property_infos to allow this function to be called on multiple files, with
@@ -108,7 +118,8 @@
auto property_info_entry = PropertyInfoEntry{};
auto parse_error = std::string{};
- if (!ParsePropertyInfoLine(trimmed_line, &property_info_entry, &parse_error)) {
+ if (!ParsePropertyInfoLine(trimmed_line, require_prefix_or_exact, &property_info_entry,
+ &parse_error)) {
errors->emplace_back(parse_error);
continue;
}
diff --git a/property_service/property_info_checker/property_info_checker.cpp b/property_service/property_info_checker/property_info_checker.cpp
index 52c4383..61b368e 100644
--- a/property_service/property_info_checker/property_info_checker.cpp
+++ b/property_service/property_info_checker/property_info_checker.cpp
@@ -153,7 +153,7 @@
}
auto errors = std::vector<std::string>{};
- ParsePropertyInfoFile(file_contents, &property_info_entries, &errors);
+ ParsePropertyInfoFile(file_contents, true, &property_info_entries, &errors);
if (!errors.empty()) {
for (const auto& error : errors) {
std::cerr << "Could not read line from '" << filename << "': " << error << std::endl;