1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-12-27 00:23:49 +03:00

Compare commits

..

42 Commits

Author SHA1 Message Date
Alasdair Kergon
ae6918742e pre-release 2006-09-19 17:43:03 +00:00
Alasdair Kergon
863484bb65 Reorder mm bounds_check code to reduce window for a dmeventd race. (dm_free_aux) 2006-09-19 17:30:04 +00:00
Alasdair Kergon
1cd7ebce4c 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() for generalisation.
Avoid adding duplicates to list of parallel PVs to avoid.
2006-09-11 21:14:56 +00:00
Alasdair Kergon
eef8c7862e 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.
2006-09-11 14:24:58 +00:00
Alasdair Kergon
b52375d446 fix vgreduce clustered check 2006-09-07 23:23:45 +00:00
Alasdair Kergon
6e2babc2ce When using local file locking, skip clustered VGs.
Add fallback_to_clustered_locking and fallback_to_local_locking parameters.
2006-09-02 01:18:17 +00:00
Alasdair Kergon
08e253bed1 lvm.static uses built-in cluster locking instead of external locking.
Don't attempt to load shared libraries if built statically.
2006-08-31 22:21:00 +00:00
Alasdair Kergon
c6661477a2 Change default locking_lib to liblvm2clusterlock.so. 2006-08-31 20:56:33 +00:00
Alasdair Kergon
415cfd99a0 Add skip_dev_dir() to process command line VGs. 2006-08-25 23:02:33 +00:00
Patrick Caulfield
8c2e37381a Stop clvmd complaining about nodes that have left the cluster 2006-08-24 12:45:05 +00:00
Alasdair Kergon
45df79feba stub.h shouldn't be here 2006-08-22 15:56:06 +00:00
Patrick Caulfield
5824f992b7 Add needed new parameter to create_toolcontext(). 2006-08-22 09:49:20 +00:00
Alasdair Kergon
b0b60fafd5 Move lvm_snprintf into libdevmapper. 2006-08-21 12:54:53 +00:00
Alasdair Kergon
8d98b02ba2 Add dm_snprintf 2006-08-21 12:52:39 +00:00
Alasdair Kergon
a93fe79bc4 Add dm_split_words() and dm_split_lvm_name() to libdevmapper. 2006-08-21 12:07:03 +00:00
Alasdair Kergon
4aebd7be37 fix lvm.conf (5) refs 2006-08-18 22:35:59 +00:00
Alasdair Kergon
3170a5db32 mirror man page tweaks 2006-08-18 22:27:01 +00:00
Alasdair Kergon
3605b9eef6 Add mirroring into man pages 2006-08-18 21:49:19 +00:00
Alasdair Kergon
a945f1fde2 reorder bounds check code 2006-08-18 21:38:58 +00:00
Alasdair Kergon
461a997b5b Prevent mirror renames. 2006-08-18 21:19:54 +00:00
Alasdair Kergon
a80afd7b4e Move CMDLIB code into separate file and record whether static build. 2006-08-18 21:17:18 +00:00
Alasdair Kergon
aad2b51d85 post 2006-08-17 20:04:38 +00:00
Alasdair Kergon
36a9a81ff1 wrappers files 2006-08-17 19:56:28 +00:00
Alasdair Kergon
42c88546ae pre-release 2006-08-17 19:55:50 +00:00
Alasdair Kergon
0f0e86ef9b Fix PE_ALIGN for pagesize over 32KB. 2006-08-17 19:53:36 +00:00
Alasdair Kergon
98efd9a857 wrap PE_ALIGN 2006-08-17 19:30:59 +00:00
Alasdair Kergon
a0c27d95b7 Separate out LVM1_PE_ALIGN. 2006-08-17 19:15:27 +00:00
Alasdair Kergon
984651d99d Add lvm_getpagesize wrapper. 2006-08-17 18:23:44 +00:00
Alasdair Kergon
c6f7370b30 Add --maxphysicalvolumes to vgchange. 2006-08-16 14:41:42 +00:00
Alasdair Kergon
3e4b8e8985 post-release 2006-08-15 19:13:06 +00:00
Alasdair Kergon
73f08b98d2 pre-release 2006-08-15 19:06:09 +00:00
Alasdair Kergon
8607a74206 post-release 2006-08-15 17:43:10 +00:00
Alasdair Kergon
8339f3ceb3 pre-release 2006-08-15 17:38:38 +00:00
Alasdair Kergon
c0c9f3cc19 fix getopt_long error check 2006-08-10 20:53:21 +00:00
Alasdair Kergon
81f4813c29 Add --table argument to dmsetup for a one-line table.
Abort if errors are found during cmdline option processing.
2006-08-10 14:11:03 +00:00
Alasdair Kergon
94f57745b9 Add checks for duplicate LV name, lvid and PV id before writing metadata.
Report all sanity check failures, not just the first.
2006-08-09 19:33:25 +00:00
Alasdair Kergon
54fb2ebbe0 Add lockfs indicator to debug output. 2006-08-08 21:22:31 +00:00
Alasdair Kergon
02d122b65b Fix missing lockfs on first snapshot creation. 2006-08-08 21:20:00 +00:00
Alasdair Kergon
df0a5561a1 Add --trustcache option to reporting commands in preparation for supporting
event-driven model.  Without changes to the way the cache gets updated, the
option is currently unreliable without a global lock to prevent any lvm2
commands from running concurrently.
2006-08-01 14:56:33 +00:00
Alasdair Kergon
f7c55da7d0 Fix locking for mimage removal. 2006-07-20 20:37:10 +00:00
Alasdair Kergon
b385f701ce Fix clvmd_init_rhel4 'status' exit code. 2006-07-19 18:55:58 +00:00
Alasdair Kergon
05dd42f443 post-release 2006-07-17 14:39:54 +00:00
99 changed files with 1358 additions and 583 deletions

View File

@@ -1 +1 @@
2.02.07-cvs (2006-07-17)
2.02.10-cvs (2006-08-17)

View File

@@ -1,3 +1,44 @@
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.

View File

@@ -1,3 +1,14 @@
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.

8
configure vendored
View File

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

View File

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

View File

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

View File

@@ -539,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;
}

View File

@@ -48,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;
}
@@ -121,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;

View File

@@ -48,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;
}
@@ -121,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;

View File

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

View File

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

View File

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

View File

@@ -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;
@@ -257,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;
}
@@ -342,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);
@@ -528,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;
@@ -536,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);
@@ -637,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;
@@ -672,7 +673,11 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
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;

View File

@@ -37,6 +37,7 @@ typedef enum {
ACTIVATE,
DEACTIVATE,
SUSPEND,
SUSPEND_WITH_LOCKFS,
CLEAN
} action_t;
@@ -911,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;
}
@@ -937,7 +938,7 @@ static int _clean_tree(struct dev_manager *dm, struct dm_tree_node *root)
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;
}
@@ -984,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;
@@ -1049,9 +1050,10 @@ 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);
}
/*

View File

@@ -47,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);

View File

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

View File

@@ -241,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;
}

View File

@@ -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.");
@@ -167,7 +167,7 @@ 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/",
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");
@@ -178,7 +178,7 @@ static int _process_config(struct cmd_context *cmd)
#endif
/* proc dir */
if (lvm_snprintf(cmd->proc_dir, sizeof(cmd->proc_dir), "%s",
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");
@@ -319,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;
@@ -587,7 +587,7 @@ 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);
@@ -646,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_tree_node(cmd, "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 *);
@@ -740,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_tree_node(cmd, "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 *);
@@ -839,7 +841,7 @@ static int _init_backup(struct cmd_context *cmd)
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'.",
@@ -860,7 +862,7 @@ static int _init_backup(struct cmd_context *cmd)
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'.",
@@ -879,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;
@@ -902,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);

View File

@@ -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? */
@@ -87,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);

View File

@@ -187,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);

View File

@@ -32,7 +32,9 @@
#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"

View File

@@ -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) */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -233,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;
}
/*
@@ -623,7 +623,7 @@ static int _build_pv_names(struct formatter *f, struct volume_group *vg)
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)
if (dm_snprintf(buffer, sizeof(buffer), "pv%d", count++) < 0)
return_0;
if (!(name = dm_pool_strdup(f->mem, buffer)))

View File

@@ -853,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);
@@ -994,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,
@@ -1005,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;
@@ -1055,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);
@@ -1189,18 +1189,18 @@ 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
@@ -1533,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);

View File

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

View File

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

View File

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

View File

@@ -20,6 +20,7 @@
#include "activate.h"
#include "toolcontext.h"
#include "memlock.h"
#include "defaults.h"
#include <signal.h>
#include <sys/stat.h>
@@ -134,24 +135,31 @@ int init_locking(int type, struct cmd_context *cmd)
return 1;
case 1:
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, cmd))
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:
log_very_verbose("Cluster locking selected.");
if (!init_cluster_locking(&_locking, cmd))
break;
log_very_verbose("Cluster locking enabled.");
return 1;
#endif
@@ -160,6 +168,16 @@ int init_locking(int type, struct cmd_context *cmd)
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;
@@ -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;

View File

@@ -32,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;
@@ -163,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;
@@ -237,6 +243,11 @@ int full_scan_done()
return _full_scan_done;
}
int trust_cache()
{
return _trust_cache;
}
int lockingfailed()
{
return _lockingfailed;
@@ -307,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';
@@ -402,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;

View File

@@ -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);
@@ -83,6 +84,7 @@ 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);

View File

@@ -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,
@@ -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) {
@@ -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;
}

View File

@@ -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)
{
@@ -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;
}
/*

View File

@@ -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 */
@@ -403,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);

View File

@@ -199,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;
@@ -211,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;
@@ -223,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;
@@ -412,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;

View File

@@ -28,6 +28,7 @@
#include "log.h"
#include "intl.h"
#include "lvm-types.h"
#include "lvm-wrappers.h"
#include <libdevmapper.h>

View File

@@ -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.");

View File

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

View File

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

View File

@@ -17,6 +17,7 @@
#include "config.h"
#include "lvm-string.h"
#include "sharedlib.h"
#include "toolcontext.h"
#include <limits.h>
#include <sys/stat.h>
@@ -32,7 +33,7 @@ void get_shared_library_path(struct cmd_context *cmd, const char *libname,
* if present */
if (libname[0] == '/' ||
!(lib_dir = find_config_tree_str(cmd, "global/library_dir", 0)) ||
(lvm_snprintf(path, path_len, "%s/%s", lib_dir,
(dm_snprintf(path, path_len, "%s/%s", lib_dir,
libname) == -1) || stat(path, &info) == -1)
strncpy(path, libname, path_len);
}
@@ -43,6 +44,12 @@ void *load_shared_library(struct cmd_context *cmd, const char *libname,
char path[PATH_MAX];
void *library;
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);

View File

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

View File

@@ -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;
}
@@ -540,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;
}
@@ -784,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;
}
@@ -813,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;
}
@@ -870,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;
}
@@ -910,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;
}
@@ -1324,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);
@@ -1467,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);
@@ -1476,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);

View File

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

View File

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

View File

@@ -1543,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 : "",
@@ -1554,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

View File

@@ -17,6 +17,7 @@
#define LIB_DEVICE_MAPPER_H
#include <inttypes.h>
#include <stdarg.h>
#include <sys/types.h>
#ifdef linux
@@ -582,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 */

123
libdm/libdm-string.c Normal file
View 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;
}

View File

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

View File

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

View File

@@ -4,7 +4,7 @@ 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 [-f|--force] device_name
@@ -19,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
@@ -101,6 +101,9 @@ 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.
@@ -112,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.
@@ -160,10 +163,10 @@ 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -11,7 +11,7 @@ vgscan \- scan all disks for volume groups and rebuild caches
.SH DESCRIPTION
vgscan scans all SCSI, (E)IDE disks, multiple devices and a bunch
of other disk devices in the system looking for LVM physical volumes
and volume groups. Define a filter in \fBlvm.conf\fP(8) to restrict
and volume groups. Define a filter in \fBlvm.conf\fP(5) to restrict
the scan to avoid a CD ROM, for example.
.LP
In LVM2, vgscans take place automatically; but you might still need to

View File

@@ -119,9 +119,9 @@ case "$1" in
status)
status clvmd
rtrn=$?
vols=$( $LVDISPLAY -C --nohead 2> /dev/null | awk '($3 ~ /....a./) {print $1}' )
echo active volumes: ${vols:-"(none)"}
rtrn=0
;;
*)

View File

@@ -80,7 +80,9 @@ endif
LVMLIBS = -llvm
CLEAN_TARGETS = liblvm2cmd.so liblvm2cmd.a lvm lvm.o lvm.static lvm.cflow lvm.xref lvm.tree lvm.rxref lvm.rtree
CLEAN_TARGETS = liblvm2cmd.so liblvm2cmd.a liblvm2cmd-static.a lvm lvm.o \
lvm2cmd.o lvm2cmd-static.o lvm2cmdlib.o lvm.static \
lvm.cflow lvm.xref lvm.tree lvm.rxref lvm.rtree
ifeq ("@CMDLIB@", "yes")
TARGETS += liblvm2cmd.so
@@ -104,9 +106,13 @@ lvm.static: $(OBJECTS) lvm-static.o $(top_srcdir)/lib/liblvm.a
$(CC) -o $@ $(OBJECTS) lvm-static.o -static $(LDFLAGS) $(LVMLIBS) \
$(LIBS) -rdynamic
liblvm2cmd.a: $(top_srcdir)/lib/liblvm.a $(OBJECTS)
liblvm2cmd.a: $(top_srcdir)/lib/liblvm.a $(OBJECTS) lvmcmdlib.o lvm2cmd.o
cat $(top_srcdir)/lib/liblvm.a > $@
$(AR) rs $@ $(OBJECTS)
$(AR) rs $@ $(OBJECTS) lvmcmdlib.o lvm2cmd.o
liblvm2cmd-static.a: $(top_srcdir)/lib/liblvm.a $(OBJECTS) lvmcmdlib.o lvm2cmd-static.o
cat $(top_srcdir)/lib/liblvm.a > $@
$(AR) rs $@ $(OBJECTS) lvmcmdlib.o lvm2cmd-static.o
liblvm2cmd.so: liblvm2cmd.a $(LDDEPS)
@@ -141,8 +147,8 @@ install_cmdlib_dynamic: liblvm2cmd.so
$(INSTALL) -D $(OWNER) $(GROUP) -m 444 lvm2cmd.h \
$(includedir)/lvm2cmd.h
install_cmdlib_static: liblvm2cmd.a
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) liblvm2cmd.a \
install_cmdlib_static: liblvm2cmd-static.a
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) liblvm2cmd-static.a \
$(libdir)/liblvm2cmd.a.$(LIB_VERSION)
$(LN_S) -f liblvm2cmd.a.$(LIB_VERSION) $(libdir)/liblvm2cmd.a
$(INSTALL) -D $(OWNER) $(GROUP) -m 444 lvm2cmd.h \

View File

@@ -49,6 +49,7 @@ arg(nosync_ARG, '\0', "nosync", NULL)
arg(corelog_ARG, '\0', "corelog", NULL)
arg(monitor_ARG, '\0', "monitor", yes_no_arg)
arg(config_ARG, '\0', "config", string_arg)
arg(trustcache_ARG, '\0', "trustcache", NULL)
/* Allow some variations */
arg(resizable_ARG, '\0', "resizable", yes_no_arg)

View File

@@ -343,6 +343,7 @@ xx(lvs,
"\t[-P|--partial] " "\n"
"\t[--segments]\n"
"\t[--separator Separator]\n"
"\t[--trustcache]\n"
"\t[--unbuffered]\n"
"\t[--units hsbkmgtHKMGT]\n"
"\t[-v|--verbose]\n"
@@ -351,7 +352,7 @@ xx(lvs,
aligned_ARG, all_ARG, ignorelockingfailure_ARG, noheadings_ARG,
nolocking_ARG, nosuffix_ARG, options_ARG, partial_ARG, segments_ARG,
separator_ARG, sort_ARG, unbuffered_ARG, units_ARG)
separator_ARG, sort_ARG, trustcache_ARG, unbuffered_ARG, units_ARG)
xx(lvscan,
"List all logical volumes in all volume groups",
@@ -527,6 +528,7 @@ xx(pvs,
"\t[-P|--partial] " "\n"
"\t[--segments]\n"
"\t[--separator Separator]\n"
"\t[--trustcache]\n"
"\t[--unbuffered]\n"
"\t[--units hsbkmgtHKMGT]\n"
"\t[-v|--verbose]\n"
@@ -535,7 +537,7 @@ xx(pvs,
aligned_ARG, all_ARG, ignorelockingfailure_ARG, noheadings_ARG,
nolocking_ARG, nosuffix_ARG, options_ARG, partial_ARG, segments_ARG,
separator_ARG, sort_ARG, unbuffered_ARG, units_ARG)
separator_ARG, sort_ARG, trustcache_ARG, unbuffered_ARG, units_ARG)
xx(pvscan,
"List all physical volumes",
@@ -605,6 +607,7 @@ xx(vgchange,
"\t -c|--clustered {y|n} |" "\n"
"\t -x|--resizeable {y|n} |" "\n"
"\t -l|--logicalvolume MaxLogicalVolumes |" "\n"
"\t -p|--maxphysicalvolumes MaxPhysicalVolumes |" "\n"
"\t -s|--physicalextentsize PhysicalExtentSize[kKmMgGtT] |" "\n"
"\t --addtag Tag |\n"
"\t --deltag Tag}\n"
@@ -612,8 +615,8 @@ xx(vgchange,
addtag_ARG, alloc_ARG, allocation_ARG, autobackup_ARG, available_ARG,
clustered_ARG, deltag_ARG, ignorelockingfailure_ARG, logicalvolume_ARG,
monitor_ARG, partial_ARG, physicalextentsize_ARG, resizeable_ARG,
resizable_ARG, test_ARG, uuid_ARG)
maxphysicalvolumes_ARG, monitor_ARG, partial_ARG, physicalextentsize_ARG,
resizeable_ARG, resizable_ARG, test_ARG, uuid_ARG)
xx(vgck,
"Check the consistency of volume group(s)",
@@ -819,6 +822,7 @@ xx(vgs,
"\t[-O|--sort [+|-]key1[,[+|-]key2[,...]]]\n"
"\t[-P|--partial] " "\n"
"\t[--separator Separator]\n"
"\t[--trustcache]\n"
"\t[--unbuffered]\n"
"\t[--units hsbkmgtHKMGT]\n"
"\t[-v|--verbose]\n"
@@ -827,7 +831,7 @@ xx(vgs,
aligned_ARG, all_ARG, ignorelockingfailure_ARG, noheadings_ARG,
nolocking_ARG, nosuffix_ARG, options_ARG, partial_ARG, separator_ARG,
sort_ARG, unbuffered_ARG, units_ARG)
sort_ARG, trustcache_ARG, unbuffered_ARG, units_ARG)
xx(vgscan,
"Search for all volume groups",

View File

@@ -98,6 +98,7 @@ enum {
NOOPENCOUNT_ARG,
NOTABLE_ARG,
OPTIONS_ARG,
TABLE_ARG,
TARGET_ARG,
TREE_ARG,
UID_ARG,
@@ -112,6 +113,7 @@ static int _values[NUM_SWITCHES];
static int _num_devices;
static char *_uuid;
static char *_fields;
static char *_table;
static char *_target;
static char *_command;
static struct dm_tree *_dtree;
@@ -119,17 +121,55 @@ static struct dm_tree *_dtree;
/*
* Commands
*/
static int _parse_line(struct dm_task *dmt, char *buffer, const char *file,
int line)
{
char ttype[LINE_SIZE], *ptr, *comment;
unsigned long long start, size;
int n;
/* trim trailing space */
for (ptr = buffer + strlen(buffer) - 1; ptr >= buffer; ptr--)
if (!isspace((int) *ptr))
break;
ptr++;
*ptr = '\0';
/* trim leading space */
for (ptr = buffer; *ptr && isspace((int) *ptr); ptr++)
;
if (!*ptr || *ptr == '#')
return 1;
if (sscanf(ptr, "%llu %llu %s %n",
&start, &size, ttype, &n) < 3) {
err("Invalid format on line %d of table %s", line, file);
return 0;
}
ptr += n;
if ((comment = strchr(ptr, (int) '#')))
*comment = '\0';
if (!dm_task_add_target(dmt, start, size, ttype, ptr))
return 0;
return 1;
}
static int _parse_file(struct dm_task *dmt, const char *file)
{
char *buffer = NULL;
size_t buffer_size = 0;
char ttype[LINE_SIZE], *ptr, *comment;
FILE *fp;
unsigned long long start, size;
int r = 0, n, line = 0;
int r = 0, line = 0;
/* one-line table on cmdline */
if (_table)
return _parse_line(dmt, _table, "", ++line);
/* OK for empty stdin */
if (file) {
if (!(fp = fopen(file, "r"))) {
err("Couldn't open '%s' for reading", file);
@@ -145,38 +185,13 @@ static int _parse_file(struct dm_task *dmt, const char *file)
return 0;
}
while (fgets(buffer, (int) buffer_size, fp)) {
while (fgets(buffer, (int) buffer_size, fp))
#else
while (getline(&buffer, &buffer_size, fp) > 0) {
while (getline(&buffer, &buffer_size, fp) > 0)
#endif
line++;
/* trim trailing space */
for (ptr = buffer + strlen(buffer) - 1; ptr >= buffer; ptr--)
if (!isspace((int) *ptr))
break;
ptr++;
*ptr = '\0';
/* trim leading space */
for (ptr = buffer; *ptr && isspace((int) *ptr); ptr++) ;
if (!*ptr || *ptr == '#')
continue;
if (sscanf(ptr, "%llu %llu %s %n",
&start, &size, ttype, &n) < 3) {
err("%s:%d Invalid format", file, line);
if (!_parse_line(dmt, buffer, file ? : "on stdin", ++line))
goto out;
}
ptr += n;
if ((comment = strchr(ptr, (int) '#')))
*comment = '\0';
if (!dm_task_add_target(dmt, start, size, ttype, ptr))
goto out;
}
r = 1;
out:
@@ -725,23 +740,23 @@ static int _error_device(int argc __attribute((unused)), char **argv __attribute
size = _get_device_size(name);
if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
return 0;
if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
return 0;
if (!_set_task_device(dmt, name, 0))
goto err;
if (!dm_task_add_target(dmt, 0, size, "error", ""))
if (!dm_task_add_target(dmt, 0, size, "error", ""))
goto err;
if (_switches[READ_ONLY] && !dm_task_set_ro(dmt))
goto err;
if (_switches[READ_ONLY] && !dm_task_set_ro(dmt))
goto err;
if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
goto err;
if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
goto err;
if (!dm_task_run(dmt))
goto err;
if (!dm_task_run(dmt))
goto err;
if (!_simple(DM_DEVICE_RESUME, name, 0, 0)) {
_simple(DM_DEVICE_CLEAR, name, 0, 0);
@@ -1472,7 +1487,8 @@ struct command {
static struct command _commands[] = {
{"create", "<dev_name> [-j|--major <major> -m|--minor <minor>]\n"
"\t [-U|--uid <uid>] [-G|--gid <gid>] [-M|--mode <octal_mode>]\n"
"\t [-u|uuid <uuid>] [--notable] [<table_file>]",
"\t [-u|uuid <uuid>]"
"\t [--notable | --table <table> | <table_file>]",
1, 2, _create},
{"remove", "[-f|--force] <device>", 0, 1, _remove},
{"remove_all", "[-f|--force]", 0, 0, _remove_all},
@@ -1611,6 +1627,7 @@ static int _process_switches(int *argc, char ***argv)
{"noopencount", 0, &ind, NOOPENCOUNT_ARG},
{"notable", 0, &ind, NOTABLE_ARG},
{"options", 1, &ind, OPTIONS_ARG},
{"table", 1, &ind, TABLE_ARG},
{"target", 1, &ind, TARGET_ARG},
{"tree", 0, &ind, TREE_ARG},
{"uid", 1, &ind, UID_ARG},
@@ -1667,6 +1684,8 @@ static int _process_switches(int *argc, char ***argv)
optind = OPTIND_INIT;
while ((ind = -1, c = GETOPTLONG_FN(*argc, *argv, "cCfGj:m:Mno:ru:Uv",
long_options, NULL)) != -1) {
if (c == ':' || c == '?')
return 0;
if (c == 'c' || c == 'C' || ind == COLS_ARG)
_switches[COLS_ARG]++;
if (c == 'f' || ind == FORCE_ARG)
@@ -1720,6 +1739,10 @@ static int _process_switches(int *argc, char ***argv)
_switches[NOLOCKFS_ARG]++;
if ((ind == NOOPENCOUNT_ARG))
_switches[NOOPENCOUNT_ARG]++;
if ((ind == TABLE_ARG)) {
_switches[TABLE_ARG]++;
_table = optarg;
}
if ((ind == TREE_ARG))
_switches[TREE_ARG]++;
if ((ind == VERSION_ARG))
@@ -1745,6 +1768,11 @@ static int _process_switches(int *argc, char ***argv)
if (_switches[TREE_ARG] && !_process_tree_options(_fields))
return 0;
if (_switches[TABLE_ARG] && _switches[NOTABLE_ARG]) {
fprintf(stderr, "--table and --notable are incompatible.\n");
return 0;
}
*argv += optind;
*argc -= optind;
return 1;
@@ -1755,7 +1783,7 @@ int main(int argc, char **argv)
struct command *c;
int r = 1;
(void) setlocale(LC_ALL, "");
(void) setlocale(LC_ALL, "");
if (!_process_switches(&argc, &argv)) {
fprintf(stderr, "Couldn't process command line.\n");

View File

@@ -102,7 +102,7 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
int argc, char **argv)
{
int region_size;
int pagesize = getpagesize();
int pagesize = lvm_getpagesize();
memset(lp, 0, sizeof(*lp));
@@ -565,6 +565,12 @@ int lvconvert(struct cmd_context * cmd, int argc, char **argv)
goto error;
}
if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume group %s", lp.vg_name);
goto error;
}
if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", lp.vg_name);
goto error;

View File

@@ -94,19 +94,7 @@ static int _lvcreate_name_params(struct lvcreate_params *lp,
}
} else {
vg_name = argv[0];
/* Strip dev_dir (optional) */
if (*vg_name == '/') {
while (*vg_name == '/')
vg_name++;
vg_name--;
}
if (!strncmp(vg_name, cmd->dev_dir,
strlen(cmd->dev_dir))) {
vg_name += strlen(cmd->dev_dir);
while (*vg_name == '/')
vg_name++;
}
vg_name = skip_dev_dir(cmd, argv[0]);
if (strrchr(vg_name, '/')) {
log_error("Volume group name expected "
"(no slash)");
@@ -249,7 +237,7 @@ static int _read_mirror_params(struct lvcreate_params *lp,
{
int argc = *pargc;
int region_size;
int pagesize = getpagesize();
int pagesize = lvm_getpagesize();
if (argc && (unsigned) argc < lp->mirrors) {
log_error("Too few physical volumes on "
@@ -498,6 +486,12 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
return 0;
}
if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume group %s", lp->vg_name);
return 0;
}
if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", lp->vg_name);
return 0;

21
tools/lvm2cmd-static.c Normal file
View File

@@ -0,0 +1,21 @@
/*
* 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 "lvm2cmdline.h"
#include "lvm2cmd.h"
void *lvm2_init(void)
{
return cmdlib_lvm2_init(1);
}

21
tools/lvm2cmd.c Normal file
View File

@@ -0,0 +1,21 @@
/*
* 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 "lvm2cmdline.h"
#include "lvm2cmd.h"
void *lvm2_init(void)
{
return cmdlib_lvm2_init(0);
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -16,6 +16,16 @@
#ifndef _LVM_CMDLINE_H
#define _LVM_CMDLINE_H
int lvm2_main(int argc, char **argv, int is_static);
struct cmd_context;
int lvm2_main(int argc, char **argv, unsigned is_static);
void *cmdlib_lvm2_init(unsigned is_static);
void lvm_fin(struct cmd_context *cmd);
struct cmd_context *init_lvm(unsigned is_static);
void lvm_register_commands(void);
int lvm_split(char *str, int *argc, char **argv, int max);
int lvm_run_command(struct cmd_context *cmd, int argc, char **argv);
#endif

110
tools/lvmcmdlib.c Normal file
View File

@@ -0,0 +1,110 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 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 "tools.h"
#include "lvm2cmdline.h"
#include "label.h"
#include "version.h"
#include "lvm2cmd.h"
#include <signal.h>
#include <syslog.h>
#include <libgen.h>
#include <sys/stat.h>
#include <time.h>
#include <sys/resource.h>
void *cmdlib_lvm2_init(unsigned is_static)
{
struct cmd_context *cmd;
lvm_register_commands();
if (!(cmd = init_lvm(is_static)))
return NULL;
return (void *) cmd;
}
int lvm2_run(void *handle, const char *cmdline)
{
int argc, ret, oneoff = 0;
char *args[MAX_ARGS], **argv, *cmdcopy = NULL;
struct cmd_context *cmd;
argv = args;
if (!handle) {
oneoff = 1;
if (!(handle = lvm2_init())) {
log_error("Handle initialisation failed.");
return ECMD_FAILED;
}
}
cmd = (struct cmd_context *) handle;
cmd->argv = argv;
if (!(cmdcopy = dm_strdup(cmdline))) {
log_error("Cmdline copy failed.");
ret = ECMD_FAILED;
goto out;
}
if (lvm_split(cmdcopy, &argc, argv, MAX_ARGS) == MAX_ARGS) {
log_error("Too many arguments. Limit is %d.", MAX_ARGS);
ret = EINVALID_CMD_LINE;
goto out;
}
if (!argc) {
log_error("No command supplied");
ret = EINVALID_CMD_LINE;
goto out;
}
ret = lvm_run_command(cmd, argc, argv);
out:
dm_free(cmdcopy);
if (oneoff)
lvm2_exit(handle);
return ret;
}
void lvm2_log_level(void *handle, int level)
{
struct cmd_context *cmd = (struct cmd_context *) handle;
cmd->default_settings.verbose = level - VERBOSE_BASE_LEVEL;
return;
}
void lvm2_log_fn(lvm2_log_fn_t log_fn)
{
init_log_fn(log_fn);
}
void lvm2_exit(void *handle)
{
struct cmd_context *cmd = (struct cmd_context *) handle;
lvm_fin(cmd);
}

View File

@@ -443,7 +443,7 @@ static void _register_command(const char *name, command_fn fn,
_create_new_command(name, fn, desc, usagestr, nargs, args);
}
static void _register_commands()
void lvm_register_commands(void)
{
#define xx(a, b, c...) _register_command(# a, a, b, ## c, \
driverloaded_ARG, \
@@ -707,6 +707,17 @@ static int _get_settings(struct cmd_context *cmd)
return EINVALID_CMD_LINE;
}
if (arg_count(cmd, trustcache_ARG)) {
if (arg_count(cmd, all_ARG)) {
log_error("--trustcache is incompatible with --all");
return EINVALID_CMD_LINE;
}
init_trust_cache(1);
log_print("WARNING: Cache file of PVs will be trusted. "
"New devices holding PVs may get ignored.");
} else
init_trust_cache(0);
/* Handle synonyms */
if (!_merge_synonym(cmd, resizable_ARG, resizeable_ARG) ||
!_merge_synonym(cmd, allocation_ARG, allocatable_ARG) ||
@@ -832,7 +843,7 @@ static char *_copy_command_line(struct cmd_context *cmd, int argc, char **argv)
return NULL;
}
static int _run_command(struct cmd_context *cmd, int argc, char **argv)
int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
{
int ret = 0;
int locking_type;
@@ -925,7 +936,7 @@ static int _run_command(struct cmd_context *cmd, int argc, char **argv)
return ret;
}
static int _split(char *str, int *argc, char **argv, int max)
int lvm_split(char *str, int *argc, char **argv, int max)
{
char *b = str, *e;
*argc = 0;
@@ -984,11 +995,11 @@ static void _close_stray_fds(void)
}
}
static struct cmd_context *_init_lvm(void)
struct cmd_context *init_lvm(unsigned is_static)
{
struct cmd_context *cmd;
if (!(cmd = create_toolcontext(&the_args[0]))) {
if (!(cmd = create_toolcontext(&the_args[0], is_static))) {
stack;
return NULL;
}
@@ -1010,7 +1021,7 @@ static void _fin_commands(void)
dm_free(_commands);
}
static void _fin(struct cmd_context *cmd)
void lvm_fin(struct cmd_context *cmd)
{
_fin_commands();
destroy_toolcontext(cmd);
@@ -1044,7 +1055,7 @@ static int _run_script(struct cmd_context *cmd, int argc, char **argv)
ret = EINVALID_CMD_LINE;
break;
}
if (_split(buffer, &argc, argv, MAX_ARGS) == MAX_ARGS) {
if (lvm_split(buffer, &argc, argv, MAX_ARGS) == MAX_ARGS) {
buffer[50] = '\0';
log_error("Too many arguments: %s", buffer);
ret = EINVALID_CMD_LINE;
@@ -1054,7 +1065,7 @@ static int _run_script(struct cmd_context *cmd, int argc, char **argv)
continue;
if (!strcmp(argv[0], "quit") || !strcmp(argv[0], "exit"))
break;
_run_command(cmd, argc, argv);
lvm_run_command(cmd, argc, argv);
}
fclose(script);
@@ -1177,7 +1188,7 @@ static int _hist_file(char *buffer, size_t size)
{
char *e = getenv("HOME");
if (lvm_snprintf(buffer, size, "%s/.lvm_history", e) < 0) {
if (dm_snprintf(buffer, size, "%s/.lvm_history", e) < 0) {
log_error("$HOME/.lvm_history: path too long");
return 0;
}
@@ -1240,7 +1251,7 @@ static int _shell(struct cmd_context *cmd)
argv = args;
if (_split(input, &argc, argv, MAX_ARGS) == MAX_ARGS) {
if (lvm_split(input, &argc, argv, MAX_ARGS) == MAX_ARGS) {
log_error("Too many arguments, sorry.");
continue;
}
@@ -1259,7 +1270,7 @@ static int _shell(struct cmd_context *cmd)
break;
}
ret = _run_command(cmd, argc, argv);
ret = lvm_run_command(cmd, argc, argv);
if (ret == ENO_SUCH_CMD)
log_error("No such command '%s'. Try 'help'.",
argv[0]);
@@ -1273,92 +1284,6 @@ static int _shell(struct cmd_context *cmd)
#endif
#ifdef CMDLIB
void *lvm2_init(void)
{
struct cmd_context *cmd;
_register_commands();
if (!(cmd = _init_lvm()))
return NULL;
return (void *) cmd;
}
int lvm2_run(void *handle, const char *cmdline)
{
int argc, ret, oneoff = 0;
char *args[MAX_ARGS], **argv, *cmdcopy = NULL;
struct cmd_context *cmd;
argv = args;
if (!handle) {
oneoff = 1;
if (!(handle = lvm2_init())) {
log_error("Handle initialisation failed.");
return ECMD_FAILED;
}
}
cmd = (struct cmd_context *) handle;
cmd->argv = argv;
if (!(cmdcopy = dm_strdup(cmdline))) {
log_error("Cmdline copy failed.");
ret = ECMD_FAILED;
goto out;
}
if (_split(cmdcopy, &argc, argv, MAX_ARGS) == MAX_ARGS) {
log_error("Too many arguments. Limit is %d.", MAX_ARGS);
ret = EINVALID_CMD_LINE;
goto out;
}
if (!argc) {
log_error("No command supplied");
ret = EINVALID_CMD_LINE;
goto out;
}
ret = _run_command(cmd, argc, argv);
out:
dm_free(cmdcopy);
if (oneoff)
lvm2_exit(handle);
return ret;
}
void lvm2_log_level(void *handle, int level)
{
struct cmd_context *cmd = (struct cmd_context *) handle;
cmd->default_settings.verbose = level - VERBOSE_BASE_LEVEL;
return;
}
void lvm2_log_fn(lvm2_log_fn_t log_fn)
{
init_log_fn(log_fn);
}
void lvm2_exit(void *handle)
{
struct cmd_context *cmd = (struct cmd_context *) handle;
_fin(cmd);
}
#endif
/*
* Determine whether we should fall back and exec the equivalent LVM1 tool
*/
@@ -1386,7 +1311,7 @@ static void _exec_lvm1_command(char **argv)
{
char path[PATH_MAX];
if (lvm_snprintf(path, sizeof(path), "%s.lvm1", argv[0]) < 0) {
if (dm_snprintf(path, sizeof(path), "%s.lvm1", argv[0]) < 0) {
log_error("Failed to create LVM1 tool pathname");
return;
}
@@ -1395,7 +1320,7 @@ static void _exec_lvm1_command(char **argv)
log_sys_error("execvp", path);
}
int lvm2_main(int argc, char **argv, int is_static)
int lvm2_main(int argc, char **argv, unsigned is_static)
{
char *namebase, *base;
int ret, alias = 0;
@@ -1421,11 +1346,11 @@ int lvm2_main(int argc, char **argv, int is_static)
free(namebase);
if (!(cmd = _init_lvm()))
if (!(cmd = init_lvm(is_static)))
return -1;
cmd->argv = argv;
_register_commands();
lvm_register_commands();
if (_lvm1_fallback(cmd)) {
/* Attempt to run equivalent LVM1 tool instead */
@@ -1461,14 +1386,14 @@ int lvm2_main(int argc, char **argv, int is_static)
argv++;
}
ret = _run_command(cmd, argc, argv);
ret = lvm_run_command(cmd, argc, argv);
if ((ret == ENO_SUCH_CMD) && (!alias))
ret = _run_script(cmd, argc, argv);
if (ret == ENO_SUCH_CMD)
log_error("No such command. Try 'help'.");
out:
_fin(cmd);
lvm_fin(cmd);
if (ret == ECMD_PROCESSED)
ret = 0;
return ret;

View File

@@ -29,9 +29,7 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv)
struct lv_list *lvl;
if (argc == 3) {
vg_name = argv[0];
if (!strncmp(vg_name, cmd->dev_dir, strlen(cmd->dev_dir)))
vg_name += strlen(cmd->dev_dir);
vg_name = skip_dev_dir(cmd, argv[0]);
lv_name_old = argv[1];
lv_name_new = argv[2];
if (strchr(lv_name_old, '/') &&
@@ -111,6 +109,12 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv)
goto error;
}
if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume group %s", vg->name);
goto error;
}
if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg->name);
goto error;
@@ -140,6 +144,14 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv)
goto error;
}
if ((lv->status & MIRRORED) ||
(lv->status & MIRROR_LOG) ||
(lv->status & MIRROR_IMAGE)) {
log_error("Mirrored LV, \"%s\" cannot be renamed: %s",
lv->name, strerror(ENOSYS));
goto error;
}
if (!archive(lv->vg)) {
stack;
goto error;

View File

@@ -138,6 +138,12 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
return ECMD_FAILED;
}
if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume group %s", vg->name);
return ECMD_FAILED;
}
if (vg->status & EXPORTED_VG) {
log_error("Volume group %s is exported", vg->name);
return ECMD_FAILED;
@@ -480,14 +486,14 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
}
if (lp->resizefs) {
if (lvm_snprintf(lv_path, PATH_MAX, "%s%s/%s", cmd->dev_dir,
if (dm_snprintf(lv_path, PATH_MAX, "%s%s/%s", cmd->dev_dir,
lp->vg_name, lp->lv_name) < 0) {
log_error("Couldn't create LV path for %s",
lp->lv_name);
return ECMD_FAILED;
}
if (lvm_snprintf(size_buf, SIZE_BUF, "%" PRIu64,
if (dm_snprintf(size_buf, SIZE_BUF, "%" PRIu64,
(uint64_t) lp->extents * vg->extent_size / 2)
< 0) {
log_error("Couldn't generate new LV size string");

View File

@@ -67,6 +67,12 @@ static int _pvchange_single(struct cmd_context *cmd, struct physical_volume *pv,
return 0;
}
if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume group %s", vg->name);
return 0;
}
if (vg->status & EXPORTED_VG) {
unlock_vg(cmd, pv->vg_name);
log_error("Volume group \"%s\" is exported", vg->name);

View File

@@ -27,9 +27,7 @@ static const char *_extract_lvname(struct cmd_context *cmd, const char *vgname,
if (!strchr(arg, '/'))
return arg;
lvname = arg;
if (!strncmp(lvname, cmd->dev_dir, strlen(cmd->dev_dir)))
lvname += strlen(cmd->dev_dir);
lvname = skip_dev_dir(cmd, arg);
while (*lvname == '/')
lvname++;
if (!strchr(lvname, '/')) {
@@ -68,6 +66,12 @@ static struct volume_group *_get_vg(struct cmd_context *cmd, const char *vgname)
return NULL;
}
if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume group %s", vgname);
return NULL;
}
if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vgname);
unlock_vg(cmd, vgname);

View File

@@ -77,6 +77,13 @@ static int _pvresize_single(struct cmd_context *cmd,
return ECMD_FAILED;
}
if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
!lockingfailed()) {
unlock_vg(cmd, vg_name);
log_error("Skipping clustered volume group %s", vg->name);
return ECMD_FAILED;
}
if (vg->status & EXPORTED_VG) {
unlock_vg(cmd, vg_name);
log_error("Volume group \"%s\" is exported", vg->name);

View File

@@ -68,13 +68,20 @@ static int _pvsegs_sub_single(struct cmd_context *cmd, struct volume_group *vg,
if (!(vg = vg_read(cmd, pv->vg_name, NULL, &consistent))) {
log_error("Can't read %s: skipping", pv->vg_name);
unlock_vg(cmd, pv->vg_name);
return ECMD_FAILED;
goto out;
}
if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume group %s", vg->name);
ret = ECMD_FAILED;
goto out;
}
if (!report_object(handle, vg, NULL, pv, NULL, pvseg))
ret = ECMD_FAILED;
out:
unlock_vg(cmd, pv->vg_name);
return ret;
}
@@ -109,14 +116,22 @@ static int _pvs_single(struct cmd_context *cmd, struct volume_group *vg,
if (!(vg = vg_read(cmd, pv->vg_name, (char *)&pv->vgid, &consistent))) {
log_error("Can't read %s: skipping", pv->vg_name);
unlock_vg(cmd, pv->vg_name);
return ECMD_FAILED;
goto out;
}
if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume group %s",
vg->name);
ret = ECMD_FAILED;
goto out;
}
}
if (!report_object(handle, vg, NULL, pv, NULL, NULL))
ret = ECMD_FAILED;
out:
if (pv->vg_name)
unlock_vg(cmd, pv->vg_name);

View File

@@ -80,6 +80,28 @@ const char *command_name(struct cmd_context *cmd)
return cmd->command->name;
}
/*
* Strip dev_dir if present
*/
char *skip_dev_dir(struct cmd_context *cmd, const char *vg_name)
{
/* FIXME Do this properly */
if (*vg_name == '/') {
while (*vg_name == '/')
vg_name++;
vg_name--;
}
if (!strncmp(vg_name, cmd->dev_dir, strlen(cmd->dev_dir))) {
vg_name += strlen(cmd->dev_dir);
while (*vg_name == '/')
vg_name++;
}
return (char *) vg_name;
}
/*
* Metadata iteration functions
*/
@@ -268,7 +290,7 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv,
} else {
vglv_sz = strlen(vgname) + strlen(lv_name) + 2;
if (!(vglv = dm_pool_alloc(cmd->mem, vglv_sz)) ||
lvm_snprintf(vglv, vglv_sz, "%s/%s", vgname,
dm_snprintf(vglv, vglv_sz, "%s/%s", vgname,
lv_name) < 0) {
log_error("vg/lv string alloc failed");
return ECMD_FAILED;
@@ -307,9 +329,20 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv,
if (!vg)
log_error("Volume group \"%s\" "
"not found", vgname);
else
else {
if ((vg->status & CLUSTERED) &&
!locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume "
"group %s", vgname);
if (ret_max < ECMD_FAILED)
ret_max = ECMD_FAILED;
continue;
}
log_error("Volume group \"%s\" "
"inconsistent", vgname);
}
if (!vg || !(vg = recover_vg(cmd, vgname, lock_type))) {
if (ret_max < ECMD_FAILED)
ret_max = ECMD_FAILED;
@@ -317,6 +350,15 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv,
}
}
if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
!lockingfailed()) {
unlock_vg(cmd, vgname);
log_error("Skipping clustered volume group %s", vgname);
if (ret_max < ECMD_FAILED)
ret_max = ECMD_FAILED;
continue;
}
tags_arg = &tags;
list_init(&lvnames); /* LVs to be processed in this VG */
list_iterate_items(sll, &arg_lvnames) {
@@ -416,6 +458,13 @@ static int _process_one_vg(struct cmd_context *cmd, const char *vg_name,
return ECMD_FAILED;
}
if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume group %s", vg_name);
unlock_vg(cmd, vg_name);
return ECMD_FAILED;
}
if (!list_empty(tags)) {
/* Only process if a tag matches or it's on arg_vgnames */
if (!str_list_match_item(arg_vgnames, vg_name) &&
@@ -450,7 +499,6 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
struct list arg_vgnames, tags;
const char *vg_name, *vgid;
char *dev_dir = cmd->dev_dir;
list_init(&tags);
list_init(&arg_vgnames);
@@ -475,13 +523,7 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
continue;
}
if (*vg_name == '/') {
while (*vg_name == '/')
vg_name++;
vg_name--;
}
if (!strncmp(vg_name, dev_dir, strlen(dev_dir)))
vg_name += strlen(dev_dir);
vg_name = skip_dev_dir(cmd, vg_name);
if (strchr(vg_name, '/')) {
log_error("Invalid volume group name: %s",
vg_name);
@@ -665,6 +707,15 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
}
if (!consistent)
continue;
if ((vg->status & CLUSTERED) &&
!locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume "
"group %s", sll->str);
continue;
}
ret = process_each_pv_in_vg(cmd, vg, &tags,
handle,
process_single);
@@ -768,21 +819,13 @@ const char *extract_vgname(struct cmd_context *cmd, const char *lv_name)
char *default_vgname(struct cmd_context *cmd)
{
char *vg_path;
char *dev_dir = cmd->dev_dir;
/* Take default VG from environment? */
vg_path = getenv("LVM_VG_NAME");
if (!vg_path)
return 0;
/* Strip dev_dir (optional) */
if (*vg_path == '/') {
while (*vg_path == '/')
vg_path++;
vg_path--;
}
if (!strncmp(vg_path, dev_dir, strlen(dev_dir)))
vg_path += strlen(dev_dir);
vg_path = skip_dev_dir(cmd, vg_path);
if (strchr(vg_path, '/')) {
log_error("Environment Volume Group in LVM_VG_NAME invalid: "
@@ -1038,6 +1081,10 @@ struct volume_group *recover_vg(struct cmd_context *cmd, const char *vgname,
{
int consistent = 1;
/* Don't attempt automatic recovery without proper locking */
if (lockingfailed())
return NULL;
lock_type &= ~LCK_TYPE_MASK;
lock_type |= LCK_WRITE;
@@ -1098,14 +1145,14 @@ int validate_vg_name(struct cmd_context *cmd, const char *vg_name)
int generate_log_name_format(struct volume_group *vg __attribute((unused)),
const char *lv_name, char *buffer, size_t size)
{
if (lvm_snprintf(buffer, size, "%s_mlog", lv_name) < 0) {
if (dm_snprintf(buffer, size, "%s_mlog", lv_name) < 0) {
stack;
return 0;
}
/* FIXME I think we can cope without this. Cf. _add_lv_to_dtree()
if (find_lv_in_vg(vg, buffer) &&
lvm_snprintf(buffer, size, "%s_mlog_%%d",
dm_snprintf(buffer, size, "%s_mlog_%%d",
lv_name) < 0) {
stack;
return 0;
@@ -1135,7 +1182,7 @@ int set_lv(struct cmd_context *cmd, struct logical_volume *lv, int value)
return 0;
}
if (lvm_snprintf(name, PATH_MAX, "%s%s/%s", cmd->dev_dir,
if (dm_snprintf(name, PATH_MAX, "%s%s/%s", cmd->dev_dir,
lv->vg->name, lv->name) < 0) {
log_error("Name too long - device not cleared (%s)", lv->name);
return 0;
@@ -1157,7 +1204,6 @@ int set_lv(struct cmd_context *cmd, struct logical_volume *lv, int value)
return 1;
}
/*
* This function writes a new header to the mirror log header to the lv
*
@@ -1183,7 +1229,7 @@ static int _write_log_header(struct cmd_context *cmd, struct logical_volume *lv)
return 0;
}
if (lvm_snprintf(name, PATH_MAX, "%s%s/%s", cmd->dev_dir,
if (dm_snprintf(name, PATH_MAX, "%s%s/%s", cmd->dev_dir,
lv->vg->name, lv->name) < 0) {
log_error("Name too long - log header not written (%s)", lv->name);
return 0;
@@ -1254,6 +1300,12 @@ struct logical_volume *create_mirror_log(struct cmd_context *cmd,
goto error;
}
if (!activation() && in_sync) {
log_error("Aborting. Unable to create in-sync mirror log "
"while activation is disabled.");
goto error;
}
if (!activate_lv(cmd, log_lv)) {
log_error("Aborting. Failed to activate mirror log. "
"Remove new LVs and retry.");
@@ -1266,7 +1318,7 @@ struct logical_volume *create_mirror_log(struct cmd_context *cmd,
goto error;
}
if (!_write_log_header(cmd, log_lv)) {
if (activation() && !_write_log_header(cmd, log_lv)) {
log_error("Aborting. Failed to write mirror log header. "
"Remove new LV and retry.");
goto error;

View File

@@ -76,6 +76,7 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
char *default_vgname(struct cmd_context *cmd);
const char *extract_vgname(struct cmd_context *cmd, const char *lv_name);
char *skip_dev_dir(struct cmd_context *cmd, const char *vg_name);
/*
* Builds a list of pv's from the names in argv. Used in

View File

@@ -24,10 +24,7 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
}
vg_name = argv[0];
if (!strncmp(vg_name, cmd->dev_dir, strlen(cmd->dev_dir)))
vg_name += strlen(cmd->dev_dir);
vg_name = skip_dev_dir(cmd, argv[0]);
if (!validate_name(vg_name)) {
log_error("Volume group name \"%s\" is invalid", vg_name);

View File

@@ -312,7 +312,7 @@ static int _vgchange_logicalvolume(struct cmd_context *cmd,
if (max_lv && max_lv < vg->lv_count) {
log_error("MaxLogicalVolume is less than the current number "
"%d of logical volume(s) for \"%s\"", vg->lv_count,
"%d of LVs for \"%s\"", vg->lv_count,
vg->name);
return ECMD_FAILED;
}
@@ -332,6 +332,53 @@ static int _vgchange_logicalvolume(struct cmd_context *cmd,
return ECMD_PROCESSED;
}
static int _vgchange_physicalvolumes(struct cmd_context *cmd,
struct volume_group *vg)
{
uint32_t max_pv = arg_uint_value(cmd, maxphysicalvolumes_ARG, 0);
if (!(vg->status & RESIZEABLE_VG)) {
log_error("Volume group \"%s\" must be resizeable "
"to change MaxPhysicalVolumes", vg->name);
return ECMD_FAILED;
}
if (arg_sign_value(cmd, maxphysicalvolumes_ARG, 0) == SIGN_MINUS) {
log_error("MaxPhysicalVolumes may not be negative");
return EINVALID_CMD_LINE;
}
if (!(vg->fid->fmt->features & FMT_UNLIMITED_VOLS)) {
if (!max_pv)
max_pv = 255;
else if (max_pv > 255) {
log_error("MaxPhysicalVolume limit is 255");
return ECMD_FAILED;
}
}
if (max_pv && max_pv < vg->pv_count) {
log_error("MaxPhysicalVolumes is less than the current number "
"%d of PVs for \"%s\"", vg->pv_count,
vg->name);
return ECMD_FAILED;
}
if (!archive(vg))
return ECMD_FAILED;
vg->max_pv = max_pv;
if (!vg_write(vg) || !vg_commit(vg))
return ECMD_FAILED;
backup(vg);
log_print("Volume group \"%s\" successfully changed", vg->name);
return ECMD_PROCESSED;
}
static int _vgchange_pesize(struct cmd_context *cmd, struct volume_group *vg)
{
uint32_t extent_size;
@@ -508,6 +555,9 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
else if (arg_count(cmd, logicalvolume_ARG))
r = _vgchange_logicalvolume(cmd, vg);
else if (arg_count(cmd, maxphysicalvolumes_ARG))
r = _vgchange_physicalvolumes(cmd, vg);
else if (arg_count(cmd, addtag_ARG))
r = _vgchange_tag(cmd, vg, addtag_ARG);
@@ -533,24 +583,26 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
{
if (!
(arg_count(cmd, available_ARG) + arg_count(cmd, logicalvolume_ARG) +
arg_count(cmd, maxphysicalvolumes_ARG) +
arg_count(cmd, resizeable_ARG) + arg_count(cmd, deltag_ARG) +
arg_count(cmd, addtag_ARG) + arg_count(cmd, uuid_ARG) +
arg_count(cmd, physicalextentsize_ARG) +
arg_count(cmd, clustered_ARG) + arg_count(cmd, alloc_ARG) +
arg_count(cmd, monitor_ARG))) {
log_error("One of -a, -c, -l, -s, -x, --uuid, --alloc, --addtag or "
"--deltag required");
log_error("One of -a, -c, -l, -p, -s, -x, --uuid, --alloc, "
"--addtag or --deltag required");
return EINVALID_CMD_LINE;
}
/* FIXME Cope with several changes at once! */
if (arg_count(cmd, available_ARG) + arg_count(cmd, logicalvolume_ARG) +
arg_count(cmd, maxphysicalvolumes_ARG) +
arg_count(cmd, resizeable_ARG) + arg_count(cmd, deltag_ARG) +
arg_count(cmd, addtag_ARG) + arg_count(cmd, alloc_ARG) +
arg_count(cmd, uuid_ARG) + arg_count(cmd, clustered_ARG) +
arg_count(cmd, physicalextentsize_ARG) > 1) {
log_error("Only one of -a, -c, -l, -s, -x, --uuid, --alloc, "
"--addtag or --deltag allowed");
log_error("Only one of -a, -c, -l, -p, -s, -x, --uuid, "
"--alloc, --addtag or --deltag allowed");
return EINVALID_CMD_LINE;
}

View File

@@ -38,7 +38,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
}
vg_name = argv[0];
vg_name = skip_dev_dir(cmd, argv[0]);
max_lv = arg_uint_value(cmd, maxlogicalvolumes_ARG, 0);
max_pv = arg_uint_value(cmd, maxphysicalvolumes_ARG, 0);
alloc = arg_uint_value(cmd, alloc_ARG, ALLOC_NORMAL);
@@ -84,10 +84,6 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
}
/* Strip dev_dir if present */
if (!strncmp(vg_name, cmd->dev_dir, strlen(cmd->dev_dir)))
vg_name += strlen(cmd->dev_dir);
if (!validate_vg_name(cmd, vg_name)) {
log_error("New volume group name \"%s\" is invalid", vg_name);
return ECMD_FAILED;

View File

@@ -32,7 +32,7 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
}
vg_name = argv[0];
vg_name = skip_dev_dir(cmd, argv[0]);
argc--;
argv++;
@@ -53,6 +53,12 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv)
goto error;
}
if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume group %s", vg->name);
goto error;
}
if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg->name);
goto error;

View File

@@ -41,6 +41,13 @@ static int _vgmerge_single(struct cmd_context *cmd, const char *vg_name_to,
return ECMD_FAILED;
}
if ((vg_to->status & CLUSTERED) && !locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume group %s", vg_name_to);
unlock_vg(cmd, vg_name_to);
return ECMD_FAILED;
}
if (vg_to->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg_to->name);
unlock_vg(cmd, vg_name_to);
@@ -66,6 +73,12 @@ static int _vgmerge_single(struct cmd_context *cmd, const char *vg_name_to,
goto error;
}
if ((vg_from->status & CLUSTERED) && !locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume group %s", vg_name_from);
goto error;
}
if (vg_from->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg_from->name);
goto error;
@@ -231,7 +244,7 @@ static int _vgmerge_single(struct cmd_context *cmd, const char *vg_name_to,
int vgmerge(struct cmd_context *cmd, int argc, char **argv)
{
char *vg_name_to;
char *vg_name_to, *vg_name_from;
int opt = 0;
int ret = 0, ret_max = 0;
@@ -240,12 +253,14 @@ int vgmerge(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
}
vg_name_to = argv[0];
vg_name_to = skip_dev_dir(cmd, argv[0]);
argc--;
argv++;
for (; opt < argc; opt++) {
ret = _vgmerge_single(cmd, vg_name_to, argv[opt]);
vg_name_from = skip_dev_dir(cmd, argv[opt]);
ret = _vgmerge_single(cmd, vg_name_to, vg_name_from);
if (ret > ret_max)
ret_max = ret;
}

View File

@@ -459,7 +459,7 @@ int vgreduce(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
}
vg_name = argv[0];
vg_name = skip_dev_dir(cmd, argv[0]);
argv++;
argc--;
@@ -476,6 +476,13 @@ int vgreduce(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
}
if (vg && (vg->status & CLUSTERED) && !locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume group %s", vg->name);
unlock_vg(cmd, vg_name);
return ECMD_FAILED;
}
if (arg_count(cmd, removemissing_ARG)) {
if (vg && consistent) {
log_error("Volume group \"%s\" is already consistent",
@@ -491,6 +498,13 @@ int vgreduce(struct cmd_context *cmd, int argc, char **argv)
unlock_vg(cmd, vg_name);
return ECMD_FAILED;
}
if ((vg->status & CLUSTERED) && !locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume group %s",
vg->name);
unlock_vg(cmd, vg_name);
return ECMD_FAILED;
}
if (!archive(vg)) {
init_partial(0);
unlock_vg(cmd, vg_name);

View File

@@ -35,18 +35,12 @@ int vgrename(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
}
vg_name_old = argv[0];
vg_name_new = argv[1];
vg_name_old = skip_dev_dir(cmd, argv[0]);
vg_name_new = skip_dev_dir(cmd, argv[1]);
dev_dir = cmd->dev_dir;
length = strlen(dev_dir);
/* If present, strip dev_dir */
if (!strncmp(vg_name_old, dev_dir, length))
vg_name_old += length;
if (!strncmp(vg_name_new, dev_dir, length))
vg_name_new += length;
/* Check sanity of new name */
if (strlen(vg_name_new) > NAME_LEN - length - 2) {
log_error("New volume group path exceeds maximum length "
@@ -108,6 +102,13 @@ int vgrename(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
}
if ((vg_old->status & CLUSTERED) && !locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume group %s", vg_old->name);
unlock_vg(cmd, vg_name_old);
return ECMD_FAILED;
}
if (vg_old->status & EXPORTED_VG)
log_info("Volume group \"%s\" is exported", vg_old->name);

View File

@@ -196,6 +196,13 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
}
if ((vg_from->status & CLUSTERED) && !locking_is_clustered() &&
!lockingfailed()) {
log_error("Skipping clustered volume group %s", vg_from->name);
unlock_vg(cmd, vg_name_from);
return ECMD_FAILED;
}
if (vg_from->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg_from->name);
unlock_vg(cmd, vg_name_from);