deploy: Change large parts to be fd-relative, drop fsync
This is a continuation of earlier work to drop the individual fsync on files/directories in favor of relying on `syncfs()` for speed. As part of that cleanup, I'm porting it to be fd-relative. I feel relatively confident about this change given that this area of the code has notable test suite coverage, although that code runs as non-root.
This commit is contained in:
parent
3a4f90cf8e
commit
1810de2b51
|
|
@ -924,114 +924,110 @@ ostree_sysroot_write_origin_file (OstreeSysroot *sysroot,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
get_kernel_from_tree (GFile *deployroot,
|
get_kernel_from_tree (int deployment_dfd,
|
||||||
GFile **out_kernel,
|
int *out_boot_dfd,
|
||||||
GFile **out_initramfs,
|
char **out_kernel_name,
|
||||||
GCancellable *cancellable,
|
char **out_initramfs_name,
|
||||||
GError **error)
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
g_autoptr(GFile) ostree_bootdir
|
glnx_fd_close int ret_boot_dfd = -1;
|
||||||
= g_file_resolve_relative_path (deployroot, "usr/lib/ostree-boot");
|
g_auto(GLnxDirFdIterator) dfditer = { 0, };
|
||||||
g_autoptr(GFile) bootdir = g_file_get_child (deployroot, "boot");
|
g_autofree char *ret_kernel_name = NULL;
|
||||||
g_autoptr(GFileEnumerator) dir_enum = NULL;
|
g_autofree char *ret_initramfs_name = NULL;
|
||||||
g_autoptr(GFile) ret_kernel = NULL;
|
gs_free char *kernel_checksum = NULL;
|
||||||
g_autoptr(GFile) ret_initramfs = NULL;
|
gs_free char *initramfs_checksum = NULL;
|
||||||
g_autofree char *kernel_checksum = NULL;
|
|
||||||
g_autofree char *initramfs_checksum = NULL;
|
|
||||||
|
|
||||||
if (g_file_query_exists (ostree_bootdir, NULL))
|
ret_boot_dfd = glnx_opendirat_with_errno (deployment_dfd, "usr/lib/ostree-boot", TRUE);
|
||||||
|
if (ret_boot_dfd == -1)
|
||||||
{
|
{
|
||||||
dir_enum = g_file_enumerate_children (ostree_bootdir, OSTREE_GIO_FAST_QUERYINFO,
|
if (errno != ENOENT)
|
||||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
{
|
||||||
NULL, error);
|
glnx_set_prefix_error_from_errno (error, "%s", "openat");
|
||||||
if (!dir_enum)
|
goto out;
|
||||||
goto out;
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
if (!glnx_opendirat (deployment_dfd, "boot", TRUE, &ret_boot_dfd, error))
|
||||||
dir_enum = g_file_enumerate_children (bootdir, OSTREE_GIO_FAST_QUERYINFO,
|
goto out;
|
||||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
}
|
||||||
NULL, error);
|
|
||||||
if (!dir_enum)
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!glnx_dirfd_iterator_init_at (ret_boot_dfd, ".", FALSE, &dfditer, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
GFileInfo *file_info = NULL;
|
struct dirent *dent;
|
||||||
const char *name;
|
|
||||||
|
|
||||||
if (!gs_file_enumerator_iterate (dir_enum, &file_info, NULL,
|
if (!glnx_dirfd_iterator_next_dent (&dfditer, &dent, cancellable, error))
|
||||||
cancellable, error))
|
|
||||||
goto out;
|
goto out;
|
||||||
if (file_info == NULL)
|
|
||||||
|
if (dent == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
name = g_file_info_get_name (file_info);
|
if (ret_kernel_name == NULL && g_str_has_prefix (dent->d_name, "vmlinuz-"))
|
||||||
|
|
||||||
if (ret_kernel == NULL && g_str_has_prefix (name, "vmlinuz-"))
|
|
||||||
{
|
{
|
||||||
const char *dash = strrchr (name, '-');
|
const char *dash = strrchr (dent->d_name, '-');
|
||||||
g_assert (dash);
|
g_assert (dash);
|
||||||
if (ostree_validate_structureof_checksum_string (dash + 1, NULL))
|
if (ostree_validate_structureof_checksum_string (dash + 1, NULL))
|
||||||
{
|
{
|
||||||
kernel_checksum = g_strdup (dash + 1);
|
kernel_checksum = g_strdup (dash + 1);
|
||||||
ret_kernel = g_file_enumerator_get_child (dir_enum, file_info);
|
ret_kernel_name = g_strdup (dent->d_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ret_initramfs == NULL && g_str_has_prefix (name, "initramfs-"))
|
else if (ret_initramfs_name == NULL && g_str_has_prefix (dent->d_name, "initramfs-"))
|
||||||
{
|
{
|
||||||
const char *dash = strrchr (name, '-');
|
const char *dash = strrchr (dent->d_name, '-');
|
||||||
g_assert (dash);
|
g_assert (dash);
|
||||||
if (ostree_validate_structureof_checksum_string (dash + 1, NULL))
|
if (ostree_validate_structureof_checksum_string (dash + 1, NULL))
|
||||||
{
|
{
|
||||||
initramfs_checksum = g_strdup (dash + 1);
|
initramfs_checksum = g_strdup (dash + 1);
|
||||||
ret_initramfs = g_file_enumerator_get_child (dir_enum, file_info);
|
ret_initramfs_name = g_strdup (dent->d_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret_kernel && ret_initramfs)
|
if (ret_kernel_name != NULL && ret_initramfs_name != NULL)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret_kernel == NULL)
|
if (ret_kernel_name == NULL)
|
||||||
{
|
{
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
||||||
"Failed to find boot/vmlinuz-<CHECKSUM> in %s",
|
"Failed to find boot/vmlinuz-<CHECKSUM> in tree");
|
||||||
gs_file_get_path_cached (deployroot));
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret_initramfs != NULL)
|
if (ret_initramfs_name != NULL)
|
||||||
{
|
{
|
||||||
if (strcmp (kernel_checksum, initramfs_checksum) != 0)
|
if (strcmp (kernel_checksum, initramfs_checksum) != 0)
|
||||||
{
|
{
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
||||||
"Mismatched kernel %s checksum vs initrd %s",
|
"Mismatched kernel checksum vs initrd in tree");
|
||||||
gs_file_get_basename_cached (ret_initramfs),
|
|
||||||
gs_file_get_basename_cached (ret_initramfs));
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ot_transfer_out_value (out_kernel, &ret_kernel);
|
*out_boot_dfd = ret_boot_dfd;
|
||||||
ot_transfer_out_value (out_initramfs, &ret_initramfs);
|
ret_boot_dfd = -1;
|
||||||
|
*out_kernel_name = g_steal_pointer (&ret_kernel_name);
|
||||||
|
*out_initramfs_name = g_steal_pointer (&ret_initramfs_name);
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
checksum_from_kernel_src (GFile *src,
|
checksum_from_kernel_src (const char *name,
|
||||||
char **out_checksum,
|
char **out_checksum,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
const char *last_dash = strrchr (gs_file_get_path_cached (src), '-');
|
const char *last_dash = strrchr (name, '-');
|
||||||
if (!last_dash)
|
if (!last_dash)
|
||||||
{
|
{
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
"Malformed initramfs name '%s', missing '-'", gs_file_get_basename_cached (src));
|
"Malformed kernel/initramfs name '%s', missing '-'", name);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
*out_checksum = g_strdup (last_dash + 1);
|
*out_checksum = g_strdup (last_dash + 1);
|
||||||
|
|
@ -1267,16 +1263,18 @@ install_deployment_kernel (OstreeSysroot *sysroot,
|
||||||
const char *osname = ostree_deployment_get_osname (deployment);
|
const char *osname = ostree_deployment_get_osname (deployment);
|
||||||
const char *bootcsum = ostree_deployment_get_bootcsum (deployment);
|
const char *bootcsum = ostree_deployment_get_bootcsum (deployment);
|
||||||
g_autoptr(GFile) bootdir = NULL;
|
g_autoptr(GFile) bootdir = NULL;
|
||||||
g_autoptr(GFile) bootcsumdir = NULL;
|
g_autofree char *bootcsumdir = NULL;
|
||||||
g_autoptr(GFile) bootconfpath = NULL;
|
g_autofree char *bootconfdir = NULL;
|
||||||
g_autoptr(GFile) bootconfpath_parent = NULL;
|
g_autofree char *bootconf_name = NULL;
|
||||||
g_autofree char *dest_kernel_name = NULL;
|
g_autofree char *dest_kernel_name = NULL;
|
||||||
g_autoptr(GFile) dest_kernel_path = NULL;
|
g_autofree char *dest_initramfs_name = NULL;
|
||||||
g_autoptr(GFile) dest_initramfs_path = NULL;
|
g_autofree char *tree_kernel_name = NULL;
|
||||||
g_autoptr(GFile) tree_kernel_path = NULL;
|
g_autofree char *tree_initramfs_name = NULL;
|
||||||
g_autoptr(GFile) tree_initramfs_path = NULL;
|
g_autofree char *deployment_dirpath = NULL;
|
||||||
g_autoptr(GFile) deployment_dir = NULL;
|
|
||||||
glnx_fd_close int deployment_dfd = -1;
|
glnx_fd_close int deployment_dfd = -1;
|
||||||
|
glnx_fd_close int tree_boot_dfd = -1;
|
||||||
|
glnx_fd_close int boot_dfd = -1;
|
||||||
|
glnx_fd_close int bootcsum_dfd = -1;
|
||||||
g_autofree char *contents = NULL;
|
g_autofree char *contents = NULL;
|
||||||
g_autofree char *deployment_version = NULL;
|
g_autofree char *deployment_version = NULL;
|
||||||
g_autoptr(GHashTable) osrelease_values = NULL;
|
g_autoptr(GHashTable) osrelease_values = NULL;
|
||||||
|
|
@ -1293,50 +1291,62 @@ install_deployment_kernel (OstreeSysroot *sysroot,
|
||||||
OstreeBootconfigParser *bootconfig;
|
OstreeBootconfigParser *bootconfig;
|
||||||
|
|
||||||
bootconfig = ostree_deployment_get_bootconfig (deployment);
|
bootconfig = ostree_deployment_get_bootconfig (deployment);
|
||||||
deployment_dir = ostree_sysroot_get_deployment_directory (sysroot, deployment);
|
deployment_dirpath = ostree_sysroot_get_deployment_dirpath (sysroot, deployment);
|
||||||
|
|
||||||
if (!glnx_opendirat (AT_FDCWD, gs_file_get_path_cached (deployment_dir), FALSE,
|
if (!glnx_opendirat (sysroot->sysroot_fd, deployment_dirpath, FALSE,
|
||||||
&deployment_dfd, error))
|
&deployment_dfd, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!get_kernel_from_tree (deployment_dir, &tree_kernel_path, &tree_initramfs_path,
|
if (!get_kernel_from_tree (deployment_dfd, &tree_boot_dfd,
|
||||||
|
&tree_kernel_name, &tree_initramfs_name,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
bootdir = g_file_get_child (ostree_sysroot_get_path (sysroot), "boot");
|
if (!glnx_opendirat (sysroot->sysroot_fd, "boot", TRUE, &boot_dfd, error))
|
||||||
bootcsumdir = ot_gfile_resolve_path_printf (bootdir, "ostree/%s-%s",
|
|
||||||
osname,
|
|
||||||
bootcsum);
|
|
||||||
bootconfpath = ot_gfile_resolve_path_printf (bootdir, "loader.%d/entries/ostree-%s-%d.conf",
|
|
||||||
new_bootversion, osname,
|
|
||||||
ostree_deployment_get_index (deployment));
|
|
||||||
|
|
||||||
if (!ot_util_ensure_directory_and_fsync (bootcsumdir, cancellable, error))
|
|
||||||
goto out;
|
|
||||||
bootconfpath_parent = g_file_get_parent (bootconfpath);
|
|
||||||
if (!ot_util_ensure_directory_and_fsync (bootconfpath_parent, cancellable, error))
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
dest_kernel_name = remove_checksum_from_kernel_name (gs_file_get_basename_cached (tree_kernel_path),
|
bootcsumdir = g_strdup_printf ("ostree/%s-%s", osname, bootcsum);
|
||||||
bootcsum);
|
bootconfdir = g_strdup_printf ("loader.%d/entries", new_bootversion);
|
||||||
dest_kernel_path = g_file_get_child (bootcsumdir, dest_kernel_name);
|
bootconf_name = g_strdup_printf ("ostree-%s-%d.conf", osname,
|
||||||
if (!g_file_query_exists (dest_kernel_path, NULL))
|
ostree_deployment_get_index (deployment));
|
||||||
|
|
||||||
|
if (!glnx_shutil_mkdir_p_at (boot_dfd, bootcsumdir, 0775, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
if (!glnx_opendirat (boot_dfd, bootcsumdir, TRUE, &bootcsum_dfd, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!glnx_shutil_mkdir_p_at (boot_dfd, bootconfdir, 0775, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
dest_kernel_name = remove_checksum_from_kernel_name (tree_kernel_name, bootcsum);
|
||||||
|
|
||||||
|
if (fstatat (bootcsum_dfd, dest_kernel_name, &stbuf, 0) != 0)
|
||||||
{
|
{
|
||||||
if (!gs_file_linkcopy_sync_data (tree_kernel_path, dest_kernel_path, G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_ALL_METADATA,
|
if (errno != ENOENT)
|
||||||
cancellable, error))
|
{
|
||||||
|
glnx_set_prefix_error_from_errno (error, "fstat %s", dest_kernel_name);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (!glnx_file_copy_at (tree_boot_dfd, tree_kernel_name, NULL,
|
||||||
|
bootcsum_dfd, dest_kernel_name, 0,
|
||||||
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tree_initramfs_path)
|
if (tree_initramfs_name)
|
||||||
{
|
{
|
||||||
g_autofree char *dest_initramfs_name = remove_checksum_from_kernel_name (gs_file_get_basename_cached (tree_initramfs_path),
|
dest_initramfs_name = remove_checksum_from_kernel_name (tree_initramfs_name, bootcsum);
|
||||||
bootcsum);
|
|
||||||
dest_initramfs_path = g_file_get_child (bootcsumdir, dest_initramfs_name);
|
|
||||||
|
|
||||||
if (!g_file_query_exists (dest_initramfs_path, NULL))
|
if (fstatat (bootcsum_dfd, dest_initramfs_name, &stbuf, 0) != 0)
|
||||||
{
|
{
|
||||||
if (!gs_file_linkcopy_sync_data (tree_initramfs_path, dest_initramfs_path, G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_ALL_METADATA,
|
if (errno != ENOENT)
|
||||||
cancellable, error))
|
{
|
||||||
|
glnx_set_prefix_error_from_errno (error, "fstat %s", dest_initramfs_name);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (!glnx_file_copy_at (tree_boot_dfd, tree_initramfs_name, NULL,
|
||||||
|
bootcsum_dfd, dest_initramfs_name, 0,
|
||||||
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1428,15 +1438,14 @@ install_deployment_kernel (OstreeSysroot *sysroot,
|
||||||
version_key = g_strdup_printf ("%d", n_deployments - ostree_deployment_get_index (deployment));
|
version_key = g_strdup_printf ("%d", n_deployments - ostree_deployment_get_index (deployment));
|
||||||
ostree_bootconfig_parser_set (bootconfig, "version", version_key);
|
ostree_bootconfig_parser_set (bootconfig, "version", version_key);
|
||||||
|
|
||||||
linux_relpath = g_file_get_relative_path (bootdir, dest_kernel_path);
|
{ g_autofree char * boot_relpath = g_strconcat ("/", bootcsumdir, "/", dest_kernel_name, NULL);
|
||||||
linux_key = g_strconcat ("/", linux_relpath, NULL);
|
ostree_bootconfig_parser_set (bootconfig, "linux", boot_relpath);
|
||||||
ostree_bootconfig_parser_set (bootconfig, "linux", linux_key);
|
}
|
||||||
|
|
||||||
if (dest_initramfs_path)
|
if (dest_initramfs_name)
|
||||||
{
|
{
|
||||||
initramfs_relpath = g_file_get_relative_path (bootdir, dest_initramfs_path);
|
g_autofree char * boot_relpath = g_strconcat ("/", bootcsumdir, "/", dest_initramfs_name, NULL);
|
||||||
initrd_key = g_strconcat ("/", initramfs_relpath, NULL);
|
ostree_bootconfig_parser_set (bootconfig, "initrd", boot_relpath);
|
||||||
ostree_bootconfig_parser_set (bootconfig, "initrd", initrd_key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val = ostree_bootconfig_parser_get (bootconfig, "options");
|
val = ostree_bootconfig_parser_get (bootconfig, "options");
|
||||||
|
|
@ -1450,15 +1459,16 @@ install_deployment_kernel (OstreeSysroot *sysroot,
|
||||||
options_key = _ostree_kernel_args_to_string (kargs);
|
options_key = _ostree_kernel_args_to_string (kargs);
|
||||||
ostree_bootconfig_parser_set (bootconfig, "options", options_key);
|
ostree_bootconfig_parser_set (bootconfig, "options", options_key);
|
||||||
|
|
||||||
if (!ostree_bootconfig_parser_write (ostree_deployment_get_bootconfig (deployment), bootconfpath,
|
{ glnx_fd_close int bootconf_dfd = -1;
|
||||||
cancellable, error))
|
|
||||||
|
if (!glnx_opendirat (boot_dfd, bootconfdir, TRUE, &bootconf_dfd, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Now sync out parent directories */
|
if (!ostree_bootconfig_parser_write_at (ostree_deployment_get_bootconfig (deployment),
|
||||||
if (!ot_util_fsync_directory (bootcsumdir, cancellable, error))
|
bootconf_dfd, bootconf_name,
|
||||||
goto out;
|
cancellable, error))
|
||||||
if (!ot_util_fsync_directory (bootconfpath_parent, cancellable, error))
|
goto out;
|
||||||
goto out;
|
}
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
out:
|
out:
|
||||||
|
|
@ -1935,8 +1945,9 @@ ostree_sysroot_deploy_tree (OstreeSysroot *self,
|
||||||
glnx_unref_object OstreeRepo *repo = NULL;
|
glnx_unref_object OstreeRepo *repo = NULL;
|
||||||
g_autoptr(GFile) osdeploydir = NULL;
|
g_autoptr(GFile) osdeploydir = NULL;
|
||||||
g_autoptr(GFile) deployment_var = NULL;
|
g_autoptr(GFile) deployment_var = NULL;
|
||||||
g_autoptr(GFile) tree_kernel_path = NULL;
|
glnx_fd_close int tree_boot_dfd = -1;
|
||||||
g_autoptr(GFile) tree_initramfs_path = NULL;
|
g_autofree char *tree_kernel_path = NULL;
|
||||||
|
g_autofree char *tree_initramfs_path = NULL;
|
||||||
glnx_fd_close int deployment_dfd = -1;
|
glnx_fd_close int deployment_dfd = -1;
|
||||||
glnx_unref_object OstreeSePolicy *sepolicy = NULL;
|
glnx_unref_object OstreeSePolicy *sepolicy = NULL;
|
||||||
g_autofree char *new_bootcsum = NULL;
|
g_autofree char *new_bootcsum = NULL;
|
||||||
|
|
@ -1979,9 +1990,8 @@ ostree_sysroot_deploy_tree (OstreeSysroot *self,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
deployment_dir = ostree_sysroot_get_deployment_directory (self, new_deployment);
|
if (!get_kernel_from_tree (deployment_dfd, &tree_boot_dfd,
|
||||||
|
&tree_kernel_path, &tree_initramfs_path,
|
||||||
if (!get_kernel_from_tree (deployment_dir, &tree_kernel_path, &tree_initramfs_path,
|
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue