summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2018-06-11 14:29:24 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-06-11 14:29:24 +0000
commit7da6b579c1e9fdd8b8913525159b678ed6e14df1 (patch)
tree0b4fa2805ce324bbd44302b835486f2a4063ed2a
parent3ee8926f5dc70f5740ec235f2a0cf3abd29ac543 (diff)
parent596fac3c6dfd195a4a5bf40bdec7ffb4987383e4 (diff)
downloadsystem_core-7da6b579c1e9fdd8b8913525159b678ed6e14df1.tar.gz
system_core-7da6b579c1e9fdd8b8913525159b678ed6e14df1.tar.bz2
system_core-7da6b579c1e9fdd8b8913525159b678ed6e14df1.zip
Merge "fs_mgr: fs_mgr_get_boot_config_from_kernel_cmdline deal with quote"
-rw-r--r--fs_mgr/fs_mgr_boot_config.cpp67
-rw-r--r--fs_mgr/fs_mgr_priv_boot_config.h6
-rw-r--r--fs_mgr/tests/Android.bp36
-rw-r--r--fs_mgr/tests/fs_mgr_test.cpp131
4 files changed, 226 insertions, 14 deletions
diff --git a/fs_mgr/fs_mgr_boot_config.cpp b/fs_mgr/fs_mgr_boot_config.cpp
index 9c5d3f3bb..b02fe991c 100644
--- a/fs_mgr/fs_mgr_boot_config.cpp
+++ b/fs_mgr/fs_mgr_boot_config.cpp
@@ -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) {
- FS_MGR_CHECK(out_val != nullptr);
+std::vector<std::pair<std::string, std::string>> fs_mgr_parse_boot_config(const std::string& cmdline) {
+ static constexpr char quote = '"';
- 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;
- }
+ 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);
+
+ 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
diff --git a/fs_mgr/fs_mgr_priv_boot_config.h b/fs_mgr/fs_mgr_priv_boot_config.h
index d98dc02c1..417fb380b 100644
--- a/fs_mgr/fs_mgr_priv_boot_config.h
+++ b/fs_mgr/fs_mgr_priv_boot_config.h
@@ -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);
diff --git a/fs_mgr/tests/Android.bp b/fs_mgr/tests/Android.bp
new file mode 100644
index 000000000..5497223e0
--- /dev/null
+++ b/fs_mgr/tests/Android.bp
@@ -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",
+ ],
+}
diff --git a/fs_mgr/tests/fs_mgr_test.cpp b/fs_mgr/tests/fs_mgr_test.cpp
new file mode 100644
index 000000000..2e76752c0
--- /dev/null
+++ b/fs_mgr/tests/fs_mgr_test.cpp
@@ -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;
+}