|
Packit Service |
3470d1 |
/* BEGIN_ICS_COPYRIGHT7 ****************************************
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
Copyright (c) 2015-2017, Intel Corporation
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
Redistribution and use in source and binary forms, with or without
|
|
Packit Service |
3470d1 |
modification, are permitted provided that the following conditions are met:
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
* Redistributions of source code must retain the above copyright notice,
|
|
Packit Service |
3470d1 |
this list of conditions and the following disclaimer.
|
|
Packit Service |
3470d1 |
* Redistributions in binary form must reproduce the above copyright
|
|
Packit Service |
3470d1 |
notice, this list of conditions and the following disclaimer in the
|
|
Packit Service |
3470d1 |
documentation and/or other materials provided with the distribution.
|
|
Packit Service |
3470d1 |
* Neither the name of Intel Corporation nor the names of its contributors
|
|
Packit Service |
3470d1 |
may be used to endorse or promote products derived from this software
|
|
Packit Service |
3470d1 |
without specific prior written permission.
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
Packit Service |
3470d1 |
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
Packit Service |
3470d1 |
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
Packit Service |
3470d1 |
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
Packit Service |
3470d1 |
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
Packit Service |
3470d1 |
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
Packit Service |
3470d1 |
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
Packit Service |
3470d1 |
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
Packit Service |
3470d1 |
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
Packit Service |
3470d1 |
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
** END_ICS_COPYRIGHT7 ****************************************/
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
/* [ICS VERSION STRING: unknown] */
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
#include "opareport.h"
|
|
Packit Service |
3470d1 |
#include <iba/stl_helper.h>
|
|
Packit Service |
3470d1 |
#include <limits.h>
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// Fabric Topology Verification and related reports
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
void ShowProblem(Format_t format, int indent, int detail, const char* pformat, ...)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
va_list args;
|
|
Packit Service |
3470d1 |
static char buffer[100];
|
|
Packit Service |
3470d1 |
int cnt;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
if (detail >= 0) {
|
|
Packit Service |
3470d1 |
va_start(args, pformat);
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("%*s", indent, "");
|
|
Packit Service |
3470d1 |
vprintf(pformat, args);
|
|
Packit Service |
3470d1 |
printf("\n");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
cnt = vsnprintf(buffer, sizeof(buffer), pformat, args);
|
|
Packit Service |
3470d1 |
ASSERT(cnt <= sizeof(buffer)-1); /* make sure message fits */
|
|
Packit Service |
3470d1 |
XmlPrintStr("Problem", buffer, indent);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
va_end(args);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// verify a port against its corresponding ExpectedLink->PortSelector
|
|
Packit Service |
3470d1 |
// Only valid to be called for ports with ExpectedLink
|
|
Packit Service |
3470d1 |
// returns FALSE if any discrepencies
|
|
Packit Service |
3470d1 |
// only does output if detail >= 0
|
|
Packit Service |
3470d1 |
boolean PortVerify(PortData *portp, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
ExpectedLink *elinkp = portp->elinkp;
|
|
Packit Service |
3470d1 |
PortSelector *portselp = NULL;
|
|
Packit Service |
3470d1 |
boolean ret=TRUE;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
if (elinkp->portp1 == portp) {
|
|
Packit Service |
3470d1 |
portselp = elinkp->portselp1;
|
|
Packit Service |
3470d1 |
} else if (elinkp->portp2 == portp) {
|
|
Packit Service |
3470d1 |
portselp = elinkp->portselp2;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (portselp) { // not specified in input topology xml file; accept any port on the other end of the link
|
|
Packit Service |
3470d1 |
if (portselp->NodeGUID && portselp->NodeGUID != portp->nodep->NodeInfo.NodeGUID) {
|
|
Packit Service |
3470d1 |
ret = FALSE;
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail,
|
|
Packit Service |
3470d1 |
"NodeGuid mismatch: expected: 0x%016"PRIx64" found: 0x%016"PRIx64,
|
|
Packit Service |
3470d1 |
portselp->NodeGUID, portp->nodep->NodeInfo.NodeGUID);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (portselp->NodeDesc
|
|
Packit Service |
3470d1 |
&& 0 != strncmp(portselp->NodeDesc,
|
|
Packit Service |
3470d1 |
(char*)portp->nodep->NodeDesc.NodeString,
|
|
Packit Service |
3470d1 |
NODE_DESCRIPTION_ARRAY_SIZE)) {
|
|
Packit Service |
3470d1 |
ret = FALSE;
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail,
|
|
Packit Service |
3470d1 |
"NodeDesc mismatch: expected: '%s' found: '%.*s'",
|
|
Packit Service |
3470d1 |
portselp->NodeDesc, NODE_DESCRIPTION_ARRAY_SIZE,
|
|
Packit Service |
3470d1 |
(char*)portp->nodep->NodeDesc.NodeString);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (portselp->gotPortNum && portselp->PortNum != portp->PortNum) {
|
|
Packit Service |
3470d1 |
ret = FALSE;
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail,
|
|
Packit Service |
3470d1 |
"PortNum mismatch: expected: %3u found: %3u",
|
|
Packit Service |
3470d1 |
portselp->PortNum, portp->PortNum);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (portselp->PortGUID && portselp->PortGUID != portp->PortGUID) {
|
|
Packit Service |
3470d1 |
ret = FALSE;
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail,
|
|
Packit Service |
3470d1 |
"PortGuid mismatch: expected: 0x%016"PRIx64" found: 0x%016"PRIx64,
|
|
Packit Service |
3470d1 |
portselp->PortGUID, portp->PortGUID);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (portselp->NodeType && portselp->NodeType != portp->nodep->NodeInfo.NodeType) {
|
|
Packit Service |
3470d1 |
ret = FALSE;
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail,
|
|
Packit Service |
3470d1 |
"NodeType mismatch: expected: %s found: %s",
|
|
Packit Service |
3470d1 |
StlNodeTypeToText(portselp->NodeType),
|
|
Packit Service |
3470d1 |
StlNodeTypeToText(portp->nodep->NodeInfo.NodeType));
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
/* to get here the port must have a neighbor and hence should be linkup
|
|
Packit Service |
3470d1 |
* but it could be quarantined or failing to move to Active
|
|
Packit Service |
3470d1 |
*/
|
|
Packit Service |
3470d1 |
if (portp->PortInfo.PortStates.s.PortState != IB_PORT_ACTIVE) {
|
|
Packit Service |
3470d1 |
ret = FALSE;
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail,
|
|
Packit Service |
3470d1 |
"Port not Active: PortState: %s",
|
|
Packit Service |
3470d1 |
StlPortStateToText(portp->PortInfo.PortStates.s.PortState));
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
return ret;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// check attributes of link against input topology
|
|
Packit Service |
3470d1 |
// Only valid to be called for ports with ExpectedLink
|
|
Packit Service |
3470d1 |
// returns FALSE if link fails to verify
|
|
Packit Service |
3470d1 |
// only does output if detail >= 0
|
|
Packit Service |
3470d1 |
boolean LinkAttrVerify(ExpectedLink *elinkp, PortData *portp1, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
PortData *portp2 = portp1->neighbor;
|
|
Packit Service |
3470d1 |
boolean ret = TRUE;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
if (elinkp->expected_rate && elinkp->expected_rate != portp1->rate) {
|
|
Packit Service |
3470d1 |
ret = FALSE;
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail,
|
|
Packit Service |
3470d1 |
"Link Rate mismatch: expected: %4s found: %4s",
|
|
Packit Service |
3470d1 |
StlStaticRateToText(elinkp->expected_rate),
|
|
Packit Service |
3470d1 |
StlStaticRateToText(portp1->rate));
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
if (elinkp->expected_mtu && elinkp->expected_mtu != MIN(portp1->PortInfo.MTU.Cap, portp2->PortInfo.MTU.Cap)) {
|
|
Packit Service |
3470d1 |
ret = FALSE;
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail,
|
|
Packit Service |
3470d1 |
"Link MTU mismatch: expected minimum MTU: %5s found MTU: %5s",
|
|
Packit Service |
3470d1 |
IbMTUToText(elinkp->expected_mtu),
|
|
Packit Service |
3470d1 |
IbMTUToText(MIN(portp1->PortInfo.MTU.Cap, portp2->PortInfo.MTU.Cap)));
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
return ret;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
typedef enum {
|
|
Packit Service |
3470d1 |
LINK_VERIFY_OK = 0, // link matches input topology
|
|
Packit Service |
3470d1 |
LINK_VERIFY_DIFF = 1, // link fully resolved but diff from input topology
|
|
Packit Service |
3470d1 |
LINK_VERIFY_UNEXPECTED = 2, // link not found in input topology
|
|
Packit Service |
3470d1 |
LINK_VERIFY_MISSING = 3, // link not found in fabric, but in input topology
|
|
Packit Service |
3470d1 |
LINK_VERIFY_DUP = 4, // possible duplicate in input topology
|
|
Packit Service |
3470d1 |
LINK_VERIFY_CONN = 5, // link partially resolved, wrong cabling
|
|
Packit Service |
3470d1 |
LINK_VERIFY_MAX=5 // maximum value of the above
|
|
Packit Service |
3470d1 |
} LinkVerifyResult_t;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// check both fabric ports and link attributes against input topology
|
|
Packit Service |
3470d1 |
// only does output if detail >= 0
|
|
Packit Service |
3470d1 |
LinkVerifyResult_t LinkFabricVerify(PortData *portp, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
LinkVerifyResult_t ret = LINK_VERIFY_OK;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// all checks which are based off of found ports/links in fabric
|
|
Packit Service |
3470d1 |
if (portp->elinkp && portp->neighbor->elinkp) {
|
|
Packit Service |
3470d1 |
ExpectedLink *elinkp = portp->elinkp;
|
|
Packit Service |
3470d1 |
DEBUG_ASSERT(portp->elinkp == portp->neighbor->elinkp);
|
|
Packit Service |
3470d1 |
// check both sides for expected characteristics
|
|
Packit Service |
3470d1 |
if (! PortVerify(portp, format, indent, detail))
|
|
Packit Service |
3470d1 |
ret = LINK_VERIFY_DIFF;
|
|
Packit Service |
3470d1 |
if (! PortVerify(portp->neighbor, format, indent, detail))
|
|
Packit Service |
3470d1 |
ret = LINK_VERIFY_DIFF;
|
|
Packit Service |
3470d1 |
// check expected link characteristics
|
|
Packit Service |
3470d1 |
if (! LinkAttrVerify(elinkp, portp, format, indent, detail))
|
|
Packit Service |
3470d1 |
ret = LINK_VERIFY_DIFF;
|
|
Packit Service |
3470d1 |
} else if (! portp->elinkp && ! portp->neighbor->elinkp) {
|
|
Packit Service |
3470d1 |
ret = LINK_VERIFY_UNEXPECTED; // extra link
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Unexpected Link");
|
|
Packit Service |
3470d1 |
} else {
|
|
Packit Service |
3470d1 |
// only one side resolved
|
|
Packit Service |
3470d1 |
DEBUG_ASSERT(0); // we only set elinkp if both sides resolved
|
|
Packit Service |
3470d1 |
ret = LINK_VERIFY_UNEXPECTED; // internal error
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
return ret;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// compare ExpectedLink against fabric
|
|
Packit Service |
3470d1 |
// LinkFabricVerify will have caught links which are different or extra
|
|
Packit Service |
3470d1 |
// this is focused on duplicate ExpectedLink or missing links
|
|
Packit Service |
3470d1 |
// only does output if detail >= 0
|
|
Packit Service |
3470d1 |
// side controls message output:
|
|
Packit Service |
3470d1 |
// 0 - both ports and link info - for initial checks
|
|
Packit Service |
3470d1 |
// 1 - elinkp->port 1 - when in process of outputting port 1 info
|
|
Packit Service |
3470d1 |
// 2 - elinkp->port 2 - when in process of outputting port 2 info
|
|
Packit Service |
3470d1 |
// 3 - link info only - when in process of outputting summary link info
|
|
Packit Service |
3470d1 |
LinkVerifyResult_t ExpectedLinkVerify(ExpectedLink *elinkp, uint8 side, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
LinkVerifyResult_t ret = LINK_VERIFY_OK;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
if (! elinkp->portp1 && ! elinkp->portp2) {
|
|
Packit Service |
3470d1 |
if (side == 0 || side == 3)
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Missing Link");
|
|
Packit Service |
3470d1 |
ret = LINK_VERIFY_MISSING; // missing link
|
|
Packit Service |
3470d1 |
} else if (elinkp->portp1 && elinkp->portp2) {
|
|
Packit Service |
3470d1 |
if (elinkp->portp1->elinkp != elinkp) {
|
|
Packit Service |
3470d1 |
// duplicate port, or incomplete/duplicate link in input topology
|
|
Packit Service |
3470d1 |
ret = LINK_VERIFY_DUP;
|
|
Packit Service |
3470d1 |
if (side == 0 || side == 1)
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Duplicate Port in input or incorrectly cabled");
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (elinkp->portp2->elinkp != elinkp) {
|
|
Packit Service |
3470d1 |
// duplicate port, or incomplete/duplicate link in input topology
|
|
Packit Service |
3470d1 |
ret = LINK_VERIFY_DUP;
|
|
Packit Service |
3470d1 |
if (side == 0 || side == 2)
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Duplicate Port in input or incorrectly cabled");
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (ret == LINK_VERIFY_DUP && side == 3) {
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Duplicate Port in input or incorrectly cabled");
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
} else { /* elinkp->portp1 || elinkp->portp2 */
|
|
Packit Service |
3470d1 |
// only 1 side resolved -> incorrectly cabled
|
|
Packit Service |
3470d1 |
ret = LINK_VERIFY_CONN;
|
|
Packit Service |
3470d1 |
if (detail >= 0 && (side == 0 || side == 3)) {
|
|
Packit Service |
3470d1 |
if (elinkp->portp1) {
|
|
Packit Service |
3470d1 |
if (elinkp->portp1->neighbor) {
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Incorrect Link, 2nd port found to be:");
|
|
Packit Service |
3470d1 |
ShowLinkPortBriefSummary(elinkp->portp1->neighbor, " ",
|
|
Packit Service |
3470d1 |
0, NULL, format, indent, 0);
|
|
Packit Service |
3470d1 |
} else {
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Incorrect Link, 2nd port not found");
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
} else /* elinkp->portp2 */ {
|
|
Packit Service |
3470d1 |
if (elinkp->portp2->neighbor) {
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Incorrect Link, 1st port found to be:");
|
|
Packit Service |
3470d1 |
ShowLinkPortBriefSummary(elinkp->portp2->neighbor, " ",
|
|
Packit Service |
3470d1 |
0, NULL, format, indent, 0);
|
|
Packit Service |
3470d1 |
} else {
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Incorrect Link, 1st port not found");
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
return ret;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
void ShowLinkPortVerifySummaryCallback(uint64 context, PortData *portp,
|
|
Packit Service |
3470d1 |
Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
if (portp->elinkp && portp->neighbor->elinkp) {
|
|
Packit Service |
3470d1 |
(void)PortVerify(portp, format, indent, detail);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// show fabric link verify errors from portp to its neighbor
|
|
Packit Service |
3470d1 |
void ShowLinkVerifySummary(PortData *portp, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
ShowLinkFromBriefSummary(portp, 0, ShowLinkPortVerifySummaryCallback, format, indent, detail);
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
ShowLinkToBriefSummary(portp->neighbor, "<-> ", FALSE, 0, ShowLinkPortVerifySummaryCallback, format, indent, detail);
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
if (format == FORMAT_XML)
|
|
Packit Service |
3470d1 |
indent +=4;
|
|
Packit Service |
3470d1 |
if (portp->elinkp && portp->neighbor->elinkp
|
|
Packit Service |
3470d1 |
&& (! PortVerify(portp, format, indent, -1)
|
|
Packit Service |
3470d1 |
|| ! PortVerify(portp->neighbor, format, indent, -1)))
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Port Attributes Inconsistent");
|
|
Packit Service |
3470d1 |
if (portp->elinkp && portp->neighbor->elinkp) {
|
|
Packit Service |
3470d1 |
(void)LinkAttrVerify(portp->elinkp, portp, format, indent, detail);
|
|
Packit Service |
3470d1 |
} else if (! portp->elinkp && ! portp->neighbor->elinkp) {
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Unexpected Link");
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (format == FORMAT_XML)
|
|
Packit Service |
3470d1 |
printf("%*s</Link>\n", indent-4, "");
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// header used before a series of links
|
|
Packit Service |
3470d1 |
void ShowExpectedLinkBriefSummaryHeader(Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("%*sRate MTU NodeGUID Port or PortGUID Type Name\n", indent, "");
|
|
Packit Service |
3470d1 |
if (detail && (g_Fabric.flags & FF_CABLEDATA)) {
|
|
Packit Service |
3470d1 |
//printf("%*sPortDetails\n", indent+4, "");
|
|
Packit Service |
3470d1 |
//printf("%*sLinkDetails\n", indent+4, "");
|
|
Packit Service |
3470d1 |
printf("%*sCable: %-*s %-*s\n", indent+4, "",
|
|
Packit Service |
3470d1 |
CABLE_LABEL_STRLEN, "CableLabel",
|
|
Packit Service |
3470d1 |
CABLE_LENGTH_STRLEN, "CableLen");
|
|
Packit Service |
3470d1 |
printf("%*s%s\n", indent+4, "", "CableDetails");
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
void ShowExpectedLinkPortVerifySummaryCallback(ExpectedLink *elinkp, uint8 side,
|
|
Packit Service |
3470d1 |
Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
(void)ExpectedLinkVerify(elinkp, side, format, indent, detail);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// show input link verify errors
|
|
Packit Service |
3470d1 |
void ShowExpectedLinkVerifySummary(ExpectedLink *elinkp, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
// top level information about link
|
|
Packit Service |
3470d1 |
if (format == FORMAT_XML) {
|
|
Packit Service |
3470d1 |
printf("%*s<Link id=\"0x%016"PRIx64"\">\n", indent, "", (uint64)(uintn)elinkp);
|
|
Packit Service |
3470d1 |
indent+=4;
|
|
Packit Service |
3470d1 |
if (elinkp->expected_rate)
|
|
Packit Service |
3470d1 |
XmlPrintRate(elinkp->expected_rate, indent);
|
|
Packit Service |
3470d1 |
if (elinkp->expected_mtu)
|
|
Packit Service |
3470d1 |
XmlPrintDec("MTU",
|
|
Packit Service |
3470d1 |
GetBytesFromMtu(elinkp->expected_mtu), indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("Internal", elinkp->internal, indent);
|
|
Packit Service |
3470d1 |
if (detail)
|
|
Packit Service |
3470d1 |
ShowExpectedLinkBriefSummary(elinkp, format, indent+4, detail-1);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// From Side (Port 1)
|
|
Packit Service |
3470d1 |
ShowExpectedLinkPortSelBriefSummary("", elinkp, elinkp->portselp1,
|
|
Packit Service |
3470d1 |
1, ShowExpectedLinkPortVerifySummaryCallback,
|
|
Packit Service |
3470d1 |
format, indent, detail);
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// To Side (Port 2)
|
|
Packit Service |
3470d1 |
ShowExpectedLinkPortSelBriefSummary("", elinkp, elinkp->portselp2,
|
|
Packit Service |
3470d1 |
2, ShowExpectedLinkPortVerifySummaryCallback,
|
|
Packit Service |
3470d1 |
format, indent, detail);
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// Summary information about Link itself
|
|
Packit Service |
3470d1 |
if (detail && format != FORMAT_XML)
|
|
Packit Service |
3470d1 |
ShowExpectedLinkBriefSummary(elinkp, format, indent+4, detail-1);
|
|
Packit Service |
3470d1 |
(void)ExpectedLinkVerify(elinkp, 3, format, indent, detail);
|
|
Packit Service |
3470d1 |
if (format == FORMAT_XML)
|
|
Packit Service |
3470d1 |
printf("%*s</Link>\n", indent-4, "");
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// Verify links in fabric against specified topology
|
|
Packit Service |
3470d1 |
void ShowVerifyLinksReport(Point *focus, report_t report, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
LIST_ITEM *p;
|
|
Packit Service |
3470d1 |
uint32 counts[LINK_VERIFY_MAX+1] = {0};
|
|
Packit Service |
3470d1 |
uint32 port_errors = 0;
|
|
Packit Service |
3470d1 |
uint32 link_errors = 0;
|
|
Packit Service |
3470d1 |
uint32 fabric_checked = 0;
|
|
Packit Service |
3470d1 |
uint32 input_checked = 0;
|
|
Packit Service |
3470d1 |
char *xml_prefix = "";
|
|
Packit Service |
3470d1 |
char *prefix = "";
|
|
Packit Service |
3470d1 |
char *report_name = "";
|
|
Packit Service |
3470d1 |
LinkVerifyResult_t res;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
switch (report) {
|
|
Packit Service |
3470d1 |
default: // should not happen, but just in case
|
|
Packit Service |
3470d1 |
ASSERT(0);
|
|
Packit Service |
3470d1 |
case REPORT_VERIFYLINKS:
|
|
Packit Service |
3470d1 |
report_name = "verifylinks";
|
|
Packit Service |
3470d1 |
xml_prefix = "";
|
|
Packit Service |
3470d1 |
prefix = "";
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case REPORT_VERIFYEXTLINKS:
|
|
Packit Service |
3470d1 |
report_name = "verifyextlinks";
|
|
Packit Service |
3470d1 |
xml_prefix = "Ext";
|
|
Packit Service |
3470d1 |
prefix = "External ";
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case REPORT_VERIFYFILINKS:
|
|
Packit Service |
3470d1 |
report_name = "verifyfilinks";
|
|
Packit Service |
3470d1 |
xml_prefix = "FI";
|
|
Packit Service |
3470d1 |
prefix = "FI ";
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case REPORT_VERIFYISLINKS:
|
|
Packit Service |
3470d1 |
report_name = "verifyislinks";
|
|
Packit Service |
3470d1 |
xml_prefix = "IS";
|
|
Packit Service |
3470d1 |
prefix = "Inter-Switch ";
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case REPORT_VERIFYEXTISLINKS:
|
|
Packit Service |
3470d1 |
report_name = "verifyextislinks";
|
|
Packit Service |
3470d1 |
xml_prefix = "ExtIS";
|
|
Packit Service |
3470d1 |
prefix = "External Inter-Switch ";
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
// intro for report
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("%*s%sLinks Topology Verification\n", indent, "", prefix);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
printf("%*s<Verify%sLinks> \n", indent, "", xml_prefix, prefix);
|
|
Packit Service |
3470d1 |
indent+=4;
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (! g_topology_in_file) {
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("%*sReport skipped: -T option not specified\n", indent, "");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
printf("%*s\n", indent, "");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
goto done;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (! (g_Fabric.flags & (FF_EXPECTED_LINKS|FF_EXPECTED_EXTLINKS))) {
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("%*sReport skipped: no LinkSummary nor ExternalLinkSummary information provided\n", indent, "");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
printf("%*s\n", indent, "");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
goto done;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (0 == (report & (REPORT_VERIFYEXTLINKS|REPORT_VERIFYEXTISLINKS))
|
|
Packit Service |
3470d1 |
&& ((g_Fabric.flags & (FF_EXPECTED_LINKS|FF_EXPECTED_EXTLINKS)) == FF_EXPECTED_EXTLINKS)) {
|
|
Packit Service |
3470d1 |
fprintf(stderr, "opareport: Warning: %s requested, but only ExternalLinkSummary information provided\n", report_name);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
ShowPointFocus(focus, (FIND_FLAG_FABRIC|FIND_FLAG_ELINK), format, indent, detail);
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// First we look at all the fabric links
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("%*s%sLinks Found with incorrect configuration:\n", indent, "", prefix);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
printf("%*s\n", indent, "", prefix);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
for (p=QListHead(&g_Fabric.AllPorts); p != NULL; p = QListNext(&g_Fabric.AllPorts, p)) {
|
|
Packit Service |
3470d1 |
PortData *portp1, *portp2;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
portp1 = (PortData *)QListObj(p);
|
|
Packit Service |
3470d1 |
// to avoid duplicated processing, only process "from" ports in link
|
|
Packit Service |
3470d1 |
if (! portp1->from)
|
|
Packit Service |
3470d1 |
continue;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
switch (report) {
|
|
Packit Service |
3470d1 |
default: // should not happen, but just in case
|
|
Packit Service |
3470d1 |
case REPORT_VERIFYLINKS:
|
|
Packit Service |
3470d1 |
// process all links
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case REPORT_VERIFYEXTLINKS:
|
|
Packit Service |
3470d1 |
if (isInternalLink(portp1))
|
|
Packit Service |
3470d1 |
continue;
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case REPORT_VERIFYFILINKS:
|
|
Packit Service |
3470d1 |
if (! isFILink(portp1))
|
|
Packit Service |
3470d1 |
continue;
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case REPORT_VERIFYISLINKS:
|
|
Packit Service |
3470d1 |
if (! isISLink(portp1))
|
|
Packit Service |
3470d1 |
continue;
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case REPORT_VERIFYEXTISLINKS:
|
|
Packit Service |
3470d1 |
if (isInternalLink(portp1))
|
|
Packit Service |
3470d1 |
continue;
|
|
Packit Service |
3470d1 |
if (! isISLink(portp1))
|
|
Packit Service |
3470d1 |
continue;
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
portp2 = portp1->neighbor;
|
|
Packit Service |
3470d1 |
// We process only links whose PortData or resolved ExpectedLink
|
|
Packit Service |
3470d1 |
// match the focus
|
|
Packit Service |
3470d1 |
if (! ( ComparePortPoint(portp1, focus)
|
|
Packit Service |
3470d1 |
|| ComparePortPoint(portp2, focus)
|
|
Packit Service |
3470d1 |
|| (portp1->elinkp && CompareExpectedLinkPoint(portp1->elinkp, focus))
|
|
Packit Service |
3470d1 |
|| (portp2->elinkp && CompareExpectedLinkPoint(portp2->elinkp, focus))))
|
|
Packit Service |
3470d1 |
continue;
|
|
Packit Service |
3470d1 |
fabric_checked++;
|
|
Packit Service |
3470d1 |
// detail=-1 in LinkFabricVerify will suppress its output
|
|
Packit Service |
3470d1 |
res = LinkFabricVerify(portp1, format, indent, -1);
|
|
Packit Service |
3470d1 |
counts[res]++;
|
|
Packit Service |
3470d1 |
if (res != LINK_VERIFY_OK) {
|
|
Packit Service |
3470d1 |
if (detail) {
|
|
Packit Service |
3470d1 |
if (port_errors) {
|
|
Packit Service |
3470d1 |
if (format == FORMAT_TEXT) {
|
|
Packit Service |
3470d1 |
printf("\n"); // blank line between links
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
} else {
|
|
Packit Service |
3470d1 |
ShowLinkBriefSummaryHeader(format, indent, detail-1);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
ShowLinkVerifySummary(portp1, format, indent, detail-1);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
port_errors++;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
if (detail && port_errors)
|
|
Packit Service |
3470d1 |
printf("\n"); // blank line between links
|
|
Packit Service |
3470d1 |
printf("%*s%u of %u Fabric Links Checked\n", indent, "",
|
|
Packit Service |
3470d1 |
fabric_checked, g_Fabric.LinkCount);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
XmlPrintDec("FabricLinksChecked", fabric_checked, indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("TotalFabricLinks", g_Fabric.LinkCount, indent);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// now look at all the expected Links from the input topology
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("\n%*s%sLinks Expected but Missing, Duplicate in input or Incorrect:\n", indent, "", prefix);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
printf("%*s\n", indent, "", prefix);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
for (p=QListHead(&g_Fabric.ExpectedLinks); p != NULL; p = QListNext(&g_Fabric.ExpectedLinks, p)) {
|
|
Packit Service |
3470d1 |
ExpectedLink *elinkp = (ExpectedLink *)QListObj(p);
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// do our best to filter expected links
|
|
Packit Service |
3470d1 |
// the is*ExpectedLink functions are purposely generously inclusive
|
|
Packit Service |
3470d1 |
switch (report) {
|
|
Packit Service |
3470d1 |
default: // should not happen, but just in case
|
|
Packit Service |
3470d1 |
case REPORT_VERIFYLINKS:
|
|
Packit Service |
3470d1 |
// process all links
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case REPORT_VERIFYEXTLINKS:
|
|
Packit Service |
3470d1 |
if (! isExternalExpectedLink(elinkp))
|
|
Packit Service |
3470d1 |
continue;
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case REPORT_VERIFYFILINKS:
|
|
Packit Service |
3470d1 |
if (! isFIExpectedLink(elinkp))
|
|
Packit Service |
3470d1 |
continue;
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case REPORT_VERIFYISLINKS:
|
|
Packit Service |
3470d1 |
if (! isISExpectedLink(elinkp))
|
|
Packit Service |
3470d1 |
continue;
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case REPORT_VERIFYEXTISLINKS:
|
|
Packit Service |
3470d1 |
if (! isExternalExpectedLink(elinkp))
|
|
Packit Service |
3470d1 |
continue;
|
|
Packit Service |
3470d1 |
if (! isISExpectedLink(elinkp))
|
|
Packit Service |
3470d1 |
continue;
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// We process only elinks whose resolved ports or ExpectedLink
|
|
Packit Service |
3470d1 |
// match the focus
|
|
Packit Service |
3470d1 |
if (! ( (elinkp->portp1 && ComparePortPoint(elinkp->portp1, focus))
|
|
Packit Service |
3470d1 |
|| (elinkp->portp2 && ComparePortPoint(elinkp->portp2, focus))
|
|
Packit Service |
3470d1 |
|| CompareExpectedLinkPoint(elinkp, focus)))
|
|
Packit Service |
3470d1 |
continue;
|
|
Packit Service |
3470d1 |
input_checked++;
|
|
Packit Service |
3470d1 |
// detail=-1 in ExpectedLinkVerify will suppress its output
|
|
Packit Service |
3470d1 |
res = ExpectedLinkVerify(elinkp, 0, format, indent, -1);
|
|
Packit Service |
3470d1 |
counts[res]++;
|
|
Packit Service |
3470d1 |
if (res != LINK_VERIFY_OK) {
|
|
Packit Service |
3470d1 |
if (detail) {
|
|
Packit Service |
3470d1 |
if (link_errors) {
|
|
Packit Service |
3470d1 |
if (format == FORMAT_TEXT) {
|
|
Packit Service |
3470d1 |
printf("\n"); // blank line between links
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
} else {
|
|
Packit Service |
3470d1 |
ShowExpectedLinkBriefSummaryHeader(format, indent, detail-1);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
ShowExpectedLinkVerifySummary(elinkp, format, indent, detail-1);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
link_errors++;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
if (detail && link_errors)
|
|
Packit Service |
3470d1 |
printf("\n"); // blank line between links
|
|
Packit Service |
3470d1 |
printf("%*s%u of %u Input Links Checked\n", indent, "",
|
|
Packit Service |
3470d1 |
input_checked, QListCount(&g_Fabric.ExpectedLinks));
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
XmlPrintDec("InputLinksChecked", input_checked, indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("TotalInputLinks", QListCount(&g_Fabric.ExpectedLinks), indent);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// final summary information
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("\n%*sTotal of %u Incorrect Links found\n", indent, "", port_errors+link_errors);
|
|
Packit Service |
3470d1 |
printf("%*s%u Missing, %u Unexpected, %u Misconnected, %u Duplicate, %u Different\n", indent, "",
|
|
Packit Service |
3470d1 |
counts[LINK_VERIFY_MISSING], counts[LINK_VERIFY_UNEXPECTED],
|
|
Packit Service |
3470d1 |
counts[LINK_VERIFY_CONN], counts[LINK_VERIFY_DUP],
|
|
Packit Service |
3470d1 |
counts[LINK_VERIFY_DIFF]);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
XmlPrintDec("TotalLinksIncorrect", port_errors+link_errors, indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("Missing", counts[LINK_VERIFY_MISSING], indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("Unexpected", counts[LINK_VERIFY_UNEXPECTED], indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("Misconnected", counts[LINK_VERIFY_CONN], indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("Duplicate", counts[LINK_VERIFY_DUP], indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("Different", counts[LINK_VERIFY_DIFF], indent);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
done:
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
DisplaySeparator();
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
indent-=4;
|
|
Packit Service |
3470d1 |
printf("%*s</Verify%sLinks>\n", indent, "", xml_prefix);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// verify a node against its corresponding ExpectedNode
|
|
Packit Service |
3470d1 |
// Only valid to be called for SMs with ExpectedNode
|
|
Packit Service |
3470d1 |
// returns FALSE if any discrepencies
|
|
Packit Service |
3470d1 |
// only does output if detail >= 0
|
|
Packit Service |
3470d1 |
boolean NodeVerify(NodeData *nodep, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
ExpectedNode *enodep = nodep->enodep;
|
|
Packit Service |
3470d1 |
boolean ret=TRUE;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
ASSERT(enodep);
|
|
Packit Service |
3470d1 |
if (enodep->NodeGUID && enodep->NodeGUID != nodep->NodeInfo.NodeGUID) {
|
|
Packit Service |
3470d1 |
ret = FALSE;
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail,
|
|
Packit Service |
3470d1 |
"NodeGuid mismatch: expected: 0x%016"PRIx64" found: 0x%016"PRIx64,
|
|
Packit Service |
3470d1 |
enodep->NodeGUID, nodep->NodeInfo.NodeGUID);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (enodep->NodeDesc
|
|
Packit Service |
3470d1 |
&& 0 != strncmp(enodep->NodeDesc,
|
|
Packit Service |
3470d1 |
(char*)nodep->NodeDesc.NodeString,
|
|
Packit Service |
3470d1 |
NODE_DESCRIPTION_ARRAY_SIZE)) {
|
|
Packit Service |
3470d1 |
ret = FALSE;
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail,
|
|
Packit Service |
3470d1 |
"NodeDesc mismatch: expected: '%s' found: '%.*s'",
|
|
Packit Service |
3470d1 |
enodep->NodeDesc, NODE_DESCRIPTION_ARRAY_SIZE,
|
|
Packit Service |
3470d1 |
(char*)nodep->NodeDesc.NodeString);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (enodep->NodeType && enodep->NodeType != nodep->NodeInfo.NodeType) {
|
|
Packit Service |
3470d1 |
ret = FALSE;
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail,
|
|
Packit Service |
3470d1 |
"NodeType mismatch: expected: %s found: %s",
|
|
Packit Service |
3470d1 |
StlNodeTypeToText(enodep->NodeType),
|
|
Packit Service |
3470d1 |
StlNodeTypeToText(nodep->NodeInfo.NodeType));
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
return ret;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
typedef enum {
|
|
Packit Service |
3470d1 |
NODE_VERIFY_OK = 0, // node matches input topology
|
|
Packit Service |
3470d1 |
NODE_VERIFY_DIFF = 1, // node fully resolved but diff from input topology
|
|
Packit Service |
3470d1 |
NODE_VERIFY_UNEXPECTED = 2, // node not found in input topology
|
|
Packit Service |
3470d1 |
NODE_VERIFY_MISSING = 3, // node not found in fabric, but in input topology
|
|
Packit Service |
3470d1 |
NODE_VERIFY_DUP = 4, // possible duplicate in input topology
|
|
Packit Service |
3470d1 |
NODE_VERIFY_MAX=4 // maximum value of the above
|
|
Packit Service |
3470d1 |
} NodeVerifyResult_t;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// check both fabric node against input topology
|
|
Packit Service |
3470d1 |
// only does output if detail >= 0
|
|
Packit Service |
3470d1 |
NodeVerifyResult_t NodeFabricVerify(NodeData *nodep, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
NodeVerifyResult_t ret = NODE_VERIFY_OK;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// all checks which are based off of found node in fabric
|
|
Packit Service |
3470d1 |
if (nodep->enodep) {
|
|
Packit Service |
3470d1 |
if (! NodeVerify(nodep, format, indent, detail))
|
|
Packit Service |
3470d1 |
ret = NODE_VERIFY_DIFF;
|
|
Packit Service |
3470d1 |
} else {
|
|
Packit Service |
3470d1 |
ret = NODE_VERIFY_UNEXPECTED; // extra node
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Unexpected %s",
|
|
Packit Service |
3470d1 |
StlNodeTypeToText(nodep->NodeInfo.NodeType));
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
return ret;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// compare ExpectedNode against fabric
|
|
Packit Service |
3470d1 |
// NodeFabricVerify will have caught nodes which are different or extra
|
|
Packit Service |
3470d1 |
// this is focused on duplicate ExpectedNodes or missing nodes
|
|
Packit Service |
3470d1 |
// only does output if detail >= 0
|
|
Packit Service |
3470d1 |
NodeVerifyResult_t ExpectedNodeVerify(ExpectedNode *enodep, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
NodeVerifyResult_t ret = NODE_VERIFY_OK;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
if (! enodep->nodep) {
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Missing %s",
|
|
Packit Service |
3470d1 |
StlNodeTypeToText(enodep->NodeType));
|
|
Packit Service |
3470d1 |
ret = NODE_VERIFY_MISSING; // missing link
|
|
Packit Service |
3470d1 |
} else {
|
|
Packit Service |
3470d1 |
if (enodep->nodep->enodep != enodep) {
|
|
Packit Service |
3470d1 |
// duplicate node in input topology
|
|
Packit Service |
3470d1 |
ret = NODE_VERIFY_DUP;
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Duplicate %s in input",
|
|
Packit Service |
3470d1 |
StlNodeTypeToText(enodep->NodeType));
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
return ret;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// show fabric node verify errors
|
|
Packit Service |
3470d1 |
void ShowNodeVerifySummary(NodeData *nodep, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
ShowNodeBriefSummary(nodep, NULL, FALSE, format, indent, 0);
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
if (format == FORMAT_XML)
|
|
Packit Service |
3470d1 |
indent +=4;
|
|
Packit Service |
3470d1 |
if (nodep->enodep && ! NodeVerify(nodep, format, indent, detail-1)) {
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Node Attributes Inconsistent");
|
|
Packit Service |
3470d1 |
} else {
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Unexpected %s",
|
|
Packit Service |
3470d1 |
StlNodeTypeToText(nodep->NodeInfo.NodeType));
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (format == FORMAT_XML)
|
|
Packit Service |
3470d1 |
printf("%*s</Node>\n", indent-4, "");
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// show input node verify errors
|
|
Packit Service |
3470d1 |
void ShowExpectedNodeVerifySummary(ExpectedNode *enodep, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
ShowExpectedNodeBriefSummary("", enodep, "Node", FALSE, format, indent, detail-1);
|
|
Packit Service |
3470d1 |
if (format == FORMAT_XML)
|
|
Packit Service |
3470d1 |
indent+=4;
|
|
Packit Service |
3470d1 |
(void)ExpectedNodeVerify(enodep, format, indent, detail);
|
|
Packit Service |
3470d1 |
if (format == FORMAT_XML)
|
|
Packit Service |
3470d1 |
printf("%*s</Node>\n", indent-4, "");
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// Verify nodes in fabric against specified topology
|
|
Packit Service |
3470d1 |
void ShowVerifyNodesReport(Point *focus, uint8 NodeType, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
LIST_ITEM *p;
|
|
Packit Service |
3470d1 |
uint32 counts[NODE_VERIFY_MAX+1] = {0};
|
|
Packit Service |
3470d1 |
uint32 fabric_errors = 0;
|
|
Packit Service |
3470d1 |
uint32 input_errors = 0;
|
|
Packit Service |
3470d1 |
uint32 fabric_checked = 0;
|
|
Packit Service |
3470d1 |
uint32 input_checked = 0;
|
|
Packit Service |
3470d1 |
NodeVerifyResult_t res;
|
|
Packit Service |
3470d1 |
const char *NodeTypeText = StlNodeTypeToText(NodeType);
|
|
Packit Service |
3470d1 |
QUICK_LIST *fabric_listp;
|
|
Packit Service |
3470d1 |
QUICK_LIST *input_listp;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
switch (NodeType) {
|
|
Packit Service |
3470d1 |
case STL_NODE_FI:
|
|
Packit Service |
3470d1 |
fabric_listp = &g_Fabric.AllFIs;
|
|
Packit Service |
3470d1 |
input_listp = &g_Fabric.ExpectedFIs;
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case STL_NODE_SW:
|
|
Packit Service |
3470d1 |
fabric_listp = &g_Fabric.AllSWs;
|
|
Packit Service |
3470d1 |
input_listp = &g_Fabric.ExpectedSWs;
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
ASSERT(0);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// intro for report
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("%*s%ss Topology Verification\n", indent, "", NodeTypeText);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
printf("%*s<Verify%ss> \n", indent, "", NodeTypeText, NodeTypeText);
|
|
Packit Service |
3470d1 |
indent+=4;
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (! g_topology_in_file) {
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("%*sReport skipped: -T option not specified\n", indent, "");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
printf("%*s\n", indent, "");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
goto done;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (! (g_Fabric.flags & FF_EXPECTED_NODES)) {
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("%*sReport skipped: no Nodes information provided\n", indent, "");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
printf("%*s\n", indent, "");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
goto done;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
ShowPointFocus(focus, (FIND_FLAG_FABRIC|FIND_FLAG_ENODE), format, indent, detail);
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// First we look at all the fabric nodes
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("%*s%ss Found with incorrect configuration:\n", indent, "", NodeTypeText);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
printf("%*s\n", indent, "", NodeTypeText);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
for (p=QListHead(fabric_listp); p != NULL; p = QListNext(fabric_listp, p)) {
|
|
Packit Service |
3470d1 |
NodeData *nodep = (NodeData *)QListObj(p);
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// We process only nodes whose NodeData or resolved ExpectedNode
|
|
Packit Service |
3470d1 |
// match the focus
|
|
Packit Service |
3470d1 |
if (! ( CompareNodePoint(nodep, focus)
|
|
Packit Service |
3470d1 |
|| (nodep->enodep && CompareExpectedNodePoint(nodep->enodep, focus))))
|
|
Packit Service |
3470d1 |
continue;
|
|
Packit Service |
3470d1 |
fabric_checked++;
|
|
Packit Service |
3470d1 |
// detail=-1 in NodeFabricVerify will suppress its output
|
|
Packit Service |
3470d1 |
res = NodeFabricVerify(nodep, format, indent, -1);
|
|
Packit Service |
3470d1 |
counts[res]++;
|
|
Packit Service |
3470d1 |
if (res != NODE_VERIFY_OK) {
|
|
Packit Service |
3470d1 |
if (detail) {
|
|
Packit Service |
3470d1 |
if (fabric_errors) {
|
|
Packit Service |
3470d1 |
if (format == FORMAT_TEXT) {
|
|
Packit Service |
3470d1 |
printf("\n"); // blank line between links
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
} else {
|
|
Packit Service |
3470d1 |
// use detail 0 so don't show Port stuff
|
|
Packit Service |
3470d1 |
ShowNodeBriefSummaryHeadings(format, indent, 0 /*detail-1*/);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
ShowNodeVerifySummary(nodep, format, indent, detail-1);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
fabric_errors++;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
if (detail && fabric_errors)
|
|
Packit Service |
3470d1 |
printf("\n"); // blank line between links
|
|
Packit Service |
3470d1 |
printf("%*s%u of %u Fabric %ss Checked\n", indent, "",
|
|
Packit Service |
3470d1 |
fabric_checked, QListCount(fabric_listp), NodeTypeText);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
switch (NodeType) {
|
|
Packit Service |
3470d1 |
case STL_NODE_FI:
|
|
Packit Service |
3470d1 |
XmlPrintDec("FabricFIsChecked", fabric_checked, indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("TotalFabricFIs", QListCount(fabric_listp), indent);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case STL_NODE_SW:
|
|
Packit Service |
3470d1 |
XmlPrintDec("FabricSWsChecked", fabric_checked, indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("TotalFabricSWs", QListCount(fabric_listp), indent);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// now look at all the expected Nodes from the input topology
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("\n%*s%ss Expected but Missing or Duplicate in input:\n", indent, "", NodeTypeText);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
printf("%*s\n", indent, "", NodeTypeText);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
for (p=QListHead(input_listp); p != NULL; p = QListNext(input_listp, p)) {
|
|
Packit Service |
3470d1 |
ExpectedNode *enodep = (ExpectedNode *)QListObj(p);
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// We process only enodes whose resolved node or ExpectedNode
|
|
Packit Service |
3470d1 |
// match the focus
|
|
Packit Service |
3470d1 |
if (! ( (enodep->nodep && CompareNodePoint(enodep->nodep, focus))
|
|
Packit Service |
3470d1 |
|| CompareExpectedNodePoint(enodep, focus)))
|
|
Packit Service |
3470d1 |
continue;
|
|
Packit Service |
3470d1 |
input_checked++;
|
|
Packit Service |
3470d1 |
// detail=-1 in ExpectedNodeVerify will suppress its output
|
|
Packit Service |
3470d1 |
res = ExpectedNodeVerify(enodep, format, indent, -1);
|
|
Packit Service |
3470d1 |
counts[res]++;
|
|
Packit Service |
3470d1 |
if (res != NODE_VERIFY_OK) {
|
|
Packit Service |
3470d1 |
if (detail) {
|
|
Packit Service |
3470d1 |
if (input_errors) {
|
|
Packit Service |
3470d1 |
if (format == FORMAT_TEXT) {
|
|
Packit Service |
3470d1 |
printf("\n"); // blank line between links
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
} else {
|
|
Packit Service |
3470d1 |
// use detail 0 so don't show Port stuff
|
|
Packit Service |
3470d1 |
ShowNodeBriefSummaryHeadings(format, indent, 0 /*detail-1*/);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
ShowExpectedNodeVerifySummary(enodep, format, indent, detail-1);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
input_errors++;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
if (detail && input_errors)
|
|
Packit Service |
3470d1 |
printf("\n"); // blank line between links
|
|
Packit Service |
3470d1 |
printf("%*s%u of %u Input %ss Checked\n", indent, "",
|
|
Packit Service |
3470d1 |
input_checked, QListCount(input_listp), NodeTypeText);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
switch (NodeType) {
|
|
Packit Service |
3470d1 |
case STL_NODE_FI:
|
|
Packit Service |
3470d1 |
XmlPrintDec("InputFIsChecked", input_checked, indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("TotalInputFIs", QListCount(input_listp), indent);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case STL_NODE_SW:
|
|
Packit Service |
3470d1 |
XmlPrintDec("InputSWsChecked", input_checked, indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("TotalInputSWs", QListCount(input_listp), indent);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// final summary information
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("\n%*sTotal of %u Incorrect %ss found\n", indent, "", fabric_errors+input_errors, NodeTypeText);
|
|
Packit Service |
3470d1 |
printf("%*s%u Missing, %u Unexpected, %u Duplicate, %u Different\n", indent, "",
|
|
Packit Service |
3470d1 |
counts[NODE_VERIFY_MISSING], counts[NODE_VERIFY_UNEXPECTED],
|
|
Packit Service |
3470d1 |
counts[NODE_VERIFY_DUP],
|
|
Packit Service |
3470d1 |
counts[NODE_VERIFY_DIFF]);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
switch (NodeType) {
|
|
Packit Service |
3470d1 |
case STL_NODE_FI:
|
|
Packit Service |
3470d1 |
XmlPrintDec("TotalFIsIncorrect", fabric_errors+input_errors, indent);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case STL_NODE_SW:
|
|
Packit Service |
3470d1 |
XmlPrintDec("TotalSWsIncorrect", fabric_errors+input_errors, indent);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
XmlPrintDec("Missing", counts[NODE_VERIFY_MISSING], indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("Unexpected", counts[NODE_VERIFY_UNEXPECTED], indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("Duplicate", counts[NODE_VERIFY_DUP], indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("Different", counts[NODE_VERIFY_DIFF], indent);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
done:
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
DisplaySeparator();
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
indent-=4;
|
|
Packit Service |
3470d1 |
printf("%*s</Verify%ss>\n", indent, "", NodeTypeText);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// verify a SM against its corresponding ExpectedSM
|
|
Packit Service |
3470d1 |
// Only valid to be called for nodes with ExpectedSM
|
|
Packit Service |
3470d1 |
// returns FALSE if any discrepencies
|
|
Packit Service |
3470d1 |
// only does output if detail >= 0
|
|
Packit Service |
3470d1 |
boolean SMVerify(SMData *smp, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
ExpectedSM *esmp = smp->esmp;
|
|
Packit Service |
3470d1 |
boolean ret=TRUE;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
ASSERT(esmp);
|
|
Packit Service |
3470d1 |
if (esmp->NodeGUID && esmp->NodeGUID != smp->portp->nodep->NodeInfo.NodeGUID) {
|
|
Packit Service |
3470d1 |
ret = FALSE;
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail,
|
|
Packit Service |
3470d1 |
"NodeGuid mismatch: expected: 0x%016"PRIx64" found: 0x%016"PRIx64,
|
|
Packit Service |
3470d1 |
esmp->NodeGUID, smp->portp->nodep->NodeInfo.NodeGUID);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (esmp->NodeDesc
|
|
Packit Service |
3470d1 |
&& 0 != strncmp(esmp->NodeDesc,
|
|
Packit Service |
3470d1 |
(char*)smp->portp->nodep->NodeDesc.NodeString,
|
|
Packit Service |
3470d1 |
NODE_DESCRIPTION_ARRAY_SIZE)) {
|
|
Packit Service |
3470d1 |
ret = FALSE;
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail,
|
|
Packit Service |
3470d1 |
"NodeDesc mismatch: expected: '%s' found: '%.*s'",
|
|
Packit Service |
3470d1 |
esmp->NodeDesc, NODE_DESCRIPTION_ARRAY_SIZE,
|
|
Packit Service |
3470d1 |
(char*)smp->portp->nodep->NodeDesc.NodeString);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (esmp->gotPortNum && esmp->PortNum != smp->portp->PortNum) {
|
|
Packit Service |
3470d1 |
ret = FALSE;
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail,
|
|
Packit Service |
3470d1 |
"PortNum mismatch: expected: %3u found: %3u",
|
|
Packit Service |
3470d1 |
esmp->PortNum, smp->portp->PortNum);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (esmp->PortGUID && esmp->PortGUID != smp->portp->PortGUID) {
|
|
Packit Service |
3470d1 |
ret = FALSE;
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail,
|
|
Packit Service |
3470d1 |
"PortGuid mismatch: expected: 0x%016"PRIx64" found: 0x%016"PRIx64,
|
|
Packit Service |
3470d1 |
esmp->PortGUID, smp->portp->PortGUID);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (esmp->NodeType && esmp->NodeType != smp->portp->nodep->NodeInfo.NodeType) {
|
|
Packit Service |
3470d1 |
ret = FALSE;
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail,
|
|
Packit Service |
3470d1 |
"NodeType mismatch: expected: %s found: %s",
|
|
Packit Service |
3470d1 |
StlNodeTypeToText(esmp->NodeType),
|
|
Packit Service |
3470d1 |
StlNodeTypeToText(smp->portp->nodep->NodeInfo.NodeType));
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
return ret;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
typedef enum {
|
|
Packit Service |
3470d1 |
SM_VERIFY_OK = 0, // SM matches input topology
|
|
Packit Service |
3470d1 |
SM_VERIFY_DIFF = 1, // SM fully resolved but diff from input topology
|
|
Packit Service |
3470d1 |
SM_VERIFY_UNEXPECTED = 2, // SM not found in input topology
|
|
Packit Service |
3470d1 |
SM_VERIFY_MISSING = 3, // SM not found in fabric, but in input topology
|
|
Packit Service |
3470d1 |
SM_VERIFY_DUP = 4, // possible duplicate in input topology
|
|
Packit Service |
3470d1 |
SM_VERIFY_MAX=4 // maximum value of the above
|
|
Packit Service |
3470d1 |
} SMVerifyResult_t;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// check both fabric node against input topology
|
|
Packit Service |
3470d1 |
// only does output if detail >= 0
|
|
Packit Service |
3470d1 |
SMVerifyResult_t SMFabricVerify(SMData *smp, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
SMVerifyResult_t ret = SM_VERIFY_OK;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// all checks which are based off of found SM in fabric
|
|
Packit Service |
3470d1 |
if (smp->esmp) {
|
|
Packit Service |
3470d1 |
if (! SMVerify(smp, format, indent, detail))
|
|
Packit Service |
3470d1 |
ret = SM_VERIFY_DIFF;
|
|
Packit Service |
3470d1 |
} else {
|
|
Packit Service |
3470d1 |
ret = SM_VERIFY_UNEXPECTED; // extra node
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Unexpected SM");
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
return ret;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// compare ExpectedSM against fabric
|
|
Packit Service |
3470d1 |
// SMFabricVerify will have caught nodes which are different or extra
|
|
Packit Service |
3470d1 |
// this is focused on duplicate ExpectedSMs or missing SMs
|
|
Packit Service |
3470d1 |
// only does output if detail >= 0
|
|
Packit Service |
3470d1 |
SMVerifyResult_t ExpectedSMVerify(ExpectedSM *esmp, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
SMVerifyResult_t ret = SM_VERIFY_OK;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
if (! esmp->smp) {
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Missing SM");
|
|
Packit Service |
3470d1 |
ret = SM_VERIFY_MISSING; // missing link
|
|
Packit Service |
3470d1 |
} else {
|
|
Packit Service |
3470d1 |
if (esmp->smp->esmp != esmp) {
|
|
Packit Service |
3470d1 |
// duplicate node in input topology
|
|
Packit Service |
3470d1 |
ret = SM_VERIFY_DUP;
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Duplicate SM in input");
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
return ret;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// show fabric SM verify errors
|
|
Packit Service |
3470d1 |
void ShowSMVerifySummary(SMData *smp, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
ShowVerifySMBriefSummary(smp, FALSE, format, indent, 0);
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
if (format == FORMAT_XML)
|
|
Packit Service |
3470d1 |
indent +=4;
|
|
Packit Service |
3470d1 |
if (smp->esmp && ! SMVerify(smp, format, indent, detail-1)) {
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "SM Attributes Inconsistent");
|
|
Packit Service |
3470d1 |
} else {
|
|
Packit Service |
3470d1 |
ShowProblem(format, indent, detail, "Unexpected SM");
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (format == FORMAT_XML)
|
|
Packit Service |
3470d1 |
printf("%*s</SM>\n", indent-4, "");
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// show input SM verify errors
|
|
Packit Service |
3470d1 |
void ShowExpectedSMVerifySummary(ExpectedSM *esmp, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
ShowExpectedSMBriefSummary("", esmp, "SM", FALSE, format, indent, detail-1);
|
|
Packit Service |
3470d1 |
if (format == FORMAT_XML)
|
|
Packit Service |
3470d1 |
indent+=4;
|
|
Packit Service |
3470d1 |
(void)ExpectedSMVerify(esmp, format, indent, detail);
|
|
Packit Service |
3470d1 |
if (format == FORMAT_XML)
|
|
Packit Service |
3470d1 |
printf("%*s</SM>\n", indent-4, "");
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// Verify SMs in fabric against specified topology
|
|
Packit Service |
3470d1 |
void ShowVerifySMsReport(Point *focus, Format_t format, int indent, int detail)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
LIST_ITEM *p;
|
|
Packit Service |
3470d1 |
cl_map_item_t *ip;
|
|
Packit Service |
3470d1 |
uint32 counts[SM_VERIFY_MAX+1] = {0};
|
|
Packit Service |
3470d1 |
uint32 fabric_errors = 0;
|
|
Packit Service |
3470d1 |
uint32 input_errors = 0;
|
|
Packit Service |
3470d1 |
uint32 fabric_checked = 0;
|
|
Packit Service |
3470d1 |
uint32 input_checked = 0;
|
|
Packit Service |
3470d1 |
SMVerifyResult_t res;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// intro for report
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("%*sSMs Topology Verification\n", indent, "");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
printf("%*s<VerifySMs> \n", indent, "");
|
|
Packit Service |
3470d1 |
indent+=4;
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (! g_topology_in_file) {
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("%*sReport skipped: -T option not specified\n", indent, "");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
printf("%*s\n", indent, "");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
goto done;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (! (g_Fabric.flags & FF_EXPECTED_NODES)) {
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("%*sReport skipped: no Nodes information provided\n", indent, "");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
printf("%*s\n", indent, "");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
goto done;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
ShowPointFocus(focus, (FIND_FLAG_FABRIC|FIND_FLAG_ESM), format, indent, detail);
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// First we look at all the fabric SMs
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("%*sSMs Found with incorrect configuration:\n", indent, "");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
printf("%*s\n", indent, "");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
for (ip=cl_qmap_head(&g_Fabric.AllSMs); ip != cl_qmap_end(&g_Fabric.AllSMs); ip = cl_qmap_next(ip)) {
|
|
Packit Service |
3470d1 |
SMData *smp = PARENT_STRUCT(ip, SMData, AllSMsEntry);
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// We process only SMs whose SMData or resolved ExpectedSM
|
|
Packit Service |
3470d1 |
// match the focus
|
|
Packit Service |
3470d1 |
if (! ( CompareSmPoint(smp, focus)
|
|
Packit Service |
3470d1 |
|| (smp->esmp && CompareExpectedSMPoint(smp->esmp, focus))))
|
|
Packit Service |
3470d1 |
continue;
|
|
Packit Service |
3470d1 |
fabric_checked++;
|
|
Packit Service |
3470d1 |
// detail=-1 in SMFabricVerify will suppress its output
|
|
Packit Service |
3470d1 |
res = SMFabricVerify(smp, format, indent, -1);
|
|
Packit Service |
3470d1 |
counts[res]++;
|
|
Packit Service |
3470d1 |
if (res != SM_VERIFY_OK) {
|
|
Packit Service |
3470d1 |
if (detail) {
|
|
Packit Service |
3470d1 |
if (fabric_errors) {
|
|
Packit Service |
3470d1 |
if (format == FORMAT_TEXT) {
|
|
Packit Service |
3470d1 |
printf("\n"); // blank line between links
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
} else {
|
|
Packit Service |
3470d1 |
ShowVerifySMBriefSummaryHeadings(format, indent, detail-1);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
ShowSMVerifySummary(smp, format, indent, detail-1);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
fabric_errors++;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
if (detail && fabric_errors)
|
|
Packit Service |
3470d1 |
printf("\n"); // blank line between links
|
|
Packit Service |
3470d1 |
printf("%*s%u of %u Fabric SMs Checked\n", indent, "",
|
|
Packit Service |
3470d1 |
fabric_checked, (unsigned)cl_qmap_count(&g_Fabric.AllSMs));
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
XmlPrintDec("FabricSMsChecked", fabric_checked, indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("TotalFabricSMs", (unsigned)cl_qmap_count(&g_Fabric.AllSMs), indent);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// now look at all the expected Nodes from the input topology
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("\n%*sSMs Expected but Missing or Duplicate in input:\n", indent, "");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
printf("%*s\n", indent, "");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
for (p=QListHead(&g_Fabric.ExpectedSMs); p != NULL; p = QListNext(&g_Fabric.ExpectedSMs, p)) {
|
|
Packit Service |
3470d1 |
ExpectedSM *esmp = (ExpectedSM *)QListObj(p);
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// We process only ExpectedSMs whose resolved SMData or ExpectedSM
|
|
Packit Service |
3470d1 |
// match the focus
|
|
Packit Service |
3470d1 |
if (! ( (esmp->smp && CompareSmPoint(esmp->smp, focus))
|
|
Packit Service |
3470d1 |
|| CompareExpectedSMPoint(esmp, focus)))
|
|
Packit Service |
3470d1 |
continue;
|
|
Packit Service |
3470d1 |
input_checked++;
|
|
Packit Service |
3470d1 |
// detail=-1 in ExpectedSMVerify will suppress its output
|
|
Packit Service |
3470d1 |
res = ExpectedSMVerify(esmp, format, indent, -1);
|
|
Packit Service |
3470d1 |
counts[res]++;
|
|
Packit Service |
3470d1 |
if (res != SM_VERIFY_OK) {
|
|
Packit Service |
3470d1 |
if (detail) {
|
|
Packit Service |
3470d1 |
if (input_errors) {
|
|
Packit Service |
3470d1 |
if (format == FORMAT_TEXT) {
|
|
Packit Service |
3470d1 |
printf("\n"); // blank line between links
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
} else {
|
|
Packit Service |
3470d1 |
ShowVerifySMBriefSummaryHeadings(format, indent, detail-1);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
ShowExpectedSMVerifySummary(esmp, format, indent, detail-1);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
input_errors++;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
if (detail && input_errors)
|
|
Packit Service |
3470d1 |
printf("\n"); // blank line between links
|
|
Packit Service |
3470d1 |
printf("%*s%u of %u Input SMs Checked\n", indent, "",
|
|
Packit Service |
3470d1 |
input_checked, QListCount(&g_Fabric.ExpectedSMs));
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
XmlPrintDec("InputSMsChecked", input_checked, indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("TotalInputSMs", QListCount(&g_Fabric.ExpectedSMs), indent);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// final summary information
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
printf("\n%*sTotal of %u Incorrect SMs found\n", indent, "", fabric_errors+input_errors);
|
|
Packit Service |
3470d1 |
printf("%*s%u Missing, %u Unexpected, %u Duplicate, %u Different\n", indent, "",
|
|
Packit Service |
3470d1 |
counts[SM_VERIFY_MISSING], counts[SM_VERIFY_UNEXPECTED],
|
|
Packit Service |
3470d1 |
counts[SM_VERIFY_DUP],
|
|
Packit Service |
3470d1 |
counts[SM_VERIFY_DIFF]);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
XmlPrintDec("TotalSMsIncorrect", fabric_errors+input_errors, indent);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
XmlPrintDec("Missing", counts[SM_VERIFY_MISSING], indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("Unexpected", counts[SM_VERIFY_UNEXPECTED], indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("Duplicate", counts[SM_VERIFY_DUP], indent);
|
|
Packit Service |
3470d1 |
XmlPrintDec("Different", counts[SM_VERIFY_DIFF], indent);
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
done:
|
|
Packit Service |
3470d1 |
switch (format) {
|
|
Packit Service |
3470d1 |
case FORMAT_TEXT:
|
|
Packit Service |
3470d1 |
DisplaySeparator();
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
case FORMAT_XML:
|
|
Packit Service |
3470d1 |
indent-=4;
|
|
Packit Service |
3470d1 |
printf("%*s</VerifySMs>\n", indent, "");
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
default:
|
|
Packit Service |
3470d1 |
break;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|