#include "slimFC.h" list FCHostList; void showUsage(void) { printf(" Syntax:\n"); printf(" devlist -- slimFC devlist\n"); printf(" showdata -- slimFC showdata \n"); printf(" resetchip -- slimFC resetchip \n"); printf(" loopbacktest -- slimFC loopbacktest \n"); printf(" I or EX (Internal or External)\n"); printf(" 4/8/16/32/AUTO\n"); printf(" clearStatistics -- slimFC clearstatistics \n"); printf(" Examples:\n"); printf(" slimFC devlist\n"); printf(" slimFC showdata H3P0\n"); printf(" slimFC resetchip H3P1\n"); printf(" slimFC loopbacktest H3P0 i auto\n"); return; } void printErrorCode(string strErrorCode) { cout << "[ERROR] " << strErrorCode << endl; return; } string translateStringToUpperCase(string strInput) { string strTemp = ""; for(string::iterator iter=strInput.begin();iter!=strInput.end();iter++) { strTemp += toupper(*iter); } return strTemp; } int executeShellCommandGetResult(string input, string *output, bool checkResult) { input += " 2>/dev/null; printf \"Result: $?\""; *output = ""; int rc = 0; FILE *fptr = NULL; fptr = popen(input.c_str(), "r"); if(fptr == NULL) { printErrorCode("open pipe failed"); rc = -1; return rc; } char tempString[256] = {0}; string strOutputString = ""; while(feof(fptr) == 0) { memset(tempString, 0, sizeof(tempString)); fgets(tempString, 256, fptr); strOutputString += tempString; } size_t found = (strOutputString).find("Result: 0"); if(found == string::npos) { if(checkResult == 1) { printErrorCode("execute shell command error"); rc = -1; } } found = (strOutputString).find("Result: "); strOutputString.erase(found, 12); for(string::iterator iter=strOutputString.begin();iter!=strOutputString.end();iter++) { if((iter==strOutputString.end()-1) && ((*iter=='\n') || (*iter=='\r'))) { break; } if((iter==strOutputString.end()) && ((*iter=='\n') || (*iter=='\r'))) { break; } *output += *iter; } if(pclose(fptr) != 0) { printErrorCode("close pipe failed"); rc = -1; return rc; } return rc; } int initFCHostList(void) { int rc = 0; FCHostList.clear(); stringstream ssTemp; ssTemp.clear(); ssTemp.str(""); string tempInputString = ""; string tempOutputString = ""; string strPCIESlotRootBDF[MAX_PCIE_SLOT_AMOUNT]; for(uint32_t cnt=0; cnt> tempFCHostStruct.portBus; // get Dev ssTemp.clear(); ssTemp.str(""); ssTemp << hex << tempOutputString[3] << tempOutputString[4]; ssTemp >> tempFCHostStruct.portDev; // get Func ssTemp.clear(); ssTemp.str(""); ssTemp << hex << tempOutputString[6]; ssTemp >> tempFCHostStruct.portFunc; // get HostName ssTemp.clear(); ssTemp.str(""); ssTemp << dec << portAmount+1; string strHostName = ""; tempInputString = "ls -lv /sys/class/fc_host 2>/dev/null | grep " + tempFCHostStruct.BDF + " | rev | cut -d '/' -f1 | rev "; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } found = tempOutputString.find("host"); if(found == string::npos) { break; } string strTempHostName = tempOutputString; tempInputString = "cat /sys/class/fc_host/" + tempOutputString + "/symbolic_name"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } found = tempOutputString.find("Emulex 111-03648"); if(found == string::npos) { continue; } strHostName = strTempHostName; tempFCHostStruct.hostName = strHostName; // get WWNN tempInputString = "cat /sys/class/fc_host/" + tempFCHostStruct.hostName + "/node_name 2>/dev/null | sed 's/0x//g' | fold -w2 | paste -sd:"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } tempFCHostStruct.WWNN = tempOutputString; // get WWPN tempInputString = "cat /sys/class/fc_host/" + tempFCHostStruct.hostName + "/port_name 2>/dev/null | sed 's/0x//g' | fold -w2 | paste -sd:"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } tempFCHostStruct.WWPN = tempOutputString; // set wellKnownName ssTemp.clear(); ssTemp.str(""); ssTemp << hex << tempFCHostStruct.portBus; tempInputString = "ls -lv /sys/class/pci_bus | grep 'pci_bus/0000:" + ssTemp.str() + "' | rev | cut -d '/' -f 5 | rev"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } if(tempOutputString == strPCIESlotRootBDF[0]) { tempFCHostStruct.wellKnownName = "H0"; } else if(tempOutputString == strPCIESlotRootBDF[1]) { tempFCHostStruct.wellKnownName = "H1"; } else if(tempOutputString == strPCIESlotRootBDF[2]) { tempFCHostStruct.wellKnownName = "H2"; } else if(tempOutputString == strPCIESlotRootBDF[3]) { tempFCHostStruct.wellKnownName = "H3"; } else if(tempOutputString == strPCIESlotRootBDF[4]) { tempFCHostStruct.wellKnownName = "H4"; } ssTemp.clear(); ssTemp.str(""); ssTemp << dec << portAmount%4; tempFCHostStruct.portNumber = portAmount%4; tempFCHostStruct.wellKnownName += "P" + ssTemp.str(); tempFCHostStruct.note = tempFCHostStruct.wellKnownName + " (Radagast)"; tempFCHostStruct.chipType = eChipTypeRadagast; FCHostList.push_back(tempFCHostStruct); } // for Gandalf for(uint32_t portAmount=0; portAmount> tempFCHostStruct.portBus; // get Dev ssTemp.clear(); ssTemp.str(""); ssTemp << hex << tempOutputString[3] << tempOutputString[4]; ssTemp >> tempFCHostStruct.portDev; // get Func ssTemp.clear(); ssTemp.str(""); ssTemp << hex << tempOutputString[6]; ssTemp >> tempFCHostStruct.portFunc; // get HostName ssTemp.clear(); ssTemp.str(""); ssTemp << dec << portAmount+1; string strHostName = ""; tempInputString = "ls -lv /sys/class/fc_host 2>/dev/null | grep " + tempFCHostStruct.BDF + " | rev | cut -d '/' -f1 | rev "; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } found = tempOutputString.find("host"); if(found == string::npos) { break; } string strTempHostName = tempOutputString; tempInputString = "cat /sys/class/fc_host/" + tempOutputString + "/symbolic_name"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } found = tempOutputString.find("Emulex 111-03249"); if(found == string::npos) { continue; } strHostName = strTempHostName; tempFCHostStruct.hostName = strHostName; // get WWNN tempInputString = "cat /sys/class/fc_host/" + tempFCHostStruct.hostName + "/node_name 2>/dev/null | sed 's/0x//g' | fold -w2 | paste -sd:"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } tempFCHostStruct.WWNN = tempOutputString; // get WWPN tempInputString = "cat /sys/class/fc_host/" + tempFCHostStruct.hostName + "/port_name 2>/dev/null | sed 's/0x//g' | fold -w2 | paste -sd:"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } tempFCHostStruct.WWPN = tempOutputString; // set wellKnownName ssTemp.clear(); ssTemp.str(""); ssTemp << hex << tempFCHostStruct.portBus; tempInputString = "ls -lv /sys/class/pci_bus | grep 'pci_bus/0000:" + ssTemp.str() + "' | rev | cut -d '/' -f 3 | rev"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } if(tempOutputString == strPCIESlotRootBDF[0]) { tempFCHostStruct.wellKnownName = "H0"; } else if(tempOutputString == strPCIESlotRootBDF[1]) { tempFCHostStruct.wellKnownName = "H1"; } else if(tempOutputString == strPCIESlotRootBDF[2]) { tempFCHostStruct.wellKnownName = "H2"; } else if(tempOutputString == strPCIESlotRootBDF[3]) { tempFCHostStruct.wellKnownName = "H3"; } else if(tempOutputString == strPCIESlotRootBDF[4]) { tempFCHostStruct.wellKnownName = "H4"; } ssTemp.clear(); ssTemp.str(""); ssTemp << dec << portAmount%4; tempFCHostStruct.portNumber = portAmount%4; tempFCHostStruct.wellKnownName += "P" + ssTemp.str(); tempFCHostStruct.note = tempFCHostStruct.wellKnownName + " (Gandalf)"; tempFCHostStruct.chipType = eChipTypeRadagast; FCHostList.push_back(tempFCHostStruct); } // for Hobbit for(uint32_t portAmount=0; portAmount> tempFCHostStruct.portBus; // get Dev ssTemp.clear(); ssTemp.str(""); ssTemp << hex << tempOutputString[3] << tempOutputString[4]; ssTemp >> tempFCHostStruct.portDev; // get Func ssTemp.clear(); ssTemp.str(""); ssTemp << hex << tempOutputString[6]; ssTemp >> tempFCHostStruct.portFunc; // get HostName ssTemp.clear(); ssTemp.str(""); ssTemp << dec << portAmount+1; string strHostName = ""; tempInputString = "ls -lv /sys/class/fc_host 2>/dev/null | grep " + tempFCHostStruct.BDF + " | rev | cut -d '/' -f1 | rev "; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } found = tempOutputString.find("host"); if(found == string::npos) { break; } string strTempHostName = tempOutputString; tempInputString = "cat /sys/class/fc_host/" + tempOutputString + "/symbolic_name"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } found = tempOutputString.find("Emulex 111-02451"); if(found == string::npos) { continue; } strHostName = strTempHostName; tempFCHostStruct.hostName = strHostName; // get WWNN tempInputString = "cat /sys/class/fc_host/" + tempFCHostStruct.hostName + "/node_name 2>/dev/null | sed 's/0x//g' | fold -w2 | paste -sd:"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } tempFCHostStruct.WWNN = tempOutputString; // get WWPN tempInputString = "cat /sys/class/fc_host/" + tempFCHostStruct.hostName + "/port_name 2>/dev/null | sed 's/0x//g' | fold -w2 | paste -sd:"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } tempFCHostStruct.WWPN = tempOutputString; // set wellKnownName ssTemp.clear(); ssTemp.str(""); ssTemp << hex << tempFCHostStruct.portBus; tempInputString = "ls -lv /sys/class/pci_bus | grep 'pci_bus/0000:" + ssTemp.str() + "' | rev | cut -d '/' -f 5 | rev"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } if(tempOutputString == strPCIESlotRootBDF[0]) { tempFCHostStruct.wellKnownName = "H0"; } else if(tempOutputString == strPCIESlotRootBDF[1]) { tempFCHostStruct.wellKnownName = "H1"; } else if(tempOutputString == strPCIESlotRootBDF[2]) { tempFCHostStruct.wellKnownName = "H2"; } else if(tempOutputString == strPCIESlotRootBDF[3]) { tempFCHostStruct.wellKnownName = "H3"; } else if(tempOutputString == strPCIESlotRootBDF[4]) { tempFCHostStruct.wellKnownName = "H4"; } ssTemp.clear(); ssTemp.str(""); switch(portAmount%4) { case 0: ssTemp << dec << 2; tempFCHostStruct.portNumber = 2; break; case 1: ssTemp << dec << 3; tempFCHostStruct.portNumber = 3; break; case 2: ssTemp << dec << 0; tempFCHostStruct.portNumber = 0; break; case 3: ssTemp << dec << 1; tempFCHostStruct.portNumber = 1; break; } tempFCHostStruct.wellKnownName += "P" + ssTemp.str(); tempFCHostStruct.note = tempFCHostStruct.wellKnownName + " (Hobbit)"; tempFCHostStruct.chipType = eChipTypeRadagast; FCHostList.push_back(tempFCHostStruct); } // for XE201 for(uint32_t portAmount=0; portAmount> tempFCHostStruct.portBus; // get Dev ssTemp.clear(); ssTemp.str(""); ssTemp << hex << tempOutputString[3] << tempOutputString[4]; ssTemp >> tempFCHostStruct.portDev; // get Func ssTemp.clear(); ssTemp.str(""); ssTemp << hex << tempOutputString[6]; ssTemp >> tempFCHostStruct.portFunc; // get HostName ssTemp.clear(); ssTemp.str(""); ssTemp << dec << portAmount+1; string strHostName = ""; tempInputString = "ls -lv /sys/class/fc_host 2>/dev/null | grep " + tempFCHostStruct.BDF + " | rev | cut -d '/' -f1 | rev "; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } found = tempOutputString.find("host"); if(found == string::npos) { break; } string strTempHostName = tempOutputString; tempInputString = "cat /sys/class/fc_host/" + tempOutputString + "/symbolic_name"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } found = tempOutputString.find("Emulex LPe16000"); size_t found2 = tempOutputString.find("111-04232"); if(found==string::npos && found2==string::npos) { continue; } strHostName = strTempHostName; tempFCHostStruct.hostName = strHostName; // get WWNN tempInputString = "cat /sys/class/fc_host/" + tempFCHostStruct.hostName + "/node_name 2>/dev/null | sed 's/0x//g' | fold -w2 | paste -sd:"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } tempFCHostStruct.WWNN = tempOutputString; // get WWPN tempInputString = "cat /sys/class/fc_host/" + tempFCHostStruct.hostName + "/port_name 2>/dev/null | sed 's/0x//g' | fold -w2 | paste -sd:"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } tempFCHostStruct.WWPN = tempOutputString; // set wellKnownName ssTemp.clear(); ssTemp.str(""); ssTemp << hex << tempFCHostStruct.portBus; tempInputString = "ls -lv /sys/class/pci_bus | grep 'pci_bus/0000:" + ssTemp.str() + "' | rev | cut -d '/' -f 3 | rev"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } ssTemp.clear(); ssTemp.str(""); switch(portAmount%4) { case 0: tempFCHostStruct.wellKnownName = "0g"; ssTemp << dec << 2; tempFCHostStruct.portNumber = 2; break; case 1: tempFCHostStruct.wellKnownName = "0h"; ssTemp << dec << 3; tempFCHostStruct.portNumber = 3; break; case 2: tempFCHostStruct.wellKnownName = "0e"; ssTemp << dec << 0; tempFCHostStruct.portNumber = 0; break; case 3: tempFCHostStruct.wellKnownName = "0f"; ssTemp << dec << 1; tempFCHostStruct.portNumber = 1; break; } tempFCHostStruct.chipType = eChipTypeRadagast; tempFCHostStruct.note = tempFCHostStruct.wellKnownName + " (XE201)"; FCHostList.push_back(tempFCHostStruct); } return rc; } int devList(string strInput) { int rc = -1; // cout << "----------------" << endl; // cout << "Device" << endl; // cout << "----------------" << endl; if(strInput == "verbose") { for(list ::iterator iter=FCHostList.begin();iter!=FCHostList.end();iter++) { cout << iter->BDF << " " << iter->note<< endl; } } else { for(list ::iterator iter=FCHostList.begin();iter!=FCHostList.end();iter++) { cout << iter->note<< endl; } } rc = 0; return rc; } int main(int argc, char *argv[]) { if(argc==1 || argc>5) { printErrorCode("parameter amount is not 1, 2, or 3 !!!"); showUsage(); return -1; } int rc = 0; if((rc=initFCHostList()) != 0) { return rc; } stringstream ssTemp; ssTemp.clear(); ssTemp.str(""); string parm[5] = {"", "", "", "", ""}; unsigned int parmDecimal[5]; for(int i=0; i> parmDecimal[i]; } list ::iterator iter = FCHostList.begin(); for(iter=FCHostList.begin(); iter!=FCHostList.end(); iter++) { if(translateStringToUpperCase(iter->wellKnownName) == translateStringToUpperCase(parm[2])) { break; } } int linkPath = 0; unsigned int dataValue = 0; char portName[FC_DEVICE_NAME_LENGTH]; strncpy(portName, "", sizeof(portName)); string tempInputString = ""; string tempOutputString = ""; string op = parm[1]; if(strcasecmp(op.c_str(), "devlist") != 0) { if(iter == FCHostList.end()) { string strErrorMsg = "No such wellKnownName: " + parm[2]; printErrorCode(strErrorMsg); rc = -1; return rc; } if(translateStringToUpperCase(iter->wellKnownName) != translateStringToUpperCase(parm[2])) { string strErrorMsg = "No such wellKnownName: " + parm[2]; printErrorCode(strErrorMsg); rc = -1; return rc; } } if(strcasecmp(op.c_str(), "devlist") == 0) { if((rc=devList("verbose")) != 0) { return rc; } } else if(iter->chipType==eChipTypeRadagast || iter->chipType==eChipTypeGandalf || iter->chipType==eChipTypeHobbit) { if(strcasecmp(op.c_str(), "resetchip") == 0) { tempInputString = "hbacmd reset " + iter->WWPN; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } cout << tempOutputString << endl; } else if(strcasecmp(op.c_str(), "showdata") == 0) { //LINK STATUS tempInputString = "cat /sys/class/fc_host/" + iter->hostName + "/port_state"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } cout << "Link status: " << tempOutputString << endl; //WWN cout << "WWN: " << iter->WWPN << endl; //STATISTICS tempInputString = "hbacmd portstatistics " + iter->WWPN; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } cout << "Statistics: " << endl; cout << tempOutputString << endl; //FW FLASH ADDRESS //FW REVISION tempInputString = "hbacmd hbaattributes " + iter->WWPN + " | grep \"FW Version\""; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } cout << tempOutputString << endl; } else if(strcasecmp(op.c_str(), "clearstatistics") == 0) { tempInputString = "echo 1 > /sys/class/fc_host/" + iter->hostName + "/statistics/reset_statistics"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } } else if(strcasecmp(op.c_str(), "loopbacktest") == 0) { if(strcasecmp(parm[3].c_str(), "I") == 0) { linkPath = 1; printf("Internal loopback\n"); } else { if(strcasecmp(parm[3].c_str(), "EX") == 0) { linkPath = 2; printf("External loopback \n"); } else { printf("[ERROR] Undefined link path\n"); rc = -1; return rc; } } tempInputString = "hbacmd loopbacktest " + iter->WWPN + " "; ssTemp.clear(); ssTemp.str(""); ssTemp << linkPath; tempInputString += ssTemp.str() + " 400 0 1a2b3c4d"; if((rc = executeShellCommandGetResult(tempInputString, &tempOutputString, true)) != 0) { return rc; } if(tempOutputString.find("Loopback Test Succeeded; cycles complete = 400") == string::npos) { cout << tempOutputString << endl; printErrorCode("Loopback Test Failed"); rc = -1; return rc; } cout << tempOutputString << endl; } else { rc = -1; printErrorCode("No such operation !!!"); showUsage(); return rc; } } if(rc == 0) { cout << " Success" <