fs_mgr: Split libfs_mgr and libfstab

The goal is to make the header definitions of the two curiously
intertwined libraries less chaotic.

After this change, libfstab's header would be self contained. In the
sense that all symbols exported by its headers are defined in its
compilation units.
libfs_mgr would still embed libfstab like before, it can use internal
symbols (symbols not exported by public headers) of libfstab through
the libfstab/fstab_priv.h private header.

Keep include_fstab/ as a symbolic link pointing to its new location.
This is a temporary workaround as there are still some bad build rules
(incorrectly) depending on the old include path with Android.bp
`include_dirs` directive.

Bug: 293695109
Test: build
Change-Id: Ib70a84984ac2cbfca5f5b27fadebf6a16e58146a
This commit is contained in:
Yi-Yo Chiang 2023-07-24 20:03:01 +08:00
parent c30f033b4e
commit 96126069c2
16 changed files with 146 additions and 85 deletions

View file

@ -89,8 +89,6 @@ cc_defaults {
static_libs: [
"libavb",
"libfs_avb",
"libfstab",
"libdm",
"libgsi",
],
export_static_lib_headers: [
@ -173,47 +171,6 @@ cc_library {
],
}
cc_library_static {
// Do not ever make this a shared library as long as it is vendor_available.
// It does not have a stable interface.
name: "libfstab",
vendor_available: true,
ramdisk_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
apex_available: [
"//apex_available:anyapex",
"//apex_available:platform",
],
host_supported: true,
defaults: ["fs_mgr_defaults"],
local_include_dirs: ["include/"],
srcs: [
"fs_mgr_fstab.cpp",
"fs_mgr_boot_config.cpp",
"fs_mgr_slotselect.cpp",
],
target: {
darwin: {
enabled: false,
},
vendor: {
cflags: [
// Skipping entries in fstab should only be done in a system
// process as the config file is in /system_ext.
// Remove the op from the vendor variant.
"-DNO_SKIP_MOUNT",
],
},
},
export_include_dirs: ["include_fstab"],
header_libs: [
"libbase_headers",
"libgsi_headers",
],
min_sdk_version: "31",
}
cc_binary {
name: "remount",
defaults: ["fs_mgr_defaults"],

View file

@ -23,15 +23,7 @@
#include <fs_mgr.h>
#include <fstab/fstab.h>
#include "fs_mgr_priv_boot_config.h"
/* The CHECK() in logging.h will use program invocation name as the tag.
* Thus, the log will have prefix "init: " when libfs_mgr is statically
* linked in the init process. This might be opaque when debugging.
* Appends "in libfs_mgr" at the end of the abort message to explicitly
* indicate the check happens in fs_mgr.
*/
#define FS_MGR_CHECK(x) CHECK(x) << "in libfs_mgr "
#include "libfstab/fstab_priv.h"
#define FS_MGR_TAG "[libfs_mgr] "
@ -89,10 +81,7 @@
using namespace std::chrono_literals;
bool fs_mgr_set_blk_ro(const std::string& blockdev, bool readonly = true);
bool fs_mgr_update_for_slotselect(android::fs_mgr::Fstab* fstab);
bool fs_mgr_is_device_unlocked();
const std::string& get_android_dt_dir();
bool is_dt_compatible();
bool fs_mgr_is_ext4(const std::string& blk_device);
bool fs_mgr_is_f2fs(const std::string& blk_device);
@ -104,7 +93,6 @@ namespace android {
namespace fs_mgr {
bool UnmapDevice(const std::string& name);
bool InRecovery();
struct OverlayfsCheckResult {
bool supported;

1
fs_mgr/include_fstab Symbolic link
View file

@ -0,0 +1 @@
libfstab/include

View file

@ -0,0 +1,62 @@
//
// Copyright (C) 2023 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.
//
package {
default_applicable_licenses: [
"Android-Apache-2.0",
"system_core_fs_mgr_license",
],
}
cc_library_static {
// Do not ever make this a shared library as long as it is vendor_available.
// It does not have a stable interface.
name: "libfstab",
vendor_available: true,
ramdisk_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
host_supported: true,
defaults: ["fs_mgr_defaults"],
export_include_dirs: ["include"],
header_libs: [
"libbase_headers",
"libgsi_headers",
],
srcs: [
"fstab.cpp",
"boot_config.cpp",
"slotselect.cpp",
],
target: {
darwin: {
enabled: false,
},
vendor: {
cflags: [
// Skipping entries in fstab should only be done in a system
// process as the config file is in /system_ext.
// Remove the op from the vendor variant.
"-DNO_SKIP_MOUNT",
],
},
},
apex_available: [
"//apex_available:anyapex",
"//apex_available:platform",
],
min_sdk_version: "31",
}

View file

@ -20,11 +20,12 @@
#include <vector>
#include <android-base/file.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/properties.h>
#include "fs_mgr_priv.h"
#include "fstab_priv.h"
#include "logging_macros.h"
std::vector<std::pair<std::string, std::string>> fs_mgr_parse_cmdline(const std::string& cmdline) {
static constexpr char quote = '"';
@ -84,7 +85,7 @@ std::vector<std::pair<std::string, std::string>> fs_mgr_parse_proc_bootconfig(
bool fs_mgr_get_boot_config_from_bootconfig(const std::string& bootconfig,
const std::string& android_key, std::string* out_val) {
FS_MGR_CHECK(out_val != nullptr);
FSTAB_CHECK(out_val != nullptr);
const std::string bootconfig_key("androidboot." + android_key);
for (const auto& [key, value] : fs_mgr_parse_proc_bootconfig(bootconfig)) {
@ -100,7 +101,7 @@ bool fs_mgr_get_boot_config_from_bootconfig(const std::string& bootconfig,
bool fs_mgr_get_boot_config_from_kernel(const std::string& cmdline, const std::string& android_key,
std::string* out_val) {
FS_MGR_CHECK(out_val != nullptr);
FSTAB_CHECK(out_val != nullptr);
const std::string cmdline_key("androidboot." + android_key);
for (const auto& [key, value] : fs_mgr_parse_cmdline(cmdline)) {
@ -140,7 +141,7 @@ bool fs_mgr_get_boot_config_from_kernel_cmdline(const std::string& key, std::str
// kernel cmdline (in that order). Returns 'true' if successfully
// found, 'false' otherwise.
bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val) {
FS_MGR_CHECK(out_val != nullptr);
FSTAB_CHECK(out_val != nullptr);
// firstly, check the device tree
if (is_dt_compatible()) {

View file

@ -36,7 +36,8 @@
#include <android-base/strings.h>
#include <libgsi/libgsi.h>
#include "fs_mgr_priv.h"
#include "fstab_priv.h"
#include "logging_macros.h"
using android::base::EndsWith;
using android::base::ParseByteCount;
@ -54,7 +55,7 @@ constexpr char kDefaultAndroidDtDir[] = "/proc/device-tree/firmware/android";
constexpr char kProcMountsPath[] = "/proc/mounts";
struct FlagList {
const char *name;
const char* name;
uint64_t flag;
};
@ -80,7 +81,7 @@ FlagList kMountFlagsList[] = {
off64_t CalculateZramSize(int percentage) {
off64_t total;
total = sysconf(_SC_PHYS_PAGES);
total = sysconf(_SC_PHYS_PAGES);
total *= percentage;
total /= 100;
@ -400,7 +401,7 @@ std::string ReadFstabFromDt() {
std::string mount_point;
file_name =
android::base::StringPrintf("%s/%s/mnt_point", fstabdir_name.c_str(), dp->d_name);
android::base::StringPrintf("%s/%s/mnt_point", fstabdir_name.c_str(), dp->d_name);
if (ReadDtFile(file_name, &value)) {
LINFO << "dt_fstab: Using a specified mount point " << value << " for " << dp->d_name;
mount_point = value;
@ -416,14 +417,16 @@ std::string ReadFstabFromDt() {
}
fstab_entry.push_back(value);
file_name = android::base::StringPrintf("%s/%s/mnt_flags", fstabdir_name.c_str(), dp->d_name);
file_name =
android::base::StringPrintf("%s/%s/mnt_flags", fstabdir_name.c_str(), dp->d_name);
if (!ReadDtFile(file_name, &value)) {
LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;
return {};
}
fstab_entry.push_back(value);
file_name = android::base::StringPrintf("%s/%s/fsmgr_flags", fstabdir_name.c_str(), dp->d_name);
file_name =
android::base::StringPrintf("%s/%s/fsmgr_flags", fstabdir_name.c_str(), dp->d_name);
if (!ReadDtFile(file_name, &value)) {
LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;
return {};

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 The Android Open Source Project
* Copyright (C) 2023 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.
@ -14,16 +14,17 @@
* limitations under the License.
*/
#ifndef __CORE_FS_MGR_PRIV_BOOTCONFIG_H
#define __CORE_FS_MGR_PRIV_BOOTCONFIG_H
#pragma once
#include <sys/cdefs.h>
#include <string>
#include <utility>
#include <vector>
std::vector<std::pair<std::string, std::string>> fs_mgr_parse_cmdline(const std::string& cmdline);
#include <fstab/fstab.h>
// Do not include logging_macros.h here as this header is used by fs_mgr, too.
std::vector<std::pair<std::string, std::string>> fs_mgr_parse_cmdline(const std::string& cmdline);
bool fs_mgr_get_boot_config_from_kernel(const std::string& cmdline, const std::string& key,
std::string* out_val);
bool fs_mgr_get_boot_config_from_kernel_cmdline(const std::string& key, std::string* out_val);
@ -34,4 +35,17 @@ bool fs_mgr_get_boot_config_from_bootconfig(const std::string& bootconfig, const
std::string* out_val);
bool fs_mgr_get_boot_config_from_bootconfig_source(const std::string& key, std::string* out_val);
#endif /* __CORE_FS_MGR_PRIV_BOOTCONFIG_H */
bool fs_mgr_update_for_slotselect(android::fs_mgr::Fstab* fstab);
const std::string& get_android_dt_dir();
bool is_dt_compatible();
namespace android {
namespace fs_mgr {
bool InRecovery();
bool ParseFstabFromString(const std::string& fstab_str, bool proc_mounts, Fstab* fstab_out);
bool SkipMountWithConfig(const std::string& skip_config, Fstab* fstab, bool verbose);
std::string GetFstabPath();
} // namespace fs_mgr
} // namespace android

View file

@ -20,6 +20,8 @@
#include <fstab/fstab.h>
#include <fuzzer/FuzzedDataProvider.h>
#include "../fstab_priv.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
FuzzedDataProvider fdp(data, size);

View file

@ -93,13 +93,6 @@ struct FstabEntry {
// Unless explicitly requested, a lookup on mount point should always return the 1st one.
using Fstab = std::vector<FstabEntry>;
// Exported for testability. Regular users should use ReadFstabFromFile().
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 ReadFstabFromProcMounts(Fstab* fstab);
bool ReadFstabFromDt(Fstab* fstab, bool verbose = true);

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2023 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.
*/
#pragma once
#include <android-base/logging.h>
#define FSTAB_TAG "[libfstab] "
/* The CHECK() in logging.h will use program invocation name as the tag.
* Thus, the log will have prefix "init: " when libfs_mgr is statically
* linked in the init process. This might be opaque when debugging.
* Append a library name tag at the end of the abort message to aid debugging.
*/
#define FSTAB_CHECK(x) CHECK(x) << "in " << FSTAB_TAG
// Logs a message to kernel
#define LINFO LOG(INFO) << FSTAB_TAG
#define LWARNING LOG(WARNING) << FSTAB_TAG
#define LERROR LOG(ERROR) << FSTAB_TAG
#define LFATAL LOG(FATAL) << FSTAB_TAG
// Logs a message with strerror(errno) at the end
#define PINFO PLOG(INFO) << FSTAB_TAG
#define PWARNING PLOG(WARNING) << FSTAB_TAG
#define PERROR PLOG(ERROR) << FSTAB_TAG
#define PFATAL PLOG(FATAL) << FSTAB_TAG

View file

@ -18,8 +18,8 @@
#include <string>
#include "fs_mgr.h"
#include "fs_mgr_priv.h"
#include "fstab_priv.h"
#include "logging_macros.h"
// Realistically, this file should be part of the android::fs_mgr namespace;
using namespace android::fs_mgr;

View file

@ -38,7 +38,6 @@ cc_test {
],
static_libs: [
"libfs_mgr",
"libfstab",
],
srcs: [
"file_wait_test.cpp",
@ -109,7 +108,6 @@ cc_test {
],
static_libs: [
"libfs_mgr",
"libfstab",
"libgmock",
"libgtest",
],

View file

@ -31,7 +31,7 @@
#include <fstab/fstab.h>
#include <gtest/gtest.h>
#include "../fs_mgr_priv_boot_config.h"
#include "../fs_mgr_priv.h"
using namespace android::fs_mgr;

View file

@ -23,6 +23,8 @@
#include <gtest/gtest.h>
#include <libdm/dm.h>
#include "../fs_mgr_priv.h"
using testing::Contains;
using testing::Not;