Merge "Support getting public key data"
diff --git a/adb/daemon/remount_service.cpp b/adb/daemon/remount_service.cpp
index c36f1b6..5e6d416 100644
--- a/adb/daemon/remount_service.cpp
+++ b/adb/daemon/remount_service.cpp
@@ -49,6 +49,8 @@
 #include "set_verity_enable_state_service.h"
 
 using android::base::Realpath;
+using android::fs_mgr::Fstab;
+using android::fs_mgr::ReadDefaultFstab;
 
 // Returns the last device used to mount a directory in /proc/mounts.
 // This will find overlayfs entry where upperdir=lowerdir, to make sure
diff --git a/adb/daemon/set_verity_enable_state_service.cpp b/adb/daemon/set_verity_enable_state_service.cpp
index f5c28c6..92851c0 100644
--- a/adb/daemon/set_verity_enable_state_service.cpp
+++ b/adb/daemon/set_verity_enable_state_service.cpp
@@ -211,8 +211,8 @@
         // Not using AVB - assume VB1.0.
 
         // read all fstab entries at once from all sources
-        Fstab fstab;
-        if (!ReadDefaultFstab(&fstab)) {
+        android::fs_mgr::Fstab fstab;
+        if (!android::fs_mgr::ReadDefaultFstab(&fstab)) {
             WriteFdExactly(fd.get(), "Failed to read fstab\n");
             suggest_run_adb_root(fd.get());
             return;
diff --git a/adb/daemon/transport_qemu.cpp b/adb/daemon/transport_qemu.cpp
index e996c17..aa760bc 100644
--- a/adb/daemon/transport_qemu.cpp
+++ b/adb/daemon/transport_qemu.cpp
@@ -78,7 +78,7 @@
         /* This could be an older version of the emulator, that doesn't
          * implement adb QEMUD service. Fall back to the old TCP way. */
         D("adb service is not available. Falling back to TCP socket.");
-        std::thread(server_socket_thread, android::base::StringPrintf("tcp:%d", port)).detach();
+        std::thread(server_socket_thread, tcp_listen_inaddr_any, port).detach();
         return;
     }
 
diff --git a/adb/fdevent.cpp b/adb/fdevent.cpp
index e096560..fa3738d 100644
--- a/adb/fdevent.cpp
+++ b/adb/fdevent.cpp
@@ -33,6 +33,8 @@
 #include <list>
 #include <mutex>
 #include <unordered_map>
+#include <utility>
+#include <variant>
 #include <vector>
 
 #include <android-base/chrono_utils.h>
@@ -121,13 +123,8 @@
                                        state.c_str());
 }
 
-void fdevent_install(fdevent* fde, int fd, fd_func func, void* arg) {
-    check_main_thread();
-    CHECK_GE(fd, 0);
-    memset(fde, 0, sizeof(fdevent));
-}
-
-fdevent* fdevent_create(int fd, fd_func func, void* arg) {
+template <typename F>
+static fdevent* fdevent_create_impl(int fd, F func, void* arg) {
     check_main_thread();
     CHECK_GE(fd, 0);
 
@@ -150,6 +147,14 @@
     return fde;
 }
 
+fdevent* fdevent_create(int fd, fd_func func, void* arg) {
+    return fdevent_create_impl(fd, func, arg);
+}
+
+fdevent* fdevent_create(int fd, fd_func2 func, void* arg) {
+    return fdevent_create_impl(fd, func, arg);
+}
+
 unique_fd fdevent_release(fdevent* fde) {
     check_main_thread();
     if (!fde) {
@@ -290,13 +295,27 @@
     }
 }
 
+template <class T>
+struct always_false : std::false_type {};
+
 static void fdevent_call_fdfunc(fdevent* fde) {
     unsigned events = fde->events;
     fde->events = 0;
     CHECK(fde->state & FDE_PENDING);
     fde->state &= (~FDE_PENDING);
     D("fdevent_call_fdfunc %s", dump_fde(fde).c_str());
-    fde->func(fde->fd.get(), events, fde->arg);
+    std::visit(
+            [&](auto&& f) {
+                using F = std::decay_t<decltype(f)>;
+                if constexpr (std::is_same_v<fd_func, F>) {
+                    f(fde->fd.get(), events, fde->arg);
+                } else if constexpr (std::is_same_v<fd_func2, F>) {
+                    f(fde, events, fde->arg);
+                } else {
+                    static_assert(always_false<F>::value, "non-exhaustive visitor");
+                }
+            },
+            fde->func);
 }
 
 static void fdevent_run_flush() EXCLUDES(run_queue_mutex) {
diff --git a/adb/fdevent.h b/adb/fdevent.h
index df2339a..70e0a96 100644
--- a/adb/fdevent.h
+++ b/adb/fdevent.h
@@ -21,6 +21,7 @@
 #include <stdint.h>  /* for int64_t */
 
 #include <functional>
+#include <variant>
 
 #include "adb_unique_fd.h"
 
@@ -30,6 +31,7 @@
 #define FDE_ERROR             0x0004
 
 typedef void (*fd_func)(int fd, unsigned events, void *userdata);
+typedef void (*fd_func2)(struct fdevent* fde, unsigned events, void* userdata);
 
 struct fdevent {
     uint64_t id;
@@ -40,15 +42,14 @@
     uint16_t state = 0;
     uint16_t events = 0;
 
-    fd_func func = nullptr;
+    std::variant<fd_func, fd_func2> func;
     void* arg = nullptr;
 };
 
-/* Allocate and initialize a new fdevent object
- * Note: use FD_TIMER as 'fd' to create a fd-less object
- * (used to implement timers).
-*/
+// Allocate and initialize a new fdevent object
+// TODO: Switch these to unique_fd.
 fdevent *fdevent_create(int fd, fd_func func, void *arg);
+fdevent* fdevent_create(int fd, fd_func2 func, void* arg);
 
 // Deallocate an fdevent object that was created by fdevent_create.
 void fdevent_destroy(fdevent *fde);
@@ -56,16 +57,14 @@
 // fdevent_destroy, except releasing the file descriptor previously owned by the fdevent.
 unique_fd fdevent_release(fdevent* fde);
 
-/* Change which events should cause notifications
-*/
+// Change which events should cause notifications
 void fdevent_set(fdevent *fde, unsigned events);
 void fdevent_add(fdevent *fde, unsigned events);
 void fdevent_del(fdevent *fde, unsigned events);
 
 void fdevent_set_timeout(fdevent *fde, int64_t  timeout_ms);
 
-/* loop forever, handling events.
-*/
+// Loop forever, handling events.
 void fdevent_loop();
 
 void check_main_thread();
diff --git a/adb/fdevent_test.cpp b/adb/fdevent_test.cpp
index 816134f..a9746bb 100644
--- a/adb/fdevent_test.cpp
+++ b/adb/fdevent_test.cpp
@@ -30,10 +30,16 @@
 
 class FdHandler {
   public:
-    FdHandler(int read_fd, int write_fd) : read_fd_(read_fd), write_fd_(write_fd) {
-        read_fde_ = fdevent_create(read_fd_, FdEventCallback, this);
+    FdHandler(int read_fd, int write_fd, bool use_new_callback)
+        : read_fd_(read_fd), write_fd_(write_fd) {
+        if (use_new_callback) {
+            read_fde_ = fdevent_create(read_fd_, FdEventNewCallback, this);
+            write_fde_ = fdevent_create(write_fd_, FdEventNewCallback, this);
+        } else {
+            read_fde_ = fdevent_create(read_fd_, FdEventCallback, this);
+            write_fde_ = fdevent_create(write_fd_, FdEventCallback, this);
+        }
         fdevent_add(read_fde_, FDE_READ);
-        write_fde_ = fdevent_create(write_fd_, FdEventCallback, this);
     }
 
     ~FdHandler() {
@@ -64,6 +70,29 @@
         }
     }
 
+    static void FdEventNewCallback(fdevent* fde, unsigned events, void* userdata) {
+        int fd = fde->fd.get();
+        FdHandler* handler = reinterpret_cast<FdHandler*>(userdata);
+        ASSERT_EQ(0u, (events & ~(FDE_READ | FDE_WRITE))) << "unexpected events: " << events;
+        if (events & FDE_READ) {
+            ASSERT_EQ(fd, handler->read_fd_);
+            char c;
+            ASSERT_EQ(1, adb_read(fd, &c, 1));
+            handler->queue_.push(c);
+            fdevent_add(handler->write_fde_, FDE_WRITE);
+        }
+        if (events & FDE_WRITE) {
+            ASSERT_EQ(fd, handler->write_fd_);
+            ASSERT_FALSE(handler->queue_.empty());
+            char c = handler->queue_.front();
+            handler->queue_.pop();
+            ASSERT_EQ(1, adb_write(fd, &c, 1));
+            if (handler->queue_.empty()) {
+                fdevent_del(handler->write_fde_, FDE_WRITE);
+            }
+        }
+    }
+
   private:
     const int read_fd_;
     const int write_fd_;
@@ -84,56 +113,60 @@
 }
 
 TEST_F(FdeventTest, smoke) {
-    const size_t PIPE_COUNT = 10;
-    const size_t MESSAGE_LOOP_COUNT = 100;
-    const std::string MESSAGE = "fdevent_test";
-    int fd_pair1[2];
-    int fd_pair2[2];
-    ASSERT_EQ(0, adb_socketpair(fd_pair1));
-    ASSERT_EQ(0, adb_socketpair(fd_pair2));
-    ThreadArg thread_arg;
-    thread_arg.first_read_fd = fd_pair1[0];
-    thread_arg.last_write_fd = fd_pair2[1];
-    thread_arg.middle_pipe_count = PIPE_COUNT;
-    int writer = fd_pair1[1];
-    int reader = fd_pair2[0];
+    for (bool use_new_callback : {true, false}) {
+        fdevent_reset();
+        const size_t PIPE_COUNT = 10;
+        const size_t MESSAGE_LOOP_COUNT = 100;
+        const std::string MESSAGE = "fdevent_test";
+        int fd_pair1[2];
+        int fd_pair2[2];
+        ASSERT_EQ(0, adb_socketpair(fd_pair1));
+        ASSERT_EQ(0, adb_socketpair(fd_pair2));
+        ThreadArg thread_arg;
+        thread_arg.first_read_fd = fd_pair1[0];
+        thread_arg.last_write_fd = fd_pair2[1];
+        thread_arg.middle_pipe_count = PIPE_COUNT;
+        int writer = fd_pair1[1];
+        int reader = fd_pair2[0];
 
-    PrepareThread();
+        PrepareThread();
 
-    std::vector<std::unique_ptr<FdHandler>> fd_handlers;
-    fdevent_run_on_main_thread([&thread_arg, &fd_handlers]() {
-        std::vector<int> read_fds;
-        std::vector<int> write_fds;
+        std::vector<std::unique_ptr<FdHandler>> fd_handlers;
+        fdevent_run_on_main_thread([&thread_arg, &fd_handlers, use_new_callback]() {
+            std::vector<int> read_fds;
+            std::vector<int> write_fds;
 
-        read_fds.push_back(thread_arg.first_read_fd);
-        for (size_t i = 0; i < thread_arg.middle_pipe_count; ++i) {
-            int fds[2];
-            ASSERT_EQ(0, adb_socketpair(fds));
-            read_fds.push_back(fds[0]);
-            write_fds.push_back(fds[1]);
+            read_fds.push_back(thread_arg.first_read_fd);
+            for (size_t i = 0; i < thread_arg.middle_pipe_count; ++i) {
+                int fds[2];
+                ASSERT_EQ(0, adb_socketpair(fds));
+                read_fds.push_back(fds[0]);
+                write_fds.push_back(fds[1]);
+            }
+            write_fds.push_back(thread_arg.last_write_fd);
+
+            for (size_t i = 0; i < read_fds.size(); ++i) {
+                fd_handlers.push_back(
+                        std::make_unique<FdHandler>(read_fds[i], write_fds[i], use_new_callback));
+            }
+        });
+        WaitForFdeventLoop();
+
+        for (size_t i = 0; i < MESSAGE_LOOP_COUNT; ++i) {
+            std::string read_buffer = MESSAGE;
+            std::string write_buffer(MESSAGE.size(), 'a');
+            ASSERT_TRUE(WriteFdExactly(writer, read_buffer.c_str(), read_buffer.size()));
+            ASSERT_TRUE(ReadFdExactly(reader, &write_buffer[0], write_buffer.size()));
+            ASSERT_EQ(read_buffer, write_buffer);
         }
-        write_fds.push_back(thread_arg.last_write_fd);
 
-        for (size_t i = 0; i < read_fds.size(); ++i) {
-            fd_handlers.push_back(std::make_unique<FdHandler>(read_fds[i], write_fds[i]));
-        }
-    });
-    WaitForFdeventLoop();
+        fdevent_run_on_main_thread([&fd_handlers]() { fd_handlers.clear(); });
+        WaitForFdeventLoop();
 
-    for (size_t i = 0; i < MESSAGE_LOOP_COUNT; ++i) {
-        std::string read_buffer = MESSAGE;
-        std::string write_buffer(MESSAGE.size(), 'a');
-        ASSERT_TRUE(WriteFdExactly(writer, read_buffer.c_str(), read_buffer.size()));
-        ASSERT_TRUE(ReadFdExactly(reader, &write_buffer[0], write_buffer.size()));
-        ASSERT_EQ(read_buffer, write_buffer);
+        TerminateThread();
+        ASSERT_EQ(0, adb_close(writer));
+        ASSERT_EQ(0, adb_close(reader));
     }
-
-    fdevent_run_on_main_thread([&fd_handlers]() { fd_handlers.clear(); });
-    WaitForFdeventLoop();
-
-    TerminateThread();
-    ASSERT_EQ(0, adb_close(writer));
-    ASSERT_EQ(0, adb_close(reader));
 }
 
 struct InvalidFdArg {
diff --git a/adb/sysdeps/posix/network.cpp b/adb/sysdeps/posix/network.cpp
index 33ddb4e..4de240e 100644
--- a/adb/sysdeps/posix/network.cpp
+++ b/adb/sysdeps/posix/network.cpp
@@ -24,6 +24,7 @@
 #include <string>
 
 #include <android-base/logging.h>
+#include <android-base/stringprintf.h>
 #include <cutils/sockets.h>
 
 #include "adb_unique_fd.h"
@@ -136,11 +137,13 @@
         return fd;
     }
     if (getaddrinfo_error != 0) {
-        *error = gai_strerror(getaddrinfo_error);
-        LOG(WARNING) << "failed to resolve host '" << host << "': " << *error;
+        *error = android::base::StringPrintf("failed to resolve host: '%s': %s", host.c_str(),
+                                             gai_strerror(getaddrinfo_error));
+        LOG(WARNING) << *error;
     } else {
-        *error = strerror(errno);
-        LOG(WARNING) << "failed to connect to '" << host << "': " << *error;
+        *error = android::base::StringPrintf("failed to connect to '%s:%d': %s", host.c_str(), port,
+                                             strerror(errno));
+        LOG(WARNING) << *error;
     }
     return -1;
 }
diff --git a/adb/transport.h b/adb/transport.h
index 71e4857..065c81f 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -401,7 +401,8 @@
 asocket* create_device_tracker(bool long_output);
 
 #if !ADB_HOST
-void server_socket_thread(std::string_view spec);
+unique_fd tcp_listen_inaddr_any(int port, std::string* error);
+void server_socket_thread(std::function<unique_fd(int, std::string*)> listen_func, int port);
 
 #if defined(__ANDROID__)
 void qemu_socket_thread(int port);
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index c254d1d..9a74fb3 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -236,16 +236,15 @@
 
 #else  // !ADB_HOST
 
-void server_socket_thread(std::string_view spec) {
-    unique_fd serverfd;
-
+void server_socket_thread(std::function<unique_fd(int, std::string*)> listen_func, int port) {
     adb_thread_setname("server socket");
-    D("transport: server_socket_thread() starting");
-    int port;
+
+    unique_fd serverfd;
+    std::string error;
+
     while (serverfd == -1) {
-        std::string error;
         errno = 0;
-        serverfd.reset(socket_spec_listen(spec, &error, &port));
+        serverfd = listen_func(port, &error);
         if (errno == EAFNOSUPPORT || errno == EINVAL || errno == EPROTONOSUPPORT) {
             D("unrecoverable error: '%s'", error.c_str());
             return;
@@ -258,8 +257,7 @@
     }
 
     while (true) {
-        std::string spec_str{spec};
-        D("server: trying to get new connection from %s", spec_str.c_str());
+        D("server: trying to get new connection from fd %d", serverfd.get());
         unique_fd fd(adb_socket_accept(serverfd, nullptr, nullptr));
         if (fd >= 0) {
             D("server: new connection on fd %d", fd.get());
@@ -275,6 +273,18 @@
 
 #endif
 
+unique_fd tcp_listen_inaddr_any(int port, std::string* error) {
+    return unique_fd{network_inaddr_any_server(port, SOCK_STREAM, error)};
+}
+
+#if !ADB_HOST
+static unique_fd vsock_listen(int port, std::string* error) {
+    return unique_fd{
+        socket_spec_listen(android::base::StringPrintf("vsock:%d", port), error, nullptr)
+    };
+}
+#endif
+
 void local_init(int port) {
 #if ADB_HOST
     D("transport: local client init");
@@ -282,8 +292,8 @@
 #elif !defined(__ANDROID__)
     // Host adbd.
     D("transport: local server init");
-    std::thread(server_socket_thread, android::base::StringPrintf("tcp:%d", port)).detach();
-    std::thread(server_socket_thread, android::base::StringPrintf("vsock:%d", port)).detach();
+    std::thread(server_socket_thread, tcp_listen_inaddr_any, port).detach();
+    std::thread(server_socket_thread, vsock_listen, port).detach();
 #else
     D("transport: local server init");
     // For the adbd daemon in the system image we need to distinguish
@@ -291,9 +301,9 @@
     if (use_qemu_goldfish()) {
         std::thread(qemu_socket_thread, port).detach();
     } else {
-        std::thread(server_socket_thread, android::base::StringPrintf("tcp:%d", port)).detach();
+        std::thread(server_socket_thread, tcp_listen_inaddr_any, port).detach();
     }
-    std::thread(server_socket_thread, android::base::StringPrintf("vsock:%d", port)).detach();
+    std::thread(server_socket_thread, vsock_listen, port).detach();
 #endif // !ADB_HOST
 }
 
diff --git a/base/include/android-base/unique_fd.h b/base/include/android-base/unique_fd.h
index 2c890b4..83213e9 100644
--- a/base/include/android-base/unique_fd.h
+++ b/base/include/android-base/unique_fd.h
@@ -17,10 +17,10 @@
 #pragma once
 
 #include <dirent.h>
+#include <errno.h>
 #include <fcntl.h>
 
 #if !defined(_WIN32)
-#include <dirent.h>
 #include <sys/socket.h>
 #endif
 
@@ -114,6 +114,8 @@
 
  private:
   void reset(int new_value, void* previous_tag) {
+    int previous_errno = errno;
+
     if (fd_ != -1) {
       close(fd_, this);
     }
@@ -122,6 +124,8 @@
     if (new_value != -1) {
       tag(new_value, previous_tag, this);
     }
+
+    errno = previous_errno;
   }
 
   int fd_ = -1;
diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp
index a2336bf..1b09f79 100644
--- a/fastboot/device/commands.cpp
+++ b/fastboot/device/commands.cpp
@@ -28,6 +28,7 @@
 #include <cutils/android_reboot.h>
 #include <ext4_utils/wipe.h>
 #include <fs_mgr.h>
+#include <fs_mgr/roots.h>
 #include <libgsi/libgsi.h>
 #include <liblp/builder.h>
 #include <liblp/liblp.h>
@@ -462,13 +463,56 @@
     return UpdateSuper(device, args[1], wipe);
 }
 
-bool GsiHandler(FastbootDevice* device, const std::vector<std::string>& args) {
-    if (!android::gsi::IsGsiInstalled()) {
-        return device->WriteStatus(FastbootResult::FAIL, "No GSI is installed");
+class AutoMountMetadata {
+  public:
+    AutoMountMetadata() {
+        Fstab proc_mounts;
+        if (!ReadFstabFromFile("/proc/mounts", &proc_mounts)) {
+            LOG(ERROR) << "Could not read /proc/mounts";
+            return;
+        }
+
+        auto iter = std::find_if(proc_mounts.begin(), proc_mounts.end(),
+                [](const auto& entry) { return entry.mount_point == "/metadata"; });
+        if (iter != proc_mounts.end()) {
+            mounted_ = true;
+            return;
+        }
+
+        if (!ReadDefaultFstab(&fstab_)) {
+            LOG(ERROR) << "Could not read default fstab";
+            return;
+        }
+        mounted_ = EnsurePathMounted(&fstab_, "/metadata");
+        should_unmount_ = true;
     }
+    ~AutoMountMetadata() {
+        if (mounted_ && should_unmount_) {
+            EnsurePathUnmounted(&fstab_, "/metadata");
+        }
+    }
+    explicit operator bool() const { return mounted_; }
+
+  private:
+    Fstab fstab_;
+    bool mounted_ = false;
+    bool should_unmount_ = false;
+};
+
+bool GsiHandler(FastbootDevice* device, const std::vector<std::string>& args) {
     if (args.size() != 2) {
         return device->WriteFail("Invalid arguments");
     }
+
+    AutoMountMetadata mount_metadata;
+    if (!mount_metadata) {
+        return device->WriteFail("Could not find GSI install");
+    }
+
+    if (!android::gsi::IsGsiInstalled()) {
+        return device->WriteStatus(FastbootResult::FAIL, "No GSI is installed");
+    }
+
     if (args[1] == "wipe") {
         if (!android::gsi::UninstallGsi()) {
             return device->WriteStatus(FastbootResult::FAIL, strerror(errno));
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 17cab3a..4cdd8bc 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -1948,11 +1948,10 @@
             std::string size = next_arg(&args);
             fb->ResizePartition(partition, size);
         } else if (command == "gsi") {
-            if (args.empty()) {
-                syntax_error("missing 'wipe' or 'disable' argument");
-            } else if (args.size() == 1 && args[0] == "wipe") {
+            std::string arg = next_arg(&args);
+            if (arg == "wipe") {
                 fb->RawCommand("gsi:wipe", "wiping GSI");
-            } else if (args.size() == 1 && args[0] == "disable") {
+            } else if (arg == "disable") {
                 fb->RawCommand("gsi:disable", "disabling GSI");
             } else {
                 syntax_error("expected 'wipe' or 'disable'");
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 943a071..e5caf3a 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -90,9 +90,9 @@
 using android::base::unique_fd;
 using android::dm::DeviceMapper;
 using android::dm::DmDeviceState;
-using android::fs_mgr::AvbHandle;
-using android::fs_mgr::AvbHashtreeResult;
-using android::fs_mgr::AvbUniquePtr;
+
+// Realistically, this file should be part of the android::fs_mgr namespace;
+using namespace android::fs_mgr;
 
 using namespace std::literals;
 
@@ -1255,16 +1255,6 @@
     return ret;
 }
 
-int fs_mgr_do_mount_one(struct fstab_rec* rec) {
-    if (!rec) {
-        return FS_MGR_DOMNT_FAILED;
-    }
-
-    auto entry = FstabRecToFstabEntry(rec);
-
-    return fs_mgr_do_mount_one(entry);
-}
-
 // If tmp_mount_point is non-null, mount the filesystem there.  This is for the
 // tmp mount we do to check the user password
 // If multiple fstab entries are to be mounted on "n_name", it will try to mount each one
diff --git a/fs_mgr/fs_mgr_format.cpp b/fs_mgr/fs_mgr_format.cpp
index 1a0e7ab..1c6652a 100644
--- a/fs_mgr/fs_mgr_format.cpp
+++ b/fs_mgr/fs_mgr_format.cpp
@@ -37,6 +37,9 @@
 
 using android::base::unique_fd;
 
+// Realistically, this file should be part of the android::fs_mgr namespace;
+using namespace android::fs_mgr;
+
 static int get_dev_sz(const std::string& fs_blkdev, uint64_t* dev_sz) {
     unique_fd fd(TEMP_FAILURE_RETRY(open(fs_blkdev.c_str(), O_RDONLY | O_CLOEXEC)));
 
@@ -132,9 +135,3 @@
         return -EINVAL;
     }
 }
-
-int fs_mgr_do_format(struct fstab_rec* rec, bool crypt_footer) {
-    auto entry = FstabRecToFstabEntry(rec);
-
-    return fs_mgr_do_format(entry, crypt_footer);
-}
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index de3aac1..ee88e0d 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -41,14 +41,18 @@
 using android::base::Split;
 using android::base::StartsWith;
 
+namespace android {
+namespace fs_mgr {
+namespace {
+
 const std::string kDefaultAndroidDtDir("/proc/device-tree/firmware/android");
 
-struct flag_list {
+struct FlagList {
     const char *name;
     uint64_t flag;
 };
 
-static struct flag_list mount_flags_list[] = {
+FlagList kMountFlagsList[] = {
         {"noatime", MS_NOATIME},
         {"noexec", MS_NOEXEC},
         {"nosuid", MS_NOSUID},
@@ -66,7 +70,7 @@
         {"defaults", 0},
 };
 
-static off64_t calculate_zram_size(int percentage) {
+off64_t CalculateZramSize(int percentage) {
     off64_t total;
 
     total  = sysconf(_SC_PHYS_PAGES);
@@ -78,16 +82,12 @@
     return total;
 }
 
-/* fills 'dt_value' with the underlying device tree value string without
- * the trailing '\0'. Returns true if 'dt_value' has a valid string, 'false'
- * otherwise.
- */
-static bool read_dt_file(const std::string& file_name, std::string* dt_value)
-{
+// Fills 'dt_value' with the underlying device tree value string without the trailing '\0'.
+// Returns true if 'dt_value' has a valid string, 'false' otherwise.
+bool ReadDtFile(const std::string& file_name, std::string* dt_value) {
     if (android::base::ReadFileToString(file_name, dt_value)) {
         if (!dt_value->empty()) {
-            // trim the trailing '\0' out, otherwise the comparison
-            // will produce false-negatives.
+            // Trim the trailing '\0' out, otherwise the comparison will produce false-negatives.
             dt_value->resize(dt_value->size() - 1);
             return true;
         }
@@ -96,19 +96,19 @@
     return false;
 }
 
-const static std::array<const char*, 3> kFileContentsEncryptionMode = {
+const std::array<const char*, 3> kFileContentsEncryptionMode = {
         "aes-256-xts",
         "adiantum",
         "ice",
 };
 
-const static std::array<const char*, 3> kFileNamesEncryptionMode = {
+const std::array<const char*, 3> kFileNamesEncryptionMode = {
         "aes-256-cts",
         "aes-256-heh",
         "adiantum",
 };
 
-static void ParseFileEncryption(const std::string& arg, FstabEntry* entry) {
+void ParseFileEncryption(const std::string& arg, FstabEntry* entry) {
     // The fileencryption flag is followed by an = and the mode of contents encryption, then
     // optionally a and the mode of filenames encryption (defaults to aes-256-cts).  Get it and
     // return it.
@@ -150,8 +150,8 @@
     }
 }
 
-static bool SetMountFlag(const std::string& flag, FstabEntry* entry) {
-    for (const auto& [name, value] : mount_flags_list) {
+bool SetMountFlag(const std::string& flag, FstabEntry* entry) {
+    for (const auto& [name, value] : kMountFlagsList) {
         if (flag == name) {
             entry->flags |= value;
             return true;
@@ -160,7 +160,7 @@
     return false;
 }
 
-static void ParseMountFlags(const std::string& flags, FstabEntry* entry) {
+void ParseMountFlags(const std::string& flags, FstabEntry* entry) {
     std::string fs_options;
     for (const auto& flag : Split(flags, ",")) {
         if (!SetMountFlag(flag, entry)) {
@@ -174,7 +174,7 @@
     entry->fs_options = std::move(fs_options);
 }
 
-static void ParseFsMgrFlags(const std::string& flags, FstabEntry* entry) {
+void ParseFsMgrFlags(const std::string& flags, FstabEntry* entry) {
     entry->fs_mgr_flags.val = 0U;
     for (const auto& flag : Split(flags, ",")) {
         std::string arg;
@@ -255,7 +255,7 @@
                 arg.pop_back();
                 int val;
                 if (ParseInt(arg, &val, 0, 100)) {
-                    entry->zram_size = calculate_zram_size(val);
+                    entry->zram_size = CalculateZramSize(val);
                 } else {
                     LWARNING << "Warning: zramsize= flag malformed: " << arg;
                 }
@@ -346,7 +346,7 @@
     }
 }
 
-static std::string init_android_dt_dir() {
+std::string InitAndroidDtDir() {
     std::string android_dt_dir;
     // The platform may specify a custom Android DT path in kernel cmdline
     if (!fs_mgr_get_boot_config_from_kernel_cmdline("android_dt_dir", &android_dt_dir)) {
@@ -356,30 +356,23 @@
     return android_dt_dir;
 }
 
-// FIXME: The same logic is duplicated in system/core/init/
-const std::string& get_android_dt_dir() {
-    // Set once and saves time for subsequent calls to this function
-    static const std::string kAndroidDtDir = init_android_dt_dir();
-    return kAndroidDtDir;
-}
-
-static bool is_dt_fstab_compatible() {
+bool IsDtFstabCompatible() {
     std::string dt_value;
     std::string file_name = get_android_dt_dir() + "/fstab/compatible";
 
-    if (read_dt_file(file_name, &dt_value) && dt_value == "android,fstab") {
+    if (ReadDtFile(file_name, &dt_value) && dt_value == "android,fstab") {
         // If there's no status property or its set to "ok" or "okay", then we use the DT fstab.
         std::string status_value;
         std::string status_file_name = get_android_dt_dir() + "/fstab/status";
-        return !read_dt_file(status_file_name, &status_value) || status_value == "ok" ||
+        return !ReadDtFile(status_file_name, &status_value) || status_value == "ok" ||
                status_value == "okay";
     }
 
     return false;
 }
 
-static std::string read_fstab_from_dt() {
-    if (!is_dt_compatible() || !is_dt_fstab_compatible()) {
+std::string ReadFstabFromDt() {
+    if (!is_dt_compatible() || !IsDtFstabCompatible()) {
         return {};
     }
 
@@ -400,7 +393,7 @@
         std::string value;
         // skip a partition entry if the status property is present and not set to ok
         file_name = android::base::StringPrintf("%s/%s/status", fstabdir_name.c_str(), dp->d_name);
-        if (read_dt_file(file_name, &value)) {
+        if (ReadDtFile(file_name, &value)) {
             if (value != "okay" && value != "ok") {
                 LINFO << "dt_fstab: Skip disabled entry for partition " << dp->d_name;
                 continue;
@@ -408,7 +401,7 @@
         }
 
         file_name = android::base::StringPrintf("%s/%s/dev", fstabdir_name.c_str(), dp->d_name);
-        if (!read_dt_file(file_name, &value)) {
+        if (!ReadDtFile(file_name, &value)) {
             LERROR << "dt_fstab: Failed to find device for partition " << dp->d_name;
             return {};
         }
@@ -417,7 +410,7 @@
         std::string mount_point;
         file_name =
             android::base::StringPrintf("%s/%s/mnt_point", fstabdir_name.c_str(), dp->d_name);
-        if (read_dt_file(file_name, &value)) {
+        if (ReadDtFile(file_name, &value)) {
             LINFO << "dt_fstab: Using a specified mount point " << value << " for " << dp->d_name;
             mount_point = value;
         } else {
@@ -426,21 +419,21 @@
         fstab_entry.push_back(mount_point);
 
         file_name = android::base::StringPrintf("%s/%s/type", fstabdir_name.c_str(), dp->d_name);
-        if (!read_dt_file(file_name, &value)) {
+        if (!ReadDtFile(file_name, &value)) {
             LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;
             return {};
         }
         fstab_entry.push_back(value);
 
         file_name = android::base::StringPrintf("%s/%s/mnt_flags", fstabdir_name.c_str(), dp->d_name);
-        if (!read_dt_file(file_name, &value)) {
+        if (!ReadDtFile(file_name, &value)) {
             LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;
             return {};
         }
         fstab_entry.push_back(value);
 
         file_name = android::base::StringPrintf("%s/%s/fsmgr_flags", fstabdir_name.c_str(), dp->d_name);
-        if (!read_dt_file(file_name, &value)) {
+        if (!ReadDtFile(file_name, &value)) {
             LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;
             return {};
         }
@@ -460,19 +453,26 @@
     return fstab_result;
 }
 
-bool is_dt_compatible() {
-    std::string file_name = get_android_dt_dir() + "/compatible";
-    std::string dt_value;
-    if (read_dt_file(file_name, &dt_value)) {
-        if (dt_value == "android,firmware") {
-            return true;
+// Identify path to fstab file. Lookup is based on pattern fstab.<hardware>,
+// fstab.<hardware.platform> in folders /odm/etc, vendor/etc, or /.
+std::string GetFstabPath() {
+    for (const char* prop : {"hardware", "hardware.platform"}) {
+        std::string hw;
+
+        if (!fs_mgr_get_boot_config(prop, &hw)) continue;
+
+        for (const char* prefix : {"/odm/etc/fstab.", "/vendor/etc/fstab.", "/fstab."}) {
+            std::string fstab_path = prefix + hw;
+            if (access(fstab_path.c_str(), F_OK) == 0) {
+                return fstab_path;
+            }
         }
     }
 
-    return false;
+    return "";
 }
 
-static bool fs_mgr_read_fstab_file(FILE* fstab_file, bool proc_mounts, Fstab* fstab_out) {
+bool ReadFstabFile(FILE* fstab_file, bool proc_mounts, Fstab* fstab_out) {
     ssize_t len;
     size_t alloc_len = 0;
     char *line = NULL;
@@ -568,7 +568,7 @@
  *   /dev/block/pci/soc.0/f9824900.sdhci/by-name/vendor
  * it returns a set { "soc/1da4000.ufshc", "soc.0/f9824900.sdhci" }.
  */
-static std::set<std::string> extract_boot_devices(const Fstab& fstab) {
+std::set<std::string> ExtraBootDevices(const Fstab& fstab) {
     std::set<std::string> boot_devices;
 
     for (const auto& entry : fstab) {
@@ -601,13 +601,13 @@
     return boot_devices;
 }
 
-static void EraseFstabEntry(Fstab* fstab, const std::string& mount_point) {
+void EraseFstabEntry(Fstab* fstab, const std::string& mount_point) {
     auto iter = std::remove_if(fstab->begin(), fstab->end(),
                                [&](const auto& entry) { return entry.mount_point == mount_point; });
     fstab->erase(iter, fstab->end());
 }
 
-static void TransformFstabForGsi(Fstab* fstab) {
+void TransformFstabForGsi(Fstab* fstab) {
     EraseFstabEntry(fstab, "/system");
     EraseFstabEntry(fstab, "/data");
 
@@ -631,6 +631,8 @@
     fstab->emplace_back(userdata);
 }
 
+}  // namespace
+
 bool ReadFstabFromFile(const std::string& path, Fstab* fstab) {
     auto fstab_file = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose};
     if (!fstab_file) {
@@ -640,7 +642,7 @@
 
     bool is_proc_mounts = path == "/proc/mounts";
 
-    if (!fs_mgr_read_fstab_file(fstab_file.get(), is_proc_mounts, fstab)) {
+    if (!ReadFstabFile(fstab_file.get(), is_proc_mounts, fstab)) {
         LERROR << __FUNCTION__ << "(): failed to load fstab from : '" << path << "'";
         return false;
     }
@@ -651,18 +653,9 @@
     return true;
 }
 
-struct fstab* fs_mgr_read_fstab(const char* fstab_path) {
-    Fstab fstab;
-    if (!ReadFstabFromFile(fstab_path, &fstab)) {
-        return nullptr;
-    }
-
-    return FstabToLegacyFstab(fstab);
-}
-
 // Returns fstab entries parsed from the device tree if they exist
 bool ReadFstabFromDt(Fstab* fstab, bool log) {
-    std::string fstab_buf = read_fstab_from_dt();
+    std::string fstab_buf = ReadFstabFromDt();
     if (fstab_buf.empty()) {
         if (log) LINFO << __FUNCTION__ << "(): failed to read fstab from dt";
         return false;
@@ -676,7 +669,7 @@
         return false;
     }
 
-    if (!fs_mgr_read_fstab_file(fstab_file.get(), false, fstab)) {
+    if (!ReadFstabFile(fstab_file.get(), false, fstab)) {
         if (log) {
             LERROR << __FUNCTION__ << "(): failed to load fstab from kernel:" << std::endl
                    << fstab_buf;
@@ -687,38 +680,6 @@
     return true;
 }
 
-struct fstab* fs_mgr_read_fstab_dt() {
-    Fstab fstab;
-    if (!ReadFstabFromDt(&fstab)) {
-        return nullptr;
-    }
-
-    return FstabToLegacyFstab(fstab);
-}
-
-/*
- * Identify path to fstab file. Lookup is based on pattern
- * fstab.<hardware>, fstab.<hardware.platform> in folders
-   /odm/etc, vendor/etc, or /.
- */
-static std::string get_fstab_path()
-{
-    for (const char* prop : {"hardware", "hardware.platform"}) {
-        std::string hw;
-
-        if (!fs_mgr_get_boot_config(prop, &hw)) continue;
-
-        for (const char* prefix : {"/odm/etc/fstab.", "/vendor/etc/fstab.", "/fstab."}) {
-            std::string fstab_path = prefix + hw;
-            if (access(fstab_path.c_str(), F_OK) == 0) {
-                return fstab_path;
-            }
-        }
-    }
-
-    return std::string();
-}
-
 // Loads the fstab file and combines with fstab entries passed in from device tree.
 bool ReadDefaultFstab(Fstab* fstab) {
     Fstab dt_fstab;
@@ -731,7 +692,7 @@
     if (access("/system/bin/recovery", F_OK) == 0) {
         default_fstab_path = "/etc/recovery.fstab";
     } else {  // normal boot
-        default_fstab_path = get_fstab_path();
+        default_fstab_path = GetFstabPath();
     }
 
     Fstab default_fstab;
@@ -748,6 +709,92 @@
     return !fstab->empty();
 }
 
+FstabEntry* GetEntryForMountPoint(Fstab* fstab, const std::string& path) {
+    if (fstab == nullptr) {
+        return nullptr;
+    }
+
+    for (auto& entry : *fstab) {
+        if (entry.mount_point == path) {
+            return &entry;
+        }
+    }
+
+    return nullptr;
+}
+
+std::set<std::string> GetBootDevices() {
+    // First check the kernel commandline, then try the device tree otherwise
+    std::string dt_file_name = get_android_dt_dir() + "/boot_devices";
+    std::string value;
+    if (fs_mgr_get_boot_config_from_kernel_cmdline("boot_devices", &value) ||
+        ReadDtFile(dt_file_name, &value)) {
+        auto boot_devices = Split(value, ",");
+        return std::set<std::string>(boot_devices.begin(), boot_devices.end());
+    }
+
+    // Fallback to extract boot devices from fstab.
+    Fstab fstab;
+    if (!ReadDefaultFstab(&fstab)) {
+        return {};
+    }
+
+    return ExtraBootDevices(fstab);
+}
+
+FstabEntry BuildGsiSystemFstabEntry() {
+    // .logical_partition_name is required to look up AVB Hashtree descriptors.
+    FstabEntry system = {.blk_device = "system_gsi",
+                         .mount_point = "/system",
+                         .fs_type = "ext4",
+                         .flags = MS_RDONLY,
+                         .fs_options = "barrier=1",
+                         .avb_key = "/gsi.avbpubkey",
+                         .logical_partition_name = "system"};
+    system.fs_mgr_flags.wait = true;
+    system.fs_mgr_flags.logical = true;
+    system.fs_mgr_flags.first_stage_mount = true;
+    return system;
+}
+
+}  // namespace fs_mgr
+}  // namespace android
+
+// FIXME: The same logic is duplicated in system/core/init/
+const std::string& get_android_dt_dir() {
+    // Set once and saves time for subsequent calls to this function
+    static const std::string kAndroidDtDir = android::fs_mgr::InitAndroidDtDir();
+    return kAndroidDtDir;
+}
+
+bool is_dt_compatible() {
+    std::string file_name = get_android_dt_dir() + "/compatible";
+    std::string dt_value;
+    if (android::fs_mgr::ReadDtFile(file_name, &dt_value)) {
+        if (dt_value == "android,firmware") {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+// Everything from here down is deprecated and will be removed shortly.
+
+using android::fs_mgr::Fstab;
+using android::fs_mgr::FstabEntry;
+using android::fs_mgr::ReadDefaultFstab;
+using android::fs_mgr::ReadFstabFromFile;
+
+struct fstab* fs_mgr_read_fstab(const char* fstab_path) {
+    Fstab fstab;
+    if (!ReadFstabFromFile(fstab_path, &fstab)) {
+        return nullptr;
+    }
+
+    return FstabToLegacyFstab(fstab);
+}
+
 struct fstab* fs_mgr_read_fstab_default() {
     Fstab fstab;
     if (!ReadDefaultFstab(&fstab)) {
@@ -789,8 +836,6 @@
     free(fstab);
 }
 
-// Returns the fstab_rec* whose mount_point is path.
-// Returns nullptr if not found.
 struct fstab_rec* fs_mgr_get_entry_for_mount_point(struct fstab* fstab, const std::string& path) {
     if (!fstab) {
         return nullptr;
@@ -803,39 +848,6 @@
     return nullptr;
 }
 
-FstabEntry* GetEntryForMountPoint(Fstab* fstab, const std::string& path) {
-    if (fstab == nullptr) {
-        return nullptr;
-    }
-
-    for (auto& entry : *fstab) {
-        if (entry.mount_point == path) {
-            return &entry;
-        }
-    }
-
-    return nullptr;
-}
-
-std::set<std::string> fs_mgr_get_boot_devices() {
-    // First check the kernel commandline, then try the device tree otherwise
-    std::string dt_file_name = get_android_dt_dir() + "/boot_devices";
-    std::string value;
-    if (fs_mgr_get_boot_config_from_kernel_cmdline("boot_devices", &value) ||
-        read_dt_file(dt_file_name, &value)) {
-        auto boot_devices = Split(value, ",");
-        return std::set<std::string>(boot_devices.begin(), boot_devices.end());
-    }
-
-    // Fallback to extract boot devices from fstab.
-    Fstab fstab;
-    if (!ReadDefaultFstab(&fstab)) {
-        return {};
-    }
-
-    return extract_boot_devices(fstab);
-}
-
 FstabEntry FstabRecToFstabEntry(const fstab_rec* fstab_rec) {
     FstabEntry entry;
     entry.blk_device = fstab_rec->blk_device;
@@ -977,20 +989,3 @@
 int fs_mgr_is_checkpoint_blk(const struct fstab_rec* fstab) {
     return fstab->fs_mgr_flags & MF_CHECKPOINT_BLK;
 }
-
-FstabEntry BuildGsiSystemFstabEntry() {
-    // .logical_partition_name is required to look up AVB Hashtree descriptors.
-    FstabEntry system = {
-            .blk_device = "system_gsi",
-            .mount_point = "/system",
-            .fs_type = "ext4",
-            .flags = MS_RDONLY,
-            .fs_options = "barrier=1",
-            .avb_key = "/gsi.avbpubkey",
-            .logical_partition_name = "system"
-    };
-    system.fs_mgr_flags.wait = true;
-    system.fs_mgr_flags.logical = true;
-    system.fs_mgr_flags.first_stage_mount = true;
-    return system;
-}
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 3b9ddee..83e5d7b 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -143,10 +143,10 @@
                           FileWaitMode wait_mode = FileWaitMode::Exists);
 
 bool fs_mgr_set_blk_ro(const std::string& blockdev, bool readonly = true);
-bool fs_mgr_update_for_slotselect(Fstab* fstab);
+bool fs_mgr_update_for_slotselect(android::fs_mgr::Fstab* fstab);
 bool fs_mgr_is_device_unlocked();
 const std::string& get_android_dt_dir();
 bool is_dt_compatible();
-int load_verity_state(const FstabEntry& entry, int* mode);
+int load_verity_state(const android::fs_mgr::FstabEntry& entry, int* mode);
 
 #endif /* __CORE_FS_MGR_PRIV_H */
diff --git a/fs_mgr/fs_mgr_slotselect.cpp b/fs_mgr/fs_mgr_slotselect.cpp
index 41cd7dd..09c1b7e 100644
--- a/fs_mgr/fs_mgr_slotselect.cpp
+++ b/fs_mgr/fs_mgr_slotselect.cpp
@@ -21,6 +21,9 @@
 #include "fs_mgr.h"
 #include "fs_mgr_priv.h"
 
+// Realistically, this file should be part of the android::fs_mgr namespace;
+using namespace android::fs_mgr;
+
 // https://source.android.com/devices/tech/ota/ab/ab_implement#partitions
 // All partitions that are A/B-ed should be named as follows (slots are always
 // named a, b, etc.): boot_a, boot_b, system_a, system_b, vendor_a, vendor_b.
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index 9adf8cc..c53e866 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -46,6 +46,9 @@
 #include "fs_mgr.h"
 #include "fs_mgr_priv.h"
 
+// Realistically, this file should be part of the android::fs_mgr namespace;
+using namespace android::fs_mgr;
+
 #define VERITY_TABLE_RSA_KEY "/verity_key"
 #define VERITY_TABLE_HASH_IDX 8
 #define VERITY_TABLE_SALT_IDX 9
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 2934363..6e9f1b0 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -60,7 +60,7 @@
 #define FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE 0
 #define FS_MGR_MNTALL_FAIL (-1)
 // fs_mgr_mount_all() updates fstab entries that reference device-mapper.
-int fs_mgr_mount_all(Fstab* fstab, int mount_mode);
+int fs_mgr_mount_all(android::fs_mgr::Fstab* fstab, int mount_mode);
 
 #define FS_MGR_DOMNT_FAILED (-1)
 #define FS_MGR_DOMNT_BUSY (-2)
@@ -68,28 +68,28 @@
 int fs_mgr_do_mount(fstab* fstab, const char* n_name, char* n_blk_device, char* tmp_mount_point);
 int fs_mgr_do_mount(fstab* fstab, const char* n_name, char* n_blk_device, char* tmp_mount_point,
                     bool needs_checkpoint);
-int fs_mgr_do_mount(Fstab* fstab, const char* n_name, char* n_blk_device, char* tmp_mount_point);
-int fs_mgr_do_mount(Fstab* fstab, const char* n_name, char* n_blk_device, char* tmp_mount_point,
-                    bool need_cp);
-int fs_mgr_do_mount_one(const FstabEntry& entry, const std::string& mount_point = "");
-int fs_mgr_do_mount_one(fstab_rec* rec);
+int fs_mgr_do_mount(android::fs_mgr::Fstab* fstab, const char* n_name, char* n_blk_device,
+                    char* tmp_mount_point);
+int fs_mgr_do_mount(android::fs_mgr::Fstab* fstab, const char* n_name, char* n_blk_device,
+                    char* tmp_mount_point, bool need_cp);
+int fs_mgr_do_mount_one(const android::fs_mgr::FstabEntry& entry,
+                        const std::string& mount_point = "");
 int fs_mgr_do_tmpfs_mount(const char *n_name);
 fstab_rec const* fs_mgr_get_crypt_entry(fstab const* fstab);
 void fs_mgr_get_crypt_info(fstab* fstab, char* key_loc, char* real_blk_device, size_t size);
 bool fs_mgr_load_verity_state(int* mode);
 bool fs_mgr_update_verity_state(
         std::function<void(const std::string& mount_point, int mode)> callback);
-bool fs_mgr_swapon_all(const Fstab& fstab);
-bool fs_mgr_update_logical_partition(FstabEntry* entry);
+bool fs_mgr_swapon_all(const android::fs_mgr::Fstab& fstab);
+bool fs_mgr_update_logical_partition(android::fs_mgr::FstabEntry* entry);
 
-int fs_mgr_do_format(const FstabEntry& entry, bool reserve_footer);
-int fs_mgr_do_format(fstab_rec* rec, bool reserve_footer);
+int fs_mgr_do_format(const android::fs_mgr::FstabEntry& entry, bool reserve_footer);
 
 #define FS_MGR_SETUP_VERITY_SKIPPED  (-3)
 #define FS_MGR_SETUP_VERITY_DISABLED (-2)
 #define FS_MGR_SETUP_VERITY_FAIL (-1)
 #define FS_MGR_SETUP_VERITY_SUCCESS 0
-int fs_mgr_setup_verity(FstabEntry* fstab, bool wait_for_verity_dev);
+int fs_mgr_setup_verity(android::fs_mgr::FstabEntry* fstab, bool wait_for_verity_dev);
 
 // Return the name of the super partition if it exists. If a slot number is
 // specified, the super partition for the corresponding metadata slot will be
diff --git a/fs_mgr/include/fs_mgr_overlayfs.h b/fs_mgr/include/fs_mgr_overlayfs.h
index 4bf2238..64682cc 100644
--- a/fs_mgr/include/fs_mgr_overlayfs.h
+++ b/fs_mgr/include/fs_mgr_overlayfs.h
@@ -21,8 +21,8 @@
 #include <string>
 #include <vector>
 
-bool fs_mgr_overlayfs_mount_all(Fstab* fstab);
-std::vector<std::string> fs_mgr_overlayfs_required_devices(Fstab* fstab);
+bool fs_mgr_overlayfs_mount_all(android::fs_mgr::Fstab* fstab);
+std::vector<std::string> fs_mgr_overlayfs_required_devices(android::fs_mgr::Fstab* fstab);
 bool fs_mgr_overlayfs_setup(const char* backing = nullptr, const char* mount_point = nullptr,
                             bool* change = nullptr);
 bool fs_mgr_overlayfs_teardown(const char* mount_point = nullptr, bool* change = nullptr);
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h
index 549ff68..a942d43 100644
--- a/fs_mgr/include_fstab/fstab/fstab.h
+++ b/fs_mgr/include_fstab/fstab/fstab.h
@@ -65,7 +65,6 @@
 };
 
 struct fstab* fs_mgr_read_fstab_default();
-struct fstab* fs_mgr_read_fstab_dt();
 struct fstab* fs_mgr_read_fstab(const char* fstab_path);
 void fs_mgr_free_fstab(struct fstab* fstab);
 
@@ -88,7 +87,9 @@
 
 std::string fs_mgr_get_slot_suffix();
 std::string fs_mgr_get_other_slot_suffix();
-std::set<std::string> fs_mgr_get_boot_devices();
+
+namespace android {
+namespace fs_mgr {
 
 struct FstabEntry {
     std::string blk_device;
@@ -187,10 +188,15 @@
 
 FstabEntry* GetEntryForMountPoint(Fstab* fstab, const std::string& path);
 
-// Temporary conversion functions.
-FstabEntry FstabRecToFstabEntry(const fstab_rec* fstab_rec);
-Fstab LegacyFstabToFstab(const struct fstab* legacy_fstab);
-fstab* FstabToLegacyFstab(const Fstab& fstab);
-
 // Helper method to build a GSI fstab entry for mounting /system.
 FstabEntry BuildGsiSystemFstabEntry();
+
+std::set<std::string> GetBootDevices();
+
+}  // namespace fs_mgr
+}  // namespace android
+
+// Temporary conversion functions.
+android::fs_mgr::FstabEntry FstabRecToFstabEntry(const fstab_rec* fstab_rec);
+android::fs_mgr::Fstab LegacyFstabToFstab(const struct fstab* legacy_fstab);
+fstab* FstabToLegacyFstab(const android::fs_mgr::Fstab& fstab);
diff --git a/fs_mgr/libfs_avb/tests/avb_util_test.cpp b/fs_mgr/libfs_avb/tests/avb_util_test.cpp
index 5fdbe28..835410f 100644
--- a/fs_mgr/libfs_avb/tests/avb_util_test.cpp
+++ b/fs_mgr/libfs_avb/tests/avb_util_test.cpp
@@ -28,6 +28,7 @@
 // Target classes or functions to test:
 using android::fs_mgr::AvbPartitionToDevicePatition;
 using android::fs_mgr::DeriveAvbPartitionName;
+using android::fs_mgr::FstabEntry;
 using android::fs_mgr::GetAvbFooter;
 using android::fs_mgr::GetChainPartitionInfo;
 using android::fs_mgr::GetTotalSize;
diff --git a/fs_mgr/tests/fs_mgr_test.cpp b/fs_mgr/tests/fs_mgr_test.cpp
index e2b283a..870c98c 100644
--- a/fs_mgr/tests/fs_mgr_test.cpp
+++ b/fs_mgr/tests/fs_mgr_test.cpp
@@ -32,6 +32,8 @@
 
 #include "../fs_mgr_priv_boot_config.h"
 
+using namespace android::fs_mgr;
+
 namespace {
 
 const std::string cmdline =
diff --git a/init/builtins.cpp b/init/builtins.cpp
index b41b035..c8ceb0c 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -76,6 +76,8 @@
 using namespace std::literals::string_literals;
 
 using android::base::unique_fd;
+using android::fs_mgr::Fstab;
+using android::fs_mgr::ReadFstabFromFile;
 
 #define chmod DO_NOT_USE_CHMOD_USE_FCHMODAT_SYMLINK_NOFOLLOW
 
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 79536e4..7d5bf57 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -49,6 +49,11 @@
 using android::fs_mgr::AvbHandle;
 using android::fs_mgr::AvbHashtreeResult;
 using android::fs_mgr::AvbUniquePtr;
+using android::fs_mgr::BuildGsiSystemFstabEntry;
+using android::fs_mgr::Fstab;
+using android::fs_mgr::FstabEntry;
+using android::fs_mgr::ReadDefaultFstab;
+using android::fs_mgr::ReadFstabFromDt;
 
 using namespace std::literals;
 
@@ -156,7 +161,7 @@
 // -----------------
 FirstStageMount::FirstStageMount(Fstab fstab)
     : need_dm_verity_(false), fstab_(std::move(fstab)), uevent_listener_(16 * 1024 * 1024) {
-    auto boot_devices = fs_mgr_get_boot_devices();
+    auto boot_devices = android::fs_mgr::GetBootDevices();
     device_handler_ = std::make_unique<DeviceHandler>(
             std::vector<Permissions>{}, std::vector<SysfsPermissions>{}, std::vector<Subsystem>{},
             std::move(boot_devices), false);
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 7545d53..399ea4c 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -245,7 +245,7 @@
     uevent_handlers.emplace_back(std::make_unique<DeviceHandler>(
             std::move(ueventd_configuration.dev_permissions),
             std::move(ueventd_configuration.sysfs_permissions),
-            std::move(ueventd_configuration.subsystems), fs_mgr_get_boot_devices(), true));
+            std::move(ueventd_configuration.subsystems), android::fs_mgr::GetBootDevices(), true));
     uevent_handlers.emplace_back(std::make_unique<FirmwareHandler>(
             std::move(ueventd_configuration.firmware_directories)));
 
diff --git a/libnativeloader/Android.bp b/libnativeloader/Android.bp
index 2802d36..1ec21e9 100644
--- a/libnativeloader/Android.bp
+++ b/libnativeloader/Android.bp
@@ -23,6 +23,10 @@
         "llndk.libraries.txt",
         "vndksp.libraries.txt",
     ],
+    stubs: {
+        symbol_file: "libnativeloader.map.txt",
+        versions: ["1"],
+    },
 }
 
 cc_library_headers {
diff --git a/rootdir/etc/ld.config.legacy.txt b/rootdir/etc/ld.config.legacy.txt
index a854e93..48ca998 100644
--- a/rootdir/etc/ld.config.legacy.txt
+++ b/rootdir/etc/ld.config.legacy.txt
@@ -105,7 +105,8 @@
 # Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
-namespace.conscrypt.links = default
+namespace.conscrypt.links = runtime,default
+namespace.conscrypt.link.runtime.shared_libs  = libjavacore.so
 namespace.conscrypt.link.default.shared_libs  = libc.so
 namespace.conscrypt.link.default.shared_libs += libm.so
 namespace.conscrypt.link.default.shared_libs += libdl.so
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index a617418..582ce27 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -176,7 +176,8 @@
 # Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
-namespace.conscrypt.links = default
+namespace.conscrypt.links = runtime,default
+namespace.conscrypt.link.runtime.shared_libs  = libjavacore.so
 namespace.conscrypt.link.default.shared_libs  = libc.so
 namespace.conscrypt.link.default.shared_libs += libm.so
 namespace.conscrypt.link.default.shared_libs += libdl.so
@@ -466,7 +467,10 @@
 namespace.system.asan.search.paths +=           /%PRODUCT_SERVICES%/${LIB}
 
 namespace.system.links = runtime
-namespace.system.link.runtime.shared_libs = libdexfile_external.so
+namespace.system.link.runtime.shared_libs  = libdexfile_external.so
+namespace.system.link.runtime.shared_libs += libnativebridge.so
+namespace.system.link.runtime.shared_libs += libnativehelper.so
+namespace.system.link.runtime.shared_libs += libnativeloader.so
 
 ###############################################################################
 # Namespace config for binaries under /postinstall.
diff --git a/rootdir/etc/ld.config.vndk_lite.txt b/rootdir/etc/ld.config.vndk_lite.txt
index ae486ea..d0bdf3a 100644
--- a/rootdir/etc/ld.config.vndk_lite.txt
+++ b/rootdir/etc/ld.config.vndk_lite.txt
@@ -124,7 +124,8 @@
 # Keep in sync with ld.config.txt in the com.android.runtime APEX.
 namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
 namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
-namespace.conscrypt.links = default
+namespace.conscrypt.links = runtime,default
+namespace.conscrypt.link.runtime.shared_libs  = libjavacore.so
 namespace.conscrypt.link.default.shared_libs  = libc.so
 namespace.conscrypt.link.default.shared_libs += libm.so
 namespace.conscrypt.link.default.shared_libs += libdl.so
@@ -333,7 +334,10 @@
 namespace.default.asan.search.paths +=           /%PRODUCT_SERVICES%/${LIB}
 
 namespace.default.links = runtime
-namespace.default.link.runtime.shared_libs = libdexfile_external.so
+namespace.default.link.runtime.shared_libs  = libdexfile_external.so
+namespace.default.link.runtime.shared_libs += libnativebridge.so
+namespace.default.link.runtime.shared_libs += libnativehelper.so
+namespace.default.link.runtime.shared_libs += libnativeloader.so
 
 ###############################################################################
 # "runtime" APEX namespace