update_engine: drop MTD logic

It has no users.

Note that I'm also dropping unit tests of the form:

  EXPECT_TRUE(utils::SplitPartitionName("/dev/loop10_0", &disk, &part_num));
  EXPECT_EQ("/dev/loop", disk);
  EXPECT_EQ(10, part_num);

  EXPECT_TRUE(utils::SplitPartitionName("/dev/loop28p11_0", &disk, &part_num));
  EXPECT_EQ("/dev/loop28", disk);
  EXPECT_EQ(11, part_num);

AFAICT, the part of the change that introduced these
(https://crrev.com/c/191785) was not based on any real issue; it was
(correctly) handling partition suffixes for loop devices (e.g., the 'p1'
in '/dev/loop0p1'), but the underscore syntax is specific to
ubi/ubiblock and should not apply to loop devices.

See the ubiblock naming code [1], analogous loop device naming code [2],
and the partition-name generation code [3].

[1] https://elixir.bootlin.com/linux/v5.1.15/source/drivers/mtd/ubi/block.c#L402
[2] https://elixir.bootlin.com/linux/v5.1.15/source/drivers/block/loop.c#L2012
[3] https://elixir.bootlin.com/linux/v5.1.15/source/block/partition-generic.c#L35

BUG=chromium:978563
TEST=unit tests

Change-Id: I38754a5060ed3c9e6b11fb53d82ff6fb79149c72
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index f405bd9..53acc11 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -54,9 +54,6 @@
 #endif  // USE_FEC
 #include "update_engine/payload_consumer/file_descriptor_utils.h"
 #include "update_engine/payload_consumer/mount_history.h"
-#if USE_MTD
-#include "update_engine/payload_consumer/mtd_file_descriptor.h"
-#endif  // USE_MTD
 #include "update_engine/payload_consumer/payload_constants.h"
 #include "update_engine/payload_consumer/payload_verifier.h"
 #include "update_engine/payload_consumer/xz_extent_writer.h"
@@ -76,40 +73,9 @@
 namespace {
 const int kUpdateStateOperationInvalid = -1;
 const int kMaxResumedUpdateFailures = 10;
-#if USE_MTD
-const int kUbiVolumeAttachTimeout = 5 * 60;
-#endif
 
 const uint64_t kCacheSize = 1024 * 1024;  // 1MB
 
-FileDescriptorPtr CreateFileDescriptor(const char* path) {
-  FileDescriptorPtr ret;
-#if USE_MTD
-  if (strstr(path, "/dev/ubi") == path) {
-    if (!UbiFileDescriptor::IsUbi(path)) {
-      // The volume might not have been attached at boot time.
-      int volume_no;
-      if (utils::SplitPartitionName(path, nullptr, &volume_no)) {
-        utils::TryAttachingUbiVolume(volume_no, kUbiVolumeAttachTimeout);
-      }
-    }
-    if (UbiFileDescriptor::IsUbi(path)) {
-      LOG(INFO) << path << " is a UBI device.";
-      ret.reset(new UbiFileDescriptor);
-    }
-  } else if (MtdFileDescriptor::IsMtd(path)) {
-    LOG(INFO) << path << " is an MTD device.";
-    ret.reset(new MtdFileDescriptor);
-  } else {
-    LOG(INFO) << path << " is not an MTD nor a UBI device.";
-#endif
-    ret.reset(new EintrSafeFileDescriptor);
-#if USE_MTD
-  }
-#endif
-  return ret;
-}
-
 // Opens path for read/write. On success returns an open FileDescriptor
 // and sets *err to 0. On failure, sets *err to errno and returns nullptr.
 FileDescriptorPtr OpenFile(const char* path,
@@ -121,18 +87,11 @@
   bool read_only = (mode & O_ACCMODE) == O_RDONLY;
   utils::SetBlockDeviceReadOnly(path, read_only);
 
-  FileDescriptorPtr fd = CreateFileDescriptor(path);
+  FileDescriptorPtr fd(new EintrSafeFileDescriptor());
   if (cache_writes && !read_only) {
     fd = FileDescriptorPtr(new CachedFileDescriptor(fd, kCacheSize));
     LOG(INFO) << "Caching writes.";
   }
-#if USE_MTD
-  // On NAND devices, we can either read, or write, but not both. So here we
-  // use O_WRONLY.
-  if (UbiFileDescriptor::IsUbi(path) || MtdFileDescriptor::IsMtd(path)) {
-    mode = O_WRONLY;
-  }
-#endif
   if (!fd->Open(path, mode, 000)) {
     *err = errno;
     PLOG(ERROR) << "Unable to open file " << path;
diff --git a/payload_consumer/mtd_file_descriptor.cc b/payload_consumer/mtd_file_descriptor.cc
deleted file mode 100644
index 5d940cb..0000000
--- a/payload_consumer/mtd_file_descriptor.cc
+++ /dev/null
@@ -1,263 +0,0 @@
-//
-// Copyright (C) 2014 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 "update_engine/payload_consumer/mtd_file_descriptor.h"
-
-#include <fcntl.h>
-#include <mtd/ubi-user.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <memory>
-#include <string>
-
-#include <base/files/file_path.h>
-#include <base/strings/string_number_conversions.h>
-#include <base/strings/string_util.h>
-#include <base/strings/stringprintf.h>
-
-#include "update_engine/common/subprocess.h"
-#include "update_engine/common/utils.h"
-
-using std::string;
-
-namespace {
-
-static const char kSysfsClassUbi[] = "/sys/class/ubi/";
-static const char kUsableEbSize[] = "/usable_eb_size";
-static const char kReservedEbs[] = "/reserved_ebs";
-
-using chromeos_update_engine::UbiVolumeInfo;
-using chromeos_update_engine::utils::ReadFile;
-
-// Return a UbiVolumeInfo pointer if |path| is a UBI volume. Otherwise, return
-// a null unique pointer.
-std::unique_ptr<UbiVolumeInfo> GetUbiVolumeInfo(const string& path) {
-  base::FilePath device_node(path);
-  base::FilePath ubi_name(device_node.BaseName());
-
-  string sysfs_node(kSysfsClassUbi);
-  sysfs_node.append(ubi_name.MaybeAsASCII());
-
-  std::unique_ptr<UbiVolumeInfo> ret;
-
-  // Obtain volume info from sysfs.
-  string s_reserved_ebs;
-  if (!ReadFile(sysfs_node + kReservedEbs, &s_reserved_ebs)) {
-    LOG(ERROR) << "Cannot read " << sysfs_node + kReservedEbs;
-    return ret;
-  }
-  string s_eb_size;
-  if (!ReadFile(sysfs_node + kUsableEbSize, &s_eb_size)) {
-    LOG(ERROR) << "Cannot read " << sysfs_node + kUsableEbSize;
-    return ret;
-  }
-
-  base::TrimWhitespaceASCII(
-      s_reserved_ebs, base::TRIM_TRAILING, &s_reserved_ebs);
-  base::TrimWhitespaceASCII(s_eb_size, base::TRIM_TRAILING, &s_eb_size);
-
-  uint64_t reserved_ebs, eb_size;
-  if (!base::StringToUint64(s_reserved_ebs, &reserved_ebs)) {
-    LOG(ERROR) << "Cannot parse reserved_ebs: " << s_reserved_ebs;
-    return ret;
-  }
-  if (!base::StringToUint64(s_eb_size, &eb_size)) {
-    LOG(ERROR) << "Cannot parse usable_eb_size: " << s_eb_size;
-    return ret;
-  }
-
-  ret.reset(new UbiVolumeInfo);
-  ret->reserved_ebs = reserved_ebs;
-  ret->eraseblock_size = eb_size;
-  return ret;
-}
-
-}  // namespace
-
-namespace chromeos_update_engine {
-
-MtdFileDescriptor::MtdFileDescriptor()
-    : read_ctx_(nullptr, &mtd_read_close),
-      write_ctx_(nullptr, &mtd_write_close) {}
-
-bool MtdFileDescriptor::IsMtd(const char* path) {
-  uint64_t size;
-  return mtd_node_info(path, &size, nullptr, nullptr) == 0;
-}
-
-bool MtdFileDescriptor::Open(const char* path, int flags, mode_t mode) {
-  // This File Descriptor does not support read and write.
-  TEST_AND_RETURN_FALSE((flags & O_ACCMODE) != O_RDWR);
-  // But we need to open the underlying file descriptor in O_RDWR mode because
-  // during write, we need to read back to verify the write actually sticks or
-  // we have to skip the block. That job is done by mtdutils library.
-  if ((flags & O_ACCMODE) == O_WRONLY) {
-    flags &= ~O_ACCMODE;
-    flags |= O_RDWR;
-  }
-  TEST_AND_RETURN_FALSE(
-      EintrSafeFileDescriptor::Open(path, flags | O_CLOEXEC, mode));
-
-  if ((flags & O_ACCMODE) == O_RDWR) {
-    write_ctx_.reset(mtd_write_descriptor(fd_, path));
-    nr_written_ = 0;
-  } else {
-    read_ctx_.reset(mtd_read_descriptor(fd_, path));
-  }
-
-  if (!read_ctx_ && !write_ctx_) {
-    Close();
-    return false;
-  }
-
-  return true;
-}
-
-bool MtdFileDescriptor::Open(const char* path, int flags) {
-  mode_t cur = umask(022);
-  umask(cur);
-  return Open(path, flags, 0777 & ~cur);
-}
-
-ssize_t MtdFileDescriptor::Read(void* buf, size_t count) {
-  CHECK(read_ctx_);
-  return mtd_read_data(read_ctx_.get(), static_cast<char*>(buf), count);
-}
-
-ssize_t MtdFileDescriptor::Write(const void* buf, size_t count) {
-  CHECK(write_ctx_);
-  ssize_t result =
-      mtd_write_data(write_ctx_.get(), static_cast<const char*>(buf), count);
-  if (result > 0) {
-    nr_written_ += result;
-  }
-  return result;
-}
-
-off64_t MtdFileDescriptor::Seek(off64_t offset, int whence) {
-  if (write_ctx_) {
-    // Ignore seek in write mode.
-    return nr_written_;
-  }
-  return EintrSafeFileDescriptor::Seek(offset, whence);
-}
-
-bool MtdFileDescriptor::Close() {
-  read_ctx_.reset();
-  write_ctx_.reset();
-  return EintrSafeFileDescriptor::Close();
-}
-
-bool UbiFileDescriptor::IsUbi(const char* path) {
-  base::FilePath device_node(path);
-  base::FilePath ubi_name(device_node.BaseName());
-  TEST_AND_RETURN_FALSE(base::StartsWith(
-      ubi_name.MaybeAsASCII(), "ubi", base::CompareCase::SENSITIVE));
-
-  return static_cast<bool>(GetUbiVolumeInfo(path));
-}
-
-bool UbiFileDescriptor::Open(const char* path, int flags, mode_t mode) {
-  std::unique_ptr<UbiVolumeInfo> info = GetUbiVolumeInfo(path);
-  if (!info) {
-    return false;
-  }
-
-  // This File Descriptor does not support read and write.
-  TEST_AND_RETURN_FALSE((flags & O_ACCMODE) != O_RDWR);
-  TEST_AND_RETURN_FALSE(
-      EintrSafeFileDescriptor::Open(path, flags | O_CLOEXEC, mode));
-
-  usable_eb_blocks_ = info->reserved_ebs;
-  eraseblock_size_ = info->eraseblock_size;
-  volume_size_ = usable_eb_blocks_ * eraseblock_size_;
-
-  if ((flags & O_ACCMODE) == O_WRONLY) {
-    // It's best to use volume update ioctl so that UBI layer will mark the
-    // volume as being updated, and only clear that mark if the update is
-    // successful. We will need to pad to the whole volume size at close.
-    uint64_t vsize = volume_size_;
-    if (ioctl(fd_, UBI_IOCVOLUP, &vsize) != 0) {
-      PLOG(ERROR) << "Cannot issue volume update ioctl";
-      EintrSafeFileDescriptor::Close();
-      return false;
-    }
-    mode_ = kWriteOnly;
-    nr_written_ = 0;
-  } else {
-    mode_ = kReadOnly;
-  }
-
-  return true;
-}
-
-bool UbiFileDescriptor::Open(const char* path, int flags) {
-  mode_t cur = umask(022);
-  umask(cur);
-  return Open(path, flags, 0777 & ~cur);
-}
-
-ssize_t UbiFileDescriptor::Read(void* buf, size_t count) {
-  CHECK(mode_ == kReadOnly);
-  return EintrSafeFileDescriptor::Read(buf, count);
-}
-
-ssize_t UbiFileDescriptor::Write(const void* buf, size_t count) {
-  CHECK(mode_ == kWriteOnly);
-  ssize_t nr_chunk = EintrSafeFileDescriptor::Write(buf, count);
-  if (nr_chunk >= 0) {
-    nr_written_ += nr_chunk;
-  }
-  return nr_chunk;
-}
-
-off64_t UbiFileDescriptor::Seek(off64_t offset, int whence) {
-  if (mode_ == kWriteOnly) {
-    // Ignore seek in write mode.
-    return nr_written_;
-  }
-  return EintrSafeFileDescriptor::Seek(offset, whence);
-}
-
-bool UbiFileDescriptor::Close() {
-  bool pad_ok = true;
-  if (IsOpen() && mode_ == kWriteOnly) {
-    char buf[1024];
-    memset(buf, 0xFF, sizeof(buf));
-    while (nr_written_ < volume_size_) {
-      // We have written less than the whole volume. In order for us to clear
-      // the update marker, we need to fill the rest. It is recommended to fill
-      // UBI writes with 0xFF.
-      uint64_t to_write = volume_size_ - nr_written_;
-      if (to_write > sizeof(buf)) {
-        to_write = sizeof(buf);
-      }
-      ssize_t nr_chunk = EintrSafeFileDescriptor::Write(buf, to_write);
-      if (nr_chunk < 0) {
-        LOG(ERROR) << "Cannot 0xFF-pad before closing.";
-        // There is an error, but we can't really do any meaningful thing here.
-        pad_ok = false;
-        break;
-      }
-      nr_written_ += nr_chunk;
-    }
-  }
-  return EintrSafeFileDescriptor::Close() && pad_ok;
-}
-
-}  // namespace chromeos_update_engine
diff --git a/payload_consumer/mtd_file_descriptor.h b/payload_consumer/mtd_file_descriptor.h
deleted file mode 100644
index c0170b7..0000000
--- a/payload_consumer/mtd_file_descriptor.h
+++ /dev/null
@@ -1,103 +0,0 @@
-//
-// Copyright (C) 2014 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 UPDATE_ENGINE_PAYLOAD_CONSUMER_MTD_FILE_DESCRIPTOR_H_
-#define UPDATE_ENGINE_PAYLOAD_CONSUMER_MTD_FILE_DESCRIPTOR_H_
-
-// This module defines file descriptors that deal with NAND media. We are
-// concerned with raw NAND access (as MTD device), and through UBI layer.
-
-#include <memory>
-
-#include <mtdutils.h>
-
-#include "update_engine/payload_consumer/file_descriptor.h"
-
-namespace chromeos_update_engine {
-
-// A class defining the file descriptor API for raw MTD device. This file
-// descriptor supports either random read, or sequential write but not both at
-// once.
-class MtdFileDescriptor : public EintrSafeFileDescriptor {
- public:
-  MtdFileDescriptor();
-
-  static bool IsMtd(const char* path);
-
-  bool Open(const char* path, int flags, mode_t mode) override;
-  bool Open(const char* path, int flags) override;
-  ssize_t Read(void* buf, size_t count) override;
-  ssize_t Write(const void* buf, size_t count) override;
-  off64_t Seek(off64_t offset, int whence) override;
-  uint64_t BlockDevSize() override { return 0; }
-  bool BlkIoctl(int request,
-                uint64_t start,
-                uint64_t length,
-                int* result) override {
-    return false;
-  }
-  bool Close() override;
-
- private:
-  std::unique_ptr<MtdReadContext, decltype(&mtd_read_close)> read_ctx_;
-  std::unique_ptr<MtdWriteContext, decltype(&mtd_write_close)> write_ctx_;
-  uint64_t nr_written_;
-};
-
-struct UbiVolumeInfo {
-  // Number of eraseblocks.
-  uint64_t reserved_ebs;
-  // Size of each eraseblock.
-  uint64_t eraseblock_size;
-};
-
-// A file descriptor to update a UBI volume, similar to MtdFileDescriptor.
-// Once the file descriptor is opened for write, the volume is marked as being
-// updated. The volume will not be usable until an update is completed. See
-// UBI_IOCVOLUP ioctl operation.
-class UbiFileDescriptor : public EintrSafeFileDescriptor {
- public:
-  // Perform some queries about |path| to see if it is a UBI volume.
-  static bool IsUbi(const char* path);
-
-  bool Open(const char* path, int flags, mode_t mode) override;
-  bool Open(const char* path, int flags) override;
-  ssize_t Read(void* buf, size_t count) override;
-  ssize_t Write(const void* buf, size_t count) override;
-  off64_t Seek(off64_t offset, int whence) override;
-  uint64_t BlockDevSize() override { return 0; }
-  bool BlkIoctl(int request,
-                uint64_t start,
-                uint64_t length,
-                int* result) override {
-    return false;
-  }
-  bool Close() override;
-
- private:
-  enum Mode { kReadOnly, kWriteOnly };
-
-  uint64_t usable_eb_blocks_;
-  uint64_t eraseblock_size_;
-  uint64_t volume_size_;
-  uint64_t nr_written_;
-
-  Mode mode_;
-};
-
-}  // namespace chromeos_update_engine
-
-#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_MTD_FILE_DESCRIPTOR_H_
diff --git a/payload_consumer/postinstall_runner_action.cc b/payload_consumer/postinstall_runner_action.cc
index cc3843d..894ac7d 100644
--- a/payload_consumer/postinstall_runner_action.cc
+++ b/payload_consumer/postinstall_runner_action.cc
@@ -111,8 +111,7 @@
   const InstallPlan::Partition& partition =
       install_plan_.partitions[current_partition_];
 
-  const string mountable_device =
-      utils::MakePartitionNameForMount(partition.target_path);
+  const string mountable_device = partition.target_path;
   if (mountable_device.empty()) {
     LOG(ERROR) << "Cannot make mountable device from " << partition.target_path;
     return CompletePostinstall(ErrorCode::kPostinstallRunnerError);