From 3a0d882c5e428343b2ec346f8ac1c80249546ca7 Mon Sep 17 00:00:00 2001 From: ed Date: Tue, 22 Oct 2024 20:53:19 +0000 Subject: [PATCH] fix NetMap `-j0` compat would crash on startup if `-j0` was combined with `--ipa` or `--ipu` --- copyparty/svchub.py | 14 +++++++++++--- copyparty/util.py | 24 ++++++++++++++++++------ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/copyparty/svchub.py b/copyparty/svchub.py index 719e4507..a804b568 100644 --- a/copyparty/svchub.py +++ b/copyparty/svchub.py @@ -223,7 +223,7 @@ class SvcHub(object): args.chpw_no = noch if args.ipu: - iu, nm = load_ipu(self.log, args.ipu) + iu, nm = load_ipu(self.log, args.ipu, True) setattr(args, "ipu_iu", iu) setattr(args, "ipu_nm", nm) @@ -378,6 +378,14 @@ class SvcHub(object): self.broker = Broker(self) + # create netmaps early to avoid firewall gaps, + # but the mutex blocks multiprocessing startup + for zs in "ipu_iu ftp_ipa_nm tftp_ipa_nm".split(): + try: + getattr(args, zs).mutex = threading.Lock() + except: + pass + def setup_session_db(self) -> None: if not HAVE_SQLITE3: self.args.no_ses = True @@ -761,8 +769,8 @@ class SvcHub(object): al.idp_h_grp = al.idp_h_grp.lower() al.idp_h_key = al.idp_h_key.lower() - al.ftp_ipa_nm = build_netmap(al.ftp_ipa or al.ipa) - al.tftp_ipa_nm = build_netmap(al.tftp_ipa or al.ipa) + al.ftp_ipa_nm = build_netmap(al.ftp_ipa or al.ipa, True) + al.tftp_ipa_nm = build_netmap(al.tftp_ipa or al.ipa, True) mte = ODict.fromkeys(DEF_MTE.split(","), True) al.mte = odfusion(mte, al.mte) diff --git a/copyparty/util.py b/copyparty/util.py index 61264e7d..d9c9d2e7 100644 --- a/copyparty/util.py +++ b/copyparty/util.py @@ -669,13 +669,20 @@ class HLog(logging.Handler): class NetMap(object): def __init__( - self, ips: list[str], cidrs: list[str], keep_lo=False, strict_cidr=False + self, + ips: list[str], + cidrs: list[str], + keep_lo=False, + strict_cidr=False, + defer_mutex=False, ) -> None: """ ips: list of plain ipv4/ipv6 IPs, not cidr cidrs: list of cidr-notation IPs (ip/prefix) """ - self.mutex = threading.Lock() + + # fails multiprocessing; defer assignment + self.mutex: Optional[threading.Lock] = None if defer_mutex else threading.Lock() if "::" in ips: ips = [x for x in ips if x != "::"] + list( @@ -714,6 +721,9 @@ class NetMap(object): try: return self.cache[ip] except: + # intentionally crash the calling thread if unset: + assert self.mutex # type: ignore # !rm + with self.mutex: return self._map(ip) @@ -2654,7 +2664,7 @@ def list_ips() -> list[str]: return list(ret) -def build_netmap(csv: str): +def build_netmap(csv: str, defer_mutex: bool = False): csv = csv.lower().strip() if csv in ("any", "all", "no", ",", ""): @@ -2689,10 +2699,12 @@ def build_netmap(csv: str): cidrs.append(zs) ips = [x.split("/")[0] for x in cidrs] - return NetMap(ips, cidrs, True) + return NetMap(ips, cidrs, True, False, defer_mutex) -def load_ipu(log: "RootLogger", ipus: list[str]) -> tuple[dict[str, str], NetMap]: +def load_ipu( + log: "RootLogger", ipus: list[str], defer_mutex: bool = False +) -> tuple[dict[str, str], NetMap]: ip_u = {"": "*"} cidr_u = {} for ipu in ipus: @@ -2709,7 +2721,7 @@ def load_ipu(log: "RootLogger", ipus: list[str]) -> tuple[dict[str, str], NetMap cidr_u[cidr] = uname ip_u[cip] = uname try: - nm = NetMap(["::"], list(cidr_u.keys()), True, True) + nm = NetMap(["::"], list(cidr_u.keys()), True, True, defer_mutex) except Exception as ex: t = "failed to translate --ipu into netmap, probably due to invalid config: %r" log("root", t % (ex,), 1)