| … | … | @@ -108,7 +108,18 @@ async function runDaemon () { |
| 108 | 108 | const storage = flags.storage || path.join(HOME, '.mirall', 'storage') |
| 109 | 109 | const downloads = flags.downloads || path.join(HOME, '.mirall', 'downloads') |
| 110 | 110 | fs.mkdirSync(path.dirname(sock), { recursive: true }) |
| 111 | | try { fs.unlinkSync(sock) } catch {} // clear a stale socket from a prior run |
| 111 | // Single-daemon guard: if a LIVE daemon already owns this sock, refuse rather than blindly |
| 112 | // unlinking it (which would rip the socket out from under the running daemon and leave two |
| 113 | // processes fighting the single-writer RocksDB lock). Only clear a genuinely stale sock. |
| 114 | let liveDaemon = false |
| 115 | try { |
| 116 | const { Client } = await import('hyper-svc') |
| 117 | const probe = await Client.connectUds(sock) // throws if nothing is listening (stale/absent) |
| 118 | liveDaemon = true |
| 119 | try { probe.close && probe.close() } catch {} |
| 120 | } catch {} |
| 121 | if (liveDaemon && !flags['force-duplicate']) return fail('a mirall daemon is already running on ' + sock + ' (stop it, or pass --force-duplicate with a different --sock to run another)') |
| 122 | if (!liveDaemon) { try { fs.unlinkSync(sock) } catch {} } // clear a stale socket from a prior run |
| 112 | 123 | |
| 113 | 124 | // --bootstrap '[{"host":"127.0.0.1","port":N},…]' points the swarm at a local testnet |
| 114 | 125 | // (deterministic multi-node testing); omit for the public DHT. |