/* vg_read and vg_read_for_update flags */
#define READ_ALLOW_INCONSISTENT 0x00010000U
#define READ_ALLOW_EXPORTED 0x00020000U
+#define READ_OK_NOTFOUND 0x00040000U
#define READ_WARN_INCONSISTENT 0x00080000U
-
-/* A meta-flag, useful with toollib for_each_* functions. */
-#define READ_FOR_UPDATE 0x00100000U
+#define READ_FOR_UPDATE 0x00100000U /* A meta-flag, useful with toollib for_each_* functions. */
/* vg's "read_status" field */
#define FAILED_INCONSISTENT 0x00000001U
* 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, uint32_t lockd_state);
+ const char *vgid, uint32_t read_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, uint32_t lockd_state);
+ const char *vgid, uint32_t read_flags, uint32_t lockd_state);
/*
* Test validity of a VG handle.
* 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
+ * read_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
* Zero value means that the VG is open and appropriate locks are held.
*/
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,
+ const char *vgid,
+ uint32_t lock_flags,
+ uint64_t status_flags,
+ uint32_t read_flags,
uint32_t lockd_state)
{
struct volume_group *vg = NULL;
uint32_t warn_flags = 0;
int already_locked;
- if (misc_flags & READ_ALLOW_INCONSISTENT || lock_flags != LCK_VG_WRITE)
+ if ((read_flags & READ_ALLOW_INCONSISTENT) || (lock_flags != LCK_VG_WRITE))
consistent = 0;
if (!validate_name(vg_name) && !is_orphan_vg(vg_name)) {
consistent_in = consistent;
warn_flags = WARN_PV_READ;
- if (consistent || (misc_flags & READ_WARN_INCONSISTENT))
+ if (consistent || (read_flags & READ_WARN_INCONSISTENT))
warn_flags |= WARN_INCONSISTENT;
/* If consistent == 1, we get NULL here if correction fails. */
failure |= FAILED_INCONSISTENT;
goto bad;
}
- log_error("Volume group \"%s\" not found", vg_name);
+ if (!(read_flags & READ_OK_NOTFOUND))
+ log_error("Volume group \"%s\" not found", vg_name);
failure |= FAILED_NOTFOUND;
goto bad;
}
* *consistent = 1.
*/
struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name,
- const char *vgid, uint32_t flags, uint32_t lockd_state)
+ const char *vgid, uint32_t read_flags, uint32_t lockd_state)
{
- uint64_t status = UINT64_C(0);
+ uint64_t status_flags = UINT64_C(0);
uint32_t lock_flags = LCK_VG_READ;
- if (flags & READ_FOR_UPDATE) {
- status |= EXPORTED_VG | LVM_WRITE;
+ if (read_flags & READ_FOR_UPDATE) {
+ status_flags |= EXPORTED_VG | LVM_WRITE;
lock_flags = LCK_VG_WRITE;
}
- if (flags & READ_ALLOW_EXPORTED)
- status &= ~EXPORTED_VG;
+ if (read_flags & READ_ALLOW_EXPORTED)
+ status_flags &= ~EXPORTED_VG;
- return _vg_lock_and_read(cmd, vg_name, vgid, lock_flags, status, flags, lockd_state);
+ return _vg_lock_and_read(cmd, vg_name, vgid, lock_flags, status_flags, read_flags, lockd_state);
}
/*
* 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, uint32_t lockd_state)
+ const char *vgid, uint32_t read_flags, uint32_t lockd_state)
{
- return vg_read(cmd, vg_name, vgid, flags | READ_FOR_UPDATE, lockd_state);
+ return vg_read(cmd, vg_name, vgid, read_flags | READ_FOR_UPDATE, lockd_state);
}
/*
* If *skip is 1, it's OK for the caller to read the list of PVs in the VG.
*/
static int _ignore_vg(struct volume_group *vg, const char *vg_name,
- struct dm_list *arg_vgnames, int allow_inconsistent, int *skip)
+ struct dm_list *arg_vgnames, uint32_t read_flags, int *skip)
{
uint32_t read_error = vg_read_error(vg);
*skip = 0;
- if ((read_error & FAILED_INCONSISTENT) && allow_inconsistent)
+ if ((read_error & FAILED_NOTFOUND) && (read_flags & READ_OK_NOTFOUND)) {
+ read_error &= ~FAILED_NOTFOUND;
+ *skip = 1;
+ return 0;
+ }
+
+ if ((read_error & FAILED_INCONSISTENT) && (read_flags & READ_OK_NOTFOUND)) {
+ read_error &= ~FAILED_INCONSISTENT;
+ *skip = 1;
+ return 0;
+ }
+
+ if ((read_error & FAILED_INCONSISTENT) && (read_flags & READ_ALLOW_INCONSISTENT))
read_error &= ~FAILED_INCONSISTENT; /* Check for other errors */
if ((read_error & FAILED_CLUSTERED) && vg->cmd->ignore_clustered_vgs) {
}
vg = vg_read(cmd, vg_name, vg_uuid, flags, lockd_state);
- if (_ignore_vg(vg, vg_name, arg_vgnames, flags & READ_ALLOW_INCONSISTENT, &skip)) {
+ if (_ignore_vg(vg, vg_name, arg_vgnames, flags, &skip)) {
stack;
ret_max = ECMD_FAILED;
goto endvg;
}
vg = vg_read(cmd, vg_name, vg_uuid, flags, lockd_state);
- if (_ignore_vg(vg, vg_name, arg_vgnames, flags & READ_ALLOW_INCONSISTENT, &skip)) {
+ if (_ignore_vg(vg, vg_name, arg_vgnames, flags, &skip)) {
stack;
ret_max = ECMD_FAILED;
goto endvg;
* should produce an error. Any devices remaining in all_devices were
* not found and should be processed by process_device_list().
*/
-static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t flags,
+static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
struct dm_list *all_vgnameids,
struct dm_list *all_devices,
struct dm_list *arg_devices,
continue;
}
- 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)) {
+ vg = vg_read(cmd, vg_name, vg_uuid, read_flags, lockd_state);
+ if (_ignore_vg(vg, vg_name, NULL, read_flags, &skip)) {
stack;
ret_max = ECMD_FAILED;
if (!skip)
int process_each_pv(struct cmd_context *cmd,
int argc, char **argv,
const char *only_this_vgname,
- uint32_t flags,
+ uint32_t read_flags,
struct processing_handle *handle,
process_single_pv_fn_t process_single_pv)
{
int ret_max = ECMD_PROCESSED;
int ret;
+ /*
+ * When processing a specific VG name, warn if it's inconsistent and
+ * print an error if it's not found. Otherwise we're processing all
+ * VGs, in which case the command doesn't care if the VG is inconsisent
+ * or not found; it just wants to skip that VG. (It may be not found
+ * if it was removed between creating the list of all VGs and then
+ * processing each VG.
+ */
+ if (only_this_vgname)
+ read_flags |= READ_WARN_INCONSISTENT;
+ else
+ read_flags |= READ_OK_NOTFOUND;
+
/* Disable error in vg_read so we can print it from ignore_vg. */
cmd->vg_read_print_access_error = 0;
/* get_arg_devices reports the error for any PV names not found. */
ret_max = ECMD_FAILED;
- ret = _process_pvs_in_vgs(cmd, flags, &all_vgnameids, &all_devices,
+ ret = _process_pvs_in_vgs(cmd, read_flags, &all_vgnameids, &all_devices,
&arg_devices, &arg_tags,
process_all_pvs, process_all_devices,
handle, process_single_pv);