Commit 40039320 authored by David Johnson's avatar David Johnson

Add dynamic, per-experiment blobs. Add tables for client side service blobs.

Per-experiment blobs can be created by the parser, and are inserted into
the blobs table at swapin based on what's in virt_blobs.  We go to some
effort to keep any existing filename<->uuid mapping in teh blobs table
so that any caching already done by the server and client in a previous
download of a blob remains intact.  We also remove blobs on experiment
modify that are no longer necessary.  Finally, we remove dynamic blobs
at swapout.
parent a12ed9ed
...@@ -138,7 +138,11 @@ $EXPT_RESOURCESHOSED = 0; ...@@ -138,7 +138,11 @@ $EXPT_RESOURCESHOSED = 0;
"firewall_rules", "firewall_rules",
"elabinelab_attributes", "elabinelab_attributes",
"virt_tiptunnels", "virt_tiptunnels",
"ipsubnets"); "ipsubnets",
"virt_blobs",
"virt_client_service_ctl",
"virt_client_service_hooks",
"virt_client_service_opts");
%physicalTables = ("delays" => ["node_id", "vname", "vnode0", "vnode1"], %physicalTables = ("delays" => ["node_id", "vname", "vnode0", "vnode1"],
"ipport_ranges" => undef, "ipport_ranges" => undef,
...@@ -3507,6 +3511,133 @@ sub SetupProgramAgents($) ...@@ -3507,6 +3511,133 @@ sub SetupProgramAgents($)
return 0; return 0;
} }
#
# Convert virt_blobs into real blobs. We go to some pain to keep the same
# filenames associated with the same uuid to make sure caching doesn't get
# needlessly broken on the client (on a modify).
#
sub UploadBlobs($$)
{
my ($self,$update) = @_;
# Must be a real reference.
return -1
if (! ref($self));
my $pid = $self->pid();
my $eid = $self->eid();
my $idx = $self->idx();
my $virtexp = $self->GetVirtExperiment();
return -1
if (!defined($virtexp));
my %blobs = ();
my %virt_blobs = ();
#
# Grab the existing blobs tied to our experiment
#
my $qres = DBQueryFatal("select uuid,filename,vblob_id" .
" from blobs where exptidx=$idx");
if (defined($qres) && $qres->numrows()) {
while (my ($uuid,$filename,$vblob_id) = $qres->fetchrow_array()) {
$blobs{$vblob_id} = [ 0,$uuid,$filename ];
}
}
#
# Now grab our experiment virt blobs
#
my $virt_blobs_table = $virtexp->Table("virt_blobs");
foreach my $row ($virt_blobs_table->Rows()) {
my $vblob_id = $row->vblob_id();
my $filename = $row->filename();
$virt_blobs{$vblob_id} = $filename;
}
#
# Make sure each virt_blob is in the blobs table!
#
foreach my $vblob_id (keys(%virt_blobs)) {
my $vfilename = $virt_blobs{$vblob_id};
if (exists($blobs{$vblob_id})
&& $blobs{$vblob_id}->[2] eq $vfilename) {
# this one is a keeper, so mark it!
$blobs{$vblob_id}->[0] = 1;
}
else {
my $found = 0;
foreach my $rvblob_id (keys(%blobs)) {
# if this one's a keeper, skip it!
next
if ($blobs{$rvblob_id}->[0]);
# if the filenames match, we adjust the vblob_id field
# in the blobs table to match what we have -- this leaves
# the uuid<->filename mapping intact
if ($blobs{$rvblob_id}->[2] eq $vfilename) {
my $uuid = $blobs{$rvblob_id}->[1];
$blobs{$vblob_id} = [ 1,$blobs{$rvblob_id}->[1],
$blobs{$rvblob_id}->[2] ];
DBQueryFatal("replace into blobs (uuid,vblob_id)" .
" values ('$uuid','$vblob_id')");
$found = 1;
last;
}
}
if (!$found) {
# need to add this blob fresh!
my $swapperuid = $experiment->swapper();
DBQueryFatal("insert into blobs" .
" (uuid,filename,owner_uid,vblob_id,exptidx)" .
" values (UUID(),'$vfilename','$swapperuid'," .
" '$vblob_id',$idx)");
}
}
}
#
# Only remove real blobs if we're done using them (i.e., on a modify)
#
if ($update) {
foreach my $vblob_id (keys(%blobs)) {
my ($keep,$uuid,$filename) = @{$blobs{$vblob_id}};
DBQueryFatal("delete from blobs" .
" where exptidx=$idx and vblob_id='${vblob_id}'");
}
}
return 0;
}
#
# Remove any real blobs that were a result of a virt blob (i.e., those
# blobs that have our exptidx and a valid vblob_id).
#
sub RemoveBlobs($$)
{
my ($self) = @_;
# Must be a real reference.
return -1
if (! ref($self));
my $idx = $self->idx();
my $qres = DBQueryFatal("delete from blobs" .
" left join virt_blobs as vblobs" .
" on blobs.vblob_id=vblobs.vblob_id" .
" where blobs.exptidx=$idx" .
" and vblobs.vblob_id is not NULL");
# XXX: probably should clean out blob_files stuff too!
return 0;
}
# #
# Seed the virt_agents table. Each lan/link needs an agent to handle # Seed the virt_agents table. Each lan/link needs an agent to handle
# changes to delays or other link parameters, and that agent (might be # changes to delays or other link parameters, and that agent (might be
......
...@@ -73,6 +73,11 @@ my $debug = 0; ...@@ -73,6 +73,11 @@ my $debug = 0;
"virt_parameters" => [ "name", "value" ], "virt_parameters" => [ "name", "value" ],
"virt_paths" => [ "pathname", "segmentname"], "virt_paths" => [ "pathname", "segmentname"],
"experiment_blobs" => [ "path", "action" ], "experiment_blobs" => [ "path", "action" ],
"virt_blobs" => [ "vblob_id", "filename" ],
"virt_client_service_ctl" => [ "vnode", "service_idx", "env", "whence" ],
"virt_client_service_hooks"=> [ "vnode", "service_idx", "env", "whence",
"hook_vblob_id" ],
"virt_client_service_opts" => [ "vnode", "opt_name", "opt_value" ],
); );
# #
...@@ -1198,6 +1203,27 @@ package VirtExperiment::VirtTableRow::experiment_blobs; ...@@ -1198,6 +1203,27 @@ package VirtExperiment::VirtTableRow::experiment_blobs;
use vars qw(@ISA); use vars qw(@ISA);
@ISA = "VirtExperiment::VirtTableRow"; @ISA = "VirtExperiment::VirtTableRow";
use VirtExperiment; use VirtExperiment;
use VirtExperiment;
package VirtExperiment::VirtTableRow::virt_blobs;
use vars qw(@ISA);
@ISA = "VirtExperiment::VirtTableRow";
use VirtExperiment;
package VirtExperiment::VirtTableRow::virt_client_service_ctl;
use vars qw(@ISA);
@ISA = "VirtExperiment::VirtTableRow";
use VirtExperiment;
package VirtExperiment::VirtTableRow::virt_client_service_hooks;
use vars qw(@ISA);
@ISA = "VirtExperiment::VirtTableRow";
use VirtExperiment;
package VirtExperiment::VirtTableRow::virt_client_service_opts;
use vars qw(@ISA);
@ISA = "VirtExperiment::VirtTableRow";
use VirtExperiment;
# _Always_ make sure that this 1 is at the end of the file... # _Always_ make sure that this 1 is at the end of the file...
1; 1;
...@@ -125,6 +125,18 @@ my %virtual_tables = ...@@ -125,6 +125,18 @@ my %virtual_tables =
"experiment_blobs" => { rows => undef, "experiment_blobs" => { rows => undef,
tag => "blobs", tag => "blobs",
row => "blob"}, row => "blob"},
"virt_blobs" => { rows => undef,
tag => "virt_blobs",
row => "virt_blob"},
"virt_client_service_ctl" => { rows => undef,
tag => "virt_client_service_ctl",
row => "virt_client_service_ctlrow"},
"virt_client_service_hooks"=> { rows => undef,
tag => "virt_client_service_hooks",
row => "virt_client_service_hook"},
"virt_client_service_opts" => { rows => undef,
tag => "virt_client_service_opts",
row => "virt_client_service_opt"},
# This is a fake table. See below. If we add more, lets generalize. # This is a fake table. See below. If we add more, lets generalize.
"external_sourcefiles" => { rows => undef, "external_sourcefiles" => { rows => undef,
tag => "nsfiles", tag => "nsfiles",
......
...@@ -575,6 +575,11 @@ sub doSwapout($) { ...@@ -575,6 +575,11 @@ sub doSwapout($) {
$experiment->DeleteInternalProgramAgents(); $experiment->DeleteInternalProgramAgents();
} }
if ($type >= RETRY) {
print "Removing dynamic blobs.\n";
$experiment->RemoveBlobs();
}
if ($type >= CLEANUP) { if ($type >= CLEANUP) {
# #
# Undo plab in elab specialness. # Undo plab in elab specialness.
...@@ -1101,6 +1106,18 @@ sub doSwapin($) { ...@@ -1101,6 +1106,18 @@ sub doSwapin($) {
} }
TBDebugTimeStamp("tarfiles_setup finished"); TBDebugTimeStamp("tarfiles_setup finished");
#
# Handle virt blobs.
#
if ($type >= RETRY) {
print "Creating virt blobs.\n";
$experiment->UploadBlobs(0);
}
elsif ($type == MODIFY) {
print "Updating virt blobs.\n";
$experiment->UploadBlobs(1);
}
# #
# If there are any Plab dslice nodes in the experiment, create the # If there are any Plab dslice nodes in the experiment, create the
# dslice now # dslice now
......
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