Merge "Declare __FAKE_USE_VA_ARGS as a variadic function."
diff --git a/adb/daemon/remount_service.cpp b/adb/daemon/remount_service.cpp
index dfdc365..1bb2fbb 100644
--- a/adb/daemon/remount_service.cpp
+++ b/adb/daemon/remount_service.cpp
@@ -178,10 +178,6 @@
     }
 
     unsigned long remount_flags = get_mount_flags(fd, dir);
-    if ((remount_flags & MS_RDONLY) == 0) {
-        // Mount is already writable.
-        return true;
-    }
     remount_flags &= ~MS_RDONLY;
     remount_flags |= MS_REMOUNT;
 
@@ -192,7 +188,7 @@
         WriteFdFmt(fd, "remount of the %s mount failed: %s.\n", dir, strerror(errno));
         return false;
     }
-    if (mount(dev.c_str(), dir, "none", remount_flags, nullptr) == -1) {
+    if (mount(dev.c_str(), dir, "none", MS_REMOUNT, nullptr) == -1) {
         WriteFdFmt(fd, "remount of the %s superblock failed: %s\n", dir, strerror(errno));
         return false;
     }
diff --git a/fs_mgr/fs_mgr_dm_linear.cpp b/fs_mgr/fs_mgr_dm_linear.cpp
index 28e910b..05e03e1 100644
--- a/fs_mgr/fs_mgr_dm_linear.cpp
+++ b/fs_mgr/fs_mgr_dm_linear.cpp
@@ -79,6 +79,25 @@
     return true;
 }
 
+static bool CreateLogicalPartition(const std::string& block_device, const LpMetadata& metadata,
+                                   const LpMetadataPartition& partition, std::string* path) {
+    DeviceMapper& dm = DeviceMapper::Instance();
+
+    DmTable table;
+    if (!CreateDmTable(block_device, metadata, partition, &table)) {
+        return false;
+    }
+    std::string name = GetPartitionName(partition);
+    if (!dm.CreateDevice(name, table)) {
+        return false;
+    }
+    if (!dm.GetDmDevicePathByName(name, path)) {
+        return false;
+    }
+    LINFO << "Created logical partition " << name << " on device " << *path;
+    return true;
+}
+
 bool CreateLogicalPartitions(const std::string& block_device) {
     uint32_t slot = SlotNumberForSlotSuffix(fs_mgr_get_slot_suffix());
     auto metadata = ReadMetadata(block_device.c_str(), slot);
@@ -86,23 +105,36 @@
         LOG(ERROR) << "Could not read partition table.";
         return true;
     }
-
-    DeviceMapper& dm = DeviceMapper::Instance();
     for (const auto& partition : metadata->partitions) {
-        DmTable table;
-        if (!CreateDmTable(block_device, *metadata.get(), partition, &table)) {
-            return false;
-        }
-        std::string name = GetPartitionName(partition);
-        if (!dm.CreateDevice(name, table)) {
-            return false;
-        }
         std::string path;
-        dm.GetDmDevicePathByName(partition.name, &path);
-        LINFO << "Created logical partition " << name << " on device " << path;
+        if (!CreateLogicalPartition(block_device, *metadata.get(), partition, &path)) {
+            LERROR << "Could not create logical partition: " << GetPartitionName(partition);
+            return false;
+        }
     }
     return true;
 }
 
+bool CreateLogicalPartition(const std::string& block_device, uint32_t metadata_slot,
+                            const std::string& partition_name, std::string* path) {
+    auto metadata = ReadMetadata(block_device.c_str(), metadata_slot);
+    if (!metadata) {
+        LOG(ERROR) << "Could not read partition table.";
+        return true;
+    }
+    for (const auto& partition : metadata->partitions) {
+        if (GetPartitionName(partition) == partition_name) {
+            return CreateLogicalPartition(block_device, *metadata.get(), partition, path);
+        }
+    }
+    LERROR << "Could not find any partition with name: " << partition_name;
+    return false;
+}
+
+bool DestroyLogicalPartition(const std::string& name) {
+    DeviceMapper& dm = DeviceMapper::Instance();
+    return dm.DeleteDevice(name);
+}
+
 }  // namespace fs_mgr
 }  // namespace android
diff --git a/fs_mgr/include/fs_mgr_dm_linear.h b/fs_mgr/include/fs_mgr_dm_linear.h
index 42af9d0..cac475c 100644
--- a/fs_mgr/include/fs_mgr_dm_linear.h
+++ b/fs_mgr/include/fs_mgr_dm_linear.h
@@ -39,6 +39,15 @@
 
 bool CreateLogicalPartitions(const std::string& block_device);
 
+// Create a block device for a single logical partition, given metadata and
+// the partition name. On success, a path to the partition's block device is
+// returned.
+bool CreateLogicalPartition(const std::string& block_device, uint32_t metadata_slot,
+                            const std::string& partition_name, std::string* path);
+
+// Destroy the block device for a logical partition, by name.
+bool DestroyLogicalPartition(const std::string& name);
+
 }  // namespace fs_mgr
 }  // namespace android
 
diff --git a/libsync/include/ndk/sync.h b/libsync/include/ndk/sync.h
index 49f01e1..ba7d8c4 100644
--- a/libsync/include/ndk/sync.h
+++ b/libsync/include/ndk/sync.h
@@ -27,11 +27,14 @@
 #define ANDROID_SYNC_H
 
 #include <stdint.h>
+#include <sys/cdefs.h>
 
 #include <linux/sync_file.h>
 
 __BEGIN_DECLS
 
+#if __ANDROID_API__ >= 26
+
 /* Fences indicate the status of an asynchronous task. They are initially
  * in unsignaled state (0), and make a one-time transition to either signaled
  * (1) or error (< 0) state. A sync file is a collection of one or more fences;
@@ -88,6 +91,8 @@
 /** Free a struct sync_file_info structure */
 void sync_file_info_free(struct sync_file_info* info) __INTRODUCED_IN(26);
 
+#endif /* __ANDROID_API__ >= 26 */
+
 __END_DECLS
 
 #endif /* ANDROID_SYNC_H */
diff --git a/libutils/Android.bp b/libutils/Android.bp
index bbfa9d8..d635e65 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -155,6 +155,7 @@
             ],
         },
         linux: {
+            shared_libs: ["libbase"],
             srcs: [
                 "Looper.cpp",
             ],
diff --git a/libutils/Looper.cpp b/libutils/Looper.cpp
index 7bc2397..102fdf0 100644
--- a/libutils/Looper.cpp
+++ b/libutils/Looper.cpp
@@ -60,24 +60,22 @@
 static pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT;
 static pthread_key_t gTLSKey = 0;
 
-Looper::Looper(bool allowNonCallbacks) :
-        mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),
-        mPolling(false), mEpollFd(-1), mEpollRebuildRequired(false),
-        mNextRequestSeq(0), mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {
-    mWakeEventFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
-    LOG_ALWAYS_FATAL_IF(mWakeEventFd < 0, "Could not make wake event fd: %s",
-                        strerror(errno));
+Looper::Looper(bool allowNonCallbacks)
+    : mAllowNonCallbacks(allowNonCallbacks),
+      mSendingMessage(false),
+      mPolling(false),
+      mEpollRebuildRequired(false),
+      mNextRequestSeq(0),
+      mResponseIndex(0),
+      mNextMessageUptime(LLONG_MAX) {
+    mWakeEventFd.reset(eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC));
+    LOG_ALWAYS_FATAL_IF(mWakeEventFd.get() < 0, "Could not make wake event fd: %s", strerror(errno));
 
     AutoMutex _l(mLock);
     rebuildEpollLocked();
 }
 
 Looper::~Looper() {
-    close(mWakeEventFd);
-    mWakeEventFd = -1;
-    if (mEpollFd >= 0) {
-        close(mEpollFd);
-    }
 }
 
 void Looper::initTLSKey() {
@@ -137,18 +135,18 @@
 #if DEBUG_CALLBACKS
         ALOGD("%p ~ rebuildEpollLocked - rebuilding epoll set", this);
 #endif
-        close(mEpollFd);
+        mEpollFd.reset();
     }
 
     // Allocate the new epoll instance and register the wake pipe.
-    mEpollFd = epoll_create(EPOLL_SIZE_HINT);
+    mEpollFd.reset(epoll_create(EPOLL_SIZE_HINT));
     LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance: %s", strerror(errno));
 
     struct epoll_event eventItem;
     memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
     eventItem.events = EPOLLIN;
-    eventItem.data.fd = mWakeEventFd;
-    int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeEventFd, & eventItem);
+    eventItem.data.fd = mWakeEventFd.get();
+    int result = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, mWakeEventFd.get(), &eventItem);
     LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake event fd to epoll instance: %s",
                         strerror(errno));
 
@@ -157,7 +155,7 @@
         struct epoll_event eventItem;
         request.initEventItem(&eventItem);
 
-        int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, request.fd, & eventItem);
+        int epollResult = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, request.fd, &eventItem);
         if (epollResult < 0) {
             ALOGE("Error adding epoll events for fd %d while rebuilding epoll set: %s",
                   request.fd, strerror(errno));
@@ -239,7 +237,7 @@
     mPolling = true;
 
     struct epoll_event eventItems[EPOLL_MAX_EVENTS];
-    int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
+    int eventCount = epoll_wait(mEpollFd.get(), eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
 
     // No longer idling.
     mPolling = false;
@@ -281,7 +279,7 @@
     for (int i = 0; i < eventCount; i++) {
         int fd = eventItems[i].data.fd;
         uint32_t epollEvents = eventItems[i].events;
-        if (fd == mWakeEventFd) {
+        if (fd == mWakeEventFd.get()) {
             if (epollEvents & EPOLLIN) {
                 awoken();
             } else {
@@ -401,11 +399,11 @@
 #endif
 
     uint64_t inc = 1;
-    ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd, &inc, sizeof(uint64_t)));
+    ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd.get(), &inc, sizeof(uint64_t)));
     if (nWrite != sizeof(uint64_t)) {
         if (errno != EAGAIN) {
-            LOG_ALWAYS_FATAL("Could not write wake signal to fd %d: %s",
-                    mWakeEventFd, strerror(errno));
+            LOG_ALWAYS_FATAL("Could not write wake signal to fd %d: %s", mWakeEventFd.get(),
+                             strerror(errno));
         }
     }
 }
@@ -416,7 +414,7 @@
 #endif
 
     uint64_t counter;
-    TEMP_FAILURE_RETRY(read(mWakeEventFd, &counter, sizeof(uint64_t)));
+    TEMP_FAILURE_RETRY(read(mWakeEventFd.get(), &counter, sizeof(uint64_t)));
 }
 
 void Looper::pushResponse(int events, const Request& request) {
@@ -467,14 +465,14 @@
 
         ssize_t requestIndex = mRequests.indexOfKey(fd);
         if (requestIndex < 0) {
-            int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);
+            int epollResult = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, fd, &eventItem);
             if (epollResult < 0) {
                 ALOGE("Error adding epoll events for fd %d: %s", fd, strerror(errno));
                 return -1;
             }
             mRequests.add(fd, request);
         } else {
-            int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem);
+            int epollResult = epoll_ctl(mEpollFd.get(), EPOLL_CTL_MOD, fd, &eventItem);
             if (epollResult < 0) {
                 if (errno == ENOENT) {
                     // Tolerate ENOENT because it means that an older file descriptor was
@@ -495,7 +493,7 @@
                             "being recycled, falling back on EPOLL_CTL_ADD: %s",
                             this, strerror(errno));
 #endif
-                    epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);
+                    epollResult = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, fd, &eventItem);
                     if (epollResult < 0) {
                         ALOGE("Error modifying or adding epoll events for fd %d: %s",
                                 fd, strerror(errno));
@@ -542,7 +540,7 @@
         // updating the epoll set so that we avoid accidentally leaking callbacks.
         mRequests.removeItemsAt(requestIndex);
 
-        int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, nullptr);
+        int epollResult = epoll_ctl(mEpollFd.get(), EPOLL_CTL_DEL, fd, nullptr);
         if (epollResult < 0) {
             if (seq != -1 && (errno == EBADF || errno == ENOENT)) {
                 // Tolerate EBADF or ENOENT when the sequence number is known because it
diff --git a/libutils/include/utils/Looper.h b/libutils/include/utils/Looper.h
index 4509d75..c439c5c 100644
--- a/libutils/include/utils/Looper.h
+++ b/libutils/include/utils/Looper.h
@@ -24,6 +24,8 @@
 
 #include <sys/epoll.h>
 
+#include <android-base/unique_fd.h>
+
 namespace android {
 
 /*
@@ -447,7 +449,7 @@
 
     const bool mAllowNonCallbacks; // immutable
 
-    int mWakeEventFd;  // immutable
+    android::base::unique_fd mWakeEventFd;  // immutable
     Mutex mLock;
 
     Vector<MessageEnvelope> mMessageEnvelopes; // guarded by mLock
@@ -457,7 +459,7 @@
     // any use of it is racy anyway.
     volatile bool mPolling;
 
-    int mEpollFd; // guarded by mLock but only modified on the looper thread
+    android::base::unique_fd mEpollFd;  // guarded by mLock but only modified on the looper thread
     bool mEpollRebuildRequired; // guarded by mLock
 
     // Locked list of file descriptor monitoring requests.
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 5e5e7af..9536fc7 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -33,6 +33,10 @@
 #include <memory>
 #include <vector>
 
+#if defined(__BIONIC__)
+#include <android/fdsan.h>
+#endif
+
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/macros.h>  // TEMP_FAILURE_RETRY may or may not be in unistd
@@ -165,6 +169,44 @@
   return 0;
 }
 
+ZipArchive::ZipArchive(const int fd, bool assume_ownership)
+    : mapped_zip(fd),
+      close_file(assume_ownership),
+      directory_offset(0),
+      central_directory(),
+      directory_map(new android::FileMap()),
+      num_entries(0),
+      hash_table_size(0),
+      hash_table(nullptr) {
+#if defined(__BIONIC__)
+  if (assume_ownership) {
+    android_fdsan_exchange_owner_tag(fd, 0, reinterpret_cast<uint64_t>(this));
+  }
+#endif
+}
+
+ZipArchive::ZipArchive(void* address, size_t length)
+    : mapped_zip(address, length),
+      close_file(false),
+      directory_offset(0),
+      central_directory(),
+      directory_map(new android::FileMap()),
+      num_entries(0),
+      hash_table_size(0),
+      hash_table(nullptr) {}
+
+ZipArchive::~ZipArchive() {
+  if (close_file && mapped_zip.GetFileDescriptor() >= 0) {
+#if defined(__BIONIC__)
+    android_fdsan_close_with_tag(mapped_zip.GetFileDescriptor(), reinterpret_cast<uint64_t>(this));
+#else
+    close(mapped_zip.GetFileDescriptor());
+#endif
+  }
+
+  free(hash_table);
+}
+
 static int32_t MapCentralDirectory0(const char* debug_file_name, ZipArchive* archive,
                                     off64_t file_length, off64_t read_amount, uint8_t* scan_buffer) {
   const off64_t search_start = file_length - read_amount;
diff --git a/libziparchive/zip_archive_private.h b/libziparchive/zip_archive_private.h
index 18e0229..0a73300 100644
--- a/libziparchive/zip_archive_private.h
+++ b/libziparchive/zip_archive_private.h
@@ -156,33 +156,9 @@
   uint32_t hash_table_size;
   ZipString* hash_table;
 
-  ZipArchive(const int fd, bool assume_ownership)
-      : mapped_zip(fd),
-        close_file(assume_ownership),
-        directory_offset(0),
-        central_directory(),
-        directory_map(new android::FileMap()),
-        num_entries(0),
-        hash_table_size(0),
-        hash_table(nullptr) {}
-
-  ZipArchive(void* address, size_t length)
-      : mapped_zip(address, length),
-        close_file(false),
-        directory_offset(0),
-        central_directory(),
-        directory_map(new android::FileMap()),
-        num_entries(0),
-        hash_table_size(0),
-        hash_table(nullptr) {}
-
-  ~ZipArchive() {
-    if (close_file && mapped_zip.GetFileDescriptor() >= 0) {
-      close(mapped_zip.GetFileDescriptor());
-    }
-
-    free(hash_table);
-  }
+  ZipArchive(const int fd, bool assume_ownership);
+  ZipArchive(void* address, size_t length);
+  ~ZipArchive();
 
   bool InitializeCentralDirectory(const char* debug_file_name, off64_t cd_start_offset,
                                   size_t cd_size);