Merge "liblp: Try to merge extents during partition resizes."
diff --git a/fs_mgr/fs_mgr_dm_linear.cpp b/fs_mgr/fs_mgr_dm_linear.cpp
index 05e03e1..aa68ceb 100644
--- a/fs_mgr/fs_mgr_dm_linear.cpp
+++ b/fs_mgr/fs_mgr_dm_linear.cpp
@@ -133,7 +133,11 @@
 
 bool DestroyLogicalPartition(const std::string& name) {
     DeviceMapper& dm = DeviceMapper::Instance();
-    return dm.DeleteDevice(name);
+    if (!dm.DeleteDevice(name)) {
+        return false;
+    }
+    LINFO << "Unmapped logical partition " << name;
+    return true;
 }
 
 }  // namespace fs_mgr
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index 68d024b..2015e4d 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -511,13 +511,18 @@
 bool MetadataBuilder::ResizePartition(Partition* partition, uint64_t requested_size) {
     // Align the space needed up to the nearest sector.
     uint64_t aligned_size = AlignTo(requested_size, device_info_.logical_block_size);
+    uint64_t old_size = partition->size();
 
-    if (aligned_size > partition->size()) {
-        return GrowPartition(partition, aligned_size);
-    }
-    if (aligned_size < partition->size()) {
+    if (aligned_size > old_size) {
+        if (!GrowPartition(partition, aligned_size)) {
+            return false;
+        }
+    } else if (aligned_size < partition->size()) {
         ShrinkPartition(partition, aligned_size);
     }
+
+    LINFO << "Partition " << partition->name() << " will resize from " << old_size << " bytes to "
+          << aligned_size << " bytes";
     return true;
 }
 
diff --git a/fs_mgr/liblp/utility.h b/fs_mgr/liblp/utility.h
index 4522275..6ef5124 100644
--- a/fs_mgr/liblp/utility.h
+++ b/fs_mgr/liblp/utility.h
@@ -26,6 +26,8 @@
 #include "liblp/metadata_format.h"
 
 #define LP_TAG "[liblp]"
+#define LWARN LOG(WARNING) << LP_TAG
+#define LINFO LOG(INFO) << LP_TAG
 #define LERROR LOG(ERROR) << LP_TAG
 #define PERROR PLOG(ERROR) << LP_TAG
 
diff --git a/fs_mgr/liblp/writer.cpp b/fs_mgr/liblp/writer.cpp
index 156319b..fc9d83f 100644
--- a/fs_mgr/liblp/writer.cpp
+++ b/fs_mgr/liblp/writer.cpp
@@ -304,7 +304,11 @@
         PERROR << __PRETTY_FUNCTION__ << "open failed: " << block_device;
         return false;
     }
-    return FlashPartitionTable(fd, metadata, slot_number);
+    if (!FlashPartitionTable(fd, metadata, slot_number)) {
+        return false;
+    }
+    LWARN << "Flashed new logical partition geometry to " << block_device;
+    return true;
 }
 
 bool UpdatePartitionTable(const std::string& block_device, const LpMetadata& metadata,
@@ -314,7 +318,12 @@
         PERROR << __PRETTY_FUNCTION__ << "open failed: " << block_device;
         return false;
     }
-    return UpdatePartitionTable(fd, metadata, slot_number);
+    if (!UpdatePartitionTable(fd, metadata, slot_number)) {
+        return false;
+    }
+    LINFO << "Updated logical partition table at slot " << slot_number << " on device "
+          << block_device;
+    return true;
 }
 
 bool UpdatePartitionTable(int fd, const LpMetadata& metadata, uint32_t slot_number) {
diff --git a/init/Android.bp b/init/Android.bp
index 660d586..a93bb66 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -127,7 +127,6 @@
         "ueventd.cpp",
         "ueventd_parser.cpp",
         "util.cpp",
-        "watchdogd.cpp",
     ],
     whole_static_libs: ["libcap"],
     header_libs: ["bootimg_headers"],
@@ -157,7 +156,6 @@
     srcs: ["main.cpp"],
     symlinks: [
         "sbin/ueventd",
-        "sbin/watchdogd",
     ],
 }
 */
diff --git a/init/Android.mk b/init/Android.mk
index d0cb820..9d9d368 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -98,7 +98,6 @@
 # Create symlinks.
 LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \
     ln -sf ../init $(TARGET_ROOT_OUT)/sbin/ueventd; \
-    ln -sf ../init $(TARGET_ROOT_OUT)/sbin/watchdogd
 
 LOCAL_SANITIZE := signed-integer-overflow
 include $(BUILD_EXECUTABLE)
diff --git a/init/devices.cpp b/init/devices.cpp
index ba08180..58c8b2e 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -34,7 +34,7 @@
 #include "util.h"
 
 #ifdef _INIT_INIT_H
-#error "Do not include init.h in files used by ueventd or watchdogd; it will expose init's globals"
+#error "Do not include init.h in files used by ueventd; it will expose init's globals"
 #endif
 
 using android::base::Basename;
diff --git a/init/host_init_stubs.cpp b/init/host_init_stubs.cpp
index 2352fc7..8866bdc 100644
--- a/init/host_init_stubs.cpp
+++ b/init/host_init_stubs.cpp
@@ -41,10 +41,9 @@
 }
 
 // selinux.h
-bool SelinuxHasVendorInit() {
-    return true;
+int SelinuxGetVendorAndroidVersion() {
+    return 10000;
 }
-
 void SelabelInitialize() {}
 
 bool SelabelLookupFileContext(const std::string& key, int type, std::string* result) {
diff --git a/init/host_init_stubs.h b/init/host_init_stubs.h
index f0e1f07..0af11f6 100644
--- a/init/host_init_stubs.h
+++ b/init/host_init_stubs.h
@@ -23,6 +23,9 @@
 
 #include <string>
 
+// android/api-level.h
+#define __ANDROID_API_P__ 28
+
 // sys/system_properties.h
 #define PROP_VALUE_MAX 92
 
@@ -41,7 +44,7 @@
                            const std::string& source_context, const ucred& cr, std::string* error);
 
 // selinux.h
-bool SelinuxHasVendorInit();
+int SelinuxGetVendorAndroidVersion();
 void SelabelInitialize();
 bool SelabelLookupFileContext(const std::string& key, int type, std::string* result);
 
diff --git a/init/init.cpp b/init/init.cpp
index 7ad9ec3..e0cce0e 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -58,7 +58,6 @@
 #include "sigchld_handler.h"
 #include "ueventd.h"
 #include "util.h"
-#include "watchdogd.h"
 
 using namespace std::chrono_literals;
 using namespace std::string_literals;
@@ -617,10 +616,6 @@
         return ueventd_main(argc, argv);
     }
 
-    if (!strcmp(basename(argv[0]), "watchdogd")) {
-        return watchdogd_main(argc, argv);
-    }
-
     if (argc > 1 && !strcmp(argv[1], "subcontext")) {
         android::base::InitLogging(argv, &android::base::KernelLogger);
         const BuiltinFunctionMap function_map;
diff --git a/init/init.h b/init/init.h
index 6c82fa1..f244ad7 100644
--- a/init/init.h
+++ b/init/init.h
@@ -31,8 +31,8 @@
 namespace android {
 namespace init {
 
-// Note: These globals are *only* valid in init, so they should not be used in ueventd,
-// watchdogd, or any files that may be included in those, such as devices.cpp and util.cpp.
+// Note: These globals are *only* valid in init, so they should not be used in ueventd
+// or any files that may be included in ueventd, such as devices.cpp and util.cpp.
 // TODO: Have an Init class and remove all globals.
 extern std::string default_console;
 extern std::vector<std::string> late_import_paths;
diff --git a/init/property_service.cpp b/init/property_service.cpp
index c0d811f..cd2f630 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -16,6 +16,7 @@
 
 #include "property_service.h"
 
+#include <android/api-level.h>
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -576,7 +577,7 @@
     size_t flen = 0;
 
     const char* context = kInitContext.c_str();
-    if (SelinuxHasVendorInit()) {
+    if (SelinuxGetVendorAndroidVersion() >= __ANDROID_API_P__) {
         for (const auto& [path_prefix, secontext] : paths_and_secontexts) {
             if (StartsWith(filename, path_prefix)) {
                 context = secontext;
diff --git a/init/selinux.cpp b/init/selinux.cpp
index b788be9..fd7e86f 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -47,6 +47,7 @@
 
 #include "selinux.h"
 
+#include <android/api-level.h>
 #include <fcntl.h>
 #include <stdlib.h>
 #include <sys/wait.h>
@@ -472,29 +473,27 @@
     selinux_set_callback(SELINUX_CB_LOG, cb);
 }
 
-// This function checks whether the sepolicy supports vendor init.
-bool SelinuxHasVendorInit() {
+// This function returns the Android version with which the vendor SEPolicy was compiled.
+// It is used for version checks such as whether or not vendor_init should be used
+int SelinuxGetVendorAndroidVersion() {
     if (!IsSplitPolicyDevice()) {
-        // If this device does not split sepolicy files, vendor_init will be available in the latest
-        // monolithic sepolicy file.
-        return true;
+        // If this device does not split sepolicy files, it's not a Treble device and therefore,
+        // we assume it's always on the latest platform.
+        return __ANDROID_API_FUTURE__;
     }
 
     std::string version;
     if (!GetVendorMappingVersion(&version)) {
-        // Return true as the default if we failed to load the vendor sepolicy version.
-        return true;
+        LOG(FATAL) << "Could not read vendor SELinux version";
     }
 
     int major_version;
     std::string major_version_str(version, 0, version.find('.'));
     if (!ParseInt(major_version_str, &major_version)) {
-        PLOG(ERROR) << "Failed to parse the vendor sepolicy major version " << major_version_str;
-        // Return true as the default if we failed to parse the major version.
-        return true;
+        PLOG(FATAL) << "Failed to parse the vendor sepolicy major version " << major_version_str;
     }
 
-    return major_version >= 28;
+    return major_version;
 }
 
 // selinux_android_file_context_handle() takes on the order of 10+ms to run, so we want to cache
diff --git a/init/selinux.h b/init/selinux.h
index 30069b5..c41d7f0 100644
--- a/init/selinux.h
+++ b/init/selinux.h
@@ -27,7 +27,7 @@
 void SelinuxRestoreContext();
 
 void SelinuxSetupKernelLogging();
-bool SelinuxHasVendorInit();
+int SelinuxGetVendorAndroidVersion();
 
 void SelabelInitialize();
 bool SelabelLookupFileContext(const std::string& key, int type, std::string* result);
diff --git a/init/service.cpp b/init/service.cpp
index 4c2747e..d20e90a 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -46,10 +46,12 @@
 #include "util.h"
 
 #if defined(__ANDROID__)
+#include <android/api-level.h>
 #include <sys/system_properties.h>
 
 #include "init.h"
 #include "property_service.h"
+#include "selinux.h"
 #else
 #include "host_init_stubs.h"
 #endif
@@ -1211,6 +1213,13 @@
     }
 
     std::vector<std::string> str_args(args.begin() + 2, args.end());
+
+    if (SelinuxGetVendorAndroidVersion() <= __ANDROID_API_P__) {
+        if (str_args[0] == "/sbin/watchdogd") {
+            str_args[0] = "/system/bin/watchdogd";
+        }
+    }
+
     service_ = std::make_unique<Service>(name, restart_action_subcontext, str_args);
     return Success();
 }
diff --git a/init/subcontext.cpp b/init/subcontext.cpp
index ee72513..c2a21d4 100644
--- a/init/subcontext.cpp
+++ b/init/subcontext.cpp
@@ -30,6 +30,7 @@
 #include "util.h"
 
 #if defined(__ANDROID__)
+#include <android/api-level.h>
 #include "property_service.h"
 #include "selinux.h"
 #else
@@ -355,7 +356,7 @@
 static bool shutting_down;
 
 std::vector<Subcontext>* InitializeSubcontexts() {
-    if (SelinuxHasVendorInit()) {
+    if (SelinuxGetVendorAndroidVersion() >= __ANDROID_API_P__) {
         for (const auto& [path_prefix, secontext] : paths_and_secontexts) {
             subcontexts.emplace_back(path_prefix, secontext);
         }
diff --git a/init/util.cpp b/init/util.cpp
index 7735717..105ac87 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -47,7 +47,7 @@
 #endif
 
 #ifdef _INIT_INIT_H
-#error "Do not include init.h in files used by ueventd or watchdogd; it will expose init's globals"
+#error "Do not include init.h in files used by ueventd; it will expose init's globals"
 #endif
 
 using android::base::boot_clock;
diff --git a/init/watchdogd.h b/init/watchdogd.h
deleted file mode 100644
index 73f77d5..0000000
--- a/init/watchdogd.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2012 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 _INIT_WATCHDOGD_H_
-#define _INIT_WATCHDOGD_H_
-
-namespace android {
-namespace init {
-
-int watchdogd_main(int argc, char **argv);
-
-}  // namespace init
-}  // namespace android
-
-#endif
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index df5da65..be2145d 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -190,6 +190,7 @@
         "tests/MemoryRangeTest.cpp",
         "tests/MemoryRemoteTest.cpp",
         "tests/MemoryTest.cpp",
+        "tests/RegsInfoTest.cpp",
         "tests/RegsIterateTest.cpp",
         "tests/RegsStepIfSignalHandlerTest.cpp",
         "tests/RegsTest.cpp",
diff --git a/libunwindstack/RegsInfo.h b/libunwindstack/RegsInfo.h
index 47825f5..e6dd33c 100644
--- a/libunwindstack/RegsInfo.h
+++ b/libunwindstack/RegsInfo.h
@@ -25,11 +25,13 @@
 
 template <typename AddressType>
 struct RegsInfo {
+  static constexpr size_t MAX_REGISTERS = 64;
+
   RegsInfo(RegsImpl<AddressType>* regs) : regs(regs) {}
 
   RegsImpl<AddressType>* regs = nullptr;
   uint64_t saved_reg_map = 0;
-  AddressType saved_regs[64];
+  AddressType saved_regs[MAX_REGISTERS];
 
   inline AddressType Get(uint32_t reg) {
     if (IsSaved(reg)) {
@@ -39,23 +41,23 @@
   }
 
   inline AddressType* Save(uint32_t reg) {
-    if (reg > sizeof(saved_regs) / sizeof(AddressType)) {
-      // This should never happen as since all currently supported
-      // architectures have the total number of registers < 64.
+    if (reg > MAX_REGISTERS) {
+      // This should never happen since all currently supported
+      // architectures have < 64 total registers.
       abort();
     }
-    saved_reg_map |= 1 << reg;
+    saved_reg_map |= 1ULL << reg;
     saved_regs[reg] = (*regs)[reg];
     return &(*regs)[reg];
   }
 
   inline bool IsSaved(uint32_t reg) {
-    if (reg > sizeof(saved_regs) / sizeof(AddressType)) {
-      // This should never happen as since all currently supported
-      // architectures have the total number of registers < 64.
+    if (reg > MAX_REGISTERS) {
+      // This should never happen since all currently supported
+      // architectures have < 64 total registers.
       abort();
     }
-    return saved_reg_map & (1 << reg);
+    return saved_reg_map & (1ULL << reg);
   }
 
   inline uint16_t Total() { return regs->total_regs(); }
diff --git a/libunwindstack/tests/RegsInfoTest.cpp b/libunwindstack/tests/RegsInfoTest.cpp
new file mode 100644
index 0000000..052b5bf
--- /dev/null
+++ b/libunwindstack/tests/RegsInfoTest.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2018 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 <stdint.h>
+
+#include <gtest/gtest.h>
+
+#include <unwindstack/Regs.h>
+
+#include "RegsFake.h"
+#include "RegsInfo.h"
+
+namespace unwindstack {
+
+TEST(RegsInfoTest, single_uint32_t) {
+  RegsImplFake<uint32_t> regs(10);
+  RegsInfo<uint32_t> info(&regs);
+
+  regs[1] = 0x100;
+  ASSERT_FALSE(info.IsSaved(1));
+  ASSERT_EQ(0x100U, info.Get(1));
+  ASSERT_EQ(10, info.Total());
+
+  uint32_t* value = info.Save(1);
+  ASSERT_EQ(value, &regs[1]);
+  regs[1] = 0x200;
+  ASSERT_TRUE(info.IsSaved(1));
+  ASSERT_EQ(0x100U, info.Get(1));
+  ASSERT_EQ(0x200U, regs[1]);
+}
+
+TEST(RegsInfoTest, single_uint64_t) {
+  RegsImplFake<uint64_t> regs(20);
+  RegsInfo<uint64_t> info(&regs);
+
+  regs[3] = 0x300;
+  ASSERT_FALSE(info.IsSaved(3));
+  ASSERT_EQ(0x300U, info.Get(3));
+  ASSERT_EQ(20, info.Total());
+
+  uint64_t* value = info.Save(3);
+  ASSERT_EQ(value, &regs[3]);
+  regs[3] = 0x400;
+  ASSERT_TRUE(info.IsSaved(3));
+  ASSERT_EQ(0x300U, info.Get(3));
+  ASSERT_EQ(0x400U, regs[3]);
+}
+
+TEST(RegsInfoTest, all) {
+  RegsImplFake<uint64_t> regs(64);
+  RegsInfo<uint64_t> info(&regs);
+
+  for (uint32_t i = 0; i < 64; i++) {
+    regs[i] = i * 0x100;
+    ASSERT_EQ(i * 0x100, info.Get(i)) << "Reg " + std::to_string(i) + " failed.";
+  }
+
+  for (uint32_t i = 0; i < 64; i++) {
+    ASSERT_FALSE(info.IsSaved(i)) << "Reg " + std::to_string(i) + " failed.";
+    uint64_t* reg = info.Save(i);
+    ASSERT_EQ(reg, &regs[i]) << "Reg " + std::to_string(i) + " failed.";
+    *reg = i * 0x1000 + 0x100;
+    ASSERT_EQ(i * 0x1000 + 0x100, regs[i]) << "Reg " + std::to_string(i) + " failed.";
+  }
+
+  for (uint32_t i = 0; i < 64; i++) {
+    ASSERT_TRUE(info.IsSaved(i)) << "Reg " + std::to_string(i) + " failed.";
+    ASSERT_EQ(i * 0x100, info.Get(i)) << "Reg " + std::to_string(i) + " failed.";
+  }
+}
+
+}  // namespace unwindstack
diff --git a/lmkd/Android.bp b/lmkd/Android.bp
index 2efda86..9ac082f 100644
--- a/lmkd/Android.bp
+++ b/lmkd/Android.bp
@@ -7,17 +7,8 @@
         "liblog",
     ],
     local_include_dirs: ["include"],
-    cflags: ["-Werror"],
-
+    cflags: ["-Werror", "-DLMKD_TRACE_KILLS"],
     init_rc: ["lmkd.rc"],
-
-    product_variables: {
-        debuggable: {
-            cflags: [
-                "-DLMKD_TRACE_KILLS"
-            ],
-        },
-    },
 }
 
 cc_library_static {
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index e7c13e0..1a14be3 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -52,8 +52,8 @@
 
 #else /* LMKD_TRACE_KILLS */
 
-#define TRACE_KILL_START(pid)
-#define TRACE_KILL_END()
+#define TRACE_KILL_START(pid) ((void)(pid))
+#define TRACE_KILL_END() ((void)0)
 
 #endif /* LMKD_TRACE_KILLS */
 
diff --git a/watchdogd/Android.bp b/watchdogd/Android.bp
new file mode 100644
index 0000000..0fbc33c
--- /dev/null
+++ b/watchdogd/Android.bp
@@ -0,0 +1,14 @@
+cc_binary {
+    name: "watchdogd",
+    recovery_available: true,
+    srcs: ["watchdogd.cpp"],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+    ],
+    shared_libs: ["libbase"],
+    sanitize: {
+        misc_undefined: ["signed-integer-overflow"],
+    },
+}
diff --git a/init/watchdogd.cpp b/watchdogd/watchdogd.cpp
similarity index 79%
rename from init/watchdogd.cpp
rename to watchdogd/watchdogd.cpp
index e03a2c3..5dc41e6 100644
--- a/init/watchdogd.cpp
+++ b/watchdogd/watchdogd.cpp
@@ -23,16 +23,9 @@
 
 #include <android-base/logging.h>
 
-#ifdef _INIT_INIT_H
-#error "Do not include init.h in files used by ueventd or watchdogd; it will expose init's globals"
-#endif
-
 #define DEV_NAME "/dev/watchdog"
 
-namespace android {
-namespace init {
-
-int watchdogd_main(int argc, char **argv) {
+int main(int argc, char** argv) {
     android::base::InitLogging(argv, &android::base::KernelLogger);
 
     int interval = 10;
@@ -43,7 +36,7 @@
 
     LOG(INFO) << "watchdogd started (interval " << interval << ", margin " << margin << ")!";
 
-    int fd = open(DEV_NAME, O_RDWR|O_CLOEXEC);
+    int fd = open(DEV_NAME, O_RDWR | O_CLOEXEC);
     if (fd == -1) {
         PLOG(ERROR) << "Failed to open " << DEV_NAME;
         return 1;
@@ -63,9 +56,8 @@
                 interval = 1;
             }
             LOG(WARNING) << "Adjusted interval to timeout returned by driver: "
-                         << "timeout " << timeout
-                         << ", interval " << interval
-                         << ", margin " << margin;
+                         << "timeout " << timeout << ", interval " << interval << ", margin "
+                         << margin;
         }
     }
 
@@ -74,6 +66,3 @@
         sleep(interval);
     }
 }
-
-}  // namespace init
-}  // namespace android