\chapter{Merging and unmerging}

\note{In this chapter, \i{file} and \i{regular file} have their Unix meanings.}

\section{Overview}

The merge process merges the contents of the \t{D} directory onto the filesystem under \t{ROOT}\@.
This is not a straight copy; there are various subtleties which must be addressed.

The unmerge process removes an installed package's files. It is not covered in detail in this
specification.

\section{Directories}

Directories are merged recursively onto the filesystem. The method used to perform the merge is not
specified, so long as the end result is correct. In particular, merging a directory may alter or
remove the source directory under \t{D}.

Ebuilds must not attempt to merge a directory on top of any existing file that is not either a
directory or a symlink to a directory.

\subsection{Permissions}

The owner, group and mode (including set*id and sticky bits) of the directory must be preserved,
except as follows:

\begin{compactitem}
\item Any directory owned by the user used to perform the build must become owned by the superuser.
\item Any directory whose group is the primary group of the user used to perform the build must have
    its group be that of the superuser.
\end{compactitem}

On SELinux systems, the SELinux context must also be preserved. Other directory attributes,
including modification time, may be discarded.

\subsection{Empty directories}

Behaviour upon encountering an empty directory is undefined. Ebuilds must not attempt to install an
empty directory.

\section{Regular files}

Regular files are merged onto the filesystem (but see the notes on configuration file protection,
below). The method used to perform the merge is not specified, so long as the end result is correct.
In particular, merging a regular file may alter or remove the source file under \t{D}.

Ebuilds must not attempt to merge a regular file on top of any existing file that is not either a
regular file or a symlink to a regular file.

\subsection{Permissions}

The owner, group and mode (including set*id and sticky bits) of the file must be preserved, except
as follows:

\begin{compactitem}
\item Any file owned by the user used to perform the build must become owned by the superuser.
\item Any file whose group is the primary group of the user used to perform the build must have
    its group be that of the superuser.
\item The package manager may reduce read and write permissions on executable files that have a
    set*id bit set.
\end{compactitem}

On SELinux systems, the SELinux context must also be preserved. Other
file attributes may be discarded.

\subsection{File modification times}

\featurelabel{mtime-preserve}
In EAPIs listed in table~\ref{tab:mtime-preserve}, the package manager
must preserve modification times of regular files. This includes files
being compressed before merging. Exceptions to this are files newly
created by the package manager and binary object files being stripped
of symbols.

When preserving, the seconds part of every regular file's mtime must
be preserved exactly. The sub-second part must either be set to zero,
or set to the greatest value supported by the operating system and
filesystem that is not greater than the sub-second part of the
original time.

For any given destination filesystem, the package manager must ensure
that for any two preserved files $a$, $b$ in that filesystem the
relation $\mbox{mtime}(a) \leq \mbox{mtime}(b)$ still holds, if it
held under the original image directory.

In other EAPIs, the behaviour with respect to file modification times
is undefined.

\ChangeWhenAddingAnEAPI{9}
\begin{centertable}{Preservation of file modification times (mtimes)}
    \label{tab:mtime-preserve}
    \begin{tabular}{ll}
      \toprule
      \multicolumn{1}{c}{\textbf{EAPI}} &
      \multicolumn{1}{c}{\textbf{mtimes preserved?}} \\
      \midrule
      0, 1, 2             & Undefined \\
      3, 4, 5, 6, 7, 8, 9 & Yes       \\
      \bottomrule
    \end{tabular}
\end{centertable}

\subsection{Configuration file protection}
\label{sec:config-protect}

The package manager must provide a means to prevent user configuration files from being
overwritten by any package updates. The profile variables \t{CONFIG_PROTECT} and
\t{CONFIG_PROTECT_MASK} (section~\ref{sec:profile-variables}) control the paths for which this
must be enforced.

In order to ensure interoperability with configuration update tools, the following scheme must be
used by all package managers when merging any regular file:

\begin{compactenum}
\item If the directory containing the file to be merged is not listed in \t{CONFIG_PROTECT}, and is
    not a subdirectory of any such directory, and if the file is not listed in \t{CONFIG_PROTECT},
    the file is merged normally.
\item If the directory containing the file to be merged is listed in \t{CONFIG_PROTECT_MASK}, or
    is a subdirectory of such a directory, or if the file is listed in \t{CONFIG_PROTECT_MASK},
    the file is merged normally.
\item If no existing file with the intended filename exists, or the existing file has identical
    content to the one being merged, the file is installed normally.
\item Otherwise, prepend the filename with \t{._cfg0000_}. If no file with the new name exists,
    then the file is merged with this name.
\item Otherwise, increment the number portion (to form \t{._cfg0001_<name>}) and repeat step 4.
    Continue this process until a usable filename is found.
\item If 9999 is reached in this way, behaviour is undefined.
\end{compactenum}

\section{Symlinks}

Symlinks are merged as symlinks onto the filesystem. The link destination for a merged link shall be
the same as the link destination for the link under \t{D}, except as noted below. The method used to
perform the merge is not specified, so long as the end result is correct; in particular, merging a
symlink may alter or remove the symlink under \t{D}.

Ebuilds must not attempt to merge a symlink on top of a directory.

\subsection{Rewriting}

\featurelabel{symlink-rewrite} In EAPIs listed in table~\ref{tab:symlink-rewrite} as rewriting
symlinks, any absolute symlink whose link target starts with \t{D} must be rewritten with the
leading \t{D} removed. The package manager should issue a notice when encountering such a symlink.
In all other EAPIs, symlinks must be merged with their targets unmodified.

\ChangeWhenAddingAnEAPI{9}
\begin{centertable}{Rewriting of absolute symlinks in EAPIs}
    \label{tab:symlink-rewrite}
    \begin{tabular}{ll}
      \toprule
      \multicolumn{1}{c}{\textbf{EAPI}} &
      \multicolumn{1}{c}{\textbf{Rewrite symlinks?}} \\
      \midrule
      0, 1, 2, 3, 4, 5, 6, 7, 8 & Yes \\
      9                         & No  \\
      \bottomrule
    \end{tabular}
\end{centertable}

\section{Hard links}

A hard link may be merged either as a single file with links or as multiple independent files.

\section{Other files}

Ebuilds must not attempt to install any other type of file (FIFOs, device nodes etc).

% vim: set filetype=tex fileencoding=utf8 et tw=100 spell spelllang=en :

%%% Local Variables:
%%% mode: latex
%%% TeX-master: "pms"
%%% LaTeX-indent-level: 4
%%% LaTeX-item-indent: 0
%%% TeX-brace-indent-level: 4
%%% fill-column: 100
%%% End:
