Gitweb:
http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c7b17836ea139b...
Commit: c7b17836ea139ba7448f5a5c1d2fbe93676baa36
Parent: ceb79c9a500f38ac31c8d79904c3730805feb3dc
Author: Petr Rockai <prockai(a)redhat.com>
AuthorDate: Mon Aug 13 19:44:10 2012 +0200
Committer: Petr Rockai <prockai(a)redhat.com>
CommitterDate: Wed Sep 26 14:49:15 2012 +0200
Implement devices/global_filter.
The global filter is applied first, and is also applied in pvscan --cache (which
is called from udev rules to keep lvmetad updated). Cf. example.conf.
---
daemons/lvmetad/lvmetad-core.c | 87 +++++++++++++-------
doc/example.conf.in | 8 ++
lib/cache/lvmcache.c | 2 -
lib/cache/lvmetad.c | 167 ++++++++++++++++++++++++++++++--------
lib/cache/lvmetad.h | 27 ++++++-
lib/commands/toolcontext.c | 45 +++++++++--
lib/commands/toolcontext.h | 1 +
lib/device/dev-cache.c | 4 +-
lib/device/dev-cache.h | 1 +
lib/filters/filter-persistent.c | 5 +-
lib/filters/filter-persistent.h | 1 -
libdaemon/client/daemon-shared.c | 4 +-
test/lib/aux.sh | 2 +-
tools/pvscan.c | 31 +-------
tools/vgrename.c | 3 +-
tools/vgscan.c | 3 +-
16 files changed, 279 insertions(+), 112 deletions(-)
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
index c96e285..09ba20d 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -41,6 +41,8 @@ typedef struct {
pthread_mutex_t vgid_to_metadata;
pthread_mutex_t pvid_to_vgid;
} lock;
+ char token[128];
+ pthread_mutex_t token_lock;
} lvmetad_state;
static void lock_pvid_to_pvmeta(lvmetad_state *s) {
@@ -58,6 +60,16 @@ static void lock_pvid_to_vgid(lvmetad_state *s) {
static void unlock_pvid_to_vgid(lvmetad_state *s) {
pthread_mutex_unlock(&s->lock.pvid_to_vgid); }
+static response reply_fail(const char *reason)
+{
+ return daemon_reply_simple("failed", "reason = %s", reason, NULL);
+}
+
+static response reply_unknown(const char *reason)
+{
+ return daemon_reply_simple("unknown", "reason = %s", reason, NULL);
+}
+
/*
* TODO: It may be beneficial to clean up the vg lock hash from time to time,
* since if we have many "rogue" requests for nonexistent things, we will keep
@@ -257,13 +269,13 @@ static response pv_lookup(lvmetad_state *s, request r)
struct dm_config_node *pv;
if (!pvid && !devt)
- return daemon_reply_simple("failed", "reason = %s", "need PVID
or device", NULL);
+ return reply_fail("need PVID or device");
if (!(res.cft = dm_config_create()))
- return daemon_reply_simple("failed", "reason = %s", "out of
memory", NULL);
+ return reply_fail("out of memory");
if (!(res.cft->root = make_text_node(res.cft, "response", "OK",
NULL, NULL)))
- return daemon_reply_simple("failed", "reason = %s", "out of
memory", NULL);
+ return reply_fail("out of memory");
lock_pvid_to_pvmeta(s);
if (!pvid && devt)
@@ -273,14 +285,14 @@ static response pv_lookup(lvmetad_state *s, request r)
WARN(s, "pv_lookup: could not find device %" PRIu64, devt);
unlock_pvid_to_pvmeta(s);
dm_config_destroy(res.cft);
- return daemon_reply_simple("unknown", "reason = %s", "device
not found", NULL);
+ return reply_unknown("device not found");
}
pv = make_pv_node(s, pvid, res.cft, NULL, res.cft->root);
if (!pv) {
unlock_pvid_to_pvmeta(s);
dm_config_destroy(res.cft);
- return daemon_reply_simple("unknown", "reason = %s", "PV not
found", NULL);
+ return reply_unknown("PV not found");
}
pv->key = "physical_volume";
@@ -381,12 +393,12 @@ static response vg_lookup(lvmetad_state *s, request r)
DEBUG(s, "vg_lookup: updated uuid = %s, name = %s", uuid, name);
if (!uuid)
- return daemon_reply_simple("unknown", "reason = %s", "VG not
found", NULL);
+ return reply_unknown("VG not found");
cft = lock_vg(s, uuid);
if (!cft || !cft->root) {
unlock_vg(s, uuid);
- return daemon_reply_simple("unknown", "reason = %s", "UUID not
found", NULL);
+ return reply_unknown("UUID not found");
}
metadata = cft->root;
@@ -426,7 +438,7 @@ static response vg_lookup(lvmetad_state *s, request r)
return res;
bad:
unlock_vg(s, uuid);
- return daemon_reply_simple("failed", "reason = %s", "Out of
memory", NULL);
+ return reply_fail("out of memory");
}
static int compare_value(struct dm_config_value *a, struct dm_config_value *b)
@@ -694,7 +706,7 @@ static response pv_gone(lvmetad_state *s, request r)
pvid = dm_hash_lookup_binary(s->device_to_pvid, &device, sizeof(device));
if (!pvid) {
unlock_pvid_to_pvmeta(s);
- return daemon_reply_simple("unknown", "reason = %s", "device
not in cache", NULL);
+ return reply_unknown("device not in cache");
}
DEBUG(s, "pv_gone (updated): %s / %" PRIu64, pvid, device);
@@ -709,7 +721,7 @@ static response pv_gone(lvmetad_state *s, request r)
dm_config_destroy(pvmeta);
return daemon_reply_simple("OK", NULL);
} else
- return daemon_reply_simple("unknown", "reason = %s", "PVID
does not exist", NULL);
+ return reply_unknown("PVID does not exist");
}
static response pv_found(lvmetad_state *s, request r)
@@ -726,12 +738,12 @@ static response pv_found(lvmetad_state *s, request r)
int complete = 0, orphan = 0;
if (!pvid)
- return daemon_reply_simple("failed", "reason = %s", "need PV
UUID", NULL);
+ return reply_fail("need PV UUID");
if (!pvmeta)
- return daemon_reply_simple("failed", "reason = %s", "need PV
metadata", NULL);
+ return reply_fail("need PV metadata");
if (!dm_config_get_uint64(pvmeta, "pvmeta/device", &device))
- return daemon_reply_simple("failed", "reason = %s", "need PV
device number", NULL);
+ return reply_fail("need PV device number");
DEBUG(s, "pv_found %s, vgid = %s, device = %" PRIu64, pvid, vgid, device);
@@ -745,14 +757,14 @@ static response pv_found(lvmetad_state *s, request r)
if (!(cft = dm_config_create()) ||
!(cft->root = dm_config_clone_node(cft, pvmeta, 0))) {
unlock_pvid_to_pvmeta(s);
- return daemon_reply_simple("failed", "reason = %s", "out of
memory", NULL);
+ return reply_fail("out of memory");
}
pvid_dup = dm_config_find_str(cft->root, "pvmeta/id", NULL);
if (!dm_hash_insert(s->pvid_to_pvmeta, pvid, cft) ||
!dm_hash_insert_binary(s->device_to_pvid, &device, sizeof(device),
(void*)pvid_dup)) {
unlock_pvid_to_pvmeta(s);
- return daemon_reply_simple("failed", "reason = %s", "out of
memory", NULL);
+ return reply_fail("out of memory");
}
if (pvmeta_old)
dm_config_destroy(pvmeta_old);
@@ -761,16 +773,15 @@ static response pv_found(lvmetad_state *s, request r)
if (metadata) {
if (!vgid)
- return daemon_reply_simple("failed", "reason = %s", "need VG
UUID", NULL);
+ return reply_fail("need VG UUID");
DEBUG(s, "obtained vgid = %s, vgname = %s", vgid, vgname);
if (!vgname)
- return daemon_reply_simple("failed", "reason = %s", "need VG
name", NULL);
+ return reply_fail("need VG name");
if (daemon_request_int(r, "metadata/seqno", -1) < 0)
- return daemon_reply_simple("failed", "reason = %s", "need VG
seqno", NULL);
+ return reply_fail("need VG seqno");
if (!update_metadata(s, vgname, vgid, metadata))
- return daemon_reply_simple("failed", "reason = %s",
- "metadata update failed", NULL);
+ return reply_fail("metadata update failed");
} else {
lock_pvid_to_vgid(s);
vgid = dm_hash_lookup(s->pvid_to_vgid, pvid);
@@ -784,8 +795,7 @@ static response pv_found(lvmetad_state *s, request r)
orphan = 1;
else {
unlock_vg(s, vgid);
- return daemon_reply_simple("failed", "reason = %s",
- "non-orphan VG without metadata encountered", NULL);
+ return reply_fail("non-orphan VG without metadata encountered");
}
unlock_vg(s, vgid);
}
@@ -804,17 +814,16 @@ static response vg_update(lvmetad_state *s, request r)
const char *vgname = daemon_request_str(r, "vgname", NULL);
if (metadata) {
if (!vgid)
- return daemon_reply_simple("failed", "reason = %s", "need VG
UUID", NULL);
+ return reply_fail("need VG UUID");
if (!vgname)
- return daemon_reply_simple("failed", "reason = %s", "need VG
name", NULL);
+ return reply_fail("need VG name");
if (daemon_request_int(r, "metadata/seqno", -1) < 0)
- return daemon_reply_simple("failed", "reason = %s", "need VG
seqno", NULL);
+ return reply_fail("need VG seqno");
/* TODO defer metadata update here; add a separate vg_commit
* call; if client does not commit, die */
if (!update_metadata(s, vgname, vgid, metadata))
- return daemon_reply_simple("failed", "reason = %s",
- "metadata update failed", NULL);
+ return reply_fail("metadata update failed");
}
return daemon_reply_simple("OK", NULL);
}
@@ -824,7 +833,7 @@ static response vg_remove(lvmetad_state *s, request r)
const char *vgid = daemon_request_str(r, "uuid", NULL);
if (!vgid)
- return daemon_reply_simple("failed", "reason = %s", "need VG
UUID", NULL);
+ return reply_fail("need VG UUID");
DEBUG(s, "vg_remove: %s", vgid);
@@ -839,6 +848,24 @@ static response handler(daemon_state s, client_handle h, request r)
{
lvmetad_state *state = s.private;
const char *rq = daemon_request_str(r, "request", "NONE");
+ const char *token = daemon_request_str(r, "token", "NONE");
+
+ pthread_mutex_lock(&state->token_lock);
+ if (!strcmp(rq, "token_update")) {
+ strncpy(state->token, token, 128);
+ state->token[127] = 0;
+ pthread_mutex_unlock(&state->token_lock);
+ return daemon_reply_simple("OK", NULL);
+ }
+
+ if (strcmp(token, state->token)) {
+ pthread_mutex_unlock(&state->token_lock);
+ return daemon_reply_simple("token_mismatch",
+ "expected = %s", state->token,
+ "received = %s", token,
+ "reason = %s", "token mismatch", NULL);
+ }
+ pthread_mutex_unlock(&state->token_lock);
/*
* TODO Add a stats call, with transaction count/rate, time since last
@@ -869,7 +896,7 @@ static response handler(daemon_state s, client_handle h, request r)
if (!strcmp(rq, "vg_list"))
return vg_list(state, r);
- return daemon_reply_simple("failed", "reason = %s", "no such
request", NULL);
+ return reply_fail("request not implemented");
}
static int init(daemon_state *s)
@@ -885,11 +912,13 @@ static int init(daemon_state *s)
ls->pvid_to_vgid = dm_hash_create(32);
ls->vgname_to_vgid = dm_hash_create(32);
ls->lock.vg = dm_hash_create(32);
+ ls->token[0] = 0;
pthread_mutexattr_init(&rec);
pthread_mutexattr_settype(&rec, PTHREAD_MUTEX_RECURSIVE_NP);
pthread_mutex_init(&ls->lock.pvid_to_pvmeta, &rec);
pthread_mutex_init(&ls->lock.vgid_to_metadata, &rec);
pthread_mutex_init(&ls->lock.pvid_to_vgid, NULL);
+ pthread_mutex_init(&ls->token_lock, NULL);
/* Set up stderr logging depending on the -d option. */
daemon_log_parse(ls->log, DAEMON_LOG_OUTLET_STDERR, ls->debug_config, 1);
diff --git a/doc/example.conf.in b/doc/example.conf.in
index 7b26bdc..b4cda6f 100644
--- a/doc/example.conf.in
+++ b/doc/example.conf.in
@@ -79,6 +79,14 @@ devices {
# Use anchors if you want to be really specific
# filter = [ "a|^/dev/hda8$|", "r/.*/" ]
+ # Since "filter" is often overriden from command line, it is not suitable
+ # for system-wide device filtering (udev rules, lvmetad). To hide devices
+ # from LVM-specific udev processing and/or from lvmetad, you need to set
+ # global_filter. The syntax is the same as for normal "filter"
+ # above. Devices that fail the global_filter are not even opened by LVM.
+
+ # global_filter = []
+
# The results of the filtering are cached on disk to avoid
# rescanning dud devices (which can take a very long time).
# By default this cache is stored in the @DEFAULT_SYS_DIR@/@DEFAULT_CACHE_SUBDIR@
directory
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 6f9cfad..2c431b1 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -109,8 +109,6 @@ int lvmcache_init(void)
_vg_global_lock_held = 0;
}
- lvmetad_init();
-
return 1;
}
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index 53dbab0..90d43dd 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -20,38 +20,120 @@
#include "lvmcache.h"
#include "lvmetad-client.h"
#include "format-text.h" // TODO for disk_locn, used as a DA representation
+#include "filter.h"
+#include "assert.h"
+#include "crc.h"
-static int _using_lvmetad = 0;
static daemon_handle _lvmetad;
-static const char *_lvmetad_token;
+static int _lvmetad_use = 0;
+static int _lvmetad_connected = 0;
-void lvmetad_init(void)
+static char *_lvmetad_token = NULL;
+static const char *_lvmetad_socket = NULL;
+static struct cmd_context *_lvmetad_cmd = NULL;
+
+void lvmetad_disconnect(void)
+{
+ daemon_close(_lvmetad);
+ _lvmetad_connected = 0;
+ _lvmetad_cmd = NULL;
+}
+
+void lvmetad_init(struct cmd_context *cmd)
{
- const char *socket = getenv("LVM_LVMETAD_SOCKET");
- if (_using_lvmetad) { /* configured by the toolcontext */
- _lvmetad = lvmetad_open(socket ?: DEFAULT_RUN_DIR "/lvmetad.socket");
- if (_lvmetad.socket_fd < 0 || _lvmetad.error) {
+ if (_lvmetad_use && _lvmetad_socket && !_lvmetad_connected) {
+ assert(_lvmetad_socket);
+ _lvmetad = lvmetad_open(_lvmetad_socket);
+ if (_lvmetad.socket_fd >= 0 && !_lvmetad.error) {
+ _lvmetad_connected = 1;
+ _lvmetad_cmd = cmd;
+ } else
log_warn("WARNING: Failed to connect to lvmetad: %s. Falling back to internal
scanning.", strerror(_lvmetad.error));
- _using_lvmetad = 0;
- }
}
}
+int lvmetad_active(void)
+{
+ return _lvmetad_use && _lvmetad_connected;
+}
+
+void lvmetad_set_active(int active)
+{
+ _lvmetad_use = active;
+}
+
+void lvmetad_set_token(const struct dm_config_value *filter)
+{
+ if (_lvmetad_token)
+ dm_free(_lvmetad_token);
+ int ft = 0;
+ while (filter && filter->type == DM_CFG_STRING) {
+ ft = calc_crc(ft, (const uint8_t *) filter->v.str, strlen(filter->v.str));
+ filter = filter->next;
+ }
+ if (!dm_asprintf(&_lvmetad_token, "filter:%u", ft))
+ log_warn("WARNING: Failed to set lvmetad token. Out of memory?");
+}
+
+void lvmetad_set_socket(const char *sock)
+{
+ _lvmetad_socket = sock;
+}
+
+static daemon_reply _lvmetad_send(const char *id, ...);
+
+static int _token_update()
+{
+ daemon_reply repl = _lvmetad_send("token_update", NULL);
+
+ if (strcmp(daemon_reply_str(repl, "response", ""), "OK"))
{
+ daemon_reply_destroy(repl);
+ return 0;
+ }
+
+ daemon_reply_destroy(repl);
+ return 1;
+}
+
+
static daemon_reply _lvmetad_send(const char *id, ...)
{
va_list ap;
- va_start(ap, id);
- daemon_reply repl;
- daemon_request req = daemon_request_make(id);
+ daemon_reply repl, token_set;
+ daemon_request req;
+ int try = 0;
+ char *future_token;
- // daemon_request_extend(req, "token", _lvmetad_token, NULL);
+retry:
+ req = daemon_request_make(id);
+
+ if (_lvmetad_token)
+ daemon_request_extend(req, "token = %s", _lvmetad_token, NULL);
+
+ va_start(ap, id);
daemon_request_extend_v(req, ap);
+ va_end(ap);
repl = daemon_send(_lvmetad, req);
daemon_request_destroy(req);
- va_end(ap);
+ if (!strcmp(daemon_reply_str(repl, "response", ""),
"token_mismatch") && try < 2 && !test_mode()) {
+ future_token = _lvmetad_token;
+ _lvmetad_token = (char *) "update in progress";
+ if (!_token_update()) goto out;
+
+ if (pvscan_lvmetad_all_devs(_lvmetad_cmd, NULL)) {
+ _lvmetad_token = future_token;
+ if (!_token_update()) goto out;
+ }
+ _lvmetad_token = future_token;
+ ++ try;
+ daemon_reply_destroy(repl);
+ goto retry;
+ }
+
+out:
return repl;
}
@@ -203,7 +285,7 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const
char *vgna
struct pv_list *pvl;
struct lvmcache_info *info;
- if (!_using_lvmetad)
+ if (!lvmetad_active())
return NULL;
if (vgid) {
@@ -317,7 +399,7 @@ int lvmetad_vg_update(struct volume_group *vg)
if (!vg)
return 0;
- if (!_using_lvmetad || test_mode())
+ if (!lvmetad_active() || test_mode())
return 1; /* fake it */
if (!(vgmeta = _export_vg_to_config_tree(vg)))
@@ -369,7 +451,7 @@ int lvmetad_vg_remove(struct volume_group *vg)
daemon_reply reply;
int result;
- if (!_using_lvmetad || test_mode())
+ if (!lvmetad_active() || test_mode())
return 1; /* just fake it */
if (!id_write_format(&vg->id, uuid, sizeof(uuid)))
@@ -390,7 +472,7 @@ int lvmetad_pv_lookup(struct cmd_context *cmd, struct id pvid, int
*found)
int result = 0;
struct dm_config_node *cn;
- if (!_using_lvmetad)
+ if (!lvmetad_active())
return_0;
if (!id_write_format(&pvid, uuid, sizeof(uuid)))
@@ -423,7 +505,7 @@ int lvmetad_pv_lookup_by_dev(struct cmd_context *cmd, struct device
*dev, int *f
daemon_reply reply;
struct dm_config_node *cn;
- if (!_using_lvmetad)
+ if (!lvmetad_active())
return_0;
reply = _lvmetad_send("pv_lookup", "device = %d", dev->dev,
NULL);
@@ -450,7 +532,7 @@ int lvmetad_pv_list_to_lvmcache(struct cmd_context *cmd)
daemon_reply reply;
struct dm_config_node *cn;
- if (!_using_lvmetad)
+ if (!lvmetad_active())
return 1;
reply = _lvmetad_send("pv_list", NULL);
@@ -476,7 +558,7 @@ int lvmetad_vg_list_to_lvmcache(struct cmd_context *cmd)
daemon_reply reply;
struct dm_config_node *cn;
- if (!_using_lvmetad)
+ if (!lvmetad_active())
return 1;
reply = _lvmetad_send("vg_list", NULL);
@@ -576,7 +658,7 @@ int lvmetad_pv_found(struct id pvid, struct device *device, const
struct format_
const char *status;
int result;
- if (!_using_lvmetad || test_mode())
+ if (!lvmetad_active() || test_mode())
return 1;
if (!id_write_format(&pvid, uuid, sizeof(uuid)))
@@ -659,7 +741,7 @@ int lvmetad_pv_gone(dev_t device, const char *pv_name,
activation_handler handle
int result;
int found;
- if (!_using_lvmetad || test_mode())
+ if (!lvmetad_active() || test_mode())
return 1;
/*
@@ -669,7 +751,7 @@ int lvmetad_pv_gone(dev_t device, const char *pv_name,
activation_handler handle
* the whole stack from top to bottom (not yet upstream).
*/
- reply = daemon_send_simple(_lvmetad, "pv_gone", "device = %d",
device, NULL);
+ reply = _lvmetad_send("pv_gone", "device = %d", device, NULL);
result = _lvmetad_handle_reply(reply, "drop PV", pv_name, &found);
/* We don't care whether or not the daemon had the PV cached. */
@@ -684,16 +766,6 @@ int lvmetad_pv_gone_by_dev(struct device *dev, activation_handler
handler)
return lvmetad_pv_gone(dev->dev, dev_name(dev), handler);
}
-int lvmetad_active(void)
-{
- return _using_lvmetad;
-}
-
-void lvmetad_set_active(int active)
-{
- _using_lvmetad = active;
-}
-
/*
* The following code implements pvscan --cache.
*/
@@ -771,3 +843,30 @@ bad:
"It is strongly recommended that you restart lvmetad immediately.");
return 0;
}
+
+int pvscan_lvmetad_all_devs(struct cmd_context *cmd, activation_handler handler)
+{
+ struct dev_iter *iter;
+ struct device *dev;
+ int r = 1;
+
+ if (!(iter = dev_iter_create(cmd->lvmetad_filter, 1))) {
+ log_error("dev_iter creation failed");
+ return 0;
+ }
+
+ while ((dev = dev_iter_get(iter))) {
+ if (!pvscan_lvmetad_single(cmd, dev, handler)) {
+ r = 0;
+ break;
+ }
+
+ if (sigint_caught())
+ break;
+ }
+
+ dev_iter_destroy(iter);
+
+ return r;
+}
+
diff --git a/lib/cache/lvmetad.h b/lib/cache/lvmetad.h
index 7a6fe0b..cb85929 100644
--- a/lib/cache/lvmetad.h
+++ b/lib/cache/lvmetad.h
@@ -30,7 +30,7 @@ typedef int (*activation_handler) (struct volume_group *vg, int
partial,
* Initialise the communication with lvmetad. Normally called by
* lvmcache_init. Sets up a global handle for our process.
*/
-void lvmetad_init(void);
+void lvmetad_init(struct cmd_context *);
/*
* Override the use of lvmetad for retrieving scan results and metadata.
@@ -38,12 +38,29 @@ void lvmetad_init(void);
void lvmetad_set_active(int);
/*
+ * Configure the socket that lvmetad_init will use to connect to the daemon.
+ */
+void lvmetad_set_socket(const char *);
+
+/*
* Check whether lvmetad is active (where active means both that it is running
* and that we have a working connection with it).
*/
int lvmetad_active(void);
/*
+ * Drop connection to lvmetad. A subsequent lvmetad_init() will re-establish
+ * the connection (possibly at a different socket path).
+ */
+void lvmetad_disconnect(void);
+
+/*
+ * Set the "lvmetad validity token" (currently only consists of the lvmetad
+ * filter. See lvm.conf.
+ */
+void lvmetad_set_token(const struct dm_config_value *filter);
+
+/*
* Send a new version of VG metadata to lvmetad. This is normally called after
* vg_write but before vg_commit. After vg_commit, lvmetad_vg_commit is called
* to seal the transaction. The result of lvmetad_vg_update is that the new
@@ -111,11 +128,16 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd,
int pvscan_lvmetad_single(struct cmd_context *cmd, struct device *dev,
activation_handler handler);
+int pvscan_lvmetad_all_devs(struct cmd_context *cmd, activation_handler handler);
+
# else /* LVMETAD_SUPPORT */
-# define lvmetad_init() do { } while (0)
+# define lvmetad_init(cmd) do { } while (0)
+# define lvmetad_disconnect() do { } while (0)
# define lvmetad_set_active(a) do { } while (0)
+# define lvmetad_set_socket(a) do { } while (0)
# define lvmetad_active() (0)
+# define lvmetad_set_token(a) do { } while (0)
# define lvmetad_vg_update(vg) (1)
# define lvmetad_vg_remove(vg) (1)
# define lvmetad_pv_found(pvid, device, fmt, label_sector, vg, handler) (1)
@@ -127,6 +149,7 @@ int pvscan_lvmetad_single(struct cmd_context *cmd, struct device
*dev,
# define lvmetad_vg_list_to_lvmcache(cmd) (1)
# define lvmetad_vg_lookup(cmd, vgname, vgid) (NULL)
# define pvscan_lvmetad_single(cmd, dev, handler) (0)
+# define pvscan_lvmetad_all_devs(cmd, handler) (0)
# endif /* LVMETAD_SUPPORT */
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 9c2404f..c5e0ee3 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -399,7 +399,20 @@ static int _process_config(struct cmd_context *cmd)
(find_config_tree_int(cmd, "global/detect_internal_vg_cache_corruption",
DEFAULT_DETECT_INTERNAL_VG_CACHE_CORRUPTION));
+ lvmetad_disconnect();
+ const char *lvmetad_socket = getenv("LVM_LVMETAD_SOCKET");
+ if (!lvmetad_socket)
+ lvmetad_socket = DEFAULT_RUN_DIR "/lvmetad.socket";
+
+ /* TODO?
+ lvmetad_socket = find_config_tree_str(cmd, "lvmetad/socket_path",
+ DEFAULT_RUN_DIR "/lvmetad.socket");
+ */
+ lvmetad_set_socket(lvmetad_socket);
+ cn = find_config_tree_node(cmd, "devices/global_filter");
+ lvmetad_set_token(cn ? cn->v : NULL);
lvmetad_set_active(find_config_tree_int(cmd, "global/use_lvmetad", 0));
+ lvmetad_init(cmd);
return 1;
}
@@ -818,13 +831,14 @@ static int _init_filters(struct cmd_context *cmd, unsigned
load_persistent_cache
{
static char cache_file[PATH_MAX];
const char *dev_cache = NULL, *cache_dir, *cache_file_prefix;
- struct dev_filter *f3, *f4;
+ struct dev_filter *f3 = NULL, *f4 = NULL, *toplevel_components[2] = { 0 };
struct stat st;
+ const struct dm_config_node *cn;
cmd->dump_filter = 0;
if (!(f3 = _init_filter_components(cmd)))
- return_0;
+ goto_bad;
init_ignore_suspended_devices(find_config_tree_int(cmd,
"devices/ignore_suspended_devices", DEFAULT_IGNORE_SUSPENDED_DEVICES));
@@ -843,8 +857,7 @@ static int _init_filters(struct cmd_context *cmd, unsigned
load_persistent_cache
cache_dir ? : DEFAULT_CACHE_SUBDIR,
cache_file_prefix ? : DEFAULT_CACHE_FILE_PREFIX) < 0) {
log_error("Persistent cache filename too long.");
- f3->destroy(f3);
- return 0;
+ goto bad;
}
} else if (!(dev_cache = find_config_tree_str(cmd, "devices/cache", NULL))
&&
(dm_snprintf(cache_file, sizeof(cache_file),
@@ -852,8 +865,7 @@ static int _init_filters(struct cmd_context *cmd, unsigned
load_persistent_cache
cmd->system_dir, DEFAULT_CACHE_SUBDIR,
DEFAULT_CACHE_FILE_PREFIX) < 0)) {
log_error("Persistent cache filename too long.");
- f3->destroy(f3);
- return 0;
+ goto bad;
}
if (!dev_cache)
@@ -883,9 +895,26 @@ static int _init_filters(struct cmd_context *cmd, unsigned
load_persistent_cache
log_verbose("Failed to load existing device cache from %s",
dev_cache);
- cmd->filter = f4;
+ if (!(cn = find_config_tree_node(cmd, "devices/global_filter"))) {
+ cmd->filter = f4;
+ } else if (!(cmd->lvmetad_filter = regex_filter_create(cn->v)))
+ goto_bad;
+ else {
+ toplevel_components[0] = cmd->lvmetad_filter;
+ toplevel_components[1] = f4;
+ if (!(cmd->filter = composite_filter_create(2, toplevel_components)))
+ goto_bad;
+ }
return 1;
+bad:
+ if (f3)
+ f3->destroy(f3);
+ if (f4)
+ f4->destroy(f4);
+ if (toplevel_components[0])
+ toplevel_components[0]->destroy(toplevel_components[0]);
+ return 0;
}
struct format_type *get_format_by_name(struct cmd_context *cmd, const char *format)
@@ -1495,6 +1524,8 @@ int refresh_filters(struct cmd_context *cmd)
cmd->filter = NULL;
}
+ cmd->lvmetad_filter = NULL;
+
if (!(r = _init_filters(cmd, 0)))
stack;
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index e0ef041..6e5803f 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -91,6 +91,7 @@ struct cmd_context {
unsigned independent_metadata_areas:1; /* Active formats have MDAs outside PVs */
struct dev_filter *filter;
+ struct dev_filter *lvmetad_filter;
int dump_filter; /* Dump filter when exiting? */
struct dm_list config_files;
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index 1da9a77..79b3028 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -971,8 +971,8 @@ struct dev_iter *dev_iter_create(struct dev_filter *f, int dev_scan)
if (dev_scan && !trust_cache()) {
/* Flag gets reset between each command */
- if (!full_scan_done() && f)
- persistent_filter_wipe(f); /* Calls _full_scan(1) */
+ if (!full_scan_done() && f && f->wipe)
+ f->wipe(f); /* Calls _full_scan(1) */
} else
_full_scan(0);
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
index f3511cc..3267c9d 100644
--- a/lib/device/dev-cache.h
+++ b/lib/device/dev-cache.h
@@ -25,6 +25,7 @@
struct dev_filter {
int (*passes_filter) (struct dev_filter * f, struct device * dev);
void (*destroy) (struct dev_filter * f);
+ void (*wipe) (struct dev_filter * f);
void *private;
unsigned use_count;
};
diff --git a/lib/filters/filter-persistent.c b/lib/filters/filter-persistent.c
index 79e40b8..d00a99a 100644
--- a/lib/filters/filter-persistent.c
+++ b/lib/filters/filter-persistent.c
@@ -51,7 +51,7 @@ static int _init_hash(struct pfilter *pf)
return 1;
}
-int persistent_filter_wipe(struct dev_filter *f)
+static void _persistent_filter_wipe(struct dev_filter *f)
{
struct pfilter *pf = (struct pfilter *) f->private;
@@ -60,8 +60,6 @@ int persistent_filter_wipe(struct dev_filter *f)
/* Trigger complete device scan */
dev_cache_scan(1);
-
- return 1;
}
static int _read_array(struct pfilter *pf, struct dm_config_tree *cft,
@@ -368,6 +366,7 @@ struct dev_filter *persistent_filter_create(struct dev_filter *real,
f->destroy = _persistent_destroy;
f->use_count = 0;
f->private = pf;
+ f->wipe = _persistent_filter_wipe;
return f;
diff --git a/lib/filters/filter-persistent.h b/lib/filters/filter-persistent.h
index ad56a62..c2eee30 100644
--- a/lib/filters/filter-persistent.h
+++ b/lib/filters/filter-persistent.h
@@ -21,7 +21,6 @@
struct dev_filter *persistent_filter_create(struct dev_filter *f,
const char *file);
-int persistent_filter_wipe(struct dev_filter *f);
int persistent_filter_load(struct dev_filter *f, struct dm_config_tree **cft_out);
int persistent_filter_dump(struct dev_filter *f, int merge_existing);
diff --git a/libdaemon/client/daemon-shared.c b/libdaemon/client/daemon-shared.c
index 40c02b0..4b98f51 100644
--- a/libdaemon/client/daemon-shared.c
+++ b/libdaemon/client/daemon-shared.c
@@ -221,8 +221,10 @@ static void chain_node(struct dm_config_node *cn,
if (parent && !parent->child)
parent->child = cn;
- if (pre_sib)
+ if (pre_sib) {
+ cn->sib = pre_sib->sib;
pre_sib->sib = cn;
+ }
}
diff --git a/test/lib/aux.sh b/test/lib/aux.sh
index 0b46c79..d6a2008 100644
--- a/test/lib/aux.sh
+++ b/test/lib/aux.sh
@@ -527,5 +527,5 @@ target_at_least()
test -f DEVICES && devs=$(cat DEVICES)
-unset LVM_VALGRIND
+#unset LVM_VALGRIND
"$@"
diff --git a/tools/pvscan.c b/tools/pvscan.c
index 9287388..239ce97 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -106,32 +106,6 @@ static int _auto_activation_handler(struct volume_group *vg, int
partial,
return 1;
}
-static int _pvscan_lvmetad_all_devs(struct cmd_context *cmd, activation_handler handler)
-{
- struct dev_iter *iter;
- struct device *dev;
- int r = 1;
-
- if (!(iter = dev_iter_create(cmd->filter, 1))) {
- log_error("dev_iter creation failed");
- return 0;
- }
-
- while ((dev = dev_iter_get(iter))) {
- if (!pvscan_lvmetad_single(cmd, dev, handler)) {
- r = 0;
- break;
- }
-
- if (sigint_caught())
- break;
- }
-
- dev_iter_destroy(iter);
-
- return r;
-}
-
static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char **argv)
{
int ret = ECMD_PROCESSED;
@@ -168,7 +142,7 @@ static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char
**argv)
/* Scan everything? */
if (!argc && !devno_args) {
- if (!_pvscan_lvmetad_all_devs(cmd, handler))
+ if (!pvscan_lvmetad_all_devs(cmd, handler))
ret = ECMD_FAILED;
goto out;
}
@@ -283,7 +257,8 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
}
- persistent_filter_wipe(cmd->filter);
+ if (cmd->filter->wipe)
+ cmd->filter->wipe(cmd->filter);
lvmcache_destroy(cmd, 1);
/* populate lvmcache */
diff --git a/tools/vgrename.c b/tools/vgrename.c
index 451d085..b476602 100644
--- a/tools/vgrename.c
+++ b/tools/vgrename.c
@@ -181,7 +181,8 @@ static int vg_rename_path(struct cmd_context *cmd, const char
*old_vg_path,
vg_name_old, vg_name_new);
/* FIXME lvmcache corruption - vginfo duplicated instead of renamed */
- persistent_filter_wipe(cmd->filter);
+ if (cmd->filter->wipe)
+ cmd->filter->wipe(cmd->filter);
lvmcache_destroy(cmd, 1);
return 1;
diff --git a/tools/vgscan.c b/tools/vgscan.c
index a34f3ba..8deafb6 100644
--- a/tools/vgscan.c
+++ b/tools/vgscan.c
@@ -50,7 +50,8 @@ int vgscan(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
}
- persistent_filter_wipe(cmd->filter);
+ if (cmd->filter->wipe)
+ cmd->filter->wipe(cmd->filter);
lvmcache_destroy(cmd, 1);
_lvmetad = lvmetad_active();