mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-23 21:35:29 +03:00
host tags
This commit is contained in:
parent
bd806a41df
commit
286253a73f
@ -219,6 +219,14 @@ activation {
|
|||||||
|
|
||||||
# Nice value used while devices suspended
|
# Nice value used while devices suspended
|
||||||
process_priority = -18
|
process_priority = -18
|
||||||
|
|
||||||
|
# If volume_list is defined, each LV is only activated if there is a
|
||||||
|
# match against the list.
|
||||||
|
# "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
|
||||||
|
#
|
||||||
|
# volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "toolcontext.h"
|
#include "toolcontext.h"
|
||||||
#include "dev_manager.h"
|
#include "dev_manager.h"
|
||||||
|
#include "str_list.h"
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -111,6 +112,87 @@ int activation(void)
|
|||||||
return _activation;
|
return _activation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _passes_activation_filter(struct cmd_context *cmd,
|
||||||
|
struct logical_volume *lv)
|
||||||
|
{
|
||||||
|
struct config_node *cn;
|
||||||
|
struct config_value *cv;
|
||||||
|
char *str;
|
||||||
|
char path[PATH_MAX];
|
||||||
|
|
||||||
|
if (!(cn = find_config_node(cmd->cf->root, "activation/volume_list",
|
||||||
|
'/'))) {
|
||||||
|
/* If no hosts tags defined, activate */
|
||||||
|
if (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) ||
|
||||||
|
str_list_match_list(&cmd->tags, &lv->vg->tags))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Don't activate */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cv = cn->v; cv; cv = cv->next) {
|
||||||
|
if (cv->type != CFG_STRING) {
|
||||||
|
log_error("Ignoring invalid string in config file "
|
||||||
|
"activation/volume_list");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
str = cv->v.str;
|
||||||
|
if (!*str) {
|
||||||
|
log_error("Ignoring empty string in config file "
|
||||||
|
"activation/volume_list");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tag? */
|
||||||
|
if (*str == '@') {
|
||||||
|
str++;
|
||||||
|
if (!*str) {
|
||||||
|
log_error("Ignoring empty tag in config file "
|
||||||
|
"activation/volume_list");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* If any host tag matches any LV or VG tag, activate */
|
||||||
|
if (!strcmp(str, "*")) {
|
||||||
|
if (str_list_match_list(&cmd->tags, &lv->tags)
|
||||||
|
|| str_list_match_list(&cmd->tags,
|
||||||
|
&lv->vg->tags))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* If supplied tag matches LV or VG tag, activate */
|
||||||
|
if (str_list_match_item(&lv->tags, str) ||
|
||||||
|
str_list_match_item(&lv->vg->tags, str))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!index(str, '/')) {
|
||||||
|
/* vgname supplied */
|
||||||
|
if (!strcmp(str, lv->vg->name))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* vgname/lvname */
|
||||||
|
if (lvm_snprintf(path, sizeof(path), "%s/%s", lv->vg->name,
|
||||||
|
lv->name) < 0) {
|
||||||
|
log_error("lvm_snprintf error from %s/%s", lv->vg->name,
|
||||||
|
lv->name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strcmp(path, str))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int library_version(char *version, size_t size)
|
int library_version(char *version, size_t size)
|
||||||
{
|
{
|
||||||
if (!activation())
|
if (!activation())
|
||||||
@ -466,6 +548,12 @@ int lv_activate(struct cmd_context *cmd, const char *lvid_s)
|
|||||||
if (!(lv = lv_from_lvid(cmd, lvid_s)))
|
if (!(lv = lv_from_lvid(cmd, lvid_s)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (!_passes_activation_filter(cmd, lv)) {
|
||||||
|
log_verbose("Not activating %s/%s due to config file settings",
|
||||||
|
lv->vg->name, lv->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (test_mode()) {
|
if (test_mode()) {
|
||||||
_skip("Activating '%s'.", lv->name);
|
_skip("Activating '%s'.", lv->name);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "format-text.h"
|
#include "format-text.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "memlock.h"
|
#include "memlock.h"
|
||||||
|
#include "str_list.h"
|
||||||
|
|
||||||
#ifdef HAVE_LIBDL
|
#ifdef HAVE_LIBDL
|
||||||
#include "sharedlib.h"
|
#include "sharedlib.h"
|
||||||
@ -110,8 +111,12 @@ static void _init_logging(struct cmd_context *cmd)
|
|||||||
append = 0;
|
append = 0;
|
||||||
|
|
||||||
log_file = find_config_str(cmd->cf->root, "log/file", '/', 0);
|
log_file = find_config_str(cmd->cf->root, "log/file", '/', 0);
|
||||||
if (log_file)
|
|
||||||
|
if (log_file) {
|
||||||
|
release_log_memory();
|
||||||
|
fin_log();
|
||||||
init_log_file(log_file, append);
|
init_log_file(log_file, append);
|
||||||
|
}
|
||||||
|
|
||||||
log_file = find_config_str(cmd->cf->root, "log/activate_file", '/', 0);
|
log_file = find_config_str(cmd->cf->root, "log/activate_file", '/', 0);
|
||||||
if (log_file)
|
if (log_file)
|
||||||
@ -442,6 +447,105 @@ static int _init_hostname(struct cmd_context *cmd)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _set_tag(struct cmd_context *cmd, const char *tag)
|
||||||
|
{
|
||||||
|
log_very_verbose("Setting host tag: %s", pool_strdup(cmd->libmem, tag));
|
||||||
|
|
||||||
|
if (!str_list_add(cmd->libmem, &cmd->tags, tag)) {
|
||||||
|
log_error("_init_tags: str_list_add %s failed", tag);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _check_host_filters(struct cmd_context *cmd, struct config_node *hn,
|
||||||
|
int *passes)
|
||||||
|
{
|
||||||
|
struct config_node *cn;
|
||||||
|
struct config_value *cv;
|
||||||
|
|
||||||
|
*passes = 1;
|
||||||
|
|
||||||
|
for (cn = hn; cn; cn = cn->sib) {
|
||||||
|
if (!cn->v)
|
||||||
|
continue;
|
||||||
|
if (!strcmp(cn->key, "host_list")) {
|
||||||
|
*passes = 0;
|
||||||
|
if (cn->v->type == CFG_EMPTY_ARRAY)
|
||||||
|
continue;
|
||||||
|
for (cv = cn->v; cv; cv = cv->next) {
|
||||||
|
if (cv->type != CFG_STRING) {
|
||||||
|
log_error("Invalid hostname string "
|
||||||
|
"for tag %s", cn->key);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!strcmp(cv->v.str, cmd->hostname)) {
|
||||||
|
*passes = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!strcmp(cn->key, "host_filter")) {
|
||||||
|
log_error("host_filter not supported yet");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _init_tags(struct cmd_context *cmd)
|
||||||
|
{
|
||||||
|
struct config_node *tn, *cn;
|
||||||
|
const char *tag;
|
||||||
|
int passes;
|
||||||
|
|
||||||
|
list_init(&cmd->tags);
|
||||||
|
|
||||||
|
if (!(tn = find_config_node(cmd->cf->root, "tags", '/')) ||
|
||||||
|
!tn->child) {
|
||||||
|
log_very_verbose("No tags defined in config file");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (find_config_int(cmd->cf->root, "tags/hosttags", '/',
|
||||||
|
DEFAULT_HOSTTAGS)) {
|
||||||
|
/* FIXME Strip out invalid chars: only A-Za-z0-9_+.- */
|
||||||
|
if (!_set_tag(cmd, cmd->hostname)) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cn = tn->child; cn; cn = cn->sib) {
|
||||||
|
if (cn->v)
|
||||||
|
continue;
|
||||||
|
tag = cn->key;
|
||||||
|
if (*tag == '@')
|
||||||
|
tag++;
|
||||||
|
if (!validate_name(tag)) {
|
||||||
|
log_error("Invalid tag in config file: %s", cn->key);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (cn->child) {
|
||||||
|
passes = 0;
|
||||||
|
if (!_check_host_filters(cmd, cn->child, &passes)) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!passes)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!_set_tag(cmd, tag)) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Entry point */
|
/* Entry point */
|
||||||
struct cmd_context *create_toolcontext(struct arg *the_args)
|
struct cmd_context *create_toolcontext(struct arg *the_args)
|
||||||
{
|
{
|
||||||
@ -509,6 +613,9 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
|
|||||||
if (!_init_hostname(cmd))
|
if (!_init_hostname(cmd))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (!_init_tags(cmd))
|
||||||
|
goto error;
|
||||||
|
|
||||||
cmd->current_settings = cmd->default_settings;
|
cmd->current_settings = cmd->default_settings;
|
||||||
|
|
||||||
return cmd;
|
return cmd;
|
||||||
@ -518,6 +625,16 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int refresh_toolcontext(struct cmd_context *cmd)
|
||||||
|
{
|
||||||
|
_init_logging(cmd);
|
||||||
|
_init_tags(cmd);
|
||||||
|
|
||||||
|
/* FIXME Reset filters and dev_cache */
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void _destroy_formats(struct list *formats)
|
static void _destroy_formats(struct list *formats)
|
||||||
{
|
{
|
||||||
struct list *fmtl, *tmp;
|
struct list *fmtl, *tmp;
|
||||||
|
@ -63,6 +63,9 @@ struct cmd_context {
|
|||||||
struct config_info default_settings;
|
struct config_info default_settings;
|
||||||
struct config_info current_settings;
|
struct config_info current_settings;
|
||||||
|
|
||||||
|
/* List of defined tags */
|
||||||
|
struct list tags;
|
||||||
|
|
||||||
char sys_dir[PATH_MAX];
|
char sys_dir[PATH_MAX];
|
||||||
char dev_dir[PATH_MAX];
|
char dev_dir[PATH_MAX];
|
||||||
char proc_dir[PATH_MAX];
|
char proc_dir[PATH_MAX];
|
||||||
@ -70,5 +73,6 @@ struct cmd_context {
|
|||||||
|
|
||||||
struct cmd_context *create_toolcontext(struct arg *the_args);
|
struct cmd_context *create_toolcontext(struct arg *the_args);
|
||||||
void destroy_toolcontext(struct cmd_context *cmd);
|
void destroy_toolcontext(struct cmd_context *cmd);
|
||||||
|
int refresh_toolcontext(struct cmd_context *cmd);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#define DEFAULT_INDENT 1
|
#define DEFAULT_INDENT 1
|
||||||
#define DEFAULT_UNITS "h"
|
#define DEFAULT_UNITS "h"
|
||||||
#define DEFAULT_SUFFIX 1
|
#define DEFAULT_SUFFIX 1
|
||||||
|
#define DEFAULT_HOSTTAGS 0
|
||||||
|
|
||||||
#ifdef DEVMAPPER_SUPPORT
|
#ifdef DEVMAPPER_SUPPORT
|
||||||
# define DEFAULT_ACTIVATION 1
|
# define DEFAULT_ACTIVATION 1
|
||||||
|
@ -47,11 +47,9 @@ void init_log_file(const char *log_file, int append)
|
|||||||
|
|
||||||
void init_log_direct(const char *log_file, int append)
|
void init_log_direct(const char *log_file, int append)
|
||||||
{
|
{
|
||||||
const char *filename;
|
|
||||||
int open_flags = append ? 0 : O_TRUNC;
|
int open_flags = append ? 0 : O_TRUNC;
|
||||||
|
|
||||||
filename = dbg_strdup(log_file);
|
dev_create_file(log_file, &_log_dev, &_log_dev_alias);
|
||||||
dev_create_file(filename, &_log_dev, &_log_dev_alias);
|
|
||||||
if (!dev_open_flags(&_log_dev, O_RDWR | O_CREAT | open_flags, 1, 0))
|
if (!dev_open_flags(&_log_dev, O_RDWR | O_CREAT | open_flags, 1, 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -76,6 +74,9 @@ void log_suppress(int suppress)
|
|||||||
|
|
||||||
void release_log_memory(void)
|
void release_log_memory(void)
|
||||||
{
|
{
|
||||||
|
if (!_log_direct)
|
||||||
|
return;
|
||||||
|
|
||||||
dbg_free((char *) _log_dev_alias.str);
|
dbg_free((char *) _log_dev_alias.str);
|
||||||
_log_dev_alias.str = "activate_log file";
|
_log_dev_alias.str = "activate_log file";
|
||||||
}
|
}
|
||||||
|
@ -750,8 +750,11 @@ static int _run_command(struct cmd_context *cmd, int argc, char **argv)
|
|||||||
set_cmd_name(cmd->command->name);
|
set_cmd_name(cmd->command->name);
|
||||||
|
|
||||||
if (reload_config_file(&cmd->cf)) {
|
if (reload_config_file(&cmd->cf)) {
|
||||||
;
|
/* Reinitialise various settings inc. logging, filters */
|
||||||
/* FIXME Reinitialise various settings inc. logging, filters */
|
if (!refresh_toolcontext(cmd)) {
|
||||||
|
log_error("Updated config file invalid. Aborting.");
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = _get_settings(cmd)))
|
if ((ret = _get_settings(cmd)))
|
||||||
|
Loading…
Reference in New Issue
Block a user