From 9d7220368761447c54a157b2f7e1b00fbca3316d Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Sun, 12 May 2019 16:06:02 -0700 Subject: [PATCH] sysprofd: add API to get a FD for a file in proc This is useful for optimized parsing of proc files such as necessary by the memory source to seek() back to the start (instead of re-opening a new file). --- src/helpers.c | 20 ++++++++++++ src/helpers.h | 2 ++ src/libsysprof/sysprof-helpers.c | 50 ++++++++++++++++++++++++++++++ src/libsysprof/sysprof-helpers.h | 5 +++ src/org.gnome.Sysprof3.Service.xml | 20 +++++++++++- src/sysprofd/ipc-service-impl.c | 46 +++++++++++++++++++++++++++ 6 files changed, 142 insertions(+), 1 deletion(-) diff --git a/src/helpers.c b/src/helpers.c index b8064662..ebba6851 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -22,6 +22,7 @@ #include "config.h" +#include #include #include #ifdef __linux__ @@ -281,6 +282,25 @@ helpers_get_proc_file (const gchar *path, g_file_get_contents (canon, contents, len, NULL); } +gboolean +helpers_get_proc_fd (const gchar *path, + gint *out_fd) +{ + g_autofree gchar *canon = NULL; + g_autoptr(GFile) file = NULL; + + g_assert (path != NULL); + g_assert (out_fd != NULL); + + /* Canonicalize filename */ + file = g_file_new_for_path (path); + canon = g_file_get_path (file); + + return g_file_is_native (file) && + (g_str_has_prefix (canon, "/proc/") || g_str_has_prefix (canon, "/sys/")) && + -1 != (*out_fd = open (canon, O_RDONLY | O_CLOEXEC)); +} + gboolean helpers_can_see_pids (void) { diff --git a/src/helpers.h b/src/helpers.h index 430a4e2b..212106b7 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -39,5 +39,7 @@ gboolean helpers_perf_event_open (GVariant *options, gboolean helpers_get_proc_file (const gchar *path, gchar **contents, gsize *len); +gboolean helpers_get_proc_fd (const gchar *path, + gint *out_fd); G_END_DECLS diff --git a/src/libsysprof/sysprof-helpers.c b/src/libsysprof/sysprof-helpers.c index f02c63ed..d5772867 100644 --- a/src/libsysprof/sysprof-helpers.c +++ b/src/libsysprof/sysprof-helpers.c @@ -229,6 +229,56 @@ sysprof_helpers_list_processes_finish (SysprofHelpers *self, return FALSE; } +gboolean +sysprof_helpers_get_proc_fd (SysprofHelpers *self, + const gchar *path, + GCancellable *cancellable, + gint *out_fd, + GError **error) +{ + g_return_val_if_fail (SYSPROF_IS_HELPERS (self), FALSE); + g_return_val_if_fail (path != NULL, FALSE); + g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE); + g_return_val_if_fail (out_fd != NULL, FALSE); + + *out_fd = -1; + + if (self->proxy != NULL) + { + g_autoptr(GVariant) reply = NULL; + g_autoptr(GUnixFDList) out_fd_list = NULL; + + reply = g_dbus_proxy_call_with_unix_fd_list_sync (G_DBUS_PROXY (self->proxy), + "GetProcFd", + g_variant_new ("(^ay)", path), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, + NULL, + &out_fd_list, + cancellable, + error); + + if (reply != NULL && out_fd_list != NULL) + { + gint handle = -1; + + g_variant_get (reply, "(h)", &handle); + + if (handle < g_unix_fd_list_get_length (out_fd_list)) + { + *out_fd = g_unix_fd_list_get (out_fd_list, handle, error); + return *out_fd != -1; + } + } + } + + if (!helpers_get_proc_fd (path, out_fd)) + return FALSE; + + g_clear_error (error); + return TRUE; +} + static void sysprof_helpers_get_proc_file_cb (IpcService *service, GAsyncResult *result, diff --git a/src/libsysprof/sysprof-helpers.h b/src/libsysprof/sysprof-helpers.h index 517ba49a..99aae855 100644 --- a/src/libsysprof/sysprof-helpers.h +++ b/src/libsysprof/sysprof-helpers.h @@ -54,6 +54,11 @@ gboolean sysprof_helpers_list_processes_finish (SysprofHelpers gint32 **processes, gsize *n_processes, GError **error); +gboolean sysprof_helpers_get_proc_fd (SysprofHelpers *self, + const gchar *path, + GCancellable *cancellable, + gint *out_fd, + GError **error); gboolean sysprof_helpers_get_proc_file (SysprofHelpers *self, const gchar *path, GCancellable *cancellable, diff --git a/src/org.gnome.Sysprof3.Service.xml b/src/org.gnome.Sysprof3.Service.xml index d39f68c2..fad593a3 100644 --- a/src/org.gnome.Sysprof3.Service.xml +++ b/src/org.gnome.Sysprof3.Service.xml @@ -27,7 +27,7 @@ GetProcFile: @path: the path including "/proc/" prefix. - Gets a file from /proc. + Gets a file from /proc/ or /sys/. The file must be a C-string (no embedded NUL bytes) but need not be UTF-8. @@ -40,6 +40,24 @@ + + + + + +