Merge "Add asan.permitted.paths for the media namespace" into qt-dev
diff --git a/fastboot/fuzzy_fastboot/main.cpp b/fastboot/fuzzy_fastboot/main.cpp
index ff918a7..a1d69d2 100644
--- a/fastboot/fuzzy_fastboot/main.cpp
+++ b/fastboot/fuzzy_fastboot/main.cpp
@@ -244,16 +244,29 @@
 // Testing creation/resize/delete of logical partitions
 TEST_F(LogicalPartitionCompliance, CreateResizeDeleteLP) {
     ASSERT_TRUE(UserSpaceFastboot());
+    std::string test_partition_name = "test_partition";
+    std::string slot_count;
+    // Add suffix to test_partition_name if device is slotted.
+    EXPECT_EQ(fb->GetVar("slot-count", &slot_count), SUCCESS) << "getvar slot-count failed";
+    int32_t num_slots = strtol(slot_count.c_str(), nullptr, 10);
+    if (num_slots > 0) {
+        std::string current_slot;
+        EXPECT_EQ(fb->GetVar("current-slot", &current_slot), SUCCESS)
+                << "getvar current-slot failed";
+        std::string slot_suffix = "_" + current_slot;
+        test_partition_name += slot_suffix;
+    }
+
     GTEST_LOG_(INFO) << "Testing 'fastboot create-logical-partition' command";
-    EXPECT_EQ(fb->CreatePartition("test_partition_a", "0"), SUCCESS)
+    EXPECT_EQ(fb->CreatePartition(test_partition_name, "0"), SUCCESS)
             << "create-logical-partition failed";
     GTEST_LOG_(INFO) << "Testing 'fastboot resize-logical-partition' command";
-    EXPECT_EQ(fb->ResizePartition("test_partition_a", "4096"), SUCCESS)
+    EXPECT_EQ(fb->ResizePartition(test_partition_name, "4096"), SUCCESS)
             << "resize-logical-partition failed";
     std::vector<char> buf(4096);
 
     GTEST_LOG_(INFO) << "Flashing a logical partition..";
-    EXPECT_EQ(fb->FlashPartition("test_partition_a", buf), SUCCESS)
+    EXPECT_EQ(fb->FlashPartition(test_partition_name, buf), SUCCESS)
             << "flash logical -partition failed";
     GTEST_LOG_(INFO) << "Rebooting to bootloader mode";
     // Reboot to bootloader mode and attempt to flash the logical partitions
@@ -262,7 +275,7 @@
     ReconnectFastbootDevice();
     ASSERT_FALSE(UserSpaceFastboot());
     GTEST_LOG_(INFO) << "Attempt to flash a logical partition..";
-    EXPECT_EQ(fb->FlashPartition("test_partition", buf), DEVICE_FAIL)
+    EXPECT_EQ(fb->FlashPartition(test_partition_name, buf), DEVICE_FAIL)
             << "flash logical partition must fail in bootloader";
     GTEST_LOG_(INFO) << "Rebooting back to fastbootd mode";
     fb->RebootTo("fastboot");
@@ -270,7 +283,7 @@
     ReconnectFastbootDevice();
     ASSERT_TRUE(UserSpaceFastboot());
     GTEST_LOG_(INFO) << "Testing 'fastboot delete-logical-partition' command";
-    EXPECT_EQ(fb->DeletePartition("test_partition_a"), SUCCESS)
+    EXPECT_EQ(fb->DeletePartition(test_partition_name), SUCCESS)
             << "delete logical-partition failed";
 }
 
diff --git a/init/README.md b/init/README.md
index 929f0e4..1b8b848 100644
--- a/init/README.md
+++ b/init/README.md
@@ -414,7 +414,8 @@
 
 `class_start_post_data <serviceclass>`
 > Like `class_start`, but only considers services that were started
-  after /data was mounted. Only used for FDE devices.
+  after /data was mounted, and that were running at the time
+ `class_reset_post_data` was called. Only used for FDE devices.
 
 `class_stop <serviceclass>`
 > Stop and disable all services of the specified class if they are
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 34f229b..25f324c 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -104,35 +104,36 @@
     }
 }
 
-static Result<Success> class_start(const std::string& class_name, bool post_data_only) {
+static Result<Success> do_class_start(const BuiltinArguments& args) {
     // Do not start a class if it has a property persist.dont_start_class.CLASS set to 1.
-    if (android::base::GetBoolProperty("persist.init.dont_start_class." + class_name, false))
+    if (android::base::GetBoolProperty("persist.init.dont_start_class." + args[1], false))
         return Success();
     // Starting a class does not start services which are explicitly disabled.
     // They must  be started individually.
     for (const auto& service : ServiceList::GetInstance()) {
-        if (service->classnames().count(class_name)) {
-            if (post_data_only && !service->is_post_data()) {
-                continue;
-            }
+        if (service->classnames().count(args[1])) {
             if (auto result = service->StartIfNotDisabled(); !result) {
                 LOG(ERROR) << "Could not start service '" << service->name()
-                           << "' as part of class '" << class_name << "': " << result.error();
+                           << "' as part of class '" << args[1] << "': " << result.error();
             }
         }
     }
     return Success();
 }
 
-static Result<Success> do_class_start(const BuiltinArguments& args) {
-    return class_start(args[1], false /* post_data_only */);
-}
-
 static Result<Success> do_class_start_post_data(const BuiltinArguments& args) {
     if (args.context != kInitContext) {
         return Error() << "command 'class_start_post_data' only available in init context";
     }
-    return class_start(args[1], true /* post_data_only */);
+    for (const auto& service : ServiceList::GetInstance()) {
+        if (service->classnames().count(args[1])) {
+            if (auto result = service->StartIfPostData(); !result) {
+                LOG(ERROR) << "Could not start service '" << service->name()
+                           << "' as part of class '" << args[1] << "': " << result.error();
+            }
+        }
+    }
+    return Success();
 }
 
 static Result<Success> do_class_stop(const BuiltinArguments& args) {
diff --git a/init/service.cpp b/init/service.cpp
index 2f96681..ccc37b7 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -1154,10 +1154,23 @@
 
 void Service::ResetIfPostData() {
     if (post_data_) {
+        if (flags_ & SVC_RUNNING) {
+            running_at_post_data_reset_ = true;
+        }
         StopOrReset(SVC_RESET);
     }
 }
 
+Result<Success> Service::StartIfPostData() {
+    // Start the service, but only if it was started after /data was mounted,
+    // and it was still running when we reset the post-data services.
+    if (running_at_post_data_reset_) {
+        return Start();
+    }
+
+    return Success();
+}
+
 void Service::Stop() {
     StopOrReset(SVC_DISABLED);
 }
diff --git a/init/service.h b/init/service.h
index dc2b128..ae29f28 100644
--- a/init/service.h
+++ b/init/service.h
@@ -79,6 +79,7 @@
     Result<Success> ExecStart();
     Result<Success> Start();
     Result<Success> StartIfNotDisabled();
+    Result<Success> StartIfPostData();
     Result<Success> Enable();
     void Reset();
     void ResetIfPostData();
@@ -248,6 +249,8 @@
     bool pre_apexd_ = false;
 
     bool post_data_ = false;
+
+    bool running_at_post_data_reset_ = false;
 };
 
 class ServiceList {