spindb 0.51.4 → 0.51.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/version.js +1 -1
- package/dist/core/cow-copy.js +64 -21
- package/dist/core/cow-copy.js.map +1 -1
- package/package.json +1 -1
package/dist/config/version.js
CHANGED
package/dist/core/cow-copy.js
CHANGED
|
@@ -44,33 +44,76 @@ async function cloneWithStrategy(src, dst, platform) {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
if (platform === 'linux') {
|
|
47
|
-
// ZFS block cloning
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
// `--reflink=
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
47
|
+
// ZFS block cloning refuses a source whose blocks aren't in a committed
|
|
48
|
+
// transaction group yet: `cp --reflink=always` then fails with EAGAIN
|
|
49
|
+
// ("Resource temporarily unavailable"). This is TRANSIENT — it clears once
|
|
50
|
+
// ZFS commits the txg (~zfs_txg_timeout, 5s default). `sync -f` flushes the
|
|
51
|
+
// file but does NOT force the block-clone-ready txg (only `zpool sync` does,
|
|
52
|
+
// which an unprivileged container can't run), so a single attempt routinely
|
|
53
|
+
// loses the race and we'd silently fall back to a full copy — defeating the
|
|
54
|
+
// whole point of branching on ZFS. Retry the reflink across the commit
|
|
55
|
+
// window. A NON-EAGAIN failure (e.g. ENOTSUP on ext4) means the volume has
|
|
56
|
+
// no reflink support at all — fall back immediately, no point retrying.
|
|
57
|
+
//
|
|
58
|
+
// We deliberately avoid `--reflink=auto` because it silently falls back to a
|
|
59
|
+
// full copy, which would make us report 'reflink' when nothing was shared.
|
|
60
|
+
const REFLINK_MAX_ATTEMPTS = 12;
|
|
61
|
+
const REFLINK_RETRY_DELAY_MS = 1500;
|
|
62
|
+
let lastError;
|
|
63
|
+
for (let attempt = 1; attempt <= REFLINK_MAX_ATTEMPTS; attempt++) {
|
|
64
|
+
// Best-effort flush each attempt; harmless if `sync` is unavailable.
|
|
65
|
+
try {
|
|
66
|
+
await spawnAsync('sync', ['-f', src]);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// sync unavailable/failed — proceed; worst case is a fallback full copy.
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
// Force the C locale: `cp` reports its EAGAIN error via strerror(), whose
|
|
73
|
+
// text is localized. In a non-English locale the message wouldn't match
|
|
74
|
+
// isTransientReflinkError() and we'd misclassify the transient txg race as
|
|
75
|
+
// a permanent failure and abandon the reflink.
|
|
76
|
+
await spawnAsync('cp', ['-R', '--reflink=always', src, dst], {
|
|
77
|
+
env: { LC_ALL: 'C' },
|
|
78
|
+
});
|
|
79
|
+
return 'reflink';
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
lastError = error;
|
|
83
|
+
if (!isTransientReflinkError(error)) {
|
|
84
|
+
// No CoW on this volume (ext4 etc.) — retrying can't help.
|
|
85
|
+
return fallbackToDeepCopy(src, dst, error);
|
|
86
|
+
}
|
|
87
|
+
// EAGAIN: the failed clone may have left a partial dst behind — clear it,
|
|
88
|
+
// wait for the txg to commit, and retry.
|
|
89
|
+
await rm(dst, { recursive: true, force: true }).catch(() => { });
|
|
90
|
+
if (attempt < REFLINK_MAX_ATTEMPTS) {
|
|
91
|
+
await new Promise((resolve) => setTimeout(resolve, REFLINK_RETRY_DELAY_MS));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
68
94
|
}
|
|
95
|
+
// Still EAGAIN after the full commit window — fall back to a real copy so the
|
|
96
|
+
// branch still succeeds (just not instant).
|
|
97
|
+
return fallbackToDeepCopy(src, dst, lastError);
|
|
69
98
|
}
|
|
70
99
|
// Windows (NTFS has no reflink) and any unknown platform: full copy.
|
|
71
100
|
await deepCopy(src, dst);
|
|
72
101
|
return 'copy';
|
|
73
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* `cp --reflink=always` fails with EAGAIN ("Resource temporarily unavailable")
|
|
105
|
+
* when ZFS block cloning can't yet clone the source because its blocks aren't in
|
|
106
|
+
* a committed txg — a transient race that clears on the next txg commit.
|
|
107
|
+
* Distinguish it from a real "no reflink support" failure (ENOTSUP/EOPNOTSUPP on
|
|
108
|
+
* ext4, NTFS, etc.) so we retry the former and fall back immediately on the latter.
|
|
109
|
+
*/
|
|
110
|
+
export function isTransientReflinkError(error) {
|
|
111
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
112
|
+
const stderr = typeof error === 'object' && error !== null && 'stderr' in error
|
|
113
|
+
? String(error.stderr ?? '')
|
|
114
|
+
: '';
|
|
115
|
+
return /resource temporarily unavailable|EAGAIN/i.test(`${message} ${stderr}`);
|
|
116
|
+
}
|
|
74
117
|
/**
|
|
75
118
|
* A failed reflink may have left a partial destination behind. Remove it, then
|
|
76
119
|
* perform a guaranteed full copy.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cow-copy.js","sourceRoot":"","sources":["../../core/cow-copy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAU1C;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAW,EACX,GAAW,EACX,OAAwC;IAExC,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAA;IACtD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAC1B,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;IAC1D,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,CAAA;AACrD,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,GAAW,EACX,GAAW,EACX,QAAyB;IAEzB,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,wEAAwE;QACxE,2EAA2E;QAC3E,IAAI,CAAC;YACH,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;YACzC,OAAO,SAAS,CAAA;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,CAAA;QAC5C,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,
|
|
1
|
+
{"version":3,"file":"cow-copy.js","sourceRoot":"","sources":["../../core/cow-copy.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spindb",
|
|
3
|
-
"version": "0.51.
|
|
3
|
+
"version": "0.51.5",
|
|
4
4
|
"author": "Bob Bass <bob@bbass.co>",
|
|
5
5
|
"license": "PolyForm-Noncommercial-1.0.0",
|
|
6
6
|
"description": "Zero-config Docker-free local database containers. Create, backup, and clone a variety of popular databases.",
|