Less naive version of sync-after-transaction (RhBug:1461765)

If syncfs() is available (ie on Linux), only sync modified filesystems.
In order to do this, keep the diskspace information around throughout
the transaction.

Skip the sync entirely on chroot installations for now, but this
too should be configurable (always/auto/never or so).

There's a bit of a chicken-egg problem with post-transaction plugins:
for example systemd_inhibit should only be released after syncing,
but OTOH some other plugins might be performing actions whose results
should be syncing. Leaving it alone for now.
This commit is contained in:
Panu Matilainen 2017-09-07 11:40:10 +03:00
parent 4bb954086a
commit eef82b0e81
2 changed files with 23 additions and 3 deletions

View File

@ -767,6 +767,7 @@ AC_CHECK_FUNCS(lutimes)
AC_CHECK_FUNCS(mergesort)
AC_CHECK_FUNCS(getauxval)
AC_CHECK_FUNCS(setprogname, [], [], [#include <stdlib.h>])
AC_CHECK_FUNCS(syncfs)
AC_MSG_CHECKING([whether __progname is defined])
AC_LINK_IFELSE([AC_LANG_PROGRAM([extern const char *__progname;],

View File

@ -1271,6 +1271,7 @@ static int rpmtsSetup(rpmts ts, rpmprobFilterFlags ignoreSet)
static int rpmtsFinish(rpmts ts)
{
rpmtsFreeDSI(ts);
return rpmChrootSet(NULL);
}
@ -1369,7 +1370,6 @@ static int rpmtsPrepare(rpmts ts)
exit:
fpCacheFree(fpc);
rpmtsFreeDSI(ts);
return rc;
}
@ -1495,6 +1495,26 @@ rpmRC runScript(rpmts ts, rpmte te, Header h, ARGV_const_t prefixes,
return rc;
}
static void rpmtsSync(rpmts ts)
{
if (rpmChrootDone())
return;
#if HAVE_SYNCFS
for (rpmDiskSpaceInfo dsi = ts->dsi; dsi->bsize; dsi++) {
int fd = open(dsi->mntPoint, O_RDONLY);
if (fd != -1) {
rpmlog(RPMLOG_DEBUG, "syncing fs %s\n", dsi->mntPoint);
syncfs(fd);
close(fd);
}
}
#else
rpmlog(RPMLOG_DEBUG, "syncing all filesystems\n");
sync();
#endif
}
int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
{
int rc = -1; /* assume failure */
@ -1608,8 +1628,7 @@ exit:
/* Finish up... */
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) && rpmtsNElements(ts) > 0) {
rpmlog(RPMLOG_DEBUG, "syncing disks...\n");
sync();
rpmtsSync(ts);
}
(void) umask(oldmask);
(void) rpmtsFinish(ts);