sysprof/0021-sysprof-user-sampler-implement-await-for-FDs.patch
Christian Hergert 3869a62c8e Backport debuginfod and sysprof-live-unwinder
Resolves: RHEL-65743
2024-11-06 15:10:06 -08:00

228 lines
6.7 KiB
Diff

From 781d438e5e3d4189d8a1970707983ccc6897175c Mon Sep 17 00:00:00 2001
From: Christian Hergert <chergert@redhat.com>
Date: Wed, 6 Nov 2024 15:09:13 -0800
Subject: [PATCH] sysprof-user-sampler: implement await for FDs
This allows us to not need libdex 0.9+ for use by the sampler.
---
src/libsysprof/meson.build | 1 +
src/libsysprof/sysprof-fd-private.h | 39 ++++++++++++++++
src/libsysprof/sysprof-fd.c | 67 +++++++++++++++++++++++++++
src/libsysprof/sysprof-user-sampler.c | 33 +++++++++++--
4 files changed, 136 insertions(+), 4 deletions(-)
create mode 100644 src/libsysprof/sysprof-fd-private.h
create mode 100644 src/libsysprof/sysprof-fd.c
diff --git a/src/libsysprof/meson.build b/src/libsysprof/meson.build
index e49c3a37..2ae977ca 100644
--- a/src/libsysprof/meson.build
+++ b/src/libsysprof/meson.build
@@ -144,6 +144,7 @@ libsysprof_private_sources = [
'sysprof-document-symbols.c',
'sysprof-elf-loader.c',
'sysprof-elf.c',
+ 'sysprof-fd.c',
'sysprof-leak-detector.c',
'sysprof-maps-parser.c',
'sysprof-mount-device.c',
diff --git a/src/libsysprof/sysprof-fd-private.h b/src/libsysprof/sysprof-fd-private.h
new file mode 100644
index 00000000..1d4dfabc
--- /dev/null
+++ b/src/libsysprof/sysprof-fd-private.h
@@ -0,0 +1,39 @@
+/* sysprof-fd-private.h
+ *
+ * Copyright 2024 Christian Hergert <chergert@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#pragma once
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define SYSPROF_TYPE_FD (sysprof_fd_get_type())
+
+typedef struct _SysprofFD SysprofFD;
+
+GType sysprof_fd_get_type (void) G_GNUC_CONST;
+int sysprof_fd_peek (const SysprofFD *fd);
+int sysprof_fd_steal (SysprofFD *fd);
+SysprofFD *sysprof_fd_dup (const SysprofFD *fd);
+void sysprof_fd_free (SysprofFD *fd);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (SysprofFD, sysprof_fd_free)
+
+G_END_DECLS
diff --git a/src/libsysprof/sysprof-fd.c b/src/libsysprof/sysprof-fd.c
new file mode 100644
index 00000000..5e34f8d9
--- /dev/null
+++ b/src/libsysprof/sysprof-fd.c
@@ -0,0 +1,67 @@
+/* sysprof-fd.c
+ *
+ * Copyright 2024 Christian Hergert <chergert@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "config.h"
+
+#include <unistd.h>
+
+#include "sysprof-fd-private.h"
+
+int
+sysprof_fd_peek (const SysprofFD *fd)
+{
+ if (fd == NULL)
+ return -1;
+
+ return *(int *)fd;
+}
+
+int
+sysprof_fd_steal (SysprofFD *fd)
+{
+ if (fd == NULL)
+ return -1;
+
+ return g_steal_fd ((int *)fd);
+}
+
+void
+sysprof_fd_free (SysprofFD *fd)
+{
+ int real = sysprof_fd_steal (fd);
+ if (real != -1)
+ close (real);
+ g_free (fd);
+}
+
+SysprofFD *
+sysprof_fd_dup (const SysprofFD *fd)
+{
+ int real = sysprof_fd_peek (fd);
+
+ if (real == -1)
+ return NULL;
+
+ real = dup (real);
+
+ return g_memdup2 (&real, sizeof real);
+}
+
+G_DEFINE_BOXED_TYPE (SysprofFD, sysprof_fd, sysprof_fd_dup, sysprof_fd_free)
diff --git a/src/libsysprof/sysprof-user-sampler.c b/src/libsysprof/sysprof-user-sampler.c
index 0e3afeae..1ae3ea27 100644
--- a/src/libsysprof/sysprof-user-sampler.c
+++ b/src/libsysprof/sysprof-user-sampler.c
@@ -32,6 +32,7 @@
#include "sysprof-recording-private.h"
#include "sysprof-user-sampler.h"
#include "sysprof-muxer-source.h"
+#include "sysprof-fd-private.h"
#include "ipc-unwinder.h"
@@ -81,6 +82,30 @@ close_fd (gpointer data)
}
}
+static void
+promise_resolve_fd (DexPromise *promise,
+ int fd)
+{
+ GValue gvalue = {SYSPROF_TYPE_FD, {{.v_pointer = &fd}, {.v_int = 0}}};
+ dex_promise_resolve (promise, &gvalue);
+}
+
+static int
+await_fd (DexFuture *future,
+ GError **error)
+{
+ SysprofFD *fd = dex_await_boxed (future, error);
+ int ret = -1;
+
+ if (fd != NULL)
+ {
+ ret = sysprof_fd_steal (fd);
+ sysprof_fd_free (fd);
+ }
+
+ return ret;
+}
+
static void
sysprof_user_sampler_ioctl (SysprofUserSampler *self,
gboolean enable)
@@ -145,7 +170,7 @@ _perf_event_open_cb (GObject *object,
if (-1 == (fd = g_unix_fd_list_get (fd_list, handle, &error)))
goto failure;
- dex_promise_resolve_fd (promise, g_steal_fd (&fd));
+ promise_resolve_fd (promise, g_steal_fd (&fd));
return;
}
@@ -230,7 +255,7 @@ try_again:
_perf_event_open_cb,
dex_ref (promise));
- if (-1 == (perf_fd = dex_await_fd (dex_ref (promise), error)))
+ if (-1 == (perf_fd = await_fd (dex_ref (promise), error)))
{
g_clear_pointer (&options, g_variant_unref);
@@ -270,7 +295,7 @@ call_unwind_cb (GObject *object,
if (ipc_unwinder_call_unwind_finish (IPC_UNWINDER (object), &out_capture_fd, &out_fd_list, result, &error) &&
-1 != (capture_fd = g_unix_fd_list_get (out_fd_list, g_variant_get_handle (out_capture_fd), &error)))
- dex_promise_resolve_fd (promise, g_steal_fd (&capture_fd));
+ promise_resolve_fd (promise, g_steal_fd (&capture_fd));
else
dex_promise_reject (promise, error);
}
@@ -402,7 +427,7 @@ sysprof_user_sampler_prepare_fiber (gpointer user_data)
call_unwind_cb,
dex_ref (promise));
- fd = dex_await_fd (dex_ref (promise), &error);
+ fd = await_fd (dex_ref (promise), &error);
if (fd == -1)
{
--
2.45.2