[sysprof] sysprofd: add API to set perf_event_paranoid



commit 667180cbc8f4f823445e0c7b7beb72d6d7d26cdc
Author: Christian Hergert <chergert redhat com>
Date:   Wed Feb 24 11:26:10 2021 -0800

    sysprofd: add API to set perf_event_paranoid
    
    This will allow us to get more information on demand when running the
    profiler without endless tweaking by end users.

 src/org.gnome.Sysprof3.Service.xml | 12 ++++++++++
 src/sysprofd/ipc-service-impl.c    | 47 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)
---
diff --git a/src/org.gnome.Sysprof3.Service.xml b/src/org.gnome.Sysprof3.Service.xml
index de325a9..0f28264 100644
--- a/src/org.gnome.Sysprof3.Service.xml
+++ b/src/org.gnome.Sysprof3.Service.xml
@@ -106,5 +106,17 @@
       <arg name="governor" type="s" direction="in"/>
       <arg name="old_governor" type="s" direction="out"/>
     </method>
+
+    <!--
+      SetParanoid:
+      @governor: the new perf paranoid setting
+      @old_governor: the old perf paranoid setting
+
+      Sets the perf_event_paranoid setting for the system.
+    -->
+    <method name="SetParanoid">
+      <arg name="paranoid" type="i" direction="in"/>
+      <arg name="old_paranoid" type="i" direction="out"/>
+    </method>
   </interface>
 </node>
diff --git a/src/sysprofd/ipc-service-impl.c b/src/sysprofd/ipc-service-impl.c
index 88ab4b3..da9bf47 100644
--- a/src/sysprofd/ipc-service-impl.c
+++ b/src/sysprofd/ipc-service-impl.c
@@ -375,6 +375,52 @@ finish:
   return TRUE;
 }
 
+static gboolean
+ipc_service_impl_handle_set_paranoid (IpcService            *service,
+                                      GDBusMethodInvocation *invocation,
+                                      int                    paranoid)
+{
+  g_autoptr(GError) error = NULL;
+  g_autofree gchar *str = NULL;
+  int previous = G_MAXINT;
+
+  g_assert (IPC_IS_SERVICE (service));
+  g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation));
+
+  paranoid = CLAMP (paranoid, -1, 2);
+
+  if (!g_file_get_contents ("/proc/sys/kernel/perf_event_paranoid", &str, NULL, &error))
+    {
+      g_warning ("Failed to discover previous perf_event_paranoid setting: %s", error->message);
+      goto finish;
+    }
+
+  previous = g_ascii_strtoll (str, NULL, 10);
+
+  if (previous != paranoid)
+    {
+      char paranoid_str[8];
+      gssize len = g_snprintf (paranoid_str, sizeof paranoid_str, "%d", paranoid);
+
+      if (!file_set_contents_no_backup ("/proc/sys/kernel/perf_event_paranoid", paranoid_str, len, &error))
+        g_warning ("Failed to set perf_event_paranoid: %s", error->message);
+    }
+
+finish:
+  if (error != NULL)
+    g_dbus_method_invocation_return_error (g_steal_pointer (&invocation),
+                                           G_DBUS_ERROR,
+                                           G_DBUS_ERROR_FAILED,
+                                           "Failed to set perf_event_paranoid: %s",
+                                           error->message);
+  else
+    ipc_service_complete_set_paranoid (service,
+                                       g_steal_pointer (&invocation),
+                                       previous);
+
+  return TRUE;
+}
+
 static void
 init_service_iface (IpcServiceIface *iface)
 {
@@ -384,6 +430,7 @@ init_service_iface (IpcServiceIface *iface)
   iface->handle_perf_event_open = ipc_service_impl_handle_perf_event_open;
   iface->handle_get_process_info = ipc_service_impl_handle_get_process_info;
   iface->handle_set_governor = ipc_service_impl_handle_set_governor;
+  iface->handle_set_paranoid = ipc_service_impl_handle_set_paranoid;
 }
 
 G_DEFINE_TYPE_WITH_CODE (IpcServiceImpl, ipc_service_impl, IPC_TYPE_SERVICE_SKELETON,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]