Add support for requesting cache regeneration sandbox/klewandowski/generate-skel4
authorKarol Lewandowski <k.lewandowsk@samsung.com>
Wed, 21 May 2025 11:25:33 +0000 (13:25 +0200)
committerKarol Lewandowski <k.lewandowsk@samsung.com>
Wed, 21 May 2025 11:36:29 +0000 (13:36 +0200)
This commit adds external interface for /etc/skel cache regeneration,
to be used by tpkplugin - called during tpk package (de)installation
& upgrade.

Change-Id: I3a40ac0bce2cef9ef189748252e6b80a6d6a7eb5

src/library/include/sessiond-platform.h
src/library/src/lib.c
src/service/src/main.cpp
src/service/src/main_context.hpp
src/service/src/main_skel.cpp
src/service/src/main_skel.hpp
src/tpkplugin/CMakeLists.txt
src/tpkplugin/plugin.c

index fd5c8872acecdcc411a1cebe870c826ab39e20bc..d8a7cf63f3733ff526612e8a017e0f91a0328707 100644 (file)
@@ -69,6 +69,19 @@ int subsession_register_bus_watch_callback(subsession_watch_context *ctx, subses
  */
 int subsession_unregister_bus_watch_callback(subsession_watch_context *ctx);
 
+/**
+ * @brief Request sessiond to recreate its internal cache
+ * @since_tizen 9.0
+ *
+ * @return This function does return error if it occurred
+ * @retval #SUBSESSION_ERROR_IO_ERROR Unable to regegenerate cache
+ * @remarks This function is to be used when system's /etc/skel changes.
+ *          sessiond caches it's contents to be able to perform fast user
+ *          additions.  If original filesystem changed the cache needs to
+ *          be rebuilt.  Supposed to be called from pkgmgr plugin only.
+ */
+int subsession_regenerate_cache(void);
+
 #ifdef __cplusplus
 }
 #endif
index dea0785c81b5ab04b7ff9ed95b20930738fbec0e..e47eb8e2cef1d51f8416d3d1b91cdbe9ebc98917 100644 (file)
@@ -72,6 +72,7 @@ static struct {
        gchar * GetUserList;
        gchar * SwitchUserDone;
        gchar * GetCurrentUser;
+       gchar * RegenerateCache;
 
 } dbus_method_call = {
        .AddUser = "AddUser",
@@ -84,7 +85,8 @@ static struct {
        .RemoveUserDone = "RemoveUserDone",
        .GetUserList = "GetUserList",
        .SwitchUserDone = "SwitchUserDone",
-       .GetCurrentUser = "GetCurrentUser"
+       .GetCurrentUser = "GetCurrentUser",
+       .RegenerateCache = "RegenerateCache"
 };
 
 typedef struct {
@@ -1071,3 +1073,9 @@ EXPORT_API int subsession_get_current_user(int session_uid, subsession_user_t us
 
        return SUBSESSION_ERROR_NONE;
 }
+
+// This is privileged call
+EXPORT_API int subsession_regenerate_cache(void)
+{
+       return_with_log_error_result_(method_call_async(dbus_method_call.RegenerateCache, g_variant_new("()"), NULL, NULL));
+}
index 4d3c84ed66d9721515c143b9ce0f6918043316be..f218e851ca7ba5c096e87ff08b161ca00ec92f54 100644 (file)
@@ -49,7 +49,7 @@ int main(int argc, char **argv) try {
        if (isRestoreOnly(argc, argv)) {
                restore_all_user_sessions();
        } else if (isGenSkel(argc, argv)) {
-               regenerate_skel();
+               regenerate_skel_cache();
        } else {
                g_sessiond_context = std::make_unique <sessiond_context> ();
                restore_all_user_sessions();
index 9fc05648f597b524d5646ed33fc0dd80d58719ae..3d0927f517b5ef615095c4c3acdbf87341e416de 100644 (file)
@@ -37,6 +37,7 @@
 #include "globals.hpp"
 #include "fs_helpers.hpp"
 #include "main_restore.hpp"
+#include "main_skel.hpp"
 #include "os_ops.hpp"
 #include "tuple_g_variant_helpers.hpp"
 #include "tuple_hash.hpp"
@@ -497,6 +498,19 @@ struct sessiond_context {
                g_dbus_method_invocation_return_value(invocation, ret);
        }
 
+       void on_regenerate_cache(GDBusMethodInvocation *invocation, std::string_view sender, GVariant *parameters)
+       {
+               LOGD("Regenerate Skel Cache started");
+               try {
+                       regenerate_skel_cache();
+               } catch (std::exception& ex) {
+                       g_dbus_method_invocation_return_dbus_error(invocation,
+                                                                  get_dbus_error_mapping(SUBSESSION_ERROR_IO_ERROR), ex.what());
+                       throw;
+               }
+               LOGD("Regenerate Skel Cache succesfully finished");
+       }
+
        static void glib_name_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data)
        {
                auto self = static_cast<sessiond_context *>(user_data);
@@ -610,6 +624,8 @@ struct sessiond_context {
                                        "<arg name=\"session_uid\"        type=\"i\" direction=\"in\"/>"
                                        "<arg name=\"subsession_id\"      type=\"s\" direction=\"out\"/>"
                                "</method>"
+                               "<method name=\"RegenerateCache\">"
+                               "</method>"
                                "<signal name=\"AddUserStarted\">"
                                        "<arg name=\"session_uid\"        type=\"i\" direction=\"out\"/>"
                                        "<arg name=\"subsession_id\"      type=\"s\" direction=\"out\"/>"
@@ -654,6 +670,7 @@ struct sessiond_context {
                std::make_pair(  "SwitchUserDone"sv, &sessiond_context::on_switch_user_done   ),
                std::make_pair(     "GetUserList"sv, &sessiond_context::on_get_user_list      ),
                std::make_pair(  "GetCurrentUser"sv, &sessiond_context::on_get_current_user   ),
+               std::make_pair( "RegenerateCache"sv, &sessiond_context::on_regenerate_cache   ),
        };
 
        // TODO: Currently, the first parameter is always a single-element tuple.
index d17bce2317354e8d31c9108c60f2221d00b66bac..d1a8ae97cd8b1e54704a434c20147fc1549f083b 100644 (file)
@@ -51,7 +51,7 @@ void print_creds(void)
 }
 
 
-int regenerate_skel()
+void regenerate_skel_cache(void)
 {
        print_creds();
 
@@ -78,6 +78,4 @@ int regenerate_skel()
                        continue;
                }
        }
-
-       return 0;
 }
index c38727966c076216b5cd0c276d08feff4765994e..8bdbaa961a70f9ce7f9691066afcfe78fdfc3228 100644 (file)
@@ -1,3 +1,3 @@
 #pragma once
 
-void regenerate_skel();
+void regenerate_skel_cache(void);
index eae3d9b5da21fb7796d101c77dc371e56a9f9cc3..abd39996e01545c156fad0fbb34359ce55f5e540 100644 (file)
@@ -2,6 +2,7 @@ FIND_PACKAGE(PkgConfig)
 INCLUDE(GNUInstallDirs)
 
 pkg_check_modules(deps REQUIRED
+                  IMPORTED_TARGET
                   dlog
                   capi-system-info
                   pkgmgr-info
@@ -9,7 +10,7 @@ pkg_check_modules(deps REQUIRED
 
 ADD_LIBRARY(libsessiond-update-skelimg SHARED plugin.c)
 TARGET_COMPILE_OPTIONS(libsessiond-update-skelimg PUBLIC -fPIC ${deps_CFLAGS})
-TARGET_LINK_LIBRARIES(libsessiond-update-skelimg PRIVATE ${deps_LDFLAGS})
+TARGET_LINK_LIBRARIES(libsessiond-update-skelimg PRIVATE ${deps_LDFLAGS} libsessiond)
 
 INSTALL(TARGETS libsessiond-update-skelimg LIBRARY DESTINATION /etc/package-manager/parserlib/)
 INSTALL(FILES sessiond-update-skelimg.info DESTINATION /usr/share/parser-plugins/)
index cb6cd2fb9557b7349c3dc0aa3e27d6699f3f116f..16c4809a26274631ce2f62add2ae7307b35128e8 100644 (file)
@@ -4,6 +4,8 @@
 #include <libxml/tree.h>
 #include <pkgmgr-info.h>
 #include <stdlib.h>
+#include "sessiond.h"
+#include "sessiond-platform.h"
 
 #ifndef EXPORT_API
 #define EXPORT_API __attribute__((visibility("default")))
 #define LOG_TAG "SESSIOND_GEN_SKEL_IMG"
 
 static int gen_skel(void) {
-       // The logic for skel generation is not in plugin to make it possible to call it also manually during image build
-       return system("/usr/bin/sessiond --regenerate-skel");
+       (void)subsession_regenerate_cache();
+
+       // Failure to regenerate cache should not cause package to not install
+       // NOTE: sessiond has to also depend on other mechanisms (eg. compare timestamp of cached data vs timestamp of skel to ensure data is up to date
+       return 0;
 }
 
 EXPORT_API