Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
emulab
emulab-devel
Commits
949d9709
Commit
949d9709
authored
Jun 11, 2009
by
Leigh B. Stoller
Browse files
Wrap up a vinterface in an object, and add methods to reserve and free
shared bandwidth for that interface in the interface_state table.
parent
ed7889f2
Changes
1
Hide whitespace changes
Inline
Side-by-side
db/Interface.pm.in
View file @
949d9709
...
...
@@ -144,6 +144,7 @@ sub switch_port($) { return $_[0]->{'WIRES'}->{'port2'}; }
#
Interface
State
table
sub
enabled
($)
{
return
$
_
[
0
]->{
'STATE'
}->{
'enabled'
};
}
sub
tagged
($)
{
return
$
_
[
0
]->{
'STATE'
}->{
'tagged'
};
}
sub
remaining_bandwidth
{
return
$
_
[
0
]->{
'STATE'
}->{
'remaining_bandwidth'
};
}
sub
IsExperimental
($)
{
...
...
@@ -428,6 +429,202 @@ sub LookUpWideAreaSwitch($$)
return
undef
;
}
####################################################################################
package
Interface
::
VInterface
;
use
libdb
;
use
libtestbed
;
use
English
;
use
overload
(
'""'
=>
'Stringify'
);
my
$
nextfake
=
0
;
#
#
Lookup
by
node_id
,
unit
#
sub
Lookup
($$$$)
{
my
($
class
,
$
nodeid
,
$
unit
)
=
@
_
;
$
nodeid
=
$
nodeid
->
node_id
()
if
(
ref
($
nodeid
));
my
$
query_result
=
DBQueryWarn
(
"select * from vinterfaces "
.
"where node_id='$nodeid' and unit='$unit'"
);
return
undef
if
(
!$query_result);
return
undef
if
(
!$query_result->numrows);
my
$
vinterface
=
{};
$
vinterface
->{
"DBROW"
}
=
$
query_result
->
fetchrow_hashref
();
bless
($
vinterface
,
$
class
);
}
#
accessors
sub
field
($$)
{
return
((
! ref($_[0])) ? -1 : $_[0]->{'DBROW'}->{$_[1]}); }
sub
node_id
($)
{
return
field
($
_
[
0
],
'node_id'
);
}
sub
unit
($)
{
return
field
($
_
[
0
],
'unit'
);
}
sub
mac
($)
{
return
field
($
_
[
0
],
'mac'
);
}
sub
IP
($)
{
return
field
($
_
[
0
],
'IP'
);
}
sub
mask
($)
{
return
field
($
_
[
0
],
'mask'
);
}
sub
type
($)
{
return
field
($
_
[
0
],
'type'
);
}
sub
iface
($)
{
return
field
($
_
[
0
],
'iface'
);
}
sub
rtabid
($)
{
return
field
($
_
[
0
],
'rtabid'
);
}
sub
vnode_id
($)
{
return
field
($
_
[
0
],
'vnode_id'
);
}
sub
exptidx
($)
{
return
field
($
_
[
0
],
'exptidx'
);
}
sub
virtlanidx
($)
{
return
field
($
_
[
0
],
'virtlanidx'
);
}
sub
vlanid
($)
{
return
field
($
_
[
0
],
'vlanid'
);
}
sub
bandwidth
($)
{
return
field
($
_
[
0
],
'bandwidth'
);
}
#
The
virtual
iface
name
is
$
type
$
unit
sub
viface
($)
{
return
$
_
[
0
]->
type
()
.
$
_
[
0
]->
unit
();
}
#
#
Create
a
new
vinterface
#
sub
Create
($$$)
{
my
($
class
,
$
nodeid
,
$
argref
)
=
@
_
;
$
nodeid
=
$
nodeid
->
node_id
()
if
(
ref
($
nodeid
));
$
argref
->{
'node_id'
}
=
$
nodeid
;
#
This
is
generated
by
the
insert
.
delete
($
argref
->{
'unit'
})
if
(
exists
($
argref
->{
'unit'
}));
my
$
query
=
"insert into vinterfaces set "
.
join
(
","
,
map
(
"$_='"
.
$
argref
->{$
_
}
.
"'"
,
keys
(%{$
argref
})));
my
$
query_result
=
DBQueryWarn
($
query
);
return
undef
if
(
!defined($query_result));
my
$
unit
=
$
query_result
->
insertid
;
return
Interface
::
VInterface
->
Lookup
($
nodeid
,
$
unit
);
}
#
#
Create
a
fake
object
,
as
for
the
mapper
(
assign_wrapper
)
during
debugging
.
#
sub
MakeFake
($$$)
{
my
($
class
,
$
nodeid
,
$
argref
)
=
@
_
;
$
nodeid
=
$
nodeid
->
node_id
()
if
(
ref
($
nodeid
));
$
argref
->{
'node_id'
}
=
$
nodeid
;
#
This
is
usually
generated
by
the
insert
.
$
argref
->{
'unit'
}
=
$
nextfake
++;
my
$
self
=
{};
$
self
->{
"DBROW"
}
=
$
argref
;
bless
($
self
,
$
class
);
return
$
self
;
}
#
#
Stringify
for
output
.
#
sub
Stringify
($)
{
my
($
self
)
=
@
_
;
my
$
nodeid
=
$
self
->
node_id
();
my
$
unit
=
$
self
->
unit
();
my
$
iface
=
(
defined
($
self
->
iface
())
?
":"
.
$
self
->
iface
()
:
""
);
my
$
vnodeid
=
(
defined
($
self
->
vnode_id
())
?
":"
.
$
self
->
vnode_id
()
:
""
);
return
"[VInterface: $nodeid:${unit}${iface}${vnodeid}]"
;
}
#
#
On
a
shared
node
,
we
have
to
"reserve"
the
required
bandwidth
on
#
the
physical
interface
.
#
sub
ReserveSharedBandwidth
($$)
{
my
($
self
,
$
bandwidth
)
=
@
_
;
my
$
nodeid
=
$
self
->
node_id
();
my
$
unit
=
$
self
->
unit
();
my
$
iface
=
$
self
->
iface
();
#
Must
be
a
trivial
link
.
return
0
if
(
!defined($iface));
#
#
A
non
-
zero
bandwidth
in
the
vinterfaces
table
tells
us
what
has
#
bee
reserved
for
each
interface
.
These
are
combined
in
the
#
interface_state
table
to
ensure
we
do
not
oversubscribe
the
physical
#
link
.
When
releasing
a
node
,
we
have
to
be
careful
to
release
the
#
shared
bandwidth
for
each
vinterface
on
that
node
.
#
DBQueryWarn
(
"lock tables vinterfaces write, interface_state write"
)
or
return
-
1
;
my
$
query_result
=
DBQueryWarn
(
"update interface_state set "
.
" remaining_bandwidth=remaining_bandwidth-${bandwidth} "
.
"where node_id='$nodeid' and iface='$iface' and "
.
"remaining_bandwidth>=$bandwidth"
);
if
(
!$query_result || !$query_result->affectedrows) {
DBQueryWarn
(
"unlock tables"
);
return
-
1
;
}
if
(
!DBQueryWarn("update vinterfaces set bandwidth=$bandwidth ".
"where node_id='$nodeid' and unit='$unit'"
))
{
DBQueryWarn
(
"update interface_state set "
.
" remaining_bandwidth=remaining_bandwidth+${bandwidth} "
.
"where node_id='$nodeid' and iface='$iface'"
);
DBQueryWarn
(
"unlock tables"
);
return
-
1
;
}
$
self
->{
"DBROW"
}->{
'bandwidth'
}
=
$
bandwidth
;
DBQueryWarn
(
"unlock tables"
);
return
0
;
}
sub
ReleaseSharedBandwidth
($)
{
my
($
self
)
=
@
_
;
my
$
nodeid
=
$
self
->
node_id
();
my
$
unit
=
$
self
->
unit
();
my
$
iface
=
$
self
->
iface
();
my
$
bandwidth
=
$
self
->
bandwidth
();
#
Trivial
link
?
return
0
if
(
!$bandwidth);
DBQueryWarn
(
"lock tables vinterfaces write, interface_state write"
)
or
return
-
1
;
if
(
!DBQueryWarn("update interface_state set ".
" remaining_bandwidth=remaining_bandwidth+${bandwidth} "
.
"where node_id='$nodeid' and iface='$iface'"
))
{
DBQueryWarn
(
"unlock tables"
);
return
-
1
;
}
#
If
this
fails
we
need
to
clean
up
by
hand
.
I
will
add
a
section
#
to
the
nightly
DB
check
that
scans
for
mismatches
.
if
(
!DBQueryWarn("update vinterfaces set bandwidth=0 ".
"where node_id='$nodeid' and unit='$unit'"
))
{
DBQueryWarn
(
"unlock tables"
);
return
-
1
;
}
$
self
->{
"DBROW"
}->{
'bandwidth'
}
=
0
;
DBQueryWarn
(
"unlock tables"
);
return
0
;
}
#
_Always_
make
sure
that
this
1
is
at
the
end
of
the
file
...
1
;
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment