Merge "DO NOT MERGE - Merge qt-dev-plus-aosp-without-vendor (5699924) into stage-aosp-master" into stage-aosp-master
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 39abc4a..c436be3 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -389,6 +389,8 @@
" set_active SLOT Set the active slot.\n"
" oem [COMMAND...] Execute OEM-specific command.\n"
" gsi wipe|disable Wipe or disable a GSI installation (fastbootd only).\n"
+ " wipe-super [SUPER_EMPTY] Wipe the super partition. This will reset it to\n"
+ " contain an empty set of default dynamic partitions.\n"
"\n"
"boot image:\n"
" boot KERNEL [RAMDISK [SECOND]]\n"
@@ -1582,6 +1584,76 @@
return false;
}
+static bool wipe_super(const android::fs_mgr::LpMetadata& metadata, const std::string& slot,
+ std::string* message) {
+ auto super_device = GetMetadataSuperBlockDevice(metadata);
+ auto block_size = metadata.geometry.logical_block_size;
+ auto super_bdev_name = android::fs_mgr::GetBlockDevicePartitionName(*super_device);
+
+ if (super_bdev_name != "super") {
+ // retrofit devices do not allow flashing to the retrofit partitions,
+ // so enable it if we can.
+ fb->RawCommand("oem allow-flash-super");
+ }
+
+ // Note: do not use die() in here, since we want TemporaryDir's destructor
+ // to be called.
+ TemporaryDir temp_dir;
+
+ bool ok;
+ if (metadata.block_devices.size() > 1) {
+ ok = WriteSplitImageFiles(temp_dir.path, metadata, block_size, {}, true);
+ } else {
+ auto image_path = temp_dir.path + "/"s + super_bdev_name + ".img";
+ ok = WriteToImageFile(image_path, metadata, block_size, {}, true);
+ }
+ if (!ok) {
+ *message = "Could not generate a flashable super image file";
+ return false;
+ }
+
+ for (const auto& block_device : metadata.block_devices) {
+ auto partition = android::fs_mgr::GetBlockDevicePartitionName(block_device);
+ bool force_slot = !!(block_device.flags & LP_BLOCK_DEVICE_SLOT_SUFFIXED);
+
+ std::string image_name;
+ if (metadata.block_devices.size() > 1) {
+ image_name = "super_" + partition + ".img";
+ } else {
+ image_name = partition + ".img";
+ }
+
+ auto image_path = temp_dir.path + "/"s + image_name;
+ auto flash = [&](const std::string& partition_name) {
+ do_flash(partition_name.c_str(), image_path.c_str());
+ };
+ do_for_partitions(partition, slot, flash, force_slot);
+
+ unlink(image_path.c_str());
+ }
+ return true;
+}
+
+static void do_wipe_super(const std::string& image, const std::string& slot_override) {
+ if (access(image.c_str(), R_OK) != 0) {
+ die("Could not read image: %s", image.c_str());
+ }
+ auto metadata = android::fs_mgr::ReadFromImageFile(image);
+ if (!metadata) {
+ die("Could not parse image: %s", image.c_str());
+ }
+
+ auto slot = slot_override;
+ if (slot.empty()) {
+ slot = get_current_slot();
+ }
+
+ std::string message;
+ if (!wipe_super(*metadata.get(), slot, &message)) {
+ die(message);
+ }
+}
+
int FastBootTool::Main(int argc, char* argv[]) {
bool wants_wipe = false;
bool wants_reboot = false;
@@ -1958,6 +2030,14 @@
} else {
syntax_error("expected 'wipe' or 'disable'");
}
+ } else if (command == "wipe-super") {
+ std::string image;
+ if (args.empty()) {
+ image = find_item_given_name("super_empty.img");
+ } else {
+ image = next_arg(&args);
+ }
+ do_wipe_super(image, slot_override);
} else {
syntax_error("unknown command %s", command.c_str());
}
diff --git a/fastboot/util.cpp b/fastboot/util.cpp
index d02b37f..900d6ea 100644
--- a/fastboot/util.cpp
+++ b/fastboot/util.cpp
@@ -53,6 +53,10 @@
exit(EXIT_FAILURE);
}
+void die(const std::string& str) {
+ die("%s", str.c_str());
+}
+
void set_verbose() {
g_verbose = true;
}
diff --git a/fastboot/util.h b/fastboot/util.h
index 2535414..c719df2 100644
--- a/fastboot/util.h
+++ b/fastboot/util.h
@@ -15,4 +15,7 @@
// use the same attribute for compile-time format string checking.
void die(const char* fmt, ...) __attribute__((__noreturn__))
__attribute__((__format__(__printf__, 1, 2)));
+
void verbose(const char* fmt, ...) __attribute__((__format__(__printf__, 1, 2)));
+
+void die(const std::string& str) __attribute__((__noreturn__));
diff --git a/init/host_init_verifier.cpp b/init/host_init_verifier.cpp
index 9323aa0..8aa3509 100644
--- a/init/host_init_verifier.cpp
+++ b/init/host_init_verifier.cpp
@@ -129,6 +129,23 @@
return nullptr;
}
+static std::optional<std::set<std::string>> ReadKnownInterfaces(
+ const std::string& known_interfaces_file) {
+ if (known_interfaces_file.empty()) {
+ LOG(WARNING) << "Missing a known interfaces file.";
+ return {};
+ }
+
+ std::string known_interfaces;
+ if (!ReadFileToString(known_interfaces_file, &known_interfaces)) {
+ LOG(ERROR) << "Failed to read known interfaces file '" << known_interfaces_file << "'";
+ return {};
+ }
+
+ auto interfaces = Split(known_interfaces, " ");
+ return std::set<std::string>(interfaces.begin(), interfaces.end());
+}
+
namespace android {
namespace init {
@@ -139,11 +156,12 @@
#include "generated_stub_builtin_function_map.h"
void PrintUsage() {
- std::cout << "usage: host_init_verifier [-p FILE] <init rc file>\n"
+ std::cout << "usage: host_init_verifier [-p FILE] -k FILE <init rc file>\n"
"\n"
"Tests an init script for correctness\n"
"\n"
"-p FILE\tSearch this passwd file for users and groups\n"
+ "-k FILE\tUse this file as a space-separated list of known interfaces\n"
<< std::endl;
}
@@ -151,13 +169,15 @@
android::base::InitLogging(argv, &android::base::StdioLogger);
android::base::SetMinimumLogSeverity(android::base::ERROR);
+ std::string known_interfaces_file;
+
while (true) {
static const struct option long_options[] = {
{"help", no_argument, nullptr, 'h'},
{nullptr, 0, nullptr, 0},
};
- int arg = getopt_long(argc, argv, "p:", long_options, nullptr);
+ int arg = getopt_long(argc, argv, "p:k:", long_options, nullptr);
if (arg == -1) {
break;
@@ -170,6 +190,9 @@
case 'p':
passwd_files.emplace_back(optarg);
break;
+ case 'k':
+ known_interfaces_file = optarg;
+ break;
default:
std::cerr << "getprop: getopt returned invalid result: " << arg << std::endl;
return EXIT_FAILURE;
@@ -189,7 +212,9 @@
ActionManager& am = ActionManager::GetInstance();
ServiceList& sl = ServiceList::GetInstance();
Parser parser;
- parser.AddSectionParser("service", std::make_unique<ServiceParser>(&sl, nullptr));
+ parser.AddSectionParser(
+ "service", std::make_unique<ServiceParser>(&sl, nullptr,
+ ReadKnownInterfaces(known_interfaces_file)));
parser.AddSectionParser("on", std::make_unique<ActionParser>(&am, nullptr));
parser.AddSectionParser("import", std::make_unique<HostImportParser>());
diff --git a/init/init.cpp b/init/init.cpp
index b6911e5..675f3e5 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -113,7 +113,8 @@
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {
Parser parser;
- parser.AddSectionParser("service", std::make_unique<ServiceParser>(&service_list, subcontexts));
+ parser.AddSectionParser(
+ "service", std::make_unique<ServiceParser>(&service_list, subcontexts, std::nullopt));
parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager, subcontexts));
parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));
@@ -124,7 +125,8 @@
Parser CreateServiceOnlyParser(ServiceList& service_list) {
Parser parser;
- parser.AddSectionParser("service", std::make_unique<ServiceParser>(&service_list, subcontexts));
+ parser.AddSectionParser(
+ "service", std::make_unique<ServiceParser>(&service_list, subcontexts, std::nullopt));
return parser;
}
diff --git a/init/init_test.cpp b/init/init_test.cpp
index 1bcc5ef..a09db18 100644
--- a/init/init_test.cpp
+++ b/init/init_test.cpp
@@ -44,7 +44,8 @@
Action::set_function_map(&test_function_map);
Parser parser;
- parser.AddSectionParser("service", std::make_unique<ServiceParser>(service_list, nullptr));
+ parser.AddSectionParser("service",
+ std::make_unique<ServiceParser>(service_list, nullptr, std::nullopt));
parser.AddSectionParser("on", std::make_unique<ActionParser>(&am, nullptr));
parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));
diff --git a/init/service_parser.cpp b/init/service_parser.cpp
index 33ed050..ba35104 100644
--- a/init/service_parser.cpp
+++ b/init/service_parser.cpp
@@ -152,6 +152,12 @@
return Error() << "Interface name must not be a value name '" << interface_name << "'";
}
+ if (known_interfaces_ && known_interfaces_->count(interface_name) == 0) {
+ return Error() << "Interface is not in the known set of hidl_interfaces: '"
+ << interface_name << "'. Please ensure the interface is built "
+ << "by a hidl_interface target.";
+ }
+
const std::string fullname = interface_name + "/" + instance_name;
for (const auto& svc : *service_list_) {
diff --git a/init/service_parser.h b/init/service_parser.h
index 0a5b291..5a16768 100644
--- a/init/service_parser.h
+++ b/init/service_parser.h
@@ -28,8 +28,12 @@
class ServiceParser : public SectionParser {
public:
- ServiceParser(ServiceList* service_list, std::vector<Subcontext>* subcontexts)
- : service_list_(service_list), subcontexts_(subcontexts), service_(nullptr) {}
+ ServiceParser(ServiceList* service_list, std::vector<Subcontext>* subcontexts,
+ const std::optional<std::set<std::string>>& known_interfaces)
+ : service_list_(service_list),
+ subcontexts_(subcontexts),
+ known_interfaces_(known_interfaces),
+ service_(nullptr) {}
Result<void> ParseSection(std::vector<std::string>&& args, const std::string& filename,
int line) override;
Result<void> ParseLineSection(std::vector<std::string>&& args, int line) override;
@@ -81,6 +85,7 @@
ServiceList* service_list_;
std::vector<Subcontext>* subcontexts_;
+ std::optional<std::set<std::string>> known_interfaces_;
std::unique_ptr<Service> service_;
std::string filename_;
};
diff --git a/logd/Android.bp b/logd/Android.bp
index 9b86258..b337b7c 100644
--- a/logd/Android.bp
+++ b/logd/Android.bp
@@ -39,7 +39,6 @@
"FlushCommand.cpp",
"LogBuffer.cpp",
"LogBufferElement.cpp",
- "LogBufferInterface.cpp",
"LogTimes.cpp",
"LogStatistics.cpp",
"LogWhiteBlackList.cpp",
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index 404433f..c2d5b97 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -27,7 +27,6 @@
#include <sysutils/SocketClient.h>
#include "LogBufferElement.h"
-#include "LogBufferInterface.h"
#include "LogStatistics.h"
#include "LogTags.h"
#include "LogTimes.h"
@@ -75,7 +74,7 @@
typedef std::list<LogBufferElement*> LogBufferElementCollection;
-class LogBuffer : public LogBufferInterface {
+class LogBuffer {
LogBufferElementCollection mLogElements;
pthread_rwlock_t mLogElementsLock;
@@ -108,14 +107,14 @@
LastLogTimes& mTimes;
explicit LogBuffer(LastLogTimes* times);
- ~LogBuffer() override;
+ ~LogBuffer();
void init();
bool isMonotonic() {
return monotonic;
}
- int log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid,
- const char* msg, uint16_t len) override;
+ int log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, const char* msg,
+ uint16_t len);
// lastTid is an optional context to help detect if the last previous
// valid message was from the same source so we can differentiate chatty
// filter types (identical or expired)
diff --git a/logd/LogBufferInterface.cpp b/logd/LogBufferInterface.cpp
deleted file mode 100644
index 66b3ab4..0000000
--- a/logd/LogBufferInterface.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2017 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 "LogBufferInterface.h"
-
-LogBufferInterface::LogBufferInterface() {
-}
-LogBufferInterface::~LogBufferInterface() {}
\ No newline at end of file
diff --git a/logd/LogBufferInterface.h b/logd/LogBufferInterface.h
deleted file mode 100644
index 2bb08f9..0000000
--- a/logd/LogBufferInterface.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012-2014 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.
- */
-
-#ifndef _LOGD_LOG_BUFFER_INTERFACE_H__
-#define _LOGD_LOG_BUFFER_INTERFACE_H__
-
-#include <sys/types.h>
-
-#include <android-base/macros.h>
-#include <log/log_id.h>
-#include <log/log_time.h>
-
-// Abstract interface that handles log when log available.
-class LogBufferInterface {
- public:
- LogBufferInterface();
- virtual ~LogBufferInterface();
- // Handles a log entry when available in LogListener.
- // Returns the size of the handled log message.
- virtual int log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
- pid_t tid, const char* msg, uint16_t len) = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(LogBufferInterface);
-};
-
-#endif // _LOGD_LOG_BUFFER_INTERFACE_H__
diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp
index 7f78e19..443570f 100644
--- a/logd/LogListener.cpp
+++ b/logd/LogListener.cpp
@@ -30,9 +30,8 @@
#include "LogListener.h"
#include "LogUtils.h"
-LogListener::LogListener(LogBufferInterface* buf, LogReader* reader)
- : SocketListener(getLogSocket(), false), logbuf(buf), reader(reader) {
-}
+LogListener::LogListener(LogBuffer* buf, LogReader* reader)
+ : SocketListener(getLogSocket(), false), logbuf(buf), reader(reader) {}
bool LogListener::onDataAvailable(SocketClient* cli) {
static bool name_set;
@@ -107,13 +106,10 @@
// NB: hdr.msg_flags & MSG_TRUNC is not tested, silently passing a
// truncated message to the logs.
- if (logbuf != nullptr) {
- int res = logbuf->log(
- logId, header->realtime, cred->uid, cred->pid, header->tid, msg,
- ((size_t)n <= UINT16_MAX) ? (uint16_t)n : UINT16_MAX);
- if (res > 0 && reader != nullptr) {
- reader->notifyNewLog(static_cast<log_mask_t>(1 << logId));
- }
+ int res = logbuf->log(logId, header->realtime, cred->uid, cred->pid, header->tid, msg,
+ ((size_t)n <= UINT16_MAX) ? (uint16_t)n : UINT16_MAX);
+ if (res > 0) {
+ reader->notifyNewLog(static_cast<log_mask_t>(1 << logId));
}
return true;
diff --git a/logd/LogListener.h b/logd/LogListener.h
index e16c5fb..8fe3da4 100644
--- a/logd/LogListener.h
+++ b/logd/LogListener.h
@@ -21,11 +21,11 @@
#include "LogReader.h"
class LogListener : public SocketListener {
- LogBufferInterface* logbuf;
+ LogBuffer* logbuf;
LogReader* reader;
public:
- LogListener(LogBufferInterface* buf, LogReader* reader /* nullable */);
+ LogListener(LogBuffer* buf, LogReader* reader);
protected:
virtual bool onDataAvailable(SocketClient* cli);