diff options
author | David Teigland <teigland@redhat.com> | 2015-03-05 16:41:49 -0600 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2015-03-11 13:31:15 -0500 |
commit | 794bfb6945c1963112f0c03547bfc4cada8fc5ab (patch) | |
tree | 643f311bd9b3c65760c345a20b51348ade8a4574 | |
parent | e0bec833ec2418562c3bfa6759d7658db72bc27b (diff) | |
download | lvm2-794bfb6945c1963112f0c03547bfc4cada8fc5ab.tar.gz |
lvmlockd: remove client side updates about local vgs
-rw-r--r-- | daemons/lvmlockd/lvmlockd-client.h | 2 | ||||
-rw-r--r-- | lib/cache/lvmetad.c | 3 | ||||
-rw-r--r-- | lib/locking/lvmlockd.c | 401 | ||||
-rw-r--r-- | lib/locking/lvmlockd.h | 20 | ||||
-rw-r--r-- | lib/metadata/metadata-exported.h | 4 | ||||
-rw-r--r-- | lib/metadata/metadata.c | 57 | ||||
-rw-r--r-- | lib/metadata/replicator_manip.c | 4 | ||||
-rw-r--r-- | lib/metadata/vg.c | 2 | ||||
-rw-r--r-- | liblvm/lvm_vg.c | 2 | ||||
-rw-r--r-- | tools/lvconvert.c | 9 | ||||
-rw-r--r-- | tools/lvcreate.c | 5 | ||||
-rw-r--r-- | tools/lvrename.c | 5 | ||||
-rw-r--r-- | tools/lvresize.c | 5 | ||||
-rw-r--r-- | tools/pvmove.c | 2 | ||||
-rw-r--r-- | tools/pvscan.c | 19 | ||||
-rw-r--r-- | tools/toollib.c | 23 | ||||
-rw-r--r-- | tools/vgmerge.c | 2 | ||||
-rw-r--r-- | tools/vgreduce.c | 10 | ||||
-rw-r--r-- | tools/vgrename.c | 12 | ||||
-rw-r--r-- | tools/vgsplit.c | 6 |
20 files changed, 268 insertions, 325 deletions
diff --git a/daemons/lvmlockd/lvmlockd-client.h b/daemons/lvmlockd/lvmlockd-client.h index 0f0c3051e..c5c31c33b 100644 --- a/daemons/lvmlockd/lvmlockd-client.h +++ b/daemons/lvmlockd/lvmlockd-client.h @@ -39,8 +39,6 @@ static inline void lvmlockd_close(daemon_handle h) * Errors returned as the lvmlockd result value. */ #define ENOLS 210 /* lockspace not found */ -#define ELOCALVG 211 /* vg is local */ -#define EOTHERVG 212 /* vg sysid specifies other host */ #define ESTARTING 213 /* lockspace is starting */ #endif diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c index 26454ec54..a13f47903 100644 --- a/lib/cache/lvmetad.c +++ b/lib/cache/lvmetad.c @@ -1197,6 +1197,9 @@ void lvmetad_validate_global_cache(struct cmd_context *cmd, int force) daemon_reply reply; int global_invalid; + if (!lvmetad_used()) + return; + if (force) goto do_scan; diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c index d11725575..bce830c40 100644 --- a/lib/locking/lvmlockd.c +++ b/lib/locking/lvmlockd.c @@ -96,6 +96,11 @@ int lvmlockd_connected(void) return 0; } +int lvmlockd_active(void) +{ + return _lvmlockd_active; +} + void lvmlockd_set_active(int active) { _lvmlockd_active = active; @@ -687,39 +692,7 @@ static int _free_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg) static int _free_vg_local(struct cmd_context *cmd, struct volume_group *vg) { - daemon_reply reply; - char uuid[64] __attribute__((aligned(8))); - int result; - int ret; - - if (!_lvmlockd_active) - return 1; - if (!lvmlockd_connected()) - return 0; - - memset(uuid, 0, sizeof(uuid)); - id_write_format(&vg->id, uuid, sizeof(uuid)); - - reply = _lockd_send("rem_local", - "pid = %d", getpid(), - "vg_name = %s", vg->name, - "vg_uuid = %s", uuid[0] ? uuid : "none", - "vg_lock_type = %s", "none", - NULL); - - if (!_lockd_result(reply, &result, NULL)) { - ret = 0; - } else { - ret = (result < 0) ? 0 : 1; - } - - if (!ret) { - log_error("_free_vg_local lvmlockd result %d", result); - } - - daemon_reply_destroy(reply); - - return ret; + return 1; } /* vgcreate */ @@ -804,20 +777,12 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg) { char uuid[64] __attribute__((aligned(8))); daemon_reply reply; - const char *lock_type; int host_id = 0; int result; int ret; memset(uuid, 0, sizeof(uuid)); - /* - * We do not skip non-lockd vg's here (see add_local below). - * We use this to ensure lvmlockd has seen the local vg. - * It is an optimization in case lvmlockd has not seen the - * local vg yet. - */ - if (!_lvmlockd_active) return 1; if (!lvmlockd_connected()) @@ -828,6 +793,9 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg) if (cmd->lock_vg_mode && !strcmp(cmd->lock_vg_mode, "na")) return 1; + if (!is_lockd_type(vg->lock_type)) + return 1; + log_debug("lockd_start_vg %s lock_type %s", vg->name, vg->lock_type ? vg->lock_type : "empty"); @@ -847,23 +815,7 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg) id_write_format(&vg->id, uuid, sizeof(uuid)); - if (!is_lockd_type(vg->lock_type)) { - const char *sysid = NULL; - - if (vg->system_id && (strlen(vg->system_id) > 0)) - sysid = vg->system_id; - - reply = _lockd_send("add_local", - "pid = %d", getpid(), - "vg_name = %s", vg->name, - "vg_uuid = %s", uuid[0] ? uuid : "none", - "vg_sysid = %s", sysid ?: "none", - "our_system_id = %s", cmd->system_id ?: "none", - NULL); - - lock_type = "local"; - } else { - reply = _lockd_send("start_vg", + reply = _lockd_send("start_vg", "pid = %d", getpid(), "vg_name = %s", vg->name, "vg_lock_type = %s", vg->lock_type, @@ -873,9 +825,6 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg) "host_id = %d", host_id, NULL); - lock_type = vg->lock_type; - } - if (!_lockd_result(reply, &result, NULL)) { result = -1; ret = 0; @@ -889,7 +838,7 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg) } if (!ret) - log_error("Locking start %s VG %s %d", lock_type, vg->name, result); + log_error("Locking start %s VG %s %d", vg->lock_type, vg->name, result); else log_debug("lockd_start_vg %s done", vg->name); @@ -1212,17 +1161,6 @@ int lockd_gl(struct cmd_context *cmd, const char *def_mode, uint32_t flags) return 0; } - /* - * The lockd_gl() caller uses this flag when it is going to change the - * VG namesapce. lvmlockd uses this to encode extra information in the - * global lock data (a separate version number in the lvb) about what - * was changed. Other hosts will see this extra information in the gl - * data and know that the VG namespace changed, which determines the - * kind of cache refresh they need to do. - */ - if (flags & LDGL_UPDATE_NAMES) - opts = "update_names"; - if (!_lockd_request(cmd, "lock_gl", NULL, NULL, NULL, NULL, NULL, mode, opts, &result, &result_flags)) { @@ -1324,11 +1262,30 @@ int lockd_gl(struct cmd_context *cmd, const char *def_mode, uint32_t flags) return 1; } -int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode, uint32_t flags) +/* + * VG lock + * + * Return 1: continue, lockd_state may still indicate an error + * Return 0: failure, do not continue + * + * lvmlockd could also return the lock_type that it used for the VG, + * and we could encode that in lockd_state, and verify later that it + * matches vg->lock_type. + * + * The result of the VG lock operation needs to be saved in lockd_state + * because the result needs to be passed into vg_read so it can be + * assessed in combination with vg->lock_state. + */ + +int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode, + uint32_t flags, uint32_t *lockd_state) { const char *mode = NULL; uint32_t result_flags; int result; + int ret; + + *lockd_state = 0; if (!is_real_vg(vg_name)) return 1; @@ -1342,6 +1299,9 @@ int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode, /* * An unlock is simply sent or skipped without any need * for the mode checking for sh/ex. + * + * TODO: look at lockd_state from the sh/ex lock, and if it + * failed, don't bother sending the unlock to lvmlockd. */ if (def_mode && !strcmp(def_mode, "un")) { if (cmd->lock_vg_mode && !strcmp(cmd->lock_vg_mode, "na")) @@ -1378,142 +1338,141 @@ int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode, mode = cmd->lockd_vg_default_sh ? "sh" : "ex"; if (!strcmp(mode, "ex") && find_config_tree_bool(cmd, global_read_only_lock_modes_CFG, NULL)) { - log_error("Disallow lock-vg ex with read_only_lock_modes"); + log_error("Disallow VG ex lock with read_only_lock_modes"); return 0; } + + if (!strcmp(mode, "ex")) + *lockd_state |= LDST_EX; + else if (!strcmp(mode, "sh")) + *lockd_state |= LDST_SH; + req: if (!_lockd_request(cmd, "lock_vg", vg_name, NULL, NULL, NULL, NULL, mode, NULL, &result, &result_flags)) { - /* No result from lvmlockd, it is probably not running. */ - /* - * See comment in lockd_gl() about these cases - * where we keep going if the mode is "un" or "sh". + * No result from lvmlockd, it is probably not running. + * Decide if it is ok to continue without a lock after + * reading the VG and looking at the lock_type. */ + *lockd_state |= LDST_FAIL_REQUEST; + return 1; + } - if (!strcmp(mode, "un")) - return 1; - - if (!strcmp(mode, "sh")) { - log_warn("Reading VG %s without shared lock.", vg_name); - return 1; - } + switch (result) { + case 0: + /* success */ + break; + case -ENOLS: + *lockd_state |= LDST_FAIL_NOLS; + break; + case -ESTARTING: + *lockd_state |= LDST_FAIL_STARTING; + break; + default: + *lockd_state |= LDST_FAIL_OTHER; + } - log_error("Locking failed for VG %s", vg_name); - return 0; + /* + * Normal success. + */ + if (!result) { + ret = 1; + goto out; } /* - * result and result_flags were returned from lvmlockd. - * - * ENOLS: no lockspace for the VG was found, the VG may not - * be started yet. The VG should be started manually or by system, - * e.g. vgchange --lock-start - * - * ESTARTING: the lockspace for the VG is starting and should - * finish shortly. - * - * ELOCALVG: the VG is local and does not need locking. - * - * EOTHERVG: - * - * The VG is local and its system_id does not match - * the local system_id saved in lvmlockd (lvmlockd - * caches the names/system_ids of local VGs so it - * can quickly avoid any distributed locking on them.) - * - * In many cases we could simply return 0 (a failure) - * here, causing this VG to be skipped by the command - * before it's even read. But there are a couple of - * reasons why we want to return 1 (success) here and - * proceed through vg_read and get to access_vg_systemid: - * - * . The command may allow reading foreign VG's, - * i.e. vgs --foreign, which would not work if we - * skipped the VG here. - * - * . The local host may accept multiple system_ids, - * i.e. allow_system_id(), and lvmlockd does not - * know about all the allowed system_ids. - * - * If neither of these are true, then access_vg_systemid - * will deny access, and the VG will be skipped at that - * point. So, to allow the two exceptions above, we - * return success here and allow VG access to be - * decided later in access_vg_systemid. + * The lockspace for the VG is starting (the VG must not + * be local), and is not yet ready to do locking. Allow + * reading without a sh lock during this period. */ - - if (result == -ELOCALVG || result == -EOTHERVG) - return 1; - - if (result == -ENOLS || result == -ESTARTING) { - if (!strcmp(mode, "un")) - return 1; - - if (strcmp(mode, "sh")) { - /* - * An ex lock request always fails here. Based on the - * result number and result flags we can often print a - * reason for the failure. - * - * (In the future we might want to continue through - * vg_read without the lock, and add something after - * vg_read to check if the lock request failed, and - * fail at that point. Going through the vg_read - * before failing may provide more information about - * the failure and the VG.) - */ - if ((result == -ENOLS) && (result_flags & LD_RF_INACTIVE_LS)) { - if (result_flags & LD_RF_ADD_LS_ERROR) - log_error("VG %s lock failed: lock start error", vg_name); - else - log_error("VG %s lock failed: locking stopped", vg_name); - - } else if (result == -ENOLS) { - log_error("VG %s lock failed: lock start required", vg_name); - - } else if (result == -ESTARTING) { - log_error("VG %s lock failed: lock start in progress", vg_name); - - } else { - log_error("VG %s lock failed: %d", vg_name, result); - } - return 0; - } - - /* - * When a sh lock failed we will allow the command to proceed - * because there's little harm that it could do. See the - * reasoning above for proceeding after a failed gl sh lock. - * Do we want to invalidate the cached VG in these cases to - * force rereading from disk? - */ - - if (result == -ESTARTING) { - log_warn("Skipping lock for VG %s: lock start in progress", vg_name); - return 1; + if (result == -ESTARTING) { + if (!strcmp(mode, "un")) { + ret = 1; + goto out; + } else if (!strcmp(mode, "sh")) { + log_warn("VG %s lock skipped: lock start in progress", vg_name); + ret = 1; + goto out; + } else { + log_error("VG %s lock failed: lock start in progress", vg_name); + ret = 0; + goto out; } - - if ((result == -ENOLS) && (result_flags & LD_RF_ADD_LS_ERROR)) { - log_warn("Skipping lock for VG %s: lock start error", vg_name); - return 1; + } + + /* + * An unused/previous lockspace for the VG was found. + * This means it must be a lockd VG, not local. The + * lockspace needs to be started to be used. + */ + if ((result == -ENOLS) && (result_flags & LD_RF_INACTIVE_LS)) { + if (!strcmp(mode, "un")) { + ret = 1; + goto out; + } else if (!strcmp(mode, "sh")) { + log_warn("VG %s lock skipped: lockspace is inactive", vg_name); + ret = 1; + goto out; + } else { + log_error("VG %s lock failed: lockspace is inactive", vg_name); + ret = 0; + goto out; } - - if ((result == -ENOLS) && (result_flags & LD_RF_INACTIVE_LS)) { - log_warn("Skipping lock for VG %s: locking stopped", vg_name); - return 1; + } + + /* + * An unused lockspace for the VG was found. The previous + * start of the lockspace failed, so we can print a more useful + * error message. + */ + if ((result == -ENOLS) && (result_flags & LD_RF_ADD_LS_ERROR)) { + if (!strcmp(mode, "un")) { + ret = 1; + goto out; + } else if (!strcmp(mode, "sh")) { + log_warn("VG %s lock skipped: lockspace start error", vg_name); + ret = 1; + goto out; + } else { + log_error("VG %s lock failed: lockspace start error", vg_name); + ret = 0; + goto out; } - - if (result == -ENOLS) { - log_warn("Skipping lock for VG %s: lock start required", vg_name); - return 1; + } + + /* + * No lockspace for the VG was found. It may be a local + * VG that lvmlockd doesn't keep track of, or it may be + * a lockd VG that lvmlockd doesn't yet know about (it hasn't + * been started yet.) Decide what to do after the VG is + * read and we can see the lock_type. + */ + if (result == -ENOLS) { + ret = 1; + goto out; + } + + /* + * Unknown error. + */ + if (result) { + if (!strcmp(mode, "un")) { + ret = 1; + goto out; + } else if (!strcmp(mode, "sh")) { + log_warn("VG %s lock skipped: error %d", vg_name, result); + ret = 1; + goto out; + } else { + log_error("VG %s lock failed: error %d", vg_name, result); + ret = 0; + goto out; } - - log_error("VG %s shared lock error %d", vg_name, result); - return 0; } - + +out: /* * A notice from lvmlockd that duplicate gl locks have been found. * It would be good for the user to disable one of them. @@ -1521,34 +1480,12 @@ int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode, if ((result_flags & LD_RF_DUP_GL_LS) && strcmp(mode, "un")) log_warn("Duplicate sanlock global lock in VG %s", vg_name); - if (result < 0) { - if (ignorelockingfailure()) { - log_debug("Ignore failed locking for VG %s", vg_name); - return 1; - } else { - log_error("VG %s lock error: %d", vg_name, result); - return 0; - } + if (!ret && ignorelockingfailure()) { + log_debug("Ignore failed locking for VG %s", vg_name); + return 1; } - return 1; -} - -/* A shortcut for back to back lockd_gl() + lockd_vg() */ - -int lockd_gl_vg(struct cmd_context *cmd, const char *vg_name, - const char *def_gl_mode, const char *def_vg_mode, - uint32_t flags) -{ - if (!lockd_gl(cmd, def_gl_mode, flags)) - return 0; - - if (!lockd_vg(cmd, vg_name, def_vg_mode, flags)) { - lockd_gl(cmd, "un", LDGL_MODE_NOARG); - return 0; - } - - return 1; + return ret; } int lockd_vg_update(struct volume_group *vg) @@ -2053,36 +1990,6 @@ int lockd_free_lv(struct cmd_context *cmd, struct volume_group *vg, } } -int lockd_update_local(struct cmd_context *cmd) -{ - daemon_reply reply; - int result; - int ret; - - if (!_lvmlockd_active) - return 1; - if (!lvmlockd_connected()) - return 0; - - reply = _lockd_send("update_local", - "pid = %d", getpid(), - NULL); - - if (!_lockd_result(reply, &result, NULL)) { - ret = 0; - } else { - ret = (result < 0) ? 0 : 1; - } - - if (!ret) { - log_error("lockd_update_local lvmlockd result %d", result); - } - - daemon_reply_destroy(reply); - - return ret; -} - int lockd_rename_vg_before(struct cmd_context *cmd, struct volume_group *vg) { struct lv_list *lvl; diff --git a/lib/locking/lvmlockd.h b/lib/locking/lvmlockd.h index ac66bbfd2..86dde91c8 100644 --- a/lib/locking/lvmlockd.h +++ b/lib/locking/lvmlockd.h @@ -40,6 +40,15 @@ #define LD_RF_INACTIVE_LS 0x00000010 #define LD_RF_ADD_LS_ERROR 0x00000020 +/* lockd_state flags */ +#define LDST_EX 0x00000001 +#define LDST_SH 0x00000002 +#define LDST_FAIL_REQUEST 0x00000004 +#define LDST_FAIL_NOLS 0x00000008 +#define LDST_FAIL_STARTING 0x00000010 +#define LDST_FAIL_OTHER 0x00000020 +#define LDST_FAIL (LDST_FAIL_REQUEST | LDST_FAIL_NOLS | LDST_FAIL_STARTING | LDST_FAIL_OTHER) + /* * lock_type lock_type_num * "none" -> LOCK_TYPE_NONE @@ -92,6 +101,7 @@ void lvmlockd_set_socket(const char *); void lvmlockd_disconnect(void); void lvmlockd_connect_or_warn(void); int lvmlockd_connected(void); +int lvmlockd_active(void); /* vgcreate/vgremove use init/free */ @@ -109,15 +119,13 @@ int lockd_rename_vg_final(struct cmd_context *cmd, struct volume_group *vg, int int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg); int lockd_stop_vg(struct cmd_context *cmd, struct volume_group *vg); int lockd_start_wait(struct cmd_context *cmd); -int lockd_update_local(struct cmd_context *cmd); /* locking */ int lockd_gl_create(struct cmd_context *cmd, const char *def_mode, const char *vg_lock_type); int lockd_gl(struct cmd_context *cmd, const char *def_mode, uint32_t flags); -int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode, uint32_t flags); -int lockd_gl_vg(struct cmd_context *cmd, const char *vg_name, - const char *def_gl_mode, const char *def_vg_mode, uint32_t flags); +int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode, + uint32_t flags, uint32_t *lockd_state); int lockd_vg_update(struct volume_group *vg); int lockd_lv_name(struct cmd_context *cmd, struct volume_group *vg, @@ -155,12 +163,10 @@ int lockd_init_lv_args(struct cmd_context *cmd, struct volume_group *vg, #define lockd_start_vg(cmd, vg) (1) #define lockd_stop_vg(cmd, vg) (1) #define lockd_start_wait(cmd) (1) -#define lockd_update_local(cmd) (1) #define lockd_gl_create(cmd, def_mode, vg_lock_type) (1) #define lockd_gl(cmd, def_mode, flags) (1) -#define lockd_vg(cmd, vg_name, def_mode, flags) (1) -#define lockd_gl_vg(cmd, vg_name, def_gl_mode, def_vg_mode, flags) (1) +#define lockd_vg(cmd, vg_name, def_mode, flags, lockd_state) (1) #define lockd_vg_update(vg) (1) #define lockd_lv_name(cmd, vg, lv_name, lock_args, def_mode, flags) (1) diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h index 208c13f09..d38bef19f 100644 --- a/lib/metadata/metadata-exported.h +++ b/lib/metadata/metadata-exported.h @@ -626,9 +626,9 @@ int lv_resize(struct cmd_context *cmd, struct logical_volume *lv, * Return a handle to VG metadata. */ struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name, - const char *vgid, uint32_t flags); + const char *vgid, uint32_t flags, uint32_t lockd_state); struct volume_group *vg_read_for_update(struct cmd_context *cmd, const char *vg_name, - const char *vgid, uint32_t flags); + const char *vgid, uint32_t flags, uint32_t lockd_state); /* * Test validity of a VG handle. diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c index 23e366a77..a2a454f7b 100644 --- a/lib/metadata/metadata.c +++ b/lib/metadata/metadata.c @@ -4416,7 +4416,8 @@ static int _access_vg_clustered(struct cmd_context *cmd, struct volume_group *vg return 1; } -static int _access_vg_lock_type(struct cmd_context *cmd, struct volume_group *vg) +static int _access_vg_lock_type(struct cmd_context *cmd, struct volume_group *vg, + uint32_t lockd_state) { if (!is_real_vg(vg->name)) return 1; @@ -4424,10 +4425,38 @@ static int _access_vg_lock_type(struct cmd_context *cmd, struct volume_group *vg if (cmd->lockd_vg_disable) return 1; - if (is_lockd_type(vg->lock_type) && !find_config_tree_bool(cmd, global_use_lvmlockd_CFG, NULL)) { - log_warn("Cannot access VG %s which requires lvmlockd (lock_type %s).", - vg->name, vg->lock_type); - return 0; + /* + * Local VG requires no lock from lvmlockd. + */ + if (!is_lockd_type(vg->lock_type)) + return 1; + + /* + * When lvmlockd is not running, only allow read access to the VG. + */ + if (!lvmlockd_active()) { + if (lockd_state & LDST_EX) { + log_error("Cannot access VG %s which requires lvmlockd for lock_type %s.", + vg->name, vg->lock_type); + return 0; + } else { + log_warn("Reading VG %s without a lock.", vg->name); + return 1; + } + } + + /* + * The lock failed. If the lock was ex, we cannot continue. + * If the lock was sh, we can allow reading. + */ + if (lockd_state & LDST_FAIL) { + if (lockd_state & LDST_EX) { + log_error("Cannot access VG %s due to failed lock.", vg->name); + return 0; + } else { + log_warn("Reading VG %s without a lock.", vg->name); + return 1; + } } return 1; @@ -4508,7 +4537,8 @@ static int _access_vg_systemid(struct cmd_context *cmd, struct volume_group *vg) /* * FIXME: move _vg_bad_status_bits() checks in here. */ -static int _vg_access_permitted(struct cmd_context *cmd, struct volume_group *vg, uint32_t *failure) +static int _vg_access_permitted(struct cmd_context *cmd, struct volume_group *vg, + uint32_t lockd_state, uint32_t *failure) { if (!is_real_vg(vg->name)) { /* Disallow use of LVM1 orphans when a host system ID is set. */ @@ -4524,7 +4554,7 @@ static int _vg_access_permitted(struct cmd_context *cmd, struct volume_group *vg return 0; } - if (!_access_vg_lock_type(cmd, vg)) { + if (!_access_vg_lock_type(cmd, vg, lockd_state)) { *failure |= FAILED_LOCK_TYPE; return 0; } @@ -4550,7 +4580,8 @@ static int _vg_access_permitted(struct cmd_context *cmd, struct volume_group *vg */ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const char *vg_name, const char *vgid, uint32_t lock_flags, - uint64_t status_flags, uint32_t misc_flags) + uint64_t status_flags, uint32_t misc_flags, + uint32_t lockd_state) { struct volume_group *vg = NULL; int consistent = 1; @@ -4596,7 +4627,7 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha goto bad; } - if (!_vg_access_permitted(cmd, vg, &failure)) + if (!_vg_access_permitted(cmd, vg, lockd_state, &failure)) goto bad; /* consistent == 0 when VG is not found, but failed == FAILED_NOTFOUND */ @@ -4672,7 +4703,7 @@ bad_no_unlock: * *consistent = 1. */ struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name, - const char *vgid, uint32_t flags) + const char *vgid, uint32_t flags, uint32_t lockd_state) { uint64_t status = UINT64_C(0); uint32_t lock_flags = LCK_VG_READ; @@ -4685,7 +4716,7 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name, if (flags & READ_ALLOW_EXPORTED) status &= ~EXPORTED_VG; - return _vg_lock_and_read(cmd, vg_name, vgid, lock_flags, status, flags); + return _vg_lock_and_read(cmd, vg_name, vgid, lock_flags, status, flags, lockd_state); } /* @@ -4694,9 +4725,9 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name, * request the new metadata to be written and committed). */ struct volume_group *vg_read_for_update(struct cmd_context *cmd, const char *vg_name, - const char *vgid, uint32_t flags) + const char *vgid, uint32_t flags, uint32_t lockd_state) { - return vg_read(cmd, vg_name, vgid, flags | READ_FOR_UPDATE); + return vg_read(cmd, vg_name, vgid, flags | READ_FOR_UPDATE, lockd_state); } /* diff --git a/lib/metadata/replicator_manip.c b/lib/metadata/replicator_manip.c index 54dc75929..fc4bf5fa1 100644 --- a/lib/metadata/replicator_manip.c +++ b/lib/metadata/replicator_manip.c @@ -566,7 +566,7 @@ int cmd_vg_read(struct cmd_context *cmd, struct dm_list *cmd_vgs) /* Iterate through alphabeticaly ordered cmd_vg list */ dm_list_iterate_items(cvl, cmd_vgs) { - cvl->vg = vg_read(cmd, cvl->vg_name, cvl->vgid, cvl->flags); + cvl->vg = vg_read(cmd, cvl->vg_name, cvl->vgid, cvl->flags, 0); if (vg_read_error(cvl->vg)) { log_debug_metadata("Failed to vg_read %s", cvl->vg_name); return 0; @@ -644,7 +644,7 @@ int lv_read_replicator_vgs(const struct logical_volume *lv) dm_list_iterate_items(rsite, &first_seg(lv)->replicator->rsites) { if (!rsite->vg_name) continue; - vg = vg_read(lv->vg->cmd, rsite->vg_name, 0, 0); // READ_WITHOUT_LOCK + vg = vg_read(lv->vg->cmd, rsite->vg_name, 0, 0, 0); // READ_WITHOUT_LOCK if (vg_read_error(vg)) { log_error("Unable to read volume group %s", rsite->vg_name); diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c index aa69d77e8..4d2aabef9 100644 --- a/lib/metadata/vg.c +++ b/lib/metadata/vg.c @@ -718,7 +718,7 @@ int vgreduce_single(struct cmd_context *cmd, struct volume_group *vg, vg->extent_count -= pv_pe_count(pv); orphan_vg = vg_read_for_update(cmd, vg->fid->fmt->orphan_vg_name, - NULL, 0); + NULL, 0, 0); if (vg_read_error(orphan_vg)) goto bad; diff --git a/liblvm/lvm_vg.c b/liblvm/lvm_vg.c index 76c5c6356..a2d42d23f 100644 --- a/liblvm/lvm_vg.c +++ b/liblvm/lvm_vg.c @@ -218,7 +218,7 @@ static vg_t _lvm_vg_open(lvm_t libh, const char *vgname, const char *mode, return NULL; } - vg = vg_read((struct cmd_context *)libh, vgname, NULL, internal_flags); + vg = vg_read((struct cmd_context *)libh, vgname, NULL, internal_flags, 0); if (vg_read_error(vg)) { /* FIXME: use log_errno either here in inside vg_read */ release_vg(vg); diff --git a/tools/lvconvert.c b/tools/lvconvert.c index 6ef0fe1f3..8db955c8a 100644 --- a/tools/lvconvert.c +++ b/tools/lvconvert.c @@ -76,6 +76,9 @@ struct lvconvert_params { thin_discards_t discards; }; +/* FIXME: temporarily put here until merged with poll daemon changes. */ +static uint32_t lockd_state; + static int _lvconvert_validate_names(struct lvconvert_params *lp) { int i, j; @@ -705,11 +708,11 @@ static struct volume_group *_get_lvconvert_vg(struct cmd_context *cmd, dev_close_all(); if (name && !strchr(name, '/')) - return vg_read_for_update(cmd, name, NULL, 0); + return vg_read_for_update(cmd, name, NULL, 0, lockd_state); /* 'name' is the full LV name; must extract_vgname() */ return vg_read_for_update(cmd, extract_vgname(cmd, name), - NULL, 0); + NULL, 0, lockd_state); } static struct logical_volume *_get_lvconvert_lv(struct cmd_context *cmd __attribute__((unused)), @@ -3507,7 +3510,7 @@ static int lvconvert_single(struct cmd_context *cmd, struct lvconvert_params *lp cmd->handles_missing_pvs = 1; } - if (!lockd_vg(cmd, lp->vg_name, "ex", 0)) + if (!lockd_vg(cmd, lp->vg_name, "ex", 0, &lockd_state)) goto_out; if (!(lv = get_vg_lock_and_logical_volume(cmd, lp->vg_name, lp->lv_name))) diff --git a/tools/lvcreate.c b/tools/lvcreate.c index 864e36d9e..041af0d14 100644 --- a/tools/lvcreate.c +++ b/tools/lvcreate.c @@ -1445,6 +1445,7 @@ int lvcreate(struct cmd_context *cmd, int argc, char **argv) }; struct lvcreate_cmdline_params lcp = { 0 }; struct volume_group *vg; + uint32_t lockd_state; if (!_lvcreate_params(cmd, argc, argv, &lp, &lcp)) { stack; @@ -1456,11 +1457,11 @@ int lvcreate(struct cmd_context *cmd, int argc, char **argv) return EINVALID_CMD_LINE; } - if (!lockd_vg(cmd, lp.vg_name, "ex", 0)) + if (!lockd_vg(cmd, lp.vg_name, "ex", 0, &lockd_state)) return_ECMD_FAILED; log_verbose("Finding volume group \"%s\"", lp.vg_name); - vg = vg_read_for_update(cmd, lp.vg_name, NULL, 0); + vg = vg_read_for_update(cmd, lp.vg_name, NULL, 0, lockd_state); if (vg_read_error(vg)) { release_vg(vg); return_ECMD_FAILED; diff --git a/tools/lvrename.c b/tools/lvrename.c index dbfa4caa0..6bbf31bf7 100644 --- a/tools/lvrename.c +++ b/tools/lvrename.c @@ -27,6 +27,7 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv) char *st; struct volume_group *vg; struct lv_list *lvl; + uint32_t lockd_state; int r = ECMD_FAILED; if (argc == 3) { @@ -98,11 +99,11 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv) return EINVALID_CMD_LINE; } - if (!lockd_vg(cmd, vg_name, "ex", 0)) + if (!lockd_vg(cmd, vg_name, "ex", 0, &lockd_state)) return_ECMD_FAILED; log_verbose("Checking for existing volume group \"%s\"", vg_name); - vg = vg_read_for_update(cmd, vg_name, NULL, 0); + vg = vg_read_for_update(cmd, vg_name, NULL, 0, lockd_state); if (vg_read_error(vg)) { release_vg(vg); return_ECMD_FAILED; diff --git a/tools/lvresize.c b/tools/lvresize.c index 704b41697..30ac4f987 100644 --- a/tools/lvresize.c +++ b/tools/lvresize.c @@ -169,16 +169,17 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv) struct volume_group *vg; struct dm_list *pvh = NULL; struct logical_volume *lv; + uint32_t lockd_state; int r = ECMD_FAILED; if (!_lvresize_params(cmd, argc, argv, &lp)) return EINVALID_CMD_LINE; - if (!lockd_vg(cmd, lp.vg_name, "ex", 0)) + if (!lockd_vg(cmd, lp.vg_name, "ex", 0, &lockd_state)) return_ECMD_FAILED; log_verbose("Finding volume group %s", lp.vg_name); - vg = vg_read_for_update(cmd, lp.vg_name, NULL, 0); + vg = vg_read_for_update(cmd, lp.vg_name, NULL, 0, lockd_state); if (vg_read_error(vg)) { release_vg(vg); return_ECMD_FAILED; diff --git a/tools/pvmove.c b/tools/pvmove.c index 30725844c..a9a90b2d9 100644 --- a/tools/pvmove.c +++ b/tools/pvmove.c @@ -92,7 +92,7 @@ static struct volume_group *_get_vg(struct cmd_context *cmd, const char *vgname) { dev_close_all(); - return vg_read_for_update(cmd, vgname, NULL, 0); + return vg_read_for_update(cmd, vgname, NULL, 0, 0); } /* Create list of PVs for allocation of replacement extents */ diff --git a/tools/pvscan.c b/tools/pvscan.c index 42581b573..b98f35f23 100644 --- a/tools/pvscan.c +++ b/tools/pvscan.c @@ -106,7 +106,7 @@ static int _auto_activation_handler(struct cmd_context *cmd, return_0; /* NB. This is safe because we know lvmetad is running and we won't hit disk. */ - vg = vg_read(cmd, vgname, (const char *)&vgid_raw, 0); + vg = vg_read(cmd, vgname, (const char *)&vgid_raw, 0, 0); if (vg_read_error(vg)) { log_error("Failed to read Volume Group \"%s\" (%s) during autoactivation.", vgname, vgid); release_vg(vg); @@ -321,23 +321,6 @@ static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char **argv) out: sync_local_dev_names(cmd); unlock_vg(cmd, VG_GLOBAL); - - /* - * lvmlockd wants to know about any new local vgs that - * have been added to lvmetad. If not done automatically - * here, then an explicit vgchange --lock-start would be - * needed to cause lvmlockd to update its list of local vgs - * from lvmetad. We could possibly optimize this by only - * calling this if a new vg has been found. - * - * This will do nothing during startup because lvmlockd is - * not yet running. lvmlockd will get an initial list of - * local vgs from lvmetad when it's started. This call is - * for the case when lvmetad/lvmlockd are already running - * and a new local vg appears to the system. - */ - lockd_update_local(cmd); - return ret; } diff --git a/tools/toollib.c b/tools/toollib.c index 7ca60c25b..d2beb0ff1 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -714,7 +714,7 @@ int vgcreate_params_set_from_args(struct cmd_context *cmd, struct vgcreate_params *vp_def) { const char *system_id_arg_str; - const char *lock_type; + const char *lock_type = NULL; int locking_type; int use_lvmlockd; int use_clvmd; @@ -1943,6 +1943,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t flags, struct vgnameid_list *vgnl; const char *vg_name; const char *vg_uuid; + uint32_t lockd_state; int selected; int whole_selected = 0; int ret_max = ECMD_PROCESSED; @@ -1967,10 +1968,10 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t flags, vg_uuid = vgnl->vgid; skip = 0; - if (!lockd_vg(cmd, vg_name, NULL, 0)) + if (!lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) continue; - vg = vg_read(cmd, vg_name, vg_uuid, flags); + vg = vg_read(cmd, vg_name, vg_uuid, flags, lockd_state); if (_ignore_vg(vg, vg_name, arg_vgnames, flags & READ_ALLOW_INCONSISTENT, &skip)) { stack; ret_max = ECMD_FAILED; @@ -1996,7 +1997,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t flags, unlock_vg(cmd, vg_name); endvg: release_vg(vg); - lockd_vg(cmd, vg_name, "un", 0); + lockd_vg(cmd, vg_name, "un", 0, &lockd_state); } /* the VG is selected if at least one LV is selected */ @@ -2364,6 +2365,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t flags, struct dm_str_list *sl; struct dm_list *tags_arg; struct dm_list lvnames; + uint32_t lockd_state; const char *vg_name; const char *vg_uuid; const char *vgn; @@ -2410,10 +2412,10 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t flags, } } - if (!lockd_vg(cmd, vg_name, NULL, 0)) + if (!lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) continue; - vg = vg_read(cmd, vg_name, vg_uuid, flags); + vg = vg_read(cmd, vg_name, vg_uuid, flags, lockd_state); if (_ignore_vg(vg, vg_name, arg_vgnames, flags & READ_ALLOW_INCONSISTENT, &skip)) { stack; ret_max = ECMD_FAILED; @@ -2433,7 +2435,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t flags, unlock_vg(cmd, vg_name); endvg: release_vg(vg); - lockd_vg(cmd, vg_name, "un", 0); + lockd_vg(cmd, vg_name, "un", 0, &lockd_state); } return ret_max; @@ -2877,6 +2879,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t flags, struct vgnameid_list *vgnl; const char *vg_name; const char *vg_uuid; + uint32_t lockd_state; int ret_max = ECMD_PROCESSED; int ret; int skip; @@ -2889,10 +2892,10 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t flags, vg_uuid = vgnl->vgid; skip = 0; - if (!lockd_vg(cmd, vg_name, NULL, 0)) + if (!lockd_vg(cmd, vg_name, NULL, 0, &lockd_state)) continue; - vg = vg_read(cmd, vg_name, vg_uuid, flags | READ_WARN_INCONSISTENT); + vg = vg_read(cmd, vg_name, vg_uuid, flags | READ_WARN_INCONSISTENT, lockd_state); if (_ignore_vg(vg, vg_name, NULL, flags & READ_ALLOW_INCONSISTENT, &skip)) { stack; ret_max = ECMD_FAILED; @@ -2916,7 +2919,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t flags, unlock_vg(cmd, vg->name); endvg: release_vg(vg); - lockd_vg(cmd, vg_name, "un", 0); + lockd_vg(cmd, vg_name, "un", 0, &lockd_state); /* Quit early when possible. */ if (!process_all_pvs && dm_list_empty(arg_tags) && dm_list_empty(arg_devices)) diff --git a/tools/vgmerge.c b/tools/vgmerge.c index e60346c75..e6e20278c 100644 --- a/tools/vgmerge.c +++ b/tools/vgmerge.c @@ -20,7 +20,7 @@ static struct volume_group *_vgmerge_vg_read(struct cmd_context *cmd, { struct volume_group *vg; log_verbose("Checking for volume group \"%s\"", vg_name); - vg = vg_read_for_update(cmd, vg_name, NULL, 0); + vg = vg_read_for_update(cmd, vg_name, NULL, 0, 0); if (vg_read_error(vg)) { release_vg(vg); return NULL; diff --git a/tools/vgreduce.c b/tools/vgreduce.c index fda8fb6d1..7ab2dca93 100644 --- a/tools/vgreduce.c +++ b/tools/vgreduce.c @@ -141,6 +141,7 @@ int vgreduce(struct cmd_context *cmd, int argc, char **argv) { struct volume_group *vg; const char *vg_name; + uint32_t lockd_state; int ret = ECMD_FAILED; int fixed = 1; int repairing = arg_count(cmd, removemissing_ARG); @@ -195,10 +196,13 @@ int vgreduce(struct cmd_context *cmd, int argc, char **argv) init_ignore_suspended_devices(1); cmd->handles_missing_pvs = 1; - if (!lockd_gl_vg(cmd, vg_name, "ex", "ex", 0)) + if (!lockd_gl(cmd, "ex", 0)) return_ECMD_FAILED; - vg = vg_read_for_update(cmd, vg_name, NULL, READ_ALLOW_EXPORTED); + if (!lockd_vg(cmd, vg_name, "ex", 0, &lockd_state)) + return_ECMD_FAILED; + + vg = vg_read_for_update(cmd, vg_name, NULL, READ_ALLOW_EXPORTED, lockd_state); if (vg_read_error(vg) == FAILED_ALLOCATION || vg_read_error(vg) == FAILED_NOTFOUND) goto_out; @@ -221,7 +225,7 @@ int vgreduce(struct cmd_context *cmd, int argc, char **argv) log_verbose("Trying to open VG %s for recovery...", vg_name); vg = vg_read_for_update(cmd, vg_name, NULL, - READ_ALLOW_INCONSISTENT | READ_ALLOW_EXPORTED); + READ_ALLOW_INCONSISTENT | READ_ALLOW_EXPORTED, lockd_state); locked |= !vg_read_error(vg); diff --git a/tools/vgrename.c b/tools/vgrename.c index c0ed348c2..2cef1fc72 100644 --- a/tools/vgrename.c +++ b/tools/vgrename.c @@ -17,13 +17,14 @@ static struct volume_group *_get_old_vg_for_rename(struct cmd_context *cmd, const char *vg_name_old, - const char *vgid) + const char *vgid, + uint32_t lockd_state) { struct volume_group *vg; /* FIXME we used to print an error about EXPORTED, but proceeded nevertheless. */ - vg = vg_read_for_update(cmd, vg_name_old, vgid, READ_ALLOW_EXPORTED); + vg = vg_read_for_update(cmd, vg_name_old, vgid, READ_ALLOW_EXPORTED, lockd_state); if (vg_read_error(vg)) { release_vg(vg); return_NULL; @@ -67,6 +68,7 @@ static int vg_rename_path(struct cmd_context *cmd, const char *old_vg_path, const char *vgid = NULL, *vg_name, *vg_name_old; char old_path[NAME_LEN], new_path[NAME_LEN]; struct volume_group *vg = NULL; + uint32_t lockd_state; int lock_vg_old_first = 1; vg_name_old = skip_dev_dir(cmd, old_vg_path, NULL); @@ -114,14 +116,14 @@ static int vg_rename_path(struct cmd_context *cmd, const char *old_vg_path, } else vgid = NULL; - if (!lockd_vg(cmd, vg_name_old, "ex", 0)) + if (!lockd_vg(cmd, vg_name_old, "ex", 0, &lockd_state)) return_0; if (strcmp(vg_name_new, vg_name_old) < 0) lock_vg_old_first = 0; if (lock_vg_old_first) { - vg = _get_old_vg_for_rename(cmd, vg_name_old, vgid); + vg = _get_old_vg_for_rename(cmd, vg_name_old, vgid, lockd_state); if (!vg) return_0; @@ -133,7 +135,7 @@ static int vg_rename_path(struct cmd_context *cmd, const char *old_vg_path, if (!_lock_new_vg_for_rename(cmd, vg_name_new)) return_0; - vg = _get_old_vg_for_rename(cmd, vg_name_old, vgid); + vg = _get_old_vg_for_rename(cmd, vg_name_old, vgid, lockd_state); if (!vg) { unlock_vg(cmd, vg_name_new); return_0; diff --git a/tools/vgsplit.c b/tools/vgsplit.c index ec6f2fd78..e04bf232b 100644 --- a/tools/vgsplit.c +++ b/tools/vgsplit.c @@ -422,7 +422,7 @@ static struct volume_group *_vgsplit_to(struct cmd_context *cmd, if (vg_read_error(vg_to) == FAILED_EXIST) { *existing_vg = 1; release_vg(vg_to); - vg_to = vg_read_for_update(cmd, vg_name_to, NULL, 0); + vg_to = vg_read_for_update(cmd, vg_name_to, NULL, 0, 0); if (vg_read_error(vg_to)) { release_vg(vg_to); @@ -448,7 +448,7 @@ static struct volume_group *_vgsplit_from(struct cmd_context *cmd, log_verbose("Checking for volume group \"%s\"", vg_name_from); - vg_from = vg_read_for_update(cmd, vg_name_from, NULL, 0); + vg_from = vg_read_for_update(cmd, vg_name_from, NULL, 0, 0); if (vg_read_error(vg_from)) { release_vg(vg_from); return NULL; @@ -672,7 +672,7 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv) if (!test_mode()) { release_vg(vg_to); vg_to = vg_read_for_update(cmd, vg_name_to, NULL, - READ_ALLOW_EXPORTED); + READ_ALLOW_EXPORTED, 0); if (vg_read_error(vg_to)) { log_error("Volume group \"%s\" became inconsistent: " "please fix manually", vg_name_to); |