summaryrefslogtreecommitdiff
path: root/tools/polldaemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/polldaemon.c')
-rw-r--r--tools/polldaemon.c68
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,