From d686ce12b65c29d968db93f027b4b85fb59359f5 Mon Sep 17 00:00:00 2001 From: ed Date: Mon, 25 Jul 2022 02:07:59 +0200 Subject: [PATCH] lsof db on stuck transaction --- copyparty/up2k.py | 16 +++++++++++----- copyparty/util.py | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/copyparty/up2k.py b/copyparty/up2k.py index d02af739..707060d7 100644 --- a/copyparty/up2k.py +++ b/copyparty/up2k.py @@ -32,6 +32,7 @@ from .util import ( absreal, atomic_move, djoin, + db_ex_chk, fsenc, min_ex, quotep, @@ -645,7 +646,7 @@ class Up2k(object): with self.mutex: reg = self.register_vpath(top, vol.flags) assert reg and self.pp - cur, _ = reg + cur, db_path = reg db = Dbw(cur, 0, time.time()) self.pp.n = next(db.c.execute("select count(w) from up"))[0] @@ -665,7 +666,8 @@ class Up2k(object): try: n_add = self._build_dir(db, top, set(excl), top, rtop, rei, reh, []) n_rm = self._drop_lost(db.c, top) - except: + except Exception as ex: + db_ex_chk(self.log, ex, db_path) t = "failed to index volume [{}]:\n{}" self.log(t.format(top, min_ex()), c=1) @@ -1946,9 +1948,13 @@ class Up2k(object): if not cur: return False - self.db_rm(cur, rd, fn) - self.db_add(cur, wark, rd, fn, lmod, sz, ip, at) - cur.connection.commit() + try: + self.db_rm(cur, rd, fn) + self.db_add(cur, wark, rd, fn, lmod, sz, ip, at) + cur.connection.commit() + except Exception as ex: + db_ex_chk(self.log, ex, self.register_vpath(ptop, {})[1]) + raise if "e2t" in self.flags[ptop]: self.tagq.put((ptop, wark, rd, fn)) diff --git a/copyparty/util.py b/copyparty/util.py index 6497a15b..0a758067 100644 --- a/copyparty/util.py +++ b/copyparty/util.py @@ -1207,6 +1207,20 @@ def s3dec(rd: str, fn: str) -> tuple[str, str]: return ret[0], ret[1] +def db_ex_chk(log: "NamedLogger", ex: Exception, db_path: str) -> None: + if str(ex) != "database is locked": + return False + + try: + rc, so, se = runcmd([b"lsof", fsenc(db_path)]) + zs = (so.strip() + "\n" + se.strip()).strip() + log("lsof {} = {}\n{}".format(db_path, rc, zs), 3) + except: + pass + + return True + + def atomic_move(usrc: str, udst: str) -> None: src = fsenc(usrc) dst = fsenc(udst)