1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-23 21:35:29 +03:00

host tags

This commit is contained in:
Alasdair Kergon 2004-03-08 18:13:22 +00:00
parent bd806a41df
commit 286253a73f
7 changed files with 228 additions and 6 deletions

View File

@ -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", "@*" ]
} }

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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";
} }

View 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)))