diff --git a/anaconda.spec b/anaconda.spec index 6ea0893..749902c 100644 --- a/anaconda.spec +++ b/anaconda.spec @@ -4,7 +4,7 @@ %endif Name: anaconda Version: 33.19 -Release: 29 +Release: 30 Summary: Graphical system installer License: GPLv2+ and MIT URL: http://fedoraproject.org/wiki/Anaconda @@ -119,6 +119,8 @@ Patch6075: change-inst-repo-default-value.patch Patch6076: delete-datezone-map.patch Patch6077: backport-fix-boot-options-generated-by-dracut-module.patch +Patch9026: fix-deadlock-when-forking-in-multithread.patch + %define dbusver 1.2.3 %define dnfver 3.6.0 %define dracutver 034-7 @@ -333,6 +335,12 @@ update-desktop-database &> /dev/null || : %{_datadir}/gtk-doc %changelog +* Fri Oct 29 2021 orange-snn - 33.19-30 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:fix deadlock when forking in multithread + * Fri Oct 29 2021 fengtao - 33.19-29 - Type:bugfix - ID:NA diff --git a/fix-deadlock-when-forking-in-multithread.patch b/fix-deadlock-when-forking-in-multithread.patch new file mode 100644 index 0000000..1529c7d --- /dev/null +++ b/fix-deadlock-when-forking-in-multithread.patch @@ -0,0 +1,152 @@ +From ed78249ad5f3bf44777d0bdd39bb3f1a2890239d Mon Sep 17 00:00:00 2001 +From: "t.feng" +Date: Mon, 2 Aug 2021 15:07:01 +0600 +Subject: [PATCH] fix deadlock when forking in multithread + +--- + pyanaconda/core/glib.py | 19 +++++++++++++++++-- + pyanaconda/payload/dnf/payload.py | 15 +++++++++++---- + pyanaconda/payload/dnf/utils.py | 2 ++ + .../ui/gui/spokes/installation_progress.py | 4 ++++ + 4 files changed, 34 insertions(+), 6 deletions(-) + +diff --git a/pyanaconda/core/glib.py b/pyanaconda/core/glib.py +index 03c598d..e1cb8db 100644 +--- a/pyanaconda/core/glib.py ++++ b/pyanaconda/core/glib.py +@@ -33,9 +33,10 @@ from gi.repository.GLib import markup_escape_text, format_size_full, \ + MainLoop, MainContext, \ + GError, Variant, VariantType, Bytes, \ + IOCondition, IOChannel, SpawnFlags, \ +- MAXUINT ++ MAXUINT, Mutex + +-__all__ = ["create_main_loop", "create_new_context", ++__all__ = ["glib_mutex", "run_with_mutex", ++ "create_main_loop", "create_new_context", + "markup_escape_text", "format_size_full", + "timeout_add_seconds", "timeout_add", "idle_add", + "io_add_watch", "child_watch_add", +@@ -46,6 +47,9 @@ __all__ = ["create_main_loop", "create_new_context", + "MAXUINT"] + + ++glib_mutex = Mutex() ++ ++ + def create_main_loop(): + """Create GLib main loop. + +@@ -59,3 +63,14 @@ def create_new_context(): + + :returns: GLib.MainContext.""" + return MainContext.new() ++ ++ ++def run_with_mutex(func): ++ """run in glib mutex ++ """ ++ def _call_method(*args, **kwargs): ++ glib_mutex.lock() ++ func(*args, **kwargs) ++ glib_mutex.unlock() ++ return _call_method ++ +diff --git a/pyanaconda/payload/dnf/payload.py b/pyanaconda/payload/dnf/payload.py +index 45003da..0145a62 100644 +--- a/pyanaconda/payload/dnf/payload.py ++++ b/pyanaconda/payload/dnf/payload.py +@@ -36,6 +36,7 @@ import libdnf.repo + import rpm + import re + import pyanaconda.localization ++import time + + from blivet.size import Size + from dnf.const import GROUP_PACKAGE_TYPES +@@ -84,6 +85,7 @@ from pyanaconda.progress import progressQ, progress_message + from pyanaconda.simpleconfig import SimpleConfigFile + from pyanaconda.ui.lib.payload import get_payload, get_source, create_source, set_source, \ + set_up_sources, tear_down_sources ++from pyanaconda.core.glib import glib_mutex + + log = get_packaging_logger() + +@@ -1327,10 +1329,15 @@ class DNFPayload(Payload): + pre_msg = (N_("Preparing transaction from installation source")) + progress_message(pre_msg) + +- queue_instance = multiprocessing.Queue() +- process = multiprocessing.Process(target=do_transaction, +- args=(self._base, queue_instance)) +- process.start() ++ while True: ++ if glib_mutex.trylock(): ++ queue_instance = multiprocessing.Queue() ++ process = multiprocessing.Process(target=do_transaction, ++ args=(self._base, queue_instance)) ++ process.start() ++ glib_mutex.unlock() ++ break ++ time.sleep(0.5) + (token, msg) = queue_instance.get() + # When the installation works correctly it will get 'install' updates + # followed by a 'post' message and then a 'quit' message. +diff --git a/pyanaconda/payload/dnf/utils.py b/pyanaconda/payload/dnf/utils.py +index dfac5c9..0d7c10c 100644 +--- a/pyanaconda/payload/dnf/utils.py ++++ b/pyanaconda/payload/dnf/utils.py +@@ -27,6 +27,7 @@ from pyanaconda.progress import progressQ + from pyanaconda.core import util + from pyanaconda.core.configuration.anaconda import conf + from pyanaconda.product import productName, productVersion ++from pyanaconda.core.glib import glib_mutex + + log = get_packaging_logger() + +@@ -126,6 +127,7 @@ def do_transaction(base, queue_instance): + # always raise a BaseException, so presence of 'quit' without a preceeding + # 'post' message also indicates a problem. + try: ++ glib_mutex.unlock() + display = TransactionProgress(queue_instance) + base.do_transaction(display=display) + exit_reason = "DNF quit" +diff --git a/pyanaconda/ui/gui/spokes/installation_progress.py b/pyanaconda/ui/gui/spokes/installation_progress.py +index 0de742b..2ca0f67 100644 +--- a/pyanaconda/ui/gui/spokes/installation_progress.py ++++ b/pyanaconda/ui/gui/spokes/installation_progress.py +@@ -29,6 +29,7 @@ from pykickstart.constants import KS_SHUTDOWN, KS_REBOOT + from pyanaconda.ui.gui.hubs.summary import SummaryHub + from pyanaconda.ui.gui.spokes import StandaloneSpoke + from pyanaconda.ui.gui.utils import gtk_call_once ++from pyanaconda.core.glib import run_with_mutex + + log = get_module_logger(__name__) + +@@ -185,12 +186,14 @@ class ProgressSpoke(StandaloneSpoke): + + log.debug("The installation has started.") + ++ @run_with_mutex + def _init_progress_bar(self, steps): + self._totalSteps = steps + self._currentStep = 0 + + gtk_call_once(self._progressBar.set_fraction, 0.0) + ++ @run_with_mutex + def _step_progress_bar(self): + if not self._totalSteps: + return +@@ -198,6 +201,7 @@ class ProgressSpoke(StandaloneSpoke): + self._currentStep += 1 + gtk_call_once(self._progressBar.set_fraction, self._currentStep/self._totalSteps) + ++ @run_with_mutex + def _update_progress_message(self, message): + if not self._totalSteps: + return +-- +2.23.0 +