Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 516f1190 authored by Stefan Raspl's avatar Stefan Raspl Committed by Paolo Bonzini
Browse files

tools/kvm_stat: eliminate extra guest/pid selection dialog



We can do with a single dialog that takes both, pids and guest names.
Note that we keep both interactive commands, 'p' and 'g' for now, to
avoid confusion among users used to a specific key.

While at it, we improve on some minor glitches regarding curses usage,
e.g. cursor still visible when not supposed to be.

Signed-off-by: default avatarStefan Raspl <raspl@linux.vnet.ibm.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent c0e8c21e
Loading
Loading
Loading
Loading
+37 −73
Original line number Original line Diff line number Diff line
@@ -1041,6 +1041,8 @@ class Tui(object):


    def _update_pid(self, pid):
    def _update_pid(self, pid):
        """Propagates pid selection to stats object."""
        """Propagates pid selection to stats object."""
        self.screen.addstr(4, 1, 'Updating pid filter...')
        self.screen.refresh()
        self.stats.pid_filter = pid
        self.stats.pid_filter = pid


    def _refresh_header(self, pid=None):
    def _refresh_header(self, pid=None):
@@ -1144,10 +1146,10 @@ class Tui(object):
               ' filters)',
               ' filters)',
               '   c     clear filter',
               '   c     clear filter',
               '   f     filter by regular expression',
               '   f     filter by regular expression',
               '   g     filter by guest name',
               '   g     filter by guest name/PID',
               '   h     display interactive commands reference',
               '   h     display interactive commands reference',
               '   o     toggle sorting order (Total vs CurAvg/s)',
               '   o     toggle sorting order (Total vs CurAvg/s)',
               '   p     filter by PID',
               '   p     filter by guest name/PID',
               '   q     quit',
               '   q     quit',
               '   r     reset stats',
               '   r     reset stats',
               '   s     set update interval',
               '   s     set update interval',
@@ -1199,44 +1201,6 @@ class Tui(object):
                msg = '"' + regex + '": Not a valid regular expression'
                msg = '"' + regex + '": Not a valid regular expression'
                continue
                continue


    def _show_vm_selection_by_pid(self):
        """Draws PID selection mask.

        Asks for a pid until a valid pid or 0 has been entered.

        """
        msg = ''
        while True:
            self.screen.erase()
            self.screen.addstr(0, 0,
                               'Show statistics for specific pid.',
                               curses.A_BOLD)
            self.screen.addstr(1, 0,
                               'This might limit the shown data to the trace '
                               'statistics.')
            self.screen.addstr(5, 0, msg)
            self._print_all_gnames(7)

            curses.echo()
            self.screen.addstr(3, 0, "Pid [0 or pid]: ")
            pid = self.screen.getstr().decode(ENCODING)
            curses.noecho()

            try:
                if len(pid) > 0:
                    pid = int(pid)
                    if pid != 0 and not os.path.isdir(os.path.join('/proc/',
                                                                   str(pid))):
                        msg = '"' + str(pid) + '": Not a running process'
                        continue
                else:
                    pid = 0
                self._refresh_header(pid)
                self._update_pid(pid)
                break
            except ValueError:
                msg = '"' + str(pid) + '": Not a valid pid'

    def _show_set_update_interval(self):
    def _show_set_update_interval(self):
        """Draws update interval selection mask."""
        """Draws update interval selection mask."""
        msg = ''
        msg = ''
@@ -1269,17 +1233,17 @@ class Tui(object):
                msg = '"' + str(val) + '": Invalid value'
                msg = '"' + str(val) + '": Invalid value'
        self._refresh_header()
        self._refresh_header()


    def _show_vm_selection_by_guest_name(self):
    def _show_vm_selection_by_guest(self):
        """Draws guest selection mask.
        """Draws guest selection mask.


        Asks for a guest name until a valid guest name or '' is entered.
        Asks for a guest name or pid until a valid guest name or '' is entered.


        """
        """
        msg = ''
        msg = ''
        while True:
        while True:
            self.screen.erase()
            self.screen.erase()
            self.screen.addstr(0, 0,
            self.screen.addstr(0, 0,
                               'Show statistics for specific guest.',
                               'Show statistics for specific guest or pid.',
                               curses.A_BOLD)
                               curses.A_BOLD)
            self.screen.addstr(1, 0,
            self.screen.addstr(1, 0,
                               'This might limit the shown data to the trace '
                               'This might limit the shown data to the trace '
@@ -1287,32 +1251,39 @@ class Tui(object):
            self.screen.addstr(5, 0, msg)
            self.screen.addstr(5, 0, msg)
            self._print_all_gnames(7)
            self._print_all_gnames(7)
            curses.echo()
            curses.echo()
            self.screen.addstr(3, 0, "Guest [ENTER or guest]: ")
            curses.curs_set(1)
            gname = self.screen.getstr().decode(ENCODING)
            self.screen.addstr(3, 0, "Guest or pid [ENTER exits]: ")
            guest = self.screen.getstr().decode(ENCODING)
            curses.noecho()
            curses.noecho()


            if not gname:
            pid = 0
                self._refresh_header(0)
            if not guest or guest == '0':
                self._update_pid(0)
                break
            if guest.isdigit():
                if not os.path.isdir(os.path.join('/proc/', guest)):
                    msg = '"' + guest + '": Not a running process'
                    continue
                pid = int(guest)
                break
                break
            else:
            pids = []
            pids = []
            try:
            try:
                    pids = self.get_pid_from_gname(gname)
                pids = self.get_pid_from_gname(guest)
            except:
            except:
                    msg = '"' + gname + '": Internal error while searching, ' \
                msg = '"' + guest + '": Internal error while searching, ' \
                      'use pid filter instead'
                      'use pid filter instead'
                continue
                continue
            if len(pids) == 0:
            if len(pids) == 0:
                    msg = '"' + gname + '": Not an active guest'
                msg = '"' + guest + '": Not an active guest'
                continue
                continue
            if len(pids) > 1:
            if len(pids) > 1:
                    msg = '"' + gname + '": Multiple matches found, use pid ' \
                msg = '"' + guest + '": Multiple matches found, use pid ' \
                      'filter instead'
                      'filter instead'
                continue
                continue
                self._refresh_header(pids[0])
            pid = pids[0]
                self._update_pid(pids[0])
            break
            break
        curses.curs_set(0)
        self._refresh_header(pid)
        self._update_pid(pid)


    def show_stats(self):
    def show_stats(self):
        """Refreshes the screen and processes user input."""
        """Refreshes the screen and processes user input."""
@@ -1344,20 +1315,13 @@ class Tui(object):
                    self._show_filter_selection()
                    self._show_filter_selection()
                    curses.curs_set(0)
                    curses.curs_set(0)
                    sleeptime = self._delay_initial
                    sleeptime = self._delay_initial
                if char == 'g':
                if char == 'g' or char == 'p':
                    curses.curs_set(1)
                    self._show_vm_selection_by_guest()
                    self._show_vm_selection_by_guest_name()
                    curses.curs_set(0)
                    sleeptime = self._delay_initial
                    sleeptime = self._delay_initial
                if char == 'h':
                if char == 'h':
                    self._show_help_interactive()
                    self._show_help_interactive()
                if char == 'o':
                if char == 'o':
                    self._sorting = not self._sorting
                    self._sorting = not self._sorting
                if char == 'p':
                    curses.curs_set(1)
                    self._show_vm_selection_by_pid()
                    curses.curs_set(0)
                    sleeptime = self._delay_initial
                if char == 'q':
                if char == 'q':
                    break
                    break
                if char == 'r':
                if char == 'r':
+2 −2
Original line number Original line Diff line number Diff line
@@ -35,13 +35,13 @@ INTERACTIVE COMMANDS


*f*::	filter by regular expression
*f*::	filter by regular expression


*g*::	filter by guest name
*g*::	filter by guest name/PID


*h*::	display interactive commands reference
*h*::	display interactive commands reference


*o*::   toggle sorting order (Total vs CurAvg/s)
*o*::   toggle sorting order (Total vs CurAvg/s)


*p*::	filter by PID
*p*::	filter by guest name/PID


*q*::	quit
*q*::	quit