Skip to content

Commit

Permalink
Add generic --sa-path option to specify path to SA
Browse files Browse the repository at this point in the history
The specified path may be off-subnet.  This option doesn't make sense
for all commands but is currently universal.
  • Loading branch information
jgunthorpe committed Aug 2, 2016
1 parent be9c64d commit 46cebbb
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 19 deletions.
28 changes: 23 additions & 5 deletions libibtool/libibopts.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@ def tmpl_node_guid(s):
def tmpl_port_guid(s):
return IBA.GUID(s);

def _set_sa_path(option,opt,value,parser):
try:
path = rdma.path.from_string(value)
path.dqpn = 1
path.sqpn = 1
path.qkey = IBA.IB_DEFAULT_QP1_QKEY
parser.values.sa_path = path
parser.values.use_sa = True
except ValueError:
parser.error("invalid path: %s" % value)

class LibIBOpts(object):
"""Emulate the commandline parsing of legacy tools."""
debug = 0;
Expand Down Expand Up @@ -156,6 +167,8 @@ def setup(o,address=True,discovery=False):
help="Use internal names for all the fields instead of libib compatible names.");
o.add_option("--sa",dest="use_sa",action="store_true",
help="Instead of issuing SMPs, use corresponding record queries to the SA.");
o.add_option("--sa-path",action="callback",callback=_set_sa_path,type=str,dest="sa_path",
help="Specify the path to the SA, implies --sa.");

if address:
try:
Expand Down Expand Up @@ -249,11 +262,11 @@ def get_gmp_path(self,path,umad):
self.debug_print_path("GMP",path);
return path;

def get_umad(self,gmp=False):
def get_umad(self,gmp=False,local_sa=False):
"""Return a generic umad."""
return self.get_umad_for_target(gmp=gmp);
return self.get_umad_for_target(gmp=gmp,local_sa=local_sa);

def get_umad_for_target(self,path=False,gmp=False):
def get_umad_for_target(self,path=False,gmp=False,local_sa=False):
"""Return a UMAD suitable for use to talk to *path*. *path* is an
:class:`rdma.path.IBPath`. If *path* is `None` then a loopback path is
resolved, if *path* is `False` then no path is resolved.
Expand All @@ -270,7 +283,12 @@ def get_umad_for_target(self,path=False,gmp=False):
if self.args.use_sa:
__import__("rdma.satransactor");
import sys;
umad = sys.modules["rdma.satransactor"].SATransactor(umad);
if local_sa or self.args.sa_path is None:
sa_path = self.end_port.sa_path
else:
sa_path = self.args.sa_path
rdma.path.resolve_path(umad, sa_path)
umad = sys.modules["rdma.satransactor"].SATransactor(umad,sa_path);

if path is False:
self.path = None;
Expand All @@ -290,7 +308,7 @@ def get_sched(self,umad,path=None):
if self.args.use_sa:
if path is not None:
umad.get_path_lid(path);
return umad.__class__(rdma.sched.MADSchedule(umad._parent));
return umad.__class__(rdma.sched.MADSchedule(umad._parent), self.args.sa_path);
return rdma.sched.MADSchedule(umad);

def get_end_port(self):
Expand Down
7 changes: 6 additions & 1 deletion libibtool/saquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,13 @@ def cmd_saquery(argv,o):
n,query.__class__.__name__,", ".join(query.COMPONENT_MASK.iterkeys())));
set_mad_attr(query_cm,n,v);

path = None
if args.sa_path:
with lib.get_umad(gmp=True,local_sa=True) as umad:
path = args.sa_path
rdma.path.resolve_path(umad, path)

with lib.get_umad(gmp=True) as umad:
path = umad.end_port.sa_path;

# Special help for PathRecords, spec says SGID and numbPath are mandatory for GetTable.
if args.kind == IBA.SAPathRecord and not args.use_get and not args.no_defaults:
Expand Down
32 changes: 19 additions & 13 deletions rdma/satransactor.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ class SATransactor(rdma.madtransactor.MADTransactor):
It is also a context manager that wrappers the *parent*'s :meth:`close`."""

def __init__(self,parent):
def __init__(self,parent,sa_path=None):
"""*parent* is the :class:`~rdma.madtransactor.MADTransactor` we are
wrappering."""
self._parent = parent;
self.end_port = parent.end_port;
self.sa_path = sa_path or self.end_port.sa_path;

def get_path_lid(self,path):
"""Resolve *path* to a LID. This is only does something if *path*
Expand Down Expand Up @@ -115,21 +116,26 @@ def _finish_nodeinfo(self,rpayload):
self.req_path._cached_node_type = rpayload.nodeInfo.nodeType;
return rpayload.nodeInfo;

def _subn_adm_do(self,payload,path,attributeModifier,method,completer=None):
if path is None:
path = self.sa_path
return rdma.madtransactor.MADTransactor._subn_adm_do(self,payload,path,attributeModifier,method,completer)

def SubnGet(self,payload,path,attributeModifier=0):
ID = payload.MAD_ATTRIBUTE_ID;
meth = payload.MAD_SUBNGET;
if ID == IBA.SMPGUIDInfo.MAD_ATTRIBUTE_ID:
req = IBA.ComponentMask(IBA.SAGUIDInfoRecord());
req.LID = self.get_path_lid(path);
req.blockNum = attributeModifier;
return self._subn_adm_do(req,self.end_port.sa_path,0,
return self._subn_adm_do(req,self.sa_path,0,
req.MAD_SUBNADMGET,
lambda x:x.GUIDInfo);
if ID == IBA.SMPLinearForwardingTable.MAD_ATTRIBUTE_ID:
req = IBA.ComponentMask(IBA.SALinearForwardingTableRecord());
req.LID = self.get_path_lid(path);
req.blockNum = attributeModifier;
return self._subn_adm_do(req,self.end_port.sa_path,0,
return self._subn_adm_do(req,self.sa_path,0,
req.MAD_SUBNADMGET,
(lambda x:x.linearForwardingTable,
self._sa_error));
Expand All @@ -138,20 +144,20 @@ def SubnGet(self,payload,path,attributeModifier=0):
req.LID = self.get_path_lid(path);
req.blockNum = attributeModifier & ((1<<9)-1);
req.position = (attributeModifier >> 12) & 0xF;
return self._subn_adm_do(req,self.end_port.sa_path,0,
return self._subn_adm_do(req,self.sa_path,0,
req.MAD_SUBNADMGET,
(lambda x:x.multicastForwardingTable,
self._sa_error));
if ID == IBA.SMPNodeDescription.MAD_ATTRIBUTE_ID:
req = IBA.ComponentMask(IBA.SANodeRecord());
req.LID = self.get_path_lid(path);
return self._subn_adm_do(req,self.end_port.sa_path,0,
return self._subn_adm_do(req,self.sa_path,0,
req.MAD_SUBNADMGET,
self._finish_nodedesc);
if ID == IBA.SMPNodeInfo.MAD_ATTRIBUTE_ID:
req = IBA.ComponentMask(IBA.SANodeRecord());
req.LID = self.get_path_lid(path);
return self._subn_adm_do(req,self.end_port.sa_path,0,
return self._subn_adm_do(req,self.sa_path,0,
req.MAD_SUBNADMGET,
self._finish_nodeinfo);

Expand All @@ -162,7 +168,7 @@ def SubnGet(self,payload,path,attributeModifier=0):
if nt is None or nt == IBA.NODE_SWITCH:
req.portNum = attributeModifier >> 16;
req.blockNum = attributeModifier & 0xFFFF;
return self._subn_adm_do(req,self.end_port.sa_path,0,
return self._subn_adm_do(req,self.sa_path,0,
req.MAD_SUBNADMGET,
(lambda x:x.PKeyTable,
self._sa_error));
Expand All @@ -175,41 +181,41 @@ def SubnGet(self,payload,path,attributeModifier=0):
# This can mean 'whatever port' or it can mean 'switch port 0'
# If we don't know the node type then do a get table and
# figure it out.
return self._subn_adm_do(req,self.end_port.sa_path,0,
return self._subn_adm_do(req,self.sa_path,0,
req.MAD_SUBNADMGETTABLE,
self._finish_port_info_attr0);

req.portNum = attributeModifier;
return self._subn_adm_do(req,self.end_port.sa_path,0,
return self._subn_adm_do(req,self.sa_path,0,
req.MAD_SUBNADMGET,
lambda x:x.portInfo);
if ID == IBA.SMPSLToVLMappingTable.MAD_ATTRIBUTE_ID:
req = IBA.ComponentMask(IBA.SASLToVLMappingTableRecord());
req.LID = self.get_path_lid(path);
req.inputPortNum = (attributeModifier >> 8) & 0xFF;
req.outputPortNum = attributeModifier & 0xFF;
return self._subn_adm_do(req,self.end_port.sa_path,0,
return self._subn_adm_do(req,self.sa_path,0,
req.MAD_SUBNADMGET,
(lambda x:x.SLToVLMappingTable,
self._sa_error));
if ID == IBA.SMPSMInfo.MAD_ATTRIBUTE_ID:
req = IBA.ComponentMask(IBA.SASMInfoRecord());
req.LID = self.get_path_lid(path);
return self._subn_adm_do(req,self.end_port.sa_path,0,
return self._subn_adm_do(req,self.sa_path,0,
req.MAD_SUBNADMGET,
lambda x:x.SMInfo);
if ID == IBA.SMPSwitchInfo.MAD_ATTRIBUTE_ID:
req = IBA.ComponentMask(IBA.SASwitchInfoRecord());
req.LID = self.get_path_lid(path);
return self._subn_adm_do(req,self.end_port.sa_path,0,
return self._subn_adm_do(req,self.sa_path,0,
req.MAD_SUBNADMGET,
lambda x:x.switchInfo);
if ID == IBA.SMPVLArbitrationTable.MAD_ATTRIBUTE_ID:
req = IBA.ComponentMask(IBA.SAVLArbitrationTableRecord());
req.LID = self.get_path_lid(path);
req.outputPortNum = attributeModifier & 0xFFFF;
req.blockNum = (attributeModifier >> 16) & 0xFFFF;
return self._subn_adm_do(req,self.end_port.sa_path,0,
return self._subn_adm_do(req,self.sa_path,0,
req.MAD_SUBNADMGET,
(lambda x:x.VLArbitrationTable,
self._sa_error));
Expand Down

0 comments on commit 46cebbb

Please sign in to comment.