Commit 65506d22 authored by Robert Ricci's avatar Robert Ricci

Fix another old, and significant, bug

Each pclass hold a mapping from type names to nodes of that type
that are currently available for use. This structure was not being
properly maintained; when a mapping was removed, only the entry
for the pnodes *current* type was being put back. When the pnode
goes empty, *all* of its possible types should be marked as available.

The consequence was that for pnodes that could take on multiple types
(which is the common case in Emulab), once a node had been considered
for a certain type (say, 'pc', 'pcvm', or 'delay'), it would *never*
be considered for another type again.

Add a new function that gets called when a pnode goes empty, to reset
*all* of its type mappings in its pclass.

Fixing this bug could have some serious positive consequences.
parent 4ddc7226
......@@ -412,7 +412,9 @@ int pclass_set(tb_vnode *v,tb_pnode *p)
int pclass_unset(tb_pnode *p)
{
// add pnode to all lists in equivalence class.
// add pnode back to the list in the equivalence class that corresponds with
// the current type of the vnode - may be used whether or not the pnode is
// empty.
tb_pclass *c = p->my_class;
tb_pclass::pclass_members_map::iterator dit;
......@@ -443,6 +445,22 @@ int pclass_unset(tb_pnode *p)
return 0;
}
int pclass_reset_maps(tb_pnode *p)
{
// add pnode to *all* lists in equivalence class - should only be called if
// the pnode is empty
tb_pclass *c = p->my_class;
tb_pclass::pclass_members_map::iterator dit;
for (dit=c->members.begin();dit!=c->members.end();++dit) {
if (! (*dit).second->exists(p)) {
(*dit).second->push_front(p);
}
}
return 0;
}
void pclass_debug()
{
cout << "PClasses:\n";
......
......@@ -130,6 +130,10 @@ int generate_pclasses(tb_pgraph &PG, bool pclass_for_each_pnode,
int pclass_set(tb_vnode *v,tb_pnode *p);
int pclass_unset(tb_pnode *p);
// This should be called when the pnode becomes free (and pclass_unset should
// still be called first)
int pclass_reset_maps(tb_pnode *p);
void pclass_debug();
int count_enabled_pclasses();
......
......@@ -1068,6 +1068,7 @@ void remove_node(vvertex vv)
SDEBUG(cerr << " releasing pnode" << endl);
SSUB(SCORE_PNODE);
pnode->remove_current_type();
pclass_reset_maps(pnode);
// ptypes
tb_pnode::types_list::iterator lit = pnode->type_list.begin();
while (lit != pnode->type_list.end()) {
......
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