};
struct DirBackendAdd {
- virtual fs::path AddSubsessionPrepare (const fs::path& subsession_path, int uid, int gid) const = 0;
+ virtual fs::path AddSubsessionPrepare (const fs::path& subsession_path, int uid, int gid) const = 0;
+ virtual fs::path AddSubsessionPrepareFromTemplate (const fs::path& subsession_path, const fs::path& main_path) 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;
};
return subsession_path;
}
-fs::path DirBackendAddFixedSize::AddSubsessionPrepareFromTemplate (const fs::path& subsession_path, const fs::path& main_path, int uid, int gid) const
+fs::path DirBackendAddFixedSize::AddSubsessionPrepareFromTemplate (const fs::path& subsession_path, const fs::path& main_path) const
{
fs::path template_path = main_path / ".template";
- fs::copy(GetImagePathFromSubsessionPath(subsession_path), GetImagePathFromSubsessionPath(template_path));
- do_resizefs(GetImagePathFromSubsessionPath(subsession_path);
+
+ auto tmp_subsession_path = subsession_path;
+ tmp_subsession_path.replace_filename(TMP_NEW_PREFIX + subsession_path.filename().native());
+
+ fs::copy_file (DirBackendFixedSize::GetImagePathFromSubsessionPath(subsession_path),
+ DirBackendFixedSize::GetImagePathFromSubsessionPath(template_path));
+ do_resize2fs (DirBackendFixedSize::GetImagePathFromSubsessionPath(tmp_subsession_path), size_kB);
+
+ return tmp_subsession_path;
}
fs::path DirBackendAddFixedSize::AddSubsessionPrepare (const fs::path& subsession_path, int uid, int gid) const
DirBackendAddFixedSize(uint32_t s) : size_kB(s) { }
fs::path AddSubsessionPrepare (const fs::path& subsession_path, int uid, int gid) const override;
+ fs::path AddSubsessionPrepareFromTemplate (const fs::path& subsession_path, const fs::path& main_path) 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;
};
using namespace std::string_literals;
+fs::path DirBackendAddRegularDir::AddSubsessionPrepareFromTemplate (const fs::path& subsession_path, const fs::path &main_path) const
+{
+ throw std::runtime_error("not supported");
+}
+
fs::path DirBackendAddRegularDir::AddSubsessionPrepare (const fs::path& subsession_path, int uid, int gid) const
{
auto tmp_subsession_path = subsession_path;
struct DirBackendAddRegularDir : public DirBackendAdd {
fs::path AddSubsessionPrepare (const fs::path& subsession_path, int uid, int gid) const override;
+ fs::path AddSubsessionPrepareFromTemplate (const fs::path& subsession_path, const fs::path &main_path) 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;
};
"Subsession directory already exists");
const int system_share_gid = OS::get_gid_from_name(system_share_group);
-
- // Work off a temporary dir and then switch it at once so that it appears atomically
const auto tmp_subsession_path = backend.AddSubsessionPrepareFromTemplate
- ( subsession_path, main_path,
- , session_uid, system_share_gid
- );
+ ( subsession_path, main_path );
+ backend.AddSubsessionFinalize(tmp_subsession_path, subsession_path, session_uid, system_share_gid);
+
}
- catch (std::exception const &ex) {
- LOGE("Exception while creating user subsession data [session_uid=%d subsession_id=%s]: %s", session_uid, subsession_id.data(), ex.what());
- throw std::runtime_error("Couldn't add user subsession data");
+ catch (const std::exception &ex) {
+ LOGE("Logic exception while copying skel from template [session_uid=%d subsession_id=%s]: %s", session_uid, subsession_id.data(), ex.what());
+ return add_user_subsession_inner(session_uid, subsession_id, backend);
}
}
-void add_user_subsession_internal(const int session_uid, const std::string_view subsession_id, const DirBackendAdd &backend)
+void add_user_subsession_inner(const int session_uid, const std::string_view subsession_id, const DirBackendAdd &backend)
{
try {
fs::path main_path = get_main_dir_by_user_id(session_uid);
throw std::runtime_error("Couldn't enumerate user subsessions");
}
-void do_resizefs(const fs::path& image_path, uint64_t size_kB)
+void do_resize2fs(const fs::path& image_path, uint64_t size_kB)
{
const auto child_pid = OS::throwing_fork();
if (child_pid == 0) {
std::filesystem::path get_last_subsession_path_by_user_id(const int uid);
bool subsession_exists(const int session_uid, const std::string_view subsession_id);
void add_user_subsession(const int session_uid, const std::string_view subsession_id, const DirBackendAdd& backend);
+void add_user_subsession_inner(const int session_uid, const std::string_view subsession_id, const DirBackendAdd& backend);
void remove_user_subsession(const int session_uid, const std::string_view subsession_id);
bool switch_user_subsession(const int session_uid, const std::string_view prev_subsession, const std::string_view next_subsession);
std::vector<std::string> get_user_list(const int session_uid);