In OpenSM 4.9.0 (May 2017) and beyond, a unified port groups policy file
is supported. It is used for routing chains, root GUID file, search
ordering port file, partition file, GUID routing order file, IO GUID
file, CN GUID file, and QoS policy file.

Defining Port Groups
The basic idea behind the port groups feature is the ability to divide the
fabric into sub-groups and give each group an identifier that can be used
to relate to all nodes in this group.

1. Defining a Port Group Policy File
In order to define a port group policy file, set the parameter
'pgrp_policy_file' in the opensm configuration file.

pgrp_policy_file /etc/opensm/conf/port_groups_policy_file

2. Configuring a Port Group Policy
The port groups policy file details the port groups in the fabric. The policy
file should be composed of one or more paragraphs that define a group. Each
paragraph should begin with the line 'port-group' and end with the line
'end-port-group'.

For example:
port-group
...port group qualifiers...
end-port-group

3. Port Group Qualifiers
Unlike the port group's beginning and ending which do not require a colon,
all qualifiers must end with a colon (':'). Also, a colon is a predefined
mark that must not be used inside qualifier values. Inclusion of a colon
in the name or in the use of a port group will result in the policy's failure.

Parameter |              Description                      | Example
----------------------------------------------------------------------------
name      | Each group must have a name. Without a name   | name: grp1
          | qualifier, the policy fails.                  |
----------------------------------------------------------------------------
use       | 'use' is an optional qualifier that one can   | use: first port
          | define in order to describe the usage of this | group
          | port group (if undefined, an empry string is  |
          | used as a default).                           |
----------------------------------------------------------------------------

4. Rule Qualifier
There are several qualifiers used to describe a rule that determines which
ports will be added to the group. Each port group may include one or more
rules out of the rules described in the table below (at least one rule must
be defined for each port group).

Parameter |              Description                      | Example
----------------------------------------------------------------------------
guid list | Comma separated list of guids to include in   | port-guid: 0x283,
          | the group.                                    | 0x286, 0x289
          | If no specific physical ports were            |
          | configured, all physical ports of the guid    |
          | are chosen. However, for each guid, one       |
          | can detail specific physical ports to be      |
          | included in the group. This can be done       |
          | using the following syntax:                   |
          | o Specify a specific port in a guid to be     |
          |   chosen                                      |
          | port-guid: 0x283@3                            |
          | o Specify a specific list of ports in a guid  |
          |   to be chosen                                |
          | port-guid: 0x286@1/5/7                        |
          | o Specify a specific range of ports in a      |
          |   guid to be chosen                           |
          | port-guid: 0x289@2-5                          |
          | o Specify a list of specific ports and port   |
          |   ranges in a guid to be chosen               |
          | port-guid: 0x289@2-5/7/9-13/18                |
          | o Complex rule                                |
          | port-guid: 0x283@5-8/12/14, 0x286,            |
          | 0x289/6/8/12                                  |
----------------------------------------------------------------------------
port guid | It is possible to configure a range of guids  | port-guid-range:
range     | to be chosen to the group. However, while     | 0x283-0x289
          | using the range qualifier, it is impossible   |
          | to detail specific physical ports.            |
          | Note: A list of ranges cannot be specified.   |
          | The example below is invalid and will         |
          | cause the policy to fail:                     |
          | port-guid-range: 0x283-0x289, 0x290-0x295     |
----------------------------------------------------------------------------
port name | One can configure a list of hostnames as a    | port-name:
          | rule. Hosts with a node description that is   | hostname=kuku;
          | built out of these hostnames will be chosen.  | port=2; hca_idx=1
          | Since the node description contains the       |
          | network card index as well, one might also    |
          | specify a network card index and a physical   |
          | port to be chosen. For example, the given     |
          | configuration will cause only physical port   |
          | 2 of a host with the node description 'kuku   |
          | HCA-1' to be chosen.                          |
          | port and hca_idx parameters are optional. If  |
          | the port is unspecified, all physical ports   |
          | are chosen. If hca_idx is unspecified, all    |
          | card numbers are chosen. Specifying a         |
          | hostname is mandatory.                        |
          | One can configure a list of                   |
          | hostname/port/hca_idx sets in the same        |
          | qualifier as follows:                         |
          | port-name: hostname=kuku; port=2; hca_idx=1,  |
          | hostname=host1; port=3, hostname=host2        |
          | Note: In the case the name of the host        |
          | contains ';' there is a special syntax that   |
          | works for regular names as well:              |
          | port-name: hostname='kuku'; port=2; hca_idx=1,|
          | hostname='host;1'; port=3, hostname='host;2'  |
          | Note: port-name qualifier is not relevant for |
          | switches, but for HCA's only.                 |
----------------------------------------------------------------------------
port      | One can define a regular expression so that   | port-regexp: SW.*
regex     | only nodes with a matching node               |
          | description will be chosen to the group.      |
          ------------------------------------------------------------------
          | It is possible to specify one physical port   | port-regexp: SW.*:3
          | to be chosen for matching nodes (there is no  |
          | option to define a list or a range of ports). |
          | The example given will cause only nodes       |
          | that match physical port 3 to be added to     |
          | the group.                                    |
----------------------------------------------------------------------------
union     | It is possible to define a rule that unites   | union-rule: grp1,
rule      | two different port groups. This means that    | grp2
          | all ports from both groups will be included   |
          | in the united group.                          |
----------------------------------------------------------------------------
subtract  | One can define a rule that subtracts one port | subtract-rule:
rule      | group from another. The given rules, for      | grp1, grp2
          | example, will cause all the ports which are a |
          | part of grp1, but not included in grp2, to be |
          | chosen.                                       |
          | In subtraction (unlike union), the order      |
          | does matter, since the purpose is to subtract |
          | the second group from the first one.          |
          | There is no option to define more than two    |
          | groups for union/subtraction. However, one    |
          | can unite/subtract groups which are a union   |
          | or subtraction themselves, as shown in the    |
          | port groups policy file example.              |
----------------------------------------------------------------------------

5. Predefined Port Groups
The following port groups are predefined:
o ALL - a group that includes all nodes in the fabric
o ALL_SWITCHES - a group that includes all switches in the fabric
o ALL_CAS - a group that includes all HC's in the fabric
o ALL_MGMT_CAS - a group containing all management HC's nodes in the fabric
o ALL_COMPUTE_CAS - a group containing all compute HC's nodes in the fabric
o ALL_ROUTERS - a group that includes all routers in the fabric
o ALL_ANS - a group that includes all ANs in the fabric
o ALL_SW_TO_CA - a group containing all the ports of the switch connected to a host.
o ALL_SW_TO_SW - a group containing all the ports of the switch connected to a switch.

These names are reserved and cannot be specified in the port group policy file.

6. Port Groups Policy Examples
port-group
name: grp3
use: Subtract of groups grp1 and grp2
subtract-rule: grp1, grp2
end-port-group

port-group
name: grp1
port-guid: 0x281, 0x282, 0x283
end-port-group

port-group
name: grp2
port-guid-range: 0x282-0x286
port-name: hostname=server1 port=1
end-port-group

port-group
name: grp4
port-name: hostname=kika port=1 hca_idx=1
end-port-group

port-group
name: grp3
union-rule: grp3, grp4
end-port-group
