tests/vm: Add workaround to consume console
authorRobert Foley <robert.foley@linaro.org>
Wed, 1 Jul 2020 13:56:25 +0000 (14:56 +0100)
committerAlex Bennée <alex.bennee@linaro.org>
Sat, 11 Jul 2020 14:53:00 +0000 (15:53 +0100)
This adds support to basevm.py so that we always
drain the console chars.  This makes use of
support added in an earlier commit that allows
QEMUMachine to use the ConsoleSocket.

This is a workaround we found was needed since
there is a known issue where QEMU will hang waiting
for console characters to be consumed.

We also added the option of logging the console to a file.
LOG_CONSOLE=1 will now log the output to a file.

Signed-off-by: Robert Foley <robert.foley@linaro.org>
Reviewed-by: Peter Puhov <peter.puhov@linaro.org>
Acked-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20200601211421.1277-10-robert.foley@linaro.org>
Message-Id: <20200701135652.1366-14-alex.bennee@linaro.org>

tests/vm/Makefile.include
tests/vm/basevm.py

index 39f918a430a5f8df2a299c9147413ffa08c84d3d..f21948c46a529d4589357be54b427bf1deea66e2 100644 (file)
@@ -49,6 +49,7 @@ endif
        @echo '    EXTRA_CONFIGURE_OPTS="..."'
        @echo "    J=[0..9]*                     - Override the -jN parameter for make commands"
        @echo "    DEBUG=1                       - Enable verbose output on host and interactive debugging"
+       @echo "    LOG_CONSOLE=1                 - Log console to file in: ~/.cache/qemu-vm "
        @echo "    V=1                           - Enable verbose ouput on host and guest commands"
        @echo "    QEMU_LOCAL=1                 - Use QEMU binary local to this build."
        @echo "    QEMU=/path/to/qemu            - Change path to QEMU binary"
@@ -75,6 +76,7 @@ $(IMAGES_DIR)/%.img:  $(SRC_PATH)/tests/vm/% \
                $(if $(GENISOIMAGE),--genisoimage $(GENISOIMAGE)) \
                $(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \
                $(if $(EFI_AARCH64),--efi-aarch64 $(EFI_AARCH64)) \
+               $(if $(LOG_CONSOLE),--log-console) \
                --image "$@" \
                --force \
                --build-image $@, \
@@ -91,6 +93,7 @@ vm-build-%: $(IMAGES_DIR)/%.img
                $(if $(V),--verbose) \
                $(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \
                $(if $(EFI_AARCH64),--efi-aarch64 $(EFI_AARCH64)) \
+               $(if $(LOG_CONSOLE),--log-console) \
                --image "$<" \
                $(if $(BUILD_TARGET),--build-target $(BUILD_TARGET)) \
                --snapshot \
@@ -114,6 +117,7 @@ vm-boot-ssh-%: $(IMAGES_DIR)/%.img
                $(if $(V)$(DEBUG), --debug) \
                $(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \
                $(if $(EFI_AARCH64),--efi-aarch64 $(EFI_AARCH64)) \
+               $(if $(LOG_CONSOLE),--log-console) \
                --image "$<" \
                --interactive \
                false, \
index 15aec593e54f605f0d519da365d94bebd7ce766a..4c2878f022143026a512452faef5bcce7bd475aa 100644 (file)
@@ -117,6 +117,11 @@ class BaseVM(object):
              "w").write(self._config['ssh_pub_key'])
 
         self.debug = args.debug
+        self._console_log_path = None
+        if args.log_console:
+                self._console_log_path = \
+                         os.path.join(os.path.expanduser("~/.cache/qemu-vm"),
+                                      "{}.install.log".format(self.name))
         self._stderr = sys.stderr
         self._devnull = open(os.devnull, "w")
         if self.debug:
@@ -271,7 +276,13 @@ class BaseVM(object):
         args += self._data_args + extra_args + self._config['extra_args']
         logging.debug("QEMU args: %s", " ".join(args))
         qemu_path = get_qemu_path(self.arch, self._build_path)
-        guest = QEMUMachine(binary=qemu_path, args=args)
+
+        # Since console_log_path is only set when the user provides the
+        # log_console option, we will set drain_console=True so the
+        # console is always drained.
+        guest = QEMUMachine(binary=qemu_path, args=args,
+                            console_log=self._console_log_path,
+                            drain_console=True)
         guest.set_machine(self._config['machine'])
         guest.set_console()
         try:
@@ -285,6 +296,8 @@ class BaseVM(object):
             raise
         atexit.register(self.shutdown)
         self._guest = guest
+        # Init console so we can start consuming the chars.
+        self.console_init()
         usernet_info = guest.qmp("human-monitor-command",
                                  command_line="info usernet")
         self.ssh_port = None
@@ -296,7 +309,9 @@ class BaseVM(object):
             raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \
                             usernet_info)
 
-    def console_init(self, timeout = 120):
+    def console_init(self, timeout = None):
+        if timeout == None:
+            timeout = self.socket_timeout
         vm = self._guest
         vm.console_socket.settimeout(timeout)
         self.console_raw_path = os.path.join(vm._temp_dir,
@@ -578,6 +593,8 @@ def parse_args(vmcls):
     parser.add_option("--efi-aarch64",
                       default="/usr/share/qemu-efi-aarch64/QEMU_EFI.fd",
                       help="Path to efi image for aarch64 VMs.")
+    parser.add_option("--log-console", action="store_true",
+                      help="Log console to file.")
     parser.disable_interspersed_args()
     return parser.parse_args()