Bug #1130

`cp -Rp symlink-with-nohistory' fails...

Added by qhwt+dfly over 5 years ago. Updated about 5 years ago.

Status:NewStart date:
Priority:NormalDue date:
Assignee:qhwt+dfly% Done:

0%

Category:-
Target version:-

Description

Hello.

How it fails:
$ mkdir test test2
$ chflags nohistory test
$ chflags history test2 # to make sure test2 doesn't have nohistory
$ ln -s foo test/bar # this creates a symlink with nohistory set
$ cp -Rp test/bar test2
cp: chflags: test2/bar: Function not implemented

Why does that matter:
installation of postfix fails (I know makedefs barfs first, but that's
another story, and perhaps someone else's working on it). I have my
${WRKDIR} on a HAMMER PFS with nohistory flag set. On the other hand
${PREFIX} (=/usr/pkg) has no nohistory set on it. And ${WRKDIR} and
${PREFIX} are on different partitions. I don't think this is very odd
configuration, as you want your ${WRKDIR} on a big partition but don't
want to retain the history, while you want to keep your ${PREFIX} on
a UFS filesystem to be very conservative, or at least retain history.

There's the following code in postfix-install script, which is responsible
for the installation:

compare_or_symlink() {
:

ln -s $link $tempdir/junk || exit 1
mv -f $tempdir/junk $2 || {

$tempdir points to somewhere under ${WRKDIR}, so it has nohistory flag set,
so symlinks get created with nohistory flag set, then mv'ed to
${PREFIX}/*bin. Since ${WRKDIR} and ${PREFIX}/*bin are in different
partitions, mv internally invokes `cp -PRp' to perform the copy
across partitions, then fails.
Currently there are three workarounds for this problem(known to me):
A) run `bmake install' twice, B) set nohistory flag on ${PREFIX}/*, or
C) patch cp to special case the history flags rather than let it
unconditionally refuse to chflags() on a symlink.

But: why does cp refuse to set file flags on a symlink in the first place?

History

#1 Updated by dillon over 5 years ago

: ln -s $link $tempdir/junk || exit 1
: mv -f $tempdir/junk $2 || {
:
:$tempdir points to somewhere under ${WRKDIR}, so it has nohistory flag set,
:so symlinks get created with nohistory flag set, then mv'ed to
:${PREFIX}/*bin. Since ${WRKDIR} and ${PREFIX}/*bin are in different
:partitions, mv internally invokes `cp -PRp' to perform the copy
:across partitions, then fails.
:Currently there are three workarounds for this problem(known to me):
:A) run `bmake install' twice, B) set nohistory flag on ${PREFIX}/*, or
:C) patch cp to special case the history flags rather than let it
: unconditionally refuse to chflags() on a symlink.
:
:But: why does cp refuse to set file flags on a symlink in the first place?

It isn't possible to set the flags on a symlink. There is no
lchflags() system call. I think it would be fairly easy to add
a lchflags() though any use of such a call would not be backwards
compatible to older systems.

A normal chflags() call on a symlink would try to dive the link, just
like chmod() and chown() do.

This brings up another issue with regards to 'nohistory', that being
the problem of programs such as cp and mv trying to copy the flag
and resulting in files being marked nohistory that you might not
otherwise want marked nohistory. It could very well be that the only
solution is to add a PFS-wide nohistory flag and not use chflags for
that purpose.

-Matt
Matthew Dillon
<>

#2 Updated by dillon over 5 years ago

::A) run `bmake install' twice, B) set nohistory flag on ${PREFIX}/*, or
::C) patch cp to special case the history flags rather than let it
:: unconditionally refuse to chflags() on a symlink.
::
::But: why does cp refuse to set file flags on a symlink in the first place?

I think for now cp should probably refuse to chflags() a symlink but
otherwise work the same and still generate a 0 exit code.

-Matt

#3 Updated by corecode about 5 years ago

is this resolved?

#4 Updated by qhwt+dfly about 5 years ago

yes, committed as 3d6b90ba on -DEVELOPMENT, or 6fab5bd4 on 2.0-RELEASE.
However, now that we can set file flags on symlinks, I'd change cp
to inherit them as well instead of silently ignoring it, what do
people think?

#5 Updated by dillon about 5 years ago

:YONETANI Tomokazu <> added the comment:
:
:yes, committed as 3d6b90ba on -DEVELOPMENT, or 6fab5bd4 on 2.0-RELEASE.
:However, now that we can set file flags on symlinks, I'd change cp
:to inherit them as well instead of silently ignoring it, what do
:people think?
:
:----------
:assignedto: -> qhwt+dfly
:status: chatting -> resolved

As long as a new-built cp still works on older systems that do
not have the system call (i.e. doesn't fault and exit due to the
missing system call).

This may be the right time to change missing system call errors
(ENOSYS) to not generate a signal any more, like linux.

-Matt
Matthew Dillon
<>

Also available in: Atom PDF