From 190e85aaf6cfa553ce31467a7ef57a1ae13305a5 Mon Sep 17 00:00:00 2001 From: Alexandr Ilenko Date: Mon, 20 Jun 2022 09:46:43 +0300 Subject: [PATCH 12/20] virtual-media.3: Add: "NfsShare", based on "NetDevShare" --- src/netdev.hpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/netdev.hpp b/src/netdev.hpp index 47d39a1..fc1b907 100644 --- a/src/netdev.hpp +++ b/src/netdev.hpp @@ -115,3 +115,69 @@ class SmbShare : public NetDevShare return ec; } }; + +class NfsShare final: public NetDevShare +{ + static constexpr const char* mountType = "nfs"; + public: + explicit NfsShare(const fs::path& mountDir): NetDevShare(mountDir) + { + } + + virtual const char* getMountType() const override + { + return mountType; + } + + bool mount(const fs::path& remote, bool rw, + const std::unique_ptr& credentials) override + { + LogMsg(Logger::Debug, "Trying to mount remote : ", remote); + + try { + auto mountUri = parseMountUri(remote); + const std::string params = "nolock"; + const std::string& mountAddress = mountUri.first; + const std::string& mountPath = mountUri.second; + auto options = params + ",addr=" + mountAddress; + + LogMsg(Logger::Debug, "Mounting URI: ", mountPath); + LogMsg(Logger::Debug, "With options: ", options); + + auto ec = ::mount((":" + mountPath).c_str(), mountDir.c_str(), + mountType, 0, options.c_str()); + utils::secureCleanup(options); + + if (ec) + { + LogMsg(Logger::Error, "Mount failed with ec = ", ec, + " errno = ", errno); + return false; + } + } catch (const std::exception& ex) { + + LogMsg(Logger::Error, "Mount failed: ", ex.what()); + return false; + } + return true; + } + private: + using MountAddress = std::string; + using MountPath = std::string; + + static std::pair parseMountUri(const std::string uri) + { + // All paths start with '//', so seek a cursor to the 2 positions + // forward. + constexpr unsigned char startAddressPos = 2U; + auto hostnameEndPos = uri.find('/', startAddressPos); + if (hostnameEndPos == std::string::npos) { + throw std::invalid_argument("Mount Uri"); + } + return { + uri.substr(startAddressPos, hostnameEndPos - startAddressPos), + uri.substr(hostnameEndPos), + }; + } + +}; -- 2.35.1