Commit 31009d09 authored by Mike Hibler's avatar Mike Hibler

Slight beefing up of support for alternate MBRs:

 * when creating an image from a node, make sure the new image
   gets the MBR version used by the existing image
 * when loading a single-partition image that requires a different
   MBR, invalidate all other existing partition ("invalidate" in the
   sense that we remove any partitions table entries, we don't do anything
   to the disk)
parent db959f35
......@@ -148,6 +148,7 @@ my %xmlfields =
"node_id" => ["node_id", $SLOT_OPTIONAL, ""],
"shared", => ["shared", $SLOT_OPTIONAL, 0],
"global", => ["global", $SLOT_ADMINONLY, 0],
"mbr_version", => ["mbr_version", $SLOT_OPTIONAL],
"makedefault", => ["makedefault", $SLOT_ADMINONLY, 0],
);
......@@ -479,6 +480,29 @@ if (exists($newimageid_args{"node_id"}) &&
}
}
#
# If no MBR version was specified, and a snapshot node was given,
# try to deduce the default MBR version based on what is currently
# on the node we are snapshotting.
#
if (!exists($newimageid_args{"mbr_version"}) && defined($node_id)) {
my $mbrvers = 1;
#
# If there is only one MBR version for all images on the disk,
# use that. Otherwise, if there is no or ambiguous info, default
# to version 1.
#
my $query_result =
DBQueryFatal("select mbr_version from partitions as p, images as i ".
" where p.imageid=i.imageid and p.node_id='$node_id' ".
" group by mbr_version");
if ($query_result && $query_result->numrows == 1) {
($mbrvers) = $query_result->fetchrow_array();
}
$newimageid_args{"mbr_version"} = $mbrvers;
}
#
# Mereusers are not allowed to create more than one osid/imageid mapping
# for each machinetype. They cannot actually do that through the EZ form
......
......@@ -150,6 +150,7 @@ my %xmlfields =
"max_concurrent", => ["max_concurrent", $SLOT_OPTIONAL, 0],
"shared", => ["shared", $SLOT_OPTIONAL, 0],
"global", => ["global", $SLOT_ADMINONLY, 0],
"mbr_version", => ["mbr_version", $SLOT_OPTIONAL],
"reboot_waittime", => ["reboot_waittime", $SLOT_ADMINONLY],
);
......@@ -435,6 +436,29 @@ if (exists($newimageid_args{"node_id"}) &&
}
}
#
# If no MBR version was specified, and a snapshot node was given,
# try to deduce the default MBR version based on what is currently
# on the node we are snapshotting.
#
if (!exists($newimageid_args{"mbr_version"}) && defined($node_id)) {
my $mbrvers = 1;
#
# If there is only one MBR version for all images on the disk,
# use that. Otherwise, if there is no or ambiguous info, default
# to version 1.
#
my $query_result =
DBQueryFatal("select mbr_version from partitions as p, images as i ".
" where p.imageid=i.imageid and p.node_id='$node_id' ".
" group by mbr_version");
if ($query_result && $query_result->numrows == 1) {
($mbrvers) = $query_result->fetchrow_array();
}
$newimageid_args{"mbr_version"} = $mbrvers;
}
#
# See what node types this image will work on. Must be at least one!
#
......
......@@ -191,7 +191,7 @@ sub Create($$$$$$$$)
push(@arg_slots, $key);
}
# Pass-through optional slots, otherwise the DB default is used.
foreach my $key ("path", "shared", "global", "ezid") {
foreach my $key ("path", "shared", "global", "ezid", "mbr_version") {
if (exists($argref->{$key})) {
push(@arg_slots, $key);
}
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2007 University of Utah and the Flux Group.
# Copyright (c) 2000-2008 University of Utah and the Flux Group.
# All rights reserved.
#
# Osload library. Basically the backend to the osload script, but also used
......@@ -282,18 +282,68 @@ sub osload ($$) {
}
#
# Assign partition table entries for each partition in the image.
# XXX assumes a DOS MBR, but this is ingrained in the DB schema
# as well (i.e., the images.part[1234]_osid fields).
#
my $MINPART = 1;
my $MAXPART = 4;
#
# Assign partition table entries for each partition in the image
# that has an OSID associated with it.
#
# This is complicated by the fact that an image that covers only
# part of the slices, should only change the partition table entries
# for the subset of slices that are written to disk.
# part of the slices should only change the partition table entries
# for the subset of slices that are written to disk...
#
my $startpart = $loadpart == 0 ? 1 : $loadpart;
# ...UNLESS, the new image requires a different version of the MBR
# in which case we must invalidate all partitions except the ones we
# are loading since the partition boundaries may have changed.
#
my $startpart = $loadpart == 0 ? $MINPART : $loadpart;
my $endpart = $startpart + $loadlen;
for (my $i = $startpart; $i < $endpart; $i++) {
for (my $i = $MINPART; $i <= $MAXPART; $i++) {
my $partname = "part${i}_osid";
my $dbresult;
#
# Partition is outside the range affected by this image.
# Normally, we just leave it alone, unless a change of MBR
# is implied by the current image.
#
if ($i < $startpart || $i >= $endpart) {
if (defined($rowref->{'mbr_version'})) {
$dbresult =
DBQueryWarn("select mbr_version ".
" from partitions as p,images as i ".
" where p.imageid=i.imageid ".
" and node_id='$node' and partition='$i'");
if ($dbresult && $dbresult->numrows) {
my ($pmbr) = $dbresult->fetchrow_array();
if ($pmbr != $rowref->{'mbr_version'}) {
tbwarn("$node: Existing partition $i inconsistent".
" with new image partitioning,".
" invalidating existing partition");
$dbresult =
DBQueryWarn("delete from partitions ".
"where node_id='$node' and ".
"partition='$i'");
if (!$dbresult) {
tberror("$node: Could not update ".
"partition table");
goto failednode;
}
}
}
}
next;
}
#
# This image has an OSID in the current partition,
# replace the partition table info.
#
if (defined($rowref->{$partname})) {
my $osid = $rowref->{$partname};
......@@ -303,6 +353,10 @@ sub osload ($$) {
"values ".
"('$node','$i','$osid','$imageid','$imagepid')");
}
#
# Otherwise, if there is no OS for a particular image partition,
# clear any current partitions table info.
#
else {
$dbresult =
DBQueryWarn("delete from partitions ".
......
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