From unknown Sun Jun 22 08:05:50 2025 X-Loop: help-debbugs@gnu.org Subject: [bug#70350] [PATCH] pack: =?UTF-8?Q?=E2=80=98-R=E2=80=99?= (once) does not include fakechroot fallback. Resent-From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix@cbaines.net, dev@jpoiret.xyz, ludo@gnu.org, othacehe@gnu.org, rekado@elephly.net, zimon.toutoune@gmail.com, me@tobias.gr, guix-patches@gnu.org Resent-Date: Fri, 12 Apr 2024 10:02:04 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 70350 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 70350@debbugs.gnu.org Cc: Ludovic =?UTF-8?Q?Court=C3=A8s?= , romain.garbage@inria.fr, Christopher Baines , Josselin Poiret , Ludovic =?UTF-8?Q?Court=C3=A8s?= , Mathieu Othacehe , Ricardo Wurmus , Simon Tournier , Tobias Geerinckx-Rice X-Debbugs-Original-To: guix-patches@gnu.org X-Debbugs-Original-Xcc: Christopher Baines , Josselin Poiret , Ludovic =?UTF-8?Q?Court=C3=A8s?= , Mathieu Othacehe , Ricardo Wurmus , Simon Tournier , Tobias Geerinckx-Rice Received: via spool by submit@debbugs.gnu.org id=B.17129161095254 (code B ref -1); Fri, 12 Apr 2024 10:02:04 +0000 Received: (at submit) by debbugs.gnu.org; 12 Apr 2024 10:01:49 +0000 Received: from localhost ([127.0.0.1]:57917 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1rvDj9-0001MW-Mn for submit@debbugs.gnu.org; Fri, 12 Apr 2024 06:01:49 -0400 Received: from lists.gnu.org ([2001:470:142::17]:49802) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1rvDj3-0001KX-D0 for submit@debbugs.gnu.org; Fri, 12 Apr 2024 06:01:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rvDin-0002iu-MP for guix-patches@gnu.org; Fri, 12 Apr 2024 06:01:25 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rvDim-000190-Ep; Fri, 12 Apr 2024 06:01:24 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:Date:Subject:To:From:in-reply-to: references; bh=wKoIiFhKzzqwldiPEG+NQ0gzgMrioWP0sLeN6o1yCW4=; b=MlizuLosbeH9p3 mpjmYvNa08H6BDD3ubtq1KUrG5PnfdhiOVNgQzzc0PiXZMwD4QSxNawVbSn1EdSc0O6mNmkaS9dLY 4IAphg8OfkwGLWj7KP0P4meuLk9D/GqogWWFUEsPCzOytFPOUL+hWGQm3ALbMkRo+KeQe8A2t9v+e JQAOEk718Nd/JF3mNbZEj1LgU6RgcTH+tUXIN5K+NDMTubSySywD/2F8nB+BYptPQ/y5sAethVLJ8 M0npzHQE2dL+xqKm+0YszLQt3XlwR9WEzXhDie/509kfmnHTLraDGNRrReLK0C5aWNyZTK64UV+S6 NXPxIFGlDtMQc+6umB2Q==; From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Date: Fri, 12 Apr 2024 12:01:17 +0200 Message-ID: X-Mailer: git-send-email 2.41.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Score: -0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) From: Ludovic Courtès Previously, ‘guix pack -R’ would build a wrapper containing both the “userns” and “fakechroot” engines, instead of providing nothing but the “userns” engine as the manual says. This patch fixes it. * guix/scripts/pack.scm (wrapped-package): Add #:fakechroot? [build]: When FAKECHROOT? is false, ‘elf-loader-compile-flags’ always returns '(). Change-Id: Ic75cc8c36bf0a3881f299b274d78bd9fc2d4e2bb --- guix/scripts/pack.scm | 78 ++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 38 deletions(-) Hello! I stumbled upon the bug whereby ‘guix pack -RR’, just like (guix build gremlins), loads entire ELF files in memory just to parse them, which can OOM if said files are large enough: https://issues.guix.gnu.org/59365#4 I thought passing a single ‘-R’ would allow me to work around the problem, since the fakechroot engine was not supposed to be compiled in this case, but it turns out it was. This patch makes ‘guix pack’ conform with the doc: with a single ‘-R’, only the “userns” engine gets compiled. Thoughts? Ludo’. diff --git a/guix/scripts/pack.scm b/guix/scripts/pack.scm index 3e45c34895..fe4df042d7 100644 --- a/guix/scripts/pack.scm +++ b/guix/scripts/pack.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2015, 2017-2023 Ludovic Courtès +;;; Copyright © 2015, 2017-2024 Ludovic Courtès ;;; Copyright © 2017, 2018 Ricardo Wurmus ;;; Copyright © 2018 Konrad Hinsen ;;; Copyright © 2018 Chris Marusich @@ -1066,10 +1066,11 @@ (define* (wrapped-package package #:optional (output* "out") (compiler (c-compiler)) - #:key proot?) + #:key proot? (fakechroot? proot?)) "Return the OUTPUT of PACKAGE with its binaries wrapped such that they are relocatable. When PROOT? is true, include PRoot in the result and use it as a -last resort for relocation." +last resort for relocation. When FAKECHROOT? is true, include +libfakechroot.so and related ld.so machinery as a fallback." (define runner (local-file (search-auxiliary-file "run-in-namespace.c"))) @@ -1161,43 +1162,44 @@ (define* (wrapped-package package (define (elf-loader-compile-flags program) ;; Return the cpp flags defining macros for the ld.so/fakechroot ;; wrapper of PROGRAM. + #$(if fakechroot? + ;; TODO: Handle scripts by wrapping their interpreter. + #~(if (elf-file? program) + (let* ((bv (call-with-input-file program + get-bytevector-all)) + (elf (parse-elf bv)) + (interp (elf-interpreter elf)) + (gconv (and interp + (string-append (dirname interp) + "/gconv")))) + (if interp + (list (string-append "-DPROGRAM_INTERPRETER=\"" + interp "\"") + (string-append "-DFAKECHROOT_LIBRARY=\"" + #$(fakechroot-library) "\"") - ;; TODO: Handle scripts by wrapping their interpreter. - (if (elf-file? program) - (let* ((bv (call-with-input-file program - get-bytevector-all)) - (elf (parse-elf bv)) - (interp (elf-interpreter elf)) - (gconv (and interp - (string-append (dirname interp) - "/gconv")))) - (if interp - (list (string-append "-DPROGRAM_INTERPRETER=\"" - interp "\"") - (string-append "-DFAKECHROOT_LIBRARY=\"" - #$(fakechroot-library) "\"") + (string-append "-DLOADER_AUDIT_MODULE=\"" + #$(audit-module) "\"") - (string-append "-DLOADER_AUDIT_MODULE=\"" - #$(audit-module) "\"") - - ;; XXX: Normally (runpath #$(audit-module)) is - ;; enough. However, to work around - ;; - ;; (glibc <= 2.32), pass the whole search path of - ;; PROGRAM, which presumably is a superset of that - ;; of the audit module. - (string-append "-DLOADER_AUDIT_RUNPATH={ " - (string-join - (map object->string - (runpath program)) - ", " 'suffix) - "NULL }") - (if gconv - (string-append "-DGCONV_DIRECTORY=\"" - gconv "\"") - "-UGCONV_DIRECTORY")) - '())) - '())) + ;; XXX: Normally (runpath #$(audit-module)) is + ;; enough. However, to work around + ;; + ;; (glibc <= 2.32), pass the whole search path of + ;; PROGRAM, which presumably is a superset of that + ;; of the audit module. + (string-append "-DLOADER_AUDIT_RUNPATH={ " + (string-join + (map object->string + (runpath program)) + ", " 'suffix) + "NULL }") + (if gconv + (string-append "-DGCONV_DIRECTORY=\"" + gconv "\"") + "-UGCONV_DIRECTORY")) + '())) + '()) + #~'())) (define (build-wrapper program) ;; Build a user-namespace wrapper for PROGRAM. base-commit: 4e7337536ba41e888a601c92fada8a4adca9d2c6 -- 2.41.0 From unknown Sun Jun 22 08:05:50 2025 MIME-Version: 1.0 X-Mailer: MIME-tools 5.505 (Entity 5.505) X-Loop: help-debbugs@gnu.org From: help-debbugs@gnu.org (GNU bug Tracking System) To: Ludovic =?UTF-8?Q?Court=C3=A8s?= Subject: bug#70350: closed (Re: [bug#70350] [PATCH] pack: =?UTF-8?Q?=E2=80=98-R=E2=80=99?= (once) does not include fakechroot fallback.) Message-ID: References: <875xvzztqj.fsf@gnu.org> X-Gnu-PR-Message: they-closed 70350 X-Gnu-PR-Package: guix-patches X-Gnu-PR-Keywords: patch Reply-To: 70350@debbugs.gnu.org Date: Mon, 29 Apr 2024 22:33:01 +0000 Content-Type: multipart/mixed; boundary="----------=_1714429981-16951-1" This is a multi-part message in MIME format... ------------=_1714429981-16951-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Your bug report #70350: [PATCH] pack: =E2=80=98-R=E2=80=99 (once) does not include fakechro= ot fallback. which was filed against the guix-patches package, has been closed. The explanation is attached below, along with your original report. If you require more details, please reply to 70350@debbugs.gnu.org. --=20 70350: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D70350 GNU Bug Tracking System Contact help-debbugs@gnu.org with problems ------------=_1714429981-16951-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at 70350-done) by debbugs.gnu.org; 29 Apr 2024 22:32:21 +0000 Received: from localhost ([127.0.0.1]:58895 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1s1ZXo-0004PD-JT for submit@debbugs.gnu.org; Mon, 29 Apr 2024 18:32:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:36042) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1s1ZXm-0004P6-Gk for 70350-done@debbugs.gnu.org; Mon, 29 Apr 2024 18:32:19 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1s1ZXI-00056z-Rp; Mon, 29 Apr 2024 18:31:50 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:Date:References:In-Reply-To:Subject:To: From; bh=rIElSOKSWw5uFqaHRiruZWHWIzwyLgEE0ZZXGjlIvPU=; b=CzKlJu7qHr9tfHBJSV/m RhkJX8OpbFs/6mjeXZ5m+v8qWG8jHZQ+Y5cqI0i4Qg0++wsz0xSDfylj525l0j5MXMXxXOjn69O3I qAyegt0QWsTb1ACdByBUg8Jyvgvsg8dWXRVod2Xbi9HcC2VeCqWUGkKlMSP2+lPpTGyESxtpqQR2x D5rY8mY7fRie3q80krba6JV5EICzPnCyEuR+pPmXF8CYx+weOvvBJPFVx914I/bYJcEiP14CJPBZ+ d/YiCbOzD/Z5gFNhMxxg8wHmHdTuuFznHE/w5Q+zM7nQRYIqr9EbDmgPy1fxb6UcHhPnULRBWJTMh qDZNT1C7L8HacQ==; From: =?utf-8?Q?Ludovic_Court=C3=A8s?= To: 70350-done@debbugs.gnu.org Subject: Re: [bug#70350] [PATCH] pack: =?utf-8?B?4oCYLVLigJk=?= (once) does not include fakechroot fallback. In-Reply-To: ("Ludovic =?utf-8?Q?Court=C3=A8s=22's?= message of "Fri, 12 Apr 2024 12:01:17 +0200") References: Date: Tue, 30 Apr 2024 00:31:16 +0200 Message-ID: <875xvzztqj.fsf@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 70350-done Cc: Josselin Poiret , Tobias Geerinckx-Rice , Simon Tournier , Mathieu Othacehe , romain.garbage@inria.fr, Ricardo Wurmus , Christopher Baines X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Ludovic Court=C3=A8s skribis: > From: Ludovic Court=C3=A8s > > Previously, =E2=80=98guix pack -R=E2=80=99 would build a wrapper containi= ng both the > =E2=80=9Cuserns=E2=80=9D and =E2=80=9Cfakechroot=E2=80=9D engines, instea= d of providing nothing but the > =E2=80=9Cuserns=E2=80=9D engine as the manual says. This patch fixes it. > > * guix/scripts/pack.scm (wrapped-package): Add #:fakechroot? > [build]: When FAKECHROOT? is false, =E2=80=98elf-loader-compile-flags=E2= =80=99 always > returns '(). > > Change-Id: Ic75cc8c36bf0a3881f299b274d78bd9fc2d4e2bb Pushed as a15db2ee5090441c08d9a642d9284ef3ccdd95d0. Ludo'. ------------=_1714429981-16951-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at submit) by debbugs.gnu.org; 12 Apr 2024 10:01:49 +0000 Received: from localhost ([127.0.0.1]:57917 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1rvDj9-0001MW-Mn for submit@debbugs.gnu.org; Fri, 12 Apr 2024 06:01:49 -0400 Received: from lists.gnu.org ([2001:470:142::17]:49802) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1rvDj3-0001KX-D0 for submit@debbugs.gnu.org; Fri, 12 Apr 2024 06:01:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rvDin-0002iu-MP for guix-patches@gnu.org; Fri, 12 Apr 2024 06:01:25 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rvDim-000190-Ep; Fri, 12 Apr 2024 06:01:24 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:Date:Subject:To:From:in-reply-to: references; bh=wKoIiFhKzzqwldiPEG+NQ0gzgMrioWP0sLeN6o1yCW4=; b=MlizuLosbeH9p3 mpjmYvNa08H6BDD3ubtq1KUrG5PnfdhiOVNgQzzc0PiXZMwD4QSxNawVbSn1EdSc0O6mNmkaS9dLY 4IAphg8OfkwGLWj7KP0P4meuLk9D/GqogWWFUEsPCzOytFPOUL+hWGQm3ALbMkRo+KeQe8A2t9v+e JQAOEk718Nd/JF3mNbZEj1LgU6RgcTH+tUXIN5K+NDMTubSySywD/2F8nB+BYptPQ/y5sAethVLJ8 M0npzHQE2dL+xqKm+0YszLQt3XlwR9WEzXhDie/509kfmnHTLraDGNRrReLK0C5aWNyZTK64UV+S6 NXPxIFGlDtMQc+6umB2Q==; From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= To: guix-patches@gnu.org Subject: [PATCH] =?UTF-8?q?pack:=20=E2=80=98-R=E2=80=99=20(once)=20does=20?= =?UTF-8?q?not=20include=20fakechroot=20fallback.?= Date: Fri, 12 Apr 2024 12:01:17 +0200 Message-ID: X-Mailer: git-send-email 2.41.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-Debbugs-Cc: Christopher Baines , Josselin Poiret , Ludovic Courtès , Mathieu Othacehe , Ricardo Wurmus , Simon Tournier , Tobias Geerinckx-Rice Content-Transfer-Encoding: 8bit X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: submit Cc: =?UTF-8?q?Ludovic=20Court=C3=A8s?= , romain.garbage@inria.fr X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) From: Ludovic Courtès Previously, ‘guix pack -R’ would build a wrapper containing both the “userns” and “fakechroot” engines, instead of providing nothing but the “userns” engine as the manual says. This patch fixes it. * guix/scripts/pack.scm (wrapped-package): Add #:fakechroot? [build]: When FAKECHROOT? is false, ‘elf-loader-compile-flags’ always returns '(). Change-Id: Ic75cc8c36bf0a3881f299b274d78bd9fc2d4e2bb --- guix/scripts/pack.scm | 78 ++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 38 deletions(-) Hello! I stumbled upon the bug whereby ‘guix pack -RR’, just like (guix build gremlins), loads entire ELF files in memory just to parse them, which can OOM if said files are large enough: https://issues.guix.gnu.org/59365#4 I thought passing a single ‘-R’ would allow me to work around the problem, since the fakechroot engine was not supposed to be compiled in this case, but it turns out it was. This patch makes ‘guix pack’ conform with the doc: with a single ‘-R’, only the “userns” engine gets compiled. Thoughts? Ludo’. diff --git a/guix/scripts/pack.scm b/guix/scripts/pack.scm index 3e45c34895..fe4df042d7 100644 --- a/guix/scripts/pack.scm +++ b/guix/scripts/pack.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2015, 2017-2023 Ludovic Courtès +;;; Copyright © 2015, 2017-2024 Ludovic Courtès ;;; Copyright © 2017, 2018 Ricardo Wurmus ;;; Copyright © 2018 Konrad Hinsen ;;; Copyright © 2018 Chris Marusich @@ -1066,10 +1066,11 @@ (define* (wrapped-package package #:optional (output* "out") (compiler (c-compiler)) - #:key proot?) + #:key proot? (fakechroot? proot?)) "Return the OUTPUT of PACKAGE with its binaries wrapped such that they are relocatable. When PROOT? is true, include PRoot in the result and use it as a -last resort for relocation." +last resort for relocation. When FAKECHROOT? is true, include +libfakechroot.so and related ld.so machinery as a fallback." (define runner (local-file (search-auxiliary-file "run-in-namespace.c"))) @@ -1161,43 +1162,44 @@ (define* (wrapped-package package (define (elf-loader-compile-flags program) ;; Return the cpp flags defining macros for the ld.so/fakechroot ;; wrapper of PROGRAM. + #$(if fakechroot? + ;; TODO: Handle scripts by wrapping their interpreter. + #~(if (elf-file? program) + (let* ((bv (call-with-input-file program + get-bytevector-all)) + (elf (parse-elf bv)) + (interp (elf-interpreter elf)) + (gconv (and interp + (string-append (dirname interp) + "/gconv")))) + (if interp + (list (string-append "-DPROGRAM_INTERPRETER=\"" + interp "\"") + (string-append "-DFAKECHROOT_LIBRARY=\"" + #$(fakechroot-library) "\"") - ;; TODO: Handle scripts by wrapping their interpreter. - (if (elf-file? program) - (let* ((bv (call-with-input-file program - get-bytevector-all)) - (elf (parse-elf bv)) - (interp (elf-interpreter elf)) - (gconv (and interp - (string-append (dirname interp) - "/gconv")))) - (if interp - (list (string-append "-DPROGRAM_INTERPRETER=\"" - interp "\"") - (string-append "-DFAKECHROOT_LIBRARY=\"" - #$(fakechroot-library) "\"") + (string-append "-DLOADER_AUDIT_MODULE=\"" + #$(audit-module) "\"") - (string-append "-DLOADER_AUDIT_MODULE=\"" - #$(audit-module) "\"") - - ;; XXX: Normally (runpath #$(audit-module)) is - ;; enough. However, to work around - ;; - ;; (glibc <= 2.32), pass the whole search path of - ;; PROGRAM, which presumably is a superset of that - ;; of the audit module. - (string-append "-DLOADER_AUDIT_RUNPATH={ " - (string-join - (map object->string - (runpath program)) - ", " 'suffix) - "NULL }") - (if gconv - (string-append "-DGCONV_DIRECTORY=\"" - gconv "\"") - "-UGCONV_DIRECTORY")) - '())) - '())) + ;; XXX: Normally (runpath #$(audit-module)) is + ;; enough. However, to work around + ;; + ;; (glibc <= 2.32), pass the whole search path of + ;; PROGRAM, which presumably is a superset of that + ;; of the audit module. + (string-append "-DLOADER_AUDIT_RUNPATH={ " + (string-join + (map object->string + (runpath program)) + ", " 'suffix) + "NULL }") + (if gconv + (string-append "-DGCONV_DIRECTORY=\"" + gconv "\"") + "-UGCONV_DIRECTORY")) + '())) + '()) + #~'())) (define (build-wrapper program) ;; Build a user-namespace wrapper for PROGRAM. base-commit: 4e7337536ba41e888a601c92fada8a4adca9d2c6 -- 2.41.0 ------------=_1714429981-16951-1--