svn commit: r254627 - in head: bin/chflags bin/ls lib/libc/gen lib/libc/sys sys/cddl/contrib/opensolaris/uts/common/fs/zfs sys/fs/msdosfs sys/fs/smbfs sys/sys sys/ufs/ufs

Bruce Evans brde at optusnet.com.au
Thu Aug 21 04:31:23 UTC 2014


[My mail connection wasn't working back in June when I wrote this.  This
is the first of many replies to try to prevent breakage of mv.

I have now checked what happens for simple tests on ref11.  Details in
later replies.]

On Sat, 28 Jun 2014, Bruce Evans wrote:

> On Fri, 27 Jun 2014, Kenneth D. Merry wrote:
>
>> On Fri, Jun 27, 2014 at 12:48:29 -0700, Xin LI wrote:
>>> Hi,
>>> 
>>> Craig have hit an interesting issue today, where he tried to 'mv' a file
>>> from ZFS dataset to a NFS mount, 'mv' bails out because chflags failed.
>>> 
>>> I think it's probably sensible to have mv ignoring UF_ARCHIVE, and set the
>>> flag on the target unconditionally?  i.e.:
>>> 
>>> Index: mv.c
>>> ===================================================================
>>> --- mv.c (revision 267940)
>>> +++ mv.c (working copy)
>>> @@ -337,8 +337,8 @@
>>>   * on a file that we copied, i.e., that we didn't create.)
>>>   */
>>>   errno = 0;
>>> - if (fchflags(to_fd, sbp->st_flags))
>>> - if (errno != EOPNOTSUPP || sbp->st_flags != 0)
>>> + if (fchflags(to_fd, sbp->st_flags | UF_ARCHIVE))
>>> + if (errno != EOPNOTSUPP || (sbp->st_flags & ~UF_ARCHIVE) != 0)
>>>   warn("%s: set flags (was: 0%07o)", to, sbp->st_flags);
>>> 
>>>   tval[0].tv_sec = sbp->st_atime;
>> 
>> Yes, that sounds like a good way to do it.
>
> No, this is very broken.
>
> Ignoring the error is bad enough.  POSIX requires duplicating all of
> the attributes and certain error handling when they cannot be
> duplicated.  File flags aren't a POSIX attribute, but not duplicating
> or handling errors differently for them them breaks the spirit of the
> POSIX spec.
>
> Forcing the archive flag to be set on the copy is worse.  It is broken
> especially broken  if the source and target both support the archive flag,
> since it then fails to preserve the flag when it is clear on the source.
>
> The old code was bad too.  I think it usually gives the POSIX behaviour,
> but it only applies to the unusual case where only a few regular files
> are moved, and its checking if the preservation worked can be done
> better by stat()ing the result and comparing with the original.  The
> usual case (by number of files moved, if not by mv instances), is for
> moving whole directory heirarchies.  The above code is not used in that
> case.  cp -pR is used.  cp -pR is more buggy than the above in general,
> but for the chflags() its error handling is less fancy and thus stricter
> than the above, so tends to produce thousands or warnings instead of only
> 1.  More and different details in another reply.
>
> I sent the following mail to ken about this (mostly for cp -p instead of
> mv) in April, but received no reply:
>
> old> Copying files on freefall now causes annoying warnings.  This is because
> old> zfs supports UF_ARCHIVE but nfs doesn't:
> old> old> % Script started on Sat Apr  5 05:10:55 2014
> old> % pts/29:bde at freefall:~/zmsun> cp -p $l/msun/Makefile .
> old> % cp: chflags: ./Makefile: Operation not supported
> old> % pts/29:bde at freefall:~/zmsun> echo $?
> old> % 1
> old> % pts/29:bde at freefall:~/zmsun> ls -lo $l/msun/Makefile Makefile
> old> % -rw-r--r--  1 root  wheel  uarch 8610 Mar  2 11:00 
> /usr/src/lib/msun/Makefile
> old> % -rw-r--r--  1 bde   devel  -     8610 Mar  2 11:00 Makefile
> old> % pts/29:bde at freefall:~/zmsun> exit
> old> % old> % Script done on Sat Apr  5 05:11:28 2014
> old> old> cp works, but this is hard to determine since the exit status is 1. 
> Oops,
> old> that means that cp doesn't work.  It also cannot copy the more important
> old> uid and gid, but it doesn't warn about this or change the exit status to
> old> 1 for this.  Not warning is a historical hack to keep cp usable.  Not
> old> indicating the error in any other way is not good, but is also 
> historical.
> old> This is only done when chown() returns EPERM.  For chflags() on nfs, 
> we're
> old> getting EOPNOTSUPPORT for the whole syscall.
>
> So cp -pR is completely broken for use by mv for the uid and gid, but works
> almost as correctly as possibly for file flags.  POSIX has relaxed
> requirements for cp relative to mv, since cp without -p is not required
> to preserve any attributes, and cp with -p can't be expected to preserve
> all the attributes in many cases, unlike the usual case for mv where it
> is not across a file system.
>
> old> The support is useless in practice, at least on freefall, because zfs
> old> always sets UF_ARCHIVE and nothing ever clears it.  zfs sets it even
> old> for directories and symlinks.
> old> old> Also, sys/stat.h still has SF_ARCHIVED:
> old> old> % #define	UF_ARCHIVE	0x00000800	/* file needs to be 
> archived */
> old> % #define	SF_ARCHIVED	0x00010000	/* file is archived */
> old> old> It's not clear what SF_ARCHIVED means, especially since no file 
> system
> old> supports it.  The only references to it are:
> old> old> % ./fs/tmpfs/tmpfs_subr.c:	if ((flags & ~(SF_APPEND | 
> SF_ARCHIVED | SF_IMMUTABLE | SF_NOUNLINK |
> old> % ./ufs/ufs/ufs_vnops.c:		if ((vap->va_flags & ~(SF_APPEND | 
> SF_ARCHIVED | SF_IMMUTABLE |
> old> old> So applications can set this flag for ffs and tmpfs, but since the 
> fs never
> old> changes it, it is almost useless.  Perhaps we left it for compatibility
> old> in ffs.  tmpfs doesn't have anything to be compatible with.
> old> old> UF_ARCHIVE and UF_NODUMP are fairly bogus for tmpfs too.  I think 
> all they
> old> do is prevent the above error when copying files from fs's that support
> old> them.
> old> old> Bruce
>
> Attributes like file times cannot be preserved in general, and the
> checks for this are both too strict and too weak.  Too strict because
> it is impossible to preserve file times in general (utimes() cannot
> even ask to preserve sub-microsecond resolution.  POSIX file systems
> are only required to support seconds resolution.  FreeBSD supports
> some non-POSIX file systems that have worse than seconds resolution).
> Too weak because it is impossible to ask for strict preservation.
> Syscalls silently change times to something that they can represent
> or write.  Utilities don't check if the requested settings were
> actually made.  They should check, but then there are problems
> handling errors and complications configuring the utilities to do
> the sloppy preservation that they historically did.  File times are
> only a relatively simple unimportant case.
>
> Bruce

Bruce


More information about the svn-src-head mailing list