uboot: (firmwareOdroidC2/C4) don't invoke patch tool, use patches = [] instead
https://github.com/NixOS/nixpkgs/blob/master/pkgs/stdenv/generic/setup.sh#L948 this can do it nicely. Signed-off-by: Anton Arapov <anton@deadbeef.mx>
This commit is contained in:
commit
56de2bcd43
30691 changed files with 3076956 additions and 0 deletions
79
pkgs/applications/virtualization/qemu/binfmt-p-wrapper.c
Normal file
79
pkgs/applications/virtualization/qemu/binfmt-p-wrapper.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
// This is a tiny wrapper that converts the extra arv[0] argument
|
||||
// from binfmt-misc with the P flag enabled to QEMU parameters.
|
||||
// It also prevents LD_* environment variables from being applied
|
||||
// to QEMU itself.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef TARGET_QEMU
|
||||
#error "Define TARGET_QEMU to be the path to the qemu-user binary (e.g., -DTARGET_QEMU=\"/full/path/to/qemu-riscv64\")"
|
||||
#endif
|
||||
|
||||
extern char **environ;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "%s: This should be run as the binfmt interpreter with the P flag\n", argv[0]);
|
||||
fprintf(stderr, "%s: My preconfigured qemu-user binary: %s\n", argv[0], TARGET_QEMU);
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t environ_count = 0;
|
||||
for (char **cur = environ; *cur != NULL; ++cur) {
|
||||
environ_count++;
|
||||
}
|
||||
|
||||
size_t new_argc = 3;
|
||||
size_t new_argv_alloc = argc + 2 * environ_count + 2; // [ "-E", env ] for each LD_* env + [ "-0", argv0 ]
|
||||
char **new_argv = (char**)malloc((new_argv_alloc + 1) * sizeof(char*));
|
||||
if (!new_argv) {
|
||||
fprintf(stderr, "FATAL: Failed to allocate new argv array\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
new_argv[0] = TARGET_QEMU;
|
||||
new_argv[1] = "-0";
|
||||
new_argv[2] = argv[2];
|
||||
|
||||
// Pass all LD_ env variables as -E and strip them in `new_environ`
|
||||
size_t new_environc = 0;
|
||||
char **new_environ = (char**)malloc((environ_count + 1) * sizeof(char*));
|
||||
if (!new_environ) {
|
||||
fprintf(stderr, "FATAL: Failed to allocate new environ array\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
for (char **cur = environ; *cur != NULL; ++cur) {
|
||||
if (strncmp("LD_", *cur, 3) == 0) {
|
||||
new_argv[new_argc++] = "-E";
|
||||
new_argv[new_argc++] = *cur;
|
||||
} else {
|
||||
new_environ[new_environc++] = *cur;
|
||||
}
|
||||
}
|
||||
new_environ[new_environc] = NULL;
|
||||
|
||||
size_t new_arg_start = new_argc;
|
||||
new_argc += argc - 3 + 2; // [ "--", full_binary_path ]
|
||||
|
||||
if (argc > 3) {
|
||||
memcpy(&new_argv[new_arg_start + 2], &argv[3], (argc - 3) * sizeof(char**));
|
||||
}
|
||||
|
||||
new_argv[new_arg_start] = "--";
|
||||
new_argv[new_arg_start + 1] = argv[1];
|
||||
new_argv[new_argc] = NULL;
|
||||
|
||||
#ifdef DEBUG
|
||||
for (size_t i = 0; i < new_argc; ++i) {
|
||||
fprintf(stderr, "argv[%zu] = %s\n", i, new_argv[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
return execve(new_argv[0], new_argv, new_environ);
|
||||
}
|
||||
|
||||
// vim: et:ts=4:sw=4
|
||||
31
pkgs/applications/virtualization/qemu/binfmt-p-wrapper.nix
Normal file
31
pkgs/applications/virtualization/qemu/binfmt-p-wrapper.nix
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# binfmt preserve-argv[0] wrapper
|
||||
#
|
||||
# More details in binfmt-p-wrapper.c
|
||||
#
|
||||
# The wrapper has to be static so LD_* environment variables
|
||||
# cannot affect the execution of the wrapper itself.
|
||||
|
||||
{ lib, stdenv, pkgsStatic, enableDebug ? false }:
|
||||
|
||||
name: emulator:
|
||||
|
||||
pkgsStatic.stdenv.mkDerivation {
|
||||
inherit name;
|
||||
|
||||
src = ./binfmt-p-wrapper.c;
|
||||
|
||||
dontUnpack = true;
|
||||
dontInstall = true;
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
mkdir -p $out/bin
|
||||
$CC -o $out/bin/${name} -static -std=c99 -O2 \
|
||||
-DTARGET_QEMU=\"${emulator}\" \
|
||||
${lib.optionalString enableDebug "-DDEBUG"} \
|
||||
$src
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
}
|
||||
268
pkgs/applications/virtualization/qemu/default.nix
Normal file
268
pkgs/applications/virtualization/qemu/default.nix
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
{ lib, stdenv, fetchurl, fetchpatch, python3, python3Packages, zlib, pkg-config, glib, buildPackages
|
||||
, perl, pixman, vde2, alsa-lib, texinfo, flex
|
||||
, bison, lzo, snappy, libaio, libtasn1, gnutls, nettle, curl, ninja, meson, sigtool
|
||||
, makeWrapper, runtimeShell, removeReferencesTo
|
||||
, attr, libcap, libcap_ng, socat
|
||||
, CoreServices, Cocoa, Hypervisor, rez, setfile
|
||||
, guestAgentSupport ? with stdenv.hostPlatform; isLinux || isSunOS || isWindows
|
||||
, numaSupport ? stdenv.isLinux && !stdenv.isAarch32, numactl
|
||||
, seccompSupport ? stdenv.isLinux, libseccomp
|
||||
, alsaSupport ? lib.hasSuffix "linux" stdenv.hostPlatform.system && !nixosTestRunner
|
||||
, pulseSupport ? !stdenv.isDarwin && !nixosTestRunner, libpulseaudio
|
||||
, sdlSupport ? !stdenv.isDarwin && !nixosTestRunner, SDL2, SDL2_image
|
||||
, jackSupport ? !stdenv.isDarwin && !nixosTestRunner, libjack2
|
||||
, gtkSupport ? !stdenv.isDarwin && !xenSupport && !nixosTestRunner, gtk3, gettext, vte, wrapGAppsHook
|
||||
, vncSupport ? !nixosTestRunner, libjpeg, libpng
|
||||
, smartcardSupport ? !nixosTestRunner, libcacard
|
||||
, spiceSupport ? !stdenv.isDarwin && !nixosTestRunner, spice, spice-protocol
|
||||
, ncursesSupport ? !nixosTestRunner, ncurses
|
||||
, usbredirSupport ? spiceSupport, usbredir
|
||||
, xenSupport ? false, xen
|
||||
, cephSupport ? false, ceph
|
||||
, glusterfsSupport ? false, glusterfs, libuuid
|
||||
, openGLSupport ? sdlSupport, mesa, libepoxy, libdrm
|
||||
, virglSupport ? openGLSupport, virglrenderer
|
||||
, libiscsiSupport ? true, libiscsi
|
||||
, smbdSupport ? false, samba
|
||||
, tpmSupport ? true
|
||||
, uringSupport ? stdenv.isLinux, liburing
|
||||
, hostCpuOnly ? false
|
||||
, hostCpuTargets ? (if hostCpuOnly
|
||||
then (lib.optional stdenv.isx86_64 "i386-softmmu"
|
||||
++ ["${stdenv.hostPlatform.qemuArch}-softmmu"])
|
||||
else null)
|
||||
, nixosTestRunner ? false
|
||||
, doCheck ? false
|
||||
, qemu # for passthru.tests
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "qemu"
|
||||
+ lib.optionalString xenSupport "-xen"
|
||||
+ lib.optionalString hostCpuOnly "-host-cpu-only"
|
||||
+ lib.optionalString nixosTestRunner "-for-vm-tests";
|
||||
version = "7.0.0";
|
||||
|
||||
src = fetchurl {
|
||||
url= "https://download.qemu.org/qemu-${version}.tar.xz";
|
||||
sha256 = "sha256-9rN1x5UfcoQCeYsLqrsthkeMpT1Eztvvq74cRr9G+Dk=";
|
||||
};
|
||||
|
||||
depsBuildBuild = [ buildPackages.stdenv.cc ];
|
||||
|
||||
nativeBuildInputs = [ makeWrapper removeReferencesTo pkg-config flex bison meson ninja perl python3 python3Packages.sphinx python3Packages.sphinx_rtd_theme ]
|
||||
++ lib.optionals gtkSupport [ wrapGAppsHook ]
|
||||
++ lib.optionals stdenv.isDarwin [ sigtool ];
|
||||
|
||||
buildInputs = [ zlib glib perl pixman
|
||||
vde2 texinfo lzo snappy libtasn1
|
||||
gnutls nettle curl
|
||||
]
|
||||
++ lib.optionals ncursesSupport [ ncurses ]
|
||||
++ lib.optionals stdenv.isDarwin [ CoreServices Cocoa Hypervisor rez setfile ]
|
||||
++ lib.optionals seccompSupport [ libseccomp ]
|
||||
++ lib.optionals numaSupport [ numactl ]
|
||||
++ lib.optionals alsaSupport [ alsa-lib ]
|
||||
++ lib.optionals pulseSupport [ libpulseaudio ]
|
||||
++ lib.optionals sdlSupport [ SDL2 SDL2_image ]
|
||||
++ lib.optionals jackSupport [ libjack2 ]
|
||||
++ lib.optionals gtkSupport [ gtk3 gettext vte ]
|
||||
++ lib.optionals vncSupport [ libjpeg libpng ]
|
||||
++ lib.optionals smartcardSupport [ libcacard ]
|
||||
++ lib.optionals spiceSupport [ spice-protocol spice ]
|
||||
++ lib.optionals usbredirSupport [ usbredir ]
|
||||
++ lib.optionals stdenv.isLinux [ libaio libcap_ng libcap attr ]
|
||||
++ lib.optionals xenSupport [ xen ]
|
||||
++ lib.optionals cephSupport [ ceph ]
|
||||
++ lib.optionals glusterfsSupport [ glusterfs libuuid ]
|
||||
++ lib.optionals openGLSupport [ mesa libepoxy libdrm ]
|
||||
++ lib.optionals virglSupport [ virglrenderer ]
|
||||
++ lib.optionals libiscsiSupport [ libiscsi ]
|
||||
++ lib.optionals smbdSupport [ samba ]
|
||||
++ lib.optionals uringSupport [ liburing ];
|
||||
|
||||
dontUseMesonConfigure = true; # meson's configurePhase isn't compatible with qemu build
|
||||
|
||||
outputs = [ "out" ] ++ lib.optional guestAgentSupport "ga";
|
||||
# On aarch64-linux we would shoot over the Hydra's 2G output limit.
|
||||
separateDebugInfo = !(stdenv.isAarch64 && stdenv.isLinux);
|
||||
|
||||
patches = [
|
||||
./fix-qemu-ga.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
|
||||
# Cocoa clipboard support only works on macOS 10.14+
|
||||
./revert-ui-cocoa-add-clipboard-support.patch
|
||||
# Standard about panel requires AppKit and macOS 10.13+
|
||||
(fetchpatch {
|
||||
url = "https://gitlab.com/qemu-project/qemu/-/commit/99eb313ddbbcf73c1adcdadceba1423b691c6d05.diff";
|
||||
sha256 = "sha256-gTRf9XENAfbFB3asYCXnw4OV4Af6VE1W56K2xpYDhgM=";
|
||||
revert = true;
|
||||
})
|
||||
# Workaround for upstream issue with nested virtualisation: https://gitlab.com/qemu-project/qemu/-/issues/1008
|
||||
(fetchpatch {
|
||||
url = "https://gitlab.com/qemu-project/qemu/-/commit/3e4546d5bd38a1e98d4bd2de48631abf0398a3a2.diff";
|
||||
sha256 = "sha256-oC+bRjEHixv1QEFO9XAm4HHOwoiT+NkhknKGPydnZ5E=";
|
||||
revert = true;
|
||||
})
|
||||
# make nixos tests that boot from USB more stable
|
||||
# https://lists.nongnu.org/archive/html/qemu-devel/2022-05/msg01484.html
|
||||
(fetchpatch {
|
||||
url = "https://gitlab.com/raboof/qemu/-/commit/3fb5e8fe4434130b1167a995b2a01c077cca2cd5.patch";
|
||||
sha256 = "sha256-evzrN3i4ntc/AFG0C0rezQpQbWcnx74nXO+5DLErX8o=";
|
||||
})
|
||||
]
|
||||
++ lib.optional nixosTestRunner ./force-uid0-on-9p.patch;
|
||||
|
||||
postPatch = ''
|
||||
# Otherwise tries to ensure /var/run exists.
|
||||
sed -i "/install_subdir('run', install_dir: get_option('localstatedir'))/d" \
|
||||
qga/meson.build
|
||||
|
||||
# glibc 2.33 compat fix: if `has_statx = true` is set, `tools/virtiofsd/passthrough_ll.c` will
|
||||
# rely on `stx_mnt_id`[1] which is not part of glibc's `statx`-struct definition.
|
||||
#
|
||||
# `has_statx` will be set to `true` if a simple C program which uses a few `statx`
|
||||
# consts & struct fields successfully compiles. It seems as this only builds on glibc-2.33
|
||||
# since most likely[2] and because of that, the problematic code-path will be used.
|
||||
#
|
||||
# [1] https://github.com/torvalds/linux/commit/fa2fcf4f1df1559a0a4ee0f46915b496cc2ebf60#diff-64bab5a0a3fcb55e1a6ad77b1dfab89d2c9c71a770a07ecf44e6b82aae76a03a
|
||||
# [2] https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=io/bits/statx-generic.h;h=c34697e3c1fd79cddd60db294302e461ed8db6e2;hp=7a09e94be2abb92d2df612090c132e686a24d764;hb=88a2cf6c4bab6e94a65e9c0db8813709372e9180;hpb=c4e4b2e149705559d28b16a9b47ba2f6142d6a6c
|
||||
substituteInPlace meson.build \
|
||||
--replace 'has_statx = cc.links(statx_test)' 'has_statx = false'
|
||||
'';
|
||||
|
||||
preConfigure = ''
|
||||
unset CPP # intereferes with dependency calculation
|
||||
# this script isn't marked as executable b/c it's indirectly used by meson. Needed to patch its shebang
|
||||
chmod +x ./scripts/shaderinclude.pl
|
||||
patchShebangs .
|
||||
# avoid conflicts with libc++ include for <version>
|
||||
mv VERSION QEMU_VERSION
|
||||
substituteInPlace configure \
|
||||
--replace '$source_path/VERSION' '$source_path/QEMU_VERSION'
|
||||
substituteInPlace meson.build \
|
||||
--replace "'VERSION'" "'QEMU_VERSION'"
|
||||
'';
|
||||
|
||||
configureFlags = [
|
||||
"--disable-strip" # We'll strip ourselves after separating debug info.
|
||||
"--enable-docs"
|
||||
"--enable-tools"
|
||||
"--localstatedir=/var"
|
||||
"--sysconfdir=/etc"
|
||||
# Always use our Meson, not the bundled version, which doesn't
|
||||
# have our patches and will be subtly broken because of that.
|
||||
"--meson=meson"
|
||||
"--cross-prefix=${stdenv.cc.targetPrefix}"
|
||||
"--cpu=${stdenv.hostPlatform.uname.processor}"
|
||||
(lib.enableFeature guestAgentSupport "guest-agent")
|
||||
] ++ lib.optional numaSupport "--enable-numa"
|
||||
++ lib.optional seccompSupport "--enable-seccomp"
|
||||
++ lib.optional smartcardSupport "--enable-smartcard"
|
||||
++ lib.optional spiceSupport "--enable-spice"
|
||||
++ lib.optional usbredirSupport "--enable-usb-redir"
|
||||
++ lib.optional (hostCpuTargets != null) "--target-list=${lib.concatStringsSep "," hostCpuTargets}"
|
||||
++ lib.optional stdenv.isDarwin "--enable-cocoa"
|
||||
++ lib.optional stdenv.isDarwin "--enable-hvf"
|
||||
++ lib.optional stdenv.isLinux "--enable-linux-aio"
|
||||
++ lib.optional gtkSupport "--enable-gtk"
|
||||
++ lib.optional xenSupport "--enable-xen"
|
||||
++ lib.optional cephSupport "--enable-rbd"
|
||||
++ lib.optional glusterfsSupport "--enable-glusterfs"
|
||||
++ lib.optional openGLSupport "--enable-opengl"
|
||||
++ lib.optional virglSupport "--enable-virglrenderer"
|
||||
++ lib.optional tpmSupport "--enable-tpm"
|
||||
++ lib.optional libiscsiSupport "--enable-libiscsi"
|
||||
++ lib.optional smbdSupport "--smbd=${samba}/bin/smbd"
|
||||
++ lib.optional uringSupport "--enable-linux-io-uring";
|
||||
|
||||
dontWrapGApps = true;
|
||||
|
||||
# QEMU attaches entitlements with codesign and strip removes those,
|
||||
# voiding the entitlements and making it non-operational.
|
||||
# The alternative is to re-sign with entitlements after stripping:
|
||||
# * https://github.com/qemu/qemu/blob/v6.1.0/scripts/entitlement.sh#L25
|
||||
dontStrip = stdenv.isDarwin;
|
||||
|
||||
postFixup = ''
|
||||
# the .desktop is both invalid and pointless
|
||||
rm -f $out/share/applications/qemu.desktop
|
||||
'' + lib.optionalString guestAgentSupport ''
|
||||
# move qemu-ga (guest agent) to separate output
|
||||
mkdir -p $ga/bin
|
||||
mv $out/bin/qemu-ga $ga/bin/
|
||||
ln -s $ga/bin/qemu-ga $out/bin
|
||||
remove-references-to -t $out $ga/bin/qemu-ga
|
||||
'' + lib.optionalString gtkSupport ''
|
||||
# wrap GTK Binaries
|
||||
for f in $out/bin/qemu-system-*; do
|
||||
wrapGApp $f
|
||||
done
|
||||
'';
|
||||
preBuild = "cd build";
|
||||
|
||||
# tests can still timeout on slower systems
|
||||
inherit doCheck;
|
||||
checkInputs = [ socat ];
|
||||
preCheck = ''
|
||||
# time limits are a little meagre for a build machine that's
|
||||
# potentially under load.
|
||||
substituteInPlace ../tests/unit/meson.build \
|
||||
--replace 'timeout: slow_tests' 'timeout: 50 * slow_tests'
|
||||
substituteInPlace ../tests/qtest/meson.build \
|
||||
--replace 'timeout: slow_qtests' 'timeout: 50 * slow_qtests'
|
||||
substituteInPlace ../tests/fp/meson.build \
|
||||
--replace 'timeout: 90)' 'timeout: 300)'
|
||||
|
||||
# point tests towards correct binaries
|
||||
substituteInPlace ../tests/unit/test-qga.c \
|
||||
--replace '/bin/echo' "$(type -P echo)"
|
||||
substituteInPlace ../tests/unit/test-io-channel-command.c \
|
||||
--replace '/bin/socat' "$(type -P socat)"
|
||||
|
||||
# combined with a long package name, some temp socket paths
|
||||
# can end up exceeding max socket name len
|
||||
substituteInPlace ../tests/qtest/bios-tables-test.c \
|
||||
--replace 'qemu-test_acpi_%s_tcg_%s' '%s_%s'
|
||||
|
||||
# get-fsinfo attempts to access block devices, disallowed by sandbox
|
||||
sed -i -e '/\/qga\/get-fsinfo/d' -e '/\/qga\/blacklist/d' \
|
||||
../tests/unit/test-qga.c
|
||||
'' + lib.optionalString stdenv.isDarwin ''
|
||||
# skip test that stalls on darwin, perhaps due to subtle differences
|
||||
# in fifo behaviour
|
||||
substituteInPlace ../tests/unit/meson.build \
|
||||
--replace "'test-io-channel-command'" "#'test-io-channel-command'"
|
||||
'';
|
||||
|
||||
# Add a ‘qemu-kvm’ wrapper for compatibility/convenience.
|
||||
postInstall = ''
|
||||
ln -s $out/libexec/virtiofsd $out/bin
|
||||
ln -s $out/bin/qemu-system-${stdenv.hostPlatform.qemuArch} $out/bin/qemu-kvm
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
qemu-system-i386 = "bin/qemu-system-i386";
|
||||
tests = {
|
||||
qemu-tests = qemu.override { doCheck = true; };
|
||||
};
|
||||
};
|
||||
|
||||
# Builds in ~3h with 2 cores, and ~20m with a big-parallel builder.
|
||||
requiredSystemFeatures = [ "big-parallel" ];
|
||||
|
||||
meta = with lib; {
|
||||
homepage = "http://www.qemu.org/";
|
||||
description = "A generic and open source machine emulator and virtualizer";
|
||||
license = licenses.gpl2Plus;
|
||||
mainProgram = "qemu-kvm";
|
||||
maintainers = with maintainers; [ eelco qyliss ];
|
||||
platforms = platforms.unix;
|
||||
priority = 10; # Prefer virtiofsd from the virtiofsd package.
|
||||
};
|
||||
}
|
||||
36
pkgs/applications/virtualization/qemu/fix-qemu-ga.patch
Normal file
36
pkgs/applications/virtualization/qemu/fix-qemu-ga.patch
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
diff -Naur a/qga/commands-posix.c b/qga/commands-posix.c
|
||||
--- a/qga/commands-posix.c
|
||||
+++ b/qga/commands-posix.c
|
||||
@@ -109,6 +109,8 @@
|
||||
reopen_fd_to_null(1);
|
||||
reopen_fd_to_null(2);
|
||||
|
||||
+ execle("/run/current-system/sw/bin/shutdown", "shutdown", "-h", shutdown_flag, "+0",
|
||||
+ "hypervisor initiated shutdown", (char*)NULL, environ);
|
||||
execle("/sbin/shutdown", "shutdown", "-h", shutdown_flag, "+0",
|
||||
"hypervisor initiated shutdown", (char*)NULL, environ);
|
||||
_exit(EXIT_FAILURE);
|
||||
@@ -157,11 +159,13 @@
|
||||
pid_t pid;
|
||||
Error *local_err = NULL;
|
||||
struct timeval tv;
|
||||
+ static const char hwclock_path_nix[] = "/run/current-system/sw/bin/hwclock";
|
||||
static const char hwclock_path[] = "/sbin/hwclock";
|
||||
static int hwclock_available = -1;
|
||||
|
||||
if (hwclock_available < 0) {
|
||||
- hwclock_available = (access(hwclock_path, X_OK) == 0);
|
||||
+ hwclock_available = (access(hwclock_path_nix, X_OK) == 0) ||
|
||||
+ (access(hwclock_path, X_OK) == 0);
|
||||
}
|
||||
|
||||
if (!hwclock_available) {
|
||||
@@ -207,6 +211,8 @@
|
||||
|
||||
/* Use '/sbin/hwclock -w' to set RTC from the system time,
|
||||
* or '/sbin/hwclock -s' to set the system time from RTC. */
|
||||
+ execle(hwclock_path_nix, "hwclock", has_time ? "-w" : "-s",
|
||||
+ NULL, environ);
|
||||
execle(hwclock_path, "hwclock", has_time ? "-w" : "-s",
|
||||
NULL, environ);
|
||||
_exit(EXIT_FAILURE);
|
||||
81
pkgs/applications/virtualization/qemu/force-uid0-on-9p.patch
Normal file
81
pkgs/applications/virtualization/qemu/force-uid0-on-9p.patch
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
|
||||
index 45e9a1f9b0..494ee00c66 100644
|
||||
--- a/hw/9pfs/9p-local.c
|
||||
+++ b/hw/9pfs/9p-local.c
|
||||
@@ -84,6 +84,23 @@ static void unlinkat_preserve_errno(int dirfd, const char *path, int flags)
|
||||
|
||||
#define VIRTFS_META_DIR ".virtfs_metadata"
|
||||
|
||||
+static int is_in_store_path(const char *path)
|
||||
+{
|
||||
+ static char *store_path = NULL;
|
||||
+ int store_path_len = -1;
|
||||
+
|
||||
+ if (store_path_len == -1) {
|
||||
+ if ((store_path = getenv("NIX_STORE")) != NULL)
|
||||
+ store_path_len = strlen(store_path);
|
||||
+ else
|
||||
+ store_path_len = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (store_path_len > 0)
|
||||
+ return strncmp(path, store_path, strlen(store_path)) == 0;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static FILE *local_fopenat(int dirfd, const char *name, const char *mode)
|
||||
{
|
||||
int fd, o_mode = 0;
|
||||
@@ -161,6 +178,8 @@ static int local_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf)
|
||||
if (err) {
|
||||
goto err_out;
|
||||
}
|
||||
+ stbuf->st_uid = 0;
|
||||
+ stbuf->st_gid = 0;
|
||||
if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
|
||||
/* Actual credentials are part of extended attrs */
|
||||
uid_t tmp_uid;
|
||||
@@ -280,6 +299,9 @@ static int fchmodat_nofollow(int dirfd, const char *name, mode_t mode)
|
||||
{
|
||||
int fd, ret;
|
||||
|
||||
+ if (is_in_store_path(name))
|
||||
+ return 0;
|
||||
+
|
||||
/* FIXME: this should be handled with fchmodat(AT_SYMLINK_NOFOLLOW).
|
||||
* Unfortunately, the linux kernel doesn't implement it yet. As an
|
||||
* alternative, let's open the file and use fchmod() instead. This
|
||||
@@ -661,6 +683,8 @@ static int local_fstat(FsContext *fs_ctx, int fid_type,
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
+ stbuf->st_uid = 0;
|
||||
+ stbuf->st_gid = 0;
|
||||
if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
|
||||
/* Actual credentials are part of extended attrs */
|
||||
uid_t tmp_uid;
|
||||
@@ -795,8 +819,11 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
|
||||
if (err) {
|
||||
goto out;
|
||||
}
|
||||
- err = fchownat(dirfd, name, credp->fc_uid, credp->fc_gid,
|
||||
- AT_SYMLINK_NOFOLLOW);
|
||||
+ if (is_in_store_path(name))
|
||||
+ err = 0;
|
||||
+ else
|
||||
+ err = fchownat(dirfd, name, credp->fc_uid, credp->fc_gid,
|
||||
+ AT_SYMLINK_NOFOLLOW);
|
||||
if (err == -1) {
|
||||
/*
|
||||
* If we fail to change ownership and if we are
|
||||
@@ -911,7 +938,9 @@ static int local_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if ((credp->fc_uid == -1 && credp->fc_gid == -1) ||
|
||||
+ if (is_in_store_path(name)) {
|
||||
+ ret = 0;
|
||||
+ } else if ((credp->fc_uid == -1 && credp->fc_gid == -1) ||
|
||||
(fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
|
||||
(fs_ctx->export_flags & V9FS_SM_NONE)) {
|
||||
ret = fchownat(dirfd, name, credp->fc_uid, credp->fc_gid,
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
From 747a741772cde6bb340eb8bdb493390280de8d16 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 97e681e167..fd50d6243a 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;
|
||||
@@ -98,6 +104,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,208 @@
|
|||
From 19b0952b36b6b5c4bd2665cc0bd4e55a85f81b55 Mon Sep 17 00:00:00 2001
|
||||
From: Will Cohen <willcohen@users.noreply.github.com>
|
||||
Date: Tue, 29 Mar 2022 14:00:56 -0400
|
||||
Subject: [PATCH] Revert "ui/cocoa: Add clipboard support"
|
||||
|
||||
This reverts commit 7e3e20d89129614f4a7b2451fe321cc6ccca3b76.
|
||||
---
|
||||
include/ui/clipboard.h | 2 +-
|
||||
ui/clipboard.c | 2 +-
|
||||
ui/cocoa.m | 121 -----------------------------------------
|
||||
3 files changed, 2 insertions(+), 123 deletions(-)
|
||||
|
||||
diff --git a/include/ui/clipboard.h b/include/ui/clipboard.h
|
||||
index ce76aa451f..c4e1dc4ff4 100644
|
||||
--- a/include/ui/clipboard.h
|
||||
+++ b/include/ui/clipboard.h
|
||||
@@ -269,7 +269,7 @@ void qemu_clipboard_set_data(QemuClipboardPeer *peer,
|
||||
QemuClipboardInfo *info,
|
||||
QemuClipboardType type,
|
||||
uint32_t size,
|
||||
- const void *data,
|
||||
+ void *data,
|
||||
bool update);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(QemuClipboardInfo, qemu_clipboard_info_unref)
|
||||
diff --git a/ui/clipboard.c b/ui/clipboard.c
|
||||
index 9079ef829b..6b9ed59e1b 100644
|
||||
--- a/ui/clipboard.c
|
||||
+++ b/ui/clipboard.c
|
||||
@@ -140,7 +140,7 @@ void qemu_clipboard_set_data(QemuClipboardPeer *peer,
|
||||
QemuClipboardInfo *info,
|
||||
QemuClipboardType type,
|
||||
uint32_t size,
|
||||
- const void *data,
|
||||
+ void *data,
|
||||
bool update)
|
||||
{
|
||||
if (!info ||
|
||||
diff --git a/ui/cocoa.m b/ui/cocoa.m
|
||||
index c4e5468f9e..cd3bdf0cec 100644
|
||||
--- a/ui/cocoa.m
|
||||
+++ b/ui/cocoa.m
|
||||
@@ -28,7 +28,6 @@
|
||||
#include <crt_externs.h>
|
||||
|
||||
#include "qemu-common.h"
|
||||
-#include "ui/clipboard.h"
|
||||
#include "ui/console.h"
|
||||
#include "ui/input.h"
|
||||
#include "ui/kbd-state.h"
|
||||
@@ -107,10 +106,6 @@ static void cocoa_switch(DisplayChangeListener *dcl,
|
||||
static QemuSemaphore app_started_sem;
|
||||
static bool allow_events;
|
||||
|
||||
-static NSInteger cbchangecount = -1;
|
||||
-static QemuClipboardInfo *cbinfo;
|
||||
-static QemuEvent cbevent;
|
||||
-
|
||||
// Utility functions to run specified code block with iothread lock held
|
||||
typedef void (^CodeBlock)(void);
|
||||
typedef bool (^BoolCodeBlock)(void);
|
||||
@@ -1805,105 +1800,6 @@ static void addRemovableDevicesMenuItems(void)
|
||||
qapi_free_BlockInfoList(pointerToFree);
|
||||
}
|
||||
|
||||
-@interface QemuCocoaPasteboardTypeOwner : NSObject<NSPasteboardTypeOwner>
|
||||
-@end
|
||||
-
|
||||
-@implementation QemuCocoaPasteboardTypeOwner
|
||||
-
|
||||
-- (void)pasteboard:(NSPasteboard *)sender provideDataForType:(NSPasteboardType)type
|
||||
-{
|
||||
- if (type != NSPasteboardTypeString) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- with_iothread_lock(^{
|
||||
- QemuClipboardInfo *info = qemu_clipboard_info_ref(cbinfo);
|
||||
- qemu_event_reset(&cbevent);
|
||||
- qemu_clipboard_request(info, QEMU_CLIPBOARD_TYPE_TEXT);
|
||||
-
|
||||
- while (info == cbinfo &&
|
||||
- info->types[QEMU_CLIPBOARD_TYPE_TEXT].available &&
|
||||
- info->types[QEMU_CLIPBOARD_TYPE_TEXT].data == NULL) {
|
||||
- qemu_mutex_unlock_iothread();
|
||||
- qemu_event_wait(&cbevent);
|
||||
- qemu_mutex_lock_iothread();
|
||||
- }
|
||||
-
|
||||
- if (info == cbinfo) {
|
||||
- NSData *data = [[NSData alloc] initWithBytes:info->types[QEMU_CLIPBOARD_TYPE_TEXT].data
|
||||
- length:info->types[QEMU_CLIPBOARD_TYPE_TEXT].size];
|
||||
- [sender setData:data forType:NSPasteboardTypeString];
|
||||
- [data release];
|
||||
- }
|
||||
-
|
||||
- qemu_clipboard_info_unref(info);
|
||||
- });
|
||||
-}
|
||||
-
|
||||
-@end
|
||||
-
|
||||
-static QemuCocoaPasteboardTypeOwner *cbowner;
|
||||
-
|
||||
-static void cocoa_clipboard_notify(Notifier *notifier, void *data);
|
||||
-static void cocoa_clipboard_request(QemuClipboardInfo *info,
|
||||
- QemuClipboardType type);
|
||||
-
|
||||
-static QemuClipboardPeer cbpeer = {
|
||||
- .name = "cocoa",
|
||||
- .notifier = { .notify = cocoa_clipboard_notify },
|
||||
- .request = cocoa_clipboard_request
|
||||
-};
|
||||
-
|
||||
-static void cocoa_clipboard_update_info(QemuClipboardInfo *info)
|
||||
-{
|
||||
- if (info->owner == &cbpeer || info->selection != QEMU_CLIPBOARD_SELECTION_CLIPBOARD) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- if (info != cbinfo) {
|
||||
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
||||
- qemu_clipboard_info_unref(cbinfo);
|
||||
- cbinfo = qemu_clipboard_info_ref(info);
|
||||
- cbchangecount = [[NSPasteboard generalPasteboard] declareTypes:@[NSPasteboardTypeString] owner:cbowner];
|
||||
- [pool release];
|
||||
- }
|
||||
-
|
||||
- qemu_event_set(&cbevent);
|
||||
-}
|
||||
-
|
||||
-static void cocoa_clipboard_notify(Notifier *notifier, void *data)
|
||||
-{
|
||||
- QemuClipboardNotify *notify = data;
|
||||
-
|
||||
- switch (notify->type) {
|
||||
- case QEMU_CLIPBOARD_UPDATE_INFO:
|
||||
- cocoa_clipboard_update_info(notify->info);
|
||||
- return;
|
||||
- case QEMU_CLIPBOARD_RESET_SERIAL:
|
||||
- /* ignore */
|
||||
- return;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static void cocoa_clipboard_request(QemuClipboardInfo *info,
|
||||
- QemuClipboardType type)
|
||||
-{
|
||||
- NSData *text;
|
||||
-
|
||||
- switch (type) {
|
||||
- case QEMU_CLIPBOARD_TYPE_TEXT:
|
||||
- text = [[NSPasteboard generalPasteboard] dataForType:NSPasteboardTypeString];
|
||||
- if (text) {
|
||||
- qemu_clipboard_set_data(&cbpeer, info, type,
|
||||
- [text length], [text bytes], true);
|
||||
- [text release];
|
||||
- }
|
||||
- break;
|
||||
- default:
|
||||
- break;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* The startup process for the OSX/Cocoa UI is complicated, because
|
||||
* OSX insists that the UI runs on the initial main thread, and so we
|
||||
@@ -1938,7 +1834,6 @@ static void cocoa_clipboard_request(QemuClipboardInfo *info,
|
||||
COCOA_DEBUG("Second thread: calling qemu_main()\n");
|
||||
status = qemu_main(gArgc, gArgv, *_NSGetEnviron());
|
||||
COCOA_DEBUG("Second thread: qemu_main() returned, exiting\n");
|
||||
- [cbowner release];
|
||||
exit(status);
|
||||
}
|
||||
|
||||
@@ -2054,18 +1949,6 @@ static void cocoa_refresh(DisplayChangeListener *dcl)
|
||||
[cocoaView setAbsoluteEnabled:YES];
|
||||
});
|
||||
}
|
||||
-
|
||||
- if (cbchangecount != [[NSPasteboard generalPasteboard] changeCount]) {
|
||||
- qemu_clipboard_info_unref(cbinfo);
|
||||
- cbinfo = qemu_clipboard_info_new(&cbpeer, QEMU_CLIPBOARD_SELECTION_CLIPBOARD);
|
||||
- if ([[NSPasteboard generalPasteboard] availableTypeFromArray:@[NSPasteboardTypeString]]) {
|
||||
- cbinfo->types[QEMU_CLIPBOARD_TYPE_TEXT].available = true;
|
||||
- }
|
||||
- qemu_clipboard_update(cbinfo);
|
||||
- cbchangecount = [[NSPasteboard generalPasteboard] changeCount];
|
||||
- qemu_event_set(&cbevent);
|
||||
- }
|
||||
-
|
||||
[pool release];
|
||||
}
|
||||
|
||||
@@ -2105,10 +1988,6 @@ static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts)
|
||||
|
||||
// register vga output callbacks
|
||||
register_displaychangelistener(&dcl);
|
||||
-
|
||||
- qemu_event_init(&cbevent, false);
|
||||
- cbowner = [[QemuCocoaPasteboardTypeOwner alloc] init];
|
||||
- qemu_clipboard_peer_register(&cbpeer);
|
||||
}
|
||||
|
||||
static QemuDisplay qemu_display_cocoa = {
|
||||
--
|
||||
2.35.1
|
||||
|
||||
22
pkgs/applications/virtualization/qemu/utils.nix
Normal file
22
pkgs/applications/virtualization/qemu/utils.nix
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{ stdenv, installShellFiles, qemu }:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "qemu-utils";
|
||||
inherit (qemu) version;
|
||||
|
||||
nativeBuildInputs = [ installShellFiles ];
|
||||
buildInputs = [ qemu ];
|
||||
unpackPhase = "true";
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p "$out/bin"
|
||||
cp "${qemu}/bin/qemu-img" "$out/bin/qemu-img"
|
||||
cp "${qemu}/bin/qemu-io" "$out/bin/qemu-io"
|
||||
cp "${qemu}/bin/qemu-nbd" "$out/bin/qemu-nbd"
|
||||
|
||||
installManPage ${qemu}/share/man/man1/qemu-img.1.gz
|
||||
installManPage ${qemu}/share/man/man8/qemu-nbd.8.gz
|
||||
'';
|
||||
|
||||
inherit (qemu) meta;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue