qemu: backport 9p-darwin to v6.2.0

main
Will Cohen 2 years ago committed by Alyssa Ross
parent 36a211e1ee
commit b20f90e940
  1. 83
      pkgs/applications/virtualization/qemu/9p-ignore-noatime.patch
  2. 77
      pkgs/applications/virtualization/qemu/allow-virtfs-on-darwin.patch
  3. 54
      pkgs/applications/virtualization/qemu/default.nix
  4. 190
      pkgs/applications/virtualization/qemu/provide-fallback-for-utimensat.patch
  5. 54
      pkgs/applications/virtualization/qemu/rename-9p-util.patch

@ -1,44 +1,49 @@
commit cdc3e7eeafa9f683214d2c15d52ef384c3de6611
Author: aszlig <aszlig@nix.build>
Date: Mon Mar 18 13:21:01 2019 +0100
9pfs: Ignore O_NOATIME open flag
Since Linux 4.19, overlayfs uses the O_NOATIME flag on its lowerdir,
which in turn causes errors when the Nix store is mounted in the guest
because the file owner of the store paths typically don't match the
owner of the QEMU process.
After submitting a patch to the overlayfs mailing list[1], it turns out
that my patch was incomplete[2] and needs a bit more rework.
So instead of using an incomplete kernel patch in nixpkgs, which affects
*all* users of overlayfs, not just NixOS VM tests, I decided that for
now it's better to patch QEMU instead.
The change here really only ignores the O_NOATIME flag so that the
behaviour is similar to what NFS does. From open(2):
This flag may not be effective on all filesystems. One example is NFS,
where the server maintains the access time.
This change is therefore only temporary until the final fix lands in the
stable kernel releases.
[1]: https://www.spinics.net/lists/linux-unionfs/msg06755.html
[2]: https://www.spinics.net/lists/linux-unionfs/msg06756.html
Signed-off-by: aszlig <aszlig@nix.build>
From 9e4932ae99946b1a08ab5b5345fd2bc3486e54a5 Mon Sep 17 00:00:00 2001
From: aszlig <aszlig@nix.build>
Date: Mon, 18 Mar 2019 13:21:01 +0100
Subject: [PATCH] 9pfs: Ignore O_NOATIME open flag
Since Linux 4.19, overlayfs uses the O_NOATIME flag on its lowerdir,
which in turn causes errors when the Nix store is mounted in the guest
because the file owner of the store paths typically don't match the
owner of the QEMU process.
After submitting a patch to the overlayfs mailing list[1], it turns out
that my patch was incomplete[2] and needs a bit more rework.
So instead of using an incomplete kernel patch in nixpkgs, which affects
*all* users of overlayfs, not just NixOS VM tests, I decided that for
now it's better to patch QEMU instead.
The change here really only ignores the O_NOATIME flag so that the
behaviour is similar to what NFS does. From open(2):
This flag may not be effective on all filesystems. One example is NFS,
where the server maintains the access time.
This change is therefore only temporary until the final fix lands in the
stable kernel releases.
[1]: https://www.spinics.net/lists/linux-unionfs/msg06755.html
[2]: https://www.spinics.net/lists/linux-unionfs/msg06756.html
Signed-off-by: aszlig <aszlig@nix.build>
---
hw/9pfs/9p.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index 55821343e5..0b8425fe18 100644
index a6d6b3f835..4eb26e2294 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -127,7 +127,6 @@ static int dotl_to_open_flags(int flags)
{ P9_DOTL_LARGEFILE, O_LARGEFILE },
{ P9_DOTL_DIRECTORY, O_DIRECTORY },
{ P9_DOTL_NOFOLLOW, O_NOFOLLOW },
@@ -139,7 +139,6 @@ static int dotl_to_open_flags(int flags)
{ P9_DOTL_DSYNC, O_DSYNC },
{ P9_DOTL_FASYNC, FASYNC },
#ifndef CONFIG_DARWIN
- { P9_DOTL_NOATIME, O_NOATIME },
{ P9_DOTL_SYNC, O_SYNC },
};
/*
* On Darwin, we could map to F_NOCACHE, which is
* similar, but doesn't quite have the same
--
2.35.1

@ -0,0 +1,77 @@
From 4ca09b7cd1d42eb6b1587fed74cd4d684e31bfbe Mon Sep 17 00:00:00 2001
From: Keno Fischer <keno@juliacomputing.com>
Date: Sun, 27 Feb 2022 17:35:22 -0500
Subject: [PATCH] 9p: darwin: meson: Allow VirtFS on Darwin
To allow VirtFS on darwin, we need to check that pthread_fchdir_np is
available, which has only been available since macOS 10.12.
Additionally, virtfs_proxy_helper is disabled on Darwin. This patch
series does not currently provide an implementation of the proxy-helper,
but this functionality could be implemented later on.
Signed-off-by: Keno Fischer <keno@juliacomputing.com>
[Michael Roitzsch: - Rebase for NixOS]
Signed-off-by: Michael Roitzsch <reactorcontrol@icloud.com>
[Will Cohen: - Rebase to master]
Signed-off-by: Will Cohen <wwcohen@gmail.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
[Will Cohen: - Add check for pthread_fchdir_np to virtfs
- Add comments to patch commit
- Note that virtfs_proxy_helper does not work
on macOS
- Fully adjust meson virtfs error note to specify
macOS
- Rebase to master]
Signed-off-by: Will Cohen <wwcohen@gmail.com>
Message-Id: <20220227223522.91937-12-wwcohen@gmail.com>
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Acked-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
---
fsdev/meson.build | 1 +
meson.build | 17 +++++++++++------
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/fsdev/meson.build b/fsdev/meson.build
index adf57cc43e..b632b66348 100644
--- a/fsdev/meson.build
+++ b/fsdev/meson.build
@@ -7,6 +7,7 @@ fsdev_ss.add(when: ['CONFIG_FSDEV_9P'], if_true: files(
'qemu-fsdev.c',
), if_false: files('qemu-fsdev-dummy.c'))
softmmu_ss.add_all(when: 'CONFIG_LINUX', if_true: fsdev_ss)
+softmmu_ss.add_all(when: 'CONFIG_DARWIN', if_true: fsdev_ss)
if have_virtfs_proxy_helper
executable('virtfs-proxy-helper',
diff --git a/meson.build b/meson.build
index 2265fa409a..6d73c02903 100644
--- a/meson.build
+++ b/meson.build
@@ -1383,12 +1383,17 @@ endif
have_host_block_device = (targetos != 'darwin' or
cc.has_header('IOKit/storage/IOMedia.h'))
-have_virtfs = (targetos == 'linux' and
- have_system and
- libattr.found() and
- libcap_ng.found())
-
-have_virtfs_proxy_helper = have_virtfs and have_tools
+have_virtfs = get_option('virtfs') \
+ .require(targetos == 'linux' or targetos == 'darwin',
+ error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
+ .require(targetos == 'linux' or cc.has_function('pthread_fchdir_np'),
+ error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
+ .require(targetos == 'darwin' or (libattr.found() and libcap_ng.found()),
+ error_message: 'virtio-9p (virtfs) on Linux requires libcap-ng-devel and libattr-devel') \
+ .disable_auto_if(not have_tools and not have_system) \
+ .allowed()
+
+have_virtfs_proxy_helper = targetos != 'darwin' and have_virtfs and have_tools
if get_option('virtfs').enabled()
if not have_virtfs
--
2.35.1

@ -88,14 +88,64 @@ stdenv.mkDerivation rec {
patches = [
./fix-qemu-ga.patch
./9p-ignore-noatime.patch
# Cocoa clipboard support only works on macOS 10.14+
(fetchpatch {
url = "https://gitlab.com/qemu-project/qemu/-/commit/7e3e20d89129614f4a7b2451fe321cc6ccca3b76.diff";
sha256 = "09xz06g57wxbacic617pq9c0qb7nly42gif0raplldn5lw964xl2";
revert = true;
})
] ++ lib.optional nixosTestRunner ./force-uid0-on-9p.patch;
# 9p-darwin for 7.0 backported to 6.2.0
#
# Can generally be removed when updating derivation to 7.0. Nine of the
# patches can be drawn directly from QEMU upstream, but the second commit
# and the eleventh commit had to be modified when rebasing back to 6.2.0.
(fetchpatch {
url = "https://gitlab.com/qemu-project/qemu/-/commit/e0bd743bb2dd4985791d4de880446bdbb4e04fed.patch";
sha256 = "sha256-c6QYL3zig47fJwm6rqkqGp3E1PakVTaihvXDRebbBlQ=";
})
./rename-9p-util.patch
(fetchpatch {
url = "https://gitlab.com/qemu-project/qemu/-/commit/f41db099c71151291c269bf48ad006de9cbd9ca6.patch";
sha256 = "sha256-70/rrhZw+02JJbJ3CoW8B1GbdM4Lwb2WkUdwstYAoIQ=";
})
(fetchpatch {
url = "https://gitlab.com/qemu-project/qemu/-/commit/6b3b279bd670c6a2fa23c9049820c814f0e2c846.patch";
sha256 = "sha256-7WqklSvLirEuxTXTIMQDQhWpXnwMseJ1RumT+faq/Y8=";
})
(fetchpatch {
url = "https://gitlab.com/qemu-project/qemu/-/commit/67a71e3b71a2834d028031a92e76eb9444e423c6.patch";
sha256 = "sha256-COFm/SwfJSoSl9YDpL6ceAE8CcE4mGhsGxw1HMuL++o=";
})
(fetchpatch {
url = "https://gitlab.com/qemu-project/qemu/-/commit/38d7fd68b0c8775b5253ab84367419621aa032e6.patch";
sha256 = "sha256-iwGIzq9FWW6zpbDg/IKrp5OZpK9cgQqTRWWq8WBIHRQ=";
})
(fetchpatch {
url = "https://gitlab.com/qemu-project/qemu/-/commit/57b3910bc3513ab515296692daafd1c546f3c115.patch";
sha256 = "sha256-ybl9+umZAcQKHYL7NkGJQC0W7bccTagA9KQiFaR2LYA=";
})
(fetchpatch {
url = "https://gitlab.com/qemu-project/qemu/-/commit/b5989326f558faedd2511f29459112cced2ca8f5.patch";
sha256 = "sha256-s+O9eCgj2Ev+INjL9LY9MJBdISIdZLslI3lue2DICGM=";
})
(fetchpatch {
url = "https://gitlab.com/qemu-project/qemu/-/commit/029ed1bd9defa33a80bb40cdcd003699299af8db.patch";
sha256 = "sha256-mGqcRWcEibDJdhTRrN7ZWrMuCfUWW8vWiFj7sb2/RYo=";
})
(fetchpatch {
url = "https://gitlab.com/qemu-project/qemu/-/commit/d3671fd972cd185a6923433aa4802f54d8b62112.patch";
sha256 = "sha256-GUh5o7mbFTm/dm6CqcGdoMlC+YrV8RlcEwu/mxrfTzo=";
})
./allow-virtfs-on-darwin.patch
# QEMU upstream does not demand compatibility to pre-10.13, so 9p-darwin
# support on nix requires utimensat fallback. The patch adding this fallback
# set was removed during the process of upstreaming this functionality, and
# will still be needed in nix until the macOS SDK reaches 10.13+.
./provide-fallback-for-utimensat.patch
# Still needed indefinitely
./9p-ignore-noatime.patch
]
++ lib.optional nixosTestRunner ./force-uid0-on-9p.patch;
postPatch = ''
# Otherwise tries to ensure /var/run exists.

@ -0,0 +1,190 @@
From 70328c307001f4bb75d30d93c5bba3c3cd790c88 Mon Sep 17 00:00:00 2001
From: Keno Fischer <keno@juliacomputing.com>
Date: Sat, 16 Jun 2018 20:56:54 -0400
Subject: [PATCH] 9p: darwin: Provide fallback impl for utimensat
This function is new in Mac OS 10.13. Provide a fallback implementation
when building against older SDKs. The complication in the definition comes
having to separately handle the used SDK version and the target OS version.
- If the SDK version is too low (__MAC_10_13 not defined), utimensat is not
defined in the header, so we must not try to use it (doing so would error).
- Otherwise, if the targetted OS version is at least 10.13, we know this
function is available, so we can unconditionally call it.
- Lastly, we check for the availability of the __builtin_available macro to
potentially insert a dynamic check for this OS version. However, __builtin_available
is only available with sufficiently recent versions of clang and while all
Apple clang versions that ship with Xcode versions that support the 10.13
SDK support with builtin, we want to allow building with compilers other
than Apple clang that may not support this builtin.
Signed-off-by: Keno Fischer <keno@juliacomputing.com>
Signed-off-by: Michael Roitzsch <reactorcontrol@icloud.com>
Signed-off-by: Will Cohen <wwcohen@gmail.com>
---
hw/9pfs/9p-local.c | 2 +-
hw/9pfs/9p-util-darwin.c | 96 ++++++++++++++++++++++++++++++++++++++++
hw/9pfs/9p-util-linux.c | 6 +++
hw/9pfs/9p-util.h | 8 ++++
4 files changed, 111 insertions(+), 1 deletion(-)
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index d42ce6d8b8..b2c1fa42e1 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -1085,7 +1085,7 @@ static int local_utimensat(FsContext *s, V9fsPath *fs_path,
goto out;
}
- ret = utimensat(dirfd, name, buf, AT_SYMLINK_NOFOLLOW);
+ ret = utimensat_nofollow(dirfd, name, buf);
close_preserve_errno(dirfd);
out:
g_free(dirpath);
diff --git a/hw/9pfs/9p-util-darwin.c b/hw/9pfs/9p-util-darwin.c
index bec0253474..2fc0475292 100644
--- a/hw/9pfs/9p-util-darwin.c
+++ b/hw/9pfs/9p-util-darwin.c
@@ -95,3 +95,99 @@ int qemu_mknodat(int dirfd, const char *filename, mode_t mode, dev_t dev)
}
#endif
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+static int update_times_from_stat(int fd, struct timespec times[2],
+ int update0, int update1)
+{
+ struct stat buf;
+ int ret = fstat(fd, &buf);
+ if (ret == -1) {
+ return ret;
+ }
+ if (update0) {
+ times[0] = buf.st_atimespec;
+ }
+ if (update1) {
+ times[1] = buf.st_mtimespec;
+ }
+ return 0;
+}
+
+int utimensat_nofollow(int dirfd, const char *filename,
+ const struct timespec times_in[2])
+{
+ int ret, fd;
+ int special0, special1;
+ struct timeval futimes_buf[2];
+ struct timespec times[2];
+ memcpy(times, times_in, 2 * sizeof(struct timespec));
+
+/* Check whether we have an SDK version that defines utimensat */
+#if defined(__MAC_10_13)
+# if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_13
+# define UTIMENSAT_AVAILABLE 1
+# elif __has_builtin(__builtin_available)
+# define UTIMENSAT_AVAILABLE __builtin_available(macos 10.13, *)
+# else
+# define UTIMENSAT_AVAILABLE 0
+# endif
+ if (UTIMENSAT_AVAILABLE) {
+ return utimensat(dirfd, filename, times, AT_SYMLINK_NOFOLLOW);
+ }
+#endif
+
+ /* utimensat not available. Use futimes. */
+ fd = openat_file(dirfd, filename, O_PATH_9P_UTIL | O_NOFOLLOW, 0);
+ if (fd == -1) {
+ return -1;
+ }
+
+ special0 = times[0].tv_nsec == UTIME_OMIT;
+ special1 = times[1].tv_nsec == UTIME_OMIT;
+ if (special0 || special1) {
+ /* If both are set, nothing to do */
+ if (special0 && special1) {
+ ret = 0;
+ goto done;
+ }
+
+ ret = update_times_from_stat(fd, times, special0, special1);
+ if (ret < 0) {
+ goto done;
+ }
+ }
+
+ special0 = times[0].tv_nsec == UTIME_NOW;
+ special1 = times[1].tv_nsec == UTIME_NOW;
+ if (special0 || special1) {
+ ret = futimes(fd, NULL);
+ if (ret < 0) {
+ goto done;
+ }
+
+ /* If both are set, we are done */
+ if (special0 && special1) {
+ ret = 0;
+ goto done;
+ }
+
+ ret = update_times_from_stat(fd, times, special0, special1);
+ if (ret < 0) {
+ goto done;
+ }
+ }
+
+ futimes_buf[0].tv_sec = times[0].tv_sec;
+ futimes_buf[0].tv_usec = times[0].tv_nsec / 1000;
+ futimes_buf[1].tv_sec = times[1].tv_sec;
+ futimes_buf[1].tv_usec = times[1].tv_nsec / 1000;
+ ret = futimes(fd, futimes_buf);
+
+done:
+ close_preserve_errno(fd);
+ return ret;
+}
diff --git a/hw/9pfs/9p-util-linux.c b/hw/9pfs/9p-util-linux.c
index db451b0784..320697f347 100644
--- a/hw/9pfs/9p-util-linux.c
+++ b/hw/9pfs/9p-util-linux.c
@@ -68,3 +68,9 @@ int qemu_mknodat(int dirfd, const char *filename, mode_t mode, dev_t dev)
{
return mknodat(dirfd, filename, mode, dev);
}
+
+int utimensat_nofollow(int dirfd, const char *filename,
+ const struct timespec times[2])
+{
+ return utimensat(dirfd, filename, times, AT_SYMLINK_NOFOLLOW);
+}
diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h
index 1f74d37558..a4b002d1b5 100644
--- a/hw/9pfs/9p-util.h
+++ b/hw/9pfs/9p-util.h
@@ -36,6 +36,12 @@ static inline int qemu_lsetxattr(const char *path, const char *name,
#define qemu_lsetxattr lsetxattr
#endif
+/* Compatibility with old SDK Versions for Darwin */
+#if defined(CONFIG_DARWIN) && !defined(UTIME_NOW)
+#define UTIME_NOW -1
+#define UTIME_OMIT -2
+#endif
+
static inline void close_preserve_errno(int fd)
{
int serrno = errno;
@@ -96,6 +102,8 @@ ssize_t flistxattrat_nofollow(int dirfd, const char *filename,
char *list, size_t size);
ssize_t fremovexattrat_nofollow(int dirfd, const char *filename,
const char *name);
+int utimensat_nofollow(int dirfd, const char *filename,
+ const struct timespec times[2]);
/**
* Darwin has d_seekoff, which appears to function similarly to d_off.
--
2.35.1

@ -0,0 +1,54 @@
From 011b121d7f84c8974f03a81582cf1107249245bb Mon Sep 17 00:00:00 2001
From: Keno Fischer <keno@juliacomputing.com>
Date: Sun, 27 Feb 2022 17:35:13 -0500
Subject: [PATCH] 9p: Rename 9p-util -> 9p-util-linux
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The current file only has the Linux versions of these functions.
Rename the file accordingly and update the Makefile to only build
it on Linux. A Darwin version of these will follow later in the
series.
Signed-off-by: Keno Fischer <keno@juliacomputing.com>
[Michael Roitzsch: - Rebase for NixOS]
Signed-off-by: Michael Roitzsch <reactorcontrol@icloud.com>
Signed-off-by: Will Cohen <wwcohen@gmail.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20220227223522.91937-3-wwcohen@gmail.com>
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
---
hw/9pfs/{9p-util.c => 9p-util-linux.c} | 0
hw/9pfs/meson.build | 2 +-
2 files changed, 1 insertion(+), 1 deletion(-)
rename hw/9pfs/{9p-util.c => 9p-util-linux.c} (100%)
diff --git a/hw/9pfs/9p-util.c b/hw/9pfs/9p-util-linux.c
similarity index 100%
rename from hw/9pfs/9p-util.c
rename to hw/9pfs/9p-util-linux.c
diff --git a/hw/9pfs/meson.build b/hw/9pfs/meson.build
index 99be5d9119..1b28e70040 100644
--- a/hw/9pfs/meson.build
+++ b/hw/9pfs/meson.build
@@ -4,7 +4,6 @@ fs_ss.add(files(
'9p-posix-acl.c',
'9p-proxy.c',
'9p-synth.c',
- '9p-util.c',
'9p-xattr-user.c',
'9p-xattr.c',
'9p.c',
@@ -14,6 +13,7 @@ fs_ss.add(files(
'coth.c',
'coxattr.c',
))
+fs_ss.add(when: 'CONFIG_LINUX', if_true: files('9p-util-linux.c'))
fs_ss.add(when: 'CONFIG_XEN', if_true: files('xen-9p-backend.c'))
softmmu_ss.add_all(when: 'CONFIG_FSDEV_9P', if_true: fs_ss)
--
2.35.1
Loading…
Cancel
Save