Fix cp not to give chflags error on NFS

Bruce Evans brde at optusnet.com.au
Sat Apr 1 18:16:53 UTC 2017


On Sat, 1 Apr 2017, Eitan Adler wrote:

> +freebsd-standards for folks that know more than I do
>
> On 1 April 2017 at 08:54, Lewis Donzis <lew at perftech.com> wrote:
>> It's fairly annoying that cp has no way to suppress the chflags error when the destination file is on an NFS mount.  A bigger problem than the error message is that it returns exit status 1, which causes things like make to fail when there really was no error.
>>
>> What do you think about the following change to /usr/src/bin/cp/utils.c:
>>
>> 398c398
>> <               if (fdval ?
>> ---
>>>               if ((fdval ?
>> 401c401
>> <                   chflags(to.p_path, fs->st_flags))) {
>> ---
>>>                   chflags(to.p_path, fs->st_flags))) && errno != ENOTSUP) {
>>
>> which simply ignores the error if the destination filesystem doesn't support chflags?

This would break cp.

Some corresponding breakage is mv has been committed, but it is so broken
that it has no effect in the usual case where there is a chflags() error.
IIRC, the usual case is mv of a directory (tree) across file systems.
That is done using cp -pR (although cp has bugs like snapping hard links
than make it unsuitable for that), so the error is detected as above.
IIRC, mv handles the case of moving single files across file systems, and
breaks it in a more sophisticated way than just ignoring the error.

> I believe POSIX requires this error:
> http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cp.html
>
> ===
> The file permission bits and the S_ISUID and S_ISGID bits. Other,
> implementation-defined, bits may be duplicated as well. If this
> duplication fails for any reason, cp shall write a diagnostic message
> to standard error.
> ===

File flags are an extension, so POSIX doesn't require anything for them.
In the above it just allows the implementation to duplicate.  This
allowance is not quite vacuous, since it requires the diagnostic if
for failure to duplicate the implementation-defined bits, and disallows
duplication of bits unless the implementation defines (that is, documents)
that it attempts to duplicate them.

mv also has the special handling for setugid bits.  This is for security.
Some file flags are important for security too, so errors duplicating them
are more important than most errors and should not be silently ignored.

POSIX in 2001 also requires mv to duplicate file times.  This is impossible
in many cases, at least with file times that POSIX didn't support in 2001,
since the source file time might have more precision than the target can
represent.  Some fuzziness must be allowed.  I think later versions of
POSIX specify some fuzziness.  But an application like make might need
exact duplication of nanoseconds.

msdosfs silently ignores some errors but not others.  It often gets this
backwards.  For file times, some of the file systems that it supports
can only represent times to the nearest 2 seconds, so they cannot duplicate
even POSIX-2001 seconds resolution.  msdosfs silently rounds to 2-second
boundaries and reports successful duplication.  This is not very good
error handling.  cp and mv need to know if the file system will silently
round, and if not they need to read back the time to see if it was
duplicated.  The check should be optional.  Similarly for most attributes,
but default to checking for almost everything, or everything including
file times.

I use an application 'cpattrs' for comparing and duplicating attributes.
Its args specify which attributes to duplicate.  File times can be
rounded before duplication or compared fuzzily.

> We can possibly define "implementation defined bits" to not include
> other flags if the flags are unsupported on the destination filesystem
> but this seems weird to me.

Technically, not if you try to copy the bits, and it is too easy for
the user to forget which file systems support file flags and whether
the source has any important ones, unless at least 1 diagnostic is
printed.

Anyway, some flags are too important to ignore errors for.  The bug
in mv is to ignore fails mainly for copying the archive flag.  This
is a fairly unimportant flag.  cpattrs allows specifiying which
attributes to compare and copy, but it doesn't support specifying
individual bits in flags.

nfs should support file flags iff the server does.  Unfortunately, there
is no protocol to set them (at least in nfs3).

Bruce


More information about the freebsd-bugs mailing list