diff --git a/mxraid/mxraid_assemble b/mxraid/mxraid_assemble index 82150ac..1746d91 100755 --- a/mxraid/mxraid_assemble +++ b/mxraid/mxraid_assemble @@ -30,17 +30,23 @@ sub exec_usage { options: - -a assemble arrays when run as root - -c check database - -d file alternative database file - -h print this help and exit - -l list arrays on host, with -v will also show candidates - -m monochrome warnings (for the purists) - -n label print config records for new assemblies on host - -q be quiet - -v be more verbose - -V print Version information and exit - + -a assemble arrays when run as root + -c check database + -d file alternative database file + -h print this help and exit + -l list arrays on host, with -v will also show candidates + -m monochrome warnings (for the purists) + -n label print config records for new assemblies on host + -q be quiet + -r l:d(:m) config hints, if not a RAID 6 with 16 disks (level, disks, match) + -v be more verbose + -V print Version information and exit + + example (list state and assist in assembling a RAID1): + + mxraid_assemble -lv -n D0014 -r 1:2:flash + + __HELP =things to come @@ -81,7 +87,7 @@ sub check_enclosures { my $ROOT=$<==0?1:0; my %opts; -getopts('acd:hlmn:qvV', \%opts) or die "# ERROR: getopts failed, try -h.\n"; # Values in %opts +getopts('acd:hlmn:qr:vV', \%opts) or die "# ERROR: getopts failed, try -h.\n"; # Values in %opts exec_usage if $opts{h}; exec_version if $opts{V}; @@ -154,10 +160,16 @@ if ($opts{n}) { my $color = MxRaid::Color->new(); $do_default_action = 0; - my ($entry, $cnt) = ('',0); - my @candidates; + my ($entry, $cnt, $size) = ('', 0, 0); + my ($level, $num_wanted, $match) = (6, 16, undef); + my $chunk_size = 512; + my $dev_no = 0; my @mounts = split m/\n/, `cat /proc/self/mounts`; + my @candidates; + if ($opts{r}) { + ($level,$num_wanted,$match) = split m/:/, $opts{r}; + } $entry .= $opts{n}.':'; for my $rec (@{$hd->non_raid_disks()}) { my $dev = $rec->[0]; @@ -166,44 +178,68 @@ if ($opts{n}) { warn "# NOTE: /dev/$dev is mounted, skipping.\n" if $VERBOSE >= 2; next; } + if (defined $match) { + next unless ($rec->[1] =~ m/$match/i or $rec->[2] =~ m/$match/i); + } push @candidates, $rec->[0]; $entry .= ' '.$rec->[1]; + $size += $rec->[3]; $cnt++; } - # warn "# NOTE: got $cnt disk(s), default is 16.\n" if $cnt != 16; - # warn "# NOTE: label '$opts{n}' doesn't look good.\n" unless $opts{n} =~ m/^[CDM][\da-f]\d{3}$/; - if ($cnt != 16) { - my $msg = "got $cnt disk(s), default is 16."; + if ($cnt != $num_wanted) { + my $msg = "got $cnt disk(s), expected $num_wanted."; $msg = $color->t_red($msg) unless $opts{m}; print "# NOTE: $msg\n"; } - if ($opts{n} !~ m/^[CDM][\da-f]\d{3}$/) { - my $msg = "label '$opts{n}' doesn't look good."; + my $msg = "label '$opts{n}' doesn't follow the CDM scheme."; $msg = $color->t_red($msg) unless $opts{m}; print "# NOTE: $msg\n"; } - - my $level=6; - my $chunk_size=512; - my $dev='md127'; if ($cnt) { - print "# Record for '$MDADMCONF_DB'\n"; + if ($level == 0) { + # do nothing + } elsif ($level == 1) { + $size /= 2; + } elsif ($level == 5 and $cnt>1) { + $size = int ((($cnt-1)/$cnt) * $size); + } elsif ($level == 6 and $cnt>2) { + $size = int ((($cnt-2)/$cnt) * $size); + } else { + print "# RAID level $level not handled ($cnt disks)\n"; + } + $size /= 1024**4; # TB + + + # 100TB -> 512k, 50TB -> 256k + while ( $size/$chunk_size < 0.115 and $chunk_size > 64) { + $chunk_size/=2; + } + + while (-e "/dev/md$dev_no") { + $dev_no++; + die "# ERROR: out of devices ($dev_no). Stopped", if $dev_no >= 128; + } + + my $dev='md'.$dev_no; + print "# Record for '$MDADMCONF_DB'\n\n"; print $entry; - print "\n\n"; - print "# Hint for creation with mdadm:\n\n"; + print "\n\n\n"; + print "# Hint for creation with mdadm & mkfs.xfs:\n\n"; printf "mdadm -C /dev/%s -l %d -n %d -N %s -c %s %s\n\n", $dev, $level, $cnt, $opts{n}, - '0x0', + $chunk_size, '/dev/' . join(' /dev/', @candidates); - my $msg = 'always check the chunk-size (-c)!'; - printf "# HINT: %s (8TB:512/4TB:256/2TB:128)\n\n", $opts{m}?$msg:$color->t_red($msg); + printf "mkfs.xfs -L %s /dev/%s\n\n", lc($opts{n}), $dev; + + + printf "# Note: size of array will be %.1f TB\n\n", $size; } }