libotutil: Add API to create directory hierarchy recursively *and* fsync

To be really sure that any directory entries have hit disk we need to
call fsync() on the directory fd.  This API allows us to conveniently
create a directory hierarchy, fsyncing all of it along the way.
deploy: Ensure that all directories we create are fsync()d

There's two halves to this; first, when we create an hierarchy, we
need to call fsync().  Second, we need to fsync again anytime after
we've modified a directory.
checkout: fsync() directory on checkouts

We want to be really sure that our deployment roots have hit the disk.
deploy: Ensure that any modified config files are fsync()d

It really wouldn't do for one to be missing one's ssh keys for
example...
deploy: Also fsync parent directory of modified config files
deploy: Ensure .origin file is fsync()ed on disk

Along with its parent directory.
libotutil: Make use of dirfd-relative API in ot_gfile_replace_contents_fsync()

It's just more efficient.
deploy: fdatasync() bootloader configuration files

Yet more data we're writing out that needs to be sync'd.
deploy: fsync() kernel/initramfs and bootloader config parent directories

Ensure they've hit disk.
deploy: fsync() copy of /etc

This unfortunately requires reimplementing gs_shutil_cp_a(), except
while we're here, we also use the *at calls.