#! /usr/bin/env perl use strict; use warnings; use Data::Dumper; # create an encrypted ZFS pool using geli # @DATADRIVES: list of drives to use for data # @DEDUPDRIVES: list of drives to use for deduplication (optional) # $RAIDLEVEL: raidz, raidz2, mirror, etc. # $pool: name of the pool to create # $poolSettings: settings to apply to the pool after creation # $combinedKeyFile: path to the combined geli key file, passed as first argument my @DATADRIVES=qw'da7 da6'; # list of all drives to use my @DEDUPDRIVES= (); # list of drives to use for deduplication (optional) my $RAIDLEVEL = 'mirror'; # Raid level to create: mirror raidz raidz2 my $pool = 'backup'; # pool name to create. Destoyed if it exists my $poolSettings = "atime=off compress=gzip-9 volmode=full"; # settings to apply to the pool after creation $poolSettings .= ' dedup=on' if @DEDUPDRIVES; # if dedup drives are used, enable dedup on pool my @alldrives = (@DATADRIVES,@DEDUPDRIVES); my $alldrives = join( ' ', @alldrives ); sub runCommand { my $command = shift; print "$command\n"; #`$command`; } my $combinedKeyFile = shift; die "No combined key file provided\n" unless defined $combinedKeyFile; # destroy the pool, if it exists if ( `zpool list -H | grep '^$pool'` ) { &runCommand( "zpool destroy $pool" ); } # if geli sees some disks already created, detach and clear them. my @disks = `geli status | grep '^da' | cut -d' ' -f1 2>/dev/null`; chomp @disks; if ( join ' ', @disks ) { warn "Detaching and clearing existing geli disks: " . join( ' ', @disks ) . "\nPress Enter to continue..."; <>; my $temp = join( ' ', @disks ); &runCommand( "geli detach $temp" ); # detach first $temp =~ s/\.eli//g; # remove .eli extension &runCommand( "geli clear $temp"); # clear after detaching } # remove any partitions from the drives my @partitionedDrives = `gpart list -a | grep 'Geom name:' | rev | cut -d' ' -f1 | rev`; chomp @partitionedDrives; my %partitionedDrives = map{ $_=>1 } @partitionedDrives; # remove any partitions from the drives we are going to use foreach my $drive ( @DATADRIVES,@DEDUPDRIVES ) { &runCommand( "gpart destroy -F $drive" ) if $partitionedDrives{$drive}; } &runCommand( "geli init -e AES-XTS -l 256 -s 4096 -K $combinedKeyFile -P " . join( ' ', @alldrives ) ); &runCommand( "geli configure -t " . join( ' ', @alldrives ) ); &runCommand( "geli attach -k $combinedKeyFile -p " . join( ' ', @alldrives ) ); &runCommand( "zpool create -f $pool $RAIDLEVEL " . join( ' ', map{ $_ . '.eli' } @DATADRIVES) . ( @DEDUPDRIVES ? ' dedup mirror ' . join( ' ', map{ $_ . '.eli' } @DEDUPDRIVES) : '' ) ); &runCommand( "zfs set $poolSettings $pool" ); 1;