libsysprof-analyze: implement key/value superblock option API

This currently gets used in libsysprof to try to cross mount namespaces to
somewhere we can access a binary on the same subvolume.
This commit is contained in:
Christian Hergert
2023-05-11 15:21:36 -07:00
parent 35f87b6121
commit ff1b4d00bd
3 changed files with 38 additions and 2 deletions

View File

@ -281,10 +281,42 @@ sysprof_mount_get_superblock_options (SysprofMount *self)
return self->superblock_options;
}
const char *
char *
sysprof_mount_get_superblock_option (SysprofMount *self,
const char *option)
{
gsize option_len;
g_return_val_if_fail (SYSPROF_IS_MOUNT (self), NULL);
g_return_val_if_fail (option != NULL, NULL);
if (self->superblock_options == NULL)
return NULL;
option_len = strlen (option);
for (const char *c = strstr (self->superblock_options, option);
c != NULL;
c = strstr (c+1, option))
{
if ((c == self->superblock_options || c[-1] == ',') &&
(c[option_len] == 0 || c[option_len] == '='))
{
const char *value;
const char *endptr;
if (c[option_len] == 0)
return g_strdup ("");
value = &c[option_len+1];
if (!(endptr = strchr (value, ',')))
return g_strdup (value);
return g_strndup (value, endptr - value);
}
}
return NULL;
}

View File

@ -50,7 +50,7 @@ const char *sysprof_mount_get_filesystem_type (SysprofMount *self);
SYSPROF_AVAILABLE_IN_ALL
const char *sysprof_mount_get_superblock_options (SysprofMount *self);
SYSPROF_AVAILABLE_IN_ALL
const char *sysprof_mount_get_superblock_option (SysprofMount *self,
char *sysprof_mount_get_superblock_option (SysprofMount *self,
const char *option);
G_END_DECLS

View File

@ -73,6 +73,7 @@ main (int argc,
for (guint j = 0; j < n_mounts; j++)
{
g_autoptr(SysprofMount) mount = g_list_model_get_item (mounts, j);
g_autofree char *subvol = sysprof_mount_get_superblock_option (mount, "subvol");
g_print (" %d %d %d:%d %s %s %s %s %s\n",
sysprof_mount_get_mount_id (mount),
@ -84,6 +85,9 @@ main (int argc,
sysprof_mount_get_mount_source (mount),
sysprof_mount_get_filesystem_type (mount),
sysprof_mount_get_superblock_options (mount));
if (subvol != NULL)
g_print (" Had subvol superblock option: %s\n", subvol);
}
}