[sysprof] flatpak: add helpers to locate flatpak installation debug dirs



commit aad61d52f3a694a73b76161cac537126a2e9aa86
Author: Christian Hergert <chergert redhat com>
Date:   Fri Aug 2 18:15:02 2019 -0700

    flatpak: add helpers to locate flatpak installation debug dirs
    
    The goal here is to be able to locate all of the debug directories for
    active flatpak runtimes so that we can possibly decode debug libraries
    from them (after verifying build-id/CRC).

 src/libsysprof/meson.build       |   1 +
 src/libsysprof/sysprof-flatpak.c | 136 +++++++++++++++++++++++++++++++++++++++
 src/libsysprof/sysprof-flatpak.h |  29 +++++++++
 src/tests/meson.build            |   7 ++
 src/tests/test-flatpak.c         |  13 ++++
 5 files changed, 186 insertions(+)
---
diff --git a/src/libsysprof/meson.build b/src/libsysprof/meson.build
index 2f21dd3..12e3ac6 100644
--- a/src/libsysprof/meson.build
+++ b/src/libsysprof/meson.build
@@ -65,6 +65,7 @@ libsysprof_private_sources = [
   'binfile.c',
   'demangle.cpp',
   'elfparser.c',
+  'sysprof-flatpak.c',
   'sysprof-helpers.c',
   'sysprof-kallsyms.c',
   'sysprof-line-reader.c',
diff --git a/src/libsysprof/sysprof-flatpak.c b/src/libsysprof/sysprof-flatpak.c
new file mode 100644
index 0000000..5f470e0
--- /dev/null
+++ b/src/libsysprof/sysprof-flatpak.c
@@ -0,0 +1,136 @@
+/* sysprof-flatpak.c
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "config.h"
+
+#include <sys/utsname.h>
+
+#include "sysprof-flatpak.h"
+
+#define ETC_INSTALLATIONS_D "/etc/flatpak/installations.d"
+
+gchar **
+get_installations (void)
+{
+  GPtrArray *ret = g_ptr_array_new ();
+  g_autoptr(GDir) dir = NULL;
+
+  /* We might be running from a container, so ignore XDG_DATA_HOME as
+   * that will likely be different that what we care about the host.
+   * TODO: Can we find a way to support non-standard XDG_DATA_HOME?
+   */
+  g_ptr_array_add (ret, g_build_filename (g_get_home_dir (), ".local", "share", "flatpak", NULL));
+  g_ptr_array_add (ret, g_strdup ("/var/lib/flatpak"));
+
+  /* Now look at /etc/flatpak/installations.d for keyfiles with Path= */
+  if ((dir = g_dir_open (ETC_INSTALLATIONS_D, 0, NULL)))
+    {
+      const gchar *name;
+
+      while ((name = g_dir_read_name (dir)))
+        {
+          g_autofree gchar *path = g_build_filename (ETC_INSTALLATIONS_D, name, NULL);
+          g_autoptr(GKeyFile) kf = g_key_file_new ();
+
+          if (g_key_file_load_from_file (kf, path, G_KEY_FILE_NONE, NULL))
+            {
+              g_auto(GStrv) groups = g_key_file_get_groups (kf, NULL);
+
+              for (guint i = 0; groups[i]; i++)
+                {
+                  if (g_key_file_has_key (kf, groups[i], "Path", NULL))
+                    {
+                      gchar *val = g_key_file_get_string (kf, groups[i], "Path", NULL);
+
+                      if (val)
+                        g_ptr_array_add (ret, g_steal_pointer (&val));
+                    }
+                }
+            }
+        }
+    }
+
+  g_ptr_array_add (ret, NULL);
+  return (gchar **)g_ptr_array_free (ret, FALSE);
+}
+
+static void
+get_arch (gchar *out,
+          gsize  len)
+{
+  struct utsname u;
+  uname (&u);
+  g_strlcpy (out, u.machine, len);
+}
+
+void
+_sysprof_flatpak_debug_dirs (GPtrArray *dirs)
+{
+  g_auto(GStrv) installs = get_installations ();
+  gchar arch[32];
+
+  g_assert (dirs != NULL);
+
+  get_arch (arch, sizeof arch);
+
+  /* For each of the installations, we want to look at all of the runtimes that
+   * exist within it. Of those runtimes, we want to limit ourselves to the active
+   * version of each runtime, and see if we have a deployment for the current
+   * system arch that contains a "lib/debug" directory. We could add more, but
+   * it's just too many directories.
+   */
+
+  for (guint i = 0; installs[i]; i++)
+    {
+      g_autofree gchar *repo_dir = g_build_filename (installs[i], "runtime", NULL);
+      g_autoptr(GDir) dir = g_dir_open (repo_dir, 0, NULL);
+      const gchar *name;
+
+      if (dir == NULL)
+        continue;
+
+      while ((name = g_dir_read_name (dir)))
+        {
+          g_autofree gchar *version_dir = g_build_filename (installs[i], "runtime", name, arch, NULL);
+          g_autoptr(GDir) vdir = g_dir_open (version_dir, 0, NULL);
+          const gchar *version;
+
+          if (vdir == NULL)
+            continue;
+
+          while ((version = g_dir_read_name (vdir)))
+            {
+              g_autofree gchar *lib_debug = g_build_filename (version_dir, version, "active", "files", 
"lib", "debug", NULL);
+
+              if (g_file_test (lib_debug, G_FILE_TEST_EXISTS))
+                g_ptr_array_add (dirs, g_steal_pointer (&lib_debug));
+            }
+        }
+    }
+}
+
+gchar **
+sysprof_flatpak_debug_dirs (void)
+{
+  GPtrArray *dirs = g_ptr_array_new ();
+  _sysprof_flatpak_debug_dirs (dirs);
+  g_ptr_array_add (dirs, NULL);
+  return (gchar **)g_ptr_array_free (dirs, FALSE);
+}
diff --git a/src/libsysprof/sysprof-flatpak.h b/src/libsysprof/sysprof-flatpak.h
new file mode 100644
index 0000000..04cc004
--- /dev/null
+++ b/src/libsysprof/sysprof-flatpak.h
@@ -0,0 +1,29 @@
+/* sysprof-flatpak.h
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+gchar **sysprof_flatpak_debug_dirs (void);
+
+G_END_DECLS
diff --git a/src/tests/meson.build b/src/tests/meson.build
index 690ec5c..ac80997 100644
--- a/src/tests/meson.build
+++ b/src/tests/meson.build
@@ -50,6 +50,13 @@ test_mountinfo = executable('test-mountinfo',
   dependencies: test_deps,
 )
 
+test_flatpak = executable('test-flatpak',
+  [ 'test-flatpak.c',
+    '../libsysprof/sysprof-flatpak.c'],
+        c_args: test_cflags,
+  dependencies: test_deps,
+)
+
 
 if get_option('enable_gtk')
 
diff --git a/src/tests/test-flatpak.c b/src/tests/test-flatpak.c
new file mode 100644
index 0000000..52abfba
--- /dev/null
+++ b/src/tests/test-flatpak.c
@@ -0,0 +1,13 @@
+#include "sysprof-flatpak.h"
+
+gint
+main (gint   argc,
+      gchar *argv[])
+{
+  g_auto(GStrv) debug_dirs = sysprof_flatpak_debug_dirs ();
+
+  for (guint i = 0; debug_dirs[i]; i++)
+    g_print ("%s\n", debug_dirs[i]);
+
+  return 0;
+}


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