svn commit: r303929 - head/usr.bin/xinstall
Bryan Drewery
bdrewery at FreeBSD.org
Wed Aug 10 18:19:03 UTC 2016
Author: bdrewery
Date: Wed Aug 10 18:19:02 2016
New Revision: 303929
URL: https://svnweb.freebsd.org/changeset/base/303929
Log:
Fix -S with -b not atomically updating the destination file.
With both of these flags, the backup was created via rename(dest, backup)
followed by rename(tmp, dest). This left the destination file missing
for a moment which contradicts the point of -S.
This fixes a race with installworld where PRECIOUSPROG and PRECIOUSLIB
files (which use -S for installation) would briefly be missing. In the
case of installing rtld with parallel installworld it could render an
error due to not having rtld present to run install/cp in another
process.
Reported by: jhb
Reviewed by: jhb
MFC after: 1 week
Sponsored by: EMC / Isilon Storage Division
Differential Revision: https://reviews.freebsd.org/D7451
Modified:
head/usr.bin/xinstall/xinstall.c
Modified: head/usr.bin/xinstall/xinstall.c
==============================================================================
--- head/usr.bin/xinstall/xinstall.c Wed Aug 10 18:18:51 2016 (r303928)
+++ head/usr.bin/xinstall/xinstall.c Wed Aug 10 18:19:02 2016 (r303929)
@@ -892,11 +892,17 @@ install(const char *from_name, const cha
}
if (verbose)
(void)printf("install: %s -> %s\n", to_name, backup);
- if (rename(to_name, backup) < 0) {
+ if (unlink(backup) < 0 && errno != ENOENT) {
serrno = errno;
unlink(tempfile);
errno = serrno;
- err(EX_OSERR, "rename: %s to %s", to_name,
+ err(EX_OSERR, "unlink: %s", backup);
+ }
+ if (link(to_name, backup) < 0) {
+ serrno = errno;
+ unlink(tempfile);
+ errno = serrno;
+ err(EX_OSERR, "link: %s to %s", to_name,
backup);
}
}
More information about the svn-src-head
mailing list