Extract some functions 65/325265/1
authorMichal Bloch <m.bloch@samsung.com>
Wed, 4 Jun 2025 17:34:51 +0000 (19:34 +0200)
committerMichal Bloch <m.bloch@samsung.com>
Thu, 5 Jun 2025 14:08:53 +0000 (16:08 +0200)
For easy replacement.

Change-Id: Ic1437fe0d2cb8b8a6c25b7442a295f27676b2e88

src/service/src/main_context.hpp
src/service/src/main_restore.cpp
src/service/src/os_ops.cpp
src/service/src/os_ops.hpp

index e67d510a0139fece781e43346078829c6cb32c75..a9a711cb1ec18d7120498429ebecb06631090a39 100644 (file)
@@ -154,6 +154,17 @@ struct sessiond_context {
                throw std::runtime_error("Bus name lost");
        }
 
+       void save_last_subsession(int uid, std::string_view subsession)
+       {
+               last_subsession_per_session[uid] = subsession;
+
+               try {
+                       std::ofstream(get_last_subsession_path_by_user_id(uid), std::ios::out | std::ios::trunc) << subsession;
+               } catch (const std::exception &ex) {
+                       LOGE("Count not save last subsession for user %d", uid);
+               }
+       }
+
        bool is_subsession_currently_active(int session_uid, const std::string_view subsession_id)
        {
                std::string_view current_subsession_id = SUBSESSION_INITIAL_SID;
@@ -242,13 +253,7 @@ struct sessiond_context {
                if (!switch_user_subsession(session_uid, prev_subsession_id, next_subsession_id))
                        return false;
 
-               last_subsession_per_session[session_uid] = next_subsession_id;
-
-               try {
-                       std::ofstream(get_last_subsession_path_by_user_id(session_uid), std::ios::out | std::ios::trunc) << next_subsession_id;
-               } catch (const std::exception &ex) {
-                       LOGE("Count not save last subsession for user %d", session_uid);
-               }
+               save_last_subsession(session_uid, next_subsession_id);
 
                wait_switch.try_emplace(session_uid, session_uid, connection, "SwitchUserCompleted");
                wait_switch.at(session_uid).on_start(switch_id, { std::string(prev_subsession_id), next_subsession_id });
index b6705266d26d63a39cab21830cc7491682dc137d..526cd2afc1f4b4da414585a41e0d22cb7b78f7aa 100644 (file)
@@ -78,11 +78,18 @@ static void restoration_unlock(int fd)
        close(fd);
 }
 
+static std::string get_last_subsession_of_user(int uid)
+{
+       std::string last_subsession;
+       std::ifstream(get_last_subsession_path_by_user_id(uid), std::ios::in) >> last_subsession;
+       return last_subsession;
+}
+
 static void restore_user_session(const fs::path& username, int uid)
 {
        std::string last_subsession;
        try {
-               std::ifstream(get_last_subsession_path_by_user_id(uid), std::ios::in) >> last_subsession;
+               last_subsession = get_last_subsession_of_user(uid);
        } catch (const std::exception &ex) {
                LOGE("Could not retrieve last subsession of user %s (uid %d): %s", username.c_str(), uid, ex.what());
 
@@ -111,7 +118,7 @@ static void restore_user_session(const fs::path& username, int uid)
        try {
                switch_user_subsession(uid, SUBSESSION_INITIAL_SID, last_subsession);
                if (g_sessiond_context)
-                       g_sessiond_context->last_subsession_per_session[uid] = last_subsession;
+                       g_sessiond_context->save_last_subsession(uid, last_subsession);
        } catch (const std::exception &ex) {
                LOGE("Could not switch to last subsession %s of user %s (uid %d)", last_subsession.c_str(), username.c_str(), uid);
        }
@@ -160,29 +167,19 @@ static void regenerate_template_sessions(int uid) try
        LOGW("Exception while regenerating template subsessions for uid %d: %s", uid, ex.what());
 }
 
+static std::vector <std::pair <int, std::string>> get_restorable_users()
+{
+       /* TODO: skip users such as `root` or `guest`. */
+       return OS::get_all_users();
+}
+
 void restore_all_user_sessions(bool restore_only)
 {
        /* In theory this should live among OS or FS helpers, but
         * this happens at early boot so we care about performance
         * enough to skip abstractions and do things directly. */
 
-       for (auto const& entry : fs::directory_iterator("/opt/usr/home")) {
-               if (!fs::is_directory(entry.status()))
-                       continue;
-
-               const auto& username = entry.path().filename();
-               int uid;
-               try {
-                       /* This has to be under a try clause because user
-                        * name doesn't necessarily map to an existing UID,
-                        * this can happen e.g. when you install debug rpm
-                        * packages which leaves some build artifacts under
-                        * the `abuild` folder which isn't a user on target. */
-                       uid = OS::get_uid_from_name(username.native());
-               } catch (const std::exception &ex) {
-                       LOGW("Could not get uid of user '%s', skipping", username.c_str());
-                       continue;
-               }
+       for (auto const& [uid, username] : get_restorable_users()) {
 
                /* We rely on all image-based subsessions being mounted to
                 * make sure that external updates (e.g. when packages are
@@ -206,19 +203,7 @@ void restore_all_user_sessions(bool restore_only)
 
 void regenerate_all_user_templates(void)
 {
-       for (auto const& entry : fs::directory_iterator("/opt/usr/home")) {
-               if (!fs::is_directory(entry.status()))
-                       continue;
-
-               const auto& username = entry.path().filename();
-               int uid;
-               try {
-                       uid = OS::get_uid_from_name(username.native());
-               } catch (const std::exception &ex) {
-                       LOGW("Could not get uid of user '%s', skipping", username.c_str());
-                       continue;
-               }
-
+       for (auto const& [uid, username] : get_restorable_users()) {
                LOGI("Regenerating template sessions for user %s (uid %d)", username.c_str(), uid);
                regenerate_template_sessions(uid);
        }
index 5f0f6aee9c722036deba9c1382032f513f4a9761..b214b4ec34c185787bcff8791217243a51e13ecf 100644 (file)
@@ -284,6 +284,42 @@ void OS::throw_if_child_failed(int child_pid, std::string_view message_on_fail)
                throw std::runtime_error (std::string(message_on_fail));
 }
 
+// not quite the same as "all users", just entries in /home/, but sufficient for us
+static std::vector <std::string> get_all_homies()
+{
+       std::vector <std::string> ret;
+
+       for (auto const& entry : fs::directory_iterator("/opt/usr/home")) {
+               if (!fs::is_directory(entry.status()))
+                       continue;
+
+               ret.emplace_back(entry.path().filename().native());
+       }
+
+       return ret;
+}
+
+std::vector <std::pair <int, std::string>> OS::get_all_users()
+{
+       std::vector <std::pair <int, std::string>> ret;
+
+       for (auto homies = get_all_homies(); auto &homie : homies) {
+               try {
+                       /* This has to be under a try clause because /home/
+                        * entries don't necessarily map to an existing UID,
+                        * this can happen e.g. when you install debug rpm
+                        * packages which leaves some build artifacts under
+                        * the `abuild` folder which isn't a user on target. */
+                       const int uid = OS::get_uid_from_name(homie);
+                       ret.emplace_back(uid, std::move(homie));
+               } catch (const std::exception &ex) {
+                       LOGW("Could not get uid of user '%s', skipping", homie.c_str());
+               }
+       }
+
+       return ret;
+}
+
 std::string OS::get_home_dir_by_user_id(const int uid)
 {
        auto buffer = allocate_sysconf_buffer(_SC_GETPW_R_SIZE_MAX);
index e40f547a427f71afc3cea3ddbe5ca764f3b0134a..8dc0088738e6474b709cd2e352095c500b64edb7 100644 (file)
@@ -6,6 +6,8 @@
 #include <filesystem>
 #include <string>
 #include <string_view>
+#include <utility>
+#include <vector>
 
 namespace fs = std::filesystem;
 
@@ -30,6 +32,8 @@ namespace OS {
 
        void throw_if_child_failed(int child_pid, std::string_view message_on_fail);
 
+       std::vector <std::pair <int, std::string>> get_all_users();
+
        std::string get_home_dir_by_user_id(const int uid);
 
        int get_gid_from_name(std::string_view group_name);