struct DirBackendAdd {
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 fs::path AddSubsessionPrepareFromTemplate (const fs::path& subsession_path, 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;
};
return subsession_path;
}
-fs::path DirBackendAddFixedSize::AddSubsessionPrepareFromTemplate (const fs::path& subsession_path, const fs::path& main_path) const
+fs::path DirBackendAddFixedSize::AddSubsessionPrepareFromTemplate (const fs::path& subsession_path, const fs::path& main_path, int uid, int gid) const
{
fs::path template_path = main_path / ".template";
auto tmp_subsession_path = subsession_path;
tmp_subsession_path.replace_filename(TMP_NEW_PREFIX + subsession_path.filename().native());
+ auto image_template = DirBackendFixedSize::GetImagePathFromSubsessionPath(template_path);
+ auto image_new_tmp = DirBackendFixedSize::GetImagePathFromSubsessionPath(tmp_subsession_path);
+ fs::copy_file (image_template, image_new_tmp);
+ do_resize2fs (image_new_tmp, size_kB);
- fs::copy_file (DirBackendFixedSize::GetImagePathFromSubsessionPath(template_path),
- DirBackendFixedSize::GetImagePathFromSubsessionPath(tmp_subsession_path));
+ try {
+ fs::create_directory(tmp_subsession_path);
+ OS::change_owner_and_group(tmp_subsession_path, uid, gid);
+ } catch (const std::exception& ex) {
+ fs::remove(image_new_tmp);
+ fs::remove(tmp_subsession_path);
+ throw;
+ }
- do_resize2fs (DirBackendFixedSize::GetImagePathFromSubsessionPath(tmp_subsession_path), size_kB);
+/*
+ // We do not really need to do this, frankly it will make add_user() slower and switch() later due to mount done here
+ try {
+ do_mount(image_path, tmp_subsession_path);
+ } catch (const std::exception& ex) {
+ fs::remove(tmp_subsession_path);
+ fs::remove(image_path);
+ throw;
+ }
+*/
return tmp_subsession_path;
}
try {
fs::create_directory(tmp_subsession_path);
+ OS::change_owner_and_group(tmp_subsession_path, uid, gid);
} catch (const std::exception& ex) {
fs::remove(image_path);
throw;
void DirBackendAddFixedSize::AddSubsessionFinalize (const fs::path& tmpdir_path, const fs::path& subsession_path, int uid, int gid) const
{
- umount_and_remove(tmpdir_path);
+ // XXX keep mounts! it should be possible to reuse this dir too!
+ // umount_and_remove(tmpdir_path);
const auto image_path = DirBackendFixedSize::GetImagePathFromSubsessionPath(subsession_path);
auto temp_image_path = image_path;
temp_image_path.replace_filename(TMP_NEW_PREFIX + image_path.filename().native());
+ LOGI("rename %s %s", temp_image_path.data(), image_path.data());
fs::rename(temp_image_path, image_path);
/* The image file (as opposed to the FS inside it) doesn't
/* Order matters - handle .img first and the directory last,
* since all other logic assumes that the existence of the dir
* signifies that a valid subsession exists. */
- fs::create_directory(subsession_path);
+ //fs::create_directory(subsession_path);
+ fs::rename(tmpdir_path, subsession_path);
/* The mountpoint's properties don't actually matter, since
* they are completely replaced with the image filesystem's
* root dir's, but this way they are consistent regardless of
* whether the image is mounted or not. */
- OS::change_owner_and_group(subsession_path, uid, gid);
+ // XXX moved to AddSubsessionPrepare*
+ //OS::change_owner_and_group(subsession_path, uid, gid);
}
void DirBackendFixedSize::RemoveSubsession (const fs::path& subsession_path) 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;
+ fs::path AddSubsessionPrepareFromTemplate (const fs::path& subsession_path, 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;
};
using namespace std::string_literals;
-fs::path DirBackendAddRegularDir::AddSubsessionPrepareFromTemplate (const fs::path& subsession_path, const fs::path &main_path) const
+fs::path DirBackendAddRegularDir::AddSubsessionPrepareFromTemplate (const fs::path& subsession_path, const fs::path &main_path, int uid, int gid) const
{
throw std::runtime_error("not supported");
}
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;
+ fs::path AddSubsessionPrepareFromTemplate (const fs::path& subsession_path, 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;
};
const int system_share_gid = OS::get_gid_from_name(system_share_group);
const auto tmp_subsession_path = backend.AddSubsessionPrepareFromTemplate
- ( subsession_path, main_path );
+ ( subsession_path, main_path, session_uid, system_share_gid );
backend.AddSubsessionFinalize(tmp_subsession_path, subsession_path, session_uid, system_share_gid);
}
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);
+ return add_user_subsession_inner(session_uid, subsession_id, backend, false);
}
}
-void add_user_subsession_inner(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, bool force)
{
try {
fs::path main_path = get_main_dir_by_user_id(session_uid);
fs::path subsession_path = main_path / subsession_id;
- if (fs::exists(subsession_path))
- throw std::system_error(EEXIST, std::generic_category(),
- "Subsession directory already exists");
+ if (fs::exists(subsession_path)) {
+ if (force) {
+ LOGI("Removing old subsession subsession_id=%s in force mode", subsession_id.data());
+ fs::remove_all(subsession_path);
+ } else
+ throw std::system_error(EEXIST, std::generic_category(),
+ "Subsession directory already exists");
+ }
const int system_share_gid = OS::get_gid_from_name(system_share_group);
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 add_user_subsession_inner(const int session_uid, const std::string_view subsession_id, const DirBackendAdd& backend, bool force);
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);
const int username_uid = OS::get_uid_from_name(username.string());
try {
- add_user_subsession_inner(username_uid, ".template", DirBackendAddFixedSize {template_img_size_kb});
+ add_user_subsession_inner(username_uid, ".template", DirBackendAddFixedSize {template_img_size_kb}, true);
} catch (std::exception& ex) {
LOGW("Unable to generate skel template for username %s (uid %d): %s", username, username_uid, ex.what());
continue;