Bug 1731756

Summary: qemu-user-static (4.0.0 and 4.1.0-rc1) fail listxattr syscall with ENOSYS "Function not implemented"
Product: [Fedora] Fedora Reporter: Marcel Bargull <marcel.bargull>
Component: qemuAssignee: Fedora Virtualization Maintainers <virt-maint>
Status: CLOSED RAWHIDE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: rawhideCC: amit, berrange, cfergeau, crobinso, dwmw2, itamar, pbonzini, rjones, virt-maint
Target Milestone: ---   
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2019-07-29 12:03:39 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description Marcel Bargull 2019-07-21 20:10:39 UTC
Description of problem:

When the listxattr syscall is requested via the Fedora 31 qemu-user-static (4.0.0 and 4.1.0-rc1),
errno is set to ENOSYS "Function not implemented".
The version from Fedora 30, qemu-user-static-3.1.0-9, works fine.

Version-Release number of selected component (if applicable):


Ran via Docker on:
$ uname -srmo                                                                                          
Linux 4.19.59-1-MANJARO x86_64 GNU/Linux
$ docker --version
Docker version 18.09.7-ce, build 2d0083d657

How reproducible:

Steps to Reproduce:

1.1. compile the following program with `gcc -x c -o ./listxattr-test`

#include <sys/xattr.h>
#include <stdio.h>
int main() {
    if ( listxattr(".", (char *) 0, 0) >= 0 )
        return 0;
    return 1;

1.2. run `qemu-x86_64-static ./listxattr-test`
     (Exits with non-zero status and prints "Function not implemented".)

2. Alternatively, run this Docker-based full reproducer:

docker run --rm fedora:31 sh -euc "$( cat <<'EOT'

dnf install -q -y gcc qemu-user-static
{ cat <<'EOF'
#include <sys/xattr.h>

#include <stdio.h>

int main() {
    if ( listxattr(".", (char *) 0, 0) >= 0 )
        return 0;
    return 1;
} | gcc -x c - -o ./listxattr-test

qemu-x86_64-static --version
set -x
qemu-x86_64-static ./listxattr-test
echo success!


Actual results:

qemu-x86_64 version 4.0.0 (qemu-4.0.0-5.fc31)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers
+ ./listxattr-test
+ qemu-x86_64-static ./listxattr-test
Function not implemented

Expected results:

qemu-x86_64 version 4.0.0 (qemu-4.0.0-5.fc31)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers
+ ./listxattr-test
+ qemu-x86_64-static ./listxattr-test
+ echo success!

Additional info:

The older qemu-user-static-3.1.0-9.fc30.x86_64 works fine.
Likewise, the QEMU build from Alpine Linux 3.10 (QEMU version 4.0.0) does not show the erroneous behavoir.
The following Dockerfile is a more elaborate reproducer that checks multiple versions from Fedora as well as the Alpine one.
(The Dockerfile's build argument `arch` was just to test whether the guest architecture (aarch64, ppc64le, or x86_64) mattered, which it did not.)

# Dockerfile:

ARG arch=x86_64

FROM fedora:30 as qemu-fedora
RUN dnf install -y /usr/bin/{curl,rpm2cpio,cpio} && dnf clean all
# Build for 4.1.0-0.1.rc1 obtained from:
#   https://koji.fedoraproject.org/koji/packageinfo?packageID=3685
#   https://koji.fedoraproject.org/koji/taskinfo?taskID=36311616
WORKDIR /opt/qemu
RUN set -eux && \
    for rpm_url in \
        'https://kojipkgs.fedoraproject.org/packages/qemu/3.1.0/9.fc30/x86_64/qemu-user-static-3.1.0-9.fc30.x86_64.rpm' \
        'https://kojipkgs.fedoraproject.org/packages/qemu/4.0.0/5.fc31/x86_64/qemu-user-static-4.0.0-5.fc31.x86_64.rpm' \
        'https://kojipkgs.fedoraproject.org//work/tasks/1616/36311616/qemu-user-static-4.1.0-0.1.rc1.fc31.x86_64.rpm' \
        ; do \
      mkdir ./tmp && cd ./tmp && \
      curl -L "${rpm_url}" \
        | rpm2cpio \
        | cpio -idm \
      && \
      version="${rpm_url}" && \
      version="${version#*/qemu-user-static-}" && \
      version="${version%.fc*}" && \
      for f in ./usr/bin/qemu-*-static ; do \
        mv "${f}" "../$( basename "${f%-static}" )-fedora-static-${version}" ; \
      done && \
      cd .. && rm -rf ./tmp ; \

FROM   amd64/alpine:3.10 as alpine-x86_64
FROM arm64v8/alpine:3.10 as alpine-aarch64
FROM ppc64le/alpine:3.10 as alpine-ppc64le

FROM alpine-x86_64 as qemu-alpine
WORKDIR /opt/qemu
RUN set -eux && \
    for arch_ in x86_64 aarch64 ppc64le ; do \
      apk add "qemu-${arch_}" && \
      cp "/usr/bin/qemu-${arch_}" "./qemu-${arch_}-alpine" ; \

FROM "alpine-${arch}" as listxattr-test
ARG arch
COPY --from=qemu-fedora "/opt/qemu/qemu-${arch}-fedora-static-4.0.0-5" "/usr/bin/qemu-${arch}-static"
RUN apk add gcc musl-dev || true
RUN set -eu && \
    echo \
'#include <sys/xattr.h>'$'\n'\
'#include <stdio.h>'$'\n'\
'int main() {'$'\n'\
'    if ( listxattr(".", (char *) 0, 0) >= 0 )'$'\n'\
'        return 0;'$'\n'\
'    perror("");'$'\n'\
'    return 1;'$'\n'\
    | gcc -x c - -static -o /opt/listxattr-test

FROM alpine-x86_64 as qemu-listxattr-bug
ARG arch
COPY --from=listxattr-test /opt/listxattr-test /opt/listxattr-test
COPY --from=qemu-alpine "/opt/qemu/qemu-${arch}-"* /opt/qemu/
COPY --from=qemu-fedora "/opt/qemu/qemu-${arch}-"* /opt/qemu/
    for qemu in /opt/qemu/* ; do \
      echo "${qemu}" && \
      "${qemu}" /opt/listxattr-test ; \
    done || true

# output of the last RUN command:
#   /opt/qemu/qemu-x86_64-alpine
#   /opt/qemu/qemu-x86_64-fedora-static-3.1.0-9
#   /opt/qemu/qemu-x86_64-fedora-static-4.0.0-5
#   Function not implemented
#   /opt/qemu/qemu-x86_64-fedora-static-4.1.0-0.1.rc1
#   Function not implemented

Comment 1 Cole Robinson 2019-07-23 19:23:14 UTC
Thanks for the report. I think we need to pass --enable-attr to qemu configure for static builds, which was dropped in some recent spec reworks. I'll do it for the next build tomorrow

Comment 2 Cole Robinson 2019-07-29 12:03:39 UTC
Should be fixed in rawhide and virt-preview now