Subversion Repositories zfs_utils

Rev

Rev 29 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

#! /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;