Merge "Remove include/private/android_logger.h"
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 3969367..0921d72 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -527,12 +527,15 @@
 
 static bool UnzipToMemory(ZipArchiveHandle zip, const std::string& entry_name,
                           std::vector<char>* out) {
-    ZipEntry zip_entry;
+    ZipEntry64 zip_entry;
     if (FindEntry(zip, entry_name, &zip_entry) != 0) {
         fprintf(stderr, "archive does not contain '%s'\n", entry_name.c_str());
         return false;
     }
 
+    if (zip_entry.uncompressed_length > std::numeric_limits<size_t>::max()) {
+      die("entry '%s' is too large: %" PRIu64, entry_name.c_str(), zip_entry.uncompressed_length);
+    }
     out->resize(zip_entry.uncompressed_length);
 
     fprintf(stderr, "extracting %s (%zu MB) to RAM...\n", entry_name.c_str(),
@@ -638,14 +641,14 @@
 static int unzip_to_file(ZipArchiveHandle zip, const char* entry_name) {
     unique_fd fd(make_temporary_fd(entry_name));
 
-    ZipEntry zip_entry;
+    ZipEntry64 zip_entry;
     if (FindEntry(zip, entry_name, &zip_entry) != 0) {
         fprintf(stderr, "archive does not contain '%s'\n", entry_name);
         errno = ENOENT;
         return -1;
     }
 
-    fprintf(stderr, "extracting %s (%" PRIu32 " MB) to disk...", entry_name,
+    fprintf(stderr, "extracting %s (%" PRIu64 " MB) to disk...", entry_name,
             zip_entry.uncompressed_length / 1024 / 1024);
     double start = now();
     int error = ExtractEntryToFile(zip, &zip_entry, fd);
diff --git a/fs_mgr/libdm/dm.cpp b/fs_mgr/libdm/dm.cpp
index 78a9005..bb7d8b3 100644
--- a/fs_mgr/libdm/dm.cpp
+++ b/fs_mgr/libdm/dm.cpp
@@ -429,7 +429,7 @@
 
 // Accepts a device mapper device name (like system_a, vendor_b etc) and
 // returns its UUID.
-bool DeviceMapper::GetDmDeviceUUIDByName(const std::string& name, std::string* uuid) {
+bool DeviceMapper::GetDmDeviceUuidByName(const std::string& name, std::string* uuid) {
     struct dm_ioctl io;
     InitIo(&io, name);
     if (ioctl(fd_, DM_DEV_STATUS, &io) < 0) {
diff --git a/fs_mgr/libdm/include/libdm/dm.h b/fs_mgr/libdm/include/libdm/dm.h
index 0b2553f..5d6db46 100644
--- a/fs_mgr/libdm/include/libdm/dm.h
+++ b/fs_mgr/libdm/include/libdm/dm.h
@@ -177,7 +177,7 @@
     //
     // WaitForFile() should not be used in conjunction with this call, since it
     // could race with ueventd.
-    bool GetDmDeviceUUIDByName(const std::string& name, std::string* path);
+    bool GetDmDeviceUuidByName(const std::string& name, std::string* path);
 
     // Returns a device's unique path as generated by ueventd. This will return
     // true as long as the device has been created, even if ueventd has not
diff --git a/fs_mgr/libsnapshot/cow_snapuserd_test.cpp b/fs_mgr/libsnapshot/cow_snapuserd_test.cpp
index d767022..6970ec1 100644
--- a/fs_mgr/libsnapshot/cow_snapuserd_test.cpp
+++ b/fs_mgr/libsnapshot/cow_snapuserd_test.cpp
@@ -37,52 +37,86 @@
 class SnapuserdTest : public ::testing::Test {
   protected:
     void SetUp() override {
-        cow_ = std::make_unique<TemporaryFile>();
-        ASSERT_GE(cow_->fd, 0) << strerror(errno);
+        cow_system_ = std::make_unique<TemporaryFile>();
+        ASSERT_GE(cow_system_->fd, 0) << strerror(errno);
+
+        cow_product_ = std::make_unique<TemporaryFile>();
+        ASSERT_GE(cow_product_->fd, 0) << strerror(errno);
+
+        size_ = 100_MiB;
     }
 
-    void TearDown() override { cow_ = nullptr; }
+    void TearDown() override {
+        cow_system_ = nullptr;
+        cow_product_ = nullptr;
+    }
 
-    std::unique_ptr<TemporaryFile> cow_;
+    std::unique_ptr<TemporaryFile> cow_system_;
+    std::unique_ptr<TemporaryFile> cow_product_;
+
+    unique_fd sys_fd_;
+    unique_fd product_fd_;
+    size_t size_;
+
+    int system_blksize_;
+    int product_blksize_;
+    std::string system_device_name_;
+    std::string product_device_name_;
+
+    std::unique_ptr<uint8_t[]> random_buffer_1_;
+    std::unique_ptr<uint8_t[]> random_buffer_2_;
+    std::unique_ptr<uint8_t[]> zero_buffer_;
+    std::unique_ptr<uint8_t[]> system_buffer_;
+    std::unique_ptr<uint8_t[]> product_buffer_;
+
+    void Init();
+    void CreateCowDevice(std::unique_ptr<TemporaryFile>& cow);
+    void CreateSystemDmUser();
+    void CreateProductDmUser();
+    void StartSnapuserdDaemon();
+    void CreateSnapshotDevices();
+
+    void TestIO(unique_fd& snapshot_fd, std::unique_ptr<uint8_t[]>&& buf);
 };
 
-TEST_F(SnapuserdTest, ReadWrite) {
-    loff_t offset = 0;
-    size_t size = 100_MiB;
+void SnapuserdTest::Init() {
     unique_fd rnd_fd;
-    unique_fd sys_fd;
-    unique_fd snapshot_fd;
-    unique_fd system_a_fd;
-    std::string cmd;
+    loff_t offset = 0;
 
     rnd_fd.reset(open("/dev/random", O_RDONLY));
     ASSERT_TRUE(rnd_fd > 0);
 
-    std::unique_ptr<uint8_t[]> random_buffer_1;
-    std::unique_ptr<uint8_t[]> random_buffer_2;
-    std::unique_ptr<uint8_t[]> system_buffer;
-
-    random_buffer_1 = std::make_unique<uint8_t[]>(size);
-
-    random_buffer_2 = std::make_unique<uint8_t[]>(size);
-
-    system_buffer = std::make_unique<uint8_t[]>(size);
+    random_buffer_1_ = std::make_unique<uint8_t[]>(size_);
+    random_buffer_2_ = std::make_unique<uint8_t[]>(size_);
+    system_buffer_ = std::make_unique<uint8_t[]>(size_);
+    product_buffer_ = std::make_unique<uint8_t[]>(size_);
+    zero_buffer_ = std::make_unique<uint8_t[]>(size_);
 
     // Fill random data
-    for (size_t j = 0; j < (size / 1_MiB); j++) {
-        ASSERT_EQ(ReadFullyAtOffset(rnd_fd, (char*)random_buffer_1.get() + offset, 1_MiB, 0), true);
+    for (size_t j = 0; j < (size_ / 1_MiB); j++) {
+        ASSERT_EQ(ReadFullyAtOffset(rnd_fd, (char*)random_buffer_1_.get() + offset, 1_MiB, 0),
+                  true);
 
-        ASSERT_EQ(ReadFullyAtOffset(rnd_fd, (char*)random_buffer_2.get() + offset, 1_MiB, 0), true);
+        ASSERT_EQ(ReadFullyAtOffset(rnd_fd, (char*)random_buffer_2_.get() + offset, 1_MiB, 0),
+                  true);
 
         offset += 1_MiB;
     }
 
-    sys_fd.reset(open("/dev/block/mapper/system_a", O_RDONLY));
-    ASSERT_TRUE(sys_fd > 0);
+    sys_fd_.reset(open("/dev/block/mapper/system_a", O_RDONLY));
+    ASSERT_TRUE(sys_fd_ > 0);
+
+    product_fd_.reset(open("/dev/block/mapper/product_a", O_RDONLY));
+    ASSERT_TRUE(product_fd_ > 0);
 
     // Read from system partition from offset 0 of size 100MB
-    ASSERT_EQ(ReadFullyAtOffset(sys_fd, system_buffer.get(), size, 0), true);
+    ASSERT_EQ(ReadFullyAtOffset(sys_fd_, system_buffer_.get(), size_, 0), true);
 
+    // Read from system partition from offset 0 of size 100MB
+    ASSERT_EQ(ReadFullyAtOffset(product_fd_, product_buffer_.get(), size_, 0), true);
+}
+
+void SnapuserdTest::CreateCowDevice(std::unique_ptr<TemporaryFile>& cow) {
     //================Create a COW file with the following operations===========
     //
     // Create COW file which is gz compressed
@@ -96,12 +130,12 @@
     options.compression = "gz";
     CowWriter writer(options);
 
-    ASSERT_TRUE(writer.Initialize(cow_->fd));
+    ASSERT_TRUE(writer.Initialize(cow->fd));
 
     // Write 100MB random data to COW file which is gz compressed from block 0
-    ASSERT_TRUE(writer.AddRawBlocks(0, random_buffer_1.get(), size));
+    ASSERT_TRUE(writer.AddRawBlocks(0, random_buffer_1_.get(), size_));
 
-    size_t num_blocks = size / options.block_size;
+    size_t num_blocks = size_ / options.block_size;
     size_t blk_start_copy = num_blocks;
     size_t blk_end_copy = blk_start_copy + num_blocks;
     size_t source_blk = 0;
@@ -110,7 +144,7 @@
     // has to read from block 0 in system_a partition
     //
     // This initializes copy operation from block 0 of size 100 MB from
-    // /dev/block/mapper/system_a
+    // /dev/block/mapper/system_a or product_a
     for (size_t i = blk_start_copy; i < blk_end_copy; i++) {
         ASSERT_TRUE(writer.AddCopy(i, source_blk));
         source_blk += 1;
@@ -125,14 +159,17 @@
     // Final 100MB filled with random data which is gz compressed
     size_t blk_random2_replace_start = blk_zero_copy_end;
 
-    ASSERT_TRUE(writer.AddRawBlocks(blk_random2_replace_start, random_buffer_2.get(), size));
+    ASSERT_TRUE(writer.AddRawBlocks(blk_random2_replace_start, random_buffer_2_.get(), size_));
 
     // Flush operations
     ASSERT_TRUE(writer.Finalize());
 
-    ASSERT_EQ(lseek(cow_->fd, 0, SEEK_SET), 0);
+    ASSERT_EQ(lseek(cow->fd, 0, SEEK_SET), 0);
+}
 
-    //================Setup dm-snapshot and start snapuserd daemon===========
+void SnapuserdTest::CreateSystemDmUser() {
+    unique_fd system_a_fd;
+    std::string cmd;
 
     // Create a COW device. Number of sectors is chosen random which can
     // hold at least 400MB of data
@@ -140,39 +177,77 @@
     system_a_fd.reset(open("/dev/block/mapper/system_a", O_RDONLY));
     ASSERT_TRUE(system_a_fd > 0);
 
-    int blksize;
-    int err = ioctl(system_a_fd.get(), BLKGETSIZE, &blksize);
-    if (err < 0) {
-        ASSERT_TRUE(0);
-    }
+    int err = ioctl(system_a_fd.get(), BLKGETSIZE, &system_blksize_);
+    ASSERT_GE(err, 0);
 
-    cmd = "dmctl create system_cow user 0 " + std::to_string(blksize);
+    std::string str(cow_system_->path);
+    std::size_t found = str.find_last_of("/\\");
+    ASSERT_NE(found, std::string::npos);
+    system_device_name_ = str.substr(found + 1);
+    cmd = "dmctl create " + system_device_name_ + " user 0 " + std::to_string(system_blksize_);
+
     system(cmd.c_str());
+}
 
+void SnapuserdTest::CreateProductDmUser() {
+    unique_fd product_a_fd;
+    std::string cmd;
+
+    // Create a COW device. Number of sectors is chosen random which can
+    // hold at least 400MB of data
+
+    product_a_fd.reset(open("/dev/block/mapper/product_a", O_RDONLY));
+    ASSERT_TRUE(product_a_fd > 0);
+
+    int err = ioctl(product_a_fd.get(), BLKGETSIZE, &product_blksize_);
+    ASSERT_GE(err, 0);
+
+    std::string str(cow_product_->path);
+    std::size_t found = str.find_last_of("/\\");
+    ASSERT_NE(found, std::string::npos);
+    product_device_name_ = str.substr(found + 1);
+    cmd = "dmctl create " + product_device_name_ + " user 0 " + std::to_string(product_blksize_);
+
+    system(cmd.c_str());
+}
+
+void SnapuserdTest::StartSnapuserdDaemon() {
     // Start the snapuserd daemon
     if (fork() == 0) {
-        const char* argv[] = {"/system/bin/snapuserd", cow_->path, "/dev/block/mapper/system_a",
-                              nullptr};
+        const char* argv[] = {"/system/bin/snapuserd",       cow_system_->path,
+                              "/dev/block/mapper/system_a",  cow_product_->path,
+                              "/dev/block/mapper/product_a", nullptr};
         if (execv(argv[0], const_cast<char**>(argv))) {
             ASSERT_TRUE(0);
         }
     }
+}
+
+void SnapuserdTest::CreateSnapshotDevices() {
+    std::string cmd;
+
+    cmd = "dmctl create system-snapshot -ro snapshot 0 " + std::to_string(system_blksize_);
+    cmd += " /dev/block/mapper/system_a";
+    cmd += " /dev/block/mapper/" + system_device_name_;
+    cmd += " P 8";
+
+    system(cmd.c_str());
 
     cmd.clear();
 
-    cmd = "dmctl create system-snapshot -ro snapshot 0 " + std::to_string(blksize);
-    cmd += " /dev/block/mapper/system_a /dev/block/mapper/system_cow ";
-    cmd += "P 8";
+    cmd = "dmctl create product-snapshot -ro snapshot 0 " + std::to_string(product_blksize_);
+    cmd += " /dev/block/mapper/product_a";
+    cmd += " /dev/block/mapper/" + product_device_name_;
+    cmd += " P 8";
+
     system(cmd.c_str());
+}
 
-    // Wait so that snapshot device is created
-    sleep(5);
-    std::unique_ptr<uint8_t[]> snapuserd_buffer = std::make_unique<uint8_t[]>(size);
+void SnapuserdTest::TestIO(unique_fd& snapshot_fd, std::unique_ptr<uint8_t[]>&& buf) {
+    loff_t offset = 0;
+    std::unique_ptr<uint8_t[]> buffer = std::move(buf);
 
-    offset = 0;
-
-    snapshot_fd.reset(open("/dev/block/mapper/system-snapshot", O_RDONLY));
-    ASSERT_TRUE(snapshot_fd > 0);
+    std::unique_ptr<uint8_t[]> snapuserd_buffer = std::make_unique<uint8_t[]>(size_);
 
     //================Start IO operation on dm-snapshot device=================
     // This will test the following paths:
@@ -189,16 +264,16 @@
     // dm-snap->dm-snap-persistent->dm-user->snapuserd->read_compressed_cow (replace
     // op)->decompress_cow->return
 
-    ASSERT_EQ(ReadFullyAtOffset(snapshot_fd, snapuserd_buffer.get(), size, offset), true);
+    ASSERT_EQ(ReadFullyAtOffset(snapshot_fd, snapuserd_buffer.get(), size_, offset), true);
 
     // Update the offset
-    offset += size;
+    offset += size_;
 
-    // Compare data with random_buffer_1.
-    ASSERT_EQ(memcmp(snapuserd_buffer.get(), random_buffer_1.get(), size), 0);
+    // Compare data with random_buffer_1_.
+    ASSERT_EQ(memcmp(snapuserd_buffer.get(), random_buffer_1_.get(), size_), 0);
 
     // Clear the buffer
-    memset(snapuserd_buffer.get(), 0, size);
+    memset(snapuserd_buffer.get(), 0, size_);
 
     // Read from snapshot device of size 100MB from offset 100MB. This tests the
     // copy operation.
@@ -207,13 +282,13 @@
     //
     // dm-snap->dm-snap-persistent->dm-user->snapuserd->read_from_system_a_partition
     // (copy op) -> return
-    ASSERT_EQ(ReadFullyAtOffset(snapshot_fd, snapuserd_buffer.get(), size, offset), true);
+    ASSERT_EQ(ReadFullyAtOffset(snapshot_fd, snapuserd_buffer.get(), size_, offset), true);
 
     // Update the offset
-    offset += size;
+    offset += size_;
 
-    // Compare data with system_buffer.
-    ASSERT_EQ(memcmp(snapuserd_buffer.get(), system_buffer.get(), size), 0);
+    // Compare data with buffer.
+    ASSERT_EQ(memcmp(snapuserd_buffer.get(), buffer.get(), size_), 0);
 
     // Read from snapshot device of size 100MB from offset 200MB. This tests the
     // zero operation.
@@ -222,16 +297,13 @@
     //
     // dm-snap->dm-snap-persistent->dm-user->snapuserd->fill_memory_with_zero
     // (zero op) -> return
-    ASSERT_EQ(ReadFullyAtOffset(snapshot_fd, snapuserd_buffer.get(), size, offset), true);
-
-    // Fill the random_buffer_1 with zero as we no longer need it
-    memset(random_buffer_1.get(), 0, size);
+    ASSERT_EQ(ReadFullyAtOffset(snapshot_fd, snapuserd_buffer.get(), size_, offset), true);
 
     // Compare data with zero filled buffer
-    ASSERT_EQ(memcmp(snapuserd_buffer.get(), random_buffer_1.get(), size), 0);
+    ASSERT_EQ(memcmp(snapuserd_buffer.get(), zero_buffer_.get(), size_), 0);
 
     // Update the offset
-    offset += size;
+    offset += size_;
 
     // Read from snapshot device of size 100MB from offset 300MB. This tests the
     // final replace operation.
@@ -240,10 +312,34 @@
     //
     // dm-snap->dm-snap-persistent->dm-user->snapuserd->read_compressed_cow (replace
     // op)->decompress_cow->return
-    ASSERT_EQ(ReadFullyAtOffset(snapshot_fd, snapuserd_buffer.get(), size, offset), true);
+    ASSERT_EQ(ReadFullyAtOffset(snapshot_fd, snapuserd_buffer.get(), size_, offset), true);
 
-    // Compare data with random_buffer_2.
-    ASSERT_EQ(memcmp(snapuserd_buffer.get(), random_buffer_2.get(), size), 0);
+    // Compare data with random_buffer_2_.
+    ASSERT_EQ(memcmp(snapuserd_buffer.get(), random_buffer_2_.get(), size_), 0);
+}
+
+TEST_F(SnapuserdTest, ReadWrite) {
+    unique_fd snapshot_fd;
+
+    Init();
+
+    CreateCowDevice(cow_system_);
+    CreateCowDevice(cow_product_);
+
+    CreateSystemDmUser();
+    CreateProductDmUser();
+
+    StartSnapuserdDaemon();
+
+    CreateSnapshotDevices();
+
+    snapshot_fd.reset(open("/dev/block/mapper/system-snapshot", O_RDONLY));
+    ASSERT_TRUE(snapshot_fd > 0);
+    TestIO(snapshot_fd, std::move(system_buffer_));
+
+    snapshot_fd.reset(open("/dev/block/mapper/product-snapshot", O_RDONLY));
+    ASSERT_TRUE(snapshot_fd > 0);
+    TestIO(snapshot_fd, std::move(product_buffer_));
 }
 
 }  // namespace snapshot
diff --git a/fs_mgr/libsnapshot/snapuserd.cpp b/fs_mgr/libsnapshot/snapuserd.cpp
index 605af9b..d3f4f70 100644
--- a/fs_mgr/libsnapshot/snapuserd.cpp
+++ b/fs_mgr/libsnapshot/snapuserd.cpp
@@ -17,10 +17,12 @@
 #include <linux/types.h>
 #include <stdlib.h>
 
+#include <csignal>
 #include <cstring>
 #include <iostream>
 #include <limits>
 #include <string>
+#include <thread>
 #include <vector>
 
 #include <android-base/file.h>
@@ -35,6 +37,7 @@
 namespace android {
 namespace snapshot {
 
+using namespace android;
 using namespace android::dm;
 using android::base::unique_fd;
 
@@ -45,6 +48,60 @@
 
 static_assert(PAYLOAD_SIZE >= BLOCK_SIZE);
 
+class Target {
+  public:
+    // Represents an already-created Target, which is referenced by UUID.
+    Target(std::string uuid) : uuid_(uuid) {}
+
+    const auto& uuid() { return uuid_; }
+    std::string control_path() { return std::string("/dev/dm-user-") + uuid(); }
+
+  private:
+    const std::string uuid_;
+};
+
+class Daemon {
+    // The Daemon class is a singleton to avoid
+    // instantiating more than once
+  public:
+    static Daemon& Instance() {
+        static Daemon instance;
+        return instance;
+    }
+
+    bool IsRunning();
+
+  private:
+    bool is_running_;
+
+    Daemon();
+    Daemon(Daemon const&) = delete;
+    void operator=(Daemon const&) = delete;
+
+    static void SignalHandler(int signal);
+};
+
+Daemon::Daemon() {
+    is_running_ = true;
+    signal(SIGINT, Daemon::SignalHandler);
+    signal(SIGTERM, Daemon::SignalHandler);
+}
+
+bool Daemon::IsRunning() {
+    return is_running_;
+}
+
+void Daemon::SignalHandler(int signal) {
+    LOG(DEBUG) << "Snapuserd received signal: " << signal;
+    switch (signal) {
+        case SIGINT:
+        case SIGTERM: {
+            Daemon::Instance().is_running_ = false;
+            break;
+        }
+    }
+}
+
 class BufferSink : public IByteSink {
   public:
     void Initialize(size_t size) {
@@ -558,10 +615,26 @@
         return 1;
     }
 
-    // TODO: use UUID to support multiple partitions
-    ctrl_fd_.reset(open("/dev/dm-user", O_RDWR));
+    std::string str(in_cow_device_);
+    std::size_t found = str.find_last_of("/\\");
+    CHECK(found != std::string::npos);
+    std::string device_name = str.substr(found + 1);
+
+    LOG(DEBUG) << "Fetching UUID for: " << device_name;
+
+    auto& dm = dm::DeviceMapper::Instance();
+    std::string uuid;
+    if (!dm.GetDmDeviceUuidByName(device_name, &uuid)) {
+        LOG(ERROR) << "Unable to find UUID for " << in_cow_device_;
+        return 1;
+    }
+
+    LOG(DEBUG) << "UUID: " << uuid;
+    Target t(uuid);
+
+    ctrl_fd_.reset(open(t.control_path().c_str(), O_RDWR));
     if (ctrl_fd_ < 0) {
-        LOG(ERROR) << "Unable to open /dev/dm-user";
+        LOG(ERROR) << "Unable to open " << t.control_path();
         return 1;
     }
 
@@ -682,9 +755,30 @@
 }  // namespace snapshot
 }  // namespace android
 
+void run_thread(std::string cow_device, std::string backing_device) {
+    android::snapshot::Snapuserd snapd(cow_device, backing_device);
+    snapd.Run();
+}
+
 int main([[maybe_unused]] int argc, char** argv) {
     android::base::InitLogging(argv, &android::base::KernelLogger);
-    android::snapshot::Snapuserd snapd(argv[1], argv[2]);
 
-    return snapd.Run();
+    android::snapshot::Daemon& daemon = android::snapshot::Daemon::Instance();
+
+    while (daemon.IsRunning()) {
+        // TODO: This is hardcoded wherein:
+        // argv[1] = system_cow, argv[2] = /dev/block/mapper/system_a
+        // argv[3] = product_cow, argv[4] = /dev/block/mapper/product_a
+        //
+        // This should be fixed based on some kind of IPC or setup a
+        // command socket and spin up the thread based when a new
+        // partition is visible.
+        std::thread system_a(run_thread, argv[1], argv[2]);
+        std::thread product_a(run_thread, argv[3], argv[4]);
+
+        system_a.join();
+        product_a.join();
+    }
+
+    return 0;
 }
diff --git a/fs_mgr/tools/dmctl.cpp b/fs_mgr/tools/dmctl.cpp
index 1bfd9b2..9edcda7 100644
--- a/fs_mgr/tools/dmctl.cpp
+++ b/fs_mgr/tools/dmctl.cpp
@@ -38,6 +38,7 @@
 #include <vector>
 
 using namespace std::literals::string_literals;
+using namespace std::chrono_literals;
 using namespace android::dm;
 using DmBlockDevice = ::android::dm::DeviceMapper::DmBlockDevice;
 
@@ -242,8 +243,9 @@
         return ret;
     }
 
+    std::string ignore_path;
     DeviceMapper& dm = DeviceMapper::Instance();
-    if (!dm.CreateDevice(name, table)) {
+    if (!dm.CreateDevice(name, table, &ignore_path, 5s)) {
         std::cerr << "Failed to create device-mapper device with name: " << name << std::endl;
         return -EIO;
     }
@@ -392,7 +394,7 @@
     return 0;
 }
 
-static int GetUUIDCmdHandler(int argc, char** argv) {
+static int GetUuidCmdHandler(int argc, char** argv) {
     if (argc != 1) {
         std::cerr << "Invalid arguments, see \'dmctl help\'" << std::endl;
         return -EINVAL;
@@ -400,7 +402,7 @@
 
     DeviceMapper& dm = DeviceMapper::Instance();
     std::string uuid;
-    if (!dm.GetDmDeviceUUIDByName(argv[0], &uuid)) {
+    if (!dm.GetDmDeviceUuidByName(argv[0], &uuid)) {
         std::cerr << "Could not query uuid of device \"" << argv[0] << "\"." << std::endl;
         return -EINVAL;
     }
@@ -521,7 +523,7 @@
         {"list", DmListCmdHandler},
         {"help", HelpCmdHandler},
         {"getpath", GetPathCmdHandler},
-        {"getuuid", GetUUIDCmdHandler},
+        {"getuuid", GetUuidCmdHandler},
         {"info", InfoCmdHandler},
         {"table", TableCmdHandler},
         {"status", StatusCmdHandler},
diff --git a/include/private/android_filesystem_capability.h b/include/private/android_filesystem_capability.h
deleted file mode 120000
index f310b35..0000000
--- a/include/private/android_filesystem_capability.h
+++ /dev/null
@@ -1 +0,0 @@
-../../libcutils/include/private/android_filesystem_capability.h
\ No newline at end of file
diff --git a/include/private/canned_fs_config.h b/include/private/canned_fs_config.h
deleted file mode 120000
index 8f92b2d..0000000
--- a/include/private/canned_fs_config.h
+++ /dev/null
@@ -1 +0,0 @@
-../../libcutils/include/private/canned_fs_config.h
\ No newline at end of file
diff --git a/include/private/fs_config.h b/include/private/fs_config.h
deleted file mode 100644
index e9868a4..0000000
--- a/include/private/fs_config.h
+++ /dev/null
@@ -1,4 +0,0 @@
-// TODO(b/63135587) remove this file after the transitive dependency
-// from private/android_filesystem_config.h is resolved. All files that use
-// libcutils/include/private/fs_config.h should include the file directly, not
-// indirectly via private/android_filesystem_config.h.