libsysprof-analyze: treat overlay as SysprofMount

This creates a synthesized SysprofMount for the overlays so that we can
process them as we walk the other mounts.
This commit is contained in:
Christian Hergert
2023-05-22 18:36:27 -07:00
parent 754e5df789
commit 1469e8691a
5 changed files with 75 additions and 51 deletions

View File

@ -35,6 +35,7 @@
#include "sysprof-document-frame-private.h"
#include "sysprof-document-jitmap.h"
#include "sysprof-document-mmap.h"
#include "sysprof-document-overlay.h"
#include "sysprof-document-process-private.h"
#include "sysprof-document-symbols-private.h"
#include "sysprof-mount-private.h"
@ -437,7 +438,15 @@ sysprof_document_load_overlays (SysprofDocument *self)
SysprofProcessInfo *process_info = _sysprof_document_process_info (self, pid, TRUE);
if (process_info != NULL)
sysprof_mount_namespace_add_overlay (process_info->mount_namespace, overlay);
{
const char *mount_point = sysprof_document_overlay_get_destination (overlay);
const char *host_path = sysprof_document_overlay_get_source (overlay);
int layer = sysprof_document_overlay_get_layer (overlay);
g_autoptr(SysprofMount) mount = _sysprof_mount_new_for_overlay (self->strings, mount_point, host_path, layer);
sysprof_mount_namespace_add_mount (process_info->mount_namespace,
g_steal_pointer (&mount));
}
}
while (gtk_bitset_iter_next (&iter, &i));
}

View File

@ -24,7 +24,6 @@
#include "sysprof-mount-private.h"
#include "sysprof-mount-device-private.h"
#include "sysprof-document-overlay.h"
G_BEGIN_DECLS
@ -38,8 +37,6 @@ void sysprof_mount_namespace_add_device (SysprofMountNamespa
SysprofMountDevice *mount);
void sysprof_mount_namespace_add_mount (SysprofMountNamespace *self,
SysprofMount *mount);
void sysprof_mount_namespace_add_overlay (SysprofMountNamespace *self,
SysprofDocumentOverlay *overlay);
char **sysprof_mount_namespace_translate (SysprofMountNamespace *self,
const char *path);

View File

@ -150,16 +150,6 @@ sysprof_mount_namespace_add_mount (SysprofMountNamespace *self,
self->mounts_dirty = TRUE;
}
void
sysprof_mount_namespace_add_overlay (SysprofMountNamespace *self,
SysprofDocumentOverlay *overlay)
{
g_return_if_fail (SYSPROF_IS_MOUNT_NAMESPACE (self));
g_return_if_fail (SYSPROF_IS_DOCUMENT_OVERLAY (overlay));
/* TODO */
}
static SysprofMountDevice *
sysprof_mount_namespace_find_device (SysprofMountNamespace *self,
SysprofMount *mount,
@ -196,9 +186,9 @@ sysprof_mount_namespace_find_device (SysprofMountNamespace *self,
return NULL;
}
static gint
sort_by_length (gconstpointer a,
gconstpointer b)
static int
compare_mount (gconstpointer a,
gconstpointer b)
{
SysprofMount *mount_a = *(SysprofMount * const *)a;
SysprofMount *mount_b = *(SysprofMount * const *)b;
@ -209,8 +199,13 @@ sort_by_length (gconstpointer a,
return -1;
else if (blen > alen)
return 1;
else
return 0;
if (mount_a->layer < mount_b->layer)
return -1;
else if (mount_a->layer > mount_b->layer)
return 1;
return 0;
}
/**
@ -237,9 +232,9 @@ sysprof_mount_namespace_translate (SysprofMountNamespace *self,
g_return_val_if_fail (SYSPROF_IS_MOUNT_NAMESPACE (self), NULL);
g_return_val_if_fail (file != NULL, NULL);
if (self->mounts_dirty)
if G_UNLIKELY (self->mounts_dirty)
{
g_ptr_array_sort (self->mounts, sort_by_length);
g_ptr_array_sort (self->mounts, compare_mount);
self->mounts_dirty = FALSE;
}
@ -253,25 +248,21 @@ sysprof_mount_namespace_translate (SysprofMountNamespace *self,
const char *relative;
char *translated;
if (!(relative = _sysprof_mount_get_relative_path (mount, file)) ||
!(device = sysprof_mount_namespace_find_device (self, mount, relative)))
if (!(relative = _sysprof_mount_get_relative_path (mount, file)))
continue;
device_mount_point = sysprof_mount_device_get_mount_point (device);
translated = g_build_filename (device_mount_point, relative, NULL);
if (!mount->is_overlay)
{
if (!(device = sysprof_mount_namespace_find_device (self, mount, relative)))
continue;
/* TODO: Still a bit to do here, because we need to handle overlays
* still as a SysprofMount. Additionally, we may need to adjust the
* paths a bit more based on subvolume, but I need a system such
* as Silverblue or GNOME OS to test that again to match or improve
* on existing behavior in libsysprof.
*/
/* TODO: After we've translated to what we'd expect to see on the
* host system, we'll need to translate once again to what we can
* actually access if we're inside a container ourselves, such as
* Toolbox or Flatpak and use /var/run/host or similar.
*/
device_mount_point = sysprof_mount_device_get_mount_point (device);
translated = g_build_filename (device_mount_point, relative, NULL);
}
else
{
translated = g_build_filename (mount->mount_source, relative, NULL);
}
g_array_append_val (strv, translated);
}

View File

@ -25,8 +25,28 @@
G_BEGIN_DECLS
struct _SysprofMount
{
GObject parent_instance;
int mount_id;
int parent_mount_id;
int device_major;
int device_minor;
GRefString *root;
GRefString *mount_point;
GRefString *mount_source;
GRefString *filesystem_type;
GRefString *superblock_options;
guint is_overlay : 1;
guint layer : 15;
};
SysprofMount *_sysprof_mount_new_for_mountinfo (SysprofStrings *strings,
const char *mountinfo);
SysprofMount *_sysprof_mount_new_for_overlay (SysprofStrings *strings,
const char *mount_point,
const char *host_path,
int layer);
const char *_sysprof_mount_get_relative_path (SysprofMount *self,
const char *path);

View File

@ -24,20 +24,6 @@
#include "sysprof-mount-private.h"
struct _SysprofMount
{
GObject parent_instance;
int mount_id;
int parent_mount_id;
int device_major;
int device_minor;
GRefString *root;
GRefString *mount_point;
GRefString *mount_source;
GRefString *filesystem_type;
GRefString *superblock_options;
};
enum {
PROP_0,
PROP_DEVICE_MAJOR,
@ -239,6 +225,27 @@ finish:
return g_steal_pointer (&self);
}
SysprofMount *
_sysprof_mount_new_for_overlay (SysprofStrings *strings,
const char *mount_point,
const char *host_path,
int layer)
{
SysprofMount *self;
g_return_val_if_fail (strings != NULL, NULL);
g_return_val_if_fail (mount_point != NULL, NULL);
g_return_val_if_fail (host_path != NULL, NULL);
self = g_object_new (SYSPROF_TYPE_MOUNT, NULL);
self->mount_point = sysprof_strings_get (strings, mount_point);
self->root = sysprof_strings_get (strings, "/");
self->mount_source = sysprof_strings_get (strings, host_path);
self->is_overlay = TRUE;
return self;
}
int
sysprof_mount_get_device_major (SysprofMount *self)
{