diff --git a/src/libsysprof-analyze/sysprof-document.c b/src/libsysprof-analyze/sysprof-document.c index 665069dd..866ddd4e 100644 --- a/src/libsysprof-analyze/sysprof-document.c +++ b/src/libsysprof-analyze/sysprof-document.c @@ -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)); } diff --git a/src/libsysprof-analyze/sysprof-mount-namespace-private.h b/src/libsysprof-analyze/sysprof-mount-namespace-private.h index 5f0f3d6f..6dd80e32 100644 --- a/src/libsysprof-analyze/sysprof-mount-namespace-private.h +++ b/src/libsysprof-analyze/sysprof-mount-namespace-private.h @@ -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); diff --git a/src/libsysprof-analyze/sysprof-mount-namespace.c b/src/libsysprof-analyze/sysprof-mount-namespace.c index a355c3bc..31b73c8c 100644 --- a/src/libsysprof-analyze/sysprof-mount-namespace.c +++ b/src/libsysprof-analyze/sysprof-mount-namespace.c @@ -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); } diff --git a/src/libsysprof-analyze/sysprof-mount-private.h b/src/libsysprof-analyze/sysprof-mount-private.h index fe965c2c..e0b75dd5 100644 --- a/src/libsysprof-analyze/sysprof-mount-private.h +++ b/src/libsysprof-analyze/sysprof-mount-private.h @@ -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); diff --git a/src/libsysprof-analyze/sysprof-mount.c b/src/libsysprof-analyze/sysprof-mount.c index 76b18b65..32733dc9 100644 --- a/src/libsysprof-analyze/sysprof-mount.c +++ b/src/libsysprof-analyze/sysprof-mount.c @@ -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) {