mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
libsysprof: add SysprofProfiler:acquire-privileges property
If this property is set to TRUE (the default) it queries sysprofd and policy-kit for appropriate privileges. That generally means that the instruments will use sysprofd to get access to things like /proc files, perf event streams, and what not. If set to FALSE, then this tells the instruments that they should try to do that work locally instead of querying the sysprofd instance via D-Bus.
This commit is contained in:
@ -33,10 +33,12 @@ struct _SysprofProfiler
|
||||
GObject parent_instance;
|
||||
GPtrArray *instruments;
|
||||
SysprofSpawnable *spawnable;
|
||||
guint acquire_privileges : 1;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ACQUIRE_PRIVILEGES,
|
||||
PROP_SPAWNABLE,
|
||||
N_PROPS
|
||||
};
|
||||
@ -66,6 +68,10 @@ sysprof_profiler_get_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ACQUIRE_PRIVILEGES:
|
||||
g_value_set_boolean (value, sysprof_profiler_get_acquire_privileges (self));
|
||||
break;
|
||||
|
||||
case PROP_SPAWNABLE:
|
||||
g_value_set_object (value, sysprof_profiler_get_spawnable (self));
|
||||
break;
|
||||
@ -85,6 +91,10 @@ sysprof_profiler_set_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ACQUIRE_PRIVILEGES:
|
||||
sysprof_profiler_set_acquire_privileges (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_SPAWNABLE:
|
||||
sysprof_profiler_set_spawnable (self, g_value_get_object (value));
|
||||
break;
|
||||
@ -103,6 +113,13 @@ sysprof_profiler_class_init (SysprofProfilerClass *klass)
|
||||
object_class->get_property = sysprof_profiler_get_property;
|
||||
object_class->set_property = sysprof_profiler_set_property;
|
||||
|
||||
properties[PROP_ACQUIRE_PRIVILEGES] =
|
||||
g_param_spec_boolean ("acquire-privileges", NULL, NULL,
|
||||
TRUE,
|
||||
(G_PARAM_READWRITE |
|
||||
G_PARAM_EXPLICIT_NOTIFY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
properties [PROP_SPAWNABLE] =
|
||||
g_param_spec_object ("spawnable", NULL, NULL,
|
||||
SYSPROF_TYPE_SPAWNABLE,
|
||||
@ -114,6 +131,7 @@ sysprof_profiler_class_init (SysprofProfilerClass *klass)
|
||||
static void
|
||||
sysprof_profiler_init (SysprofProfiler *self)
|
||||
{
|
||||
self->acquire_privileges = TRUE;
|
||||
self->instruments = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
|
||||
#ifdef __linux__
|
||||
@ -169,7 +187,8 @@ sysprof_profiler_record_async (SysprofProfiler *self,
|
||||
recording = _sysprof_recording_new (writer,
|
||||
self->spawnable,
|
||||
(SysprofInstrument **)self->instruments->pdata,
|
||||
self->instruments->len);
|
||||
self->instruments->len,
|
||||
self->acquire_privileges);
|
||||
|
||||
g_task_return_pointer (task, g_object_ref (recording), g_object_unref);
|
||||
|
||||
@ -225,3 +244,36 @@ sysprof_profiler_set_spawnable (SysprofProfiler *self,
|
||||
if (g_set_object (&self->spawnable, spawnable))
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_SPAWNABLE]);
|
||||
}
|
||||
|
||||
gboolean
|
||||
sysprof_profiler_get_acquire_privileges (SysprofProfiler *self)
|
||||
{
|
||||
g_return_val_if_fail (SYSPROF_IS_PROFILER (self), FALSE);
|
||||
|
||||
return self->acquire_privileges;
|
||||
}
|
||||
|
||||
/**
|
||||
* sysprof_profiler_set_acquire_privileges:
|
||||
* @self: a [class@Sysprof.Profiler]
|
||||
*
|
||||
* Sets if the the profiler should automatically acquire privileges using
|
||||
* D-Bus, Policy-Kit, and sysprofd.
|
||||
*
|
||||
* Set to false if you want to profile only from what the current process
|
||||
* can see. Generally that means your user needs perf capabilities.
|
||||
*/
|
||||
void
|
||||
sysprof_profiler_set_acquire_privileges (SysprofProfiler *self,
|
||||
gboolean acquire_privileges)
|
||||
{
|
||||
g_return_if_fail (SYSPROF_IS_PROFILER (self));
|
||||
|
||||
acquire_privileges = !!acquire_privileges;
|
||||
|
||||
if (self->acquire_privileges != acquire_privileges)
|
||||
{
|
||||
self->acquire_privileges = acquire_privileges;
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACQUIRE_PRIVILEGES]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,24 +36,29 @@ SYSPROF_AVAILABLE_IN_ALL
|
||||
G_DECLARE_FINAL_TYPE (SysprofProfiler, sysprof_profiler, SYSPROF, PROFILER, GObject)
|
||||
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
SysprofProfiler *sysprof_profiler_new (void);
|
||||
SysprofProfiler *sysprof_profiler_new (void);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
SysprofSpawnable *sysprof_profiler_get_spawnable (SysprofProfiler *self);
|
||||
SysprofSpawnable *sysprof_profiler_get_spawnable (SysprofProfiler *self);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
void sysprof_profiler_set_spawnable (SysprofProfiler *self,
|
||||
SysprofSpawnable *spawnable);
|
||||
void sysprof_profiler_set_spawnable (SysprofProfiler *self,
|
||||
SysprofSpawnable *spawnable);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
void sysprof_profiler_add_instrument (SysprofProfiler *self,
|
||||
SysprofInstrument *instrument);
|
||||
void sysprof_profiler_add_instrument (SysprofProfiler *self,
|
||||
SysprofInstrument *instrument);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
void sysprof_profiler_record_async (SysprofProfiler *self,
|
||||
SysprofCaptureWriter *writer,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
void sysprof_profiler_record_async (SysprofProfiler *self,
|
||||
SysprofCaptureWriter *writer,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
SysprofRecording *sysprof_profiler_record_finish (SysprofProfiler *self,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
SysprofRecording *sysprof_profiler_record_finish (SysprofProfiler *self,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
SYSPROF_AVAILABLE_IN_49
|
||||
gboolean sysprof_profiler_get_acquire_privileges (SysprofProfiler *self);
|
||||
SYSPROF_AVAILABLE_IN_49
|
||||
void sysprof_profiler_set_acquire_privileges (SysprofProfiler *self,
|
||||
gboolean acquire_privileges);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@ -79,12 +79,18 @@ struct _SysprofRecording
|
||||
|
||||
/* The process we have spawned, if any */
|
||||
GSubprocess *subprocess;
|
||||
|
||||
/* If we should preauth or otherwise use sysprofd to access
|
||||
* privileges when setting up the recording.
|
||||
*/
|
||||
guint use_sysprofd : 1;
|
||||
};
|
||||
|
||||
SysprofRecording *_sysprof_recording_new (SysprofCaptureWriter *writer,
|
||||
SysprofSpawnable *spawnable,
|
||||
SysprofInstrument **instruments,
|
||||
guint n_instruments);
|
||||
guint n_instruments,
|
||||
gboolean use_sysprofd);
|
||||
void _sysprof_recording_start (SysprofRecording *self);
|
||||
SysprofSpawnable *_sysprof_recording_get_spawnable (SysprofRecording *self);
|
||||
DexFuture *_sysprof_recording_add_file (SysprofRecording *self,
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include <libdex.h>
|
||||
|
||||
#include "sysprof-recording-private.h"
|
||||
#include "sysprof-util-private.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@ -99,6 +100,7 @@ static DexFuture *
|
||||
sysprof_recording_fiber (gpointer user_data)
|
||||
{
|
||||
SysprofRecording *self = user_data;
|
||||
g_autoptr(GDBusConnection) connection = NULL;
|
||||
g_autoptr(GCancellable) cancellable = NULL;
|
||||
g_autoptr(DexFuture) record = NULL;
|
||||
g_autoptr(DexFuture) monitor = NULL;
|
||||
@ -115,12 +117,24 @@ sysprof_recording_fiber (gpointer user_data)
|
||||
|
||||
cancellable = g_cancellable_new ();
|
||||
|
||||
/* First ensure that all our required policy have been acquired on
|
||||
* the bus so that we don't need to individually acquire them from
|
||||
* each of the instruments after the recording starts.
|
||||
*/
|
||||
if (!dex_await (_sysprof_instruments_acquire_policy (self->instruments, self), &error))
|
||||
return dex_future_new_for_error (g_steal_pointer (&error));
|
||||
if (self->use_sysprofd)
|
||||
{
|
||||
/* Get our D-Bus system connection if we're using sysprofd. */
|
||||
if (!(connection = dex_await_object (dex_bus_get (G_BUS_TYPE_SYSTEM), NULL)))
|
||||
return dex_future_new_for_error (g_steal_pointer (&error));
|
||||
|
||||
/* Let every instrument know what bus we're using so that they can
|
||||
* automatically enable/disable sysprofd/policy-kit integration.
|
||||
*/
|
||||
_sysprof_instruments_set_connection (self->instruments, connection);
|
||||
|
||||
/* First ensure that all our required policy have been acquired on
|
||||
* the bus so that we don't need to individually acquire them from
|
||||
* each of the instruments after the recording starts.
|
||||
*/
|
||||
if (!dex_await (_sysprof_instruments_acquire_policy (self->instruments, self), &error))
|
||||
return dex_future_new_for_error (g_steal_pointer (&error));
|
||||
}
|
||||
|
||||
/* Now allow instruments to prepare for the recording */
|
||||
if (!dex_await (_sysprof_instruments_prepare (self->instruments, self), &error))
|
||||
@ -420,7 +434,8 @@ SysprofRecording *
|
||||
_sysprof_recording_new (SysprofCaptureWriter *writer,
|
||||
SysprofSpawnable *spawnable,
|
||||
SysprofInstrument **instruments,
|
||||
guint n_instruments)
|
||||
guint n_instruments,
|
||||
gboolean use_sysprofd)
|
||||
{
|
||||
SysprofRecording *self;
|
||||
|
||||
@ -428,6 +443,7 @@ _sysprof_recording_new (SysprofCaptureWriter *writer,
|
||||
|
||||
self = g_object_new (SYSPROF_TYPE_RECORDING, NULL);
|
||||
self->writer = sysprof_capture_writer_ref (writer);
|
||||
self->use_sysprofd = !!use_sysprofd;
|
||||
|
||||
g_set_object (&self->spawnable, spawnable);
|
||||
|
||||
@ -517,6 +533,7 @@ typedef struct _AddFile
|
||||
SysprofCaptureWriter *writer;
|
||||
char *path;
|
||||
guint compress : 1;
|
||||
guint use_sysprofd : 1;
|
||||
} AddFile;
|
||||
|
||||
static void
|
||||
@ -572,25 +589,18 @@ sysprof_recording_add_file_fiber (gpointer user_data)
|
||||
if (g_file_has_prefix (file, proc))
|
||||
{
|
||||
g_autoptr(GDBusConnection) connection = NULL;
|
||||
g_autoptr(GVariant) reply = NULL;
|
||||
g_autoptr(GBytes) input_bytes = NULL;
|
||||
|
||||
if (!(connection = dex_await_object (dex_bus_get (G_BUS_TYPE_SYSTEM), &error)))
|
||||
if (add_file->use_sysprofd)
|
||||
{
|
||||
/* Only use D-Bus if sysprofd use is requested */
|
||||
if (!(connection = dex_await_object (dex_bus_get (G_BUS_TYPE_SYSTEM), &error)))
|
||||
return dex_future_new_for_error (g_steal_pointer (&error));
|
||||
}
|
||||
|
||||
if (!(input_bytes = dex_await_boxed (sysprof_get_proc_file_bytes (connection, g_file_get_path (file)), &error)))
|
||||
return dex_future_new_for_error (g_steal_pointer (&error));
|
||||
|
||||
if (!(reply = dex_await_variant (dex_dbus_connection_call (connection,
|
||||
"org.gnome.Sysprof3",
|
||||
"/org/gnome/Sysprof3",
|
||||
"org.gnome.Sysprof3.Service",
|
||||
"GetProcFile",
|
||||
g_variant_new ("(^ay)", g_file_get_path (file)),
|
||||
G_VARIANT_TYPE ("(ay)"),
|
||||
G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION,
|
||||
G_MAXINT),
|
||||
&error)))
|
||||
return dex_future_new_for_error (g_steal_pointer (&error));
|
||||
|
||||
input_bytes = g_variant_get_data_as_bytes (reply);
|
||||
input = g_memory_input_stream_new_from_bytes (input_bytes);
|
||||
}
|
||||
else
|
||||
@ -662,6 +672,7 @@ _sysprof_recording_add_file (SysprofRecording *self,
|
||||
add_file->writer = sysprof_capture_writer_ref (self->writer);
|
||||
add_file->path = g_strdup (path);
|
||||
add_file->compress = !!compress;
|
||||
add_file->use_sysprofd = self->use_sysprofd;
|
||||
|
||||
return dex_scheduler_spawn (NULL, 0,
|
||||
sysprof_recording_add_file_fiber,
|
||||
|
||||
Reference in New Issue
Block a user