1
0
mirror of git://sourceware.org/git/lvm2.git synced 2026-01-18 00:34:07 +03:00

Compare commits

..

1 Commits

Author SHA1 Message Date
David Teigland
b6e67d688e writecache: enable use with thin pool data
. it's of little use since the thin pool cannot be extended
  while it's using writecache.

. lvconvert --splitcache on tdata isn't working, the writecache
  table doesn't get updated with the cleaner setting.

. adding writecache to existing tdata not yet implemented
2020-10-28 13:37:44 -05:00
457 changed files with 21017 additions and 28712 deletions

1
.gitignore vendored
View File

@@ -32,7 +32,6 @@ make.tmpl
/configure.scan
/cscope.*
/html/
/python/
/reports/
/tags
/tmp/

View File

@@ -18,7 +18,7 @@ top_builddir = @top_builddir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
SUBDIRS = libdm conf daemons include lib libdaemon man scripts tools
SUBDIRS = conf daemons include lib libdaemon libdm man scripts tools
ifeq ("@UDEV_RULES@", "yes")
SUBDIRS += udev
@@ -47,6 +47,8 @@ include $(top_srcdir)/base/Makefile
include $(top_srcdir)/device_mapper/Makefile
include $(top_srcdir)/test/unit/Makefile
libdm: include
libdaemon: include
lib: libdaemon $(BASE_TARGET) $(DEVICE_MAPPER_TARGET)
daemons: lib libdaemon tools
scripts: lib
@@ -54,13 +56,16 @@ tools: lib libdaemon
po: tools daemons
man: tools
all_man: tools
scripts: libdm
test: tools daemons
unit-test run-unit-test: test
lib.device-mapper: include.device-mapper
libdm.device-mapper: include.device-mapper
daemons.device-mapper: libdm.device-mapper
tools.device-mapper: libdm.device-mapper
scripts.device-mapper: include.device-mapper
device-mapper: tools.device-mapper daemons.device-mapper man.device-mapper
device_mapper: device-mapper
ifeq ("@INTL@", "yes")
lib.pofile: include.pofile
@@ -76,10 +81,9 @@ daemons.cflow: tools.cflow
cflow: include.cflow
endif
CSCOPE_DIRS = base daemons device_mapper include lib libdaemon scripts tools libdm test
ifneq ("@CSCOPE_CMD@", "")
cscope.out:
@CSCOPE_CMD@ -b -R $(patsubst %,-s%,$(addprefix $(srcdir)/,$(CSCOPE_DIRS)))
@CSCOPE_CMD@ -b -R -s$(top_srcdir)
all: cscope.out
endif
DISTCLEAN_TARGETS += cscope.out
@@ -112,11 +116,11 @@ rpm: dist
$(LN_S) -f $(abs_top_srcdir)/spec/packages.inc $(rpmbuilddir)/SOURCES
DM_VER=$$(cut -d- -f1 $(top_srcdir)/VERSION_DM);\
GIT_VER=$$(cd $(top_srcdir); git describe | cut -d- --output-delimiter=. -f2,3 || echo 0);\
$(SED) -e "s,\(device_mapper_version\) [0-9.]*$$,\1 $$DM_VER," \
sed -e "s,\(device_mapper_version\) [0-9.]*$$,\1 $$DM_VER," \
-e "s,^\(Version:[^0-9%]*\)[0-9.]*$$,\1 $(LVM_VER)," \
-e "s,^\(Release:[^0-9%]*\)[0-9.]\+,\1 $$GIT_VER," \
$(top_srcdir)/spec/source.inc >$(rpmbuilddir)/SOURCES/source.inc
V=$(V) rpmbuild -v --define "_topdir $(rpmbuilddir)" -ba $(top_srcdir)/spec/lvm2.spec
rpmbuild -v --define "_topdir $(rpmbuilddir)" -ba $(top_srcdir)/spec/lvm2.spec
generate: conf.generate man.generate
$(MAKE) -C conf generate
@@ -150,31 +154,6 @@ install_all_man:
install_tmpfiles_configuration:
$(MAKE) -C scripts install_tmpfiles_configuration
help:
@echo -e "\nAvailable targets:"
@echo " all Default target."
@echo " all_man Build all man pages with generators."
@echo " clean Remove all compile files."
@echo " device-mapper Device mapper part of lvm2."
@echo " dist Generate distributable file."
@echo " distclean Remove all build files."
@echo " generate Generate man pages for sources."
@echo " help Display callable targets."
@echo " install Install all files."
@echo " install_all_man Install all man pages."
@echo " install_cluster Install cmirrord."
@echo " install_device-mapper Install device mapper files."
@echo " install_initscripts Install initialization scripts."
@echo " install_lvm2 Install lvm2 files."
@echo " install_systemd_units Install systemd units."
@echo " lcov Generate lcov output."
@echo " lcov-dated Generate lcov with timedate suffix."
@echo " lcov-reset Reset lcov counters"
@echo " man Build man pages."
@echo " rpm Build rpm."
@echo " run-unit-test Run unit tests."
@echo " tags Generate c/etags."
ifneq ("$(LCOV)", "")
.PHONY: lcov-reset lcov lcov-dated
@@ -204,8 +183,8 @@ endif
ifneq ($(shell which ctags 2>/dev/null),)
.PHONY: tags
tags:
test -z "$(shell find $(addprefix $(top_srcdir)/,$(CSCOPE_DIRS)) -type f -name '*.[ch]' -newer tags 2>/dev/null | head -1)" || $(RM) tags
test -f tags || find $(addprefix $(top_srcdir)/,$(CSCOPE_DIRS)) -maxdepth 5 -type f -name '*.[ch]' -exec ctags -a '{}' +
test -z "$(shell find $(top_srcdir) -type f -name '*.[ch]' -newer tags 2>/dev/null | head -1)" || $(RM) tags
test -f tags || find $(top_srcdir) -maxdepth 5 -type f -name '*.[ch]' -exec ctags -a '{}' +
CLEAN_TARGETS += tags
endif

View File

@@ -1 +1 @@
2.03.13(2)-git (2021-05-07)
2.03.11(2)-git (2020-08-09)

View File

@@ -1 +1 @@
1.02.179-git (2021-05-07)
1.02.175-git (2020-08-09)

View File

@@ -1,78 +1,6 @@
Version 2.03.13 -
===============================
Simplified handling of archive() and backup() internal calls.
Fix load of kvdo target when it is not present in memory (2.03.12).
Version 2.03.12 - 07th May 2021
===============================
Allow attaching cache to thin data volume.
Fix memleak when generating list of outdated pvs.
Better hyphenation usage in man pages.
Replace use of deprecated security_context_t with char*.
Configure supports AIO_LIBS and AIO_CFLAGS.
Improve build process for static builds.
New --setautoactivation option to modify LV or VG auto activation.
New metadata based autoactivation property for LVs and VGs.
Improve signal handling with lvmpolld.
Signal handler can interrupt command also for SIGTERM.
Lvreduce --yes support.
Add configure option --with/out-symvers for non-glibc builds.
Report error when the filesystem is missing on fsadm resized volume.
Handle better blockdev with --getsize64 support for fsadm.
Do not include editline/history.h when using editline library.
Support error and zero segtype for thin-pool data for testing.
Support mixed extension for striped, error and zero segtypes.
Support resize also for stacked virtual volumes.
Skip dm-zero devices just like with dm-error target.
Reduce ioctl() calls when checking target status.
Merge polling does not fail, when LV is found to be already merged.
Poll volumes with at least 100ms delays.
Do not flush dm cache when cached LV is going to be removed.
New lvmlockctl_kill_command configuration option.
Support interruption while waiting on device close before deactivation.
Flush thin-pool messages before removing more thin volumes.
Improve hash function with less collisions and make it faster.
Reduce ioctl count when deactivating volumes.
Reduce number of metadata parsing.
Enhance performance of lvremove and vgremove commands.
Support interruption when taking archive and backup.
Accelerate large lvremoves.
Speedup search for cached device nodes.
Speedup command initialization.
Add devices file feature, off by default for now.
Support extension of writecached volumes.
Fix problem with unbound variable usage within fsadm.
Fix IMSM MD RAID detection on 4k devices.
Check for presence of VDO target before starting any conversion.
Support metatadata profiles with volume VDO pool conversions.
Support -Zn for conversion of already formated VDO pools.
Avoid removing LVs on error path of lvconvert during creation volumes.
Fix crashing lvdisplay when thin volume was waiting for merge.
Support option --errorwhenfull when converting volume to thin-pool.
Improve thin-performance profile support conversion to thin-pool.
Add workaround to avoid read of internal 'converted' devices.
Prohibit merging snapshot into the read-only thick snapshot origin.
Restore support for flipping rw/r permissions for thin snapshot origin.
Support resize of cached volumes.
Disable autoactivation with global/event_activation=0.
Check if lvcreate passes read_only_volume_list with tags and skips zeroing.
Allocation prints better error when metadata cannot fit on a single PV.
Pvmove can better resolve full thin-pool tree move.
Limit pool metadata spare to 16GiB.
Improves conversion and allocation of pool metadata.
Support thin pool metadata 15.88GiB, adds 64MiB, thin_pool_crop_metadata=0.
Enhance lvdisplay to report raid available/partial.
Support online rename of VDO pools.
Improve removal of pmspare when last pool is removed.
Fix problem with wiping of converted LVs.
Fix memleak in scanning (2.03.11).
Fix corner case allocation for thin-pools.
Version 2.03.11 - 08th January 2021
===================================
Fix pvck handling MDA at offset different from 4096.
Partial or degraded activation of writecache is not allowed.
Enhance error handling for fsadm and handle correct fsck result.
Version 2.03.11 -
==================================
Enhance error handling for fsadm and hanled correct fsck result.
Dmeventd lvm plugin ignores higher reserved_stack lvm.conf values.
Support using BLKZEROOUT for clearing devices.
Support interruption when wipping LVs.
@@ -92,9 +20,6 @@ Version 2.03.11 - 08th January 2021
Enhance --use-policy percentage rounding.
Configure --with-vdo and --with-writecache as internal segments.
Improving VDO man page examples.
Allow pvmove of writecache origin.
Report integrity fields.
Integrity volumes defaults to journal mode.
Switch code base to use flexible array syntax.
Fix 64bit math when calculation cachevol size.
Preserve uint32_t for seqno handling.
@@ -266,6 +191,7 @@ Version 2.03.00 - 10th October 2018
Remove clvmd
Remove lvmlib (api)
Remove lvmetad
lvconvert: provide possible layouts between linear and striped/raid
Use versionsort to fix archive file expiry beyond 100000 files.
Version 2.02.178-rc1 - 24th May 2018
@@ -1785,7 +1711,7 @@ Version 2.02.105 - 20th January 2014
Allow lvmetad to reuse stale socket.
Only unlink lvmetad socket on error if created by the same process.
Append missing newline to lvmetad missing socket path error message.
Check for non-zero alignment in _text_pv_add_metadata_area() to not div by 0.
Check for non-zero aligment in _text_pv_add_metadata_area() to not div by 0.
Add allocation/use_blkid_wiping to lvm.conf to enable blkid wiping.
Enable blkid_wiping by default if the blkid library is present.
Add configure --disable-blkid_wiping to disable libblkid signature detection.

View File

@@ -1,14 +1,5 @@
Version 1.02.179 -
================================
Version 1.02.177 - 07th May 2021
================================
Configure proceeds without libaio to allow build of device-mapper only.
Fix symbol versioning build with -O2 -flto.
Add dm_tree_node_add_thin_pool_target_v1 with crop_metadata support.
Version 1.02.175 - 08th January 2021
====================================
Version 1.02.175 -
===================================
Version 1.02.173 - 09th August 2020
===================================
@@ -560,7 +551,7 @@ Version 1.02.86 - 23rd June 2014
Add DM_REPORT_FIELD_TYPE_STRING_LIST: separate string and string list fields.
Add dm_str_list to libdevmapper for string list type definition and its reuse.
Add dmsetup -S/--select to define selection criteria for dmsetup reports.
Add dm_report_init_with_selection to initialize report with selection criteria.
Add dm_report_init_with_selection to intialize report with selection criteria.
Add DM_REPORT_FIELD_TYPE_SIZE: separate number and size reporting fields.
Use RemoveOnStop for dm-event.socket systemd unit.
Document env var 'DM_DEFAULT_NAME_MANGLING_MODE' in dmsetup man page.

10
aclocal.m4 vendored
View File

@@ -496,14 +496,12 @@ AC_DEFUN([AM_PATH_PYTHON],
m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])])
else
dnl Query Python for its version number. Although site.py simply uses
dnl sys.version[:3], printing that failed with Python 3.10, since the
dnl trailing zero was eliminated. So now we output just the major
dnl and minor version numbers, as numbers. Apparently the tertiary
dnl version is not of interest.
dnl Query Python for its version number. Getting [:3] seems to be
dnl the best way to do this; it's what "site.py" does in the standard
dnl library.
AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version],
[am_cv_python_version=`$PYTHON -c "import sys; print('%u.%u' % sys.version_info[[:2]])"`])
[am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`])
AC_SUBST([PYTHON_VERSION], [$am_cv_python_version])
dnl Use the values of $prefix and $exec_prefix for the corresponding

View File

@@ -22,26 +22,17 @@ struct dm_hash_node {
void *data;
unsigned data_len;
unsigned keylen;
unsigned hash;
char key[];
};
struct dm_hash_table {
unsigned num_nodes;
unsigned num_hint;
unsigned mask_slots; /* (slots - 1) -> used as hash mask */
unsigned collisions; /* Collissions of hash keys */
unsigned search; /* How many keys were searched */
unsigned found; /* How many nodes were found */
unsigned same_hash; /* Was there a colision with same masked hash and len ? */
unsigned num_slots;
struct dm_hash_node **slots;
};
#if 0 /* TO BE REMOVED */
static unsigned _hash(const void *key, unsigned len)
{
/* Permutation of the Integers 0 through 255 */
static unsigned char _nums[] = {
/* Permutation of the Integers 0 through 255 */
static unsigned char _nums[] = {
1, 14, 110, 25, 97, 174, 132, 119, 138, 170, 125, 118, 27, 233, 140, 51,
87, 197, 177, 107, 234, 169, 56, 68, 30, 7, 173, 73, 188, 40, 36, 65,
49, 213, 104, 190, 57, 211, 148, 223, 48, 115, 15, 2, 67, 186, 210, 28,
@@ -66,79 +57,7 @@ static unsigned _hash(const void *key, unsigned len)
44, 38, 31, 149, 135, 0, 216, 52, 63, 23, 37, 69, 39, 117, 146, 184,
163, 200, 222, 235, 248, 243, 219, 10, 152, 131, 123, 229, 203, 76, 120,
209
};
const uint8_t *str = key;
unsigned h = 0, g;
unsigned i;
for (i = 0; i < len; i++) {
h <<= 4;
h += _nums[*str++];
g = h & ((unsigned) 0xf << 16u);
if (g) {
h ^= g >> 16u;
h ^= g >> 5u;
}
}
return h;
}
/* In-kernel DM hashing, still lots of collisions */
static unsigned _hash_in_kernel(const char *key, unsigned len)
{
const unsigned char *str = (unsigned char *)key;
const unsigned hash_mult = 2654435387U;
unsigned hash = 0, i;
for (i = 0; i < len; ++i)
hash = (hash + str[i]) * hash_mult;
return hash;
}
#endif
#undef get16bits
#if (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))
#define get16bits(d) (*((const uint16_t *) (d)))
#endif
#if !defined (get16bits)
#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
+(uint32_t)(((const uint8_t *)(d))[0]) )
#endif
/*
* Adapted Bob Jenkins hash to read by 2 bytes if possible.
* https://secure.wikimedia.org/wikipedia/en/wiki/Jenkins_hash_function
*
* Reduces amount of hash collisions
*/
static unsigned _hash(const void *key, unsigned len)
{
const uint8_t *str = (uint8_t*) key;
unsigned hash = 0, i;
unsigned sz = len / 2;
for(i = 0; i < sz; ++i) {
hash += get16bits(str + 2 * i);
hash += (hash << 10);
hash ^= (hash >> 6);
}
if (len & 1) {
hash += str[len - 1];
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return hash;
}
};
static struct dm_hash_node *_create_node(const void *key, unsigned len)
{
@@ -152,32 +71,49 @@ static struct dm_hash_node *_create_node(const void *key, unsigned len)
return n;
}
static unsigned long _hash(const void *key, unsigned len)
{
const unsigned char *str = key;
unsigned long h = 0, g;
unsigned i;
for (i = 0; i < len; i++) {
h <<= 4;
h += _nums[*str++];
g = h & ((unsigned long) 0xf << 16u);
if (g) {
h ^= g >> 16u;
h ^= g >> 5u;
}
}
return h;
}
struct dm_hash_table *dm_hash_create(unsigned size_hint)
{
size_t len;
unsigned new_size = 16u;
struct dm_hash_table *hc = zalloc(sizeof(*hc));
if (!hc) {
log_error("Failed to allocate memory for hash.");
return 0;
}
hc->num_hint = size_hint;
if (!hc)
return_0;
/* round size hint up to a power of two */
while (new_size < size_hint)
new_size = new_size << 1;
hc->mask_slots = new_size - 1;
hc->num_slots = new_size;
len = sizeof(*(hc->slots)) * new_size;
if (!(hc->slots = zalloc(len))) {
free(hc);
log_error("Failed to allocate slots for hash.");
return 0;
}
if (!(hc->slots = zalloc(len)))
goto_bad;
return hc;
bad:
free(hc->slots);
free(hc);
return 0;
}
static void _free_nodes(struct dm_hash_table *t)
@@ -185,16 +121,7 @@ static void _free_nodes(struct dm_hash_table *t)
struct dm_hash_node *c, *n;
unsigned i;
#ifdef DEBUG
log_debug("Free hash hint:%d slots:%d nodes:%d (s:%d f:%d c:%d h:%d)",
t->num_hint, t->mask_slots + 1, t->num_nodes,
t->search, t->found, t->collisions, t->same_hash);
#endif
if (!t->num_nodes)
return;
for (i = 0; i <= t->mask_slots; i++)
for (i = 0; i < t->num_slots; i++)
for (c = t->slots[i]; c; c = n) {
n = c->next;
free(c);
@@ -208,30 +135,21 @@ void dm_hash_destroy(struct dm_hash_table *t)
free(t);
}
static struct dm_hash_node **_findh(struct dm_hash_table *t, const void *key,
uint32_t len, unsigned hash)
{
struct dm_hash_node **c;
++t->search;
for (c = &t->slots[hash & t->mask_slots]; *c; c = &((*c)->next)) {
if ((*c)->keylen == len && (*c)->hash == hash) {
if (!memcmp(key, (*c)->key, len)) {
++t->found;
break;
}
++t->same_hash;
}
++t->collisions;
}
return c;
}
static struct dm_hash_node **_find(struct dm_hash_table *t, const void *key,
uint32_t len)
{
return _findh(t, key, len, _hash(key, len));
unsigned h = _hash(key, len) & (t->num_slots - 1);
struct dm_hash_node **c;
for (c = &t->slots[h]; *c; c = &((*c)->next)) {
if ((*c)->keylen != len)
continue;
if (!memcmp(key, (*c)->key, len))
break;
}
return c;
}
void *dm_hash_lookup_binary(struct dm_hash_table *t, const void *key,
@@ -245,8 +163,7 @@ void *dm_hash_lookup_binary(struct dm_hash_table *t, const void *key,
int dm_hash_insert_binary(struct dm_hash_table *t, const void *key,
uint32_t len, void *data)
{
unsigned hash = _hash(key, len);
struct dm_hash_node **c = _findh(t, key, len, hash);
struct dm_hash_node **c = _find(t, key, len);
if (*c)
(*c)->data = data;
@@ -257,7 +174,6 @@ int dm_hash_insert_binary(struct dm_hash_table *t, const void *key,
return 0;
n->data = data;
n->hash = hash;
n->next = 0;
*c = n;
t->num_nodes++;
@@ -301,7 +217,7 @@ static struct dm_hash_node **_find_str_with_val(struct dm_hash_table *t,
struct dm_hash_node **c;
unsigned h;
h = _hash(key, len) & t->mask_slots;
h = _hash(key, len) & (t->num_slots - 1);
for (c = &t->slots[h]; *c; c = &((*c)->next)) {
if ((*c)->keylen != len)
@@ -332,7 +248,7 @@ int dm_hash_insert_allow_multiple(struct dm_hash_table *t, const char *key,
n->data = (void *)val;
n->data_len = val_len;
h = _hash(key, len) & t->mask_slots;
h = _hash(key, len) & (t->num_slots - 1);
first = t->slots[h];
@@ -400,7 +316,7 @@ void *dm_hash_lookup_with_count(struct dm_hash_table *t, const char *key, int *c
*count = 0;
h = _hash(key, len) & t->mask_slots;
h = _hash(key, len) & (t->num_slots - 1);
for (c = &t->slots[h]; *c; c = &((*c)->next)) {
if ((*c)->keylen != len)
@@ -429,7 +345,7 @@ void dm_hash_iter(struct dm_hash_table *t, dm_hash_iterate_fn f)
struct dm_hash_node *c, *n;
unsigned i;
for (i = 0; i <= t->mask_slots; i++)
for (i = 0; i < t->num_slots; i++)
for (c = t->slots[i]; c; c = n) {
n = c->next;
f(c->data);
@@ -439,8 +355,8 @@ void dm_hash_iter(struct dm_hash_table *t, dm_hash_iterate_fn f)
void dm_hash_wipe(struct dm_hash_table *t)
{
_free_nodes(t);
memset(t->slots, 0, sizeof(struct dm_hash_node *) * (t->mask_slots + 1));
t->num_nodes = t->collisions = t->search = t->same_hash = 0u;
memset(t->slots, 0, sizeof(struct dm_hash_node *) * t->num_slots);
t->num_nodes = 0u;
}
char *dm_hash_get_key(struct dm_hash_table *t __attribute__((unused)),
@@ -460,7 +376,7 @@ static struct dm_hash_node *_next_slot(struct dm_hash_table *t, unsigned s)
struct dm_hash_node *c = NULL;
unsigned i;
for (i = s; i <= t->mask_slots && !c; i++)
for (i = s; i < t->num_slots && !c; i++)
c = t->slots[i];
return c;
@@ -473,5 +389,7 @@ struct dm_hash_node *dm_hash_get_first(struct dm_hash_table *t)
struct dm_hash_node *dm_hash_get_next(struct dm_hash_table *t, struct dm_hash_node *n)
{
return n->next ? n->next : _next_slot(t, (n->hash & t->mask_slots) + 1);
unsigned h = _hash(n->key, n->keylen) & (t->num_slots - 1);
return n->next ? n->next : _next_slot(t, h + 1);
}

View File

@@ -78,14 +78,14 @@ devices {
# routines to acquire this information. For example, this information
# is used to drive LVM filtering like MD component detection, multipath
# component detection, partition detection and others.
#
#
# Accepted values:
# none
# No external device information source is used.
# udev
# Reuse existing udev database records. Applicable only if LVM is
# compiled with udev support.
#
#
external_device_info_source = "none"
# Configuration option devices/hints.
@@ -94,13 +94,13 @@ devices {
# scanning, and will only scan the listed PVs. Removing the hint file
# will cause lvm to generate a new one. Disable hints if PVs will
# be copied onto devices using non-lvm commands, like dd.
#
#
# Accepted values:
# all
# Use all hints.
# none
# Use no hints.
#
#
# This configuration option has an automatic default value.
# hints = "all"
@@ -118,44 +118,12 @@ devices {
# Prefer the name with the least number of slashes.
# Prefer a name that is a symlink.
# Prefer the path with least value in lexicographical order.
#
#
# Example
# preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ]
#
#
# This configuration option does not have a default value defined.
# Configuration option devices/use_devicesfile.
# Enable or disable the use of a devices file.
# When enabled, lvm will only use devices that
# are lised in the devices file. A devices file will
# be used, regardless of this setting, when the --devicesfile
# option is set to a specific file name.
# This configuration option has an automatic default value.
# use_devicesfile = 0
# Configuration option devices/devicesfile.
# The name of the system devices file, listing devices that LVM should use.
# This should not be used to select a non-system devices file.
# The --devicesfile option is intended for alternative devices files.
# This configuration option has an automatic default value.
# devicesfile = "system.devices"
# Configuration option devices/search_for_devnames.
# Look outside of the devices file for missing devname entries.
# A devname entry is used for a device that does not have a stable
# device id, e.g. wwid, so the unstable device name is used as
# the device id. After reboot, or if the device is reattached,
# the device name may change, in which case lvm will not find
# the expected PV on the device listed in the devices file.
# This setting controls whether lvm will search other devices,
# outside the devices file, to look for the missing PV on a
# renamed device. If "none", lvm will not look at other devices,
# and the PV may appear to be missing. If "auto", lvm will look
# at other devices, but only those that are likely to have the PV.
# If "all", lvm will look at all devices on the system.
# This configuration option has an automatic default value.
# search_for_devnames = "auto"
# Configuration option devices/filter.
# Limit the block devices that are used by LVM commands.
# This is a list of regular expressions used to accept or reject block
@@ -171,7 +139,7 @@ devices {
# then the device is accepted. Be careful mixing 'a' and 'r' patterns,
# as the combination might produce unexpected results (test changes.)
# Run vgscan after changing the filter to regenerate the cache.
#
#
# Example
# Accept every block device:
# filter = [ "a|.*|" ]
@@ -183,7 +151,7 @@ devices {
# filter = [ "a|loop|", "r|/dev/hdc|", "a|/dev/ide|", "r|.*|" ]
# Use anchors to be very specific:
# filter = [ "a|^/dev/hda8$|", "r|.*|" ]
#
#
# This configuration option has an automatic default value.
# filter = [ "a|.*|" ]
@@ -201,10 +169,10 @@ devices {
# List of additional acceptable block device types.
# These are of device type names from /proc/devices, followed by the
# maximum number of partitions.
#
#
# Example
# types = [ "fd", 16 ]
#
#
# This configuration option is advanced.
# This configuration option does not have a default value defined.
@@ -246,7 +214,7 @@ devices {
# Configuration option devices/md_component_checks.
# The checks LVM should use to detect MD component devices.
# MD component devices are block devices used by MD software RAID.
#
#
# Accepted values:
# auto
# LVM will skip scanning the end of devices when it has other
@@ -257,7 +225,7 @@ devices {
# full
# LVM will scan the start and end of devices for MD superblocks.
# This requires an extra read at the end of devices.
#
#
# This configuration option has an automatic default value.
# md_component_checks = "auto"
@@ -270,16 +238,16 @@ devices {
# Configuration option devices/md_chunk_alignment.
# Align the start of a PV data area with md device's stripe-width.
# This applies if a PV is placed directly on an md device.
# default_data_alignment will be overridden if it is not aligned
# default_data_alignment will be overriden if it is not aligned
# with the value detected for this setting.
# This setting is overridden by data_alignment_detection,
# This setting is overriden by data_alignment_detection,
# data_alignment, and the --dataalignment option.
md_chunk_alignment = 1
# Configuration option devices/default_data_alignment.
# Align the start of a PV data area with this number of MiB.
# Set to 1 for 1MiB, 2 for 2MiB, etc. Set to 0 to disable.
# This setting is overridden by data_alignment and the --dataalignment
# This setting is overriden by data_alignment and the --dataalignment
# option.
# This configuration option has an automatic default value.
# default_data_alignment = 1
@@ -293,9 +261,9 @@ devices {
# preferred unit of receiving I/O, e.g. MD stripe width.
# minimum_io_size is used if optimal_io_size is undefined (0).
# If md_chunk_alignment is enabled, that detects the optimal_io_size.
# default_data_alignment and md_chunk_alignment will be overridden
# default_data_alignment and md_chunk_alignment will be overriden
# if they are not aligned with the value detected for this setting.
# This setting is overridden by data_alignment and the --dataalignment
# This setting is overriden by data_alignment and the --dataalignment
# option.
data_alignment_detection = 1
@@ -304,7 +272,7 @@ devices {
# When non-zero, this setting overrides default_data_alignment.
# Set to 0 to disable, in which case default_data_alignment
# is used to align the first PE in units of MiB.
# This setting is overridden by the --dataalignment option.
# This setting is overriden by the --dataalignment option.
data_alignment = 0
# Configuration option devices/data_alignment_offset_detection.
@@ -315,7 +283,7 @@ devices {
# partitioning will have an alignment_offset of 3584 bytes (sector 7
# is the lowest aligned logical block, the 4KiB sectors start at
# LBA -1, and consequently sector 63 is aligned on a 4KiB boundary).
# This setting is overridden by the --dataalignmentoffset option.
# This setting is overriden by the --dataalignmentoffset option.
data_alignment_offset_detection = 1
# Configuration option devices/ignore_suspended_devices.
@@ -399,7 +367,7 @@ allocation {
# defined here, it will check whether any of them are attached to the
# PVs concerned and then seek to match those PV tags between existing
# extents and new extents.
#
#
# Example
# Use the special tag "@*" as a wildcard to match any PV tag:
# cling_tag_list = [ "@*" ]
@@ -407,7 +375,7 @@ allocation {
# PVs are tagged with either @site1 or @site2 to indicate where
# they are situated:
# cling_tag_list = [ "@site1", "@site2" ]
#
#
# This configuration option does not have a default value defined.
# Configuration option allocation/maximise_cling.
@@ -466,25 +434,25 @@ allocation {
# Configuration option allocation/cache_metadata_format.
# Sets default metadata format for new cache.
#
#
# Accepted values:
# 0 Automatically detected best available format
# 1 Original format
# 2 Improved 2nd. generation format
#
#
# This configuration option has an automatic default value.
# cache_metadata_format = 0
# Configuration option allocation/cache_mode.
# The default cache mode used for new cache.
#
#
# Accepted values:
# writethrough
# Data blocks are immediately written from the cache to disk.
# writeback
# Data blocks are written from the cache back to disk after some
# delay to improve performance.
#
#
# This setting replaces allocation/cache_pool_cachemode.
# This configuration option has an automatic default value.
# cache_mode = "writethrough"
@@ -525,13 +493,6 @@ allocation {
# This configuration option has an automatic default value.
# thin_pool_metadata_require_separate_pvs = 0
# Configuration option allocation/thin_pool_crop_metadata.
# Older version of lvm2 cropped pool's metadata size to 15.81 GiB.
# This is slightly less then the actual maximum 15.88 GiB.
# For compatibility with older version and use of cropped size set to 1.
# This configuration option has an automatic default value.
# thin_pool_crop_metadata = 0
# Configuration option allocation/thin_pool_zero.
# Thin pool data chunks are zeroed before they are first used.
# Zeroing with a larger thin pool chunk size reduces performance.
@@ -540,18 +501,18 @@ allocation {
# Configuration option allocation/thin_pool_discards.
# The discards behaviour of thin pool volumes.
#
#
# Accepted values:
# ignore
# nopassdown
# passdown
#
#
# This configuration option has an automatic default value.
# thin_pool_discards = "passdown"
# Configuration option allocation/thin_pool_chunk_size_policy.
# The chunk size calculation policy for thin pool volumes.
#
#
# Accepted values:
# generic
# If thin_pool_chunk_size is defined, use it. Otherwise, calculate
@@ -563,7 +524,7 @@ allocation {
# the chunk size for performance based on device hints exposed in
# sysfs - the optimal_io_size. The chunk size is always at least
# 512KiB.
#
#
# This configuration option has an automatic default value.
# thin_pool_chunk_size_policy = "generic"
@@ -976,7 +937,8 @@ global {
# a volume group's metadata, instead of always granting the read-only
# requests immediately, delay them to allow the read-write requests to
# be serviced. Without this setting, write access may be stalled by a
# high volume of read-only requests. This option only affects file locks.
# high volume of read-only requests. This option only affects
# locking_type 1 viz. local file-based locking.
prioritise_write_locks = 1
# Configuration option global/library_dir.
@@ -1000,7 +962,7 @@ global {
# Configuration option global/mirror_segtype_default.
# The segment type used by the short mirroring option -m.
# The --type mirror|raid1 option overrides this setting.
#
#
# Accepted values:
# mirror
# The original RAID1 implementation from LVM/DM. It is
@@ -1020,16 +982,16 @@ global {
# handling a failure. This mirror implementation is not
# cluster-aware and cannot be used in a shared (active/active)
# fashion in a cluster.
#
#
mirror_segtype_default = "@DEFAULT_MIRROR_SEGTYPE@"
# Configuration option global/support_mirrored_mirror_log.
# Enable mirrored 'mirror' log type for testing.
#
#
# This type is deprecated to create or convert to but can
# be enabled to test that activation of existing mirrored
# logs and conversion to disk/core works.
#
#
# Not supported for regular operation!
# This configuration option has an automatic default value.
# support_mirrored_mirror_log = 0
@@ -1040,7 +1002,7 @@ global {
# The --stripes/-i and --mirrors/-m options can both be specified
# during the creation of a logical volume to use both striping and
# mirroring for the LV. There are two different implementations.
#
#
# Accepted values:
# raid10
# LVM uses MD's RAID10 personality through DM. This is the
@@ -1050,7 +1012,7 @@ global {
# is done by creating a mirror LV on top of striped sub-LVs,
# effectively creating a RAID 0+1 array. The layering is suboptimal
# in terms of providing redundancy and performance.
#
#
raid10_segtype_default = "@DEFAULT_RAID10_SEGTYPE@"
# Configuration option global/sparse_segtype_default.
@@ -1058,7 +1020,7 @@ global {
# The --type snapshot|thin option overrides this setting.
# The combination of -V and -L options creates a sparse LV. There are
# two different implementations.
#
#
# Accepted values:
# snapshot
# The original snapshot implementation from LVM/DM. It uses an old
@@ -1070,7 +1032,7 @@ global {
# bigger minimal chunk size (64KiB) and uses a separate volume for
# metadata. It has better performance, especially when more data
# is used. It also supports full snapshots.
#
#
sparse_segtype_default = "@DEFAULT_SPARSE_SEGTYPE@"
# Configuration option global/lvdisplay_shows_full_device_path.
@@ -1084,15 +1046,12 @@ global {
# Configuration option global/event_activation.
# Activate LVs based on system-generated device events.
# When a PV appears on the system, a system-generated uevent triggers
# the lvm2-pvscan service which runs the pvscan --cache -aay command.
# If the new PV completes a VG, pvscan autoactivates LVs in the VG.
# When event_activation is disabled, the lvm2-activation services are
# generated and run at fixed points during system startup. These
# services run vgchange -aay to autoactivate LVs in VGs that happen
# to be present at that point in time.
# See the --setautoactivation option or the auto_activation_volume_list
# setting to configure autoactivation for specific VGs or LVs.
# When a device appears on the system, a system-generated event runs
# the pvscan command to activate LVs if the new PV completes the VG.
# Use auto_activation_volume_list to select which LVs should be
# activated from these events (the default is all.)
# When event_activation is disabled, the system will generally run
# a direct activation command to activate LVs in complete VGs.
# This configuration option has an automatic default value.
# event_activation = 1
@@ -1125,17 +1084,6 @@ global {
# This configuration option has an automatic default value.
# sanlock_lv_extend = 256
# Configuration option global/lvmlockctl_kill_command.
# The command that lvmlockctl --kill should use to force LVs offline.
# The lvmlockctl --kill command is run when a shared VG has lost
# access to locks (e.g. when sanlock has lost access to storage.)
# An empty string means that there will be no automatic attempt by
# lvmlockctl --kill to forcibly shut down LVs in the VG, and the user
# can manually intervene as described in lvmlockd(8).
# The VG name will be appended to the command specified here.
# This configuration option has an automatic default value.
# lvmlockctl_kill_command = ""
# Configuration option global/thin_check_executable.
# The full path to the thin_check command.
# LVM uses this command to check that a thin metadata device is in a
@@ -1182,20 +1130,20 @@ global {
# causing problems. Features include: block_size, discards,
# discards_non_power_2, external_origin, metadata_resize,
# external_origin_extend, error_if_no_space.
#
#
# Example
# thin_disabled_features = [ "discards", "block_size" ]
#
#
# This configuration option does not have a default value defined.
# Configuration option global/cache_disabled_features.
# Features to not use in the cache driver.
# This can be helpful for testing, or to avoid using a feature that is
# causing problems. Features include: policy_mq, policy_smq, metadata2.
#
#
# Example
# cache_disabled_features = [ "policy_smq" ]
#
#
# This configuration option does not have a default value defined.
# Configuration option global/cache_check_executable.
@@ -1247,16 +1195,6 @@ global {
# This configuration option has an automatic default value.
# vdo_format_options = [ "" ]
# Configuration option global/vdo_disabled_features.
# Features to not use in the vdo driver.
# This can be helpful for testing, or to avoid using a feature that is
# causing problems. Features include: online_rename
#
# Example
# vdo_disabled_features = [ "online_rename" ]
#
# This configuration option does not have a default value defined.
# Configuration option global/fsadm_executable.
# The full path to the fsadm command.
# LVM uses this command to help with lvresize -r operations.
@@ -1269,7 +1207,7 @@ global {
# or vgimport.) A VG on shared storage devices is accessible only to
# the host with a matching system ID. See 'man lvmsystemid' for
# information on limitations and correct usage.
#
#
# Accepted values:
# none
# The host has no system ID.
@@ -1286,7 +1224,7 @@ global {
# file
# Use the contents of another file (system_id_file) to set the
# system ID.
#
#
system_id_source = "none"
# Configuration option global/system_id_file.
@@ -1338,7 +1276,7 @@ activation {
# Configuration option activation/udev_sync.
# Use udev notifications to synchronize udev and LVM.
# The --noudevsync option overrides this setting.
# The --nodevsync option overrides this setting.
# When disabled, LVM commands will not wait for notifications from
# udev, but continue irrespective of any possible udev processing in
# the background. Only use this if udev is not running or has rules
@@ -1412,7 +1350,7 @@ activation {
# If this list is defined, an LV is only activated if it matches an
# entry in this list. If this list is undefined, it imposes no limits
# on LV activation (all are allowed).
#
#
# Accepted values:
# vgname
# The VG name is matched exactly and selects all LVs in the VG.
@@ -1426,30 +1364,30 @@ activation {
# or VG. See tags/hosttags. If any host tags exist but volume_list
# is not defined, a default single-entry list containing '@*'
# is assumed.
#
#
# Example
# volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
#
#
# This configuration option does not have a default value defined.
# Configuration option activation/auto_activation_volume_list.
# A list of VGs or LVs that should be autoactivated.
# Autoactivation is an activation command run with -aay,
# i.e. vgchange -aay, lvchange -aay, or pvscan --cache -aay.
# When this list is defined, an autoactivation command will only
# activate LVs included in the list. If this list is undefined,
# it has no effect. If this list is defined but empty, then no
# LVs will be autoactivated. LVs can be included in the list by
# LV name, VG name (applies to all LVs in the VG), or tag name.
# VGs and LVs can also have an autoactivation property set in
# metadata, see --setautoactivation. LVs included in this list
# will not be autoactivated if the VG or LV autoactivation
# property is disabled (see vgs or lvs "-o autoactivation").
# The volume_list setting and the "activation skip" property
# also apply to autoactivation.
# The -aay option is meant to be used by activation commands that
# are run automatically by the system, e.g. from systemd services.
#
# Only LVs selected by this list are auto-activated.
# This list works like volume_list, but it is used only by
# auto-activation commands. It does not apply to direct activation
# commands. If this list is defined, an LV is only auto-activated
# if it matches an entry in this list. If this list is undefined, it
# imposes no limits on LV auto-activation (all are allowed.) If this
# list is defined and empty, i.e. "[]", then no LVs are selected for
# auto-activation. An LV that is selected by this list for
# auto-activation, must also be selected by volume_list (if defined)
# before it is activated. Auto-activation is an activation command that
# includes the 'a' argument: --activate ay or -a ay. The 'a' (auto)
# argument for auto-activation is meant to be used by activation
# commands that are run automatically by the system, as opposed to LVM
# commands run directly by a user. A user may also use the 'a' flag
# directly to perform auto-activation. Also see pvscan(8) for more
# information about auto-activation.
#
# Accepted values:
# vgname
# The VG name is matched exactly and selects all LVs in the VG.
@@ -1463,10 +1401,10 @@ activation {
# or VG. See tags/hosttags. If any host tags exist but volume_list
# is not defined, a default single-entry list containing '@*'
# is assumed.
#
#
# Example
# auto_activation_volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
#
#
# This configuration option does not have a default value defined.
# Configuration option activation/read_only_volume_list.
@@ -1475,7 +1413,7 @@ activation {
# against this list, and if it matches, it is activated in read-only
# mode. This overrides the permission setting stored in the metadata,
# e.g. from --permission rw.
#
#
# Accepted values:
# vgname
# The VG name is matched exactly and selects all LVs in the VG.
@@ -1489,10 +1427,10 @@ activation {
# or VG. See tags/hosttags. If any host tags exist but volume_list
# is not defined, a default single-entry list containing '@*'
# is assumed.
#
#
# Example
# read_only_volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
#
#
# This configuration option does not have a default value defined.
# Configuration option activation/raid_region_size.
@@ -1515,13 +1453,13 @@ activation {
# Configuration option activation/readahead.
# Setting to use when there is no readahead setting in metadata.
#
#
# Accepted values:
# none
# Disable readahead.
# auto
# Use default value chosen by kernel.
#
#
# This configuration option has an automatic default value.
# readahead = "auto"
@@ -1533,7 +1471,7 @@ activation {
# performed by dmeventd automatically, and the steps perfomed by the
# manual command lvconvert --repair --use-policies.
# Automatic handling requires dmeventd to be monitoring the LV.
#
#
# Accepted values:
# warn
# Use the system log to warn the user that a device in the RAID LV
@@ -1544,7 +1482,7 @@ activation {
# allocate
# Attempt to use any extra physical volumes in the VG as spares and
# replace faulty devices.
#
#
raid_fault_policy = "warn"
# Configuration option activation/mirror_image_fault_policy.
@@ -1556,7 +1494,7 @@ activation {
# determines the steps perfomed by dmeventd automatically, and the steps
# performed by the manual command lvconvert --repair --use-policies.
# Automatic handling requires dmeventd to be monitoring the LV.
#
#
# Accepted values:
# remove
# Simply remove the faulty device and run without it. If the log
@@ -1581,7 +1519,7 @@ activation {
# the redundant nature of the mirror. This policy acts like
# 'remove' if no suitable device and space can be allocated for the
# replacement.
#
#
mirror_image_fault_policy = "remove"
# Configuration option activation/mirror_log_fault_policy.
@@ -1596,26 +1534,26 @@ activation {
# The minimum value is 50 (a smaller value is treated as 50.)
# Also see snapshot_autoextend_percent.
# Automatic extension requires dmeventd to be monitoring the LV.
#
#
# Example
# Using 70% autoextend threshold and 20% autoextend size, when a 1G
# snapshot exceeds 700M, it is extended to 1.2G, and when it exceeds
# 840M, it is extended to 1.44G:
# snapshot_autoextend_threshold = 70
#
#
snapshot_autoextend_threshold = 100
# Configuration option activation/snapshot_autoextend_percent.
# Auto-extending a snapshot adds this percent extra space.
# The amount of additional space added to a snapshot is this
# percent of its current size.
#
#
# Example
# Using 70% autoextend threshold and 20% autoextend size, when a 1G
# snapshot exceeds 700M, it is extended to 1.2G, and when it exceeds
# 840M, it is extended to 1.44G:
# snapshot_autoextend_percent = 20
#
#
snapshot_autoextend_percent = 20
# Configuration option activation/thin_pool_autoextend_threshold.
@@ -1624,26 +1562,26 @@ activation {
# The minimum value is 50 (a smaller value is treated as 50.)
# Also see thin_pool_autoextend_percent.
# Automatic extension requires dmeventd to be monitoring the LV.
#
#
# Example
# Using 70% autoextend threshold and 20% autoextend size, when a 1G
# thin pool exceeds 700M, it is extended to 1.2G, and when it exceeds
# 840M, it is extended to 1.44G:
# thin_pool_autoextend_threshold = 70
#
#
thin_pool_autoextend_threshold = 100
# Configuration option activation/thin_pool_autoextend_percent.
# Auto-extending a thin pool adds this percent extra space.
# The amount of additional space added to a thin pool is this
# percent of its current size.
#
#
# Example
# Using 70% autoextend threshold and 20% autoextend size, when a 1G
# thin pool exceeds 700M, it is extended to 1.2G, and when it exceeds
# 840M, it is extended to 1.44G:
# thin_pool_autoextend_percent = 20
#
#
thin_pool_autoextend_percent = 20
# Configuration option activation/vdo_pool_autoextend_threshold.
@@ -1652,13 +1590,13 @@ activation {
# The minimum value is 50 (a smaller value is treated as 50.)
# Also see vdo_pool_autoextend_percent.
# Automatic extension requires dmeventd to be monitoring the LV.
#
#
# Example
# Using 70% autoextend threshold and 20% autoextend size, when a 10G
# VDO pool exceeds 7G, it is extended to 12G, and when it exceeds
# 8.4G, it is extended to 14.4G:
# vdo_pool_autoextend_threshold = 70
#
#
# This configuration option has an automatic default value.
# vdo_pool_autoextend_threshold = 100
@@ -1666,7 +1604,7 @@ activation {
# Auto-extending a VDO pool adds this percent extra space.
# The amount of additional space added to a VDO pool is this
# percent of its current size.
#
#
# Example
# Using 70% autoextend threshold and 20% autoextend size, when a 10G
# VDO pool exceeds 7G, it is extended to 12G, and when it exceeds
@@ -1685,10 +1623,10 @@ activation {
# pages corresponding to lines that match are not pinned. On some
# systems, locale-archive was found to make up over 80% of the memory
# used by the process.
#
#
# Example
# mlock_filter = [ "locale/locale-archive", "gconv/gconv-modules.cache" ]
#
#
# This configuration option is advanced.
# This configuration option does not have a default value defined.
@@ -1729,7 +1667,7 @@ activation {
# Configuration option activation/activation_mode.
# How LVs with missing devices are activated.
# The --activationmode option overrides this setting.
#
#
# Accepted values:
# complete
# Only allow activation of an LV if all of the Physical Volumes it
@@ -1744,7 +1682,7 @@ activation {
# could cause data loss with a portion of the LV inaccessible.
# This setting should not normally be used, but may sometimes
# assist with data recovery.
#
#
activation_mode = "degraded"
# Configuration option activation/lock_start_list.
@@ -1792,7 +1730,7 @@ activation {
# Configuration option metadata/pvmetadatacopies.
# Number of copies of metadata to store on each PV.
# The --pvmetadatacopies option overrides this setting.
#
#
# Accepted values:
# 2
# Two copies of the VG metadata are stored on the PV, one at the
@@ -1802,7 +1740,7 @@ activation {
# 0
# No copies of VG metadata are stored on the PV. This may be
# useful for VGs containing large numbers of PVs.
#
#
# This configuration option is advanced.
# This configuration option has an automatic default value.
# pvmetadatacopies = 1
@@ -1952,7 +1890,7 @@ activation {
# sequences are copied verbatim. Each special character sequence is
# introduced by the '%' character and such sequence is then
# substituted with a value as described below.
#
#
# Accepted values:
# %a
# The abbreviated name of the day of the week according to the
@@ -2075,7 +2013,7 @@ activation {
# The timezone name or abbreviation.
# %%
# A literal '%' character.
#
#
# This configuration option has an automatic default value.
# time_format = "%Y-%m-%d %T %z"
@@ -2344,12 +2282,12 @@ dmeventd {
# applied to the local machine as a 'host tag'. If this subsection is
# empty (has no host_list), then the subsection name is always applied
# as a 'host tag'.
#
#
# Example
# The host tag foo is given to all hosts, and the host tag
# bar is given to the hosts named machine1 and machine2.
# tags { foo { } bar { host_list = [ "machine1", "machine2" ] } }
#
#
# This configuration section has variable name.
# This configuration section has an automatic default value.
# tag {

View File

@@ -28,13 +28,13 @@ local {
# main configuration file, e.g. lvm.conf. When used, it must be set to
# a unique value among all hosts sharing access to the storage,
# e.g. a host name.
#
#
# Example
# Set no system ID:
# system_id = ""
# Set the system_id to a specific name:
# system_id = "host1"
#
#
# This configuration option has an automatic default value.
# system_id = ""

306
configure vendored
View File

@@ -640,7 +640,6 @@ LVMLOCKD_PIDFILE
LVMPOLLD_PIDFILE
DMEVENTD_PIDFILE
WRITE_INSTALL
WRITECACHE
VDO_LIB
VDO_INCLUDE
VDO
@@ -703,7 +702,6 @@ LIB_SUFFIX
LDDEPS
JOBS
INTL
INTEGRITY
HAVE_VALGRIND
HAVE_REALTIME
HAVE_LIBDL
@@ -747,7 +745,6 @@ BUILD_DMFILEMAPD
BUILD_LOCKDDLM_CONTROL
BUILD_LOCKDDLM
BUILD_LOCKDSANLOCK
BUILD_LOCKDIDM
BUILD_LVMLOCKD
BUILD_LVMPOLLD
BUILD_LVMDBUSD
@@ -783,8 +780,6 @@ LOCKD_DLM_LIBS
LOCKD_DLM_CFLAGS
LOCKD_SANLOCK_LIBS
LOCKD_SANLOCK_CFLAGS
LOCKD_IDM_LIBS
LOCKD_IDM_CFLAGS
VALGRIND_LIBS
VALGRIND_CFLAGS
GENPNG
@@ -800,8 +795,6 @@ PKGCONFIGINIT_CFLAGS
PKG_CONFIG_LIBDIR
PKG_CONFIG_PATH
PKG_CONFIG
AIO_LIBS
AIO_CFLAGS
VDO_FORMAT_CMD
CACHE_RESTORE_CMD
CACHE_REPAIR_CMD
@@ -875,7 +868,6 @@ infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
@@ -941,7 +933,6 @@ enable_cmirrord
with_cmirrord_pidfile
enable_debug
with_optimisation
with_symvers
enable_profiling
enable_valgrind_pool
enable_devmapper
@@ -949,7 +940,6 @@ enable_lvmpolld
enable_lvmlockd_sanlock
enable_lvmlockd_dlm
enable_lvmlockd_dlmcontrol
enable_lvmlockd_idm
enable_use_lvmlockd
with_lvmlockd_pidfile
enable_use_lvmpolld
@@ -1006,8 +996,6 @@ CXX
CXXFLAGS
CCC
CPP
AIO_CFLAGS
AIO_LIBS
PKG_CONFIG
PKG_CONFIG_PATH
PKG_CONFIG_LIBDIR
@@ -1023,8 +1011,6 @@ LOCKD_DLM_CFLAGS
LOCKD_DLM_LIBS
LOCKD_DLM_CONTROL_CFLAGS
LOCKD_DLM_CONTROL_LIBS
LOCKD_IDM_CFLAGS
LOCKD_IDM_LIBS
NOTIFY_DBUS_CFLAGS
NOTIFY_DBUS_LIBS
BLKID_CFLAGS
@@ -1074,7 +1060,6 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE}'
@@ -1327,15 +1312,6 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-runstatedir | --runstatedir | --runstatedi | --runstated \
| --runstate | --runstat | --runsta | --runst | --runs \
| --run | --ru | --r)
ac_prev=runstatedir ;;
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
| --run=* | --ru=* | --r=*)
runstatedir=$ac_optarg ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1473,7 +1449,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir runstatedir
libdir localedir mandir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@@ -1626,7 +1602,6 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@@ -1684,7 +1659,6 @@ Optional Features:
--enable-lvmlockd-dlm enable the LVM lock daemon using dlm
--enable-lvmlockd-dlmcontrol
enable lvmlockd remote refresh using libdlmcontrol
--enable-lvmlockd-idm enable the LVM lock daemon using idm
--disable-use-lvmlockd disable usage of LVM lock daemon
--disable-use-lvmpolld disable usage of LVM Poll Daemon
--enable-dmfilemapd enable the dmstats filemap daemon
@@ -1726,21 +1700,22 @@ Optional Packages:
create nodes on resume or create [ON=resume]
--with-default-name-mangling=MANGLING
default name mangling: auto/none/hex [auto]
--with-snapshots=TYPE snapshot support: internal/none [internal]
--with-mirrors=TYPE mirror support: internal/none [internal]
--with-snapshots=TYPE snapshot support: internal/shared/none [internal]
--with-mirrors=TYPE mirror support: internal/shared/none [internal]
--with-default-mirror-segtype=TYPE
default mirror segtype: raid1/mirror [raid1]
--with-default-raid10-segtype=TYPE
default mirror segtype: raid10/mirror [raid10]
--with-default-sparse-segtype=TYPE
default sparse segtype: thin/snapshot [thin]
--with-thin=TYPE thin provisioning support: internal/none [internal]
--with-thin=TYPE thin provisioning support: internal/shared/none
[internal]
--with-thin-check=PATH thin_check tool: [autodetect]
--with-thin-dump=PATH thin_dump tool: [autodetect]
--with-thin-repair=PATH thin_repair tool: [autodetect]
--with-thin-restore=PATH
thin_restore tool: [autodetect]
--with-cache=TYPE cache support: internal/none [internal]
--with-cache=TYPE cache support: internal/shared/none [internal]
--with-cache-check=PATH cache_check tool: [autodetect]
--with-cache-dump=PATH cache_dump tool: [autodetect]
--with-cache-repair=PATH
@@ -1762,8 +1737,6 @@ Optional Packages:
--with-cmirrord-pidfile=PATH
cmirrord pidfile [PID_DIR/cmirrord.pid]
--with-optimisation=OPT C optimisation flag [OPT=-O2]
--with-symvers=STYLE use symbol versioning of the shared library
[default=gnu]
--with-lvmlockd-pidfile=PATH
lvmlockd pidfile [PID_DIR/lvmlockd.pid]
--with-lvmpolld-pidfile=PATH
@@ -1810,8 +1783,6 @@ Some influential environment variables:
CXX C++ compiler command
CXXFLAGS C++ compiler flags
CPP C preprocessor
AIO_CFLAGS C compiler flags for AIO
AIO_LIBS linker flags for AIO
PKG_CONFIG path to pkg-config utility
PKG_CONFIG_PATH
directories to add to pkg-config's search path
@@ -1839,10 +1810,6 @@ Some influential environment variables:
C compiler flags for LOCKD_DLM_CONTROL, overriding pkg-config
LOCKD_DLM_CONTROL_LIBS
linker flags for LOCKD_DLM_CONTROL, overriding pkg-config
LOCKD_IDM_CFLAGS
C compiler flags for LOCKD_IDM, overriding pkg-config
LOCKD_IDM_LIBS
linker flags for LOCKD_IDM, overriding pkg-config
NOTIFY_DBUS_CFLAGS
C compiler flags for NOTIFY_DBUS, overriding pkg-config
NOTIFY_DBUS_LIBS
@@ -3124,18 +3091,19 @@ if test -z "$CFLAGS"; then :
fi
case "$host_os" in
linux*)
CLDFLAGS="${CLDFLAGS-"$LDFLAGS"} -Wl,--version-script,.export.sym"
# equivalent to -rdynamic
ELDFLAGS="-Wl,--export-dynamic"
# FIXME Generate list and use --dynamic-list=.dlopen.sym
CLDWHOLEARCHIVE="-Wl,-whole-archive"
CLDNOWHOLEARCHIVE="-Wl,-no-whole-archive"
LDDEPS="$LDDEPS .export.sym"
LIB_SUFFIX=so
DEVMAPPER=yes
BUILD_LVMPOLLD=no
LOCKDSANLOCK=no
LOCKDDLM=no
LOCKDDLM_CONTROL=no
LOCKDIDM=no
ODIRECT=yes
DM_IOCTLS=yes
SELINUX=yes
@@ -3144,6 +3112,7 @@ case "$host_os" in
;;
darwin*)
CFLAGS="$CFLAGS -no-cpp-precomp -fno-common"
CLDFLAGS="${CLDFLAGS-"$LDFLAGS"}"
ELDFLAGS=
CLDWHOLEARCHIVE="-all_load"
CLDNOWHOLEARCHIVE=
@@ -6108,7 +6077,7 @@ fi
for ac_header in assert.h ctype.h dirent.h errno.h fcntl.h float.h \
getopt.h inttypes.h langinfo.h libgen.h limits.h locale.h paths.h \
getopt.h inttypes.h langinfo.h libaio.h libgen.h limits.h locale.h paths.h \
signal.h stdarg.h stddef.h stdio.h stdlib.h string.h sys/file.h \
sys/ioctl.h syslog.h sys/mman.h sys/param.h sys/resource.h sys/stat.h \
sys/time.h sys/types.h sys/utsname.h sys/wait.h time.h \
@@ -6141,19 +6110,6 @@ fi
done
for ac_header in libaio.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "libaio.h" "ac_cv_header_libaio_h" "$ac_includes_default"
if test "x$ac_cv_header_libaio_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBAIO_H 1
_ACEOF
LVM_NEEDS_LIBAIO_WARN=
else
LVM_NEEDS_LIBAIO_WARN=y
fi
done
case "$host_os" in
linux*)
@@ -8417,7 +8373,7 @@ fi
case "$MANGLING" in
auto) mangling=DM_STRING_MANGLING_AUTO;;
no|none|disabled) mangling=DM_STRING_MANGLING_NONE;;
none|disabled) mangling=DM_STRING_MANGLING_NONE;;
hex) mangling=DM_STRING_MANGLING_HEX;;
*) as_fn_error $? "--with-default-name-mangling parameter invalid" "$LINENO" 5;;
esac
@@ -8444,7 +8400,7 @@ fi
$as_echo "$SNAPSHOTS" >&6; }
case "$SNAPSHOTS" in
no|none|shared) ;;
none|shared) ;;
internal)
$as_echo "#define SNAPSHOT_INTERNAL 1" >>confdefs.h
;;
@@ -8466,7 +8422,7 @@ fi
$as_echo "$MIRRORS" >&6; }
case "$MIRRORS" in
no|none|shared) ;;
none|shared) ;;
internal)
$as_echo "#define MIRRORED_INTERNAL 1" >>confdefs.h
;;
@@ -8511,10 +8467,7 @@ _ACEOF
# Check whether --with-default-sparse-segtype was given.
if test "${with_default_sparse_segtype+set}" = set; then :
withval=$with_default_sparse_segtype; case "$withval" in
thin|snapshot) DEFAULT_SPARSE_SEGTYPE=$withval ;;
*) as_fn_error $? "--with-default-sparse-segtype parameter invalid" "$LINENO" 5 ;;
esac
withval=$with_default_sparse_segtype; DEFAULT_SPARSE_SEGTYPE=$withval
else
DEFAULT_SPARSE_SEGTYPE="thin"
fi
@@ -8568,7 +8521,7 @@ fi
$as_echo "$THIN" >&6; }
case "$THIN" in
no|none) test "$DEFAULT_SPARSE_SEGTYPE" = "thin" && DEFAULT_SPARSE_SEGTYPE="snapshot" ;;
none) test "$DEFAULT_SPARSE_SEGTYPE" = "thin" && DEFAULT_SPARSE_SEGTYPE="snapshot" ;;
shared) ;;
internal)
$as_echo "#define THIN_INTERNAL 1" >>confdefs.h
@@ -9049,6 +9002,7 @@ $as_echo "$THIN_CHECK_NEEDS_CHECK" >&6; }
$as_echo "#define THIN_CHECK_NEEDS_CHECK 1" >>confdefs.h
fi
;;
esac
@@ -9123,7 +9077,7 @@ fi
$as_echo "$CACHE" >&6; }
case "$CACHE" in
no|none|shared) ;;
none|shared) ;;
internal)
$as_echo "#define CACHE_INTERNAL 1" >>confdefs.h
;;
@@ -9660,7 +9614,7 @@ else
fi
case "$VDO" in
no|none) ;;
none) ;;
internal)
$as_echo "#define VDO_INTERNAL 1" >>confdefs.h
@@ -9812,7 +9766,7 @@ fi
$as_echo "$WRITECACHE" >&6; }
case "$WRITECACHE" in
no|none) ;;
none) ;;
internal)
$as_echo "#define WRITECACHE_INTERNAL 1" >>confdefs.h
@@ -9837,7 +9791,7 @@ fi
$as_echo "$INTEGRITY" >&6; }
case "$INTEGRITY" in
no|none) ;;
none) ;;
internal)
$as_echo "#define INTEGRITY_INTERNAL 1" >>confdefs.h
@@ -9846,14 +9800,6 @@ $as_echo "#define INTEGRITY_INTERNAL 1" >>confdefs.h
*) as_fn_error $? "--with-integrity parameter invalid" "$LINENO" 5 ;;
esac
################################################################################
# Allow users to override default location for libaio
# there seems to be no pkg-config support available
AIO_CFLAGS=
AIO_LIBS=${AIO_LIBS:--laio}
################################################################################
# Check whether --enable-readline was given.
if test "${enable_readline+set}" = set; then :
@@ -10435,35 +10381,6 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $COPTIMISE_FLAG" >&5
$as_echo "$COPTIMISE_FLAG" >&6; }
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use symbol versioning" >&5
$as_echo_n "checking whether to use symbol versioning... " >&6; }
# Check whether --with-symvers was given.
if test "${with_symvers+set}" = set; then :
withval=$with_symvers; case "$withval" in
gnu|no) symvers=$withval ;;
*) as_fn_error $? "--with-symvers parameter invalid" "$LINENO" 5 ;;
esac
else
symvers=gnu
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $symvers" >&5
$as_echo "$symvers" >&6; }
if test "$GCC" = "yes" && test "$symvers" = "gnu" ; then
$as_echo "#define GNU_SYMVER 1" >>confdefs.h
case "$host_os" in
linux*)
CLDFLAGS="${CLDFLAGS-"$LDFLAGS"} -Wl,--version-script,.export.sym"
LDDEPS="$LDDEPS .export.sym"
;;
esac
fi
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to gather gcov profiling data" >&5
$as_echo_n "checking whether to gather gcov profiling data... " >&6; }
@@ -10800,6 +10717,7 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable valgrind awareness of pools" >&5
$as_echo_n "checking whether to enable valgrind awareness of pools... " >&6; }
@@ -11203,167 +11121,6 @@ $as_echo "#define LOCKDDLM_CONTROL_SUPPORT 1" >>confdefs.h
BUILD_LVMLOCKD=yes
fi
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build lvmlockdidm" >&5
$as_echo_n "checking whether to build lvmlockdidm... " >&6; }
# Check whether --enable-lvmlockd-idm was given.
if test "${enable_lvmlockd_idm+set}" = set; then :
enableval=$enable_lvmlockd_idm; LOCKDIDM=$enableval
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LOCKDIDM" >&5
$as_echo "$LOCKDIDM" >&6; }
BUILD_LOCKDIDM=$LOCKDIDM
if test "$BUILD_LOCKDIDM" = yes; then
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LOCKD_IDM" >&5
$as_echo_n "checking for LOCKD_IDM... " >&6; }
if test -n "$LOCKD_IDM_CFLAGS"; then
pkg_cv_LOCKD_IDM_CFLAGS="$LOCKD_IDM_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libseagate_ilm >= 0.1.0\""; } >&5
($PKG_CONFIG --exists --print-errors "libseagate_ilm >= 0.1.0") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_LOCKD_IDM_CFLAGS=`$PKG_CONFIG --cflags "libseagate_ilm >= 0.1.0" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test -n "$LOCKD_IDM_LIBS"; then
pkg_cv_LOCKD_IDM_LIBS="$LOCKD_IDM_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libseagate_ilm >= 0.1.0\""; } >&5
($PKG_CONFIG --exists --print-errors "libseagate_ilm >= 0.1.0") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_LOCKD_IDM_LIBS=`$PKG_CONFIG --libs "libseagate_ilm >= 0.1.0" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test $pkg_failed = yes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
LOCKD_IDM_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libseagate_ilm >= 0.1.0" 2>&1`
else
LOCKD_IDM_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libseagate_ilm >= 0.1.0" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$LOCKD_IDM_PKG_ERRORS" >&5
$bailout
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
$bailout
else
LOCKD_IDM_CFLAGS=$pkg_cv_LOCKD_IDM_CFLAGS
LOCKD_IDM_LIBS=$pkg_cv_LOCKD_IDM_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
fi
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BLKID" >&5
$as_echo_n "checking for BLKID... " >&6; }
if test -n "$BLKID_CFLAGS"; then
pkg_cv_BLKID_CFLAGS="$BLKID_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"blkid >= 2.24\""; } >&5
($PKG_CONFIG --exists --print-errors "blkid >= 2.24") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_BLKID_CFLAGS=`$PKG_CONFIG --cflags "blkid >= 2.24" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test -n "$BLKID_LIBS"; then
pkg_cv_BLKID_LIBS="$BLKID_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"blkid >= 2.24\""; } >&5
($PKG_CONFIG --exists --print-errors "blkid >= 2.24") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_BLKID_LIBS=`$PKG_CONFIG --libs "blkid >= 2.24" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test $pkg_failed = yes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
BLKID_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "blkid >= 2.24" 2>&1`
else
BLKID_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "blkid >= 2.24" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$BLKID_PKG_ERRORS" >&5
$bailout
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
$bailout
else
BLKID_CFLAGS=$pkg_cv_BLKID_CFLAGS
BLKID_LIBS=$pkg_cv_BLKID_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
HAVE_LOCKD_IDM=yes
fi
$as_echo "#define LOCKDIDM_SUPPORT 1" >>confdefs.h
BUILD_LVMLOCKD=yes
fi
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build lvmlockd" >&5
$as_echo_n "checking whether to build lvmlockd... " >&6; }
@@ -12205,7 +11962,7 @@ $as_echo_n "checking for $am_display_PYTHON version... " >&6; }
if ${am_cv_python_version+:} false; then :
$as_echo_n "(cached) " >&6
else
am_cv_python_version=`$PYTHON -c "import sys; print('%u.%u' % sys.version_info[:2])"`
am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"`
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5
$as_echo "$am_cv_python_version" >&6; }
@@ -13189,12 +12946,12 @@ fi
# Put the nasty error message in config.log where it belongs
echo "$EDITLINE_PKG_ERRORS" >&5
as_fn_error $? "libedit could not be found which is required for the --enable-editline option." "$LINENO" 5
as_fn_error $? "libedit could not be found which is required for the --enable-readline option." "$LINENO" 5
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
as_fn_error $? "libedit could not be found which is required for the --enable-editline option." "$LINENO" 5
as_fn_error $? "libedit could not be found which is required for the --enable-readline option." "$LINENO" 5
else
EDITLINE_CFLAGS=$pkg_cv_EDITLINE_CFLAGS
@@ -13647,12 +13404,13 @@ $as_echo_n "checking whether to enable readline... " >&6; }
$as_echo "$READLINE" >&6; }
if test "$EDITLINE" = yes; then
for ac_header in editline/readline.h
for ac_header in editline/readline.h editline/history.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "editline/readline.h" "ac_cv_header_editline_readline_h" "$ac_includes_default"
if test "x$ac_cv_header_editline_readline_h" = xyes; then :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_EDITLINE_READLINE_H 1
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
else
@@ -14348,8 +14106,6 @@ _ACEOF
@@ -15727,10 +15483,6 @@ if test -n "$VDO_CONFIGURE_WARN"; then :
$as_echo "$as_me: WARNING: Unrecognized 'vdoformat' tool is REQUIRED for VDO logical volume creation!" >&2;}
fi
if test -n "$LVM_NEEDS_LIBAIO_WARN"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Only libdm part can be build without libaio: make [install_]device-mapper" >&5
$as_echo "$as_me: WARNING: Only libdm part can be build without libaio: make [install_]device-mapper" >&2;}
fi
if test "$ODIRECT" != yes; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: O_DIRECT disabled: low-memory pvmove may lock up" >&5

View File

@@ -30,18 +30,19 @@ AC_CANONICAL_TARGET([])
AS_IF([test -z "$CFLAGS"], [COPTIMISE_FLAG="-O2"])
case "$host_os" in
linux*)
CLDFLAGS="${CLDFLAGS-"$LDFLAGS"} -Wl,--version-script,.export.sym"
# equivalent to -rdynamic
ELDFLAGS="-Wl,--export-dynamic"
# FIXME Generate list and use --dynamic-list=.dlopen.sym
CLDWHOLEARCHIVE="-Wl,-whole-archive"
CLDNOWHOLEARCHIVE="-Wl,-no-whole-archive"
LDDEPS="$LDDEPS .export.sym"
LIB_SUFFIX=so
DEVMAPPER=yes
BUILD_LVMPOLLD=no
LOCKDSANLOCK=no
LOCKDDLM=no
LOCKDDLM_CONTROL=no
LOCKDIDM=no
ODIRECT=yes
DM_IOCTLS=yes
SELINUX=yes
@@ -50,6 +51,7 @@ case "$host_os" in
;;
darwin*)
CFLAGS="$CFLAGS -no-cpp-precomp -fno-common"
CLDFLAGS="${CLDFLAGS-"$LDFLAGS"}"
ELDFLAGS=
CLDWHOLEARCHIVE="-all_load"
CLDNOWHOLEARCHIVE=
@@ -102,14 +104,14 @@ AC_HEADER_SYS_WAIT
AC_HEADER_TIME
AC_CHECK_HEADERS([assert.h ctype.h dirent.h errno.h fcntl.h float.h \
getopt.h inttypes.h langinfo.h libgen.h limits.h locale.h paths.h \
getopt.h inttypes.h langinfo.h libaio.h libgen.h limits.h locale.h paths.h \
signal.h stdarg.h stddef.h stdio.h stdlib.h string.h sys/file.h \
sys/ioctl.h syslog.h sys/mman.h sys/param.h sys/resource.h sys/stat.h \
sys/time.h sys/types.h sys/utsname.h sys/wait.h time.h \
unistd.h], , [AC_MSG_ERROR(bailing out)])
AC_CHECK_HEADERS(termios.h sys/statvfs.h sys/timerfd.h sys/vfs.h linux/magic.h linux/fiemap.h)
AC_CHECK_HEADERS(libaio.h,LVM_NEEDS_LIBAIO_WARN=,LVM_NEEDS_LIBAIO_WARN=y)
case "$host_os" in
linux*)
AC_CHECK_HEADERS(asm/byteorder.h linux/fs.h malloc.h,,AC_MSG_ERROR(bailing out)) ;;
@@ -290,7 +292,7 @@ AC_ARG_WITH(default-name-mangling,
MANGLING=$withval, MANGLING=auto)
case "$MANGLING" in
auto) mangling=DM_STRING_MANGLING_AUTO;;
no|none|disabled) mangling=DM_STRING_MANGLING_NONE;;
none|disabled) mangling=DM_STRING_MANGLING_NONE;;
hex) mangling=DM_STRING_MANGLING_HEX;;
*) AC_MSG_ERROR([--with-default-name-mangling parameter invalid]);;
esac
@@ -302,12 +304,12 @@ dnl -- snapshots inclusion type
AC_MSG_CHECKING(whether to include snapshots)
AC_ARG_WITH(snapshots,
AC_HELP_STRING([--with-snapshots=TYPE],
[snapshot support: internal/none [internal]]),
[snapshot support: internal/shared/none [internal]]),
SNAPSHOTS=$withval, SNAPSHOTS=internal)
AC_MSG_RESULT($SNAPSHOTS)
case "$SNAPSHOTS" in
no|none|shared) ;;
none|shared) ;;
internal) AC_DEFINE([SNAPSHOT_INTERNAL], 1,
[Define to 1 to include built-in support for snapshots.]) ;;
*) AC_MSG_ERROR([--with-snapshots parameter invalid]) ;;
@@ -318,12 +320,12 @@ dnl -- mirrors inclusion type
AC_MSG_CHECKING(whether to include mirrors)
AC_ARG_WITH(mirrors,
AC_HELP_STRING([--with-mirrors=TYPE],
[mirror support: internal/none [internal]]),
[mirror support: internal/shared/none [internal]]),
MIRRORS=$withval, MIRRORS=internal)
AC_MSG_RESULT($MIRRORS)
case "$MIRRORS" in
no|none|shared) ;;
none|shared) ;;
internal) AC_DEFINE([MIRRORED_INTERNAL], 1,
[Define to 1 to include built-in support for mirrors.]) ;;
*) AC_MSG_ERROR([--with-mirrors parameter invalid]) ;;
@@ -353,17 +355,14 @@ AC_DEFINE_UNQUOTED([DEFAULT_RAID10_SEGTYPE], ["$DEFAULT_RAID10_SEGTYPE"],
AC_ARG_WITH(default-sparse-segtype,
AC_HELP_STRING([--with-default-sparse-segtype=TYPE],
[default sparse segtype: thin/snapshot [thin]]),
[ case "$withval" in
thin|snapshot) DEFAULT_SPARSE_SEGTYPE=$withval ;;
*) AC_MSG_ERROR(--with-default-sparse-segtype parameter invalid) ;;
esac], DEFAULT_SPARSE_SEGTYPE="thin")
DEFAULT_SPARSE_SEGTYPE=$withval, DEFAULT_SPARSE_SEGTYPE="thin")
################################################################################
dnl -- thin provisioning
AC_MSG_CHECKING(whether to include thin provisioning)
AC_ARG_WITH(thin,
AC_HELP_STRING([--with-thin=TYPE],
[thin provisioning support: internal/none [internal]]),
[thin provisioning support: internal/shared/none [internal]]),
THIN=$withval, THIN=internal)
AC_ARG_WITH(thin-check,
AC_HELP_STRING([--with-thin-check=PATH],
@@ -385,7 +384,7 @@ AC_ARG_WITH(thin-restore,
AC_MSG_RESULT($THIN)
case "$THIN" in
no|none) test "$DEFAULT_SPARSE_SEGTYPE" = "thin" && DEFAULT_SPARSE_SEGTYPE="snapshot" ;;
none) test "$DEFAULT_SPARSE_SEGTYPE" = "thin" && DEFAULT_SPARSE_SEGTYPE="snapshot" ;;
shared) ;;
internal) AC_DEFINE([THIN_INTERNAL], 1,
[Define to 1 to include built-in support for thin provisioning.]) ;;
@@ -462,6 +461,7 @@ case "$THIN" in
if test "$THIN_CHECK_NEEDS_CHECK" = yes; then
AC_DEFINE([THIN_CHECK_NEEDS_CHECK], 1, [Define to 1 if the external 'thin_check' tool requires the --clear-needs-check-flag option])
fi
;;
esac
@@ -482,7 +482,7 @@ dnl -- cache inclusion type
AC_MSG_CHECKING(whether to include cache)
AC_ARG_WITH(cache,
AC_HELP_STRING([--with-cache=TYPE],
[cache support: internal/none [internal]]),
[cache support: internal/shared/none [internal]]),
CACHE=$withval, CACHE="internal")
AC_ARG_WITH(cache-check,
AC_HELP_STRING([--with-cache-check=PATH],
@@ -503,7 +503,7 @@ AC_ARG_WITH(cache-restore,
AC_MSG_RESULT($CACHE)
case "$CACHE" in
no|none|shared) ;;
none|shared) ;;
internal) AC_DEFINE([CACHE_INTERNAL], 1, [Define to 1 to include built-in support for cache.]) ;;
*) AC_MSG_ERROR([--with-cache parameter invalid]) ;;
esac
@@ -616,8 +616,8 @@ AC_ARG_WITH(vdo-format,
[vdoformat tool: [autodetect]]),
VDO_FORMAT_CMD=$withval, VDO_FORMAT_CMD="autodetect")
case "$VDO" in
no|none) ;;
internal)
none) ;;
internal)
AC_DEFINE([VDO_INTERNAL], 1, [Define to 1 to include built-in support for vdo.])
if test "$VDO_FORMAT_CMD" = "autodetect"; then
AC_PATH_TOOL(VDO_FORMAT_CMD, vdoformat, [], [$PATH])
@@ -646,7 +646,7 @@ AC_DEFINE_UNQUOTED([VDO_FORMAT_CMD], ["$VDO_FORMAT_CMD"],
#AC_ARG_WITH(vdo-lib,
# AC_HELP_STRING([--with-vdo-lib=PATH],
# [vdo support: Path to utils lib: [/usr/lib]]),
# VDO_LIB=$withval, VDO_LIB="/usr/lib")
# VDO_LIB=$withval, VDO_LIB="/usr/lib")
#AC_MSG_RESULT($VDO_LIB)
################################################################################
@@ -660,8 +660,8 @@ AC_ARG_WITH(writecache,
AC_MSG_RESULT($WRITECACHE)
case "$WRITECACHE" in
no|none) ;;
internal)
none) ;;
internal)
AC_DEFINE([WRITECACHE_INTERNAL], 1, [Define to 1 to include built-in support for writecache.])
;;
*) AC_MSG_ERROR([--with-writecache parameter invalid]) ;;
@@ -678,21 +678,13 @@ AC_ARG_WITH(integrity,
AC_MSG_RESULT($INTEGRITY)
case "$INTEGRITY" in
no|none) ;;
none) ;;
internal)
AC_DEFINE([INTEGRITY_INTERNAL], 1, [Define to 1 to include built-in support for integrity.])
;;
*) AC_MSG_ERROR([--with-integrity parameter invalid]) ;;
esac
################################################################################
# Allow users to override default location for libaio
# there seems to be no pkg-config support available
AIO_CFLAGS=
AIO_LIBS=${AIO_LIBS:--laio}
AC_ARG_VAR([AIO_CFLAGS], [C compiler flags for AIO])
AC_ARG_VAR([AIO_LIBS], [linker flags for AIO])
################################################################################
dnl -- Disable readline
AC_ARG_ENABLE([readline],
@@ -833,29 +825,6 @@ AC_ARG_WITH(optimisation,
COPTIMISE_FLAG=$withval)
AC_MSG_RESULT($COPTIMISE_FLAG)
################################################################################
dnl -- Symbol versioning
AC_MSG_CHECKING(whether to use symbol versioning)
AC_ARG_WITH(symvers,
AC_HELP_STRING([--with-symvers=STYLE],
[use symbol versioning of the shared library [default=gnu]]),
[ case "$withval" in
gnu|no) symvers=$withval ;;
*) AC_MSG_ERROR(--with-symvers parameter invalid) ;;
esac], symvers=gnu)
AC_MSG_RESULT($symvers)
if test "$GCC" = "yes" && test "$symvers" = "gnu" ; then
AC_DEFINE(GNU_SYMVER, 1,
[Define to use GNU versioning in the shared library.])
case "$host_os" in
linux*)
CLDFLAGS="${CLDFLAGS-"$LDFLAGS"} -Wl,--version-script,.export.sym"
LDDEPS="$LDDEPS .export.sym"
;;
esac
fi
################################################################################
dnl -- Enable profiling
AC_MSG_CHECKING(whether to gather gcov profiling data)
@@ -890,6 +859,7 @@ TESTSUITE_DATA='${datarootdir}/lvm2-testsuite'
# double eval needed ${datarootdir} -> ${prefix}/share -> real path
AC_DEFINE_UNQUOTED(TESTSUITE_DATA, ["$(eval echo $(eval echo $TESTSUITE_DATA))"], [Path to testsuite data])
################################################################################
dnl -- Enable valgrind awareness of memory pools
AC_MSG_CHECKING(whether to enable valgrind awareness of pools)
@@ -990,25 +960,6 @@ if test "$BUILD_LOCKDDLM_CONTROL" = yes; then
BUILD_LVMLOCKD=yes
fi
################################################################################
dnl -- Build lvmlockdidm
AC_MSG_CHECKING(whether to build lvmlockdidm)
AC_ARG_ENABLE(lvmlockd-idm,
AC_HELP_STRING([--enable-lvmlockd-idm],
[enable the LVM lock daemon using idm]),
LOCKDIDM=$enableval)
AC_MSG_RESULT($LOCKDIDM)
BUILD_LOCKDIDM=$LOCKDIDM
dnl -- Look for Seagate IDM libraries
if test "$BUILD_LOCKDIDM" = yes; then
PKG_CHECK_MODULES(LOCKD_IDM, libseagate_ilm >= 0.1.0, [HAVE_LOCKD_IDM=yes], $bailout)
PKG_CHECK_MODULES(BLKID, blkid >= 2.24, [HAVE_LOCKD_IDM=yes], $bailout)
AC_DEFINE([LOCKDIDM_SUPPORT], 1, [Define to 1 to include code that uses lvmlockd IDM option.])
BUILD_LVMLOCKD=yes
fi
################################################################################
dnl -- Build lvmlockd
AC_MSG_CHECKING(whether to build lvmlockd)
@@ -1469,7 +1420,7 @@ if test "$EDITLINE" == yes; then
PKG_CHECK_MODULES([EDITLINE], [libedit], [
AC_DEFINE([EDITLINE_SUPPORT], 1,
[Define to 1 to include the LVM editline shell.])], AC_MSG_ERROR(
[libedit could not be found which is required for the --enable-editline option.])
[libedit could not be found which is required for the --enable-readline option.])
)
fi
@@ -1606,7 +1557,7 @@ AC_MSG_CHECKING(whether to enable readline)
AC_MSG_RESULT($READLINE)
if test "$EDITLINE" = yes; then
AC_CHECK_HEADERS(editline/readline.h,,hard_bailout)
AC_CHECK_HEADERS(editline/readline.h editline/history.h,,hard_bailout)
fi
AC_MSG_CHECKING(whether to enable editline)
AC_MSG_RESULT($EDITLINE)
@@ -1828,7 +1779,6 @@ AC_SUBST(BLKDEACTIVATE)
AC_SUBST(HAVE_LIBDL)
AC_SUBST(HAVE_REALTIME)
AC_SUBST(HAVE_VALGRIND)
AC_SUBST(INTEGRITY)
AC_SUBST(INTL)
AC_SUBST(JOBS)
AC_SUBST(LDDEPS)
@@ -1905,7 +1855,6 @@ AC_SUBST(VDO)
AC_SUBST(VDO_FORMAT_CMD)
AC_SUBST(VDO_INCLUDE)
AC_SUBST(VDO_LIB)
AC_SUBST(WRITECACHE)
AC_SUBST(WRITE_INSTALL)
AC_SUBST(DMEVENTD_PIDFILE)
AC_SUBST(LVMPOLLD_PIDFILE)
@@ -2006,8 +1955,6 @@ AS_IF([test -n "$CACHE_CHECK_VERSION_WARN"],
AS_IF([test -n "$VDO_CONFIGURE_WARN"],
[AC_MSG_WARN([Unrecognized 'vdoformat' tool is REQUIRED for VDO logical volume creation!])])
AS_IF([test -n "$LVM_NEEDS_LIBAIO_WARN"],
[AC_MSG_WARN([Only libdm part can be build without libaio: make [[install_]]device-mapper])])
AS_IF([test "$ODIRECT" != yes],
[AC_MSG_WARN([O_DIRECT disabled: low-memory pvmove may lock up])])

View File

@@ -22,9 +22,6 @@ SOURCES = clogd.c cluster.c compat.c functions.c link_mon.c local.c logging.c
TARGETS = cmirrord
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
CFLOW_TARGET := $(TARGETS)
include $(top_builddir)/make.tmpl
LMLIBS += $(CPG_LIBS)
@@ -36,8 +33,6 @@ cmirrord: $(OBJECTS)
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) \
$(LMLIBS) -L$(top_builddir)/libdm -ldevmapper $(LIBS)
install_cluster: $(TARGETS)
install: $(TARGETS)
@echo " [INSTALL] $<"
$(Q) $(INSTALL_PROGRAM) -D $< $(usrsbindir)/$(<F)
install: install_cluster
$(Q) $(INSTALL_PROGRAM) -D cmirrord $(usrsbindir)/cmirrord

View File

@@ -1548,7 +1548,7 @@ static void cpg_config_callback(cpg_handle_t handle, const struct cpg_name *gnam
member_list, member_list_entries);
}
static cpg_callbacks_t cpg_callbacks = {
cpg_callbacks_t cpg_callbacks = {
.cpg_deliver_fn = cpg_message_callback,
.cpg_confchg_fn = cpg_config_callback,
};

View File

@@ -39,7 +39,7 @@ struct clog_request {
* machine. If the two are equal, there is no need
* to do endian conversions.
*/
union version_u {
union {
uint64_t version[2]; /* LE version and native version */
struct dm_list list;
} u;

View File

@@ -658,7 +658,8 @@ static int clog_dtr(struct dm_ulog_request *rq)
if (lc->disk_fd != -1 && close(lc->disk_fd))
LOG_ERROR("Failed to close disk log: %s",
strerror(errno));
free(lc->disk_buffer);
if (lc->disk_buffer)
free(lc->disk_buffer);
free(lc->clean_bits);
free(lc->sync_bits);
free(lc);

View File

@@ -14,21 +14,11 @@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
abs_srcdir = @abs_srcdir@
SOURCES = libdevmapper-event.c
SOURCES2 = dmeventd.c
TARGETS = dmeventd
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES) $(SOURCES2) \
plugins/lvm2/dmeventd_lvm.c \
plugins/mirror/dmeventd_mirror.c \
plugins/raid/dmeventd_raid.c \
plugins/snapshot/dmeventd_snapshot.c \
plugins/thin/dmeventd_thin.c \
plugins/vdo/dmeventd_vdo.c \
)
CFLOW_TARGET := $(TARGETS)
.PHONY: install_lib_dynamic install_lib_static install_include \
install_pkgconfig install_dmeventd_dynamic install_dmeventd_static \
@@ -47,7 +37,6 @@ endif
LIB_VERSION = $(LIB_VERSION_DM)
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
LIBS = $(PTHREAD_LIBS) -L$(interfacebuilddir) -ldevmapper
CLEAN_TARGETS = dmeventd.static $(LIB_NAME).a
@@ -57,6 +46,7 @@ endif
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
CFLOW_TARGET = dmeventd
EXPORTED_HEADER = $(srcdir)/libdevmapper-event.h
EXPORTED_FN_PREFIX = dm_event
@@ -65,26 +55,34 @@ include $(top_builddir)/make.tmpl
all: device-mapper
device-mapper: $(TARGETS)
plugins.device-mapper: $(LIB_SHARED)
CFLAGS_dmeventd.o += $(EXTRA_EXEC_CFLAGS)
LIBS += $(PTHREAD_LIBS) -L$(top_builddir)/libdm -ldevmapper
dmeventd: $(LIB_SHARED) dmeventd.o
@echo " [CC] $@"
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS) dmeventd.o \
-o $@ $(DL_LIBS) $(DMEVENT_LIBS) $(LIBS)
$(Q) $(CC) $(CFLAGS) -L. $(LDFLAGS) $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS) dmeventd.o \
-o $@ $(DL_LIBS) $(DMEVENT_LIBS) $(LIBS) -lm
dmeventd.static: $(LIB_STATIC) dmeventd.o
@echo " [CC] $@"
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -static dmeventd.o \
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -static -L. -L$(interfacebuilddir) dmeventd.o \
-o $@ $(DL_LIBS) $(DMEVENT_LIBS) $(LIBS) $(STATIC_LIBS)
ifeq ("@PKGCONFIG@", "yes")
INSTALL_LIB_TARGETS += install_pkgconfig
endif
ifneq ("$(CFLOW_CMD)", "")
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
-include $(top_builddir)/lib/liblvm-internal.cflow
-include $(top_builddir)/lib/liblvm2cmd.cflow
-include $(top_builddir)/daemons/dmeventd/$(LIB_NAME).cflow
-include $(top_builddir)/daemons/dmeventd/plugins/mirror/$(LIB_NAME)-lvm2mirror.cflow
endif
install_include: $(srcdir)/libdevmapper-event.h
@echo " [INSTALL] $(<F)"
@echo " [INSTALL] $<"
$(Q) $(INSTALL_DATA) -D $< $(includedir)/$(<F)
install_pkgconfig: libdevmapper-event.pc

View File

@@ -1742,8 +1742,7 @@ static void _init_thread_signals(void)
sigset_t my_sigset;
struct sigaction act = { .sa_handler = _sig_alarm };
if (sigaction(SIGALRM, &act, NULL))
log_sys_debug("sigaction", "SIGLARM");
sigaction(SIGALRM, &act, NULL);
sigfillset(&my_sigset);
/* These are used for exiting */

View File

@@ -25,6 +25,9 @@ LIB_NAME = libdevmapper-event-lvm2mirror
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
LIB_VERSION = $(LIB_VERSION_LVM)
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
include $(top_builddir)/make.tmpl
install_lvm2: install_dm_plugin

View File

@@ -24,6 +24,9 @@ LIB_NAME = libdevmapper-event-lvm2raid
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
LIB_VERSION = $(LIB_VERSION_LVM)
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
include $(top_builddir)/make.tmpl
install_lvm2: install_dm_plugin

View File

@@ -77,7 +77,7 @@ static int _process_raid_event(struct dso_state *state, char *params, const char
if (dead) {
/*
* Use the first event to run a repair ignoring any additional ones.
* Use the first event to run a repair ignoring any additonal ones.
*
* We presume lvconvert to do pre-repair
* checks to avoid bloat in this plugin.

View File

@@ -24,6 +24,9 @@ LIB_NAME = libdevmapper-event-lvm2thin
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
LIB_VERSION = $(LIB_VERSION_LVM)
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
include $(top_builddir)/make.tmpl
install_lvm2: install_dm_plugin

View File

@@ -24,6 +24,9 @@ LIB_NAME = libdevmapper-event-lvm2vdo
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
LIB_VERSION = $(LIB_VERSION_LVM)
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
include $(top_builddir)/make.tmpl
install_lvm2: install_dm_plugin

View File

@@ -15,8 +15,7 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
lvmdbuspydir = $(python3dir)/lvmdbusd
lvmdbusdir = $(DESTDIR)$(lvmdbuspydir)
lvmdbusdir = $(python3dir)/lvmdbusd
LVMDBUS_SRCDIR_FILES = \
automatedproperties.py \
@@ -54,16 +53,16 @@ include $(top_builddir)/make.tmpl
all:
$(Q) test -x $(LVMDBUSD) || chmod 755 $(LVMDBUSD)
install_lvmdbusd: $(LVMDBUSD)
install_lvmdbusd:
@echo " [INSTALL] $<"
$(Q) $(INSTALL_DIR) $(sbindir)
$(Q) $(INSTALL_SCRIPT) $(LVMDBUSD) $(sbindir)
$(Q) $(INSTALL_DIR) $(lvmdbusdir)
$(Q) (cd $(srcdir); $(INSTALL_DATA) $(LVMDBUS_SRCDIR_FILES) $(lvmdbusdir))
$(Q) $(INSTALL_DATA) $(LVMDBUS_BUILDDIR_FILES) $(lvmdbusdir)
$(Q) PYTHON=$(PYTHON3) $(PYCOMPILE) --destdir "$(DESTDIR)" --basedir "$(lvmdbuspydir)" $(LVMDBUS_SRCDIR_FILES) $(LVMDBUS_BUILDDIR_FILES)
$(Q) $(CHMOD) 755 $(lvmdbusdir)/__pycache__
$(Q) $(CHMOD) 444 $(lvmdbusdir)/__pycache__/*.py[co]
$(Q) $(INSTALL_DIR) $(DESTDIR)$(lvmdbusdir)
$(Q) (cd $(srcdir); $(INSTALL_DATA) $(LVMDBUS_SRCDIR_FILES) $(DESTDIR)$(lvmdbusdir))
$(Q) $(INSTALL_DATA) $(LVMDBUS_BUILDDIR_FILES) $(DESTDIR)$(lvmdbusdir)
$(Q) PYTHON=$(PYTHON3) $(PYCOMPILE) --destdir "$(DESTDIR)" --basedir "$(lvmdbusdir)" $(LVMDBUS_SRCDIR_FILES) $(LVMDBUS_BUILDDIR_FILES)
$(Q) $(CHMOD) 755 $(DESTDIR)$(lvmdbusdir)/__pycache__
$(Q) $(CHMOD) 444 $(DESTDIR)$(lvmdbusdir)/__pycache__/*.py[co]
install_lvm2: install_lvmdbusd

View File

@@ -30,39 +30,33 @@ ifeq ("@BUILD_LOCKDDLM@", "yes")
LOCK_LIBS += -ldlmcontrol
endif
ifeq ("@BUILD_LOCKDIDM@", "yes")
SOURCES += lvmlockd-idm.c
LOCK_LIBS += -lseagate_ilm -lblkid
endif
SOURCES2 = lvmlockctl.c
TARGETS = lvmlockd lvmlockctl
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
CFLOW_TARGET = lvmlockd
.PHONY: install_lvmlockd install_lvmlockctl
.PHONY: install_lvmlockd
include $(top_builddir)/make.tmpl
CFLAGS += $(EXTRA_EXEC_CFLAGS)
INCLUDES += -I$(top_srcdir)/libdaemon/server
LDFLAGS += -L$(top_builddir)/libdaemon/server $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS)
LIBS += $(DAEMON_LIBS) $(PTHREAD_LIBS)
LIBS += $(RT_LIBS) $(DAEMON_LIBS) $(PTHREAD_LIBS)
ifeq ($(USE_SD_NOTIFY),yes)
CFLAGS += $(shell pkg-config --cflags libsystemd) -DUSE_SD_NOTIFY
LIBS += $(shell pkg-config --libs libsystemd)
endif
lvmlockd: $(OBJECTS) $(top_builddir)/libdaemon/server/libdaemonserver.a $(INTERNAL_LIBS)
lvmlockd: $(OBJECTS) $(top_builddir)/libdaemon/client/libdaemonclient.a \
$(top_builddir)/libdaemon/server/libdaemonserver.a
@echo " [CC] $@"
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $+ $(LOCK_LIBS) $(LIBS)
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(LOCK_LIBS) -ldaemonserver $(INTERNAL_LIBS) $(LIBS)
lvmlockctl: lvmlockctl.o $(INTERNAL_LIBS)
lvmlockctl: lvmlockctl.o $(top_builddir)/libdaemon/client/libdaemonclient.a
@echo " [CC] $@"
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS)
$(Q) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ lvmlockctl.o $(INTERNAL_LIBS) $(LIBS)
install_lvmlockd: lvmlockd
@echo " [INSTALL] $<"

View File

@@ -18,11 +18,8 @@
#include <errno.h>
#include <fcntl.h>
#include <syslog.h>
#include <ctype.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <sys/wait.h>
static int quit = 0;
static int info = 0;
@@ -33,7 +30,6 @@ static int kill_vg = 0;
static int drop_vg = 0;
static int gl_enable = 0;
static int gl_disable = 0;
static int use_stderr = 0;
static int stop_lockspaces = 0;
static char *arg_vg_name = NULL;
@@ -51,22 +47,6 @@ do { \
printf(fmt "\n", ##args); \
} while (0)
#define log_sys_emerg(fmt, args...) \
do { \
if (use_stderr) \
fprintf(stderr, fmt "\n", ##args); \
else \
syslog(LOG_EMERG, fmt, ##args); \
} while (0)
#define log_sys_warn(fmt, args...) \
do { \
if (use_stderr) \
fprintf(stderr, fmt "\n", ##args); \
else \
syslog(LOG_WARNING, fmt, ##args); \
} while (0)
#define MAX_LINE 512
/* copied from lvmlockd-internal.h */
@@ -522,274 +502,51 @@ static int do_stop_lockspaces(void)
return rv;
}
static int _reopen_fd_to_null(int fd)
static int do_kill(void)
{
int null_fd;
int r = 0;
if ((null_fd = open("/dev/null", O_RDWR)) == -1) {
log_error("open error /dev/null %d", errno);
return 0;
}
if (close(fd)) {
log_error("close error fd %d %d", fd, errno);
goto out;
}
if (dup2(null_fd, fd) == -1) {
log_error("dup2 error %d", errno);
goto out;
}
r = 1;
out:
if (close(null_fd)) {
log_error("close error fd %d %d", null_fd, errno);
return 0;
}
return r;
}
#define MAX_AV_COUNT 32
#define ONE_ARG_LEN 1024
static void _run_command_pipe(const char *cmd_str, pid_t *pid_out, FILE **fp_out)
{
char arg[ONE_ARG_LEN];
char *av[MAX_AV_COUNT + 1]; /* +1 for NULL */
char *arg_dup;
int av_count = 0;
int cmd_len;
int arg_len;
pid_t pid = 0;
FILE *fp = NULL;
int pipefd[2];
int i;
for (i = 0; i < MAX_AV_COUNT + 1; i++)
av[i] = NULL;
cmd_len = strlen(cmd_str);
memset(&arg, 0, sizeof(arg));
arg_len = 0;
for (i = 0; i < cmd_len; i++) {
if (!cmd_str[i])
break;
if (av_count == MAX_AV_COUNT)
goto out;
if (cmd_str[i] == '\\') {
if (i == (cmd_len - 1))
break;
i++;
if (cmd_str[i] == '\\') {
arg[arg_len++] = cmd_str[i];
continue;
}
if (isspace(cmd_str[i])) {
arg[arg_len++] = cmd_str[i];
continue;
} else {
break;
}
}
if (isalnum(cmd_str[i]) || ispunct(cmd_str[i])) {
arg[arg_len++] = cmd_str[i];
} else if (isspace(cmd_str[i])) {
if (arg_len) {
if (!(arg_dup = strdup(arg)))
goto out;
av[av_count++] = arg_dup;
}
memset(arg, 0, sizeof(arg));
arg_len = 0;
} else {
break;
}
}
if (arg_len) {
if (av_count >= MAX_AV_COUNT)
goto out;
if (!(arg_dup = strdup(arg)))
goto out;
av[av_count++] = arg_dup;
}
if (pipe(pipefd)) {
log_error("pipe error %d", errno);
goto out;
}
pid = fork();
if (pid < 0) {
log_error("fork error %d", errno);
pid = 0;
goto out;
}
if (pid == 0) {
/* Child -> writer, convert pipe[0] to STDOUT */
if (!_reopen_fd_to_null(STDIN_FILENO))
log_error("reopen STDIN error");
else if (close(pipefd[0 /*read*/]))
log_error("close error pipe[0] %d", errno);
else if (close(STDOUT_FILENO))
log_error("close error STDOUT %d", errno);
else if (dup2(pipefd[1 /*write*/], STDOUT_FILENO) == -1)
log_error("dup2 error STDOUT %d", errno);
else if (close(pipefd[1]))
log_error("close error pipe[1] %d", errno);
else {
execvp(av[0], av);
log_error("execvp error %d", errno);
}
_exit(errno);
}
/* Parent -> reader */
if (close(pipefd[1 /*write*/]))
log_error("close error STDOUT %d", errno);
if (!(fp = fdopen(pipefd[0 /*read*/], "r"))) {
log_error("fdopen STDIN error %d", errno);
if (close(pipefd[0]))
log_error("close error STDIN %d", errno);
}
out:
for (i = 0; i < MAX_AV_COUNT + 1; i++)
free(av[i]);
*pid_out = pid;
*fp_out = fp;
}
/* Returns -1 on error, 0 on success. */
static int _close_command_pipe(pid_t pid, FILE *fp)
{
int status, estatus;
int ret = -1;
if (waitpid(pid, &status, 0) != pid) {
log_error("waitpid error pid %d %d", pid, errno);
goto out;
}
if (WIFEXITED(status)) {
/* pid exited with an exit code */
estatus = WEXITSTATUS(status);
/* exit status 0: child success */
if (!estatus) {
ret = 0;
goto out;
}
/* exit status not zero: child error */
log_error("child exit error %d", estatus);
goto out;
}
if (WIFSIGNALED(status)) {
/* pid terminated due to a signal */
log_error("child exit from signal");
goto out;
}
log_error("child exit problem");
out:
if (fp && fclose(fp))
log_error("fclose error STDIN %d", errno);
return ret;
}
/* Returns -1 on error, 0 on success. */
static int _get_kill_command(char *kill_cmd)
{
char config_cmd[PATH_MAX + 128] = { 0 };
char config_val[1024] = { 0 };
char line[PATH_MAX] = { 0 };
pid_t pid = 0;
FILE *fp = NULL;
snprintf(config_cmd, PATH_MAX, "%s config --typeconfig full global/lvmlockctl_kill_command", LVM_PATH);
_run_command_pipe(config_cmd, &pid, &fp);
if (!pid) {
log_error("failed to run %s", config_cmd);
return -1;
}
if (!fp) {
log_error("failed to get output %s", config_cmd);
_close_command_pipe(pid, fp);
return -1;
}
if (!fgets(line, sizeof(line), fp)) {
log_error("no output from %s", config_cmd);
goto bad;
}
if (sscanf(line, "lvmlockctl_kill_command=\"%256[^\n\"]\"", config_val) != 1) {
log_error("unrecognized config value from %s", config_cmd);
goto bad;
}
if (!config_val[0] || (config_val[0] == ' ')) {
log_error("invalid config value from %s", config_cmd);
goto bad;
}
if (config_val[0] != '/') {
log_error("lvmlockctl_kill_command must be full path");
goto bad;
}
printf("Found lvmlockctl_kill_command: %s\n", config_val);
snprintf(kill_cmd, PATH_MAX, "%s %s", config_val, arg_vg_name);
kill_cmd[PATH_MAX-1] = '\0';
_close_command_pipe(pid, fp);
return 0;
bad:
_close_command_pipe(pid, fp);
return -1;
}
/* Returns -1 on error, 0 on success. */
static int _run_kill_command(char *kill_cmd)
{
pid_t pid = 0;
FILE *fp = NULL;
daemon_reply reply;
int result;
int rv;
_run_command_pipe(kill_cmd, &pid, &fp);
rv = _close_command_pipe(pid, fp);
syslog(LOG_EMERG, "Lost access to sanlock lease storage in VG %s.", arg_vg_name);
/* These two lines explain the manual alternative to the FIXME below. */
syslog(LOG_EMERG, "Immediately deactivate LVs in VG %s.", arg_vg_name);
syslog(LOG_EMERG, "Once VG is unused, run lvmlockctl --drop %s.", arg_vg_name);
if (!pid)
return -1;
/*
* It may not be strictly necessary to notify lvmlockd of the kill, but
* lvmlockd can use this information to avoid attempting any new lock
* requests in the VG (which would fail anyway), and can return an
* error indicating that the VG has been killed.
*/
if (rv < 0)
return -1;
reply = _lvmlockd_send("kill_vg",
"cmd = %s", "lvmlockctl",
"pid = " FMTd64, (int64_t) getpid(),
"vg_name = %s", arg_vg_name,
NULL);
return 0;
if (!_lvmlockd_result(reply, &result)) {
log_error("lvmlockd result %d", result);
rv = result;
} else {
rv = 0;
}
daemon_reply_destroy(reply);
/*
* FIXME: here is where we should implement a strong form of
* blkdeactivate, and if it completes successfully, automatically call
* do_drop() afterward. (The drop step may not always be necessary
* if the lvm commands run while shutting things down release all the
* leases.)
*
* run_strong_blkdeactivate();
* do_drop();
*/
return rv;
}
static int do_drop(void)
@@ -798,7 +555,7 @@ static int do_drop(void)
int result;
int rv;
log_sys_warn("Dropping locks for VG %s.", arg_vg_name);
syslog(LOG_WARNING, "Dropping locks for VG %s.", arg_vg_name);
/*
* Check for misuse by looking for any active LVs in the VG
@@ -826,84 +583,6 @@ static int do_drop(void)
return rv;
}
static int do_kill(void)
{
char kill_cmd[PATH_MAX] = { 0 };
daemon_reply reply;
int no_kill_command = 0;
int result;
int rv;
log_sys_emerg("lvmlockd lost access to locks in VG %s.", arg_vg_name);
rv = _get_kill_command(kill_cmd);
if (rv < 0) {
log_sys_emerg("Immediately deactivate LVs in VG %s.", arg_vg_name);
log_sys_emerg("Once VG is unused, run lvmlockctl --drop %s.", arg_vg_name);
no_kill_command = 1;
}
/*
* It may not be strictly necessary to notify lvmlockd of the kill, but
* lvmlockd can use this information to avoid attempting any new lock
* requests in the VG (which would fail anyway), and can return an
* error indicating that the VG has been killed.
*/
_lvmlockd = lvmlockd_open(NULL);
if (_lvmlockd.socket_fd < 0 || _lvmlockd.error) {
log_error("Cannot connect to lvmlockd for kill_vg.");
goto run;
}
reply = _lvmlockd_send("kill_vg",
"cmd = %s", "lvmlockctl",
"pid = " FMTd64, (int64_t) getpid(),
"vg_name = %s", arg_vg_name,
NULL);
if (!_lvmlockd_result(reply, &result))
log_error("lvmlockd result %d kill_vg", result);
daemon_reply_destroy(reply);
lvmlockd_close(_lvmlockd);
run:
if (no_kill_command)
return 0;
rv = _run_kill_command(kill_cmd);
if (rv < 0) {
log_sys_emerg("Failed to run VG %s kill command %s", arg_vg_name, kill_cmd);
log_sys_emerg("Immediately deactivate LVs in VG %s.", arg_vg_name);
log_sys_emerg("Once VG is unused, run lvmlockctl --drop %s.", arg_vg_name);
return -1;
}
log_sys_warn("Successful VG %s kill command %s", arg_vg_name, kill_cmd);
/*
* If kill command was successfully, call do_drop(). (The drop step
* may not always be necessary if the lvm commands run while shutting
* things down release all the leases.)
*/
rv = 0;
_lvmlockd = lvmlockd_open(NULL);
if (_lvmlockd.socket_fd < 0 || _lvmlockd.error) {
log_sys_emerg("Failed to connect to lvmlockd to drop locks in VG %s.", arg_vg_name);
return -1;
}
reply = _lvmlockd_send("drop_vg",
"cmd = %s", "lvmlockctl",
"pid = " FMTd64, (int64_t) getpid(),
"vg_name = %s", arg_vg_name,
NULL);
if (!_lvmlockd_result(reply, &result)) {
log_sys_emerg("Failed to drop locks in VG %s", arg_vg_name);
rv = result;
}
daemon_reply_destroy(reply);
lvmlockd_close(_lvmlockd);
return rv;
}
static void print_usage(void)
{
printf("lvmlockctl options\n");
@@ -921,7 +600,7 @@ static void print_usage(void)
printf("--force | -f 0|1>\n");
printf(" Force option for other commands.\n");
printf("--kill | -k <vgname>\n");
printf(" Kill access to the VG locks are lost (see lvmlockctl_kill_command).\n");
printf(" Kill access to the VG when sanlock cannot renew lease.\n");
printf("--drop | -r <vgname>\n");
printf(" Clear locks for the VG when it is unused after kill (-k).\n");
printf("--gl-enable | -E <vgname>\n");
@@ -930,8 +609,6 @@ static void print_usage(void)
printf(" Tell lvmlockd to disable the global lock in a sanlock VG.\n");
printf("--stop-lockspaces | -S\n");
printf(" Stop all lockspaces.\n");
printf("--stderr | -e\n");
printf(" Send kill and drop messages to stderr instead of syslog\n");
}
static int read_options(int argc, char *argv[])
@@ -951,7 +628,6 @@ static int read_options(int argc, char *argv[])
{"gl-enable", required_argument, 0, 'E' },
{"gl-disable", required_argument, 0, 'D' },
{"stop-lockspaces", no_argument, 0, 'S' },
{"stderr", no_argument, 0, 'e' },
{0, 0, 0, 0 }
};
@@ -961,7 +637,7 @@ static int read_options(int argc, char *argv[])
}
while (1) {
c = getopt_long(argc, argv, "hqidE:D:w:k:r:Se", long_options, &option_index);
c = getopt_long(argc, argv, "hqidE:D:w:k:r:S", long_options, &option_index);
if (c == -1)
break;
@@ -987,30 +663,23 @@ static int read_options(int argc, char *argv[])
break;
case 'k':
kill_vg = 1;
free(arg_vg_name);
arg_vg_name = strdup(optarg);
break;
case 'r':
drop_vg = 1;
free(arg_vg_name);
arg_vg_name = strdup(optarg);
break;
case 'E':
gl_enable = 1;
free(arg_vg_name);
arg_vg_name = strdup(optarg);
break;
case 'D':
gl_disable = 1;
free(arg_vg_name);
arg_vg_name = strdup(optarg);
break;
case 'S':
stop_lockspaces = 1;
break;
case 'e':
use_stderr = 1;
break;
default:
print_usage();
exit(1);
@@ -1029,12 +698,8 @@ int main(int argc, char **argv)
if (rv < 0)
return rv;
/* do_kill handles lvmlockd connections itself */
if (kill_vg)
return do_kill();
_lvmlockd = lvmlockd_open(NULL);
if (_lvmlockd.socket_fd < 0 || _lvmlockd.error) {
log_error("Cannot connect to lvmlockd.");
return -1;
@@ -1055,6 +720,11 @@ int main(int argc, char **argv)
goto out;
}
if (kill_vg) {
rv = do_kill();
goto out;
}
if (drop_vg) {
rv = do_drop();
goto out;

View File

@@ -421,63 +421,6 @@ struct lockspace *alloc_lockspace(void)
return ls;
}
static char **alloc_pvs_path(struct pvs *pvs, int num)
{
if (!num)
return NULL;
pvs->path = malloc(sizeof(char *) * num);
if (!pvs->path)
return NULL;
memset(pvs->path, 0x0, sizeof(char *) * num);
return pvs->path;
}
static void free_pvs_path(struct pvs *pvs)
{
int i;
for (i = 0; i < pvs->num; i++) {
if (!pvs->path[i])
continue;
free((char *)pvs->path[i]);
pvs->path[i] = NULL;
}
if (!pvs->path) {
free(pvs->path);
pvs->path = NULL;
}
}
static char **alloc_and_copy_pvs_path(struct pvs *dst, struct pvs *src)
{
int i;
if (!alloc_pvs_path(dst, src->num))
return NULL;
dst->num = 0;
for (i = 0; i < src->num; i++) {
if (!src->path[i] || !strcmp(src->path[i], "none"))
continue;
dst->path[dst->num] = strdup(src->path[i]);
if (!dst->path[dst->num]) {
log_error("out of memory for copying pvs path");
goto failed;
}
dst->num++;
}
return dst->path;
failed:
free_pvs_path(dst);
return NULL;
}
static struct action *alloc_action(void)
{
struct action *act;
@@ -567,9 +510,6 @@ static void free_action(struct action *act)
free(act->path);
act->path = NULL;
}
free_pvs_path(&act->pvs);
pthread_mutex_lock(&unused_struct_mutex);
if (unused_action_count >= MAX_UNUSED_ACTION) {
free(act);
@@ -624,12 +564,9 @@ static int setup_structs(void)
struct lock *lk;
int data_san = lm_data_size_sanlock();
int data_dlm = lm_data_size_dlm();
int data_idm = lm_data_size_idm();
int i;
resource_lm_data_size = data_san > data_dlm ? data_san : data_dlm;
resource_lm_data_size = resource_lm_data_size > data_idm ?
resource_lm_data_size : data_idm;
pthread_mutex_init(&unused_struct_mutex, NULL);
INIT_LIST_HEAD(&unused_action);
@@ -746,8 +683,6 @@ static const char *lm_str(int x)
return "dlm";
case LD_LM_SANLOCK:
return "sanlock";
case LD_LM_IDM:
return "idm";
default:
return "lm_unknown";
}
@@ -937,7 +872,7 @@ static int read_adopt_file(struct list_head *vg_lockd)
char vg_uuid[72];
char lm_type_str[16];
char mode[8];
struct lockspace *ls = NULL, *ls2;
struct lockspace *ls, *ls2;
struct resource *r;
FILE *fp;
@@ -961,9 +896,8 @@ static int read_adopt_file(struct list_head *vg_lockd)
goto fail;
memset(vg_uuid, 0, sizeof(vg_uuid));
memset(lm_type_str, 0, sizeof(lm_type_str));
if (sscanf(adopt_line, "VG: %63s %64s %15s %64s",
if (sscanf(adopt_line, "VG: %63s %64s %16s %64s",
vg_uuid, ls->vg_name, lm_type_str, ls->vg_args) != 4) {
goto fail;
}
@@ -982,9 +916,8 @@ static int read_adopt_file(struct list_head *vg_lockd)
r->type = LD_RT_LV;
memset(vg_uuid, 0, sizeof(vg_uuid));
memset(mode, 0, sizeof(mode));
if (sscanf(adopt_line, "LV: %64s %64s %s %7s %u",
if (sscanf(adopt_line, "LV: %64s %64s %s %8s %u",
vg_uuid, r->name, r->lv_args, mode, &r->version) != 5) {
goto fail;
}
@@ -1033,8 +966,6 @@ static int lm_prepare_lockspace(struct lockspace *ls, struct action *act)
rv = lm_prepare_lockspace_dlm(ls);
else if (ls->lm_type == LD_LM_SANLOCK)
rv = lm_prepare_lockspace_sanlock(ls);
else if (ls->lm_type == LD_LM_IDM)
rv = lm_prepare_lockspace_idm(ls);
else
return -1;
@@ -1051,8 +982,6 @@ static int lm_add_lockspace(struct lockspace *ls, struct action *act, int adopt)
rv = lm_add_lockspace_dlm(ls, adopt);
else if (ls->lm_type == LD_LM_SANLOCK)
rv = lm_add_lockspace_sanlock(ls, adopt);
else if (ls->lm_type == LD_LM_IDM)
rv = lm_add_lockspace_idm(ls, adopt);
else
return -1;
@@ -1069,8 +998,6 @@ static int lm_rem_lockspace(struct lockspace *ls, struct action *act, int free_v
rv = lm_rem_lockspace_dlm(ls, free_vg);
else if (ls->lm_type == LD_LM_SANLOCK)
rv = lm_rem_lockspace_sanlock(ls, free_vg);
else if (ls->lm_type == LD_LM_IDM)
rv = lm_rem_lockspace_idm(ls, free_vg);
else
return -1;
@@ -1088,9 +1015,6 @@ static int lm_lock(struct lockspace *ls, struct resource *r, int mode, struct ac
rv = lm_lock_dlm(ls, r, mode, vb_out, adopt);
else if (ls->lm_type == LD_LM_SANLOCK)
rv = lm_lock_sanlock(ls, r, mode, vb_out, retry, adopt);
else if (ls->lm_type == LD_LM_IDM)
rv = lm_lock_idm(ls, r, mode, vb_out, act->lv_uuid,
&act->pvs, adopt);
else
return -1;
@@ -1108,8 +1032,6 @@ static int lm_convert(struct lockspace *ls, struct resource *r,
rv = lm_convert_dlm(ls, r, mode, r_version);
else if (ls->lm_type == LD_LM_SANLOCK)
rv = lm_convert_sanlock(ls, r, mode, r_version);
else if (ls->lm_type == LD_LM_IDM)
rv = lm_convert_idm(ls, r, mode, r_version);
else
return -1;
@@ -1127,8 +1049,6 @@ static int lm_unlock(struct lockspace *ls, struct resource *r, struct action *ac
rv = lm_unlock_dlm(ls, r, r_version, lmu_flags);
else if (ls->lm_type == LD_LM_SANLOCK)
rv = lm_unlock_sanlock(ls, r, r_version, lmu_flags);
else if (ls->lm_type == LD_LM_IDM)
rv = lm_unlock_idm(ls, r, r_version, lmu_flags);
else
return -1;
@@ -1143,8 +1063,6 @@ static int lm_hosts(struct lockspace *ls, int notify)
return lm_hosts_dlm(ls, notify);
else if (ls->lm_type == LD_LM_SANLOCK)
return lm_hosts_sanlock(ls, notify);
else if (ls->lm_type == LD_LM_IDM)
return lm_hosts_idm(ls, notify);
return -1;
}
@@ -1154,8 +1072,6 @@ static void lm_rem_resource(struct lockspace *ls, struct resource *r)
lm_rem_resource_dlm(ls, r);
else if (ls->lm_type == LD_LM_SANLOCK)
lm_rem_resource_sanlock(ls, r);
else if (ls->lm_type == LD_LM_IDM)
lm_rem_resource_idm(ls, r);
}
static int lm_find_free_lock(struct lockspace *ls, uint64_t *free_offset, int *sector_size, int *align_size)
@@ -1164,8 +1080,6 @@ static int lm_find_free_lock(struct lockspace *ls, uint64_t *free_offset, int *s
return 0;
else if (ls->lm_type == LD_LM_SANLOCK)
return lm_find_free_lock_sanlock(ls, free_offset, sector_size, align_size);
else if (ls->lm_type == LD_LM_IDM)
return 0;
return -1;
}
@@ -1774,8 +1688,8 @@ static int res_update(struct lockspace *ls, struct resource *r,
}
/*
* For DLM and IDM locking scheme, there is nothing to deallocate when freeing a
* LV, the LV will simply be unlocked by rem_resource.
* There is nothing to deallocate when freeing a dlm LV, the LV
* will simply be unlocked by rem_resource.
*/
static int free_lv(struct lockspace *ls, struct resource *r)
@@ -1784,8 +1698,6 @@ static int free_lv(struct lockspace *ls, struct resource *r)
return lm_free_lv_sanlock(ls, r);
else if (ls->lm_type == LD_LM_DLM)
return 0;
else if (ls->lm_type == LD_LM_IDM)
return 0;
else
return -EINVAL;
}
@@ -1886,7 +1798,9 @@ static void res_process(struct lockspace *ls, struct resource *r,
act->result = -EINVAL;
list_del(&act->list);
add_client_result(act);
} else if (act->op == LD_OP_LOCK && act->mode == LD_LK_UN) {
}
if (act->op == LD_OP_LOCK && act->mode == LD_LK_UN) {
rv = res_unlock(ls, r, act);
if (rv == -ENOENT && (act->flags & LD_AF_UNLOCK_CANCEL))
@@ -2766,7 +2680,7 @@ out_rem:
log_debug("S %s clearing locks", ls->name);
(void) clear_locks(ls, free_vg, drop_vg);
rv = clear_locks(ls, free_vg, drop_vg);
/*
* Tell any other hosts in the lockspace to leave it
@@ -2844,8 +2758,6 @@ out_act:
ls->drop_vg = drop_vg;
if (ls->lm_type == LD_LM_DLM && !strcmp(ls->name, gl_lsname_dlm))
global_dlm_lockspace_exists = 0;
if (ls->lm_type == LD_LM_IDM && !strcmp(ls->name, gl_lsname_idm))
global_idm_lockspace_exists = 0;
/*
* Avoid a name collision of the same lockspace is added again before
@@ -2937,8 +2849,6 @@ static void gl_ls_name(char *ls_name)
memcpy(ls_name, gl_lsname_dlm, MAX_NAME);
else if (gl_use_sanlock)
memcpy(ls_name, gl_lsname_sanlock, MAX_NAME);
else if (gl_use_idm)
memcpy(ls_name, gl_lsname_idm, MAX_NAME);
else
memset(ls_name, 0, MAX_NAME);
}
@@ -2967,20 +2877,9 @@ static int add_lockspace_thread(const char *ls_name,
strncpy(ls->name, ls_name, MAX_NAME);
ls->lm_type = lm_type;
if (act) {
if (act)
ls->start_client_id = act->client_id;
/*
* Copy PV list to lockspact structure, so this is
* used for VG locking for idm scheme.
*/
if (lm_type == LD_LM_IDM &&
!alloc_and_copy_pvs_path(&ls->pvs, &act->pvs)) {
free(ls);
return -ENOMEM;
}
}
if (vg_uuid)
strncpy(ls->vg_uuid, vg_uuid, 64);
@@ -3007,18 +2906,6 @@ static int add_lockspace_thread(const char *ls_name,
pthread_mutex_lock(&lockspaces_mutex);
ls2 = find_lockspace_name(ls->name);
if (ls2) {
/*
* If find an existed lockspace, we need to update the PV list
* based on the latest information, and release for the old
* PV list in case it keeps stale information.
*/
free_pvs_path(&ls2->pvs);
if (lm_type == LD_LM_IDM &&
!alloc_and_copy_pvs_path(&ls2->pvs, &ls->pvs)) {
log_debug("add_lockspace_thread %s fails to allocate pvs", ls->name);
rv = -ENOMEM;
}
if (ls2->thread_stop) {
log_debug("add_lockspace_thread %s exists and stopping", ls->name);
rv = -EAGAIN;
@@ -3031,7 +2918,6 @@ static int add_lockspace_thread(const char *ls_name,
}
pthread_mutex_unlock(&lockspaces_mutex);
free_resource(r);
free_pvs_path(&ls->pvs);
free(ls);
return rv;
}
@@ -3045,8 +2931,6 @@ static int add_lockspace_thread(const char *ls_name,
if (ls->lm_type == LD_LM_DLM && !strcmp(ls->name, gl_lsname_dlm))
global_dlm_lockspace_exists = 1;
if (ls->lm_type == LD_LM_IDM && !strcmp(ls->name, gl_lsname_idm))
global_idm_lockspace_exists = 1;
list_add_tail(&ls->list, &lockspaces);
pthread_mutex_unlock(&lockspaces_mutex);
@@ -3057,7 +2941,6 @@ static int add_lockspace_thread(const char *ls_name,
list_del(&ls->list);
pthread_mutex_unlock(&lockspaces_mutex);
free_resource(r);
free_pvs_path(&ls->pvs);
free(ls);
return rv;
}
@@ -3066,15 +2949,16 @@ static int add_lockspace_thread(const char *ls_name,
}
/*
* There is no variant for sanlock because, with sanlock, the global
* lockspace is one of the vg lockspaces.
* There is no add_sanlock_global_lockspace or
* rem_sanlock_global_lockspace because with sanlock,
* the global lockspace is one of the vg lockspaces.
*/
static int add_global_lockspace(char *ls_name, int lm_type,
struct action *act)
static int add_dlm_global_lockspace(struct action *act)
{
int rv;
if (global_dlm_lockspace_exists || global_idm_lockspace_exists)
if (global_dlm_lockspace_exists)
return 0;
/*
@@ -3082,9 +2966,9 @@ static int add_global_lockspace(char *ls_name, int lm_type,
* lock request, insert an internal gl sh lock request?
*/
rv = add_lockspace_thread(ls_name, NULL, NULL, lm_type, NULL, act);
rv = add_lockspace_thread(gl_lsname_dlm, NULL, NULL, LD_LM_DLM, NULL, act);
if (rv < 0)
log_debug("add_global_lockspace add_lockspace_thread %d", rv);
log_debug("add_dlm_global_lockspace add_lockspace_thread %d", rv);
/*
* EAGAIN may be returned for a short period because
@@ -3097,12 +2981,12 @@ static int add_global_lockspace(char *ls_name, int lm_type,
}
/*
* When DLM or IDM locking scheme is used for global lock, if the global
* lockspace is the only one left, then stop it. This is not used for
* an explicit rem_lockspace action from the client, only for auto
* remove.
* If dlm gl lockspace is the only one left, then stop it.
* This is not used for an explicit rem_lockspace action from
* the client, only for auto remove.
*/
static int rem_global_lockspace(char *ls_name)
static int rem_dlm_global_lockspace(void)
{
struct lockspace *ls, *ls_gl = NULL;
int others = 0;
@@ -3110,7 +2994,7 @@ static int rem_global_lockspace(char *ls_name)
pthread_mutex_lock(&lockspaces_mutex);
list_for_each_entry(ls, &lockspaces, list) {
if (!strcmp(ls->name, ls_name)) {
if (!strcmp(ls->name, gl_lsname_dlm)) {
ls_gl = ls;
continue;
}
@@ -3142,26 +3026,6 @@ out:
return rv;
}
static int add_dlm_global_lockspace(struct action *act)
{
return add_global_lockspace(gl_lsname_dlm, LD_LM_DLM, act);
}
static int rem_dlm_global_lockspace(void)
{
return rem_global_lockspace(gl_lsname_dlm);
}
static int add_idm_global_lockspace(struct action *act)
{
return add_global_lockspace(gl_lsname_idm, LD_LM_IDM, act);
}
static int rem_idm_global_lockspace(void)
{
return rem_global_lockspace(gl_lsname_idm);
}
/*
* When the first dlm lockspace is added for a vg, automatically add a separate
* dlm lockspace for the global lock.
@@ -3187,9 +3051,6 @@ static int add_lockspace(struct action *act)
if (gl_use_dlm) {
rv = add_dlm_global_lockspace(act);
return rv;
} else if (gl_use_idm) {
rv = add_idm_global_lockspace(act);
return rv;
} else {
return -EINVAL;
}
@@ -3198,8 +3059,6 @@ static int add_lockspace(struct action *act)
if (act->rt == LD_RT_VG) {
if (gl_use_dlm)
add_dlm_global_lockspace(NULL);
else if (gl_use_idm)
add_idm_global_lockspace(NULL);
vg_ls_name(act->vg_name, ls_name);
@@ -3267,15 +3126,14 @@ static int rem_lockspace(struct action *act)
pthread_mutex_unlock(&lockspaces_mutex);
/*
* For DLM and IDM locking scheme, the global lockspace was
* automatically added when the first vg lockspace was added,
* now reverse that by automatically removing the dlm global
* lockspace when the last vg lockspace is removed.
* The dlm global lockspace was automatically added when
* the first dlm vg lockspace was added, now reverse that
* by automatically removing the dlm global lockspace when
* the last dlm vg lockspace is removed.
*/
if (rt == LD_RT_VG && gl_use_dlm)
rem_dlm_global_lockspace();
else if (rt == LD_RT_VG && gl_use_idm)
rem_idm_global_lockspace();
return 0;
}
@@ -3399,7 +3257,6 @@ static int for_each_lockspace(int do_stop, int do_free, int do_force)
if (ls->free_vg) {
/* In future we may need to free ls->actions here */
free_ls_resources(ls);
free_pvs_path(&ls->pvs);
free(ls);
free_count++;
}
@@ -3413,7 +3270,6 @@ static int for_each_lockspace(int do_stop, int do_free, int do_force)
if (!gl_type_static) {
gl_use_dlm = 0;
gl_use_sanlock = 0;
gl_use_idm = 0;
}
}
pthread_mutex_unlock(&lockspaces_mutex);
@@ -3489,9 +3345,6 @@ static int work_init_vg(struct action *act)
rv = lm_init_vg_sanlock(ls_name, act->vg_name, act->flags, act->vg_args);
else if (act->lm_type == LD_LM_DLM)
rv = lm_init_vg_dlm(ls_name, act->vg_name, act->flags, act->vg_args);
else if (act->lm_type == LD_LM_IDM)
/* Non't do anything for IDM when initialize VG */
rv = 0;
else
rv = -EINVAL;
@@ -3595,8 +3448,6 @@ static int work_init_lv(struct action *act)
} else if (act->lm_type == LD_LM_DLM) {
return 0;
} else if (act->lm_type == LD_LM_IDM) {
return 0;
} else {
log_error("init_lv ls_name %s bad lm_type %d", ls_name, act->lm_type);
return -EINVAL;
@@ -3660,29 +3511,20 @@ static void *worker_thread_main(void *arg_in)
if (act->op == LD_OP_RUNNING_LM) {
int run_sanlock = lm_is_running_sanlock();
int run_dlm = lm_is_running_dlm();
int run_idm = lm_is_running_idm();
if (daemon_test) {
run_sanlock = gl_use_sanlock;
run_dlm = gl_use_dlm;
run_idm = gl_use_idm;
}
/*
* It's not possible to enable multiple locking schemes
* for global lock, otherwise, it must be conflict and
* reports it!
*/
if ((run_sanlock + run_dlm + run_idm) >= 2)
if (run_sanlock && run_dlm)
act->result = -EXFULL;
else if (!run_sanlock && !run_dlm && !run_idm)
else if (!run_sanlock && !run_dlm)
act->result = -ENOLCK;
else if (run_sanlock)
act->result = LD_LM_SANLOCK;
else if (run_dlm)
act->result = LD_LM_DLM;
else if (run_idm)
act->result = LD_LM_IDM;
add_client_result(act);
} else if ((act->op == LD_OP_LOCK) && (act->flags & LD_AF_SEARCH_LS)) {
@@ -3970,9 +3812,6 @@ static int client_send_result(struct client *cl, struct action *act)
} else if (gl_use_dlm) {
if (!gl_lsname_dlm[0])
strcat(result_flags, "NO_GL_LS,");
} else if (gl_use_idm) {
if (!gl_lsname_idm[0])
strcat(result_flags, "NO_GL_LS,");
} else {
int found_lm = 0;
@@ -3980,8 +3819,6 @@ static int client_send_result(struct client *cl, struct action *act)
found_lm++;
if (lm_support_sanlock() && lm_is_running_sanlock())
found_lm++;
if (lm_support_idm() && lm_is_running_idm())
found_lm++;
if (!found_lm)
strcat(result_flags, "NO_GL_LS,NO_LM");
@@ -4157,13 +3994,11 @@ static int add_lock_action(struct action *act)
if (gl_use_sanlock && (act->op == LD_OP_ENABLE || act->op == LD_OP_DISABLE)) {
vg_ls_name(act->vg_name, ls_name);
} else {
if (!gl_use_dlm && !gl_use_sanlock && !gl_use_idm) {
if (!gl_use_dlm && !gl_use_sanlock) {
if (lm_is_running_dlm())
gl_use_dlm = 1;
else if (lm_is_running_sanlock())
gl_use_sanlock = 1;
else if (lm_is_running_idm())
gl_use_idm = 1;
}
gl_ls_name(ls_name);
}
@@ -4211,17 +4046,6 @@ static int add_lock_action(struct action *act)
add_dlm_global_lockspace(NULL);
goto retry;
} else if (act->op == LD_OP_LOCK && act->rt == LD_RT_GL && act->mode != LD_LK_UN && gl_use_idm) {
/*
* Automatically start the idm global lockspace when
* a command tries to acquire the global lock.
*/
log_debug("lockspace \"%s\" not found for idm gl, adding...", ls_name);
act->flags |= LD_AF_SEARCH_LS;
act->flags |= LD_AF_WAIT_STARTING;
add_idm_global_lockspace(NULL);
goto retry;
} else if (act->op == LD_OP_LOCK && act->mode == LD_LK_UN) {
log_debug("lockspace \"%s\" not found for unlock ignored", ls_name);
return -ENOLS;
@@ -4442,8 +4266,6 @@ static int str_to_lm(const char *str)
return LD_LM_SANLOCK;
if (!strcmp(str, "dlm"))
return LD_LM_DLM;
if (!strcmp(str, "idm"))
return LD_LM_IDM;
return -2;
}
@@ -4779,14 +4601,12 @@ static void client_recv_action(struct client *cl)
const char *vg_sysid;
const char *path;
const char *str;
struct pvs pvs;
char buf[17]; /* "path[%d]\0", %d outputs signed integer so max to 10 bytes */
int64_t val;
uint32_t opts = 0;
int result = 0;
int cl_pid;
int op, rt, lm, mode;
int rv, i;
int rv;
buffer_init(&req.buffer);
@@ -4875,13 +4695,11 @@ static void client_recv_action(struct client *cl)
if (!cl->name[0] && cl_name)
strncpy(cl->name, cl_name, MAX_NAME);
if (!gl_use_dlm && !gl_use_sanlock && !gl_use_idm && (lm > 0)) {
if (!gl_use_dlm && !gl_use_sanlock && (lm > 0)) {
if (lm == LD_LM_DLM && lm_support_dlm())
gl_use_dlm = 1;
else if (lm == LD_LM_SANLOCK && lm_support_sanlock())
gl_use_sanlock = 1;
else if (lm == LD_LM_IDM && lm_support_idm())
gl_use_idm = 1;
log_debug("set gl_use_%s", lm_str(lm));
}
@@ -4938,40 +4756,6 @@ static void client_recv_action(struct client *cl)
if (val)
act->host_id = val;
/* Create PV list for idm */
if (lm == LD_LM_IDM) {
memset(&pvs, 0x0, sizeof(pvs));
pvs.num = daemon_request_int(req, "path_num", 0);
log_error("pvs_num = %d", pvs.num);
if (!pvs.num)
goto skip_pvs_path;
/* Receive the pv list which is transferred from LVM command */
if (!alloc_pvs_path(&pvs, pvs.num)) {
log_error("fail to allocate pvs path");
rv = -ENOMEM;
goto out;
}
for (i = 0; i < pvs.num; i++) {
snprintf(buf, sizeof(buf), "path[%d]", i);
pvs.path[i] = (char *)daemon_request_str(req, buf, NULL);
}
if (!alloc_and_copy_pvs_path(&act->pvs, &pvs)) {
log_error("fail to allocate pvs path");
rv = -ENOMEM;
goto out;
}
if (pvs.path)
free(pvs.path);
pvs.path = NULL;
}
skip_pvs_path:
act->max_retries = daemon_request_int(req, "max_retries", DEFAULT_MAX_RETRIES);
dm_config_destroy(req.cft);
@@ -4993,12 +4777,6 @@ skip_pvs_path:
goto out;
}
if (lm == LD_LM_IDM && !lm_support_idm()) {
log_debug("idm not supported");
rv = -EPROTONOSUPPORT;
goto out;
}
if (act->op == LD_OP_LOCK && act->mode != LD_LK_UN)
cl->lock_ops = 1;
@@ -5188,7 +4966,7 @@ static void *client_thread_main(void *arg_in)
}
out:
if (adopt_opt && lock_acquire_written)
(void) unlink(adopt_file);
unlink(adopt_file);
return NULL;
}
@@ -5597,7 +5375,6 @@ static void adopt_locks(void)
}
list_del(&ls->list);
free_pvs_path(&ls->pvs);
free(ls);
}
@@ -5638,7 +5415,6 @@ static void adopt_locks(void)
if (rv < 0) {
log_error("Failed to create lockspace thread for VG %s", ls->vg_name);
list_del(&ls->list);
free_pvs_path(&ls->pvs);
free(ls);
free_action(act);
count_start_fail++;
@@ -5962,13 +5738,13 @@ static void adopt_locks(void)
if (count_start_fail || count_adopt_fail)
goto fail;
(void) unlink(adopt_file);
unlink(adopt_file);
write_adopt_file();
log_debug("adopt_locks done");
return;
fail:
(void) unlink(adopt_file);
unlink(adopt_file);
log_error("adopt_locks failed, reset host");
}
@@ -6081,7 +5857,6 @@ static int main_loop(daemon_state *ds_arg)
}
strcpy(gl_lsname_dlm, S_NAME_GL_DLM);
strcpy(gl_lsname_idm, S_NAME_GL_IDM);
INIT_LIST_HEAD(&lockspaces);
pthread_mutex_init(&lockspaces_mutex, NULL);
@@ -6335,8 +6110,6 @@ int main(int argc, char *argv[])
gl_use_dlm = 1;
else if (lm == LD_LM_SANLOCK && lm_support_sanlock())
gl_use_sanlock = 1;
else if (lm == LD_LM_IDM && lm_support_idm())
gl_use_idm = 1;
else {
fprintf(stderr, "invalid gl-type option\n");
exit(EXIT_FAILURE);

View File

@@ -327,7 +327,8 @@ int lm_rem_resource_dlm(struct lockspace *ls, struct resource *r)
log_error("S %s R %s rem_resource_dlm unlock error %d", ls->name, r->name, rv);
}
out:
free(rdd->vb);
if (rdd->vb)
free(rdd->vb);
memset(rdd, 0, sizeof(struct rd_dlm));
r->lm_init = 0;

View File

@@ -1,837 +0,0 @@
/*
* Copyright (C) 2020-2021 Seagate Ltd.
*
* 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.
*/
#define _XOPEN_SOURCE 500 /* pthread */
#define _ISOC99_SOURCE
#include "tools/tool.h"
#include "daemon-server.h"
#include "lib/mm/xlate.h"
#include "lvmlockd-internal.h"
#include "daemons/lvmlockd/lvmlockd-client.h"
#include "ilm.h"
#include <blkid/blkid.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <poll.h>
#include <regex.h>
#include <stddef.h>
#include <syslog.h>
#include <sys/sysmacros.h>
#include <time.h>
#define IDM_TIMEOUT 60000 /* unit: millisecond, 60 seconds */
/*
* Each lockspace thread has its own In-Drive Mutex (IDM) lock manager's
* connection. After established socket connection, the lockspace has
* been created in IDM lock manager and afterwards use the socket file
* descriptor to send any requests for lock related operations.
*/
struct lm_idm {
int sock; /* IDM lock manager connection */
};
struct rd_idm {
struct idm_lock_id id;
struct idm_lock_op op;
uint64_t vb_timestamp;
struct val_blk *vb;
};
int lm_data_size_idm(void)
{
return sizeof(struct rd_idm);
}
static uint64_t read_utc_us(void)
{
struct timespec cur_time;
clock_gettime(CLOCK_REALTIME, &cur_time);
/*
* Convert to microseconds unit. IDM reserves the MSB in 8 bytes
* and the low 56 bits are used for timestamp; 56 bits can support
* calendar year to 2284, so it has 260 years for overflow. Thus it
* is quite safe for overflow issue when wrote this code.
*/
return cur_time.tv_sec * 1000000 + cur_time.tv_nsec / 1000;
}
static int uuid_read_format(char *uuid_str, const char *buffer)
{
int out = 0;
/* just strip out any dashes */
while (*buffer) {
if (*buffer == '-') {
buffer++;
continue;
}
if (out >= 32) {
log_error("Too many characters to be uuid.");
return -1;
}
uuid_str[out++] = *buffer;
buffer++;
}
if (out != 32) {
log_error("Couldn't read uuid: incorrect number of "
"characters.");
return -1;
}
return 0;
}
#define SYSFS_ROOT "/sys"
#define BUS_SCSI_DEVS "/bus/scsi/devices"
static struct idm_lock_op glb_lock_op;
static void lm_idm_free_dir_list(struct dirent **dir_list, int dir_num)
{
int i;
for (i = 0; i < dir_num; ++i)
free(dir_list[i]);
free(dir_list);
}
static int lm_idm_scsi_directory_select(const struct dirent *s)
{
regex_t regex;
int ret;
/* Only select directory with the format x:x:x:x */
ret = regcomp(&regex, "^[0-9]+:[0-9]+:[0-9]+:[0-9]+$", REG_EXTENDED);
if (ret)
return 0;
ret = regexec(&regex, s->d_name, 0, NULL, 0);
if (!ret) {
regfree(&regex);
return 1;
}
regfree(&regex);
return 0;
}
static int lm_idm_scsi_find_block_dirctory(const char *block_path)
{
struct stat stats;
if ((stat(block_path, &stats) >= 0) && S_ISDIR(stats.st_mode))
return 0;
return -1;
}
static int lm_idm_scsi_block_node_select(const struct dirent *s)
{
if (DT_LNK != s->d_type && DT_DIR != s->d_type)
return 0;
if (DT_DIR == s->d_type) {
/* Skip this directory: '.' and parent: '..' */
if (!strcmp(s->d_name, ".") || !strcmp(s->d_name, ".."))
return 0;
}
return 1;
}
static int lm_idm_scsi_find_block_node(const char *blk_path, char **blk_dev)
{
struct dirent **dir_list;
int dir_num;
dir_num = scandir(blk_path, &dir_list, lm_idm_scsi_block_node_select, NULL);
if (dir_num < 0) {
log_error("Cannot find valid directory entry in %s", blk_path);
return -1;
}
/*
* Should have only one block name under the path, if the dir_num is
* not 1 (e.g. 0 or any number bigger than 1), it must be wrong and
* should never happen.
*/
if (dir_num == 1)
*blk_dev = strdup(dir_list[0]->d_name);
else
*blk_dev = NULL;
lm_idm_free_dir_list(dir_list, dir_num);
if (!*blk_dev)
return -1;
return dir_num;
}
static int lm_idm_scsi_search_propeller_partition(char *dev)
{
int i, nparts;
blkid_probe pr;
blkid_partlist ls;
int found = -1;
pr = blkid_new_probe_from_filename(dev);
if (!pr) {
log_error("%s: failed to create a new libblkid probe", dev);
return -1;
}
/* Binary interface */
ls = blkid_probe_get_partitions(pr);
if (!ls) {
log_error("%s: failed to read partitions", dev);
return -1;
}
/* List partitions */
nparts = blkid_partlist_numof_partitions(ls);
if (!nparts)
goto done;
for (i = 0; i < nparts; i++) {
const char *p;
blkid_partition par = blkid_partlist_get_partition(ls, i);
p = blkid_partition_get_name(par);
if (p) {
log_debug("partition name='%s'", p);
if (!strcmp(p, "propeller"))
found = blkid_partition_get_partno(par);
}
if (found >= 0)
break;
}
done:
blkid_free_probe(pr);
return found;
}
static char *lm_idm_scsi_get_block_device_node(const char *scsi_path)
{
char *blk_path = NULL;
char *blk_dev = NULL;
char *dev_node = NULL;
int ret;
/*
* Locate the "block" directory, such like:
* /sys/bus/scsi/devices/1:0:0:0/block
*/
ret = asprintf(&blk_path, "%s/%s", scsi_path, "block");
if (ret < 0) {
log_error("Fail to allocate block path for %s", scsi_path);
goto fail;
}
ret = lm_idm_scsi_find_block_dirctory(blk_path);
if (ret < 0) {
log_error("Fail to find block path %s", blk_path);
goto fail;
}
/*
* Locate the block device name, such like:
* /sys/bus/scsi/devices/1:0:0:0/block/sdb
*
* After return from this function and if it makes success,
* the global variable "blk_dev" points to the block device
* name, in this example it points to string "sdb".
*/
ret = lm_idm_scsi_find_block_node(blk_path, &blk_dev);
if (ret < 0) {
log_error("Fail to find block node");
goto fail;
}
ret = asprintf(&dev_node, "/dev/%s", blk_dev);
if (ret < 0) {
log_error("Fail to allocate memory for blk node path");
goto fail;
}
ret = lm_idm_scsi_search_propeller_partition(dev_node);
if (ret < 0)
goto fail;
free(blk_path);
free(blk_dev);
return dev_node;
fail:
free(blk_path);
free(blk_dev);
free(dev_node);
return NULL;
}
static int lm_idm_get_gl_lock_pv_list(void)
{
struct dirent **dir_list;
char scsi_bus_path[PATH_MAX];
char *drive_path;
int i, dir_num, ret;
if (glb_lock_op.drive_num)
return 0;
snprintf(scsi_bus_path, sizeof(scsi_bus_path), "%s%s",
SYSFS_ROOT, BUS_SCSI_DEVS);
dir_num = scandir(scsi_bus_path, &dir_list,
lm_idm_scsi_directory_select, NULL);
if (dir_num < 0) { /* scsi mid level may not be loaded */
log_error("Attached devices: none");
return -1;
}
for (i = 0; i < dir_num; i++) {
char *scsi_path;
ret = asprintf(&scsi_path, "%s/%s", scsi_bus_path,
dir_list[i]->d_name);
if (ret < 0) {
log_error("Fail to allocate memory for scsi directory");
goto failed;
}
if (glb_lock_op.drive_num >= ILM_DRIVE_MAX_NUM) {
log_error("Global lock: drive number %d exceeds limitation (%d) ?!",
glb_lock_op.drive_num, ILM_DRIVE_MAX_NUM);
free(scsi_path);
goto failed;
}
drive_path = lm_idm_scsi_get_block_device_node(scsi_path);
if (!drive_path) {
free(scsi_path);
continue;
}
glb_lock_op.drives[glb_lock_op.drive_num] = drive_path;
glb_lock_op.drive_num++;
free(scsi_path);
}
lm_idm_free_dir_list(dir_list, dir_num);
return 0;
failed:
lm_idm_free_dir_list(dir_list, dir_num);
for (i = 0; i < glb_lock_op.drive_num; i++) {
if (glb_lock_op.drives[i]) {
free(glb_lock_op.drives[i]);
glb_lock_op.drives[i] = NULL;
}
}
return -1;
}
static void lm_idm_update_vb_timestamp(uint64_t *vb_timestamp)
{
uint64_t utc_us = read_utc_us();
/*
* It's possible that the multiple nodes have no clock
* synchronization with microsecond prcision and the time
* is going backward. For this case, simply increment the
* existing timestamp and write out to drive.
*/
if (*vb_timestamp >= utc_us)
(*vb_timestamp)++;
else
*vb_timestamp = utc_us;
}
int lm_prepare_lockspace_idm(struct lockspace *ls)
{
struct lm_idm *lm = NULL;
lm = malloc(sizeof(struct lm_idm));
if (!lm) {
log_error("S %s prepare_lockspace_idm fail to allocate lm_idm for %s",
ls->name, ls->vg_name);
return -ENOMEM;
}
memset(lm, 0x0, sizeof(struct lm_idm));
ls->lm_data = lm;
log_debug("S %s prepare_lockspace_idm done", ls->name);
return 0;
}
int lm_add_lockspace_idm(struct lockspace *ls, int adopt)
{
char killpath[IDM_FAILURE_PATH_LEN];
char killargs[IDM_FAILURE_ARGS_LEN];
struct lm_idm *lmi = (struct lm_idm *)ls->lm_data;
int rv;
if (daemon_test)
return 0;
if (!strcmp(ls->name, S_NAME_GL_IDM)) {
/*
* Prepare the pv list for global lock, if the drive contains
* "propeller" partition, then this drive will be considered
* as a member of pv list.
*/
rv = lm_idm_get_gl_lock_pv_list();
if (rv < 0) {
log_error("S %s add_lockspace_idm fail to get pv list for glb lock",
ls->name);
return -EIO;
} else {
log_error("S %s add_lockspace_idm get pv list for glb lock",
ls->name);
}
}
/*
* Construct the execution path for command "lvmlockctl" by using the
* path to the lvm binary and appending "lockctl".
*/
memset(killpath, 0, sizeof(killpath));
snprintf(killpath, IDM_FAILURE_PATH_LEN, "%slockctl", LVM_PATH);
/* Pass the argument "--kill vg_name" for killpath */
memset(killargs, 0, sizeof(killargs));
snprintf(killargs, IDM_FAILURE_ARGS_LEN, "--kill %s", ls->vg_name);
/* Connect with IDM lock manager per every lockspace. */
rv = ilm_connect(&lmi->sock);
if (rv < 0) {
log_error("S %s add_lockspace_idm fail to connect the lock manager %d",
ls->name, lmi->sock);
lmi->sock = 0;
rv = -EMANAGER;
goto fail;
}
rv = ilm_set_killpath(lmi->sock, killpath, killargs);
if (rv < 0) {
log_error("S %s add_lockspace_idm fail to set kill path %d",
ls->name, rv);
rv = -EMANAGER;
goto fail;
}
log_debug("S %s add_lockspace_idm kill path is: \"%s %s\"",
ls->name, killpath, killargs);
log_debug("S %s add_lockspace_idm done", ls->name);
return 0;
fail:
if (lmi && lmi->sock)
close(lmi->sock);
if (lmi)
free(lmi);
return rv;
}
int lm_rem_lockspace_idm(struct lockspace *ls, int free_vg)
{
struct lm_idm *lmi = (struct lm_idm *)ls->lm_data;
int i, rv = 0;
if (daemon_test)
goto out;
rv = ilm_disconnect(lmi->sock);
if (rv < 0)
log_error("S %s rem_lockspace_idm error %d", ls->name, rv);
/* Release pv list for global lock */
if (!strcmp(ls->name, "lvm_global")) {
for (i = 0; i < glb_lock_op.drive_num; i++) {
if (glb_lock_op.drives[i]) {
free(glb_lock_op.drives[i]);
glb_lock_op.drives[i] = NULL;
}
}
}
out:
free(lmi);
ls->lm_data = NULL;
return rv;
}
static int lm_add_resource_idm(struct lockspace *ls, struct resource *r)
{
struct rd_idm *rdi = (struct rd_idm *)r->lm_data;
if (r->type == LD_RT_GL || r->type == LD_RT_VG) {
rdi->vb = zalloc(sizeof(struct val_blk));
if (!rdi->vb)
return -ENOMEM;
}
return 0;
}
int lm_rem_resource_idm(struct lockspace *ls, struct resource *r)
{
struct rd_idm *rdi = (struct rd_idm *)r->lm_data;
if (rdi->vb)
free(rdi->vb);
memset(rdi, 0, sizeof(struct rd_idm));
r->lm_init = 0;
return 0;
}
static int to_idm_mode(int ld_mode)
{
switch (ld_mode) {
case LD_LK_EX:
return IDM_MODE_EXCLUSIVE;
case LD_LK_SH:
return IDM_MODE_SHAREABLE;
default:
break;
};
return -1;
}
int lm_lock_idm(struct lockspace *ls, struct resource *r, int ld_mode,
struct val_blk *vb_out, char *lv_uuid, struct pvs *pvs,
int adopt)
{
struct lm_idm *lmi = (struct lm_idm *)ls->lm_data;
struct rd_idm *rdi = (struct rd_idm *)r->lm_data;
char **drive_path = NULL;
uint64_t timestamp;
int reset_vb = 0;
int rv, i;
if (!r->lm_init) {
rv = lm_add_resource_idm(ls, r);
if (rv < 0)
return rv;
r->lm_init = 1;
}
rdi->op.mode = to_idm_mode(ld_mode);
if (rv < 0) {
log_error("lock_idm invalid mode %d", ld_mode);
return -EINVAL;
}
log_debug("S %s R %s lock_idm", ls->name, r->name);
if (daemon_test) {
if (rdi->vb) {
vb_out->version = le16_to_cpu(rdi->vb->version);
vb_out->flags = le16_to_cpu(rdi->vb->flags);
vb_out->r_version = le32_to_cpu(rdi->vb->r_version);
}
return 0;
}
rdi->op.timeout = IDM_TIMEOUT;
/*
* Generate the UUID string, for RT_VG, it only needs to generate
* UUID string for VG level, for RT_LV, it needs to generate
* UUID strings for both VG and LV levels. At the end, these IDs
* are used as identifier for IDM in drive firmware.
*/
if (r->type == LD_RT_VG || r->type == LD_RT_LV)
log_debug("S %s R %s VG uuid %s", ls->name, r->name, ls->vg_uuid);
if (r->type == LD_RT_LV)
log_debug("S %s R %s LV uuid %s", ls->name, r->name, lv_uuid);
memset(&rdi->id, 0x0, sizeof(struct idm_lock_id));
if (r->type == LD_RT_VG) {
uuid_read_format(rdi->id.vg_uuid, ls->vg_uuid);
} else if (r->type == LD_RT_LV) {
uuid_read_format(rdi->id.vg_uuid, ls->vg_uuid);
uuid_read_format(rdi->id.lv_uuid, lv_uuid);
}
/*
* Establish the drive path list for lock, since different lock type
* has different drive list; the GL lock uses the global pv list,
* the VG lock uses the pv list spanned for the whole volume group,
* the LV lock uses the pv list for the logical volume.
*/
switch (r->type) {
case LD_RT_GL:
drive_path = glb_lock_op.drives;
rdi->op.drive_num = glb_lock_op.drive_num;
break;
case LD_RT_VG:
drive_path = (char **)ls->pvs.path;
rdi->op.drive_num = ls->pvs.num;
break;
case LD_RT_LV:
drive_path = (char **)pvs->path;
rdi->op.drive_num = pvs->num;
break;
default:
break;
}
if (!drive_path) {
log_error("S %s R %s cannot find the valid drive path array",
ls->name, r->name);
return -EINVAL;
}
if (rdi->op.drive_num >= ILM_DRIVE_MAX_NUM) {
log_error("S %s R %s exceeds limitation for drive path array",
ls->name, r->name);
return -EINVAL;
}
for (i = 0; i < rdi->op.drive_num; i++)
rdi->op.drives[i] = drive_path[i];
log_debug("S %s R %s mode %d drive_num %d timeout %d",
ls->name, r->name, rdi->op.mode,
rdi->op.drive_num, rdi->op.timeout);
for (i = 0; i < rdi->op.drive_num; i++)
log_debug("S %s R %s drive path[%d] %s",
ls->name, r->name, i, rdi->op.drives[i]);
rv = ilm_lock(lmi->sock, &rdi->id, &rdi->op);
if (rv < 0) {
log_debug("S %s R %s lock_idm acquire mode %d rv %d",
ls->name, r->name, ld_mode, rv);
return -ELOCKIO;
}
if (rdi->vb) {
rv = ilm_read_lvb(lmi->sock, &rdi->id, (char *)&timestamp,
sizeof(uint64_t));
/*
* If fail to read value block, which might be caused by drive
* failure, notify up layer to invalidate metadata.
*/
if (rv < 0) {
log_error("S %s R %s lock_idm get_lvb error %d",
ls->name, r->name, rv);
reset_vb = 1;
/* Reset timestamp */
rdi->vb_timestamp = 0;
/*
* If the cached timestamp mismatches with the stored value
* in the IDM, this means another host has updated timestamp
* for the new VB. Let's reset VB and notify up layer to
* invalidate metadata.
*/
} else if (rdi->vb_timestamp != timestamp) {
log_debug("S %s R %s lock_idm get lvb timestamp %lu:%lu",
ls->name, r->name, rdi->vb_timestamp,
timestamp);
rdi->vb_timestamp = timestamp;
reset_vb = 1;
}
if (reset_vb == 1) {
memset(rdi->vb, 0, sizeof(struct val_blk));
memset(vb_out, 0, sizeof(struct val_blk));
/*
* The lock is still acquired, but the vb values has
* been invalidated.
*/
rv = 0;
goto out;
}
/* Otherwise, copy the cached VB to up layer */
memcpy(vb_out, rdi->vb, sizeof(struct val_blk));
}
out:
return rv;
}
int lm_convert_idm(struct lockspace *ls, struct resource *r,
int ld_mode, uint32_t r_version)
{
struct lm_idm *lmi = (struct lm_idm *)ls->lm_data;
struct rd_idm *rdi = (struct rd_idm *)r->lm_data;
int mode, rv;
if (rdi->vb && r_version && (r->mode == LD_LK_EX)) {
if (!rdi->vb->version) {
/* first time vb has been written */
rdi->vb->version = VAL_BLK_VERSION;
}
rdi->vb->r_version = r_version;
log_debug("S %s R %s convert_idm set r_version %u",
ls->name, r->name, r_version);
lm_idm_update_vb_timestamp(&rdi->vb_timestamp);
log_debug("S %s R %s convert_idm vb %x %x %u timestamp %lu",
ls->name, r->name, rdi->vb->version, rdi->vb->flags,
rdi->vb->r_version, rdi->vb_timestamp);
}
mode = to_idm_mode(ld_mode);
if (mode < 0) {
log_error("S %s R %s convert_idm invalid mode %d",
ls->name, r->name, ld_mode);
return -EINVAL;
}
log_debug("S %s R %s convert_idm", ls->name, r->name);
if (daemon_test)
return 0;
if (rdi->vb && r_version && (r->mode == LD_LK_EX)) {
rv = ilm_write_lvb(lmi->sock, &rdi->id,
(char *)rdi->vb_timestamp, sizeof(uint64_t));
if (rv < 0) {
log_error("S %s R %s convert_idm write lvb error %d",
ls->name, r->name, rv);
return -ELMERR;
}
}
rv = ilm_convert(lmi->sock, &rdi->id, mode);
if (rv < 0)
log_error("S %s R %s convert_idm convert error %d",
ls->name, r->name, rv);
return rv;
}
int lm_unlock_idm(struct lockspace *ls, struct resource *r,
uint32_t r_version, uint32_t lmu_flags)
{
struct lm_idm *lmi = (struct lm_idm *)ls->lm_data;
struct rd_idm *rdi = (struct rd_idm *)r->lm_data;
int rv;
if (rdi->vb && r_version && (r->mode == LD_LK_EX)) {
if (!rdi->vb->version) {
/* first time vb has been written */
rdi->vb->version = VAL_BLK_VERSION;
}
if (r_version)
rdi->vb->r_version = r_version;
lm_idm_update_vb_timestamp(&rdi->vb_timestamp);
log_debug("S %s R %s unlock_idm vb %x %x %u timestamp %lu",
ls->name, r->name, rdi->vb->version, rdi->vb->flags,
rdi->vb->r_version, rdi->vb_timestamp);
}
log_debug("S %s R %s unlock_idm", ls->name, r->name);
if (daemon_test)
return 0;
if (rdi->vb && r_version && (r->mode == LD_LK_EX)) {
rv = ilm_write_lvb(lmi->sock, &rdi->id,
(char *)&rdi->vb_timestamp, sizeof(uint64_t));
if (rv < 0) {
log_error("S %s R %s unlock_idm set_lvb error %d",
ls->name, r->name, rv);
return -ELMERR;
}
}
rv = ilm_unlock(lmi->sock, &rdi->id);
if (rv < 0)
log_error("S %s R %s unlock_idm error %d", ls->name, r->name, rv);
return rv;
}
int lm_hosts_idm(struct lockspace *ls, int notify)
{
struct resource *r;
struct lm_idm *lmi = (struct lm_idm *)ls->lm_data;
struct rd_idm *rdi;
int count, self, found_others = 0;
int rv;
list_for_each_entry(r, &ls->resources, list) {
if (!r->lm_init)
continue;
rdi = (struct rd_idm *)r->lm_data;
rv = ilm_get_host_count(lmi->sock, &rdi->id, &rdi->op,
&count, &self);
if (rv < 0) {
log_error("S %s lm_hosts_idm error %d", ls->name, rv);
return rv;
}
/* Fixup: need to reduce self count */
if (count > found_others)
found_others = count;
}
return found_others;
}
int lm_get_lockspaces_idm(struct list_head *ls_rejoin)
{
/* TODO: Need to add support for adoption. */
return -1;
}
int lm_is_running_idm(void)
{
int sock, rv;
if (daemon_test)
return gl_use_idm;
rv = ilm_connect(&sock);
if (rv < 0) {
log_error("Fail to connect seagate IDM lock manager %d", rv);
return 0;
}
ilm_disconnect(sock);
return 1;
}

View File

@@ -20,7 +20,6 @@
#define R_NAME_GL "GLLK"
#define R_NAME_VG "VGLK"
#define S_NAME_GL_DLM "lvm_global"
#define S_NAME_GL_IDM "lvm_global"
#define LVM_LS_PREFIX "lvm_" /* ls name is prefix + vg_name */
/* global lockspace name for sanlock is a vg name */
@@ -30,7 +29,6 @@ enum {
LD_LM_UNUSED = 1, /* place holder so values match lib/locking/lvmlockd.h */
LD_LM_DLM = 2,
LD_LM_SANLOCK = 3,
LD_LM_IDM = 4,
};
/* operation types */
@@ -120,11 +118,6 @@ struct client {
*/
#define DEFAULT_MAX_RETRIES 4
struct pvs {
char **path;
int num;
};
struct action {
struct list_head list;
uint32_t client_id;
@@ -147,7 +140,6 @@ struct action {
char vg_args[MAX_ARGS+1];
char lv_args[MAX_ARGS+1];
char vg_sysid[MAX_NAME+1];
struct pvs pvs; /* PV list for idm */
};
struct resource {
@@ -192,7 +184,6 @@ struct lockspace {
uint64_t free_lock_offset; /* for sanlock, start search for free lock here */
int free_lock_sector_size; /* for sanlock */
int free_lock_align_size; /* for sanlock */
struct pvs pvs; /* for idm: PV list */
uint32_t start_client_id; /* client_id that started the lockspace */
pthread_t thread; /* makes synchronous lock requests */
@@ -334,13 +325,10 @@ static inline int list_empty(const struct list_head *head)
EXTERN int gl_type_static;
EXTERN int gl_use_dlm;
EXTERN int gl_use_sanlock;
EXTERN int gl_use_idm;
EXTERN int gl_vg_removed;
EXTERN char gl_lsname_dlm[MAX_NAME+1];
EXTERN char gl_lsname_sanlock[MAX_NAME+1];
EXTERN char gl_lsname_idm[MAX_NAME+1];
EXTERN int global_dlm_lockspace_exists;
EXTERN int global_idm_lockspace_exists;
EXTERN int daemon_test; /* run as much as possible without a live lock manager */
EXTERN int daemon_debug;
@@ -631,102 +619,4 @@ static inline int lm_support_sanlock(void)
#endif /* sanlock support */
#ifdef LOCKDIDM_SUPPORT
int lm_data_size_idm(void);
int lm_init_vg_idm(char *ls_name, char *vg_name, uint32_t flags, char *vg_args);
int lm_prepare_lockspace_idm(struct lockspace *ls);
int lm_add_lockspace_idm(struct lockspace *ls, int adopt);
int lm_rem_lockspace_idm(struct lockspace *ls, int free_vg);
int lm_lock_idm(struct lockspace *ls, struct resource *r, int ld_mode,
struct val_blk *vb_out, char *lv_uuid, struct pvs *pvs,
int adopt);
int lm_convert_idm(struct lockspace *ls, struct resource *r,
int ld_mode, uint32_t r_version);
int lm_unlock_idm(struct lockspace *ls, struct resource *r,
uint32_t r_version, uint32_t lmu_flags);
int lm_hosts_idm(struct lockspace *ls, int notify);
int lm_get_lockspaces_idm(struct list_head *ls_rejoin);
int lm_is_running_idm(void);
int lm_rem_resource_idm(struct lockspace *ls, struct resource *r);
static inline int lm_support_idm(void)
{
return 1;
}
#else
static inline int lm_data_size_idm(void)
{
return -1;
}
static inline int lm_init_vg_idm(char *ls_name, char *vg_name, uint32_t flags,
char *vg_args)
{
return -1;
}
static inline int lm_prepare_lockspace_idm(struct lockspace *ls)
{
return -1;
}
static inline int lm_add_lockspace_idm(struct lockspace *ls, int adopt)
{
return -1;
}
static inline int lm_rem_lockspace_idm(struct lockspace *ls, int free_vg)
{
return -1;
}
static inline int lm_lock_idm(struct lockspace *ls, struct resource *r, int ld_mode,
struct val_blk *vb_out, char *lv_uuid, struct pvs *pvs,
int adopt)
{
return -1;
}
static inline int lm_convert_idm(struct lockspace *ls, struct resource *r,
int ld_mode, uint32_t r_version)
{
return -1;
}
static inline int lm_unlock_idm(struct lockspace *ls, struct resource *r,
uint32_t r_version, uint32_t lmu_flags)
{
return -1;
}
static inline int lm_hosts_idm(struct lockspace *ls, int notify)
{
return -1;
}
static inline int lm_get_lockspaces_idm(struct list_head *ls_rejoin)
{
return -1;
}
static inline int lm_is_running_idm(void)
{
return 0;
}
static inline int lm_rem_resource_idm(struct lockspace *ls, struct resource *r)
{
return -1;
}
static inline int lm_support_idm(void)
{
return 0;
}
#endif /* Seagate IDM support */
#endif /* _LVM_LVMLOCKD_INTERNAL_H */

View File

@@ -1503,7 +1503,8 @@ out:
fail:
if (lms && lms->sock)
close(lms->sock);
free(lms);
if (lms)
free(lms);
return ret;
}
@@ -1633,7 +1634,8 @@ int lm_rem_resource_sanlock(struct lockspace *ls, struct resource *r)
/* FIXME: assert r->mode == UN or unlock if it's not? */
free(rds->vb);
if (rds->vb)
free(rds->vb);
memset(rds, 0, sizeof(struct rd_sanlock));
r->lm_init = 0;

View File

@@ -19,11 +19,12 @@ SOURCES = lvmpolld-core.c lvmpolld-data-utils.c lvmpolld-cmd-utils.c
TARGETS = lvmpolld
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
CFLOW_TARGET := $(TARGETS)
.PHONY: install_lvmpolld
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
CFLOW_TARGET = lvmpolld
include $(top_builddir)/make.tmpl
CFLAGS += $(EXTRA_EXEC_CFLAGS)

View File

@@ -92,12 +92,6 @@ const char **cmdargv_ctr(const struct lvmpolld_lv *pdlv, const char *lvm_binary,
if (!add_to_cmd_arr(&cmd_argv, "-An", &i))
goto err;
if (pdlv->devicesfile) {
if (!add_to_cmd_arr(&cmd_argv, "--devicesfile", &i) ||
!add_to_cmd_arr(&cmd_argv, pdlv->devicesfile, &i))
goto err;
}
/* terminating NULL */
if (!add_to_cmd_arr(&cmd_argv, NULL, &i))
goto err;

View File

@@ -149,7 +149,7 @@ static void _lvmpolld_global_unlock(struct lvmpolld_state *ls)
static int _fini(struct daemon_state *s)
{
int done;
const struct timespec t = { .tv_nsec = 10000000 }; /* .01 sec */
const struct timespec t = { .tv_nsec = 250000000 }; /* .25 sec */
struct lvmpolld_state *ls = s->private;
DEBUGLOG(s, "fini");
@@ -236,7 +236,9 @@ static int poll_for_output(struct lvmpolld_lv *pdlv, struct lvmpolld_thread_data
}
while (1) {
r = poll(fds, 2, pdlv_get_timeout(pdlv) * 1000);
do {
r = poll(fds, 2, pdlv_get_timeout(pdlv) * 1000);
} while (r < 0 && errno == EINTR);
DEBUGLOG(pdlv->ls, "%s: %s %d", PD_LOG_PREFIX, "poll() returned", r);
if (r < 0) {
@@ -553,15 +555,14 @@ static struct lvmpolld_lv *construct_pdlv(request req, struct lvmpolld_state *ls
const char *interval, const char *id,
const char *vgname, const char *lvname,
const char *sysdir, enum poll_type type,
unsigned abort_polling, unsigned uinterval,
const char *devicesfile)
unsigned abort_polling, unsigned uinterval)
{
const char **cmdargv, **cmdenvp;
struct lvmpolld_lv *pdlv;
unsigned handle_missing_pvs = daemon_request_int(req, LVMPD_PARM_HANDLE_MISSING_PVS, 0);
pdlv = pdlv_create(ls, id, vgname, lvname, sysdir, type,
interval, uinterval, pdst, devicesfile);
interval, uinterval, pdst);
if (!pdlv) {
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "failed to create internal LV data structure.");
@@ -620,7 +621,6 @@ static response poll_init(client_handle h, struct lvmpolld_state *ls, request re
const char *lvname = daemon_request_str(req, LVMPD_PARM_LVNAME, NULL);
const char *vgname = daemon_request_str(req, LVMPD_PARM_VGNAME, NULL);
const char *sysdir = daemon_request_str(req, LVMPD_PARM_SYSDIR, NULL);
const char *devicesfile = daemon_request_str(req, LVMPD_PARM_DEVICESFILE, NULL);
unsigned abort_polling = daemon_request_int(req, LVMPD_PARM_ABORT, 0);
assert(type < POLL_TYPE_MAX);
@@ -680,7 +680,7 @@ static response poll_init(client_handle h, struct lvmpolld_state *ls, request re
pdlv->init_rq_count++; /* safe. protected by store lock */
} else {
pdlv = construct_pdlv(req, ls, pdst, interval, id, vgname,
lvname, sysdir, type, abort_polling, 2 * uinterval, devicesfile);
lvname, sysdir, type, abort_polling, 2 * uinterval);
if (!pdlv) {
pdst_unlock(pdst);
free(id);

View File

@@ -93,13 +93,11 @@ struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
const char *vgname, const char *lvname,
const char *sysdir, enum poll_type type,
const char *sinterval, unsigned pdtimeout,
struct lvmpolld_store *pdst,
const char *devicesfile)
struct lvmpolld_store *pdst)
{
char *lvmpolld_id = strdup(id), /* copy */
*full_lvname = _construct_full_lvname(vgname, lvname), /* copy */
*lvm_system_dir_env = _construct_lvm_system_dir_env(sysdir); /* copy */
char *devicesfile_dup = devicesfile ? strdup(devicesfile) : NULL;
struct lvmpolld_lv tmp = {
.ls = ls,
@@ -107,7 +105,6 @@ struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
.lvmpolld_id = lvmpolld_id,
.lvid = _get_lvid(lvmpolld_id, sysdir),
.lvname = full_lvname,
.devicesfile = devicesfile_dup,
.lvm_system_dir_env = lvm_system_dir_env,
.sinterval = strdup(sinterval), /* copy */
.pdtimeout = pdtimeout < MIN_POLLING_TIMEOUT ? MIN_POLLING_TIMEOUT : pdtimeout,
@@ -127,7 +124,6 @@ struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
return pdlv;
err:
free((void *)devicesfile_dup);
free((void *)full_lvname);
free((void *)lvmpolld_id);
free((void *)lvm_system_dir_env);
@@ -140,7 +136,6 @@ err:
void pdlv_destroy(struct lvmpolld_lv *pdlv)
{
free((void *)pdlv->lvmpolld_id);
free((void *)pdlv->devicesfile);
free((void *)pdlv->lvname);
free((void *)pdlv->sinterval);
free((void *)pdlv->lvm_system_dir_env);

View File

@@ -49,7 +49,6 @@ struct lvmpolld_lv {
const enum poll_type type;
const char *const lvid;
const char *const lvmpolld_id;
const char *const devicesfile;
const char *const lvname; /* full vg/lv name */
const unsigned pdtimeout; /* in seconds */
const char *const sinterval;
@@ -102,8 +101,7 @@ struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
const char *vgname, const char *lvname,
const char *sysdir, enum poll_type type,
const char *sinterval, unsigned pdtimeout,
struct lvmpolld_store *pdst,
const char *devicesfile);
struct lvmpolld_store *pdst);
/* only call with appropriate struct lvmpolld_store lock held */
void pdlv_destroy(struct lvmpolld_lv *pdlv);

View File

@@ -35,7 +35,6 @@
#define LVMPD_PARM_SYSDIR "sysdir"
#define LVMPD_PARM_VALUE "value" /* either retcode or signal value */
#define LVMPD_PARM_VGNAME "vgname"
#define LVMPD_PARM_DEVICESFILE "devicesfile"
#define LVMPD_RESP_FAILED "failed"
#define LVMPD_RESP_FINISHED "finished"

View File

@@ -1072,10 +1072,10 @@ int dm_tree_node_add_replicator_dev_target(struct dm_tree_node *node,
#define DM_THIN_MIN_DATA_BLOCK_SIZE (UINT32_C(128))
#define DM_THIN_MAX_DATA_BLOCK_SIZE (UINT32_C(2097152))
/*
* Max supported size for thin pool metadata device (17045913600 bytes)
* Max supported size for thin pool metadata device (17112760320 bytes)
* Limitation is hardcoded into the kernel and bigger device size
* is not accepted.
* drivers/md/dm-thin-metadata.h THIN_METADATA_MAX_SECTORS
* But here DM_THIN_MAX_METADATA_SIZE got defined incorrectly
* Correct size is (UINT64_C(255) * ((1 << 14) - 64) * (4096 / (1 << 9)))
*/
#define DM_THIN_MAX_METADATA_SIZE (UINT64_C(255) * (1 << 14) * (4096 / (1 << 9)) - 256 * 1024)
@@ -1088,16 +1088,6 @@ int dm_tree_node_add_thin_pool_target(struct dm_tree_node *node,
uint64_t low_water_mark,
unsigned skip_block_zeroing);
int dm_tree_node_add_thin_pool_target_v1(struct dm_tree_node *node,
uint64_t size,
uint64_t transaction_id,
const char *metadata_uuid,
const char *pool_uuid,
uint32_t data_block_size,
uint64_t low_water_mark,
unsigned skip_block_zeroing,
unsigned crop_metadata);
/* Supported messages for thin provision target */
typedef enum {
DM_THIN_MESSAGE_CREATE_SNAP, /* device_id, origin_id */

View File

@@ -242,3 +242,18 @@ bad:
}
return NULL;
}
#if defined(__GNUC__)
/*
* Maintain backward compatibility with older versions that did not
* accept a 'min_num_bits' argument to dm_bitset_parse_list().
*/
dm_bitset_t dm_bitset_parse_list_v1_02_129(const char *str, struct dm_pool *mem);
dm_bitset_t dm_bitset_parse_list_v1_02_129(const char *str, struct dm_pool *mem)
{
return dm_bitset_parse_list(str, mem, 0);
}
#else /* if defined(__GNUC__) */
#endif

View File

@@ -493,10 +493,7 @@ static void _dm_task_free_targets(struct dm_task *dmt)
for (t = dmt->head; t; t = n) {
n = t->next;
if (dmt->secure_data)
_dm_zfree_string(t->params);
else
free(t->params);
_dm_zfree_string(t->params);
free(t->type);
free(t);
}
@@ -507,10 +504,7 @@ static void _dm_task_free_targets(struct dm_task *dmt)
void dm_task_destroy(struct dm_task *dmt)
{
_dm_task_free_targets(dmt);
if (dmt->secure_data)
_dm_zfree_dmi(dmt->dmi.v4);
else
free(dmt->dmi.v4);
_dm_zfree_dmi(dmt->dmi.v4);
free(dmt->dev_name);
free(dmt->mangled_dev_name);
free(dmt->newname);
@@ -1118,7 +1112,7 @@ static int _add_params(int type)
static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
{
size_t min_size;
const size_t min_size = 16 * 1024;
const int (*version)[3];
struct dm_ioctl *dmi;
@@ -1137,18 +1131,6 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
else if (dmt->head)
log_debug_activation(INTERNAL_ERROR "dm '%s' ioctl should not define parameters.",
_cmd_data_v4[dmt->type].name);
switch (dmt->type) {
case DM_DEVICE_CREATE:
case DM_DEVICE_DEPS:
case DM_DEVICE_LIST:
case DM_DEVICE_STATUS:
case DM_DEVICE_TABLE:
case DM_DEVICE_TARGET_MSG:
min_size = 16 * 1024;
break;
default:
min_size = 2 * 1024;
}
if (count && (dmt->sector || dmt->message)) {
log_error("targets and message are incompatible");
@@ -1352,7 +1334,7 @@ static int _process_mapper_dir(struct dm_task *dmt)
}
if (closedir(d))
log_sys_debug("closedir", dir);
log_sys_error("closedir", dir);
return r;
}
@@ -1600,30 +1582,23 @@ static int _reload_with_suppression_v4(struct dm_task *dmt)
t2->params[len] = '\0';
if (t1->start != t2->start) {
log_debug("reload %u:%u diff start %llu %llu type %s %s", task->major, task->minor,
(unsigned long long)t1->start, (unsigned long long)t2->start, t1->type, t2->type);
log_debug("reload %u:%u start diff", task->major, task->minor);
goto no_match;
}
if (t1->length != t2->length) {
log_debug("reload %u:%u diff length %llu %llu type %s %s", task->major, task->minor,
(unsigned long long)t1->length, (unsigned long long)t2->length, t1->type, t2->type);
log_debug("reload %u:%u length diff", task->major, task->minor);
goto no_match;
}
if (strcmp(t1->type, t2->type)) {
log_debug("reload %u:%u diff type %s %s", task->major, task->minor, t1->type, t2->type);
log_debug("reload %u:%u type diff %s %s", task->major, task->minor, t1->type, t2->type);
goto no_match;
}
if (strcmp(t1->params, t2->params)) {
if (dmt->skip_reload_params_compare) {
log_debug("reload %u:%u diff params ignore for type %s",
task->major, task->minor, t1->type);
log_debug("reload params1 %s", t1->params);
log_debug("reload params2 %s", t2->params);
} else {
log_debug("reload %u:%u diff params for type %s",
task->major, task->minor, t1->type);
log_debug("reload params1 %s", t1->params);
log_debug("reload params2 %s", t2->params);
if (dmt->skip_reload_params_compare)
log_debug("reload %u:%u skip params ignore %s %s",
task->major, task->minor, t1->params, t2->params);
else {
log_debug("reload %u:%u params diff", task->major, task->minor);
goto no_match;
}
}
@@ -2209,3 +2184,52 @@ void dm_lib_exit(void)
_version_ok = 1;
_version_checked = 0;
}
#if defined(__GNUC__)
/*
* Maintain binary backward compatibility.
* Version script mechanism works with 'gcc' compatible compilers only.
*/
/*
* This following code is here to retain ABI compatibility after adding
* the field deferred_remove to struct dm_info in version 1.02.89.
*
* Binaries linked against version 1.02.88 of libdevmapper or earlier
* will use this function that returns dm_info without the
* deferred_remove field.
*
* Binaries compiled against version 1.02.89 onwards will use
* the new function dm_task_get_info_with_deferred_remove due to the
* #define.
*
* N.B. Keep this function at the end of the file to make sure that
* no code in this file accidentally calls it.
*/
int dm_task_get_info_base(struct dm_task *dmt, struct dm_info *info);
int dm_task_get_info_base(struct dm_task *dmt, struct dm_info *info)
{
struct dm_info new_info;
if (!dm_task_get_info(dmt, &new_info))
return 0;
memcpy(info, &new_info, offsetof(struct dm_info, deferred_remove));
return 1;
}
int dm_task_get_info_with_deferred_remove(struct dm_task *dmt, struct dm_info *info);
int dm_task_get_info_with_deferred_remove(struct dm_task *dmt, struct dm_info *info)
{
struct dm_info new_info;
if (!dm_task_get_info(dmt, &new_info))
return 0;
memcpy(info, &new_info, offsetof(struct dm_info, internal_suspend));
return 1;
}
#endif

View File

@@ -382,7 +382,7 @@ static int _find_dm_name_of_device(dev_t st_rdev, char *buf, size_t buf_len)
}
if (closedir(d))
log_sys_debug("closedir", _dm_dir);
log_sys_error("closedir", _dm_dir);
return r;
}
@@ -931,7 +931,7 @@ int dm_task_add_target(struct dm_task *dmt, uint64_t start, uint64_t size,
#ifdef HAVE_SELINUX
static int _selabel_lookup(const char *path, mode_t mode,
char **scontext)
security_context_t *scontext)
{
#ifdef HAVE_SELINUX_LABEL_H
if (!_selabel_handle &&
@@ -974,7 +974,7 @@ static int _is_selinux_enabled(void)
int dm_prepare_selinux_context(const char *path, mode_t mode)
{
#ifdef HAVE_SELINUX
char *scontext = NULL;
security_context_t scontext = NULL;
if (_is_selinux_enabled() <= 0)
return 1;
@@ -1002,7 +1002,7 @@ int dm_prepare_selinux_context(const char *path, mode_t mode)
int dm_set_selinux_context(const char *path, mode_t mode)
{
#ifdef HAVE_SELINUX
char *scontext = NULL;
security_context_t scontext = NULL;
if (_is_selinux_enabled() <= 0)
return 1;
@@ -1224,7 +1224,7 @@ int get_dev_node_read_ahead(const char *dev_name, uint32_t major, uint32_t minor
int len;
int r = 1;
int fd;
long read_ahead_long = 0;
long read_ahead_long;
/*
* If we know the device number, use sysfs if we can.

View File

@@ -599,7 +599,7 @@ static struct dm_config_node *_section(struct parser *p, struct dm_config_node *
match(TOK_IDENTIFIER);
}
if (!*str) {
if (!strlen(str)) {
log_error("Parse error at byte %" PRIptrdiff_t " (line %d): empty section identifier",
p->tb - p->fb + 1, p->line);
return NULL;
@@ -983,7 +983,7 @@ static const char *_find_config_str(const void *start, node_lookup_fn find_fn,
}
if (fail)
log_very_verbose("%s not found in config: defaulting to \"%s\"",
log_very_verbose("%s not found in config: defaulting to %s",
path, fail);
return fail;
}

View File

@@ -380,13 +380,13 @@ struct dm_tree *dm_tree_create(void)
dtree->mem = dmem;
dtree->optional_uuid_suffixes = NULL;
if (!(dtree->devs = dm_hash_create(61))) {
if (!(dtree->devs = dm_hash_create(8))) {
log_error("dtree hash creation failed");
dm_pool_destroy(dtree->mem);
return NULL;
}
if (!(dtree->uuids = dm_hash_create(31))) {
if (!(dtree->uuids = dm_hash_create(32))) {
log_error("dtree uuid hash creation failed");
dm_hash_destroy(dtree->devs);
dm_pool_destroy(dtree->mem);
@@ -2382,7 +2382,7 @@ static int _mirror_emit_segment_line(struct dm_task *dmt, struct load_segment *s
EMIT_PARAMS(pos, " %u ", seg->mirror_area_count);
if (!_emit_areas_line(dmt, seg, params, paramsize, &pos))
if (_emit_areas_line(dmt, seg, params, paramsize, &pos) <= 0)
return_0;
if (handle_errors)
@@ -2584,7 +2584,7 @@ static int _raid_emit_segment_line(struct dm_task *dmt, uint32_t major,
/* Print number of metadata/data device pairs */
EMIT_PARAMS(pos, " %u", area_count);
if (!_emit_areas_line(dmt, seg, params, paramsize, &pos))
if (_emit_areas_line(dmt, seg, params, paramsize, &pos) <= 0)
return_0;
return 1;
@@ -2824,9 +2824,6 @@ static int _integrity_emit_segment_line(struct dm_task *dmt,
if (set->sectors_per_bit_set)
EMIT_PARAMS(pos, " sectors_per_bit:%llu", (unsigned long long)set->sectors_per_bit);
if (!dm_task_secure_data(dmt))
stack;
return 1;
}
@@ -2930,6 +2927,7 @@ static int _emit_segment_line(struct dm_task *dmt, uint32_t major,
size_t paramsize)
{
int pos = 0;
int r;
int target_type_is_raid = 0;
char originbuf[DM_FORMAT_DEV_BUFSIZE], cowbuf[DM_FORMAT_DEV_BUFSIZE];
@@ -2940,7 +2938,8 @@ static int _emit_segment_line(struct dm_task *dmt, uint32_t major,
break;
case SEG_MIRRORED:
/* Mirrors are pretty complicated - now in separate function */
if (!_mirror_emit_segment_line(dmt, seg, params, paramsize))
r = _mirror_emit_segment_line(dmt, seg, params, paramsize);
if (!r)
return_0;
break;
case SEG_SNAPSHOT:
@@ -2961,7 +2960,7 @@ static int _emit_segment_line(struct dm_task *dmt, uint32_t major,
EMIT_PARAMS(pos, "%u %u ", seg->area_count, seg->stripe_size);
break;
case SEG_VDO:
if (!_vdo_emit_segment_line(dmt, seg, params, paramsize))
if (!(r = _vdo_emit_segment_line(dmt, seg, params, paramsize)))
return_0;
break;
case SEG_CRYPT:
@@ -2990,8 +2989,9 @@ static int _emit_segment_line(struct dm_task *dmt, uint32_t major,
case SEG_RAID6_LA_6:
case SEG_RAID6_RA_6:
target_type_is_raid = 1;
if (!_raid_emit_segment_line(dmt, major, minor, seg, seg_start,
params, paramsize))
r = _raid_emit_segment_line(dmt, major, minor, seg, seg_start,
params, paramsize);
if (!r)
return_0;
break;
@@ -3032,9 +3032,10 @@ static int _emit_segment_line(struct dm_task *dmt, uint32_t major,
case SEG_CRYPT:
case SEG_LINEAR:
case SEG_STRIPED:
if (!_emit_areas_line(dmt, seg, params, paramsize, &pos))
return_0;
if ((r = _emit_areas_line(dmt, seg, params, paramsize, &pos)) <= 0) {
stack;
return r;
}
if (!params[0]) {
log_error("No parameters supplied for %s target "
"%u:%u.", _dm_segtypes[seg->type].target,
@@ -3977,24 +3978,6 @@ int dm_tree_node_add_thin_pool_target(struct dm_tree_node *node,
uint32_t data_block_size,
uint64_t low_water_mark,
unsigned skip_block_zeroing)
{
return dm_tree_node_add_thin_pool_target_v1(node, size, transaction_id,
metadata_uuid, pool_uuid,
data_block_size,
low_water_mark,
skip_block_zeroing,
1);
}
int dm_tree_node_add_thin_pool_target_v1(struct dm_tree_node *node,
uint64_t size,
uint64_t transaction_id,
const char *metadata_uuid,
const char *pool_uuid,
uint32_t data_block_size,
uint64_t low_water_mark,
unsigned skip_block_zeroing,
unsigned crop_metadata)
{
struct load_segment *seg, *mseg;
uint64_t devsize = 0;
@@ -4022,18 +4005,17 @@ int dm_tree_node_add_thin_pool_target_v1(struct dm_tree_node *node,
if (!_link_tree_nodes(node, seg->metadata))
return_0;
if (crop_metadata)
/* FIXME: more complex target may need more tweaks */
dm_list_iterate_items(mseg, &seg->metadata->props.segs) {
devsize += mseg->size;
if (devsize > DM_THIN_MAX_METADATA_SIZE) {
log_debug_activation("Ignoring %" PRIu64 " of device.",
devsize - DM_THIN_MAX_METADATA_SIZE);
mseg->size -= (devsize - DM_THIN_MAX_METADATA_SIZE);
devsize = DM_THIN_MAX_METADATA_SIZE;
/* FIXME: drop remaining segs */
}
/* FIXME: more complex target may need more tweaks */
dm_list_iterate_items(mseg, &seg->metadata->props.segs) {
devsize += mseg->size;
if (devsize > DM_THIN_MAX_METADATA_SIZE) {
log_debug_activation("Ignoring %" PRIu64 " of device.",
devsize - DM_THIN_MAX_METADATA_SIZE);
mseg->size -= (devsize - DM_THIN_MAX_METADATA_SIZE);
devsize = DM_THIN_MAX_METADATA_SIZE;
/* FIXME: drop remaining segs */
}
}
if (!(seg->pool = dm_tree_find_node_by_uuid(node->dtree, pool_uuid))) {
log_error("Missing pool uuid %s.", pool_uuid);
@@ -4328,6 +4310,61 @@ void dm_tree_node_set_callback(struct dm_tree_node *dnode,
dnode->callback_data = data;
}
#if defined(__GNUC__)
/*
* Backward compatible implementations.
*
* Keep these at the end of the file to make sure that
* no code in this file accidentally calls it.
*/
/* Backward compatible dm_tree_node_size_changed() implementations. */
int dm_tree_node_size_changed_base(const struct dm_tree_node *dnode);
int dm_tree_node_size_changed_base(const struct dm_tree_node *dnode)
{
/* Base does not make difference between smaller and bigger */
return dm_tree_node_size_changed(dnode) ? 1 : 0;
}
/*
* Retain ABI compatibility after adding the DM_CACHE_FEATURE_METADATA2
* in version 1.02.138.
*
* Binaries compiled against version 1.02.138 onwards will use
* the new function dm_tree_node_add_cache_target which detects unknown
* feature flags and returns error for them.
*/
int dm_tree_node_add_cache_target_base(struct dm_tree_node *node,
uint64_t size,
uint64_t feature_flags, /* DM_CACHE_FEATURE_* */
const char *metadata_uuid,
const char *data_uuid,
const char *origin_uuid,
const char *policy_name,
const struct dm_config_node *policy_settings,
uint32_t data_block_size);
int dm_tree_node_add_cache_target_base(struct dm_tree_node *node,
uint64_t size,
uint64_t feature_flags,
const char *metadata_uuid,
const char *data_uuid,
const char *origin_uuid,
const char *policy_name,
const struct dm_config_node *policy_settings,
uint32_t data_block_size)
{
/* Old version supported only these FEATURE bits, others were ignored so masked them */
static const uint64_t _mask =
DM_CACHE_FEATURE_WRITEBACK |
DM_CACHE_FEATURE_WRITETHROUGH |
DM_CACHE_FEATURE_PASSTHROUGH;
return dm_tree_node_add_cache_target(node, size, feature_flags & _mask,
metadata_uuid, data_uuid, origin_uuid,
policy_name, policy_settings, 0, 0, 0, 0, data_block_size);
}
#endif
int dm_tree_node_add_vdo_target(struct dm_tree_node *node,
uint64_t size,
const char *vdo_pool_name,

View File

@@ -110,7 +110,7 @@ int dm_is_empty_dir(const char *dir)
DIR *d;
if (!(d = opendir(dir))) {
log_sys_debug("opendir", dir);
log_sys_error("opendir", dir);
return 0;
}
@@ -119,7 +119,7 @@ int dm_is_empty_dir(const char *dir)
break;
if (closedir(d))
log_sys_debug("closedir", dir);
log_sys_error("closedir", dir);
return dirent ? 0 : 1;
}

View File

@@ -492,7 +492,7 @@ static int _report_field_string_list(struct dm_report *rh,
delimiter = ",";
delimiter_len = strlen(delimiter);
i = pos = 0;
i = pos = len = 0;
dm_list_iterate_items(sl, data) {
arr[i].str = sl->str;
if (!sort) {
@@ -2474,7 +2474,7 @@ dm_percent_t dm_make_percent(uint64_t numerator, uint64_t denominator)
int dm_report_value_cache_set(struct dm_report *rh, const char *name, const void *data)
{
if (!rh->value_cache && (!(rh->value_cache = dm_hash_create(63)))) {
if (!rh->value_cache && (!(rh->value_cache = dm_hash_create(64)))) {
log_error("Failed to create cache for values used during reporting.");
return 0;
}
@@ -3774,7 +3774,7 @@ static struct selection_node *_parse_selection(struct dm_report *rh,
struct field_selection *fs;
struct selection_node *sn;
const char *ws, *we; /* field name */
const char *vs = NULL, *ve = NULL; /* value */
const char *vs, *ve; /* value */
const char *last;
uint32_t flags, field_num;
int implicit;

View File

@@ -94,7 +94,7 @@ journal_watermark:number
commit_time:number
Commit time in milliseconds. When this time passes, the journal is
written. The journal is also written immediately if the FLUSH
written. The journal is also written immediatelly if the FLUSH
request is received.
internal_hash:algorithm(:key) (the key is optional)

2
include/.gitignore vendored
View File

@@ -1,3 +1 @@
*.h
.symlinks
.symlinks_created

View File

@@ -132,9 +132,6 @@
/* Path to fsadm binary. */
#undef FSADM_PATH
/* Define to use GNU versioning in the shared library. */
#undef GNU_SYMVER
/* Define to 1 if you have the `alarm' function. */
#undef HAVE_ALARM
@@ -185,6 +182,9 @@
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
#undef HAVE_DOPRNT
/* Define to 1 if you have the <editline/history.h> header file. */
#undef HAVE_EDITLINE_HISTORY_H
/* Define to 1 if you have the <editline/readline.h> header file. */
#undef HAVE_EDITLINE_READLINE_H
@@ -561,9 +561,6 @@
/* Define to 1 to include code that uses lvmlockd sanlock option. */
#undef LOCKDSANLOCK_SUPPORT
/* Define to 1 to include code that uses lvmlockd IDM option. */
#undef LOCKDIDM_SUPPORT
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
slash. */
#undef LSTAT_FOLLOWS_SLASHED_SYMLINK

View File

@@ -15,7 +15,6 @@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
abs_srcdir = @abs_srcdir@
SOURCES =\
activate/activate.c \
@@ -30,7 +29,6 @@ SOURCES =\
device/bcache.c \
device/bcache-utils.c \
device/dev-cache.c \
device/device_id.c \
device/dev-ext.c \
device/dev-io.c \
device/dev-md.c \
@@ -54,7 +52,6 @@ SOURCES =\
filters/filter-usable.c \
filters/filter-internal.c \
filters/filter-signature.c \
filters/filter-deviceid.c \
format_text/archive.c \
format_text/archiver.c \
format_text/export.c \

View File

@@ -29,7 +29,6 @@
#include "lib/metadata/segtype.h"
#include "lib/misc/sharedlib.h"
#include "lib/metadata/metadata.h"
#include "lib/misc/lvm-signal.h"
#include <limits.h>
#include <fcntl.h>
@@ -178,22 +177,6 @@ int lv_passes_auto_activation_filter(struct cmd_context *cmd, struct logical_vol
return _lv_passes_volumes_filter(cmd, lv, cn, activation_auto_activation_volume_list_CFG);
}
static int _passes_readonly_filter(struct cmd_context *cmd,
const struct logical_volume *lv)
{
const struct dm_config_node *cn;
if (!(cn = find_config_tree_array(cmd, activation_read_only_volume_list_CFG, NULL)))
return 0;
return _lv_passes_volumes_filter(cmd, lv, cn, activation_read_only_volume_list_CFG);
}
int lv_passes_readonly_filter(const struct logical_volume *lv)
{
return _passes_readonly_filter(lv->vg->cmd, lv);
}
#ifndef DEVMAPPER_SUPPORT
void set_activation(int act, int silent)
{
@@ -291,10 +274,6 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg)
{
return 0;
}
int lv_raid_status(const struct logical_volume *lv, struct lv_status_raid **status)
{
return 0;
}
int lv_writecache_message(const struct logical_volume *lv, const char *msg)
{
return 0;
@@ -413,7 +392,7 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
{
return 0;
}
int device_is_usable(struct device *dev, struct dev_usable_check_params check, int *is_lv)
int device_is_usable(struct device *dev, struct dev_usable_check_params check)
{
return 0;
}
@@ -476,6 +455,17 @@ static int _passes_activation_filter(struct cmd_context *cmd,
return _lv_passes_volumes_filter(cmd, lv, cn, activation_volume_list_CFG);
}
static int _passes_readonly_filter(struct cmd_context *cmd,
const struct logical_volume *lv)
{
const struct dm_config_node *cn;
if (!(cn = find_config_tree_array(cmd, activation_read_only_volume_list_CFG, NULL)))
return 0;
return _lv_passes_volumes_filter(cmd, lv, cn, activation_read_only_volume_list_CFG);
}
int library_version(char *version, size_t size)
{
if (!activation())
@@ -574,9 +564,13 @@ int module_present(struct cmd_context *cmd, const char *target_name)
}
#ifdef MODPROBE_CMD
if (strcmp(target_name, TARGET_NAME_VDO) == 0)
argv[1] = MODULE_NAME_VDO; /* ATM kvdo is without dm- prefix */
else if (dm_snprintf(module, sizeof(module), "dm-%s", target_name) < 0) {
if (strcmp(target_name, MODULE_NAME_VDO) == 0) {
argv[1] = target_name; /* ATM kvdo is without dm- prefix */
if ((ret = exec_cmd(cmd, argv, NULL, 0)))
return ret;
}
if (dm_snprintf(module, sizeof(module), "dm-%s", target_name) < 0) {
log_error("module_present module name too long: %s",
target_name);
return 0;
@@ -829,15 +823,12 @@ int lv_info_with_seg_status(struct cmd_context *cmd,
#define OPEN_COUNT_CHECK_USLEEP_DELAY 200000
/* Only report error if error_if_used is set */
/* Returns 0 if in use, 1 if it is unused, 2 when it is not present in table */
int lv_check_not_in_use(const struct logical_volume *lv, int error_if_used)
{
struct lvinfo info;
unsigned int open_count_check_retries;
if (!lv_info(lv->vg->cmd, lv, 0, &info, 1, 0) || !info.exists)
return 2;
else if (!info.open_count)
if (!lv_info(lv->vg->cmd, lv, 0, &info, 1, 0) || !info.exists || !info.open_count)
return 1;
/* If sysfs is not used, use open_count information only. */
@@ -864,24 +855,25 @@ int lv_check_not_in_use(const struct logical_volume *lv, int error_if_used)
}
open_count_check_retries = retry_deactivation() ? OPEN_COUNT_CHECK_RETRIES : 1;
while (open_count_check_retries--) {
if (interruptible_usleep(OPEN_COUNT_CHECK_USLEEP_DELAY))
break; /* interrupted */
while (info.open_count > 0 && open_count_check_retries--) {
if (!open_count_check_retries) {
if (error_if_used)
log_error("Logical volume %s in use.", display_lvname(lv));
else
log_debug_activation("Logical volume %s in use.", display_lvname(lv));
return 0;
}
usleep(OPEN_COUNT_CHECK_USLEEP_DELAY);
log_debug_activation("Retrying open_count check for %s.",
display_lvname(lv));
if (!lv_info(lv->vg->cmd, lv, 0, &info, 1, 0) || !info.exists) {
if (!lv_info(lv->vg->cmd, lv, 0, &info, 1, 0)) {
stack; /* device dissappeared? */
return 1;
} else if (!info.open_count)
return 1;
break;
}
}
if (error_if_used)
log_error("Logical volume %s in use.", display_lvname(lv));
else
log_debug_activation("Logical volume %s in use.", display_lvname(lv));
return 0;
return 1;
}
/*
@@ -972,28 +964,35 @@ int lv_raid_percent(const struct logical_volume *lv, dm_percent_t *percent)
int lv_raid_data_offset(const struct logical_volume *lv, uint64_t *data_offset)
{
struct lv_status_raid *raid_status;
int r;
struct dev_manager *dm;
struct dm_status_raid *status;
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
return 0;
log_debug_activation("Checking raid data offset and dev sectors for LV %s/%s",
lv->vg->name, lv->name);
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
if (!lv_raid_status(lv, &raid_status))
return_0;
if (!(r = dev_manager_raid_status(dm, lv, &status))) {
dev_manager_destroy(dm);
return_0;
}
*data_offset = raid_status->raid->data_offset;
*data_offset = status->data_offset;
dm_pool_destroy(raid_status->mem);
dev_manager_destroy(dm);
return 1;
return r;
}
int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health)
{
int r = 1;
struct lv_status_raid *raid_status;
int r;
struct dev_manager *dm;
struct dm_status_raid *status;
*dev_health = NULL;
@@ -1003,23 +1002,25 @@ int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health)
log_debug_activation("Checking raid device health for LV %s.",
display_lvname(lv));
if (!lv_raid_status(lv, &raid_status))
return_0;
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
if (!(*dev_health = dm_pool_strdup(lv->vg->cmd->mem,
raid_status->raid->dev_health))) {
stack;
r = 0;
if (!(r = dev_manager_raid_status(dm, lv, &status)) ||
!(*dev_health = dm_pool_strdup(lv->vg->cmd->mem,
status->dev_health))) {
dev_manager_destroy(dm);
return_0;
}
dm_pool_destroy(raid_status->mem);
dev_manager_destroy(dm);
return r;
}
int lv_raid_dev_count(const struct logical_volume *lv, uint32_t *dev_cnt)
{
struct lv_status_raid *raid_status;
struct dev_manager *dm;
struct dm_status_raid *status;
*dev_cnt = 0;
@@ -1028,20 +1029,24 @@ int lv_raid_dev_count(const struct logical_volume *lv, uint32_t *dev_cnt)
log_debug_activation("Checking raid device count for LV %s/%s",
lv->vg->name, lv->name);
if (!lv_raid_status(lv, &raid_status))
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
*dev_cnt = raid_status->raid->dev_count;
if (!dev_manager_raid_status(dm, lv, &status)) {
dev_manager_destroy(dm);
return_0;
}
*dev_cnt = status->dev_count;
dm_pool_destroy(raid_status->mem);
dev_manager_destroy(dm);
return 1;
}
int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt)
{
struct lv_status_raid *raid_status;
struct dev_manager *dm;
struct dm_status_raid *status;
*cnt = 0;
@@ -1051,20 +1056,25 @@ int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt)
log_debug_activation("Checking raid mismatch count for LV %s.",
display_lvname(lv));
if (!lv_raid_status(lv, &raid_status))
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
*cnt = raid_status->raid->mismatch_count;
if (!dev_manager_raid_status(dm, lv, &status)) {
dev_manager_destroy(dm);
return_0;
}
*cnt = status->mismatch_count;
dm_pool_destroy(raid_status->mem);
dev_manager_destroy(dm);
return 1;
}
int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action)
{
struct lv_status_raid *raid_status;
int r = 1;
struct dev_manager *dm;
struct dm_status_raid *status;
char *action;
*sync_action = NULL;
@@ -1074,27 +1084,30 @@ int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action)
log_debug_activation("Checking raid sync_action for LV %s.",
display_lvname(lv));
if (!lv_raid_status(lv, &raid_status))
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
/* status->sync_action can be NULL if dm-raid version < 1.5.0 */
if (!raid_status->raid->sync_action ||
!(*sync_action = dm_pool_strdup(lv->vg->cmd->mem,
raid_status->raid->sync_action))) {
stack;
r = 0;
if (!dev_manager_raid_status(dm, lv, &status) ||
!status->sync_action ||
!(action = dm_pool_strdup(lv->vg->cmd->mem,
status->sync_action))) {
dev_manager_destroy(dm);
return_0;
}
dm_pool_destroy(raid_status->mem);
*sync_action = action;
return r;
dev_manager_destroy(dm);
return 1;
}
int lv_raid_message(const struct logical_volume *lv, const char *msg)
{
struct lv_status_raid *raid_status;
struct dev_manager *dm = NULL;
int r = 0;
struct dev_manager *dm;
struct dm_status_raid *status;
if (!seg_is_raid(first_seg(lv))) {
/*
@@ -1119,10 +1132,16 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg)
return 0;
}
if (!lv_raid_status(lv, &raid_status))
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
if (!raid_status->raid->sync_action) {
if (!(r = dev_manager_raid_status(dm, lv, &status))) {
log_error("Failed to retrieve status of %s.",
display_lvname(lv));
goto out;
}
if (!status->sync_action) {
log_error("Kernel driver does not support this action: %s", msg);
goto out;
}
@@ -1144,43 +1163,19 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg)
log_error("\"%s\" is not a supported sync operation.", msg);
goto out;
}
if (strcmp(raid_status->raid->sync_action, "idle")) {
if (strcmp(status->sync_action, "idle")) {
log_error("%s state is currently \"%s\". Unable to switch to \"%s\".",
display_lvname(lv), raid_status->raid->sync_action, msg);
display_lvname(lv), status->sync_action, msg);
goto out;
}
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
r = dev_manager_raid_message(dm, lv, msg);
out:
if (dm)
dev_manager_destroy(dm);
dm_pool_destroy(raid_status->mem);
dev_manager_destroy(dm);
return r;
}
int lv_raid_status(const struct logical_volume *lv, struct lv_status_raid **status)
{
struct dev_manager *dm;
int exists;
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
if (!dev_manager_raid_status(dm, lv, status, &exists)) {
dev_manager_destroy(dm);
if (exists)
stack;
return 0;
}
/* User has to call dm_pool_destroy(status->mem)! */
return 1;
}
int lv_writecache_message(const struct logical_volume *lv, const char *msg)
{
int r = 0;
@@ -1213,7 +1208,6 @@ int lv_cache_status(const struct logical_volume *cache_lv,
{
struct dev_manager *dm;
struct lv_segment *cache_seg;
int exists;
if (lv_is_cache_pool(cache_lv)) {
if (dm_list_empty(&cache_lv->segs_using_this_lv) ||
@@ -1231,14 +1225,21 @@ int lv_cache_status(const struct logical_volume *cache_lv,
return 0;
}
if (!lv_info(cache_lv->vg->cmd, cache_lv, 1, NULL, 0, 0)) {
log_error("Cannot check status for locally inactive cache volume %s.",
display_lvname(cache_lv));
return 0;
}
log_debug_activation("Checking status for cache volume %s.",
display_lvname(cache_lv));
if (!(dm = dev_manager_create(cache_lv->vg->cmd, cache_lv->vg->name, 1)))
return_0;
if (!dev_manager_cache_status(dm, cache_lv, status, &exists)) {
if (!dev_manager_cache_status(dm, cache_lv, status)) {
dev_manager_destroy(dm);
if (exists)
stack;
return 0;
return_0;
}
/* User has to call dm_pool_destroy(status->mem)! */
@@ -1249,16 +1250,19 @@ int lv_thin_pool_status(const struct logical_volume *lv, int flush,
struct lv_status_thin_pool **thin_pool_status)
{
struct dev_manager *dm;
int exists;
if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
return 0;
log_debug_activation("Checking thin pool status for LV %s.",
display_lvname(lv));
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
if (!dev_manager_thin_pool_status(dm, lv, flush, thin_pool_status, &exists)) {
if (!dev_manager_thin_pool_status(dm, lv, flush, thin_pool_status)) {
dev_manager_destroy(dm);
if (exists)
stack;
return 0;
return_0;
}
/* User has to call dm_pool_destroy(thin_pool_status->mem)! */
@@ -1270,16 +1274,19 @@ int lv_thin_status(const struct logical_volume *lv, int flush,
struct lv_status_thin **thin_status)
{
struct dev_manager *dm;
int exists;
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
return 0;
log_debug_activation("Checking thin status for LV %s.",
display_lvname(lv));
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
if (!dev_manager_thin_status(dm, lv, flush, thin_status, &exists)) {
if (!dev_manager_thin_status(dm, lv, flush, thin_status)) {
dev_manager_destroy(dm);
if (exists)
stack;
return 0;
return_0;
}
/* User has to call dm_pool_destroy(thin_status->mem)! */
@@ -1289,16 +1296,20 @@ int lv_thin_status(const struct logical_volume *lv, int flush,
int lv_thin_device_id(const struct logical_volume *lv, uint32_t *device_id)
{
struct dev_manager *dm;
int exists;
int r;
struct dev_manager *dm;
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
return 0;
log_debug_activation("Checking device id for LV %s.",
display_lvname(lv));
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
if (!(r = dev_manager_thin_device_id(dm, lv, device_id, &exists)))
if (exists)
stack;
if (!(r = dev_manager_thin_device_id(dm, lv, device_id)))
stack;
dev_manager_destroy(dm);
@@ -1315,22 +1326,28 @@ int lv_thin_device_id(const struct logical_volume *lv, uint32_t *device_id)
int lv_vdo_pool_status(const struct logical_volume *lv, int flush,
struct lv_status_vdo **vdo_status)
{
int r = 0;
struct dev_manager *dm;
int exists;
if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
return 0;
log_debug_activation("Checking VDO pool status for LV %s.",
display_lvname(lv));
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, !lv_is_pvmove(lv))))
return_0;
if (!dev_manager_vdo_pool_status(dm, lv, flush, vdo_status, &exists)) {
dev_manager_destroy(dm);
if (exists)
stack;
return 0;
}
if (!dev_manager_vdo_pool_status(dm, lv, vdo_status, flush))
goto_out;
/* User has to call dm_pool_destroy(vdo_status->mem) */
r = 1;
out:
if (!r)
dev_manager_destroy(dm);
return 1;
return r;
}
int lv_vdo_pool_percent(const struct logical_volume *lv, dm_percent_t *percent)
@@ -2026,6 +2043,12 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
if (!activation())
return 1;
/* Ignore origin_only unless LV is origin in both old and new metadata */
/* or LV is thin or thin pool volume */
if (!lv_is_thin_volume(lv) && !lv_is_thin_pool(lv) &&
!(lv_is_origin(lv) && lv_is_origin(lv_pre)))
laopts->origin_only = 0;
if (test_mode()) {
_skip("Suspending %s%s.", display_lvname(lv),
laopts->origin_only ? " origin without snapshots" : "");
@@ -2047,12 +2070,6 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
lv_calculate_readahead(lv, NULL);
/* Ignore origin_only unless LV is origin in both old and new metadata */
/* or LV is thin or thin pool volume */
if (!lv_is_thin_volume(lv) && !lv_is_thin_pool(lv) &&
!(lv_is_origin(lv) && lv_is_origin(lv_pre)))
laopts->origin_only = 0;
/*
* Preload devices for the LV.
* If the PVMOVE LV is being removed, it's only present in the old
@@ -2386,47 +2403,44 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, const struct logi
log_debug_activation("Deactivating %s.", display_lvname(lv));
if (!lv_info(cmd, lv, 0, &info, 0, 0))
goto_out;
if (!info.exists) {
r = 1;
/* Check attached snapshot segments are also inactive */
dm_list_iterate(snh, &lv->snapshot_segs) {
if (!lv_info(cmd, dm_list_struct_base(snh, struct lv_segment, origin_list)->cow,
0, &info, 0, 0))
goto_out;
if (info.exists) {
r = 0; /* Snapshot left in table? */
break;
}
}
if (lv_is_vdo_pool(lv)) {
/* If someone has remove 'linear' mapping over VDO device
* we may still be able to deactivate the rest of the tree
* i.e. in test-suite we simulate this via 'dmsetup remove' */
if (!lv_info(cmd, lv, 1, &info, 1, 0))
goto_out;
if (info.exists && !info.open_count)
r = 0; /* Unused VDO device left in table? */
}
if (r)
goto out;
}
if (lv_is_visible(lv) || lv_is_virtual_origin(lv) ||
lv_is_merging_thin_snapshot(lv)) {
switch (lv_check_not_in_use(lv, 1)) {
case 0: goto_out;
case 2: goto no_exists;
}
if (!lv_check_not_in_use(lv, 1))
goto_out;
if (lv_is_origin(lv) && _lv_has_open_snapshots(lv))
goto_out;
} else {
if (!lv_info(cmd, lv, 0, &info, 0, 0))
goto_out;
if (!info.exists) {
no_exists:
r = 1;
/* Check attached snapshot segments are also inactive */
dm_list_iterate(snh, &lv->snapshot_segs) {
if (!lv_info(cmd, dm_list_struct_base(snh, struct lv_segment, origin_list)->cow,
0, &info, 0, 0))
goto_out;
if (info.exists) {
r = 0; /* Snapshot left in table? */
break;
}
}
if (lv_is_vdo_pool(lv)) {
/* If someone has remove 'linear' mapping over VDO device
* we may still be able to deactivate the rest of the tree
* i.e. in test-suite we simulate this via 'dmsetup remove' */
if (!lv_info(cmd, lv, 1, &info, 1, 0))
goto_out;
if (info.exists && !info.open_count)
r = 0; /* Unused VDO device left in table? */
}
if (r)
goto out;
}
}
if (!monitor_dev_for_events(cmd, lv, &laopts, 0))
@@ -2823,7 +2837,7 @@ static int _deactivate_sub_lv_cb(struct logical_volume *lv, void *data)
*/
int deactivate_lv_with_sub_lv(const struct logical_volume *lv)
{
struct logical_volume *flv = NULL;
struct logical_volume *flv;
if (!deactivate_lv(lv->vg->cmd, lv)) {
log_error("Cannot deactivate logical volume %s.",
@@ -2833,7 +2847,7 @@ int deactivate_lv_with_sub_lv(const struct logical_volume *lv)
if (!for_each_sub_lv((struct logical_volume *)lv, _deactivate_sub_lv_cb, &flv)) {
log_error("Cannot deactivate subvolume %s of logical volume %s.",
(flv) ? display_lvname(flv) : "", display_lvname(lv));
display_lvname(flv), display_lvname(lv));
return 0;
}

View File

@@ -188,7 +188,6 @@ int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health);
int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt);
int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action);
int lv_raid_message(const struct logical_volume *lv, const char *msg);
int lv_raid_status(const struct logical_volume *lv, struct lv_status_raid **status);
int lv_writecache_message(const struct logical_volume *lv, const char *msg);
int lv_cache_status(const struct logical_volume *cache_lv,
struct lv_status_cache **status);
@@ -209,8 +208,6 @@ int lvs_in_vg_opened(const struct volume_group *vg);
int lv_is_active(const struct logical_volume *lv);
int lv_passes_readonly_filter(const struct logical_volume *lv);
/* Check is any component LV is active */
const struct logical_volume *lv_component_is_active(const struct logical_volume *lv);
const struct logical_volume *lv_holder_is_active(const struct logical_volume *lv);
@@ -254,7 +251,7 @@ struct dev_usable_check_params {
* Returns 1 if mapped device is not suspended, blocked or
* is using a reserved name.
*/
int device_is_usable(struct device *dev, struct dev_usable_check_params check, int *is_lv);
int device_is_usable(struct device *dev, struct dev_usable_check_params check);
/*
* Declaration moved here from fs.h to keep header fs.h hidden

View File

@@ -26,7 +26,6 @@
#include "lib/activate/activate.h"
#include "lib/misc/lvm-exec.h"
#include "lib/datastruct/str_list.h"
#include "lib/misc/lvm-signal.h"
#include <limits.h>
#include <dirent.h>
@@ -262,7 +261,7 @@ static int _info_run(const char *dlid, struct dm_info *dminfo,
int dmtask;
int with_flush; /* TODO: arg for _info_run */
void *target = NULL;
uint64_t target_start, target_length, start, length, length_crop = 0;
uint64_t target_start, target_length, start, length;
char *target_name, *target_params;
const char *devname;
@@ -298,7 +297,7 @@ static int _info_run(const char *dlid, struct dm_info *dminfo,
/* Uses max DM_THIN_MAX_METADATA_SIZE sectors for metadata device */
if (lv_is_thin_pool_metadata(seg_status->seg->lv) &&
(length > DM_THIN_MAX_METADATA_SIZE))
length_crop = DM_THIN_MAX_METADATA_SIZE;
length = DM_THIN_MAX_METADATA_SIZE;
/* Uses virtual size with headers for VDO pool device */
if (lv_is_vdo_pool(seg_status->seg->lv))
@@ -311,9 +310,7 @@ static int _info_run(const char *dlid, struct dm_info *dminfo,
target = dm_get_next_target(dmt, target, &target_start,
&target_length, &target_name, &target_params);
if ((start == target_start) &&
((length == target_length) ||
(length_crop && (length_crop == target_length))))
if ((start == target_start) && (length == target_length))
break; /* Keep target_params when matching segment is found */
target_params = NULL; /* Marking this target_params unusable */
@@ -406,7 +403,7 @@ static int _ignore_blocked_mirror_devices(struct device *dev,
.check_blocked = 1,
.check_suspended = ignore_suspended_devices(),
.check_error_target = 1,
.check_reserved = 0 }, NULL))
.check_reserved = 0 }))
goto out; /* safe to use */
stack;
}
@@ -621,17 +618,16 @@ static int _ignore_frozen_raid(struct device *dev, const char *params)
*
* Returns: 1 if usable, 0 otherwise
*/
int device_is_usable(struct device *dev, struct dev_usable_check_params check, int *is_lv)
int device_is_usable(struct device *dev, struct dev_usable_check_params check)
{
struct dm_task *dmt;
struct dm_info info;
const char *name, *uuid;
uint64_t start, length;
char *target_type = NULL;
char *params, *vgname, *lvname, *layer;
char vg_name[NAME_LEN];
char *params, *vgname = NULL, *lvname, *layer;
void *next = NULL;
int only_error_or_zero_target = 1;
int only_error_target = 1;
int r = 0;
if (!(dmt = _setup_task_run(DM_DEVICE_STATUS, &info, NULL, NULL, NULL,
@@ -654,49 +650,42 @@ int device_is_usable(struct device *dev, struct dev_usable_check_params check, i
goto out;
}
if (uuid && (check.check_reserved || check.check_lv)) {
if (!strncmp(uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1)) { /* with LVM- prefix */
if (check.check_reserved) {
/* Check internal lvm devices */
if (strlen(uuid) > (sizeof(UUID_PREFIX) + 2 * ID_LEN)) { /* 68 with suffix */
log_debug_activation("%s: Reserved uuid %s on internal LV device %s not usable.",
dev_name(dev), uuid, name);
goto out;
}
/* Recognize some older reserved LVs just from the LV name (snapshot, pvmove...) */
vgname = vg_name;
if (!dm_strncpy(vg_name, name, sizeof(vg_name)) ||
!dm_split_lvm_name(NULL, NULL, &vgname, &lvname, &layer))
goto_out;
/* FIXME: fails to handle dev aliases i.e. /dev/dm-5, replace with UUID suffix */
if (lvname && (is_reserved_lvname(lvname) || *layer)) {
log_debug_activation("%s: Reserved internal LV device %s/%s%s%s not usable.",
dev_name(dev), vgname, lvname, *layer ? "-" : "", layer);
goto out;
}
}
if (check.check_lv) {
/* Skip LVs */
if (is_lv)
*is_lv = 1;
goto out;
}
}
if (check.check_reserved &&
(!strncmp(uuid, CRYPT_TEMP, sizeof(CRYPT_TEMP) - 1) ||
!strncmp(uuid, CRYPT_SUBDEV, sizeof(CRYPT_SUBDEV) - 1) ||
!strncmp(uuid, STRATIS, sizeof(STRATIS) - 1))) {
/* Skip private crypto devices */
log_debug_activation("%s: Reserved uuid %s on %s device %s not usable.",
dev_name(dev), uuid,
uuid[0] == 'C' ? "crypto" : "stratis",
name);
/* Check internal lvm devices */
if (check.check_reserved &&
uuid && !strncmp(uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1)) {
if (strlen(uuid) > (sizeof(UUID_PREFIX) + 2 * ID_LEN)) { /* 68 */
log_debug_activation("%s: Reserved uuid %s on internal LV device %s not usable.",
dev_name(dev), uuid, name);
goto out;
}
if (!(vgname = strdup(name)) ||
!dm_split_lvm_name(NULL, NULL, &vgname, &lvname, &layer))
goto_out;
/* FIXME: fails to handle dev aliases i.e. /dev/dm-5, replace with UUID suffix */
if (lvname && (is_reserved_lvname(lvname) || *layer)) {
log_debug_activation("%s: Reserved internal LV device %s/%s%s%s not usable.",
dev_name(dev), vgname, lvname, *layer ? "-" : "", layer);
goto out;
}
}
if (check.check_lv && uuid && !strncmp(uuid, "LVM-", 4)) {
/* Skip LVs */
goto out;
}
if (check.check_reserved && uuid &&
(!strncmp(uuid, CRYPT_TEMP, sizeof(CRYPT_TEMP) - 1) ||
!strncmp(uuid, CRYPT_SUBDEV, sizeof(CRYPT_SUBDEV) - 1) ||
!strncmp(uuid, STRATIS, sizeof(STRATIS) - 1))) {
/* Skip private crypto devices */
log_debug_activation("%s: Reserved uuid %s on %s device %s not usable.",
dev_name(dev), uuid,
uuid[0] == 'C' ? "crypto" : "stratis",
name);
goto out;
}
/* FIXME Also check for mpath no paths */
@@ -767,15 +756,13 @@ int device_is_usable(struct device *dev, struct dev_usable_check_params check, i
goto out;
}
if (only_error_or_zero_target &&
strcmp(target_type, TARGET_NAME_ERROR) &&
strcmp(target_type, TARGET_NAME_ZERO))
only_error_or_zero_target = 0;
if (strcmp(target_type, TARGET_NAME_ERROR))
only_error_target = 0;
} while (next);
/* Skip devices consisting entirely of error or zero targets. */
/* Skip devices consisting entirely of error targets. */
/* FIXME Deal with device stacked above error targets? */
if (check.check_error_target && only_error_or_zero_target) {
if (check.check_error_target && only_error_target) {
log_debug_activation("%s: Error device %s not usable.",
dev_name(dev), name);
goto out;
@@ -786,6 +773,7 @@ int device_is_usable(struct device *dev, struct dev_usable_check_params check, i
r = 1;
out:
free(vgname);
dm_task_destroy(dmt);
return r;
}
@@ -842,7 +830,8 @@ static int _info(struct cmd_context *cmd,
if (strcmp(suffix_position + 1, suffix))
continue;
(void) dm_strncpy(old_style_dlid, dlid, sizeof(old_style_dlid));
(void) strncpy(old_style_dlid, dlid, sizeof(old_style_dlid));
old_style_dlid[sizeof(old_style_dlid) - 1] = '\0';
if (!_info_run(old_style_dlid, dminfo, read_ahead, seg_status,
name_check, with_open_count, with_read_ahead,
0, 0))
@@ -1124,8 +1113,7 @@ static int _percent_run(struct dev_manager *dm, const char *name,
const char *dlid,
const char *target_type, int wait,
const struct logical_volume *lv, dm_percent_t *overall_percent,
uint32_t *event_nr, int fail_if_percent_unsupported,
int *interrupted)
uint32_t *event_nr, int fail_if_percent_unsupported)
{
int r = 0;
struct dm_task *dmt;
@@ -1146,12 +1134,9 @@ static int _percent_run(struct dev_manager *dm, const char *name,
if (!(segtype = get_segtype_from_string(dm->cmd, target_type)))
return_0;
if (wait)
sigint_allow();
if (!(dmt = _setup_task_run(wait ? DM_DEVICE_WAITEVENT : DM_DEVICE_STATUS, &info,
name, dlid, event_nr, 0, 0, 0, 0, 0)))
goto_bad;
return_0;
if (!info.exists)
goto_out;
@@ -1219,19 +1204,8 @@ static int _percent_run(struct dev_manager *dm, const char *name,
display_percent(dm->cmd, *overall_percent));
r = 1;
out:
out:
dm_task_destroy(dmt);
bad:
if (wait) {
sigint_restore();
if (sigint_caught()) {
*interrupted = 1;
return_0;
}
}
return r;
}
@@ -1240,24 +1214,20 @@ static int _percent(struct dev_manager *dm, const char *name, const char *dlid,
const struct logical_volume *lv, dm_percent_t *percent,
uint32_t *event_nr, int fail_if_percent_unsupported)
{
int interrupted = 0;
if (dlid && *dlid) {
if (_percent_run(dm, NULL, dlid, target_type, wait, lv, percent,
event_nr, fail_if_percent_unsupported, &interrupted))
event_nr, fail_if_percent_unsupported))
return 1;
if (!interrupted &&
_original_uuid_format_check_required(dm->cmd) &&
if (_original_uuid_format_check_required(dm->cmd) &&
_percent_run(dm, NULL, dlid + sizeof(UUID_PREFIX) - 1,
target_type, wait, lv, percent,
event_nr, fail_if_percent_unsupported, &interrupted))
event_nr, fail_if_percent_unsupported))
return 1;
}
if (!interrupted && name &&
_percent_run(dm, name, NULL, target_type, wait, lv, percent,
event_nr, fail_if_percent_unsupported, &interrupted))
if (name && _percent_run(dm, name, NULL, target_type, wait, lv, percent,
event_nr, fail_if_percent_unsupported))
return 1;
return_0;
@@ -1459,7 +1429,7 @@ int dev_manager_mirror_percent(struct dev_manager *dm,
int dev_manager_raid_status(struct dev_manager *dm,
const struct logical_volume *lv,
struct lv_status_raid **status, int *exists)
struct dm_status_raid **status)
{
int r = 0;
const char *dlid;
@@ -1469,11 +1439,6 @@ int dev_manager_raid_status(struct dev_manager *dm,
char *type = NULL;
char *params = NULL;
const char *layer = lv_layer(lv);
struct dm_status_raid *sr;
*exists = -1;
if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_cache))))
return_0;
if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
return_0;
@@ -1481,11 +1446,8 @@ int dev_manager_raid_status(struct dev_manager *dm,
if (!(dmt = _setup_task_run(DM_DEVICE_STATUS, &info, NULL, dlid, 0, 0, 0, 0, 0, 0)))
return_0;
if (!(*exists = info.exists))
goto out;
log_debug_activation("Checking raid status for volume %s.",
display_lvname(lv));
if (!info.exists)
goto_out;
dm_get_next_target(dmt, NULL, &start, &length, &type, &params);
@@ -1497,13 +1459,9 @@ int dev_manager_raid_status(struct dev_manager *dm,
/* FIXME Check there's only one target */
if (!dm_get_status_raid(dm->mem, params, &sr))
if (!dm_get_status_raid(dm->mem, params, status))
goto_out;
(*status)->mem = dm->mem; /* User has to destroy this mem pool later */
(*status)->raid = sr;
(*status)->in_sync = dm_make_percent(sr->insync_regions, sr->total_regions);
r = 1;
out:
dm_task_destroy(dmt);
@@ -1592,7 +1550,7 @@ out:
int dev_manager_cache_status(struct dev_manager *dm,
const struct logical_volume *lv,
struct lv_status_cache **status, int *exists)
struct lv_status_cache **status)
{
int r = 0;
const char *dlid;
@@ -1603,18 +1561,14 @@ int dev_manager_cache_status(struct dev_manager *dm,
char *params = NULL;
struct dm_status_cache *c;
*exists = -1;
if (!(dlid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
return_0;
if (!(dmt = _setup_task_run(DM_DEVICE_STATUS, &info, NULL, dlid, 0, 0, 0, 0, 0, 0)))
return_0;
if (!(*exists = info.exists))
goto out;
log_debug_activation("Checking status for cache volume %s.",
display_lvname(lv));
if (!info.exists)
goto_out;
dm_get_next_target(dmt, NULL, &start, &length, &type, &params);
@@ -1659,7 +1613,7 @@ out:
int dev_manager_thin_pool_status(struct dev_manager *dm,
const struct logical_volume *lv, int flush,
struct lv_status_thin_pool **status, int *exists)
struct lv_status_thin_pool **status)
{
struct dm_status_thin_pool *dm_status;
const char *dlid;
@@ -1670,10 +1624,6 @@ int dev_manager_thin_pool_status(struct dev_manager *dm,
char *params = NULL;
int r = 0;
*exists = -1;
if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_thin_pool))))
return_0;
/* Build dlid for the thin pool layer */
if (!(dlid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
return_0;
@@ -1681,11 +1631,8 @@ int dev_manager_thin_pool_status(struct dev_manager *dm,
if (!(dmt = _setup_task_run(DM_DEVICE_STATUS, &info, NULL, dlid, 0, 0, 0, 0, flush, 0)))
return_0;
if (!(*exists = info.exists))
goto out;
log_debug_activation("Checking thin pool status for LV %s.",
display_lvname(lv));
if (!info.exists)
goto_out;
dm_get_next_target(dmt, NULL, &start, &length, &type, &params);
@@ -1698,6 +1645,9 @@ int dev_manager_thin_pool_status(struct dev_manager *dm,
if (!dm_get_status_thin_pool(dm->mem, params, &dm_status))
goto_out;
if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_thin_pool))))
goto_out;
(*status)->mem = dm->mem;
(*status)->thin_pool = dm_status;
@@ -1720,7 +1670,7 @@ out:
int dev_manager_thin_status(struct dev_manager *dm,
const struct logical_volume *lv, int flush,
struct lv_status_thin **status, int *exists)
struct lv_status_thin **status)
{
struct dm_status_thin *dm_status;
const char *dlid;
@@ -1732,21 +1682,14 @@ int dev_manager_thin_status(struct dev_manager *dm,
uint64_t csize;
int r = 0;
*exists = -1;
if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_thin))))
return_0;
if (!(dlid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
return_0;
if (!(dmt = _setup_task_run(DM_DEVICE_STATUS, &info, NULL, dlid, 0, 0, 0, 0, flush, 0)))
return_0;
if (!(*exists = info.exists))
goto out;
log_debug_activation("Checking thin status for LV %s.",
display_lvname(lv));
if (!info.exists)
goto_out;
dm_get_next_target(dmt, NULL, &start, &length, &type, &params);
@@ -1759,6 +1702,9 @@ int dev_manager_thin_status(struct dev_manager *dm,
if (!dm_get_status_thin(dm->mem, params, &dm_status))
goto_out;
if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_thin))))
goto_out;
(*status)->mem = dm->mem;
(*status)->thin = dm_status;
@@ -1791,7 +1737,7 @@ out:
*/
int dev_manager_thin_device_id(struct dev_manager *dm,
const struct logical_volume *lv,
uint32_t *device_id, int *exists)
uint32_t *device_id)
{
const char *dlid;
struct dm_task *dmt;
@@ -1801,7 +1747,6 @@ int dev_manager_thin_device_id(struct dev_manager *dm,
const char *layer = lv_layer(lv);
int r = 0;
*exists = -1;
if (lv_is_merging_origin(lv) && !lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
/* If the merge has already happened, that table
* can already be using correct LV without -real layer */
@@ -1814,11 +1759,8 @@ int dev_manager_thin_device_id(struct dev_manager *dm,
if (!(dmt = _setup_task_run(DM_DEVICE_TABLE, &info, NULL, dlid, 0, 0, 0, 0, 1, 0)))
return_0;
if (!(*exists = info.exists))
goto out;
log_debug_activation("Checking device id for LV %s.",
display_lvname(lv));
if (!info.exists)
goto_out;
if (dm_get_next_target(dmt, NULL, &start, &length,
&target_type, &params)) {
@@ -1847,9 +1789,11 @@ out:
}
int dev_manager_vdo_pool_status(struct dev_manager *dm,
const struct logical_volume *lv, int flush,
struct lv_status_vdo **status, int *exists)
const struct logical_volume *lv,
struct lv_status_vdo **vdo_status,
int flush)
{
struct lv_status_vdo *status;
const char *dlid;
struct dm_info info;
uint64_t start, length;
@@ -1858,9 +1802,12 @@ int dev_manager_vdo_pool_status(struct dev_manager *dm,
char *params = NULL;
int r = 0;
*exists = -1;
if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_vdo))))
return_0;
*vdo_status = NULL;
if (!(status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_vdo)))) {
log_error("Cannot allocate VDO status structure.");
return 0;
}
if (!(dlid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
return_0;
@@ -1868,11 +1815,8 @@ int dev_manager_vdo_pool_status(struct dev_manager *dm,
if (!(dmt = _setup_task_run(DM_DEVICE_STATUS, &info, NULL, dlid, 0, 0, 0, 0, flush, 0)))
return_0;
if (!(*exists = info.exists))
goto out;
log_debug_activation("Checking VDO pool status for LV %s.",
display_lvname(lv));
if (!info.exists)
goto_out;
if (dm_get_next_target(dmt, NULL, &start, &length, &type, &params)) {
log_error("More then one table line found for %s.",
@@ -1886,10 +1830,11 @@ int dev_manager_vdo_pool_status(struct dev_manager *dm,
goto out;
}
if (!parse_vdo_pool_status(dm->mem, lv, params, *status))
if (!parse_vdo_pool_status(dm->mem, lv, params, status))
goto_out;
(*status)->mem = dm->mem;
status->mem = dm->mem;
*vdo_status = status;
r = 1;
out:
@@ -2325,31 +2270,21 @@ static int _pool_callback(struct dm_tree_node *node,
const struct pool_cb_data *data = cb_data;
const struct logical_volume *pool_lv = data->pool_lv;
const struct logical_volume *mlv = first_seg(pool_lv)->metadata_lv;
struct cmd_context *cmd = pool_lv->vg->cmd;
long buf[64 / sizeof(long)]; /* buffer for short disk header (64B) */
int args = 0;
char *mpath;
const char *argv[19] = { /* Max supported 15 args */
find_config_tree_str_allow_empty(cmd, data->exec, NULL)
find_config_tree_str_allow_empty(pool_lv->vg->cmd, data->exec, NULL)
};
if (!*argv[0]) /* *_check tool is unconfigured/disabled with "" setting */
return 1;
if (lv_is_cache_vol(pool_lv)) {
if (!(mpath = lv_dmpath_suffix_dup(data->dm->mem, pool_lv, "-cmeta"))) {
log_error("Failed to build device path for checking cachevol metadata %s.",
display_lvname(pool_lv));
return 0;
}
} else {
if (!(mpath = lv_dmpath_dup(data->dm->mem, mlv))) {
log_error("Failed to build device path for checking pool metadata %s.",
display_lvname(mlv));
return 0;
}
if (!(mpath = lv_dmpath_dup(data->dm->mem, mlv))) {
log_error("Failed to build device path for checking pool metadata %s.",
display_lvname(mlv));
return 0;
}
log_debug("Running check command on %s", mpath);
if (data->skip_zero) {
if ((fd = open(mpath, O_RDONLY)) < 0) {
@@ -2377,7 +2312,7 @@ static int _pool_callback(struct dm_tree_node *node,
}
}
if (!(cn = find_config_tree_array(cmd, data->opts, NULL))) {
if (!(cn = find_config_tree_array(mlv->vg->cmd, data->opts, NULL))) {
log_error(INTERNAL_ERROR "Unable to find configuration for pool check options.");
return 0;
}
@@ -2399,7 +2334,7 @@ static int _pool_callback(struct dm_tree_node *node,
argv[++args] = mpath;
if (!(ret = exec_cmd(cmd, (const char * const *)argv,
if (!(ret = exec_cmd(pool_lv->vg->cmd, (const char * const *)argv,
&status, 0))) {
if (status == ENOENT) {
log_warn("WARNING: Check is skipped, please install recommended missing binary %s!",
@@ -2408,7 +2343,7 @@ static int _pool_callback(struct dm_tree_node *node,
}
if ((data->version.maj || data->version.min || data->version.patch) &&
!_check_tool_version(cmd, argv[0],
!_check_tool_version(pool_lv->vg->cmd, argv[0],
data->version.maj, data->version.min, data->version.patch)) {
log_warn("WARNING: Check is skipped, please upgrade installed version of %s!",
argv[0]);
@@ -2452,6 +2387,10 @@ static int _pool_register_callback(struct dev_manager *dm,
return 1;
#endif
/* Skip for single-device cache pool */
if (lv_is_cache(lv) && lv_is_cache_vol(first_seg(lv)->pool_lv))
return 1;
if (!(data = dm_pool_zalloc(dm->mem, sizeof(*data)))) {
log_error("Failed to allocated path for callback.");
return 0;
@@ -3544,12 +3483,6 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
!_pool_register_callback(dm, dnode, lv))
return_0;
if (lv_is_cache(lv) && lv_is_cache_vol(first_seg(lv)->pool_lv) &&
/* Register callback only for layer activation or non-layered cache LV */
(layer || !lv_layer(lv)) &&
!_pool_register_callback(dm, dnode, lv))
return_0;
/*
* Update tables for ANY PVMOVE holders for active LV where the name starts with 'pvmove',
* but it's not anymore PVMOVE LV and also it's not a PVMOVE _mimage LV.

View File

@@ -59,7 +59,7 @@ int dev_manager_mirror_percent(struct dev_manager *dm,
dm_percent_t *percent, uint32_t *event_nr);
int dev_manager_raid_status(struct dev_manager *dm,
const struct logical_volume *lv,
struct lv_status_raid **status, int *exists);
struct dm_status_raid **status);
int dev_manager_raid_message(struct dev_manager *dm,
const struct logical_volume *lv,
const char *msg);
@@ -68,19 +68,20 @@ int dev_manager_writecache_message(struct dev_manager *dm,
const char *msg);
int dev_manager_cache_status(struct dev_manager *dm,
const struct logical_volume *lv,
struct lv_status_cache **status, int *exists);
struct lv_status_cache **status);
int dev_manager_thin_status(struct dev_manager *dm,
const struct logical_volume *lv, int flush,
struct lv_status_thin **status, int *exists);
struct lv_status_thin **status);
int dev_manager_thin_device_id(struct dev_manager *dm,
const struct logical_volume *lv,
uint32_t *device_id, int *exist);
uint32_t *device_id);
int dev_manager_thin_pool_status(struct dev_manager *dm,
const struct logical_volume *lv, int flush,
struct lv_status_thin_pool **status, int *exists);
struct lv_status_thin_pool **status);
int dev_manager_vdo_pool_status(struct dev_manager *dm,
const struct logical_volume *lv, int flush,
struct lv_status_vdo **status, int *exists);
const struct logical_volume *lv,
struct lv_status_vdo **vdo_status,
int flush);
int dev_manager_suspend(struct dev_manager *dm, const struct logical_volume *lv,
struct lv_activate_opts *laopts, int lockfs, int flush_required);
int dev_manager_activate(struct dev_manager *dm, const struct logical_volume *lv,

View File

@@ -76,7 +76,7 @@ static int _rm_dir(const char *dev_dir, const char *vg_name)
return 0;
}
if (dir_exists(vg_path) && dm_is_empty_dir(vg_path)) {
if (dir_exists(vg_path) && is_empty_dir(vg_path)) {
log_very_verbose("Removing directory %s", vg_path);
rmdir(vg_path);
}
@@ -93,7 +93,7 @@ static void _rm_blks(const char *dir)
DIR *d;
if (!(d = opendir(dir))) {
log_sys_debug("opendir", dir);
log_sys_error("opendir", dir);
return;
}
@@ -104,7 +104,7 @@ static void _rm_blks(const char *dir)
continue;
if (dm_snprintf(path, sizeof(path), "%s/%s", dir, name) == -1) {
log_debug("Couldn't create path for %s.", name);
log_error("Couldn't create path for %s", name);
continue;
}
@@ -113,12 +113,12 @@ static void _rm_blks(const char *dir)
continue;
log_very_verbose("Removing %s", path);
if (unlink(path) < 0)
log_sys_debug("unlink", path);
log_sys_error("unlink", path);
}
}
if (closedir(d))
log_sys_debug("closedir", dir);
log_sys_error("closedir", dir);
}
static int _mk_link(const char *dev_dir, const char *vg_name,
@@ -169,7 +169,7 @@ static int _mk_link(const char *dev_dir, const char *vg_name,
log_very_verbose("Removing %s", lvm1_group_path);
if (unlink(lvm1_group_path) < 0)
log_sys_debug("unlink", lvm1_group_path);
log_sys_error("unlink", lvm1_group_path);
}
}

354
lib/cache/lvmcache.c vendored
View File

@@ -18,7 +18,6 @@
#include "lib/cache/lvmcache.h"
#include "lib/commands/toolcontext.h"
#include "lib/device/dev-cache.h"
#include "lib/device/device_id.h"
#include "lib/locking/locking.h"
#include "lib/metadata/metadata.h"
#include "lib/mm/memlock.h"
@@ -88,9 +87,6 @@ static int _vgs_locked = 0;
static int _found_duplicate_vgnames = 0;
static int _outdated_warning = 0;
static const char *_scan_lock_global_file = DEFAULT_RUN_DIR "/scan_lock_global";
static int _scan_lock_global_file_exists = 0;
int lvmcache_init(struct cmd_context *cmd)
{
/*
@@ -104,13 +100,13 @@ int lvmcache_init(struct cmd_context *cmd)
dm_list_init(&_unused_duplicates);
dm_list_init(&_prev_unused_duplicate_devs);
if (!(_vgname_hash = dm_hash_create(127)))
if (!(_vgname_hash = dm_hash_create(128)))
return 0;
if (!(_vgid_hash = dm_hash_create(126)))
if (!(_vgid_hash = dm_hash_create(128)))
return 0;
if (!(_pvid_hash = dm_hash_create(125)))
if (!(_pvid_hash = dm_hash_create(128)))
return 0;
return 1;
@@ -129,19 +125,6 @@ void lvmcache_unlock_vgname(const char *vgname)
}
}
unsigned int lvmcache_vg_info_count(void)
{
struct lvmcache_vginfo *vginfo;
unsigned int count = 0;
dm_list_iterate_items(vginfo, &_vginfos) {
if (is_orphan_vg(vginfo->vgname))
continue;
count++;
}
return count;
}
int lvmcache_found_duplicate_vgnames(void)
{
return _found_duplicate_vgnames;
@@ -524,25 +507,6 @@ static const char *_get_pvsummary_device_hint(char *pvid)
return NULL;
}
static const char *_get_pvsummary_device_id(char *pvid, const char **device_id_type)
{
char pvid_s[ID_LEN + 1] __attribute__((aligned(8)));
struct lvmcache_vginfo *vginfo;
struct pv_list *pvl;
dm_list_iterate_items(vginfo, &_vginfos) {
dm_list_iterate_items(pvl, &vginfo->pvsummaries) {
(void) dm_strncpy(pvid_s, (char *) &pvl->pv->id, sizeof(pvid_s));
if (!strcmp(pvid_s, pvid)) {
*device_id_type = pvl->pv->device_id_type;
return pvl->pv->device_id;
}
}
}
return NULL;
}
/*
* Check if any PVs in vg->pvs have the same PVID as any
* entries in _unused_duplicates.
@@ -648,8 +612,6 @@ static void _choose_duplicates(struct cmd_context *cmd,
struct device_list *devl, *devl_safe, *devl_add, *devl_del;
struct lvmcache_info *info;
struct device *dev1, *dev2;
const char *device_id = NULL, *device_id_type = NULL;
const char *idname1 = NULL, *idname2 = NULL;
uint32_t dev1_major, dev1_minor, dev2_major, dev2_minor;
uint64_t dev1_size, dev2_size, pvsummary_size;
int in_subsys1, in_subsys2;
@@ -658,7 +620,6 @@ static void _choose_duplicates(struct cmd_context *cmd,
int has_lv1, has_lv2;
int same_size1, same_size2;
int same_name1 = 0, same_name2 = 0;
int same_id1 = 0, same_id2 = 0;
int prev_unchosen1, prev_unchosen2;
int change;
@@ -789,19 +750,6 @@ next:
same_name2 = !strcmp(device_hint, dev_name(dev2));
}
if ((device_id = _get_pvsummary_device_id(devl->dev->pvid, &device_id_type))) {
uint16_t idtype = idtype_from_str(device_id_type);
if (idtype) {
idname1 = device_id_system_read(cmd, dev1, idtype);
idname2 = device_id_system_read(cmd, dev2, idtype);
}
if (idname1)
same_id1 = !strcmp(idname1, device_id);
if (idname2)
same_id2 = !strcmp(idname2, device_id);
}
has_lv1 = (dev1->flags & DEV_USED_FOR_LV) ? 1 : 0;
has_lv2 = (dev2->flags & DEV_USED_FOR_LV) ? 1 : 0;
@@ -820,12 +768,6 @@ next:
dev_name(dev2), dev2_major, dev2_minor,
device_hint ?: "none");
log_debug_cache("PV %s: device_id %s. %s is %s. %s is %s.",
devl->dev->pvid,
device_id ?: ".",
dev_name(dev1), idname1 ?: ".",
dev_name(dev2), idname2 ?: ".");
log_debug_cache("PV %s: size %llu. %s is %llu. %s is %llu.",
devl->dev->pvid,
(unsigned long long)pvsummary_size,
@@ -866,13 +808,6 @@ next:
} else if (prev_unchosen2 && !prev_unchosen1) {
/* keep 1 (NB when unchosen is set we unprefer) */
reason = "of previous preference";
} else if (same_id1 && !same_id2) {
/* keep 1 */
reason = "device id";
} else if (same_id2 && !same_id1) {
/* change to 2 */
change = 1;
reason = "device id";
} else if (has_lv1 && !has_lv2) {
/* keep 1 */
reason = "device is used by LV";
@@ -1093,127 +1028,6 @@ int lvmcache_label_reopen_vg_rw(struct cmd_context *cmd, const char *vgname, con
return 1;
}
/*
* During label_scan, the md component filter is applied to each device after
* the device header has been read. This often just checks the start of the
* device for an md header, and if the device has an md header at the end, the
* md component filter wouldn't detect it. In some cases, the full md filter
* is enabled during label_scan, in which case the md component filter will
* check both the start and end of the device for md superblocks.
*
* In this function, after label_scan is done, we may decide that a full md
* component check should be applied to a device if it hasn't been yet. This
* is based on some clues or uncertainty that arose during label_scan.
*
* label_scan saved metadata info about pvs in lvmcache pvsummaries. That
* pvsummary metadata includes the pv size. So now, after label_scan is done,
* we can compare the pv size with the size of the device the pv was read from.
* If the pv and dev sizes do not match, it can sometimes be normal, but other
* times it can be a clue that label_scan mistakenly read the pv from an md
* component device instead of from the md device itself. So for unmatching
* sizes, we do a full md component check on the device.
*/
void lvmcache_extra_md_component_checks(struct cmd_context *cmd)
{
struct lvmcache_vginfo *vginfo, *vginfo2;
struct lvmcache_info *info, *info2;
struct device *dev;
const char *device_hint;
uint64_t devsize, pvsize;
int do_check_size, do_check_name;
int md_check_start;
/*
* use_full_md_check: if set then no more needs to be done here,
* all devs have already been fully checked as md components.
*
* md_component_checks "full": use_full_md_check was set, and caused
* filter-md to already do a full check, no more is needed.
*
* md_component_checks "start": skip end of device md component checks,
* the start of device has already been checked by filter-md.
*
* md_component_checks "auto": do full checks only when lvm finds some
* clue or reasons to believe it might be useful, which is what this
* function is looking for.
*/
if (!cmd->md_component_detection || cmd->use_full_md_check ||
!strcmp(cmd->md_component_checks, "none"))
return;
md_check_start = !strcmp(cmd->md_component_checks, "start");
/*
* We want to avoid extra scanning for end-of-device md superblocks
* whenever possible, since it can add up to a lot of extra io if we're
* not careful to do it only when there's a good reason to believe a
* dev is an md component.
*
* If the pv/dev size mismatches are commonly occuring for
* non-md-components then we'll want to stop using that as a trigger
* for the full md check.
*/
dm_list_iterate_items_safe(vginfo, vginfo2, &_vginfos) {
dm_list_iterate_items_safe(info, info2, &vginfo->infos) {
dev = info->dev;
device_hint = _get_pvsummary_device_hint(dev->pvid);
pvsize = _get_pvsummary_size(dev->pvid);
devsize = dev->size;
do_check_size = 0;
do_check_name = 0;
if (!devsize && !dev_get_size(dev, &devsize))
log_debug("No size for %s.", dev_name(dev));
/*
* PV larger than dev not common; dev larger than PV
* can be common, but not as often as PV larger.
*/
if (pvsize && devsize && (pvsize != devsize))
do_check_size = 1;
if (device_hint && !strncmp(device_hint, "/dev/md", 7))
do_check_name = 1;
if (!do_check_size && !do_check_name)
continue;
/*
* If only the size is different (which can be fairly
* common for non-md-component devs) and the user has
* set "start" to disable full md checks, then skip it.
* If the size is different, *and* the device name hint
* looks like an md device, then it seems very likely
* to be an md component, so do a full check on it even
* if the user has set "start".
*
* In "auto" mode, do a full check if either the size
* or the name indicates a possible md component.
*/
if (do_check_size && !do_check_name && md_check_start) {
log_debug("extra md component check skip %llu %llu device_hint %s dev %s",
(unsigned long long)pvsize, (unsigned long long)devsize,
device_hint ?: "none", dev_name(dev));
continue;
}
log_debug("extra md component check %llu %llu device_hint %s dev %s",
(unsigned long long)pvsize, (unsigned long long)devsize,
device_hint ?: "none", dev_name(dev));
if (dev_is_md_component(dev, NULL, 1)) {
log_debug("dropping PV from md component %s", dev_name(dev));
dev->flags &= ~DEV_SCAN_FOUND_LABEL;
/* lvmcache_del will also delete vginfo if info was last one */
lvmcache_del(info);
lvmcache_del_dev_from_duplicates(dev);
cmd->filter->wipe(cmd, cmd->filter, dev, NULL);
}
}
}
}
/*
* Uses label_scan to populate lvmcache with 'vginfo' struct for each VG
* and associated 'info' structs for those VGs. Only VG summary information
@@ -1242,13 +1056,14 @@ int lvmcache_label_scan(struct cmd_context *cmd)
{
struct dm_list del_cache_devs;
struct dm_list add_cache_devs;
struct dm_list renamed_devs;
struct lvmcache_info *info;
struct lvmcache_vginfo *vginfo;
struct device_list *devl;
int vginfo_count = 0;
dm_list_init(&renamed_devs);
int r = 0;
log_debug_cache("lvmcache label scan begin");
log_debug_cache("Finding VG info");
/*
* Duplicates found during this label scan are added to _initial_duplicates.
@@ -1260,24 +1075,13 @@ int lvmcache_label_scan(struct cmd_context *cmd)
* Do the actual scanning. This populates lvmcache
* with infos/vginfos based on reading headers from
* each device, and a vg summary from each mda.
*
* Note that this will *skip* scanning a device if
* an info struct already exists in lvmcache for
* the device.
*/
label_scan(cmd);
/*
* When devnames are used as device ids (which is dispreferred),
* changing/unstable devnames can lead to entries in the devices file
* not being matched to a dev even if the PV is present on the system.
* Or, a devices file entry may have been matched to the wrong device
* (with the previous name) that does not have the PVID specified in
* the entry. This function detects that problem, scans labels on all
* devs on the system to find the missing PVIDs, and corrects the
* devices file. We then need to run label scan on these correct
* devices.
*/
device_ids_find_renamed_devs(cmd, &renamed_devs, NULL, 0);
if (!dm_list_empty(&renamed_devs))
label_scan_devs(cmd, cmd->filter, &renamed_devs);
/*
* _choose_duplicates() returns:
*
@@ -1321,8 +1125,17 @@ int lvmcache_label_scan(struct cmd_context *cmd)
_warn_unused_duplicates(cmd);
}
log_debug_cache("lvmcache label scan done");
return 1;
r = 1;
dm_list_iterate_items(vginfo, &_vginfos) {
if (is_orphan_vg(vginfo->vgname))
continue;
vginfo_count++;
}
log_debug_cache("Found VG info for %d VGs", vginfo_count);
return r;
}
int lvmcache_get_vgnameids(struct cmd_context *cmd,
@@ -1409,7 +1222,8 @@ static void _free_vginfo(struct lvmcache_vginfo *vginfo)
free(vginfo->vgname);
free(vginfo->system_id);
free(vginfo->creation_host);
free(vginfo->lock_type);
if (vginfo->lock_type)
free(vginfo->lock_type);
free(vginfo);
}
@@ -2745,115 +2559,19 @@ bool lvmcache_scan_mismatch(struct cmd_context *cmd, const char *vgname, const c
return true;
}
/*
* max_size_bytes and max_size_percent may come from different areas and
* different vgs because of different area sizes.
*/
static uint64_t _max_metadata_size_bytes;
static dm_percent_t _max_metadata_size_percent = DM_PERCENT_INVALID;
static uint64_t _max_metadata_size;
void lvmcache_save_metadata_size_bytes(uint64_t val)
void lvmcache_save_metadata_size(uint64_t val)
{
if (!_max_metadata_size_bytes)
_max_metadata_size_bytes = val;
else if (_max_metadata_size_bytes < val)
_max_metadata_size_bytes = val;
if (!_max_metadata_size)
_max_metadata_size = val;
else if (_max_metadata_size < val)
_max_metadata_size = val;
}
uint64_t lvmcache_max_metadata_size_bytes(void)
uint64_t lvmcache_max_metadata_size(void)
{
return _max_metadata_size_bytes;
}
/*
* TODO: enable/disable scan_lock_global with config setting:
* y: always use it
* n: never use it
* auto (default): use based on /run/lvm/scan_lock_global
*/
void lvmcache_save_metadata_size_percent(uint64_t meta_size, uint64_t mdah_size)
{
dm_percent_t pc = dm_make_percent(meta_size, mdah_size);
if (pc == DM_PERCENT_INVALID || pc == DM_PERCENT_FAILED ||
pc == DM_PERCENT_0 || pc == DM_PERCENT_1)
return;
if (_max_metadata_size_percent == DM_PERCENT_INVALID) {
_max_metadata_size_percent = pc;
return;
}
if (_max_metadata_size_percent < pc)
_max_metadata_size_percent = pc;
}
/*
* TODO: make the percent at which scan_lock_global is used
* configurable?
*/
#define SCAN_LOCK_GLOBAL_METADATA_PERCENT (DM_PERCENT_1 * 25)
void set_scan_lock_global(struct cmd_context *cmd)
{
FILE *fp;
if (_max_metadata_size_percent == DM_PERCENT_INVALID)
return;
if (_max_metadata_size_percent >= SCAN_LOCK_GLOBAL_METADATA_PERCENT) {
if (_scan_lock_global_file_exists)
return;
log_debug("Creating %s.", _scan_lock_global_file);
if (!(fp = fopen(_scan_lock_global_file, "w")))
return;
if (fclose(fp))
stack;
} else {
if (_scan_lock_global_file_exists) {
log_debug("Unlinking %s.", _scan_lock_global_file);
if (unlink(_scan_lock_global_file))
stack;
}
}
}
int do_scan_lock_global(struct cmd_context *cmd, int *gl_ex)
{
struct stat buf;
if (cmd->nolocking)
return 0;
/* global lock is already held */
if (cmd->lockf_global_ex)
return 0;
if (!stat(_scan_lock_global_file, &buf)) {
_scan_lock_global_file_exists = 1;
/*
* Tell the caller to use sh or ex. A command that may write
* vg metadata should use ex, otherwise sh.
*
* lockd_vg_default_sh/LOCKD_VG_SH is set for commands that
* do not modify vg metadata.
*
* FIXME: this variable/flag was previously used only for
* lvmlockd locking logic, but is now more general, so
* it should be renamed.
*/
if (cmd->lockd_vg_default_sh)
*gl_ex = 0;
else
*gl_ex = 1;
return 1;
}
return 0;
return _max_metadata_size;
}
int lvmcache_vginfo_has_pvid(struct lvmcache_vginfo *vginfo, char *pvid)
@@ -2917,7 +2635,7 @@ void lvmcache_get_outdated_devs(struct cmd_context *cmd,
}
dm_list_iterate_items(info, &vginfo->outdated_infos) {
if (!(devl = dm_pool_zalloc(cmd->mem, sizeof(*devl))))
if (!(devl = zalloc(sizeof(*devl))))
return;
devl->dev = info->dev;
dm_list_add(devs, &devl->list);
@@ -3004,12 +2722,6 @@ const char *dev_filtered_reason(struct device *dev)
return "device is too small (pv_min_size)";
if (dev->filtered_flags & DEV_FILTERED_UNUSABLE)
return "device is not in a usable state";
if (dev->filtered_flags & DEV_FILTERED_DEVICES_FILE)
return "device is not in devices file";
if (dev->filtered_flags & DEV_FILTERED_DEVICES_LIST)
return "device is not in devices list";
if (dev->filtered_flags & DEV_FILTERED_IS_LV)
return "device is an LV";
/* flag has not been added here */
if (dev->filtered_flags)

13
lib/cache/lvmcache.h vendored
View File

@@ -183,9 +183,8 @@ bool lvmcache_scan_mismatch(struct cmd_context *cmd, const char *vgname, const c
int lvmcache_vginfo_has_pvid(struct lvmcache_vginfo *vginfo, char *pvid);
uint64_t lvmcache_max_metadata_size_bytes(void);
void lvmcache_save_metadata_size_bytes(uint64_t val);
void lvmcache_save_metadata_size_percent(uint64_t meta_size, uint64_t mdah_size);
uint64_t lvmcache_max_metadata_size(void);
void lvmcache_save_metadata_size(uint64_t val);
int dev_in_device_list(struct device *dev, struct dm_list *head);
@@ -223,12 +222,4 @@ const char *devname_error_reason(const char *devname);
struct metadata_area *lvmcache_get_dev_mda(struct device *dev, int mda_num);
void lvmcache_extra_md_component_checks(struct cmd_context *cmd);
unsigned int lvmcache_vg_info_count(void);
void set_scan_lock_global(struct cmd_context *cmd);
int do_scan_lock_global(struct cmd_context *cmd, int *gl_ex);
#endif

View File

@@ -32,7 +32,6 @@
#include "lib/cache/lvmcache.h"
#include "lib/format_text/archiver.h"
#include "lib/lvmpolld/lvmpolld-client.h"
#include "lib/device/device_id.h"
#include <locale.h>
#include <sys/stat.h>
@@ -230,7 +229,7 @@ static void _get_sysfs_dir(struct cmd_context *cmd, char *buf, size_t buf_size)
return;
}
(void) dm_strncpy(buf, sys_mnt, buf_size);
strncpy(buf, sys_mnt, buf_size);
}
static uint32_t _parse_debug_fields(struct cmd_context *cmd, int cfg, const char *cfgname)
@@ -661,8 +660,6 @@ static int _process_config(struct cmd_context *cmd)
*/
cmd->default_settings.udev_fallback = udev_disabled ? 1 : -1;
cmd->default_settings.issue_discards = find_config_tree_bool(cmd, devices_issue_discards_CFG, NULL);
init_retry_deactivation(find_config_tree_bool(cmd, activation_retry_deactivation_CFG, NULL));
init_activation_checks(find_config_tree_bool(cmd, activation_checks_CFG, NULL));
@@ -966,8 +963,8 @@ static void _destroy_config(struct cmd_context *cmd)
/* CONFIG_FILE/CONFIG_MERGED_FILES */
if ((cft = remove_config_tree_by_source(cmd, CONFIG_MERGED_FILES)))
config_destroy(cft);
else if ((cft = remove_config_tree_by_source(cmd, CONFIG_FILE)))
config_destroy(cft);
else
remove_config_tree_by_source(cmd, CONFIG_FILE);
dm_list_iterate_items(cfl, &cmd->config_files)
config_destroy(cfl->cft);
@@ -1069,7 +1066,7 @@ static int _init_dev_cache(struct cmd_context *cmd)
return 1;
}
#define MAX_FILTERS 11
#define MAX_FILTERS 10
static struct dev_filter *_init_filter_chain(struct cmd_context *cmd)
{
@@ -1088,9 +1085,6 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd)
* sysfs filter. Only available on 2.6 kernels. Non-critical.
* Listed first because it's very efficient at eliminating
* unavailable devices.
*
* TODO: I suspect that using the lvm_type and device_id
* filters before this one may be more efficient.
*/
if (find_config_tree_bool(cmd, devices_sysfs_scan_CFG, NULL)) {
if ((filters[nr_filt] = sysfs_filter_create()))
@@ -1106,7 +1100,7 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd)
/* global regex filter. Optional. */
if ((cn = find_config_tree_node(cmd, devices_global_filter_CFG, NULL))) {
if (!(filters[nr_filt] = regex_filter_create(cn->v, 0, 1))) {
if (!(filters[nr_filt] = regex_filter_create(cn->v))) {
log_error("Failed to create global regex device filter");
goto bad;
}
@@ -1115,7 +1109,7 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd)
/* regex filter. Optional. */
if ((cn = find_config_tree_node(cmd, devices_filter_CFG, NULL))) {
if (!(filters[nr_filt] = regex_filter_create(cn->v, 1, 0))) {
if (!(filters[nr_filt] = regex_filter_create(cn->v))) {
log_error("Failed to create regex device filter");
goto bad;
}
@@ -1129,13 +1123,6 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd)
}
nr_filt++;
/* filter based on the device_ids saved in the devices file */
if (!(filters[nr_filt] = deviceid_filter_create(cmd))) {
log_error("Failed to create deviceid device filter");
goto bad;
}
nr_filt++;
/* usable device filter. Required. */
if (!(filters[nr_filt] = usable_filter_create(cmd, cmd->dev_types, FILTER_MODE_NO_LVMETAD))) {
log_error("Failed to create usabled device filter");
@@ -1498,7 +1485,6 @@ int init_run_by_dmeventd(struct cmd_context *cmd)
init_dmeventd_monitor(DMEVENTD_MONITOR_IGNORE);
init_ignore_suspended_devices(1);
init_disable_dmeventd_monitoring(1); /* Lock settings */
cmd->run_by_dmeventd = 1;
return 0;
}
@@ -1731,8 +1717,6 @@ struct cmd_context *create_toolcontext(unsigned is_clvmd,
if (!_init_dev_cache(cmd))
goto_out;
devices_file_init(cmd);
memlock_init(cmd);
if (!_init_formats(cmd))
@@ -1858,7 +1842,6 @@ int refresh_toolcontext(struct cmd_context *cmd)
_destroy_segtypes(&cmd->segtypes);
_destroy_formats(cmd, &cmd->formats);
devices_file_exit(cmd);
if (!dev_cache_exit())
stack;
_destroy_dev_types(cmd);
@@ -1938,8 +1921,6 @@ int refresh_toolcontext(struct cmd_context *cmd)
if (!_init_dev_cache(cmd))
return_0;
devices_file_init(cmd);
if (!_init_formats(cmd))
return_0;
@@ -1989,7 +1970,6 @@ void destroy_toolcontext(struct cmd_context *cmd)
_destroy_filters(cmd);
if (cmd->mem)
dm_pool_destroy(cmd->mem);
devices_file_exit(cmd);
dev_cache_exit();
_destroy_dev_types(cmd);
_destroy_tags(cmd);

View File

@@ -39,7 +39,7 @@ struct config_info {
int udev_rules;
int udev_sync;
int udev_fallback;
int issue_discards;
int cache_vgmetadata;
const char *msg_prefix;
const char *fmt_name;
const char *dmeventd_executable;
@@ -182,27 +182,14 @@ struct cmd_context {
unsigned pvscan_recreate_hints:1; /* enable special case hint handling for pvscan --cache */
unsigned scan_lvs:1;
unsigned wipe_outdated_pvs:1;
unsigned enable_devices_list:1; /* command is using --devices option */
unsigned enable_devices_file:1; /* command is using devices file */
unsigned pending_devices_file:1; /* command may create and enable devices file */
unsigned create_edit_devices_file:1; /* command expects to create and/or edit devices file */
unsigned edit_devices_file:1; /* command expects to edit devices file */
unsigned filter_deviceid_skip:1; /* don't use filter-deviceid */
unsigned filter_regex_with_devices_file:1; /* use filter-regex even when devices file is enabled */
unsigned filter_nodata_only:1; /* only use filters that do not require data from the dev */
unsigned run_by_dmeventd:1; /* command is being run by dmeventd */
unsigned sysinit:1; /* --sysinit is used */
/*
* Devices and filtering.
*/
struct dev_filter *filter;
struct dm_list hints;
struct dm_list use_devices; /* struct dev_use for each entry in devices file */
const char *md_component_checks;
const char *search_for_devnames; /* config file setting */
const char *devicesfile; /* from --devicesfile option */
struct dm_list deviceslist; /* from --devices option, struct dm_str_list */
/*
* Configuration.
@@ -234,7 +221,6 @@ struct cmd_context {
char system_dir[PATH_MAX];
char dev_dir[PATH_MAX];
char proc_dir[PATH_MAX];
char devices_file_path[PATH_MAX];
/*
* Reporting.
@@ -256,7 +242,6 @@ struct cmd_context {
unsigned rand_seed;
struct dm_list pending_delete; /* list of LVs for removal */
struct dm_pool *pending_delete_mem; /* memory pool for pending deletes */
int early_lock_vg_mode;
};
/*

View File

@@ -710,7 +710,7 @@ static struct dm_config_value *_get_def_array_values(struct cmd_context *cmd,
return array;
}
if (!(token = enc_value = strdup(def_enc_value))) {
if (!(p = token = enc_value = strdup(def_enc_value))) {
log_error("_get_def_array_values: strdup failed");
return NULL;
}
@@ -1141,10 +1141,8 @@ int config_def_check(struct cft_check_handle *handle)
* sections and settings with full path as a key.
* If section name is variable, use '#' as a substitute.
*/
*vp = 0;
*rp = 0;
if (!handle->cmd->cft_def_hash) {
if (!(handle->cmd->cft_def_hash = dm_hash_create(60))) {
if (!(handle->cmd->cft_def_hash = dm_hash_create(64))) {
log_error("Failed to create configuration definition hash.");
r = 0; goto out;
}
@@ -1710,7 +1708,6 @@ static int _out_prefix_fn(const struct dm_config_node *cn, const char *line, voi
const char *node_type_name = cn->v ? "option" : "section";
char path[CFG_PATH_MAX_LEN];
char commentline[MAX_COMMENT_LINE+1];
int is_deprecated = 0;
if (cn->id <= 0)
return 1;
@@ -1724,14 +1721,13 @@ static int _out_prefix_fn(const struct dm_config_node *cn, const char *line, voi
cfg_def = cfg_def_get_item_p(cn->id);
is_deprecated = _def_node_is_deprecated(cfg_def, out->tree_spec);
if (out->tree_spec->withsummary || out->tree_spec->withcomments) {
_cfg_def_make_path(path, sizeof(path), cfg_def->id, cfg_def, 1);
fprintf(out->fp, "\n");
fprintf(out->fp, "%s# Configuration %s %s.\n", line, node_type_name, path);
if (out->tree_spec->withcomments && is_deprecated && cfg_def->deprecation_comment)
if (out->tree_spec->withcomments &&
_def_node_is_deprecated(cfg_def, out->tree_spec))
fprintf(out->fp, "%s# %s", line, cfg_def->deprecation_comment);
if (cfg_def->comment) {
@@ -1742,14 +1738,14 @@ static int _out_prefix_fn(const struct dm_config_node *cn, const char *line, voi
continue;
commentline[0] = '\0';
}
fprintf(out->fp, "%s#%s%s\n", line, commentline[0] ? " " : "", commentline);
fprintf(out->fp, "%s# %s\n", line, commentline);
/* withsummary prints only the first comment line. */
if (!out->tree_spec->withcomments)
break;
}
}
if (is_deprecated)
if (_def_node_is_deprecated(cfg_def, out->tree_spec))
fprintf(out->fp, "%s# This configuration %s is deprecated.\n", line, node_type_name);
if (cfg_def->flags & CFG_ADVANCED)
@@ -1777,7 +1773,7 @@ static int _out_prefix_fn(const struct dm_config_node *cn, const char *line, voi
return_0;
fprintf(out->fp, "%s# Available since version %s.\n", line, version);
if (is_deprecated) {
if (_def_node_is_deprecated(cfg_def, out->tree_spec)) {
if (!_get_config_node_version(cfg_def->deprecated_since_version, version))
return_0;
fprintf(out->fp, "%s# Deprecated since version %s.\n", line, version);

View File

@@ -288,32 +288,6 @@ cfg_array(devices_preferred_names_CFG, "preferred_names", devices_CFG_SECTION, C
"preferred_names = [ \"^/dev/mpath/\", \"^/dev/mapper/mpath\", \"^/dev/[hs]d\" ]\n"
"#\n")
cfg(devices_use_devicesfile_CFG, "use_devicesfile", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_USE_DEVICES_FILE, vsn(2, 3, 12), NULL, 0, NULL,
"Enable or disable the use of a devices file.\n"
"When enabled, lvm will only use devices that\n"
"are lised in the devices file. A devices file will\n"
"be used, regardless of this setting, when the --devicesfile\n"
"option is set to a specific file name.\n")
cfg(devices_devicesfile_CFG, "devicesfile", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_DEVICES_FILE, vsn(2, 3, 12), NULL, 0, NULL,
"The name of the system devices file, listing devices that LVM should use.\n"
"This should not be used to select a non-system devices file.\n"
"The --devicesfile option is intended for alternative devices files.\n")
cfg(devices_search_for_devnames_CFG, "search_for_devnames", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_SEARCH_FOR_DEVNAMES, vsn(2, 3, 12), NULL, 0, NULL,
"Look outside of the devices file for missing devname entries.\n"
"A devname entry is used for a device that does not have a stable\n"
"device id, e.g. wwid, so the unstable device name is used as\n"
"the device id. After reboot, or if the device is reattached,\n"
"the device name may change, in which case lvm will not find\n"
"the expected PV on the device listed in the devices file.\n"
"This setting controls whether lvm will search other devices,\n"
"outside the devices file, to look for the missing PV on a\n"
"renamed device. If \"none\", lvm will not look at other devices,\n"
"and the PV may appear to be missing. If \"auto\", lvm will look\n"
"at other devices, but only those that are likely to have the PV.\n"
"If \"all\", lvm will look at all devices on the system.\n")
cfg_array(devices_filter_CFG, "filter", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, "#Sa|.*|", vsn(1, 0, 0), NULL, 0, NULL,
"Limit the block devices that are used by LVM commands.\n"
"This is a list of regular expressions used to accept or reject block\n"
@@ -352,16 +326,16 @@ cfg_array(devices_global_filter_CFG, "global_filter", devices_CFG_SECTION, CFG_D
"global_filter are not opened by LVM.\n")
cfg_runtime(devices_cache_CFG, "cache", devices_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(1, 0, 0), vsn(1, 2, 19), NULL,
NULL)
"This setting is no longer used.\n")
cfg_runtime(devices_cache_dir_CFG, "cache_dir", devices_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(1, 2, 19), vsn(2, 3, 0), NULL,
NULL)
"This setting is no longer used.\n")
cfg(devices_cache_file_prefix_CFG, "cache_file_prefix", devices_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, DEFAULT_CACHE_FILE_PREFIX, vsn(1, 2, 19), NULL, vsn(2, 3, 0), NULL,
NULL)
"This setting is no longer used.\n")
cfg(devices_write_cache_state_CFG, "write_cache_state", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, 1, vsn(1, 0, 0), NULL, vsn(2, 3, 0), NULL,
NULL)
"This setting is no longer used.\n")
cfg_array(devices_types_CFG, "types", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED | CFG_ADVANCED, CFG_TYPE_INT | CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL, 0, NULL,
"List of additional acceptable block device types.\n"
@@ -427,15 +401,15 @@ cfg(devices_fw_raid_component_detection_CFG, "fw_raid_component_detection", devi
cfg(devices_md_chunk_alignment_CFG, "md_chunk_alignment", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_MD_CHUNK_ALIGNMENT, vsn(2, 2, 48), NULL, 0, NULL,
"Align the start of a PV data area with md device's stripe-width.\n"
"This applies if a PV is placed directly on an md device.\n"
"default_data_alignment will be overridden if it is not aligned\n"
"default_data_alignment will be overriden if it is not aligned\n"
"with the value detected for this setting.\n"
"This setting is overridden by data_alignment_detection,\n"
"This setting is overriden by data_alignment_detection,\n"
"data_alignment, and the --dataalignment option.\n")
cfg(devices_default_data_alignment_CFG, "default_data_alignment", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, FIRST_PE_AT_ONE_MB_IN_MB, vsn(2, 2, 75), NULL, 0, NULL,
"Align the start of a PV data area with this number of MiB.\n"
"Set to 1 for 1MiB, 2 for 2MiB, etc. Set to 0 to disable.\n"
"This setting is overridden by data_alignment and the --dataalignment\n"
"This setting is overriden by data_alignment and the --dataalignment\n"
"option.\n")
cfg(devices_data_alignment_detection_CFG, "data_alignment_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_DATA_ALIGNMENT_DETECTION, vsn(2, 2, 51), NULL, 0, NULL,
@@ -447,9 +421,9 @@ cfg(devices_data_alignment_detection_CFG, "data_alignment_detection", devices_CF
"preferred unit of receiving I/O, e.g. MD stripe width.\n"
"minimum_io_size is used if optimal_io_size is undefined (0).\n"
"If md_chunk_alignment is enabled, that detects the optimal_io_size.\n"
"default_data_alignment and md_chunk_alignment will be overridden\n"
"default_data_alignment and md_chunk_alignment will be overriden\n"
"if they are not aligned with the value detected for this setting.\n"
"This setting is overridden by data_alignment and the --dataalignment\n"
"This setting is overriden by data_alignment and the --dataalignment\n"
"option.\n")
cfg(devices_data_alignment_CFG, "data_alignment", devices_CFG_SECTION, 0, CFG_TYPE_INT, 0, vsn(2, 2, 45), NULL, 0, NULL,
@@ -457,7 +431,7 @@ cfg(devices_data_alignment_CFG, "data_alignment", devices_CFG_SECTION, 0, CFG_TY
"When non-zero, this setting overrides default_data_alignment.\n"
"Set to 0 to disable, in which case default_data_alignment\n"
"is used to align the first PE in units of MiB.\n"
"This setting is overridden by the --dataalignment option.\n")
"This setting is overriden by the --dataalignment option.\n")
cfg(devices_data_alignment_offset_detection_CFG, "data_alignment_offset_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_DATA_ALIGNMENT_OFFSET_DETECTION, vsn(2, 2, 50), NULL, 0, NULL,
"Shift the start of an aligned PV data area based on sysfs information.\n"
@@ -467,7 +441,7 @@ cfg(devices_data_alignment_offset_detection_CFG, "data_alignment_offset_detectio
"partitioning will have an alignment_offset of 3584 bytes (sector 7\n"
"is the lowest aligned logical block, the 4KiB sectors start at\n"
"LBA -1, and consequently sector 63 is aligned on a 4KiB boundary).\n"
"This setting is overridden by the --dataalignmentoffset option.\n")
"This setting is overriden by the --dataalignmentoffset option.\n")
cfg(devices_ignore_suspended_devices_CFG, "ignore_suspended_devices", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_IGNORE_SUSPENDED_DEVICES, vsn(1, 2, 19), NULL, 0, NULL,
"Ignore DM devices that have I/O suspended while scanning devices.\n"
@@ -493,7 +467,7 @@ cfg(devices_ignore_lvm_mirrors_CFG, "ignore_lvm_mirrors", devices_CFG_SECTION, 0
"different way, making them a better choice for VG stacking.\n")
cfg(devices_disable_after_error_count_CFG, "disable_after_error_count", devices_CFG_SECTION, 0, CFG_TYPE_INT, 0, vsn(2, 2, 75), NULL, vsn(2, 3, 0), NULL,
NULL)
"This setting is no longer used.\n")
cfg(devices_require_restorefile_with_uuid_CFG, "require_restorefile_with_uuid", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_REQUIRE_RESTOREFILE_WITH_UUID, vsn(2, 2, 73), NULL, 0, NULL,
"Allow use of pvcreate --uuid without requiring --restorefile.\n")
@@ -654,11 +628,6 @@ cfg(allocation_cache_pool_max_chunks_CFG, "cache_pool_max_chunks", allocation_CF
cfg(allocation_thin_pool_metadata_require_separate_pvs_CFG, "thin_pool_metadata_require_separate_pvs", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS, vsn(2, 2, 89), NULL, 0, NULL,
"Thin pool metadata and data will always use different PVs.\n")
cfg(allocation_thin_pool_crop_metadata_CFG, "thin_pool_crop_metadata", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_CROP_METADATA, vsn(2, 3, 12), NULL, 0, NULL,
"Older version of lvm2 cropped pool's metadata size to 15.81 GiB.\n"
"This is slightly less then the actual maximum 15.88 GiB.\n"
"For compatibility with older version and use of cropped size set to 1.\n")
cfg(allocation_thin_pool_zero_CFG, "thin_pool_zero", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_ZERO, vsn(2, 2, 99), NULL, 0, NULL,
"Thin pool data chunks are zeroed before they are first used.\n"
"Zeroing with a larger thin pool chunk size reduces performance.\n")
@@ -974,13 +943,13 @@ cfg(global_activation_CFG, "activation", global_CFG_SECTION, 0, CFG_TYPE_BOOL, D
"the error messages.\n")
cfg(global_fallback_to_lvm1_CFG, "fallback_to_lvm1", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 0, vsn(1, 0, 18), NULL, vsn(2, 3, 0), NULL,
NULL)
"This setting is no longer used.\n")
cfg(global_format_CFG, "format", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_FORMAT, vsn(1, 0, 0), NULL, vsn(2, 3, 0), NULL,
NULL)
"This setting is no longer used.\n")
cfg_array(global_format_libraries_CFG, "format_libraries", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL, vsn(2, 3, 0), NULL,
NULL)
"This setting is no longer used.")
cfg_array(global_segment_libraries_CFG, "segment_libraries", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 18), NULL, vsn(2, 3, 3), NULL, NULL)
@@ -991,16 +960,16 @@ cfg(global_etc_CFG, "etc", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_ETC_D
"Location of /etc system configuration directory.\n")
cfg(global_locking_type_CFG, "locking_type", global_CFG_SECTION, 0, CFG_TYPE_INT, 1, vsn(1, 0, 0), NULL, vsn(2, 3, 0), NULL,
NULL)
"This setting is no longer used.")
cfg(global_wait_for_locks_CFG, "wait_for_locks", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_WAIT_FOR_LOCKS, vsn(2, 2, 50), NULL, 0, NULL,
"When disabled, fail if a lock request would block.\n")
cfg(global_fallback_to_clustered_locking_CFG, "fallback_to_clustered_locking", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_FALLBACK_TO_CLUSTERED_LOCKING, vsn(2, 2, 42), NULL, vsn(2, 3, 0), NULL,
NULL)
"This setting is no longer used.\n")
cfg(global_fallback_to_local_locking_CFG, "fallback_to_local_locking", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_FALLBACK_TO_LOCAL_LOCKING, vsn(2, 2, 42), NULL, vsn(2, 3, 0), NULL,
NULL)
"This setting is no longer used.\n")
cfg(global_locking_dir_CFG, "locking_dir", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_LOCK_DIR, vsn(1, 0, 0), "@DEFAULT_LOCK_DIR@", 0, NULL,
"Directory to use for LVM command file locks.\n"
@@ -1013,13 +982,14 @@ cfg(global_prioritise_write_locks_CFG, "prioritise_write_locks", global_CFG_SECT
"a volume group's metadata, instead of always granting the read-only\n"
"requests immediately, delay them to allow the read-write requests to\n"
"be serviced. Without this setting, write access may be stalled by a\n"
"high volume of read-only requests. This option only affects file locks.\n")
"high volume of read-only requests. This option only affects\n"
"locking_type 1 viz. local file-based locking.\n")
cfg(global_library_dir_CFG, "library_dir", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL, 0, NULL,
"Search this directory first for shared libraries.\n")
cfg(global_locking_library_CFG, "locking_library", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_LOCKING_LIB, vsn(1, 0, 0), NULL, vsn(2, 3, 0), NULL,
NULL)
"This setting is no longer used.\n")
cfg(global_abort_on_internal_errors_CFG, "abort_on_internal_errors", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ABORT_ON_INTERNAL_ERRORS, vsn(2, 2, 57), NULL, 0, NULL,
"Abort a command that encounters an internal error.\n"
@@ -1027,7 +997,7 @@ cfg(global_abort_on_internal_errors_CFG, "abort_on_internal_errors", global_CFG_
"encountered the internal error. Please only enable for debugging.\n")
cfg(global_detect_internal_vg_cache_corruption_CFG, "detect_internal_vg_cache_corruption", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 2, 96), NULL, vsn(2, 2, 174), NULL,
NULL)
"No longer used.\n")
cfg(global_metadata_read_only_CFG, "metadata_read_only", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_METADATA_READ_ONLY, vsn(2, 2, 75), NULL, 0, NULL,
"No operations that change on-disk metadata are permitted.\n"
@@ -1117,21 +1087,18 @@ cfg(global_lvdisplay_shows_full_device_path_CFG, "lvdisplay_shows_full_device_pa
cfg(global_event_activation_CFG, "event_activation", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 1, vsn(2, 3, 1), 0, 0, NULL,
"Activate LVs based on system-generated device events.\n"
"When a PV appears on the system, a system-generated uevent triggers\n"
"the lvm2-pvscan service which runs the pvscan --cache -aay command.\n"
"If the new PV completes a VG, pvscan autoactivates LVs in the VG.\n"
"When event_activation is disabled, the lvm2-activation services are\n"
"generated and run at fixed points during system startup. These\n"
"services run vgchange -aay to autoactivate LVs in VGs that happen\n"
"to be present at that point in time.\n"
"See the --setautoactivation option or the auto_activation_volume_list\n"
"setting to configure autoactivation for specific VGs or LVs.\n")
"When a device appears on the system, a system-generated event runs\n"
"the pvscan command to activate LVs if the new PV completes the VG.\n"
"Use auto_activation_volume_list to select which LVs should be\n"
"activated from these events (the default is all.)\n"
"When event_activation is disabled, the system will generally run\n"
"a direct activation command to activate LVs in complete VGs.\n")
cfg(global_use_lvmetad_CFG, "use_lvmetad", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 2, 93), 0, vsn(2, 3, 0), NULL,
NULL)
"This setting is no longer used.\n")
cfg(global_lvmetad_update_wait_time_CFG, "lvmetad_update_wait_time", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, 0, vsn(2, 2, 151), NULL, vsn(2, 3, 0), NULL,
NULL)
"This setting is no longer used.\n")
cfg(global_use_aio_CFG, "use_aio", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_USE_AIO, vsn(2, 2, 183), NULL, 0, NULL,
"Use async I/O when reading and writing devices.\n")
@@ -1155,15 +1122,6 @@ cfg(global_sanlock_lv_extend_CFG, "sanlock_lv_extend", global_CFG_SECTION, CFG_D
"and can cause lvcreate to fail. Applicable only if LVM is compiled\n"
"with lockd support\n")
cfg(global_lvmlockctl_kill_command_CFG, "lvmlockctl_kill_command", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, "", vsn(2, 3, 12), NULL, 0, NULL,
"The command that lvmlockctl --kill should use to force LVs offline.\n"
"The lvmlockctl --kill command is run when a shared VG has lost\n"
"access to locks (e.g. when sanlock has lost access to storage.)\n"
"An empty string means that there will be no automatic attempt by\n"
"lvmlockctl --kill to forcibly shut down LVs in the VG, and the user\n"
"can manually intervene as described in lvmlockd(8).\n"
"The VG name will be appended to the command specified here.\n")
cfg(global_thin_check_executable_CFG, "thin_check_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, THIN_CHECK_CMD, vsn(2, 2, 94), "@THIN_CHECK_CMD@", 0, NULL,
"The full path to the thin_check command.\n"
"LVM uses this command to check that a thin metadata device is in a\n"
@@ -1249,15 +1207,6 @@ cfg(global_vdo_format_executable_CFG, "vdo_format_executable", global_CFG_SECTIO
cfg_array(global_vdo_format_options_CFG, "vdo_format_options", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_VDO_FORMAT_OPTIONS_CONFIG, VDO_1ST_VSN, NULL, 0, NULL,
"List of options passed added to standard vdoformat command.\n")
cfg_array(global_vdo_disabled_features_CFG, "vdo_disabled_features", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 3, 11), NULL, 0, NULL,
"Features to not use in the vdo driver.\n"
"This can be helpful for testing, or to avoid using a feature that is\n"
"causing problems. Features include: online_rename\n"
"#\n"
"Example\n"
"vdo_disabled_features = [ \"online_rename\" ]\n"
"#\n")
cfg(global_fsadm_executable_CFG, "fsadm_executable", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_FSADM_PATH, vsn(2, 2, 170), "@FSADM_PATH@", 0, NULL,
"The full path to the fsadm command.\n"
"LVM uses this command to help with lvresize -r operations.\n")
@@ -1326,7 +1275,7 @@ cfg(global_io_memory_size_CFG, "io_memory_size", global_CFG_SECTION, CFG_DEFAULT
cfg(activation_udev_sync_CFG, "udev_sync", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_UDEV_SYNC, vsn(2, 2, 51), NULL, 0, NULL,
"Use udev notifications to synchronize udev and LVM.\n"
"The --noudevsync option overrides this setting.\n"
"The --nodevsync option overrides this setting.\n"
"When disabled, LVM commands will not wait for notifications from\n"
"udev, but continue irrespective of any possible udev processing in\n"
"the background. Only use this if udev is not running or has rules\n"
@@ -1405,22 +1354,22 @@ cfg_array(activation_volume_list_CFG, "volume_list", activation_CFG_SECTION, CFG
"#\n")
cfg_array(activation_auto_activation_volume_list_CFG, "auto_activation_volume_list", activation_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 97), NULL, 0, NULL,
"A list of VGs or LVs that should be autoactivated.\n"
"Autoactivation is an activation command run with -aay,\n"
"i.e. vgchange -aay, lvchange -aay, or pvscan --cache -aay.\n"
"When this list is defined, an autoactivation command will only\n"
"activate LVs included in the list. If this list is undefined,\n"
"it has no effect. If this list is defined but empty, then no\n"
"LVs will be autoactivated. LVs can be included in the list by\n"
"LV name, VG name (applies to all LVs in the VG), or tag name.\n"
"VGs and LVs can also have an autoactivation property set in\n"
"metadata, see --setautoactivation. LVs included in this list\n"
"will not be autoactivated if the VG or LV autoactivation\n"
"property is disabled (see vgs or lvs \"-o autoactivation\").\n"
"The volume_list setting and the \"activation skip\" property\n"
"also apply to autoactivation.\n"
"The -aay option is meant to be used by activation commands that\n"
"are run automatically by the system, e.g. from systemd services.\n"
"Only LVs selected by this list are auto-activated.\n"
"This list works like volume_list, but it is used only by\n"
"auto-activation commands. It does not apply to direct activation\n"
"commands. If this list is defined, an LV is only auto-activated\n"
"if it matches an entry in this list. If this list is undefined, it\n"
"imposes no limits on LV auto-activation (all are allowed.) If this\n"
"list is defined and empty, i.e. \"[]\", then no LVs are selected for\n"
"auto-activation. An LV that is selected by this list for\n"
"auto-activation, must also be selected by volume_list (if defined)\n"
"before it is activated. Auto-activation is an activation command that\n"
"includes the 'a' argument: --activate ay or -a ay. The 'a' (auto)\n"
"argument for auto-activation is meant to be used by activation\n"
"commands that are run automatically by the system, as opposed to LVM\n"
"commands run directly by a user. A user may also use the 'a' flag\n"
"directly to perform auto-activation. Also see pvscan(8) for more\n"
"information about auto-activation.\n"
"#\n"
"Accepted values:\n"
" vgname\n"
@@ -1776,7 +1725,7 @@ cfg(metadata_pvmetadataignore_CFG, "pvmetadataignore", metadata_CFG_SECTION, CFG
cfg(metadata_stripesize_CFG, "stripesize", metadata_CFG_SECTION, CFG_ADVANCED | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_STRIPESIZE, vsn(1, 0, 0), NULL, 0, NULL, NULL)
cfg_array(metadata_dirs_CFG, "dirs", metadata_CFG_SECTION, CFG_ADVANCED | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL, vsn(2, 3, 0), NULL,
NULL)
"This setting is no longer used.\n")
cfg_section(metadata_disk_areas_CFG_SUBSECTION, "disk_areas", metadata_CFG_SECTION, CFG_UNSUPPORTED | CFG_DEFAULT_COMMENTED, vsn(1, 0, 0), vsn(2, 3, 0), NULL, NULL)
cfg_section(disk_area_CFG_SUBSECTION, "disk_area", metadata_disk_areas_CFG_SUBSECTION, CFG_NAME_VARIABLE | CFG_UNSUPPORTED | CFG_DEFAULT_COMMENTED, vsn(1, 0, 0), vsn(2, 3, 0), NULL, NULL)

View File

@@ -118,8 +118,6 @@
#define DEFAULT_THIN_REPAIR_OPTION1 ""
#define DEFAULT_THIN_REPAIR_OPTIONS_CONFIG "#S" DEFAULT_THIN_REPAIR_OPTION1
#define DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS 0
#define DEFAULT_THIN_POOL_CROP_METADATA 0
#define DEFAULT_THIN_POOL_MAX_METADATA_SIZE_V1_KB (UINT64_C(255) * ((1 << 14) - 64) * 4) /* KB */ /* 0x3f8040 blocks */
#define DEFAULT_THIN_POOL_MAX_METADATA_SIZE (DM_THIN_MAX_METADATA_SIZE / 2) /* KB */
#define DEFAULT_THIN_POOL_MIN_METADATA_SIZE 2048 /* KB */
#define DEFAULT_THIN_POOL_OPTIMAL_METADATA_SIZE (128 * 1024) /* KB */
@@ -323,9 +321,4 @@
#define DEFAULT_MD_COMPONENT_CHECKS "auto"
#define DEFAULT_USE_DEVICES_FILE 0
#define DEFAULT_DEVICES_FILE "system.devices"
#define DEFAULT_SEARCH_FOR_DEVNAMES "auto"
#endif /* _LVM_DEFAULTS_H */

View File

@@ -218,7 +218,7 @@ struct dm_list *str_to_str_list(struct dm_pool *mem, const char *str,
return NULL;
}
p1 = str;
p1 = p2 = str;
while (*p1) {
if (!(p2 = strstr(p1, delim)))
next = p2 = str + strlen(str);

View File

@@ -42,7 +42,7 @@ static int *_fd_table;
static void log_sys_warn(const char *call)
{
log_warn("WARNING: %s failed: %s.", call, strerror(errno));
log_warn("%s failed: %s", call, strerror(errno));
}
// Assumes the list is not empty.
@@ -74,7 +74,7 @@ static struct cb_set *_cb_set_create(unsigned nr)
unsigned i;
struct cb_set *cbs = malloc(sizeof(*cbs) + nr * sizeof(*cbs->vec));
if (!cbs)
if (!cbs->vec)
return NULL;
dm_list_init(&cbs->free);
@@ -92,7 +92,7 @@ static void _cb_set_destroy(struct cb_set *cbs)
// never be in flight IO.
if (!dm_list_empty(&cbs->allocated)) {
// bail out
log_warn("WARNING: async io still in flight.");
log_error("async io still in flight");
return;
}
@@ -1351,26 +1351,26 @@ static bool _writeback_v(struct radix_tree_iterator *it,
struct block *b = v.ptr;
if (_test_flags(b, BF_DIRTY))
_issue_write(b);
_issue_write(b);
return true;
return true;
}
static bool _invalidate_v(struct radix_tree_iterator *it,
uint8_t *kb, uint8_t *ke, union radix_value v)
{
struct block *b = v.ptr;
struct invalidate_iterator *iit = container_of(it, struct invalidate_iterator, it);
struct invalidate_iterator *iit = container_of(it, struct invalidate_iterator, it);
if (b->error || _test_flags(b, BF_DIRTY)) {
log_warn("WARNING: bcache_invalidate: block (%d, %llu) still dirty.",
b->di, (unsigned long long) b->index);
iit->success = false;
return true;
log_warn("bcache_invalidate: block (%d, %llu) still dirty",
b->di, (unsigned long long) b->index);
iit->success = false;
return true;
}
if (b->ref_count) {
log_warn("WARNING: bcache_invalidate: block (%d, %llu) still held.",
log_warn("bcache_invalidate: block (%d, %llu) still held",
b->di, (unsigned long long) b->index);
iit->success = false;
return true;
@@ -1386,7 +1386,7 @@ static bool _invalidate_v(struct radix_tree_iterator *it,
bool bcache_invalidate_di(struct bcache *cache, int di)
{
union key k;
union key k;
struct invalidate_iterator it;
k.parts.di = di;
@@ -1401,7 +1401,7 @@ bool bcache_invalidate_di(struct bcache *cache, int di)
radix_tree_iterate(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.di), &it.it);
if (it.success)
(void) radix_tree_remove_prefix(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.di));
radix_tree_remove_prefix(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.di));
return it.success;
}
@@ -1429,14 +1429,14 @@ static bool _abort_v(struct radix_tree_iterator *it,
void bcache_abort_di(struct bcache *cache, int di)
{
union key k;
union key k;
struct radix_tree_iterator it;
k.parts.di = di;
it.visit = _abort_v;
radix_tree_iterate(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.di), &it);
(void) radix_tree_remove_prefix(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.di));
radix_tree_remove_prefix(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.di));
}
//----------------------------------------------------------------
@@ -1512,9 +1512,10 @@ int bcache_change_fd(int di, int fd)
if (di >= _fd_table_size)
return 0;
if (di < 0) {
log_error(INTERNAL_ERROR "Cannot change not opened DI with FD:%d", fd);
log_error(INTERNAL_ERROR "Cannot change not openned DI with FD:%d", fd);
return 0;
}
_fd_table[di] = fd;
return 1;
}

View File

@@ -16,7 +16,6 @@
#include "base/memory/zalloc.h"
#include "lib/misc/lib.h"
#include "lib/device/dev-type.h"
#include "lib/device/device_id.h"
#include "lib/datastruct/btree.h"
#include "lib/config/config.h"
#include "lib/commands/toolcontext.h"
@@ -28,7 +27,6 @@
#endif
#include <unistd.h>
#include <dirent.h>
#include <locale.h>
struct dev_iter {
struct btree_iter *current;
@@ -70,13 +68,11 @@ static void _dev_init(struct device *dev)
dev->bcache_fd = -1;
dev->bcache_di = -1;
dev->read_ahead = -1;
dev->part = -1;
dev->ext.enabled = 0;
dev->ext.src = DEV_EXT_NONE;
dm_list_init(&dev->aliases);
dm_list_init(&dev->ids);
}
void dev_destroy_file(struct device *dev)
@@ -293,13 +289,13 @@ static int _compare_paths(const char *path0, const char *path1)
/* We prefer symlinks - they exist for a reason!
* So we prefer a shorter path before the first symlink in the name.
* FIXME Configuration option to invert this? */
while (s0 && s1) {
if ((s0 = strchr(s0, '/')))
while (s0) {
s0 = strchr(s0, '/');
s1 = strchr(s1, '/');
if (s0) {
*s0 = '\0';
if ((s1 = strchr(s1, '/')))
*s1 = '\0';
}
if (lstat(p0, &stat0)) {
log_sys_very_verbose("lstat", p0);
return 1;
@@ -312,10 +308,10 @@ static int _compare_paths(const char *path0, const char *path1)
return 0;
if (!S_ISLNK(stat0.st_mode) && S_ISLNK(stat1.st_mode))
return 1;
if (s0)
if (s0) {
*s0++ = '/';
if (s1)
*s1++ = '/';
}
}
/* ASCII comparison */
@@ -325,38 +321,20 @@ static int _compare_paths(const char *path0, const char *path1)
return 1;
}
enum add_hash {
NO_HASH,
HASH,
REHASH
};
static int _add_alias(struct device *dev, const char *path, enum add_hash hash)
static int _add_alias(struct device *dev, const char *path)
{
struct dm_str_list *sl;
struct dm_str_list *sl = _zalloc(sizeof(*sl));
struct dm_str_list *strl;
const char *oldpath;
int prefer_old = 1;
if (hash == REHASH)
dm_hash_remove(_cache.names, path);
if (!sl)
return_0;
/* Is name already there? */
dm_list_iterate_items(strl, &dev->aliases)
if (!strcmp(strl->str, path)) {
path = strl->str;
goto out;
}
if (!(path = dm_pool_strdup(_cache.mem, path)) ||
!(sl = _zalloc(sizeof(*sl)))) {
log_error("Failed to add allias to dev cache.");
return 0;
}
if (!strncmp(path, "/dev/nvme", 9)) {
log_debug("Found nvme device %s", dev_name(dev));
dev->flags |= DEV_IS_NVME;
dm_list_iterate_items(strl, &dev->aliases) {
if (!strcmp(strl->str, path))
return 1;
}
sl->str = path;
@@ -370,17 +348,11 @@ static int _add_alias(struct device *dev, const char *path, enum add_hash hash)
dm_list_add(&dev->aliases, &sl->list);
else
dm_list_add_h(&dev->aliases, &sl->list);
out:
if ((hash != NO_HASH) &&
!dm_hash_insert(_cache.names, path, dev)) {
log_error("Couldn't add name to hash in dev cache.");
return 0;
}
return 1;
}
int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value)
static int _get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value)
{
FILE *fp;
size_t len;
@@ -407,7 +379,7 @@ int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_n
r = 1;
out:
if (fclose(fp))
log_sys_debug("fclose", path);
log_sys_error("fclose", path);
return r;
}
@@ -421,7 +393,7 @@ static int _get_dm_uuid_from_sysfs(char *buf, size_t buf_size, int major, int mi
return 0;
}
return get_sysfs_value(path, buf, buf_size, 0);
return _get_sysfs_value(path, buf, buf_size, 0);
}
static struct dm_list *_get_or_add_list_by_index_key(struct dm_hash_table *idx, const char *key)
@@ -451,6 +423,7 @@ static struct device *_insert_sysfs_dev(dev_t devno, const char *devname)
static struct device _fake_dev = { .flags = DEV_USED_FOR_LV };
struct stat stat0;
char path[PATH_MAX];
char *path_copy;
struct device *dev;
if (dm_snprintf(path, sizeof(path), "%s%s", _cache.dev_dir, devname) < 0) {
@@ -468,9 +441,15 @@ static struct device *_insert_sysfs_dev(dev_t devno, const char *devname)
if (!(dev = _dev_create(devno)))
return_NULL;
if (!_add_alias(dev, path, NO_HASH)) {
if (!(path_copy = dm_pool_strdup(_cache.mem, path))) {
log_error("_insert_sysfs_dev: %s: dm_pool_strdup failed", devname);
return NULL;
}
if (!_add_alias(dev, path_copy)) {
log_error("Couldn't add alias to dev cache.");
_free(dev);
return_NULL;
return NULL;
}
if (!btree_insert(_cache.sysfs_only_devices, (uint32_t) devno, dev)) {
@@ -495,7 +474,7 @@ static struct device *_get_device_for_sysfs_dev_name_using_devno(const char *dev
return NULL;
}
if (!get_sysfs_value(path, buf, sizeof(buf), 1))
if (!_get_sysfs_value(path, buf, sizeof(buf), 1))
return_NULL;
if (sscanf(buf, "%d:%d", &major, &minor) != 2) {
@@ -666,7 +645,7 @@ static int _index_dev_by_vgid_and_lvid(struct device *dev)
r = 1;
out:
if (closedir(d))
log_sys_debug("closedir", path);
log_sys_error("closedir", path);
return r;
}
@@ -712,6 +691,7 @@ static int _insert_dev(const char *path, dev_t d)
struct device *dev;
struct device *dev_by_devt;
struct device *dev_by_path;
char *path_copy;
dev_by_devt = (struct device *) btree_lookup(_cache.devices, (uint32_t) d);
dev_by_path = (struct device *) dm_hash_lookup(_cache.names, path);
@@ -745,8 +725,20 @@ static int _insert_dev(const char *path, dev_t d)
return 0;
}
if (!_add_alias(dev, path, HASH))
return_0;
if (!(path_copy = dm_pool_strdup(_cache.mem, path))) {
log_error("Failed to duplicate path string.");
return 0;
}
if (!_add_alias(dev, path_copy)) {
log_error("Couldn't add alias to dev cache.");
return 0;
}
if (!dm_hash_insert(_cache.names, path_copy, dev)) {
log_error("Couldn't add name to hash in dev cache.");
return 0;
}
return 1;
}
@@ -758,8 +750,20 @@ static int _insert_dev(const char *path, dev_t d)
log_debug_devs("Found dev %d:%d %s - new alias.",
(int)MAJOR(d), (int)MINOR(d), path);
if (!_add_alias(dev, path, HASH))
return_0;
if (!(path_copy = dm_pool_strdup(_cache.mem, path))) {
log_error("Failed to duplicate path string.");
return 0;
}
if (!_add_alias(dev, path_copy)) {
log_error("Couldn't add alias to dev cache.");
return 0;
}
if (!dm_hash_insert(_cache.names, path_copy, dev)) {
log_error("Couldn't add name to hash in dev cache.");
return 0;
}
return 1;
}
@@ -785,10 +789,25 @@ static int _insert_dev(const char *path, dev_t d)
return 0;
}
if (!_add_alias(dev, path, REHASH))
return_0;
if (!(path_copy = dm_pool_strdup(_cache.mem, path))) {
log_error("Failed to duplicate path string.");
return 0;
}
if (!_add_alias(dev, path_copy)) {
log_error("Couldn't add alias to dev cache.");
return 0;
}
dm_hash_remove(_cache.names, path);
if (!dm_hash_insert(_cache.names, path_copy, dev)) {
log_error("Couldn't add name to hash in dev cache.");
return 0;
}
return 1;
}
/*
@@ -800,8 +819,22 @@ static int _insert_dev(const char *path, dev_t d)
(int)MAJOR(d), (int)MINOR(d), path,
(int)MAJOR(dev_by_path->dev), (int)MINOR(dev_by_path->dev));
if (!_add_alias(dev, path, REHASH))
return_0;
if (!(path_copy = dm_pool_strdup(_cache.mem, path))) {
log_error("Failed to duplicate path string.");
return 0;
}
if (!_add_alias(dev, path_copy)) {
log_error("Couldn't add alias to dev cache.");
return 0;
}
dm_hash_remove(_cache.names, path);
if (!dm_hash_insert(_cache.names, path_copy, dev)) {
log_error("Couldn't add name to hash in dev cache.");
return 0;
}
return 1;
}
@@ -810,6 +843,16 @@ static int _insert_dev(const char *path, dev_t d)
return 0;
}
static char *_join(const char *dir, const char *name)
{
size_t len = strlen(dir) + strlen(name) + 2;
char *r = malloc(len);
if (r)
snprintf(r, len, "%s/%s", dir, name);
return r;
}
/*
* Get rid of extra slashes in the path string.
*/
@@ -836,39 +879,27 @@ static int _insert_dir(const char *dir)
{
int n, dirent_count, r = 1;
struct dirent **dirent;
char path[PATH_MAX];
size_t len;
char *path;
if (!dm_strncpy(path, dir, sizeof(path) - 1)) {
log_debug_devs("Dir path %s is too long", path);
return 0;
}
_collapse_slashes(path);
len = strlen(path);
if (len && path[len - 1] != '/')
path[len++] = '/';
setlocale(LC_COLLATE, "C"); /* Avoid sorting by locales */
dirent_count = scandir(dir, &dirent, NULL, alphasort);
if (dirent_count > 0) {
for (n = 0; n < dirent_count; n++) {
if (dirent[n]->d_name[0] == '.')
continue;
if (!dm_strncpy(path + len, dirent[n]->d_name, sizeof(path) - len)) {
log_debug_devs("Path %s/%s is too long.", dir, dirent[n]->d_name);
r = 0;
if (dirent[n]->d_name[0] == '.') {
free(dirent[n]);
continue;
}
r &= _insert(path, NULL, 1, 0);
}
if (!(path = _join(dir, dirent[n]->d_name)))
return_0;
_collapse_slashes(path);
r &= _insert(path, NULL, 1, 0);
free(path);
for (n = 0; n < dirent_count; n++)
free(dirent[n]);
}
free(dirent);
}
setlocale(LC_COLLATE, "");
return r;
}
@@ -936,12 +967,12 @@ static int _dev_cache_iterate_sysfs_for_index(const char *path)
r = !partial_failure;
if (closedir(d))
log_sys_debug("closedir", path);
log_sys_error("closedir", path);
return r;
}
static int dev_cache_index_devs(void)
int dev_cache_index_devs(void)
{
static int sysfs_has_dev_block = -1;
char path[PATH_MAX];
@@ -962,7 +993,7 @@ static int dev_cache_index_devs(void)
return 1;
}
log_sys_debug("stat", path);
log_sys_error("stat", path);
return 0;
}
} else if (!sysfs_has_dev_block)
@@ -1222,9 +1253,9 @@ int dev_cache_init(struct cmd_context *cmd)
if (!(_cache.mem = dm_pool_create("dev_cache", 10 * 1024)))
return_0;
if (!(_cache.names = dm_hash_create(120)) ||
!(_cache.vgid_index = dm_hash_create(30)) ||
!(_cache.lvid_index = dm_hash_create(29))) {
if (!(_cache.names = dm_hash_create(128)) ||
!(_cache.vgid_index = dm_hash_create(32)) ||
!(_cache.lvid_index = dm_hash_create(32))) {
dm_pool_destroy(_cache.mem);
_cache.mem = 0;
return_0;
@@ -1290,20 +1321,12 @@ int dev_cache_check_for_open_devices(void)
int dev_cache_exit(void)
{
struct device *dev;
struct dm_hash_node *n;
int num_open = 0;
if (_cache.names) {
if (_cache.names)
if ((num_open = _check_for_open_devices(1)) > 0)
log_error(INTERNAL_ERROR "%d device(s) were left open and have been closed.", num_open);
dm_hash_iterate(n, _cache.names) {
dev = (struct device *) dm_hash_get_data(_cache.names, n);
free_dids(&dev->ids);
}
}
if (_cache.mem)
dm_pool_destroy(_cache.mem);
@@ -1405,165 +1428,93 @@ struct device *dev_hash_get(const char *name)
return (struct device *) dm_hash_lookup(_cache.names, name);
}
static void _remove_alias(struct device *dev, const char *name)
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f)
{
struct dm_str_list *strl;
struct stat buf;
struct device *d = (struct device *) dm_hash_lookup(_cache.names, name);
int info_available = 0;
int ret = 1;
dm_list_iterate_items(strl, &dev->aliases) {
if (!strcmp(strl->str, name)) {
dm_list_del(&strl->list);
return;
if (d && (d->flags & DEV_REGULAR))
return d;
/* If the entry's wrong, remove it */
if (stat(name, &buf) < 0) {
if (d)
dm_hash_remove(_cache.names, name);
log_sys_very_verbose("stat", name);
d = NULL;
} else
info_available = 1;
if (d && (buf.st_rdev != d->dev)) {
dm_hash_remove(_cache.names, name);
d = NULL;
}
if (!d) {
_insert(name, info_available ? &buf : NULL, 0, obtain_device_list_from_udev());
d = (struct device *) dm_hash_lookup(_cache.names, name);
if (!d) {
log_debug_devs("Device name not found in dev_cache repeat dev_cache_scan for %s", name);
dev_cache_scan();
d = (struct device *) dm_hash_lookup(_cache.names, name);
}
}
if (!d)
return NULL;
if (d && (d->flags & DEV_REGULAR))
return d;
if (f && !(d->flags & DEV_REGULAR)) {
ret = f->passes_filter(cmd, f, d, NULL);
if (ret == -EAGAIN) {
log_debug_devs("get device by name defer filter %s", dev_name(d));
d->flags |= DEV_FILTER_AFTER_SCAN;
ret = 1;
}
}
if (f && !(d->flags & DEV_REGULAR) && !ret)
return NULL;
return d;
}
static struct device *_dev_cache_seek_devt(dev_t dev)
{
struct device *d = NULL;
struct dm_hash_node *n = dm_hash_get_first(_cache.names);
while (n) {
d = dm_hash_get_data(_cache.names, n);
if (d->dev == dev)
return d;
n = dm_hash_get_next(_cache.names, n);
}
return NULL;
}
/*
* Check that paths for this dev still refer to the same dev_t. This is known
* to drop invalid paths in the case where lvm deactivates an LV, which causes
* that LV path to go away, but that LV path is not removed from dev-cache (it
* probably should be). Later a new path to a different LV is added to
* dev-cache, where the new LV has the same major:minor as the previously
* deactivated LV. The new LV will find the existing struct dev, and that
* struct dev will have dev->aliases entries that refer to the name of the old
* deactivated LV. Those old paths are all invalid and are dropped here.
* TODO This is very inefficient. We probably want a hash table indexed by
* major:minor for keys to speed up these lookups.
*/
static void _verify_aliases(struct device *dev, const char *newname)
{
struct dm_str_list *strl, *strl2;
struct stat st;
dm_list_iterate_items_safe(strl, strl2, &dev->aliases) {
/* newname was just stat'd and added by caller */
if (newname && !strcmp(strl->str, newname))
continue;
if (stat(strl->str, &st) || (st.st_rdev != dev->dev)) {
log_debug("Drop invalid path %s for %d:%d (new path %s).",
strl->str, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), newname ?: "");
dm_hash_remove(_cache.names, strl->str);
dm_list_del(&strl->list);
}
}
}
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f)
{
struct device *dev = (struct device *) dm_hash_lookup(_cache.names, name);
struct stat st;
int ret;
/*
* DEV_REGULAR means that is "dev" is actually a file, not a device.
* FIXME: I don't think dev-cache is used for files any more and this
* can be dropped?
*/
if (dev && (dev->flags & DEV_REGULAR))
return dev;
/*
* The requested path is invalid, remove any dev-cache
* info for it.
*/
if (stat(name, &st)) {
if (dev) {
log_print("Device path %s is invalid for %d:%d %s.",
name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev));
dm_hash_remove(_cache.names, name);
_remove_alias(dev, name);
/* Remove any other names in dev->aliases that are incorrect. */
_verify_aliases(dev, NULL);
}
return NULL;
}
if (!S_ISBLK(st.st_mode)) {
log_debug("Not a block device %s.", name);
return NULL;
}
/*
* dev-cache has incorrect info for the requested path.
* Remove incorrect info and then add new dev-cache entry.
*/
if (dev && (st.st_rdev != dev->dev)) {
log_debug("Device path %s does not match %d:%d %s.",
name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev));
dm_hash_remove(_cache.names, name);
_remove_alias(dev, name);
/* Remove any other names in dev->aliases that are incorrect. */
_verify_aliases(dev, NULL);
/* Add new dev-cache entry next. */
dev = NULL;
}
/*
* Either add a new struct dev for st_rdev and name,
* or add name as a new alias for an existing struct dev
* for st_rdev.
*/
if (!dev) {
if (!_insert_dev(name, st.st_rdev))
return_NULL;
/* Get the struct dev that was just added. */
dev = (struct device *) dm_hash_lookup(_cache.names, name);
if (!dev) {
log_error("Failed to get device %s", name);
return NULL;
}
_verify_aliases(dev, name);
}
/*
* The caller passed a filter if they only want the dev if it
* passes filters.
*/
if (!f)
return dev;
ret = f->passes_filter(cmd, f, dev, NULL);
/*
* This might happen if this function is called before
* filters can do i/o. I don't think this will happen
* any longer and this EAGAIN case can be removed.
*/
if (ret == -EAGAIN) {
log_debug_devs("dev_cache_get filter deferred %s", dev_name(dev));
dev->flags |= DEV_FILTER_AFTER_SCAN;
ret = 1;
}
if (!ret) {
log_debug_devs("dev_cache_get filter excludes %s", dev_name(dev));
return NULL;
}
return dev;
}
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t dev, struct dev_filter *f, int *filtered)
{
char path[PATH_MAX];
const char *sysfs_dir;
struct stat info;
struct device *d = (struct device *) btree_lookup(_cache.devices, (uint32_t) dev);
struct device *d = _dev_cache_seek_devt(dev);
int ret;
if (filtered)
*filtered = 0;
if (d && (d->flags & DEV_REGULAR))
return d;
if (!d) {
sysfs_dir = dm_sysfs_dir();
if (sysfs_dir && *sysfs_dir) {
@@ -1584,12 +1535,12 @@ struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t dev, struct
log_debug_devs("Device num not found in dev_cache repeat dev_cache_scan for %d:%d",
(int)MAJOR(dev), (int)MINOR(dev));
dev_cache_scan();
d = (struct device *) btree_lookup(_cache.devices, (uint32_t) dev);
if (!d)
return NULL;
d = _dev_cache_seek_devt(dev);
}
if (!d)
return NULL;
if (d->flags & DEV_REGULAR)
return d;
@@ -1609,7 +1560,6 @@ struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t dev, struct
if (filtered)
*filtered = 1;
return NULL;
}
@@ -1699,335 +1649,3 @@ bool dev_cache_has_md_with_end_superblock(struct dev_types *dt)
return false;
}
static int _setup_devices_list(struct cmd_context *cmd)
{
struct dm_str_list *strl;
struct dev_use *du;
/*
* For each --devices arg, add a du to cmd->use_devices.
* The du has devname is the devices arg value.
*/
dm_list_iterate_items(strl, &cmd->deviceslist) {
if (!(du = dm_pool_zalloc(cmd->mem, sizeof(struct dev_use))))
return_0;
if (!(du->devname = dm_pool_strdup(cmd->mem, strl->str)))
return_0;
dm_list_add(&cmd->use_devices, &du->list);
}
return 1;
}
static int _setup_devices_file_dmeventd(struct cmd_context *cmd)
{
char path[PATH_MAX];
struct stat st;
/*
* When command is run by dmeventd there is no --devicesfile
* option that can enable/disable the use of a devices file.
*/
if (!find_config_tree_bool(cmd, devices_use_devicesfile_CFG, NULL)) {
cmd->enable_devices_file = 0;
return 1;
}
/*
* If /etc/lvm/devices/dmeventd.devices exists, then use that.
* The optional dmeventd.devices allows the user to control
* which devices dmeventd will look at and use.
* Otherwise, disable the devices file because dmeventd should
* be able to manage LVs in any VG (i.e. LVs in a non-system
* devices file.)
*/
if (dm_snprintf(path, sizeof(path), "%s/devices/dmeventd.devices", cmd->system_dir) < 0) {
log_warn("Failed to copy devices path");
cmd->enable_devices_file = 0;
return 1;
}
if (stat(path, &st)) {
/* No dmeventd.devices, so do not use a devices file. */
cmd->enable_devices_file = 0;
return 1;
}
cmd->enable_devices_file = 1;
(void) dm_strncpy(cmd->devices_file_path, path, sizeof(cmd->devices_file_path));
return 1;
}
int setup_devices_file(struct cmd_context *cmd)
{
char dirpath[PATH_MAX];
const char *filename = NULL;
struct stat st;
int rv;
if (cmd->run_by_dmeventd)
return _setup_devices_file_dmeventd(cmd);
if (cmd->devicesfile) {
/* --devicesfile <filename> or "" has been set which overrides
lvm.conf settings use_devicesfile and devicesfile. */
if (!strlen(cmd->devicesfile))
cmd->enable_devices_file = 0;
else {
cmd->enable_devices_file = 1;
filename = cmd->devicesfile;
}
/* TODO: print a warning if --devicesfile system.devices
while lvm.conf use_devicesfile=0. */
} else {
if (!find_config_tree_bool(cmd, devices_use_devicesfile_CFG, NULL))
cmd->enable_devices_file = 0;
else {
cmd->enable_devices_file = 1;
filename = find_config_tree_str(cmd, devices_devicesfile_CFG, NULL);
if (!validate_name(filename)) {
log_error("Invalid devices file name from config setting \"%s\".", filename);
return 0;
}
}
}
if (!cmd->enable_devices_file)
return 1;
if (dm_snprintf(dirpath, sizeof(dirpath), "%s/devices", cmd->system_dir) < 0) {
log_error("Failed to copy devices dir path");
return 0;
}
if (stat(dirpath, &st)) {
log_debug("Creating %s.", dirpath);
dm_prepare_selinux_context(dirpath, S_IFDIR);
rv = mkdir(dirpath, 0755);
dm_prepare_selinux_context(NULL, 0);
if ((rv < 0) && stat(dirpath, &st)) {
log_error("Failed to create %s %d", dirpath, errno);
return 0;
}
}
if (dm_snprintf(cmd->devices_file_path, sizeof(cmd->devices_file_path),
"%s/devices/%s", cmd->system_dir, filename) < 0) {
log_error("Failed to copy devices file path");
return 0;
}
return 1;
}
/*
* Add all system devices to dev-cache, and attempt to
* match all devices_file entries to dev-cache entries.
*/
int setup_devices(struct cmd_context *cmd)
{
int file_exists;
int lock_mode = 0;
if (cmd->enable_devices_list) {
if (!_setup_devices_list(cmd))
return_0;
goto scan;
}
if (!setup_devices_file(cmd))
return_0;
if (!cmd->enable_devices_file)
goto scan;
file_exists = devices_file_exists(cmd);
/*
* Removing the devices file is another way of disabling the use of
* a devices file, unless the command creates the devices file.
*/
if (!file_exists && !cmd->create_edit_devices_file) {
log_debug("Devices file not found, ignoring.");
cmd->enable_devices_file = 0;
goto scan;
}
/*
* Don't let pvcreate or vgcreate create a new system devices file
* unless it's specified explicitly with --devicesfile. This avoids
* a problem where a system is running with existing PVs, and is
* not using a devices file based on the fact that the system
* devices file doesn't exist. If the user simply uses pvcreate
* to create a new PV, they almost certainly do not want that to
* create a new system devices file containing the new PV and none
* of the existing PVs that the system is already using.
* However, if they use the vgimportdevices or lvmdevices command
* then they are clearly intending to use the devices file, so we
* can create it. Or, if they specify a non-system devices file
* with pvcreate/vgcreate, then they clearly want to use a devices
* file and we can create it (and creating a non-system devices file
* would not cause existing PVs to disappear from the main system.)
*
* An exception is if pvcreate/vgcreate get to device_id_write and
* did not see any existing VGs during label scan. In that case
* they will create a new system devices file, since there will be
* no VGs that the new file would hide.
*/
if (cmd->create_edit_devices_file && !cmd->devicesfile && !file_exists &&
(!strncmp(cmd->name, "pvcreate", 8) || !strncmp(cmd->name, "vgcreate", 8))) {
/* The command will decide in device_ids_write whether to create
a new system devices file. */
cmd->enable_devices_file = 0;
cmd->pending_devices_file = 1;
goto scan;
}
if (!file_exists && cmd->sysinit) {
cmd->enable_devices_file = 0;
goto scan;
}
if (!file_exists) {
/*
* pvcreate/vgcreate/vgimportdevices/lvmdevices-add create
* a new devices file here if it doesn't exist.
* They have the create_edit_devices_file flag set.
* First they create/lock-ex the devices file lockfile.
* Other commands will not use a devices file if none exists.
*/
lock_mode = LOCK_EX;
if (!lock_devices_file(cmd, lock_mode)) {
log_error("Failed to lock the devices file to create.");
return 0;
}
/* The file will be created in device_ids_write() */
if (!devices_file_exists(cmd))
goto scan;
} else {
/*
* Commands that intend to edit the devices file have
* edit_devices_file or create_edit_devices_file set (create if
* they can also create a new devices file) and lock it ex
* here prior to reading. Other commands that intend to just
* read the devices file lock sh.
*/
lock_mode = (cmd->create_edit_devices_file || cmd->edit_devices_file) ? LOCK_EX : LOCK_SH;
if (!lock_devices_file(cmd, lock_mode)) {
log_error("Failed to lock the devices file.");
return 0;
}
}
/*
* Read the list of device ids that lvm can use.
* Adds a struct dev_id to cmd->use_devices for each one.
*/
if (!device_ids_read(cmd)) {
log_error("Failed to read the devices file.");
unlock_devices_file(cmd);
return 0;
}
/*
* When the command is editing the devices file, it acquires
* the ex lock above, will later call device_ids_write(), and
* then unlock the lock after writing the file.
* When the command is just reading the devices file, it's
* locked sh above just before reading the file, and unlocked
* here after reading.
*/
if (lock_mode == LOCK_SH)
unlock_devices_file(cmd);
scan:
/*
* Add a 'struct device' to dev-cache for each device available on the system.
* This will not open or read any devices, but may look at sysfs properties.
* This list of devs comes from looking /dev entries, or from asking libudev.
*/
dev_cache_scan();
/*
* Match entries from cmd->use_devices with device structs in dev-cache.
*/
device_ids_match(cmd);
return 1;
}
/*
* The alternative to setup_devices() when the command is interested
* in using only one PV.
*
* Add one system device to dev-cache, and attempt to
* match its dev-cache entry to a devices_file entry.
*/
int setup_device(struct cmd_context *cmd, const char *devname)
{
struct stat buf;
struct device *dev;
if (cmd->enable_devices_list) {
if (!_setup_devices_list(cmd))
return_0;
goto scan;
}
if (!setup_devices_file(cmd))
return_0;
if (!cmd->enable_devices_file)
goto scan;
if (!devices_file_exists(cmd)) {
log_debug("Devices file not found, ignoring.");
cmd->enable_devices_file = 0;
goto scan;
}
if (!lock_devices_file(cmd, LOCK_SH)) {
log_error("Failed to lock the devices file to read.");
return 0;
}
if (!device_ids_read(cmd)) {
log_error("Failed to read the devices file.");
unlock_devices_file(cmd);
return 0;
}
unlock_devices_file(cmd);
scan:
if (stat(devname, &buf) < 0) {
log_error("Cannot access device %s.", devname);
return 0;
}
if (!S_ISBLK(buf.st_mode)) {
log_error("Invaild device type %s.", devname);
return 0;
}
if (!_insert_dev(devname, buf.st_rdev))
return_0;
if (!(dev = (struct device *) dm_hash_lookup(_cache.names, devname)))
return_0;
/* Match this device to an entry in devices_file so it will not
be rejected by filter-deviceid. */
if (cmd->enable_devices_file)
device_ids_match_dev(cmd, dev);
return 1;
}

View File

@@ -34,6 +34,7 @@ struct dev_filter {
const char *name;
};
int dev_cache_index_devs(void);
struct dm_list *dev_cache_get_dev_list_for_vgid(const char *vgid);
struct dm_list *dev_cache_get_dev_list_for_lvid(const char *lvid);
@@ -74,10 +75,4 @@ void dev_cache_failed_path(struct device *dev, const char *path);
bool dev_cache_has_md_with_end_superblock(struct dev_types *dt);
int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value);
int setup_devices_file(struct cmd_context *cmd);
int setup_devices(struct cmd_context *cmd);
int setup_device(struct cmd_context *cmd, const char *devname);
#endif

View File

@@ -81,7 +81,7 @@ typedef struct dasd_information2_t {
int dasd_is_cdl_formatted(struct device *dev)
{
int ret = 0;
dasd_information2_t dasd_info2 = { 0 };
dasd_information2_t dasd_info2;
if (!dev_open_readonly(dev))
return_0;

View File

@@ -104,7 +104,7 @@ static int _dev_get_size_dev(struct device *dev, uint64_t *size)
}
if (ioctl(fd, BLKGETSIZE64, size) < 0) {
log_warn("WARNING: %s: ioctl BLKGETSIZE64 %s", name, strerror(errno));
log_sys_error("ioctl BLKGETSIZE64", name);
if (do_close && !dev_close_immediate(dev))
stack;
return 0;
@@ -124,7 +124,7 @@ static int _dev_get_size_dev(struct device *dev, uint64_t *size)
static int _dev_read_ahead_dev(struct device *dev, uint32_t *read_ahead)
{
long read_ahead_long = 0;
long read_ahead_long;
if (dev->read_ahead != -1) {
*read_ahead = (uint32_t) dev->read_ahead;
@@ -132,13 +132,12 @@ static int _dev_read_ahead_dev(struct device *dev, uint32_t *read_ahead)
}
if (!dev_open_readonly_quiet(dev)) {
log_warn("WARNING: Failed to open %s to get readahead %s.",
dev_name(dev), strerror(errno));
log_error("Failed to open to get readahead %s", dev_name(dev));
return 0;
}
if (ioctl(dev->fd, BLKRAGET, &read_ahead_long) < 0) {
log_warn("WARNING: %s: ioctl BLKRAGET %s.", dev_name(dev), strerror(errno));
log_sys_error("ioctl BLKRAGET", dev_name(dev));
if (!dev_close_immediate(dev))
stack;
return 0;
@@ -171,7 +170,7 @@ static int _dev_discard_blocks(struct device *dev, uint64_t offset_bytes, uint64
test_mode() ? " (test mode - suppressed)" : "");
if (!test_mode() && ioctl(dev->fd, BLKDISCARD, &discard_range) < 0) {
log_warn("WARNING: %s: ioctl BLKDISCARD at offset %" PRIu64 " size %" PRIu64 " failed: %s.",
log_error("%s: BLKDISCARD ioctl at offset %" PRIu64 " size %" PRIu64 " failed: %s.",
dev_name(dev), offset_bytes, size_bytes, strerror(errno));
if (!dev_close_immediate(dev))
stack;

View File

@@ -55,17 +55,7 @@ static int _dev_has_md_magic(struct device *dev, uint64_t sb_offset)
static int _dev_has_imsm_magic(struct device *dev, uint64_t devsize_sectors)
{
char imsm_signature[IMSM_SIG_LEN];
uint64_t off;
unsigned int physical_block_size = 0;
unsigned int logical_block_size = 0;
if (!dev_get_direct_block_sizes(dev, &physical_block_size, &logical_block_size))
return_0;
if (logical_block_size == 4096)
off = (devsize_sectors * 512) - 8192;
else
off = (devsize_sectors * 512) - 1024;
uint64_t off = (devsize_sectors * 512) - 1024;
if (!dev_read_bytes(dev, off, IMSM_SIG_LEN, imsm_signature))
return_0;
@@ -166,14 +156,17 @@ static int _udev_dev_is_md_component(struct device *dev)
if (!(ext = dev_ext_get(dev)))
return_0;
if (!(value = udev_device_get_property_value((struct udev_device *)ext->handle, DEV_EXT_UDEV_BLKID_TYPE)))
if (!(value = udev_device_get_property_value((struct udev_device *)ext->handle, DEV_EXT_UDEV_BLKID_TYPE))) {
dev->flags |= DEV_UDEV_INFO_MISSING;
return 0;
}
return !strcmp(value, DEV_EXT_UDEV_BLKID_TYPE_SW_RAID);
}
#else
static int _udev_dev_is_md_component(struct device *dev)
{
dev->flags |= DEV_UDEV_INFO_MISSING;
return 0;
}
#endif

View File

@@ -21,7 +21,6 @@
#include "lib/metadata/metadata.h"
#include "lib/device/bcache.h"
#include "lib/label/label.h"
#include "lib/commands/toolcontext.h"
#ifdef BLKID_WIPING_SUPPORT
#include <blkid.h>
@@ -36,16 +35,36 @@
#include <ctype.h>
/*
* An nvme device has major number 259 (BLKEXT), minor number <minor>,
* and reading /sys/dev/block/259:<minor>/device/dev shows a character
* device cmajor:cminor where cmajor matches the major number of the
* nvme character device entry in /proc/devices. Checking all of that
* is excessive and unnecessary compared to just comparing /dev/name*.
* dev is pmem if /sys/dev/block/<major>:<minor>/queue/dax is 1
*/
int dev_is_nvme(struct dev_types *dt, struct device *dev)
int dev_is_pmem(struct device *dev)
{
return (dev->flags & DEV_IS_NVME) ? 1 : 0;
FILE *fp;
char path[PATH_MAX];
int is_pmem = 0;
if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/queue/dax",
dm_sysfs_dir(),
(int) MAJOR(dev->dev),
(int) MINOR(dev->dev)) < 0) {
log_warn("Sysfs path for %s dax is too long.", dev_name(dev));
return 0;
}
if (!(fp = fopen(path, "r")))
return 0;
if (fscanf(fp, "%d", &is_pmem) != 1)
log_warn("Failed to parse DAX %s.", path);
if (is_pmem)
log_debug("%s is pmem", dev_name(dev));
if (fclose(fp))
log_sys_debug("fclose", path);
return is_pmem ? 1 : 0;
}
int dev_is_lv(struct device *dev)
@@ -211,7 +230,7 @@ struct dev_types *create_dev_types(const char *proc_dir,
log_error("Expecting string in devices/types "
"in config file");
if (fclose(pd))
log_sys_debug("fclose", proc_devices);
log_sys_error("fclose", proc_devices);
goto bad;
}
dev_len = strlen(cv->v.str);
@@ -222,7 +241,7 @@ struct dev_types *create_dev_types(const char *proc_dir,
"in devices/types in config file",
name);
if (fclose(pd))
log_sys_debug("fclose", proc_devices);
log_sys_error("fclose", proc_devices);
goto bad;
}
if (!cv->v.i) {
@@ -230,7 +249,7 @@ struct dev_types *create_dev_types(const char *proc_dir,
"%s in devices/types in config file",
name);
if (fclose(pd))
log_sys_debug("fclose", proc_devices);
log_sys_error("fclose", proc_devices);
goto bad;
}
if (dev_len <= strlen(line + i) &&
@@ -283,9 +302,6 @@ int dev_subsystem_part_major(struct dev_types *dt, struct device *dev)
const char *dev_subsystem_name(struct dev_types *dt, struct device *dev)
{
if (dev->flags & DEV_IS_NVME)
return "NVME";
if (MAJOR(dev->dev) == dt->device_mapper_major)
return "DM";
@@ -332,6 +348,7 @@ int major_is_scsi_device(struct dev_types *dt, int major)
return (dt->dev_type_array[major].flags & PARTITION_SCSI_DEVICE) ? 1 : 0;
}
static int _loop_is_with_partscan(struct device *dev)
{
FILE *fp;
@@ -363,45 +380,6 @@ static int _loop_is_with_partscan(struct device *dev)
return partscan;
}
int dev_get_partition_number(struct device *dev, int *num)
{
char path[PATH_MAX];
char buf[8] = { 0 };
dev_t devt = dev->dev;
struct stat sb;
if (dev->part != -1) {
*num = dev->part;
return 1;
}
if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/partition",
dm_sysfs_dir(), (int)MAJOR(devt), (int)MINOR(devt)) < 0) {
log_error("Failed to create sysfs path for %s", dev_name(dev));
return 0;
}
if (stat(path, &sb)) {
dev->part = 0;
*num = 0;
return 1;
}
if (!get_sysfs_value(path, buf, sizeof(buf), 0)) {
log_error("Failed to read sysfs path for %s", dev_name(dev));
return 0;
}
if (!buf[0]) {
log_error("Failed to read sysfs partition value for %s", dev_name(dev));
return 0;
}
dev->part = atoi(buf);
*num = dev->part;
return 1;
}
/* See linux/genhd.h and fs/partitions/msdos */
#define PART_MAGIC 0xAA55
#define PART_MAGIC_OFFSET UINT64_C(0x1FE)
@@ -420,28 +398,6 @@ struct partition {
uint32_t nr_sects;
} __attribute__((packed));
static int _has_sys_partition(struct device *dev)
{
char path[PATH_MAX];
struct stat info;
int major = (int) MAJOR(dev->dev);
int minor = (int) MINOR(dev->dev);
/* check if dev is a partition */
if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d/partition",
dm_sysfs_dir(), major, minor) < 0) {
log_warn("WARNING: %s: partition path is too long.", dev_name(dev));
return 0;
}
if (stat(path, &info) == -1) {
if (errno != ENOENT)
log_sys_debug("stat", path);
return 0;
}
return 1;
}
static int _is_partitionable(struct dev_types *dt, struct device *dev)
{
int parts = major_max_partitions(dt, MAJOR(dev->dev));
@@ -458,13 +414,6 @@ static int _is_partitionable(struct dev_types *dt, struct device *dev)
_loop_is_with_partscan(dev))
return 1;
if (dev_is_nvme(dt, dev)) {
/* If this dev is already a partition then it's not partitionable. */
if (_has_sys_partition(dev))
return 0;
return 1;
}
if ((parts <= 1) || (MINOR(dev->dev) % parts))
return 0;
@@ -602,22 +551,16 @@ int dev_is_partitioned(struct dev_types *dt, struct device *dev)
*/
int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
{
const char *sysfs_dir = dm_sysfs_dir();
int major = (int) MAJOR(dev->dev);
int minor = (int) MINOR(dev->dev);
char path[PATH_MAX];
char temp_path[PATH_MAX];
char buffer[64];
struct stat info;
FILE *fp = NULL;
int parts, residue, size, ret = 0;
/*
* /dev/nvme devs don't use the major:minor numbering like
* block dev types that have their own major number, so
* the calculation based on minor number doesn't work.
*/
if (dev_is_nvme(dt, dev))
goto sys_partition;
/*
* Try to get the primary dev out of the
* list of known device types first.
@@ -633,14 +576,23 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
goto out;
}
sys_partition:
/*
* If we can't get the primary dev out of the list of known device
* types, try to look at sysfs directly then. This is more complex
* way and it also requires certain sysfs layout to be present
* which might not be there in old kernels!
*/
if (!_has_sys_partition(dev)) {
/* check if dev is a partition */
if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d/partition",
sysfs_dir, major, minor) < 0) {
log_error("dm_snprintf partition failed");
goto out;
}
if (stat(path, &info) == -1) {
if (errno != ENOENT)
log_sys_error("stat", path);
*result = dev->dev;
ret = 1;
goto out; /* dev is not a partition! */
@@ -653,31 +605,25 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
* - basename ../../block/md0/md0 = md0
* Parent's 'dev' sysfs attribute = /sys/block/md0/dev
*/
if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d",
dm_sysfs_dir(), major, minor) < 0) {
log_warn("WARNING: %s: major:minor sysfs path is too long.", dev_name(dev));
return 0;
}
if ((size = readlink(path, temp_path, sizeof(temp_path) - 1)) < 0) {
log_warn("WARNING: Readlink of %s failed.", path);
if ((size = readlink(dirname(path), temp_path, sizeof(temp_path) - 1)) < 0) {
log_sys_error("readlink", path);
goto out;
}
temp_path[size] = '\0';
if (dm_snprintf(path, sizeof(path), "%s/block/%s/dev",
dm_sysfs_dir(), basename(dirname(temp_path))) < 0) {
log_warn("WARNING: sysfs path for %s is too long.",
basename(dirname(temp_path)));
sysfs_dir, basename(dirname(temp_path))) < 0) {
log_error("dm_snprintf dev failed");
goto out;
}
/* finally, parse 'dev' attribute and create corresponding dev_t */
if (!(fp = fopen(path, "r"))) {
if (errno == ENOENT)
log_debug("sysfs file %s does not exist.", path);
log_error("sysfs file %s does not exist.", path);
else
log_sys_debug("fopen", path);
log_sys_error("fopen", path);
goto out;
}
@@ -687,7 +633,7 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
}
if (sscanf(buffer, "%d:%d", &major, &minor) != 2) {
log_warn("WARNING: sysfs file %s not in expected MAJ:MIN format: %s",
log_error("sysfs file %s not in expected MAJ:MIN format: %s",
path, buffer);
goto out;
}
@@ -695,29 +641,29 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
ret = 2;
out:
if (fp && fclose(fp))
log_sys_debug("fclose", path);
log_sys_error("fclose", path);
return ret;
}
#ifdef BLKID_WIPING_SUPPORT
int get_fs_block_size(const char *pathname, uint32_t *fs_block_size)
int get_fs_block_size(struct device *dev, uint32_t *fs_block_size)
{
char *block_size_str = NULL;
if ((block_size_str = blkid_get_tag_value(NULL, "BLOCK_SIZE", pathname))) {
if ((block_size_str = blkid_get_tag_value(NULL, "BLOCK_SIZE", dev_name(dev)))) {
*fs_block_size = (uint32_t)atoi(block_size_str);
free(block_size_str);
log_debug("Found blkid BLOCK_SIZE %u for fs on %s", *fs_block_size, pathname);
log_debug("Found blkid BLOCK_SIZE %u for fs on %s", *fs_block_size, dev_name(dev));
return 1;
} else {
log_debug("No blkid BLOCK_SIZE for fs on %s", pathname);
log_debug("No blkid BLOCK_SIZE for fs on %s", dev_name(dev));
*fs_block_size = 0;
return 0;
}
}
#else
int get_fs_block_size(const char *pathname, uint32_t *fs_block_size)
int get_fs_block_size(struct device *dev, uint32_t *fs_block_size)
{
log_debug("Disabled blkid BLOCK_SIZE for fs.");
*fs_block_size = 0;
@@ -757,7 +703,7 @@ static int _blkid_wipe(blkid_probe probe, struct device *dev, const char *name,
return 0;
}
log_warn("WARNING: " MSG_FAILED_SIG_OFFSET MSG_WIPING_SKIPPED, type, name);
log_error("WARNING: " MSG_FAILED_SIG_OFFSET MSG_WIPING_SKIPPED, type, name);
return 2;
}
if (blkid_probe_lookup_value(probe, "SBMAGIC", &magic, &len)) {
@@ -891,7 +837,7 @@ static int _wipe_signature(struct device *dev, const char *type, const char *nam
int (*signature_detection_fn)(struct device *dev, uint64_t *offset_found, int full))
{
int wipe;
uint64_t offset_found = 0;
uint64_t offset_found;
wipe = signature_detection_fn(dev, &offset_found, 1);
if (wipe == -1) {
@@ -955,9 +901,9 @@ int wipe_known_signatures(struct cmd_context *cmd, struct device *dev,
yes, force, wiped);
#endif
if (blkid_wiping_enabled) {
log_warn("WARNING: allocation/use_blkid_wiping=1 configuration setting is set "
log_warn("allocation/use_blkid_wiping=1 configuration setting is set "
"while LVM is not compiled with blkid wiping support.");
log_warn("WARNING: Falling back to native LVM signature detection.");
log_warn("Falling back to native LVM signature detection.");
}
return _wipe_known_signatures_with_lvm(dev, name,
types_to_exclude,
@@ -973,23 +919,25 @@ static int _snprintf_attr(char *buf, size_t buf_size, const char *sysfs_dir,
if (dm_snprintf(buf, buf_size, "%s/dev/block/%d:%d/%s", sysfs_dir,
(int)MAJOR(dev), (int)MINOR(dev),
attribute) < 0) {
log_warn("WARNING: sysfs path for %s attribute is too long.", attribute);
log_warn("dm_snprintf %s failed.", attribute);
return 0;
}
return 1;
}
static int _dev_sysfs_block_attribute(struct dev_types *dt,
const char *attribute,
struct device *dev,
unsigned long *value)
static unsigned long _dev_topology_attribute(struct dev_types *dt,
const char *attribute,
struct device *dev,
unsigned long default_value)
{
const char *sysfs_dir = dm_sysfs_dir();
char path[PATH_MAX], buffer[64];
FILE *fp;
dev_t primary = 0;
int ret = 0;
struct stat info;
dev_t uninitialized_var(primary);
unsigned long result = default_value;
unsigned long value = 0UL;
if (!attribute || !*attribute)
goto_out;
@@ -998,16 +946,16 @@ static int _dev_sysfs_block_attribute(struct dev_types *dt,
goto_out;
if (!_snprintf_attr(path, sizeof(path), sysfs_dir, attribute, dev->dev))
goto_out;
goto_out;
/*
* check if the desired sysfs attribute exists
* - if not: either the kernel doesn't have topology support
* or the device could be a partition
*/
if (!(fp = fopen(path, "r"))) {
if (stat(path, &info) == -1) {
if (errno != ENOENT) {
log_sys_debug("fopen", path);
log_sys_debug("stat", path);
goto out;
}
if (!dev_get_primary_dev(dt, dev, &primary))
@@ -1017,54 +965,44 @@ static int _dev_sysfs_block_attribute(struct dev_types *dt,
if (!_snprintf_attr(path, sizeof(path), sysfs_dir, attribute, primary))
goto_out;
if (!(fp = fopen(path, "r"))) {
if (stat(path, &info) == -1) {
if (errno != ENOENT)
log_sys_debug("fopen", path);
log_sys_debug("stat", path);
goto out;
}
}
if (!(fp = fopen(path, "r"))) {
log_sys_debug("fopen", path);
goto out;
}
if (!fgets(buffer, sizeof(buffer), fp)) {
log_sys_debug("fgets", path);
goto out_close;
}
if (sscanf(buffer, "%lu", value) != 1) {
log_warn("WARNING: sysfs file %s not in expected format: %s", path, buffer);
if (sscanf(buffer, "%lu", &value) != 1) {
log_warn("sysfs file %s not in expected format: %s", path, buffer);
goto out_close;
}
ret = 1;
log_very_verbose("Device %s: %s is %lu%s.",
dev_name(dev), attribute, value, default_value ? "" : " bytes");
result = value >> SECTOR_SHIFT;
if (!result && value) {
log_warn("WARNING: Device %s: %s is %lu and is unexpectedly less than sector.",
dev_name(dev), attribute, value);
result = 1;
}
out_close:
if (fclose(fp))
log_sys_debug("fclose", path);
out:
return ret;
}
static unsigned long _dev_topology_attribute(struct dev_types *dt,
const char *attribute,
struct device *dev,
unsigned long default_value)
{
unsigned long result = default_value;
unsigned long value = 0UL;
if (_dev_sysfs_block_attribute(dt, attribute, dev, &value)) {
log_very_verbose("Device %s: %s is %lu%s.",
dev_name(dev), attribute, value, default_value ? "" : " bytes");
result = value >> SECTOR_SHIFT;
if (!result && value) {
log_warn("WARNING: Device %s: %s is %lu and is unexpectedly less than sector.",
dev_name(dev), attribute, value);
result = 1;
}
}
return result;
}
@@ -1095,17 +1033,8 @@ unsigned long dev_discard_granularity(struct dev_types *dt, struct device *dev)
int dev_is_rotational(struct dev_types *dt, struct device *dev)
{
unsigned long value;
return _dev_sysfs_block_attribute(dt, "queue/rotational", dev, &value) ? (int) value : 1;
return (int) _dev_topology_attribute(dt, "queue/rotational", dev, 1UL);
}
/* dev is pmem if /sys/dev/block/<major>:<minor>/queue/dax is 1 */
int dev_is_pmem(struct dev_types *dt, struct device *dev)
{
unsigned long value;
return _dev_sysfs_block_attribute(dt, "queue/dax", dev, &value) ? (int) value : 0;
}
#else
int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
@@ -1142,11 +1071,6 @@ int dev_is_rotational(struct dev_types *dt, struct device *dev)
{
return 1;
}
int dev_is_pmem(struct dev_types *dt, struct device *dev)
{
return 0;
}
#endif
#ifdef UDEV_SYNC_SUPPORT
@@ -1261,8 +1185,10 @@ int udev_dev_is_md_component(struct device *dev)
const char *value;
int ret = 0;
if (!obtain_device_list_from_udev())
if (!obtain_device_list_from_udev()) {
dev->flags |= DEV_UDEV_INFO_MISSING;
return 0;
}
if (!(udev_device = _udev_get_dev(dev)))
return 0;
@@ -1289,6 +1215,7 @@ int udev_dev_is_mpath_component(struct device *dev)
int udev_dev_is_md_component(struct device *dev)
{
dev->flags |= DEV_UDEV_INFO_MISSING;
return 0;
}

View File

@@ -83,7 +83,6 @@ int dev_is_md_with_end_superblock(struct dev_types *dt, struct device *dev);
int major_max_partitions(struct dev_types *dt, int major);
int dev_is_partitioned(struct dev_types *dt, struct device *dev);
int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result);
int dev_get_partition_number(struct device *dev, int *num);
/* Various device properties */
unsigned long dev_alignment_offset(struct dev_types *dt, struct device *dev);
@@ -94,12 +93,10 @@ unsigned long dev_discard_granularity(struct dev_types *dt, struct device *dev);
int dev_is_rotational(struct dev_types *dt, struct device *dev);
int dev_is_pmem(struct dev_types *dt, struct device *dev);
int dev_is_nvme(struct dev_types *dt, struct device *dev);
int dev_is_pmem(struct device *dev);
int dev_is_lv(struct device *dev);
int get_fs_block_size(const char *pathname, uint32_t *fs_block_size);
int get_fs_block_size(struct device *dev, uint32_t *fs_block_size);
#endif

View File

@@ -37,8 +37,7 @@
#define DEV_BCACHE_WRITE 0x00008000 /* bcache_fd is open with RDWR */
#define DEV_SCAN_FOUND_LABEL 0x00010000 /* label scan read dev and found label */
#define DEV_IS_MD_COMPONENT 0x00020000 /* device is an md component */
#define DEV_IS_NVME 0x00040000 /* set if dev is nvme */
#define DEV_MATCHED_USE_ID 0x00080000 /* matched an entry from cmd->use_devices */
#define DEV_UDEV_INFO_MISSING 0x00040000 /* we have no udev info for this device */
/*
* Support for external device info.
@@ -57,54 +56,12 @@ struct dev_ext {
void *handle;
};
#define DEV_ID_TYPE_SYS_WWID 0x0001
#define DEV_ID_TYPE_SYS_SERIAL 0x0002
#define DEV_ID_TYPE_MPATH_UUID 0x0003
#define DEV_ID_TYPE_MD_UUID 0x0004
#define DEV_ID_TYPE_LOOP_FILE 0x0005
#define DEV_ID_TYPE_CRYPT_UUID 0x0006
#define DEV_ID_TYPE_LVMLV_UUID 0x0007
#define DEV_ID_TYPE_DEVNAME 0x0008
/*
* A device ID of a certain type for a device.
* A struct device may have multiple dev_id structs on dev->ids.
* One of them will be the one that's used, pointed to by dev->id.
*/
struct dev_id {
struct dm_list list;
struct device *dev;
uint16_t idtype; /* DEV_ID_TYPE_ */
char *idname; /* id string determined by idtype */
};
/*
* A device listed in devices file that lvm should use.
* Each entry in the devices file is represented by a struct dev_use.
* The structs are kept on cmd->use_devices.
* idtype/idname/pvid/part are set when reading the devices file.
* du->dev is set when a struct dev_use is matched to a struct device.
*/
struct dev_use {
struct dm_list list;
struct device *dev;
int part;
uint16_t idtype;
char *idname;
char *devname;
char *pvid;
};
/*
* All devices in LVM will be represented by one of these.
* pointer comparisons are valid.
*/
struct device {
struct dm_list aliases; /* struct dm_str_list */
struct dm_list ids; /* struct dev_id, different entries for different idtypes */
struct dev_id *id; /* points to the the ids entry being used for this dev */
dev_t dev;
/* private */
@@ -115,7 +72,6 @@ struct device {
int read_ahead;
int bcache_fd;
int bcache_di;
int part; /* partition number */
uint32_t flags;
uint32_t filtered_flags;
unsigned size_seqno;

File diff suppressed because it is too large Load Diff

View File

@@ -1,55 +0,0 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _LVM_DEVICE_ID_H
#define _LVM_DEVICE_ID_H
void free_du(struct dev_use *du);
void free_dus(struct dm_list *list);
void free_did(struct dev_id *did);
void free_dids(struct dm_list *list);
const char *idtype_to_str(uint16_t idtype);
uint16_t idtype_from_str(const char *str);
const char *dev_idtype_for_metadata(struct cmd_context *cmd, struct device *dev);
const char *dev_idname_for_metadata(struct cmd_context *cmd, struct device *dev);
int device_ids_use_devname(struct cmd_context *cmd);
int device_ids_read(struct cmd_context *cmd);
int device_ids_write(struct cmd_context *cmd);
int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid,
const char *idtype_arg, const char *id_arg);
void device_id_pvremove(struct cmd_context *cmd, struct device *dev);
void device_ids_match(struct cmd_context *cmd);
int device_ids_match_dev(struct cmd_context *cmd, struct device *dev);
void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, int *device_ids_invalid, int noupdate);
int device_ids_version_unchanged(struct cmd_context *cmd);
void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_list, int *search_count, int noupdate);
const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, uint16_t idtype);
struct dev_use *get_du_for_dev(struct cmd_context *cmd, struct device *dev);
struct dev_use *get_du_for_pvid(struct cmd_context *cmd, const char *pvid);
char *devices_file_version(void);
int devices_file_exists(struct cmd_context *cmd);
int devices_file_touch(struct cmd_context *cmd);
int lock_devices_file(struct cmd_context *cmd, int mode);
int lock_devices_file_try(struct cmd_context *cmd, int mode, int *held);
void unlock_devices_file(struct cmd_context *cmd);
void devices_file_init(struct cmd_context *cmd);
void devices_file_exit(struct cmd_context *cmd);
void unlink_searched_devnames(struct cmd_context *cmd);
#endif

View File

@@ -95,8 +95,6 @@ const char *get_lock_type_string(lock_type_t lock_type)
return "dlm";
case LOCK_TYPE_SANLOCK:
return "sanlock";
case LOCK_TYPE_IDM:
return "idm";
}
return "invalid";
}
@@ -113,8 +111,6 @@ lock_type_t get_lock_type_from_string(const char *str)
return LOCK_TYPE_DLM;
if (!strcmp(str, "sanlock"))
return LOCK_TYPE_SANLOCK;
if (!strcmp(str, "idm"))
return LOCK_TYPE_IDM;
return LOCK_TYPE_INVALID;
}
@@ -403,7 +399,7 @@ int lvdisplay_full(struct cmd_context *cmd,
void *handle __attribute__((unused)))
{
struct lvinfo info;
int inkernel, snap_active = 0, partial = 0, raid_is_avail = 1;
int inkernel, snap_active = 0;
char uuid[64] __attribute__((aligned(8)));
const char *access_str;
struct lv_segment *snap_seg = NULL, *mirror_seg = NULL;
@@ -479,7 +475,7 @@ int lvdisplay_full(struct cmd_context *cmd,
snap_active ? "active" : "INACTIVE");
}
snap_seg = NULL;
} else if (lv_is_cow(lv) && (snap_seg = find_snapshot(lv))) {
} else if ((snap_seg = find_snapshot(lv))) {
if (inkernel &&
(snap_active = lv_snapshot_percent(snap_seg->cow,
&snap_percent)))
@@ -562,18 +558,11 @@ int lvdisplay_full(struct cmd_context *cmd,
log_print("LV VDO Pool name %s", seg_lv(seg, 0)->name);
}
if (lv_is_partial(lv))
partial = 1;
if (lv_is_raid(lv))
raid_is_avail = raid_is_available(lv) ? 1 : 0;
if (inkernel && info.suspended)
log_print("LV Status suspended");
else if (activation())
log_print("LV Status %savailable%s",
(inkernel && raid_is_avail) ? "" : "NOT ",
partial ? " (partial)" : "");
log_print("LV Status %savailable",
inkernel ? "" : "NOT ");
/********* FIXME lv_number
log_print("LV # %u", lv->lv_number + 1);

View File

@@ -1,69 +0,0 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2012 Red Hat, Inc. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "base/memory/zalloc.h"
#include "lib/misc/lib.h"
#include "lib/filters/filter.h"
#include "lib/commands/toolcontext.h"
static int _passes_deviceid_filter(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
{
dev->filtered_flags &= ~DEV_FILTERED_DEVICES_FILE;
dev->filtered_flags &= ~DEV_FILTERED_DEVICES_LIST;
if (!cmd->enable_devices_file && !cmd->enable_devices_list)
return 1;
if (cmd->filter_deviceid_skip)
return 1;
if (dev->flags & DEV_MATCHED_USE_ID)
return 1;
if (cmd->enable_devices_file)
dev->filtered_flags |= DEV_FILTERED_DEVICES_FILE;
else if (cmd->enable_devices_list)
dev->filtered_flags |= DEV_FILTERED_DEVICES_LIST;
log_debug_devs("%s: Skipping (deviceid)", dev_name(dev));
return 0;
}
static void _destroy_deviceid_filter(struct dev_filter *f)
{
if (f->use_count)
log_error(INTERNAL_ERROR "Destroying deviceid filter while in use %u times.", f->use_count);
free(f);
}
struct dev_filter *deviceid_filter_create(struct cmd_context *cmd)
{
struct dev_filter *f;
if (!(f = zalloc(sizeof(struct dev_filter)))) {
log_error("deviceid filter allocation failed");
return NULL;
}
f->passes_filter = _passes_deviceid_filter;
f->destroy = _destroy_deviceid_filter;
f->use_count = 0;
f->name = "deviceid";
log_debug_devs("deviceid filter initialised.");
return f;
}

View File

@@ -16,7 +16,6 @@
#include "lib/misc/lib.h"
#include "lib/filters/filter.h"
#include "lib/activate/activate.h"
#include "lib/commands/toolcontext.h"
#ifdef UDEV_SYNC_SUPPORT
#include <libudev.h>
#include "lib/device/dev-ext-udev-constants.h"
@@ -28,6 +27,7 @@
#define MPATH_PREFIX "mpath-"
struct mpath_priv {
struct dm_pool *mem;
struct dev_filter f;
@@ -35,9 +35,6 @@ struct mpath_priv {
struct dm_hash_table *hash;
};
/*
* given "/dev/foo" return "foo"
*/
static const char *_get_sysfs_name(struct device *dev)
{
const char *name;
@@ -56,11 +53,6 @@ static const char *_get_sysfs_name(struct device *dev)
return name;
}
/*
* given major:minor
* readlink translates /sys/dev/block/major:minor to /sys/.../foo
* from /sys/.../foo return "foo"
*/
static const char *_get_sysfs_name_by_devt(const char *sysfs_dir, dev_t devno,
char *buf, size_t buf_size)
{
@@ -68,7 +60,7 @@ static const char *_get_sysfs_name_by_devt(const char *sysfs_dir, dev_t devno,
char path[PATH_MAX];
int size;
if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d", sysfs_dir,
if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d", sysfs_dir,
(int) MAJOR(devno), (int) MINOR(devno)) < 0) {
log_error("Sysfs path string is too long.");
return NULL;
@@ -110,28 +102,27 @@ static int _get_sysfs_string(const char *path, char *buffer, int max_size)
return r;
}
static int _get_sysfs_dm_mpath(struct dev_types *dt, const char *sysfs_dir, const char *holder_name)
static int _get_sysfs_get_major_minor(const char *sysfs_dir, const char *kname, int *major, int *minor)
{
char path[PATH_MAX];
char buffer[128];
char path[PATH_MAX], buffer[64];
if (dm_snprintf(path, sizeof(path), "%sblock/%s/dm/uuid", sysfs_dir, holder_name) < 0) {
if (dm_snprintf(path, sizeof(path), "%s/block/%s/dev", sysfs_dir, kname) < 0) {
log_error("Sysfs path string is too long.");
return 0;
}
buffer[0] = '\0';
if (!_get_sysfs_string(path, buffer, sizeof(buffer)))
return_0;
if (!strncmp(buffer, MPATH_PREFIX, 6))
return 1;
if (sscanf(buffer, "%d:%d", major, minor) != 2) {
log_error("Failed to parse major minor from %s", buffer);
return 0;
}
return 0;
return 1;
}
static int _get_holder_name(const char *dir, char *name, int max_size)
static int _get_parent_mpath(const char *dir, char *name, int max_size)
{
struct dirent *d;
DIR *dr;
@@ -158,13 +149,13 @@ static int _get_holder_name(const char *dir, char *name, int max_size)
}
if (closedir(dr))
log_sys_debug("closedir", dir);
log_sys_error("closedir", dir);
return r;
}
#ifdef UDEV_SYNC_SUPPORT
static int _udev_dev_is_mpath_component(struct device *dev)
static int _udev_dev_is_mpath(struct device *dev)
{
const char *value;
struct dev_ext *ext;
@@ -183,148 +174,95 @@ static int _udev_dev_is_mpath_component(struct device *dev)
return 0;
}
#else
static int _udev_dev_is_mpath_component(struct device *dev)
static int _udev_dev_is_mpath(struct device *dev)
{
return 0;
}
#endif
static int _native_dev_is_mpath_component(struct cmd_context *cmd, struct dev_filter *f, struct device *dev)
static int _native_dev_is_mpath(struct dev_filter *f, struct device *dev)
{
struct mpath_priv *mp = (struct mpath_priv *) f->private;
struct dev_types *dt = mp->dt;
const char *part_name;
const char *name; /* e.g. "sda" for "/dev/sda" */
char link_path[PATH_MAX]; /* some obscure, unpredictable sysfs path */
char holders_path[PATH_MAX]; /* e.g. "/sys/block/sda/holders/" */
char dm_dev_path[PATH_MAX]; /* e.g. "/dev/dm-1" */
char holder_name[256]; /* e.g. "dm-1" */
const char *sysfs_dir = dm_sysfs_dir();
int dev_major = MAJOR(dev->dev);
int dev_minor = MINOR(dev->dev);
int dm_dev_major;
int dm_dev_minor;
const char *part_name, *name;
struct stat info;
char path[PATH_MAX], parent_name[PATH_MAX];
const char *sysfs_dir = dm_sysfs_dir();
int major = MAJOR(dev->dev);
int minor = MINOR(dev->dev);
dev_t primary_dev;
long look;
/* Limit this filter to SCSI or NVME devices */
if (!major_is_scsi_device(dt, dev_major) && !dev_is_nvme(dt, dev))
/* Limit this filter only to SCSI devices */
if (!major_is_scsi_device(dt, MAJOR(dev->dev)))
return 0;
switch (dev_get_primary_dev(dt, dev, &primary_dev)) {
case 2: /* The dev is partition. */
part_name = dev_name(dev); /* name of original dev for log_debug msg */
/* gets "foo" for "/dev/foo" where "/dev/foo" comes from major:minor */
if (!(name = _get_sysfs_name_by_devt(sysfs_dir, primary_dev, link_path, sizeof(link_path))))
if (!(name = _get_sysfs_name_by_devt(sysfs_dir, primary_dev, parent_name, sizeof(parent_name))))
return_0;
log_debug_devs("%s: Device is a partition, using primary "
"device %s for mpath component detection",
part_name, name);
break;
case 1: /* The dev is already a primary dev. Just continue with the dev. */
/* gets "foo" for "/dev/foo" */
if (!(name = _get_sysfs_name(dev)))
return_0;
break;
default: /* 0, error. */
log_warn("Failed to get primary device for %d:%d.", dev_major, dev_minor);
log_warn("Failed to get primary device for %d:%d.", major, minor);
return 0;
}
if (dm_snprintf(holders_path, sizeof(holders_path), "%sblock/%s/holders", sysfs_dir, name) < 0) {
if (dm_snprintf(path, sizeof(path), "%s/block/%s/holders", sysfs_dir, name) < 0) {
log_warn("Sysfs path to check mpath is too long.");
return 0;
}
/* also will filter out partitions */
if (stat(holders_path, &info))
if (stat(path, &info))
return 0;
if (!S_ISDIR(info.st_mode)) {
log_warn("Path %s is not a directory.", holders_path);
log_warn("Path %s is not a directory.", path);
return 0;
}
/*
* If holders dir contains an entry such as "dm-1", then this sets
* holder_name to "dm-1".
*
* If holders dir is empty, return 0 (this is generally where
* devs that are not mpath components return.)
*/
if (!_get_holder_name(holders_path, holder_name, sizeof(holder_name)))
if (!_get_parent_mpath(path, parent_name, sizeof(parent_name)))
return 0;
if (dm_snprintf(dm_dev_path, sizeof(dm_dev_path), "%s/%s", cmd->dev_dir, holder_name) < 0) {
log_warn("dm device path to check mpath is too long.");
return 0;
}
if (!_get_sysfs_get_major_minor(sysfs_dir, parent_name, &major, &minor))
return_0;
/*
* stat "/dev/dm-1" which is the holder of the dev we're checking
* dm_dev_major:dm_dev_minor come from stat("/dev/dm-1")
*/
if (stat(dm_dev_path, &info)) {
log_debug("filter-mpath %s holder %s stat result %d",
dev_name(dev), dm_dev_path, errno);
if (major != dt->device_mapper_major)
return 0;
}
dm_dev_major = (int)MAJOR(info.st_rdev);
dm_dev_minor = (int)MINOR(info.st_rdev);
if (dm_dev_major != dt->device_mapper_major) {
log_debug_devs("filter-mpath %s holder %s %d:%d does not have dm major",
dev_name(dev), dm_dev_path, dm_dev_major, dm_dev_minor);
return 0;
}
/*
* Save the result of checking that "/dev/dm-1" is an mpath device
* to avoid repeating it for each path component.
* The minor number of "/dev/dm-1" is added to the hash table with
* const value 2 meaning that dm minor 1 (for /dev/dm-1) is a multipath dev
* and const value 1 meaning that dm minor 1 is not a multipath dev.
*/
look = (long) dm_hash_lookup_binary(mp->hash, &dm_dev_minor, sizeof(dm_dev_minor));
/* Avoid repeated detection of multipath device and use first checked result */
look = (long) dm_hash_lookup_binary(mp->hash, &minor, sizeof(minor));
if (look > 0) {
log_debug_devs("filter-mpath %s holder %s %u:%u already checked as %sbeing mpath.",
dev_name(dev), holder_name, dm_dev_major, dm_dev_minor, (look > 1) ? "" : "not ");
log_debug_devs("%s(%u:%u): already checked as %sbeing mpath.",
parent_name, major, minor, (look > 1) ? "" : "not ");
return (look > 1) ? 1 : 0;
}
/*
* Returns 1 if /sys/block/<holder_name>/dm/uuid indicates that
* <holder_name> is a dm device with dm uuid prefix mpath-.
* When true, <holder_name> will be something like "dm-1".
*
* (Is a hash table worth it to avoid reading one sysfs file?)
*/
if (_get_sysfs_dm_mpath(dt, sysfs_dir, holder_name)) {
log_debug_devs("filter-mpath %s holder %s %u:%u ignore mpath component",
dev_name(dev), holder_name, dm_dev_major, dm_dev_minor);
(void) dm_hash_insert_binary(mp->hash, &dm_dev_minor, sizeof(dm_dev_minor), (void*)2);
if (lvm_dm_prefix_check(major, minor, MPATH_PREFIX)) {
(void) dm_hash_insert_binary(mp->hash, &minor, sizeof(minor), (void*)2);
return 1;
}
(void) dm_hash_insert_binary(mp->hash, &dm_dev_minor, sizeof(dm_dev_minor), (void*)1);
(void) dm_hash_insert_binary(mp->hash, &minor, sizeof(minor), (void*)1);
return 0;
}
static int _dev_is_mpath_component(struct cmd_context *cmd, struct dev_filter *f, struct device *dev)
static int _dev_is_mpath(struct dev_filter *f, struct device *dev)
{
if (dev->ext.src == DEV_EXT_NONE)
return _native_dev_is_mpath_component(cmd, f, dev);
return _native_dev_is_mpath(f, dev);
if (dev->ext.src == DEV_EXT_UDEV)
return _udev_dev_is_mpath_component(dev);
return _udev_dev_is_mpath(dev);
log_error(INTERNAL_ERROR "Missing hook for mpath recognition "
"using external device info source %s", dev_ext_name(dev));
@@ -334,11 +272,11 @@ static int _dev_is_mpath_component(struct cmd_context *cmd, struct dev_filter *f
#define MSG_SKIPPING "%s: Skipping mpath component device"
static int _ignore_mpath_component(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
static int _ignore_mpath(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
{
dev->filtered_flags &= ~DEV_FILTERED_MPATH_COMPONENT;
if (_dev_is_mpath_component(cmd, f, dev) == 1) {
if (_dev_is_mpath(f, dev) == 1) {
if (dev->ext.src == DEV_EXT_NONE)
log_debug_devs(MSG_SKIPPING, dev_name(dev));
else
@@ -365,8 +303,8 @@ static void _destroy(struct dev_filter *f)
struct dev_filter *mpath_filter_create(struct dev_types *dt)
{
const char *sysfs_dir = dm_sysfs_dir();
struct mpath_priv *mp;
struct dm_pool *mem;
struct mpath_priv *mp;
struct dm_hash_table *hash;
if (!*sysfs_dir) {
@@ -374,7 +312,7 @@ struct dev_filter *mpath_filter_create(struct dev_types *dt)
return NULL;
}
if (!(hash = dm_hash_create(110))) {
if (!(hash = dm_hash_create(128))) {
log_error("mpath hash table creation failed.");
return NULL;
}
@@ -390,13 +328,19 @@ struct dev_filter *mpath_filter_create(struct dev_types *dt)
goto bad;
}
mp->f.passes_filter = _ignore_mpath_component;
if (!(mp = dm_pool_zalloc(mem, sizeof(*mp)))) {
log_error("mpath filter allocation failed.");
goto bad;
}
mp->f.passes_filter = _ignore_mpath;
mp->f.destroy = _destroy;
mp->f.use_count = 0;
mp->f.private = mp;
mp->f.name = "mpath";
mp->dt = dt;
mp->mem = mem;
mp->dt = dt;
mp->hash = hash;
log_debug_devs("mpath filter initialised.");

View File

@@ -58,7 +58,7 @@ static int _init_hash(struct pfilter *pf)
if (pf->devices)
dm_hash_destroy(pf->devices);
if (!(pf->devices = dm_hash_create(111)))
if (!(pf->devices = dm_hash_create(128)))
return_0;
return 1;

View File

@@ -15,16 +15,11 @@
#include "lib/misc/lib.h"
#include "lib/filters/filter.h"
#include "lib/commands/toolcontext.h"
struct rfilter {
struct dm_pool *mem;
dm_bitset_t accept;
struct dm_regex *engine;
unsigned config_filter:1;
unsigned config_global_filter:1;
unsigned warned_filter:1;
unsigned warned_global_filter:1;
};
static int _extract_pattern(struct dm_pool *mem, const char *pat,
@@ -158,22 +153,6 @@ static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct devic
dev->filtered_flags &= ~DEV_FILTERED_REGEX;
if (cmd->enable_devices_list)
return 1;
if (cmd->enable_devices_file && !cmd->filter_regex_with_devices_file) {
/* can't warn in create_filter because enable_devices_file is set later */
if (rf->config_filter && !rf->warned_filter) {
log_warn("Please remove the lvm.conf filter, it is ignored with the devices file.");
rf->warned_filter = 1;
}
if (rf->config_global_filter && !rf->warned_global_filter) {
log_warn("Please remove the lvm.conf global_filter, it is ignored with the devices file.");
rf->warned_global_filter = 1;
}
return 1;
}
dm_list_iterate_items(sl, &dev->aliases) {
m = dm_regex_match(rf->engine, sl->str);
@@ -213,7 +192,7 @@ static void _regex_destroy(struct dev_filter *f)
dm_pool_destroy(rf->mem);
}
struct dev_filter *regex_filter_create(const struct dm_config_value *patterns, int config_filter, int config_global_filter)
struct dev_filter *regex_filter_create(const struct dm_config_value *patterns)
{
struct dm_pool *mem = dm_pool_create("filter regex", 10 * 1024);
struct rfilter *rf;
@@ -227,9 +206,6 @@ struct dev_filter *regex_filter_create(const struct dm_config_value *patterns, i
rf->mem = mem;
rf->config_filter = config_filter;
rf->config_global_filter = config_global_filter;
if (!_build_matcher(rf, patterns))
goto_bad;

View File

@@ -218,15 +218,15 @@ static int _read_devs(struct dev_set *ds, const char *dir, unsigned sysfs_depth)
if (dm_snprintf(path, sizeof(path), "%s/%s", dir,
d->d_name) < 0) {
log_warn("WARNING: sysfs path name too long: %s in %s.",
d->d_name, dir);
log_error("sysfs path name too long: %s in %s",
d->d_name, dir);
continue;
}
/* devices have a "dev" file */
if (dm_snprintf(file, sizeof(file), "%s/dev", path) < 0) {
log_warn("WARNING: sysfs path name too long: %s in %s.",
d->d_name, dir);
log_error("sysfs path name too long: %s in %s",
d->d_name, dir);
continue;
}
@@ -242,7 +242,7 @@ static int _read_devs(struct dev_set *ds, const char *dir, unsigned sysfs_depth)
}
if (closedir(dr))
log_sys_debug("closedir", dir);
log_sys_error("closedir", dir);
return r;
}

View File

@@ -111,7 +111,6 @@ static int _passes_usable_filter(struct cmd_context *cmd, struct dev_filter *f,
filter_mode_t mode = data->mode;
int skip_lvs = data->skip_lvs;
struct dev_usable_check_params ucp = {0};
int is_lv = 0;
int r = 1;
dev->filtered_flags &= ~DEV_FILTERED_MINSIZE;
@@ -146,11 +145,8 @@ static int _passes_usable_filter(struct cmd_context *cmd, struct dev_filter *f,
break;
}
if (!(r = device_is_usable(dev, ucp, &is_lv))) {
if (is_lv)
dev->filtered_flags |= DEV_FILTERED_IS_LV;
else
dev->filtered_flags |= DEV_FILTERED_UNUSABLE;
if (!(r = device_is_usable(dev, ucp))) {
dev->filtered_flags |= DEV_FILTERED_UNUSABLE;
log_debug_devs("%s: Skipping unusable device.", dev_name(dev));
}
}

View File

@@ -30,7 +30,6 @@ struct dev_filter *partitioned_filter_create(struct dev_types *dt);
struct dev_filter *persistent_filter_create(struct dev_types *dt, struct dev_filter *f);
struct dev_filter *sysfs_filter_create(void);
struct dev_filter *signature_filter_create(struct dev_types *dt);
struct dev_filter *deviceid_filter_create(struct cmd_context *cmd);
struct dev_filter *internal_filter_create(void);
int internal_filter_allow(struct dm_pool *mem, struct device *dev);
@@ -44,7 +43,7 @@ void internal_filter_clear(void);
* r|.*| - reject everything else
*/
struct dev_filter *regex_filter_create(const struct dm_config_value *patterns, int config_filter, int config_global_filter);
struct dev_filter *regex_filter_create(const struct dm_config_value *patterns);
typedef enum {
FILTER_MODE_NO_LVMETAD,
@@ -64,8 +63,5 @@ struct dev_filter *usable_filter_create(struct cmd_context *cmd, struct dev_type
#define DEV_FILTERED_DEVTYPE 0x00000100
#define DEV_FILTERED_MINSIZE 0x00000200
#define DEV_FILTERED_UNUSABLE 0x00000400
#define DEV_FILTERED_DEVICES_FILE 0x00000800
#define DEV_FILTERED_DEVICES_LIST 0x00001000
#define DEV_FILTERED_IS_LV 0x00002000
#endif /* _LVM_FILTER_H */

View File

@@ -17,7 +17,6 @@
#include "lib/format_text/archiver.h"
#include "lib/format_text/format-text.h"
#include "lib/misc/lvm-string.h"
#include "lib/misc/lvm-signal.h"
#include "lib/cache/lvmcache.h"
#include "lib/mm/memlock.h"
#include "lib/commands/toolcontext.h"
@@ -103,13 +102,13 @@ static int _archive(struct volume_group *vg, int compulsory)
{
char *desc;
if (vg_is_archived(vg))
return 1; /* VG has been already archived */
/* Don't archive orphan VGs. */
if (is_orphan_vg(vg->name))
return 1;
if (vg_is_archived(vg))
return 1; /* VG has been already archived */
if (!vg->cmd->archive_params->enabled || !vg->cmd->archive_params->dir) {
vg->status |= ARCHIVED_VG;
return 1;
@@ -156,13 +155,7 @@ static int _archive(struct volume_group *vg, int compulsory)
int archive(struct volume_group *vg)
{
int r;
sigint_allow();
r = _archive(vg, 1);
sigint_restore();
return r;
return _archive(vg, 1);
}
int archive_display(struct cmd_context *cmd, const char *vg_name)
@@ -225,7 +218,6 @@ static int _backup(struct volume_group *vg)
{
char name[PATH_MAX];
char *desc;
int r;
if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 0)))
return_0;
@@ -237,11 +229,7 @@ static int _backup(struct volume_group *vg)
return 0;
}
sigint_allow();
r = backup_to_file(name, desc, vg);
sigint_restore();
return r;
return backup_to_file(name, desc, vg);
}
int backup_locally(struct volume_group *vg)
@@ -279,7 +267,6 @@ int backup_locally(struct volume_group *vg)
int backup(struct volume_group *vg)
{
/* Unlock memory if possible */
memlock_unlock(vg->cmd);
@@ -334,7 +321,7 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd,
}
if (vg)
set_pv_devices(tf, vg);
set_pv_devices(tf, vg, NULL);
if (!vg)
tf->fmt->ops->destroy_instance(tf);

View File

@@ -23,7 +23,6 @@
#include "lib/metadata/segtype.h"
#include "lib/format_text/text_export.h"
#include "lib/commands/toolcontext.h"
#include "lib/device/device_id.h"
#include "libdaemon/client/config-util.h"
#include <stdarg.h>
@@ -528,7 +527,6 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
struct physical_volume *pv;
char buffer[PATH_MAX * 2];
const char *name;
const char *idtype, *idname;
outf(f, "physical_volumes {");
_inc_indent(f);
@@ -557,13 +555,6 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
dm_escape_double_quotes(buffer, pv_dev_name(pv)));
outnl(f);
idtype = dev_idtype_for_metadata(vg->cmd, pv->dev);
idname = dev_idname_for_metadata(vg->cmd, pv->dev);
if (idtype && idname) {
outf(f, "device_id_type = \"%s\"", idtype);
outf(f, "device_id = \"%s\"", idname);
}
if (!_print_flag_config(f, pv->status, PV_FLAGS))
return_0;
@@ -880,50 +871,45 @@ bad:
return 0;
}
static int _print_historical_lv_with_descendants(struct formatter *f, struct historical_logical_volume *hlv,
char *descendants_buffer)
{
char buffer[40];
if (!id_write_format(&hlv->lvid.id[1], buffer, sizeof(buffer)))
return_0;
outnl(f);
outf(f, "%s {", hlv->name);
_inc_indent(f);
outf(f, "id = \"%s\"", buffer);
if (!_print_timestamp(f, "creation_time", hlv->timestamp, buffer, sizeof(buffer)))
return_0;
if (!_print_timestamp(f, "removal_time", hlv->timestamp_removed, buffer, sizeof(buffer)))
return_0;
if (hlv->indirect_origin) {
if (hlv->indirect_origin->is_historical)
outf(f, "origin = \"%s%s\"", HISTORICAL_LV_PREFIX, hlv->indirect_origin->historical->name);
else
outf(f, "origin = \"%s\"", hlv->indirect_origin->live->name);
}
if (descendants_buffer)
outf(f, "descendants = %s", descendants_buffer);
_dec_indent(f);
outf(f, "}");
return 1;
}
static int _print_historical_lv(struct formatter *f, struct historical_logical_volume *hlv)
{
char buffer[40];
char *descendants_buffer = NULL;
int r = 0;
if (_alloc_printed_indirect_descendants(&hlv->indirect_glvs, &descendants_buffer))
r = _print_historical_lv_with_descendants(f, hlv, descendants_buffer);
if (!id_write_format(&hlv->lvid.id[1], buffer, sizeof(buffer)))
goto_out;
if (!_alloc_printed_indirect_descendants(&hlv->indirect_glvs, &descendants_buffer))
goto_out;
outnlgo(f);
outfgo(f, "%s {", hlv->name);
_inc_indent(f);
outfgo(f, "id = \"%s\"", buffer);
if (!_print_timestamp(f, "creation_time", hlv->timestamp, buffer, sizeof(buffer)))
goto_out;
if (!_print_timestamp(f, "removal_time", hlv->timestamp_removed, buffer, sizeof(buffer)))
goto_out;
if (hlv->indirect_origin) {
if (hlv->indirect_origin->is_historical)
outfgo(f, "origin = \"%s%s\"", HISTORICAL_LV_PREFIX, hlv->indirect_origin->historical->name);
else
outfgo(f, "origin = \"%s\"", hlv->indirect_origin->live->name);
}
if (descendants_buffer)
outfgo(f, "descendants = %s", descendants_buffer);
_dec_indent(f);
outfgo(f, "}");
r = 1;
out:
free(descendants_buffer);
return r;
@@ -960,13 +946,12 @@ static int _build_pv_names(struct formatter *f, struct volume_group *vg)
int count = 0;
struct pv_list *pvl;
struct physical_volume *pv;
char buffer[32], *name;
char uuid[64];
char buffer[32], *uuid, *name;
if (!(f->mem = dm_pool_create("text pv_names", 512)))
return_0;
if (!(f->pv_names = dm_hash_create(115)))
if (!(f->pv_names = dm_hash_create(128)))
return_0;
dm_list_iterate_items(pvl, &vg->pvs) {
@@ -979,7 +964,8 @@ static int _build_pv_names(struct formatter *f, struct volume_group *vg)
if (!(name = dm_pool_strdup(f->mem, buffer)))
return_0;
if (!id_write_format(&pv->id, uuid, sizeof(uuid)))
if (!(uuid = dm_pool_zalloc(f->mem, 64)) ||
!id_write_format(&pv->id, uuid, 64))
return_0;
if (!dm_hash_insert(f->pv_names, uuid, name))
@@ -1045,53 +1031,62 @@ static int _text_vg_export(struct formatter *f,
int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp)
{
struct formatter *f;
int r;
struct formatter f = {
.indent = 0,
.header = 1,
.out_with_comment = &_out_with_comment_file,
.nl = &_nl_file,
.data.fp = fp,
};
_init();
if ((r = _text_vg_export(&f, vg, desc)))
r = !ferror(f.data.fp);
if (!(f = zalloc(sizeof(*f))))
return_0;
f->data.fp = fp;
f->indent = 0;
f->header = 1;
f->out_with_comment = &_out_with_comment_file;
f->nl = &_nl_file;
r = _text_vg_export(f, vg, desc);
if (r)
r = !ferror(f->data.fp);
free(f);
return r;
}
/* Returns amount of buffer used incl. terminating NUL */
size_t text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf, uint32_t *buf_size)
{
size_t r;
struct formatter f = {
.indent = 0,
.header = 0,
.out_with_comment = &_out_with_comment_raw,
.nl = &_nl_raw,
.data.buf.size = 65536, /* Initial metadata limit */
};
struct formatter *f;
size_t r = 0;
_init();
if (!(f.data.buf.start = zalloc(f.data.buf.size))) {
if (!(f = zalloc(sizeof(*f))))
return_0;
f->data.buf.size = 65536; /* Initial metadata limit */
if (!(f->data.buf.start = zalloc(f->data.buf.size))) {
log_error("text_export buffer allocation failed");
return 0;
goto out;
}
if (!_text_vg_export(&f, vg, desc)) {
free(f.data.buf.start);
return 0;
f->indent = 0;
f->header = 0;
f->out_with_comment = &_out_with_comment_raw;
f->nl = &_nl_raw;
if (!_text_vg_export(f, vg, desc)) {
free(f->data.buf.start);
goto_out;
}
r = f.data.buf.used + 1;
*buf = f.data.buf.start;
r = f->data.buf.used + 1;
*buf = f->data.buf.start;
if (buf_size)
*buf_size = f.data.buf.size;
*buf_size = f->data.buf.size;
out:
free(f);
return r;
}

View File

@@ -35,7 +35,6 @@ static const struct flag _vg_flags[] = {
{LVM_READ, "READ", STATUS_FLAG},
{LVM_WRITE, "WRITE", STATUS_FLAG},
{LVM_WRITE_LOCKED, "WRITE_LOCKED", COMPATIBLE_FLAG},
{NOAUTOACTIVATE, "NOAUTOACTIVATE", COMPATIBLE_FLAG},
{CLUSTERED, "CLUSTERED", STATUS_FLAG},
{SHARED, "SHARED", STATUS_FLAG},
{PARTIAL_VG, NULL, 0},
@@ -71,10 +70,8 @@ static const struct flag _lv_flags[] = {
{LV_REMOVE_AFTER_RESHAPE, "REMOVE_AFTER_RESHAPE", SEGTYPE_FLAG},
{LV_WRITEMOSTLY, "WRITEMOSTLY", STATUS_FLAG},
{LV_ACTIVATION_SKIP, "ACTIVATION_SKIP", COMPATIBLE_FLAG},
{LV_NOAUTOACTIVATE, "NOAUTOACTIVATE", COMPATIBLE_FLAG},
{LV_ERROR_WHEN_FULL, "ERROR_WHEN_FULL", COMPATIBLE_FLAG},
{LV_METADATA_FORMAT, "METADATA_FORMAT", SEGTYPE_FLAG},
{LV_CROP_METADATA, "CROP_METADATA", SEGTYPE_FLAG},
{LV_CACHE_VOL, "CACHE_VOL", COMPATIBLE_FLAG},
{LV_CACHE_USES_CACHEVOL, "CACHE_USES_CACHEVOL", SEGTYPE_FLAG},
{LV_NOSCAN, NULL, 0},

View File

@@ -28,7 +28,6 @@
#include "lib/mm/xlate.h"
#include "lib/label/label.h"
#include "lib/cache/lvmcache.h"
#include "libdaemon/client/config-util.h"
#include <unistd.h>
#include <limits.h>
@@ -64,7 +63,8 @@ void free_text_fidtc(struct volume_group *vg)
fidtc->preserve = 0;
free(fidtc->write_buf);
if (fidtc->write_buf)
free(fidtc->write_buf);
fidtc->write_buf = NULL;
fidtc->write_buf_size = 0;
fidtc->new_metadata_size = 0;
@@ -580,7 +580,6 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
struct metadata_area *mda)
{
char desc[2048];
struct dm_config_tree *cft;
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
struct text_fid_context *fidtc = (struct text_fid_context *) fid->private;
struct raw_locn *rlocn_old;
@@ -661,29 +660,14 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
(void) dm_snprintf(desc, sizeof(desc), "Write[%u] from %s.", vg->write_count, vg->cmd->cmd_line);
new_size = text_vg_export_raw(vg, desc, &write_buf, &write_buf_size);
if (!new_size || !write_buf) {
log_error("VG %s metadata writing failed", vg->name);
goto out;
}
fidtc->write_buf = write_buf;
fidtc->write_buf_size = write_buf_size;
fidtc->new_metadata_size = new_size;
}
/* Immediatelly reuse existing buffer for parsing metadata back.
* Such VG is then used for as precommitted VG and later committed VG.
*
* 'Lazy' creation of such VG might improve performance, but we
* lose important validation that written metadata can be parsed. */
if (!(cft = config_tree_from_string_without_dup_node_check(write_buf))) {
log_error("Error parsing metadata for VG %s.", vg->name);
goto out;
}
release_vg(vg->vg_precommitted);
vg->vg_precommitted = import_vg_from_config_tree(vg->cmd, vg->fid, cft);
dm_config_destroy(cft);
if (!vg->vg_precommitted)
goto_out;
if (!new_size || !write_buf) {
log_error("VG %s metadata writing failed", vg->name);
goto out;
}
log_debug_metadata("VG %s seqno %u metadata write to %s mda_start %llu mda_size %llu mda_last %llu",
@@ -1646,9 +1630,7 @@ int read_metadata_location_summary(const struct format_type *fmt,
vgsummary->mda_size = rlocn->size;
/* Keep track of largest metadata size we find. */
lvmcache_save_metadata_size_bytes(rlocn->size);
/* Keep track of the most full metadata area. */
lvmcache_save_metadata_size_percent(rlocn->size, mdah->size);
lvmcache_save_metadata_size(rlocn->size);
lvmcache_lookup_mda(vgsummary);
@@ -2036,7 +2018,9 @@ static void _text_destroy(struct format_type *fmt)
if (fmt->orphan_vg)
free_orphan_vg(fmt->orphan_vg);
free(fmt->private);
if (fmt->private)
free(fmt->private);
free(fmt);
}
@@ -2225,7 +2209,7 @@ static int _create_vg_text_instance(struct format_instance *fid,
vg_name = fic->context.vg_ref.vg_name;
vg_id = fic->context.vg_ref.vg_id;
if (!(fid->metadata_areas_index = dm_hash_create(116))) {
if (!(fid->metadata_areas_index = dm_hash_create(128))) {
log_error("Couldn't create metadata index for format "
"instance of VG %s.", vg_name);
return 0;

View File

@@ -186,8 +186,6 @@ struct volume_group *text_read_metadata(struct format_instance *fid,
goto_out;
(*vsn)->read_desc(vg->vgmem, cft, when, desc);
vg->committed_cft = cft; /* Reuse CFT for recreation of committed VG */
cft = NULL;
break;
}
@@ -200,8 +198,7 @@ struct volume_group *text_read_metadata(struct format_instance *fid,
*use_previous_vg = 0;
out:
if (cft)
config_destroy(cft);
config_destroy(cft);
return vg;
}
@@ -234,7 +231,7 @@ static struct volume_group *_import_vg_from_config_tree(struct cmd_context *cmd,
if (!(vg = (*vsn)->read_vg(cmd, fid->fmt, fid, cft)))
stack;
else {
set_pv_devices(fid, vg);
set_pv_devices(fid, vg, NULL);
if ((vg_missing = vg_missing_pv_count(vg)))
log_verbose("There are %d physical volumes missing.", vg_missing);

View File

@@ -128,7 +128,7 @@ static int _read_id(struct id *id, const struct dm_config_node *cn, const char *
return 1;
}
static int _read_flag_config(const struct dm_config_node *n, uint64_t *status, enum pv_vg_lv_e type)
static int _read_flag_config(const struct dm_config_node *n, uint64_t *status, int type)
{
const struct dm_config_value *cv;
*status = 0;
@@ -188,7 +188,7 @@ static int _read_pv(struct cmd_context *cmd,
struct physical_volume *pv;
struct pv_list *pvl;
const struct dm_config_value *cv;
const char *str;
const char *device_hint;
uint64_t size, ba_start;
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl))) ||
@@ -233,21 +233,11 @@ static int _read_pv(struct cmd_context *cmd,
return 0;
}
if (dm_config_get_str(pvn, "device", &str)) {
if (!(pv->device_hint = dm_pool_strdup(mem, str)))
if (dm_config_get_str(pvn, "device", &device_hint)) {
if (!(pv->device_hint = dm_pool_strdup(mem, device_hint)))
log_error("Failed to allocate memory for device hint in read_pv.");
}
if (dm_config_get_str(pvn, "device_id", &str)) {
if (!(pv->device_id = dm_pool_strdup(mem, str)))
log_error("Failed to allocate memory for device_id in read_pv.");
}
if (dm_config_get_str(pvn, "device_id_type", &str)) {
if (!(pv->device_id_type = dm_pool_strdup(mem, str)))
log_error("Failed to allocate memory for device_id_type in read_pv.");
}
if (!_read_uint64(pvn, "pe_start", &pv->pe_start)) {
log_error("Couldn't read extent start value (pe_start) "
"for physical volume.");
@@ -316,7 +306,7 @@ static int _read_pvsummary(struct cmd_context *cmd,
{
struct physical_volume *pv;
struct pv_list *pvl;
const char *str;
const char *device_hint;
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl))) ||
!(pvl->pv = dm_pool_zalloc(mem, sizeof(*pvl->pv))))
@@ -336,19 +326,9 @@ static int _read_pvsummary(struct cmd_context *cmd,
!_read_uint64(pvn, "dev_size", &pv->size))
log_warn("Couldn't read dev size for physical volume.");
if (dm_config_get_str(pvn, "device", &str)) {
if (!(pv->device_hint = dm_pool_strdup(mem, str)))
log_error("Failed to allocate memory for device hint in read_pv_sum.");
}
if (dm_config_get_str(pvn, "device_id", &str)) {
if (!(pv->device_id = dm_pool_strdup(mem, str)))
log_error("Failed to allocate memory for device_id in read_pv_sum.");
}
if (dm_config_get_str(pvn, "device_id_type", &str)) {
if (!(pv->device_id_type = dm_pool_strdup(mem, str)))
log_error("Failed to allocate memory for device_id_type in read_pv_sum.");
if (dm_config_get_str(pvn, "device", &device_hint)) {
if (!(pv->device_hint = dm_pool_strdup(mem, device_hint)))
log_error("Failed to allocate memory for device hint in read_pv.");
}
dm_list_add(&vgsummary->pvsummaries, &pvl->list);
@@ -1074,7 +1054,7 @@ static struct volume_group *_read_vg(struct cmd_context *cmd,
* The pv hash memorises the pv section names -> pv
* structures.
*/
if (!(pv_hash = dm_hash_create(59))) {
if (!(pv_hash = dm_hash_create(64))) {
log_error("Couldn't create pv hash table.");
goto bad;
}
@@ -1083,7 +1063,7 @@ static struct volume_group *_read_vg(struct cmd_context *cmd,
* The lv hash memorises the lv section names -> lv
* structures.
*/
if (!(lv_hash = dm_hash_create(1023))) {
if (!(lv_hash = dm_hash_create(1024))) {
log_error("Couldn't create lv hash table.");
goto bad;
}

View File

@@ -20,7 +20,9 @@
#define outhint(args...) do {if (!out_hint(args)) return_0;} while (0)
#define outfc(args...) do {if (!out_text_with_comment(args)) return_0;} while (0)
#define outf(args...) do {if (!out_text(args)) return_0;} while (0)
#define outfgo(args...) do {if (!out_text(args)) goto_out;} while (0)
#define outnl(f) do {if (!out_newline(f)) return_0;} while (0)
#define outnlgo(f) do {if (!out_newline(f)) goto_out;} while (0)
struct formatter;
struct lv_segment;

View File

@@ -379,7 +379,7 @@ static int _text_read(struct cmd_context *cmd, struct labeller *labeller, struct
struct label_header *lh = (struct label_header *) label_buf;
struct pv_header *pvhdr;
struct pv_header_extension *pvhdr_ext;
struct metadata_area *mda = NULL;
struct metadata_area *mda;
struct metadata_area *mda1 = NULL;
struct metadata_area *mda2 = NULL;
struct disk_locn *dlocn_xl;

View File

@@ -240,8 +240,9 @@ static int _target_present(struct cmd_context *cmd,
if (!_integrity_checked) {
_integrity_checked = 1;
if (!(_integrity_present = target_present_version(cmd, TARGET_NAME_INTEGRITY, 1,
&maj, &min, &patchlevel)))
_integrity_present = target_present(cmd, TARGET_NAME_INTEGRITY, 1);
if (!target_version(TARGET_NAME_INTEGRITY, &maj, &min, &patchlevel))
return 0;
if (maj < 1 || min < 6) {
@@ -294,7 +295,7 @@ static int _integrity_add_target_line(struct dev_manager *dm,
if (!seg->integrity_data_sectors) {
log_error("_integrity_add_target_line zero size");
return 0;
return_0;
}
if (!dm_tree_node_add_integrity_target(node, seg->integrity_data_sectors,

View File

@@ -145,7 +145,6 @@
#include "lib/activate/activate.h"
#include "lib/label/hints.h"
#include "lib/device/dev-type.h"
#include "lib/device/device_id.h"
#include <sys/stat.h>
#include <fcntl.h>
@@ -167,10 +166,8 @@ static const char *_newhints_file = DEFAULT_RUN_DIR "/newhints";
* than they were built with. Increase the minor number
* when adding features that older lvm versions can just
* ignore while continuing to use the other content.
*
* MAJOR 2: add devices_file
*/
#define HINTS_VERSION_MAJOR 2
#define HINTS_VERSION_MAJOR 1
#define HINTS_VERSION_MINOR 1
#define HINT_LINE_LEN (PATH_MAX + NAME_LEN + ID_LEN + 64)
@@ -448,7 +445,7 @@ static int _dev_in_hint_hash(struct cmd_context *cmd, struct device *dev)
return 0;
if (!dev_get_size(dev, &devsize) || !devsize)
return 0;
return_0;
return 1;
}
@@ -715,9 +712,8 @@ static int _read_hint_file(struct cmd_context *cmd, struct dm_list *hints, int *
break;
}
if (hv_major != HINTS_VERSION_MAJOR) {
log_debug("ignore hints with version %d.%d current %d.%d",
hv_major, hv_minor, HINTS_VERSION_MAJOR, HINTS_VERSION_MINOR);
if (hv_major > HINTS_VERSION_MAJOR) {
log_debug("ignore hints with newer major version %d.%d", hv_major, hv_minor);
*needs_refresh = 1;
break;
}
@@ -762,25 +758,6 @@ static int _read_hint_file(struct cmd_context *cmd, struct dm_list *hints, int *
continue;
}
keylen = strlen("devices_file:");
if (!strncmp(_hint_line, "devices_file:", keylen)) {
const char *df_hint = _hint_line + keylen;
const char *df_config = find_config_tree_str(cmd, devices_devicesfile_CFG, NULL);
/* when a devices file is not used, hints should have devices_file:. */
if (!cmd->enable_devices_file || !df_hint || !df_config) {
if (df_hint[0] != '.') {
log_debug("ignore hints with different devices_file: not enabled vs %s", df_hint);
*needs_refresh = 1;
break;
}
} else if (strcmp(df_hint, df_config)) {
log_debug("ignore hints with different devices_file: %s vs %s", df_hint, df_config);
*needs_refresh = 1;
break;
}
continue;
}
keylen = strlen("devs_hash:");
if (!strncmp(_hint_line, "devs_hash:", keylen)) {
if (sscanf(_hint_line + keylen, "%u %u", &read_hash, &read_count) != 2) {
@@ -850,12 +827,8 @@ static int _read_hint_file(struct cmd_context *cmd, struct dm_list *hints, int *
if (!(iter = dev_iter_create(NULL, 0)))
return 0;
while ((dev = dev_iter_get(cmd, iter))) {
if (cmd->enable_devices_file && !get_du_for_dev(cmd, dev))
continue;
if (!_dev_in_hint_hash(cmd, dev))
continue;
(void) dm_strncpy(devpath, dev_name(dev), sizeof(devpath));
calc_hash = calc_crc(calc_hash, (const uint8_t *)devpath, strlen(devpath));
calc_count++;
@@ -914,7 +887,6 @@ int write_hint_file(struct cmd_context *cmd, int newhints)
struct device *dev;
const char *vgname;
char *filter_str = NULL;
const char *config_devices_file = NULL;
uint32_t hash = INITIAL_CRC;
uint32_t count = 0;
time_t t;
@@ -975,19 +947,6 @@ int write_hint_file(struct cmd_context *cmd, int newhints)
fprintf(fp, "scan_lvs:%d\n", cmd->scan_lvs);
/*
* Only associate hints with the default/system devices file.
* If no default/system devices file is used, "." is set.
* If we are using a devices file other than the config setting
* (from --devicesfile), then we should not be using hints and
* shouldn't get here.
*/
config_devices_file = find_config_tree_str(cmd, devices_devicesfile_CFG, NULL);
if (cmd->enable_devices_file && !cmd->devicesfile && config_devices_file)
fprintf(fp, "devices_file:%s\n", config_devices_file);
else
fprintf(fp, "devices_file:.\n");
/*
* iterate through all devs and write a line for each
* dev flagged DEV_SCAN_FOUND_LABEL
@@ -1005,9 +964,6 @@ int write_hint_file(struct cmd_context *cmd, int newhints)
* 2. add PVs to the hint file
*/
while ((dev = dev_iter_get(cmd, iter))) {
if (cmd->enable_devices_file && !get_du_for_dev(cmd, dev))
continue;
if (!_dev_in_hint_hash(cmd, dev)) {
if (dev->flags & DEV_SCAN_FOUND_LABEL) {
/* should never happen */
@@ -1288,14 +1244,12 @@ check:
*/
int get_hints(struct cmd_context *cmd, struct dm_list *hints_out, int *newhints,
struct dm_list *devs_in, struct dm_list *devs_out, char **vgname_out)
struct dm_list *devs_in, struct dm_list *devs_out)
{
struct dm_list hints_list;
int needs_refresh = 0;
char *vgname = NULL;
*vgname_out = NULL;
dm_list_init(&hints_list);
/* Decide below if the caller should create new hints. */
@@ -1374,7 +1328,7 @@ int get_hints(struct cmd_context *cmd, struct dm_list *hints_out, int *newhints,
}
/*
* couldn't read file for some reason, not normal, just skip using hints
* couln't read file for some reason, not normal, just skip using hints
*/
if (!_read_hint_file(cmd, &hints_list, &needs_refresh)) {
log_debug("get_hints: read fail");
@@ -1399,6 +1353,7 @@ int get_hints(struct cmd_context *cmd, struct dm_list *hints_out, int *newhints,
/* create new hints after scan */
*newhints = NEWHINTS_REFRESH;
return 0;
}
/*
@@ -1430,12 +1385,12 @@ int get_hints(struct cmd_context *cmd, struct dm_list *hints_out, int *newhints,
_apply_hints(cmd, &hints_list, vgname, devs_in, devs_out);
log_debug("get_hints: applied using %d other %d vgname %s",
dm_list_size(devs_out), dm_list_size(devs_in), vgname ?: "");
log_debug("get_hints: applied using %d other %d",
dm_list_size(devs_out), dm_list_size(devs_in));
dm_list_splice(hints_out, &hints_list);
*vgname_out = vgname;
free(vgname);
return 1;
}

View File

@@ -17,10 +17,10 @@
struct hint {
struct dm_list list;
char name[PATH_MAX];
char pvid[ID_LEN + 1];
char vgname[NAME_LEN];
dev_t devt;
char name[PATH_MAX] __attribute__((aligned(8)));
char vgname[NAME_LEN] __attribute__((aligned(8)));
char pvid[ID_LEN + 1] __attribute__((aligned(8)));
unsigned chosen:1; /* this hint's dev was chosen for scanning */
};
@@ -33,7 +33,7 @@ void clear_hint_file(struct cmd_context *cmd);
void invalidate_hints(struct cmd_context *cmd);
int get_hints(struct cmd_context *cmd, struct dm_list *hints, int *newhints,
struct dm_list *devs_in, struct dm_list *devs_out, char **vgname_out);
struct dm_list *devs_in, struct dm_list *devs_out);
int validate_hints(struct cmd_context *cmd, struct dm_list *hints);

View File

@@ -25,7 +25,6 @@
#include "lib/label/hints.h"
#include "lib/metadata/metadata.h"
#include "lib/format_text/layout.h"
#include "lib/device/device_id.h"
#include <sys/stat.h>
#include <fcntl.h>
@@ -582,8 +581,7 @@ retry_open:
if (di == -1) {
log_error("Failed to set bcache fd.");
if (close(fd))
log_sys_debug("close", name);
close(fd);
dev->bcache_fd = -1;
return 0;
}
@@ -807,6 +805,16 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
}
}
/*
* This will search the system's /dev for new path names and
* could help us reopen the device if it finds a new preferred
* path name for this dev's major:minor. It does that by
* inserting a new preferred path name on dev->aliases. open
* uses the first name from that list.
*/
log_debug_devs("Scanning refreshing device paths.");
dev_cache_scan();
/* Put devs that failed to open back on the original list to retry. */
dm_list_splice(devs, &reopen_devs);
goto scan_more;
@@ -928,12 +936,6 @@ static void _prepare_open_file_limit(struct cmd_context *cmd, unsigned int num_d
#endif
}
/*
* Currently the only caller is pvck which probably doesn't need
* deferred filters checked after the read... it wants to know if
* anything has the pvid, even a dev that might be filtered.
*/
int label_scan_for_pvid(struct cmd_context *cmd, char *pvid, struct device **dev_out)
{
char buf[LABEL_SIZE] __attribute__((aligned(8)));
@@ -946,20 +948,7 @@ int label_scan_for_pvid(struct cmd_context *cmd, char *pvid, struct device **dev
dm_list_init(&devs);
/*
* Creates a list of available devices, does not open or read any,
* and does not filter them.
*/
if (!setup_devices(cmd)) {
log_error("Failed to set up devices.");
return 0;
}
/*
* Iterating over all available devices with cmd->filter filters
* devices; those returned from dev_iter_get are the devs that
* pass filters, and are those we can use.
*/
dev_cache_scan();
if (!(iter = dev_iter_create(cmd->filter, 0))) {
log_error("Scanning failed to get devices.");
@@ -1032,9 +1021,7 @@ int label_scan(struct cmd_context *cmd)
struct dev_iter *iter;
struct device_list *devl, *devl2;
struct device *dev;
char *vgname_hint = NULL;
uint64_t max_metadata_size_bytes;
int device_ids_invalid = 0;
int using_hints;
int create_hints = 0; /* NEWHINTS_NONE */
@@ -1051,17 +1038,12 @@ int label_scan(struct cmd_context *cmd)
}
/*
* Creates a list of available devices, does not open or read any,
* and does not filter them. The list of all available devices
* is kept in "dev-cache", and comes from /dev entries or libudev.
* The list of devs found here needs to be filtered to get the
* list of devs we can use. The dev_iter calls using cmd->filter
* are what filters the devs.
* dev_cache_scan() creates a list of devices on the system
* (saved in in dev-cache) which we can iterate through to
* search for LVM devs. The dev cache list either comes from
* looking at dev nodes under /dev, or from udev.
*/
if (!setup_devices(cmd)) {
log_error("Failed to set up devices.");
return 0;
}
dev_cache_scan();
/*
* If we know that there will be md components with an end
@@ -1098,7 +1080,7 @@ int label_scan(struct cmd_context *cmd)
* so this will usually do nothing.
*/
label_scan_invalidate(dev);
}
};
dev_iter_destroy(iter);
/*
@@ -1138,54 +1120,21 @@ int label_scan(struct cmd_context *cmd)
* by using hints which tell us which devices are PVs, which
* are the only devices we actually need to scan. Without
* hints we need to scan all devs to find which are PVs.
*/
if (!get_hints(cmd, &hints_list, &create_hints, &all_devs, &scan_devs, &vgname_hint)) {
dm_list_splice(&scan_devs, &all_devs);
dm_list_init(&hints_list);
using_hints = 0;
} else
using_hints = 1;
/*
* If the command is using hints and a single vgname
*
* TODO: if the command is using hints and a single vgname
* arg, we can also take the vg lock here, prior to scanning.
* This means we would not need to rescan the PVs in the VG
* in vg_read (skip lvmcache_label_rescan_vg) after the
* vg lock is usually taken. (Some commands are already
* able to avoid rescan in vg_read, but locking early would
* apply to more cases.)
*
* TODO: we don't know exactly which vg lock mode (read or write)
* the command will use in vg_read() for the normal lock_vol(),
* but we could make a fairly accurate guess of READ/WRITE based
* on looking at the command name. If we guess wrong we can
* just unlock_vg and lock_vol again with the correct mode in
* vg_read().
*/
if (vgname_hint) {
uint32_t lck_type = LCK_VG_WRITE;
log_debug("Early lock vg");
/* FIXME: borrowing this lockd flag which should be
quite close to what we want, based on the command name.
Need to do proper mode selection here, and then check
in case the later lock_vol in vg_read wants different. */
if (cmd->lockd_vg_default_sh)
lck_type = LCK_VG_READ;
if (!lock_vol(cmd, vgname_hint, lck_type, NULL)) {
log_warn("Could not pre-lock VG %s.", vgname_hint);
/* not an error since this is just an optimization */
} else {
/* Save some state indicating that the vg lock
is already held so that the normal lock_vol()
will know. */
cmd->early_lock_vg_mode = lck_type;
}
free(vgname_hint);
}
if (!get_hints(cmd, &hints_list, &create_hints, &all_devs, &scan_devs)) {
dm_list_splice(&scan_devs, &all_devs);
dm_list_init(&hints_list);
using_hints = 0;
} else
using_hints = 1;
/*
* If the total number of devices exceeds the soft open file
@@ -1221,7 +1170,7 @@ int label_scan(struct cmd_context *cmd)
* If the largest metadata is within 1MB of the bcache size, then start
* warning.
*/
max_metadata_size_bytes = lvmcache_max_metadata_size_bytes();
max_metadata_size_bytes = lvmcache_max_metadata_size();
if (max_metadata_size_bytes + (1024 * 1024) > _current_bcache_size_bytes) {
/* we want bcache to be 1MB larger than the max metadata seen */
@@ -1236,14 +1185,6 @@ int label_scan(struct cmd_context *cmd)
(unsigned long long)want_size_kb);
}
/*
* If vg metadata is using a large percentage of a metadata area, then
* create /run/lvm/scan_lock_global to tell future lvm commands to
* begin doing lock_global() prior to scanning to avoid problems due to
* metadata wrapping between label_scan and vg_read.
*/
set_scan_lock_global(cmd);
dm_list_init(&cmd->hints);
/*
@@ -1255,14 +1196,9 @@ int label_scan(struct cmd_context *cmd)
if (!validate_hints(cmd, &hints_list)) {
log_debug("Will scan %d remaining devices", dm_list_size(&all_devs));
_scan_list(cmd, cmd->filter, &all_devs, 0, NULL);
/* scan_devs are the devs that have been scanned */
dm_list_splice(&scan_devs, &all_devs);
free_hints(&hints_list);
using_hints = 0;
create_hints = 0;
/* invalid hints means a new dev probably appeared and
we should search for any missing pvids again. */
unlink_searched_devnames(cmd);
} else {
/* The hints may be used by another device iteration. */
dm_list_splice(&cmd->hints, &hints_list);
@@ -1270,10 +1206,32 @@ int label_scan(struct cmd_context *cmd)
}
/*
* Check if the devices_file content is up to date and
* if not update it.
* Stronger exclusion of md components that might have been
* misidentified as PVs due to having an end-of-device md superblock.
* If we're not using hints, and are not already doing a full md check
* on devs being scanned, then if udev info is missing for a PV, scan
* the end of the PV to verify it's not an md component. The full
* dev_is_md_component call will do new reads at the end of the dev.
*/
device_ids_validate(cmd, &scan_devs, &device_ids_invalid, 0);
if (cmd->md_component_detection && !cmd->use_full_md_check && !using_hints &&
!strcmp(cmd->md_component_checks, "auto")) {
int once = 0;
dm_list_iterate_items(devl, &scan_devs) {
if (!(devl->dev->flags & DEV_SCAN_FOUND_LABEL))
continue;
if (!(devl->dev->flags & DEV_UDEV_INFO_MISSING))
continue;
if (!once++)
log_debug_devs("Scanning end of PVs with no udev info for MD components");
if (dev_is_md_component(devl->dev, NULL, 1)) {
log_debug_devs("Scan dropping PV from MD component %s", dev_name(devl->dev));
devl->dev->flags &= ~DEV_SCAN_FOUND_LABEL;
lvmcache_del_dev(devl->dev);
lvmcache_del_dev_from_duplicates(devl->dev);
}
}
}
dm_list_iterate_items_safe(devl, devl2, &all_devs) {
dm_list_del(&devl->list);
@@ -1285,23 +1243,6 @@ int label_scan(struct cmd_context *cmd)
free(devl);
}
dm_list_iterate_items_safe(devl, devl2, &filtered_devs) {
dm_list_del(&devl->list);
free(devl);
}
/*
* Look for md components that might have been missed by filter-md
* during the scan. With the label scanning complete we have metadata
* available that can sometimes offer a clue that a dev is actually an
* md component (device name hint, pv size vs dev size). In some of
* those cases we may want to do a full md check on a dev that has been
* scanned. This is done before hints are written so that any devs
* dropped due to being md components will not be included in a new
* hint file.
*/
lvmcache_extra_md_component_checks(cmd);
/*
* If hints were not available/usable, then we scanned all devs,
* and we now know which are PVs. Save this list of PVs we've
@@ -1309,7 +1250,7 @@ int label_scan(struct cmd_context *cmd)
* (create_hints variable has NEWHINTS_X value which indicates
* the reason for creating the new hints.)
*/
if (create_hints && !device_ids_invalid)
if (create_hints)
write_hint_file(cmd, create_hints);
return 1;
@@ -1319,7 +1260,7 @@ int label_scan(struct cmd_context *cmd)
* Read the header of the disk and if it's a PV
* save the pvid in dev->pvid.
*/
int label_read_pvid(struct device *dev, int *has_pvid)
int label_read_pvid(struct device *dev)
{
char buf[4096] __attribute__((aligned(8)));
struct label_header *lh;
@@ -1338,17 +1279,14 @@ int label_read_pvid(struct device *dev, int *has_pvid)
*/
if (!dev_read_bytes(dev, 0, 4096, buf)) {
label_scan_invalidate(dev);
return_0;
return 0;
}
if (has_pvid)
*has_pvid = 0;
lh = (struct label_header *)(buf + 512);
if (memcmp(lh->id, LABEL_ID, sizeof(lh->id))) {
/* Not an lvm deice */
label_scan_invalidate(dev);
return 1;
return 0;
}
/*
@@ -1358,12 +1296,9 @@ int label_read_pvid(struct device *dev, int *has_pvid)
if (memcmp(lh->type, LVM2_LABEL, sizeof(lh->type))) {
/* Not an lvm deice */
label_scan_invalidate(dev);
return 1;
return 0;
}
if (has_pvid)
*has_pvid = 1;
pvh = (struct pv_header *)(buf + 512 + 32);
memcpy(dev->pvid, pvh->pv_uuid, ID_LEN);
return 1;
@@ -1473,12 +1408,12 @@ void label_scan_invalidate_lv(struct cmd_context *cmd, struct logical_volume *lv
struct device *dev;
dev_t devt;
if (lv_info(cmd, lv, 0, &lvinfo, 0, 0) && lvinfo.exists) {
/* FIXME: Still unclear what is it supposed to find */
devt = MKDEV(lvinfo.major, lvinfo.minor);
if ((dev = dev_cache_get_by_devt(cmd, devt, NULL, NULL)))
label_scan_invalidate(dev);
}
if (!lv_info(cmd, lv, 0, &lvinfo, 0, 0))
return;
devt = MKDEV(lvinfo.major, lvinfo.minor);
if ((dev = dev_cache_get_by_devt(cmd, devt, NULL, NULL)))
label_scan_invalidate(dev);
}
/*
@@ -1495,7 +1430,6 @@ void label_scan_drop(struct cmd_context *cmd)
return;
while ((dev = dev_iter_get(cmd, iter))) {
cmd->filter->wipe(cmd, cmd->filter, dev, NULL);
if (_in_bcache(dev))
_scan_dev_close(dev);
}
@@ -1641,8 +1575,7 @@ int label_scan_reopen_rw(struct device *dev)
if (!bcache_change_fd(dev->bcache_di, fd)) {
log_error("Failed to change to rw fd %s di %d fd %d.",
dev_name(dev), dev->bcache_di, fd);
if (close(fd))
log_sys_debug("close", dev_name(dev));
close(fd);
return 0;
}
@@ -1705,7 +1638,7 @@ bool dev_write_bytes(struct device *dev, uint64_t start, size_t len, void *data)
_scan_dev_close(dev);
dev->flags |= DEV_BCACHE_WRITE;
(void) label_scan_open(dev); /* checked later */
label_scan_open(dev);
}
if (dev->bcache_di < 0) {

View File

@@ -112,12 +112,13 @@ void label_scan_invalidate(struct device *dev);
void label_scan_invalidate_lv(struct cmd_context *cmd, struct logical_volume *lv);
void label_scan_drop(struct cmd_context *cmd);
void label_scan_destroy(struct cmd_context *cmd);
void label_scan_confirm(struct device *dev);
int label_scan_setup_bcache(void);
int label_scan_open(struct device *dev);
int label_scan_open_excl(struct device *dev);
int label_scan_open_rw(struct device *dev);
int label_scan_reopen_rw(struct device *dev);
int label_read_pvid(struct device *dev, int *has_pvid);
int label_read_pvid(struct device *dev);
int label_scan_for_pvid(struct cmd_context *cmd, char *pvid, struct device **dev_out);

View File

@@ -203,11 +203,6 @@ int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags, const str
if (is_orphan_vg(vol))
return 1;
if (!is_global && cmd->early_lock_vg_mode && (lck_type != LCK_UNLOCK)) {
log_debug("VG was locked early.");
return 1;
}
if (!_blocking_supported)
flags |= LCK_NONBLOCK;
@@ -359,8 +354,10 @@ static int _lockf_global(struct cmd_context *cmd, const char *mode, int convert,
if (!strcmp(mode, "ex")) {
flags |= LCK_WRITE;
if (cmd->lockf_global_ex)
if (cmd->lockf_global_ex) {
log_warn("global flock already held ex");
return 1;
}
ret = lock_vol(cmd, VG_GLOBAL, flags, NULL);
if (ret)

View File

@@ -56,11 +56,8 @@ int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags, const str
#define unlock_vg(cmd, vg, vol) \
do { \
if (is_real_vg(vol)) { \
if (!sync_local_dev_names(cmd)) \
stack; \
vg_backup_if_needed(vg); \
} \
if (is_real_vg(vol) && !sync_local_dev_names(cmd)) \
stack; \
if (!lock_vol(cmd, vol, LCK_VG_UNLOCK, NULL)) \
stack; \
} while (0)

View File

@@ -25,11 +25,6 @@ static int _use_lvmlockd = 0; /* is 1 if command is configured to use lv
static int _lvmlockd_connected = 0; /* is 1 if command is connected to lvmlockd */
static int _lvmlockd_init_failed = 0; /* used to suppress further warnings */
struct lvmlockd_pvs {
char **path;
int num;
};
void lvmlockd_set_socket(const char *sock)
{
_lvmlockd_socket = sock;
@@ -183,34 +178,18 @@ static int _lockd_result(daemon_reply reply, int *result, uint32_t *lockd_flags)
return 1;
}
static daemon_reply _lockd_send_with_pvs(const char *req_name,
const struct lvmlockd_pvs *lock_pvs, ...)
static daemon_reply _lockd_send(const char *req_name, ...)
{
va_list ap;
daemon_reply repl;
daemon_request req;
int i;
char key[32];
const char *val;
va_list ap;
req = daemon_request_make(req_name);
va_start(ap, lock_pvs);
va_start(ap, req_name);
daemon_request_extend_v(req, ap);
va_end(ap);
/* Pass PV list */
if (lock_pvs && lock_pvs->num) {
daemon_request_extend(req, "path_num = " FMTd64,
(int64_t)(lock_pvs)->num, NULL);
for (i = 0; i < lock_pvs->num; i++) {
snprintf(key, sizeof(key), "path[%d] = %%s", i);
val = lock_pvs->path[i] ? lock_pvs->path[i] : "none";
daemon_request_extend(req, key, val, NULL);
}
}
repl = daemon_send(_lvmlockd, req);
daemon_request_destroy(req);
@@ -218,166 +197,6 @@ static daemon_reply _lockd_send_with_pvs(const char *req_name,
return repl;
}
#define _lockd_send(req_name, args...) \
_lockd_send_with_pvs(req_name, NULL, ##args)
static int _lockd_retrive_vg_pv_num(struct volume_group *vg)
{
struct pv_list *pvl;
int num = 0;
dm_list_iterate_items(pvl, &vg->pvs)
num++;
return num;
}
static void _lockd_retrive_vg_pv_list(struct volume_group *vg,
struct lvmlockd_pvs *lock_pvs)
{
struct pv_list *pvl;
int pv_num, i;
memset(lock_pvs, 0x0, sizeof(*lock_pvs));
pv_num = _lockd_retrive_vg_pv_num(vg);
if (!pv_num) {
log_error("Fail to any PVs for VG %s", vg->name);
return;
}
/* Allocate buffer for PV list */
lock_pvs->path = zalloc(sizeof(*lock_pvs->path) * pv_num);
if (!lock_pvs->path) {
log_error("Fail to allocate PV list for VG %s", vg->name);
return;
}
i = 0;
dm_list_iterate_items(pvl, &vg->pvs) {
lock_pvs->path[i] = strdup(pv_dev_name(pvl->pv));
if (!lock_pvs->path[i]) {
log_error("Fail to allocate PV path for VG %s", vg->name);
goto fail;
}
log_debug("VG %s find PV device %s", vg->name, lock_pvs->path[i]);
i++;
}
lock_pvs->num = pv_num;
return;
fail:
for (i = 0; i < pv_num; i++) {
if (!lock_pvs->path[i])
continue;
free(lock_pvs->path[i]);
}
free(lock_pvs->path);
return;
}
static int _lockd_retrive_lv_pv_num(struct volume_group *vg,
const char *lv_name)
{
struct logical_volume *lv = find_lv(vg, lv_name);
struct pv_list *pvl;
int num;
if (!lv)
return 0;
num = 0;
dm_list_iterate_items(pvl, &vg->pvs) {
if (lv_is_on_pv(lv, pvl->pv))
num++;
}
return num;
}
static void _lockd_retrive_lv_pv_list(struct volume_group *vg,
const char *lv_name,
struct lvmlockd_pvs *lock_pvs)
{
struct logical_volume *lv = find_lv(vg, lv_name);
struct pv_list *pvl;
int pv_num, i = 0;
memset(lock_pvs, 0x0, sizeof(*lock_pvs));
/* Cannot find any existed LV? */
if (!lv)
return;
pv_num = _lockd_retrive_lv_pv_num(vg, lv_name);
if (!pv_num) {
/*
* Fixup for 'lvcreate --type error -L1 -n $lv1 $vg', in this
* case, the drive path list is empty since it doesn't establish
* the structure 'pvseg->lvseg->lv->name'.
*
* So create drive path list with all drives in the VG.
*/
log_error("Fail to find any PVs for %s/%s, try to find PVs from VG instead",
vg->name, lv_name);
_lockd_retrive_vg_pv_list(vg, lock_pvs);
return;
}
/* Allocate buffer for PV list */
lock_pvs->path = malloc(sizeof(*lock_pvs->path) * pv_num);
if (!lock_pvs->path) {
log_error("Fail to allocate PV list for %s/%s", vg->name, lv_name);
return;
}
dm_list_iterate_items(pvl, &vg->pvs) {
if (lv_is_on_pv(lv, pvl->pv)) {
lock_pvs->path[i] = strdup(pv_dev_name(pvl->pv));
if (!lock_pvs->path[i]) {
log_error("Fail to allocate PV path for LV %s/%s",
vg->name, lv_name);
goto fail;
}
log_debug("Find PV device %s for LV %s/%s",
lock_pvs->path[i], vg->name, lv_name);
i++;
}
}
lock_pvs->num = pv_num;
return;
fail:
for (i = 0; i < pv_num; i++) {
if (!lock_pvs->path[i])
continue;
free(lock_pvs->path[i]);
lock_pvs->path[i] = NULL;
}
free(lock_pvs->path);
lock_pvs->path = NULL;
lock_pvs->num = 0;
return;
}
static void _lockd_free_pv_list(struct lvmlockd_pvs *lock_pvs)
{
int i;
for (i = 0; i < lock_pvs->num; i++) {
free(lock_pvs->path[i]);
lock_pvs->path[i] = NULL;
}
free(lock_pvs->path);
lock_pvs->path = NULL;
lock_pvs->num = 0;
}
/*
* result/lockd_flags are values returned from lvmlockd.
*
@@ -408,7 +227,6 @@ static int _lockd_request(struct cmd_context *cmd,
const char *lv_lock_args,
const char *mode,
const char *opts,
const struct lvmlockd_pvs *lock_pvs,
int *result,
uint32_t *lockd_flags)
{
@@ -433,8 +251,7 @@ static int _lockd_request(struct cmd_context *cmd,
cmd_name = "none";
if (vg_name && lv_name) {
reply = _lockd_send_with_pvs(req_name,
lock_pvs,
reply = _lockd_send(req_name,
"cmd = %s", cmd_name,
"pid = " FMTd64, (int64_t) pid,
"mode = %s", mode,
@@ -454,8 +271,7 @@ static int _lockd_request(struct cmd_context *cmd,
req_name, mode, vg_name, lv_name, *result, *lockd_flags);
} else if (vg_name) {
reply = _lockd_send_with_pvs(req_name,
lock_pvs,
reply = _lockd_send(req_name,
"cmd = %s", cmd_name,
"pid = " FMTd64, (int64_t) pid,
"mode = %s", mode,
@@ -472,8 +288,7 @@ static int _lockd_request(struct cmd_context *cmd,
req_name, mode, vg_name, *result, *lockd_flags);
} else {
reply = _lockd_send_with_pvs(req_name,
lock_pvs,
reply = _lockd_send(req_name,
"cmd = %s", cmd_name,
"pid = " FMTd64, (int64_t) pid,
"mode = %s", mode,
@@ -567,7 +382,6 @@ static int _extend_sanlock_lv(struct cmd_context *cmd, struct volume_group *vg,
{
struct device *dev;
char path[PATH_MAX];
char *name;
uint64_t old_size_bytes;
uint64_t new_size_bytes;
uint32_t extend_bytes;
@@ -609,10 +423,8 @@ static int _extend_sanlock_lv(struct cmd_context *cmd, struct volume_group *vg,
new_size_bytes = lv->size * SECTOR_SIZE;
if (!(name = dm_build_dm_name(lv->vg->cmd->mem, lv->vg->name, lv->name, NULL)))
return_0;
if (dm_snprintf(path, sizeof(path), "%s/%s", dm_dir(), name) < 0) {
if (dm_snprintf(path, sizeof(path), "%s/mapper/%s-%s", lv->vg->cmd->dev_dir,
lv->vg->name, lv->name) < 0) {
log_error("Extend sanlock LV %s name too long - extended size not zeroed.",
display_lvname(lv));
return 0;
@@ -738,8 +550,7 @@ static int _deactivate_sanlock_lv(struct cmd_context *cmd, struct volume_group *
return 1;
}
static int _init_vg(struct cmd_context *cmd, struct volume_group *vg,
const char *lock_type)
static int _init_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
{
daemon_reply reply;
const char *reply_str;
@@ -755,7 +566,7 @@ static int _init_vg(struct cmd_context *cmd, struct volume_group *vg,
reply = _lockd_send("init_vg",
"pid = " FMTd64, (int64_t) getpid(),
"vg_name = %s", vg->name,
"vg_lock_type = %s", lock_type,
"vg_lock_type = %s", "dlm",
NULL);
if (!_lockd_result(reply, &result, NULL)) {
@@ -775,12 +586,10 @@ static int _init_vg(struct cmd_context *cmd, struct volume_group *vg,
log_error("VG %s init failed: invalid parameters for dlm", vg->name);
break;
case -EMANAGER:
log_error("VG %s init failed: lock manager %s is not running",
vg->name, lock_type);
log_error("VG %s init failed: lock manager dlm is not running", vg->name);
break;
case -EPROTONOSUPPORT:
log_error("VG %s init failed: lock manager %s is not supported by lvmlockd",
vg->name, lock_type);
log_error("VG %s init failed: lock manager dlm is not supported by lvmlockd", vg->name);
break;
case -EEXIST:
log_error("VG %s init failed: a lockspace with the same name exists", vg->name);
@@ -804,7 +613,7 @@ static int _init_vg(struct cmd_context *cmd, struct volume_group *vg,
goto out;
}
vg->lock_type = lock_type;
vg->lock_type = "dlm";
vg->lock_args = vg_lock_args;
if (!vg_write(vg) || !vg_commit(vg)) {
@@ -819,16 +628,6 @@ out:
return ret;
}
static int _init_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
{
return _init_vg(cmd, vg, "dlm");
}
static int _init_vg_idm(struct cmd_context *cmd, struct volume_group *vg)
{
return _init_vg(cmd, vg, "idm");
}
static int _init_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg, int lv_lock_count)
{
daemon_reply reply;
@@ -992,7 +791,7 @@ out:
/* called after vg_remove on disk */
static int _free_vg(struct cmd_context *cmd, struct volume_group *vg)
static int _free_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
{
daemon_reply reply;
uint32_t lockd_flags = 0;
@@ -1018,27 +817,16 @@ static int _free_vg(struct cmd_context *cmd, struct volume_group *vg)
}
if (!ret)
log_error("%s: lock type %s lvmlockd result %d",
__func__, vg->lock_type, result);
log_error("_free_vg_dlm lvmlockd result %d", result);
daemon_reply_destroy(reply);
return 1;
}
static int _free_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
{
return _free_vg(cmd, vg);
}
static int _free_vg_idm(struct cmd_context *cmd, struct volume_group *vg)
{
return _free_vg(cmd, vg);
}
/* called before vg_remove on disk */
static int _busy_vg(struct cmd_context *cmd, struct volume_group *vg)
static int _busy_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
{
daemon_reply reply;
uint32_t lockd_flags = 0;
@@ -1073,24 +861,13 @@ static int _busy_vg(struct cmd_context *cmd, struct volume_group *vg)
}
if (!ret)
log_error("%s: lock type %s lvmlockd result %d", __func__,
vg->lock_type, result);
log_error("_busy_vg_dlm lvmlockd result %d", result);
out:
daemon_reply_destroy(reply);
return ret;
}
static int _busy_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
{
return _busy_vg(cmd, vg);
}
static int _busy_vg_idm(struct cmd_context *cmd, struct volume_group *vg)
{
return _busy_vg(cmd, vg);
}
/* called before vg_remove on disk */
static int _free_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg)
@@ -1196,8 +973,6 @@ int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg,
return _init_vg_dlm(cmd, vg);
case LOCK_TYPE_SANLOCK:
return _init_vg_sanlock(cmd, vg, lv_lock_count);
case LOCK_TYPE_IDM:
return _init_vg_idm(cmd, vg);
default:
log_error("Unknown lock_type.");
return 0;
@@ -1239,8 +1014,7 @@ int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg,
* When removing (not changing), each LV is locked
* when it is removed, they do not need checking here.
*/
if (lock_type_num == LOCK_TYPE_DLM || lock_type_num == LOCK_TYPE_SANLOCK ||
lock_type_num == LOCK_TYPE_IDM) {
if (lock_type_num == LOCK_TYPE_DLM || lock_type_num == LOCK_TYPE_SANLOCK) {
if (changing && !_lockd_all_lvs(cmd, vg)) {
log_error("Cannot change VG %s with active LVs", vg->name);
return 0;
@@ -1264,9 +1038,6 @@ int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg,
case LOCK_TYPE_SANLOCK:
/* returning an error will prevent vg_remove() */
return _free_vg_sanlock(cmd, vg);
case LOCK_TYPE_IDM:
/* returning an error will prevent vg_remove() */
return _busy_vg_idm(cmd, vg);
default:
log_error("Unknown lock_type.");
return 0;
@@ -1285,9 +1056,6 @@ void lockd_free_vg_final(struct cmd_context *cmd, struct volume_group *vg)
case LOCK_TYPE_DLM:
_free_vg_dlm(cmd, vg);
break;
case LOCK_TYPE_IDM:
_free_vg_idm(cmd, vg);
break;
default:
log_error("Unknown lock_type.");
}
@@ -1319,7 +1087,6 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int start_i
int host_id = 0;
int result;
int ret;
struct lvmlockd_pvs lock_pvs;
memset(uuid, 0, sizeof(uuid));
@@ -1355,15 +1122,7 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int start_i
host_id = find_config_tree_int(cmd, local_host_id_CFG, NULL);
}
/*
* Create the VG's PV list when start the VG, the PV list
* is passed to lvmlockd, and the the PVs path will be used
* to send SCSI commands for idm locking scheme.
*/
if (!strcmp(vg->lock_type, "idm")) {
_lockd_retrive_vg_pv_list(vg, &lock_pvs);
reply = _lockd_send_with_pvs("start_vg",
&lock_pvs,
reply = _lockd_send("start_vg",
"pid = " FMTd64, (int64_t) getpid(),
"vg_name = %s", vg->name,
"vg_lock_type = %s", vg->lock_type,
@@ -1373,20 +1132,6 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int start_i
"host_id = " FMTd64, (int64_t) host_id,
"opts = %s", start_init ? "start_init" : "none",
NULL);
_lockd_free_pv_list(&lock_pvs);
} else {
reply = _lockd_send_with_pvs("start_vg",
NULL,
"pid = " FMTd64, (int64_t) getpid(),
"vg_name = %s", vg->name,
"vg_lock_type = %s", vg->lock_type,
"vg_lock_args = %s", vg->lock_args ?: "none",
"vg_uuid = %s", uuid[0] ? uuid : "none",
"version = " FMTd64, (int64_t) vg->seqno,
"host_id = " FMTd64, (int64_t) host_id,
"opts = %s", start_init ? "start_init" : "none",
NULL);
}
if (!_lockd_result(reply, &result, &lockd_flags)) {
ret = 0;
@@ -1541,7 +1286,7 @@ int lockd_start_wait(struct cmd_context *cmd)
* can provide in the lock-gl call.
*
* lockd_gl() and lockd_gl_create() differ in the specific cases where
* ENOLS (no lockspace found) is overridden. In the vgcreate case, the
* ENOLS (no lockspace found) is overriden. In the vgcreate case, the
* override cases are related to sanlock bootstrap, and the lock_type of
* the vg being created is needed.
*
@@ -1614,7 +1359,7 @@ int lockd_global_create(struct cmd_context *cmd, const char *def_mode, const cha
req:
if (!_lockd_request(cmd, "lock_gl",
NULL, vg_lock_type, NULL, NULL, NULL, NULL, mode, NULL,
NULL, &result, &lockd_flags)) {
&result, &lockd_flags)) {
/* No result from lvmlockd, it is probably not running. */
log_error("Global lock failed: check that lvmlockd is running.");
return 0;
@@ -1850,7 +1595,7 @@ int lockd_global(struct cmd_context *cmd, const char *def_mode)
if (!_lockd_request(cmd, "lock_gl",
NULL, NULL, NULL, NULL, NULL, NULL, mode, opts,
NULL, &result, &lockd_flags)) {
&result, &lockd_flags)) {
/* No result from lvmlockd, it is probably not running. */
/* We don't care if an unlock fails. */
@@ -2118,7 +1863,7 @@ int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode,
if (!_lockd_request(cmd, "lock_vg",
vg_name, NULL, NULL, NULL, NULL, NULL, mode, NULL,
NULL, &result, &lockd_flags)) {
&result, &lockd_flags)) {
/*
* No result from lvmlockd, it is probably not running.
* Decide if it is ok to continue without a lock in
@@ -2378,7 +2123,6 @@ int lockd_lv_name(struct cmd_context *cmd, struct volume_group *vg,
uint32_t lockd_flags;
int refreshed = 0;
int result;
struct lvmlockd_pvs lock_pvs;
/*
* Verify that when --readonly is used, no LVs should be activated or used.
@@ -2444,28 +2188,13 @@ int lockd_lv_name(struct cmd_context *cmd, struct volume_group *vg,
retry:
log_debug("lockd LV %s/%s mode %s uuid %s", vg->name, lv_name, mode, lv_uuid);
/* Pass PV list for IDM lock type */
if (!strcmp(vg->lock_type, "idm")) {
_lockd_retrive_lv_pv_list(vg, lv_name, &lock_pvs);
if (!_lockd_request(cmd, "lock_lv",
vg->name, vg->lock_type, vg->lock_args,
lv_name, lv_uuid, lock_args, mode, opts,
&lock_pvs, &result, &lockd_flags)) {
_lockd_free_pv_list(&lock_pvs);
/* No result from lvmlockd, it is probably not running. */
log_error("Locking failed for LV %s/%s", vg->name, lv_name);
return 0;
}
_lockd_free_pv_list(&lock_pvs);
} else {
if (!_lockd_request(cmd, "lock_lv",
vg->name, vg->lock_type, vg->lock_args,
lv_name, lv_uuid, lock_args, mode, opts,
NULL, &result, &lockd_flags)) {
/* No result from lvmlockd, it is probably not running. */
log_error("Locking failed for LV %s/%s", vg->name, lv_name);
return 0;
}
if (!_lockd_request(cmd, "lock_lv",
vg->name, vg->lock_type, vg->lock_args,
lv_name, lv_uuid, lock_args, mode, opts,
&result, &lockd_flags)) {
/* No result from lvmlockd, it is probably not running. */
log_error("Locking failed for LV %s/%s", vg->name, lv_name);
return 0;
}
/* The lv was not active/locked. */
@@ -2947,7 +2676,6 @@ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, struct logic
return 1;
case LOCK_TYPE_SANLOCK:
case LOCK_TYPE_DLM:
case LOCK_TYPE_IDM:
break;
default:
log_error("lockd_init_lv: unknown lock_type.");
@@ -3090,8 +2818,6 @@ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, struct logic
lv->lock_args = "pending";
else if (!strcmp(vg->lock_type, "dlm"))
lv->lock_args = "dlm";
else if (!strcmp(vg->lock_type, "idm"))
lv->lock_args = "idm";
return 1;
}
@@ -3107,7 +2833,6 @@ int lockd_free_lv(struct cmd_context *cmd, struct volume_group *vg,
return 1;
case LOCK_TYPE_DLM:
case LOCK_TYPE_SANLOCK:
case LOCK_TYPE_IDM:
if (!lock_args)
return 1;
return _free_lv(cmd, vg, lv_name, lv_id, lock_args);
@@ -3279,10 +3004,6 @@ const char *lockd_running_lock_type(struct cmd_context *cmd, int *found_multiple
log_debug("lvmlockd found dlm");
lock_type = "dlm";
break;
case LOCK_TYPE_IDM:
log_debug("lvmlockd found idm");
lock_type = "idm";
break;
default:
log_error("Failed to find a running lock manager.");
break;

View File

@@ -472,7 +472,7 @@ static void _set_time_prefix(char *prefix, int buflen)
if (!len)
goto fail;
len = dm_snprintf(prefix + len, buflen - len, ".%06ld ", ts.tv_nsec/1000);
len = dm_snprintf(prefix + len, buflen - len, ".%ld ", ts.tv_nsec/1000);
if (len < 0)
goto fail;
@@ -576,7 +576,7 @@ static void _vprint_log(int level, const char *file, int line, int dm_errno_or_c
if (log_once) {
if (!_duplicated)
_duplicated = dm_hash_create(117);
_duplicated = dm_hash_create(128);
if (_duplicated) {
if (dm_hash_lookup(_duplicated, message))
level = _LOG_NOTICE;

View File

@@ -247,13 +247,6 @@ static int _process_poll_init(const struct cmd_context *cmd, const char *poll_ty
goto out_req;
}
if (parms->devicesfile[0] &&
!(daemon_request_extend(req, LVMPD_PARM_DEVICESFILE " = %s",
parms->devicesfile, NULL))) {
log_error("Failed to create %s request." , poll_type);
goto out_req;
}
rep = daemon_send(_lvmpolld, req);
if (rep.error) {

View File

@@ -60,7 +60,6 @@ struct daemon_parms {
const char *progress_title;
uint64_t lv_type;
struct poll_functions *poll_fns;
char devicesfile[128];
};
int poll_daemon(struct cmd_context *cmd, unsigned background,

Some files were not shown because too many files have changed in this diff Show More