All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Bernatowicz, Marcin" <marcin.bernatowicz@linux.intel.com>
To: Adam Miszczak <adam.miszczak@linux.intel.com>,
	igt-dev@lists.freedesktop.org
Cc: kamil.konieczny@linux.intel.com
Subject: Re: [PATCH i-g-t 6/7] tools/vmtb: Add VM dmesg wait support
Date: Thu, 8 Oct 2026 15:56:07 +0200	[thread overview]
Message-ID: <d8aa547c-4fa4-41a4-b6cf-af232dac0876@linux.intel.com> (raw)
In-Reply-To: <20260928072600.426902-7-adam.miszczak@linux.intel.com>

LGTM,

Reviewed-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>

On 9/28/2026 9:25 AM, Adam Miszczak wrote:
> Introduce VirtualMachine.wait_for_dmesg() to block until a line matching
> a given regex pattern appears on the guest serial console, returning the
> matched line or raising an exception on timeout.
>
> QEMU output (including guest dmesg) is buffered in a thread-safe buffer
> guarded by a condition variable, notifying waiters as new lines arrive.
> ANSI escape (color) codes are stripped from dmesg before logging.
>
> New function provides 'from_beginning' parameter:
> default (from_beginning=True) scans the whole dmesg collected since
> power on, while from_beginning=False resumes right after the previously
> matched line (uses cursor shared for all patterns).
>
> Signed-off-by: Adam Miszczak <adam.miszczak@linux.intel.com>
> ---
>   tools/vmtb/bench/machines/virtual/vm.py | 48 ++++++++++++++++++++++++-
>   1 file changed, 47 insertions(+), 1 deletion(-)
>
> diff --git a/tools/vmtb/bench/machines/virtual/vm.py b/tools/vmtb/bench/machines/virtual/vm.py
> index e0b6fb150..6b8425d13 100644
> --- a/tools/vmtb/bench/machines/virtual/vm.py
> +++ b/tools/vmtb/bench/machines/virtual/vm.py
> @@ -26,6 +26,10 @@ from bench.machines.virtual.device import VirtualDevice
>   
>   logger = logging.getLogger('VirtualMachine')
>   
> +# Matches ANSI escape sequences (e.g. color codes like \x1b[0;32m) emitted on the
> +# guest serial console, so they can be stripped before logging dmesg lines.
> +ANSI_ESCAPE_RE = re.compile(r'\x1b\[[0-9;]*[A-Za-z]')
> +
>   
>   class VirtualMachine(MachineInterface):
>       class Decorators():
> @@ -113,6 +117,13 @@ class VirtualMachine(MachineInterface):
>           self.migrate_destination_vm: bool = False
>           self._migration_ongoing: bool = False
>   
> +        # Buffer of guest serial console (dmesg) lines captured since power on,
> +        # guarded by a condition variable to allow waiting for specific messages.
> +        self._dmesg_buffer: typing.List[str] = []
> +        self._dmesg_condition = threading.Condition()
> +        # Dmesg wait cursor (shared across patterns): first dmesg line not consumed yet
> +        self._dmesg_scan_idx: int = 0
> +
>           self.dmesg_logger = self.__setup_dmesg_logger()
>   
>       def __str__(self) -> str:
> @@ -180,7 +191,11 @@ class VirtualMachine(MachineInterface):
>   
>       def __log_qemu_output(self, out: typing.TextIO) -> None:
>           for line in iter(out.readline, ''):
> -            self.dmesg_logger.debug(line.strip())
> +            stripped_line = ANSI_ESCAPE_RE.sub('', line).strip()
> +            self.dmesg_logger.debug(stripped_line)
> +            with self._dmesg_condition:
> +                self._dmesg_buffer.append(stripped_line)
> +                self._dmesg_condition.notify_all()
>   
>       def __sockets_exists(self) -> bool:
>           return self.questagent_sockpath.exists() and self.qmp_sockpath.exists()
> @@ -587,6 +602,37 @@ class VirtualMachine(MachineInterface):
>   
>           return True
>   
> +    @Decorators.timeout_signal
> +    def wait_for_dmesg(self, pattern: str, from_beginning: bool = True, timeout: int = 300) -> str:
> +        """Wait until a line matching the given regex pattern appears in the guest dmesg.
> +
> +        Scans the guest serial console output and blocks until a matching line is observed.
> +        By default the whole dmesg collected since VM power on is scanned.
> +        Clear 'from_beginning' to start right after the line matched by a previous
> +        wait_for_dmesg() call, to match consecutive occurrences of a repeating message.
> +        Returns the matched dmesg line (e.g. for further parsing) or raises AlarmTimeoutError
> +        if the pattern does not appear within the given timeout (in seconds).
> +        """
> +        regex = re.compile(pattern)
> +        logger.debug("[VM%s] Waiting for dmesg pattern: '%s'%s", self.vmnum, pattern,
> +                     '' if from_beginning else ' (since last match)')
> +
> +        with self._dmesg_condition:
> +            scan_idx = 0 if from_beginning else self._dmesg_scan_idx
> +            while True:
> +                while scan_idx < len(self._dmesg_buffer):
> +                    line = self._dmesg_buffer[scan_idx]
> +                    scan_idx += 1
> +                    if regex.search(line):
> +                        # Do not rewind the cursor
> +                        self._dmesg_scan_idx = max(self._dmesg_scan_idx, scan_idx)
> +                        logger.debug("[VM%s] Matched dmesg pattern: '%s'", self.vmnum, pattern)
> +                        return line
> +
> +                # Poll with a short timeout so the SIGALRM raised by
> +                # Decorators.timeout_signal can interrupt the wait and propagate.
> +                self._dmesg_condition.wait(timeout=1)
> +
>       def save_state_init(self) -> None:
>           """Initiate VM snapshot-save operation (asynchronous)."""
>           logger.debug("Starting VM%s state save (snapshot)", self.vmnum)

  reply	other threads:[~2026-10-08 13:59 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-28  7:25 [PATCH i-g-t 0/7] tools/vmtb: Sync VM Test Bench core with current xe SR-IOV Adam Miszczak
2026-09-28  7:25 ` [PATCH i-g-t 1/7] tools/vmtb: Introduce asynchronous VM state save/load functions Adam Miszczak
2026-10-08 13:53   ` Bernatowicz, Marcin
2026-09-28  7:25 ` [PATCH i-g-t 2/7] tools/vmtb: Rework VF scheduler provisioning Adam Miszczak
2026-10-08 13:54   ` Bernatowicz, Marcin
2026-09-28  7:25 ` [PATCH i-g-t 3/7] tools/vmtb: Align driver/device layer with current xe SR-IOV interfaces Adam Miszczak
2026-10-08 13:54   ` Bernatowicz, Marcin
2026-09-28  7:25 ` [PATCH i-g-t 4/7] tools/vmtb: Fix guest timeout handling and PCI BDF matching Adam Miszczak
2026-10-08 13:55   ` Bernatowicz, Marcin
2026-09-28  7:25 ` [PATCH i-g-t 5/7] tools/vmtb: Add pre-test environment cleanup Adam Miszczak
2026-10-08 13:55   ` Bernatowicz, Marcin
2026-09-28  7:25 ` [PATCH i-g-t 6/7] tools/vmtb: Add VM dmesg wait support Adam Miszczak
2026-10-08 13:56   ` Bernatowicz, Marcin [this message]
2026-09-28  7:26 ` [PATCH i-g-t 7/7] tools/vmtb: Extend IGT and WSIM executors Adam Miszczak
2026-10-08 12:59   ` Bernatowicz, Marcin
2026-09-28 20:28 ` ✓ i915.CI.BAT: success for tools/vmtb: Sync VM Test Bench core with current xe SR-IOV Patchwork
2026-09-28 20:47 ` ✓ Xe.CI.BAT: " Patchwork
2026-09-29  2:19 ` ✗ Xe.CI.FULL: failure " Patchwork
2026-09-29  4:08 ` ✗ i915.CI.Full: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d8aa547c-4fa4-41a4-b6cf-af232dac0876@linux.intel.com \
    --to=marcin.bernatowicz@linux.intel.com \
    --cc=adam.miszczak@linux.intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=kamil.konieczny@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.