fs_mgr: fs_mgr_get_boot_config_from_kernel_cmdline deal with quote
Spans quoted with " are dealt with atomically, and are stripped from the key/value results when parsing the kernel cmdline. Test: compile, device boot, fs_mgr_unit_test Bug: 109821005 Change-Id: I45f3d7395f34295edefdeaafa4c15c6ee25cc4da
This commit is contained in:
parent
3ee8926f5d
commit
596fac3c6d
4 changed files with 226 additions and 14 deletions
|
@ -14,7 +14,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
|
@ -23,28 +26,64 @@
|
|||
|
||||
#include "fs_mgr_priv.h"
|
||||
|
||||
// Tries to get the given boot config value from kernel cmdline.
|
||||
// Returns true if successfully found, false otherwise.
|
||||
bool fs_mgr_get_boot_config_from_kernel_cmdline(const std::string& key, std::string* out_val) {
|
||||
std::vector<std::pair<std::string, std::string>> fs_mgr_parse_boot_config(const std::string& cmdline) {
|
||||
static constexpr char quote = '"';
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> result;
|
||||
size_t base = 0;
|
||||
while (true) {
|
||||
// skip quoted spans
|
||||
auto found = base;
|
||||
while (((found = cmdline.find_first_of(" \"", found)) != cmdline.npos) &&
|
||||
(cmdline[found] == quote)) {
|
||||
// unbalanced quote is ok
|
||||
if ((found = cmdline.find(quote, found + 1)) == cmdline.npos) break;
|
||||
++found;
|
||||
}
|
||||
std::string piece;
|
||||
auto source = cmdline.substr(base, found - base);
|
||||
std::remove_copy(source.begin(), source.end(),
|
||||
std::back_insert_iterator<std::string>(piece), quote);
|
||||
auto equal_sign = piece.find('=');
|
||||
if (equal_sign == piece.npos) {
|
||||
if (!piece.empty()) {
|
||||
// no difference between <key> and <key>=
|
||||
result.emplace_back(std::move(piece), "");
|
||||
}
|
||||
} else {
|
||||
result.emplace_back(piece.substr(0, equal_sign), piece.substr(equal_sign + 1));
|
||||
}
|
||||
if (found == cmdline.npos) break;
|
||||
base = found + 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
std::string cmdline;
|
||||
std::string cmdline_key("androidboot." + key);
|
||||
if (android::base::ReadFileToString("/proc/cmdline", &cmdline)) {
|
||||
for (const auto& entry : android::base::Split(android::base::Trim(cmdline), " ")) {
|
||||
std::vector<std::string> pieces = android::base::Split(entry, "=");
|
||||
if (pieces.size() == 2) {
|
||||
if (pieces[0] == cmdline_key) {
|
||||
*out_val = pieces[1];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
const std::string cmdline_key("androidboot." + android_key);
|
||||
for (const auto& [key, value] : fs_mgr_parse_boot_config(cmdline)) {
|
||||
if (key == cmdline_key) {
|
||||
*out_val = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
*out_val = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Tries to get the given boot config value from kernel cmdline.
|
||||
// Returns true if successfully found, false otherwise.
|
||||
bool fs_mgr_get_boot_config_from_kernel_cmdline(const std::string& key, std::string* out_val) {
|
||||
std::string cmdline;
|
||||
if (!android::base::ReadFileToString("/proc/cmdline", &cmdline)) return false;
|
||||
return fs_mgr_get_boot_config_from_kernel(cmdline, key, out_val);
|
||||
}
|
||||
|
||||
// Tries to get the boot config value in properties, kernel cmdline and
|
||||
// device tree (in that order). returns 'true' if successfully found, 'false'
|
||||
// otherwise
|
||||
|
|
|
@ -19,7 +19,13 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> fs_mgr_parse_boot_config(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);
|
||||
bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val);
|
||||
|
||||
|
|
36
fs_mgr/tests/Android.bp
Normal file
36
fs_mgr/tests/Android.bp
Normal file
|
@ -0,0 +1,36 @@
|
|||
// Copyright (C) 2018 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.
|
||||
|
||||
cc_test {
|
||||
name: "fs_mgr_unit_test",
|
||||
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"liblog",
|
||||
],
|
||||
static_libs: [
|
||||
"libfs_mgr",
|
||||
"libfstab",
|
||||
],
|
||||
|
||||
srcs: [
|
||||
"fs_mgr_test.cpp",
|
||||
],
|
||||
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
"-Werror",
|
||||
],
|
||||
}
|
131
fs_mgr/tests/fs_mgr_test.cpp
Normal file
131
fs_mgr/tests/fs_mgr_test.cpp
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright (C) 2018 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 <algorithm>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <android-base/strings.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "../fs_mgr_priv_boot_config.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const std::string cmdline =
|
||||
"rcupdate.rcu_expedited=1 rootwait ro "
|
||||
"init=/init androidboot.bootdevice=1d84000.ufshc "
|
||||
"androidboot.baseband=sdy androidboot.keymaster=1 skip_initramfs "
|
||||
"androidboot.serialno=BLAHBLAHBLAH androidboot.slot_suffix=_a "
|
||||
"androidboot.hardware.platform=sdw813 androidboot.hardware=foo "
|
||||
"androidboot.revision=EVT1.0 androidboot.bootloader=burp-0.1-7521 "
|
||||
"androidboot.hardware.sku=mary androidboot.hardware.radio.subtype=0 "
|
||||
"androidboot.dtbo_idx=2 androidboot.mode=normal "
|
||||
"androidboot.hardware.ddr=1GB,combuchi,LPDDR4X "
|
||||
"androidboot.ddr_info=combuchiandroidboot.ddr_size=2GB "
|
||||
"androidboot.hardware.ufs=2GB,combushi "
|
||||
"androidboot.boottime=0BLE:58,1BLL:22,1BLE:571,2BLL:105,ODT:0,AVB:123 "
|
||||
"androidboot.ramdump=disabled "
|
||||
"dm=\"1 vroot none ro 1,0 10416 verity 1 624684 fec_start 624684\" "
|
||||
"root=/dev/dm-0 "
|
||||
"androidboot.vbmeta.device=PARTUUID=aa08f1a4-c7c9-402e-9a66-9707cafa9ceb "
|
||||
"androidboot.vbmeta.avb_version=\"1.1\" "
|
||||
"androidboot.vbmeta.device_state=unlocked "
|
||||
"androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=5248 "
|
||||
"androidboot.vbmeta.digest="
|
||||
"ac13147e959861c20f2a6da97d25fe79e60e902c022a371c5c039d31e7c68860 "
|
||||
"androidboot.vbmeta.invalidate_on_error=yes "
|
||||
"androidboot.veritymode=enforcing androidboot.verifiedbootstate=orange "
|
||||
"androidboot.space=\"sha256 5248 androidboot.nospace=nope\" "
|
||||
"printk.devkmsg=on msm_rtb.filter=0x237 ehci-hcd.park=3 "
|
||||
"\"string =\"\"string '\" "
|
||||
"service_locator.enable=1 firmware_class.path=/vendor/firmware "
|
||||
"cgroup.memory=nokmem lpm_levels.sleep_disabled=1 "
|
||||
"buildvariant=userdebug console=null "
|
||||
"terminator=\"truncated";
|
||||
|
||||
const std::vector<std::pair<std::string, std::string>> result_space = {
|
||||
{"rcupdate.rcu_expedited", "1"},
|
||||
{"rootwait", ""},
|
||||
{"ro", ""},
|
||||
{"init", "/init"},
|
||||
{"androidboot.bootdevice", "1d84000.ufshc"},
|
||||
{"androidboot.baseband", "sdy"},
|
||||
{"androidboot.keymaster", "1"},
|
||||
{"skip_initramfs", ""},
|
||||
{"androidboot.serialno", "BLAHBLAHBLAH"},
|
||||
{"androidboot.slot_suffix", "_a"},
|
||||
{"androidboot.hardware.platform", "sdw813"},
|
||||
{"androidboot.hardware", "foo"},
|
||||
{"androidboot.revision", "EVT1.0"},
|
||||
{"androidboot.bootloader", "burp-0.1-7521"},
|
||||
{"androidboot.hardware.sku", "mary"},
|
||||
{"androidboot.hardware.radio.subtype", "0"},
|
||||
{"androidboot.dtbo_idx", "2"},
|
||||
{"androidboot.mode", "normal"},
|
||||
{"androidboot.hardware.ddr", "1GB,combuchi,LPDDR4X"},
|
||||
{"androidboot.ddr_info", "combuchiandroidboot.ddr_size=2GB"},
|
||||
{"androidboot.hardware.ufs", "2GB,combushi"},
|
||||
{"androidboot.boottime", "0BLE:58,1BLL:22,1BLE:571,2BLL:105,ODT:0,AVB:123"},
|
||||
{"androidboot.ramdump", "disabled"},
|
||||
{"dm", "1 vroot none ro 1,0 10416 verity 1 624684 fec_start 624684"},
|
||||
{"root", "/dev/dm-0"},
|
||||
{"androidboot.vbmeta.device", "PARTUUID=aa08f1a4-c7c9-402e-9a66-9707cafa9ceb"},
|
||||
{"androidboot.vbmeta.avb_version", "1.1"},
|
||||
{"androidboot.vbmeta.device_state", "unlocked"},
|
||||
{"androidboot.vbmeta.hash_alg", "sha256"},
|
||||
{"androidboot.vbmeta.size", "5248"},
|
||||
{"androidboot.vbmeta.digest",
|
||||
"ac13147e959861c20f2a6da97d25fe79e60e902c022a371c5c039d31e7c68860"},
|
||||
{"androidboot.vbmeta.invalidate_on_error", "yes"},
|
||||
{"androidboot.veritymode", "enforcing"},
|
||||
{"androidboot.verifiedbootstate", "orange"},
|
||||
{"androidboot.space", "sha256 5248 androidboot.nospace=nope"},
|
||||
{"printk.devkmsg", "on"},
|
||||
{"msm_rtb.filter", "0x237"},
|
||||
{"ehci-hcd.park", "3"},
|
||||
{"string ", "string '"},
|
||||
{"service_locator.enable", "1"},
|
||||
{"firmware_class.path", "/vendor/firmware"},
|
||||
{"cgroup.memory", "nokmem"},
|
||||
{"lpm_levels.sleep_disabled", "1"},
|
||||
{"buildvariant", "userdebug"},
|
||||
{"console", "null"},
|
||||
{"terminator", "truncated"},
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(fs_mgr, fs_mgr_parse_boot_config) {
|
||||
EXPECT_EQ(result_space, fs_mgr_parse_boot_config(cmdline));
|
||||
}
|
||||
|
||||
TEST(fs_mgr, fs_mgr_get_boot_config_from_kernel_cmdline) {
|
||||
std::string content;
|
||||
for (const auto& entry : result_space) {
|
||||
static constexpr char androidboot[] = "androidboot.";
|
||||
if (!android::base::StartsWith(entry.first, androidboot)) continue;
|
||||
auto key = entry.first.substr(strlen(androidboot));
|
||||
EXPECT_TRUE(fs_mgr_get_boot_config_from_kernel(cmdline, key, &content)) << " for " << key;
|
||||
EXPECT_EQ(entry.second, content);
|
||||
}
|
||||
EXPECT_FALSE(fs_mgr_get_boot_config_from_kernel(cmdline, "vbmeta.avb_versio", &content));
|
||||
EXPECT_TRUE(content.empty()) << content;
|
||||
EXPECT_FALSE(fs_mgr_get_boot_config_from_kernel(cmdline, "nospace", &content));
|
||||
EXPECT_TRUE(content.empty()) << content;
|
||||
}
|
Loading…
Reference in a new issue