lib/deploy: Add support for overlay initrds
In FCOS and RHCOS, the need to configure software in the initramfs has come up multiple times. Sometimes, using kernel arguments suffices. Other times, it really must be a configuration file. Rebuilding the initramfs on the client-side however is a costly operation. Not only does it add complexity to the update workflow, it also erodes a lot of the value obtained from using the baked "blessed" initramfs from the tree itself. One elegant way to address this is to allow specifying multiple initramfses. This is supported by most bootloaders (notably GRUB) and results in each initrd being overlayed on top of each other. This patch allows libostree clients to leverage this so that they can avoid regenerating the initramfs entirely. libostree itself is agnostic as to what kind and how much data overlay initrds contain. It's up to the clients to enforce such boundaries. To implement this, we add a new ostree_sysroot_stage_overlay_initrd which takes a file descriptor and returns a checksum. Then users can pass these checksums when calling the deploy APIs via the new array option `overlay_initrds`. We copy these files into `/boot` and add them to the BLS as another `initrd` entry.
This commit is contained in:
1 parent
40fea4c443
commit
81b13da8e3
11 files changed
+390
-8
No files matched your search
@@ -298,6 +298,8 @@ cleanup_old_deployments (OstreeSysroot *self,
|
||||
g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
g_autoptr(GHashTable) active_boot_checksums =
|
||||
g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
g_autoptr(GHashTable) active_overlay_initrds =
|
||||
g_hash_table_new (g_str_hash, g_str_equal); /* borrows from deployment's bootconfig */
|
||||
for (guint i = 0; i < self->deployments->len; i++)
|
||||
{
|
||||
OstreeDeployment *deployment = self->deployments->pdata[i];
|
||||
@@ -306,6 +308,11 @@ cleanup_old_deployments (OstreeSysroot *self,
|
||||
/* Transfer ownership */
|
||||
g_hash_table_replace (active_deployment_dirs, deployment_path, deployment_path);
|
||||
g_hash_table_replace (active_boot_checksums, bootcsum, bootcsum);
|
||||
|
||||
OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (deployment);
|
||||
char **initrds = ostree_bootconfig_parser_get_overlay_initrds (bootconfig);
|
||||
for (char **it = initrds; it && *it; it++)
|
||||
g_hash_table_add (active_overlay_initrds, (char*)glnx_basename (*it));
|
||||
}
|
||||
|
||||
/* Find all deployment directories, both active and inactive */
|
||||
@@ -349,6 +356,42 @@ cleanup_old_deployments (OstreeSysroot *self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Clean up overlay initrds */
|
||||
glnx_autofd int overlays_dfd =
|
||||
glnx_opendirat_with_errno (self->sysroot_fd, _OSTREE_SYSROOT_INITRAMFS_OVERLAYS, FALSE);
|
||||
if (overlays_dfd < 0)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
return glnx_throw_errno_prefix (error, "open(initrd_overlays)");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_autoptr(GPtrArray) initrds_to_delete = g_ptr_array_new_with_free_func (g_free);
|
||||
g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
|
||||
if (!glnx_dirfd_iterator_init_at (overlays_dfd, ".", TRUE, &dfd_iter, error))
|
||||
return FALSE;
|
||||
while (TRUE)
|
||||
{
|
||||
struct dirent *dent;
|
||||
if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error))
|
||||
return FALSE;
|
||||
if (dent == NULL)
|
||||
break;
|
||||
|
||||
/* there shouldn't be other file types there, but let's be conservative */
|
||||
if (dent->d_type != DT_REG)
|
||||
continue;
|
||||
|
||||
if (!g_hash_table_lookup (active_overlay_initrds, dent->d_name))
|
||||
g_ptr_array_add (initrds_to_delete, g_strdup (dent->d_name));
|
||||
}
|
||||
for (guint i = 0; i < initrds_to_delete->len; i++)
|
||||
{
|
||||
if (!ot_ensure_unlinked_at (overlays_dfd, initrds_to_delete->pdata[i], error))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user