summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/man-nixos-install.xml47
-rw-r--r--nixos/lib/make-iso9660-image.nix13
-rw-r--r--nixos/lib/make-iso9660-image.sh70
-rw-r--r--nixos/lib/test-driver/Machine.pm4
-rw-r--r--nixos/maintainers/scripts/ec2/amazon-hvm-install-config.nix6
-rw-r--r--nixos/modules/config/no-x-libs.nix2
-rw-r--r--nixos/modules/installer/cd-dvd/installation-cd-base.nix3
-rw-r--r--nixos/modules/installer/cd-dvd/iso-image.nix188
-rw-r--r--nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix2
-rw-r--r--nixos/modules/installer/tools/nixos-install.sh11
-rw-r--r--nixos/modules/misc/ids.nix2
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/rename.nix5
-rw-r--r--nixos/modules/services/databases/mysql.nix18
-rw-r--r--nixos/modules/services/misc/mediatomb.nix282
-rw-r--r--nixos/modules/services/networking/networkmanager.nix5
-rw-r--r--nixos/modules/services/x11/desktop-managers/default.nix2
-rw-r--r--nixos/modules/services/x11/desktop-managers/xbmc.nix31
-rw-r--r--nixos/modules/system/boot/luksroot.nix28
-rw-r--r--nixos/modules/system/boot/stage-1.nix69
-rw-r--r--nixos/modules/tasks/filesystems/btrfs.nix6
-rw-r--r--nixos/modules/tasks/filesystems/cifs.nix2
-rw-r--r--nixos/modules/tasks/filesystems/ext.nix5
-rw-r--r--nixos/modules/tasks/filesystems/f2fs.nix4
-rw-r--r--nixos/modules/tasks/filesystems/jfs.nix2
-rw-r--r--nixos/modules/tasks/filesystems/reiserfs.nix4
-rw-r--r--nixos/modules/tasks/filesystems/unionfs-fuse.nix5
-rw-r--r--nixos/modules/tasks/filesystems/vfat.nix2
-rw-r--r--nixos/modules/tasks/filesystems/xfs.nix2
-rw-r--r--nixos/modules/tasks/filesystems/zfs.nix13
-rw-r--r--nixos/modules/virtualisation/amazon-image.nix2
-rw-r--r--nixos/modules/virtualisation/qemu-vm.nix2
-rw-r--r--nixos/release-combined.nix1
-rw-r--r--nixos/release.nix5
-rw-r--r--nixos/tests/boot.nix63
-rw-r--r--nixos/tests/installer.nix12
-rw-r--r--nixos/tests/virtualbox.nix5
37 files changed, 695 insertions, 229 deletions
diff --git a/nixos/doc/manual/man-nixos-install.xml b/nixos/doc/manual/man-nixos-install.xml
index 06e7b4a98470..7ad1be1ec105 100644
--- a/nixos/doc/manual/man-nixos-install.xml
+++ b/nixos/doc/manual/man-nixos-install.xml
@@ -26,6 +26,22 @@
       <replaceable>root</replaceable>
     </arg>
     <arg>
+      <group choice='req'>
+        <arg choice='plain'><option>--max-jobs</option></arg>
+        <arg choice='plain'><option>-j</option></arg>
+      </group>
+      <replaceable>number</replaceable>
+    </arg>
+    <arg>
+      <option>--cores</option>
+      <replaceable>number</replaceable>
+    </arg>
+    <arg>
+      <option>--option</option>
+      <replaceable>name</replaceable>
+      <replaceable>value</replaceable>
+    </arg>
+    <arg>
       <arg choice='plain'><option>--show-trace</option></arg>
     </arg>
     <arg>
@@ -96,6 +112,37 @@ it.</para>
     </listitem>
   </varlistentry>
 
+  <varlistentry><term><option>--max-jobs</option></term>
+    <term><option>-j</option></term>
+  
+    <listitem><para>Sets the maximum number of build jobs that Nix will
+    perform in parallel to the specified number. The default is <literal>1</literal>.
+    A higher value is useful on SMP systems or to exploit I/O latency.</para></listitem>
+  
+  </varlistentry>
+  
+  
+  <varlistentry><term><option>--cores</option></term>
+  
+    <listitem><para>Sets the value of the <envar>NIX_BUILD_CORES</envar>
+    environment variable in the invocation of builders.  Builders can
+    use this variable at their discretion to control the maximum amount
+    of parallelism.  For instance, in Nixpkgs, if the derivation
+    attribute <varname>enableParallelBuilding</varname> is set to
+    <literal>true</literal>, the builder passes the
+    <option>-j<replaceable>N</replaceable></option> flag to GNU Make.
+    The value <literal>0</literal> means that the builder should use all
+    available CPU cores in the system.</para></listitem>
+  
+  </varlistentry>
+
+  <varlistentry><term><option>--option</option> <replaceable>name</replaceable> <replaceable>value</replaceable></term>
+
+    <listitem><para>Set the Nix configuration option
+    <replaceable>name</replaceable> to <replaceable>value</replaceable>.</para></listitem>
+
+  </varlistentry>
+
   <varlistentry>
     <term><option>--show-trace</option></term>
     <listitem>
diff --git a/nixos/lib/make-iso9660-image.nix b/nixos/lib/make-iso9660-image.nix
index 5ad546e9534d..b2409c6006bc 100644
--- a/nixos/lib/make-iso9660-image.nix
+++ b/nixos/lib/make-iso9660-image.nix
@@ -1,4 +1,4 @@
-{ stdenv, perl, cdrkit, pathsFromGraph
+{ stdenv, perl, pathsFromGraph, xorriso, syslinux
 
 , # The file name of the resulting ISO image.
   isoName ? "cd.iso"
@@ -22,12 +22,18 @@
 , # Whether this should be an efi-bootable El-Torito CD.
   efiBootable ? false
 
+, # Wheter this should be an hybrid CD (bootable from USB as well as CD).
+  usbBootable ? false
+
 , # The path (in the ISO file system) of the boot image.
   bootImage ? ""
 
 , # The path (in the ISO file system) of the efi boot image.
   efiBootImage ? ""
 
+, # The path (outside the ISO file system) of the isohybrid-mbr image.
+  isohybridMbrImage ? ""
+
 , # Whether to compress the resulting ISO image with bzip2.
   compressImage ? false
 
@@ -38,13 +44,14 @@
 
 assert bootable -> bootImage != "";
 assert efiBootable -> efiBootImage != "";
+assert usbBootable -> isohybridMbrImage != "";
 
 stdenv.mkDerivation {
   name = "iso9660-image";
   builder = ./make-iso9660-image.sh;
-  buildInputs = [perl cdrkit];
+  buildInputs = [perl xorriso syslinux];
 
-  inherit isoName bootable bootImage compressImage volumeID pathsFromGraph efiBootImage efiBootable;
+  inherit isoName bootable bootImage compressImage volumeID pathsFromGraph efiBootImage efiBootable isohybridMbrImage usbBootable;
 
   # !!! should use XML.
   sources = map (x: x.source) contents;
diff --git a/nixos/lib/make-iso9660-image.sh b/nixos/lib/make-iso9660-image.sh
index 675b5bb35148..c9a373794692 100644
--- a/nixos/lib/make-iso9660-image.sh
+++ b/nixos/lib/make-iso9660-image.sh
@@ -13,6 +13,20 @@ stripSlash() {
     if test "${res:0:1}" = /; then res=${res:1}; fi
 }
 
+# Escape potential equal signs (=) with backslash (\=)
+escapeEquals() {
+    echo "$1" | sed -e 's/\\/\\\\/g' -e 's/=/\\=/g'
+}
+
+# Queues an file/directory to be placed on the ISO.
+# An entry consists of a local source path (2) and
+# a destination path on the ISO (1).
+addPath() {
+    target="$1"
+    source="$2"
+    echo "$(escapeEquals "$target")=$(escapeEquals "$source")" >> pathlist
+}
+
 stripSlash "$bootImage"; bootImage="$res"
 
 
@@ -31,11 +45,20 @@ if test -n "$bootable"; then
         fi
     done
 
-    bootFlags="-b $bootImage -c .boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table"
+    isoBootFlags="-eltorito-boot ${bootImage}
+                  -eltorito-catalog .boot.cat
+                  -no-emul-boot -boot-load-size 4 -boot-info-table"
+fi
+
+if test -n "$usbBootable"; then
+    usbBootFlags="-isohybrid-mbr ${isohybridMbrImage}"
 fi
 
 if test -n "$efiBootable"; then
-    bootFlags="$bootFlags -eltorito-alt-boot -e $efiBootImage -no-emul-boot"
+    efiBootFlags="-eltorito-alt-boot
+                  -e $efiBootImage
+                  -no-emul-boot
+                  -isohybrid-gpt-basdat"
 fi
 
 touch pathlist
@@ -44,14 +67,14 @@ touch pathlist
 # Add the individual files.
 for ((i = 0; i < ${#targets_[@]}; i++)); do
     stripSlash "${targets_[$i]}"
-    echo "$res=${sources_[$i]}" >> pathlist
+    addPath "$res" "${sources_[$i]}"
 done
 
 
 # Add the closures of the top-level store objects.
 storePaths=$(perl $pathsFromGraph closure-*)
 for i in $storePaths; do
-    echo "${i:1}=$i" >> pathlist
+    addPath "${i:1}" "$i"
 done
 
 
@@ -59,7 +82,7 @@ done
 # nix-store --load-db.
 if [ -n "$object" ]; then
     printRegistration=1 perl $pathsFromGraph closure-* > nix-path-registration
-    echo "nix-path-registration=nix-path-registration" >> pathlist
+    addPath "nix-path-registration" "nix-path-registration"
 fi
 
 
@@ -70,22 +93,39 @@ for ((n = 0; n < ${#objects[*]}; n++)); do
     if test "$symlink" != "none"; then
         mkdir -p $(dirname ./$symlink)
         ln -s $object ./$symlink
-        echo "$symlink=./$symlink" >> pathlist
+        addPath "$symlink" "./$symlink"
     fi
 done
 
-# !!! what does this do?
-cat pathlist | sed -e 's/=\(.*\)=\(.*\)=/\\=\1=\2\\=/' | tee pathlist.safer
-
-
 mkdir -p $out/iso
-genCommand="genisoimage -iso-level 4 -r -J $bootFlags -hide-rr-moved -graft-points -path-list pathlist.safer ${volumeID:+-V $volumeID}"
-if test -z "$compressImage"; then
-    $genCommand -o $out/iso/$isoName
-else
-    $genCommand | bzip2 > $out/iso/$isoName.bz2
+
+xorriso="xorriso
+ -as mkisofs
+ -iso-level 3
+ -volid ${volumeID}
+ -appid nixos
+ -publisher nixos
+ -graft-points
+ -full-iso9660-filenames
+ ${isoBootFlags}
+ ${usbBootFlags}
+ ${efiBootFlags}
+ -r
+ -path-list pathlist
+ --sort-weight 0 /
+ --sort-weight 1 /isolinux" # Make sure isolinux is near the beginning of the ISO
+
+$xorriso -output $out/iso/$isoName
+
+if test -n "$usbBootable"; then
+    echo "Making image hybrid..."
+    isohybrid --uefi $out/iso/$isoName
 fi
 
+if test -n "$compressImage"; then
+    echo "Compressing image..."
+    bzip2 $out/iso/$isoName
+fi
 
 mkdir -p $out/nix-support
 echo $system > $out/nix-support/system
diff --git a/nixos/lib/test-driver/Machine.pm b/nixos/lib/test-driver/Machine.pm
index 85c2bfa88e1a..e0791692d3ef 100644
--- a/nixos/lib/test-driver/Machine.pm
+++ b/nixos/lib/test-driver/Machine.pm
@@ -37,6 +37,10 @@ sub new {
             if defined $args->{hda};
         $startCommand .= "-cdrom $args->{cdrom} "
             if defined $args->{cdrom};
+        $startCommand .= "-device piix3-usb-uhci -drive id=usbdisk,file=$args->{usb},if=none,readonly -device usb-storage,drive=usbdisk "
+            if defined $args->{usb};
+        $startCommand .= "-bios $args->{bios} "
+            if defined $args->{bios};
         $startCommand .= $args->{qemuFlags} || "";
     } else {
         $startCommand = Cwd::abs_path $startCommand;
diff --git a/nixos/maintainers/scripts/ec2/amazon-hvm-install-config.nix b/nixos/maintainers/scripts/ec2/amazon-hvm-install-config.nix
index 530769cec5b7..c0ec38bf489a 100644
--- a/nixos/maintainers/scripts/ec2/amazon-hvm-install-config.nix
+++ b/nixos/maintainers/scripts/ec2/amazon-hvm-install-config.nix
@@ -23,9 +23,9 @@ in
   boot.kernelParams = [ "console=ttyS0" ];
 
   boot.initrd.extraUtilsCommands = ''
-    cp -v ${pkgs.gawk}/bin/gawk $out/bin/gawk
-    cp -v ${pkgs.gnused}/bin/sed $out/bin/gnused
-    cp -v ${pkgs.utillinux}/sbin/sfdisk $out/bin/sfdisk
+    copy_bin_and_libs ${pkgs.gawk}/bin/gawk
+    copy_bin_and_libs ${pkgs.gnused}/bin/sed
+    copy_bin_and_libs ${pkgs.utillinux}/sbin/sfdisk
     cp -v ${growpart} $out/bin/growpart
   '';
   boot.initrd.postDeviceCommands = ''
diff --git a/nixos/modules/config/no-x-libs.nix b/nixos/modules/config/no-x-libs.nix
index 47393c9d3f5c..13477337bda5 100644
--- a/nixos/modules/config/no-x-libs.nix
+++ b/nixos/modules/config/no-x-libs.nix
@@ -27,6 +27,6 @@ with lib;
     fonts.fontconfig.enable = false;
 
     nixpkgs.config.packageOverrides = pkgs:
-      { dbus = pkgs.dbus.override { useX11 = false; }; };
+      { dbus = pkgs.dbus.override { x11Support = false; }; };
   };
 }
diff --git a/nixos/modules/installer/cd-dvd/installation-cd-base.nix b/nixos/modules/installer/cd-dvd/installation-cd-base.nix
index b723a91e4f35..4896eee29084 100644
--- a/nixos/modules/installer/cd-dvd/installation-cd-base.nix
+++ b/nixos/modules/installer/cd-dvd/installation-cd-base.nix
@@ -36,6 +36,9 @@ with lib;
   # EFI booting
   isoImage.makeEfiBootable = true;
 
+  # USB booting
+  isoImage.makeUsbBootable = true;
+
   # Add Memtest86+ to the CD.
   boot.loader.grub.memtest86.enable = true;
 
diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix
index 39db7d9b8f72..d9d7254aba25 100644
--- a/nixos/modules/installer/cd-dvd/iso-image.nix
+++ b/nixos/modules/installer/cd-dvd/iso-image.nix
@@ -7,66 +7,89 @@
 with lib;
 
 let
-
-  # The Grub image.
-  grubImage = pkgs.runCommand "grub_eltorito" {}
+  # Timeout in syslinux is in units of 1/10 of a second.
+  # 0 is used to disable timeouts.
+  syslinuxTimeout = if config.boot.loader.timeout == null then
+      0
+    else
+      max (config.boot.loader.timeout * 10) 1;
+
+
+  max = x: y: if x > y then x else y;
+
+  # The configuration file for syslinux.
+
+  # Notes on syslinux configuration and UNetbootin compatiblity:
+  #   * Do not use '/syslinux/syslinux.cfg' as the path for this
+  #     configuration. UNetbootin will not parse the file and use it as-is.
+  #     This results in a broken configuration if the partition label does
+  #     not match the specified config.isoImage.volumeID. For this reason
+  #     we're using '/isolinux/isolinux.cfg'.
+  #   * Use APPEND instead of adding command-line arguments directly after
+  #     the LINUX entries.
+  #   * COM32 entries (chainload, reboot, poweroff) are not recognized. They
+  #     result in incorrect boot entries.
+
+  baseIsolinuxCfg =
     ''
-      ${pkgs.grub2}/bin/grub-mkimage -p /boot/grub -O i386-pc -o tmp biosdisk iso9660 help linux linux16 chain png jpeg echo gfxmenu reboot
-      cat ${pkgs.grub2}/lib/grub/*/cdboot.img tmp > $out
-    ''; # */
-
-
-  # The configuration file for Grub.
-  grubCfg =
-    ''
-      set default=${builtins.toString config.boot.loader.grub.default}
-      set timeout=${builtins.toString config.boot.loader.grub.timeout}
-
-      if loadfont /boot/grub/unicode.pf2; then
-        set gfxmode=640x480
-        insmod gfxterm
-        insmod vbe
-        terminal_output gfxterm
-
-        insmod png
-        if background_image /boot/grub/splash.png; then
-          set color_normal=white/black
-          set color_highlight=black/white
-        else
-          set menu_color_normal=cyan/blue
-          set menu_color_highlight=white/blue
-        fi
-
-      fi
-
-      ${config.boot.loader.grub.extraEntries}
+    SERIAL 0 38400
+    TIMEOUT ${builtins.toString syslinuxTimeout}
+    UI vesamenu.c32
+    MENU TITLE NixOS
+    MENU BACKGROUND /isolinux/background.png
+    DEFAULT boot
+
+    LABEL boot
+    MENU LABEL NixOS ${config.system.nixosVersion} Installer
+    LINUX /boot/bzImage
+    APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
+    INITRD /boot/initrd
     '';
 
+  isolinuxMemtest86Entry = ''
+    LABEL memtest
+    MENU LABEL Memtest86+
+    LINUX /boot/memtest.bin
+    APPEND ${toString config.boot.loader.grub.memtest86.params}
+  '';
+
+  isolinuxCfg = baseIsolinuxCfg + (optionalString config.boot.loader.grub.memtest86.enable isolinuxMemtest86Entry);
 
   # The efi boot image
   efiDir = pkgs.runCommand "efi-directory" {} ''
-    mkdir -p $out/efi/boot
-    cp -v ${pkgs.gummiboot}/lib/gummiboot/gummiboot${targetArch}.efi $out/efi/boot/boot${targetArch}.efi
+    mkdir -p $out/EFI/boot
+    cp -v ${pkgs.gummiboot}/lib/gummiboot/gummiboot${targetArch}.efi $out/EFI/boot/boot${targetArch}.efi
     mkdir -p $out/loader/entries
     echo "title NixOS LiveCD" > $out/loader/entries/nixos-livecd.conf
     echo "linux /boot/bzImage" >> $out/loader/entries/nixos-livecd.conf
     echo "initrd /boot/initrd" >> $out/loader/entries/nixos-livecd.conf
     echo "options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}" >> $out/loader/entries/nixos-livecd.conf
     echo "default nixos-livecd" > $out/loader/loader.conf
-    echo "timeout 5" >> $out/loader/loader.conf
+    echo "timeout ${builtins.toString config.boot.loader.gummiboot.timeout}" >> $out/loader/loader.conf
   '';
 
-  efiImg = pkgs.runCommand "efi-image_eltorito" { buildInputs = [ pkgs.mtools ]; }
+  efiImg = pkgs.runCommand "efi-image_eltorito" { buildInputs = [ pkgs.mtools pkgs.libfaketime ]; }
+    # Be careful about determinism: du --apparent-size,
+    #   dates (cp -p, touch, mcopy -m, faketime for label), IDs (mkfs.vfat -i)
     ''
-      #Let's hope 15M is enough
-      dd bs=2048 count=7680 if=/dev/zero of="$out"
-      ${pkgs.dosfstools}/sbin/mkfs.vfat "$out"
-      mcopy -svi "$out" ${efiDir}/* ::
-      mmd -i "$out" boot
-      mcopy -v -i "$out" \
-        ${config.boot.kernelPackages.kernel}/bzImage ::boot/bzImage
-      mcopy -v -i "$out" \
-        ${config.system.build.initialRamdisk}/initrd ::boot/initrd
+      mkdir ./contents && cd ./contents
+      cp -rp "${efiDir}"/* .
+      mkdir ./boot
+      cp -p "${config.boot.kernelPackages.kernel}/bzImage" \
+        "${config.system.build.initialRamdisk}/initrd" ./boot/
+      touch --date=@0 ./*
+
+      usage_size=$(du -sb --apparent-size . | tr -cd '[:digit:]')
+      # Make the image 110% as big as the files need to make up for FAT overhead
+      image_size=$(( ($usage_size * 110) / 100 ))
+      # Make the image fit blocks of 1M
+      block_size=$((1024*1024))
+      image_size=$(( ($image_size / $block_size + 1) * $block_size ))
+      echo "Usage size: $usage_size"
+      echo "Image size: $image_size"
+      truncate --size=$image_size "$out"
+      ${pkgs.libfaketime}/bin/faketime "2000-01-01 00:00:00" ${pkgs.dosfstools}/sbin/mkfs.vfat -i 12345678 -n EFIBOOT "$out"
+      mcopy -bpsvm -i "$out" ./* ::
     ''; # */
 
   targetArch = if pkgs.stdenv.isi686 then
@@ -152,9 +175,24 @@ in
       '';
     };
 
+    isoImage.makeUsbBootable = mkOption {
+      default = false;
+      description = ''
+        Whether the ISO image should be bootable from CD as well as USB.
+      '';
+    };
 
-  };
+    isoImage.splashImage = mkOption {
+      default = pkgs.fetchurl {
+          url = https://raw.githubusercontent.com/NixOS/nixos-artwork/5729ab16c6a5793c10a2913b5a1b3f59b91c36ee/ideas/grub-splash/grub-nixos-1.png;
+          sha256 = "43fd8ad5decf6c23c87e9026170a13588c2eba249d9013cb9f888da5e2002217";
+        };
+      description = ''
+        The splash image to use in the bootloader.
+      '';
+    };
 
+  };
 
   config = {
 
@@ -166,7 +204,7 @@ in
 
     # !!! Hack - attributes expected by other modules.
     system.boot.loader.kernelFile = "bzImage";
-    environment.systemPackages = [ pkgs.grub2 ];
+    environment.systemPackages = [ pkgs.grub2 pkgs.syslinux ];
 
     # In stage 1 of the boot, mount the CD as the root FS by label so
     # that we don't need to know its device.  We pass the label of the
@@ -216,7 +254,7 @@ in
         options = "allow_other,cow,nonempty,chroot=/mnt-root,max_files=32768,hide_meta_files,dirs=/nix/.rw-store=rw:/nix/.ro-store=ro";
       };
 
-    boot.initrd.availableKernelModules = [ "squashfs" "iso9660" ];
+    boot.initrd.availableKernelModules = [ "squashfs" "iso9660" "usb-storage" ];
 
     boot.initrd.kernelModules = [ "loop" ];
 
@@ -236,15 +274,12 @@ in
     # Individual files to be included on the CD, outside of the Nix
     # store on the CD.
     isoImage.contents =
-      [ { source = grubImage;
-          target = "/boot/grub/grub_eltorito";
-        }
-        { source = pkgs.substituteAll  {
-            name = "grub.cfg";
-            src = pkgs.writeText "grub.cfg-in" grubCfg;
+      [ { source = pkgs.substituteAll  {
+            name = "isolinux.cfg";
+            src = pkgs.writeText "isolinux.cfg-in" isolinuxCfg;
             bootRoot = "/boot";
           };
-          target = "/boot/grub/grub.cfg";
+          target = "/isolinux/isolinux.cfg";
         }
         { source = config.boot.kernelPackages.kernel + "/bzImage";
           target = "/boot/bzImage";
@@ -252,51 +287,44 @@ in
         { source = config.system.build.initialRamdisk + "/initrd";
           target = "/boot/initrd";
         }
-        { source = "${pkgs.grub2}/share/grub/unicode.pf2";
-          target = "/boot/grub/unicode.pf2";
-        }
-        { source = config.boot.loader.grub.splashImage;
-          target = "/boot/grub/splash.png";
-        }
         { source = config.system.build.squashfsStore;
           target = "/nix-store.squashfs";
         }
+        { source = "${pkgs.syslinux}/share/syslinux";
+          target = "/isolinux";
+        }
+        { source = config.isoImage.splashImage;
+          target = "/isolinux/background.png";
+        }
       ] ++ optionals config.isoImage.makeEfiBootable [
         { source = efiImg;
           target = "/boot/efi.img";
         }
-        { source = "${efiDir}/efi";
-          target = "/efi";
+        { source = "${efiDir}/EFI";
+          target = "/EFI";
         }
         { source = "${efiDir}/loader";
           target = "/loader";
         }
-      ] ++ mapAttrsToList (n: v: { source = v; target = "/boot/${n}"; }) config.boot.loader.grub.extraFiles;
-
-    # The Grub menu.
-    boot.loader.grub.extraEntries =
-      ''
-        menuentry "NixOS ${config.system.nixosVersion} Installer" {
-          linux /boot/bzImage init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
-          initrd /boot/initrd
-        }
-
-        menuentry "Boot from hard disk" {
-          set root=(hd0)
-          chainloader +1
+      ] ++ optionals config.boot.loader.grub.memtest86.enable [
+        { source = "${pkgs.memtest86plus}/memtest.bin";
+          target = "/boot/memtest.bin";
         }
-      '';
+      ];
 
-    boot.loader.grub.timeout = 10;
+    boot.loader.timeout = 10;
 
     # Create the ISO image.
     system.build.isoImage = import ../../../lib/make-iso9660-image.nix ({
-      inherit (pkgs) stdenv perl cdrkit pathsFromGraph;
+      inherit (pkgs) stdenv perl pathsFromGraph xorriso syslinux;
 
       inherit (config.isoImage) isoName compressImage volumeID contents;
 
       bootable = true;
-      bootImage = "/boot/grub/grub_eltorito";
+      bootImage = "/isolinux/isolinux.bin";
+    } // optionalAttrs config.isoImage.makeUsbBootable {
+      usbBootable = true;
+      isohybridMbrImage = "${pkgs.syslinux}/share/syslinux/isohdpfx.bin";
     } // optionalAttrs config.isoImage.makeEfiBootable {
       efiBootable = true;
       efiBootImage = "boot/efi.img";
diff --git a/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix b/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix
index 4ce7582c166a..46dc1c705022 100644
--- a/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix
+++ b/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix
@@ -98,7 +98,7 @@ in
 
   boot.initrd.extraUtilsCommands =
     ''
-      cp ${pkgs.utillinux}/sbin/hwclock $out/bin
+      copy_bin_and_libs ${pkgs.utillinux}/sbin/hwclock
     '';
 
   boot.initrd.postDeviceCommands =
diff --git a/nixos/modules/installer/tools/nixos-install.sh b/nixos/modules/installer/tools/nixos-install.sh
index 8f3de10c6133..1ccd6547df5e 100644
--- a/nixos/modules/installer/tools/nixos-install.sh
+++ b/nixos/modules/installer/tools/nixos-install.sh
@@ -28,9 +28,14 @@ chrootCommand=(/run/current-system/sw/bin/bash)
 while [ "$#" -gt 0 ]; do
     i="$1"; shift 1
     case "$i" in
-        -I)
-            given_path="$1"; shift 1
-            extraBuildFlags+=("$i" "$given_path")
+        --max-jobs|-j|--cores|-I)
+            j="$1"; shift 1
+            extraBuildFlags+=("$i" "$j")
+            ;;
+        --option)
+            j="$1"; shift 1
+            k="$1"; shift 1
+            extraBuildFlags+=("$i" "$j" "$k")
             ;;
         --root)
             mountPoint="$1"; shift 1
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index b03107610fe4..acb4af7a933d 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -212,6 +212,7 @@
       uptimed = 184;
       zope2 = 185;
       ripple-data-api = 186;
+      mediatomb = 187;
 
       # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
 
@@ -401,6 +402,7 @@
       #uptimed = 184; # unused
       #zope2 = 185; # unused
       #ripple-data-api = 186; #unused
+      mediatomb = 187;
 
       # When adding a gid, make sure it doesn't match an existing
       # uid. Users and groups with the same name should have equal
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index cca1c1a73d39..738faa79e29b 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -191,6 +191,7 @@
   ./services/misc/gitlab.nix
   ./services/misc/gitolite.nix
   ./services/misc/gpsd.nix
+  ./services/misc/mediatomb.nix
   ./services/misc/mesos-master.nix
   ./services/misc/mesos-slave.nix
   ./services/misc/nix-daemon.nix
diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix
index e820b2cb9ce4..07fe568697b6 100644
--- a/nixos/modules/rename.nix
+++ b/nixos/modules/rename.nix
@@ -107,7 +107,6 @@ in zipModules ([]
 ++ obsolete [ "services" "sshd" "permitRootLogin" ] [ "services" "openssh" "permitRootLogin" ]
 ++ obsolete [ "services" "xserver" "startSSHAgent" ] [ "services" "xserver" "startOpenSSHAgent" ]
 ++ obsolete [ "services" "xserver" "startOpenSSHAgent" ] [ "programs" "ssh" "startAgent" ]
-++ obsolete [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "xbmc" ]
 
 # VirtualBox
 ++ obsolete [ "services" "virtualbox" "enable" ] [ "services" "virtualboxGuest" "enable" ]
@@ -136,6 +135,10 @@ in zipModules ([]
 
 ++ obsolete [ "services" "mysql55" ] [ "services" "mysql" ]
 
+# XBMC
+++ obsolete [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ]
+++ obsolete [ "services" "xserver" "desktopManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ]
+
 # Options that are obsolete and have no replacement.
 ++ obsolete' [ "boot" "loader" "grub" "bootDevice" ]
 ++ obsolete' [ "boot" "initrd" "luks" "enable" ]
diff --git a/nixos/modules/services/databases/mysql.nix b/nixos/modules/services/databases/mysql.nix
index b94a3fbf3de7..05b13492052a 100644
--- a/nixos/modules/services/databases/mysql.nix
+++ b/nixos/modules/services/databases/mysql.nix
@@ -8,9 +8,7 @@ let
 
   mysql = cfg.package;
 
-  is55 = mysql.mysqlVersion == "5.5";
-
-  mysqldDir = if is55 then "${mysql}/bin" else "${mysql}/libexec";
+  atLeast55 = versionAtLeast mysql.mysqlVersion "5.5";
 
   pidFile = "${cfg.pidDir}/mysqld.pid";
 
@@ -24,7 +22,7 @@ let
     port = ${toString cfg.port}
     ${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave") "log-bin=mysql-bin"}
     ${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave") "server-id = ${toString cfg.replication.serverId}"}
-    ${optionalString (cfg.replication.role == "slave" && !is55)
+    ${optionalString (cfg.replication.role == "slave" && !atLeast55)
     ''
       master-host = ${cfg.replication.masterHost}
       master-user = ${cfg.replication.masterUser}
@@ -75,7 +73,7 @@ in
       };
 
       pidDir = mkOption {
-        default = "/var/run/mysql";
+        default = "/run/mysqld";
         description = "Location of the file which stores the PID of the MySQL server";
       };
 
@@ -180,15 +178,19 @@ in
 
             mkdir -m 0700 -p ${cfg.pidDir}
             chown -R ${cfg.user} ${cfg.pidDir}
+
+            # Make the socket directory
+            mkdir -m 0700 -p /run/mysqld
+            chown -R ${cfg.user} /run/mysqld
           '';
 
-        serviceConfig.ExecStart = "${mysqldDir}/mysqld --defaults-extra-file=${myCnf} ${mysqldOptions}";
+        serviceConfig.ExecStart = "${mysql}/bin/mysqld --defaults-extra-file=${myCnf} ${mysqldOptions}";
 
         postStart =
           ''
             # Wait until the MySQL server is available for use
             count=0
-            while [ ! -e /tmp/mysql.sock ]
+            while [ ! -e /run/mysqld/mysqld.sock ]
             do
                 if [ $count -eq 30 ]
                 then
@@ -222,7 +224,7 @@ in
                     fi
                   '') cfg.initialDatabases}
 
-                ${optionalString (cfg.replication.role == "slave" && is55)
+                ${optionalString (cfg.replication.role == "slave" && atLeast55)
                   ''
                     # Set up the replication master
 
diff --git a/nixos/modules/services/misc/mediatomb.nix b/nixos/modules/services/misc/mediatomb.nix
new file mode 100644
index 000000000000..23227548039c
--- /dev/null
+++ b/nixos/modules/services/misc/mediatomb.nix
@@ -0,0 +1,282 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  uid = config.ids.uids.mediatomb;
+  gid = config.ids.gids.mediatomb;
+  cfg = config.services.mediatomb;
+
+  mtConf = pkgs.writeText "config.xml" ''
+  <?xml version="1.0" encoding="UTF-8"?>
+  <config version="2" xmlns="http://mediatomb.cc/config/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://mediatomb.cc/config/2 http://mediatomb.cc/config/2.xsd">
+    <server>
+      <ui enabled="yes" show-tooltips="yes">
+        <accounts enabled="no" session-timeout="30">
+          <account user="mediatomb" password="mediatomb"/>
+        </accounts>
+      </ui>
+      <name>${cfg.serverName}</name>
+      <udn>uuid:${cfg.uuid}</udn>
+      <home>${cfg.dataDir}</home>
+      <webroot>${pkgs.mediatomb}/share/mediatomb/web</webroot>
+      <storage>
+        <sqlite3 enabled="yes">
+          <database-file>mediatomb.db</database-file>
+        </sqlite3>
+      </storage>
+      <protocolInfo extend="${if cfg.ps3Support then "yes" else "no"}"/>
+      ${if cfg.dsmSupport then ''
+      <custom-http-headers>
+        <add header="X-User-Agent: redsonic"/>
+      </custom-http-headers>
+
+      <manufacturerURL>redsonic.com</manufacturerURL>
+      <modelNumber>105</modelNumber>
+      '' else ""}
+      ${if cfg.tg100Support then ''
+      <upnp-string-limit>101</upnp-string-limit>
+      '' else ""}
+      <extended-runtime-options>
+        <mark-played-items enabled="yes" suppress-cds-updates="yes">
+          <string mode="prepend">*</string>
+          <mark>
+            <content>video</content>
+          </mark>
+        </mark-played-items>
+      </extended-runtime-options>
+    </server>
+    <import hidden-files="no">
+      <scripting script-charset="UTF-8">
+        <common-script>/nix/store/cngbzn39vidd6jm4wgzxfafqll74ybfa-mediatomb-0.12.1/share/mediatomb/js/common.js</common-script>
+        <playlist-script>/nix/store/cngbzn39vidd6jm4wgzxfafqll74ybfa-mediatomb-0.12.1/share/mediatomb/js/playlists.js</playlist-script>
+        <virtual-layout type="builtin">
+          <import-script>/nix/store/cngbzn39vidd6jm4wgzxfafqll74ybfa-mediatomb-0.12.1/share/mediatomb/js/import.js</import-script>
+        </virtual-layout>
+      </scripting>
+      <mappings>
+        <extension-mimetype ignore-unknown="no">
+          <map from="mp3" to="audio/mpeg"/>
+          <map from="ogx" to="application/ogg"/>
+          <map from="ogv" to="video/ogg"/>
+          <map from="oga" to="audio/ogg"/>
+          <map from="ogg" to="audio/ogg"/>
+          <map from="ogm" to="video/ogg"/>
+          <map from="asf" to="video/x-ms-asf"/>
+          <map from="asx" to="video/x-ms-asf"/>
+          <map from="wma" to="audio/x-ms-wma"/>
+          <map from="wax" to="audio/x-ms-wax"/>
+          <map from="wmv" to="video/x-ms-wmv"/>
+          <map from="wvx" to="video/x-ms-wvx"/>
+          <map from="wm" to="video/x-ms-wm"/>
+          <map from="wmx" to="video/x-ms-wmx"/>
+          <map from="m3u" to="audio/x-mpegurl"/>
+          <map from="pls" to="audio/x-scpls"/>
+          <map from="flv" to="video/x-flv"/>
+          <map from="mkv" to="video/x-matroska"/>
+          <map from="mka" to="audio/x-matroska"/>
+          ${if cfg.ps3Support then ''
+          <map from="avi" to="video/divx"/>
+          '' else ""}
+          ${if cfg.dsmSupport then ''
+          <map from="avi" to="video/avi"/>
+          '' else ""}
+        </extension-mimetype>
+        <mimetype-upnpclass>
+          <map from="audio/*" to="object.item.audioItem.musicTrack"/>
+          <map from="video/*" to="object.item.videoItem"/>
+          <map from="image/*" to="object.item.imageItem"/>
+        </mimetype-upnpclass>
+        <mimetype-contenttype>
+          <treat mimetype="audio/mpeg" as="mp3"/>
+          <treat mimetype="application/ogg" as="ogg"/>
+          <treat mimetype="audio/ogg" as="ogg"/>
+          <treat mimetype="audio/x-flac" as="flac"/>
+          <treat mimetype="audio/x-ms-wma" as="wma"/>
+          <treat mimetype="audio/x-wavpack" as="wv"/>
+          <treat mimetype="image/jpeg" as="jpg"/>
+          <treat mimetype="audio/x-mpegurl" as="playlist"/>
+          <treat mimetype="audio/x-scpls" as="playlist"/>
+          <treat mimetype="audio/x-wav" as="pcm"/>
+          <treat mimetype="audio/L16" as="pcm"/>
+          <treat mimetype="video/x-msvideo" as="avi"/>
+          <treat mimetype="video/mp4" as="mp4"/>
+          <treat mimetype="audio/mp4" as="mp4"/>
+          <treat mimetype="application/x-iso9660" as="dvd"/>
+          <treat mimetype="application/x-iso9660-image" as="dvd"/>
+        </mimetype-contenttype>
+      </mappings>
+      <online-content>
+        <YouTube enabled="no" refresh="28800" update-at-start="no" purge-after="604800" racy-content="exclude" format="mp4" hd="no">
+          <favorites user="mediatomb"/>
+          <standardfeed feed="most_viewed" time-range="today"/>
+          <playlists user="mediatomb"/>
+          <uploads user="mediatomb"/>
+          <standardfeed feed="recently_featured" time-range="today"/>
+        </YouTube>
+      </online-content>
+    </import>
+    <transcoding enabled="${if cfg.transcoding then "yes" else "no"}">
+      <mimetype-profile-mappings>
+        <transcode mimetype="video/x-flv" using="vlcmpeg"/>
+        <transcode mimetype="application/ogg" using="vlcmpeg"/>
+        <transcode mimetype="application/ogg" using="oggflac2raw"/>
+        <transcode mimetype="audio/x-flac" using="oggflac2raw"/>
+      </mimetype-profile-mappings>
+      <profiles>
+        <profile name="oggflac2raw" enabled="no" type="external">
+          <mimetype>audio/L16</mimetype>
+          <accept-url>no</accept-url>
+          <first-resource>yes</first-resource>
+          <accept-ogg-theora>no</accept-ogg-theora>
+          <agent command="ogg123" arguments="-d raw -o byteorder:big -f %out %in"/>
+          <buffer size="1048576" chunk-size="131072" fill-size="262144"/>
+        </profile>
+        <profile name="vlcmpeg" enabled="no" type="external">
+          <mimetype>video/mpeg</mimetype>
+          <accept-url>yes</accept-url>
+          <first-resource>yes</first-resource>
+          <accept-ogg-theora>yes</accept-ogg-theora>
+          <agent command="vlc" arguments="-I dummy %in --sout #transcode{venc=ffmpeg,vcodec=mp2v,vb=4096,fps=25,aenc=ffmpeg,acodec=mpga,ab=192,samplerate=44100,channels=2}:standard{access=file,mux=ps,dst=%out} vlc:quit"/>
+          <buffer size="14400000" chunk-size="512000" fill-size="120000"/>
+        </profile>
+      </profiles>
+    </transcoding>
+  </config>
+  '';
+
+in {
+
+
+  ###### interface
+
+  options = {
+
+    services.mediatomb = {
+
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to enable the mediatomb DLNA server.
+        '';
+      };
+
+      serverName = mkOption {
+        type = types.string;
+        default = "mediatomb";
+        description = ''
+          How to identify the server on the network.
+        '';
+      };
+
+      ps3Support = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to enable ps3 specific tweaks.
+          WARNING: incompatible with DSM 320 support.
+        '';
+      };
+
+      dsmSupport = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to enable D-Link DSM 320 specific tweaks.
+          WARNING: incompatible with ps3 support.
+        '';
+      };
+
+      tg100Support = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to enable Telegent TG100 specific tweaks.
+        '';
+      };
+
+      transcoding = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to enable transcoding.
+        '';
+      };
+
+      dataDir = mkOption {
+        type = types.path;
+        default = "/var/lib/mediatomb";
+        description = ''
+          The directory where mediatomb stores its state, data, etc.
+        '';
+      };
+
+      user = mkOption {
+        default = "mediatomb";
+        description = "User account under which mediatomb runs.";
+      };
+
+      group = mkOption {
+        default = "mediatomb";
+        description = "Group account under which mediatomb runs.";
+      };
+
+      port = mkOption {
+        default = 49152;
+        description = ''
+          The network port to listen on.
+        '';
+      };
+
+      uuid = mkOption {
+        default = "fdfc8a4e-a3ad-4c1d-b43d-a2eedb03a687";
+        description = ''
+          A unique (on your network) to identify the server by.
+        '';
+      };
+
+      customCfg = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Allow mediatomb to create and use its own config file inside ${cfg.dataDir}.
+        '';
+      };
+    };
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+    systemd.services.mediatomb = {
+      description = "MediaTomb media Server";
+      after = [ "local-fs.target" "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+      path = [ pkgs.mediatomb ];
+      serviceConfig.ExecStart = "${pkgs.mediatomb}/bin/mediatomb -p ${toString cfg.port} ${if cfg.customCfg then "" else "-c ${mtConf}"} -m ${cfg.dataDir}";
+      serviceConfig.User = "${cfg.user}";
+    };
+
+    users.extraGroups = optionalAttrs (cfg.group == "mediatomb") (singleton {
+      name = "mediatomb";
+      gid = gid;
+    });
+
+    users.extraUsers = optionalAttrs (cfg.user == "mediatomb") (singleton {
+      name = "mediatomb";
+      isSystemUser = true;
+      group = cfg.group;
+      home = "${cfg.dataDir}";
+      createHome = true;
+      description = "Mediatomb DLNA Server User";
+    });
+
+    networking.firewall = {
+      allowedUDPPorts = [ 1900 cfg.port ];
+      allowedTCPPorts = [ cfg.port ];
+    };
+  };
+}
diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix
index 3a64d3f09e02..f00c5d1f701d 100644
--- a/nixos/modules/services/networking/networkmanager.nix
+++ b/nixos/modules/services/networking/networkmanager.nix
@@ -183,6 +183,9 @@ in {
       { source = "${networkmanager_pptp}/etc/NetworkManager/VPN/nm-pptp-service.name";
         target = "NetworkManager/VPN/nm-pptp-service.name";
       }
+      { source = "${networkmanager_l2tp}/etc/NetworkManager/VPN/nm-l2tp-service.name";
+        target = "NetworkManager/VPN/nm-l2tp-service.name";
+      }
     ] ++ optional (cfg.appendNameservers == [] || cfg.insertNameservers == [])
            { source = overrideNameserversScript;
              target = "NetworkManager/dispatcher.d/02overridedns";
@@ -197,6 +200,7 @@ in {
         networkmanager_vpnc
         networkmanager_openconnect
         networkmanager_pptp
+        networkmanager_l2tp
         modemmanager
         ];
 
@@ -240,6 +244,7 @@ in {
         networkmanager_vpnc
         networkmanager_openconnect
         networkmanager_pptp
+        networkmanager_l2tp
         modemmanager
         ];
 
diff --git a/nixos/modules/services/x11/desktop-managers/default.nix b/nixos/modules/services/x11/desktop-managers/default.nix
index 9165658a7be7..998bcd354c53 100644
--- a/nixos/modules/services/x11/desktop-managers/default.nix
+++ b/nixos/modules/services/x11/desktop-managers/default.nix
@@ -19,7 +19,7 @@ in
   # E.g., if KDE is enabled, it supersedes xterm.
   imports = [
     ./none.nix ./xterm.nix ./xfce.nix ./kde4.nix ./kde5.nix
-    ./e19.nix ./gnome3.nix ./xbmc.nix ./kodi.nix
+    ./e19.nix ./gnome3.nix ./kodi.nix
   ];
 
   options = {
diff --git a/nixos/modules/services/x11/desktop-managers/xbmc.nix b/nixos/modules/services/x11/desktop-managers/xbmc.nix
deleted file mode 100644
index 97e966ca0197..000000000000
--- a/nixos/modules/services/x11/desktop-managers/xbmc.nix
+++ /dev/null
@@ -1,31 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
-
-let
-  cfg = config.services.xserver.desktopManager.xbmc;
-in
-
-{
-  options = {
-    services.xserver.desktopManager.xbmc = {
-      enable = mkOption {
-        default = false;
-        example = true;
-        description = "Enable the xbmc multimedia center.";
-      };
-    };
-  };
-
-  config = mkIf cfg.enable {
-    services.xserver.desktopManager.session = [{
-      name = "xbmc";
-      start = ''
-        ${pkgs.xbmc}/bin/xbmc --lircdev /var/run/lirc/lircd --standalone &
-        waitPID=$!
-      '';
-    }];
-    
-    environment.systemPackages = [ pkgs.xbmc ];
-  };
-}
\ No newline at end of file
diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix
index e1e472186e37..20eee8e06e07 100644
--- a/nixos/modules/system/boot/luksroot.nix
+++ b/nixos/modules/system/boot/luksroot.nix
@@ -405,29 +405,19 @@ in
 
     # copy the cryptsetup binary and it's dependencies
     boot.initrd.extraUtilsCommands = ''
-      cp -pdv ${pkgs.cryptsetup}/sbin/cryptsetup $out/bin
-
-      cp -pdv ${pkgs.libgcrypt}/lib/libgcrypt*.so.* $out/lib
-      cp -pdv ${pkgs.libgpgerror}/lib/libgpg-error*.so.* $out/lib
-      cp -pdv ${pkgs.cryptsetup}/lib/libcryptsetup*.so.* $out/lib
-      cp -pdv ${pkgs.popt}/lib/libpopt*.so.* $out/lib
+      copy_bin_and_libs ${pkgs.cryptsetup}/bin/cryptsetup
 
       ${optionalString luks.yubikeySupport ''
-      cp -pdv ${pkgs.ykpers}/bin/ykchalresp $out/bin
-      cp -pdv ${pkgs.ykpers}/bin/ykinfo $out/bin
-      cp -pdv ${pkgs.openssl}/bin/openssl $out/bin
-
-      cc -O3 -I${pkgs.openssl}/include -L${pkgs.openssl}/lib ${./pbkdf2-sha512.c} -o $out/bin/pbkdf2-sha512 -lcrypto
-      strip -s $out/bin/pbkdf2-sha512
+        copy_bin_and_libs ${pkgs.ykpers}/bin/ykchalresp
+        copy_bin_and_libs ${pkgs.ykpers}/bin/ykinfo
+        copy_bin_and_libs ${pkgs.openssl}/bin/openssl
 
-      cp -pdv ${pkgs.libusb1}/lib/libusb*.so.* $out/lib
-      cp -pdv ${pkgs.ykpers}/lib/libykpers*.so.* $out/lib
-      cp -pdv ${pkgs.libyubikey}/lib/libyubikey*.so.* $out/lib
-      cp -pdv ${pkgs.openssl}/lib/libssl*.so.* $out/lib
-      cp -pdv ${pkgs.openssl}/lib/libcrypto*.so.* $out/lib
+        cc -O3 -I${pkgs.openssl}/include -L${pkgs.openssl}/lib ${./pbkdf2-sha512.c} -o pbkdf2-sha512 -lcrypto
+        strip -s pbkdf2-sha512
+        copy_bin_and_libs pbkdf2-sha512
 
-      mkdir -p $out/etc/ssl
-      cp -pdv ${pkgs.openssl}/etc/ssl/openssl.cnf $out/etc/ssl
+        mkdir -p $out/etc/ssl
+        cp -pdv ${pkgs.openssl}/etc/ssl/openssl.cnf $out/etc/ssl
 
       cat > $out/bin/openssl-wrap <<EOF
 #!$out/bin/sh
diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix
index 2c3dfd2f460f..8b58eccdcec7 100644
--- a/nixos/modules/system/boot/stage-1.nix
+++ b/nixos/modules/system/boot/stage-1.nix
@@ -39,46 +39,60 @@ let
       mkdir -p $out/bin $out/lib
       ln -s $out/bin $out/sbin
 
-      # Copy what we need from Glibc.
-      cp -pv ${pkgs.glibc}/lib/ld*.so.? $out/lib
-      cp -pv ${pkgs.glibc}/lib/libc.so.* $out/lib
-      cp -pv ${pkgs.glibc}/lib/libm.so.* $out/lib
-      cp -pv ${pkgs.glibc}/lib/libpthread.so.* $out/lib
-      cp -pv ${pkgs.glibc}/lib/librt.so.* $out/lib
-      cp -pv ${pkgs.glibc}/lib/libdl.so.* $out/lib
-      cp -pv ${pkgs.gcc.cc}/lib*/libgcc_s.so.* $out/lib
+      copy_bin_and_libs () {
+        [ -f "$out/bin/$(basename $1)" ] && rm "$out/bin/$(basename $1)"
+        cp -pdv $1 $out/bin
+      }
 
       # Copy BusyBox.
-      cp -pvd ${pkgs.busybox}/bin/* ${pkgs.busybox}/sbin/* $out/bin/
+      for BIN in ${pkgs.busybox}/{s,}bin/*; do
+        copy_bin_and_libs $BIN
+      done
 
       # Copy some utillinux stuff.
-      cp -vf --remove-destination ${pkgs.utillinux}/sbin/blkid $out/bin
-      cp -pdv ${pkgs.utillinux}/lib/libblkid*.so.* $out/lib
-      cp -pdv ${pkgs.utillinux}/lib/libuuid*.so.* $out/lib
+      copy_bin_and_libs ${pkgs.utillinux}/sbin/blkid
 
       # Copy dmsetup and lvm.
-      cp -v ${pkgs.lvm2}/sbin/dmsetup $out/bin/dmsetup
-      cp -v ${pkgs.lvm2}/sbin/lvm $out/bin/lvm
-      cp -v ${pkgs.lvm2}/lib/libdevmapper.so.*.* $out/lib
-      cp -v ${pkgs.systemd}/lib/libsystemd.so.* $out/lib
+      copy_bin_and_libs ${pkgs.lvm2}/sbin/dmsetup
+      copy_bin_and_libs ${pkgs.lvm2}/sbin/lvm
 
       # Add RAID mdadm tool.
-      cp -v ${pkgs.mdadm}/sbin/mdadm $out/bin/mdadm
+      copy_bin_and_libs ${pkgs.mdadm}/sbin/mdadm
 
       # Copy udev.
-      cp -v ${udev}/lib/systemd/systemd-udevd ${udev}/bin/udevadm $out/bin
-      cp -v ${udev}/lib/udev/*_id $out/bin
-      cp -pdv ${udev}/lib/libudev.so.* $out/lib
-      cp -v ${pkgs.kmod}/lib/libkmod.so.* $out/lib
-      cp -v ${pkgs.acl}/lib/libacl.so.* $out/lib
-      cp -v ${pkgs.attr}/lib/libattr.so.* $out/lib
+      copy_bin_and_libs ${udev}/lib/systemd/systemd-udevd
+      copy_bin_and_libs ${udev}/bin/udevadm
+      for BIN in ${udev}/lib/udev/*_id; do
+        copy_bin_and_libs $BIN
+      done
 
       # Copy modprobe.
-      cp -v ${pkgs.kmod}/bin/kmod $out/bin/
+      copy_bin_and_libs ${pkgs.kmod}/bin/kmod
       ln -sf kmod $out/bin/modprobe
 
       ${config.boot.initrd.extraUtilsCommands}
 
+      # Copy ld manually since it isn't detected correctly
+      cp -pv ${pkgs.glibc}/lib/ld*.so.? $out/lib
+
+      # Copy all of the needed libraries for the binaries
+      for BIN in $(find $out/{bin,sbin} -type f); do
+        echo "Copying libs for bin $BIN"
+        LDD="$(ldd $BIN)" || continue
+        LIBS="$(echo "$LDD" | awk '{print $3}' | sed '/^$/d')"
+        for LIB in $LIBS; do
+          [ ! -f "$out/lib/$(basename $LIB)" ] && cp -pdv $LIB $out/lib
+          while [ "$(readlink $LIB)" != "" ]; do
+            LINK="$(readlink $LIB)"
+            if [ "${LINK:0:1}" != "/" ]; then
+              LINK="$(dirname $LIB)/$LINK"
+            fi
+            LIB="$LINK"
+            [ ! -f "$out/lib/$(basename $LIB)" ] && cp -pdv $LIB $out/lib
+          done
+        done
+      done
+
       # Strip binaries further than normal.
       chmod -R u+w $out
       stripDirs "lib bin" "-s"
@@ -100,10 +114,11 @@ let
       echo "testing patched programs..."
       $out/bin/ash -c 'echo hello world' | grep "hello world"
       export LD_LIBRARY_PATH=$out/lib
-      $out/bin/mount --help 2>&1 | grep "BusyBox"
+      $out/bin/mount --help 2>&1 | grep -q "BusyBox"
+      $out/bin/blkid --help 2>&1 | grep -q 'libblkid'
       $out/bin/udevadm --version
-      $out/bin/dmsetup --version 2>&1 | tee -a log | grep "version:"
-      LVM_SYSTEM_DIR=$out $out/bin/lvm version 2>&1 | tee -a log | grep "LVM"
+      $out/bin/dmsetup --version 2>&1 | tee -a log | grep -q "version:"
+      LVM_SYSTEM_DIR=$out $out/bin/lvm version 2>&1 | tee -a log | grep -q "LVM"
       $out/bin/mdadm --version
 
       ${config.boot.initrd.extraUtilsCommandsTest}
diff --git a/nixos/modules/tasks/filesystems/btrfs.nix b/nixos/modules/tasks/filesystems/btrfs.nix
index d0a2ac645e0b..049f7708d739 100644
--- a/nixos/modules/tasks/filesystems/btrfs.nix
+++ b/nixos/modules/tasks/filesystems/btrfs.nix
@@ -17,13 +17,9 @@ in
 
     boot.initrd.extraUtilsCommands = mkIf inInitrd
       ''
-        mkdir -p $out/bin
-        cp -v ${pkgs.btrfsProgs}/bin/btrfs $out/bin
+        copy_bin_and_libs ${pkgs.btrfsProgs}/bin/btrfs
         ln -sv btrfs $out/bin/btrfsck
         ln -sv btrfsck $out/bin/fsck.btrfs
-        # !!! Increases uncompressed initrd by 240k
-        cp -pv ${pkgs.zlib}/lib/libz.so* $out/lib
-        cp -pv ${pkgs.lzo}/lib/liblzo2.so* $out/lib
       '';
 
     boot.initrd.extraUtilsCommandsTest = mkIf inInitrd
diff --git a/nixos/modules/tasks/filesystems/cifs.nix b/nixos/modules/tasks/filesystems/cifs.nix
index c60f175db841..3932b5c9acf9 100644
--- a/nixos/modules/tasks/filesystems/cifs.nix
+++ b/nixos/modules/tasks/filesystems/cifs.nix
@@ -18,7 +18,7 @@ in
 
     boot.initrd.extraUtilsCommands = mkIf inInitrd
       ''
-        cp -v ${pkgs.cifs_utils}/sbin/mount.cifs $out/bin
+        copy_bin_and_libs ${pkgs.cifs_utils}/sbin/mount.cifs
       '';
 
   };
diff --git a/nixos/modules/tasks/filesystems/ext.nix b/nixos/modules/tasks/filesystems/ext.nix
index 24592e9d5882..cc9d0ef37d59 100644
--- a/nixos/modules/tasks/filesystems/ext.nix
+++ b/nixos/modules/tasks/filesystems/ext.nix
@@ -10,12 +10,11 @@
     boot.initrd.extraUtilsCommands =
       ''
         # Copy e2fsck and friends.
-        cp -v ${pkgs.e2fsprogs}/sbin/e2fsck $out/bin
-        cp -v ${pkgs.e2fsprogs}/sbin/tune2fs $out/bin
+        copy_bin_and_libs ${pkgs.e2fsprogs}/sbin/e2fsck
+        copy_bin_and_libs ${pkgs.e2fsprogs}/sbin/tune2fs
         ln -sv e2fsck $out/bin/fsck.ext2
         ln -sv e2fsck $out/bin/fsck.ext3
         ln -sv e2fsck $out/bin/fsck.ext4
-        cp -pdv ${pkgs.e2fsprogs}/lib/lib*.so.* $out/lib
       '';
 
   };
diff --git a/nixos/modules/tasks/filesystems/f2fs.nix b/nixos/modules/tasks/filesystems/f2fs.nix
index 1ed7b1b6a62e..430ac630a885 100644
--- a/nixos/modules/tasks/filesystems/f2fs.nix
+++ b/nixos/modules/tasks/filesystems/f2fs.nix
@@ -13,9 +13,7 @@ in
     boot.initrd.availableKernelModules = mkIf inInitrd [ "f2fs" ];
 
     boot.initrd.extraUtilsCommands = mkIf inInitrd ''
-      mkdir -p $out/bin $out/lib
-      cp -v   ${pkgs.f2fs-tools}/sbin/fsck.f2fs $out/bin
-      cp -pdv ${pkgs.f2fs-tools}/lib/lib*.so.* $out/lib
+      copy_bin_and_libs ${pkgs.f2fs-tools}/sbin/fsck.f2fs
     '';
   };
 }
diff --git a/nixos/modules/tasks/filesystems/jfs.nix b/nixos/modules/tasks/filesystems/jfs.nix
index b7091ce9b184..fc3905c7dc20 100644
--- a/nixos/modules/tasks/filesystems/jfs.nix
+++ b/nixos/modules/tasks/filesystems/jfs.nix
@@ -13,7 +13,7 @@ in
     boot.initrd.kernelModules = mkIf inInitrd [ "jfs" ];
 
     boot.initrd.extraUtilsCommands = mkIf inInitrd ''
-      cp -v ${pkgs.jfsutils}/sbin/fsck.jfs "$out/bin/"
+      copy_bin_and_libs ${pkgs.jfsutils}/sbin/fsck.jfs
     '';
   };
 }
diff --git a/nixos/modules/tasks/filesystems/reiserfs.nix b/nixos/modules/tasks/filesystems/reiserfs.nix
index a3bfb3fed8ef..ab4c43e2ab82 100644
--- a/nixos/modules/tasks/filesystems/reiserfs.nix
+++ b/nixos/modules/tasks/filesystems/reiserfs.nix
@@ -17,8 +17,8 @@ in
 
     boot.initrd.extraUtilsCommands = mkIf inInitrd
       ''
-        cp -v ${pkgs.reiserfsprogs}/sbin/reiserfsck $out/bin
-        ln -sv reiserfsck $out/bin/fsck.reiserfs
+        copy_bin_and_libs ${pkgs.reiserfsprogs}/sbin/reiserfsck
+        ln -s reiserfsck $out/bin/fsck.reiserfs
       '';
 
   };
diff --git a/nixos/modules/tasks/filesystems/unionfs-fuse.nix b/nixos/modules/tasks/filesystems/unionfs-fuse.nix
index fe195e0db0b6..3e38bffa3ba2 100644
--- a/nixos/modules/tasks/filesystems/unionfs-fuse.nix
+++ b/nixos/modules/tasks/filesystems/unionfs-fuse.nix
@@ -7,9 +7,8 @@
       boot.initrd.kernelModules = [ "fuse" ];
 
       boot.initrd.extraUtilsCommands = ''
-        cp -v ${pkgs.fuse}/lib/libfuse* $out/lib
-        cp -v ${pkgs.fuse}/sbin/mount.fuse $out/bin
-        cp -v ${pkgs.unionfs-fuse}/bin/unionfs $out/bin
+        copy_bin_and_libs ${pkgs.fuse}/sbin/mount.fuse
+        copy_bin_and_libs ${pkgs.unionfs-fuse}/bin/unionfs
         substitute ${pkgs.unionfs-fuse}/sbin/mount.unionfs-fuse $out/bin/mount.unionfs-fuse \
           --replace '${pkgs.bash}/bin/bash' /bin/sh \
           --replace '${pkgs.fuse}/sbin' /bin \
diff --git a/nixos/modules/tasks/filesystems/vfat.nix b/nixos/modules/tasks/filesystems/vfat.nix
index 4cfe6e208f7e..958e27ae8a32 100644
--- a/nixos/modules/tasks/filesystems/vfat.nix
+++ b/nixos/modules/tasks/filesystems/vfat.nix
@@ -17,7 +17,7 @@ in
 
     boot.initrd.extraUtilsCommands = mkIf inInitrd
       ''
-        cp -v ${pkgs.dosfstools}/sbin/dosfsck $out/bin
+        copy_bin_and_libs ${pkgs.dosfstools}/sbin/dosfsck
         ln -sv dosfsck $out/bin/fsck.vfat
       '';
 
diff --git a/nixos/modules/tasks/filesystems/xfs.nix b/nixos/modules/tasks/filesystems/xfs.nix
index 5225b62a88c5..d7c3930f4a3c 100644
--- a/nixos/modules/tasks/filesystems/xfs.nix
+++ b/nixos/modules/tasks/filesystems/xfs.nix
@@ -17,7 +17,7 @@ in
 
     boot.initrd.extraUtilsCommands = mkIf inInitrd
       ''
-        cp -v ${pkgs.xfsprogs}/sbin/fsck.xfs $out/bin
+        copy_bin_and_libs ${pkgs.xfsprogs}/sbin/fsck.xfs
       '';
 
     # Trick just to set 'sh' after the extraUtils nuke-refs.
diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix
index 1ac89c4c2554..d4b10e9ed09e 100644
--- a/nixos/modules/tasks/filesystems/zfs.nix
+++ b/nixos/modules/tasks/filesystems/zfs.nix
@@ -203,11 +203,14 @@ in
         kernelModules = [ "spl" "zfs" ];
         extraUtilsCommands =
           ''
-            cp -v ${zfsUserPkg}/sbin/zfs $out/bin
-            cp -v ${zfsUserPkg}/sbin/zdb $out/bin
-            cp -v ${zfsUserPkg}/sbin/zpool $out/bin
-            cp -pdv ${zfsUserPkg}/lib/lib*.so* $out/lib
-            cp -pdv ${pkgs.zlib}/lib/lib*.so* $out/lib
+            copy_bin_and_libs ${zfsUserPkg}/sbin/zfs
+            copy_bin_and_libs ${zfsUserPkg}/sbin/zdb
+            copy_bin_and_libs ${zfsUserPkg}/sbin/zpool
+          '';
+        extraUtilsCommandsTest = mkIf inInitrd
+          ''
+            $out/bin/zfs --help >/dev/null 2>&1
+            $out/bin/zpool --help >/dev/null 2>&1
           '';
         postDeviceCommands = concatStringsSep "\n" ([''
             ZFS_FORCE="${optionalString cfgZfs.forceImportRoot "-f"}"
diff --git a/nixos/modules/virtualisation/amazon-image.nix b/nixos/modules/virtualisation/amazon-image.nix
index 0473c2454e22..600a29f31bc5 100644
--- a/nixos/modules/virtualisation/amazon-image.nix
+++ b/nixos/modules/virtualisation/amazon-image.nix
@@ -165,7 +165,7 @@ in
     boot.initrd.extraUtilsCommands =
       ''
         # We need swapon in the initrd.
-        cp --remove-destination ${pkgs.utillinux}/sbin/swapon $out/bin
+        copy_bin_and_libs ${pkgs.utillinux}/sbin/swapon
       '';
 
     # Don't put old configurations in the GRUB menu.  The user has no
diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix
index a5a133dfa5dc..8c7e840910de 100644
--- a/nixos/modules/virtualisation/qemu-vm.nix
+++ b/nixos/modules/virtualisation/qemu-vm.nix
@@ -346,7 +346,7 @@ in
     boot.initrd.extraUtilsCommands =
       ''
         # We need mke2fs in the initrd.
-        cp -vf --remove-destination ${pkgs.e2fsprogs}/sbin/mke2fs $out/bin
+        copy_bin_and_libs ${pkgs.e2fsprogs}/sbin/mke2fs
       '';
 
     boot.initrd.postDeviceCommands =
diff --git a/nixos/release-combined.nix b/nixos/release-combined.nix
index 22d14aa57a0c..cb1c200ab475 100644
--- a/nixos/release-combined.nix
+++ b/nixos/release-combined.nix
@@ -57,6 +57,7 @@ in rec {
         (all nixos.tests.installer.simple)
         (all nixos.tests.installer.simpleLabels)
         (all nixos.tests.installer.simpleProvided)
+        (all nixos.tests.installer.swraid)
         (all nixos.tests.installer.btrfsSimple)
         (all nixos.tests.installer.btrfsSubvols)
         (all nixos.tests.installer.btrfsSubvolDefault)
diff --git a/nixos/release.nix b/nixos/release.nix
index f84501d741a6..4c2a1c76f1cb 100644
--- a/nixos/release.nix
+++ b/nixos/release.nix
@@ -260,6 +260,7 @@ in rec {
   tests.installer.simple = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).simple.test);
   tests.installer.simpleLabels = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).simpleLabels.test);
   tests.installer.simpleProvided = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).simpleProvided.test);
+  tests.installer.swraid = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).swraid.test);
   tests.installer.btrfsSimple = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).btrfsSimple.test);
   tests.installer.btrfsSubvols = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).btrfsSubvols.test);
   tests.installer.btrfsSubvolDefault = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).btrfsSubvolDefault.test);
@@ -310,6 +311,10 @@ in rec {
   tests.udisks2 = callTest tests/udisks2.nix {};
   tests.virtualbox = callTest tests/virtualbox.nix {};
   tests.xfce = callTest tests/xfce.nix {};
+  tests.bootBiosCdrom = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootBiosCdrom);
+  tests.bootBiosUsb = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootBiosUsb);
+  tests.bootUefiCdrom = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootUefiCdrom);
+  tests.bootUefiUsb = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootUefiUsb);
 
 
   /* Build a bunch of typical closures so that Hydra can keep track of
diff --git a/nixos/tests/boot.nix b/nixos/tests/boot.nix
new file mode 100644
index 000000000000..2fdbb0c00b85
--- /dev/null
+++ b/nixos/tests/boot.nix
@@ -0,0 +1,63 @@
+{ system ? builtins.currentSystem }:
+
+with import ../lib/testing.nix { inherit system; };
+with import ../lib/qemu-flags.nix;
+with pkgs.lib;
+
+let
+
+  iso =
+    (import ../lib/eval-config.nix {
+      inherit system;
+      modules =
+        [ ../modules/installer/cd-dvd/installation-cd-minimal.nix
+          ../modules/testing/test-instrumentation.nix
+          { key = "serial";
+            boot.loader.grub.timeout = mkOverride 0 0;
+
+            # The test cannot access the network, so any sources we
+            # need must be included in the ISO.
+            isoImage.storeContents =
+              [ pkgs.glibcLocales
+                pkgs.sudo
+                pkgs.docbook5
+                pkgs.docbook5_xsl
+                pkgs.grub
+                pkgs.perlPackages.XMLLibXML
+                pkgs.unionfs-fuse
+                pkgs.gummiboot
+              ];
+          }
+        ];
+    }).config.system.build.isoImage;
+
+  makeBootTest = name: machineConfig:
+    makeTest {
+      inherit iso;
+      name = "boot-" + name;
+      nodes = { };
+      testScript =
+        ''
+          my $machine = createMachine({ ${machineConfig}, qemuFlags => '-m 768' });
+          $machine->start;
+          $machine->waitForUnit("multi-user.target");
+          $machine->shutdown;
+        '';
+    };
+in {
+    bootBiosCdrom = makeBootTest "bios-cdrom" ''
+        cdrom => glob("${iso}/iso/*.iso")
+      '';
+    bootBiosUsb = makeBootTest "bios-usb" ''
+        usb => glob("${iso}/iso/*.iso")
+      '';
+    bootUefiCdrom = makeBootTest "uefi-cdrom" ''
+        cdrom => glob("${iso}/iso/*.iso"),
+        bios => '${pkgs.OVMF}/FV/OVMF.fd'
+      '';
+    bootUefiUsb = makeBootTest "uefi-usb" ''
+        usb => glob("${iso}/iso/*.iso"),
+        bios => '${pkgs.OVMF}/FV/OVMF.fd'
+      '';
+  }
+
diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix
index c7815bde3f5c..af87705b9279 100644
--- a/nixos/tests/installer.nix
+++ b/nixos/tests/installer.nix
@@ -327,12 +327,12 @@ in {
           $machine->succeed(
               "parted /dev/vda --"
               . " mklabel msdos"
-              . " mkpart primary ext2 1M 30MB" # /boot
-              . " mkpart extended 30M -1s"
-              . " mkpart logical 31M 1531M" # md0 (root), first device
-              . " mkpart logical 1540M 3040M" # md0 (root), second device
-              . " mkpart logical 3050M 3306M" # md1 (swap), first device
-              . " mkpart logical 3320M 3576M", # md1 (swap), second device
+              . " mkpart primary ext2 1M 100MB" # /boot
+              . " mkpart extended 100M -1s"
+              . " mkpart logical 102M 1602M" # md0 (root), first device
+              . " mkpart logical 1603M 3103M" # md0 (root), second device
+              . " mkpart logical 3104M 3360M" # md1 (swap), first device
+              . " mkpart logical 3361M 3617M", # md1 (swap), second device
               "udevadm settle",
               "ls -l /dev/vda* >&2",
               "cat /proc/partitions >&2",
diff --git a/nixos/tests/virtualbox.nix b/nixos/tests/virtualbox.nix
index b2b1ec877798..febe0923ba23 100644
--- a/nixos/tests/virtualbox.nix
+++ b/nixos/tests/virtualbox.nix
@@ -39,9 +39,8 @@ import ./make-test.nix ({ pkgs, ... }: with pkgs.lib; let
     ];
 
     boot.initrd.extraUtilsCommands = ''
-      cp -av -t "$out/bin/" \
-        "${pkgs.linuxPackages.virtualboxGuestAdditions}/sbin/mount.vboxsf" \
-        "${pkgs.utillinux}/bin/unshare"
+      copy_bin_and_libs "${pkgs.linuxPackages.virtualboxGuestAdditions}/sbin/mount.vboxsf"
+      copy_bin_and_libs "${pkgs.utillinux}/bin/unshare"
       ${(attrs.extraUtilsCommands or (const "")) pkgs}
     '';