Tidy up Drive and unmounting a little.
authorCarl Hetherington <cth@carlh.net>
Thu, 9 Apr 2020 18:52:20 +0000 (20:52 +0200)
committerCarl Hetherington <cth@carlh.net>
Sun, 12 Apr 2020 22:23:46 +0000 (00:23 +0200)
src/lib/copy_to_drive_job.cc
src/lib/cross.h
src/lib/cross_common.cc
src/lib/cross_linux.cc
src/lib/disk_writer_messages.h
src/tools/dcpomatic_disk.cc
src/tools/dcpomatic_disk_writer.cc

index fcac7e41bcd5012a53161642b4a0be849b13808e..8a8073ec21e505e37906718c5d02c6b772b08224 100644 (file)
@@ -64,7 +64,7 @@ CopyToDriveJob::json_name () const
 void
 CopyToDriveJob::run ()
 {
-       if (!_nanomsg.send(String::compose(DISK_WRITER_WRITE "\n%1\n%2\n", _dcp.string(), _drive.internal_name()), 2000)) {
+       if (!_nanomsg.send(String::compose(DISK_WRITER_WRITE "\n%1\n%2\n", _dcp.string(), _drive.device()), 2000)) {
                throw CommunicationFailedError ();
        }
 
index 7bbb394a1f87247e5fcbd6030fc829687d16f0a5..ece36fe252aef51da20217295dcba7ad6211b1b7 100644 (file)
@@ -98,35 +98,44 @@ private:
 class Drive
 {
 public:
-       Drive (std::string internal_name, uint64_t size, bool mounted, boost::optional<std::string> vendor, boost::optional<std::string> model)
-               : _internal_name(internal_name)
+       Drive (std::string device, std::vector<boost::filesystem::path> mount_points, uint64_t size, boost::optional<std::string> vendor, boost::optional<std::string> model)
+               : _device(device)
+               , _mount_points(mount_points)
                , _size(size)
-               , _mounted(mounted)
                , _vendor(vendor)
                , _model(model)
        {}
 
+       explicit Drive (std::string);
+
+       std::string as_xml () const;
+
        std::string description () const;
-       std::string internal_name () const {
-               return _internal_name;
+
+       std::string device () const {
+               return _device;
        }
+
        bool mounted () const {
-               return _mounted;
+               return !_mount_points.empty();
        }
 
+       std::string log_summary () const;
+
+       /** Unmount any mounted partitions on a drive.
+        *  @return true on success, false on failure.
+        */
+       bool unmount ();
+
+       static std::vector<Drive> get ();
+
 private:
-       std::string _internal_name;
+       std::string _device;
+       std::vector<boost::filesystem::path> _mount_points;
        /** size in bytes */
        uint64_t _size;
-       bool _mounted;
        boost::optional<std::string> _vendor;
        boost::optional<std::string> _model;
 };
 
-std::vector<Drive> get_drives ();
-/** Unmount any mounted partitions on a drive.
- *  @return true on success, false on failure.
- */
-bool unmount_drive (std::string drive);
-
 #endif
index 10ffb0677bf48060610a8e31122576e2087848c5..07e37343628214c7a04a5430e5b2b25bbe084f86 100644 (file)
 
 #include "cross.h"
 #include "compose.hpp"
+#include "dcpomatic_log.h"
+#include <dcp/raw_convert.h>
+#include <boost/foreach.hpp>
+#include <libxml++/libxml++.h>
+#include <iostream>
 
 #include "i18n.h"
 
 using std::string;
 
+Drive::Drive (string xml)
+{
+       cxml::Document doc;
+       doc.read_string (xml);
+       _device = doc.string_child("Device");
+       BOOST_FOREACH (cxml::ConstNodePtr i, doc.node_children("MountPoint")) {
+               _mount_points.push_back (i->content());
+       }
+       _size = doc.number_child<uint64_t>("Size");
+       _vendor = doc.optional_string_child("Vendor");
+       _model = doc.optional_string_child("Model");
+}
+
+
+string
+Drive::as_xml () const
+{
+       xmlpp::Document doc;
+       xmlpp::Element* root = doc.create_root_node ("Drive");
+       root->add_child("Device")->add_child_text(_device);
+       BOOST_FOREACH (boost::filesystem::path i, _mount_points) {
+               root->add_child("MountPoint")->add_child_text(i.string());
+       }
+       root->add_child("Size")->add_child_text(dcp::raw_convert<string>(_size));
+       if (_vendor) {
+               root->add_child("Vendor")->add_child_text(*_vendor);
+       }
+       if (_model) {
+               root->add_child("Model")->add_child_text(*_model);
+       }
+
+       std::cout << "xml is " << doc.write_to_string("UTF-8") << "\n";
+       return doc.write_to_string("UTF-8");
+}
+
+
 string
 Drive::description () const
 {
@@ -46,6 +87,24 @@ Drive::description () const
                name = _("Unknown");
        }
 
-       return String::compose(_("%1 (%2 GB) [%3]"), name, gb, _internal_name);
+       return String::compose(_("%1 (%2 GB) [%3]"), name, gb, _device);
 }
 
+string
+Drive::log_summary () const
+{
+       string mp;
+       BOOST_FOREACH (boost::filesystem::path i, _mount_points) {
+               mp += i.string() + ",";
+       }
+       if (mp.empty()) {
+               mp = "[none]";
+       } else {
+               mp = mp.substr (0, mp.length() - 1);
+       }
+
+       return String::compose(
+               "Device %1 mounted on %2 size %3 vendor %4 model %5",
+               _device, mp, _size, _vendor.get_value_or("[none]"), _model.get_value_or("[none]")
+                       );
+}
index 14a7e5b4748c50be8d7c8db8259fd765745aad0e..d8a33482f6b40d1cbbeb178973c94ddad617a1e5 100644 (file)
@@ -258,6 +258,8 @@ running_32_on_64 ()
        return false;
 }
 
+
+static
 vector<pair<string, string> >
 get_mounts (string prefix)
 {
@@ -278,8 +280,9 @@ get_mounts (string prefix)
        return mounts;
 }
 
+
 vector<Drive>
-get_drives ()
+Drive::get ()
 {
        vector<Drive> drives;
 
@@ -300,7 +303,6 @@ get_drives ()
                        if (size == 0) {
                                continue;
                        }
-                       bool mounted = false;
                        optional<string> vendor;
                        try {
                                vendor = dcp::file_to_string("/sys/block/" + name + "/device/vendor");
@@ -311,19 +313,35 @@ get_drives ()
                                model = dcp::file_to_string("/sys/block/" + name + "/device/model");
                                boost::trim(*model);
                        } catch (...) {}
+                       vector<boost::filesystem::path> mount_points;
                        for (vector<pair<string, string> >::const_iterator j = mounted_devices.begin(); j != mounted_devices.end(); ++j) {
                                if (boost::algorithm::starts_with(j->first, "/dev/" + name)) {
-                                       mounted = true;
+                                       mount_points.push_back (j->second);
                                }
                        }
-                       drives.push_back(Drive("/dev/" + i->path().filename().string(), size, mounted, vendor, model));
-                       LOG_DISK("Block device %1 size %2 %3 vendor %4 model %5", name, size, mounted ? "mounted" : "not mounted", vendor.get_value_or("[none]"), model.get_value_or("[none]"));
+                       drives.push_back(Drive("/dev/" + name, mount_points, size, vendor, model));
+                       LOG_DISK_NC(drives.back().log_summary());
                }
        }
 
        return drives;
 }
 
+
+bool
+Drive::unmount () 
+{
+       BOOST_FOREACH (boost::filesystem::path i, _mount_points) {
+               int const r = umount(i.string().c_str());
+               LOG_DISK("Tried to unmount %1 and got %2 and %3", i.string(), r, errno);
+               if (r == -1) {
+                       return false;
+               }
+       }
+       return true;
+}
+
+
 void
 unprivileged ()
 {
@@ -354,17 +372,3 @@ config_path ()
        return p;
 }
 
-bool
-unmount_drive (string drive)
-{
-       vector<pair<string, string> > mounts = get_mounts (drive);
-       for (vector<pair<string, string> >::const_iterator i = mounts.begin(); i != mounts.end(); ++i) {
-               int const r = umount(i->second.c_str());
-               LOG_DISK("Tried to unmount %1 and got %2 and %3", i->second, r, errno);
-               if (r == -1) {
-                       return false;
-               }
-       }
-       return true;
-}
-
index 39253a76e3e0d2989c4bcc9e7f55c0793cf97bd1..9d8196374c94d9fd739a61b50524b2321e3f30e4 100644 (file)
@@ -59,7 +59,7 @@
 
 // Front-end sends:
 #define DISK_WRITER_UNMOUNT "U"
-// Internal name of the drive to write to
+// XML representation of Drive object to unmount 
 
 // Back-end responds:
 // DISK_WRITER_OK
index ba92cf94e808cbb4133fc2eadabfddecf5c655fe..3ceead860f2fd4c2f773900930310baa939c26aa 100644 (file)
@@ -178,7 +178,7 @@ private:
                        if (!_nanomsg.send(DISK_WRITER_UNMOUNT "\n", 2000)) {
                                throw CommunicationFailedError ();
                        }
-                       if (!_nanomsg.send(drive.internal_name() + "\n", 2000)) {
+                       if (!_nanomsg.send(drive.as_xml() + "\n", 2000)) {
                                throw CommunicationFailedError ();
                        }
                        optional<string> reply = _nanomsg.receive (2000);
@@ -218,7 +218,7 @@ private:
                _drive->Clear ();
                int re_select = wxNOT_FOUND;
                int j = 0;
-               _drives = get_drives ();
+               _drives = Drive::get ();
                BOOST_FOREACH (Drive i, _drives) {
                        wxString const s = std_to_wx(i.description());
                        if (s == current) {
index 5e76341ebe48559e7849893b790f1f53587ba059..4a93cba98b85ef974f6adb8c521c344740255a81 100644 (file)
@@ -403,11 +403,12 @@ try
                exit (EXIT_SUCCESS);
        } else if (*s == DISK_WRITER_UNMOUNT) {
                /* XXX: should do Linux polkit stuff here */
-               optional<string> device = nanomsg->receive (LONG_TIMEOUT);
-               if (!device) {
+               optional<string> xml_head = nanomsg->receive (LONG_TIMEOUT);
+               optional<string> xml_body = nanomsg->receive (LONG_TIMEOUT);
+               if (!xml_head || !xml_body) {
                        throw CommunicationFailedError ();
                }
-               if (unmount_drive(*device)) {
+               if (Drive(*xml_head + *xml_body).unmount()) {
                        if (!nanomsg->send (DISK_WRITER_OK "\n", LONG_TIMEOUT)) {
                                throw CommunicationFailedError();
                        }
@@ -449,8 +450,8 @@ try
 
                bool on_drive_list = false;
                bool mounted = false;
-               for (auto const& i: get_drives()) {
-                       if (i.internal_name() == *device) {
+               for (auto const& i: Drive::get()) {
+                       if (i.device() == *device) {
                                on_drive_list = true;
                                mounted = i.mounted();
                        }