Subject: Re: bug#79433: 9.7: cp(1): lchownat(2/3) fallback bogus?

From: Steffen Nurpmeso <[email-masked]>
Date: Fri, 12 Sep 2025 15:39:28 +0200

Hello Martin o/,

[i resort a bit]

Martin D Kealey wrote in
 <[email-masked]>:
 |On Thu, 11 Sept 2025 at 21:49, Steffen Nurpmeso <[email-masked]> wrote:
 ...
 |>   cp: failed to preserve ownership for
 |> /tmp/.pkgmk/pkg/usr/share/kbd/keymaps/i386/qwertz/sr-latin.map.gz:
 |> Operation not supported
 ...
 |>|>|cp -a is used in the makefile. The -a means no dereference and preserve
 |>|>|links and other attributes. This should not be a problem if you have
 |>|>|the same user.
 |>|>
 |>|> GNU coreutils 9.7 cp(1) is of a different opinion:
 |>|>
 |>|>   $ touch xa
 |>|>   $ ln -s xa xb
 |>|>   $ cp -a xb xc
 |>|>   cp: failed to preserve ownership for xc: Operation not supported
 |>|
 |>|No. This is security settings on your system.
 |>|
 |>|On my laptop:
 ...
 |> [.] Looking at coreutils cp.c the error comes from
 |>
 |>         if (x->preserve_ownership)
 |>           {
 |>             if (lchownat (dst_dirfd, relname, p->st.st_uid, p->st.st_gid)
 |>                 != 0)
 |>   ...
 |>                     error (0, errno, _("failed to preserve ownership for
 ...
 |>
 |>   wherever i try, and so it seems to me the GNU coreutils
 |>   lib/fchownat.c fallback implementation of lchownat() is bogus
 ...

 |It's important to note the distinction between ENOSYS “Function not 
 |implemented”, which means there's no kernel call available, and  ENOTSUP “
 |Operation not supported”, which means the system call exists but the 
 |filesystem driver doesn't implement the requested function (either 
 |generally, or not for the target object).
 |
 |If lchown exists but reports ENOTSUP, then it is extremely unlikely that 

(Like i had shown, lchown(3/2) just works.)

 |fchownat would get a different result, especially when you consider that 
 |lchown may actually be a library call that invokes fchownat.
 |
 |What filesystem underpins the files you're trying to manipulate in the 
 |example you've given? (Any chance it's NFS?)

This is BTRFS and tmpfs.  This is glibc 2.40, and Linux kernel
6.1.150.  There is no lchown* except for

  $ grep -r lchown /usr/include/
  /usr/include/llvm/Analysis/TargetLibraryInfo.def:/// int lchown(const char *path, uid_t owner, gid_t group);
  /usr/include/llvm/Analysis/TargetLibraryInfo.def:TLI_DEFINE_ENUM_INTERNAL(lchown)
  /usr/include/llvm/Analysis/TargetLibraryInfo.def:TLI_DEFINE_STRING_INTERNAL("lchown")
  /usr/include/uv.h:UV_EXTERN int uv_fs_lchown(uv_loop_t* loop,
  /usr/include/libmount/libmount.h: * filesystem mounted, but subsequent X-mount.owner=/X-mount.group= lchown(2) failed
  /usr/include/unistd.h:extern int lchown (const char *__file, __uid_t __owner, __gid_t __group)
  /usr/include/bits/syscall.h:#ifdef __NR_lchown
  /usr/include/bits/syscall.h:# define SYS_lchown __NR_lchown
  /usr/include/bits/syscall.h:#ifdef __NR_lchown32
  /usr/include/bits/syscall.h:# define SYS_lchown32 __NR_lchown32
  /usr/include/asm/unistd_x32.h:#define __NR_lchown (__X32_SYSCALL_BIT + 94)
  /usr/include/asm/unistd_64.h:#define __NR_lchown 94
  /usr/include/asm/unistd_32.h:#define __NR_lchown 16
  /usr/include/asm/unistd_32.h:#define __NR_lchown32 198
  /usr/include/python3.12/pyconfig.h:/* Define to 1 if you have the 'lchown' function. */

 |-Martin
 |
 |PS: The English descriptions of those errors are arguably swapped, but 
 |their E* symbols are clear(er).
 --End of <[email-masked]\
 .com>

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)