Merge "Using WideChar->UTF8 versions of Windows API to obtain temp folder."
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index 0200077..e085bc5 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -1307,8 +1307,8 @@
     // device itself. This device consists of the real blocks in the super
     // partition that this logical partition occupies.
     auto& dm = DeviceMapper::Instance();
-    std::string ignore_path;
-    if (!CreateLogicalPartition(params, &ignore_path)) {
+    std::string base_path;
+    if (!CreateLogicalPartition(params, &base_path)) {
         LOG(ERROR) << "Could not create logical partition " << params.GetPartitionName()
                    << " as device " << params.GetDeviceName();
         return false;
@@ -1316,6 +1316,7 @@
     created_devices.EmplaceBack<AutoUnmapDevice>(&dm, params.GetDeviceName());
 
     if (!live_snapshot_status.has_value()) {
+        *path = base_path;
         created_devices.Release();
         return true;
     }
diff --git a/libkeyutils/Android.bp b/libkeyutils/Android.bp
index dda491a..b388e95 100644
--- a/libkeyutils/Android.bp
+++ b/libkeyutils/Android.bp
@@ -16,17 +16,3 @@
     srcs: ["keyutils_test.cpp"],
     test_suites: ["device-tests"],
 }
-
-cc_binary {
-    name: "mini-keyctl",
-    srcs: [
-        "mini_keyctl.cpp",
-        "mini_keyctl_utils.cpp"
-    ],
-    shared_libs: [
-        "libbase",
-        "libkeyutils",
-        "liblog",
-    ],
-    cflags: ["-Werror", "-Wall", "-Wextra", "-fexceptions"],
-}
diff --git a/libkeyutils/mini_keyctl.cpp b/libkeyutils/mini_keyctl.cpp
deleted file mode 100644
index fe89e62..0000000
--- a/libkeyutils/mini_keyctl.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-/*
- * A tool loads keys to keyring.
- */
-
-#include "mini_keyctl_utils.h"
-
-#include <error.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <android-base/parseint.h>
-
-static void Usage(int exit_code) {
-  fprintf(stderr, "usage: mini-keyctl <action> [args,]\n");
-  fprintf(stderr, "       mini-keyctl add <type> <desc> <data> <keyring>\n");
-  fprintf(stderr, "       mini-keyctl padd <type> <desc> <keyring>\n");
-  fprintf(stderr, "       mini-keyctl unlink <key> <keyring>\n");
-  fprintf(stderr, "       mini-keyctl restrict_keyring <keyring>\n");
-  fprintf(stderr, "       mini-keyctl security <key>\n");
-  _exit(exit_code);
-}
-
-static key_serial_t parseKeyOrDie(const char* str) {
-  key_serial_t key;
-  if (!android::base::ParseInt(str, &key)) {
-    error(1 /* exit code */, 0 /* errno */, "Unparsable key: '%s'\n", str);
-  }
-  return key;
-}
-
-int main(int argc, const char** argv) {
-  if (argc < 2) Usage(1);
-  const std::string action = argv[1];
-
-  if (action == "add") {
-    if (argc != 6) Usage(1);
-    std::string type = argv[2];
-    std::string desc = argv[3];
-    std::string data = argv[4];
-    std::string keyring = argv[5];
-    return Add(type, desc, data, keyring);
-  } else if (action == "padd") {
-    if (argc != 5) Usage(1);
-    std::string type = argv[2];
-    std::string desc = argv[3];
-    std::string keyring = argv[4];
-    return Padd(type, desc, keyring);
-  } else if (action == "restrict_keyring") {
-    if (argc != 3) Usage(1);
-    std::string keyring = argv[2];
-    return RestrictKeyring(keyring);
-  } else if (action == "unlink") {
-    if (argc != 4) Usage(1);
-    key_serial_t key = parseKeyOrDie(argv[2]);
-    const std::string keyring = argv[3];
-    return Unlink(key, keyring);
-  } else if (action == "security") {
-    if (argc != 3) Usage(1);
-    const char* key_str = argv[2];
-    key_serial_t key = parseKeyOrDie(key_str);
-    std::string context = RetrieveSecurityContext(key);
-    if (context.empty()) {
-      perror(key_str);
-      return 1;
-    }
-    fprintf(stderr, "%s\n", context.c_str());
-    return 0;
-  } else {
-    fprintf(stderr, "Unrecognized action: %s\n", action.c_str());
-    Usage(1);
-  }
-
-  return 0;
-}
diff --git a/libkeyutils/mini_keyctl/Android.bp b/libkeyutils/mini_keyctl/Android.bp
new file mode 100644
index 0000000..a04a3db
--- /dev/null
+++ b/libkeyutils/mini_keyctl/Android.bp
@@ -0,0 +1,27 @@
+cc_library_static {
+    name: "libmini_keyctl_static",
+    srcs: [
+        "mini_keyctl_utils.cpp"
+    ],
+    shared_libs: [
+        "libbase",
+        "libkeyutils",
+    ],
+    cflags: ["-Werror", "-Wall", "-Wextra"],
+    export_include_dirs: ["."],
+}
+
+cc_binary {
+    name: "mini-keyctl",
+    srcs: [
+        "mini_keyctl.cpp",
+    ],
+    static_libs: [
+        "libmini_keyctl_static",
+    ],
+    shared_libs: [
+        "libbase",
+        "libkeyutils",
+    ],
+    cflags: ["-Werror", "-Wall", "-Wextra"],
+}
diff --git a/libkeyutils/mini_keyctl/mini_keyctl.cpp b/libkeyutils/mini_keyctl/mini_keyctl.cpp
new file mode 100644
index 0000000..8aace9a
--- /dev/null
+++ b/libkeyutils/mini_keyctl/mini_keyctl.cpp
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+/*
+ * A tool loads keys to keyring.
+ */
+
+#include <dirent.h>
+#include <errno.h>
+#include <error.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <iostream>
+#include <iterator>
+#include <string>
+
+#include <android-base/file.h>
+#include <android-base/parseint.h>
+#include <keyutils.h>
+#include <mini_keyctl_utils.h>
+
+constexpr int kMaxCertSize = 4096;
+
+static void Usage(int exit_code) {
+  fprintf(stderr, "usage: mini-keyctl <action> [args,]\n");
+  fprintf(stderr, "       mini-keyctl add <type> <desc> <data> <keyring>\n");
+  fprintf(stderr, "       mini-keyctl padd <type> <desc> <keyring>\n");
+  fprintf(stderr, "       mini-keyctl unlink <key> <keyring>\n");
+  fprintf(stderr, "       mini-keyctl restrict_keyring <keyring>\n");
+  fprintf(stderr, "       mini-keyctl security <key>\n");
+  _exit(exit_code);
+}
+
+static key_serial_t parseKeyOrDie(const char* str) {
+  key_serial_t key;
+  if (!android::base::ParseInt(str, &key)) {
+    error(1 /* exit code */, 0 /* errno */, "Unparsable key: '%s'\n", str);
+  }
+  return key;
+}
+
+int Unlink(key_serial_t key, const std::string& keyring) {
+  key_serial_t keyring_id = android::GetKeyringId(keyring);
+  if (keyctl_unlink(key, keyring_id) < 0) {
+    error(1, errno, "Failed to unlink key %x from keyring %s", key, keyring.c_str());
+    return 1;
+  }
+  return 0;
+}
+
+int Add(const std::string& type, const std::string& desc, const std::string& data,
+        const std::string& keyring) {
+  if (data.size() > kMaxCertSize) {
+    error(1, 0, "Certificate too large");
+    return 1;
+  }
+
+  key_serial_t keyring_id = android::GetKeyringId(keyring);
+  key_serial_t key = add_key(type.c_str(), desc.c_str(), data.c_str(), data.size(), keyring_id);
+
+  if (key < 0) {
+    error(1, errno, "Failed to add key");
+    return 1;
+  }
+
+  std::cout << key << std::endl;
+  return 0;
+}
+
+int Padd(const std::string& type, const std::string& desc, const std::string& keyring) {
+  key_serial_t keyring_id = android::GetKeyringId(keyring);
+
+  // read from stdin to get the certificates
+  std::istreambuf_iterator<char> begin(std::cin), end;
+  std::string data(begin, end);
+
+  if (data.size() > kMaxCertSize) {
+    error(1, 0, "Certificate too large");
+    return 1;
+  }
+
+  key_serial_t key = add_key(type.c_str(), desc.c_str(), data.c_str(), data.size(), keyring_id);
+
+  if (key < 0) {
+    error(1, errno, "Failed to add key");
+    return 1;
+  }
+
+  std::cout << key << std::endl;
+  return 0;
+}
+
+int RestrictKeyring(const std::string& keyring) {
+  key_serial_t keyring_id = android::GetKeyringId(keyring);
+  if (keyctl_restrict_keyring(keyring_id, nullptr, nullptr) < 0) {
+    error(1, errno, "Cannot restrict keyring '%s'", keyring.c_str());
+    return 1;
+  }
+  return 0;
+}
+
+std::string RetrieveSecurityContext(key_serial_t key) {
+  // Simply assume this size is enough in practice.
+  const int kMaxSupportedSize = 256;
+  std::string context;
+  context.resize(kMaxSupportedSize);
+  long retval = keyctl_get_security(key, context.data(), kMaxSupportedSize);
+  if (retval < 0) {
+    error(1, errno, "Cannot get security context of key %x", key);
+    return std::string();
+  }
+  if (retval > kMaxSupportedSize) {
+    error(1, 0, "The key has unexpectedly long security context than %d", kMaxSupportedSize);
+    return std::string();
+  }
+  context.resize(retval);
+  return context;
+}
+
+int main(int argc, const char** argv) {
+  if (argc < 2) Usage(1);
+  const std::string action = argv[1];
+
+  if (action == "add") {
+    if (argc != 6) Usage(1);
+    std::string type = argv[2];
+    std::string desc = argv[3];
+    std::string data = argv[4];
+    std::string keyring = argv[5];
+    return Add(type, desc, data, keyring);
+  } else if (action == "padd") {
+    if (argc != 5) Usage(1);
+    std::string type = argv[2];
+    std::string desc = argv[3];
+    std::string keyring = argv[4];
+    return Padd(type, desc, keyring);
+  } else if (action == "restrict_keyring") {
+    if (argc != 3) Usage(1);
+    std::string keyring = argv[2];
+    return RestrictKeyring(keyring);
+  } else if (action == "unlink") {
+    if (argc != 4) Usage(1);
+    key_serial_t key = parseKeyOrDie(argv[2]);
+    const std::string keyring = argv[3];
+    return Unlink(key, keyring);
+  } else if (action == "security") {
+    if (argc != 3) Usage(1);
+    const char* key_str = argv[2];
+    key_serial_t key = parseKeyOrDie(key_str);
+    std::string context = RetrieveSecurityContext(key);
+    if (context.empty()) {
+      perror(key_str);
+      return 1;
+    }
+    fprintf(stderr, "%s\n", context.c_str());
+    return 0;
+  } else {
+    fprintf(stderr, "Unrecognized action: %s\n", action.c_str());
+    Usage(1);
+  }
+
+  return 0;
+}
diff --git a/libkeyutils/mini_keyctl/mini_keyctl_utils.cpp b/libkeyutils/mini_keyctl/mini_keyctl_utils.cpp
new file mode 100644
index 0000000..fb9503f
--- /dev/null
+++ b/libkeyutils/mini_keyctl/mini_keyctl_utils.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2019 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 <mini_keyctl_utils.h>
+
+#include <fstream>
+#include <iterator>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <android-base/logging.h>
+#include <android-base/parseint.h>
+
+namespace android {
+
+namespace {
+
+std::vector<std::string> SplitBySpace(const std::string& s) {
+  std::istringstream iss(s);
+  return std::vector<std::string>{std::istream_iterator<std::string>{iss},
+                                  std::istream_iterator<std::string>{}};
+}
+
+}  // namespace
+
+// Find the keyring id. request_key(2) only finds keys in the process, session or thread keyring
+// hierarchy, but not internal keyring of a kernel subsystem (e.g. .fs-verity). To support all
+// cases, this function looks up a keyring's ID by parsing /proc/keys. The keyring description may
+// contain other information in the descritption section depending on the key type, only the first
+// word in the keyring description is used for searching.
+key_serial_t GetKeyringId(const std::string& keyring_desc) {
+  // If the keyring id is already a hex number, directly convert it to keyring id
+  key_serial_t keyring_id;
+  if (android::base::ParseInt(keyring_desc.c_str(), &keyring_id)) {
+    return keyring_id;
+  }
+
+  // Only keys allowed by SELinux rules will be shown here.
+  std::ifstream proc_keys_file("/proc/keys");
+  if (!proc_keys_file.is_open()) {
+    PLOG(ERROR) << "Failed to open /proc/keys";
+    return -1;
+  }
+
+  std::string line;
+  while (getline(proc_keys_file, line)) {
+    std::vector<std::string> tokens = SplitBySpace(line);
+    if (tokens.size() < 9) {
+      continue;
+    }
+    std::string key_id = "0x" + tokens[0];
+    std::string key_type = tokens[7];
+    // The key description may contain space.
+    std::string key_desc_prefix = tokens[8];
+    // The prefix has a ":" at the end
+    std::string key_desc_pattern = keyring_desc + ":";
+    if (key_type != "keyring" || key_desc_prefix != key_desc_pattern) {
+      continue;
+    }
+    if (!android::base::ParseInt(key_id.c_str(), &keyring_id)) {
+      LOG(ERROR) << "Unexpected key format in /proc/keys: " << key_id;
+      return -1;
+    }
+    return keyring_id;
+  }
+  return -1;
+}
+
+}  // namespace android
diff --git a/libkeyutils/mini_keyctl/mini_keyctl_utils.h b/libkeyutils/mini_keyctl/mini_keyctl_utils.h
new file mode 100644
index 0000000..cc31d29
--- /dev/null
+++ b/libkeyutils/mini_keyctl/mini_keyctl_utils.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2019 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 _MINI_KEYCTL_MINI_KEYCTL_UTILS_H_
+#define _MINI_KEYCTL_MINI_KEYCTL_UTILS_H_
+
+#include <string>
+
+#include <keyutils.h>
+
+namespace android {
+key_serial_t GetKeyringId(const std::string& keyring_desc);
+}  // namespace android
+
+#endif  // _MINI_KEYCTL_MINI_KEYCTL_UTILS_H_
diff --git a/libkeyutils/mini_keyctl_utils.cpp b/libkeyutils/mini_keyctl_utils.cpp
deleted file mode 100644
index 79b4680..0000000
--- a/libkeyutils/mini_keyctl_utils.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2019 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 <mini_keyctl_utils.h>
-
-#include <dirent.h>
-#include <errno.h>
-#include <error.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <fstream>
-#include <iostream>
-#include <iterator>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include <android-base/file.h>
-#include <android-base/parseint.h>
-#include <android-base/properties.h>
-#include <android-base/strings.h>
-#include <keyutils.h>
-
-static constexpr int kMaxCertSize = 4096;
-
-static std::vector<std::string> SplitBySpace(const std::string& s) {
-  std::istringstream iss(s);
-  return std::vector<std::string>{std::istream_iterator<std::string>{iss},
-                                  std::istream_iterator<std::string>{}};
-}
-
-// Find the keyring id. Because request_key(2) syscall is not available or the key is
-// kernel keyring, the id is looked up from /proc/keys. The keyring description may contain other
-// information in the descritption section depending on the key type, only the first word in the
-// keyring description is used for searching.
-static key_serial_t GetKeyringIdOrDie(const std::string& keyring_desc) {
-  // If the keyring id is already a hex number, directly convert it to keyring id
-  key_serial_t keyring_id;
-  if (android::base::ParseInt(keyring_desc.c_str(), &keyring_id)) {
-    return keyring_id;
-  }
-
-  // Only keys allowed by SELinux rules will be shown here.
-  std::ifstream proc_keys_file("/proc/keys");
-  if (!proc_keys_file.is_open()) {
-    error(1, errno, "Failed to open /proc/keys");
-    return -1;
-  }
-
-  std::string line;
-  while (getline(proc_keys_file, line)) {
-    std::vector<std::string> tokens = SplitBySpace(line);
-    if (tokens.size() < 9) {
-      continue;
-    }
-    std::string key_id = "0x" + tokens[0];
-    std::string key_type = tokens[7];
-    // The key description may contain space.
-    std::string key_desc_prefix = tokens[8];
-    // The prefix has a ":" at the end
-    std::string key_desc_pattern = keyring_desc + ":";
-    if (key_type != "keyring" || key_desc_prefix != key_desc_pattern) {
-      continue;
-    }
-    if (!android::base::ParseInt(key_id.c_str(), &keyring_id)) {
-      error(1, 0, "Unexpected key format in /proc/keys: %s", key_id.c_str());
-      return -1;
-    }
-    return keyring_id;
-  }
-  return -1;
-}
-
-int Unlink(key_serial_t key, const std::string& keyring) {
-  key_serial_t keyring_id = GetKeyringIdOrDie(keyring);
-  if (keyctl_unlink(key, keyring_id) < 0) {
-    error(1, errno, "Failed to unlink key %x from keyring %s", key, keyring.c_str());
-    return 1;
-  }
-  return 0;
-}
-
-int Add(const std::string& type, const std::string& desc, const std::string& data,
-        const std::string& keyring) {
-  if (data.size() > kMaxCertSize) {
-    error(1, 0, "Certificate too large");
-    return 1;
-  }
-
-  key_serial_t keyring_id = GetKeyringIdOrDie(keyring);
-  key_serial_t key = add_key(type.c_str(), desc.c_str(), data.c_str(), data.size(), keyring_id);
-
-  if (key < 0) {
-    error(1, errno, "Failed to add key");
-    return 1;
-  }
-
-  std::cout << key << std::endl;
-  return 0;
-}
-
-int Padd(const std::string& type, const std::string& desc, const std::string& keyring) {
-  key_serial_t keyring_id = GetKeyringIdOrDie(keyring);
-
-  // read from stdin to get the certificates
-  std::istreambuf_iterator<char> begin(std::cin), end;
-  std::string data(begin, end);
-
-  if (data.size() > kMaxCertSize) {
-    error(1, 0, "Certificate too large");
-    return 1;
-  }
-
-  key_serial_t key = add_key(type.c_str(), desc.c_str(), data.c_str(), data.size(), keyring_id);
-
-  if (key < 0) {
-    error(1, errno, "Failed to add key");
-    return 1;
-  }
-
-  std::cout << key << std::endl;
-  return 0;
-}
-
-int RestrictKeyring(const std::string& keyring) {
-  key_serial_t keyring_id = GetKeyringIdOrDie(keyring);
-  if (keyctl_restrict_keyring(keyring_id, nullptr, nullptr) < 0) {
-    error(1, errno, "Cannot restrict keyring '%s'", keyring.c_str());
-    return 1;
-  }
-  return 0;
-}
-
-std::string RetrieveSecurityContext(key_serial_t key) {
-  // Simply assume this size is enough in practice.
-  const int kMaxSupportedSize = 256;
-  std::string context;
-  context.resize(kMaxSupportedSize);
-  long retval = keyctl_get_security(key, context.data(), kMaxSupportedSize);
-  if (retval < 0) {
-    error(1, errno, "Cannot get security context of key %x", key);
-    return std::string();
-  }
-  if (retval > kMaxSupportedSize) {
-    error(1, 0, "The key has unexpectedly long security context than %d", kMaxSupportedSize);
-    return std::string();
-  }
-  context.resize(retval);
-  return context;
-}
diff --git a/libkeyutils/mini_keyctl_utils.h b/libkeyutils/mini_keyctl_utils.h
deleted file mode 100644
index 3616831..0000000
--- a/libkeyutils/mini_keyctl_utils.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2019 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 "include/keyutils.h"
-
-#include <string>
-
-// Add key to a keyring. Returns non-zero if error happens.
-int Add(const std::string& type, const std::string& desc, const std::string& data,
-        const std::string& keyring);
-
-// Add key from stdin to a keyring. Returns non-zero if error happens.
-int Padd(const std::string& type, const std::string& desc, const std::string& keyring);
-
-// Removes the link from a keyring to a key if exists. Return non-zero if error happens.
-int Unlink(key_serial_t key, const std::string& keyring);
-
-// Apply key-linking to a keyring. Return non-zero if error happens.
-int RestrictKeyring(const std::string& keyring);
-
-// Retrieves a key's security context. Return the context string, or empty string on error.
-std::string RetrieveSecurityContext(key_serial_t key);
diff --git a/liblog/Android.bp b/liblog/Android.bp
index 8a63007..c40c5ef 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -15,7 +15,6 @@
 //
 
 liblog_sources = [
-    "config_write.cpp",
     "log_event_list.cpp",
     "log_event_write.cpp",
     "logger_lock.cpp",
diff --git a/liblog/README.md b/liblog/README.md
index 98bee9f..871399a 100644
--- a/liblog/README.md
+++ b/liblog/README.md
@@ -96,11 +96,6 @@
 
     int android_log_destroy(android_log_context *ctx)
 
-    #include <log/log_transport.h>
-
-    int android_set_log_transport(int transport_flag)
-    int android_get_log_transport()
-
 Description
 -----------
 
@@ -144,11 +139,6 @@
 that was used when opening the sub-log.  It is recommended to open the log `ANDROID_LOG_RDONLY` in
 these cases.
 
-`android_set_log_transport()` selects transport filters.  Argument is either `LOGGER_DEFAULT`,
-`LOGGER_LOGD`, or `LOGGER_NULL`. Log to logger daemon for default or logd, or drop contents on floor
-respectively.  `Both android_set_log_transport()` and `android_get_log_transport()` return the
-current transport mask, or a negative errno for any problems.
-
 Errors
 ------
 
diff --git a/liblog/config_write.cpp b/liblog/config_write.cpp
deleted file mode 100644
index 6ed893d..0000000
--- a/liblog/config_write.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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 <log/log_transport.h>
-
-#include "config_write.h"
-#include "logger.h"
-
-struct listnode __android_log_transport_write = {&__android_log_transport_write,
-                                                 &__android_log_transport_write};
-struct listnode __android_log_persist_write = {&__android_log_persist_write,
-                                               &__android_log_persist_write};
-
-static void __android_log_add_transport(struct listnode* list,
-                                        struct android_log_transport_write* transport) {
-  uint32_t i;
-
-  /* Try to keep one functioning transport for each log buffer id */
-  for (i = LOG_ID_MIN; i < LOG_ID_MAX; i++) {
-    struct android_log_transport_write* transp;
-
-    if (list_empty(list)) {
-      if (!transport->available || ((*transport->available)(static_cast<log_id_t>(i)) >= 0)) {
-        list_add_tail(list, &transport->node);
-        return;
-      }
-    } else {
-      write_transport_for_each(transp, list) {
-        if (!transp->available) {
-          return;
-        }
-        if (((*transp->available)(static_cast<log_id_t>(i)) < 0) &&
-            (!transport->available || ((*transport->available)(static_cast<log_id_t>(i)) >= 0))) {
-          list_add_tail(list, &transport->node);
-          return;
-        }
-      }
-    }
-  }
-}
-
-void __android_log_config_write() {
-  if ((__android_log_transport == LOGGER_DEFAULT) || (__android_log_transport & LOGGER_LOGD)) {
-#if (FAKE_LOG_DEVICE == 0)
-    extern struct android_log_transport_write logdLoggerWrite;
-    extern struct android_log_transport_write pmsgLoggerWrite;
-
-    __android_log_add_transport(&__android_log_transport_write, &logdLoggerWrite);
-    __android_log_add_transport(&__android_log_persist_write, &pmsgLoggerWrite);
-#else
-    extern struct android_log_transport_write fakeLoggerWrite;
-
-    __android_log_add_transport(&__android_log_transport_write, &fakeLoggerWrite);
-#endif
-  }
-}
-
-void __android_log_config_write_close() {
-  struct android_log_transport_write* transport;
-  struct listnode* n;
-
-  write_transport_for_each_safe(transport, n, &__android_log_transport_write) {
-    transport->logMask = 0;
-    list_remove(&transport->node);
-  }
-  write_transport_for_each_safe(transport, n, &__android_log_persist_write) {
-    transport->logMask = 0;
-    list_remove(&transport->node);
-  }
-}
diff --git a/liblog/config_write.h b/liblog/config_write.h
deleted file mode 100644
index a901f13..0000000
--- a/liblog/config_write.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <cutils/list.h>
-
-#include "log_portability.h"
-
-__BEGIN_DECLS
-
-extern struct listnode __android_log_transport_write;
-extern struct listnode __android_log_persist_write;
-
-#define write_transport_for_each(transp, transports)                           \
-  for ((transp) = node_to_item((transports)->next,                             \
-                               struct android_log_transport_write, node);      \
-       ((transp) != node_to_item((transports),                                 \
-                                 struct android_log_transport_write, node)) && \
-       ((transp) != node_to_item((transp)->node.next,                          \
-                                 struct android_log_transport_write, node));   \
-       (transp) = node_to_item((transp)->node.next,                            \
-                               struct android_log_transport_write, node))
-
-#define write_transport_for_each_safe(transp, n, transports)                   \
-  for ((transp) = node_to_item((transports)->next,                             \
-                               struct android_log_transport_write, node),      \
-      (n) = (transp)->node.next;                                               \
-       ((transp) != node_to_item((transports),                                 \
-                                 struct android_log_transport_write, node)) && \
-       ((transp) !=                                                            \
-        node_to_item((n), struct android_log_transport_write, node));          \
-       (transp) = node_to_item((n), struct android_log_transport_write, node), \
-      (n) = (transp)->node.next)
-
-void __android_log_config_write();
-void __android_log_config_write_close();
-
-__END_DECLS
diff --git a/liblog/fake_writer.cpp b/liblog/fake_writer.cpp
index c0b0e69..4d07caa 100644
--- a/liblog/fake_writer.cpp
+++ b/liblog/fake_writer.cpp
@@ -20,7 +20,6 @@
 
 #include <log/log.h>
 
-#include "config_write.h"
 #include "fake_log_device.h"
 #include "log_portability.h"
 #include "logger.h"
@@ -32,9 +31,9 @@
 static int logFds[(int)LOG_ID_MAX] = {-1, -1, -1, -1, -1, -1};
 
 struct android_log_transport_write fakeLoggerWrite = {
-    .node = {&fakeLoggerWrite.node, &fakeLoggerWrite.node},
-    .context.priv = &logFds,
     .name = "fake",
+    .logMask = 0,
+    .context.priv = &logFds,
     .available = NULL,
     .open = fakeOpen,
     .close = fakeClose,
diff --git a/liblog/include/log/log_transport.h b/liblog/include/log/log_transport.h
deleted file mode 100644
index bda7c25..0000000
--- a/liblog/include/log/log_transport.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-**
-** Copyright 2017, The Android Open Source Project
-**
-** This file is dual licensed.  It may be redistributed and/or modified
-** under the terms of the Apache 2.0 License OR version 2 of the GNU
-** General Public License.
-*/
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Logging transports, bit mask to select features. Function returns selection.
- */
-/* clang-format off */
-#define LOGGER_DEFAULT 0x00
-#define LOGGER_LOGD    0x01
-#define LOGGER_KERNEL  0x02 /* Reserved/Deprecated */
-#define LOGGER_NULL    0x04 /* Does not release resources of other selections */
-#define LOGGER_RESERVED 0x08 /* Reserved, previously for logging to local memory */
-#define LOGGER_RESERVED2  0x10 /* Reserved, previously for logs sent to stderr */
-/* clang-format on */
-
-/* Both return the selected transport flag mask, or negative errno */
-int android_set_log_transport(int transport_flag);
-int android_get_log_transport();
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/liblog/log_event_list.cpp b/liblog/log_event_list.cpp
index f148ef3..18ea930 100644
--- a/liblog/log_event_list.cpp
+++ b/liblog/log_event_list.cpp
@@ -176,13 +176,6 @@
   return 0;
 }
 
-static inline void copy4LE(uint8_t* buf, uint32_t val) {
-  buf[0] = val & 0xFF;
-  buf[1] = (val >> 8) & 0xFF;
-  buf[2] = (val >> 16) & 0xFF;
-  buf[3] = (val >> 24) & 0xFF;
-}
-
 int android_log_write_int32(android_log_context ctx, int32_t value) {
   size_t needed;
   android_log_context_internal* context;
@@ -201,22 +194,11 @@
   }
   context->count[context->list_nest_depth]++;
   context->storage[context->pos + 0] = EVENT_TYPE_INT;
-  copy4LE(&context->storage[context->pos + 1], value);
+  *reinterpret_cast<int32_t*>(&context->storage[context->pos + 1]) = value;
   context->pos += needed;
   return 0;
 }
 
-static inline void copy8LE(uint8_t* buf, uint64_t val) {
-  buf[0] = val & 0xFF;
-  buf[1] = (val >> 8) & 0xFF;
-  buf[2] = (val >> 16) & 0xFF;
-  buf[3] = (val >> 24) & 0xFF;
-  buf[4] = (val >> 32) & 0xFF;
-  buf[5] = (val >> 40) & 0xFF;
-  buf[6] = (val >> 48) & 0xFF;
-  buf[7] = (val >> 56) & 0xFF;
-}
-
 int android_log_write_int64(android_log_context ctx, int64_t value) {
   size_t needed;
   android_log_context_internal* context;
@@ -235,7 +217,7 @@
   }
   context->count[context->list_nest_depth]++;
   context->storage[context->pos + 0] = EVENT_TYPE_LONG;
-  copy8LE(&context->storage[context->pos + 1], value);
+  *reinterpret_cast<int64_t*>(&context->storage[context->pos + 1]) = value;
   context->pos += needed;
   return 0;
 }
@@ -267,7 +249,7 @@
   }
   context->count[context->list_nest_depth]++;
   context->storage[context->pos + 0] = EVENT_TYPE_STRING;
-  copy4LE(&context->storage[context->pos + 1], len);
+  *reinterpret_cast<ssize_t*>(&context->storage[context->pos + 1]) = len;
   if (len) {
     memcpy(&context->storage[context->pos + 5], value, len);
   }
@@ -299,7 +281,7 @@
   ivalue = *(uint32_t*)&value;
   context->count[context->list_nest_depth]++;
   context->storage[context->pos + 0] = EVENT_TYPE_FLOAT;
-  copy4LE(&context->storage[context->pos + 1], ivalue);
+  *reinterpret_cast<uint32_t*>(&context->storage[context->pos + 1]) = ivalue;
   context->pos += needed;
   return 0;
 }
diff --git a/liblog/logd_reader.cpp b/liblog/logd_reader.cpp
index d5bf844..e372dce 100644
--- a/liblog/logd_reader.cpp
+++ b/liblog/logd_reader.cpp
@@ -66,7 +66,6 @@
                             struct android_log_transport_context* transp, char* buf, size_t len);
 
 struct android_log_transport_read logdLoggerRead = {
-    .node = {&logdLoggerRead.node, &logdLoggerRead.node},
     .name = "logd",
     .available = logdAvailable,
     .version = logdVersion,
diff --git a/liblog/logd_writer.cpp b/liblog/logd_writer.cpp
index 2c64b0b..09aaffb 100644
--- a/liblog/logd_writer.cpp
+++ b/liblog/logd_writer.cpp
@@ -34,7 +34,6 @@
 #include <private/android_filesystem_config.h>
 #include <private/android_logger.h>
 
-#include "config_write.h"
 #include "log_portability.h"
 #include "logger.h"
 #include "uio.h"
@@ -48,9 +47,9 @@
 static int logdWrite(log_id_t logId, struct timespec* ts, struct iovec* vec, size_t nr);
 
 struct android_log_transport_write logdLoggerWrite = {
-    .node = {&logdLoggerWrite.node, &logdLoggerWrite.node},
-    .context.sock = -EBADF,
     .name = "logd",
+    .logMask = 0,
+    .context.sock = -EBADF,
     .available = logdAvailable,
     .open = logdOpen,
     .close = logdClose,
diff --git a/liblog/logger.h b/liblog/logger.h
index 4b4ef5f..8cae66c 100644
--- a/liblog/logger.h
+++ b/liblog/logger.h
@@ -31,12 +31,9 @@
   void* priv;
   atomic_int sock;
   atomic_int fd;
-  struct listnode* node;
-  atomic_uintptr_t atomic_pointer;
 };
 
 struct android_log_transport_write {
-  struct listnode node;
   const char* name;                  /* human name to describe the transport */
   unsigned logMask;                  /* mask cache of available() success */
   union android_log_context_union context; /* Initialized by static allocation */
@@ -54,7 +51,6 @@
 struct android_log_logger;
 
 struct android_log_transport_read {
-  struct listnode node;
   const char* name; /* human name to describe the transport */
 
   /* Does not cause resources to be taken */
@@ -149,6 +145,4 @@
 int __android_log_trylock();
 void __android_log_unlock();
 
-extern int __android_log_transport;
-
 __END_DECLS
diff --git a/liblog/logger_write.cpp b/liblog/logger_write.cpp
index 7fc8747..abcead7 100644
--- a/liblog/logger_write.cpp
+++ b/liblog/logger_write.cpp
@@ -25,17 +25,18 @@
 #endif
 
 #include <log/event_tag_map.h>
-#include <log/log_transport.h>
 #include <private/android_filesystem_config.h>
 #include <private/android_logger.h>
 
-#include "config_write.h"
 #include "log_portability.h"
 #include "logger.h"
 #include "uio.h"
 
 #define LOG_BUF_SIZE 1024
 
+android_log_transport_write* android_log_write = nullptr;
+android_log_transport_write* android_log_persist_write = nullptr;
+
 static int __write_to_log_init(log_id_t, struct iovec* vec, size_t nr);
 static int (*write_to_log)(log_id_t, struct iovec* vec, size_t nr) = __write_to_log_init;
 
@@ -105,7 +106,6 @@
  * Release any logger resources. A new log write will immediately re-acquire.
  */
 void __android_log_close() {
-  struct android_log_transport_write* transport;
 #if defined(__ANDROID__)
   EventTagMap* m;
 #endif
@@ -124,19 +124,16 @@
    * disengenuous use of this function.
    */
 
-  write_transport_for_each(transport, &__android_log_persist_write) {
-    if (transport->close) {
-      (*transport->close)();
-    }
+  if (android_log_write != nullptr) {
+    android_log_write->close();
   }
 
-  write_transport_for_each(transport, &__android_log_transport_write) {
-    if (transport->close) {
-      (*transport->close)();
-    }
+  if (android_log_persist_write != nullptr) {
+    android_log_persist_write->close();
   }
 
-  __android_log_config_write_close();
+  android_log_write = nullptr;
+  android_log_persist_write = nullptr;
 
 #if defined(__ANDROID__)
   /*
@@ -161,52 +158,52 @@
 #endif
 }
 
+static bool transport_initialize(android_log_transport_write* transport) {
+  if (transport == nullptr) {
+    return false;
+  }
+
+  __android_log_cache_available(transport);
+  if (!transport->logMask) {
+    return false;
+  }
+
+  // TODO: Do we actually need to call close() if open() fails?
+  if (transport->open() < 0) {
+    transport->close();
+    return false;
+  }
+
+  return true;
+}
+
 /* log_init_lock assumed */
 static int __write_to_log_initialize() {
-  struct android_log_transport_write* transport;
-  struct listnode* n;
-  int i = 0, ret = 0;
+#if (FAKE_LOG_DEVICE == 0)
+  extern struct android_log_transport_write logdLoggerWrite;
+  extern struct android_log_transport_write pmsgLoggerWrite;
 
-  __android_log_config_write();
-  write_transport_for_each_safe(transport, n, &__android_log_transport_write) {
-    __android_log_cache_available(transport);
-    if (!transport->logMask) {
-      list_remove(&transport->node);
-      continue;
-    }
-    if (!transport->open || ((*transport->open)() < 0)) {
-      if (transport->close) {
-        (*transport->close)();
-      }
-      list_remove(&transport->node);
-      continue;
-    }
-    ++ret;
-  }
-  write_transport_for_each_safe(transport, n, &__android_log_persist_write) {
-    __android_log_cache_available(transport);
-    if (!transport->logMask) {
-      list_remove(&transport->node);
-      continue;
-    }
-    if (!transport->open || ((*transport->open)() < 0)) {
-      if (transport->close) {
-        (*transport->close)();
-      }
-      list_remove(&transport->node);
-      continue;
-    }
-    ++i;
-  }
-  if (!ret && !i) {
+  android_log_write = &logdLoggerWrite;
+  android_log_persist_write = &pmsgLoggerWrite;
+#else
+  extern struct android_log_transport_write fakeLoggerWrite;
+
+  android_log_write = &fakeLoggerWrite;
+#endif
+
+  if (!transport_initialize(android_log_write)) {
+    android_log_write = nullptr;
     return -ENODEV;
   }
 
-  return ret;
+  if (!transport_initialize(android_log_persist_write)) {
+    android_log_persist_write = nullptr;
+  }
+
+  return 1;
 }
 
 static int __write_to_log_daemon(log_id_t log_id, struct iovec* vec, size_t nr) {
-  struct android_log_transport_write* node;
   int ret, save_errno;
   struct timespec ts;
   size_t len, i;
@@ -283,28 +280,11 @@
       return -EPERM;
     }
   } else {
-    /* Validate the incoming tag, tag content can not split across iovec */
-    char prio = ANDROID_LOG_VERBOSE;
-    const char* tag = static_cast<const char*>(vec[0].iov_base);
-    size_t len = vec[0].iov_len;
-    if (!tag) {
-      len = 0;
-    }
-    if (len > 0) {
-      prio = *tag;
-      if (len > 1) {
-        --len;
-        ++tag;
-      } else {
-        len = vec[1].iov_len;
-        tag = ((const char*)vec[1].iov_base);
-        if (!tag) {
-          len = 0;
-        }
-      }
-    }
+    int prio = *static_cast<int*>(vec[0].iov_base);
+    const char* tag = static_cast<const char*>(vec[1].iov_base);
+    size_t len = vec[1].iov_len;
     /* tag must be nul terminated */
-    if (tag && strnlen(tag, len) >= len) {
+    if (strnlen(tag, len) >= len) {
       tag = NULL;
     }
 
@@ -325,20 +305,17 @@
 
   ret = 0;
   i = 1 << log_id;
-  write_transport_for_each(node, &__android_log_transport_write) {
-    if (node->logMask & i) {
-      ssize_t retval;
-      retval = (*node->write)(log_id, &ts, vec, nr);
-      if (ret >= 0) {
-        ret = retval;
-      }
+
+  if (android_log_write != nullptr && (android_log_write->logMask & i)) {
+    ssize_t retval;
+    retval = android_log_write->write(log_id, &ts, vec, nr);
+    if (ret >= 0) {
+      ret = retval;
     }
   }
 
-  write_transport_for_each(node, &__android_log_persist_write) {
-    if (node->logMask & i) {
-      (void)(*node->write)(log_id, &ts, vec, nr);
-    }
+  if (android_log_persist_write != nullptr && (android_log_persist_write->logMask & i)) {
+    android_log_persist_write->write(log_id, &ts, vec, nr);
   }
 
   errno = save_errno;
@@ -354,9 +331,6 @@
     ret = __write_to_log_initialize();
     if (ret < 0) {
       __android_log_unlock();
-      if (!list_empty(&__android_log_persist_write)) {
-        __write_to_log_daemon(log_id, vec, nr);
-      }
       errno = save_errno;
       return ret;
     }
@@ -546,81 +520,3 @@
 
   return write_to_log(LOG_ID_SECURITY, vec, 4);
 }
-
-static int __write_to_log_null(log_id_t log_id, struct iovec* vec, size_t nr) {
-  size_t len, i;
-
-  if ((log_id < LOG_ID_MIN) || (log_id >= LOG_ID_MAX)) {
-    return -EINVAL;
-  }
-
-  for (len = i = 0; i < nr; ++i) {
-    len += vec[i].iov_len;
-  }
-  if (!len) {
-    return -EINVAL;
-  }
-  return len;
-}
-
-/* Following functions need access to our internal write_to_log status */
-
-int __android_log_transport;
-
-int android_set_log_transport(int transport_flag) {
-  int retval;
-
-  if (transport_flag < 0) {
-    return -EINVAL;
-  }
-
-  retval = LOGGER_NULL;
-
-  __android_log_lock();
-
-  if (transport_flag & LOGGER_NULL) {
-    write_to_log = __write_to_log_null;
-
-    __android_log_unlock();
-
-    return retval;
-  }
-
-  __android_log_transport &= LOGGER_LOGD;
-
-  transport_flag &= LOGGER_LOGD;
-
-  if (__android_log_transport != transport_flag) {
-    __android_log_transport = transport_flag;
-    __android_log_config_write_close();
-
-    write_to_log = __write_to_log_init;
-    /* generically we only expect these two values for write_to_log */
-  } else if ((write_to_log != __write_to_log_init) && (write_to_log != __write_to_log_daemon)) {
-    write_to_log = __write_to_log_init;
-  }
-
-  retval = __android_log_transport;
-
-  __android_log_unlock();
-
-  return retval;
-}
-
-int android_get_log_transport() {
-  int ret = LOGGER_DEFAULT;
-
-  __android_log_lock();
-  if (write_to_log == __write_to_log_null) {
-    ret = LOGGER_NULL;
-  } else {
-    __android_log_transport &= LOGGER_LOGD;
-    ret = __android_log_transport;
-    if ((write_to_log != __write_to_log_init) && (write_to_log != __write_to_log_daemon)) {
-      ret = -EINVAL;
-    }
-  }
-  __android_log_unlock();
-
-  return ret;
-}
diff --git a/liblog/pmsg_reader.cpp b/liblog/pmsg_reader.cpp
index 005fec8..2db45a1 100644
--- a/liblog/pmsg_reader.cpp
+++ b/liblog/pmsg_reader.cpp
@@ -37,7 +37,6 @@
                      struct android_log_transport_context* transp);
 
 struct android_log_transport_read pmsgLoggerRead = {
-    .node = {&pmsgLoggerRead.node, &pmsgLoggerRead.node},
     .name = "pmsg",
     .available = pmsgAvailable,
     .version = pmsgVersion,
diff --git a/liblog/pmsg_writer.cpp b/liblog/pmsg_writer.cpp
index 69720ed..54980d9 100644
--- a/liblog/pmsg_writer.cpp
+++ b/liblog/pmsg_writer.cpp
@@ -29,7 +29,6 @@
 #include <private/android_filesystem_config.h>
 #include <private/android_logger.h>
 
-#include "config_write.h"
 #include "log_portability.h"
 #include "logger.h"
 #include "uio.h"
@@ -40,9 +39,9 @@
 static int pmsgWrite(log_id_t logId, struct timespec* ts, struct iovec* vec, size_t nr);
 
 struct android_log_transport_write pmsgLoggerWrite = {
-    .node = {&pmsgLoggerWrite.node, &pmsgLoggerWrite.node},
-    .context.fd = -1,
     .name = "pmsg",
+    .logMask = 0,
+    .context.fd = -1,
     .available = pmsgAvailable,
     .open = pmsgOpen,
     .close = pmsgClose,
@@ -100,7 +99,7 @@
       return -EINVAL;
     }
 
-    if (SNET_EVENT_LOG_TAG != *static_cast<uint8_t*>(vec[0].iov_base)) {
+    if (SNET_EVENT_LOG_TAG != *static_cast<uint32_t*>(vec[0].iov_base)) {
       return -EPERM;
     }
   }
diff --git a/liblog/tests/liblog_benchmark.cpp b/liblog/tests/liblog_benchmark.cpp
index 7163743..4642b9b 100644
--- a/liblog/tests/liblog_benchmark.cpp
+++ b/liblog/tests/liblog_benchmark.cpp
@@ -29,7 +29,6 @@
 #include <benchmark/benchmark.h>
 #include <cutils/sockets.h>
 #include <log/event_tag_map.h>
-#include <log/log_transport.h>
 #include <private/android_logger.h>
 
 BENCHMARK_MAIN();
@@ -73,21 +72,6 @@
 }
 BENCHMARK(BM_log_maximum);
 
-static void set_log_null() {
-  android_set_log_transport(LOGGER_NULL);
-}
-
-static void set_log_default() {
-  android_set_log_transport(LOGGER_DEFAULT);
-}
-
-static void BM_log_maximum_null(benchmark::State& state) {
-  set_log_null();
-  BM_log_maximum(state);
-  set_log_default();
-}
-BENCHMARK(BM_log_maximum_null);
-
 /*
  *	Measure the time it takes to collect the time using
  * discrete acquisition (state.PauseTiming() to state.ResumeTiming())
@@ -618,13 +602,6 @@
 }
 BENCHMARK(BM_log_event_overhead_42);
 
-static void BM_log_event_overhead_null(benchmark::State& state) {
-  set_log_null();
-  BM_log_event_overhead(state);
-  set_log_default();
-}
-BENCHMARK(BM_log_event_overhead_null);
-
 /*
  *	Measure the time it takes to submit the android event logging call
  * using discrete acquisition under very-light load (<1% CPU utilization).
@@ -639,15 +616,6 @@
 }
 BENCHMARK(BM_log_light_overhead);
 
-static void BM_log_light_overhead_null(benchmark::State& state) {
-  set_log_null();
-  BM_log_light_overhead(state);
-  set_log_default();
-}
-// Default gets out of hand for this test, so we set a reasonable number of
-// iterations for a timely result.
-BENCHMARK(BM_log_light_overhead_null)->Iterations(500);
-
 static void caught_latency(int /*signum*/) {
   unsigned long long v = 0xDEADBEEFA55A5AA5ULL;
 
diff --git a/liblog/tests/log_wrap_test.cpp b/liblog/tests/log_wrap_test.cpp
index ebf0b15..c7dd8e8 100644
--- a/liblog/tests/log_wrap_test.cpp
+++ b/liblog/tests/log_wrap_test.cpp
@@ -27,12 +27,9 @@
 #include <log/log_properties.h>
 #include <log/log_read.h>
 #include <log/log_time.h>
-#include <log/log_transport.h>
 
 #ifdef __ANDROID__
 static void read_with_wrap() {
-  android_set_log_transport(LOGGER_LOGD);
-
   // Read the last line in the log to get a starting timestamp. We're assuming
   // the log is not empty.
   const int mode = ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK;
diff --git a/lmkd/event.logtags b/lmkd/event.logtags
index 065c6db..452f411 100644
--- a/lmkd/event.logtags
+++ b/lmkd/event.logtags
@@ -17,8 +17,8 @@
 # Multiple values are separated by commas.
 #
 # The data type is a number from the following values:
-# 1: int
-# 2: long
+# 1: int32_t
+# 2: int64_t
 # 3: string
 # 4: list
 #
@@ -34,5 +34,5 @@
 #
 # TODO: generate ".java" and ".h" files with integer constants from this file.
 
-# for meminfo logs
-10195355 meminfo (MemFree|1),(Cached|1),(SwapCached|1),(Buffers|1),(Shmem|1),(Unevictable|1),(SwapTotal|1),(SwapFree|1),(ActiveAnon|1),(InactiveAnon|1),(ActiveFile|1),(InactiveFile|1),(SReclaimable|1),(SUnreclaim|1),(KernelStack|1),(PageTables|1),(ION_heap|1),(ION_heap_pool|1),(CmaFree|1)
+# for killinfo logs
+10195355 killinfo (Pid|1|5),(Uid|1|5),(OomAdj|1),(MinOomAdj|1),(TaskSize|1),(enum kill_reasons|1|5),(MemFree|1),(Cached|1),(SwapCached|1),(Buffers|1),(Shmem|1),(Unevictable|1),(SwapTotal|1),(SwapFree|1),(ActiveAnon|1),(InactiveAnon|1),(ActiveFile|1),(InactiveFile|1),(SReclaimable|1),(SUnreclaim|1),(KernelStack|1),(PageTables|1),(IonHeap|1),(IonHeapPool|1),(CmaFree|1)
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 449088a..e3f2bc2 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -84,7 +84,7 @@
 #define PERCEPTIBLE_APP_ADJ 200
 
 /* Android Logger event logtags (see event.logtags) */
-#define MEMINFO_LOG_TAG 10195355
+#define KILLINFO_LOG_TAG 10195355
 
 /* gid containing AID_SYSTEM required */
 #define INKERNEL_MINFREE_PATH "/sys/module/lowmemorykiller/parameters/minfree"
@@ -1394,7 +1394,7 @@
     char *buf;
     char *save_ptr;
     char *line;
-    char zone_name[LINE_MAX];
+    char zone_name[LINE_MAX + 1];
     struct zoneinfo_node *node = NULL;
     int node_idx = 0;
     int zone_idx = 0;
@@ -1566,7 +1566,17 @@
     return 0;
 }
 
-static void meminfo_log(union meminfo *mi) {
+static void killinfo_log(struct proc* procp, int min_oom_score, int tasksize,
+                         int kill_reason, union meminfo *mi) {
+    /* log process information */
+    android_log_write_int32(ctx, procp->pid);
+    android_log_write_int32(ctx, procp->uid);
+    android_log_write_int32(ctx, procp->oomadj);
+    android_log_write_int32(ctx, min_oom_score);
+    android_log_write_int32(ctx, (int32_t)min(tasksize * page_k, INT32_MAX));
+    android_log_write_int32(ctx, kill_reason);
+
+    /* log meminfo fields */
     for (int field_idx = 0; field_idx < MI_FIELD_COUNT; field_idx++) {
         android_log_write_int32(ctx, (int32_t)min(mi->arr[field_idx] * page_k, INT32_MAX));
     }
@@ -1640,7 +1650,8 @@
 static int last_killed_pid = -1;
 
 /* Kill one process specified by procp.  Returns the size of the process killed */
-static int kill_one_process(struct proc* procp, int min_oom_score, const char *reason) {
+static int kill_one_process(struct proc* procp, int min_oom_score, int kill_reason,
+                            const char *kill_desc, union meminfo *mi) {
     int pid = procp->pid;
     uid_t uid = procp->uid;
     int tgid;
@@ -1684,9 +1695,12 @@
     set_process_group_and_prio(pid, SP_FOREGROUND, ANDROID_PRIORITY_HIGHEST);
 
     inc_killcnt(procp->oomadj);
-    if (reason) {
+
+    killinfo_log(procp, min_oom_score, tasksize, kill_reason, mi);
+
+    if (kill_desc) {
         ALOGI("Kill '%s' (%d), uid %d, oom_adj %d to free %ldkB; reason: %s", taskname, pid,
-              uid, procp->oomadj, tasksize * page_k, reason);
+              uid, procp->oomadj, tasksize * page_k, kill_desc);
     } else {
         ALOGI("Kill '%s' (%d), uid %d, oom_adj %d to free %ldkB", taskname, pid,
               uid, procp->oomadj, tasksize * page_k);
@@ -1712,7 +1726,8 @@
  * Find one process to kill at or above the given oom_adj level.
  * Returns size of the killed process.
  */
-static int find_and_kill_process(int min_score_adj, const char *reason) {
+static int find_and_kill_process(int min_score_adj, int kill_reason, const char *kill_desc,
+                                 union meminfo *mi) {
     int i;
     int killed_size = 0;
     bool lmk_state_change_start = false;
@@ -1727,7 +1742,7 @@
             if (!procp)
                 break;
 
-            killed_size = kill_one_process(procp, min_score_adj, reason);
+            killed_size = kill_one_process(procp, min_score_adj, kill_reason, kill_desc, mi);
             if (killed_size >= 0) {
                 if (!lmk_state_change_start) {
                     lmk_state_change_start = true;
@@ -2051,7 +2066,7 @@
 
     /* Kill a process if necessary */
     if (kill_reason != NONE) {
-        int pages_freed = find_and_kill_process(min_score_adj, kill_desc);
+        int pages_freed = find_and_kill_process(min_score_adj, kill_reason, kill_desc, &mi);
         if (pages_freed > 0) {
             killing = true;
             if (cut_thrashing_limit) {
@@ -2062,7 +2077,6 @@
                 thrashing_limit = (thrashing_limit * (100 - thrashing_limit_decay_pct)) / 100;
             }
         }
-        meminfo_log(&mi);
     }
 
 no_kill:
@@ -2251,12 +2265,10 @@
 do_kill:
     if (low_ram_device) {
         /* For Go devices kill only one task */
-        if (find_and_kill_process(level_oomadj[level], NULL) == 0) {
+        if (find_and_kill_process(level_oomadj[level], -1, NULL, &mi) == 0) {
             if (debug_process_killing) {
                 ALOGI("Nothing to kill");
             }
-        } else {
-            meminfo_log(&mi);
         }
     } else {
         int pages_freed;
@@ -2276,7 +2288,7 @@
             min_score_adj = level_oomadj[level];
         }
 
-        pages_freed = find_and_kill_process(min_score_adj, NULL);
+        pages_freed = find_and_kill_process(min_score_adj, -1, NULL, &mi);
 
         if (pages_freed == 0) {
             /* Rate limit kill reports when nothing was reclaimed */
@@ -2289,9 +2301,7 @@
             last_kill_tm = curr_tm;
         }
 
-        /* Log meminfo whenever we kill or when report rate limit allows */
-        meminfo_log(&mi);
-
+        /* Log whenever we kill or when report rate limit allows */
         if (use_minfree_levels) {
             ALOGI("Reclaimed %ldkB, cache(%ldkB) and "
                 "free(%" PRId64 "kB)-reserved(%" PRId64 "kB) below min(%ldkB) for oom_adj %d",
@@ -2714,7 +2724,7 @@
     thrashing_limit_decay_pct = clamp(0, 100, property_get_int32("ro.lmk.thrashing_limit_decay",
         low_ram_device ? DEF_THRASHING_DECAY_LOWRAM : DEF_THRASHING_DECAY));
 
-    ctx = create_android_logger(MEMINFO_LOG_TAG);
+    ctx = create_android_logger(KILLINFO_LOG_TAG);
 
     statslog_init();
 
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index a0059db..c8f0a8b 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -58,15 +58,6 @@
 endif
 
 #######################################
-# fsverity_init
-
-include $(CLEAR_VARS)
-LOCAL_MODULE:= fsverity_init
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_SRC_FILES := fsverity_init.sh
-include $(BUILD_PREBUILT)
-
-#######################################
 # init.environ.rc
 
 include $(CLEAR_VARS)
diff --git a/rootdir/fsverity_init.sh b/rootdir/fsverity_init.sh
deleted file mode 100644
index 4fee15f..0000000
--- a/rootdir/fsverity_init.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/system/bin/sh
-#
-# Copyright (C) 2019 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.
-#
-
-# Enforce fsverity signature checking
-echo 1 > /proc/sys/fs/verity/require_signatures
-
-# Load all keys
-for cert in /product/etc/security/fsverity/*.der; do
-  /system/bin/mini-keyctl padd asymmetric fsv_product .fs-verity < "$cert" ||
-    log -p e -t fsverity_init "Failed to load $cert"
-done
-
-DEBUGGABLE=$(getprop ro.debuggable)
-if [ $DEBUGGABLE != "1" ]; then
-  # Prevent future key links to .fs-verity keyring
-  /system/bin/mini-keyctl restrict_keyring .fs-verity ||
-    log -p e -t fsverity_init "Failed to restrict .fs-verity keyring"
-fi
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 9183901..bad0642 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -489,10 +489,6 @@
     mkdir /data/bootchart 0755 shell shell
     bootchart start
 
-    # Load fsverity keys. This needs to happen before apexd, as post-install of
-    # APEXes may rely on keys.
-    exec -- /system/bin/fsverity_init
-
     # Make sure that apexd is started in the default namespace
     enter_default_mount_ns
 
@@ -823,6 +819,9 @@
 
     class_start core
 
+    # Requires keystore (currently a core service) to be ready first.
+    exec -- /system/bin/fsverity_init
+
 on nonencrypted
     class_start main
     class_start late_start