diff options
-rw-r--r-- | cmogstored.c | 1 | ||||
-rw-r--r-- | cmogstored.h | 1 | ||||
-rw-r--r-- | svc.c | 29 | ||||
-rw-r--r-- | svc_dev.c | 5 |
4 files changed, 35 insertions, 1 deletions
diff --git a/cmogstored.c b/cmogstored.c index 64b932d..31bdd85 100644 --- a/cmogstored.c +++ b/cmogstored.c @@ -419,6 +419,7 @@ static void fork_worker(unsigned worker_id) mog_process_register(pid, worker_id); } else if (pid == 0) { mog_process_reset(); + mog_svc_each(mog_svc_atfork_child, &parent); /* worker will call mog_intr_enable() later in notify loop */ run_worker(parent); diff --git a/cmogstored.h b/cmogstored.h index 3c1801c..1006fc3 100644 --- a/cmogstored.h +++ b/cmogstored.h @@ -371,6 +371,7 @@ bool mog_svc_start_each(void *svc_ptr, void *have_mgmt_ptr); void mog_svc_thrpool_rescale(struct mog_svc *, unsigned ndev_new); void mog_svc_aio_threads_enqueue(struct mog_svc *, unsigned nr); void mog_svc_aio_threads_handler(void); +bool mog_svc_atfork_child(void *svc_ptr, void *parent); /* dev.c */ struct mog_dev *mog_dev_for(struct mog_svc *, uint32_t mog_devid, bool update); @@ -69,6 +69,35 @@ static void svc_once(void) atexit(svc_atexit); } +bool mog_svc_atfork_child(void *svc_ptr, void *parent) +{ + struct mog_svc *svc = svc_ptr; + pid_t ppid = *((pid_t *)parent); + const char *failfn; + + if (closedir(svc->dir) < 0) { + failfn = "closedir"; + goto err; + } + + svc->dir = opendir(svc->docroot); + if (svc->dir == NULL) { + failfn = "opendir"; + goto err; + } + + svc->docroot_fd = dirfd(svc->dir); + if (svc->docroot_fd < 0) { + failfn = "dirfd"; + goto err; + } + return true; +err: + syslog(LOG_ERR, "%s(%s) failed with: %m", failfn, svc->docroot); + kill(ppid, SIGTERM); + return false; +} + struct mog_svc * mog_svc_new(const char *docroot) { struct mog_svc *svc; @@ -129,7 +129,10 @@ static int svc_scandev(struct mog_svc *svc, unsigned *nr, mog_scandev_cb cb) switch (hash_insert_if_absent(devhash, dev, NULL)) { case 0: - free(dev); + /* do not free dev, it is in svc->by_mog_devid */ + syslog(LOG_ERR, + "%s/%s seen twice in readdir (BUG?)", + svc->docroot, ent->d_name); break; case 1: (*nr)++; |