Commit 11752432 authored by Leigh Stoller's avatar Leigh Stoller

Add physical memory accounting for openvz/xen nodes. The total

amount a physical has is stored in the node types table, and the
per-vm memory requirement is stored in the nodes table. ptopgen
adds up usage, and subtracts from the total for the ptop file.
The vtop number comes from a virt_node_attribute table, and we
pass this through to the client side. Note that this is less
important for openvz, more so for XEN.

In the NS file:

	tb-set-node-memory-size $node 1024

Number is in MBs. The mapper defaults this to 128 for openvz and 256
for xen. Maximum is hardwired to 256 and 512 respectively. Need to
think about a good way to configure this in.
parent cb9d504b
......@@ -1546,6 +1546,9 @@ sub rebootable($;$) {
sub bios_waittime($;$) {
return NodeTypeInfo($_[0])->bios_waittime($_[1]);
}
sub memory($;$) {
return NodeTypeInfo($_[0])->memory($_[1]);
}
#
# Perform some updates ...
......@@ -1621,7 +1624,7 @@ sub ClearBootAttributes($)
"update_accounts=0,ipport_next=ipport_low,rtabid=0, ".
"sfshostid=NULL,allocstate='$allocFreeState',boot_errno=0, ".
"destination_x=NULL,destination_y=NULL, ".
"destination_orientation=NULL ".
"destination_orientation=NULL,reserved_memory=0 ".
"where node_id='$node_id'")
or return -1;
......@@ -2092,6 +2095,14 @@ sub CreateVnodes($$$)
return -1;
}
# Need this below.
my $total_memory = $node->memory();
my $node_attributes = $node->GetNodeAttributes();
if (defined($node_attributes) &&
exists($node_attributes->{"physical_ram"})) {
$total_memory = $node_attributes->{"physical_ram"};
}
#
# Assign however many we are told to (typically by assign). Locally
# this is not a problem since nodes are not shared; assign always
......@@ -2176,6 +2187,44 @@ sub CreateVnodes($$$)
if ($opmode eq "ALWAYSUP");
my $allocstate = TBDB_ALLOCSTATE_FREE_CLEAN();
#
# Check memory constraints before we create anything.
#
my $reserved_memory = ();
if (defined($total_memory)) {
foreach my $ref (@tocreate) {
my ($n, $vname) = @{ $ref };
my $vm_memsize;
#
# Look to see if the container can actually get the memory it
# needs. This really only matters on a shared node. On a
# dedicated node, assign will never violate this, but on a
# shared node it could happen if two swapins are running
# at the same time. Like bandwidth.
#
$experiment->GetVirtNodeAttribute($vname,
"VM_MEMSIZE", \$vm_memsize)
== 0 or goto bad;
if ($vm_memsize) {
if ($verbose) {
print STDERR
"$vname is reserving $vm_memsize MB on $node\n";
}
if ($total_memory < $vm_memsize) {
print STDERR "*** CreateVnodes: ".
"no free memory for $vname on $pnode\n";
goto bad;
}
$total_memory -= $vm_memsize;
# remember for below.
$reserved_memory{$vname} = $vm_memsize;
}
}
}
#
# Create a bunch.
#
......@@ -2186,14 +2235,14 @@ sub CreateVnodes($$$)
my ( $jailip, $jailmask );
if ($isjailed) {
$query_result =
DBQueryWarn( "SELECT attrvalue FROM virt_node_attributes " .
"WHERE pid='$pid' AND eid='$eid' AND " .
"vname='$vname' AND " .
"attrkey='routable_control_ip'" );
if( $query_result && $query_result->numrows &&
( $query_result->fetchrow_array() )[ 0 ] eq "true" ) {
my $routable_control_ip;
$experiment->GetVirtNodeAttribute($vname, "routable_control_ip",
\$routable_control_ip)
== 0 or goto bad;
if ($routable_control_ip &&
$routable_control_ip eq "true") {
#
# Grab a public IP address from the free pool, if there
# is one.
......@@ -2274,12 +2323,10 @@ sub CreateVnodes($$$)
"def_boot_osid" => $osid,
"update_accounts" => 1,
"jailflag" => $isjailed);
# This is deprecated and will be removed. We now create real
# interfaces, see below.
if (0 && $isjailed && !$isremote) {
$nodesets{"jailip"} = $jailip;
$nodesets{"jailipmask"} = $JAILIPMASK;
}
if (exists($reserved_memory{$vname})) {
$nodesets{"reserved_memory"} = $reserved_memory{$vname};
}
my $statement = "insert into nodes set ".
join(",", map("$_='" . $nodesets{$_} . "'", keys(%nodesets)));
......
This diff is collapsed.
# -*- tcl -*-
#
# Copyright (c) 2000-2012 University of Utah and the Flux Group.
# Copyright (c) 2000-2013 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -67,6 +67,7 @@ proc tb-set-usewatunnels {onoff} {}
proc tb-set-wasolver-weights {delay bw plr} {}
proc tb-use-endnodeshaping {onoff} {}
proc tb-force-endnodeshaping {onoff} {}
proc tb-set-node-memory-size {node mem} {}
proc tb-set-multiplexed {link onoff} {}
proc tb-set-endnodeshaping {link onoff} {}
proc tb-set-noshaping {link onoff} {}
......
# -*- tcl -*-
#
# Copyright (c) 2000-2012 University of Utah and the Flux Group.
# Copyright (c) 2000-2013 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -2304,6 +2304,16 @@ proc tb-set-node-routable-ip {node onoff} {
}
}
# This number is MBs.
proc tb-set-node-memory-size {node mem} {
if {[$node info class] != "Node"} {
perror "\[tb-set-node-memory-size] $node is not a node."
return
}
$node add-attribute "MEMORY_SIZE" "$mem"
$node add-desire "?+ram" "$mem"
}
# The following codes are written, in order to use OML to send data to a server
# in an Emulab experiment. It will define a node to run OML server and create
# two files (MP.c and MP.h) for users. (mp represents measurement point in
......
......@@ -506,11 +506,22 @@ while (my ($class,$type,$isvirt) = $result->fetchrow_array) {
# look for the pxe_boot_path pointing to the tpm version of grub.
our %node_usb;
$result = DBQueryFatal("select node_id from node_attributes where attrkey='pxe_boot_path' and attrvalue='/tftpboot/pxeboot_tpm'");
$result = DBQueryFatal("select node_id from node_attributes ".
"where attrkey='pxe_boot_path' and ".
" attrvalue='/tftpboot/pxeboot_tpm'");
while (($node) = $result->fetchrow_array) {
$node_usb{$node} = 1;
}
# Physical RAM overrides.
my %node_ram;
$result = DBQueryFatal("select node_id,attrvalue from node_attributes ".
"where attrkey='physical_ram'");
while (my ($nodeid,$ram) = $result->fetchrow_array) {
$node_ram{$nodeid} = $ram;
}
# Read node_startloc
$result = DBQueryFatal("select node_id,building from node_startloc");
while (($node,$building) = $result->fetchrow_array) {
......@@ -768,6 +779,27 @@ while (my ($node_id,$count) = $result->fetchrow_array) {
$globalcounts{$node_id} = $count;
}
#
# Get the memory usage on each physical node.
# This will be subtracted from whatever the type/node info says.
# Note that we have to exclude nodes from this experiment
# that are already mapped to the node since the user already owns that memory.
#
my %node_ramusage;
if ($virtstuff) {
$result =
DBQueryFatal("select n.phys_nodeid,n.reserved_memory from nodes as n ".
"left join reserved as r on r.node_id=n.node_id ".
"where n.node_id!=n.phys_nodeid ".
(defined($experiment) ?
"and r.exptidx!=" . $experiment->idx() : ""));
while (my ($pnode,$memory) = $result->fetchrow_array()) {
$node_ramusage{$pnode} += $memory;
}
}
# Find available nodes.
#
# This first query deals with just local nodes. Local nodes can host
......@@ -990,6 +1022,15 @@ foreach $node (@nodenames) {
my ($latitude, $longitude, $country);
# per-node override RAM.
$ram = $node_ram{$node} if (exists($node_ram{$node}));
if (exists($node_ramusage{$node})) {
$ram -= $node_ramusage{$node};
# Should this be an error?
$ram = 0
if ($ram < 0);
}
# XXX temporary hack until node reboot avoidance
# is available. Nodes running the FBSD-NSE image
# will have a feature def-osid-fbsd-nse 0.0
......@@ -1159,9 +1200,10 @@ foreach $node (@nodenames) {
if ($trivspeed) {
push @flags, "trivial_bw:$trivspeed";
}
# Add CPU and RAM information
$cpu_ram_features_present++;
if (! $sharing_mode{$node}) {
# Add CPU and RAM information
$cpu_ram_features_present++;
# This number can be use for fine-tuning packing
push @features, "?+virtpercent:100";
}
......
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