diff --git a/guider/guider.py b/guider/guider.py index 7e98d024..81458f57 100755 --- a/guider/guider.py +++ b/guider/guider.py @@ -7,7 +7,7 @@ __credits__ = "Peace Lee" __license__ = "GPLv2" __version__ = "3.9.8" -__revision__ = "231003" +__revision__ = "231004" __maintainer__ = "Peace Lee" __email__ = "iipeace5@gmail.com" __repository__ = "https://github.com/iipeace/guider" @@ -24281,7 +24281,6 @@ def printTrace(console=False): try: eventPath = SysMgr.getTraceEventPath() tracePath = "%s/../trace" % eventPath - tracingPath = "%s/../tracing_on" % eventPath origStatus = None # change trace file to pipe # @@ -24289,12 +24288,14 @@ def printTrace(console=False): tracePath += "_pipe" # save tracing status # else: - origStatus = SysMgr.readFile(tracingPath) + origStatus = SysMgr.readTraceFile("../tracing_on") + + # set trace fd # traceFd = open(tracePath, "r") # check tracing status change # if origStatus == "1": - newStatus = SysMgr.readFile(tracingPath) + newStatus = SysMgr.readTraceFile("../tracing_on") if newStatus == "0": SysMgr.printWarn( "tracing is stopped because '%s' is open" @@ -25225,6 +25226,16 @@ def doLogTrace(msg=None, level=None): SysMgr.printOpenErr(tracePath) return -1 + # get trace status # + traceStat = SysMgr.readTraceFile("../tracing_on") + + # tracing on # + if SysMgr.forceEnable and traceStat == "0": + recoverTraceStat = True + SysMgr.writeTraceCmd("../tracing_on", "1") + else: + recoverTraceStat = False + # print messages # try: msgList = msg.split("\n") @@ -25235,8 +25246,6 @@ def doLogTrace(msg=None, level=None): sys.exit(0) except: try: - traceStatPath = "%s/../tracing_on" % SysMgr.getTraceEventPath() - traceStat = SysMgr.readFile(traceStatPath) if traceStat == "0": SysMgr.printErr( "failed to write trace message because tracing is off" @@ -25244,8 +25253,11 @@ def doLogTrace(msg=None, level=None): except SystemExit: sys.exit(0) except: - SysMgr.printWarn("failed to write trace message", reason=True) + SysMgr.printWarn("failed to get trace status", reason=True) return -1 + finally: + if recoverTraceStat: + SysMgr.writeTraceCmd("../tracing_on", traceStat) return 0 @@ -28080,6 +28092,105 @@ def splitFile( ) return pathList + @staticmethod + def doLess(inputArg=None): + # check input # + if inputArg: + if type(inputArg) is not list: + inputArg = [inputArg] + elif SysMgr.hasMainArg(): + inputArg = SysMgr.getMainArgs() + elif SysMgr.inputParam: + inputArg = str(SysMgr.inputParam).split(",") + inputArg = UtilMgr.cleanItem(inputArg, True) + else: + SysMgr.printErr("no input for PATH") + return -1 + + # convert input files # + inputArg = UtilMgr.getFileList(inputArg, sort=True, exceptDir=True) + if not inputArg: + SysMgr.printErr("no target file") + return -1 + + wbuf = [] + cursor = 0 + + # print files # + for path in inputArg: + fsize = UtilMgr.getFileSizeStr(path) + SysMgr.printStat(r"start reading '%s%s'..." % (path, fsize)) + + try: + lines = SysMgr.readFile(path).split("\n") + wbuf += [ + twoLine, + "%s%s <%s lines>" % ( + path, fsize, UtilMgr.convNum(len(lines)) + ), + twoLine, + ] + wbuf += lines + except SystemExit: + sys.exit(0) + except: + SysMgr.printErr("failed to less '%s%s'" % (path, fsize), True) + continue + + # clear screen and print a page # + SysMgr.clearScreen() + SysMgr.printPipe( + wbuf[cursor : cursor + SysMgr.ttyRows - 1], pager=False + ) + + def _handleInput(k, cursor, wbuf): + if k == "q": + sys.exit(0) + elif k == "f": + cursor += SysMgr.ttyRows + elif k == "b": + cursor -= SysMgr.ttyRows + elif k == "g": + cursor = 0 + elif k == "G": + cursor = len(wbuf) - 1 + elif k == "\x1b[D": + cursor -= 1 + elif k in ("\x1b[C", ""): + cursor += 1 + elif k.isdigit(): + cursor = long(k) + + # update cursor # + if cursor < 0: + cursor = 0 + elif cursor >= len(wbuf) - SysMgr.ttyRows: + cursor = max(len(wbuf) - SysMgr.ttyRows, 0) + + return cursor + + # handle input # + while 1: + try: + sys.stdout.write(": ") + sys.stdout.flush() + + # read input # + k = sys.stdin.readline() + + # handle key # + cursor = _handleInput(k.strip(), cursor, wbuf) + + # clear screen and print a page # + SysMgr.clearScreen() + SysMgr.printPipe( + wbuf[cursor : cursor + SysMgr.ttyRows - 1], pager=False + ) + except SystemExit: + sys.exit(0) + except: + SysMgr.printWarn("failed to move page", True, True) + @staticmethod def doDump(): # get argument # @@ -33022,7 +33133,7 @@ def readMemoryMap(): addrs.rstrip().split("-"), False ) startAddr = long(start, 16) - size = long(end, 16) - startAddr + size = long(end, 16) - startAddr + 1 sizeUnit = "%s (%7s)" % ( UtilMgr.convNum(size), UtilMgr.convSize2Unit(size), @@ -33179,6 +33290,7 @@ def _checkMode(): "fserver", "hserver", "iotest", + "less", "list", "merge", "mkcache", @@ -33527,6 +33639,7 @@ def getCmdList(): "fadvise": ("File", "Linux"), "getafnt": ("Affinity", "Linux"), "getpid": ("PID", "Linux"), + "less": ("Pager", "Linux/MacOS/Windows"), "merge": ("File", "Linux/MacOS/Windows"), "mkcache": ("Cache", "Linux/MacOS/Windows"), "mount": ("Mount", "Linux"), @@ -36652,6 +36765,28 @@ def _getDesc(s, t=0): "Print IDs", ) + # less # + elif SysMgr.checkMode("less"): + helpStr = _getDesc("Print files with pager", t=5) + + helpStr += """ +Options: + -I set file path + -g set filter + -o set output path + -m set terminal size + -v verbose + """ + + helpStr += """ +Examples: + - {2:1} + # {0:1} {1:1} a.out + # {0:1} {1:1} -I a.out + """.format( + cmd, mode, "Print files with pager" + ) + # strings # elif SysMgr.checkMode("strings"): helpStr = _getDesc( @@ -38036,6 +38171,9 @@ def _getDesc(s, t=0): # {0:1} {1:1} -q DISABLETP:"irq*" # {0:1} {1:1} -q CLEARFILTER + - {2:1} after enabling tracing forcefully + # {0:1} {1:1} -f + - Print tracepoint list # {0:1} {1:1} -l # {0:1} {1:1} -l -H -a @@ -41203,6 +41341,14 @@ class fanotify_response(Structure): "failed to call fanotify_init because %s" % SysMgr.getErrReason() ) + + # check kernel config # + if not "CONFIG_FANOTIFY=" in SysMgr.getKconf(): + SysMgr.printErr( + "failed to use fanotify, please check kernel configs" + ) + sys.exit(-1) + return False # get mask flags # @@ -50232,6 +50378,10 @@ def checkCmdMode(): elif SysMgr.checkMode("print"): SysMgr.doPrintFile() + # LESS MODE # + elif SysMgr.checkMode("less"): + SysMgr.doLess() + # DUMP MODE # elif SysMgr.checkMode("dump"): SysMgr.doDump() @@ -56198,6 +56348,30 @@ def doSetSched(): # wait for next tick # time.sleep(SysMgr.intervalEnable) + @staticmethod + def getKconf(): + if os.path.exists("/proc/config.gz"): + inputParam = "/proc/config.gz" + else: + inputParam = "/boot/config-%s" % SysMgr.getKernelVersion(name=True) + + # check config file # + if not os.path.exists(inputParam): + SysMgr.printWarn("no kernel config file", True) + return "" + + # get configs # + try: + if inputParam.endswith("gz"): + return UtilMgr.ungzip(inputParam).decode() + else: + return open(inputParam, "r").read() + except SystemExit: + sys.exit(0) + except: + SysMgr.printOpenErr(inputParam) + return "" + @staticmethod def doPrintKconf(): SysMgr.printLogo(big=True, onlyFile=True) @@ -65584,15 +65758,17 @@ def mergeCommStat(statList, commIdx=None): if not commIdx: commIdx = ConfigMgr.PROCSTAT_ATTR.index("COMM") + if statList[commIdx][-1] == ")": + return statList + # merge comm parts that splited by space # - if statList[commIdx][-1] != ")": - idx = commIdx + 1 - while 1: - tmpStr = str(statList[idx]) - statList[commIdx] = "%s %s" % (statList[commIdx], tmpStr) - statList.pop(idx) - if ")" in tmpStr: - break + idx = commIdx + 1 + while 1: + tmpStr = str(statList[idx]) + statList[commIdx] = "%s %s" % (statList[commIdx], tmpStr) + statList.pop(idx) + if ")" in tmpStr: + break return statList @@ -68106,7 +68282,7 @@ def enableEvents(): SysMgr.applyTraceAttr(filters, "enable", "1", True) # prepare for recovering tracing status after printing # - tracingStat = os.path.join(SysMgr.getTraceEventPath(), "../tracing_on") + tracingStat = SysMgr.readTraceFile("../tracing_on") orig = SysMgr.readFile(tracingStat) SysMgr.addExitFunc(SysMgr.writeTraceCmd, ["../tracing_on", orig]) @@ -105269,6 +105445,9 @@ def runIrqTop(self): # run loop # while 1: + # update uptime # + SysMgr.updateUptime() + # save timestamp # prevTime = time.time() @@ -124952,9 +125131,6 @@ def printIrqs(self): SysMgr.printTopStats() def saveIrqs(self, full=False): - # update uptime # - SysMgr.updateUptime() - # read irq buf # irqBuf = SysMgr.readProcStat( SysMgr.irqFd, "interrupts", SysMgr, "irqFd" @@ -129878,10 +130054,13 @@ def printPsiStat(self, nrIndent): # get total diff # try: diff = ( - stat["total"] - SysMgr.prevPsiData[res][attr]["total"] + ( + stat["total"] + - SysMgr.prevPsiData[res][attr]["total"] + ) + / 10000.0 + / SysMgr.uptimeDiff ) - diff /= 10000.0 - diff /= SysMgr.uptimeDiff SysMgr.psiData[res][attr]["diff"] = diff except SystemExit: sys.exit(0)