summaryrefslogtreecommitdiff
path: root/partition_tools
diff options
context:
space:
mode:
authorYifan Hong <elsk@google.com>2019-03-15 14:19:08 -0700
committerYifan Hong <elsk@google.com>2019-03-20 16:28:06 -0700
commitb84fb57317c99f56e77dd21d80d230a3d5aefe9b (patch)
treed762d8b9e8ae566079eca9fc71e9ab41014bc21c /partition_tools
parentb48d79fa91f888fbd3fd63465f9d28b682cd74c3 (diff)
downloadextras-b84fb57317c99f56e77dd21d80d230a3d5aefe9b.tar.gz
Make lpdump possible without root.
Test: adb unroot && adb shell lpdump Bug: 126233777 Change-Id: Ie559072fe53fee43d7c4a9e8f97a89d979e5b9bc
Diffstat (limited to 'partition_tools')
-rw-r--r--partition_tools/Android.bp57
-rw-r--r--partition_tools/aidl/Android.bp30
-rw-r--r--partition_tools/aidl/android/lpdump/ILpdump.aidl4
-rw-r--r--partition_tools/lpdump.cc39
-rw-r--r--partition_tools/lpdump_host.cc21
-rw-r--r--partition_tools/lpdump_target.cc84
-rw-r--r--partition_tools/lpdumpd.cc75
-rw-r--r--partition_tools/lpdumpd.rc35
8 files changed, 336 insertions, 9 deletions
diff --git a/partition_tools/Android.bp b/partition_tools/Android.bp
index 4a1bb272..2b9e37fd 100644
--- a/partition_tools/Android.bp
+++ b/partition_tools/Android.bp
@@ -27,8 +27,8 @@ cc_defaults {
},
}
-cc_binary {
- name: "lpdump",
+cc_library_shared {
+ name: "liblpdump",
defaults: ["lp_defaults"],
host_supported: true,
shared_libs: [
@@ -42,6 +42,7 @@ cc_binary {
target: {
android: {
shared_libs: [
+ "libcutils",
"libfs_mgr",
],
},
@@ -49,6 +50,40 @@ cc_binary {
}
cc_binary {
+ name: "lpdump",
+ defaults: ["lp_defaults"],
+ host_supported: true,
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "liblp",
+ ],
+ target: {
+ android: {
+ srcs: [
+ "lpdump_target.cc",
+ ],
+ shared_libs: [
+ "liblpdump_interface-cpp",
+ "libbinder",
+ "libutils",
+ ],
+ required: [
+ "lpdumpd",
+ ],
+ },
+ host: {
+ srcs: [
+ "lpdump_host.cc",
+ ],
+ shared_libs: [
+ "liblpdump",
+ ],
+ },
+ },
+}
+
+cc_binary {
name: "lpmake",
defaults: ["lp_defaults"],
host_supported: true,
@@ -75,3 +110,21 @@ cc_binary {
"lpflash.cc",
],
}
+
+cc_binary {
+ name: "lpdumpd",
+ defaults: ["lp_defaults"],
+ init_rc: ["lpdumpd.rc"],
+ shared_libs: [
+ "libbase",
+ "libbinder",
+ "liblog",
+ "liblp",
+ "liblpdump",
+ "liblpdump_interface-cpp",
+ "libutils",
+ ],
+ srcs: [
+ "lpdumpd.cc",
+ ],
+}
diff --git a/partition_tools/aidl/Android.bp b/partition_tools/aidl/Android.bp
new file mode 100644
index 00000000..60be072f
--- /dev/null
+++ b/partition_tools/aidl/Android.bp
@@ -0,0 +1,30 @@
+//
+// Copyright (C) 2019 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.
+//
+
+aidl_interface {
+ name: "liblpdump_interface",
+ srcs: [
+ "android/lpdump/ILpdump.aidl",
+ ],
+ backend: {
+ cpp: {
+ gen_log: true,
+ },
+ ndk: {
+ enabled: false,
+ },
+ },
+}
diff --git a/partition_tools/aidl/android/lpdump/ILpdump.aidl b/partition_tools/aidl/android/lpdump/ILpdump.aidl
new file mode 100644
index 00000000..e1343608
--- /dev/null
+++ b/partition_tools/aidl/android/lpdump/ILpdump.aidl
@@ -0,0 +1,4 @@
+package android.lpdump;
+interface ILpdump {
+ @utf8InCpp String run(in @utf8InCpp String[] args);
+}
diff --git a/partition_tools/lpdump.cc b/partition_tools/lpdump.cc
index 365b86cc..e3c6d393 100644
--- a/partition_tools/lpdump.cc
+++ b/partition_tools/lpdump.cc
@@ -28,6 +28,7 @@
#include <android-base/strings.h>
#include <android-base/parseint.h>
#ifdef __ANDROID__
+#include <cutils/android_get_control_file.h>
#include <fs_mgr.h>
#endif
#include <liblp/liblp.h>
@@ -77,14 +78,35 @@ static bool IsBlockDevice(const char* file) {
return !stat(file, &s) && S_ISBLK(s.st_mode);
}
+// Reimplementation of fs_mgr_get_slot_suffix() without reading
+// kernel commandline.
+static std::string GetSlotSuffix() {
+ return base::GetProperty("ro.boot.slot_suffix", "");
+}
+
+// Reimplementation of fs_mgr_get_super_partition_name() without reading
+// kernel commandline. Always return the super partition at current slot.
+static std::string GetSuperPartionName() {
+ std::string super_partition = base::GetProperty("ro.boot.super_partition", "");
+ if (super_partition.empty()) {
+ return LP_METADATA_DEFAULT_PARTITION_NAME;
+ }
+ return super_partition + GetSlotSuffix();
+}
+
class FileOrBlockDeviceOpener final : public PartitionOpener {
public:
android::base::unique_fd Open(const std::string& path, int flags) const override {
// Try a local file first.
- android::base::unique_fd fd(open(path.c_str(), flags));
- if (fd >= 0) {
- return fd;
- }
+ android::base::unique_fd fd;
+
+#ifdef __ANDROID__
+ fd.reset(android_get_control_file(path.c_str()));
+ if (fd >= 0) return fd;
+#endif
+ fd.reset(open(path.c_str(), flags));
+ if (fd >= 0) return fd;
+
return PartitionOpener::Open(path, flags);
}
};
@@ -96,6 +118,9 @@ int LpdumpMain(int argc, char* argv[], std::ostream& cout, std::ostream& cerr) {
{ nullptr, 0, nullptr, 0 },
};
+ // Allow this function to be invoked by lpdumpd multiple times.
+ optind = 1;
+
int rv;
int index;
uint32_t slot = 0;
@@ -122,8 +147,8 @@ int LpdumpMain(int argc, char* argv[], std::ostream& cout, std::ostream& cerr) {
}
} else {
#ifdef __ANDROID__
- auto slot_number = SlotNumberForSlotSuffix(fs_mgr_get_slot_suffix());
- pt = ReadMetadata(fs_mgr_get_super_partition_name(), slot_number);
+ auto slot_number = SlotNumberForSlotSuffix(GetSlotSuffix());
+ pt = ReadMetadata(GetSuperPartionName(), slot_number);
#else
return usage(argc, argv, cerr);
#endif
@@ -190,6 +215,6 @@ int LpdumpMain(int argc, char* argv[], std::ostream& cout, std::ostream& cerr) {
return EX_OK;
}
-int main(int argc, char* argv[]) {
+int LpdumpMain(int argc, char* argv[]) {
return LpdumpMain(argc, argv, std::cout, std::cerr);
}
diff --git a/partition_tools/lpdump_host.cc b/partition_tools/lpdump_host.cc
new file mode 100644
index 00000000..7011a234
--- /dev/null
+++ b/partition_tools/lpdump_host.cc
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+int LpdumpMain(int argc, char* argv[]);
+
+int main(int argc, char* argv[]) {
+ return LpdumpMain(argc, argv);
+}
diff --git a/partition_tools/lpdump_target.cc b/partition_tools/lpdump_target.cc
new file mode 100644
index 00000000..e777602a
--- /dev/null
+++ b/partition_tools/lpdump_target.cc
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2019 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 <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android/lpdump/ILpdump.h>
+#include <binder/IServiceManager.h>
+#include <iostream>
+#include <string>
+#include <vector>
+
+using namespace android;
+using namespace std::chrono_literals;
+using ::android::lpdump::ILpdump;
+
+int Run(ILpdump* service, const std::vector<std::string>& args) {
+ std::string output;
+ binder::Status status = service->run(args, &output);
+ if (status.isOk()) {
+ std::cout << output;
+ return 0;
+ }
+ std::cerr << status.exceptionMessage();
+ if (status.serviceSpecificErrorCode() != 0) {
+ return status.serviceSpecificErrorCode();
+ }
+ return -status.exceptionCode();
+}
+
+std::vector<std::string> GetArgVector(int argc, char* argv[]) {
+ std::vector<std::string> args;
+ args.reserve(argc);
+ for (int i = 0; i < argc; ++i) {
+ args.push_back(argv[i]);
+ }
+ return args;
+}
+
+class LpdumpService {
+public:
+ LpdumpService() {
+ base::SetProperty("sys.lpdumpd", "start");
+ status_t status = getService(String16("lpdump_service"), &service_);
+ int wait_counter = 0;
+ while (status != OK && wait_counter++ < 3) {
+ sleep(1);
+ status = getService(String16("lpdump"), &service_);
+ }
+ if (status != OK || service_ == nullptr) {
+ std::cerr << "Cannot get lpdump service: " << strerror(-status) << std::endl;
+ LOG(ERROR) << "Cannot get lpdump service: " << strerror(-status);
+ }
+ }
+ ~LpdumpService() {
+ base::SetProperty("sys.lpdumpd", "stop");
+ }
+ sp<ILpdump> get() { return service_; }
+private:
+ sp<ILpdump> service_;
+};
+
+int main(int argc, char* argv[]) {
+ LpdumpService wrapper;
+ sp<ILpdump> service = wrapper.get();
+ if (service == nullptr) {
+ return 1;
+ }
+ int ret = Run(service.get(), GetArgVector(argc, argv));
+ base::SetProperty("sys.lpdumpd", "stop");
+ return ret;
+}
diff --git a/partition_tools/lpdumpd.cc b/partition_tools/lpdumpd.cc
new file mode 100644
index 00000000..83ec60ed
--- /dev/null
+++ b/partition_tools/lpdumpd.cc
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2019 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 <limits>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <android-base/logging.h>
+#include <android-base/strings.h>
+#include <android/lpdump/BnLpdump.h>
+#include <android/lpdump/ILpdump.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+int LpdumpMain(int argc, char* argv[], std::ostream&, std::ostream&);
+
+namespace android {
+namespace lpdump {
+
+using binder::Status;
+
+class Lpdump : public BnLpdump {
+ public:
+ Lpdump() = default;
+ virtual ~Lpdump() = default;
+
+ Status run(const std::vector<std::string>& args, std::string* aidl_return) override {
+ if (args.size() > std::numeric_limits<int>::max()) {
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+ }
+ std::vector<std::string> m_args = args;
+ char* argv[m_args.size()];
+ for (size_t i = 0; i < m_args.size(); ++i) {
+ argv[i] = m_args[i].data();
+ }
+ LOG(DEBUG) << "Dumping with args: " << base::Join(args, " ");
+ std::stringstream output;
+ int ret = LpdumpMain((int)m_args.size(), argv, output, output);
+ if (ret == 0) {
+ *aidl_return = output.str();
+ return Status::ok();
+ } else {
+ return Status::fromServiceSpecificError(ret, output.str().c_str());
+ }
+ }
+};
+
+} // namespace lpdump
+} // namespace android
+
+int main(int, char**) {
+ using namespace android;
+
+ sp<lpdump::Lpdump> service = new lpdump::Lpdump();
+ defaultServiceManager()->addService(String16("lpdump_service"), service);
+ LOG(VERBOSE) << "lpdumpd starting";
+ ProcessState::self()->startThreadPool();
+ IPCThreadState::self()->joinThreadPool();
+ return 0;
+}
diff --git a/partition_tools/lpdumpd.rc b/partition_tools/lpdumpd.rc
new file mode 100644
index 00000000..46ef5b35
--- /dev/null
+++ b/partition_tools/lpdumpd.rc
@@ -0,0 +1,35 @@
+#
+# Copyright (C) 2019 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.
+#
+
+service lpdumpd /system/bin/lpdumpd
+ # TODO(b/129011369): make this killable by lmkd
+ oneshot
+ disabled
+ user system
+ group system
+ # On Launch devices, assume "super". On virtual devices, ${ro.boot.super_partition}
+ # might be something else.
+ file /dev/block/by-name/${ro.boot.super_partition:-super} r
+ # On retrofit devices, ${ro.boot.super_partition} is slot-suffixed.
+ # Use NO_SUCH_DEVICE_NO_SUCH_SUFFIX as default values so that host_init_verifier does
+ # not complain about missing sysprops
+ file /dev/block/by-name/${ro.boot.super_partition:-NO_SUCH_DEVICE}${ro.boot.slot_suffix:-_NO_SUCH_SUFFIX} r
+
+on property:sys.lpdumpd=start
+ start lpdumpd
+
+on property:sys.lpdumpd=stop
+ stop lpdumpd