Commit 6a4c2c0b authored by Mike Hibler's avatar Mike Hibler

Another short-term tweak to LVM creation policy--avoid SSDs.

We don't want to stripe an SSD in with regular HDs (specifically at
Wisconsin) when creating the LVM VG for vnodes. They are typically a
lot smaller and won't improve performance of the VG since any operation
will likely be limited by the speed of the rotating disks.
parent 4eab7986
......@@ -171,11 +171,31 @@ sub removePortForward($) {
return forwardPort($ref,1);
}
# Is the given device an SSD?
sub isSSD($)
{
my ($dev) = @_;
my $isssd = 0;
if (-e "/dev/$dev" && -x "/sbin/hdparm" &&
open(HFD, "/sbin/hdparm -I /dev/$dev 2>/dev/null |")) {
while (my $line = <HFD>) {
chomp($line);
if ($line =~ /:\s+solid state device$/i) {
$isssd = 1;
last;
}
}
close(HFD);
}
return $isssd;
}
#
# A spare disk or disk partition is one whose partition ID is 0 and is not
# mounted and is not in /etc/fstab AND is >= the specified minsize (in MiB).
# Yes, this means it's possible that we might steal partitions that are
# in /etc/fstab by UUID -- oh well.
# Note that we do now check labels and UUIDs as well as names in fstab.
#
# This function returns a hash of:
# device name => part number => {size,path}
......@@ -184,8 +204,11 @@ sub removePortForward($) {
# Note that a device name => {size,fullpath} entry is filled IF the device
# has no partitions.
#
sub findSpareDisks($) {
my ($minsize) = @_;
# If the optional $skipssds is set, we identify each disk as an SSD or not,
# skipping ones that are.
#
sub findSpareDisks($;$) {
my ($minsize,$skipssds) = @_;
my %retval = ();
my %mounts = ();
......@@ -230,6 +253,7 @@ sub findSpareDisks($) {
open (PFD,"/proc/partitions")
or die "open(/proc/partitions): $!";
while (my $line = <PFD>) {
chomp($line);
......@@ -272,6 +296,16 @@ sub findSpareDisks($) {
$dev = $1;
}
# This is a partition on an earlier discovered disk device,
# ignore the disk device. This is signalled by clearing the size.
if (exists($retval{$dev}{"size"})) {
delete $retval{$dev}{"size"};
delete $retval{$dev}{"path"};
if (scalar(keys(%{$retval{$dev}})) == 0) {
delete $retval{$dev};
}
}
# XXX don't include extended partitions (the reason is to filter
# out pseudo partitions that linux creates for bsd disklabel
# slices -- we don't want to use those!
......@@ -281,15 +315,10 @@ sub findSpareDisks($) {
next
if ($part > 4);
# This is a partition on an earlier discovered disk device,
# ignore the disk device.
if (exists($retval{$dev}{"size"})) {
delete $retval{$dev}{"size"};
delete $retval{$dev}{"path"};
if (scalar(keys(%{$retval{$dev}})) == 0) {
delete $retval{$dev};
}
}
# If asked to, ignore SSDs
next
if ($skipssds && isSSD($dev));
if (!defined($mounts{"/dev/$devpart"})
&& !defined($ftents{"/dev/$devpart"})) {
......@@ -326,6 +355,10 @@ sub findSpareDisks($) {
}
else {
isdisk:
# If asked to, ignore SSDs
next
if ($skipssds && isSSD($devpart));
if (!defined($mounts{"/dev/$devpart"}) &&
!defined($ftents{"/dev/$devpart"}) &&
$size >= $minsize) {
......@@ -334,9 +367,9 @@ isdisk:
}
}
}
foreach my $k (keys(%retval)) {
if (scalar(keys(%{$retval{$k}})) == 0) {
delete $retval{$k};
foreach my $d (keys(%retval)) {
if (scalar(keys(%{$retval{$d}})) == 0) {
delete $retval{$d};
}
}
close(PFD);
......
......@@ -272,6 +272,9 @@ my $MAXROUTETTABLE = 255;
# Striping
my $STRIPE_COUNT = 1;
# Avoid using SSDs unless there are only SSDs
my $LVM_AVOIDSSD = 1;
# Whether or not to use only unpartitioned (unused) disks to form the Xen VG.
my $LVM_FULLDISKONLY = 0;
......@@ -527,21 +530,31 @@ sub rootPreConfig($)
}
#
# Make sure pieces are at least a 5GiB.
# Make sure pieces are at least 5 GiB.
#
my %devs = libvnode::findSpareDisks(5 * 1024);
my $minpsize = 5 * 1024;
my %devs = findSpareDisks($minpsize, $LVM_AVOIDSSD);
# if ignoring SSDs but came up with nothing, we have to use them!
if ($LVM_AVOIDSSD && keys(%devs) == 0) {
%devs = findSpareDisks($minpsize, 0);
}
#
# Turn on write caching. Hacky.
# XXX note we do not use the returned "path" here as we need to
# change the setting on all devices, not just the whole disk devices.
#
my %diddev = ();
foreach my $dev (keys(%devs)) {
# only mess with the disks we are going to use
if (exists($devs{$dev}{"size"}) || $LVM_FULLDISKONLY == 0) {
if (!exists($diddev{$dev}) &&
(exists($devs{$dev}{"size"}) || $LVM_FULLDISKONLY == 0)) {
mysystem2("hdparm -W1 /dev/$dev");
$diddev{$dev} = 1;
}
}
undef %diddev;
#
# See if our LVM volume group for VMs exists and create it if not.
......@@ -552,7 +565,8 @@ sub rootPreConfig($)
if ($debug);
#
# Total up potential maximum size
# Total up potential maximum size.
# Also determine mix of SSDs and non-SSDs if required.
#
my $maxtotalSize = 0;
my $sizeThreshold = 0;
......@@ -575,7 +589,7 @@ sub rootPreConfig($)
#
my $totalSize = 0;
my @blockdevs = ();
foreach my $dev (keys(%devs)) {
foreach my $dev (sort keys(%devs)) {
#
# Whole disk is available, use it.
#
......@@ -1739,6 +1753,29 @@ sub vnodePreConfig($$$$$){
">> $vnoderoot/boot/loader.conf");
}
}
#
# XXX avoid extra filesystem creation in libsetup if possible.
# This is specifically for the case of local home/proj directories.
# If we have to stick an extra FS mount in /etc/fstab, then we can
# no longer cleanly image the root partition.
#
# So we set it up to only use the extra space if it is explicitly
# specified by the user with XEN_EXTRAFS or XEN_EXTRADISKS.
# Otherwise we force use of '/'.
#
# We do this by mildly abusing the /var/emulab/boot/extrafs file,
# that was intended for coexistence between blockstores and mkextrafs.
# By putting FS=/ in there, we can force libsetup's os_mkextrafs to
# use the root filesystem.
#
if (!exists($vnconfig->{'attributes'}->{'XEN_EXTRAFS'}) &&
!exists($vnconfig->{'attributes'}->{'XEN_EXTRADISKS'})) {
mysystem("echo 'FS=/' > $vnoderoot/var/emulab/boot/extrafs");
} else {
unlink("$vnoderoot/var/emulab/boot/extrafs");
}
#
# We have to do what slicefix does when it localizes an image.
#
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment