Change:
Describe the bug Take an error: To Reproduce Steps to reproduce the behavior: to : Expected behavior Installed parallels tools Screenshots If applicable, add screenshots to help explain your problem. Additional context Add any other context about the problem here. Metadata Please run and paste the result. Maintainer information:
Depending on kernel version, the value of is not a package, but . The module is thus broken for kernel versions at or above 4.15.
I've seen it. But this line was removed
Right, the idea behind that PR (cc was good, but the implementation was not. It needs some more effort.
So how do we install parallels tools?
I wanna know so far :)
I marked this as stale due to inactivity. &rarr;

Discussion:
package = mkOption { type = types.nullOr types.package; default = config.boot.kernelPackages.prl-tools; <del> defaultText = literalExpression "config.boot.kernelPackages.prl-tools"; </del> <ins> defaultText = "config.boot.kernelPackages.prl-tools"; example = literalExpression "config.boot.kernelPackages.prl-tools"; </ins> description = '' Defines which package to use for prl-tools. Override to change the version. '';

}; config = mkIf config.hardware.parallels.enable { <del> services.xserver = { drivers = singleton { name = "prlvideo"; modules = [ prl-tools ]; }; screenSection = '' Option "NoMTRR" ''; config = '' Section "InputClass" Identifier "prlmouse" MatchIsPointer "on" MatchTag "prlmouse" Driver "prlmouse" EndSection ''; }; hardware.opengl.package = prl-tools; hardware.opengl.package32 = pkgs.pkgsi686Linux.linuxPackages.prl-tools.override { libsOnly = true; kernel = null; }; hardware.opengl.setLdLibraryPath = true; </del> services.udev.packages = [ prl-tools ];

boot.extraModulePackages = [ prl-tools ]; <del> boot.kernelModules = [ "prl_tg" "prl_eth" "prl_fs" "prl_fs_freeze" ]; </del> <ins> boot.kernelModules = [ "prl_fs" "prl_fs_freeze" "prl_tg" ] ++ optional (pkgs.stdenv.hostPlatform.system == "aarch64-linux") "prl_notifier"; </ins> services.timesyncd.enable = false; systemd.services.prltoolsd = { <del> description = "Parallels Tools' service"; </del> <ins> description = "Parallels Tools Service"; </ins> wantedBy = [ "multi-user.target" ]; <ins> path = [ prl-tools ]; </ins> serviceConfig = { ExecStart = "${prl-tools}/bin/prltoolsd -f"; PIDFile = "/var/run/prltoolsd.pid"; <ins> WorkingDirectory = "${prl-tools}/bin"; </ins> }; }; systemd.services.prlfsmountd = mkIf config.hardware.parallels.autoMountShares { <del> description = "Parallels Shared Folders Daemon"; </del> <ins> description = "Parallels Guest File System Sharing Tool"; </ins> wantedBy = [ "multi-user.target" ]; <ins> path = [ prl-tools ]; </ins> serviceConfig = rec { ExecStart = "${prl-tools}/sbin/prlfsmountd ${PIDFile}"; ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p /media"; ExecStopPost = "${prl-tools}/sbin/prlfsmountd -u"; PIDFile = "/run/prlfsmountd.pid"; <ins> WorkingDirectory = "${prl-tools}/bin"; </ins> }; }; systemd.services.prlshprint = { <del> description = "Parallels Shared Printer Tool"; </del> <ins> description = "Parallels Printing Tool"; </ins> wantedBy = [ "multi-user.target" ]; bindsTo = [ "cups.service" ]; <ins> path = [ prl-tools ]; </ins> serviceConfig = { Type = "forking"; ExecStart = "${prl-tools}/bin/prlshprint"; <ins> WorkingDirectory = "${prl-tools}/bin"; </ins> }; };

prlcc = { description = "Parallels Control Center"; wantedBy = [ "graphical-session.target" ]; <ins> path = [ prl-tools ]; </ins> serviceConfig = { ExecStart = "${prl-tools}/bin/prlcc"; <ins> WorkingDirectory = "${prl-tools}/bin"; </ins> }; }; prldnd = { <del> description = "Parallels Control Center"; </del> <ins> description = "Parallels Drag And Drop Tool"; </ins> wantedBy = [ "graphical-session.target" ]; <ins> path = [ prl-tools ]; </ins> serviceConfig = { ExecStart = "${prl-tools}/bin/prldnd"; <del> }; }; prl_wmouse_d  = { description = "Parallels Walking Mouse Daemon"; wantedBy = [ "graphical-session.target" ]; serviceConfig = { ExecStart = "${prl-tools}/bin/prl_wmouse_d"; </del> <ins> WorkingDirectory = "${prl-tools}/bin"; </ins> }; }; prlcp = { <del> description = "Parallels CopyPaste Tool"; </del> <ins> description = "Parallels Copy Paste Tool"; </ins> wantedBy = [ "graphical-session.target" ]; <ins> path = [ prl-tools ]; </ins> serviceConfig = { ExecStart = "${prl-tools}/bin/prlcp"; <ins> Restart = "always"; WorkingDirectory = "${prl-tools}/bin"; </ins> }; }; prlsga = { description = "Parallels Shared Guest Applications Tool"; wantedBy = [ "graphical-session.target" ]; <ins> path = [ prl-tools ]; </ins> serviceConfig = { ExecStart = "${prl-tools}/bin/prlsga"; <ins> WorkingDirectory = "${prl-tools}/bin"; </ins> }; }; prlshprof = { description = "Parallels Shared Profile Tool"; wantedBy = [ "graphical-session.target" ]; <ins> path = [ prl-tools ]; </ins> serviceConfig = { ExecStart = "${prl-tools}/bin/prlshprof"; <ins> WorkingDirectory = "${prl-tools}/bin"; </ins> }; }; };

{ stdenv, lib, makeWrapper, p7zip <del> , gawk, util-linux, xorg, glib, dbus-glib, zlib </del> <ins> , gawk, util-linux, xorg, glib, dbus-glib, zlib, bbe, bash, timetrap, netcat, cups </ins> , kernel ? null, libsOnly ? false <del> , undmg, fetchurl </del> <ins> , fetchurl, undmg, perl, autoPatchelfHook </ins> }: assert (!libsOnly) -> kernel != null; <ins> assert lib.elem stdenv.hostPlatform.system [ "x86_64-linux" "i686-linux" "aarch64-linux" ]; </ins> <del> let xorgFullVer = lib.getVersion xorg.xorgserver; xorgVer = lib.versions.majorMinor xorgFullVer; x64 = if stdenv.hostPlatform.system == "x86_64-linux" then true else if stdenv.hostPlatform.system == "i686-linux" then false else throw "Parallels Tools for Linux only support {x86-64,i686}-linux targets"; in </del> stdenv.mkDerivation rec { <del> version = "${prl_major}.2.1-41615"; prl_major = "12"; </del> <ins> version = "17.1.4-51567"; </ins> pname = "prl-tools"; # We download the full distribution to extract prl-tools-lin.iso from # => ${dmg}/Parallels Desktop.app/Contents/Resources/Tools/prl-tools-lin.iso src = fetchurl { <del> url =  "https://download.parallels.com/desktop/v${prl_major}/${version}/ParallelsDesktop-${version}.dmg"; sha256 = "1jwzwif69qlhmfky9kigjaxpxfj0lyrl1iyrpqy4iwqvajdgbbym"; </del> <ins> url =  "https://download.parallels.com/desktop/v${lib.versions.major version}/${version}/ParallelsDesktop-${version}.dmg"; sha256 = "sha256-gjLxQOTFuVghv1Bj+zfbNW97q1IN2rurSnPQi13gzRA="; </ins> }; hardeningDisable = [ "pic" "format" ]; <del> # also maybe python2 to generate xorg.conf nativeBuildInputs = [ p7zip undmg ] ++ lib.optionals (!libsOnly) [ makeWrapper ] ++ kernel.moduleBuildDependencies; </del> <ins> nativeBuildInputs = [ p7zip undmg perl bbe autoPatchelfHook ] ++ lib.optionals (!libsOnly) [ makeWrapper ] ++ kernel.moduleBuildDependencies; buildInputs = with xorg; [ libXrandr libXext libX11 libXcomposite libXinerama ] ++ lib.optionals (!libsOnly) [ libXi glib dbus-glib zlib ]; runtimeDependencies = [ glib xorg.libXrandr ]; </ins> inherit libsOnly; unpackPhase = '' undmg "${src}" export sourceRoot=prl-tools-build <del> 7z x "Parallels Desktop.app/Contents/Resources/Tools/prl-tools-lin.iso" -o$sourceRoot </del> <ins> 7z x "Parallels Desktop.app/Contents/Resources/Tools/prl-tools-lin${lib.optionalString stdenv.isAarch64 "-arm"}.iso" -o$sourceRoot </ins> if test -z "$libsOnly"; then ( cd $sourceRoot/kmods; tar -xaf prl_mod.tar.gz ) fi <del> ( cd $sourceRoot/tools; tar -xaf prltools${if x64 then ".x64" else ""}.tar.gz ) </del> ''; <del> kernelVersion = if libsOnly then "" else lib.getName kernel.name; kernelDir = if libsOnly then "" else "${kernel.dev}/lib/modules/${kernelVersion}"; scriptPath = lib.concatStringsSep ":" (lib.optionals (!libsOnly) [ "${util-linux}/bin" "${gawk}/bin" ]); </del> <ins> patches = lib.optionals (lib.versionAtLeast kernel.version "5.18") [ ./prl-tools.patch ]; kernelVersion = lib.optionalString (!libsOnly) kernel.modDirVersion; kernelDir = lib.optionalString (!libsOnly) "${kernel.dev}/lib/modules/${kernelVersion}"; libPath = lib.concatStringsSep ":" [ "${glib.out}/lib" "${xorg.libXrandr}/lib" ]; scriptPath = lib.concatStringsSep ":" (lib.optionals (!libsOnly) [ "${util-linux}/bin" "${gawk}/bin" "${bash}/bin" "${timetrap}/bin" "${netcat}/bin" "${cups}/sbin" ]); </ins> buildPhase = '' if test -z "$libsOnly"; then

SRC=$kernelDir/build  KVER=$kernelVersion ) <del> # Xorg config (maybe would be useful for other versions) #python2 installer/xserver-config.py xorg ${xorgVer} /dev/null parallels.conf </del> fi ''; <del> libPath = with xorg; lib.makeLibraryPath ([ stdenv.cc.cc libXrandr libXext libX11 libXcomposite libXinerama ] ++ lib.optionals (!libsOnly) [ libXi glib dbus-glib zlib ]); </del> installPhase = '' if test -z "$libsOnly"; then ( # kernel modules cd kmods mkdir -p $out/lib/modules/${kernelVersion}/extra <del> cp prl_eth/pvmnet/prl_eth.ko $out/lib/modules/${kernelVersion}/extra cp prl_tg/Toolgate/Guest/Linux/prl_tg/prl_tg.ko $out/lib/modules/${kernelVersion}/extra </del> cp prl_fs/SharedFolders/Guest/Linux/prl_fs/prl_fs.ko $out/lib/modules/${kernelVersion}/extra cp prl_fs_freeze/Snapshot/Guest/Linux/prl_freeze/prl_fs_freeze.ko $out/lib/modules/${kernelVersion}/extra <ins> cp prl_tg/Toolgate/Guest/Linux/prl_tg/prl_tg.ko $out/lib/modules/${kernelVersion}/extra ${lib.optionalString stdenv.isAarch64 "cp prl_notifier/Installation/lnx/prl_notifier/prl_notifier.ko $out/lib/modules/${kernelVersion}/extra"} </ins> ) fi ( # tools <del> cd tools </del> <ins> cd tools/tools${if stdenv.isAarch64 then "-arm64" else if stdenv.isx86_64 then "64" else "32"} </ins> mkdir -p $out/lib if test -z "$libsOnly"; then <ins> # prltoolsd contains hardcoded /bin/bash path # we're lucky because it uses only -c command # => replace to /bin/sh bbe -e "s:/bin/bash:/bin/shx00x00:" -o bin/prltoolsd.tmp bin/prltoolsd rm -f bin/prltoolsd mv bin/prltoolsd.tmp bin/prltoolsd </ins> # install binaries for i in bin/* sbin/prl_nettool sbin/prl_snapshot; do <ins> # also patch binaries to replace /usr/bin/XXX to XXX # here a two possible cases: # 1. it is uses as null terminated string and should be truncated by null; # 2. it is uses inside shell script and should be truncated by space. for p in bin/* sbin/prl_nettool sbin/prl_snapshot sbin/prlfsmountd; do p=$(basename $p) bbe -e "s:/usr/bin/$px00:./$px00x00x00x00x00x00x00x00:" -o $i.tmp $i bbe -e "s:/usr/sbin/$px00:./$px00x00x00x00x00x00x00x00 :" -o $i $i.tmp bbe -e "s:/usr/bin/$p:$p         :" -o $i.tmp $i bbe -e "s:/usr/sbin/$p:$p          :" -o $i $i.tmp done </ins> install -Dm755 $i $out/$i done <del> # other binaries for i in xorg.7.1/usr/bin/*; do cp $i $out/bin done for i in $out/bin/* $out/sbin/*; do patchelf  --interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)"  --set-rpath "$out/lib:$libPath"  $i || true </del> <ins> install -Dm755 ../../tools/prlfsmountd.sh $out/sbin/prlfsmountd for f in $out/bin/* $out/sbin/*; do wrapProgram $f  --prefix LD_LIBRARY_PATH ':' "$libPath"  --prefix PATH ':' "$scriptPath" </ins> done <del> mkdir -p $out/bin install -Dm755 ../installer/prlfsmountd.sh $out/sbin/prlfsmountd wrapProgram $out/sbin/prlfsmountd  --prefix PATH ':' "$scriptPath" for i in lib/*.a; do </del> <ins> for i in lib/libPrl*.0.0; do </ins> cp $i $out/lib <ins> ln -s $out/$i $out/''${i%.0.0} </ins> done <del> for i in xorg.7.1/usr/lib/libprl_wmouse_watcher.*; do cp $i $out/lib done </del> <ins> mkdir -p $out/share/man/man8 install -Dm644 ../mount.prl_fs.8 $out/share/man/man8 </ins> <del> mkdir -p $out/lib/udev/rules.d for i in *.rules; do sed 's,/bin/bash,${stdenv.shell},g' $i > $out/lib/udev/rules.d/$i done </del> <ins> substituteInPlace ../99prltoolsd-hibernate  --replace "/bin/bash" "${bash}/bin/bash" </ins> <del> ( cd xorg.${xorgVer} # Install the X modules. ( cd x-server/modules for i in */*; do install -Dm755 $i $out/lib/xorg/modules/$i done ) ( cd usr/lib libGLXname=$(echo libglx.so*) install -Dm755 $libGLXname $out/lib/xorg/modules/extensions/$libGLXname ln -s $libGLXname $out/lib/xorg/modules/extensions/libglx.so ln -s $libGLXname $out/lib/xorg/modules/extensions/libglx.so.1 ) ) </del> <ins> mkdir -p $out/etc/pm/sleep.d install -Dm644 ../99prltoolsd-hibernate $out/etc/pm/sleep.d </ins> fi <del> for i in xorg.7.1/usr/lib/libGL.*; do cp $i $out/lib done cd $out find -name *.so* -type f -exec  patchelf --set-rpath "$out/lib:$libPath" {} ; cd lib libGLname=$(echo libGL.so*) ln -s $libGLname libGL.so ln -s $libGLname libGL.so.1 </del> ) ''; <del> dontStrip = true; dontPatchELF = true; </del> meta = with lib; { description = "Parallels Tools for Linux guests"; homepage = "https://parallels.com"; <del> platforms = [ "i686-linux" "x86_64-linux" ]; </del> <ins> platforms = platforms.linux; </ins> license = licenses.unfree; <del> # I was making this package blindly and requesting testing from the real user, # so I can't even test it by myself and won't provide future updates. maintainers = with maintainers; [ abbradar ]; </del> <ins> maintainers = with maintainers; [ catap wegank ]; </ins> }; }

<ins> diff -puNr prl-tools-build/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg.c prl-tools-build/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg.c --- prl-tools-build/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg.c +++ prl-tools-build/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg.c @@ -382,7 +382,7 @@ static int prl_tg_initialize(struct tg_d } #endif /* Set DMA ability. Only lower 4G is possible to address */ -	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); +	rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)); if (rc) { printk(KERN_ERR "no usable DMA configurationn"); goto err_out; diff -puNr prl-tools-build/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg_call.c prl-tools-build/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg_call.c --- prl-tools-build/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg_call.c +++ prl-tools-build/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg_call.c @@ -76,7 +76,7 @@ static int tg_req_map_internal(struct TG uple->p[i] = vmalloc_to_page(mem); page_cache_get(uple->p[i]); -		dst->RequestPages[i] = pci_map_page(pdev, uple->p[i], 0, PAGE_SIZE, DMA_BIDIRECTIONAL) >> PAGE_SHIFT; +		dst->RequestPages[i] = dma_map_page(&pdev->dev, uple->p[i], 0, PAGE_SIZE, DMA_BIDIRECTIONAL) >> PAGE_SHIFT; if (!dst->RequestPages[i]) { page_cache_release(uple->p[i]); goto err; @@ -88,7 +88,7 @@ static int tg_req_map_internal(struct TG err: for (i = 0; i < uple->count; i++) { -		pci_unmap_page(pdev, dst->RequestPages[i] << PAGE_SHIFT, PAGE_SIZE, DMA_BIDIRECTIONAL); +		dma_unmap_page(&pdev->dev, dst->RequestPages[i] << PAGE_SHIFT, PAGE_SIZE, DMA_BIDIRECTIONAL); page_cache_release(uple->p[i]); } kfree(uple); @@ -129,7 +129,7 @@ static TG_PAGED_BUFFER *tg_req_map_user_ pfn = (u64 *)dbuf - 1; for (; npages > 0; npages--, mapped++) { -		dma_addr_t addr = pci_map_page(pdev, uple->p[npages-1], 0, PAGE_SIZE, DMA_BIDIRECTIONAL); +		dma_addr_t addr = dma_map_page(&pdev->dev, uple->p[npages-1], 0, PAGE_SIZE, DMA_BIDIRECTIONAL); if (!addr) { DPRINTK("[3] %d < %d	n", got, npages); @@ -144,7 +144,7 @@ static TG_PAGED_BUFFER *tg_req_map_user_ err_unmap: for (i = 0; i < mapped; i++, pfn++) -		pci_unmap_page(pdev, *pfn << PAGE_SHIFT, PAGE_SIZE, DMA_BIDIRECTIONAL); +		dma_unmap_page(&pdev->dev, *pfn << PAGE_SHIFT, PAGE_SIZE, DMA_BIDIRECTIONAL); err_put: for(i = 0; i < got; i++) @@ -176,7 +176,7 @@ static TG_PAGED_BUFFER *tg_req_map_kerne goto err; } -		addr = pci_map_page(pdev, page, 0, PAGE_SIZE, DMA_BIDIRECTIONAL); +		addr = dma_map_page(&pdev->dev, page, 0, PAGE_SIZE, DMA_BIDIRECTIONAL); if (!addr) { DPRINTK("[2] va:%p can't mapn", buffer); goto err; @@ -189,7 +189,7 @@ static TG_PAGED_BUFFER *tg_req_map_kerne err: for (; i > 0; i--, pfn--) -		pci_unmap_page(pdev, *pfn << PAGE_SHIFT, PAGE_SIZE, DMA_BIDIRECTIONAL); +		dma_unmap_page(&pdev->dev, *pfn << PAGE_SHIFT, PAGE_SIZE, DMA_BIDIRECTIONAL); return ERR_PTR(-ENOMEM); } @@ -203,7 +203,7 @@ static inline int tg_req_unmap_internal( dst->RequestSize + ~PAGE_MASK) >> PAGE_SHIFT; for (i = 0; i < count; i++) -		pci_unmap_page(req->dev->pci_dev, dst->RequestPages[i] << PAGE_SHIFT, PAGE_SIZE, DMA_BIDIRECTIONAL); +		dma_unmap_page(&req->dev->pci_dev->dev, dst->RequestPages[i] << PAGE_SHIFT, PAGE_SIZE, DMA_BIDIRECTIONAL); return count; } @@ -264,7 +264,7 @@ static void tg_req_unmap_pages(struct TG pfn = (u64 *)(dbuf + 1); for (; npages > 0; npages--, pfn++) -			pci_unmap_page(pdev, (*pfn) << PAGE_SHIFT, PAGE_SIZE, DMA_BIDIRECTIONAL); +			dma_unmap_page(&pdev->dev, (*pfn) << PAGE_SHIFT, PAGE_SIZE, DMA_BIDIRECTIONAL); dbuf = (TG_PAGED_BUFFER *)pfn; } @@ -374,7 +374,7 @@ static int tg_req_submit(struct TG_PENDI * also no any offset inside page needed. */ req->pg = vmalloc_to_page(dst); -	req->phys = pci_map_page(dev->pci_dev, vmalloc_to_page(dst), 0, PAGE_SIZE, DMA_BIDIRECTIONAL); +	req->phys = dma_map_page(&dev->pci_dev->dev, vmalloc_to_page(dst), 0, PAGE_SIZE, DMA_BIDIRECTIONAL); if (!req->phys) { DPRINTK("Can not allocate memory for DMA mappingn"); goto out; @@ -405,7 +405,7 @@ static int tg_req_submit(struct TG_PENDI out: if (ret != TG_STATUS_PENDING) { page_cache_release(req->pg); -		pci_unmap_page(dev->pci_dev, req->phys, PAGE_SIZE, DMA_BIDIRECTIONAL); +		dma_unmap_page(&dev->pci_dev->dev, req->phys, PAGE_SIZE, DMA_BIDIRECTIONAL); } DPRINTK("EXITn"); @@ -460,7 +460,7 @@ out_wait: wait_for_completion(&req->waiting); out: page_cache_release(req->pg); -	pci_unmap_page(dev->pci_dev, req->phys, PAGE_SIZE, DMA_BIDIRECTIONAL); +	dma_unmap_page(&dev->pci_dev->dev, req->phys, PAGE_SIZE, DMA_BIDIRECTIONAL); DPRINTK("EXITn"); return ret; } diff -puNr prl-tools-build/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs/inode.c prl-tools-build/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs/inode.c --- prl-tools-build/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs/inode.c +++ prl-tools-build/kmods/prl_fs/SharedFolders/Guest/Linux/prl_fs/inode.c @@ -16,6 +16,7 @@ #include <linux/pagemap.h> #include <linux/namei.h> #include <linux/cred.h> +#include <linux/writeback.h> #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 40)) &&  (LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)) @@ -57,7 +58,7 @@ unsigned long *prlfs_dfl( struct dentry } #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) -#define prl_uaccess_kernel() uaccess_kernel() +#define prl_uaccess_kernel() (false) #else #define prl_uaccess_kernel() segment_eq(get_fs(), KERNEL_DS) #endif @@ -954,7 +955,7 @@ static const struct address_space_operat .writepage		= prlfs_writepage, .write_begin    = simple_write_begin, .write_end      = prlfs_write_end, -	.set_page_dirty = __set_page_dirty_nobuffers, +	.dirty_folio    = filemap_dirty_folio, }; </ins>

phc-intel = if lib.versionAtLeast kernel.version "4.10" then callPackage ../os-specific/linux/phc-intel { } else null; <del> # Disable for kernels 4.15 and above due to compatibility issues prl-tools = if lib.versionOlder kernel.version "4.15" then callPackage ../os-specific/linux/prl-tools { } else null; </del> <ins> prl-tools = callPackage ../os-specific/linux/prl-tools { }; </ins> sch_cake = callPackage ../os-specific/linux/sch_cake { };