Merge "logd: fix memory leak due to slow reader"
diff --git a/adb/adb_trace.cpp b/adb/adb_trace.cpp
index a8ec5fb..a024a89 100644
--- a/adb/adb_trace.cpp
+++ b/adb/adb_trace.cpp
@@ -41,6 +41,11 @@
                const char* tag, const char* file, unsigned int line,
                const char* message) {
     android::base::StderrLogger(id, severity, tag, file, line, message);
+#if defined(_WIN32)
+    // stderr can be buffered on Windows (and setvbuf doesn't seem to work), so explicitly flush.
+    fflush(stderr);
+#endif
+
 #if !ADB_HOST
     // Only print logs of INFO or higher to logcat, so that `adb logcat` with adbd tracing on
     // doesn't result in exponential logging.
diff --git a/adb/client/usb_libusb.cpp b/adb/client/usb_libusb.cpp
index 10b6090..f2ca63b 100644
--- a/adb/client/usb_libusb.cpp
+++ b/adb/client/usb_libusb.cpp
@@ -332,13 +332,6 @@
             return;
         }
 
-        rc = libusb_set_interface_alt_setting(handle.get(), interface_num, 0);
-        if (rc != 0) {
-            LOG(WARNING) << "failed to set interface alt setting for device '" << device_serial
-                         << "'" << libusb_error_name(rc);
-            return;
-        }
-
         for (uint8_t endpoint : {bulk_in, bulk_out}) {
             rc = libusb_clear_halt(handle.get(), endpoint);
             if (rc != 0) {
diff --git a/fastboot/usb_osx.cpp b/fastboot/usb_osx.cpp
index ed02c4a..f597f50 100644
--- a/fastboot/usb_osx.cpp
+++ b/fastboot/usb_osx.cpp
@@ -61,7 +61,7 @@
 
     UInt8 bulkIn;
     UInt8 bulkOut;
-    IOUSBInterfaceInterface190 **interface;
+    IOUSBInterfaceInterface500** interface;
     unsigned int zero_mask;
 };
 
@@ -86,13 +86,13 @@
 
 /** Try out all the interfaces and see if there's a match. Returns 0 on
  * success, -1 on failure. */
-static int try_interfaces(IOUSBDeviceInterface182 **dev, usb_handle *handle) {
+static int try_interfaces(IOUSBDeviceInterface500** dev, usb_handle* handle) {
     IOReturn kr;
     IOUSBFindInterfaceRequest request;
     io_iterator_t iterator;
     io_service_t usbInterface;
     IOCFPlugInInterface **plugInInterface;
-    IOUSBInterfaceInterface190 **interface = NULL;
+    IOUSBInterfaceInterface500** interface = NULL;
     HRESULT result;
     SInt32 score;
     UInt8 interfaceNumEndpoints;
@@ -128,10 +128,10 @@
         }
 
         // Now create the interface interface for the interface
-        result = (*plugInInterface)->QueryInterface(
-                plugInInterface,
-                CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID),
-                (LPVOID*) &interface);
+        result = (*plugInInterface)
+                         ->QueryInterface(plugInInterface,
+                                          CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID500),
+                                          (LPVOID*)&interface);
 
         // No longer need the intermediate plugin
         (*plugInInterface)->Release(plugInInterface);
@@ -270,7 +270,7 @@
 static int try_device(io_service_t device, usb_handle *handle) {
     kern_return_t kr;
     IOCFPlugInInterface **plugin = NULL;
-    IOUSBDeviceInterface182 **dev = NULL;
+    IOUSBDeviceInterface500** dev = NULL;
     SInt32 score;
     HRESULT result;
     UInt8 serialIndex;
@@ -287,8 +287,8 @@
     }
 
     // Now create the device interface.
-    result = (*plugin)->QueryInterface(plugin,
-            CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*) &dev);
+    result = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID500),
+                                       (LPVOID*)&dev);
     if ((result != 0) || (dev == NULL)) {
         ERR("Couldn't create a device interface (%08x)\n", (int) result);
         goto error;
diff --git a/fs_mgr/fs_mgr_avb.cpp b/fs_mgr/fs_mgr_avb.cpp
index 7c6093e..31affbe 100644
--- a/fs_mgr/fs_mgr_avb.cpp
+++ b/fs_mgr/fs_mgr_avb.cpp
@@ -322,17 +322,6 @@
             continue;
         }
 
-        // Ensures that hashtree descriptor is in /vbmeta or /boot or in
-        // the same partition for verity setup.
-        std::string vbmeta_partition_name(verify_data.vbmeta_images[i].partition_name);
-        if (vbmeta_partition_name != "vbmeta" &&
-            vbmeta_partition_name != "boot" &&  // for legacy device to append top-level vbmeta
-            vbmeta_partition_name != partition_name) {
-            LWARNING << "Skip vbmeta image at " << verify_data.vbmeta_images[i].partition_name
-                     << " for partition: " << partition_name.c_str();
-            continue;
-        }
-
         for (size_t j = 0; j < num_descriptors && !found; j++) {
             AvbDescriptor desc;
             if (!avb_descriptor_validate_and_byteswap(descriptors[j], &desc)) {
diff --git a/init/README.md b/init/README.md
index 4b21e32..5c07ac1 100644
--- a/init/README.md
+++ b/init/README.md
@@ -332,6 +332,13 @@
   This is particularly useful for creating a periodic service combined with the restart_period
   option described above.
 
+`updatable`
+> Mark that the service can be overridden (via the 'override' option) later in
+  the boot sequence by APEXes. When a service with updatable option is started
+  before APEXes are all activated, the execution is delayed until the activation
+  is finished. A service that is not marked as updatable cannot be overridden by
+  APEXes.
+
 `user <username>`
 > Change to 'username' before exec'ing this service.
   Currently defaults to root.  (??? probably should default to nobody)
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 8660d2a..5676f92 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -1079,6 +1079,7 @@
         }
         success &= parser.ParseConfigFile(c);
     }
+    ServiceList::GetInstance().MarkServicesUpdate();
     if (success) {
         return Success();
     } else {
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index a8b7862..1e434d2 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -560,7 +560,7 @@
         std::vector<std::string> links = device_handler_->GetBlockDeviceSymlinks(uevent);
         if (!links.empty()) {
             auto [it, inserted] = by_name_symlink_map_.emplace(uevent.partition_name, links[0]);
-            if (!inserted) {
+            if (!inserted && (links[0] != it->second)) {
                 LOG(ERROR) << "Partition '" << uevent.partition_name
                            << "' already existed in the by-name symlink map with a value of '"
                            << it->second << "', new value '" << links[0] << "' will be ignored.";
diff --git a/init/service.cpp b/init/service.cpp
index 1bda7ec..5aa3764 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -765,6 +765,11 @@
     return Success();
 }
 
+Result<Success> Service::ParseUpdatable(std::vector<std::string>&& args) {
+    updatable_ = true;
+    return Success();
+}
+
 class Service::OptionParserMap : public KeywordMap<OptionParser> {
   public:
     OptionParserMap() {}
@@ -817,6 +822,7 @@
         {"socket",      {3,     6,    &Service::ParseSocket}},
         {"timeout_period",
                         {1,     1,    &Service::ParseTimeoutPeriod}},
+        {"updatable",   {0,     0,    &Service::ParseUpdatable}},
         {"user",        {1,     1,    &Service::ParseUser}},
         {"writepid",    {1,     kMax, &Service::ParseWritepid}},
     };
@@ -834,6 +840,13 @@
 }
 
 Result<Success> Service::ExecStart() {
+    if (is_updatable() && !ServiceList::GetInstance().IsServicesUpdated()) {
+        // Don't delay the service for ExecStart() as the semantic is that
+        // the caller might depend on the side effect of the execution.
+        return Error() << "Cannot start an updatable service '" << name_
+                       << "' before configs from APEXes are all loaded";
+    }
+
     flags_ |= SVC_ONESHOT;
 
     if (auto result = Start(); !result) {
@@ -851,6 +864,13 @@
 }
 
 Result<Success> Service::Start() {
+    if (is_updatable() && !ServiceList::GetInstance().IsServicesUpdated()) {
+        ServiceList::GetInstance().DelayService(*this);
+        return Error() << "Cannot start an updatable service '" << name_
+                       << "' before configs from APEXes are all loaded. "
+                       << "Queued for execution.";
+    }
+
     bool disabled = (flags_ & (SVC_DISABLED | SVC_RESET));
     // Starting a service removes it from the disabled or reset state and
     // immediately takes it out of the restarting state if it was in there.
@@ -1280,6 +1300,32 @@
     }
 }
 
+void ServiceList::MarkServicesUpdate() {
+    services_update_finished_ = true;
+
+    // start the delayed services
+    for (const auto& name : delayed_service_names_) {
+        Service* service = FindService(name);
+        if (service == nullptr) {
+            LOG(ERROR) << "delayed service '" << name << "' could not be found.";
+            continue;
+        }
+        if (auto result = service->Start(); !result) {
+            LOG(ERROR) << result.error_string();
+        }
+    }
+    delayed_service_names_.clear();
+}
+
+void ServiceList::DelayService(const Service& service) {
+    if (services_update_finished_) {
+        LOG(ERROR) << "Cannot delay the start of service '" << service.name()
+                   << "' because all services are already updated. Ignoring.";
+        return;
+    }
+    delayed_service_names_.emplace_back(service.name());
+}
+
 Result<Success> ServiceParser::ParseSection(std::vector<std::string>&& args,
                                             const std::string& filename, int line) {
     if (args.size() < 3) {
@@ -1291,6 +1337,8 @@
         return Error() << "invalid service name '" << name << "'";
     }
 
+    filename_ = filename;
+
     Subcontext* restart_action_subcontext = nullptr;
     if (subcontexts_) {
         for (auto& subcontext : *subcontexts_) {
@@ -1326,6 +1374,11 @@
                                << "'";
             }
 
+            if (StartsWith(filename_, "/apex/") && !old_service->is_updatable()) {
+                return Error() << "cannot update a non-updatable service '" << service_->name()
+                               << "' with a config in APEX";
+            }
+
             service_list_->RemoveService(*old_service);
             old_service = nullptr;
         }
diff --git a/init/service.h b/init/service.h
index 49b09ce..56e75b0 100644
--- a/init/service.h
+++ b/init/service.h
@@ -123,6 +123,7 @@
     std::chrono::seconds restart_period() const { return restart_period_; }
     std::optional<std::chrono::seconds> timeout_period() const { return timeout_period_; }
     const std::vector<std::string>& args() const { return args_; }
+    bool is_updatable() const { return updatable_; }
 
   private:
     using OptionParser = Result<Success> (Service::*)(std::vector<std::string>&& args);
@@ -170,6 +171,7 @@
     Result<Success> ParseFile(std::vector<std::string>&& args);
     Result<Success> ParseUser(std::vector<std::string>&& args);
     Result<Success> ParseWritepid(std::vector<std::string>&& args);
+    Result<Success> ParseUpdatable(std::vector<std::string>&& args);
 
     template <typename T>
     Result<Success> AddDescriptor(std::vector<std::string>&& args);
@@ -235,6 +237,8 @@
     std::chrono::seconds restart_period_ = 5s;
     std::optional<std::chrono::seconds> timeout_period_;
 
+    bool updatable_ = false;
+
     std::vector<std::string> args_;
 
     std::vector<std::function<void(const siginfo_t& siginfo)>> reap_callbacks_;
@@ -279,8 +283,15 @@
     const std::vector<std::unique_ptr<Service>>& services() const { return services_; }
     const std::vector<Service*> services_in_shutdown_order() const;
 
+    void MarkServicesUpdate();
+    bool IsServicesUpdated() const { return services_update_finished_; }
+    void DelayService(const Service& service);
+
   private:
     std::vector<std::unique_ptr<Service>> services_;
+
+    bool services_update_finished_ = false;
+    std::vector<std::string> delayed_service_names_;
 };
 
 class ServiceParser : public SectionParser {
@@ -291,6 +302,7 @@
                                  int line) override;
     Result<Success> ParseLineSection(std::vector<std::string>&& args, int line) override;
     Result<Success> EndSection() override;
+    void EndFile() override { filename_ = ""; }
 
   private:
     bool IsValidName(const std::string& name) const;
@@ -298,6 +310,7 @@
     ServiceList* service_list_;
     std::vector<Subcontext>* subcontexts_;
     std::unique_ptr<Service> service_;
+    std::string filename_;
 };
 
 }  // namespace init