Merge "liblp: Indicate usable regions in ResizePartition"
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index 7f37dc5..bea6739 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -152,7 +152,13 @@
     auto lock = LockExclusive();
     if (!lock) return false;
 
-    if (ReadUpdateState(lock.get()) != UpdateState::Initiated) {
+    auto update_state = ReadUpdateState(lock.get());
+    if (update_state == UpdateState::Unverified) {
+        LOG(INFO) << "FinishedSnapshotWrites already called before. Ignored.";
+        return true;
+    }
+
+    if (update_state != UpdateState::Initiated) {
         LOG(ERROR) << "Can only transition to the Unverified state from the Initiated state.";
         return false;
     }
@@ -211,8 +217,27 @@
     }
 
     auto cow_name = GetCowName(name);
-    int cow_flags = IImageManager::CREATE_IMAGE_ZERO_FILL;
-    return images_->CreateBackingImage(cow_name, cow_size, cow_flags);
+    int cow_flags = IImageManager::CREATE_IMAGE_DEFAULT;
+    if (!images_->CreateBackingImage(cow_name, cow_size, cow_flags)) {
+        return false;
+    }
+
+    // when the kernel creates a persistent dm-snapshot, it requires a CoW file
+    // to store the modifications. The kernel interface does not specify how
+    // the CoW is used, and there is no standard associated.
+    // By looking at the current implementation, the CoW file is treated as:
+    // - a _NEW_ snapshot if its first 32 bits are zero, so the newly created
+    // dm-snapshot device will look like a perfect copy of the origin device;
+    // - an _EXISTING_ snapshot if the first 32 bits are equal to a
+    // kernel-specified magic number and the CoW file metadata is set as valid,
+    // so it can be used to resume the last state of a snapshot device;
+    // - an _INVALID_ snapshot otherwise.
+    // To avoid zero-filling the whole CoW file when a new dm-snapshot is
+    // created, here we zero-fill only the first 32 bits. This is a temporary
+    // workaround that will be discussed again when the kernel API gets
+    // consolidated.
+    ssize_t dm_snap_magic_size = 4;  // 32 bit
+    return images_->ZeroFillNewImage(cow_name, dm_snap_magic_size);
 }
 
 bool SnapshotManager::MapSnapshot(LockedFile* lock, const std::string& name,
@@ -947,7 +972,7 @@
     // flushed remaining I/O. We could in theory replace with dm-zero (or
     // re-use the table above), but for now it's better to know why this
     // would fail.
-    if (!dm.DeleteDeviceIfExists(dm_name)) {
+    if (dm_name != name && !dm.DeleteDeviceIfExists(dm_name)) {
         LOG(ERROR) << "Unable to delete snapshot device " << dm_name << ", COW cannot be "
                    << "reclaimed until after reboot.";
         return false;
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index 14246ae..da18af6 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -153,12 +153,12 @@
     shared_libs: [
         "libunwindstack",
     ],
+    relative_install_path: "libunwindstack_test",
 }
 
-cc_test {
-    name: "libunwindstack_test",
+cc_defaults {
+    name: "libunwindstack_testlib_flags",
     defaults: ["libunwindstack_flags"],
-    isolated: true,
 
     srcs: [
         "tests/ArmExidxDecodeTest.cpp",
@@ -183,7 +183,6 @@
         "tests/ElfTestUtils.cpp",
         "tests/IsolatedSettings.cpp",
         "tests/JitDebugTest.cpp",
-        "tests/LocalUnwinderTest.cpp",
         "tests/LogFake.cpp",
         "tests/MapInfoCreateMemoryTest.cpp",
         "tests/MapInfoGetBuildIDTest.cpp",
@@ -253,11 +252,28 @@
         "tests/files/offline/straddle_arm/*",
         "tests/files/offline/straddle_arm64/*",
     ],
+}
+
+cc_test {
+    name: "libunwindstack_test",
+    defaults: ["libunwindstack_testlib_flags"],
+    isolated: true,
+
+    srcs: [
+        "tests/LocalUnwinderTest.cpp",
+    ],
     required: [
         "libunwindstack_local",
     ],
 }
 
+// Skip LocalUnwinderTest until atest understands required properly.
+cc_test {
+    name: "libunwindstack_unit_test",
+    defaults: ["libunwindstack_testlib_flags"],
+    isolated: true,
+}
+
 //-------------------------------------------------------------------------
 // Tools
 //-------------------------------------------------------------------------
diff --git a/libunwindstack/TEST_MAPPING b/libunwindstack/TEST_MAPPING
new file mode 100644
index 0000000..55771c0
--- /dev/null
+++ b/libunwindstack/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "libunwindstack_unit_test"
+    }
+  ]
+}
diff --git a/libunwindstack/tests/LocalUnwinderTest.cpp b/libunwindstack/tests/LocalUnwinderTest.cpp
index 56a18cd..9936f7a 100644
--- a/libunwindstack/tests/LocalUnwinderTest.cpp
+++ b/libunwindstack/tests/LocalUnwinderTest.cpp
@@ -170,10 +170,10 @@
 
   std::string testlib(testing::internal::GetArgvs()[0]);
   auto const value = testlib.find_last_of('/');
-  if (value == std::string::npos) {
-    testlib = "../";
+  if (value != std::string::npos) {
+    testlib = testlib.substr(0, value + 1);
   } else {
-    testlib = testlib.substr(0, value + 1) + "../";
+    testlib = "";
   }
   testlib += "libunwindstack_local.so";