Browse Source

daemon: add new pidfd based D-Bus API

Provide a new set of APIs with identical semantics as the existing
ByPID family of calls but instead of working with process ids, they
take pidfds, file descriptors representing processes, instead. The
fds can be translated back to pids (in the correct namespace) and
also be monitored via select/poll/epoll.
The current implementation translates them directly back to pids,
but in the future the monitoring code that watches processes (if
they are still alive) could be converted be event driven via pidfds.
Christian Kellner 5 years ago
parent
commit
a6552044cd
1 changed files with 86 additions and 0 deletions
  1. 86 0
      daemon/gamemode-dbus.c

+ 86 - 0
daemon/gamemode-dbus.c

@@ -32,7 +32,9 @@ POSSIBILITY OF SUCH DAMAGE.
 #define _GNU_SOURCE
 
 #include "gamemode.h"
+#include "common-helpers.h"
 #include "common-logging.h"
+#include "common-pidfds.h"
 
 #include <systemd/sd-bus.h>
 #include <systemd/sd-daemon.h>
@@ -189,6 +191,84 @@ static int method_query_status_by_pid(sd_bus_message *m, void *userdata,
 	return sd_bus_reply_method_return(m, "i", status);
 }
 
+/**
+ * Handles the RegisterGameByPIDFd D-BUS Method
+ */
+static int method_register_game_by_pidfd(sd_bus_message *m, void *userdata,
+                                         __attribute__((unused)) sd_bus_error *ret_error)
+{
+	int fds[2] = { -1, -1 };
+	pid_t pids[2] = { 0, 0 };
+	GameModeContext *context = userdata;
+
+	int ret = sd_bus_message_read(m, "hh", &fds[0], &fds[1]);
+	if (ret < 0) {
+		LOG_ERROR("Failed to parse input parameters: %s\n", strerror(-ret));
+		return ret;
+	}
+
+	int reply = pidfds_to_pids(fds, pids, 2);
+
+	if (reply == 2)
+		reply = game_mode_context_register(context, pids[0], pids[1]);
+	else
+		reply = -1;
+
+	return sd_bus_reply_method_return(m, "i", reply);
+}
+
+/**
+ * Handles the UnregisterGameByPIDFd D-BUS Method
+ */
+static int method_unregister_game_by_pidfd(sd_bus_message *m, void *userdata,
+                                           __attribute__((unused)) sd_bus_error *ret_error)
+{
+	int fds[2] = { -1, -1 };
+	pid_t pids[2] = { 0, 0 };
+	GameModeContext *context = userdata;
+
+	int ret = sd_bus_message_read(m, "hh", &fds[0], &fds[1]);
+	if (ret < 0) {
+		LOG_ERROR("Failed to parse input parameters: %s\n", strerror(-ret));
+		return ret;
+	}
+
+	int reply = pidfds_to_pids(fds, pids, 2);
+
+	if (reply == 2)
+		reply = game_mode_context_unregister(context, pids[0], pids[1]);
+	else
+		reply = -1;
+
+	return sd_bus_reply_method_return(m, "i", reply);
+}
+
+/**
+ * Handles the QueryStatusByPIDFd D-BUS Method
+ */
+static int method_query_status_by_pidfd(sd_bus_message *m, void *userdata,
+                                        __attribute__((unused)) sd_bus_error *ret_error)
+{
+	int fds[2] = { -1, -1 };
+	pid_t pids[2] = { 0, 0 };
+	GameModeContext *context = userdata;
+
+	int ret = sd_bus_message_read(m, "hh", &fds[0], &fds[1]);
+	if (ret < 0) {
+		LOG_ERROR("Failed to parse input parameters: %s\n", strerror(-ret));
+		return ret;
+	}
+
+	int reply = pidfds_to_pids(fds, pids, 2);
+
+	if (reply == 2)
+		reply = game_mode_context_query_status(context, pids[0], pids[1]);
+	else
+		reply = -1;
+
+	return sd_bus_reply_method_return(m, "i", reply);
+}
+
 /**
  * Handles the ClientCount D-BUS Property
  */
@@ -323,6 +403,12 @@ static const sd_bus_vtable gamemode_vtable[] = {
 	              SD_BUS_VTABLE_UNPRIVILEGED),
 	SD_BUS_METHOD("QueryStatusByPID", "ii", "i", method_query_status_by_pid,
 	              SD_BUS_VTABLE_UNPRIVILEGED),
+	SD_BUS_METHOD("RegisterGameByPIDFd", "hh", "i", method_register_game_by_pidfd,
+	              SD_BUS_VTABLE_UNPRIVILEGED),
+	SD_BUS_METHOD("UnregisterGameByPIDFd", "hh", "i", method_unregister_game_by_pidfd,
+	              SD_BUS_VTABLE_UNPRIVILEGED),
+	SD_BUS_METHOD("QueryStatusByPIDFd", "hh", "i", method_query_status_by_pidfd,
+	              SD_BUS_VTABLE_UNPRIVILEGED),
 	SD_BUS_METHOD("RefreshConfig", "", "i", method_refresh_config, SD_BUS_VTABLE_UNPRIVILEGED),
 	SD_BUS_METHOD("ListGames", "", "a(io)", method_list_games, SD_BUS_VTABLE_UNPRIVILEGED),