Solaris::DeviceTree::Node - Abstract base class for all device nodes
This class acts as an abstract base class for subclasses of Solaris::DeviceTree to provide methods of general use returning default values for attributes and properties for nodes and supply tree traversal and searching methods. It should not be necessary to instantiate objects of this class directly.
Tree traversal:
$parent = $node->parent_node @childs = $node->child_nodes $root = $node->root_node @siblings = $node->sibling_nodes
Value access:
$path = $node->devfs_path $nodename = $node->node_name $bindingname = $node->binding_name $drivername = $node->driver_name $busaddr = $node->bus_addr $instance = $node->instance @compat = $node->compatible_names %ops = $node->driver_ops if( $node->is_pseudo_node ) ... if( $node->is_sid_node ) ... if( $node->is_prom_node ) ... $nodeid = $node->nodeid %state = $node->state $props = $node->props; $props->{'myprop'}->... $pprops = $node->prom_props; $pprops->{'mypprop'}->... $minors = $node->minor_nodes; $minors->[0]->... $ctrl = $node->controller $target = $node->target $lun = $node->lun $slice = $node->slice $rmt = $node->rmt
Derived value access:
$prop = $node->find_prop( devfs_path => '/aliases', prop_name => 'disk' ) $solaris_path = $node->solaris_path
Node type detection:
if( $node->is_network_node ) ... if( $node->is_block_node ) ... if( $node->is_controller_node ) ...
Node selection:
@network_nodes = $node->network_nodes @block_nodes = $node->block_nodes @controller_nodes = $node->controller_nodes $node = $node->find_nodes( devfs_path => '/pci@1f,0/pci@1f,2000' ); @nodes = $node->find_nodes( func => sub { $_->is_network_node } );
The following methods are available:
Returns the parent node for this node. If this is the root node undef is returned.
undef
This method returns a list with all children.
Returns the root node of the tree.
Returns the list of siblings for this object. A sibling is a child from our parent, but not ourselves.
Returns the physical path assocatiated with this node. Default is undef.
Returns the name of the node used in the pysical path. Default is undef.
Returns the binding name of the driver for the node. Default is undef.
Returns the driver name for the node. Default is undef.
Returns the address on the bus for this node. Default is undef.
Returns the instance number of the bound driver for this node. Default is undef.
Returns the list of device which are compatible to this node. Default is the empty list.
Returns a hash which keys indicate which driver entry points are supported by the driver bound to this node. This is done to allow writing of something like if( exists $ops{'STREAM'} ) .... Default is the empty list.
if( exists $ops{'STREAM'} ) ...
Returns true if this is a pseudo / SID / PROM node. The default is false.
true
false
Returns the type of the node differing between pseudo, SID, etc. Default is undef.
Returns a hash which keys indicate the state in which the bound driver is. Default is the empty list.
Returns a reference to the properties associated with this node. Default is undef.
Returns a reference to the PROM properties associated with this node. Default is undef.
Returns a reference to a list containing the minor nodes associated to this node. Default is undef.
This method returns the name of the associated Solaris device. This is currently something like
c0t0d0s0 for a disk device hme0 for a network device
or undef if no corresponding Solaris device could be found.
Returns the controller number which is associated to this node. Default is undef.
Returns the target number which is associated to this node. Default is undef.
Returns the logical unit number which is associated to this node. Default is undef.
Returns the slice number which is associated to this node. Default is undef.
Returns the tape number which is associated to this node. Default is undef.
This method returns true if the node represents a network card.
This method returns true if the node represents a block device (which is essentially a disk).
This method returns true if the node represents a controller device.
This method returns all nodes for network cards in the tree.
This method returns all nodes for disks in the tree.
This method returns all nodes for controller devices.
This method returns nodes matching certain criteria. Currently it is possible to match against a physical path or to specify a subroutine where the node is returned if the subroutine returns true. As in Perl grep $_ is locally bound to the node being checked.
$_
In a scalar context the method returns only the first node found. In an array context the method returns all matching nodes.
Examples:
$node = $node->find_nodes( devfs_path => '/pci@1f,0/pci@1f,2000' ); @nodes = $node->find_nodes( func => sub { $_->is_network_node } );
This method picks a node by criteria from the devicetree and then selects either a property or a prom property depending on the options given. At least one of
prop_name prom_prop_name
must be specified. All options valid for find_nodes are also applicable to this method.
Example:
$prop = $node->find_prop( devfs_path => '/aliases', prop_name => 'disk' )
This method finds the minor node with the specified name.
#=head2 prom_path # #This method converts between a Solaris device path and an OBP device path. # #The conversion is quite complex. As a first step the IOCTLS # # OPROMDEV2PROMNAME (OIOC | 15) /* Convert devfs path to prom path */ # OPROMPROM2DEVNAME (OIOC | 16) /* Convert prom path to devfs path */ # #from the openeepr driver accessed through /dev/openprom might be taken. #However, some older machines are not aware of that. It would #be optimal to use devfs_dev_to_prom_name from libdevinfo(3devinfo), but that one is #a static function and reprogramming that one is *not* fun. # #=cut
openeepr
/dev/openprom
devfs_dev_to_prom_name
# This method takes an obp path in an OBP::Path object and returns a # solaris path. # In other words: a path containing only prom nodes is transformed to # a path containing pseudo nodes. # $promPath is a reference to an OBP::Path::Component array # This method returns an OBP::Path object. The returned object might or # might not point to a node in the obp tree. sub solaris_path { my ($this, $promPath) = @_; $promPath = new OBP::Path( string => $promPath ) if( !ref( $promPath ) ); return $promPath if( @{$promPath->components} == 0 );
my $pc; # leftmost path component, the one to check against $pc = shift @{$promPath->components};
#print "Matching ", $pc->string, " ", $this->devfsPath, "\n"; my @children = $this->children( nodename => $pc->node, busaddress => $pc->busaddress ); if( @children == 0 ) { # no direct match found # Check if we have a transfer node.
# The mapping might or might not lead to different pathes. # Examples: # Ultra 10 IDE disk: disk -> dad # ATAPI cdrom: cdrom -> sd # SCSI disk: disk -> sd # Ultra 1: SCSI disk: sd -> sd @children = $this->children( nodename => $pc->node, busaddr => undef, instance => undef ); if( @children == 0 ) { # No transfer node found. Because we can't find the next node in the # device tree we guess that the path stays the same and return what we have. return new OBP::Path( components => [ $pc, @{$promPath->components} ] ); } elsif( @children == 1 ) { # we found the transfer node. Continue with the node specified in the # driverName attribute but leave the address and args (if any) the same. my $transferNode = $children[ 0 ]; my @target = $this->children( nodename => $transferNode->driverName, busaddress => $pc->busaddress ); if( @target == 0 ) { # We have a transfer node but no node to continue. Return the corrected # node and leave the rest as is. return new OBP::Path( components => [ new OBP::Path::Component( node => $transferNode->driverName, adr => $pc->adr, subadr => $pc->subadr, arg => $pc->arg, ), @{$promPath->components} ] ); } elsif( @target == 1 ) { # Everything fine. Prepend the found note after node transferal to # the result of the continued search. my $contnode = $target[ 0 ]; return new OBP::Path( components => [ new OBP::Path::Component( string => $contnode->nodeName . "@" . $contnode->busAddress . ( defined $pc->arg ? ':' . $pc->arg : '' ) ), @{$contnode->solarisPath( $promPath )->components} ] ); } else { warn "Found more than one node after node transfer. This should not happen."; } } else { # This is a very ugly situation. We have a valid prefix and we don't # know yet how to continue correctly. Both might be valid Solaris pathes. # It is unfortunately possible (is it?) that one path can be continued # and the other can not. So all pathes should be tried and compared here. # -> TODO warn " Found more than one transfer node:\n " . join( "\n ", map { $_->devfsPath } @children ) . "\n"; my $match = $children[ 0 ]; return new OBP::Path( components => [ $pc, @{$match->solarisPath( $promPath )->components} ] ); } } elsif( @children == 1 ) { # found exact match. Continue with the next node. my $match = $children[ 0 ]; return new OBP::Path( components => [ $pc, @{$match->solarisPath( $promPath )->components} ] ); } else { # -> TODO: Wildcard match warn "Wildcard match. Just taking the first match."; my $match = $children[ 0 ]; return new OBP::Path( components => [ $pc, @{$match->solarisPath( $promPath )->components} ] ); } }
Copyright 1999-2003 Dagobert Michelsen.
Solaris::DeviceTree::Libdevinfo, Solaris::DeviceTree::PathToInst, Solaris::DeviceTree::Filesystem, eeprom(1m).
To install Solaris::DeviceTree::Libdevinfo::Impl, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Solaris::DeviceTree::Libdevinfo::Impl
CPAN shell
perl -MCPAN -e shell install Solaris::DeviceTree::Libdevinfo::Impl
For more information on module installation, please visit the detailed CPAN module installation guide.