# Default user options
FEATURES="assume-digests binpkg-logs
config-protect-if-modified distlocks ebuild-locks
- fixlafiles news parallel-fetch protect-owned
+ fixlafiles merge-sync news parallel-fetch protect-owned
sandbox sfperms strict unknown-features-warn unmerge-logs
unmerge-orphans userfetch"
when fetching from a local mirror, but instead use a "local" mirror setting
in \fI/etc/portage/mirrors\fR, as described in \fBportage\fR(5).
.TP
+.B merge\-sync
+After a package is merged or unmerged, sync relevant files to
+disk in order to avoid data\-loss in the event of a power failure.
+This feature is enabled by default.
+.TP
.B metadata\-transfer
Automatically perform a metadata transfer when `emerge \-\-sync` is run.
In versions of portage >=2.1.5, this feature is disabled by
"downgrade-backup", "ebuild-locks", "fakeroot",
"fail-clean", "force-mirror", "force-prefix", "getbinpkg",
"installsources", "keeptemp", "keepwork", "fixlafiles", "lmirror",
+ "merge-sync",
"metadata-transfer", "mirror", "multilib-strict", "news",
"noauto", "noclean", "nodoc", "noinfo", "noman",
"nostrip", "notitles", "parallel-fetch", "parallel-install",
'portage.util.env_update:env_update',
'portage.util.listdir:dircache,listdir',
'portage.util.movefile:movefile',
+ 'portage.util._ctypes:find_library,LoadLibrary',
'portage.util._dyn_libs.PreservedLibsRegistry:PreservedLibsRegistry',
'portage.util._dyn_libs.LinkageMapELF:LinkageMapELF@LinkageMap',
'portage.util._async.SchedulerInterface:SchedulerInterface',
from itertools import chain
import logging
import os as _os
+import platform
import pwd
import re
import stat
disk and avoid data-loss in the event of a power failure. This method
does nothing if FEATURES=merge-sync is disabled.
"""
- pass
+ if not self._device_path_map or \
+ "merge-sync" not in self.settings.features:
+ return
+
+ syncfs = self._get_syncfs()
+ if syncfs is None:
+ try:
+ proc = subprocess.Popen(["sync"])
+ except EnvironmentError:
+ pass
+ else:
+ proc.wait()
+ else:
+ for path in self._device_path_map.values():
+ try:
+ fd = os.open(path, os.O_RDONLY)
+ except OSError:
+ pass
+ else:
+ try:
+ syncfs(fd)
+ except OSError:
+ pass
+ finally:
+ os.close(fd)
+
+ def _get_syncfs(self):
+ if platform.system() == "Linux":
+ filename = find_library("c")
+ if filename is not None:
+ library = LoadLibrary(filename)
+ if library is not None:
+ try:
+ return library.syncfs
+ except AttributeError:
+ pass
+
+ return None
def merge(self, mergeroot, inforoot, myroot=None, myebuild=None, cleanup=0,
mydbapi=None, prev_mtimes=None, counter=None):