Add 'AddUserFixedSize' dbus call. 56/320156/8
authorMichal Bloch <m.bloch@samsung.com>
Wed, 19 Feb 2025 16:19:34 +0000 (17:19 +0100)
committerMichal Bloch <m.bloch@samsung.com>
Thu, 27 Feb 2025 15:28:30 +0000 (16:28 +0100)
Change-Id: I29aa18dcf5812e9a0376f705c39b5483c642c8f4
Signed-off-by: Michal Bloch <m.bloch@samsung.com>
doc/sessiond-dbus-interface.md
src/library/src/lib.c
src/service/src/main.cpp
src/service/src/tuple_g_variant_helpers.hpp

index 6ffed2d41490380aa3acba7f999d71e4b0f540c0..5de6afe3459c0e399415da5752a6e8ea108e3df4 100644 (file)
@@ -97,6 +97,16 @@ In case of an error, methods return a DBus error.
             session_uid <int32> in
             subsession_id_list <array<string>> out
 
+11. Add a user to the subsession, with a fixed disk usage limit (in kB):
+
+        objpath: /org/tizen/sessiond
+        interface: org.tizen.sessiond.subsession.Manager
+        member: AddUserFixedSize
+        parameters: (isu)
+            session_uid <int32> in
+            subsession_id <string> in
+            size_kB <uint32> in
+
 # Signals
 
 1. On user add:
@@ -128,7 +138,7 @@ In case of an error, methods return a DBus error.
             prev_subsession_id <string>
             next_subsession_id <string>
 
-4. On user add completed:
+4. On user add (either regular dir or fixed size) completed:
 
         objpath: /org/tizen/sessiond
         interface: org.tizen.sessiond.subsession.Manager
index 2b002af070b0bef9b6beac0e3685ba2ab5cd478a..64ed4ad0bfef64f613e001df0e09ca3ffd585943 100644 (file)
@@ -62,6 +62,7 @@ static session_connection_data_t session_connection_data = {
                        session_connection_data.objpath
 static struct {
        gchar * AddUser;
+       gchar * AddUserFixedSize;
        gchar * RemoveUser;
        gchar * SwitchUser;
        gchar * AddUserWait;
@@ -74,6 +75,7 @@ static struct {
 
 } dbus_method_call = {
        .AddUser = "AddUser",
+       .AddUserFixedSize = "AddUserFixedSize",
        .RemoveUser = "RemoveUser",
        .SwitchUser = "SwitchUser",
        .AddUserWait = "AddUserWait",
index 9ab65ae295b33eed74b473017070424db8c000a8..f9656811ff4c26f927f1458412c58d6cbf3a99c1 100644 (file)
@@ -36,6 +36,7 @@
 #include "tuple_hash.hpp"
 #include "wait_manager.hpp"
 #include "dir_backend_regular_dir.hpp"
+#include "dir_backend_fixed_size.hpp"
 
 static constexpr const char * get_dbus_error_mapping (subsession_error_e subsession_error)
 {
@@ -53,6 +54,15 @@ static constexpr const char * get_dbus_error_mapping (subsession_error_e subsess
 
 using namespace std::string_view_literals;
 
+static bool is_subsession_size_limit_valid (unsigned size_kB)
+{
+       static constexpr int MINIMUM_FOR_EXT2_OVERHEAD = 220; // determined empirically
+       if (size_kB < MINIMUM_FOR_EXT2_OVERHEAD)
+               return false;
+
+       return true;
+}
+
 struct introspection_data {
        introspection_data(std::string_view xml)
        {
@@ -184,6 +194,31 @@ struct sessiond_context {
                g_dbus_method_invocation_return_value(invocation, nullptr);
        }
 
+       void on_add_user_fixed_size(GDBusMethodInvocation *invocation, std::string_view sender, GVariant *parameters)
+       {
+               auto [ session_uid, subsession_id, size_kB ] = tuple_from_g_variant<int, std::string, unsigned>(parameters);
+
+               if (check_parameters_invalid(invocation, session_uid, subsession_id))
+                       return;
+               if (!is_subsession_size_limit_valid(size_kB)) {
+                       g_dbus_method_invocation_return_dbus_error(invocation,
+                               get_dbus_error_mapping(SUBSESSION_ERROR_INVALID_PARAMETER), "Size too small");
+                       return;
+               }
+
+               GError *err = nullptr;
+               if (!g_dbus_connection_emit_signal(connection, nullptr, bus_object.data(), bus_iface.data(), "AddUserStarted",
+                               vals_to_g_variant(session_uid, subsession_id), &err))
+                       g_error_throw(err, "Failed to emit a signal: ");
+
+               add_user_subsession(session_uid, subsession_id, DirBackendAddFixedSize {size_kB});
+
+               wait_add.try_emplace(session_uid, session_uid, connection, "AddUserCompleted");
+               wait_add.at(session_uid).on_start(subsession_id, { });
+
+               g_dbus_method_invocation_return_value(invocation, nullptr);
+       }
+
        void on_remove_user(GDBusMethodInvocation *invocation, std::string_view sender, GVariant *parameters)
        {
                auto [ session_uid, subsession_id ] = tuple_from_g_variant<int, std::string>(parameters);
@@ -459,6 +494,11 @@ struct sessiond_context {
                                        "<arg name=\"session_uid\"        type=\"i\" direction=\"in\"/>"
                                        "<arg name=\"subsession_id\"      type=\"s\" direction=\"in\"/>"
                                "</method>"
+                               "<method name=\"AddUserFixedSize\">"
+                                       "<arg name=\"session_uid\"        type=\"i\" direction=\"in\"/>"
+                                       "<arg name=\"subsession_id\"      type=\"s\" direction=\"in\"/>"
+                                       "<arg name=\"size_kB\"            type=\"u\" direction=\"in\"/>"
+                               "</method>"
                                "<method name=\"RemoveUser\">"
                                        "<arg name=\"session_uid\"        type=\"i\" direction=\"in\"/>"
                                        "<arg name=\"subsession_id\"      type=\"s\" direction=\"in\"/>"
@@ -528,17 +568,18 @@ struct sessiond_context {
                "</node>";
 
        constexpr static std::array methods = {
-               std::make_pair(       "AddUser"sv, &sessiond_context::on_add_user        ),
-               std::make_pair(    "RemoveUser"sv, &sessiond_context::on_remove_user     ),
-               std::make_pair(    "SwitchUser"sv, &sessiond_context::on_switch_user     ),
-               std::make_pair(   "AddUserWait"sv, &sessiond_context::on_add_user_wait   ),
-               std::make_pair("RemoveUserWait"sv, &sessiond_context::on_remove_user_wait),
-               std::make_pair("SwitchUserWait"sv, &sessiond_context::on_switch_user_wait),
-               std::make_pair(   "AddUserDone"sv, &sessiond_context::on_add_user_done   ),
-               std::make_pair("RemoveUserDone"sv, &sessiond_context::on_remove_user_done),
-               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(         "AddUser"sv, &sessiond_context::on_add_user           ),
+               std::make_pair("AddUserFixedSize"sv, &sessiond_context::on_add_user_fixed_size),
+               std::make_pair(      "RemoveUser"sv, &sessiond_context::on_remove_user        ),
+               std::make_pair(      "SwitchUser"sv, &sessiond_context::on_switch_user        ),
+               std::make_pair(     "AddUserWait"sv, &sessiond_context::on_add_user_wait      ),
+               std::make_pair(  "RemoveUserWait"sv, &sessiond_context::on_remove_user_wait   ),
+               std::make_pair(  "SwitchUserWait"sv, &sessiond_context::on_switch_user_wait   ),
+               std::make_pair(     "AddUserDone"sv, &sessiond_context::on_add_user_done      ),
+               std::make_pair(  "RemoveUserDone"sv, &sessiond_context::on_remove_user_done   ),
+               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   ),
        };
 
        // TODO: Currently, the first parameter is always a single-element tuple.
index 2466ca020736f65f890c1987d8a29bf29e0152c1..eb4c52478e38fd0b3894f933326e1ff68975ad8b 100644 (file)
@@ -41,6 +41,12 @@ constexpr inline char type_of_g_variant_one<int>()
        return 'i';
 }
 
+template<>
+constexpr inline char type_of_g_variant_one<unsigned>()
+{
+       return 'u';
+}
+
 template<>
 constexpr inline char type_of_g_variant_one<uint64_t>()
 {