Merge "ueventd: populate /dev/block/mapper link"
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp
index 14cdb69..8c33ca5 100644
--- a/adb/daemon/usb.cpp
+++ b/adb/daemon/usb.cpp
@@ -304,33 +304,57 @@
 
                 switch (event.type) {
                     case FUNCTIONFS_BIND:
-                        CHECK(!bound) << "received FUNCTIONFS_BIND while already bound?";
-                        CHECK(!enabled) << "received FUNCTIONFS_BIND while already enabled?";
-                        bound = true;
+                        if (bound) {
+                            LOG(WARNING) << "received FUNCTIONFS_BIND while already bound?";
+                            running = false;
+                        }
 
+                        if (enabled) {
+                            LOG(WARNING) << "received FUNCTIONFS_BIND while already enabled?";
+                            running = false;
+                        }
+
+                        bound = true;
                         break;
 
                     case FUNCTIONFS_ENABLE:
-                        CHECK(bound) << "received FUNCTIONFS_ENABLE while not bound?";
-                        CHECK(!enabled) << "received FUNCTIONFS_ENABLE while already enabled?";
-                        enabled = true;
+                        if (!bound) {
+                            LOG(WARNING) << "received FUNCTIONFS_ENABLE while not bound?";
+                            running = false;
+                        }
 
+                        if (enabled) {
+                            LOG(WARNING) << "received FUNCTIONFS_ENABLE while already enabled?";
+                            running = false;
+                        }
+
+                        enabled = true;
                         StartWorker();
                         break;
 
                     case FUNCTIONFS_DISABLE:
-                        CHECK(bound) << "received FUNCTIONFS_DISABLE while not bound?";
-                        CHECK(enabled) << "received FUNCTIONFS_DISABLE while not enabled?";
-                        enabled = false;
+                        if (!bound) {
+                            LOG(WARNING) << "received FUNCTIONFS_DISABLE while not bound?";
+                        }
 
+                        if (!enabled) {
+                            LOG(WARNING) << "received FUNCTIONFS_DISABLE while not enabled?";
+                        }
+
+                        enabled = false;
                         running = false;
                         break;
 
                     case FUNCTIONFS_UNBIND:
-                        CHECK(!enabled) << "received FUNCTIONFS_UNBIND while still enabled?";
-                        CHECK(bound) << "received FUNCTIONFS_UNBIND when not bound?";
-                        bound = false;
+                        if (enabled) {
+                            LOG(WARNING) << "received FUNCTIONFS_UNBIND while still enabled?";
+                        }
 
+                        if (!bound) {
+                            LOG(WARNING) << "received FUNCTIONFS_UNBIND when not bound?";
+                        }
+
+                        bound = false;
                         running = false;
                         break;
                 }
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index ba6b9eb..045bb48 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -1602,14 +1602,6 @@
     return true;
 }
 
-std::string fs_mgr_get_verity_device_name(const FstabEntry& entry) {
-    if (entry.mount_point == "/") {
-        // In AVB, the dm device name is vroot instead of system.
-        return entry.fs_mgr_flags.avb ? "vroot" : "system";
-    }
-    return Basename(entry.mount_point);
-}
-
 bool fs_mgr_is_verity_enabled(const FstabEntry& entry) {
     if (!entry.fs_mgr_flags.verify && !entry.fs_mgr_flags.avb) {
         return false;
@@ -1617,7 +1609,7 @@
 
     DeviceMapper& dm = DeviceMapper::Instance();
 
-    std::string mount_point = fs_mgr_get_verity_device_name(entry);
+    std::string mount_point = GetVerityDeviceName(entry);
     if (dm.GetState(mount_point) == DmDeviceState::INVALID) {
         return false;
     }
@@ -1646,7 +1638,7 @@
     }
 
     DeviceMapper& dm = DeviceMapper::Instance();
-    std::string device = fs_mgr_get_verity_device_name(entry);
+    std::string device = GetVerityDeviceName(entry);
 
     std::vector<DeviceMapper::TargetInfo> table;
     if (dm.GetState(device) == DmDeviceState::INVALID || !dm.GetTableInfo(device, &table)) {
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 2f1e41f..f6f6f50 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -768,6 +768,17 @@
     return system;
 }
 
+std::string GetVerityDeviceName(const FstabEntry& entry) {
+    std::string base_device;
+    if (entry.mount_point == "/") {
+        // In AVB, the dm device name is vroot instead of system.
+        base_device = entry.fs_mgr_flags.avb ? "vroot" : "system";
+    } else {
+        base_device = android::base::Basename(entry.mount_point);
+    }
+    return base_device + "-verity";
+}
+
 }  // namespace fs_mgr
 }  // namespace android
 
diff --git a/fs_mgr/fs_mgr_remount.cpp b/fs_mgr/fs_mgr_remount.cpp
index 24044d8..093d44d 100644
--- a/fs_mgr/fs_mgr_remount.cpp
+++ b/fs_mgr/fs_mgr_remount.cpp
@@ -340,6 +340,7 @@
                 blk_device = rentry.blk_device;
                 break;
             }
+            // Find overlayfs mount point?
             if ((mount_point == "/") && (rentry.mount_point == "/system")) {
                 blk_device = rentry.blk_device;
                 mount_point = "/system";
@@ -352,6 +353,12 @@
         }
         fs_mgr_set_blk_ro(blk_device, false);
 
+        // Find system-as-root mount point?
+        if ((mount_point == "/system") && !GetEntryForMountPoint(&mounts, mount_point) &&
+            GetEntryForMountPoint(&mounts, "/")) {
+            mount_point = "/";
+        }
+
         // Now remount!
         if (::mount(blk_device.c_str(), mount_point.c_str(), entry.fs_type.c_str(), MS_REMOUNT,
                     nullptr) == 0) {
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h
index e811447..88da41d 100644
--- a/fs_mgr/include_fstab/fstab/fstab.h
+++ b/fs_mgr/include_fstab/fstab/fstab.h
@@ -107,5 +107,10 @@
 
 std::set<std::string> GetBootDevices();
 
+// Return the name of the dm-verity device for the given fstab entry. This does
+// not check whether the device is valid or exists; it merely returns the
+// expected name.
+std::string GetVerityDeviceName(const FstabEntry& entry);
+
 }  // namespace fs_mgr
 }  // namespace android
diff --git a/fs_mgr/libfs_avb/avb_util.cpp b/fs_mgr/libfs_avb/avb_util.cpp
index f4e4d4e..d9650f3 100644
--- a/fs_mgr/libfs_avb/avb_util.cpp
+++ b/fs_mgr/libfs_avb/avb_util.cpp
@@ -105,14 +105,15 @@
     table.set_readonly(true);
 
     const std::string mount_point(Basename(fstab_entry->mount_point));
+    const std::string device_name(GetVerityDeviceName(*fstab_entry));
     android::dm::DeviceMapper& dm = android::dm::DeviceMapper::Instance();
-    if (!dm.CreateDevice(mount_point, table)) {
+    if (!dm.CreateDevice(device_name, table)) {
         LERROR << "Couldn't create verity device!";
         return false;
     }
 
     std::string dev_path;
-    if (!dm.GetDmDevicePathByName(mount_point, &dev_path)) {
+    if (!dm.GetDmDevicePathByName(device_name, &dev_path)) {
         LERROR << "Couldn't get verity device path!";
         return false;
     }
diff --git a/libcutils/android_reboot.cpp b/libcutils/android_reboot.cpp
index ce41cd3..e0def71 100644
--- a/libcutils/android_reboot.cpp
+++ b/libcutils/android_reboot.cpp
@@ -23,12 +23,12 @@
 
 #define TAG "android_reboot"
 
-int android_reboot(int cmd, int /*flags*/, const char* arg) {
+int android_reboot(unsigned cmd, int /*flags*/, const char* arg) {
     int ret;
     const char* restart_cmd = NULL;
     char* prop_value;
 
-    switch (static_cast<unsigned>(cmd)) {
+    switch (cmd) {
         case ANDROID_RB_RESTART:  // deprecated
         case ANDROID_RB_RESTART2:
             restart_cmd = "reboot";
diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp
index a3df380..6217bc8 100644
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -91,7 +91,7 @@
     { 00750, AID_ROOT,         AID_SHELL,        0, "sbin" },
     { 00777, AID_ROOT,         AID_ROOT,         0, "sdcard" },
     { 00751, AID_ROOT,         AID_SDCARD_R,     0, "storage" },
-    { 00755, AID_ROOT,         AID_SHELL,        0, "system/bin" },
+    { 00751, AID_ROOT,         AID_SHELL,        0, "system/bin" },
     { 00755, AID_ROOT,         AID_ROOT,         0, "system/etc/ppp" },
     { 00755, AID_ROOT,         AID_SHELL,        0, "system/vendor" },
     { 00751, AID_ROOT,         AID_SHELL,        0, "system/xbin" },
diff --git a/libcutils/include/cutils/android_reboot.h b/libcutils/include/cutils/android_reboot.h
index 99030ed..cd27eef 100644
--- a/libcutils/include/cutils/android_reboot.h
+++ b/libcutils/include/cutils/android_reboot.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef __CUTILS_ANDROID_REBOOT_H__
-#define __CUTILS_ANDROID_REBOOT_H__
+#pragma once
 
 #include <sys/cdefs.h>
 
@@ -36,10 +35,8 @@
 /* Reboot or shutdown the system.
  * This call uses ANDROID_RB_PROPERTY to request reboot to init process.
  * Due to that, process calling this should have proper selinux permission
- * to write to the property. Otherwise, the call will fail.
+ * to write to the property or the call will fail.
  */
-int android_reboot(int cmd, int flags, const char *arg);
+int android_reboot(unsigned cmd, int flags, const char* arg);
 
 __END_DECLS
-
-#endif /* __CUTILS_ANDROID_REBOOT_H__ */
diff --git a/liblog/Android.bp b/liblog/Android.bp
index 9b41ebe..da475cb 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -139,6 +139,5 @@
 llndk_library {
     name: "liblog",
     symbol_file: "liblog.map.txt",
-    unversioned: true,
     export_include_dirs: ["include_vndk"],
 }
diff --git a/libstats/include/stats_event_list.h b/libstats/include/stats_event_list.h
index b5bc5af..845a197 100644
--- a/libstats/include/stats_event_list.h
+++ b/libstats/include/stats_event_list.h
@@ -18,15 +18,18 @@
 #define ANDROID_STATS_LOG_STATS_EVENT_LIST_H
 
 #include <log/log_event_list.h>
+#include <sys/uio.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 void reset_log_context(android_log_context ctx);
 int write_to_logger(android_log_context context, log_id_t id);
-void note_log_drop(int error);
+void note_log_drop(int error, int atom_tag);
 void stats_log_close();
 int android_log_write_char_array(android_log_context ctx, const char* value, size_t len);
+extern int (*write_to_statsd)(struct iovec* vec, size_t nr);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/libstats/stats_event_list.c b/libstats/stats_event_list.c
index 5b90361..ae12cbe 100644
--- a/libstats/stats_event_list.c
+++ b/libstats/stats_event_list.c
@@ -41,7 +41,7 @@
 extern struct android_log_transport_write statsdLoggerWrite;
 
 static int __write_to_statsd_init(struct iovec* vec, size_t nr);
-static int (*write_to_statsd)(struct iovec* vec, size_t nr) = __write_to_statsd_init;
+int (*write_to_statsd)(struct iovec* vec, size_t nr) = __write_to_statsd_init;
 
 // Similar to create_android_logger(), but instead of allocation a new buffer,
 // this function resets the buffer for resuse.
@@ -120,8 +120,8 @@
     return retValue;
 }
 
-void note_log_drop(int error) {
-    statsdLoggerWrite.noteDrop(error);
+void note_log_drop(int error, int tag) {
+    statsdLoggerWrite.noteDrop(error, tag);
 }
 
 void stats_log_close() {
diff --git a/libstats/statsd_writer.c b/libstats/statsd_writer.c
index f5be95c..b778f92 100644
--- a/libstats/statsd_writer.c
+++ b/libstats/statsd_writer.c
@@ -47,9 +47,18 @@
 #endif
 #endif
 
+#ifndef htole64
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define htole64(x) (x)
+#else
+#define htole64(x) __bswap_64(x)
+#endif
+#endif
+
 static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
 static atomic_int dropped = 0;
 static atomic_int log_error = 0;
+static atomic_int atom_tag = 0;
 
 void statsd_writer_init_lock() {
     /*
@@ -152,9 +161,10 @@
     return 1;
 }
 
-static void statsdNoteDrop(int error) {
+static void statsdNoteDrop(int error, int tag) {
     atomic_fetch_add_explicit(&dropped, 1, memory_order_relaxed);
     atomic_exchange_explicit(&log_error, error, memory_order_relaxed);
+    atomic_exchange_explicit(&atom_tag, tag, memory_order_relaxed);
 }
 
 static int statsdWrite(struct timespec* ts, struct iovec* vec, size_t nr) {
@@ -203,12 +213,17 @@
     if (sock >= 0) {
         int32_t snapshot = atomic_exchange_explicit(&dropped, 0, memory_order_relaxed);
         if (snapshot) {
-            android_log_event_int_t buffer;
+            android_log_event_long_t buffer;
             header.id = LOG_ID_STATS;
             // store the last log error in the tag field. This tag field is not used by statsd.
             buffer.header.tag = htole32(atomic_load(&log_error));
-            buffer.payload.type = EVENT_TYPE_INT;
-            buffer.payload.data = htole32(snapshot);
+            buffer.payload.type = EVENT_TYPE_LONG;
+            // format:
+            // |atom_tag|dropped_count|
+            int64_t composed_long = atomic_load(&atom_tag);
+            // Send 2 int32's via an int64.
+            composed_long = ((composed_long << 32) | ((int64_t)snapshot));
+            buffer.payload.data = htole64(composed_long);
 
             newVec[headerLength].iov_base = &buffer;
             newVec[headerLength].iov_len = sizeof(buffer);
diff --git a/libstats/statsd_writer.h b/libstats/statsd_writer.h
index 4fc3f8b..fe2d37c 100644
--- a/libstats/statsd_writer.h
+++ b/libstats/statsd_writer.h
@@ -39,7 +39,7 @@
     /* write log to transport, returns number of bytes propagated, or -errno */
     int (*write)(struct timespec* ts, struct iovec* vec, size_t nr);
     /* note one log drop */
-    void (*noteDrop)(int error);
+    void (*noteDrop)(int error, int tag);
 };
 
 #endif  // ANDROID_STATS_LOG_STATS_WRITER_H