diff options
Diffstat (limited to 'tools/polldaemon.c')
-rw-r--r-- | tools/polldaemon.c | 68 |
1 files changed, 51 insertions, 17 deletions
diff --git a/tools/polldaemon.c b/tools/polldaemon.c index 50579ba..a9138a1 100644 --- a/tools/polldaemon.c +++ b/tools/polldaemon.c @@ -32,6 +32,8 @@ static void _sigchld_handler(int sig __attribute__((unused))) */ static int _become_daemon(struct cmd_context *cmd) { + static const char devnull[] = "/dev/null"; + int null_fd; pid_t pid; struct sigaction act = { {_sigchld_handler}, @@ -42,6 +44,8 @@ static int _become_daemon(struct cmd_context *cmd) sigaction(SIGCHLD, &act, NULL); + sync_local_dev_names(cmd); /* Flush ops and reset dm cookie */ + if ((pid = fork()) == -1) { log_error("fork failed: %s", strerror(errno)); return -1; @@ -55,16 +59,33 @@ static int _become_daemon(struct cmd_context *cmd) if (setsid() == -1) log_error("Background process failed to setsid: %s", strerror(errno)); - init_verbose(VERBOSE_BASE_LEVEL); - close(STDIN_FILENO); - close(STDOUT_FILENO); - close(STDERR_FILENO); + /* For poll debugging it's best to disable for compilation */ +#if 1 + if ((null_fd = open(devnull, O_RDWR)) == -1) { + log_sys_error("open", devnull); + _exit(ECMD_FAILED); + } + + if ((dup2(null_fd, STDIN_FILENO) < 0) || /* reopen stdin */ + (dup2(null_fd, STDOUT_FILENO) < 0) || /* reopen stdout */ + (dup2(null_fd, STDERR_FILENO) < 0)) { /* reopen stderr */ + log_sys_error("dup2", "redirect"); + (void) close(null_fd); + _exit(ECMD_FAILED); + } + + if (null_fd > STDERR_FILENO) + (void) close(null_fd); + init_verbose(VERBOSE_BASE_LEVEL); +#endif strncpy(*cmd->argv, "(lvm2)", strlen(*cmd->argv)); reset_locking(); - lvmcache_init(); + if (!lvmcache_init()) + /* FIXME Clean up properly here */ + _exit(ECMD_FAILED); dev_close_all(); return 1; @@ -87,8 +108,8 @@ progress_t poll_mirror_progress(struct cmd_context *cmd, overall_percent = copy_percent(lv); if (parms->progress_display) - log_print("%s: %s: %.1f%%", name, parms->progress_title, - percent_to_float(overall_percent)); + log_print_unless_silent("%s: %s: %.1f%%", name, parms->progress_title, + percent_to_float(overall_percent)); else log_verbose("%s: %s: %.1f%%", name, parms->progress_title, percent_to_float(overall_percent)); @@ -144,7 +165,7 @@ static int _check_lv_status(struct cmd_context *cmd, /* Finished? Or progress to next segment? */ if (progress == PROGRESS_FINISHED_ALL) { if (!parms->poll_fns->finish_copy(cmd, vg, lv, lvs_changed)) - return 0; + return_0; } else { if (parms->poll_fns->update_metadata && !parms->poll_fns->update_metadata(cmd, vg, lv, lvs_changed, 0)) { @@ -183,26 +204,34 @@ static int _wait_for_single_lv(struct cmd_context *cmd, const char *name, const /* Locks the (possibly renamed) VG again */ vg = parms->poll_fns->get_copy_vg(cmd, name, uuid); if (vg_read_error(vg)) { - free_vg(vg); + release_vg(vg); log_error("ABORTING: Can't reread VG for %s", name); /* What more could we do here? */ return 0; } - if (!(lv = parms->poll_fns->get_copy_lv(cmd, vg, name, uuid, - parms->lv_type))) { + lv = parms->poll_fns->get_copy_lv(cmd, vg, name, uuid, parms->lv_type); + + if (!lv && parms->lv_type == PVMOVE) { + log_print_unless_silent("%s: no pvmove in progress - already finished or aborted.", + name); + unlock_and_release_vg(cmd, vg, vg->name); + return 1; + } + + if (!lv) { log_error("ABORTING: Can't find LV in %s for %s", vg->name, name); - unlock_and_free_vg(cmd, vg, vg->name); + unlock_and_release_vg(cmd, vg, vg->name); return 0; } if (!_check_lv_status(cmd, vg, lv, name, parms, &finished)) { - unlock_and_free_vg(cmd, vg, vg->name); - return 0; + unlock_and_release_vg(cmd, vg, vg->name); + return_0; } - unlock_and_free_vg(cmd, vg, vg->name); + unlock_and_release_vg(cmd, vg, vg->name); /* * FIXME Sleeping after testing, while preferred, also works around @@ -232,6 +261,11 @@ static int _poll_vg(struct cmd_context *cmd, const char *vgname, const char *name; int finished; + if (!parms) { + log_error(INTERNAL_ERROR "Handle is undefined."); + return ECMD_FAILED; + } + dm_list_iterate_items(lvl, &vg->lvs) { lv = lvl->lv; if (!(lv->status & parms->lv_type)) @@ -271,7 +305,7 @@ static void _poll_for_all_vgs(struct cmd_context *cmd, */ int poll_daemon(struct cmd_context *cmd, const char *name, const char *uuid, unsigned background, - uint32_t lv_type, struct poll_functions *poll_fns, + uint64_t lv_type, struct poll_functions *poll_fns, const char *progress_title) { struct daemon_parms parms; @@ -281,7 +315,7 @@ int poll_daemon(struct cmd_context *cmd, const char *name, const char *uuid, parms.aborting = arg_is_set(cmd, abort_ARG); parms.background = background; - interval_sign = arg_sign_value(cmd, interval_ARG, 0); + interval_sign = arg_sign_value(cmd, interval_ARG, SIGN_NONE); if (interval_sign == SIGN_MINUS) log_error("Argument to --interval cannot be negative"); parms.interval = arg_uint_value(cmd, interval_ARG, |