mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-03 05:18:29 +03:00
Introduce as-yet-unused _vg_lock_and_read() and associated header file
definitions.
This commit is contained in:
parent
8544a8a254
commit
bc92cde62c
@ -104,6 +104,29 @@ struct pv_segment;
|
||||
#define MIRROR_BY_LV 0x00000002U /* mirror using whole mimage LVs */
|
||||
#define MIRROR_SKIP_INIT_SYNC 0x00000010U /* skip initial sync */
|
||||
|
||||
/* vg_read and vg_read_for_update flags */
|
||||
#define READ_ALLOW_INCONSISTENT 0x00010000U
|
||||
#define READ_ALLOW_EXPORTED 0x00020000U
|
||||
#define READ_REQUIRE_RESIZEABLE 0x00040000U
|
||||
#define READ_CHECK_EXISTENCE 0x00080000U /* Also used in vg->read_status */
|
||||
|
||||
/* FIXME Deduce these next requirements internally instead of having caller specify. */
|
||||
#define LOCK_NONBLOCKING 0x00000100U /* Fail if not available immediately. */
|
||||
#define LOCK_KEEP 0x00000200U /* Do not unlock upon read failure. */
|
||||
|
||||
/* A meta-flag, useful with toollib for_each_* functions. */
|
||||
#define READ_FOR_UPDATE 0x00100000U
|
||||
|
||||
/* vg's "read_status" field */
|
||||
#define FAILED_INCONSISTENT 0x00000001U
|
||||
#define FAILED_LOCKING 0x00000002U
|
||||
#define FAILED_NOTFOUND 0x00000004U
|
||||
#define FAILED_READ_ONLY 0x00000008U
|
||||
#define FAILED_EXPORTED 0x00000010U
|
||||
#define FAILED_RESIZEABLE 0x00000020U
|
||||
#define FAILED_CLUSTERED 0x00000040U
|
||||
#define FAILED_ALLOCATION 0x00000080U
|
||||
|
||||
/* Ordered list - see lv_manip.c */
|
||||
typedef enum {
|
||||
ALLOC_INVALID,
|
||||
@ -232,6 +255,17 @@ struct volume_group {
|
||||
struct dm_list lvs;
|
||||
|
||||
struct dm_list tags;
|
||||
|
||||
/*
|
||||
* vg_t handle fields.
|
||||
* FIXME: Split these out.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Store result of the last vg_read().
|
||||
* 0 for success else appropriate FAILURE_* bits set.
|
||||
*/
|
||||
uint32_t read_status;
|
||||
};
|
||||
|
||||
/* There will be one area for each stripe */
|
||||
|
@ -2377,7 +2377,38 @@ int pv_analyze(struct cmd_context *cmd, const char *pv_name,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint32_t _vg_check_status(const struct volume_group *vg, uint32_t status)
|
||||
{
|
||||
uint32_t failure = 0;
|
||||
|
||||
if ((status & CLUSTERED) &&
|
||||
(vg_is_clustered(vg)) && !locking_is_clustered() &&
|
||||
!lockingfailed()) {
|
||||
log_error("Skipping clustered volume group %s", vg->name);
|
||||
/* Return because other flags are considered undefined. */
|
||||
return FAILED_CLUSTERED;
|
||||
}
|
||||
|
||||
if ((status & EXPORTED_VG) &&
|
||||
(vg->status & EXPORTED_VG)) {
|
||||
log_error("Volume group %s is exported", vg->name);
|
||||
failure |= FAILED_EXPORTED;
|
||||
}
|
||||
|
||||
if ((status & LVM_WRITE) &&
|
||||
!(vg->status & LVM_WRITE)) {
|
||||
log_error("Volume group %s is read-only", vg->name);
|
||||
failure |= FAILED_READ_ONLY;
|
||||
}
|
||||
|
||||
if ((status & RESIZEABLE_VG) &&
|
||||
!(vg->status & RESIZEABLE_VG)) {
|
||||
log_error("Volume group %s is not resizeable.", vg->name);
|
||||
failure |= FAILED_RESIZEABLE;
|
||||
}
|
||||
|
||||
return failure;
|
||||
}
|
||||
|
||||
/**
|
||||
* vg_check_status - check volume group status flags and log error
|
||||
@ -2461,6 +2492,138 @@ vg_t *vg_lock_and_read(struct cmd_context *cmd, const char *vg_name,
|
||||
return vg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a (vg_t) volume group handle from a struct volume_group pointer and a
|
||||
* possible failure code or zero for success.
|
||||
*/
|
||||
static vg_t *_vg_make_handle(struct cmd_context *cmd,
|
||||
struct volume_group *vg,
|
||||
uint32_t failure)
|
||||
{
|
||||
if (!vg && !(vg = dm_pool_zalloc(cmd->mem, sizeof(*vg)))) {
|
||||
log_error("Error allocating vg handle.");
|
||||
return_NULL;
|
||||
}
|
||||
|
||||
vg->read_status = failure;
|
||||
|
||||
return (vg_t *)vg;
|
||||
}
|
||||
|
||||
static vg_t *_recover_vg(struct cmd_context *cmd, const char *lock_name,
|
||||
const char *vg_name, const char *vgid,
|
||||
uint32_t lock_flags)
|
||||
{
|
||||
int consistent = 1;
|
||||
struct volume_group *vg;
|
||||
|
||||
lock_flags &= ~LCK_TYPE_MASK;
|
||||
lock_flags |= LCK_WRITE;
|
||||
|
||||
unlock_vg(cmd, lock_name);
|
||||
|
||||
dev_close_all();
|
||||
|
||||
if (!lock_vol(cmd, lock_name, lock_flags))
|
||||
return_NULL;
|
||||
|
||||
if (!(vg = vg_read_internal(cmd, vg_name, vgid, &consistent)))
|
||||
return_NULL;
|
||||
|
||||
if (!consistent)
|
||||
return_NULL;
|
||||
|
||||
return (vg_t *)vg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Consolidated locking, reading, and status flag checking.
|
||||
*
|
||||
* If the metadata is inconsistent, setting READ_ALLOW_INCONSISTENT in
|
||||
* misc_flags will return it with FAILED_INCONSISTENT set instead of
|
||||
* giving you nothing.
|
||||
*
|
||||
* Use vg_read_error(vg) to determine the result. Nonzero means there were
|
||||
* problems reading the volume group.
|
||||
* Zero value means that the VG is open and appropriate locks are held.
|
||||
*/
|
||||
static vg_t *_vg_lock_and_read(struct cmd_context *cmd, const char *vg_name,
|
||||
const char *vgid, uint32_t lock_flags,
|
||||
uint32_t status_flags, uint32_t misc_flags)
|
||||
{
|
||||
struct volume_group *vg = 0;
|
||||
const char *lock_name;
|
||||
int consistent = 1;
|
||||
int consistent_in;
|
||||
uint32_t failure = 0;
|
||||
int already_locked;
|
||||
|
||||
if (misc_flags & READ_ALLOW_INCONSISTENT || !(lock_flags & LCK_WRITE))
|
||||
consistent = 0;
|
||||
|
||||
if (!validate_name(vg_name) && !is_orphan_vg(vg_name)) {
|
||||
log_error("Volume group name %s has invalid characters",
|
||||
vg_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lock_name = is_orphan_vg(vg_name) ? VG_ORPHANS : vg_name;
|
||||
already_locked = vgname_is_locked(lock_name);
|
||||
|
||||
if (!already_locked && !lock_vol(cmd, lock_name, lock_flags)) {
|
||||
log_error("Can't get lock for %s", vg_name);
|
||||
return _vg_make_handle(cmd, vg, FAILED_LOCKING);
|
||||
}
|
||||
|
||||
if (is_orphan_vg(vg_name))
|
||||
status_flags &= ~LVM_WRITE;
|
||||
|
||||
if (misc_flags & READ_CHECK_EXISTENCE)
|
||||
consistent = 0;
|
||||
|
||||
consistent_in = consistent;
|
||||
|
||||
/* If consistent == 1, we get NULL here if correction fails. */
|
||||
if (!(vg = vg_read_internal(cmd, vg_name, vgid, &consistent))) {
|
||||
if (consistent_in && !consistent) {
|
||||
log_error("Volume group \"%s\" inconsistent.", vg_name);
|
||||
failure |= FAILED_INCONSISTENT;
|
||||
goto_bad;
|
||||
}
|
||||
|
||||
if (!(misc_flags & READ_CHECK_EXISTENCE))
|
||||
log_error("Volume group \"%s\" not found", vg_name);
|
||||
else
|
||||
failure |= READ_CHECK_EXISTENCE;
|
||||
|
||||
failure |= FAILED_NOTFOUND;
|
||||
goto_bad;
|
||||
}
|
||||
|
||||
/* consistent == 0 when VG is not found, but failed == FAILED_NOTFOUND */
|
||||
if (!consistent && !failure)
|
||||
if (!(vg = _recover_vg(cmd, lock_name, vg_name, vgid, lock_flags))) {
|
||||
log_error("Recovery of volume group \"%s\" failed.",
|
||||
vg_name);
|
||||
failure |= FAILED_INCONSISTENT;
|
||||
goto_bad;
|
||||
}
|
||||
|
||||
|
||||
failure |= _vg_check_status(vg, status_flags);
|
||||
if (failure)
|
||||
goto_bad;
|
||||
|
||||
return _vg_make_handle(cmd, vg, failure);
|
||||
|
||||
bad:
|
||||
if (failure != (FAILED_NOTFOUND | READ_CHECK_EXISTENCE) &&
|
||||
!(misc_flags & LOCK_KEEP) && !already_locked)
|
||||
unlock_vg(cmd, lock_name);
|
||||
|
||||
return _vg_make_handle(cmd, vg, failure);
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets/Sets for external LVM library
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user