mirror of
git://sourceware.org/git/lvm2.git
synced 2025-12-25 20:23:49 +03:00
Compare commits
98 Commits
dm_v1_02_0
...
dm_v1_02_1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae6918742e | ||
|
|
863484bb65 | ||
|
|
1cd7ebce4c | ||
|
|
eef8c7862e | ||
|
|
b52375d446 | ||
|
|
6e2babc2ce | ||
|
|
08e253bed1 | ||
|
|
c6661477a2 | ||
|
|
415cfd99a0 | ||
|
|
8c2e37381a | ||
|
|
45df79feba | ||
|
|
5824f992b7 | ||
|
|
b0b60fafd5 | ||
|
|
8d98b02ba2 | ||
|
|
a93fe79bc4 | ||
|
|
4aebd7be37 | ||
|
|
3170a5db32 | ||
|
|
3605b9eef6 | ||
|
|
a945f1fde2 | ||
|
|
461a997b5b | ||
|
|
a80afd7b4e | ||
|
|
aad2b51d85 | ||
|
|
36a9a81ff1 | ||
|
|
42c88546ae | ||
|
|
0f0e86ef9b | ||
|
|
98efd9a857 | ||
|
|
a0c27d95b7 | ||
|
|
984651d99d | ||
|
|
c6f7370b30 | ||
|
|
3e4b8e8985 | ||
|
|
73f08b98d2 | ||
|
|
8607a74206 | ||
|
|
8339f3ceb3 | ||
|
|
c0c9f3cc19 | ||
|
|
81f4813c29 | ||
|
|
94f57745b9 | ||
|
|
54fb2ebbe0 | ||
|
|
02d122b65b | ||
|
|
df0a5561a1 | ||
|
|
f7c55da7d0 | ||
|
|
b385f701ce | ||
|
|
05dd42f443 | ||
|
|
36d816d5cb | ||
|
|
92a6746e70 | ||
|
|
1728848a39 | ||
|
|
f9eb4e7487 | ||
|
|
d0b9f33aeb | ||
|
|
718583b241 | ||
|
|
6737127e9a | ||
|
|
19a7b4479b | ||
|
|
c340647502 | ||
|
|
0f987d2982 | ||
|
|
52bcaed169 | ||
|
|
177bd565ac | ||
|
|
c801c32fc5 | ||
|
|
d090cf3058 | ||
|
|
1e4b82cc94 | ||
|
|
3426f31184 | ||
|
|
b4fb7af1df | ||
|
|
b36647598b | ||
|
|
fd6b94f20e | ||
|
|
296dc0ed8a | ||
|
|
4f869e14d6 | ||
|
|
5704270e9d | ||
|
|
505b381e85 | ||
|
|
da6cb15393 | ||
|
|
16843f6cc8 | ||
|
|
64f3ad1fd4 | ||
|
|
ff4c4f99b3 | ||
|
|
f5d2e09569 | ||
|
|
f2bdbe0d4d | ||
|
|
c51a13caa6 | ||
|
|
7840c78a23 | ||
|
|
c706f3246b | ||
|
|
608eedf88d | ||
|
|
a564ca82be | ||
|
|
c868b1fee2 | ||
|
|
22374f718f | ||
|
|
abe3cfcf41 | ||
|
|
59db4b50cd | ||
|
|
bdae38765d | ||
|
|
66d3ceeb61 | ||
|
|
445dd17db3 | ||
|
|
cff78a2577 | ||
|
|
6a09e64195 | ||
|
|
22eabe5eab | ||
|
|
b69ba36c2d | ||
|
|
5240aad22b | ||
|
|
2897eb3cb3 | ||
|
|
d3f2f00c25 | ||
|
|
bacfb913a0 | ||
|
|
c99d0236a0 | ||
|
|
aac2b655f7 | ||
|
|
126c41e73a | ||
|
|
359ee54f0d | ||
|
|
28ab560907 | ||
|
|
ead252fee4 | ||
|
|
abf67914c4 |
@@ -38,6 +38,7 @@ ifeq ($(MAKECMDGOALS),distclean)
|
||||
lib/snapshot \
|
||||
po \
|
||||
test/mm test/device test/format1 test/regex test/filters
|
||||
DISTCLEAN_TARGETS += lib/misc/configure.h
|
||||
endif
|
||||
|
||||
include make.tmpl
|
||||
|
||||
84
WHATS_NEW
84
WHATS_NEW
@@ -1,5 +1,85 @@
|
||||
Version 2.02.06 -
|
||||
=================================
|
||||
Version 2.02.10 -
|
||||
==================================
|
||||
Extend _check_contiguous() to detect single-area LVs.
|
||||
Include mirror log (untested) in _for_each_pv() processing.
|
||||
Use MIRROR_LOG_SIZE constant.
|
||||
Remove struct seg_pvs from _for_each_pv() to generalise.
|
||||
Avoid adding duplicates to list of parallel PVs to avoid.
|
||||
Fix several incorrect comparisons in parallel area avoidance code.
|
||||
Fix segment lengths when flattening existing parallel areas.
|
||||
Log existing parallel areas prior to allocation.
|
||||
Fix mirror log creation when activation disabled.
|
||||
Don't attempt automatic recovery without proper locking.
|
||||
When using local file locking, skip clustered VGs.
|
||||
Add fallback_to_clustered_locking and fallback_to_local_locking parameters.
|
||||
lvm.static uses built-in cluster locking instead of external locking.
|
||||
Don't attempt to load shared libraries if built statically.
|
||||
Change default locking_lib to liblvm2clusterlock.so.
|
||||
Add skip_dev_dir() to process command line VGs.
|
||||
Stop clvmd complaining about nodes that have left the cluster.
|
||||
Move lvm_snprintf(), split_words() and split_dm_name() into libdevmapper.
|
||||
Add lvconvert man page.
|
||||
Add mirror options to man pages.
|
||||
Prevent mirror renames.
|
||||
Move CMDLIB code into separate file and record whether static build.
|
||||
|
||||
Version 2.02.09 - 17th August 2006
|
||||
==================================
|
||||
Fix PE_ALIGN for pagesize over 32KB.
|
||||
Separate out LVM1_PE_ALIGN and pe_align().
|
||||
Add lvm_getpagesize wrapper.
|
||||
Add --maxphysicalvolumes to vgchange.
|
||||
|
||||
Version 2.02.08 - 15th August 2006
|
||||
==================================
|
||||
Add checks for duplicate LV name, lvid and PV id before writing metadata.
|
||||
Report all sanity check failures, not just the first.
|
||||
Fix missing lockfs on first snapshot creation.
|
||||
Add unreliable --trustcache option to reporting commands.
|
||||
Fix locking for mimage removal.
|
||||
Fix clvmd_init_rhel4 'status' exit code.
|
||||
|
||||
Version 2.02.07 - 17th July 2006
|
||||
================================
|
||||
Fix activation logic in lvchange --persistent.
|
||||
Don't ignore persistent minor numbers when activating.
|
||||
Use RTLD_GLOBAL when loading shared libraries.
|
||||
Add some forgotten memlock checks to _vg_read to protect against full scans.
|
||||
Add mutex to dmeventd_mirror to avoid concurrent execution.
|
||||
Fix vgreduce --removemissing to return success if VG is already consistent.
|
||||
Fix return code if VG specified on command line is not found.
|
||||
Fix PV tools to include orphaned PVs in default output again.
|
||||
Fixed unaligned access when using clvm.
|
||||
Fix an extra dev_close in a label_read error path.
|
||||
Append patches to commit emails.
|
||||
Fix target_register_events args.
|
||||
Prevent snapshots of mirrors.
|
||||
Add DISTCLEAN_TARGETS to make template for configure.h.
|
||||
More fixes to error paths.
|
||||
Fix lvcreate corelog validation.
|
||||
Add --config for overriding most config file settings from cmdline.
|
||||
Quote arguments when printing command line.
|
||||
Remove linefeed from 'initialising logging' message.
|
||||
Add 'Completed' debug message.
|
||||
Don't attempt library exit after reloading config files.
|
||||
Always compile with libdevmapper, even if device-mapper is disabled.
|
||||
|
||||
Version 2.02.06 - 12th May 2006
|
||||
===============================
|
||||
Propagate --monitor around cluster.
|
||||
Add --monitor to vgcreate and lvcreate to control dmeventd registration.
|
||||
Filter LCK_NONBLOCK in clvmd lock_vg.
|
||||
Add --nosync to lvcreate with LV flag NOTSYNCED.
|
||||
Use mirror's uuid for a core log.
|
||||
Add mirror log fault-handling policy.
|
||||
Improve mirror warning messages and tidy dmeventd syslog output.
|
||||
Propagate nosync flag around cluster.
|
||||
Allow vgreduce to handle mirror log failures.
|
||||
Add --corelog to lvcreate and lvconvert.
|
||||
Create a log header for replacement in-sync mirror log.
|
||||
Use set_lv() and dev_set() to wipe sections of devices.
|
||||
Add mirror_in_sync() flag to avoid unnecessary resync on activation.
|
||||
Add mirror_library description to example.conf.
|
||||
Fix uuid_from_num() buffer overrun.
|
||||
Make SIZE_SHORT the default for display_size().
|
||||
Fix some memory leaks in error paths found by coverity.
|
||||
|
||||
27
WHATS_NEW_DM
27
WHATS_NEW_DM
@@ -1,3 +1,30 @@
|
||||
Version 1.02.10 - 19 Sep 2006
|
||||
=============================
|
||||
Add dm_snprintf(), dm_split_words() and dm_split_lvm_name() to libdevmapper.
|
||||
Reorder mm bounds_check code to reduce window for a dmeventd race.
|
||||
|
||||
Version 1.02.09 - 15 Aug 2006
|
||||
=============================
|
||||
Add --table argument to dmsetup for a one-line table.
|
||||
Abort if errors are found during cmdline option processing.
|
||||
Add lockfs indicator to debug output.
|
||||
|
||||
Version 1.02.08 - 17 July 2006
|
||||
==============================
|
||||
Append full patch to check in emails.
|
||||
Avoid duplicate dmeventd subdir with 'make distclean'.
|
||||
Update dmsetup man page.
|
||||
Add --force to dmsetup remove* to load error target.
|
||||
dmsetup remove_all also performs mknodes.
|
||||
Don't suppress identical table reloads if permission changes.
|
||||
Fix corelog segment line.
|
||||
Suppress some compiler warnings.
|
||||
|
||||
Version 1.02.07 - 11 May 2006
|
||||
=============================
|
||||
Add DM_CORELOG flag to dm_tree_node_add_mirror_target().
|
||||
Avoid a dmeventd compiler warning.
|
||||
|
||||
Version 1.02.06 - 10 May 2006
|
||||
=============================
|
||||
Move DEFS into configure.h.
|
||||
|
||||
49
configure
vendored
49
configure
vendored
@@ -7534,14 +7534,6 @@ fi;
|
||||
echo "$as_me:$LINENO: result: $CMDLIB" >&5
|
||||
echo "${ECHO_T}$CMDLIB" >&6
|
||||
|
||||
if test x$CMDLIB = xyes; then
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define CMDLIB 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
echo "$as_me:$LINENO: checking whether to build fsadm" >&5
|
||||
echo $ECHO_N "checking whether to build fsadm... $ECHO_C" >&6
|
||||
@@ -10699,7 +10691,6 @@ done
|
||||
|
||||
fi
|
||||
|
||||
if test x$DEVMAPPER = xyes; then
|
||||
|
||||
for ac_header in libdevmapper.h
|
||||
do
|
||||
@@ -10854,7 +10845,6 @@ fi
|
||||
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
if test x$HAVE_SELINUX = xyes; then
|
||||
|
||||
@@ -11053,45 +11043,6 @@ else
|
||||
echo "${ECHO_T}no" >&6
|
||||
fi
|
||||
|
||||
# Extract the first word of "ifconfig", so it can be a program name with args.
|
||||
set dummy ifconfig; ac_word=$2
|
||||
echo "$as_me:$LINENO: checking for $ac_word" >&5
|
||||
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
|
||||
if test "${ac_cv_path_MODPROBE_CMD+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
case $MODPROBE_CMD in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_MODPROBE_CMD="$MODPROBE_CMD" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_MODPROBE_CMD="$as_dir/$ac_word$ac_exec_ext"
|
||||
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
MODPROBE_CMD=$ac_cv_path_MODPROBE_CMD
|
||||
|
||||
if test -n "$MODPROBE_CMD"; then
|
||||
echo "$as_me:$LINENO: result: $MODPROBE_CMD" >&5
|
||||
echo "${ECHO_T}$MODPROBE_CMD" >&6
|
||||
else
|
||||
echo "$as_me:$LINENO: result: no" >&5
|
||||
echo "${ECHO_T}no" >&6
|
||||
fi
|
||||
|
||||
|
||||
if test x$MODPROBE_CMD != x; then
|
||||
|
||||
|
||||
@@ -351,10 +351,6 @@ AC_ARG_ENABLE(cmdlib, [ --enable-cmdlib Build shared command library],
|
||||
CMDLIB=$enableval, CMDLIB=no)
|
||||
AC_MSG_RESULT($CMDLIB)
|
||||
|
||||
if test x$CMDLIB = xyes; then
|
||||
AC_DEFINE([CMDLIB], 1, [Define to 1 to build the shared command library.])
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Enable fsadm
|
||||
AC_MSG_CHECKING(whether to build fsadm)
|
||||
@@ -538,9 +534,7 @@ if test x$INTL = xyes; then
|
||||
AC_CHECK_HEADERS(libintl.h,,AC_MSG_ERROR(bailing out))
|
||||
fi
|
||||
|
||||
if test x$DEVMAPPER = xyes; then
|
||||
AC_CHECK_HEADERS(libdevmapper.h,,AC_MSG_ERROR(bailing out))
|
||||
fi
|
||||
AC_CHECK_HEADERS(libdevmapper.h,,AC_MSG_ERROR(bailing out))
|
||||
|
||||
if test x$HAVE_SELINUX = xyes; then
|
||||
AC_CHECK_HEADERS(selinux/selinux.h,,AC_MSG_ERROR(bailing out))
|
||||
|
||||
@@ -59,9 +59,7 @@ ifeq ("@DMEVENTD@", "yes")
|
||||
LVMLIBS += -ldevmapper-event
|
||||
endif
|
||||
|
||||
ifeq ("@DEVMAPPER@", "yes")
|
||||
LVMLIBS += -ldevmapper
|
||||
endif
|
||||
LVMLIBS += -ldevmapper
|
||||
|
||||
DEFS += -D_REENTRANT
|
||||
CFLAGS += -fno-strict-aliasing
|
||||
|
||||
@@ -137,7 +137,7 @@ static int _cluster_send_message(void *buf, int msglen, char *csid, const char *
|
||||
|
||||
if (cman_send_data(c_handle, buf, msglen, 0, CLUSTER_PORT_CLVMD, nodeid) <= 0)
|
||||
{
|
||||
log_error(errtext);
|
||||
log_error(errtext);
|
||||
}
|
||||
return msglen;
|
||||
}
|
||||
@@ -152,16 +152,18 @@ static void _get_our_csid(char *csid)
|
||||
|
||||
/* Call a callback routine for each node is that known (down means not running a clvmd) */
|
||||
static int _cluster_do_node_callback(struct local_client *client,
|
||||
void (*callback) (struct local_client *, char *,
|
||||
int))
|
||||
void (*callback) (struct local_client *, char *,
|
||||
int))
|
||||
{
|
||||
int i;
|
||||
int somedown = 0;
|
||||
|
||||
for (i = 0; i < _get_num_nodes(); i++) {
|
||||
callback(client, (char *)&nodes[i].cn_nodeid, node_updown[nodes[i].cn_nodeid]);
|
||||
if (!node_updown[nodes[i].cn_nodeid])
|
||||
somedown = -1;
|
||||
if (nodes[i].cn_member) {
|
||||
callback(client, (char *)&nodes[i].cn_nodeid, node_updown[nodes[i].cn_nodeid]);
|
||||
if (!node_updown[nodes[i].cn_nodeid])
|
||||
somedown = -1;
|
||||
}
|
||||
}
|
||||
return somedown;
|
||||
}
|
||||
@@ -205,7 +207,7 @@ static void event_callback(cman_handle_t handle, void *private, int reason, int
|
||||
|
||||
static struct local_client *cman_client;
|
||||
static int _cluster_fd_callback(struct local_client *fd, char *buf, int len, char *csid,
|
||||
struct local_client **new_client)
|
||||
struct local_client **new_client)
|
||||
{
|
||||
|
||||
/* Save this for data_callback */
|
||||
@@ -243,7 +245,7 @@ static void _add_up_node(char *csid)
|
||||
max_updown_nodes);
|
||||
} else {
|
||||
log_error
|
||||
("Realloc failed. Node status for clvmd will be wrong. quitting\n");
|
||||
("Realloc failed. Node status for clvmd will be wrong. quitting\n");
|
||||
exit(999);
|
||||
}
|
||||
}
|
||||
@@ -297,36 +299,37 @@ static void get_members()
|
||||
return;
|
||||
}
|
||||
|
||||
/* Not enough room for new nodes list ? */
|
||||
if (num_nodes > count_nodes && nodes) {
|
||||
free(nodes);
|
||||
nodes = NULL;
|
||||
}
|
||||
/* Not enough room for new nodes list ? */
|
||||
if (num_nodes > count_nodes && nodes) {
|
||||
free(nodes);
|
||||
nodes = NULL;
|
||||
}
|
||||
|
||||
if (nodes == NULL) {
|
||||
count_nodes = num_nodes + 10; /* Overallocate a little */
|
||||
if (nodes == NULL) {
|
||||
count_nodes = num_nodes + 10; /* Overallocate a little */
|
||||
nodes = malloc(count_nodes * sizeof(struct cman_node));
|
||||
if (!nodes) {
|
||||
log_error("Unable to allocate nodes array\n");
|
||||
exit(5);
|
||||
}
|
||||
if (!nodes) {
|
||||
log_error("Unable to allocate nodes array\n");
|
||||
exit(5);
|
||||
}
|
||||
}
|
||||
|
||||
status = cman_get_nodes(c_handle, count_nodes, &retnodes, nodes);
|
||||
if (status < 0) {
|
||||
log_error("Unable to get node details");
|
||||
exit(6);
|
||||
}
|
||||
|
||||
if (node_updown == NULL) {
|
||||
node_updown =
|
||||
(int *) malloc(sizeof(int) *
|
||||
max(num_nodes, max_updown_nodes));
|
||||
memset(node_updown, 0,
|
||||
sizeof(int) * max(num_nodes, max_updown_nodes));
|
||||
}
|
||||
log_error("Unable to get node details");
|
||||
exit(6);
|
||||
}
|
||||
|
||||
if (node_updown == NULL) {
|
||||
node_updown =
|
||||
(int *) malloc(sizeof(int) *
|
||||
max(num_nodes, max_updown_nodes));
|
||||
memset(node_updown, 0,
|
||||
sizeof(int) * max(num_nodes, max_updown_nodes));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Convert a node name to a CSID */
|
||||
static int _csid_from_name(char *csid, char *name)
|
||||
{
|
||||
|
||||
@@ -180,7 +180,7 @@ static int lock_vg(struct local_client *client)
|
||||
}
|
||||
else {
|
||||
|
||||
status = sync_lock(lockname, (int)lock_cmd, (int)lock_flags, &lkid);
|
||||
status = sync_lock(lockname, (int)lock_cmd, (lock_flags & LCK_NONBLOCK) ? LKF_NOQUEUE : 0, &lkid);
|
||||
if (status)
|
||||
status = errno;
|
||||
else
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "log.h"
|
||||
#include "activate.h"
|
||||
#include "locking.h"
|
||||
#include "defaults.h"
|
||||
|
||||
static struct cmd_context *cmd = NULL;
|
||||
static struct dm_hash_table *lv_hash = NULL;
|
||||
@@ -306,6 +307,12 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
|
||||
if (lock_flags & LCK_PARTIAL_MODE)
|
||||
init_partial(1);
|
||||
|
||||
if (lock_flags & LCK_MIRROR_NOSYNC_MODE)
|
||||
init_mirror_in_sync(1);
|
||||
|
||||
if (!(lock_flags & LCK_DMEVENTD_REGISTER_MODE))
|
||||
init_dmeventd_register(0);
|
||||
|
||||
switch (command) {
|
||||
case LCK_LV_EXCLUSIVE:
|
||||
status = do_activate_lv(resource, lock_flags, LKM_EXMODE);
|
||||
@@ -337,6 +344,12 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
|
||||
if (lock_flags & LCK_PARTIAL_MODE)
|
||||
init_partial(0);
|
||||
|
||||
if (lock_flags & LCK_MIRROR_NOSYNC_MODE)
|
||||
init_mirror_in_sync(0);
|
||||
|
||||
if (!(lock_flags & LCK_DMEVENTD_REGISTER_MODE))
|
||||
init_dmeventd_register(DEFAULT_DMEVENTD_MONITOR);
|
||||
|
||||
/* clean the pool for another command */
|
||||
dm_pool_empty(cmd->mem);
|
||||
|
||||
@@ -497,7 +510,7 @@ static void check_config()
|
||||
{
|
||||
int locking_type;
|
||||
|
||||
locking_type = find_config_int(cmd->cft->root, "global/locking_type", 1);
|
||||
locking_type = find_config_tree_int(cmd, "global/locking_type", 1);
|
||||
|
||||
if (locking_type == 3) /* compiled-in cluster support */
|
||||
return;
|
||||
@@ -505,7 +518,7 @@ static void check_config()
|
||||
if (locking_type == 2) { /* External library, check name */
|
||||
const char *libname;
|
||||
|
||||
libname = find_config_str(cmd->cft->root, "global/locking_library",
|
||||
libname = find_config_tree_str(cmd, "global/locking_library",
|
||||
"");
|
||||
if (strstr(libname, "liblvm2clusterlock.so"))
|
||||
return;
|
||||
@@ -526,7 +539,7 @@ void init_lvhash()
|
||||
/* Called to initialise the LVM context of the daemon */
|
||||
int init_lvm(int using_gulm)
|
||||
{
|
||||
if (!(cmd = create_toolcontext(NULL))) {
|
||||
if (!(cmd = create_toolcontext(NULL, 0))) {
|
||||
log_error("Failed to allocate command context");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1213,14 +1213,14 @@ static void sig_alarm(int signum)
|
||||
/* Init thread signal handling. */
|
||||
static void init_thread_signals(void)
|
||||
{
|
||||
sigset_t sigset;
|
||||
sigset_t my_sigset;
|
||||
struct sigaction act;
|
||||
|
||||
memset(&act, 0, sizeof(act));
|
||||
act.sa_handler = sig_alarm;
|
||||
sigaction(SIGALRM, &act, NULL);
|
||||
sigfillset(&sigset);
|
||||
pthread_sigmask(SIG_BLOCK, &sigset, NULL);
|
||||
sigfillset(&my_sigset);
|
||||
pthread_sigmask(SIG_BLOCK, &my_sigset, NULL);
|
||||
}
|
||||
|
||||
static int daemonize(void)
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#define ME_INSYNC 1
|
||||
#define ME_FAILURE 2
|
||||
|
||||
static pthread_mutex_t _lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* FIXME: We may need to lock around operations to these */
|
||||
static int register_count = 0;
|
||||
static struct dm_pool *mem_pool = NULL;
|
||||
@@ -46,7 +48,7 @@ static int _get_mirror_event(char *params)
|
||||
char *p;
|
||||
int log_argc, num_devs, num_failures=0;
|
||||
|
||||
if (max_args <= split_words(params, max_args, args)) {
|
||||
if (max_args <= dm_split_words(params, max_args, 0, args)) {
|
||||
syslog(LOG_ERR, "Unable to split mirror parameters: Arg list too long");
|
||||
return -E2BIG;
|
||||
}
|
||||
@@ -99,10 +101,13 @@ static int _get_mirror_event(char *params)
|
||||
return rtn;
|
||||
}
|
||||
|
||||
static void _temporary_log_fn(int level, const char *file, int line, const char *format)
|
||||
static void _temporary_log_fn(int level, const char *file,
|
||||
int line, const char *format)
|
||||
{
|
||||
return;
|
||||
syslog(LOG_DEBUG, "%s", format);
|
||||
if (!strncmp(format, "WARNING: ", 9) && (level < 5))
|
||||
syslog(LOG_CRIT, "%s", format);
|
||||
else
|
||||
syslog(LOG_DEBUG, "%s", format);
|
||||
}
|
||||
|
||||
static int _remove_failed_devices(const char *device)
|
||||
@@ -116,7 +121,7 @@ static int _remove_failed_devices(const char *device)
|
||||
if (strlen(device) > 200)
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
if (!split_dm_name(mem_pool, device, &vg, &lv, &layer)) {
|
||||
if (!dm_split_lvm_name(mem_pool, device, &vg, &lv, &layer)) {
|
||||
syslog(LOG_ERR, "Unable to determine VG name from %s",
|
||||
device);
|
||||
return -ENOMEM;
|
||||
@@ -147,6 +152,10 @@ void process_event(const char *device, enum dm_event_type event)
|
||||
char *target_type = NULL;
|
||||
char *params;
|
||||
|
||||
if (pthread_mutex_trylock(&_lock)) {
|
||||
syslog(LOG_NOTICE, "Another thread is handling an event. Waiting...");
|
||||
pthread_mutex_lock(&_lock);
|
||||
}
|
||||
/* FIXME Move inside libdevmapper */
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_STATUS))) {
|
||||
syslog(LOG_ERR, "Unable to create dm_task.\n");
|
||||
@@ -201,11 +210,12 @@ void process_event(const char *device, enum dm_event_type event)
|
||||
fail:
|
||||
if (dmt)
|
||||
dm_task_destroy(dmt);
|
||||
pthread_mutex_unlock(&_lock);
|
||||
}
|
||||
|
||||
int register_device(const char *device)
|
||||
{
|
||||
syslog(LOG_INFO, "Monitoring %s for events\n", device);
|
||||
syslog(LOG_INFO, "Monitoring mirror device, %s for events\n", device);
|
||||
|
||||
/*
|
||||
* Need some space for allocations. 1024 should be more
|
||||
@@ -224,8 +234,6 @@ int register_device(const char *device)
|
||||
|
||||
int unregister_device(const char *device)
|
||||
{
|
||||
syslog(LOG_INFO, "Stopped monitoring %s for events\n", device);
|
||||
|
||||
if (!(--register_count)) {
|
||||
dm_pool_destroy(mem_pool);
|
||||
mem_pool = NULL;
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#define ME_INSYNC 1
|
||||
#define ME_FAILURE 2
|
||||
|
||||
static pthread_mutex_t _lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* FIXME: We may need to lock around operations to these */
|
||||
static int register_count = 0;
|
||||
static struct dm_pool *mem_pool = NULL;
|
||||
@@ -46,7 +48,7 @@ static int _get_mirror_event(char *params)
|
||||
char *p;
|
||||
int log_argc, num_devs, num_failures=0;
|
||||
|
||||
if (max_args <= split_words(params, max_args, args)) {
|
||||
if (max_args <= dm_split_words(params, max_args, 0, args)) {
|
||||
syslog(LOG_ERR, "Unable to split mirror parameters: Arg list too long");
|
||||
return -E2BIG;
|
||||
}
|
||||
@@ -99,10 +101,13 @@ static int _get_mirror_event(char *params)
|
||||
return rtn;
|
||||
}
|
||||
|
||||
static void _temporary_log_fn(int level, const char *file, int line, const char *format)
|
||||
static void _temporary_log_fn(int level, const char *file,
|
||||
int line, const char *format)
|
||||
{
|
||||
return;
|
||||
syslog(LOG_DEBUG, "%s", format);
|
||||
if (!strncmp(format, "WARNING: ", 9) && (level < 5))
|
||||
syslog(LOG_CRIT, "%s", format);
|
||||
else
|
||||
syslog(LOG_DEBUG, "%s", format);
|
||||
}
|
||||
|
||||
static int _remove_failed_devices(const char *device)
|
||||
@@ -116,7 +121,7 @@ static int _remove_failed_devices(const char *device)
|
||||
if (strlen(device) > 200)
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
if (!split_dm_name(mem_pool, device, &vg, &lv, &layer)) {
|
||||
if (!dm_split_lvm_name(mem_pool, device, &vg, &lv, &layer)) {
|
||||
syslog(LOG_ERR, "Unable to determine VG name from %s",
|
||||
device);
|
||||
return -ENOMEM;
|
||||
@@ -147,6 +152,10 @@ void process_event(const char *device, enum dm_event_type event)
|
||||
char *target_type = NULL;
|
||||
char *params;
|
||||
|
||||
if (pthread_mutex_trylock(&_lock)) {
|
||||
syslog(LOG_NOTICE, "Another thread is handling an event. Waiting...");
|
||||
pthread_mutex_lock(&_lock);
|
||||
}
|
||||
/* FIXME Move inside libdevmapper */
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_STATUS))) {
|
||||
syslog(LOG_ERR, "Unable to create dm_task.\n");
|
||||
@@ -201,11 +210,12 @@ void process_event(const char *device, enum dm_event_type event)
|
||||
fail:
|
||||
if (dmt)
|
||||
dm_task_destroy(dmt);
|
||||
pthread_mutex_unlock(&_lock);
|
||||
}
|
||||
|
||||
int register_device(const char *device)
|
||||
{
|
||||
syslog(LOG_INFO, "Monitoring %s for events\n", device);
|
||||
syslog(LOG_INFO, "Monitoring mirror device, %s for events\n", device);
|
||||
|
||||
/*
|
||||
* Need some space for allocations. 1024 should be more
|
||||
@@ -224,8 +234,6 @@ int register_device(const char *device)
|
||||
|
||||
int unregister_device(const char *device)
|
||||
{
|
||||
syslog(LOG_INFO, "Stopped monitoring %s for events\n", device);
|
||||
|
||||
if (!(--register_count)) {
|
||||
dm_pool_destroy(mem_pool);
|
||||
mem_pool = NULL;
|
||||
|
||||
@@ -207,11 +207,26 @@ global {
|
||||
# Location of proc filesystem
|
||||
proc = "/proc"
|
||||
|
||||
# Type of locking to use. Defaults to file-based locking (1).
|
||||
# Type of locking to use. Defaults to local file-based locking (1).
|
||||
# Turn locking off by setting to 0 (dangerous: risks metadata corruption
|
||||
# if LVM2 commands get run concurrently).
|
||||
# Type 2 uses the external shared library locking_library.
|
||||
# Type 3 uses built-in clustered locking.
|
||||
locking_type = 1
|
||||
|
||||
# If using external locking (type 2) and initialisation fails,
|
||||
# with this set to 1 an attempt will be made to use the built-in
|
||||
# clustered locking.
|
||||
# If you are using a customised locking_library you should set this to 0.
|
||||
fallback_to_clustered_locking = 1
|
||||
|
||||
# If an attempt to initialise type 2 or type 3 locking failed, perhaps
|
||||
# because cluster components such as clvmd are not running, with this set
|
||||
# to 1 an attempt will be made to use local file-based locking (type 1).
|
||||
# If this succeeds, only commands against local volume groups will proceed.
|
||||
# Volume Groups marked as clustered will be ignored.
|
||||
fallback_to_local_locking = 1
|
||||
|
||||
# Local non-LV directory that holds file-based locks while commands are
|
||||
# in progress. A directory like /tmp that may get wiped on reboot is OK.
|
||||
locking_dir = "/var/lock/lvm"
|
||||
@@ -223,6 +238,9 @@ global {
|
||||
|
||||
# Search this directory first for shared libraries.
|
||||
# library_dir = "/lib"
|
||||
|
||||
# The external locking library to load if locking_type is set to 2.
|
||||
# locking_library = "liblvm2clusterlock.so"
|
||||
}
|
||||
|
||||
activation {
|
||||
@@ -232,9 +250,6 @@ activation {
|
||||
# target or make it return zeros.
|
||||
missing_stripe_filler = "/dev/ioerror"
|
||||
|
||||
# Size (in KB) of each copy operation when mirroring
|
||||
mirror_region_size = 512
|
||||
|
||||
# How much stack (in KB) to reserve for use while devices suspended
|
||||
reserved_stack = 256
|
||||
|
||||
@@ -251,6 +266,54 @@ activation {
|
||||
# "@*" matches if any tag defined on the host is also set in the LV or VG
|
||||
#
|
||||
# volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
|
||||
|
||||
# Size (in KB) of each copy operation when mirroring
|
||||
mirror_region_size = 512
|
||||
|
||||
# 'mirror_image_fault_policy' and 'mirror_log_fault_policy' define
|
||||
# how a device failure affecting a mirror is handled.
|
||||
# A mirror is composed of mirror images (copies) and a log.
|
||||
# A disk log ensures that a mirror does not need to be re-synced
|
||||
# (all copies made the same) every time a machine reboots or crashes.
|
||||
#
|
||||
# In the event of a failure, the specified policy will be used to
|
||||
# determine what happens:
|
||||
#
|
||||
# "remove" - Simply remove the faulty device and run without it. If
|
||||
# the log device fails, the mirror would convert to using
|
||||
# an in-memory log. This means the mirror will not
|
||||
# remember its sync status across crashes/reboots and
|
||||
# the entire mirror will be re-synced. If a
|
||||
# mirror image fails, the mirror will convert to a
|
||||
# non-mirrored device if there is only one remaining good
|
||||
# copy.
|
||||
#
|
||||
# "allocate" - Remove the faulty device and try to allocate space on
|
||||
# a new device to be a replacement for the failed device.
|
||||
# Using this policy for the log is fast and maintains the
|
||||
# ability to remember sync state through crashes/reboots.
|
||||
# Using this policy for a mirror device is slow, as it
|
||||
# requires the mirror to resynchronize the devices, but it
|
||||
# will preserve the mirror characteristic of the device.
|
||||
# This policy acts like "remove" if no suitable device and
|
||||
# space can be allocated for the replacement.
|
||||
# Currently this is not implemented properly and behaves
|
||||
# similarly to:
|
||||
#
|
||||
# "allocate_anywhere" - Operates like "allocate", but it does not
|
||||
# require that the new space being allocated be on a
|
||||
# device is not part of the mirror. For a log device
|
||||
# failure, this could mean that the log is allocated on
|
||||
# the same device as a mirror device. For a mirror
|
||||
# device, this could mean that the mirror device is
|
||||
# allocated on the same device as another mirror device.
|
||||
# This policy would not be wise for mirror devices
|
||||
# because it would break the redundant nature of the
|
||||
# mirror. This policy acts like "remove" if no suitable
|
||||
# device and space can be allocated for the replacement.
|
||||
|
||||
mirror_log_fault_policy = "allocate"
|
||||
mirror_device_fault_policy = "remove"
|
||||
}
|
||||
|
||||
|
||||
@@ -291,7 +354,13 @@ activation {
|
||||
|
||||
# Event daemon
|
||||
#
|
||||
#dmeventd {
|
||||
# dmeventd {
|
||||
# mirror_library is the library used when monitoring a mirror device.
|
||||
#
|
||||
# "libdevmapper-event-lvm2mirror.so" attempts to recover from failures.
|
||||
# It removes failed devices from a volume group and reconfigures a
|
||||
# mirror as necessary.
|
||||
#
|
||||
# mirror_library = "libdevmapper-event-lvm2mirror.so"
|
||||
#}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
../lib/misc/lvm-exec.h
|
||||
../lib/misc/lvm-file.h
|
||||
../lib/misc/lvm-string.h
|
||||
../lib/misc/lvm-wrappers.h
|
||||
../lib/misc/sharedlib.h
|
||||
../lib/regex/matcher.h
|
||||
../lib/report/report.h
|
||||
|
||||
@@ -78,6 +78,7 @@ SOURCES =\
|
||||
misc/lvm-exec.c \
|
||||
misc/lvm-file.c \
|
||||
misc/lvm-string.c \
|
||||
misc/lvm-wrappers.c \
|
||||
mm/memlock.c \
|
||||
regex/matcher.c \
|
||||
regex/parse_rx.c \
|
||||
|
||||
@@ -39,7 +39,7 @@ int lvm1_present(struct cmd_context *cmd)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (lvm_snprintf(path, sizeof(path), "%s/lvm/global", cmd->proc_dir)
|
||||
if (dm_snprintf(path, sizeof(path), "%s/lvm/global", cmd->proc_dir)
|
||||
< 0) {
|
||||
log_error("LVM1 proc global snprintf failed");
|
||||
return 0;
|
||||
@@ -152,11 +152,16 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
|
||||
}
|
||||
|
||||
int pv_uses_vg(struct cmd_context *cmd, struct physical_volume *pv,
|
||||
struct volume_group *vg)
|
||||
struct volume_group *vg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void activation_release(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void activation_exit(void)
|
||||
{
|
||||
return;
|
||||
@@ -193,7 +198,7 @@ static int _passes_activation_filter(struct cmd_context *cmd,
|
||||
char *str;
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (!(cn = find_config_node(cmd->cft->root, "activation/volume_list"))) {
|
||||
if (!(cn = find_config_tree_node(cmd, "activation/volume_list"))) {
|
||||
/* If no host tags defined, activate */
|
||||
if (list_empty(&cmd->tags))
|
||||
return 1;
|
||||
@@ -252,9 +257,9 @@ static int _passes_activation_filter(struct cmd_context *cmd,
|
||||
continue;
|
||||
}
|
||||
/* vgname/lvname */
|
||||
if (lvm_snprintf(path, sizeof(path), "%s/%s", lv->vg->name,
|
||||
if (dm_snprintf(path, sizeof(path), "%s/%s", lv->vg->name,
|
||||
lv->name) < 0) {
|
||||
log_error("lvm_snprintf error from %s/%s", lv->vg->name,
|
||||
log_error("dm_snprintf error from %s/%s", lv->vg->name,
|
||||
lv->name);
|
||||
continue;
|
||||
}
|
||||
@@ -337,7 +342,7 @@ int target_present(const char *target_name, int use_modprobe)
|
||||
if (target_version(target_name, &maj, &min, &patchlevel))
|
||||
return 1;
|
||||
|
||||
if (lvm_snprintf(module, sizeof(module), "dm-%s", target_name)
|
||||
if (dm_snprintf(module, sizeof(module), "dm-%s", target_name)
|
||||
< 0) {
|
||||
log_error("target_present module name too long: %s",
|
||||
target_name);
|
||||
@@ -523,7 +528,7 @@ static int _lv_deactivate(struct logical_volume *lv)
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _lv_suspend_lv(struct logical_volume *lv)
|
||||
static int _lv_suspend_lv(struct logical_volume *lv, int lockfs)
|
||||
{
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
@@ -531,7 +536,7 @@ static int _lv_suspend_lv(struct logical_volume *lv)
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
|
||||
return_0;
|
||||
|
||||
if (!(r = dev_manager_suspend(dm, lv)))
|
||||
if (!(r = dev_manager_suspend(dm, lv, lockfs)))
|
||||
stack;
|
||||
|
||||
dev_manager_destroy(dm);
|
||||
@@ -574,14 +579,29 @@ int lvs_in_vg_opened(struct volume_group *vg)
|
||||
return count;
|
||||
}
|
||||
|
||||
static int _register_dev_for_events(struct cmd_context *cmd,
|
||||
struct logical_volume *lv, int do_reg)
|
||||
/*
|
||||
* register_dev_for_events
|
||||
*
|
||||
* This function uses proper error codes (but breaks convention)
|
||||
* to return:
|
||||
* -1 on error
|
||||
* 0 if the lv's targets don't do event [un]registration
|
||||
* 0 if the lv is already [un]registered -- FIXME: not implemented
|
||||
* 1 if the lv had a segment which was [un]registered
|
||||
*
|
||||
* Returns: -1 on error
|
||||
*/
|
||||
int register_dev_for_events(struct cmd_context *cmd,
|
||||
struct logical_volume *lv, int do_reg)
|
||||
{
|
||||
#ifdef DMEVENTD
|
||||
int r = 0;
|
||||
struct list *tmp;
|
||||
struct lv_segment *seg;
|
||||
int (*reg) (struct dm_pool *mem, struct lv_segment *,
|
||||
struct config_tree *cft, int events);
|
||||
int (*reg) (struct lv_segment *, int events);
|
||||
|
||||
if (do_reg && !dmeventd_register_mode())
|
||||
return 1;
|
||||
|
||||
list_iterate(tmp, &lv->segments) {
|
||||
seg = list_item(tmp, struct lv_segment);
|
||||
@@ -595,17 +615,21 @@ static int _register_dev_for_events(struct cmd_context *cmd,
|
||||
reg = seg->segtype->ops->target_unregister_events;
|
||||
|
||||
if (!reg)
|
||||
return_0;
|
||||
continue;
|
||||
|
||||
/* FIXME specify events */
|
||||
if (!reg(cmd->mem, seg, cmd->cft, 0)) {
|
||||
/* FIXME specify events */
|
||||
if (!reg(seg, 0)) {
|
||||
stack;
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
return r;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||
@@ -613,6 +637,7 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||
{
|
||||
struct logical_volume *lv, *lv_pre;
|
||||
struct lvinfo info;
|
||||
int lockfs = 0;
|
||||
|
||||
if (!activation())
|
||||
return 1;
|
||||
@@ -643,12 +668,16 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||
}
|
||||
}
|
||||
|
||||
if (!_register_dev_for_events(cmd, lv, 0))
|
||||
if (register_dev_for_events(cmd, lv, 0) != 1)
|
||||
/* FIXME Consider aborting here */
|
||||
stack;
|
||||
|
||||
memlock_inc();
|
||||
if (!_lv_suspend_lv(lv)) {
|
||||
|
||||
if (lv_is_origin(lv_pre) || lv_is_cow(lv_pre))
|
||||
lockfs = 1;
|
||||
|
||||
if (!_lv_suspend_lv(lv, lockfs)) {
|
||||
memlock_dec();
|
||||
fs_unlock();
|
||||
return 0;
|
||||
@@ -697,7 +726,7 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
|
||||
memlock_dec();
|
||||
fs_unlock();
|
||||
|
||||
if (!_register_dev_for_events(cmd, lv, 1))
|
||||
if (register_dev_for_events(cmd, lv, 1) != 1)
|
||||
stack;
|
||||
|
||||
return 1;
|
||||
@@ -743,7 +772,7 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_register_dev_for_events(cmd, lv, 0))
|
||||
if (register_dev_for_events(cmd, lv, 0) != 1)
|
||||
stack;
|
||||
|
||||
memlock_inc();
|
||||
@@ -816,7 +845,7 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
|
||||
memlock_dec();
|
||||
fs_unlock();
|
||||
|
||||
if (!_register_dev_for_events(cmd, lv, 1))
|
||||
if (!register_dev_for_events(cmd, lv, 1) != 1)
|
||||
stack;
|
||||
|
||||
return r;
|
||||
@@ -862,28 +891,21 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
|
||||
* Does PV use VG somewhere in its construction?
|
||||
* Returns 1 on failure.
|
||||
*/
|
||||
int pv_uses_vg(struct cmd_context *cmd, struct physical_volume *pv,
|
||||
struct volume_group *vg)
|
||||
int pv_uses_vg(struct physical_volume *pv,
|
||||
struct volume_group *vg)
|
||||
{
|
||||
struct dev_manager *dm;
|
||||
int r;
|
||||
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
if (!dm_is_dm_major(MAJOR(pv->dev->dev)))
|
||||
return 0;
|
||||
|
||||
if (!(dm = dev_manager_create(cmd, vg->name))) {
|
||||
stack;
|
||||
return 1;
|
||||
}
|
||||
return dev_manager_device_uses_vg(pv->dev, vg);
|
||||
}
|
||||
|
||||
r = dev_manager_device_uses_vg(dm, pv->dev, vg);
|
||||
|
||||
dev_manager_destroy(dm);
|
||||
|
||||
return r;
|
||||
void activation_release(void)
|
||||
{
|
||||
dev_manager_release();
|
||||
}
|
||||
|
||||
void activation_exit(void)
|
||||
|
||||
@@ -40,6 +40,7 @@ int target_present(const char *target_name, int use_modprobe);
|
||||
int target_version(const char *target_name, uint32_t *maj,
|
||||
uint32_t *min, uint32_t *patchlevel);
|
||||
|
||||
void activation_release(void);
|
||||
void activation_exit(void);
|
||||
|
||||
int lv_suspend(struct cmd_context *cmd, const char *lvid_s);
|
||||
@@ -80,10 +81,14 @@ int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
int lvs_in_vg_activated(struct volume_group *vg);
|
||||
int lvs_in_vg_opened(struct volume_group *vg);
|
||||
|
||||
|
||||
int register_dev_for_events(struct cmd_context *cmd,
|
||||
struct logical_volume *lv, int do_reg);
|
||||
|
||||
/*
|
||||
* Returns 1 if PV has a dependency tree that uses anything in VG.
|
||||
*/
|
||||
int pv_uses_vg(struct cmd_context *cmd, struct physical_volume *pv,
|
||||
int pv_uses_vg(struct physical_volume *pv,
|
||||
struct volume_group *vg);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -37,6 +37,7 @@ typedef enum {
|
||||
ACTIVATE,
|
||||
DEACTIVATE,
|
||||
SUSPEND,
|
||||
SUSPEND_WITH_LOCKFS,
|
||||
CLEAN
|
||||
} action_t;
|
||||
|
||||
@@ -329,7 +330,7 @@ static int _percent_run(struct dev_manager *dm, const char *name,
|
||||
|
||||
if (segtype->ops->target_percent &&
|
||||
!segtype->ops->target_percent(&dm->target_state, dm->mem,
|
||||
dm->cmd->cft, seg, params,
|
||||
dm->cmd, seg, params,
|
||||
&total_numerator,
|
||||
&total_denominator,
|
||||
percent))
|
||||
@@ -401,7 +402,7 @@ struct dev_manager *dev_manager_create(struct cmd_context *cmd,
|
||||
dm->mem = mem;
|
||||
|
||||
if (!stripe_filler) {
|
||||
stripe_filler = find_config_str(cmd->cft->root,
|
||||
stripe_filler = find_config_tree_str(cmd,
|
||||
"activation/missing_stripe_filler",
|
||||
DEFAULT_STRIPE_FILLER);
|
||||
}
|
||||
@@ -426,6 +427,11 @@ void dev_manager_destroy(struct dev_manager *dm)
|
||||
dm_pool_destroy(dm->mem);
|
||||
}
|
||||
|
||||
void dev_manager_release(void)
|
||||
{
|
||||
dm_lib_release();
|
||||
}
|
||||
|
||||
void dev_manager_exit(void)
|
||||
{
|
||||
dm_lib_exit();
|
||||
@@ -679,7 +685,7 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
(seg_type(seg, s) == AREA_LV && !seg_lv(seg, s)))
|
||||
dm_tree_node_add_target_area(node,
|
||||
dm->stripe_filler,
|
||||
NULL, 0);
|
||||
NULL, UINT64_C(0));
|
||||
else if (seg_type(seg, s) == AREA_PV)
|
||||
dm_tree_node_add_target_area(node,
|
||||
dev_name(seg_dev(seg, s)),
|
||||
@@ -704,7 +710,6 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
}
|
||||
|
||||
static int _add_origin_target_to_dtree(struct dev_manager *dm,
|
||||
struct dm_tree *dtree,
|
||||
struct dm_tree_node *dnode,
|
||||
struct logical_volume *lv)
|
||||
{
|
||||
@@ -720,7 +725,6 @@ static int _add_origin_target_to_dtree(struct dev_manager *dm,
|
||||
}
|
||||
|
||||
static int _add_snapshot_target_to_dtree(struct dev_manager *dm,
|
||||
struct dm_tree *dtree,
|
||||
struct dm_tree_node *dnode,
|
||||
struct logical_volume *lv)
|
||||
{
|
||||
@@ -749,7 +753,6 @@ static int _add_snapshot_target_to_dtree(struct dev_manager *dm,
|
||||
}
|
||||
|
||||
static int _add_target_to_dtree(struct dev_manager *dm,
|
||||
struct dm_tree *dtree,
|
||||
struct dm_tree_node *dnode,
|
||||
struct lv_segment *seg)
|
||||
{
|
||||
@@ -761,7 +764,7 @@ static int _add_target_to_dtree(struct dev_manager *dm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
return seg->segtype->ops->add_target_line(dm, dm->mem, dm->cmd->cft,
|
||||
return seg->segtype->ops->add_target_line(dm, dm->mem, dm->cmd,
|
||||
&dm->target_state, seg,
|
||||
dnode,
|
||||
extent_size * seg->len,
|
||||
@@ -814,12 +817,12 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
|
||||
|
||||
/* Now we've added its dependencies, we can add the target itself */
|
||||
if (lv_is_origin(seg->lv) && !layer) {
|
||||
if (!_add_origin_target_to_dtree(dm, dtree, dnode, seg->lv))
|
||||
if (!_add_origin_target_to_dtree(dm, dnode, seg->lv))
|
||||
return_0;
|
||||
} else if (lv_is_cow(seg->lv) && !layer) {
|
||||
if (!_add_snapshot_target_to_dtree(dm, dtree, dnode, seg->lv))
|
||||
if (!_add_snapshot_target_to_dtree(dm, dnode, seg->lv))
|
||||
return_0;
|
||||
} else if (!_add_target_to_dtree(dm, dtree, dnode, seg))
|
||||
} else if (!_add_target_to_dtree(dm, dnode, seg))
|
||||
return_0;
|
||||
|
||||
if (lv_is_origin(seg->lv) && !layer)
|
||||
@@ -864,10 +867,10 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
* Major/minor settings only apply to the visible layer.
|
||||
*/
|
||||
if (!(dnode = dm_tree_add_new_dev(dtree, name, dlid,
|
||||
layer ? lv->major : 0,
|
||||
layer ? lv->minor : 0,
|
||||
layer ? UINT32_C(0) : (uint32_t) lv->major,
|
||||
layer ? UINT32_C(0) : (uint32_t) lv->minor,
|
||||
_read_only_lv(lv),
|
||||
lv->vg->status & PRECOMMITTED,
|
||||
(lv->vg->status & PRECOMMITTED) ? 1 : 0,
|
||||
lvlayer)))
|
||||
return_0;
|
||||
|
||||
@@ -909,7 +912,7 @@ static int _create_lv_symlinks(struct dev_manager *dm, struct dm_tree_node *root
|
||||
name = dm_tree_node_get_name(child);
|
||||
|
||||
if (name && lvlayer->old_name && *lvlayer->old_name && strcmp(name, lvlayer->old_name)) {
|
||||
if (!split_dm_name(dm->mem, lvlayer->old_name, &vgname, &lvname, &layer)) {
|
||||
if (!dm_split_lvm_name(dm->mem, lvlayer->old_name, &vgname, &lvname, &layer)) {
|
||||
log_error("_create_lv_symlinks: Couldn't split up old device name %s", lvlayer->old_name);
|
||||
return 0;
|
||||
}
|
||||
@@ -921,7 +924,7 @@ static int _create_lv_symlinks(struct dev_manager *dm, struct dm_tree_node *root
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _clean_tree(struct dev_manager *dm, struct logical_volume *lv, struct dm_tree_node *root)
|
||||
static int _clean_tree(struct dev_manager *dm, struct dm_tree_node *root)
|
||||
{
|
||||
void *handle = NULL;
|
||||
struct dm_tree_node *child;
|
||||
@@ -935,7 +938,7 @@ static int _clean_tree(struct dev_manager *dm, struct logical_volume *lv, struct
|
||||
if (!(uuid = dm_tree_node_get_uuid(child)))
|
||||
continue;
|
||||
|
||||
if (!split_dm_name(dm->mem, name, &vgname, &lvname, &layer)) {
|
||||
if (!dm_split_lvm_name(dm->mem, name, &vgname, &lvname, &layer)) {
|
||||
log_error("_clean_tree: Couldn't split up device name %s.", name);
|
||||
return 0;
|
||||
}
|
||||
@@ -973,7 +976,7 @@ static int _tree_action(struct dev_manager *dm, struct logical_volume *lv, actio
|
||||
switch(action) {
|
||||
case CLEAN:
|
||||
/* Deactivate any unused non-toplevel nodes */
|
||||
if (!_clean_tree(dm, lv, root))
|
||||
if (!_clean_tree(dm, root))
|
||||
goto_out;
|
||||
break;
|
||||
case DEACTIVATE:
|
||||
@@ -982,8 +985,8 @@ static int _tree_action(struct dev_manager *dm, struct logical_volume *lv, actio
|
||||
goto_out;
|
||||
break;
|
||||
case SUSPEND:
|
||||
if (!lv_is_origin(lv) && !lv_is_cow(lv))
|
||||
dm_tree_skip_lockfs(root);
|
||||
dm_tree_skip_lockfs(root);
|
||||
case SUSPEND_WITH_LOCKFS:
|
||||
if (!dm_tree_suspend_children(root, dlid, ID_LEN + sizeof(UUID_PREFIX) - 1))
|
||||
goto_out;
|
||||
break;
|
||||
@@ -1047,16 +1050,17 @@ int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv)
|
||||
return r;
|
||||
}
|
||||
|
||||
int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv)
|
||||
int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv,
|
||||
int lockfs)
|
||||
{
|
||||
return _tree_action(dm, lv, SUSPEND);
|
||||
return _tree_action(dm, lv, lockfs ? SUSPEND_WITH_LOCKFS : SUSPEND);
|
||||
}
|
||||
|
||||
/*
|
||||
* Does device use VG somewhere in its construction?
|
||||
* Returns 1 if uncertain.
|
||||
*/
|
||||
int dev_manager_device_uses_vg(struct dev_manager *dm, struct device *dev,
|
||||
int dev_manager_device_uses_vg(struct device *dev,
|
||||
struct volume_group *vg)
|
||||
{
|
||||
struct dm_tree *dtree;
|
||||
@@ -1069,7 +1073,7 @@ int dev_manager_device_uses_vg(struct dev_manager *dm, struct device *dev,
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!dm_tree_add_dev(dtree, MAJOR(dev->dev), MINOR(dev->dev))) {
|
||||
if (!dm_tree_add_dev(dtree, (uint32_t) MAJOR(dev->dev), (uint32_t) MINOR(dev->dev))) {
|
||||
log_error("Failed to add device %s (%" PRIu32 ":%" PRIu32") to dtree",
|
||||
dev_name(dev), (uint32_t) MAJOR(dev->dev), (uint32_t) MINOR(dev->dev));
|
||||
goto out;
|
||||
|
||||
@@ -29,6 +29,7 @@ struct device;
|
||||
struct dev_manager *dev_manager_create(struct cmd_context *cmd,
|
||||
const char *vg_name);
|
||||
void dev_manager_destroy(struct dev_manager *dm);
|
||||
void dev_manager_release(void);
|
||||
void dev_manager_exit(void);
|
||||
|
||||
/*
|
||||
@@ -46,7 +47,8 @@ int dev_manager_snapshot_percent(struct dev_manager *dm,
|
||||
int dev_manager_mirror_percent(struct dev_manager *dm,
|
||||
struct logical_volume *lv, int wait,
|
||||
float *percent, uint32_t *event_nr);
|
||||
int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv);
|
||||
int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv,
|
||||
int lockfs);
|
||||
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv);
|
||||
int dev_manager_preload(struct dev_manager *dm, struct logical_volume *lv);
|
||||
int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv);
|
||||
@@ -59,7 +61,7 @@ int dev_manager_lv_rmnodes(const struct logical_volume *lv);
|
||||
*/
|
||||
int dev_manager_execute(struct dev_manager *dm);
|
||||
|
||||
int dev_manager_device_uses_vg(struct dev_manager *dm, struct device *dev,
|
||||
int dev_manager_device_uses_vg(struct device *dev,
|
||||
struct volume_group *vg);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,7 +30,7 @@ static int _mk_dir(const char *dev_dir, const char *vg_name)
|
||||
{
|
||||
char vg_path[PATH_MAX];
|
||||
|
||||
if (lvm_snprintf(vg_path, sizeof(vg_path), "%s%s",
|
||||
if (dm_snprintf(vg_path, sizeof(vg_path), "%s%s",
|
||||
dev_dir, vg_name) == -1) {
|
||||
log_error("Couldn't construct name of volume "
|
||||
"group directory.");
|
||||
@@ -53,7 +53,7 @@ static int _rm_dir(const char *dev_dir, const char *vg_name)
|
||||
{
|
||||
char vg_path[PATH_MAX];
|
||||
|
||||
if (lvm_snprintf(vg_path, sizeof(vg_path), "%s%s",
|
||||
if (dm_snprintf(vg_path, sizeof(vg_path), "%s%s",
|
||||
dev_dir, vg_name) == -1) {
|
||||
log_error("Couldn't construct name of volume "
|
||||
"group directory.");
|
||||
@@ -87,7 +87,7 @@ static void _rm_blks(const char *dir)
|
||||
if (!strcmp(name, ".") || !strcmp(name, ".."))
|
||||
continue;
|
||||
|
||||
if (lvm_snprintf(path, sizeof(path), "%s/%s", dir, name) == -1) {
|
||||
if (dm_snprintf(path, sizeof(path), "%s/%s", dir, name) == -1) {
|
||||
log_error("Couldn't create path for %s", name);
|
||||
continue;
|
||||
}
|
||||
@@ -109,28 +109,28 @@ static int _mk_link(const char *dev_dir, const char *vg_name,
|
||||
char vg_path[PATH_MAX];
|
||||
struct stat buf;
|
||||
|
||||
if (lvm_snprintf(vg_path, sizeof(vg_path), "%s%s",
|
||||
if (dm_snprintf(vg_path, sizeof(vg_path), "%s%s",
|
||||
dev_dir, vg_name) == -1) {
|
||||
log_error("Couldn't create path for volume group dir %s",
|
||||
vg_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lvm_snprintf(lv_path, sizeof(lv_path), "%s/%s", vg_path,
|
||||
if (dm_snprintf(lv_path, sizeof(lv_path), "%s/%s", vg_path,
|
||||
lv_name) == -1) {
|
||||
log_error("Couldn't create source pathname for "
|
||||
"logical volume link %s", lv_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lvm_snprintf(link_path, sizeof(link_path), "%s/%s",
|
||||
if (dm_snprintf(link_path, sizeof(link_path), "%s/%s",
|
||||
dm_dir(), dev) == -1) {
|
||||
log_error("Couldn't create destination pathname for "
|
||||
"logical volume link for %s", lv_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lvm_snprintf(lvm1_group_path, sizeof(lvm1_group_path), "%s/group",
|
||||
if (dm_snprintf(lvm1_group_path, sizeof(lvm1_group_path), "%s/group",
|
||||
vg_path) == -1) {
|
||||
log_error("Couldn't create pathname for LVM1 group file for %s",
|
||||
vg_name);
|
||||
@@ -190,7 +190,7 @@ static int _rm_link(const char *dev_dir, const char *vg_name,
|
||||
struct stat buf;
|
||||
char lv_path[PATH_MAX];
|
||||
|
||||
if (lvm_snprintf(lv_path, sizeof(lv_path), "%s%s/%s",
|
||||
if (dm_snprintf(lv_path, sizeof(lv_path), "%s%s/%s",
|
||||
dev_dir, vg_name, lv_name) == -1) {
|
||||
log_error("Couldn't determine link pathname.");
|
||||
return 0;
|
||||
|
||||
22
lib/cache/lvmcache.c
vendored
22
lib/cache/lvmcache.c
vendored
@@ -50,7 +50,7 @@ int lvmcache_init(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void lvmcache_lock_vgname(const char *vgname, int read_only)
|
||||
void lvmcache_lock_vgname(const char *vgname, int read_only __attribute((unused)))
|
||||
{
|
||||
if (!_lock_hash && !lvmcache_init()) {
|
||||
log_error("Internal cache initialisation failed");
|
||||
@@ -169,14 +169,18 @@ struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid)
|
||||
const char *vgname_from_vgid(struct dm_pool *mem, const char *vgid)
|
||||
{
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
const char *vgname = NULL;
|
||||
|
||||
if ((vginfo = vginfo_from_vgid(vgid))) {
|
||||
if (mem)
|
||||
return dm_pool_strdup(mem, vginfo->vgname);
|
||||
return vginfo->vgname;
|
||||
}
|
||||
if (!*vgid)
|
||||
vgname = ORPHAN;
|
||||
|
||||
return NULL;
|
||||
if ((vginfo = vginfo_from_vgid(vgid)))
|
||||
vgname = vginfo->vgname;
|
||||
|
||||
if (mem && vgname)
|
||||
return dm_pool_strdup(mem, vgname);
|
||||
|
||||
return vgname;
|
||||
}
|
||||
|
||||
struct lvmcache_info *info_from_pvid(const char *pvid)
|
||||
@@ -237,7 +241,7 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(iter = dev_iter_create(cmd->filter, (full_scan == 2) ? 1: 0))) {
|
||||
if (!(iter = dev_iter_create(cmd->filter, (full_scan == 2) ? 1 : 0))) {
|
||||
log_error("dev_iter creation failed");
|
||||
goto out;
|
||||
}
|
||||
@@ -857,7 +861,7 @@ static void _lvmcache_destroy_vgnamelist(struct lvmcache_vginfo *vginfo)
|
||||
} while ((vginfo = next));
|
||||
}
|
||||
|
||||
static void _lvmcache_destroy_lockname(int present)
|
||||
static void _lvmcache_destroy_lockname(int present __attribute((unused)))
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ static int _get_env_vars(struct cmd_context *cmd)
|
||||
|
||||
/* Set to "" to avoid using any system directory */
|
||||
if ((e = getenv("LVM_SYSTEM_DIR"))) {
|
||||
if (lvm_snprintf(cmd->sys_dir, sizeof(cmd->sys_dir),
|
||||
if (dm_snprintf(cmd->sys_dir, sizeof(cmd->sys_dir),
|
||||
"%s", e) < 0) {
|
||||
log_error("LVM_SYSTEM_DIR environment variable "
|
||||
"is too long.");
|
||||
@@ -84,10 +84,11 @@ static void _init_logging(struct cmd_context *cmd)
|
||||
time_t t;
|
||||
|
||||
const char *log_file;
|
||||
char timebuf[26];
|
||||
|
||||
/* Syslog */
|
||||
cmd->default_settings.syslog =
|
||||
find_config_int(cmd->cft->root, "log/syslog", DEFAULT_SYSLOG);
|
||||
find_config_tree_int(cmd, "log/syslog", DEFAULT_SYSLOG);
|
||||
if (cmd->default_settings.syslog != 1)
|
||||
fin_syslog();
|
||||
|
||||
@@ -96,37 +97,37 @@ static void _init_logging(struct cmd_context *cmd)
|
||||
|
||||
/* Debug level for log file output */
|
||||
cmd->default_settings.debug =
|
||||
find_config_int(cmd->cft->root, "log/level", DEFAULT_LOGLEVEL);
|
||||
find_config_tree_int(cmd, "log/level", DEFAULT_LOGLEVEL);
|
||||
init_debug(cmd->default_settings.debug);
|
||||
|
||||
/* Verbose level for tty output */
|
||||
cmd->default_settings.verbose =
|
||||
find_config_int(cmd->cft->root, "log/verbose", DEFAULT_VERBOSE);
|
||||
find_config_tree_int(cmd, "log/verbose", DEFAULT_VERBOSE);
|
||||
init_verbose(cmd->default_settings.verbose + VERBOSE_BASE_LEVEL);
|
||||
|
||||
/* Log message formatting */
|
||||
init_indent(find_config_int(cmd->cft->root, "log/indent",
|
||||
init_indent(find_config_tree_int(cmd, "log/indent",
|
||||
DEFAULT_INDENT));
|
||||
|
||||
cmd->default_settings.msg_prefix = find_config_str(cmd->cft->root,
|
||||
cmd->default_settings.msg_prefix = find_config_tree_str(cmd,
|
||||
"log/prefix",
|
||||
DEFAULT_MSG_PREFIX);
|
||||
init_msg_prefix(cmd->default_settings.msg_prefix);
|
||||
|
||||
cmd->default_settings.cmd_name = find_config_int(cmd->cft->root,
|
||||
cmd->default_settings.cmd_name = find_config_tree_int(cmd,
|
||||
"log/command_names",
|
||||
DEFAULT_CMD_NAME);
|
||||
init_cmd_name(cmd->default_settings.cmd_name);
|
||||
|
||||
/* Test mode */
|
||||
cmd->default_settings.test =
|
||||
find_config_int(cmd->cft->root, "global/test", 0);
|
||||
find_config_tree_int(cmd, "global/test", 0);
|
||||
|
||||
/* Settings for logging to file */
|
||||
if (find_config_int(cmd->cft->root, "log/overwrite", DEFAULT_OVERWRITE))
|
||||
if (find_config_tree_int(cmd, "log/overwrite", DEFAULT_OVERWRITE))
|
||||
append = 0;
|
||||
|
||||
log_file = find_config_str(cmd->cft->root, "log/file", 0);
|
||||
log_file = find_config_tree_str(cmd, "log/file", 0);
|
||||
|
||||
if (log_file) {
|
||||
release_log_memory();
|
||||
@@ -134,15 +135,17 @@ static void _init_logging(struct cmd_context *cmd)
|
||||
init_log_file(log_file, append);
|
||||
}
|
||||
|
||||
log_file = find_config_str(cmd->cft->root, "log/activate_file", 0);
|
||||
log_file = find_config_tree_str(cmd, "log/activate_file", 0);
|
||||
if (log_file)
|
||||
init_log_direct(log_file, append);
|
||||
|
||||
init_log_while_suspended(find_config_int(cmd->cft->root,
|
||||
init_log_while_suspended(find_config_tree_int(cmd,
|
||||
"log/activation", 0));
|
||||
|
||||
t = time(NULL);
|
||||
log_verbose("Logging initialised at %s", ctime(&t));
|
||||
ctime_r(&t, &timebuf[0]);
|
||||
timebuf[24] = '\0';
|
||||
log_verbose("Logging initialised at %s", timebuf);
|
||||
|
||||
/* Tell device-mapper about our logging */
|
||||
#ifdef DEVMAPPER_SUPPORT
|
||||
@@ -155,7 +158,7 @@ static int _process_config(struct cmd_context *cmd)
|
||||
mode_t old_umask;
|
||||
|
||||
/* umask */
|
||||
cmd->default_settings.umask = find_config_int(cmd->cft->root,
|
||||
cmd->default_settings.umask = find_config_tree_int(cmd,
|
||||
"global/umask",
|
||||
DEFAULT_UMASK);
|
||||
|
||||
@@ -164,8 +167,8 @@ static int _process_config(struct cmd_context *cmd)
|
||||
log_verbose("Set umask to %04o", cmd->default_settings.umask);
|
||||
|
||||
/* dev dir */
|
||||
if (lvm_snprintf(cmd->dev_dir, sizeof(cmd->dev_dir), "%s/",
|
||||
find_config_str(cmd->cft->root, "devices/dir",
|
||||
if (dm_snprintf(cmd->dev_dir, sizeof(cmd->dev_dir), "%s/",
|
||||
find_config_tree_str(cmd, "devices/dir",
|
||||
DEFAULT_DEV_DIR)) < 0) {
|
||||
log_error("Device directory given in config file too long");
|
||||
return 0;
|
||||
@@ -175,8 +178,8 @@ static int _process_config(struct cmd_context *cmd)
|
||||
#endif
|
||||
|
||||
/* proc dir */
|
||||
if (lvm_snprintf(cmd->proc_dir, sizeof(cmd->proc_dir), "%s",
|
||||
find_config_str(cmd->cft->root, "global/proc",
|
||||
if (dm_snprintf(cmd->proc_dir, sizeof(cmd->proc_dir), "%s",
|
||||
find_config_tree_str(cmd, "global/proc",
|
||||
DEFAULT_PROC_DIR)) < 0) {
|
||||
log_error("Device directory given in config file too long");
|
||||
return 0;
|
||||
@@ -189,17 +192,17 @@ static int _process_config(struct cmd_context *cmd)
|
||||
}
|
||||
|
||||
/* activation? */
|
||||
cmd->default_settings.activation = find_config_int(cmd->cft->root,
|
||||
cmd->default_settings.activation = find_config_tree_int(cmd,
|
||||
"global/activation",
|
||||
DEFAULT_ACTIVATION);
|
||||
set_activation(cmd->default_settings.activation);
|
||||
|
||||
cmd->default_settings.suffix = find_config_int(cmd->cft->root,
|
||||
cmd->default_settings.suffix = find_config_tree_int(cmd,
|
||||
"global/suffix",
|
||||
DEFAULT_SUFFIX);
|
||||
|
||||
if (!(cmd->default_settings.unit_factor =
|
||||
units_to_bytes(find_config_str(cmd->cft->root,
|
||||
units_to_bytes(find_config_tree_str(cmd,
|
||||
"global/units",
|
||||
DEFAULT_UNITS),
|
||||
&cmd->default_settings.unit_type))) {
|
||||
@@ -316,7 +319,7 @@ static int _load_config_file(struct cmd_context *cmd, const char *tag)
|
||||
if (*tag)
|
||||
filler = "_";
|
||||
|
||||
if (lvm_snprintf(config_file, sizeof(config_file), "%s/lvm%s%s.conf",
|
||||
if (dm_snprintf(config_file, sizeof(config_file), "%s/lvm%s%s.conf",
|
||||
cmd->sys_dir, filler, tag) < 0) {
|
||||
log_error("LVM_SYSTEM_DIR or tag was too long");
|
||||
return 0;
|
||||
@@ -469,7 +472,7 @@ static int _init_dev_cache(struct cmd_context *cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(cn = find_config_node(cmd->cft->root, "devices/scan"))) {
|
||||
if (!(cn = find_config_tree_node(cmd, "devices/scan"))) {
|
||||
if (!dev_cache_add_dir("/dev")) {
|
||||
log_error("Failed to add /dev to internal "
|
||||
"device cache");
|
||||
@@ -494,7 +497,7 @@ static int _init_dev_cache(struct cmd_context *cmd)
|
||||
}
|
||||
}
|
||||
|
||||
if (!(cn = find_config_node(cmd->cft->root, "devices/loopfiles")))
|
||||
if (!(cn = find_config_tree_node(cmd, "devices/loopfiles")))
|
||||
return 1;
|
||||
|
||||
for (cv = cn->v; cv; cv = cv->next) {
|
||||
@@ -536,14 +539,14 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
|
||||
* Listed first because it's very efficient at eliminating
|
||||
* unavailable devices.
|
||||
*/
|
||||
if (find_config_bool(cmd->cft->root, "devices/sysfs_scan",
|
||||
if (find_config_tree_bool(cmd, "devices/sysfs_scan",
|
||||
DEFAULT_SYSFS_SCAN)) {
|
||||
if ((filters[nr_filt] = sysfs_filter_create(cmd->proc_dir)))
|
||||
nr_filt++;
|
||||
}
|
||||
|
||||
/* regex filter. Optional. */
|
||||
if (!(cn = find_config_node(cmd->cft->root, "devices/filter")))
|
||||
if (!(cn = find_config_tree_node(cmd, "devices/filter")))
|
||||
log_very_verbose("devices/filter not found in config file: "
|
||||
"no regex filter installed");
|
||||
|
||||
@@ -553,14 +556,14 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
|
||||
}
|
||||
|
||||
/* device type filter. Required. */
|
||||
cn = find_config_node(cmd->cft->root, "devices/types");
|
||||
cn = find_config_tree_node(cmd, "devices/types");
|
||||
if (!(filters[nr_filt++] = lvm_type_filter_create(cmd->proc_dir, cn))) {
|
||||
log_error("Failed to create lvm type filter");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* md component filter. Optional, non-critical. */
|
||||
if (find_config_bool(cmd->cft->root, "devices/md_component_detection",
|
||||
if (find_config_tree_bool(cmd, "devices/md_component_detection",
|
||||
DEFAULT_MD_COMPONENT_DETECTION)) {
|
||||
init_md_filtering(1);
|
||||
if ((filters[nr_filt] = md_filter_create()))
|
||||
@@ -584,14 +587,14 @@ static int _init_filters(struct cmd_context *cmd)
|
||||
if (!(f3 = _init_filter_components(cmd)))
|
||||
return 0;
|
||||
|
||||
if (lvm_snprintf(cache_file, sizeof(cache_file),
|
||||
if (dm_snprintf(cache_file, sizeof(cache_file),
|
||||
"%s/.cache", cmd->sys_dir) < 0) {
|
||||
log_error("Persistent cache filename too long ('%s/.cache').",
|
||||
cmd->sys_dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev_cache = find_config_str(cmd->cft->root, "devices/cache",
|
||||
dev_cache = find_config_tree_str(cmd, "devices/cache",
|
||||
cache_file);
|
||||
if (!(f4 = persistent_filter_create(f3, dev_cache))) {
|
||||
log_error("Failed to create persistent device filter");
|
||||
@@ -599,7 +602,7 @@ static int _init_filters(struct cmd_context *cmd)
|
||||
}
|
||||
|
||||
/* Should we ever dump persistent filter state? */
|
||||
if (find_config_int(cmd->cft->root, "devices/write_cache_state", 1))
|
||||
if (find_config_tree_int(cmd, "devices/write_cache_state", 1))
|
||||
cmd->dump_filter = 1;
|
||||
|
||||
if (!*cmd->sys_dir)
|
||||
@@ -643,8 +646,9 @@ static int _init_formats(struct cmd_context *cmd)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBDL
|
||||
/* Load any formats in shared libs */
|
||||
if ((cn = find_config_node(cmd->cft->root, "global/format_libraries"))) {
|
||||
/* Load any formats in shared libs if not static */
|
||||
if (!cmd->is_static &&
|
||||
(cn = find_config_tree_node(cmd, "global/format_libraries"))) {
|
||||
|
||||
struct config_value *cv;
|
||||
struct format_type *(*init_format_fn) (struct cmd_context *);
|
||||
@@ -656,7 +660,7 @@ static int _init_formats(struct cmd_context *cmd)
|
||||
"global/format_libraries");
|
||||
return 0;
|
||||
}
|
||||
if (!(lib = load_shared_library(cmd->cft, cv->v.str,
|
||||
if (!(lib = load_shared_library(cmd, cv->v.str,
|
||||
"format", 0))) {
|
||||
stack;
|
||||
return 0;
|
||||
@@ -684,7 +688,7 @@ static int _init_formats(struct cmd_context *cmd)
|
||||
|
||||
cmd->fmt_backup = fmt;
|
||||
|
||||
format = find_config_str(cmd->cft->root, "global/format",
|
||||
format = find_config_tree_str(cmd, "global/format",
|
||||
DEFAULT_FORMAT);
|
||||
|
||||
list_iterate_items(fmt, &cmd->formats) {
|
||||
@@ -737,8 +741,9 @@ static int _init_segtypes(struct cmd_context *cmd)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBDL
|
||||
/* Load any formats in shared libs */
|
||||
if ((cn = find_config_node(cmd->cft->root, "global/segment_libraries"))) {
|
||||
/* Load any formats in shared libs unless static */
|
||||
if (!cmd->is_static &&
|
||||
(cn = find_config_tree_node(cmd, "global/segment_libraries"))) {
|
||||
|
||||
struct config_value *cv;
|
||||
struct segment_type *(*init_segtype_fn) (struct cmd_context *);
|
||||
@@ -752,7 +757,7 @@ static int _init_segtypes(struct cmd_context *cmd)
|
||||
"global/segment_libraries");
|
||||
return 0;
|
||||
}
|
||||
if (!(lib = load_shared_library(cmd->cft, cv->v.str,
|
||||
if (!(lib = load_shared_library(cmd, cv->v.str,
|
||||
"segment type", 0))) {
|
||||
stack;
|
||||
return 0;
|
||||
@@ -827,16 +832,16 @@ static int _init_backup(struct cmd_context *cmd)
|
||||
|
||||
/* set up archiving */
|
||||
cmd->default_settings.archive =
|
||||
find_config_bool(cmd->cft->root, "backup/archive",
|
||||
find_config_tree_bool(cmd, "backup/archive",
|
||||
DEFAULT_ARCHIVE_ENABLED);
|
||||
|
||||
days = (uint32_t) find_config_int(cmd->cft->root, "backup/retain_days",
|
||||
days = (uint32_t) find_config_tree_int(cmd, "backup/retain_days",
|
||||
DEFAULT_ARCHIVE_DAYS);
|
||||
|
||||
min = (uint32_t) find_config_int(cmd->cft->root, "backup/retain_min",
|
||||
min = (uint32_t) find_config_tree_int(cmd, "backup/retain_min",
|
||||
DEFAULT_ARCHIVE_NUMBER);
|
||||
|
||||
if (lvm_snprintf
|
||||
if (dm_snprintf
|
||||
(default_dir, sizeof(default_dir), "%s/%s", cmd->sys_dir,
|
||||
DEFAULT_ARCHIVE_SUBDIR) == -1) {
|
||||
log_err("Couldn't create default archive path '%s/%s'.",
|
||||
@@ -844,7 +849,7 @@ static int _init_backup(struct cmd_context *cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
dir = find_config_str(cmd->cft->root, "backup/archive_dir",
|
||||
dir = find_config_tree_str(cmd, "backup/archive_dir",
|
||||
default_dir);
|
||||
|
||||
if (!archive_init(cmd, dir, days, min)) {
|
||||
@@ -854,10 +859,10 @@ static int _init_backup(struct cmd_context *cmd)
|
||||
|
||||
/* set up the backup */
|
||||
cmd->default_settings.backup =
|
||||
find_config_bool(cmd->cft->root, "backup/backup",
|
||||
find_config_tree_bool(cmd, "backup/backup",
|
||||
DEFAULT_BACKUP_ENABLED);
|
||||
|
||||
if (lvm_snprintf
|
||||
if (dm_snprintf
|
||||
(default_dir, sizeof(default_dir), "%s/%s", cmd->sys_dir,
|
||||
DEFAULT_BACKUP_SUBDIR) == -1) {
|
||||
log_err("Couldn't create default backup path '%s/%s'.",
|
||||
@@ -865,7 +870,7 @@ static int _init_backup(struct cmd_context *cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
dir = find_config_str(cmd->cft->root, "backup/backup_dir", default_dir);
|
||||
dir = find_config_tree_str(cmd, "backup/backup_dir", default_dir);
|
||||
|
||||
if (!backup_init(cmd, dir)) {
|
||||
log_debug("backup_init failed.");
|
||||
@@ -876,7 +881,7 @@ static int _init_backup(struct cmd_context *cmd)
|
||||
}
|
||||
|
||||
/* Entry point */
|
||||
struct cmd_context *create_toolcontext(struct arg *the_args)
|
||||
struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static)
|
||||
{
|
||||
struct cmd_context *cmd;
|
||||
|
||||
@@ -899,6 +904,7 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
|
||||
}
|
||||
memset(cmd, 0, sizeof(*cmd));
|
||||
cmd->args = the_args;
|
||||
cmd->is_static = is_static;
|
||||
cmd->hosttags = 0;
|
||||
list_init(&cmd->formats);
|
||||
list_init(&cmd->segtypes);
|
||||
@@ -921,7 +927,7 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
|
||||
|
||||
if (!(cmd->libmem = dm_pool_create("library", 4 * 1024))) {
|
||||
log_error("Library memory pool creation failed");
|
||||
return 0;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!_init_lvm_conf(cmd))
|
||||
@@ -1021,7 +1027,7 @@ int refresh_toolcontext(struct cmd_context *cmd)
|
||||
persistent_filter_dump(cmd->filter);
|
||||
}
|
||||
|
||||
activation_exit();
|
||||
activation_release();
|
||||
lvmcache_destroy();
|
||||
label_exit();
|
||||
_destroy_segtypes(&cmd->segtypes);
|
||||
|
||||
@@ -64,6 +64,7 @@ struct cmd_context {
|
||||
struct command *command;
|
||||
struct arg *args;
|
||||
char **argv;
|
||||
unsigned is_static; /* Static binary? */
|
||||
|
||||
struct dev_filter *filter;
|
||||
int dump_filter; /* Dump filter when exiting? */
|
||||
@@ -71,6 +72,7 @@ struct cmd_context {
|
||||
struct list config_files;
|
||||
int config_valid;
|
||||
struct config_tree *cft;
|
||||
struct config_tree *cft_override;
|
||||
struct config_info default_settings;
|
||||
struct config_info current_settings;
|
||||
|
||||
@@ -86,7 +88,7 @@ struct cmd_context {
|
||||
char proc_dir[PATH_MAX];
|
||||
};
|
||||
|
||||
struct cmd_context *create_toolcontext(struct arg *the_args);
|
||||
struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static);
|
||||
void destroy_toolcontext(struct cmd_context *cmd);
|
||||
int refresh_toolcontext(struct cmd_context *cmd);
|
||||
int config_files_changed(struct cmd_context *cmd);
|
||||
|
||||
@@ -41,10 +41,10 @@ enum {
|
||||
};
|
||||
|
||||
struct parser {
|
||||
char *fb, *fe; /* file limits */
|
||||
const char *fb, *fe; /* file limits */
|
||||
|
||||
int t; /* token limits and type */
|
||||
char *tb, *te;
|
||||
const char *tb, *te;
|
||||
|
||||
int fd; /* descriptor for file being parsed */
|
||||
int line; /* line number we are on */
|
||||
@@ -77,7 +77,7 @@ static const int sep = '/';
|
||||
|
||||
#define match(t) do {\
|
||||
if (!_match_aux(p, (t))) {\
|
||||
log_error("Parse error at line %d: unexpected token", p->line); \
|
||||
log_error("Parse error at byte %d (line %d): unexpected token", p->tb - p->fb + 1, p->line); \
|
||||
return 0;\
|
||||
} \
|
||||
} while(0);
|
||||
@@ -101,12 +101,12 @@ struct config_tree *create_config_tree(const char *filename)
|
||||
struct dm_pool *mem = dm_pool_create("config", 10 * 1024);
|
||||
|
||||
if (!mem) {
|
||||
stack;
|
||||
log_error("Failed to allocate config pool.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(c = dm_pool_zalloc(mem, sizeof(*c)))) {
|
||||
stack;
|
||||
log_error("Failed to allocate config tree.");
|
||||
dm_pool_destroy(mem);
|
||||
return 0;
|
||||
}
|
||||
@@ -125,6 +125,46 @@ void destroy_config_tree(struct config_tree *cft)
|
||||
dm_pool_destroy(((struct cs *) cft)->mem);
|
||||
}
|
||||
|
||||
static int _parse_config_file(struct parser *p, struct config_tree *cft)
|
||||
{
|
||||
p->tb = p->te = p->fb;
|
||||
p->line = 1;
|
||||
_get_token(p, TOK_SECTION_E);
|
||||
if (!(cft->root = _file(p)))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct config_tree *create_config_tree_from_string(struct cmd_context *cmd,
|
||||
const char *config_settings)
|
||||
{
|
||||
struct cs *c;
|
||||
struct config_tree *cft;
|
||||
struct parser *p;
|
||||
|
||||
if (!(cft = create_config_tree(NULL)))
|
||||
return_NULL;
|
||||
|
||||
c = (struct cs *) cft;
|
||||
if (!(p = dm_pool_alloc(c->mem, sizeof(*p)))) {
|
||||
log_error("Failed to allocate config tree parser.");
|
||||
destroy_config_tree(cft);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p->mem = c->mem;
|
||||
p->fb = config_settings;
|
||||
p->fe = config_settings + strlen(config_settings);
|
||||
|
||||
if (!_parse_config_file(p, cft)) {
|
||||
destroy_config_tree(cft);
|
||||
return_NULL;
|
||||
}
|
||||
|
||||
return cft;
|
||||
}
|
||||
|
||||
int read_config_fd(struct config_tree *cft, struct device *dev,
|
||||
off_t offset, size_t size, off_t offset2, size_t size2,
|
||||
checksum_fn_t checksum_fn, uint32_t checksum)
|
||||
@@ -134,6 +174,7 @@ int read_config_fd(struct config_tree *cft, struct device *dev,
|
||||
int r = 0;
|
||||
int use_mmap = 1;
|
||||
off_t mmap_offset = 0;
|
||||
char *buf;
|
||||
|
||||
if (!(p = dm_pool_alloc(c->mem, sizeof(*p)))) {
|
||||
stack;
|
||||
@@ -146,7 +187,7 @@ int read_config_fd(struct config_tree *cft, struct device *dev,
|
||||
use_mmap = 0;
|
||||
|
||||
if (use_mmap) {
|
||||
mmap_offset = offset % getpagesize();
|
||||
mmap_offset = offset % lvm_getpagesize();
|
||||
/* memory map the file */
|
||||
p->fb = mmap((caddr_t) 0, size + mmap_offset, PROT_READ,
|
||||
MAP_PRIVATE, dev_fd(dev), offset - mmap_offset);
|
||||
@@ -156,22 +197,23 @@ int read_config_fd(struct config_tree *cft, struct device *dev,
|
||||
}
|
||||
p->fb = p->fb + mmap_offset;
|
||||
} else {
|
||||
if (!(p->fb = dm_malloc(size + size2))) {
|
||||
if (!(buf = dm_malloc(size + size2))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!dev_read(dev, (uint64_t) offset, size, p->fb)) {
|
||||
if (!dev_read(dev, (uint64_t) offset, size, buf)) {
|
||||
log_error("Read from %s failed", dev_name(dev));
|
||||
goto out;
|
||||
}
|
||||
if (size2) {
|
||||
if (!dev_read(dev, (uint64_t) offset2, size2,
|
||||
p->fb + size)) {
|
||||
buf + size)) {
|
||||
log_error("Circular read from %s failed",
|
||||
dev_name(dev));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
p->fb = buf;
|
||||
}
|
||||
|
||||
if (checksum_fn && checksum !=
|
||||
@@ -183,11 +225,7 @@ int read_config_fd(struct config_tree *cft, struct device *dev,
|
||||
|
||||
p->fe = p->fb + size + size2;
|
||||
|
||||
/* parse */
|
||||
p->tb = p->te = p->fb;
|
||||
p->line = 1;
|
||||
_get_token(p, TOK_SECTION_E);
|
||||
if (!(cft->root = _file(p))) {
|
||||
if (!_parse_config_file(p, cft)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
@@ -196,7 +234,7 @@ int read_config_fd(struct config_tree *cft, struct device *dev,
|
||||
|
||||
out:
|
||||
if (!use_mmap)
|
||||
dm_free(p->fb);
|
||||
dm_free(buf);
|
||||
else {
|
||||
/* unmap the file */
|
||||
if (munmap((char *) (p->fb - mmap_offset), size + mmap_offset)) {
|
||||
@@ -529,7 +567,7 @@ static struct config_value *_type(struct parser *p)
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error("Parse error at line %d: expected a value", p->line);
|
||||
log_error("Parse error at byte %d (line %d): expected a value", p->tb - p->fb + 1, p->line);
|
||||
return 0;
|
||||
}
|
||||
return v;
|
||||
@@ -721,8 +759,8 @@ static char *_dup_tok(struct parser *p)
|
||||
/*
|
||||
* utility functions
|
||||
*/
|
||||
struct config_node *find_config_node(const struct config_node *cn,
|
||||
const char *path)
|
||||
static struct config_node *_find_config_node(const struct config_node *cn,
|
||||
const char *path)
|
||||
{
|
||||
const char *e;
|
||||
|
||||
@@ -753,10 +791,32 @@ struct config_node *find_config_node(const struct config_node *cn,
|
||||
return (struct config_node *) cn;
|
||||
}
|
||||
|
||||
const char *find_config_str(const struct config_node *cn,
|
||||
const char *path, const char *fail)
|
||||
static struct config_node *_find_first_config_node(const struct config_node *cn1,
|
||||
const struct config_node *cn2,
|
||||
const char *path)
|
||||
{
|
||||
const struct config_node *n = find_config_node(cn, path);
|
||||
struct config_node *cn;
|
||||
|
||||
if (cn1 && (cn = _find_config_node(cn1, path)))
|
||||
return cn;
|
||||
|
||||
if (cn2 && (cn = _find_config_node(cn2, path)))
|
||||
return cn;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct config_node *find_config_node(const struct config_node *cn,
|
||||
const char *path)
|
||||
{
|
||||
return _find_config_node(cn, path);
|
||||
}
|
||||
|
||||
static const char *_find_config_str(const struct config_node *cn1,
|
||||
const struct config_node *cn2,
|
||||
const char *path, const char *fail)
|
||||
{
|
||||
const struct config_node *n = _find_first_config_node(cn1, cn2, path);
|
||||
|
||||
/* Empty strings are ignored */
|
||||
if ((n && n->v->type == CFG_STRING) && (*n->v->v.str)) {
|
||||
@@ -770,9 +830,17 @@ const char *find_config_str(const struct config_node *cn,
|
||||
return fail;
|
||||
}
|
||||
|
||||
int find_config_int(const struct config_node *cn, const char *path, int fail)
|
||||
const char *find_config_str(const struct config_node *cn,
|
||||
const char *path, const char *fail)
|
||||
{
|
||||
const struct config_node *n = find_config_node(cn, path);
|
||||
return _find_config_str(cn, NULL, path, fail);
|
||||
}
|
||||
|
||||
static int _find_config_int(const struct config_node *cn1,
|
||||
const struct config_node *cn2,
|
||||
const char *path, int fail)
|
||||
{
|
||||
const struct config_node *n = _find_first_config_node(cn1, cn2, path);
|
||||
|
||||
if (n && n->v->type == CFG_INT) {
|
||||
log_very_verbose("Setting %s to %d", path, n->v->v.i);
|
||||
@@ -784,10 +852,16 @@ int find_config_int(const struct config_node *cn, const char *path, int fail)
|
||||
return fail;
|
||||
}
|
||||
|
||||
float find_config_float(const struct config_node *cn, const char *path,
|
||||
float fail)
|
||||
int find_config_int(const struct config_node *cn, const char *path, int fail)
|
||||
{
|
||||
const struct config_node *n = find_config_node(cn, path);
|
||||
return _find_config_int(cn, NULL, path, fail);
|
||||
}
|
||||
|
||||
static float _find_config_float(const struct config_node *cn1,
|
||||
const struct config_node *cn2,
|
||||
const char *path, float fail)
|
||||
{
|
||||
const struct config_node *n = _find_first_config_node(cn1, cn2, path);
|
||||
|
||||
if (n && n->v->type == CFG_FLOAT) {
|
||||
log_very_verbose("Setting %s to %f", path, n->v->v.r);
|
||||
@@ -801,6 +875,36 @@ float find_config_float(const struct config_node *cn, const char *path,
|
||||
|
||||
}
|
||||
|
||||
float find_config_float(const struct config_node *cn, const char *path,
|
||||
float fail)
|
||||
{
|
||||
return _find_config_float(cn, NULL, path, fail);
|
||||
}
|
||||
|
||||
struct config_node *find_config_tree_node(struct cmd_context *cmd,
|
||||
const char *path)
|
||||
{
|
||||
return _find_first_config_node(cmd->cft_override ? cmd->cft_override->root : NULL, cmd->cft->root, path);
|
||||
}
|
||||
|
||||
const char *find_config_tree_str(struct cmd_context *cmd,
|
||||
const char *path, const char *fail)
|
||||
{
|
||||
return _find_config_str(cmd->cft_override ? cmd->cft_override->root : NULL, cmd->cft->root, path, fail);
|
||||
}
|
||||
|
||||
int find_config_tree_int(struct cmd_context *cmd, const char *path,
|
||||
int fail)
|
||||
{
|
||||
return _find_config_int(cmd->cft_override ? cmd->cft_override->root : NULL, cmd->cft->root, path, fail);
|
||||
}
|
||||
|
||||
float find_config_tree_float(struct cmd_context *cmd, const char *path,
|
||||
float fail)
|
||||
{
|
||||
return _find_config_float(cmd->cft_override ? cmd->cft_override->root : NULL, cmd->cft->root, path, fail);
|
||||
}
|
||||
|
||||
static int _str_in_array(const char *str, const char *values[])
|
||||
{
|
||||
int i;
|
||||
@@ -827,9 +931,11 @@ static int _str_to_bool(const char *str, int fail)
|
||||
return fail;
|
||||
}
|
||||
|
||||
int find_config_bool(const struct config_node *cn, const char *path, int fail)
|
||||
static int _find_config_bool(const struct config_node *cn1,
|
||||
const struct config_node *cn2,
|
||||
const char *path, int fail)
|
||||
{
|
||||
const struct config_node *n = find_config_node(cn, path);
|
||||
const struct config_node *n = _find_first_config_node(cn1, cn2, path);
|
||||
struct config_value *v;
|
||||
|
||||
if (!n)
|
||||
@@ -848,6 +954,16 @@ int find_config_bool(const struct config_node *cn, const char *path, int fail)
|
||||
return fail;
|
||||
}
|
||||
|
||||
int find_config_bool(const struct config_node *cn, const char *path, int fail)
|
||||
{
|
||||
return _find_config_bool(cn, NULL, path, fail);
|
||||
}
|
||||
|
||||
int find_config_tree_bool(struct cmd_context *cmd, const char *path, int fail)
|
||||
{
|
||||
return _find_config_bool(cmd->cft_override ? cmd->cft_override->root : NULL, cmd->cft->root, path, fail);
|
||||
}
|
||||
|
||||
int get_config_uint32(const struct config_node *cn, const char *path,
|
||||
uint32_t *result)
|
||||
{
|
||||
|
||||
@@ -54,9 +54,11 @@ struct config_tree_list {
|
||||
};
|
||||
|
||||
struct config_tree *create_config_tree(const char *filename);
|
||||
struct config_tree *create_config_tree_from_string(struct cmd_context *cmd,
|
||||
const char *config_settings);
|
||||
void destroy_config_tree(struct config_tree *cft);
|
||||
|
||||
typedef uint32_t (*checksum_fn_t) (uint32_t initial, void *buf, uint32_t size);
|
||||
typedef uint32_t (*checksum_fn_t) (uint32_t initial, const void *buf, uint32_t size);
|
||||
|
||||
int read_config_fd(struct config_tree *cft, struct device *dev,
|
||||
off_t offset, size_t size, off_t offset2, size_t size2,
|
||||
@@ -71,20 +73,30 @@ int merge_config_tree(struct cmd_context *cmd, struct config_tree *cft,
|
||||
|
||||
struct config_node *find_config_node(const struct config_node *cn,
|
||||
const char *path);
|
||||
|
||||
const char *find_config_str(const struct config_node *cn, const char *path,
|
||||
const char *fail);
|
||||
|
||||
int find_config_int(const struct config_node *cn, const char *path, int fail);
|
||||
|
||||
float find_config_float(const struct config_node *cn, const char *path,
|
||||
float fail);
|
||||
|
||||
/*
|
||||
* These versions check an override tree, if present, first.
|
||||
*/
|
||||
struct config_node *find_config_tree_node(struct cmd_context *cmd,
|
||||
const char *path);
|
||||
const char *find_config_tree_str(struct cmd_context *cmd,
|
||||
const char *path, const char *fail);
|
||||
int find_config_tree_int(struct cmd_context *cmd, const char *path,
|
||||
int fail);
|
||||
float find_config_tree_float(struct cmd_context *cmd, const char *path,
|
||||
float fail);
|
||||
|
||||
/*
|
||||
* Understands (0, ~0), (y, n), (yes, no), (on,
|
||||
* off), (true, false).
|
||||
*/
|
||||
int find_config_bool(const struct config_node *cn, const char *path, int fail);
|
||||
int find_config_tree_bool(struct cmd_context *cmd, const char *path, int fail);
|
||||
|
||||
int get_config_uint32(const struct config_node *cn, const char *path,
|
||||
uint32_t *result);
|
||||
|
||||
@@ -32,9 +32,14 @@
|
||||
#define DEFAULT_MD_COMPONENT_DETECTION 1
|
||||
|
||||
#define DEFAULT_LOCK_DIR "/var/lock/lvm"
|
||||
#define DEFAULT_LOCKING_LIB "lvm2_locking.so"
|
||||
#define DEFAULT_LOCKING_LIB "liblvm2clusterlock.so"
|
||||
#define DEFAULT_FALLBACK_TO_LOCAL_LOCKING 1
|
||||
#define DEFAULT_FALLBACK_TO_CLUSTERED_LOCKING 1
|
||||
|
||||
#define DEFAULT_MIRROR_LOG_FAULT_POLICY "allocate"
|
||||
#define DEFAULT_MIRROR_DEV_FAULT_POLICY "remove"
|
||||
#define DEFAULT_DMEVENTD_MIRROR_LIB "libdevmapper-event-lvm2mirror.so"
|
||||
#define DEFAULT_DMEVENTD_MONITOR 1
|
||||
|
||||
#define DEFAULT_UMASK 0077
|
||||
|
||||
|
||||
@@ -645,8 +645,7 @@ struct dev_iter *dev_iter_create(struct dev_filter *f, int dev_scan)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (dev_scan) {
|
||||
if (dev_scan && !trust_cache()) {
|
||||
/* Flag gets reset between each command */
|
||||
if (!full_scan_done())
|
||||
persistent_filter_wipe(f); /* Calls _full_scan(1) */
|
||||
|
||||
@@ -176,7 +176,7 @@ static int _aligned_io(struct device_area *where, void *buffer,
|
||||
}
|
||||
|
||||
if (!block_size)
|
||||
block_size = getpagesize();
|
||||
block_size = lvm_getpagesize();
|
||||
|
||||
_widen_region(block_size, where, &widened);
|
||||
|
||||
@@ -602,7 +602,7 @@ int dev_write(struct device *dev, uint64_t offset, size_t len, void *buffer)
|
||||
return _aligned_io(&where, buffer, 1);
|
||||
}
|
||||
|
||||
int dev_zero(struct device *dev, uint64_t offset, size_t len)
|
||||
int dev_set(struct device *dev, uint64_t offset, size_t len, int value)
|
||||
{
|
||||
size_t s;
|
||||
char buffer[4096];
|
||||
@@ -620,7 +620,7 @@ int dev_zero(struct device *dev, uint64_t offset, size_t len)
|
||||
" sectors", dev_name(dev), offset >> SECTOR_SHIFT,
|
||||
len >> SECTOR_SHIFT);
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
memset(buffer, value, sizeof(buffer));
|
||||
while (1) {
|
||||
s = len > sizeof(buffer) ? sizeof(buffer) : len;
|
||||
if (!dev_write(dev, offset, s, buffer))
|
||||
|
||||
@@ -62,7 +62,7 @@ static int _has_partition_table(struct device *dev)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!dev_read(dev, 0, sizeof(buf), &buf)) {
|
||||
if (!dev_read(dev, UINT64_C(0), sizeof(buf), &buf)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ const char *dev_name(const struct device *dev);
|
||||
int dev_read(struct device *dev, uint64_t offset, size_t len, void *buffer);
|
||||
int dev_write(struct device *dev, uint64_t offset, size_t len, void *buffer);
|
||||
int dev_append(struct device *dev, size_t len, void *buffer);
|
||||
int dev_zero(struct device *dev, uint64_t offset, size_t len);
|
||||
int dev_set(struct device *dev, uint64_t offset, size_t len, int value);
|
||||
void dev_flush(struct device *dev);
|
||||
|
||||
struct device *dev_create_file(const char *filename, struct device *dev,
|
||||
|
||||
@@ -38,11 +38,13 @@ static int _errseg_merge_segments(struct lv_segment *seg1, struct lv_segment *se
|
||||
}
|
||||
|
||||
#ifdef DEVMAPPER_SUPPORT
|
||||
static int _errseg_add_target_line(struct dev_manager *dm, struct dm_pool *mem,
|
||||
struct config_tree *cft, void **target_state,
|
||||
struct lv_segment *seg,
|
||||
static int _errseg_add_target_line(struct dev_manager *dm __attribute((unused)),
|
||||
struct dm_pool *mem __attribute((unused)),
|
||||
struct cmd_context *cmd __attribute((unused)),
|
||||
void **target_state __attribute((unused)),
|
||||
struct lv_segment *seg __attribute((unused)),
|
||||
struct dm_tree_node *node, uint64_t len,
|
||||
uint32_t *pvmove_mirror_count)
|
||||
uint32_t *pvmove_mirror_count __attribute((unused)))
|
||||
{
|
||||
return dm_tree_node_add_error_target(node, len);
|
||||
}
|
||||
@@ -64,7 +66,7 @@ static int _errseg_target_present(void)
|
||||
|
||||
static void _errseg_destroy(const struct segment_type *segtype)
|
||||
{
|
||||
dm_free((void *) segtype);
|
||||
dm_free((void *)segtype);
|
||||
}
|
||||
|
||||
static struct segtype_handler _error_ops = {
|
||||
|
||||
@@ -32,7 +32,7 @@ static int _locate_sysfs_blocks(const char *proc, char *path, size_t len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lvm_snprintf(proc_mounts, sizeof(proc_mounts),
|
||||
if (dm_snprintf(proc_mounts, sizeof(proc_mounts),
|
||||
"%s/mounts", proc) < 0) {
|
||||
log_error("Failed to create /proc/mounts string");
|
||||
return 0;
|
||||
@@ -44,9 +44,9 @@ static int _locate_sysfs_blocks(const char *proc, char *path, size_t len)
|
||||
}
|
||||
|
||||
while (fgets(buffer, sizeof(buffer), fp)) {
|
||||
if (split_words(buffer, 4, split) == 4 &&
|
||||
if (dm_split_words(buffer, 4, 0, split) == 4 &&
|
||||
!strcmp(split[2], "sysfs")) {
|
||||
if (lvm_snprintf(path, len, "%s/%s", split[1],
|
||||
if (dm_snprintf(path, len, "%s/%s", split[1],
|
||||
"block") >= 0) {
|
||||
r = 1;
|
||||
}
|
||||
@@ -183,7 +183,7 @@ static int _read_devs(struct dev_set *ds, const char *dir)
|
||||
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
|
||||
continue;
|
||||
|
||||
if (lvm_snprintf(path, sizeof(path), "%s/%s", dir,
|
||||
if (dm_snprintf(path, sizeof(path), "%s/%s", dir,
|
||||
d->d_name) < 0) {
|
||||
log_error("sysfs path name too long: %s in %s",
|
||||
d->d_name, dir);
|
||||
|
||||
@@ -145,7 +145,7 @@ static int _scan_proc_dev(const char *proc, const struct config_node *cn)
|
||||
/* All types unrecognised initially */
|
||||
memset(_max_partitions_by_major, 0, sizeof(int) * NUMBER_OF_MAJORS);
|
||||
|
||||
if (lvm_snprintf(proc_devices, sizeof(proc_devices),
|
||||
if (dm_snprintf(proc_devices, sizeof(proc_devices),
|
||||
"%s/devices", proc) < 0) {
|
||||
log_error("Failed to create /proc/devices string");
|
||||
return 0;
|
||||
|
||||
@@ -458,7 +458,7 @@ static void _add_pv_to_list(struct list *head, struct disk_list *data)
|
||||
|
||||
/*
|
||||
* Build a list of pv_d's structures, allocated from mem.
|
||||
* We keep track of the first object allocated form the pool
|
||||
* We keep track of the first object allocated from the pool
|
||||
* so we can free off all the memory if something goes wrong.
|
||||
*/
|
||||
int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
|
||||
@@ -576,7 +576,7 @@ static int _write_lvs(struct disk_list *data)
|
||||
|
||||
pos = data->pvd.lv_on_disk.base;
|
||||
|
||||
if (!dev_zero(data->dev, pos, data->pvd.lv_on_disk.size)) {
|
||||
if (!dev_set(data->dev, pos, data->pvd.lv_on_disk.size, 0)) {
|
||||
log_error("Couldn't zero lv area on device '%s'",
|
||||
dev_name(data->dev));
|
||||
return 0;
|
||||
|
||||
@@ -172,6 +172,7 @@ struct disk_list {
|
||||
* Layout constants.
|
||||
*/
|
||||
#define METADATA_ALIGN 4096UL
|
||||
#define LVM1_PE_ALIGN (65536UL >> SECTOR_SHIFT) /* PE alignment */
|
||||
|
||||
#define METADATA_BASE 0UL
|
||||
#define PV_SIZE 1024UL
|
||||
|
||||
@@ -408,7 +408,7 @@ static int _format1_pv_write(const struct format_type *fmt, struct physical_volu
|
||||
|
||||
/* Ensure any residual PE structure is gone */
|
||||
pv->pe_size = pv->pe_count = 0;
|
||||
pv->pe_start = PE_ALIGN;
|
||||
pv->pe_start = LVM1_PE_ALIGN;
|
||||
|
||||
if (!(mem = dm_pool_create("lvm1 pv_write", 1024))) {
|
||||
stack;
|
||||
@@ -431,7 +431,7 @@ static int _format1_pv_write(const struct format_type *fmt, struct physical_volu
|
||||
dev_write in order to make other disk tools happy */
|
||||
dl->pvd.pv_on_disk.base = METADATA_BASE;
|
||||
dl->pvd.pv_on_disk.size = PV_SIZE;
|
||||
dl->pvd.pe_on_disk.base = PE_ALIGN << SECTOR_SHIFT;
|
||||
dl->pvd.pe_on_disk.base = LVM1_PE_ALIGN << SECTOR_SHIFT;
|
||||
|
||||
list_add(&pvs, &dl->list);
|
||||
if (!write_disks(fmt, &pvs)) {
|
||||
|
||||
@@ -103,7 +103,7 @@ int import_pv(struct dm_pool *mem, struct device *dev,
|
||||
static int _system_id(struct cmd_context *cmd, char *s, const char *prefix)
|
||||
{
|
||||
|
||||
if (lvm_snprintf(s, NAME_LEN, "%s%s%lu",
|
||||
if (dm_snprintf(s, NAME_LEN, "%s%s%lu",
|
||||
prefix, cmd->hostname, time(NULL)) < 0) {
|
||||
log_error("Generated system_id too long");
|
||||
return 0;
|
||||
|
||||
@@ -153,7 +153,7 @@ int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
|
||||
if (pe_start && end < pe_start)
|
||||
end = pe_start;
|
||||
|
||||
pvd->pe_start = _round_up(end, PE_ALIGN);
|
||||
pvd->pe_start = _round_up(end, LVM1_PE_ALIGN);
|
||||
|
||||
} while ((pvd->pe_start + (pvd->pe_total * extent_size))
|
||||
> pv->size);
|
||||
|
||||
@@ -277,7 +277,7 @@ int archive_vg(struct volume_group *vg,
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (lvm_snprintf(archive_name, sizeof(archive_name),
|
||||
if (dm_snprintf(archive_name, sizeof(archive_name),
|
||||
"%s/%s_%05u.vg", dir, vg->name, ix) < 0) {
|
||||
log_error("Archive file name too long.");
|
||||
return 0;
|
||||
|
||||
@@ -190,7 +190,7 @@ static int __backup(struct volume_group *vg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lvm_snprintf(name, sizeof(name), "%s/%s",
|
||||
if (dm_snprintf(name, sizeof(name), "%s/%s",
|
||||
vg->cmd->backup_params->dir, vg->name) < 0) {
|
||||
log_error("Failed to generate volume group metadata backup "
|
||||
"filename.");
|
||||
@@ -233,7 +233,7 @@ int backup_remove(struct cmd_context *cmd, const char *vg_name)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (lvm_snprintf(path, sizeof(path), "%s/%s",
|
||||
if (dm_snprintf(path, sizeof(path), "%s/%s",
|
||||
cmd->backup_params->dir, vg_name) < 0) {
|
||||
log_err("Failed to generate backup filename (for removal).");
|
||||
return 0;
|
||||
@@ -342,7 +342,7 @@ int backup_restore(struct cmd_context *cmd, const char *vg_name)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (lvm_snprintf(path, sizeof(path), "%s/%s",
|
||||
if (dm_snprintf(path, sizeof(path), "%s/%s",
|
||||
cmd->backup_params->dir, vg_name) < 0) {
|
||||
log_err("Failed to generate backup filename (for restore).");
|
||||
return 0;
|
||||
@@ -397,7 +397,7 @@ void check_current_backup(struct volume_group *vg)
|
||||
if ((vg->status & PARTIAL_VG) || (vg->status & EXPORTED_VG))
|
||||
return;
|
||||
|
||||
if (lvm_snprintf(path, sizeof(path), "%s/%s",
|
||||
if (dm_snprintf(path, sizeof(path), "%s/%s",
|
||||
vg->cmd->backup_params->dir, vg->name) < 0) {
|
||||
log_debug("Failed to generate backup filename.");
|
||||
return;
|
||||
|
||||
@@ -183,7 +183,8 @@ static int _out_with_comment_file(struct formatter *f, const char *comment,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _out_with_comment_raw(struct formatter *f, const char *comment,
|
||||
static int _out_with_comment_raw(struct formatter *f,
|
||||
const char *comment __attribute((unused)),
|
||||
const char *fmt, va_list ap)
|
||||
{
|
||||
int n;
|
||||
@@ -232,7 +233,7 @@ static int _sectors_to_units(uint64_t sectors, char *buffer, size_t s)
|
||||
for (i = 0; (d > 1024.0) && _units[i]; i++)
|
||||
d /= 1024.0;
|
||||
|
||||
return lvm_snprintf(buffer, s, "# %g %s", d, _units[i]) > 0;
|
||||
return dm_snprintf(buffer, s, "# %g %s", d, _units[i]) > 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -281,7 +282,7 @@ int out_text(struct formatter *f, const char *fmt, ...)
|
||||
}
|
||||
|
||||
static int _print_header(struct formatter *f,
|
||||
struct volume_group *vg, const char *desc)
|
||||
const char *desc)
|
||||
{
|
||||
time_t t;
|
||||
|
||||
@@ -612,46 +613,27 @@ static int _build_pv_names(struct formatter *f, struct volume_group *vg)
|
||||
struct physical_volume *pv;
|
||||
char buffer[32], *name;
|
||||
|
||||
if (!(f->mem = dm_pool_create("text pv_names", 512))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
if (!(f->mem = dm_pool_create("text pv_names", 512)))
|
||||
return_0;
|
||||
|
||||
if (!(f->pv_names = dm_hash_create(128))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
if (!(f->pv_names = dm_hash_create(128)))
|
||||
return_0;
|
||||
|
||||
list_iterate_items(pvl, &vg->pvs) {
|
||||
pv = pvl->pv;
|
||||
|
||||
/* FIXME But skip if there's already an LV called pv%d ! */
|
||||
if (lvm_snprintf(buffer, sizeof(buffer), "pv%d", count++) < 0) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
if (dm_snprintf(buffer, sizeof(buffer), "pv%d", count++) < 0)
|
||||
return_0;
|
||||
|
||||
if (!(name = dm_pool_strdup(f->mem, buffer))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
if (!(name = dm_pool_strdup(f->mem, buffer)))
|
||||
return_0;
|
||||
|
||||
if (!dm_hash_insert(f->pv_names, dev_name(pv->dev), name)) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
if (!dm_hash_insert(f->pv_names, dev_name(pv->dev), name))
|
||||
return_0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
bad:
|
||||
if (f->mem)
|
||||
dm_pool_destroy(f->mem);
|
||||
|
||||
if (f->pv_names)
|
||||
dm_hash_destroy(f->pv_names);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _text_vg_export(struct formatter *f,
|
||||
@@ -663,35 +645,33 @@ static int _text_vg_export(struct formatter *f,
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
#define fail do {stack; goto out;} while(0)
|
||||
|
||||
if (f->header && !_print_header(f, vg, desc))
|
||||
fail;
|
||||
if (f->header && !_print_header(f, desc))
|
||||
goto_out;
|
||||
|
||||
if (!out_text(f, "%s {", vg->name))
|
||||
fail;
|
||||
goto_out;
|
||||
|
||||
_inc_indent(f);
|
||||
|
||||
if (!_print_vg(f, vg))
|
||||
fail;
|
||||
goto_out;
|
||||
|
||||
outnl(f);
|
||||
if (!_print_pvs(f, vg))
|
||||
fail;
|
||||
goto_out;
|
||||
|
||||
outnl(f);
|
||||
if (!_print_lvs(f, vg))
|
||||
fail;
|
||||
goto_out;
|
||||
|
||||
_dec_indent(f);
|
||||
if (!out_text(f, "}"))
|
||||
fail;
|
||||
goto_out;
|
||||
|
||||
if (!f->header && !_print_header(f, vg, desc))
|
||||
fail;
|
||||
if (!f->header && !_print_header(f, desc))
|
||||
goto_out;
|
||||
|
||||
#undef fail
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
|
||||
@@ -53,6 +53,7 @@ static struct flag _lv_flags[] = {
|
||||
{VISIBLE_LV, "VISIBLE"},
|
||||
{PVMOVE, "PVMOVE"},
|
||||
{LOCKED, "LOCKED"},
|
||||
{MIRROR_NOTSYNCED, "NOTSYNCED"},
|
||||
{MIRROR_IMAGE, NULL},
|
||||
{MIRROR_LOG, NULL},
|
||||
{MIRRORED, NULL},
|
||||
|
||||
@@ -69,7 +69,8 @@ struct text_context {
|
||||
* NOTE: Currently there can be only one vg per text file.
|
||||
*/
|
||||
|
||||
static int _text_vg_setup(struct format_instance *fid, struct volume_group *vg)
|
||||
static int _text_vg_setup(struct format_instance *fid __attribute((unused)),
|
||||
struct volume_group *vg)
|
||||
{
|
||||
if (vg->extent_size & (vg->extent_size - 1)) {
|
||||
log_error("Extent size must be power of 2");
|
||||
@@ -79,7 +80,8 @@ static int _text_vg_setup(struct format_instance *fid, struct volume_group *vg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _text_lv_setup(struct format_instance *fid, struct logical_volume *lv)
|
||||
static int _text_lv_setup(struct format_instance *fid __attribute((unused)),
|
||||
struct logical_volume *lv)
|
||||
{
|
||||
/******** FIXME Any LV size restriction?
|
||||
uint64_t max_size = UINT_MAX;
|
||||
@@ -851,7 +853,7 @@ static int _scan_file(const struct format_type *fmt)
|
||||
tmp != dirent->d_name + strlen(dirent->d_name)
|
||||
- 4)) {
|
||||
vgname = dirent->d_name;
|
||||
if (lvm_snprintf(path, PATH_MAX, "%s/%s",
|
||||
if (dm_snprintf(path, PATH_MAX, "%s/%s",
|
||||
dl->dir, vgname) < 0) {
|
||||
log_error("Name too long %s/%s",
|
||||
dl->dir, vgname);
|
||||
@@ -992,7 +994,7 @@ static int _text_scan(const struct format_type *fmt)
|
||||
}
|
||||
|
||||
/* For orphan, creates new mdas according to policy.
|
||||
Always have an mda between end-of-label and PE_ALIGN boundary */
|
||||
Always have an mda between end-of-label and pe_align() boundary */
|
||||
static int _mda_setup(const struct format_type *fmt,
|
||||
uint64_t pe_start, uint64_t pe_end,
|
||||
int pvmetadatacopies,
|
||||
@@ -1003,15 +1005,15 @@ static int _mda_setup(const struct format_type *fmt,
|
||||
uint64_t start1, mda_size1; /* First area - start of disk */
|
||||
uint64_t start2, mda_size2; /* Second area - end of disk */
|
||||
uint64_t wipe_size = 8 << SECTOR_SHIFT;
|
||||
size_t pagesize = getpagesize();
|
||||
size_t pagesize = lvm_getpagesize();
|
||||
|
||||
if (!pvmetadatacopies) {
|
||||
/* Space available for PEs */
|
||||
pv->size -= PE_ALIGN;
|
||||
pv->size -= pe_align();
|
||||
return 1;
|
||||
}
|
||||
|
||||
alignment = PE_ALIGN << SECTOR_SHIFT;
|
||||
alignment = pe_align() << SECTOR_SHIFT;
|
||||
disk_size = pv->size << SECTOR_SHIFT;
|
||||
pe_start <<= SECTOR_SHIFT;
|
||||
pe_end <<= SECTOR_SHIFT;
|
||||
@@ -1053,7 +1055,7 @@ static int _mda_setup(const struct format_type *fmt,
|
||||
pvmetadatacopies = 1;
|
||||
}
|
||||
|
||||
/* Round up to PE_ALIGN boundary */
|
||||
/* Round up to pe_align() boundary */
|
||||
mda_adjustment = (mda_size1 + start1) % alignment;
|
||||
if (mda_adjustment)
|
||||
mda_size1 += (alignment - mda_adjustment);
|
||||
@@ -1071,9 +1073,9 @@ static int _mda_setup(const struct format_type *fmt,
|
||||
if (!add_mda(fmt, fmt->cmd->mem, mdas, pv->dev, start1,
|
||||
mda_size1)) return 0;
|
||||
|
||||
if (!dev_zero((struct device *) pv->dev, start1,
|
||||
(size_t) (mda_size1 >
|
||||
wipe_size ? : mda_size1))) {
|
||||
if (!dev_set((struct device *) pv->dev, start1,
|
||||
(size_t) (mda_size1 >
|
||||
wipe_size ? : mda_size1), 0)) {
|
||||
log_error("Failed to wipe new metadata area");
|
||||
return 0;
|
||||
}
|
||||
@@ -1117,9 +1119,9 @@ static int _mda_setup(const struct format_type *fmt,
|
||||
if (mda_size2) {
|
||||
if (!add_mda(fmt, fmt->cmd->mem, mdas, pv->dev, start2,
|
||||
mda_size2)) return 0;
|
||||
if (!dev_zero(pv->dev, start2,
|
||||
(size_t) (mda_size1 >
|
||||
wipe_size ? : mda_size1))) {
|
||||
if (!dev_set(pv->dev, start2,
|
||||
(size_t) (mda_size1 >
|
||||
wipe_size ? : mda_size1), 0)) {
|
||||
log_error("Failed to wipe new metadata area");
|
||||
return 0;
|
||||
}
|
||||
@@ -1187,22 +1189,22 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume
|
||||
|
||||
/* Set pe_start to first aligned sector after any metadata
|
||||
* areas that begin before pe_start */
|
||||
pv->pe_start = PE_ALIGN;
|
||||
pv->pe_start = pe_align();
|
||||
list_iterate_items(mda, &info->mdas) {
|
||||
mdac = (struct mda_context *) mda->metadata_locn;
|
||||
if (pv->dev == mdac->area.dev &&
|
||||
(mdac->area.start < (pv->pe_start << SECTOR_SHIFT)) &&
|
||||
(mdac->area.start <= (pv->pe_start << SECTOR_SHIFT)) &&
|
||||
(mdac->area.start + mdac->area.size >
|
||||
(pv->pe_start << SECTOR_SHIFT))) {
|
||||
pv->pe_start = (mdac->area.start + mdac->area.size)
|
||||
>> SECTOR_SHIFT;
|
||||
adjustment = pv->pe_start % PE_ALIGN;
|
||||
adjustment = pv->pe_start % pe_align();
|
||||
if (adjustment)
|
||||
pv->pe_start += (PE_ALIGN - adjustment);
|
||||
pv->pe_start += (pe_align() - adjustment);
|
||||
}
|
||||
}
|
||||
if (!add_da
|
||||
(fmt, NULL, &info->das, pv->pe_start << SECTOR_SHIFT, UINT64_C(0))) {
|
||||
(NULL, &info->das, pv->pe_start << SECTOR_SHIFT, UINT64_C(0))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -1339,7 +1341,7 @@ static int _text_pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _text_destroy_instance(struct format_instance *fid)
|
||||
static void _text_destroy_instance(struct format_instance *fid __attribute((unused)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1372,7 +1374,7 @@ static void _text_destroy(const struct format_type *fmt)
|
||||
dm_free(fmt->private);
|
||||
}
|
||||
|
||||
dm_free((void *) fmt);
|
||||
dm_free((void *)fmt);
|
||||
}
|
||||
|
||||
static struct metadata_area_ops _metadata_text_file_ops = {
|
||||
@@ -1531,7 +1533,7 @@ static struct format_instance *_text_create_text_instance(const struct format_ty
|
||||
dir_list = &((struct mda_lists *) fmt->private)->dirs;
|
||||
|
||||
list_iterate_items(dl, dir_list) {
|
||||
if (lvm_snprintf(path, PATH_MAX, "%s/%s",
|
||||
if (dm_snprintf(path, PATH_MAX, "%s/%s",
|
||||
dl->dir, vgname) < 0) {
|
||||
log_error("Name too long %s/%s", dl->dir,
|
||||
vgname);
|
||||
@@ -1781,7 +1783,7 @@ struct format_type *create_text_format(struct cmd_context *cmd)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((cn = find_config_node(cmd->cft->root, "metadata/dirs"))) {
|
||||
if ((cn = find_config_tree_node(cmd, "metadata/dirs"))) {
|
||||
for (cv = cn->v; cv; cv = cv->next) {
|
||||
if (cv->type != CFG_STRING) {
|
||||
log_error("Invalid string in config file: "
|
||||
@@ -1797,7 +1799,7 @@ struct format_type *create_text_format(struct cmd_context *cmd)
|
||||
}
|
||||
}
|
||||
|
||||
if ((cn = find_config_node(cmd->cft->root, "metadata/disk_areas"))) {
|
||||
if ((cn = find_config_tree_node(cmd, "metadata/disk_areas"))) {
|
||||
for (cn = cn->child; cn; cn = cn->sib) {
|
||||
if (!_get_config_disk_area(cmd, cn, &mda_lists->raws))
|
||||
goto err;
|
||||
|
||||
@@ -46,7 +46,7 @@ struct labeller *text_labeller_create(const struct format_type *fmt);
|
||||
|
||||
int pvhdr_read(struct device *dev, char *buf);
|
||||
|
||||
int add_da(const struct format_type *fmt, struct dm_pool *mem, struct list *das,
|
||||
int add_da(struct dm_pool *mem, struct list *das,
|
||||
uint64_t start, uint64_t size);
|
||||
void del_das(struct list *das);
|
||||
|
||||
|
||||
@@ -129,6 +129,6 @@ struct volume_group *text_vg_import_file(struct format_instance *fid,
|
||||
const char *file,
|
||||
time_t *when, char **desc)
|
||||
{
|
||||
return text_vg_import_fd(fid, file, NULL, 0, 0, 0, 0, NULL, 0,
|
||||
return text_vg_import_fd(fid, file, NULL, (off_t)0, 0, (off_t)0, 0, NULL, 0,
|
||||
when, desc);
|
||||
}
|
||||
|
||||
@@ -83,6 +83,6 @@ struct mda_context {
|
||||
#define FMTT_VERSION 1
|
||||
#define MDA_HEADER_SIZE 512
|
||||
#define LVM2_LABEL "LVM2 001"
|
||||
#define MDA_SIZE_MIN (8 * (unsigned) getpagesize())
|
||||
#define MDA_SIZE_MIN (8 * (unsigned) lvm_getpagesize())
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
static int _text_can_handle(struct labeller *l, char *buf, uint64_t sector)
|
||||
static int _text_can_handle(struct labeller *l __attribute((unused)),
|
||||
char *buf,
|
||||
uint64_t sector __attribute((unused)))
|
||||
{
|
||||
struct label_header *lh = (struct label_header *) buf;
|
||||
|
||||
@@ -86,7 +88,7 @@ static int _text_write(struct label *label, char *buf)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int add_da(const struct format_type *fmt, struct dm_pool *mem, struct list *das,
|
||||
int add_da(struct dm_pool *mem, struct list *das,
|
||||
uint64_t start, uint64_t size)
|
||||
{
|
||||
struct data_area_list *dal;
|
||||
@@ -179,7 +181,8 @@ void del_mdas(struct list *mdas)
|
||||
}
|
||||
}
|
||||
|
||||
static int _text_initialise_label(struct labeller *l, struct label *label)
|
||||
static int _text_initialise_label(struct labeller *l __attribute((unused)),
|
||||
struct label *label)
|
||||
{
|
||||
strncpy(label->type, LVM2_LABEL, sizeof(label->type));
|
||||
|
||||
@@ -220,7 +223,7 @@ static int _text_read(struct labeller *l, struct device *dev, char *buf,
|
||||
/* Data areas holding the PEs */
|
||||
dlocn_xl = pvhdr->disk_areas_xl;
|
||||
while ((offset = xlate64(dlocn_xl->offset))) {
|
||||
add_da(info->fmt, NULL, &info->das, offset,
|
||||
add_da(NULL, &info->das, offset,
|
||||
xlate64(dlocn_xl->size));
|
||||
dlocn_xl++;
|
||||
}
|
||||
@@ -248,7 +251,8 @@ static int _text_read(struct labeller *l, struct device *dev, char *buf,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _text_destroy_label(struct labeller *l, struct label *label)
|
||||
static void _text_destroy_label(struct labeller *l __attribute((unused)),
|
||||
struct label *label)
|
||||
{
|
||||
struct lvmcache_info *info = (struct lvmcache_info *) label->info;
|
||||
|
||||
|
||||
@@ -271,7 +271,7 @@ int label_read(struct device *dev, struct label **result)
|
||||
lvmcache_update_vgname_and_id(info, ORPHAN, ORPHAN,
|
||||
0, NULL);
|
||||
|
||||
goto out;
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!(l = _find_labeller(dev, buf, §or)))
|
||||
|
||||
@@ -256,7 +256,7 @@ static int _cluster_request(char cmd, const char *node, void *data, int len,
|
||||
strcpy(rarray[i].node, inptr);
|
||||
inptr += strlen(inptr) + 1;
|
||||
|
||||
rarray[i].status = *(int *) inptr;
|
||||
memcpy(&rarray[i].status, inptr, sizeof(int));
|
||||
inptr += sizeof(int);
|
||||
|
||||
rarray[i].response = dm_malloc(strlen(inptr) + 1);
|
||||
@@ -333,6 +333,12 @@ static int _lock_for_cluster(unsigned char cmd, unsigned int flags, char *name)
|
||||
if (partial_mode())
|
||||
args[1] |= LCK_PARTIAL_MODE;
|
||||
|
||||
if (mirror_in_sync())
|
||||
args[1] |= LCK_MIRROR_NOSYNC_MODE;
|
||||
|
||||
if (dmeventd_register_mode())
|
||||
args[1] |= LCK_DMEVENTD_REGISTER_MODE;
|
||||
|
||||
/*
|
||||
* VG locks are just that: locks, and have no side effects
|
||||
* so we only need to do them on the local node because all
|
||||
@@ -392,9 +398,9 @@ int lock_resource(struct cmd_context *cmd, const char *resource, int flags)
|
||||
case LCK_VG:
|
||||
/* If the VG name is empty then lock the unused PVs */
|
||||
if (!*resource)
|
||||
lvm_snprintf(lockname, sizeof(lockname), "P_orphans");
|
||||
dm_snprintf(lockname, sizeof(lockname), "P_orphans");
|
||||
else
|
||||
lvm_snprintf(lockname, sizeof(lockname), "V_%s",
|
||||
dm_snprintf(lockname, sizeof(lockname), "V_%s",
|
||||
resource);
|
||||
|
||||
cluster_cmd = CLVMD_CMD_LOCK_VG;
|
||||
@@ -446,7 +452,7 @@ void reset_locking(void)
|
||||
}
|
||||
|
||||
#ifdef CLUSTER_LOCKING_INTERNAL
|
||||
int init_cluster_locking(struct locking_type *locking, struct config_tree *cft)
|
||||
int init_cluster_locking(struct locking_type *locking, struct cmd_context *cmd)
|
||||
{
|
||||
locking->lock_resource = _lock_resource;
|
||||
locking->fin_locking = _locking_end;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "locking_types.h"
|
||||
#include "defaults.h"
|
||||
#include "sharedlib.h"
|
||||
#include "toolcontext.h"
|
||||
|
||||
static void *_locking_lib = NULL;
|
||||
static void (*_reset_fn) (void) = NULL;
|
||||
@@ -55,7 +56,7 @@ static void _reset_external_locking(void)
|
||||
_reset_fn();
|
||||
}
|
||||
|
||||
int init_external_locking(struct locking_type *locking, struct config_tree *cft)
|
||||
int init_external_locking(struct locking_type *locking, struct cmd_context *cmd)
|
||||
{
|
||||
const char *libname;
|
||||
|
||||
@@ -69,10 +70,10 @@ int init_external_locking(struct locking_type *locking, struct config_tree *cft)
|
||||
locking->reset_locking = _reset_external_locking;
|
||||
locking->flags = 0;
|
||||
|
||||
libname = find_config_str(cft->root, "global/locking_library",
|
||||
DEFAULT_LOCKING_LIB);
|
||||
libname = find_config_tree_str(cmd, "global/locking_library",
|
||||
DEFAULT_LOCKING_LIB);
|
||||
|
||||
if (!(_locking_lib = load_shared_library(cft, libname, "locking", 1))) {
|
||||
if (!(_locking_lib = load_shared_library(cmd, libname, "locking", 1))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -90,5 +91,5 @@ int init_external_locking(struct locking_type *locking, struct config_tree *cft)
|
||||
}
|
||||
|
||||
log_verbose("Loaded external locking library %s", libname);
|
||||
return _init_fn(2, cft, &locking->flags);
|
||||
return _init_fn(2, cmd->cft, &locking->flags);
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ static void _remove_ctrl_c_handler()
|
||||
log_sys_error("signal", "_remove_ctrl_c_handler");
|
||||
}
|
||||
|
||||
static void _trap_ctrl_c(int sig)
|
||||
static void _trap_ctrl_c(int sig __attribute((unused)))
|
||||
{
|
||||
_remove_ctrl_c_handler();
|
||||
log_error("CTRL-c detected: giving up waiting for lock");
|
||||
@@ -212,10 +212,10 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
|
||||
switch (flags & LCK_SCOPE_MASK) {
|
||||
case LCK_VG:
|
||||
if (!*resource)
|
||||
lvm_snprintf(lockfile, sizeof(lockfile),
|
||||
dm_snprintf(lockfile, sizeof(lockfile),
|
||||
"%s/P_orphans", _lock_dir);
|
||||
else
|
||||
lvm_snprintf(lockfile, sizeof(lockfile),
|
||||
dm_snprintf(lockfile, sizeof(lockfile),
|
||||
"%s/V_%s", _lock_dir, resource);
|
||||
|
||||
if (!_lock_file(lockfile, flags))
|
||||
@@ -271,7 +271,7 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int init_file_locking(struct locking_type *locking, struct config_tree *cft)
|
||||
int init_file_locking(struct locking_type *locking, struct cmd_context *cmd)
|
||||
{
|
||||
locking->lock_resource = _file_lock_resource;
|
||||
locking->reset_locking = _reset_file_locking;
|
||||
@@ -279,8 +279,8 @@ int init_file_locking(struct locking_type *locking, struct config_tree *cft)
|
||||
locking->flags = 0;
|
||||
|
||||
/* Get lockfile directory from config file */
|
||||
strncpy(_lock_dir, find_config_str(cft->root, "global/locking_dir",
|
||||
DEFAULT_LOCK_DIR),
|
||||
strncpy(_lock_dir, find_config_tree_str(cmd, "global/locking_dir",
|
||||
DEFAULT_LOCK_DIR),
|
||||
sizeof(_lock_dir));
|
||||
|
||||
if (!create_dir(_lock_dir))
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "activate.h"
|
||||
#include "toolcontext.h"
|
||||
#include "memlock.h"
|
||||
#include "defaults.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -33,7 +34,7 @@ static int _vg_lock_count = 0; /* Number of locks held */
|
||||
static int _vg_write_lock_held = 0; /* VG write lock held? */
|
||||
static int _signals_blocked = 0;
|
||||
|
||||
static void _block_signals(int flags)
|
||||
static void _block_signals(int flags __attribute((unused)))
|
||||
{
|
||||
sigset_t set;
|
||||
|
||||
@@ -122,36 +123,43 @@ static void _update_vg_lock_count(int flags)
|
||||
/*
|
||||
* Select a locking type
|
||||
*/
|
||||
int init_locking(int type, struct config_tree *cft)
|
||||
int init_locking(int type, struct cmd_context *cmd)
|
||||
{
|
||||
init_lockingfailed(0);
|
||||
|
||||
switch (type) {
|
||||
case 0:
|
||||
init_no_locking(&_locking, cft);
|
||||
init_no_locking(&_locking, cmd);
|
||||
log_print("WARNING: Locking disabled. Be careful! "
|
||||
"This could corrupt your metadata.");
|
||||
return 1;
|
||||
|
||||
case 1:
|
||||
if (!init_file_locking(&_locking, cft))
|
||||
log_very_verbose("File-based locking selected.");
|
||||
if (!init_file_locking(&_locking, cmd))
|
||||
break;
|
||||
log_very_verbose("File-based locking enabled.");
|
||||
return 1;
|
||||
|
||||
#ifdef HAVE_LIBDL
|
||||
case 2:
|
||||
if (!init_external_locking(&_locking, cft))
|
||||
if (!cmd->is_static) {
|
||||
log_very_verbose("External locking selected.");
|
||||
if (!init_external_locking(&_locking, cmd))
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
if (!find_config_tree_int(cmd, "locking/fallback_to_clustered_locking",
|
||||
DEFAULT_FALLBACK_TO_CLUSTERED_LOCKING))
|
||||
break;
|
||||
log_very_verbose("External locking enabled.");
|
||||
return 1;
|
||||
log_very_verbose("Falling back to clustered locking.");
|
||||
/* Fall through */
|
||||
#endif
|
||||
|
||||
#ifdef CLUSTER_LOCKING_INTERNAL
|
||||
case 3:
|
||||
if (!init_cluster_locking(&_locking, cft))
|
||||
log_very_verbose("Cluster locking selected.");
|
||||
if (!init_cluster_locking(&_locking, cmd))
|
||||
break;
|
||||
log_very_verbose("Cluster locking enabled.");
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
@@ -160,13 +168,23 @@ int init_locking(int type, struct config_tree *cft)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((type == 2 || type == 3) &&
|
||||
find_config_tree_int(cmd, "locking/fallback_to_local_locking",
|
||||
DEFAULT_FALLBACK_TO_LOCAL_LOCKING)) {
|
||||
log_print("WARNING: Falling back to local file-based locking.");
|
||||
log_print("Volume Groups with the clustered attribute will "
|
||||
"be inaccessible.");
|
||||
if (init_file_locking(&_locking, cmd))
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!ignorelockingfailure())
|
||||
return 0;
|
||||
|
||||
/* FIXME Ensure only read ops are permitted */
|
||||
log_verbose("Locking disabled - only read operations permitted.");
|
||||
|
||||
init_no_locking(&_locking, cft);
|
||||
init_no_locking(&_locking, cmd);
|
||||
init_lockingfailed(1);
|
||||
|
||||
return 1;
|
||||
@@ -189,7 +207,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname)
|
||||
if (!*vgname)
|
||||
return 1;
|
||||
|
||||
if (lvm_snprintf(path, sizeof(path), "%s/lvm/VGs/%s", cmd->proc_dir,
|
||||
if (dm_snprintf(path, sizeof(path), "%s/lvm/VGs/%s", cmd->proc_dir,
|
||||
vgname) < 0) {
|
||||
log_error("LVM1 proc VG pathname too long for %s", vgname);
|
||||
return 0;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "uuid.h"
|
||||
#include "config.h"
|
||||
|
||||
int init_locking(int type, struct config_tree *cf);
|
||||
int init_locking(int type, struct cmd_context *cmd);
|
||||
void fin_locking(void);
|
||||
void reset_locking(void);
|
||||
int vg_write_lock_held(void);
|
||||
@@ -74,6 +74,9 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
|
||||
* Additional lock bits for cluster communication
|
||||
*/
|
||||
#define LCK_PARTIAL_MODE 0x00000001 /* Running in partial mode */
|
||||
#define LCK_MIRROR_NOSYNC_MODE 0x00000002 /* Mirrors don't require sync */
|
||||
#define LCK_DMEVENTD_REGISTER_MODE 0x00000004 /* Register with dmeventd */
|
||||
|
||||
|
||||
/*
|
||||
* Common combinations
|
||||
|
||||
@@ -36,10 +36,10 @@ struct locking_type {
|
||||
/*
|
||||
* Locking types
|
||||
*/
|
||||
int init_no_locking(struct locking_type *locking, struct config_tree *cf);
|
||||
int init_no_locking(struct locking_type *locking, struct cmd_context *cmd);
|
||||
|
||||
int init_file_locking(struct locking_type *locking, struct config_tree *cf);
|
||||
int init_file_locking(struct locking_type *locking, struct cmd_context *cmd);
|
||||
|
||||
int init_external_locking(struct locking_type *locking, struct config_tree *cf);
|
||||
int init_external_locking(struct locking_type *locking, struct cmd_context *cmd);
|
||||
|
||||
int init_cluster_locking(struct locking_type *locking, struct config_tree *cf);
|
||||
int init_cluster_locking(struct locking_type *locking, struct cmd_context *cmd);
|
||||
|
||||
@@ -76,7 +76,7 @@ static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int init_no_locking(struct locking_type *locking, struct config_tree *cft)
|
||||
int init_no_locking(struct locking_type *locking, struct cmd_context *cmd)
|
||||
{
|
||||
locking->lock_resource = _no_lock_resource;
|
||||
locking->reset_locking = _no_reset_locking;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "device.h"
|
||||
#include "memlock.h"
|
||||
#include "lvm-string.h"
|
||||
#include "defaults.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <syslog.h>
|
||||
@@ -31,6 +32,7 @@ static int _partial = 0;
|
||||
static int _md_filtering = 0;
|
||||
static int _pvmove = 0;
|
||||
static int _full_scan_done = 0; /* Restrict to one full scan during each cmd */
|
||||
static int _trust_cache = 0; /* Don't scan when incomplete VGs encountered */
|
||||
static int _debug_level = 0;
|
||||
static int _syslog = 0;
|
||||
static int _log_to_file = 0;
|
||||
@@ -45,6 +47,8 @@ static int _security_level = SECURITY_LEVEL;
|
||||
static char _cmd_name[30] = "";
|
||||
static char _msg_prefix[30] = " ";
|
||||
static int _already_logging = 0;
|
||||
static int _mirror_in_sync = 0;
|
||||
static int _dmeventd_register = DEFAULT_DMEVENTD_MONITOR;
|
||||
|
||||
static lvm2_log_fn_t _lvm2_log_fn = NULL;
|
||||
|
||||
@@ -160,6 +164,11 @@ void init_full_scan_done(int level)
|
||||
_full_scan_done = level;
|
||||
}
|
||||
|
||||
void init_trust_cache(int trustcache)
|
||||
{
|
||||
_trust_cache = trustcache;
|
||||
}
|
||||
|
||||
void init_ignorelockingfailure(int level)
|
||||
{
|
||||
_ignorelockingfailure = level;
|
||||
@@ -175,6 +184,16 @@ void init_security_level(int level)
|
||||
_security_level = level;
|
||||
}
|
||||
|
||||
void init_mirror_in_sync(int in_sync)
|
||||
{
|
||||
_mirror_in_sync = in_sync;
|
||||
}
|
||||
|
||||
void init_dmeventd_register(int reg)
|
||||
{
|
||||
_dmeventd_register = reg;
|
||||
}
|
||||
|
||||
void init_cmd_name(int status)
|
||||
{
|
||||
_log_cmd_name = status;
|
||||
@@ -224,6 +243,11 @@ int full_scan_done()
|
||||
return _full_scan_done;
|
||||
}
|
||||
|
||||
int trust_cache()
|
||||
{
|
||||
return _trust_cache;
|
||||
}
|
||||
|
||||
int lockingfailed()
|
||||
{
|
||||
return _lockingfailed;
|
||||
@@ -239,6 +263,16 @@ int security_level()
|
||||
return _security_level;
|
||||
}
|
||||
|
||||
int mirror_in_sync(void)
|
||||
{
|
||||
return _mirror_in_sync;
|
||||
}
|
||||
|
||||
int dmeventd_register_mode(void)
|
||||
{
|
||||
return _dmeventd_register;
|
||||
}
|
||||
|
||||
void init_debug(int level)
|
||||
{
|
||||
_debug_level = level;
|
||||
@@ -284,7 +318,7 @@ void print_log(int level, const char *file, int line, const char *format, ...)
|
||||
log_it:
|
||||
if (!_log_suppress) {
|
||||
if (_verbose_level > _LOG_DEBUG)
|
||||
lvm_snprintf(locn, sizeof(locn), "#%s:%d ",
|
||||
dm_snprintf(locn, sizeof(locn), "#%s:%d ",
|
||||
file, line);
|
||||
else
|
||||
locn[0] = '\0';
|
||||
@@ -379,7 +413,7 @@ void print_log(int level, const char *file, int line, const char *format, ...)
|
||||
_already_logging = 1;
|
||||
memset(&buf, ' ', sizeof(buf));
|
||||
bufused = 0;
|
||||
if ((n = lvm_snprintf(buf, sizeof(buf) - bufused - 1,
|
||||
if ((n = dm_snprintf(buf, sizeof(buf) - bufused - 1,
|
||||
"%s:%d %s%s", file, line, _cmd_name,
|
||||
_msg_prefix)) == -1)
|
||||
goto done;
|
||||
|
||||
@@ -66,6 +66,7 @@ void init_partial(int level);
|
||||
void init_md_filtering(int level);
|
||||
void init_pvmove(int level);
|
||||
void init_full_scan_done(int level);
|
||||
void init_trust_cache(int trustcache);
|
||||
void init_debug(int level);
|
||||
void init_cmd_name(int status);
|
||||
void init_msg_prefix(const char *prefix);
|
||||
@@ -73,6 +74,8 @@ void init_indent(int indent);
|
||||
void init_ignorelockingfailure(int level);
|
||||
void init_lockingfailed(int level);
|
||||
void init_security_level(int level);
|
||||
void init_mirror_in_sync(int in_sync);
|
||||
void init_dmeventd_register(int reg);
|
||||
|
||||
void set_cmd_name(const char *cmd_name);
|
||||
|
||||
@@ -81,10 +84,13 @@ int partial_mode(void);
|
||||
int md_filtering(void);
|
||||
int pvmove_mode(void);
|
||||
int full_scan_done(void);
|
||||
int trust_cache(void);
|
||||
int debug_level(void);
|
||||
int ignorelockingfailure(void);
|
||||
int lockingfailed(void);
|
||||
int security_level(void);
|
||||
int mirror_in_sync(void);
|
||||
int dmeventd_register_mode(void);
|
||||
|
||||
/* Suppress messages to stdout/stderr (1) or everywhere (2) */
|
||||
/* Returns previous setting */
|
||||
|
||||
@@ -158,7 +158,7 @@ void release_lv_segment_area(struct lv_segment *seg, uint32_t s,
|
||||
}
|
||||
|
||||
if (seg_lv(seg, s)->status & MIRROR_IMAGE) {
|
||||
lv_reduce(seg_lv(seg, s), area_reduction);
|
||||
lv_reduce(seg_lv(seg, s), area_reduction);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -490,6 +490,49 @@ void alloc_destroy(struct alloc_handle *ah)
|
||||
dm_pool_destroy(ah->mem);
|
||||
}
|
||||
|
||||
static int _log_parallel_areas(struct dm_pool *mem, struct list *parallel_areas)
|
||||
{
|
||||
struct seg_pvs *spvs;
|
||||
struct pv_list *pvl;
|
||||
char *pvnames;
|
||||
|
||||
if (!parallel_areas)
|
||||
return 1;
|
||||
|
||||
if (!dm_pool_begin_object(mem, 256)) {
|
||||
log_error("dm_pool_begin_object failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
list_iterate_items(spvs, parallel_areas) {
|
||||
list_iterate_items(pvl, &spvs->pvs) {
|
||||
if (!dm_pool_grow_object(mem, dev_name(pvl->pv->dev), strlen(dev_name(pvl->pv->dev)))) {
|
||||
log_error("dm_pool_grow_object failed");
|
||||
dm_pool_abandon_object(mem);
|
||||
return 0;
|
||||
}
|
||||
if (!dm_pool_grow_object(mem, " ", 1)) {
|
||||
log_error("dm_pool_grow_object failed");
|
||||
dm_pool_abandon_object(mem);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dm_pool_grow_object(mem, "\0", 1)) {
|
||||
log_error("dm_pool_grow_object failed");
|
||||
dm_pool_abandon_object(mem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pvnames = dm_pool_end_object(mem);
|
||||
log_debug("Parallel PVs at LE %" PRIu32 " length %" PRIu32 ": %s",
|
||||
spvs->le, spvs->len, pvnames);
|
||||
dm_pool_free(mem, pvnames);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _setup_alloced_segment(struct logical_volume *lv, uint32_t status,
|
||||
uint32_t area_count,
|
||||
uint32_t stripe_size,
|
||||
@@ -498,7 +541,7 @@ static int _setup_alloced_segment(struct logical_volume *lv, uint32_t status,
|
||||
struct physical_volume *mirrored_pv,
|
||||
uint32_t mirrored_pe,
|
||||
uint32_t region_size,
|
||||
struct logical_volume *log_lv)
|
||||
struct logical_volume *log_lv __attribute((unused)))
|
||||
{
|
||||
uint32_t s, extents, area_multiple, extra_areas = 0;
|
||||
struct lv_segment *seg;
|
||||
@@ -614,7 +657,7 @@ static int _alloc_parallel_area(struct alloc_handle *ah, uint32_t needed,
|
||||
if (log_area) {
|
||||
ah->log_area.pv = log_area->map->pv;
|
||||
ah->log_area.pe = log_area->start;
|
||||
ah->log_area.len = 1; /* FIXME Calculate & check this */
|
||||
ah->log_area.len = MIRROR_LOG_SIZE; /* FIXME Calculate & check this */
|
||||
consume_pv_area(log_area, ah->log_area.len);
|
||||
}
|
||||
|
||||
@@ -642,14 +685,21 @@ static int _comp_area(const void *l, const void *r)
|
||||
*/
|
||||
static int _check_contiguous(struct lv_segment *prev_lvseg,
|
||||
struct physical_volume *pv, struct pv_area *pva,
|
||||
struct pv_area **areas)
|
||||
struct pv_area **areas, uint32_t areas_size)
|
||||
{
|
||||
struct pv_segment *prev_pvseg;
|
||||
struct lv_segment *lastseg;
|
||||
uint32_t s;
|
||||
|
||||
for (s = 0; s < prev_lvseg->area_count; s++) {
|
||||
if (seg_type(prev_lvseg, s) != AREA_PV)
|
||||
continue; /* FIXME Broken */
|
||||
for (s = 0; s < prev_lvseg->area_count && s < areas_size; s++) {
|
||||
if (seg_type(prev_lvseg, s) == AREA_LV) {
|
||||
lastseg = list_item(list_last(&seg_lv(prev_lvseg, s)->segments), struct lv_segment);
|
||||
/* FIXME For more areas supply flattened prev_lvseg to ensure consistency */
|
||||
if (lastseg->area_count == 1 &&
|
||||
_check_contiguous(lastseg, pv, pva, &areas[s], 1))
|
||||
return 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(prev_pvseg = seg_pvseg(prev_lvseg, s)))
|
||||
continue; /* FIXME Broken */
|
||||
@@ -711,14 +761,15 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
|
||||
* the maximum we can allocate in one go accordingly.
|
||||
*/
|
||||
if (ah->parallel_areas) {
|
||||
next_le = (prev_lvseg ? prev_lvseg->le + prev_lvseg->len : 0) + *allocated / ah->area_multiple;
|
||||
list_iterate_items(spvs, ah->parallel_areas) {
|
||||
next_le = (prev_lvseg ? prev_lvseg->le + prev_lvseg->len : 0) + *allocated;
|
||||
if (next_le >= spvs->le) {
|
||||
if (next_le + max_parallel > spvs->le + spvs->len)
|
||||
max_parallel = (spvs->le + spvs->len - next_le) * ah->area_multiple;
|
||||
parallel_pvs = &spvs->pvs;
|
||||
break;
|
||||
}
|
||||
if (next_le >= spvs->le + spvs->len)
|
||||
continue;
|
||||
|
||||
if (max_parallel > (spvs->le + spvs->len) * ah->area_multiple)
|
||||
max_parallel = (spvs->le + spvs->len) * ah->area_multiple;
|
||||
parallel_pvs = &spvs->pvs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -752,7 +803,8 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
|
||||
if (prev_lvseg &&
|
||||
_check_contiguous(prev_lvseg,
|
||||
pvm->pv,
|
||||
pva, areas)) {
|
||||
pva, areas,
|
||||
areas_size)) {
|
||||
contiguous_count++;
|
||||
goto next_pv;
|
||||
}
|
||||
@@ -760,7 +812,8 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
|
||||
}
|
||||
|
||||
/* Is it big enough on its own? */
|
||||
if ((pva->count < max_parallel - *allocated) &&
|
||||
if (pva->count * ah->area_multiple <
|
||||
max_parallel - *allocated &&
|
||||
((!can_split && !ah->log_count) ||
|
||||
(already_found_one &&
|
||||
!(alloc == ALLOC_ANYWHERE))))
|
||||
@@ -853,6 +906,9 @@ static int _allocate(struct alloc_handle *ah,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_log_parallel_areas(ah->mem, ah->parallel_areas))
|
||||
stack;
|
||||
|
||||
areas_size = list_size(pvms);
|
||||
if (areas_size < ah->area_count + ah->log_count) {
|
||||
if (ah->alloc != ALLOC_ANYWHERE) {
|
||||
@@ -1102,7 +1158,7 @@ int lv_add_mirror_segment(struct alloc_handle *ah,
|
||||
struct lv_segment *seg;
|
||||
uint32_t m;
|
||||
|
||||
if (list_empty(&log_lv->segments)) {
|
||||
if (log_lv && list_empty(&log_lv->segments)) {
|
||||
log_error("Log LV %s is empty.", log_lv->name);
|
||||
return 0;
|
||||
}
|
||||
@@ -1213,7 +1269,7 @@ int lv_extend(struct logical_volume *lv,
|
||||
log_error("Aborting. Failed to extend %s.",
|
||||
seg_lv(seg, m)->name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
seg->area_len += extents;
|
||||
seg->len += extents;
|
||||
@@ -1240,7 +1296,7 @@ char *generate_lv_name(struct volume_group *vg, const char *format,
|
||||
high = i;
|
||||
}
|
||||
|
||||
if (lvm_snprintf(buffer, len, format, high + 1) < 0)
|
||||
if (dm_snprintf(buffer, len, format, high + 1) < 0)
|
||||
return NULL;
|
||||
|
||||
return buffer;
|
||||
@@ -1326,11 +1382,15 @@ struct logical_volume *lv_create_empty(struct format_instance *fi,
|
||||
return lv;
|
||||
}
|
||||
|
||||
/* Recursively process each PV used by part of an LV */
|
||||
/*
|
||||
* Call fn for each AREA_PV used by the LV segment at lv:le of length *max_seg_len.
|
||||
* If any constituent area contains more than one segment, max_seg_len is
|
||||
* reduced to cover only the first.
|
||||
*/
|
||||
static int _for_each_pv(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
uint32_t le, uint32_t len,
|
||||
int (*fn)(struct cmd_context *cmd, struct pv_segment *peg, struct seg_pvs *spvs),
|
||||
struct seg_pvs *spvs)
|
||||
uint32_t le, uint32_t len, uint32_t *max_seg_len,
|
||||
int (*fn)(struct cmd_context *cmd, struct pv_segment *peg, void *data),
|
||||
void *data)
|
||||
{
|
||||
struct lv_segment *seg;
|
||||
uint32_t s;
|
||||
@@ -1345,39 +1405,44 @@ static int _for_each_pv(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
/* Remaining logical length of segment */
|
||||
remaining_seg_len = seg->len - (le - seg->le);
|
||||
|
||||
if (len > remaining_seg_len)
|
||||
if (remaining_seg_len > len)
|
||||
remaining_seg_len = len;
|
||||
|
||||
if (spvs->len > remaining_seg_len)
|
||||
spvs->len = remaining_seg_len;
|
||||
if (max_seg_len && *max_seg_len > remaining_seg_len)
|
||||
*max_seg_len = remaining_seg_len;
|
||||
|
||||
area_multiple = segtype_is_striped(seg->segtype) ? seg->area_count : 1;
|
||||
area_len = remaining_seg_len / area_multiple;
|
||||
area_len = remaining_seg_len / area_multiple ? : 1;
|
||||
|
||||
for (s = 0; s < seg->area_count; s++) {
|
||||
for (s = 0; s < seg->area_count; s++)
|
||||
if (seg_type(seg, s) == AREA_LV) {
|
||||
if (!_for_each_pv(cmd, seg_lv(seg, s),
|
||||
seg_le(seg, s) + (le - seg->le) / area_multiple,
|
||||
area_len, fn, spvs)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
} else if (seg_type(seg, s) == AREA_PV) {
|
||||
if (!fn(cmd, seg_pvseg(seg, s), spvs)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
area_len, max_seg_len, fn, data))
|
||||
return_0;
|
||||
} else if ((seg_type(seg, s) == AREA_PV) &&
|
||||
!fn(cmd, seg_pvseg(seg, s), data))
|
||||
return_0;
|
||||
|
||||
if (seg_is_mirrored(seg) &&
|
||||
!_for_each_pv(cmd, seg->log_lv, 0, MIRROR_LOG_SIZE,
|
||||
NULL, fn, data))
|
||||
return_0;
|
||||
|
||||
/* FIXME Add snapshot cow LVs etc. */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _add_pvs(struct cmd_context *cmd, struct pv_segment *peg, struct seg_pvs *spvs)
|
||||
static int _add_pvs(struct cmd_context *cmd, struct pv_segment *peg, void *data)
|
||||
{
|
||||
struct seg_pvs *spvs = (struct seg_pvs *) data;
|
||||
struct pv_list *pvl;
|
||||
|
||||
/* FIXME Don't add again if it's already on the list! */
|
||||
/* Don't add again if it's already on list. */
|
||||
list_iterate_items(pvl, &spvs->pvs)
|
||||
if (pvl->pv == peg->pv)
|
||||
return 1;
|
||||
|
||||
if (!(pvl = dm_pool_alloc(cmd->mem, sizeof(*pvl)))) {
|
||||
log_error("pv_list allocation failed");
|
||||
@@ -1386,11 +1451,8 @@ static int _add_pvs(struct cmd_context *cmd, struct pv_segment *peg, struct seg_
|
||||
|
||||
pvl->pv = peg->pv;
|
||||
|
||||
/* FIXME Use ordered list to facilitate comparison */
|
||||
list_add(&spvs->pvs, &pvl->list);
|
||||
|
||||
/* FIXME Add mirror logs, snapshot cow LVs etc. */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1426,7 +1488,7 @@ struct list *build_parallel_areas_from_lv(struct cmd_context *cmd,
|
||||
|
||||
/* Find next segment end */
|
||||
/* FIXME Unnecessary nesting! */
|
||||
if (!_for_each_pv(cmd, lv, current_le, lv->le_count, _add_pvs, spvs)) {
|
||||
if (!_for_each_pv(cmd, lv, current_le, spvs->len, &spvs->len, _add_pvs, (void *) spvs)) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,13 @@
|
||||
#include "pv_alloc.h"
|
||||
#include "activate.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
unsigned long pe_align(void)
|
||||
{
|
||||
return MAX(65536UL, lvm_getpagesize()) >> SECTOR_SHIFT;
|
||||
}
|
||||
|
||||
static int _add_pv_to_vg(struct format_instance *fid, struct volume_group *vg,
|
||||
const char *pv_name)
|
||||
{
|
||||
@@ -60,7 +67,7 @@ static int _add_pv_to_vg(struct format_instance *fid, struct volume_group *vg,
|
||||
}
|
||||
|
||||
/* Ensure PV doesn't depend on another PV already in the VG */
|
||||
if (pv_uses_vg(fid->fmt->cmd, pv, vg)) {
|
||||
if (pv_uses_vg(pv, vg)) {
|
||||
log_error("Physical volume %s might be constructed from same "
|
||||
"volume group %s", pv_name, vg->name);
|
||||
return 0;
|
||||
@@ -78,8 +85,8 @@ static int _add_pv_to_vg(struct format_instance *fid, struct volume_group *vg,
|
||||
|
||||
/* FIXME Do proper rounding-up alignment? */
|
||||
/* Reserved space for label; this holds 0 for PVs created by LVM1 */
|
||||
if (pv->pe_start < PE_ALIGN)
|
||||
pv->pe_start = PE_ALIGN;
|
||||
if (pv->pe_start < pe_align())
|
||||
pv->pe_start = pe_align();
|
||||
|
||||
/*
|
||||
* The next two fields should be corrected
|
||||
@@ -722,23 +729,68 @@ int vg_remove(struct volume_group *vg)
|
||||
|
||||
int vg_validate(struct volume_group *vg)
|
||||
{
|
||||
struct lv_list *lvl;
|
||||
struct pv_list *pvl, *pvl2;
|
||||
struct lv_list *lvl, *lvl2;
|
||||
char uuid[64];
|
||||
int r = 1;
|
||||
|
||||
list_iterate_items(pvl, &vg->pvs) {
|
||||
list_iterate_items(pvl2, &vg->pvs) {
|
||||
if (pvl == pvl2)
|
||||
break;
|
||||
if (id_equal(&pvl->pv->id,
|
||||
&pvl2->pv->id)) {
|
||||
if (!id_write_format(&pvl->pv->id, uuid,
|
||||
sizeof(uuid)))
|
||||
stack;
|
||||
log_error("Internal error: Duplicate PV id "
|
||||
"%s detected for %s in %s.",
|
||||
uuid, dev_name(pvl->pv->dev),
|
||||
vg->name);
|
||||
r = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!check_pv_segments(vg)) {
|
||||
log_error("Internal error: PV segments corrupted in %s.",
|
||||
vg->name);
|
||||
return 0;
|
||||
r = 0;
|
||||
}
|
||||
|
||||
list_iterate_items(lvl, &vg->lvs) {
|
||||
list_iterate_items(lvl2, &vg->lvs) {
|
||||
if (lvl == lvl2)
|
||||
break;
|
||||
if (!strcmp(lvl->lv->name, lvl2->lv->name)) {
|
||||
log_error("Internal error: Duplicate LV name "
|
||||
"%s detected in %s.", lvl->lv->name,
|
||||
vg->name);
|
||||
r = 0;
|
||||
}
|
||||
if (id_equal(&lvl->lv->lvid.id[1],
|
||||
&lvl2->lv->lvid.id[1])) {
|
||||
if (!id_write_format(&lvl->lv->lvid.id[1], uuid,
|
||||
sizeof(uuid)))
|
||||
stack;
|
||||
log_error("Internal error: Duplicate LV id "
|
||||
"%s detected for %s and %s in %s.",
|
||||
uuid, lvl->lv->name, lvl2->lv->name,
|
||||
vg->name);
|
||||
r = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list_iterate_items(lvl, &vg->lvs) {
|
||||
if (!check_lv_segments(lvl->lv, 1)) {
|
||||
log_error("Internal error: LV segments corrupted in %s.",
|
||||
lvl->lv->name);
|
||||
return 0;
|
||||
r = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -993,7 +1045,11 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
|
||||
if (list_size(&correct_vg->pvs) != list_size(pvids)) {
|
||||
log_debug("Cached VG %s had incorrect PV list",
|
||||
vg->name);
|
||||
correct_vg = NULL;
|
||||
|
||||
if (memlock())
|
||||
inconsistent = 1;
|
||||
else
|
||||
correct_vg = NULL;
|
||||
} else list_iterate_items(pvl, &correct_vg->pvs) {
|
||||
if (!str_list_match_item(pvids, pvl->pv->dev->pvid)) {
|
||||
log_debug("Cached VG %s had incorrect PV list",
|
||||
@@ -1008,6 +1064,10 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
|
||||
if (!correct_vg) {
|
||||
inconsistent = 0;
|
||||
|
||||
if (memlock()) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
lvmcache_label_scan(cmd, 2);
|
||||
if (!(fmt = fmt_from_vgname(vgname, vgid))) {
|
||||
stack;
|
||||
@@ -1149,7 +1209,8 @@ static struct volume_group *_vg_read_by_vgid(struct cmd_context *cmd,
|
||||
if (!consistent) {
|
||||
log_error("Volume group %s metadata is "
|
||||
"inconsistent", vginfo->vgname);
|
||||
return NULL;
|
||||
if (!partial_mode())
|
||||
return NULL;
|
||||
}
|
||||
return vg;
|
||||
}
|
||||
@@ -1342,7 +1403,7 @@ struct list *get_pvs(struct cmd_context *cmd)
|
||||
return results;
|
||||
}
|
||||
|
||||
int pv_write(struct cmd_context *cmd, struct physical_volume *pv,
|
||||
int pv_write(struct cmd_context *cmd __attribute((unused)), struct physical_volume *pv,
|
||||
struct list *mdas, int64_t label_sector)
|
||||
{
|
||||
if (!pv->fmt->ops->pv_write) {
|
||||
|
||||
@@ -29,12 +29,12 @@
|
||||
#define MAX_STRIPES 128U
|
||||
#define SECTOR_SHIFT 9L
|
||||
#define SECTOR_SIZE ( 1L << SECTOR_SHIFT )
|
||||
#define STRIPE_SIZE_MIN ( (unsigned) getpagesize() >> SECTOR_SHIFT) /* PAGESIZE in sectors */
|
||||
#define STRIPE_SIZE_MIN ( (unsigned) lvm_getpagesize() >> SECTOR_SHIFT) /* PAGESIZE in sectors */
|
||||
#define STRIPE_SIZE_MAX ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
|
||||
#define STRIPE_SIZE_LIMIT ((UINT_MAX >> 2) + 1)
|
||||
#define PV_MIN_SIZE ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
|
||||
#define PE_ALIGN (65536UL >> SECTOR_SHIFT) /* PE alignment */
|
||||
#define MAX_RESTRICTED_LVS 255 /* Used by FMT_RESTRICTED_LVIDS */
|
||||
#define MIRROR_LOG_SIZE 1 /* Extents */
|
||||
|
||||
/* Various flags */
|
||||
/* Note that the bits no longer necessarily correspond to LVM1 disk format */
|
||||
@@ -58,8 +58,9 @@
|
||||
#define VIRTUAL 0x00010000U /* LV - internal use only */
|
||||
#define MIRROR_LOG 0x00020000U /* LV */
|
||||
#define MIRROR_IMAGE 0x00040000U /* LV */
|
||||
#define ACTIVATE_EXCL 0x00080000U /* LV - internal use only */
|
||||
#define PRECOMMITTED 0x00100000U /* VG - internal use only */
|
||||
#define MIRROR_NOTSYNCED 0x00080000U /* LV */
|
||||
#define ACTIVATE_EXCL 0x00100000U /* LV - internal use only */
|
||||
#define PRECOMMITTED 0x00200000U /* VG - internal use only */
|
||||
|
||||
#define LVM_READ 0x00000100U /* LV VG */
|
||||
#define LVM_WRITE 0x00000200U /* LV VG */
|
||||
@@ -402,6 +403,7 @@ struct format_handler {
|
||||
/*
|
||||
* Utility functions
|
||||
*/
|
||||
unsigned long pe_align(void);
|
||||
int vg_validate(struct volume_group *vg);
|
||||
int vg_write(struct volume_group *vg);
|
||||
int vg_commit(struct volume_group *vg);
|
||||
@@ -580,6 +582,8 @@ int add_mirror_layers(struct alloc_handle *ah,
|
||||
|
||||
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
|
||||
struct list *removable_pvs, int remove_log);
|
||||
int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
|
||||
struct list *removable_pvs, int remove_log);
|
||||
/*
|
||||
* Given mirror image or mirror log segment, find corresponding mirror segment
|
||||
*/
|
||||
|
||||
@@ -23,6 +23,13 @@
|
||||
#include "lvm-string.h"
|
||||
#include "locking.h" /* FIXME Should not be used in this file */
|
||||
|
||||
#include "defaults.h" /* FIXME: should this be defaults.h? */
|
||||
|
||||
/* These are the flags that represent the mirror failure restoration policies */
|
||||
#define MIRROR_REMOVE 0
|
||||
#define MIRROR_ALLOCATE 1
|
||||
#define MIRROR_ALLOCATE_ANYWHERE 2
|
||||
|
||||
struct lv_segment *find_mirror_seg(struct lv_segment *seg)
|
||||
{
|
||||
return seg->mirror_seg;
|
||||
@@ -192,6 +199,12 @@ int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
|
||||
|
||||
/* Delete the 'orphan' LVs */
|
||||
for (m = num_mirrors; m < old_area_count; m++) {
|
||||
/* LV is now independent of the mirror so must acquire lock. */
|
||||
if (!activate_lv(mirrored_seg->lv->vg->cmd, seg_lv(mirrored_seg, m))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!deactivate_lv(mirrored_seg->lv->vg->cmd, seg_lv(mirrored_seg, m))) {
|
||||
stack;
|
||||
return 0;
|
||||
@@ -204,6 +217,11 @@ int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
|
||||
}
|
||||
|
||||
if (lv1) {
|
||||
if (!activate_lv(mirrored_seg->lv->vg->cmd, lv1)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!deactivate_lv(mirrored_seg->lv->vg->cmd, lv1)) {
|
||||
stack;
|
||||
return 0;
|
||||
@@ -216,6 +234,11 @@ int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
|
||||
}
|
||||
|
||||
if (log_lv) {
|
||||
if (!activate_lv(mirrored_seg->lv->vg->cmd, log_lv)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!deactivate_lv(mirrored_seg->lv->vg->cmd, log_lv)) {
|
||||
stack;
|
||||
return 0;
|
||||
@@ -230,6 +253,163 @@ int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int get_mirror_fault_policy(struct cmd_context *cmd, int log_policy)
|
||||
{
|
||||
const char *policy;
|
||||
|
||||
if (log_policy)
|
||||
policy = find_config_str(NULL, "activation/mirror_log_fault_policy",
|
||||
DEFAULT_MIRROR_LOG_FAULT_POLICY);
|
||||
else
|
||||
policy = find_config_str(NULL, "activation/mirror_device_fault_policy",
|
||||
DEFAULT_MIRROR_DEV_FAULT_POLICY);
|
||||
|
||||
if (!strcmp(policy, "remove"))
|
||||
return MIRROR_REMOVE;
|
||||
else if (!strcmp(policy, "allocate"))
|
||||
return MIRROR_ALLOCATE;
|
||||
else if (!strcmp(policy, "allocate_anywhere"))
|
||||
return MIRROR_ALLOCATE_ANYWHERE;
|
||||
|
||||
if (log_policy)
|
||||
log_error("Bad activation/mirror_log_fault_policy");
|
||||
else
|
||||
log_error("Bad activation/mirror_device_fault_policy");
|
||||
|
||||
return MIRROR_REMOVE;
|
||||
}
|
||||
|
||||
static int get_mirror_log_fault_policy(struct cmd_context *cmd)
|
||||
{
|
||||
return get_mirror_fault_policy(cmd, 1);
|
||||
}
|
||||
|
||||
static int get_mirror_device_fault_policy(struct cmd_context *cmd)
|
||||
{
|
||||
return get_mirror_fault_policy(cmd, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* replace_mirror_images
|
||||
* @mirrored_seg: segment (which may be linear now) to restore
|
||||
* @num_mirrors: number of copies we should end up with
|
||||
* @replace_log: replace log if not present
|
||||
* @in_sync: was the original mirror in-sync?
|
||||
*
|
||||
* in_sync will be set to 0 if new mirror devices are being added
|
||||
* In other words, it is only useful if the log (and only the log)
|
||||
* is being restored.
|
||||
*
|
||||
* Returns: 0 on failure, 1 on reconfig, -1 if no reconfig done
|
||||
*/
|
||||
static int replace_mirror_images(struct lv_segment *mirrored_seg,
|
||||
uint32_t num_mirrors,
|
||||
int log_policy, int in_sync)
|
||||
{
|
||||
int r = -1;
|
||||
struct logical_volume *lv = mirrored_seg->lv;
|
||||
|
||||
/* FIXME: Use lvconvert rather than duplicating its code */
|
||||
|
||||
if (mirrored_seg->area_count < num_mirrors) {
|
||||
log_error("WARNING: Failed to replace mirror device in %s/%s",
|
||||
mirrored_seg->lv->vg->name, mirrored_seg->lv->name);
|
||||
|
||||
if ((mirrored_seg->area_count > 1) && !mirrored_seg->log_lv)
|
||||
log_error("WARNING: Use 'lvconvert -m %d %s/%s --corelog' to replace failed devices",
|
||||
num_mirrors - 1, lv->vg->name, lv->name);
|
||||
else
|
||||
log_error("WARNING: Use 'lvconvert -m %d %s/%s' to replace failed devices",
|
||||
num_mirrors - 1, lv->vg->name, lv->name);
|
||||
r = 0;
|
||||
|
||||
/* REMEMBER/FIXME: set in_sync to 0 if a new mirror device was added */
|
||||
in_sync = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: right now, we ignore the allocation policy specified to
|
||||
* allocate the new log.
|
||||
*/
|
||||
if ((mirrored_seg->area_count > 1) && !mirrored_seg->log_lv &&
|
||||
(log_policy != MIRROR_REMOVE)) {
|
||||
log_error("WARNING: Failed to replace mirror log device in %s/%s",
|
||||
lv->vg->name, lv->name);
|
||||
|
||||
log_error("WARNING: Use 'lvconvert -m %d %s/%s' to replace failed devices",
|
||||
mirrored_seg->area_count - 1 , lv->vg->name, lv->name);
|
||||
r = 0;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
|
||||
struct list *removable_pvs, int remove_log)
|
||||
{
|
||||
int r;
|
||||
int insync = 0;
|
||||
int log_policy, dev_policy;
|
||||
uint32_t old_num_mirrors = mirrored_seg->area_count;
|
||||
int had_log = (mirrored_seg->log_lv) ? 1 : 0;
|
||||
float sync_percent = 0;
|
||||
|
||||
/* was the mirror in-sync before problems? */
|
||||
if (!lv_mirror_percent(mirrored_seg->lv->vg->cmd,
|
||||
mirrored_seg->lv, 0, &sync_percent, NULL))
|
||||
log_error("WARNING: Unable to determine mirror sync status of %s/%s.",
|
||||
mirrored_seg->lv->vg->name, mirrored_seg->lv->name);
|
||||
else if (sync_percent >= 100.0)
|
||||
insync = 1;
|
||||
|
||||
/*
|
||||
* While we are only removing devices, we can have sync set.
|
||||
* Setting this is only useful if we are moving to core log
|
||||
* otherwise the disk log will contain the sync information
|
||||
*/
|
||||
init_mirror_in_sync(insync);
|
||||
|
||||
r = remove_mirror_images(mirrored_seg, num_mirrors,
|
||||
removable_pvs, remove_log);
|
||||
if (!r)
|
||||
/* Unable to remove bad devices */
|
||||
return 0;
|
||||
|
||||
log_print("WARNING: Bad device removed from mirror volume, %s/%s",
|
||||
mirrored_seg->lv->vg->name, mirrored_seg->lv->name);
|
||||
|
||||
log_policy = get_mirror_log_fault_policy(mirrored_seg->lv->vg->cmd);
|
||||
dev_policy = get_mirror_device_fault_policy(mirrored_seg->lv->vg->cmd);
|
||||
|
||||
r = replace_mirror_images(mirrored_seg,
|
||||
(dev_policy != MIRROR_REMOVE) ?
|
||||
old_num_mirrors : num_mirrors,
|
||||
log_policy, insync);
|
||||
|
||||
if (!r)
|
||||
/* Failed to replace device(s) */
|
||||
log_error("WARNING: Unable to find substitute device for mirror volume, %s/%s",
|
||||
mirrored_seg->lv->vg->name, mirrored_seg->lv->name);
|
||||
else if (r > 0)
|
||||
/* Success in replacing device(s) */
|
||||
log_print("WARNING: Mirror volume, %s/%s restored - substitute for failed device found.",
|
||||
mirrored_seg->lv->vg->name, mirrored_seg->lv->name);
|
||||
else
|
||||
/* Bad device removed, but not replaced because of policy */
|
||||
if (mirrored_seg->area_count == 1) {
|
||||
log_print("WARNING: Mirror volume, %s/%s converted to linear due to device failure.",
|
||||
mirrored_seg->lv->vg->name, mirrored_seg->lv->name);
|
||||
} else if (had_log && !mirrored_seg->log_lv) {
|
||||
log_print("WARNING: Mirror volume, %s/%s disk log removed due to device failure.",
|
||||
mirrored_seg->lv->vg->name, mirrored_seg->lv->name);
|
||||
}
|
||||
/*
|
||||
* If we made it here, we at least removed the bad device.
|
||||
* Consider this success.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _create_layers_for_mirror(struct alloc_handle *ah,
|
||||
uint32_t first_area,
|
||||
uint32_t num_mirrors,
|
||||
@@ -248,7 +428,7 @@ static int _create_layers_for_mirror(struct alloc_handle *ah,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lvm_snprintf(img_name, len, "%s_mimage_%%d", lv->name) < 0) {
|
||||
if (dm_snprintf(img_name, len, "%s_mimage_%%d", lv->name) < 0) {
|
||||
log_error("img_name allocation failed. "
|
||||
"Remove new LV and retry.");
|
||||
return 0;
|
||||
|
||||
@@ -67,23 +67,19 @@ struct segtype_handler {
|
||||
int (*merge_segments) (struct lv_segment * seg1,
|
||||
struct lv_segment * seg2);
|
||||
int (*add_target_line) (struct dev_manager *dm, struct dm_pool *mem,
|
||||
struct config_tree *cft, void **target_state,
|
||||
struct cmd_context *cmd, void **target_state,
|
||||
struct lv_segment *seg,
|
||||
struct dm_tree_node *node, uint64_t len,
|
||||
uint32_t *pvmove_mirror_count);
|
||||
int (*target_percent) (void **target_state, struct dm_pool * mem,
|
||||
struct config_tree * cft,
|
||||
struct lv_segment * seg, char *params,
|
||||
struct cmd_context *cmd,
|
||||
struct lv_segment *seg, char *params,
|
||||
uint64_t *total_numerator,
|
||||
uint64_t *total_denominator, float *percent);
|
||||
int (*target_present) (void);
|
||||
void (*destroy) (const struct segment_type * segtype);
|
||||
int (*target_register_events) (struct dm_pool *mem,
|
||||
struct lv_segment *seg,
|
||||
struct config_tree *cft, int events);
|
||||
int (*target_unregister_events) (struct dm_pool *mem,
|
||||
struct lv_segment *seg,
|
||||
struct config_tree *cft, int events);
|
||||
int (*target_register_events) (struct lv_segment *seg, int events);
|
||||
int (*target_unregister_events) (struct lv_segment *seg, int events);
|
||||
};
|
||||
|
||||
struct segment_type *get_segtype_from_string(struct cmd_context *cmd,
|
||||
|
||||
@@ -154,7 +154,7 @@ static int _mirrored_text_export(const struct lv_segment *seg, struct formatter
|
||||
|
||||
#ifdef DEVMAPPER_SUPPORT
|
||||
static struct mirror_state *_mirrored_init_target(struct dm_pool *mem,
|
||||
struct config_tree *cft)
|
||||
struct cmd_context *cmd)
|
||||
{
|
||||
struct mirror_state *mirr_state;
|
||||
|
||||
@@ -164,7 +164,7 @@ static struct mirror_state *_mirrored_init_target(struct dm_pool *mem,
|
||||
}
|
||||
|
||||
mirr_state->default_region_size = 2 *
|
||||
find_config_int(cft->root,
|
||||
find_config_tree_int(cmd,
|
||||
"activation/mirror_region_size",
|
||||
DEFAULT_MIRROR_REGION_SIZE);
|
||||
|
||||
@@ -172,9 +172,10 @@ static struct mirror_state *_mirrored_init_target(struct dm_pool *mem,
|
||||
}
|
||||
|
||||
static int _mirrored_target_percent(void **target_state, struct dm_pool *mem,
|
||||
struct config_tree *cft, struct lv_segment *seg,
|
||||
struct cmd_context *cmd, struct lv_segment *seg,
|
||||
char *params, uint64_t *total_numerator,
|
||||
uint64_t *total_denominator, float *percent)
|
||||
uint64_t *total_denominator,
|
||||
float *percent __attribute((unused)))
|
||||
{
|
||||
struct mirror_state *mirr_state;
|
||||
uint64_t numerator, denominator;
|
||||
@@ -183,7 +184,7 @@ static int _mirrored_target_percent(void **target_state, struct dm_pool *mem,
|
||||
char *pos = params;
|
||||
|
||||
if (!*target_state)
|
||||
*target_state = _mirrored_init_target(mem, cft);
|
||||
*target_state = _mirrored_init_target(mem, cmd);
|
||||
|
||||
mirr_state = *target_state;
|
||||
|
||||
@@ -237,13 +238,26 @@ static int _add_log(struct dev_manager *dm, struct lv_segment *seg,
|
||||
(seg->lv->vg->status & CLUSTERED)))
|
||||
clustered = 1;
|
||||
|
||||
if (seg->log_lv &&
|
||||
!(log_dlid = build_dlid(dm, seg->log_lv->lvid.s, NULL))) {
|
||||
log_error("Failed to build uuid for log LV %s.",
|
||||
seg->log_lv->name);
|
||||
return 0;
|
||||
if (seg->log_lv) {
|
||||
/* If disk log, use its UUID */
|
||||
if (!(log_dlid = build_dlid(dm, seg->log_lv->lvid.s, NULL))) {
|
||||
log_error("Failed to build uuid for log LV %s.",
|
||||
seg->log_lv->name);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* If core log, use mirror's UUID and set DM_CORELOG flag */
|
||||
if (!(log_dlid = build_dlid(dm, seg->lv->lvid.s, NULL))) {
|
||||
log_error("Failed to build uuid for mirror LV %s.",
|
||||
seg->lv->name);
|
||||
return 0;
|
||||
}
|
||||
log_flags |= DM_CORELOG;
|
||||
}
|
||||
|
||||
if (mirror_in_sync() && !(seg->status & PVMOVE))
|
||||
log_flags |= DM_NOSYNC;
|
||||
|
||||
if (_block_on_error_available && !(seg->status & PVMOVE))
|
||||
log_flags |= DM_BLOCK_ON_ERROR;
|
||||
|
||||
@@ -251,7 +265,7 @@ static int _add_log(struct dev_manager *dm, struct lv_segment *seg,
|
||||
}
|
||||
|
||||
static int _mirrored_add_target_line(struct dev_manager *dm, struct dm_pool *mem,
|
||||
struct config_tree *cft, void **target_state,
|
||||
struct cmd_context *cmd, void **target_state,
|
||||
struct lv_segment *seg,
|
||||
struct dm_tree_node *node, uint64_t len,
|
||||
uint32_t *pvmove_mirror_count)
|
||||
@@ -264,7 +278,7 @@ static int _mirrored_add_target_line(struct dev_manager *dm, struct dm_pool *mem
|
||||
int r;
|
||||
|
||||
if (!*target_state)
|
||||
*target_state = _mirrored_init_target(mem, cft);
|
||||
*target_state = _mirrored_init_target(mem, cmd);
|
||||
|
||||
mirr_state = *target_state;
|
||||
|
||||
@@ -353,7 +367,7 @@ static int _mirrored_target_present(void)
|
||||
}
|
||||
|
||||
#ifdef DMEVENTD
|
||||
static int _setup_registration(struct dm_pool *mem, struct config_tree *cft,
|
||||
static int _setup_registration(struct dm_pool *mem, struct cmd_context *cmd,
|
||||
char **dso)
|
||||
{
|
||||
char *path;
|
||||
@@ -364,10 +378,10 @@ static int _setup_registration(struct dm_pool *mem, struct config_tree *cft,
|
||||
return 0;
|
||||
}
|
||||
|
||||
libpath = find_config_str(cft->root, "dmeventd/mirror_library",
|
||||
DEFAULT_DMEVENTD_MIRROR_LIB);
|
||||
libpath = find_config_tree_str(cmd, "dmeventd/mirror_library",
|
||||
DEFAULT_DMEVENTD_MIRROR_LIB);
|
||||
|
||||
get_shared_library_path(cft, libpath, path, PATH_MAX);
|
||||
get_shared_library_path(cmd, libpath, path, PATH_MAX);
|
||||
|
||||
*dso = path;
|
||||
|
||||
@@ -376,9 +390,8 @@ static int _setup_registration(struct dm_pool *mem, struct config_tree *cft,
|
||||
|
||||
/* FIXME This gets run while suspended and performs banned operations. */
|
||||
/* FIXME Merge these two functions */
|
||||
static int _target_register_events(struct dm_pool *mem,
|
||||
struct lv_segment *seg,
|
||||
struct config_tree *cft, int events)
|
||||
static int _target_register_events(struct lv_segment *seg,
|
||||
int events)
|
||||
{
|
||||
char *dso, *name;
|
||||
struct logical_volume *lv;
|
||||
@@ -387,12 +400,12 @@ static int _target_register_events(struct dm_pool *mem,
|
||||
lv = seg->lv;
|
||||
vg = lv->vg;
|
||||
|
||||
if (!_setup_registration(mem, cft, &dso)) {
|
||||
if (!_setup_registration(vg->cmd->mem, vg->cmd, &dso)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(name = build_dm_name(mem, vg->name, lv->name, NULL)))
|
||||
if (!(name = build_dm_name(vg->cmd->mem, vg->name, lv->name, NULL)))
|
||||
return_0;
|
||||
|
||||
/* FIXME Save a returned handle here so we can unregister it later */
|
||||
@@ -404,9 +417,8 @@ static int _target_register_events(struct dm_pool *mem,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _target_unregister_events(struct dm_pool *mem,
|
||||
struct lv_segment *seg,
|
||||
struct config_tree *cft, int events)
|
||||
static int _target_unregister_events(struct lv_segment *seg,
|
||||
int events)
|
||||
{
|
||||
char *dso;
|
||||
char *name;
|
||||
@@ -417,10 +429,10 @@ static int _target_unregister_events(struct dm_pool *mem,
|
||||
vg = lv->vg;
|
||||
|
||||
/* FIXME Remove this and use handle to avoid config file race */
|
||||
if (!_setup_registration(mem, cft, &dso))
|
||||
if (!_setup_registration(vg->cmd->mem, vg->cmd, &dso))
|
||||
return_0;
|
||||
|
||||
if (!(name = build_dm_name(mem, vg->name, lv->name, NULL)))
|
||||
if (!(name = build_dm_name(vg->cmd->mem, vg->name, lv->name, NULL)))
|
||||
return_0;
|
||||
|
||||
/* FIXME Use handle returned by registration function instead of dso */
|
||||
|
||||
@@ -1,430 +0,0 @@
|
||||
/* lib/misc/configure.h. Generated by configure. */
|
||||
/* lib/misc/configure.h.in. Generated from configure.in by autoheader. */
|
||||
|
||||
/* Define to 1 if the `closedir' function returns void instead of `int'. */
|
||||
/* #undef CLOSEDIR_VOID */
|
||||
|
||||
/* Define to 1 to include built-in support for clustered LVM locking. */
|
||||
/* #undef CLUSTER_LOCKING_INTERNAL */
|
||||
|
||||
/* Define to 1 to build the shared command library. */
|
||||
/* #undef CMDLIB */
|
||||
|
||||
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
|
||||
systems. This function is required for `alloca.c' support on those systems.
|
||||
*/
|
||||
/* #undef CRAY_STACKSEG_END */
|
||||
|
||||
/* Define to 1 if using `alloca.c'. */
|
||||
/* #undef C_ALLOCA */
|
||||
|
||||
/* Define to 1 to enable device-mapper interaction. */
|
||||
#define DEVMAPPER_SUPPORT 1
|
||||
|
||||
/* Define to 1 to enable the device-mapper event daemon. */
|
||||
/* #undef DMEVENTD */
|
||||
|
||||
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||
#define HAVE_ALLOCA 1
|
||||
|
||||
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
|
||||
*/
|
||||
#define HAVE_ALLOCA_H 1
|
||||
|
||||
/* Define to 1 if you have the <asm/byteorder.h> header file. */
|
||||
/* #undef HAVE_ASM_BYTEORDER_H */
|
||||
|
||||
/* Define to 1 if you have the <assert.h> header file. */
|
||||
#define HAVE_ASSERT_H 1
|
||||
|
||||
/* Define to 1 if you have the <ctype.h> header file. */
|
||||
#define HAVE_CTYPE_H 1
|
||||
|
||||
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#define HAVE_DIRENT_H 1
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
|
||||
/* #undef HAVE_DOPRNT */
|
||||
|
||||
/* Define to 1 if you have the `dup2' function. */
|
||||
/* #undef HAVE_DUP2 */
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the `fork' function. */
|
||||
#define HAVE_FORK 1
|
||||
|
||||
/* Define to 1 if you have the <fstab.h> header file. */
|
||||
/* #undef HAVE_FSTAB_H */
|
||||
|
||||
/* Define to 1 if you have the `gethostname' function. */
|
||||
#define HAVE_GETHOSTNAME 1
|
||||
|
||||
/* Define to 1 if you have the `getmntent' function. */
|
||||
/* #undef HAVE_GETMNTENT */
|
||||
|
||||
/* Define to 1 to if getopt_long is available. */
|
||||
#define HAVE_GETOPTLONG 1
|
||||
|
||||
/* Define to 1 if you have the <getopt.h> header file. */
|
||||
#define HAVE_GETOPT_H 1
|
||||
|
||||
/* Define to 1 if you have the `getpagesize' function. */
|
||||
#define HAVE_GETPAGESIZE 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <libdevmapper.h> header file. */
|
||||
#define HAVE_LIBDEVMAPPER_H 1
|
||||
|
||||
/* Define to 1 if dynamic libraries are available. */
|
||||
#define HAVE_LIBDL 1
|
||||
|
||||
/* Define to 1 if you have the <libgen.h> header file. */
|
||||
#define HAVE_LIBGEN_H 1
|
||||
|
||||
/* Define to 1 if you have the <libintl.h> header file. */
|
||||
/* #undef HAVE_LIBINTL_H */
|
||||
|
||||
/* Define to 1 if you have the `readline' library (-lreadline). */
|
||||
/* #undef HAVE_LIBREADLINE */
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define to 1 if you have the <linux/fs.h> header file. */
|
||||
/* #undef HAVE_LINUX_FS_H */
|
||||
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#define HAVE_LOCALE_H 1
|
||||
|
||||
/* Define to 1 if `lstat' has the bug that it succeeds when given the
|
||||
zero-length file name argument. */
|
||||
/* #undef HAVE_LSTAT_EMPTY_STRING_BUG */
|
||||
|
||||
/* Define to 1 if you have the <machine/endian.h> header file. */
|
||||
#define HAVE_MACHINE_ENDIAN_H 1
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||
to 0 otherwise. */
|
||||
#define HAVE_MALLOC 1
|
||||
|
||||
/* Define to 1 if you have the <malloc.h> header file. */
|
||||
/* #undef HAVE_MALLOC_H */
|
||||
|
||||
/* Define to 1 if you have the `memmove' function. */
|
||||
/* #undef HAVE_MEMMOVE */
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
/* Define to 1 if you have the `mkdir' function. */
|
||||
#define HAVE_MKDIR 1
|
||||
|
||||
/* Define to 1 if you have a working `mmap' system call. */
|
||||
#define HAVE_MMAP 1
|
||||
|
||||
/* Define to 1 if you have the <mntent.h> header file. */
|
||||
/* #undef HAVE_MNTENT_H */
|
||||
|
||||
/* Define to 1 if you have the `munmap' function. */
|
||||
#define HAVE_MUNMAP 1
|
||||
|
||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||
/* #undef HAVE_NDIR_H */
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
/* #undef HAVE_NETDB_H */
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
/* #undef HAVE_NETINET_IN_H */
|
||||
|
||||
/* Define to 1 if you have the <pthread.h> header file. */
|
||||
/* #undef HAVE_PTHREAD_H */
|
||||
|
||||
/* Define to 1 if you have the <readline/history.h> header file. */
|
||||
/* #undef HAVE_READLINE_HISTORY_H */
|
||||
|
||||
/* Define to 1 if you have the <readline/readline.h> header file. */
|
||||
/* #undef HAVE_READLINE_READLINE_H */
|
||||
|
||||
/* Define to 1 if rl_completion_matches() is available. */
|
||||
/* #undef HAVE_RL_COMPLETION_MATCHES */
|
||||
|
||||
/* Define to 1 if you have the `rmdir' function. */
|
||||
#define HAVE_RMDIR 1
|
||||
|
||||
/* Define to 1 if you have the <search.h> header file. */
|
||||
/* #undef HAVE_SEARCH_H */
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
/* #undef HAVE_SELECT */
|
||||
|
||||
/* Define to 1 to include support for selinux. */
|
||||
/* #undef HAVE_SELINUX */
|
||||
|
||||
/* Define to 1 if you have the <selinux/selinux.h> header file. */
|
||||
/* #undef HAVE_SELINUX_SELINUX_H */
|
||||
|
||||
/* Define to 1 if you have the `setlocale' function. */
|
||||
#define HAVE_SETLOCALE 1
|
||||
|
||||
/* Define to 1 if you have the <signal.h> header file. */
|
||||
#define HAVE_SIGNAL_H 1
|
||||
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
/* #undef HAVE_SOCKET */
|
||||
|
||||
/* Define to 1 if `stat' has the bug that it succeeds when given the
|
||||
zero-length file name argument. */
|
||||
/* #undef HAVE_STAT_EMPTY_STRING_BUG */
|
||||
|
||||
/* Define to 1 if you have the <stddef.h> header file. */
|
||||
#define HAVE_STDDEF_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdio.h> header file. */
|
||||
#define HAVE_STDIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strcasecmp' function. */
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#define HAVE_STRCHR 1
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#define HAVE_STRERROR 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strncasecmp' function. */
|
||||
#define HAVE_STRNCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `strrchr' function. */
|
||||
#define HAVE_STRRCHR 1
|
||||
|
||||
/* Define to 1 if you have the `strstr' function. */
|
||||
#define HAVE_STRSTR 1
|
||||
|
||||
/* Define to 1 if you have the `strtol' function. */
|
||||
#define HAVE_STRTOL 1
|
||||
|
||||
/* Define to 1 if you have the `strtoul' function. */
|
||||
#define HAVE_STRTOUL 1
|
||||
|
||||
/* Define to 1 if `st_rdev' is member of `struct stat'. */
|
||||
#define HAVE_STRUCT_STAT_ST_RDEV 1
|
||||
|
||||
/* Define to 1 if your `struct stat' has `st_rdev'. Deprecated, use
|
||||
`HAVE_STRUCT_STAT_ST_RDEV' instead. */
|
||||
#define HAVE_ST_RDEV 1
|
||||
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#define HAVE_SYSLOG_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
/* #undef HAVE_SYS_DIR_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/disk.h> header file. */
|
||||
#define HAVE_SYS_DISK_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/file.h> header file. */
|
||||
#define HAVE_SYS_FILE_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#define HAVE_SYS_IOCTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#define HAVE_SYS_MMAN_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/mount.h> header file. */
|
||||
/* #undef HAVE_SYS_MOUNT_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
/* #undef HAVE_SYS_NDIR_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/resource.h> header file. */
|
||||
#define HAVE_SYS_RESOURCE_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
/* #undef HAVE_SYS_SELECT_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
/* #undef HAVE_SYS_SOCKET_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/uio.h> header file. */
|
||||
/* #undef HAVE_SYS_UIO_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/un.h> header file. */
|
||||
/* #undef HAVE_SYS_UN_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/utsname.h> header file. */
|
||||
#define HAVE_SYS_UTSNAME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/vfs.h> header file. */
|
||||
/* #undef HAVE_SYS_VFS_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/wait.h> header file. */
|
||||
#define HAVE_SYS_WAIT_H 1
|
||||
|
||||
/* Define to 1 if you have the <time.h> header file. */
|
||||
#define HAVE_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the `uname' function. */
|
||||
#define HAVE_UNAME 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the <utmpx.h> header file. */
|
||||
/* #undef HAVE_UTMPX_H */
|
||||
|
||||
/* Define to 1 if you have the `vfork' function. */
|
||||
#define HAVE_VFORK 1
|
||||
|
||||
/* Define to 1 if you have the <vfork.h> header file. */
|
||||
/* #undef HAVE_VFORK_H */
|
||||
|
||||
/* Define to 1 if you have the `vprintf' function. */
|
||||
#define HAVE_VPRINTF 1
|
||||
|
||||
/* Define to 1 if `fork' works. */
|
||||
#define HAVE_WORKING_FORK 1
|
||||
|
||||
/* Define to 1 if `vfork' works. */
|
||||
#define HAVE_WORKING_VFORK 1
|
||||
|
||||
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
|
||||
slash. */
|
||||
/* #undef LSTAT_FOLLOWS_SLASHED_SYMLINK */
|
||||
|
||||
/* Define to 1 if 'lvm' should fall back to using LVM1 binaries if
|
||||
device-mapper is missing from the kernel */
|
||||
/* #undef LVM1_FALLBACK */
|
||||
|
||||
/* Define to 1 to include built-in support for LVM1 metadata. */
|
||||
#define LVM1_INTERNAL 1
|
||||
|
||||
/* Define to 1 to include built-in support for mirrors. */
|
||||
#define MIRRORED_INTERNAL 1
|
||||
|
||||
/* The path to 'modprobe', if available. */
|
||||
#define MODPROBE_CMD "/sbin/ifconfig"
|
||||
|
||||
/* Define to 1 to enable O_DIRECT support. */
|
||||
/* #undef O_DIRECT_SUPPORT */
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME ""
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING ""
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION ""
|
||||
|
||||
/* Define to 1 to include built-in support for GFS pool metadata. */
|
||||
#define POOL_INTERNAL 1
|
||||
|
||||
/* Define to 1 to include the LVM readline shell. */
|
||||
/* #undef READLINE_SUPPORT */
|
||||
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Define to the type of arg 1 for `select'. */
|
||||
/* #undef SELECT_TYPE_ARG1 */
|
||||
|
||||
/* Define to the type of args 2, 3 and 4 for `select'. */
|
||||
/* #undef SELECT_TYPE_ARG234 */
|
||||
|
||||
/* Define to the type of arg 5 for `select'. */
|
||||
/* #undef SELECT_TYPE_ARG5 */
|
||||
|
||||
/* Define to 1 to include built-in support for snapshots. */
|
||||
#define SNAPSHOT_INTERNAL 1
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at run-time.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
/* #undef STACK_DIRECTION */
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
|
||||
/* #undef TM_IN_SYS_TIME */
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
/* #undef inline */
|
||||
#endif
|
||||
|
||||
/* Define to rpl_malloc if the replacement function should be used. */
|
||||
/* #undef malloc */
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef mode_t */
|
||||
|
||||
/* Define to `long' if <sys/types.h> does not define. */
|
||||
/* #undef off_t */
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef pid_t */
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
/* #undef size_t */
|
||||
|
||||
/* Define as `fork' if `vfork' does not work. */
|
||||
/* #undef vfork */
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "crc.h"
|
||||
|
||||
/* Calculate an endian-independent CRC of supplied buffer */
|
||||
uint32_t calc_crc(uint32_t initial, void *buf, uint32_t size)
|
||||
uint32_t calc_crc(uint32_t initial, const void *buf, uint32_t size)
|
||||
{
|
||||
static const uint32_t crctab[] = {
|
||||
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
|
||||
@@ -27,7 +27,7 @@ uint32_t calc_crc(uint32_t initial, void *buf, uint32_t size)
|
||||
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
|
||||
};
|
||||
uint32_t i, crc = initial;
|
||||
uint8_t *data = (uint8_t *) buf;
|
||||
const uint8_t *data = (const uint8_t *) buf;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
crc ^= *data++;
|
||||
|
||||
@@ -18,6 +18,6 @@
|
||||
|
||||
#define INITIAL_CRC 0xf597a6cf
|
||||
|
||||
uint32_t calc_crc(uint32_t initial, void *buf, uint32_t size);
|
||||
uint32_t calc_crc(uint32_t initial, const void *buf, uint32_t size);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "log.h"
|
||||
#include "intl.h"
|
||||
#include "lvm-types.h"
|
||||
#include "lvm-wrappers.h"
|
||||
|
||||
#include <libdevmapper.h>
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ int create_temp_name(const char *dir, char *buffer, size_t len, int *fd)
|
||||
|
||||
for (i = 0; i < 20; i++, num++) {
|
||||
|
||||
if (lvm_snprintf(buffer, len, "%s/.lvm_%s_%d_%d",
|
||||
if (dm_snprintf(buffer, len, "%s/.lvm_%s_%d_%d",
|
||||
dir, hostname, pid, num) == -1) {
|
||||
log_err("Not enough space to build temporary file "
|
||||
"string.");
|
||||
|
||||
@@ -14,33 +14,10 @@
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "lvm-types.h"
|
||||
#include "lvm-string.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
* On error, up to glibc 2.0.6, snprintf returned -1 if buffer was too small;
|
||||
* From glibc 2.1 it returns number of chars (excl. trailing null) that would
|
||||
* have been written had there been room.
|
||||
*
|
||||
* lvm_snprintf reverts to the old behaviour.
|
||||
*/
|
||||
int lvm_snprintf(char *buf, size_t bufsize, const char *format, ...)
|
||||
{
|
||||
int n;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
n = vsnprintf(buf, bufsize, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (n < 0 || (n > bufsize - 1))
|
||||
return -1;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int emit_to_buffer(char **buffer, size_t *size, const char *fmt, ...)
|
||||
{
|
||||
int n;
|
||||
@@ -58,47 +35,6 @@ int emit_to_buffer(char **buffer, size_t *size, const char *fmt, ...)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* consume characters while they match the predicate function.
|
||||
*/
|
||||
static char *_consume(char *buffer, int (*fn) (int))
|
||||
{
|
||||
while (*buffer && fn(*buffer))
|
||||
buffer++;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static int _isword(int c)
|
||||
{
|
||||
return !isspace(c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Split buffer into NULL-separated words in argv.
|
||||
* Returns number of words.
|
||||
*/
|
||||
int split_words(char *buffer, unsigned max, char **argv)
|
||||
{
|
||||
unsigned arg;
|
||||
|
||||
for (arg = 0; arg < max; arg++) {
|
||||
buffer = _consume(buffer, isspace);
|
||||
if (!*buffer)
|
||||
break;
|
||||
|
||||
argv[arg] = buffer;
|
||||
buffer = _consume(buffer, _isword);
|
||||
|
||||
if (*buffer) {
|
||||
*buffer = '\0';
|
||||
buffer++;
|
||||
}
|
||||
}
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Device layer names are all of the form <vg>-<lv>-<layer>, any
|
||||
* other hyphens that appear in these names are quoted with yet
|
||||
@@ -169,47 +105,6 @@ char *build_dm_name(struct dm_pool *mem, const char *vgname,
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove hyphen quoting from a component of a name.
|
||||
* NULL-terminates the component and returns start of next component.
|
||||
*/
|
||||
static char *_unquote(char *component)
|
||||
{
|
||||
char *c = component;
|
||||
char *o = c;
|
||||
char *r;
|
||||
|
||||
while (*c) {
|
||||
if (*(c + 1)) {
|
||||
if (*c == '-') {
|
||||
if (*(c + 1) == '-')
|
||||
c++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
*o = *c;
|
||||
o++;
|
||||
c++;
|
||||
}
|
||||
|
||||
r = (*c) ? c + 1 : c;
|
||||
*o = '\0';
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int split_dm_name(struct dm_pool *mem, const char *dmname,
|
||||
char **vgname, char **lvname, char **layer)
|
||||
{
|
||||
if (!(*vgname = dm_pool_strdup(mem, dmname)))
|
||||
return 0;
|
||||
|
||||
_unquote(*layer = _unquote(*lvname = _unquote(*vgname)));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int validate_name(const char *n)
|
||||
{
|
||||
register char c;
|
||||
|
||||
@@ -23,25 +23,11 @@
|
||||
|
||||
struct pool;
|
||||
|
||||
/*
|
||||
* On error, up to glibc 2.0.6, snprintf returned -1 if buffer was too small;
|
||||
* From glibc 2.1 it returns number of chars (excl. trailing null) that would
|
||||
* have been written had there been room.
|
||||
*
|
||||
* lvm_snprintf reverts to the old behaviour.
|
||||
*/
|
||||
int lvm_snprintf(char *buf, size_t bufsize, const char *format, ...);
|
||||
|
||||
int emit_to_buffer(char **buffer, size_t *size, const char *fmt, ...);
|
||||
|
||||
int split_words(char *buffer, unsigned max, char **argv);
|
||||
|
||||
char *build_dm_name(struct dm_pool *mem, const char *vg,
|
||||
const char *lv, const char *layer);
|
||||
|
||||
int split_dm_name(struct dm_pool *mem, const char *dmname,
|
||||
char **vgname, char **lvname, char **layer);
|
||||
|
||||
int validate_name(const char *n);
|
||||
|
||||
#endif
|
||||
|
||||
22
lib/misc/lvm-wrappers.c
Normal file
22
lib/misc/lvm-wrappers.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 General Public License v.2.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
int lvm_getpagesize(void)
|
||||
{
|
||||
return getpagesize();
|
||||
}
|
||||
21
lib/misc/lvm-wrappers.h
Normal file
21
lib/misc/lvm-wrappers.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2005 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 General Public License v.2.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _LVM_WRAPPERS_H
|
||||
#define _LVM_WRAPPERS_H
|
||||
|
||||
int lvm_getpagesize(void);
|
||||
|
||||
#endif
|
||||
@@ -17,12 +17,13 @@
|
||||
#include "config.h"
|
||||
#include "lvm-string.h"
|
||||
#include "sharedlib.h"
|
||||
#include "toolcontext.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
void get_shared_library_path(struct config_tree *cft, const char *libname,
|
||||
void get_shared_library_path(struct cmd_context *cmd, const char *libname,
|
||||
char *path, size_t path_len)
|
||||
{
|
||||
struct stat info;
|
||||
@@ -31,29 +32,35 @@ void get_shared_library_path(struct config_tree *cft, const char *libname,
|
||||
/* If libname doesn't begin with '/' then use lib_dir/libname,
|
||||
* if present */
|
||||
if (libname[0] == '/' ||
|
||||
!(lib_dir = find_config_str(cft->root, "global/library_dir", 0)) ||
|
||||
(lvm_snprintf(path, path_len, "%s/%s", lib_dir,
|
||||
!(lib_dir = find_config_tree_str(cmd, "global/library_dir", 0)) ||
|
||||
(dm_snprintf(path, path_len, "%s/%s", lib_dir,
|
||||
libname) == -1) || stat(path, &info) == -1)
|
||||
strncpy(path, libname, path_len);
|
||||
}
|
||||
|
||||
void *load_shared_library(struct config_tree *cft, const char *libname,
|
||||
void *load_shared_library(struct cmd_context *cmd, const char *libname,
|
||||
const char *desc, int silent)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
void *library;
|
||||
|
||||
get_shared_library_path(cft, libname, path, sizeof(path));
|
||||
if (cmd->is_static) {
|
||||
log_error("Not loading shared %s library %s in static mode.",
|
||||
desc, libname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
get_shared_library_path(cmd, libname, path, sizeof(path));
|
||||
|
||||
log_very_verbose("Opening shared %s library %s", desc, path);
|
||||
|
||||
if (!(library = dlopen(path, RTLD_LAZY))) {
|
||||
if (!(library = dlopen(path, RTLD_LAZY | RTLD_GLOBAL))) {
|
||||
if (silent && ignorelockingfailure())
|
||||
log_verbose("Unable to open external %s library %s",
|
||||
desc, path);
|
||||
log_verbose("Unable to open external %s library %s: %s",
|
||||
desc, path, dlerror());
|
||||
else
|
||||
log_error("Unable to open external %s library %s",
|
||||
desc, path);
|
||||
log_error("Unable to open external %s library %s: %s",
|
||||
desc, path, dlerror());
|
||||
}
|
||||
|
||||
return library;
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
#include "config.h"
|
||||
#include <dlfcn.h>
|
||||
|
||||
void get_shared_library_path(struct config_tree *cft, const char *libname,
|
||||
void get_shared_library_path(struct cmd_context *cmd, const char *libname,
|
||||
char *path, size_t path_len);
|
||||
void *load_shared_library(struct config_tree *cf, const char *libname,
|
||||
void *load_shared_library(struct cmd_context *cmd, const char *libname,
|
||||
const char *what, int silent);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -58,7 +58,7 @@ static int _default_priority;
|
||||
|
||||
static void _touch_memory(void *mem, size_t size)
|
||||
{
|
||||
size_t pagesize = getpagesize();
|
||||
size_t pagesize = lvm_getpagesize();
|
||||
void *pos = mem;
|
||||
void *end = mem + size - sizeof(long);
|
||||
|
||||
@@ -144,13 +144,13 @@ int memlock(void)
|
||||
|
||||
void memlock_init(struct cmd_context *cmd)
|
||||
{
|
||||
_size_stack = find_config_int(cmd->cft->root,
|
||||
_size_stack = find_config_tree_int(cmd,
|
||||
"activation/reserved_stack",
|
||||
DEFAULT_RESERVED_STACK) * 1024;
|
||||
_size_malloc_tmp = find_config_int(cmd->cft->root,
|
||||
_size_malloc_tmp = find_config_tree_int(cmd,
|
||||
"activation/reserved_memory",
|
||||
DEFAULT_RESERVED_MEMORY) * 1024;
|
||||
_default_priority = find_config_int(cmd->cft->root,
|
||||
_default_priority = find_config_tree_int(cmd,
|
||||
"activation/process_priority",
|
||||
DEFAULT_PROCESS_PRIORITY);
|
||||
}
|
||||
|
||||
@@ -172,9 +172,9 @@ static int _devices_disp(struct report_handle *rh, struct field *field,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lvm_snprintf(extent_str, sizeof(extent_str), "(%" PRIu32
|
||||
if (dm_snprintf(extent_str, sizeof(extent_str), "(%" PRIu32
|
||||
")", extent) < 0) {
|
||||
log_error("Extent number lvm_snprintf failed");
|
||||
log_error("Extent number dm_snprintf failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -276,7 +276,7 @@ static int _int_disp(struct report_handle *rh, struct field *field,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lvm_snprintf(repstr, 12, "%d", value) < 0) {
|
||||
if (dm_snprintf(repstr, 12, "%d", value) < 0) {
|
||||
log_error("int too big: %d", value);
|
||||
return 0;
|
||||
}
|
||||
@@ -333,9 +333,12 @@ static int _lvstatus_disp(struct report_handle *rh, struct field *field,
|
||||
|
||||
if (lv->status & PVMOVE)
|
||||
repstr[0] = 'p';
|
||||
else if (lv->status & MIRRORED)
|
||||
repstr[0] = 'm';
|
||||
else if (lv->status & MIRROR_IMAGE)
|
||||
else if (lv->status & MIRRORED) {
|
||||
if (lv->status & MIRROR_NOTSYNCED)
|
||||
repstr[0] = 'M';
|
||||
else
|
||||
repstr[0] = 'm';
|
||||
}else if (lv->status & MIRROR_IMAGE)
|
||||
repstr[0] = 'i';
|
||||
else if (lv->status & MIRROR_LOG)
|
||||
repstr[0] = 'l';
|
||||
@@ -472,7 +475,8 @@ static int _vgstatus_disp(struct report_handle *rh, struct field *field,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _segtype_disp(struct report_handle *rh, struct field *field,
|
||||
static int _segtype_disp(struct report_handle *rh __attribute((unused)),
|
||||
struct field *field,
|
||||
const void *data)
|
||||
{
|
||||
const struct lv_segment *seg = (const struct lv_segment *) data;
|
||||
@@ -536,7 +540,7 @@ static int _lvname_disp(struct report_handle *rh, struct field *field,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lvm_snprintf(repstr, len, "[%s]", lv->name) < 0) {
|
||||
if (dm_snprintf(repstr, len, "[%s]", lv->name) < 0) {
|
||||
log_error("lvname snprintf failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -780,7 +784,7 @@ static int _uint32_disp(struct report_handle *rh, struct field *field,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lvm_snprintf(repstr, 11, "%u", value) < 0) {
|
||||
if (dm_snprintf(repstr, 11, "%u", value) < 0) {
|
||||
log_error("uint32 too big: %u", value);
|
||||
return 0;
|
||||
}
|
||||
@@ -809,7 +813,7 @@ static int _int32_disp(struct report_handle *rh, struct field *field,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lvm_snprintf(repstr, 12, "%d", value) < 0) {
|
||||
if (dm_snprintf(repstr, 12, "%d", value) < 0) {
|
||||
log_error("int32 too big: %d", value);
|
||||
return 0;
|
||||
}
|
||||
@@ -866,7 +870,7 @@ static int _snpercent_disp(struct report_handle *rh, struct field *field,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lvm_snprintf(repstr, 7, "%.2f", snap_percent) < 0) {
|
||||
if (dm_snprintf(repstr, 7, "%.2f", snap_percent) < 0) {
|
||||
log_error("snapshot percentage too large");
|
||||
return 0;
|
||||
}
|
||||
@@ -906,7 +910,7 @@ static int _copypercent_disp(struct report_handle *rh, struct field *field,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lvm_snprintf(repstr, 7, "%.2f", percent) < 0) {
|
||||
if (dm_snprintf(repstr, 7, "%.2f", percent) < 0) {
|
||||
log_error("copy percentage too large");
|
||||
return 0;
|
||||
}
|
||||
@@ -1320,7 +1324,7 @@ static int _report_headings(void *handle)
|
||||
|
||||
heading = _fields[fp->field_num].heading;
|
||||
if (rh->flags & RH_ALIGNED) {
|
||||
if (lvm_snprintf(buf, sizeof(buf), "%-*.*s",
|
||||
if (dm_snprintf(buf, sizeof(buf), "%-*.*s",
|
||||
fp->width, fp->width, heading) < 0) {
|
||||
log_error("snprintf heading failed");
|
||||
dm_pool_end_object(rh->mem);
|
||||
@@ -1463,7 +1467,7 @@ int report_output(void *handle)
|
||||
strlen(repstr)))
|
||||
goto bad;
|
||||
} else if (field->props->flags & FLD_ALIGN_LEFT) {
|
||||
if (lvm_snprintf(buf, sizeof(buf), "%-*.*s",
|
||||
if (dm_snprintf(buf, sizeof(buf), "%-*.*s",
|
||||
width, width, repstr) < 0) {
|
||||
log_error("snprintf repstr failed");
|
||||
dm_pool_end_object(rh->mem);
|
||||
@@ -1472,7 +1476,7 @@ int report_output(void *handle)
|
||||
if (!dm_pool_grow_object(rh->mem, buf, width))
|
||||
goto bad;
|
||||
} else if (field->props->flags & FLD_ALIGN_RIGHT) {
|
||||
if (lvm_snprintf(buf, sizeof(buf), "%*.*s",
|
||||
if (dm_snprintf(buf, sizeof(buf), "%*.*s",
|
||||
width, width, repstr) < 0) {
|
||||
log_error("snprintf repstr failed");
|
||||
dm_pool_end_object(rh->mem);
|
||||
|
||||
@@ -27,7 +27,7 @@ static const char *_snap_name(const struct lv_segment *seg)
|
||||
}
|
||||
|
||||
static int _snap_text_import(struct lv_segment *seg, const struct config_node *sn,
|
||||
struct dm_hash_table *pv_hash)
|
||||
struct dm_hash_table *pv_hash __attribute((unused)))
|
||||
{
|
||||
uint32_t chunk_size;
|
||||
const char *org_name, *cow_name;
|
||||
@@ -87,8 +87,10 @@ static int _snap_text_export(const struct lv_segment *seg, struct formatter *f)
|
||||
}
|
||||
|
||||
#ifdef DEVMAPPER_SUPPORT
|
||||
static int _snap_target_percent(void **target_state, struct dm_pool *mem,
|
||||
struct config_tree *cft, struct lv_segment *seg,
|
||||
static int _snap_target_percent(void **target_state __attribute((unused)),
|
||||
struct dm_pool *mem __attribute((unused)),
|
||||
struct cmd_context *cmd __attribute((unused)),
|
||||
struct lv_segment *seg __attribute((unused)),
|
||||
char *params, uint64_t *total_numerator,
|
||||
uint64_t *total_denominator, float *percent)
|
||||
{
|
||||
@@ -126,7 +128,7 @@ static int _snap_target_present(void)
|
||||
|
||||
static void _snap_destroy(const struct segment_type *segtype)
|
||||
{
|
||||
dm_free((void *) segtype);
|
||||
dm_free((void *)segtype);
|
||||
}
|
||||
|
||||
static struct segtype_handler _snapshot_ops = {
|
||||
|
||||
@@ -151,11 +151,13 @@ static int _striped_merge_segments(struct lv_segment *seg1, struct lv_segment *s
|
||||
}
|
||||
|
||||
#ifdef DEVMAPPER_SUPPORT
|
||||
static int _striped_add_target_line(struct dev_manager *dm, struct dm_pool *mem,
|
||||
struct config_tree *cft, void **target_state,
|
||||
static int _striped_add_target_line(struct dev_manager *dm,
|
||||
struct dm_pool *mem __attribute((unused)),
|
||||
struct cmd_context *cmd __attribute((unused)),
|
||||
void **target_state __attribute((unused)),
|
||||
struct lv_segment *seg,
|
||||
struct dm_tree_node *node, uint64_t len,
|
||||
uint32_t *pvmove_mirror_count)
|
||||
uint32_t *pvmove_mirror_count __attribute((unused)))
|
||||
{
|
||||
if (!seg->area_count) {
|
||||
log_error("Internal error: striped add_target_line called "
|
||||
@@ -189,7 +191,7 @@ static int _striped_target_present(void)
|
||||
|
||||
static void _striped_destroy(const struct segment_type *segtype)
|
||||
{
|
||||
dm_free((void *) segtype);
|
||||
dm_free((void *)segtype);
|
||||
}
|
||||
|
||||
static struct segtype_handler _striped_ops = {
|
||||
|
||||
@@ -40,7 +40,7 @@ static int _zero_merge_segments(struct lv_segment *seg1, struct lv_segment *seg2
|
||||
#ifdef DEVMAPPER_SUPPORT
|
||||
static int _zero_add_target_line(struct dev_manager *dm __attribute((unused)),
|
||||
struct dm_pool *mem __attribute((unused)),
|
||||
struct config_tree *cft __attribute((unused)),
|
||||
struct cmd_context *cmd __attribute((unused)),
|
||||
void **target_state __attribute((unused)),
|
||||
struct lv_segment *seg __attribute((unused)),
|
||||
struct dm_tree_node *node,uint64_t len,
|
||||
|
||||
@@ -109,3 +109,6 @@ dm_hash_get_first
|
||||
dm_hash_get_next
|
||||
dm_set_selinux_context
|
||||
dm_task_set_geometry
|
||||
dm_split_lvm_name
|
||||
dm_split_words
|
||||
dm_snprintf
|
||||
|
||||
@@ -23,6 +23,7 @@ SOURCES =\
|
||||
libdm-common.c \
|
||||
libdm-file.c \
|
||||
libdm-deptree.c \
|
||||
libdm-string.c \
|
||||
mm/dbg_malloc.c \
|
||||
mm/pool.c \
|
||||
$(interface)/libdm-iface.c
|
||||
|
||||
@@ -1461,7 +1461,6 @@ static int _reload_with_suppression_v4(struct dm_task *dmt)
|
||||
{
|
||||
struct dm_task *task;
|
||||
struct target *t1, *t2;
|
||||
int matches = 1;
|
||||
int r;
|
||||
|
||||
/* New task to get existing table information */
|
||||
@@ -1491,6 +1490,9 @@ static int _reload_with_suppression_v4(struct dm_task *dmt)
|
||||
return r;
|
||||
}
|
||||
|
||||
if ((task->dmi.v4->flags & DM_READONLY_FLAG) ? 1 : 0 != dmt->read_only)
|
||||
goto no_match;
|
||||
|
||||
t1 = dmt->head;
|
||||
t2 = task->head;
|
||||
|
||||
@@ -1498,21 +1500,20 @@ static int _reload_with_suppression_v4(struct dm_task *dmt)
|
||||
if ((t1->start != t2->start) ||
|
||||
(t1->length != t2->length) ||
|
||||
(strcmp(t1->type, t2->type)) ||
|
||||
(strcmp(t1->params, t2->params))) {
|
||||
matches = 0;
|
||||
break;
|
||||
}
|
||||
(strcmp(t1->params, t2->params)))
|
||||
goto no_match;
|
||||
t1 = t1->next;
|
||||
t2 = t2->next;
|
||||
}
|
||||
|
||||
if (matches && !t1 && !t2) {
|
||||
if (!t1 && !t2) {
|
||||
dmt->dmi.v4 = task->dmi.v4;
|
||||
task->dmi.v4 = NULL;
|
||||
dm_task_destroy(task);
|
||||
return 1;
|
||||
}
|
||||
|
||||
no_match:
|
||||
dm_task_destroy(task);
|
||||
|
||||
/* Now do the original reload */
|
||||
@@ -1542,7 +1543,7 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
|
||||
dmi->flags |= DM_SKIP_BDGET_FLAG;
|
||||
|
||||
log_debug("dm %s %s %s%s%s %s%.0d%s%.0d%s"
|
||||
"%s%c %.0llu %s [%u]",
|
||||
"%s%c%s %.0llu %s [%u]",
|
||||
_cmd_data_v4[dmt->type].name,
|
||||
dmi->name, dmi->uuid, dmt->newname ? " " : "",
|
||||
dmt->newname ? dmt->newname : "",
|
||||
@@ -1553,6 +1554,7 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
|
||||
dmt->major > 0 && dmt->minor == 0 ? "0" : "",
|
||||
dmt->major > 0 ? ") " : "",
|
||||
dmt->no_open_count ? 'N' : 'O',
|
||||
dmt->skip_lockfs ? "S " : "",
|
||||
dmt->sector, dmt->message ? dmt->message : "",
|
||||
dmi->data_size);
|
||||
#ifdef DM_IOCTLS
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#define LIB_DEVICE_MAPPER_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef linux
|
||||
@@ -350,6 +351,7 @@ int dm_tree_node_add_mirror_target(struct dm_tree_node *node,
|
||||
#define DM_NOSYNC 0x00000001 /* Known already in sync */
|
||||
#define DM_FORCESYNC 0x00000002 /* Force resync */
|
||||
#define DM_BLOCK_ON_ERROR 0x00000004 /* On error, suspend I/O */
|
||||
#define DM_CORELOG 0x00000008 /* In-memory log */
|
||||
|
||||
int dm_tree_node_add_mirror_target_log(struct dm_tree_node *node,
|
||||
uint32_t region_size,
|
||||
@@ -581,4 +583,28 @@ struct dm_hash_node *dm_hash_get_next(struct dm_hash_table *t, struct dm_hash_no
|
||||
*********/
|
||||
int dm_set_selinux_context(const char *path, mode_t mode);
|
||||
|
||||
/*********************
|
||||
* string manipulation
|
||||
*********************/
|
||||
|
||||
/*
|
||||
* Break up the name of a mapped device into its constituent
|
||||
* Volume Group, Logical Volume and Layer (if present).
|
||||
*/
|
||||
int dm_split_lvm_name(struct dm_pool *mem, const char *dmname,
|
||||
char **vgname, char **lvname, char **layer);
|
||||
|
||||
/*
|
||||
* Destructively split buffer into NULL-separated words in argv.
|
||||
* Returns number of words.
|
||||
*/
|
||||
int dm_split_words(char *buffer, unsigned max,
|
||||
unsigned ignore_comments, /* Not implemented */
|
||||
char **argv);
|
||||
|
||||
/*
|
||||
* Returns -1 if buffer too small
|
||||
*/
|
||||
int dm_snprintf(char *buf, size_t bufsize, const char *format, ...);
|
||||
|
||||
#endif /* LIB_DEVICE_MAPPER_H */
|
||||
|
||||
@@ -1242,9 +1242,12 @@ static int _emit_segment_line(struct dm_task *dmt, struct load_segment *seg, uin
|
||||
log_parm_count = 1; /* Region size */
|
||||
log_parm_count += hweight32(seg->flags); /* [no]sync, block_on_error etc. */
|
||||
|
||||
if (seg->flags & DM_CORELOG)
|
||||
log_parm_count--; /* DM_CORELOG does not count in the param list */
|
||||
|
||||
if (seg->clustered) {
|
||||
if (seg->uuid)
|
||||
log_parm_count++; /* uuid */
|
||||
log_parm_count++;
|
||||
if ((tw = _dm_snprintf(params + pos, paramsize - pos, "clustered_")) < 0) {
|
||||
stack; /* Out of space */
|
||||
return -1;
|
||||
@@ -1701,18 +1704,19 @@ int dm_tree_node_add_mirror_target_log(struct dm_tree_node *node,
|
||||
seg = list_item(list_last(&node->props.segs), struct load_segment);
|
||||
|
||||
if (log_uuid) {
|
||||
if (!(log_node = dm_tree_find_node_by_uuid(node->dtree, log_uuid))) {
|
||||
log_error("Couldn't find mirror log uuid %s.", log_uuid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_link_tree_nodes(node, log_node))
|
||||
return_0;
|
||||
|
||||
if (!(seg->uuid = dm_pool_strdup(node->dtree->mem, log_uuid))) {
|
||||
log_error("log uuid pool_strdup failed");
|
||||
return 0;
|
||||
}
|
||||
if (!(flags & DM_CORELOG)) {
|
||||
if (!(log_node = dm_tree_find_node_by_uuid(node->dtree, log_uuid))) {
|
||||
log_error("Couldn't find mirror log uuid %s.", log_uuid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_link_tree_nodes(node, log_node))
|
||||
return_0;
|
||||
}
|
||||
}
|
||||
|
||||
seg->log = log_node;
|
||||
|
||||
123
libdm/libdm-string.c
Normal file
123
libdm/libdm-string.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of the device-mapper userspace tools.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use,
|
||||
* modify, copy, or redistribute it subject to the terms and conditions
|
||||
* of the GNU General Public License v.2.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "libdevmapper.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
* consume characters while they match the predicate function.
|
||||
*/
|
||||
static char *_consume(char *buffer, int (*fn) (int))
|
||||
{
|
||||
while (*buffer && fn(*buffer))
|
||||
buffer++;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static int _isword(int c)
|
||||
{
|
||||
return !isspace(c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Split buffer into NULL-separated words in argv.
|
||||
* Returns number of words.
|
||||
*/
|
||||
int dm_split_words(char *buffer, unsigned max, unsigned ignore_comments,
|
||||
char **argv)
|
||||
{
|
||||
unsigned arg;
|
||||
|
||||
for (arg = 0; arg < max; arg++) {
|
||||
buffer = _consume(buffer, isspace);
|
||||
if (!*buffer)
|
||||
break;
|
||||
|
||||
argv[arg] = buffer;
|
||||
buffer = _consume(buffer, _isword);
|
||||
|
||||
if (*buffer) {
|
||||
*buffer = '\0';
|
||||
buffer++;
|
||||
}
|
||||
}
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove hyphen quoting from a component of a name.
|
||||
* NULL-terminates the component and returns start of next component.
|
||||
*/
|
||||
static char *_unquote(char *component)
|
||||
{
|
||||
char *c = component;
|
||||
char *o = c;
|
||||
char *r;
|
||||
|
||||
while (*c) {
|
||||
if (*(c + 1)) {
|
||||
if (*c == '-') {
|
||||
if (*(c + 1) == '-')
|
||||
c++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
*o = *c;
|
||||
o++;
|
||||
c++;
|
||||
}
|
||||
|
||||
r = (*c) ? c + 1 : c;
|
||||
*o = '\0';
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int dm_split_lvm_name(struct dm_pool *mem, const char *dmname,
|
||||
char **vgname, char **lvname, char **layer)
|
||||
{
|
||||
if (!(*vgname = dm_pool_strdup(mem, dmname)))
|
||||
return 0;
|
||||
|
||||
_unquote(*layer = _unquote(*lvname = _unquote(*vgname)));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* On error, up to glibc 2.0.6, snprintf returned -1 if buffer was too small;
|
||||
* From glibc 2.1 it returns number of chars (excl. trailing null) that would
|
||||
* have been written had there been room.
|
||||
*
|
||||
* dm_snprintf reverts to the old behaviour.
|
||||
*/
|
||||
int dm_snprintf(char *buf, size_t bufsize, const char *format, ...)
|
||||
{
|
||||
int n;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
n = vsnprintf(buf, bufsize, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (n < 0 || (n > bufsize - 1))
|
||||
return -1;
|
||||
|
||||
return n;
|
||||
}
|
||||
@@ -77,15 +77,6 @@ void *dm_malloc_aux_debug(size_t s, const char *file, int line)
|
||||
nb->length = s;
|
||||
nb->id = ++_mem_stats.block_serialno;
|
||||
nb->next = 0;
|
||||
nb->prev = _tail;
|
||||
|
||||
/* link to tail of the list */
|
||||
if (!_head)
|
||||
_head = _tail = nb;
|
||||
else {
|
||||
_tail->next = nb;
|
||||
_tail = nb;
|
||||
}
|
||||
|
||||
/* stomp a pretty pattern across the new memory
|
||||
and fill in the boundary bytes */
|
||||
@@ -99,6 +90,16 @@ void *dm_malloc_aux_debug(size_t s, const char *file, int line)
|
||||
*ptr++ = (char) nb->id;
|
||||
}
|
||||
|
||||
nb->prev = _tail;
|
||||
|
||||
/* link to tail of the list */
|
||||
if (!_head)
|
||||
_head = _tail = nb;
|
||||
else {
|
||||
_tail->next = nb;
|
||||
_tail = nb;
|
||||
}
|
||||
|
||||
_mem_stats.blocks_allocated++;
|
||||
if (_mem_stats.blocks_allocated > _mem_stats.blocks_max)
|
||||
_mem_stats.blocks_max = _mem_stats.blocks_allocated;
|
||||
@@ -134,12 +135,6 @@ void dm_free_aux(void *p)
|
||||
|
||||
/* have we freed this before ? */
|
||||
assert(mb->id != 0);
|
||||
mb->id = 0;
|
||||
|
||||
/* stomp a different pattern across the memory */
|
||||
ptr = ((char *) mb) + sizeof(struct memblock);
|
||||
for (i = 0; i < mb->length; i++)
|
||||
*ptr++ = i & 1 ? (char) 0xde : (char) 0xad;
|
||||
|
||||
/* unlink */
|
||||
if (mb->prev)
|
||||
@@ -152,6 +147,13 @@ void dm_free_aux(void *p)
|
||||
else
|
||||
_tail = mb->prev;
|
||||
|
||||
mb->id = 0;
|
||||
|
||||
/* stomp a different pattern across the memory */
|
||||
ptr = ((char *) mb) + sizeof(struct memblock);
|
||||
for (i = 0; i < mb->length; i++)
|
||||
*ptr++ = i & 1 ? (char) 0xde : (char) 0xad;
|
||||
|
||||
assert(_mem_stats.blocks_allocated);
|
||||
_mem_stats.blocks_allocated--;
|
||||
_mem_stats.bytes -= mb->length;
|
||||
|
||||
@@ -195,8 +195,8 @@ clean: $(SUBDIRS.clean)
|
||||
$(SOURCES:%.c=%.pot) $(LDDEPS)
|
||||
|
||||
distclean: $(SUBDIRS.distclean)
|
||||
$(RM) $(OBJECTS) $(TARGETS) $(CLEAN_TARGETS) $(SOURCES:%.c=%.d) \
|
||||
$(SOURCES:%.c=%.pot) $(LDDEPS) \
|
||||
$(RM) $(OBJECTS) $(TARGETS) $(CLEAN_TARGETS) $(DISTCLEAN_TARGETS) \
|
||||
$(SOURCES:%.c=%.d) $(SOURCES:%.c=%.pot) $(LDDEPS) \
|
||||
config.cache config.log config.status \
|
||||
Makefile make.tmpl core \
|
||||
version.h lvm2.po
|
||||
|
||||
@@ -17,7 +17,8 @@ top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
MAN5=lvm.conf.5
|
||||
MAN8=lvchange.8 lvcreate.8 lvdisplay.8 lvextend.8 lvm.8 lvmchange.8 \
|
||||
MAN8=lvchange.8 lvconvert.8 lvcreate.8 lvdisplay.8 lvextend.8 lvm.8 \
|
||||
lvmchange.8 \
|
||||
lvmdiskscan.8 lvreduce.8 lvremove.8 lvrename.8 lvresize.8 lvs.8 \
|
||||
lvscan.8 pvchange.8 pvcreate.8 pvdisplay.8 pvmove.8 pvremove.8 \
|
||||
pvresize.8 pvs.8 pvscan.8 vgcfgbackup.8 vgcfgrestore.8 vgchange.8 \
|
||||
|
||||
@@ -4,12 +4,13 @@ dmsetup \- low level logical volume management
|
||||
.SH SYNOPSIS
|
||||
.ad l
|
||||
.B dmsetup create
|
||||
.I device_name [-u uuid] [--notable] [table_file]
|
||||
.I device_name [-u uuid] [--notable | --table <table> | table_file]
|
||||
.br
|
||||
.B dmsetup remove
|
||||
.I device_name
|
||||
.I [-f|--force] device_name
|
||||
.br
|
||||
.B dmsetup remove_all
|
||||
.I [-f|--force]
|
||||
.br
|
||||
.B dmsetup suspend
|
||||
.I [--nolockfs] device_name
|
||||
@@ -18,13 +19,13 @@ dmsetup \- low level logical volume management
|
||||
.I device_name
|
||||
.br
|
||||
.B dmsetup load
|
||||
.I device_name [table_file]
|
||||
.I device_name [--table <table> | table_file]
|
||||
.br
|
||||
.B dmsetup clear
|
||||
.I device_name
|
||||
.br
|
||||
.B dmsetup reload
|
||||
.I device_name [table_file]
|
||||
.I device_name [--table <table> | table_file]
|
||||
.br
|
||||
.B dmsetup rename
|
||||
.I device_name new_name
|
||||
@@ -100,10 +101,13 @@ Specify which fields to display. Only \fB-o\ name\fP is supported.
|
||||
.IP \fB-r|--readonly
|
||||
.br
|
||||
Set the table being loaded read-only.
|
||||
.IP \fB--table\ <table>
|
||||
.br
|
||||
Specify a one-line table directly on the command line.
|
||||
.IP \fB-u|--uuid
|
||||
.br
|
||||
Specify the uuid.
|
||||
.IP \fB-v|--verbose [-v|--verbose]
|
||||
.IP \fB-v|--verbose\ [-v|--verbose]
|
||||
.br
|
||||
Produce additional output.
|
||||
.IP \fB--version
|
||||
@@ -111,10 +115,10 @@ Produce additional output.
|
||||
Display the library and kernel driver version.
|
||||
.SH COMMANDS
|
||||
.IP \fBcreate
|
||||
.I device_name [-u uuid] [--notable] [table_file]
|
||||
.I device_name [-u uuid] [--notable | --table <table> | table_file]
|
||||
.br
|
||||
Creates a device with the given name.
|
||||
If table_file is supplied, the table is loaded and made live.
|
||||
If table_file or <table> is supplied, the table is loaded and made live.
|
||||
Otherwise a table is read from standard input unless --notable is used.
|
||||
The optional uuid can be used in place of
|
||||
device_name in subsequent dmsetup commands.
|
||||
@@ -159,19 +163,38 @@ device/nodevice; active, open, rw, uuid.
|
||||
Others specify how the tree is displayed:
|
||||
ascii, utf, vt100; compact, inverted, notrunc.
|
||||
.IP \fBload|reload
|
||||
.I device_name [table_file]
|
||||
.I device_name [--table <table> | table_file]
|
||||
.br
|
||||
Loads table_file into the inactive table slot for device_name.
|
||||
If table_file is not supplied, reads a table from standard input.
|
||||
Loads <table> or table_file into the inactive table slot for device_name.
|
||||
If neither is supplied, reads a table from standard input.
|
||||
.IP \fBmknodes
|
||||
.I [device_name]
|
||||
.br
|
||||
Ensure that the node in /dev/mapper for device_name is correct.
|
||||
If no device_name is supplied, ensure that all nodes in /dev/mapper
|
||||
correspond to mapped devices currently loaded by the device-mapper kernel
|
||||
driver, adding, changing or removing nodes as necessary.
|
||||
.IP \fBremove
|
||||
.I device_name
|
||||
.I [-f|--force] device_name
|
||||
.br
|
||||
Removes a device. It will no longer be visible to dmsetup and
|
||||
will be deleted when its open_count is zero.
|
||||
Removes a device. It will no longer be visible to dmsetup.
|
||||
Open devices cannot be removed except with older kernels
|
||||
that contain a version of device-mapper prior to 4.8.0.
|
||||
In this case the device will be deleted when its open_count
|
||||
drops to zero. From version 4.8.0 onwards, if a device can't
|
||||
be removed because an uninterruptible process is waiting for
|
||||
I/O to return from it, adding --force will replace the table
|
||||
with one that fails all I/O, which might allow the
|
||||
process to be killed.
|
||||
.IP \fBremove_all
|
||||
.I [-f|--force]
|
||||
.br
|
||||
Attempts to remove all device definitions i.e. reset the driver.
|
||||
Use with care!
|
||||
Use with care! From version 4.8.0 onwards, if devices can't
|
||||
be removed because uninterruptible processess are waiting for
|
||||
I/O to return from them, adding --force will replace the table
|
||||
with one that fails all I/O, which might allow the
|
||||
process to be killed. This also runs \fBmknodes\fP afterwards.
|
||||
.IP \fBrename
|
||||
.I device_name new_name
|
||||
.br
|
||||
|
||||
@@ -9,6 +9,7 @@ lvchange \- change attributes of a logical volume
|
||||
[\-C/\-\-contiguous y/n] [\-d/\-\-debug] [\-\-deltag Tag]
|
||||
[\-h/\-?/\-\-help]
|
||||
[\-\-ignorelockingfailure]
|
||||
[\-\-monitor {y|n}]
|
||||
[\-M/\-\-persistent y/n] [\-\-minor minor]
|
||||
[\-P/\-\-partial y/n]
|
||||
[\-p/\-\-permission r/w] [\-r/\-\-readahead ReadAheadSectors]
|
||||
@@ -42,6 +43,14 @@ allocated physical extents are already contiguous.
|
||||
.I \-\-minor minor
|
||||
Set the minor number.
|
||||
.TP
|
||||
.I \-\-monitor y/n
|
||||
Controls whether or not a mirrored logical volume is monitored by
|
||||
dmeventd, if it is installed.
|
||||
If a device used by a monitored mirror reports an I/O error,
|
||||
the failure is handled according to
|
||||
\fBmirror_image_fault_policy\fP and \fBmirror_log_fault_policy\fP
|
||||
set in \fBlvm.conf\fP.
|
||||
.TP
|
||||
.I \-M, \-\-persistent y/n
|
||||
Set to y to make the minor number specified persistent.
|
||||
.TP
|
||||
|
||||
57
man/lvconvert.8
Normal file
57
man/lvconvert.8
Normal file
@@ -0,0 +1,57 @@
|
||||
.TH LVCONVERT 8 "LVM TOOLS" "Red Hat, Inc" \" -*- nroff -*-
|
||||
.SH NAME
|
||||
lvconvert \- convert a logical volume between linear and mirror
|
||||
.SH SYNOPSIS
|
||||
.B lvconvert
|
||||
[\-m/\-\-mirrors Mirrors [\-\-corelog]]
|
||||
[\-A/\-\-alloc AllocationPolicy]
|
||||
[\-h/\-?/\-\-help]
|
||||
[\-v/\-\-verbose]
|
||||
[\-\-version]
|
||||
LogicalVolume[Path] [PhysicalVolume[Path]...]
|
||||
.SH DESCRIPTION
|
||||
lvconvert will change a linear logical volume to a mirror
|
||||
logical volume or vis versa. It is also used to add and
|
||||
remove disk logs from mirror devices.
|
||||
.SH OPTIONS
|
||||
See \fBlvm\fP for common options.
|
||||
.TP
|
||||
.I \-m, \-\-mirrors Mirrors
|
||||
Specifies the degree of the mirror you wish to create.
|
||||
For example, "-m 1" would convert the original logical
|
||||
volume to a mirror volume with 2-sides; that is, a
|
||||
linear volume plus one copy.
|
||||
.TP
|
||||
.I \-\-corelog
|
||||
This optional argument tells lvconvert to switch the
|
||||
mirror from using a disk-based (persistent) log to
|
||||
an in-memory log. You may only specify this option
|
||||
when the \-\-mirror argument is the same degree of
|
||||
the mirror you are changing.
|
||||
.SH Examples
|
||||
"lvconvert -m1 vg00/lvol1"
|
||||
.br
|
||||
converts the linear logical volume "vg00/lvol1" to
|
||||
a mirror logical volume. This command could also
|
||||
be used to convert a two-way mirror with an
|
||||
in-memory log to a two-way mirror with a disk log.
|
||||
|
||||
"lvconvert -m1 --corelog vg00/lvol1"
|
||||
.br
|
||||
converts a two-way mirror with a disk log to a
|
||||
two-way mirror with an in-memory log.
|
||||
|
||||
"lvconvert -m0 vg00/lvol1"
|
||||
.br
|
||||
converts a mirror logical volume to a linear logical
|
||||
volume.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR lvm (8),
|
||||
.BR vgcreate (8),
|
||||
.BR lvremove (8),
|
||||
.BR lvrename (8),
|
||||
.BR lvextend (8),
|
||||
.BR lvreduce (8),
|
||||
.BR lvdisplay (8),
|
||||
.BR lvscan (8)
|
||||
@@ -11,6 +11,7 @@ lvcreate \- create a logical volume in an existing volume group
|
||||
{\-l/\-\-extents LogicalExtentsNumber |
|
||||
\-L/\-\-size LogicalVolumeSize[kKmMgGtT]}
|
||||
[\-M/\-\-persistent y/n] [\-\-minor minor]
|
||||
[\-m/\-\-mirrors Mirrors [\-\-nosync] [\-\-corelog]]
|
||||
[\-n/\-\-name LogicalVolumeName]
|
||||
[\-p/\-\-permission r/rw] [\-r/\-\-readahead ReadAheadSectors]
|
||||
[-R|--regionsize MirrorLogRegionSize]
|
||||
@@ -79,6 +80,23 @@ Set the minor number.
|
||||
.I \-M, \-\-persistent y/n
|
||||
Set to y to make the minor number specified persistent.
|
||||
.TP
|
||||
.I \-m, \-\-mirrors Mirrors
|
||||
Creates a mirrored logical volume with "Mirrors" copies. For example,
|
||||
specifying "-m 1" would result in a mirror with two-sides; that is, a
|
||||
linear volume plus one copy.
|
||||
|
||||
Specifying the optional argument "--nosync" will cause the creation
|
||||
of the mirror to skip the initial resynchronization. Any data written
|
||||
afterwards will be mirrored, but the original contents will not be
|
||||
copied. This is useful for skipping a potentially long and resource
|
||||
intensive initial sync.
|
||||
|
||||
Specifying the optional argument "--corelog" will create a mirror with
|
||||
an in-memory log verses a disk-based (persistent) log. While this
|
||||
removes the need for an extra log device and *may* be slightly faster,
|
||||
it requires that the entire mirror be resynchronized upon each
|
||||
instantiation (e.g. a reboot).
|
||||
.TP
|
||||
.I \-n, \-\-name LogicalVolumeName
|
||||
The name for the new logical volume.
|
||||
.br
|
||||
@@ -122,10 +140,15 @@ Default is yes.
|
||||
Warning: trying to mount an unzeroed logical volume can cause the system to
|
||||
hang.
|
||||
.SH Examples
|
||||
"lvcreate -i 3 -I 8 -L 100 vg00" tries to create a striped logical
|
||||
"lvcreate -i 3 -I 8 -L 100M vg00" tries to create a striped logical
|
||||
volume with 3 stripes, a stripesize of 8KB and a size of 100MB in the volume
|
||||
group named vg00. The logical volume name will be chosen by lvcreate.
|
||||
|
||||
"lvcreate -m1 -L 500M vg00" tries to create a mirror logical volume
|
||||
with 2 sides with a useable size of 500 MiB. This operation would
|
||||
require 3 devices - two for the mirror devices and one for the disk
|
||||
log.
|
||||
|
||||
"lvcreate --size 100m --snapshot --name snap /dev/vg00/lvol1"
|
||||
.br
|
||||
creates a snapshot logical volume named /dev/vg00/snap which has access to the
|
||||
|
||||
@@ -15,6 +15,9 @@ lvextend allows you to extend the size of a logical volume.
|
||||
Extension of snapshot logical volumes (see
|
||||
.B lvcreate(8)
|
||||
for information to create snapshots) is supported as well.
|
||||
But to change the number of copies in a mirrored logical
|
||||
volume use
|
||||
.BR lvconvert (8).
|
||||
.SH OPTIONS
|
||||
See \fBlvm\fP for common options.
|
||||
.TP
|
||||
@@ -48,6 +51,7 @@ there are enough free physical extents in it.
|
||||
.SH SEE ALSO
|
||||
.BR lvm (8),
|
||||
.BR lvcreate (8),
|
||||
.BR lvconvert (8),
|
||||
.BR lvreduce (8),
|
||||
.BR lvresize (8),
|
||||
.BR lvchange (8)
|
||||
|
||||
@@ -38,7 +38,7 @@ The following commands are built into lvm without links normally
|
||||
being created in the filesystem for them.
|
||||
.TP
|
||||
\fBdumpconfig\fP \(em Display the configuration information after
|
||||
loading \fBlvm.conf\fP (8) and any other configuration files.
|
||||
loading \fBlvm.conf\fP (5) and any other configuration files.
|
||||
.TP
|
||||
\fBformats\fP \(em Display recognised metadata formats.
|
||||
.TP
|
||||
|
||||
@@ -252,7 +252,7 @@ if \fBlocking_type\fP is set to 1. The default is \fB/var/lock/lvm\fP.
|
||||
.IP
|
||||
\fBlocking_library\fP \(em The name of the external locking
|
||||
library to load if \fBlocking_type\fP is set to 2.
|
||||
The default is \fBlvm2_locking.so\fP. If you need to write
|
||||
The default is \fBliblvm2clusterlock.so\fP. If you need to write
|
||||
such a library, look at the lib/locking source code directory.
|
||||
.TP
|
||||
\fBtags\fP \(em Host tag settings
|
||||
|
||||
@@ -21,10 +21,14 @@ running lvreduce so that the extents that are to be removed are not in use.
|
||||
Shrinking snapshot logical volumes (see
|
||||
.B lvcreate(8)
|
||||
for information to create snapshots) is supported as well.
|
||||
But to change the number of copies in a mirrored logical
|
||||
volume use
|
||||
.B lvconvert (8).
|
||||
.br
|
||||
Sizes will be rounded if necessary - for example, the volume size must
|
||||
be an exact number of extents and the size of a striped segment must
|
||||
be a multiple of the number of stripes.
|
||||
.br
|
||||
.SH OPTIONS
|
||||
See \fBlvm\fP for common options.
|
||||
.TP
|
||||
@@ -49,6 +53,7 @@ an absolute size.
|
||||
in volume group vg00 by 3 logical extents.
|
||||
.SH SEE ALSO
|
||||
.BR lvchange (8),
|
||||
.BR lvconvert (8),
|
||||
.BR lvcreate (8),
|
||||
.BR lvextend (8),
|
||||
.BR lvm (8),
|
||||
|
||||
@@ -19,6 +19,9 @@ shrunk first so that the extents that are to be removed are not in use.
|
||||
Resizing snapshot logical volumes (see
|
||||
.B lvcreate(8)
|
||||
for information about creating snapshots) is supported as well.
|
||||
But to change the number of copies in a mirrored logical
|
||||
volume use
|
||||
.BR lvconvert (8).
|
||||
.SH OPTIONS
|
||||
See \fBlvm\fP for common options.
|
||||
.TP
|
||||
@@ -49,6 +52,7 @@ must use a single value throughout.
|
||||
StripeSize must be 2^n (n = 2 to 9)
|
||||
.SH SEE ALSO
|
||||
.BR lvm (8),
|
||||
.BR lvconvert (8),
|
||||
.BR lvcreate (8),
|
||||
.BR lvreduce (8),
|
||||
.BR lvchange (8)
|
||||
|
||||
@@ -44,7 +44,7 @@ can also be chosen.
|
||||
The lv_attr bits are:
|
||||
.RS
|
||||
.IP 1 3
|
||||
Volume type: (m)irrored, (o)rigin, (p)vmove, (s)napshot,
|
||||
Volume type: (m)irrored, (M)irrored without initial sync, (o)rigin, (p)vmove, (s)napshot,
|
||||
invalid (S)napshot, (v)irtual
|
||||
.IP 2 3
|
||||
Permissions: (w)riteable, (r)ead-only
|
||||
|
||||
@@ -9,6 +9,7 @@ vgchange \- change attributes of a volume group
|
||||
.IR AllocationPolicy ]
|
||||
.RB [ \-A | \-\-autobackup " {" y | n }]
|
||||
.RB [ \-a | \-\-available " [e|l] {" y | n }]
|
||||
.RB [ \-\-monitor " {" y | n }]
|
||||
.RB [ \-d | \-\-debug]
|
||||
.RB [ \-\-deltag
|
||||
.IR Tag ]
|
||||
@@ -16,6 +17,8 @@ vgchange \- change attributes of a volume group
|
||||
.RB [ \-\-ignorelockingfailure]
|
||||
.RB [ \-l | \-\-logicalvolume
|
||||
.IR MaxLogicalVolumes ]
|
||||
.RB [ -p | \-\-maxphysicalvolumes
|
||||
.IR MaxPhysicalVolumes ]
|
||||
.RB [ \-P | \-\-partial]
|
||||
.RB [ \-s | \-\-physicalextentsize
|
||||
.IR PhysicalExtentSize [ \fBkKmMgGtT\fR ]]
|
||||
@@ -57,10 +60,33 @@ on the local node.
|
||||
Logical volumes with single-host snapshots are always activated
|
||||
exclusively because they can only be used on one node at once.
|
||||
.TP
|
||||
.BR \-\-monitor " " { y | n }
|
||||
Controls whether or not a mirrored logical volume is monitored by
|
||||
dmeventd, if it is installed.
|
||||
If a device used by a monitored mirror reports an I/O error,
|
||||
the failure is handled according to
|
||||
.BR mirror_image_fault_policy
|
||||
and
|
||||
.BR mirror_log_fault_policy
|
||||
set in
|
||||
.BR lvm.conf (5).
|
||||
.TP
|
||||
.BR \-l ", " \-\-logicalvolume " " \fIMaxLogicalVolumes\fR
|
||||
Changes the maximum logical volume number of an existing inactive
|
||||
volume group.
|
||||
.TP
|
||||
.BR \-p ", " \-\-maxphysicalvolumes " " \fIMaxPhysicalVolumes\fR
|
||||
Changes the maximum number of physical volumes that can belong
|
||||
to this volume group.
|
||||
For volume groups with metadata in lvm1 format, the limit is 255.
|
||||
If the metadata uses lvm2 format, the value 0
|
||||
removes this restriction: there is then no limit.
|
||||
If you have a large number of physical volumes in
|
||||
a volume group with metadata in lvm2 format,
|
||||
for tool performance reasons, you should consider
|
||||
some use of \fB--metadatacopies 0\fP
|
||||
as described in \fBpvcreate(8)\fP.
|
||||
.TP
|
||||
.BR \-s ", " \-\-physicalextentsize " " \fIPhysicalExtentSize\fR[\fBkKmMgGtT\fR]
|
||||
Changes the physical extent size on physical volumes of this volume group.
|
||||
A size suffix (k for kilobytes up to t for terabytes) is optional, megabytes
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user