Create fixed-size subsessions via template copy 52/322852/4
authorMichal Bloch <m.bloch@samsung.com>
Thu, 22 May 2025 18:07:51 +0000 (20:07 +0200)
committerMichal Bloch <m.bloch@samsung.com>
Wed, 28 May 2025 15:37:40 +0000 (17:37 +0200)
Regular dirs added in the next commit.

Change-Id: I2b859f71174c690fa2c1658f2986fad60dd803e9

src/service/src/dir_backend.hpp
src/service/src/dir_backend_fixed_size.cpp
src/service/src/dir_backend_fixed_size.hpp
src/service/src/dir_backend_regular_dir.cpp
src/service/src/dir_backend_regular_dir.hpp
src/service/src/fs_helpers.cpp

index b451c2c0ce527ac7f80b118bfc2ca289e4499ac5..ef4f8c1928b1605b88bad8c8ff797898ac325b4e 100644 (file)
@@ -13,6 +13,7 @@ struct DirBackend {
 
 struct DirBackendAdd {
        virtual fs::path AddSubsessionPrepare (const fs::path& subsession_path, int uid, int gid) const = 0;
+       virtual bool AddSubsessionPrepareFromTemplate (const std::string_view subsession_name, const fs::path& main_path, int uid, int gid) const = 0;
        virtual void AddSubsessionFinalize (const fs::path& tmpdir_path, const fs::path& subsession_path, int uid, int gid) const = 0;
        virtual void AddSubsessionCleanupFailure (const fs::path& tmpdir_path, const fs::path& subsession_path) const = 0;
        virtual std::string_view TemplateName() const = 0;
index d4d1a529f7beb526dff2fa2af48217d18e375876..7399a3323dcdcdd674b0e708682e68396cd07e3c 100644 (file)
@@ -95,6 +95,57 @@ static void umount_and_remove (const fs::path& path) try {
        throw;
 }
 
+bool DirBackendAddFixedSize::AddSubsessionPrepareFromTemplate (const std::string_view subsession_name, const fs::path& main_path, int uid, int gid) const
+{
+       if (!OS::have_resize2fs())
+               return false;
+
+       const auto template_dir = main_path / TemplateName();
+       const auto template_img = DirBackendFixedSize::GetImagePathFromSubsessionPath(template_dir);
+       const auto subsession_dir = main_path / subsession_name;
+       const auto subsession_img = DirBackendFixedSize::GetImagePathFromSubsessionPath(subsession_dir);
+
+       /* Unmount to make sure the image copy is in a consistent state. */
+       OS::do_umount(template_dir);
+
+       try {
+               /* Note that this could be slightly faster if we kept two copies
+                * of the template and just renamed one of them, then later after
+                * sending the "adding done" D-Bus event we would clone the other
+                * copy. However that would come with a disk usage trade-off and
+                * make for more complicated sessiond architecture. */
+               fs::copy_file(template_img, subsession_img);
+       } catch (const std::exception &ex) {
+               LOGE("Could not copy template image '%s' to '%s' for uid=%d: %s"
+                       , template_img.c_str()
+                       , subsession_img.c_str()
+                       , uid
+                       , ex.what()
+               );
+
+               OS::do_mount(template_img, template_dir);
+               throw;
+       }
+
+       OS::do_mount(template_img, template_dir);
+
+       try {
+               OS::do_resize2fs(subsession_img, size_kB);
+               OS::change_owner_and_group(subsession_img, uid, gid);
+               fs::create_directory(subsession_dir);
+       } catch (const std::exception &ex) {
+               LOGE("Could not work on image '%s' for uid=%d: %s"
+                       , subsession_img.c_str()
+                       , uid
+                       , ex.what()
+               );
+               throw;
+       }
+
+       OS::do_mount(subsession_img, subsession_dir);
+       return true;
+}
+
 void DirBackendAddFixedSize::AddSubsessionCleanupFailure (const fs::path& tmpdir_path, const fs::path& subsession_path) const
 {
        auto tmp_image_path = DirBackendFixedSize::GetImagePathFromSubsessionPath(subsession_path);
index c1a94e4c4f60dd3dccad57ca112a4ca06b02b04d..4a78aca69439521605cad53207592af37f354049 100644 (file)
@@ -17,6 +17,7 @@ struct DirBackendAddFixedSize : public DirBackendAdd {
        DirBackendAddFixedSize(uint32_t s) : size_kB(s) { }
 
        fs::path AddSubsessionPrepare (const fs::path& subsession_path, int uid, int gid) const override;
+       bool AddSubsessionPrepareFromTemplate (const std::string_view subsession_name, const fs::path& main_path, int uid, int gid) const override;
        void AddSubsessionFinalize (const fs::path& tmpdir_path, const fs::path& subsession_path, int uid, int gid) const override;
        void AddSubsessionCleanupFailure (const fs::path& tmpdir_path, const fs::path& subsession_path) const override;
        std::string_view TemplateName() const override;
index de5e971b939f21814057ff9b8ea24add85610009..baa9bc68ce55cb30c561c63383685c685aeed854 100644 (file)
@@ -53,6 +53,11 @@ void DirBackendAddRegularDir::AddSubsessionFinalize (const fs::path& tmpdir_path
        fs::rename(tmpdir_path, subsession_path);
 }
 
+bool DirBackendAddRegularDir::AddSubsessionPrepareFromTemplate (const std::string_view subsession_name, const fs::path& main_path, int uid, int gid) const
+{
+       return false; // not supported yet
+}
+
 void DirBackendAddRegularDir::AddSubsessionCleanupFailure (const fs::path& tmpdir_path, const fs::path& subsession_path) const
 {
        fs::remove_all(tmpdir_path);
index d9b0dcaa99b8eb00c129c1d8f719727b20d6bf26..e552f1e50384370c0fde14a23edf42ee041c0656 100644 (file)
@@ -10,6 +10,7 @@ struct DirBackendRegularDir : public DirBackend {
 
 struct DirBackendAddRegularDir : public DirBackendAdd {
        fs::path AddSubsessionPrepare (const fs::path& subsession_path, int uid, int gid) const override;
+       bool AddSubsessionPrepareFromTemplate (const std::string_view subsession_name, const fs::path& main_path, int uid, int gid) const override;
        void AddSubsessionFinalize (const fs::path& tmpdir_path, const fs::path& subsession_path, int uid, int gid) const override;
        void AddSubsessionCleanupFailure (const fs::path& tmpdir_path, const fs::path& subsession_path) const override;
        std::string_view TemplateName() const override;
index 13f2aa8424437271e197a527c829cbe1fcf0995b..b6d0890d6729fe0ec19c5ff73702a52fa242c358 100644 (file)
@@ -142,6 +142,20 @@ void add_user_subsession(const int session_uid, const std::string_view subsessio
                throw std::runtime_error("Couldn't add user subsession data");
        }
 
+       try {
+               const bool added_via_template = backend.AddSubsessionPrepareFromTemplate
+                       ( subsession_id
+                       , main_path
+                       , session_uid
+                       , OS::get_gid_from_name(system_share_group)
+               );
+               if (added_via_template)
+                       return;
+       }
+       catch (const std::exception &ex) {
+               LOGE("Exception while creating subsession from template [session_uid=%d subsession_id=%s]: %s", session_uid, subsession_id.data(), ex.what());
+       }
+
        add_user_subsession_inner(main_path, session_uid, subsession_id, backend, false);
 }