master - vgremove: warn when removing sanlock global lock
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9aabf441bdb848...
Commit: 9aabf441bdb8480f2e99722955fedcb4a19d760d
Parent: 772b54a08bae19f59d93ca456691e3ce3cbb00da
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Jul 27 14:51:43 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jul 29 14:27:32 2015 -0500
vgremove: warn when removing sanlock global lock
When the sanlock VG holding the global lock is removed,
print a warning indicating that the global needs to be
enabled in another sanlock VG.
---
daemons/lvmlockd/lvmlockd-core.c | 58 +++++++++++++++++++++++++++++++---
daemons/lvmlockd/lvmlockd-internal.h | 2 +
lib/locking/lvmlockd.c | 12 +++++--
lib/locking/lvmlockd.h | 2 +-
4 files changed, 64 insertions(+), 10 deletions(-)
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
index 1361569..dc0d3e7 100644
--- a/daemons/lvmlockd/lvmlockd-core.c
+++ b/daemons/lvmlockd/lvmlockd-core.c
@@ -1966,6 +1966,30 @@ static void free_ls_resources(struct lockspace *ls)
}
/*
+ * ls is the vg being removed that holds the global lock.
+ * check if any other vgs will be left without a global lock.
+ */
+
+static int other_sanlock_vgs_exist(struct lockspace *ls_rem)
+{
+ struct lockspace *ls;
+
+ list_for_each_entry(ls, &lockspaces_inactive, list) {
+ log_debug("other sanlock vg exists inactive %s", ls->name);
+ return 1;
+ }
+
+ list_for_each_entry(ls, &lockspaces, list) {
+ if (!strcmp(ls->name, ls_rem->name))
+ continue;
+ log_debug("other sanlock vg exists %s", ls->name);
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
* Process actions queued for this lockspace by
* client_recv_action / add_lock_action.
*
@@ -1981,6 +2005,7 @@ static void *lockspace_thread_main(void *arg_in)
struct lockspace *ls = arg_in;
struct resource *r, *r2;
struct action *add_act, *act, *safe;
+ struct action *act_op_free = NULL;
struct list_head tmp_act;
struct list_head act_close;
int free_vg = 0;
@@ -2253,9 +2278,10 @@ out_act:
pthread_mutex_lock(&ls->mutex);
list_for_each_entry_safe(act, safe, &ls->actions, list) {
- if (act->op == LD_OP_FREE)
+ if (act->op == LD_OP_FREE) {
+ act_op_free = act;
act->result = 0;
- else if (act->op == LD_OP_STOP)
+ } else if (act->op == LD_OP_STOP)
act->result = 0;
else if (act->op == LD_OP_RENAME_BEFORE)
act->result = 0;
@@ -2266,6 +2292,19 @@ out_act:
}
pthread_mutex_unlock(&ls->mutex);
+ /*
+ * If this freed a sanlock vg that had gl enabled, and other sanlock
+ * vgs exist, return a flag so the command can warn that the gl has
+ * been removed and may need to be enabled in another sanlock vg.
+ */
+
+ if (free_vg && ls->sanlock_gl_enabled && act_op_free) {
+ pthread_mutex_lock(&lockspaces_mutex);
+ if (other_sanlock_vgs_exist(ls))
+ act_op_free->flags |= LD_AF_WARN_GL_REMOVED;
+ pthread_mutex_unlock(&lockspaces_mutex);
+ }
+
pthread_mutex_lock(&client_mutex);
list_for_each_entry_safe(act, safe, &tmp_act, list) {
list_del(&act->list);
@@ -2276,11 +2315,12 @@ out_act:
pthread_mutex_lock(&lockspaces_mutex);
ls->thread_done = 1;
+ ls->free_vg = free_vg;
pthread_mutex_unlock(&lockspaces_mutex);
/*
- * worker_thread will join this thread, and move the
- * ls struct from lockspaces list to lockspaces_inactive.
+ * worker_thread will join this thread, and free the
+ * ls or move it to lockspaces_inactive.
*/
pthread_mutex_lock(&worker_mutex);
worker_wake = 1;
@@ -2837,9 +2877,14 @@ static int for_each_lockspace(int do_stop, int do_free, int do_force)
pthread_join(ls->thread, NULL);
list_del(&ls->list);
+
/* In future we may need to free ls->actions here */
free_ls_resources(ls);
- list_add(&ls->list, &lockspaces_inactive);
+
+ if (ls->free_vg)
+ free(ls);
+ else
+ list_add(&ls->list, &lockspaces_inactive);
free_count++;
} else {
need_free++;
@@ -3363,6 +3408,9 @@ static void client_send_result(struct client *cl, struct action *act)
if (act->flags & LD_AF_ADD_LS_ERROR)
strcat(result_flags, "ADD_LS_ERROR,");
+
+ if (act->flags & LD_AF_WARN_GL_REMOVED)
+ strcat(result_flags, "WARN_GL_REMOVED,");
if (act->op == LD_OP_INIT) {
/*
diff --git a/daemons/lvmlockd/lvmlockd-internal.h b/daemons/lvmlockd/lvmlockd-internal.h
index 7bbddb4..1ecb5dc 100644
--- a/daemons/lvmlockd/lvmlockd-internal.h
+++ b/daemons/lvmlockd/lvmlockd-internal.h
@@ -101,6 +101,7 @@ struct client {
#define LD_AF_INACTIVE_LS 0x00004000
#define LD_AF_ADD_LS_ERROR 0x00008000
#define LD_AF_ADOPT 0x00010000
+#define LD_AF_WARN_GL_REMOVED 0x00020000
/*
* Number of times to repeat a lock request after
@@ -182,6 +183,7 @@ struct lockspace {
unsigned int thread_done : 1;
unsigned int sanlock_gl_enabled: 1;
unsigned int sanlock_gl_dup: 1;
+ unsigned int free_vg: 1;
struct list_head actions; /* new client actions */
struct list_head resources; /* resource/lock state for gl/vg/lv */
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index 84eb861..66c6615 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -115,9 +115,6 @@ static void _flags_str_to_lockd_flags(const char *flags_str, uint32_t *lockd_fla
if (strstr(flags_str, "NO_GL_LS"))
*lockd_flags |= LD_RF_NO_GL_LS;
- if (strstr(flags_str, "LOCAL_LS"))
- *lockd_flags |= LD_RF_LOCAL_LS;
-
if (strstr(flags_str, "DUP_GL_LS"))
*lockd_flags |= LD_RF_DUP_GL_LS;
@@ -126,6 +123,9 @@ static void _flags_str_to_lockd_flags(const char *flags_str, uint32_t *lockd_fla
if (strstr(flags_str, "ADD_LS_ERROR"))
*lockd_flags |= LD_RF_ADD_LS_ERROR;
+
+ if (strstr(flags_str, "WARN_GL_REMOVED"))
+ *lockd_flags |= LD_RF_WARN_GL_REMOVED;
}
/*
@@ -722,6 +722,7 @@ static int _free_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
static int _free_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg)
{
daemon_reply reply;
+ uint32_t lockd_flags = 0;
int result;
int ret;
@@ -743,7 +744,7 @@ static int _free_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg)
"vg_lock_args = %s", vg->lock_args,
NULL);
- if (!_lockd_result(reply, &result, NULL)) {
+ if (!_lockd_result(reply, &result, &lockd_flags)) {
ret = 0;
} else {
ret = (result < 0) ? 0 : 1;
@@ -764,6 +765,9 @@ static int _free_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg)
goto out;
}
+ if (lockd_flags & LD_RF_WARN_GL_REMOVED)
+ log_warn("VG %s held the sanlock global lock, enable global lock in another VG.", vg->name);
+
/*
* The usleep delay gives sanlock time to close the lock lv,
* and usually avoids having an annoying error printed.
diff --git a/lib/locking/lvmlockd.h b/lib/locking/lvmlockd.h
index ffd6a99..f141635 100644
--- a/lib/locking/lvmlockd.h
+++ b/lib/locking/lvmlockd.h
@@ -27,7 +27,7 @@
/* lvmlockd result flags */
#define LD_RF_NO_LOCKSPACES 0x00000001
#define LD_RF_NO_GL_LS 0x00000002
-#define LD_RF_LOCAL_LS 0x00000004
+#define LD_RF_WARN_GL_REMOVED 0x00000004
#define LD_RF_DUP_GL_LS 0x00000008
#define LD_RF_INACTIVE_LS 0x00000010
#define LD_RF_ADD_LS_ERROR 0x00000020
8 years, 9 months
master - vgcreate: improve checks for existing global lock
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=772b54a08bae19...
Commit: 772b54a08bae19f59d93ca456691e3ce3cbb00da
Parent: e593213b875e96a3de77594f7ce8dd1809a930a0
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Jul 24 10:06:58 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jul 29 14:27:32 2015 -0500
vgcreate: improve checks for existing global lock
This tries harder to avoid creating duplicate global locks in
sanlock VGs by refusing to create a new sanlock VG with a
global lock if other sanlock VGs exist that may have a gl.
---
daemons/lvmlockd/lvmlockd-core.c | 6 -----
lib/cache/lvmcache.c | 13 +++++++++++
lib/cache/lvmcache.h | 2 +
lib/locking/lvmlockd.c | 45 +++++++++++++++++++++++++++++--------
4 files changed, 50 insertions(+), 16 deletions(-)
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
index 7375d9e..1361569 100644
--- a/daemons/lvmlockd/lvmlockd-core.c
+++ b/daemons/lvmlockd/lvmlockd-core.c
@@ -3341,12 +3341,6 @@ static void client_send_result(struct client *cl, struct action *act)
* or if lockspaces exist, but not one with the global lock.
* Given this detail, it may be able to procede without
* the lock.
- *
- * FIXME: it would also help the caller to know if there
- * are other sanlock VGs that have not been started.
- * If there are, then one of them might have a global
- * lock enabled. In that case, vgcreate may not want
- * to create a new sanlock vg with gl enabled.
*/
pthread_mutex_lock(&lockspaces_mutex);
if (list_empty(&lockspaces))
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 36926f2..cfa1d5f 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -2345,3 +2345,16 @@ int lvmcache_lookup_mda(struct lvmcache_vgsummary *vgsummary)
return 0;
}
+
+int lvmcache_contains_lock_type_sanlock(struct cmd_context *cmd)
+{
+ struct lvmcache_vginfo *vginfo;
+
+ dm_list_iterate_items(vginfo, &_vginfos) {
+ if (vginfo->lock_type && !strcmp(vginfo->lock_type, "sanlock"))
+ return 1;
+ }
+
+ return 0;
+}
+
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 008b194..76b9b10 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -188,4 +188,6 @@ int lvmcache_found_duplicate_pvs(void);
void lvmcache_set_preferred_duplicates(const char *vgid);
+int lvmcache_contains_lock_type_sanlock(struct cmd_context *cmd);
+
#endif
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index e9d7882..84eb861 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -1177,23 +1177,48 @@ int lockd_gl_create(struct cmd_context *cmd, const char *def_mode, const char *v
* skip acquiring the global lock when creating this initial
* VG, and enable the global lock in this VG.
*
- * Here we assume that this is an initial bootstrap condition
- * based on the fact that lvmlockd has seen no lockd VGs.
- * (A commmand line option could be added to allow the user
- * to make this initial bootstrap condition explicit.)
+ * This initial bootstrap condition is identified based on
+ * two things:
*
- * That assumption might be wrong. It is possible that a global
- * lock does exist in a VG that has not yet been seen. If that
- * VG appears after this creates a new VG with a new enabled
- * global lock, then there will be two VGs containing enabled
- * global locks, and one will need to be disabled by the user.
+ * 1. No sanlock VGs have been started in lvmlockd, causing
+ * lvmlockd to return NO_GL_LS/NO_LOCKSPACES.
+ *
+ * 2. No sanlock VGs are seen in lvmcache after the disk
+ * scan performed in lvmetad_validate_global_cache().
+ *
+ * If both of those are true, we go ahead and create this new
+ * VG which will have the global lock enabled. However, this
+ * has a shortcoming: another sanlock VG may exist that hasn't
+ * appeared to the system yet. If that VG has its global lock
+ * enabled, then when it appears later, duplicate global locks
+ * will be seen, and a warning will indicate that one of them
+ * should be disabled.
+ *
+ * The two bootstrap conditions have another shortcoming to the
+ * opposite effect: other sanlock VGs may be visible to the
+ * system, but none of them have a global lock enabled.
+ * In that case, it would make sense to create this new VG with
+ * an enabled global lock. (FIXME: we could detect that none
+ * of the existing sanlock VGs have a gl enabled and allow this
+ * vgcreate to go ahead.) Enabling the global lock in one of
+ * the existing sanlock VGs is currently the simplest solution.
*/
if ((lockd_flags & LD_RF_NO_GL_LS) &&
(lockd_flags & LD_RF_NO_LOCKSPACES) &&
!strcmp(vg_lock_type, "sanlock")) {
- log_print_unless_silent("Enabling sanlock global lock");
lvmetad_validate_global_cache(cmd, 1);
+ /*
+ * lvmcache holds provisional VG lock_type info because
+ * lvmetad_validate_global_cache did a disk scan.
+ */
+ if (lvmcache_contains_lock_type_sanlock(cmd)) {
+ /* FIXME: we could check that all are started, and then check that none have gl enabled. */
+ log_error("Global lock failed: start existing sanlock VGs to access global lock.");
+ log_error("(If all sanlock VGs are started, enable global lock with lvmlockctl.)");
+ return 0;
+ }
+ log_print_unless_silent("Enabling sanlock global lock");
return 1;
}
8 years, 9 months
master - lvmcache: add lock_type to VG summary and info structs
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e593213b875e96...
Commit: e593213b875e96a3de77594f7ce8dd1809a930a0
Parent: 3cd644aeb5cac432a92ad50584973a3430168ed6
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Jul 24 15:20:37 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jul 29 14:27:32 2015 -0500
lvmcache: add lock_type to VG summary and info structs
vgsummary information contains provisional VG information
that is obtained without holding the VG lock. This info
can be used to lock the VG, and then read it with vg_read().
After the VG is read properly, the vgsummary info should
be verified.
Add the VG lock_type to the vgsummary. It needs to be
known before the VG can be locked and read.
---
lib/cache/lvmcache.c | 30 +++++++++++++++++++++++++-----
lib/cache/lvmcache.h | 12 ++++++++++++
lib/format_text/import_vsn1.c | 7 +++++++
3 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 9f5b83a..36926f2 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -56,6 +56,7 @@ struct lvmcache_vginfo {
char _padding[7];
struct lvmcache_vginfo *next; /* Another VG with same name? */
char *creation_host;
+ char *lock_type;
uint32_t mda_checksum;
size_t mda_size;
size_t vgmetadata_size;
@@ -1447,7 +1448,7 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
}
static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstatus,
- const char *creation_host)
+ const char *creation_host, const char *lock_type)
{
if (!info || !info->vginfo)
return 1;
@@ -1460,11 +1461,11 @@ static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstat
info->vginfo->status = vgstatus;
if (!creation_host)
- return 1;
+ goto set_lock_type;
if (info->vginfo->creation_host && !strcmp(creation_host,
info->vginfo->creation_host))
- return 1;
+ goto set_lock_type;
if (info->vginfo->creation_host)
dm_free(info->vginfo->creation_host);
@@ -1478,6 +1479,24 @@ static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstat
log_debug_cache("lvmcache: %s: VG %s: Set creation host to %s.",
dev_name(info->dev), info->vginfo->vgname, creation_host);
+set_lock_type:
+
+ if (!lock_type)
+ goto out;
+
+ if (info->vginfo->lock_type && !strcmp(lock_type, info->vginfo->lock_type))
+ goto out;
+
+ if (info->vginfo->lock_type)
+ dm_free(info->vginfo->lock_type);
+
+ if (!(info->vginfo->lock_type = dm_strdup(lock_type))) {
+ log_error("cache creation host alloc failed for %s",
+ lock_type);
+ return 0;
+ }
+
+out:
return 1;
}
@@ -1546,7 +1565,7 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info, struct lvmcache_vg
if (!_lvmcache_update_vgname(info, vgname, vgid, vgsummary->vgstatus,
vgsummary->creation_host, info->fmt) ||
!_lvmcache_update_vgid(info, info->vginfo, vgid) ||
- !_lvmcache_update_vgstatus(info, vgsummary->vgstatus, vgsummary->creation_host) ||
+ !_lvmcache_update_vgstatus(info, vgsummary->vgstatus, vgsummary->creation_host, vgsummary->lock_type) ||
!_lvmcache_update_vg_mda_info(info, vgsummary->mda_checksum, vgsummary->mda_size))
return_0;
@@ -1561,7 +1580,8 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
struct lvmcache_vgsummary vgsummary = {
.vgname = vg->name,
.vgstatus = vg->status,
- .vgid = vg->id
+ .vgid = vg->id,
+ .lock_type = vg->lock_type
};
pvid_s[sizeof(pvid_s) - 1] = '\0';
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 780325a..008b194 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -39,11 +39,23 @@ struct disk_locn;
struct lvmcache_vginfo;
+/*
+ * vgsummary represents a summary of the VG that is read
+ * without a lock. The info does not come through vg_read(),
+ * but through reading mdas. It provides information about
+ * the VG that is needed to lock the VG and then read it fully
+ * with vg_read(), after which the VG summary should be checked
+ * against the full VG metadata to verify it was correct (since
+ * it was read without a lock.)
+ *
+ * Once read, vgsummary information is saved in lvmcache_vginfo.
+ */
struct lvmcache_vgsummary {
const char *vgname;
struct id vgid;
uint64_t vgstatus;
char *creation_host;
+ const char *lock_type;
uint32_t mda_checksum;
size_t mda_size;
};
diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c
index a4dcdf1..7888695 100644
--- a/lib/format_text/import_vsn1.c
+++ b/lib/format_text/import_vsn1.c
@@ -1031,6 +1031,11 @@ static void _read_desc(struct dm_pool *mem,
*when = u;
}
+/*
+ * It would be more accurate to call this _read_vgsummary().
+ * It is used to read vgsummary information about a VG
+ * before locking and reading the VG via vg_read().
+ */
static int _read_vgname(const struct format_type *fmt, const struct dm_config_tree *cft,
struct lvmcache_vgsummary *vgsummary)
{
@@ -1067,6 +1072,8 @@ static int _read_vgname(const struct format_type *fmt, const struct dm_config_tr
return 0;
}
+ dm_config_get_str(vgn, "lock_type", &vgsummary->lock_type);
+
return 1;
}
8 years, 9 months
master - libdm: Require librt for new dm_timestamp.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=3cd644aeb5cac4...
Commit: 3cd644aeb5cac432a92ad50584973a3430168ed6
Parent: a28fb37b9e0e5b3a754e897887a8fdb22fd2d98d
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Wed Jul 29 19:30:22 2015 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Wed Jul 29 19:30:22 2015 +0100
libdm: Require librt for new dm_timestamp.
---
configure | 3 +++
configure.in | 2 ++
libdm/libdevmapper.pc.in | 2 +-
3 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/configure b/configure
index 97fe8f2..07059b8 100755
--- a/configure
+++ b/configure
@@ -659,6 +659,7 @@ SELINUX_PC
SELINUX_LIBS
REPLICATORS
READLINE_LIBS
+RT_PC
RAID
PYTHON_LIBDIRS
PYTHON_INCDIRS
@@ -12794,6 +12795,7 @@ fi
$as_echo "#define HAVE_REALTIME 1" >>confdefs.h
LIBS="-lrt $LIBS"
+ RT_PC="librt"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Disabling realtime clock" >&5
$as_echo "$as_me: WARNING: Disabling realtime clock" >&2;}
@@ -14143,6 +14145,7 @@ LVM_LIBAPI=`echo "$VER" | $AWK -F '[()]' '{print $2}'`
+
################################################################################
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmetad/Makefile daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile lib/misc/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile lib/cache_segtype/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdev
mapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_lvmlockd_systemd_red_hat.service scripts/lvm2_lvmlocking_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan
_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
diff --git a/configure.in b/configure.in
index e273e1d..1825fb7 100644
--- a/configure.in
+++ b/configure.in
@@ -1570,6 +1570,7 @@ if test "$REALTIME" = yes; then
if test "$HAVE_REALTIME" = yes; then
AC_DEFINE([HAVE_REALTIME], 1, [Define to 1 to include support for realtime clock.])
LIBS="-lrt $LIBS"
+ RT_PC="librt"
else
AC_MSG_WARN(Disabling realtime clock)
fi
@@ -1984,6 +1985,7 @@ AC_SUBST(PYTHON_LIBDIRS)
AC_SUBST(QUORUM_CFLAGS)
AC_SUBST(QUORUM_LIBS)
AC_SUBST(RAID)
+AC_SUBST(RT_PC)
AC_SUBST(READLINE_LIBS)
AC_SUBST(REPLICATORS)
AC_SUBST(SACKPT_CFLAGS)
diff --git a/libdm/libdevmapper.pc.in b/libdm/libdevmapper.pc.in
index eb7071d..63c0720 100644
--- a/libdm/libdevmapper.pc.in
+++ b/libdm/libdevmapper.pc.in
@@ -8,4 +8,4 @@ Description: device-mapper library
Version: @DM_LIB_PATCHLEVEL@
Cflags: -I${includedir}
Libs: -L${libdir} -ldevmapper
-Requires.private: @SELINUX_PC@ @UDEV_PC@
+Requires.private: @SELINUX_PC@ @UDEV_PC@ @RT_PC@
8 years, 9 months
master - libdm: Add dm_timestamp functions.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a28fb37b9e0e5b...
Commit: a28fb37b9e0e5b3a754e897887a8fdb22fd2d98d
Parent: a5491d36982c7afe10f655ad0592fb20f9a331fd
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Wed Jul 29 19:21:07 2015 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Wed Jul 29 19:21:07 2015 +0100
libdm: Add dm_timestamp functions.
---
WHATS_NEW_DM | 1 +
lib/Makefile.in | 5 -
lib/misc/timestamp.c | 129 --------------------------
lib/misc/timestamp.h | 33 -------
libdm/.exported_symbols.DM_1_02_104 | 5 +
libdm/Makefile.in | 1 +
libdm/libdevmapper.h | 42 +++++++++-
libdm/libdm-timestamp.c | 170 +++++++++++++++++++++++++++++++++++
8 files changed, 218 insertions(+), 168 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index dcc2a24..81acfe9 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.104 -
=================================
+ Add dm_timestamp functions to libdevmapper.
Version 1.02.103 - 24th July 2015
=================================
diff --git a/lib/Makefile.in b/lib/Makefile.in
index dbd4e3f..e29ff29 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -122,11 +122,6 @@ SOURCES =\
uuid/uuid.c \
zero/zero.c
-ifeq ("@HAVE_REALTIME@", "yes")
- SOURCES +=\
- misc/timestamp.c
-endif
-
ifeq ("@LVM1@", "internal")
SOURCES +=\
format1/disk-rep.c \
diff --git a/lib/misc/timestamp.c b/lib/misc/timestamp.c
deleted file mode 100644
index 47b5586..0000000
--- a/lib/misc/timestamp.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2006 Rackable Systems All rights reserved.
- *
- * This file is part of LVM2.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License v.2.1.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Abstract out the time methods used so they can be adjusted later -
- * the results of these routines should stay in-core. This implementation
- * requires librt.
- */
-
-#include "lib.h"
-#include <stdlib.h>
-
-#include "timestamp.h"
-
-/*
- * The realtime section uses clock_gettime with the CLOCK_MONOTONIC
- * parameter to prevent issues with time warps
- */
-#ifdef HAVE_REALTIME
-
-#include <time.h>
-#include <bits/time.h>
-
-struct timestamp {
- struct timespec t;
-};
-
-struct timestamp *get_timestamp(void)
-{
- struct timestamp *ts = NULL;
-
- if (!(ts = dm_malloc(sizeof(*ts))))
- return_NULL;
-
- if (clock_gettime(CLOCK_MONOTONIC, &ts->t)) {
- log_sys_error("clock_gettime", "get_timestamp");
- return NULL;
- }
-
- return ts;
-}
-
-/* cmp_timestamp: Compare two timestamps
- *
- * Return: -1 if t1 is less than t2
- * 0 if t1 is equal to t2
- * 1 if t1 is greater than t2
- */
-int cmp_timestamp(struct timestamp *t1, struct timestamp *t2)
-{
- if(t1->t.tv_sec < t2->t.tv_sec)
- return -1;
- if(t1->t.tv_sec > t2->t.tv_sec)
- return 1;
-
- if(t1->t.tv_nsec < t2->t.tv_nsec)
- return -1;
- if(t1->t.tv_nsec > t2->t.tv_nsec)
- return 1;
-
- return 0;
-}
-
-#else /* ! HAVE_REALTIME */
-
-/*
- * The !realtime section just uses gettimeofday and is therefore subject
- * to ntp-type time warps - not sure if should allow that.
- */
-
-#include <sys/time.h>
-
-struct timestamp {
- struct timeval t;
-};
-
-struct timestamp *get_timestamp(void)
-{
- struct timestamp *ts = NULL;
-
- if (!(ts = dm_malloc(sizeof(*ts))))
- return_NULL;
-
- if (gettimeofday(&ts->t, NULL)) {
- log_sys_error("gettimeofday", "get_timestamp");
- return NULL;
- }
-
- return ts;
-}
-
-/* cmp_timestamp: Compare two timestamps
- *
- * Return: -1 if t1 is less than t2
- * 0 if t1 is equal to t2
- * 1 if t1 is greater than t2
- */
-int cmp_timestamp(struct timestamp *t1, struct timestamp *t2)
-{
- if(t1->t.tv_sec < t2->t.tv_sec)
- return -1;
- if(t1->t.tv_sec > t2->t.tv_sec)
- return 1;
-
- if(t1->t.tv_usec < t2->t.tv_usec)
- return -1;
- if(t1->t.tv_usec > t2->t.tv_usec)
- return 1;
-
- return 0;
-}
-
-#endif /* HAVE_REALTIME */
-
-void destroy_timestamp(struct timestamp *t)
-{
- dm_free(t);
-}
diff --git a/lib/misc/timestamp.h b/lib/misc/timestamp.h
deleted file mode 100644
index 50e2a85..0000000
--- a/lib/misc/timestamp.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2006 Rackable Systems All rights reserved.
- *
- * This file is part of LVM2.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License v.2.1.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _LVM_TIMESTAMP_H
-#define _LVM_TIMESTAMP_H
-
-struct timestamp;
-
-struct timestamp *get_timestamp(void);
-
-/* cmp_timestamp: Compare two timestamps
- *
- * Return: -1 if t1 is less than t2
- * 0 if t1 is equal to t2
- * 1 if t1 is greater than t2
- */
-int cmp_timestamp(struct timestamp *t1, struct timestamp *t2);
-
-void destroy_timestamp(struct timestamp *t);
-
-#endif /* _LVM_TIMESTAMP_H */
-
diff --git a/libdm/.exported_symbols.DM_1_02_104 b/libdm/.exported_symbols.DM_1_02_104
index 7bd144d..9fafa48 100644
--- a/libdm/.exported_symbols.DM_1_02_104
+++ b/libdm/.exported_symbols.DM_1_02_104
@@ -1 +1,6 @@
dm_size_to_string
+dm_timestamp_alloc
+dm_timestamp_compare
+dm_timestamp_get
+dm_timestamp_delta
+dm_timestamp_destroy
diff --git a/libdm/Makefile.in b/libdm/Makefile.in
index ba65c6a..73f6f40 100644
--- a/libdm/Makefile.in
+++ b/libdm/Makefile.in
@@ -25,6 +25,7 @@ SOURCES =\
libdm-deptree.c \
libdm-string.c \
libdm-report.c \
+ libdm-timestamp.c \
libdm-config.c \
mm/dbg_malloc.c \
mm/pool.c \
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index 3a900be..001d4c0 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2006 Rackable Systems All rights reserved.
*
* This file is part of the device-mapper userspace tools.
*
@@ -1664,6 +1665,45 @@ typedef int32_t dm_percent_t;
float dm_percent_to_float(dm_percent_t percent);
dm_percent_t dm_make_percent(uint64_t numerator, uint64_t denominator);
+/********************
+ * timestamp handling
+ ********************/
+
+struct dm_timestamp;
+
+/*
+ * Create a dm_timestamp object to use with dm_timestamp_get.
+ */
+struct dm_timestamp *dm_timestamp_alloc(void);
+
+/*
+ * Update dm_timestamp object to represent the current time.
+ */
+int dm_timestamp_get(struct dm_timestamp *ts);
+
+/*
+ * Compare two timestamps.
+ *
+ * Return: -1 if ts1 is less than ts2
+ * 0 if ts1 is equal to ts2
+ * 1 if ts1 is greater than ts2
+ */
+int dm_timestamp_compare(struct dm_timestamp *ts1, struct dm_timestamp *ts2);
+
+/*
+ * Return the absolute difference in nanoseconds between
+ * the dm_timestamp objects ts1 and ts2.
+ *
+ * Callers that need to know whether ts1 is before, equal to, or after ts2
+ * in addition to the magnitude should use dm_timestamp_compare.
+ */
+uint64_t dm_timestamp_delta(struct dm_timestamp *ts1, struct dm_timestamp *ts2);
+
+/*
+ * Destroy a dm_timestamp object.
+ */
+void dm_timestamp_destroy(struct dm_timestamp *ts);
+
/*********************
* reporting functions
*********************/
diff --git a/libdm/libdm-timestamp.c b/libdm/libdm-timestamp.c
new file mode 100644
index 0000000..d2bd7bf
--- /dev/null
+++ b/libdm/libdm-timestamp.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2006 Rackable Systems All rights reserved.
+ * Copyright (C) 2015 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of the device-mapper userspace tools.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Abstract out the time methods used so they can be adjusted later -
+ * the results of these routines should stay in-core.
+ */
+
+#include "dmlib.h"
+
+#include <stdlib.h>
+
+#define NSEC_PER_USEC UINT64_C(1000)
+#define NSEC_PER_MSEC UINT64_C(1000000)
+#define NSEC_PER_SEC UINT64_C(1000000000)
+
+/*
+ * The realtime section uses clock_gettime with the CLOCK_MONOTONIC
+ * parameter to prevent issues with time warps
+ * This implementation requires librt.
+ */
+#ifdef HAVE_REALTIME
+
+#include <time.h>
+#include <bits/time.h>
+
+struct dm_timestamp {
+ struct timespec t;
+};
+
+static uint64_t _timestamp_to_uint64(struct dm_timestamp *ts)
+{
+ uint64_t stamp = 0;
+
+ stamp += (uint64_t) ts->t.tv_sec * NSEC_PER_SEC;
+ stamp += (uint64_t) ts->t.tv_nsec;
+
+ return stamp;
+}
+
+struct dm_timestamp *dm_timestamp_alloc(void)
+{
+ struct dm_timestamp *ts = NULL;
+
+ if (!(ts = dm_malloc(sizeof(*ts))))
+ stack;
+
+ return ts;
+}
+
+int dm_timestamp_get(struct dm_timestamp *ts)
+{
+ if (!ts)
+ return 0;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &ts->t)) {
+ log_sys_error("clock_gettime", "get_timestamp");
+ return 0;
+ }
+
+ return 1;
+}
+
+#else /* ! HAVE_REALTIME */
+
+/*
+ * The !realtime section just uses gettimeofday and is therefore subject
+ * to ntp-type time warps - not sure if should allow that.
+ */
+
+#include <sys/time.h>
+
+struct dm_timestamp {
+ struct timeval t;
+};
+
+static uint64_t _timestamp_to_uint64(struct dm_timestamp *ts)
+{
+ uint64_t stamp = 0;
+
+ stamp += ts->t.tv_sec * NSEC_PER_SEC;
+ stamp += ts->t.tv_usec * NSEC_PER_USEC;
+
+ return stamp;
+}
+
+struct dm_timestamp *dm_timestamp_alloc(void)
+{
+ struct dm_timestamp *ts;
+
+ if (!(ts = dm_malloc(sizeof(*ts))))
+ stack;
+
+ return ts;
+}
+
+int dm_timestamp_get(struct dm_timestamp *ts)
+{
+ if (!ts)
+ return 0;
+
+ if (gettimeofday(&ts->t, NULL)) {
+ log_sys_error("gettimeofday", "get_timestamp");
+ return 0;
+ }
+
+ return 1;
+}
+
+#endif /* HAVE_REALTIME */
+
+/*
+ * Compare two timestamps.
+ *
+ * Return: -1 if ts1 is less than ts2
+ * 0 if ts1 is equal to ts2
+ * 1 if ts1 is greater than ts2
+ */
+int dm_timestamp_compare(struct dm_timestamp *ts1, struct dm_timestamp *ts2)
+{
+ uint64_t t1, t2;
+
+ t1 = _timestamp_to_uint64(ts1);
+ t2 = _timestamp_to_uint64(ts2);
+
+ if (t2 < t1)
+ return 1;
+
+ if (t1 < t2)
+ return -1;
+
+ return 0;
+}
+
+/*
+ * Return the absolute difference in nanoseconds between
+ * the dm_timestamp objects ts1 and ts2.
+ *
+ * Callers that need to know whether ts1 is before, equal to, or after ts2
+ * in addition to the magnitude should use dm_timestamp_compare.
+ */
+uint64_t dm_timestamp_delta(struct dm_timestamp *ts1, struct dm_timestamp *ts2)
+{
+ uint64_t t1, t2;
+
+ t1 = _timestamp_to_uint64(ts1);
+ t2 = _timestamp_to_uint64(ts2);
+
+ if (t1 > t2)
+ return t1 - t2;
+
+ return t2 - t1;
+}
+
+void dm_timestamp_destroy(struct dm_timestamp *ts)
+{
+ dm_free(ts);
+}
8 years, 9 months
master - dmsetup: Accept vg/lv name format.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a5491d36982c7a...
Commit: a5491d36982c7afe10f655ad0592fb20f9a331fd
Parent: ca0d9a70d15ca44c1d0d6f65a277c5e2ac7dd161
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Wed Jul 29 12:24:36 2015 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Wed Jul 29 12:24:36 2015 +0100
dmsetup: Accept vg/lv name format.
If there is exactly one / which is not the first character, check
for /dev/vg/lv (as dm_dir()/../$name i.e. /dev/mapper/../vg/lv.)
---
WHATS_NEW | 1 +
libdm/libdm-common.c | 60 ++++++++++++++++++++++++++++++++++---------------
2 files changed, 42 insertions(+), 19 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 436d1d9..1d8f472 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.127 -
=================================
+ Recognise vg/lv name format in dmsetup.
Fix regression in cache causing some PVs to bypass filters (2.02.105).
Version 2.02.126 - 24th July 2015
diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c
index b56643f..0811db0 100644
--- a/libdm/libdm-common.c
+++ b/libdm/libdm-common.c
@@ -546,35 +546,57 @@ static int _dm_task_set_name_from_path(struct dm_task *dmt, const char *path,
{
char buf[PATH_MAX];
struct stat st1, st2;
- const char *final_name;
+ const char *final_name = NULL;
+ size_t len;
if (dmt->type == DM_DEVICE_CREATE) {
log_error("Name \"%s\" invalid. It contains \"/\".", path);
return 0;
}
- if (stat(path, &st1)) {
- log_error("Device %s not found", path);
- return 0;
+ if (!stat(path, &st1)) {
+ /*
+ * Found directly.
+ * If supplied path points to same device as last component
+ * under /dev/mapper, use that name directly.
+ */
+ if (dm_snprintf(buf, sizeof(buf), "%s/%s", _dm_dir, name) == -1) {
+ log_error("Couldn't create path for %s", name);
+ return 0;
+ }
+
+ if (!stat(buf, &st2) && (st1.st_rdev == st2.st_rdev))
+ final_name = name;
+ } else {
+ /* Not found. */
+ /* If there is exactly one '/' try a prefix of /dev */
+ if ((len = strlen(path)) < 3 || path[0] == '/' ||
+ dm_count_chars(path, len, '/') != 1) {
+ log_error("Device %s not found", path);
+ return 0;
+ }
+ if (dm_snprintf(buf, sizeof(buf), "%s/../%s", _dm_dir, path) == -1) {
+ log_error("Couldn't create /dev path for %s", path);
+ return 0;
+ }
+ if (stat(buf, &st1)) {
+ log_error("Device %s not found", path);
+ return 0;
+ }
+ /* Found */
}
/*
- * If supplied path points to same device as last component
- * under /dev/mapper, use that name directly. Otherwise call
- * _find_dm_name_of_device() to scan _dm_dir for a match.
+ * If we don't have the dm name yet, Call _find_dm_name_of_device() to
+ * scan _dm_dir for a match.
*/
- if (dm_snprintf(buf, sizeof(buf), "%s/%s", _dm_dir, name) == -1) {
- log_error("Couldn't create path for %s", name);
- return 0;
- }
-
- if (!stat(buf, &st2) && (st1.st_rdev == st2.st_rdev))
- final_name = name;
- else if (_find_dm_name_of_device(st1.st_rdev, buf, sizeof(buf)))
- final_name = buf;
- else {
- log_error("Device %s not found", name);
- return 0;
+ if (!final_name) {
+ if (_find_dm_name_of_device(st1.st_rdev, buf, sizeof(buf)))
+ final_name = buf;
+ else {
+ log_error("Device %s not found", name);
+ return 0;
+ }
}
/* This is an already existing path - do not mangle! */
8 years, 9 months
master - dmsetup: remove dead code that covered "info -c -o help" case once
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ca0d9a70d15ca4...
Commit: ca0d9a70d15ca44c1d0d6f65a277c5e2ac7dd161
Parent: cf700151eba483aeedbf790fd66ce1c44e19c707
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Jul 29 13:10:31 2015 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Wed Jul 29 13:16:09 2015 +0200
dmsetup: remove dead code that covered "info -c -o help" case once
The "-o help" is now handled as implicit field and it gets processed
just like any other field - all handled by libdevmapper now.
---
tools/dmsetup.c | 11 ++---------
1 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/tools/dmsetup.c b/tools/dmsetup.c
index e6cc44f..7a26db1 100644
--- a/tools/dmsetup.c
+++ b/tools/dmsetup.c
@@ -3857,15 +3857,8 @@ unknown:
goto out;
}
- if (_switches[COLS_ARG]) {
- if (!_report_init(cmd))
- goto out;
- if (!_report) {
- if (!strcmp(cmd->name, "info"))
- r = 0; /* info -c -o help */
- goto out;
- }
- }
+ if (_switches[COLS_ARG] && !_report_init(cmd))
+ goto out;
#ifdef UDEV_SYNC_SUPPORT
if (!_set_up_udev_support(dev_dir))
8 years, 9 months
master - cache: fix regression causing some PVs to bypass filters
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=cf700151eba483...
Commit: cf700151eba483aeedbf790fd66ce1c44e19c707
Parent: af1c7bf0c71f9cc132e9cf211eb1512078af0081
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Jul 29 09:43:03 2015 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Wed Jul 29 10:19:12 2015 +0200
cache: fix regression causing some PVs to bypass filters
This is a regression introduced by commit
6c0e44d5a2e82aa160d48e83992e7ca342bc4bdf which changed
the way dev_cache_get fn works - before this patch, when a
device was not found, it fired a full rescan to correct the
cache. However, the change coming with that commit missed
this full_rescan call, causing the lvmcache to still contain
info about PVs which should be filtered now.
Such situation may have happened by coincidence of using
old persistent cache (/etc/lvm/cache/.cache) which does not
reflect the actual state anymore, a device name/symlink which
now points to a device which should be filtered and a fact we
keep info about usable DM devices in .cache no matter what
the filter setting is.
This bug could be hidden though by changes introduced in
commit f1a000a477558e157532d5f2cd2f9c9139d4f87c as it
calls full_rescan earlier before this problem is hit.
But we need to fix this anyway for the dev_cache_get
to be correct if we happen to use the same code path
again somewhere sometime.
For example, simple reproducer was (before commit
1a000a477558e157532d5f2cd2f9c9139d4f87c):
- /dev/sda contains a PV header with UUID y5PzRD-RBAv-7sBx-V3SP-vDmy-DeSq-GUh65M
- lvm.conf: filter = [ "r|.*|" ]
- rm -f .cache (to start with clean state)
- dmsetup create test --table "0 8388608 linear /dev/sda 0" (8388608 is
just the size of the /dev/sda device I use in the reproducer)
- pvs (this will create .cache file which contains
"/dev/disk/by-id/lvm-pv-uuid-y5PzRD-RBAv-7sBx-V3SP-vDmy-DeSq-GUh65M"
as well as "/dev/mapper/test" and the target node "/dev/dm-1" - all the
usable DM mappings (and their symlinks) get into the .cache file even
though the filter "is set to "ignore all" - we do this - so far it's OK)
- dmsetup remove test (so we end up with /dev/disk/by-id/lvm-pv-uuid-...
pointing to the /dev/sda now since it's the underlying device
containing the actual PV header)
- now calling "pvs" with such .cache file and we get:
$ pvs
PV VG Fmt Attr PSize PFree
/dev/disk/by-id/lvm-pv-uuid-y5PzRD-RBAv-7sBx-V3SP-vDmy-DeSq-GUh65M vg lvm2 a-- 4.00g 0
Even though we have set filter = [ "r|.*|" ] in the lvm.conf file!
---
WHATS_NEW | 1 +
lib/device/dev-cache.c | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index df2a730..436d1d9 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.127 -
=================================
+ Fix regression in cache causing some PVs to bypass filters (2.02.105).
Version 2.02.126 - 24th July 2015
=================================
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index d854e2b..e58ac0f 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -945,7 +945,7 @@ struct device *dev_cache_get(const char *name, struct dev_filter *f)
if (d)
dm_hash_remove(_cache.names, name);
log_sys_very_verbose("stat", name);
- return NULL;
+ d = NULL;
}
if (d && (buf.st_rdev != d->dev)) {
8 years, 9 months
master - libdm: Add dm_size_to_string to libdevmapper.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=af1c7bf0c71f9c...
Commit: af1c7bf0c71f9cc132e9cf211eb1512078af0081
Parent: fa11ddd7df9cd29956cb2610d4a730980734b8c2
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Mon Jul 27 21:30:20 2015 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Mon Jul 27 21:30:20 2015 +0100
libdm: Add dm_size_to_string to libdevmapper.
Moved out from lib/display and a little documentation added.
It's tuned to LVM's requirements historically and its behaviour
might not always be what you would expect.
---
configure.in | 2 +-
lib/display/display.c | 156 ++--------------------------------
libdm/.exported_symbols.DM_1_02_104 | 1 +
libdm/libdevmapper.h | 26 ++++++
libdm/libdm-string.c | 157 ++++++++++++++++++++++++++++++++++-
5 files changed, 193 insertions(+), 149 deletions(-)
diff --git a/configure.in b/configure.in
index c2cd69a..e273e1d 100644
--- a/configure.in
+++ b/configure.in
@@ -1726,7 +1726,7 @@ if test "$BUILD_CMIRRORD" = yes; then
fi
if test "$BUILD_LVMLOCKD" = yes; then
- AC_CHECK_FUNCS(clock_gettime strtoull,,hard_bailout)
+ AC_CHECK_FUNCS(clock_gettime strtoull,,hard_bailout)
fi
if test "$BUILD_LVMPOLLD" = yes; then
diff --git a/lib/display/display.c b/lib/display/display.c
index 62ad1fe..308ce31 100644
--- a/lib/display/display.c
+++ b/lib/display/display.c
@@ -24,10 +24,6 @@
#include <stdarg.h>
-#define SIZE_BUF 128
-
-typedef enum { SIZE_LONG = 0, SIZE_SHORT = 1, SIZE_UNIT = 2 } size_len_t;
-
static const struct {
alloc_policy_t alloc;
const char str[14]; /* must be changed when size extends 13 chars */
@@ -146,164 +142,30 @@ const char *display_lvname(const struct logical_volume *lv)
return name;
}
-#define BASE_UNKNOWN 0
-#define BASE_SHARED 1
-#define BASE_1024 8
-#define BASE_1000 15
-#define BASE_SPECIAL 21
-#define NUM_UNIT_PREFIXES 6
-#define NUM_SPECIAL 3
-
/* Size supplied in sectors */
static const char *_display_size(const struct cmd_context *cmd,
- uint64_t size, size_len_t sl)
+ uint64_t size, dm_size_suffix_t suffix_type)
{
- unsigned base = BASE_UNKNOWN;
- unsigned s;
- int suffix, precision;
- uint64_t byte = UINT64_C(0);
- uint64_t units = UINT64_C(1024);
- char *size_buf = NULL;
- const char * const size_str[][3] = {
- /* BASE_UNKNOWN */
- {" ", " ", " "}, /* [0] */
-
- /* BASE_SHARED - Used if cmd->si_unit_consistency = 0 */
- {" Exabyte", " EB", "E"}, /* [1] */
- {" Petabyte", " PB", "P"}, /* [2] */
- {" Terabyte", " TB", "T"}, /* [3] */
- {" Gigabyte", " GB", "G"}, /* [4] */
- {" Megabyte", " MB", "M"}, /* [5] */
- {" Kilobyte", " KB", "K"}, /* [6] */
- {" Byte ", " B", "B"}, /* [7] */
-
- /* BASE_1024 - Used if cmd->si_unit_consistency = 1 */
- {" Exbibyte", " EiB", "e"}, /* [8] */
- {" Pebibyte", " PiB", "p"}, /* [9] */
- {" Tebibyte", " TiB", "t"}, /* [10] */
- {" Gibibyte", " GiB", "g"}, /* [11] */
- {" Mebibyte", " MiB", "m"}, /* [12] */
- {" Kibibyte", " KiB", "k"}, /* [13] */
- {" Byte ", " B", "b"}, /* [14] */
-
- /* BASE_1000 - Used if cmd->si_unit_consistency = 1 */
- {" Exabyte", " EB", "E"}, /* [15] */
- {" Petabyte", " PB", "P"}, /* [16] */
- {" Terabyte", " TB", "T"}, /* [17] */
- {" Gigabyte", " GB", "G"}, /* [18] */
- {" Megabyte", " MB", "M"}, /* [19] */
- {" Kilobyte", " kB", "K"}, /* [20] */
-
- /* BASE_SPECIAL */
- {" Byte ", " B ", "B"}, /* [21] (shared with BASE_1000) */
- {" Units ", " Un", "U"}, /* [22] */
- {" Sectors ", " Se", "S"}, /* [23] */
- };
-
- if (!(size_buf = dm_pool_alloc(cmd->mem, SIZE_BUF))) {
- log_error("no memory for size display buffer");
- return "";
- }
-
- suffix = cmd->current_settings.suffix;
-
- if (!cmd->si_unit_consistency) {
- /* Case-independent match */
- for (s = 0; s < NUM_UNIT_PREFIXES; s++)
- if (toupper((int) cmd->current_settings.unit_type) ==
- *size_str[BASE_SHARED + s][2]) {
- base = BASE_SHARED;
- break;
- }
- } else {
- /* Case-dependent match for powers of 1000 */
- for (s = 0; s < NUM_UNIT_PREFIXES; s++)
- if (cmd->current_settings.unit_type ==
- *size_str[BASE_1000 + s][2]) {
- base = BASE_1000;
- break;
- }
-
- /* Case-dependent match for powers of 1024 */
- if (base == BASE_UNKNOWN)
- for (s = 0; s < NUM_UNIT_PREFIXES; s++)
- if (cmd->current_settings.unit_type ==
- *size_str[BASE_1024 + s][2]) {
- base = BASE_1024;
- break;
- }
- }
-
- if (base == BASE_UNKNOWN)
- /* Check for special units - s, b or u */
- for (s = 0; s < NUM_SPECIAL; s++)
- if (toupper((int) cmd->current_settings.unit_type) ==
- *size_str[BASE_SPECIAL + s][2]) {
- base = BASE_SPECIAL;
- break;
- }
-
- if (size == UINT64_C(0)) {
- if (base == BASE_UNKNOWN)
- s = 0;
- sprintf(size_buf, "0%s", suffix ? size_str[base + s][sl] : "");
- return size_buf;
- }
-
- size *= UINT64_C(512);
-
- if (base != BASE_UNKNOWN)
- byte = cmd->current_settings.unit_factor;
- else {
- /* Human-readable style */
- if (cmd->current_settings.unit_type == 'H') {
- units = UINT64_C(1000);
- base = BASE_1000;
- } else {
- units = UINT64_C(1024);
- base = BASE_1024;
- }
-
- if (!cmd->si_unit_consistency)
- base = BASE_SHARED;
-
- byte = units * units * units * units * units * units;
-
- for (s = 0; s < NUM_UNIT_PREFIXES && size < byte; s++)
- byte /= units;
-
- suffix = 1;
- }
-
- /* FIXME Make precision configurable */
- switch (toupper(*size_str[base + s][SIZE_UNIT])) {
- case 'B':
- case 'S':
- precision = 0;
- break;
- default:
- precision = 2;
- }
-
- snprintf(size_buf, SIZE_BUF - 1, "%.*f%s", precision,
- (double) size / byte, suffix ? size_str[base + s][sl] : "");
-
- return size_buf;
+ return dm_size_to_string(cmd->mem, size, cmd->current_settings.unit_type,
+ cmd->si_unit_consistency,
+ cmd->current_settings.unit_factor,
+ cmd->current_settings.suffix,
+ suffix_type);
}
const char *display_size_long(const struct cmd_context *cmd, uint64_t size)
{
- return _display_size(cmd, size, SIZE_LONG);
+ return _display_size(cmd, size, DM_SIZE_LONG);
}
const char *display_size_units(const struct cmd_context *cmd, uint64_t size)
{
- return _display_size(cmd, size, SIZE_UNIT);
+ return _display_size(cmd, size, DM_SIZE_UNIT);
}
const char *display_size(const struct cmd_context *cmd, uint64_t size)
{
- return _display_size(cmd, size, SIZE_SHORT);
+ return _display_size(cmd, size, DM_SIZE_SHORT);
}
void pvdisplay_colons(const struct physical_volume *pv)
diff --git a/libdm/.exported_symbols.DM_1_02_104 b/libdm/.exported_symbols.DM_1_02_104
new file mode 100644
index 0000000..7bd144d
--- /dev/null
+++ b/libdm/.exported_symbols.DM_1_02_104
@@ -0,0 +1 @@
+dm_size_to_string
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index 6523c70..3a900be 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -1532,6 +1532,32 @@ int dm_strncpy(char *dest, const char *src, size_t n);
uint64_t dm_units_to_factor(const char *units, char *unit_type,
int strict, const char **endptr);
+/*
+ * Type of unit specifier used by dm_size_to_string().
+ */
+typedef enum {
+ DM_SIZE_LONG = 0, /* Megabyte */
+ DM_SIZE_SHORT = 1, /* MB or MiB */
+ DM_SIZE_UNIT = 2 /* M or m */
+} dm_size_suffix_t;
+
+/*
+ * Convert a size (in 512-byte sectors) into a printable string using units of unit_type.
+ * An upper-case unit_type indicates output units based on powers of 1000 are
+ * required; a lower-case unit_type indicates powers of 1024.
+ * For correct operation, unit_factor must be one of:
+ * 0 - the correct value will be calculated internally;
+ * or the output from dm_units_to_factor() corresponding to unit_type;
+ * or 'u' or 'U', an arbitrary number of bytes to use as the power base.
+ * Set include_suffix to 1 to include a suffix of suffix_type.
+ * Set use_si_units to 0 for suffixes that don't distinguish between 1000 and 1024.
+ * Set use_si_units to 1 for a suffix that does distinguish.
+ */
+const char *dm_size_to_string(struct dm_pool *mem, uint64_t size,
+ char unit_type, int use_si_units,
+ uint64_t unit_factor, int include_suffix,
+ dm_size_suffix_t suffix_type);
+
/**************************
* file/stream manipulation
**************************/
diff --git a/libdm/libdm-string.c b/libdm/libdm-string.c
index bc41b70..587abfe 100644
--- a/libdm/libdm-string.c
+++ b/libdm/libdm-string.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2012 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 Red Hat, Inc. All rights reserved.
*
* This file is part of the device-mapper userspace tools.
*
@@ -443,6 +443,161 @@ static int _close_enough(double d1, double d2)
return fabs(d1 - d2) < DBL_EPSILON;
}
+#define BASE_UNKNOWN 0
+#define BASE_SHARED 1
+#define BASE_1024 8
+#define BASE_1000 15
+#define BASE_SPECIAL 21
+#define NUM_UNIT_PREFIXES 6
+#define NUM_SPECIAL 3
+
+#define SIZE_BUF 128
+
+const char *dm_size_to_string(struct dm_pool *mem, uint64_t size,
+ char unit_type, int use_si_units,
+ uint64_t unit_factor, int include_suffix,
+ dm_size_suffix_t suffix_type)
+{
+ unsigned base = BASE_UNKNOWN;
+ unsigned s;
+ int precision;
+ uint64_t byte = UINT64_C(0);
+ uint64_t units = UINT64_C(1024);
+ char *size_buf = NULL;
+ char new_unit_type = '\0', unit_type_buf[2];
+ const char * const size_str[][3] = {
+ /* BASE_UNKNOWN */
+ {" ", " ", " "}, /* [0] */
+
+ /* BASE_SHARED - Used if use_si_units = 0 */
+ {" Exabyte", " EB", "E"}, /* [1] */
+ {" Petabyte", " PB", "P"}, /* [2] */
+ {" Terabyte", " TB", "T"}, /* [3] */
+ {" Gigabyte", " GB", "G"}, /* [4] */
+ {" Megabyte", " MB", "M"}, /* [5] */
+ {" Kilobyte", " KB", "K"}, /* [6] */
+ {" Byte ", " B", "B"}, /* [7] */
+
+ /* BASE_1024 - Used if use_si_units = 1 */
+ {" Exbibyte", " EiB", "e"}, /* [8] */
+ {" Pebibyte", " PiB", "p"}, /* [9] */
+ {" Tebibyte", " TiB", "t"}, /* [10] */
+ {" Gibibyte", " GiB", "g"}, /* [11] */
+ {" Mebibyte", " MiB", "m"}, /* [12] */
+ {" Kibibyte", " KiB", "k"}, /* [13] */
+ {" Byte ", " B", "b"}, /* [14] */
+
+ /* BASE_1000 - Used if use_si_units = 1 */
+ {" Exabyte", " EB", "E"}, /* [15] */
+ {" Petabyte", " PB", "P"}, /* [16] */
+ {" Terabyte", " TB", "T"}, /* [17] */
+ {" Gigabyte", " GB", "G"}, /* [18] */
+ {" Megabyte", " MB", "M"}, /* [19] */
+ {" Kilobyte", " kB", "K"}, /* [20] */
+
+ /* BASE_SPECIAL */
+ {" Byte ", " B ", "B"}, /* [21] (shared with BASE_1000) */
+ {" Units ", " Un", "U"}, /* [22] */
+ {" Sectors ", " Se", "S"}, /* [23] */
+ };
+
+ if (!(size_buf = dm_pool_alloc(mem, SIZE_BUF))) {
+ log_error("no memory for size display buffer");
+ return "";
+ }
+
+ if (!use_si_units) {
+ /* Case-independent match */
+ for (s = 0; s < NUM_UNIT_PREFIXES; s++)
+ if (toupper((int) unit_type) ==
+ *size_str[BASE_SHARED + s][2]) {
+ base = BASE_SHARED;
+ break;
+ }
+ } else {
+ /* Case-dependent match for powers of 1000 */
+ for (s = 0; s < NUM_UNIT_PREFIXES; s++)
+ if (unit_type == *size_str[BASE_1000 + s][2]) {
+ base = BASE_1000;
+ break;
+ }
+
+ /* Case-dependent match for powers of 1024 */
+ if (base == BASE_UNKNOWN)
+ for (s = 0; s < NUM_UNIT_PREFIXES; s++)
+ if (unit_type == *size_str[BASE_1024 + s][2]) {
+ base = BASE_1024;
+ break;
+ }
+ }
+
+ if (base == BASE_UNKNOWN)
+ /* Check for special units - s, b or u */
+ for (s = 0; s < NUM_SPECIAL; s++)
+ if (toupper((int) unit_type) ==
+ *size_str[BASE_SPECIAL + s][2]) {
+ base = BASE_SPECIAL;
+ break;
+ }
+
+ if (size == UINT64_C(0)) {
+ if (base == BASE_UNKNOWN)
+ s = 0;
+ sprintf(size_buf, "0%s", include_suffix ? size_str[base + s][suffix_type] : "");
+ return size_buf;
+ }
+
+ size *= UINT64_C(512);
+
+ if (base != BASE_UNKNOWN) {
+ if (!unit_factor) {
+ unit_type_buf[0] = unit_type;
+ unit_type_buf[1] = '\0';
+ if (!(unit_factor = dm_units_to_factor(&unit_type_buf[0], &new_unit_type, 1, NULL)) ||
+ unit_type != new_unit_type) {
+ /* The two functions should match (and unrecognised units get treated like 'h'). */
+ log_error(INTERNAL_ERROR "Inconsistent units: %c and %c.", unit_type, new_unit_type);
+ return "";
+ }
+ }
+ byte = unit_factor;
+ } else {
+ /* Human-readable style */
+ if (unit_type == 'H') {
+ units = UINT64_C(1000);
+ base = BASE_1000;
+ } else {
+ units = UINT64_C(1024);
+ base = BASE_1024;
+ }
+
+ if (!use_si_units)
+ base = BASE_SHARED;
+
+ byte = units * units * units * units * units * units;
+
+ for (s = 0; s < NUM_UNIT_PREFIXES && size < byte; s++)
+ byte /= units;
+
+ include_suffix = 1;
+ }
+
+ /* FIXME Make precision configurable */
+ switch (toupper(*size_str[base + s][DM_SIZE_UNIT])) {
+ case 'B':
+ case 'S':
+ precision = 0;
+ break;
+ default:
+ precision = 2;
+ }
+
+ snprintf(size_buf, SIZE_BUF - 1, "%.*f%s", precision,
+ (double) size / byte, include_suffix ? size_str[base + s][suffix_type] : "");
+
+ return size_buf;
+}
+
uint64_t dm_units_to_factor(const char *units, char *unit_type,
int strict, const char **endptr)
{
8 years, 9 months
master - lvmlockd: Drop -lrt now handled by configure.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=fa11ddd7df9cd2...
Commit: fa11ddd7df9cd29956cb2610d4a730980734b8c2
Parent: 3e333e9b5c0fcae2014dcb22f14d288b440b9576
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Mon Jul 27 14:53:08 2015 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Mon Jul 27 14:53:08 2015 +0100
lvmlockd: Drop -lrt now handled by configure.
---
daemons/lvmlockd/Makefile.in | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/daemons/lvmlockd/Makefile.in b/daemons/lvmlockd/Makefile.in
index fed7c22..a2aca30 100644
--- a/daemons/lvmlockd/Makefile.in
+++ b/daemons/lvmlockd/Makefile.in
@@ -34,7 +34,7 @@ include $(top_builddir)/make.tmpl
INCLUDES += -I$(top_srcdir)/libdaemon/server
LVMLIBS = -ldaemonserver $(LVMINTERNAL_LIBS) -ldevmapper
-LIBS += $(PTHREAD_LIBS) -lrt
+LIBS += $(PTHREAD_LIBS)
ifeq ("@BUILD_LOCKDSANLOCK@", "yes")
LIBS += -lsanlock_client
8 years, 9 months