r94 - in lvm2/upstream/current: . daemons/clvmd doc include lib
lib/activate lib/cache lib/commands lib/config lib/datastruct
lib/device lib/display lib/filters lib/format1
lib/format_pool lib/format_text lib/label lib/locking lib/log
lib/metadata lib/mirror lib/misc lib/mm lib/report
lib/snapshot lib/striped lib/uuid man po scripts tools
Bastian Blank
waldi at costa.debian.org
Thu Jul 21 12:48:13 UTC 2005
Author: waldi
Date: Tue Jun 14 11:13:22 2005
New Revision: 94
Added:
lvm2/upstream/current/CONTRIBUTORS
lvm2/upstream/current/lib/format_text/archiver.c
lvm2/upstream/current/lib/format_text/archiver.h
lvm2/upstream/current/lib/metadata/pv_alloc.h
lvm2/upstream/current/lib/metadata/pv_manip.c
lvm2/upstream/current/scripts/lvmconf.sh
lvm2/upstream/current/tools/lvconvert.c
Removed:
lvm2/upstream/current/tools/archiver.c
lvm2/upstream/current/tools/archiver.h
Modified:
lvm2/upstream/current/VERSION
lvm2/upstream/current/WHATS_NEW
lvm2/upstream/current/daemons/clvmd/Makefile.in
lvm2/upstream/current/daemons/clvmd/clvmd-cman.c
lvm2/upstream/current/daemons/clvmd/clvmd-command.c
lvm2/upstream/current/daemons/clvmd/clvmd-comms.h
lvm2/upstream/current/daemons/clvmd/clvmd-gulm.c
lvm2/upstream/current/daemons/clvmd/clvmd.c
lvm2/upstream/current/daemons/clvmd/clvmd.h
lvm2/upstream/current/daemons/clvmd/lvm-functions.c
lvm2/upstream/current/daemons/clvmd/lvm-functions.h
lvm2/upstream/current/daemons/clvmd/tcp-comms.c
lvm2/upstream/current/daemons/clvmd/tcp-comms.h
lvm2/upstream/current/doc/example.conf
lvm2/upstream/current/include/.symlinks
lvm2/upstream/current/lib/Makefile.in
lvm2/upstream/current/lib/activate/activate.c
lvm2/upstream/current/lib/activate/dev_manager.c
lvm2/upstream/current/lib/activate/fs.c
lvm2/upstream/current/lib/activate/targets.h
lvm2/upstream/current/lib/cache/lvmcache.c
lvm2/upstream/current/lib/cache/lvmcache.h
lvm2/upstream/current/lib/commands/toolcontext.c
lvm2/upstream/current/lib/commands/toolcontext.h
lvm2/upstream/current/lib/config/config.c
lvm2/upstream/current/lib/config/defaults.h
lvm2/upstream/current/lib/datastruct/list.h
lvm2/upstream/current/lib/datastruct/lvm-types.h
lvm2/upstream/current/lib/device/dev-cache.c
lvm2/upstream/current/lib/device/dev-cache.h
lvm2/upstream/current/lib/device/dev-io.c
lvm2/upstream/current/lib/device/device.h
lvm2/upstream/current/lib/display/display.c
lvm2/upstream/current/lib/filters/filter-persistent.c
lvm2/upstream/current/lib/filters/filter-regex.c
lvm2/upstream/current/lib/filters/filter-sysfs.c
lvm2/upstream/current/lib/filters/filter.c
lvm2/upstream/current/lib/format1/disk-rep.c
lvm2/upstream/current/lib/format1/format1.c
lvm2/upstream/current/lib/format1/import-export.c
lvm2/upstream/current/lib/format1/import-extents.c
lvm2/upstream/current/lib/format1/vg_number.c
lvm2/upstream/current/lib/format_pool/disk_rep.c
lvm2/upstream/current/lib/format_pool/format_pool.c
lvm2/upstream/current/lib/format_pool/import_export.c
lvm2/upstream/current/lib/format_text/archive.c
lvm2/upstream/current/lib/format_text/export.c
lvm2/upstream/current/lib/format_text/flags.c
lvm2/upstream/current/lib/format_text/format-text.c
lvm2/upstream/current/lib/format_text/import-export.h
lvm2/upstream/current/lib/format_text/import_vsn1.c
lvm2/upstream/current/lib/format_text/layout.h
lvm2/upstream/current/lib/format_text/text_export.h
lvm2/upstream/current/lib/format_text/text_import.h
lvm2/upstream/current/lib/format_text/text_label.c
lvm2/upstream/current/lib/label/label.c
lvm2/upstream/current/lib/locking/cluster_locking.c
lvm2/upstream/current/lib/locking/file_locking.c
lvm2/upstream/current/lib/locking/locking.c
lvm2/upstream/current/lib/locking/locking.h
lvm2/upstream/current/lib/locking/locking_types.h
lvm2/upstream/current/lib/log/log.c
lvm2/upstream/current/lib/log/log.h
lvm2/upstream/current/lib/metadata/lv_alloc.h
lvm2/upstream/current/lib/metadata/lv_manip.c
lvm2/upstream/current/lib/metadata/merge.c
lvm2/upstream/current/lib/metadata/metadata.c
lvm2/upstream/current/lib/metadata/metadata.h
lvm2/upstream/current/lib/metadata/mirror.c
lvm2/upstream/current/lib/metadata/pv_map.c
lvm2/upstream/current/lib/metadata/pv_map.h
lvm2/upstream/current/lib/metadata/segtype.h
lvm2/upstream/current/lib/metadata/snapshot_manip.c
lvm2/upstream/current/lib/mirror/mirrored.c
lvm2/upstream/current/lib/misc/lvm-file.c
lvm2/upstream/current/lib/misc/selinux.c
lvm2/upstream/current/lib/misc/selinux.h
lvm2/upstream/current/lib/mm/dbg_malloc.c
lvm2/upstream/current/lib/mm/dbg_malloc.h
lvm2/upstream/current/lib/report/columns.h
lvm2/upstream/current/lib/report/report.c
lvm2/upstream/current/lib/report/report.h
lvm2/upstream/current/lib/snapshot/snapshot.c
lvm2/upstream/current/lib/striped/striped.c
lvm2/upstream/current/lib/uuid/uuid.h
lvm2/upstream/current/man/pvcreate.8
lvm2/upstream/current/po/lvm2.po
lvm2/upstream/current/scripts/clvmd_init_rhel4
lvm2/upstream/current/tools/Makefile.in
lvm2/upstream/current/tools/args.h
lvm2/upstream/current/tools/commands.h
lvm2/upstream/current/tools/lvchange.c
lvm2/upstream/current/tools/lvcreate.c
lvm2/upstream/current/tools/lvdisplay.c
lvm2/upstream/current/tools/lvmcmdline.c
lvm2/upstream/current/tools/lvmdiskscan.c
lvm2/upstream/current/tools/lvremove.c
lvm2/upstream/current/tools/lvrename.c
lvm2/upstream/current/tools/lvresize.c
lvm2/upstream/current/tools/polldaemon.c
lvm2/upstream/current/tools/pvchange.c
lvm2/upstream/current/tools/pvcreate.c
lvm2/upstream/current/tools/pvdisplay.c
lvm2/upstream/current/tools/pvmove.c
lvm2/upstream/current/tools/pvscan.c
lvm2/upstream/current/tools/reporter.c
lvm2/upstream/current/tools/toollib.c
lvm2/upstream/current/tools/toollib.h
lvm2/upstream/current/tools/tools.h
lvm2/upstream/current/tools/vgcfgbackup.c
lvm2/upstream/current/tools/vgchange.c
lvm2/upstream/current/tools/vgconvert.c
lvm2/upstream/current/tools/vgcreate.c
lvm2/upstream/current/tools/vgdisplay.c
lvm2/upstream/current/tools/vgmerge.c
lvm2/upstream/current/tools/vgreduce.c
lvm2/upstream/current/tools/vgremove.c
lvm2/upstream/current/tools/vgrename.c
lvm2/upstream/current/tools/vgscan.c
lvm2/upstream/current/tools/vgsplit.c
Log:
Load LVM2.2.01.11 into /lvm2/upstream/current.
Added: lvm2/upstream/current/CONTRIBUTORS
==============================================================================
Modified: lvm2/upstream/current/VERSION
==============================================================================
--- lvm2/upstream/current/VERSION (original)
+++ lvm2/upstream/current/VERSION Tue Jun 14 11:13:22 2005
@@ -1 +1 @@
-2.01.05 (2005-02-18)
+2.01.11 (2005-06-13)
Modified: lvm2/upstream/current/WHATS_NEW
==============================================================================
--- lvm2/upstream/current/WHATS_NEW (original)
+++ lvm2/upstream/current/WHATS_NEW Tue Jun 14 11:13:22 2005
@@ -1,3 +1,99 @@
+Version 2.01.11 - 13th June 2005
+================================
+ Use matchpathcon mode parameter.
+ Don't defer closing dead FDs in clvmd.
+ Remove hard-coded 64k text metadata writing restriction.
+ Make VG name restrictions consistent.
+ Introduce lvconvert. So far only removes mirror images.
+ Allow mirror images to be resized.
+ Allow mirror images to have more than one segment.
+ Centralise restrictions on LV names.
+ Always insert an intermediate layer for mirrors.
+ Suppress hidden LVs from reports unless --all is given.
+ Use square brackets for hidden LVs in reports.
+ Allow the creation of mirrors with contiguous extents.
+ Always perform sanity checks against metadata before committing it to disk.
+ Split lv_extend into two steps: choosing extents + allocation to LV(s).
+ Add mirror log region size to metadata.
+ Use list_iterate_items throughout and add list*back macros.
+ Introduce seg_ macros to access areas.
+ Add segtype_is_ macros.
+ Support tiny metadata areas for pool conversions.
+ Mirror activation handles disk log as well as core.
+ Activation code recognises mirror log dependency.
+ Add mirror_log and regionsize fields to report.
+ Fix non-orphan pvchange -u.
+ Fix vgmerge to handle duplicate LVIDs.
+ Move archiver code from tools into library.
+ vgscan/change/display/vgs automatically create metadata backups if needed.
+ Merge cloned allocation functions.
+ Fix contiguous allocation policy with linear.
+ Cope with missing format1 PVs again.
+ Remove lists of free PV segments.
+ Simplify pv_maps code and remove slow bitset algorithm.
+ Red-Hat-ify the clvmd rhel4 initscript.
+ %Zu->%zu
+ Fix loopfiles alias alloc & mem debugging.
+ Un-inline dbg_strdup.
+ lv_reduce tidying.
+ Remove some unnecessary parameters.
+ Introduce seg_is macros.
+
+Version 2.01.10 - 3rd May 2005
+==============================
+ Don't create backup and archive dirs till needed.
+ Reinstate full PV size when removing from VG.
+ Support loopfiles for testing.
+ Tidy lv_segment interface.
+ pv_segment support.
+ vgchange --physicalextentsize
+ Internal snapshot restructuring.
+ Remove unused internal non-persistent snapshot option.
+ Allow offline extension of snapshot volumes.
+ Move from 2-step to 3-step on-disk metadata commit.
+ Scan ramdisks too and allow non-O_DIRECT fallback.
+ Annotate, tidy and extend list.h.
+ Alignment tidying.
+ Make clvmd work around some "bugs" in gulm's node state notifications.
+ Tidy clvmd's SIGHUP handler
+
+Version 2.01.09 - 4th April 2005
+================================
+ Add --ignorelockingfailure to vgmknodes.
+ clvmd: Don't allow user operations to start until the lvm thread is fully up.
+ clvmd-gulm: set KEEPALIVE on sockets.
+
+Version 2.01.08 - 22nd March 2005
+=================================
+ Add clustered attribute so vgchange can identify clustered VGs w/o locking.
+ Improve detection of external changes affecting internal cache.
+ Add 'already in device cache' debug message.
+ Add -a to pvdisplay -C.
+ Avoid rmdir opendir error messsages when dir was already removed.
+ Tighten signal handlers.
+ Avoid some compiler warnings.
+ Additional rename failure error message.
+ read/write may be macros.
+ clvmd: don't take out lvm thread lock at startup, it only protects jobs list.
+
+Version 2.01.07 - 8th March 2005
+================================
+ Cope with new devices appearing by rescanning /dev if a uuid can't be found.
+ Remove DESTDIR from LVM_SHARED_PATH.
+ clvmd fixes: make FDs close-on-exec
+ gulm unlocks VG & orphan locks at startup in case they are stale
+ gulm now unlocks VG & orphan locks if client dies.
+
+Version 2.01.06 - 1st March 2005
+================================
+ Suppress 'open failed' error messages during scanning.
+ Option to suppress warnings of file descriptors left open.
+ Fix default value of metadatacopies in documentation (2->1).
+ Fix clvmd-gulm locking.
+ ./configure --enable-debug now enables debugging code in clvmd.
+ Fix clvmd-gulm node up/down code so it actually works.
+ clvmd-gulm now releases locks when shut down.
+
Version 2.01.05 - 18th February 2005
====================================
Static binary invokes dynamic binary if appropriate.
Modified: lvm2/upstream/current/daemons/clvmd/Makefile.in
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/Makefile.in (original)
+++ lvm2/upstream/current/daemons/clvmd/Makefile.in Tue Jun 14 11:13:22 2005
@@ -34,6 +34,10 @@
CMAN = yes
endif
+ifeq ("@DEBUG@", "yes")
+ CFLAGS += -DDEBUG
+endif
+
ifeq ("$(GULM)", "yes")
SOURCES += clvmd-gulm.c tcp-comms.c
LMLIBS += -lccs -lgulm
Modified: lvm2/upstream/current/daemons/clvmd/clvmd-cman.c
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/clvmd-cman.c (original)
+++ lvm2/upstream/current/daemons/clvmd/clvmd-cman.c Tue Jun 14 11:13:22 2005
@@ -77,6 +77,8 @@
/* Don't print an error here because we could be just probing for CMAN */
return -1;
}
+ /* Set Close-on-exec */
+ fcntl(cluster_sock, F_SETFD, 1);
/* Bind to our port number on the cluster.
Writes to this will block if the cluster loses quorum */
@@ -101,6 +103,7 @@
return -1;
}
dlm_ls_pthread_init(lockspace);
+
return 0;
}
Modified: lvm2/upstream/current/daemons/clvmd/clvmd-command.c
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/clvmd-command.c (original)
+++ lvm2/upstream/current/daemons/clvmd/clvmd-command.c Tue Jun 14 11:13:22 2005
@@ -274,9 +274,10 @@
hash_iterate(v, lock_hash) {
int lkid = (int)(long)hash_get_data(lock_hash, v);
+ char *lockname = hash_get_key(lock_hash, v);
- DEBUGLOG("cleanup: Unlocking lkid %x\n", lkid);
- sync_unlock("DUMMY", lkid);
+ DEBUGLOG("cleanup: Unlocking lock %s %x\n", lockname, lkid);
+ sync_unlock(lockname, lkid);
}
hash_destroy(lock_hash);
Modified: lvm2/upstream/current/daemons/clvmd/clvmd-comms.h
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/clvmd-comms.h (original)
+++ lvm2/upstream/current/daemons/clvmd/clvmd-comms.h Tue Jun 14 11:13:22 2005
@@ -40,6 +40,7 @@
void (*get_our_csid) (char *csid);
void (*add_up_node) (char *csid);
+ void (*reread_config) (void);
void (*cluster_closedown) (void);
int (*sync_lock) (const char *resource, int mode, int flags, int *lockid);
Modified: lvm2/upstream/current/daemons/clvmd/clvmd-gulm.c
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/clvmd-gulm.c (original)
+++ lvm2/upstream/current/daemons/clvmd/clvmd-gulm.c Tue Jun 14 11:13:22 2005
@@ -2,6 +2,7 @@
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved.
+** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
**
*******************************************************************************
******************************************************************************/
@@ -46,6 +47,7 @@
#include "log.h"
#include "clvm.h"
#include "clvmd-comms.h"
+#include "lvm-functions.h"
#include "clvmd.h"
#include "hash.h"
#include "clvmd-gulm.h"
@@ -58,13 +60,15 @@
/* hash list of outstanding lock requests */
static struct hash_table *lock_hash;
-/* Copy of the current core state */
-static uint8_t current_corestate;
+/* Copy of the current quorate state */
+static uint8_t gulm_quorate = 0;
+static enum {INIT_NOTDONE, INIT_DONE, INIT_WAITQUORATE} init_state = INIT_NOTDONE;
/* Number of active nodes */
static int num_nodes;
static char *cluster_name;
+static int in_shutdown = 0;
static pthread_mutex_t lock_start_mutex;
static volatile int lock_start_flag;
@@ -114,6 +118,9 @@
client->callback = callback;
add_client(client);
+ /* Set Close-on-exec */
+ fcntl(fd, F_SETFD, 1);
+
return 0;
}
@@ -129,12 +136,11 @@
exit(0);
}
-static void sighup_handler(int sig)
+static void _reread_config(void)
{
- DEBUGLOG("got SIGHUP\n");
-
- /* Re-read CCS node list */
- get_all_cluster_nodes();
+ /* Re-read CCS node list */
+ DEBUGLOG("Re-reading CCS config\n");
+ get_all_cluster_nodes();
}
static int _init_cluster(void)
@@ -224,7 +230,7 @@
exit(status);
}
- /* Request a list of nodes, we can;t really do anything until
+ /* Request a list of nodes, we can't really do anything until
this comes back */
status = lg_core_nodelist(gulm_if);
if (status)
@@ -237,15 +243,14 @@
signal(SIGINT, badsig_handler);
signal(SIGTERM, badsig_handler);
- /* Re-read the node list on SIGHUP */
- signal(SIGHUP, sighup_handler);
-
return 0;
}
static void _cluster_closedown(void)
{
DEBUGLOG("cluster_closedown\n");
+ in_shutdown = 1;
+ unlock_all();
lg_lock_logout(gulm_if);
lg_core_logout(gulm_if);
lg_release(gulm_if);
@@ -258,6 +263,7 @@
struct utsname nodeinfo;
uint8_t mask[GIO_KEY_SIZE];
+ DEBUGLOG("Dropping expired locks for %s\n", nodename?nodename:"(null)");
memset(mask, 0xff, GIO_KEY_SIZE);
if (!nodename)
@@ -303,12 +309,16 @@
if (error)
exit(error);
- current_corestate = corestate;
+ /* Get the current core state (for quorum) */
+ lg_core_corestate(gulm_if);
+
return 0;
}
static void set_node_state(struct node_info *ninfo, char *csid, uint8_t nodestate)
{
+ int oldstate = ninfo->state;
+
if (nodestate == lg_core_Logged_in)
{
/* Don't clobber NODE_CLVMD state */
@@ -330,11 +340,17 @@
if (ninfo->state != NODE_DOWN)
num_nodes--;
ninfo->state = NODE_DOWN;
- tcp_remove_client(csid);
}
}
- DEBUGLOG("set_node_state, '%s' state = %d, num_nodes=%d\n",
- ninfo->name, ninfo->state, num_nodes);
+ /* Gulm doesn't always send node DOWN events, so even if this a a node UP we must
+ * assume (ahem) that it prevously went down at some time. So we close
+ * the sockets here to make sure that we don't have any dead connections
+ * to that node.
+ */
+ tcp_remove_client(csid);
+
+ DEBUGLOG("set_node_state, '%s' state = %d (oldstate=%d), num_nodes=%d\n",
+ ninfo->name, ninfo->state, oldstate, num_nodes);
}
static struct node_info *add_or_set_node(char *name, struct in6_addr *ip, uint8_t state)
@@ -391,7 +407,16 @@
char ourcsid[GULM_MAX_CSID_LEN];
DEBUGLOG("Got Nodelist, stop\n");
- clvmd_cluster_init_completed();
+ if (gulm_quorate)
+ {
+ clvmd_cluster_init_completed();
+ init_state = INIT_DONE;
+ }
+ else
+ {
+ if (init_state == INIT_NOTDONE)
+ init_state = INIT_WAITQUORATE;
+ }
/* Mark ourself as up */
_get_our_csid(ourcsid);
@@ -409,10 +434,15 @@
static int core_statechange(void *misc, uint8_t corestate, uint8_t quorate, struct in6_addr *masterip, char *mastername)
{
- DEBUGLOG("CORE Got statechange corestate:%#x mastername:%s\n",
- corestate, mastername);
+ DEBUGLOG("CORE Got statechange. quorate:%d, corestate:%x mastername:%s\n",
+ quorate, corestate, mastername);
- current_corestate = corestate;
+ gulm_quorate = quorate;
+ if (quorate && init_state == INIT_WAITQUORATE)
+ {
+ clvmd_cluster_init_completed();
+ init_state = INIT_DONE;
+ }
return 0;
}
@@ -478,6 +508,10 @@
DEBUGLOG("LOCK lock state: %s, error = %d\n", key, error);
+ /* No waiting process to wake up when we are shutting down */
+ if (in_shutdown)
+ return 0;
+
lwait = hash_lookup(lock_hash, key);
if (!lwait)
{
@@ -596,10 +630,17 @@
struct node_info *ninfo;
ninfo = hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
- if (!ninfo)
+ if (!ninfo) {
+ DEBUGLOG("gulm_add_up_node no node_hash entry for csid %s\n", print_csid(csid));
return;
+ }
+ DEBUGLOG("gulm_add_up_node %s\n", ninfo->name);
+
+ if (ninfo->state == NODE_DOWN)
+ num_nodes++;
ninfo->state = NODE_CLVMD;
+
return;
}
@@ -616,13 +657,14 @@
running clvmd - gulm may set it DOWN quite soon */
if (ninfo->state == NODE_CLVMD)
ninfo->state = NODE_UP;
+ drop_expired_locks(ninfo->name);
return;
}
/* Call a callback for each node, so the caller knows whether it's up or down */
static int _cluster_do_node_callback(struct local_client *master_client,
- void (*callback)(struct local_client *, char *csid, int node_up))
+ void (*callback)(struct local_client *, char *csid, int node_up))
{
struct hash_node *hn;
struct node_info *ninfo;
@@ -638,8 +680,19 @@
DEBUGLOG("down_callback. node %s, state = %d\n", ninfo->name, ninfo->state);
client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
- if (client)
- callback(master_client, csid, ninfo->state == NODE_CLVMD);
+ if (!client)
+ {
+ /* If it's up but not connected, try to make contact */
+ if (ninfo->state == NODE_UP)
+ gulm_connect_csid(csid, &client);
+
+ client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
+
+ }
+ if (ninfo->state != NODE_DOWN)
+ callback(master_client, csid, ninfo->state == NODE_CLVMD);
+
+
}
return 0;
}
@@ -727,6 +780,11 @@
return status;
}
+ /* When we are shutting down, don't wait for unlocks
+ to be acknowledged, just do it. */
+ if (in_shutdown)
+ return status;
+
/* Wait for it to complete */
pthread_cond_wait(&lwait.cond, &lwait.mutex);
@@ -763,7 +821,7 @@
if (status)
goto out;
- /* If we can't get this lock then bail out */
+ /* If we can't get this lock too then bail out */
status = _lock_resource(lock2, lg_lock_state_Exclusive, LCK_NONBLOCK, lockid);
if (status == lg_err_TryFailed)
{
@@ -775,10 +833,16 @@
case LCK_READ:
status = _lock_resource(lock1, lg_lock_state_Shared, flags, lockid);
+ if (status)
+ goto out;
+ status = _unlock_resource(lock2, *lockid);
break;
case LCK_WRITE:
status = _lock_resource(lock2, lg_lock_state_Exclusive, flags, lockid);
+ if (status)
+ goto out;
+ status = _unlock_resource(lock1, *lockid);
break;
default:
@@ -805,36 +869,16 @@
lockid == LCK_READ ||
lockid == LCK_WRITE);
- switch (lockid)
- {
- case LCK_EXCL:
- status = _unlock_resource(lock1, lockid);
- if (status)
- goto out;
- status = _unlock_resource(lock2, lockid);
- break;
-
- case LCK_READ:
- status = _unlock_resource(lock1, lockid);
- break;
+ status = _unlock_resource(lock1, lockid);
+ if (!status)
+ status = _unlock_resource(lock2, lockid);
- case LCK_WRITE:
- status = _unlock_resource(lock2, lockid);
- break;
- }
-
- out:
return status;
}
static int _is_quorate()
{
- if (current_corestate == lg_core_Slave ||
- current_corestate == lg_core_Master ||
- current_corestate == lg_core_Client)
- return 1;
- else
- return 0;
+ return gulm_quorate;
}
/* Get all the cluster node names & IPs from CCS and
@@ -938,6 +982,7 @@
.is_quorate = _is_quorate,
.get_our_csid = _get_our_csid,
.add_up_node = gulm_add_up_node,
+ .reread_config = _reread_config,
.cluster_closedown = _cluster_closedown,
.sync_lock = _sync_lock,
.sync_unlock = _sync_unlock,
Modified: lvm2/upstream/current/daemons/clvmd/clvmd.c
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/clvmd.c (original)
+++ lvm2/upstream/current/daemons/clvmd/clvmd.c Tue Jun 14 11:13:22 2005
@@ -87,8 +87,10 @@
static pthread_t lvm_thread;
static pthread_mutex_t lvm_thread_mutex;
static pthread_cond_t lvm_thread_cond;
+static pthread_mutex_t lvm_start_mutex;
static struct list lvm_cmd_head;
-static int quit = 0;
+static volatile sig_atomic_t quit = 0;
+static volatile sig_atomic_t reread_config = 0;
static int child_pipe[2];
/* Reasons the daemon failed initialisation */
@@ -100,6 +102,7 @@
/* Prototypes for code further down */
static void sigusr2_handler(int sig);
+static void sighup_handler(int sig);
static void sigterm_handler(int sig);
static void send_local_reply(struct local_client *client, int status,
int clientid);
@@ -165,6 +168,7 @@
int debug = 0;
int cmd_timeout = DEFAULT_CMD_TIMEOUT;
sigset_t ss;
+ int using_gulm = 0;
/* Deal with command-line arguments */
opterr = 0;
@@ -220,8 +224,10 @@
/* Set up signal handlers, USR1 is for cluster change notifications (in cman)
USR2 causes child threads to exit.
+ HUP causes gulm version to re-read nodes list from CCS.
PIPE should be ignored */
signal(SIGUSR2, sigusr2_handler);
+ signal(SIGHUP, sighup_handler);
signal(SIGPIPE, SIG_IGN);
/* Block SIGUSR2 in the main process */
@@ -233,6 +239,7 @@
list_init(&lvm_cmd_head);
pthread_mutex_init(&lvm_thread_mutex, NULL);
pthread_cond_init(&lvm_thread_cond, NULL);
+ pthread_mutex_init(&lvm_start_mutex, NULL);
init_lvhash();
/* Start the cluster interface */
@@ -250,6 +257,7 @@
max_csid_len = GULM_MAX_CSID_LEN;
max_cluster_message = GULM_MAX_CLUSTER_MESSAGE;
max_cluster_member_name_len = GULM_MAX_CLUSTER_MEMBER_NAME_LEN;
+ using_gulm = 1;
syslog(LOG_NOTICE, "Cluster LVM daemon started - connected to GULM");
}
#endif
@@ -276,6 +284,7 @@
child_init_signal(DFAIL_MALLOC);
newfd->fd = local_sock;
+ newfd->removeme = 0;
newfd->type = LOCAL_RENDEZVOUS;
newfd->callback = local_rendezvous_callback;
newfd->next = local_client_head.next;
@@ -284,7 +293,7 @@
/* This needs to be started after cluster initialisation
as it may need to take out locks */
DEBUGLOG("starting LVM thread\n");
- pthread_create(&lvm_thread, NULL, lvm_thread_fn, nodeinfo.nodename);
+ pthread_create(&lvm_thread, NULL, lvm_thread_fn, (void *)using_gulm);
/* Tell the rest of the cluster our version number */
/* CMAN can do this immediately, gulm needs to wait until
@@ -342,6 +351,7 @@
newfd->fd = client_fd;
newfd->type = LOCAL_SOCK;
newfd->xid = 0;
+ newfd->removeme = 0;
newfd->callback = local_sock_callback;
newfd->bits.localsock.replies = NULL;
newfd->bits.localsock.expected_replies = 0;
@@ -508,13 +518,38 @@
FD_SET(thisfd->fd, &in);
}
- if ((select_status = select(FD_SETSIZE, &in, NULL, NULL, &tv)) > 0) {
+ select_status = select(FD_SETSIZE, &in, NULL, NULL, &tv);
+
+ if (reread_config) {
+ int saved_errno = errno;
+
+ reread_config = 0;
+ if (clops->reread_config)
+ clops->reread_config();
+ errno = saved_errno;
+ }
+
+ if (select_status > 0) {
struct local_client *lastfd = NULL;
char csid[MAX_CSID_LEN];
char buf[max_cluster_message];
for (thisfd = &local_client_head; thisfd != NULL;
thisfd = thisfd->next) {
+
+ if (thisfd->removeme) {
+ struct local_client *free_fd;
+ lastfd->next = thisfd->next;
+ free_fd = thisfd;
+ thisfd = lastfd;
+
+ DEBUGLOG("removeme set for fd %d\n", free_fd->fd);
+
+ /* Queue cleanup, this also frees the client struct */
+ add_to_lvmqueue(free_fd, NULL, 0, NULL);
+ break;
+ }
+
if (FD_ISSET(thisfd->fd, &in)) {
struct local_client *newfd;
int ret;
@@ -543,8 +578,10 @@
lastfd->next = thisfd->next;
free_fd = thisfd;
thisfd = lastfd;
- cmd_client_cleanup(free_fd);
- free(free_fd);
+ close(free_fd->fd);
+
+ /* Queue cleanup, this also frees the client struct */
+ add_to_lvmqueue(free_fd, NULL, 0, NULL);
break;
}
@@ -900,6 +937,7 @@
DEBUGLOG("creating pipe, [%d, %d]\n", comms_pipe[0],
comms_pipe[1]);
newfd->fd = comms_pipe[0];
+ newfd->removeme = 0;
newfd->type = THREAD_PIPE;
newfd->callback = local_pipe_callback;
newfd->next = thisfd->next;
@@ -1056,8 +1094,8 @@
/* Get the node name as we /may/ need it later */
clops->name_from_csid(csid, nodename);
- DEBUGLOG("process_remote_command %d for clientid 0x%x on node %s\n",
- msg->cmd, msg->clientid, nodename);
+ DEBUGLOG("process_remote_command %d for clientid 0x%x XID %d on node %s\n",
+ msg->cmd, msg->clientid, msg->xid, nodename);
/* Is the data to be found in the system LV ? */
if (msg->flags & CLVMD_FLAG_SYSTEMLV) {
@@ -1300,6 +1338,11 @@
DEBUGLOG("in sub thread: client = %p\n", client);
+ /* Don't start until the LVM thread is ready */
+ pthread_mutex_lock(&lvm_start_mutex);
+ pthread_mutex_unlock(&lvm_start_mutex);
+ DEBUGLOG("Sub thread ready for work.\n");
+
/* Ignore SIGUSR1 (handled by master process) but enable
SIGUSR2 (kills subthreads) */
sigemptyset(&ss);
@@ -1565,6 +1608,14 @@
static int process_work_item(struct lvm_thread_cmd *cmd)
{
+ /* If msg is NULL then this is a cleanup request */
+ if (cmd->msg == NULL) {
+ DEBUGLOG("process_work_item: free fd %d\n", cmd->client->fd);
+ cmd_client_cleanup(cmd->client);
+ free(cmd->client);
+ return 0;
+ }
+
if (!cmd->remote) {
DEBUGLOG("process_work_item: local\n");
process_local_command(cmd->msg, cmd->msglen, cmd->client,
@@ -1584,9 +1635,12 @@
{
struct list *cmdl, *tmp;
sigset_t ss;
+ int using_gulm = (int)arg;
+
+ /* Don't let anyone else to do work until we are started */
+ pthread_mutex_lock(&lvm_start_mutex);
DEBUGLOG("LVM thread function started\n");
- pthread_mutex_lock(&lvm_thread_mutex);
/* Ignore SIGUSR1 & 2 */
sigemptyset(&ss);
@@ -1595,8 +1649,10 @@
pthread_sigmask(SIG_BLOCK, &ss, NULL);
/* Initialise the interface to liblvm */
- init_lvm();
- pthread_mutex_unlock(&lvm_thread_mutex);
+ init_lvm(using_gulm);
+
+ /* Allow others to get moving */
+ pthread_mutex_unlock(&lvm_start_mutex);
/* Now wait for some actual work */
for (;;) {
@@ -1615,7 +1671,8 @@
pthread_mutex_unlock(&lvm_thread_mutex);
process_work_item(cmd);
- free(cmd->msg);
+ if (cmd->msg)
+ free(cmd->msg);
free(cmd);
pthread_mutex_lock(&lvm_thread_mutex);
@@ -1634,17 +1691,22 @@
if (!cmd)
return ENOMEM;
- cmd->msg = malloc(msglen);
- if (!cmd->msg) {
- log_error("Unable to allocate buffer space\n");
- free(cmd);
- return -1;
+ if (msglen) {
+ cmd->msg = malloc(msglen);
+ if (!cmd->msg) {
+ log_error("Unable to allocate buffer space\n");
+ free(cmd);
+ return -1;
+ }
+ memcpy(cmd->msg, msg, msglen);
+ }
+ else {
+ cmd->msg = NULL;
}
-
cmd->client = client;
cmd->msglen = msglen;
cmd->xid = client->xid;
- memcpy(cmd->msg, msg, msglen);
+
if (csid) {
memcpy(cmd->csid, csid, max_csid_len);
cmd->remote = 1;
@@ -1677,6 +1739,8 @@
log_error("Can't create local socket: %m");
return -1;
}
+ /* Set Close-on-exec */
+ fcntl(local_socket, F_SETFD, 1);
memset(&sockaddr, 0, sizeof(sockaddr));
memcpy(sockaddr.sun_path, CLVMD_SOCKNAME, sizeof(CLVMD_SOCKNAME));
@@ -1771,6 +1835,12 @@
return;
}
+static void sighup_handler(int sig)
+{
+ DEBUGLOG("got SIGHUP\n");
+ reread_config = 1;
+}
+
int sync_lock(const char *resource, int mode, int flags, int *lockid)
{
return clops->sync_lock(resource, mode, flags, lockid);
Modified: lvm2/upstream/current/daemons/clvmd/clvmd.h
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/clvmd.h (original)
+++ lvm2/upstream/current/daemons/clvmd/clvmd.h Tue Jun 14 11:13:22 2005
@@ -86,6 +86,7 @@
struct local_client *next;
unsigned short xid;
fd_callback_t callback;
+ uint8_t removeme;
union {
struct localsock_bits localsock;
@@ -93,9 +94,9 @@
struct netsock_bits net;
} bits;
};
-#define DEBUG
+
#ifdef DEBUG
-#define DEBUGLOG(fmt, args...) fprintf(stderr, "CLVMD[%d]: %ld ", getpid(), time(NULL) ); fprintf(stderr, fmt, ## args)
+#define DEBUGLOG(fmt, args...) {time_t P; time(&P); fprintf(stderr, "CLVMD[%x]: %.15s ", (int)pthread_self(), ctime(&P)+4 ); fprintf(stderr, fmt, ## args);}
#else
#define DEBUGLOG(fmt, args...)
#endif
Modified: lvm2/upstream/current/daemons/clvmd/lvm-functions.c
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/lvm-functions.c (original)
+++ lvm2/upstream/current/daemons/clvmd/lvm-functions.c Tue Jun 14 11:13:22 2005
@@ -388,6 +388,44 @@
return status == 1 ? 0 : EBUSY;
}
+
+/* Only called at gulm startup. Drop any leftover VG or P_orphan locks
+ that might be hanging around if we died for any reason
+*/
+static void drop_vg_locks()
+{
+ char vg[128];
+ char line[255];
+ FILE *vgs =
+ popen
+ ("lvm pvs --nolocking --noheadings -o vg_name", "r");
+
+ sync_unlock("P_orphans", LCK_EXCL);
+
+ if (!vgs)
+ return;
+
+ while (fgets(line, sizeof(line), vgs)) {
+ char *vgend;
+ char *vgstart;
+
+ if (line[strlen(line)-1] == '\n')
+ line[strlen(line)-1] = '\0';
+
+ vgstart = line + strspn(line, " ");
+ vgend = vgstart + strcspn(vgstart, " ");
+ *vgend = '\0';
+
+ if (strncmp(vgstart, "WARNING:", 8) == 0)
+ continue;
+
+ sprintf(vg, "V_%s", vgstart);
+ sync_unlock(vg, LCK_EXCL);
+
+ }
+ fclose(vgs);
+}
+
/*
* Ideally, clvmd should be started before any LVs are active
* but this may not be the case...
@@ -470,7 +508,7 @@
}
/* Called to initialise the LVM context of the daemon */
-int init_lvm(void)
+int init_lvm(int using_gulm)
{
if (!(cmd = create_toolcontext(NULL))) {
log_error("Failed to allocate command context");
@@ -484,6 +522,10 @@
/* Check lvm.conf is setup for cluster-LVM */
check_config();
+ /* Remove any non-LV locks that may have been left around */
+ if (using_gulm)
+ drop_vg_locks();
+
get_initial_state();
return 1;
Modified: lvm2/upstream/current/daemons/clvmd/lvm-functions.h
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/lvm-functions.h (original)
+++ lvm2/upstream/current/daemons/clvmd/lvm-functions.h Tue Jun 14 11:13:22 2005
@@ -25,7 +25,7 @@
extern int post_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
char *resource);
extern int do_check_lvm1(char *vgname);
-extern int init_lvm(void);
+extern int init_lvm(int using_gulm);
extern void init_lvhash(void);
extern int hold_unlock(char *resource);
Modified: lvm2/upstream/current/daemons/clvmd/tcp-comms.c
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/tcp-comms.c (original)
+++ lvm2/upstream/current/daemons/clvmd/tcp-comms.c Tue Jun 14 11:13:22 2005
@@ -2,6 +2,7 @@
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved.
+** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
**
*******************************************************************************
******************************************************************************/
@@ -68,6 +69,7 @@
{
int one = 1;
setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
+ setsockopt(listen_fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(int));
}
memset(&addr, 0, sizeof(addr)); // Bind to INADDR_ANY
@@ -84,6 +86,9 @@
listen(listen_fd, 5);
+ /* Set Close-on-exec */
+ fcntl(listen_fd, F_SETFD, 1);
+
return 0;
}
@@ -100,6 +105,8 @@
if (client)
{
hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
+ client->removeme = 1;
+ close(client->fd);
}
/* Look for a mangled one too */
@@ -109,6 +116,8 @@
if (client)
{
hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
+ client->removeme = 1;
+ close(client->fd);
}
/* Put it back as we found it */
@@ -221,6 +230,25 @@
return newfd;
}
+/* Try to get at least 'len' bytes from the socket */
+static int really_read(int fd, char *buf, int len)
+{
+ int got, offset;
+
+ got = offset = 0;
+
+ do {
+ got = read(fd, buf+offset, len-offset);
+ DEBUGLOG("really_read. got %d bytes\n", got);
+ offset += got;
+ } while (got > 0 && offset < len);
+
+ if (got < 0)
+ return got;
+ else
+ return offset;
+}
+
static int read_from_tcpsock(struct local_client *client, char *buf, int len, char *csid,
struct local_client **new_client)
@@ -241,7 +269,7 @@
/* Read just the header first, then get the rest if there is any.
* Stream sockets, sigh.
*/
- status = read(client->fd, buf, sizeof(struct clvm_header));
+ status = really_read(client->fd, buf, sizeof(struct clvm_header));
if (status > 0)
{
int status2;
@@ -251,7 +279,7 @@
/* Get the rest */
if (arglen && arglen < GULM_MAX_CLUSTER_MESSAGE)
{
- status2 = read(client->fd, buf+status, arglen);
+ status2 = really_read(client->fd, buf+status, arglen);
if (status2 > 0)
status += status2;
else
@@ -280,17 +308,19 @@
add_down_node(remcsid);
}
else {
+ gulm_add_up_node(csid);
/* Send it back to clvmd */
- process_message(client, buf, len, csid);
+ process_message(client, buf, status, csid);
}
return status;
}
-static int connect_csid(char *csid, struct local_client **newclient)
+int gulm_connect_csid(char *csid, struct local_client **newclient)
{
int fd;
struct sockaddr_in6 addr;
int status;
+ int one = 1;
DEBUGLOG("Connecting socket\n");
fd = socket(PF_INET6, SOCK_STREAM, 0);
@@ -320,6 +350,10 @@
return -1;
}
+ /* Set Close-on-exec */
+ fcntl(fd, F_SETFD, 1);
+ setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(int));
+
status = alloc_client(fd, csid, newclient);
if (status)
close(fd);
@@ -350,7 +384,7 @@
client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
if (!client)
{
- status = connect_csid(csid, &client);
+ status = gulm_connect_csid(csid, &client);
if (status)
return -1;
}
Modified: lvm2/upstream/current/daemons/clvmd/tcp-comms.h
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/tcp-comms.h (original)
+++ lvm2/upstream/current/daemons/clvmd/tcp-comms.h Tue Jun 14 11:13:22 2005
@@ -10,3 +10,4 @@
int cluster_fd_gulm_callback(struct local_client *fd, char *buf, int len, char *csid, struct local_client **new_client);
int gulm_cluster_send_message(void *buf, int msglen, char *csid, const char *errtext);
void get_our_gulm_csid(char *csid);
+int gulm_connect_csid(char *csid, struct local_client **newclient);
Modified: lvm2/upstream/current/doc/example.conf
==============================================================================
--- lvm2/upstream/current/doc/example.conf (original)
+++ lvm2/upstream/current/doc/example.conf Tue Jun 14 11:13:22 2005
@@ -258,11 +258,10 @@
#
# metadata {
# Default number of copies of metadata to hold on each PV. 0, 1 or 2.
- # It's best to leave this at 2.
- # You might want to override it from the command line with 0 or 1
+ # You might want to override it from the command line with 0
# when running pvcreate on new PVs which are to be added to large VGs.
- # pvmetadatacopies = 2
+ # pvmetadatacopies = 1
# Approximate default size of on-disk metadata areas in sectors.
# You should increase this if you have large volume groups or
Modified: lvm2/upstream/current/include/.symlinks
==============================================================================
--- lvm2/upstream/current/include/.symlinks (original)
+++ lvm2/upstream/current/include/.symlinks Tue Jun 14 11:13:22 2005
@@ -23,6 +23,7 @@
../lib/filters/filter.h
../lib/format1/format1.h
../lib/format_pool/format_pool.h
+../lib/format_text/archiver.h
../lib/format_text/format-text.h
../lib/format_text/text_export.h
../lib/format_text/text_import.h
@@ -31,6 +32,7 @@
../lib/log/log.h
../lib/metadata/lv_alloc.h
../lib/metadata/metadata.h
+../lib/metadata/pv_alloc.h
../lib/metadata/segtype.h
../lib/mm/dbg_malloc.h
../lib/mm/memlock.h
Modified: lvm2/upstream/current/lib/Makefile.in
==============================================================================
--- lvm2/upstream/current/lib/Makefile.in (original)
+++ lvm2/upstream/current/lib/Makefile.in Tue Jun 14 11:13:22 2005
@@ -54,6 +54,7 @@
filters/filter-md.c \
filters/filter.c \
format_text/archive.c \
+ format_text/archiver.c \
format_text/export.c \
format_text/flags.c \
format_text/format-text.c \
@@ -70,6 +71,7 @@
metadata/merge.c \
metadata/metadata.c \
metadata/mirror.c \
+ metadata/pv_manip.c \
metadata/pv_map.c \
metadata/segtype.c \
metadata/snapshot_manip.c \
Modified: lvm2/upstream/current/lib/activate/activate.c
==============================================================================
--- lvm2/upstream/current/lib/activate/activate.c (original)
+++ lvm2/upstream/current/lib/activate/activate.c Tue Jun 14 11:13:22 2005
@@ -517,17 +517,15 @@
*/
int lvs_in_vg_activated(struct volume_group *vg)
{
- struct list *lvh;
- struct logical_volume *lv;
+ struct lv_list *lvl;
int count = 0;
if (!activation())
return 0;
- list_iterate(lvh, &vg->lvs) {
- lv = list_item(lvh, struct lv_list)->lv;
- if (lv->status & VISIBLE_LV)
- count += (_lv_active(lv) == 1);
+ list_iterate_items(lvl, &vg->lvs) {
+ if (lvl->lv->status & VISIBLE_LV)
+ count += (_lv_active(lvl->lv) == 1);
}
return count;
@@ -535,17 +533,15 @@
int lvs_in_vg_opened(struct volume_group *vg)
{
- struct list *lvh;
- struct logical_volume *lv;
+ struct lv_list *lvl;
int count = 0;
if (!activation())
return 0;
- list_iterate(lvh, &vg->lvs) {
- lv = list_item(lvh, struct lv_list)->lv;
- if (lv->status & VISIBLE_LV)
- count += (_lv_open_count(lv) > 0);
+ list_iterate_items(lvl, &vg->lvs) {
+ if (lvl->lv->status & VISIBLE_LV)
+ count += (_lv_open_count(lvl->lv) > 0);
}
return count;
Modified: lvm2/upstream/current/lib/activate/dev_manager.c
==============================================================================
--- lvm2/upstream/current/lib/activate/dev_manager.c (original)
+++ lvm2/upstream/current/lib/activate/dev_manager.c Tue Jun 14 11:13:22 2005
@@ -727,6 +727,54 @@
return 1;
}
+int compose_log_line(struct dev_manager *dm, struct lv_segment *seg,
+ char *params, size_t paramsize, int *pos, int areas,
+ uint32_t region_size)
+{
+ int tw;
+ char devbuf[10];
+ char *name;
+ struct dev_layer *dl;
+
+ if (!seg->log_lv)
+ tw = lvm_snprintf(params, paramsize, "core 1 %u %u ",
+ region_size, areas);
+ else {
+ if (!(name = build_dm_name(dm->mem, seg->log_lv->vg->name,
+ seg->log_lv->name, NULL))) {
+ stack;
+ return 0;
+ }
+
+ if (!(dl = hash_lookup(dm->layers, seg->log_lv->lvid.s))) {
+ log_error("device layer %s missing from hash",
+ seg->log_lv->lvid.s);
+ return 0;
+ }
+
+ if (!dm_format_dev(devbuf, sizeof(devbuf), dl->info.major,
+ dl->info.minor)) {
+ log_error("Failed to format device number as dm "
+ "target (%u,%u)",
+ dl->info.major, dl->info.minor);
+ return 0;
+ }
+
+ /* FIXME add sync parm? */
+ tw = lvm_snprintf(params, paramsize, "disk 2 %s %u %u ",
+ devbuf, region_size, areas);
+ }
+
+ if (tw < 0) {
+ stack;
+ return -1;
+ }
+
+ *pos += tw;
+
+ return 1;
+}
+
int compose_areas_line(struct dev_manager *dm, struct lv_segment *seg,
char *params, size_t paramsize, int *pos, int start_area,
int areas)
@@ -740,24 +788,26 @@
for (s = start_area; s < areas; s++, *pos += tw) {
trailing_space = (areas - s - 1) ? " " : "";
- if ((seg->area[s].type == AREA_PV &&
- (!seg->area[s].u.pv.pv || !seg->area[s].u.pv.pv->dev)) ||
- (seg->area[s].type == AREA_LV && !seg->area[s].u.lv.lv))
+ if ((seg_type(seg, s) == AREA_PV &&
+ (!seg_pvseg(seg, s) ||
+ !seg_pv(seg, s) ||
+ !seg_dev(seg, s))) ||
+ (seg_type(seg, s) == AREA_LV && !seg_lv(seg, s)))
tw = lvm_snprintf(params + *pos, paramsize - *pos,
"%s 0%s", dm->stripe_filler,
trailing_space);
- else if (seg->area[s].type == AREA_PV)
+ else if (seg_type(seg, s) == AREA_PV)
tw = lvm_snprintf(params + *pos, paramsize - *pos,
"%s %" PRIu64 "%s",
- dev_name(seg->area[s].u.pv.pv->dev),
- (seg->area[s].u.pv.pv->pe_start +
- (esize * seg->area[s].u.pv.pe)),
+ dev_name(seg_dev(seg, s)),
+ (seg_pv(seg, s)->pe_start +
+ (esize * seg_pe(seg, s))),
trailing_space);
else {
if (!(dl = hash_lookup(dm->layers,
- seg->area[s].u.lv.lv->lvid.s))) {
+ seg_lv(seg, s)->lvid.s))) {
log_error("device layer %s missing from hash",
- seg->area[s].u.lv.lv->lvid.s);
+ seg_lv(seg, s)->lvid.s);
return 0;
}
if (!dm_format_dev
@@ -770,7 +820,7 @@
}
tw = lvm_snprintf(params + *pos, paramsize - *pos,
"%s %" PRIu64 "%s", devbuf,
- esize * seg->area[s].u.lv.le,
+ esize * seg_le(seg, s),
trailing_space);
}
@@ -818,14 +868,12 @@
static int _populate_vanilla(struct dev_manager *dm,
struct dm_task *dmt, struct dev_layer *dl)
{
- struct list *segh;
struct lv_segment *seg;
struct logical_volume *lv = dl->lv;
dm->pvmove_mirror_count = 0u;
- list_iterate(segh, &lv->segments) {
- seg = list_item(segh, struct lv_segment);
+ list_iterate_items(seg, &lv->segments) {
if (!_emit_target(dm, dmt, seg)) {
log_error("Unable to build table for '%s'", lv->name);
return 0;
@@ -875,22 +923,23 @@
{
char *origin, *cow;
char params[PATH_MAX * 2 + 32];
- struct snapshot *s;
+ struct lv_segment *snap_seg;
struct dev_layer *dlo, *dlc;
char devbufo[10], devbufc[10];
uint64_t size;
- if (!(s = find_cow(dl->lv))) {
+ if (!(snap_seg = find_cow(dl->lv))) {
log_error("Couldn't find snapshot for '%s'.", dl->lv->name);
return 0;
}
- if (!(origin = _build_dlid(dm->mem, s->origin->lvid.s, "real"))) {
+ if (!(origin = _build_dlid(dm->mem, snap_seg->origin->lvid.s,
+ "real"))) {
stack;
return 0;
}
- if (!(cow = _build_dlid(dm->mem, s->cow->lvid.s, "cow"))) {
+ if (!(cow = _build_dlid(dm->mem, snap_seg->cow->lvid.s, "cow"))) {
stack;
return 0;
}
@@ -909,24 +958,24 @@
if (!dm_format_dev(devbufo, sizeof(devbufo), dlo->info.major,
dlo->info.minor)) {
log_error("Couldn't create origin device parameters for '%s'.",
- s->origin->name);
+ snap_seg->origin->name);
return 0;
}
if (!dm_format_dev(devbufc, sizeof(devbufc), dlc->info.major,
dlc->info.minor)) {
log_error("Couldn't create cow device parameters for '%s'.",
- s->cow->name);
+ snap_seg->cow->name);
return 0;
}
if (lvm_snprintf(params, sizeof(params), "%s %s P %d",
- devbufo, devbufc, s->chunk_size) == -1) {
+ devbufo, devbufc, snap_seg->chunk_size) == -1) {
stack;
return 0;
}
- size = (uint64_t) s->le_count * s->origin->vg->extent_size;
+ size = (uint64_t) snap_seg->len * snap_seg->origin->vg->extent_size;
log_debug("Adding target: 0 %" PRIu64 " snapshot %s", size, params);
if (!dm_task_add_target(dmt, UINT64_C(0), size, "snapshot", params)) {
@@ -1176,7 +1225,6 @@
* only one layer.
*/
struct dev_layer *dl, *dlr;
- struct list *segh;
struct lv_segment *seg;
uint32_t s;
@@ -1194,14 +1242,22 @@
_set_flag(dl, TOPLEVEL);
/* Add dependencies for any LVs that segments refer to */
- list_iterate(segh, &lv->segments) {
- seg = list_item(segh, struct lv_segment);
+ list_iterate_items(seg, &lv->segments) {
+ if (seg->log_lv &&
+ !str_list_add(dm->mem, &dl->pre_create,
+ _build_dlid(dm->mem, seg->log_lv->lvid.s,
+ NULL))) {
+ stack;
+ return 0;
+ }
+ // FIXME Check we don't want NOPROPAGATE here
+
for (s = 0; s < seg->area_count; s++) {
- if (seg->area[s].type != AREA_LV)
+ if (seg_type(seg, s) != AREA_LV)
continue;
if (!str_list_add(dm->mem, &dl->pre_create,
_build_dlid(dm->mem,
- seg->area[s].u.lv.lv->
+ seg_lv(seg, s)->
lvid.s, NULL))) {
stack;
return 0;
@@ -1274,16 +1330,16 @@
static int _expand_origin(struct dev_manager *dm, struct logical_volume *lv)
{
struct logical_volume *active;
- struct snapshot *s;
- struct list *sh;
+ struct lv_segment *snap_seg;
+ struct lv_list *lvl;
/*
* We only need to create an origin layer if one of our
* snapshots is in the active list
*/
- list_iterate(sh, &dm->active_list) {
- active = list_item(sh, struct lv_list)->lv;
- if ((s = find_cow(active)) && (s->origin == lv))
+ list_iterate_items(lvl, &dm->active_list) {
+ active = lvl->lv;
+ if ((snap_seg = find_cow(active)) && (snap_seg->origin == lv))
return _expand_origin_real(dm, lv);
}
@@ -1294,7 +1350,7 @@
}
static int _expand_snapshot(struct dev_manager *dm, struct logical_volume *lv,
- struct snapshot *s)
+ struct lv_segment *snap_seg)
{
/*
* snapshot(org, cow)
@@ -1331,13 +1387,15 @@
/* add the dependency on the real origin device */
if (!str_list_add(dm->mem, &dl->pre_create,
- _build_dlid(dm->mem, s->origin->lvid.s, "real"))) {
+ _build_dlid(dm->mem, snap_seg->origin->lvid.s,
+ "real"))) {
stack;
return 0;
}
/* add the dependency on the visible origin device */
- if (!str_list_add(dm->mem, &dl->pre_suspend, s->origin->lvid.s)) {
+ if (!str_list_add(dm->mem, &dl->pre_suspend,
+ snap_seg->origin->lvid.s)) {
stack;
return 0;
}
@@ -1350,13 +1408,13 @@
*/
static int _expand_lv(struct dev_manager *dm, struct logical_volume *lv)
{
- struct snapshot *s;
+ struct lv_segment *snap_seg;
/*
* FIXME: this doesn't cope with recursive snapshots yet.
*/
- if ((s = find_cow(lv)))
- return _expand_snapshot(dm, lv, s);
+ if ((snap_seg = find_cow(lv)))
+ return _expand_snapshot(dm, lv, snap_seg);
else if (lv_is_origin(lv))
return _expand_origin(dm, lv);
@@ -1384,12 +1442,12 @@
static int _trace_layer_marks(struct dev_manager *dm, struct dev_layer *dl,
int flag)
{
- struct list *sh;
+ struct str_list *strl;
const char *dlid;
struct dev_layer *dep;
- list_iterate(sh, &dl->pre_create) {
- dlid = list_item(sh, struct str_list)->str;
+ list_iterate_items(strl, &dl->pre_create) {
+ dlid = strl->str;
if (!(dep = hash_lookup(dm->layers, dlid))) {
log_error("Couldn't find device layer '%s'.", dlid);
@@ -1439,14 +1497,14 @@
*/
static int _mark_lvs(struct dev_manager *dm, struct list *lvs, int flag)
{
- struct list *lvh;
- struct logical_volume *lv;
+ struct lv_list *lvl;
struct dev_layer *dl;
- list_iterate(lvh, lvs) {
- lv = list_item(lvh, struct lv_list)->lv;
+ list_iterate_items(lvl, lvs) {
+ if (lvl->lv->status & SNAPSHOT)
+ continue;
- if (!(dl = _lookup(dm, lv->lvid.s, NULL))) {
+ if (!(dl = _lookup(dm, lvl->lv->lvid.s, NULL))) {
stack;
return 0;
}
@@ -1464,12 +1522,12 @@
static int _suspend_parents(struct dev_manager *dm, struct dev_layer *dl)
{
- struct list *sh;
+ struct str_list *strl;
struct dev_layer *dep;
const char *dlid;
- list_iterate(sh, &dl->pre_suspend) {
- dlid = list_item(sh, struct str_list)->str;
+ list_iterate_items(strl, &dl->pre_suspend) {
+ dlid = strl->str;
if (!(dep = hash_lookup(dm->layers, dlid))) {
log_debug("_suspend_parents couldn't find device "
@@ -1498,12 +1556,12 @@
static int _resume_with_deps(struct dev_manager *dm, struct dev_layer *dl)
{
- struct list *sh;
+ struct str_list *strl;
struct dev_layer *dep;
const char *dlid;
- list_iterate(sh, &dl->pre_create) {
- dlid = list_item(sh, struct str_list)->str;
+ list_iterate_items(strl, &dl->pre_create) {
+ dlid = strl->str;
if (!(dep = hash_lookup(dm->layers, dlid))) {
log_debug("_resume_with_deps couldn't find device "
@@ -1536,7 +1594,7 @@
*/
static int _create_rec(struct dev_manager *dm, struct dev_layer *dl)
{
- struct list *sh;
+ struct str_list *strl;
struct dev_layer *dep;
const char *dlid;
char *newname, *suffix;
@@ -1548,8 +1606,8 @@
return 0;
}
- list_iterate(sh, &dl->pre_create) {
- dlid = list_item(sh, struct str_list)->str;
+ list_iterate_items(strl, &dl->pre_create) {
+ dlid = strl->str;
if (!(dep = hash_lookup(dm->layers, dlid))) {
log_error("Couldn't find device layer '%s'.", dlid);
@@ -1605,15 +1663,15 @@
static int _build_all_layers(struct dev_manager *dm, struct volume_group *vg)
{
- struct list *lvh;
- struct logical_volume *lvt;
+ struct lv_list *lvl;
/*
* Build layers for complete vg.
*/
- list_iterate(lvh, &vg->lvs) {
- lvt = list_item(lvh, struct lv_list)->lv;
- if (!_expand_lv(dm, lvt)) {
+ list_iterate_items(lvl, &vg->lvs) {
+ if (lvl->lv->status & SNAPSHOT)
+ continue;
+ if (!_expand_lv(dm, lvl->lv)) {
stack;
return 0;
}
@@ -1653,15 +1711,15 @@
{
struct hash_node *hn;
struct dev_layer *dl;
- struct list *sh;
+ struct str_list *strl;
const char *dlid;
struct dev_layer *dep;
hash_iterate(hn, dm->layers) {
dl = hash_get_data(dm->layers, hn);
- list_iterate(sh, &dl->pre_suspend) {
- dlid = list_item(sh, struct str_list)->str;
+ list_iterate_items(strl, &dl->pre_suspend) {
+ dlid = strl->str;
if (!(dep = hash_lookup(dm->layers, dlid))) {
log_debug("_populate_pre_suspend_lists: "
@@ -1676,8 +1734,8 @@
}
}
- list_iterate(sh, &dl->pre_create) {
- dlid = list_item(sh, struct str_list)->str;
+ list_iterate_items(strl, &dl->pre_create) {
+ dlid = strl->str;
if (!(dep = hash_lookup(dm->layers, dlid))) {
log_debug("_populate_pre_suspend_lists: "
@@ -1702,6 +1760,7 @@
static int _remove_old_layers(struct dev_manager *dm)
{
int change;
+ struct dl_list *dll;
struct list *rh, *n;
struct dev_layer *dl;
@@ -1724,10 +1783,8 @@
} while (change);
if (!list_empty(&dm->remove_list)) {
- list_iterate(rh, &dm->remove_list) {
- dl = list_item(rh, struct dl_list)->dl;
- log_error("Couldn't deactivate device %s", dl->name);
- }
+ list_iterate_items(dll, &dm->remove_list)
+ log_error("Couldn't deactivate device %s", dll->dl->name);
return 0;
}
@@ -1914,14 +1971,14 @@
static int _add_lvs(struct pool *mem,
struct list *head, struct logical_volume *origin)
{
- struct logical_volume *lv;
- struct snapshot *s;
- struct list *lvh;
+ struct lv_segment *snap_seg;
+ struct lv_list *lvl;
- list_iterate(lvh, &origin->vg->lvs) {
- lv = list_item(lvh, struct lv_list)->lv;
- if ((s = find_cow(lv)) && s->origin == origin)
- if (!_add_lv(mem, head, lv))
+ list_iterate_items(lvl, &origin->vg->lvs) {
+ if (lvl->lv->status & SNAPSHOT)
+ continue;
+ if ((snap_seg = find_cow(lvl->lv)) && snap_seg->origin == origin)
+ if (!_add_lv(mem, head, lvl->lv))
return 0;
}
@@ -1930,13 +1987,11 @@
static void _remove_lv(struct list *head, struct logical_volume *lv)
{
- struct list *lvh;
struct lv_list *lvl;
- list_iterate(lvh, head) {
- lvl = list_item(lvh, struct lv_list);
+ list_iterate_items(lvl, head) {
if (lvl->lv == lv) {
- list_del(lvh);
+ list_del(&lvl->list);
break;
}
}
@@ -1945,30 +2000,32 @@
static int _remove_lvs(struct dev_manager *dm, struct logical_volume *lv)
{
struct logical_volume *active, *old_origin;
- struct snapshot *s;
- struct list *sh, *active_head;
+ struct lv_segment *snap_seg;
+ struct list *active_head;
+ struct lv_list *lvl;
active_head = &dm->active_list;
/* Remove any snapshots with given origin */
- list_iterate(sh, active_head) {
- active = list_item(sh, struct lv_list)->lv;
- if ((s = find_cow(active)) && s->origin == lv) {
+ list_iterate_items(lvl, active_head) {
+ active = lvl->lv;
+ if ((snap_seg = find_cow(active)) && snap_seg->origin == lv) {
_remove_lv(active_head, active);
}
}
_remove_lv(active_head, lv);
- if (!(s = find_cow(lv)))
+ if (!(snap_seg = find_cow(lv)))
return 1;
- old_origin = s->origin;
+ old_origin = snap_seg->origin;
/* Was this the last active snapshot with this origin? */
- list_iterate(sh, active_head) {
- active = list_item(sh, struct lv_list)->lv;
- if ((s = find_cow(active)) && s->origin == old_origin) {
+ list_iterate_items(lvl, active_head) {
+ active = lvl->lv;
+ if ((snap_seg = find_cow(active)) &&
+ snap_seg->origin == old_origin) {
return 1;
}
}
@@ -1980,15 +2037,17 @@
struct logical_volume *lv)
{
struct logical_volume *suspended;
- struct snapshot *s;
- struct list *sh, *suspend_head;
+ struct lv_segment *snap_seg;
+ struct list *suspend_head;
+ struct lv_list *lvl;
suspend_head = &dm->suspend_list;
/* Remove from list any snapshots with given origin */
- list_iterate(sh, suspend_head) {
- suspended = list_item(sh, struct lv_list)->lv;
- if ((s = find_cow(suspended)) && s->origin == lv) {
+ list_iterate_items(lvl, suspend_head) {
+ suspended = lvl->lv;
+ if ((snap_seg = find_cow(suspended)) &&
+ snap_seg->origin == lv) {
_remove_lv(suspend_head, suspended);
}
}
@@ -2001,13 +2060,13 @@
static int _targets_present(struct dev_manager *dm, struct list *lvs)
{
struct logical_volume *lv;
- struct list *lvh, *segh;
+ struct lv_list *lvl;
struct segment_type *segtype;
struct lv_segment *seg;
int snapshots = 0, mirrors = 0;
- list_iterate(lvh, lvs) {
- lv = list_item(lvh, struct lv_list)->lv;
+ list_iterate_items(lvl, lvs) {
+ lv = lvl->lv;
if (!snapshots)
if (lv_is_cow(lv) || lv_is_origin(lv))
@@ -2018,8 +2077,7 @@
mirrors = 1;
if (lv->status & VIRTUAL) {
- list_iterate(segh, &lv->segments) {
- seg = list_item(segh, struct lv_segment);
+ list_iterate_items(seg, &lv->segments) {
if (seg->segtype->ops->target_present &&
!seg->segtype->ops->target_present()) {
log_error("Can't expand LV: %s target "
@@ -2068,14 +2126,14 @@
static int _fill_in_active_list(struct dev_manager *dm, struct volume_group *vg)
{
char *dlid;
- struct list *lvh;
- struct logical_volume *lv;
+ struct lv_list *lvl;
struct dev_layer *dl;
- list_iterate(lvh, &vg->lvs) {
- lv = list_item(lvh, struct lv_list)->lv;
+ list_iterate_items(lvl, &vg->lvs) {
+ if (lvl->lv->status & SNAPSHOT)
+ continue;
- if (!(dlid = _build_dlid(dm->mem, lv->lvid.s, NULL))) {
+ if (!(dlid = _build_dlid(dm->mem, lvl->lv->lvid.s, NULL))) {
stack;
return 0;
}
@@ -2084,16 +2142,16 @@
pool_free(dm->mem, dlid);
if (dl) {
- log_debug("Found active lv %s%s", lv->name,
+ log_debug("Found active lv %s%s", lvl->lv->name,
dl->info.suspended ? " (suspended)" : "");
- if (!_add_lv(dm->mem, &dm->active_list, lv)) {
+ if (!_add_lv(dm->mem, &dm->active_list, lvl->lv)) {
stack;
return 0;
}
if (dl->info.suspended) {
- if (!_add_lv(dm->mem, &dm->suspend_list, lv)) {
+ if (!_add_lv(dm->mem, &dm->suspend_list, lvl->lv)) {
stack;
return 0;
}
Modified: lvm2/upstream/current/lib/activate/fs.c
==============================================================================
--- lvm2/upstream/current/lib/activate/fs.c (original)
+++ lvm2/upstream/current/lib/activate/fs.c Tue Jun 14 11:13:22 2005
@@ -65,7 +65,7 @@
return 0;
}
- if (is_empty_dir(vg_path)) {
+ if (dir_exists(vg_path) && is_empty_dir(vg_path)) {
log_very_verbose("Removing directory %s", vg_path);
rmdir(vg_path);
}
@@ -180,7 +180,7 @@
}
#ifdef HAVE_SELINUX
- if (!set_selinux_context(lv_path)) {
+ if (!set_selinux_context(lv_path, S_IFLNK)) {
stack;
return 0;
}
Modified: lvm2/upstream/current/lib/activate/targets.h
==============================================================================
--- lvm2/upstream/current/lib/activate/targets.h (original)
+++ lvm2/upstream/current/lib/activate/targets.h Tue Jun 14 11:13:22 2005
@@ -19,7 +19,12 @@
struct dev_manager;
struct lv_segment;
-int compose_areas_line(struct dev_manager *dm, struct lv_segment *seg, char *params, size_t paramsize, int *pos,
- int start_area, int areas);
+int compose_areas_line(struct dev_manager *dm, struct lv_segment *seg,
+ char *params, size_t paramsize, int *pos,
+ int start_area, int areas);
+
+int compose_log_line(struct dev_manager *dm, struct lv_segment *seg,
+ char *params, size_t paramsize, int *pos, int areas,
+ uint32_t region_size);
#endif
Modified: lvm2/upstream/current/lib/cache/lvmcache.c
==============================================================================
--- lvm2/upstream/current/lib/cache/lvmcache.c (original)
+++ lvm2/upstream/current/lib/cache/lvmcache.c Tue Jun 14 11:13:22 2005
@@ -104,10 +104,31 @@
const struct format_type *fmt_from_vgname(const char *vgname)
{
struct lvmcache_vginfo *vginfo;
+ struct lvmcache_info *info;
+ struct label *label;
+ struct list *devh, *tmp;
+ struct list devs;
+ struct device_list *devl;
if (!(vginfo = vginfo_from_vgname(vgname)))
return NULL;
+ /* This function is normally called before reading metadata so
+ * we check cached labels here. Unfortunately vginfo is volatile. */
+ list_init(&devs);
+ list_iterate_items(info, &vginfo->infos) {
+ devl = dbg_malloc(sizeof(*devl));
+ devl->dev = info->dev;
+ list_add(&devs, &devl->list);
+ }
+
+ list_iterate_safe(devh, tmp, &devs) {
+ devl = list_item(devh, struct device_list);
+ label_read(devl->dev, &label);
+ list_del(&devl->list);
+ dbg_free(devl);
+ }
+
return vginfo->fmt;
}
@@ -166,7 +187,6 @@
struct label *label;
struct dev_iter *iter;
struct device *dev;
- struct list *fmth;
struct format_type *fmt;
static int _scanning_in_progress = 0;
@@ -188,7 +208,7 @@
goto out;
}
- if (!(iter = dev_iter_create(cmd->filter))) {
+ if (!(iter = dev_iter_create(cmd->filter, (full_scan == 2) ? 1: 0))) {
log_error("dev_iter creation failed");
goto out;
}
@@ -201,8 +221,7 @@
_has_scanned = 1;
/* Perform any format-specific scanning e.g. text files */
- list_iterate(fmth, &cmd->formats) {
- fmt = list_item(fmth, struct format_type);
+ list_iterate_items(fmt, &cmd->formats) {
if (fmt->ops->scan && !fmt->ops->scan(fmt))
goto out;
}
@@ -266,7 +285,7 @@
if (memlock())
return NULL;
- lvmcache_label_scan(cmd, 1);
+ lvmcache_label_scan(cmd, 2);
/* Try again */
if ((info = info_from_pvid((char *) pvid))) {
@@ -403,23 +422,24 @@
/* FIXME Check consistency of list! */
vginfo->fmt = info->fmt;
+ log_debug("lvmcache: %s now %s%s", dev_name(info->dev),
+ *vgname ? "in VG " : "orphaned", vgname);
+
return 1;
}
int lvmcache_update_vg(struct volume_group *vg)
{
- struct list *pvh;
- struct physical_volume *pv;
+ struct pv_list *pvl;
struct lvmcache_info *info;
char pvid_s[ID_LEN + 1];
int vgid_updated = 0;
pvid_s[sizeof(pvid_s) - 1] = '\0';
- list_iterate(pvh, &vg->pvs) {
- pv = list_item(pvh, struct pv_list)->pv;
- strncpy(pvid_s, (char *) &pv->id, sizeof(pvid_s) - 1);
- /* FIXME Could pv->dev->pvid ever be different? */
+ list_iterate_items(pvl, &vg->pvs) {
+ strncpy(pvid_s, (char *) &pvl->pv->id, sizeof(pvid_s) - 1);
+ /* FIXME Could pvl->pv->dev->pvid ever be different? */
if ((info = info_from_pvid(pvid_s))) {
lvmcache_update_vgname(info, vg->name);
if (!vgid_updated) {
@@ -551,6 +571,8 @@
void lvmcache_destroy(void)
{
+ log_verbose("Wiping internal VG cache");
+
_has_scanned = 0;
if (_vgid_hash) {
Modified: lvm2/upstream/current/lib/cache/lvmcache.h
==============================================================================
--- lvm2/upstream/current/lib/cache/lvmcache.h (original)
+++ lvm2/upstream/current/lib/cache/lvmcache.h Tue Jun 14 11:13:22 2005
@@ -36,9 +36,10 @@
struct lvmcache_vginfo {
struct list list; /* Join these vginfos together */
struct list infos; /* List head for lvmcache_infos */
+ const struct format_type *fmt;
char *vgname; /* "" == orphan */
char vgid[ID_LEN + 1];
- const struct format_type *fmt;
+ char _padding[7];
};
struct lvmcache_info {
@@ -56,7 +57,8 @@
int lvmcache_init(void);
void lvmcache_destroy(void);
-/* Set full_scan to 1 to reread every filtered device label */
+/* Set full_scan to 1 to reread every filtered device label or
+ * 2 to rescan /dev for new devices */
int lvmcache_label_scan(struct cmd_context *cmd, int full_scan);
/* Add/delete a device */
Modified: lvm2/upstream/current/lib/commands/toolcontext.c
==============================================================================
--- lvm2/upstream/current/lib/commands/toolcontext.c (original)
+++ lvm2/upstream/current/lib/commands/toolcontext.c Tue Jun 14 11:13:22 2005
@@ -35,6 +35,8 @@
#include "str_list.h"
#include "segtype.h"
#include "lvmcache.h"
+#include "dev-cache.h"
+#include "archiver.h"
#ifdef HAVE_LIBDL
#include "sharedlib.h"
@@ -493,6 +495,24 @@
}
}
+ if (!(cn = find_config_node(cmd->cft->root, "devices/loopfiles")))
+ return 1;
+
+ for (cv = cn->v; cv; cv = cv->next) {
+ if (cv->type != CFG_STRING) {
+ log_error("Invalid string in config file: "
+ "devices/loopfiles");
+ return 0;
+ }
+
+ if (!dev_cache_add_loopfile(cv->v.str)) {
+ log_error("Failed to add loopfile %s to internal "
+ "device cache", cv->v.str);
+ return 0;
+ }
+ }
+
+
return 1;
}
@@ -602,7 +622,6 @@
const char *format;
struct format_type *fmt;
- struct list *fmth;
#ifdef HAVE_LIBDL
const struct config_node *cn;
@@ -669,8 +688,7 @@
format = find_config_str(cmd->cft->root, "global/format",
DEFAULT_FORMAT);
- list_iterate(fmth, &cmd->formats) {
- fmt = list_item(fmth, struct format_type);
+ list_iterate_items(fmt, &cmd->formats) {
if (!strcasecmp(fmt->name, format) ||
(fmt->alias && !strcasecmp(fmt->alias, format))) {
cmd->default_settings.fmt = fmt;
@@ -795,6 +813,69 @@
return 1;
}
+static int _init_backup(struct cmd_context *cmd)
+{
+ uint32_t days, min;
+ char default_dir[PATH_MAX];
+ const char *dir;
+
+ if (!cmd->sys_dir) {
+ log_warn("WARNING: Metadata changes will NOT be backed up");
+ backup_init(cmd, "");
+ archive_init(cmd, "", 0, 0);
+ return 1;
+ }
+
+ /* set up archiving */
+ cmd->default_settings.archive =
+ find_config_bool(cmd->cft->root, "backup/archive",
+ DEFAULT_ARCHIVE_ENABLED);
+
+ days = (uint32_t) find_config_int(cmd->cft->root, "backup/retain_days",
+ DEFAULT_ARCHIVE_DAYS);
+
+ min = (uint32_t) find_config_int(cmd->cft->root, "backup/retain_min",
+ DEFAULT_ARCHIVE_NUMBER);
+
+ if (lvm_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'.",
+ cmd->sys_dir, DEFAULT_ARCHIVE_SUBDIR);
+ return 0;
+ }
+
+ dir = find_config_str(cmd->cft->root, "backup/archive_dir",
+ default_dir);
+
+ if (!archive_init(cmd, dir, days, min)) {
+ log_debug("backup_init failed.");
+ return 0;
+ }
+
+ /* set up the backup */
+ cmd->default_settings.backup =
+ find_config_bool(cmd->cft->root, "backup/backup",
+ DEFAULT_BACKUP_ENABLED);
+
+ if (lvm_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'.",
+ cmd->sys_dir, DEFAULT_BACKUP_SUBDIR);
+ return 0;
+ }
+
+ dir = find_config_str(cmd->cft->root, "backup/backup_dir", default_dir);
+
+ if (!backup_init(cmd, dir)) {
+ log_debug("backup_init failed.");
+ return 0;
+ }
+
+ return 1;
+}
+
/* Entry point */
struct cmd_context *create_toolcontext(struct arg *the_args)
{
@@ -883,6 +964,9 @@
if (!_init_segtypes(cmd))
goto error;
+ if (!_init_backup(cmd))
+ goto error;
+
cmd->current_settings = cmd->default_settings;
cmd->config_valid = 1;
@@ -993,6 +1077,8 @@
if (cmd->dump_filter)
persistent_filter_dump(cmd->filter);
+ archive_exit(cmd);
+ backup_exit(cmd);
activation_exit();
lvmcache_destroy();
label_exit();
Modified: lvm2/upstream/current/lib/commands/toolcontext.h
==============================================================================
--- lvm2/upstream/current/lib/commands/toolcontext.h (original)
+++ lvm2/upstream/current/lib/commands/toolcontext.h Tue Jun 14 11:13:22 2005
@@ -32,20 +32,20 @@
int syslog;
int activation;
int suffix;
- uint64_t unit_factor;
- char unit_type;
- const char *msg_prefix;
- int cmd_name; /* Show command name? */
-
int archive; /* should we archive ? */
int backup; /* should we backup ? */
-
+ const char *msg_prefix;
struct format_type *fmt;
-
+ uint64_t unit_factor;
+ int cmd_name; /* Show command name? */
mode_t umask;
+ char unit_type;
+ char _padding[1];
};
struct config_tree;
+struct archive_params;
+struct backup_params;
/* FIXME Split into tool & library contexts */
/* command-instance-related variables needed by library */
@@ -75,6 +75,9 @@
struct config_info default_settings;
struct config_info current_settings;
+ struct archive_params *archive_params;
+ struct backup_params *backup_params;
+
/* List of defined tags */
struct list tags;
int hosttags;
Modified: lvm2/upstream/current/lib/config/config.c
==============================================================================
--- lvm2/upstream/current/lib/config/config.c (original)
+++ lvm2/upstream/current/lib/config/config.c Tue Jun 14 11:13:22 2005
@@ -235,7 +235,7 @@
return 1;
}
- if (!(dev = dev_create_file(c->filename, NULL, NULL))) {
+ if (!(dev = dev_create_file(c->filename, NULL, NULL, 1))) {
stack;
return 0;
}
Modified: lvm2/upstream/current/lib/config/defaults.h
==============================================================================
--- lvm2/upstream/current/lib/config/defaults.h (original)
+++ lvm2/upstream/current/lib/config/defaults.h Tue Jun 14 11:13:22 2005
@@ -91,19 +91,22 @@
#define DEFAULT_REP_HEADINGS 1
#define DEFAULT_REP_SEPARATOR " "
-#define DEFAULT_LVS_COLS "lv_name,vg_name,lv_attr,lv_size,origin,snap_percent,move_pv,copy_percent"
+#define DEFAULT_LVS_COLS "lv_name,vg_name,lv_attr,lv_size,origin,snap_percent,move_pv,mirror_log,copy_percent"
#define DEFAULT_VGS_COLS "vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free"
#define DEFAULT_PVS_COLS "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free"
#define DEFAULT_SEGS_COLS "lv_name,vg_name,lv_attr,stripes,segtype,seg_size"
+#define DEFAULT_PVSEGS_COLS "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"
-#define DEFAULT_LVS_COLS_VERB "lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,lv_kernel_major,lv_kernel_minor,origin,snap_percent,move_pv,copy_percent,lv_uuid"
+#define DEFAULT_LVS_COLS_VERB "lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,lv_kernel_major,lv_kernel_minor,origin,snap_percent,move_pv,copy_percent,mirror_log,lv_uuid"
#define DEFAULT_VGS_COLS_VERB "vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid"
#define DEFAULT_PVS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,dev_size,pv_uuid"
#define DEFAULT_SEGS_COLS_VERB "lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize"
+#define DEFAULT_PVSEGS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"
#define DEFAULT_LVS_SORT "vg_name,lv_name"
#define DEFAULT_VGS_SORT "vg_name"
#define DEFAULT_PVS_SORT "pv_name"
#define DEFAULT_SEGS_SORT "vg_name,lv_name,seg_start"
+#define DEFAULT_PVSEGS_SORT "pv_name,pvseg_start"
#endif /* _LVM_DEFAULTS_H */
Modified: lvm2/upstream/current/lib/datastruct/list.h
==============================================================================
--- lvm2/upstream/current/lib/datastruct/list.h (original)
+++ lvm2/upstream/current/lib/datastruct/list.h Tue Jun 14 11:13:22 2005
@@ -18,17 +18,30 @@
#include <assert.h>
+/*
+ * A list consists of a list head plus elements.
+ * Each element has 'next' and 'previous' pointers.
+ * The list head's pointers point to the first and the last element.
+ */
+
struct list {
struct list *n, *p;
};
+/*
+ * Initialise a list before use.
+ * The list head's next and previous pointers point back to itself.
+ */
#define LIST_INIT(name) struct list name = { &(name), &(name) }
-
static inline void list_init(struct list *head)
{
head->n = head->p = head;
}
+/*
+ * Insert an element before 'head'.
+ * If 'head' is the list head, this adds an element to the end of the list.
+ */
static inline void list_add(struct list *head, struct list *elem)
{
assert(head->n);
@@ -40,6 +53,10 @@
head->p = elem;
}
+/*
+ * Insert an element after 'head'.
+ * If 'head' is the list head, this adds an element to the front of the list.
+ */
static inline void list_add_h(struct list *head, struct list *elem)
{
assert(head->n);
@@ -51,53 +68,162 @@
head->n = elem;
}
+/*
+ * Delete an element from its list.
+ * Note that this doesn't change the element itself - it may still be safe
+ * to follow its pointers.
+ */
static inline void list_del(struct list *elem)
{
elem->n->p = elem->p;
elem->p->n = elem->n;
}
+/*
+ * Is the list empty?
+ */
static inline int list_empty(struct list *head)
{
return head->n == head;
}
+/*
+ * Is this the first element of the list?
+ */
+static inline int list_start(struct list *head, struct list *elem)
+{
+ return elem->p == head;
+}
+
+/*
+ * Is this the last element of the list?
+ */
static inline int list_end(struct list *head, struct list *elem)
{
return elem->n == head;
}
-static inline struct list *list_next(struct list *head, struct list *elem)
+/*
+ * Return first element of the list or NULL if empty
+ */
+static inline struct list *list_first(struct list *head)
{
- return (list_end(head, elem) ? NULL : elem->n);
+ return (list_empty(head) ? NULL : head->n);
}
-#define list_item(v, t) \
- ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->list))
+/*
+ * Return last element of the list or NULL if empty
+ */
+static inline struct list *list_last(struct list *head)
+{
+ return (list_empty(head) ? NULL : head->p);
+}
-#define list_struct_base(v, t, h) \
- ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->h))
+/*
+ * Return the previous element of the list, or NULL if we've reached the start.
+ */
+static inline struct list *list_prev(struct list *head, struct list *elem)
+{
+ return (list_start(head, elem) ? NULL : elem->p);
+}
+
+/*
+ * Return the next element of the list, or NULL if we've reached the end.
+ */
+static inline struct list *list_next(struct list *head, struct list *elem)
+{
+ return (list_end(head, elem) ? NULL : elem->n);
+}
-/* Given a known element in a known structure, locate another */
+/*
+ * Given the address v of an instance of 'struct list' called 'head'
+ * contained in a structure of type t, return the containing structure.
+ */
+#define list_struct_base(v, t, head) \
+ ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->head))
+
+/*
+ * Given the address v of an instance of 'struct list list' contained in
+ * a structure of type t, return the containing structure.
+ */
+#define list_item(v, t) list_struct_base((v), t, list)
+
+/*
+ * Given the address v of one known element e in a known structure of type t,
+ * return another element f.
+ */
#define struct_field(v, t, e, f) \
(((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->e))->f)
-/* Given a known element in a known structure, locate the list head */
+/*
+ * Given the address v of a known element e in a known structure of type t,
+ * return the list head 'list'
+ */
#define list_head(v, t, e) struct_field(v, t, e, list)
+/*
+ * Set v to each element of a list in turn.
+ */
#define list_iterate(v, head) \
for (v = (head)->n; v != head; v = v->n)
+/*
+ * Set v to each element in a list in turn, starting from the element
+ * in front of 'start'.
+ * You can use this to 'unwind' a list_iterate and back out actions on
+ * already-processed elements.
+ * If 'start' is 'head' it walks the list backwards.
+ */
#define list_uniterate(v, head, start) \
for (v = (start)->p; v != head; v = v->p)
+/*
+ * A safe way to walk a list and delete and free some elements along
+ * the way.
+ * t must be defined as a temporary variable of the same type as v.
+ */
#define list_iterate_safe(v, t, head) \
for (v = (head)->n, t = v->n; v != head; v = t, t = v->n)
-#define list_iterate_items(v, head) \
- for (v = list_item((head)->n, typeof(*v)); &v->list != (head); \
- v = list_item(v->list.n, typeof(*v)))
-
+/*
+ * Walk a list, setting 'v' in turn to the containing structure of each item.
+ * The containing structure should be the same type as 'v'.
+ * The 'struct list' variable within the containing structure is 'field'.
+ */
+#define list_iterate_items_gen(v, head, field) \
+ for (v = list_struct_base((head)->n, typeof(*v), field); \
+ &v->field != (head); \
+ v = list_struct_base(v->field.n, typeof(*v), field))
+
+/*
+ * Walk a list, setting 'v' in turn to the containing structure of each item.
+ * The containing structure should be the same type as 'v'.
+ * The list should be 'struct list list' within the containing structure.
+ */
+#define list_iterate_items(v, head) list_iterate_items_gen(v, (head), list)
+
+/*
+ * Walk a list backwards, setting 'v' in turn to the containing structure
+ * of each item.
+ * The containing structure should be the same type as 'v'.
+ * The 'struct list' variable within the containing structure is 'field'.
+ */
+#define list_iterate_back_items_gen(v, head, field) \
+ for (v = list_struct_base((head)->p, typeof(*v), field); \
+ &v->field != (head); \
+ v = list_struct_base(v->field.p, typeof(*v), field))
+
+/*
+ * Walk a list backwards, setting 'v' in turn to the containing structure
+ * of each item.
+ * The containing structure should be the same type as 'v'.
+ * The list should be 'struct list list' within the containing structure.
+ */
+#define list_iterate_back_items(v, head) list_iterate_back_items_gen(v, (head), list)
+
+/*
+ * Return the number of elements in a list by walking it.
+ */
static inline unsigned int list_size(const struct list *head)
{
unsigned int s = 0;
Modified: lvm2/upstream/current/lib/datastruct/lvm-types.h
==============================================================================
--- lvm2/upstream/current/lib/datastruct/lvm-types.h (original)
+++ lvm2/upstream/current/lib/datastruct/lvm-types.h Tue Jun 14 11:13:22 2005
@@ -22,7 +22,7 @@
#include <inttypes.h>
/* Define some portable printing types */
-#define PRIsize_t "Zu"
+#define PRIsize_t "zu"
struct str_list {
struct list list;
Modified: lvm2/upstream/current/lib/device/dev-cache.c
==============================================================================
--- lvm2/upstream/current/lib/device/dev-cache.c (original)
+++ lvm2/upstream/current/lib/device/dev-cache.c Tue Jun 14 11:13:22 2005
@@ -21,6 +21,7 @@
#include "lvm-types.h"
#include "btree.h"
#include "filter.h"
+#include "filter-persistent.h"
#include <unistd.h>
#include <sys/param.h>
@@ -43,39 +44,60 @@
int has_scanned;
struct list dirs;
+ struct list files;
} _cache;
-#define _alloc(x) pool_alloc(_cache.mem, (x))
+#define _alloc(x) pool_zalloc(_cache.mem, (x))
#define _free(x) pool_free(_cache.mem, (x))
+#define _strdup(x) pool_strdup(_cache.mem, (x))
static int _insert(const char *path, int rec);
struct device *dev_create_file(const char *filename, struct device *dev,
- struct str_list *alias)
+ struct str_list *alias, int use_malloc)
{
int allocate = !dev;
- if (allocate && !(dev = dbg_malloc(sizeof(*dev)))) {
- log_error("struct device allocation failed");
- return NULL;
- }
- if (allocate && !(alias = dbg_malloc(sizeof(*alias)))) {
- log_error("struct str_list allocation failed");
- dbg_free(dev);
- return NULL;
- }
- if (!(alias->str = dbg_strdup(filename))) {
- log_error("filename strdup failed");
- if (allocate) {
- dbg_free(dev);
- dbg_free(alias);
+ if (allocate) {
+ if (use_malloc) {
+ if (!(dev = dbg_malloc(sizeof(*dev)))) {
+ log_error("struct device allocation failed");
+ return NULL;
+ }
+ if (!(alias = dbg_malloc(sizeof(*alias)))) {
+ log_error("struct str_list allocation failed");
+ dbg_free(dev);
+ return NULL;
+ }
+ if (!(alias->str = dbg_strdup(filename))) {
+ log_error("filename strdup failed");
+ dbg_free(dev);
+ dbg_free(alias);
+ return NULL;
+ }
+ dev->flags = DEV_ALLOCED;
+ } else {
+ if (!(dev = _alloc(sizeof(*dev)))) {
+ log_error("struct device allocation failed");
+ return NULL;
+ }
+ if (!(alias = _alloc(sizeof(*alias)))) {
+ log_error("struct str_list allocation failed");
+ _free(dev);
+ return NULL;
+ }
+ if (!(alias->str = _strdup(filename))) {
+ log_error("filename strdup failed");
+ return NULL;
+ }
}
+ } else if (!(alias->str = dbg_strdup(filename))) {
+ log_error("filename strdup failed");
return NULL;
}
- dev->flags = DEV_REGULAR;
- if (allocate)
- dev->flags |= DEV_ALLOCED;
+
+ dev->flags |= DEV_REGULAR;
list_init(&dev->aliases);
list_add(&dev->aliases, &alias->list);
dev->end = UINT64_C(0);
@@ -174,7 +196,7 @@
static int _add_alias(struct device *dev, const char *path)
{
struct str_list *sl = _alloc(sizeof(*sl));
- struct list *ah;
+ struct str_list *strl;
const char *oldpath;
int prefer_old = 1;
@@ -184,9 +206,9 @@
}
/* Is name already there? */
- list_iterate(ah, &dev->aliases) {
- if (!strcmp(list_item(ah, struct str_list)->str, path)) {
- stack;
+ list_iterate_items(strl, &dev->aliases) {
+ if (!strcmp(strl->str, path)) {
+ log_debug("%s: Already in device cache", path);
return 1;
}
}
@@ -220,12 +242,25 @@
static int _insert_dev(const char *path, dev_t d)
{
struct device *dev;
+ static dev_t loopfile_count = 0;
+ int loopfile = 0;
+
+ /* Generate pretend device numbers for loopfiles */
+ if (!d) {
+ d = ++loopfile_count;
+ loopfile = 1;
+ }
/* is this device already registered ? */
if (!(dev = (struct device *) btree_lookup(_cache.devices,
(uint32_t) d))) {
/* create new device */
- if (!(dev = _dev_create(d))) {
+ if (loopfile) {
+ if (!(dev = dev_create_file(path, NULL, NULL, 0))) {
+ stack;
+ return 0;
+ }
+ } else if (!(dev = _dev_create(d))) {
stack;
return 0;
}
@@ -237,7 +272,7 @@
}
}
- if (!_add_alias(dev, path)) {
+ if (!loopfile && !_add_alias(dev, path)) {
log_err("Couldn't add alias to dev cache.");
return 0;
}
@@ -313,6 +348,28 @@
return r;
}
+static int _insert_file(const char *path)
+{
+ struct stat info;
+
+ if (stat(path, &info) < 0) {
+ log_sys_very_verbose("stat", path);
+ return 0;
+ }
+
+ if (!S_ISREG(info.st_mode)) {
+ log_debug("%s: Not a regular file", path);
+ return 0;
+ }
+
+ if (!_insert_dev(path, 0)) {
+ stack;
+ return 0;
+ }
+
+ return 1;
+}
+
static int _insert(const char *path, int rec)
{
struct stat info;
@@ -355,19 +412,21 @@
return r;
}
-static void _full_scan(void)
+static void _full_scan(int dev_scan)
{
- struct list *dh;
+ struct dir_list *dl;
- if (_cache.has_scanned)
+ if (_cache.has_scanned && !dev_scan)
return;
- list_iterate(dh, &_cache.dirs) {
- struct dir_list *dl = list_item(dh, struct dir_list);
+ list_iterate_items(dl, &_cache.dirs)
_insert_dir(dl->dir);
- };
+
+ list_iterate_items(dl, &_cache.files)
+ _insert_file(dl->dir);
_cache.has_scanned = 1;
+ init_full_scan_done(1);
}
int dev_cache_has_scanned(void)
@@ -379,15 +438,14 @@
{
if (!do_scan)
_cache.has_scanned = 1;
- else {
- _cache.has_scanned = 0;
- _full_scan();
- }
+ else
+ _full_scan(1);
}
int dev_cache_init(void)
{
_cache.names = NULL;
+ _cache.has_scanned = 0;
if (!(_cache.mem = pool_create("dev_cache", 10 * 1024))) {
stack;
@@ -407,6 +465,7 @@
}
list_init(&_cache.dirs);
+ list_init(&_cache.files);
return 1;
@@ -444,6 +503,7 @@
_cache.devices = NULL;
_cache.has_scanned = 0;
list_init(&_cache.dirs);
+ list_init(&_cache.files);
}
int dev_cache_add_dir(const char *path)
@@ -472,6 +532,32 @@
return 1;
}
+int dev_cache_add_loopfile(const char *path)
+{
+ struct dir_list *dl;
+ struct stat st;
+
+ if (stat(path, &st)) {
+ log_error("Ignoring %s: %s", path, strerror(errno));
+ /* But don't fail */
+ return 1;
+ }
+
+ if (!S_ISREG(st.st_mode)) {
+ log_error("Ignoring %s: Not a regular file", path);
+ return 1;
+ }
+
+ if (!(dl = _alloc(sizeof(*dl) + strlen(path) + 1))) {
+ log_error("dir_list allocation failed for file");
+ return 0;
+ }
+
+ strcpy(dl->dir, path);
+ list_add(&_cache.files, &dl->list);
+ return 1;
+}
+
/* Check cached device name is still valid before returning it */
/* This should be a rare occurrence */
/* set quiet if the cache is expected to be out-of-date */
@@ -482,6 +568,9 @@
const char *name;
int r;
+ if ((dev->flags & DEV_REGULAR))
+ return dev_name(dev);
+
while ((r = stat(name = list_item(dev->aliases.n,
struct str_list)->str, &buf)) ||
(buf.st_rdev != dev->dev)) {
@@ -526,6 +615,9 @@
struct stat buf;
struct device *d = (struct device *) hash_lookup(_cache.names, name);
+ if (d && (d->flags & DEV_REGULAR))
+ return d;
+
/* If the entry's wrong, remove it */
if (d && (stat(name, &buf) || (buf.st_rdev != d->dev))) {
hash_remove(_cache.names, name);
@@ -537,10 +629,11 @@
d = (struct device *) hash_lookup(_cache.names, name);
}
- return (d && (!f || f->passes_filter(f, d))) ? d : NULL;
+ return (d && (!f || (d->flags & DEV_REGULAR) ||
+ f->passes_filter(f, d))) ? d : NULL;
}
-struct dev_iter *dev_iter_create(struct dev_filter *f)
+struct dev_iter *dev_iter_create(struct dev_filter *f, int dev_scan)
{
struct dev_iter *di = dbg_malloc(sizeof(*di));
@@ -549,7 +642,14 @@
return NULL;
}
- _full_scan();
+
+ if (dev_scan) {
+ /* Flag gets reset between each command */
+ if (!full_scan_done())
+ persistent_filter_wipe(f); /* Calls _full_scan(1) */
+ } else
+ _full_scan(0);
+
di->current = btree_first(_cache.devices);
di->filter = f;
@@ -572,7 +672,7 @@
{
while (iter->current) {
struct device *d = _iter_next(iter);
- if (!iter->filter ||
+ if (!iter->filter || (d->flags & DEV_REGULAR) ||
iter->filter->passes_filter(iter->filter, d))
return d;
}
Modified: lvm2/upstream/current/lib/device/dev-cache.h
==============================================================================
--- lvm2/upstream/current/lib/device/dev-cache.h (original)
+++ lvm2/upstream/current/lib/device/dev-cache.h Tue Jun 14 11:13:22 2005
@@ -39,13 +39,14 @@
int dev_cache_has_scanned(void);
int dev_cache_add_dir(const char *path);
+int dev_cache_add_loopfile(const char *path);
struct device *dev_cache_get(const char *name, struct dev_filter *f);
/*
* Object for iterating through the cache.
*/
struct dev_iter;
-struct dev_iter *dev_iter_create(struct dev_filter *f);
+struct dev_iter *dev_iter_create(struct dev_filter *f, int dev_scan);
void dev_iter_destroy(struct dev_iter *iter);
struct device *dev_iter_get(struct dev_iter *iter);
Modified: lvm2/upstream/current/lib/device/dev-io.c
==============================================================================
--- lvm2/upstream/current/lib/device/dev-io.c (original)
+++ lvm2/upstream/current/lib/device/dev-io.c Tue Jun 14 11:13:22 2005
@@ -222,11 +222,25 @@
return 1;
}
-/*-----------------------------------------------------------------
- * Public functions
- *---------------------------------------------------------------*/
+static int _dev_get_size_file(const struct device *dev, uint64_t *size)
+{
+ const char *name = dev_name(dev);
+ struct stat info;
-int dev_get_size(const struct device *dev, uint64_t *size)
+ if (stat(name, &info)) {
+ log_sys_error("stat", name);
+ return 0;
+ }
+
+ *size = info.st_size;
+ *size >>= SECTOR_SHIFT; /* Convert to sectors */
+
+ log_very_verbose("%s: size is %" PRIu64 " sectors", name, *size);
+
+ return 1;
+}
+
+static int _dev_get_size_dev(const struct device *dev, uint64_t *size)
{
int fd;
const char *name = dev_name(dev);
@@ -252,6 +266,18 @@
return 1;
}
+/*-----------------------------------------------------------------
+ * Public functions
+ *---------------------------------------------------------------*/
+
+int dev_get_size(const struct device *dev, uint64_t *size)
+{
+ if ((dev->flags & DEV_REGULAR))
+ return _dev_get_size_file(dev, size);
+ else
+ return _dev_get_size_dev(dev, size);
+}
+
/* FIXME Unused
int dev_get_sectsize(struct device *dev, uint32_t *size)
{
@@ -330,8 +356,13 @@
}
#ifdef O_DIRECT_SUPPORT
- if (direct)
- flags |= O_DIRECT;
+ if (direct) {
+ if (!(dev->flags & DEV_O_DIRECT_TESTED))
+ dev->flags |= DEV_O_DIRECT;
+
+ if ((dev->flags & DEV_O_DIRECT))
+ flags |= O_DIRECT;
+ }
#endif
#ifdef O_NOATIME
@@ -341,12 +372,31 @@
#endif
if ((dev->fd = open(name, flags, 0777)) < 0) {
- log_sys_error("open", name);
+#ifdef O_DIRECT_SUPPORT
+ if (direct && !(dev->flags & DEV_O_DIRECT_TESTED)) {
+ flags &= ~O_DIRECT;
+ if ((dev->fd = open(name, flags, 0777)) >= 0) {
+ dev->flags &= ~DEV_O_DIRECT;
+ log_debug("%s: Not using O_DIRECT", name);
+ goto opened;
+ }
+ }
+#endif
+ if (quiet)
+ log_sys_debug("open", name);
+ else
+ log_sys_error("open", name);
return 0;
}
+#ifdef O_DIRECT_SUPPORT
+ opened:
+ if (direct)
+ dev->flags |= DEV_O_DIRECT_TESTED;
+#endif
dev->open_count++;
dev->flags &= ~DEV_ACCESSED_W;
+
if ((flags & O_ACCMODE) == O_RDWR)
dev->flags |= DEV_OPENED_RW;
else
@@ -370,8 +420,9 @@
list_add(&_open_devices, &dev->open_list);
- log_debug("Opened %s %s", dev_name(dev),
- dev->flags & DEV_OPENED_RW ? "RW" : "RO");
+ log_debug("Opened %s %s%s", dev_name(dev),
+ dev->flags & DEV_OPENED_RW ? "RW" : "RO",
+ dev->flags & DEV_O_DIRECT ? " O_DIRECT" : "");
return 1;
}
Modified: lvm2/upstream/current/lib/device/device.h
==============================================================================
--- lvm2/upstream/current/lib/device/device.h (original)
+++ lvm2/upstream/current/lib/device/device.h Tue Jun 14 11:13:22 2005
@@ -23,6 +23,8 @@
#define DEV_REGULAR 0x00000002 /* Regular file? */
#define DEV_ALLOCED 0x00000004 /* dbg_malloc used */
#define DEV_OPENED_RW 0x00000008 /* Opened RW */
+#define DEV_O_DIRECT 0x00000010 /* Use O_DIRECT */
+#define DEV_O_DIRECT_TESTED 0x00000020 /* DEV_O_DIRECT is reliable */
/*
* All devices in LVM will be represented by one of these.
@@ -41,6 +43,7 @@
struct list open_list;
char pvid[ID_LEN + 1];
+ char _padding[7];
};
struct device_list {
@@ -63,7 +66,7 @@
/* Use quiet version if device number could change e.g. when opening LV */
int dev_open(struct device *dev);
int dev_open_quiet(struct device *dev);
-int dev_open_flags(struct device *dev, int flags, int append, int quiet);
+int dev_open_flags(struct device *dev, int flags, int direct, int quiet);
int dev_close(struct device *dev);
int dev_close_immediate(struct device *dev);
void dev_close_all(void);
@@ -80,7 +83,7 @@
void dev_flush(struct device *dev);
struct device *dev_create_file(const char *filename, struct device *dev,
- struct str_list *alias);
+ struct str_list *alias, int use_malloc);
static inline const char *dev_name(const struct device *dev)
{
Modified: lvm2/upstream/current/lib/display/display.c
==============================================================================
--- lvm2/upstream/current/lib/display/display.c (original)
+++ lvm2/upstream/current/lib/display/display.c Tue Jun 14 11:13:22 2005
@@ -337,10 +337,9 @@
void *handle)
{
struct lvinfo info;
- int inkernel, snap_active;
+ int inkernel, snap_active = 0;
char uuid[64];
- struct snapshot *snap = NULL;
- struct list *slh, *snaplist;
+ struct lv_segment *snap_seg = NULL;
float snap_percent; /* fused, fsize; */
if (!id_write_format(&lv->lvid.id[1], uuid, sizeof(uuid))) {
@@ -364,27 +363,30 @@
if (lv_is_origin(lv)) {
log_print("LV snapshot status source of");
- snaplist = find_snapshots(lv);
- list_iterate(slh, snaplist) {
- snap = list_item(slh, struct snapshot_list)->snapshot;
- snap_active = lv_snapshot_percent(snap->cow,
- &snap_percent);
- if (!snap_active || snap_percent < 0 ||
- snap_percent >= 100) snap_active = 0;
+ list_iterate_items_gen(snap_seg, &lv->snapshot_segs,
+ origin_list) {
+ if (inkernel &&
+ (snap_active = lv_snapshot_percent(snap_seg->cow,
+ &snap_percent)))
+ if (snap_percent < 0 || snap_percent >= 100)
+ snap_active = 0;
log_print(" %s%s/%s [%s]",
lv->vg->cmd->dev_dir, lv->vg->name,
- snap->cow->name,
+ snap_seg->cow->name,
(snap_active > 0) ? "active" : "INACTIVE");
}
- snap = NULL;
- } else if ((snap = find_cow(lv))) {
- snap_active = lv_snapshot_percent(lv, &snap_percent);
- if (!snap_active || snap_percent < 0 || snap_percent >= 100)
- snap_active = 0;
+ snap_seg = NULL;
+ } else if ((snap_seg = find_cow(lv))) {
+ if (inkernel &&
+ (snap_active = lv_snapshot_percent(snap_seg->cow,
+ &snap_percent)))
+ if (snap_percent < 0 || snap_percent >= 100)
+ snap_active = 0;
+
log_print("LV snapshot status %s destination for %s%s/%s",
(snap_active > 0) ? "active" : "INACTIVE",
lv->vg->cmd->dev_dir, lv->vg->name,
- snap->origin->name);
+ snap_seg->origin->name);
}
if (inkernel && info.suspended)
@@ -402,15 +404,24 @@
log_print("LV Size %s",
display_size(cmd,
- snap ? snap->origin->size : lv->size,
+ snap_seg ? snap_seg->origin->size : lv->size,
SIZE_SHORT));
log_print("Current LE %u",
- snap ? snap->origin->le_count : lv->le_count);
+ snap_seg ? snap_seg->origin->le_count : lv->le_count);
+
+ if (snap_seg) {
+ log_print("COW-table size %s",
+ display_size(cmd, (uint64_t) lv->size, SIZE_SHORT));
+ log_print("COW-table LE %u", lv->le_count);
+
+ if (snap_active)
+ log_print("Allocated to snapshot %.2f%% ", snap_percent);
-/********** FIXME allocation
- log_print("Allocated LE %u", lv->allocated_le);
-**********/
+ log_print("Snapshot chunk size %s",
+ display_size(cmd, (uint64_t) snap_seg->chunk_size,
+ SIZE_SHORT));
+ }
log_print("Segments %u", list_size(&lv->segments));
@@ -418,31 +429,6 @@
log_print("Stripe size (KByte) %u", lv->stripesize / 2);
***********/
- if (snap) {
- if (snap_percent == -1)
- snap_percent = 100;
-
- log_print("Snapshot chunk size %s",
- display_size(cmd, (uint64_t) snap->chunk_size,
- SIZE_SHORT));
-
-/*
- size = display_size(lv->size, SIZE_SHORT);
- sscanf(size, "%f", &fsize);
- fused = fsize * snap_percent / 100;
-*/
- log_print("Allocated to snapshot %.2f%% ", /* [%.2f/%s]", */
- snap_percent); /*, fused, size); */
- /* dbg_free(size); */
- }
-
-/********** FIXME Snapshot
- size = ???
- log_print("Allocated to COW-table %s", size);
- dbg_free(size);
- }
-******************/
-
log_print("Allocation %s", get_alloc_string(lv->alloc));
log_print("Read ahead sectors %u", lv->read_ahead);
@@ -463,26 +449,28 @@
void display_stripe(const struct lv_segment *seg, uint32_t s, const char *pre)
{
- switch (seg->area[s].type) {
+ switch (seg_type(seg, s)) {
case AREA_PV:
+ /* FIXME Re-check the conditions for 'Missing' */
log_print("%sPhysical volume\t%s", pre,
- seg->area[s].u.pv.pv ?
- dev_name(seg->area[s].u.pv.pv->dev) : "Missing");
+ seg_pv(seg, s) ?
+ dev_name(seg_dev(seg, s)) :
+ "Missing");
- if (seg->area[s].u.pv.pv)
+ if (seg_pv(seg, s))
log_print("%sPhysical extents\t%d to %d", pre,
- seg->area[s].u.pv.pe,
- seg->area[s].u.pv.pe + seg->area_len - 1);
+ seg_pe(seg, s),
+ seg_pe(seg, s) + seg->area_len - 1);
break;
case AREA_LV:
log_print("%sLogical volume\t%s", pre,
- seg->area[s].u.lv.lv ?
- seg->area[s].u.lv.lv->name : "Missing");
+ seg_lv(seg, s) ?
+ seg_lv(seg, s)->name : "Missing");
- if (seg->area[s].u.lv.lv)
+ if (seg_lv(seg, s))
log_print("%sLogical extents\t%d to %d", pre,
- seg->area[s].u.lv.le,
- seg->area[s].u.lv.le + seg->area_len - 1);
+ seg_le(seg, s),
+ seg_le(seg, s) + seg->area_len - 1);
}
}
@@ -550,7 +538,7 @@
vg->status & SHARED ? "yes" : "no");
}
log_print("MAX LV %u", vg->max_lv);
- log_print("Cur LV %u", vg->lv_count);
+ log_print("Cur LV %u", vg->lv_count + vg->snapshot_count);
log_print("Open LV %u", lvs_in_vg_opened(vg));
/****** FIXME Max LV Size
log_print ( "MAX LV Size %s",
Modified: lvm2/upstream/current/lib/filters/filter-persistent.c
==============================================================================
--- lvm2/upstream/current/lib/filters/filter-persistent.c (original)
+++ lvm2/upstream/current/lib/filters/filter-persistent.c Tue Jun 14 11:13:22 2005
@@ -53,7 +53,9 @@
{
struct pfilter *pf = (struct pfilter *) f->private;
+ log_verbose("Wiping cache of LVM-capable devices");
hash_wipe(pf->devices);
+
/* Trigger complete device scan */
dev_cache_scan(1);
@@ -202,16 +204,14 @@
struct pfilter *pf = (struct pfilter *) f->private;
void *l = hash_lookup(pf->devices, dev_name(dev));
struct str_list *sl;
- struct list *ah;
if (!l) {
l = pf->real->passes_filter(pf->real, dev) ?
PF_GOOD_DEVICE : PF_BAD_DEVICE;
- list_iterate(ah, &dev->aliases) {
- sl = list_item(ah, struct str_list);
+ list_iterate_items(sl, &dev->aliases)
hash_insert(pf->devices, sl->str, l);
- }
+
} else if (l == PF_BAD_DEVICE)
log_debug("%s: Skipping (cached)", dev_name(dev));
Modified: lvm2/upstream/current/lib/filters/filter-regex.c
==============================================================================
--- lvm2/upstream/current/lib/filters/filter-regex.c (original)
+++ lvm2/upstream/current/lib/filters/filter-regex.c Tue Jun 14 11:13:22 2005
@@ -158,13 +158,11 @@
static int _accept_p(struct dev_filter *f, struct device *dev)
{
- struct list *ah;
int m, first = 1, rejected = 0;
struct rfilter *rf = (struct rfilter *) f->private;
struct str_list *sl;
- list_iterate(ah, &dev->aliases) {
- sl = list_item(ah, struct str_list);
+ list_iterate_items(sl, &dev->aliases) {
m = matcher_run(rf->engine, sl->str);
if (m >= 0) {
Modified: lvm2/upstream/current/lib/filters/filter-sysfs.c
==============================================================================
--- lvm2/upstream/current/lib/filters/filter-sysfs.c (original)
+++ lvm2/upstream/current/lib/filters/filter-sysfs.c Tue Jun 14 11:13:22 2005
@@ -172,7 +172,7 @@
unsigned char dtype;
struct stat info;
char path[PATH_MAX];
- dev_t dev;
+ dev_t dev = { 0 };
int r = 1;
if (!(dr = opendir(dir))) {
Modified: lvm2/upstream/current/lib/filters/filter.c
==============================================================================
--- lvm2/upstream/current/lib/filters/filter.c (original)
+++ lvm2/upstream/current/lib/filters/filter.c Tue Jun 14 11:13:22 2005
@@ -70,6 +70,7 @@
{"i2o_block", 16}, /* i2o Block Disk */
{"iseries/vd", 8}, /* iSeries disks */
{"gnbd", 1}, /* Network block device */
+ {"ramdisk", 1}, /* RAM disk */
{NULL, 0}
};
@@ -88,7 +89,7 @@
}
/* Check it's accessible */
- if (!dev_open_flags(dev, O_RDONLY, 0, 0)) {
+ if (!dev_open_flags(dev, O_RDONLY, 0, 1)) {
log_debug("%s: Skipping: open failed", name);
return 0;
}
Modified: lvm2/upstream/current/lib/format1/disk-rep.c
==============================================================================
--- lvm2/upstream/current/lib/format1/disk-rep.c (original)
+++ lvm2/upstream/current/lib/format1/disk-rep.c Tue Jun 14 11:13:22 2005
@@ -424,11 +424,11 @@
static void _add_pv_to_list(struct list *head, struct disk_list *data)
{
- struct list *pvdh;
struct pv_disk *pvd;
+ struct disk_list *diskl;
- list_iterate(pvdh, head) {
- pvd = &list_item(pvdh, struct disk_list)->pvd;
+ list_iterate_items(diskl, head) {
+ pvd = &diskl->pvd;
if (!strncmp(data->pvd.pv_uuid, pvd->pv_uuid,
sizeof(pvd->pv_uuid))) {
if (MAJOR(data->dev->dev) != md_major()) {
@@ -439,7 +439,7 @@
}
log_very_verbose("Duplicate PV %s - using md %s",
pvd->pv_uuid, dev_name(data->dev));
- list_del(pvdh);
+ list_del(&diskl->list);
break;
}
}
@@ -458,14 +458,14 @@
struct dev_iter *iter;
struct device *dev;
struct disk_list *data = NULL;
- struct list *vgih;
struct lvmcache_vginfo *vginfo;
+ struct lvmcache_info *info;
/* Fast path if we already saw this VG and cached the list of PVs */
if (vg_name && (vginfo = vginfo_from_vgname(vg_name)) &&
vginfo->infos.n) {
- list_iterate(vgih, &vginfo->infos) {
- dev = list_item(vgih, struct lvmcache_info)->dev;
+ list_iterate_items(info, &vginfo->infos) {
+ dev = info->dev;
if (dev && !(data = read_disk(fmt, dev, mem, vg_name)))
break;
_add_pv_to_list(head, data);
@@ -482,7 +482,7 @@
/* vgcache_del(vg_name); */
}
- if (!(iter = dev_iter_create(filter))) {
+ if (!(iter = dev_iter_create(filter, 1))) {
log_error("read_pvs_in_vg: dev_iter_create failed");
return 0;
}
@@ -518,18 +518,16 @@
static int _write_uuids(struct disk_list *data)
{
struct uuid_list *ul;
- struct list *uh;
uint64_t pos = data->pvd.pv_uuidlist_on_disk.base;
uint64_t end = pos + data->pvd.pv_uuidlist_on_disk.size;
- list_iterate(uh, &data->uuids) {
+ list_iterate_items(ul, &data->uuids) {
if (pos >= end) {
log_error("Too many uuids to fit on %s",
dev_name(data->dev));
return 0;
}
- ul = list_item(uh, struct uuid_list);
if (!dev_write(data->dev, pos, NAME_LEN, ul->uuid))
fail;
@@ -552,7 +550,7 @@
static int _write_lvs(struct disk_list *data)
{
- struct list *lvh;
+ struct lvd_list *ll;
uint64_t pos, offset;
pos = data->pvd.lv_on_disk.base;
@@ -563,9 +561,7 @@
return 0;
}
- list_iterate(lvh, &data->lvds) {
- struct lvd_list *ll = list_item(lvh, struct lvd_list);
-
+ list_iterate_items(ll, &data->lvds) {
offset = sizeof(struct lv_disk) * ll->lvd.lv_number;
if (offset + sizeof(struct lv_disk) > data->pvd.lv_on_disk.size) {
log_error("lv_number %d too large", ll->lvd.lv_number);
@@ -704,11 +700,9 @@
*/
int write_disks(const struct format_type *fmt, struct list *pvs)
{
- struct list *pvh;
struct disk_list *dl;
- list_iterate(pvh, pvs) {
- dl = list_item(pvh, struct disk_list);
+ list_iterate_items(dl, pvs) {
if (!(_write_all_pvd(fmt, dl)))
fail;
Modified: lvm2/upstream/current/lib/format1/format1.c
==============================================================================
--- lvm2/upstream/current/lib/format1/format1.c (original)
+++ lvm2/upstream/current/lib/format1/format1.c Tue Jun 14 11:13:22 2005
@@ -46,9 +46,7 @@
* This means an active VG won't be affected if disks are inserted
* bearing an exported VG with the same name.
*/
- list_iterate(pvh, pvs) {
- dl = list_item(pvh, struct disk_list);
-
+ list_iterate_items(dl, pvs) {
if (first_time) {
exported = dl->pvd.pv_status & VG_EXPORTED;
first_time = 0;
@@ -148,7 +146,6 @@
vg->seqno = 0;
list_init(&vg->pvs);
list_init(&vg->lvs);
- list_init(&vg->snapshots);
list_init(&vg->tags);
if (!_check_vgs(pvs, &partial))
@@ -247,13 +244,10 @@
struct list *pvds, const char *dev_dir,
struct dev_filter *filter)
{
- struct list *pvh;
struct pv_list *pvl;
struct disk_list *data;
- list_iterate(pvh, &vg->pvs) {
- pvl = list_item(pvh, struct pv_list);
-
+ list_iterate_items(pvl, &vg->pvs) {
if (!(data = _flatten_pv(fid, mem, vg, pvl->pv, dev_dir))) {
stack;
return 0;
Modified: lvm2/upstream/current/lib/format1/import-export.c
==============================================================================
--- lvm2/upstream/current/lib/format1/import-export.c (original)
+++ lvm2/upstream/current/lib/format1/import-export.c Tue Jun 14 11:13:22 2005
@@ -26,6 +26,7 @@
#include "filter.h"
#include "toolcontext.h"
#include "segtype.h"
+#include "pv_alloc.h"
#include <time.h>
@@ -86,9 +87,15 @@
pv->pe_size = pvd->pe_size;
pv->pe_start = pvd->pe_start;
pv->pe_count = pvd->pe_total;
- pv->pe_alloc_count = pvd->pe_allocated;
+ pv->pe_alloc_count = 0;
list_init(&pv->tags);
+ list_init(&pv->segments);
+
+ if (!alloc_pv_segment_whole_pv(mem, pv)) {
+ stack;
+ return 0;
+ }
return 1;
}
@@ -323,6 +330,8 @@
lv->size = lvd->lv_size;
lv->le_count = lvd->lv_allocated_le;
+ lv->snapshot = NULL;
+ list_init(&lv->snapshot_segs);
list_init(&lv->segments);
list_init(&lv->tags);
@@ -373,14 +382,11 @@
int export_extents(struct disk_list *dl, uint32_t lv_num,
struct logical_volume *lv, struct physical_volume *pv)
{
- struct list *segh;
struct pe_disk *ped;
struct lv_segment *seg;
uint32_t pe, s;
- list_iterate(segh, &lv->segments) {
- seg = list_item(segh, struct lv_segment);
-
+ list_iterate_items(seg, &lv->segments) {
for (s = 0; s < seg->area_count; s++) {
if (!(seg->segtype->flags & SEG_FORMAT1_SUPPORT)) {
log_error("Segment type %s in LV %s: "
@@ -388,16 +394,16 @@
seg->segtype->name, lv->name);
return 0;
}
- if (seg->area[s].type != AREA_PV) {
+ if (seg_type(seg, s) != AREA_PV) {
log_error("LV stripe found in LV %s: "
"unsupported by format1", lv->name);
return 0;
}
- if (seg->area[s].u.pv.pv != pv)
+ if (seg_pv(seg, s) != pv)
continue; /* not our pv */
for (pe = 0; pe < (seg->len / seg->area_count); pe++) {
- ped = &dl->extents[pe + seg->area[s].u.pv.pe];
+ ped = &dl->extents[pe + seg_pe(seg, s)];
ped->lv_num = lv_num;
ped->le_num = (seg->le / seg->area_count) + pe +
s * (lv->le_count / seg->area_count);
@@ -412,15 +418,11 @@
struct volume_group *vg,
struct list *pvds, struct list *results, int *count)
{
- struct list *pvdh;
struct disk_list *dl;
struct pv_list *pvl;
*count = 0;
- list_iterate(pvdh, pvds) {
-
- dl = list_item(pvdh, struct disk_list);
-
+ list_iterate_items(dl, pvds) {
if (!(pvl = pool_zalloc(mem, sizeof(*pvl))) ||
!(pvl->pv = pool_alloc(mem, sizeof(*pvl->pv)))) {
stack;
@@ -471,12 +473,9 @@
struct disk_list *dl;
struct lvd_list *ll;
struct lv_disk *lvd;
- struct list *pvdh, *lvdh;
- list_iterate(pvdh, pvds) {
- dl = list_item(pvdh, struct disk_list);
- list_iterate(lvdh, &dl->lvds) {
- ll = list_item(lvdh, struct lvd_list);
+ list_iterate_items(dl, pvds) {
+ list_iterate_items(ll, &dl->lvds) {
lvd = &ll->lvd;
if (!find_lv(vg, lvd->lv_name) &&
@@ -495,7 +494,6 @@
struct physical_volume *pv, const char *dev_dir)
{
int r = 0;
- struct list *lvh, *sh;
struct lv_list *ll;
struct lvd_list *lvdl;
size_t len;
@@ -522,8 +520,10 @@
}
memset(dl->extents, 0, len);
- list_iterate(lvh, &vg->lvs) {
- ll = list_item(lvh, struct lv_list);
+ list_iterate_items(ll, &vg->lvs) {
+ if (ll->lv->status & SNAPSHOT)
+ continue;
+
if (!(lvdl = pool_alloc(dl->mem, sizeof(*lvdl)))) {
stack;
goto out;
@@ -532,7 +532,6 @@
_export_lv(&lvdl->lvd, vg, ll->lv, dev_dir);
lv_num = lvnum_from_lvid(&ll->lv->lvid);
-
lvdl->lvd.lv_number = lv_num;
if (!hash_insert(lvd_hash, ll->lv->name, &lvdl->lvd)) {
@@ -545,35 +544,18 @@
goto out;
}
- list_add(&dl->lvds, &lvdl->list);
- dl->pvd.lv_cur++;
- }
+ if (lv_is_origin(ll->lv))
+ lvdl->lvd.lv_access |= LV_SNAPSHOT_ORG;
- /*
- * Now we need to run through the snapshots, exporting
- * the SNAPSHOT_ORG flags etc.
- */
- list_iterate(sh, &vg->snapshots) {
- struct lv_disk *org, *cow;
- struct snapshot *s = list_item(sh,
- struct snapshot_list)->snapshot;
-
- if (!(org = hash_lookup(lvd_hash, s->origin->name))) {
- log_err("Couldn't find snapshot origin '%s'.",
- s->origin->name);
- goto out;
+ if (lv_is_cow(ll->lv)) {
+ lvdl->lvd.lv_access |= LV_SNAPSHOT;
+ lvdl->lvd.lv_chunk_size = ll->lv->snapshot->chunk_size;
+ lvdl->lvd.lv_snapshot_minor =
+ lvnum_from_lvid(&ll->lv->snapshot->origin->lvid);
}
- if (!(cow = hash_lookup(lvd_hash, s->cow->name))) {
- log_err("Couldn't find snapshot cow store '%s'.",
- s->cow->name);
- goto out;
- }
-
- org->lv_access |= LV_SNAPSHOT_ORG;
- cow->lv_access |= LV_SNAPSHOT;
- cow->lv_snapshot_minor = org->lv_number;
- cow->lv_chunk_size = s->chunk_size;
+ list_add(&dl->lvds, &lvdl->list);
+ dl->pvd.lv_cur++;
}
r = 1;
@@ -590,19 +572,17 @@
struct list *pvds)
{
struct logical_volume *lvs[MAX_LV];
- struct list *pvdh, *lvdh;
struct disk_list *dl;
+ struct lvd_list *ll;
struct lv_disk *lvd;
int lvnum;
struct logical_volume *org, *cow;
/* build an index of lv numbers */
memset(lvs, 0, sizeof(lvs));
- list_iterate(pvdh, pvds) {
- dl = list_item(pvdh, struct disk_list);
-
- list_iterate(lvdh, &dl->lvds) {
- lvd = &(list_item(lvdh, struct lvd_list)->lvd);
+ list_iterate_items(dl, pvds) {
+ list_iterate_items(ll, &dl->lvds) {
+ lvd = &ll->lvd;
lvnum = lvd->lv_number;
@@ -624,11 +604,9 @@
/*
* Now iterate through yet again adding the snapshots.
*/
- list_iterate(pvdh, pvds) {
- dl = list_item(pvdh, struct disk_list);
-
- list_iterate(lvdh, &dl->lvds) {
- lvd = &(list_item(lvdh, struct lvd_list)->lvd);
+ list_iterate_items(dl, pvds) {
+ list_iterate_items(ll, &dl->lvds) {
+ lvd = &ll->lvd;
if (!(lvd->lv_access & LV_SNAPSHOT))
continue;
@@ -646,7 +624,8 @@
continue;
/* insert the snapshot */
- if (!vg_add_snapshot(org, cow, 1, NULL, org->le_count,
+ if (!vg_add_snapshot(vg->fid, NULL, org, cow, NULL,
+ org->le_count,
lvd->lv_chunk_size)) {
log_err("Couldn't add snapshot.");
return 0;
@@ -661,10 +640,8 @@
{
struct uuid_list *ul;
struct pv_list *pvl;
- struct list *pvh;
- list_iterate(pvh, &vg->pvs) {
- pvl = list_item(pvh, struct pv_list);
+ list_iterate_items(pvl, &vg->pvs) {
if (!(ul = pool_alloc(dl->mem, sizeof(*ul)))) {
stack;
return 0;
@@ -684,14 +661,11 @@
*/
void export_numbers(struct list *pvds, struct volume_group *vg)
{
- struct list *pvdh;
struct disk_list *dl;
int pv_num = 1;
- list_iterate(pvdh, pvds) {
- dl = list_item(pvdh, struct disk_list);
+ list_iterate_items(dl, pvds)
dl->pvd.pv_number = pv_num++;
- }
}
/*
@@ -699,26 +673,20 @@
*/
void export_pv_act(struct list *pvds)
{
- struct list *pvdh;
struct disk_list *dl;
int act = 0;
- list_iterate(pvdh, pvds) {
- dl = list_item(pvdh, struct disk_list);
+ list_iterate_items(dl, pvds)
if (dl->pvd.pv_status & PV_ACTIVE)
act++;
- }
- list_iterate(pvdh, pvds) {
- dl = list_item(pvdh, struct disk_list);
+ list_iterate_items(dl, pvds)
dl->vgd.pv_act = act;
- }
}
int export_vg_number(struct format_instance *fid, struct list *pvds,
const char *vg_name, struct dev_filter *filter)
{
- struct list *pvdh;
struct disk_list *dl;
int vg_num;
@@ -727,10 +695,8 @@
return 0;
}
- list_iterate(pvdh, pvds) {
- dl = list_item(pvdh, struct disk_list);
+ list_iterate_items(dl, pvds)
dl->vgd.vg_number = vg_num;
- }
return 1;
}
Modified: lvm2/upstream/current/lib/format1/import-extents.c
==============================================================================
--- lvm2/upstream/current/lib/format1/import-extents.c (original)
+++ lvm2/upstream/current/lib/format1/import-extents.c Tue Jun 14 11:13:22 2005
@@ -48,7 +48,6 @@
struct volume_group *vg)
{
struct hash_table *maps = hash_create(32);
- struct list *llh;
struct lv_list *ll;
struct lv_map *lvm;
@@ -58,8 +57,9 @@
return NULL;
}
- list_iterate(llh, &vg->lvs) {
- ll = list_item(llh, struct lv_list);
+ list_iterate_items(ll, &vg->lvs) {
+ if (ll->lv->status & SNAPSHOT)
+ continue;
if (!(lvm = pool_alloc(mem, sizeof(*lvm)))) {
stack;
@@ -89,13 +89,12 @@
static int _fill_lv_array(struct lv_map **lvs,
struct hash_table *maps, struct disk_list *dl)
{
- struct list *lvh;
+ struct lvd_list *ll;
struct lv_map *lvm;
memset(lvs, 0, sizeof(*lvs) * MAX_LV);
- list_iterate(lvh, &dl->lvds) {
- struct lvd_list *ll = list_item(lvh, struct lvd_list);
+ list_iterate_items(ll, &dl->lvds) {
if (!(lvm = hash_lookup(maps, strrchr(ll->lvd.lv_name, '/')
+ 1))) {
log_err("Physical volume (%s) contains an "
@@ -116,15 +115,13 @@
static int _fill_maps(struct hash_table *maps, struct volume_group *vg,
struct list *pvds)
{
- struct list *pvdh;
struct disk_list *dl;
struct physical_volume *pv;
struct lv_map *lvms[MAX_LV], *lvm;
struct pe_disk *e;
uint32_t i, lv_num, le;
- list_iterate(pvdh, pvds) {
- dl = list_item(pvdh, struct disk_list);
+ list_iterate_items(dl, pvds) {
pv = find_pv(vg, dl->dev);
e = dl->extents;
@@ -205,58 +202,59 @@
static int _read_linear(struct cmd_context *cmd, struct lv_map *lvm)
{
- uint32_t le = 0;
+ uint32_t le = 0, len;
struct lv_segment *seg;
+ struct segment_type *segtype;
+
+ if (!(segtype = get_segtype_from_string(cmd, "striped"))) {
+ stack;
+ return 0;
+ }
while (le < lvm->lv->le_count) {
- seg = alloc_lv_segment(cmd->mem, 1);
+ len = 0;
- seg->lv = lvm->lv;
- if (!(seg->segtype = get_segtype_from_string(cmd, "striped"))) {
+ do
+ len++;
+ while ((lvm->map[le + len].pv == lvm->map[le].pv) &&
+ (lvm->map[le].pv &&
+ lvm->map[le + len].pe == lvm->map[le].pe + len));
+
+ if (!(seg = alloc_lv_segment(cmd->mem, segtype, lvm->lv, le,
+ len, 0, 0, NULL, 1, len, 0, 0, 0))) {
+ log_error("Failed to allocate linear segment.");
+ return 0;
+ }
+
+ if (!set_lv_segment_area_pv(seg, 0, lvm->map[le].pv,
+ lvm->map[le].pe)) {
stack;
return 0;
}
- seg->le = le;
- seg->len = 0;
- seg->area_len = 0;
- seg->stripe_size = 0;
-
- seg->area[0].type = AREA_PV;
- seg->area[0].u.pv.pv = lvm->map[le].pv;
- seg->area[0].u.pv.pe = lvm->map[le].pe;
-
- do {
- seg->len++;
- seg->area_len++;
- } while ((lvm->map[le + seg->len].pv == seg->area[0].u.pv.pv) &&
- (seg->area[0].u.pv.pv &&
- lvm->map[le + seg->len].pe == seg->area[0].u.pv.pe +
- seg->len));
+ list_add(&lvm->lv->segments, &seg->list);
le += seg->len;
-
- list_add(&lvm->lv->segments, &seg->list);
}
return 1;
}
-static int _check_stripe(struct lv_map *lvm, struct lv_segment *seg,
- uint32_t base_le, uint32_t len)
+static int _check_stripe(struct lv_map *lvm, uint32_t area_count,
+ uint32_t seg_len, uint32_t base_le, uint32_t len)
{
- uint32_t le, st;
-
- le = base_le + seg->len;
+ uint32_t st;
/*
* Is the next physical extent in every stripe adjacent to the last?
*/
- for (st = 0; st < seg->area_count; st++)
- if ((lvm->map[le + st * len].pv != seg->area[st].u.pv.pv) ||
- (seg->area[st].u.pv.pv &&
- lvm->map[le + st * len].pe !=
- seg->area[st].u.pv.pe + seg->len)) return 0;
+ for (st = 0; st < area_count; st++)
+ if ((lvm->map[base_le + st * len + seg_len].pv !=
+ lvm->map[base_le + st * len].pv) ||
+ (lvm->map[base_le + st * len].pv &&
+ lvm->map[base_le + st * len + seg_len].pe !=
+ lvm->map[base_le + st * len].pe + seg_len))
+ return 0;
return 1;
}
@@ -264,7 +262,9 @@
static int _read_stripes(struct cmd_context *cmd, struct lv_map *lvm)
{
uint32_t st, le = 0, len;
+ uint32_t area_len;
struct lv_segment *seg;
+ struct segment_type *segtype;
/*
* Work out overall striped length
@@ -276,43 +276,46 @@
}
len = lvm->lv->le_count / lvm->stripes;
+ if (!(segtype = get_segtype_from_string(cmd, "striped"))) {
+ stack;
+ return 0;
+ }
+
while (le < len) {
- if (!(seg = alloc_lv_segment(cmd->mem, lvm->stripes))) {
- stack;
- return 0;
- }
+ area_len = 1;
- seg->lv = lvm->lv;
- if (!(seg->segtype = get_segtype_from_string(cmd, "striped"))) {
- stack;
+ /*
+ * Find how many blocks are contiguous in all stripes
+ * and so can form part of this segment
+ */
+ while (_check_stripe(lvm, lvm->stripes,
+ area_len * lvm->stripes, le, len))
+ area_len++;
+
+ if (!(seg = alloc_lv_segment(cmd->mem, segtype, lvm->lv,
+ lvm->stripes * le,
+ lvm->stripes * area_len,
+ 0, lvm->stripe_size, NULL,
+ lvm->stripes,
+ area_len, 0, 0, 0))) {
+ log_error("Failed to allocate striped segment.");
return 0;
}
- seg->stripe_size = lvm->stripe_size;
- seg->le = seg->area_count * le;
- seg->len = 1;
- seg->area_len = 1;
/*
* Set up start positions of each stripe in this segment
*/
- for (st = 0; st < seg->area_count; st++) {
- seg->area[st].u.pv.pv = lvm->map[le + st * len].pv;
- seg->area[st].u.pv.pe = lvm->map[le + st * len].pe;
- }
+ for (st = 0; st < seg->area_count; st++)
+ if (!set_lv_segment_area_pv(seg, st,
+ lvm->map[le + st * len].pv,
+ lvm->map[le + st * len].pe)) {
+ stack;
+ return 0;
+ }
- /*
- * Find how many blocks are contiguous in all stripes
- * and so can form part of this segment
- */
- while (_check_stripe(lvm, seg, le, len)) {
- seg->len++;
- seg->area_len++;
- }
+ list_add(&lvm->lv->segments, &seg->list);
le += seg->len;
- seg->len *= seg->area_count;
-
- list_add(&lvm->lv->segments, &seg->list);
}
return 1;
Modified: lvm2/upstream/current/lib/format1/vg_number.c
==============================================================================
--- lvm2/upstream/current/lib/format1/vg_number.c (original)
+++ lvm2/upstream/current/lib/format1/vg_number.c Tue Jun 14 11:13:22 2005
@@ -27,7 +27,6 @@
int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,
const char *candidate_vg, int *result)
{
- struct list *pvh;
struct list all_pvs;
struct disk_list *dl;
struct pool *mem = pool_create("lvm1 vg_number", 10 * 1024);
@@ -47,8 +46,7 @@
memset(numbers, 0, sizeof(numbers));
- list_iterate(pvh, &all_pvs) {
- dl = list_item(pvh, struct disk_list);
+ list_iterate_items(dl, &all_pvs) {
if (!*dl->pvd.vg_name || !strcmp(dl->pvd.vg_name, candidate_vg))
continue;
Modified: lvm2/upstream/current/lib/format_pool/disk_rep.c
==============================================================================
--- lvm2/upstream/current/lib/format_pool/disk_rep.c (original)
+++ lvm2/upstream/current/lib/format_pool/disk_rep.c Tue Jun 14 11:13:22 2005
@@ -57,12 +57,9 @@
static void _add_pl_to_list(struct list *head, struct pool_list *data)
{
- struct list *pvdh;
struct pool_list *pl;
- list_iterate(pvdh, head) {
- pl = list_item(pvdh, struct pool_list);
-
+ list_iterate_items(pl, head) {
if (id_equal(&data->pv_uuid, &pl->pv_uuid)) {
char uuid[ID_LEN + 7];
@@ -76,7 +73,7 @@
}
log_very_verbose("Duplicate PV %s - using md %s",
uuid, dev_name(data->dev));
- list_del(pvdh);
+ list_del(&pl->list);
break;
}
}
@@ -247,11 +244,9 @@
struct lvmcache_vginfo *vginfo, struct list *head,
uint32_t *devcount)
{
-
- struct list *vgih = NULL;
- struct device *dev;
- struct pool_list *pl = NULL;
- struct pool *tmpmem = NULL;
+ struct lvmcache_info *info;
+ struct pool_list *pl;
+ struct pool *tmpmem;
uint32_t sp_count = 0;
uint32_t *sp_devs = NULL;
@@ -264,16 +259,16 @@
return 0;
}
- list_iterate(vgih, &vginfo->infos) {
- dev = list_item(vgih, struct lvmcache_info)->dev;
- if (dev &&
- !(pl = read_pool_disk(fmt, dev, mem, vginfo->vgname)))
+ list_iterate_items(info, &vginfo->infos) {
+ if (info->dev &&
+ !(pl = read_pool_disk(fmt, info->dev, mem, vginfo->vgname)))
break;
/*
* We need to keep track of the total expected number
* of devices per subpool
*/
if (!sp_count) {
+ /* FIXME pl left uninitialised if !info->dev */
sp_count = pl->pd.pl_subpools;
if (!(sp_devs =
pool_zalloc(tmpmem,
@@ -298,9 +293,8 @@
}
*devcount = 0;
- for (i = 0; i < sp_count; i++) {
+ for (i = 0; i < sp_count; i++)
*devcount += sp_devs[i];
- }
pool_destroy(tmpmem);
Modified: lvm2/upstream/current/lib/format_pool/format_pool.c
==============================================================================
--- lvm2/upstream/current/lib/format_pool/format_pool.c (original)
+++ lvm2/upstream/current/lib/format_pool/format_pool.c Tue Jun 14 11:13:22 2005
@@ -33,8 +33,6 @@
static struct user_subpool *_build_usp(struct list *pls, struct pool *mem,
int *sps)
{
-
- struct list *plhs;
struct pool_list *pl;
struct user_subpool *usp = NULL, *cur_sp = NULL;
struct user_device *cur_dev = NULL;
@@ -43,9 +41,7 @@
* FIXME: Need to do some checks here - I'm tempted to add a
* user_pool structure and build the entire thing to check against.
*/
- list_iterate(plhs, pls) {
- pl = list_item(plhs, struct pool_list);
-
+ list_iterate_items(pl, pls) {
*sps = pl->pd.pl_subpools;
if (!usp && (!(usp = pool_zalloc(mem, sizeof(*usp) * (*sps))))) {
log_error("Unable to allocate %d subpool structures",
@@ -72,13 +68,13 @@
"structures", pl->pd.pl_sp_devs);
return 0;
}
+
cur_dev = &cur_sp->devs[pl->pd.pl_sp_devid];
cur_dev->sp_id = cur_sp->id;
cur_dev->devid = pl->pd.pl_sp_id;
cur_dev->blocks = pl->pd.pl_blocks;
cur_dev->pv = pl->pv;
cur_dev->initialized = 1;
-
}
return usp;
@@ -132,7 +128,6 @@
vg->system_id = NULL;
list_init(&vg->pvs);
list_init(&vg->lvs);
- list_init(&vg->snapshots);
list_init(&vg->tags);
if (!import_pool_vg(vg, smem, pds)) {
Modified: lvm2/upstream/current/lib/format_pool/import_export.c
==============================================================================
--- lvm2/upstream/current/lib/format_pool/import_export.c (original)
+++ lvm2/upstream/current/lib/format_pool/import_export.c Tue Jun 14 11:13:22 2005
@@ -21,6 +21,7 @@
#include "disk_rep.h"
#include "sptype_names.h"
#include "lv_alloc.h"
+#include "pv_alloc.h"
#include "str_list.h"
#include "display.h"
#include "segtype.h"
@@ -29,12 +30,9 @@
int import_pool_vg(struct volume_group *vg, struct pool *mem, struct list *pls)
{
- struct list *plhs;
struct pool_list *pl;
- list_iterate(plhs, pls) {
- pl = list_item(plhs, struct pool_list);
-
+ list_iterate_items(pl, pls) {
vg->extent_count +=
((pl->pd.pl_blocks) / POOL_PE_SIZE);
@@ -60,7 +58,6 @@
int import_pool_lvs(struct volume_group *vg, struct pool *mem, struct list *pls)
{
struct pool_list *pl;
- struct list *plhs;
struct lv_list *lvl = pool_zalloc(mem, sizeof(*lvl));
struct logical_volume *lv;
@@ -82,12 +79,12 @@
lv->name = NULL;
lv->le_count = 0;
lv->read_ahead = 0;
+ lv->snapshot = NULL;
+ list_init(&lv->snapshot_segs);
list_init(&lv->segments);
list_init(&lv->tags);
- list_iterate(plhs, pls) {
- pl = list_item(plhs, struct pool_list);
-
+ list_iterate_items(pl, pls) {
lv->size += pl->pd.pl_blocks;
if (lv->name)
@@ -112,6 +109,8 @@
} else {
lv->minor = -1;
}
+ lv->snapshot = NULL;
+ list_init(&lv->snapshot_segs);
list_init(&lv->segments);
list_init(&lv->tags);
}
@@ -129,11 +128,8 @@
{
struct pv_list *pvl;
struct pool_list *pl;
- struct list *plhs;
-
- list_iterate(plhs, pls) {
- pl = list_item(plhs, struct pool_list);
+ list_iterate_items(pl, pls) {
if (!(pvl = pool_zalloc(mem, sizeof(*pvl)))) {
log_error("Unable to allocate pv list structure");
return 0;
@@ -175,9 +171,15 @@
pv->pe_size = POOL_PE_SIZE;
pv->pe_start = POOL_PE_START;
pv->pe_count = pv->size / POOL_PE_SIZE;
- pv->pe_alloc_count = pv->pe_count;
+ pv->pe_alloc_count = 0;
list_init(&pv->tags);
+ list_init(&pv->segments);
+
+ if (!alloc_pv_segment_whole_pv(mem, pv)) {
+ stack;
+ return 0;
+ }
return 1;
}
@@ -200,40 +202,44 @@
uint32_t *le_cur)
{
struct lv_segment *seg;
+ struct segment_type *segtype;
int j;
+ uint32_t area_len;
- if (!(seg = alloc_lv_segment(mem, usp->num_devs))) {
- log_error("Unable to allocate striped lv_segment structure");
+ if (usp->striping & (usp->striping - 1)) {
+ log_error("Stripe size must be a power of 2");
return 0;
}
- if(usp->striping & (usp->striping - 1)) {
- log_error("Stripe size must be a power of 2");
+
+ area_len = (usp->devs[0].blocks) / POOL_PE_SIZE;
+
+ if (!(segtype = get_segtype_from_string(lv->vg->cmd,
+ "striped"))) {
+ stack;
return 0;
}
- seg->stripe_size = usp->striping;
- seg->status |= 0;
- seg->le += *le_cur;
- /* add the subpool type to the segment tag list */
- str_list_add(mem, &seg->tags, _cvt_sptype(usp->type));
+ if (!(seg = alloc_lv_segment(mem, segtype, lv, *le_cur,
+ area_len * usp->num_devs, 0,
+ usp->striping, NULL, usp->num_devs,
+ area_len, 0, 0, 0))) {
+ log_error("Unable to allocate striped lv_segment structure");
+ return 0;
+ }
- for (j = 0; j < usp->num_devs; j++) {
- if (!(seg->segtype = get_segtype_from_string(lv->vg->cmd,
- "striped"))) {
+ for (j = 0; j < usp->num_devs; j++)
+ if (!set_lv_segment_area_pv(seg, j, usp->devs[j].pv, 0)) {
stack;
return 0;
}
- seg->area_len = (usp->devs[j].blocks) / POOL_PE_SIZE;
- seg->len += seg->area_len;
- *le_cur += seg->area_len;
- seg->lv = lv;
-
- seg->area[j].type = AREA_PV;
- seg->area[j].u.pv.pv = usp->devs[j].pv;
- seg->area[j].u.pv.pe = 0;
- }
+ /* add the subpool type to the segment tag list */
+ str_list_add(mem, &seg->tags, _cvt_sptype(usp->type));
+
list_add(&lv->segments, &seg->list);
+
+ *le_cur += seg->len;
+
return 1;
}
@@ -242,54 +248,56 @@
uint32_t *le_cur)
{
struct lv_segment *seg;
+ struct segment_type *segtype;
int j;
+ uint32_t area_len;
+
+ if (!(segtype = get_segtype_from_string(lv->vg->cmd, "striped"))) {
+ stack;
+ return 0;
+ }
for (j = 0; j < usp->num_devs; j++) {
- /* linear segments only have 1 data area */
- if (!(seg = alloc_lv_segment(mem, 1))) {
+ area_len = (usp->devs[j].blocks) / POOL_PE_SIZE;
+
+ if (!(seg = alloc_lv_segment(mem, segtype, lv, *le_cur,
+ area_len, 0, usp->striping,
+ NULL, 1, area_len,
+ POOL_PE_SIZE, 0, 0))) {
log_error("Unable to allocate linear lv_segment "
"structure");
return 0;
}
- seg->stripe_size = usp->striping;
- seg->le += *le_cur;
- seg->chunk_size = POOL_PE_SIZE;
- seg->status |= 0;
- if (!(seg->segtype = get_segtype_from_string(lv->vg->cmd,
- "striped"))) {
- stack;
- return 0;
- }
+
/* add the subpool type to the segment tag list */
str_list_add(mem, &seg->tags, _cvt_sptype(usp->type));
- seg->lv = lv;
+ if (!set_lv_segment_area_pv(seg, 0, usp->devs[j].pv, 0)) {
+ stack;
+ return 0;
+ }
+ list_add(&lv->segments, &seg->list);
- seg->area_len = (usp->devs[j].blocks) / POOL_PE_SIZE;
- seg->len = seg->area_len;
*le_cur += seg->len;
- seg->area[0].type = AREA_PV;
- seg->area[0].u.pv.pv = usp->devs[j].pv;
- seg->area[0].u.pv.pe = 0;
- list_add(&lv->segments, &seg->list);
}
+
return 1;
}
int import_pool_segments(struct list *lvs, struct pool *mem,
struct user_subpool *usp, int subpools)
{
-
- struct list *lvhs;
struct lv_list *lvl;
struct logical_volume *lv;
uint32_t le_cur = 0;
int i;
- list_iterate(lvhs, lvs) {
- lvl = list_item(lvhs, struct lv_list);
-
+ list_iterate_items(lvl, lvs) {
lv = lvl->lv;
+
+ if (lv->status & SNAPSHOT)
+ continue;
+
for (i = 0; i < subpools; i++) {
if (usp[i].striping) {
if (!_add_stripe_seg(mem, &usp[i], lv, &le_cur)) {
@@ -306,5 +314,4 @@
}
return 1;
-
}
Modified: lvm2/upstream/current/lib/format_text/archive.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/archive.c (original)
+++ lvm2/upstream/current/lib/format_text/archive.c Tue Jun 14 11:13:22 2005
@@ -53,7 +53,7 @@
struct list list;
char *path;
- int index;
+ uint32_t index;
};
/*
@@ -91,7 +91,6 @@
static void _insert_file(struct list *head, struct archive_file *b)
{
- struct list *bh;
struct archive_file *bf = NULL;
if (list_empty(head)) {
@@ -99,11 +98,9 @@
return;
}
- /* index increases through list */
- list_iterate(bh, head) {
- bf = list_item(bh, struct archive_file);
-
- if (bf->index > b->index) {
+ /* index reduces through list */
+ list_iterate_items(bf, head) {
+ if (b->index > bf->index) {
list_add(&bf->list, &b->list);
return;
}
@@ -132,7 +129,8 @@
static struct list *_scan_archive(struct pool *mem,
const char *vgname, const char *dir)
{
- int i, count, ix;
+ int i, count;
+ uint32_t ix;
char vgname_found[64], *path;
struct dirent **dirent;
struct archive_file *af;
@@ -147,13 +145,13 @@
/* Sort fails beyond 5-digit indexes */
if ((count = scandir(dir, &dirent, NULL, alphasort)) < 0) {
- log_err("Couldn't scan archive directory.");
+ log_err("Couldn't scan the archive directory (%s).", dir);
return 0;
}
for (i = 0; i < count; i++) {
- /* ignore dot files */
- if (dirent[i]->d_name[0] == '.')
+ if (!strcmp(dirent[i]->d_name, ".") ||
+ !strcmp(dirent[i]->d_name, ".."))
continue;
/* check the name is the correct format */
@@ -199,7 +197,6 @@
static void _remove_expired(struct list *archives, uint32_t archives_size,
uint32_t retain_days, uint32_t min_archive)
{
- struct list *bh;
struct archive_file *bf;
struct stat sb;
time_t retain_time;
@@ -213,9 +210,7 @@
retain_time = time(NULL) - (time_t) retain_days *SECS_PER_DAY;
/* Assume list is ordered oldest first (by index) */
- list_iterate(bh, archives) {
- bf = list_item(bh, struct archive_file);
-
+ list_iterate_items(bf, archives) {
/* Get the mtime of the file and unlink if too old */
if (stat(bf->path, &sb)) {
log_sys_error("stat", bf->path);
@@ -240,7 +235,7 @@
uint32_t retain_days, uint32_t min_archive)
{
int i, fd, renamed = 0;
- unsigned int ix = 0;
+ uint32_t ix = 0;
struct archive_file *last;
FILE *fp = NULL;
char temp_file[PATH_MAX], archive_name[PATH_MAX];
@@ -272,20 +267,20 @@
* Now we want to rename this file to <vg>_index.vg.
*/
if (!(archives = _scan_archive(vg->cmd->mem, vg->name, dir))) {
- log_err("Couldn't scan the archive directory (%s).", dir);
+ stack;
return 0;
}
if (list_empty(archives))
ix = 0;
else {
- last = list_item(archives->p, struct archive_file);
+ last = list_item(list_first(archives), struct archive_file);
ix = last->index + 1;
}
for (i = 0; i < 10; i++) {
if (lvm_snprintf(archive_name, sizeof(archive_name),
- "%s/%s_%05d.vg", dir, vg->name, ix) < 0) {
+ "%s/%s_%05u.vg", dir, vg->name, ix) < 0) {
log_error("Archive file name too long.");
return 0;
}
@@ -344,22 +339,19 @@
int archive_list(struct cmd_context *cmd, const char *dir, const char *vgname)
{
- struct list *archives, *ah;
+ struct list *archives;
struct archive_file *af;
if (!(archives = _scan_archive(cmd->mem, vgname, dir))) {
- log_err("Couldn't scan the archive directory (%s).", dir);
+ stack;
return 0;
}
if (list_empty(archives))
log_print("No archives found in %s.", dir);
- list_iterate(ah, archives) {
- af = list_item(ah, struct archive_file);
-
+ list_iterate_back_items(af, archives)
_display_archive(cmd, af);
- }
pool_free(cmd->mem, archives);
Added: lvm2/upstream/current/lib/format_text/archiver.c
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/lib/format_text/archiver.c Tue Jun 14 11:13:22 2005
@@ -0,0 +1,418 @@
+/*
+ * 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 "lib.h"
+#include "archiver.h"
+#include "format-text.h"
+#include "lvm-file.h"
+#include "lvm-string.h"
+#include "lvmcache.h"
+#include "toolcontext.h"
+
+#include <unistd.h>
+
+struct archive_params {
+ int enabled;
+ char *dir;
+ unsigned int keep_days;
+ unsigned int keep_number;
+};
+
+struct backup_params {
+ int enabled;
+ char *dir;
+};
+
+int archive_init(struct cmd_context *cmd, const char *dir,
+ unsigned int keep_days, unsigned int keep_min)
+{
+ if (!(cmd->archive_params = pool_zalloc(cmd->libmem,
+ sizeof(*cmd->archive_params)))) {
+ log_error("archive_params alloc failed");
+ return 0;
+ }
+
+ cmd->archive_params->dir = NULL;
+
+ if (!*dir)
+ return 1;
+
+ if (!(cmd->archive_params->dir = dbg_strdup(dir))) {
+ log_error("Couldn't copy archive directory name.");
+ return 0;
+ }
+
+ cmd->archive_params->keep_days = keep_days;
+ cmd->archive_params->keep_number = keep_min;
+ cmd->archive_params->enabled = 1;
+
+ return 1;
+}
+
+void archive_exit(struct cmd_context *cmd)
+{
+ if (cmd->archive_params->dir)
+ dbg_free(cmd->archive_params->dir);
+ memset(cmd->archive_params, 0, sizeof(*cmd->archive_params));
+}
+
+void archive_enable(struct cmd_context *cmd, int flag)
+{
+ cmd->archive_params->enabled = flag;
+}
+
+static char *_build_desc(struct pool *mem, const char *line, int before)
+{
+ size_t len = strlen(line) + 32;
+ char *buffer;
+
+ if (!(buffer = pool_zalloc(mem, strlen(line) + 32))) {
+ stack;
+ return NULL;
+ }
+
+ if (snprintf(buffer, len,
+ "Created %s executing '%s'",
+ before ? "*before*" : "*after*", line) < 0) {
+ stack;
+ return NULL;
+ }
+
+ return buffer;
+}
+
+static int __archive(struct volume_group *vg)
+{
+ char *desc;
+
+ if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 1))) {
+ stack;
+ return 0;
+ }
+
+ return archive_vg(vg, vg->cmd->archive_params->dir, desc,
+ vg->cmd->archive_params->keep_days,
+ vg->cmd->archive_params->keep_number);
+}
+
+int archive(struct volume_group *vg)
+{
+ if (!vg->cmd->archive_params->enabled || !vg->cmd->archive_params->dir)
+ return 1;
+
+ if (test_mode()) {
+ log_verbose("Test mode: Skipping archiving of volume group.");
+ return 1;
+ }
+
+ if (!create_dir(vg->cmd->archive_params->dir))
+ return 0;
+
+ /* Trap a read-only file system */
+ if ((access(vg->cmd->archive_params->dir, R_OK | W_OK | X_OK) == -1) &&
+ (errno == EROFS))
+ return 0;
+
+ log_verbose("Archiving volume group \"%s\" metadata (seqno %u).", vg->name,
+ vg->seqno);
+ if (!__archive(vg)) {
+ log_error("Volume group \"%s\" metadata archive failed.",
+ vg->name);
+ return 0;
+ }
+
+ return 1;
+}
+
+int archive_display(struct cmd_context *cmd, const char *vg_name)
+{
+ int r1, r2;
+
+ init_partial(1);
+ r1 = archive_list(cmd, cmd->archive_params->dir, vg_name);
+ r2 = backup_list(cmd, cmd->backup_params->dir, vg_name);
+ init_partial(0);
+
+ return r1 && r2;
+}
+
+int backup_init(struct cmd_context *cmd, const char *dir)
+{
+ if (!(cmd->backup_params = pool_zalloc(cmd->libmem,
+ sizeof(*cmd->archive_params)))) {
+ log_error("archive_params alloc failed");
+ return 0;
+ }
+
+ cmd->backup_params->dir = NULL;
+ if (!*dir)
+ return 1;
+
+ if (!(cmd->backup_params->dir = dbg_strdup(dir))) {
+ log_error("Couldn't copy backup directory name.");
+ return 0;
+ }
+
+ return 1;
+}
+
+void backup_exit(struct cmd_context *cmd)
+{
+ if (cmd->backup_params->dir)
+ dbg_free(cmd->backup_params->dir);
+ memset(cmd->backup_params, 0, sizeof(*cmd->backup_params));
+}
+
+void backup_enable(struct cmd_context *cmd, int flag)
+{
+ cmd->backup_params->enabled = flag;
+}
+
+static int __backup(struct volume_group *vg)
+{
+ char name[PATH_MAX];
+ char *desc;
+
+ if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 0))) {
+ stack;
+ return 0;
+ }
+
+ if (lvm_snprintf(name, sizeof(name), "%s/%s",
+ vg->cmd->backup_params->dir, vg->name) < 0) {
+ log_error("Failed to generate volume group metadata backup "
+ "filename.");
+ return 0;
+ }
+
+ return backup_to_file(name, desc, vg);
+}
+
+int backup(struct volume_group *vg)
+{
+ if (!vg->cmd->backup_params->enabled || !vg->cmd->backup_params->dir) {
+ log_print("WARNING: This metadata update is NOT backed up");
+ return 1;
+ }
+
+ if (test_mode()) {
+ log_verbose("Test mode: Skipping volume group backup.");
+ return 1;
+ }
+
+ if (!create_dir(vg->cmd->backup_params->dir))
+ return 0;
+
+ /* Trap a read-only file system */
+ if ((access(vg->cmd->backup_params->dir, R_OK | W_OK | X_OK) == -1) &&
+ (errno == EROFS))
+ return 0;
+
+ if (!__backup(vg)) {
+ log_error("Backup of volume group %s metadata failed.",
+ vg->name);
+ return 0;
+ }
+
+ return 1;
+}
+
+int backup_remove(struct cmd_context *cmd, const char *vg_name)
+{
+ char path[PATH_MAX];
+
+ if (lvm_snprintf(path, sizeof(path), "%s/%s",
+ cmd->backup_params->dir, vg_name) < 0) {
+ log_err("Failed to generate backup filename (for removal).");
+ return 0;
+ }
+
+ /*
+ * Let this fail silently.
+ */
+ unlink(path);
+ return 1;
+}
+
+struct volume_group *backup_read_vg(struct cmd_context *cmd,
+ const char *vg_name, const char *file)
+{
+ struct volume_group *vg = NULL;
+ struct format_instance *tf;
+ struct metadata_area *mda;
+ void *context;
+
+ if (!(context = create_text_context(cmd, file,
+ cmd->cmd_line)) ||
+ !(tf = cmd->fmt_backup->ops->create_instance(cmd->fmt_backup, NULL,
+ context))) {
+ log_error("Couldn't create text format object.");
+ return NULL;
+ }
+
+ list_iterate_items(mda, &tf->metadata_areas) {
+ if (!(vg = mda->ops->vg_read(tf, vg_name, mda)))
+ stack;
+ break;
+ }
+
+ tf->fmt->ops->destroy_instance(tf);
+ return vg;
+}
+
+/* ORPHAN and VG locks held before calling this */
+int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg)
+{
+ struct pv_list *pvl;
+ struct physical_volume *pv;
+ struct lvmcache_info *info;
+
+ /*
+ * FIXME: Check that the PVs referenced in the backup are
+ * not members of other existing VGs.
+ */
+
+ /* Attempt to write out using currently active format */
+ if (!(vg->fid = cmd->fmt->ops->create_instance(cmd->fmt, vg->name,
+ NULL))) {
+ log_error("Failed to allocate format instance");
+ return 0;
+ }
+
+ /* Add any metadata areas on the PVs */
+ list_iterate_items(pvl, &vg->pvs) {
+ pv = pvl->pv;
+ if (!(info = info_from_pvid(pv->dev->pvid))) {
+ log_error("PV %s missing from cache",
+ dev_name(pv->dev));
+ return 0;
+ }
+ if (cmd->fmt != info->fmt) {
+ log_error("PV %s is a different format (seqno %s)",
+ dev_name(pv->dev), info->fmt->name);
+ return 0;
+ }
+ if (!vg->fid->fmt->ops->
+ pv_setup(vg->fid->fmt, UINT64_C(0), 0, 0, 0,
+ UINT64_C(0), &vg->fid->metadata_areas, pv, vg)) {
+ log_error("Format-specific setup for %s failed",
+ dev_name(pv->dev));
+ return 0;
+ }
+ }
+
+ if (!vg_write(vg) || !vg_commit(vg)) {
+ stack;
+ return 0;
+ }
+
+ return 1;
+}
+
+/* ORPHAN and VG locks held before calling this */
+int backup_restore_from_file(struct cmd_context *cmd, const char *vg_name,
+ const char *file)
+{
+ struct volume_group *vg;
+
+ /*
+ * Read in the volume group from the text file.
+ */
+ if (!(vg = backup_read_vg(cmd, vg_name, file))) {
+ stack;
+ return 0;
+ }
+
+ return backup_restore_vg(cmd, vg);
+}
+
+int backup_restore(struct cmd_context *cmd, const char *vg_name)
+{
+ char path[PATH_MAX];
+
+ if (lvm_snprintf(path, sizeof(path), "%s/%s",
+ cmd->backup_params->dir, vg_name) < 0) {
+ log_err("Failed to generate backup filename (for restore).");
+ return 0;
+ }
+
+ return backup_restore_from_file(cmd, vg_name, path);
+}
+
+int backup_to_file(const char *file, const char *desc, struct volume_group *vg)
+{
+ int r = 0;
+ struct format_instance *tf;
+ struct metadata_area *mda;
+ void *context;
+ struct cmd_context *cmd;
+
+ cmd = vg->cmd;
+
+ log_verbose("Creating volume group backup \"%s\" (seqno %u).", file, vg->seqno);
+
+ if (!(context = create_text_context(cmd, file, desc)) ||
+ !(tf = cmd->fmt_backup->ops->create_instance(cmd->fmt_backup, NULL,
+ context))) {
+ log_error("Couldn't create backup object.");
+ return 0;
+ }
+
+ /* Write and commit the metadata area */
+ list_iterate_items(mda, &tf->metadata_areas) {
+ if (!(r = mda->ops->vg_write(tf, vg, mda))) {
+ stack;
+ continue;
+ }
+ if (mda->ops->vg_commit &&
+ !(r = mda->ops->vg_commit(tf, vg, mda))) {
+ stack;
+ }
+ }
+
+ tf->fmt->ops->destroy_instance(tf);
+ return r;
+}
+
+/*
+ * Update backup (and archive) if they're out-of-date or don't exist.
+ */
+void check_current_backup(struct volume_group *vg)
+{
+ char path[PATH_MAX];
+ struct volume_group *vg_backup;
+
+ if ((vg->status & PARTIAL_VG) || (vg->status & EXPORTED_VG))
+ return;
+
+ if (lvm_snprintf(path, sizeof(path), "%s/%s",
+ vg->cmd->backup_params->dir, vg->name) < 0) {
+ log_debug("Failed to generate backup filename.");
+ return;
+ }
+
+ log_suppress(1);
+ /* Up-to-date backup exists? */
+ if ((vg_backup = backup_read_vg(vg->cmd, vg->name, path)) &&
+ (vg->seqno == vg_backup->seqno) &&
+ (id_equal(&vg->id, &vg_backup->id)))
+ return;
+ log_suppress(0);
+
+ if (vg_backup)
+ archive(vg_backup);
+ archive(vg);
+ backup(vg);
+}
Added: lvm2/upstream/current/lib/format_text/archiver.h
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/lib/format_text/archiver.h Tue Jun 14 11:13:22 2005
@@ -0,0 +1,60 @@
+/*
+ * 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
+ */
+
+#ifndef _LVM_TOOL_ARCHIVE_H
+#define _LVM_TOOL_ARCHIVE_H
+
+#include "metadata.h"
+
+/*
+ * There are two operations that come under the general area of
+ * backups. 'Archiving' occurs just before a volume group
+ * configuration is changed. The user may configure when
+ * archived files are expired. Typically archives will be stored
+ * in /etc/lvm/archive.
+ *
+ * A 'backup' is a redundant copy of the *current* volume group
+ * configuration. As such it should be taken just after the
+ * volume group is changed. Only 1 backup file will exist.
+ * Typically backups will be stored in /etc/lvm/backups.
+ */
+
+int archive_init(struct cmd_context *cmd, const char *dir,
+ unsigned int keep_days, unsigned int keep_min);
+void archive_exit(struct cmd_context *cmd);
+
+void archive_enable(struct cmd_context *cmd, int flag);
+int archive(struct volume_group *vg);
+int archive_display(struct cmd_context *cmd, const char *vg_name);
+
+int backup_init(struct cmd_context *cmd, const char *dir);
+void backup_exit(struct cmd_context *cmd);
+
+void backup_enable(struct cmd_context *cmd, int flag);
+int backup(struct volume_group *vg);
+int backup_remove(struct cmd_context *cmd, const char *vg_name);
+
+struct volume_group *backup_read_vg(struct cmd_context *cmd,
+ const char *vg_name, const char *file);
+int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg);
+int backup_restore_from_file(struct cmd_context *cmd, const char *vg_name,
+ const char *file);
+int backup_restore(struct cmd_context *cmd, const char *vg_name);
+
+int backup_to_file(const char *file, const char *desc, struct volume_group *vg);
+
+void check_current_backup(struct volume_group *vg);
+
+#endif
Modified: lvm2/upstream/current/lib/format_text/export.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/export.c (original)
+++ lvm2/upstream/current/lib/format_text/export.c Tue Jun 14 11:13:22 2005
@@ -30,7 +30,7 @@
struct formatter;
typedef int (*out_with_comment_fn) (struct formatter * f, const char *comment,
const char *fmt, va_list ap);
-typedef void (*nl_fn) (struct formatter * f);
+typedef int (*nl_fn) (struct formatter * f);
/*
* The first half of this file deals with
* exporting the vg, ie. writing it to a file.
@@ -42,7 +42,7 @@
union {
FILE *fp; /* where we're writing to */
struct {
- char *buf;
+ char *start;
uint32_t size;
uint32_t used;
} buf;
@@ -95,22 +95,34 @@
/*
* Newline function for prettier layout.
*/
-static void _nl_file(struct formatter *f)
+static int _nl_file(struct formatter *f)
{
fprintf(f->data.fp, "\n");
+
+ return 1;
}
-static void _nl_raw(struct formatter *f)
+static int _nl_raw(struct formatter *f)
{
- if (f->data.buf.used >= f->data.buf.size - 1)
- return;
+ char *newbuf;
+
+ /* If metadata doesn't fit, double the buffer size */
+ if (f->data.buf.used + 2 > f->data.buf.size) {
+ if (!(newbuf = dbg_realloc(f->data.buf.start,
+ f->data.buf.size * 2))) {
+ stack;
+ return 0;
+ }
+ f->data.buf.start = newbuf;
+ f->data.buf.size *= 2;
+ }
- *f->data.buf.buf = '\n';
- f->data.buf.buf += 1;
+ *(f->data.buf.start + f->data.buf.used) = '\n';
f->data.buf.used += 1;
- *f->data.buf.buf = '\0';
- return;
+ *(f->data.buf.start + f->data.buf.used) = '\0';
+
+ return 1;
}
#define COMMENT_TAB 6
@@ -153,17 +165,27 @@
const char *fmt, va_list ap)
{
int n;
+ char *newbuf;
- n = vsnprintf(f->data.buf.buf, f->data.buf.size - f->data.buf.used,
- fmt, ap);
-
- if (n < 0 || (n > f->data.buf.size - f->data.buf.used - 1))
- return 0;
+ retry:
+ n = vsnprintf(f->data.buf.start + f->data.buf.used,
+ f->data.buf.size - f->data.buf.used, fmt, ap);
+
+ /* If metadata doesn't fit, double the buffer size */
+ if (n < 0 || (n + f->data.buf.used + 2 > f->data.buf.size)) {
+ if (!(newbuf = dbg_realloc(f->data.buf.start,
+ f->data.buf.size * 2))) {
+ stack;
+ return 0;
+ }
+ f->data.buf.start = newbuf;
+ f->data.buf.size *= 2;
+ goto retry;
+ }
- f->data.buf.buf += n;
f->data.buf.used += n;
- f->nl(f);
+ outnl(f);
return 1;
}
@@ -257,10 +279,10 @@
outf(f, "# Generated by LVM2: %s", ctime(&t));
outf(f, CONTENTS_FIELD " = \"" CONTENTS_VALUE "\"");
outf(f, FORMAT_VERSION_FIELD " = %d", FORMAT_VERSION_VALUE);
- f->nl(f);
+ outnl(f);
outf(f, "description = \"%s\"", desc);
- f->nl(f);
+ outnl(f);
outf(f, "creation_host = \"%s\"\t# %s %s %s %s %s", _utsname.nodename,
_utsname.sysname, _utsname.nodename, _utsname.release,
_utsname.version, _utsname.machine);
@@ -309,7 +331,7 @@
/* Default policy is NORMAL; INHERIT is meaningless */
if (vg->alloc != ALLOC_NORMAL && vg->alloc != ALLOC_INHERIT) {
- f->nl(f);
+ outnl(f);
outf(f, "allocation_policy = \"%s\"",
get_alloc_string(vg->alloc));
}
@@ -330,7 +352,7 @@
static int _print_pvs(struct formatter *f, struct volume_group *vg)
{
- struct list *pvh;
+ struct pv_list *pvl;
struct physical_volume *pv;
char buffer[4096];
const char *name;
@@ -338,15 +360,15 @@
outf(f, "physical_volumes {");
_inc_indent(f);
- list_iterate(pvh, &vg->pvs) {
- pv = list_item(pvh, struct pv_list)->pv;
+ list_iterate_items(pvl, &vg->pvs) {
+ pv = pvl->pv;
if (!(name = _get_pv_name(f, pv))) {
stack;
return 0;
}
- f->nl(f);
+ outnl(f);
outf(f, "%s {", name);
_inc_indent(f);
@@ -360,7 +382,7 @@
stack;
return 0;
}
- f->nl(f);
+ outnl(f);
if (!print_flags(pv->status, PV_FLAGS, buffer, sizeof(buffer))) {
stack;
@@ -407,7 +429,7 @@
return 0;
}
- f->nl(f);
+ outnl(f);
outf(f, "type = \"%s\"", seg->segtype->name);
if (!list_empty(&seg->tags)) {
@@ -436,27 +458,27 @@
const char *name;
unsigned int s;
- f->nl(f);
+ outnl(f);
outf(f, "%ss = [", type);
_inc_indent(f);
for (s = 0; s < seg->area_count; s++) {
- switch (seg->area[s].type) {
+ switch (seg_type(seg, s)) {
case AREA_PV:
- if (!(name = _get_pv_name(f, seg->area[s].u.pv.pv))) {
+ if (!(name = _get_pv_name(f, seg_pv(seg, s)))) {
stack;
return 0;
}
outf(f, "\"%s\", %u%s", name,
- seg->area[s].u.pv.pe,
+ seg_pe(seg, s),
(s == seg->area_count - 1) ? "" : ",");
break;
case AREA_LV:
outf(f, "\"%s\", %u%s",
- seg->area[s].u.lv.lv->name,
- seg->area[s].u.lv.le,
+ seg_lv(seg, s)->name,
+ seg_le(seg, s),
(s == seg->area_count - 1) ? "" : ",");
}
}
@@ -466,105 +488,68 @@
return 1;
}
-static int _count_segments(struct logical_volume *lv)
-{
- int r = 0;
- struct list *segh;
-
- list_iterate(segh, &lv->segments)
- r++;
-
- return r;
-}
-
-static int _print_snapshot(struct formatter *f, struct snapshot *snap,
- unsigned int count)
+static int _print_lv(struct formatter *f, struct logical_volume *lv)
{
- char buffer[256];
- struct lv_segment seg;
-
- f->nl(f);
+ struct lv_segment *seg;
+ char buffer[4096];
+ int seg_count;
- outf(f, "snapshot%u {", count);
+ outnl(f);
+ outf(f, "%s {", lv->name);
_inc_indent(f);
- if (!id_write_format(&snap->id, buffer, sizeof(buffer))) {
+ /* FIXME: Write full lvid */
+ if (!id_write_format(&lv->lvid.id[1], buffer, sizeof(buffer))) {
stack;
return 0;
}
outf(f, "id = \"%s\"", buffer);
- seg.status = LVM_READ | LVM_WRITE | VISIBLE_LV;
- if (!print_flags(seg.status, LV_FLAGS, buffer, sizeof(buffer))) {
+ if (!print_flags(lv->status, LV_FLAGS, buffer, sizeof(buffer))) {
stack;
return 0;
}
-
outf(f, "status = %s", buffer);
- outf(f, "segment_count = 1");
-
- f->nl(f);
-
- if (!(seg.segtype = get_segtype_from_string(snap->origin->vg->cmd,
- "snapshot"))) {
- stack;
- return 0;
- }
-
- seg.le = 0;
- seg.len = snap->le_count;
- seg.origin = snap->origin;
- seg.cow = snap->cow;
- seg.chunk_size = snap->chunk_size;
- /* FIXME Dummy values */
- list_init(&seg.list);
- seg.lv = snap->cow;
- seg.stripe_size = 0;
- seg.area_count = 0;
- seg.area_len = 0;
- seg.extents_copied = 0;
-
- /* Can't tag a snapshot independently of its origin */
- list_init(&seg.tags);
-
- if (!_print_segment(f, snap->origin->vg, 1, &seg)) {
- stack;
- return 0;
+ if (!list_empty(&lv->tags)) {
+ if (!print_tags(&lv->tags, buffer, sizeof(buffer))) {
+ stack;
+ return 0;
+ }
+ outf(f, "tags = %s", buffer);
}
- _dec_indent(f);
- outf(f, "}");
-
- return 1;
-}
-
-static int _print_snapshots(struct formatter *f, struct volume_group *vg)
-{
- struct list *sh;
- struct snapshot *s;
- unsigned int count = 0;
-
- list_iterate(sh, &vg->snapshots) {
- s = list_item(sh, struct snapshot_list)->snapshot;
+ if (lv->alloc != ALLOC_INHERIT)
+ outf(f, "allocation_policy = \"%s\"",
+ get_alloc_string(lv->alloc));
- if (!_print_snapshot(f, s, count++)) {
+ if (lv->read_ahead)
+ outf(f, "read_ahead = %u", lv->read_ahead);
+ if (lv->major >= 0)
+ outf(f, "major = %d", lv->major);
+ if (lv->minor >= 0)
+ outf(f, "minor = %d", lv->minor);
+ outf(f, "segment_count = %u", list_size(&lv->segments));
+ outnl(f);
+
+ seg_count = 1;
+ list_iterate_items(seg, &lv->segments) {
+ if (!_print_segment(f, lv->vg, seg_count++, seg)) {
stack;
return 0;
}
}
+ _dec_indent(f);
+ outf(f, "}");
+
return 1;
}
static int _print_lvs(struct formatter *f, struct volume_group *vg)
{
- struct list *lvh;
- struct logical_volume *lv;
- struct lv_segment *seg;
- char buffer[4096];
- int seg_count;
+ struct lv_list *lvl;
/*
* Don't bother with an lv section if there are no lvs.
@@ -575,63 +560,25 @@
outf(f, "logical_volumes {");
_inc_indent(f);
- list_iterate(lvh, &vg->lvs) {
- lv = list_item(lvh, struct lv_list)->lv;
-
- f->nl(f);
- outf(f, "%s {", lv->name);
- _inc_indent(f);
-
- /* FIXME: Write full lvid */
- if (!id_write_format(&lv->lvid.id[1], buffer, sizeof(buffer))) {
+ /*
+ * Write visible LVs first
+ */
+ list_iterate_items(lvl, &vg->lvs) {
+ if (!(lvl->lv->status & VISIBLE_LV))
+ continue;
+ if (!_print_lv(f, lvl->lv)) {
stack;
return 0;
}
+ }
- outf(f, "id = \"%s\"", buffer);
-
- if (!print_flags(lv->status, LV_FLAGS, buffer, sizeof(buffer))) {
+ list_iterate_items(lvl, &vg->lvs) {
+ if ((lvl->lv->status & VISIBLE_LV))
+ continue;
+ if (!_print_lv(f, lvl->lv)) {
stack;
return 0;
}
- outf(f, "status = %s", buffer);
-
- if (!list_empty(&lv->tags)) {
- if (!print_tags(&lv->tags, buffer, sizeof(buffer))) {
- stack;
- return 0;
- }
- outf(f, "tags = %s", buffer);
- }
-
- if (lv->alloc != ALLOC_INHERIT)
- outf(f, "allocation_policy = \"%s\"",
- get_alloc_string(lv->alloc));
-
- if (lv->read_ahead)
- outf(f, "read_ahead = %u", lv->read_ahead);
- if (lv->major >= 0)
- outf(f, "major = %d", lv->major);
- if (lv->minor >= 0)
- outf(f, "minor = %d", lv->minor);
- outf(f, "segment_count = %u", _count_segments(lv));
- f->nl(f);
-
- seg_count = 1;
- list_iterate_items(seg, &lv->segments) {
- if (!_print_segment(f, vg, seg_count++, seg)) {
- stack;
- return 0;
- }
- }
-
- _dec_indent(f);
- outf(f, "}");
- }
-
- if (!_print_snapshots(f, vg)) {
- stack;
- return 0;
}
_dec_indent(f);
@@ -648,7 +595,7 @@
static int _build_pv_names(struct formatter *f, struct volume_group *vg)
{
int count = 0;
- struct list *pvh;
+ struct pv_list *pvl;
struct physical_volume *pv;
char buffer[32], *name;
@@ -662,8 +609,8 @@
goto bad;
}
- list_iterate(pvh, &vg->pvs) {
- pv = list_item(pvh, struct pv_list)->pv;
+ list_iterate_items(pvl, &vg->pvs) {
+ pv = pvl->pv;
/* FIXME But skip if there's already an LV called pv%d ! */
if (lvm_snprintf(buffer, sizeof(buffer), "pv%d", count++) < 0) {
@@ -716,11 +663,11 @@
if (!_print_vg(f, vg))
fail;
- f->nl(f);
+ outnl(f);
if (!_print_pvs(f, vg))
fail;
- f->nl(f);
+ outnl(f);
if (!_print_lvs(f, vg))
fail;
@@ -771,11 +718,10 @@
}
/* Returns amount of buffer used incl. terminating NUL */
-int text_vg_export_raw(struct volume_group *vg, const char *desc, char *buf,
- uint32_t size)
+int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
{
struct formatter *f;
- int r;
+ int r = 0;
_init();
@@ -785,8 +731,13 @@
}
memset(f, 0, sizeof(*f));
- f->data.buf.buf = buf;
- f->data.buf.size = size;
+
+ f->data.buf.size = 65536; /* Initial metadata limit */
+ if (!(f->data.buf.start = dbg_malloc(f->data.buf.size))) {
+ log_error("text_export buffer allocation failed");
+ goto out;
+ }
+
f->indent = 0;
f->header = 0;
f->out_with_comment = &_out_with_comment_raw;
@@ -794,11 +745,12 @@
if (!_text_vg_export(f, vg, desc)) {
stack;
- r = 0;
+ dbg_free(f->data.buf.start);
goto out;
}
r = f->data.buf.used + 1;
+ *buf = f->data.buf.start;
out:
dbg_free(f);
@@ -806,3 +758,4 @@
}
#undef outf
+#undef outnl
Modified: lvm2/upstream/current/lib/format_text/flags.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/flags.c (original)
+++ lvm2/upstream/current/lib/format_text/flags.c Tue Jun 14 11:13:22 2005
@@ -52,8 +52,11 @@
{VISIBLE_LV, "VISIBLE"},
{PVMOVE, "PVMOVE"},
{LOCKED, "LOCKED"},
+ {MIRROR_IMAGE, NULL},
+ {MIRROR_LOG, NULL},
{MIRRORED, NULL},
{VIRTUAL, NULL},
+ {SNAPSHOT, NULL},
{0, NULL}
};
Modified: lvm2/upstream/current/lib/format_text/format-text.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/format-text.c (original)
+++ lvm2/upstream/current/lib/format_text/format-text.c Tue Jun 14 11:13:22 2005
@@ -183,57 +183,74 @@
static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
struct mda_header *mdah,
- const char *vgname)
+ const char *vgname,
+ int precommit)
{
size_t len;
char vgnamebuf[NAME_LEN + 2];
struct raw_locn *rlocn;
+ struct lvmcache_info *info;
- rlocn = mdah->raw_locns;
+ rlocn = mdah->raw_locns; /* Slot 0 */
+
+ if (precommit)
+ rlocn++; /* Slot 1 */
+ /* FIXME Loop through rlocns two-at-a-time. List null-terminated. */
/* FIXME Ignore if checksum incorrect!!! */
- while (rlocn->offset) {
- if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
- sizeof(vgnamebuf), vgnamebuf)) {
- stack;
- return NULL;
- }
- if (!strncmp(vgnamebuf, vgname, len = strlen(vgname)) &&
- (isspace(vgnamebuf[len]) || vgnamebuf[len] == '{')) {
- return rlocn;
- }
- rlocn++;
+ if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
+ sizeof(vgnamebuf), vgnamebuf)) {
+ stack;
+ goto error;
}
+ if (!strncmp(vgnamebuf, vgname, len = strlen(vgname)) &&
+ (isspace(vgnamebuf[len]) || vgnamebuf[len] == '{')) {
+ return rlocn;
+ }
+
+ error:
+ if ((info = info_from_pvid(dev_area->dev->pvid)))
+ lvmcache_update_vgname(info, ORPHAN);
+
return NULL;
}
-static struct raw_locn *_vg_posn(struct format_instance *fid,
- struct device_area *dev_area,
- const char *vgname)
+/*
+ * Determine offset for uncommitted metadata
+ */
+static uint64_t _next_rlocn_offset(struct raw_locn *rlocn,
+ struct mda_header *mdah)
{
+ if (!rlocn)
+ /* Find an empty slot */
+ /* FIXME Assume only one VG per mdah for now */
+ return MDA_HEADER_SIZE;
- struct mda_header *mdah;
-
- if (!(mdah = _raw_read_mda_header(fid->fmt, dev_area))) {
- stack;
- return NULL;
- }
-
- return _find_vg_rlocn(dev_area, mdah, vgname);
+ /* Start of free space - round up to next sector; circular */
+ return ((rlocn->offset + rlocn->size +
+ (SECTOR_SIZE - rlocn->size % SECTOR_SIZE) -
+ MDA_HEADER_SIZE) % (mdah->size - MDA_HEADER_SIZE))
+ + MDA_HEADER_SIZE;
}
static int _raw_holds_vgname(struct format_instance *fid,
struct device_area *dev_area, const char *vgname)
{
int r = 0;
+ struct mda_header *mdah;
if (!dev_open(dev_area->dev)) {
stack;
return 0;
}
- if (_vg_posn(fid, dev_area, vgname))
+ if (!(mdah = _raw_read_mda_header(fid->fmt, dev_area))) {
+ stack;
+ return 0;
+ }
+
+ if (_find_vg_rlocn(dev_area, mdah, vgname, 0))
r = 1;
if (!dev_close(dev_area->dev))
@@ -244,7 +261,8 @@
static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
const char *vgname,
- struct device_area *area)
+ struct device_area *area,
+ int precommit)
{
struct volume_group *vg = NULL;
struct raw_locn *rlocn;
@@ -263,8 +281,8 @@
goto out;
}
- if (!(rlocn = _vg_posn(fid, area, vgname))) {
- stack;
+ if (!(rlocn = _find_vg_rlocn(area, mdah, vgname, precommit))) {
+ log_debug("VG %s not found on %s", vgname, dev_name(area->dev));
goto out;
}
@@ -287,8 +305,9 @@
stack;
goto out;
}
- log_debug("Read %s metadata (%u) from %s at %" PRIu64 " size %" PRIu64,
- vg->name, vg->seqno, dev_name(area->dev),
+ log_debug("Read %s %smetadata (%u) from %s at %" PRIu64 " size %"
+ PRIu64, vg->name, precommit ? "pre-commit " : "",
+ vg->seqno, dev_name(area->dev),
area->start + rlocn->offset, rlocn->size);
out:
@@ -304,7 +323,16 @@
{
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
- return _vg_read_raw_area(fid, vgname, &mdac->area);
+ return _vg_read_raw_area(fid, vgname, &mdac->area, 0);
+}
+
+static struct volume_group *_vg_read_precommit_raw(struct format_instance *fid,
+ const char *vgname,
+ struct metadata_area *mda)
+{
+ struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
+
+ return _vg_read_raw_area(fid, vgname, &mdac->area, 1);
}
static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
@@ -313,19 +341,15 @@
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
struct raw_locn *rlocn;
struct mda_header *mdah;
- struct physical_volume *pv;
- struct list *pvh;
+ struct pv_list *pvl;
int r = 0;
uint32_t new_wrap = 0, old_wrap = 0;
-
- /* FIXME Essential fix! Make dynamic (realloc? pool?) */
- char buf[65536];
+ char *buf = NULL;
int found = 0;
/* Ignore any mda on a PV outside the VG. vgsplit relies on this */
- list_iterate(pvh, &vg->pvs) {
- pv = list_item(pvh, struct pv_list)->pv;
- if (pv->dev == mdac->area.dev) {
+ list_iterate_items(pvl, &vg->pvs) {
+ if (pvl->pv->dev == mdac->area.dev) {
found = 1;
break;
}
@@ -344,20 +368,10 @@
goto out;
}
- if ((rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name))) {
- /* Start of free space - round up to next sector; circular */
- mdac->rlocn.offset =
- ((rlocn->offset + rlocn->size +
- (SECTOR_SIZE - rlocn->size % SECTOR_SIZE) -
- MDA_HEADER_SIZE) % (mdah->size - MDA_HEADER_SIZE))
- + MDA_HEADER_SIZE;
- } else {
- /* Find an empty slot */
- /* FIXME Assume only one VG per mdah for now */
- mdac->rlocn.offset = MDA_HEADER_SIZE;
- }
+ rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, 0);
+ mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah);
- if (!(mdac->rlocn.size = text_vg_export_raw(vg, "", buf, sizeof(buf)))) {
+ if (!(mdac->rlocn.size = text_vg_export_raw(vg, "", &buf))) {
log_error("VG %s metadata writing failed", vg->name);
goto out;
}
@@ -417,24 +431,26 @@
if (!r && !dev_close(mdac->area.dev))
stack;
+ if (buf)
+ dbg_free(buf);
return r;
}
-static int _vg_commit_raw(struct format_instance *fid, struct volume_group *vg,
- struct metadata_area *mda)
+static int _vg_commit_raw_rlocn(struct format_instance *fid,
+ struct volume_group *vg,
+ struct metadata_area *mda,
+ int precommit)
{
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
struct mda_header *mdah;
struct raw_locn *rlocn;
- struct physical_volume *pv;
- struct list *pvh;
+ struct pv_list *pvl;
int r = 0;
int found = 0;
/* Ignore any mda on a PV outside the VG. vgsplit relies on this */
- list_iterate(pvh, &vg->pvs) {
- pv = list_item(pvh, struct pv_list)->pv;
- if (pv->dev == mdac->area.dev) {
+ list_iterate_items(pvl, &vg->pvs) {
+ if (pvl->pv->dev == mdac->area.dev) {
found = 1;
break;
}
@@ -448,18 +464,23 @@
goto out;
}
- if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name))) {
- rlocn = &mdah->raw_locns[0];
+ if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, 0))) {
+ mdah->raw_locns[0].offset = 0;
mdah->raw_locns[1].offset = 0;
+ mdah->raw_locns[2].offset = 0;
+ rlocn = &mdah->raw_locns[0];
}
+ if (precommit)
+ rlocn++;
+
rlocn->offset = mdac->rlocn.offset;
rlocn->size = mdac->rlocn.size;
rlocn->checksum = mdac->rlocn.checksum;
- log_debug("Committing %s metadata (%u) to %s header at %" PRIu64,
- vg->name, vg->seqno, dev_name(mdac->area.dev),
- mdac->area.start);
+ log_debug("%sCommitting %s metadata (%u) to %s header at %" PRIu64,
+ precommit ? "Pre-" : "", vg->name, vg->seqno,
+ dev_name(mdac->area.dev), mdac->area.start);
if (!_raw_write_mda_header(fid->fmt, mdac->area.dev, mdac->area.start,
mdah)) {
log_error("Failed to write metadata area header");
@@ -469,25 +490,36 @@
r = 1;
out:
- if (!dev_close(mdac->area.dev))
+ if (!precommit && !dev_close(mdac->area.dev))
stack;
return r;
}
+static int _vg_commit_raw(struct format_instance *fid, struct volume_group *vg,
+ struct metadata_area *mda)
+{
+ return _vg_commit_raw_rlocn(fid, vg, mda, 0);
+}
+
+static int _vg_precommit_raw(struct format_instance *fid,
+ struct volume_group *vg,
+ struct metadata_area *mda)
+{
+ return _vg_commit_raw_rlocn(fid, vg, mda, 1);
+}
+
/* Close metadata area devices */
static int _vg_revert_raw(struct format_instance *fid, struct volume_group *vg,
struct metadata_area *mda)
{
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
- struct physical_volume *pv;
- struct list *pvh;
+ struct pv_list *pvl;
int found = 0;
/* Ignore any mda on a PV outside the VG. vgsplit relies on this */
- list_iterate(pvh, &vg->pvs) {
- pv = list_item(pvh, struct pv_list)->pv;
- if (pv->dev == mdac->area.dev) {
+ list_iterate_items(pvl, &vg->pvs) {
+ if (pvl->pv->dev == mdac->area.dev) {
found = 1;
break;
}
@@ -520,7 +552,7 @@
goto out;
}
- if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name))) {
+ if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, 0))) {
rlocn = &mdah->raw_locns[0];
mdah->raw_locns[1].offset = 0;
}
@@ -546,13 +578,13 @@
static struct volume_group *_vg_read_file_name(struct format_instance *fid,
const char *vgname,
- const char *path_live)
+ const char *read_path)
{
struct volume_group *vg;
time_t when;
char *desc;
- if (!(vg = text_vg_import_file(fid, path_live, &when, &desc))) {
+ if (!(vg = text_vg_import_file(fid, read_path, &when, &desc))) {
stack;
return NULL;
}
@@ -565,10 +597,10 @@
if (vgname && strcmp(vgname, vg->name)) {
pool_free(fid->fmt->cmd->mem, vg);
log_err("'%s' does not contain volume group '%s'.",
- path_live, vgname);
+ read_path, vgname);
return NULL;
} else
- log_debug("Read volume group %s from %s", vg->name, path_live);
+ log_debug("Read volume group %s from %s", vg->name, read_path);
return vg;
}
@@ -582,6 +614,15 @@
return _vg_read_file_name(fid, vgname, tc->path_live);
}
+static struct volume_group *_vg_read_precommit_file(struct format_instance *fid,
+ const char *vgname,
+ struct metadata_area *mda)
+{
+ struct text_context *tc = (struct text_context *) mda->metadata_locn;
+
+ return _vg_read_file_name(fid, vgname, tc->path_edit);
+}
+
static int _vg_write_file(struct format_instance *fid, struct volume_group *vg,
struct metadata_area *mda)
{
@@ -737,7 +778,7 @@
{
struct dirent *dirent;
struct dir_list *dl;
- struct list *dlh, *dir_list;
+ struct list *dir_list;
char *tmp;
DIR *d;
struct volume_group *vg;
@@ -747,8 +788,7 @@
dir_list = &((struct mda_lists *) fmt->private)->dirs;
- list_iterate(dlh, dir_list) {
- dl = list_item(dlh, struct dir_list);
+ list_iterate_items(dl, dir_list) {
if (!(d = opendir(dl->dir))) {
log_sys_error("opendir", dl->dir);
continue;
@@ -836,7 +876,7 @@
static int _scan_raw(const struct format_type *fmt)
{
struct raw_list *rl;
- struct list *rlh, *raw_list;
+ struct list *raw_list;
char vgnamebuf[NAME_LEN + 2];
struct volume_group *vg;
struct format_instance fid;
@@ -846,14 +886,12 @@
fid.fmt = fmt;
list_init(&fid.metadata_areas);
- list_iterate(rlh, raw_list) {
- rl = list_item(rlh, struct raw_list);
-
+ list_iterate_items(rl, raw_list) {
/* FIXME We're reading mdah twice here... */
if (vgname_from_mda(fmt, &rl->dev_area, vgnamebuf,
sizeof(vgnamebuf))) {
if ((vg = _vg_read_raw_area(&fid, vgnamebuf,
- &rl->dev_area)))
+ &rl->dev_area, 0)))
lvmcache_update_vg(vg);
}
}
@@ -878,6 +916,7 @@
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();
if (!pvmetadatacopies) {
/* Space available for PEs */
@@ -905,10 +944,21 @@
/* Place mda straight after label area at start of disk */
start1 = LABEL_SCAN_SIZE;
+ /* Unless the space available is tiny, round to PAGE_SIZE boundary */
+ if ((!pe_start && !pe_end) ||
+ ((pe_start > start1) && (pe_start - start1 >= MDA_SIZE_MIN))) {
+ mda_adjustment = start1 % pagesize;
+ if (mda_adjustment) {
+ start1 += (pagesize - mda_adjustment);
+ pv->size -= ((pagesize - mda_adjustment) >>
+ SECTOR_SHIFT);
+ }
+ }
+
/* Ensure it's not going to be bigger than the disk! */
- if (mda_size1 > disk_size) {
- log_print("Warning: metadata area fills disk %s",
- dev_name(pv->dev));
+ if (start1 + mda_size1 > disk_size) {
+ log_print("Warning: metadata area fills disk leaving no "
+ "space for data on %s.", dev_name(pv->dev));
/* Leave some free space for rounding */
/* Avoid empty data area as could cause tools problems */
mda_size1 = disk_size - start1 - alignment * 2;
@@ -1001,7 +1051,6 @@
struct label *label;
struct lvmcache_info *info;
struct mda_context *mdac;
- struct list *mdash;
struct metadata_area *mda;
char buf[MDA_HEADER_SIZE];
struct mda_header *mdah = (struct mda_header *) buf;
@@ -1029,8 +1078,7 @@
del_mdas(&info->mdas);
else
list_init(&info->mdas);
- list_iterate(mdash, mdas) {
- mda = list_item(mdash, struct metadata_area);
+ list_iterate_items(mda, mdas) {
mdac = mda->metadata_locn;
log_debug("Creating metadata area on %s at sector %"
PRIu64 " size %" PRIu64 " sectors",
@@ -1053,8 +1101,7 @@
/* Set pe_start to first aligned sector after any metadata
* areas that begin before pe_start */
pv->pe_start = PE_ALIGN;
- list_iterate(mdash, &info->mdas) {
- mda = list_item(mdash, struct metadata_area);
+ 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)) &&
@@ -1078,8 +1125,7 @@
return 0;
}
- list_iterate(mdash, &info->mdas) {
- mda = list_item(mdash, struct metadata_area);
+ list_iterate_items(mda, &info->mdas) {
mdac = mda->metadata_locn;
memset(&buf, 0, sizeof(buf));
mdah->size = mdac->area.size;
@@ -1102,45 +1148,16 @@
return 1;
}
-static int _get_pv_from_vg(const struct format_type *fmt, const char *vg_name,
- const char *id, struct physical_volume *pv)
-{
- struct volume_group *vg;
- struct list *pvh;
- struct pv_list *pvl;
- int consistent = 0;
-
- if (!(vg = vg_read(fmt->cmd, vg_name, &consistent))) {
- log_error("format_text: _vg_read failed to read VG %s",
- vg_name);
- return 0;
- }
-
- if (!consistent)
- log_error("Warning: Volume group %s is not consistent",
- vg_name);
-
- list_iterate(pvh, &vg->pvs) {
- pvl = list_item(pvh, struct pv_list);
- if (id_equal(&pvl->pv->id, (const struct id *) id)) {
- memcpy(pv, pvl->pv, sizeof(*pv));
- return 1;
- }
- }
- return 0;
-}
-
static int _add_raw(struct list *raw_list, struct device_area *dev_area)
{
struct raw_list *rl;
- struct list *rlh;
/* Already present? */
- list_iterate(rlh, raw_list) {
- rl = list_item(rlh, struct raw_list);
+ list_iterate_items(rl, raw_list) {
/* FIXME Check size/overlap consistency too */
if (rl->dev_area.dev == dev_area->dev &&
- rl->dev_area.start == dev_area->start) return 1;
+ rl->dev_area.start == dev_area->start)
+ return 1;
}
if (!(rl = dbg_malloc(sizeof(struct raw_list)))) {
@@ -1161,7 +1178,6 @@
struct lvmcache_info *info;
struct metadata_area *mda, *mda_new;
struct mda_context *mdac, *mdac_new;
- struct list *mdah, *dah;
struct data_area_list *da;
if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter))) {
@@ -1178,19 +1194,19 @@
/* Have we already cached vgname? */
if (info->vginfo && info->vginfo->vgname && *info->vginfo->vgname &&
- _get_pv_from_vg(info->fmt, info->vginfo->vgname, info->dev->pvid,
- pv)) {
+ get_pv_from_vg_by_id(info->fmt, info->vginfo->vgname,
+ info->dev->pvid, pv)) {
return 1;
}
- /* Perform full scan and try again */
- if (!memlock()) {
- lvmcache_label_scan(fmt->cmd, 1);
+ /* Perform full scan (just the first time) and try again */
+ if (!memlock() && !full_scan_done()) {
+ lvmcache_label_scan(fmt->cmd, 2);
if (info->vginfo && info->vginfo->vgname &&
*info->vginfo->vgname &&
- _get_pv_from_vg(info->fmt, info->vginfo->vgname,
- info->dev->pvid, pv)) {
+ get_pv_from_vg_by_id(info->fmt, info->vginfo->vgname,
+ info->dev->pvid, pv)) {
return 1;
}
}
@@ -1208,17 +1224,15 @@
list_size(&info->das), dev_name(dev));
return 0;
}
- list_iterate(dah, &info->das) {
- da = list_item(dah, struct data_area_list);
+
+ list_iterate_items(da, &info->das)
pv->pe_start = da->disk_locn.offset >> SECTOR_SHIFT;
- }
if (!mdas)
return 1;
/* Add copy of mdas to supplied list */
- list_iterate(mdah, &info->mdas) {
- mda = list_item(mdah, struct metadata_area);
+ list_iterate_items(mda, &info->mdas) {
mdac = (struct mda_context *) mda->metadata_locn;
if (!(mda_new = pool_alloc(fmt->cmd->mem, sizeof(*mda_new)))) {
log_error("metadata_area allocation failed");
@@ -1275,6 +1289,7 @@
static struct metadata_area_ops _metadata_text_file_ops = {
vg_read:_vg_read_file,
+ vg_read_precommit:_vg_read_precommit_file,
vg_write:_vg_write_file,
vg_remove:_vg_remove_file,
vg_commit:_vg_commit_file
@@ -1289,8 +1304,10 @@
static struct metadata_area_ops _metadata_text_raw_ops = {
vg_read:_vg_read_raw,
+ vg_read_precommit:_vg_read_precommit_raw,
vg_write:_vg_write_raw,
vg_remove:_vg_remove_raw,
+ vg_precommit:_vg_precommit_raw,
vg_commit:_vg_commit_raw,
vg_revert:_vg_revert_raw
};
@@ -1305,7 +1322,7 @@
{
struct metadata_area *mda, *mda_new, *mda2;
struct mda_context *mdac, *mdac_new, *mdac2;
- struct list *pvmdas, *pvmdash, *mdash;
+ struct list *pvmdas;
struct lvmcache_info *info;
int found;
uint64_t pe_end = 0;
@@ -1320,8 +1337,7 @@
/* Iterate through all mdas on this PV */
if ((info = info_from_pvid(pv->dev->pvid))) {
pvmdas = &info->mdas;
- list_iterate(pvmdash, pvmdas) {
- mda = list_item(pvmdash, struct metadata_area);
+ list_iterate_items(mda, pvmdas) {
mdac =
(struct mda_context *) mda->metadata_locn;
@@ -1329,10 +1345,7 @@
/* Ensure it isn't already on list */
found = 0;
- list_iterate(mdash, mdas) {
- mda2 =
- list_item(mdash,
- struct metadata_area);
+ list_iterate_items(mda2, mdas) {
if (mda2->ops !=
&_metadata_text_raw_ops) continue;
mdac2 =
@@ -1394,9 +1407,10 @@
struct mda_context *mdac, *mdac_new;
struct dir_list *dl;
struct raw_list *rl;
- struct list *dlh, *dir_list, *rlh, *raw_list, *mdas, *mdash, *infoh;
+ struct list *dir_list, *raw_list, *mdas;
char path[PATH_MAX];
struct lvmcache_vginfo *vginfo;
+ struct lvmcache_info *info;
if (!(fid = pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
log_error("Couldn't allocate format instance object.");
@@ -1418,8 +1432,7 @@
} else {
dir_list = &((struct mda_lists *) fmt->private)->dirs;
- list_iterate(dlh, dir_list) {
- dl = list_item(dlh, struct dir_list);
+ list_iterate_items(dl, dir_list) {
if (lvm_snprintf(path, PATH_MAX, "%s/%s",
dl->dir, vgname) < 0) {
log_error("Name too long %s/%s", dl->dir,
@@ -1439,9 +1452,7 @@
raw_list = &((struct mda_lists *) fmt->private)->raws;
- list_iterate(rlh, raw_list) {
- rl = list_item(rlh, struct raw_list);
-
+ list_iterate_items(rl, raw_list) {
/* FIXME Cache this; rescan below if some missing */
if (!_raw_holds_vgname(fid, &rl->dev_area, vgname))
continue;
@@ -1469,10 +1480,9 @@
stack;
goto out;
}
- list_iterate(infoh, &vginfo->infos) {
- mdas = &(list_item(infoh, struct lvmcache_info)->mdas);
- list_iterate(mdash, mdas) {
- mda = list_item(mdash, struct metadata_area);
+ list_iterate_items(info, &vginfo->infos) {
+ mdas = &info->mdas;
+ list_iterate_items(mda, mdas) {
mdac =
(struct mda_context *) mda->metadata_locn;
@@ -1646,7 +1656,8 @@
fmt->ops = &_text_handler;
fmt->name = FMT_TEXT_NAME;
fmt->alias = FMT_TEXT_ALIAS;
- fmt->features = FMT_SEGMENTS | FMT_MDAS | FMT_TAGS | FMT_UNLIMITED_VOLS;
+ fmt->features = FMT_SEGMENTS | FMT_MDAS | FMT_TAGS | FMT_PRECOMMIT |
+ FMT_UNLIMITED_VOLS;
if (!(mda_lists = dbg_malloc(sizeof(struct mda_lists)))) {
log_error("Failed to allocate dir_list");
Modified: lvm2/upstream/current/lib/format_text/import-export.h
==============================================================================
--- lvm2/upstream/current/lib/format_text/import-export.h (original)
+++ lvm2/upstream/current/lib/format_text/import-export.h Tue Jun 14 11:13:22 2005
@@ -59,8 +59,7 @@
int read_tags(struct pool *mem, struct list *tags, struct config_value *cv);
int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp);
-int text_vg_export_raw(struct volume_group *vg, const char *desc, char *buf,
- uint32_t size);
+int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf);
struct volume_group *text_vg_import_file(struct format_instance *fid,
const char *file,
time_t *when, char **desc);
Modified: lvm2/upstream/current/lib/format_text/import_vsn1.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/import_vsn1.c (original)
+++ lvm2/upstream/current/lib/format_text/import_vsn1.c Tue Jun 14 11:13:22 2005
@@ -22,6 +22,7 @@
#include "toolcontext.h"
#include "lvmcache.h"
#include "lv_alloc.h"
+#include "pv_alloc.h"
#include "segtype.h"
#include "text_import.h"
@@ -31,7 +32,7 @@
struct hash_table * pv_hash);
#define _read_int32(root, path, result) \
- get_config_uint32(root, path, result)
+ get_config_uint32(root, path, (uint32_t *) result)
#define _read_uint32(root, path, result) \
get_config_uint32(root, path, result)
@@ -190,6 +191,7 @@
}
list_init(&pv->tags);
+ list_init(&pv->segments);
/* Optional tags */
if ((cn = find_config_node(pvn, "tags")) &&
@@ -208,6 +210,11 @@
pv->pe_alloc_count = 0;
pv->fmt = fid->fmt;
+ if (!alloc_pv_segment_whole_pv(mem, pv)) {
+ stack;
+ return 0;
+ }
+
vg->pv_count++;
list_add(&vg->pvs, &pvl->list);
@@ -216,12 +223,9 @@
static void _insert_segment(struct logical_volume *lv, struct lv_segment *seg)
{
- struct list *segh;
struct lv_segment *comp;
- list_iterate(segh, &lv->segments) {
- comp = list_item(segh, struct lv_segment);
-
+ list_iterate_items(comp, &lv->segments) {
if (comp->le > seg->le) {
list_add(&comp->list, &seg->list);
return;
@@ -283,19 +287,13 @@
return 0;
}
- if (!(seg = alloc_lv_segment(mem, area_count))) {
+ if (!(seg = alloc_lv_segment(mem, segtype, lv, start_extent,
+ extent_count, 0, 0, NULL, area_count,
+ extent_count, 0, 0, 0))) {
log_error("Segment allocation failed");
return 0;
}
- seg->lv = lv;
- seg->le = start_extent;
- seg->len = extent_count;
- seg->area_len = extent_count;
- seg->status = 0u;
- seg->segtype = segtype;
- seg->extents_copied = 0u;
-
if (seg->segtype->ops->text_import &&
!seg->segtype->ops->text_import(seg, sn, pv_hash)) {
stack;
@@ -315,17 +313,18 @@
*/
_insert_segment(lv, seg);
- if (seg->segtype->flags & SEG_AREAS_MIRRORED)
+ if (seg_is_mirrored(seg))
lv->status |= MIRRORED;
- if (seg->segtype->flags & SEG_VIRTUAL)
+ if (seg_is_virtual(seg))
lv->status |= VIRTUAL;
return 1;
}
int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
- const struct config_node *cn, struct hash_table *pv_hash)
+ const struct config_node *cn, struct hash_table *pv_hash,
+ uint32_t flags)
{
unsigned int s;
struct config_value *cv;
@@ -361,19 +360,17 @@
/* FIXME Cope if LV not yet read in */
if ((pv = hash_lookup(pv_hash, cv->v.str))) {
- seg->area[s].type = AREA_PV;
- seg->area[s].u.pv.pv = pv;
- seg->area[s].u.pv.pe = cv->next->v.i;
+ if (!set_lv_segment_area_pv(seg, s, pv, cv->next->v.i)) {
+ stack;
+ return 0;
+ }
/*
* Adjust extent counts in the pv and vg.
*/
- pv->pe_alloc_count += seg->area_len;
seg->lv->vg->free_count -= seg->area_len;
-
} else if ((lv1 = find_lv(seg->lv->vg, cv->v.str))) {
- seg->area[s].type = AREA_LV;
- seg->area[s].u.lv.lv = lv1;
- seg->area[s].u.lv.le = cv->next->v.i;
+ set_lv_segment_area_lv(seg, s, lv1, cv->next->v.i,
+ flags);
} else {
log_error("Couldn't find volume '%s' "
"for segment '%s'.",
@@ -437,7 +434,7 @@
/*
* Check there are no gaps or overlaps in the lv.
*/
- if (!lv_check_segments(lv)) {
+ if (!check_lv_segments(lv)) {
stack;
return 0;
}
@@ -508,6 +505,8 @@
if (!_read_int32(lvn, "read_ahead", &lv->read_ahead))
lv->read_ahead = 0;
+ lv->snapshot = NULL;
+ list_init(&lv->snapshot_segs);
list_init(&lv->segments);
list_init(&lv->tags);
@@ -561,24 +560,29 @@
lv->size = (uint64_t) lv->le_count * (uint64_t) vg->extent_size;
- /* Skip this for now for snapshots */
- if (!(lv->status & SNAPSHOT)) {
- lv->minor = -1;
- if ((lv->status & FIXED_MINOR) &&
- !_read_int32(lvn, "minor", &lv->minor)) {
- log_error("Couldn't read minor number for logical "
- "volume %s.", lv->name);
- return 0;
- }
- lv->major = -1;
- if ((lv->status & FIXED_MINOR) &&
- !_read_int32(lvn, "major", &lv->major)) {
- log_error("Couldn't read major number for logical "
- "volume %s.", lv->name);
- }
- } else {
+ /*
+ * FIXME We now have 2 LVs for each snapshot. The real one was
+ * created by vg_add_snapshot from the segment text_import.
+ */
+ if (lv->status & SNAPSHOT) {
vg->lv_count--;
list_del(&lvl->list);
+ return 1;
+ }
+
+ lv->minor = -1;
+ if ((lv->status & FIXED_MINOR) &&
+ !_read_int32(lvn, "minor", &lv->minor)) {
+ log_error("Couldn't read minor number for logical "
+ "volume %s.", lv->name);
+ return 0;
+ }
+
+ lv->major = -1;
+ if ((lv->status & FIXED_MINOR) &&
+ !_read_int32(lvn, "major", &lv->major)) {
+ log_error("Couldn't read major number for logical "
+ "volume %s.", lv->name);
}
return 1;
@@ -736,7 +740,6 @@
}
list_init(&vg->lvs);
- list_init(&vg->snapshots);
list_init(&vg->tags);
/* Optional tags */
Modified: lvm2/upstream/current/lib/format_text/layout.h
==============================================================================
--- lvm2/upstream/current/lib/format_text/layout.h (original)
+++ lvm2/upstream/current/lib/format_text/layout.h Tue Jun 14 11:13:22 2005
@@ -81,5 +81,6 @@
#define FMTT_VERSION 1
#define MDA_HEADER_SIZE 512
#define LVM2_LABEL "LVM2 001"
+#define MDA_SIZE_MIN (8 * getpagesize())
#endif
Modified: lvm2/upstream/current/lib/format_text/text_export.h
==============================================================================
--- lvm2/upstream/current/lib/format_text/text_export.h (original)
+++ lvm2/upstream/current/lib/format_text/text_export.h Tue Jun 14 11:13:22 2005
@@ -17,6 +17,7 @@
#define _LVM_TEXT_EXPORT_H
#define outf(args...) do {if (!out_text(args)) {stack; return 0;}} while (0)
+#define outnl(f) do {if (!f->nl(f)) {stack; return 0;}} while (0)
struct formatter;
struct lv_segment;
Modified: lvm2/upstream/current/lib/format_text/text_import.h
==============================================================================
--- lvm2/upstream/current/lib/format_text/text_import.h (original)
+++ lvm2/upstream/current/lib/format_text/text_import.h Tue Jun 14 11:13:22 2005
@@ -20,6 +20,7 @@
struct config_node;
int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
- const struct config_node *cn, struct hash_table *pv_hash);
+ const struct config_node *cn, struct hash_table *pv_hash,
+ uint32_t flags);
#endif
Modified: lvm2/upstream/current/lib/format_text/text_label.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/text_label.c (original)
+++ lvm2/upstream/current/lib/format_text/text_label.c Tue Jun 14 11:13:22 2005
@@ -39,7 +39,6 @@
struct pv_header *pvhdr;
struct lvmcache_info *info;
struct disk_locn *pvh_dlocn_xl;
- struct list *mdash, *dash;
struct metadata_area *mda;
struct mda_context *mdac;
struct data_area_list *da;
@@ -57,9 +56,7 @@
pvh_dlocn_xl = &pvhdr->disk_areas_xl[0];
/* List of data areas (holding PEs) */
- list_iterate(dash, &info->das) {
- da = list_item(dash, struct data_area_list);
-
+ list_iterate_items(da, &info->das) {
pvh_dlocn_xl->offset = xlate64(da->disk_locn.offset);
pvh_dlocn_xl->size = xlate64(da->disk_locn.size);
pvh_dlocn_xl++;
@@ -71,8 +68,7 @@
pvh_dlocn_xl++;
/* List of metadata area header locations */
- list_iterate(mdash, &info->mdas) {
- mda = list_item(mdash, struct metadata_area);
+ list_iterate_items(mda, &info->mdas) {
mdac = (struct mda_context *) mda->metadata_locn;
if (mdac->area.dev != info->dev)
@@ -198,7 +194,6 @@
struct lvmcache_info *info;
struct disk_locn *dlocn_xl;
uint64_t offset;
- struct list *mdah;
struct metadata_area *mda;
char vgnamebuf[NAME_LEN + 2];
struct mda_context *mdac;
@@ -235,8 +230,7 @@
dlocn_xl++;
}
- list_iterate(mdah, &info->mdas) {
- mda = list_item(mdah, struct metadata_area);
+ list_iterate_items(mda, &info->mdas) {
mdac = (struct mda_context *) mda->metadata_locn;
if (vgname_from_mda(info->fmt, &mdac->area, vgnamebuf,
sizeof(vgnamebuf))) {
Modified: lvm2/upstream/current/lib/label/label.c
==============================================================================
--- lvm2/upstream/current/lib/label/label.c (original)
+++ lvm2/upstream/current/lib/label/label.c Tue Jun 14 11:13:22 2005
@@ -98,14 +98,11 @@
struct labeller *label_get_handler(const char *name)
{
- struct list *lih;
struct labeller_i *li;
- list_iterate(lih, &_labellers) {
- li = list_item(lih, struct labeller_i);
+ list_iterate_items(li, &_labellers)
if (!strcmp(li->name, name))
return li->l;
- }
return NULL;
}
@@ -113,16 +110,20 @@
static struct labeller *_find_labeller(struct device *dev, char *buf,
uint64_t *label_sector)
{
- struct list *lih;
struct labeller_i *li;
struct labeller *r = NULL;
struct label_header *lh;
+ struct lvmcache_info *info;
uint64_t sector;
int found = 0;
char readbuf[LABEL_SCAN_SIZE];
if (!dev_open(dev)) {
stack;
+
+ if ((info = info_from_pvid(dev->pvid)))
+ lvmcache_update_vgname(info, ORPHAN);
+
return NULL;
}
@@ -161,8 +162,7 @@
continue;
}
- list_iterate(lih, &_labellers) {
- li = list_item(lih, struct labeller_i);
+ list_iterate_items(li, &_labellers) {
if (li->l->ops->can_handle(li->l, (char *) lh, sector)) {
log_very_verbose("%s: %s label detected",
dev_name(dev), li->name);
@@ -182,10 +182,13 @@
}
}
- if (!found)
+ out:
+ if (!found) {
+ if ((info = info_from_pvid(dev->pvid)))
+ lvmcache_update_vgname(info, ORPHAN);
log_very_verbose("%s: No label detected", dev_name(dev));
+ }
- out:
if (!dev_close(dev))
stack;
@@ -200,7 +203,6 @@
int r = 1;
uint64_t sector;
int wipe;
- struct list *lih;
struct labeller_i *li;
struct label_header *lh;
@@ -236,8 +238,7 @@
if (xlate64(lh->sector_xl) == sector)
wipe = 1;
} else {
- list_iterate(lih, &_labellers) {
- li = list_item(lih, struct labeller_i);
+ list_iterate_items(li, &_labellers) {
if (li->l->ops->can_handle(li->l, (char *) lh,
sector)) {
wipe = 1;
@@ -279,7 +280,7 @@
return 0;
}
- if ((r = l->ops->read(l, dev, buf, result)) && result && *result)
+ if ((r = (l->ops->read)(l, dev, buf, result)) && result && *result)
(*result)->sector = sector;
return r;
@@ -309,7 +310,7 @@
lh->sector_xl = xlate64(label->sector);
lh->offset_xl = xlate32(sizeof(*lh));
- if (!label->labeller->ops->write(label, buf)) {
+ if (!(label->labeller->ops->write)(label, buf)) {
stack;
return 0;
}
Modified: lvm2/upstream/current/lib/locking/cluster_locking.c
==============================================================================
--- lvm2/upstream/current/lib/locking/cluster_locking.c (original)
+++ lvm2/upstream/current/lib/locking/cluster_locking.c Tue Jun 14 11:13:22 2005
@@ -446,7 +446,7 @@
locking->lock_resource = _lock_resource;
locking->fin_locking = _locking_end;
locking->reset_locking = _reset_locking;
- locking->flags = LCK_PRE_MEMLOCK;
+ locking->flags = LCK_PRE_MEMLOCK | LCK_CLUSTERED;
_clvmd_sock = _open_local_sock();
if (_clvmd_sock == -1)
@@ -463,6 +463,7 @@
/* Ask LVM to lock memory before calling us */
*flags |= LCK_PRE_MEMLOCK;
+ *flags |= LCK_CLUSTERED;
return 1;
}
Modified: lvm2/upstream/current/lib/locking/file_locking.c
==============================================================================
--- lvm2/upstream/current/lib/locking/file_locking.c (original)
+++ lvm2/upstream/current/lib/locking/file_locking.c Tue Jun 14 11:13:22 2005
@@ -41,7 +41,7 @@
static sig_t _oldhandler;
static sigset_t _fullsigset, _intsigset;
-static int _handler_installed;
+static volatile sig_atomic_t _handler_installed;
static int _release_lock(const char *file, int unlock)
{
@@ -95,38 +95,40 @@
static void _remove_ctrl_c_handler()
{
siginterrupt(SIGINT, 0);
- if (!_handler_installed || _oldhandler == SIG_ERR)
+ if (!_handler_installed)
return;
+ _handler_installed = 0;
+
sigprocmask(SIG_SETMASK, &_fullsigset, NULL);
if (signal(SIGINT, _oldhandler) == SIG_ERR)
log_sys_error("signal", "_remove_ctrl_c_handler");
-
- _handler_installed = 0;
}
static void _trap_ctrl_c(int sig)
{
_remove_ctrl_c_handler();
log_error("CTRL-c detected: giving up waiting for lock");
- return;
}
static void _install_ctrl_c_handler()
{
- if ((_oldhandler = signal(SIGINT, _trap_ctrl_c)) == SIG_ERR)
+ _handler_installed = 1;
+
+ if ((_oldhandler = signal(SIGINT, _trap_ctrl_c)) == SIG_ERR) {
+ _handler_installed = 0;
return;
+ }
sigprocmask(SIG_SETMASK, &_intsigset, NULL);
siginterrupt(SIGINT, 1);
-
- _handler_installed = 1;
}
static int _lock_file(const char *file, int flags)
{
int operation;
int r = 1;
+ int old_errno;
struct lock_list *ll;
struct stat buf1, buf2;
@@ -176,10 +178,12 @@
_install_ctrl_c_handler();
r = flock(ll->lf, operation);
+ old_errno = errno;
if (!(flags & LCK_NONBLOCK))
_remove_ctrl_c_handler();
if (r) {
+ errno = old_errno;
log_sys_error("flock", ll->res);
goto err;
}
Modified: lvm2/upstream/current/lib/locking/locking.c
==============================================================================
--- lvm2/upstream/current/lib/locking/locking.c (original)
+++ lvm2/upstream/current/lib/locking/locking.c Tue Jun 14 11:13:22 2005
@@ -124,6 +124,8 @@
*/
int init_locking(int type, struct config_tree *cft)
{
+ init_lockingfailed(0);
+
switch (type) {
case 0:
init_no_locking(&_locking, cft);
@@ -165,6 +167,7 @@
log_verbose("Locking disabled - only read operations permitted.");
init_no_locking(&_locking, cft);
+ init_lockingfailed(1);
return 1;
}
@@ -262,13 +265,10 @@
/* Unlock list of LVs */
int resume_lvs(struct cmd_context *cmd, struct list *lvs)
{
- struct list *lvh;
- struct logical_volume *lv;
+ struct lv_list *lvl;
- list_iterate(lvh, lvs) {
- lv = list_item(lvh, struct lv_list)->lv;
- resume_lv(cmd, lv->lvid.s);
- }
+ list_iterate_items(lvl, lvs)
+ resume_lv(cmd, lvl->lv->lvid.s);
return 1;
}
@@ -277,15 +277,14 @@
int suspend_lvs(struct cmd_context *cmd, struct list *lvs)
{
struct list *lvh;
- struct logical_volume *lv;
+ struct lv_list *lvl;
- list_iterate(lvh, lvs) {
- lv = list_item(lvh, struct lv_list)->lv;
- if (!suspend_lv(cmd, lv->lvid.s)) {
- log_error("Failed to suspend %s", lv->name);
- list_uniterate(lvh, lvs, lvh) {
- lv = list_item(lvh, struct lv_list)->lv;
- resume_lv(cmd, lv->lvid.s);
+ list_iterate_items(lvl, lvs) {
+ if (!suspend_lv(cmd, lvl->lv->lvid.s)) {
+ log_error("Failed to suspend %s", lvl->lv->name);
+ list_uniterate(lvh, lvs, &lvl->list) {
+ lvl = list_item(lvh, struct lv_list);
+ resume_lv(cmd, lvl->lv->lvid.s);
}
return 0;
@@ -299,15 +298,14 @@
int activate_lvs_excl(struct cmd_context *cmd, struct list *lvs)
{
struct list *lvh;
- struct logical_volume *lv;
+ struct lv_list *lvl;
- list_iterate(lvh, lvs) {
- lv = list_item(lvh, struct lv_list)->lv;
- if (!activate_lv_excl(cmd, lv->lvid.s)) {
- log_error("Failed to activate %s", lv->name);
- list_uniterate(lvh, lvs, lvh) {
- lv = list_item(lvh, struct lv_list)->lv;
- activate_lv(cmd, lv->lvid.s);
+ list_iterate_items(lvl, lvs) {
+ if (!activate_lv_excl(cmd, lvl->lv->lvid.s)) {
+ log_error("Failed to activate %s", lvl->lv->name);
+ list_uniterate(lvh, lvs, &lvl->list) {
+ lvl = list_item(lvh, struct lv_list);
+ activate_lv(cmd, lvl->lv->lvid.s);
}
return 0;
@@ -321,3 +319,9 @@
{
return _vg_write_lock_held;
}
+
+int locking_is_clustered(void)
+{
+ return (_locking.flags & LCK_CLUSTERED) ? 1 : 0;
+}
+
Modified: lvm2/upstream/current/lib/locking/locking.h
==============================================================================
--- lvm2/upstream/current/lib/locking/locking.h (original)
+++ lvm2/upstream/current/lib/locking/locking.h Tue Jun 14 11:13:22 2005
@@ -20,6 +20,7 @@
void fin_locking(void);
void reset_locking(void);
int vg_write_lock_held(void);
+int locking_is_clustered(void);
/*
* LCK_VG:
Modified: lvm2/upstream/current/lib/locking/locking_types.h
==============================================================================
--- lvm2/upstream/current/lib/locking/locking_types.h (original)
+++ lvm2/upstream/current/lib/locking/locking_types.h Tue Jun 14 11:13:22 2005
@@ -23,6 +23,7 @@
typedef void (*reset_lock_fn) (void);
#define LCK_PRE_MEMLOCK 0x00000001 /* Is memlock() needed before calls? */
+#define LCK_CLUSTERED 0x00000002
struct locking_type {
uint32_t flags;
@@ -40,4 +41,5 @@
int init_file_locking(struct locking_type *locking, struct config_tree *cf);
int init_external_locking(struct locking_type *locking, struct config_tree *cf);
+
int init_cluster_locking(struct locking_type *locking, struct config_tree *cf);
Modified: lvm2/upstream/current/lib/log/log.c
==============================================================================
--- lvm2/upstream/current/lib/log/log.c (original)
+++ lvm2/upstream/current/lib/log/log.c Tue Jun 14 11:13:22 2005
@@ -30,6 +30,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 _debug_level = 0;
static int _syslog = 0;
static int _log_to_file = 0;
@@ -39,6 +40,7 @@
static int _log_cmd_name = 0;
static int _log_suppress = 0;
static int _ignorelockingfailure = 0;
+static int _lockingfailed = 0;
static int _security_level = SECURITY_LEVEL;
static char _cmd_name[30] = "";
static char _msg_prefix[30] = " ";
@@ -70,7 +72,7 @@
{
int open_flags = append ? 0 : O_TRUNC;
- dev_create_file(log_file, &_log_dev, &_log_dev_alias);
+ dev_create_file(log_file, &_log_dev, &_log_dev_alias, 1);
if (!dev_open_flags(&_log_dev, O_RDWR | O_CREAT | open_flags, 1, 0))
return;
@@ -149,11 +151,21 @@
_pvmove = level;
}
+void init_full_scan_done(int level)
+{
+ _full_scan_done = level;
+}
+
void init_ignorelockingfailure(int level)
{
_ignorelockingfailure = level;
}
+void init_lockingfailed(int level)
+{
+ _lockingfailed = level;
+}
+
void init_security_level(int level)
{
_security_level = level;
@@ -203,6 +215,16 @@
return _pvmove;
}
+int full_scan_done()
+{
+ return _full_scan_done;
+}
+
+int lockingfailed()
+{
+ return _lockingfailed;
+}
+
int ignorelockingfailure()
{
return _ignorelockingfailure;
Modified: lvm2/upstream/current/lib/log/log.h
==============================================================================
--- lvm2/upstream/current/lib/log/log.h (original)
+++ lvm2/upstream/current/lib/log/log.h Tue Jun 14 11:13:22 2005
@@ -65,11 +65,13 @@
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_debug(int level);
void init_cmd_name(int status);
void init_msg_prefix(const char *prefix);
void init_indent(int indent);
void init_ignorelockingfailure(int level);
+void init_lockingfailed(int level);
void init_security_level(int level);
void set_cmd_name(const char *cmd_name);
@@ -78,8 +80,10 @@
int partial_mode(void);
int md_filtering(void);
int pvmove_mode(void);
+int full_scan_done(void);
int debug_level(void);
int ignorelockingfailure(void);
+int lockingfailed(void);
int security_level(void);
/* Suppress messages to stdout/stderr */
Modified: lvm2/upstream/current/lib/metadata/lv_alloc.h
==============================================================================
--- lvm2/upstream/current/lib/metadata/lv_alloc.h (original)
+++ lvm2/upstream/current/lib/metadata/lv_alloc.h Tue Jun 14 11:13:22 2005
@@ -16,5 +16,64 @@
#ifndef _LVM_LV_ALLOC_H
#include "pool.h"
-struct lv_segment *alloc_lv_segment(struct pool *mem, uint32_t num_areas);
+struct lv_segment *alloc_lv_segment(struct pool *mem,
+ struct segment_type *segtype,
+ struct logical_volume *lv,
+ uint32_t le, uint32_t len,
+ uint32_t status,
+ uint32_t stripe_size,
+ struct logical_volume *log_lv,
+ uint32_t area_count,
+ uint32_t area_len,
+ uint32_t chunk_size,
+ uint32_t region_size,
+ uint32_t extents_copied);
+
+struct lv_segment *alloc_snapshot_seg(struct logical_volume *lv,
+ uint32_t status, uint32_t old_le_count);
+
+int set_lv_segment_area_pv(struct lv_segment *seg, uint32_t area_num,
+ struct physical_volume *pv, uint32_t pe);
+void set_lv_segment_area_lv(struct lv_segment *seg, uint32_t area_num,
+ struct logical_volume *lv, uint32_t le,
+ uint32_t flags);
+
+struct alloc_handle;
+struct alloc_handle *allocate_extents(struct volume_group *vg,
+ struct logical_volume *lv,
+ struct segment_type *segtype,
+ uint32_t stripes,
+ uint32_t mirrors, uint32_t log_count,
+ uint32_t extents,
+ struct physical_volume *mirrored_pv,
+ uint32_t mirrored_pe,
+ uint32_t status,
+ struct list *allocatable_pvs,
+ alloc_policy_t alloc);
+
+int lv_add_segment(struct alloc_handle *ah,
+ uint32_t first_area, uint32_t num_areas,
+ struct logical_volume *lv,
+ struct segment_type *segtype,
+ uint32_t stripe_size,
+ struct physical_volume *mirrored_pv,
+ uint32_t mirrored_pe,
+ uint32_t status,
+ uint32_t region_size,
+ struct logical_volume *log_lv);
+
+int lv_add_log_segment(struct alloc_handle *ah, struct logical_volume *log_lv);
+int lv_add_virtual_segment(struct logical_volume *lv, uint32_t status,
+ uint32_t extents, struct segment_type *segtype);
+int lv_add_mirror_segment(struct alloc_handle *ah,
+ struct logical_volume *lv,
+ struct logical_volume **sub_lvs,
+ uint32_t mirrors,
+ struct segment_type *segtype,
+ uint32_t status,
+ uint32_t region_size,
+ struct logical_volume *log_lv);
+
+void alloc_destroy(struct alloc_handle *ah);
+
#endif
Modified: lvm2/upstream/current/lib/metadata/lv_manip.c
==============================================================================
--- lvm2/upstream/current/lib/metadata/lv_manip.c (original)
+++ lvm2/upstream/current/lib/metadata/lv_manip.c Tue Jun 14 11:13:22 2005
@@ -20,514 +20,1020 @@
#include "lvm-string.h"
#include "toolcontext.h"
#include "lv_alloc.h"
+#include "pv_alloc.h"
#include "display.h"
#include "segtype.h"
/*
- * These functions adjust the pe counts in pv's
- * after we've added or removed segments.
+ * Find first unused LV number.
*/
-static void _get_extents(struct lv_segment *seg)
+uint32_t find_free_lvnum(struct logical_volume *lv)
{
- unsigned int s, count;
- struct physical_volume *pv;
+ int lvnum_used[MAX_RESTRICTED_LVS + 1];
+ uint32_t i = 0;
+ struct lv_list *lvl;
+ int lvnum;
- for (s = 0; s < seg->area_count; s++) {
- if (seg->area[s].type != AREA_PV)
- continue;
+ memset(&lvnum_used, 0, sizeof(lvnum_used));
- pv = seg->area[s].u.pv.pv;
- count = seg->area_len;
- pv->pe_alloc_count += count;
+ list_iterate_items(lvl, &lv->vg->lvs) {
+ lvnum = lvnum_from_lvid(&lvl->lv->lvid);
+ if (lvnum <= MAX_RESTRICTED_LVS)
+ lvnum_used[lvnum] = 1;
}
-}
-
-static void _put_extents(struct lv_segment *seg)
-{
- unsigned int s, count;
- struct physical_volume *pv;
- for (s = 0; s < seg->area_count; s++) {
- if (seg->area[s].type != AREA_PV)
- continue;
+ while (lvnum_used[i])
+ i++;
- pv = seg->area[s].u.pv.pv;
+ /* FIXME What if none are free? */
- if (pv) {
- count = seg->area_len;
- assert(pv->pe_alloc_count >= count);
- pv->pe_alloc_count -= count;
- }
- }
+ return i;
}
-struct lv_segment *alloc_lv_segment(struct pool *mem, uint32_t num_areas)
+/*
+ * All lv_segments get created here.
+ */
+struct lv_segment *alloc_lv_segment(struct pool *mem,
+ struct segment_type *segtype,
+ struct logical_volume *lv,
+ uint32_t le, uint32_t len,
+ uint32_t status,
+ uint32_t stripe_size,
+ struct logical_volume *log_lv,
+ uint32_t area_count,
+ uint32_t area_len,
+ uint32_t chunk_size,
+ uint32_t region_size,
+ uint32_t extents_copied)
{
struct lv_segment *seg;
- uint32_t len = sizeof(*seg) + (num_areas * sizeof(seg->area[0]));
+ uint32_t sz = sizeof(*seg) + (area_count * sizeof(seg->area[0]));
- if (!(seg = pool_zalloc(mem, len))) {
+ if (!(seg = pool_zalloc(mem, sz))) {
stack;
return NULL;
}
- seg->area_count = num_areas;
+ if (!segtype) {
+ log_error("alloc_lv_segment: Missing segtype.");
+ return NULL;
+ }
+
+ seg->segtype = segtype;
+ seg->lv = lv;
+ seg->le = le;
+ seg->len = len;
+ seg->status = status;
+ seg->stripe_size = stripe_size;
+ seg->area_count = area_count;
+ seg->area_len = area_len;
+ seg->chunk_size = chunk_size;
+ seg->region_size = region_size;
+ seg->extents_copied = extents_copied;
+ seg->log_lv = log_lv;
list_init(&seg->tags);
+ if (log_lv)
+ log_lv->status |= MIRROR_LOG;
+
return seg;
}
-static int _alloc_parallel_area(struct logical_volume *lv, uint32_t area_count,
- uint32_t stripe_size,
- struct segment_type *segtype,
- struct pv_area **areas, uint32_t *ix)
+struct lv_segment *alloc_snapshot_seg(struct logical_volume *lv,
+ uint32_t status, uint32_t old_le_count)
{
- uint32_t count, area_len, smallest;
- uint32_t s;
struct lv_segment *seg;
- int striped = 0;
+ struct segment_type *segtype;
- /* Striped or mirrored? */
- if (segtype->flags & SEG_AREAS_STRIPED)
- striped = 1;
+ segtype = get_segtype_from_string(lv->vg->cmd, "snapshot");
+ if (!segtype) {
+ log_error("Failed to find snapshot segtype");
+ return NULL;
+ }
- count = lv->le_count - *ix;
- area_len = count / (striped ? area_count : 1);
- smallest = areas[area_count - 1]->count;
+ if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv, old_le_count,
+ lv->le_count - old_le_count, status, 0,
+ NULL, 0, lv->le_count - old_le_count,
+ 0, 0, 0))) {
+ log_error("Couldn't allocate new snapshot segment.");
+ return NULL;
+ }
- if (smallest < area_len)
- area_len = smallest;
+ list_add(&lv->segments, &seg->list);
+ lv->status |= VIRTUAL;
+
+ return seg;
+}
+
+/*
+ * Link part of a PV to an LV segment.
+ */
+int set_lv_segment_area_pv(struct lv_segment *seg, uint32_t area_num,
+ struct physical_volume *pv, uint32_t pe)
+{
+ seg->area[area_num].type = AREA_PV;
+ pv->pe_alloc_count += seg->area_len;
- if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, area_count))) {
- log_err("Couldn't allocate new parallel segment.");
+ if (!(seg_pvseg(seg, area_num) =
+ assign_peg_to_lvseg(pv, pe, seg->area_len, seg, area_num))) {
+ stack;
return 0;
}
- seg->lv = lv;
- seg->segtype = segtype;
- seg->le = *ix;
- seg->len = area_len * (striped ? area_count : 1);
- seg->area_len = area_len;
- seg->stripe_size = stripe_size;
- seg->extents_copied = 0u;
+ return 1;
+}
- for (s = 0; s < area_count; s++) {
- struct pv_area *pva = areas[s];
- seg->area[s].type = AREA_PV;
- seg->area[s].u.pv.pv = pva->map->pvl->pv;
- seg->area[s].u.pv.pe = pva->start;
- consume_pv_area(pva, area_len);
- }
+/*
+ * Link one LV segment to another. Assumes sizes already match.
+ */
+void set_lv_segment_area_lv(struct lv_segment *seg, uint32_t area_num,
+ struct logical_volume *lv, uint32_t le,
+ uint32_t flags)
+{
+ seg->area[area_num].type = AREA_LV;
+ seg_lv(seg, area_num) = lv;
+ seg_le(seg, area_num) = le;
+ lv->status |= flags;
+}
- list_add(&lv->segments, &seg->list);
- *ix += seg->len;
+/*
+ * Reduce the size of an lv_segment. New size can be zero.
+ */
+static int _lv_segment_reduce(struct lv_segment *seg, uint32_t reduction)
+{
+ uint32_t area_reduction, s;
- if (!striped)
- lv->status |= MIRRORED;
+ /* Caller must ensure exact divisibility */
+ if (seg_is_striped(seg)) {
+ if (reduction % seg->area_count) {
+ log_error("Segment extent reduction %" PRIu32
+ "not divisible by #stripes %" PRIu32,
+ reduction, seg->area_count);
+ return 0;
+ }
+ area_reduction = (reduction / seg->area_count);
+ } else
+ area_reduction = reduction;
+
+ seg->len -= reduction;
+ seg->area_len -= area_reduction;
+
+ for (s = 0; s < seg->area_count; s++) {
+ if (seg_type(seg, s) == AREA_PV) {
+ release_pv_segment(seg_pvseg(seg, s), area_reduction);
+ seg->lv->vg->free_count += area_reduction;
+ } else if (seg_lv(seg, s)->status & MIRROR_IMAGE)
+ lv_reduce(seg_lv(seg, s), area_reduction);
+ }
return 1;
}
-static int _comp_area(const void *l, const void *r)
+/*
+ * Entry point for all LV reductions in size.
+ */
+int lv_reduce(struct logical_volume *lv, uint32_t extents)
{
- const struct pv_area *lhs = *((const struct pv_area **) l);
- const struct pv_area *rhs = *((const struct pv_area **) r);
+ struct lv_list *lvl;
+ struct lv_segment *seg;
+ uint32_t count = extents;
+ uint32_t reduction;
- if (lhs->count < rhs->count)
- return 1;
+ list_iterate_back_items(seg, &lv->segments) {
+ if (!count)
+ break;
- else if (lhs->count > rhs->count)
- return -1;
+ if (seg->len <= count) {
+ /* remove this segment completely */
+ /* FIXME Check this is safe */
+ if (seg->log_lv && !lv_remove(seg->log_lv)) {
+ stack;
+ return 0;
+ }
+ list_del(&seg->list);
+ reduction = seg->len;
+ } else
+ reduction = count;
- return 0;
+ if (!_lv_segment_reduce(seg, reduction)) {
+ stack;
+ return 0;
+ }
+ count -= reduction;
+ }
+
+ lv->le_count -= extents;
+ lv->size = (uint64_t) lv->le_count * lv->vg->extent_size;
+
+ /* Remove the LV if it is now empty */
+ if (!lv->le_count) {
+ if (!(lvl = find_lv_in_vg(lv->vg, lv->name))) {
+ stack;
+ return 0;
+ }
+
+ list_del(&lvl->list);
+
+ lv->vg->lv_count--;
+ } else if (lv->vg->fid->fmt->ops->lv_setup &&
+ !lv->vg->fid->fmt->ops->lv_setup(lv->vg->fid, lv)) {
+ stack;
+ return 0;
+ }
+
+ return 1;
}
-static int _alloc_parallel(struct logical_volume *lv,
- struct list *pvms, uint32_t allocated,
- uint32_t stripes, uint32_t stripe_size,
- uint32_t mirrors, struct segment_type *segtype)
+/*
+ * Completely remove an LV.
+ */
+int lv_remove(struct logical_volume *lv)
{
- int r = 0;
- struct list *pvmh;
- struct pv_area **areas;
- unsigned int pv_count = 0, ix;
- struct pv_map *pvm;
- size_t len;
- uint32_t area_count;
- if (stripes > 1 && mirrors > 1) {
- log_error("striped mirrors are not supported yet");
+ if (!lv_reduce(lv, lv->le_count)) {
+ stack;
return 0;
}
- if (stripes > 1)
- area_count = stripes;
- else
+ return 1;
+}
+
+/*
+ * A set of contiguous physical extents allocated
+ */
+struct alloced_area {
+ struct list list;
+
+ struct physical_volume *pv;
+ uint32_t pe;
+ uint32_t len;
+};
+
+/*
+ * Details of an allocation attempt
+ */
+struct alloc_handle {
+ struct pool *mem;
+
+ alloc_policy_t alloc; /* Overall policy */
+ uint32_t area_count; /* Number of parallel areas */
+ uint32_t area_multiple; /* seg->len = area_len * area_multiple */
+ uint32_t log_count; /* Number of parallel 1-extent logs */
+ uint32_t total_area_len; /* Total number of parallel extents */
+
+ struct alloced_area log_area; /* Extent used for log */
+ struct list alloced_areas[0]; /* Lists of areas in each stripe */
+};
+
+/*
+ * Preparation for a specific allocation attempt
+ */
+static struct alloc_handle *_alloc_init(struct pool *mem,
+ struct segment_type *segtype,
+ alloc_policy_t alloc,
+ uint32_t mirrors,
+ uint32_t stripes,
+ uint32_t log_count,
+ struct physical_volume *mirrored_pv)
+{
+ struct alloc_handle *ah;
+ uint32_t s, area_count;
+
+ if (stripes > 1 && mirrors > 1) {
+ log_error("Striped mirrors are not supported yet");
+ return NULL;
+ }
+
+ if ((stripes > 1 || mirrors > 1) && mirrored_pv) {
+ log_error("Can't mix striping or mirroring with "
+ "creation of a mirrored PV yet");
+ return NULL;
+ }
+
+ if (log_count && (stripes > 1 || mirrored_pv)) {
+ log_error("Can't mix striping or pvmove with "
+ "a mirror log yet.");
+ return NULL;
+ }
+
+ if (segtype_is_virtual(segtype))
+ area_count = 0;
+ else if (mirrors > 1)
area_count = mirrors;
+ else if (mirrored_pv)
+ area_count = 1;
+ else
+ area_count = stripes;
+
+ if (!(ah = pool_zalloc(mem, sizeof(*ah) + sizeof(ah->alloced_areas[0]) * area_count))) {
+ log_error("allocation handle allocation failed");
+ return NULL;
+ }
- list_iterate(pvmh, pvms)
- pv_count++;
+ if (segtype_is_virtual(segtype))
+ return ah;
- /* allocate an array of pv_areas, one candidate per pv */
- len = sizeof(*areas) * pv_count;
- if (!(areas = dbg_malloc(sizeof(*areas) * pv_count))) {
- log_err("Couldn't allocate areas array.");
- return 0;
+ if (!(ah->mem = pool_create("allocation", 1024))) {
+ log_error("allocation pool creation failed");
+ return NULL;
}
- while (allocated != lv->le_count) {
+ ah->area_count = area_count;
+ ah->log_count = log_count;
+ ah->alloc = alloc;
+ ah->area_multiple = segtype_is_striped(segtype) ? ah->area_count : 1;
- ix = 0;
- list_iterate(pvmh, pvms) {
- pvm = list_item(pvmh, struct pv_map);
+ list_init(&ah->alloced_areas[0]);
- if (list_empty(&pvm->areas))
- continue;
+ for (s = 0; s < ah->area_count; s++)
+ list_init(&ah->alloced_areas[s]);
+
+ return ah;
+}
+
+void alloc_destroy(struct alloc_handle *ah)
+{
+ if (ah->mem)
+ pool_destroy(ah->mem);
+}
- areas[ix++] = list_item(pvm->areas.n, struct pv_area);
+static int _setup_alloced_segment(struct logical_volume *lv, uint32_t status,
+ uint32_t area_count,
+ uint32_t stripe_size,
+ struct segment_type *segtype,
+ struct alloced_area *aa,
+ struct physical_volume *mirrored_pv,
+ uint32_t mirrored_pe,
+ uint32_t region_size,
+ struct logical_volume *log_lv)
+{
+ uint32_t s, extents, area_multiple, extra_areas = 0;
+ struct lv_segment *seg;
+
+ if (mirrored_pv)
+ extra_areas = 1;
+
+ area_multiple = segtype_is_striped(segtype) ? area_count : 1;
+
+ if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv,
+ lv->le_count,
+ aa[0].len * area_multiple,
+ status, stripe_size, log_lv,
+ area_count + extra_areas,
+ aa[0].len, 0u, region_size, 0u))) {
+ log_error("Couldn't allocate new LV segment.");
+ return 0;
+ }
+
+ if (extra_areas) {
+ if (!set_lv_segment_area_pv(seg, 0, mirrored_pv, mirrored_pe)) {
+ stack;
+ return 0;
}
+ }
- if (ix < area_count) {
- log_error("Insufficient allocatable extents suitable "
- "for parallel use for logical volume "
- "%s: %u required", lv->name, lv->le_count);
- goto out;
+ for (s = 0; s < area_count; s++) {
+ if (!set_lv_segment_area_pv(seg, s + extra_areas, aa[s].pv,
+ aa[s].pe)) {
+ stack;
+ return 0;
}
+ }
- /* sort the areas so we allocate from the biggest */
- qsort(areas, ix, sizeof(*areas), _comp_area);
+ list_add(&lv->segments, &seg->list);
+
+ extents = aa[0].len * area_multiple;
+ lv->le_count += extents;
+ lv->size += (uint64_t) extents *lv->vg->extent_size;
+
+ lv->vg->free_count -= aa[0].len * area_count;
+
+ if (segtype_is_mirrored(segtype))
+ lv->status |= MIRRORED;
- if (!_alloc_parallel_area(lv, area_count, stripe_size, segtype,
- areas, &allocated)) {
+ return 1;
+}
+
+static int _setup_alloced_segments(struct logical_volume *lv,
+ struct list *alloced_areas,
+ uint32_t area_count,
+ uint32_t status,
+ uint32_t stripe_size,
+ struct segment_type *segtype,
+ struct physical_volume *mirrored_pv,
+ uint32_t mirrored_pe,
+ uint32_t region_size,
+ struct logical_volume *log_lv)
+{
+ struct alloced_area *aa;
+
+ list_iterate_items(aa, &alloced_areas[0]) {
+ if (!_setup_alloced_segment(lv, status, area_count,
+ stripe_size, segtype, aa,
+ mirrored_pv, mirrored_pe,
+ region_size, log_lv)) {
stack;
- goto out;
+ return 0;
}
}
- r = 1;
- out:
- dbg_free(areas);
- return r;
+ return 1;
}
/*
- * The heart of the allocation code. This function takes a
- * pv_area and allocates it to the lv. If the lv doesn't need
- * the complete area then the area is split, otherwise the area
- * is unlinked from the pv_map.
+ * This function takes a list of pv_areas and adds them to allocated_areas.
+ * If the complete area is not needed then it gets split.
+ * The part used is removed from the pv_map so it can't be allocated twice.
*/
-static int _alloc_linear_area(struct logical_volume *lv, uint32_t *ix,
- struct pv_map *map, struct pv_area *pva)
+static int _alloc_parallel_area(struct alloc_handle *ah, uint32_t needed,
+ struct pv_area **areas,
+ uint32_t *ix, struct pv_area *log_area)
{
- uint32_t count, remaining;
- struct lv_segment *seg;
+ uint32_t area_len, smallest, remaining;
+ uint32_t s;
+ struct alloced_area *aa;
+
+ remaining = needed - *ix;
+ area_len = remaining / ah->area_multiple;
- count = pva->count;
- remaining = lv->le_count - *ix;
- if (count > remaining)
- count = remaining;
+ smallest = areas[ah->area_count - 1]->count;
- if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, 1))) {
- log_err("Couldn't allocate new stripe segment.");
+ if (area_len > smallest)
+ area_len = smallest;
+
+ if (!(aa = pool_alloc(ah->mem, sizeof(*aa) *
+ (ah->area_count + (log_area ? 1 : 0))))) {
+ log_error("alloced_area allocation failed");
return 0;
}
- seg->lv = lv;
- if (!(seg->segtype = get_segtype_from_string(lv->vg->cmd, "striped"))) {
- stack;
- return 0;
+ for (s = 0; s < ah->area_count; s++) {
+ aa[s].pv = areas[s]->map->pv;
+ aa[s].pe = areas[s]->start;
+ aa[s].len = area_len;
+ list_add(&ah->alloced_areas[s], &aa[s].list);
}
- seg->le = *ix;
- seg->len = count;
- seg->area_len = count;
- seg->stripe_size = 0;
- seg->area[0].type = AREA_PV;
- seg->area[0].u.pv.pv = map->pvl->pv;
- seg->area[0].u.pv.pe = pva->start;
- list_add(&lv->segments, &seg->list);
+ ah->total_area_len += area_len;
+
+ for (s = 0; s < ah->area_count; s++)
+ consume_pv_area(areas[s], area_len);
+
+ 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 */
+ consume_pv_area(log_area, ah->log_area.len);
+ }
+
+ *ix += area_len * ah->area_multiple;
- consume_pv_area(pva, count);
- *ix += count;
return 1;
}
-static int _alloc_mirrored_area(struct logical_volume *lv, uint32_t *ix,
- struct pv_map *map, struct pv_area *pva,
- struct segment_type *segtype,
- struct physical_volume *mirrored_pv,
- uint32_t mirrored_pe)
+static int _comp_area(const void *l, const void *r)
{
- uint32_t count, remaining;
- struct lv_segment *seg;
-
- count = pva->count;
- remaining = lv->le_count - *ix;
- if (count > remaining)
- count = remaining;
+ const struct pv_area *lhs = *((const struct pv_area **) l);
+ const struct pv_area *rhs = *((const struct pv_area **) r);
- if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, 2))) {
- log_err("Couldn't allocate new mirrored segment.");
- return 0;
- }
+ if (lhs->count < rhs->count)
+ return 1;
- seg->lv = lv;
- seg->segtype = segtype;
- seg->le = *ix;
- seg->status = 0u;
- seg->len = count;
- seg->area_len = count;
- seg->stripe_size = 0;
- seg->extents_copied = 0u;
- /* FIXME Remove AREA_PV restriction here? */
- seg->area[0].type = AREA_PV;
- seg->area[0].u.pv.pv = mirrored_pv;
- seg->area[0].u.pv.pe = mirrored_pe;
- seg->area[1].type = AREA_PV;
- seg->area[1].u.pv.pv = map->pvl->pv;
- seg->area[1].u.pv.pe = pva->start;
- list_add(&lv->segments, &seg->list);
+ else if (lhs->count > rhs->count)
+ return -1;
- consume_pv_area(pva, count);
- *ix += count;
- return 1;
+ return 0;
}
/*
- * Only one area per pv is allowed, so we search
- * for the biggest area, or the first area that
- * can complete the allocation.
+ * Is pva contiguous to any existing areas or on the same PV?
*/
+static int _check_contiguous(struct lv_segment *prev_lvseg,
+ struct physical_volume *pv, struct pv_area *pva,
+ struct pv_area **areas)
+{
+ struct pv_segment *prev_pvseg;
+ uint32_t s;
+
+ for (s = 0; s < prev_lvseg->area_count; s++) {
+ if (seg_type(prev_lvseg, s) != AREA_PV)
+ continue; /* FIXME Broken */
+
+ if (!(prev_pvseg = seg_pvseg(prev_lvseg, s)))
+ continue; /* FIXME Broken */
+
+ if ((prev_pvseg->pv != pv))
+ continue;
+
+ if (prev_pvseg->pe + prev_pvseg->len == pva->start) {
+ areas[s] = pva;
+ return 1;
+ }
+ }
+
+ return 0;
+}
/*
- * FIXME: subsequent lvextends may not be contiguous.
+ * Choose sets of parallel areas to use, respecting any constraints.
*/
-static int _alloc_contiguous(struct logical_volume *lv,
- struct list *pvms, uint32_t allocated)
+/* FIXME Also accept existing areas new space must be parallel to */
+static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
+ struct list *pvms, struct pv_area **areas,
+ uint32_t areas_size, unsigned can_split,
+ struct lv_segment *prev_lvseg,
+ uint32_t *allocated, uint32_t needed)
{
- struct list *tmp1;
struct pv_map *pvm;
struct pv_area *pva;
+ unsigned already_found_one = 0;
+ unsigned contiguous = 0, contiguous_count = 0;
+ unsigned ix;
+ unsigned ix_offset = 0; /* Offset for non-contiguous allocations */
+
+ /* FIXME Do calculations on free extent counts before selecting space */
+ /* FIXME Select log PV appropriately if there isn't one yet */
+
+ if ((alloc == ALLOC_CONTIGUOUS)) {
+ contiguous = 1;
+ if (prev_lvseg)
+ ix_offset = prev_lvseg->area_count;
+ else
+ ix_offset = ah->area_count;
+ }
+
+ /* FIXME This algorithm needs a lot of cleaning up! */
+ /* FIXME anywhere doesn't find all space yet */
+ /* ix_offset holds the number of allocations that must be contiguous */
+ /* ix holds the number of areas found on other PVs */
+ do {
+ ix = 0;
- list_iterate(tmp1, pvms) {
- pvm = list_item(tmp1, struct pv_map);
+ /*
+ * Put the smallest area of each PV that is at least the
+ * size we need into areas array. If there isn't one
+ * that fits completely and we're allowed more than one
+ * LV segment, then take the largest remaining instead.
+ */
+ list_iterate_items(pvm, pvms) {
+ if (list_empty(&pvm->areas))
+ continue; /* Next PV */
- if (list_empty(&pvm->areas))
- continue;
+ /* Don't allocate onto the log pv */
+ if ((alloc != ALLOC_ANYWHERE) && ah->log_count &&
+ (pvm->pv == ah->log_area.pv))
+ continue; /* Next PV */
+
+ already_found_one = 0;
+ /* First area in each list is the largest */
+ list_iterate_items(pva, &pvm->areas) {
+ if (contiguous) {
+ if (prev_lvseg &&
+ _check_contiguous(prev_lvseg,
+ pvm->pv,
+ pva, areas)) {
+ contiguous_count++;
+ break; /* Next PV */
+ }
+ continue;
+ }
+
+ /* Is it big enough on its own? */
+ if ((pva->count < needed - *allocated) &&
+ ((!can_split && !ah->log_count) ||
+ (already_found_one &&
+ !(alloc == ALLOC_ANYWHERE))))
+ break; /* Next PV */
+
+ if (!already_found_one ||
+ alloc == ALLOC_ANYWHERE) {
+ ix++;
+ already_found_one = 1;
+ }
- /* first item in the list is the biggest */
- pva = list_item(pvm->areas.n, struct pv_area);
- if (pva->count < lv->le_count)
- continue;
+ areas[ix + ix_offset -1] = pva;
+
+ break; /* Next PV */
+ }
+ if (ix >= areas_size)
+ break;
+ }
- if (!_alloc_linear_area(lv, &allocated, pvm, pva)) {
+ if (contiguous && (contiguous_count < ix_offset))
+ break;
+
+ /* Only allocate log_area the first time around */
+ if (ix + ix_offset < ah->area_count +
+ (ah->log_count && !ah->log_area.len) ?
+ ah->log_count : 0)
+ /* FIXME With ALLOC_ANYWHERE, need to split areas */
+ break;
+
+ /* sort the areas so we allocate from the biggest */
+ if (ix > 1)
+ qsort(areas + ix_offset, ix, sizeof(*areas),
+ _comp_area);
+
+ /* First time around, use smallest area as log_area */
+ /* FIXME decide which PV to use at top of function instead */
+ if (!_alloc_parallel_area(ah, needed, areas,
+ allocated,
+ (ah->log_count && !ah->log_area.len) ?
+ *(areas + ix_offset + ix - 1) :
+ NULL)) {
stack;
return 0;
}
- break;
- }
-
- if (allocated != lv->le_count) {
- log_error("Insufficient allocatable extents (%u) "
- "for logical volume %s: %u required",
- allocated, lv->name, lv->le_count);
- return 0;
- }
+ } while (*allocated != needed && can_split);
return 1;
}
-/* FIXME Contiguous depends on *segment* (i.e. stripe) not LV */
-static int _alloc_mirrored(struct logical_volume *lv,
- struct list *pvms, uint32_t allocated,
+/*
+ * Allocate several segments, each the same size, in parallel.
+ * If mirrored_pv and mirrored_pe are supplied, it is used as
+ * the first area, and additional areas are allocated parallel to it.
+ */
+static int _allocate(struct alloc_handle *ah,
+ struct volume_group *vg,
+ struct logical_volume *lv, uint32_t status,
+ uint32_t new_extents,
+ struct list *allocatable_pvs,
+ uint32_t stripes, uint32_t mirrors,
struct segment_type *segtype,
struct physical_volume *mirrored_pv,
uint32_t mirrored_pe)
{
- struct list *tmp1;
- struct pv_map *pvm;
- struct pv_area *pva;
- uint32_t max_found = 0;
+ struct pv_area **areas;
+ uint32_t allocated = lv ? lv->le_count : 0;
+ uint32_t old_allocated;
+ struct lv_segment *prev_lvseg = NULL;
+ unsigned can_split = 1; /* Are we allowed more than one segment? */
+ int r = 0;
+ struct list *pvms;
+ uint32_t areas_size;
- /* Try each PV in turn */
- list_iterate(tmp1, pvms) {
- pvm = list_item(tmp1, struct pv_map);
+ if (allocated >= new_extents) {
+ log_error("_allocate called with no work to do!");
+ return 1;
+ }
- if (list_empty(&pvm->areas))
- continue;
+ if (mirrored_pv || (ah->alloc == ALLOC_CONTIGUOUS))
+ can_split = 0;
- /* first item in the list is the biggest */
- pva = list_item(pvm->areas.n, struct pv_area);
- if (pva->count < lv->le_count - allocated) {
- max_found = pva->count;
- continue;
- }
+ if (lv && !list_empty(&lv->segments))
+ prev_lvseg = list_item(list_last(&lv->segments),
+ struct lv_segment);
+ /*
+ * Build the sets of available areas on the pv's.
+ */
+ if (!(pvms = create_pv_maps(ah->mem, vg, allocatable_pvs))) {
+ stack;
+ return 0;
+ }
- if (!_alloc_mirrored_area(lv, &allocated, pvm, pva, segtype,
- mirrored_pv, mirrored_pe)) {
- stack;
+ areas_size = list_size(pvms);
+ if (areas_size < ah->area_count + ah->log_count) {
+ if (ah->alloc != ALLOC_ANYWHERE) {
+ log_error("Not enough PVs with free space available "
+ "for parallel allocation.");
+ log_error("Consider --alloc anywhere if desperate.");
return 0;
}
+ areas_size = ah->area_count + ah->log_count;
+ }
+
+ /* Allocate an array of pv_areas to hold the largest space on each PV */
+ if (!(areas = dbg_malloc(sizeof(*areas) * areas_size))) {
+ log_err("Couldn't allocate areas array.");
+ return 0;
+ }
+
+ old_allocated = allocated;
+ if (!_find_parallel_space(ah, ALLOC_CONTIGUOUS, pvms, areas,
+ areas_size, can_split,
+ prev_lvseg, &allocated, new_extents)) {
+ stack;
+ goto out;
+ }
- break;
+ if ((allocated == new_extents) || (ah->alloc == ALLOC_CONTIGUOUS) ||
+ (!can_split && (allocated != old_allocated)))
+ goto finished;
+
+ old_allocated = allocated;
+ if (!_find_parallel_space(ah, ALLOC_NORMAL, pvms, areas,
+ areas_size, can_split,
+ prev_lvseg, &allocated, new_extents)) {
+ stack;
+ goto out;
}
- if (allocated != lv->le_count) {
- log_error("Insufficient contiguous allocatable extents (%u) "
- "for logical volume %s: %u required",
- allocated + max_found, lv->name, lv->le_count);
+ if ((allocated == new_extents) || (ah->alloc == ALLOC_NORMAL) ||
+ (!can_split && (allocated != old_allocated)))
+ goto finished;
+
+ if (!_find_parallel_space(ah, ALLOC_ANYWHERE, pvms, areas,
+ areas_size, can_split,
+ prev_lvseg, &allocated, new_extents)) {
+ stack;
+ goto out;
+ }
+
+ finished:
+ if (allocated != new_extents) {
+ log_error("Insufficient suitable %sallocatable extents "
+ "for logical volume %s: %u more required",
+ can_split ? "" : "contiguous ",
+ lv ? lv->name : "",
+ (new_extents - allocated) * ah->area_count
+ / ah->area_multiple);
+ goto out;
+ }
+
+ r = 1;
+
+ out:
+ dbg_free(areas);
+ return r;
+}
+
+int lv_add_virtual_segment(struct logical_volume *lv, uint32_t status,
+ uint32_t extents, struct segment_type *segtype)
+{
+ struct lv_segment *seg;
+
+ if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv,
+ lv->le_count, extents, status, 0,
+ NULL, 0, extents, 0, 0, 0))) {
+ log_error("Couldn't allocate new zero segment.");
return 0;
}
+ list_add(&lv->segments, &seg->list);
+
+ lv->le_count += extents;
+ lv->size += (uint64_t) extents *lv->vg->extent_size;
+
+ lv->status |= VIRTUAL;
+
return 1;
}
/*
- * Areas just get allocated in order until the lv
- * is full.
+ * Entry point for all extent allocations.
*/
-static int _alloc_next_free(struct logical_volume *lv,
- struct list *pvms, uint32_t allocated)
+struct alloc_handle *allocate_extents(struct volume_group *vg,
+ struct logical_volume *lv,
+ struct segment_type *segtype,
+ uint32_t stripes,
+ uint32_t mirrors, uint32_t log_count,
+ uint32_t extents,
+ struct physical_volume *mirrored_pv,
+ uint32_t mirrored_pe,
+ uint32_t status,
+ struct list *allocatable_pvs,
+ alloc_policy_t alloc)
{
- struct list *tmp1, *tmp2;
- struct pv_map *pvm;
- struct pv_area *pva;
+ struct alloc_handle *ah;
- list_iterate(tmp1, pvms) {
- pvm = list_item(tmp1, struct pv_map);
+ if (segtype_is_virtual(segtype)) {
+ log_error("allocate_extents does not handle virtual segments");
+ return NULL;
+ }
- list_iterate(tmp2, &pvm->areas) {
- pva = list_item(tmp2, struct pv_area);
- if (!_alloc_linear_area(lv, &allocated, pvm, pva) ||
- (allocated == lv->le_count))
- goto done;
- }
+ if (vg->fid->fmt->ops->segtype_supported &&
+ !vg->fid->fmt->ops->segtype_supported(vg->fid, segtype)) {
+ log_error("Metadata format (%s) does not support required "
+ "LV segment type (%s).", vg->fid->fmt->name,
+ segtype->name);
+ log_error("Consider changing the metadata format by running "
+ "vgconvert.");
+ return NULL;
}
- done:
- if (allocated != lv->le_count) {
- log_error("Insufficient allocatable logical extents (%u) "
- "for logical volume %s: %u required",
- allocated, lv->name, lv->le_count);
- return 0;
+ if (alloc == ALLOC_INHERIT)
+ alloc = vg->alloc;
+
+ if (!(ah = _alloc_init(vg->cmd->mem, segtype, alloc, mirrors,
+ stripes, log_count, mirrored_pv))) {
+ stack;
+ return NULL;
}
- return 1;
+ if (!segtype_is_virtual(segtype) &&
+ !_allocate(ah, vg, lv, status, (lv ? lv->le_count : 0) + extents,
+ allocatable_pvs,
+ stripes, mirrors, segtype, mirrored_pv, mirrored_pe)) {
+ stack;
+ alloc_destroy(ah);
+ return NULL;
+ }
+
+ return ah;
}
-static int _alloc_virtual(struct logical_volume *lv,
- uint32_t allocated, struct segment_type *segtype)
+/*
+ * Add new segments to an LV from supplied list of areas.
+ */
+int lv_add_segment(struct alloc_handle *ah,
+ uint32_t first_area, uint32_t num_areas,
+ struct logical_volume *lv,
+ struct segment_type *segtype,
+ uint32_t stripe_size,
+ struct physical_volume *mirrored_pv,
+ uint32_t mirrored_pe,
+ uint32_t status,
+ uint32_t region_size,
+ struct logical_volume *log_lv)
{
- struct lv_segment *seg;
+ if (!segtype) {
+ log_error("Missing segtype in lv_add_segment().");
+ return 0;
+ }
- if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, 0))) {
- log_err("Couldn't allocate new zero segment.");
+ if (segtype_is_virtual(segtype)) {
+ log_error("lv_add_segment cannot handle virtual segments");
return 0;
}
- seg->lv = lv;
- seg->segtype = segtype;
- seg->status = 0u;
- seg->le = allocated;
- seg->len = lv->le_count - allocated;
- seg->area_len = seg->len;
- seg->stripe_size = 0;
- seg->extents_copied = 0u;
- list_add(&lv->segments, &seg->list);
- lv->status |= VIRTUAL;
+ if (!_setup_alloced_segments(lv, &ah->alloced_areas[first_area],
+ num_areas, status,
+ stripe_size, segtype,
+ mirrored_pv, mirrored_pe,
+ region_size, log_lv)) {
+ stack;
+ return 0;
+ }
+
+ if ((segtype->flags & SEG_CAN_SPLIT) && !lv_merge_segments(lv)) {
+ log_err("Couldn't merge segments after extending "
+ "logical volume.");
+ return 0;
+ }
+
+ if (lv->vg->fid->fmt->ops->lv_setup &&
+ !lv->vg->fid->fmt->ops->lv_setup(lv->vg->fid, lv)) {
+ stack;
+ return 0;
+ }
return 1;
}
/*
- * Chooses a correct allocation policy.
+ * Turn an empty LV into a mirror log.
*/
-static int _allocate(struct volume_group *vg, struct logical_volume *lv,
- struct list *allocatable_pvs, uint32_t allocated,
- alloc_policy_t alloc, struct segment_type *segtype,
- uint32_t stripes, uint32_t stripe_size, uint32_t mirrors,
- struct physical_volume *mirrored_pv, uint32_t mirrored_pe,
- uint32_t status)
+int lv_add_log_segment(struct alloc_handle *ah, struct logical_volume *log_lv)
{
- int r = 0;
- struct pool *scratch;
- struct list *pvms, *old_tail = lv->segments.p, *segh;
struct lv_segment *seg;
- if (segtype->flags & SEG_VIRTUAL)
- return _alloc_virtual(lv, allocated, segtype);
+ if (list_size(&log_lv->segments)) {
+ log_error("Log segments can only be added to an empty LV");
+ return 0;
+ }
+
+ if (!(seg = alloc_lv_segment(log_lv->vg->cmd->mem,
+ get_segtype_from_string(log_lv->vg->cmd,
+ "striped"),
+ log_lv, 0, ah->log_area.len, MIRROR_LOG,
+ 0, NULL, 1, ah->log_area.len, 0, 0, 0))) {
+ log_error("Couldn't allocate new mirror log segment.");
+ return 0;
+ }
- if (!(scratch = pool_create("allocation", 1024))) {
+ if (!set_lv_segment_area_pv(seg, 0, ah->log_area.pv, ah->log_area.pe)) {
stack;
return 0;
}
- if (alloc == ALLOC_INHERIT)
- alloc = vg->alloc;
+ list_add(&log_lv->segments, &seg->list);
+ log_lv->le_count += ah->log_area.len;
+ log_lv->size += (uint64_t) log_lv->le_count *log_lv->vg->extent_size;
- /*
- * Build the sets of available areas on the pv's.
- */
- if (!(pvms = create_pv_maps(scratch, vg, allocatable_pvs)))
- goto out;
+ log_lv->vg->free_count--;
- if (stripes > 1 || mirrors > 1)
- r = _alloc_parallel(lv, pvms, allocated, stripes, stripe_size,
- mirrors, segtype);
+ if (log_lv->vg->fid->fmt->ops->lv_setup &&
+ !log_lv->vg->fid->fmt->ops->lv_setup(log_lv->vg->fid, log_lv)) {
+ stack;
+ return 0;
+ }
- else if (mirrored_pv)
- r = _alloc_mirrored(lv, pvms, allocated, segtype, mirrored_pv,
- mirrored_pe);
+ return 1;
+}
- else if (alloc == ALLOC_CONTIGUOUS)
- r = _alloc_contiguous(lv, pvms, allocated);
+/*
+ * Add a mirror segment
+ */
+int lv_add_mirror_segment(struct alloc_handle *ah,
+ struct logical_volume *lv,
+ struct logical_volume **sub_lvs,
+ uint32_t mirrors,
+ struct segment_type *segtype,
+ uint32_t status,
+ uint32_t region_size,
+ struct logical_volume *log_lv)
+{
+ struct lv_segment *seg;
+ uint32_t m;
- else if (alloc == ALLOC_NORMAL || alloc == ALLOC_ANYWHERE)
- r = _alloc_next_free(lv, pvms, allocated);
+ if (list_empty(&log_lv->segments)) {
+ log_error("Log LV %s is empty.", log_lv->name);
+ return 0;
+ }
- else {
- log_error("Unrecognised allocation policy: "
- "unable to set up logical volume.");
- goto out;
+ if (!(seg = alloc_lv_segment(lv->vg->cmd->mem,
+ get_segtype_from_string(lv->vg->cmd,
+ "mirror"),
+ lv, lv->le_count, ah->total_area_len, 0,
+ 0, log_lv, mirrors, ah->total_area_len, 0,
+ region_size, 0))) {
+ log_error("Couldn't allocate new mirror segment.");
+ return 0;
}
- if (r) {
- vg->free_count -= lv->le_count - allocated;
+ for (m = 0; m < mirrors; m++)
+ set_lv_segment_area_lv(seg, m, sub_lvs[m], 0, MIRROR_IMAGE);
- /*
- * Iterate through the new segments, updating pe
- * counts in pv's.
- */
- for (segh = lv->segments.p; segh != old_tail; segh = segh->p) {
- seg = list_item(segh, struct lv_segment);
- _get_extents(seg);
- seg->status = status;
+ list_add(&lv->segments, &seg->list);
+ lv->le_count += ah->total_area_len;
+ lv->size += (uint64_t) lv->le_count *lv->vg->extent_size;
+
+ if (lv->vg->fid->fmt->ops->lv_setup &&
+ !lv->vg->fid->fmt->ops->lv_setup(lv->vg->fid, lv)) {
+ stack;
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/*
+ * Entry point for single-step LV allocation + extension.
+ */
+int lv_extend(struct logical_volume *lv,
+ struct segment_type *segtype,
+ uint32_t stripes, uint32_t stripe_size,
+ uint32_t mirrors, uint32_t extents,
+ struct physical_volume *mirrored_pv, uint32_t mirrored_pe,
+ uint32_t status, struct list *allocatable_pvs,
+ alloc_policy_t alloc)
+{
+ int r = 1;
+ uint32_t m;
+ struct alloc_handle *ah;
+ struct lv_segment *first_seg;
+
+ if (segtype_is_virtual(segtype))
+ return lv_add_virtual_segment(lv, status, extents, segtype);
+
+ if (!(ah = allocate_extents(lv->vg, lv, segtype, stripes, mirrors, 0,
+ extents, mirrored_pv, mirrored_pe, status,
+ allocatable_pvs, alloc))) {
+ stack;
+ return 0;
+ }
+
+ if (mirrors < 2) {
+ if (!lv_add_segment(ah, 0, ah->area_count, lv, segtype, stripe_size,
+ mirrored_pv, mirrored_pe, status, 0, NULL)) {
+ stack;
+ goto out;
}
} else {
- /*
- * Put the segment list back how we found it.
- */
- old_tail->n = &lv->segments;
- lv->segments.p = old_tail;
+ list_iterate_items(first_seg, &lv->segments)
+ break;
+ for (m = 0; m < mirrors; m++) {
+ if (!lv_add_segment(ah, m, 1, seg_lv(first_seg, m),
+ get_segtype_from_string(lv->vg->cmd,
+ "striped"),
+ 0, NULL, 0, 0, 0, NULL)) {
+ log_error("Aborting. Failed to extend %s.",
+ seg_lv(first_seg, m)->name);
+ return 0;
+ }
+ }
+ first_seg->area_len += extents;
+ first_seg->len += extents;
+ lv->le_count += extents;
+ lv->size += (uint64_t) extents *lv->vg->extent_size;
}
out:
- pool_destroy(scratch);
+ alloc_destroy(ah);
return r;
}
-static char *_generate_lv_name(struct volume_group *vg, const char *format,
- char *buffer, size_t len)
+char *generate_lv_name(struct volume_group *vg, const char *format,
+ char *buffer, size_t len)
{
- struct list *lvh;
- struct logical_volume *lv;
+ struct lv_list *lvl;
int high = -1, i;
- list_iterate(lvh, &vg->lvs) {
- lv = (list_item(lvh, struct lv_list)->lv);
-
- if (sscanf(lv->name, format, &i) != 1)
+ list_iterate_items(lvl, &vg->lvs) {
+ if (sscanf(lvl->lv->name, format, &i) != 1)
continue;
if (i > high)
@@ -540,11 +1046,15 @@
return buffer;
}
+/*
+ * Create a new empty LV.
+ */
struct logical_volume *lv_create_empty(struct format_instance *fi,
const char *name,
- const char *name_format,
+ union lvid *lvid,
uint32_t status,
alloc_policy_t alloc,
+ int import,
struct volume_group *vg)
{
struct cmd_context *cmd = vg->cmd;
@@ -558,14 +1068,15 @@
return NULL;
}
- if (!name && !(name = _generate_lv_name(vg, name_format, dname,
- sizeof(dname)))) {
+ if (strstr(name, "%d") &&
+ !(name = generate_lv_name(vg, name, dname, sizeof(dname)))) {
log_error("Failed to generate unique name for the new "
"logical volume");
return NULL;
}
- log_verbose("Creating logical volume %s", name);
+ if (!import)
+ log_verbose("Creating logical volume %s", name);
if (!(ll = pool_zalloc(cmd->mem, sizeof(*ll))) ||
!(ll->lv = pool_zalloc(cmd->mem, sizeof(*ll->lv)))) {
@@ -592,9 +1103,14 @@
lv->minor = -1;
lv->size = UINT64_C(0);
lv->le_count = 0;
+ lv->snapshot = NULL;
+ list_init(&lv->snapshot_segs);
list_init(&lv->segments);
list_init(&lv->tags);
+ if (lvid)
+ lv->lvid = *lvid;
+
if (fi->fmt->ops->lv_setup && !fi->fmt->ops->lv_setup(fi, lv)) {
stack;
if (ll)
@@ -602,150 +1118,10 @@
return NULL;
}
- vg->lv_count++;
+ if (!import)
+ vg->lv_count++;
+
list_add(&vg->lvs, &ll->list);
return lv;
}
-
-int lv_extend(struct format_instance *fid,
- struct logical_volume *lv,
- struct segment_type *segtype,
- uint32_t stripes, uint32_t stripe_size,
- uint32_t mirrors, uint32_t extents,
- struct physical_volume *mirrored_pv, uint32_t mirrored_pe,
- uint32_t status, struct list *allocatable_pvs,
- alloc_policy_t alloc)
-{
- uint32_t old_le_count = lv->le_count;
- uint64_t old_size = lv->size;
-
- lv->le_count += extents;
- lv->size += (uint64_t) extents *lv->vg->extent_size;
-
- if (fid->fmt->ops->segtype_supported &&
- !fid->fmt->ops->segtype_supported(fid, segtype)) {
- log_error("Metadata format (%s) does not support required "
- "LV segment type (%s).", fid->fmt->name,
- segtype->name);
- log_error("Consider changing the metadata format by running "
- "vgconvert.");
- return 0;
- }
-
- if (!_allocate(lv->vg, lv, allocatable_pvs, old_le_count, alloc,
- segtype, stripes, stripe_size, mirrors, mirrored_pv,
- mirrored_pe, status)) {
- lv->le_count = old_le_count;
- lv->size = old_size;
- stack;
- return 0;
- }
-
- if ((segtype->flags & SEG_CAN_SPLIT) && !lv_merge_segments(lv)) {
- log_err("Couldn't merge segments after extending "
- "logical volume.");
- return 0;
- }
-
- if (fid->fmt->ops->lv_setup && !fid->fmt->ops->lv_setup(fid, lv)) {
- stack;
- return 0;
- }
-
- return 1;
-}
-
-int lv_reduce(struct format_instance *fi,
- struct logical_volume *lv, uint32_t extents)
-{
- struct list *segh;
- struct lv_segment *seg;
- uint32_t count = extents;
- int striped;
-
- for (segh = lv->segments.p;
- (segh != &lv->segments) && count; segh = segh->p) {
- seg = list_item(segh, struct lv_segment);
-
- if (seg->len <= count) {
- /* remove this segment completely */
- count -= seg->len;
- _put_extents(seg);
- list_del(segh);
- } else {
- /* reduce this segment */
- _put_extents(seg);
- seg->len -= count;
- striped = seg->segtype->flags & SEG_AREAS_STRIPED;
- /* Caller must ensure exact divisibility */
- if (striped && (count % seg->area_count)) {
- log_error("Segment extent reduction %" PRIu32
- "not divisible by #stripes %" PRIu32,
- count, seg->area_count);
- return 0;
- }
- seg->area_len -=
- count / (striped ? seg->area_count : 1);
- _get_extents(seg);
- count = 0;
- }
- }
-
- lv->le_count -= extents;
- lv->size = (uint64_t) lv->le_count * lv->vg->extent_size;
- lv->vg->free_count += extents;
-
- if (fi->fmt->ops->lv_setup && !fi->fmt->ops->lv_setup(fi, lv)) {
- stack;
- return 0;
- }
-
- return 1;
-}
-
-int lv_remove(struct volume_group *vg, struct logical_volume *lv)
-{
- struct list *segh;
- struct lv_list *lvl;
-
- /* find the lv list */
- if (!(lvl = find_lv_in_vg(vg, lv->name))) {
- stack;
- return 0;
- }
-
- /* iterate through the lv's segments freeing off the pe's */
- list_iterate(segh, &lv->segments)
- _put_extents(list_item(segh, struct lv_segment));
-
- vg->lv_count--;
- vg->free_count += lv->le_count;
-
- list_del(&lvl->list);
-
- return 1;
-}
-
-uint32_t find_free_lvnum(struct logical_volume *lv)
-{
- int lvnum_used[MAX_RESTRICTED_LVS + 1];
- uint32_t i = 0;
- struct list *lvh;
- struct lv_list *lvl;
- int lvnum;
-
- memset(&lvnum_used, 0, sizeof(lvnum_used));
-
- list_iterate(lvh, &lv->vg->lvs) {
- lvl = list_item(lvh, struct lv_list);
- lvnum = lvnum_from_lvid(&lvl->lv->lvid);
- if (lvnum <= MAX_RESTRICTED_LVS)
- lvnum_used[lvnum] = 1;
- }
-
- while (lvnum_used[i])
- i++;
-
- return i;
-}
Modified: lvm2/upstream/current/lib/metadata/merge.c
==============================================================================
--- lvm2/upstream/current/lib/metadata/merge.c (original)
+++ lvm2/upstream/current/lib/metadata/merge.c Tue Jun 14 11:13:22 2005
@@ -17,6 +17,7 @@
#include "metadata.h"
#include "toolcontext.h"
#include "lv_alloc.h"
+#include "pv_alloc.h"
#include "str_list.h"
#include "segtype.h"
@@ -57,11 +58,13 @@
/*
* Verify that an LV's segments are consecutive, complete and don't overlap.
*/
-int lv_check_segments(struct logical_volume *lv)
+int check_lv_segments(struct logical_volume *lv)
{
struct lv_segment *seg;
uint32_t le = 0;
unsigned seg_count = 0;
+ int r = 1;
+ uint32_t area_multiplier, s;
list_iterate_items(seg, &lv->segments) {
seg_count++;
@@ -69,13 +72,58 @@
log_error("LV %s invalid: segment %u should begin at "
"LE %" PRIu32 " (found %" PRIu32 ").",
lv->name, seg_count, le, seg->le);
- return 0;
+ r = 0;
+ }
+
+ area_multiplier = segtype_is_striped(seg->segtype) ?
+ seg->area_count : 1;
+
+ if (seg->area_len * area_multiplier != seg->len) {
+ log_error("LV %s: segment %u has inconsistent "
+ "area_len %u",
+ lv->name, seg_count, seg->area_len);
+ r = 0;
+ }
+
+ for (s = 0; s < seg->area_count; s++) {
+ if (seg_type(seg, s) == AREA_PV) {
+ if (!seg_pvseg(seg, s) ||
+ seg_pvseg(seg, s)->lvseg != seg ||
+ seg_pvseg(seg, s)->lv_area != s) {
+ log_error("LV %s: segment %u has "
+ "inconsistent PV area %u",
+ lv->name, seg_count, s);
+ r = 0;
+ }
+ } else {
+ if (!seg_lv(seg, s) ||
+ seg_lv(seg, s)->vg != lv->vg ||
+ seg_lv(seg, s) == lv) {
+ log_error("LV %s: segment %u has "
+ "inconsistent LV area %u",
+ lv->name, seg_count, s);
+ r = 0;
+ }
+ if (seg_le(seg, s) != le) {
+ log_error("LV %s: segment %u has "
+ "inconsistent LV area %u "
+ "size",
+ lv->name, seg_count, s);
+ r = 0;
+ }
+ }
}
le += seg->len;
}
- return 1;
+ if (le != lv->le_count) {
+ log_error("LV %s: inconsistent LE count %u != %u",
+ lv->name, le, lv->le_count);
+ r = 0;
+ }
+
+ return r;
}
/*
@@ -85,27 +133,29 @@
static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
uint32_t le)
{
- size_t len;
struct lv_segment *split_seg;
uint32_t s;
uint32_t offset = le - seg->le;
uint32_t area_offset;
- if (!(seg->segtype->flags & SEG_CAN_SPLIT)) {
+ if (!seg_can_split(seg)) {
log_error("Unable to split the %s segment at LE %" PRIu32
" in LV %s", seg->segtype->name, le, lv->name);
return 0;
}
/* Clone the existing segment */
- if (!(split_seg = alloc_lv_segment(lv->vg->cmd->mem, seg->area_count))) {
- log_error("Couldn't allocate new LV segment.");
+ if (!(split_seg = alloc_lv_segment(lv->vg->cmd->mem, seg->segtype,
+ seg->lv, seg->le, seg->len,
+ seg->status, seg->stripe_size,
+ seg->log_lv,
+ seg->area_count, seg->area_len,
+ seg->chunk_size, seg->region_size,
+ seg->extents_copied))) {
+ log_error("Couldn't allocate cloned LV segment.");
return 0;
}
- len = sizeof(*seg) + (seg->area_count * sizeof(seg->area[0]));
- memcpy(split_seg, seg, len);
-
if (!str_list_dup(lv->vg->cmd->mem, &split_seg->tags, &seg->tags)) {
log_error("LV segment tags duplication failed");
return 0;
@@ -113,45 +163,55 @@
/* In case of a striped segment, the offset has to be / stripes */
area_offset = offset;
- if (seg->segtype->flags & SEG_AREAS_STRIPED)
+ if (seg_is_striped(seg))
area_offset /= seg->area_count;
+ split_seg->area_len -= area_offset;
+ seg->area_len = area_offset;
+
+ split_seg->len -= offset;
+ seg->len = offset;
+
+ split_seg->le = seg->le + seg->len;
+
/* Adjust the PV mapping */
for (s = 0; s < seg->area_count; s++) {
+ seg_type(split_seg, s) = seg_type(seg, s);
+
/* Split area at the offset */
- switch (seg->area[s].type) {
+ switch (seg_type(seg, s)) {
case AREA_LV:
- split_seg->area[s].u.lv.le =
- seg->area[s].u.lv.le + area_offset;
+ seg_lv(split_seg, s) = seg_lv(seg, s);
+ seg_le(split_seg, s) =
+ seg_le(seg, s) + seg->area_len;
log_debug("Split %s:%u[%u] at %u: %s LE %u", lv->name,
- seg->le, s, le, seg->area[s].u.lv.lv->name,
- split_seg->area[s].u.lv.le);
+ seg->le, s, le, seg_lv(seg, s)->name,
+ seg_le(split_seg, s));
break;
case AREA_PV:
- split_seg->area[s].u.pv.pe =
- seg->area[s].u.pv.pe + area_offset;
+ if (!assign_peg_to_lvseg(seg_pv(seg, s),
+ seg_pe(seg, s) +
+ seg->area_len,
+ seg_pvseg(seg, s)->len -
+ seg->area_len,
+ split_seg, s)) {
+ stack;
+ return 0;
+ }
log_debug("Split %s:%u[%u] at %u: %s PE %u", lv->name,
seg->le, s, le,
- dev_name(seg->area[s].u.pv.pv->dev),
- split_seg->area[s].u.pv.pe);
+ dev_name(seg_dev(seg, s)),
+ seg_pe(split_seg, s));
break;
default:
log_error("Unrecognised segment type %u",
- seg->area[s].type);
+ seg_type(seg, s));
return 0;
}
}
- split_seg->area_len -= area_offset;
- seg->area_len = area_offset;
-
- split_seg->len -= offset;
- seg->len = offset;
-
- split_seg->le = seg->le + seg->len;
-
/* Add split off segment to the list _after_ the original one */
list_add_h(&seg->list, &split_seg->list);
Modified: lvm2/upstream/current/lib/metadata/metadata.c
==============================================================================
--- lvm2/upstream/current/lib/metadata/metadata.c (original)
+++ lvm2/upstream/current/lib/metadata/metadata.c Tue Jun 14 11:13:22 2005
@@ -21,6 +21,8 @@
#include "lvm-string.h"
#include "lvmcache.h"
#include "memlock.h"
+#include "str_list.h"
+#include "pv_alloc.h"
static int _add_pv_to_vg(struct format_instance *fid, struct volume_group *vg,
const char *pv_name)
@@ -99,9 +101,14 @@
return 0;
}
- pvl->pv = pv;
+ if (!alloc_pv_segment_whole_pv(mem, pv)) {
+ stack;
+ return 0;
+ }
+ pvl->pv = pv;
list_add(&vg->pvs, &pvl->list);
+
vg->pv_count++;
vg->extent_count += pv->pe_count;
vg->free_count += pv->pe_count;
@@ -109,23 +116,70 @@
return 1;
}
+static int _copy_pv(struct physical_volume *pv_to,
+ struct physical_volume *pv_from)
+{
+ memcpy(pv_to, pv_from, sizeof(*pv_to));
+
+ if (!str_list_dup(pv_to->fmt->cmd->mem, &pv_to->tags, &pv_from->tags)) {
+ log_error("PV tags duplication failed");
+ return 0;
+ }
+
+ if (!peg_dup(pv_to->fmt->cmd->mem, &pv_to->segments,
+ &pv_from->segments)) {
+ stack;
+ return 0;
+ }
+
+ return 1;
+}
+
+int get_pv_from_vg_by_id(const struct format_type *fmt, const char *vg_name,
+ const char *id, struct physical_volume *pv)
+{
+ struct volume_group *vg;
+ struct pv_list *pvl;
+ int consistent = 0;
+
+ if (!(vg = vg_read(fmt->cmd, vg_name, &consistent))) {
+ log_error("get_pv_from_vg_by_id: vg_read failed to read VG %s",
+ vg_name);
+ return 0;
+ }
+
+ if (!consistent)
+ log_error("Warning: Volume group %s is not consistent",
+ vg_name);
+
+ list_iterate_items(pvl, &vg->pvs) {
+ if (id_equal(&pvl->pv->id, (const struct id *) id)) {
+ if (!_copy_pv(pv, pvl->pv)) {
+ stack;
+ return 0;
+ }
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
int vg_rename(struct cmd_context *cmd, struct volume_group *vg,
const char *new_name)
{
struct pool *mem = cmd->mem;
- struct physical_volume *pv;
- struct list *pvh;
+ struct pv_list *pvl;
if (!(vg->name = pool_strdup(mem, new_name))) {
log_error("vg->name allocation failed for '%s'", new_name);
return 0;
}
- list_iterate(pvh, &vg->pvs) {
- pv = list_item(pvh, struct pv_list)->pv;
- if (!(pv->vg_name = pool_strdup(mem, new_name))) {
+ list_iterate_items(pvl, &vg->pvs) {
+ if (!(pvl->pv->vg_name = pool_strdup(mem, new_name))) {
log_error("pv->vg_name allocation failed for '%s'",
- dev_name(pv->dev));
+ dev_name(pvl->pv->dev));
return 0;
}
}
@@ -221,7 +275,6 @@
list_init(&vg->lvs);
vg->snapshot_count = 0;
- list_init(&vg->snapshots);
list_init(&vg->tags);
@@ -249,6 +302,182 @@
return NULL;
}
+static int _recalc_extents(uint32_t *extents, const char *desc1,
+ const char *desc2, uint32_t old_size,
+ uint32_t new_size)
+{
+ uint64_t size = (uint64_t) old_size * (*extents);
+
+ if (size % new_size) {
+ log_error("New size %" PRIu64 " for %s%s not an exact number "
+ "of new extents.", size, desc1, desc2);
+ return 0;
+ }
+
+ size /= new_size;
+
+ if (size > UINT32_MAX) {
+ log_error("New extent count %" PRIu64 " for %s%s exceeds "
+ "32 bits.", size, desc1, desc2);
+ return 0;
+ }
+
+ *extents = (uint32_t) size;
+
+ return 1;
+}
+
+int vg_change_pesize(struct cmd_context *cmd, struct volume_group *vg,
+ uint32_t new_size)
+{
+ uint32_t old_size = vg->extent_size;
+ struct pv_list *pvl;
+ struct lv_list *lvl;
+ struct physical_volume *pv;
+ struct logical_volume *lv;
+ struct lv_segment *seg;
+ struct pv_segment *pvseg;
+ uint32_t s;
+
+ vg->extent_size = new_size;
+
+ if (vg->fid->fmt->ops->vg_setup &&
+ !vg->fid->fmt->ops->vg_setup(vg->fid, vg)) {
+ stack;
+ return 0;
+ }
+
+ if (!_recalc_extents(&vg->extent_count, vg->name, "", old_size,
+ new_size)) {
+ stack;
+ return 0;
+ }
+
+ if (!_recalc_extents(&vg->free_count, vg->name, " free space",
+ old_size, new_size)) {
+ stack;
+ return 0;
+ }
+
+ /* foreach PV */
+ list_iterate_items(pvl, &vg->pvs) {
+ pv = pvl->pv;
+
+ pv->pe_size = new_size;
+ if (!_recalc_extents(&pv->pe_count, dev_name(pv->dev), "",
+ old_size, new_size)) {
+ stack;
+ return 0;
+ }
+
+ if (!_recalc_extents(&pv->pe_alloc_count, dev_name(pv->dev),
+ " allocated space", old_size, new_size)) {
+ stack;
+ return 0;
+ }
+
+ /* foreach free PV Segment */
+ list_iterate_items(pvseg, &pv->segments) {
+ if (pvseg->lvseg)
+ continue;
+
+ if (!_recalc_extents(&pvseg->pe, dev_name(pv->dev),
+ " PV segment start", old_size,
+ new_size)) {
+ stack;
+ return 0;
+ }
+ if (!_recalc_extents(&pvseg->len, dev_name(pv->dev),
+ " PV segment length", old_size,
+ new_size)) {
+ stack;
+ return 0;
+ }
+ }
+ }
+
+ /* foreach LV */
+ list_iterate_items(lvl, &vg->lvs) {
+ lv = lvl->lv;
+
+ if (!_recalc_extents(&lv->le_count, lv->name, "", old_size,
+ new_size)) {
+ stack;
+ return 0;
+ }
+
+ list_iterate_items(seg, &lv->segments) {
+ if (!_recalc_extents(&seg->le, lv->name,
+ " segment start", old_size,
+ new_size)) {
+ stack;
+ return 0;
+ }
+
+ if (!_recalc_extents(&seg->len, lv->name,
+ " segment length", old_size,
+ new_size)) {
+ stack;
+ return 0;
+ }
+
+ if (!_recalc_extents(&seg->area_len, lv->name,
+ " area length", old_size,
+ new_size)) {
+ stack;
+ return 0;
+ }
+
+ if (!_recalc_extents(&seg->extents_copied, lv->name,
+ " extents moved", old_size,
+ new_size)) {
+ stack;
+ return 0;
+ }
+
+ /* foreach area */
+ for (s = 0; s < seg->area_count; s++) {
+ switch (seg_type(seg, s)) {
+ case AREA_PV:
+ if (!_recalc_extents
+ (&seg_pe(seg, s),
+ lv->name,
+ " pvseg start", old_size,
+ new_size)) {
+ stack;
+ return 0;
+ }
+ if (!_recalc_extents
+ (&seg_pvseg(seg, s)->len,
+ lv->name,
+ " pvseg length", old_size,
+ new_size)) {
+ stack;
+ return 0;
+ }
+ break;
+ case AREA_LV:
+ if (!_recalc_extents
+ (&seg_le(seg, s), lv->name,
+ " area start", old_size,
+ new_size)) {
+ stack;
+ return 0;
+ }
+ break;
+ default:
+ log_error("Unrecognised segment type "
+ "%u", seg_type(seg, s));
+ return 0;
+ }
+ }
+ }
+
+ }
+
+ return 1;
+}
+
/* Sizes in sectors */
struct physical_volume *pv_create(const struct format_type *fmt,
struct device *dev,
@@ -311,6 +540,7 @@
pv->fmt = fmt;
list_init(&pv->tags);
+ list_init(&pv->segments);
if (!fmt->ops->pv_setup(fmt, pe_start, existing_extent_count,
existing_extent_size,
@@ -329,26 +559,22 @@
struct pv_list *find_pv_in_vg(struct volume_group *vg, const char *pv_name)
{
- struct list *pvh;
struct pv_list *pvl;
- list_iterate(pvh, &vg->pvs) {
- pvl = list_item(pvh, struct pv_list);
+ list_iterate_items(pvl, &vg->pvs)
if (pvl->pv->dev == dev_cache_get(pv_name, vg->cmd->filter))
return pvl;
- }
return NULL;
}
int pv_is_in_vg(struct volume_group *vg, struct physical_volume *pv)
{
- struct list *pvh;
+ struct pv_list *pvl;
- list_iterate(pvh, &vg->pvs) {
- if (pv == list_item(pvh, struct pv_list)->pv)
+ list_iterate_items(pvl, &vg->pvs)
+ if (pv == pvl->pv)
return 1;
- }
return 0;
}
@@ -356,21 +582,17 @@
struct physical_volume *find_pv_in_vg_by_uuid(struct volume_group *vg,
struct id *id)
{
- struct list *pvh;
struct pv_list *pvl;
- list_iterate(pvh, &vg->pvs) {
- pvl = list_item(pvh, struct pv_list);
+ list_iterate_items(pvl, &vg->pvs)
if (id_equal(&pvl->pv->id, id))
return pvl->pv;
- }
return NULL;
}
struct lv_list *find_lv_in_vg(struct volume_group *vg, const char *lv_name)
{
- struct list *lvh;
struct lv_list *lvl;
const char *ptr;
@@ -380,11 +602,9 @@
else
ptr = lv_name;
- list_iterate(lvh, &vg->lvs) {
- lvl = list_item(lvh, struct lv_list);
+ list_iterate_items(lvl, &vg->lvs)
if (!strcmp(lvl->lv->name, ptr))
return lvl;
- }
return NULL;
}
@@ -392,14 +612,11 @@
struct lv_list *find_lv_in_vg_by_lvid(struct volume_group *vg,
const union lvid *lvid)
{
- struct list *lvh;
struct lv_list *lvl;
- list_iterate(lvh, &vg->lvs) {
- lvl = list_item(lvh, struct lv_list);
+ list_iterate_items(lvl, &vg->lvs)
if (!strncmp(lvl->lv->lvid.s, lvid->s, sizeof(*lvid)))
return lvl;
- }
return NULL;
}
@@ -412,15 +629,12 @@
struct physical_volume *find_pv(struct volume_group *vg, struct device *dev)
{
- struct list *pvh;
- struct physical_volume *pv;
+ struct pv_list *pvl;
- list_iterate(pvh, &vg->pvs) {
- pv = list_item(pvh, struct pv_list)->pv;
+ list_iterate_items(pvl, &vg->pvs)
+ if (dev == pvl->pv->dev)
+ return pvl->pv;
- if (dev == pv->dev)
- return pv;
- }
return NULL;
}
@@ -445,27 +659,34 @@
/* Find segment at a given logical extent in an LV */
struct lv_segment *find_seg_by_le(struct logical_volume *lv, uint32_t le)
{
- struct list *segh;
struct lv_segment *seg;
- list_iterate(segh, &lv->segments) {
- seg = list_item(segh, struct lv_segment);
+ list_iterate_items(seg, &lv->segments)
if (le >= seg->le && le < seg->le + seg->len)
return seg;
- }
+
+ return NULL;
+}
+
+/* Find segment at a given physical extent in a PV */
+struct pv_segment *find_peg_by_pe(struct physical_volume *pv, uint32_t pe)
+{
+ struct pv_segment *peg;
+
+ list_iterate_items(peg, &pv->segments)
+ if (pe >= peg->pe && pe < peg->pe + peg->len)
+ return peg;
return NULL;
}
int vg_remove(struct volume_group *vg)
{
- struct list *mdah;
struct metadata_area *mda;
/* FIXME Improve recovery situation? */
/* Remove each copy of the metadata */
- list_iterate(mdah, &vg->fid->metadata_areas) {
- mda = list_item(mdah, struct metadata_area);
+ list_iterate_items(mda, &vg->fid->metadata_areas) {
if (mda->ops->vg_remove &&
!mda->ops->vg_remove(vg->fid, vg, mda)) {
stack;
@@ -482,8 +703,23 @@
*/
int vg_write(struct volume_group *vg)
{
- struct list *mdah, *mdah2;
+ struct list *mdah;
struct metadata_area *mda;
+ struct lv_list *lvl;
+
+ if (!check_pv_segments(vg)) {
+ log_error("Internal error: PV segments corrupted in %s.",
+ vg->name);
+ return 0;
+ }
+
+ list_iterate_items(lvl, &vg->lvs) {
+ if (!check_lv_segments(lvl->lv)) {
+ log_error("Internal error: LV segments corrupted in %s.",
+ lvl->lv->name);
+ return 0;
+ }
+ }
if (vg->status & PARTIAL_VG) {
log_error("Cannot change metadata for partial volume group %s",
@@ -499,14 +735,14 @@
vg->seqno++;
/* Write to each copy of the metadata area */
- list_iterate(mdah, &vg->fid->metadata_areas) {
- mda = list_item(mdah, struct metadata_area);
+ list_iterate_items(mda, &vg->fid->metadata_areas) {
if (!mda->ops->vg_write) {
log_error("Format does not support writing volume"
"group metadata areas");
/* Revert */
- list_uniterate(mdah2, &vg->fid->metadata_areas, mdah) {
- mda = list_item(mdah2, struct metadata_area);
+ list_uniterate(mdah, &vg->fid->metadata_areas, &mda->list) {
+ mda = list_item(mdah, struct metadata_area);
+
if (mda->ops->vg_revert &&
!mda->ops->vg_revert(vg->fid, vg, mda)) {
stack;
@@ -517,8 +753,25 @@
if (!mda->ops->vg_write(vg->fid, vg, mda)) {
stack;
/* Revert */
- list_uniterate(mdah2, &vg->fid->metadata_areas, mdah) {
- mda = list_item(mdah2, struct metadata_area);
+ list_uniterate(mdah, &vg->fid->metadata_areas, &mda->list) {
+ mda = list_item(mdah, struct metadata_area);
+
+ if (mda->ops->vg_revert &&
+ !mda->ops->vg_revert(vg->fid, vg, mda)) {
+ stack;
+ }
+ }
+ return 0;
+ }
+ }
+
+ /* Now pre-commit each copy of the new metadata */
+ list_iterate_items(mda, &vg->fid->metadata_areas) {
+ if (mda->ops->vg_precommit &&
+ !mda->ops->vg_precommit(vg->fid, vg, mda)) {
+ stack;
+ /* Revert */
+ list_iterate_items(mda, &vg->fid->metadata_areas) {
if (mda->ops->vg_revert &&
!mda->ops->vg_revert(vg->fid, vg, mda)) {
stack;
@@ -534,14 +787,12 @@
/* Commit pending changes */
int vg_commit(struct volume_group *vg)
{
- struct list *mdah;
struct metadata_area *mda;
int cache_updated = 0;
int failed = 0;
/* Commit to each copy of the metadata area */
- list_iterate(mdah, &vg->fid->metadata_areas) {
- mda = list_item(mdah, struct metadata_area);
+ list_iterate_items(mda, &vg->fid->metadata_areas) {
failed = 0;
if (mda->ops->vg_commit &&
!mda->ops->vg_commit(vg->fid, vg, mda)) {
@@ -553,7 +804,6 @@
lvmcache_update_vg(vg);
cache_updated = 1;
}
-
}
/* If at least one mda commit succeeded, it was committed */
@@ -563,11 +813,9 @@
/* Don't commit any pending changes */
int vg_revert(struct volume_group *vg)
{
- struct list *mdah;
struct metadata_area *mda;
- list_iterate(mdah, &vg->fid->metadata_areas) {
- mda = list_item(mdah, struct metadata_area);
+ list_iterate_items(mda, &vg->fid->metadata_areas) {
if (mda->ops->vg_revert &&
!mda->ops->vg_revert(vg->fid, vg, mda)) {
stack;
@@ -581,8 +829,7 @@
static struct volume_group *_vg_read_orphans(struct cmd_context *cmd)
{
struct lvmcache_vginfo *vginfo;
- struct list *ih;
- struct device *dev;
+ struct lvmcache_info *info;
struct pv_list *pvl;
struct volume_group *vg;
struct physical_volume *pv;
@@ -598,7 +845,6 @@
}
list_init(&vg->pvs);
list_init(&vg->lvs);
- list_init(&vg->snapshots);
list_init(&vg->tags);
vg->cmd = cmd;
if (!(vg->name = pool_strdup(cmd->mem, ORPHAN))) {
@@ -606,9 +852,8 @@
return NULL;
}
- list_iterate(ih, &vginfo->infos) {
- dev = list_item(ih, struct lvmcache_info)->dev;
- if (!(pv = pv_read(cmd, dev_name(dev), NULL, NULL, 1))) {
+ list_iterate_items(info, &vginfo->infos) {
+ if (!(pv = pv_read(cmd, dev_name(info->dev), NULL, NULL, 1))) {
continue;
}
if (!(pvl = pool_zalloc(cmd->mem, sizeof(*pvl)))) {
@@ -630,17 +875,22 @@
* and take appropriate action if it isn't (e.g. abort; get write lock
* and call vg_read again).
*/
-struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
- int *consistent)
+static struct volume_group *_vg_read(struct cmd_context *cmd,
+ const char *vgname,
+ int *consistent, int precommitted)
{
struct format_instance *fid;
const struct format_type *fmt;
struct volume_group *vg, *correct_vg = NULL;
- struct list *mdah;
struct metadata_area *mda;
int inconsistent = 0;
if (!*vgname) {
+ if (precommitted) {
+ log_error("Internal error: vg_read requires vgname "
+ "with pre-commit.");
+ return NULL;
+ }
*consistent = 1;
return _vg_read_orphans(cmd);
}
@@ -654,7 +904,7 @@
stack;
return NULL;
}
- lvmcache_label_scan(cmd, 1);
+ lvmcache_label_scan(cmd, 2);
if (!(fmt = fmt_from_vgname(vgname))) {
stack;
return NULL;
@@ -662,6 +912,12 @@
}
}
+ if (precommitted && !(fmt->features & FMT_PRECOMMIT)) {
+ log_error("Internal error: %s doesn't support "
+ "pre-commit", fmt->name);
+ return NULL;
+ }
+
/* create format instance with appropriate metadata area */
if (!(fid = fmt->ops->create_instance(fmt, vgname, NULL))) {
log_error("Failed to create format instance");
@@ -669,9 +925,11 @@
}
/* Ensure contents of all metadata areas match - else do recovery */
- list_iterate(mdah, &fid->metadata_areas) {
- mda = list_item(mdah, struct metadata_area);
- if (!(vg = mda->ops->vg_read(fid, vgname, mda))) {
+ list_iterate_items(mda, &fid->metadata_areas) {
+ if ((precommitted &&
+ !(vg = mda->ops->vg_read_precommit(fid, vgname, mda))) ||
+ (!precommitted &&
+ !(vg = mda->ops->vg_read(fid, vgname, mda)))) {
inconsistent = 1;
continue;
}
@@ -687,15 +945,66 @@
}
}
- /* Failed to find VG */
+ /* Failed to find VG where we expected it - full scan and retry */
if (!correct_vg) {
- stack;
- return NULL;
+ inconsistent = 0;
+
+ lvmcache_label_scan(cmd, 2);
+ if (!(fmt = fmt_from_vgname(vgname))) {
+ stack;
+ return NULL;
+ }
+
+ if (precommitted && !(fmt->features & FMT_PRECOMMIT)) {
+ log_error("Internal error: %s doesn't support "
+ "pre-commit", fmt->name);
+ return NULL;
+ }
+
+ /* create format instance with appropriate metadata area */
+ if (!(fid = fmt->ops->create_instance(fmt, vgname, NULL))) {
+ log_error("Failed to create format instance");
+ return NULL;
+ }
+
+ /* Ensure contents of all metadata areas match - else recover */
+ list_iterate_items(mda, &fid->metadata_areas) {
+ if ((precommitted &&
+ !(vg = mda->ops->vg_read_precommit(fid, vgname,
+ mda))) ||
+ (!precommitted &&
+ !(vg = mda->ops->vg_read(fid, vgname, mda)))) {
+ inconsistent = 1;
+ continue;
+ }
+ if (!correct_vg) {
+ correct_vg = vg;
+ continue;
+ }
+ /* FIXME Also ensure contents same - checksums same? */
+ if (correct_vg->seqno != vg->seqno) {
+ inconsistent = 1;
+ if (vg->seqno > correct_vg->seqno)
+ correct_vg = vg;
+ }
+ }
+
+ /* Give up looking */
+ if (!correct_vg) {
+ stack;
+ return NULL;
+ }
}
lvmcache_update_vg(correct_vg);
if (inconsistent) {
+ if (precommitted) {
+ log_error("Inconsistent pre-commit metadata copies "
+ "for volume group %s", vgname);
+ return NULL;
+ }
+
if (!*consistent)
return correct_vg;
@@ -733,6 +1042,19 @@
return correct_vg;
}
+struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
+ int *consistent)
+{
+ return _vg_read(cmd, vgname, consistent, 0);
+}
+
+struct volume_group *vg_read_precommitted(struct cmd_context *cmd,
+ const char *vgname,
+ int *consistent)
+{
+ return _vg_read(cmd, vgname, consistent, 1);
+}
+
/* This is only called by lv_from_lvid, which is only called from
* activate.c so we know the appropriate VG lock is already held and
* the vg_read is therefore safe.
@@ -740,9 +1062,10 @@
struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid)
{
const char *vgname;
- struct list *vgnames, *slh;
+ struct list *vgnames;
struct volume_group *vg;
struct lvmcache_vginfo *vginfo;
+ struct str_list *strl;
int consistent = 0;
/* Is corresponding vgname already cached? */
@@ -768,13 +1091,13 @@
* allowed to do a full scan here any more. */
// The slow way - full scan required to cope with vgrename
- if (!(vgnames = get_vgs(cmd, 1))) {
+ if (!(vgnames = get_vgs(cmd, 2))) {
log_error("vg_read_by_vgid: get_vgs failed");
return NULL;
}
- list_iterate(slh, vgnames) {
- vgname = list_item(slh, struct str_list)->str;
+ list_iterate_items(strl, vgnames) {
+ vgname = strl->str;
if (!vgname || !*vgname)
continue; // FIXME Unnecessary?
consistent = 0;
@@ -832,14 +1155,14 @@
if (!(dev = dev_cache_get(pv_name, cmd->filter))) {
stack;
- return 0;
+ return NULL;
}
if (!(label_read(dev, &label))) {
if (warnings)
log_error("No physical volume label read from %s",
pv_name);
- return 0;
+ return NULL;
}
info = (struct lvmcache_info *) label->info;
@@ -848,22 +1171,28 @@
if (!(pv = pool_zalloc(cmd->mem, sizeof(*pv)))) {
log_error("pv allocation for '%s' failed", pv_name);
- return 0;
+ return NULL;
}
list_init(&pv->tags);
+ list_init(&pv->segments);
/* FIXME Move more common code up here */
if (!(info->fmt->ops->pv_read(info->fmt, pv_name, pv, mdas))) {
log_error("Failed to read existing physical volume '%s'",
pv_name);
- return 0;
+ return NULL;
}
if (!pv->size)
return NULL;
- else
- return pv;
+
+ if (!alloc_pv_segment_whole_pv(cmd->mem, pv)) {
+ stack;
+ return NULL;
+ }
+
+ return pv;
}
/* May return empty list */
@@ -874,10 +1203,11 @@
struct list *get_pvs(struct cmd_context *cmd)
{
+ struct str_list *strl;
struct list *results;
const char *vgname;
struct list *pvh, *tmp;
- struct list *vgnames, *slh;
+ struct list *vgnames;
struct volume_group *vg;
int consistent = 0;
int old_partial;
@@ -904,8 +1234,8 @@
old_pvmove = pvmove_mode();
init_partial(1);
init_pvmove(1);
- list_iterate(slh, vgnames) {
- vgname = list_item(slh, struct str_list)->str;
+ list_iterate_items(strl, vgnames) {
+ vgname = strl->str;
if (!vgname)
continue; /* FIXME Unnecessary? */
consistent = 0;
Modified: lvm2/upstream/current/lib/metadata/metadata.h
==============================================================================
--- lvm2/upstream/current/lib/metadata/metadata.h (original)
+++ lvm2/upstream/current/lib/metadata/metadata.h Tue Jun 14 11:13:22 2005
@@ -50,11 +50,13 @@
#define VISIBLE_LV 0x00000040 /* LV */
#define FIXED_MINOR 0x00000080 /* LV */
/* FIXME Remove when metadata restructuring is completed */
-#define SNAPSHOT 0x00001000 /* LV - tmp internal use only */
+#define SNAPSHOT 0x00001000 /* LV - internal use only */
#define PVMOVE 0x00002000 /* VG LV SEG */
#define LOCKED 0x00004000 /* LV */
#define MIRRORED 0x00008000 /* LV - internal use only */
#define VIRTUAL 0x00010000 /* LV - internal use only */
+#define MIRROR_LOG 0x00020000 /* LV */
+#define MIRROR_IMAGE 0x00040000 /* LV */
#define LVM_READ 0x00000100 /* LV VG */
#define LVM_WRITE 0x00000200 /* LV VG */
@@ -68,6 +70,7 @@
#define FMT_UNLIMITED_VOLS 0x00000008 /* Unlimited PVs/LVs? */
#define FMT_RESTRICTED_LVIDS 0x00000010 /* LVID <= 255 */
#define FMT_ORPHAN_ALLOCATABLE 0x00000020 /* Orphan PV allocatable? */
+#define FMT_PRECOMMIT 0x00000040 /* Supports pre-commit? */
typedef enum {
ALLOC_INVALID,
@@ -98,6 +101,18 @@
void *private;
};
+struct pv_segment {
+ struct list list; /* Member of pv->segments: ordered list
+ * covering entire data area on this PV */
+
+ struct physical_volume *pv;
+ uint32_t pe;
+ uint32_t len;
+
+ struct lv_segment *lvseg; /* NULL if free space */
+ uint32_t lv_area; /* Index to area in LV segment */
+};
+
struct physical_volume {
struct id id;
struct device *dev;
@@ -113,6 +128,7 @@
uint32_t pe_count;
uint32_t pe_alloc_count;
+ struct list segments; /* Ordered pv_segments covering complete PV */
struct list tags;
};
@@ -124,6 +140,9 @@
struct volume_group *(*vg_read) (struct format_instance * fi,
const char *vg_name,
struct metadata_area * mda);
+ struct volume_group *(*vg_read_precommit) (struct format_instance * fi,
+ const char *vg_name,
+ struct metadata_area * mda);
/*
* Write out complete VG metadata. You must ensure internal
* consistency before calling. eg. PEs can't refer to PVs not
@@ -140,6 +159,9 @@
*/
int (*vg_write) (struct format_instance * fid, struct volume_group * vg,
struct metadata_area * mda);
+ int (*vg_precommit) (struct format_instance * fid,
+ struct volume_group * vg,
+ struct metadata_area * mda);
int (*vg_commit) (struct format_instance * fid,
struct volume_group * vg, struct metadata_area * mda);
int (*vg_revert) (struct format_instance * fid,
@@ -184,11 +206,8 @@
/* logical volumes */
uint32_t lv_count;
- struct list lvs;
-
- /* snapshots */
uint32_t snapshot_count;
- struct list snapshots;
+ struct list lvs;
struct list tags;
};
@@ -210,8 +229,11 @@
uint32_t area_len;
struct logical_volume *origin;
struct logical_volume *cow;
- uint32_t chunk_size;
+ struct list origin_list;
+ uint32_t chunk_size; /* For snapshots - in sectors */
+ uint32_t region_size; /* For mirrors - in sectors */
uint32_t extents_copied;
+ struct logical_volume *log_lv;
struct list tags;
@@ -220,8 +242,7 @@
area_type_t type;
union {
struct {
- struct physical_volume *pv;
- uint32_t pe;
+ struct pv_segment *pvseg;
} pv;
struct {
struct logical_volume *lv;
@@ -231,6 +252,14 @@
} area[0];
};
+#define seg_type(seg, s) (seg)->area[(s)].type
+#define seg_pvseg(seg, s) (seg)->area[(s)].u.pv.pvseg
+#define seg_pv(seg, s) (seg)->area[(s)].u.pv.pvseg->pv
+#define seg_dev(seg, s) (seg)->area[(s)].u.pv.pvseg->pv->dev
+#define seg_pe(seg, s) (seg)->area[(s)].u.pv.pvseg->pe
+#define seg_lv(seg, s) (seg)->area[(s)].u.lv.lv
+#define seg_le(seg, s) (seg)->area[(s)].u.lv.le
+
struct logical_volume {
union lvid lvid;
char *name;
@@ -246,21 +275,14 @@
uint64_t size;
uint32_t le_count;
+ uint32_t origin_count;
+ struct list snapshot_segs;
+ struct lv_segment *snapshot;
+
struct list segments;
struct list tags;
};
-struct snapshot {
- struct id id;
-
- int persistent; /* boolean */
- uint32_t chunk_size; /* in 512 byte sectors */
- uint32_t le_count;
-
- struct logical_volume *origin;
- struct logical_volume *cow;
-};
-
struct name_list {
struct list list;
char *name;
@@ -284,15 +306,14 @@
struct logical_volume *lv;
};
-struct snapshot_list {
+struct mda_list {
struct list list;
-
- struct snapshot *snapshot;
+ struct device_area mda;
};
-struct mda_list {
+struct peg_list {
struct list list;
- struct device_area mda;
+ struct pv_segment *peg;
};
/*
@@ -374,6 +395,9 @@
int vg_revert(struct volume_group *vg);
struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name,
int *consistent);
+struct volume_group *vg_read_precommitted(struct cmd_context *cmd,
+ const char *vg_name,
+ int *consistent);
struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid);
struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name,
struct list *mdas, uint64_t *label_sector,
@@ -407,20 +431,23 @@
const char *new_name);
int vg_extend(struct format_instance *fi, struct volume_group *vg,
int pv_count, char **pv_names);
+int vg_change_pesize(struct cmd_context *cmd, struct volume_group *vg,
+ uint32_t new_extent_size);
/* Manipulate LVs */
struct logical_volume *lv_create_empty(struct format_instance *fi,
const char *name,
- const char *name_format,
+ union lvid *lvid,
uint32_t status,
alloc_policy_t alloc,
+ int import,
struct volume_group *vg);
-int lv_reduce(struct format_instance *fi,
- struct logical_volume *lv, uint32_t extents);
+/* Entry point for all LV extent reductions */
+int lv_reduce(struct logical_volume *lv, uint32_t extents);
-int lv_extend(struct format_instance *fid,
- struct logical_volume *lv,
+/* Entry point for all LV extent allocations */
+int lv_extend(struct logical_volume *lv,
struct segment_type *segtype,
uint32_t stripes, uint32_t stripe_size,
uint32_t mirrors, uint32_t extents,
@@ -428,8 +455,8 @@
uint32_t status, struct list *allocatable_pvs,
alloc_policy_t alloc);
-/* lv must be part of vg->lvs */
-int lv_remove(struct volume_group *vg, struct logical_volume *lv);
+/* lv must be part of lv->vg->lvs */
+int lv_remove(struct logical_volume *lv);
/* Manipulate PV structures */
int pv_add(struct volume_group *vg, struct physical_volume *pv);
@@ -440,6 +467,8 @@
struct pv_list *find_pv_in_vg(struct volume_group *vg, const char *pv_name);
struct physical_volume *find_pv_in_vg_by_uuid(struct volume_group *vg,
struct id *id);
+int get_pv_from_vg_by_id(const struct format_type *fmt, const char *vg_name,
+ const char *id, struct physical_volume *pv);
/* Find an LV within a given VG */
struct lv_list *find_lv_in_vg(struct volume_group *vg, const char *lv_name);
@@ -463,6 +492,9 @@
/* Find LV segment containing given LE */
struct lv_segment *find_seg_by_le(struct logical_volume *lv, uint32_t le);
+/* Find PV segment containing given LE */
+struct pv_segment *find_peg_by_pe(struct physical_volume *pv, uint32_t pe);
+
/*
* Remove a dev_dir if present.
*/
@@ -471,7 +503,7 @@
/*
* Checks that an lv has no gaps or overlapping segments.
*/
-int lv_check_segments(struct logical_volume *lv);
+int check_lv_segments(struct logical_volume *lv);
/*
* Sometimes (eg, after an lvextend), it is possible to merge two
@@ -493,24 +525,34 @@
int pv_is_in_vg(struct volume_group *vg, struct physical_volume *pv);
-struct snapshot *find_cow(const struct logical_volume *lv);
-struct snapshot *find_origin(const struct logical_volume *lv);
-struct list *find_snapshots(const struct logical_volume *lv);
+struct lv_segment *find_cow(const struct logical_volume *lv);
-int vg_add_snapshot(struct logical_volume *origin, struct logical_volume *cow,
- int persistent, struct id *id, uint32_t extent_count,
+int vg_add_snapshot(struct format_instance *fid, const char *name,
+ struct logical_volume *origin, struct logical_volume *cow,
+ union lvid *lvid, uint32_t extent_count,
uint32_t chunk_size);
-int vg_remove_snapshot(struct volume_group *vg, struct logical_volume *cow);
+int vg_remove_snapshot(struct logical_volume *cow);
+
/*
* Mirroring functions
*/
+struct alloc_handle;
+int create_mirror_layers(struct alloc_handle *ah,
+ uint32_t first_area,
+ uint32_t num_mirrors,
+ struct logical_volume *lv,
+ struct segment_type *segtype,
+ uint32_t status,
+ uint32_t region_size,
+ struct logical_volume *log_lv);
int insert_pvmove_mirrors(struct cmd_context *cmd,
struct logical_volume *lv_mirr,
struct list *source_pvl,
struct logical_volume *lv,
struct list *allocatable_pvs,
+ alloc_policy_t alloc,
struct list *lvs_changed);
int remove_pvmove_mirrors(struct volume_group *vg,
struct logical_volume *lv_mirr);
@@ -527,6 +569,8 @@
struct logical_volume *lv);
uint32_t find_free_lvnum(struct logical_volume *lv);
+char *generate_lv_name(struct volume_group *vg, const char *format,
+ char *buffer, size_t len);
static inline int validate_name(const char *n)
{
@@ -540,6 +584,9 @@
if (*n == '-')
return 0;
+ if (!strcmp(n, ".") || !strcmp(n, ".."))
+ return 0;
+
while ((len++, c = *n++))
if (!isalnum(c) && c != '.' && c != '_' && c != '-' && c != '+')
return 0;
Modified: lvm2/upstream/current/lib/metadata/mirror.c
==============================================================================
--- lvm2/upstream/current/lib/metadata/mirror.c (original)
+++ lvm2/upstream/current/lib/metadata/mirror.c Tue Jun 14 11:13:22 2005
@@ -19,6 +19,142 @@
#include "segtype.h"
#include "display.h"
#include "activate.h"
+#include "lv_alloc.h"
+#include "lvm-string.h"
+
+/*
+ * Reduce mirrored_seg to num_mirrors images.
+ */
+int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors)
+{
+ uint32_t m;
+
+ for (m = num_mirrors; m < mirrored_seg->area_count; m++) {
+ if (!lv_remove(seg_lv(mirrored_seg, m))) {
+ stack;
+ return 0;
+ }
+ }
+
+ mirrored_seg->area_count = num_mirrors;
+
+ return 1;
+}
+
+int remove_all_mirror_images(struct logical_volume *lv)
+{
+ struct lv_segment *first_seg, *seg;
+ struct logical_volume *lv1;
+
+ list_iterate_items(first_seg, &lv->segments)
+ break;
+
+ if (!remove_mirror_images(first_seg, 1)) {
+ stack;
+ return 0;
+ }
+
+ if (!lv_remove(first_seg->log_lv)) {
+ stack;
+ return 0;
+ }
+
+ lv1 = seg_lv(first_seg, 0);
+
+ lv->segments = lv1->segments;
+ lv->segments.n->p = &lv->segments;
+ lv->segments.p->n = &lv->segments;
+
+ list_init(&lv1->segments);
+ lv1->le_count = 0;
+ lv1->size = 0;
+ if (!lv_remove(lv1)) {
+ stack;
+ return 0;
+ }
+
+ lv->status &= ~MIRRORED;
+
+ list_iterate_items(seg, &lv->segments)
+ seg->lv = lv;
+
+ return 1;
+}
+
+/*
+ * Add mirror images to an existing mirror
+ */
+/* FIXME
+int add_mirror_images(struct alloc_handle *ah,
+ uint32_t first_area,
+ uint32_t num_areas,
+ struct logical_volume *lv)
+{
+}
+*/
+
+int create_mirror_layers(struct alloc_handle *ah,
+ uint32_t first_area,
+ uint32_t num_mirrors,
+ struct logical_volume *lv,
+ struct segment_type *segtype,
+ uint32_t status,
+ uint32_t region_size,
+ struct logical_volume *log_lv)
+{
+ uint32_t m;
+ struct logical_volume **img_lvs;
+ char *img_name;
+ size_t len;
+
+ if (!(img_lvs = alloca(sizeof(*img_lvs) * num_mirrors))) {
+ log_error("img_lvs allocation failed. "
+ "Remove new LV and retry.");
+ return 0;
+ }
+
+ len = strlen(lv->name) + 32;
+ if (!(img_name = alloca(len))) {
+ log_error("img_name allocation failed. "
+ "Remove new LV and retry.");
+ return 0;
+ }
+
+ if (lvm_snprintf(img_name, len, "%s_mimage_%%d", lv->name) < 0) {
+ log_error("img_name allocation failed. "
+ "Remove new LV and retry.");
+ return 0;
+ }
+
+ for (m = 0; m < num_mirrors; m++) {
+ if (!(img_lvs[m] = lv_create_empty(lv->vg->fid, img_name,
+ NULL, LVM_READ | LVM_WRITE,
+ ALLOC_INHERIT, 0, lv->vg))) {\
+ log_error("Aborting. Failed to create submirror LV. "
+ "Remove new LV and retry.");
+ return 0;
+ }
+
+ if (!lv_add_segment(ah, m, 1, img_lvs[m],
+ get_segtype_from_string(lv->vg->cmd,
+ "striped"),
+ 0, NULL, 0, 0, 0, NULL)) {
+ log_error("Aborting. Failed to add submirror segment "
+ "to %s. Remove new LV and retry.",
+ img_lvs[m]->name);
+ return 0;
+ }
+ }
+
+ if (!lv_add_mirror_segment(ah, lv, img_lvs, num_mirrors, segtype,
+ 0, region_size, log_lv)) {
+ log_error("Aborting. Failed to add mirror segment. "
+ "Remove new LV and retry.");
+ return 0;
+ }
+
+ return 1;
+}
/*
* Replace any LV segments on given PV with temporary mirror.
@@ -29,9 +165,9 @@
struct list *source_pvl,
struct logical_volume *lv,
struct list *allocatable_pvs,
+ alloc_policy_t alloc,
struct list *lvs_changed)
{
- struct list *segh;
struct lv_segment *seg;
struct lv_list *lvl;
struct pv_list *pvl;
@@ -57,16 +193,15 @@
}
/* Split LV segments to match PE ranges */
- list_iterate(segh, &lv->segments) {
- seg = list_item(segh, struct lv_segment);
+ list_iterate_items(seg, &lv->segments) {
for (s = 0; s < seg->area_count; s++) {
- if (seg->area[s].type != AREA_PV ||
- seg->area[s].u.pv.pv->dev != pvl->pv->dev)
+ if (seg_type(seg, s) != AREA_PV ||
+ seg_dev(seg, s) != pvl->pv->dev)
continue;
/* Do these PEs need moving? */
list_iterate_items(per, pvl->pe_ranges) {
- pe_start = seg->area[s].u.pv.pe;
+ pe_start = seg_pe(seg, s);
pe_end = pe_start + seg->area_len - 1;
per_end = per->start + per->count - 1;
@@ -75,7 +210,7 @@
(pe_start > per_end))
continue;
- if (seg->segtype->flags & SEG_AREAS_STRIPED)
+ if (seg_is_striped(seg))
stripe_multiplier = seg->area_count;
else
stripe_multiplier = 1;
@@ -102,14 +237,13 @@
}
/* Work through all segments on the supplied PV */
- list_iterate(segh, &lv->segments) {
- seg = list_item(segh, struct lv_segment);
+ list_iterate_items(seg, &lv->segments) {
for (s = 0; s < seg->area_count; s++) {
- if (seg->area[s].type != AREA_PV ||
- seg->area[s].u.pv.pv->dev != pvl->pv->dev)
+ if (seg_type(seg, s) != AREA_PV ||
+ seg_dev(seg, s) != pvl->pv->dev)
continue;
- pe_start = seg->area[s].u.pv.pe;
+ pe_start = seg_pe(seg, s);
/* Do these PEs need moving? */
list_iterate_items(per, pvl->pe_ranges) {
@@ -121,8 +255,9 @@
log_debug("Matched PE range %u-%u against "
"%s %u len %u", per->start, per_end,
- dev_name(seg->area[s].u.pv.pv->dev),
- seg->area[s].u.pv.pe, seg->area_len);
+ dev_name(seg_dev(seg, s)),
+ seg_pe(seg, s),
+ seg->area_len);
/* First time, add LV to list of LVs affected */
if (!lv_used) {
@@ -137,25 +272,23 @@
log_very_verbose("Moving %s:%u-%u of %s/%s",
dev_name(pvl->pv->dev),
- seg->area[s].u.pv.pe,
- seg->area[s].u.pv.pe +
+ seg_pe(seg, s),
+ seg_pe(seg, s) +
seg->area_len - 1,
lv->vg->name, lv->name);
start_le = lv_mirr->le_count;
- if (!lv_extend(lv->vg->fid, lv_mirr, segtype, 1,
+ if (!lv_extend(lv_mirr, segtype, 1,
seg->area_len, 0u, seg->area_len,
- seg->area[s].u.pv.pv,
- seg->area[s].u.pv.pe,
+ seg_pv(seg, s),
+ seg_pe(seg, s),
PVMOVE, allocatable_pvs,
- lv->alloc)) {
+ alloc)) {
log_error("Unable to allocate "
"temporary LV for pvmove.");
return 0;
}
- seg->area[s].type = AREA_LV;
- seg->area[s].u.lv.lv = lv_mirr;
- seg->area[s].u.lv.le = start_le;
+ set_lv_segment_area_lv(seg, s, lv_mirr, start_le, 0);
extent_count += seg->area_len;
@@ -176,29 +309,27 @@
int remove_pvmove_mirrors(struct volume_group *vg,
struct logical_volume *lv_mirr)
{
- struct list *lvh, *segh;
+ struct lv_list *lvl;
struct logical_volume *lv1;
struct lv_segment *seg, *mir_seg;
uint32_t s, c;
/* Loop through all LVs except the temporary mirror */
- list_iterate(lvh, &vg->lvs) {
- lv1 = list_item(lvh, struct lv_list)->lv;
+ list_iterate_items(lvl, &vg->lvs) {
+ lv1 = lvl->lv;
if (lv1 == lv_mirr)
continue;
/* Find all segments that point at the temporary mirror */
- list_iterate(segh, &lv1->segments) {
- seg = list_item(segh, struct lv_segment);
+ list_iterate_items(seg, &lv1->segments) {
for (s = 0; s < seg->area_count; s++) {
- if (seg->area[s].type != AREA_LV ||
- seg->area[s].u.lv.lv != lv_mirr)
+ if (seg_type(seg, s) != AREA_LV ||
+ seg_lv(seg, s) != lv_mirr)
continue;
/* Find the mirror segment pointed at */
if (!(mir_seg = find_seg_by_le(lv_mirr,
- seg->area[s].
- u.lv.le))) {
+ seg_le(seg, s)))) {
/* FIXME Error message */
log_error("No segment found with LE");
return 0;
@@ -206,10 +337,9 @@
/* Check the segment params are compatible */
/* FIXME Improve error mesg & remove restrcn */
- if ((!(mir_seg->segtype->flags
- & SEG_AREAS_MIRRORED)) ||
+ if (!seg_is_mirrored(mir_seg) ||
!(mir_seg->status & PVMOVE) ||
- mir_seg->le != seg->area[s].u.lv.le ||
+ mir_seg->le != seg_le(seg, s) ||
mir_seg->area_count != 2 ||
mir_seg->area_len != seg->area_len) {
log_error("Incompatible segments");
@@ -225,9 +355,12 @@
else
c = 0;
- seg->area[s].type = AREA_PV;
- seg->area[s].u.pv.pv = mir_seg->area[c].u.pv.pv;
- seg->area[s].u.pv.pe = mir_seg->area[c].u.pv.pe;
+ if (!set_lv_segment_area_pv(seg, s,
+ seg_pv(mir_seg, c),
+ seg_pe(mir_seg, c))) {
+ stack;
+ return 0;
+ }
/* Replace mirror with old area */
if (!
@@ -254,16 +387,14 @@
const char *get_pvmove_pvname_from_lv_mirr(struct logical_volume *lv_mirr)
{
- struct list *segh;
struct lv_segment *seg;
- list_iterate(segh, &lv_mirr->segments) {
- seg = list_item(segh, struct lv_segment);
- if (!(seg->segtype->flags & SEG_AREAS_MIRRORED))
+ list_iterate_items(seg, &lv_mirr->segments) {
+ if (!seg_is_mirrored(seg))
continue;
if (seg->area[0].type != AREA_PV)
continue;
- return dev_name(seg->area[0].u.pv.pv->dev);
+ return dev_name(seg_dev(seg, 0));
}
return NULL;
@@ -271,16 +402,14 @@
const char *get_pvmove_pvname_from_lv(struct logical_volume *lv)
{
- struct list *segh;
struct lv_segment *seg;
uint32_t s;
- list_iterate(segh, &lv->segments) {
- seg = list_item(segh, struct lv_segment);
+ list_iterate_items(seg, &lv->segments) {
for (s = 0; s < seg->area_count; s++) {
- if (seg->area[s].type != AREA_LV)
+ if (seg_type(seg, s) != AREA_LV)
continue;
- return get_pvmove_pvname_from_lv_mirr(seg->area[s].u.lv.lv);
+ return get_pvmove_pvname_from_lv_mirr(seg_lv(seg, s));
}
}
@@ -291,23 +420,22 @@
struct device *dev,
uint32_t lv_type)
{
- struct list *lvh, *segh;
+ struct lv_list *lvl;
struct logical_volume *lv;
struct lv_segment *seg;
/* Loop through all LVs */
- list_iterate(lvh, &vg->lvs) {
- lv = list_item(lvh, struct lv_list)->lv;
+ list_iterate_items(lvl, &vg->lvs) {
+ lv = lvl->lv;
if (!(lv->status & lv_type))
continue;
/* Check segment origins point to pvname */
- list_iterate(segh, &lv->segments) {
- seg = list_item(segh, struct lv_segment);
+ list_iterate_items(seg, &lv->segments) {
if (seg->area[0].type != AREA_PV)
continue;
- if (seg->area[0].u.pv.pv->dev != dev)
+ if (seg_dev(seg, 0) != dev)
continue;
return lv;
}
@@ -334,9 +462,9 @@
struct list *lvs_using_lv(struct cmd_context *cmd, struct volume_group *vg,
struct logical_volume *lv)
{
- struct list *lvh, *segh, *lvs;
+ struct list *lvs;
struct logical_volume *lv1;
- struct lv_list *lvl;
+ struct lv_list *lvl, *lvl1;
struct lv_segment *seg;
uint32_t s;
@@ -348,17 +476,16 @@
list_init(lvs);
/* Loop through all LVs except the one supplied */
- list_iterate(lvh, &vg->lvs) {
- lv1 = list_item(lvh, struct lv_list)->lv;
+ list_iterate_items(lvl1, &vg->lvs) {
+ lv1 = lvl1->lv;
if (lv1 == lv)
continue;
/* Find whether any segment points at the supplied LV */
- list_iterate(segh, &lv1->segments) {
- seg = list_item(segh, struct lv_segment);
+ list_iterate_items(seg, &lv1->segments) {
for (s = 0; s < seg->area_count; s++) {
- if (seg->area[s].type != AREA_LV ||
- seg->area[s].u.lv.lv != lv)
+ if (seg_type(seg, s) != AREA_LV ||
+ seg_lv(seg, s) != lv)
continue;
if (!(lvl = pool_alloc(cmd->mem, sizeof(*lvl)))) {
log_error("lv_list alloc failed");
@@ -379,15 +506,12 @@
float copy_percent(struct logical_volume *lv_mirr)
{
uint32_t numerator = 0u, denominator = 0u;
- struct list *segh;
struct lv_segment *seg;
- list_iterate(segh, &lv_mirr->segments) {
- seg = list_item(segh, struct lv_segment);
-
+ list_iterate_items(seg, &lv_mirr->segments) {
denominator += seg->area_len;
- if (seg->segtype->flags & SEG_AREAS_MIRRORED)
+ if (seg_is_mirrored(seg))
numerator += seg->extents_copied;
else
numerator += seg->area_len;
Added: lvm2/upstream/current/lib/metadata/pv_alloc.h
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/lib/metadata/pv_alloc.h Tue Jun 14 11:13:22 2005
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 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_PV_ALLOC_H
+#include "pool.h"
+
+int alloc_pv_segment_whole_pv(struct pool *mem, struct physical_volume *pv);
+int peg_dup(struct pool *mem, struct list *peg_new, struct list *peg_old);
+struct pv_segment *assign_peg_to_lvseg(struct physical_volume *pv, uint32_t pe,
+ uint32_t area_len,
+ struct lv_segment *seg,
+ uint32_t area_num);
+int pv_split_segment(struct physical_volume *pv, uint32_t pe);
+int release_pv_segment(struct pv_segment *peg, uint32_t area_reduction);
+int check_pv_segments(struct volume_group *vg);
+void merge_pv_segments(struct pv_segment *peg1, struct pv_segment *peg2);
+
+#endif
Added: lvm2/upstream/current/lib/metadata/pv_manip.c
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/lib/metadata/pv_manip.c Tue Jun 14 11:13:22 2005
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2003 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
+ */
+
+#include "lib.h"
+#include "pool.h"
+#include "metadata.h"
+#include "pv_alloc.h"
+#include "toolcontext.h"
+
+static struct pv_segment *_alloc_pv_segment(struct pool *mem,
+ struct physical_volume *pv,
+ uint32_t pe, uint32_t len,
+ struct lv_segment *lvseg,
+ uint32_t lv_area)
+{
+ struct pv_segment *peg;
+
+ if (!(peg = pool_zalloc(mem, sizeof(*peg)))) {
+ log_error("pv_segment allocation failed");
+ return NULL;
+ }
+
+ peg->pv = pv;
+ peg->pe = pe;
+ peg->len = len;
+ peg->lvseg = lvseg;
+ peg->lv_area = lv_area;
+
+ list_init(&peg->list);
+
+ return peg;
+}
+
+int alloc_pv_segment_whole_pv(struct pool *mem, struct physical_volume *pv)
+{
+ struct pv_segment *peg;
+
+ if (!pv->pe_count)
+ return 1;
+
+ /* FIXME Cope with holes in PVs */
+ if (!(peg = _alloc_pv_segment(mem, pv, 0, pv->pe_count, NULL, 0))) {
+ stack;
+ return 0;
+ }
+
+ list_add(&pv->segments, &peg->list);
+
+ return 1;
+}
+
+int peg_dup(struct pool *mem, struct list *peg_new, struct list *peg_old)
+{
+ struct pv_segment *peg, *pego;
+
+ list_init(peg_new);
+
+ list_iterate_items(pego, peg_old) {
+ if (!(peg = _alloc_pv_segment(mem, pego->pv, pego->pe,
+ pego->len, pego->lvseg,
+ pego->lv_area))) {
+ stack;
+ return 0;
+ }
+ list_add(peg_new, &peg->list);
+ }
+
+ return 1;
+}
+
+/*
+ * Split peg at given extent.
+ * Second part is always deallocated.
+ */
+static int _pv_split_segment(struct physical_volume *pv, struct pv_segment *peg,
+ uint32_t pe)
+{
+ struct pv_segment *peg_new;
+
+ if (!(peg_new = _alloc_pv_segment(pv->fmt->cmd->mem, peg->pv, pe,
+ peg->len + peg->pe - pe,
+ NULL, 0))) {
+ stack;
+ return 0;
+ }
+
+ peg->len = peg->len - peg_new->len;
+
+ list_add_h(&peg->list, &peg_new->list);
+
+ return 1;
+}
+
+/*
+ * Ensure there is a PV segment boundary at the given extent.
+ */
+int pv_split_segment(struct physical_volume *pv, uint32_t pe)
+{
+ struct pv_segment *peg;
+
+ if (pe == pv->pe_count)
+ return 1;
+
+ if (!(peg = find_peg_by_pe(pv, pe))) {
+ log_error("Segment with extent %" PRIu32 " in PV %s not found",
+ pe, dev_name(pv->dev));
+ return 0;
+ }
+
+ /* This is a peg start already */
+ if (pe == peg->pe)
+ return 1;
+
+ if (!_pv_split_segment(pv, peg, pe)) {
+ stack;
+ return 0;
+ }
+
+ return 1;
+}
+
+static struct pv_segment null_pv_segment = {
+ pv: NULL,
+ pe: 0
+};
+
+struct pv_segment *assign_peg_to_lvseg(struct physical_volume *pv,
+ uint32_t pe, uint32_t area_len,
+ struct lv_segment *seg,
+ uint32_t area_num)
+{
+ struct pv_segment *peg;
+
+ /* Missing format1 PV */
+ if (!pv)
+ return &null_pv_segment;
+
+ if (!pv_split_segment(pv, pe) ||
+ !pv_split_segment(pv, pe + area_len)) {
+ stack;
+ return NULL;
+ }
+
+ if (!(peg = find_peg_by_pe(pv, pe))) {
+ log_error("Missing PV segment on %s at %u.",
+ dev_name(pv->dev), pe);
+ return NULL;
+ }
+
+ peg->lvseg = seg;
+ peg->lv_area = area_num;
+
+ return peg;
+}
+
+int release_pv_segment(struct pv_segment *peg, uint32_t area_reduction)
+{
+ peg->pv->pe_alloc_count -= area_reduction;
+
+ if (!peg->lvseg->area_len) {
+ peg->lvseg = NULL;
+ peg->lv_area = 0;
+
+ /* FIXME merge free space */
+
+ return 1;
+ }
+
+ if (!pv_split_segment(peg->pv, peg->pe + peg->lvseg->area_len)) {
+ stack;
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Only for use by lv_segment merging routines.
+ */
+void merge_pv_segments(struct pv_segment *peg1, struct pv_segment *peg2)
+{
+ peg1->len += peg2->len;
+
+ list_del(&peg2->list);
+}
+
+/*
+ * Check all pv_segments in VG for consistency
+ */
+int check_pv_segments(struct volume_group *vg)
+{
+ struct physical_volume *pv;
+ struct pv_list *pvl;
+ struct pv_segment *peg;
+ unsigned s, segno;
+ uint32_t start_pe, alloced;
+ uint32_t pv_count = 0, free_count = 0, extent_count = 0;
+ int ret = 1;
+
+ list_iterate_items(pvl, &vg->pvs) {
+ pv = pvl->pv;
+ segno = 0;
+ start_pe = 0;
+ alloced = 0;
+ pv_count++;
+
+ list_iterate_items(peg, &pv->segments) {
+ s = peg->lv_area;
+
+ /* FIXME Remove this next line eventually */
+ log_debug("%s %u: %6u %6u: %s(%u:%u)",
+ dev_name(pv->dev), segno++, peg->pe, peg->len,
+ peg->lvseg ? peg->lvseg->lv->name : "NULL",
+ peg->lvseg ? peg->lvseg->le : 0, s);
+ /* FIXME Add details here on failure instead */
+ if (start_pe != peg->pe) {
+ log_error("Gap in pvsegs: %u, %u",
+ start_pe, peg->pe);
+ ret = 0;
+ }
+ if (peg->lvseg) {
+ if (seg_type(peg->lvseg, s) != AREA_PV) {
+ log_error("Wrong lvseg area type");
+ ret = 0;
+ }
+ if (seg_pvseg(peg->lvseg, s) != peg) {
+ log_error("Inconsistent pvseg pointers");
+ ret = 0;
+ }
+ if (peg->lvseg->area_len != peg->len) {
+ log_error("Inconsistent length: %u %u",
+ peg->len,
+ peg->lvseg->area_len);
+ ret = 0;
+ }
+ alloced += peg->len;
+ }
+ start_pe += peg->len;
+ }
+
+ if (start_pe != pv->pe_count) {
+ log_error("PV segment pe_count mismatch: %u != %u",
+ start_pe, pv->pe_count);
+ ret = 0;
+ }
+
+ if (alloced != pv->pe_alloc_count) {
+ log_error("PV segment pe_alloc_count mismatch: "
+ "%u != %u", alloced, pv->pe_alloc_count);
+ ret = 0;
+ }
+
+ extent_count += start_pe;
+ free_count += (start_pe - alloced);
+ }
+
+ if (pv_count != vg->pv_count) {
+ log_error("PV segment VG pv_count mismatch: %u != %u",
+ pv_count, vg->pv_count);
+ ret = 0;
+ }
+
+ if (free_count != vg->free_count) {
+ log_error("PV segment VG free_count mismatch: %u != %u",
+ free_count, vg->free_count);
+ ret = 0;
+ }
+
+ if (extent_count != vg->extent_count) {
+ log_error("PV segment VG extent_count mismatch: %u != %u",
+ extent_count, vg->extent_count);
+ ret = 0;
+ }
+
+ return ret;
+}
Modified: lvm2/upstream/current/lib/metadata/pv_map.c
==============================================================================
--- lvm2/upstream/current/lib/metadata/pv_map.c (original)
+++ lvm2/upstream/current/lib/metadata/pv_map.c Tue Jun 14 11:13:22 2005
@@ -16,213 +16,107 @@
#include "lib.h"
#include "pv_map.h"
#include "hash.h"
-
-static int _create_maps(struct pool *mem, struct list *pvs, struct list *maps)
-{
- struct list *tmp;
- struct pv_map *pvm;
- struct pv_list *pvl;
-
- list_iterate(tmp, pvs) {
- pvl = list_item(tmp, struct pv_list);
-
- if (!(pvl->pv->status & ALLOCATABLE_PV))
- continue;
-
- if (!(pvm = pool_zalloc(mem, sizeof(*pvm)))) {
- stack;
- return 0;
- }
-
- pvm->pvl = pvl;
- if (!(pvm->allocated_extents =
- bitset_create(mem, pvl->pv->pe_count))) {
- stack;
- return 0;
- }
-
- list_init(&pvm->areas);
- list_add(maps, &pvm->list);
- }
-
- return 1;
-}
-
-static int _set_allocd(struct hash_table *hash,
- struct physical_volume *pv, uint32_t pe)
-{
- struct pv_map *pvm;
-
- if (!(pvm = (struct pv_map *) hash_lookup(hash, dev_name(pv->dev)))) {
- /*
- * it doesn't matter that this fails, it just
- * means this part of the lv is on a pv that
- * we're not interested in allocating to.
- */
- return 1;
- }
-
- /* sanity check */
- if (bit(pvm->allocated_extents, pe)) {
- log_error("Physical extent %d of %s referenced by more than "
- "one logical volume", pe, dev_name(pv->dev));
- return 0;
- }
-
- bit_set(pvm->allocated_extents, pe);
- return 1;
-}
-
-static int _fill_bitsets(struct volume_group *vg, struct list *maps)
-{
- struct list *lvh, *pvmh, *segh;
- struct logical_volume *lv;
- struct pv_map *pvm;
- uint32_t s, pe;
- struct hash_table *hash;
- struct lv_segment *seg;
- int r = 0;
-
- if (!(hash = hash_create(128))) {
- log_err("Couldn't create hash table for pv maps.");
- return 0;
- }
-
- /* populate the hash table */
- list_iterate(pvmh, maps) {
- pvm = list_item(pvmh, struct pv_map);
- if (!hash_insert(hash, dev_name(pvm->pvl->pv->dev), pvm)) {
- stack;
- goto out;
- }
- }
-
- /* iterate through all the lv's setting bit's for used pe's */
- list_iterate(lvh, &vg->lvs) {
- lv = list_item(lvh, struct lv_list)->lv;
-
- list_iterate(segh, &lv->segments) {
- seg = list_item(segh, struct lv_segment);
-
- for (s = 0u; s < seg->area_count; s++) {
- for (pe = 0u; pe < seg->area_len; pe++) {
- if (seg->area[s].type != AREA_PV)
- continue;
- if (!_set_allocd(hash,
- seg->area[s].u.pv.pv,
- seg->area[s].u.pv.pe
- + pe)) {
- stack;
- goto out;
- }
- }
- }
- }
- }
- r = 1;
-
- out:
- hash_destroy(hash);
- return r;
-}
+#include "pv_alloc.h"
/*
- * Areas are maintained in size order.
+ * Areas are maintained in size order, largest first.
*/
static void _insert_area(struct list *head, struct pv_area *a)
{
- struct list *pvah;
- struct pv_area *pva = NULL;
-
- if (list_empty(head)) {
- list_add(head, &a->list);
- return;
- }
-
- list_iterate(pvah, head) {
- pva = list_item(pvah, struct pv_area);
+ struct pv_area *pva;
- if (pva->count < a->count)
+ list_iterate_items(pva, head) {
+ if (a->count > pva->count)
break;
}
- list_add_h(&pva->list, &a->list);
+ list_add(&pva->list, &a->list);
}
static int _create_single_area(struct pool *mem, struct pv_map *pvm,
- uint32_t end, uint32_t *extent)
+ uint32_t start, uint32_t length)
{
- uint32_t e = *extent, b;
struct pv_area *pva;
- while (e <= end && bit(pvm->allocated_extents, e))
- e++;
-
- if (e > end) {
- *extent = e;
- return 1;
- }
-
- b = e++;
-
- while (e <= end && !bit(pvm->allocated_extents, e))
- e++;
-
if (!(pva = pool_zalloc(mem, sizeof(*pva)))) {
stack;
return 0;
}
log_debug("Allowing allocation on %s start PE %" PRIu32 " length %"
- PRIu32, dev_name(pvm->pvl->pv->dev), b, e - b);
+ PRIu32, dev_name(pvm->pv->dev), start, length);
pva->map = pvm;
- pva->start = b;
- pva->count = e - b;
+ pva->start = start;
+ pva->count = length;
_insert_area(&pvm->areas, pva);
- *extent = e;
return 1;
}
-static int _create_areas(struct pool *mem, struct pv_map *pvm, uint32_t start,
- uint32_t count)
+static int _create_alloc_areas_for_pv(struct pool *mem, struct pv_map *pvm,
+ uint32_t start, uint32_t count)
{
- uint32_t pe, end;
+ struct pv_segment *peg;
+ uint32_t pe, end, area_len;
+ /* Only select extents from start to end inclusive */
end = start + count - 1;
- if (end > pvm->pvl->pv->pe_count - 1)
- end = pvm->pvl->pv->pe_count - 1;
+ if (end > pvm->pv->pe_count - 1)
+ end = pvm->pv->pe_count - 1;
pe = start;
- while (pe <= end)
- if (!_create_single_area(mem, pvm, end, &pe)) {
+
+ /* Walk through complete ordered list of device segments */
+ list_iterate_items(peg, &pvm->pv->segments) {
+ /* pe holds the next extent we want to check */
+
+ /* Beyond the range we're interested in? */
+ if (pe > end)
+ break;
+
+ /* Skip if we haven't reached the first seg we want yet */
+ if (pe > peg->pe + peg->len - 1)
+ continue;
+
+ /* Free? */
+ if (peg->lvseg)
+ goto next;
+
+ /* How much of this peg do we need? */
+ area_len = (end >= peg->pe + peg->len - 1) ?
+ peg->len - (pe - peg->pe) : end - pe + 1;
+
+ if (!_create_single_area(mem, pvm, pe, area_len)) {
stack;
return 0;
}
+ next:
+ pe = peg->pe + peg->len;
+ }
+
return 1;
}
-static int _create_allocatable_areas(struct pool *mem, struct pv_map *pvm)
+static int _create_all_areas_for_pv(struct pool *mem, struct pv_map *pvm,
+ struct list *pe_ranges)
{
- struct list *alloc_areas, *aah;
struct pe_range *aa;
- alloc_areas = pvm->pvl->pe_ranges;
+ if (!pe_ranges) {
+ /* Use whole PV */
+ if (!_create_alloc_areas_for_pv(mem, pvm, UINT32_C(0),
+ pvm->pv->pe_count)) {
+ stack;
+ return 0;
+ }
- if (alloc_areas) {
- list_iterate(aah, alloc_areas) {
- aa = list_item(aah, struct pe_range);
- if (!_create_areas(mem, pvm, aa->start, aa->count)) {
- stack;
- return 0;
- }
+ return 1;
+ }
- }
- } else {
- /* Use whole PV */
- if (!_create_areas(mem, pvm, UINT32_C(0),
- pvm->pvl->pv->pe_count)) {
+ list_iterate_items(aa, pe_ranges) {
+ if (!_create_alloc_areas_for_pv(mem, pvm, aa->start,
+ aa->count)) {
stack;
return 0;
}
@@ -231,16 +125,26 @@
return 1;
}
-static int _create_all_areas(struct pool *mem, struct list *maps,
- struct list *pvs)
+static int _create_maps(struct pool *mem, struct list *pvs, struct list *pvms)
{
- struct list *tmp;
struct pv_map *pvm;
+ struct pv_list *pvl;
+
+ list_iterate_items(pvl, pvs) {
+ if (!(pvl->pv->status & ALLOCATABLE_PV))
+ continue;
+
+ if (!(pvm = pool_zalloc(mem, sizeof(*pvm)))) {
+ stack;
+ return 0;
+ }
- list_iterate(tmp, maps) {
- pvm = list_item(tmp, struct pv_map);
+ pvm->pv = pvl->pv;
- if (!_create_allocatable_areas(mem, pvm)) {
+ list_init(&pvm->areas);
+ list_add(pvms, &pvm->list);
+
+ if (!_create_all_areas_for_pv(mem, pvm, pvl->pe_ranges)) {
stack;
return 0;
}
@@ -249,40 +153,29 @@
return 1;
}
+/*
+ * Create list of PV areas available for this particular allocation
+ */
struct list *create_pv_maps(struct pool *mem, struct volume_group *vg,
- struct list *pvs)
+ struct list *allocatable_pvs)
{
- struct list *maps = pool_zalloc(mem, sizeof(*maps));
+ struct list *pvms;
- if (!maps) {
- stack;
+ if (!(pvms = pool_zalloc(mem, sizeof(*pvms)))) {
+ log_error("create_pv_maps alloc failed");
return NULL;
}
- list_init(maps);
+ list_init(pvms);
- if (!_create_maps(mem, pvs, maps)) {
+ if (!_create_maps(mem, allocatable_pvs, pvms)) {
log_error("Couldn't create physical volume maps in %s",
vg->name);
- goto bad;
- }
-
- if (!_fill_bitsets(vg, maps)) {
- log_error("Couldn't fill extent allocation bitmaps in %s",
- vg->name);
- goto bad;
- }
-
- if (!_create_all_areas(mem, maps, pvs)) {
- log_error("Couldn't create area maps in %s", vg->name);
- goto bad;
+ pool_free(mem, pvms);
+ return NULL;
}
- return maps;
-
- bad:
- pool_free(mem, maps);
- return NULL;
+ return pvms;
}
void consume_pv_area(struct pv_area *pva, uint32_t to_go)
Modified: lvm2/upstream/current/lib/metadata/pv_map.h
==============================================================================
--- lvm2/upstream/current/lib/metadata/pv_map.h (original)
+++ lvm2/upstream/current/lib/metadata/pv_map.h Tue Jun 14 11:13:22 2005
@@ -33,19 +33,21 @@
uint32_t start;
uint32_t count;
- struct list list;
+ struct list list; /* pv_map.areas */
};
struct pv_map {
- struct pv_list *pvl;
- bitset_t allocated_extents;
- struct list areas;
+ struct physical_volume *pv;
+ struct list areas; /* struct pv_areas */
struct list list;
};
-struct list *create_pv_maps(struct pool *mem,
- struct volume_group *vg, struct list *pvs);
+/*
+ * Find intersection between available_pvs and free space in VG
+ */
+struct list *create_pv_maps(struct pool *mem, struct volume_group *vg,
+ struct list *allocatable_pvs);
void consume_pv_area(struct pv_area *area, uint32_t to_go);
Modified: lvm2/upstream/current/lib/metadata/segtype.h
==============================================================================
--- lvm2/upstream/current/lib/metadata/segtype.h (original)
+++ lvm2/upstream/current/lib/metadata/segtype.h Tue Jun 14 11:13:22 2005
@@ -33,6 +33,16 @@
#define SEG_FORMAT1_SUPPORT 0x00000010
#define SEG_VIRTUAL 0x00000020
+#define seg_is_mirrored(seg) ((seg)->segtype->flags & SEG_AREAS_MIRRORED ? 1 : 0)
+#define seg_is_striped(seg) ((seg)->segtype->flags & SEG_AREAS_STRIPED ? 1 : 0)
+#define seg_is_snapshot(seg) ((seg)->segtype->flags & SEG_SNAPSHOT ? 1 : 0)
+#define seg_is_virtual(seg) ((seg)->segtype->flags & SEG_VIRTUAL ? 1 : 0)
+#define seg_can_split(seg) ((seg)->segtype->flags & SEG_CAN_SPLIT ? 1 : 0)
+
+#define segtype_is_striped(segtype) ((segtype)->flags & SEG_AREAS_STRIPED ? 1 : 0)
+#define segtype_is_mirrored(segtype) ((segtype)->flags & SEG_AREAS_MIRRORED ? 1 : 0)
+#define segtype_is_virtual(segtype) ((segtype)->flags & SEG_VIRTUAL ? 1 : 0)
+
struct segment_type {
struct list list;
struct cmd_context *cmd;
Modified: lvm2/upstream/current/lib/metadata/snapshot_manip.c
==============================================================================
--- lvm2/upstream/current/lib/metadata/snapshot_manip.c (original)
+++ lvm2/upstream/current/lib/metadata/snapshot_manip.c Tue Jun 14 11:13:22 2005
@@ -16,101 +16,31 @@
#include "lib.h"
#include "metadata.h"
#include "toolcontext.h"
+#include "lv_alloc.h"
int lv_is_origin(const struct logical_volume *lv)
{
- struct list *slh;
- struct snapshot *s;
-
- list_iterate(slh, &lv->vg->snapshots) {
- s = list_item(slh, struct snapshot_list)->snapshot;
- if (s->origin == lv)
- return 1;
- }
-
- return 0;
+ return lv->origin_count ? 1 : 0;
}
int lv_is_cow(const struct logical_volume *lv)
{
- struct list *slh;
- struct snapshot *s;
-
- list_iterate(slh, &lv->vg->snapshots) {
- s = list_item(slh, struct snapshot_list)->snapshot;
- if (s->cow == lv)
- return 1;
- }
-
- return 0;
-}
-
-struct snapshot *find_origin(const struct logical_volume *lv)
-{
- struct list *slh;
- struct snapshot *s;
-
- list_iterate(slh, &lv->vg->snapshots) {
- s = list_item(slh, struct snapshot_list)->snapshot;
- if (s->origin == lv)
- return s;
- }
-
- return NULL;
+ return lv->snapshot ? 1 : 0;
}
-struct snapshot *find_cow(const struct logical_volume *lv)
+/* Given a cow LV, return the snapshot lv_segment that uses it */
+struct lv_segment *find_cow(const struct logical_volume *lv)
{
- struct list *slh;
- struct snapshot *s;
-
- list_iterate(slh, &lv->vg->snapshots) {
- s = list_item(slh, struct snapshot_list)->snapshot;
- if (s->cow == lv)
- return s;
- }
-
- return NULL;
+ return lv->snapshot;
}
-struct list *find_snapshots(const struct logical_volume *lv)
+int vg_add_snapshot(struct format_instance *fid, const char *name,
+ struct logical_volume *origin,
+ struct logical_volume *cow, union lvid *lvid,
+ uint32_t extent_count, uint32_t chunk_size)
{
- struct list *slh;
- struct list *snaplist;
- struct snapshot *s;
- struct snapshot_list *newsl;
- struct pool *mem = lv->vg->cmd->mem;
-
- if (!(snaplist = pool_alloc(mem, sizeof(*snaplist)))) {
- log_error("snapshot name list allocation failed");
- return NULL;
- }
-
- list_init(snaplist);
-
- list_iterate(slh, &lv->vg->snapshots) {
- s = list_item(slh, struct snapshot_list)->snapshot;
- if (!(s->origin == lv))
- continue;
- if (!(newsl = pool_alloc(mem, sizeof(*newsl)))) {
- log_error("snapshot_list structure allocation failed");
- pool_free(mem, snaplist);
- return NULL;
- }
- newsl->snapshot = s;
- list_add(snaplist, &newsl->list);
- }
-
- return snaplist;
-}
-
-int vg_add_snapshot(struct logical_volume *origin, struct logical_volume *cow,
- int persistent, struct id *id, uint32_t extent_count,
- uint32_t chunk_size)
-{
- struct snapshot *s;
- struct snapshot_list *sl;
- struct pool *mem = origin->vg->cmd->mem;
+ struct logical_volume *snap;
+ struct lv_segment *seg;
/*
* Is the cow device already being used ?
@@ -120,55 +50,53 @@
return 0;
}
- if (!(s = pool_alloc(mem, sizeof(*s)))) {
+ if (!(snap = lv_create_empty(fid, name ? name : "snapshot%d",
+ lvid, LVM_READ | LVM_WRITE | VISIBLE_LV,
+ ALLOC_INHERIT, 1, origin->vg))) {
stack;
return 0;
}
- s->persistent = persistent;
- s->chunk_size = chunk_size;
- s->le_count = extent_count;
- s->origin = origin;
- s->cow = cow;
-
- if (id)
- s->id = *id;
- else if (!id_create(&s->id)) {
- log_error("Random UUID creation failed for snapshot %s.",
- cow->name);
- return 0;
- }
+ snap->le_count = extent_count;
- if (!(sl = pool_alloc(mem, sizeof(*sl)))) {
+ if (!(seg = alloc_snapshot_seg(snap, 0, 0))) {
stack;
- pool_free(mem, s);
return 0;
}
- cow->status &= ~VISIBLE_LV;
- sl->snapshot = s;
- list_add(&origin->vg->snapshots, &sl->list);
+ seg->chunk_size = chunk_size;
+ seg->origin = origin;
+ seg->cow = cow;
+ seg->lv->status |= SNAPSHOT;
+
+ origin->origin_count++;
origin->vg->snapshot_count++;
+ origin->vg->lv_count--;
+ cow->snapshot = seg;
+
+ cow->status &= ~VISIBLE_LV;
+
+ list_add(&origin->snapshot_segs, &seg->origin_list);
return 1;
}
-int vg_remove_snapshot(struct volume_group *vg, struct logical_volume *cow)
+int vg_remove_snapshot(struct logical_volume *cow)
{
- struct list *slh;
- struct snapshot_list *sl;
-
- list_iterate(slh, &vg->snapshots) {
- sl = list_item(slh, struct snapshot_list);
+ list_del(&cow->snapshot->origin_list);
+ cow->snapshot->origin->origin_count--;
- if (sl->snapshot->cow == cow) {
- list_del(slh);
- vg->snapshot_count--;
- return 1;
- }
+ if (!lv_remove(cow->snapshot->lv)) {
+ log_error("Failed to remove internal snapshot LV %s",
+ cow->snapshot->lv->name);
+ return 0;
}
- /* fail */
- log_err("Asked to remove an unknown snapshot.");
- return 0;
+ cow->snapshot = NULL;
+
+ cow->vg->snapshot_count--;
+ cow->vg->lv_count++;
+ cow->status |= VISIBLE_LV;
+
+ return 1;
}
Modified: lvm2/upstream/current/lib/mirror/mirrored.c
==============================================================================
--- lvm2/upstream/current/lib/mirror/mirrored.c (original)
+++ lvm2/upstream/current/lib/mirror/mirrored.c Tue Jun 14 11:13:22 2005
@@ -35,7 +35,7 @@
};
struct mirror_state {
- uint32_t region_size;
+ uint32_t default_region_size;
};
static const char *_name(const struct lv_segment *seg)
@@ -45,14 +45,25 @@
static void _display(const struct lv_segment *seg)
{
+ const char *size;
+
log_print(" Mirrors\t\t%u", seg->area_count);
log_print(" Mirror size\t\t%u", seg->area_len);
+ if (seg->log_lv)
+ log_print(" Mirror log volume\t%s", seg->log_lv->name);
+
+ if (seg->region_size) {
+ size = display_size(seg->lv->vg->cmd,
+ (uint64_t) seg->region_size,
+ SIZE_SHORT);
+ log_print(" Mirror region size\t%s", size);
+ }
+
log_print(" Mirror original:");
display_stripe(seg, 0, " ");
log_print(" Mirror destination:");
display_stripe(seg, 1, " ");
log_print(" ");
-
}
static int _text_import_area_count(struct config_node *sn, uint32_t *area_count)
@@ -70,6 +81,7 @@
struct hash_table *pv_hash)
{
const struct config_node *cn;
+ char *logname = NULL;
if (find_config_node(sn, "extents_moved")) {
if (get_config_uint32(sn, "extents_moved",
@@ -82,13 +94,42 @@
}
}
+ if (find_config_node(sn, "region_size")) {
+ if (!get_config_uint32(sn, "region_size",
+ &seg->region_size)) {
+ log_error("Couldn't read 'region_size' for "
+ "segment '%s'.", sn->key);
+ return 0;
+ }
+ }
+
+ if ((cn = find_config_node(sn, "mirror_log"))) {
+ if (!cn->v || !cn->v->v.str) {
+ log_error("Mirror log type must be a string.");
+ return 0;
+ }
+ logname = cn->v->v.str;
+ if (!(seg->log_lv = find_lv(seg->lv->vg, logname))) {
+ log_error("Unrecognised mirror log in segment %s.",
+ sn->key);
+ return 0;
+ }
+ seg->log_lv->status |= MIRROR_LOG;
+ }
+
+ if (logname && !seg->region_size) {
+ log_error("Missing region size for mirror log for segment "
+ "'%s'.", sn->key);
+ return 0;
+ }
+
if (!(cn = find_config_node(sn, "mirrors"))) {
log_error("Couldn't find mirrors array for segment "
"'%s'.", sn->key);
return 0;
}
- return text_import_areas(seg, sn, cn, pv_hash);
+ return text_import_areas(seg, sn, cn, pv_hash, MIRROR_IMAGE);
}
static int _text_export(const struct lv_segment *seg, struct formatter *f)
@@ -96,7 +137,11 @@
outf(f, "mirror_count = %u", seg->area_count);
if (seg->status & PVMOVE)
out_size(f, (uint64_t) seg->extents_copied * seg->lv->vg->extent_size,
- "extents_moved = %u", seg->extents_copied);
+ "extents_moved = %" PRIu32, seg->extents_copied);
+ if (seg->log_lv)
+ outf(f, "mirror_log = \"%s\"", seg->log_lv->name);
+ if (seg->region_size)
+ outf(f, "region_size = %" PRIu32, seg->region_size);
return out_areas(f, seg, "mirror");
}
@@ -112,7 +157,7 @@
return NULL;
}
- mirr_state->region_size = 2 *
+ mirr_state->default_region_size = 2 *
find_config_int(cft->root,
"activation/mirror_region_size",
DEFAULT_MIRROR_REGION_SIZE);
@@ -131,6 +176,7 @@
int areas = seg->area_count;
int start_area = 0u;
uint32_t region_size, region_max;
+ int ret;
if (!*target_state)
*target_state = _init_target(mem, cft);
@@ -155,21 +201,29 @@
} else {
*target = "mirror";
- /* Find largest power of 2 region size unit we can use */
- region_max = (1 << (ffs(seg->area_len) - 1)) *
+ if (!(seg->status & PVMOVE)) {
+ if (!seg->region_size) {
+ log_error("Missing region size for mirror segment.");
+ return 0;
+ }
+ region_size = seg->region_size;
+ } else {
+ /* Find largest power of 2 region size unit we can use */
+ region_max = (1 << (ffs(seg->area_len) - 1)) *
seg->lv->vg->extent_size;
- region_size = mirr_state->region_size;
- if (region_max < region_size) {
- region_size = region_max;
- log_verbose("Using reduced mirror region size of %u sectors",
- region_size);
+ region_size = mirr_state->default_region_size;
+ if (region_max < region_size) {
+ region_size = region_max;
+ log_verbose("Using reduced mirror region size of %u sectors",
+ region_size);
+ }
}
- if ((*pos = lvm_snprintf(params, paramsize, "core 1 %u %u ",
- region_size, areas)) < 0) {
+ if ((ret = compose_log_line(dm, seg, params, paramsize, pos,
+ areas, region_size)) <= 0) {
stack;
- return -1;
+ return ret;
}
}
Modified: lvm2/upstream/current/lib/misc/lvm-file.c
==============================================================================
--- lvm2/upstream/current/lib/misc/lvm-file.c (original)
+++ lvm2/upstream/current/lib/misc/lvm-file.c Tue Jun 14 11:13:22 2005
@@ -86,7 +86,11 @@
{
struct stat buf;
- link(old, new);
+ if (link(old, new)) {
+ log_error("%s: rename to %s failed: %s", old, new,
+ strerror(errno));
+ return 0;
+ }
if (stat(old, &buf)) {
log_sys_error("stat", old);
@@ -148,7 +152,8 @@
if (*orig) {
rc = mkdir(orig, 0777);
if (rc < 0 && errno != EEXIST) {
- log_sys_error("mkdir", orig);
+ if (errno != EROFS)
+ log_sys_error("mkdir", orig);
dbg_free(orig);
return 0;
}
@@ -160,7 +165,8 @@
/* Create final directory */
rc = mkdir(dir, 0777);
if (rc < 0 && errno != EEXIST) {
- log_sys_error("mkdir", dir);
+ if (errno != EROFS)
+ log_sys_error("mkdir", dir);
return 0;
}
return 1;
Modified: lvm2/upstream/current/lib/misc/selinux.c
==============================================================================
--- lvm2/upstream/current/lib/misc/selinux.c (original)
+++ lvm2/upstream/current/lib/misc/selinux.c Tue Jun 14 11:13:22 2005
@@ -18,25 +18,28 @@
#include <selinux/selinux.h>
-int set_selinux_context(const char *path)
+int set_selinux_context(const char *path, mode_t mode)
{
security_context_t scontext;
- log_very_verbose("Setting SELinux context for %s", path);
if (is_selinux_enabled() <= 0)
return 1;
- if (matchpathcon(path, 0, &scontext) < 0) {
- log_sys_error("matchpathcon", path);
+ if (matchpathcon(path, mode, &scontext) < 0) {
+ log_error("%s: matchpathcon %07o failed: %s", path, mode,
+ strerror(errno));
return 0;
}
+ log_very_verbose("Setting SELinux context for %s to %s.",
+ path, scontext);
+
if ((lsetfilecon(path, scontext) < 0) && (errno != ENOTSUP)) {
log_sys_error("lsetfilecon", path);
- free(scontext);
+ freecon(scontext);
return 0;
}
- free(scontext);
+ freecon(scontext);
return 1;
}
Modified: lvm2/upstream/current/lib/misc/selinux.h
==============================================================================
--- lvm2/upstream/current/lib/misc/selinux.h (original)
+++ lvm2/upstream/current/lib/misc/selinux.h Tue Jun 14 11:13:22 2005
@@ -15,6 +15,8 @@
#ifndef _LVM_SELINUX_H
#define _LVM_SELINUX_H
-int set_selinux_context(const char * path);
+#include <sys/types.h>
+
+int set_selinux_context(const char * path, mode_t mode);
#endif
Modified: lvm2/upstream/current/lib/mm/dbg_malloc.c
==============================================================================
--- lvm2/upstream/current/lib/mm/dbg_malloc.c (original)
+++ lvm2/upstream/current/lib/mm/dbg_malloc.c Tue Jun 14 11:13:22 2005
@@ -19,6 +19,16 @@
#include <stdarg.h>
+char *dbg_strdup(const char *str)
+{
+ char *ret = dbg_malloc(strlen(str) + 1);
+
+ if (ret)
+ strcpy(ret, str);
+
+ return ret;
+}
+
#ifdef DEBUG_MEM
struct memblock {
@@ -102,6 +112,9 @@
if (_mem_stats.bytes > _mem_stats.mbytes)
_mem_stats.mbytes = _mem_stats.bytes;
+ /* log_debug("Allocated: %u %u %u", nb->id, _mem_stats.blocks_allocated,
+ _mem_stats.bytes); */
+
return nb + 1;
}
@@ -183,6 +196,8 @@
for (c = 0; c < sizeof(str) - 1; c++) {
if (c >= mb->length)
str[c] = ' ';
+ else if (*(char *)(mb->magic + c) == '\0')
+ str[c] = '\0';
else if (*(char *)(mb->magic + c) < ' ')
str[c] = '?';
else
Modified: lvm2/upstream/current/lib/mm/dbg_malloc.h
==============================================================================
--- lvm2/upstream/current/lib/mm/dbg_malloc.h (original)
+++ lvm2/upstream/current/lib/mm/dbg_malloc.h Tue Jun 14 11:13:22 2005
@@ -21,7 +21,9 @@
#include <string.h>
void *malloc_aux(size_t s, const char *file, int line);
-# define dbg_malloc(s) malloc_aux((s), __FILE__, __LINE__)
+#define dbg_malloc(s) malloc_aux((s), __FILE__, __LINE__)
+
+char *dbg_strdup(const char *str);
#ifdef DEBUG_MEM
@@ -42,14 +44,4 @@
#endif
-static inline char *dbg_strdup(const char *str)
-{
- char *ret = dbg_malloc(strlen(str) + 1);
-
- if (ret)
- strcpy(ret, str);
-
- return ret;
-}
-
#endif
Modified: lvm2/upstream/current/lib/report/columns.h
==============================================================================
--- lvm2/upstream/current/lib/report/columns.h (original)
+++ lvm2/upstream/current/lib/report/columns.h Tue Jun 14 11:13:22 2005
@@ -19,7 +19,7 @@
/* *INDENT-OFF* */
FIELD(LVS, lv, STR, "LV UUID", lvid.id[1], 38, uuid, "lv_uuid")
-FIELD(LVS, lv, STR, "LV", name, 4, string, "lv_name")
+FIELD(LVS, lv, STR, "LV", lvid, 4, lvname, "lv_name")
FIELD(LVS, lv, STR, "Attr", lvid, 4, lvstatus, "lv_attr")
FIELD(LVS, lv, NUM, "Maj", major, 3, int32, "lv_major")
FIELD(LVS, lv, NUM, "Min", minor, 3, int32, "lv_minor")
@@ -32,6 +32,7 @@
FIELD(LVS, lv, NUM, "Copy%", lvid, 6, copypercent, "copy_percent")
FIELD(LVS, lv, STR, "Move", lvid, 4, movepv, "move_pv")
FIELD(LVS, lv, STR, "LV Tags", tags, 7, tags, "lv_tags")
+FIELD(LVS, lv, STR, "Log", lvid, 3, loglv, "mirror_log")
FIELD(PVS, pv, STR, "Fmt", id, 3, pvfmt, "pv_fmt")
FIELD(PVS, pv, STR, "PV UUID", id, 38, uuid, "pv_uuid")
@@ -67,8 +68,12 @@
FIELD(SEGS, seg, NUM, "#Str", area_count, 4, uint32, "stripes")
FIELD(SEGS, seg, NUM, "Stripe", stripe_size, 6, size32, "stripesize")
FIELD(SEGS, seg, NUM, "Chunk", chunk_size, 5, size32, "chunksize")
+FIELD(SEGS, seg, NUM, "Region", region_size, 6, size32, "regionsize")
FIELD(SEGS, seg, NUM, "Start", list, 5, segstart, "seg_start")
FIELD(SEGS, seg, NUM, "SSize", list, 5, segsize, "seg_size")
FIELD(SEGS, seg, STR, "Seg Tags", tags, 8, tags, "seg_tags")
FIELD(SEGS, seg, STR, "Devices", list, 5, devices, "devices")
+
+FIELD(PVSEGS, pvseg, NUM, "Start", pe, 5, uint32, "pvseg_start")
+FIELD(PVSEGS, pvseg, NUM, "SSize", len, 5, uint32, "pvseg_size")
/* *INDENT-ON* */
Modified: lvm2/upstream/current/lib/report/report.c
==============================================================================
--- lvm2/upstream/current/lib/report/report.c (original)
+++ lvm2/upstream/current/lib/report/report.c Tue Jun 14 11:13:22 2005
@@ -31,6 +31,7 @@
struct logical_volume _lv;
struct volume_group _vg;
struct lv_segment _seg;
+ struct pv_segment _pvseg;
} _dummy;
/*
@@ -153,14 +154,14 @@
}
for (s = 0; s < seg->area_count; s++) {
- switch (seg->area[s].type) {
+ switch (seg_type(seg, s)) {
case AREA_LV:
- name = seg->area[s].u.lv.lv->name;
- extent = seg->area[s].u.lv.le;
+ name = seg_lv(seg, s)->name;
+ extent = seg_le(seg, s);
break;
case AREA_PV:
- name = dev_name(seg->area[s].u.pv.pv->dev);
- extent = seg->area[s].u.pv.pe;
+ name = dev_name(seg_dev(seg, s));
+ extent = seg_pe(seg, s);
break;
default:
name = "unknown";
@@ -324,7 +325,7 @@
const struct logical_volume *lv = (const struct logical_volume *) data;
struct lvinfo info;
char *repstr;
- struct snapshot *snap;
+ struct lv_segment *snap_seg;
float snap_percent;
if (!(repstr = pool_zalloc(rh->mem, 7))) {
@@ -336,6 +337,10 @@
repstr[0] = 'p';
else if (lv->status & MIRRORED)
repstr[0] = 'm';
+ else if (lv->status & MIRROR_IMAGE)
+ repstr[0] = 'i';
+ else if (lv->status & MIRROR_LOG)
+ repstr[0] = 'l';
else if (lv->status & VIRTUAL)
repstr[0] = 'v';
else if (lv_is_origin(lv))
@@ -373,8 +378,8 @@
repstr[5] = '-';
/* Snapshot dropped? */
- if ((snap = find_cow(lv)) &&
- (!lv_snapshot_percent(snap->cow, &snap_percent) ||
+ if ((snap_seg = find_cow(lv)) &&
+ (!lv_snapshot_percent(snap_seg->cow, &snap_percent) ||
snap_percent < 0 || snap_percent >= 100)) {
repstr[0] = toupper(repstr[0]);
if (info.suspended)
@@ -478,10 +483,10 @@
const void *data)
{
const struct logical_volume *lv = (const struct logical_volume *) data;
- struct snapshot *snap;
+ struct lv_segment *snap_seg;
- if ((snap = find_cow(lv)))
- return _string_disp(rh, field, &snap->origin->name);
+ if ((snap_seg = find_cow(lv)))
+ return _string_disp(rh, field, &snap_seg->origin->name);
field->report_string = "";
field->sort_value = (const void *) field->report_string;
@@ -489,19 +494,68 @@
return 1;
}
+static int _loglv_disp(struct report_handle *rh, struct field *field,
+ const void *data)
+{
+ const struct logical_volume *lv = (const struct logical_volume *) data;
+ struct lv_segment *seg;
+
+ list_iterate_items(seg, &lv->segments) {
+ if (!seg_is_mirrored(seg) || !seg->log_lv)
+ continue;
+ return _string_disp(rh, field, &seg->log_lv->name);
+ }
+
+ field->report_string = "";
+ field->sort_value = (const void *) field->report_string;
+
+ return 1;
+}
+
+static int _lvname_disp(struct report_handle *rh, struct field *field,
+ const void *data)
+{
+ const struct logical_volume *lv = (const struct logical_volume *) data;
+ char *repstr;
+ size_t len;
+
+ if (lv->status & VISIBLE_LV) {
+ repstr = lv->name;
+ return _string_disp(rh, field, &repstr);
+ }
+
+ len = strlen(lv->name) + 3;
+ if (!(repstr = pool_zalloc(rh->mem, len))) {
+ log_error("pool_alloc failed");
+ return 0;
+ }
+
+ if (lvm_snprintf(repstr, len, "[%s]", lv->name) < 0) {
+ log_error("lvname snprintf failed");
+ return 0;
+ }
+
+ field->report_string = repstr;
+
+ if (!(field->sort_value = pool_strdup(rh->mem, lv->name))) {
+ log_error("pool_strdup failed");
+ return 0;
+ }
+
+ return 1;
+}
+
static int _movepv_disp(struct report_handle *rh, struct field *field,
const void *data)
{
const struct logical_volume *lv = (const struct logical_volume *) data;
const char *name;
- struct list *segh;
struct lv_segment *seg;
- list_iterate(segh, &lv->segments) {
- seg = list_item(segh, struct lv_segment);
+ list_iterate_items(seg, &lv->segments) {
if (!(seg->status & PVMOVE))
continue;
- name = dev_name(seg->area[0].u.pv.pv->dev);
+ name = dev_name(seg_dev(seg, 0));
return _string_disp(rh, field, &name);
}
@@ -762,7 +816,7 @@
const void *data)
{
const struct logical_volume *lv = (const struct logical_volume *) data;
- struct snapshot *snap;
+ struct lv_segment *snap_seg;
struct lvinfo info;
float snap_percent;
uint64_t *sortval;
@@ -773,15 +827,16 @@
return 0;
}
- if (!(snap = find_cow(lv)) ||
- (lv_info(snap->cow, &info, 0) && !info.exists)) {
+ if (!(snap_seg = find_cow(lv)) ||
+ (lv_info(snap_seg->cow, &info, 0) && !info.exists)) {
field->report_string = "";
*sortval = UINT64_C(0);
field->sort_value = sortval;
return 1;
}
- if (!lv_snapshot_percent(snap->cow, &snap_percent) || snap_percent < 0) {
+ if (!lv_snapshot_percent(snap_seg->cow, &snap_percent)
+ || snap_percent < 0) {
field->report_string = "100.00";
*sortval = UINT64_C(100);
field->sort_value = sortval;
@@ -855,9 +910,9 @@
static struct {
report_type_t type;
- const char id[30];
+ const char id[32];
off_t offset;
- const char heading[30];
+ const char heading[32];
int width;
uint32_t flags;
field_report_fn report_fn;
@@ -915,12 +970,9 @@
static int _add_sort_key(struct report_handle *rh, uint32_t field_num,
uint32_t flags)
{
- struct list *fh;
struct field_properties *fp, *found = NULL;
- list_iterate(fh, &rh->field_props) {
- fp = list_item(fh, struct field_properties);
-
+ list_iterate_items(fp, &rh->field_props) {
if (fp->field_num == field_num) {
found = fp;
break;
@@ -1077,6 +1129,9 @@
case SEGS:
rh->field_prefix = "seg_";
break;
+ case PVSEGS:
+ rh->field_prefix = "pvseg_";
+ break;
default:
rh->field_prefix = "";
}
@@ -1096,6 +1151,8 @@
/* Ensure options selected are compatible */
if (rh->type & SEGS)
rh->type |= LVS;
+ if (rh->type & PVSEGS)
+ rh->type |= PVS;
if ((rh->type & LVS) && (rh->type & PVS)) {
log_error("Can't report LV and PV fields at the same time");
return NULL;
@@ -1106,6 +1163,8 @@
*report_type = SEGS;
else if (rh->type & LVS)
*report_type = LVS;
+ else if (rh->type & PVSEGS)
+ *report_type = PVSEGS;
else if (rh->type & PVS)
*report_type = PVS;
@@ -1126,10 +1185,9 @@
*/
int report_object(void *handle, struct volume_group *vg,
struct logical_volume *lv, struct physical_volume *pv,
- struct lv_segment *seg)
+ struct lv_segment *seg, struct pv_segment *pvseg)
{
struct report_handle *rh = handle;
- struct list *fh;
struct field_properties *fp;
struct row *row;
struct field *field;
@@ -1159,9 +1217,7 @@
list_add(&rh->rows, &row->list);
/* For each field to be displayed, call its report_fn */
- list_iterate(fh, &rh->field_props) {
- fp = list_item(fh, struct field_properties);
-
+ list_iterate_items(fp, &rh->field_props) {
skip = 0;
if (!(field = pool_zalloc(rh->mem, sizeof(*field)))) {
@@ -1186,6 +1242,9 @@
break;
case SEGS:
data = (void *) seg + _fields[fp->field_num].offset;
+ break;
+ case PVSEGS:
+ data = (void *) pvseg + _fields[fp->field_num].offset;
}
if (skip) {
@@ -1219,7 +1278,6 @@
static int _report_headings(void *handle)
{
struct report_handle *rh = handle;
- struct list *fh;
struct field_properties *fp;
const char *heading;
char buf[1024];
@@ -1238,8 +1296,7 @@
}
/* First heading line */
- list_iterate(fh, &rh->field_props) {
- fp = list_item(fh, struct field_properties);
+ list_iterate_items(fp, &rh->field_props) {
if (fp->flags & FLD_HIDDEN)
continue;
@@ -1256,7 +1313,7 @@
} else if (!pool_grow_object(rh->mem, heading, strlen(heading)))
goto bad;
- if (!list_end(&rh->field_props, fh))
+ if (!list_end(&rh->field_props, &fp->list))
if (!pool_grow_object(rh->mem, rh->separator,
strlen(rh->separator)))
goto bad;
@@ -1324,7 +1381,6 @@
static int _sort_rows(struct report_handle *rh)
{
struct row *(*rows)[];
- struct list *rowh;
uint32_t count = 0;
struct row *row;
@@ -1334,10 +1390,8 @@
return 0;
}
- list_iterate(rowh, &rh->rows) {
- row = list_item(rowh, struct row);
+ list_iterate_items(row, &rh->rows)
(*rows)[count++] = row;
- }
qsort(rows, count, sizeof(**rows), _row_compare);
Modified: lvm2/upstream/current/lib/report/report.h
==============================================================================
--- lvm2/upstream/current/lib/report/report.h (original)
+++ lvm2/upstream/current/lib/report/report.h Tue Jun 14 11:13:22 2005
@@ -18,7 +18,7 @@
#include "metadata.h"
-typedef enum { LVS = 1, PVS = 2, VGS = 4, SEGS = 8 } report_type_t;
+typedef enum { LVS = 1, PVS = 2, VGS = 4, SEGS = 8, PVSEGS = 16 } report_type_t;
struct field;
struct report_handle;
@@ -32,7 +32,7 @@
void report_free(void *handle);
int report_object(void *handle, struct volume_group *vg,
struct logical_volume *lv, struct physical_volume *pv,
- struct lv_segment *seg);
+ struct lv_segment *seg, struct pv_segment *pvseg);
int report_output(void *handle);
#endif
Modified: lvm2/upstream/current/lib/snapshot/snapshot.c
==============================================================================
--- lvm2/upstream/current/lib/snapshot/snapshot.c (original)
+++ lvm2/upstream/current/lib/snapshot/snapshot.c Tue Jun 14 11:13:22 2005
@@ -70,8 +70,8 @@
return 0;
}
- if (!vg_add_snapshot(org, cow, 1, &seg->lv->lvid.id[1], seg->len,
- chunk_size)) {
+ if (!vg_add_snapshot(seg->lv->vg->fid, seg->lv->name, org, cow,
+ &seg->lv->lvid, seg->len, chunk_size)) {
stack;
return 0;
}
Modified: lvm2/upstream/current/lib/striped/striped.c
==============================================================================
--- lvm2/upstream/current/lib/striped/striped.c (original)
+++ lvm2/upstream/current/lib/striped/striped.c Tue Jun 14 11:13:22 2005
@@ -26,6 +26,7 @@
#include "targets.h"
#include "lvm-string.h"
#include "activate.h"
+#include "pv_alloc.h"
static const char *_name(const struct lv_segment *seg)
{
@@ -81,7 +82,7 @@
seg->area_len /= seg->area_count;
- return text_import_areas(seg, sn, cn, pv_hash);
+ return text_import_areas(seg, sn, cn, pv_hash, 0);
}
static int _text_export(const struct lv_segment *seg, struct formatter *f)
@@ -118,8 +119,10 @@
width = first->area_len;
- if ((first->area[s].u.pv.pv != second->area[s].u.pv.pv) ||
- (first->area[s].u.pv.pe + width != second->area[s].u.pv.pe))
+ if ((seg_pv(first, s) !=
+ seg_pv(second, s)) ||
+ (seg_pe(first, s) + width !=
+ seg_pe(second, s)))
return 0;
}
@@ -131,12 +134,19 @@
static int _merge_segments(struct lv_segment *seg1, struct lv_segment *seg2)
{
+ uint32_t s;
+
if (!_segments_compatible(seg1, seg2))
return 0;
seg1->len += seg2->len;
seg1->area_len += seg2->area_len;
+ for (s = 0; s < seg1->area_count; s++)
+ if (seg1->area[s].type == AREA_PV)
+ merge_pv_segments(seg_pvseg(seg1, s),
+ seg_pvseg(seg2, s));
+
return 1;
}
Modified: lvm2/upstream/current/lib/uuid/uuid.h
==============================================================================
--- lvm2/upstream/current/lib/uuid/uuid.h (original)
+++ lvm2/upstream/current/lib/uuid/uuid.h Tue Jun 14 11:13:22 2005
@@ -25,11 +25,11 @@
/*
* Unique logical volume identifier
- * With format1 this is VG uuid + LV uuid + '\0'
+ * With format1 this is VG uuid + LV uuid + '\0' + padding
*/
union lvid {
struct id id[2];
- char s[2 * sizeof(struct id) + 1];
+ char s[2 * sizeof(struct id) + 1 + 7];
};
int lvid_from_lvnum(union lvid *lvid, struct id *vgid, uint32_t lv_num);
Modified: lvm2/upstream/current/man/pvcreate.8
==============================================================================
--- lvm2/upstream/current/man/pvcreate.8 (original)
+++ lvm2/upstream/current/man/pvcreate.8 Tue Jun 14 11:13:22 2005
@@ -91,10 +91,10 @@
.BR \-\-metadatacopies " copies"
The number of metadata areas to set aside on each PV. Currently
this can be 0, 1 or 2.
-If set to 2 (the default), two copies of the volume group metadata
+If set to 2, two copies of the volume group metadata
are held on the PV, one at the front of the PV and one at the end.
-If set to 1, one copy is kept at the front of the PV (starting in the
-5th sector).
+If set to 1 (the default), one copy is kept at the front of the PV
+(starting in the 5th sector).
If set to 0, no copies are kept on this PV - you might wish to use this
with VGs containing large numbers of PVs. But if you do this and
then later use \fBvgsplit\fP you must ensure that each VG is still going
Modified: lvm2/upstream/current/po/lvm2.po
==============================================================================
--- lvm2/upstream/current/po/lvm2.po (original)
+++ lvm2/upstream/current/po/lvm2.po Tue Jun 14 11:13:22 2005
@@ -7,7 +7,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2005-02-01 16:32+0000\n"
+"POT-Creation-Date: 2005-06-13 15:43+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
"Language-Team: LANGUAGE <LL at li.org>\n"
@@ -53,9 +53,9 @@
#: activate/activate.c:418 activate/activate.c:426 activate/activate.c:431
#: activate/activate.c:443 activate/activate.c:455 activate/activate.c:469
#: activate/activate.c:474 activate/activate.c:486 activate/activate.c:491
-#: activate/activate.c:503 activate/activate.c:508 activate/activate.c:572
-#: activate/activate.c:618 activate/activate.c:663 activate/activate.c:732
-#: activate/activate.c:771 activate/dev_manager.c:179
+#: activate/activate.c:503 activate/activate.c:508 activate/activate.c:568
+#: activate/activate.c:614 activate/activate.c:659 activate/activate.c:728
+#: activate/activate.c:767 activate/dev_manager.c:179
#: activate/dev_manager.c:197 activate/dev_manager.c:225
#: activate/dev_manager.c:234 activate/dev_manager.c:239
#: activate/dev_manager.c:245 activate/dev_manager.c:286
@@ -67,238 +67,269 @@
#: activate/dev_manager.c:555 activate/dev_manager.c:615
#: activate/dev_manager.c:621 activate/dev_manager.c:628
#: activate/dev_manager.c:657 activate/dev_manager.c:714
-#: activate/dev_manager.c:723 activate/dev_manager.c:778
-#: activate/dev_manager.c:803 activate/dev_manager.c:846
-#: activate/dev_manager.c:866 activate/dev_manager.c:889
-#: activate/dev_manager.c:894 activate/dev_manager.c:925
-#: activate/dev_manager.c:933 activate/dev_manager.c:950
-#: activate/dev_manager.c:955 activate/dev_manager.c:970
-#: activate/dev_manager.c:975 activate/dev_manager.c:1008
-#: activate/dev_manager.c:1018 activate/dev_manager.c:1034
-#: activate/dev_manager.c:1044 activate/dev_manager.c:1066
-#: activate/dev_manager.c:1075 activate/dev_manager.c:1089
-#: activate/dev_manager.c:1097 activate/dev_manager.c:1110
-#: activate/dev_manager.c:1130 activate/dev_manager.c:1135
-#: activate/dev_manager.c:1141 activate/dev_manager.c:1163
-#: activate/dev_manager.c:1184 activate/dev_manager.c:1206
-#: activate/dev_manager.c:1218 activate/dev_manager.c:1230
-#: activate/dev_manager.c:1244 activate/dev_manager.c:1257
-#: activate/dev_manager.c:1267 activate/dev_manager.c:1307
-#: activate/dev_manager.c:1318 activate/dev_manager.c:1328
-#: activate/dev_manager.c:1335 activate/dev_manager.c:1341
-#: activate/dev_manager.c:1409 activate/dev_manager.c:1428
-#: activate/dev_manager.c:1450 activate/dev_manager.c:1458
-#: activate/dev_manager.c:1486 activate/dev_manager.c:1491
-#: activate/dev_manager.c:1520 activate/dev_manager.c:1526
-#: activate/dev_manager.c:1547 activate/dev_manager.c:1565
-#: activate/dev_manager.c:1579 activate/dev_manager.c:1589
-#: activate/dev_manager.c:1599 activate/dev_manager.c:1617
-#: activate/dev_manager.c:1640 activate/dev_manager.c:1674
-#: activate/dev_manager.c:1690 activate/dev_manager.c:1748
-#: activate/dev_manager.c:1757 activate/dev_manager.c:1766
-#: activate/dev_manager.c:1775 activate/dev_manager.c:1780
-#: activate/dev_manager.c:1785 activate/dev_manager.c:1797
-#: activate/dev_manager.c:1807 activate/dev_manager.c:1813
-#: activate/dev_manager.c:1849 activate/dev_manager.c:1854
-#: activate/dev_manager.c:1886 activate/dev_manager.c:1904
-#: activate/dev_manager.c:2079 activate/dev_manager.c:2091
-#: activate/dev_manager.c:2097 activate/dev_manager.c:2111
-#: activate/dev_manager.c:2116 activate/dev_manager.c:2123
-#: activate/dev_manager.c:2131 activate/dev_manager.c:2139
-#: activate/dev_manager.c:2145 activate/dev_manager.c:2152
-#: activate/dev_manager.c:2157 activate/dev_manager.c:2185 activate/fs.c:234
-#: activate/fs.c:241 activate/fs.c:248 activate/fs.c:251 activate/fs.c:325
-#: archiver.c:71 archiver.c:78 archiver.c:90 archiver.c:166 archiver.c:236
-#: archiver.c:286 archiver.c:303 archiver.c:345 archiver.c:350
-#: cache/lvmcache.c:454 cache/lvmcache.c:495 cache/lvmcache.c:526
-#: commands/toolcontext.c:274 commands/toolcontext.c:293
-#: commands/toolcontext.c:300 commands/toolcontext.c:377
-#: commands/toolcontext.c:392 commands/toolcontext.c:416
-#: commands/toolcontext.c:467 commands/toolcontext.c:643
-#: commands/toolcontext.c:740 config/config.c:105 config/config.c:110
-#: config/config.c:140 config/config.c:161 config/config.c:192
-#: config/config.c:239 config/config.c:244 config/config.c:406
-#: config/config.c:424 config/config.c:429 config/config.c:439
-#: config/config.c:453 config/config.c:469 config/config.c:525
-#: config/config.c:708 datastruct/btree.c:90 datastruct/hash.c:96
-#: datastruct/hash.c:109 datastruct/str_list.c:24 datastruct/str_list.c:38
-#: datastruct/str_list.c:47 datastruct/str_list.c:77 device/dev-cache.c:182
-#: device/dev-cache.c:189 device/dev-cache.c:195 device/dev-cache.c:229
-#: device/dev-cache.c:300 device/dev-cache.c:348 device/dev-cache.c:393
-#: device/dev-cache.c:398 device/dev-io.c:174 device/dev-io.c:204
-#: device/dev-io.c:322 device/dev-io.c:465 device/dev-io.c:486
-#: device/dev-io.c:504 device/dev-io.c:523 device/dev-io.c:551
-#: device/dev-md.c:41 device/dev-md.c:49 device/dev-md.c:64 device/device.c:61
-#: device/device.c:66 device/device.c:90 display/display.c:211
-#: display/display.c:242 display/display.c:300 display/display.c:347
-#: display/display.c:587 display/display.c:623 error/errseg.c:90
-#: filters/filter-composite.c:54 filters/filter-persistent.c:45
-#: filters/filter-persistent.c:103 filters/filter-persistent.c:108
-#: filters/filter-persistent.c:239 filters/filter-persistent.c:245
-#: filters/filter-persistent.c:257 filters/filter-regex.c:78
-#: filters/filter-regex.c:105 filters/filter-regex.c:126
-#: filters/filter-regex.c:151 filters/filter-regex.c:212
-#: filters/filter-regex.c:217 filters/filter-regex.c:224
-#: filters/filter-regex.c:229 filters/filter-sysfs.c:285 filters/filter.c:253
-#: format1/disk-rep.c:220 format1/disk-rep.c:232 format1/disk-rep.c:237
-#: format1/disk-rep.c:256 format1/disk-rep.c:259 format1/disk-rep.c:290
-#: format1/disk-rep.c:293 format1/disk-rep.c:312 format1/disk-rep.c:315
-#: format1/disk-rep.c:332 format1/disk-rep.c:342 format1/disk-rep.c:348
-#: format1/disk-rep.c:413 format1/disk-rep.c:420 format1/disk-rep.c:511
-#: format1/disk-rep.c:534 format1/disk-rep.c:546 format1/disk-rep.c:576
-#: format1/disk-rep.c:590 format1/disk-rep.c:623 format1/disk-rep.c:688
-#: format1/disk-rep.c:695 format1/disk-rep.c:713 format1/format1.c:177
-#: format1/format1.c:192 format1/format1.c:201 format1/format1.c:206
-#: format1/format1.c:223 format1/format1.c:237 format1/format1.c:258
-#: format1/format1.c:269 format1/format1.c:284 format1/format1.c:310
-#: format1/format1.c:315 format1/format1.c:320 format1/format1.c:325
-#: format1/format1.c:362 format1/format1.c:409 format1/format1.c:425
-#: format1/format1.c:430 format1/format1.c:437 format1/format1.c:449
-#: format1/format1.c:500 format1/format1.c:520 format1/format1.c:529
-#: format1/format1.c:573 format1/import-export.c:61
-#: format1/import-export.c:121 format1/import-export.c:141
-#: format1/import-export.c:158 format1/import-export.c:166
-#: format1/import-export.c:201 format1/import-export.c:206
-#: format1/import-export.c:211 format1/import-export.c:289
-#: format1/import-export.c:426 format1/import-export.c:431
-#: format1/import-export.c:452 format1/import-export.c:459
-#: format1/import-export.c:484 format1/import-export.c:506
-#: format1/import-export.c:511 format1/import-export.c:520
-#: format1/import-export.c:528 format1/import-export.c:539
-#: format1/import-export.c:544 format1/import-export.c:669
-#: format1/import-export.c:726 format1/import-extents.c:65
+#: activate/dev_manager.c:723 activate/dev_manager.c:745
+#: activate/dev_manager.c:769 activate/dev_manager.c:828
+#: activate/dev_manager.c:853 activate/dev_manager.c:894
+#: activate/dev_manager.c:914 activate/dev_manager.c:938
+#: activate/dev_manager.c:943 activate/dev_manager.c:974
+#: activate/dev_manager.c:982 activate/dev_manager.c:999
+#: activate/dev_manager.c:1004 activate/dev_manager.c:1019
+#: activate/dev_manager.c:1024 activate/dev_manager.c:1057
+#: activate/dev_manager.c:1067 activate/dev_manager.c:1083
+#: activate/dev_manager.c:1093 activate/dev_manager.c:1115
+#: activate/dev_manager.c:1124 activate/dev_manager.c:1138
+#: activate/dev_manager.c:1146 activate/dev_manager.c:1159
+#: activate/dev_manager.c:1179 activate/dev_manager.c:1184
+#: activate/dev_manager.c:1190 activate/dev_manager.c:1212
+#: activate/dev_manager.c:1232 activate/dev_manager.c:1250
+#: activate/dev_manager.c:1262 activate/dev_manager.c:1274
+#: activate/dev_manager.c:1286 activate/dev_manager.c:1300
+#: activate/dev_manager.c:1313 activate/dev_manager.c:1323
+#: activate/dev_manager.c:1363 activate/dev_manager.c:1374
+#: activate/dev_manager.c:1384 activate/dev_manager.c:1392
+#: activate/dev_manager.c:1399 activate/dev_manager.c:1467
+#: activate/dev_manager.c:1486 activate/dev_manager.c:1508
+#: activate/dev_manager.c:1516 activate/dev_manager.c:1544
+#: activate/dev_manager.c:1549 activate/dev_manager.c:1578
+#: activate/dev_manager.c:1584 activate/dev_manager.c:1605
+#: activate/dev_manager.c:1623 activate/dev_manager.c:1637
+#: activate/dev_manager.c:1647 activate/dev_manager.c:1657
+#: activate/dev_manager.c:1675 activate/dev_manager.c:1698
+#: activate/dev_manager.c:1732 activate/dev_manager.c:1748
+#: activate/dev_manager.c:1805 activate/dev_manager.c:1814
+#: activate/dev_manager.c:1823 activate/dev_manager.c:1832
+#: activate/dev_manager.c:1837 activate/dev_manager.c:1842
+#: activate/dev_manager.c:1854 activate/dev_manager.c:1864
+#: activate/dev_manager.c:1870 activate/dev_manager.c:1906
+#: activate/dev_manager.c:1911 activate/dev_manager.c:1943
+#: activate/dev_manager.c:1961 activate/dev_manager.c:2137
+#: activate/dev_manager.c:2149 activate/dev_manager.c:2155
+#: activate/dev_manager.c:2169 activate/dev_manager.c:2174
+#: activate/dev_manager.c:2181 activate/dev_manager.c:2189
+#: activate/dev_manager.c:2197 activate/dev_manager.c:2203
+#: activate/dev_manager.c:2210 activate/dev_manager.c:2215
+#: activate/dev_manager.c:2243 activate/fs.c:234 activate/fs.c:241
+#: activate/fs.c:248 activate/fs.c:251 activate/fs.c:325 archiver.c:68
+#: archiver.c:75 archiver.c:87 archiver.c:163 archiver.c:236 archiver.c:286
+#: archiver.c:303 archiver.c:345 archiver.c:350 cache/lvmcache.c:474
+#: cache/lvmcache.c:515 cache/lvmcache.c:546 commands/toolcontext.c:276
+#: commands/toolcontext.c:295 commands/toolcontext.c:302
+#: commands/toolcontext.c:379 commands/toolcontext.c:394
+#: commands/toolcontext.c:418 commands/toolcontext.c:469
+#: commands/toolcontext.c:662 commands/toolcontext.c:758 config/config.c:105
+#: config/config.c:110 config/config.c:140 config/config.c:161
+#: config/config.c:192 config/config.c:239 config/config.c:244
+#: config/config.c:406 config/config.c:424 config/config.c:429
+#: config/config.c:439 config/config.c:453 config/config.c:469
+#: config/config.c:525 config/config.c:708 datastruct/btree.c:90
+#: datastruct/hash.c:96 datastruct/hash.c:109 datastruct/str_list.c:24
+#: datastruct/str_list.c:38 datastruct/str_list.c:47 datastruct/str_list.c:77
+#: device/dev-cache.c:204 device/dev-cache.c:217 device/dev-cache.c:260
+#: device/dev-cache.c:264 device/dev-cache.c:335 device/dev-cache.c:366
+#: device/dev-cache.c:405 device/dev-cache.c:451 device/dev-cache.c:456
+#: device/dev-io.c:174 device/dev-io.c:204 device/dev-io.c:348
+#: device/dev-io.c:516 device/dev-io.c:537 device/dev-io.c:555
+#: device/dev-io.c:574 device/dev-io.c:602 device/dev-md.c:41
+#: device/dev-md.c:49 device/dev-md.c:64 device/device.c:61 device/device.c:66
+#: device/device.c:90 display/display.c:211 display/display.c:242
+#: display/display.c:300 display/display.c:346 display/display.c:575
+#: display/display.c:611 error/errseg.c:90 filters/filter-composite.c:54
+#: filters/filter-persistent.c:45 filters/filter-persistent.c:105
+#: filters/filter-persistent.c:110 filters/filter-persistent.c:239
+#: filters/filter-persistent.c:245 filters/filter-persistent.c:257
+#: filters/filter-regex.c:78 filters/filter-regex.c:105
+#: filters/filter-regex.c:126 filters/filter-regex.c:151
+#: filters/filter-regex.c:210 filters/filter-regex.c:215
+#: filters/filter-regex.c:222 filters/filter-regex.c:227
+#: filters/filter-sysfs.c:285 filters/filter.c:254 format1/disk-rep.c:220
+#: format1/disk-rep.c:232 format1/disk-rep.c:237 format1/disk-rep.c:256
+#: format1/disk-rep.c:259 format1/disk-rep.c:290 format1/disk-rep.c:293
+#: format1/disk-rep.c:312 format1/disk-rep.c:315 format1/disk-rep.c:332
+#: format1/disk-rep.c:342 format1/disk-rep.c:348 format1/disk-rep.c:413
+#: format1/disk-rep.c:420 format1/disk-rep.c:511 format1/disk-rep.c:532
+#: format1/disk-rep.c:544 format1/disk-rep.c:572 format1/disk-rep.c:586
+#: format1/disk-rep.c:619 format1/disk-rep.c:684 format1/disk-rep.c:691
+#: format1/disk-rep.c:707 format1/format1.c:174 format1/format1.c:189
+#: format1/format1.c:198 format1/format1.c:203 format1/format1.c:220
+#: format1/format1.c:234 format1/format1.c:252 format1/format1.c:263
+#: format1/format1.c:278 format1/format1.c:304 format1/format1.c:309
+#: format1/format1.c:314 format1/format1.c:319 format1/format1.c:356
+#: format1/format1.c:403 format1/format1.c:419 format1/format1.c:424
+#: format1/format1.c:431 format1/format1.c:443 format1/format1.c:494
+#: format1/format1.c:514 format1/format1.c:523 format1/format1.c:567
+#: format1/import-export.c:62 format1/import-export.c:96
+#: format1/import-export.c:128 format1/import-export.c:148
+#: format1/import-export.c:165 format1/import-export.c:173
+#: format1/import-export.c:208 format1/import-export.c:213
+#: format1/import-export.c:218 format1/import-export.c:296
+#: format1/import-export.c:428 format1/import-export.c:433
+#: format1/import-export.c:454 format1/import-export.c:461
+#: format1/import-export.c:483 format1/import-export.c:504
+#: format1/import-export.c:509 format1/import-export.c:518
+#: format1/import-export.c:528 format1/import-export.c:538
+#: format1/import-export.c:543 format1/import-export.c:646
+#: format1/import-export.c:694 format1/import-extents.c:65
#: format1/import-extents.c:72 format1/import-extents.c:77
-#: format1/import-extents.c:133 format1/import-extents.c:199
-#: format1/import-extents.c:216 format1/import-extents.c:281
-#: format1/import-extents.c:287 format1/import-extents.c:335
-#: format1/import-extents.c:351 format1/import-extents.c:366
-#: format1/layout.c:124 format1/lvm1-label.c:66 format1/vg_number.c:39
-#: format1/vg_number.c:44 format_pool/disk_rep.c:51 format_pool/disk_rep.c:107
-#: format_pool/disk_rep.c:263 format_pool/disk_rep.c:366
-#: format_pool/disk_rep.c:376 format_pool/disk_rep.c:381
+#: format1/import-extents.c:130 format1/import-extents.c:196
+#: format1/import-extents.c:210 format1/import-extents.c:231
+#: format1/import-extents.c:280 format1/import-extents.c:312
+#: format1/import-extents.c:338 format1/import-extents.c:354
+#: format1/import-extents.c:369 format1/layout.c:124 format1/lvm1-label.c:66
+#: format1/vg_number.c:38 format1/vg_number.c:43 format_pool/disk_rep.c:51
+#: format_pool/disk_rep.c:104 format_pool/disk_rep.c:258
+#: format_pool/disk_rep.c:360 format_pool/disk_rep.c:370
+#: format_pool/disk_rep.c:375 format_pool/format_pool.c:134
#: format_pool/format_pool.c:139 format_pool/format_pool.c:144
-#: format_pool/format_pool.c:149 format_pool/format_pool.c:159
-#: format_pool/format_pool.c:168 format_pool/format_pool.c:173
-#: format_pool/format_pool.c:193 format_pool/format_pool.c:202
-#: format_pool/format_pool.c:208 format_pool/format_pool.c:238
-#: format_pool/format_pool.c:243 format_pool/format_pool.c:253
-#: format_pool/format_pool.c:258 format_pool/import_export.c:97
-#: format_pool/import_export.c:223 format_pool/import_export.c:260
-#: format_pool/import_export.c:296 format_pool/import_export.c:301
-#: format_text/archive.c:122 format_text/archive.c:142
-#: format_text/archive.c:169 format_text/archive.c:264
-#: format_text/archive.c:374 format_text/export.c:257 format_text/export.c:258
-#: format_text/export.c:259 format_text/export.c:262 format_text/export.c:264
-#: format_text/export.c:267 format_text/export.c:277 format_text/export.c:281
-#: format_text/export.c:283 format_text/export.c:286 format_text/export.c:289
-#: format_text/export.c:293 format_text/export.c:296 format_text/export.c:300
-#: format_text/export.c:304 format_text/export.c:307 format_text/export.c:308
-#: format_text/export.c:313 format_text/export.c:338 format_text/export.c:345
-#: format_text/export.c:350 format_text/export.c:354 format_text/export.c:358
-#: format_text/export.c:360 format_text/export.c:366 format_text/export.c:369
-#: format_text/export.c:373 format_text/export.c:376 format_text/export.c:379
-#: format_text/export.c:382 format_text/export.c:387 format_text/export.c:391
-#: format_text/export.c:400 format_text/export.c:403 format_text/export.c:406
-#: format_text/export.c:411 format_text/export.c:415 format_text/export.c:418
-#: format_text/export.c:423 format_text/export.c:428 format_text/export.c:441
-#: format_text/export.c:448 format_text/export.c:452 format_text/export.c:457
-#: format_text/export.c:465 format_text/export.c:488 format_text/export.c:492
-#: format_text/export.c:496 format_text/export.c:500 format_text/export.c:504
-#: format_text/export.c:505 format_text/export.c:511 format_text/export.c:533
-#: format_text/export.c:538 format_text/export.c:553 format_text/export.c:575
-#: format_text/export.c:582 format_text/export.c:587 format_text/export.c:591
-#: format_text/export.c:594 format_text/export.c:597 format_text/export.c:601
-#: format_text/export.c:604 format_text/export.c:608 format_text/export.c:612
-#: format_text/export.c:614 format_text/export.c:616 format_text/export.c:617
-#: format_text/export.c:623 format_text/export.c:629 format_text/export.c:633
-#: format_text/export.c:638 format_text/export.c:656 format_text/export.c:661
-#: format_text/export.c:670 format_text/export.c:675 format_text/export.c:680
-#: format_text/export.c:703 format_text/export.c:709 format_text/export.c:712
-#: format_text/export.c:717 format_text/export.c:721 format_text/export.c:725
-#: format_text/export.c:729 format_text/export.c:732 format_text/export.c:755
-#: format_text/export.c:783 format_text/export.c:796 format_text/flags.c:88
-#: format_text/flags.c:132 format_text/format-text.c:128
-#: format_text/format-text.c:176 format_text/format-text.c:198
-#: format_text/format-text.c:219 format_text/format-text.c:232
-#: format_text/format-text.c:240 format_text/format-text.c:257
-#: format_text/format-text.c:262 format_text/format-text.c:267
-#: format_text/format-text.c:287 format_text/format-text.c:296
-#: format_text/format-text.c:338 format_text/format-text.c:343
-#: format_text/format-text.c:388 format_text/format-text.c:401
-#: format_text/format-text.c:418 format_text/format-text.c:447
-#: format_text/format-text.c:473 format_text/format-text.c:500
-#: format_text/format-text.c:514 format_text/format-text.c:519
-#: format_text/format-text.c:542 format_text/format-text.c:556
-#: format_text/format-text.c:793 format_text/format-text.c:798
-#: format_text/format-text.c:807 format_text/format-text.c:818
-#: format_text/format-text.c:831 format_text/format-text.c:1014
-#: format_text/format-text.c:1072 format_text/format-text.c:1077
-#: format_text/format-text.c:1088 format_text/format-text.c:1090
-#: format_text/format-text.c:1098 format_text/format-text.c:1168
-#: format_text/format-text.c:1174 format_text/format-text.c:1353
-#: format_text/format-text.c:1359 format_text/format-text.c:1378
-#: format_text/format-text.c:1412 format_text/format-text.c:1432
-#: format_text/format-text.c:1450 format_text/format-text.c:1455
-#: format_text/format-text.c:1469 format_text/format-text.c:1482
-#: format_text/format-text.c:1488 format_text/format-text.c:1519
-#: format_text/format-text.c:1524 format_text/format-text.c:1529
-#: format_text/format-text.c:1538 format_text/format-text.c:1641
+#: format_pool/format_pool.c:154 format_pool/format_pool.c:163
+#: format_pool/format_pool.c:168 format_pool/format_pool.c:188
+#: format_pool/format_pool.c:197 format_pool/format_pool.c:203
+#: format_pool/format_pool.c:233 format_pool/format_pool.c:238
+#: format_pool/format_pool.c:248 format_pool/format_pool.c:253
+#: format_pool/import_export.c:94 format_pool/import_export.c:180
+#: format_pool/import_export.c:218 format_pool/import_export.c:232
+#: format_pool/import_export.c:256 format_pool/import_export.c:276
+#: format_pool/import_export.c:304 format_pool/import_export.c:309
+#: format_text/archive.c:119 format_text/archive.c:140
+#: format_text/archive.c:167 format_text/archive.c:259
+#: format_text/archive.c:270 format_text/archive.c:346
+#: format_text/archive.c:366 format_text/archiver.c:82
+#: format_text/archiver.c:89 format_text/archiver.c:101
+#: format_text/archiver.c:189 format_text/archiver.c:267
+#: format_text/archiver.c:317 format_text/archiver.c:334
+#: format_text/archiver.c:376 format_text/archiver.c:381
+#: format_text/export.c:113 format_text/export.c:178 format_text/export.c:188
+#: format_text/export.c:279 format_text/export.c:280 format_text/export.c:281
+#: format_text/export.c:282 format_text/export.c:284 format_text/export.c:285
+#: format_text/export.c:286 format_text/export.c:289 format_text/export.c:299
+#: format_text/export.c:303 format_text/export.c:305 format_text/export.c:308
+#: format_text/export.c:311 format_text/export.c:315 format_text/export.c:318
+#: format_text/export.c:322 format_text/export.c:326 format_text/export.c:329
+#: format_text/export.c:330 format_text/export.c:334 format_text/export.c:335
+#: format_text/export.c:360 format_text/export.c:367 format_text/export.c:371
+#: format_text/export.c:372 format_text/export.c:376 format_text/export.c:380
+#: format_text/export.c:382 format_text/export.c:385 format_text/export.c:388
+#: format_text/export.c:391 format_text/export.c:395 format_text/export.c:398
+#: format_text/export.c:401 format_text/export.c:404 format_text/export.c:409
+#: format_text/export.c:413 format_text/export.c:422 format_text/export.c:425
+#: format_text/export.c:428 format_text/export.c:432 format_text/export.c:433
+#: format_text/export.c:437 format_text/export.c:440 format_text/export.c:445
+#: format_text/export.c:450 format_text/export.c:461 format_text/export.c:463
+#: format_text/export.c:470 format_text/export.c:474 format_text/export.c:479
+#: format_text/export.c:487 format_text/export.c:497 format_text/export.c:498
+#: format_text/export.c:503 format_text/export.c:507 format_text/export.c:510
+#: format_text/export.c:513 format_text/export.c:517 format_text/export.c:520
+#: format_text/export.c:524 format_text/export.c:528 format_text/export.c:530
+#: format_text/export.c:532 format_text/export.c:533 format_text/export.c:534
+#: format_text/export.c:539 format_text/export.c:545 format_text/export.c:560
+#: format_text/export.c:570 format_text/export.c:579 format_text/export.c:585
+#: format_text/export.c:603 format_text/export.c:608 format_text/export.c:617
+#: format_text/export.c:622 format_text/export.c:627 format_text/export.c:650
+#: format_text/export.c:656 format_text/export.c:659 format_text/export.c:664
+#: format_text/export.c:666 format_text/export.c:668 format_text/export.c:670
+#: format_text/export.c:672 format_text/export.c:676 format_text/export.c:679
+#: format_text/export.c:702 format_text/export.c:729 format_text/export.c:747
+#: format_text/flags.c:91 format_text/flags.c:135
+#: format_text/format-text.c:128 format_text/format-text.c:176
+#: format_text/format-text.c:203 format_text/format-text.c:244
+#: format_text/format-text.c:249 format_text/format-text.c:257
+#: format_text/format-text.c:275 format_text/format-text.c:280
+#: format_text/format-text.c:305 format_text/format-text.c:315
+#: format_text/format-text.c:362 format_text/format-text.c:367
+#: format_text/format-text.c:402 format_text/format-text.c:415
+#: format_text/format-text.c:432 format_text/format-text.c:463
+#: format_text/format-text.c:494 format_text/format-text.c:532
+#: format_text/format-text.c:546 format_text/format-text.c:551
+#: format_text/format-text.c:574 format_text/format-text.c:588
+#: format_text/format-text.c:833 format_text/format-text.c:838
+#: format_text/format-text.c:847 format_text/format-text.c:858
+#: format_text/format-text.c:871 format_text/format-text.c:1063
+#: format_text/format-text.c:1119 format_text/format-text.c:1124
+#: format_text/format-text.c:1134 format_text/format-text.c:1136
+#: format_text/format-text.c:1144 format_text/format-text.c:1184
+#: format_text/format-text.c:1190 format_text/format-text.c:1366
+#: format_text/format-text.c:1372 format_text/format-text.c:1391
+#: format_text/format-text.c:1426 format_text/format-text.c:1445
+#: format_text/format-text.c:1461 format_text/format-text.c:1466
+#: format_text/format-text.c:1480 format_text/format-text.c:1492
+#: format_text/format-text.c:1498 format_text/format-text.c:1529
+#: format_text/format-text.c:1534 format_text/format-text.c:1539
+#: format_text/format-text.c:1548 format_text/format-text.c:1651
#: format_text/import.c:53 format_text/import.c:72
-#: format_text/import_vsn1.c:123 format_text/import_vsn1.c:134
-#: format_text/import_vsn1.c:167 format_text/import_vsn1.c:276
-#: format_text/import_vsn1.c:282 format_text/import_vsn1.c:301
-#: format_text/import_vsn1.c:413 format_text/import_vsn1.c:441
-#: format_text/import_vsn1.c:449 format_text/import_vsn1.c:466
-#: format_text/import_vsn1.c:473 format_text/import_vsn1.c:502
-#: format_text/import_vsn1.c:558 format_text/import_vsn1.c:606
-#: format_text/import_vsn1.c:631 format_text/import_vsn1.c:641
-#: format_text/import_vsn1.c:646 format_text/import_vsn1.c:716
+#: format_text/import_vsn1.c:124 format_text/import_vsn1.c:135
+#: format_text/import_vsn1.c:168 format_text/import_vsn1.c:214
+#: format_text/import_vsn1.c:280 format_text/import_vsn1.c:286
+#: format_text/import_vsn1.c:299 format_text/import_vsn1.c:364
+#: format_text/import_vsn1.c:410 format_text/import_vsn1.c:438
+#: format_text/import_vsn1.c:446 format_text/import_vsn1.c:463
+#: format_text/import_vsn1.c:470 format_text/import_vsn1.c:499
+#: format_text/import_vsn1.c:557 format_text/import_vsn1.c:610
+#: format_text/import_vsn1.c:635 format_text/import_vsn1.c:645
+#: format_text/import_vsn1.c:650 format_text/import_vsn1.c:720
#: format_text/tags.c:29 format_text/tags.c:36 format_text/tags.c:43
#: format_text/tags.c:49 format_text/tags.c:68 label/label.c:91
-#: label/label.c:125 label/label.c:190 label/label.c:212 label/label.c:264
-#: label/label.c:278 label/label.c:313 label/label.c:321 label/label.c:333
-#: label/label.c:345 locking/cluster_locking.c:85
+#: label/label.c:122 label/label.c:193 label/label.c:214 label/label.c:265
+#: label/label.c:279 label/label.c:314 label/label.c:322 label/label.c:334
+#: label/label.c:346 locking/cluster_locking.c:85
#: locking/cluster_locking.c:424 locking/cluster_locking.c:436
#: locking/cluster_locking.c:440 locking/external_locking.c:76 lvchange.c:49
-#: lvchange.c:87 lvchange.c:93 lvchange.c:101 lvchange.c:108 lvchange.c:115
-#: lvchange.c:165 lvchange.c:173 lvchange.c:207 lvchange.c:292 lvchange.c:350
-#: lvchange.c:358 lvcreate.c:265 lvcreate.c:436 lvcreate.c:517 lvcreate.c:523
-#: lvcreate.c:564 lvcreate.c:571 lvcreate.c:656 lvmcmdline.c:1004
-#: lvremove.c:74 lvrename.c:146 lvrename.c:157 lvrename.c:164 lvrename.c:169
-#: lvresize.c:360 lvresize.c:417 lvresize.c:424 lvresize.c:431 lvresize.c:443
-#: lvresize.c:450 lvresize.c:456 lvresize.c:475 lvresize.c:489 lvresize.c:514
-#: metadata/lv_manip.c:70 metadata/lv_manip.c:202 metadata/lv_manip.c:237
-#: metadata/lv_manip.c:324 metadata/lv_manip.c:369 metadata/lv_manip.c:462
-#: metadata/lv_manip.c:599 metadata/lv_manip.c:641 metadata/lv_manip.c:652
-#: metadata/lv_manip.c:700 metadata/lv_manip.c:714 metadata/merge.c:179
-#: metadata/metadata.c:174 metadata/metadata.c:198 metadata/metadata.c:266
-#: metadata/metadata.c:281 metadata/metadata.c:471 metadata/metadata.c:512
-#: metadata/metadata.c:518 metadata/metadata.c:524 metadata/metadata.c:548
-#: metadata/metadata.c:573 metadata/metadata.c:591 metadata/metadata.c:654
-#: metadata/metadata.c:659 metadata/metadata.c:692 metadata/metadata.c:834
-#: metadata/metadata.c:913 metadata/metadata.c:946 metadata/mirror.c:48
-#: metadata/mirror.c:88 metadata/mirror.c:97 metadata/mirror.c:247
-#: metadata/mirror.c:327 metadata/pv_map.c:33 metadata/pv_map.c:40
-#: metadata/pv_map.c:95 metadata/pv_map.c:115 metadata/pv_map.c:172
-#: metadata/pv_map.c:199 metadata/pv_map.c:217 metadata/pv_map.c:226
-#: metadata/pv_map.c:244 metadata/pv_map.c:258 metadata/snapshot_manip.c:124
-#: metadata/snapshot_manip.c:143 mirror/mirrored.c:96 mirror/mirrored.c:171
-#: mirror/mirrored.c:251 misc/lvm-string.c:152 pvmove.c:98 pvmove.c:103
-#: pvmove.c:179 pvmove.c:207 pvmove.c:214 pvmove.c:278 pvmove.c:285
-#: pvmove.c:294 pvmove.c:323 pvmove.c:336 pvmove.c:343 pvmove.c:350
-#: pvmove.c:358 pvmove.c:370 pvmove.c:511 pvscan.c:54 regex/matcher.c:182
+#: lvchange.c:87 lvchange.c:93 lvchange.c:107 lvchange.c:114 lvchange.c:121
+#: lvchange.c:171 lvchange.c:179 lvchange.c:213 lvchange.c:298 lvchange.c:356
+#: lvchange.c:364 lvconvert.c:43 lvconvert.c:73 lvconvert.c:90 lvconvert.c:219
+#: lvcreate.c:141 lvcreate.c:309 lvcreate.c:333 lvcreate.c:349 lvcreate.c:511
+#: lvcreate.c:599 lvcreate.c:653 lvcreate.c:660 lvcreate.c:665 lvcreate.c:671
+#: lvcreate.c:678 lvcreate.c:705 lvcreate.c:745 lvcreate.c:753 lvcreate.c:759
+#: lvcreate.c:766 lvcreate.c:856 lvmcmdline.c:946 lvremove.c:86 lvrename.c:87
+#: lvrename.c:144 lvrename.c:155 lvrename.c:162 lvrename.c:167 lvresize.c:417
+#: lvresize.c:474 lvresize.c:481 lvresize.c:488 lvresize.c:500 lvresize.c:507
+#: lvresize.c:513 lvresize.c:532 lvresize.c:546 lvresize.c:571
+#: metadata/lv_manip.c:73 metadata/lv_manip.c:139 metadata/lv_manip.c:210
+#: metadata/lv_manip.c:219 metadata/lv_manip.c:231 metadata/lv_manip.c:240
+#: metadata/lv_manip.c:254 metadata/lv_manip.c:390 metadata/lv_manip.c:398
+#: metadata/lv_manip.c:435 metadata/lv_manip.c:644 metadata/lv_manip.c:692
+#: metadata/lv_manip.c:717 metadata/lv_manip.c:729 metadata/lv_manip.c:740
+#: metadata/lv_manip.c:821 metadata/lv_manip.c:829 metadata/lv_manip.c:866
+#: metadata/lv_manip.c:878 metadata/lv_manip.c:907 metadata/lv_manip.c:919
+#: metadata/lv_manip.c:965 metadata/lv_manip.c:995 metadata/lv_manip.c:1002
+#: metadata/lv_manip.c:1115 metadata/merge.c:199 metadata/merge.c:239
+#: metadata/metadata.c:105 metadata/metadata.c:131 metadata/metadata.c:158
+#: metadata/metadata.c:228 metadata/metadata.c:252 metadata/metadata.c:346
+#: metadata/metadata.c:352 metadata/metadata.c:358 metadata/metadata.c:369
+#: metadata/metadata.c:375 metadata/metadata.c:387 metadata/metadata.c:393
+#: metadata/metadata.c:405 metadata/metadata.c:413 metadata/metadata.c:420
+#: metadata/metadata.c:427 metadata/metadata.c:434 metadata/metadata.c:447
+#: metadata/metadata.c:455 metadata/metadata.c:464 metadata/metadata.c:495
+#: metadata/metadata.c:510 metadata/metadata.c:692 metadata/metadata.c:748
+#: metadata/metadata.c:754 metadata/metadata.c:761 metadata/metadata.c:772
+#: metadata/metadata.c:777 metadata/metadata.c:799 metadata/metadata.c:821
+#: metadata/metadata.c:838 metadata/metadata.c:904 metadata/metadata.c:909
+#: metadata/metadata.c:954 metadata/metadata.c:994 metadata/metadata.c:1157
+#: metadata/metadata.c:1191 metadata/metadata.c:1243 metadata/metadata.c:1276
+#: metadata/mirror.c:34 metadata/mirror.c:53 metadata/mirror.c:58
+#: metadata/mirror.c:72 metadata/mirror.c:184 metadata/mirror.c:223
+#: metadata/mirror.c:232 metadata/mirror.c:361 metadata/mirror.c:380
+#: metadata/mirror.c:455 metadata/pv_manip.c:55 metadata/pv_manip.c:74
+#: metadata/pv_manip.c:95 metadata/pv_manip.c:127 metadata/pv_manip.c:152
+#: metadata/pv_manip.c:182 metadata/pv_map.c:42 metadata/pv_map.c:90
+#: metadata/pv_map.c:110 metadata/pv_map.c:120 metadata/pv_map.c:138
+#: metadata/pv_map.c:148 metadata/snapshot_manip.c:56
+#: metadata/snapshot_manip.c:63 mirror/mirrored.c:137 mirror/mirrored.c:142
+#: mirror/mirrored.c:144 mirror/mirrored.c:225 mirror/mirrored.c:305
+#: misc/lvm-string.c:152 pvchange.c:185 pvmove.c:98 pvmove.c:103 pvmove.c:180
+#: pvmove.c:208 pvmove.c:215 pvmove.c:279 pvmove.c:286 pvmove.c:295
+#: pvmove.c:324 pvmove.c:337 pvmove.c:344 pvmove.c:351 pvmove.c:359
+#: pvmove.c:371 pvmove.c:512 pvscan.c:54 regex/matcher.c:182
#: regex/matcher.c:203 regex/matcher.c:208 regex/matcher.c:282
#: regex/matcher.c:287 regex/matcher.c:300 regex/matcher.c:322
#: regex/parse_rx.c:229 regex/parse_rx.c:280 regex/parse_rx.c:305
#: regex/parse_rx.c:328 regex/parse_rx.c:340 regex/ttree.c:91
-#: regex/ttree.c:111 report/report.c:522 report/report.c:550
-#: report/report.c:682 snapshot/snapshot.c:75 snapshot/snapshot.c:84
+#: regex/ttree.c:111 report/report.c:576 report/report.c:604
+#: report/report.c:736 snapshot/snapshot.c:75 snapshot/snapshot.c:84
#: snapshot/snapshot.c:85 snapshot/snapshot.c:86 snapshot/snapshot.c:155
-#: striped/striped.c:90 striped/striped.c:160 striped/striped.c:209
-#: toollib.c:734 toollib.c:784 toollib.c:831 uuid/uuid.c:91 uuid/uuid.c:95
-#: vgcfgbackup.c:65 vgcfgbackup.c:74 vgcfgbackup.c:81 vgreduce.c:28
-#: vgreduce.c:84 vgreduce.c:92 vgreduce.c:98 vgreduce.c:106 vgreduce.c:142
-#: vgreduce.c:158 zero/zero.c:90
+#: striped/striped.c:91 striped/striped.c:170 striped/striped.c:219
+#: toollib.c:760 toollib.c:810 toollib.c:857 uuid/uuid.c:91 uuid/uuid.c:95
+#: vgcfgbackup.c:65 vgcfgbackup.c:74 vgcfgbackup.c:81 vgchange.c:302
+#: vgmerge.c:160 vgreduce.c:28 vgreduce.c:90 vgreduce.c:96 vgreduce.c:104
+#: vgreduce.c:140 vgreduce.c:156 zero/zero.c:90
msgid "<backtrace>"
msgstr ""
@@ -316,32 +347,32 @@
msgid "Failed to get %s target version"
msgstr ""
-#: activate/activate.c:567
+#: activate/activate.c:563
#, c-format
msgid "Skipping: Suspending '%s'."
msgstr ""
-#: activate/activate.c:613
+#: activate/activate.c:609
#, c-format
msgid "Skipping: Resuming '%s'."
msgstr ""
-#: activate/activate.c:658
+#: activate/activate.c:654
#, c-format
msgid "Skipping: Deactivating '%s'."
msgstr ""
-#: activate/activate.c:671
+#: activate/activate.c:667
#, c-format
msgid "LV %s/%s in use: not removing"
msgstr ""
-#: activate/activate.c:697 activate/activate.c:721
+#: activate/activate.c:693 activate/activate.c:717
#, c-format
msgid "Not activating %s/%s due to config file settings"
msgstr ""
-#: activate/activate.c:727
+#: activate/activate.c:723
#, c-format
msgid "Skipping: Activating '%s'."
msgstr ""
@@ -368,8 +399,8 @@
msgid "Couldn't split up dm layer name %s"
msgstr ""
-#: activate/dev_manager.c:464 format_text/format-text.c:640
-#: format_text/format-text.c:665 format_text/format-text.c:699
+#: activate/dev_manager.c:464 format_text/format-text.c:681
+#: format_text/format-text.c:706 format_text/format-text.c:740
#, c-format
msgid "Renaming %s to %s"
msgstr ""
@@ -460,152 +491,152 @@
msgid "Adding target: %llu %llu %s %s"
msgstr ""
-#: activate/dev_manager.c:759
+#: activate/dev_manager.c:750 activate/dev_manager.c:809
#, c-format
msgid "device layer %s missing from hash"
msgstr ""
-#: activate/dev_manager.c:766
+#: activate/dev_manager.c:757 activate/dev_manager.c:816
#, c-format
msgid "Failed to format device number as dm target (%u,%u)"
msgstr ""
-#: activate/dev_manager.c:795
+#: activate/dev_manager.c:845
msgid "Insufficient space for target parameters."
msgstr ""
-#: activate/dev_manager.c:808
+#: activate/dev_manager.c:858
#, c-format
-msgid "Insufficient space in params[%Zu] for target parameters."
+msgid "Insufficient space in params[%zu] for target parameters."
msgstr ""
-#: activate/dev_manager.c:814
+#: activate/dev_manager.c:864
msgid "Target parameter size too big. Aborting."
msgstr ""
-#: activate/dev_manager.c:830
+#: activate/dev_manager.c:878
#, c-format
msgid "Unable to build table for '%s'"
msgstr ""
-#: activate/dev_manager.c:851
+#: activate/dev_manager.c:899
#, c-format
msgid "Couldn't find real device layer %s in hash"
msgstr ""
-#: activate/dev_manager.c:857 activate/dev_manager.c:911
+#: activate/dev_manager.c:905 activate/dev_manager.c:960
#, c-format
msgid "Couldn't create origin device parameters for '%s'."
msgstr ""
-#: activate/dev_manager.c:862
+#: activate/dev_manager.c:910
#, c-format
msgid "Adding target: 0 %llu snapshot-origin %s"
msgstr ""
-#: activate/dev_manager.c:884
+#: activate/dev_manager.c:932
#, c-format
msgid "Couldn't find snapshot for '%s'."
msgstr ""
-#: activate/dev_manager.c:899
+#: activate/dev_manager.c:948
#, c-format
msgid "Couldn't find origin device layer %s in hash"
msgstr ""
-#: activate/dev_manager.c:905
+#: activate/dev_manager.c:954
#, c-format
msgid "Couldn't find cow device layer %s in hash"
msgstr ""
-#: activate/dev_manager.c:918
+#: activate/dev_manager.c:967
#, c-format
msgid "Couldn't create cow device parameters for '%s'."
msgstr ""
-#: activate/dev_manager.c:931
+#: activate/dev_manager.c:980
#, c-format
msgid "Adding target: 0 %llu snapshot %s"
msgstr ""
-#: activate/dev_manager.c:1015 activate/dev_manager.c:1095
+#: activate/dev_manager.c:1064 activate/dev_manager.c:1144
#, c-format
msgid "Getting device info for %s"
msgstr ""
-#: activate/dev_manager.c:1041
+#: activate/dev_manager.c:1090
#, c-format
msgid "Getting device status percentage for %s"
msgstr ""
-#: activate/dev_manager.c:1072
+#: activate/dev_manager.c:1121
#, c-format
msgid "Getting device mirror status percentage for %s"
msgstr ""
-#: activate/dev_manager.c:1395 activate/dev_manager.c:1555
+#: activate/dev_manager.c:1453 activate/dev_manager.c:1613
#, c-format
msgid "Couldn't find device layer '%s'."
msgstr ""
-#: activate/dev_manager.c:1475
+#: activate/dev_manager.c:1533
#, c-format
msgid "_suspend_parents couldn't find device layer '%s' - skipping."
msgstr ""
-#: activate/dev_manager.c:1481
+#: activate/dev_manager.c:1539
#, c-format
msgid "BUG: pre-suspend loop detected (%s)"
msgstr ""
-#: activate/dev_manager.c:1509
+#: activate/dev_manager.c:1567
#, c-format
msgid "_resume_with_deps couldn't find device layer '%s' - skipping."
msgstr ""
-#: activate/dev_manager.c:1515 activate/dev_manager.c:1560
+#: activate/dev_manager.c:1573 activate/dev_manager.c:1618
#, c-format
msgid "BUG: pre-create loop detected (%s)"
msgstr ""
-#: activate/dev_manager.c:1667 activate/dev_manager.c:1683
+#: activate/dev_manager.c:1725 activate/dev_manager.c:1741
#, c-format
msgid ""
"_populate_pre_suspend_lists: Couldn't find device layer '%s' - skipping."
msgstr ""
-#: activate/dev_manager.c:1729
+#: activate/dev_manager.c:1787
#, c-format
msgid "Couldn't deactivate device %s"
msgstr ""
-#: activate/dev_manager.c:1846
+#: activate/dev_manager.c:1903
#, c-format
msgid "Found existing layer '%s'"
msgstr ""
-#: activate/dev_manager.c:2025
+#: activate/dev_manager.c:2083
#, c-format
msgid "Can't expand LV: %s target support missing from kernel?"
msgstr ""
-#: activate/dev_manager.c:2037
+#: activate/dev_manager.c:2095
msgid "Can't expand LV: Mirror support missing from tools?"
msgstr ""
-#: activate/dev_manager.c:2044
+#: activate/dev_manager.c:2102
msgid "Can't expand LV: Mirror support missing from kernel?"
msgstr ""
-#: activate/dev_manager.c:2052
+#: activate/dev_manager.c:2110
msgid "Can't expand LV: Snapshot support missing from tools?"
msgstr ""
-#: activate/dev_manager.c:2059
+#: activate/dev_manager.c:2117
msgid "Can't expand LV: Snapshot support missing from kernel?"
msgstr ""
-#: activate/dev_manager.c:2087
+#: activate/dev_manager.c:2145
#, c-format
msgid "Found active lv %s%s"
msgstr ""
@@ -621,30 +652,31 @@
#: activate/fs.c:50 activate/fs.c:85 activate/fs.c:105 activate/fs.c:158
#: activate/fs.c:171 activate/fs.c:178 activate/fs.c:213
-#: commands/toolcontext.c:340 commands/toolcontext.c:781 config/config.c:155
+#: commands/toolcontext.c:342 commands/toolcontext.c:799 config/config.c:155
#: config/config.c:204 config/config.c:220 config/config.c:285
-#: config/config.c:382 device/dev-cache.c:150 device/dev-cache.c:154
-#: device/dev-cache.c:322 device/dev-cache.c:329 device/dev-cache.c:490
-#: device/dev-cache.c:492 device/dev-io.c:131 device/dev-io.c:235
-#: device/dev-io.c:240 device/dev-io.c:242 device/dev-io.c:248
-#: device/dev-io.c:344 device/dev-io.c:400 filters/filter-persistent.c:184
+#: config/config.c:382 device/dev-cache.c:172 device/dev-cache.c:176
+#: device/dev-cache.c:356 device/dev-cache.c:379 device/dev-cache.c:386
+#: device/dev-cache.c:579 device/dev-cache.c:581 device/dev-io.c:131
+#: device/dev-io.c:231 device/dev-io.c:249 device/dev-io.c:254
+#: device/dev-io.c:256 device/dev-io.c:262 device/dev-io.c:386
+#: device/dev-io.c:388 device/dev-io.c:451 filters/filter-persistent.c:186
#: filters/filter-sysfs.c:43 filters/filter-sysfs.c:155
-#: filters/filter-sysfs.c:179 filters/filter-sysfs.c:222 filters/filter.c:152
-#: format_text/archive.c:221 format_text/archive.c:230
-#: format_text/format-text.c:615 format_text/format-text.c:629
-#: format_text/format-text.c:635 format_text/format-text.c:660
-#: format_text/format-text.c:722 format_text/format-text.c:727
-#: format_text/format-text.c:753 format_text/format-text.c:778
+#: filters/filter-sysfs.c:179 filters/filter-sysfs.c:222 filters/filter.c:153
+#: format_text/archive.c:216 format_text/archive.c:225
+#: format_text/format-text.c:656 format_text/format-text.c:670
+#: format_text/format-text.c:676 format_text/format-text.c:701
+#: format_text/format-text.c:763 format_text/format-text.c:768
+#: format_text/format-text.c:793 format_text/format-text.c:818
#: locking/file_locking.c:61 locking/file_locking.c:69
-#: locking/file_locking.c:72 locking/file_locking.c:103
-#: locking/file_locking.c:169 locking/file_locking.c:183
-#: locking/file_locking.c:290 locking/file_locking.c:295 locking/locking.c:44
-#: locking/locking.c:49 locking/locking.c:65 locking/locking.c:200
-#: log/log.c:62 lvmcmdline.c:1411 misc/lvm-file.c:47 misc/lvm-file.c:92
-#: misc/lvm-file.c:102 misc/lvm-file.c:151 misc/lvm-file.c:163
-#: misc/lvm-file.c:192 misc/lvm-file.c:201 misc/lvm-file.c:229
-#: misc/lvm-file.c:234 mm/memlock.c:98 mm/memlock.c:106 mm/memlock.c:117
-#: toollib.c:966 uuid/uuid.c:84 uuid/uuid.c:89
+#: locking/file_locking.c:72 locking/file_locking.c:105
+#: locking/file_locking.c:171 locking/file_locking.c:187
+#: locking/file_locking.c:294 locking/file_locking.c:299 locking/locking.c:44
+#: locking/locking.c:49 locking/locking.c:65 locking/locking.c:203
+#: log/log.c:64 lvmcmdline.c:1347 misc/lvm-file.c:47 misc/lvm-file.c:96
+#: misc/lvm-file.c:106 misc/lvm-file.c:156 misc/lvm-file.c:169
+#: misc/lvm-file.c:198 misc/lvm-file.c:207 misc/lvm-file.c:235
+#: misc/lvm-file.c:240 mm/memlock.c:98 mm/memlock.c:106 mm/memlock.c:117
+#: toollib.c:992 uuid/uuid.c:84 uuid/uuid.c:89
#, c-format
msgid "%s: %s failed: %s"
msgstr ""
@@ -712,11 +744,11 @@
msgid "No space to stack fs operation"
msgstr ""
-#: archiver.c:43
+#: archiver.c:40 format_text/archiver.c:53
msgid "Couldn't copy archive directory name."
msgstr ""
-#: archiver.c:105
+#: archiver.c:102 format_text/archiver.c:116
msgid "Test mode: Skipping archiving of volume group."
msgstr ""
@@ -725,45 +757,45 @@
msgid "Archiving volume group \"%s\" metadata."
msgstr ""
-#: archiver.c:111
+#: archiver.c:111 format_text/archiver.c:131
#, c-format
msgid "Volume group \"%s\" metadata archive failed."
msgstr ""
-#: archiver.c:141
+#: archiver.c:138 format_text/archiver.c:164
msgid "Couldn't copy backup directory name."
msgstr ""
-#: archiver.c:172
+#: archiver.c:169 format_text/archiver.c:195
msgid "Failed to generate volume group metadata backup filename."
msgstr ""
-#: archiver.c:183
+#: archiver.c:180 format_text/archiver.c:206
msgid "WARNING: This metadata update is NOT backed up"
msgstr ""
-#: archiver.c:188
+#: archiver.c:185 format_text/archiver.c:211
msgid "Test mode: Skipping volume group backup."
msgstr ""
-#: archiver.c:193
+#: archiver.c:193 format_text/archiver.c:224
#, c-format
msgid "Backup of volume group %s metadata failed."
msgstr ""
-#: archiver.c:207
+#: archiver.c:207 format_text/archiver.c:238
msgid "Failed to generate backup filename (for removal)."
msgstr ""
-#: archiver.c:230
+#: archiver.c:230 format_text/archiver.c:261
msgid "Couldn't create text format object."
msgstr ""
-#: archiver.c:259
+#: archiver.c:259 format_text/archiver.c:290
msgid "Failed to allocate format instance"
msgstr ""
-#: archiver.c:267
+#: archiver.c:267 format_text/archiver.c:298
#, c-format
msgid "PV %s missing from cache"
msgstr ""
@@ -773,12 +805,12 @@
msgid "PV %s is a different format (%s)"
msgstr ""
-#: archiver.c:279
+#: archiver.c:279 format_text/archiver.c:310
#, c-format
msgid "Format-specific setup for %s failed"
msgstr ""
-#: archiver.c:316
+#: archiver.c:316 format_text/archiver.c:347
msgid "Failed to generate backup filename (for restore)."
msgstr ""
@@ -787,11 +819,11 @@
msgid "Creating volume group backup \"%s\""
msgstr ""
-#: archiver.c:338
+#: archiver.c:338 format_text/archiver.c:369
msgid "Couldn't create backup object."
msgstr ""
-#: cache/lvmcache.c:57 cache/lvmcache.c:182 cache/lvmcache.c:444
+#: cache/lvmcache.c:57 cache/lvmcache.c:202 cache/lvmcache.c:464
msgid "Internal cache initialisation failed"
msgstr ""
@@ -800,247 +832,283 @@
msgid "Cache locking failure for %s"
msgstr ""
-#: cache/lvmcache.c:192 toollib.c:467
+#: cache/lvmcache.c:212 toollib.c:492
msgid "dev_iter creation failed"
msgstr ""
-#: cache/lvmcache.c:226
+#: cache/lvmcache.c:245
msgid "vgnames list allocation failed"
msgstr ""
-#: cache/lvmcache.c:233 toollib.c:147 toollib.c:192 toollib.c:200
-#: toollib.c:212 toollib.c:272 toollib.c:381 toollib.c:401 toollib.c:526
+#: cache/lvmcache.c:252 toollib.c:150 toollib.c:195 toollib.c:203
+#: toollib.c:215 toollib.c:275 toollib.c:406 toollib.c:426 toollib.c:552
msgid "strlist allocation failed"
msgstr ""
-#: cache/lvmcache.c:327
+#: cache/lvmcache.c:346
#, c-format
msgid "_lvmcache_update: pvid insertion failed: %s"
msgstr ""
-#: cache/lvmcache.c:348
+#: cache/lvmcache.c:367
#, c-format
msgid "_lvmcache_update: vgid hash insertion failed: %s"
msgstr ""
-#: cache/lvmcache.c:376
+#: cache/lvmcache.c:395
msgid "lvmcache_update_vgname: list alloc failed"
msgstr ""
-#: cache/lvmcache.c:382
+#: cache/lvmcache.c:401
#, c-format
msgid "cache vgname alloc failed for %s"
msgstr ""
-#: cache/lvmcache.c:387
+#: cache/lvmcache.c:406
#, c-format
msgid "cache_update: vg hash insertion failed: %s"
msgstr ""
-#: cache/lvmcache.c:458
+#: cache/lvmcache.c:425
+#, c-format
+msgid "lvmcache: %s now %s%s"
+msgstr ""
+
+#: cache/lvmcache.c:478
msgid "lvmcache_info allocation failed"
msgstr ""
-#: cache/lvmcache.c:473
+#: cache/lvmcache.c:493
#, c-format
msgid "Ignoring duplicate PV %s on %s - using md %s"
msgstr ""
-#: cache/lvmcache.c:480
+#: cache/lvmcache.c:500
#, c-format
msgid "Duplicate PV %s on %s - using md %s"
msgstr ""
-#: cache/lvmcache.c:485
+#: cache/lvmcache.c:505
#, c-format
msgid "Found duplicate PV %s: using %s not %s"
msgstr ""
-#: commands/toolcontext.c:71
+#: cache/lvmcache.c:574
+msgid "Wiping internal VG cache"
+msgstr ""
+
+#: commands/toolcontext.c:73
msgid "LVM_SYSTEM_DIR environment variable is too long."
msgstr ""
-#: commands/toolcontext.c:144
+#: commands/toolcontext.c:146
#, c-format
msgid "Logging initialised at %s"
msgstr ""
-#: commands/toolcontext.c:163
+#: commands/toolcontext.c:165
#, c-format
msgid "Set umask to %04o"
msgstr ""
-#: commands/toolcontext.c:169 commands/toolcontext.c:180
+#: commands/toolcontext.c:171 commands/toolcontext.c:182
msgid "Device directory given in config file too long"
msgstr ""
-#: commands/toolcontext.c:185
+#: commands/toolcontext.c:187
#, c-format
msgid "Warning: proc dir %s not found - some checks will be bypassed"
msgstr ""
-#: commands/toolcontext.c:205 lvmcmdline.c:694
+#: commands/toolcontext.c:207 lvmcmdline.c:694
msgid "Invalid units specification"
msgstr ""
-#: commands/toolcontext.c:214
+#: commands/toolcontext.c:216
#, c-format
msgid "Setting host tag: %s"
msgstr ""
-#: commands/toolcontext.c:217
+#: commands/toolcontext.c:219
#, c-format
msgid "_set_tag: str_list_add %s failed"
msgstr ""
-#: commands/toolcontext.c:241
+#: commands/toolcontext.c:243
#, c-format
msgid "Invalid hostname string for tag %s"
msgstr ""
-#: commands/toolcontext.c:252
+#: commands/toolcontext.c:254
msgid "host_filter not supported yet"
msgstr ""
-#: commands/toolcontext.c:287
+#: commands/toolcontext.c:289
#, c-format
msgid "Invalid tag in config file: %s"
msgstr ""
-#: commands/toolcontext.c:320
+#: commands/toolcontext.c:322
msgid "LVM_SYSTEM_DIR or tag was too long"
msgstr ""
-#: commands/toolcontext.c:325
+#: commands/toolcontext.c:327
msgid "config_tree_list allocation failed"
msgstr ""
-#: commands/toolcontext.c:330
+#: commands/toolcontext.c:332
msgid "config_tree allocation failed"
msgstr ""
-#: commands/toolcontext.c:345
+#: commands/toolcontext.c:347
#, c-format
msgid "Loading config file: %s"
msgstr ""
-#: commands/toolcontext.c:347
+#: commands/toolcontext.c:349
#, c-format
msgid "Failed to load config file %s"
msgstr ""
-#: commands/toolcontext.c:370 commands/toolcontext.c:408
+#: commands/toolcontext.c:372 commands/toolcontext.c:410
msgid "Failed to create config tree"
msgstr ""
-#: commands/toolcontext.c:473
+#: commands/toolcontext.c:475
msgid "Failed to add /dev to internal device cache"
msgstr ""
-#: commands/toolcontext.c:477
+#: commands/toolcontext.c:479
msgid "device/scan not in config file: Defaulting to /dev"
msgstr ""
-#: commands/toolcontext.c:484
+#: commands/toolcontext.c:486
msgid "Invalid string in config file: devices/scan"
msgstr ""
-#: commands/toolcontext.c:490 format_text/format-text.c:1681
+#: commands/toolcontext.c:492 format_text/format-text.c:1692
#, c-format
msgid "Failed to add %s to internal device cache"
msgstr ""
-#: commands/toolcontext.c:528
+#: commands/toolcontext.c:503
+msgid "Invalid string in config file: devices/loopfiles"
+msgstr ""
+
+#: commands/toolcontext.c:509
+#, c-format
+msgid "Failed to add loopfile %s to internal device cache"
+msgstr ""
+
+#: commands/toolcontext.c:548
msgid "devices/filter not found in config file: no regex filter installed"
msgstr ""
-#: commands/toolcontext.c:532
+#: commands/toolcontext.c:552
msgid "Failed to create regex device filter"
msgstr ""
-#: commands/toolcontext.c:539
+#: commands/toolcontext.c:559
msgid "Failed to create lvm type filter"
msgstr ""
-#: commands/toolcontext.c:570
+#: commands/toolcontext.c:590
#, c-format
msgid "Persistent cache filename too long ('%s/.cache')."
msgstr ""
-#: commands/toolcontext.c:578
+#: commands/toolcontext.c:598
msgid "Failed to create persistent device filter"
msgstr ""
-#: commands/toolcontext.c:592
+#: commands/toolcontext.c:612
#, c-format
msgid "Failed to load existing device cache from %s"
msgstr ""
-#: commands/toolcontext.c:637
+#: commands/toolcontext.c:656
msgid "Invalid string in config file: global/format_libraries"
msgstr ""
-#: commands/toolcontext.c:648
+#: commands/toolcontext.c:667
#, c-format
msgid "Shared library %s does not contain format functions"
msgstr ""
-#: commands/toolcontext.c:681
+#: commands/toolcontext.c:699
#, c-format
msgid "_init_formats: Default format (%s) not found"
msgstr ""
-#: commands/toolcontext.c:734
+#: commands/toolcontext.c:752
msgid "Invalid string in config file: global/segment_libraries"
msgstr ""
-#: commands/toolcontext.c:745
+#: commands/toolcontext.c:763
#, c-format
msgid "Shared library %s does not contain segment type functions"
msgstr ""
-#: commands/toolcontext.c:759
+#: commands/toolcontext.c:777
#, c-format
msgid "Duplicate segment type %s: unloading shared library %s"
msgstr ""
-#: commands/toolcontext.c:786
+#: commands/toolcontext.c:804
msgid "_init_hostname: pool_strdup failed"
msgstr ""
-#: commands/toolcontext.c:791
+#: commands/toolcontext.c:809
msgid "_init_hostname: pool_strdup kernel_vsn failed"
msgstr ""
-#: commands/toolcontext.c:808
+#: commands/toolcontext.c:823
+msgid "WARNING: Metadata changes will NOT be backed up"
+msgstr ""
+
+#: commands/toolcontext.c:843
+#, c-format
+msgid "Couldn't create default archive path '%s/%s'."
+msgstr ""
+
+#: commands/toolcontext.c:852 commands/toolcontext.c:872
+msgid "backup_init failed."
+msgstr ""
+
+#: commands/toolcontext.c:864
+#, c-format
+msgid "Couldn't create default backup path '%s/%s'."
+msgstr ""
+
+#: commands/toolcontext.c:889
msgid "setlocale failed"
msgstr ""
-#: commands/toolcontext.c:817
+#: commands/toolcontext.c:898
msgid "Failed to allocate command context"
msgstr ""
-#: commands/toolcontext.c:835
+#: commands/toolcontext.c:916
msgid ""
"Failed to create LVM2 system dir for metadata backups, config files and "
"internal cache."
msgstr ""
-#: commands/toolcontext.c:837
+#: commands/toolcontext.c:918
msgid ""
"Set environment variable LVM_SYSTEM_DIR to alternative location or empty "
"string."
msgstr ""
-#: commands/toolcontext.c:843
+#: commands/toolcontext.c:924
msgid "Library memory pool creation failed"
msgstr ""
-#: commands/toolcontext.c:874
+#: commands/toolcontext.c:955
msgid "Command memory pool creation failed"
msgstr ""
-#: commands/toolcontext.c:934
+#: commands/toolcontext.c:1018
msgid "Reloading config files"
msgstr ""
@@ -1145,84 +1213,103 @@
msgid "%s not found in config: defaulting to %f"
msgstr ""
-#: device/dev-cache.c:60 device/dev-cache.c:97
+#: device/dev-cache.c:65 device/dev-cache.c:82 device/dev-cache.c:119
msgid "struct device allocation failed"
msgstr ""
-#: device/dev-cache.c:64
+#: device/dev-cache.c:69 device/dev-cache.c:86
msgid "struct str_list allocation failed"
msgstr ""
-#: device/dev-cache.c:69
+#: device/dev-cache.c:74 device/dev-cache.c:91 device/dev-cache.c:96
msgid "filename strdup failed"
msgstr ""
-#: device/dev-cache.c:202
+#: device/dev-cache.c:211
+#, c-format
+msgid "%s: Already in device cache"
+msgstr ""
+
+#: device/dev-cache.c:224
#, c-format
msgid "%s: Aliased to %s in device cache%s"
msgstr ""
-#: device/dev-cache.c:206
+#: device/dev-cache.c:228
#, c-format
msgid "%s: Added to device cache"
msgstr ""
-#: device/dev-cache.c:234
+#: device/dev-cache.c:269
msgid "Couldn't insert device into binary tree."
msgstr ""
-#: device/dev-cache.c:241
+#: device/dev-cache.c:276
msgid "Couldn't add alias to dev cache."
msgstr ""
-#: device/dev-cache.c:246
+#: device/dev-cache.c:281
msgid "Couldn't add name to hash in dev cache."
msgstr ""
-#: device/dev-cache.c:334
+#: device/dev-cache.c:361
+#, c-format
+msgid "%s: Not a regular file"
+msgstr ""
+
+#: device/dev-cache.c:391
#, c-format
msgid "%s: Symbolic link to directory"
msgstr ""
-#: device/dev-cache.c:343
+#: device/dev-cache.c:400
#, c-format
msgid "%s: Not a block device"
msgstr ""
-#: device/dev-cache.c:405
+#: device/dev-cache.c:463
msgid "Couldn't create binary tree for dev-cache."
msgstr ""
-#: device/dev-cache.c:421
+#: device/dev-cache.c:480
#, c-format
msgid "Device '%s' has been left open."
msgstr ""
-#: device/dev-cache.c:455
+#: device/dev-cache.c:515 device/dev-cache.c:541
#, c-format
msgid "Ignoring %s: %s"
msgstr ""
-#: device/dev-cache.c:461
+#: device/dev-cache.c:521
#, c-format
msgid "Ignoring %s: Not a directory"
msgstr ""
-#: device/dev-cache.c:466
+#: device/dev-cache.c:526
msgid "dir_list allocation failed"
msgstr ""
-#: device/dev-cache.c:495 device/dev-cache.c:499
+#: device/dev-cache.c:547
+#, c-format
+msgid "Ignoring %s: Not a regular file"
+msgstr ""
+
+#: device/dev-cache.c:552
+msgid "dir_list allocation failed for file"
+msgstr ""
+
+#: device/dev-cache.c:584 device/dev-cache.c:588
#, c-format
msgid "Path %s no longer valid for device(%d,%d)"
msgstr ""
-#: device/dev-cache.c:516
+#: device/dev-cache.c:605
#, c-format
msgid "Aborting - please provide new pathname for what used to be %s"
msgstr ""
-#: device/dev-cache.c:548
+#: device/dev-cache.c:641
msgid "dev_iter allocation failed"
msgstr ""
@@ -1255,54 +1342,59 @@
msgid "Bounce buffer alloca failed"
msgstr ""
-#: device/dev-io.c:250
+#: device/dev-io.c:238 device/dev-io.c:264
#, c-format
msgid "%s: size is %llu sectors"
msgstr ""
-#: device/dev-io.c:307
+#: device/dev-io.c:333
#, c-format
msgid "WARNING: %s already opened read-only"
msgstr ""
-#: device/dev-io.c:316
+#: device/dev-io.c:342
#, c-format
msgid "WARNING: dev_open(%s) called while suspended"
msgstr ""
-#: device/dev-io.c:328
+#: device/dev-io.c:354
#, c-format
msgid "%s: stat failed: Has device name changed?"
msgstr ""
-#: device/dev-io.c:357
+#: device/dev-io.c:380
+#, c-format
+msgid "%s: Not using O_DIRECT"
+msgstr ""
+
+#: device/dev-io.c:407
#, c-format
msgid "%s: fstat failed: Has device name changed?"
msgstr ""
-#: device/dev-io.c:373
+#: device/dev-io.c:423
#, c-format
-msgid "Opened %s %s"
+msgid "Opened %s %s%s"
msgstr ""
-#: device/dev-io.c:405
+#: device/dev-io.c:456
#, c-format
msgid "Closed %s"
msgstr ""
-#: device/dev-io.c:418
+#: device/dev-io.c:469
#, c-format
msgid "Attempt to close device '%s' which is not open."
msgstr ""
-#: device/dev-io.c:528
+#: device/dev-io.c:579
#, c-format
-msgid "Wiping %s at %llu length %Zu"
+msgid "Wiping %s at %llu length %zu"
msgstr ""
-#: device/dev-io.c:531
+#: device/dev-io.c:582
#, c-format
-msgid "Wiping %s at sector %llu length %Zu sectors"
+msgid "Wiping %s at sector %llu length %zu sectors"
msgstr ""
#: display/display.c:130
@@ -1358,7 +1450,7 @@
msgid "PE Size (KByte) %u"
msgstr ""
-#: display/display.c:282 display/display.c:573
+#: display/display.c:282 display/display.c:561
#, c-format
msgid "Total PE %u"
msgstr ""
@@ -1378,9 +1470,9 @@
msgid "PV UUID %s"
msgstr ""
-#: display/display.c:286 display/display.c:312 display/display.c:459
-#: display/display.c:506 display/display.c:592 format_text/archive.c:316
-#: lvmcmdline.c:729 mirror/mirrored.c:54 striped/striped.c:50
+#: display/display.c:286 display/display.c:312 display/display.c:445
+#: display/display.c:494 display/display.c:580 format_text/archive.c:311
+#: lvmcmdline.c:729 mirror/mirrored.c:66 striped/striped.c:51
msgid " "
msgstr ""
@@ -1404,257 +1496,267 @@
msgid "%s%s/%s:%s:%d:%d:-1:%d:%llu:%d:-1:%d:%d:%d:%d"
msgstr ""
-#: display/display.c:353
+#: display/display.c:352
msgid "--- Logical volume ---"
msgstr ""
-#: display/display.c:355
+#: display/display.c:354
#, c-format
msgid "LV Name %s%s/%s"
msgstr ""
-#: display/display.c:357
+#: display/display.c:356
#, c-format
msgid "VG Name %s"
msgstr ""
-#: display/display.c:359
+#: display/display.c:358
#, c-format
msgid "LV UUID %s"
msgstr ""
-#: display/display.c:361
+#: display/display.c:360
#, c-format
msgid "LV Write Access %s"
msgstr ""
-#: display/display.c:365
+#: display/display.c:364
msgid "LV snapshot status source of"
msgstr ""
-#: display/display.c:374
+#: display/display.c:373
#, c-format
msgid " %s%s/%s [%s]"
msgstr ""
-#: display/display.c:384
+#: display/display.c:386
#, c-format
msgid "LV snapshot status %s destination for %s%s/%s"
msgstr ""
-#: display/display.c:391
+#: display/display.c:393
msgid "LV Status suspended"
msgstr ""
-#: display/display.c:393
+#: display/display.c:395
#, c-format
msgid "LV Status %savailable"
msgstr ""
-#: display/display.c:401
+#: display/display.c:403
#, c-format
msgid "# open %u"
msgstr ""
-#: display/display.c:403
+#: display/display.c:405
#, c-format
msgid "LV Size %s"
msgstr ""
-#: display/display.c:408
+#: display/display.c:410
#, c-format
msgid "Current LE %u"
msgstr ""
-#: display/display.c:415
+#: display/display.c:414
#, c-format
-msgid "Segments %u"
+msgid "COW-table size %s"
msgstr ""
-#: display/display.c:425
+#: display/display.c:416
#, c-format
-msgid "Snapshot chunk size %s"
+msgid "COW-table LE %u"
msgstr ""
-#: display/display.c:434
+#: display/display.c:419
#, c-format
msgid "Allocated to snapshot %.2f%% "
msgstr ""
-#: display/display.c:446
+#: display/display.c:421
+#, c-format
+msgid "Snapshot chunk size %s"
+msgstr ""
+
+#: display/display.c:426
+#, c-format
+msgid "Segments %u"
+msgstr ""
+
+#: display/display.c:432
#, c-format
msgid "Allocation %s"
msgstr ""
-#: display/display.c:447
+#: display/display.c:433
#, c-format
msgid "Read ahead sectors %u"
msgstr ""
-#: display/display.c:451
+#: display/display.c:437
#, c-format
msgid "Persistent major %d"
msgstr ""
-#: display/display.c:452
+#: display/display.c:438
#, c-format
msgid "Persistent minor %d"
msgstr ""
-#: display/display.c:456
+#: display/display.c:442
#, c-format
msgid "Block device %d:%d"
msgstr ""
-#: display/display.c:468
+#: display/display.c:455
#, c-format
msgid "%sPhysical volume\t%s"
msgstr ""
-#: display/display.c:473
+#: display/display.c:461
#, c-format
msgid "%sPhysical extents\t%d to %d"
msgstr ""
-#: display/display.c:478
+#: display/display.c:466
#, c-format
msgid "%sLogical volume\t%s"
msgstr ""
-#: display/display.c:483
+#: display/display.c:471
#, c-format
msgid "%sLogical extents\t%d to %d"
msgstr ""
-#: display/display.c:494
+#: display/display.c:482
msgid "--- Segments ---"
msgstr ""
-#: display/display.c:497
+#: display/display.c:485
#, c-format
msgid "Logical extent %u to %u:"
msgstr ""
-#: display/display.c:500
+#: display/display.c:488
#, c-format
msgid " Type\t\t%s"
msgstr ""
-#: display/display.c:526
+#: display/display.c:514
msgid "--- Volume group ---"
msgstr ""
-#: display/display.c:527
+#: display/display.c:515
#, c-format
msgid "VG Name %s"
msgstr ""
-#: display/display.c:528
+#: display/display.c:516
#, c-format
msgid "System ID %s"
msgstr ""
-#: display/display.c:529
+#: display/display.c:517
#, c-format
msgid "Format %s"
msgstr ""
-#: display/display.c:531
+#: display/display.c:519
#, c-format
msgid "Metadata Areas %d"
msgstr ""
-#: display/display.c:533
+#: display/display.c:521
#, c-format
msgid "Metadata Sequence No %d"
msgstr ""
-#: display/display.c:536
+#: display/display.c:524
#, c-format
msgid "VG Access %s%s%s%s"
msgstr ""
-#: display/display.c:541
+#: display/display.c:529
#, c-format
msgid "VG Status %s%sresizable"
msgstr ""
-#: display/display.c:548
+#: display/display.c:536
msgid "Clustered yes"
msgstr ""
-#: display/display.c:549
+#: display/display.c:537
#, c-format
msgid "Shared %s"
msgstr ""
-#: display/display.c:552
+#: display/display.c:540
#, c-format
msgid "MAX LV %u"
msgstr ""
-#: display/display.c:553
+#: display/display.c:541
#, c-format
msgid "Cur LV %u"
msgstr ""
-#: display/display.c:554
+#: display/display.c:542
#, c-format
msgid "Open LV %u"
msgstr ""
-#: display/display.c:560
+#: display/display.c:548
#, c-format
msgid "Max PV %u"
msgstr ""
-#: display/display.c:561
+#: display/display.c:549
#, c-format
msgid "Cur PV %u"
msgstr ""
-#: display/display.c:562
+#: display/display.c:550
#, c-format
msgid "Act PV %u"
msgstr ""
-#: display/display.c:564
+#: display/display.c:552
#, c-format
msgid "VG Size %s"
msgstr ""
-#: display/display.c:569
+#: display/display.c:557
#, c-format
msgid "PE Size %s"
msgstr ""
-#: display/display.c:575
+#: display/display.c:563
#, c-format
msgid "Alloc PE / Size %u / %s"
msgstr ""
-#: display/display.c:581
+#: display/display.c:569
#, c-format
msgid "Free PE / Size %u / %s"
msgstr ""
-#: display/display.c:591
+#: display/display.c:579
#, c-format
msgid "VG UUID %s"
msgstr ""
-#: display/display.c:627
+#: display/display.c:615
#, c-format
msgid "%s:%s:%d:-1:%u:%u:%u:-1:%u:%u:%u:%llu:%u:%u:%u:%u:%s"
msgstr ""
-#: display/display.c:651
+#: display/display.c:639
#, c-format
msgid "\"%s\" %-9s [%-9s used / %s free]"
msgstr ""
-#: display/display.c:671 display/display.c:680 pvscan.c:33
-#: report/report.c:1268 report/report.c:1423
+#: display/display.c:659 display/display.c:668 pvscan.c:33
+#: report/report.c:1325 report/report.c:1477
#, c-format
msgid "%s"
msgstr ""
@@ -1663,8 +1765,8 @@
msgid "Please specify one file for output"
msgstr ""
-#: error/errseg.c:100 mirror/mirrored.c:261 snapshot/snapshot.c:165
-#: striped/striped.c:220 zero/zero.c:100
+#: error/errseg.c:100 mirror/mirrored.c:315 snapshot/snapshot.c:165
+#: striped/striped.c:230 zero/zero.c:100
#, c-format
msgid "Initialised segtype: %s"
msgstr ""
@@ -1696,36 +1798,40 @@
msgid "md filter allocation failed"
msgstr ""
-#: filters/filter-persistent.c:70
+#: filters/filter-persistent.c:56
+msgid "Wiping cache of LVM-capable devices"
+msgstr ""
+
+#: filters/filter-persistent.c:72
#, c-format
msgid "Couldn't find %s array in '%s'"
msgstr ""
-#: filters/filter-persistent.c:81
+#: filters/filter-persistent.c:83
msgid "Devices array contains a value which is not a string ... ignoring"
msgstr ""
-#: filters/filter-persistent.c:87
+#: filters/filter-persistent.c:89
#, c-format
msgid "Couldn't add '%s' to filter ... ignoring"
msgstr ""
-#: filters/filter-persistent.c:125
+#: filters/filter-persistent.c:127
#, c-format
msgid "Loaded persistent filter cache from %s"
msgstr ""
-#: filters/filter-persistent.c:169
+#: filters/filter-persistent.c:171
#, c-format
msgid "Internal persistent device cache empty - not writing to %s"
msgstr ""
-#: filters/filter-persistent.c:174
+#: filters/filter-persistent.c:176
#, c-format
msgid "Device cache incomplete - not writing to %s"
msgstr ""
-#: filters/filter-persistent.c:179
+#: filters/filter-persistent.c:181
#, c-format
msgid "Dumping persistent device cache to %s"
msgstr ""
@@ -1755,12 +1861,12 @@
msgid "invalid filter pattern"
msgstr ""
-#: filters/filter-regex.c:174
+#: filters/filter-regex.c:172
#, c-format
msgid "%s: New preferred name"
msgstr ""
-#: filters/filter-regex.c:190
+#: filters/filter-regex.c:188
#, c-format
msgid "%s: Skipping (regex)"
msgstr ""
@@ -1800,54 +1906,54 @@
msgid "sysfs dev_set creation failed"
msgstr ""
-#: filters/filter.c:85
+#: filters/filter.c:86
#, c-format
msgid "%s: Skipping: Unrecognised LVM device type %llu"
msgstr ""
-#: filters/filter.c:92
+#: filters/filter.c:93
#, c-format
msgid "%s: Skipping: open failed"
msgstr ""
-#: filters/filter.c:98
+#: filters/filter.c:99
#, c-format
msgid "%s: Skipping: dev_get_size failed"
msgstr ""
-#: filters/filter.c:103
+#: filters/filter.c:104
#, c-format
msgid "%s: Skipping: Too small to hold a PV"
msgstr ""
-#: filters/filter.c:108
+#: filters/filter.c:109
#, c-format
msgid "%s: Skipping: Partition table signature found"
msgstr ""
-#: filters/filter.c:135
+#: filters/filter.c:136
msgid "No proc filesystem found: using all block device types"
msgstr ""
-#: filters/filter.c:147
+#: filters/filter.c:148
msgid "Failed to create /proc/devices string"
msgstr ""
-#: filters/filter.c:202
+#: filters/filter.c:203
msgid "Expecting string in devices/types in config file"
msgstr ""
-#: filters/filter.c:210
+#: filters/filter.c:211
#, c-format
msgid "Max partition count missing for %s in devices/types in config file"
msgstr ""
-#: filters/filter.c:216
+#: filters/filter.c:217
#, c-format
msgid "Zero partition count invalid for %s in devices/types in config file"
msgstr ""
-#: filters/filter.c:244
+#: filters/filter.c:245
msgid "LVM type filter allocation failed"
msgstr ""
@@ -1901,12 +2007,12 @@
msgid "Found %s in %sVG %s"
msgstr ""
-#: format1/disk-rep.c:435 format_pool/disk_rep.c:72
+#: format1/disk-rep.c:435 format_pool/disk_rep.c:69
#, c-format
msgid "Ignoring duplicate PV %s on %s"
msgstr ""
-#: format1/disk-rep.c:440 format_pool/disk_rep.c:77
+#: format1/disk-rep.c:440 format_pool/disk_rep.c:74
#, c-format
msgid "Duplicate PV %s - using md %s"
msgstr ""
@@ -1915,220 +2021,218 @@
msgid "read_pvs_in_vg: dev_iter_create failed"
msgstr ""
-#: format1/disk-rep.c:527
+#: format1/disk-rep.c:526
#, c-format
msgid "Too many uuids to fit on %s"
msgstr ""
-#: format1/disk-rep.c:561
+#: format1/disk-rep.c:559
#, c-format
msgid "Couldn't zero lv area on device '%s'"
msgstr ""
-#: format1/disk-rep.c:571
+#: format1/disk-rep.c:567
#, c-format
msgid "lv_number %d too large"
msgstr ""
-#: format1/disk-rep.c:604
+#: format1/disk-rep.c:600
msgid "Invalid PV structure size."
msgstr ""
-#: format1/disk-rep.c:613
+#: format1/disk-rep.c:609
msgid "Couldn't allocate temporary PV buffer."
msgstr ""
-#: format1/disk-rep.c:639
+#: format1/disk-rep.c:635
#, c-format
msgid "Failed to write PV structure onto %s"
msgstr ""
-#: format1/disk-rep.c:658
+#: format1/disk-rep.c:654
#, c-format
msgid "Failed to write VG data to %s"
msgstr ""
-#: format1/disk-rep.c:663
+#: format1/disk-rep.c:659
#, c-format
msgid "Failed to write PV uuid list to %s"
msgstr ""
-#: format1/disk-rep.c:668
+#: format1/disk-rep.c:664
#, c-format
msgid "Failed to write LV's to %s"
msgstr ""
-#: format1/disk-rep.c:673
+#: format1/disk-rep.c:669
#, c-format
msgid "Failed to write extents to %s"
msgstr ""
-#: format1/disk-rep.c:715
+#: format1/disk-rep.c:709
#, c-format
msgid "Successfully wrote data to %s"
msgstr ""
-#: format1/format1.c:77
+#: format1/format1.c:75
#, c-format
msgid "VG data differs between PVs %s and %s"
msgstr ""
-#: format1/format1.c:79 format1/format1.c:94
+#: format1/format1.c:77 format1/format1.c:92
#, c-format
msgid "VG data on %s: %s %s %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u"
msgstr ""
-#: format1/format1.c:120
+#: format1/format1.c:118
#, c-format
msgid "%d PV(s) found for VG %s: expected %d"
msgstr ""
-#: format1/format1.c:307 format_pool/format_pool.c:235
+#: format1/format1.c:301 format_pool/format_pool.c:230
#, c-format
msgid "Reading physical volume data %s from disk"
msgstr ""
-#: format1/format1.c:348
+#: format1/format1.c:342
#, c-format
msgid "Physical volumes cannot be bigger than %s"
msgstr ""
-#: format1/format1.c:369
+#: format1/format1.c:363
msgid "Metadata would overwrite physical extents"
msgstr ""
-#: format1/format1.c:384
+#: format1/format1.c:378
#, c-format
msgid "logical volumes cannot contain more than %d extents."
msgstr ""
-#: format1/format1.c:389
+#: format1/format1.c:383
#, c-format
msgid "logical volumes cannot be larger than %s"
msgstr ""
-#: format1/format1.c:471
+#: format1/format1.c:465
#, c-format
msgid "Extent size must be between %s and %s"
msgstr ""
-#: format1/format1.c:481
+#: format1/format1.c:475
#, c-format
msgid "Extent size must be multiple of %s"
msgstr ""
-#: format1/format1.c:489 format_text/format-text.c:71
+#: format1/format1.c:483 format_text/format-text.c:71
msgid "Extent size must be power of 2"
msgstr ""
-#: format1/format1.c:585
+#: format1/format1.c:579
msgid "Couldn't create lvm1 label handler."
msgstr ""
-#: format1/format1.c:590
+#: format1/format1.c:584
msgid "Couldn't register lvm1 label handler."
msgstr ""
-#: format1/format1.c:594 format_pool/format_pool.c:360
-#: format_text/format-text.c:1695
+#: format1/format1.c:588 format_pool/format_pool.c:355
+#: format_text/format-text.c:1706
#, c-format
msgid "Initialised format: %s"
msgstr ""
-#: format1/import-export.c:71
+#: format1/import-export.c:72
#, c-format
msgid "System ID %s on %s differs from %s for volume group"
msgstr ""
-#: format1/import-export.c:101
+#: format1/import-export.c:108
msgid "Generated system_id too long"
msgstr ""
-#: format1/import-export.c:147
+#: format1/import-export.c:154
#, c-format
msgid "Volume group name %s too long to export"
msgstr ""
-#: format1/import-export.c:386
+#: format1/import-export.c:392
#, c-format
msgid "Segment type %s in LV %s: unsupported by format1"
msgstr ""
-#: format1/import-export.c:392
+#: format1/import-export.c:398
#, c-format
msgid "LV stripe found in LV %s: unsupported by format1"
msgstr ""
-#: format1/import-export.c:562
-#, c-format
-msgid "Couldn't find snapshot origin '%s'."
-msgstr ""
-
-#: format1/import-export.c:568
-#, c-format
-msgid "Couldn't find snapshot cow store '%s'."
-msgstr ""
-
-#: format1/import-export.c:610
+#: format1/import-export.c:590
msgid "Logical volume number out of bounds."
msgstr ""
-#: format1/import-export.c:617
+#: format1/import-export.c:597
#, c-format
msgid "Couldn't find logical volume '%s'."
msgstr ""
-#: format1/import-export.c:639
+#: format1/import-export.c:617
#, c-format
msgid "Couldn't find origin logical volume for snapshot '%s'."
msgstr ""
-#: format1/import-export.c:651
+#: format1/import-export.c:630
msgid "Couldn't add snapshot."
msgstr ""
-#: format1/import-extents.c:56
+#: format1/import-extents.c:55
msgid "Unable to create hash table for holding extent maps."
msgstr ""
-#: format1/import-extents.c:101
+#: format1/import-extents.c:100
#, c-format
msgid "Physical volume (%s) contains an unknown logical volume (%s)."
msgstr ""
-#: format1/import-extents.c:148
+#: format1/import-extents.c:145
msgid "invalid lv in extent map"
msgstr ""
-#: format1/import-extents.c:155
+#: format1/import-extents.c:152
msgid "logical extent number out of bounds"
msgstr ""
-#: format1/import-extents.c:161
+#: format1/import-extents.c:158
#, c-format
msgid "logical extent (%u) already mapped."
msgstr ""
-#: format1/import-extents.c:181
+#: format1/import-extents.c:178
#, c-format
msgid "Logical volume (%s) contains an incomplete mapping table."
msgstr ""
+#: format1/import-extents.c:225
+msgid "Failed to allocate linear segment."
+msgstr ""
+
#: format1/import-extents.c:273
#, c-format
msgid ""
"Number of stripes (%u) incompatible with logical extent count (%u) for %s"
msgstr ""
-#: format1/import-extents.c:356
+#: format1/import-extents.c:301
+msgid "Failed to allocate striped segment."
+msgstr ""
+
+#: format1/import-extents.c:359
msgid "Couldn't allocate logical volume maps."
msgstr ""
-#: format1/import-extents.c:361
+#: format1/import-extents.c:364
msgid "Couldn't fill logical volume maps."
msgstr ""
-#: format1/import-extents.c:371
+#: format1/import-extents.c:374
msgid "Couldn't build extent segments."
msgstr ""
@@ -2162,112 +2266,112 @@
msgstr ""
#: format1/lvm1-label.c:111 format_pool/pool_label.c:100
-#: format_text/text_label.c:282
+#: format_text/text_label.c:276
msgid "Couldn't allocate labeller object."
msgstr ""
-#: format_pool/disk_rep.c:99 format_pool/disk_rep.c:103
+#: format_pool/disk_rep.c:96 format_pool/disk_rep.c:100
#, c-format
msgid "Calculated uuid %s for %s"
msgstr ""
-#: format_pool/disk_rep.c:281
+#: format_pool/disk_rep.c:276
#, c-format
msgid "Unable to allocate %d 32-bit uints"
msgstr ""
-#: format_pool/disk_rep.c:349
+#: format_pool/disk_rep.c:343
#, c-format
msgid "No devices for vg %s found in cache"
msgstr ""
-#: format_pool/disk_rep.c:371
+#: format_pool/disk_rep.c:365
msgid "Unable to allocate pool list structure"
msgstr ""
-#: format_pool/format_pool.c:51
+#: format_pool/format_pool.c:47
#, c-format
msgid "Unable to allocate %d subpool structures"
msgstr ""
-#: format_pool/format_pool.c:71
+#: format_pool/format_pool.c:67
#, c-format
msgid "Unable to allocate %d pool_device structures"
msgstr ""
-#: format_pool/format_pool.c:93
+#: format_pool/format_pool.c:89
#, c-format
msgid "Missing subpool %d in pool %s"
msgstr ""
-#: format_pool/format_pool.c:98
+#: format_pool/format_pool.c:94
#, c-format
msgid "Missing device %d for subpool %d in pool %s"
msgstr ""
-#: format_pool/format_pool.c:119
+#: format_pool/format_pool.c:115
msgid "Unable to allocate volume group structure"
msgstr ""
-#: format_pool/format_pool.c:285
+#: format_pool/format_pool.c:280
msgid "Unable to allocate format instance structure for pool format"
msgstr ""
-#: format_pool/format_pool.c:295
+#: format_pool/format_pool.c:290
msgid "Unable to allocate metadata area structure for pool format"
msgstr ""
-#: format_pool/format_pool.c:338
+#: format_pool/format_pool.c:333
msgid "Unable to allocate format type structure for pool format"
msgstr ""
-#: format_pool/format_pool.c:351
+#: format_pool/format_pool.c:346
msgid "Couldn't create pool label handler."
msgstr ""
-#: format_pool/format_pool.c:356
+#: format_pool/format_pool.c:351
msgid "Couldn't register pool label handler."
msgstr ""
-#: format_pool/import_export.c:68
+#: format_pool/import_export.c:65
msgid "Unable to allocate lv list structure"
msgstr ""
-#: format_pool/import_export.c:73
+#: format_pool/import_export.c:70
msgid "Unable to allocate logical volume structure"
msgstr ""
-#: format_pool/import_export.c:102
+#: format_pool/import_export.c:99
#, c-format
msgid "Calculated lv uuid for lv %s: %s"
msgstr ""
-#: format_pool/import_export.c:138
+#: format_pool/import_export.c:134
msgid "Unable to allocate pv list structure"
msgstr ""
-#: format_pool/import_export.c:142
+#: format_pool/import_export.c:138
msgid "Unable to allocate pv structure"
msgstr ""
-#: format_pool/import_export.c:170
+#: format_pool/import_export.c:166
msgid "Unable to duplicate vg_name string"
msgstr ""
-#: format_pool/import_export.c:193
+#: format_pool/import_export.c:195
#, c-format
msgid "Found sptype %X and converted it to %s"
msgstr ""
-#: format_pool/import_export.c:206
-msgid "Unable to allocate striped lv_segment structure"
-msgstr ""
-
#: format_pool/import_export.c:210
msgid "Stripe size must be a power of 2"
msgstr ""
-#: format_pool/import_export.c:250
+#: format_pool/import_export.c:226
+msgid "Unable to allocate striped lv_segment structure"
+msgstr ""
+
+#: format_pool/import_export.c:267
msgid "Unable to allocate linear lv_segment structure"
msgstr ""
@@ -2276,74 +2380,93 @@
msgid "The '%s' operation is not supported for the pool labeller."
msgstr ""
-#: format_text/archive.c:150
-msgid "Couldn't scan archive directory."
+#: format_text/archive.c:148
+#, c-format
+msgid "Couldn't scan the archive directory (%s)."
msgstr ""
-#: format_text/archive.c:177
+#: format_text/archive.c:175
msgid "Couldn't create new archive file."
msgstr ""
-#: format_text/archive.c:228
+#: format_text/archive.c:223
#, c-format
msgid "Expiring archive %s"
msgstr ""
-#: format_text/archive.c:253
+#: format_text/archive.c:248
msgid "Couldn't create temporary archive name."
msgstr ""
-#: format_text/archive.c:258
+#: format_text/archive.c:253
msgid "Couldn't create FILE object for archive."
msgstr ""
-#: format_text/archive.c:275 format_text/archive.c:351
-#, c-format
-msgid "Couldn't scan the archive directory (%s)."
-msgstr ""
-
-#: format_text/archive.c:289
+#: format_text/archive.c:284
msgid "Archive file name too long."
msgstr ""
-#: format_text/archive.c:300
+#: format_text/archive.c:295
#, c-format
msgid "Archive rename failed for %s"
msgstr ""
-#: format_text/archive.c:317
+#: format_text/archive.c:312
#, c-format
msgid "File:\t\t%s"
msgstr ""
-#: format_text/archive.c:322
+#: format_text/archive.c:317
msgid "Couldn't create text instance object."
msgstr ""
-#: format_text/archive.c:332
+#: format_text/archive.c:327
msgid "Unable to read archive file."
msgstr ""
-#: format_text/archive.c:337
+#: format_text/archive.c:332
#, c-format
msgid "VG name: \t%s"
msgstr ""
-#: format_text/archive.c:338
+#: format_text/archive.c:333
#, c-format
msgid "Description:\t%s"
msgstr ""
-#: format_text/archive.c:339
+#: format_text/archive.c:334
#, c-format
msgid "Backup Time:\t%s"
msgstr ""
-#: format_text/archive.c:356
+#: format_text/archive.c:351
#, c-format
msgid "No archives found in %s."
msgstr ""
+#: format_text/archiver.c:43 format_text/archiver.c:155
+msgid "archive_params alloc failed"
+msgstr ""
+
+#: format_text/archiver.c:128
+#, c-format
+msgid "Archiving volume group \"%s\" metadata (seqno %u)."
+msgstr ""
+
+#: format_text/archiver.c:303
+#, c-format
+msgid "PV %s is a different format (seqno %s)"
+msgstr ""
+
+#: format_text/archiver.c:364
+#, c-format
+msgid "Creating volume group backup \"%s\" (seqno %u)."
+msgstr ""
+
+#: format_text/archiver.c:402
+msgid "Failed to generate backup filename."
+msgstr ""
+
#: format_text/export.c:69
#, c-format
msgid "uname failed: %s"
@@ -2353,19 +2476,23 @@
msgid "Internal error tracking indentation"
msgstr ""
-#: format_text/flags.c:73
+#: format_text/export.c:737
+msgid "text_export buffer allocation failed"
+msgstr ""
+
+#: format_text/flags.c:76
msgid "Unknown flag set requested."
msgstr ""
-#: format_text/flags.c:119
+#: format_text/flags.c:122
msgid "Metadata inconsistency: Not all flags successfully exported."
msgstr ""
-#: format_text/flags.c:141
+#: format_text/flags.c:144
msgid "Status value is not a string."
msgstr ""
-#: format_text/flags.c:152
+#: format_text/flags.c:155
#, c-format
msgid "Unknown status flag '%s'."
msgstr ""
@@ -2397,205 +2524,200 @@
msgid "Incorrect start sector in metadata area header: %llu"
msgstr ""
-#: format_text/format-text.c:275 format_text/format-text.c:376
+#: format_text/format-text.c:285
+#, c-format
+msgid "VG %s not found on %s"
+msgstr ""
+
+#: format_text/format-text.c:293 format_text/format-text.c:390
#, c-format
msgid "VG %s metadata too large for circular buffer"
msgstr ""
-#: format_text/format-text.c:290
+#: format_text/format-text.c:308
#, c-format
-msgid "Read %s metadata (%u) from %s at %llu size %llu"
+msgid "Read %s %smetadata (%u) from %s at %llu size %llu"
msgstr ""
-#: format_text/format-text.c:361
+#: format_text/format-text.c:375
#, c-format
msgid "VG %s metadata writing failed"
msgstr ""
-#: format_text/format-text.c:381
+#: format_text/format-text.c:395
#, c-format
msgid "Writing %s metadata to %s at %llu len %llu"
msgstr ""
-#: format_text/format-text.c:393
+#: format_text/format-text.c:407
#, c-format
msgid "Writing metadata to %s at %llu len %u"
msgstr ""
-#: format_text/format-text.c:460
+#: format_text/format-text.c:481
#, c-format
-msgid "Committing %s metadata (%u) to %s header at %llu"
+msgid "%sCommitting %s metadata (%u) to %s header at %llu"
msgstr ""
-#: format_text/format-text.c:465 format_text/format-text.c:534
+#: format_text/format-text.c:486 format_text/format-text.c:566
msgid "Failed to write metadata area header"
msgstr ""
-#: format_text/format-text.c:567
+#: format_text/format-text.c:599
#, c-format
msgid "'%s' does not contain volume group '%s'."
msgstr ""
-#: format_text/format-text.c:571
+#: format_text/format-text.c:603
#, c-format
msgid "Read volume group %s from %s"
msgstr ""
-#: format_text/format-text.c:605
+#: format_text/format-text.c:646
msgid "Text format failed to determine directory."
msgstr ""
-#: format_text/format-text.c:610
+#: format_text/format-text.c:651
msgid "Couldn't create temporary text file name."
msgstr ""
-#: format_text/format-text.c:620
+#: format_text/format-text.c:661
#, c-format
msgid "Writing %s metadata to %s"
msgstr ""
-#: format_text/format-text.c:623
+#: format_text/format-text.c:664
#, c-format
msgid "Failed to write metadata to %s."
msgstr ""
-#: format_text/format-text.c:641 format_text/format-text.c:667
-#: format_text/format-text.c:704
+#: format_text/format-text.c:682 format_text/format-text.c:708
+#: format_text/format-text.c:745 misc/lvm-file.c:90
#, c-format
msgid "%s: rename to %s failed: %s"
msgstr ""
-#: format_text/format-text.c:656
+#: format_text/format-text.c:697
#, c-format
msgid "Test mode: Skipping committing %s metadata (%u)"
msgstr ""
-#: format_text/format-text.c:659
+#: format_text/format-text.c:700
#, c-format
msgid "Unlinking %s"
msgstr ""
-#: format_text/format-text.c:664
+#: format_text/format-text.c:705
#, c-format
msgid "Committing %s metadata (%u)"
msgstr ""
-#: format_text/format-text.c:701
+#: format_text/format-text.c:742
msgid "Test mode: Skipping rename"
msgstr ""
-#: format_text/format-text.c:765 format_text/format-text.c:1425
+#: format_text/format-text.c:805 format_text/format-text.c:1438
#, c-format
msgid "Name too long %s/%s"
msgstr ""
-#: format_text/format-text.c:894
+#: format_text/format-text.c:933
#, c-format
msgid "Physical extents end beyond end of device %s!"
msgstr ""
-#: format_text/format-text.c:910
+#: format_text/format-text.c:960
#, c-format
-msgid "Warning: metadata area fills disk %s"
+msgid "Warning: metadata area fills disk leaving no space for data on %s."
msgstr ""
-#: format_text/format-text.c:940 format_text/format-text.c:986
+#: format_text/format-text.c:990 format_text/format-text.c:1036
msgid "Failed to wipe new metadata area"
msgstr ""
-#: format_text/format-text.c:1035
+#: format_text/format-text.c:1083
#, c-format
msgid "Creating metadata area on %s at sector %llu size %llu sectors"
msgstr ""
-#: format_text/format-text.c:1114
-#, c-format
-msgid "format_text: _vg_read failed to read VG %s"
-msgstr ""
-
-#: format_text/format-text.c:1120
-#, c-format
-msgid "Warning: Volume group %s is not consistent"
-msgstr ""
-
-#: format_text/format-text.c:1147
+#: format_text/format-text.c:1164
msgid "_add_raw allocation failed"
msgstr ""
-#: format_text/format-text.c:1207
+#: format_text/format-text.c:1223
#, c-format
msgid "Must be exactly one data area (found %d) on PV %s"
msgstr ""
-#: format_text/format-text.c:1224 format_text/format-text.c:1228
+#: format_text/format-text.c:1238 format_text/format-text.c:1242
msgid "metadata_area allocation failed"
msgstr ""
-#: format_text/format-text.c:1402
+#: format_text/format-text.c:1416
msgid "Couldn't allocate format instance object."
msgstr ""
-#: format_text/format-text.c:1513
+#: format_text/format-text.c:1523
#, c-format
msgid "%s: Volume group filename may not end in .tmp"
msgstr ""
-#: format_text/format-text.c:1547
+#: format_text/format-text.c:1557
msgid "Couldn't allocate text format context object."
msgstr ""
-#: format_text/format-text.c:1569
+#: format_text/format-text.c:1579
msgid "_add_dir allocation failed"
msgstr ""
-#: format_text/format-text.c:1572
+#: format_text/format-text.c:1582
#, c-format
msgid "Adding text format metadata dir: %s"
msgstr ""
-#: format_text/format-text.c:1589
+#: format_text/format-text.c:1599
msgid "Empty metadata disk_area section of config file"
msgstr ""
-#: format_text/format-text.c:1594
+#: format_text/format-text.c:1604
msgid "Missing start_sector in metadata disk_area section of config file"
msgstr ""
-#: format_text/format-text.c:1601
+#: format_text/format-text.c:1611
msgid "Missing size in metadata disk_area section of config file"
msgstr ""
-#: format_text/format-text.c:1608
+#: format_text/format-text.c:1618
msgid "Missing uuid in metadata disk_area section of config file"
msgstr ""
-#: format_text/format-text.c:1614
+#: format_text/format-text.c:1624
#, c-format
msgid "Invalid uuid in metadata disk_area section of config file: %s"
msgstr ""
-#: format_text/format-text.c:1623 format_text/import_vsn1.c:155
+#: format_text/format-text.c:1633 format_text/import_vsn1.c:156
msgid "Couldn't find device."
msgstr ""
-#: format_text/format-text.c:1625 format_text/import_vsn1.c:157
+#: format_text/format-text.c:1635 format_text/import_vsn1.c:158
#, c-format
msgid "Couldn't find device with uuid '%s'."
msgstr ""
-#: format_text/format-text.c:1652
+#: format_text/format-text.c:1663
msgid "Failed to allocate dir_list"
msgstr ""
-#: format_text/format-text.c:1663
+#: format_text/format-text.c:1674
msgid "Couldn't create text label handler."
msgstr ""
-#: format_text/format-text.c:1668
+#: format_text/format-text.c:1679
msgid "Couldn't register text label handler."
msgstr ""
-#: format_text/format-text.c:1675
+#: format_text/format-text.c:1686
msgid "Invalid string in config file: metadata/dirs"
msgstr ""
@@ -2603,215 +2725,215 @@
msgid "Couldn't read volume group metadata."
msgstr ""
-#: format_text/import_vsn1.c:47
+#: format_text/import_vsn1.c:48
#, c-format
msgid "Can't process text format file - %s."
msgstr ""
-#: format_text/import_vsn1.c:95
+#: format_text/import_vsn1.c:96
msgid "Couldn't find uuid."
msgstr ""
-#: format_text/import_vsn1.c:101
+#: format_text/import_vsn1.c:102
msgid "uuid must be a string."
msgstr ""
-#: format_text/import_vsn1.c:106
+#: format_text/import_vsn1.c:107
msgid "Invalid uuid."
msgstr ""
-#: format_text/import_vsn1.c:139
+#: format_text/import_vsn1.c:140
msgid "Empty pv section."
msgstr ""
-#: format_text/import_vsn1.c:144
+#: format_text/import_vsn1.c:145
msgid "Couldn't read uuid for volume group."
msgstr ""
-#: format_text/import_vsn1.c:172
+#: format_text/import_vsn1.c:173
msgid "Couldn't find status flags for physical volume."
msgstr ""
-#: format_text/import_vsn1.c:177
+#: format_text/import_vsn1.c:178
msgid "Couldn't read status flags for physical volume."
msgstr ""
-#: format_text/import_vsn1.c:182
+#: format_text/import_vsn1.c:183
msgid "Couldn't read extent size for volume group."
msgstr ""
-#: format_text/import_vsn1.c:187
+#: format_text/import_vsn1.c:188
msgid "Couldn't find extent count (pe_count) for physical volume."
msgstr ""
-#: format_text/import_vsn1.c:197
+#: format_text/import_vsn1.c:199
#, c-format
msgid "Couldn't read tags for physical volume %s in %s."
msgstr ""
-#: format_text/import_vsn1.c:248
+#: format_text/import_vsn1.c:252
msgid "Empty segment section."
msgstr ""
-#: format_text/import_vsn1.c:253
+#: format_text/import_vsn1.c:257
#, c-format
msgid "Couldn't read 'start_extent' for segment '%s'."
msgstr ""
-#: format_text/import_vsn1.c:259
+#: format_text/import_vsn1.c:263
#, c-format
msgid "Couldn't read 'extent_count' for segment '%s'."
msgstr ""
-#: format_text/import_vsn1.c:269
+#: format_text/import_vsn1.c:273
msgid "Segment type must be a string."
msgstr ""
-#: format_text/import_vsn1.c:287
+#: format_text/import_vsn1.c:293
msgid "Segment allocation failed"
msgstr ""
-#: format_text/import_vsn1.c:308
+#: format_text/import_vsn1.c:306
#, c-format
msgid "Couldn't read tags for a segment of %s/%s."
msgstr ""
-#: format_text/import_vsn1.c:336
+#: format_text/import_vsn1.c:335
#, c-format
msgid "Zero areas not allowed for segment '%s'"
msgstr ""
-#: format_text/import_vsn1.c:378
+#: format_text/import_vsn1.c:375
#, c-format
msgid "Couldn't find volume '%s' for segment '%s'."
msgstr ""
-#: format_text/import_vsn1.c:391
+#: format_text/import_vsn1.c:388
#, c-format
msgid "Incorrect number of areas in area array for segment '%s'."
msgstr ""
-#: format_text/import_vsn1.c:421
+#: format_text/import_vsn1.c:418
msgid "Only one segment permitted for snapshot"
msgstr ""
-#: format_text/import_vsn1.c:427
+#: format_text/import_vsn1.c:424
msgid "Couldn't read segment count for logical volume."
msgstr ""
-#: format_text/import_vsn1.c:432
+#: format_text/import_vsn1.c:429
msgid "segment_count and actual number of segments disagree."
msgstr ""
-#: format_text/import_vsn1.c:478 format_text/import_vsn1.c:544
+#: format_text/import_vsn1.c:475 format_text/import_vsn1.c:543
msgid "Empty logical volume section."
msgstr ""
-#: format_text/import_vsn1.c:483
+#: format_text/import_vsn1.c:480
msgid "Couldn't find status flags for logical volume."
msgstr ""
-#: format_text/import_vsn1.c:488
+#: format_text/import_vsn1.c:485
msgid "Couldn't read status flags for logical volume."
msgstr ""
-#: format_text/import_vsn1.c:496 format_text/import_vsn1.c:710
+#: format_text/import_vsn1.c:493 format_text/import_vsn1.c:714
msgid "allocation_policy must be a string."
msgstr ""
-#: format_text/import_vsn1.c:517
+#: format_text/import_vsn1.c:516
#, c-format
msgid "Couldn't read tags for logical volume %s/%s."
msgstr ""
-#: format_text/import_vsn1.c:537
+#: format_text/import_vsn1.c:536
#, c-format
msgid "Lost logical volume reference %s"
msgstr ""
-#: format_text/import_vsn1.c:550
+#: format_text/import_vsn1.c:549
#, c-format
msgid "Couldn't read uuid for logical volume %s."
msgstr ""
-#: format_text/import_vsn1.c:569
+#: format_text/import_vsn1.c:576
#, c-format
msgid "Couldn't read minor number for logical volume %s."
msgstr ""
-#: format_text/import_vsn1.c:576
+#: format_text/import_vsn1.c:584
#, c-format
msgid "Couldn't read major number for logical volume %s."
msgstr ""
-#: format_text/import_vsn1.c:597
+#: format_text/import_vsn1.c:601
#, c-format
msgid "Couldn't find section '%s'."
msgstr ""
-#: format_text/import_vsn1.c:626
+#: format_text/import_vsn1.c:630
msgid "Couldn't find volume group in file."
msgstr ""
-#: format_text/import_vsn1.c:654
+#: format_text/import_vsn1.c:658
msgid "system_id must be a string"
msgstr ""
-#: format_text/import_vsn1.c:661
+#: format_text/import_vsn1.c:665
#, c-format
msgid "Couldn't read uuid for volume group %s."
msgstr ""
-#: format_text/import_vsn1.c:666
+#: format_text/import_vsn1.c:670
#, c-format
msgid "Couldn't read 'seqno' for volume group %s."
msgstr ""
-#: format_text/import_vsn1.c:672
+#: format_text/import_vsn1.c:676
#, c-format
msgid "Couldn't find status flags for volume group %s."
msgstr ""
-#: format_text/import_vsn1.c:678
+#: format_text/import_vsn1.c:682
#, c-format
msgid "Couldn't read status flags for volume group %s."
msgstr ""
-#: format_text/import_vsn1.c:684
+#: format_text/import_vsn1.c:688
#, c-format
msgid "Couldn't read extent size for volume group %s."
msgstr ""
-#: format_text/import_vsn1.c:695
+#: format_text/import_vsn1.c:699
#, c-format
msgid "Couldn't read 'max_lv' for volume group %s."
msgstr ""
-#: format_text/import_vsn1.c:701
+#: format_text/import_vsn1.c:705
#, c-format
msgid "Couldn't read 'max_pv' for volume group %s."
msgstr ""
-#: format_text/import_vsn1.c:726
+#: format_text/import_vsn1.c:730
msgid "Couldn't create hash table."
msgstr ""
-#: format_text/import_vsn1.c:733
+#: format_text/import_vsn1.c:737
#, c-format
msgid "Couldn't find all physical volumes for volume group %s."
msgstr ""
-#: format_text/import_vsn1.c:745
+#: format_text/import_vsn1.c:748
#, c-format
msgid "Couldn't read tags for volume group %s."
msgstr ""
-#: format_text/import_vsn1.c:751
+#: format_text/import_vsn1.c:754
#, c-format
msgid "Couldn't read all logical volume names for volume group %s."
msgstr ""
-#: format_text/import_vsn1.c:758
+#: format_text/import_vsn1.c:761
#, c-format
msgid "Couldn't read all logical volumes for volume group %s."
msgstr ""
@@ -2820,15 +2942,15 @@
msgid "Found a tag that is not a string"
msgstr ""
-#: format_text/text_label.c:100 format_text/text_label.c:105
+#: format_text/text_label.c:96 format_text/text_label.c:101
msgid "struct data_area_list allocation failed"
msgstr ""
-#: format_text/text_label.c:140 format_text/text_label.c:151
+#: format_text/text_label.c:136 format_text/text_label.c:147
msgid "struct mda_list allocation failed"
msgstr ""
-#: format_text/text_label.c:145 format_text/text_label.c:156
+#: format_text/text_label.c:141 format_text/text_label.c:152
msgid "struct mda_context allocation failed"
msgstr ""
@@ -2836,22 +2958,22 @@
msgid "Couldn't allocate memory for labeller list object."
msgstr ""
-#: label/label.c:130 label/label.c:223
+#: label/label.c:131 label/label.c:225
#, c-format
msgid "%s: Failed to read label area"
msgstr ""
-#: label/label.c:142 label/label.c:170
+#: label/label.c:143 label/label.c:170
#, c-format
msgid "Ignoring additional label on %s at sector %llu"
msgstr ""
-#: label/label.c:147
+#: label/label.c:148
#, c-format
msgid "%s: Label for sector %llu found at sector %llu - ignoring"
msgstr ""
-#: label/label.c:156
+#: label/label.c:157
#, c-format
msgid "Label checksum incorrect on %s - ignoring"
msgstr ""
@@ -2861,46 +2983,46 @@
msgid "%s: %s label detected"
msgstr ""
-#: label/label.c:186
+#: label/label.c:189
#, c-format
msgid "%s: No label detected"
msgstr ""
-#: label/label.c:209
+#: label/label.c:211
#, c-format
msgid "Scanning for labels to wipe from %s"
msgstr ""
-#: label/label.c:250
+#: label/label.c:251
#, c-format
msgid "%s: Wiping label at sector %llu"
msgstr ""
-#: label/label.c:254
+#: label/label.c:255
#, c-format
msgid "Failed to remove label from %s at sector %llu"
msgstr ""
-#: label/label.c:296
+#: label/label.c:297
msgid "Label handler does not support label writes"
msgstr ""
-#: label/label.c:301
+#: label/label.c:302
#, c-format
msgid "Label sector %llu beyond range (%ld)"
msgstr ""
-#: label/label.c:325
+#: label/label.c:326
#, c-format
msgid "%s: Writing label to sector %llu"
msgstr ""
-#: label/label.c:328
+#: label/label.c:329
#, c-format
msgid "Failed to write label to %s"
msgstr ""
-#: label/label.c:363
+#: label/label.c:364
msgid "label allocaction failed"
msgstr ""
@@ -2943,8 +3065,8 @@
msgid "Error locking on node %s: %s"
msgstr ""
-#: locking/cluster_locking.c:406 locking/file_locking.c:260
-#: locking/locking.c:244 locking/no_locking.c:71
+#: locking/cluster_locking.c:406 locking/file_locking.c:264
+#: locking/locking.c:247 locking/no_locking.c:71
#, c-format
msgid "Unrecognised lock scope: %d"
msgstr ""
@@ -2977,87 +3099,87 @@
msgid "CTRL-c detected: giving up waiting for lock"
msgstr ""
-#: locking/file_locking.c:147
+#: locking/file_locking.c:149
#, c-format
msgid "Unrecognised lock type: %d"
msgstr ""
-#: locking/file_locking.c:161
+#: locking/file_locking.c:163
#, c-format
msgid "Locking %s %c%c"
msgstr ""
-#: locking/file_locking.c:231
+#: locking/file_locking.c:235
#, c-format
msgid "Unlocking LV %s"
msgstr ""
-#: locking/file_locking.c:236
+#: locking/file_locking.c:240
#, c-format
msgid "Locking LV %s (NL)"
msgstr ""
-#: locking/file_locking.c:241
+#: locking/file_locking.c:245
#, c-format
msgid "Locking LV %s (R)"
msgstr ""
-#: locking/file_locking.c:246
+#: locking/file_locking.c:250
#, c-format
msgid "Locking LV %s (W)"
msgstr ""
-#: locking/file_locking.c:251
+#: locking/file_locking.c:255
#, c-format
msgid "Locking LV %s (EX)"
msgstr ""
-#: locking/locking.c:130
+#: locking/locking.c:132
msgid ""
"WARNING: Locking disabled. Be careful! This could corrupt your metadata."
msgstr ""
-#: locking/locking.c:137
+#: locking/locking.c:139
msgid "File-based locking enabled."
msgstr ""
-#: locking/locking.c:144
+#: locking/locking.c:146
msgid "External locking enabled."
msgstr ""
-#: locking/locking.c:152
+#: locking/locking.c:154
msgid "Cluster locking enabled."
msgstr ""
-#: locking/locking.c:157
+#: locking/locking.c:159
msgid "Unknown locking type requested."
msgstr ""
-#: locking/locking.c:165
+#: locking/locking.c:167
msgid "Locking disabled - only read operations permitted."
msgstr ""
-#: locking/locking.c:191
+#: locking/locking.c:194
#, c-format
msgid "LVM1 proc VG pathname too long for %s"
msgstr ""
-#: locking/locking.c:196
+#: locking/locking.c:199
#, c-format
msgid "%s exists: Is the original LVM driver using this volume group?"
msgstr ""
-#: locking/locking.c:285 lvresize.c:469
+#: locking/locking.c:284 lvresize.c:526
#, c-format
msgid "Failed to suspend %s"
msgstr ""
-#: locking/locking.c:307
+#: locking/locking.c:305
#, c-format
msgid "Failed to activate %s"
msgstr ""
-#: log/log.c:133
+#: log/log.c:135
msgid "Test mode: Metadata will NOT be updated."
msgstr ""
@@ -3081,22 +3203,23 @@
msgid "Setting logical volume \"%s\" read-only"
msgstr ""
-#: lvchange.c:47 lvchange.c:162 lvchange.c:205 lvchange.c:290 lvchange.c:348
+#: lvchange.c:47 lvchange.c:168 lvchange.c:211 lvchange.c:296 lvchange.c:354
+#: lvconvert.c:87
#, c-format
msgid "Updating logical volume \"%s\" on disk(s)"
msgstr ""
-#: lvchange.c:56 lvchange.c:214 lvchange.c:299
+#: lvchange.c:56 lvchange.c:220 lvchange.c:305 lvconvert.c:97
#, c-format
msgid "Failed to lock %s"
msgstr ""
-#: lvchange.c:66 lvchange.c:224 lvchange.c:309
+#: lvchange.c:66 lvchange.c:230 lvchange.c:315
#, c-format
msgid "Updating permissions for \"%s\" in kernel"
msgstr ""
-#: lvchange.c:68 lvchange.c:226 lvchange.c:311 lvresize.c:481
+#: lvchange.c:68 lvchange.c:232 lvchange.c:317 lvconvert.c:110 lvresize.c:538
#, c-format
msgid "Problem reactivating %s"
msgstr ""
@@ -3113,203 +3236,313 @@
#: lvchange.c:98
#, c-format
+msgid "Locking failed: ignoring clustered logical volume %s"
+msgstr ""
+
+#: lvchange.c:104
+#, c-format
msgid "Activating logical volume \"%s\" exclusively"
msgstr ""
-#: lvchange.c:105
+#: lvchange.c:111
#, c-format
msgid "Activating logical volume \"%s\" locally"
msgstr ""
-#: lvchange.c:112
+#: lvchange.c:118
#, c-format
msgid "Activating logical volume \"%s\""
msgstr ""
-#: lvchange.c:122
+#: lvchange.c:128
#, c-format
msgid "Spawning background pvmove process for %s"
msgstr ""
-#: lvchange.c:133
+#: lvchange.c:139
#, c-format
msgid "Refreshing logical volume \"%s\" (if active)"
msgstr ""
-#: lvchange.c:150
+#: lvchange.c:156
#, c-format
msgid "Allocation policy of logical volume \"%s\" is already %s"
msgstr ""
-#: lvchange.c:159
+#: lvchange.c:165
#, c-format
msgid "Setting contiguous allocation policy for \"%s\" to %s"
msgstr ""
-#: lvchange.c:195
+#: lvchange.c:201
#, c-format
msgid "Read ahead is already %u for \"%s\""
msgstr ""
-#: lvchange.c:202
+#: lvchange.c:208
#, c-format
msgid "Setting read ahead to %u for \"%s\""
msgstr ""
-#: lvchange.c:241
+#: lvchange.c:247
#, c-format
msgid "Minor number is already not persistent for \"%s\""
msgstr ""
-#: lvchange.c:248
+#: lvchange.c:254
#, c-format
msgid "Disabling persistent device number for \"%s\""
msgstr ""
-#: lvchange.c:252
+#: lvchange.c:258
msgid "Minor number must be specified with -My"
msgstr ""
-#: lvchange.c:256
+#: lvchange.c:262
msgid "Major number must be specified with -My"
msgstr ""
-#: lvchange.c:264
+#: lvchange.c:270
#, c-format
msgid "%s device number not changed."
msgstr ""
-#: lvchange.c:270
+#: lvchange.c:276
#, c-format
msgid "Ensuring %s is inactive."
msgstr ""
-#: lvchange.c:272
+#: lvchange.c:278
#, c-format
msgid "%s: deactivation failed"
msgstr ""
-#: lvchange.c:278
+#: lvchange.c:284
#, c-format
msgid "Setting persistent device number to (%d, %d) for \"%s\""
msgstr ""
-#: lvchange.c:281
+#: lvchange.c:287
#, c-format
msgid "Re-activating logical volume \"%s\""
msgstr ""
-#: lvchange.c:284
+#: lvchange.c:290
#, c-format
msgid "%s: reactivation failed"
msgstr ""
-#: lvchange.c:324 lvcreate.c:542 pvchange.c:46 vgchange.c:219 vgcreate.c:117
+#: lvchange.c:330 lvcreate.c:724 pvchange.c:49 vgchange.c:322 vgcreate.c:111
msgid "Failed to get tag"
msgstr ""
-#: lvchange.c:329
+#: lvchange.c:335
#, c-format
msgid "Logical volume %s/%s does not support tags"
msgstr ""
-#: lvchange.c:336 lvcreate.c:553
+#: lvchange.c:342 lvcreate.c:735
#, c-format
msgid "Failed to add tag %s to %s/%s"
msgstr ""
-#: lvchange.c:342
+#: lvchange.c:348
#, c-format
msgid "Failed to remove tag %s from %s/%s"
msgstr ""
-#: lvchange.c:374
+#: lvchange.c:381
#, c-format
msgid "Only -a permitted with read-only volume group \"%s\""
msgstr ""
-#: lvchange.c:383
+#: lvchange.c:390
#, c-format
msgid "Can't change logical volume \"%s\" under snapshot"
msgstr ""
-#: lvchange.c:389
+#: lvchange.c:396
#, c-format
msgid "Can't change snapshot logical volume \"%s\""
msgstr ""
-#: lvchange.c:395
+#: lvchange.c:402
#, c-format
msgid "Unable to change pvmove LV %s"
msgstr ""
-#: lvchange.c:397
+#: lvchange.c:404
msgid "Use 'pvmove --abort' to abandon a pvmove"
msgstr ""
-#: lvchange.c:450
+#: lvchange.c:409
+#, c-format
+msgid "Unable to change mirror log LV %s directly"
+msgstr ""
+
+#: lvchange.c:414
+#, c-format
+msgid "Unable to change mirror image LV %s directly"
+msgstr ""
+
+#: lvchange.c:420
+#, c-format
+msgid "Unable to change internal LV %s directly"
+msgstr ""
+
+#: lvchange.c:474
#, c-format
msgid "Logical volume \"%s\" changed"
msgstr ""
-#: lvchange.c:472
+#: lvchange.c:496
msgid ""
"One or more of -a, -C, -j, -m, -M, -p, -r, --refresh, --alloc, --addtag or --"
"deltag required"
msgstr ""
-#: lvchange.c:482
+#: lvchange.c:506
msgid "Only -a permitted with --ignorelockingfailure"
msgstr ""
-#: lvchange.c:487
+#: lvchange.c:511 lvconvert.c:172
msgid "Please give logical volume path(s)"
msgstr ""
-#: lvchange.c:493
+#: lvchange.c:517
msgid "--major and --minor require -My"
msgstr ""
-#: lvchange.c:498
+#: lvchange.c:522
msgid "Only give one logical volume when specifying minor"
msgstr ""
-#: lvchange.c:503
+#: lvchange.c:527
msgid "Only one of --alloc and --contiguous permitted"
msgstr ""
-#: lvcreate.c:63
+#: lvconvert.c:37
+#, c-format
+msgid "Logical volume %s is already not mirrored."
+msgstr ""
+
+#: lvconvert.c:49
+#, c-format
+msgid "Logical volume %s has multiple mirror segments."
+msgstr ""
+
+#: lvconvert.c:57
+#, c-format
+msgid "Logical volume %s already has %u mirror(s)."
+msgstr ""
+
+#: lvconvert.c:68 lvconvert.c:82
+msgid "Adding mirror images is not supported yet."
+msgstr ""
+
+#: lvconvert.c:107
+#, c-format
+msgid "Updating \"%s\" in kernel"
+msgstr ""
+
+#: lvconvert.c:114
+#, c-format
+msgid "Logical volume %s converted."
+msgstr ""
+
+#: lvconvert.c:125
+#, c-format
+msgid "Cannot convert locked LV %s"
+msgstr ""
+
+#: lvconvert.c:130
+#, c-format
+msgid "Can't convert logical volume \"%s\" under snapshot"
+msgstr ""
+
+#: lvconvert.c:136
+#, c-format
+msgid "Can't convert snapshot logical volume \"%s\""
+msgstr ""
+
+#: lvconvert.c:142
+#, c-format
+msgid "Unable to convert pvmove LV %s"
+msgstr ""
+
+#: lvconvert.c:167
+msgid "--mirrors argument required"
+msgstr ""
+
+#: lvconvert.c:182 lvrename.c:54
+msgid "Please provide a valid volume group name"
+msgstr ""
+
+#: lvconvert.c:189 lvrename.c:102 vgrename.c:65
+#, c-format
+msgid "Checking for existing volume group \"%s\""
+msgstr ""
+
+#: lvconvert.c:192 lvcreate.c:851 lvrename.c:105 lvresize.c:566 pvchange.c:59
+#: pvmove.c:61 vgcreate.c:144 vgextend.c:47 vgmerge.c:33 vgmerge.c:57
+#: vgreduce.c:265 vgrename.c:68 vgrename.c:102 vgsplit.c:189 vgsplit.c:213
+#, c-format
+msgid "Can't get lock for %s"
+msgstr ""
+
+#: lvconvert.c:197 lvcreate.c:480 lvrename.c:110 pvmove.c:66 vgdisplay.c:24
+#: vgmerge.c:38 vgmerge.c:64 vgreduce.c:271 vgrename.c:73 vgsplit.c:194
+#, c-format
+msgid "Volume group \"%s\" doesn't exist"
+msgstr ""
+
+#: lvconvert.c:202 lvcreate.c:485 lvrename.c:115 metadata/metadata.c:1135
+#: polldaemon.c:200 pvchange.c:72 pvmove.c:72 toollib.c:42 vgchange.c:415
+#: vgck.c:32 vgconvert.c:54 vgextend.c:57 vgmerge.c:44 vgmerge.c:69
+#: vgreduce.c:321 vgremove.c:35 vgrename.c:80 vgsplit.c:200
+#, c-format
+msgid "Volume group \"%s\" is exported"
+msgstr ""
+
+#: lvconvert.c:207 lvcreate.c:490 lvremove.c:27 lvrename.c:120 pvchange.c:78
+#: pvmove.c:78 vgchange.c:410 vgconvert.c:49 vgexport.c:38 vgextend.c:62
+#: vgmerge.c:50 vgmerge.c:74 vgreduce.c:327 vgrename.c:86 vgsplit.c:206
+#, c-format
+msgid "Volume group \"%s\" is read-only"
+msgstr ""
+
+#: lvconvert.c:212
+#, c-format
+msgid "Logical volume \"%s\" not found in volume group \"%s\""
+msgstr ""
+
+#: lvcreate.c:65
msgid "Please specify a logical volume to act as the snapshot origin."
msgstr ""
-#: lvcreate.c:71
+#: lvcreate.c:73
msgid "The origin name should include the volume group."
msgstr ""
-#: lvcreate.c:87 lvresize.c:101
+#: lvcreate.c:89 lvresize.c:102
msgid "Please provide a volume group name"
msgstr ""
-#: lvcreate.c:106
+#: lvcreate.c:108
msgid "Volume group name expected (no slash)"
msgstr ""
-#: lvcreate.c:121
+#: lvcreate.c:123
#, c-format
msgid "Inconsistent volume group names given: \"%s\" and \"%s\""
msgstr ""
-#: lvcreate.c:140 lvrename.c:88
-msgid ""
-"Names starting \"snapshot\" are reserved. Please choose a different LV name."
-msgstr ""
-
#: lvcreate.c:146
#, c-format
msgid "Logical volume name \"%s\" is invalid"
msgstr ""
-#: lvcreate.c:159 lvresize.c:63
+#: lvcreate.c:159 lvresize.c:64
msgid "Please specify either size or extents (not both)"
msgstr ""
@@ -3329,7 +3562,7 @@
msgid "Ignoring stripesize argument with single stripe"
msgstr ""
-#: lvcreate.c:206 lvresize.c:279
+#: lvcreate.c:206 lvresize.c:287
#, c-format
msgid "Using default stripesize %dKB"
msgstr ""
@@ -3349,215 +3582,246 @@
msgid "Invalid stripe size %d"
msgstr ""
-#: lvcreate.c:247
+#: lvcreate.c:238
+#, c-format
+msgid "Too few physical volumes on command line for %d-way mirroring"
+msgstr ""
+
+#: lvcreate.c:245
+msgid "Negative regionsize is invalid"
+msgstr ""
+
+#: lvcreate.c:255
+#, c-format
+msgid "Region size (%u) must be a power of 2"
+msgstr ""
+
+#: lvcreate.c:279
msgid "Redundant stripes argument: default is 1"
msgstr ""
-#: lvcreate.c:254
+#: lvcreate.c:293
+msgid "Redundant mirrors argument: default is 0"
+msgstr ""
+
+#: lvcreate.c:298
msgid "-Z is incompatible with snapshots"
msgstr ""
-#: lvcreate.c:258
+#: lvcreate.c:302
msgid "Negative chunk size is invalid"
msgstr ""
-#: lvcreate.c:262
+#: lvcreate.c:306
#, c-format
msgid "Setting chunksize to %d sectors."
msgstr ""
-#: lvcreate.c:270
+#: lvcreate.c:314
msgid "-c is only available with snapshots"
msgstr ""
-#: lvcreate.c:277 metadata/mirror.c:54
+#: lvcreate.c:321
+msgid "mirrors and snapshots are currently incompatible"
+msgstr ""
+
+#: lvcreate.c:327
+msgid "mirrors and stripes are currently incompatible"
+msgstr ""
+
+#: lvcreate.c:340 metadata/mirror.c:190
#, c-format
msgid "%s: Required device-mapper target(s) not detected in your kernel"
msgstr ""
-#: lvcreate.c:302
+#: lvcreate.c:368
msgid "Conflicting contiguous and alloc arguments"
msgstr ""
-#: lvcreate.c:327
+#: lvcreate.c:393
msgid "Please specify minor number with --minor when using -My"
msgstr ""
-#: lvcreate.c:332
+#: lvcreate.c:398
msgid "Please specify major number with --major when using -My"
msgstr ""
-#: lvcreate.c:338
+#: lvcreate.c:404
msgid "--major and --minor incompatible with -Mn"
msgstr ""
-#: lvcreate.c:367
+#: lvcreate.c:433
msgid "Name allocation failed - device not zeroed"
msgstr ""
-#: lvcreate.c:373
+#: lvcreate.c:439
#, c-format
msgid "Name too long - device not zeroed (%s)"
msgstr ""
-#: lvcreate.c:377
+#: lvcreate.c:443
#, c-format
msgid "Zeroing start of logical volume \"%s\""
msgstr ""
-#: lvcreate.c:380
+#: lvcreate.c:446
#, c-format
msgid "%s: not found: device not zeroed"
msgstr ""
-#: lvcreate.c:407 pvmove.c:291 toollib.c:325 vgreduce.c:258
+#: lvcreate.c:477 pvmove.c:292 toollib.c:350 vgreduce.c:263
#, c-format
msgid "Finding volume group \"%s\""
msgstr ""
-#: lvcreate.c:410 lvrename.c:112 pvmove.c:66 vgdisplay.c:24 vgmerge.c:38
-#: vgmerge.c:64 vgreduce.c:266 vgrename.c:73 vgsplit.c:178
+#: lvcreate.c:495 lvrename.c:125
#, c-format
-msgid "Volume group \"%s\" doesn't exist"
-msgstr ""
-
-#: lvcreate.c:415 lvrename.c:117 metadata/metadata.c:812 polldaemon.c:192
-#: pvchange.c:69 pvmove.c:72 toollib.c:42 vgchange.c:312 vgck.c:32
-#: vgconvert.c:54 vgextend.c:57 vgmerge.c:44 vgmerge.c:69 vgreduce.c:316
-#: vgremove.c:35 vgrename.c:80 vgsplit.c:184
-#, c-format
-msgid "Volume group \"%s\" is exported"
-msgstr ""
-
-#: lvcreate.c:420 lvremove.c:27 lvrename.c:122 pvchange.c:75 pvmove.c:78
-#: vgchange.c:307 vgconvert.c:49 vgexport.c:38 vgextend.c:62 vgmerge.c:50
-#: vgmerge.c:74 vgreduce.c:322 vgrename.c:86 vgsplit.c:190
-#, c-format
-msgid "Volume group \"%s\" is read-only"
+msgid "Logical volume \"%s\" already exists in volume group \"%s\""
msgstr ""
-#: lvcreate.c:425 lvrename.c:127
-#, c-format
-msgid "Logical volume \"%s\" already exists in volume group \"%s\""
+#: lvcreate.c:501
+msgid "Metadata does not support mirroring."
msgstr ""
-#: lvcreate.c:443
+#: lvcreate.c:518
#, c-format
msgid "Setting stripe size %d KB to physical extent size %u KB"
msgstr ""
-#: lvcreate.c:456 lvresize.c:198
+#: lvcreate.c:531 lvresize.c:206
#, c-format
msgid "Rounding up size to full physical extent %s"
msgstr ""
-#: lvcreate.c:464
+#: lvcreate.c:539
#, c-format
msgid "Rounding size (%d extents) up to stripe boundary size (%d extents)"
msgstr ""
-#: lvcreate.c:472
+#: lvcreate.c:547
msgid "Can't create snapshot without using device-mapper kernel driver"
msgstr ""
-#: lvcreate.c:477
+#: lvcreate.c:552
#, c-format
msgid "Couldn't find origin volume '%s'."
msgstr ""
-#: lvcreate.c:482
+#: lvcreate.c:557
msgid "Snapshots of snapshots are not supported yet."
msgstr ""
-#: lvcreate.c:487
+#: lvcreate.c:562
msgid "Snapshots of locked devices are not supported yet"
msgstr ""
-#: lvcreate.c:496
+#: lvcreate.c:571
#, c-format
msgid "Unable to create logical volume %s with no extents"
msgstr ""
-#: lvcreate.c:503
+#: lvcreate.c:578
#, c-format
msgid "Insufficient free extents (%u) in volume group %s: %u required"
msgstr ""
-#: lvcreate.c:509
+#: lvcreate.c:584
#, c-format
msgid "Number of stripes (%u) must not exceed number of physical volumes (%d)"
msgstr ""
-#: lvcreate.c:528
-msgid "Setting read ahead sectors"
+#: lvcreate.c:591
+msgid "Can't create mirror without using device-mapper kernel driver."
msgstr ""
-#: lvcreate.c:536
-#, c-format
+#: lvcreate.c:610
+msgid "Failed to generate LV name."
+msgstr ""
+
+#: lvcreate.c:622 mirror/mirrored.c:218
+#, c-format
+msgid "Using reduced mirror region size of %u sectors"
+msgstr ""
+
+#: lvcreate.c:630 lvcreate.c:636 lvcreate.c:644
+msgid "log_name allocation failed. Remove new LV and retry."
+msgstr ""
+
+#: lvcreate.c:683
+msgid "Aborting. Failed to activate mirror log. Remove new LVs and retry."
+msgstr ""
+
+#: lvcreate.c:689
+msgid "Aborting. Failed to wipe mirror log. Remove new LV and retry."
+msgstr ""
+
+#: lvcreate.c:695
+msgid "Aborting. Failed to deactivate mirror log. Remove new LV and retry."
+msgstr ""
+
+#: lvcreate.c:710
+msgid "Setting read ahead sectors"
+msgstr ""
+
+#: lvcreate.c:718
+#, c-format
msgid "Setting device number to (%d, %d)"
msgstr ""
-#: lvcreate.c:547 vgchange.c:224
+#: lvcreate.c:729 vgchange.c:327
#, c-format
msgid "Volume group %s does not support tags"
msgstr ""
-#: lvcreate.c:578
+#: lvcreate.c:773
msgid ""
"Aborting. Failed to activate snapshot exception store. Remove new LV and "
"retry."
msgstr ""
-#: lvcreate.c:581
+#: lvcreate.c:776
msgid "Failed to activate new LV."
msgstr ""
-#: lvcreate.c:588
+#: lvcreate.c:783
msgid ""
"Aborting. Failed to wipe snapshot exception store. Remove new LV and retry."
msgstr ""
-#: lvcreate.c:593
+#: lvcreate.c:788
#, c-format
msgid "WARNING: \"%s\" not zeroed"
msgstr ""
-#: lvcreate.c:602
+#: lvcreate.c:797
msgid "Couldn't deactivate new snapshot."
msgstr ""
-#: lvcreate.c:608
+#: lvcreate.c:803
#, c-format
msgid "Failed to suspend origin %s"
msgstr ""
-#: lvcreate.c:614
+#: lvcreate.c:809
msgid "Couldn't create snapshot."
msgstr ""
-#: lvcreate.c:623
+#: lvcreate.c:818
#, c-format
msgid "Problem reactivating origin %s"
msgstr ""
-#: lvcreate.c:630
+#: lvcreate.c:825
#, c-format
msgid "Logical volume \"%s\" created"
msgstr ""
-#: lvcreate.c:651 lvrename.c:107 lvresize.c:509 pvchange.c:56 pvmove.c:61
-#: vgcreate.c:139 vgextend.c:47 vgmerge.c:33 vgmerge.c:57 vgreduce.c:260
-#: vgrename.c:68 vgrename.c:102 vgsplit.c:173 vgsplit.c:197
-#, c-format
-msgid "Can't get lock for %s"
-msgstr ""
-
-#: lvdisplay.c:36 lvdisplay.c:45 pvdisplay.c:62 pvdisplay.c:71 vgdisplay.c:65
-#: vgdisplay.c:74
+#: lvdisplay.c:39 lvdisplay.c:48 pvdisplay.c:62 pvdisplay.c:72 vgdisplay.c:67
+#: vgdisplay.c:76
msgid "Incompatible options selected"
msgstr ""
-#: lvdisplay.c:50
+#: lvdisplay.c:53
msgid "Options -v and -c are incompatible"
msgstr ""
@@ -3644,109 +3908,91 @@
msgid "%-16.16s%s"
msgstr ""
-#: lvmcmdline.c:798
+#: lvmcmdline.c:799
msgid "Couldn't copy command line."
msgstr ""
-#: lvmcmdline.c:811
+#: lvmcmdline.c:812
#, c-format
msgid "Parsing: %s"
msgstr ""
-#: lvmcmdline.c:817
+#: lvmcmdline.c:818
msgid "Error during parsing of command line."
msgstr ""
-#: lvmcmdline.c:826
+#: lvmcmdline.c:827
msgid "Updated config file invalid. Aborting."
msgstr ""
-#: lvmcmdline.c:835
+#: lvmcmdline.c:836
#, c-format
msgid "Processing: %s"
msgstr ""
-#: lvmcmdline.c:838
+#: lvmcmdline.c:839
msgid "O_DIRECT will be used"
msgstr ""
-#: lvmcmdline.c:851
+#: lvmcmdline.c:852
#, c-format
msgid "Locking type %d initialisation failed."
msgstr ""
-#: lvmcmdline.c:863
+#: lvmcmdline.c:864
msgid "Test mode: Wiping internal cache"
msgstr ""
-#: lvmcmdline.c:921
-msgid "WARNING: Metadata changes will NOT be backed up"
-msgstr ""
-
-#: lvmcmdline.c:941
-#, c-format
-msgid "Couldn't create default archive path '%s/%s'."
-msgstr ""
-
-#: lvmcmdline.c:950 lvmcmdline.c:970
-msgid "backup_init failed."
-msgstr ""
-
-#: lvmcmdline.c:962
-#, c-format
-msgid "Couldn't create default backup path '%s/%s'."
-msgstr ""
-
-#: lvmcmdline.c:1058
+#: lvmcmdline.c:994
#, c-format
msgid "Line too long (max 255) beginning: %s"
msgstr ""
-#: lvmcmdline.c:1065
+#: lvmcmdline.c:1001
#, c-format
msgid "Too many arguments: %s"
msgstr ""
-#: lvmcmdline.c:1197
+#: lvmcmdline.c:1133
msgid "$HOME/.lvm_history: path too long"
msgstr ""
-#: lvmcmdline.c:1212
+#: lvmcmdline.c:1148
#, c-format
msgid "Couldn't read history from %s."
msgstr ""
-#: lvmcmdline.c:1227
+#: lvmcmdline.c:1163
#, c-format
msgid "Couldn't write history to %s."
msgstr ""
-#: lvmcmdline.c:1260
+#: lvmcmdline.c:1196
msgid "Too many arguments, sorry."
msgstr ""
-#: lvmcmdline.c:1274
+#: lvmcmdline.c:1210
msgid "Exiting."
msgstr ""
-#: lvmcmdline.c:1280
+#: lvmcmdline.c:1216
#, c-format
msgid "No such command '%s'. Try 'help'."
msgstr ""
-#: lvmcmdline.c:1406
+#: lvmcmdline.c:1342
msgid "Failed to create LVM1 tool pathname"
msgstr ""
-#: lvmcmdline.c:1443
+#: lvmcmdline.c:1390
msgid "Falling back to LVM1 tools, but no command specified."
msgstr ""
-#: lvmcmdline.c:1459
+#: lvmcmdline.c:1406
msgid "Please supply an LVM command."
msgstr ""
-#: lvmcmdline.c:1473
+#: lvmcmdline.c:1420
msgid "No such command. Try 'help'."
msgstr ""
@@ -3800,45 +4046,55 @@
#: lvremove.c:38
#, c-format
+msgid "Can't remove logical volume %s used by a mirror"
+msgstr ""
+
+#: lvremove.c:44
+#, c-format
+msgid "Can't remove logical volume %s used as mirror log"
+msgstr ""
+
+#: lvremove.c:50
+#, c-format
msgid "Can't remove locked LV %s"
msgstr ""
-#: lvremove.c:46
+#: lvremove.c:58
#, c-format
msgid "Can't remove open logical volume \"%s\""
msgstr ""
-#: lvremove.c:55
+#: lvremove.c:67
#, c-format
msgid "Logical volume \"%s\" not removed"
msgstr ""
-#: lvremove.c:66
+#: lvremove.c:78
#, c-format
msgid "Unable to deactivate logical volume \"%s\""
msgstr ""
-#: lvremove.c:72
+#: lvremove.c:84
#, c-format
msgid "Removing snapshot %s"
msgstr ""
-#: lvremove.c:79
+#: lvremove.c:91
#, c-format
msgid "Releasing logical volume \"%s\""
msgstr ""
-#: lvremove.c:81
+#: lvremove.c:93
#, c-format
msgid "Error releasing logical volume \"%s\""
msgstr ""
-#: lvremove.c:94
+#: lvremove.c:106
#, c-format
msgid "Logical volume \"%s\" successfully removed"
msgstr ""
-#: lvremove.c:101
+#: lvremove.c:113
msgid "Please enter one or more logical volume paths"
msgstr ""
@@ -3851,10 +4107,6 @@
msgid "Old and new logical volume names required"
msgstr ""
-#: lvrename.c:54
-msgid "Please provide a valid volume group name"
-msgstr ""
-
#: lvrename.c:61
#, c-format
msgid "Logical volume names must have the same volume group (\"%s\" or \"%s\")"
@@ -3862,203 +4114,224 @@
#: lvrename.c:76
#, c-format
-msgid "New logical volume path exceeds maximum length of %Zu!"
+msgid "New logical volume path exceeds maximum length of %zu!"
msgstr ""
#: lvrename.c:82
msgid "New logical volume name may not be blank"
msgstr ""
-#: lvrename.c:94
+#: lvrename.c:92
#, c-format
msgid "New logical volume name \"%s\" is invalid"
msgstr ""
-#: lvrename.c:100
+#: lvrename.c:98
msgid "Old and new logical volume names must differ"
msgstr ""
-#: lvrename.c:104 vgrename.c:65
-#, c-format
-msgid "Checking for existing volume group \"%s\""
-msgstr ""
-
-#: lvrename.c:133
+#: lvrename.c:131
#, c-format
msgid "Existing logical volume \"%s\" not found in volume group \"%s\""
msgstr ""
-#: lvrename.c:141
+#: lvrename.c:139
#, c-format
msgid "Cannot rename locked LV %s"
msgstr ""
-#: lvrename.c:151
+#: lvrename.c:149
msgid "Failed to allocate space for new name"
msgstr ""
-#: lvrename.c:155 vgmerge.c:163 vgrename.c:134
+#: lvrename.c:153 vgmerge.c:190 vgrename.c:134
msgid "Writing out updated volume group"
msgstr ""
-#: lvrename.c:178
+#: lvrename.c:176
#, c-format
msgid "Renamed \"%s\" to \"%s\" in volume group \"%s\""
msgstr ""
-#: lvresize.c:79
+#: lvresize.c:80
msgid "Negative argument not permitted - use lvreduce"
msgstr ""
-#: lvresize.c:84
+#: lvresize.c:85
msgid "Positive sign not permitted - use lvextend"
msgstr ""
-#: lvresize.c:92
+#: lvresize.c:93
msgid "Please provide the logical volume name"
msgstr ""
-#: lvresize.c:136
+#: lvresize.c:138
#, c-format
msgid "Volume group %s doesn't exist"
msgstr ""
-#: lvresize.c:141
+#: lvresize.c:143
#, c-format
msgid "Volume group %s is exported"
msgstr ""
-#: lvresize.c:146
+#: lvresize.c:148
#, c-format
msgid "Volume group %s is read-only"
msgstr ""
-#: lvresize.c:152
+#: lvresize.c:154
#, c-format
msgid "Logical volume %s not found in volume group %s"
msgstr ""
-#: lvresize.c:161
+#: lvresize.c:163
msgid "Varied striping not supported. Ignoring."
msgstr ""
-#: lvresize.c:166
+#: lvresize.c:170
+msgid "Mirrors not supported. Ignoring."
+msgstr ""
+
+#: lvresize.c:175
msgid "Stripesize may not be negative."
msgstr ""
-#: lvresize.c:173
+#: lvresize.c:182
msgid "Varied stripesize not supported. Ignoring."
msgstr ""
-#: lvresize.c:179
-#, c-format
-msgid "Can't resize locked LV %s"
+#: lvresize.c:184
+msgid "Mirrors and striping cannot be combined yet."
msgstr ""
-#: lvresize.c:184
-msgid "Snapshot origin volumes cannot be resized yet."
+#: lvresize.c:192
+#, c-format
+msgid "Can't resize locked LV %s"
msgstr ""
-#: lvresize.c:211
+#: lvresize.c:219
#, c-format
msgid "Unable to reduce %s below 1 extent"
msgstr ""
-#: lvresize.c:220
+#: lvresize.c:228
msgid "New size of 0 not permitted"
msgstr ""
-#: lvresize.c:225 lvresize.c:330
+#: lvresize.c:233 lvresize.c:365
#, c-format
msgid "New size (%d extents) matches existing size (%d extents)"
msgstr ""
-#: lvresize.c:240
+#: lvresize.c:248
#, c-format
msgid "VolumeType does not match (%s)"
msgstr ""
-#: lvresize.c:257
+#: lvresize.c:265
msgid "Please specify number of stripes (-i) and stripesize (-I)"
msgstr ""
-#: lvresize.c:271
+#: lvresize.c:279
#, c-format
msgid "Using stripesize of last segment %dKB"
msgstr ""
-#: lvresize.c:290
-msgid "Ignoring stripes and stripesize arguments when reducing"
+#: lvresize.c:303
+#, c-format
+msgid "Extending %u mirror images."
msgstr ""
-#: lvresize.c:313
+#: lvresize.c:309
+msgid "Cannot vary number of mirrors in LV yet."
+msgstr ""
+
+#: lvresize.c:319
+msgid "Ignoring stripes, stripesize and mirrors arguments when reducing"
+msgstr ""
+
+#: lvresize.c:348
msgid "Stripesize for striped segment should not be 0!"
msgstr ""
-#: lvresize.c:322
+#: lvresize.c:357
#, c-format
msgid ""
"Rounding size (%d extents) down to stripe boundary size for segment (%d "
"extents)"
msgstr ""
-#: lvresize.c:337
+#: lvresize.c:372
#, c-format
msgid "New size given (%d extents) not larger than existing size (%d extents)"
msgstr ""
-#: lvresize.c:347
+#: lvresize.c:382
#, c-format
msgid "New size given (%d extents) not less than existing size (%d extents)"
msgstr ""
-#: lvresize.c:357
+#: lvresize.c:392
+msgid "Mirrors cannot be resized while active yet."
+msgstr ""
+
+#: lvresize.c:398
+msgid "Snapshot origin volumes cannot be reduced in size yet."
+msgstr ""
+
+#: lvresize.c:406
+msgid ""
+"Snapshot origin volumes can be resized only while inactive: try lvchange -an"
+msgstr ""
+
+#: lvresize.c:414
msgid "Ignoring PVs on command line when reducing"
msgstr ""
-#: lvresize.c:368
+#: lvresize.c:425
msgid "lv_info failed: aborting"
msgstr ""
-#: lvresize.c:373
+#: lvresize.c:430
#, c-format
msgid "Logical volume %s must be activated before resizing filesystem"
msgstr ""
-#: lvresize.c:379
+#: lvresize.c:436
#, c-format
msgid "WARNING: Reducing active%s logical volume to %s"
msgstr ""
-#: lvresize.c:385
+#: lvresize.c:442
msgid "THIS MAY DESTROY YOUR DATA (filesystem etc.)"
msgstr ""
-#: lvresize.c:392
+#: lvresize.c:449
#, c-format
msgid "Logical volume %s NOT reduced"
msgstr ""
-#: lvresize.c:403
+#: lvresize.c:460
#, c-format
msgid "Couldn't create LV path for %s"
msgstr ""
-#: lvresize.c:411
+#: lvresize.c:468
msgid "Couldn't generate new LV size string"
msgstr ""
-#: lvresize.c:435
+#: lvresize.c:492
#, c-format
msgid "%sing logical volume %s to %s"
msgstr ""
-#: lvresize.c:485
+#: lvresize.c:542
#, c-format
msgid "Logical volume %s successfully resized"
msgstr ""
-#: lvresize.c:507
+#: lvresize.c:564
#, c-format
msgid "Finding volume group %s"
msgstr ""
@@ -4072,514 +4345,718 @@
msgid "No additional command line arguments allowed"
msgstr ""
-#: metadata/lv_manip.c:102
-msgid "Couldn't allocate new parallel segment."
+#: metadata/lv_manip.c:78
+msgid "alloc_lv_segment: Missing segtype."
msgstr ""
-#: metadata/lv_manip.c:159
-msgid "striped mirrors are not supported yet"
+#: metadata/lv_manip.c:110
+msgid "Failed to find snapshot segtype"
msgstr ""
-#: metadata/lv_manip.c:174
-msgid "Couldn't allocate areas array."
+#: metadata/lv_manip.c:118
+msgid "Couldn't allocate new snapshot segment."
msgstr ""
-#: metadata/lv_manip.c:191
+#: metadata/lv_manip.c:169
#, c-format
-msgid ""
-"Insufficient allocatable extents suitable for parallel use for logical "
-"volume %s: %u required"
+msgid "Segment extent reduction %unot divisible by #stripes %u"
msgstr ""
-#: metadata/lv_manip.c:231
-msgid "Couldn't allocate new stripe segment."
+#: metadata/lv_manip.c:303
+msgid "Striped mirrors are not supported yet"
msgstr ""
-#: metadata/lv_manip.c:270
-msgid "Couldn't allocate new mirrored segment."
+#: metadata/lv_manip.c:308
+msgid "Can't mix striping or mirroring with creation of a mirrored PV yet"
msgstr ""
-#: metadata/lv_manip.c:332
-#, c-format
-msgid ""
-"Insufficient allocatable extents (%u) for logical volume %s: %u required"
+#: metadata/lv_manip.c:314
+msgid "Can't mix striping or pvmove with a mirror log yet."
msgstr ""
-#: metadata/lv_manip.c:377
-#, c-format
-msgid ""
-"Insufficient contiguous allocatable extents (%u) for logical volume %s: %u "
-"required"
+#: metadata/lv_manip.c:329
+msgid "allocation handle allocation failed"
+msgstr ""
+
+#: metadata/lv_manip.c:337
+msgid "allocation pool creation failed"
+msgstr ""
+
+#: metadata/lv_manip.c:384
+msgid "Couldn't allocate new LV segment."
+msgstr ""
+
+#: metadata/lv_manip.c:466
+msgid "alloced_area allocation failed"
+msgstr ""
+
+#: metadata/lv_manip.c:678
+msgid "_allocate called with no work to do!"
msgstr ""
-#: metadata/lv_manip.c:410
+#: metadata/lv_manip.c:699
+msgid "Not enough PVs with free space available for parallel allocation."
+msgstr ""
+
+#: metadata/lv_manip.c:701
+msgid "Consider --alloc anywhere if desperate."
+msgstr ""
+
+#: metadata/lv_manip.c:709
+msgid "Couldn't allocate areas array."
+msgstr ""
+
+#: metadata/lv_manip.c:746
#, c-format
msgid ""
-"Insufficient allocatable logical extents (%u) for logical volume %s: %u "
+"Insufficient suitable %sallocatable extents for logical volume %s: %u more "
"required"
msgstr ""
-#: metadata/lv_manip.c:425
+#: metadata/lv_manip.c:770
msgid "Couldn't allocate new zero segment."
msgstr ""
-#: metadata/lv_manip.c:490
-msgid "Unrecognised allocation policy: unable to set up logical volume."
+#: metadata/lv_manip.c:802
+msgid "allocate_extents does not handle virtual segments"
+msgstr ""
+
+#: metadata/lv_manip.c:808
+#, c-format
+msgid "Metadata format (%s) does not support required LV segment type (%s)."
+msgstr ""
+
+#: metadata/lv_manip.c:811
+msgid "Consider changing the metadata format by running vgconvert."
+msgstr ""
+
+#: metadata/lv_manip.c:852
+msgid "Missing segtype in lv_add_segment()."
+msgstr ""
+
+#: metadata/lv_manip.c:857
+msgid "lv_add_segment cannot handle virtual segments"
+msgstr ""
+
+#: metadata/lv_manip.c:871
+msgid "Couldn't merge segments after extending logical volume."
+msgstr ""
+
+#: metadata/lv_manip.c:893
+msgid "Log segments can only be added to an empty LV"
+msgstr ""
+
+#: metadata/lv_manip.c:902
+msgid "Couldn't allocate new mirror log segment."
+msgstr ""
+
+#: metadata/lv_manip.c:942
+#, c-format
+msgid "Log LV %s is empty."
+msgstr ""
+
+#: metadata/lv_manip.c:952
+msgid "Couldn't allocate new mirror segment."
msgstr ""
-#: metadata/lv_manip.c:556
+#: metadata/lv_manip.c:1013
+#, c-format
+msgid "Aborting. Failed to extend %s."
+msgstr ""
+
+#: metadata/lv_manip.c:1066
#, c-format
msgid "Maximum number of logical volumes (%u) reached in volume group %s"
msgstr ""
-#: metadata/lv_manip.c:563
+#: metadata/lv_manip.c:1073
msgid "Failed to generate unique name for the new logical volume"
msgstr ""
-#: metadata/lv_manip.c:568
+#: metadata/lv_manip.c:1079
#, c-format
msgid "Creating logical volume %s"
msgstr ""
-#: metadata/lv_manip.c:572
+#: metadata/lv_manip.c:1083
msgid "lv_list allocation failed"
msgstr ""
-#: metadata/lv_manip.c:582
+#: metadata/lv_manip.c:1093
msgid "lv name strdup failed"
msgstr ""
-#: metadata/lv_manip.c:628
+#: metadata/merge.c:72
#, c-format
-msgid "Metadata format (%s) does not support required LV segment type (%s)."
+msgid "LV %s invalid: segment %u should begin at LE %u (found %u)."
msgstr ""
-#: metadata/lv_manip.c:631
-msgid "Consider changing the metadata format by running vgconvert."
+#: metadata/merge.c:82
+#, c-format
+msgid "LV %s: segment %u has inconsistent area_len %u"
msgstr ""
-#: metadata/lv_manip.c:646
-msgid "Couldn't merge segments after extending logical volume."
+#: metadata/merge.c:93
+#, c-format
+msgid "LV %s: segment %u has inconsistent PV area %u"
msgstr ""
-#: metadata/lv_manip.c:683
+#: metadata/merge.c:102
#, c-format
-msgid "Segment extent reduction %unot divisible by #stripes %u"
+msgid "LV %s: segment %u has inconsistent LV area %u"
msgstr ""
-#: metadata/merge.c:69
+#: metadata/merge.c:108
#, c-format
-msgid "LV %s invalid: segment %u should begin at LE %u (found %u)."
+msgid "LV %s: segment %u has inconsistent LV area %u size"
msgstr ""
-#: metadata/merge.c:95
+#: metadata/merge.c:121
+#, c-format
+msgid "LV %s: inconsistent LE count %u != %u"
+msgstr ""
+
+#: metadata/merge.c:142
#, c-format
msgid "Unable to split the %s segment at LE %u in LV %s"
msgstr ""
-#: metadata/merge.c:102
-msgid "Couldn't allocate new LV segment."
+#: metadata/merge.c:155
+msgid "Couldn't allocate cloned LV segment."
msgstr ""
-#: metadata/merge.c:110
+#: metadata/merge.c:160
msgid "LV segment tags duplication failed"
msgstr ""
-#: metadata/merge.c:126
+#: metadata/merge.c:187
#, c-format
msgid "Split %s:%u[%u] at %u: %s LE %u"
msgstr ""
-#: metadata/merge.c:134
+#: metadata/merge.c:202
#, c-format
msgid "Split %s:%u[%u] at %u: %s PE %u"
msgstr ""
-#: metadata/merge.c:141
+#: metadata/merge.c:209 metadata/metadata.c:469
#, c-format
msgid "Unrecognised segment type %u"
msgstr ""
-#: metadata/merge.c:169
+#: metadata/merge.c:229
#, c-format
msgid "Segment with extent %u in LV %s not found"
msgstr ""
-#: metadata/metadata.c:33
+#: metadata/metadata.c:35
#, c-format
msgid "Adding physical volume '%s' to volume group '%s'"
msgstr ""
-#: metadata/metadata.c:37
+#: metadata/metadata.c:39
#, c-format
msgid "pv_list allocation for '%s' failed"
msgstr ""
-#: metadata/metadata.c:43
+#: metadata/metadata.c:45
#, c-format
msgid "%s not identified as an existing physical volume"
msgstr ""
-#: metadata/metadata.c:49
+#: metadata/metadata.c:51
#, c-format
msgid "Physical volume '%s' is already in volume group '%s'"
msgstr ""
-#: metadata/metadata.c:55
+#: metadata/metadata.c:57
#, c-format
msgid "Physical volume %s is of different format type (%s)"
msgstr ""
-#: metadata/metadata.c:61 metadata/metadata.c:120
+#: metadata/metadata.c:63 metadata/metadata.c:175
#, c-format
msgid "vg->name allocation failed for '%s'"
msgstr ""
-#: metadata/metadata.c:84
+#: metadata/metadata.c:86
#, c-format
msgid "Format-specific setup of physical volume '%s' failed."
msgstr ""
-#: metadata/metadata.c:90
+#: metadata/metadata.c:92
#, c-format
msgid "Physical volume '%s' listed more than once."
msgstr ""
-#: metadata/metadata.c:96
+#: metadata/metadata.c:98
#, c-format
msgid "No space for '%s' - volume group '%s' holds max %d physical volume(s)."
msgstr ""
-#: metadata/metadata.c:127
+#: metadata/metadata.c:125
+msgid "PV tags duplication failed"
+msgstr ""
+
+#: metadata/metadata.c:146
+#, c-format
+msgid "get_pv_from_vg_by_id: vg_read failed to read VG %s"
+msgstr ""
+
+#: metadata/metadata.c:152
+#, c-format
+msgid "Warning: Volume group %s is not consistent"
+msgstr ""
+
+#: metadata/metadata.c:181
#, c-format
msgid "pv->vg_name allocation failed for '%s'"
msgstr ""
-#: metadata/metadata.c:144
+#: metadata/metadata.c:198
#, c-format
msgid "Unable to add physical volume '%s' to volume group '%s'."
msgstr ""
-#: metadata/metadata.c:182
+#: metadata/metadata.c:236
#, c-format
msgid "A volume group called '%s' already exists."
msgstr ""
-#: metadata/metadata.c:188
+#: metadata/metadata.c:242
#, c-format
msgid "Couldn't create uuid for volume group '%s'."
msgstr ""
-#: metadata/metadata.c:230 metadata/metadata.c:667
+#: metadata/metadata.c:283 metadata/metadata.c:923 metadata/metadata.c:966
msgid "Failed to create format instance"
msgstr ""
-#: metadata/metadata.c:236
+#: metadata/metadata.c:289
#, c-format
msgid "Format specific setup of volume group '%s' failed."
msgstr ""
-#: metadata/metadata.c:273
+#: metadata/metadata.c:312
+#, c-format
+msgid "New size %llu for %s%s not an exact number of new extents."
+msgstr ""
+
+#: metadata/metadata.c:320
+#, c-format
+msgid "New extent count %llu for %s%s exceeds 32 bits."
+msgstr ""
+
+#: metadata/metadata.c:502
#, c-format
msgid "Failed to create random uuid for %s."
msgstr ""
-#: metadata/metadata.c:288
+#: metadata/metadata.c:517 vgreduce.c:196 vgremove.c:62
#, c-format
msgid "%s: Couldn't get size."
msgstr ""
-#: metadata/metadata.c:294
+#: metadata/metadata.c:523
#, c-format
msgid "WARNING: %s: Overriding real size. You could lose data."
msgstr ""
-#: metadata/metadata.c:296
+#: metadata/metadata.c:525
#, c-format
msgid "%s: Pretending size is %llu sectors."
msgstr ""
-#: metadata/metadata.c:302
+#: metadata/metadata.c:531
#, c-format
msgid "%s: Size must exceed minimum of %ld sectors."
msgstr ""
-#: metadata/metadata.c:319
+#: metadata/metadata.c:549
#, c-format
msgid "%s: Format-specific setup of physical volume failed."
msgstr ""
-#: metadata/metadata.c:433
+#: metadata/metadata.c:647
#, c-format
msgid "Physical volume %s not found"
msgstr ""
-#: metadata/metadata.c:438
+#: metadata/metadata.c:652
#, c-format
msgid "Physical volume %s not in a volume group"
msgstr ""
-#: metadata/metadata.c:489
+#: metadata/metadata.c:711
+#, c-format
+msgid "Internal error: PV segments corrupted in %s."
+msgstr ""
+
+#: metadata/metadata.c:718
+#, c-format
+msgid "Internal error: LV segments corrupted in %s."
+msgstr ""
+
+#: metadata/metadata.c:725
#, c-format
msgid "Cannot change metadata for partial volume group %s"
msgstr ""
-#: metadata/metadata.c:495
+#: metadata/metadata.c:731
msgid "Aborting vg_write: No metadata areas to write to!"
msgstr ""
-#: metadata/metadata.c:505
+#: metadata/metadata.c:740
msgid "Format does not support writing volumegroup metadata areas"
msgstr ""
-#: metadata/metadata.c:596
+#: metadata/metadata.c:843
msgid "vg allocation failed"
msgstr ""
-#: metadata/metadata.c:605
+#: metadata/metadata.c:851
msgid "vg name allocation failed"
msgstr ""
-#: metadata/metadata.c:615
+#: metadata/metadata.c:860
msgid "pv_list allocation failed"
msgstr ""
-#: metadata/metadata.c:705
+#: metadata/metadata.c:890
+msgid "Internal error: vg_read requires vgname with pre-commit."
+msgstr ""
+
+#: metadata/metadata.c:916 metadata/metadata.c:959
+#, c-format
+msgid "Internal error: %s doesn't support pre-commit"
+msgstr ""
+
+#: metadata/metadata.c:1003
+#, c-format
+msgid "Inconsistent pre-commit metadata copies for volume group %s"
+msgstr ""
+
+#: metadata/metadata.c:1014
#, c-format
msgid "Inconsistent metadata copies found for partial volume group %s"
msgstr ""
-#: metadata/metadata.c:711
+#: metadata/metadata.c:1020
#, c-format
msgid "Inconsistent metadata copies found - updating to use version %u"
msgstr ""
-#: metadata/metadata.c:714
+#: metadata/metadata.c:1023
msgid "Automatic metadata correction failed"
msgstr ""
-#: metadata/metadata.c:718
+#: metadata/metadata.c:1027
msgid "Automatic metadata correction commit failed"
msgstr ""
-#: metadata/metadata.c:725
+#: metadata/metadata.c:1034
#, c-format
msgid "WARNING: Interrupted pvmove detected in volume group %s"
msgstr ""
-#: metadata/metadata.c:727
+#: metadata/metadata.c:1036
msgid "Please restore the metadata by running vgcfgrestore."
msgstr ""
-#: metadata/metadata.c:754 metadata/metadata.c:784
+#: metadata/metadata.c:1077 metadata/metadata.c:1107
#, c-format
msgid "Volume group %s metadata is inconsistent"
msgstr ""
-#: metadata/metadata.c:772
+#: metadata/metadata.c:1095
msgid "vg_read_by_vgid: get_vgs failed"
msgstr ""
-#: metadata/metadata.c:804
+#: metadata/metadata.c:1127
#, c-format
msgid "Finding volume group for uuid %s"
msgstr ""
-#: metadata/metadata.c:806
+#: metadata/metadata.c:1129
#, c-format
msgid "Volume group for uuid not found: %s"
msgstr ""
-#: metadata/metadata.c:810
+#: metadata/metadata.c:1133
#, c-format
msgid "Found volume group \"%s\""
msgstr ""
-#: metadata/metadata.c:816
+#: metadata/metadata.c:1139
#, c-format
msgid "Can't find logical volume id %s"
msgstr ""
-#: metadata/metadata.c:840
+#: metadata/metadata.c:1163
#, c-format
msgid "No physical volume label read from %s"
msgstr ""
-#: metadata/metadata.c:850
+#: metadata/metadata.c:1173
#, c-format
msgid "pv allocation for '%s' failed"
msgstr ""
-#: metadata/metadata.c:858
+#: metadata/metadata.c:1182
#, c-format
msgid "Failed to read existing physical volume '%s'"
msgstr ""
-#: metadata/metadata.c:889
+#: metadata/metadata.c:1219
msgid "PV list allocation failed"
msgstr ""
-#: metadata/metadata.c:897
+#: metadata/metadata.c:1227
msgid "get_pvs: get_vgs failed"
msgstr ""
-#: metadata/metadata.c:917
+#: metadata/metadata.c:1247
#, c-format
msgid "Warning: Volume Group %s is not consistent"
msgstr ""
-#: metadata/metadata.c:935
+#: metadata/metadata.c:1265
msgid "Format does not support writing physical volumes"
msgstr ""
-#: metadata/metadata.c:940
+#: metadata/metadata.c:1270
#, c-format
msgid "Assertion failed: can't _pv_write non-orphan PV (in VG %s)"
msgstr ""
-#: metadata/mirror.c:122
+#: metadata/mirror.c:111
+msgid "img_lvs allocation failed. Remove new LV and retry."
+msgstr ""
+
+#: metadata/mirror.c:118 metadata/mirror.c:124
+msgid "img_name allocation failed. Remove new LV and retry."
+msgstr ""
+
+#: metadata/mirror.c:132
+msgid "Aborting. Failed to create submirror LV. Remove new LV and retry."
+msgstr ""
+
+#: metadata/mirror.c:142
+#, c-format
+msgid ""
+"Aborting. Failed to add submirror segment to %s. Remove new LV and retry."
+msgstr ""
+
+#: metadata/mirror.c:151
+msgid "Aborting. Failed to add mirror segment. Remove new LV and retry."
+msgstr ""
+
+#: metadata/mirror.c:256
#, c-format
msgid "Matched PE range %u-%u against %s %u len %u"
msgstr ""
-#: metadata/mirror.c:130 metadata/mirror.c:364
+#: metadata/mirror.c:265 metadata/mirror.c:491
msgid "lv_list alloc failed"
msgstr ""
-#: metadata/mirror.c:138
+#: metadata/mirror.c:273
#, c-format
msgid "Moving %s:%u-%u of %s/%s"
msgstr ""
-#: metadata/mirror.c:152
+#: metadata/mirror.c:287
msgid "Unable to allocate temporary LV for pvmove."
msgstr ""
-#: metadata/mirror.c:169
+#: metadata/mirror.c:302
#, c-format
msgid "Moving %u extents of logical volume %s/%s"
msgstr ""
-#: metadata/mirror.c:203
+#: metadata/mirror.c:334
msgid "No segment found with LE"
msgstr ""
-#: metadata/mirror.c:215
+#: metadata/mirror.c:345
msgid "Incompatible segments"
msgstr ""
-#: metadata/mirror.c:237
+#: metadata/mirror.c:370
msgid "Missing striped segtype"
msgstr ""
-#: metadata/mirror.c:344
+#: metadata/mirror.c:472
msgid "lvs list alloc failed"
msgstr ""
-#: metadata/pv_map.c:67
+#: metadata/pv_manip.c:31
+msgid "pv_segment allocation failed"
+msgstr ""
+
+#: metadata/pv_manip.c:117
#, c-format
-msgid "Physical extent %d of %s referenced by more than one logical volume"
+msgid "Segment with extent %u in PV %s not found"
msgstr ""
-#: metadata/pv_map.c:87
-msgid "Couldn't create hash table for pv maps."
+#: metadata/pv_manip.c:157
+#, c-format
+msgid "Missing PV segment on %s at %u."
msgstr ""
-#: metadata/pv_map.c:176
+#: metadata/pv_manip.c:223
#, c-format
-msgid "Allowing allocation on %s start PE %u length %u"
+msgid "%s %u: %6u %6u: %s(%u:%u)"
msgstr ""
-#: metadata/pv_map.c:265
+#: metadata/pv_manip.c:229
#, c-format
-msgid "Couldn't create physical volume maps in %s"
+msgid "Gap in pvsegs: %u, %u"
+msgstr ""
+
+#: metadata/pv_manip.c:235
+msgid "Wrong lvseg area type"
+msgstr ""
+
+#: metadata/pv_manip.c:239
+msgid "Inconsistent pvseg pointers"
msgstr ""
-#: metadata/pv_map.c:271
+#: metadata/pv_manip.c:243
#, c-format
-msgid "Couldn't fill extent allocation bitmaps in %s"
+msgid "Inconsistent length: %u %u"
msgstr ""
-#: metadata/pv_map.c:277
+#: metadata/pv_manip.c:254
#, c-format
-msgid "Couldn't create area maps in %s"
+msgid "PV segment pe_count mismatch: %u != %u"
msgstr ""
-#: metadata/segtype.c:30
+#: metadata/pv_manip.c:260
#, c-format
-msgid "Unrecognised segment type %s"
+msgid "PV segment pe_alloc_count mismatch: %u != %u"
msgstr ""
-#: metadata/snapshot_manip.c:85
-msgid "snapshot name list allocation failed"
+#: metadata/pv_manip.c:270
+#, c-format
+msgid "PV segment VG pv_count mismatch: %u != %u"
msgstr ""
-#: metadata/snapshot_manip.c:96
-msgid "snapshot_list structure allocation failed"
+#: metadata/pv_manip.c:276
+#, c-format
+msgid "PV segment VG free_count mismatch: %u != %u"
msgstr ""
-#: metadata/snapshot_manip.c:119
+#: metadata/pv_manip.c:282
#, c-format
-msgid "'%s' is already in use as a snapshot."
+msgid "PV segment VG extent_count mismatch: %u != %u"
+msgstr ""
+
+#: metadata/pv_map.c:46
+#, c-format
+msgid "Allowing allocation on %s start PE %u length %u"
+msgstr ""
+
+#: metadata/pv_map.c:165
+msgid "create_pv_maps alloc failed"
msgstr ""
-#: metadata/snapshot_manip.c:137
+#: metadata/pv_map.c:172
#, c-format
-msgid "Random UUID creation failed for snapshot %s."
+msgid "Couldn't create physical volume maps in %s"
msgstr ""
-#: metadata/snapshot_manip.c:172
-msgid "Asked to remove an unknown snapshot."
+#: metadata/segtype.c:30
+#, c-format
+msgid "Unrecognised segment type %s"
msgstr ""
-#: mirror/mirrored.c:48
+#: metadata/snapshot_manip.c:49
+#, c-format
+msgid "'%s' is already in use as a snapshot."
+msgstr ""
+
+#: metadata/snapshot_manip.c:90
+#, c-format
+msgid "Failed to remove internal snapshot LV %s"
+msgstr ""
+
+#: mirror/mirrored.c:50
#, c-format
msgid " Mirrors\t\t%u"
msgstr ""
-#: mirror/mirrored.c:49
+#: mirror/mirrored.c:51
#, c-format
msgid " Mirror size\t\t%u"
msgstr ""
-#: mirror/mirrored.c:50
+#: mirror/mirrored.c:53
+#, c-format
+msgid " Mirror log volume\t%s"
+msgstr ""
+
+#: mirror/mirrored.c:59
+#, c-format
+msgid " Mirror region size\t%s"
+msgstr ""
+
+#: mirror/mirrored.c:62
msgid " Mirror original:"
msgstr ""
-#: mirror/mirrored.c:52
+#: mirror/mirrored.c:64
msgid " Mirror destination:"
msgstr ""
-#: mirror/mirrored.c:61
+#: mirror/mirrored.c:72
#, c-format
msgid "Couldn't read 'mirror_count' for segment '%s'."
msgstr ""
-#: mirror/mirrored.c:79
+#: mirror/mirrored.c:91
#, c-format
msgid "Couldn't read 'extents_moved' for segment '%s'."
msgstr ""
-#: mirror/mirrored.c:86
+#: mirror/mirrored.c:100
+#, c-format
+msgid "Couldn't read 'region_size' for segment '%s'."
+msgstr ""
+
+#: mirror/mirrored.c:108
+msgid "Mirror log type must be a string."
+msgstr ""
+
+#: mirror/mirrored.c:113
+#, c-format
+msgid "Unrecognised mirror log in segment %s."
+msgstr ""
+
+#: mirror/mirrored.c:121
+#, c-format
+msgid "Missing region size for mirror log for segment '%s'."
+msgstr ""
+
+#: mirror/mirrored.c:127
#, c-format
msgid "Couldn't find mirrors array for segment '%s'."
msgstr ""
-#: mirror/mirrored.c:111
+#: mirror/mirrored.c:156
msgid "struct mirr_state allocation failed"
msgstr ""
-#: mirror/mirrored.c:165
-#, c-format
-msgid "Using reduced mirror region size of %u sectors"
+#: mirror/mirrored.c:206
+msgid "Missing region size for mirror segment."
msgstr ""
-#: mirror/mirrored.c:193
+#: mirror/mirrored.c:247
#, c-format
msgid "Mirror status: %s"
msgstr ""
-#: mirror/mirrored.c:196
+#: mirror/mirrored.c:250
#, c-format
msgid "Failure parsing mirror status: %s"
msgstr ""
@@ -4588,22 +5065,22 @@
msgid "Not enough space to build temporary file string."
msgstr ""
-#: misc/lvm-file.c:97
+#: misc/lvm-file.c:101
#, c-format
msgid "%s: rename to %s failed"
msgstr ""
-#: misc/lvm-file.c:143
+#: misc/lvm-file.c:147
#, c-format
msgid "Creating directory \"%s\""
msgstr ""
-#: misc/lvm-file.c:182
+#: misc/lvm-file.c:188
#, c-format
msgid "Directory \"%s\" not found"
msgstr ""
-#: misc/lvm-file.c:213
+#: misc/lvm-file.c:219
msgid "sync_dir failed in strdup"
msgstr ""
@@ -4617,9 +5094,9 @@
msgid "Unable to open external %s library %s"
msgstr ""
-#: mm/dbg_malloc.c:224
+#: mm/dbg_malloc.c:239
#, c-format
-msgid "Huge memory allocation (size %Zu) rejected - metadata corruption?"
+msgid "Huge memory allocation (size %zu) rejected - metadata corruption?"
msgstr ""
#: mm/memlock.c:100
@@ -4647,7 +5124,7 @@
#: mm/pool-fast.c:45
#, c-format
-msgid "Couldn't create memory pool %s (size %Zu)"
+msgid "Couldn't create memory pool %s (size %zu)"
msgstr ""
#: mm/pool-fast.c:134
@@ -4656,14 +5133,14 @@
#: mm/pool-fast.c:223
#, c-format
-msgid "Out of memory. Requested %Zu bytes."
+msgid "Out of memory. Requested %zu bytes."
msgstr ""
#: polldaemon.c:34
msgid "Forking background process"
msgstr ""
-#: polldaemon.c:39 toollib.c:958
+#: polldaemon.c:39 toollib.c:984
#, c-format
msgid "fork failed: %s"
msgstr ""
@@ -4673,177 +5150,187 @@
msgid "Background process failed to setsid: %s"
msgstr ""
-#: polldaemon.c:80
+#: polldaemon.c:82
msgid "Failed to generate list of copied LVs: can't abort."
msgstr ""
-#: polldaemon.c:90
+#: polldaemon.c:92
msgid "ABORTING: Mirror percentage check failed."
msgstr ""
-#: polldaemon.c:96 polldaemon.c:98
+#: polldaemon.c:98 polldaemon.c:100
#, c-format
msgid "%s: Moved: %.1f%%"
msgstr ""
-#: polldaemon.c:107
+#: polldaemon.c:112
msgid "ABORTING: Failed to generate list of copied LVs"
msgstr ""
-#: polldaemon.c:119
+#: polldaemon.c:124
msgid "ABORTING: Segment progression failed."
msgstr ""
-#: polldaemon.c:146
+#: polldaemon.c:154
#, c-format
msgid "ABORTING: Can't reread VG for %s"
msgstr ""
-#: polldaemon.c:153
+#: polldaemon.c:161
#, c-format
msgid "ABORTING: Can't find mirror LV in %s for %s"
msgstr ""
-#: polldaemon.c:181
+#: polldaemon.c:189
#, c-format
msgid "Couldn't read volume group %s"
msgstr ""
-#: polldaemon.c:186
+#: polldaemon.c:194
#, c-format
msgid "Volume Group %s inconsistent - skipping"
msgstr ""
-#: polldaemon.c:238
+#: polldaemon.c:246
#, c-format
msgid "Checking progress every %u seconds"
msgstr ""
-#: pvchange.c:52
+#: pvchange.c:55
#, c-format
msgid "Finding volume group of physical volume \"%s\""
msgstr ""
-#: pvchange.c:62
+#: pvchange.c:65
#, c-format
msgid "Unable to find volume group of \"%s\""
msgstr ""
-#: pvchange.c:81
+#: pvchange.c:84
#, c-format
msgid "Unable to find \"%s\" in volume group \"%s\""
msgstr ""
-#: pvchange.c:88
+#: pvchange.c:91
#, c-format
msgid "Volume group containing %s does not support tags"
msgstr ""
-#: pvchange.c:94
+#: pvchange.c:97
#, c-format
msgid "Volume group containing %s has active logical volumes"
msgstr ""
-#: pvchange.c:103
+#: pvchange.c:106
#, c-format
msgid "Can't change tag on Physical Volume %s not in volume group"
msgstr ""
-#: pvchange.c:108
+#: pvchange.c:111
msgid "Can't get lock for orphans"
msgstr ""
-#: pvchange.c:114
+#: pvchange.c:117
#, c-format
msgid "Unable to read PV \"%s\""
msgstr ""
-#: pvchange.c:123
+#: pvchange.c:126
#, c-format
msgid "Allocatability not supported by orphan %s format PV %s"
msgstr ""
-#: pvchange.c:131
+#: pvchange.c:134
#, c-format
msgid "Physical volume \"%s\" is already allocatable"
msgstr ""
-#: pvchange.c:141
+#: pvchange.c:144
#, c-format
msgid "Physical volume \"%s\" is already unallocatable"
msgstr ""
-#: pvchange.c:151
+#: pvchange.c:154
#, c-format
msgid "Setting physical volume \"%s\" allocatable"
msgstr ""
-#: pvchange.c:155
+#: pvchange.c:158
#, c-format
msgid "Setting physical volume \"%s\" NOT allocatable"
msgstr ""
-#: pvchange.c:163
+#: pvchange.c:166
#, c-format
msgid "Failed to add tag %s to physical volume %s"
msgstr ""
-#: pvchange.c:169
+#: pvchange.c:172
#, c-format
msgid "Failed to remove tag %s from physical volume%s"
msgstr ""
-#: pvchange.c:177
+#: pvchange.c:180
#, c-format
msgid "Failed to generate new random UUID for %s."
msgstr ""
-#: pvchange.c:183
+#: pvchange.c:188
+#, c-format
+msgid "Changing uuid of %s to %s."
+msgstr ""
+
+#: pvchange.c:195
+#, c-format
+msgid "pv_write with new uuid failed for %s."
+msgstr ""
+
+#: pvchange.c:204
#, c-format
msgid "Updating physical volume \"%s\""
msgstr ""
-#: pvchange.c:187
+#: pvchange.c:208
#, c-format
msgid "Failed to store physical volume \"%s\" in volume group \"%s\""
msgstr ""
-#: pvchange.c:196
+#: pvchange.c:217
#, c-format
msgid "Failed to store physical volume \"%s\""
msgstr ""
-#: pvchange.c:203
+#: pvchange.c:224
#, c-format
msgid "Physical volume \"%s\" changed"
msgstr ""
-#: pvchange.c:225
+#: pvchange.c:246
msgid "Please give exactly one option of -x, -uuid, --addtag or --deltag"
msgstr ""
-#: pvchange.c:231
+#: pvchange.c:252
msgid "Please give a physical volume path"
msgstr ""
-#: pvchange.c:236
+#: pvchange.c:257
msgid "Option a and PhysicalVolumePath are exclusive"
msgstr ""
-#: pvchange.c:241 toollib.c:511
+#: pvchange.c:262 toollib.c:537
msgid "Using physical volume(s) on command line"
msgstr ""
-#: pvchange.c:246
+#: pvchange.c:267
#, c-format
msgid "Failed to read physical volume %s"
msgstr ""
-#: pvchange.c:254 toollib.c:581
+#: pvchange.c:275 toollib.c:607
msgid "Scanning for physical volume names"
msgstr ""
-#: pvchange.c:265
+#: pvchange.c:286
#, c-format
msgid "%d physical volume%s changed / %d physical volume%s not changed"
msgstr ""
@@ -4864,16 +5351,8 @@
msgid "%s: physical volume not initialized"
msgstr ""
-#: pvcreate.c:66 pvscan.c:126 vgscan.c:51
-msgid "Wiping cache of LVM-capable devices"
-msgstr ""
-
-#: pvcreate.c:68 pvscan.c:129 vgscan.c:54
-msgid "Wiping internal cache"
-msgstr ""
-
-#: pvcreate.c:72 pvcreate.c:162 pvremove.c:76 vgcreate.c:134 vgextend.c:40
-#: vgremove.c:83
+#: pvcreate.c:72 pvcreate.c:162 pvremove.c:76 vgcreate.c:139 vgextend.c:40
+#: vgremove.c:91
msgid "Can't get lock for orphan PVs"
msgstr ""
@@ -4925,17 +5404,17 @@
msgid "%s: Couldn't find device. Check your filters?"
msgstr ""
-#: pvcreate.c:202 vgconvert.c:125
+#: pvcreate.c:202 vgconvert.c:127
#, c-format
msgid "Failed to setup physical volume \"%s\""
msgstr ""
-#: pvcreate.c:206 vgconvert.c:136
+#: pvcreate.c:206 vgconvert.c:138
#, c-format
msgid "Set up physical volume for \"%s\" with %llu available sectors"
msgstr ""
-#: pvcreate.c:211 vgconvert.c:141
+#: pvcreate.c:211 vgconvert.c:143
#, c-format
msgid "Failed to wipe existing label on %s"
msgstr ""
@@ -4950,17 +5429,17 @@
msgid "%s not opened: device not zeroed"
msgstr ""
-#: pvcreate.c:226 vgconvert.c:148
+#: pvcreate.c:226 vgconvert.c:150
#, c-format
msgid "Writing physical volume data to disk \"%s\""
msgstr ""
-#: pvcreate.c:230 vgconvert.c:153
+#: pvcreate.c:230 vgconvert.c:155
#, c-format
msgid "Failed to write physical volume \"%s\""
msgstr ""
-#: pvcreate.c:234 vgconvert.c:159
+#: pvcreate.c:234 vgconvert.c:161
#, c-format
msgid "Physical volume \"%s\" successfully created"
msgstr ""
@@ -4981,16 +5460,16 @@
msgid "Option y can only be given with option f"
msgstr ""
-#: pvcreate.c:271 vgconvert.c:203
+#: pvcreate.c:271 vgconvert.c:205
#, c-format
msgid "labelsector must be less than %lu"
msgstr ""
-#: pvcreate.c:279 vgconvert.c:211
+#: pvcreate.c:279 vgconvert.c:213
msgid "Metadata parameters only apply to text format"
msgstr ""
-#: pvcreate.c:285 vgconvert.c:217
+#: pvcreate.c:285 vgconvert.c:219
msgid "Metadatacopies may only be 0, 1 or 2"
msgstr ""
@@ -5009,7 +5488,7 @@
msgid "\"%s\" is a new physical volume of \"%s\""
msgstr ""
-#: pvdisplay.c:76
+#: pvdisplay.c:77
msgid "Option -v not allowed with option -c"
msgstr ""
@@ -5029,11 +5508,11 @@
msgid "No extents available for allocation"
msgstr ""
-#: pvmove.c:147
+#: pvmove.c:146
msgid "Creation of temporary pvmove LV failed"
msgstr ""
-#: pvmove.c:154
+#: pvmove.c:153
msgid "lvs_changed list struct allocation failed"
msgstr ""
@@ -5052,88 +5531,88 @@
msgid "Skipping locked LV %s"
msgstr ""
-#: pvmove.c:186
+#: pvmove.c:187
#, c-format
msgid "No data to move for %s"
msgstr ""
-#: pvmove.c:197
+#: pvmove.c:198
msgid "Updating volume group metadata"
msgstr ""
-#: pvmove.c:199 pvmove.c:223
+#: pvmove.c:200 pvmove.c:224
msgid "ABORTING: Volume group metadata update failed."
msgstr ""
-#: pvmove.c:235
+#: pvmove.c:236
msgid "ABORTING: Temporary mirror activation failed. Run pvmove --abort."
msgstr ""
-#: pvmove.c:243 pvmove.c:425
+#: pvmove.c:244 pvmove.c:426
#, c-format
msgid "Unable to reactivate logical volume \"%s\""
msgstr ""
-#: pvmove.c:251
+#: pvmove.c:252
msgid "Unable to resume logical volumes"
msgstr ""
-#: pvmove.c:299
+#: pvmove.c:300
#, c-format
msgid "Detected pvmove in progress for %s"
msgstr ""
-#: pvmove.c:301
+#: pvmove.c:302
msgid "Ignoring remaining command line arguments"
msgstr ""
-#: pvmove.c:304
+#: pvmove.c:305
msgid "ABORTING: Failed to generate list of moving LVs"
msgstr ""
-#: pvmove.c:312
+#: pvmove.c:313
msgid "ABORTING: Temporary mirror activation failed."
msgstr ""
-#: pvmove.c:390
+#: pvmove.c:391
msgid "ABORTING: Removal of temporary mirror failed"
msgstr ""
-#: pvmove.c:396 pvmove.c:415 pvmove.c:449
+#: pvmove.c:397 pvmove.c:416 pvmove.c:450
msgid "ABORTING: Failed to write new data locations to disk."
msgstr ""
-#: pvmove.c:403
+#: pvmove.c:404
msgid "Locking LVs to remove temporary mirror failed"
msgstr ""
-#: pvmove.c:409
+#: pvmove.c:410
msgid "Suspension of temporary mirror LV failed"
msgstr ""
-#: pvmove.c:435
+#: pvmove.c:436
#, c-format
msgid "ABORTING: Unable to deactivate temporary logical volume \"%s\""
msgstr ""
-#: pvmove.c:440
+#: pvmove.c:441
msgid "Removing temporary pvmove LV"
msgstr ""
-#: pvmove.c:442
+#: pvmove.c:443
msgid "ABORTING: Removal of temporary pvmove LV failed"
msgstr ""
-#: pvmove.c:447
+#: pvmove.c:448
msgid "Writing out final volume group after pvmove"
msgstr ""
-#: pvmove.c:467
+#: pvmove.c:468
#, c-format
msgid "ABORTING: Can't reread PV %s"
msgstr ""
-#: pvmove.c:503 toollib.c:882
+#: pvmove.c:504 toollib.c:908
msgid "Failed to clone PV name"
msgstr ""
@@ -5187,15 +5666,15 @@
msgid "WARNING: only considering physical volumes %s"
msgstr ""
-#: pvscan.c:132
+#: pvscan.c:129
msgid "Walking through all physical volumes"
msgstr ""
-#: pvscan.c:185
+#: pvscan.c:182
msgid "No matching physical volumes found"
msgstr ""
-#: pvscan.c:189
+#: pvscan.c:186
#, c-format
msgid "Total: %d [%s] / in use: %d [%s] / in no VG: %d [%s]"
msgstr ""
@@ -5233,136 +5712,141 @@
msgid "Parse error in regex"
msgstr ""
-#: report/report.c:124 report/report.c:527 report/report.c:555
+#: report/report.c:125 report/report.c:541 report/report.c:581
+#: report/report.c:609
msgid "pool_strdup failed"
msgstr ""
-#: report/report.c:151 report/report.c:210
+#: report/report.c:152 report/report.c:211
msgid "pool_begin_object failed"
msgstr ""
-#: report/report.c:171 report/report.c:182 report/report.c:188
-#: report/report.c:194 report/report.c:217 report/report.c:223
-#: report/report.c:1265
+#: report/report.c:172 report/report.c:183 report/report.c:189
+#: report/report.c:195 report/report.c:218 report/report.c:224
+#: report/report.c:1322
msgid "pool_grow_object failed"
msgstr ""
-#: report/report.c:177
+#: report/report.c:178
msgid "Extent number lvm_snprintf failed"
msgstr ""
-#: report/report.c:270 report/report.c:275 report/report.c:331
-#: report/report.c:404 report/report.c:431 report/report.c:532
-#: report/report.c:560 report/report.c:677 report/report.c:700
-#: report/report.c:705 report/report.c:729 report/report.c:734
-#: report/report.c:772 report/report.c:792 report/report.c:817
-#: report/report.c:832
+#: report/report.c:271 report/report.c:276 report/report.c:332
+#: report/report.c:409 report/report.c:436 report/report.c:529
+#: report/report.c:586 report/report.c:614 report/report.c:731
+#: report/report.c:754 report/report.c:759 report/report.c:783
+#: report/report.c:788 report/report.c:826 report/report.c:847
+#: report/report.c:872 report/report.c:887
msgid "pool_alloc failed"
msgstr ""
-#: report/report.c:280
+#: report/report.c:281
#, c-format
msgid "int too big: %d"
msgstr ""
-#: report/report.c:710
+#: report/report.c:534
+msgid "lvname snprintf failed"
+msgstr ""
+
+#: report/report.c:764
#, c-format
msgid "uint32 too big: %u"
msgstr ""
-#: report/report.c:739
+#: report/report.c:793
#, c-format
msgid "int32 too big: %d"
msgstr ""
-#: report/report.c:797
+#: report/report.c:852
msgid "snapshot percentage too large"
msgstr ""
-#: report/report.c:837
+#: report/report.c:892
msgid "copy percentage too large"
msgstr ""
-#: report/report.c:894 report/report.c:933
+#: report/report.c:949 report/report.c:985
msgid "struct field_properties allocation failed"
msgstr ""
-#: report/report.c:946
+#: report/report.c:998
#, c-format
msgid "Ignoring duplicate sort field: %s"
msgstr ""
-#: report/report.c:978
+#: report/report.c:1030
msgid "Missing sort field name"
msgstr ""
-#: report/report.c:1009 report/report.c:1031
+#: report/report.c:1061 report/report.c:1083
#, c-format
msgid "Unrecognised field: %.*s"
msgstr ""
-#: report/report.c:1047
+#: report/report.c:1099
msgid "report_handle pool_zalloc failed"
msgstr ""
-#: report/report.c:1085
+#: report/report.c:1140
msgid "Allocation of memory pool for report failed"
msgstr ""
-#: report/report.c:1100
+#: report/report.c:1157
msgid "Can't report LV and PV fields at the same time"
msgstr ""
-#: report/report.c:1140
+#: report/report.c:1198
msgid "report_object: One of *lv and *pv must be NULL!"
msgstr ""
-#: report/report.c:1145
+#: report/report.c:1203
msgid "struct row allocation failed"
msgstr ""
-#: report/report.c:1154
+#: report/report.c:1212
msgid "row sort value structure allocation failed"
msgstr ""
-#: report/report.c:1168
+#: report/report.c:1224
msgid "struct field allocation failed"
msgstr ""
-#: report/report.c:1195
+#: report/report.c:1254
#, c-format
msgid "report function failed for field %s"
msgstr ""
-#: report/report.c:1236
+#: report/report.c:1294
msgid "pool_begin_object failed for headings"
msgstr ""
-#: report/report.c:1250
+#: report/report.c:1307
msgid "snprintf heading failed"
msgstr ""
-#: report/report.c:1273
+#: report/report.c:1330
msgid "Failed to generate report headings for printing"
msgstr ""
-#: report/report.c:1333
+#: report/report.c:1389
msgid "sort array allocation failed"
msgstr ""
-#: report/report.c:1378
+#: report/report.c:1432
msgid "pool_begin_object failed for row"
msgstr ""
-#: report/report.c:1396 report/report.c:1405
+#: report/report.c:1450 report/report.c:1459
msgid "snprintf repstr failed"
msgstr ""
-#: report/report.c:1420
+#: report/report.c:1474
msgid "pool_grow_object failed for row"
msgstr ""
-#: report/report.c:1433
+#: report/report.c:1487
msgid "Failed to generate row for printing"
msgstr ""
@@ -5371,17 +5855,17 @@
msgid "Volume group %s not found"
msgstr ""
-#: reporter.c:65 toollib.c:233 toollib.c:321
+#: reporter.c:64 reporter.c:105 toollib.c:236 toollib.c:346
#, c-format
msgid "Can't lock %s: skipping"
msgstr ""
-#: reporter.c:70
+#: reporter.c:69 reporter.c:110
#, c-format
msgid "Can't read %s: skipping"
msgstr ""
-#: reporter.c:160
+#: reporter.c:212
#, c-format
msgid "Invalid options string: %s"
msgstr ""
@@ -5406,37 +5890,37 @@
msgid "Unknown logical volume specified for snapshot origin."
msgstr ""
-#: striped/striped.c:42
+#: striped/striped.c:43
#, c-format
msgid " Stripes\t\t%u"
msgstr ""
-#: striped/striped.c:43
+#: striped/striped.c:44
#, c-format
msgid " Stripe size\t\t%u KB"
msgstr ""
-#: striped/striped.c:46
+#: striped/striped.c:47
#, c-format
msgid " Stripe %d:"
msgstr ""
-#: striped/striped.c:56
+#: striped/striped.c:57
#, c-format
msgid "Couldn't read 'stripe_count' for segment '%s'."
msgstr ""
-#: striped/striped.c:71
+#: striped/striped.c:72
#, c-format
msgid "Couldn't read stripe_size for segment '%s'."
msgstr ""
-#: striped/striped.c:77
+#: striped/striped.c:78
#, c-format
msgid "Couldn't find stripes array for segment '%s'."
msgstr ""
-#: striped/striped.c:164
+#: striped/striped.c:174
msgid "Internal error: striped target with no stripes"
msgstr ""
@@ -5458,158 +5942,183 @@
"Metadata in LVM1 format can still be displayed using LVM1's pvdata command."
msgstr ""
-#: toollib.c:91
+#: toollib.c:94
msgid "One or more specified logical volume(s) not found."
msgstr ""
-#: toollib.c:127
+#: toollib.c:130
msgid "Using logical volume(s) on command line"
msgstr ""
-#: toollib.c:140 toollib.c:374 toollib.c:517 toollib.c:863
+#: toollib.c:143 toollib.c:399 toollib.c:543 toollib.c:889
#, c-format
msgid "Skipping invalid tag %s"
msgstr ""
-#: toollib.c:167 toollib.c:622 toollib.c:633
+#: toollib.c:170 toollib.c:648 toollib.c:659
#, c-format
msgid "\"%s\": Invalid path for Logical Volume"
msgstr ""
-#: toollib.c:208
+#: toollib.c:211
msgid "vg/lv string alloc failed"
msgstr ""
-#: toollib.c:221
+#: toollib.c:224
msgid "Finding all logical volumes"
msgstr ""
-#: toollib.c:223 toollib.c:412
+#: toollib.c:226 toollib.c:437
msgid "No volume groups found"
msgstr ""
-#: toollib.c:243 vgcfgbackup.c:55 vgck.c:22 vgreduce.c:282 vgscan.c:22
+#: toollib.c:246 vgcfgbackup.c:55 vgck.c:22 vgreduce.c:287 vgscan.c:22
#, c-format
msgid "Volume group \"%s\" not found"
msgstr ""
-#: toollib.c:246 vgchange.c:301 vgck.c:27 vgconvert.c:43 vgscan.c:29
+#: toollib.c:249 vgchange.c:404 vgck.c:27 vgconvert.c:43 vgscan.c:29
#, c-format
msgid "Volume group \"%s\" inconsistent"
msgstr ""
-#: toollib.c:368
+#: toollib.c:393
msgid "Using volume group(s) on command line"
msgstr ""
-#: toollib.c:395
+#: toollib.c:420
#, c-format
msgid "Invalid volume group name: %s"
msgstr ""
-#: toollib.c:410
+#: toollib.c:435
msgid "Finding all volume groups"
msgstr ""
-#: toollib.c:533 toollib.c:888
+#: toollib.c:559 toollib.c:914
#, c-format
msgid "Physical Volume \"%s\" not found in Volume Group \"%s\""
msgstr ""
-#: toollib.c:544
+#: toollib.c:570
#, c-format
msgid "Failed to read physical volume \"%s\""
msgstr ""
-#: toollib.c:570
+#: toollib.c:596
msgid "Using all physical volume(s) in volume group"
msgstr ""
-#: toollib.c:640
+#: toollib.c:666
msgid "Allocation of vg_name failed"
msgstr ""
-#: toollib.c:650
+#: toollib.c:676
#, c-format
msgid "Path required for Logical Volume \"%s\""
msgstr ""
-#: toollib.c:681
+#: toollib.c:707
#, c-format
msgid "Environment Volume Group in LVM_VG_NAME invalid: \"%s\""
msgstr ""
-#: toollib.c:697
+#: toollib.c:723
#, c-format
msgid "Adding PE range: start PE %u length %u"
msgstr ""
-#: toollib.c:705
+#: toollib.c:731
#, c-format
msgid "Overlapping PE ranges detected (%u-%u, %u-%u)"
msgstr ""
-#: toollib.c:714 toollib.c:851 toollib.c:908
+#: toollib.c:740 toollib.c:877 toollib.c:934
msgid "Allocation of list failed"
msgstr ""
-#: toollib.c:778
+#: toollib.c:804
#, c-format
msgid "PE range error: start extent %u to end extent %u"
msgstr ""
-#: toollib.c:793
+#: toollib.c:819
#, c-format
msgid "Physical extent parsing error at %s"
msgstr ""
-#: toollib.c:806
+#: toollib.c:832
#, c-format
msgid "Physical volume %s not allocatable"
msgstr ""
-#: toollib.c:812
+#: toollib.c:838
#, c-format
msgid "No free extents on physical volume \"%s\""
msgstr ""
-#: toollib.c:817 toollib.c:915
+#: toollib.c:843 toollib.c:941
msgid "Unable to allocate physical volume list."
msgstr ""
-#: toollib.c:824
+#: toollib.c:850
msgid "Allocation of pe_ranges list failed"
msgstr ""
-#: toollib.c:896
+#: toollib.c:922
msgid "No specified PVs have space available"
msgstr ""
-#: toollib.c:938
+#: toollib.c:964
#, c-format
msgid "Can't lock %s for metadata recovery: skipping"
msgstr ""
-#: toollib.c:955
+#: toollib.c:981
#, c-format
msgid "Executing: %s %s %s %s"
msgstr ""
-#: toollib.c:972
+#: toollib.c:998
#, c-format
msgid "wait4 child process %u failed: %s"
msgstr ""
-#: toollib.c:978
+#: toollib.c:1004
#, c-format
msgid "Child %u exited abnormally"
msgstr ""
-#: toollib.c:983
+#: toollib.c:1009
#, c-format
msgid "%s failed: %u"
msgstr ""
+#: toollib.c:1019
+msgid ""
+"Names starting \"snapshot\" are reserved. Please choose a different LV name."
+msgstr ""
+
+#: toollib.c:1025
+msgid ""
+"Names starting \"pvmove\" are reserved. Please choose a different LV name."
+msgstr ""
+
+#: toollib.c:1031
+msgid ""
+"Names including \"_mlog\" are reserved. Please choose a different LV name."
+msgstr ""
+
+#: toollib.c:1037
+msgid ""
+"Names including \"_mimage\" are reserved. Please choose a different LV name."
+msgstr ""
+
+#: toollib.c:1054
+#, c-format
+msgid "%s: already exists in filesystem"
+msgstr ""
+
#: uuid/uuid.c:133
msgid "UUID contains invalid character"
msgstr ""
@@ -5690,101 +6199,145 @@
#: vgchange.c:87
#, c-format
+msgid "Locking inactive: ignoring clustered volume group %s"
+msgstr ""
+
+#: vgchange.c:97
+#, c-format
msgid "%d logical volume(s) in volume group \"%s\" already active"
msgstr ""
-#: vgchange.c:91
+#: vgchange.c:101
#, c-format
msgid "Activated logical volumes in volume group \"%s\""
msgstr ""
-#: vgchange.c:95
+#: vgchange.c:105
#, c-format
msgid "Deactivated logical volumes in volume group \"%s\""
msgstr ""
-#: vgchange.c:98
+#: vgchange.c:108
#, c-format
msgid "%d logical volume(s) in volume group \"%s\" now active"
msgstr ""
-#: vgchange.c:110 vgcreate.c:47
+#: vgchange.c:120 vgcreate.c:47
msgid "Volume Group allocation policy cannot inherit from anything"
msgstr ""
-#: vgchange.c:116
+#: vgchange.c:126
#, c-format
msgid "Volume group allocation policy is already %s"
msgstr ""
-#: vgchange.c:131 vgchange.c:166 vgchange.c:208 vgchange.c:250 vgchange.c:282
+#: vgchange.c:141 vgchange.c:176 vgchange.c:211 vgchange.c:253 vgchange.c:311
+#: vgchange.c:353 vgchange.c:385
#, c-format
msgid "Volume group \"%s\" successfully changed"
msgstr ""
-#: vgchange.c:142
+#: vgchange.c:152
#, c-format
msgid "Volume group \"%s\" is already resizeable"
msgstr ""
-#: vgchange.c:148
+#: vgchange.c:158
#, c-format
msgid "Volume group \"%s\" is already not resizeable"
msgstr ""
-#: vgchange.c:177
+#: vgchange.c:187
+#, c-format
+msgid "Volume group \"%s\" is already clustered"
+msgstr ""
+
+#: vgchange.c:193
+#, c-format
+msgid "Volume group \"%s\" is already not clustered"
+msgstr ""
+
+#: vgchange.c:222
#, c-format
msgid "Volume group \"%s\" must be resizeable to change MaxLogicalVolume"
msgstr ""
-#: vgchange.c:186
+#: vgchange.c:231
msgid "MaxLogicalVolume limit is 255"
msgstr ""
-#: vgchange.c:192
+#: vgchange.c:237
#, c-format
msgid ""
"MaxLogicalVolume is less than the current number %d of logical volume(s) for "
"\"%s\""
msgstr ""
-#: vgchange.c:233 vgcreate.c:127
+#: vgchange.c:263
+#, c-format
+msgid "Volume group \"%s\" must be resizeable to change PE size"
+msgstr ""
+
+#: vgchange.c:269 vgcreate.c:64
+msgid "Physical extent size may not be negative"
+msgstr ""
+
+#: vgchange.c:275 vgcreate.c:83
+msgid "Physical extent size may not be zero"
+msgstr ""
+
+#: vgchange.c:280
+#, c-format
+msgid "Physical extent size of VG %s is already %s"
+msgstr ""
+
+#: vgchange.c:286
+msgid "Physical extent size must be a power of 2."
+msgstr ""
+
+#: vgchange.c:293
+msgid "New extent size is not a perfect fit"
+msgstr ""
+
+#: vgchange.c:336 vgcreate.c:121
#, c-format
msgid "Failed to add tag %s to volume group %s"
msgstr ""
-#: vgchange.c:239
+#: vgchange.c:342
#, c-format
msgid "Failed to remove tag %s from volume group %s"
msgstr ""
-#: vgchange.c:260
+#: vgchange.c:363
msgid "Volume group has active logical volumes"
msgstr ""
-#: vgchange.c:268
+#: vgchange.c:371
#, c-format
msgid "Failed to generate new random UUID for VG %s."
msgstr ""
-#: vgchange.c:294 vgconvert.c:36 vgexport.c:23
+#: vgchange.c:397 vgconvert.c:36 vgexport.c:23
#, c-format
msgid "Unable to find volume group \"%s\""
msgstr ""
-#: vgchange.c:347
-msgid "One of -a, -l, -x, --alloc, --addtag, --deltag or --uuid required"
+#: vgchange.c:457
+msgid ""
+"One of -a, -c, -l, -s, -x, --uuid, --alloc, --addtag or --deltag required"
msgstr ""
-#: vgchange.c:357
-msgid "Only one of -a, -l, -x, --alloc, --addtag, --deltag or --uuid allowed"
+#: vgchange.c:468
+msgid ""
+"Only one of -a, -c, -l, -s, -x, --uuid, --alloc, --addtag or --deltag allowed"
msgstr ""
-#: vgchange.c:364
+#: vgchange.c:475
msgid "--ignorelockingfailure only available with -a"
msgstr ""
-#: vgchange.c:370
+#: vgchange.c:481
msgid "-A option not necessary with -a option"
msgstr ""
@@ -5798,47 +6351,47 @@
msgid "Archive of \"%s\" metadata failed."
msgstr ""
-#: vgconvert.c:98
+#: vgconvert.c:100
#, c-format
msgid "Logical volume %s must be deactivated before conversion."
msgstr ""
-#: vgconvert.c:128 vgconvert.c:143 vgconvert.c:155 vgconvert.c:168
-#: vgconvert.c:184
+#: vgconvert.c:130 vgconvert.c:145 vgconvert.c:157 vgconvert.c:170
+#: vgconvert.c:186
msgid "Use pvcreate and vgcfgrestore to repair from archived metadata."
msgstr ""
-#: vgconvert.c:164
+#: vgconvert.c:166
#, c-format
msgid "Deleting existing metadata for VG %s"
msgstr ""
-#: vgconvert.c:166
+#: vgconvert.c:168
#, c-format
msgid "Removal of existing metadata for %s failed."
msgstr ""
-#: vgconvert.c:175
+#: vgconvert.c:177
#, c-format
msgid "Test mode: Skipping metadata writing for VG %s in format %s"
msgstr ""
-#: vgconvert.c:180
+#: vgconvert.c:182
#, c-format
msgid "Writing metadata for VG %s using format %s"
msgstr ""
-#: vgconvert.c:183
+#: vgconvert.c:185
#, c-format
msgid "Conversion failed for volume group %s."
msgstr ""
-#: vgconvert.c:188
+#: vgconvert.c:190
#, c-format
msgid "Volume group %s successfully converted"
msgstr ""
-#: vgconvert.c:198
+#: vgconvert.c:200
msgid "Please enter volume group(s)"
msgstr ""
@@ -5854,10 +6407,6 @@
msgid "Number of volumes may not exceed 255"
msgstr ""
-#: vgcreate.c:64
-msgid "Physical extent size may not be negative"
-msgstr ""
-
#: vgcreate.c:69
msgid "Max Logical Volumes may not be negative"
msgstr ""
@@ -5866,35 +6415,26 @@
msgid "Max Physical Volumes may not be negative"
msgstr ""
-#: vgcreate.c:83
-msgid "Physical extent size may not be zero"
-msgstr ""
-
-#: vgcreate.c:93
-#, c-format
-msgid "%s: already exists in filesystem"
-msgstr ""
-
-#: vgcreate.c:98 vgrename.c:55
+#: vgcreate.c:92 vgrename.c:55 vgsplit.c:226
#, c-format
msgid "New volume group name \"%s\" is invalid"
msgstr ""
-#: vgcreate.c:108
+#: vgcreate.c:102
#, c-format
msgid "Warning: Setting maxlogicalvolumes to %d (0 means unlimited)"
msgstr ""
-#: vgcreate.c:112
+#: vgcreate.c:106
#, c-format
msgid "Warning: Setting maxphysicalvolumes to %d (0 means unlimited)"
msgstr ""
-#: vgcreate.c:122
+#: vgcreate.c:116
msgid "Volume group format does not support tags"
msgstr ""
-#: vgcreate.c:162
+#: vgcreate.c:167
#, c-format
msgid "Volume group \"%s\" successfully created"
msgstr ""
@@ -5913,11 +6453,11 @@
msgid "--- Physical volumes ---"
msgstr ""
-#: vgdisplay.c:79
+#: vgdisplay.c:81
msgid "Option -c is not allowed with option -s"
msgstr ""
-#: vgdisplay.c:84
+#: vgdisplay.c:86
msgid "Option -A is not allowed with volume group names"
msgstr ""
@@ -5957,7 +6497,7 @@
msgid "Please enter physical volume(s)"
msgstr ""
-#: vgextend.c:44 vgmerge.c:31 vgmerge.c:55 vgsplit.c:171 vgsplit.c:195
+#: vgextend.c:44 vgmerge.c:31 vgmerge.c:55 vgsplit.c:187 vgsplit.c:211
#, c-format
msgid "Checking for volume group \"%s\""
msgstr ""
@@ -6002,12 +6542,12 @@
msgid "Volume group \"%s\" successfully imported"
msgstr ""
-#: vgmerge.c:27 vgsplit.c:167
+#: vgmerge.c:27 vgsplit.c:183
#, c-format
msgid "Duplicate volume group name \"%s\""
msgstr ""
-#: vgmerge.c:79 vgsplit.c:211
+#: vgmerge.c:79 vgsplit.c:233
#, c-format
msgid "Logical volumes in \"%s\" must be inactive"
msgstr ""
@@ -6032,12 +6572,22 @@
msgid "Duplicate logical volume name \"%s\" in \"%s\" and \"%s\""
msgstr ""
-#: vgmerge.c:175
+#: vgmerge.c:153
+#, c-format
+msgid "Failed to generate new random LVID for %s"
+msgstr ""
+
+#: vgmerge.c:164
+#, c-format
+msgid "Changed LVID for %s to %s"
+msgstr ""
+
+#: vgmerge.c:202
#, c-format
msgid "Volume group \"%s\" successfully merged into \"%s\""
msgstr ""
-#: vgmerge.c:192
+#: vgmerge.c:219
msgid "Please enter 2 or more volume groups to merge"
msgstr ""
@@ -6075,79 +6625,79 @@
msgid "Deactivating (if active) logical volume %s (origin of %s)"
msgstr ""
-#: vgreduce.c:95 vgreduce.c:104
+#: vgreduce.c:93 vgreduce.c:102
#, c-format
msgid "Removing LV %s from VG %s"
msgstr ""
-#: vgreduce.c:174
+#: vgreduce.c:172
#, c-format
msgid "Physical volume \"%s\" still in use"
msgstr ""
-#: vgreduce.c:179
+#: vgreduce.c:177
#, c-format
msgid "Can't remove final physical volume \"%s\" from volume group \"%s\""
msgstr ""
-#: vgreduce.c:189
+#: vgreduce.c:187
#, c-format
msgid "Removing \"%s\" from volume group \"%s\""
msgstr ""
-#: vgreduce.c:200
+#: vgreduce.c:205
#, c-format
msgid "Removal of physical volume \"%s\" from \"%s\" failed"
msgstr ""
-#: vgreduce.c:206
+#: vgreduce.c:211
#, c-format
msgid ""
"Failed to clear metadata from physical volume \"%s\" after removal from \"%s"
"\""
msgstr ""
-#: vgreduce.c:214
+#: vgreduce.c:219
#, c-format
msgid "Removed \"%s\" from volume group \"%s\""
msgstr ""
-#: vgreduce.c:227
+#: vgreduce.c:232
msgid "Please give volume group name and physical volume paths"
msgstr ""
-#: vgreduce.c:233
+#: vgreduce.c:238
msgid "Please give volume group name"
msgstr ""
-#: vgreduce.c:239
+#: vgreduce.c:244
msgid "Please enter physical volume paths or option -a"
msgstr ""
-#: vgreduce.c:244
+#: vgreduce.c:249
msgid "Option -a and physical volume paths mutually exclusive"
msgstr ""
-#: vgreduce.c:250
+#: vgreduce.c:255
msgid "Please only specify the volume group"
msgstr ""
-#: vgreduce.c:273
+#: vgreduce.c:278
#, c-format
msgid "Volume group \"%s\" is already consistent"
msgstr ""
-#: vgreduce.c:304
+#: vgreduce.c:309
#, c-format
msgid "Failed to write out a consistent VG for %s"
msgstr ""
-#: vgreduce.c:312
+#: vgreduce.c:317
#, c-format
msgid "Wrote out consistent volume group %s"
msgstr ""
-#: vgreduce.c:328
+#: vgreduce.c:333
#, c-format
msgid "Volume group \"%s\" is not reducible"
msgstr ""
@@ -6176,17 +6726,17 @@
msgid "Removing physical volume \"%s\" from volume group \"%s\""
msgstr ""
-#: vgremove.c:61
+#: vgremove.c:69
#, c-format
msgid "Failed to remove physical volume \"%s\" from volume group \"%s\""
msgstr ""
-#: vgremove.c:71
+#: vgremove.c:79
#, c-format
msgid "Volume group \"%s\" successfully removed"
msgstr ""
-#: vgremove.c:73
+#: vgremove.c:81
#, c-format
msgid "Volume group \"%s\" not properly removed"
msgstr ""
@@ -6243,11 +6793,11 @@
msgid "Found %svolume group \"%s\" using metadata type %s"
msgstr ""
-#: vgscan.c:47
+#: vgscan.c:49
msgid "Too many parameters on command line"
msgstr ""
-#: vgscan.c:57
+#: vgscan.c:56
msgid "Reading all physical volumes. This may take a while..."
msgstr ""
@@ -6256,40 +6806,40 @@
msgid "Physical volume %s not in volume group %s"
msgstr ""
-#: vgsplit.c:71
+#: vgsplit.c:87
#, c-format
msgid "Logical Volume %s split between Volume Groups"
msgstr ""
-#: vgsplit.c:88
+#: vgsplit.c:104
#, c-format
msgid "Physical Volume %s not found"
msgstr ""
-#: vgsplit.c:135
+#: vgsplit.c:149
#, c-format
msgid "Snapshot %s split"
msgstr ""
-#: vgsplit.c:157
+#: vgsplit.c:173
msgid "Existing VG, new VG and physical volumes required."
msgstr ""
-#: vgsplit.c:205
+#: vgsplit.c:221
#, c-format
msgid "Volume group \"%s\" already exists"
msgstr ""
-#: vgsplit.c:247
+#: vgsplit.c:269
msgid "Writing out updated volume groups"
msgstr ""
-#: vgsplit.c:269
+#: vgsplit.c:291
#, c-format
msgid "Volume group \"%s\" became inconsistent: please fix manually"
msgstr ""
-#: vgsplit.c:284
+#: vgsplit.c:306
#, c-format
msgid "Volume group \"%s\" successfully split from \"%s\""
msgstr ""
Modified: lvm2/upstream/current/scripts/clvmd_init_rhel4
==============================================================================
--- lvm2/upstream/current/scripts/clvmd_init_rhel4 (original)
+++ lvm2/upstream/current/scripts/clvmd_init_rhel4 Tue Jun 14 11:13:22 2005
@@ -13,6 +13,8 @@
LVDISPLAY="/usr/sbin/lvdisplay"
VGCHANGE="/usr/sbin/vgchange"
VGSCAN="/usr/sbin/vgscan"
+VGDISPLAY="/usr/sbin/vgdisplay"
+VGS="/usr/sbin/vgs"
[ -f /etc/sysconfig/cluster ] && . /etc/sysconfig/cluster
@@ -24,20 +26,15 @@
do
if ! pidof clvmd > /dev/null
then
- echo -n "Starting clvmd:"
- clvmd > /dev/null 2>&1
+ echo -n "Starting clvmd: "
+ daemon clvmd
rtrn=$?
- if [ $rtrn -eq 0 ]
+ echo
+ if [ $rtrn -ne 0 ]
then
- success
- echo
- else
- failure
- echo
break
fi
- fi
-
+ fi
# refresh cache
$VGSCAN > /dev/null 2>&1
@@ -45,28 +42,16 @@
then
for vg in $LVM_VGS
do
- echo -n "Activating lvm $vg:"
- if $VGCHANGE -ayl $vg > /dev/null 2>&1
+ if ! action "Activating VG $vg:" $VGCHANGE -ayl $vg
then
- success
- echo
- else
rtrn=$?
- failure
- echo
- fi
+ fi
done
else
- echo -n "Activating lvms:"
- if $VGCHANGE -ayl > /dev/null 2>&1
+ if ! action "Activating VGs:" $VGCHANGE -ayl
then
- success
- echo
- else
rtrn=$?
- failure
- echo
- fi
+ fi
fi
done
@@ -81,49 +66,28 @@
then
for vg in $LVM_VGS
do
- echo -n "Deactivating lvm $vg:"
- if $VGCHANGE -anl $vg > /dev/null 2>&1
+ if ! action "Deactivating VG $vg:" $VGCHANGE -anl $vg
then
- success
- echo
- else
rtrn=$?
- failure
- echo
fi
done
else
- echo -n "Deactivating lvms:"
- if $VGCHANGE -anl > /dev/null 2>&1
- then
- success
- echo
- else
- rtrn=$?
- failure
- echo
- fi
+ # Hack to only deactivate clustered volumes
+ clustervgs=`$VGDISPLAY \`$VGS --noheadings -o name\` | awk 'BEGIN {RS="VG Name"} {if (/Clustered/) print $1;}'`
+ for vg in $clustervgs; do
+ if ! action "Deactivating VG $vg:" $VGCHANGE -anl $vg
+ then
+ rtrn=$?
+ fi
+ done
fi
[ $rtrn -ne 0 ] && break
echo -n "Stopping clvm:"
- pid=$(pidof clvmd)
- if [ -n "$pid" ]
- then
- while kill $pid > /dev/null 2>&1
- do
- sleep 1
- done
- fi
- if [ $rtrn -eq 0 ]
- then
- success
- echo
- else
- failure
- echo
- fi
+ killproc clvmd -TERM
+ rtrn=$?
+ echo
done
return $rtrn
@@ -146,8 +110,10 @@
;;
restart)
- $0 stop
- $0 start
+ if stop
+ then
+ start
+ fi
rtrn=$?
;;
Added: lvm2/upstream/current/scripts/lvmconf.sh
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/scripts/lvmconf.sh Tue Jun 14 11:13:22 2005
@@ -0,0 +1,232 @@
+#!/bin/sh
+#
+# Edit an lvm.conf file to adjust various properties
+#
+#
+#
+
+function usage
+{
+ echo "usage: $0 <command>"
+ echo ""
+ echo "Commands:"
+ echo "Enable clvm: --enable-cluster --lockinglibdir <dir> [--lockinglib <lib>]"
+ echo "Disable clvm: --disable-cluster"
+ echo ""
+ echo "Global options:"
+ echo "Config file location: --file <configfile>"
+ echo ""
+}
+
+
+function parse_args
+{
+ while [ -n "$1" ]; do
+ case $1 in
+ --enable-cluster)
+ LOCKING_TYPE=2
+ shift
+ ;;
+ --disable-cluster)
+ LOCKING_TYPE=1
+ shift
+ ;;
+ --lockinglibdir)
+ if [ -n "$2" ]; then
+ LOCKINGLIBDIR=$2
+ shift 2
+ else
+ usage
+ exit 1
+ fi
+ ;;
+ --lockinglib)
+ if [ -n "$2" ]; then
+ LOCKINGLIB=$2
+ shift 2
+ else
+ usage
+ exit 1
+ fi
+ ;;
+ --file)
+ if [ -n "$2" ]; then
+ CONFIGFILE=$2
+ shift 2
+ else
+ usage
+ exit 1
+ fi
+ ;;
+ *)
+ usage
+ exit 1
+ esac
+ done
+}
+
+function validate_args
+{
+ [ -z "$CONFIGFILE" ] && CONFIGFILE="/etc/lvm/lvm.conf"
+
+ if [ ! -f "$CONFIGFILE" ]
+ then
+ echo "$CONFIGFILE does not exist"
+ exit 10
+ fi
+
+ if [ -z "$LOCKING_TYPE" ]; then
+ usage
+ exit 1
+ fi
+
+ if [ "$LOCKING_TYPE" == "2" ]; then
+
+ [ -z "$LOCKINGLIBDIR" ] && usage && exit 1
+ [ -z "$LOCKINGLIB" ] && LOCKINGLIB="liblvm2clusterlock.so"
+
+ if [ "${LOCKINGLIBDIR:0:1}" != "/" ]
+ then
+ echo "Prefix must be an absolute path name (starting with a /)"
+ exit 12
+ fi
+
+ if [ ! -f "$LOCKINGLIBDIR/$LOCKINGLIB" ]
+ then
+ echo "$LOCKINGLIBDIR/$LOCKINGLIB does not exist, did you do a \"make install\" ?"
+ exit 11
+ fi
+
+ fi
+}
+
+umask 0077
+
+parse_args "$@"
+
+validate_args
+
+
+SCRIPTFILE=/etc/lvm/.lvmconf-script.tmp
+TMPFILE=/etc/lvm/.lvmconf-tmp.tmp
+
+
+# Flags so we know which parts of the file we can replace and which need
+# adding. These are return codes from grep, so zero means it IS present!
+have_type=1
+have_dir=1
+have_library=1
+have_global=1
+
+grep -q '^[[:blank:]]*locking_type[[:blank:]]*=' $CONFIGFILE
+have_type=$?
+
+grep -q '^[[:blank:]]*library_dir[[:blank:]]*=' $CONFIGFILE
+have_dir=$?
+
+grep -q '^[[:blank:]]*locking_library[[:blank:]]*=' $CONFIGFILE
+have_library=$?
+
+# Those options are in section "global {" so we must have one if any are present.
+if [ "$have_type" = "0" -o "$have_dir" = "0" -o "$have_library" = "0" ]
+then
+
+ # See if we can find it...
+ grep -q '^[[:blank:]]*global[[:blank:]]*{' $CONFIGFILE
+ have_global=$?
+
+ if [ "$have_global" = "1" ]
+ then
+ echo "global keys but no 'global {' found, can't edit file"
+ exit 12
+ fi
+fi
+
+# So if we don't have "global {" we need to create one and
+# populate it
+
+if [ "$have_global" = "1" ]
+then
+ if [ "$LOCKING_TYPE" = "2" ]; then
+ cat $CONFIGFILE - <<EOF > $TMPFILE
+global {
+ # Enable locking for cluster LVM
+ locking_type = $LOCKING_TYPE
+ library_dir = "$LOCKINGLIBDIR"
+ locking_library = "$LOCKINGLIB"
+}
+EOF
+ fi # if we aren't setting cluster locking, we don't need to create a global section
+
+ if [ $? != 0 ]
+ then
+ echo "failed to create temporary config file, $CONFIGFILE not updated"
+ exit 1
+ fi
+else
+ #
+ # We have a "global {" section, so add or replace the
+ # locking entries as appropriate
+ #
+
+ if [ "$have_type" = "0" ]
+ then
+ SEDCMD=" s/^[[:blank:]]*locking_type[[:blank:]]*=.*/\ \ \ \ locking_type = $LOCKING_TYPE/g"
+ else
+ SEDCMD=" /global[[:blank:]]*{/a\ \ \ \ locking_type = $LOCKING_TYPE"
+ fi
+
+ if [ "$LOCKING_TYPE" = "2" ]; then
+ if [ "$have_dir" = "0" ]
+ then
+ SEDCMD="${SEDCMD}\ns'^[[:blank:]]*library_dir[[:blank:]]*=.*'\ \ \ \ library_dir = \"$LOCKINGLIBDIR\"'g"
+ else
+ SEDCMD="${SEDCMD}\n/global[[:blank:]]*{/a\ \ \ \ library_dir = \"$LOCKINGLIBDIR\""
+ fi
+
+ if [ "$have_library" = "0" ]
+ then
+ SEDCMD="${SEDCMD}\ns/^[[:blank:]]*locking_library[[:blank:]]*=.*/\ \ \ \ locking_library = \"$LOCKINGLIB\"/g"
+ else
+ SEDCMD="${SEDCMD}\n/global[[:blank:]]*{/a\ \ \ \ locking_library = \"$LOCKINGLIB\""
+ fi
+ else
+ # if we're not using cluster locking, remove the library dir and locking library name
+ if [ "$have_dir" = "0" ]
+ then
+ SEDCMD="${SEDCMD}\n/^[[:blank:]]*library_dir[[:blank:]]*=.*/d"
+ fi
+
+ if [ "$have_library" = "0" ]
+ then
+ SEDCMD="${SEDCMD}\n/^[[:blank:]]*locking_library[[:blank:]]*=.*/d"
+ fi
+ fi
+
+ echo -e $SEDCMD > $SCRIPTFILE
+ sed <$CONFIGFILE >$TMPFILE -f $SCRIPTFILE
+ if [ $? != 0 ]
+ then
+ echo "sed failed, $CONFIGFILE not updated"
+ exit 1
+ fi
+fi
+
+# Now we have a suitably editted config file in a temp place,
+# backup the original and copy our new one into place.
+
+cp $CONFIGFILE $CONFIGFILE.lvmconfold
+if [ $? != 0 ]
+ then
+ echo "failed to backup old config file, $CONFIGFILE not updated"
+ exit 2
+fi
+
+cp $TMPFILE $CONFIGFILE
+if [ $? != 0 ]
+ then
+ echo "failed to copy new config file into place, check $CONFIGFILE is still OK"
+ exit 3
+fi
+
+rm -f $SCRIPTFILE $TMPFILE
Modified: lvm2/upstream/current/tools/Makefile.in
==============================================================================
--- lvm2/upstream/current/tools/Makefile.in (original)
+++ lvm2/upstream/current/tools/Makefile.in Tue Jun 14 11:13:22 2005
@@ -21,10 +21,10 @@
endif
SOURCES =\
- archiver.c \
dumpconfig.c \
formats.c \
lvchange.c \
+ lvconvert.c \
lvcreate.c \
lvdisplay.c \
lvextend.c \
@@ -90,7 +90,7 @@
LVMLIBS += -ldevmapper
endif
-CFLAGS += -DLVM_SHARED_PATH=\"$(sbindir)/lvm\"
+CFLAGS += -DLVM_SHARED_PATH=\"$(exec_prefix)/sbin/lvm\"
include $(top_srcdir)/make.tmpl
Modified: lvm2/upstream/current/tools/args.h
==============================================================================
--- lvm2/upstream/current/tools/args.h (original)
+++ lvm2/upstream/current/tools/args.h Tue Jun 14 11:13:22 2005
@@ -59,6 +59,7 @@
arg(background_ARG, 'b', "background", NULL)
arg(blockdevice_ARG, 'b', "blockdevice", NULL)
arg(chunksize_ARG, 'c', "chunksize", size_kb_arg)
+arg(clustered_ARG, 'c', "clustered", yes_no_arg)
arg(colon_ARG, 'c', "colon", NULL)
arg(columns_ARG, 'C', "columns", NULL)
arg(contiguous_ARG, 'C', "contiguous", yes_no_arg)
@@ -84,6 +85,7 @@
arg(logicalextent_ARG, 'L', "logicalextent", int_arg_with_sign)
arg(persistent_ARG, 'M', "persistent", yes_no_arg)
arg(major_ARG, 'j', "major", major_arg)
+arg(mirrors_ARG, 'm', "mirrors", int_arg)
arg(metadatatype_ARG, 'M', "metadatatype", metadatatype_arg)
arg(maps_ARG, 'm', "maps", NULL)
arg(name_ARG, 'n', "name", string_arg)
@@ -99,6 +101,7 @@
arg(readahead_ARG, 'r', "readahead", int_arg)
arg(resizefs_ARG, 'r', "resizefs", NULL)
arg(reset_ARG, 'R', "reset", NULL)
+arg(regionsize_ARG, 'R', "regionsize", size_mb_arg)
arg(physicalextentsize_ARG, 's', "physicalextentsize", size_mb_arg)
arg(stdin_ARG, 's', "stdin", NULL)
arg(snapshot_ARG, 's', "snapshot", NULL)
Modified: lvm2/upstream/current/tools/commands.h
==============================================================================
--- lvm2/upstream/current/tools/commands.h (original)
+++ lvm2/upstream/current/tools/commands.h Tue Jun 14 11:13:22 2005
@@ -78,6 +78,19 @@
persistent_ARG, readahead_ARG, refresh_ARG, addtag_ARG, deltag_ARG,
test_ARG)
+xx(lvconvert,
+ "Change logical volume layout",
+ "lvconvert " "\n"
+ "\t[--alloc AllocationPolicy]\n"
+ "\t[-d|--debug]\n"
+ "\t[-h|-?|--help]\n"
+ "\t[-m|--mirrors Mirrors]\n"
+ "\t[-v|--verbose]\n"
+ "\t[--version]" "\n"
+ "\tLogicalVolume[Path] [LogicalVolume[Path]...]\n",
+
+ alloc_ARG, mirrors_ARG, test_ARG)
+
xx(lvcreate,
"Create a logical volume",
"lvcreate " "\n"
@@ -91,9 +104,11 @@
"\t{-l|--extents LogicalExtentsNumber |\n"
"\t -L|--size LogicalVolumeSize[kKmMgGtT]}\n"
"\t[-M|--persistent {y|n}] [--major major] [--minor minor]\n"
+ "\t[-m|--mirrors Mirrors]\n"
"\t[-n|--name LogicalVolumeName]\n"
"\t[-p|--permission {r|rw}]\n"
"\t[-r|--readahead ReadAheadSectors]\n"
+ "\t[-R|--regionsize MirrorLogRegionSize]\n"
"\t[-t|--test]\n"
"\t[--type VolumeType]\n"
"\t[-v|--verbose]\n"
@@ -122,13 +137,14 @@
"\tOriginalLogicalVolume[Path] [PhysicalVolumePath...]\n\n",
addtag_ARG, alloc_ARG, autobackup_ARG, chunksize_ARG, contiguous_ARG,
- extents_ARG, major_ARG, minor_ARG, name_ARG, permission_ARG,
- persistent_ARG, readahead_ARG, size_ARG, snapshot_ARG, stripes_ARG,
- stripesize_ARG, test_ARG, type_ARG, zero_ARG)
+ extents_ARG, major_ARG, minor_ARG, mirrors_ARG, name_ARG, permission_ARG,
+ persistent_ARG, readahead_ARG, regionsize_ARG, size_ARG, snapshot_ARG,
+ stripes_ARG, stripesize_ARG, test_ARG, type_ARG, zero_ARG)
xx(lvdisplay,
"Display information about a logical volume",
"lvdisplay\n"
+ "\t[-a|--all]\n"
"\t[-c|--colon]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
@@ -143,6 +159,7 @@
"\n"
"lvdisplay --columns|-C\n"
"\t[--aligned]\n"
+ "\t[-a|--all]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
@@ -159,9 +176,10 @@
"\t[--version]" "\n"
"\t[LogicalVolume[Path] [LogicalVolume[Path]...]]\n",
- aligned_ARG, colon_ARG, columns_ARG, disk_ARG, ignorelockingfailure_ARG,
- maps_ARG, noheadings_ARG, nosuffix_ARG, options_ARG, sort_ARG,
- partial_ARG, segments_ARG, separator_ARG, unbuffered_ARG, units_ARG)
+ aligned_ARG, all_ARG, colon_ARG, columns_ARG, disk_ARG,
+ ignorelockingfailure_ARG, maps_ARG, noheadings_ARG, nosuffix_ARG,
+ options_ARG, sort_ARG, partial_ARG, segments_ARG, separator_ARG,
+ unbuffered_ARG, units_ARG)
xx(lvextend,
"Add space to a logical volume",
@@ -173,6 +191,7 @@
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
"\t{-l|--extents [+]LogicalExtentsNumber |\n"
"\t -L|--size [+]LogicalVolumeSize[kKmMgGtT]}\n"
+ "\t[-m|--mirrors Mirrors]\n"
"\t[-n|--nofsck]\n"
"\t[-r|--resizefs]\n"
"\t[-t|--test]\n"
@@ -181,8 +200,9 @@
"\t[--version]" "\n"
"\tLogicalVolume[Path] [ PhysicalVolumePath... ]\n",
- alloc_ARG, autobackup_ARG, extents_ARG, nofsck_ARG, resizefs_ARG,
- size_ARG, stripes_ARG, stripesize_ARG, test_ARG, type_ARG)
+ alloc_ARG, autobackup_ARG, extents_ARG, mirrors_ARG, nofsck_ARG,
+ resizefs_ARG, size_ARG, stripes_ARG, stripesize_ARG, test_ARG,
+ type_ARG)
xx(lvmchange,
"With the device mapper, this is obsolete and does nothing.",
@@ -298,6 +318,7 @@
xx(lvs,
"Display information about logical volumes",
"lvs" "\n"
+ "\t[-a|--all]\n"
"\t[--aligned]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
@@ -315,9 +336,9 @@
"\t[--version]" "\n"
"\t[LogicalVolume[Path] [LogicalVolume[Path]...]]\n",
- aligned_ARG, ignorelockingfailure_ARG, noheadings_ARG, nolocking_ARG,
- nosuffix_ARG, options_ARG, partial_ARG, segments_ARG, separator_ARG,
- sort_ARG, unbuffered_ARG, units_ARG)
+ 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)
xx(lvscan,
"List all logical volumes in all volume groups",
@@ -410,6 +431,7 @@
"\n"
"pvdisplay --columns|-C\n"
"\t[--aligned]\n"
+ "\t[-a|--all]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
@@ -424,9 +446,9 @@
"\t[--version]" "\n"
"\t[PhysicalVolumePath [PhysicalVolumePath...]]\n",
- aligned_ARG, colon_ARG, columns_ARG, ignorelockingfailure_ARG, maps_ARG,
- noheadings_ARG, nosuffix_ARG, options_ARG, separator_ARG, short_ARG,
- sort_ARG, unbuffered_ARG, units_ARG)
+ aligned_ARG, all_ARG, colon_ARG, columns_ARG, ignorelockingfailure_ARG,
+ maps_ARG, noheadings_ARG, nosuffix_ARG, options_ARG, separator_ARG,
+ short_ARG, sort_ARG, unbuffered_ARG, units_ARG)
xx(pvmove,
"Move extents from one physical volume to another",
@@ -490,6 +512,7 @@
"\t[--nosuffix]\n"
"\t[-o|--options [+]Field[,Field]]\n"
"\t[-O|--sort [+|-]key1[,[+|-]key2[,...]]]\n"
+ "\t[--segments]\n"
"\t[--separator Separator]\n"
"\t[--unbuffered]\n"
"\t[--units hsbkmgtHKMGT]\n"
@@ -498,8 +521,8 @@
"\t[PhysicalVolume [PhysicalVolume...]]\n",
aligned_ARG, all_ARG, ignorelockingfailure_ARG, noheadings_ARG,
- nolocking_ARG, nosuffix_ARG, options_ARG, separator_ARG, sort_ARG,
- unbuffered_ARG, units_ARG)
+ nolocking_ARG, nosuffix_ARG, options_ARG, segments_ARG, separator_ARG,
+ sort_ARG, unbuffered_ARG, units_ARG)
xx(pvscan,
"List all physical volumes",
@@ -565,15 +588,18 @@
"\t[-v|--verbose] " "\n"
"\t[--version]" "\n"
"\t{-a|--available [e|l]{y|n} |" "\n"
+ "\t -c|--clustered {y|n} |" "\n"
"\t -x|--resizeable {y|n} |" "\n"
"\t -l|--logicalvolume MaxLogicalVolumes |" "\n"
+ "\t -s|--physicalextentsize PhysicalExtentSize[kKmMgGtT] |" "\n"
"\t --addtag Tag |\n"
"\t --deltag Tag}\n"
"\t[VolumeGroupName...]\n",
addtag_ARG, alloc_ARG, allocation_ARG, autobackup_ARG, available_ARG,
- deltag_ARG, ignorelockingfailure_ARG, logicalvolume_ARG, partial_ARG,
- resizeable_ARG, resizable_ARG, test_ARG, uuid_ARG)
+ clustered_ARG, deltag_ARG, ignorelockingfailure_ARG, logicalvolume_ARG,
+ partial_ARG, physicalextentsize_ARG, resizeable_ARG, resizable_ARG,
+ test_ARG, uuid_ARG)
xx(vgck,
"Check the consistency of volume group(s)",
@@ -607,6 +633,7 @@
"\t[-A|--autobackup {y|n}] " "\n"
"\t[--addtag Tag] " "\n"
"\t[--alloc AllocationPolicy] " "\n"
+ "\t[-c|--clustered] " "\n"
"\t[-d|--debug]" "\n"
"\t[-h|--help]" "\n"
"\t[-l|--maxlogicalvolumes MaxLogicalVolumes]" "\n"
@@ -618,7 +645,7 @@
"\t[--version] " "\n"
"\tVolumeGroupName PhysicalVolume [PhysicalVolume...]\n",
- addtag_ARG, alloc_ARG, autobackup_ARG, maxlogicalvolumes_ARG,
+ addtag_ARG, alloc_ARG, autobackup_ARG, clustered_ARG, maxlogicalvolumes_ARG,
maxphysicalvolumes_ARG, metadatatype_ARG, physicalextentsize_ARG, test_ARG)
xx(vgdisplay,
@@ -714,9 +741,12 @@
"vgmknodes\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
+ "\t[--ignorelockingfailure]\n"
"\t[-v|--verbose]\n"
"\t[--version]" "\n"
- "\t[VolumeGroupName...]\n" )
+ "\t[VolumeGroupName...]\n",
+
+ ignorelockingfailure_ARG)
xx(vgreduce,
"Remove physical volume(s) from a volume group",
@@ -764,6 +794,7 @@
"Display information about volume groups",
"vgs" "\n"
"\t[--aligned]\n"
+ "\t[-a|--all]\n"
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
@@ -779,9 +810,9 @@
"\t[--version]\n"
"\t[VolumeGroupName [VolumeGroupName...]]\n",
- aligned_ARG, ignorelockingfailure_ARG, noheadings_ARG, nolocking_ARG,
- nosuffix_ARG, options_ARG, partial_ARG, separator_ARG, sort_ARG,
- unbuffered_ARG, units_ARG)
+ aligned_ARG, all_ARG, ignorelockingfailure_ARG, noheadings_ARG,
+ nolocking_ARG, nosuffix_ARG, options_ARG, partial_ARG, separator_ARG,
+ sort_ARG, unbuffered_ARG, units_ARG)
xx(vgscan,
"Search for all volume groups",
Modified: lvm2/upstream/current/tools/lvchange.c
==============================================================================
--- lvm2/upstream/current/tools/lvchange.c (original)
+++ lvm2/upstream/current/tools/lvchange.c Tue Jun 14 11:13:22 2005
@@ -94,6 +94,12 @@
return 0;
}
} else {
+ if (lockingfailed() && (lv->vg->status & CLUSTERED)) {
+ log_verbose("Locking failed: ignoring clustered "
+ "logical volume %s", lv->name);
+ return 0;
+ }
+
if (lv_is_origin(lv) || (activate == CHANGE_AE)) {
log_verbose("Activating logical volume \"%s\" "
"exclusively", lv->name);
@@ -361,6 +367,7 @@
return 1;
}
+
static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
void *handle)
{
@@ -398,6 +405,23 @@
return ECMD_FAILED;
}
+ if (lv->status & MIRROR_LOG) {
+ log_error("Unable to change mirror log LV %s directly", lv->name);
+ return ECMD_FAILED;
+ }
+
+ if (lv->status & MIRROR_IMAGE) {
+ log_error("Unable to change mirror image LV %s directly",
+ lv->name);
+ return ECMD_FAILED;
+ }
+
+ if (!(lv->status & VISIBLE_LV)) {
+ log_error("Unable to change internal LV %s directly",
+ lv->name);
+ return ECMD_FAILED;
+ }
+
/* access permission change */
if (arg_count(cmd, permission_ARG)) {
if (!archive(lv->vg))
Added: lvm2/upstream/current/tools/lvconvert.c
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/tools/lvconvert.c Tue Jun 14 11:13:22 2005
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 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
+ */
+
+#include "tools.h"
+
+struct lvconvert_params {
+ struct list *pvh;
+};
+
+static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * lv,
+ struct list *allocatable_pvs)
+{
+ struct lv_segment *first_seg;
+ uint32_t mirrors, existing_mirrors;
+ alloc_policy_t alloc = ALLOC_INHERIT;
+ // struct alloc_handle *ah = NULL;
+ // struct logical_volume *log_lv;
+
+ if (arg_count(cmd, alloc_ARG))
+ alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, alloc);
+
+ mirrors = arg_uint_value(cmd, mirrors_ARG, 0) + 1;
+
+ if ((mirrors == 1)) {
+ if (!(lv->status & MIRRORED)) {
+ log_error("Logical volume %s is already not mirrored.",
+ lv->name);
+ return 1;
+ }
+ /* FIXME If allocatable_pvs supplied only remove those */
+ if (!remove_all_mirror_images(lv)) {
+ stack;
+ return 0;
+ }
+ } else { /* mirrors > 1 */
+ if ((lv->status & MIRRORED)) {
+ if (list_size(&lv->segments) != 1) {
+ log_error("Logical volume %s has multiple "
+ "mirror segments.", lv->name);
+ return 0;
+ }
+ list_iterate_items(first_seg, &lv->segments)
+ break;
+ existing_mirrors = first_seg->area_count;
+ if (mirrors == existing_mirrors) {
+ log_error("Logical volume %s already has %"
+ PRIu32 " mirror(s).", lv->name,
+ mirrors - 1);
+ return 1;
+ }
+ if (mirrors > existing_mirrors) {
+ /* FIXME Unless anywhere, remove PV of log_lv
+ * from allocatable_pvs & allocate
+ * (mirrors - existing_mirrors) new areas
+ */
+ /* FIXME Create mirror hierarchy to sync */
+ log_error("Adding mirror images is not "
+ "supported yet.");
+ return 0;
+ } else {
+ if (!remove_mirror_images(first_seg, mirrors)) {
+ stack;
+ return 0;
+ }
+ }
+ } else {
+ /* FIXME Share code with lvcreate */
+ /* region size, log_name, create log_lv, zero it */
+ // Allocate (mirrors) new areas & log - replace mirrored_pv with mirrored_lv
+ // Restructure as mirror - add existing param to create_mirror_layers
+ log_error("Adding mirror images is not supported yet.");
+ return 0;
+ }
+ }
+
+ log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
+
+ if (!vg_write(lv->vg)) {
+ stack;
+ return 0;
+ }
+
+ backup(lv->vg);
+
+ if (!suspend_lv(cmd, lv->lvid.s)) {
+ log_error("Failed to lock %s", lv->name);
+ vg_revert(lv->vg);
+ return 0;
+ }
+
+ if (!vg_commit(lv->vg)) {
+ resume_lv(cmd, lv->lvid.s);
+ return 0;
+ }
+
+ log_very_verbose("Updating \"%s\" in kernel", lv->name);
+
+ if (!resume_lv(cmd, lv->lvid.s)) {
+ log_error("Problem reactivating %s", lv->name);
+ return 0;
+ }
+
+ log_print("Logical volume %s converted.", lv->name);
+
+ return 1;
+}
+
+static int lvconvert_single(struct cmd_context * cmd, struct logical_volume * lv,
+ int argc, char **argv, void *handle)
+{
+ struct lvconvert_params *lp = handle;
+
+ if (lv->status & LOCKED) {
+ log_error("Cannot convert locked LV %s", lv->name);
+ return ECMD_FAILED;
+ }
+
+ if (lv_is_origin(lv)) {
+ log_error("Can't convert logical volume \"%s\" under snapshot",
+ lv->name);
+ return ECMD_FAILED;
+ }
+
+ if (lv_is_cow(lv)) {
+ log_error("Can't convert snapshot logical volume \"%s\"",
+ lv->name);
+ return ECMD_FAILED;
+ }
+
+ if (lv->status & PVMOVE) {
+ log_error("Unable to convert pvmove LV %s", lv->name);
+ return ECMD_FAILED;
+ }
+
+ if (arg_count(cmd, mirrors_ARG)) {
+ if (!archive(lv->vg))
+ return ECMD_FAILED;
+ if (!lvconvert_mirrors(cmd, lv, lp->pvh))
+ return ECMD_FAILED;
+ }
+
+ return ECMD_PROCESSED;
+}
+
+int lvconvert(struct cmd_context * cmd, int argc, char **argv)
+{
+ const char *vg_name, *lv_name;
+ char *st;
+ int consistent = 1;
+ struct volume_group *vg;
+ struct lv_list *lvl;
+ struct lvconvert_params lp;
+ int ret = ECMD_FAILED;
+
+ if (!arg_count(cmd, mirrors_ARG)) {
+ log_error("--mirrors argument required");
+ return EINVALID_CMD_LINE;
+ }
+
+ if (!argc) {
+ log_error("Please give logical volume path(s)");
+ return EINVALID_CMD_LINE;
+ }
+
+ lv_name = argv[0];
+ argv++, argc--;
+
+ vg_name = extract_vgname(cmd, lv_name);
+
+ if (!validate_name(vg_name)) {
+ log_error("Please provide a valid volume group name");
+ return EINVALID_CMD_LINE;
+ }
+
+ if ((st = strrchr(lv_name, '/')))
+ lv_name = st + 1;
+
+ log_verbose("Checking for existing volume group \"%s\"", vg_name);
+
+ if (!lock_vol(cmd, vg_name, LCK_VG_WRITE)) {
+ log_error("Can't get lock for %s", vg_name);
+ return ECMD_FAILED;
+ }
+
+ if (!(vg = vg_read(cmd, vg_name, &consistent))) {
+ log_error("Volume group \"%s\" doesn't exist", vg_name);
+ goto error;
+ }
+
+ if (vg->status & EXPORTED_VG) {
+ log_error("Volume group \"%s\" is exported", vg_name);
+ goto error;
+ }
+
+ if (!(vg->status & LVM_WRITE)) {
+ log_error("Volume group \"%s\" is read-only", vg_name);
+ goto error;
+ }
+
+ if (!(lvl = find_lv_in_vg(vg, lv_name))) {
+ log_error("Logical volume \"%s\" not found in "
+ "volume group \"%s\"", lv_name, vg_name);
+ goto error;
+ }
+
+ if (argc) {
+ if (!(lp.pvh = create_pv_list(cmd->mem, vg, argc, argv, 1))) {
+ stack;
+ goto error;
+ }
+ } else
+ lp.pvh = &vg->pvs;
+
+ ret = lvconvert_single(cmd, lvl->lv, argc, argv, &lp);
+
+error:
+ unlock_vg(cmd, vg_name);
+ return ret;
+}
Modified: lvm2/upstream/current/tools/lvcreate.c
==============================================================================
--- lvm2/upstream/current/tools/lvcreate.c (original)
+++ lvm2/upstream/current/tools/lvcreate.c Tue Jun 14 11:13:22 2005
@@ -14,6 +14,7 @@
*/
#include "tools.h"
+#include "lv_alloc.h"
#include <fcntl.h>
@@ -31,6 +32,7 @@
uint32_t stripes;
uint32_t stripe_size;
uint32_t chunk_size;
+ uint32_t region_size;
uint32_t mirrors;
@@ -135,10 +137,8 @@
if ((ptr = strrchr(lp->lv_name, '/')))
lp->lv_name = ptr + 1;
- /* FIXME Remove this restriction eventually */
- if (!strncmp(lp->lv_name, "snapshot", 8)) {
- log_error("Names starting \"snapshot\" are reserved. "
- "Please choose a different LV name.");
+ if (!apply_lvname_restrictions(lp->lv_name)) {
+ stack;
return 0;
}
@@ -228,6 +228,38 @@
return 1;
}
+static int _read_mirror_params(struct lvcreate_params *lp,
+ struct cmd_context *cmd,
+ int *pargc, char ***pargv)
+{
+ int argc = *pargc;
+
+ if (argc && (unsigned) argc < lp->mirrors) {
+ log_error("Too few physical volumes on "
+ "command line for %d-way mirroring", lp->mirrors);
+ return 0;
+ }
+
+ if (arg_count(cmd, regionsize_ARG)) {
+ if (arg_sign_value(cmd, regionsize_ARG, 0) == SIGN_MINUS) {
+ log_error("Negative regionsize is invalid");
+ return 0;
+ }
+ lp->region_size = 2 * arg_uint_value(cmd, regionsize_ARG, 0);
+ } else
+ lp->region_size = 2 * find_config_int(cmd->cft->root,
+ "activation/mirror_region_size",
+ DEFAULT_MIRROR_REGION_SIZE);
+
+ if (lp->region_size & (lp->region_size - 1)) {
+ log_error("Region size (%" PRIu32 ") must be a power of 2",
+ lp->region_size);
+ return 0;
+ }
+
+ return 1;
+}
+
static int _read_params(struct lvcreate_params *lp, struct cmd_context *cmd,
int argc, char **argv)
{
@@ -246,9 +278,21 @@
if (arg_count(cmd, stripes_ARG) && lp->stripes == 1)
log_print("Redundant stripes argument: default is 1");
- if (arg_count(cmd, snapshot_ARG) || (lp->segtype->flags & SEG_SNAPSHOT))
+ if (arg_count(cmd, snapshot_ARG) || seg_is_snapshot(lp))
lp->snapshot = 1;
+ lp->mirrors = 1;
+
+ /* Default to 2 mirrored areas if --type mirror */
+ if (seg_is_mirrored(lp))
+ lp->mirrors = 2;
+
+ if (arg_count(cmd, mirrors_ARG)) {
+ lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 0) + 1;
+ if (lp->mirrors == 1)
+ log_print("Redundant mirrors argument: default is 0");
+ }
+
if (lp->snapshot) {
if (arg_count(cmd, zero_ARG)) {
log_error("-Z is incompatible with snapshots");
@@ -272,6 +316,25 @@
}
}
+ if (lp->mirrors > 1) {
+ if (lp->snapshot) {
+ log_error("mirrors and snapshots are currently "
+ "incompatible");
+ return 0;
+ }
+
+ if (lp->stripes > 1) {
+ log_error("mirrors and stripes are currently "
+ "incompatible");
+ return 0;
+ }
+
+ if (!(lp->segtype = get_segtype_from_string(cmd, "mirror"))) {
+ stack;
+ return 0;
+ }
+ }
+
if (activation() && lp->segtype->ops->target_present &&
!lp->segtype->ops->target_present()) {
log_error("%s: Required device-mapper target(s) not "
@@ -281,8 +344,11 @@
if (!_read_name_params(lp, cmd, &argc, &argv) ||
!_read_size_params(lp, cmd, &argc, &argv) ||
- !_read_stripe_params(lp, cmd, &argc, &argv))
+ !_read_stripe_params(lp, cmd, &argc, &argv) ||
+ !_read_mirror_params(lp, cmd, &argc, &argv)) {
+ stack;
return 0;
+ }
/*
* Should we zero the lv.
@@ -392,14 +458,18 @@
static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
{
- uint32_t size_rest;
+ uint32_t size_rest, region_max;
uint32_t status = 0;
uint64_t tmp_size;
struct volume_group *vg;
- struct logical_volume *lv, *org = NULL;
+ struct logical_volume *lv, *org = NULL, *log_lv = NULL;
struct list *pvh;
const char *tag;
int consistent = 1;
+ struct alloc_handle *ah = NULL;
+ char *log_name, lv_name_buf[128];
+ const char *lv_name;
+ size_t len;
status |= lp->permission | VISIBLE_LV;
@@ -427,6 +497,11 @@
return 0;
}
+ if (lp->mirrors && !(vg->fid->fmt->features & FMT_SEGMENTS)) {
+ log_error("Metadata does not support mirroring.");
+ return 0;
+ }
+
/*
* Create the pv list.
*/
@@ -498,32 +573,139 @@
return 0;
}
- if (!(lp->segtype->flags & SEG_VIRTUAL) &&
+ if (!seg_is_virtual(lp) &&
vg->free_count < lp->extents) {
log_error("Insufficient free extents (%u) in volume group %s: "
"%u required", vg->free_count, vg->name, lp->extents);
return 0;
}
- if (lp->stripes > list_size(pvh)) {
+ if (lp->stripes > list_size(pvh) && lp->alloc != ALLOC_ANYWHERE) {
log_error("Number of stripes (%u) must not exceed "
"number of physical volumes (%d)", lp->stripes,
list_size(pvh));
return 0;
}
- if (!(lv = lv_create_empty(vg->fid, lp->lv_name, "lvol%d",
- status, lp->alloc, vg))) {
- stack;
+ if (lp->mirrors > 1 && !activation()) {
+ log_error("Can't create mirror without using "
+ "device-mapper kernel driver.");
return 0;
}
- if (!lv_extend(vg->fid, lv, lp->segtype, lp->stripes, lp->stripe_size,
- lp->mirrors, lp->extents, NULL, 0u, 0u, pvh, lp->alloc)) {
+ /* The snapshot segment gets created later */
+ if (lp->snapshot &&
+ !(lp->segtype = get_segtype_from_string(cmd, "striped"))) {
stack;
return 0;
}
+ if (!archive(vg))
+ return 0;
+
+ if (lp->lv_name)
+ lv_name = lp->lv_name;
+ else {
+ if (!generate_lv_name(vg, "lvol%d", lv_name_buf, sizeof(lv_name_buf))) {
+ log_error("Failed to generate LV name.");
+ return 0;
+ }
+ lv_name = &lv_name_buf[0];
+ }
+
+ if (lp->mirrors > 1) {
+ /* FIXME Adjust lp->region_size if necessary */
+ region_max = (1 << (ffs(lp->extents) - 1)) * vg->extent_size;
+
+ if (region_max < lp->region_size) {
+ lp->region_size = region_max;
+ log_print("Using reduced mirror region size of %" PRIu32
+ " sectors", lp->region_size);
+ }
+
+ /* FIXME Calculate how many extents needed for the log */
+
+ len = strlen(lv_name) + 32;
+ if (!(log_name = alloca(len))) {
+ log_error("log_name allocation failed. "
+ "Remove new LV and retry.");
+ return 0;
+ }
+
+ if (lvm_snprintf(log_name, len, "%s_mlog", lv_name) < 0) {
+ log_error("log_name allocation failed. "
+ "Remove new LV and retry.");
+ return 0;
+ }
+
+ if (find_lv_in_vg(vg, log_name)) {
+ if (lvm_snprintf(log_name, len, "%s_mlog_%%d",
+ lv_name) < 0) {
+ log_error("log_name allocation failed. "
+ "Remove new LV and retry.");
+ return 0;
+ }
+ }
+
+ if (!(log_lv = lv_create_empty(vg->fid, log_name, NULL,
+ VISIBLE_LV | LVM_READ | LVM_WRITE,
+ lp->alloc, 0, vg))) {
+ stack;
+ return 0;
+ }
+
+ if (!(ah = allocate_extents(vg, NULL, lp->segtype, lp->stripes,
+ lp->mirrors, 1, lp->extents,
+ NULL, 0, 0, pvh, lp->alloc))) {
+ stack;
+ return 0;
+ }
+
+ if (!lv_add_log_segment(ah, log_lv)) {
+ stack;
+ goto error;
+ }
+
+ /* store mirror log on disk(s) */
+ if (!vg_write(vg)) {
+ stack;
+ goto error;
+ }
+
+ backup(vg);
+
+ if (!vg_commit(vg)) {
+ stack;
+ goto error;
+ }
+
+ if (!activate_lv(cmd, log_lv->lvid.s)) {
+ log_error("Aborting. Failed to activate mirror log. "
+ "Remove new LVs and retry.");
+ goto error;
+ }
+
+ if (activation() && !_zero_lv(cmd, log_lv)) {
+ log_error("Aborting. Failed to wipe mirror log. "
+ "Remove new LV and retry.");
+ goto error;
+ }
+
+ if (!deactivate_lv(cmd, log_lv->lvid.s)) {
+ log_error("Aborting. Failed to deactivate mirror log. "
+ "Remove new LV and retry.");
+ goto error;
+ }
+
+ log_lv->status &= ~VISIBLE_LV;
+ }
+
+ if (!(lv = lv_create_empty(vg->fid, lv_name ? lv_name : "lvol%d", NULL,
+ status, lp->alloc, 0, vg))) {
+ stack;
+ goto error;
+ }
+
if (lp->read_ahead) {
log_verbose("Setting read ahead sectors");
lv->read_ahead = lp->read_ahead;
@@ -540,24 +722,37 @@
if (arg_count(cmd, addtag_ARG)) {
if (!(tag = arg_str_value(cmd, addtag_ARG, NULL))) {
log_error("Failed to get tag");
- return 0;
+ goto error;
}
if (!(lv->vg->fid->fmt->features & FMT_TAGS)) {
log_error("Volume group %s does not support tags",
lv->vg->name);
- return 0;
+ goto error;
}
if (!str_list_add(cmd->mem, &lv->tags, tag)) {
log_error("Failed to add tag %s to %s/%s",
tag, lv->vg->name, lv->name);
- return 0;
+ goto error;
}
}
- if (!archive(vg))
+ if (lp->mirrors > 1) {
+ if (!create_mirror_layers(ah, 0, lp->mirrors, lv,
+ lp->segtype, 0,
+ lp->region_size, log_lv)) {
+ stack;
+ goto error;
+ }
+
+ alloc_destroy(ah);
+ ah = NULL;
+ } else if (!lv_extend(lv, lp->segtype, lp->stripes, lp->stripe_size,
+ lp->mirrors, lp->extents, NULL, 0u, 0u, pvh, lp->alloc)) {
+ stack;
return 0;
+ }
/* store vg on disk(s) */
if (!vg_write(vg)) {
@@ -609,8 +804,8 @@
return 0;
}
- if (!vg_add_snapshot(org, lv, 1, NULL, org->le_count,
- lp->chunk_size)) {
+ if (!vg_add_snapshot(vg->fid, NULL, org, lv, NULL,
+ org->le_count, lp->chunk_size)) {
log_err("Couldn't create snapshot.");
return 0;
}
@@ -635,6 +830,11 @@
*/
return 1;
+
+error:
+ if (ah)
+ alloc_destroy(ah);
+ return 0;
}
int lvcreate(struct cmd_context *cmd, int argc, char **argv)
Modified: lvm2/upstream/current/tools/lvdisplay.c
==============================================================================
--- lvm2/upstream/current/tools/lvdisplay.c (original)
+++ lvm2/upstream/current/tools/lvdisplay.c Tue Jun 14 11:13:22 2005
@@ -18,6 +18,9 @@
static int _lvdisplay_single(struct cmd_context *cmd, struct logical_volume *lv,
void *handle)
{
+ if (!arg_count(cmd, all_ARG) && !(lv->status & VISIBLE_LV))
+ return ECMD_PROCESSED;
+
if (arg_count(cmd, colon_ARG))
lvdisplay_colons(lv);
else {
Modified: lvm2/upstream/current/tools/lvmcmdline.c
==============================================================================
--- lvm2/upstream/current/tools/lvmcmdline.c (original)
+++ lvm2/upstream/current/tools/lvmcmdline.c Tue Jun 14 11:13:22 2005
@@ -54,7 +54,7 @@
*/
struct arg the_args[ARG_COUNT + 1] = {
-#define arg(a, b, c, d) {b, "--" c, d, 0, NULL, 0, 0, INT64_C(0), UINT64_C(0), 0, NULL},
+#define arg(a, b, c, d) {b, "", "--" c, d, 0, NULL, 0, 0, INT64_C(0), UINT64_C(0), 0, NULL},
#include "args.h"
#undef arg
@@ -753,12 +753,13 @@
init_debug(cmd->current_settings.debug);
init_verbose(cmd->current_settings.verbose + VERBOSE_BASE_LEVEL);
init_test(cmd->current_settings.test);
+ init_full_scan_done(0);
init_msg_prefix(cmd->default_settings.msg_prefix);
init_cmd_name(cmd->default_settings.cmd_name);
- archive_enable(cmd->current_settings.archive);
- backup_enable(cmd->current_settings.backup);
+ archive_enable(cmd, cmd->current_settings.archive);
+ backup_enable(cmd, cmd->current_settings.backup);
set_activation(cmd->current_settings.activation);
@@ -911,73 +912,11 @@
srand((unsigned int) time(NULL) + (unsigned int) getpid());
}
-static int _init_backup(struct cmd_context *cmd, struct config_tree *cft)
-{
- uint32_t days, min;
- char default_dir[PATH_MAX];
- const char *dir;
-
- if (!cmd->sys_dir) {
- log_warn("WARNING: Metadata changes will NOT be backed up");
- backup_init("");
- archive_init("", 0, 0);
- return 1;
- }
-
- /* set up archiving */
- cmd->default_settings.archive =
- find_config_bool(cmd->cft->root, "backup/archive",
- DEFAULT_ARCHIVE_ENABLED);
-
- days = (uint32_t) find_config_int(cmd->cft->root, "backup/retain_days",
- DEFAULT_ARCHIVE_DAYS);
-
- min = (uint32_t) find_config_int(cmd->cft->root, "backup/retain_min",
- DEFAULT_ARCHIVE_NUMBER);
-
- if (lvm_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'.",
- cmd->sys_dir, DEFAULT_ARCHIVE_SUBDIR);
- return 0;
- }
-
- dir = find_config_str(cmd->cft->root, "backup/archive_dir",
- default_dir);
-
- if (!archive_init(dir, days, min)) {
- log_debug("backup_init failed.");
- return 0;
- }
-
- /* set up the backup */
- cmd->default_settings.backup =
- find_config_bool(cmd->cft->root, "backup/backup",
- DEFAULT_BACKUP_ENABLED);
-
- if (lvm_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'.",
- cmd->sys_dir, DEFAULT_BACKUP_SUBDIR);
- return 0;
- }
-
- dir = find_config_str(cmd->cft->root, "backup/backup_dir", default_dir);
-
- if (!backup_init(dir)) {
- log_debug("backup_init failed.");
- return 0;
- }
-
- return 1;
-}
-
static void _close_stray_fds(void)
{
struct rlimit rlim;
int fd;
+ int suppress_warnings = 0;
if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
fprintf(stderr, "getrlimit(RLIMIT_NOFILE) failed: %s\n",
@@ -985,8 +924,13 @@
return;
}
+ if (getenv("LVM_SUPPRESS_FD_WARNINGS"))
+ suppress_warnings = 1;
+
for (fd = 3; fd < rlim.rlim_cur; fd++) {
- if (!close(fd))
+ if (suppress_warnings)
+ close(fd);
+ else if (!close(fd))
fprintf(stderr, "File descriptor %d left open\n", fd);
else if (errno != EBADF)
fprintf(stderr, "Close failed on stray file "
@@ -1005,9 +949,6 @@
_init_rand();
- if (!_init_backup(cmd, cmd->cft))
- return NULL;
-
_apply_settings(cmd);
return cmd;
@@ -1025,10 +966,7 @@
static void _fin(struct cmd_context *cmd)
{
- archive_exit();
- backup_exit();
_fin_commands(cmd);
-
destroy_toolcontext(cmd);
}
Modified: lvm2/upstream/current/tools/lvmdiskscan.c
==============================================================================
--- lvm2/upstream/current/tools/lvmdiskscan.c (original)
+++ lvm2/upstream/current/tools/lvmdiskscan.c Tue Jun 14 11:13:22 2005
@@ -34,7 +34,7 @@
struct dev_iter *iter;
struct device *dev;
- if (!(iter = dev_iter_create(filter))) {
+ if (!(iter = dev_iter_create(filter, 1))) {
log_error("dev_iter_create failed");
return 0;
}
@@ -103,7 +103,7 @@
max_len = _get_max_dev_name_len(cmd->filter);
- if (!(iter = dev_iter_create(cmd->filter))) {
+ if (!(iter = dev_iter_create(cmd->filter, 0))) {
log_error("dev_iter_create failed");
return ECMD_FAILED;
}
Modified: lvm2/upstream/current/tools/lvremove.c
==============================================================================
--- lvm2/upstream/current/tools/lvremove.c (original)
+++ lvm2/upstream/current/tools/lvremove.c Tue Jun 14 11:13:22 2005
@@ -34,6 +34,18 @@
return ECMD_FAILED;
}
+ if (lv->status & MIRROR_IMAGE) {
+ log_error("Can't remove logical volume %s used by a mirror",
+ lv->name);
+ return ECMD_FAILED;
+ }
+
+ if (lv->status & MIRROR_LOG) {
+ log_error("Can't remove logical volume %s used as mirror log",
+ lv->name);
+ return ECMD_FAILED;
+ }
+
if (lv->status & LOCKED) {
log_error("Can't remove locked LV %s", lv->name);
return ECMD_FAILED;
@@ -70,14 +82,14 @@
if (lv_is_cow(lv)) {
log_verbose("Removing snapshot %s", lv->name);
- if (!vg_remove_snapshot(lv->vg, lv)) {
+ if (!vg_remove_snapshot(lv)) {
stack;
return ECMD_FAILED;
}
}
log_verbose("Releasing logical volume \"%s\"", lv->name);
- if (!lv_remove(vg, lv)) {
+ if (!lv_remove(lv)) {
log_error("Error releasing logical volume \"%s\"", lv->name);
return ECMD_FAILED;
}
Modified: lvm2/upstream/current/tools/lvrename.c
==============================================================================
--- lvm2/upstream/current/tools/lvrename.c (original)
+++ lvm2/upstream/current/tools/lvrename.c Tue Jun 14 11:13:22 2005
@@ -83,10 +83,8 @@
return ECMD_FAILED;
}
- /* FIXME Remove this restriction eventually */
- if (!strncmp(lv_name_new, "snapshot", 8)) {
- log_error("Names starting \"snapshot\" are reserved. "
- "Please choose a different LV name.");
+ if (!apply_lvname_restrictions(lv_name_new)) {
+ stack;
return ECMD_FAILED;
}
Modified: lvm2/upstream/current/tools/lvresize.c
==============================================================================
--- lvm2/upstream/current/tools/lvresize.c (original)
+++ lvm2/upstream/current/tools/lvresize.c Tue Jun 14 11:13:22 2005
@@ -23,6 +23,7 @@
uint32_t stripes;
uint32_t stripe_size;
+ uint32_t mirrors;
struct segment_type *segtype;
@@ -115,10 +116,11 @@
{
struct volume_group *vg;
struct logical_volume *lv;
- struct snapshot *snap;
+ struct lv_segment *snap_seg;
struct lvinfo info;
uint32_t stripesize_extents = 0;
uint32_t seg_stripes = 0, seg_stripesize = 0, seg_size = 0;
+ uint32_t seg_mirrors = 0;
uint32_t extents_used = 0;
uint32_t size_rest;
alloc_policy_t alloc;
@@ -161,6 +163,13 @@
log_print("Varied striping not supported. Ignoring.");
}
+ if (arg_count(cmd, mirrors_ARG)) {
+ if (vg->fid->fmt->features & FMT_SEGMENTS)
+ lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 1) + 1;
+ else
+ log_print("Mirrors not supported. Ignoring.");
+ }
+
if (arg_count(cmd, stripesize_ARG)) {
if (arg_sign_value(cmd, stripesize_ARG, 0) == SIGN_MINUS) {
log_error("Stripesize may not be negative.");
@@ -171,6 +180,10 @@
stripesize_ARG, 0);
else
log_print("Varied stripesize not supported. Ignoring.");
+ if (lp->mirrors) {
+ log_error("Mirrors and striping cannot be combined yet.");
+ return ECMD_FAILED;
+ }
}
lv = lvl->lv;
@@ -180,11 +193,6 @@
return ECMD_FAILED;
}
- if (lv_is_origin(lv)) {
- log_error("Snapshot origin volumes cannot be resized yet.");
- return ECMD_FAILED;
- }
-
alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, lv->alloc);
if (lp->size) {
@@ -245,7 +253,7 @@
if ((lp->extents > lv->le_count) &&
!(lp->stripes == 1 || (lp->stripes > 1 && lp->stripe_size))) {
list_iterate_items(seg, &lv->segments) {
- if (!(seg->segtype->flags & SEG_AREAS_STRIPED))
+ if (!seg_is_striped(seg))
continue;
sz = seg->stripe_size;
@@ -282,22 +290,48 @@
}
}
+ /* If extending, find mirrors of last segment */
+ if ((lp->extents > lv->le_count)) {
+ list_iterate_back_items(seg, &lv->segments) {
+ if (seg_is_mirrored(seg))
+ seg_mirrors = seg->area_count;
+ else
+ seg_mirrors = 0;
+ break;
+ }
+ if (!arg_count(cmd, mirrors_ARG) && seg_mirrors) {
+ log_print("Extending %" PRIu32 " mirror images.",
+ seg_mirrors);
+ lp->mirrors = seg_mirrors;
+ }
+ if ((arg_count(cmd, mirrors_ARG) || seg_mirrors) &&
+ (lp->mirrors != seg_mirrors)) {
+ log_error("Cannot vary number of mirrors in LV yet.");
+ return EINVALID_CMD_LINE;
+ }
+ }
+
/* If reducing, find stripes, stripesize & size of last segment */
if (lp->extents < lv->le_count) {
extents_used = 0;
- if (lp->stripes || lp->stripe_size)
- log_error("Ignoring stripes and stripesize arguments "
- "when reducing");
+ if (lp->stripes || lp->stripe_size || lp->mirrors)
+ log_error("Ignoring stripes, stripesize and mirrors "
+ "arguments when reducing");
list_iterate_items(seg, &lv->segments) {
seg_extents = seg->len;
- if (seg->segtype->flags & SEG_AREAS_STRIPED) {
+ if (seg_is_striped(seg)) {
seg_stripesize = seg->stripe_size;
seg_stripes = seg->area_count;
}
+ if (seg_is_mirrored(seg))
+ seg_mirrors = seg->area_count;
+ else
+ seg_mirrors = 0;
+
if (lp->extents <= extents_used + seg_extents)
break;
@@ -307,6 +341,7 @@
seg_size = lp->extents - extents_used;
lp->stripe_size = seg_stripesize;
lp->stripes = seg_stripes;
+ lp->mirrors = seg_mirrors;
}
if (lp->stripes > 1 && !lp->stripe_size) {
@@ -352,6 +387,28 @@
lp->resize = LV_EXTEND;
}
+ if (lp->mirrors && activation() &&
+ lv_info(lv, &info, 0) && info.exists) {
+ log_error("Mirrors cannot be resized while active yet.");
+ return ECMD_FAILED;
+ }
+
+ if (lv_is_origin(lv)) {
+ if (lp->resize == LV_REDUCE) {
+ log_error("Snapshot origin volumes cannot be reduced "
+ "in size yet.");
+ return ECMD_FAILED;
+ }
+
+ memset(&info, 0, sizeof(info));
+
+ if (lv_info(lv, &info, 0) && info.exists) {
+ log_error("Snapshot origin volumes can be resized "
+ "only while inactive: try lvchange -an");
+ return ECMD_FAILED;
+ }
+ }
+
if (lp->resize == LV_REDUCE) {
if (lp->argc)
log_print("Ignoring PVs on command line when reducing");
@@ -439,14 +496,14 @@
SIZE_SHORT));
if (lp->resize == LV_REDUCE) {
- if (!lv_reduce(vg->fid, lv, lv->le_count - lp->extents)) {
+ if (!lv_reduce(lv, lv->le_count - lp->extents)) {
stack;
return ECMD_FAILED;
}
- } else if (!lv_extend(vg->fid, lv, lp->segtype, lp->stripes,
- lp->stripe_size, 0u,
- lp->extents - lv->le_count,
- NULL, 0u, 0u, pvh, alloc)) {
+ } else if (!lv_extend(lv, lp->segtype, lp->stripes,
+ lp->stripe_size, lp->mirrors,
+ lp->extents - lv->le_count,
+ NULL, 0u, 0u, pvh, alloc)) {
stack;
return ECMD_FAILED;
}
@@ -460,8 +517,8 @@
backup(vg);
/* If snapshot, must suspend all associated devices */
- if ((snap = find_cow(lv)))
- lock_lvid = snap->origin->lvid.s;
+ if ((snap_seg = find_cow(lv)))
+ lock_lvid = snap_seg->origin->lvid.s;
else
lock_lvid = lv->lvid.s;
Modified: lvm2/upstream/current/tools/polldaemon.c
==============================================================================
--- lvm2/upstream/current/tools/polldaemon.c (original)
+++ lvm2/upstream/current/tools/polldaemon.c Tue Jun 14 11:13:22 2005
@@ -72,6 +72,8 @@
float segment_percent = 0.0, overall_percent = 0.0;
uint32_t event_nr = 0;
+void *x;
+
/* By default, caller should not retry */
*finished = 1;
@@ -97,6 +99,9 @@
else
log_verbose("%s: Moved: %.1f%%", name, overall_percent);
+x = pool_alloc(cmd->mem, 1);
+pool_free(cmd->mem, x);
+
if (segment_percent < 100.0) {
/* The only case the caller *should* try again later */
*finished = 0;
@@ -138,8 +143,11 @@
while (!finished) {
/* FIXME Also needed in vg/lvchange -ay? */
/* FIXME Use alarm for regular intervals instead */
- if (parms->interval && !parms->aborting)
+ if (parms->interval && !parms->aborting) {
sleep(parms->interval);
+ /* Devices might have changed while we slept */
+ init_full_scan_done(0);
+ }
/* Locks the (possibly renamed) VG again */
if (!(vg = parms->poll_fns->get_copy_vg(cmd, name))) {
Modified: lvm2/upstream/current/tools/pvchange.c
==============================================================================
--- lvm2/upstream/current/tools/pvchange.c (original)
+++ lvm2/upstream/current/tools/pvchange.c Tue Jun 14 11:13:22 2005
@@ -24,9 +24,12 @@
struct pv_list *pvl;
struct list mdas;
uint64_t sector;
+ uint32_t orig_pe_alloc_count;
const char *pv_name = dev_name(pv->dev);
const char *tag = NULL;
+ const char *orig_vg_name;
+ char uuid[64];
int consistent = 1;
int allocatable = 0;
@@ -178,6 +181,24 @@
pv_name);
return 0;
}
+ if (!id_write_format(&pv->id, uuid, sizeof(uuid))) {
+ stack;
+ return 0;
+ }
+ log_verbose("Changing uuid of %s to %s.", pv_name, uuid);
+ if (*pv->vg_name) {
+ orig_vg_name = pv->vg_name;
+ orig_pe_alloc_count = pv->pe_alloc_count;
+ pv->vg_name = ORPHAN;
+ pv->pe_alloc_count = 0;
+ if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
+ log_error("pv_write with new uuid failed "
+ "for %s.", pv_name);
+ return 0;
+ }
+ pv->vg_name = orig_vg_name;
+ pv->pe_alloc_count = orig_pe_alloc_count;
+ }
}
log_verbose("Updating physical volume \"%s\"", pv_name);
Modified: lvm2/upstream/current/tools/pvcreate.c
==============================================================================
--- lvm2/upstream/current/tools/pvcreate.c (original)
+++ lvm2/upstream/current/tools/pvcreate.c Tue Jun 14 11:13:22 2005
@@ -63,10 +63,10 @@
/* Is there an md superblock here? */
if (!dev && md_filtering()) {
unlock_vg(cmd, "");
- log_verbose("Wiping cache of LVM-capable devices");
+
persistent_filter_wipe(cmd->filter);
- log_verbose("Wiping internal cache");
lvmcache_destroy();
+
init_md_filtering(0);
if (!lock_vol(cmd, "", LCK_VG_WRITE)) {
log_error("Can't get lock for orphan PVs");
Modified: lvm2/upstream/current/tools/pvdisplay.c
==============================================================================
--- lvm2/upstream/current/tools/pvdisplay.c (original)
+++ lvm2/upstream/current/tools/pvdisplay.c Tue Jun 14 11:13:22 2005
@@ -64,6 +64,7 @@
}
return pvs(cmd, argc, argv);
} else if (arg_count(cmd, aligned_ARG) ||
+ arg_count(cmd, all_ARG) ||
arg_count(cmd, noheadings_ARG) ||
arg_count(cmd, options_ARG) ||
arg_count(cmd, separator_ARG) ||
Modified: lvm2/upstream/current/tools/pvmove.c
==============================================================================
--- lvm2/upstream/current/tools/pvmove.c (original)
+++ lvm2/upstream/current/tools/pvmove.c Tue Jun 14 11:13:22 2005
@@ -140,10 +140,9 @@
struct lv_list *lvl;
/* FIXME Cope with non-contiguous => splitting existing segments */
- /* FIXME Pass 'alloc' down to lv_extend */
- if (!(lv_mirr = lv_create_empty(vg->fid, NULL, "pvmove%d",
+ if (!(lv_mirr = lv_create_empty(vg->fid, "pvmove%d", NULL,
LVM_READ | LVM_WRITE,
- ALLOC_CONTIGUOUS, vg))) {
+ ALLOC_CONTIGUOUS, 0, vg))) {
log_error("Creation of temporary pvmove LV failed");
return NULL;
}
@@ -160,7 +159,8 @@
/* Find segments to be moved and set up mirrors */
list_iterate_items(lvl, &vg->lvs) {
lv = lvl->lv;
- if ((lv == lv_mirr) || (lv_name && strcmp(lv->name, lv_name)))
+ if ((lv == lv_mirr) ||
+ (lv_name && strcmp(lv->name, lv_name)))
continue;
if (lv_is_origin(lv) || lv_is_cow(lv)) {
log_print("Skipping snapshot-related LV %s", lv->name);
@@ -175,7 +175,8 @@
continue;
}
if (!insert_pvmove_mirrors(cmd, lv_mirr, source_pvl, lv,
- allocatable_pvs, *lvs_changed)) {
+ allocatable_pvs, alloc,
+ *lvs_changed)) {
stack;
return NULL;
}
@@ -438,7 +439,7 @@
}
log_verbose("Removing temporary pvmove LV");
- if (!lv_remove(vg, lv_mirr)) {
+ if (!lv_remove(lv_mirr)) {
log_error("ABORTING: Removal of temporary pvmove LV failed");
return 0;
}
Modified: lvm2/upstream/current/tools/pvscan.c
==============================================================================
--- lvm2/upstream/current/tools/pvscan.c (original)
+++ lvm2/upstream/current/tools/pvscan.c Tue Jun 14 11:13:22 2005
@@ -123,10 +123,7 @@
arg_count(cmd, exported_ARG) ?
"of exported volume group(s)" : "in no volume group");
- log_verbose("Wiping cache of LVM-capable devices");
persistent_filter_wipe(cmd->filter);
-
- log_verbose("Wiping internal cache");
lvmcache_destroy();
log_verbose("Walking through all physical volumes");
Modified: lvm2/upstream/current/tools/reporter.c
==============================================================================
--- lvm2/upstream/current/tools/reporter.c (original)
+++ lvm2/upstream/current/tools/reporter.c Tue Jun 14 11:13:22 2005
@@ -24,16 +24,21 @@
return ECMD_FAILED;
}
- if (!report_object(handle, vg, NULL, NULL, NULL))
+ if (!report_object(handle, vg, NULL, NULL, NULL, NULL))
return ECMD_FAILED;
+ check_current_backup(vg);
+
return ECMD_PROCESSED;
}
static int _lvs_single(struct cmd_context *cmd, struct logical_volume *lv,
void *handle)
{
- if (!report_object(handle, lv->vg, lv, NULL, NULL))
+ if (!arg_count(cmd, all_ARG) && !(lv->status & VISIBLE_LV))
+ return ECMD_PROCESSED;
+
+ if (!report_object(handle, lv->vg, lv, NULL, NULL, NULL))
return ECMD_FAILED;
return ECMD_PROCESSED;
@@ -42,18 +47,53 @@
static int _segs_single(struct cmd_context *cmd, struct lv_segment *seg,
void *handle)
{
- if (!report_object(handle, seg->lv->vg, seg->lv, NULL, seg))
+ if (!report_object(handle, seg->lv->vg, seg->lv, NULL, seg, NULL))
return ECMD_FAILED;
return ECMD_PROCESSED;
}
+static int _pvsegs_sub_single(struct cmd_context *cmd, struct volume_group *vg,
+ struct pv_segment *pvseg, void *handle)
+{
+ int consistent = 0;
+ struct physical_volume *pv = pvseg->pv;
+ int ret = ECMD_PROCESSED;
+
+ if (!lock_vol(cmd, pv->vg_name, LCK_VG_READ)) {
+ log_error("Can't lock %s: skipping", pv->vg_name);
+ return ECMD_FAILED;
+ }
+
+ if (!(vg = vg_read(cmd, pv->vg_name, &consistent))) {
+ log_error("Can't read %s: skipping", pv->vg_name);
+ unlock_vg(cmd, pv->vg_name);
+ return ECMD_FAILED;
+ }
+
+ if (!report_object(handle, vg, NULL, pv, NULL, pvseg))
+ ret = ECMD_FAILED;
+
+ unlock_vg(cmd, pv->vg_name);
+ return ret;
+}
+
static int _lvsegs_single(struct cmd_context *cmd, struct logical_volume *lv,
void *handle)
{
+ if (!arg_count(cmd, all_ARG) && !(lv->status & VISIBLE_LV))
+ return ECMD_PROCESSED;
+
return process_each_segment_in_lv(cmd, lv, handle, _segs_single);
}
+static int _pvsegs_single(struct cmd_context *cmd, struct volume_group *vg,
+ struct physical_volume *pv, void *handle)
+{
+ return process_each_segment_in_pv(cmd, vg, pv, handle,
+ _pvsegs_sub_single);
+}
+
static int _pvs_single(struct cmd_context *cmd, struct volume_group *vg,
struct physical_volume *pv, void *handle)
{
@@ -73,7 +113,7 @@
}
}
- if (!report_object(handle, vg, NULL, pv, NULL))
+ if (!report_object(handle, vg, NULL, pv, NULL, NULL))
ret = ECMD_FAILED;
if (pv->vg_name)
@@ -151,6 +191,18 @@
"report/segs_cols_verbose",
DEFAULT_SEGS_COLS_VERB);
break;
+ case PVSEGS:
+ keys = find_config_str(cmd->cft->root, "report/pvsegs_sort",
+ DEFAULT_PVSEGS_SORT);
+ if (!arg_count(cmd, verbose_ARG))
+ options = find_config_str(cmd->cft->root,
+ "report/pvsegs_cols",
+ DEFAULT_PVSEGS_COLS);
+ else
+ options = find_config_str(cmd->cft->root,
+ "report/pvsegs_cols_verbose",
+ DEFAULT_PVSEGS_COLS_VERB);
+ break;
}
/* If -o supplied use it, else use default for report_type */
@@ -208,6 +260,10 @@
r = process_each_lv(cmd, argc, argv, LCK_VG_READ, report_handle,
&_lvsegs_single);
break;
+ case PVSEGS:
+ r = process_each_pv(cmd, argc, argv, NULL, report_handle,
+ &_pvsegs_single);
+ break;
}
report_output(report_handle);
@@ -235,5 +291,12 @@
int pvs(struct cmd_context *cmd, int argc, char **argv)
{
- return _report(cmd, argc, argv, PVS);
+ report_type_t type;
+
+ if (arg_count(cmd, segments_ARG))
+ type = PVSEGS;
+ else
+ type = PVS;
+
+ return _report(cmd, argc, argv, type);
}
Modified: lvm2/upstream/current/tools/toollib.c
==============================================================================
--- lvm2/upstream/current/tools/toollib.c (original)
+++ lvm2/upstream/current/tools/toollib.c Tue Jun 14 11:13:22 2005
@@ -60,6 +60,9 @@
}
list_iterate_items(lvl, &vg->lvs) {
+ if (lvl->lv->status & SNAPSHOT)
+ continue;
+
/* Should we process this LV? */
if (process_all)
process_lv = 1;
@@ -107,9 +110,9 @@
int ret = 0;
int consistent;
- struct list *slh, *tags_arg;
+ struct list *tags_arg;
struct list *vgnames; /* VGs to process */
- struct str_list *sll;
+ struct str_list *sll, *strl;
struct volume_group *vg;
struct list tags, lvnames;
struct list arg_lvnames; /* Cmdline vgname or vgname/lvname */
@@ -225,8 +228,8 @@
}
}
- list_iterate(slh, vgnames) {
- vgname = list_item(slh, struct str_list)->str;
+ list_iterate_items(strl, vgnames) {
+ vgname = strl->str;
if (!vgname || !*vgname)
continue; /* FIXME Unnecessary? */
if (!lock_vol(cmd, vgname, lock_type)) {
@@ -285,6 +288,28 @@
return ret_max;
}
+int process_each_segment_in_pv(struct cmd_context *cmd,
+ struct volume_group *vg,
+ struct physical_volume *pv,
+ void *handle,
+ int (*process_single) (struct cmd_context * cmd,
+ struct volume_group * vg,
+ struct pv_segment * pvseg,
+ void *handle))
+{
+ struct pv_segment *pvseg;
+ int ret_max = 0;
+ int ret;
+
+ list_iterate_items(pvseg, &pv->segments) {
+ ret = process_single(cmd, vg, pvseg, handle);
+ if (ret > ret_max)
+ ret_max = ret;
+ }
+
+ return ret_max;
+}
+
int process_each_segment_in_lv(struct cmd_context *cmd,
struct logical_volume *lv,
void *handle,
@@ -463,7 +488,7 @@
int ret_max = 0;
int ret = 0;
- if (!(iter = dev_iter_create(cmd->filter))) {
+ if (!(iter = dev_iter_create(cmd->filter, 1))) {
log_error("dev_iter creation failed");
return ECMD_FAILED;
}
@@ -472,6 +497,7 @@
if (!(pv = pv_read(cmd, dev_name(dev), NULL, NULL, 0))) {
memset(&pv_dummy, 0, sizeof(pv_dummy));
list_init(&pv_dummy.tags);
+ list_init(&pv_dummy.segments);
pv_dummy.dev = dev;
pv_dummy.fmt = NULL;
pv = &pv_dummy;
@@ -986,3 +1012,48 @@
return 1;
}
+
+int apply_lvname_restrictions(const char *name)
+{
+ if (!strncmp(name, "snapshot", 8)) {
+ log_error("Names starting \"snapshot\" are reserved. "
+ "Please choose a different LV name.");
+ return 0;
+ }
+
+ if (!strncmp(name, "pvmove", 6)) {
+ log_error("Names starting \"pvmove\" are reserved. "
+ "Please choose a different LV name.");
+ return 0;
+ }
+
+ if (strstr(name, "_mlog")) {
+ log_error("Names including \"_mlog\" are reserved. "
+ "Please choose a different LV name.");
+ return 0;
+ }
+
+ if (strstr(name, "_mimage")) {
+ log_error("Names including \"_mimage\" are reserved. "
+ "Please choose a different LV name.");
+ return 0;
+ }
+
+ return 1;
+}
+
+int validate_vg_name(struct cmd_context *cmd, const char *vg_name)
+{
+ char vg_path[PATH_MAX];
+
+ if (!validate_name(vg_name))
+ return 0;
+
+ snprintf(vg_path, PATH_MAX, "%s%s", cmd->dev_dir, vg_name);
+ if (path_exists(vg_path)) {
+ log_error("%s: already exists in filesystem", vg_path);
+ return 0;
+ }
+
+ return 1;
+}
Modified: lvm2/upstream/current/tools/toollib.h
==============================================================================
--- lvm2/upstream/current/tools/toollib.h (original)
+++ lvm2/upstream/current/tools/toollib.h Tue Jun 14 11:13:22 2005
@@ -40,6 +40,14 @@
struct volume_group * vg,
struct physical_volume * pv,
void *handle));
+int process_each_segment_in_pv(struct cmd_context *cmd,
+ struct volume_group *vg,
+ struct physical_volume *pv,
+ void *handle,
+ int (*process_single) (struct cmd_context * cmd,
+ struct volume_group * vg,
+ struct pv_segment * pvseg,
+ void *handle));
int process_each_lv(struct cmd_context *cmd, int argc, char **argv,
int lock_type, void *handle,
@@ -82,4 +90,8 @@
int exec_cmd(const char *command, const char *fscmd, const char *lv_path,
const char *size);
+int apply_lvname_restrictions(const char *name);
+
+int validate_vg_name(struct cmd_context *cmd, const char *vg_name);
+
#endif
Modified: lvm2/upstream/current/tools/tools.h
==============================================================================
--- lvm2/upstream/current/tools/tools.h (original)
+++ lvm2/upstream/current/tools/tools.h Tue Jun 14 11:13:22 2005
@@ -89,7 +89,9 @@
/* a global table of possible arguments */
struct arg {
const char short_arg;
+ char _padding[7];
const char *long_arg;
+
int (*fn) (struct cmd_context * cmd, struct arg * a);
unsigned int count;
@@ -135,7 +137,7 @@
char yes_no_prompt(const char *prompt, ...);
/* we use the enums to access the switches */
-static inline const unsigned int arg_count(struct cmd_context *cmd, int a)
+static inline unsigned int arg_count(struct cmd_context *cmd, int a)
{
return cmd->args[a].count;
}
@@ -151,25 +153,25 @@
return arg_count(cmd, a) ? cmd->args[a].value : def;
}
-static inline const int32_t arg_int_value(struct cmd_context *cmd, int a,
+static inline int32_t arg_int_value(struct cmd_context *cmd, int a,
const int32_t def)
{
return arg_count(cmd, a) ? cmd->args[a].i_value : def;
}
-static inline const uint32_t arg_uint_value(struct cmd_context *cmd, int a,
+static inline uint32_t arg_uint_value(struct cmd_context *cmd, int a,
const uint32_t def)
{
return arg_count(cmd, a) ? cmd->args[a].ui_value : def;
}
-static inline const int64_t arg_int64_value(struct cmd_context *cmd, int a,
+static inline int64_t arg_int64_value(struct cmd_context *cmd, int a,
const uint64_t def)
{
return arg_count(cmd, a) ? cmd->args[a].i64_value : def;
}
-static inline const uint64_t arg_uint64_value(struct cmd_context *cmd, int a,
+static inline uint64_t arg_uint64_value(struct cmd_context *cmd, int a,
const uint64_t def)
{
return arg_count(cmd, a) ? cmd->args[a].ui64_value : def;
@@ -181,13 +183,13 @@
return arg_count(cmd, a) ? cmd->args[a].ptr : def;
}
-static inline const sign_t arg_sign_value(struct cmd_context *cmd, int a,
+static inline sign_t arg_sign_value(struct cmd_context *cmd, int a,
const sign_t def)
{
return arg_count(cmd, a) ? cmd->args[a].sign : def;
}
-static inline const int arg_count_increment(struct cmd_context *cmd, int a)
+static inline int arg_count_increment(struct cmd_context *cmd, int a)
{
return cmd->args[a].count++;
}
Modified: lvm2/upstream/current/tools/vgcfgbackup.c
==============================================================================
--- lvm2/upstream/current/tools/vgcfgbackup.c (original)
+++ lvm2/upstream/current/tools/vgcfgbackup.c Tue Jun 14 11:13:22 2005
@@ -76,7 +76,7 @@
}
/* just use the normal backup code */
- backup_enable(1); /* force a backup */
+ backup_enable(cmd, 1); /* force a backup */
if (!backup(vg)) {
stack;
return ECMD_FAILED;
Modified: lvm2/upstream/current/tools/vgchange.c
==============================================================================
--- lvm2/upstream/current/tools/vgchange.c (original)
+++ lvm2/upstream/current/tools/vgchange.c Tue Jun 14 11:13:22 2005
@@ -27,13 +27,13 @@
lv = lvl->lv;
/* Only request activation of snapshot origin devices */
- if (lv_is_cow(lv))
+ if ((lv->status & SNAPSHOT) || lv_is_cow(lv))
continue;
- /* Can't deactive a pvmove LV */
+ /* Can't deactive a pvmove or log LV */
/* FIXME There needs to be a controlled way of doing this */
if (((activate == CHANGE_AN) || (activate == CHANGE_ALN)) &&
- (lv->status & PVMOVE))
+ ((lv->status & PVMOVE) || (lv->status & MIRROR_LOG)))
continue;
if (activate == CHANGE_AN) {
@@ -83,6 +83,16 @@
return ECMD_FAILED;
}
+ if (activate && lockingfailed() && (vg->status & CLUSTERED)) {
+ log_error("Locking inactive: ignoring clustered "
+ "volume group %s", vg->name);
+ return ECMD_FAILED;
+ }
+
+ /* FIXME Move into library where clvmd can use it */
+ if (activate && !lockingfailed())
+ check_current_backup(vg);
+
if (activate && (active = lvs_in_vg_activated(vg)))
log_verbose("%d logical volume(s) in volume group \"%s\" "
"already active", active, vg->name);
@@ -168,6 +178,41 @@
return ECMD_PROCESSED;
}
+static int _vgchange_clustered(struct cmd_context *cmd,
+ struct volume_group *vg)
+{
+ int clustered = !strcmp(arg_str_value(cmd, clustered_ARG, "n"), "y");
+
+ if (clustered && (vg->status & CLUSTERED)) {
+ log_error("Volume group \"%s\" is already clustered",
+ vg->name);
+ return ECMD_FAILED;
+ }
+
+ if (!clustered && !(vg->status & CLUSTERED)) {
+ log_error("Volume group \"%s\" is already not clustered",
+ vg->name);
+ return ECMD_FAILED;
+ }
+
+ if (!archive(vg))
+ return ECMD_FAILED;
+
+ if (clustered)
+ vg->status |= CLUSTERED;
+ else
+ vg->status &= ~CLUSTERED;
+
+ 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_logicalvolume(struct cmd_context *cmd,
struct volume_group *vg)
{
@@ -210,6 +255,64 @@
return ECMD_PROCESSED;
}
+static int _vgchange_pesize(struct cmd_context *cmd, struct volume_group *vg)
+{
+ uint32_t extent_size;
+
+ if (!(vg->status & RESIZEABLE_VG)) {
+ log_error("Volume group \"%s\" must be resizeable "
+ "to change PE size", vg->name);
+ return ECMD_FAILED;
+ }
+
+ if (arg_sign_value(cmd, physicalextentsize_ARG, 0) == SIGN_MINUS) {
+ log_error("Physical extent size may not be negative");
+ return EINVALID_CMD_LINE;
+ }
+
+ extent_size = arg_uint_value(cmd, physicalextentsize_ARG, 0) * 2;
+ if (!extent_size) {
+ log_error("Physical extent size may not be zero");
+ return EINVALID_CMD_LINE;
+ }
+
+ if (extent_size == vg->extent_size) {
+ log_error("Physical extent size of VG %s is already %s",
+ vg->name, display_size(cmd, extent_size, SIZE_SHORT));
+ return ECMD_PROCESSED;
+ }
+
+ if (extent_size & (extent_size - 1)) {
+ log_error("Physical extent size must be a power of 2.");
+ return EINVALID_CMD_LINE;
+ }
+
+ if (extent_size > vg->extent_size) {
+ if ((uint64_t) vg->extent_size * vg->extent_count % extent_size) {
+ /* FIXME Adjust used PV sizes instead */
+ log_error("New extent size is not a perfect fit");
+ return EINVALID_CMD_LINE;
+ }
+ }
+
+ if (!archive(vg))
+ return ECMD_FAILED;
+
+ if (!vg_change_pesize(cmd, vg, extent_size)) {
+ stack;
+ return ECMD_FAILED;
+ }
+
+ 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_tag(struct cmd_context *cmd, struct volume_group *vg,
int arg)
{
@@ -328,12 +431,18 @@
else if (arg_count(cmd, deltag_ARG))
r = _vgchange_tag(cmd, vg, deltag_ARG);
+ else if (arg_count(cmd, physicalextentsize_ARG))
+ r = _vgchange_pesize(cmd, vg);
+
else if (arg_count(cmd, uuid_ARG))
r = _vgchange_uuid(cmd, vg);
else if (arg_count(cmd, alloc_ARG))
r = _vgchange_alloc(cmd, vg);
+ else if (arg_count(cmd, clustered_ARG))
+ r = _vgchange_clustered(cmd, vg);
+
return r;
}
@@ -343,9 +452,10 @@
(arg_count(cmd, available_ARG) + arg_count(cmd, logicalvolume_ARG) +
arg_count(cmd, resizeable_ARG) + arg_count(cmd, deltag_ARG) +
arg_count(cmd, addtag_ARG) + arg_count(cmd, uuid_ARG) +
- arg_count(cmd, alloc_ARG))) {
- log_error("One of -a, -l, -x, --alloc, --addtag, --deltag "
- "or --uuid required");
+ arg_count(cmd, physicalextentsize_ARG) +
+ arg_count(cmd, clustered_ARG) + arg_count(cmd, alloc_ARG))) {
+ log_error("One of -a, -c, -l, -s, -x, --uuid, --alloc, --addtag or "
+ "--deltag required");
return EINVALID_CMD_LINE;
}
@@ -353,9 +463,10 @@
if (arg_count(cmd, available_ARG) + arg_count(cmd, logicalvolume_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) > 1) {
- log_error("Only one of -a, -l, -x, --alloc, --addtag, --deltag "
- "or --uuid allowed");
+ 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");
return EINVALID_CMD_LINE;
}
Modified: lvm2/upstream/current/tools/vgconvert.c
==============================================================================
--- lvm2/upstream/current/tools/vgconvert.c (original)
+++ lvm2/upstream/current/tools/vgconvert.c Tue Jun 14 11:13:22 2005
@@ -92,6 +92,8 @@
if (cmd->fmt->features & FMT_RESTRICTED_LVIDS) {
list_iterate_items(lvl, &vg->lvs) {
lv = lvl->lv;
+ if (lv->status & SNAPSHOT)
+ continue;
if (lvnum_from_lvid(&lv->lvid) < MAX_RESTRICTED_LVS)
continue;
if (lv_info(lv, &info, 0) && info.exists) {
Modified: lvm2/upstream/current/tools/vgcreate.c
==============================================================================
--- lvm2/upstream/current/tools/vgcreate.c (original)
+++ lvm2/upstream/current/tools/vgcreate.c Tue Jun 14 11:13:22 2005
@@ -22,10 +22,10 @@
size_t max_lv, max_pv;
uint32_t extent_size;
char *vg_name;
- char vg_path[PATH_MAX];
struct volume_group *vg;
const char *tag;
alloc_policy_t alloc;
+ int clustered;
if (!argc) {
log_error("Please provide volume group name and "
@@ -88,13 +88,7 @@
if (!strncmp(vg_name, cmd->dev_dir, strlen(cmd->dev_dir)))
vg_name += strlen(cmd->dev_dir);
- snprintf(vg_path, PATH_MAX, "%s%s", cmd->dev_dir, vg_name);
- if (path_exists(vg_path)) {
- log_error("%s: already exists in filesystem", vg_path);
- return ECMD_FAILED;
- }
-
- if (!validate_name(vg_name)) {
+ if (!validate_vg_name(cmd, vg_name)) {
log_error("New volume group name \"%s\" is invalid", vg_name);
return ECMD_FAILED;
}
@@ -130,6 +124,17 @@
}
}
+ if (arg_count(cmd, clustered_ARG))
+ clustered = !strcmp(arg_str_value(cmd, clustered_ARG, "n"), "y");
+ else
+ /* Default depends on current locking type */
+ clustered = locking_is_clustered();
+
+ if (clustered)
+ vg->status |= CLUSTERED;
+ else
+ vg->status &= ~CLUSTERED;
+
if (!lock_vol(cmd, "", LCK_VG_WRITE)) {
log_error("Can't get lock for orphan PVs");
return ECMD_FAILED;
Modified: lvm2/upstream/current/tools/vgdisplay.c
==============================================================================
--- lvm2/upstream/current/tools/vgdisplay.c (original)
+++ lvm2/upstream/current/tools/vgdisplay.c Tue Jun 14 11:13:22 2005
@@ -53,6 +53,8 @@
process_each_pv_in_vg(cmd, vg, NULL, NULL, &pvdisplay_short);
}
+ check_current_backup(vg);
+
return ECMD_PROCESSED;
}
Modified: lvm2/upstream/current/tools/vgmerge.c
==============================================================================
--- lvm2/upstream/current/tools/vgmerge.c (original)
+++ lvm2/upstream/current/tools/vgmerge.c Tue Jun 14 11:13:22 2005
@@ -140,6 +140,33 @@
}
vg_to->pv_count += vg_from->pv_count;
+ /* Fix up LVIDs */
+ list_iterate_items(lvl1, &vg_to->lvs) {
+ union lvid *lvid1 = &lvl1->lv->lvid;
+ char uuid[64];
+
+ list_iterate_items(lvl2, &vg_from->lvs) {
+ union lvid *lvid2 = &lvl2->lv->lvid;
+
+ if (id_equal(&lvid1->id[1], &lvid2->id[1])) {
+ if (!id_create(&lvid2->id[1])) {
+ log_error("Failed to generate new "
+ "random LVID for %s",
+ lvl2->lv->name);
+ goto error;
+ }
+ if (!id_write_format(&lvid2->id[1], uuid,
+ sizeof(uuid))) {
+ stack;
+ goto error;
+ }
+
+ log_verbose("Changed LVID for %s to %s",
+ lvl2->lv->name, uuid);
+ }
+ }
+ }
+
while (!list_empty(&vg_from->lvs)) {
struct list *lvh = vg_from->lvs.n;
Modified: lvm2/upstream/current/tools/vgreduce.c
==============================================================================
--- lvm2/upstream/current/tools/vgreduce.c (original)
+++ lvm2/upstream/current/tools/vgreduce.c Tue Jun 14 11:13:22 2005
@@ -49,9 +49,9 @@
static int _remove_lv(struct cmd_context *cmd, struct logical_volume *lv,
int *list_unsafe)
{
- struct snapshot *snap;
- struct snapshot_list *snl;
- struct list *snaplist;
+ struct lv_segment *snap_seg;
+ struct list *snh, *snht;
+ struct logical_volume *cow;
log_verbose("%s/%s has missing extents: removing (including "
"dependencies)", lv->vg->name, lv->name);
@@ -65,36 +65,34 @@
log_error("Failed to deactivate LV %s", lv->name);
return 0;
}
- } else if ((snap = find_cow(lv))) {
+ } else if ((snap_seg = find_cow(lv))) {
log_verbose("Deactivating (if active) logical volume %s "
- "(origin of %s)", snap->origin->name, lv->name);
+ "(origin of %s)", snap_seg->origin->name, lv->name);
- if (!deactivate_lv(cmd, snap->origin->lvid.s)) {
+ if (!deactivate_lv(cmd, snap_seg->origin->lvid.s)) {
log_error("Failed to deactivate LV %s",
- snap->origin->name);
+ snap_seg->origin->name);
return 0;
}
/* Use the origin LV */
- lv = snap->origin;
+ lv = snap_seg->origin;
}
/* Remove snapshot dependencies */
- if (!(snaplist = find_snapshots(lv))) {
- stack;
- return 0;
- }
- /* List may be empty */
- list_iterate_items(snl, snaplist) {
+ list_iterate_safe(snh, snht, &lv->snapshot_segs) {
+ snap_seg = list_struct_base(snh, struct lv_segment,
+ origin_list);
+ cow = snap_seg->cow;
+
*list_unsafe = 1; /* May remove caller's lvht! */
- snap = snl->snapshot;
- if (!vg_remove_snapshot(lv->vg, snap->cow)) {
+ if (!vg_remove_snapshot(cow)) {
stack;
return 0;
}
- log_verbose("Removing LV %s from VG %s", snap->cow->name,
+ log_verbose("Removing LV %s from VG %s", cow->name,
lv->vg->name);
- if (!lv_remove(lv->vg, snap->cow)) {
+ if (!lv_remove(cow)) {
stack;
return 0;
}
@@ -102,7 +100,7 @@
/* Remove the LV itself */
log_verbose("Removing LV %s from VG %s", lv->name, lv->vg->name);
- if (!lv_remove(lv->vg, lv)) {
+ if (!lv_remove(lv)) {
stack;
return 0;
}
@@ -131,12 +129,12 @@
/* Are any segments of this LV on missing PVs? */
list_iterate_items(seg, &lv->segments) {
for (s = 0; s < seg->area_count; s++) {
- if (seg->area[s].type != AREA_PV)
+ if (seg_type(seg, s) != AREA_PV)
continue;
/* FIXME Also check for segs on deleted LVs */
- pv = seg->area[s].u.pv.pv;
+ pv = seg_pv(seg, s);
if (!pv || !pv->dev) {
if (!_remove_lv(cmd, lv, &list_unsafe)) {
stack;
@@ -192,6 +190,13 @@
list_del(&pvl->list);
pv->vg_name = ORPHAN;
+ pv->status = ALLOCATABLE_PV;
+
+ if (!dev_get_size(pv->dev, &pv->size)) {
+ log_error("%s: Couldn't get size.", dev_name(pv->dev));
+ return ECMD_FAILED;
+ }
+
vg->pv_count--;
vg->free_count -= pv->pe_count - pv->pe_alloc_count;
vg->extent_count -= pv->pe_count;
Modified: lvm2/upstream/current/tools/vgremove.c
==============================================================================
--- lvm2/upstream/current/tools/vgremove.c (original)
+++ lvm2/upstream/current/tools/vgremove.c Tue Jun 14 11:13:22 2005
@@ -56,6 +56,14 @@
log_verbose("Removing physical volume \"%s\" from "
"volume group \"%s\"", dev_name(pv->dev), vg_name);
pv->vg_name = ORPHAN;
+ pv->status = ALLOCATABLE_PV;
+
+ if (!dev_get_size(pv->dev, &pv->size)) {
+ log_error("%s: Couldn't get size.", dev_name(pv->dev));
+ ret = ECMD_FAILED;
+ continue;
+ }
+
/* FIXME Write to same sector label was read from */
if (!pv_write(cmd, pv, NULL, INT64_C(-1))) {
log_error("Failed to remove physical volume \"%s\""
@@ -65,7 +73,7 @@
}
}
- backup_remove(vg_name);
+ backup_remove(cmd, vg_name);
if (ret == ECMD_PROCESSED)
log_print("Volume group \"%s\" successfully removed", vg_name);
Modified: lvm2/upstream/current/tools/vgrename.c
==============================================================================
--- lvm2/upstream/current/tools/vgrename.c (original)
+++ lvm2/upstream/current/tools/vgrename.c Tue Jun 14 11:13:22 2005
@@ -51,7 +51,7 @@
return ECMD_FAILED;
}
- if (!validate_name(vg_name_new)) {
+ if (!validate_vg_name(cmd, vg_name_new)) {
log_error("New volume group name \"%s\" is invalid",
vg_name_new);
return ECMD_FAILED;
Modified: lvm2/upstream/current/tools/vgscan.c
==============================================================================
--- lvm2/upstream/current/tools/vgscan.c (original)
+++ lvm2/upstream/current/tools/vgscan.c Tue Jun 14 11:13:22 2005
@@ -36,6 +36,8 @@
(vg->status & EXPORTED_VG) ? "exported " : "", vg_name,
vg->fid->fmt->name);
+ check_current_backup(vg);
+
return ECMD_PROCESSED;
}
@@ -48,10 +50,7 @@
return EINVALID_CMD_LINE;
}
- log_verbose("Wiping cache of LVM-capable devices");
persistent_filter_wipe(cmd->filter);
-
- log_verbose("Wiping internal cache");
lvmcache_destroy();
log_print("Reading all physical volumes. This may take a while...");
Modified: lvm2/upstream/current/tools/vgsplit.c
==============================================================================
--- lvm2/upstream/current/tools/vgsplit.c (original)
+++ lvm2/upstream/current/tools/vgsplit.c Tue Jun 14 11:13:22 2005
@@ -44,6 +44,19 @@
return 1;
}
+/* FIXME Why not (lv->vg == vg) ? */
+static int _lv_is_in_vg(struct volume_group *vg, struct logical_volume *lv)
+{
+ struct lv_list *lvl;
+
+ list_iterate_items(lvl, &vg->lvs)
+ if (lv == lvl->lv)
+ return 1;
+
+ return 0;
+}
+
+
static int _move_lvs(struct volume_group *vg_from, struct volume_group *vg_to)
{
struct list *lvh, *lvht;
@@ -56,16 +69,19 @@
list_iterate_safe(lvh, lvht, &vg_from->lvs) {
lv = list_item(lvh, struct lv_list)->lv;
+ if ((lv->status & SNAPSHOT))
+ continue;
+
/* Ensure all the PVs used by this LV remain in the same */
/* VG as each other */
vg_with = NULL;
list_iterate_items(seg, &lv->segments) {
for (s = 0; s < seg->area_count; s++) {
/* FIXME Check AREA_LV too */
- if (seg->area[s].type != AREA_PV)
+ if (seg_type(seg, s) != AREA_PV)
continue;
- pv = seg->area[s].u.pv.pv;
+ pv = seg_pv(seg, s);
if (vg_with) {
if (!pv_is_in_vg(vg_with, pv)) {
log_error("Logical Volume %s "
@@ -89,8 +105,9 @@
dev_name(pv->dev));
return 0;
}
- }
+ }
+
if (vg_with == vg_from)
continue;
@@ -107,39 +124,38 @@
return 1;
}
-static int _lv_is_in_vg(struct volume_group *vg, struct logical_volume *lv)
+static int _move_snapshots(struct volume_group *vg_from,
+ struct volume_group *vg_to)
{
- struct lv_list *lvl;
+ struct list *lvh, *lvht;
+ struct logical_volume *lv;
+ struct lv_segment *seg;
+ int cow_from = 0;
+ int origin_from = 0;
- list_iterate_items(lvl, &vg->lvs)
- if (lv == lvl->lv)
- return 1;
+ list_iterate_safe(lvh, lvht, &vg_from->lvs) {
+ lv = list_item(lvh, struct lv_list)->lv;
- return 0;
-}
+ if (!(lv->status & SNAPSHOT))
+ continue;
-static int _move_snapshots(struct volume_group *vg_from,
- struct volume_group *vg_to)
-{
- struct list *slh, *slth;
- struct snapshot *snap;
- int cow_from, origin_from;
-
- list_iterate_safe(slh, slth, &vg_from->snapshots) {
- snap = list_item(slh, struct snapshot_list)->snapshot;
- cow_from = _lv_is_in_vg(vg_from, snap->cow);
- origin_from = _lv_is_in_vg(vg_from, snap->origin);
+ list_iterate_items(seg, &lv->segments) {
+ cow_from = _lv_is_in_vg(vg_from, seg->cow);
+ origin_from = _lv_is_in_vg(vg_from, seg->origin);
+ }
if (cow_from && origin_from)
- return 1;
+ continue;
if ((!cow_from && origin_from) || (cow_from && !origin_from)) {
- log_error("Snapshot %s split", snap->cow->name);
+ log_error("Snapshot %s split", seg->cow->name);
return 0;
- }
+ }
+
+ /* Move this snapshot */
+ list_del(lvh);
+ list_add(&vg_to->lvs, lvh);
+
vg_from->snapshot_count--;
vg_to->snapshot_count++;
-
- list_del(slh);
- list_add(&vg_to->snapshots, slh);
}
return 1;
@@ -206,6 +222,12 @@
goto error;
}
+ if (!validate_vg_name(cmd, vg_name_to)) {
+ log_error("New volume group name \"%s\" is invalid",
+ vg_name_to);
+ goto error;
+ }
+
if ((active = lvs_in_vg_activated(vg_from))) {
/* FIXME Remove this restriction */
log_error("Logical volumes in \"%s\" must be inactive",
More information about the pkg-lvm-commits
mailing list