Add filesystem option to automatically grow to the maximum size

This is primarily for EC2 and other cloud environments, where the disk
may be bigger than the original image.
This commit is contained in:
Eelco Dolstra 2015-09-24 18:13:14 +02:00
parent f40c7ed143
commit 9d92bd7845
5 changed files with 71 additions and 5 deletions

View file

@ -290,10 +290,23 @@ mountFS() {
if [ -z "$fsType" ]; then fsType=auto; fi
fi
echo "$device /mnt-root$mountPoint $fsType $options" >> /etc/fstab
# Filter out x- options, which busybox doesn't do yet.
local optionsFiltered="$(IFS=,; for i in $options; do if [ "${i:0:2}" != "x-" ]; then echo -n $i,; fi; done)"
echo "$device /mnt-root$mountPoint $fsType $optionsFiltered" >> /etc/fstab
checkFS "$device" "$fsType"
# Optionally resize the filesystem.
case $options in
*x-nixos.autoresize*)
if [ "$fsType" = ext2 -o "$fsType" = ext3 -o "$fsType" = ext4 ]; then
echo "resizing $device..."
resize2fs "$device"
fi
;;
esac
# Create backing directories for unionfs-fuse.
if [ "$fsType" = unionfs-fuse ]; then
for i in $(IFS=:; echo ${options##*,dirs=}); do

View file

@ -70,6 +70,12 @@ let
copy_bin_and_libs ${pkgs.kmod}/bin/kmod
ln -sf kmod $out/bin/modprobe
# Copy resize2fs if needed.
${optionalString (any (fs: fs.autoResize) (attrValues config.fileSystems)) ''
# We need mke2fs in the initrd.
copy_bin_and_libs ${pkgs.e2fsprogs}/sbin/resize2fs
''}
${config.boot.initrd.extraUtilsCommands}
# Copy ld manually since it isn't detected correctly
@ -393,7 +399,6 @@ in
}
];
system.build.bootStage1 = bootStage1;
system.build.initialRamdisk = initialRamdisk;
system.build.extraUtils = extraUtils;

View file

@ -7,7 +7,7 @@ let
fileSystems = attrValues config.fileSystems;
prioOption = prio: optionalString (prio !=null) " pri=${toString prio}";
prioOption = prio: optionalString (prio != null) " pri=${toString prio}";
fileSystemOpts = { name, config, ... }: {
@ -43,7 +43,7 @@ let
options = mkOption {
default = "defaults";
example = "data=journal";
type = types.commas;
type = types.commas; # FIXME: should be a list
description = "Options used to mount the file system.";
};
@ -58,6 +58,17 @@ let
'';
};
autoResize = mkOption {
default = false;
type = types.bool;
description = ''
If set, the filesystem is grown to its maximum size before
being mounted. (This is typically the size of the containing
partition.) This is currently only supported for ext2/3/4
filesystems that are mounted during early boot.
'';
};
noCheck = mkOption {
default = false;
type = types.bool;
@ -69,6 +80,7 @@ let
config = {
mountPoint = mkDefault name;
device = mkIf (config.fsType == "tmpfs") (mkDefault config.fsType);
options = mkIf config.autoResize "x-nixos.autoresize";
};
};

View file

@ -2,4 +2,4 @@ f: { system ? builtins.currentSystem, ... } @ args:
with import ../lib/testing.nix { inherit system; };
makeTest (if builtins.isFunction f then f (args // { inherit pkgs; }) else f)
makeTest (if builtins.isFunction f then f (args // { inherit pkgs; inherit (pkgs) lib; }) else f)

View file

@ -0,0 +1,36 @@
import ./make-test.nix ({ pkgs, lib, ...} : {
meta.maintainers = [ lib.maintainers.eelco ];
machine = { config, pkgs, ... }: {
virtualisation.diskSize = 512;
fileSystems = lib.mkVMOverride {
"/".autoResize = true;
};
};
testScript =
''
# Create a VM with a 512 MiB disk.
$machine->start;
$machine->waitForUnit("multi-user.target");
my $blocks = $machine->succeed("stat -c %b -f /");
my $bsize = $machine->succeed("stat -c %S -f /");
my $size = $blocks * $bsize;
die "wrong free space $size" if $size < 480 * 1024 * 1024 || $size > 512 * 1024 * 1024;
$machine->succeed("touch /marker");
$machine->shutdown;
# Grow the disk to 1024 MiB.
system("qemu-img resize vm-state-machine/machine.qcow2 1024M") == 0 or die;
# Start the VM again and check whether the initrd has correctly
# grown the root filesystem.
$machine->start;
$machine->waitForUnit("multi-user.target");
$machine->succeed("[ -e /marker ]");
my $blocks = $machine->succeed("stat -c %b -f /");
my $size = $blocks * $bsize;
die "wrong free space $size" if $size < 980 * 1024 * 1024 || $size > 1024 * 1024 * 1024;
'';
})