Merge "Update native_window_get_frame_timestamps args"
diff --git a/adb/Android.mk b/adb/Android.mk
index fab8c87..49e492c 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -336,7 +336,7 @@
     libfec_rs \
     libselinux \
     liblog \
-    libext4_utils_static \
+    libext4_utils \
     libsquashfs_utils \
     libcutils \
     libbase \
diff --git a/adb/adb.h b/adb/adb.h
index 19f09a3..7db3b15 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -218,8 +218,6 @@
 #define CHUNK_SIZE (64*1024)
 
 #if !ADB_HOST
-#define USB_ADB_PATH     "/dev/android_adb"
-
 #define USB_FFS_ADB_PATH  "/dev/usb-ffs/adb/"
 #define USB_FFS_ADB_EP(x) USB_FFS_ADB_PATH#x
 
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index a064de2..2befa0c 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -91,9 +91,9 @@
         "global options:\n"
         " -a         listen on all network interfaces, not just localhost\n"
         " -d         use USB device (error if multiple devices connected)\n"
-        " -e         use emulator (error if multiple emulators running)\n"
+        " -e         use TCP/IP device (error if multiple TCP/IP devices available)\n"
         " -s SERIAL\n"
-        "     use device/emulator with given serial number (overrides $ANDROID_SERIAL)\n"
+        "     use device with given serial number (overrides $ANDROID_SERIAL)\n"
         " -p PRODUCT\n"
         "     name or path ('angler'/'out/target/product/angler');\n"
         "     default $ANDROID_PRODUCT_OUT\n"
diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp
index 78434a0..1a39f6a 100644
--- a/adb/daemon/main.cpp
+++ b/adb/daemon/main.cpp
@@ -170,7 +170,7 @@
     drop_privileges(server_port);
 
     bool is_usb = false;
-    if (access(USB_ADB_PATH, F_OK) == 0 || access(USB_FFS_ADB_EP0, F_OK) == 0) {
+    if (access(USB_FFS_ADB_EP0, F_OK) == 0) {
         // Listen on USB.
         usb_init();
         is_usb = true;
diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp
index 1cc7f68..a21a193 100644
--- a/adb/usb_linux_client.cpp
+++ b/adb/usb_linux_client.cpp
@@ -74,9 +74,6 @@
     void (*kick)(usb_handle *h);
     void (*close)(usb_handle *h);
 
-    // Legacy f_adb
-    int fd = -1;
-
     // FunctionFS
     int control = -1;
     int bulk_out = -1; /* "out" from the host's perspective => source for adbd */
@@ -248,141 +245,7 @@
     },
 };
 
-static void usb_adb_open_thread(void* x) {
-    struct usb_handle *usb = (struct usb_handle *)x;
-    int fd;
-
-    adb_thread_setname("usb open");
-
-    while (true) {
-        // wait until the USB device needs opening
-        std::unique_lock<std::mutex> lock(usb->lock);
-        while (!usb->open_new_connection) {
-            usb->notify.wait(lock);
-        }
-        usb->open_new_connection = false;
-        lock.unlock();
-
-        D("[ usb_thread - opening device ]");
-        do {
-            /* XXX use inotify? */
-            fd = unix_open("/dev/android_adb", O_RDWR);
-            if (fd < 0) {
-                // to support older kernels
-                fd = unix_open("/dev/android", O_RDWR);
-            }
-            if (fd < 0) {
-                std::this_thread::sleep_for(1s);
-            }
-        } while (fd < 0);
-        D("[ opening device succeeded ]");
-
-        close_on_exec(fd);
-        usb->fd = fd;
-
-        D("[ usb_thread - registering device ]");
-        register_usb_transport(usb, 0, 0, 1);
-    }
-
-    // never gets here
-    abort();
-}
-
-static int usb_adb_write(usb_handle *h, const void *data, int len)
-{
-    int n;
-
-    D("about to write (fd=%d, len=%d)", h->fd, len);
-    n = unix_write(h->fd, data, len);
-    if(n != len) {
-        D("ERROR: fd = %d, n = %d, errno = %d (%s)",
-            h->fd, n, errno, strerror(errno));
-        return -1;
-    }
-    if (h->kicked) {
-        D("usb_adb_write finished due to kicked");
-        return -1;
-    }
-    D("[ done fd=%d ]", h->fd);
-    return 0;
-}
-
-static int usb_adb_read(usb_handle *h, void *data, int len)
-{
-    D("about to read (fd=%d, len=%d)", h->fd, len);
-    while (len > 0) {
-        // The kernel implementation of adb_read in f_adb.c doesn't support
-        // reads larger then 4096 bytes. Read the data in 4096 byte chunks to
-        // avoid the issue. (The ffs implementation doesn't have this limit.)
-        int bytes_to_read = len < 4096 ? len : 4096;
-        int n = unix_read(h->fd, data, bytes_to_read);
-        if (n != bytes_to_read) {
-            D("ERROR: fd = %d, n = %d, errno = %d (%s)",
-                h->fd, n, errno, strerror(errno));
-            return -1;
-        }
-        if (h->kicked) {
-            D("usb_adb_read finished due to kicked");
-            return -1;
-        }
-        len -= n;
-        data = ((char*)data) + n;
-    }
-    D("[ done fd=%d ]", h->fd);
-    return 0;
-}
-
-static void usb_adb_kick(usb_handle *h) {
-    D("usb_kick");
-    // Other threads may be calling usb_adb_read/usb_adb_write at the same time.
-    // If we close h->fd, the file descriptor will be reused to open other files,
-    // and the read/write thread may operate on the wrong file. So instead
-    // we set the kicked flag and reopen h->fd to a dummy file here. After read/write
-    // threads finish, we close h->fd in usb_adb_close().
-    h->kicked = true;
-    TEMP_FAILURE_RETRY(dup2(dummy_fd, h->fd));
-}
-
-static void usb_adb_close(usb_handle *h) {
-    h->kicked = false;
-    adb_close(h->fd);
-    // Notify usb_adb_open_thread to open a new connection.
-    h->lock.lock();
-    h->open_new_connection = true;
-    h->lock.unlock();
-    h->notify.notify_one();
-}
-
-static void usb_adb_init()
-{
-    usb_handle* h = new usb_handle();
-
-    h->write = usb_adb_write;
-    h->read = usb_adb_read;
-    h->kick = usb_adb_kick;
-    h->close = usb_adb_close;
-
-    // Open the file /dev/android_adb_enable to trigger
-    // the enabling of the adb USB function in the kernel.
-    // We never touch this file again - just leave it open
-    // indefinitely so the kernel will know when we are running
-    // and when we are not.
-    int fd = unix_open("/dev/android_adb_enable", O_RDWR);
-    if (fd < 0) {
-       D("failed to open /dev/android_adb_enable");
-    } else {
-        close_on_exec(fd);
-    }
-
-    D("[ usb_init - starting thread ]");
-    if (!adb_thread_create(usb_adb_open_thread, h)) {
-        fatal_errno("cannot create usb thread");
-    }
-}
-
-
-static bool init_functionfs(struct usb_handle *h)
-{
+static bool init_functionfs(struct usb_handle* h) {
     ssize_t ret;
     struct desc_v1 v1_descriptor;
     struct desc_v2 v2_descriptor;
@@ -463,7 +326,7 @@
 }
 
 static void usb_ffs_open_thread(void* x) {
-    struct usb_handle *usb = (struct usb_handle *)x;
+    struct usb_handle* usb = (struct usb_handle*)x;
 
     adb_thread_setname("usb ffs open");
 
@@ -530,8 +393,7 @@
     return 0;
 }
 
-static void usb_ffs_kick(usb_handle *h)
-{
+static void usb_ffs_kick(usb_handle* h) {
     int err;
 
     err = ioctl(h->bulk_in, FUNCTIONFS_CLEAR_HALT);
@@ -553,7 +415,7 @@
     TEMP_FAILURE_RETRY(dup2(dummy_fd, h->bulk_in));
 }
 
-static void usb_ffs_close(usb_handle *h) {
+static void usb_ffs_close(usb_handle* h) {
     h->kicked = false;
     adb_close(h->bulk_out);
     adb_close(h->bulk_in);
@@ -564,8 +426,7 @@
     h->notify.notify_one();
 }
 
-static void usb_ffs_init()
-{
+static void usb_ffs_init() {
     D("[ usb_init - using FunctionFS ]");
 
     usb_handle* h = new usb_handle();
@@ -581,33 +442,25 @@
     }
 }
 
-void usb_init()
-{
+void usb_init() {
     dummy_fd = adb_open("/dev/null", O_WRONLY);
     CHECK_NE(dummy_fd, -1);
-    if (access(USB_FFS_ADB_EP0, F_OK) == 0)
-        usb_ffs_init();
-    else
-        usb_adb_init();
+    usb_ffs_init();
 }
 
-int usb_write(usb_handle *h, const void *data, int len)
-{
+int usb_write(usb_handle* h, const void* data, int len) {
     return h->write(h, data, len);
 }
 
-int usb_read(usb_handle *h, void *data, int len)
-{
+int usb_read(usb_handle* h, void* data, int len) {
     return h->read(h, data, len);
 }
 
-int usb_close(usb_handle *h)
-{
+int usb_close(usb_handle* h) {
     h->close(h);
     return 0;
 }
 
-void usb_kick(usb_handle *h)
-{
+void usb_kick(usb_handle* h) {
     h->kick(h);
 }
diff --git a/base/file_test.cpp b/base/file_test.cpp
index f741d89..ed39ce9 100644
--- a/base/file_test.cpp
+++ b/base/file_test.cpp
@@ -134,7 +134,11 @@
   // Linux doesn't allow empty symbolic links.
   std::string min("x");
   // ext2 and ext4 both have PAGE_SIZE limits.
-  std::string max(static_cast<size_t>(4096 - 1), 'x');
+  // If file encryption is enabled, there's extra overhead to store the
+  // size of the encrypted symlink target. There's also an off-by-one
+  // in current kernels (and marlin/sailfish where we're seeing this
+  // failure are still on 3.18, far from current). http://b/33306057.
+  std::string max(static_cast<size_t>(4096 - 2 - 1 - 1), 'x');
 
   TemporaryDir td;
   std::string min_path{std::string(td.path) + "/" + "min"};
diff --git a/base/include/android-base/strings.h b/base/include/android-base/strings.h
index b8a9289..f5f5c11 100644
--- a/base/include/android-base/strings.h
+++ b/base/include/android-base/strings.h
@@ -64,6 +64,9 @@
 bool EndsWith(const std::string& s, const char* suffix);
 bool EndsWithIgnoreCase(const std::string& s, const char* suffix);
 
+// Tests whether 'lhs' equals 'rhs', ignoring case.
+bool EqualsIgnoreCase(const std::string& lhs, const std::string& rhs);
+
 }  // namespace base
 }  // namespace android
 
diff --git a/base/strings.cpp b/base/strings.cpp
index 7a94ad7..46fe939 100644
--- a/base/strings.cpp
+++ b/base/strings.cpp
@@ -112,5 +112,9 @@
   return EndsWith(s, suffix, false);
 }
 
+bool EqualsIgnoreCase(const std::string& lhs, const std::string& rhs) {
+  return strcasecmp(lhs.c_str(), rhs.c_str()) == 0;
+}
+
 }  // namespace base
 }  // namespace android
diff --git a/base/strings_test.cpp b/base/strings_test.cpp
index 5fb21dd..7a65a00 100644
--- a/base/strings_test.cpp
+++ b/base/strings_test.cpp
@@ -244,3 +244,10 @@
   ASSERT_FALSE(android::base::EndsWithIgnoreCase("foobar", "OBA"));
   ASSERT_FALSE(android::base::EndsWithIgnoreCase("foobar", "FOO"));
 }
+
+TEST(strings, EqualsIgnoreCase) {
+  ASSERT_TRUE(android::base::EqualsIgnoreCase("foo", "FOO"));
+  ASSERT_TRUE(android::base::EqualsIgnoreCase("FOO", "foo"));
+  ASSERT_FALSE(android::base::EqualsIgnoreCase("foo", "bar"));
+  ASSERT_FALSE(android::base::EqualsIgnoreCase("foo", "fool"));
+}
diff --git a/debuggerd/crasher.cpp b/debuggerd/crasher.cpp
index e650f22..689f4d4 100644
--- a/debuggerd/crasher.cpp
+++ b/debuggerd/crasher.cpp
@@ -29,8 +29,8 @@
 #include <unistd.h>
 
 // We test both kinds of logging.
-#include <android/log.h>
 #include <android-base/logging.h>
+#include <log/log.h>
 
 #if defined(STATIC_CRASHER)
 #include "debuggerd/client.h"
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index 286de5b..5610cc0 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -57,8 +57,8 @@
 
 LOCAL_STATIC_LIBRARIES := \
     libziparchive \
-    libext4_utils_host \
-    libsparse_host \
+    libext4_utils \
+    libsparse \
     libutils \
     liblog \
     libz \
diff --git a/fastboot/README.md b/fastboot/README.md
new file mode 100644
index 0000000..022d34b
--- /dev/null
+++ b/fastboot/README.md
@@ -0,0 +1,453 @@
+Fastboot
+--------
+
+The fastboot protocol is a mechanism for communicating with bootloaders
+over USB or ethernet.  It is designed to be very straightforward to implement,
+to allow it to be used across a wide range of devices and from hosts running
+Linux, macOS, or Windows.
+
+
+## Basic Requirements
+
+* USB
+  * Two bulk endpoints (in, out) are required
+  * Max packet size must be 64 bytes for full-speed, 512 bytes for
+    high-speed and 1024 bytes for Super Speed USB.
+  * The protocol is entirely host-driven and synchronous (unlike the
+    multi-channel, bi-directional, asynchronous ADB protocol)
+
+* TCP or UDP
+  * Device must be reachable via IP.
+  * Device will act as the server, fastboot will be the client.
+  * Fastboot data is wrapped in a simple protocol; see below for details.
+
+
+## Transport and Framing
+
+1. Host sends a command, which is an ascii string in a single
+   packet no greater than 64 bytes.
+
+2. Client response with a single packet no greater than 64 bytes.
+   The first four bytes of the response are "OKAY", "FAIL", "DATA",
+   or "INFO".  Additional bytes may contain an (ascii) informative
+   message.
+
+   a. INFO -> the remaining 60 bytes are an informative message
+      (providing progress or diagnostic messages).  They should
+      be displayed and then step #2 repeats
+
+   b. FAIL -> the requested command failed.  The remaining 60 bytes
+      of the response (if present) provide a textual failure message
+      to present to the user.  Stop.
+
+   c. OKAY -> the requested command completed successfully.  Go to #5
+
+   d. DATA -> the requested command is ready for the data phase.
+      A DATA response packet will be 12 bytes long, in the form of
+      DATA00000000 where the 8 digit hexadecimal number represents
+      the total data size to transfer.
+
+3. Data phase.  Depending on the command, the host or client will
+   send the indicated amount of data.  Short packets are always
+   acceptable and zero-length packets are ignored.  This phase continues
+   until the client has sent or received the number of bytes indicated
+   in the "DATA" response above.
+
+4. Client responds with a single packet no greater than 64 bytes.
+   The first four bytes of the response are "OKAY", "FAIL", or "INFO".
+   Similar to #2:
+
+   a. INFO -> display the remaining 60 bytes and return to #4
+
+   b. FAIL -> display the remaining 60 bytes (if present) as a failure
+      reason and consider the command failed.  Stop.
+
+   c. OKAY -> success.  Go to #5
+
+5. Success.  Stop.
+
+
+## Example Session
+
+    Host:    "getvar:version"        request version variable
+
+    Client:  "OKAY0.4"               return version "0.4"
+
+    Host:    "getvar:nonexistant"    request some undefined variable
+
+    Client:  "FAILUnknown variable"  getvar failure; see getvar details below
+
+    Host:    "download:00001234"     request to send 0x1234 bytes of data
+
+    Client:  "DATA00001234"          ready to accept data
+
+    Host:    < 0x1234 bytes >        send data
+
+    Client:  "OKAY"                  success
+
+    Host:    "flash:bootloader"      request to flash the data to the bootloader
+
+    Client:  "INFOerasing flash"     indicate status / progress
+             "INFOwriting flash"
+             "OKAY"                  indicate success
+
+    Host:    "powerdown"             send a command
+
+    Client:  "FAILunknown command"   indicate failure
+
+
+## Command Reference
+
+* Command parameters are indicated by printf-style escape sequences.
+
+* Commands are ascii strings and sent without the quotes (which are
+  for illustration only here) and without a trailing 0 byte.
+
+* Commands that begin with a lowercase letter are reserved for this
+  specification.  OEM-specific commands should not begin with a
+  lowercase letter, to prevent incompatibilities with future specs.
+
+The various currently defined commands are:
+
+    getvar:%s          Read a config/version variable from the bootloader.
+                       The variable contents will be returned after the
+                       OKAY response. If the variable is unknown, the bootloader
+                       should return a FAIL response, optionally with an error
+                       message.
+
+                       Previous versions of this document indicated that getvar
+                       should return an empty OKAY response for unknown
+                       variables, so older devices might exhibit this behavior,
+                       but new implementations should return FAIL instead.
+
+    download:%08x      Write data to memory which will be later used
+                       by "boot", "ramdisk", "flash", etc.  The client
+                       will reply with "DATA%08x" if it has enough
+                       space in RAM or "FAIL" if not.  The size of
+                       the download is remembered.
+
+    verify:%08x        Send a digital signature to verify the downloaded
+                       data.  Required if the bootloader is "secure"
+                       otherwise "flash" and "boot" will be ignored.
+
+    flash:%s           Write the previously downloaded image to the
+                       named partition (if possible).
+
+    erase:%s           Erase the indicated partition (clear to 0xFFs)
+
+    boot               The previously downloaded data is a boot.img
+                       and should be booted according to the normal
+                       procedure for a boot.img
+
+    continue           Continue booting as normal (if possible)
+
+    reboot             Reboot the device.
+
+    reboot-bootloader
+                       Reboot back into the bootloader.
+                       Useful for upgrade processes that require upgrading
+                       the bootloader and then upgrading other partitions
+                       using the new bootloader.
+
+    powerdown          Power off the device.
+
+
+
+## Client Variables
+
+The "getvar:%s" command is used to read client variables which
+represent various information about the device and the software
+on it.
+
+The various currently defined names are:
+
+    version             Version of FastBoot protocol supported.
+                        It should be "0.4" for this document.
+
+    version-bootloader  Version string for the Bootloader.
+
+    version-baseband    Version string of the Baseband Software
+
+    product             Name of the product
+
+    serialno            Product serial number
+
+    secure              If the value is "yes", this is a secure
+                        bootloader requiring a signature before
+                        it will install or boot images.
+
+Names starting with a lowercase character are reserved by this
+specification.  OEM-specific names should not start with lowercase
+characters.
+
+
+## TCP Protocol v1
+
+The TCP protocol is designed to be a simple way to use the fastboot protocol
+over ethernet if USB is not available.
+
+The device will open a TCP server on port 5554 and wait for a fastboot client
+to connect.
+
+### Handshake
+Upon connecting, both sides will send a 4-byte handshake message to ensure they
+are speaking the same protocol. This consists of the ASCII characters "FB"
+followed by a 2-digit base-10 ASCII version number. For example, the version 1
+handshake message will be [FB01].
+
+If either side detects a malformed handshake, it should disconnect.
+
+The protocol version to use must be the minimum of the versions sent by each
+side; if either side cannot speak this protocol version, it should disconnect.
+
+### Fastboot Data
+Once the handshake is complete, fastboot data will be sent as follows:
+
+    [data_size][data]
+
+Where data\_size is an unsigned 8-byte big-endian binary value, and data is the
+fastboot packet. The 8-byte length is intended to provide future-proofing even
+though currently fastboot packets have a 4-byte maximum length.
+
+### Example
+In this example the fastboot host queries the device for two variables,
+"version" and "none".
+
+    Host    <connect to the device on port 5555>
+    Host    FB01
+    Device  FB01
+    Host    [0x00][0x00][0x00][0x00][0x00][0x00][0x00][0x0E]getvar:version
+    Device  [0x00][0x00][0x00][0x00][0x00][0x00][0x00][0x07]OKAY0.4
+    Host    [0x00][0x00][0x00][0x00][0x00][0x00][0x00][0x0B]getvar:none
+    Device  [0x00][0x00][0x00][0x00][0x00][0x00][0x00][0x14]FAILUnknown variable
+    Host    <disconnect>
+
+
+## UDP Protocol v1
+
+The UDP protocol is more complex than TCP since we must implement reliability
+to ensure no packets are lost, but the general concept of wrapping the fastboot
+protocol is the same.
+
+Overview:
+  1. As with TCP, the device will listen on UDP port 5554.
+  2. Maximum UDP packet size is negotiated during initialization.
+  3. The host drives all communication; the device may only send a packet as a
+     response to a host packet.
+  4. If the host does not receive a response in 500ms it will re-transmit.
+
+### UDP Packet format
+
+    +----------+----+-------+-------+--------------------+
+    | Byte #   | 0  |   1   | 2 - 3 |  4+                |
+    +----------+----+-------+-------+--------------------+
+    | Contents | ID | Flags | Seq # | Data               |
+    +----------+----+-------+-------+--------------------+
+
+    ID      Packet ID:
+              0x00: Error.
+              0x01: Query.
+              0x02: Initialization.
+              0x03: Fastboot.
+
+            Packet types are described in more detail below.
+
+    Flags   Packet flags: 0 0 0 0 0 0 0 C
+              C=1 indicates a continuation packet; the data is too large and will
+                  continue in the next packet.
+
+              Remaining bits are reserved for future use and must be set to 0.
+
+    Seq #   2-byte packet sequence number (big-endian). The host will increment
+            this by 1 with each new packet, and the device must provide the
+            corresponding sequence number in the response packets.
+
+    Data    Packet data, not present in all packets.
+
+### Packet Types
+
+    Query
+          The host sends a query packet once on startup to sync with the device.
+          The host will not know the current sequence number, so the device must
+          respond to all query packets regardless of sequence number.
+
+          The response data field should contain a 2-byte big-endian value
+          giving the next expected sequence number.
+
+    Init
+          The host sends an init packet once the query response is returned. The
+          device must abort any in-progress operation and prepare for a new
+          fastboot session. This message is meant to allow recovery if a
+          previous session failed, e.g. due to network error or user Ctrl+C.
+
+          The data field contains two big-endian 2-byte values, a protocol
+          version and the max UDP packet size (including the 4-byte header).
+          Both the host and device will send these values, and in each case
+          the minimum of the sent values must be used.
+
+    Fastboot
+          These packets wrap the fastboot protocol. To write, the host will
+          send a packet with fastboot data, and the device will reply with an
+          empty packet as an ACK. To read, the host will send an empty packet,
+          and the device will reply with fastboot data. The device may not give
+          any data in the ACK packet.
+
+    Error
+          The device may respond to any packet with an error packet to indicate
+          a UDP protocol error. The data field should contain an ASCII string
+          describing the error. This is the only case where a device is allowed
+          to return a packet ID other than the one sent by the host.
+
+### Packet Size
+The maximum packet size is negotiated by the host and device in the Init packet.
+Devices must support at least 512-byte packets, but packet size has a direct
+correlation with download speed, so devices are strongly suggested to support at
+least 1024-byte packets. On a local network with 0.5ms round-trip time this will
+provide transfer rates of ~2MB/s. Over WiFi it will likely be significantly
+less.
+
+Query and Initialization packets, which are sent before size negotiation is
+complete, must always be 512 bytes or less.
+
+### Packet Re-Transmission
+The host will re-transmit any packet that does not receive a response. The
+requirement of exactly one device response packet per host packet is how we
+achieve reliability and in-order delivery of packets.
+
+For simplicity of implementation, there is no windowing of multiple
+unacknowledged packets in this version of the protocol. The host will continue
+to send the same packet until a response is received. Windowing functionality
+may be implemented in future versions if necessary to increase performance.
+
+The first Query packet will only be attempted a small number of times, but
+subsequent packets will attempt to retransmit for at least 1 minute before
+giving up. This means a device may safely ignore host UDP packets for up to 1
+minute during long operations, e.g. writing to flash.
+
+### Continuation Packets
+Any packet may set the continuation flag to indicate that the data is
+incomplete. Large data such as downloading an image may require many
+continuation packets. The receiver should respond to a continuation packet with
+an empty packet to acknowledge receipt. See examples below.
+
+### Summary
+The host starts with a Query packet, then an Initialization packet, after
+which only Fastboot packets are sent. Fastboot packets may contain data from
+the host for writes, or from the device for reads, but not both.
+
+Given a next expected sequence number S and a received packet P, the device
+behavior should be:
+
+    if P is a Query packet:
+      * respond with a Query packet with S in the data field
+    else if P has sequence == S:
+      * process P and take any required action
+      * create a response packet R with the same ID and sequence as P, containing
+        any response data required.
+      * transmit R and save it in case of re-transmission
+      * increment S
+    else if P has sequence == S - 1:
+      * re-transmit the saved response packet R from above
+    else:
+      * ignore the packet
+
+### Examples
+
+In the examples below, S indicates the starting client sequence number.
+
+    Host                                    Client
+    ======================================================================
+    [Initialization, S = 0x55AA]
+    [Host: version 1, 2048-byte packets. Client: version 2, 1024-byte packets.]
+    [Resulting values to use: version = 1, max packet size = 1024]
+    ID   Flag SeqH SeqL Data                ID   Flag SeqH SeqL Data
+    ----------------------------------------------------------------------
+    0x01 0x00 0x00 0x00
+                                            0x01 0x00 0x00 0x00 0x55 0xAA
+    0x02 0x00 0x55 0xAA 0x00 0x01 0x08 0x00
+                                            0x02 0x00 0x55 0xAA 0x00 0x02 0x04 0x00
+
+    ----------------------------------------------------------------------
+    [fastboot "getvar" commands, S = 0x0001]
+    ID    Flags SeqH  SeqL  Data            ID    Flags SeqH  SeqL  Data
+    ----------------------------------------------------------------------
+    0x03  0x00  0x00  0x01  getvar:version
+                                            0x03  0x00  0x00  0x01
+    0x03  0x00  0x00  0x02
+                                            0x03  0x00  0x00  0x02  OKAY0.4
+    0x03  0x00  0x00  0x03  getvar:none
+                                            0x03  0x00  0x00  0x03
+    0x03  0x00  0x00  0x04
+                                            0x03  0x00  0x00  0x04  FAILUnknown var
+
+    ----------------------------------------------------------------------
+    [fastboot "INFO" responses, S = 0x0000]
+    ID    Flags SeqH  SeqL  Data            ID    Flags SeqH  SeqL  Data
+    ----------------------------------------------------------------------
+    0x03  0x00  0x00  0x00  <command>
+                                            0x03  0x00  0x00  0x00
+    0x03  0x00  0x00  0x01
+                                            0x03  0x00  0x00  0x01  INFOWait1
+    0x03  0x00  0x00  0x02
+                                            0x03  0x00  0x00  0x02  INFOWait2
+    0x03  0x00  0x00  0x03
+                                            0x03  0x00  0x00  0x03  OKAY
+
+    ----------------------------------------------------------------------
+    [Chunking 2100 bytes of data, max packet size = 1024, S = 0xFFFF]
+    ID   Flag SeqH SeqL Data                ID   Flag SeqH SeqL Data
+    ----------------------------------------------------------------------
+    0x03 0x00 0xFF 0xFF download:0000834
+                                            0x03 0x00 0xFF 0xFF
+    0x03 0x00 0x00 0x00
+                                            0x03 0x00 0x00 0x00 DATA0000834
+    0x03 0x01 0x00 0x01 <1020 bytes>
+                                            0x03 0x00 0x00 0x01
+    0x03 0x01 0x00 0x02 <1020 bytes>
+                                            0x03 0x00 0x00 0x02
+    0x03 0x00 0x00 0x03 <60 bytes>
+                                            0x03 0x00 0x00 0x03
+    0x03 0x00 0x00 0x04
+                                            0x03 0x00 0x00 0x04 OKAY
+
+    ----------------------------------------------------------------------
+    [Unknown ID error, S = 0x0000]
+    ID    Flags SeqH  SeqL  Data            ID    Flags SeqH  SeqL  Data
+    ----------------------------------------------------------------------
+    0x10  0x00  0x00  0x00
+                                            0x00  0x00  0x00  0x00  <error message>
+
+    ----------------------------------------------------------------------
+    [Host packet loss and retransmission, S = 0x0000]
+    ID    Flags SeqH  SeqL  Data            ID    Flags SeqH  SeqL  Data
+    ----------------------------------------------------------------------
+    0x03  0x00  0x00  0x00  getvar:version [lost]
+    0x03  0x00  0x00  0x00  getvar:version [lost]
+    0x03  0x00  0x00  0x00  getvar:version
+                                            0x03  0x00  0x00  0x00
+    0x03  0x00  0x00  0x01
+                                            0x03  0x00  0x00  0x01  OKAY0.4
+
+    ----------------------------------------------------------------------
+    [Client packet loss and retransmission, S = 0x0000]
+    ID    Flags SeqH  SeqL  Data            ID    Flags SeqH  SeqL  Data
+    ----------------------------------------------------------------------
+    0x03  0x00  0x00  0x00  getvar:version
+                                            0x03  0x00  0x00  0x00 [lost]
+    0x03  0x00  0x00  0x00  getvar:version
+                                            0x03  0x00  0x00  0x00 [lost]
+    0x03  0x00  0x00  0x00  getvar:version
+                                            0x03  0x00  0x00  0x00
+    0x03  0x00  0x00  0x01
+                                            0x03  0x00  0x00  0x01  OKAY0.4
+
+    ----------------------------------------------------------------------
+    [Host packet delayed, S = 0x0000]
+    ID    Flags SeqH  SeqL  Data            ID    Flags SeqH  SeqL  Data
+    ----------------------------------------------------------------------
+    0x03  0x00  0x00  0x00  getvar:version [delayed]
+    0x03  0x00  0x00  0x00  getvar:version
+                                            0x03  0x00  0x00  0x00
+    0x03  0x00  0x00  0x01
+                                            0x03  0x00  0x00  0x01  OKAY0.4
+    0x03  0x00  0x00  0x00  getvar:version [arrives late with old seq#, is ignored]
diff --git a/fastboot/fastboot_protocol.txt b/fastboot/fastboot_protocol.txt
deleted file mode 100644
index b12e420..0000000
--- a/fastboot/fastboot_protocol.txt
+++ /dev/null
@@ -1,449 +0,0 @@
-FastBoot  Version  0.4
-----------------------
-
-The fastboot protocol is a mechanism for communicating with bootloaders
-over USB or ethernet.  It is designed to be very straightforward to implement,
-to allow it to be used across a wide range of devices and from hosts running
-Linux, Windows, or OSX.
-
-
-Basic Requirements
-------------------
-
-* USB
-  * Two bulk endpoints (in, out) are required
-  * Max packet size must be 64 bytes for full-speed, 512 bytes for
-    high-speed and 1024 bytes for Super Speed USB.
-  * The protocol is entirely host-driven and synchronous (unlike the
-    multi-channel, bi-directional, asynchronous ADB protocol)
-
-* TCP or UDP
-  * Device must be reachable via IP.
-  * Device will act as the server, fastboot will be the client.
-  * Fastboot data is wrapped in a simple protocol; see below for details.
-
-
-Transport and Framing
----------------------
-
-1. Host sends a command, which is an ascii string in a single
-   packet no greater than 64 bytes.
-
-2. Client response with a single packet no greater than 64 bytes.
-   The first four bytes of the response are "OKAY", "FAIL", "DATA", 
-   or "INFO".  Additional bytes may contain an (ascii) informative
-   message.
-
-   a. INFO -> the remaining 60 bytes are an informative message
-      (providing progress or diagnostic messages).  They should 
-      be displayed and then step #2 repeats
-
-   b. FAIL -> the requested command failed.  The remaining 60 bytes 
-      of the response (if present) provide a textual failure message 
-      to present to the user.  Stop.
-
-   c. OKAY -> the requested command completed successfully.  Go to #5
-
-   d. DATA -> the requested command is ready for the data phase.
-      A DATA response packet will be 12 bytes long, in the form of
-      DATA00000000 where the 8 digit hexadecimal number represents
-      the total data size to transfer.
-
-3. Data phase.  Depending on the command, the host or client will 
-   send the indicated amount of data.  Short packets are always 
-   acceptable and zero-length packets are ignored.  This phase continues
-   until the client has sent or received the number of bytes indicated
-   in the "DATA" response above.
-
-4. Client responds with a single packet no greater than 64 bytes.  
-   The first four bytes of the response are "OKAY", "FAIL", or "INFO".  
-   Similar to #2:
-
-   a. INFO -> display the remaining 60 bytes and return to #4
-   
-   b. FAIL -> display the remaining 60 bytes (if present) as a failure
-      reason and consider the command failed.  Stop.
-
-   c. OKAY -> success.  Go to #5
-
-5. Success.  Stop.
-
-
-Example Session
----------------
-
-Host:    "getvar:version"        request version variable
-
-Client:  "OKAY0.4"               return version "0.4"
-
-Host:    "getvar:nonexistant"    request some undefined variable
-
-Client:  "FAILUnknown variable"  getvar failure; see getvar details below
-
-Host:    "download:00001234"     request to send 0x1234 bytes of data
-
-Client:  "DATA00001234"          ready to accept data
-
-Host:    < 0x1234 bytes >        send data
-
-Client:  "OKAY"                  success
-
-Host:    "flash:bootloader"      request to flash the data to the bootloader
-
-Client:  "INFOerasing flash"     indicate status / progress
-         "INFOwriting flash"
-         "OKAY"                  indicate success
-
-Host:    "powerdown"             send a command
-
-Client:  "FAILunknown command"   indicate failure
-
-
-Command Reference
------------------
-
-* Command parameters are indicated by printf-style escape sequences.
-
-* Commands are ascii strings and sent without the quotes (which are
-  for illustration only here) and without a trailing 0 byte.
-
-* Commands that begin with a lowercase letter are reserved for this
-  specification.  OEM-specific commands should not begin with a 
-  lowercase letter, to prevent incompatibilities with future specs.
-
- "getvar:%s"           Read a config/version variable from the bootloader.
-                       The variable contents will be returned after the
-                       OKAY response. If the variable is unknown, the bootloader
-                       should return a FAIL response, optionally with an error
-                       message.
-
-                       Previous versions of this document indicated that getvar
-                       should return an empty OKAY response for unknown
-                       variables, so older devices might exhibit this behavior,
-                       but new implementations should return FAIL instead.
-
- "download:%08x"       Write data to memory which will be later used
-                       by "boot", "ramdisk", "flash", etc.  The client
-                       will reply with "DATA%08x" if it has enough 
-                       space in RAM or "FAIL" if not.  The size of
-                       the download is remembered.
-
-  "verify:%08x"        Send a digital signature to verify the downloaded
-                       data.  Required if the bootloader is "secure"
-                       otherwise "flash" and "boot" will be ignored.
-
-  "flash:%s"           Write the previously downloaded image to the
-                       named partition (if possible).
-
-  "erase:%s"           Erase the indicated partition (clear to 0xFFs)
-
-  "boot"               The previously downloaded data is a boot.img
-                       and should be booted according to the normal
-                       procedure for a boot.img
-
-  "continue"           Continue booting as normal (if possible)
-
-  "reboot"             Reboot the device.
-
-  "reboot-bootloader"  Reboot back into the bootloader.
-                       Useful for upgrade processes that require upgrading
-                       the bootloader and then upgrading other partitions
-                       using the new bootloader.
-
-  "powerdown"          Power off the device.
-
-
-
-Client Variables
-----------------
-
-The "getvar:%s" command is used to read client variables which
-represent various information about the device and the software
-on it.
-
-The various currently defined names are:
-
-  version             Version of FastBoot protocol supported.
-                      It should be "0.4" for this document.
-
-  version-bootloader  Version string for the Bootloader.
-
-  version-baseband    Version string of the Baseband Software
-
-  product             Name of the product
-
-  serialno            Product serial number
-
-  secure              If the value is "yes", this is a secure
-                      bootloader requiring a signature before
-                      it will install or boot images.
-
-Names starting with a lowercase character are reserved by this
-specification.  OEM-specific names should not start with lowercase
-characters.
-
-
-TCP Protocol v1
----------------
-
-The TCP protocol is designed to be a simple way to use the fastboot protocol
-over ethernet if USB is not available.
-
-The device will open a TCP server on port 5554 and wait for a fastboot client
-to connect.
-
--- Handshake --
-Upon connecting, both sides will send a 4-byte handshake message to ensure they
-are speaking the same protocol. This consists of the ASCII characters "FB"
-followed by a 2-digit base-10 ASCII version number. For example, the version 1
-handshake message will be [FB01].
-
-If either side detects a malformed handshake, it should disconnect.
-
-The protocol version to use must be the minimum of the versions sent by each
-side; if either side cannot speak this protocol version, it should disconnect.
-
--- Fastboot Data --
-Once the handshake is complete, fastboot data will be sent as follows:
-
-  [data_size][data]
-
-Where data_size is an unsigned 8-byte big-endian binary value, and data is the
-fastboot packet. The 8-byte length is intended to provide future-proofing even
-though currently fastboot packets have a 4-byte maximum length.
-
--- Example --
-In this example the fastboot host queries the device for two variables,
-"version" and "none".
-
-Host    <connect to the device on port 5555>
-Host    FB01
-Device  FB01
-Host    [0x00][0x00][0x00][0x00][0x00][0x00][0x00][0x0E]getvar:version
-Device  [0x00][0x00][0x00][0x00][0x00][0x00][0x00][0x07]OKAY0.4
-Host    [0x00][0x00][0x00][0x00][0x00][0x00][0x00][0x0B]getvar:none
-Device  [0x00][0x00][0x00][0x00][0x00][0x00][0x00][0x14]FAILUnknown variable
-Host    <disconnect>
-
-
-UDP Protocol v1
----------------
-
-The UDP protocol is more complex than TCP since we must implement reliability
-to ensure no packets are lost, but the general concept of wrapping the fastboot
-protocol is the same.
-
-Overview:
-  1. As with TCP, the device will listen on UDP port 5554.
-  2. Maximum UDP packet size is negotiated during initialization.
-  3. The host drives all communication; the device may only send a packet as a
-     response to a host packet.
-  4. If the host does not receive a response in 500ms it will re-transmit.
-
--- UDP Packet format --
-  +----------+----+-------+-------+--------------------+
-  | Byte #   | 0  |   1   | 2 - 3 |  4+                |
-  +----------+----+-------+-------+--------------------+
-  | Contents | ID | Flags | Seq # | Data               |
-  +----------+----+-------+-------+--------------------+
-
-  ID      Packet ID:
-            0x00: Error.
-            0x01: Query.
-            0x02: Initialization.
-            0x03: Fastboot.
-
-          Packet types are described in more detail below.
-
-  Flags   Packet flags: 0 0 0 0 0 0 0 C
-            C=1 indicates a continuation packet; the data is too large and will
-                continue in the next packet.
-
-            Remaining bits are reserved for future use and must be set to 0.
-
-  Seq #   2-byte packet sequence number (big-endian). The host will increment
-          this by 1 with each new packet, and the device must provide the
-          corresponding sequence number in the response packets.
-
-  Data    Packet data, not present in all packets.
-
--- Packet Types --
-Query     The host sends a query packet once on startup to sync with the device.
-          The host will not know the current sequence number, so the device must
-          respond to all query packets regardless of sequence number.
-
-          The response data field should contain a 2-byte big-endian value
-          giving the next expected sequence number.
-
-Init      The host sends an init packet once the query response is returned. The
-          device must abort any in-progress operation and prepare for a new
-          fastboot session. This message is meant to allow recovery if a
-          previous session failed, e.g. due to network error or user Ctrl+C.
-
-          The data field contains two big-endian 2-byte values, a protocol
-          version and the max UDP packet size (including the 4-byte header).
-          Both the host and device will send these values, and in each case
-          the minimum of the sent values must be used.
-
-Fastboot  These packets wrap the fastboot protocol. To write, the host will
-          send a packet with fastboot data, and the device will reply with an
-          empty packet as an ACK. To read, the host will send an empty packet,
-          and the device will reply with fastboot data. The device may not give
-          any data in the ACK packet.
-
-Error     The device may respond to any packet with an error packet to indicate
-          a UDP protocol error. The data field should contain an ASCII string
-          describing the error. This is the only case where a device is allowed
-          to return a packet ID other than the one sent by the host.
-
--- Packet Size --
-The maximum packet size is negotiated by the host and device in the Init packet.
-Devices must support at least 512-byte packets, but packet size has a direct
-correlation with download speed, so devices are strongly suggested to support at
-least 1024-byte packets. On a local network with 0.5ms round-trip time this will
-provide transfer rates of ~2MB/s. Over WiFi it will likely be significantly
-less.
-
-Query and Initialization packets, which are sent before size negotiation is
-complete, must always be 512 bytes or less.
-
--- Packet Re-Transmission --
-The host will re-transmit any packet that does not receive a response. The
-requirement of exactly one device response packet per host packet is how we
-achieve reliability and in-order delivery of packets.
-
-For simplicity of implementation, there is no windowing of multiple
-unacknowledged packets in this version of the protocol. The host will continue
-to send the same packet until a response is received. Windowing functionality
-may be implemented in future versions if necessary to increase performance.
-
-The first Query packet will only be attempted a small number of times, but
-subsequent packets will attempt to retransmit for at least 1 minute before
-giving up. This means a device may safely ignore host UDP packets for up to 1
-minute during long operations, e.g. writing to flash.
-
--- Continuation Packets --
-Any packet may set the continuation flag to indicate that the data is
-incomplete. Large data such as downloading an image may require many
-continuation packets. The receiver should respond to a continuation packet with
-an empty packet to acknowledge receipt. See examples below.
-
--- Summary --
-The host starts with a Query packet, then an Initialization packet, after
-which only Fastboot packets are sent. Fastboot packets may contain data from
-the host for writes, or from the device for reads, but not both.
-
-Given a next expected sequence number S and a received packet P, the device
-behavior should be:
-  if P is a Query packet:
-    * respond with a Query packet with S in the data field
-  else if P has sequence == S:
-    * process P and take any required action
-    * create a response packet R with the same ID and sequence as P, containing
-      any response data required.
-    * transmit R and save it in case of re-transmission
-    * increment S
-  else if P has sequence == S - 1:
-    * re-transmit the saved response packet R from above
-  else:
-    * ignore the packet
-
--- Examples --
-In the examples below, S indicates the starting client sequence number.
-
-Host                                    Client
-======================================================================
-[Initialization, S = 0x55AA]
-[Host: version 1, 2048-byte packets. Client: version 2, 1024-byte packets.]
-[Resulting values to use: version = 1, max packet size = 1024]
-ID   Flag SeqH SeqL Data                ID   Flag SeqH SeqL Data
-----------------------------------------------------------------------
-0x01 0x00 0x00 0x00
-                                        0x01 0x00 0x00 0x00 0x55 0xAA
-0x02 0x00 0x55 0xAA 0x00 0x01 0x08 0x00
-                                        0x02 0x00 0x55 0xAA 0x00 0x02 0x04 0x00
-
-----------------------------------------------------------------------
-[fastboot "getvar" commands, S = 0x0001]
-ID    Flags SeqH  SeqL  Data            ID    Flags SeqH  SeqL  Data
-----------------------------------------------------------------------
-0x03  0x00  0x00  0x01  getvar:version
-                                        0x03  0x00  0x00  0x01
-0x03  0x00  0x00  0x02
-                                        0x03  0x00  0x00  0x02  OKAY0.4
-0x03  0x00  0x00  0x03  getvar:none
-                                        0x03  0x00  0x00  0x03
-0x03  0x00  0x00  0x04
-                                        0x03  0x00  0x00  0x04  FAILUnknown var
-
-----------------------------------------------------------------------
-[fastboot "INFO" responses, S = 0x0000]
-ID    Flags SeqH  SeqL  Data            ID    Flags SeqH  SeqL  Data
-----------------------------------------------------------------------
-0x03  0x00  0x00  0x00  <command>
-                                        0x03  0x00  0x00  0x00
-0x03  0x00  0x00  0x01
-                                        0x03  0x00  0x00  0x01  INFOWait1
-0x03  0x00  0x00  0x02
-                                        0x03  0x00  0x00  0x02  INFOWait2
-0x03  0x00  0x00  0x03
-                                        0x03  0x00  0x00  0x03  OKAY
-
-----------------------------------------------------------------------
-[Chunking 2100 bytes of data, max packet size = 1024, S = 0xFFFF]
-ID   Flag SeqH SeqL Data                ID   Flag SeqH SeqL Data
-----------------------------------------------------------------------
-0x03 0x00 0xFF 0xFF download:0000834
-                                        0x03 0x00 0xFF 0xFF
-0x03 0x00 0x00 0x00
-                                        0x03 0x00 0x00 0x00 DATA0000834
-0x03 0x01 0x00 0x01 <1020 bytes>
-                                        0x03 0x00 0x00 0x01
-0x03 0x01 0x00 0x02 <1020 bytes>
-                                        0x03 0x00 0x00 0x02
-0x03 0x00 0x00 0x03 <60 bytes>
-                                        0x03 0x00 0x00 0x03
-0x03 0x00 0x00 0x04
-                                        0x03 0x00 0x00 0x04 OKAY
-
-----------------------------------------------------------------------
-[Unknown ID error, S = 0x0000]
-ID    Flags SeqH  SeqL  Data            ID    Flags SeqH  SeqL  Data
-----------------------------------------------------------------------
-0x10  0x00  0x00  0x00
-                                        0x00  0x00  0x00  0x00  <error message>
-
-----------------------------------------------------------------------
-[Host packet loss and retransmission, S = 0x0000]
-ID    Flags SeqH  SeqL  Data            ID    Flags SeqH  SeqL  Data
-----------------------------------------------------------------------
-0x03  0x00  0x00  0x00  getvar:version [lost]
-0x03  0x00  0x00  0x00  getvar:version [lost]
-0x03  0x00  0x00  0x00  getvar:version
-                                        0x03  0x00  0x00  0x00
-0x03  0x00  0x00  0x01
-                                        0x03  0x00  0x00  0x01  OKAY0.4
-
-----------------------------------------------------------------------
-[Client packet loss and retransmission, S = 0x0000]
-ID    Flags SeqH  SeqL  Data            ID    Flags SeqH  SeqL  Data
-----------------------------------------------------------------------
-0x03  0x00  0x00  0x00  getvar:version
-                                        0x03  0x00  0x00  0x00 [lost]
-0x03  0x00  0x00  0x00  getvar:version
-                                        0x03  0x00  0x00  0x00 [lost]
-0x03  0x00  0x00  0x00  getvar:version
-                                        0x03  0x00  0x00  0x00
-0x03  0x00  0x00  0x01
-                                        0x03  0x00  0x00  0x01  OKAY0.4
-
-----------------------------------------------------------------------
-[Host packet delayed, S = 0x0000]
-ID    Flags SeqH  SeqL  Data            ID    Flags SeqH  SeqL  Data
-----------------------------------------------------------------------
-0x03  0x00  0x00  0x00  getvar:version [delayed]
-0x03  0x00  0x00  0x00  getvar:version
-                                        0x03  0x00  0x00  0x00
-0x03  0x00  0x00  0x01
-                                        0x03  0x00  0x00  0x01  OKAY0.4
-0x03  0x00  0x00  0x00  getvar:version [arrives late with old seq#, is ignored]
diff --git a/fs_mgr/Android.mk b/fs_mgr/Android.mk
index 8997cab..8d5b51b 100644
--- a/fs_mgr/Android.mk
+++ b/fs_mgr/Android.mk
@@ -9,7 +9,7 @@
     libbase \
     libcrypto_utils \
     libcrypto \
-    libext4_utils_static \
+    libext4_utils \
     libsquashfs_utils \
     libselinux
 
@@ -18,6 +18,7 @@
 LOCAL_SANITIZE := integer
 LOCAL_SRC_FILES:= \
     fs_mgr.c \
+    fs_mgr_dm_ioctl.cpp \
     fs_mgr_format.c \
     fs_mgr_fstab.c \
     fs_mgr_slotselect.c \
@@ -26,7 +27,6 @@
     $(LOCAL_PATH)/include \
     system/vold \
     system/extras/ext4_utils \
-    external/openssl/include \
     bootable/recovery
 LOCAL_MODULE:= libfs_mgr
 LOCAL_STATIC_LIBRARIES := $(common_static_libraries)
@@ -57,7 +57,7 @@
     libcutils \
     liblog \
     libc \
-    libsparse_static \
+    libsparse \
     libz \
     libselinux
 LOCAL_CXX_STL := libc++_static
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index 9348e61..e699b71 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -646,6 +646,17 @@
     }
 }
 
+int fs_mgr_test_access(const char *device) {
+    int tries = 25;
+    while (tries--) {
+        if (!access(device, F_OK) || errno != ENOENT) {
+            return 0;
+        }
+        usleep(40 * 1000);
+    }
+    return -1;
+}
+
 /* When multiple fstab records share the same mount_point, it will
  * try to mount each one in turn, and ignore any duplicates after a
  * first successful mount.
diff --git a/fs_mgr/fs_mgr_dm_ioctl.cpp b/fs_mgr/fs_mgr_dm_ioctl.cpp
new file mode 100644
index 0000000..75ce621
--- /dev/null
+++ b/fs_mgr/fs_mgr_dm_ioctl.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2016 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 <errno.h>
+#include <string.h>
+
+#include <android-base/logging.h>
+#include <sys/ioctl.h>
+
+#include "fs_mgr_priv.h"
+#include "fs_mgr_priv_dm_ioctl.h"
+
+void fs_mgr_verity_ioctl_init(struct dm_ioctl *io,
+                              const std::string &name,
+                              unsigned flags)
+{
+    memset(io, 0, DM_BUF_SIZE);
+    io->data_size = DM_BUF_SIZE;
+    io->data_start = sizeof(struct dm_ioctl);
+    io->version[0] = 4;
+    io->version[1] = 0;
+    io->version[2] = 0;
+    io->flags = flags | DM_READONLY_FLAG;
+    if (!name.empty()) {
+        strlcpy(io->name, name.c_str(), sizeof(io->name));
+    }
+}
+
+bool fs_mgr_create_verity_device(struct dm_ioctl *io,
+                                 const std::string &name,
+                                 int fd)
+{
+    fs_mgr_verity_ioctl_init(io, name, 1);
+    if (ioctl(fd, DM_DEV_CREATE, io)) {
+        ERROR("Error creating device mapping (%s)", strerror(errno));
+        return false;
+    }
+    return true;
+}
+
+bool fs_mgr_destroy_verity_device(struct dm_ioctl *io,
+                                  const std::string &name,
+                                  int fd)
+{
+    fs_mgr_verity_ioctl_init(io, name, 0);
+    if (ioctl(fd, DM_DEV_REMOVE, io)) {
+        ERROR("Error removing device mapping (%s)", strerror(errno));
+        return false;
+    }
+    return true;
+}
+
+bool fs_mgr_get_verity_device_name(struct dm_ioctl *io,
+                                   const std::string &name,
+                                   int fd,
+                                   std::string *out_dev_name)
+{
+    CHECK(out_dev_name != nullptr);
+
+    fs_mgr_verity_ioctl_init(io, name, 0);
+    if (ioctl(fd, DM_DEV_STATUS, io)) {
+        ERROR("Error fetching verity device number (%s)", strerror(errno));
+        return false;
+    }
+
+    int dev_num = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00);
+    *out_dev_name = "/dev/block/dm-" + std::to_string(dev_num);
+
+    return true;
+}
+
+bool fs_mgr_resume_verity_table(struct dm_ioctl *io,
+                                const std::string &name,
+                                int fd)
+{
+    fs_mgr_verity_ioctl_init(io, name, 0);
+    if (ioctl(fd, DM_DEV_SUSPEND, io)) {
+        ERROR("Error activating verity device (%s)", strerror(errno));
+        return false;
+    }
+    return true;
+}
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index db86afa..7f917d9 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -93,6 +93,7 @@
 #define DM_BUF_SIZE 4096
 
 int fs_mgr_set_blk_ro(const char *blockdev);
+int fs_mgr_test_access(const char *device);
 int fs_mgr_update_for_slotselect(struct fstab *fstab);
 
 __END_DECLS
diff --git a/fs_mgr/fs_mgr_priv_dm_ioctl.h b/fs_mgr/fs_mgr_priv_dm_ioctl.h
new file mode 100644
index 0000000..eeae4dd
--- /dev/null
+++ b/fs_mgr/fs_mgr_priv_dm_ioctl.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 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 __CORE_FS_MGR_PRIV_DM_IOCTL_H
+#define __CORE_FS_MGR_PRIV_DM_IOCTL_H
+
+#include <string>
+#include <linux/dm-ioctl.h>
+
+void fs_mgr_verity_ioctl_init(struct dm_ioctl *io,
+                              const std::string &name,
+                              unsigned flags);
+
+bool fs_mgr_create_verity_device(struct dm_ioctl *io,
+                                 const std::string &name,
+                                 int fd);
+
+bool fs_mgr_destroy_verity_device(struct dm_ioctl *io,
+                                  const std::string &name,
+                                  int fd);
+
+bool fs_mgr_get_verity_device_name(struct dm_ioctl *io,
+                                   const std::string &name,
+                                   int fd,
+                                   std::string *out_dev_name);
+
+bool fs_mgr_resume_verity_table(struct dm_ioctl *io,
+                                const std::string &name,
+                                int fd);
+
+#endif /* __CORE_FS_MGR_PRIV_DM_IOCTL_H */
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index d43c756..e368a82 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -44,6 +44,7 @@
 
 #include "fs_mgr.h"
 #include "fs_mgr_priv.h"
+#include "fs_mgr_priv_dm_ioctl.h"
 #include "fs_mgr_priv_verity.h"
 
 #define FSTAB_PREFIX "/fstab."
@@ -184,55 +185,6 @@
     return -1;
 }
 
-static void verity_ioctl_init(struct dm_ioctl *io, const char *name, unsigned flags)
-{
-    memset(io, 0, DM_BUF_SIZE);
-    io->data_size = DM_BUF_SIZE;
-    io->data_start = sizeof(struct dm_ioctl);
-    io->version[0] = 4;
-    io->version[1] = 0;
-    io->version[2] = 0;
-    io->flags = flags | DM_READONLY_FLAG;
-    if (name) {
-        strlcpy(io->name, name, sizeof(io->name));
-    }
-}
-
-static int create_verity_device(struct dm_ioctl *io, char *name, int fd)
-{
-    verity_ioctl_init(io, name, 1);
-    if (ioctl(fd, DM_DEV_CREATE, io)) {
-        ERROR("Error creating device mapping (%s)", strerror(errno));
-        return -1;
-    }
-    return 0;
-}
-
-static int destroy_verity_device(struct dm_ioctl *io, char *name, int fd)
-{
-    verity_ioctl_init(io, name, 0);
-    if (ioctl(fd, DM_DEV_REMOVE, io)) {
-        ERROR("Error removing device mapping (%s)", strerror(errno));
-        return -1;
-    }
-    return 0;
-}
-
-static int get_verity_device_name(struct dm_ioctl *io, char *name, int fd, char **dev_name)
-{
-    verity_ioctl_init(io, name, 0);
-    if (ioctl(fd, DM_DEV_STATUS, io)) {
-        ERROR("Error fetching verity device number (%s)", strerror(errno));
-        return -1;
-    }
-    int dev_num = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00);
-    if (asprintf(dev_name, "/dev/block/dm-%u", dev_num) < 0) {
-        ERROR("Error getting verity block device name (%s)", strerror(errno));
-        return -1;
-    }
-    return 0;
-}
-
 struct verity_table_params {
     char *table;
     int mode;
@@ -301,14 +253,15 @@
     return true;
 }
 
-static int load_verity_table(struct dm_ioctl *io, char *name, uint64_t device_size, int fd,
+static int load_verity_table(struct dm_ioctl *io, const std::string &name,
+                             uint64_t device_size, int fd,
         const struct verity_table_params *params, format_verity_table_func format)
 {
     char *verity_params;
     char *buffer = (char*) io;
     size_t bufsize;
 
-    verity_ioctl_init(io, name, DM_STATUS_TABLE_FLAG);
+    fs_mgr_verity_ioctl_init(io, name, DM_STATUS_TABLE_FLAG);
 
     struct dm_target_spec *tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)];
 
@@ -344,27 +297,6 @@
     return 0;
 }
 
-static int resume_verity_table(struct dm_ioctl *io, char *name, int fd)
-{
-    verity_ioctl_init(io, name, 0);
-    if (ioctl(fd, DM_DEV_SUSPEND, io)) {
-        ERROR("Error activating verity device (%s)", strerror(errno));
-        return -1;
-    }
-    return 0;
-}
-
-static int test_access(char *device) {
-    int tries = 25;
-    while (tries--) {
-        if (!access(device, F_OK) || errno != ENOENT) {
-            return 0;
-        }
-        usleep(40 * 1000);
-    }
-    return -1;
-}
-
 static int check_verity_restart(const char *fname)
 {
     char buffer[VERITY_KMSG_BUFSIZE + 1];
@@ -823,7 +755,7 @@
     alignas(dm_ioctl) char buffer[DM_BUF_SIZE];
     bool system_root = false;
     char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
-    const char *mount_point;
+    std::string mount_point;
     char propbuf[PROPERTY_VALUE_MAX];
     const char *status;
     int fd = -1;
@@ -872,14 +804,14 @@
             mount_point = basename(fstab->recs[i].mount_point);
         }
 
-        verity_ioctl_init(io, mount_point, 0);
+        fs_mgr_verity_ioctl_init(io, mount_point, 0);
 
         if (ioctl(fd, DM_TABLE_STATUS, io)) {
             if (fstab->recs[i].fs_mgr_flags & MF_VERIFYATBOOT) {
                 status = "V";
             } else {
-                ERROR("Failed to query DM_TABLE_STATUS for %s (%s)\n", mount_point,
-                      strerror(errno));
+                ERROR("Failed to query DM_TABLE_STATUS for %s (%s)\n",
+                      mount_point.c_str(), strerror(errno));
                 continue;
             }
         }
@@ -887,7 +819,7 @@
         status = &buffer[io->data_start + sizeof(struct dm_target_spec)];
 
         if (*status == 'C' || *status == 'V') {
-            callback(&fstab->recs[i], mount_point, mode, *status);
+            callback(&fstab->recs[i], mount_point.c_str(), mode, *status);
         }
     }
 
@@ -937,14 +869,14 @@
 {
     int retval = FS_MGR_SETUP_VERITY_FAIL;
     int fd = -1;
-    char *verity_blk_name = NULL;
+    std::string verity_blk_name;
     struct fec_handle *f = NULL;
     struct fec_verity_metadata verity;
     struct verity_table_params params = { .table = NULL };
 
     alignas(dm_ioctl) char buffer[DM_BUF_SIZE];
     struct dm_ioctl *io = (struct dm_ioctl *) buffer;
-    char *mount_point = basename(fstab->mount_point);
+    const std::string mount_point(basename(fstab->mount_point));
     bool verified_at_boot = false;
 
     if (fec_open(&f, fstab->blk_device, O_RDONLY, FEC_VERITY_DISABLE,
@@ -983,13 +915,13 @@
     }
 
     // create the device
-    if (create_verity_device(io, mount_point, fd) < 0) {
+    if (!fs_mgr_create_verity_device(io, mount_point, fd)) {
         ERROR("Couldn't create verity device!\n");
         goto out;
     }
 
     // get the name of the device file
-    if (get_verity_device_name(io, mount_point, fd, &verity_blk_name) < 0) {
+    if (!fs_mgr_get_verity_device_name(io, mount_point, fd, &verity_blk_name)) {
         ERROR("Couldn't get verity device number!\n");
         goto out;
     }
@@ -1025,7 +957,8 @@
         }
     }
 
-    INFO("Enabling dm-verity for %s (mode %d)\n", mount_point, params.mode);
+    INFO("Enabling dm-verity for %s (mode %d)\n",
+         mount_point.c_str(), params.mode);
 
     if (fstab->fs_mgr_flags & MF_SLOTSELECT) {
         // Update the verity params using the actual block device path
@@ -1040,7 +973,7 @@
 
     if (params.ecc.valid) {
         // kernel may not support error correction, try without
-        INFO("Disabling error correction for %s\n", mount_point);
+        INFO("Disabling error correction for %s\n", mount_point.c_str());
         params.ecc.valid = false;
 
         if (load_verity_table(io, mount_point, verity.data_size, fd, &params,
@@ -1057,7 +990,7 @@
 
     if (params.mode != VERITY_MODE_EIO) {
         // as a last resort, EIO mode should always be supported
-        INFO("Falling back to EIO mode for %s\n", mount_point);
+        INFO("Falling back to EIO mode for %s\n", mount_point.c_str());
         params.mode = VERITY_MODE_EIO;
 
         if (load_verity_table(io, mount_point, verity.data_size, fd, &params,
@@ -1066,13 +999,13 @@
         }
     }
 
-    ERROR("Failed to load verity table for %s\n", mount_point);
+    ERROR("Failed to load verity table for %s\n", mount_point.c_str());
     goto out;
 
 loaded:
 
     // activate the device
-    if (resume_verity_table(io, mount_point, fd) < 0) {
+    if (!fs_mgr_resume_verity_table(io, mount_point, fd)) {
         goto out;
     }
 
@@ -1083,7 +1016,7 @@
     // If there is an error, allow it to mount as a normal verity partition.
     if (fstab->fs_mgr_flags & MF_VERIFYATBOOT) {
         INFO("Verifying partition %s at boot\n", fstab->blk_device);
-        int err = read_partition(verity_blk_name, verity.data_size);
+        int err = read_partition(verity_blk_name.c_str(), verity.data_size);
         if (!err) {
             INFO("Verified verity partition %s at boot\n", fstab->blk_device);
             verified_at_boot = true;
@@ -1093,15 +1026,14 @@
     // assign the new verity block device as the block device
     if (!verified_at_boot) {
         free(fstab->blk_device);
-        fstab->blk_device = verity_blk_name;
-        verity_blk_name = 0;
-    } else if (destroy_verity_device(io, mount_point, fd) < 0) {
-        ERROR("Failed to remove verity device %s\n", mount_point);
+        fstab->blk_device = strdup(verity_blk_name.c_str());
+    } else if (!fs_mgr_destroy_verity_device(io, mount_point, fd)) {
+        ERROR("Failed to remove verity device %s\n", mount_point.c_str());
         goto out;
     }
 
     // make sure we've set everything up properly
-    if (verify_dev && test_access(fstab->blk_device) < 0) {
+    if (verify_dev && fs_mgr_test_access(fstab->blk_device) < 0) {
         goto out;
     }
 
@@ -1114,7 +1046,6 @@
 
     fec_close(f);
     free(params.table);
-    free(verity_blk_name);
 
     return retval;
 }
diff --git a/include/cutils/klog.h b/include/cutils/klog.h
index c837edb..e7cd300 100644
--- a/include/cutils/klog.h
+++ b/include/cutils/klog.h
@@ -44,6 +44,4 @@
 #define KLOG_INFO(tag,x...)    klog_write(KLOG_INFO_LEVEL, "<6>" tag ": " x)
 #define KLOG_DEBUG(tag,x...)   klog_write(KLOG_DEBUG_LEVEL, "<7>" tag ": " x)
 
-#define KLOG_DEFAULT_LEVEL  3  /* messages <= this level are logged */
-
 #endif
diff --git a/include/system/radio.h b/include/system/radio.h
index ea77bdd..acf3ea7 100644
--- a/include/system/radio.h
+++ b/include/system/radio.h
@@ -84,7 +84,7 @@
 typedef uint32_t radio_handle_t;
 
 /* Opaque meta data structure used by radio meta data API (see system/radio_metadata.h) */
-typedef struct radio_medtadata radio_metadata_t;
+typedef struct radio_metadata radio_metadata_t;
 
 
 /* Additional attributes for an FM band configuration */
diff --git a/include/utils/KeyedVector.h b/include/utils/KeyedVector.h
index 42de401..f93ad6e 100644
--- a/include/utils/KeyedVector.h
+++ b/include/utils/KeyedVector.h
@@ -21,7 +21,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <android/log.h>
+#include <log/log.h>
 #include <utils/Errors.h>
 #include <utils/SortedVector.h>
 #include <utils/TypeHelpers.h>
diff --git a/init/Android.mk b/init/Android.mk
index 111fe89..6615692 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -92,7 +92,7 @@
     libsquashfs_utils \
     liblogwrap \
     libcutils \
-    libext4_utils_static \
+    libext4_utils \
     libbase \
     libc \
     libselinux \
@@ -101,7 +101,7 @@
     libcrypto \
     libc++_static \
     libdl \
-    libsparse_static \
+    libsparse \
     libz \
     libprocessgroup \
     libnl \
diff --git a/init/README.md b/init/README.md
new file mode 100644
index 0000000..cef0dbc
--- /dev/null
+++ b/init/README.md
@@ -0,0 +1,560 @@
+Android Init Language
+---------------------
+
+The Android Init Language consists of five broad classes of statements:
+Actions, Commands, Services, Options, and Imports.
+
+All of these are line-oriented, consisting of tokens separated by
+whitespace.  The c-style backslash escapes may be used to insert
+whitespace into a token.  Double quotes may also be used to prevent
+whitespace from breaking text into multiple tokens.  The backslash,
+when it is the last character on a line, may be used for line-folding.
+
+Lines which start with a # (leading whitespace allowed) are comments.
+
+Actions and Services implicitly declare a new section.  All commands
+or options belong to the section most recently declared.  Commands
+or options before the first section are ignored.
+
+Actions and Services have unique names.  If a second Action is defined
+with the same name as an existing one, its commands are appended to
+the commands of the existing action.  If a second Service is defined
+with the same name as an existing one, it is ignored and an error
+message is logged.
+
+
+Init .rc Files
+--------------
+The init language is used in plain text files that take the .rc file
+extension.  These are typically multiple of these in multiple
+locations on the system, described below.
+
+/init.rc is the primary .rc file and is loaded by the init executable
+at the beginning of its execution.  It is responsible for the initial
+set up of the system.  It imports /init.${ro.hardware}.rc which is the
+primary vendor supplied .rc file.
+
+During the mount\_all command, the init executable loads all of the
+files contained within the /{system,vendor,odm}/etc/init/ directories.
+These directories are intended for all Actions and Services used after
+file system mounting.
+
+One may specify paths in the mount\_all command line to have it import
+.rc files at the specified paths instead of the default ones listed above.
+This is primarily for supporting factory mode and other non-standard boot
+modes.  The three default paths should be used for the normal boot process.
+
+The intention of these directories is:
+
+   1. /system/etc/init/ is for core system items such as
+      SurfaceFlinger, MediaService, and logcatd.
+   2. /vendor/etc/init/ is for SoC vendor items such as actions or
+      daemons needed for core SoC functionality.
+   3. /odm/etc/init/ is for device manufacturer items such as
+      actions or daemons needed for motion sensor or other peripheral
+      functionality.
+
+All services whose binaries reside on the system, vendor, or odm
+partitions should have their service entries placed into a
+corresponding init .rc file, located in the /etc/init/
+directory of the partition where they reside.  There is a build
+system macro, LOCAL\_INIT\_RC, that handles this for developers.  Each
+init .rc file should additionally contain any actions associated with
+its service.
+
+An example is the logcatd.rc and Android.mk files located in the
+system/core/logcat directory.  The LOCAL\_INIT\_RC macro in the
+Android.mk file places logcatd.rc in /system/etc/init/ during the
+build process.  Init loads logcatd.rc during the mount\_all command and
+allows the service to be run and the action to be queued when
+appropriate.
+
+This break up of init .rc files according to their daemon is preferred
+to the previously used monolithic init .rc files.  This approach
+ensures that the only service entries that init reads and the only
+actions that init performs correspond to services whose binaries are in
+fact present on the file system, which was not the case with the
+monolithic init .rc files.  This additionally will aid in merge
+conflict resolution when multiple services are added to the system, as
+each one will go into a separate file.
+
+There are two options "early" and "late" in mount\_all command
+which can be set after optional paths. With "--early" set, the
+init executable will skip mounting entries with "latemount" flag
+and triggering fs encryption state event. With "--late" set,
+init executable will only mount entries with "latemount" flag but skip
+importing rc files. By default, no option is set, and mount\_all will
+process all entries in the given fstab.
+
+Actions
+-------
+Actions are named sequences of commands.  Actions have a trigger which
+is used to determine when the action should occur.  When an event
+occurs which matches an action's trigger, that action is added to
+the tail of a to-be-executed queue (unless it is already on the
+queue).
+
+Each action in the queue is dequeued in sequence and each command in
+that action is executed in sequence.  Init handles other activities
+(device creation/destruction, property setting, process restarting)
+"between" the execution of the commands in activities.
+
+Actions take the form of:
+
+    on <trigger> [&& <trigger>]*
+       <command>
+       <command>
+       <command>
+
+
+Services
+--------
+Services are programs which init launches and (optionally) restarts
+when they exit.  Services take the form of:
+
+    service <name> <pathname> [ <argument> ]*
+       <option>
+       <option>
+       ...
+
+
+Options
+-------
+Options are modifiers to services.  They affect how and when init
+runs the service.
+
+`console [<console>]`
+> This service needs a console. The optional second parameter chooses a
+  specific console instead of the default. The default "/dev/console" can
+  be changed by setting the "androidboot.console" kernel parameter. In
+  all cases the leading "/dev/" should be omitted, so "/dev/tty0" would be
+  specified as just "console tty0".
+
+`critical`
+> This is a device-critical service. If it exits more than four times in
+  four minutes, the device will reboot into recovery mode.
+
+`disabled`
+> This service will not automatically start with its class.
+  It must be explicitly started by name.
+
+`setenv <name> <value>`
+> Set the environment variable _name_ to _value_ in the launched process.
+
+`socket <name> <type> <perm> [ <user> [ <group> [ <seclabel> ] ] ]`
+> Create a unix domain socket named /dev/socket/_name_ and pass its fd to the
+  launched process.  _type_ must be "dgram", "stream" or "seqpacket".  User and
+  group default to 0.  'seclabel' is the SELinux security context for the
+  socket.  It defaults to the service security context, as specified by
+  seclabel or computed based on the service executable file security context.
+  For native executables see libcutils android\_get\_control\_socket().
+
+`file <path> <type>`
+> Open a file path and pass its fd to the launched process. _type_ must be
+  "r", "w" or "rw".  For native executables see libcutils
+  android\_get\_control\_file().
+
+`user <username>`
+> Change to 'username' before exec'ing this service.
+  Currently defaults to root.  (??? probably should default to nobody)
+  As of Android M, processes should use this option even if they
+  require Linux capabilities.  Previously, to acquire Linux
+  capabilities, a process would need to run as root, request the
+  capabilities, then drop to its desired uid.  There is a new
+  mechanism through fs\_config that allows device manufacturers to add
+  Linux capabilities to specific binaries on a file system that should
+  be used instead. This mechanism is described on
+  <http://source.android.com/devices/tech/config/filesystem.html>.  When
+  using this new mechanism, processes can use the user option to
+  select their desired uid without ever running as root.
+  As of Android O, processes can also request capabilities directly in their .rc
+  files. See the "capabilities" option below.
+
+`group <groupname> [ <groupname>\* ]`
+> Change to 'groupname' before exec'ing this service.  Additional
+  groupnames beyond the (required) first one are used to set the
+  supplemental groups of the process (via setgroups()).
+  Currently defaults to root.  (??? probably should default to nobody)
+
+`capabilities <capability> [ <capability>\* ]`
+> Set capabilities when exec'ing this service. 'capability' should be a Linux
+  capability without the "CAP\_" prefix, like "NET\_ADMIN" or "SETPCAP". See
+  http://man7.org/linux/man-pages/man7/capabilities.7.html for a list of Linux
+  capabilities.
+
+`seclabel <seclabel>`
+> Change to 'seclabel' before exec'ing this service.
+  Primarily for use by services run from the rootfs, e.g. ueventd, adbd.
+  Services on the system partition can instead use policy-defined transitions
+  based on their file security context.
+  If not specified and no transition is defined in policy, defaults to the init context.
+
+`oneshot`
+> Do not restart the service when it exits.
+
+`class <name>`
+> Specify a class name for the service.  All services in a
+  named class may be started or stopped together.  A service
+  is in the class "default" if one is not specified via the
+  class option.
+
+`onrestart`
+> Execute a Command (see below) when service restarts.
+
+`writepid <file...>`
+> Write the child's pid to the given files when it forks. Meant for
+  cgroup/cpuset usage.
+
+`priority <priority>`
+> Scheduling priority of the service process. This value has to be in range
+  -20 to 19. Default priority is 0. Priority is set via setpriority().
+
+`namespace <pid|mnt>`
+> Enter a new PID or mount namespace when forking the service.
+
+`oom_score_adjust <value>`
+> Sets the child's /proc/self/oom\_score\_adj to the specified value,
+  which must range from -1000 to 1000.
+
+
+Triggers
+--------
+Triggers are strings which can be used to match certain kinds of
+events and used to cause an action to occur.
+
+Triggers are subdivided into event triggers and property triggers.
+
+Event triggers are strings triggered by the 'trigger' command or by
+the QueueEventTrigger() function within the init executable.  These
+take the form of a simple string such as 'boot' or 'late-init'.
+
+Property triggers are strings triggered when a named property changes
+value to a given new value or when a named property changes value to
+any new value.  These take the form of 'property:<name>=<value>' and
+'property:<name>=\*' respectively.  Property triggers are additionally
+evaluated and triggered accordingly during the initial boot phase of
+init.
+
+An Action can have multiple property triggers but may only have one
+event trigger.
+
+For example:
+`on boot && property:a=b` defines an action that is only executed when
+the 'boot' event trigger happens and the property a equals b.
+
+`on property:a=b && property:c=d` defines an action that is executed
+at three times:
+
+   1. During initial boot if property a=b and property c=d.
+   2. Any time that property a transitions to value b, while property c already equals d.
+   3. Any time that property c transitions to value d, while property a already equals b.
+
+
+Commands
+--------
+
+`bootchart [start|stop]`
+> Start/stop bootcharting. These are present in the default init.rc files,
+  but bootcharting is only active if the file /data/bootchart/enabled exists;
+  otherwise bootchart start/stop are no-ops.
+
+`chmod <octal-mode> <path>`
+> Change file access permissions.
+
+`chown <owner> <group> <path>`
+> Change file owner and group.
+
+`class_start <serviceclass>`
+> Start all services of the specified class if they are
+  not already running.
+
+`class_stop <serviceclass>`
+> Stop and disable all services of the specified class if they are
+  currently running.
+
+`class_reset <serviceclass>`
+> Stop all services of the specified class if they are
+  currently running, without disabling them. They can be restarted
+  later using `class_start`.
+
+`copy <src> <dst>`
+> Copies a file. Similar to write, but useful for binary/large
+  amounts of data.
+
+`domainname <name>`
+> Set the domain name.
+
+`enable <servicename>`
+> Turns a disabled service into an enabled one as if the service did not
+  specify disabled.
+  If the service is supposed to be running, it will be started now.
+  Typically used when the bootloader sets a variable that indicates a specific
+  service should be started when needed. E.g.
+
+    on property:ro.boot.myfancyhardware=1
+        enable my_fancy_service_for_my_fancy_hardware
+
+`exec [ <seclabel> [ <user> [ <group>\* ] ] ] -- <command> [ <argument>\* ]`
+> Fork and execute command with the given arguments. The command starts
+  after "--" so that an optional security context, user, and supplementary
+  groups can be provided. No other commands will be run until this one
+  finishes. _seclabel_ can be a - to denote default.
+
+`export <name> <value>`
+> Set the environment variable _name_ equal to _value_ in the
+  global environment (which will be inherited by all processes
+  started after this command is executed)
+
+`hostname <name>`
+> Set the host name.
+
+`ifup <interface>`
+> Bring the network interface _interface_ online.
+
+`insmod [-f] <path> [<options>]`
+> Install the module at _path_ with the specified options.
+  -f: force installation of the module even if the version of the running kernel
+  and the version of the kernel for which the module was compiled do not match.
+
+`load_all_props`
+> Loads properties from /system, /vendor, et cetera.
+  This is included in the default init.rc.
+
+`load_persist_props`
+> Loads persistent properties when /data has been decrypted.
+  This is included in the default init.rc.
+
+`loglevel <level>`
+> Sets the kernel log level to level. Properties are expanded within _level_.
+
+`mkdir <path> [mode] [owner] [group]`
+> Create a directory at _path_, optionally with the given mode, owner, and
+  group. If not provided, the directory is created with permissions 755 and
+  owned by the root user and root group. If provided, the mode, owner and group
+  will be updated if the directory exists already.
+
+`mount_all <fstab> [ <path> ]\* [--<option>]`
+> Calls fs\_mgr\_mount\_all on the given fs\_mgr-format fstab and imports .rc files
+  at the specified paths (e.g., on the partitions just mounted) with optional
+  options "early" and "late".
+  Refer to the section of "Init .rc Files" for detail.
+
+`mount <type> <device> <dir> [ <flag>\* ] [<options>]`
+> Attempt to mount the named device at the directory _dir_
+  _flag_s include "ro", "rw", "remount", "noatime", ...
+  _options_ include "barrier=1", "noauto\_da\_alloc", "discard", ... as
+  a comma separated string, eg: barrier=1,noauto\_da\_alloc
+
+`powerctl`
+> Internal implementation detail used to respond to changes to the
+  "sys.powerctl" system property, used to implement rebooting.
+
+`restart <service>`
+> Like stop, but doesn't disable the service.
+
+`restorecon <path> [ <path>\* ]`
+> Restore the file named by _path_ to the security context specified
+  in the file\_contexts configuration.
+  Not required for directories created by the init.rc as these are
+  automatically labeled correctly by init.
+
+`restorecon_recursive <path> [ <path>\* ]`
+> Recursively restore the directory tree named by _path_ to the
+  security contexts specified in the file\_contexts configuration.
+
+`rm <path>`
+> Calls unlink(2) on the given path. You might want to
+  use "exec -- rm ..." instead (provided the system partition is
+  already mounted).
+
+`rmdir <path>`
+> Calls rmdir(2) on the given path.
+
+`setprop <name> <value>`
+> Set system property _name_ to _value_. Properties are expanded
+  within _value_.
+
+`setrlimit <resource> <cur> <max>`
+> Set the rlimit for a resource.
+
+`start <service>`
+> Start a service running if it is not already running.
+
+`stop <service>`
+> Stop a service from running if it is currently running.
+
+`swapon_all <fstab>`
+> Calls fs\_mgr\_swapon\_all on the given fstab file.
+
+`symlink <target> <path>`
+> Create a symbolic link at _path_ with the value _target_
+
+`sysclktz <mins_west_of_gmt>`
+> Set the system clock base (0 if system clock ticks in GMT)
+
+`trigger <event>`
+> Trigger an event.  Used to queue an action from another
+  action.
+
+`umount <path>`
+> Unmount the filesystem mounted at that path.
+
+`verity_load_state`
+> Internal implementation detail used to load dm-verity state.
+
+`verity_update_state <mount-point>`
+> Internal implementation detail used to update dm-verity state and
+  set the partition._mount-point_.verified properties used by adb remount
+  because fs\_mgr can't set them directly itself.
+
+`wait <path> [ <timeout> ]`
+> Poll for the existence of the given file and return when found,
+  or the timeout has been reached. If timeout is not specified it
+  currently defaults to five seconds.
+
+`write <path> <content>`
+> Open the file at _path_ and write a string to it with write(2).
+  If the file does not exist, it will be created. If it does exist,
+  it will be truncated. Properties are expanded within _content_.
+
+
+Imports
+-------
+The import keyword is not a command, but rather its own section and is
+handled immediately after the .rc file that contains it has finished
+being parsed.  It takes the below form:
+
+`import <path>`
+> Parse an init config file, extending the current configuration.
+  If _path_ is a directory, each file in the directory is parsed as
+  a config file. It is not recursive, nested directories will
+  not be parsed.
+
+There are only two times where the init executable imports .rc files:
+
+   1. When it imports /init.rc during initial boot
+   2. When it imports /{system,vendor,odm}/etc/init/ or .rc files at specified
+      paths during mount_all
+
+
+Properties
+----------
+Init provides information about the services that it is responsible
+for via the below properties.
+
+`init.svc.<name>`
+> State of a named service ("stopped", "stopping", "running", "restarting")
+
+
+Boot timing
+-----------
+Init records some boot timing information in system properties.
+
+`ro.boottime.init`
+> Time after boot in ns (via the CLOCK\_BOOTTIME clock) at which the first
+  stage of init started.
+
+`ro.boottime.init.selinux`
+> How long it took the first stage to initialize SELinux.
+
+`ro.boottime.init.cold_boot_wait`
+> How long init waited for ueventd's coldboot phase to end.
+
+`ro.boottime.<service-name>`
+> Time after boot in ns (via the CLOCK\_BOOTTIME clock) that the service was
+  first started.
+
+
+Bootcharting
+------------
+This version of init contains code to perform "bootcharting": generating log
+files that can be later processed by the tools provided by <http://www.bootchart.org/>.
+
+On the emulator, use the -bootchart _timeout_ option to boot with bootcharting
+activated for _timeout_ seconds.
+
+On a device:
+
+    adb shell 'touch /data/bootchart/enabled'
+
+Don't forget to delete this file when you're done collecting data!
+
+The log files are written to /data/bootchart/. A script is provided to
+retrieve them and create a bootchart.tgz file that can be used with the
+bootchart command-line utility:
+
+    sudo apt-get install pybootchartgui
+    # grab-bootchart.sh uses $ANDROID_SERIAL.
+    $ANDROID_BUILD_TOP/system/core/init/grab-bootchart.sh
+
+One thing to watch for is that the bootchart will show init as if it started
+running at 0s. You'll have to look at dmesg to work out when the kernel
+actually started init.
+
+
+Comparing two bootcharts
+------------------------
+A handy script named compare-bootcharts.py can be used to compare the
+start/end time of selected processes. The aforementioned grab-bootchart.sh
+will leave a bootchart tarball named bootchart.tgz at /tmp/android-bootchart.
+If two such barballs are preserved on the host machine under different
+directories, the script can list the timestamps differences. For example:
+
+Usage: system/core/init/compare-bootcharts.py _base-bootchart-dir_ _exp-bootchart-dir_
+
+    process: baseline experiment (delta) - Unit is ms (a jiffy is 10 ms on the system)
+    ------------------------------------
+    /init: 50 40 (-10)
+    /system/bin/surfaceflinger: 4320 4470 (+150)
+    /system/bin/bootanimation: 6980 6990 (+10)
+    zygote64: 10410 10640 (+230)
+    zygote: 10410 10640 (+230)
+    system_server: 15350 15150 (-200)
+    bootanimation ends at: 33790 31230 (-2560)
+
+
+Systrace
+--------
+Systrace (<http://developer.android.com/tools/help/systrace.html>) can be
+used for obtaining performance analysis reports during boot
+time on userdebug or eng builds.
+
+Here is an example of trace events of "wm" and "am" categories:
+
+    $ANDROID_BUILD_TOP/external/chromium-trace/systrace.py \
+          wm am --boot
+
+This command will cause the device to reboot. After the device is rebooted and
+the boot sequence has finished, the trace report is obtained from the device
+and written as trace.html on the host by hitting Ctrl+C.
+
+Limitation: recording trace events is started after persistent properties are loaded, so
+the trace events that are emitted before that are not recorded. Several
+services such as vold, surfaceflinger, and servicemanager are affected by this
+limitation since they are started before persistent properties are loaded.
+Zygote initialization and the processes that are forked from the zygote are not
+affected.
+
+
+Debugging init
+--------------
+By default, programs executed by init will drop stdout and stderr into
+/dev/null. To help with debugging, you can execute your program via the
+Android program logwrapper. This will redirect stdout/stderr into the
+Android logging system (accessed via logcat).
+
+For example
+service akmd /system/bin/logwrapper /sbin/akmd
+
+For quicker turnaround when working on init itself, use:
+
+    mm -j &&
+    m ramdisk-nodeps &&
+    m bootimage-nodeps &&
+    adb reboot bootloader &&
+    fastboot boot $ANDROID_PRODUCT_OUT/boot.img
+
+Alternatively, use the emulator:
+
+    emulator -partition-size 1024 \
+        -verbose -show-kernel -no-window
diff --git a/init/init.cpp b/init/init.cpp
index ee5add8..7f17a0c 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -409,7 +409,7 @@
         const char *default_value;
     } prop_map[] = {
         { "ro.boot.serialno",   "ro.serialno",   "", },
-        { "ro.boot.mode",       "ro.bootmode",   "unknown", },
+        { "ro.boot.mode",       "ro.bootmode",   "normal", },
         { "ro.boot.baseband",   "ro.baseband",   "unknown", },
         { "ro.boot.bootloader", "ro.bootloader", "unknown", },
         { "ro.boot.hardware",   "ro.hardware",   "unknown", },
@@ -800,7 +800,13 @@
     parser.AddSectionParser("service",std::make_unique<ServiceParser>());
     parser.AddSectionParser("on", std::make_unique<ActionParser>());
     parser.AddSectionParser("import", std::make_unique<ImportParser>());
-    parser.ParseConfig("/init.rc");
+
+    std::string bootscript = property_get("ro.boot.init_rc");
+    if (bootscript.empty()) {
+        parser.ParseConfig("/init.rc");
+    } else {
+        parser.ParseConfig(bootscript);
+    }
 
     ActionManager& am = ActionManager::GetInstance();
 
@@ -825,7 +831,8 @@
     std::string bootmode = property_get("ro.bootmode");
     if (bootmode == "charger") {
         am.QueueEventTrigger("charger");
-    } else {
+    } else if (bootmode == "normal") {
+        // only trigger late-init in normal boot
         am.QueueEventTrigger("late-init");
     }
 
diff --git a/init/readme.txt b/init/readme.txt
deleted file mode 100644
index 530b392..0000000
--- a/init/readme.txt
+++ /dev/null
@@ -1,560 +0,0 @@
-Android Init Language
----------------------
-
-The Android Init Language consists of five broad classes of statements,
-which are Actions, Commands, Services, Options, and Imports.
-
-All of these are line-oriented, consisting of tokens separated by
-whitespace.  The c-style backslash escapes may be used to insert
-whitespace into a token.  Double quotes may also be used to prevent
-whitespace from breaking text into multiple tokens.  The backslash,
-when it is the last character on a line, may be used for line-folding.
-
-Lines which start with a # (leading whitespace allowed) are comments.
-
-Actions and Services implicitly declare a new section.  All commands
-or options belong to the section most recently declared.  Commands
-or options before the first section are ignored.
-
-Actions and Services have unique names.  If a second Action is defined
-with the same name as an existing one, its commands are appended to
-the commands of the existing action.  If a second Service is defined
-with the same name as an existing one, it is ignored and an error
-message is logged.
-
-
-Init .rc Files
---------------
-The init language is used in plaintext files that take the .rc file
-extension.  These are typically multiple of these in multiple
-locations on the system, described below.
-
-/init.rc is the primary .rc file and is loaded by the init executable
-at the beginning of its execution.  It is responsible for the initial
-set up of the system.  It imports /init.${ro.hardware}.rc which is the
-primary vendor supplied .rc file.
-
-During the mount_all command, the init executable loads all of the
-files contained within the /{system,vendor,odm}/etc/init/ directories.
-These directories are intended for all Actions and Services used after
-file system mounting.
-
-One may specify paths in the mount_all command line to have it import
-.rc files at the specified paths instead of the default ones listed above.
-This is primarily for supporting factory mode and other non-standard boot
-modes.  The three default paths should be used for the normal boot process.
-
-The intention of these directories is as follows
-   1) /system/etc/init/ is for core system items such as
-      SurfaceFlinger, MediaService, and logcatd.
-   2) /vendor/etc/init/ is for SoC vendor items such as actions or
-      daemons needed for core SoC functionality.
-   3) /odm/etc/init/ is for device manufacturer items such as
-      actions or daemons needed for motion sensor or other peripheral
-      functionality.
-
-All services whose binaries reside on the system, vendor, or odm
-partitions should have their service entries placed into a
-corresponding init .rc file, located in the /etc/init/
-directory of the partition where they reside.  There is a build
-system macro, LOCAL_INIT_RC, that handles this for developers.  Each
-init .rc file should additionally contain any actions associated with
-its service.
-
-An example is the logcatd.rc and Android.mk files located in the
-system/core/logcat directory.  The LOCAL_INIT_RC macro in the
-Android.mk file places logcatd.rc in /system/etc/init/ during the
-build process.  Init loads logcatd.rc during the mount_all command and
-allows the service to be run and the action to be queued when
-appropriate.
-
-This break up of init .rc files according to their daemon is preferred
-to the previously used monolithic init .rc files.  This approach
-ensures that the only service entries that init reads and the only
-actions that init performs correspond to services whose binaries are in
-fact present on the file system, which was not the case with the
-monolithic init .rc files.  This additionally will aid in merge
-conflict resolution when multiple services are added to the system, as
-each one will go into a separate file.
-
-There are two options "early" and "late" in mount_all command
-which can be set after optional paths. With "--early" set, the
-init executable will skip mounting entries with "latemount" flag
-and triggering fs encryption state event. With "--late" set,
-init executable will only mount entries with "latemount" flag but skip
-importing rc files. By default, no option is set, and mount_all will
-mount_all will process all entries in the given fstab.
-
-Actions
--------
-Actions are named sequences of commands.  Actions have a trigger which
-is used to determine when the action should occur.  When an event
-occurs which matches an action's trigger, that action is added to
-the tail of a to-be-executed queue (unless it is already on the
-queue).
-
-Each action in the queue is dequeued in sequence and each command in
-that action is executed in sequence.  Init handles other activities
-(device creation/destruction, property setting, process restarting)
-"between" the execution of the commands in activities.
-
-Actions take the form of:
-
-on <trigger> [&& <trigger>]*
-   <command>
-   <command>
-   <command>
-
-
-Services
---------
-Services are programs which init launches and (optionally) restarts
-when they exit.  Services take the form of:
-
-service <name> <pathname> [ <argument> ]*
-   <option>
-   <option>
-   ...
-
-
-Options
--------
-Options are modifiers to services.  They affect how and when init
-runs the service.
-
-console [<console>]
-  This service needs a console. The optional second parameter chooses a
-  specific console instead of the default. The default "/dev/console" can
-  be changed by setting the "androidboot.console" kernel parameter. In
-  all cases the leading "/dev/" should be omitted, so "/dev/tty0" would be
-  specified as just "console tty0".
-
-critical
-  This is a device-critical service. If it exits more than four times in
-  four minutes, the device will reboot into recovery mode.
-
-disabled
-  This service will not automatically start with its class.
-  It must be explicitly started by name.
-
-setenv <name> <value>
-  Set the environment variable <name> to <value> in the launched process.
-
-socket <name> <type> <perm> [ <user> [ <group> [ <seclabel> ] ] ]
-  Create a unix domain socket named /dev/socket/<name> and pass its fd to the
-  launched process.  <type> must be "dgram", "stream" or "seqpacket".  User and
-  group default to 0.  'seclabel' is the SELinux security context for the
-  socket.  It defaults to the service security context, as specified by
-  seclabel or computed based on the service executable file security context.
-  For native executables see libcutils android_get_control_socket().
-
-file <path> <type>
-  Open a file path and pass its fd to the launched process.  <type> must be
-  "r", "w" or "rw".  For native executables see libcutils
-  android_get_control_file().
-
-user <username>
-  Change to 'username' before exec'ing this service.
-  Currently defaults to root.  (??? probably should default to nobody)
-  As of Android M, processes should use this option even if they
-  require Linux capabilities.  Previously, to acquire Linux
-  capabilities, a process would need to run as root, request the
-  capabilities, then drop to its desired uid.  There is a new
-  mechanism through fs_config that allows device manufacturers to add
-  Linux capabilities to specific binaries on a file system that should
-  be used instead. This mechanism is described on
-  http://source.android.com/devices/tech/config/filesystem.html.  When
-  using this new mechanism, processes can use the user option to
-  select their desired uid without ever running as root.
-  As of Android O, processes can also request capabilities directly in their .rc
-  files. See the "capabilities" option below.
-
-group <groupname> [ <groupname> ]*
-  Change to 'groupname' before exec'ing this service.  Additional
-  groupnames beyond the (required) first one are used to set the
-  supplemental groups of the process (via setgroups()).
-  Currently defaults to root.  (??? probably should default to nobody)
-
-capabilities <capability> [ <capability> ]*
-  Set capabilities when exec'ing this service. 'capability' should be a Linux
-  capability without the "CAP_" prefix, like "NET_ADMIN" or "SETPCAP". See
-  http://man7.org/linux/man-pages/man7/capabilities.7.html for a list of Linux
-  capabilities.
-
-seclabel <seclabel>
-  Change to 'seclabel' before exec'ing this service.
-  Primarily for use by services run from the rootfs, e.g. ueventd, adbd.
-  Services on the system partition can instead use policy-defined transitions
-  based on their file security context.
-  If not specified and no transition is defined in policy, defaults to the init context.
-
-oneshot
-  Do not restart the service when it exits.
-
-class <name>
-  Specify a class name for the service.  All services in a
-  named class may be started or stopped together.  A service
-  is in the class "default" if one is not specified via the
-  class option.
-
-onrestart
-  Execute a Command (see below) when service restarts.
-
-writepid <file...>
-  Write the child's pid to the given files when it forks. Meant for
-  cgroup/cpuset usage.
-
-priority <priority>
-  Scheduling priority of the service process. This value has to be in range
-  -20 to 19. Default priority is 0. Priority is set via setpriority().
-
-namespace <pid|mnt>
-  Enter a new PID or mount namespace when forking the service.
-
-oom_score_adjust <value>
-   Sets the child's /proc/self/oom_score_adj to the specified value,
-   which must range from -1000 to 1000.
-
-
-Triggers
---------
-Triggers are strings which can be used to match certain kinds of
-events and used to cause an action to occur.
-
-Triggers are subdivided into event triggers and property triggers.
-
-Event triggers are strings triggered by the 'trigger' command or by
-the QueueEventTrigger() function within the init executable.  These
-take the form of a simple string such as 'boot' or 'late-init'.
-
-Property triggers are strings triggered when a named property changes
-value to a given new value or when a named property changes value to
-any new value.  These take the form of 'property:<name>=<value>' and
-'property:<name>=*' respectively.  Property triggers are additionally
-evaluated and triggered accordingly during the initial boot phase of
-init.
-
-An Action can have multiple property triggers but may only have one
-event trigger.
-
-For example:
-'on boot && property:a=b' defines an action that is only executed when
-the 'boot' event trigger happens and the property a equals b.
-
-'on property:a=b && property:c=d' defines an action that is executed
-at three times,
-   1) During initial boot if property a=b and property c=d
-   2) Any time that property a transitions to value b, while property
-      c already equals d.
-   3) Any time that property c transitions to value d, while property
-      a already equals b.
-
-
-Commands
---------
-
-bootchart [start|stop]
-   Start/stop bootcharting. These are present in the default init.rc files,
-   but bootcharting is only active if the file /data/bootchart/enabled exists;
-   otherwise bootchart start/stop are no-ops.
-
-chmod <octal-mode> <path>
-   Change file access permissions.
-
-chown <owner> <group> <path>
-   Change file owner and group.
-
-class_start <serviceclass>
-   Start all services of the specified class if they are
-   not already running.
-
-class_stop <serviceclass>
-   Stop and disable all services of the specified class if they are
-   currently running.
-
-class_reset <serviceclass>
-   Stop all services of the specified class if they are
-   currently running, without disabling them. They can be restarted
-   later using class_start.
-
-copy <src> <dst>
-   Copies a file. Similar to write, but useful for binary/large
-   amounts of data.
-
-domainname <name>
-   Set the domain name.
-
-enable <servicename>
-   Turns a disabled service into an enabled one as if the service did not
-   specify disabled.
-   If the service is supposed to be running, it will be started now.
-   Typically used when the bootloader sets a variable that indicates a specific
-   service should be started when needed. E.g.
-     on property:ro.boot.myfancyhardware=1
-        enable my_fancy_service_for_my_fancy_hardware
-
-exec [ <seclabel> [ <user> [ <group> ]* ] ] -- <command> [ <argument> ]*
-   Fork and execute command with the given arguments. The command starts
-   after "--" so that an optional security context, user, and supplementary
-   groups can be provided. No other commands will be run until this one
-   finishes. <seclabel> can be a - to denote default.
-
-export <name> <value>
-   Set the environment variable <name> equal to <value> in the
-   global environment (which will be inherited by all processes
-   started after this command is executed)
-
-hostname <name>
-   Set the host name.
-
-ifup <interface>
-   Bring the network interface <interface> online.
-
-insmod [-f] <path> [<options>]
-   Install the module at <path> with the specified options.
-   -f
-   Force installation of the module even if the version of the running kernel
-   and the version of the kernel for which the module was compiled do not match.
-
-load_all_props
-   Loads properties from /system, /vendor, et cetera.
-   This is included in the default init.rc.
-
-load_persist_props
-   Loads persistent properties when /data has been decrypted.
-   This is included in the default init.rc.
-
-loglevel <level>
-   Sets the kernel log level to level. Properties are expanded within <level>.
-
-mkdir <path> [mode] [owner] [group]
-   Create a directory at <path>, optionally with the given mode, owner, and
-   group. If not provided, the directory is created with permissions 755 and
-   owned by the root user and root group. If provided, the mode, owner and group
-   will be updated if the directory exists already.
-
-mount_all <fstab> [ <path> ]* [--<option>]
-   Calls fs_mgr_mount_all on the given fs_mgr-format fstab and imports .rc files
-   at the specified paths (e.g., on the partitions just mounted) with optional
-   options "early" and "late".
-   Refer to the section of "Init .rc Files" for detail.
-
-mount <type> <device> <dir> [ <flag> ]* [<options>]
-   Attempt to mount the named device at the directory <dir>
-   <flag>s include "ro", "rw", "remount", "noatime", ...
-   <options> include "barrier=1", "noauto_da_alloc", "discard", ... as
-   a comma separated string, eg: barrier=1,noauto_da_alloc
-
-powerctl
-   Internal implementation detail used to respond to changes to the
-   "sys.powerctl" system property, used to implement rebooting.
-
-restart <service>
-   Like stop, but doesn't disable the service.
-
-restorecon <path> [ <path> ]*
-   Restore the file named by <path> to the security context specified
-   in the file_contexts configuration.
-   Not required for directories created by the init.rc as these are
-   automatically labeled correctly by init.
-
-restorecon_recursive <path> [ <path> ]*
-   Recursively restore the directory tree named by <path> to the
-   security contexts specified in the file_contexts configuration.
-
-rm <path>
-   Calls unlink(2) on the given path. You might want to
-   use "exec -- rm ..." instead (provided the system partition is
-   already mounted).
-
-rmdir <path>
-   Calls rmdir(2) on the given path.
-
-setprop <name> <value>
-   Set system property <name> to <value>. Properties are expanded
-   within <value>.
-
-setrlimit <resource> <cur> <max>
-   Set the rlimit for a resource.
-
-start <service>
-   Start a service running if it is not already running.
-
-stop <service>
-   Stop a service from running if it is currently running.
-
-swapon_all <fstab>
-   Calls fs_mgr_swapon_all on the given fstab file.
-
-symlink <target> <path>
-   Create a symbolic link at <path> with the value <target>
-
-sysclktz <mins_west_of_gmt>
-   Set the system clock base (0 if system clock ticks in GMT)
-
-trigger <event>
-   Trigger an event.  Used to queue an action from another
-   action.
-
-umount <path>
-   Unmount the filesystem mounted at that path.
-
-verity_load_state
-   Internal implementation detail used to load dm-verity state.
-
-verity_update_state <mount_point>
-   Internal implementation detail used to update dm-verity state and
-   set the partition.<mount_point>.verified properties used by adb remount
-   because fs_mgr can't set them directly itself.
-
-wait <path> [ <timeout> ]
-   Poll for the existence of the given file and return when found,
-   or the timeout has been reached. If timeout is not specified it
-   currently defaults to five seconds.
-
-write <path> <content>
-   Open the file at <path> and write a string to it with write(2).
-   If the file does not exist, it will be created. If it does exist,
-   it will be truncated. Properties are expanded within <content>.
-
-
-Imports
--------
-The import keyword is not a command, but rather its own section and is
-handled immediately after the .rc file that contains it has finished
-being parsed.  It takes the below form:
-
-import <path>
-   Parse an init config file, extending the current configuration.
-   If <path> is a directory, each file in the directory is parsed as
-   a config file. It is not recursive, nested directories will
-   not be parsed.
-
-There are only two times where the init executable imports .rc files,
-   1) When it imports /init.rc during initial boot
-   2) When it imports /{system,vendor,odm}/etc/init/ or .rc files at specified
-      paths during mount_all
-
-
-Properties
-----------
-Init provides information about the services that it is responsible
-for via the below properties.
-
-init.svc.<name>
-  State of a named service ("stopped", "stopping", "running", "restarting")
-
-
-Boot timing
------------
-Init records some boot timing information in system properties.
-
-ro.boottime.init
-  Time after boot in ns (via the CLOCK_BOOTTIME clock) at which the first
-  stage of init started.
-
-ro.boottime.init.selinux
-  How long it took the first stage to initialize SELinux.
-
-ro.boottime.init.cold_boot_wait
-  How long init waited for ueventd's coldboot phase to end.
-
-ro.boottime.<service-name>
-  Time after boot in ns (via the CLOCK_BOOTTIME clock) that the service was
-  first started.
-
-
-Bootcharting
-------------
-This version of init contains code to perform "bootcharting": generating log
-files that can be later processed by the tools provided by www.bootchart.org.
-
-On the emulator, use the -bootchart <timeout> option to boot with bootcharting
-activated for <timeout> seconds.
-
-On a device:
-
-  adb shell 'touch /data/bootchart/enabled'
-
-Don't forget to delete this file when you're done collecting data!
-
-The log files are written to /data/bootchart/. A script is provided to
-retrieve them and create a bootchart.tgz file that can be used with the
-bootchart command-line utility:
-
-  sudo apt-get install pybootchartgui
-  # grab-bootchart.sh uses $ANDROID_SERIAL.
-  $ANDROID_BUILD_TOP/system/core/init/grab-bootchart.sh
-
-One thing to watch for is that the bootchart will show init as if it started
-running at 0s. You'll have to look at dmesg to work out when the kernel
-actually started init.
-
-
-Comparing two bootcharts
-------------------------
-A handy script named compare-bootcharts.py can be used to compare the
-start/end time of selected processes. The aforementioned grab-bootchart.sh
-will leave a bootchart tarball named bootchart.tgz at /tmp/android-bootchart.
-If two such barballs are preserved on the host machine under different
-directories, the script can list the timestamps differences. For example:
-
-Usage: system/core/init/compare-bootcharts.py base_bootchart_dir
-       exp_bootchart_dir
-
-process: baseline experiment (delta)
- - Unit is ms (a jiffy is 10 ms on the system)
-------------------------------------
-/init: 50 40 (-10)
-/system/bin/surfaceflinger: 4320 4470 (+150)
-/system/bin/bootanimation: 6980 6990 (+10)
-zygote64: 10410 10640 (+230)
-zygote: 10410 10640 (+230)
-system_server: 15350 15150 (-200)
-bootanimation ends at: 33790 31230 (-2560)
-
-
-Systrace
---------
-Systrace [1] can be used for obtaining performance analysis reports during boot
-time on userdebug or eng builds.
-Here is an example of trace events of "wm" and "am" categories:
-
-  $ANDROID_BUILD_TOP/external/chromium-trace/systrace.py wm am --boot
-
-This command will cause the device to reboot. After the device is rebooted and
-the boot sequence has finished, the trace report is obtained from the device
-and written as trace.html on the host by hitting Ctrl+C.
-
-LIMITATION
-Recording trace events is started after persistent properties are loaded, so
-the trace events that are emitted before that are not recorded. Several
-services such as vold, surfaceflinger, and servicemanager are affected by this
-limitation since they are started before persistent properties are loaded.
-Zygote initialization and the processes that are forked from the zygote are not
-affected.
-
-[1] http://developer.android.com/tools/help/systrace.html
-
-
-Debugging init
---------------
-By default, programs executed by init will drop stdout and stderr into
-/dev/null. To help with debugging, you can execute your program via the
-Android program logwrapper. This will redirect stdout/stderr into the
-Android logging system (accessed via logcat).
-
-For example
-service akmd /system/bin/logwrapper /sbin/akmd
-
-For quicker turnaround when working on init itself, use:
-
-  mm -j &&
-  m ramdisk-nodeps &&
-  m bootimage-nodeps &&
-  adb reboot bootloader &&
-  fastboot boot $ANDROID_PRODUCT_OUT/boot.img
-
-Alternatively, use the emulator:
-
-  emulator -partition-size 1024 -verbose -show-kernel -no-window
diff --git a/libcutils/klog.cpp b/libcutils/klog.cpp
index 4bad28a..15adf6b 100644
--- a/libcutils/klog.cpp
+++ b/libcutils/klog.cpp
@@ -27,7 +27,7 @@
 #include <cutils/android_get_control_file.h>
 #include <cutils/klog.h>
 
-static int klog_level = KLOG_DEFAULT_LEVEL;
+static int klog_level = KLOG_INFO_LEVEL;
 
 int klog_get_level(void) {
     return klog_level;
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 02feb97..ec0352e 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -1831,7 +1831,7 @@
         return;
     }
 
-    setuid(AID_SYSTEM); // only one that can read security buffer
+    EXPECT_EQ(0, setuid(AID_SYSTEM)); // only one that can read security buffer
 
     pid_t pid = getpid();
 
diff --git a/libmemtrack/memtrack.cpp b/libmemtrack/memtrack.cpp
index 1b38925..8adc8fc 100644
--- a/libmemtrack/memtrack.cpp
+++ b/libmemtrack/memtrack.cpp
@@ -23,7 +23,7 @@
 #include <string.h>
 #include <mutex>
 
-#include <android/log.h>
+#include <log/log.h>
 
 using android::hardware::memtrack::V1_0::IMemtrack;
 using android::hardware::memtrack::V1_0::MemtrackType;
diff --git a/libsparse/Android.bp b/libsparse/Android.bp
index 7a6ae8a..dd8b5fd 100644
--- a/libsparse/Android.bp
+++ b/libsparse/Android.bp
@@ -1,7 +1,9 @@
 // Copyright 2010 The Android Open Source Project
 
-cc_defaults {
-    name: "libsparse_defaults",
+cc_library {
+    name: "libsparse",
+    host_supported: true,
+    unique_host_soname: true,
     srcs: [
         "backed_block.c",
         "output_file.c",
@@ -13,32 +15,19 @@
     cflags: ["-Werror"],
     local_include_dirs: ["include"],
     export_include_dirs: ["include"],
-}
-
-cc_library_host_static {
-    name: "libsparse_host",
-    defaults: ["libsparse_defaults"],
-    static_libs: ["libz"],
     target: {
+        host: {
+            shared_libs: ["libz-host"],
+        },
+        android: {
+            shared_libs: ["libz"],
+        },
         windows: {
             enabled: true,
         },
     },
 }
 
-cc_library_shared {
-    name: "libsparse",
-    defaults: ["libsparse_defaults"],
-    shared_libs: ["libz"],
-}
-
-cc_library_static {
-    name: "libsparse_static",
-    host_supported: true,
-    defaults: ["libsparse_defaults"],
-    static_libs: ["libz"],
-}
-
 cc_binary {
     name: "simg2img",
     host_supported: true,
@@ -47,7 +36,7 @@
         "sparse_crc32.c",
     ],
     static_libs: [
-        "libsparse_static",
+        "libsparse",
         "libz",
     ],
 
@@ -59,7 +48,7 @@
     host_supported: true,
     srcs: ["img2simg.c"],
     static_libs: [
-        "libsparse_static",
+        "libsparse",
         "libz",
     ],
 
@@ -70,7 +59,7 @@
     name: "append2simg",
     srcs: ["append2simg.c"],
     static_libs: [
-        "libsparse_static",
+        "libsparse",
         "libz",
     ],
 
diff --git a/rootdir/init.rc b/rootdir/init.rc
index ccbad4b..50788c1 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -313,6 +313,7 @@
     # Make sure /sys/kernel/debug (if present) is labeled properly
     # Note that tracefs may be mounted under debug, so we need to cross filesystems
     restorecon --recursive --cross-filesystems /sys/kernel/debug
+    chmod 0755 /sys/kernel/debug/tracing
 
     # We chown/chmod /cache again so because mount is run as root + defaults
     chown system cache /cache
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index 8725113..0633a68 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -38,8 +38,6 @@
 # these should not be world writable
 /dev/diag                 0660   radio      radio
 /dev/diag_arm9            0660   radio      radio
-/dev/android_adb          0660   adb        adb
-/dev/android_adb_enable   0660   adb        adb
 /dev/ttyMSM0              0600   bluetooth  bluetooth
 /dev/uhid                 0660   system     bluetooth
 /dev/uinput               0660   system     bluetooth
diff --git a/storaged/include/storaged.h b/storaged/include/storaged.h
index eb827cf..957070c 100644
--- a/storaged/include/storaged.h
+++ b/storaged/include/storaged.h
@@ -17,13 +17,10 @@
 #ifndef _STORAGED_H_
 #define _STORAGED_H_
 
-#define DEBUG
-
 #include <queue>
 #include <semaphore.h>
 #include <stdint.h>
 #include <string>
-#include <syslog.h>
 #include <unordered_map>
 #include <vector>
 
@@ -39,21 +36,6 @@
 #define debuginfo(...)
 #endif
 
-#define KMSG_PRIORITY(PRI)                            \
-    '<',                                              \
-    '0' + LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(PRI)) / 10, \
-    '0' + LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(PRI)) % 10, \
-    '>'
-
-static char kmsg_error_prefix[] = { KMSG_PRIORITY(LOG_ERR),
-    's', 't', 'o', 'r', 'a', 'g', 'e', 'd', ':', '\0' };
-
-static char kmsg_info_prefix[] = { KMSG_PRIORITY(LOG_INFO),
-    's', 't', 'o', 'r', 'a', 'g', 'e', 'd', ':', '\0' };
-
-static char kmsg_warning_prefix[] = { KMSG_PRIORITY(LOG_WARNING),
-    's', 't', 'o', 'r', 'a', 'g', 'e', 'd', ':', '\0' };
-
 // number of attributes diskstats has
 #define DISK_STATS_SIZE ( 11 )
 // maximum size limit of a stats file
diff --git a/storaged/main.cpp b/storaged/main.cpp
index 31ada68..0cb0f5f 100644
--- a/storaged/main.cpp
+++ b/storaged/main.cpp
@@ -29,12 +29,12 @@
 #include <vector>
 
 #include <android-base/macros.h>
+#include <android-base/logging.h>
 #include <android-base/stringprintf.h>
 #include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
 #include <binder/IPCThreadState.h>
 #include <cutils/android_get_control_file.h>
-#include <cutils/klog.h>
 #include <cutils/sched_policy.h>
 #include <private/android_filesystem_config.h>
 
@@ -90,15 +90,10 @@
 }
 
 // Function of storaged's main thread
-extern int fd_dmesg;
 void* storaged_main(void* s) {
     storaged_t* storaged = (storaged_t*)s;
 
-    if (fd_dmesg >= 0) {
-        static const char start_message[] = {KMSG_PRIORITY(LOG_INFO),
-            's', 't', 'o', 'r', 'a', 'g', 'e', 'd', ':', ' ', 'S', 't', 'a', 'r', 't', '\n'};
-        write(fd_dmesg, start_message, sizeof(start_message));
-    }
+    LOG_TO(SYSTEM, INFO) << "storaged: Start";
 
     for (;;) {
         storaged->event();
@@ -121,7 +116,6 @@
 #define DAY_TO_SEC ( 3600 * 24 )
 
 int main(int argc, char** argv) {
-    klog_set_level(KLOG_LEVEL);
     int flag_main_service = 0;
     int flag_dump_task = 0;
     int flag_config = 0;
@@ -221,11 +215,6 @@
     }
 
     if (flag_main_service) { // start main thread
-        static const char dev_kmsg[] = "/dev/kmsg";
-        fd_dmesg = android_get_control_file(dev_kmsg);
-        if (fd_dmesg < 0)
-            fd_dmesg = TEMP_FAILURE_RETRY(open(dev_kmsg, O_WRONLY));
-
         static const char mmc0_ext_csd[] = "/d/mmc0/mmc0:0001/ext_csd";
         fd_emmc = android_get_control_file(mmc0_ext_csd);
         if (fd_emmc < 0)
@@ -245,12 +234,9 @@
 
         // Start the main thread of storaged
         pthread_t storaged_main_thread;
-        if (pthread_create(&storaged_main_thread, NULL, storaged_main, &storaged)) {
-            if (fd_dmesg >= 0) {
-                std::string error_message = android::base::StringPrintf(
-                    "%s Failed to create main thread\n", kmsg_error_prefix);
-                write(fd_dmesg, error_message.c_str(), error_message.length());
-            }
+        errno = pthread_create(&storaged_main_thread, NULL, storaged_main, &storaged);
+        if (errno != 0) {
+            PLOG_TO(SYSTEM, ERROR) << "Failed to create main thread";
             return -1;
         }
 
@@ -259,7 +245,6 @@
         IPCThreadState::self()->joinThreadPool();
         pthread_join(storaged_main_thread, NULL);
 
-        close(fd_dmesg);
         close(fd_emmc);
 
         return 0;
diff --git a/storaged/storaged.rc b/storaged/storaged.rc
index f72521c..5fdbb8a 100644
--- a/storaged/storaged.rc
+++ b/storaged/storaged.rc
@@ -1,5 +1,4 @@
 service storaged /system/bin/storaged
     class main
     file /d/mmc0/mmc0:0001/ext_csd r
-    file /dev/kmsg w
     group root readproc
diff --git a/storaged/storaged_utils.cpp b/storaged/storaged_utils.cpp
index 5e04888..e91b1bb 100644
--- a/storaged/storaged_utils.cpp
+++ b/storaged/storaged_utils.cpp
@@ -27,6 +27,7 @@
 #include <time.h>
 #include <unistd.h>
 
+#include <iomanip>
 #include <sstream>
 #include <string>
 #include <unordered_map>
@@ -35,8 +36,6 @@
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
-#include <cutils/klog.h>
-#include <log/log.h>
 #include <log/log_event_list.h>
 
 #include <storaged.h>
@@ -47,8 +46,6 @@
 #define MSEC_TO_USEC ( 1000 )
 #define USEC_TO_NSEC ( 1000 )
 
-int fd_dmesg = -1;
-
 bool parse_disk_stats(const char* disk_stats_path, struct disk_stats* stats) {
     // Get time
     struct timespec ts;
@@ -56,22 +53,13 @@
     // when system is running.
     int ret = clock_gettime(CLOCK_MONOTONIC, &ts);
     if (ret < 0) {
-        if (fd_dmesg >= 0) {
-            std::string error_message = android::base::StringPrintf(
-                "%s clock_gettime() failed with errno %d\n",
-                kmsg_error_prefix, ret);
-            write(fd_dmesg, error_message.c_str(), error_message.length());
-        }
+        PLOG_TO(SYSTEM, ERROR) << "clock_gettime() failed";
         return false;
     }
 
     std::string buffer;
     if (!android::base::ReadFileToString(disk_stats_path, &buffer)) {
-        if (fd_dmesg >= 0) {
-            std::string error_message = android::base::StringPrintf(
-                "%s %s: ReadFileToString failed.\n", kmsg_error_prefix, disk_stats_path);
-            write(fd_dmesg, error_message.c_str(), error_message.length());
-        }
+        PLOG_TO(SYSTEM, ERROR) << disk_stats_path << ": ReadFileToString failed.";
         return false;
     }
 
@@ -149,13 +137,10 @@
 
 // Add src to dst
 void add_disk_stats(struct disk_stats* src, struct disk_stats* dst) {
-    if (dst->end_time != 0 && dst->end_time != src->start_time && fd_dmesg >= 0) {
-        std::string warning_message = android::base::StringPrintf(
-            "%s Two dis-continuous periods of diskstats are added. "
-            "dst end with %jd, src start with %jd\n",
-            kmsg_warning_prefix, dst->end_time, src->start_time);
-
-        write(fd_dmesg, warning_message.c_str(), warning_message.length());
+    if (dst->end_time != 0 && dst->end_time != src->start_time) {
+        LOG_TO(SYSTEM, WARNING) << "Two dis-continuous periods of diskstats"
+            << " are added. dst end with " << dst->end_time
+            << ", src start with " << src->start_time;
     }
 
     for (uint i = 0; i < DISK_STATS_SIZE; ++i) {
@@ -193,21 +178,13 @@
     CHECK(lseek(ext_csd_fd, 0, SEEK_SET) == 0);
     std::string buffer;
     if (!android::base::ReadFdToString(ext_csd_fd, &buffer)) {
-        if (fd_dmesg >= 0) {
-            std::string error_message = android::base::StringPrintf(
-                "%s ReadFdToString failed.\n", kmsg_error_prefix);
-            write(fd_dmesg, error_message.c_str(), error_message.length());
-        }
+        PLOG_TO(SYSTEM, ERROR) << "ReadFdToString failed.";
         return false;
     }
 
     if (buffer.length() < EXT_CSD_FILE_MIN_SIZE) {
-        if (fd_dmesg >= 0) {
-            std::string error_message = android::base::StringPrintf(
-                "%s EMMC ext csd file has truncated content. File length: %d\n",
-                kmsg_error_prefix, (int)buffer.length());
-            write(fd_dmesg, error_message.c_str(), error_message.length());
-        }
+        LOG_TO(SYSTEM, ERROR) << "EMMC ext csd file has truncated content. "
+            << "File length: " << buffer.length();
         return false;
     }
 
@@ -219,11 +196,7 @@
     ss << sub;
     ss >> std::hex >> ext_csd_rev;
     if (ext_csd_rev < 0) {
-        if (fd_dmesg >= 0) {
-            std::string error_message = android::base::StringPrintf(
-                "%s Failure on parsing EXT_CSD_REV.\n", kmsg_error_prefix);
-            write(fd_dmesg, error_message.c_str(), error_message.length());
-        }
+        LOG_TO(SYSTEM, ERROR) << "Failure on parsing EXT_CSD_REV.";
         return false;
     }
     ss.clear();
@@ -248,11 +221,7 @@
     ss << sub;
     ss >> std::hex >> info->eol;
     if (info->eol < 0) {
-        if (fd_dmesg >= 0) {
-            std::string error_message = android::base::StringPrintf(
-                "%s Failure on parsing EXT_PRE_EOL_INFO.\n", kmsg_error_prefix);
-            write(fd_dmesg, error_message.c_str(), error_message.length());
-        }
+        LOG_TO(SYSTEM, ERROR) << "Failure on parsing EXT_PRE_EOL_INFO.";
         return false;
     }
     ss.clear();
@@ -263,11 +232,7 @@
     ss << sub;
     ss >> std::hex >> info->lifetime_a;
     if (info->lifetime_a < 0) {
-        if (fd_dmesg >= 0) {
-            std::string error_message = android::base::StringPrintf(
-                "%s Failure on parsing EXT_DEVICE_LIFE_TIME_EST_TYP_A.\n", kmsg_error_prefix);
-            write(fd_dmesg, error_message.c_str(), error_message.length());
-        }
+        LOG_TO(SYSTEM, ERROR) << "Failure on parsing EXT_DEVICE_LIFE_TIME_EST_TYP_A.";
         return false;
     }
     ss.clear();
@@ -277,11 +242,7 @@
     ss << sub;
     ss >> std::hex >> info->lifetime_b;
     if (info->lifetime_b < 0) {
-        if (fd_dmesg >= 0) {
-            std::string error_message = android::base::StringPrintf(
-                "%s Failure on parsing EXT_DEVICE_LIFE_TIME_EST_TYP_B.\n", kmsg_error_prefix);
-            write(fd_dmesg, error_message.c_str(), error_message.length());
-        }
+        LOG_TO(SYSTEM, ERROR) << "Failure on parsing EXT_DEVICE_LIFE_TIME_EST_TYP_B.";
         return false;
     }
     ss.clear();
@@ -481,19 +442,14 @@
     memset(&zero_cmp, 0, sizeof(zero_cmp));
     if (memcmp(&zero_cmp, stats, sizeof(struct disk_stats)) == 0) return;
 
-    if (fd_dmesg >= 0) {
-        std::string info_message = android::base::StringPrintf(
-            "%s diskstats %s: %ju %ju %ju %ju %ju %ju %ju %ju %ju %ju %.1f %ju %ju\n",
-             kmsg_info_prefix, type, stats->start_time, stats->end_time,
-             stats->read_ios, stats->read_merges,
-             stats->read_sectors, stats->read_ticks,
-             stats->write_ios, stats->write_merges,
-             stats->write_sectors, stats->write_ticks,
-             stats->io_avg, stats->io_ticks,
-             stats->io_in_queue);
-
-        write(fd_dmesg, info_message.c_str(), info_message.length());
-    }
+    LOG_TO(SYSTEM, INFO) << "diskstats " << type << ": "
+              << stats->start_time << " " << stats->end_time << " "
+              << stats->read_ios << " " << stats->read_merges << " "
+              << stats->read_sectors << " " << stats->read_ticks << " "
+              << stats->write_ios << " " << stats->write_merges << " "
+              << stats->write_sectors << " " << stats->write_ticks << " "
+              << std::setprecision(1) << std::fixed << stats->io_avg << " "
+              << stats->io_ticks << " " << stats->io_in_queue;
 }
 
 void log_kernel_disk_perf(struct disk_perf* perf, const char* type) {
@@ -503,16 +459,10 @@
     memset(&zero_cmp, 0, sizeof(zero_cmp));
     if (memcmp(&zero_cmp, perf, sizeof(struct disk_perf)) == 0) return;
 
-    if (fd_dmesg >= 0) {
-        std::string info_message = android::base::StringPrintf(
-            "%s perf(ios) %s rd:%luKB/s(%lu/s) wr:%luKB/s(%lu/s) q:%lu\n",
-            kmsg_info_prefix, type,
-            (unsigned long)perf->read_perf, (unsigned long)perf->read_ios,
-            (unsigned long)perf->write_perf, (unsigned long)perf->write_ios,
-            (unsigned long)perf->queue);
-
-        write(fd_dmesg, info_message.c_str(), info_message.length());
-    }
+    LOG_TO(SYSTEM, INFO) << "perf(ios) " << type
+              << " rd:" << perf->read_perf << "KB/s(" << perf->read_ios << "/s)"
+              << " wr:" << perf->write_perf << "KB/s(" << perf->write_ios << "/s)"
+              << " q:" << perf->queue;
 }
 
 void log_kernel_emmc_info(struct emmc_info* info) {
@@ -522,13 +472,9 @@
     memset(&zero_cmp, 0, sizeof(zero_cmp));
     if (memcmp(&zero_cmp, info, sizeof(struct emmc_info)) == 0) return;
 
-    if (fd_dmesg >= 0) {
-        std::string info_message = android::base::StringPrintf(
-            "%s MMC %s eol:%d, lifetime typA:%d, typB:%d\n",
-            kmsg_info_prefix, info->mmc_ver, info->eol, info->lifetime_a, info->lifetime_b);
-
-        write(fd_dmesg, info_message.c_str(), info_message.length());
-    }
+    LOG_TO(SYSTEM, INFO) << "MMC " << info->mmc_ver << " eol:" << info->eol << ", "
+              << "lifetime typA:" << info->lifetime_a
+              << ", typB:" << info->lifetime_b;
 }
 
 void log_event_disk_stats(struct disk_stats* stats, const char* type) {
@@ -539,26 +485,14 @@
     // skip event logging diskstats when it is zero increment (all first 11 entries are zero)
     if (memcmp(&zero_cmp, stats, sizeof(uint64_t) * DISK_STATS_SIZE) == 0) return;
 
-    // Construct eventlog list
-    android_log_context ctx = create_android_logger(EVENTLOGTAG_DISKSTATS);
-
-    android_log_write_string8(ctx, type);
-    android_log_write_int64(ctx, stats->start_time);
-    android_log_write_int64(ctx, stats->end_time);
-    android_log_write_int64(ctx, stats->read_ios);
-    android_log_write_int64(ctx, stats->read_merges);
-    android_log_write_int64(ctx, stats->read_sectors);
-    android_log_write_int64(ctx, stats->read_ticks);
-    android_log_write_int64(ctx, stats->write_ios);
-    android_log_write_int64(ctx, stats->write_merges);
-    android_log_write_int64(ctx, stats->write_sectors);
-    android_log_write_int64(ctx, stats->write_ticks);
-    android_log_write_int64(ctx, (uint64_t)stats->io_avg);
-    android_log_write_int64(ctx, stats->io_ticks);
-    android_log_write_int64(ctx, stats->io_in_queue);
-
-    android_log_write_list(ctx, LOG_ID_EVENTS);
-    android_log_destroy(&ctx);
+    android_log_event_list(EVENTLOGTAG_DISKSTATS)
+        << type << stats->start_time << stats->end_time
+        << stats->read_ios << stats->read_merges
+        << stats->read_sectors << stats->read_ticks
+        << stats->write_ios << stats->write_merges
+        << stats->write_sectors << stats->write_ticks
+        << (uint64_t)stats->io_avg << stats->io_ticks << stats->io_in_queue
+        << LOG_ID_EVENTS;
 }
 
 void log_event_emmc_info(struct emmc_info* info) {
@@ -568,13 +502,7 @@
     memset(&zero_cmp, 0, sizeof(zero_cmp));
     if (memcmp(&zero_cmp, info, sizeof(struct emmc_info)) == 0) return;
 
-    android_log_context ctx = create_android_logger(EVENTLOGTAG_EMMCINFO);
-
-    android_log_write_string8(ctx, info->mmc_ver);
-    android_log_write_int32(ctx, info->eol);
-    android_log_write_int32(ctx, info->lifetime_a);
-    android_log_write_int32(ctx, info->lifetime_b);
-
-    android_log_write_list(ctx, LOG_ID_EVENTS);
-    android_log_destroy(&ctx);
+    android_log_event_list(EVENTLOGTAG_EMMCINFO)
+        << info->mmc_ver << info->eol << info->lifetime_a << info->lifetime_b
+        << LOG_ID_EVENTS;
 }
diff --git a/trusty/storage/proxy/log.h b/trusty/storage/proxy/log.h
index 3d2e654..c81beab 100644
--- a/trusty/storage/proxy/log.h
+++ b/trusty/storage/proxy/log.h
@@ -16,5 +16,5 @@
 
 #define LOG_TAG "storageproxyd"
 
-#include <android/log.h>
+#include <log/log.h>