mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-02 01:18:26 +03:00
Add activation/read_only_volume_list to override LV permission in metadata.
This commit is contained in:
parent
1e482f7ca6
commit
a18dcfb533
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.89 -
|
Version 2.02.89 -
|
||||||
==================================
|
==================================
|
||||||
|
Add activation/read_only_volume_list to override LV permission in metadata.
|
||||||
Give priority to emcpower devices with duplicate PVIDs.
|
Give priority to emcpower devices with duplicate PVIDs.
|
||||||
Add check for error in _adjust_policy_params() (lvextend --use-policies).
|
Add check for error in _adjust_policy_params() (lvextend --use-policies).
|
||||||
Supports rounding of percentage (%LV, %VG...) for LV resize upward.
|
Supports rounding of percentage (%LV, %VG...) for LV resize upward.
|
||||||
|
@ -513,6 +513,16 @@ activation {
|
|||||||
#
|
#
|
||||||
# volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
|
# volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
|
||||||
|
|
||||||
|
# If read_only_volume_list is defined, each LV that is to be activated
|
||||||
|
# is checked against the list, and if it matches, it as activated
|
||||||
|
# in read-only mode. (This overrides '--permission rw' stored in the
|
||||||
|
# metadata.)
|
||||||
|
# "vgname" and "vgname/lvname" are matched exactly.
|
||||||
|
# "@tag" matches any tag set in the LV or VG.
|
||||||
|
# "@*" matches if any tag defined on the host is also set in the LV or VG
|
||||||
|
#
|
||||||
|
# read_only_volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
|
||||||
|
|
||||||
# Size (in KB) of each copy operation when mirroring
|
# Size (in KB) of each copy operation when mirroring
|
||||||
mirror_region_size = 512
|
mirror_region_size = 512
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||||
* Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@ -288,49 +288,29 @@ int activation(void)
|
|||||||
return _activation;
|
return _activation;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _passes_activation_filter(struct cmd_context *cmd,
|
static int _passes_volumes_filter(struct cmd_context *cmd,
|
||||||
struct logical_volume *lv)
|
struct logical_volume *lv,
|
||||||
|
const struct dm_config_node *cn,
|
||||||
|
const char *config_path)
|
||||||
{
|
{
|
||||||
const struct dm_config_node *cn;
|
|
||||||
const struct dm_config_value *cv;
|
const struct dm_config_value *cv;
|
||||||
const char *str;
|
const char *str;
|
||||||
static char path[PATH_MAX];
|
static char path[PATH_MAX];
|
||||||
|
|
||||||
if (!(cn = find_config_tree_node(cmd, "activation/volume_list"))) {
|
log_verbose("%s configuration setting defined: "
|
||||||
log_verbose("activation/volume_list configuration setting "
|
"Checking the list to match %s/%s",
|
||||||
"not defined, checking only host tags for %s/%s",
|
config_path, lv->vg->name, lv->name);
|
||||||
lv->vg->name, lv->name);
|
|
||||||
|
|
||||||
/* If no host tags defined, activate */
|
|
||||||
if (dm_list_empty(&cmd->tags))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* If any host tag matches any LV or VG tag, activate */
|
|
||||||
if (str_list_match_list(&cmd->tags, &lv->tags, NULL) ||
|
|
||||||
str_list_match_list(&cmd->tags, &lv->vg->tags, NULL))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
log_verbose("No host tag matches %s/%s",
|
|
||||||
lv->vg->name, lv->name);
|
|
||||||
|
|
||||||
/* Don't activate */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
log_verbose("activation/volume_list configuration setting "
|
|
||||||
"defined, checking the list to match %s/%s",
|
|
||||||
lv->vg->name, lv->name);
|
|
||||||
|
|
||||||
for (cv = cn->v; cv; cv = cv->next) {
|
for (cv = cn->v; cv; cv = cv->next) {
|
||||||
if (cv->type != DM_CFG_STRING) {
|
if (cv->type != DM_CFG_STRING) {
|
||||||
log_error("Ignoring invalid string in config file "
|
log_error("Ignoring invalid string in config file %s",
|
||||||
"activation/volume_list");
|
config_path);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
str = cv->v.str;
|
str = cv->v.str;
|
||||||
if (!*str) {
|
if (!*str) {
|
||||||
log_error("Ignoring empty string in config file "
|
log_error("Ignoring empty string in config file %s",
|
||||||
"activation/volume_list");
|
config_path);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,7 +320,7 @@ static int _passes_activation_filter(struct cmd_context *cmd,
|
|||||||
str++;
|
str++;
|
||||||
if (!*str) {
|
if (!*str) {
|
||||||
log_error("Ignoring empty tag in config file "
|
log_error("Ignoring empty tag in config file "
|
||||||
"activation/volume_list");
|
"%s", config_path);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* If any host tag matches any LV or VG tag, activate */
|
/* If any host tag matches any LV or VG tag, activate */
|
||||||
@ -377,12 +357,52 @@ static int _passes_activation_filter(struct cmd_context *cmd,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_verbose("No item supplied in activation/volume_list configuration "
|
log_verbose("No item supplied in %s configuration setting "
|
||||||
"setting matches %s/%s", lv->vg->name, lv->name);
|
"matches %s/%s", config_path, lv->vg->name, lv->name);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _passes_activation_filter(struct cmd_context *cmd,
|
||||||
|
struct logical_volume *lv)
|
||||||
|
{
|
||||||
|
const struct dm_config_node *cn;
|
||||||
|
|
||||||
|
if (!(cn = find_config_tree_node(cmd, "activation/volume_list"))) {
|
||||||
|
log_verbose("activation/volume_list configuration setting "
|
||||||
|
"not defined: Checking only host tags for %s/%s",
|
||||||
|
lv->vg->name, lv->name);
|
||||||
|
|
||||||
|
/* If no host tags defined, activate */
|
||||||
|
if (dm_list_empty(&cmd->tags))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* If any host tag matches any LV or VG tag, activate */
|
||||||
|
if (str_list_match_list(&cmd->tags, &lv->tags, NULL) ||
|
||||||
|
str_list_match_list(&cmd->tags, &lv->vg->tags, NULL))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
log_verbose("No host tag matches %s/%s",
|
||||||
|
lv->vg->name, lv->name);
|
||||||
|
|
||||||
|
/* Don't activate */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _passes_volumes_filter(cmd, lv, cn, "activation/volume_list");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _passes_readonly_filter(struct cmd_context *cmd,
|
||||||
|
struct logical_volume *lv)
|
||||||
|
{
|
||||||
|
struct dm_config_node *cn;
|
||||||
|
|
||||||
|
if (!(cn = find_config_tree_node(cmd, "activation/read_only_volume_list")))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return _passes_volumes_filter(cmd, lv, cn, "activation/read_only_volume_list");
|
||||||
|
}
|
||||||
|
|
||||||
int library_version(char *version, size_t size)
|
int library_version(char *version, size_t size)
|
||||||
{
|
{
|
||||||
if (!activation())
|
if (!activation())
|
||||||
@ -755,16 +775,22 @@ static int _lv_activate_lv(struct logical_volume *lv, struct lv_activate_opts *l
|
|||||||
static int _lv_preload(struct logical_volume *lv, struct lv_activate_opts *laopts,
|
static int _lv_preload(struct logical_volume *lv, struct lv_activate_opts *laopts,
|
||||||
int *flush_required)
|
int *flush_required)
|
||||||
{
|
{
|
||||||
int r;
|
int r = 0;
|
||||||
struct dev_manager *dm;
|
struct dev_manager *dm;
|
||||||
|
int old_readonly = laopts->read_only;
|
||||||
|
|
||||||
|
laopts->read_only = _passes_readonly_filter(lv->vg->cmd, lv);
|
||||||
|
|
||||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, (lv->status & PVMOVE) ? 0 : 1)))
|
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, (lv->status & PVMOVE) ? 0 : 1)))
|
||||||
return_0;
|
goto_out;
|
||||||
|
|
||||||
if (!(r = dev_manager_preload(dm, lv, laopts, flush_required)))
|
if (!(r = dev_manager_preload(dm, lv, laopts, flush_required)))
|
||||||
stack;
|
stack;
|
||||||
|
|
||||||
dev_manager_destroy(dm);
|
dev_manager_destroy(dm);
|
||||||
|
|
||||||
|
laopts->read_only = old_readonly;
|
||||||
|
out:
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -789,6 +815,8 @@ static int _lv_suspend_lv(struct logical_volume *lv, struct lv_activate_opts *la
|
|||||||
int r;
|
int r;
|
||||||
struct dev_manager *dm;
|
struct dev_manager *dm;
|
||||||
|
|
||||||
|
laopts->read_only = _passes_readonly_filter(lv->vg->cmd, lv);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When we are asked to manipulate (normally suspend/resume) the PVMOVE
|
* When we are asked to manipulate (normally suspend/resume) the PVMOVE
|
||||||
* device directly, we don't want to touch the devices that use it.
|
* device directly, we don't want to touch the devices that use it.
|
||||||
@ -1463,6 +1491,8 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
laopts->read_only = _passes_readonly_filter(cmd, lv);
|
||||||
|
|
||||||
if (!_lv_activate_lv(lv, laopts))
|
if (!_lv_activate_lv(lv, laopts))
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
@ -1652,13 +1682,21 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug("Activating %s/%s%s.", lv->vg->name, lv->name,
|
if (filter)
|
||||||
laopts->exclusive ? " exclusively" : "");
|
laopts->read_only = _passes_readonly_filter(cmd, lv);
|
||||||
|
|
||||||
|
log_debug("Activating %s/%s%s%s.", lv->vg->name, lv->name,
|
||||||
|
laopts->exclusive ? " exclusively" : "",
|
||||||
|
laopts->read_only ? " read-only" : "");
|
||||||
|
|
||||||
if (!lv_info(cmd, lv, 0, &info, 0, 0))
|
if (!lv_info(cmd, lv, 0, &info, 0, 0))
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
if (info.exists && !info.suspended && info.live_table) {
|
/*
|
||||||
|
* Nothing to do?
|
||||||
|
*/
|
||||||
|
if (info.exists && !info.suspended && info.live_table &&
|
||||||
|
(info.read_only == read_only_lv(lv, laopts))) {
|
||||||
r = 1;
|
r = 1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||||
* Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@ -36,6 +36,7 @@ struct lv_activate_opts {
|
|||||||
int no_merging;
|
int no_merging;
|
||||||
int real_pool;
|
int real_pool;
|
||||||
unsigned revert;
|
unsigned revert;
|
||||||
|
unsigned read_only;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* target attribute flags */
|
/* target attribute flags */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||||
* Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@ -61,9 +61,9 @@ struct lv_layer {
|
|||||||
|
|
||||||
static const char thin_layer[] = "tpool";
|
static const char thin_layer[] = "tpool";
|
||||||
|
|
||||||
static int _read_only_lv(struct logical_volume *lv)
|
int read_only_lv(struct logical_volume *lv, struct lv_activate_opts *laopts)
|
||||||
{
|
{
|
||||||
return (!(lv->vg->status & LVM_WRITE) || !(lv->status & LVM_WRITE));
|
return (laopts->read_only || !(lv->vg->status & LVM_WRITE) || !(lv->status & LVM_WRITE));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1724,7 +1724,7 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
|||||||
if (!(dnode = dm_tree_add_new_dev_with_udev_flags(dtree, name, dlid,
|
if (!(dnode = dm_tree_add_new_dev_with_udev_flags(dtree, name, dlid,
|
||||||
layer ? UINT32_C(0) : (uint32_t) lv->major,
|
layer ? UINT32_C(0) : (uint32_t) lv->major,
|
||||||
layer ? UINT32_C(0) : (uint32_t) lv->minor,
|
layer ? UINT32_C(0) : (uint32_t) lv->minor,
|
||||||
_read_only_lv(lv),
|
read_only_lv(lv, laopts),
|
||||||
((lv->vg->status & PRECOMMITTED) | laopts->revert) ? 1 : 0,
|
((lv->vg->status & PRECOMMITTED) | laopts->revert) ? 1 : 0,
|
||||||
lvlayer,
|
lvlayer,
|
||||||
_get_udev_flags(dm, lv, layer))))
|
_get_udev_flags(dm, lv, layer))))
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||||
* Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@ -26,6 +26,8 @@ struct dev_manager;
|
|||||||
struct dm_info;
|
struct dm_info;
|
||||||
struct device;
|
struct device;
|
||||||
|
|
||||||
|
int read_only_lv(struct logical_volume *lv, struct lv_activate_opts *laopts);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constructor and destructor.
|
* Constructor and destructor.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user