mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-17 19:03:42 +01:00
lightningd: close and reopen db across fork for daemonize
Fixes: #1092 Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
58fae47868
commit
b7ed5670d5
@ -237,11 +237,12 @@ static void init_txfilter(struct wallet *w, struct txfilter *filter)
|
||||
}
|
||||
}
|
||||
|
||||
static void daemonize_but_keep_dir(void)
|
||||
static void daemonize_but_keep_dir(struct lightningd *ld)
|
||||
{
|
||||
/* daemonize moves us into /, but we want to be here */
|
||||
const char *cwd = path_cwd(NULL);
|
||||
|
||||
db_close_for_fork(ld->wallet->db);
|
||||
if (!cwd)
|
||||
fatal("Could not get current directory: %s", strerror(errno));
|
||||
if (!daemonize())
|
||||
@ -252,6 +253,7 @@ static void daemonize_but_keep_dir(void)
|
||||
fatal("Could not return to directory %s: %s",
|
||||
cwd, strerror(errno));
|
||||
|
||||
db_reopen_after_fork(ld->wallet->db);
|
||||
tal_free(cwd);
|
||||
}
|
||||
|
||||
@ -382,7 +384,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* Now we're about to start, become daemon if desired. */
|
||||
if (ld->daemon)
|
||||
daemonize_but_keep_dir();
|
||||
daemonize_but_keep_dir(ld);
|
||||
|
||||
/* Mark ourselves live. */
|
||||
log_info(ld->log, "Server started with public key %s, alias %s (color #%s) and lightningd %s",
|
||||
|
@ -16,12 +16,18 @@ void crashlog_activate(const char *argv0 UNNEEDED, struct log *log UNNEEDED)
|
||||
/* Generated stub for db_begin_transaction_ */
|
||||
void db_begin_transaction_(struct db *db UNNEEDED, const char *location UNNEEDED)
|
||||
{ fprintf(stderr, "db_begin_transaction_ called!\n"); abort(); }
|
||||
/* Generated stub for db_close_for_fork */
|
||||
void db_close_for_fork(struct db *db UNNEEDED)
|
||||
{ fprintf(stderr, "db_close_for_fork called!\n"); abort(); }
|
||||
/* Generated stub for db_commit_transaction */
|
||||
void db_commit_transaction(struct db *db UNNEEDED)
|
||||
{ fprintf(stderr, "db_commit_transaction called!\n"); abort(); }
|
||||
/* Generated stub for db_get_intvar */
|
||||
s64 db_get_intvar(struct db *db UNNEEDED, char *varname UNNEEDED, s64 defval UNNEEDED)
|
||||
{ fprintf(stderr, "db_get_intvar called!\n"); abort(); }
|
||||
/* Generated stub for db_reopen_after_fork */
|
||||
void db_reopen_after_fork(struct db *db UNNEEDED)
|
||||
{ fprintf(stderr, "db_reopen_after_fork called!\n"); abort(); }
|
||||
/* Generated stub for debug_poll */
|
||||
int debug_poll(struct pollfd *fds UNNEEDED, nfds_t nfds UNNEEDED, int timeout UNNEEDED)
|
||||
{ fprintf(stderr, "debug_poll called!\n"); abort(); }
|
||||
@ -35,7 +41,7 @@ void free_htlcs(struct lightningd *ld UNNEEDED, const struct channel *channel UN
|
||||
void gossip_init(struct lightningd *ld UNNEEDED)
|
||||
{ fprintf(stderr, "gossip_init called!\n"); abort(); }
|
||||
/* Generated stub for handle_opts */
|
||||
bool handle_opts(struct lightningd *ld UNNEEDED, int argc UNNEEDED, char *argv[] UNUSED)
|
||||
bool handle_opts(struct lightningd *ld UNNEEDED, int argc UNNEEDED, char *argv[])
|
||||
{ fprintf(stderr, "handle_opts called!\n"); abort(); }
|
||||
/* Generated stub for hash_htlc_key */
|
||||
size_t hash_htlc_key(const struct htlc_key *htlc_key UNNEEDED)
|
||||
@ -78,7 +84,7 @@ void subd_shutdown(struct subd *subd UNNEEDED, unsigned int seconds UNNEEDED)
|
||||
void timer_expired(tal_t *ctx UNNEEDED, struct timer *timer UNNEEDED)
|
||||
{ fprintf(stderr, "timer_expired called!\n"); abort(); }
|
||||
/* Generated stub for txfilter_add_derkey */
|
||||
void txfilter_add_derkey(struct txfilter *filter UNNEEDED, u8 derkey[PUBKEY_DER_LEN] UNUSED)
|
||||
void txfilter_add_derkey(struct txfilter *filter UNNEEDED, u8 derkey[PUBKEY_DER_LEN])
|
||||
{ fprintf(stderr, "txfilter_add_derkey called!\n"); abort(); }
|
||||
/* Generated stub for txfilter_new */
|
||||
struct txfilter *txfilter_new(const tal_t *ctx UNNEEDED)
|
||||
|
22
wallet/db.c
22
wallet/db.c
@ -432,6 +432,28 @@ struct db *db_setup(const tal_t *ctx, struct log *log)
|
||||
return db;
|
||||
}
|
||||
|
||||
void db_close_for_fork(struct db *db)
|
||||
{
|
||||
/* https://www.sqlite.org/faq.html#q6
|
||||
*
|
||||
* Under Unix, you should not carry an open SQLite database across a
|
||||
* fork() system call into the child process. */
|
||||
if (sqlite3_close(db->sql) != SQLITE_OK)
|
||||
fatal("sqlite3_close: %s", sqlite3_errmsg(db->sql));
|
||||
db->sql = NULL;
|
||||
}
|
||||
|
||||
void db_reopen_after_fork(struct db *db)
|
||||
{
|
||||
int err = sqlite3_open_v2(db->filename, &db->sql,
|
||||
SQLITE_OPEN_READWRITE, NULL);
|
||||
|
||||
if (err != SQLITE_OK) {
|
||||
fatal("failed to re-open database %s: %s", db->filename,
|
||||
sqlite3_errstr(err));
|
||||
}
|
||||
}
|
||||
|
||||
s64 db_get_intvar(struct db *db, char *varname, s64 defval)
|
||||
{
|
||||
int err;
|
||||
|
@ -113,6 +113,10 @@ bool db_exec_prepared_mayfail_(const char *caller,
|
||||
struct db *db,
|
||||
sqlite3_stmt *stmt);
|
||||
|
||||
/* Do not keep db open across a fork: needed for --daemon */
|
||||
void db_close_for_fork(struct db *db);
|
||||
void db_reopen_after_fork(struct db *db);
|
||||
|
||||
#define sqlite3_column_arr(ctx, stmt, col, type) \
|
||||
((type *)sqlite3_column_arr_((ctx), (stmt), (col), \
|
||||
sizeof(type), TAL_LABEL(type, "[]"), \
|
||||
|
@ -230,9 +230,6 @@ void log_add(struct log *log UNNEEDED, const char *fmt UNNEEDED, ...)
|
||||
void log_io(struct log *log UNNEEDED, enum log_level dir UNNEEDED, const char *comment UNNEEDED,
|
||||
const void *data UNNEEDED, size_t len UNNEEDED)
|
||||
{ fprintf(stderr, "log_io called!\n"); abort(); }
|
||||
/* Generated stub for logv_add */
|
||||
void logv_add(struct log *log UNNEEDED, const char *fmt UNNEEDED, va_list ap UNNEEDED)
|
||||
{ fprintf(stderr, "logv_add called!\n"); abort(); }
|
||||
/* Generated stub for new_json_result */
|
||||
struct json_result *new_json_result(const tal_t *ctx UNNEEDED)
|
||||
{ fprintf(stderr, "new_json_result called!\n"); abort(); }
|
||||
|
Loading…
Reference in New Issue
Block a user