Page MenuHomeSolus

cp -a fails for symlinks when root after coreutils rebuild ("failed to preserve ownership")
Closed, ResolvedPublic

Description

After rebuilding coreutils against glibc 2.35 we now have an issue where

# cp -a this-is-a-symlink-file dst fails with the error cp: failed to preserve ownership for this-is-a-symlink-file: Operation not supported

This is causing a bunch of issues in our tooling due to exit code 1 from cp.

Here is a successful strace from coreutils rel25: P27

Here is the failing strace from coreutils rel26: P28

In the failed strace we notice that

utimensat(AT_FDCWD, "./libz.so", [{tv_sec=1649628485, tv_nsec=721821996} /* 2022-04-10T23:08:05.721821996+0100 */, {tv_sec=1649250247, tv_nsec=338613658} /* 2022-04-06T14:04:07.338613658+0100 */], AT_SYMLINK_NOFOLLOW) = 0
llistxattr("/usr/lib64/libz.so", NULL, 0) = 0
llistxattr("/usr/lib64/libz.so", 0x7ffcba1b2140, 0) = 0

No longer happens.

Build log coreutils 25: https://build.getsol.us//logs/coreutils-8.32-25.log.gz
Build log coreutils 26: https://build.getsol.us//logs/coreutils-8.32-26.log.gz

In the build log for coreutils 26 we notice that the preserve-slink-time test is failing whereas it wasn't failing before.

This is the where the error is coming from in the coreutils source:
https://github.com/coreutils/coreutils/blob/master/src/cp.c#L311

Things tried so far
Updating coreutils to 9.0
Updating acl and attr to latest versions and rebuild coreutils against them
Building coreutils with clang

Event Timeline

joebonrichie triaged this task as Unbreak Now! priority.Apr 11 2022, 12:47 PM
joebonrichie created this task.
joebonrichie moved this task from Backlog to Package Fixes on the Software board.

Updating coreutils to the latest git source, with or without Girtablulu's patch, unfortunately doesn't fix it in my testing.

In the latest buildlog we no longer have support for
checking whether chown always updates ctime... no

Any ideas for why?

@joebonrichie Can we see the config.log from the failed configure?

configure:10661: checking whether chown always updates ctime
configure:10703: x86_64-solus-linux-gcc -o conftest -mtune=generic -march=x86-64 -g2 -pipe -fPIC -Wformat -Wformat-security -D_FORTIFY_SOURCE=2 -fstack-protector-strong --param=ssp-buffer-size=32 -fasynchronous-unwind-tables -ftree-vectorize -feliminate-unused-debug-types -Wall -Wno-error -Wp,-D_REENTRANT -fno-semantic-interposition -O3 -falign-functions=32 -flto=8  -Wl,-O1 -Wl,-z,relro -Wl,-z,now -Wl,-z,max-page-size=0x1000 -Wl,-Bsymbolic-functions -Wl,--sort-common conftest.c  >&5
configure:10703: $? = 0
configure:10703: ./conftest
configure:10703: $? = 5
configure: program exited with status 5
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "GNU coreutils"
| #define PACKAGE_TARNAME "coreutils"
| #define PACKAGE_VERSION "8.32"
| #define PACKAGE_STRING "GNU coreutils 8.32"
| #define PACKAGE_BUGREPORT "bug-coreutils@gnu.org"
| #define PACKAGE_URL "https://www.gnu.org/software/coreutils/"
| #define PACKAGE "coreutils"
| #define VERSION "8.32"
| #define HAVE_STDIO_H 1
| #define HAVE_STDLIB_H 1
| #define HAVE_STRING_H 1
| #define HAVE_INTTYPES_H 1
| #define HAVE_STDINT_H 1
| #define HAVE_STRINGS_H 1
| #define HAVE_SYS_STAT_H 1
| #define HAVE_SYS_TYPES_H 1
| #define HAVE_UNISTD_H 1
| #define HAVE_ARPA_INET_H 1
| #define HAVE_FEATURES_H 1
| #define HAVE_SYS_SOCKET_H 1
| #define HAVE_SYS_PARAM_H 1
| #define HAVE_DIRENT_H 1
| #define HAVE_FNMATCH_H 1
| #define HAVE_WCTYPE_H 1
| #define HAVE_STDIO_EXT_H 1
| #define HAVE_SYS_VFS_H 1
| #define HAVE_NETDB_H 1
| #define HAVE_NETINET_IN_H 1
| #define HAVE_GETOPT_H 1
| #define HAVE_SYS_CDEFS_H 1
| #define HAVE_TERMIOS_H 1
| #define HAVE_SYS_TIME_H 1
| #define HAVE_GRP_H 1
| #define HAVE_THREADS_H 1
| #define HAVE_ICONV_H 1
| #define HAVE_LIMITS_H 1
| #define HAVE_WCHAR_H 1
| #define HAVE_LANGINFO_H 1
| #define HAVE_MATH_H 1
| #define HAVE_SYS_MMAN_H 1
| #define HAVE_SYS_STATVFS_H 1
| #define HAVE_SYS_SELECT_H 1
| #define HAVE_PTHREAD_H 1
| #define HAVE_UTMP_H 1
| #define HAVE_UTMPX_H 1
| #define HAVE_MALLOC_H 1
| #define HAVE_SYS_IOCTL_H 1
| #define HAVE_SYS_RESOURCE_H 1
| #define HAVE_SYS_UIO_H 1
| #define HAVE_SYS_UTSNAME_H 1
| #define HAVE_SYS_WAIT_H 1
| #define HAVE_UTIME_H 1
| #define HAVE_SEMAPHORE_H 1
| #define HAVE_LINUX_FALLOC_H 1
| #define HAVE_LINUX_FS_H 1
| #define HAVE_PATHS_H 1
| #define HAVE_SYS_MTIO_H 1
| #define HAVE_SYSLOG_H 1
| #define HAVE_PWD_H 1
| #define HAVE_GMP_H 1
| #define STDC_HEADERS 1
| #define __EXTENSIONS__ 1
| #define _ALL_SOURCE 1
| #define _DARWIN_C_SOURCE 1
| #define _GNU_SOURCE 1
| #define _NETBSD_SOURCE 1
| #define _OPENBSD_SOURCE 1
| #define _POSIX_PTHREAD_SEMANTICS 1
| #define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1
| #define __STDC_WANT_IEC_60559_BFP_EXT__ 1
| #define __STDC_WANT_IEC_60559_DFP_EXT__ 1
| #define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1
| #define __STDC_WANT_IEC_60559_TYPES_EXT__ 1
| #define __STDC_WANT_LIB_EXT2__ 1
| #define __STDC_WANT_MATH_SPEC_FUNCS__ 1
| #define _TANDEM_SOURCE 1
| #define _HPUX_ALT_XOPEN_SOCKET_API 1
| #define HAVE_FSEEKO 1
| #define HAVE_FCHMOD 1
| #define HAVE_PATHCONF 1
| #define HAVE_BTOWC 1
| #define HAVE_USELOCALE 1
| #define HAVE_CANONICALIZE_FILE_NAME 1
| #define HAVE_REALPATH 1
| #define HAVE_READLINKAT 1
| #define HAVE_CHOWN 1
| #define HAVE_FCHOWN 1
| #define HAVE_FCHDIR 1
| #define HAVE_FDOPENDIR 1
| #define HAVE_FACCESSAT 1
| #define HAVE_EXPLICIT_BZERO 1
| #define HAVE_POSIX_FADVISE 1
| #define HAVE_FCHMODAT 1
| #define HAVE_LCHMOD 1
| #define HAVE_FCNTL 1
| #define HAVE_SYMLINK 1
| #define HAVE_MEMPCPY 1
| #define HAVE_FNMATCH 1
| #define HAVE_ISBLANK 1
| #define HAVE_ISWCTYPE 1
| #define HAVE_MBSRTOWCS 1
| #define HAVE_WMEMCHR 1
| #define HAVE_WMEMCPY 1
| #define HAVE_WMEMPCPY 1
| #define HAVE___FPURGE 1
| #define HAVE___FREADING 1
| #define HAVE_FSTATAT 1
| #define HAVE_FSYNC 1
| #define HAVE_STRTOF 1
| #define HAVE_FTRUNCATE 1
| #define HAVE_OPENAT 1
| #define HAVE_FSTATFS 1
| #define HAVE_FUTIMENS 1
| #define HAVE_GETDELIM 1
| #define HAVE_GETDTABLESIZE 1
| #define HAVE_GETLOGIN 1
| #define HAVE_FLOCKFILE 1
| #define HAVE_FUNLOCKFILE 1
| #define HAVE_GETPASS 1
| #define HAVE___FSETLOCKING 1
| #define HAVE_GETTIMEOFDAY 1
| #define HAVE_GETUSERSHELL 1
| #define HAVE_ISWCNTRL 1
| #define HAVE_ISWBLANK 1
| #define HAVE_LSTAT 1
| #define HAVE_LINK 1
| #define HAVE_READLINK 1
| #define HAVE_LINKAT 1
| #define HAVE_MBSINIT 1
| #define HAVE_MBRTOWC 1
| #define HAVE_MBRLEN 1
| #define HAVE_ISASCII 1
| #define HAVE_MPROTECT 1
| #define HAVE_GETGROUPLIST 1
| #define HAVE_MKNOD 1
| #define HAVE_MKOSTEMP 1
| #define HAVE_MKSTEMP 1
| #define HAVE_TZSET 1
| #define HAVE_NL_LANGINFO 1
| #define HAVE_PIPE 1
| #define HAVE_PIPE2 1
| #define HAVE_PTHREAD_SIGMASK 1
| #define HAVE_UTMPNAME 1
| #define HAVE_UTMPXNAME 1
| #define HAVE_RENAMEAT 1
| #define HAVE_RENAMEAT2 1
| #define HAVE_FPATHCONF 1
| #define HAVE_SETENV 1
| #define HAVE_SETTIMEOFDAY 1
| #define HAVE_SIGACTION 1
| #define HAVE_SIGALTSTACK 1
| #define HAVE_SIGINTERRUPT 1
| #define HAVE_SNPRINTF 1
| #define HAVE_STPNCPY 1
| #define HAVE_STRDUP 1
| #define HAVE_STRERROR_R 1
| #define HAVE___XPG_STRERROR_R 1
| #define HAVE_STRNDUP 1
| #define HAVE_STRTOIMAX 1
| #define HAVE_STRTOLD 1
| #define HAVE_STRTOUMAX 1
| #define HAVE_SYMLINKAT 1
| #define HAVE_LOCALTIME_R 1
| #define HAVE_TIMEGM 1
| #define HAVE_UNLINKAT 1
| #define HAVE_UTIME 1
| #define HAVE_FUTIMES 1
| #define HAVE_FUTIMESAT 1
| #define HAVE_UTIMENSAT 1
| #define HAVE_LUTIMES 1
| #define HAVE_WCRTOMB 1
| #define HAVE_WCWIDTH 1
| #define HAVE_WCSWIDTH 1
| #define HAVE_PAUSE 1
| #define HAVE_GETEGID 1
| #define HAVE_GETRUSAGE 1
| #define HAVE_DUPLOCALE 1
| #define HAVE_NEWLOCALE 1
| #define HAVE_FREELOCALE 1
| #define HAVE_SECURE_GETENV 1
| #define HAVE_GETUID 1
| #define HAVE_GETEUID 1
| #define HAVE_GETGID 1
| #define HAVE_SLEEP 1
| #define HAVE_CATGETS 1
| #define HAVE_SHUTDOWN 1
| #define HAVE_USLEEP 1
| #define HAVE_WCTOB 1
| #define HAVE_SETRLIMIT 1
| #define HAVE_PRCTL 1
| #define HAVE_ENDGRENT 1
| #define HAVE_ENDPWENT 1
| #define HAVE_FALLOCATE 1
| #define HAVE_ISWSPACE 1
| #define HAVE_MKFIFO 1
| #define HAVE_SETGROUPS 1
| #define HAVE_SETHOSTNAME 1
| #define HAVE_SYNC 1
| #define HAVE_SYNCFS 1
| #define HAVE_SYSINFO 1
| #define HAVE_TCGETPGRP 1
| #define HAVE_FORK 1
| #define HAVE_VFORK 1
| #define HAVE_ALLOCA_H 1
| #define HAVE_ALLOCA 1
| #define D_INO_IN_DIRENT 1
| #define HAVE_LONG_FILE_NAMES 1
| #define restrict __restrict
| #define HAVE_LANGINFO_CODESET 1
| #define HAVE_WORKING_USELOCALE 1
| #define FUNC_REALPATH_WORKS 1
| #define HAVE_UNISTD_H 1
| #define HAVE_CHOWN 1
| /* end confdefs.h.  */
| 
| #include <unistd.h>
| #include <stdlib.h>
| #include <errno.h>
| #include <fcntl.h>
| #include <sys/stat.h>
| 
| int
| main (void)
| {
|     struct stat st1, st2;
|           if (close (creat ("conftest.file", 0600))) return 1;
|           if (stat ("conftest.file", &st1)) return 2;
|           sleep (1);
|           if (chown ("conftest.file", st1.st_uid, st1.st_gid)) return 3;
|           if (stat ("conftest.file", &st2)) return 4;
|           if (st2.st_ctime <= st1.st_ctime) return 5;
| 
|   ;
|   return 0;
| }

That simple program runs fine (returns 0) on both the host system and the chroot environment if compiled with cc test.c -o test.

It also runs fine when compiled with that big command outside the ./configure script...

Some progress on this. We found out if we pass gl_cv_func_chown_ctime_works=yes to configure to force enable it, it resolves the issue and the preserve-slink-time test passes once again.

The m4 check for this is 13 years old. So unsure why it is failing. See https://github.com/coreutils/gnulib/blame/3c99da63be95a3bc6cc881e1ca6c849a921569e1/m4/chown.m4#L132.

@livingsilver94 this reminds of when i had a similar issue. See https://dev.getsol.us/source/libreoffice/browse/master/files/0001-Disable-C-17-check.patch