Commit 7942119e authored by Leigh Stoller's avatar Leigh Stoller

Added my simplistic link tracing and monitoring. Example usage and

some details can be found in the advanced tutorial that I wrote up.
See this link:

http://www.emulab.net/tutorial/docwrapper.php3?docname=advanced.html#Tracing

The basic idea is that each virt_lan entry gets a couple of new slots
describing the type of tracing that is desired.

  traced tinyint(1) default '0',
  trace_type enum('header','packet','monitor') NOT NULL default 'header',
  trace_expr tinytext,
  trace_snaplen int(11) NOT NULL default '0',
  trace_endnode tinyint(1) NOT NULL default '0',

There is a new physical table called "traces" that is a little bit
like the current delays table. A new tmcd command returns the trace
configuration to the client nodes (tmcd/common/config/rc.trace).

The delays table got a new boolean called "noshaping" that tells the
delay node to bridge, but not set up any pipes. This allows us to
capture traffic at the delay node, but without much less overhead on
the packets.

The pcapper got bloated up to do packet capture and more event stuff.
I also had to add some mutex locking around calls into the pcap
library and around malloc, since the current setup used linuxthreads,
which is not compatable with the standard libc_r library. I was
getting all kinds of memory corruption, and I am sure that if someone
breathes on the pcapper again, it will break in some new way.
parent 73303982
......@@ -3236,6 +3236,7 @@ sub TBRobotLabExpt($$)
"ipport_ranges",
"v2pmap",
"linkdelays",
"traces",
"portmap");
#
......
......@@ -145,6 +145,7 @@ CREATE TABLE delays (
vnode1 varchar(32) default NULL,
card0 tinyint(3) unsigned default NULL,
card1 tinyint(3) unsigned default NULL,
noshaping tinyint(1) default '0',
PRIMARY KEY (node_id,iface0,iface1),
KEY pid (pid,eid)
) TYPE=MyISAM;
......@@ -1709,6 +1710,26 @@ CREATE TABLE tmcd_redirect (
PRIMARY KEY (node_id)
) TYPE=MyISAM;
--
-- Table structure for table `traces`
--
CREATE TABLE traces (
node_id varchar(32) NOT NULL default '',
idx int(10) unsigned NOT NULL auto_increment,
iface0 varchar(8) NOT NULL default '',
iface1 varchar(8) NOT NULL default '',
pid varchar(32) default NULL,
eid varchar(32) default NULL,
linkvname varchar(32) default NULL,
vnode varchar(32) default NULL,
trace_type tinytext,
trace_expr tinytext,
trace_snaplen int(11) NOT NULL default '0',
PRIMARY KEY (node_id,idx),
KEY pid (pid,eid)
) TYPE=MyISAM;
--
-- Table structure for table `tunnels`
--
......@@ -2052,6 +2073,11 @@ CREATE TABLE virt_lans (
trivial_ok tinyint(4) default '1',
protocol varchar(30) NOT NULL default 'ethernet',
is_accesspoint tinyint(4) default '0',
traced tinyint(1) default '0',
trace_type enum('header','packet','monitor') NOT NULL default 'header',
trace_expr tinytext,
trace_snaplen int(11) NOT NULL default '0',
trace_endnode tinyint(1) NOT NULL default '0',
KEY pid (pid,eid,vname),
KEY vnode (pid,eid,vnode)
) TYPE=MyISAM;
......
......@@ -571,6 +571,11 @@ REPLACE INTO table_regex VALUES ('virt_lans','uselinkdelay','int','redirect','de
REPLACE INTO table_regex VALUES ('virt_lans','nobwshaping','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','usevethiface','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','trivial_ok','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','traced','int','redirect','default:boolean',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','trace_type','text','regex','^(header|packet|monitor)$',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','trace_expr','text','redirect','default:text',1,255,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','trace_snaplen','int','redirect','default:int',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_lans','trace_endnode','int','redirect','default:tinyint',0,1,NULL);
REPLACE INTO table_regex VALUES ('virt_node_desires','pid','text','redirect','projects:pid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_node_desires','eid','text','redirect','experiments:eid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_node_desires','vname','text','redirect','virt_nodes:vname',0,0,NULL);
......
......@@ -2667,3 +2667,39 @@ last_net_act,last_cpu_act,last_ext_act);
distance_remaining float default NULL,
PRIMARY KEY (node_id)
) TYPE=MyISAM;
1.339: Add stuff for tracing links and lans.
alter table virt_lans add traced tinyint(1) default '0' \
after is_accesspoint;
alter table virt_lans add trace_type \
enum('header','packet','monitor') NOT NULL default 'header' \
after traced;
alter table virt_lans add trace_expr tinytext \
after trace_type;
alter table virt_lans add trace_snaplen \
int(11) NOT NULL default '0' \
after trace_expr;
alter table virt_lans add trace_endnode \
tinyint(1) NOT NULL default '0' \
after trace_snaplen;
alter table delays add noshaping tinyint(1) default '0' \
after card1;
CREATE TABLE traces (
node_id varchar(32) NOT NULL default '',
idx int(10) unsigned NOT NULL auto_increment,
iface0 varchar(8) NOT NULL default '',
iface1 varchar(8) NOT NULL default '',
pid varchar(32) default NULL,
eid varchar(32) default NULL,
linkvname varchar(32) default NULL,
vnode varchar(32) default NULL,
trace_type tinytext,
trace_expr tinytext,
trace_snaplen int(11) NOT NULL default '0',
PRIMARY KEY (node_id,idx),
KEY pid (pid,eid)
) TYPE=MyISAM;
......@@ -10,11 +10,8 @@
INSERT INTO sitevariables VALUES ('general/testvar',NULL,'43','A test variable');
INSERT INTO sitevariables VALUES ('general/firstinit/state',NULL,'Ready','Indicates that a new emulab is not setup yet. Moves through several states.');
INSERT INTO sitevariables VALUES ('general/firstinit/pid',NULL,'testbed','The Project Name of the first project.');
INSERT INTO sitevariables VALUES ('web/nologins',NULL,'0','Non-zero value indicates that no user may log into the Web Interface; non-admin users are auto logged out.');
INSERT INTO sitevariables VALUES ('web/message',NULL,'','Message to place in large lettering under the login message on the Web Interface.');
INSERT INTO sitevariables VALUES ('web/banner',NULL,'','Message to place in large lettering at top of home page (typically a special message)');
INSERT INTO sitevariables VALUES ('idle/threshold',NULL,'4','Number of hours of inactivity for a node/expt to be considered idle.');
INSERT INTO sitevariables VALUES ('idle/mailinterval',NULL,'4','Number of hours since sending a swap request before sending another one. (Timing of first one is determined by idle/threshold.)');
INSERT INTO sitevariables VALUES ('idle/cc_grp_ldrs',NULL,'3','Start CC\'ing group and project leaders on idle messages on the Nth message.');
......@@ -25,9 +22,9 @@ INSERT INTO sitevariables VALUES ('plab/stale_age',NULL,'60','Age in minutes at
INSERT INTO sitevariables VALUES ('idle/batch_threshold',NULL,'30','Number of minutes of inactivity for a batch node/expt to be considered idle.');
INSERT INTO sitevariables VALUES ('general/recently_active',NULL,'14','Number of days to be considered a recently active user of the testbed.');
INSERT INTO sitevariables VALUES ('plab/load_metric',NULL,'load_fifteen','GMOND load metric to use (load_one, load_five, load_fifteen)');
INSERT INTO sitevariables VALUES ('plab/max_load',NULL,'5.0','Load at which to stop admitting jobs (0==admit nothing, 1000==admit all)');
INSERT INTO sitevariables VALUES ('plab/max_load','10','5.0','Load at which to stop admitting jobs (0==admit nothing, 1000==admit all)');
INSERT INTO sitevariables VALUES ('plab/min_disk',NULL,'10.0','Minimum disk space free at which to stop admitting jobs (0==admit all, 100==admit none)');
INSERT INTO sitevariables VALUES ('watchdog/interval',NULL,'60','Interval in minutes between checks for changes in timeout values (0==never check)');
INSERT INTO sitevariables VALUES ('watchdog/interval','30','60','Interval in minutes between checks for changes in timeout values (0==never check)');
INSERT INTO sitevariables VALUES ('watchdog/ntpdrift',NULL,'240','Interval in minutes between reporting back NTP drift changes (0==never report)');
INSERT INTO sitevariables VALUES ('watchdog/cvsup',NULL,'720','Interval in minutes between remote node checks for software updates (0==never check)');
INSERT INTO sitevariables VALUES ('watchdog/isalive/local',NULL,'3','Interval in minutes between local node status reports (0==never report)');
......@@ -37,26 +34,30 @@ INSERT INTO sitevariables VALUES ('watchdog/isalive/wa',NULL,'1','Interval in mi
INSERT INTO sitevariables VALUES ('watchdog/isalive/dead_time',NULL,'120','Time, in minutes, after which to consider a node dead if it has not checked in via tha watchdog');
INSERT INTO sitevariables VALUES ('plab/setup/vnode_batch_size',NULL,'40','Number of plab nodes to setup simultaneously');
INSERT INTO sitevariables VALUES ('plab/setup/vnode_wait_time',NULL,'960','Number of seconds to wait for a plab node to setup');
INSERT INTO sitevariables VALUES ('watchdog/rusage',NULL,'1','Interval in minutes between node resource usage reports (0==never report)');
INSERT INTO sitevariables VALUES ('watchdog/rusage','5','1','Interval in minutes between node resource usage reports (0==never report)');
INSERT INTO sitevariables VALUES ('watchdog/hostkeys',NULL,'999999','Interval in minutes between host key reports (0=never report, 999999=once only)');
INSERT INTO sitevariables VALUES ('plab/message',NULL,'','Message to display at the top of the plab_ez page');
INSERT INTO sitevariables VALUES ('node/ssh_pubkey',NULL,'','Boss SSH public key to install on nodes');
INSERT INTO sitevariables VALUES ('plab/message','Planetlab support is currently broken due to API incompatibilities introduced into PLC.','','Message to display at the top of the plab_ez page');
INSERT INTO sitevariables VALUES ('node/ssh_pubkey','1024 37 168728947415883137658395816497236019932357443574364998989351516015013006429180411438552594116282442938932702706360430451154958992295988097967662214818020771421328881173382895214540694120581207714991274873698590147743427181599852480329442016838781882554809552882295931111276319070960396053057987057937216750401 root@paper.cs.utah.edu','','Boss SSH public key to install on nodes');
INSERT INTO sitevariables VALUES ('web/banner',NULL,'','Message to place in large lettering at top of home page (typically a special message)');
INSERT INTO sitevariables VALUES ('general/autoswap_threshold',NULL,'16','Number of hours before an experiment is forcibly swapped');
INSERT INTO sitevariables VALUES ('general/autoswap_mode',NULL,'0','Control whether autoswap defaults to on or off in the Begin Experiment page');
INSERT INTO sitevariables VALUES ('webcam/anyone_can_view',NULL,'0','Turn webcam viewing on/off for mere users; default is off');
INSERT INTO sitevariables VALUES ('general/autoswap_mode','1','0','Control whether autoswap defaults to on or off in the Begin Experiment page');
INSERT INTO sitevariables VALUES ('webcam/anyone_can_view','1','0','Turn webcam viewing on/off for mere users; default is off');
INSERT INTO sitevariables VALUES ('webcam/admins_can_view',NULL,'1','Turn webcam viewing on/off for admin users; default is on');
INSERT INTO sitevariables VALUES ('swap/use_admission_control',NULL,'1','Use admission control when swapping in experiments');
INSERT INTO sitevariables VALUES ('swap/admission_control_debug',NULL,'0','Turn on/off admission control debugging (lots of output!)');
INSERT INTO sitevariables VALUES ('robotlab/override',NULL,'','Turn the Robot Lab on/off (open/close). This is an override over other settings');
INSERT INTO sitevariables VALUES ('robotlab/override','','','Turn the Robot Lab on/off (open/close). This is an override over other settings');
INSERT INTO sitevariables VALUES ('robotlab/exclusive',NULL,'1','Only one experiment at a time; do not turn this off!');
INSERT INTO sitevariables VALUES ('robotlab/opentime',NULL,'07:00','Time the Robot lab opens for use.');
INSERT INTO sitevariables VALUES ('robotlab/opentime','08:00','07:00','Time the Robot lab opens for use.');
INSERT INTO sitevariables VALUES ('robotlab/closetime',NULL,'18:00','Time the Robot lab closes down for the night.');
INSERT INTO sitevariables VALUES ('robotlab/open',NULL,'0','Turn the Robot Lab on/off for weekends and holidays. Overrides the open/close times.');
INSERT INTO sitevariables VALUES ('elabinelab/boss_pkg',NULL,'','Name of boss node install package');
INSERT INTO sitevariables VALUES ('elabinelab/boss_pkg_dir',NULL,'','Path from which to fetch boss packages');
INSERT INTO sitevariables VALUES ('elabinelab/ops_pkg',NULL,'','Name of ops node install package');
INSERT INTO sitevariables VALUES ('elabinelab/ops_pkg_dir',NULL,'','Path from which to fetch ops packages');
INSERT INTO sitevariables VALUES ('elabinelab/windows',NULL,'0','Turn on Windows support in inner Emulab');
INSERT INTO sitevariables VALUES ('general/version/major',NULL,'','Source code major revision number');
INSERT INTO sitevariables VALUES ('general/version/minor',NULL,'','Source code minor revision number');
INSERT INTO sitevariables VALUES ('general/version/build',NULL,'','Build version number');
INSERT INTO sitevariables VALUES ('robotlab/open','1','0','Turn the Robot Lab on/off for weekends and holidays. Overrides the open/close times.');
INSERT INTO sitevariables VALUES ('swap/admission_control_debug',NULL,'0','Turn on/off admission control debugging (lots of output!)');
INSERT INTO sitevariables VALUES ('elabinelab/boss_pkg','emulab-boss-1.8','','Name of boss node install package');
INSERT INTO sitevariables VALUES ('elabinelab/boss_pkg_dir','/share/freebsd/packages/FreeBSD-4.10-20041102','','Path from which to fetch boss packages');
INSERT INTO sitevariables VALUES ('elabinelab/ops_pkg','emulab-ops-1.4','','Name of ops node install package');
INSERT INTO sitevariables VALUES ('elabinelab/ops_pkg_dir','/share/freebsd/packages/FreeBSD-4.10-20041102','','Path from which to fetch ops packages');
INSERT INTO sitevariables VALUES ('elabinelab/windows','1','0','Turn on Windows support in inner Emulab');
INSERT INTO sitevariables VALUES ('general/firstinit/state',NULL,'Ready','Indicates that a new emulab is not setup yet. Moves through several states.');
INSERT INTO sitevariables VALUES ('general/firstinit/pid',NULL,'testbed','The Project Name of the first project.');
INSERT INTO sitevariables VALUES ('general/version/minor','456','','Source code minor revision number');
INSERT INTO sitevariables VALUES ('general/version/build','06/17/2005','','Build version number');
INSERT INTO sitevariables VALUES ('general/version/major','1','','Source code major revision number');
......@@ -42,6 +42,7 @@ sub physnodenextrtabid($);
sub getrtabid($$);
sub array_diff($$);
sub LoadCurrent();
sub SetUpTracing($$$$$);
#
# This function as the main assign loop. It converts the virtual
......@@ -326,6 +327,9 @@ sub virtlanuseveth($) { return $virt_lans{$_[0]}->{"USEVETH"}; }
sub virtlantunnel($) { return $virt_lans{$_[0]}->{"TUNNEL"}; }
sub virtlandelayinfo($$){ return @{$virt_lans{$_[0]}->{"DELAYINFO"}->{$_[1]}};}
sub virtlanqueueinfo($$){ return @{$virt_lans{$_[0]}->{"QUEUEINFO"}->{$_[1]}};}
sub virtlantraceinfo($$){ return @{$virt_lans{$_[0]}->{"TRACEINFO"}->{$_[1]}};}
sub virtlanshaped($$) { return $virt_lans{$_[0]}->{"SHAPED"}->{$_[1]};}
sub virtlansetshaped($$){ $virt_lans{$_[0]}->{"SHAPED"}->{$_[1]} = 1; }
sub virtlannetmask($) { return $virt_lans{$_[0]}->{"MASK"}; }
sub virtlanwidearea($) { return $virt_lans{$_[0]}->{"WIDEAREA"}; }
sub virtlanallsim($) { return $virt_lans{$_[0]}->{"ALLSIM"}; }
......@@ -1649,6 +1653,12 @@ foreach $plink (keys(%plinks)) {
printdb " Portmap:\n";
printdb " $virtA = $portA\n";
printdb " $virtC = $portC\n";
#
# Set up tracing across the delay node (both directions).
#
SetUpTracing($lan, $member0, $nodeB, $portB, $portD);
SetUpTracing($lan, $member1, $nodeB, $portD, $portB);
}
elsif (($lan,$virtA) = ($plink =~ m|^linkdelaysrc/([^/]+)/(.+)$|)) {
# trivial links do not have physical links, so no delay nodes.
......@@ -1691,6 +1701,11 @@ foreach $plink (keys(%plinks)) {
$portmap{$virtA} = $portA;
printdb " Portmap:\n";
printdb " $virtA = $portA\n";
#
# Set up tracing across the delay node (one direction cause its a lan).
#
SetUpTracing($lan, $member0, $nodeB, $portB, $portD);
}
elsif (($lan,$virtA,$virtB) = ($plink =~ m|^linksimple/(.+)/(.+),(.+)$|)) {
#
......@@ -1718,8 +1733,8 @@ foreach $plink (keys(%plinks)) {
# If the trivial link has all simulated members, we
# don't want a veth interface
if (! virtlanallsim($lan) ) {
# No phys mapping. We create a veth, but there is no phys mapping
# for the port.
# No phys mapping. We create a veth, but there is no
# phys mapping for the port.
$nodeA = $v2pmap{(split(":", $virtA))[0]};
$nodeB = $v2pmap{(split(":", $virtB))[0]};
$portA = NewVethIface($lan, $virtA, $nodeA);
......@@ -1760,6 +1775,12 @@ foreach $plink (keys(%plinks)) {
"$rbandwidth,$rloss,$trivonly\]\n";
}
}
#
# Set up tracing across the link. There is trace on each end node,
# on the output (after the linkdelay above).
#
SetUpTracing($lan, $virtA, $nodeA, undef, $portA);
SetUpTracing($lan, $virtB, $nodeB, undef, $portB);
}
elsif (($lan,$virtA) = ($plink =~ m|^linklan/([^/]+)/(.+)$|)) {
# node may be in the LAN multiple times.
......@@ -1827,6 +1848,10 @@ foreach $plink (keys(%plinks)) {
"$rbandwidth,$rloss,$trivonly\]\n";
}
}
#
# Set up tracing on the end node (one direction cause its a lan).
#
SetUpTracing($lan, $virtA, $nodeA, undef, $portA);
}
elsif (($lan,$virtA) = ($plink =~ m|^fakelan/([^/]+)/(.+)$|)) {
# node is attached to a fake switch (LAN).
......@@ -1841,6 +1866,11 @@ foreach $plink (keys(%plinks)) {
$portmap{$virtA} = $portA;
printdb " Portmap:\n";
printdb " $virtA = $portA\n";
#
# Set up tracing on the end node (one direction cause its a lan).
#
SetUpTracing($lan, $virtA, $nodeA, undef, $portA);
}
elsif ($plink =~ m|^linkdelaydst/([^/]+)/(.+)$| ||
$plink =~ m|^linksdelaydst/(.+)/(.+),(.+)$|) {
......@@ -1892,6 +1922,12 @@ foreach my $lan (keys(%virt_lans)) {
" idx from event_objecttypes where ".
" event_objecttypes.type='LINK'");
DBQueryFatal("replace into virt_agents ".
" (pid, eid, vname, vnode, objecttype) ".
" select '$pid', '$eid', '$lan-tracemon', '*', ".
" idx from event_objecttypes where ".
" event_objecttypes.type='LINKTRACE'");
foreach my $member (virtlanmembers($lan)) {
my ($vnode) = split(":", $member);
......@@ -1900,6 +1936,13 @@ foreach my $lan (keys(%virt_lans)) {
" select '$pid', '$eid', '${lan}-${vnode}', '*', ".
" idx from event_objecttypes where ".
" event_objecttypes.type='LINK'");
DBQueryFatal("replace into virt_agents ".
" (pid, eid, vname, vnode, objecttype) ".
" select '$pid', '$eid', '${lan}-${vnode}-tracemon', ".
" '*', ".
" idx from event_objecttypes where ".
" event_objecttypes.type='LINKTRACE'");
}
}
......@@ -1935,9 +1978,15 @@ foreach $delayid (keys(%nodedelays)) {
$q1_qinbytes,$q1_bytes,$q1_meanpsize,$q1_wait,$q1_setbit,
$q1_droptail,$q1_red,$q1_gentle) =
virtlanqueueinfo($vname, $member1);
#
# See if this delaynode was inserted strictly for tracing/monitoring.
#
my $noshaping = ((virtlanshaped($vname, $member0) ||
virtlanshaped($vname, $member1)) ? 0 : 1);
DBQueryFatal("insert into delays " .
" (pid,eid,node_id,vname,iface0,iface1" .
" (pid,eid,node_id,vname,noshaping,iface0,iface1" .
",vnode0,pipe0,delay0,bandwidth0,lossrate0" .
",vnode1,pipe1,delay1,bandwidth1,lossrate1" .
",q0_limit,q0_maxthresh,q0_minthresh,q0_weight,q0_linterm" .
......@@ -1946,7 +1995,8 @@ foreach $delayid (keys(%nodedelays)) {
",q1_limit,q1_maxthresh,q1_minthresh,q1_weight,q1_linterm" .
",q1_qinbytes,q1_bytes,q1_meanpsize,q1_wait,q1_setbit" .
",q1_droptail,q1_red,q1_gentle)" .
" values ('$pid','$eid','$pnode','$vname','$int0','$int1'".
" values ('$pid','$eid','$pnode','$vname',$noshaping ".
",'$int0','$int1'".
",'$vnode0',$pipe0,$delay,$bandwidth,$lossrate".
",'$vnode1',$pipe1,$rdelay,$rbandwidth,$rlossrate".
",$q0_limit,$q0_maxthresh,$q0_minthresh,$q0_weight,$q0_linterm".
......@@ -1962,6 +2012,11 @@ foreach $delayid (keys(%nodedelays)) {
$q0_droptail,$q0_red,$q0_gentle) =
virtlanqueueinfo($vname, $member0);
#
# See if this delaynode was inserted strictly for tracing/monitoring.
#
my $noshaping = (virtlanshaped($vname, $member0) ? 0 : 1);
#
# Obviously, its implied that the q0 params are towards the lan,
# For the reverse side, force the queue to 2 slots (should be 1
......@@ -1970,13 +2025,14 @@ foreach $delayid (keys(%nodedelays)) {
# when it gets to the node.
#
DBQueryFatal("insert into delays" .
" (pid,eid,node_id,vname,iface0,iface1," .
" (pid,eid,node_id,vname,noshaping,iface0,iface1," .
" vnode0,pipe0,delay0,bandwidth0,lossrate0," .
" vnode1,pipe1,delay1,bandwidth1,lossrate1," .
" q0_limit,q0_maxthresh,q0_minthresh,q0_weight,q0_linterm," .
" q0_qinbytes,q0_bytes,q0_meanpsize,q0_wait,q0_setbit," .
" q0_droptail,q0_red,q0_gentle,q1_limit,q1_qinbytes) " .
" values ('$pid','$eid','$pnode','$vname','$int0','$int1',".
" values ('$pid','$eid','$pnode','$vname',$noshaping, ".
" '$int0','$int1',".
" '$vnode0',$pipe0,$delay,$bandwidth,$lossrate,".
" '$vnode1',$pipe1,$rdelay,$rbandwidth,$rlossrate,".
" $q0_limit,$q0_maxthresh,$q0_minthresh,$q0_weight,$q0_linterm,".
......@@ -3038,6 +3094,45 @@ sub NewVethIface($$$;$)
return $newveth;
}
#
# Setup tracing on a link.
#
sub SetUpTracing($$$$$)
{
my ($lan, $member, $pnode, $iface0, $iface1) = @_;
my ($vnode) = split(":", $member);
if (virtnodeisjailed($vnode)) {
$pnode = "$v2vmap{$vnode}";
}
#
# First see if this member of the lan wanted tracing.
#
my ($traced, $endnode, $trace_type, $trace_expr, $trace_snaplen) =
virtlantraceinfo($lan, $member);
return
if (!$traced);
# This means its on an end node.
$iface0 = ""
if (!defined($iface0));
if ($impotent) {
printdb "Trace: $lan, $member, $endnode, $pnode, $iface0, $iface1\n";
return;
}
DBQueryFatal("insert into traces ".
" (node_id, idx, iface0, iface1, pid, eid, linkvname, ".
" vnode, trace_type, trace_expr, trace_snaplen) ".
"values ".
" ('$pnode', 0, '$iface0', '$iface1', '$pid', '$eid', ".
" '$lan', '$vnode', ".
" '$trace_type', '$trace_expr', $trace_snaplen)");
}
#
# XXX Temporary until we figure out a solution.
#
......@@ -3712,7 +3807,27 @@ sub LoadVirtLans()
$rowref->{"q_setbit"},
$rowref->{"q_droptail"},
$rowref->{"q_red"},
$rowref->{"q_gentle"} ];
$rowref->{"q_gentle"},
];
#
# The trace info is stored along with the QUEUEINFO, but its
# easier if I split it out.
#
$virt_lans{$vname}->{"TRACEINFO"}->{$member} =
[ $rowref->{"traced"},
$rowref->{"trace_endnode"},
$rowref->{"trace_type"},
$rowref->{"trace_expr"},
$rowref->{"trace_snaplen"},
];
#
# This will get set on a per-member basis when it is determined
# that the link is getting a delaynode cause its really being
# shaped, or because it is being traced or monitored.
#
$virt_lans{$vname}->{"SHAPED"}->{$member} = 0;
#
# XXX - Whenever a delay node is inserted, port speeds are set to
......@@ -4161,6 +4276,11 @@ sub CreateTopFile()
$bandwidth = &getbandwidth($node0,$lan,$bw);
$rbandwidth = &getbandwidth($node1,$lan,$rbw);
# Need to know about tracing on a per queue basis, since the
# user can specify tracing asymmetrically.
my ($traced,$trace_endnode) = virtlantraceinfo($lan, $nodeport0);
my ($rtraced,$rtrace_endnode) = virtlantraceinfo($lan, $nodeport1);
#
# Get the bandwidth we're supposed to put into the top file, which
# may be different that what we're limiting the link to
......@@ -4171,6 +4291,12 @@ sub CreateTopFile()
$top_bw = &min($top_bw0,$top_rbw1);
$top_rbw = &min($top_rbw0, $top_bw1);
#
# See if the link is really being shaped, or if the we just
# need a delay node cause of tracing/monitoring.
#
my $shaped = 0;
if (((($delay >= $delaythresh) ||
(!$nobwshaping && (requires_delay($node0, $lan, $bw) ||
requires_delay($node1, $lan, $bw))) ||
......@@ -4182,22 +4308,32 @@ sub CreateTopFile()
# Link must be shaped for other reasons (q_red).
$mustdelay ||
# Global force, or per-link force.
$forcelinkdelays || $uselinkdelay) &&
$forcelinkdelays || $uselinkdelay)) {
# Need a delay node and its really a shaped link.
$shaped = 1;
# Mark the links as shaped for later.
virtlansetshaped($lan, $nodeport0);
virtlansetshaped($lan, $nodeport1);
}
if (($shaped ||
(($traced || $rtraced) &&
!($trace_endnode && $rtrace_endnode))) &&
# XXX simulated nodes hack. We don't want to put delay nodes
# between simulated nodes. If there is a link between a
# simulated and a real node, we might need to put in delay
# nodes
# nodes.
($realnodes != 0)) {
$expt_stats{"shapedlinks"} += 1;
#
# We use a linkdelay if the link is emulated, globally forced,
# globally preferred if the link is shaped, or if the per-link
# flag was set (which means to put in a link delay regardless
# of whether the link is shaped).
#
if ($emulated ||
$forcelinkdelays || $uselinkdelays || $uselinkdelay) {
if ($emulated || $forcelinkdelays ||
($uselinkdelays && $shaped) || $uselinkdelay) {
my $plink = "linksimple/$lan/$nodeport0,$nodeport1";
print(TOPFILE "link $plink $node0 $node1 ".
......@@ -4296,6 +4432,15 @@ sub CreateTopFile()
$bandwidth = &getbandwidth($node,$lan,$bw);
$rbandwidth = &getbandwidth($node,$lan,$rbw);
# Need to know about tracing on a per queue basis, since the
# user can specify tracing asymmetrically.
my ($traced,$trace_endnode) = virtlantraceinfo($lan, $member);
#
# See if the link is really being shaped, or if the we just
# need a delay node cause of tracing/monitoring.
#
my $shaped = 0;
# XXX The expression below should be modified for
# better bandwidth support. Probably needs to happen
......@@ -4309,7 +4454,12 @@ sub CreateTopFile()
# Link must be shaped for other reasons (q_red).
$mustdelay ||
# Global force, or per-lan force.
$forcelinkdelays || $uselinkdelay) &&
$forcelinkdelays || $uselinkdelay)) {
$shaped = 1;
virtlansetshaped($lan, $member);
}
if (($shaped || ($traced && !$trace_endnode)) &&
# if we have 1 real node in the LAN, we may need to create
# a lan
($realnodes != 0)) {
......@@ -4321,16 +4471,16 @@ sub CreateTopFile()
# (which means to put in a link delay regardless
# of whether the link is shaped).
#
if ($emulated ||
$forcelinkdelays || $uselinkdelays || $uselinkdelay) {
if ($emulated || $forcelinkdelays ||
($uselinkdelays && $shaped) || $uselinkdelay) {
my $plink = "linklan/$lan/$member";
#
# We allow users to oversubscribe by letting them turn
# off the bandwidth shaping. If however, if the link was
# shaped for some other reason (like a delay), then
# turn off just the bw shaping part by setting them to 0.
# This is special; means no limits in ipfw.
# off the bandwidth shaping. If however, if the link
# was shaped for some other reason (like a delay), then
# turn off just the bw shaping part by setting them to
# 0. This is special; means no limits in ipfw.
#
if ($nobwshaping) {
$bw = $rbw = 0;
......
# -*- tcl -*-
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2004 University of Utah and the Flux Group.
# Copyright (c) 2000-2005 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -60,6 +60,12 @@ Queue instproc init {link type node} {
$self set gentle_ 0
$self set red_ 0
$self set traced 0
$self set trace_type "header"
$self set trace_expr {}
$self set trace_snaplen 0
$self set trace_endnode 0
#
# These are NS variables for queues (with NS defaults).
#
......@@ -117,6 +123,21 @@ Queue instproc agent_name {} {
return "$mylink-$mynode"
}
# Turn on tracing.
Queue instproc trace {{ttype "header"} {texpr ""}} {
$self instvar traced
$self instvar trace_expr
$self instvar trace_type
if {$texpr == ""} {
set texpr {}
}
set traced 1
set trace_type $ttype
set trace_expr $texpr
}
#
# A queue is associated with a node on a link. Return that node.
#
......@@ -269,6 +290,64 @@ LanLink instproc mustdelay {} {
set mustdelay 1
}
#
# Set up tracing.
#
Lan instproc trace {{ttype "header"} {texpr ""}} {
$self instvar nodelist
$self instvar linkq
foreach nodeport $nodelist {
set linkqueue $linkq($nodeport)
$linkqueue trace $ttype $texpr
}
}
Link instproc trace {{ttype "header"} {texpr ""}} {
$self instvar toqueue
$self instvar fromqueue
$toqueue trace $ttype $texpr
$fromqueue trace $ttype $texpr
}
Lan instproc trace_snaplen {len} {
$self instvar nodelist
$self instvar linkq
foreach nodeport $nodelist {
set linkqueue $linkq($nodeport)
$linkqueue set trace_snaplen $len
}
}
Link instproc trace_snaplen {$len} {
$self instvar toqueue
$self instvar fromqueue
$toqueue set trace_snaplen $len
$fromqueue set trace_snaplen $len
}
Lan instproc trace_endnode {onoff} {
$self instvar nodelist
$self instvar linkq
foreach nodeport $nodelist {
set linkqueue $linkq($nodeport)
$linkqueue set trace_endnode $onoff
}
}
Link instproc trace_endnode {$onoff} {
$self instvar toqueue
$self instvar fromqueue
$toqueue set trace_endnode $onoff
$fromqueue set trace_endnode $onoff
}
# get_port <node>
# This takes a node and returns the port that the node is connected
# to the LAN with. If a node is in a LAN multiple times for some
......@@ -633,6 +712,15 @@ Link instproc updatedb {DB} {
lappend fields "rest_bandwidth"
}
# Tracing.
if {[$linkqueue set traced] == 1} {
lappend fields "traced"
lappend fields "trace_type"
lappend fields "trace_expr"
lappend fields "trace_snaplen"
lappend fields "trace_endnode"
}
set values [list $self $nodeportraw $netmask $delay($nodeport) $rdelay($nodeport) $bandwidth($nodeport) $rbandwidth($nodeport) $loss($nodeport) $rloss($nodeport) $cost($nodeport) $widearea $emulated $uselinkdelay $nobwshaping $useveth $limit_ $maxthresh_ $thresh_ $q_weight_ $linterm_ ${queue-in-bytes_} $bytes_ $mean_pktsize_ $wait_ $setbit_ $droptail_ $red_ $gentle_ $trivial_ok $node $port $ip $mustdelay]
if { [info exists ebandwidth($nodeport)] } {
......@@ -643,6 +731,15 @@ Link instproc updatedb {DB} {
lappend values $rebandwidth($nodeport)
}
# Tracing.
if {[$linkqueue set traced] == 1} {
lappend values [$linkqueue set traced]
lappend values [$linkqueue set trace_type]
lappend values [$linkqueue set trace_expr]
lappend values [$linkqueue set trace_snaplen]
lappend values [$linkqueue set trace_endnode]
}
$sim spitxml_data "virt_lans" $fields $values
}
}
......@@ -761,6 +858,15 @@ Lan instproc updatedb {DB} {
if { [info exists rebandwidth($nodeport)] } {
lappend fields "rest_bandwidth"
}
# Tracing.
if {[$linkqueue set traced] == 1} {
lappend fields "traced"
lappend fields "trace_type"
lappend fields "trace_expr"
lappend fields "trace_snaplen"
lappend fields "trace_endnode"
}
set values [list $self $nodeportraw $netmask $delay($nodeport) $rdelay($nodeport) $bandwidth($nodeport) $rbandwidth($nodeport) $loss($nodeport) $rloss($nodeport) $cost($nodeport) $widearea $emulated $uselinkdelay $nobwshaping $useveth $limit_ $maxthresh_ $thresh_ $q_weight_ $linterm_ ${queue-in-bytes_} $bytes_ $mean_pktsize_ $wait_ $setbit_ $droptail_ $red_ $gentle_ $trivial_ok $protocol $is_accesspoint $node $port $ip $mustdelay]
......@@ -772,6 +878,15 @@ Lan instproc updatedb {DB} {
lappend values $rebandwidth($nodeport)
}
# Tracing.
if {[$linkqueue set traced] == 1} {
lappend values [$linkqueue set traced]
lappend values [$linkqueue set trace_type]
lappend values [$linkqueue set trace_expr]
lappend values [$linkqueue set trace_snaplen]
lappend values [$linkqueue set trace_endnode]
}
$sim spitxml_data "virt_lans" $fields $values
foreach setting_key [array names member_settings] {
......
......@@ -1169,6 +1169,9 @@ Simulator instproc make_event {outer event} {
"Link" -
"Lan" {
set otype LINK
set vnode {}
set vname $obj
switch -- $cmd {
"up" {set etype UP}
"down" {set etype DOWN}
......@@ -1204,13 +1207,28 @@ Simulator instproc make_event {outer event} {