Browse Source

lightningd: close and reopen db across fork for daemonize

Fixes: #1092
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
committed by Christian Decker
parent
commit
b7ed5670d5
  1. 6
      lightningd/lightningd.c
  2. 10
      lightningd/test/run-find_my_path.c
  3. 22
      wallet/db.c
  4. 4
      wallet/db.h
  5. 3
      wallet/test/run-wallet.c

6
lightningd/lightningd.c

@ -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",

10
lightningd/test/run-find_my_path.c

@ -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

@ -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;

4
wallet/db.h

@ -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, "[]"), \

3
wallet/test/run-wallet.c

@ -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…
Cancel
Save