From 7c37120edf6b2c8ab34a76b8dd2a651bac722eb6 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Thu, 11 May 2023 14:37:02 -0700 Subject: [PATCH] libsysprof-analyze: make SysprofMount public API And expose it via sysprof_document_process_list_mounts() so that when inspecting processes we can see what binaries were mapped as well as what the filesystem looked like to locate those mapped paths. --- src/libsysprof-analyze/meson.build | 1 + src/libsysprof-analyze/sysprof-analyze.h | 1 + .../sysprof-document-process.c | 22 +++++++- .../sysprof-document-process.h | 2 + .../sysprof-mount-namespace.c | 38 ++++++++++++- .../sysprof-mount-private.h | 21 ++------ src/libsysprof-analyze/sysprof-mount.h | 54 +++++++++++++++++++ .../tests/test-list-processes.c | 21 +++++++- 8 files changed, 138 insertions(+), 22 deletions(-) create mode 100644 src/libsysprof-analyze/sysprof-mount.h diff --git a/src/libsysprof-analyze/meson.build b/src/libsysprof-analyze/meson.build index 7d3851da..f242601d 100644 --- a/src/libsysprof-analyze/meson.build +++ b/src/libsysprof-analyze/meson.build @@ -49,6 +49,7 @@ libsysprof_analyze_public_headers = [ 'sysprof-document-sample.h', 'sysprof-document-symbols.h', 'sysprof-document-traceable.h', + 'sysprof-mount.h', 'sysprof-multi-symbolizer.h', 'sysprof-symbol.h', 'sysprof-symbolizer.h', diff --git a/src/libsysprof-analyze/sysprof-analyze.h b/src/libsysprof-analyze/sysprof-analyze.h index ad4edf25..b47f3d54 100644 --- a/src/libsysprof-analyze/sysprof-analyze.h +++ b/src/libsysprof-analyze/sysprof-analyze.h @@ -41,6 +41,7 @@ G_BEGIN_DECLS # include "sysprof-document-sample.h" # include "sysprof-document-symbols.h" # include "sysprof-document-traceable.h" +# include "sysprof-mount.h" # include "sysprof-multi-symbolizer.h" # include "sysprof-symbol.h" # include "sysprof-symbolizer.h" diff --git a/src/libsysprof-analyze/sysprof-document-process.c b/src/libsysprof-analyze/sysprof-document-process.c index fd89f721..48bbca32 100644 --- a/src/libsysprof-analyze/sysprof-document-process.c +++ b/src/libsysprof-analyze/sysprof-document-process.c @@ -22,6 +22,7 @@ #include "sysprof-document-frame-private.h" #include "sysprof-document-process-private.h" +#include "sysprof-mount.h" struct _SysprofDocumentProcess { @@ -110,7 +111,7 @@ sysprof_document_process_get_command_line (SysprofDocumentProcess *self) * sysprof_document_process_list_memory_maps: * @self: a #SysprofDocumentProcess * - * Lists the #SysprofDocumentMmap that are associated with the document. + * Lists the #SysprofDocumentMmap that are associated with the process. * * Returns: (transfer full): a #GListModel of #SysprofDocumentMmap */ @@ -125,6 +126,25 @@ sysprof_document_process_list_memory_maps (SysprofDocumentProcess *self) return g_object_ref (G_LIST_MODEL (self->process_info->address_layout)); } +/** + * sysprof_document_process_list_mounts: + * @self: a #SysprofDocumentProcess + * + * Lists the #SysprofMount that are associated with the process. + * + * Returns: (transfer full): a #GListModel of #SysprofMount + */ +GListModel * +sysprof_document_process_list_mounts (SysprofDocumentProcess *self) +{ + g_return_val_if_fail (SYSPROF_IS_DOCUMENT_PROCESS (self), NULL); + + if (self->process_info == NULL) + return G_LIST_MODEL (g_list_store_new (SYSPROF_TYPE_MOUNT)); + + return g_object_ref (G_LIST_MODEL (self->process_info->mount_namespace)); +} + void _sysprof_document_process_set_info (SysprofDocumentProcess *self, SysprofProcessInfo *process_info) diff --git a/src/libsysprof-analyze/sysprof-document-process.h b/src/libsysprof-analyze/sysprof-document-process.h index 93a795e9..83ce34fa 100644 --- a/src/libsysprof-analyze/sysprof-document-process.h +++ b/src/libsysprof-analyze/sysprof-document-process.h @@ -40,6 +40,8 @@ SYSPROF_AVAILABLE_IN_ALL const char *sysprof_document_process_get_command_line (SysprofDocumentProcess *self); SYSPROF_AVAILABLE_IN_ALL GListModel *sysprof_document_process_list_memory_maps (SysprofDocumentProcess *self); +SYSPROF_AVAILABLE_IN_ALL +GListModel *sysprof_document_process_list_mounts (SysprofDocumentProcess *self); G_DEFINE_AUTOPTR_CLEANUP_FUNC (SysprofDocumentProcess, g_object_unref) diff --git a/src/libsysprof-analyze/sysprof-mount-namespace.c b/src/libsysprof-analyze/sysprof-mount-namespace.c index d09e33d6..c096aebf 100644 --- a/src/libsysprof-analyze/sysprof-mount-namespace.c +++ b/src/libsysprof-analyze/sysprof-mount-namespace.c @@ -20,6 +20,8 @@ #include "config.h" +#include + #include "sysprof-mount-namespace-private.h" struct _SysprofMountNamespace @@ -29,7 +31,40 @@ struct _SysprofMountNamespace GPtrArray *mounts; }; -G_DEFINE_FINAL_TYPE (SysprofMountNamespace, sysprof_mount_namespace, G_TYPE_OBJECT) +static GType +sysprof_mount_namespace_get_item_type (GListModel *model) +{ + return SYSPROF_TYPE_MOUNT; +} + +static guint +sysprof_mount_namespace_get_n_items (GListModel *model) +{ + return SYSPROF_MOUNT_NAMESPACE (model)->mounts->len; +} + +static gpointer +sysprof_mount_namespace_get_item (GListModel *model, + guint position) +{ + SysprofMountNamespace *self = SYSPROF_MOUNT_NAMESPACE (model); + + if (position < self->mounts->len) + return g_object_ref (g_ptr_array_index (self->mounts, position)); + + return NULL; +} + +static void +list_model_iface_init (GListModelInterface *iface) +{ + iface->get_item_type = sysprof_mount_namespace_get_item_type; + iface->get_item = sysprof_mount_namespace_get_item; + iface->get_n_items = sysprof_mount_namespace_get_n_items; +} + +G_DEFINE_FINAL_TYPE_WITH_CODE (SysprofMountNamespace, sysprof_mount_namespace, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_model_iface_init)) static void sysprof_mount_namespace_finalize (GObject *object) @@ -54,6 +89,7 @@ static void sysprof_mount_namespace_init (SysprofMountNamespace *self) { self->devices = g_ptr_array_new_with_free_func (g_object_unref); + self->mounts = g_ptr_array_new_with_free_func (g_object_unref); } SysprofMountNamespace * diff --git a/src/libsysprof-analyze/sysprof-mount-private.h b/src/libsysprof-analyze/sysprof-mount-private.h index da08422f..37bf86cb 100644 --- a/src/libsysprof-analyze/sysprof-mount-private.h +++ b/src/libsysprof-analyze/sysprof-mount-private.h @@ -20,27 +20,12 @@ #pragma once -#include - +#include "sysprof-mount.h" #include "sysprof-strings-private.h" G_BEGIN_DECLS -#define SYSPROF_TYPE_MOUNT (sysprof_mount_get_type()) - -G_DECLARE_FINAL_TYPE (SysprofMount, sysprof_mount, SYSPROF, MOUNT, GObject) - -SysprofMount *sysprof_mount_new_for_mountinfo (SysprofStrings *strings, - const char *mountinfo); -int sysprof_mount_get_device_major (SysprofMount *self); -int sysprof_mount_get_device_minor (SysprofMount *self); -int sysprof_mount_get_mount_id (SysprofMount *self); -int sysprof_mount_get_parent_mount_id (SysprofMount *self); -const char *sysprof_mount_get_root (SysprofMount *self); -const char *sysprof_mount_get_mount_point (SysprofMount *self); -const char *sysprof_mount_get_mount_source (SysprofMount *self); -const char *sysprof_mount_get_filesystem_type (SysprofMount *self); -const char *sysprof_mount_get_superblock_option (SysprofMount *self, - const char *option); +SysprofMount *sysprof_mount_new_for_mountinfo (SysprofStrings *strings, + const char *mountinfo); G_END_DECLS diff --git a/src/libsysprof-analyze/sysprof-mount.h b/src/libsysprof-analyze/sysprof-mount.h new file mode 100644 index 00000000..c7ee83ff --- /dev/null +++ b/src/libsysprof-analyze/sysprof-mount.h @@ -0,0 +1,54 @@ +/* sysprof-mount.h + * + * Copyright 2023 Christian Hergert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 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 . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include + +#include + +G_BEGIN_DECLS + +#define SYSPROF_TYPE_MOUNT (sysprof_mount_get_type()) + +SYSPROF_AVAILABLE_IN_ALL +G_DECLARE_FINAL_TYPE (SysprofMount, sysprof_mount, SYSPROF, MOUNT, GObject) + +SYSPROF_AVAILABLE_IN_ALL +int sysprof_mount_get_device_major (SysprofMount *self); +SYSPROF_AVAILABLE_IN_ALL +int sysprof_mount_get_device_minor (SysprofMount *self); +SYSPROF_AVAILABLE_IN_ALL +int sysprof_mount_get_mount_id (SysprofMount *self); +SYSPROF_AVAILABLE_IN_ALL +int sysprof_mount_get_parent_mount_id (SysprofMount *self); +SYSPROF_AVAILABLE_IN_ALL +const char *sysprof_mount_get_root (SysprofMount *self); +SYSPROF_AVAILABLE_IN_ALL +const char *sysprof_mount_get_mount_point (SysprofMount *self); +SYSPROF_AVAILABLE_IN_ALL +const char *sysprof_mount_get_mount_source (SysprofMount *self); +SYSPROF_AVAILABLE_IN_ALL +const char *sysprof_mount_get_filesystem_type (SysprofMount *self); +SYSPROF_AVAILABLE_IN_ALL +const char *sysprof_mount_get_superblock_option (SysprofMount *self, + const char *option); + +G_END_DECLS diff --git a/src/libsysprof-analyze/tests/test-list-processes.c b/src/libsysprof-analyze/tests/test-list-processes.c index 9c6054e9..2006bf32 100644 --- a/src/libsysprof-analyze/tests/test-list-processes.c +++ b/src/libsysprof-analyze/tests/test-list-processes.c @@ -48,23 +48,40 @@ main (int argc, { g_autoptr(SysprofDocumentProcess) process = g_list_model_get_item (processes, i); g_autoptr(GListModel) memory_maps = sysprof_document_process_list_memory_maps (process); + g_autoptr(GListModel) mounts = sysprof_document_process_list_mounts (process); guint n_maps; + guint n_mounts; g_print ("%d: %s\n", sysprof_document_frame_get_pid (SYSPROF_DOCUMENT_FRAME (process)), sysprof_document_process_get_command_line (process)); + g_print (" Address Layout:\n"); n_maps = g_list_model_get_n_items (memory_maps); - for (guint j = 0; j < n_maps; j++) { g_autoptr(SysprofDocumentMmap) map = g_list_model_get_item (memory_maps, j); - g_print (" [0x%"G_GINT64_MODIFIER"x:0x%"G_GINT64_MODIFIER"x] %s\n", + g_print (" [0x%"G_GINT64_MODIFIER"x:0x%"G_GINT64_MODIFIER"x] %s\n", sysprof_document_mmap_get_start_address (map), sysprof_document_mmap_get_end_address (map), sysprof_document_mmap_get_file (map)); } + + g_print (" Mounts:\n"); + n_mounts = g_list_model_get_n_items (mounts); + for (guint j = 0; j < n_mounts; j++) + { + g_autoptr(SysprofMount) mount = g_list_model_get_item (mounts, j); + + g_print (" %d %d %d:%d %s %s\n", + sysprof_mount_get_mount_id (mount), + sysprof_mount_get_parent_mount_id (mount), + sysprof_mount_get_device_major (mount), + sysprof_mount_get_device_minor (mount), + sysprof_mount_get_root (mount), + sysprof_mount_get_mount_point (mount)); + } } return 0;