Skip to content

Commit

Permalink
Merge pull request #3722 from M4rtinK/rhel-9-wait_for_threads_to_fini…
Browse files Browse the repository at this point in the history
…sh_before_filling_install_task_queue

Wait for all background threads to finish before filling installation…
  • Loading branch information
rvykydal committed Nov 26, 2021
2 parents 11f5d9b + fa92065 commit c9ffd65
Showing 1 changed file with 25 additions and 18 deletions.
43 changes: 25 additions & 18 deletions pyanaconda/installation.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from pyanaconda.kickstart import runPostScripts, runPreInstallScripts
from pyanaconda.kexec import setup_kexec
from pyanaconda.installation_tasks import Task, TaskQueue, DBusTask
from pyanaconda.progress import progressQ
from pykickstart.constants import SNAPSHOT_WHEN_POST_INSTALL

from pyanaconda.anaconda_loggers import get_module_logger
Expand Down Expand Up @@ -214,6 +215,25 @@ def run_generate_initramfs():
return configuration_queue


def wait_for_threads_to_finish():
"""Wait for background processing threads to finish.
Wait for background processing threads to finish before filling
the installation task queue. Otherwise installation tasks might
be created based on old data in DBus modules, missing data set by
the threads that are still running.
"""

# This should be the only thread running, wait for the others to finish if not.
if threadMgr.running > 1:
# show a progress message
progressQ.send_message(N_("Waiting for %s threads to finish") % (threadMgr.running - 1))
for message in ("Thread %s is running" % n for n in threadMgr.names):
log.debug(message)
threadMgr.wait_all()
log.debug("No more threads are running, assembling installation task queue.")


def _prepare_installation(payload, ksdata):
"""Perform an installation. This method takes the ksdata as prepared by
the UI (the first hub, in graphical mode) and applies it to the disk.
Expand All @@ -225,24 +245,6 @@ def _prepare_installation(payload, ksdata):
installation_queue.queue_started.connect(lambda x: progress_message(x.status_message))
installation_queue.task_completed.connect(lambda x: progress_step(x.name))

# This should be the only thread running, wait for the others to finish if not.
if threadMgr.running > 1:
# it could be that the threads finish execution before the task is executed,
# but that should not cause any issues

def wait_for_all_treads():
for message in ("Thread %s is running" % n for n in threadMgr.names):
log.debug(message)
threadMgr.wait_all()

# Use a queue with a single task as only TaskQueues have the status_message
# property used for setting the progress status in the UI.
wait_for_threads = TaskQueue("Wait for threads to finish",
N_("Waiting for %s threads to finish") % (threadMgr.running - 1))

wait_for_threads.append(Task("Wait for all threads to finish", wait_for_all_treads))
installation_queue.append(wait_for_threads)

# Save system time to HW clock.
# - this used to be before waiting on threads, but I don't think that's needed
if conf.system.can_set_hardware_clock:
Expand Down Expand Up @@ -359,6 +361,11 @@ def run_install_bootloader():

def run_installation(payload, ksdata):
"""Run the complete installation."""
# before building the install task queue make
# sure no backgrond processing threads are running and
# the Anaconda internal state is thus final
wait_for_threads_to_finish()

queue = TaskQueue("Complete installation queue")
queue.append(_prepare_installation(payload, ksdata))
queue.append(_prepare_configuration(payload, ksdata))
Expand Down

0 comments on commit c9ffd65

Please sign in to comment.