Skip to content

Commit

Permalink
lib/deploy: Split /etc merge into two stages
Browse files Browse the repository at this point in the history
For staged deploy, we want to pay the cost of creating copies from
`/usr/etc` → `/etc` at stage time, since it can be expensive.  (We
want to minimize time spent during shutdown).

Split it up into two functions; the logic is also simply clearer.

Closes: #1514
Approved by: jlebon
  • Loading branch information
cgwalters authored and rh-atomic-bot committed Mar 26, 2018
1 parent 460fb7a commit 7ec3d06
Showing 1 changed file with 26 additions and 37 deletions.
63 changes: 26 additions & 37 deletions src/libostree/ostree-sysroot-deploy.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,6 @@ copy_modified_config_file (int orig_etc_fd,
* merge_configuration_from:
* @sysroot: Sysroot
* @merge_deployment: Source of configuration differences
* @merge_deployment_dfd: Directory fd, may be -1
* @new_deployment: Target for merge of configuration
* @new_deployment_dfd: Directory fd for @new_deployment (may *not* be -1)
* @cancellable: Cancellable
Expand All @@ -407,27 +406,22 @@ copy_modified_config_file (int orig_etc_fd,
static gboolean
merge_configuration_from (OstreeSysroot *sysroot,
OstreeDeployment *merge_deployment,
int merge_deployment_dfd,
OstreeDeployment *new_deployment,
int new_deployment_dfd,
GCancellable *cancellable,
GError **error)
{
glnx_autofd int owned_merge_deployment_dfd = -1;
GLNX_AUTO_PREFIX_ERROR ("During /etc merge", error);
const OstreeSysrootDebugFlags flags = sysroot->debug_flags;

g_assert (merge_deployment != NULL && new_deployment != NULL);
g_assert (new_deployment_dfd != -1);

/* Allow the caller to pass -1 for the merge, for convenience */
if (merge_deployment_dfd == -1)
{
g_autofree char *merge_deployment_path = ostree_sysroot_get_deployment_dirpath (sysroot, merge_deployment);
if (!glnx_opendirat (sysroot->sysroot_fd, merge_deployment_path, FALSE,
&owned_merge_deployment_dfd, error))
return FALSE;
merge_deployment_dfd = owned_merge_deployment_dfd;
}
g_autofree char *merge_deployment_path = ostree_sysroot_get_deployment_dirpath (sysroot, merge_deployment);
glnx_autofd int merge_deployment_dfd = -1;
if (!glnx_opendirat (sysroot->sysroot_fd, merge_deployment_path, FALSE,
&merge_deployment_dfd, error))
return FALSE;

/* TODO: get rid of GFile usage here */
g_autoptr(GFile) orig_etc = ot_fdrel_to_gfile (merge_deployment_dfd, "usr/etc");
Expand Down Expand Up @@ -741,22 +735,19 @@ selinux_relabel_var_if_needed (OstreeSysroot *sysroot,
return TRUE;
}

/* OSTree implements a "3 way" merge model for /etc. For a bit more information
* on this, see the manual. This function uses the configuration for
* @previous_deployment, and writes the merged configuration into @deployment's
* /etc. If available, we also load the SELinux policy from the new root.
/* Handle initial creation of /etc in the deployment. See also
* merge_configuration_from().
*/
static gboolean
merge_configuration (OstreeSysroot *sysroot,
OstreeRepo *repo,
OstreeDeployment *previous_deployment,
OstreeDeployment *deployment,
int deployment_dfd,
OstreeSePolicy **out_sepolicy,
GCancellable *cancellable,
GError **error)
prepare_deployment_etc (OstreeSysroot *sysroot,
OstreeRepo *repo,
OstreeDeployment *deployment,
int deployment_dfd,
OstreeSePolicy **out_sepolicy,
GCancellable *cancellable,
GError **error)
{
GLNX_AUTO_PREFIX_ERROR ("During /etc merge", error);
GLNX_AUTO_PREFIX_ERROR ("Preparing /etc", error);
g_autoptr(OstreeSePolicy) sepolicy = NULL;

struct stat stbuf;
Expand Down Expand Up @@ -805,14 +796,6 @@ merge_configuration (OstreeSysroot *sysroot,

}

if (previous_deployment)
{
if (!merge_configuration_from (sysroot, previous_deployment, -1,
deployment, deployment_dfd,
cancellable, error))
return FALSE;
}

if (out_sepolicy)
*out_sepolicy = g_steal_pointer (&sepolicy);
return TRUE;
Expand Down Expand Up @@ -2444,12 +2427,18 @@ ostree_sysroot_deploy_tree (OstreeSysroot *self,
}

g_autoptr(OstreeSePolicy) sepolicy = NULL;
if (!merge_configuration (self, repo, merge_deployment, new_deployment,
deployment_dfd,
&sepolicy,
cancellable, error))
if (!prepare_deployment_etc (self, repo, new_deployment, deployment_dfd,
&sepolicy, cancellable, error))
return FALSE;

if (merge_deployment)
{
if (!merge_configuration_from (self, merge_deployment,
new_deployment, deployment_dfd,
cancellable, error))
return FALSE;
}

if (!selinux_relabel_var_if_needed (self, sepolicy, os_deploy_dfd,
cancellable, error))
return FALSE;
Expand Down

0 comments on commit 7ec3d06

Please sign in to comment.