update_engine: Support full update on MTD devices

This CL fleshes out the MTD and UBI FileDescriptor subclasses and
modifies the utility functions that deal with device name and partition
number to support NAND scheme.

BUG=brillo:45
BUG=brillo:43
TEST=unittest on rambi
TEST=cros flash to storm_nand, reboot, make sure rootdev -s says something
different. Then repeat and make sure that another device is reported.
TEST=If the above was done with verified-rootfs, repeat with
non-verified image.

Change-Id: I31b9a00642f9a7ff67ea51a4cf3dc31b86095e98
Reviewed-on: https://chromium-review.googlesource.com/257192
Reviewed-by: Nam Nguyen <namnguyen@chromium.org>
Commit-Queue: Nam Nguyen <namnguyen@chromium.org>
Tested-by: Nam Nguyen <namnguyen@chromium.org>
diff --git a/mtd_file_descriptor.h b/mtd_file_descriptor.h
index 4694016..ad545b6 100644
--- a/mtd_file_descriptor.h
+++ b/mtd_file_descriptor.h
@@ -28,28 +28,28 @@
   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;
-  void Reset() override;
+  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_;
 };
 
-// TODO(namnguyen) This is a placeholder struct. This struct, and the
-// UbiFileDescriptor class below will need finalized later.
 struct UbiVolumeInfo {
-  uint64_t size;
+  // 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.
-// TODO(namnguyen) Again, this needs fleshed out when we have better library to
-// interact with UBI volumes. I would expect this class to be very similar to
-// MtdFileDescriptor, with two different contexts to bridge C-C++ divide.
 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;
@@ -57,13 +57,20 @@
   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;
-  void Reset() override;
+  bool Close() override;
 
  private:
-  std::unique_ptr<UbiVolumeInfo> CreateWriteContext(const char* path);
+  enum Mode {
+    kReadOnly,
+    kWriteOnly
+  };
 
-  std::unique_ptr<UbiVolumeInfo> read_ctx_;
-  std::unique_ptr<UbiVolumeInfo> write_ctx_;
+  uint64_t usable_eb_blocks_;
+  uint64_t eraseblock_size_;
+  uint64_t volume_size_;
+  uint64_t nr_written_;
+
+  Mode mode_;
 };
 
 }  // namespace chromeos_update_engine