Page MenuHomeFreeBSD

Fix combination of -S and -b not atomically updating the destination file.
ClosedPublic

Authored by bdrewery on Aug 9 2016, 5:45 PM.

Details

Summary

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
MFC after: 1 week
Sponsored by: EMC / Isilon Storage Division

Test Plan
/usr/tests/usr.bin/xinstall # kyua test
install_test:copy_self  ->  passed  [0.042s]
install_test:copy_self_comparing  ->  passed  [0.035s]
install_test:copy_self_safe  ->  passed  [0.035s]
install_test:copy_self_safe_comparing  ->  passed  [0.035s]
install_test:copy_to_nonexistent  ->  passed  [0.035s]
install_test:copy_to_nonexistent_backup  ->  passed  [0.035s]
install_test:copy_to_nonexistent_backup_safe  ->  passed  [0.035s]
install_test:copy_to_nonexistent_comparing  ->  passed  [0.035s]
install_test:copy_to_nonexistent_preserving  ->  passed  [0.035s]
install_test:copy_to_nonexistent_safe  ->  passed  [0.035s]
install_test:copy_to_nonexistent_safe_comparing  ->  passed  [0.035s]
install_test:hard_link  ->  passed  [0.033s]
install_test:mkdir_simple  ->  passed  [0.053s]
install_test:overwrite  ->  passed  [0.035s]
install_test:overwrite_backup  ->  passed  [0.037s]
install_test:overwrite_backup_comparing  ->  passed  [0.037s]
install_test:overwrite_backup_safe  ->  passed  [0.037s]
install_test:overwrite_backup_safe_comparing  ->  passed  [0.037s]
install_test:overwrite_comparing  ->  passed  [0.035s]
install_test:overwrite_eq  ->  passed  [0.035s]
install_test:overwrite_eq_comparing  ->  passed  [0.035s]
install_test:overwrite_eq_safe  ->  passed  [0.035s]
install_test:overwrite_eq_safe_comparing  ->  passed  [0.035s]
install_test:overwrite_safe  ->  passed  [0.035s]
install_test:overwrite_safe_comparing  ->  passed  [0.035s]
install_test:strip_changing  ->  passed  [0.045s]
install_test:strip_changing_comparing  ->  passed  [0.045s]
install_test:strip_changing_overwrite  ->  passed  [0.045s]
install_test:strip_changing_overwrite_comparing  ->  passed  [0.045s]
install_test:strip_changing_overwrite_eq  ->  passed  [0.045s]
install_test:strip_changing_overwrite_eq_comparing  ->  passed  [0.045s]
install_test:strip_noop  ->  passed  [0.037s]
install_test:symbolic_link  ->  passed  [0.033s]
install_test:symbolic_link_absolute  ->  passed  [0.035s]
install_test:symbolic_link_relative  ->  passed  [0.035s]

Results file id is usr_tests_usr.bin_xinstall.20160809-174604-325005
Results saved to /root/.kyua/store/results.usr_tests_usr.bin_xinstall.20160809-174604-325005.db

35/35 passed (0 failed)
~/git/freebsd/usr.bin/xinstall # chflags -R noschg libexec;rsync -avH --fileflags /libexec/ libexec/
~/git/freebsd/usr.bin/xinstall # cp libexec/*.so.1 .
~/git/freebsd/usr.bin/xinstall # ls -alio libexec; install -v -bS -fschg ld-elf.so.1 libexec/; ls -alio libexec
total 312
2753468 drwxr-xr-x  3 root  wheel  uarch      7 Aug  9 10:39 ./
  60219 drwxr-xr-x  5 root  wheel  uarch     15 Aug  9 10:44 ../
2753630 -rwxr-xr-x  1 root  wheel  schg  136320 Aug  9 10:39 ld-elf.so.1*
2753623 -r-xr-xr-x  1 root  wheel  uarch 136320 Jul 21 14:37 ld-elf.so.1.old*
2753472 -r-xr-xr-x  1 root  wheel  schg  111420 Jul 21 14:39 ld-elf32.so.1*
2753473 -r-xr-xr-x  1 root  wheel  uarch 111436 Jun  1 12:55 ld-elf32.so.1.old*
2753469 drwxr-xr-x  2 root  wheel  uarch      8 Jul 21 14:38 resolvconf/
install: libexec/ld-elf.so.1 -> libexec/ld-elf.so.1.old
install: ld-elf.so.1 -> libexec/ld-elf.so.1
total 229
2753468 drwxr-xr-x  3 root  wheel  uarch      7 Aug  9 10:46 ./
  60219 drwxr-xr-x  5 root  wheel  uarch     15 Aug  9 10:44 ../
2753676 -rwxr-xr-x  1 root  wheel  schg  136320 Aug  9 10:46 ld-elf.so.1*
2753630 -rwxr-xr-x  1 root  wheel  uarch 136320 Aug  9 10:39 ld-elf.so.1.old*
2753472 -r-xr-xr-x  1 root  wheel  schg  111420 Jul 21 14:39 ld-elf32.so.1*
2753473 -r-xr-xr-x  1 root  wheel  uarch 111436 Jun  1 12:55 ld-elf32.so.1.old*
2753469 drwxr-xr-x  2 root  wheel  uarch      8 Jul 21 14:38 resolvconf/


~/git/freebsd/usr.bin/xinstall # chflags -R noschg libexec;rsync -avH --fileflags /libexec/ libexec/
~/git/freebsd/usr.bin/xinstall # chflags schg libexec/*.old
~/git/freebsd/usr.bin/xinstall # ls -alio libexec; install -v -bS -fschg ld-elf.so.1 libexec/; ls -alio libexec
total 312
2753468 drwxr-xr-x  3 root  wheel  uarch           7 Jul 21 14:39 ./
  60219 drwxr-xr-x  5 root  wheel  uarch          15 Aug  9 10:44 ../
2753677 -r-xr-xr-x  1 root  wheel  schg       136320 Jul 21 14:37 ld-elf.so.1*
2753678 -r-xr-xr-x  1 root  wheel  schg,uarch 136320 Jul 15 08:54 ld-elf.so.1.old*
2753472 -r-xr-xr-x  1 root  wheel  schg       111420 Jul 21 14:39 ld-elf32.so.1*
2753473 -r-xr-xr-x  1 root  wheel  schg,uarch 111436 Jun  1 12:55 ld-elf32.so.1.old*
2753469 drwxr-xr-x  2 root  wheel  uarch           8 Jul 21 14:38 resolvconf/
install: libexec/ld-elf.so.1 -> libexec/ld-elf.so.1.old
install: unlink: libexec/ld-elf.so.1.old: Operation not permitted
total 312
2753468 drwxr-xr-x  3 root  wheel  uarch           7 Aug  9 10:47 ./
  60219 drwxr-xr-x  5 root  wheel  uarch          15 Aug  9 10:44 ../
2753677 -r-xr-xr-x  1 root  wheel  uarch      136320 Jul 21 14:37 ld-elf.so.1*
2753678 -r-xr-xr-x  1 root  wheel  schg,uarch 136320 Jul 15 08:54 ld-elf.so.1.old*
2753472 -r-xr-xr-x  1 root  wheel  schg       111420 Jul 21 14:39 ld-elf32.so.1*
2753473 -r-xr-xr-x  1 root  wheel  schg,uarch 111436 Jun  1 12:55 ld-elf32.so.1.old*
2753469 drwxr-xr-x  2 root  wheel  uarch           8 Jul 21 14:38 resolvconf/

The case of failing to modify the backup losing the schg on the destination is an existing bug I am working on a patch for.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

bdrewery retitled this revision from to Fix combination of -S and -b not atomically updating the destination file..
bdrewery updated this object.
bdrewery edited the test plan for this revision. (Show Details)
bdrewery added reviewers: jhb, bapt.
This comment was removed by bdrewery.
jhb edited edge metadata.

Thanks.

This revision is now accepted and ready to land.Aug 9 2016, 7:10 PM
This revision was automatically updated to reflect the committed changes.