mirror of
git://sourceware.org/git/lvm2.git
synced 2025-12-24 16:23:50 +03:00
Compare commits
152 Commits
dm_v1_01_0
...
dm_v1_02_0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8288b45b4f | ||
|
|
fe529faf8e | ||
|
|
ab931b177d | ||
|
|
9aa3465513 | ||
|
|
6c70fc1a6c | ||
|
|
1ccc39962a | ||
|
|
99c941fc85 | ||
|
|
19729fdcc2 | ||
|
|
02e17998ce | ||
|
|
459e00c67a | ||
|
|
292f665650 | ||
|
|
93bbb79569 | ||
|
|
273e724f2b | ||
|
|
5d2615c56f | ||
|
|
bfaaf21330 | ||
|
|
dcb8415b7a | ||
|
|
699e1c75ce | ||
|
|
465b6e613e | ||
|
|
05fa105855 | ||
|
|
d7a0cdebe5 | ||
|
|
b049ab31eb | ||
|
|
6db4dcff7a | ||
|
|
3eeaef00ec | ||
|
|
8bf4c38a00 | ||
|
|
3a32b09ad1 | ||
|
|
6315982752 | ||
|
|
374a171e82 | ||
|
|
fc5d801f91 | ||
|
|
5146641848 | ||
|
|
cdd0ac42cf | ||
|
|
e5895500a2 | ||
|
|
9cb4dde3fa | ||
|
|
3c2a4370a5 | ||
|
|
e7a360dd6f | ||
|
|
c814c2fd35 | ||
|
|
fefa7fe262 | ||
|
|
26f01a29d1 | ||
|
|
169d4090ab | ||
|
|
0b43754d60 | ||
|
|
8b3b26b813 | ||
|
|
5426af4f81 | ||
|
|
4e2c3a579d | ||
|
|
5ae2693241 | ||
|
|
41c86b0d19 | ||
|
|
40788e8c3d | ||
|
|
0d29120033 | ||
|
|
4be598f865 | ||
|
|
558a6d509e | ||
|
|
75cd02aad2 | ||
|
|
e4c4451482 | ||
|
|
0671632477 | ||
|
|
54c230c264 | ||
|
|
64ba878eda | ||
|
|
01acd6dd76 | ||
|
|
9d819b52d3 | ||
|
|
37bac5cdc9 | ||
|
|
78c718c591 | ||
|
|
284b8bf6ca | ||
|
|
5a5084b837 | ||
|
|
3b8058e1f1 | ||
|
|
2a3168e0d6 | ||
|
|
a8ac6e4a15 | ||
|
|
6172cf9fba | ||
|
|
b728ec3909 | ||
|
|
61a53bbcff | ||
|
|
17d13dd084 | ||
|
|
edcb28d591 | ||
|
|
ad101119a7 | ||
|
|
bc36676d31 | ||
|
|
d76fe120ab | ||
|
|
2e95949b80 | ||
|
|
ae14d85e24 | ||
|
|
fad6304c60 | ||
|
|
a4dd3c8ce9 | ||
|
|
6d1a5d45e2 | ||
|
|
a6c7043e03 | ||
|
|
bcc400dafa | ||
|
|
8fbedf3441 | ||
|
|
2e8a9c9874 | ||
|
|
44fc41b3e5 | ||
|
|
7212c20a1b | ||
|
|
7ff142de1c | ||
|
|
e67efb199d | ||
|
|
20128bd04b | ||
|
|
c0fefdde28 | ||
|
|
f6ee160e66 | ||
|
|
06acc2004f | ||
|
|
43ac2ce4c8 | ||
|
|
b32bf72b5f | ||
|
|
c6880c957e | ||
|
|
095b71ed96 | ||
|
|
9160e496bc | ||
|
|
2a7ac78f02 | ||
|
|
64efa4627d | ||
|
|
f7e35569ce | ||
|
|
e8af32ec2b | ||
|
|
e092ce51f6 | ||
|
|
7b78edb1b7 | ||
|
|
b332e7090e | ||
|
|
67eb7723d6 | ||
|
|
251d138474 | ||
|
|
1170dfac05 | ||
|
|
4157f141c7 | ||
|
|
f569abd28a | ||
|
|
088f9687c0 | ||
|
|
e23df1f07a | ||
|
|
c818540dfd | ||
|
|
21365cbe1a | ||
|
|
5471a80a96 | ||
|
|
d7b6fa9cd0 | ||
|
|
dfdc2e02ef | ||
|
|
893ec9a302 | ||
|
|
05f65c38e6 | ||
|
|
2e9d062ec0 | ||
|
|
6b0b394e61 | ||
|
|
25621396c9 | ||
|
|
82aa0271f3 | ||
|
|
653cab13f8 | ||
|
|
b526f86b49 | ||
|
|
53c0f00888 | ||
|
|
f0c4d9de40 | ||
|
|
03ef8cec83 | ||
|
|
85f2a2e8c2 | ||
|
|
584b3e6642 | ||
|
|
39b7ef841d | ||
|
|
aa16a9098d | ||
|
|
7b8c2707bc | ||
|
|
60e26a31a7 | ||
|
|
3473c25c14 | ||
|
|
e52f022026 | ||
|
|
b1a7df8e43 | ||
|
|
0fd2479b7c | ||
|
|
273857f914 | ||
|
|
a08b85dbc8 | ||
|
|
a0aedf299a | ||
|
|
3c61426844 | ||
|
|
786f228076 | ||
|
|
004da28792 | ||
|
|
6e2be6efb6 | ||
|
|
a994dfcfbc | ||
|
|
7a8ea2ac93 | ||
|
|
0da3965d19 | ||
|
|
885fd7bb46 | ||
|
|
08771f9c89 | ||
|
|
8be48195a5 | ||
|
|
98ce2d650e | ||
|
|
3af327116a | ||
|
|
b75434db93 | ||
|
|
04e912aacd | ||
|
|
d7be352f87 | ||
|
|
96be3ec22c | ||
|
|
32e7e0d790 |
90
WHATS_NEW
90
WHATS_NEW
@@ -1,6 +1,90 @@
|
||||
Version 2.01.14 -
|
||||
================================
|
||||
Fix pool format handler to work with pv segment code
|
||||
Version 2.02.02
|
||||
====================================
|
||||
Add some activation logic to remove_mirror_images().
|
||||
lvconvert can remove specified PVs from a mirror.
|
||||
lvconvert turns an existing LV into a mirror.
|
||||
Allow signed mirrors arguments.
|
||||
Move create_mirror_log() into toollib.
|
||||
Determine parallel PVs to avoid with ALLOC_NORMAL allocation.
|
||||
Fix lv_empty.
|
||||
|
||||
Version 2.02.01 - 23rd November 2005
|
||||
====================================
|
||||
Fix lvdisplay cmdline to accept snapshots.
|
||||
Fix open RO->RW promotion.
|
||||
Fix missing vg_revert in lvcreate error path.
|
||||
|
||||
Version 2.02.00 - 10th November 2005
|
||||
====================================
|
||||
Extend allocation areas to avoid overflow with contiguous with other PVs.
|
||||
Stop lvcreate attempting to wipe zero or error segments.
|
||||
Added new lvs table attributes.
|
||||
Separated out activation preload.
|
||||
Moved activation functions into libdevmapper.
|
||||
Fixed build_dm_name.
|
||||
Add return macros.
|
||||
Added xen xvd devices.
|
||||
Clear up precommitted metadata better.
|
||||
A pvresize implementation.
|
||||
Fix contiguous allocation when there are no preceding segments.
|
||||
Add mirror_seg pointer to lv_segment struct.
|
||||
Only keep a device open if it's known to belong to a locked VG.
|
||||
Fix lvdisplay to show all mirror destinations.
|
||||
Replacement suspend code using libdevmapper dependency tree.
|
||||
Add DEFS to make.tmpl.
|
||||
Use dm_is_dm_major instead of local copy.
|
||||
Allow mapped devices to be used as PVs.
|
||||
Move set_selinux_context into libdevmapper.
|
||||
Fix automatic text metadata buffer expansion (using macro).
|
||||
Cache formatted text metadata buffer between metadata area writes.
|
||||
Add pe_start field to pvs.
|
||||
Add 'LVM-' prefix to uuids.
|
||||
Split lv_segment_area from lv_segment to permit extension.
|
||||
Replacement deactivation code using libdevmapper dependency tree.
|
||||
Simplify dev_manager_info().
|
||||
Attempt to load missing targets using modprobe.
|
||||
Add -a to lvscan.
|
||||
Move mknodes into libdevmapper.
|
||||
Move bitset, hash, pool and dbg_malloc into libdevmapper.
|
||||
|
||||
Version 2.01.15 - 16th October 2005
|
||||
===================================
|
||||
Refuse to run pvcreate/pvremove on devices we can't open exclusively.
|
||||
Use ORPHAN lock definition throughout.
|
||||
Validate chunksize in lvcreate.
|
||||
Reduce chunksize limit to 512k.
|
||||
Fix chunksize field in reports.
|
||||
Don't hide snapshots from default 'lvs' output.
|
||||
Add is_dm_major() for use in duplicate device detection in lvmcache_add().
|
||||
Really switch device number in lvmcache when it says it is doing so.
|
||||
Option for bitset memory allocation using malloc as well as pool.
|
||||
Don't assume exactly two mirrors when parsing mirror status.
|
||||
Suppress fsync() error message on filesystems that don't support it.
|
||||
Fix yes_no_prompt() error handling.
|
||||
Add lvm.conf comment warning against multiple filter lines.
|
||||
Tidy lvmconf.sh.
|
||||
Add format1 dev_write debug messages.
|
||||
Add clustered VG attribute to report.
|
||||
Move lvconvert parameters into struct lvconvert_params.
|
||||
Add clustered VG flag to LV lock requests.
|
||||
Change LV locking macros to take lv instead of lvid.
|
||||
Prepend 'cluster' activation parameter to mirror log when appropriate.
|
||||
Pass exclusive flag to lv_activate and on to target activation code.
|
||||
Prevent snapshot creation in a clustered VG for now.
|
||||
Factor out adjusted_mirror_region_size() and generate_log_name_format().
|
||||
Move compose_log_line() into mirror directory.
|
||||
Factor out _get_library_path().
|
||||
Don't kill idling clvmd threads.
|
||||
clvmd no longer takes out locks for non-clustered LVs.
|
||||
Recognise ATA over Ethernet (aoe) devices.
|
||||
|
||||
Version 2.01.14 - 4th August 2005
|
||||
=================================
|
||||
Fix lvconvert PV parameter in help string.
|
||||
Prevent snapshots getting activated in a clustered VG.
|
||||
Separate out _build_dev_string.
|
||||
Move zero_lv to toollib.
|
||||
Fix pool format handler to work with pv segment code.
|
||||
|
||||
Version 2.01.13 - 13th July 2005
|
||||
================================
|
||||
|
||||
35
WHATS_NEW_DM
35
WHATS_NEW_DM
@@ -1,5 +1,38 @@
|
||||
Version 1.01.04 - 2 Aug 2005
|
||||
Version 1.02.02 - 2 Dec 2005
|
||||
============================
|
||||
dmeventd added.
|
||||
Export dm_task_update_nodes.
|
||||
Use names instead of numbers in messages when ioctls fail.
|
||||
|
||||
Version 1.02.01 - 23 Nov 2005
|
||||
=============================
|
||||
Resume snapshot-origins last.
|
||||
Drop leading zeros from dm_format_dev.
|
||||
Suppress attempt to reload identical table.
|
||||
Additional LVM- prefix matching for transitional period.
|
||||
|
||||
Version 1.02.00 - 10 Nov 2005
|
||||
=============================
|
||||
Added activation functions to library.
|
||||
Added return macros.
|
||||
Also suppress error if device doesn't exist with DM_DEVICE_STATUS.
|
||||
Export dm_set_selinux_context().
|
||||
Add dm_driver_version().
|
||||
Added dependency tree functions to library.
|
||||
Added hash, bitset, pool, dbg_malloc to library.
|
||||
Added ls --tree to dmsetup.
|
||||
Added dmsetup --nolockfs support for suspend/reload.
|
||||
|
||||
Version 1.01.05 - 26 Sep 2005
|
||||
=============================
|
||||
Resync list.h with LVM2.
|
||||
Remember increased buffer size and use for subsequent calls.
|
||||
On 'buffer full' condition, double buffer size and repeat ioctl.
|
||||
Fix termination of getopt_long() option array.
|
||||
Report 'buffer full' condition with v4 ioctl as well as with v1.
|
||||
|
||||
Version 1.01.04 - 2 Aug 2005
|
||||
============================
|
||||
Fix dmsetup ls -j and status --target with empty table.
|
||||
|
||||
Version 1.01.03 - 13 Jun 2005
|
||||
|
||||
50
configure
vendored
50
configure
vendored
@@ -310,7 +310,7 @@ ac_includes_default="\
|
||||
#endif"
|
||||
|
||||
ac_default_prefix=/usr
|
||||
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os AWK CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE RANLIB ac_ct_RANLIB CPP EGREP ALLOCA LIBOBJS POW_LIB MSGFMT JOBS STATIC_LINK LVM1 POOL SNAPSHOTS MIRRORS OWNER GROUP COPTIMISE_FLAG CLDFLAGS CLDWHOLEARCHIVE CLDNOWHOLEARCHIVE LDDEPS SOFLAG LVM_VERSION LVM1_FALLBACK DEBUG DEVMAPPER HAVE_LIBDL HAVE_SELINUX CMDLIB LOCALEDIR CONFDIR STATICDIR INTL_PACKAGE INTL CLVMD CLUSTER FSADM LTLIBOBJS'
|
||||
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os AWK CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE RANLIB ac_ct_RANLIB CPP EGREP ALLOCA LIBOBJS POW_LIB MSGFMT MODPROBE_CMD JOBS STATIC_LINK LVM1 POOL SNAPSHOTS MIRRORS OWNER GROUP COPTIMISE_FLAG CLDFLAGS CLDWHOLEARCHIVE CLDNOWHOLEARCHIVE LDDEPS SOFLAG LVM_VERSION LVM1_FALLBACK DEBUG DEVMAPPER HAVE_LIBDL HAVE_SELINUX CMDLIB LOCALEDIR CONFDIR STATICDIR INTL_PACKAGE INTL CLVMD CLUSTER FSADM LTLIBOBJS'
|
||||
ac_subst_files=''
|
||||
|
||||
# Initialize some variables set by options.
|
||||
@@ -1465,7 +1465,7 @@ case "$host_os" in
|
||||
LDDEPS="$LDDEPS"
|
||||
LDFLAGS="$LDFLAGS"
|
||||
SOFLAG="-dynamiclib"
|
||||
DEVMAPPER=no
|
||||
DEVMAPPER=yes
|
||||
ODIRECT=no
|
||||
SELINUX=no
|
||||
CLUSTER=none
|
||||
@@ -10768,6 +10768,51 @@ done
|
||||
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
# Extract the first word of "modprobe", so it can be a program name with args.
|
||||
set dummy modprobe; ac_word=$2
|
||||
echo "$as_me:$LINENO: checking for $ac_word" >&5
|
||||
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
|
||||
if test "${ac_cv_path_MODPROBE_CMD+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
case $MODPROBE_CMD in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_MODPROBE_CMD="$MODPROBE_CMD" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_MODPROBE_CMD="$as_dir/$ac_word$ac_exec_ext"
|
||||
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
MODPROBE_CMD=$ac_cv_path_MODPROBE_CMD
|
||||
|
||||
if test -n "$MODPROBE_CMD"; then
|
||||
echo "$as_me:$LINENO: result: $MODPROBE_CMD" >&5
|
||||
echo "${ECHO_T}$MODPROBE_CMD" >&6
|
||||
else
|
||||
echo "$as_me:$LINENO: result: no" >&5
|
||||
echo "${ECHO_T}no" >&6
|
||||
fi
|
||||
|
||||
|
||||
if test x$MODPROBE_CMD != x; then
|
||||
CFLAGS="$CFLAGS -DMODPROBE_CMD=\\\"$MODPROBE_CMD\\\""
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
if test "-f VERSION"; then
|
||||
LVM_VERSION="\"`cat VERSION`\""
|
||||
@@ -11501,6 +11546,7 @@ s,@ALLOCA@,$ALLOCA,;t t
|
||||
s,@LIBOBJS@,$LIBOBJS,;t t
|
||||
s,@POW_LIB@,$POW_LIB,;t t
|
||||
s,@MSGFMT@,$MSGFMT,;t t
|
||||
s,@MODPROBE_CMD@,$MODPROBE_CMD,;t t
|
||||
s,@JOBS@,$JOBS,;t t
|
||||
s,@STATIC_LINK@,$STATIC_LINK,;t t
|
||||
s,@LVM1@,$LVM1,;t t
|
||||
|
||||
@@ -50,7 +50,7 @@ case "$host_os" in
|
||||
LDDEPS="$LDDEPS"
|
||||
LDFLAGS="$LDFLAGS"
|
||||
SOFLAG="-dynamiclib"
|
||||
DEVMAPPER=no
|
||||
DEVMAPPER=yes
|
||||
ODIRECT=no
|
||||
SELINUX=no
|
||||
CLUSTER=none
|
||||
@@ -515,6 +515,13 @@ if test x$HAVE_SELINUX = xyes; then
|
||||
AC_CHECK_HEADERS(selinux/selinux.h,,AC_MSG_ERROR(bailing out))
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
AC_PATH_PROG(MODPROBE_CMD, modprobe)
|
||||
|
||||
if test x$MODPROBE_CMD != x; then
|
||||
CFLAGS="$CFLAGS -DMODPROBE_CMD=\\\"$MODPROBE_CMD\\\""
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
if test "-f VERSION"; then
|
||||
LVM_VERSION="\"`cat VERSION`\""
|
||||
|
||||
@@ -65,8 +65,8 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "libdevmapper.h"
|
||||
#include "list.h"
|
||||
#include "hash.h"
|
||||
#include "locking.h"
|
||||
#include "log.h"
|
||||
#include "lvm-functions.h"
|
||||
@@ -109,7 +109,7 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
|
||||
|
||||
case CLVMD_CMD_LOCK_LV:
|
||||
/* This is the biggie */
|
||||
lock_cmd = args[0];
|
||||
lock_cmd = args[0] & 0x3F;
|
||||
lock_flags = args[1];
|
||||
lockname = &args[2];
|
||||
status = do_lock_lv(lock_cmd, lock_flags, lockname);
|
||||
@@ -138,7 +138,7 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
|
||||
|
||||
static int lock_vg(struct local_client *client)
|
||||
{
|
||||
struct hash_table *lock_hash;
|
||||
struct dm_hash_table *lock_hash;
|
||||
struct clvm_header *header =
|
||||
(struct clvm_header *) client->bits.localsock.cmd;
|
||||
unsigned char lock_cmd;
|
||||
@@ -152,23 +152,23 @@ static int lock_vg(struct local_client *client)
|
||||
practice there should only ever be more than two VGs locked
|
||||
if a user tries to merge lots of them at once */
|
||||
if (client->bits.localsock.private) {
|
||||
lock_hash = (struct hash_table *)client->bits.localsock.private;
|
||||
lock_hash = (struct dm_hash_table *)client->bits.localsock.private;
|
||||
}
|
||||
else {
|
||||
lock_hash = hash_create(3);
|
||||
lock_hash = dm_hash_create(3);
|
||||
if (!lock_hash)
|
||||
return ENOMEM;
|
||||
client->bits.localsock.private = (void *)lock_hash;
|
||||
}
|
||||
|
||||
lock_cmd = args[0];
|
||||
lock_cmd = args[0] & 0x3F;
|
||||
lock_flags = args[1];
|
||||
lockname = &args[2];
|
||||
DEBUGLOG("doing PRE command LOCK_VG '%s' at %x (client=%p)\n", lockname, lock_cmd, client);
|
||||
|
||||
if (lock_cmd == LCK_UNLOCK) {
|
||||
|
||||
lkid = (int)(long)hash_lookup(lock_hash, lockname);
|
||||
lkid = (int)(long)dm_hash_lookup(lock_hash, lockname);
|
||||
if (lkid == 0)
|
||||
return EINVAL;
|
||||
|
||||
@@ -176,7 +176,7 @@ static int lock_vg(struct local_client *client)
|
||||
if (status)
|
||||
status = errno;
|
||||
else
|
||||
hash_remove(lock_hash, lockname);
|
||||
dm_hash_remove(lock_hash, lockname);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -184,7 +184,7 @@ static int lock_vg(struct local_client *client)
|
||||
if (status)
|
||||
status = errno;
|
||||
else
|
||||
hash_insert(lock_hash, lockname, (void *)lkid);
|
||||
dm_hash_insert(lock_hash, lockname, (void *)lkid);
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -268,19 +268,19 @@ void cmd_client_cleanup(struct local_client *client)
|
||||
{
|
||||
if (client->bits.localsock.private) {
|
||||
|
||||
struct hash_node *v;
|
||||
struct hash_table *lock_hash =
|
||||
(struct hash_table *)client->bits.localsock.private;
|
||||
struct dm_hash_node *v;
|
||||
struct dm_hash_table *lock_hash =
|
||||
(struct dm_hash_table *)client->bits.localsock.private;
|
||||
|
||||
hash_iterate(v, lock_hash) {
|
||||
int lkid = (int)(long)hash_get_data(lock_hash, v);
|
||||
char *lockname = hash_get_key(lock_hash, v);
|
||||
dm_hash_iterate(v, lock_hash) {
|
||||
int lkid = (int)(long)dm_hash_get_data(lock_hash, v);
|
||||
char *lockname = dm_hash_get_key(lock_hash, v);
|
||||
|
||||
DEBUGLOG("cleanup: Unlocking lock %s %x\n", lockname, lkid);
|
||||
sync_unlock(lockname, lkid);
|
||||
}
|
||||
|
||||
hash_destroy(lock_hash);
|
||||
dm_hash_destroy(lock_hash);
|
||||
client->bits.localsock.private = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <syslog.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "libdevmapper.h"
|
||||
#include "ccs.h"
|
||||
#include "list.h"
|
||||
#include "locking.h"
|
||||
@@ -49,16 +50,14 @@
|
||||
#include "clvmd-comms.h"
|
||||
#include "lvm-functions.h"
|
||||
#include "clvmd.h"
|
||||
#include "hash.h"
|
||||
#include "clvmd-gulm.h"
|
||||
#include "libgulm.h"
|
||||
#include "hash.h"
|
||||
|
||||
/* Hash list of nodes in the cluster */
|
||||
static struct hash_table *node_hash;
|
||||
static struct dm_hash_table *node_hash;
|
||||
|
||||
/* hash list of outstanding lock requests */
|
||||
static struct hash_table *lock_hash;
|
||||
static struct dm_hash_table *lock_hash;
|
||||
|
||||
/* Copy of the current quorate state */
|
||||
static uint8_t gulm_quorate = 0;
|
||||
@@ -96,7 +95,7 @@ static int _csid_from_name(char *csid, char *name);
|
||||
static void _cluster_closedown(void);
|
||||
|
||||
/* In tcp-comms.c */
|
||||
extern struct hash_table *sock_hash;
|
||||
extern struct dm_hash_table *sock_hash;
|
||||
|
||||
static int add_internal_client(int fd, fd_callback_t callback)
|
||||
{
|
||||
@@ -178,8 +177,8 @@ static int _init_cluster(void)
|
||||
pthread_mutex_lock(&lock_start_mutex);
|
||||
lock_start_flag = 1;
|
||||
|
||||
node_hash = hash_create(100);
|
||||
lock_hash = hash_create(10);
|
||||
node_hash = dm_hash_create(100);
|
||||
lock_hash = dm_hash_create(10);
|
||||
|
||||
/* Get all nodes from CCS */
|
||||
if (get_all_cluster_nodes())
|
||||
@@ -317,8 +316,6 @@ static int core_login_reply(void *misc, uint64_t gen, uint32_t error, uint32_t r
|
||||
|
||||
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 */
|
||||
@@ -349,15 +346,15 @@ static void set_node_state(struct node_info *ninfo, char *csid, uint8_t nodestat
|
||||
*/
|
||||
tcp_remove_client(csid);
|
||||
|
||||
DEBUGLOG("set_node_state, '%s' state = %d (oldstate=%d), num_nodes=%d\n",
|
||||
ninfo->name, ninfo->state, oldstate, num_nodes);
|
||||
DEBUGLOG("set_node_state, '%s' state = %d num_nodes=%d\n",
|
||||
ninfo->name, ninfo->state, num_nodes);
|
||||
}
|
||||
|
||||
static struct node_info *add_or_set_node(char *name, struct in6_addr *ip, uint8_t state)
|
||||
{
|
||||
struct node_info *ninfo;
|
||||
|
||||
ninfo = hash_lookup_binary(node_hash, (char *)ip, GULM_MAX_CSID_LEN);
|
||||
ninfo = dm_hash_lookup_binary(node_hash, (char *)ip, GULM_MAX_CSID_LEN);
|
||||
if (!ninfo)
|
||||
{
|
||||
/* If we can't find that node then re-read the config file in case it
|
||||
@@ -366,7 +363,7 @@ static struct node_info *add_or_set_node(char *name, struct in6_addr *ip, uint8_
|
||||
get_all_cluster_nodes();
|
||||
|
||||
/* Now try again */
|
||||
ninfo = hash_lookup_binary(node_hash, (char *)ip, GULM_MAX_CSID_LEN);
|
||||
ninfo = dm_hash_lookup_binary(node_hash, (char *)ip, GULM_MAX_CSID_LEN);
|
||||
if (!ninfo)
|
||||
{
|
||||
DEBUGLOG("Ignoring node %s, not part of the SAN cluster\n", name);
|
||||
@@ -512,7 +509,7 @@ static int lock_lock_state(void *misc, uint8_t *key, uint16_t keylen,
|
||||
if (in_shutdown)
|
||||
return 0;
|
||||
|
||||
lwait = hash_lookup(lock_hash, key);
|
||||
lwait = dm_hash_lookup(lock_hash, key);
|
||||
if (!lwait)
|
||||
{
|
||||
DEBUGLOG("Can't find hash entry for resource %s\n", key);
|
||||
@@ -557,22 +554,22 @@ int get_next_node_csid(void **context, char *csid)
|
||||
/* First node */
|
||||
if (!*context)
|
||||
{
|
||||
*context = hash_get_first(node_hash);
|
||||
*context = dm_hash_get_first(node_hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
*context = hash_get_next(node_hash, *context);
|
||||
*context = dm_hash_get_next(node_hash, *context);
|
||||
}
|
||||
if (*context)
|
||||
ninfo = hash_get_data(node_hash, *context);
|
||||
ninfo = dm_hash_get_data(node_hash, *context);
|
||||
|
||||
/* Find a node that is UP */
|
||||
while (*context && ninfo->state == NODE_DOWN)
|
||||
{
|
||||
*context = hash_get_next(node_hash, *context);
|
||||
*context = dm_hash_get_next(node_hash, *context);
|
||||
if (*context)
|
||||
{
|
||||
ninfo = hash_get_data(node_hash, *context);
|
||||
ninfo = dm_hash_get_data(node_hash, *context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -581,7 +578,7 @@ int get_next_node_csid(void **context, char *csid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(csid, hash_get_key(node_hash, *context), GULM_MAX_CSID_LEN);
|
||||
memcpy(csid, dm_hash_get_key(node_hash, *context), GULM_MAX_CSID_LEN);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -589,7 +586,7 @@ int gulm_name_from_csid(char *csid, char *name)
|
||||
{
|
||||
struct node_info *ninfo;
|
||||
|
||||
ninfo = hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
|
||||
ninfo = dm_hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
|
||||
if (!ninfo)
|
||||
{
|
||||
sprintf(name, "UNKNOWN %s", print_csid(csid));
|
||||
@@ -603,15 +600,15 @@ int gulm_name_from_csid(char *csid, char *name)
|
||||
|
||||
static int _csid_from_name(char *csid, char *name)
|
||||
{
|
||||
struct hash_node *hn;
|
||||
struct dm_hash_node *hn;
|
||||
struct node_info *ninfo;
|
||||
|
||||
hash_iterate(hn, node_hash)
|
||||
dm_hash_iterate(hn, node_hash)
|
||||
{
|
||||
ninfo = hash_get_data(node_hash, hn);
|
||||
ninfo = dm_hash_get_data(node_hash, hn);
|
||||
if (strcmp(ninfo->name, name) == 0)
|
||||
{
|
||||
memcpy(csid, hash_get_key(node_hash, hn), GULM_MAX_CSID_LEN);
|
||||
memcpy(csid, dm_hash_get_key(node_hash, hn), GULM_MAX_CSID_LEN);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -629,7 +626,7 @@ void gulm_add_up_node(char *csid)
|
||||
{
|
||||
struct node_info *ninfo;
|
||||
|
||||
ninfo = hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
|
||||
ninfo = dm_hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
|
||||
if (!ninfo) {
|
||||
DEBUGLOG("gulm_add_up_node no node_hash entry for csid %s\n", print_csid(csid));
|
||||
return;
|
||||
@@ -649,7 +646,7 @@ void add_down_node(char *csid)
|
||||
{
|
||||
struct node_info *ninfo;
|
||||
|
||||
ninfo = hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
|
||||
ninfo = dm_hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
|
||||
if (!ninfo)
|
||||
return;
|
||||
|
||||
@@ -666,27 +663,27 @@ void add_down_node(char *csid)
|
||||
static int _cluster_do_node_callback(struct local_client *master_client,
|
||||
void (*callback)(struct local_client *, char *csid, int node_up))
|
||||
{
|
||||
struct hash_node *hn;
|
||||
struct dm_hash_node *hn;
|
||||
struct node_info *ninfo;
|
||||
|
||||
hash_iterate(hn, node_hash)
|
||||
dm_hash_iterate(hn, node_hash)
|
||||
{
|
||||
char csid[GULM_MAX_CSID_LEN];
|
||||
struct local_client *client;
|
||||
|
||||
ninfo = hash_get_data(node_hash, hn);
|
||||
memcpy(csid, hash_get_key(node_hash, hn), GULM_MAX_CSID_LEN);
|
||||
ninfo = dm_hash_get_data(node_hash, hn);
|
||||
memcpy(csid, dm_hash_get_key(node_hash, hn), GULM_MAX_CSID_LEN);
|
||||
|
||||
DEBUGLOG("down_callback. node %s, state = %d\n", ninfo->name, ninfo->state);
|
||||
|
||||
client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
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);
|
||||
client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
|
||||
}
|
||||
if (ninfo->state != NODE_DOWN)
|
||||
@@ -735,7 +732,7 @@ static int _lock_resource(char *resource, int mode, int flags, int *lockid)
|
||||
/* This needs to be converted from DLM/LVM2 value for GULM */
|
||||
if (flags == LCK_NONBLOCK) flags = lg_lock_flag_Try;
|
||||
|
||||
hash_insert(lock_hash, resource, &lwait);
|
||||
dm_hash_insert(lock_hash, resource, &lwait);
|
||||
DEBUGLOG("lock_resource '%s', flags=%d, mode=%d\n", resource, flags, mode);
|
||||
|
||||
status = lg_lock_state_req(gulm_if, resource, strlen(resource)+1,
|
||||
@@ -751,7 +748,7 @@ static int _lock_resource(char *resource, int mode, int flags, int *lockid)
|
||||
pthread_cond_wait(&lwait.cond, &lwait.mutex);
|
||||
pthread_mutex_unlock(&lwait.mutex);
|
||||
|
||||
hash_remove(lock_hash, resource);
|
||||
dm_hash_remove(lock_hash, resource);
|
||||
DEBUGLOG("lock-resource returning %d\n", lwait.status);
|
||||
|
||||
return gulm_to_errno(lwait.status);
|
||||
@@ -767,7 +764,7 @@ static int _unlock_resource(char *resource, int lockid)
|
||||
pthread_mutex_init(&lwait.mutex, NULL);
|
||||
pthread_mutex_lock(&lwait.mutex);
|
||||
|
||||
hash_insert(lock_hash, resource, &lwait);
|
||||
dm_hash_insert(lock_hash, resource, &lwait);
|
||||
|
||||
DEBUGLOG("unlock_resource %s\n", resource);
|
||||
status = lg_lock_state_req(gulm_if, resource, strlen(resource)+1,
|
||||
@@ -790,7 +787,7 @@ static int _unlock_resource(char *resource, int lockid)
|
||||
pthread_cond_wait(&lwait.cond, &lwait.mutex);
|
||||
pthread_mutex_unlock(&lwait.mutex);
|
||||
|
||||
hash_remove(lock_hash, resource);
|
||||
dm_hash_remove(lock_hash, resource);
|
||||
|
||||
return gulm_to_errno(lwait.status);
|
||||
}
|
||||
@@ -926,7 +923,7 @@ static int get_all_cluster_nodes()
|
||||
struct node_info *ninfo;
|
||||
|
||||
/* If it's not in the list, then add it */
|
||||
ninfo = hash_lookup_binary(node_hash, nodeip, GULM_MAX_CSID_LEN);
|
||||
ninfo = dm_hash_lookup_binary(node_hash, nodeip, GULM_MAX_CSID_LEN);
|
||||
if (!ninfo)
|
||||
{
|
||||
ninfo = malloc(sizeof(struct node_info));
|
||||
@@ -939,7 +936,7 @@ static int get_all_cluster_nodes()
|
||||
strcpy(ninfo->name, nodename);
|
||||
|
||||
ninfo->state = NODE_DOWN;
|
||||
hash_insert_binary(node_hash, nodeip, GULM_MAX_CSID_LEN, ninfo);
|
||||
dm_hash_insert_binary(node_hash, nodeip, GULM_MAX_CSID_LEN, ninfo);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -747,6 +747,7 @@ static int read_from_local_sock(struct local_client *thisfd)
|
||||
|
||||
/* If the client went away in mid command then tidy up */
|
||||
if (thisfd->bits.localsock.in_progress) {
|
||||
pthread_kill(thisfd->bits.localsock.threadid, SIGUSR2);
|
||||
pthread_mutex_lock(&thisfd->bits.localsock.mutex);
|
||||
thisfd->bits.localsock.state = POST_COMMAND;
|
||||
pthread_cond_signal(&thisfd->bits.localsock.cond);
|
||||
@@ -763,7 +764,6 @@ static int read_from_local_sock(struct local_client *thisfd)
|
||||
thisfd->bits.localsock.state = PRE_COMMAND;
|
||||
pthread_cond_signal(&thisfd->bits.localsock.cond);
|
||||
pthread_mutex_unlock(&thisfd->bits.localsock.mutex);
|
||||
pthread_kill(thisfd->bits.localsock.threadid, SIGUSR2);
|
||||
|
||||
jstat =
|
||||
pthread_join(thisfd->bits.localsock.threadid,
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
#include <syslog.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "libdevmapper.h"
|
||||
#include "list.h"
|
||||
#include "lvm-types.h"
|
||||
#include "libdlm.h"
|
||||
#include "clvm.h"
|
||||
#include "clvmd-comms.h"
|
||||
@@ -41,11 +44,10 @@
|
||||
#include "toolcontext.h"
|
||||
#include "log.h"
|
||||
#include "activate.h"
|
||||
#include "hash.h"
|
||||
#include "locking.h"
|
||||
|
||||
static struct cmd_context *cmd = NULL;
|
||||
static struct hash_table *lv_hash = NULL;
|
||||
static struct dm_hash_table *lv_hash = NULL;
|
||||
static pthread_mutex_t lv_hash_lock;
|
||||
|
||||
struct lv_info {
|
||||
@@ -59,7 +61,7 @@ static int get_current_lock(char *resource)
|
||||
struct lv_info *lvi;
|
||||
|
||||
pthread_mutex_lock(&lv_hash_lock);
|
||||
lvi = hash_lookup(lv_hash, resource);
|
||||
lvi = dm_hash_lookup(lv_hash, resource);
|
||||
pthread_mutex_unlock(&lv_hash_lock);
|
||||
if (lvi) {
|
||||
return lvi->lock_mode;
|
||||
@@ -71,13 +73,13 @@ static int get_current_lock(char *resource)
|
||||
/* Called at shutdown to tidy the lockspace */
|
||||
void unlock_all()
|
||||
{
|
||||
struct hash_node *v;
|
||||
struct dm_hash_node *v;
|
||||
|
||||
pthread_mutex_lock(&lv_hash_lock);
|
||||
hash_iterate(v, lv_hash) {
|
||||
struct lv_info *lvi = hash_get_data(lv_hash, v);
|
||||
dm_hash_iterate(v, lv_hash) {
|
||||
struct lv_info *lvi = dm_hash_get_data(lv_hash, v);
|
||||
|
||||
sync_unlock(hash_get_key(lv_hash, v), lvi->lock_id);
|
||||
sync_unlock(dm_hash_get_key(lv_hash, v), lvi->lock_id);
|
||||
}
|
||||
pthread_mutex_unlock(&lv_hash_lock);
|
||||
}
|
||||
@@ -92,7 +94,7 @@ int hold_lock(char *resource, int mode, int flags)
|
||||
flags &= LKF_NOQUEUE; /* Only LKF_NOQUEUE is valid here */
|
||||
|
||||
pthread_mutex_lock(&lv_hash_lock);
|
||||
lvi = hash_lookup(lv_hash, resource);
|
||||
lvi = dm_hash_lookup(lv_hash, resource);
|
||||
pthread_mutex_unlock(&lv_hash_lock);
|
||||
if (lvi) {
|
||||
/* Already exists - convert it */
|
||||
@@ -122,7 +124,7 @@ int hold_lock(char *resource, int mode, int flags)
|
||||
strerror(errno));
|
||||
} else {
|
||||
pthread_mutex_lock(&lv_hash_lock);
|
||||
hash_insert(lv_hash, resource, lvi);
|
||||
dm_hash_insert(lv_hash, resource, lvi);
|
||||
pthread_mutex_unlock(&lv_hash_lock);
|
||||
}
|
||||
errno = saved_errno;
|
||||
@@ -138,7 +140,7 @@ int hold_unlock(char *resource)
|
||||
int saved_errno;
|
||||
|
||||
pthread_mutex_lock(&lv_hash_lock);
|
||||
lvi = hash_lookup(lv_hash, resource);
|
||||
lvi = dm_hash_lookup(lv_hash, resource);
|
||||
pthread_mutex_unlock(&lv_hash_lock);
|
||||
if (!lvi) {
|
||||
DEBUGLOG("hold_unlock, lock not already held\n");
|
||||
@@ -149,7 +151,7 @@ int hold_unlock(char *resource)
|
||||
saved_errno = errno;
|
||||
if (!status) {
|
||||
pthread_mutex_lock(&lv_hash_lock);
|
||||
hash_remove(lv_hash, resource);
|
||||
dm_hash_remove(lv_hash, resource);
|
||||
pthread_mutex_unlock(&lv_hash_lock);
|
||||
free(lvi);
|
||||
} else {
|
||||
@@ -168,11 +170,12 @@ int hold_unlock(char *resource)
|
||||
*/
|
||||
|
||||
/* Activate LV exclusive or non-exclusive */
|
||||
static int do_activate_lv(char *resource, int mode)
|
||||
static int do_activate_lv(char *resource, unsigned char lock_flags, int mode)
|
||||
{
|
||||
int oldmode;
|
||||
int status;
|
||||
int activate_lv;
|
||||
int exclusive = 0;
|
||||
struct lvinfo lvi;
|
||||
|
||||
/* Is it already open ? */
|
||||
@@ -189,13 +192,17 @@ static int do_activate_lv(char *resource, int mode)
|
||||
return 0; /* Success, we did nothing! */
|
||||
|
||||
/* Do we need to activate exclusively? */
|
||||
if (activate_lv == 2)
|
||||
if ((activate_lv == 2) || (mode == LKM_EXMODE)) {
|
||||
exclusive = 1;
|
||||
mode = LKM_EXMODE;
|
||||
}
|
||||
|
||||
/* OK, try to get the lock */
|
||||
status = hold_lock(resource, mode, LKF_NOQUEUE);
|
||||
if (status)
|
||||
return errno;
|
||||
/* Try to get the lock if it's a clustered volume group */
|
||||
if (lock_flags & LCK_CLUSTER_VG) {
|
||||
status = hold_lock(resource, mode, LKF_NOQUEUE);
|
||||
if (status)
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* If it's suspended then resume it */
|
||||
if (!lv_info_by_lvid(cmd, resource, &lvi, 0))
|
||||
@@ -206,7 +213,7 @@ static int do_activate_lv(char *resource, int mode)
|
||||
return EIO;
|
||||
|
||||
/* Now activate it */
|
||||
if (!lv_activate(cmd, resource))
|
||||
if (!lv_activate(cmd, resource, exclusive))
|
||||
return EIO;
|
||||
|
||||
return 0;
|
||||
@@ -255,14 +262,14 @@ static int do_suspend_lv(char *resource)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_deactivate_lv(char *resource)
|
||||
static int do_deactivate_lv(char *resource, unsigned char lock_flags)
|
||||
{
|
||||
int oldmode;
|
||||
int status;
|
||||
|
||||
/* Is it open ? */
|
||||
oldmode = get_current_lock(resource);
|
||||
if (oldmode == -1) {
|
||||
if (oldmode == -1 && (lock_flags & LCK_CLUSTER_VG)) {
|
||||
DEBUGLOG("do_deactivate_lock, lock not already held\n");
|
||||
return 0; /* We don't need to do anything */
|
||||
}
|
||||
@@ -270,9 +277,11 @@ static int do_deactivate_lv(char *resource)
|
||||
if (!lv_deactivate(cmd, resource))
|
||||
return EIO;
|
||||
|
||||
status = hold_unlock(resource);
|
||||
if (status)
|
||||
return errno;
|
||||
if (lock_flags & LCK_CLUSTER_VG) {
|
||||
status = hold_unlock(resource);
|
||||
if (status)
|
||||
return errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -283,7 +292,7 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
DEBUGLOG("do_lock_lv: resource '%s', cmd = 0x%x, flags = %d\n",
|
||||
DEBUGLOG("do_lock_lv: resource '%s', cmd = 0x%x, flags = %x\n",
|
||||
resource, command, lock_flags);
|
||||
|
||||
if (!cmd->config_valid || config_files_changed(cmd)) {
|
||||
@@ -296,7 +305,7 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
|
||||
|
||||
switch (command) {
|
||||
case LCK_LV_EXCLUSIVE:
|
||||
status = do_activate_lv(resource, LKM_EXMODE);
|
||||
status = do_activate_lv(resource, lock_flags, LKM_EXMODE);
|
||||
break;
|
||||
|
||||
case LCK_LV_SUSPEND:
|
||||
@@ -309,11 +318,11 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
|
||||
break;
|
||||
|
||||
case LCK_LV_ACTIVATE:
|
||||
status = do_activate_lv(resource, LKM_CRMODE);
|
||||
status = do_activate_lv(resource, lock_flags, LKM_CRMODE);
|
||||
break;
|
||||
|
||||
case LCK_LV_DEACTIVATE:
|
||||
status = do_deactivate_lv(resource);
|
||||
status = do_deactivate_lv(resource, lock_flags);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -323,7 +332,7 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
|
||||
}
|
||||
|
||||
/* clean the pool for another command */
|
||||
pool_empty(cmd->mem);
|
||||
dm_pool_empty(cmd->mem);
|
||||
|
||||
DEBUGLOG("Command return is %d\n", status);
|
||||
return status;
|
||||
@@ -433,23 +442,24 @@ static void drop_vg_locks()
|
||||
*/
|
||||
static void *get_initial_state()
|
||||
{
|
||||
char lv[64], vg[64], flags[25];
|
||||
char lv[64], vg[64], flags[25], vg_flags[25];
|
||||
char uuid[65];
|
||||
char line[255];
|
||||
FILE *lvs =
|
||||
popen
|
||||
("lvm lvs --nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr",
|
||||
("lvm lvs --nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr,vg_attr",
|
||||
"r");
|
||||
|
||||
if (!lvs)
|
||||
return NULL;
|
||||
|
||||
while (fgets(line, sizeof(line), lvs)) {
|
||||
if (sscanf(line, "%s %s %s\n", vg, lv, flags) == 3) {
|
||||
if (sscanf(line, "%s %s %s %s\n", vg, lv, flags, vg_flags) == 4) {
|
||||
|
||||
/* States: s:suspended a:active S:dropped snapshot I:invalid snapshot */
|
||||
if (strlen(vg) == 38 && /* is is a valid UUID ? */
|
||||
(flags[4] == 'a' || flags[4] == 's')) { /* is it active or suspended? */
|
||||
(flags[4] == 'a' || flags[4] == 's') && /* is it active or suspended? */
|
||||
vg_flags[5] == 'c') { /* is it clustered ? */
|
||||
/* Convert hyphen-separated UUIDs into one */
|
||||
memcpy(&uuid[0], &vg[0], 6);
|
||||
memcpy(&uuid[6], &vg[7], 4);
|
||||
@@ -503,7 +513,7 @@ static void check_config()
|
||||
void init_lvhash()
|
||||
{
|
||||
/* Create hash table for keeping LV locks & status */
|
||||
lv_hash = hash_create(100);
|
||||
lv_hash = dm_hash_create(100);
|
||||
pthread_mutex_init(&lv_hash_lock, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,17 +35,17 @@
|
||||
#include <netdb.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "libdevmapper.h"
|
||||
#include "clvm.h"
|
||||
#include "clvmd-comms.h"
|
||||
#include "clvmd.h"
|
||||
#include "clvmd-gulm.h"
|
||||
#include "hash.h"
|
||||
|
||||
#define DEFAULT_TCP_PORT 21064
|
||||
|
||||
static int listen_fd = -1;
|
||||
static int tcp_port;
|
||||
struct hash_table *sock_hash;
|
||||
struct dm_hash_table *sock_hash;
|
||||
|
||||
static int get_our_ip_address(char *addr, int *family);
|
||||
static int read_from_tcpsock(struct local_client *fd, char *buf, int len, char *csid,
|
||||
@@ -56,7 +56,7 @@ int init_comms(unsigned short port)
|
||||
{
|
||||
struct sockaddr_in6 addr;
|
||||
|
||||
sock_hash = hash_create(100);
|
||||
sock_hash = dm_hash_create(100);
|
||||
tcp_port = port ? port : DEFAULT_TCP_PORT;
|
||||
|
||||
listen_fd = socket(AF_INET6, SOCK_STREAM, 0);
|
||||
@@ -101,10 +101,10 @@ void tcp_remove_client(char *csid)
|
||||
job of clvmd.c whch will do the job when it notices the
|
||||
other end has gone. We just need to remove the client(s) from
|
||||
the hash table so we don't try to use it for sending any more */
|
||||
client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
if (client)
|
||||
{
|
||||
hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
dm_hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
client->removeme = 1;
|
||||
close(client->fd);
|
||||
}
|
||||
@@ -112,10 +112,10 @@ void tcp_remove_client(char *csid)
|
||||
/* Look for a mangled one too */
|
||||
csid[0] ^= 0x80;
|
||||
|
||||
client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
if (client)
|
||||
{
|
||||
hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
dm_hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
client->removeme = 1;
|
||||
close(client->fd);
|
||||
}
|
||||
@@ -146,7 +146,7 @@ int alloc_client(int fd, char *csid, struct local_client **new_client)
|
||||
*new_client = client;
|
||||
|
||||
/* Add to our list of node sockets */
|
||||
if (hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
|
||||
if (dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
|
||||
{
|
||||
DEBUGLOG("alloc_client mangling CSID for second connection\n");
|
||||
/* This is a duplicate connection but we can't close it because
|
||||
@@ -159,7 +159,7 @@ int alloc_client(int fd, char *csid, struct local_client **new_client)
|
||||
|
||||
/* If it still exists then kill the connection as we should only
|
||||
ever have one incoming connection from each node */
|
||||
if (hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
|
||||
if (dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
|
||||
{
|
||||
DEBUGLOG("Multiple incoming connections from node\n");
|
||||
syslog(LOG_ERR, " Bogus incoming connection from %d.%d.%d.%d\n", csid[0],csid[1],csid[2],csid[3]);
|
||||
@@ -169,7 +169,7 @@ int alloc_client(int fd, char *csid, struct local_client **new_client)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
hash_insert_binary(sock_hash, csid, GULM_MAX_CSID_LEN, client);
|
||||
dm_hash_insert_binary(sock_hash, csid, GULM_MAX_CSID_LEN, client);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -302,7 +302,7 @@ static int read_from_tcpsock(struct local_client *client, char *buf, int len, ch
|
||||
/* If the csid was mangled, then make sure we remove the right entry */
|
||||
if (client->bits.net.flags)
|
||||
remcsid[0] ^= 0x80;
|
||||
hash_remove_binary(sock_hash, remcsid, GULM_MAX_CSID_LEN);
|
||||
dm_hash_remove_binary(sock_hash, remcsid, GULM_MAX_CSID_LEN);
|
||||
|
||||
/* Tell cluster manager layer */
|
||||
add_down_node(remcsid);
|
||||
@@ -381,7 +381,7 @@ static int tcp_send_message(void *buf, int msglen, unsigned char *csid, const ch
|
||||
if (memcmp(csid, ourcsid, GULM_MAX_CSID_LEN) == 0)
|
||||
return msglen;
|
||||
|
||||
client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
|
||||
if (!client)
|
||||
{
|
||||
status = gulm_connect_csid(csid, &client);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
process_event
|
||||
register_device
|
||||
unregister_device
|
||||
dm_register_for_event
|
||||
dm_unregister_for_event
|
||||
dm_get_registered_device
|
||||
dm_set_event_timeout
|
||||
dm_get_event_timeout
|
||||
|
||||
@@ -1,51 +1,56 @@
|
||||
#
|
||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
# Copyright (C) 2005 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of the device-mapper userspace tools.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing to use,
|
||||
# modify, copy, or redistribute it subject to the terms and conditions
|
||||
# of the GNU General Public License v.2.
|
||||
# of the GNU Lesser General Public License v.2.1.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
interface = @interface@
|
||||
|
||||
TARGETS = dmevent dmeventd
|
||||
INSTALL_TYPE = install_dynamic
|
||||
SOURCES = libdevmapper-event.c \
|
||||
dmeventd.c
|
||||
|
||||
SOURCES = noop.c
|
||||
CLEAN_TARGETS = dmevent.o dmeventd.o
|
||||
LIB_STATIC = libdevmapper-event.a
|
||||
|
||||
ifeq ("@LIB_SUFFIX@","dylib")
|
||||
LIB_SHARED = libdmeventdnoop.dylib
|
||||
LIB_SHARED = libdevmapper-event.dylib
|
||||
else
|
||||
LIB_SHARED = libdmeventdnoop.so
|
||||
LIB_SHARED = libdevmapper-event.so
|
||||
endif
|
||||
|
||||
LDFLAGS += -ldl -ldevmapper -lmultilog
|
||||
|
||||
CLDFLAGS += -ldl -ldevmapper -lpthread
|
||||
|
||||
include ../make.tmpl
|
||||
|
||||
libdmeventdnoop.so: noop.o
|
||||
.PHONY: install_dynamic install_static
|
||||
|
||||
dmevent: dmevent.o $(interfacedir)/libdevmapper.$(LIB_SUFFIX) $(top_srcdir)/lib/event/libdmevent.$(LIB_SUFFIX)
|
||||
$(CC) -o $@ dmevent.o $(LDFLAGS) \
|
||||
-L$(interfacedir) -L$(DESTDIR)/lib -L$(top_srcdir)/lib/event -L$(top_srcdir)/multilog $(LIBS)
|
||||
INSTALL_TYPE = install_dynamic
|
||||
|
||||
dmeventd: dmeventd.o $(interfacedir)/libdevmapper.$(LIB_SUFFIX) $(top_srcdir)/lib/event/libdmevent.$(LIB_SUFFIX)
|
||||
$(CC) -o $@ dmeventd.o $(LDFLAGS) \
|
||||
-L$(interfacedir) -L$(DESTDIR)/lib -L$(top_srcdir)/lib/event -L$(top_srcdir)/multilog -lpthread -ldmevent $(LIBS)
|
||||
ifeq ("@STATIC_LINK@", "yes")
|
||||
INSTALL_TYPE += install_static
|
||||
endif
|
||||
|
||||
install: $(INSTALL_TYPE)
|
||||
|
||||
.PHONY: install_dynamic
|
||||
install_dynamic: libdevmapper-event.$(LIB_SUFFIX)
|
||||
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
|
||||
$(libdir)/libdevmapper-event.$(LIB_SUFFIX).$(LIB_VERSION)
|
||||
$(LN_S) -f libdevmapper-event.$(LIB_SUFFIX).$(LIB_VERSION) \
|
||||
$(libdir)/libdevmapper-event.$(LIB_SUFFIX)
|
||||
$(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper-event.h \
|
||||
$(includedir)/libdevmapper-event.h
|
||||
|
||||
install_dynamic: dmeventd
|
||||
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) dmeventd $(sbindir)/dmeventd
|
||||
install_static: libdevmapper-event.a
|
||||
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
|
||||
$(libdir)/libdevmapper-event.a.$(LIB_VERSION)
|
||||
$(LN_S) -f libdevmapper-event.a.$(LIB_VERSION) $(libdir)/libdevmapper-event.a
|
||||
|
||||
|
||||
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of the device-mapper userspace tools.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use,
|
||||
* modify, copy, or redistribute it subject to the terms and conditions
|
||||
* of the GNU Lesser General Public License v.2.1.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "libdevmapper.h"
|
||||
#include "libdm-event.h"
|
||||
#include "libmultilog.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
static enum event_type events = ALL_ERRORS; /* All until we can distinguish. */
|
||||
static char default_dso_name[] = "noop"; /* default DSO is noop */
|
||||
static int default_reg = 1; /* default action is register */
|
||||
static uint32_t timeout;
|
||||
|
||||
struct event_ops {
|
||||
int (*dm_register_for_event)(char *dso_name, char *device,
|
||||
enum event_type event_types);
|
||||
int (*dm_unregister_for_event)(char *dso_name, char *device,
|
||||
enum event_type event_types);
|
||||
int (*dm_get_registered_device)(char **dso_name, char **device,
|
||||
enum event_type *event_types, int next);
|
||||
int (*dm_set_event_timeout)(char *device, uint32_t time);
|
||||
int (*dm_get_event_timeout)(char *device, uint32_t *time);
|
||||
};
|
||||
|
||||
/* Display help. */
|
||||
static void print_usage(char *name)
|
||||
{
|
||||
char *cmd = strrchr(name, '/');
|
||||
|
||||
cmd = cmd ? cmd + 1 : name;
|
||||
printf("Usage::\n"
|
||||
"%s [options] <device>\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
" -d <dso> Specify the DSO to use.\n"
|
||||
" -h Print this usage.\n"
|
||||
" -l List registered devices.\n"
|
||||
" -r Register for event (default).\n"
|
||||
" -t <timeout> (un)register for timeout event.\n"
|
||||
" -u Unregister for event.\n"
|
||||
"\n", cmd);
|
||||
}
|
||||
|
||||
/* Parse command line arguments. */
|
||||
static int parse_argv(int argc, char **argv, char **dso_name_arg,
|
||||
char **device_arg, int *reg, int *list)
|
||||
{
|
||||
int c;
|
||||
const char *options = "d:hlrt:u";
|
||||
|
||||
while ((c = getopt(argc, argv, options)) != -1) {
|
||||
switch (c) {
|
||||
case 'd':
|
||||
*dso_name_arg = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
print_usage(argv[0]);
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'l':
|
||||
*list = 1;
|
||||
break;
|
||||
case 'r':
|
||||
*reg = 1;
|
||||
break;
|
||||
case 't':
|
||||
events = TIMEOUT;
|
||||
if (sscanf(optarg, "%"SCNu32, &timeout) != 1){
|
||||
fprintf(stderr, "invalid timeout '%s'\n",
|
||||
optarg);
|
||||
timeout = 0;
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
*reg = 0;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown option '%c'.\n"
|
||||
"Try '-h' for help.\n", c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind >= argc) {
|
||||
if (!*list) {
|
||||
fprintf(stderr, "You need to specify a device.\n");
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
*device_arg = argv[optind];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int lookup_symbol(void *dl, void **symbol, const char *name)
|
||||
{
|
||||
if ((*symbol = dlsym(dl, name)))
|
||||
return 1;
|
||||
|
||||
fprintf(stderr, "error looking up %s symbol: %s\n", name, dlerror());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lookup_symbols(void *dl, struct event_ops *e)
|
||||
{
|
||||
return lookup_symbol(dl, (void *) &e->dm_register_for_event,
|
||||
"dm_register_for_event") &&
|
||||
lookup_symbol(dl, (void *) &e->dm_unregister_for_event,
|
||||
"dm_unregister_for_event") &&
|
||||
lookup_symbol(dl, (void *) &e->dm_get_registered_device,
|
||||
"dm_get_registered_device") &&
|
||||
lookup_symbol(dl, (void *) &e->dm_set_event_timeout,
|
||||
"dm_set_event_timeout") &&
|
||||
lookup_symbol(dl, (void *) &e->dm_get_event_timeout,
|
||||
"dm_get_event_timeout");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
void *dl;
|
||||
struct event_ops e;
|
||||
int list = 0, next = 0, ret, reg = default_reg;
|
||||
char *device, *device_arg = NULL, *dso_name, *dso_name_arg = NULL;
|
||||
|
||||
if (!parse_argv(argc, argv, &dso_name_arg, &device_arg, ®, &list))
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
if (device_arg) {
|
||||
if (!(device = strdup(device_arg)))
|
||||
exit(EXIT_FAILURE);
|
||||
} else
|
||||
device = NULL;
|
||||
|
||||
if (dso_name_arg) {
|
||||
if (!(dso_name = strdup(dso_name_arg)))
|
||||
exit(EXIT_FAILURE);
|
||||
} else {
|
||||
if (!(dso_name = strdup(default_dso_name)))
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* FIXME: use -v/-q options to set this */
|
||||
multilog_add_type(standard, NULL);
|
||||
multilog_init_verbose(standard, _LOG_DEBUG);
|
||||
|
||||
if (!(dl = dlopen("libdmevent.so", RTLD_NOW))){
|
||||
fprintf(stderr, "Cannot dlopen libdmevent.so: %s\n", dlerror());
|
||||
goto out;
|
||||
}
|
||||
if (!(lookup_symbols(dl, &e)))
|
||||
goto out;
|
||||
if (list) {
|
||||
while (1) {
|
||||
if ((ret= e.dm_get_registered_device(&dso_name,
|
||||
&device,
|
||||
&events, next)))
|
||||
break;
|
||||
printf("%s %s 0x%x", dso_name, device, events);
|
||||
if (events & TIMEOUT){
|
||||
if ((ret = e.dm_get_event_timeout(device,
|
||||
&timeout))) {
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
printf(" %"PRIu32"\n", timeout);
|
||||
} else
|
||||
printf("\n");
|
||||
if (device_arg)
|
||||
break;
|
||||
|
||||
next = 1;
|
||||
}
|
||||
|
||||
ret = (ret && device_arg) ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((ret = reg ? e.dm_register_for_event(dso_name, device, events) :
|
||||
e.dm_unregister_for_event(dso_name, device, events))) {
|
||||
fprintf(stderr, "Failed to %sregister %s: %s\n",
|
||||
reg ? "": "un", device, strerror(-ret));
|
||||
ret = EXIT_FAILURE;
|
||||
} else {
|
||||
if (reg && (events & TIMEOUT) &&
|
||||
((ret = e.dm_set_event_timeout(device, timeout)))){
|
||||
fprintf(stderr, "Failed to set timeout for %s: %s\n",
|
||||
device, strerror(-ret));
|
||||
ret = EXIT_FAILURE;
|
||||
} else {
|
||||
printf("%s %sregistered successfully.\n",
|
||||
device, reg ? "" : "un");
|
||||
ret = EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
multilog_del_type(standard);
|
||||
|
||||
if (device)
|
||||
free(device);
|
||||
if (dso_name)
|
||||
free(dso_name);
|
||||
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
||||
* Emacs will notice this stuff at the end of the file and automatically
|
||||
* adjust the settings for this buffer only. This must remain at the end
|
||||
* of the file.
|
||||
* ---------------------------------------------------------------------------
|
||||
* Local variables:
|
||||
* c-file-style: "linux"
|
||||
* End:
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
12
daemons/dmeventd/dmeventd.h
Normal file
12
daemons/dmeventd/dmeventd.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef __DMEVENTD_DOT_H__
|
||||
#define __DMEVENTD_DOT_H__
|
||||
|
||||
#define EXIT_LOCKFILE_INUSE 2
|
||||
#define EXIT_DESC_CLOSE_FAILURE 3
|
||||
#define EXIT_OPEN_PID_FAILURE 4
|
||||
#define EXIT_FIFO_FAILURE 5
|
||||
#define EXIT_CHDIR_FAILURE 6
|
||||
|
||||
void dmeventd(void);
|
||||
|
||||
#endif /* __DMEVENTD_DOT_H__ */
|
||||
465
daemons/dmeventd/libdevmapper-event.c
Normal file
465
daemons/dmeventd/libdevmapper-event.c
Normal file
@@ -0,0 +1,465 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of the device-mapper userspace tools.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use,
|
||||
* modify, copy, or redistribute it subject to the terms and conditions
|
||||
* of the GNU Lesser General Public License v.2.1.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "libdevmapper-event.h"
|
||||
//#include "libmultilog.h"
|
||||
#include "dmeventd.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
/* Set by any of the external fxns the first time one of them is called */
|
||||
/* FIXME Unused */
|
||||
// static int _logging = 0;
|
||||
|
||||
/* Fetch a string off src and duplicate it into *dest. */
|
||||
/* FIXME: move to seperate module to share with the daemon. */
|
||||
static const char delimiter = ' ';
|
||||
static char *fetch_string(char **src)
|
||||
{
|
||||
char *p, *ret;
|
||||
|
||||
if ((p = strchr(*src, delimiter)))
|
||||
*p = 0;
|
||||
|
||||
if ((ret = strdup(*src)))
|
||||
*src += strlen(ret) + 1;
|
||||
|
||||
if (p)
|
||||
*p = delimiter;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Parse a device message from the daemon. */
|
||||
static int parse_message(struct dm_event_daemon_message *msg, char **dso_name,
|
||||
char **device, enum dm_event_type *events)
|
||||
{
|
||||
char *p = msg->msg;
|
||||
|
||||
if ((*dso_name = fetch_string(&p)) &&
|
||||
(*device = fetch_string(&p))) {
|
||||
*events = atoi(p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Read message from daemon. */
|
||||
static int daemon_read(struct dm_event_fifos *fifos, struct dm_event_daemon_message *msg)
|
||||
{
|
||||
int bytes = 0, ret = 0;
|
||||
fd_set fds;
|
||||
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
errno = 0;
|
||||
/* FIXME Fix error handling. Check 'ret' before errno. EINTR? EAGAIN? */
|
||||
/* FIXME errno != EOF? RTFM! */
|
||||
while (bytes < sizeof(*msg) && errno != EOF) {
|
||||
do {
|
||||
/* Watch daemon read FIFO for input. */
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fifos->server, &fds);
|
||||
/* FIXME Check for errors e.g. EBADF */
|
||||
} while (select(fifos->server+1, &fds, NULL, NULL, NULL) != 1);
|
||||
|
||||
ret = read(fifos->server, msg, sizeof(*msg) - bytes);
|
||||
bytes += ret > 0 ? ret : 0;
|
||||
}
|
||||
|
||||
// log_print("%s: \"%s\"\n", __func__, msg->msg);
|
||||
return bytes == sizeof(*msg);
|
||||
}
|
||||
|
||||
/* Write message to daemon. */
|
||||
static int daemon_write(struct dm_event_fifos *fifos, struct dm_event_daemon_message *msg)
|
||||
{
|
||||
int bytes = 0, ret = 0;
|
||||
fd_set fds;
|
||||
|
||||
|
||||
// log_print("%s: \"%s\"\n", __func__, msg->msg);
|
||||
errno = 0;
|
||||
/* FIXME Fix error handling. Check 'ret' before errno. EINTR? EAGAIN? */
|
||||
while (bytes < sizeof(*msg) && errno != EIO) {
|
||||
do {
|
||||
/* Watch daemon write FIFO to be ready for output. */
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fifos->client, &fds);
|
||||
/* FIXME Check for errors e.g. EBADF */
|
||||
} while (select(fifos->client +1, NULL, &fds, NULL, NULL) != 1);
|
||||
|
||||
ret = write(fifos->client, msg, sizeof(*msg) - bytes);
|
||||
bytes += ret > 0 ? ret : 0;
|
||||
}
|
||||
|
||||
return bytes == sizeof(*msg);
|
||||
}
|
||||
|
||||
static int daemon_talk(struct dm_event_fifos *fifos, struct dm_event_daemon_message *msg,
|
||||
int cmd, char *dso_name, char *device,
|
||||
enum dm_event_type events, uint32_t timeout)
|
||||
{
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
|
||||
/*
|
||||
* Set command and pack the arguments
|
||||
* into ASCII message string.
|
||||
*/
|
||||
msg->opcode.cmd = cmd;
|
||||
|
||||
if (sizeof(msg->msg) <= snprintf(msg->msg, sizeof(msg->msg),
|
||||
"%s %s %u %"PRIu32,
|
||||
dso_name ? dso_name : "",
|
||||
device ? device : "",
|
||||
events, timeout)) {
|
||||
stack;
|
||||
return -ENAMETOOLONG;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write command and message to and
|
||||
* read status return code from daemon.
|
||||
*/
|
||||
if (!daemon_write(fifos, msg)) {
|
||||
stack;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (!daemon_read(fifos, msg)) {
|
||||
stack;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return msg->opcode.status;
|
||||
}
|
||||
|
||||
static volatile sig_atomic_t daemon_running = 0;
|
||||
|
||||
static void daemon_running_signal_handler(int sig)
|
||||
{
|
||||
daemon_running = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* start_daemon
|
||||
*
|
||||
* This function forks off a process (dmeventd) that will handle
|
||||
* the events. A signal must be returned from the child to
|
||||
* indicate when it is ready to handle requests. The parent
|
||||
* (this function) returns 1 if there is a daemon running.
|
||||
*
|
||||
* Returns: 1 on success, 0 otherwise
|
||||
*/
|
||||
static int start_daemon(void)
|
||||
{
|
||||
int pid, ret=0;
|
||||
int old_mask;
|
||||
void *old_hand;
|
||||
|
||||
/* Must be able to acquire signal */
|
||||
old_hand = signal(SIGUSR1, &daemon_running_signal_handler);
|
||||
if (old_hand == SIG_ERR) {
|
||||
log_error("Unable to setup signal handler.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef linux
|
||||
/* FIXME Deprecated. Try posix sigprocmask instead. */
|
||||
old_mask = siggetmask();
|
||||
old_mask &= ~sigmask(SIGUSR1);
|
||||
old_mask = sigsetmask(old_mask);
|
||||
#endif
|
||||
|
||||
pid = fork();
|
||||
|
||||
if (pid < 0)
|
||||
log_error("Unable to fork.\n");
|
||||
else if (pid) { /* parent waits for child to get ready for requests */
|
||||
int status;
|
||||
|
||||
/* FIXME Better way to do this? */
|
||||
while (!waitpid(pid, &status, WNOHANG) && !daemon_running)
|
||||
sleep(1);
|
||||
|
||||
if (daemon_running) {
|
||||
log_print("dmeventd started.\n");
|
||||
ret = 1;
|
||||
} else {
|
||||
switch (WEXITSTATUS(status)) {
|
||||
case EXIT_LOCKFILE_INUSE:
|
||||
/*
|
||||
* Note, this is ok... we still have daemon
|
||||
* that we can communicate with...
|
||||
*/
|
||||
log_print("Starting dmeventd failed: "
|
||||
"dmeventd already running.\n");
|
||||
ret = 1;
|
||||
break;
|
||||
default:
|
||||
log_error("Unable to start dmeventd.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
signal(SIGUSR1, SIG_IGN); /* don't care about error */
|
||||
|
||||
/* dmeventd function is responsible for properly setting **
|
||||
** itself up. It must never return - only exit. This is**
|
||||
** why it is followed by an EXIT_FAILURE */
|
||||
dmeventd();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* FIXME What if old_hand is SIG_ERR? */
|
||||
if (signal(SIGUSR1, old_hand) == SIG_ERR)
|
||||
log_error("Unable to reset signal handler.");
|
||||
sigsetmask(old_mask);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Initialize client. */
|
||||
static int init_client(struct dm_event_fifos *fifos)
|
||||
{
|
||||
/* FIXME Is fifo the most suitable method? */
|
||||
/* FIXME Why not share comms/daemon code with something else e.g. multipath? */
|
||||
|
||||
/* init fifos */
|
||||
memset(fifos, 0, sizeof(*fifos));
|
||||
fifos->client_path = DM_EVENT_FIFO_CLIENT;
|
||||
fifos->server_path = DM_EVENT_FIFO_SERVER;
|
||||
|
||||
/* FIXME The server should be responsible for these, not the client. */
|
||||
/* Create fifos */
|
||||
if (((mkfifo(fifos->client_path, 0600) == -1) && errno != EEXIST) ||
|
||||
((mkfifo(fifos->server_path, 0600) == -1) && errno != EEXIST)) {
|
||||
log_error("%s: Failed to create a fifo.\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME Warn/abort if perms are wrong - not something to fix silently. */
|
||||
/* If they were already there, make sure permissions are ok. */
|
||||
if (chmod(fifos->client_path, 0600)) {
|
||||
log_error("Unable to set correct file permissions on %s",
|
||||
fifos->client_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (chmod(fifos->server_path, 0600)) {
|
||||
log_error("Unable to set correct file permissions on %s",
|
||||
fifos->server_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the fifo used to read from the daemon.
|
||||
* Allows daemon to create its write fifo...
|
||||
*/
|
||||
if ((fifos->server = open(fifos->server_path, O_RDWR)) < 0) {
|
||||
log_error("%s: open server fifo %s\n",
|
||||
__func__, fifos->server_path);
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Lock out anyone else trying to do communication with the daemon. */
|
||||
/* FIXME Why failure not retry? How do multiple processes communicate? */
|
||||
if (flock(fifos->server, LOCK_EX) < 0){
|
||||
log_error("%s: flock %s\n", __func__, fifos->server_path);
|
||||
close(fifos->server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Anyone listening? If not, errno will be ENXIO */
|
||||
if ((fifos->client = open(fifos->client_path,
|
||||
O_WRONLY | O_NONBLOCK)) < 0) {
|
||||
if (errno != ENXIO) {
|
||||
log_error("%s: open client fifo %s\n",
|
||||
__func__, fifos->client_path);
|
||||
close(fifos->server);
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME Unnecessary if daemon was started before calling this */
|
||||
if (!start_daemon()) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME Unnecessary if daemon was started before calling this */
|
||||
/* Daemon is started, retry the open */
|
||||
fifos->client = open(fifos->client_path, O_WRONLY | O_NONBLOCK);
|
||||
if (fifos->client < 0) {
|
||||
log_error("%s: open client fifo %s\n",
|
||||
__func__, fifos->client_path);
|
||||
close(fifos->server);
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void dtr_client(struct dm_event_fifos *fifos)
|
||||
{
|
||||
if (flock(fifos->server, LOCK_UN))
|
||||
log_error("flock unlock %s\n", fifos->server_path);
|
||||
|
||||
close(fifos->client);
|
||||
close(fifos->server);
|
||||
}
|
||||
|
||||
/* Check, if a block device exists. */
|
||||
static int device_exists(char *device)
|
||||
{
|
||||
struct stat st_buf;
|
||||
char path2[PATH_MAX];
|
||||
|
||||
if (!device)
|
||||
return 0;
|
||||
|
||||
if (device[0] == '/') /* absolute path */
|
||||
return !stat(device, &st_buf) && S_ISBLK(st_buf.st_mode);
|
||||
|
||||
if (PATH_MAX <= snprintf(path2, PATH_MAX, "%s/%s", dm_dir(), device))
|
||||
return 0;
|
||||
|
||||
return !stat(path2, &st_buf) && S_ISBLK(st_buf.st_mode);
|
||||
}
|
||||
|
||||
/* Handle the event (de)registration call and return negative error codes. */
|
||||
static int do_event(int cmd, struct dm_event_daemon_message *msg,
|
||||
char *dso_name, char *device, enum dm_event_type events,
|
||||
uint32_t timeout)
|
||||
{
|
||||
int ret;
|
||||
struct dm_event_fifos fifos;
|
||||
|
||||
/* FIXME Start the daemon here if it's not running e.g. exclusive lock file */
|
||||
|
||||
if (!init_client(&fifos)) {
|
||||
stack;
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
ret = daemon_talk(&fifos, msg, cmd, dso_name, device, events, timeout);
|
||||
|
||||
/* what is the opposite of init? */
|
||||
dtr_client(&fifos);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* External library interface. */
|
||||
int dm_event_register(char *dso_name, char *device_path,
|
||||
enum dm_event_type events)
|
||||
{
|
||||
struct dm_event_daemon_message msg;
|
||||
|
||||
if (!device_exists(device_path))
|
||||
return -ENODEV;
|
||||
|
||||
return do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, &msg,
|
||||
dso_name, device_path, events, 0);
|
||||
}
|
||||
|
||||
int dm_event_unregister(char *dso_name, char *device_path,
|
||||
enum dm_event_type events)
|
||||
{
|
||||
struct dm_event_daemon_message msg;
|
||||
|
||||
if (!device_exists(device_path))
|
||||
return -ENODEV;
|
||||
|
||||
return do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, &msg,
|
||||
dso_name, device_path, events, 0);
|
||||
}
|
||||
|
||||
int dm_event_get_registered_device(char **dso_name, char **device_path,
|
||||
enum dm_event_type *events, int next)
|
||||
{
|
||||
int ret;
|
||||
char *dso_name_arg = NULL, *device_path_arg = NULL;
|
||||
struct dm_event_daemon_message msg;
|
||||
|
||||
if (!(ret = do_event(next ? DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE :
|
||||
DM_EVENT_CMD_GET_REGISTERED_DEVICE,
|
||||
&msg, *dso_name, *device_path, *events, 0)))
|
||||
ret = parse_message(&msg, &dso_name_arg, &device_path_arg,
|
||||
events);
|
||||
|
||||
if (next){
|
||||
if (*dso_name)
|
||||
free(*dso_name);
|
||||
if (*device_path)
|
||||
free(*device_path);
|
||||
*dso_name = dso_name_arg;
|
||||
*device_path = device_path_arg;
|
||||
} else {
|
||||
if (!(*dso_name))
|
||||
*dso_name = dso_name_arg;
|
||||
if (!(*device_path))
|
||||
*device_path = device_path_arg;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dm_event_set_timeout(char *device_path, uint32_t timeout)
|
||||
{
|
||||
struct dm_event_daemon_message msg;
|
||||
|
||||
if (!device_exists(device_path))
|
||||
return -ENODEV;
|
||||
return do_event(DM_EVENT_CMD_SET_TIMEOUT, &msg,
|
||||
NULL, device_path, 0, timeout);
|
||||
}
|
||||
|
||||
int dm_event_get_timeout(char *device_path, uint32_t *timeout)
|
||||
{
|
||||
int ret;
|
||||
struct dm_event_daemon_message msg;
|
||||
|
||||
if (!device_exists(device_path))
|
||||
return -ENODEV;
|
||||
if (!(ret = do_event(DM_EVENT_CMD_GET_TIMEOUT, &msg, NULL, device_path, 0, 0)))
|
||||
*timeout = atoi(msg.msg);
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
* Overrides for Emacs so that we follow Linus's tabbing style.
|
||||
* Emacs will notice this stuff at the end of the file and automatically
|
||||
* adjust the settings for this buffer only. This must remain at the end
|
||||
* of the file.
|
||||
* ---------------------------------------------------------------------------
|
||||
* Local variables:
|
||||
* c-file-style: "linux"
|
||||
* End:
|
||||
*/
|
||||
99
daemons/dmeventd/libdevmapper-event.h
Normal file
99
daemons/dmeventd/libdevmapper-event.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of the device-mapper userspace tools.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use,
|
||||
* modify, copy, or redistribute it subject to the terms and conditions
|
||||
* of the GNU Lesser General Public License v.2.1.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note that this file is released only as part of a technology preview
|
||||
* and its contents may change in future updates in ways that do not
|
||||
* preserve compatibility.
|
||||
*/
|
||||
|
||||
#ifndef LIB_DMEVENT_H
|
||||
#define LIB_DMEVENT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* FIXME This stuff must be configurable. */
|
||||
|
||||
#define DM_EVENT_DAEMON "/sbin/dmeventd"
|
||||
#define DM_EVENT_LOCKFILE "/var/lock/dmeventd"
|
||||
#define DM_EVENT_FIFO_CLIENT "/var/run/dmeventd-client"
|
||||
#define DM_EVENT_FIFO_SERVER "/var/run/dmeventd-server"
|
||||
#define DM_EVENT_PIDFILE "/var/run/dmeventd.pid"
|
||||
|
||||
#define DM_EVENT_DEFAULT_TIMEOUT 10
|
||||
|
||||
/* Commands for the daemon passed in the message below. */
|
||||
enum dm_event_command {
|
||||
DM_EVENT_CMD_ACTIVE = 1,
|
||||
DM_EVENT_CMD_REGISTER_FOR_EVENT,
|
||||
DM_EVENT_CMD_UNREGISTER_FOR_EVENT,
|
||||
DM_EVENT_CMD_GET_REGISTERED_DEVICE,
|
||||
DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE,
|
||||
DM_EVENT_CMD_SET_TIMEOUT,
|
||||
DM_EVENT_CMD_GET_TIMEOUT,
|
||||
};
|
||||
|
||||
/* Message passed between client and daemon. */
|
||||
struct dm_event_daemon_message {
|
||||
union {
|
||||
unsigned int cmd; /* FIXME Use fixed size. */
|
||||
int status; /* FIXME Use fixed size. */
|
||||
} opcode;
|
||||
char msg[252]; /* FIXME Why is this 252 ? */
|
||||
} __attribute__((packed)); /* FIXME Do this properly! */
|
||||
|
||||
/* FIXME Is this meant to be exported? I can't see where the interface uses it. */
|
||||
/* Fifos for client/daemon communication. */
|
||||
struct dm_event_fifos {
|
||||
int client;
|
||||
int server;
|
||||
const char *client_path;
|
||||
const char *server_path;
|
||||
};
|
||||
|
||||
/* Event type definitions. */
|
||||
/* FIXME Use masks to separate the types and provide for extension. */
|
||||
enum dm_event_type {
|
||||
DM_EVENT_SINGLE = 0x01, /* Report multiple errors just once. */
|
||||
DM_EVENT_MULTI = 0x02, /* Report all of them. */
|
||||
|
||||
DM_EVENT_SECTOR_ERROR = 0x04, /* Failure on a particular sector. */
|
||||
DM_EVENT_DEVICE_ERROR = 0x08, /* Device failure. */
|
||||
DM_EVENT_PATH_ERROR = 0x10, /* Failure on an io path. */
|
||||
DM_EVENT_ADAPTOR_ERROR = 0x20, /* Failure off a host adaptor. */
|
||||
|
||||
DM_EVENT_SYNC_STATUS = 0x40, /* Mirror synchronization completed/failed. */
|
||||
DM_EVENT_TIMEOUT = 0x80, /* Timeout has occured */
|
||||
};
|
||||
|
||||
/* FIXME Use a mask. */
|
||||
#define DM_EVENT_ALL_ERRORS (DM_EVENT_SECTOR_ERROR | DM_EVENT_DEVICE_ERROR | \
|
||||
DM_EVENT_PATH_ERROR | DM_EVENT_ADAPTOR_ERROR)
|
||||
|
||||
/* Prototypes for event lib interface. */
|
||||
/* FIXME Missing consts? */
|
||||
int dm_event_register(char *dso_name, char *device, enum dm_event_type events);
|
||||
int dm_event_unregister(char *dso_name, char *device,
|
||||
enum dm_event_type events);
|
||||
int dm_event_get_registered_device(char **dso_name, char **device,
|
||||
enum dm_event_type *events, int next);
|
||||
int dm_event_set_timeout(char *device, uint32_t timeout);
|
||||
int dm_event_get_timeout(char *device, uint32_t *timeout);
|
||||
|
||||
/* Prototypes for DSO interface. */
|
||||
void process_event(const char *device, enum dm_event_type event);
|
||||
int register_device(const char *device);
|
||||
int unregister_device(const char *device);
|
||||
|
||||
#endif
|
||||
@@ -1,12 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Create test devices for dmeventd
|
||||
#
|
||||
|
||||
trap "rm -f /tmp/tmp.$$" 0 1 2 3 15
|
||||
|
||||
echo "0 1024 zero" > /tmp/tmp.$$
|
||||
dmsetup create test /tmp/tmp.$$
|
||||
dmsetup create test1 /tmp/tmp.$$
|
||||
|
||||
kill -15 $$
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of the device-mapper userspace tools.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use,
|
||||
* modify, copy, or redistribute it subject to the terms and conditions
|
||||
* of the GNU Lesser General Public License v.2.1.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "libdm-event.h"
|
||||
#include "libmultilog.h"
|
||||
|
||||
|
||||
void process_event(char *device, enum event_type event)
|
||||
{
|
||||
log_err("[%s] %s(%d) - Device: %s, Event %d\n",
|
||||
__FILE__, __func__, __LINE__, device, event);
|
||||
}
|
||||
|
||||
int register_device(char *device)
|
||||
{
|
||||
log_err("[%s] %s(%d) - Device: %s\n",
|
||||
__FILE__, __func__, __LINE__, device);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int unregister_device(char *device)
|
||||
{
|
||||
log_err("[%s] %s(%d) - Device: %s\n",
|
||||
__FILE__, __func__, __LINE__, device);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -33,8 +33,12 @@ devices {
|
||||
# pattern, the device is accepted; otherwise if any name matches any 'r'
|
||||
# pattern it is rejected; otherwise it is accepted.
|
||||
|
||||
# Remember to run vgscan after you change this parameter to ensure
|
||||
# that the cache file gets regenerated (see below).
|
||||
# Don't have more than one filter line active at once: only one gets used.
|
||||
|
||||
# Run vgscan after you change this parameter to ensure that
|
||||
# the cache file gets regenerated (see below).
|
||||
# If it doesn't do what you expect, check the output of 'vgscan -vvvv'.
|
||||
|
||||
|
||||
# By default we accept every block device:
|
||||
filter = [ "a/.*/" ]
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
../lib/commands/toolcontext.h
|
||||
../lib/config/config.h
|
||||
../lib/config/defaults.h
|
||||
../lib/datastruct/bitset.h
|
||||
../lib/datastruct/btree.h
|
||||
../lib/datastruct/hash.h
|
||||
../lib/datastruct/list.h
|
||||
../lib/datastruct/lvm-types.h
|
||||
../lib/datastruct/str_list.h
|
||||
@@ -34,16 +32,14 @@
|
||||
../lib/metadata/metadata.h
|
||||
../lib/metadata/pv_alloc.h
|
||||
../lib/metadata/segtype.h
|
||||
../lib/mm/dbg_malloc.h
|
||||
../lib/mm/memlock.h
|
||||
../lib/mm/pool.h
|
||||
../lib/mm/xlate.h
|
||||
../lib/misc/crc.h
|
||||
../lib/misc/intl.h
|
||||
../lib/misc/lib.h
|
||||
../lib/misc/lvm-exec.h
|
||||
../lib/misc/lvm-file.h
|
||||
../lib/misc/lvm-string.h
|
||||
../lib/misc/selinux.h
|
||||
../lib/misc/sharedlib.h
|
||||
../lib/regex/matcher.h
|
||||
../lib/report/report.h
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
# Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This file is part of the LVM2.
|
||||
#
|
||||
@@ -37,9 +37,7 @@ SOURCES =\
|
||||
cache/lvmcache.c \
|
||||
commands/toolcontext.c \
|
||||
config/config.c \
|
||||
datastruct/bitset.c \
|
||||
datastruct/btree.c \
|
||||
datastruct/hash.c \
|
||||
datastruct/str_list.c \
|
||||
device/dev-cache.c \
|
||||
device/dev-io.c \
|
||||
@@ -76,11 +74,10 @@ SOURCES =\
|
||||
metadata/segtype.c \
|
||||
metadata/snapshot_manip.c \
|
||||
misc/crc.c \
|
||||
misc/lvm-exec.c \
|
||||
misc/lvm-file.c \
|
||||
misc/lvm-string.c \
|
||||
mm/dbg_malloc.c \
|
||||
mm/memlock.c \
|
||||
mm/pool.c \
|
||||
regex/matcher.c \
|
||||
regex/parse_rx.c \
|
||||
regex/ttree.c \
|
||||
@@ -136,10 +133,6 @@ ifeq ("@HAVE_LIBDL@", "yes")
|
||||
misc/sharedlib.c
|
||||
endif
|
||||
|
||||
ifeq ("@HAVE_SELINUX@", "yes")
|
||||
SOURCES += misc/selinux.c
|
||||
endif
|
||||
|
||||
LIB_STATIC = liblvm.a
|
||||
|
||||
$(SUBDIRS): $(LIB_STATIC)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
@@ -19,13 +19,14 @@
|
||||
#include "memlock.h"
|
||||
#include "display.h"
|
||||
#include "fs.h"
|
||||
#include "lvm-exec.h"
|
||||
#include "lvm-file.h"
|
||||
#include "lvm-string.h"
|
||||
#include "pool.h"
|
||||
#include "toolcontext.h"
|
||||
#include "dev_manager.h"
|
||||
#include "str_list.h"
|
||||
#include "config.h"
|
||||
#include "filter.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <fcntl.h>
|
||||
@@ -78,7 +79,7 @@ int target_present(const char *target_name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int lv_info(const struct logical_volume *lv, struct lvinfo *info,
|
||||
int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, struct lvinfo *info,
|
||||
int with_open_count)
|
||||
{
|
||||
return 0;
|
||||
@@ -130,11 +131,11 @@ int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
int lv_activate(struct cmd_context *cmd, const char *lvid_s)
|
||||
int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s)
|
||||
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@@ -144,6 +145,12 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int pv_uses_vg(struct cmd_context *cmd, struct physical_volume *pv,
|
||||
struct volume_group *vg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void activation_exit(void)
|
||||
{
|
||||
return;
|
||||
@@ -257,53 +264,28 @@ int library_version(char *version, size_t size)
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
if (!dm_get_library_version(version, size))
|
||||
return 0;
|
||||
return 1;
|
||||
return dm_get_library_version(version, size);
|
||||
}
|
||||
|
||||
int driver_version(char *version, size_t size)
|
||||
{
|
||||
int r = 0;
|
||||
struct dm_task *dmt;
|
||||
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
log_very_verbose("Getting driver version");
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_VERSION))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!dm_task_run(dmt))
|
||||
log_error("Failed to get driver version");
|
||||
|
||||
if (!dm_task_get_driver_version(dmt, version, size))
|
||||
goto out;
|
||||
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
|
||||
return r;
|
||||
return dm_driver_version(version, size);
|
||||
}
|
||||
|
||||
int target_present(const char *target_name)
|
||||
static int _target_present(const char *target_name)
|
||||
{
|
||||
int r = 0;
|
||||
struct dm_task *dmt;
|
||||
struct dm_versions *target, *last_target;
|
||||
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
log_very_verbose("Getting target version for %s", target_name);
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
|
||||
return_0;
|
||||
|
||||
if (!dm_task_run(dmt)) {
|
||||
log_debug("Failed to get %s target version", target_name);
|
||||
@@ -330,26 +312,56 @@ int target_present(const char *target_name)
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if info structure populated, else 0 on failure.
|
||||
*/
|
||||
static int _lv_info(const struct logical_volume *lv, int mknodes,
|
||||
struct lvinfo *info, int with_open_count)
|
||||
int target_present(const char *target_name, int use_modprobe)
|
||||
{
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
struct dm_info dminfo;
|
||||
#ifdef MODPROBE_CMD
|
||||
char module[128];
|
||||
#endif
|
||||
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
#ifdef MODPROBE_CMD
|
||||
if (use_modprobe) {
|
||||
if (_target_present(target_name))
|
||||
return 1;
|
||||
|
||||
if (!(r = dev_manager_info(dm, lv, mknodes, with_open_count, &dminfo)))
|
||||
stack;
|
||||
if (lvm_snprintf(module, sizeof(module), "dm-%s", target_name)
|
||||
< 0) {
|
||||
log_error("target_present module name too long: %s",
|
||||
target_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!exec_cmd(MODPROBE_CMD, module, "", ""))
|
||||
return_0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return _target_present(target_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if info structure populated, else 0 on failure.
|
||||
*/
|
||||
static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int with_mknodes,
|
||||
struct lvinfo *info, int with_open_count)
|
||||
{
|
||||
struct dm_info dminfo;
|
||||
char *name;
|
||||
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
if (!(name = build_dm_name(cmd->mem, lv->vg->name, lv->name, NULL)))
|
||||
return_0;
|
||||
|
||||
log_debug("Getting device info for %s", name);
|
||||
if (!dev_manager_info(lv->vg->cmd->mem, name, lv, with_mknodes,
|
||||
with_open_count, &dminfo)) {
|
||||
dm_pool_free(cmd->mem, name);
|
||||
return_0;
|
||||
}
|
||||
|
||||
info->exists = dminfo.exists;
|
||||
info->suspended = dminfo.suspended;
|
||||
@@ -357,15 +369,17 @@ static int _lv_info(const struct logical_volume *lv, int mknodes,
|
||||
info->major = dminfo.major;
|
||||
info->minor = dminfo.minor;
|
||||
info->read_only = dminfo.read_only;
|
||||
info->live_table = dminfo.live_table;
|
||||
info->inactive_table = dminfo.inactive_table;
|
||||
|
||||
dev_manager_destroy(dm);
|
||||
return r;
|
||||
dm_pool_free(cmd->mem, name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lv_info(const struct logical_volume *lv, struct lvinfo *info,
|
||||
int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, struct lvinfo *info,
|
||||
int with_open_count)
|
||||
{
|
||||
return _lv_info(lv, 0, info, with_open_count);
|
||||
return _lv_info(cmd, lv, 0, info, with_open_count);
|
||||
}
|
||||
|
||||
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
|
||||
@@ -373,10 +387,10 @@ int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
|
||||
{
|
||||
struct logical_volume *lv;
|
||||
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s)))
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
|
||||
return 0;
|
||||
|
||||
return _lv_info(lv, 0, info, with_open_count);
|
||||
return _lv_info(cmd, lv, 0, info, with_open_count);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -390,10 +404,8 @@ int lv_snapshot_percent(struct logical_volume *lv, float *percent)
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
|
||||
return_0;
|
||||
|
||||
if (!(r = dev_manager_snapshot_percent(dm, lv, percent)))
|
||||
stack;
|
||||
@@ -404,7 +416,7 @@ int lv_snapshot_percent(struct logical_volume *lv, float *percent)
|
||||
}
|
||||
|
||||
/* FIXME Merge with snapshot_percent */
|
||||
int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
|
||||
int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv, int wait, float *percent,
|
||||
uint32_t *event_nr)
|
||||
{
|
||||
int r;
|
||||
@@ -414,18 +426,14 @@ int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
if (!lv_info(lv, &info, 0)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!lv_info(cmd, lv, &info, 0))
|
||||
return_0;
|
||||
|
||||
if (!info.exists)
|
||||
return 0;
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
|
||||
return_0;
|
||||
|
||||
if (!(r = dev_manager_mirror_percent(dm, lv, wait, percent, event_nr)))
|
||||
stack;
|
||||
@@ -435,11 +443,11 @@ int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _lv_active(struct logical_volume *lv)
|
||||
static int _lv_active(struct cmd_context *cmd, struct logical_volume *lv)
|
||||
{
|
||||
struct lvinfo info;
|
||||
|
||||
if (!lv_info(lv, &info, 0)) {
|
||||
if (!lv_info(cmd, lv, &info, 0)) {
|
||||
stack;
|
||||
return -1;
|
||||
}
|
||||
@@ -447,11 +455,11 @@ static int _lv_active(struct logical_volume *lv)
|
||||
return info.exists;
|
||||
}
|
||||
|
||||
static int _lv_open_count(struct logical_volume *lv)
|
||||
static int _lv_open_count(struct cmd_context *cmd, struct logical_volume *lv)
|
||||
{
|
||||
struct lvinfo info;
|
||||
|
||||
if (!lv_info(lv, &info, 1)) {
|
||||
if (!lv_info(cmd, lv, &info, 1)) {
|
||||
stack;
|
||||
return -1;
|
||||
}
|
||||
@@ -459,16 +467,13 @@ static int _lv_open_count(struct logical_volume *lv)
|
||||
return info.open_count;
|
||||
}
|
||||
|
||||
/* FIXME Need to detect and handle an lv rename */
|
||||
static int _lv_activate_lv(struct logical_volume *lv)
|
||||
{
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
|
||||
return_0;
|
||||
|
||||
if (!(r = dev_manager_activate(dm, lv)))
|
||||
stack;
|
||||
@@ -477,15 +482,28 @@ static int _lv_activate_lv(struct logical_volume *lv)
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _lv_preload(struct logical_volume *lv)
|
||||
{
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
|
||||
return_0;
|
||||
|
||||
if (!(r = dev_manager_preload(dm, lv)))
|
||||
stack;
|
||||
|
||||
dev_manager_destroy(dm);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _lv_deactivate(struct logical_volume *lv)
|
||||
{
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
|
||||
return_0;
|
||||
|
||||
if (!(r = dev_manager_deactivate(dm, lv)))
|
||||
stack;
|
||||
@@ -499,10 +517,8 @@ static int _lv_suspend_lv(struct logical_volume *lv)
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
|
||||
return_0;
|
||||
|
||||
if (!(r = dev_manager_suspend(dm, lv)))
|
||||
stack;
|
||||
@@ -525,7 +541,7 @@ int lvs_in_vg_activated(struct volume_group *vg)
|
||||
|
||||
list_iterate_items(lvl, &vg->lvs) {
|
||||
if (lvl->lv->status & VISIBLE_LV)
|
||||
count += (_lv_active(lvl->lv) == 1);
|
||||
count += (_lv_active(vg->cmd, lvl->lv) == 1);
|
||||
}
|
||||
|
||||
return count;
|
||||
@@ -541,7 +557,7 @@ int lvs_in_vg_opened(struct volume_group *vg)
|
||||
|
||||
list_iterate_items(lvl, &vg->lvs) {
|
||||
if (lvl->lv->status & VISIBLE_LV)
|
||||
count += (_lv_open_count(lvl->lv) > 0);
|
||||
count += (_lv_open_count(vg->cmd, lvl->lv) > 0);
|
||||
}
|
||||
|
||||
return count;
|
||||
@@ -556,7 +572,8 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||
if (!activation())
|
||||
return 1;
|
||||
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s)))
|
||||
/* Use precommitted metadata if present */
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s, 1)))
|
||||
return 0;
|
||||
|
||||
if (test_mode()) {
|
||||
@@ -564,14 +581,20 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!lv_info(lv, &info, 0)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!lv_info(cmd, lv, &info, 0))
|
||||
return_0;
|
||||
|
||||
if (!info.exists || info.suspended)
|
||||
return error_if_not_suspended ? 0 : 1;
|
||||
|
||||
/* If VG was precommitted, preload devices for the LV */
|
||||
if ((lv->vg->status & PRECOMMITTED)) {
|
||||
if (!_lv_preload(lv)) {
|
||||
/* FIXME Revert preloading */
|
||||
return_0;
|
||||
}
|
||||
}
|
||||
|
||||
memlock_inc();
|
||||
if (!_lv_suspend_lv(lv)) {
|
||||
memlock_dec();
|
||||
@@ -602,7 +625,7 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
|
||||
if (!activation())
|
||||
return 1;
|
||||
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s)))
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
|
||||
return 0;
|
||||
|
||||
if (test_mode()) {
|
||||
@@ -610,10 +633,8 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!lv_info(lv, &info, 0)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!lv_info(cmd, lv, &info, 0))
|
||||
return_0;
|
||||
|
||||
if (!info.exists || !info.suspended)
|
||||
return error_if_not_active ? 0 : 1;
|
||||
@@ -647,7 +668,7 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
|
||||
if (!activation())
|
||||
return 1;
|
||||
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s)))
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
|
||||
return 0;
|
||||
|
||||
if (test_mode()) {
|
||||
@@ -655,16 +676,14 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!lv_info(lv, &info, 1)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!lv_info(cmd, lv, &info, 1))
|
||||
return_0;
|
||||
|
||||
if (!info.exists)
|
||||
return 1;
|
||||
|
||||
if (info.open_count && (lv->status & VISIBLE_LV)) {
|
||||
log_error("LV %s/%s in use: not removing", lv->vg->name,
|
||||
log_error("LV %s/%s in use: not deactivating", lv->vg->name,
|
||||
lv->name);
|
||||
return 0;
|
||||
}
|
||||
@@ -686,7 +705,7 @@ int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
|
||||
if (!activation())
|
||||
goto activate;
|
||||
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s)))
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
|
||||
return 0;
|
||||
|
||||
if (!_passes_activation_filter(cmd, lv)) {
|
||||
@@ -701,7 +720,8 @@ int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _lv_activate(struct cmd_context *cmd, const char *lvid_s, int filter)
|
||||
static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
|
||||
int exclusive, int filter)
|
||||
{
|
||||
struct logical_volume *lv;
|
||||
struct lvinfo info;
|
||||
@@ -710,7 +730,7 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s, int filter)
|
||||
if (!activation())
|
||||
return 1;
|
||||
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s)))
|
||||
if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
|
||||
return 0;
|
||||
|
||||
if (filter && !_passes_activation_filter(cmd, lv)) {
|
||||
@@ -724,14 +744,15 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s, int filter)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!lv_info(lv, &info, 0)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!lv_info(cmd, lv, &info, 0))
|
||||
return_0;
|
||||
|
||||
if (info.exists && !info.suspended)
|
||||
if (info.exists && !info.suspended && info.live_table)
|
||||
return 1;
|
||||
|
||||
if (exclusive)
|
||||
lv->status |= ACTIVATE_EXCL;
|
||||
|
||||
memlock_inc();
|
||||
r = _lv_activate_lv(lv);
|
||||
memlock_dec();
|
||||
@@ -741,15 +762,15 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s, int filter)
|
||||
}
|
||||
|
||||
/* Activate LV */
|
||||
int lv_activate(struct cmd_context *cmd, const char *lvid_s)
|
||||
int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive)
|
||||
{
|
||||
return _lv_activate(cmd, lvid_s, 0);
|
||||
return _lv_activate(cmd, lvid_s, exclusive, 0);
|
||||
}
|
||||
|
||||
/* Activate LV only if it passes filter */
|
||||
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s)
|
||||
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive)
|
||||
{
|
||||
return _lv_activate(cmd, lvid_s, 1);
|
||||
return _lv_activate(cmd, lvid_s, exclusive, 1);
|
||||
}
|
||||
|
||||
int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
|
||||
@@ -758,15 +779,13 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
|
||||
int r = 1;
|
||||
|
||||
if (!lv) {
|
||||
r = dev_manager_mknodes();
|
||||
r = dm_mknodes(NULL);
|
||||
fs_unlock();
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!_lv_info(lv, 1, &info, 0)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
if (!_lv_info(cmd, lv, 1, &info, 0))
|
||||
return_0;
|
||||
|
||||
if (info.exists)
|
||||
r = dev_manager_lv_mknodes(lv);
|
||||
@@ -778,6 +797,34 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Does PV use VG somewhere in its construction?
|
||||
* Returns 1 on failure.
|
||||
*/
|
||||
int pv_uses_vg(struct cmd_context *cmd, struct physical_volume *pv,
|
||||
struct volume_group *vg)
|
||||
{
|
||||
struct dev_manager *dm;
|
||||
int r;
|
||||
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
if (!dm_is_dm_major(MAJOR(pv->dev->dev)))
|
||||
return 0;
|
||||
|
||||
if (!(dm = dev_manager_create(cmd, vg->name))) {
|
||||
stack;
|
||||
return 1;
|
||||
}
|
||||
|
||||
r = dev_manager_device_uses_vg(dm, pv->dev, vg);
|
||||
|
||||
dev_manager_destroy(dm);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void activation_exit(void)
|
||||
{
|
||||
dev_manager_exit();
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
|
||||
#include "metadata.h"
|
||||
|
||||
#ifdef DEVMAPPER_SUPPORT
|
||||
# include <libdevmapper.h>
|
||||
#endif
|
||||
|
||||
struct lvinfo {
|
||||
int exists;
|
||||
int suspended;
|
||||
@@ -29,6 +25,8 @@ struct lvinfo {
|
||||
int major;
|
||||
int minor;
|
||||
int read_only;
|
||||
int live_table;
|
||||
int inactive_table;
|
||||
};
|
||||
|
||||
void set_activation(int activation);
|
||||
@@ -38,7 +36,7 @@ int driver_version(char *version, size_t size);
|
||||
int library_version(char *version, size_t size);
|
||||
int lvm1_present(struct cmd_context *cmd);
|
||||
|
||||
int target_present(const char *target_name);
|
||||
int target_present(const char *target_name, int use_modprobe);
|
||||
|
||||
void activation_exit(void);
|
||||
|
||||
@@ -46,8 +44,9 @@ int lv_suspend(struct cmd_context *cmd, const char *lvid_s);
|
||||
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s);
|
||||
int lv_resume(struct cmd_context *cmd, const char *lvid_s);
|
||||
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s);
|
||||
int lv_activate(struct cmd_context *cmd, const char *lvid_s);
|
||||
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s);
|
||||
int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive);
|
||||
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s,
|
||||
int exclusive);
|
||||
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s);
|
||||
|
||||
int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv);
|
||||
@@ -55,7 +54,7 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv);
|
||||
/*
|
||||
* Returns 1 if info structure has been populated, else 0.
|
||||
*/
|
||||
int lv_info(const struct logical_volume *lv, struct lvinfo *info,
|
||||
int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, struct lvinfo *info,
|
||||
int with_open_count);
|
||||
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
|
||||
struct lvinfo *info, int with_open_count);
|
||||
@@ -70,7 +69,7 @@ int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
|
||||
* Returns 1 if percent has been set, else 0.
|
||||
*/
|
||||
int lv_snapshot_percent(struct logical_volume *lv, float *percent);
|
||||
int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
|
||||
int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv, int wait, float *percent,
|
||||
uint32_t *event_nr);
|
||||
|
||||
/*
|
||||
@@ -79,6 +78,10 @@ int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
|
||||
int lvs_in_vg_activated(struct volume_group *vg);
|
||||
int lvs_in_vg_opened(struct volume_group *vg);
|
||||
|
||||
int lv_setup_cow_store(struct logical_volume *lv);
|
||||
/*
|
||||
* Returns 1 if PV has a dependency tree that uses anything in VG.
|
||||
*/
|
||||
int pv_uses_vg(struct cmd_context *cmd, struct physical_volume *pv,
|
||||
struct volume_group *vg);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,9 +17,11 @@
|
||||
#define _LVM_DEV_MANAGER_H
|
||||
|
||||
struct logical_volume;
|
||||
struct volume_group;
|
||||
struct cmd_context;
|
||||
struct dev_manager;
|
||||
struct dm_info;
|
||||
struct device;
|
||||
|
||||
/*
|
||||
* Constructor and destructor.
|
||||
@@ -35,7 +37,8 @@ void dev_manager_exit(void);
|
||||
* (eg, an origin is created before its snapshot, but is not
|
||||
* unsuspended until the snapshot is also created.)
|
||||
*/
|
||||
int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv,
|
||||
int dev_manager_info(struct dm_pool *mem, const char *name,
|
||||
const struct logical_volume *lv,
|
||||
int mknodes, int with_open_count, struct dm_info *info);
|
||||
int dev_manager_snapshot_percent(struct dev_manager *dm,
|
||||
struct logical_volume *lv, float *percent);
|
||||
@@ -44,15 +47,18 @@ int dev_manager_mirror_percent(struct dev_manager *dm,
|
||||
float *percent, uint32_t *event_nr);
|
||||
int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv);
|
||||
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv);
|
||||
int dev_manager_preload(struct dev_manager *dm, struct logical_volume *lv);
|
||||
int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv);
|
||||
|
||||
int dev_manager_lv_mknodes(const struct logical_volume *lv);
|
||||
int dev_manager_lv_rmnodes(const struct logical_volume *lv);
|
||||
int dev_manager_mknodes(void);
|
||||
|
||||
/*
|
||||
* Put the desired changes into effect.
|
||||
*/
|
||||
int dev_manager_execute(struct dev_manager *dm);
|
||||
|
||||
int dev_manager_device_uses_vg(struct dev_manager *dm, struct device *dev,
|
||||
struct volume_group *vg);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,16 +20,11 @@
|
||||
#include "lvm-file.h"
|
||||
#include "memlock.h"
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
# include "selinux.h"
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <dirent.h>
|
||||
#include <libdevmapper.h>
|
||||
|
||||
static int _mk_dir(const char *dev_dir, const char *vg_name)
|
||||
{
|
||||
@@ -180,7 +175,7 @@ static int _mk_link(const char *dev_dir, const char *vg_name,
|
||||
}
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
if (!set_selinux_context(lv_path, S_IFLNK)) {
|
||||
if (!dm_set_selinux_context(lv_path, S_IFLNK)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -283,7 +278,7 @@ static int _stack_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
|
||||
strlen(dev) + strlen(old_lv_name) + 5;
|
||||
char *pos;
|
||||
|
||||
if (!(fsp = dbg_malloc(sizeof(*fsp) + len))) {
|
||||
if (!(fsp = dm_malloc(sizeof(*fsp) + len))) {
|
||||
log_error("No space to stack fs operation");
|
||||
return 0;
|
||||
}
|
||||
@@ -312,7 +307,7 @@ static void _pop_fs_ops(void)
|
||||
_do_fs_op(fsp->type, fsp->dev_dir, fsp->vg_name, fsp->lv_name,
|
||||
fsp->dev, fsp->old_lv_name);
|
||||
list_del(&fsp->list);
|
||||
dbg_free(fsp);
|
||||
dm_free(fsp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,12 @@ 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);
|
||||
int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
struct dm_tree_node *node, int start_area, int areas);
|
||||
|
||||
int build_dev_string(struct dev_manager *dm, char *dlid, char *devbuf,
|
||||
size_t bufsize, const char *desc);
|
||||
|
||||
char *build_dlid(struct dev_manager *dm, const char *lvid, const char *layer);
|
||||
|
||||
#endif
|
||||
|
||||
121
lib/cache/lvmcache.c
vendored
121
lib/cache/lvmcache.c
vendored
@@ -16,7 +16,6 @@
|
||||
|
||||
#include "lib.h"
|
||||
#include "lvmcache.h"
|
||||
#include "hash.h"
|
||||
#include "toolcontext.h"
|
||||
#include "dev-cache.h"
|
||||
#include "metadata.h"
|
||||
@@ -24,10 +23,10 @@
|
||||
#include "memlock.h"
|
||||
#include "str_list.h"
|
||||
|
||||
static struct hash_table *_pvid_hash = NULL;
|
||||
static struct hash_table *_vgid_hash = NULL;
|
||||
static struct hash_table *_vgname_hash = NULL;
|
||||
static struct hash_table *_lock_hash = NULL;
|
||||
static struct dm_hash_table *_pvid_hash = NULL;
|
||||
static struct dm_hash_table *_vgid_hash = NULL;
|
||||
static struct dm_hash_table *_vgname_hash = NULL;
|
||||
static struct dm_hash_table *_lock_hash = NULL;
|
||||
static struct list _vginfos;
|
||||
static int _has_scanned = 0;
|
||||
static int _vgs_locked = 0;
|
||||
@@ -36,16 +35,16 @@ int lvmcache_init(void)
|
||||
{
|
||||
list_init(&_vginfos);
|
||||
|
||||
if (!(_vgname_hash = hash_create(128)))
|
||||
if (!(_vgname_hash = dm_hash_create(128)))
|
||||
return 0;
|
||||
|
||||
if (!(_vgid_hash = hash_create(128)))
|
||||
if (!(_vgid_hash = dm_hash_create(128)))
|
||||
return 0;
|
||||
|
||||
if (!(_pvid_hash = hash_create(128)))
|
||||
if (!(_pvid_hash = dm_hash_create(128)))
|
||||
return 0;
|
||||
|
||||
if (!(_lock_hash = hash_create(128)))
|
||||
if (!(_lock_hash = dm_hash_create(128)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
@@ -58,25 +57,24 @@ void lvmcache_lock_vgname(const char *vgname, int read_only)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hash_insert(_lock_hash, vgname, (void *) 1))
|
||||
if (!dm_hash_insert(_lock_hash, vgname, (void *) 1))
|
||||
log_error("Cache locking failure for %s", vgname);
|
||||
|
||||
_vgs_locked++;
|
||||
}
|
||||
|
||||
static int _vgname_is_locked(const char *vgname) __attribute__ ((unused));
|
||||
static int _vgname_is_locked(const char *vgname)
|
||||
int vgname_is_locked(const char *vgname)
|
||||
{
|
||||
if (!_lock_hash)
|
||||
return 0;
|
||||
|
||||
return hash_lookup(_lock_hash, vgname) ? 1 : 0;
|
||||
return dm_hash_lookup(_lock_hash, vgname) ? 1 : 0;
|
||||
}
|
||||
|
||||
void lvmcache_unlock_vgname(const char *vgname)
|
||||
{
|
||||
/* FIXME: Clear all CACHE_LOCKED flags in this vg */
|
||||
hash_remove(_lock_hash, vgname);
|
||||
dm_hash_remove(_lock_hash, vgname);
|
||||
|
||||
/* FIXME Do this per-VG */
|
||||
if (!--_vgs_locked)
|
||||
@@ -95,7 +93,7 @@ struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname)
|
||||
if (!_vgname_hash)
|
||||
return NULL;
|
||||
|
||||
if (!(vginfo = hash_lookup(_vgname_hash, vgname)))
|
||||
if (!(vginfo = dm_hash_lookup(_vgname_hash, vgname)))
|
||||
return NULL;
|
||||
|
||||
return vginfo;
|
||||
@@ -117,7 +115,7 @@ const struct format_type *fmt_from_vgname(const char *vgname)
|
||||
* we check cached labels here. Unfortunately vginfo is volatile. */
|
||||
list_init(&devs);
|
||||
list_iterate_items(info, &vginfo->infos) {
|
||||
devl = dbg_malloc(sizeof(*devl));
|
||||
devl = dm_malloc(sizeof(*devl));
|
||||
devl->dev = info->dev;
|
||||
list_add(&devs, &devl->list);
|
||||
}
|
||||
@@ -126,7 +124,7 @@ const struct format_type *fmt_from_vgname(const char *vgname)
|
||||
devl = list_item(devh, struct device_list);
|
||||
label_read(devl->dev, &label);
|
||||
list_del(&devl->list);
|
||||
dbg_free(devl);
|
||||
dm_free(devl);
|
||||
}
|
||||
|
||||
return vginfo->fmt;
|
||||
@@ -144,7 +142,7 @@ struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid)
|
||||
strncpy(&id[0], vgid, ID_LEN);
|
||||
id[ID_LEN] = '\0';
|
||||
|
||||
if (!(vginfo = hash_lookup(_vgid_hash, id)))
|
||||
if (!(vginfo = dm_hash_lookup(_vgid_hash, id)))
|
||||
return NULL;
|
||||
|
||||
return vginfo;
|
||||
@@ -161,7 +159,7 @@ struct lvmcache_info *info_from_pvid(const char *pvid)
|
||||
strncpy(&id[0], pvid, ID_LEN);
|
||||
id[ID_LEN] = '\0';
|
||||
|
||||
if (!(info = hash_lookup(_pvid_hash, id)))
|
||||
if (!(info = dm_hash_lookup(_pvid_hash, id)))
|
||||
return NULL;
|
||||
|
||||
return info;
|
||||
@@ -177,7 +175,7 @@ static void _rescan_entry(struct lvmcache_info *info)
|
||||
|
||||
static int _scan_invalid(void)
|
||||
{
|
||||
hash_iter(_pvid_hash, (iterate_fn) _rescan_entry);
|
||||
dm_hash_iter(_pvid_hash, (dm_hash_iterate_fn) _rescan_entry);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -248,7 +246,7 @@ struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan)
|
||||
|
||||
list_iterate_items(vgi, &_vginfos) {
|
||||
if (!str_list_add(cmd->mem, vgnames,
|
||||
pool_strdup(cmd->mem, vgi->vgname))) {
|
||||
dm_pool_strdup(cmd->mem, vgi->vgname))) {
|
||||
log_error("strlist allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -307,13 +305,13 @@ static void _drop_vginfo(struct lvmcache_info *info)
|
||||
}
|
||||
|
||||
if (info->vginfo && list_empty(&info->vginfo->infos)) {
|
||||
hash_remove(_vgname_hash, info->vginfo->vgname);
|
||||
dm_hash_remove(_vgname_hash, info->vginfo->vgname);
|
||||
if (info->vginfo->vgname)
|
||||
dbg_free(info->vginfo->vgname);
|
||||
dm_free(info->vginfo->vgname);
|
||||
if (*info->vginfo->vgid)
|
||||
hash_remove(_vgid_hash, info->vginfo->vgid);
|
||||
dm_hash_remove(_vgid_hash, info->vginfo->vgid);
|
||||
list_del(&info->vginfo->list);
|
||||
dbg_free(info->vginfo);
|
||||
dm_free(info->vginfo);
|
||||
}
|
||||
|
||||
info->vginfo = NULL;
|
||||
@@ -323,13 +321,13 @@ static void _drop_vginfo(struct lvmcache_info *info)
|
||||
void lvmcache_del(struct lvmcache_info *info)
|
||||
{
|
||||
if (info->dev->pvid[0] && _pvid_hash)
|
||||
hash_remove(_pvid_hash, info->dev->pvid);
|
||||
dm_hash_remove(_pvid_hash, info->dev->pvid);
|
||||
|
||||
_drop_vginfo(info);
|
||||
|
||||
info->label->labeller->ops->destroy_label(info->label->labeller,
|
||||
info->label);
|
||||
dbg_free(info);
|
||||
dm_free(info);
|
||||
|
||||
return;
|
||||
} */
|
||||
@@ -339,10 +337,10 @@ static int _lvmcache_update_pvid(struct lvmcache_info *info, const char *pvid)
|
||||
if (!strcmp(info->dev->pvid, pvid))
|
||||
return 1;
|
||||
if (*info->dev->pvid) {
|
||||
hash_remove(_pvid_hash, info->dev->pvid);
|
||||
dm_hash_remove(_pvid_hash, info->dev->pvid);
|
||||
}
|
||||
strncpy(info->dev->pvid, pvid, sizeof(info->dev->pvid));
|
||||
if (!hash_insert(_pvid_hash, pvid, info)) {
|
||||
if (!dm_hash_insert(_pvid_hash, pvid, info)) {
|
||||
log_error("_lvmcache_update: pvid insertion failed: %s", pvid);
|
||||
return 0;
|
||||
}
|
||||
@@ -357,13 +355,13 @@ static int _lvmcache_update_vgid(struct lvmcache_info *info, const char *vgid)
|
||||
return 1;
|
||||
|
||||
if (info->vginfo && *info->vginfo->vgid)
|
||||
hash_remove(_vgid_hash, info->vginfo->vgid);
|
||||
dm_hash_remove(_vgid_hash, info->vginfo->vgid);
|
||||
if (!vgid)
|
||||
return 1;
|
||||
|
||||
strncpy(info->vginfo->vgid, vgid, sizeof(info->vginfo->vgid));
|
||||
info->vginfo->vgid[sizeof(info->vginfo->vgid) - 1] = '\0';
|
||||
if (!hash_insert(_vgid_hash, info->vginfo->vgid, info->vginfo)) {
|
||||
if (!dm_hash_insert(_vgid_hash, info->vginfo->vgid, info->vginfo)) {
|
||||
log_error("_lvmcache_update: vgid hash insertion failed: %s",
|
||||
info->vginfo->vgid);
|
||||
return 0;
|
||||
@@ -391,22 +389,22 @@ int lvmcache_update_vgname(struct lvmcache_info *info, const char *vgname)
|
||||
|
||||
/* Get existing vginfo or create new one */
|
||||
if (!(vginfo = vginfo_from_vgname(vgname))) {
|
||||
if (!(vginfo = dbg_malloc(sizeof(*vginfo)))) {
|
||||
if (!(vginfo = dm_malloc(sizeof(*vginfo)))) {
|
||||
log_error("lvmcache_update_vgname: list alloc failed");
|
||||
return 0;
|
||||
}
|
||||
memset(vginfo, 0, sizeof(*vginfo));
|
||||
if (!(vginfo->vgname = dbg_strdup(vgname))) {
|
||||
dbg_free(vginfo);
|
||||
if (!(vginfo->vgname = dm_strdup(vgname))) {
|
||||
dm_free(vginfo);
|
||||
log_error("cache vgname alloc failed for %s", vgname);
|
||||
return 0;
|
||||
}
|
||||
list_init(&vginfo->infos);
|
||||
if (!hash_insert(_vgname_hash, vginfo->vgname, vginfo)) {
|
||||
if (!dm_hash_insert(_vgname_hash, vginfo->vgname, vginfo)) {
|
||||
log_error("cache_update: vg hash insertion failed: %s",
|
||||
vginfo->vgname);
|
||||
dbg_free(vginfo->vgname);
|
||||
dbg_free(vginfo);
|
||||
dm_free(vginfo->vgname);
|
||||
dm_free(vginfo);
|
||||
return 0;
|
||||
}
|
||||
/* Ensure orphans appear last on list_iterate */
|
||||
@@ -474,7 +472,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!(info = dbg_malloc(sizeof(*info)))) {
|
||||
if (!(info = dm_malloc(sizeof(*info)))) {
|
||||
log_error("lvmcache_info allocation failed");
|
||||
label_destroy(label);
|
||||
return NULL;
|
||||
@@ -495,17 +493,36 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
||||
pvid, dev_name(dev),
|
||||
dev_name(existing->dev));
|
||||
return NULL;
|
||||
} else if (dm_is_dm_major(MAJOR(existing->dev->dev)) &&
|
||||
!dm_is_dm_major(MAJOR(dev->dev))) {
|
||||
log_very_verbose("Ignoring duplicate PV %s on "
|
||||
"%s - using dm %s",
|
||||
pvid, dev_name(dev),
|
||||
dev_name(existing->dev));
|
||||
return NULL;
|
||||
} else if (MAJOR(existing->dev->dev) != md_major() &&
|
||||
MAJOR(dev->dev) == md_major())
|
||||
log_very_verbose("Duplicate PV %s on %s - "
|
||||
"using md %s", pvid,
|
||||
dev_name(existing->dev),
|
||||
dev_name(dev));
|
||||
else if (!dm_is_dm_major(MAJOR(existing->dev->dev)) &&
|
||||
dm_is_dm_major(MAJOR(dev->dev)))
|
||||
log_very_verbose("Duplicate PV %s on %s - "
|
||||
"using dm %s", pvid,
|
||||
dev_name(existing->dev),
|
||||
dev_name(dev));
|
||||
/* FIXME If both dm, check dependencies */
|
||||
//else if (dm_is_dm_major(MAJOR(existing->dev->dev)) &&
|
||||
//dm_is_dm_major(MAJOR(dev->dev)))
|
||||
//
|
||||
else
|
||||
log_error("Found duplicate PV %s: using %s not "
|
||||
"%s", pvid, dev_name(dev),
|
||||
dev_name(existing->dev));
|
||||
}
|
||||
/* Switch over to new preferred device */
|
||||
existing->dev = dev;
|
||||
info = existing;
|
||||
/* Has labeller changed? */
|
||||
if (info->label->labeller != labeller) {
|
||||
@@ -525,7 +542,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
||||
|
||||
if (!_lvmcache_update_pvid(info, pvid_s)) {
|
||||
if (!existing) {
|
||||
dbg_free(info);
|
||||
dm_free(info);
|
||||
label_destroy(label);
|
||||
}
|
||||
return NULL;
|
||||
@@ -533,9 +550,9 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
||||
|
||||
if (!lvmcache_update_vgname(info, vgname)) {
|
||||
if (!existing) {
|
||||
hash_remove(_pvid_hash, pvid_s);
|
||||
dm_hash_remove(_pvid_hash, pvid_s);
|
||||
strcpy(info->dev->pvid, "");
|
||||
dbg_free(info);
|
||||
dm_free(info);
|
||||
label_destroy(label);
|
||||
}
|
||||
return NULL;
|
||||
@@ -554,14 +571,14 @@ static void _lvmcache_destroy_entry(struct lvmcache_info *info)
|
||||
list_del(&info->list);
|
||||
strcpy(info->dev->pvid, "");
|
||||
label_destroy(info->label);
|
||||
dbg_free(info);
|
||||
dm_free(info);
|
||||
}
|
||||
|
||||
static void _lvmcache_destroy_vgnamelist(struct lvmcache_vginfo *vginfo)
|
||||
{
|
||||
if (vginfo->vgname)
|
||||
dbg_free(vginfo->vgname);
|
||||
dbg_free(vginfo);
|
||||
dm_free(vginfo->vgname);
|
||||
dm_free(vginfo);
|
||||
}
|
||||
|
||||
static void _lvmcache_destroy_lockname(int present)
|
||||
@@ -576,26 +593,26 @@ void lvmcache_destroy(void)
|
||||
_has_scanned = 0;
|
||||
|
||||
if (_vgid_hash) {
|
||||
hash_destroy(_vgid_hash);
|
||||
dm_hash_destroy(_vgid_hash);
|
||||
_vgid_hash = NULL;
|
||||
}
|
||||
|
||||
if (_pvid_hash) {
|
||||
hash_iter(_pvid_hash, (iterate_fn) _lvmcache_destroy_entry);
|
||||
hash_destroy(_pvid_hash);
|
||||
dm_hash_iter(_pvid_hash, (dm_hash_iterate_fn) _lvmcache_destroy_entry);
|
||||
dm_hash_destroy(_pvid_hash);
|
||||
_pvid_hash = NULL;
|
||||
}
|
||||
|
||||
if (_vgname_hash) {
|
||||
hash_iter(_vgname_hash,
|
||||
(iterate_fn) _lvmcache_destroy_vgnamelist);
|
||||
hash_destroy(_vgname_hash);
|
||||
dm_hash_iter(_vgname_hash,
|
||||
(dm_hash_iterate_fn) _lvmcache_destroy_vgnamelist);
|
||||
dm_hash_destroy(_vgname_hash);
|
||||
_vgname_hash = NULL;
|
||||
}
|
||||
|
||||
if (_lock_hash) {
|
||||
hash_iter(_lock_hash, (iterate_fn) _lvmcache_destroy_lockname);
|
||||
hash_destroy(_lock_hash);
|
||||
dm_hash_iter(_lock_hash, (dm_hash_iterate_fn) _lvmcache_destroy_lockname);
|
||||
dm_hash_destroy(_lock_hash);
|
||||
_lock_hash = NULL;
|
||||
}
|
||||
|
||||
|
||||
1
lib/cache/lvmcache.h
vendored
1
lib/cache/lvmcache.h
vendored
@@ -81,6 +81,7 @@ struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid);
|
||||
struct lvmcache_info *info_from_pvid(const char *pvid);
|
||||
struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid);
|
||||
int vgs_locked(void);
|
||||
int vgname_is_locked(const char *vgname);
|
||||
|
||||
/* Returns list of struct str_lists containing pool-allocated copy of vgnames */
|
||||
/* Set full_scan to 1 to reread every filtered device label */
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#include "lib.h"
|
||||
#include "toolcontext.h"
|
||||
#include "pool.h"
|
||||
#include "metadata.h"
|
||||
#include "defaults.h"
|
||||
#include "lvm-string.h"
|
||||
@@ -213,7 +212,7 @@ static int _process_config(struct cmd_context *cmd)
|
||||
|
||||
static int _set_tag(struct cmd_context *cmd, const char *tag)
|
||||
{
|
||||
log_very_verbose("Setting host tag: %s", pool_strdup(cmd->libmem, tag));
|
||||
log_very_verbose("Setting host tag: %s", dm_pool_strdup(cmd->libmem, tag));
|
||||
|
||||
if (!str_list_add(cmd->libmem, &cmd->tags, tag)) {
|
||||
log_error("_set_tag: str_list_add %s failed", tag);
|
||||
@@ -323,7 +322,7 @@ static int _load_config_file(struct cmd_context *cmd, const char *tag)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(cfl = pool_alloc(cmd->libmem, sizeof(*cfl)))) {
|
||||
if (!(cfl = dm_pool_alloc(cmd->libmem, sizeof(*cfl)))) {
|
||||
log_error("config_tree_list allocation failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -800,13 +799,13 @@ static int _init_hostname(struct cmd_context *cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(cmd->hostname = pool_strdup(cmd->libmem, uts.nodename))) {
|
||||
log_error("_init_hostname: pool_strdup failed");
|
||||
if (!(cmd->hostname = dm_pool_strdup(cmd->libmem, uts.nodename))) {
|
||||
log_error("_init_hostname: dm_pool_strdup failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(cmd->kernel_vsn = pool_strdup(cmd->libmem, uts.release))) {
|
||||
log_error("_init_hostname: pool_strdup kernel_vsn failed");
|
||||
if (!(cmd->kernel_vsn = dm_pool_strdup(cmd->libmem, uts.release))) {
|
||||
log_error("_init_hostname: dm_pool_strdup kernel_vsn failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -894,7 +893,7 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
|
||||
|
||||
init_syslog(DEFAULT_LOG_FACILITY);
|
||||
|
||||
if (!(cmd = dbg_malloc(sizeof(*cmd)))) {
|
||||
if (!(cmd = dm_malloc(sizeof(*cmd)))) {
|
||||
log_error("Failed to allocate command context");
|
||||
return NULL;
|
||||
}
|
||||
@@ -920,7 +919,7 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!(cmd->libmem = pool_create("library", 4 * 1024))) {
|
||||
if (!(cmd->libmem = dm_pool_create("library", 4 * 1024))) {
|
||||
log_error("Library memory pool creation failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -951,7 +950,7 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
|
||||
if (!_init_filters(cmd))
|
||||
goto error;
|
||||
|
||||
if (!(cmd->mem = pool_create("command", 4 * 1024))) {
|
||||
if (!(cmd->mem = dm_pool_create("command", 4 * 1024))) {
|
||||
log_error("Command memory pool creation failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -973,7 +972,7 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
|
||||
return cmd;
|
||||
|
||||
error:
|
||||
dbg_free(cmd);
|
||||
dm_free(cmd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1079,21 +1078,20 @@ void destroy_toolcontext(struct cmd_context *cmd)
|
||||
|
||||
archive_exit(cmd);
|
||||
backup_exit(cmd);
|
||||
activation_exit();
|
||||
lvmcache_destroy();
|
||||
label_exit();
|
||||
_destroy_segtypes(&cmd->segtypes);
|
||||
_destroy_formats(&cmd->formats);
|
||||
cmd->filter->destroy(cmd->filter);
|
||||
pool_destroy(cmd->mem);
|
||||
dm_pool_destroy(cmd->mem);
|
||||
dev_cache_exit();
|
||||
_destroy_tags(cmd);
|
||||
_destroy_tag_configs(cmd);
|
||||
pool_destroy(cmd->libmem);
|
||||
dbg_free(cmd);
|
||||
dm_pool_destroy(cmd->libmem);
|
||||
dm_free(cmd);
|
||||
|
||||
release_log_memory();
|
||||
dump_memory();
|
||||
activation_exit();
|
||||
fin_log();
|
||||
fin_syslog();
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#define _LVM_TOOLCONTEXT_H
|
||||
|
||||
#include "dev-cache.h"
|
||||
#include "pool.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
@@ -50,8 +49,8 @@ struct backup_params;
|
||||
/* FIXME Split into tool & library contexts */
|
||||
/* command-instance-related variables needed by library */
|
||||
struct cmd_context {
|
||||
struct pool *libmem; /* For permanent config data */
|
||||
struct pool *mem; /* Transient: Cleared between each command */
|
||||
struct dm_pool *libmem; /* For permanent config data */
|
||||
struct dm_pool *mem; /* Transient: Cleared between each command */
|
||||
|
||||
const struct format_type *fmt; /* Current format to use by default */
|
||||
struct format_type *fmt_backup; /* Format to use for backups */
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "lib.h"
|
||||
#include "config.h"
|
||||
#include "crc.h"
|
||||
#include "pool.h"
|
||||
#include "device.h"
|
||||
#include "str_list.h"
|
||||
#include "toolcontext.h"
|
||||
@@ -50,12 +49,12 @@ struct parser {
|
||||
int fd; /* descriptor for file being parsed */
|
||||
int line; /* line number we are on */
|
||||
|
||||
struct pool *mem;
|
||||
struct dm_pool *mem;
|
||||
};
|
||||
|
||||
struct cs {
|
||||
struct config_tree cft;
|
||||
struct pool *mem;
|
||||
struct dm_pool *mem;
|
||||
time_t timestamp;
|
||||
char *filename;
|
||||
int exists;
|
||||
@@ -99,16 +98,16 @@ static int _tok_match(const char *str, const char *b, const char *e)
|
||||
struct config_tree *create_config_tree(const char *filename)
|
||||
{
|
||||
struct cs *c;
|
||||
struct pool *mem = pool_create("config", 10 * 1024);
|
||||
struct dm_pool *mem = dm_pool_create("config", 10 * 1024);
|
||||
|
||||
if (!mem) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(c = pool_zalloc(mem, sizeof(*c)))) {
|
||||
if (!(c = dm_pool_zalloc(mem, sizeof(*c)))) {
|
||||
stack;
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -117,13 +116,13 @@ struct config_tree *create_config_tree(const char *filename)
|
||||
c->timestamp = 0;
|
||||
c->exists = 0;
|
||||
if (filename)
|
||||
c->filename = pool_strdup(c->mem, filename);
|
||||
c->filename = dm_pool_strdup(c->mem, filename);
|
||||
return &c->cft;
|
||||
}
|
||||
|
||||
void destroy_config_tree(struct config_tree *cft)
|
||||
{
|
||||
pool_destroy(((struct cs *) cft)->mem);
|
||||
dm_pool_destroy(((struct cs *) cft)->mem);
|
||||
}
|
||||
|
||||
int read_config_fd(struct config_tree *cft, struct device *dev,
|
||||
@@ -136,7 +135,7 @@ int read_config_fd(struct config_tree *cft, struct device *dev,
|
||||
int use_mmap = 1;
|
||||
off_t mmap_offset = 0;
|
||||
|
||||
if (!(p = pool_alloc(c->mem, sizeof(*p)))) {
|
||||
if (!(p = dm_pool_alloc(c->mem, sizeof(*p)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -157,7 +156,7 @@ int read_config_fd(struct config_tree *cft, struct device *dev,
|
||||
}
|
||||
p->fb = p->fb + mmap_offset;
|
||||
} else {
|
||||
if (!(p->fb = dbg_malloc(size + size2))) {
|
||||
if (!(p->fb = dm_malloc(size + size2))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -197,7 +196,7 @@ int read_config_fd(struct config_tree *cft, struct device *dev,
|
||||
|
||||
out:
|
||||
if (!use_mmap)
|
||||
dbg_free(p->fb);
|
||||
dm_free(p->fb);
|
||||
else {
|
||||
/* unmap the file */
|
||||
if (munmap((char *) (p->fb - mmap_offset), size + mmap_offset)) {
|
||||
@@ -688,14 +687,14 @@ static void _eat_space(struct parser *p)
|
||||
*/
|
||||
static struct config_value *_create_value(struct parser *p)
|
||||
{
|
||||
struct config_value *v = pool_alloc(p->mem, sizeof(*v));
|
||||
struct config_value *v = dm_pool_alloc(p->mem, sizeof(*v));
|
||||
memset(v, 0, sizeof(*v));
|
||||
return v;
|
||||
}
|
||||
|
||||
static struct config_node *_create_node(struct parser *p)
|
||||
{
|
||||
struct config_node *n = pool_alloc(p->mem, sizeof(*n));
|
||||
struct config_node *n = dm_pool_alloc(p->mem, sizeof(*n));
|
||||
memset(n, 0, sizeof(*n));
|
||||
return n;
|
||||
}
|
||||
@@ -703,7 +702,7 @@ static struct config_node *_create_node(struct parser *p)
|
||||
static char *_dup_tok(struct parser *p)
|
||||
{
|
||||
size_t len = p->te - p->tb;
|
||||
char *str = pool_alloc(p->mem, len + 1);
|
||||
char *str = dm_pool_alloc(p->mem, len + 1);
|
||||
if (!str) {
|
||||
stack;
|
||||
return 0;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#ifndef _LVM_CONFIG_H
|
||||
#define _LVM_CONFIG_H
|
||||
|
||||
#include "lvm-types.h"
|
||||
|
||||
struct device;
|
||||
struct cmd_context;
|
||||
|
||||
|
||||
@@ -24,13 +24,13 @@ struct node {
|
||||
};
|
||||
|
||||
struct btree {
|
||||
struct pool *mem;
|
||||
struct dm_pool *mem;
|
||||
struct node *root;
|
||||
};
|
||||
|
||||
struct btree *btree_create(struct pool *mem)
|
||||
struct btree *btree_create(struct dm_pool *mem)
|
||||
{
|
||||
struct btree *t = pool_alloc(mem, sizeof(*t));
|
||||
struct btree *t = dm_pool_alloc(mem, sizeof(*t));
|
||||
|
||||
if (t) {
|
||||
t->mem = mem;
|
||||
@@ -86,7 +86,7 @@ int btree_insert(struct btree *t, uint32_t k, void *data)
|
||||
struct node *p, **c = _lookup(&t->root, key, &p), *n;
|
||||
|
||||
if (!*c) {
|
||||
if (!(n = pool_alloc(t->mem, sizeof(*n)))) {
|
||||
if (!(n = dm_pool_alloc(t->mem, sizeof(*n)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -16,11 +16,9 @@
|
||||
#ifndef _LVM_BTREE_H
|
||||
#define _LVM_BTREE_H
|
||||
|
||||
#include "pool.h"
|
||||
|
||||
struct btree;
|
||||
|
||||
struct btree *btree_create(struct pool *mem);
|
||||
struct btree *btree_create(struct dm_pool *mem);
|
||||
|
||||
void *btree_lookup(struct btree *t, uint32_t k);
|
||||
int btree_insert(struct btree *t, uint32_t k, void *data);
|
||||
|
||||
@@ -202,6 +202,26 @@ static inline struct list *list_next(struct list *head, struct list *elem)
|
||||
*/
|
||||
#define list_iterate_items(v, head) list_iterate_items_gen(v, (head), list)
|
||||
|
||||
/*
|
||||
* 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'.
|
||||
* t must be defined as a temporary variable of the same type as v.
|
||||
*/
|
||||
#define list_iterate_items_gen_safe(v, t, head, field) \
|
||||
for (v = list_struct_base((head)->n, typeof(*v), field), \
|
||||
t = list_struct_base(v->field.n, typeof(*v), field); \
|
||||
&v->field != (head); \
|
||||
v = t, t = 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.
|
||||
* t must be defined as a temporary variable of the same type as v.
|
||||
*/
|
||||
#define list_iterate_items_safe(v, t, head) \
|
||||
list_iterate_items_gen_safe(v, t, (head), list)
|
||||
|
||||
/*
|
||||
* Walk a list backwards, setting 'v' in turn to the containing structure
|
||||
* of each item.
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
#include "lib.h"
|
||||
#include "str_list.h"
|
||||
|
||||
struct list *str_list_create(struct pool *mem)
|
||||
struct list *str_list_create(struct dm_pool *mem)
|
||||
{
|
||||
struct list *sl;
|
||||
|
||||
if (!(sl = pool_alloc(mem, sizeof(struct list)))) {
|
||||
if (!(sl = dm_pool_alloc(mem, sizeof(struct list)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -30,7 +30,7 @@ struct list *str_list_create(struct pool *mem)
|
||||
return sl;
|
||||
}
|
||||
|
||||
int str_list_add(struct pool *mem, struct list *sll, const char *str)
|
||||
int str_list_add(struct dm_pool *mem, struct list *sll, const char *str)
|
||||
{
|
||||
struct str_list *sln;
|
||||
|
||||
@@ -43,7 +43,7 @@ int str_list_add(struct pool *mem, struct list *sll, const char *str)
|
||||
if (str_list_match_item(sll, str))
|
||||
return 1;
|
||||
|
||||
if (!(sln = pool_alloc(mem, sizeof(*sln)))) {
|
||||
if (!(sln = dm_pool_alloc(mem, sizeof(*sln)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -66,7 +66,7 @@ int str_list_del(struct list *sll, const char *str)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int str_list_dup(struct pool *mem, struct list *sllnew, struct list *sllold)
|
||||
int str_list_dup(struct dm_pool *mem, struct list *sllnew, struct list *sllold)
|
||||
{
|
||||
struct str_list *sl;
|
||||
|
||||
|
||||
@@ -16,14 +16,12 @@
|
||||
#ifndef _LVM_STR_LIST_H
|
||||
#define _LVM_STR_LIST_H
|
||||
|
||||
#include "pool.h"
|
||||
|
||||
struct list *str_list_create(struct pool *mem);
|
||||
int str_list_add(struct pool *mem, struct list *sll, const char *str);
|
||||
struct list *str_list_create(struct dm_pool *mem);
|
||||
int str_list_add(struct dm_pool *mem, struct list *sll, const char *str);
|
||||
int str_list_del(struct list *sll, const char *str);
|
||||
int str_list_match_item(struct list *sll, const char *str);
|
||||
int str_list_match_list(struct list *sll, struct list *sll2);
|
||||
int str_list_lists_equal(struct list *sll, struct list *sll2);
|
||||
int str_list_dup(struct pool *mem, struct list *sllnew, struct list *sllold);
|
||||
int str_list_dup(struct dm_pool *mem, struct list *sllnew, struct list *sllold);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
|
||||
#include "lib.h"
|
||||
#include "dev-cache.h"
|
||||
#include "pool.h"
|
||||
#include "hash.h"
|
||||
#include "list.h"
|
||||
#include "lvm-types.h"
|
||||
#include "btree.h"
|
||||
#include "filter.h"
|
||||
@@ -38,8 +35,8 @@ struct dir_list {
|
||||
};
|
||||
|
||||
static struct {
|
||||
struct pool *mem;
|
||||
struct hash_table *names;
|
||||
struct dm_pool *mem;
|
||||
struct dm_hash_table *names;
|
||||
struct btree *devices;
|
||||
|
||||
int has_scanned;
|
||||
@@ -48,9 +45,9 @@ static struct {
|
||||
|
||||
} _cache;
|
||||
|
||||
#define _alloc(x) pool_zalloc(_cache.mem, (x))
|
||||
#define _free(x) pool_free(_cache.mem, (x))
|
||||
#define _strdup(x) pool_strdup(_cache.mem, (x))
|
||||
#define _alloc(x) dm_pool_zalloc(_cache.mem, (x))
|
||||
#define _free(x) dm_pool_free(_cache.mem, (x))
|
||||
#define _strdup(x) dm_pool_strdup(_cache.mem, (x))
|
||||
|
||||
static int _insert(const char *path, int rec);
|
||||
|
||||
@@ -61,19 +58,19 @@ struct device *dev_create_file(const char *filename, struct device *dev,
|
||||
|
||||
if (allocate) {
|
||||
if (use_malloc) {
|
||||
if (!(dev = dbg_malloc(sizeof(*dev)))) {
|
||||
if (!(dev = dm_malloc(sizeof(*dev)))) {
|
||||
log_error("struct device allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
if (!(alias = dbg_malloc(sizeof(*alias)))) {
|
||||
if (!(alias = dm_malloc(sizeof(*alias)))) {
|
||||
log_error("struct str_list allocation failed");
|
||||
dbg_free(dev);
|
||||
dm_free(dev);
|
||||
return NULL;
|
||||
}
|
||||
if (!(alias->str = dbg_strdup(filename))) {
|
||||
if (!(alias->str = dm_strdup(filename))) {
|
||||
log_error("filename strdup failed");
|
||||
dbg_free(dev);
|
||||
dbg_free(alias);
|
||||
dm_free(dev);
|
||||
dm_free(alias);
|
||||
return NULL;
|
||||
}
|
||||
dev->flags = DEV_ALLOCED;
|
||||
@@ -92,7 +89,7 @@ struct device *dev_create_file(const char *filename, struct device *dev,
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
} else if (!(alias->str = dbg_strdup(filename))) {
|
||||
} else if (!(alias->str = dm_strdup(filename))) {
|
||||
log_error("filename strdup failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -213,7 +210,7 @@ static int _add_alias(struct device *dev, const char *path)
|
||||
}
|
||||
}
|
||||
|
||||
if (!(sl->str = pool_strdup(_cache.mem, path))) {
|
||||
if (!(sl->str = dm_pool_strdup(_cache.mem, path))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -247,7 +244,7 @@ static int _insert_dev(const char *path, dev_t d)
|
||||
|
||||
/* Generate pretend device numbers for loopfiles */
|
||||
if (!d) {
|
||||
if (hash_lookup(_cache.names, path))
|
||||
if (dm_hash_lookup(_cache.names, path))
|
||||
return 1;
|
||||
d = ++loopfile_count;
|
||||
loopfile = 1;
|
||||
@@ -279,7 +276,7 @@ static int _insert_dev(const char *path, dev_t d)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!hash_insert(_cache.names, path, dev)) {
|
||||
if (!dm_hash_insert(_cache.names, path, dev)) {
|
||||
log_err("Couldn't add name to hash in dev cache.");
|
||||
return 0;
|
||||
}
|
||||
@@ -290,7 +287,7 @@ static int _insert_dev(const char *path, dev_t d)
|
||||
static char *_join(const char *dir, const char *name)
|
||||
{
|
||||
size_t len = strlen(dir) + strlen(name) + 2;
|
||||
char *r = dbg_malloc(len);
|
||||
char *r = dm_malloc(len);
|
||||
if (r)
|
||||
snprintf(r, len, "%s/%s", dir, name);
|
||||
|
||||
@@ -340,7 +337,7 @@ static int _insert_dir(const char *dir)
|
||||
|
||||
_collapse_slashes(path);
|
||||
r &= _insert(path, 1);
|
||||
dbg_free(path);
|
||||
dm_free(path);
|
||||
|
||||
free(dirent[n]);
|
||||
}
|
||||
@@ -449,14 +446,14 @@ int dev_cache_init(void)
|
||||
_cache.names = NULL;
|
||||
_cache.has_scanned = 0;
|
||||
|
||||
if (!(_cache.mem = pool_create("dev_cache", 10 * 1024))) {
|
||||
if (!(_cache.mem = dm_pool_create("dev_cache", 10 * 1024))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(_cache.names = hash_create(128))) {
|
||||
if (!(_cache.names = dm_hash_create(128))) {
|
||||
stack;
|
||||
pool_destroy(_cache.mem);
|
||||
dm_pool_destroy(_cache.mem);
|
||||
_cache.mem = 0;
|
||||
return 0;
|
||||
}
|
||||
@@ -484,7 +481,7 @@ static void _check_closed(struct device *dev)
|
||||
|
||||
static inline void _check_for_open_devices(void)
|
||||
{
|
||||
hash_iter(_cache.names, (iterate_fn) _check_closed);
|
||||
dm_hash_iter(_cache.names, (dm_hash_iterate_fn) _check_closed);
|
||||
}
|
||||
|
||||
void dev_cache_exit(void)
|
||||
@@ -493,12 +490,12 @@ void dev_cache_exit(void)
|
||||
_check_for_open_devices();
|
||||
|
||||
if (_cache.mem) {
|
||||
pool_destroy(_cache.mem);
|
||||
dm_pool_destroy(_cache.mem);
|
||||
_cache.mem = NULL;
|
||||
}
|
||||
|
||||
if (_cache.names) {
|
||||
hash_destroy(_cache.names);
|
||||
dm_hash_destroy(_cache.names);
|
||||
_cache.names = NULL;
|
||||
}
|
||||
|
||||
@@ -592,7 +589,7 @@ const char *dev_name_confirmed(struct device *dev, int quiet)
|
||||
(int) MINOR(dev->dev));
|
||||
|
||||
/* Remove the incorrect hash entry */
|
||||
hash_remove(_cache.names, name);
|
||||
dm_hash_remove(_cache.names, name);
|
||||
|
||||
/* Leave list alone if there isn't an alternative name */
|
||||
/* so dev_name will always find something to return. */
|
||||
@@ -615,23 +612,23 @@ const char *dev_name_confirmed(struct device *dev, int quiet)
|
||||
struct device *dev_cache_get(const char *name, struct dev_filter *f)
|
||||
{
|
||||
struct stat buf;
|
||||
struct device *d = (struct device *) hash_lookup(_cache.names, name);
|
||||
struct device *d = (struct device *) dm_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);
|
||||
dm_hash_remove(_cache.names, name);
|
||||
d = NULL;
|
||||
}
|
||||
|
||||
if (!d) {
|
||||
_insert(name, 0);
|
||||
d = (struct device *) hash_lookup(_cache.names, name);
|
||||
d = (struct device *) dm_hash_lookup(_cache.names, name);
|
||||
if (!d) {
|
||||
_full_scan(0);
|
||||
d = (struct device *) hash_lookup(_cache.names, name);
|
||||
d = (struct device *) dm_hash_lookup(_cache.names, name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -641,7 +638,7 @@ struct device *dev_cache_get(const char *name, 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));
|
||||
struct dev_iter *di = dm_malloc(sizeof(*di));
|
||||
|
||||
if (!di) {
|
||||
log_error("dev_iter allocation failed");
|
||||
@@ -664,7 +661,7 @@ struct dev_iter *dev_iter_create(struct dev_filter *f, int dev_scan)
|
||||
|
||||
void dev_iter_destroy(struct dev_iter *iter)
|
||||
{
|
||||
dbg_free(iter);
|
||||
dm_free(iter);
|
||||
}
|
||||
|
||||
static inline struct device *_iter_next(struct dev_iter *iter)
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#ifndef _LVM_DEV_CACHE_H
|
||||
#define _LVM_DEV_CACHE_H
|
||||
|
||||
#include "lvm-types.h"
|
||||
#include "device.h"
|
||||
|
||||
/*
|
||||
|
||||
@@ -320,15 +320,22 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||
{
|
||||
struct stat buf;
|
||||
const char *name;
|
||||
int need_excl = 0, need_rw = 0;
|
||||
|
||||
if ((flags & O_ACCMODE) == O_RDWR)
|
||||
need_rw = 1;
|
||||
|
||||
if ((flags & O_EXCL))
|
||||
need_excl = 1;
|
||||
|
||||
if (dev->fd >= 0) {
|
||||
if ((dev->flags & DEV_OPENED_RW) ||
|
||||
((flags & O_ACCMODE) != O_RDWR)) {
|
||||
if (((dev->flags & DEV_OPENED_RW) || !need_rw) &&
|
||||
((dev->flags & DEV_OPENED_EXCL) || !need_excl)) {
|
||||
dev->open_count++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (dev->open_count) {
|
||||
if (dev->open_count && !need_excl) {
|
||||
/* FIXME Ensure we never get here */
|
||||
log_debug("WARNING: %s already opened read-only",
|
||||
dev_name(dev));
|
||||
@@ -397,16 +404,20 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||
dev->open_count++;
|
||||
dev->flags &= ~DEV_ACCESSED_W;
|
||||
|
||||
if ((flags & O_ACCMODE) == O_RDWR)
|
||||
if (need_rw)
|
||||
dev->flags |= DEV_OPENED_RW;
|
||||
else
|
||||
dev->flags &= ~DEV_OPENED_RW;
|
||||
|
||||
if (need_excl)
|
||||
dev->flags |= DEV_OPENED_EXCL;
|
||||
else
|
||||
dev->flags &= ~DEV_OPENED_EXCL;
|
||||
|
||||
if (!(dev->flags & DEV_REGULAR) &&
|
||||
((fstat(dev->fd, &buf) < 0) || (buf.st_rdev != dev->dev))) {
|
||||
log_error("%s: fstat failed: Has device name changed?", name);
|
||||
dev_close_immediate(dev);
|
||||
dev->open_count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -420,8 +431,9 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
|
||||
|
||||
list_add(&_open_devices, &dev->open_list);
|
||||
|
||||
log_debug("Opened %s %s%s", dev_name(dev),
|
||||
log_debug("Opened %s %s%s%s", dev_name(dev),
|
||||
dev->flags & DEV_OPENED_RW ? "RW" : "RO",
|
||||
dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "",
|
||||
dev->flags & DEV_O_DIRECT ? " O_DIRECT" : "");
|
||||
|
||||
return 1;
|
||||
@@ -445,6 +457,21 @@ int dev_open(struct device *dev)
|
||||
return dev_open_flags(dev, flags, 1, 0);
|
||||
}
|
||||
|
||||
int dev_test_excl(struct device *dev)
|
||||
{
|
||||
int flags;
|
||||
int r;
|
||||
|
||||
flags = vg_write_lock_held() ? O_RDWR : O_RDONLY;
|
||||
flags |= O_EXCL;
|
||||
|
||||
r = dev_open_flags(dev, flags, 1, 1);
|
||||
if (r)
|
||||
dev_close_immediate(dev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void _close(struct device *dev)
|
||||
{
|
||||
if (close(dev->fd))
|
||||
@@ -456,15 +483,17 @@ static void _close(struct device *dev)
|
||||
log_debug("Closed %s", dev_name(dev));
|
||||
|
||||
if (dev->flags & DEV_ALLOCED) {
|
||||
dbg_free((void *) list_item(dev->aliases.n, struct str_list)->
|
||||
dm_free((void *) list_item(dev->aliases.n, struct str_list)->
|
||||
str);
|
||||
dbg_free(dev->aliases.n);
|
||||
dbg_free(dev);
|
||||
dm_free(dev->aliases.n);
|
||||
dm_free(dev);
|
||||
}
|
||||
}
|
||||
|
||||
static int _dev_close(struct device *dev, int immediate)
|
||||
{
|
||||
struct lvmcache_info *info;
|
||||
|
||||
if (dev->fd < 0) {
|
||||
log_error("Attempt to close device '%s' "
|
||||
"which is not open.", dev_name(dev));
|
||||
@@ -479,8 +508,16 @@ static int _dev_close(struct device *dev, int immediate)
|
||||
if (dev->open_count > 0)
|
||||
dev->open_count--;
|
||||
|
||||
/* FIXME lookup device in cache to get vgname and see if it's locked? */
|
||||
if (immediate || (dev->open_count < 1 && !vgs_locked()))
|
||||
if (immediate && dev->open_count)
|
||||
log_debug("%s: Immediate close attempt while still referenced",
|
||||
dev_name(dev));
|
||||
|
||||
/* Close unless device is known to belong to a locked VG */
|
||||
if (immediate ||
|
||||
(dev->open_count < 1 &&
|
||||
(!(info = info_from_pvid(dev->pvid)) ||
|
||||
!info->vginfo ||
|
||||
!vgname_is_locked(info->vginfo->vgname))))
|
||||
_close(dev);
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -202,7 +202,7 @@ int _get_partition_type(struct dev_mgr *dm, struct device *d)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(buffer = dbg_malloc(SECTOR_SIZE))) {
|
||||
if (!(buffer = dm_malloc(SECTOR_SIZE))) {
|
||||
log_error("Failed to allocate partition table buffer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -17,14 +17,16 @@
|
||||
#define _LVM_DEVICE_H
|
||||
|
||||
#include "uuid.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#define DEV_ACCESSED_W 0x00000001 /* Device written to? */
|
||||
#define DEV_REGULAR 0x00000002 /* Regular file? */
|
||||
#define DEV_ALLOCED 0x00000004 /* dbg_malloc used */
|
||||
#define DEV_ALLOCED 0x00000004 /* dm_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 */
|
||||
#define DEV_OPENED_EXCL 0x00000010 /* Opened EXCL */
|
||||
#define DEV_O_DIRECT 0x00000020 /* Use O_DIRECT */
|
||||
#define DEV_O_DIRECT_TESTED 0x00000040 /* DEV_O_DIRECT is reliable */
|
||||
|
||||
/*
|
||||
* All devices in LVM will be represented by one of these.
|
||||
@@ -70,6 +72,7 @@ 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);
|
||||
int dev_test_excl(struct device *dev);
|
||||
|
||||
static inline int dev_fd(struct device *dev)
|
||||
{
|
||||
|
||||
@@ -151,7 +151,7 @@ const char *display_size(struct cmd_context *cmd, uint64_t size, size_len_t sl)
|
||||
{" ", " ", " "},
|
||||
};
|
||||
|
||||
if (!(size_buf = pool_alloc(cmd->mem, SIZE_BUF))) {
|
||||
if (!(size_buf = dm_pool_alloc(cmd->mem, SIZE_BUF))) {
|
||||
log_error("no memory for size display buffer");
|
||||
return "";
|
||||
}
|
||||
@@ -317,7 +317,7 @@ void lvdisplay_colons(struct logical_volume *lv)
|
||||
{
|
||||
int inkernel;
|
||||
struct lvinfo info;
|
||||
inkernel = lv_info(lv, &info, 1) && info.exists;
|
||||
inkernel = lv_info(lv->vg->cmd, lv, &info, 1) && info.exists;
|
||||
|
||||
log_print("%s%s/%s:%s:%d:%d:-1:%d:%" PRIu64 ":%d:-1:%d:%d:%d:%d",
|
||||
lv->vg->cmd->dev_dir,
|
||||
@@ -347,7 +347,7 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
inkernel = lv_info(lv, &info, 1) && info.exists;
|
||||
inkernel = lv_info(cmd, lv, &info, 1) && info.exists;
|
||||
|
||||
log_print("--- Logical volume ---");
|
||||
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "pool.h"
|
||||
#include "list.h"
|
||||
#include "toolcontext.h"
|
||||
#include "segtype.h"
|
||||
#include "display.h"
|
||||
@@ -40,18 +38,13 @@ static int _merge_segments(struct lv_segment *seg1, struct lv_segment *seg2)
|
||||
}
|
||||
|
||||
#ifdef DEVMAPPER_SUPPORT
|
||||
static int _compose_target_line(struct dev_manager *dm, struct pool *mem,
|
||||
static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
|
||||
struct config_tree *cft, void **target_state,
|
||||
struct lv_segment *seg, char *params,
|
||||
size_t paramsize, const char **target, int *pos,
|
||||
struct lv_segment *seg,
|
||||
struct dm_tree_node *node, uint64_t len,
|
||||
uint32_t *pvmove_mirror_count)
|
||||
{
|
||||
/* error */
|
||||
|
||||
*target = "error";
|
||||
*params = '\0';
|
||||
|
||||
return 1;
|
||||
return dm_tree_node_add_error_target(node, len);
|
||||
}
|
||||
|
||||
static int _target_present(void)
|
||||
@@ -59,8 +52,10 @@ static int _target_present(void)
|
||||
static int checked = 0;
|
||||
static int present = 0;
|
||||
|
||||
if (!checked)
|
||||
present = target_present("error");
|
||||
/* Reported truncated in older kernels */
|
||||
if (!checked &&
|
||||
(target_present("error", 0) || target_present("erro", 0)))
|
||||
present = 1;
|
||||
|
||||
checked = 1;
|
||||
return present;
|
||||
@@ -69,14 +64,14 @@ static int _target_present(void)
|
||||
|
||||
static void _destroy(const struct segment_type *segtype)
|
||||
{
|
||||
dbg_free((void *) segtype);
|
||||
dm_free((void *) segtype);
|
||||
}
|
||||
|
||||
static struct segtype_handler _error_ops = {
|
||||
name:_name,
|
||||
merge_segments:_merge_segments,
|
||||
#ifdef DEVMAPPER_SUPPORT
|
||||
compose_target_line:_compose_target_line,
|
||||
add_target_line:_add_target_line,
|
||||
target_present:_target_present,
|
||||
#endif
|
||||
destroy:_destroy,
|
||||
@@ -84,18 +79,16 @@ static struct segtype_handler _error_ops = {
|
||||
|
||||
struct segment_type *init_error_segtype(struct cmd_context *cmd)
|
||||
{
|
||||
struct segment_type *segtype = dbg_malloc(sizeof(*segtype));
|
||||
struct segment_type *segtype = dm_malloc(sizeof(*segtype));
|
||||
|
||||
if (!segtype) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
if (!segtype)
|
||||
return_NULL;
|
||||
|
||||
segtype->cmd = cmd;
|
||||
segtype->ops = &_error_ops;
|
||||
segtype->name = "error";
|
||||
segtype->private = NULL;
|
||||
segtype->flags = SEG_CAN_SPLIT | SEG_VIRTUAL;
|
||||
segtype->flags = SEG_CAN_SPLIT | SEG_VIRTUAL | SEG_CANNOT_BE_ZEROED;
|
||||
|
||||
log_very_verbose("Initialised segtype: %s", segtype->name);
|
||||
|
||||
|
||||
@@ -42,8 +42,8 @@ static void _destroy(struct dev_filter *f)
|
||||
filters++;
|
||||
}
|
||||
|
||||
dbg_free(f->private);
|
||||
dbg_free(f);
|
||||
dm_free(f->private);
|
||||
dm_free(f);
|
||||
}
|
||||
|
||||
struct dev_filter *composite_filter_create(int n, struct dev_filter **filters)
|
||||
@@ -55,7 +55,7 @@ struct dev_filter *composite_filter_create(int n, struct dev_filter **filters)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(filters_copy = dbg_malloc(sizeof(*filters) * (n + 1)))) {
|
||||
if (!(filters_copy = dm_malloc(sizeof(*filters) * (n + 1)))) {
|
||||
log_error("composite filters allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -63,9 +63,9 @@ struct dev_filter *composite_filter_create(int n, struct dev_filter **filters)
|
||||
memcpy(filters_copy, filters, sizeof(*filters) * n);
|
||||
filters_copy[n] = NULL;
|
||||
|
||||
if (!(cft = dbg_malloc(sizeof(*cft)))) {
|
||||
if (!(cft = dm_malloc(sizeof(*cft)))) {
|
||||
log_error("compsoite filters allocation failed");
|
||||
dbg_free(filters_copy);
|
||||
dm_free(filters_copy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,14 +51,14 @@ static int _ignore_md(struct dev_filter *f, struct device *dev)
|
||||
|
||||
static void _destroy(struct dev_filter *f)
|
||||
{
|
||||
dbg_free(f);
|
||||
dm_free(f);
|
||||
}
|
||||
|
||||
struct dev_filter *md_filter_create(void)
|
||||
{
|
||||
struct dev_filter *f;
|
||||
|
||||
if (!(f = dbg_malloc(sizeof(*f)))) {
|
||||
if (!(f = dm_malloc(sizeof(*f)))) {
|
||||
log_error("md filter allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "lib.h"
|
||||
#include "config.h"
|
||||
#include "dev-cache.h"
|
||||
#include "hash.h"
|
||||
#include "filter-persistent.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
@@ -25,7 +24,7 @@
|
||||
|
||||
struct pfilter {
|
||||
char *file;
|
||||
struct hash_table *devices;
|
||||
struct dm_hash_table *devices;
|
||||
struct dev_filter *real;
|
||||
};
|
||||
|
||||
@@ -39,9 +38,9 @@ struct pfilter {
|
||||
static int _init_hash(struct pfilter *pf)
|
||||
{
|
||||
if (pf->devices)
|
||||
hash_destroy(pf->devices);
|
||||
dm_hash_destroy(pf->devices);
|
||||
|
||||
if (!(pf->devices = hash_create(128))) {
|
||||
if (!(pf->devices = dm_hash_create(128))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -54,7 +53,7 @@ int persistent_filter_wipe(struct dev_filter *f)
|
||||
struct pfilter *pf = (struct pfilter *) f->private;
|
||||
|
||||
log_verbose("Wiping cache of LVM-capable devices");
|
||||
hash_wipe(pf->devices);
|
||||
dm_hash_wipe(pf->devices);
|
||||
|
||||
/* Trigger complete device scan */
|
||||
dev_cache_scan(1);
|
||||
@@ -85,7 +84,7 @@ static int _read_array(struct pfilter *pf, struct config_tree *cft,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!hash_insert(pf->devices, cv->v.str, data))
|
||||
if (!dm_hash_insert(pf->devices, cv->v.str, data))
|
||||
log_verbose("Couldn't add '%s' to filter ... ignoring",
|
||||
cv->v.str);
|
||||
/* Populate dev_cache ourselves */
|
||||
@@ -118,7 +117,7 @@ int persistent_filter_load(struct dev_filter *f)
|
||||
PF_BAD_DEVICE); */
|
||||
|
||||
/* Did we find anything? */
|
||||
if (hash_get_num_entries(pf->devices)) {
|
||||
if (dm_hash_get_num_entries(pf->devices)) {
|
||||
/* We populated dev_cache ourselves */
|
||||
dev_cache_scan(0);
|
||||
r = 1;
|
||||
@@ -136,11 +135,11 @@ static void _write_array(struct pfilter *pf, FILE *fp, const char *path,
|
||||
{
|
||||
void *d;
|
||||
int first = 1;
|
||||
struct hash_node *n;
|
||||
struct dm_hash_node *n;
|
||||
|
||||
for (n = hash_get_first(pf->devices); n;
|
||||
n = hash_get_next(pf->devices, n)) {
|
||||
d = hash_get_data(pf->devices, n);
|
||||
for (n = dm_hash_get_first(pf->devices); n;
|
||||
n = dm_hash_get_next(pf->devices, n)) {
|
||||
d = dm_hash_get_data(pf->devices, n);
|
||||
|
||||
if (d != data)
|
||||
continue;
|
||||
@@ -152,7 +151,7 @@ static void _write_array(struct pfilter *pf, FILE *fp, const char *path,
|
||||
first = 0;
|
||||
}
|
||||
|
||||
fprintf(fp, "\t\t\"%s\"", hash_get_key(pf->devices, n));
|
||||
fprintf(fp, "\t\t\"%s\"", dm_hash_get_key(pf->devices, n));
|
||||
}
|
||||
|
||||
if (!first)
|
||||
@@ -167,7 +166,7 @@ int persistent_filter_dump(struct dev_filter *f)
|
||||
|
||||
FILE *fp;
|
||||
|
||||
if (!hash_get_num_entries(pf->devices)) {
|
||||
if (!dm_hash_get_num_entries(pf->devices)) {
|
||||
log_very_verbose("Internal persistent device cache empty "
|
||||
"- not writing to %s", pf->file);
|
||||
return 0;
|
||||
@@ -202,7 +201,7 @@ int persistent_filter_dump(struct dev_filter *f)
|
||||
static int _lookup_p(struct dev_filter *f, struct device *dev)
|
||||
{
|
||||
struct pfilter *pf = (struct pfilter *) f->private;
|
||||
void *l = hash_lookup(pf->devices, dev_name(dev));
|
||||
void *l = dm_hash_lookup(pf->devices, dev_name(dev));
|
||||
struct str_list *sl;
|
||||
|
||||
if (!l) {
|
||||
@@ -210,7 +209,7 @@ static int _lookup_p(struct dev_filter *f, struct device *dev)
|
||||
PF_GOOD_DEVICE : PF_BAD_DEVICE;
|
||||
|
||||
list_iterate_items(sl, &dev->aliases)
|
||||
hash_insert(pf->devices, sl->str, l);
|
||||
dm_hash_insert(pf->devices, sl->str, l);
|
||||
|
||||
} else if (l == PF_BAD_DEVICE)
|
||||
log_debug("%s: Skipping (cached)", dev_name(dev));
|
||||
@@ -222,11 +221,11 @@ static void _destroy(struct dev_filter *f)
|
||||
{
|
||||
struct pfilter *pf = (struct pfilter *) f->private;
|
||||
|
||||
hash_destroy(pf->devices);
|
||||
dbg_free(pf->file);
|
||||
dm_hash_destroy(pf->devices);
|
||||
dm_free(pf->file);
|
||||
pf->real->destroy(pf->real);
|
||||
dbg_free(pf);
|
||||
dbg_free(f);
|
||||
dm_free(pf);
|
||||
dm_free(f);
|
||||
}
|
||||
|
||||
struct dev_filter *persistent_filter_create(struct dev_filter *real,
|
||||
@@ -235,13 +234,13 @@ struct dev_filter *persistent_filter_create(struct dev_filter *real,
|
||||
struct pfilter *pf;
|
||||
struct dev_filter *f = NULL;
|
||||
|
||||
if (!(pf = dbg_malloc(sizeof(*pf)))) {
|
||||
if (!(pf = dm_malloc(sizeof(*pf)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
memset(pf, 0, sizeof(*pf));
|
||||
|
||||
if (!(pf->file = dbg_malloc(strlen(file) + 1))) {
|
||||
if (!(pf->file = dm_malloc(strlen(file) + 1))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -253,7 +252,7 @@ struct dev_filter *persistent_filter_create(struct dev_filter *real,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(f = dbg_malloc(sizeof(*f)))) {
|
||||
if (!(f = dm_malloc(sizeof(*f)))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -265,10 +264,10 @@ struct dev_filter *persistent_filter_create(struct dev_filter *real,
|
||||
return f;
|
||||
|
||||
bad:
|
||||
dbg_free(pf->file);
|
||||
dm_free(pf->file);
|
||||
if (pf->devices)
|
||||
hash_destroy(pf->devices);
|
||||
dbg_free(pf);
|
||||
dbg_free(f);
|
||||
dm_hash_destroy(pf->devices);
|
||||
dm_free(pf);
|
||||
dm_free(f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -14,21 +14,18 @@
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "pool.h"
|
||||
#include "filter-regex.h"
|
||||
#include "matcher.h"
|
||||
#include "device.h"
|
||||
#include "bitset.h"
|
||||
#include "list.h"
|
||||
|
||||
struct rfilter {
|
||||
struct pool *mem;
|
||||
bitset_t accept;
|
||||
struct dm_pool *mem;
|
||||
dm_bitset_t accept;
|
||||
struct matcher *engine;
|
||||
};
|
||||
|
||||
static int _extract_pattern(struct pool *mem, const char *pat,
|
||||
char **regex, bitset_t accept, int ix)
|
||||
static int _extract_pattern(struct dm_pool *mem, const char *pat,
|
||||
char **regex, dm_bitset_t accept, int ix)
|
||||
{
|
||||
char sep, *r, *ptr;
|
||||
|
||||
@@ -37,11 +34,11 @@ static int _extract_pattern(struct pool *mem, const char *pat,
|
||||
*/
|
||||
switch (*pat) {
|
||||
case 'a':
|
||||
bit_set(accept, ix);
|
||||
dm_bit_set(accept, ix);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
bit_clear(accept, ix);
|
||||
dm_bit_clear(accept, ix);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -74,7 +71,7 @@ static int _extract_pattern(struct pool *mem, const char *pat,
|
||||
/*
|
||||
* copy the regex
|
||||
*/
|
||||
if (!(r = pool_strdup(mem, pat))) {
|
||||
if (!(r = dm_pool_strdup(mem, pat))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -95,13 +92,13 @@ static int _extract_pattern(struct pool *mem, const char *pat,
|
||||
|
||||
static int _build_matcher(struct rfilter *rf, struct config_value *val)
|
||||
{
|
||||
struct pool *scratch;
|
||||
struct dm_pool *scratch;
|
||||
struct config_value *v;
|
||||
char **regex;
|
||||
unsigned count = 0;
|
||||
int i, r = 0;
|
||||
|
||||
if (!(scratch = pool_create("filter matcher", 1024))) {
|
||||
if (!(scratch = dm_pool_create("filter matcher", 1024))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -122,7 +119,7 @@ static int _build_matcher(struct rfilter *rf, struct config_value *val)
|
||||
/*
|
||||
* allocate space for them
|
||||
*/
|
||||
if (!(regex = pool_alloc(scratch, sizeof(*regex) * count))) {
|
||||
if (!(regex = dm_pool_alloc(scratch, sizeof(*regex) * count))) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
@@ -130,7 +127,7 @@ static int _build_matcher(struct rfilter *rf, struct config_value *val)
|
||||
/*
|
||||
* create the accept/reject bitset
|
||||
*/
|
||||
rf->accept = bitset_create(rf->mem, count);
|
||||
rf->accept = dm_bitset_create(rf->mem, count);
|
||||
|
||||
/*
|
||||
* fill the array back to front because we
|
||||
@@ -152,7 +149,7 @@ static int _build_matcher(struct rfilter *rf, struct config_value *val)
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
pool_destroy(scratch);
|
||||
dm_pool_destroy(scratch);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -166,7 +163,7 @@ static int _accept_p(struct dev_filter *f, struct device *dev)
|
||||
m = matcher_run(rf->engine, sl->str);
|
||||
|
||||
if (m >= 0) {
|
||||
if (bit(rf->accept, m)) {
|
||||
if (dm_bit(rf->accept, m)) {
|
||||
|
||||
if (!first) {
|
||||
log_debug("%s: New preferred name",
|
||||
@@ -197,12 +194,12 @@ static int _accept_p(struct dev_filter *f, struct device *dev)
|
||||
static void _destroy(struct dev_filter *f)
|
||||
{
|
||||
struct rfilter *rf = (struct rfilter *) f->private;
|
||||
pool_destroy(rf->mem);
|
||||
dm_pool_destroy(rf->mem);
|
||||
}
|
||||
|
||||
struct dev_filter *regex_filter_create(struct config_value *patterns)
|
||||
{
|
||||
struct pool *mem = pool_create("filter regex", 10 * 1024);
|
||||
struct dm_pool *mem = dm_pool_create("filter regex", 10 * 1024);
|
||||
struct rfilter *rf;
|
||||
struct dev_filter *f;
|
||||
|
||||
@@ -211,7 +208,7 @@ struct dev_filter *regex_filter_create(struct config_value *patterns)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(rf = pool_alloc(mem, sizeof(*rf)))) {
|
||||
if (!(rf = dm_pool_alloc(mem, sizeof(*rf)))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -223,7 +220,7 @@ struct dev_filter *regex_filter_create(struct config_value *patterns)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(f = pool_zalloc(mem, sizeof(*f)))) {
|
||||
if (!(f = dm_pool_zalloc(mem, sizeof(*f)))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -234,6 +231,6 @@ struct dev_filter *regex_filter_create(struct config_value *patterns)
|
||||
return f;
|
||||
|
||||
bad:
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include "lib.h"
|
||||
#include "filter-sysfs.h"
|
||||
#include "lvm-string.h"
|
||||
#include "pool.h"
|
||||
|
||||
#ifdef linux
|
||||
|
||||
@@ -69,21 +68,21 @@ struct entry {
|
||||
|
||||
#define SET_BUCKETS 64
|
||||
struct dev_set {
|
||||
struct pool *mem;
|
||||
struct dm_pool *mem;
|
||||
const char *sys_block;
|
||||
int initialised;
|
||||
struct entry *slots[SET_BUCKETS];
|
||||
};
|
||||
|
||||
static struct dev_set *_dev_set_create(struct pool *mem, const char *sys_block)
|
||||
static struct dev_set *_dev_set_create(struct dm_pool *mem, const char *sys_block)
|
||||
{
|
||||
struct dev_set *ds;
|
||||
|
||||
if (!(ds = pool_zalloc(mem, sizeof(*ds))))
|
||||
if (!(ds = dm_pool_zalloc(mem, sizeof(*ds))))
|
||||
return NULL;
|
||||
|
||||
ds->mem = mem;
|
||||
ds->sys_block = pool_strdup(mem, sys_block);
|
||||
ds->sys_block = dm_pool_strdup(mem, sys_block);
|
||||
ds->initialised = 0;
|
||||
|
||||
return ds;
|
||||
@@ -102,7 +101,7 @@ static int _set_insert(struct dev_set *ds, dev_t dev)
|
||||
struct entry *e;
|
||||
unsigned h = _hash_dev(dev);
|
||||
|
||||
if (!(e = pool_alloc(ds->mem, sizeof(*e))))
|
||||
if (!(e = dm_pool_alloc(ds->mem, sizeof(*e))))
|
||||
return 0;
|
||||
|
||||
e->next = ds->slots[h];
|
||||
@@ -258,20 +257,20 @@ static int _accept_p(struct dev_filter *f, struct device *dev)
|
||||
static void _destroy(struct dev_filter *f)
|
||||
{
|
||||
struct dev_set *ds = (struct dev_set *) f->private;
|
||||
pool_destroy(ds->mem);
|
||||
dm_pool_destroy(ds->mem);
|
||||
}
|
||||
|
||||
struct dev_filter *sysfs_filter_create(const char *proc)
|
||||
{
|
||||
char sys_block[PATH_MAX];
|
||||
struct pool *mem;
|
||||
struct dm_pool *mem;
|
||||
struct dev_set *ds;
|
||||
struct dev_filter *f;
|
||||
|
||||
if (!_locate_sysfs_blocks(proc, sys_block, sizeof(sys_block)))
|
||||
return NULL;
|
||||
|
||||
if (!(mem = pool_create("sysfs", 256))) {
|
||||
if (!(mem = dm_pool_create("sysfs", 256))) {
|
||||
log_error("sysfs pool creation failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -281,7 +280,7 @@ struct dev_filter *sysfs_filter_create(const char *proc)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(f = pool_zalloc(mem, sizeof(*f)))) {
|
||||
if (!(f = dm_pool_zalloc(mem, sizeof(*f)))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -292,7 +291,7 @@ struct dev_filter *sysfs_filter_create(const char *proc)
|
||||
return f;
|
||||
|
||||
bad:
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
#define NUMBER_OF_MAJORS 4096
|
||||
|
||||
/* FIXME Make this sparse */
|
||||
/* 0 means LVM won't use this major number. */
|
||||
static int _max_partitions_by_major[NUMBER_OF_MAJORS];
|
||||
|
||||
@@ -71,6 +70,9 @@ static const device_info_t device_info[] = {
|
||||
{"iseries/vd", 8}, /* iSeries disks */
|
||||
{"gnbd", 1}, /* Network block device */
|
||||
{"ramdisk", 1}, /* RAM disk */
|
||||
{"aoe", 16}, /* ATA over Ethernet */
|
||||
{"device-mapper", 1}, /* Other mapped devices */
|
||||
{"xvd", 16}, /* Xen virtual block device */
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
@@ -241,7 +243,7 @@ struct dev_filter *lvm_type_filter_create(const char *proc,
|
||||
{
|
||||
struct dev_filter *f;
|
||||
|
||||
if (!(f = dbg_malloc(sizeof(struct dev_filter)))) {
|
||||
if (!(f = dm_malloc(sizeof(struct dev_filter)))) {
|
||||
log_error("LVM type filter allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -260,6 +262,6 @@ struct dev_filter *lvm_type_filter_create(const char *proc,
|
||||
|
||||
void lvm_type_filter_destroy(struct dev_filter *f)
|
||||
{
|
||||
dbg_free(f);
|
||||
dm_free(f);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ struct dev_filter *lvm_type_filter_create(const char *proc,
|
||||
void lvm_type_filter_destroy(struct dev_filter *f);
|
||||
|
||||
int md_major(void);
|
||||
|
||||
int max_partitions(int major);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
#include "lib.h"
|
||||
#include "disk-rep.h"
|
||||
#include "pool.h"
|
||||
#include "xlate.h"
|
||||
#include "filter.h"
|
||||
#include "lvmcache.h"
|
||||
@@ -255,7 +254,7 @@ static int _read_uuids(struct disk_list *data)
|
||||
if (!dev_read(data->dev, pos, sizeof(buffer), buffer))
|
||||
fail;
|
||||
|
||||
if (!(ul = pool_alloc(data->mem, sizeof(*ul))))
|
||||
if (!(ul = dm_pool_alloc(data->mem, sizeof(*ul))))
|
||||
fail;
|
||||
|
||||
memcpy(ul->uuid, buffer, NAME_LEN);
|
||||
@@ -284,7 +283,7 @@ static int _read_lvs(struct disk_list *data)
|
||||
|
||||
for (i = 0; (i < vgd->lv_max) && (read < vgd->lv_cur); i++) {
|
||||
pos = data->pvd.lv_on_disk.base + (i * sizeof(struct lv_disk));
|
||||
ll = pool_alloc(data->mem, sizeof(*ll));
|
||||
ll = dm_pool_alloc(data->mem, sizeof(*ll));
|
||||
|
||||
if (!ll)
|
||||
fail;
|
||||
@@ -305,7 +304,7 @@ static int _read_lvs(struct disk_list *data)
|
||||
static int _read_extents(struct disk_list *data)
|
||||
{
|
||||
size_t len = sizeof(struct pe_disk) * data->pvd.pe_total;
|
||||
struct pe_disk *extents = pool_alloc(data->mem, len);
|
||||
struct pe_disk *extents = dm_pool_alloc(data->mem, len);
|
||||
uint64_t pos = data->pvd.pe_on_disk.base;
|
||||
|
||||
if (!extents)
|
||||
@@ -321,10 +320,10 @@ static int _read_extents(struct disk_list *data)
|
||||
}
|
||||
|
||||
static struct disk_list *__read_disk(const struct format_type *fmt,
|
||||
struct device *dev, struct pool *mem,
|
||||
struct device *dev, struct dm_pool *mem,
|
||||
const char *vg_name)
|
||||
{
|
||||
struct disk_list *dl = pool_alloc(mem, sizeof(*dl));
|
||||
struct disk_list *dl = dm_pool_alloc(mem, sizeof(*dl));
|
||||
const char *name = dev_name(dev);
|
||||
struct lvmcache_info *info;
|
||||
|
||||
@@ -400,12 +399,12 @@ static struct disk_list *__read_disk(const struct format_type *fmt,
|
||||
return dl;
|
||||
|
||||
bad:
|
||||
pool_free(dl->mem, dl);
|
||||
dm_pool_free(dl->mem, dl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct disk_list *read_disk(const struct format_type *fmt, struct device *dev,
|
||||
struct pool *mem, const char *vg_name)
|
||||
struct dm_pool *mem, const char *vg_name)
|
||||
{
|
||||
struct disk_list *r;
|
||||
|
||||
@@ -452,7 +451,7 @@ static void _add_pv_to_list(struct list *head, struct disk_list *data)
|
||||
* so we can free off all the memory if something goes wrong.
|
||||
*/
|
||||
int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
|
||||
struct dev_filter *filter, struct pool *mem,
|
||||
struct dev_filter *filter, struct dm_pool *mem,
|
||||
struct list *head)
|
||||
{
|
||||
struct dev_iter *iter;
|
||||
@@ -506,6 +505,9 @@ static int _write_vgd(struct disk_list *data)
|
||||
struct vg_disk *vgd = &data->vgd;
|
||||
uint64_t pos = data->pvd.vg_on_disk.base;
|
||||
|
||||
log_debug("Writing %s VG metadata to %s at %" PRIu64 " len %" PRIsize_t,
|
||||
data->pvd.vg_name, dev_name(data->dev), pos, sizeof(*vgd));
|
||||
|
||||
_xlate_vgd(vgd);
|
||||
if (!dev_write(data->dev, pos, sizeof(*vgd), vgd))
|
||||
fail;
|
||||
@@ -528,6 +530,10 @@ static int _write_uuids(struct disk_list *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_debug("Writing %s uuidlist to %s at %" PRIu64 " len %d",
|
||||
data->pvd.vg_name, dev_name(data->dev),
|
||||
pos, NAME_LEN);
|
||||
|
||||
if (!dev_write(data->dev, pos, NAME_LEN, ul->uuid))
|
||||
fail;
|
||||
|
||||
@@ -539,6 +545,10 @@ static int _write_uuids(struct disk_list *data)
|
||||
|
||||
static int _write_lvd(struct device *dev, uint64_t pos, struct lv_disk *disk)
|
||||
{
|
||||
log_debug("Writing %s LV %s metadata to %s at %" PRIu64 " len %"
|
||||
PRIsize_t, disk->vg_name, disk->lv_name, dev_name(dev),
|
||||
pos, sizeof(*disk));
|
||||
|
||||
_xlate_lvd(disk);
|
||||
if (!dev_write(dev, pos, sizeof(*disk), disk))
|
||||
fail;
|
||||
@@ -581,6 +591,10 @@ static int _write_extents(struct disk_list *data)
|
||||
struct pe_disk *extents = data->extents;
|
||||
uint64_t pos = data->pvd.pe_on_disk.base;
|
||||
|
||||
log_debug("Writing %s extents metadata to %s at %" PRIu64 " len %"
|
||||
PRIsize_t, data->pvd.vg_name, dev_name(data->dev),
|
||||
pos, len);
|
||||
|
||||
_xlate_extents(extents, data->pvd.pe_total);
|
||||
if (!dev_write(data->dev, pos, len, extents))
|
||||
fail;
|
||||
@@ -604,7 +618,7 @@ static int _write_pvd(struct disk_list *data)
|
||||
/* Make sure that the gap between the PV structure and
|
||||
the next one is zeroed in order to make non LVM tools
|
||||
happy (idea from AED) */
|
||||
buf = dbg_malloc(size);
|
||||
buf = dm_malloc(size);
|
||||
if (!buf) {
|
||||
log_err("Couldn't allocate temporary PV buffer.");
|
||||
return 0;
|
||||
@@ -613,13 +627,17 @@ static int _write_pvd(struct disk_list *data)
|
||||
memset(buf, 0, size);
|
||||
memcpy(buf, &data->pvd, sizeof(struct pv_disk));
|
||||
|
||||
log_debug("Writing %s PV metadata to %s at %" PRIu64 " len %"
|
||||
PRIsize_t, data->pvd.vg_name, dev_name(data->dev),
|
||||
pos, size);
|
||||
|
||||
_xlate_pvd((struct pv_disk *) buf);
|
||||
if (!dev_write(data->dev, pos, size, buf)) {
|
||||
dbg_free(buf);
|
||||
dm_free(buf);
|
||||
fail;
|
||||
}
|
||||
|
||||
dbg_free(buf);
|
||||
dm_free(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
#include "lvm-types.h"
|
||||
#include "metadata.h"
|
||||
#include "pool.h"
|
||||
#include "toolcontext.h"
|
||||
|
||||
#define MAX_PV 256
|
||||
@@ -159,7 +158,7 @@ struct lvd_list {
|
||||
|
||||
struct disk_list {
|
||||
struct list list;
|
||||
struct pool *mem;
|
||||
struct dm_pool *mem;
|
||||
struct device *dev;
|
||||
|
||||
struct pv_disk pvd;
|
||||
@@ -191,11 +190,11 @@ int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
|
||||
*/
|
||||
|
||||
struct disk_list *read_disk(const struct format_type *fmt, struct device *dev,
|
||||
struct pool *mem, const char *vg_name);
|
||||
struct dm_pool *mem, const char *vg_name);
|
||||
|
||||
int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
|
||||
struct dev_filter *filter,
|
||||
struct pool *mem, struct list *results);
|
||||
struct dm_pool *mem, struct list *results);
|
||||
|
||||
int write_disks(const struct format_type *fmt, struct list *pvds);
|
||||
|
||||
@@ -203,33 +202,33 @@ int write_disks(const struct format_type *fmt, struct list *pvds);
|
||||
* Functions to translate to between disk and in
|
||||
* core structures.
|
||||
*/
|
||||
int import_pv(struct pool *mem, struct device *dev,
|
||||
int import_pv(struct dm_pool *mem, struct device *dev,
|
||||
struct volume_group *vg,
|
||||
struct physical_volume *pv, struct pv_disk *pvd);
|
||||
int export_pv(struct cmd_context *cmd, struct pool *mem,
|
||||
int export_pv(struct cmd_context *cmd, struct dm_pool *mem,
|
||||
struct volume_group *vg,
|
||||
struct pv_disk *pvd, struct physical_volume *pv);
|
||||
|
||||
int import_vg(struct pool *mem,
|
||||
int import_vg(struct dm_pool *mem,
|
||||
struct volume_group *vg, struct disk_list *dl, int partial);
|
||||
int export_vg(struct vg_disk *vgd, struct volume_group *vg);
|
||||
|
||||
int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd);
|
||||
int import_lv(struct dm_pool *mem, struct logical_volume *lv, struct lv_disk *lvd);
|
||||
|
||||
int import_extents(struct cmd_context *cmd, struct volume_group *vg,
|
||||
struct list *pvds);
|
||||
int export_extents(struct disk_list *dl, uint32_t lv_num,
|
||||
struct logical_volume *lv, struct physical_volume *pv);
|
||||
|
||||
int import_pvs(const struct format_type *fmt, struct pool *mem,
|
||||
int import_pvs(const struct format_type *fmt, struct dm_pool *mem,
|
||||
struct volume_group *vg,
|
||||
struct list *pvds, struct list *results, int *count);
|
||||
|
||||
int import_lvs(struct pool *mem, struct volume_group *vg, struct list *pvds);
|
||||
int import_lvs(struct dm_pool *mem, struct volume_group *vg, struct list *pvds);
|
||||
int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
||||
struct physical_volume *pv, const char *dev_dir);
|
||||
|
||||
int import_snapshots(struct pool *mem, struct volume_group *vg,
|
||||
int import_snapshots(struct dm_pool *mem, struct volume_group *vg,
|
||||
struct list *pvds);
|
||||
|
||||
int export_uuids(struct disk_list *dl, struct volume_group *vg);
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
|
||||
#include "lib.h"
|
||||
#include "disk-rep.h"
|
||||
#include "pool.h"
|
||||
#include "hash.h"
|
||||
#include "limits.h"
|
||||
#include "list.h"
|
||||
#include "display.h"
|
||||
#include "toolcontext.h"
|
||||
#include "lvmcache.h"
|
||||
@@ -128,8 +125,8 @@ static int _check_vgs(struct list *pvs, int *partial)
|
||||
static struct volume_group *_build_vg(struct format_instance *fid,
|
||||
struct list *pvs)
|
||||
{
|
||||
struct pool *mem = fid->fmt->cmd->mem;
|
||||
struct volume_group *vg = pool_alloc(mem, sizeof(*vg));
|
||||
struct dm_pool *mem = fid->fmt->cmd->mem;
|
||||
struct volume_group *vg = dm_pool_alloc(mem, sizeof(*vg));
|
||||
struct disk_list *dl;
|
||||
int partial;
|
||||
|
||||
@@ -172,7 +169,7 @@ static struct volume_group *_build_vg(struct format_instance *fid,
|
||||
|
||||
bad:
|
||||
stack;
|
||||
pool_free(mem, vg);
|
||||
dm_pool_free(mem, vg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -180,7 +177,7 @@ static struct volume_group *_vg_read(struct format_instance *fid,
|
||||
const char *vg_name,
|
||||
struct metadata_area *mda)
|
||||
{
|
||||
struct pool *mem = pool_create("lvm1 vg_read", 1024 * 10);
|
||||
struct dm_pool *mem = dm_pool_create("lvm1 vg_read", 1024 * 10);
|
||||
struct list pvs;
|
||||
struct volume_group *vg = NULL;
|
||||
list_init(&pvs);
|
||||
@@ -205,16 +202,16 @@ static struct volume_group *_vg_read(struct format_instance *fid,
|
||||
}
|
||||
|
||||
bad:
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
return vg;
|
||||
}
|
||||
|
||||
static struct disk_list *_flatten_pv(struct format_instance *fid,
|
||||
struct pool *mem, struct volume_group *vg,
|
||||
struct dm_pool *mem, struct volume_group *vg,
|
||||
struct physical_volume *pv,
|
||||
const char *dev_dir)
|
||||
{
|
||||
struct disk_list *dl = pool_alloc(mem, sizeof(*dl));
|
||||
struct disk_list *dl = dm_pool_alloc(mem, sizeof(*dl));
|
||||
|
||||
if (!dl) {
|
||||
stack;
|
||||
@@ -232,14 +229,14 @@ static struct disk_list *_flatten_pv(struct format_instance *fid,
|
||||
!export_uuids(dl, vg) ||
|
||||
!export_lvs(dl, vg, pv, dev_dir) || !calculate_layout(dl)) {
|
||||
stack;
|
||||
pool_free(mem, dl);
|
||||
dm_pool_free(mem, dl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dl;
|
||||
}
|
||||
|
||||
static int _flatten_vg(struct format_instance *fid, struct pool *mem,
|
||||
static int _flatten_vg(struct format_instance *fid, struct dm_pool *mem,
|
||||
struct volume_group *vg,
|
||||
struct list *pvds, const char *dev_dir,
|
||||
struct dev_filter *filter)
|
||||
@@ -270,7 +267,7 @@ static int _flatten_vg(struct format_instance *fid, struct pool *mem,
|
||||
static int _vg_write(struct format_instance *fid, struct volume_group *vg,
|
||||
struct metadata_area *mda)
|
||||
{
|
||||
struct pool *mem = pool_create("lvm1 vg_write", 1024 * 10);
|
||||
struct dm_pool *mem = dm_pool_create("lvm1 vg_write", 1024 * 10);
|
||||
struct list pvds;
|
||||
int r = 0;
|
||||
|
||||
@@ -286,14 +283,14 @@ static int _vg_write(struct format_instance *fid, struct volume_group *vg,
|
||||
write_disks(fid->fmt, &pvds));
|
||||
|
||||
lvmcache_update_vg(vg);
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
struct physical_volume *pv, struct list *mdas)
|
||||
{
|
||||
struct pool *mem = pool_create("lvm1 pv_read", 1024);
|
||||
struct dm_pool *mem = dm_pool_create("lvm1 pv_read", 1024);
|
||||
struct disk_list *dl;
|
||||
struct device *dev;
|
||||
int r = 0;
|
||||
@@ -325,7 +322,7 @@ static int _pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -392,7 +389,7 @@ static int _lv_setup(struct format_instance *fid, struct logical_volume *lv)
|
||||
static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
|
||||
struct list *mdas, int64_t sector)
|
||||
{
|
||||
struct pool *mem;
|
||||
struct dm_pool *mem;
|
||||
struct disk_list *dl;
|
||||
struct list pvs;
|
||||
struct label *label;
|
||||
@@ -415,12 +412,12 @@ static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
|
||||
pv->pe_size = pv->pe_count = 0;
|
||||
pv->pe_start = PE_ALIGN;
|
||||
|
||||
if (!(mem = pool_create("lvm1 pv_write", 1024))) {
|
||||
if (!(mem = dm_pool_create("lvm1 pv_write", 1024))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(dl = pool_alloc(mem, sizeof(*dl)))) {
|
||||
if (!(dl = dm_pool_alloc(mem, sizeof(*dl)))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -444,11 +441,11 @@ static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
return 1;
|
||||
|
||||
bad:
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -510,7 +507,7 @@ static struct format_instance *_create_instance(const struct format_type *fmt,
|
||||
struct format_instance *fid;
|
||||
struct metadata_area *mda;
|
||||
|
||||
if (!(fid = pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
|
||||
if (!(fid = dm_pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -519,9 +516,9 @@ static struct format_instance *_create_instance(const struct format_type *fmt,
|
||||
list_init(&fid->metadata_areas);
|
||||
|
||||
/* Define a NULL metadata area */
|
||||
if (!(mda = pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
stack;
|
||||
pool_free(fmt->cmd->mem, fid);
|
||||
dm_pool_free(fmt->cmd->mem, fid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -539,7 +536,7 @@ static void _destroy_instance(struct format_instance *fid)
|
||||
|
||||
static void _destroy(const struct format_type *fmt)
|
||||
{
|
||||
dbg_free((void *) fmt);
|
||||
dm_free((void *) fmt);
|
||||
}
|
||||
|
||||
static struct format_handler _format1_ops = {
|
||||
@@ -561,7 +558,7 @@ struct format_type *init_format(struct cmd_context *cmd);
|
||||
struct format_type *init_format(struct cmd_context *cmd)
|
||||
#endif
|
||||
{
|
||||
struct format_type *fmt = dbg_malloc(sizeof(*fmt));
|
||||
struct format_type *fmt = dm_malloc(sizeof(*fmt));
|
||||
|
||||
if (!fmt) {
|
||||
stack;
|
||||
|
||||
@@ -19,9 +19,6 @@
|
||||
|
||||
#include "lib.h"
|
||||
#include "disk-rep.h"
|
||||
#include "pool.h"
|
||||
#include "hash.h"
|
||||
#include "list.h"
|
||||
#include "lvm-string.h"
|
||||
#include "filter.h"
|
||||
#include "toolcontext.h"
|
||||
@@ -38,7 +35,7 @@ static int _check_vg_name(const char *name)
|
||||
/*
|
||||
* Extracts the last part of a path.
|
||||
*/
|
||||
static char *_create_lv_name(struct pool *mem, const char *full_name)
|
||||
static char *_create_lv_name(struct dm_pool *mem, const char *full_name)
|
||||
{
|
||||
const char *ptr = strrchr(full_name, '/');
|
||||
|
||||
@@ -47,10 +44,10 @@ static char *_create_lv_name(struct pool *mem, const char *full_name)
|
||||
else
|
||||
ptr++;
|
||||
|
||||
return pool_strdup(mem, ptr);
|
||||
return dm_pool_strdup(mem, ptr);
|
||||
}
|
||||
|
||||
int import_pv(struct pool *mem, struct device *dev,
|
||||
int import_pv(struct dm_pool *mem, struct device *dev,
|
||||
struct volume_group *vg,
|
||||
struct physical_volume *pv, struct pv_disk *pvd)
|
||||
{
|
||||
@@ -58,7 +55,7 @@ int import_pv(struct pool *mem, struct device *dev,
|
||||
memcpy(&pv->id, pvd->pv_uuid, ID_LEN);
|
||||
|
||||
pv->dev = dev;
|
||||
if (!(pv->vg_name = pool_strdup(mem, pvd->vg_name))) {
|
||||
if (!(pv->vg_name = dm_pool_strdup(mem, pvd->vg_name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -112,7 +109,7 @@ static int _system_id(struct cmd_context *cmd, char *s, const char *prefix)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int export_pv(struct cmd_context *cmd, struct pool *mem,
|
||||
int export_pv(struct cmd_context *cmd, struct dm_pool *mem,
|
||||
struct volume_group *vg,
|
||||
struct pv_disk *pvd, struct physical_volume *pv)
|
||||
{
|
||||
@@ -198,7 +195,7 @@ int export_pv(struct cmd_context *cmd, struct pool *mem,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int import_vg(struct pool *mem,
|
||||
int import_vg(struct dm_pool *mem,
|
||||
struct volume_group *vg, struct disk_list *dl, int partial)
|
||||
{
|
||||
struct vg_disk *vgd = &dl->vgd;
|
||||
@@ -209,12 +206,12 @@ int import_vg(struct pool *mem,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(vg->name = pool_strdup(mem, dl->pvd.vg_name))) {
|
||||
if (!(vg->name = dm_pool_strdup(mem, dl->pvd.vg_name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(vg->system_id = pool_alloc(mem, NAME_LEN))) {
|
||||
if (!(vg->system_id = dm_pool_alloc(mem, NAME_LEN))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -288,7 +285,7 @@ int export_vg(struct vg_disk *vgd, struct volume_group *vg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd)
|
||||
int import_lv(struct dm_pool *mem, struct logical_volume *lv, struct lv_disk *lvd)
|
||||
{
|
||||
lvid_from_lvnum(&lv->lvid, &lv->vg->id, lvd->lv_number);
|
||||
|
||||
@@ -414,7 +411,7 @@ int export_extents(struct disk_list *dl, uint32_t lv_num,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int import_pvs(const struct format_type *fmt, struct pool *mem,
|
||||
int import_pvs(const struct format_type *fmt, struct dm_pool *mem,
|
||||
struct volume_group *vg,
|
||||
struct list *pvds, struct list *results, int *count)
|
||||
{
|
||||
@@ -423,8 +420,8 @@ int import_pvs(const struct format_type *fmt, struct pool *mem,
|
||||
|
||||
*count = 0;
|
||||
list_iterate_items(dl, pvds) {
|
||||
if (!(pvl = pool_zalloc(mem, sizeof(*pvl))) ||
|
||||
!(pvl->pv = pool_alloc(mem, sizeof(*pvl->pv)))) {
|
||||
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl))) ||
|
||||
!(pvl->pv = dm_pool_alloc(mem, sizeof(*pvl->pv)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -442,15 +439,15 @@ int import_pvs(const struct format_type *fmt, struct pool *mem,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct logical_volume *_add_lv(struct pool *mem,
|
||||
static struct logical_volume *_add_lv(struct dm_pool *mem,
|
||||
struct volume_group *vg,
|
||||
struct lv_disk *lvd)
|
||||
{
|
||||
struct lv_list *ll;
|
||||
struct logical_volume *lv;
|
||||
|
||||
if (!(ll = pool_zalloc(mem, sizeof(*ll))) ||
|
||||
!(ll->lv = pool_zalloc(mem, sizeof(*ll->lv)))) {
|
||||
if (!(ll = dm_pool_zalloc(mem, sizeof(*ll))) ||
|
||||
!(ll->lv = dm_pool_zalloc(mem, sizeof(*ll->lv)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -468,7 +465,7 @@ static struct logical_volume *_add_lv(struct pool *mem,
|
||||
return lv;
|
||||
}
|
||||
|
||||
int import_lvs(struct pool *mem, struct volume_group *vg, struct list *pvds)
|
||||
int import_lvs(struct dm_pool *mem, struct volume_group *vg, struct list *pvds)
|
||||
{
|
||||
struct disk_list *dl;
|
||||
struct lvd_list *ll;
|
||||
@@ -498,14 +495,14 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
||||
struct lvd_list *lvdl;
|
||||
size_t len;
|
||||
uint32_t lv_num;
|
||||
struct hash_table *lvd_hash;
|
||||
struct dm_hash_table *lvd_hash;
|
||||
|
||||
if (!_check_vg_name(vg->name)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(lvd_hash = hash_create(32))) {
|
||||
if (!(lvd_hash = dm_hash_create(32))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -514,7 +511,7 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
||||
* setup the pv's extents array
|
||||
*/
|
||||
len = sizeof(struct pe_disk) * dl->pvd.pe_total;
|
||||
if (!(dl->extents = pool_alloc(dl->mem, len))) {
|
||||
if (!(dl->extents = dm_pool_alloc(dl->mem, len))) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
@@ -524,7 +521,7 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
||||
if (ll->lv->status & SNAPSHOT)
|
||||
continue;
|
||||
|
||||
if (!(lvdl = pool_alloc(dl->mem, sizeof(*lvdl)))) {
|
||||
if (!(lvdl = dm_pool_alloc(dl->mem, sizeof(*lvdl)))) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
@@ -534,7 +531,7 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
||||
lv_num = lvnum_from_lvid(&ll->lv->lvid);
|
||||
lvdl->lvd.lv_number = lv_num;
|
||||
|
||||
if (!hash_insert(lvd_hash, ll->lv->name, &lvdl->lvd)) {
|
||||
if (!dm_hash_insert(lvd_hash, ll->lv->name, &lvdl->lvd)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
@@ -561,14 +558,14 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
hash_destroy(lvd_hash);
|
||||
dm_hash_destroy(lvd_hash);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: More inefficient code.
|
||||
*/
|
||||
int import_snapshots(struct pool *mem, struct volume_group *vg,
|
||||
int import_snapshots(struct dm_pool *mem, struct volume_group *vg,
|
||||
struct list *pvds)
|
||||
{
|
||||
struct logical_volume *lvs[MAX_LV];
|
||||
@@ -642,7 +639,7 @@ int export_uuids(struct disk_list *dl, struct volume_group *vg)
|
||||
struct pv_list *pvl;
|
||||
|
||||
list_iterate_items(pvl, &vg->pvs) {
|
||||
if (!(ul = pool_alloc(dl->mem, sizeof(*ul)))) {
|
||||
if (!(ul = dm_pool_alloc(dl->mem, sizeof(*ul)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
|
||||
#include "lib.h"
|
||||
#include "metadata.h"
|
||||
#include "hash.h"
|
||||
#include "pool.h"
|
||||
#include "disk-rep.h"
|
||||
#include "lv_alloc.h"
|
||||
#include "display.h"
|
||||
@@ -44,10 +42,10 @@ struct lv_map {
|
||||
struct pe_specifier *map;
|
||||
};
|
||||
|
||||
static struct hash_table *_create_lv_maps(struct pool *mem,
|
||||
static struct dm_hash_table *_create_lv_maps(struct dm_pool *mem,
|
||||
struct volume_group *vg)
|
||||
{
|
||||
struct hash_table *maps = hash_create(32);
|
||||
struct dm_hash_table *maps = dm_hash_create(32);
|
||||
struct lv_list *ll;
|
||||
struct lv_map *lvm;
|
||||
|
||||
@@ -61,19 +59,19 @@ static struct hash_table *_create_lv_maps(struct pool *mem,
|
||||
if (ll->lv->status & SNAPSHOT)
|
||||
continue;
|
||||
|
||||
if (!(lvm = pool_alloc(mem, sizeof(*lvm)))) {
|
||||
if (!(lvm = dm_pool_alloc(mem, sizeof(*lvm)))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
lvm->lv = ll->lv;
|
||||
if (!(lvm->map = pool_zalloc(mem, sizeof(*lvm->map)
|
||||
if (!(lvm->map = dm_pool_zalloc(mem, sizeof(*lvm->map)
|
||||
* ll->lv->le_count))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!hash_insert(maps, ll->lv->name, lvm)) {
|
||||
if (!dm_hash_insert(maps, ll->lv->name, lvm)) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -82,12 +80,12 @@ static struct hash_table *_create_lv_maps(struct pool *mem,
|
||||
return maps;
|
||||
|
||||
bad:
|
||||
hash_destroy(maps);
|
||||
dm_hash_destroy(maps);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _fill_lv_array(struct lv_map **lvs,
|
||||
struct hash_table *maps, struct disk_list *dl)
|
||||
struct dm_hash_table *maps, struct disk_list *dl)
|
||||
{
|
||||
struct lvd_list *ll;
|
||||
struct lv_map *lvm;
|
||||
@@ -95,7 +93,7 @@ static int _fill_lv_array(struct lv_map **lvs,
|
||||
memset(lvs, 0, sizeof(*lvs) * MAX_LV);
|
||||
|
||||
list_iterate_items(ll, &dl->lvds) {
|
||||
if (!(lvm = hash_lookup(maps, strrchr(ll->lvd.lv_name, '/')
|
||||
if (!(lvm = dm_hash_lookup(maps, strrchr(ll->lvd.lv_name, '/')
|
||||
+ 1))) {
|
||||
log_err("Physical volume (%s) contains an "
|
||||
"unknown logical volume (%s).",
|
||||
@@ -112,7 +110,7 @@ static int _fill_lv_array(struct lv_map **lvs,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _fill_maps(struct hash_table *maps, struct volume_group *vg,
|
||||
static int _fill_maps(struct dm_hash_table *maps, struct volume_group *vg,
|
||||
struct list *pvds)
|
||||
{
|
||||
struct disk_list *dl;
|
||||
@@ -184,13 +182,13 @@ static int _check_single_map(struct lv_map *lvm)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _check_maps_are_complete(struct hash_table *maps)
|
||||
static int _check_maps_are_complete(struct dm_hash_table *maps)
|
||||
{
|
||||
struct hash_node *n;
|
||||
struct dm_hash_node *n;
|
||||
struct lv_map *lvm;
|
||||
|
||||
for (n = hash_get_first(maps); n; n = hash_get_next(maps, n)) {
|
||||
lvm = (struct lv_map *) hash_get_data(maps, n);
|
||||
for (n = dm_hash_get_first(maps); n; n = dm_hash_get_next(maps, n)) {
|
||||
lvm = (struct lv_map *) dm_hash_get_data(maps, n);
|
||||
|
||||
if (!_check_single_map(lvm)) {
|
||||
stack;
|
||||
@@ -327,13 +325,13 @@ static int _build_segments(struct cmd_context *cmd, struct lv_map *lvm)
|
||||
_read_linear(cmd, lvm));
|
||||
}
|
||||
|
||||
static int _build_all_segments(struct cmd_context *cmd, struct hash_table *maps)
|
||||
static int _build_all_segments(struct cmd_context *cmd, struct dm_hash_table *maps)
|
||||
{
|
||||
struct hash_node *n;
|
||||
struct dm_hash_node *n;
|
||||
struct lv_map *lvm;
|
||||
|
||||
for (n = hash_get_first(maps); n; n = hash_get_next(maps, n)) {
|
||||
lvm = (struct lv_map *) hash_get_data(maps, n);
|
||||
for (n = dm_hash_get_first(maps); n; n = dm_hash_get_next(maps, n)) {
|
||||
lvm = (struct lv_map *) dm_hash_get_data(maps, n);
|
||||
if (!_build_segments(cmd, lvm)) {
|
||||
stack;
|
||||
return 0;
|
||||
@@ -347,8 +345,8 @@ int import_extents(struct cmd_context *cmd, struct volume_group *vg,
|
||||
struct list *pvds)
|
||||
{
|
||||
int r = 0;
|
||||
struct pool *scratch = pool_create("lvm1 import_extents", 10 * 1024);
|
||||
struct hash_table *maps;
|
||||
struct dm_pool *scratch = dm_pool_create("lvm1 import_extents", 10 * 1024);
|
||||
struct dm_hash_table *maps;
|
||||
|
||||
if (!scratch) {
|
||||
stack;
|
||||
@@ -378,7 +376,7 @@ int import_extents(struct cmd_context *cmd, struct volume_group *vg,
|
||||
|
||||
out:
|
||||
if (maps)
|
||||
hash_destroy(maps);
|
||||
pool_destroy(scratch);
|
||||
dm_hash_destroy(maps);
|
||||
dm_pool_destroy(scratch);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ int calculate_layout(struct disk_list *dl)
|
||||
int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
|
||||
uint32_t max_extent_count, uint64_t pe_start)
|
||||
{
|
||||
struct pv_disk *pvd = dbg_malloc(sizeof(*pvd));
|
||||
struct pv_disk *pvd = dm_malloc(sizeof(*pvd));
|
||||
uint32_t end;
|
||||
|
||||
if (!pvd) {
|
||||
@@ -138,7 +138,7 @@ int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
|
||||
if (pvd->pe_total < PE_SIZE_PV_SIZE_REL) {
|
||||
log_error("Too few extents on %s. Try smaller extent size.",
|
||||
dev_name(pv->dev));
|
||||
dbg_free(pvd);
|
||||
dm_free(pvd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -160,13 +160,13 @@ int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
|
||||
log_error("Metadata extent limit (%u) exceeded for %s - "
|
||||
"%u required", MAX_PE_TOTAL, dev_name(pv->dev),
|
||||
pvd->pe_total);
|
||||
dbg_free(pvd);
|
||||
dm_free(pvd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pv->pe_count = pvd->pe_total;
|
||||
pv->pe_start = pvd->pe_start;
|
||||
/* We can't set pe_size here without breaking LVM1 compatibility */
|
||||
dbg_free(pvd);
|
||||
dm_free(pvd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ static void _destroy_label(struct labeller *l, struct label *label)
|
||||
|
||||
static void _destroy(struct labeller *l)
|
||||
{
|
||||
dbg_free(l);
|
||||
dm_free(l);
|
||||
}
|
||||
|
||||
struct label_ops _lvm1_ops = {
|
||||
@@ -107,7 +107,7 @@ struct labeller *lvm1_labeller_create(struct format_type *fmt)
|
||||
{
|
||||
struct labeller *l;
|
||||
|
||||
if (!(l = dbg_malloc(sizeof(*l)))) {
|
||||
if (!(l = dm_malloc(sizeof(*l)))) {
|
||||
log_err("Couldn't allocate labeller object.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "pool.h"
|
||||
#include "disk-rep.h"
|
||||
|
||||
/*
|
||||
@@ -29,7 +28,7 @@ int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,
|
||||
{
|
||||
struct list all_pvs;
|
||||
struct disk_list *dl;
|
||||
struct pool *mem = pool_create("lvm1 vg_number", 10 * 1024);
|
||||
struct dm_pool *mem = dm_pool_create("lvm1 vg_number", 10 * 1024);
|
||||
int numbers[MAX_VG], i, r = 0;
|
||||
|
||||
list_init(&all_pvs);
|
||||
@@ -62,6 +61,6 @@ int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,
|
||||
}
|
||||
|
||||
out:
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -14,12 +14,10 @@
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "pool.h"
|
||||
#include "label.h"
|
||||
#include "metadata.h"
|
||||
#include "lvmcache.h"
|
||||
#include "filter.h"
|
||||
#include "list.h"
|
||||
#include "xlate.h"
|
||||
|
||||
#include "disk_rep.h"
|
||||
@@ -35,7 +33,7 @@
|
||||
#define CPOUT_64(x, y) {(y) = xlate64_be((x));}
|
||||
|
||||
static int __read_pool_disk(const struct format_type *fmt, struct device *dev,
|
||||
struct pool *mem, struct pool_list *pl,
|
||||
struct dm_pool *mem, struct pool_list *pl,
|
||||
const char *vg_name)
|
||||
{
|
||||
char buf[512];
|
||||
@@ -240,13 +238,13 @@ void get_pool_uuid(char *uuid, uint64_t poolid, uint32_t spid, uint32_t devid)
|
||||
|
||||
}
|
||||
|
||||
static int _read_vg_pds(const struct format_type *fmt, struct pool *mem,
|
||||
static int _read_vg_pds(const struct format_type *fmt, struct dm_pool *mem,
|
||||
struct lvmcache_vginfo *vginfo, struct list *head,
|
||||
uint32_t *devcount)
|
||||
{
|
||||
struct lvmcache_info *info;
|
||||
struct pool_list *pl = NULL;
|
||||
struct pool *tmpmem;
|
||||
struct dm_pool *tmpmem;
|
||||
|
||||
uint32_t sp_count = 0;
|
||||
uint32_t *sp_devs = NULL;
|
||||
@@ -254,7 +252,7 @@ static int _read_vg_pds(const struct format_type *fmt, struct pool *mem,
|
||||
|
||||
/* FIXME: maybe should return a different error in memory
|
||||
* allocation failure */
|
||||
if (!(tmpmem = pool_create("pool read_vg", 512))) {
|
||||
if (!(tmpmem = dm_pool_create("pool read_vg", 512))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -271,11 +269,11 @@ static int _read_vg_pds(const struct format_type *fmt, struct pool *mem,
|
||||
/* FIXME pl left uninitialised if !info->dev */
|
||||
sp_count = pl->pd.pl_subpools;
|
||||
if (!(sp_devs =
|
||||
pool_zalloc(tmpmem,
|
||||
dm_pool_zalloc(tmpmem,
|
||||
sizeof(uint32_t) * sp_count))) {
|
||||
log_error("Unable to allocate %d 32-bit uints",
|
||||
sp_count);
|
||||
pool_destroy(tmpmem);
|
||||
dm_pool_destroy(tmpmem);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -296,7 +294,7 @@ static int _read_vg_pds(const struct format_type *fmt, struct pool *mem,
|
||||
for (i = 0; i < sp_count; i++)
|
||||
*devcount += sp_devs[i];
|
||||
|
||||
pool_destroy(tmpmem);
|
||||
dm_pool_destroy(tmpmem);
|
||||
|
||||
if (pl && *pl->pd.pl_pool_name)
|
||||
return 1;
|
||||
@@ -306,7 +304,7 @@ static int _read_vg_pds(const struct format_type *fmt, struct pool *mem,
|
||||
}
|
||||
|
||||
int read_pool_pds(const struct format_type *fmt, const char *vg_name,
|
||||
struct pool *mem, struct list *pdhead)
|
||||
struct dm_pool *mem, struct list *pdhead)
|
||||
{
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
uint32_t totaldevs;
|
||||
@@ -351,7 +349,7 @@ int read_pool_pds(const struct format_type *fmt, const char *vg_name,
|
||||
}
|
||||
|
||||
struct pool_list *read_pool_disk(const struct format_type *fmt,
|
||||
struct device *dev, struct pool *mem,
|
||||
struct device *dev, struct dm_pool *mem,
|
||||
const char *vg_name)
|
||||
{
|
||||
struct pool_list *pl;
|
||||
@@ -361,7 +359,7 @@ struct pool_list *read_pool_disk(const struct format_type *fmt,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(pl = pool_zalloc(mem, sizeof(*pl)))) {
|
||||
if (!(pl = dm_pool_zalloc(mem, sizeof(*pl)))) {
|
||||
log_error("Unable to allocate pool list structure");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
#include "label.h"
|
||||
#include "metadata.h"
|
||||
#include "pool.h"
|
||||
|
||||
#define MINOR_OFFSET 65536
|
||||
|
||||
@@ -138,20 +137,20 @@ int read_pool_label(struct pool_list *pl, struct labeller *l,
|
||||
void pool_label_out(struct pool_disk *pl, char *buf);
|
||||
void pool_label_in(struct pool_disk *pl, char *buf);
|
||||
void get_pool_uuid(char *uuid, uint64_t poolid, uint32_t spid, uint32_t devid);
|
||||
int import_pool_vg(struct volume_group *vg, struct pool *mem, struct list *pls);
|
||||
int import_pool_lvs(struct volume_group *vg, struct pool *mem,
|
||||
int import_pool_vg(struct volume_group *vg, struct dm_pool *mem, struct list *pls);
|
||||
int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem,
|
||||
struct list *pls);
|
||||
int import_pool_pvs(const struct format_type *fmt, struct volume_group *vg,
|
||||
struct list *pvs, struct pool *mem, struct list *pls);
|
||||
int import_pool_pv(const struct format_type *fmt, struct pool *mem,
|
||||
struct list *pvs, struct dm_pool *mem, struct list *pls);
|
||||
int import_pool_pv(const struct format_type *fmt, struct dm_pool *mem,
|
||||
struct volume_group *vg, struct physical_volume *pv,
|
||||
struct pool_list *pl);
|
||||
int import_pool_segments(struct list *lvs, struct pool *mem,
|
||||
int import_pool_segments(struct list *lvs, struct dm_pool *mem,
|
||||
struct user_subpool *usp, int sp_count);
|
||||
int read_pool_pds(const struct format_type *fmt, const char *vgname,
|
||||
struct pool *mem, struct list *head);
|
||||
struct dm_pool *mem, struct list *head);
|
||||
struct pool_list *read_pool_disk(const struct format_type *fmt,
|
||||
struct device *dev, struct pool *mem,
|
||||
struct device *dev, struct dm_pool *mem,
|
||||
const char *vg_name);
|
||||
|
||||
#endif /* DISK_REP_POOL_FORMAT_H */
|
||||
|
||||
@@ -14,12 +14,9 @@
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "pool.h"
|
||||
#include "label.h"
|
||||
#include "metadata.h"
|
||||
#include "hash.h"
|
||||
#include "limits.h"
|
||||
#include "list.h"
|
||||
#include "display.h"
|
||||
#include "toolcontext.h"
|
||||
#include "lvmcache.h"
|
||||
@@ -30,7 +27,7 @@
|
||||
#define FMT_POOL_NAME "pool"
|
||||
|
||||
/* Must be called after pvs are imported */
|
||||
static struct user_subpool *_build_usp(struct list *pls, struct pool *mem,
|
||||
static struct user_subpool *_build_usp(struct list *pls, struct dm_pool *mem,
|
||||
int *sps)
|
||||
{
|
||||
struct pool_list *pl;
|
||||
@@ -43,7 +40,7 @@ static struct user_subpool *_build_usp(struct list *pls, struct pool *mem,
|
||||
*/
|
||||
list_iterate_items(pl, pls) {
|
||||
*sps = pl->pd.pl_subpools;
|
||||
if (!usp && (!(usp = pool_zalloc(mem, sizeof(*usp) * (*sps))))) {
|
||||
if (!usp && (!(usp = dm_pool_zalloc(mem, sizeof(*usp) * (*sps))))) {
|
||||
log_error("Unable to allocate %d subpool structures",
|
||||
*sps);
|
||||
return 0;
|
||||
@@ -61,7 +58,7 @@ static struct user_subpool *_build_usp(struct list *pls, struct pool *mem,
|
||||
|
||||
if (!cur_sp->devs &&
|
||||
(!(cur_sp->devs =
|
||||
pool_zalloc(mem,
|
||||
dm_pool_zalloc(mem,
|
||||
sizeof(*usp->devs) * pl->pd.pl_sp_devs)))) {
|
||||
|
||||
log_error("Unable to allocate %d pool_device "
|
||||
@@ -103,15 +100,15 @@ static int _check_usp(char *vgname, struct user_subpool *usp, int sp_count)
|
||||
}
|
||||
|
||||
static struct volume_group *_build_vg_from_pds(struct format_instance
|
||||
*fid, struct pool *mem,
|
||||
*fid, struct dm_pool *mem,
|
||||
struct list *pds)
|
||||
{
|
||||
struct pool *smem = fid->fmt->cmd->mem;
|
||||
struct dm_pool *smem = fid->fmt->cmd->mem;
|
||||
struct volume_group *vg = NULL;
|
||||
struct user_subpool *usp = NULL;
|
||||
int sp_count;
|
||||
|
||||
if (!(vg = pool_zalloc(smem, sizeof(*vg)))) {
|
||||
if (!(vg = dm_pool_zalloc(smem, sizeof(*vg)))) {
|
||||
log_error("Unable to allocate volume group structure");
|
||||
return NULL;
|
||||
}
|
||||
@@ -176,7 +173,7 @@ static struct volume_group *_vg_read(struct format_instance *fid,
|
||||
const char *vg_name,
|
||||
struct metadata_area *mda)
|
||||
{
|
||||
struct pool *mem = pool_create("pool vg_read", 1024);
|
||||
struct dm_pool *mem = dm_pool_create("pool vg_read", 1024);
|
||||
struct list pds;
|
||||
struct volume_group *vg = NULL;
|
||||
|
||||
@@ -205,7 +202,7 @@ static struct volume_group *_vg_read(struct format_instance *fid,
|
||||
}
|
||||
|
||||
out:
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
return vg;
|
||||
}
|
||||
|
||||
@@ -222,7 +219,7 @@ static int _pv_setup(const struct format_type *fmt,
|
||||
static int _pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
struct physical_volume *pv, struct list *mdas)
|
||||
{
|
||||
struct pool *mem = pool_create("pool pv_read", 1024);
|
||||
struct dm_pool *mem = dm_pool_create("pool pv_read", 1024);
|
||||
struct pool_list *pl;
|
||||
struct device *dev;
|
||||
int r = 0;
|
||||
@@ -259,7 +256,7 @@ static int _pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
pool_destroy(mem);
|
||||
dm_pool_destroy(mem);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -276,7 +273,7 @@ static struct format_instance *_create_instance(const struct format_type *fmt,
|
||||
struct format_instance *fid;
|
||||
struct metadata_area *mda;
|
||||
|
||||
if (!(fid = pool_zalloc(fmt->cmd->mem, sizeof(*fid)))) {
|
||||
if (!(fid = dm_pool_zalloc(fmt->cmd->mem, sizeof(*fid)))) {
|
||||
log_error("Unable to allocate format instance structure for "
|
||||
"pool format");
|
||||
return NULL;
|
||||
@@ -286,10 +283,10 @@ static struct format_instance *_create_instance(const struct format_type *fmt,
|
||||
list_init(&fid->metadata_areas);
|
||||
|
||||
/* Define a NULL metadata area */
|
||||
if (!(mda = pool_zalloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
if (!(mda = dm_pool_zalloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
log_error("Unable to allocate metadata area structure "
|
||||
"for pool format");
|
||||
pool_free(fmt->cmd->mem, fid);
|
||||
dm_pool_free(fmt->cmd->mem, fid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -307,7 +304,7 @@ static void _destroy_instance(struct format_instance *fid)
|
||||
|
||||
static void _destroy(const struct format_type *fmt)
|
||||
{
|
||||
dbg_free((void *) fmt);
|
||||
dm_free((void *) fmt);
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
@@ -327,7 +324,7 @@ struct format_type *init_format(struct cmd_context *cmd);
|
||||
struct format_type *init_format(struct cmd_context *cmd)
|
||||
#endif
|
||||
{
|
||||
struct format_type *fmt = dbg_malloc(sizeof(*fmt));
|
||||
struct format_type *fmt = dm_malloc(sizeof(*fmt));
|
||||
|
||||
if (!fmt) {
|
||||
log_error("Unable to allocate format type structure for pool "
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "pool.h"
|
||||
#include "label.h"
|
||||
#include "metadata.h"
|
||||
#include "lvmcache.h"
|
||||
@@ -28,7 +27,7 @@
|
||||
|
||||
/* This file contains only imports at the moment... */
|
||||
|
||||
int import_pool_vg(struct volume_group *vg, struct pool *mem, struct list *pls)
|
||||
int import_pool_vg(struct volume_group *vg, struct dm_pool *mem, struct list *pls)
|
||||
{
|
||||
struct pool_list *pl;
|
||||
|
||||
@@ -41,7 +40,7 @@ int import_pool_vg(struct volume_group *vg, struct pool *mem, struct list *pls)
|
||||
if (vg->name)
|
||||
continue;
|
||||
|
||||
vg->name = pool_strdup(mem, pl->pd.pl_pool_name);
|
||||
vg->name = dm_pool_strdup(mem, pl->pd.pl_pool_name);
|
||||
get_pool_vg_uuid(&vg->id, &pl->pd);
|
||||
vg->extent_size = POOL_PE_SIZE;
|
||||
vg->status |= LVM_READ | LVM_WRITE | CLUSTERED | SHARED;
|
||||
@@ -55,10 +54,10 @@ int import_pool_vg(struct volume_group *vg, struct pool *mem, struct list *pls)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int import_pool_lvs(struct volume_group *vg, struct pool *mem, struct list *pls)
|
||||
int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem, struct list *pls)
|
||||
{
|
||||
struct pool_list *pl;
|
||||
struct lv_list *lvl = pool_zalloc(mem, sizeof(*lvl));
|
||||
struct lv_list *lvl = dm_pool_zalloc(mem, sizeof(*lvl));
|
||||
struct logical_volume *lv;
|
||||
|
||||
if (!lvl) {
|
||||
@@ -66,7 +65,7 @@ int import_pool_lvs(struct volume_group *vg, struct pool *mem, struct list *pls)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(lvl->lv = pool_zalloc(mem, sizeof(*lvl->lv)))) {
|
||||
if (!(lvl->lv = dm_pool_zalloc(mem, sizeof(*lvl->lv)))) {
|
||||
log_error("Unable to allocate logical volume structure");
|
||||
return 0;
|
||||
}
|
||||
@@ -90,7 +89,7 @@ int import_pool_lvs(struct volume_group *vg, struct pool *mem, struct list *pls)
|
||||
if (lv->name)
|
||||
continue;
|
||||
|
||||
if (!(lv->name = pool_strdup(mem, pl->pd.pl_pool_name))) {
|
||||
if (!(lv->name = dm_pool_strdup(mem, pl->pd.pl_pool_name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -124,17 +123,17 @@ int import_pool_lvs(struct volume_group *vg, struct pool *mem, struct list *pls)
|
||||
}
|
||||
|
||||
int import_pool_pvs(const struct format_type *fmt, struct volume_group *vg,
|
||||
struct list *pvs, struct pool *mem, struct list *pls)
|
||||
struct list *pvs, struct dm_pool *mem, struct list *pls)
|
||||
{
|
||||
struct pv_list *pvl;
|
||||
struct pool_list *pl;
|
||||
|
||||
list_iterate_items(pl, pls) {
|
||||
if (!(pvl = pool_zalloc(mem, sizeof(*pvl)))) {
|
||||
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl)))) {
|
||||
log_error("Unable to allocate pv list structure");
|
||||
return 0;
|
||||
}
|
||||
if (!(pvl->pv = pool_zalloc(mem, sizeof(*pvl->pv)))) {
|
||||
if (!(pvl->pv = dm_pool_zalloc(mem, sizeof(*pvl->pv)))) {
|
||||
log_error("Unable to allocate pv structure");
|
||||
return 0;
|
||||
}
|
||||
@@ -150,7 +149,7 @@ int import_pool_pvs(const struct format_type *fmt, struct volume_group *vg,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int import_pool_pv(const struct format_type *fmt, struct pool *mem,
|
||||
int import_pool_pv(const struct format_type *fmt, struct dm_pool *mem,
|
||||
struct volume_group *vg, struct physical_volume *pv,
|
||||
struct pool_list *pl)
|
||||
{
|
||||
@@ -162,7 +161,7 @@ int import_pool_pv(const struct format_type *fmt, struct pool *mem,
|
||||
pv->fmt = fmt;
|
||||
|
||||
pv->dev = pl->dev;
|
||||
if (!(pv->vg_name = pool_strdup(mem, pd->pl_pool_name))) {
|
||||
if (!(pv->vg_name = dm_pool_strdup(mem, pd->pl_pool_name))) {
|
||||
log_error("Unable to duplicate vg_name string");
|
||||
return 0;
|
||||
}
|
||||
@@ -197,7 +196,7 @@ static const char *_cvt_sptype(uint32_t sptype)
|
||||
return sptype_names[i].name;
|
||||
}
|
||||
|
||||
static int _add_stripe_seg(struct pool *mem,
|
||||
static int _add_stripe_seg(struct dm_pool *mem,
|
||||
struct user_subpool *usp, struct logical_volume *lv,
|
||||
uint32_t *le_cur)
|
||||
{
|
||||
@@ -243,7 +242,7 @@ static int _add_stripe_seg(struct pool *mem,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _add_linear_seg(struct pool *mem,
|
||||
static int _add_linear_seg(struct dm_pool *mem,
|
||||
struct user_subpool *usp, struct logical_volume *lv,
|
||||
uint32_t *le_cur)
|
||||
{
|
||||
@@ -284,7 +283,7 @@ static int _add_linear_seg(struct pool *mem,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int import_pool_segments(struct list *lvs, struct pool *mem,
|
||||
int import_pool_segments(struct list *lvs, struct dm_pool *mem,
|
||||
struct user_subpool *usp, int subpools)
|
||||
{
|
||||
struct lv_list *lvl;
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "pool.h"
|
||||
#include "label.h"
|
||||
#include "metadata.h"
|
||||
#include "xlate.h"
|
||||
@@ -79,7 +78,7 @@ static void _destroy_label(struct labeller *l, struct label *label)
|
||||
|
||||
static void _destroy(struct labeller *l)
|
||||
{
|
||||
dbg_free(l);
|
||||
dm_free(l);
|
||||
}
|
||||
|
||||
struct label_ops _pool_ops = {
|
||||
@@ -96,7 +95,7 @@ struct labeller *pool_labeller_create(struct format_type *fmt)
|
||||
{
|
||||
struct labeller *l;
|
||||
|
||||
if (!(l = dbg_malloc(sizeof(*l)))) {
|
||||
if (!(l = dm_malloc(sizeof(*l)))) {
|
||||
log_error("Couldn't allocate labeller object.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
#include "lib.h"
|
||||
#include "format-text.h"
|
||||
|
||||
#include "pool.h"
|
||||
#include "config.h"
|
||||
#include "hash.h"
|
||||
#include "import-export.h"
|
||||
#include "lvm-string.h"
|
||||
#include "lvm-file.h"
|
||||
@@ -109,24 +107,24 @@ static void _insert_file(struct list *head, struct archive_file *b)
|
||||
list_add_h(&bf->list, &b->list);
|
||||
}
|
||||
|
||||
static char *_join(struct pool *mem, const char *dir, const char *name)
|
||||
static char *_join(struct dm_pool *mem, const char *dir, const char *name)
|
||||
{
|
||||
if (!pool_begin_object(mem, 32) ||
|
||||
!pool_grow_object(mem, dir, strlen(dir)) ||
|
||||
!pool_grow_object(mem, "/", 1) ||
|
||||
!pool_grow_object(mem, name, strlen(name)) ||
|
||||
!pool_grow_object(mem, "\0", 1)) {
|
||||
if (!dm_pool_begin_object(mem, 32) ||
|
||||
!dm_pool_grow_object(mem, dir, strlen(dir)) ||
|
||||
!dm_pool_grow_object(mem, "/", 1) ||
|
||||
!dm_pool_grow_object(mem, name, strlen(name)) ||
|
||||
!dm_pool_grow_object(mem, "\0", 1)) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pool_end_object(mem);
|
||||
return dm_pool_end_object(mem);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a list of archive_files.
|
||||
*/
|
||||
static struct list *_scan_archive(struct pool *mem,
|
||||
static struct list *_scan_archive(struct dm_pool *mem,
|
||||
const char *vgname, const char *dir)
|
||||
{
|
||||
int i, count;
|
||||
@@ -136,7 +134,7 @@ static struct list *_scan_archive(struct pool *mem,
|
||||
struct archive_file *af;
|
||||
struct list *results;
|
||||
|
||||
if (!(results = pool_alloc(mem, sizeof(*results)))) {
|
||||
if (!(results = dm_pool_alloc(mem, sizeof(*results)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -171,7 +169,7 @@ static struct list *_scan_archive(struct pool *mem,
|
||||
/*
|
||||
* Create a new archive_file.
|
||||
*/
|
||||
if (!(af = pool_alloc(mem, sizeof(*af)))) {
|
||||
if (!(af = dm_pool_alloc(mem, sizeof(*af)))) {
|
||||
log_err("Couldn't create new archive file.");
|
||||
results = NULL;
|
||||
goto out;
|
||||
@@ -333,7 +331,7 @@ static void _display_archive(struct cmd_context *cmd, struct archive_file *af)
|
||||
log_print("Description:\t%s", desc ? desc : "<No description>");
|
||||
log_print("Backup Time:\t%s", ctime(&when));
|
||||
|
||||
pool_free(cmd->mem, vg);
|
||||
dm_pool_free(cmd->mem, vg);
|
||||
tf->fmt->ops->destroy_instance(tf);
|
||||
}
|
||||
|
||||
@@ -353,7 +351,7 @@ int archive_list(struct cmd_context *cmd, const char *dir, const char *vgname)
|
||||
list_iterate_back_items(af, archives)
|
||||
_display_archive(cmd, af);
|
||||
|
||||
pool_free(cmd->mem, archives);
|
||||
dm_pool_free(cmd->mem, archives);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ struct backup_params {
|
||||
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,
|
||||
if (!(cmd->archive_params = dm_pool_zalloc(cmd->libmem,
|
||||
sizeof(*cmd->archive_params)))) {
|
||||
log_error("archive_params alloc failed");
|
||||
return 0;
|
||||
@@ -49,7 +49,7 @@ int archive_init(struct cmd_context *cmd, const char *dir,
|
||||
if (!*dir)
|
||||
return 1;
|
||||
|
||||
if (!(cmd->archive_params->dir = dbg_strdup(dir))) {
|
||||
if (!(cmd->archive_params->dir = dm_strdup(dir))) {
|
||||
log_error("Couldn't copy archive directory name.");
|
||||
return 0;
|
||||
}
|
||||
@@ -64,7 +64,7 @@ int archive_init(struct cmd_context *cmd, const char *dir,
|
||||
void archive_exit(struct cmd_context *cmd)
|
||||
{
|
||||
if (cmd->archive_params->dir)
|
||||
dbg_free(cmd->archive_params->dir);
|
||||
dm_free(cmd->archive_params->dir);
|
||||
memset(cmd->archive_params, 0, sizeof(*cmd->archive_params));
|
||||
}
|
||||
|
||||
@@ -73,12 +73,12 @@ 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)
|
||||
static char *_build_desc(struct dm_pool *mem, const char *line, int before)
|
||||
{
|
||||
size_t len = strlen(line) + 32;
|
||||
char *buffer;
|
||||
|
||||
if (!(buffer = pool_zalloc(mem, strlen(line) + 32))) {
|
||||
if (!(buffer = dm_pool_zalloc(mem, strlen(line) + 32))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -150,7 +150,7 @@ int archive_display(struct cmd_context *cmd, const char *vg_name)
|
||||
|
||||
int backup_init(struct cmd_context *cmd, const char *dir)
|
||||
{
|
||||
if (!(cmd->backup_params = pool_zalloc(cmd->libmem,
|
||||
if (!(cmd->backup_params = dm_pool_zalloc(cmd->libmem,
|
||||
sizeof(*cmd->archive_params)))) {
|
||||
log_error("archive_params alloc failed");
|
||||
return 0;
|
||||
@@ -160,7 +160,7 @@ int backup_init(struct cmd_context *cmd, const char *dir)
|
||||
if (!*dir)
|
||||
return 1;
|
||||
|
||||
if (!(cmd->backup_params->dir = dbg_strdup(dir))) {
|
||||
if (!(cmd->backup_params->dir = dm_strdup(dir))) {
|
||||
log_error("Couldn't copy backup directory name.");
|
||||
return 0;
|
||||
}
|
||||
@@ -171,7 +171,7 @@ int backup_init(struct cmd_context *cmd, const char *dir)
|
||||
void backup_exit(struct cmd_context *cmd)
|
||||
{
|
||||
if (cmd->backup_params->dir)
|
||||
dbg_free(cmd->backup_params->dir);
|
||||
dm_free(cmd->backup_params->dir);
|
||||
memset(cmd->backup_params, 0, sizeof(*cmd->backup_params));
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
#include "lib.h"
|
||||
#include "import-export.h"
|
||||
#include "metadata.h"
|
||||
#include "hash.h"
|
||||
#include "pool.h"
|
||||
#include "display.h"
|
||||
#include "lvm-string.h"
|
||||
#include "segtype.h"
|
||||
@@ -31,13 +29,26 @@ struct formatter;
|
||||
typedef int (*out_with_comment_fn) (struct formatter * f, const char *comment,
|
||||
const char *fmt, va_list ap);
|
||||
typedef int (*nl_fn) (struct formatter * f);
|
||||
|
||||
/*
|
||||
* Macro for formatted output.
|
||||
* out_with_comment_fn returns -1 if data didn't fit and buffer was expanded.
|
||||
* Then argument list is reset and out_with_comment_fn is called again.
|
||||
*/
|
||||
#define _out_with_comment(f, buffer, fmt, ap) \
|
||||
do { \
|
||||
va_start(ap, fmt); \
|
||||
r = f->out_with_comment(f, buffer, fmt, ap); \
|
||||
va_end(ap); \
|
||||
} while (r == -1)
|
||||
|
||||
/*
|
||||
* The first half of this file deals with
|
||||
* exporting the vg, ie. writing it to a file.
|
||||
*/
|
||||
struct formatter {
|
||||
struct pool *mem; /* pv names allocated from here */
|
||||
struct hash_table *pv_names; /* dev_name -> pv_name (eg, pv1) */
|
||||
struct dm_pool *mem; /* pv names allocated from here */
|
||||
struct dm_hash_table *pv_names; /* dev_name -> pv_name (eg, pv1) */
|
||||
|
||||
union {
|
||||
FILE *fp; /* where we're writing to */
|
||||
@@ -102,19 +113,30 @@ static int _nl_file(struct formatter *f)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _nl_raw(struct formatter *f)
|
||||
static int _extend_buffer(struct formatter *f)
|
||||
{
|
||||
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;
|
||||
log_debug("Doubling metadata output buffer to %" PRIu32,
|
||||
f->data.buf.size * 2);
|
||||
if (!(newbuf = dm_realloc(f->data.buf.start,
|
||||
f->data.buf.size * 2))) {
|
||||
log_error("Buffer reallocation failed.");
|
||||
return 0;
|
||||
}
|
||||
f->data.buf.start = newbuf;
|
||||
f->data.buf.size *= 2;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _nl_raw(struct formatter *f)
|
||||
{
|
||||
/* If metadata doesn't fit, extend buffer */
|
||||
if ((f->data.buf.used + 2 > f->data.buf.size) &&
|
||||
(!_extend_buffer(f))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*(f->data.buf.start + f->data.buf.used) = '\n';
|
||||
@@ -165,22 +187,17 @@ static int _out_with_comment_raw(struct formatter *f, const char *comment,
|
||||
const char *fmt, va_list ap)
|
||||
{
|
||||
int n;
|
||||
char *newbuf;
|
||||
|
||||
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 metadata doesn't fit, extend buffer */
|
||||
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))) {
|
||||
if (!_extend_buffer(f)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
f->data.buf.start = newbuf;
|
||||
f->data.buf.size *= 2;
|
||||
goto retry;
|
||||
return -1; /* Retry */
|
||||
}
|
||||
|
||||
f->data.buf.used += n;
|
||||
@@ -231,9 +248,7 @@ int out_size(struct formatter *f, uint64_t size, const char *fmt, ...)
|
||||
if (!_sectors_to_units(size, buffer, sizeof(buffer)))
|
||||
return 0;
|
||||
|
||||
va_start(ap, fmt);
|
||||
r = f->out_with_comment(f, buffer, fmt, ap);
|
||||
va_end(ap);
|
||||
_out_with_comment(f, buffer, fmt, ap);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -247,9 +262,7 @@ int out_hint(struct formatter *f, const char *fmt, ...)
|
||||
va_list ap;
|
||||
int r;
|
||||
|
||||
va_start(ap, fmt);
|
||||
r = f->out_with_comment(f, "# Hint only", fmt, ap);
|
||||
va_end(ap);
|
||||
_out_with_comment(f, "# Hint only", fmt, ap);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -262,9 +275,7 @@ int out_text(struct formatter *f, const char *fmt, ...)
|
||||
va_list ap;
|
||||
int r;
|
||||
|
||||
va_start(ap, fmt);
|
||||
r = f->out_with_comment(f, NULL, fmt, ap);
|
||||
va_end(ap);
|
||||
_out_with_comment(f, NULL, fmt, ap);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -347,7 +358,7 @@ static inline const char *_get_pv_name(struct formatter *f,
|
||||
struct physical_volume *pv)
|
||||
{
|
||||
return (pv) ? (const char *)
|
||||
hash_lookup(f->pv_names, dev_name(pv->dev)) : "Missing";
|
||||
dm_hash_lookup(f->pv_names, dev_name(pv->dev)) : "Missing";
|
||||
}
|
||||
|
||||
static int _print_pvs(struct formatter *f, struct volume_group *vg)
|
||||
@@ -602,12 +613,12 @@ static int _build_pv_names(struct formatter *f, struct volume_group *vg)
|
||||
struct physical_volume *pv;
|
||||
char buffer[32], *name;
|
||||
|
||||
if (!(f->mem = pool_create("text pv_names", 512))) {
|
||||
if (!(f->mem = dm_pool_create("text pv_names", 512))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(f->pv_names = hash_create(128))) {
|
||||
if (!(f->pv_names = dm_hash_create(128))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -621,12 +632,12 @@ static int _build_pv_names(struct formatter *f, struct volume_group *vg)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(name = pool_strdup(f->mem, buffer))) {
|
||||
if (!(name = dm_pool_strdup(f->mem, buffer))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!hash_insert(f->pv_names, dev_name(pv->dev), name)) {
|
||||
if (!dm_hash_insert(f->pv_names, dev_name(pv->dev), name)) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -636,10 +647,10 @@ static int _build_pv_names(struct formatter *f, struct volume_group *vg)
|
||||
|
||||
bad:
|
||||
if (f->mem)
|
||||
pool_destroy(f->mem);
|
||||
dm_pool_destroy(f->mem);
|
||||
|
||||
if (f->pv_names)
|
||||
hash_destroy(f->pv_names);
|
||||
dm_hash_destroy(f->pv_names);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -686,10 +697,10 @@ static int _text_vg_export(struct formatter *f,
|
||||
|
||||
out:
|
||||
if (f->mem)
|
||||
pool_destroy(f->mem);
|
||||
dm_pool_destroy(f->mem);
|
||||
|
||||
if (f->pv_names)
|
||||
hash_destroy(f->pv_names);
|
||||
dm_hash_destroy(f->pv_names);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -701,7 +712,7 @@ int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp)
|
||||
|
||||
_init();
|
||||
|
||||
if (!(f = dbg_malloc(sizeof(*f)))) {
|
||||
if (!(f = dm_malloc(sizeof(*f)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -716,7 +727,7 @@ int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp)
|
||||
r = _text_vg_export(f, vg, desc);
|
||||
if (r)
|
||||
r = !ferror(f->data.fp);
|
||||
dbg_free(f);
|
||||
dm_free(f);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -728,7 +739,7 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
|
||||
|
||||
_init();
|
||||
|
||||
if (!(f = dbg_malloc(sizeof(*f)))) {
|
||||
if (!(f = dm_malloc(sizeof(*f)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -736,7 +747,7 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
|
||||
memset(f, 0, sizeof(*f));
|
||||
|
||||
f->data.buf.size = 65536; /* Initial metadata limit */
|
||||
if (!(f->data.buf.start = dbg_malloc(f->data.buf.size))) {
|
||||
if (!(f->data.buf.start = dm_malloc(f->data.buf.size))) {
|
||||
log_error("text_export buffer allocation failed");
|
||||
goto out;
|
||||
}
|
||||
@@ -748,7 +759,7 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
|
||||
|
||||
if (!_text_vg_export(f, vg, desc)) {
|
||||
stack;
|
||||
dbg_free(f->data.buf.start);
|
||||
dm_free(f->data.buf.start);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -756,7 +767,7 @@ int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf)
|
||||
*buf = f->data.buf.start;
|
||||
|
||||
out:
|
||||
dbg_free(f);
|
||||
dm_free(f);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ static struct flag _vg_flags[] = {
|
||||
{LVM_WRITE, "WRITE"},
|
||||
{CLUSTERED, "CLUSTERED"},
|
||||
{SHARED, "SHARED"},
|
||||
{PRECOMMITTED, NULL},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
@@ -57,6 +58,7 @@ static struct flag _lv_flags[] = {
|
||||
{MIRRORED, NULL},
|
||||
{VIRTUAL, NULL},
|
||||
{SNAPSHOT, NULL},
|
||||
{ACTIVATE_EXCL, NULL},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
|
||||
@@ -18,9 +18,7 @@
|
||||
#include "import-export.h"
|
||||
#include "device.h"
|
||||
#include "lvm-file.h"
|
||||
#include "pool.h"
|
||||
#include "config.h"
|
||||
#include "hash.h"
|
||||
#include "display.h"
|
||||
#include "toolcontext.h"
|
||||
#include "lvm-string.h"
|
||||
@@ -45,6 +43,11 @@ static struct format_instance *_create_text_instance(const struct format_type
|
||||
*fmt, const char *vgname,
|
||||
void *context);
|
||||
|
||||
struct text_fid_context {
|
||||
char *raw_metadata_buf;
|
||||
uint32_t raw_metadata_buf_size;
|
||||
};
|
||||
|
||||
struct dir_list {
|
||||
struct list list;
|
||||
char dir[0];
|
||||
@@ -83,7 +86,7 @@ static int _lv_setup(struct format_instance *fid, struct logical_volume *lv)
|
||||
if (lv->size > max_size) {
|
||||
char *dummy = display_size(max_size, SIZE_SHORT);
|
||||
log_error("logical volumes cannot be larger than %s", dummy);
|
||||
dbg_free(dummy);
|
||||
dm_free(dummy);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
@@ -119,14 +122,14 @@ static struct mda_header *_raw_read_mda_header(const struct format_type *fmt,
|
||||
{
|
||||
struct mda_header *mdah;
|
||||
|
||||
if (!(mdah = pool_alloc(fmt->cmd->mem, MDA_HEADER_SIZE))) {
|
||||
if (!(mdah = dm_pool_alloc(fmt->cmd->mem, MDA_HEADER_SIZE))) {
|
||||
log_error("struct mda_header allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!dev_read(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, mdah)) {
|
||||
stack;
|
||||
pool_free(fmt->cmd->mem, mdah);
|
||||
dm_pool_free(fmt->cmd->mem, mdah);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -174,7 +177,7 @@ static int _raw_write_mda_header(const struct format_type *fmt,
|
||||
|
||||
if (!dev_write(dev, start_byte, MDA_HEADER_SIZE, mdah)) {
|
||||
stack;
|
||||
pool_free(fmt->cmd->mem, mdah);
|
||||
dm_pool_free(fmt->cmd->mem, mdah);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -184,17 +187,22 @@ static int _raw_write_mda_header(const struct format_type *fmt,
|
||||
static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
|
||||
struct mda_header *mdah,
|
||||
const char *vgname,
|
||||
int precommit)
|
||||
int *precommitted)
|
||||
{
|
||||
size_t len;
|
||||
char vgnamebuf[NAME_LEN + 2];
|
||||
struct raw_locn *rlocn;
|
||||
struct raw_locn *rlocn, *rlocn_precommitted;
|
||||
struct lvmcache_info *info;
|
||||
|
||||
rlocn = mdah->raw_locns; /* Slot 0 */
|
||||
rlocn_precommitted = rlocn + 1; /* Slot 1 */
|
||||
|
||||
if (precommit)
|
||||
rlocn++; /* Slot 1 */
|
||||
/* Should we use precommitted metadata? */
|
||||
if (*precommitted && rlocn_precommitted->size &&
|
||||
(rlocn_precommitted->offset != rlocn->offset)) {
|
||||
rlocn = rlocn_precommitted;
|
||||
} else
|
||||
*precommitted = 0;
|
||||
|
||||
/* FIXME Loop through rlocns two-at-a-time. List null-terminated. */
|
||||
/* FIXME Ignore if checksum incorrect!!! */
|
||||
@@ -238,6 +246,7 @@ static int _raw_holds_vgname(struct format_instance *fid,
|
||||
struct device_area *dev_area, const char *vgname)
|
||||
{
|
||||
int r = 0;
|
||||
int noprecommit = 0;
|
||||
struct mda_header *mdah;
|
||||
|
||||
if (!dev_open(dev_area->dev)) {
|
||||
@@ -250,7 +259,7 @@ static int _raw_holds_vgname(struct format_instance *fid,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_find_vg_rlocn(dev_area, mdah, vgname, 0))
|
||||
if (_find_vg_rlocn(dev_area, mdah, vgname, &noprecommit))
|
||||
r = 1;
|
||||
|
||||
if (!dev_close(dev_area->dev))
|
||||
@@ -262,7 +271,7 @@ static int _raw_holds_vgname(struct format_instance *fid,
|
||||
static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
|
||||
const char *vgname,
|
||||
struct device_area *area,
|
||||
int precommit)
|
||||
int precommitted)
|
||||
{
|
||||
struct volume_group *vg = NULL;
|
||||
struct raw_locn *rlocn;
|
||||
@@ -281,7 +290,7 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(rlocn = _find_vg_rlocn(area, mdah, vgname, precommit))) {
|
||||
if (!(rlocn = _find_vg_rlocn(area, mdah, vgname, &precommitted))) {
|
||||
log_debug("VG %s not found on %s", vgname, dev_name(area->dev));
|
||||
goto out;
|
||||
}
|
||||
@@ -306,10 +315,13 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
|
||||
goto out;
|
||||
}
|
||||
log_debug("Read %s %smetadata (%u) from %s at %" PRIu64 " size %"
|
||||
PRIu64, vg->name, precommit ? "pre-commit " : "",
|
||||
PRIu64, vg->name, precommitted ? "pre-commit " : "",
|
||||
vg->seqno, dev_name(area->dev),
|
||||
area->start + rlocn->offset, rlocn->size);
|
||||
|
||||
if (precommitted)
|
||||
vg->status |= PRECOMMITTED;
|
||||
|
||||
out:
|
||||
if (!dev_close(area->dev))
|
||||
stack;
|
||||
@@ -339,13 +351,14 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
struct metadata_area *mda)
|
||||
{
|
||||
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
|
||||
struct text_fid_context *fidtc = (struct text_fid_context *) fid->private;
|
||||
struct raw_locn *rlocn;
|
||||
struct mda_header *mdah;
|
||||
struct pv_list *pvl;
|
||||
int r = 0;
|
||||
uint32_t new_wrap = 0, old_wrap = 0;
|
||||
char *buf = NULL;
|
||||
int found = 0;
|
||||
int noprecommit = 0;
|
||||
|
||||
/* Ignore any mda on a PV outside the VG. vgsplit relies on this */
|
||||
list_iterate_items(pvl, &vg->pvs) {
|
||||
@@ -368,14 +381,18 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
goto out;
|
||||
}
|
||||
|
||||
rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, 0);
|
||||
rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit);
|
||||
mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah);
|
||||
|
||||
if (!(mdac->rlocn.size = text_vg_export_raw(vg, "", &buf))) {
|
||||
if (!fidtc->raw_metadata_buf &&
|
||||
!(fidtc->raw_metadata_buf_size =
|
||||
text_vg_export_raw(vg, "", &fidtc->raw_metadata_buf))) {
|
||||
log_error("VG %s metadata writing failed", vg->name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
mdac->rlocn.size = fidtc->raw_metadata_buf_size;
|
||||
|
||||
if (mdac->rlocn.offset + mdac->rlocn.size > mdah->size)
|
||||
new_wrap = (mdac->rlocn.offset + mdac->rlocn.size) - mdah->size;
|
||||
|
||||
@@ -398,7 +415,8 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
|
||||
/* Write text out, circularly */
|
||||
if (!dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
|
||||
(size_t) (mdac->rlocn.size - new_wrap), buf)) {
|
||||
(size_t) (mdac->rlocn.size - new_wrap),
|
||||
fidtc->raw_metadata_buf)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
@@ -411,18 +429,20 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
if (!dev_write(mdac->area.dev,
|
||||
mdac->area.start + MDA_HEADER_SIZE,
|
||||
(size_t) new_wrap,
|
||||
buf + mdac->rlocn.size - new_wrap)) {
|
||||
fidtc->raw_metadata_buf +
|
||||
mdac->rlocn.size - new_wrap)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
mdac->rlocn.checksum = calc_crc(INITIAL_CRC, buf,
|
||||
mdac->rlocn.checksum = calc_crc(INITIAL_CRC, fidtc->raw_metadata_buf,
|
||||
(uint32_t) (mdac->rlocn.size -
|
||||
new_wrap));
|
||||
if (new_wrap)
|
||||
mdac->rlocn.checksum = calc_crc(mdac->rlocn.checksum,
|
||||
buf + mdac->rlocn.size -
|
||||
fidtc->raw_metadata_buf +
|
||||
mdac->rlocn.size -
|
||||
new_wrap, new_wrap);
|
||||
|
||||
r = 1;
|
||||
@@ -431,8 +451,6 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
if (!r && !dev_close(mdac->area.dev))
|
||||
stack;
|
||||
|
||||
if (buf)
|
||||
dbg_free(buf);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -442,11 +460,13 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
|
||||
int precommit)
|
||||
{
|
||||
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
|
||||
struct text_fid_context *fidtc = (struct text_fid_context *) fid->private;
|
||||
struct mda_header *mdah;
|
||||
struct raw_locn *rlocn;
|
||||
struct pv_list *pvl;
|
||||
int r = 0;
|
||||
int found = 0;
|
||||
int noprecommit = 0;
|
||||
|
||||
/* Ignore any mda on a PV outside the VG. vgsplit relies on this */
|
||||
list_iterate_items(pvl, &vg->pvs) {
|
||||
@@ -464,23 +484,41 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, 0))) {
|
||||
if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit))) {
|
||||
mdah->raw_locns[0].offset = 0;
|
||||
mdah->raw_locns[0].size = 0;
|
||||
mdah->raw_locns[0].checksum = 0;
|
||||
mdah->raw_locns[1].offset = 0;
|
||||
mdah->raw_locns[1].size = 0;
|
||||
mdah->raw_locns[1].checksum = 0;
|
||||
mdah->raw_locns[2].offset = 0;
|
||||
mdah->raw_locns[2].size = 0;
|
||||
mdah->raw_locns[2].checksum = 0;
|
||||
rlocn = &mdah->raw_locns[0];
|
||||
}
|
||||
|
||||
if (precommit)
|
||||
rlocn++;
|
||||
else {
|
||||
/* If not precommitting, wipe the precommitted rlocn */
|
||||
mdah->raw_locns[1].offset = 0;
|
||||
mdah->raw_locns[1].size = 0;
|
||||
mdah->raw_locns[1].checksum = 0;
|
||||
}
|
||||
|
||||
rlocn->offset = mdac->rlocn.offset;
|
||||
rlocn->size = mdac->rlocn.size;
|
||||
rlocn->checksum = mdac->rlocn.checksum;
|
||||
/* Is there new metadata to commit? */
|
||||
if (mdac->rlocn.size) {
|
||||
rlocn->offset = mdac->rlocn.offset;
|
||||
rlocn->size = mdac->rlocn.size;
|
||||
rlocn->checksum = mdac->rlocn.checksum;
|
||||
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);
|
||||
} else
|
||||
log_debug("Wiping pre-committed %s metadata from %s "
|
||||
"header at %" PRIu64, vg->name,
|
||||
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");
|
||||
@@ -490,8 +528,14 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
if (!precommit && !dev_close(mdac->area.dev))
|
||||
stack;
|
||||
if (!precommit) {
|
||||
if (!dev_close(mdac->area.dev))
|
||||
stack;
|
||||
if (fidtc->raw_metadata_buf) {
|
||||
dm_free(fidtc->raw_metadata_buf);
|
||||
fidtc->raw_metadata_buf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -528,10 +572,9 @@ static int _vg_revert_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
if (!found)
|
||||
return 1;
|
||||
|
||||
if (!dev_close(mdac->area.dev))
|
||||
stack;
|
||||
|
||||
return 1;
|
||||
/* Wipe pre-committed metadata */
|
||||
mdac->rlocn.size = 0;
|
||||
return _vg_commit_raw_rlocn(fid, vg, mda, 0);
|
||||
}
|
||||
|
||||
static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
@@ -541,6 +584,7 @@ static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
struct mda_header *mdah;
|
||||
struct raw_locn *rlocn;
|
||||
int r = 0;
|
||||
int noprecommit = 0;
|
||||
|
||||
if (!dev_open(mdac->area.dev)) {
|
||||
stack;
|
||||
@@ -552,7 +596,7 @@ static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, 0))) {
|
||||
if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit))) {
|
||||
rlocn = &mdah->raw_locns[0];
|
||||
mdah->raw_locns[1].offset = 0;
|
||||
}
|
||||
@@ -595,7 +639,7 @@ static struct volume_group *_vg_read_file_name(struct format_instance *fid,
|
||||
* check that it contains the correct volume group.
|
||||
*/
|
||||
if (vgname && strcmp(vgname, vg->name)) {
|
||||
pool_free(fid->fmt->cmd->mem, vg);
|
||||
dm_pool_free(fid->fmt->cmd->mem, vg);
|
||||
log_err("'%s' does not contain volume group '%s'.",
|
||||
read_path, vgname);
|
||||
return NULL;
|
||||
@@ -619,8 +663,14 @@ static struct volume_group *_vg_read_precommit_file(struct format_instance *fid,
|
||||
struct metadata_area *mda)
|
||||
{
|
||||
struct text_context *tc = (struct text_context *) mda->metadata_locn;
|
||||
struct volume_group *vg;
|
||||
|
||||
return _vg_read_file_name(fid, vgname, tc->path_edit);
|
||||
if ((vg = _vg_read_file_name(fid, vgname, tc->path_edit)))
|
||||
vg->status |= PRECOMMITTED;
|
||||
else
|
||||
vg = _vg_read_file_name(fid, vgname, tc->path_live);
|
||||
|
||||
return vg;
|
||||
}
|
||||
|
||||
static int _vg_write_file(struct format_instance *fid, struct volume_group *vg,
|
||||
@@ -666,7 +716,7 @@ static int _vg_write_file(struct format_instance *fid, struct volume_group *vg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fsync(fd)) {
|
||||
if (fsync(fd) && (errno != EROFS) && (errno != EINVAL)) {
|
||||
log_sys_error("fsync", tc->path_edit);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
@@ -1160,7 +1210,7 @@ static int _add_raw(struct list *raw_list, struct device_area *dev_area)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(rl = dbg_malloc(sizeof(struct raw_list)))) {
|
||||
if (!(rl = dm_malloc(sizeof(struct raw_list)))) {
|
||||
log_error("_add_raw allocation failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -1234,11 +1284,11 @@ static int _pv_read(const struct format_type *fmt, const char *pv_name,
|
||||
/* Add copy of mdas to supplied list */
|
||||
list_iterate_items(mda, &info->mdas) {
|
||||
mdac = (struct mda_context *) mda->metadata_locn;
|
||||
if (!(mda_new = pool_alloc(fmt->cmd->mem, sizeof(*mda_new)))) {
|
||||
if (!(mda_new = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda_new)))) {
|
||||
log_error("metadata_area allocation failed");
|
||||
return 0;
|
||||
}
|
||||
if (!(mdac_new = pool_alloc(fmt->cmd->mem, sizeof(*mdac_new)))) {
|
||||
if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem, sizeof(*mdac_new)))) {
|
||||
log_error("metadata_area allocation failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -1262,7 +1312,7 @@ static void _free_dirs(struct list *dir_list)
|
||||
|
||||
list_iterate_safe(dl, tmp, dir_list) {
|
||||
list_del(dl);
|
||||
dbg_free(dl);
|
||||
dm_free(dl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1272,7 +1322,7 @@ static void _free_raws(struct list *raw_list)
|
||||
|
||||
list_iterate_safe(rl, tmp, raw_list) {
|
||||
list_del(rl);
|
||||
dbg_free(rl);
|
||||
dm_free(rl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1281,10 +1331,10 @@ static void _destroy(const struct format_type *fmt)
|
||||
if (fmt->private) {
|
||||
_free_dirs(&((struct mda_lists *) fmt->private)->dirs);
|
||||
_free_raws(&((struct mda_lists *) fmt->private)->raws);
|
||||
dbg_free(fmt->private);
|
||||
dm_free(fmt->private);
|
||||
}
|
||||
|
||||
dbg_free((void *) fmt);
|
||||
dm_free((void *) fmt);
|
||||
}
|
||||
|
||||
static struct metadata_area_ops _metadata_text_file_ops = {
|
||||
@@ -1361,13 +1411,13 @@ static int _pv_setup(const struct format_type *fmt,
|
||||
if (found)
|
||||
continue;
|
||||
|
||||
if (!(mda_new = pool_alloc(fmt->cmd->mem,
|
||||
if (!(mda_new = dm_pool_alloc(fmt->cmd->mem,
|
||||
sizeof(*mda_new)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(mdac_new = pool_alloc(fmt->cmd->mem,
|
||||
if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem,
|
||||
sizeof(*mdac_new)))) {
|
||||
stack;
|
||||
return 0;
|
||||
@@ -1403,6 +1453,7 @@ static struct format_instance *_create_text_instance(const struct format_type
|
||||
void *context)
|
||||
{
|
||||
struct format_instance *fid;
|
||||
struct text_fid_context *fidtc;
|
||||
struct metadata_area *mda, *mda_new;
|
||||
struct mda_context *mdac, *mdac_new;
|
||||
struct dir_list *dl;
|
||||
@@ -1412,17 +1463,25 @@ static struct format_instance *_create_text_instance(const struct format_type
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
struct lvmcache_info *info;
|
||||
|
||||
if (!(fid = pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
|
||||
if (!(fid = dm_pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
|
||||
log_error("Couldn't allocate format instance object.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fid->fmt = fmt;
|
||||
if (!(fidtc = (struct text_fid_context *)
|
||||
dm_pool_zalloc(fmt->cmd->mem,sizeof(*fidtc)))) {
|
||||
log_error("Couldn't allocate text_fid_context.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fidtc->raw_metadata_buf = NULL;
|
||||
fid->private = (void *) fidtc;
|
||||
|
||||
fid->fmt = fmt;
|
||||
list_init(&fid->metadata_areas);
|
||||
|
||||
if (!vgname) {
|
||||
if (!(mda = pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -1441,7 +1500,7 @@ static struct format_instance *_create_text_instance(const struct format_type
|
||||
}
|
||||
|
||||
context = create_text_context(fmt->cmd, path, NULL);
|
||||
if (!(mda = pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -1457,12 +1516,12 @@ static struct format_instance *_create_text_instance(const struct format_type
|
||||
if (!_raw_holds_vgname(fid, &rl->dev_area, vgname))
|
||||
continue;
|
||||
|
||||
if (!(mda = pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(mdac = pool_alloc(fmt->cmd->mem, sizeof(*mdac)))) {
|
||||
if (!(mdac = dm_pool_alloc(fmt->cmd->mem, sizeof(*mdac)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -1487,13 +1546,13 @@ static struct format_instance *_create_text_instance(const struct format_type
|
||||
(struct mda_context *) mda->metadata_locn;
|
||||
|
||||
/* FIXME Check it holds this VG */
|
||||
if (!(mda_new = pool_alloc(fmt->cmd->mem,
|
||||
if (!(mda_new = dm_pool_alloc(fmt->cmd->mem,
|
||||
sizeof(*mda_new)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(mdac_new = pool_alloc(fmt->cmd->mem,
|
||||
if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem,
|
||||
sizeof(*mdac_new)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
@@ -1525,17 +1584,17 @@ void *create_text_context(struct cmd_context *cmd, const char *path,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(tc = pool_alloc(cmd->mem, sizeof(*tc)))) {
|
||||
if (!(tc = dm_pool_alloc(cmd->mem, sizeof(*tc)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(tc->path_live = pool_strdup(cmd->mem, path))) {
|
||||
if (!(tc->path_live = dm_pool_strdup(cmd->mem, path))) {
|
||||
stack;
|
||||
goto no_mem;
|
||||
}
|
||||
|
||||
if (!(tc->path_edit = pool_alloc(cmd->mem, strlen(path) + 5))) {
|
||||
if (!(tc->path_edit = dm_pool_alloc(cmd->mem, strlen(path) + 5))) {
|
||||
stack;
|
||||
goto no_mem;
|
||||
}
|
||||
@@ -1544,7 +1603,7 @@ void *create_text_context(struct cmd_context *cmd, const char *path,
|
||||
if (!desc)
|
||||
desc = "";
|
||||
|
||||
if (!(tc->desc = pool_strdup(cmd->mem, desc))) {
|
||||
if (!(tc->desc = dm_pool_strdup(cmd->mem, desc))) {
|
||||
stack;
|
||||
goto no_mem;
|
||||
}
|
||||
@@ -1552,7 +1611,7 @@ void *create_text_context(struct cmd_context *cmd, const char *path,
|
||||
return (void *) tc;
|
||||
|
||||
no_mem:
|
||||
pool_free(cmd->mem, tc);
|
||||
dm_pool_free(cmd->mem, tc);
|
||||
|
||||
log_err("Couldn't allocate text format context object.");
|
||||
return NULL;
|
||||
@@ -1575,7 +1634,7 @@ static int _add_dir(const char *dir, struct list *dir_list)
|
||||
struct dir_list *dl;
|
||||
|
||||
if (create_dir(dir)) {
|
||||
if (!(dl = dbg_malloc(sizeof(struct list) + strlen(dir) + 1))) {
|
||||
if (!(dl = dm_malloc(sizeof(struct list) + strlen(dir) + 1))) {
|
||||
log_error("_add_dir allocation failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -1647,7 +1706,7 @@ struct format_type *create_text_format(struct cmd_context *cmd)
|
||||
struct config_value *cv;
|
||||
struct mda_lists *mda_lists;
|
||||
|
||||
if (!(fmt = dbg_malloc(sizeof(*fmt)))) {
|
||||
if (!(fmt = dm_malloc(sizeof(*fmt)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -1657,9 +1716,9 @@ struct format_type *create_text_format(struct cmd_context *cmd)
|
||||
fmt->name = FMT_TEXT_NAME;
|
||||
fmt->alias = FMT_TEXT_ALIAS;
|
||||
fmt->features = FMT_SEGMENTS | FMT_MDAS | FMT_TAGS | FMT_PRECOMMIT |
|
||||
FMT_UNLIMITED_VOLS;
|
||||
FMT_UNLIMITED_VOLS | FMT_RESIZE_PV;
|
||||
|
||||
if (!(mda_lists = dbg_malloc(sizeof(struct mda_lists)))) {
|
||||
if (!(mda_lists = dm_malloc(sizeof(struct mda_lists)))) {
|
||||
log_error("Failed to allocate dir_list");
|
||||
return NULL;
|
||||
}
|
||||
@@ -1710,6 +1769,6 @@ struct format_type *create_text_format(struct cmd_context *cmd)
|
||||
err:
|
||||
_free_dirs(&mda_lists->dirs);
|
||||
|
||||
dbg_free(fmt);
|
||||
dm_free(fmt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
#include "lvm-types.h"
|
||||
#include "metadata.h"
|
||||
#include "pool.h"
|
||||
|
||||
/*
|
||||
* Archives a vg config. 'retain_days' is the minimum number of
|
||||
@@ -47,11 +46,11 @@ struct labeller *text_labeller_create(const struct format_type *fmt);
|
||||
|
||||
int pvhdr_read(struct device *dev, char *buf);
|
||||
|
||||
int add_da(const struct format_type *fmt, struct pool *mem, struct list *das,
|
||||
int add_da(const struct format_type *fmt, struct dm_pool *mem, struct list *das,
|
||||
uint64_t start, uint64_t size);
|
||||
void del_das(struct list *das);
|
||||
|
||||
int add_mda(const struct format_type *fmt, struct pool *mem, struct list *mdas,
|
||||
int add_mda(const struct format_type *fmt, struct dm_pool *mem, struct list *mdas,
|
||||
struct device *dev, uint64_t start, uint64_t size);
|
||||
void del_mdas(struct list *mdas);
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "config.h"
|
||||
#include "lvm-types.h"
|
||||
#include "metadata.h"
|
||||
#include "pool.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -46,7 +45,7 @@ struct text_vg_version_ops {
|
||||
int (*check_version) (struct config_tree * cf);
|
||||
struct volume_group *(*read_vg) (struct format_instance * fid,
|
||||
struct config_tree * cf);
|
||||
void (*read_desc) (struct pool * mem, struct config_tree * cf,
|
||||
void (*read_desc) (struct dm_pool * mem, struct config_tree * cf,
|
||||
time_t *when, char **desc);
|
||||
};
|
||||
|
||||
@@ -56,7 +55,7 @@ int print_flags(uint32_t status, int type, char *buffer, size_t size);
|
||||
int read_flags(uint32_t *status, int type, struct config_value *cv);
|
||||
|
||||
int print_tags(struct list *tags, char *buffer, size_t size);
|
||||
int read_tags(struct pool *mem, struct list *tags, struct config_value *cv);
|
||||
int read_tags(struct dm_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);
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
#include "lib.h"
|
||||
#include "metadata.h"
|
||||
#include "import-export.h"
|
||||
#include "pool.h"
|
||||
#include "display.h"
|
||||
#include "hash.h"
|
||||
#include "toolcontext.h"
|
||||
#include "lvmcache.h"
|
||||
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
#include "lib.h"
|
||||
#include "metadata.h"
|
||||
#include "import-export.h"
|
||||
#include "pool.h"
|
||||
#include "display.h"
|
||||
#include "hash.h"
|
||||
#include "toolcontext.h"
|
||||
#include "lvmcache.h"
|
||||
#include "lv_alloc.h"
|
||||
@@ -26,10 +24,10 @@
|
||||
#include "segtype.h"
|
||||
#include "text_import.h"
|
||||
|
||||
typedef int (*section_fn) (struct format_instance * fid, struct pool * mem,
|
||||
typedef int (*section_fn) (struct format_instance * fid, struct dm_pool * mem,
|
||||
struct volume_group * vg, struct config_node * pvn,
|
||||
struct config_node * vgn,
|
||||
struct hash_table * pv_hash);
|
||||
struct dm_hash_table * pv_hash);
|
||||
|
||||
#define _read_int32(root, path, result) \
|
||||
get_config_uint32(root, path, (uint32_t *) result)
|
||||
@@ -111,16 +109,16 @@ static int _read_id(struct id *id, struct config_node *cn, const char *path)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _read_pv(struct format_instance *fid, struct pool *mem,
|
||||
static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
|
||||
struct volume_group *vg, struct config_node *pvn,
|
||||
struct config_node *vgn, struct hash_table *pv_hash)
|
||||
struct config_node *vgn, struct dm_hash_table *pv_hash)
|
||||
{
|
||||
struct physical_volume *pv;
|
||||
struct pv_list *pvl;
|
||||
struct config_node *cn;
|
||||
|
||||
if (!(pvl = pool_zalloc(mem, sizeof(*pvl))) ||
|
||||
!(pvl->pv = pool_zalloc(mem, sizeof(*pvl->pv)))) {
|
||||
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl))) ||
|
||||
!(pvl->pv = dm_pool_zalloc(mem, sizeof(*pvl->pv)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -131,7 +129,7 @@ static int _read_pv(struct format_instance *fid, struct pool *mem,
|
||||
* Add the pv to the pv hash for quick lookup when we read
|
||||
* the lv segments.
|
||||
*/
|
||||
if (!hash_insert(pv_hash, pvn->key, pv)) {
|
||||
if (!dm_hash_insert(pv_hash, pvn->key, pv)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -164,7 +162,7 @@ static int _read_pv(struct format_instance *fid, struct pool *mem,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(pv->vg_name = pool_strdup(mem, vg->name))) {
|
||||
if (!(pv->vg_name = dm_pool_strdup(mem, vg->name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -236,9 +234,9 @@ static void _insert_segment(struct logical_volume *lv, struct lv_segment *seg)
|
||||
list_add(&lv->segments, &seg->list);
|
||||
}
|
||||
|
||||
static int _read_segment(struct pool *mem, struct volume_group *vg,
|
||||
static int _read_segment(struct dm_pool *mem, struct volume_group *vg,
|
||||
struct logical_volume *lv, struct config_node *sn,
|
||||
struct hash_table *pv_hash)
|
||||
struct dm_hash_table *pv_hash)
|
||||
{
|
||||
uint32_t area_count = 0u;
|
||||
struct lv_segment *seg;
|
||||
@@ -323,7 +321,7 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
|
||||
}
|
||||
|
||||
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 dm_hash_table *pv_hash,
|
||||
uint32_t flags)
|
||||
{
|
||||
unsigned int s;
|
||||
@@ -359,7 +357,7 @@ int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
|
||||
}
|
||||
|
||||
/* FIXME Cope if LV not yet read in */
|
||||
if ((pv = hash_lookup(pv_hash, cv->v.str))) {
|
||||
if ((pv = dm_hash_lookup(pv_hash, cv->v.str))) {
|
||||
if (!set_lv_segment_area_pv(seg, s, pv, cv->next->v.i)) {
|
||||
stack;
|
||||
return 0;
|
||||
@@ -389,9 +387,9 @@ int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _read_segments(struct pool *mem, struct volume_group *vg,
|
||||
static int _read_segments(struct dm_pool *mem, struct volume_group *vg,
|
||||
struct logical_volume *lv, struct config_node *lvn,
|
||||
struct hash_table *pv_hash)
|
||||
struct dm_hash_table *pv_hash)
|
||||
{
|
||||
struct config_node *sn;
|
||||
int count = 0, seg_count;
|
||||
@@ -430,7 +428,7 @@ static int _read_segments(struct pool *mem, struct volume_group *vg,
|
||||
/*
|
||||
* Check there are no gaps or overlaps in the lv.
|
||||
*/
|
||||
if (!check_lv_segments(lv)) {
|
||||
if (!check_lv_segments(lv, 0)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -446,23 +444,23 @@ static int _read_segments(struct pool *mem, struct volume_group *vg,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _read_lvnames(struct format_instance *fid, struct pool *mem,
|
||||
static int _read_lvnames(struct format_instance *fid, struct dm_pool *mem,
|
||||
struct volume_group *vg, struct config_node *lvn,
|
||||
struct config_node *vgn, struct hash_table *pv_hash)
|
||||
struct config_node *vgn, struct dm_hash_table *pv_hash)
|
||||
{
|
||||
struct logical_volume *lv;
|
||||
struct lv_list *lvl;
|
||||
struct config_node *cn;
|
||||
|
||||
if (!(lvl = pool_zalloc(mem, sizeof(*lvl))) ||
|
||||
!(lvl->lv = pool_zalloc(mem, sizeof(*lvl->lv)))) {
|
||||
if (!(lvl = dm_pool_zalloc(mem, sizeof(*lvl))) ||
|
||||
!(lvl->lv = dm_pool_zalloc(mem, sizeof(*lvl->lv)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
lv = lvl->lv;
|
||||
|
||||
if (!(lv->name = pool_strdup(mem, lvn->key))) {
|
||||
if (!(lv->name = dm_pool_strdup(mem, lvn->key))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -521,9 +519,9 @@ static int _read_lvnames(struct format_instance *fid, struct pool *mem,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _read_lvsegs(struct format_instance *fid, struct pool *mem,
|
||||
static int _read_lvsegs(struct format_instance *fid, struct dm_pool *mem,
|
||||
struct volume_group *vg, struct config_node *lvn,
|
||||
struct config_node *vgn, struct hash_table *pv_hash)
|
||||
struct config_node *vgn, struct dm_hash_table *pv_hash)
|
||||
{
|
||||
struct logical_volume *lv;
|
||||
struct lv_list *lvl;
|
||||
@@ -586,9 +584,9 @@ static int _read_lvsegs(struct format_instance *fid, struct pool *mem,
|
||||
|
||||
static int _read_sections(struct format_instance *fid,
|
||||
const char *section, section_fn fn,
|
||||
struct pool *mem,
|
||||
struct dm_pool *mem,
|
||||
struct volume_group *vg, struct config_node *vgn,
|
||||
struct hash_table *pv_hash, int optional)
|
||||
struct dm_hash_table *pv_hash, int optional)
|
||||
{
|
||||
struct config_node *n;
|
||||
|
||||
@@ -616,8 +614,8 @@ static struct volume_group *_read_vg(struct format_instance *fid,
|
||||
{
|
||||
struct config_node *vgn, *cn;
|
||||
struct volume_group *vg;
|
||||
struct hash_table *pv_hash = NULL;
|
||||
struct pool *mem = fid->fmt->cmd->mem;
|
||||
struct dm_hash_table *pv_hash = NULL;
|
||||
struct dm_pool *mem = fid->fmt->cmd->mem;
|
||||
|
||||
/* skip any top-level values */
|
||||
for (vgn = cft->root; (vgn && vgn->v); vgn = vgn->sib) ;
|
||||
@@ -627,7 +625,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(vg = pool_zalloc(mem, sizeof(*vg)))) {
|
||||
if (!(vg = dm_pool_zalloc(mem, sizeof(*vg)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -637,12 +635,12 @@ static struct volume_group *_read_vg(struct format_instance *fid,
|
||||
/* eg Set to instance of fmt1 here if reading a format1 backup? */
|
||||
vg->fid = fid;
|
||||
|
||||
if (!(vg->name = pool_strdup(mem, vgn->key))) {
|
||||
if (!(vg->name = dm_pool_strdup(mem, vgn->key))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(vg->system_id = pool_zalloc(mem, NAME_LEN))) {
|
||||
if (!(vg->system_id = dm_pool_zalloc(mem, NAME_LEN))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -722,7 +720,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
|
||||
* The pv hash memoises the pv section names -> pv
|
||||
* structures.
|
||||
*/
|
||||
if (!(pv_hash = hash_create(32))) {
|
||||
if (!(pv_hash = dm_hash_create(32))) {
|
||||
log_error("Couldn't create hash table.");
|
||||
goto bad;
|
||||
}
|
||||
@@ -759,7 +757,13 @@ static struct volume_group *_read_vg(struct format_instance *fid,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
hash_destroy(pv_hash);
|
||||
if (!fixup_imported_mirrors(vg)) {
|
||||
log_error("Failed to fixup mirror pointers after import for "
|
||||
"volume group %s.", vg->name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
dm_hash_destroy(pv_hash);
|
||||
|
||||
if (vg->status & PARTIAL_VG) {
|
||||
vg->status &= ~LVM_WRITE;
|
||||
@@ -773,13 +777,13 @@ static struct volume_group *_read_vg(struct format_instance *fid,
|
||||
|
||||
bad:
|
||||
if (pv_hash)
|
||||
hash_destroy(pv_hash);
|
||||
dm_hash_destroy(pv_hash);
|
||||
|
||||
pool_free(mem, vg);
|
||||
dm_pool_free(mem, vg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void _read_desc(struct pool *mem,
|
||||
static void _read_desc(struct dm_pool *mem,
|
||||
struct config_tree *cft, time_t *when, char **desc)
|
||||
{
|
||||
const char *d;
|
||||
@@ -788,7 +792,7 @@ static void _read_desc(struct pool *mem,
|
||||
log_suppress(1);
|
||||
d = find_config_str(cft->root, "description", "");
|
||||
log_suppress(0);
|
||||
*desc = pool_strdup(mem, d);
|
||||
*desc = dm_pool_strdup(mem, d);
|
||||
|
||||
get_config_uint32(cft->root, "creation_time", &u);
|
||||
*when = u;
|
||||
|
||||
@@ -37,6 +37,8 @@ struct data_area_list {
|
||||
/* On disk */
|
||||
struct pv_header {
|
||||
uint8_t pv_uuid[ID_LEN];
|
||||
|
||||
/* This size can be overridden if PV belongs to a VG */
|
||||
uint64_t device_size_xl; /* Bytes */
|
||||
|
||||
/* NULL-terminated list of data areas followed by */
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "lib.h"
|
||||
#include "metadata.h"
|
||||
#include "import-export.h"
|
||||
#include "pool.h"
|
||||
#include "str_list.h"
|
||||
#include "lvm-string.h"
|
||||
|
||||
@@ -53,7 +52,7 @@ int print_tags(struct list *tags, char *buffer, size_t size)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int read_tags(struct pool *mem, struct list *tags, struct config_value *cv)
|
||||
int read_tags(struct dm_pool *mem, struct list *tags, struct config_value *cv)
|
||||
{
|
||||
if (cv->type == CFG_EMPTY_ARRAY)
|
||||
return 1;
|
||||
@@ -64,7 +63,7 @@ int read_tags(struct pool *mem, struct list *tags, struct config_value *cv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!str_list_add(mem, tags, pool_strdup(mem, cv->v.str))) {
|
||||
if (!str_list_add(mem, tags, dm_pool_strdup(mem, cv->v.str))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ struct lv_segment;
|
||||
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 dm_hash_table *pv_hash,
|
||||
uint32_t flags);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -86,18 +86,18 @@ static int _write(struct label *label, char *buf)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int add_da(const struct format_type *fmt, struct pool *mem, struct list *das,
|
||||
int add_da(const struct format_type *fmt, struct dm_pool *mem, struct list *das,
|
||||
uint64_t start, uint64_t size)
|
||||
{
|
||||
struct data_area_list *dal;
|
||||
|
||||
if (!mem) {
|
||||
if (!(dal = dbg_malloc(sizeof(*dal)))) {
|
||||
if (!(dal = dm_malloc(sizeof(*dal)))) {
|
||||
log_error("struct data_area_list allocation failed");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (!(dal = pool_alloc(mem, sizeof(*dal)))) {
|
||||
if (!(dal = dm_pool_alloc(mem, sizeof(*dal)))) {
|
||||
log_error("struct data_area_list allocation failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -119,11 +119,11 @@ void del_das(struct list *das)
|
||||
list_iterate_safe(dah, tmp, das) {
|
||||
da = list_item(dah, struct data_area_list);
|
||||
list_del(&da->list);
|
||||
dbg_free(da);
|
||||
dm_free(da);
|
||||
}
|
||||
}
|
||||
|
||||
int add_mda(const struct format_type *fmt, struct pool *mem, struct list *mdas,
|
||||
int add_mda(const struct format_type *fmt, struct dm_pool *mem, struct list *mdas,
|
||||
struct device *dev, uint64_t start, uint64_t size)
|
||||
{
|
||||
/* FIXME List size restricted by pv_header SECTOR_SIZE */
|
||||
@@ -132,23 +132,23 @@ int add_mda(const struct format_type *fmt, struct pool *mem, struct list *mdas,
|
||||
struct mda_context *mdac;
|
||||
|
||||
if (!mem) {
|
||||
if (!(mdal = dbg_malloc(sizeof(struct metadata_area)))) {
|
||||
if (!(mdal = dm_malloc(sizeof(struct metadata_area)))) {
|
||||
log_error("struct mda_list allocation failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(mdac = dbg_malloc(sizeof(struct mda_context)))) {
|
||||
if (!(mdac = dm_malloc(sizeof(struct mda_context)))) {
|
||||
log_error("struct mda_context allocation failed");
|
||||
dbg_free(mdal);
|
||||
dm_free(mdal);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (!(mdal = pool_alloc(mem, sizeof(struct metadata_area)))) {
|
||||
if (!(mdal = dm_pool_alloc(mem, sizeof(struct metadata_area)))) {
|
||||
log_error("struct mda_list allocation failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(mdac = pool_alloc(mem, sizeof(struct mda_context)))) {
|
||||
if (!(mdac = dm_pool_alloc(mem, sizeof(struct mda_context)))) {
|
||||
log_error("struct mda_context allocation failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -173,9 +173,9 @@ void del_mdas(struct list *mdas)
|
||||
|
||||
list_iterate_safe(mdah, tmp, mdas) {
|
||||
mda = list_item(mdah, struct metadata_area);
|
||||
dbg_free(mda->metadata_locn);
|
||||
dm_free(mda->metadata_locn);
|
||||
list_del(&mda->list);
|
||||
dbg_free(mda);
|
||||
dm_free(mda);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ static void _destroy_label(struct labeller *l, struct label *label)
|
||||
|
||||
static void _destroy(struct labeller *l)
|
||||
{
|
||||
dbg_free(l);
|
||||
dm_free(l);
|
||||
}
|
||||
|
||||
struct label_ops _text_ops = {
|
||||
@@ -272,7 +272,7 @@ struct labeller *text_labeller_create(const struct format_type *fmt)
|
||||
{
|
||||
struct labeller *l;
|
||||
|
||||
if (!(l = dbg_malloc(sizeof(*l)))) {
|
||||
if (!(l = dm_malloc(sizeof(*l)))) {
|
||||
log_err("Couldn't allocate labeller object.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
#include "lib.h"
|
||||
#include "label.h"
|
||||
#include "list.h"
|
||||
#include "crc.h"
|
||||
#include "xlate.h"
|
||||
#include "lvmcache.h"
|
||||
@@ -46,7 +45,7 @@ static struct labeller_i *_alloc_li(const char *name, struct labeller *l)
|
||||
|
||||
len = sizeof(*li) + strlen(name) + 1;
|
||||
|
||||
if (!(li = dbg_malloc(len))) {
|
||||
if (!(li = dm_malloc(len))) {
|
||||
log_error("Couldn't allocate memory for labeller list object.");
|
||||
return NULL;
|
||||
}
|
||||
@@ -59,7 +58,7 @@ static struct labeller_i *_alloc_li(const char *name, struct labeller *l)
|
||||
|
||||
static void _free_li(struct labeller_i *li)
|
||||
{
|
||||
dbg_free(li);
|
||||
dm_free(li);
|
||||
}
|
||||
|
||||
int label_init(void)
|
||||
@@ -353,14 +352,14 @@ int label_verify(struct device *dev)
|
||||
void label_destroy(struct label *label)
|
||||
{
|
||||
label->labeller->ops->destroy_label(label->labeller, label);
|
||||
dbg_free(label);
|
||||
dm_free(label);
|
||||
}
|
||||
|
||||
struct label *label_create(struct labeller *labeller)
|
||||
{
|
||||
struct label *label;
|
||||
|
||||
if (!(label = dbg_malloc(sizeof(*label)))) {
|
||||
if (!(label = dm_malloc(sizeof(*label)))) {
|
||||
log_error("label allocaction failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ static int _send_request(char *inbuf, int inlen, char **retbuf)
|
||||
|
||||
/* Allocate buffer */
|
||||
buflen = len + outheader->arglen;
|
||||
*retbuf = dbg_malloc(buflen);
|
||||
*retbuf = dm_malloc(buflen);
|
||||
if (!*retbuf) {
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
@@ -236,7 +236,7 @@ static int _cluster_request(char cmd, const char *node, void *data, int len,
|
||||
* With an extra pair of INTs on the front to sanity
|
||||
* check the pointer when we are given it back to free
|
||||
*/
|
||||
outptr = dbg_malloc(sizeof(lvm_response_t) * num_responses +
|
||||
outptr = dm_malloc(sizeof(lvm_response_t) * num_responses +
|
||||
sizeof(int) * 2);
|
||||
if (!outptr) {
|
||||
errno = ENOMEM;
|
||||
@@ -259,12 +259,12 @@ static int _cluster_request(char cmd, const char *node, void *data, int len,
|
||||
rarray[i].status = *(int *) inptr;
|
||||
inptr += sizeof(int);
|
||||
|
||||
rarray[i].response = dbg_malloc(strlen(inptr) + 1);
|
||||
rarray[i].response = dm_malloc(strlen(inptr) + 1);
|
||||
if (rarray[i].response == NULL) {
|
||||
/* Free up everything else and return error */
|
||||
int j;
|
||||
for (j = 0; j < i; j++)
|
||||
dbg_free(rarray[i].response);
|
||||
dm_free(rarray[i].response);
|
||||
free(outptr);
|
||||
errno = ENOMEM;
|
||||
status = -1;
|
||||
@@ -281,7 +281,7 @@ static int _cluster_request(char cmd, const char *node, void *data, int len,
|
||||
|
||||
out:
|
||||
if (retbuf)
|
||||
dbg_free(retbuf);
|
||||
dm_free(retbuf);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -302,10 +302,10 @@ static int _cluster_free_request(lvm_response_t * response)
|
||||
num = ptr[1];
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
dbg_free(response[i].response);
|
||||
dm_free(response[i].response);
|
||||
}
|
||||
|
||||
dbg_free(ptr);
|
||||
dm_free(ptr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -327,8 +327,8 @@ static int _lock_for_cluster(unsigned char cmd, unsigned int flags, char *name)
|
||||
args = alloca(len);
|
||||
strcpy(args + 2, name);
|
||||
|
||||
args[0] = flags & 0xBF; /* Maskoff LOCAL flag */
|
||||
args[1] = 0; /* Not used now */
|
||||
args[0] = flags & 0x7F; /* Maskoff lock flags */
|
||||
args[1] = flags & 0xC0; /* Bitmap flags */
|
||||
|
||||
/*
|
||||
* VG locks are just that: locks, and have no side effects
|
||||
@@ -339,7 +339,8 @@ static int _lock_for_cluster(unsigned char cmd, unsigned int flags, char *name)
|
||||
*/
|
||||
if (cmd == CLVMD_CMD_LOCK_VG ||
|
||||
(flags & LCK_TYPE_MASK) == LCK_EXCL ||
|
||||
(flags & LCK_LOCAL))
|
||||
(flags & LCK_LOCAL) ||
|
||||
!(flags & LCK_CLUSTER_VG))
|
||||
node = ".";
|
||||
|
||||
status = _cluster_request(cmd, node, args, len,
|
||||
|
||||
@@ -71,8 +71,8 @@ static int _release_lock(const char *file, int unlock)
|
||||
if (close(ll->lf) < 0)
|
||||
log_sys_error("close", ll->res);
|
||||
|
||||
dbg_free(ll->res);
|
||||
dbg_free(llh);
|
||||
dm_free(ll->res);
|
||||
dm_free(llh);
|
||||
|
||||
if (file)
|
||||
return 1;
|
||||
@@ -150,11 +150,11 @@ static int _lock_file(const char *file, int flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(ll = dbg_malloc(sizeof(struct lock_list))))
|
||||
if (!(ll = dm_malloc(sizeof(struct lock_list))))
|
||||
return 0;
|
||||
|
||||
if (!(ll->res = dbg_strdup(file))) {
|
||||
dbg_free(ll);
|
||||
if (!(ll->res = dm_strdup(file))) {
|
||||
dm_free(ll);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -197,8 +197,8 @@ static int _lock_file(const char *file, int flags)
|
||||
return 1;
|
||||
|
||||
err:
|
||||
dbg_free(ll->res);
|
||||
dbg_free(ll);
|
||||
dm_free(ll->res);
|
||||
dm_free(ll);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
|
||||
break;
|
||||
case LCK_READ:
|
||||
log_debug("Locking LV %s (R)", resource);
|
||||
if (!lv_activate_with_filter(cmd, resource))
|
||||
if (!lv_activate_with_filter(cmd, resource, 0))
|
||||
return 0;
|
||||
break;
|
||||
case LCK_WRITE:
|
||||
@@ -253,7 +253,7 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
|
||||
break;
|
||||
case LCK_EXCL:
|
||||
log_debug("Locking LV %s (EX)", resource);
|
||||
if (!lv_activate_with_filter(cmd, resource))
|
||||
if (!lv_activate_with_filter(cmd, resource, 1))
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -268,7 +268,7 @@ int resume_lvs(struct cmd_context *cmd, struct list *lvs)
|
||||
struct lv_list *lvl;
|
||||
|
||||
list_iterate_items(lvl, lvs)
|
||||
resume_lv(cmd, lvl->lv->lvid.s);
|
||||
resume_lv(cmd, lvl->lv);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -280,11 +280,11 @@ int suspend_lvs(struct cmd_context *cmd, struct list *lvs)
|
||||
struct lv_list *lvl;
|
||||
|
||||
list_iterate_items(lvl, lvs) {
|
||||
if (!suspend_lv(cmd, lvl->lv->lvid.s)) {
|
||||
if (!suspend_lv(cmd, lvl->lv)) {
|
||||
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);
|
||||
resume_lv(cmd, lvl->lv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -301,11 +301,11 @@ int activate_lvs_excl(struct cmd_context *cmd, struct list *lvs)
|
||||
struct lv_list *lvl;
|
||||
|
||||
list_iterate_items(lvl, lvs) {
|
||||
if (!activate_lv_excl(cmd, lvl->lv->lvid.s)) {
|
||||
if (!activate_lv_excl(cmd, lvl->lv)) {
|
||||
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);
|
||||
activate_lv(cmd, lvl->lv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -65,6 +65,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
|
||||
#define LCK_NONBLOCK 0x00000010 /* Don't block waiting for lock? */
|
||||
#define LCK_HOLD 0x00000020 /* Hold lock when lock_vol returns? */
|
||||
#define LCK_LOCAL 0x00000040 /* Don't propagate to other nodes */
|
||||
#define LCK_CLUSTER_VG 0x00000080 /* VG is clustered */
|
||||
|
||||
/*
|
||||
* Common combinations
|
||||
@@ -79,22 +80,27 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
|
||||
#define LCK_LV_ACTIVATE (LCK_LV | LCK_READ | LCK_NONBLOCK)
|
||||
#define LCK_LV_DEACTIVATE (LCK_LV | LCK_NULL | LCK_NONBLOCK)
|
||||
|
||||
#define LCK_LV_CLUSTERED(lv) \
|
||||
(((lv)->vg->status & CLUSTERED) ? LCK_CLUSTER_VG : 0)
|
||||
|
||||
#define lock_lv_vol(cmd, lv, flags) \
|
||||
lock_vol(cmd, (lv)->lvid.s, flags | LCK_LV_CLUSTERED(lv))
|
||||
|
||||
#define unlock_vg(cmd, vol) lock_vol(cmd, vol, LCK_VG_UNLOCK)
|
||||
|
||||
#define resume_lv(cmd, vol) lock_vol(cmd, vol, LCK_LV_RESUME)
|
||||
#define suspend_lv(cmd, vol) lock_vol(cmd, vol, LCK_LV_SUSPEND | LCK_HOLD)
|
||||
#define deactivate_lv(cmd, vol) lock_vol(cmd, vol, LCK_LV_DEACTIVATE)
|
||||
#define activate_lv(cmd, vol) lock_vol(cmd, vol, LCK_LV_ACTIVATE | LCK_HOLD)
|
||||
#define activate_lv_excl(cmd, vol) \
|
||||
lock_vol(cmd, vol, LCK_LV_EXCLUSIVE | LCK_HOLD)
|
||||
#define activate_lv_local(cmd, vol) \
|
||||
lock_vol(cmd, vol, LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL)
|
||||
#define deactivate_lv_local(cmd, vol) \
|
||||
lock_vol(cmd, vol, LCK_LV_DEACTIVATE | LCK_LOCAL)
|
||||
#define resume_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_RESUME)
|
||||
#define suspend_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_SUSPEND | LCK_HOLD)
|
||||
#define deactivate_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE)
|
||||
#define activate_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD)
|
||||
#define activate_lv_excl(cmd, lv) \
|
||||
lock_lv_vol(cmd, lv, LCK_LV_EXCLUSIVE | LCK_HOLD)
|
||||
#define activate_lv_local(cmd, lv) \
|
||||
lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL)
|
||||
#define deactivate_lv_local(cmd, lv) \
|
||||
lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE | LCK_LOCAL)
|
||||
|
||||
/* Process list of LVs */
|
||||
int suspend_lvs(struct cmd_context *cmd, struct list *lvs);
|
||||
int resume_lvs(struct cmd_context *cmd, struct list *lvs);
|
||||
int activate_lvs_excl(struct cmd_context *cmd, struct list *lvs);
|
||||
|
||||
|
||||
|
||||
@@ -58,11 +58,11 @@ static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
|
||||
case LCK_UNLOCK:
|
||||
return lv_resume_if_active(cmd, resource);
|
||||
case LCK_READ:
|
||||
return lv_activate_with_filter(cmd, resource);
|
||||
return lv_activate_with_filter(cmd, resource, 0);
|
||||
case LCK_WRITE:
|
||||
return lv_suspend_if_active(cmd, resource);
|
||||
case LCK_EXCL:
|
||||
return lv_activate_with_filter(cmd, resource);
|
||||
return lv_activate_with_filter(cmd, resource, 1);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ void release_log_memory(void)
|
||||
if (!_log_direct)
|
||||
return;
|
||||
|
||||
dbg_free((char *) _log_dev_alias.str);
|
||||
dm_free((char *) _log_dev_alias.str);
|
||||
_log_dev_alias.str = "activate_log file";
|
||||
}
|
||||
|
||||
|
||||
@@ -124,4 +124,8 @@ void print_log(int level, const char *file, int line, const char *format, ...)
|
||||
#define log_sys_debug(x, y) \
|
||||
log_debug("%s: %s failed: %s", y, x, strerror(errno))
|
||||
|
||||
#define return_0 do { stack; return 0; } while (0)
|
||||
#define return_NULL do { stack; return NULL; } while (0)
|
||||
#define goto_out do { stack; goto out; } while (0)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,9 +14,8 @@
|
||||
*/
|
||||
|
||||
#ifndef _LVM_LV_ALLOC_H
|
||||
#include "pool.h"
|
||||
|
||||
struct lv_segment *alloc_lv_segment(struct pool *mem,
|
||||
struct lv_segment *alloc_lv_segment(struct dm_pool *mem,
|
||||
struct segment_type *segtype,
|
||||
struct logical_volume *lv,
|
||||
uint32_t le, uint32_t len,
|
||||
@@ -53,7 +52,8 @@ struct alloc_handle *allocate_extents(struct volume_group *vg,
|
||||
uint32_t mirrored_pe,
|
||||
uint32_t status,
|
||||
struct list *allocatable_pvs,
|
||||
alloc_policy_t alloc);
|
||||
alloc_policy_t alloc,
|
||||
struct list *parallel_areas);
|
||||
|
||||
int lv_add_segment(struct alloc_handle *ah,
|
||||
uint32_t first_area, uint32_t num_areas,
|
||||
@@ -77,7 +77,14 @@ int lv_add_mirror_segment(struct alloc_handle *ah,
|
||||
uint32_t status,
|
||||
uint32_t region_size,
|
||||
struct logical_volume *log_lv);
|
||||
int lv_add_more_mirrored_areas(struct logical_volume *lv,
|
||||
struct logical_volume **sub_lvs,
|
||||
uint32_t new_area_count,
|
||||
uint32_t status);
|
||||
|
||||
void alloc_destroy(struct alloc_handle *ah);
|
||||
|
||||
struct list *build_parallel_areas_from_lv(struct cmd_context *cmd,
|
||||
struct logical_volume *lv);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
@@ -24,6 +24,18 @@
|
||||
#include "display.h"
|
||||
#include "segtype.h"
|
||||
|
||||
/*
|
||||
* PVs used by a segment of an LV
|
||||
*/
|
||||
struct seg_pvs {
|
||||
struct list list;
|
||||
|
||||
struct list pvs; /* struct pv_list */
|
||||
|
||||
uint32_t le;
|
||||
uint32_t len;
|
||||
};
|
||||
|
||||
/*
|
||||
* Find first unused LV number.
|
||||
*/
|
||||
@@ -53,7 +65,7 @@ uint32_t find_free_lvnum(struct logical_volume *lv)
|
||||
/*
|
||||
* All lv_segments get created here.
|
||||
*/
|
||||
struct lv_segment *alloc_lv_segment(struct pool *mem,
|
||||
struct lv_segment *alloc_lv_segment(struct dm_pool *mem,
|
||||
struct segment_type *segtype,
|
||||
struct logical_volume *lv,
|
||||
uint32_t le, uint32_t len,
|
||||
@@ -67,9 +79,15 @@ struct lv_segment *alloc_lv_segment(struct pool *mem,
|
||||
uint32_t extents_copied)
|
||||
{
|
||||
struct lv_segment *seg;
|
||||
uint32_t sz = sizeof(*seg) + (area_count * sizeof(seg->area[0]));
|
||||
uint32_t areas_sz = area_count * sizeof(*seg->areas);
|
||||
|
||||
if (!(seg = pool_zalloc(mem, sz))) {
|
||||
if (!(seg = dm_pool_zalloc(mem, sizeof(*seg)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(seg->areas = dm_pool_zalloc(mem, areas_sz))) {
|
||||
dm_pool_free(mem, seg);
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -91,10 +109,13 @@ struct lv_segment *alloc_lv_segment(struct pool *mem,
|
||||
seg->region_size = region_size;
|
||||
seg->extents_copied = extents_copied;
|
||||
seg->log_lv = log_lv;
|
||||
seg->mirror_seg = NULL;
|
||||
list_init(&seg->tags);
|
||||
|
||||
if (log_lv)
|
||||
if (log_lv) {
|
||||
log_lv->status |= MIRROR_LOG;
|
||||
first_seg(log_lv)->mirror_seg = seg;
|
||||
}
|
||||
|
||||
return seg;
|
||||
}
|
||||
@@ -199,7 +220,7 @@ int move_lv_segment_area(struct lv_segment *seg_to, uint32_t area_to,
|
||||
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;
|
||||
seg->areas[area_num].type = AREA_PV;
|
||||
|
||||
if (!(seg_pvseg(seg, area_num) =
|
||||
assign_peg_to_lvseg(pv, pe, seg->area_len, seg, area_num))) {
|
||||
@@ -217,12 +238,35 @@ 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->areas[area_num].type = AREA_LV;
|
||||
seg_lv(seg, area_num) = lv;
|
||||
seg_le(seg, area_num) = le;
|
||||
lv->status |= flags;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare for adding parallel areas to an existing segment.
|
||||
*/
|
||||
static int _lv_segment_add_areas(struct logical_volume *lv,
|
||||
struct lv_segment *seg,
|
||||
uint32_t new_area_count)
|
||||
{
|
||||
struct lv_segment_area *newareas;
|
||||
uint32_t areas_sz = new_area_count * sizeof(*newareas);
|
||||
|
||||
if (!(newareas = dm_pool_zalloc(lv->vg->cmd->mem, areas_sz))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(newareas, seg->areas, seg->area_count * sizeof(*seg->areas));
|
||||
|
||||
seg->areas = newareas;
|
||||
seg->area_count = new_area_count;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reduce the size of an lv_segment. New size can be zero.
|
||||
*/
|
||||
@@ -310,13 +354,16 @@ static int _lv_reduce(struct logical_volume *lv, uint32_t extents, int delete)
|
||||
}
|
||||
|
||||
/*
|
||||
* Empty an LV
|
||||
* Empty an LV.
|
||||
*/
|
||||
int lv_empty(struct logical_volume *lv)
|
||||
{
|
||||
return _lv_reduce(lv, 0, lv->le_count);
|
||||
return _lv_reduce(lv, lv->le_count, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove given number of extents from LV.
|
||||
*/
|
||||
int lv_reduce(struct logical_volume *lv, uint32_t extents)
|
||||
{
|
||||
return _lv_reduce(lv, extents, 1);
|
||||
@@ -351,7 +398,7 @@ struct alloced_area {
|
||||
* Details of an allocation attempt
|
||||
*/
|
||||
struct alloc_handle {
|
||||
struct pool *mem;
|
||||
struct dm_pool *mem;
|
||||
|
||||
alloc_policy_t alloc; /* Overall policy */
|
||||
uint32_t area_count; /* Number of parallel areas */
|
||||
@@ -359,6 +406,10 @@ struct alloc_handle {
|
||||
uint32_t log_count; /* Number of parallel 1-extent logs */
|
||||
uint32_t total_area_len; /* Total number of parallel extents */
|
||||
|
||||
struct physical_volume *mirrored_pv; /* FIXME Remove this */
|
||||
uint32_t mirrored_pe; /* FIXME Remove this */
|
||||
struct list *parallel_areas; /* PVs to avoid */
|
||||
|
||||
struct alloced_area log_area; /* Extent used for log */
|
||||
struct list alloced_areas[0]; /* Lists of areas in each stripe */
|
||||
};
|
||||
@@ -366,13 +417,15 @@ struct alloc_handle {
|
||||
/*
|
||||
* Preparation for a specific allocation attempt
|
||||
*/
|
||||
static struct alloc_handle *_alloc_init(struct pool *mem,
|
||||
static struct alloc_handle *_alloc_init(struct dm_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 physical_volume *mirrored_pv,
|
||||
uint32_t mirrored_pe,
|
||||
struct list *parallel_areas)
|
||||
{
|
||||
struct alloc_handle *ah;
|
||||
uint32_t s, area_count;
|
||||
@@ -403,7 +456,7 @@ static struct alloc_handle *_alloc_init(struct pool *mem,
|
||||
else
|
||||
area_count = stripes;
|
||||
|
||||
if (!(ah = pool_zalloc(mem, sizeof(*ah) + sizeof(ah->alloced_areas[0]) * area_count))) {
|
||||
if (!(ah = dm_pool_zalloc(mem, sizeof(*ah) + sizeof(ah->alloced_areas[0]) * area_count))) {
|
||||
log_error("allocation handle allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -411,7 +464,7 @@ static struct alloc_handle *_alloc_init(struct pool *mem,
|
||||
if (segtype_is_virtual(segtype))
|
||||
return ah;
|
||||
|
||||
if (!(ah->mem = pool_create("allocation", 1024))) {
|
||||
if (!(ah->mem = dm_pool_create("allocation", 1024))) {
|
||||
log_error("allocation pool creation failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -426,13 +479,17 @@ static struct alloc_handle *_alloc_init(struct pool *mem,
|
||||
for (s = 0; s < ah->area_count; s++)
|
||||
list_init(&ah->alloced_areas[s]);
|
||||
|
||||
ah->mirrored_pv = mirrored_pv;
|
||||
ah->mirrored_pe = mirrored_pe;
|
||||
ah->parallel_areas = parallel_areas;
|
||||
|
||||
return ah;
|
||||
}
|
||||
|
||||
void alloc_destroy(struct alloc_handle *ah)
|
||||
{
|
||||
if (ah->mem)
|
||||
pool_destroy(ah->mem);
|
||||
dm_pool_destroy(ah->mem);
|
||||
}
|
||||
|
||||
static int _setup_alloced_segment(struct logical_volume *lv, uint32_t status,
|
||||
@@ -453,10 +510,11 @@ static int _setup_alloced_segment(struct logical_volume *lv, uint32_t status,
|
||||
|
||||
area_multiple = segtype_is_striped(segtype) ? area_count : 1;
|
||||
|
||||
/* log_lv gets set up elsehere */
|
||||
if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv,
|
||||
lv->le_count,
|
||||
aa[0].len * area_multiple,
|
||||
status, stripe_size, log_lv,
|
||||
status, stripe_size, NULL,
|
||||
area_count + extra_areas,
|
||||
aa[0].len, 0u, region_size, 0u))) {
|
||||
log_error("Couldn't allocate new LV segment.");
|
||||
@@ -537,7 +595,7 @@ static int _alloc_parallel_area(struct alloc_handle *ah, uint32_t needed,
|
||||
if (area_len > smallest)
|
||||
area_len = smallest;
|
||||
|
||||
if (!(aa = pool_alloc(ah->mem, sizeof(*aa) *
|
||||
if (!(aa = dm_pool_alloc(ah->mem, sizeof(*aa) *
|
||||
(ah->area_count + (log_area ? 1 : 0))))) {
|
||||
log_error("alloced_area allocation failed");
|
||||
return 0;
|
||||
@@ -613,7 +671,6 @@ static int _check_contiguous(struct lv_segment *prev_lvseg,
|
||||
/*
|
||||
* Choose sets of parallel areas to use, respecting any constraints.
|
||||
*/
|
||||
/* 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,
|
||||
@@ -622,20 +679,23 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
|
||||
{
|
||||
struct pv_map *pvm;
|
||||
struct pv_area *pva;
|
||||
struct pv_list *pvl;
|
||||
unsigned already_found_one = 0;
|
||||
unsigned contiguous = 0, contiguous_count = 0;
|
||||
unsigned ix;
|
||||
unsigned ix_offset = 0; /* Offset for non-contiguous allocations */
|
||||
uint32_t max_parallel; /* Maximum extents to allocate */
|
||||
uint32_t next_le;
|
||||
struct seg_pvs *spvs;
|
||||
struct list *parallel_pvs;
|
||||
|
||||
/* 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)) {
|
||||
/* Are there any preceding segments we must follow on from? */
|
||||
if ((alloc == ALLOC_CONTIGUOUS) && prev_lvseg) {
|
||||
contiguous = 1;
|
||||
if (prev_lvseg)
|
||||
ix_offset = prev_lvseg->area_count;
|
||||
else
|
||||
ix_offset = ah->area_count;
|
||||
ix_offset = prev_lvseg->area_count;
|
||||
}
|
||||
|
||||
/* FIXME This algorithm needs a lot of cleaning up! */
|
||||
@@ -645,6 +705,25 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
|
||||
do {
|
||||
ix = 0;
|
||||
|
||||
parallel_pvs = NULL;
|
||||
max_parallel = needed;
|
||||
|
||||
/*
|
||||
* If there are existing parallel PVs, avoid them and reduce
|
||||
* the maximum we can allocate in one go accordingly.
|
||||
*/
|
||||
if (ah->parallel_areas) {
|
||||
list_iterate_items(spvs, ah->parallel_areas) {
|
||||
next_le = (prev_lvseg ? prev_lvseg->le + prev_lvseg->len : 0) + *allocated;
|
||||
if (next_le >= spvs->le) {
|
||||
if (next_le + max_parallel > spvs->le + spvs->len)
|
||||
max_parallel = spvs->le + spvs->len - next_le;
|
||||
parallel_pvs = &spvs->pvs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Put the smallest area of each PV that is at least the
|
||||
* size we need into areas array. If there isn't one
|
||||
@@ -655,10 +734,18 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
|
||||
if (list_empty(&pvm->areas))
|
||||
continue; /* Next PV */
|
||||
|
||||
/* Don't allocate onto the log pv */
|
||||
if ((alloc != ALLOC_ANYWHERE) && ah->log_count &&
|
||||
(pvm->pv == ah->log_area.pv))
|
||||
continue; /* Next PV */
|
||||
if (alloc != ALLOC_ANYWHERE) {
|
||||
/* Don't allocate onto the log pv */
|
||||
if (ah->log_count &&
|
||||
pvm->pv == ah->log_area.pv)
|
||||
continue; /* Next PV */
|
||||
|
||||
/* Avoid PVs used by existing parallel areas */
|
||||
if (parallel_pvs)
|
||||
list_iterate_items(pvl, parallel_pvs)
|
||||
if (pvm->pv == pvl->pv)
|
||||
goto next_pv;
|
||||
}
|
||||
|
||||
already_found_one = 0;
|
||||
/* First area in each list is the largest */
|
||||
@@ -669,17 +756,17 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
|
||||
pvm->pv,
|
||||
pva, areas)) {
|
||||
contiguous_count++;
|
||||
break; /* Next PV */
|
||||
goto next_pv;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Is it big enough on its own? */
|
||||
if ((pva->count < needed - *allocated) &&
|
||||
if ((pva->count < max_parallel - *allocated) &&
|
||||
((!can_split && !ah->log_count) ||
|
||||
(already_found_one &&
|
||||
!(alloc == ALLOC_ANYWHERE))))
|
||||
break; /* Next PV */
|
||||
goto next_pv;
|
||||
|
||||
if (!already_found_one ||
|
||||
alloc == ALLOC_ANYWHERE) {
|
||||
@@ -687,10 +774,11 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
|
||||
already_found_one = 1;
|
||||
}
|
||||
|
||||
areas[ix + ix_offset -1] = pva;
|
||||
areas[ix + ix_offset - 1] = pva;
|
||||
|
||||
break; /* Next PV */
|
||||
goto next_pv;
|
||||
}
|
||||
next_pv:
|
||||
if (ix >= areas_size)
|
||||
break;
|
||||
}
|
||||
@@ -712,7 +800,7 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
|
||||
|
||||
/* 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,
|
||||
if (!_alloc_parallel_area(ah, max_parallel, areas,
|
||||
allocated,
|
||||
(ah->log_count && !ah->log_area.len) ?
|
||||
*(areas + ix_offset + ix - 1) :
|
||||
@@ -733,13 +821,11 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
|
||||
*/
|
||||
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 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 pv_area **areas;
|
||||
uint32_t allocated = lv ? lv->le_count : 0;
|
||||
@@ -750,12 +836,12 @@ static int _allocate(struct alloc_handle *ah,
|
||||
struct list *pvms;
|
||||
uint32_t areas_size;
|
||||
|
||||
if (allocated >= new_extents) {
|
||||
if (allocated >= new_extents && !ah->log_count) {
|
||||
log_error("_allocate called with no work to do!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (mirrored_pv || (ah->alloc == ALLOC_CONTIGUOUS))
|
||||
if (ah->mirrored_pv || (ah->alloc == ALLOC_CONTIGUOUS))
|
||||
can_split = 0;
|
||||
|
||||
if (lv && !list_empty(&lv->segments))
|
||||
@@ -780,8 +866,13 @@ static int _allocate(struct alloc_handle *ah,
|
||||
areas_size = ah->area_count + ah->log_count;
|
||||
}
|
||||
|
||||
/* Upper bound if none of the PVs in prev_lvseg is in pvms */
|
||||
/* FIXME Work size out properly */
|
||||
if (prev_lvseg)
|
||||
areas_size += prev_lvseg->area_count;
|
||||
|
||||
/* Allocate an array of pv_areas to hold the largest space on each PV */
|
||||
if (!(areas = dbg_malloc(sizeof(*areas) * areas_size))) {
|
||||
if (!(areas = dm_malloc(sizeof(*areas) * areas_size))) {
|
||||
log_err("Couldn't allocate areas array.");
|
||||
return 0;
|
||||
}
|
||||
@@ -831,7 +922,7 @@ static int _allocate(struct alloc_handle *ah,
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
dbg_free(areas);
|
||||
dm_free(areas);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -870,7 +961,8 @@ struct alloc_handle *allocate_extents(struct volume_group *vg,
|
||||
uint32_t mirrored_pe,
|
||||
uint32_t status,
|
||||
struct list *allocatable_pvs,
|
||||
alloc_policy_t alloc)
|
||||
alloc_policy_t alloc,
|
||||
struct list *parallel_areas)
|
||||
{
|
||||
struct alloc_handle *ah;
|
||||
|
||||
@@ -893,15 +985,15 @@ struct alloc_handle *allocate_extents(struct volume_group *vg,
|
||||
alloc = vg->alloc;
|
||||
|
||||
if (!(ah = _alloc_init(vg->cmd->mem, segtype, alloc, mirrors,
|
||||
stripes, log_count, mirrored_pv))) {
|
||||
stripes, log_count, mirrored_pv,
|
||||
mirrored_pe, parallel_areas))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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)) {
|
||||
allocatable_pvs, stripes, mirrors, segtype)) {
|
||||
stack;
|
||||
alloc_destroy(ah);
|
||||
return NULL;
|
||||
@@ -1027,8 +1119,10 @@ int lv_add_mirror_segment(struct alloc_handle *ah,
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (m = 0; m < mirrors; m++)
|
||||
for (m = 0; m < mirrors; m++) {
|
||||
set_lv_segment_area_lv(seg, m, sub_lvs[m], 0, MIRROR_IMAGE);
|
||||
first_seg(sub_lvs[m])->mirror_seg = seg;
|
||||
}
|
||||
|
||||
list_add(&lv->segments, &seg->list);
|
||||
lv->le_count += ah->total_area_len;
|
||||
@@ -1043,6 +1137,41 @@ int lv_add_mirror_segment(struct alloc_handle *ah,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add parallel areas to an existing mirror
|
||||
*/
|
||||
int lv_add_more_mirrored_areas(struct logical_volume *lv,
|
||||
struct logical_volume **sub_lvs,
|
||||
uint32_t num_extra_areas,
|
||||
uint32_t status)
|
||||
{
|
||||
struct lv_segment *seg;
|
||||
uint32_t old_area_count, new_area_count;
|
||||
uint32_t m;
|
||||
|
||||
if (list_size(&lv->segments) != 1) {
|
||||
log_error("Mirrored LV must only have one segment.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
seg = first_seg(lv);
|
||||
|
||||
old_area_count = seg->area_count;
|
||||
new_area_count = old_area_count + num_extra_areas;
|
||||
|
||||
if (!_lv_segment_add_areas(lv, seg, new_area_count)) {
|
||||
log_error("Failed to allocate widened LV segment for %s.",
|
||||
lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (m = old_area_count; m < new_area_count; m++) {
|
||||
set_lv_segment_area_lv(seg, m, sub_lvs[m - old_area_count], 0, status);
|
||||
first_seg(sub_lvs[m - old_area_count])->mirror_seg = seg;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Entry point for single-step LV allocation + extension.
|
||||
@@ -1058,14 +1187,14 @@ int lv_extend(struct logical_volume *lv,
|
||||
int r = 1;
|
||||
uint32_t m;
|
||||
struct alloc_handle *ah;
|
||||
struct lv_segment *first_seg;
|
||||
struct lv_segment *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))) {
|
||||
allocatable_pvs, alloc, NULL))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -1077,20 +1206,19 @@ int lv_extend(struct logical_volume *lv,
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
list_iterate_items(first_seg, &lv->segments)
|
||||
break;
|
||||
seg = first_seg(lv);
|
||||
for (m = 0; m < mirrors; m++) {
|
||||
if (!lv_add_segment(ah, m, 1, seg_lv(first_seg, m),
|
||||
if (!lv_add_segment(ah, m, 1, seg_lv(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);
|
||||
seg_lv(seg, m)->name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
first_seg->area_len += extents;
|
||||
first_seg->len += extents;
|
||||
seg->area_len += extents;
|
||||
seg->len += extents;
|
||||
lv->le_count += extents;
|
||||
lv->size += (uint64_t) extents *lv->vg->extent_size;
|
||||
}
|
||||
@@ -1152,21 +1280,21 @@ struct logical_volume *lv_create_empty(struct format_instance *fi,
|
||||
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)))) {
|
||||
if (!(ll = dm_pool_zalloc(cmd->mem, sizeof(*ll))) ||
|
||||
!(ll->lv = dm_pool_zalloc(cmd->mem, sizeof(*ll->lv)))) {
|
||||
log_error("lv_list allocation failed");
|
||||
if (ll)
|
||||
pool_free(cmd->mem, ll);
|
||||
dm_pool_free(cmd->mem, ll);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv = ll->lv;
|
||||
lv->vg = vg;
|
||||
|
||||
if (!(lv->name = pool_strdup(cmd->mem, name))) {
|
||||
if (!(lv->name = dm_pool_strdup(cmd->mem, name))) {
|
||||
log_error("lv name strdup failed");
|
||||
if (ll)
|
||||
pool_free(cmd->mem, ll);
|
||||
dm_pool_free(cmd->mem, ll);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1188,7 +1316,7 @@ struct logical_volume *lv_create_empty(struct format_instance *fi,
|
||||
if (fi->fmt->ops->lv_setup && !fi->fmt->ops->lv_setup(fi, lv)) {
|
||||
stack;
|
||||
if (ll)
|
||||
pool_free(cmd->mem, ll);
|
||||
dm_pool_free(cmd->mem, ll);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1199,3 +1327,116 @@ struct logical_volume *lv_create_empty(struct format_instance *fi,
|
||||
|
||||
return lv;
|
||||
}
|
||||
|
||||
/* Recursively process each PV used by part of an LV */
|
||||
static int _for_each_pv(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
uint32_t le, uint32_t len,
|
||||
int (*fn)(struct cmd_context *cmd, struct pv_segment *peg, struct seg_pvs *spvs),
|
||||
struct seg_pvs *spvs)
|
||||
{
|
||||
struct lv_segment *seg;
|
||||
uint32_t s;
|
||||
uint32_t remaining_seg_len, area_len, area_multiple;
|
||||
|
||||
if (!(seg = find_seg_by_le(lv, le))) {
|
||||
log_error("Failed to find segment for %s extent %" PRIu32,
|
||||
lv->name, le);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remaining logical length of segment */
|
||||
remaining_seg_len = seg->len - (le - seg->le);
|
||||
|
||||
if (len > remaining_seg_len)
|
||||
remaining_seg_len = len;
|
||||
|
||||
if (spvs->len > remaining_seg_len)
|
||||
spvs->len = remaining_seg_len;
|
||||
|
||||
area_multiple = segtype_is_striped(seg->segtype) ? seg->area_count : 1;
|
||||
area_len = remaining_seg_len / area_multiple;
|
||||
|
||||
for (s = 0; s < seg->area_count; s++) {
|
||||
if (seg_type(seg, s) == AREA_LV) {
|
||||
if (!_for_each_pv(cmd, seg_lv(seg, s),
|
||||
seg_le(seg, s) + (le - seg->le) / area_multiple,
|
||||
area_len, fn, spvs)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
} else if (seg_type(seg, s) == AREA_PV) {
|
||||
if (!fn(cmd, seg_pvseg(seg, s), spvs)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _add_pvs(struct cmd_context *cmd, struct pv_segment *peg, struct seg_pvs *spvs)
|
||||
{
|
||||
struct pv_list *pvl;
|
||||
|
||||
/* FIXME Don't add again if it's already on the list! */
|
||||
|
||||
if (!(pvl = dm_pool_alloc(cmd->mem, sizeof(*pvl)))) {
|
||||
log_error("pv_list allocation failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pvl->pv = peg->pv;
|
||||
|
||||
/* FIXME Use ordered list to facilitate comparison */
|
||||
list_add(&spvs->pvs, &pvl->list);
|
||||
|
||||
/* FIXME Add mirror logs, snapshot cow LVs etc. */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct list of segments of LVs showing which PVs they use.
|
||||
*/
|
||||
struct list *build_parallel_areas_from_lv(struct cmd_context *cmd,
|
||||
struct logical_volume *lv)
|
||||
{
|
||||
struct list *parallel_areas;
|
||||
struct seg_pvs *spvs;
|
||||
uint32_t current_le = 0;
|
||||
|
||||
if (!(parallel_areas = dm_pool_alloc(cmd->mem, sizeof(*parallel_areas)))) {
|
||||
log_error("parallel_areas allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_init(parallel_areas);
|
||||
|
||||
do {
|
||||
if (!(spvs = dm_pool_zalloc(cmd->mem, sizeof(*spvs)))) {
|
||||
log_error("allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_init(&spvs->pvs);
|
||||
|
||||
spvs->le = current_le;
|
||||
spvs->len = lv->le_count - current_le;
|
||||
|
||||
list_add(parallel_areas, &spvs->list);
|
||||
|
||||
/* Find next segment end */
|
||||
/* FIXME Unnecessary nesting! */
|
||||
if (!_for_each_pv(cmd, lv, current_le, lv->le_count, _add_pvs, spvs)) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
current_le = spvs->le + spvs->len;
|
||||
} while (current_le < lv->le_count);
|
||||
|
||||
/* FIXME Merge adjacent segments with identical PV lists (avoids need for contiguous allocation attempts between successful allocations) */
|
||||
|
||||
return parallel_areas;
|
||||
}
|
||||
|
||||
@@ -58,9 +58,9 @@ int lv_merge_segments(struct logical_volume *lv)
|
||||
/*
|
||||
* Verify that an LV's segments are consecutive, complete and don't overlap.
|
||||
*/
|
||||
int check_lv_segments(struct logical_volume *lv)
|
||||
int check_lv_segments(struct logical_volume *lv, int complete_vg)
|
||||
{
|
||||
struct lv_segment *seg;
|
||||
struct lv_segment *seg, *seg2;
|
||||
uint32_t le = 0;
|
||||
unsigned seg_count = 0;
|
||||
int r = 1;
|
||||
@@ -85,6 +85,40 @@ int check_lv_segments(struct logical_volume *lv)
|
||||
r = 0;
|
||||
}
|
||||
|
||||
if (complete_vg && seg->log_lv) {
|
||||
if (!seg_is_mirrored(seg)) {
|
||||
log_error("LV %s: segment %u has log LV but "
|
||||
"is not mirrored",
|
||||
lv->name, seg_count);
|
||||
r = 0;
|
||||
}
|
||||
|
||||
if (!(seg->log_lv->status & MIRROR_LOG)) {
|
||||
log_error("LV %s: segment %u log LV %s is not "
|
||||
"a mirror log",
|
||||
lv->name, seg_count, seg->log_lv->name);
|
||||
r = 0;
|
||||
}
|
||||
|
||||
if (!(seg2 = first_seg(seg->log_lv)) ||
|
||||
seg2->mirror_seg != seg) {
|
||||
log_error("LV %s: segment %u log LV does not "
|
||||
"point back to mirror segment",
|
||||
lv->name, seg_count);
|
||||
r = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (complete_vg && seg->status & MIRROR_IMAGE) {
|
||||
if (!seg->mirror_seg ||
|
||||
!seg_is_mirrored(seg->mirror_seg)) {
|
||||
log_error("LV %s: segment %u mirror image "
|
||||
"is not mirrored",
|
||||
lv->name, seg_count);
|
||||
r = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (s = 0; s < seg->area_count; s++) {
|
||||
if (seg_type(seg, s) == AREA_UNASSIGNED) {
|
||||
log_error("LV %s: segment %u has unassigned "
|
||||
@@ -109,6 +143,18 @@ int check_lv_segments(struct logical_volume *lv)
|
||||
lv->name, seg_count, s);
|
||||
r = 0;
|
||||
}
|
||||
|
||||
if (complete_vg && seg_lv(seg, s) &&
|
||||
(seg_lv(seg, s)->status & MIRROR_IMAGE) &&
|
||||
(find_seg_by_le(seg_lv(seg, s),
|
||||
seg_le(seg, s))->mirror_seg
|
||||
!= seg)) {
|
||||
log_error("LV %s: segment %u mirror "
|
||||
"image %u missing mirror ptr",
|
||||
lv->name, seg_count, s);
|
||||
r = 0;
|
||||
}
|
||||
|
||||
/* FIXME I don't think this ever holds?
|
||||
if (seg_le(seg, s) != le) {
|
||||
log_error("LV %s: segment %u has "
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "pool.h"
|
||||
#include "device.h"
|
||||
#include "metadata.h"
|
||||
#include "toolcontext.h"
|
||||
@@ -23,19 +22,20 @@
|
||||
#include "memlock.h"
|
||||
#include "str_list.h"
|
||||
#include "pv_alloc.h"
|
||||
#include "activate.h"
|
||||
|
||||
static int _add_pv_to_vg(struct format_instance *fid, struct volume_group *vg,
|
||||
const char *pv_name)
|
||||
{
|
||||
struct pv_list *pvl;
|
||||
struct physical_volume *pv;
|
||||
struct pool *mem = fid->fmt->cmd->mem;
|
||||
struct dm_pool *mem = fid->fmt->cmd->mem;
|
||||
struct list mdas;
|
||||
|
||||
log_verbose("Adding physical volume '%s' to volume group '%s'",
|
||||
pv_name, vg->name);
|
||||
|
||||
if (!(pvl = pool_zalloc(mem, sizeof(*pvl)))) {
|
||||
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl)))) {
|
||||
log_error("pv_list allocation for '%s' failed", pv_name);
|
||||
return 0;
|
||||
}
|
||||
@@ -59,7 +59,14 @@ static int _add_pv_to_vg(struct format_instance *fid, struct volume_group *vg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(pv->vg_name = pool_strdup(mem, vg->name))) {
|
||||
/* Ensure PV doesn't depend on another PV already in the VG */
|
||||
if (pv_uses_vg(fid->fmt->cmd, pv, vg)) {
|
||||
log_error("Physical volume %s might be constructed from same "
|
||||
"volume group %s", pv_name, vg->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(pv->vg_name = dm_pool_strdup(mem, vg->name))) {
|
||||
log_error("vg->name allocation failed for '%s'", pv_name);
|
||||
return 0;
|
||||
}
|
||||
@@ -168,16 +175,16 @@ int get_pv_from_vg_by_id(const struct format_type *fmt, const char *vg_name,
|
||||
int vg_rename(struct cmd_context *cmd, struct volume_group *vg,
|
||||
const char *new_name)
|
||||
{
|
||||
struct pool *mem = cmd->mem;
|
||||
struct dm_pool *mem = cmd->mem;
|
||||
struct pv_list *pvl;
|
||||
|
||||
if (!(vg->name = pool_strdup(mem, new_name))) {
|
||||
if (!(vg->name = dm_pool_strdup(mem, new_name))) {
|
||||
log_error("vg->name allocation failed for '%s'", new_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
list_iterate_items(pvl, &vg->pvs) {
|
||||
if (!(pvl->pv->vg_name = pool_strdup(mem, new_name))) {
|
||||
if (!(pvl->pv->vg_name = dm_pool_strdup(mem, new_name))) {
|
||||
log_error("pv->vg_name allocation failed for '%s'",
|
||||
dev_name(pvl->pv->dev));
|
||||
return 0;
|
||||
@@ -220,11 +227,11 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name,
|
||||
int pv_count, char **pv_names)
|
||||
{
|
||||
struct volume_group *vg;
|
||||
struct pool *mem = cmd->mem;
|
||||
struct dm_pool *mem = cmd->mem;
|
||||
int consistent = 0;
|
||||
int old_partial;
|
||||
|
||||
if (!(vg = pool_zalloc(mem, sizeof(*vg)))) {
|
||||
if (!(vg = dm_pool_zalloc(mem, sizeof(*vg)))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@@ -248,7 +255,7 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name,
|
||||
|
||||
vg->cmd = cmd;
|
||||
|
||||
if (!(vg->name = pool_strdup(mem, vg_name))) {
|
||||
if (!(vg->name = dm_pool_strdup(mem, vg_name))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -256,7 +263,7 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name,
|
||||
vg->seqno = 0;
|
||||
|
||||
vg->status = (RESIZEABLE_VG | LVM_READ | LVM_WRITE);
|
||||
vg->system_id = pool_alloc(mem, NAME_LEN);
|
||||
vg->system_id = dm_pool_alloc(mem, NAME_LEN);
|
||||
*vg->system_id = '\0';
|
||||
|
||||
vg->extent_size = extent_size;
|
||||
@@ -298,7 +305,7 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name,
|
||||
return vg;
|
||||
|
||||
bad:
|
||||
pool_free(mem, vg);
|
||||
dm_pool_free(mem, vg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -488,8 +495,8 @@ struct physical_volume *pv_create(const struct format_type *fmt,
|
||||
int pvmetadatacopies,
|
||||
uint64_t pvmetadatasize, struct list *mdas)
|
||||
{
|
||||
struct pool *mem = fmt->cmd->mem;
|
||||
struct physical_volume *pv = pool_alloc(mem, sizeof(*pv));
|
||||
struct dm_pool *mem = fmt->cmd->mem;
|
||||
struct physical_volume *pv = dm_pool_alloc(mem, sizeof(*pv));
|
||||
|
||||
if (!pv) {
|
||||
stack;
|
||||
@@ -506,7 +513,7 @@ struct physical_volume *pv_create(const struct format_type *fmt,
|
||||
|
||||
pv->dev = dev;
|
||||
|
||||
if (!(pv->vg_name = pool_zalloc(mem, NAME_LEN))) {
|
||||
if (!(pv->vg_name = dm_pool_zalloc(mem, NAME_LEN))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@@ -553,7 +560,7 @@ struct physical_volume *pv_create(const struct format_type *fmt,
|
||||
return pv;
|
||||
|
||||
bad:
|
||||
pool_free(mem, pv);
|
||||
dm_pool_free(mem, pv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -668,6 +675,16 @@ struct lv_segment *find_seg_by_le(struct logical_volume *lv, uint32_t le)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct lv_segment *first_seg(struct logical_volume *lv)
|
||||
{
|
||||
struct lv_segment *seg = NULL;
|
||||
|
||||
list_iterate_items(seg, &lv->segments)
|
||||
break;
|
||||
|
||||
return seg;
|
||||
}
|
||||
|
||||
/* Find segment at a given physical extent in a PV */
|
||||
struct pv_segment *find_peg_by_pe(struct physical_volume *pv, uint32_t pe)
|
||||
{
|
||||
@@ -708,7 +725,7 @@ int vg_validate(struct volume_group *vg)
|
||||
}
|
||||
|
||||
list_iterate_items(lvl, &vg->lvs) {
|
||||
if (!check_lv_segments(lvl->lv)) {
|
||||
if (!check_lv_segments(lvl->lv, 1)) {
|
||||
log_error("Internal error: LV segments corrupted in %s.",
|
||||
lvl->lv->name);
|
||||
return 0;
|
||||
@@ -850,7 +867,7 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(vg = pool_zalloc(cmd->mem, sizeof(*vg)))) {
|
||||
if (!(vg = dm_pool_zalloc(cmd->mem, sizeof(*vg)))) {
|
||||
log_error("vg allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -858,7 +875,7 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd)
|
||||
list_init(&vg->lvs);
|
||||
list_init(&vg->tags);
|
||||
vg->cmd = cmd;
|
||||
if (!(vg->name = pool_strdup(cmd->mem, ORPHAN))) {
|
||||
if (!(vg->name = dm_pool_strdup(cmd->mem, ORPHAN))) {
|
||||
log_error("vg name allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -867,7 +884,7 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd)
|
||||
if (!(pv = pv_read(cmd, dev_name(info->dev), NULL, NULL, 1))) {
|
||||
continue;
|
||||
}
|
||||
if (!(pvl = pool_zalloc(cmd->mem, sizeof(*pvl)))) {
|
||||
if (!(pvl = dm_pool_zalloc(cmd->mem, sizeof(*pvl)))) {
|
||||
log_error("pv_list allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -885,6 +902,8 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd)
|
||||
* If consistent is 0, caller must check whether consistent == 1 on return
|
||||
* and take appropriate action if it isn't (e.g. abort; get write lock
|
||||
* and call vg_read again).
|
||||
*
|
||||
* If precommitted is set, use precommitted metadata if present.
|
||||
*/
|
||||
static struct volume_group *_vg_read(struct cmd_context *cmd,
|
||||
const char *vgname,
|
||||
@@ -895,9 +914,10 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
|
||||
struct volume_group *vg, *correct_vg = NULL;
|
||||
struct metadata_area *mda;
|
||||
int inconsistent = 0;
|
||||
int use_precommitted = precommitted;
|
||||
|
||||
if (!*vgname) {
|
||||
if (precommitted) {
|
||||
if (use_precommitted) {
|
||||
log_error("Internal error: vg_read requires vgname "
|
||||
"with pre-commit.");
|
||||
return NULL;
|
||||
@@ -923,11 +943,8 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
|
||||
}
|
||||
}
|
||||
|
||||
if (precommitted && !(fmt->features & FMT_PRECOMMIT)) {
|
||||
log_error("Internal error: %s doesn't support "
|
||||
"pre-commit", fmt->name);
|
||||
return NULL;
|
||||
}
|
||||
if (use_precommitted && !(fmt->features & FMT_PRECOMMIT))
|
||||
use_precommitted = 0;
|
||||
|
||||
/* create format instance with appropriate metadata area */
|
||||
if (!(fid = fmt->ops->create_instance(fmt, vgname, NULL))) {
|
||||
@@ -937,9 +954,9 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
|
||||
|
||||
/* Ensure contents of all metadata areas match - else do recovery */
|
||||
list_iterate_items(mda, &fid->metadata_areas) {
|
||||
if ((precommitted &&
|
||||
if ((use_precommitted &&
|
||||
!(vg = mda->ops->vg_read_precommit(fid, vgname, mda))) ||
|
||||
(!precommitted &&
|
||||
(!use_precommitted &&
|
||||
!(vg = mda->ops->vg_read(fid, vgname, mda)))) {
|
||||
inconsistent = 1;
|
||||
continue;
|
||||
@@ -966,11 +983,8 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (precommitted && !(fmt->features & FMT_PRECOMMIT)) {
|
||||
log_error("Internal error: %s doesn't support "
|
||||
"pre-commit", fmt->name);
|
||||
return NULL;
|
||||
}
|
||||
if (precommitted && !(fmt->features & FMT_PRECOMMIT))
|
||||
use_precommitted = 0;
|
||||
|
||||
/* create format instance with appropriate metadata area */
|
||||
if (!(fid = fmt->ops->create_instance(fmt, vgname, NULL))) {
|
||||
@@ -980,10 +994,10 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
|
||||
|
||||
/* Ensure contents of all metadata areas match - else recover */
|
||||
list_iterate_items(mda, &fid->metadata_areas) {
|
||||
if ((precommitted &&
|
||||
if ((use_precommitted &&
|
||||
!(vg = mda->ops->vg_read_precommit(fid, vgname,
|
||||
mda))) ||
|
||||
(!precommitted &&
|
||||
(!use_precommitted &&
|
||||
!(vg = mda->ops->vg_read(fid, vgname, mda)))) {
|
||||
inconsistent = 1;
|
||||
continue;
|
||||
@@ -1010,7 +1024,8 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
|
||||
lvmcache_update_vg(correct_vg);
|
||||
|
||||
if (inconsistent) {
|
||||
if (precommitted) {
|
||||
/* FIXME Test should be if we're *using* precommitted metadata not if we were searching for it */
|
||||
if (use_precommitted) {
|
||||
log_error("Inconsistent pre-commit metadata copies "
|
||||
"for volume group %s", vgname);
|
||||
return NULL;
|
||||
@@ -1069,7 +1084,7 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
|
||||
}
|
||||
|
||||
list_iterate_items(lvl, &vg->lvs) {
|
||||
if (!check_lv_segments(lvl->lv)) {
|
||||
if (!check_lv_segments(lvl->lv, 1)) {
|
||||
log_error("Internal error: LV segments corrupted in %s.",
|
||||
lvl->lv->name);
|
||||
return NULL;
|
||||
@@ -1079,18 +1094,13 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
|
||||
return vg;
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid)
|
||||
static struct volume_group *_vg_read_by_vgid(struct cmd_context *cmd,
|
||||
const char *vgid,
|
||||
int precommitted)
|
||||
{
|
||||
const char *vgname;
|
||||
struct list *vgnames;
|
||||
@@ -1102,7 +1112,8 @@ struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid)
|
||||
/* Is corresponding vgname already cached? */
|
||||
if ((vginfo = vginfo_from_vgid(vgid)) &&
|
||||
vginfo->vgname && *vginfo->vgname) {
|
||||
if ((vg = vg_read(cmd, vginfo->vgname, &consistent)) &&
|
||||
if ((vg = _vg_read(cmd, vginfo->vgname,
|
||||
&consistent, precommitted)) &&
|
||||
!strncmp(vg->id.uuid, vgid, ID_LEN)) {
|
||||
if (!consistent) {
|
||||
log_error("Volume group %s metadata is "
|
||||
@@ -1132,7 +1143,8 @@ struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid)
|
||||
if (!vgname || !*vgname)
|
||||
continue; // FIXME Unnecessary?
|
||||
consistent = 0;
|
||||
if ((vg = vg_read(cmd, vgname, &consistent)) &&
|
||||
if ((vg = _vg_read(cmd, vgname, &consistent,
|
||||
precommitted)) &&
|
||||
!strncmp(vg->id.uuid, vgid, ID_LEN)) {
|
||||
if (!consistent) {
|
||||
log_error("Volume group %s metadata is "
|
||||
@@ -1147,7 +1159,8 @@ struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid)
|
||||
}
|
||||
|
||||
/* Only called by activate.c */
|
||||
struct logical_volume *lv_from_lvid(struct cmd_context *cmd, const char *lvid_s)
|
||||
struct logical_volume *lv_from_lvid(struct cmd_context *cmd, const char *lvid_s,
|
||||
int precommitted)
|
||||
{
|
||||
struct lv_list *lvl;
|
||||
struct volume_group *vg;
|
||||
@@ -1156,7 +1169,7 @@ struct logical_volume *lv_from_lvid(struct cmd_context *cmd, const char *lvid_s)
|
||||
lvid = (const union lvid *) lvid_s;
|
||||
|
||||
log_very_verbose("Finding volume group for uuid %s", lvid_s);
|
||||
if (!(vg = vg_read_by_vgid(cmd, lvid->id[0].uuid))) {
|
||||
if (!(vg = _vg_read_by_vgid(cmd, lvid->id[0].uuid, precommitted))) {
|
||||
log_error("Volume group for uuid not found: %s", lvid_s);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1200,7 +1213,7 @@ struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name,
|
||||
if (label_sector && *label_sector)
|
||||
*label_sector = label->sector;
|
||||
|
||||
if (!(pv = pool_zalloc(cmd->mem, sizeof(*pv)))) {
|
||||
if (!(pv = dm_pool_zalloc(cmd->mem, sizeof(*pv)))) {
|
||||
log_error("pv allocation for '%s' failed", pv_name);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1246,7 +1259,7 @@ struct list *get_pvs(struct cmd_context *cmd)
|
||||
|
||||
lvmcache_label_scan(cmd, 0);
|
||||
|
||||
if (!(results = pool_alloc(cmd->mem, sizeof(*results)))) {
|
||||
if (!(results = dm_pool_alloc(cmd->mem, sizeof(*results)))) {
|
||||
log_error("PV list allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
#define VIRTUAL 0x00010000 /* LV - internal use only */
|
||||
#define MIRROR_LOG 0x00020000 /* LV */
|
||||
#define MIRROR_IMAGE 0x00040000 /* LV */
|
||||
#define ACTIVATE_EXCL 0x00080000 /* LV - internal use only */
|
||||
#define PRECOMMITTED 0x00100000 /* VG - internal use only */
|
||||
|
||||
#define LVM_READ 0x00000100 /* LV VG */
|
||||
#define LVM_WRITE 0x00000200 /* LV VG */
|
||||
@@ -71,6 +73,7 @@
|
||||
#define FMT_RESTRICTED_LVIDS 0x00000010 /* LVID <= 255 */
|
||||
#define FMT_ORPHAN_ALLOCATABLE 0x00000020 /* Orphan PV allocatable? */
|
||||
#define FMT_PRECOMMIT 0x00000040 /* Supports pre-commit? */
|
||||
#define FMT_RESIZE_PV 0x00000080 /* Supports pvresize? */
|
||||
|
||||
typedef enum {
|
||||
ALLOC_INVALID,
|
||||
@@ -180,6 +183,7 @@ struct metadata_area {
|
||||
struct format_instance {
|
||||
const struct format_type *fmt;
|
||||
struct list metadata_areas; /* e.g. metadata locations */
|
||||
void *private;
|
||||
};
|
||||
|
||||
struct volume_group {
|
||||
@@ -213,6 +217,20 @@ struct volume_group {
|
||||
struct list tags;
|
||||
};
|
||||
|
||||
/* There will be one area for each stripe */
|
||||
struct lv_segment_area {
|
||||
area_type_t type;
|
||||
union {
|
||||
struct {
|
||||
struct pv_segment *pvseg;
|
||||
} pv;
|
||||
struct {
|
||||
struct logical_volume *lv;
|
||||
uint32_t le;
|
||||
} lv;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct segment_type;
|
||||
struct lv_segment {
|
||||
struct list list;
|
||||
@@ -235,31 +253,20 @@ struct lv_segment {
|
||||
uint32_t region_size; /* For mirrors - in sectors */
|
||||
uint32_t extents_copied;
|
||||
struct logical_volume *log_lv;
|
||||
struct lv_segment *mirror_seg;
|
||||
|
||||
struct list tags;
|
||||
|
||||
/* There will be one area for each stripe */
|
||||
struct {
|
||||
area_type_t type;
|
||||
union {
|
||||
struct {
|
||||
struct pv_segment *pvseg;
|
||||
} pv;
|
||||
struct {
|
||||
struct logical_volume *lv;
|
||||
uint32_t le;
|
||||
} lv;
|
||||
} u;
|
||||
} area[0];
|
||||
struct lv_segment_area *areas;
|
||||
};
|
||||
|
||||
#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
|
||||
#define seg_type(seg, s) (seg)->areas[(s)].type
|
||||
#define seg_pvseg(seg, s) (seg)->areas[(s)].u.pv.pvseg
|
||||
#define seg_pv(seg, s) (seg)->areas[(s)].u.pv.pvseg->pv
|
||||
#define seg_dev(seg, s) (seg)->areas[(s)].u.pv.pvseg->pv->dev
|
||||
#define seg_pe(seg, s) (seg)->areas[(s)].u.pv.pvseg->pe
|
||||
#define seg_lv(seg, s) (seg)->areas[(s)].u.lv.lv
|
||||
#define seg_le(seg, s) (seg)->areas[(s)].u.lv.le
|
||||
|
||||
struct logical_volume {
|
||||
union lvid lvid;
|
||||
@@ -397,10 +404,6 @@ int vg_commit(struct volume_group *vg);
|
||||
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,
|
||||
int warnings);
|
||||
@@ -423,6 +426,8 @@ struct physical_volume *pv_create(const struct format_type *fmt,
|
||||
uint32_t existing_extent_size,
|
||||
int pvmetadatacopies,
|
||||
uint64_t pvmetadatasize, struct list *mdas);
|
||||
int pv_resize(struct physical_volume *pv, struct volume_group *vg,
|
||||
uint32_t new_pe_count);
|
||||
|
||||
struct volume_group *vg_create(struct cmd_context *cmd, const char *name,
|
||||
uint32_t extent_size, uint32_t max_pv,
|
||||
@@ -486,7 +491,8 @@ struct volume_group *find_vg_with_lv(const char *lv_name);
|
||||
|
||||
/* Find LV with given lvid (used during activation) */
|
||||
struct logical_volume *lv_from_lvid(struct cmd_context *cmd,
|
||||
const char *lvid_s);
|
||||
const char *lvid_s,
|
||||
int precommitted);
|
||||
|
||||
/* FIXME Merge these functions with ones above */
|
||||
struct physical_volume *find_pv(struct volume_group *vg, struct device *dev);
|
||||
@@ -496,6 +502,7 @@ struct physical_volume *find_pv_by_name(struct cmd_context *cmd,
|
||||
|
||||
/* Find LV segment containing given LE */
|
||||
struct lv_segment *find_seg_by_le(struct logical_volume *lv, uint32_t le);
|
||||
struct lv_segment *first_seg(struct logical_volume *lv);
|
||||
|
||||
/* Find PV segment containing given LE */
|
||||
struct pv_segment *find_peg_by_pe(struct physical_volume *pv, uint32_t pe);
|
||||
@@ -507,8 +514,9 @@ const char *strip_dir(const char *vg_name, const char *dir);
|
||||
|
||||
/*
|
||||
* Checks that an lv has no gaps or overlapping segments.
|
||||
* Set complete_vg to perform additional VG level checks.
|
||||
*/
|
||||
int check_lv_segments(struct logical_volume *lv);
|
||||
int check_lv_segments(struct logical_volume *lv, int complete_vg);
|
||||
|
||||
/*
|
||||
* Sometimes (eg, after an lvextend), it is possible to merge two
|
||||
@@ -543,6 +551,8 @@ int vg_remove_snapshot(struct logical_volume *cow);
|
||||
* Mirroring functions
|
||||
*/
|
||||
struct alloc_handle;
|
||||
uint32_t adjusted_mirror_region_size(uint32_t extent_size, uint32_t extents,
|
||||
uint32_t region_size);
|
||||
int create_mirror_layers(struct alloc_handle *ah,
|
||||
uint32_t first_area,
|
||||
uint32_t num_mirrors,
|
||||
@@ -551,8 +561,19 @@ int create_mirror_layers(struct alloc_handle *ah,
|
||||
uint32_t status,
|
||||
uint32_t region_size,
|
||||
struct logical_volume *log_lv);
|
||||
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors);
|
||||
int remove_all_mirror_images(struct logical_volume *lv);
|
||||
int add_mirror_layers(struct alloc_handle *ah,
|
||||
uint32_t num_mirrors,
|
||||
uint32_t existing_mirrors,
|
||||
struct logical_volume *lv,
|
||||
struct segment_type *segtype);
|
||||
|
||||
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
|
||||
struct list *removable_pvs, int remove_log);
|
||||
/*
|
||||
* Given mirror image or mirror log segment, find corresponding mirror segment
|
||||
*/
|
||||
struct lv_segment *find_mirror_seg(struct lv_segment *seg);
|
||||
int fixup_imported_mirrors(struct volume_group *vg);
|
||||
|
||||
int insert_pvmove_mirrors(struct cmd_context *cmd,
|
||||
struct logical_volume *lv_mirr,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
@@ -21,98 +21,226 @@
|
||||
#include "activate.h"
|
||||
#include "lv_alloc.h"
|
||||
#include "lvm-string.h"
|
||||
#include "locking.h" /* FIXME Should not be used in this file */
|
||||
|
||||
struct lv_segment *find_mirror_seg(struct lv_segment *seg)
|
||||
{
|
||||
return seg->mirror_seg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure region size is compatible with volume size.
|
||||
*/
|
||||
uint32_t adjusted_mirror_region_size(uint32_t extent_size, uint32_t extents,
|
||||
uint32_t region_size)
|
||||
{
|
||||
uint32_t region_max;
|
||||
|
||||
region_max = (1 << (ffs(extents) - 1)) * extent_size;
|
||||
|
||||
if (region_max < region_size) {
|
||||
region_size = region_max;
|
||||
log_print("Using reduced mirror region size of %" PRIu32
|
||||
" sectors", region_max);
|
||||
return region_max;
|
||||
}
|
||||
|
||||
return region_size;
|
||||
}
|
||||
|
||||
static void _move_lv_segments(struct logical_volume *lv_to, struct logical_volume *lv_from)
|
||||
{
|
||||
struct lv_segment *seg;
|
||||
|
||||
lv_to->segments = lv_from->segments;
|
||||
lv_to->segments.n->p = &lv_to->segments;
|
||||
lv_to->segments.p->n = &lv_to->segments;
|
||||
|
||||
list_iterate_items(seg, &lv_to->segments)
|
||||
seg->lv = lv_to;
|
||||
|
||||
/* FIXME set or reset seg->mirror_seg (according to status)? */
|
||||
|
||||
list_init(&lv_from->segments);
|
||||
|
||||
lv_to->le_count = lv_from->le_count;
|
||||
lv_to->size = lv_from->size;
|
||||
|
||||
lv_from->le_count = 0;
|
||||
lv_from->size = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reduce mirrored_seg to num_mirrors images.
|
||||
*/
|
||||
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors)
|
||||
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
|
||||
struct list *removable_pvs, int remove_log)
|
||||
{
|
||||
uint32_t m;
|
||||
uint32_t s, s1;
|
||||
struct logical_volume *sub_lv;
|
||||
struct logical_volume *log_lv = NULL;
|
||||
struct logical_volume *lv1 = NULL;
|
||||
struct physical_volume *pv;
|
||||
struct lv_segment *seg;
|
||||
struct lv_segment_area area;
|
||||
int all_pvs_removable, pv_found;
|
||||
struct pv_list *pvl;
|
||||
uint32_t old_area_count = mirrored_seg->area_count;
|
||||
uint32_t new_area_count = mirrored_seg->area_count;
|
||||
|
||||
log_very_verbose("Reducing mirror set from %" PRIu32 " to %"
|
||||
PRIu32 " image(s)%s.",
|
||||
old_area_count, num_mirrors,
|
||||
remove_log ? " and no log volume" : "");
|
||||
|
||||
/* Move removable_pvs to end of array */
|
||||
if (removable_pvs) {
|
||||
for (s = 0; s < mirrored_seg->area_count; s++) {
|
||||
all_pvs_removable = 1;
|
||||
sub_lv = seg_lv(mirrored_seg, s);
|
||||
list_iterate_items(seg, &sub_lv->segments) {
|
||||
for (s1 = 0; s1 < seg->area_count; s1++) {
|
||||
if (seg_type(seg, s1) != AREA_PV)
|
||||
/* FIXME Recurse for AREA_LV */
|
||||
continue;
|
||||
|
||||
pv = seg_pv(seg, s1);
|
||||
|
||||
pv_found = 0;
|
||||
list_iterate_items(pvl, removable_pvs) {
|
||||
if (pv->dev->dev == pvl->pv->dev->dev) {
|
||||
pv_found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!pv_found) {
|
||||
all_pvs_removable = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!all_pvs_removable)
|
||||
break;
|
||||
}
|
||||
if (all_pvs_removable) {
|
||||
/* Swap segment to end */
|
||||
new_area_count--;
|
||||
area = mirrored_seg->areas[new_area_count];
|
||||
mirrored_seg->areas[new_area_count] = mirrored_seg->areas[s];
|
||||
mirrored_seg->areas[s] = area;
|
||||
}
|
||||
/* Found enough matches? */
|
||||
if (new_area_count == num_mirrors)
|
||||
break;
|
||||
}
|
||||
if (new_area_count == mirrored_seg->area_count) {
|
||||
log_error("No mirror images found using specified PVs.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (m = num_mirrors; m < mirrored_seg->area_count; m++) {
|
||||
seg_lv(mirrored_seg, m)->status &= ~MIRROR_IMAGE;
|
||||
seg_lv(mirrored_seg, m)->status |= VISIBLE_LV;
|
||||
}
|
||||
|
||||
mirrored_seg->area_count = num_mirrors;
|
||||
|
||||
/* If no more mirrors, remove mirror layer */
|
||||
if (num_mirrors == 1) {
|
||||
lv1 = seg_lv(mirrored_seg, 0);
|
||||
_move_lv_segments(mirrored_seg->lv, lv1);
|
||||
mirrored_seg->lv->status &= ~MIRRORED;
|
||||
remove_log = 1;
|
||||
}
|
||||
|
||||
if (remove_log) {
|
||||
log_lv = mirrored_seg->log_lv;
|
||||
mirrored_seg->log_lv = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* To successfully remove these unwanted LVs we need to
|
||||
* remove the LVs from the mirror set, commit that metadata
|
||||
* then deactivate and remove them fully.
|
||||
*/
|
||||
|
||||
/* FIXME lv1 has no segments here so shouldn't be written to disk! */
|
||||
|
||||
if (!vg_write(mirrored_seg->lv->vg)) {
|
||||
log_error("intermediate VG write failed.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!suspend_lv(mirrored_seg->lv->vg->cmd, mirrored_seg->lv)) {
|
||||
log_error("Failed to lock %s", mirrored_seg->lv->name);
|
||||
vg_revert(mirrored_seg->lv->vg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!vg_commit(mirrored_seg->lv->vg)) {
|
||||
resume_lv(mirrored_seg->lv->vg->cmd, mirrored_seg->lv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_very_verbose("Updating \"%s\" in kernel", mirrored_seg->lv->name);
|
||||
|
||||
if (!resume_lv(mirrored_seg->lv->vg->cmd, mirrored_seg->lv)) {
|
||||
log_error("Problem reactivating %s", mirrored_seg->lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Delete the 'orphan' LVs */
|
||||
for (m = num_mirrors; m < old_area_count; m++) {
|
||||
if (!deactivate_lv(mirrored_seg->lv->vg->cmd, seg_lv(mirrored_seg, m))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lv_remove(seg_lv(mirrored_seg, m))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
mirrored_seg->area_count = num_mirrors;
|
||||
if (lv1) {
|
||||
if (!deactivate_lv(mirrored_seg->lv->vg->cmd, lv1)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lv_remove(lv1)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (log_lv) {
|
||||
if (!deactivate_lv(mirrored_seg->lv->vg->cmd, log_lv)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lv_remove(log_lv)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
static int _create_layers_for_mirror(struct alloc_handle *ah,
|
||||
uint32_t first_area,
|
||||
uint32_t num_mirrors,
|
||||
struct logical_volume *lv,
|
||||
struct segment_type *segtype,
|
||||
struct logical_volume **img_lvs)
|
||||
{
|
||||
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. "
|
||||
@@ -129,23 +257,61 @@ int create_mirror_layers(struct alloc_handle *ah,
|
||||
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. "
|
||||
ALLOC_INHERIT, 0, lv->vg))) {
|
||||
log_error("Aborting. Failed to create mirror image LV. "
|
||||
"Remove new LV and retry.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lv_add_segment(ah, m, 1, img_lvs[m],
|
||||
if (m < first_area)
|
||||
continue;
|
||||
|
||||
if (!lv_add_segment(ah, m - first_area, 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 "
|
||||
log_error("Aborting. Failed to add mirror image segment "
|
||||
"to %s. Remove new LV and retry.",
|
||||
img_lvs[m]->name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct logical_volume **img_lvs;
|
||||
|
||||
if (!(img_lvs = alloca(sizeof(*img_lvs) * num_mirrors))) {
|
||||
log_error("img_lvs allocation failed. "
|
||||
"Remove new LV and retry.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_create_layers_for_mirror(ah, first_area, num_mirrors, lv,
|
||||
segtype, img_lvs)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Already got the parent mirror segment? */
|
||||
if (lv->status & MIRRORED)
|
||||
return lv_add_more_mirrored_areas(lv, img_lvs, num_mirrors,
|
||||
MIRROR_IMAGE);
|
||||
|
||||
/* Already got a non-mirrored area to be converted? */
|
||||
if (first_area)
|
||||
_move_lv_segments(img_lvs[0], lv);
|
||||
|
||||
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. "
|
||||
@@ -153,9 +319,35 @@ int create_mirror_layers(struct alloc_handle *ah,
|
||||
return 0;
|
||||
}
|
||||
|
||||
lv->status |= MIRRORED;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int add_mirror_layers(struct alloc_handle *ah,
|
||||
uint32_t num_mirrors,
|
||||
uint32_t existing_mirrors,
|
||||
struct logical_volume *lv,
|
||||
struct segment_type *segtype)
|
||||
{
|
||||
struct logical_volume **img_lvs;
|
||||
|
||||
if (!(img_lvs = alloca(sizeof(*img_lvs) * num_mirrors))) {
|
||||
log_error("img_lvs allocation failed. "
|
||||
"Remove new LV and retry.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_create_layers_for_mirror(ah, 0, num_mirrors,
|
||||
lv, segtype,
|
||||
img_lvs)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return lv_add_more_mirrored_areas(lv, img_lvs, num_mirrors, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace any LV segments on given PV with temporary mirror.
|
||||
* Returns list of LVs changed.
|
||||
@@ -263,7 +455,7 @@ int insert_pvmove_mirrors(struct cmd_context *cmd,
|
||||
|
||||
/* First time, add LV to list of LVs affected */
|
||||
if (!lv_used) {
|
||||
if (!(lvl = pool_alloc(cmd->mem, sizeof(*lvl)))) {
|
||||
if (!(lvl = dm_pool_alloc(cmd->mem, sizeof(*lvl)))) {
|
||||
log_error("lv_list alloc failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -475,7 +667,7 @@ struct list *lvs_using_lv(struct cmd_context *cmd, struct volume_group *vg,
|
||||
struct lv_segment *seg;
|
||||
uint32_t s;
|
||||
|
||||
if (!(lvs = pool_alloc(cmd->mem, sizeof(*lvs)))) {
|
||||
if (!(lvs = dm_pool_alloc(cmd->mem, sizeof(*lvs)))) {
|
||||
log_error("lvs list alloc failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -494,7 +686,7 @@ struct list *lvs_using_lv(struct cmd_context *cmd, struct volume_group *vg,
|
||||
if (seg_type(seg, s) != AREA_LV ||
|
||||
seg_lv(seg, s) != lv)
|
||||
continue;
|
||||
if (!(lvl = pool_alloc(cmd->mem, sizeof(*lvl)))) {
|
||||
if (!(lvl = dm_pool_alloc(cmd->mem, sizeof(*lvl)))) {
|
||||
log_error("lv_list alloc failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -526,3 +718,31 @@ float copy_percent(struct logical_volume *lv_mirr)
|
||||
|
||||
return denominator ? (float) numerator *100 / denominator : 100.0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fixup mirror pointers after single-pass segment import
|
||||
*/
|
||||
int fixup_imported_mirrors(struct volume_group *vg)
|
||||
{
|
||||
struct lv_list *lvl;
|
||||
struct lv_segment *seg;
|
||||
uint32_t s;
|
||||
|
||||
list_iterate_items(lvl, &vg->lvs) {
|
||||
list_iterate_items(seg, &lvl->lv->segments) {
|
||||
if (seg->segtype !=
|
||||
get_segtype_from_string(vg->cmd, "mirror"))
|
||||
continue;
|
||||
|
||||
if (seg->log_lv)
|
||||
first_seg(seg->log_lv)->mirror_seg = seg;
|
||||
for (s = 0; s < seg->area_count; s++)
|
||||
if (seg_type(seg, s) == AREA_LV)
|
||||
first_seg(seg_lv(seg, s))->mirror_seg
|
||||
= seg;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,10 +13,9 @@
|
||||
*/
|
||||
|
||||
#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);
|
||||
int alloc_pv_segment_whole_pv(struct dm_pool *mem, struct physical_volume *pv);
|
||||
int peg_dup(struct dm_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,
|
||||
|
||||
@@ -14,12 +14,11 @@
|
||||
*/
|
||||
|
||||
#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,
|
||||
static struct pv_segment *_alloc_pv_segment(struct dm_pool *mem,
|
||||
struct physical_volume *pv,
|
||||
uint32_t pe, uint32_t len,
|
||||
struct lv_segment *lvseg,
|
||||
@@ -27,7 +26,7 @@ static struct pv_segment *_alloc_pv_segment(struct pool *mem,
|
||||
{
|
||||
struct pv_segment *peg;
|
||||
|
||||
if (!(peg = pool_zalloc(mem, sizeof(*peg)))) {
|
||||
if (!(peg = dm_pool_zalloc(mem, sizeof(*peg)))) {
|
||||
log_error("pv_segment allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -43,7 +42,7 @@ static struct pv_segment *_alloc_pv_segment(struct pool *mem,
|
||||
return peg;
|
||||
}
|
||||
|
||||
int alloc_pv_segment_whole_pv(struct pool *mem, struct physical_volume *pv)
|
||||
int alloc_pv_segment_whole_pv(struct dm_pool *mem, struct physical_volume *pv)
|
||||
{
|
||||
struct pv_segment *peg;
|
||||
|
||||
@@ -61,7 +60,7 @@ int alloc_pv_segment_whole_pv(struct pool *mem, struct physical_volume *pv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int peg_dup(struct pool *mem, struct list *peg_new, struct list *peg_old)
|
||||
int peg_dup(struct dm_pool *mem, struct list *peg_new, struct list *peg_old)
|
||||
{
|
||||
struct pv_segment *peg, *pego;
|
||||
|
||||
@@ -302,3 +301,98 @@ int check_pv_segments(struct volume_group *vg)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _reduce_pv(struct physical_volume *pv, struct volume_group *vg, uint32_t new_pe_count)
|
||||
{
|
||||
struct pv_segment *peg, *pegt;
|
||||
uint32_t old_pe_count = pv->pe_count;
|
||||
|
||||
if (new_pe_count < pv->pe_alloc_count) {
|
||||
log_error("%s: cannot resize to %" PRIu32 " extents "
|
||||
"as %" PRIu32 " are allocated.",
|
||||
dev_name(pv->dev), new_pe_count,
|
||||
pv->pe_alloc_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check PEs to be removed are not already allocated */
|
||||
list_iterate_items(peg, &pv->segments) {
|
||||
if (peg->pe + peg->len <= new_pe_count)
|
||||
continue;
|
||||
|
||||
if (peg->lvseg) {
|
||||
log_error("%s: cannot resize to %" PRIu32 " extents as "
|
||||
"later ones are allocated.",
|
||||
dev_name(pv->dev), new_pe_count);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pv_split_segment(pv, new_pe_count)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
list_iterate_items_safe(peg, pegt, &pv->segments) {
|
||||
if (peg->pe + peg->len > new_pe_count)
|
||||
list_del(&peg->list);
|
||||
}
|
||||
|
||||
pv->pe_count = new_pe_count;
|
||||
|
||||
vg->extent_count -= (old_pe_count - new_pe_count);
|
||||
vg->free_count -= (old_pe_count - new_pe_count);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _extend_pv(struct physical_volume *pv, struct volume_group *vg,
|
||||
uint32_t new_pe_count)
|
||||
{
|
||||
struct pv_segment *peg;
|
||||
uint32_t old_pe_count = pv->pe_count;
|
||||
|
||||
if ((uint64_t) new_pe_count * pv->pe_size > pv->size ) {
|
||||
log_error("%s: cannot resize to %" PRIu32 " extents as there "
|
||||
"is only room for %" PRIu64 ".", dev_name(pv->dev),
|
||||
new_pe_count, pv->size / pv->pe_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
peg = _alloc_pv_segment(pv->fmt->cmd->mem, pv,
|
||||
old_pe_count,
|
||||
new_pe_count - old_pe_count,
|
||||
NULL, 0);
|
||||
list_add(&pv->segments, &peg->list);
|
||||
|
||||
pv->pe_count = new_pe_count;
|
||||
|
||||
vg->extent_count += (new_pe_count - old_pe_count);
|
||||
vg->free_count += (new_pe_count - old_pe_count);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Resize a PV in a VG, adding or removing segments as needed.
|
||||
* New size must fit within pv->size.
|
||||
*/
|
||||
int pv_resize(struct physical_volume *pv,
|
||||
struct volume_group *vg,
|
||||
uint32_t new_pe_count)
|
||||
{
|
||||
if ((new_pe_count == pv->pe_count)) {
|
||||
log_verbose("No change to size of physical volume %s.",
|
||||
dev_name(pv->dev));
|
||||
return 1;
|
||||
}
|
||||
|
||||
log_verbose("Resizing physical volume %s from %" PRIu32
|
||||
" to %" PRIu32 " extents.",
|
||||
dev_name(pv->dev), pv->pe_count, new_pe_count);
|
||||
|
||||
if (new_pe_count > pv->pe_count)
|
||||
return _extend_pv(pv, vg, new_pe_count);
|
||||
else
|
||||
return _reduce_pv(pv, vg, new_pe_count);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
#include "lib.h"
|
||||
#include "pv_map.h"
|
||||
#include "hash.h"
|
||||
#include "pv_alloc.h"
|
||||
|
||||
/*
|
||||
@@ -33,12 +32,12 @@ static void _insert_area(struct list *head, struct pv_area *a)
|
||||
list_add(&pva->list, &a->list);
|
||||
}
|
||||
|
||||
static int _create_single_area(struct pool *mem, struct pv_map *pvm,
|
||||
static int _create_single_area(struct dm_pool *mem, struct pv_map *pvm,
|
||||
uint32_t start, uint32_t length)
|
||||
{
|
||||
struct pv_area *pva;
|
||||
|
||||
if (!(pva = pool_zalloc(mem, sizeof(*pva)))) {
|
||||
if (!(pva = dm_pool_zalloc(mem, sizeof(*pva)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -53,7 +52,7 @@ static int _create_single_area(struct pool *mem, struct pv_map *pvm,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _create_alloc_areas_for_pv(struct pool *mem, struct pv_map *pvm,
|
||||
static int _create_alloc_areas_for_pv(struct dm_pool *mem, struct pv_map *pvm,
|
||||
uint32_t start, uint32_t count)
|
||||
{
|
||||
struct pv_segment *peg;
|
||||
@@ -98,7 +97,7 @@ static int _create_alloc_areas_for_pv(struct pool *mem, struct pv_map *pvm,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _create_all_areas_for_pv(struct pool *mem, struct pv_map *pvm,
|
||||
static int _create_all_areas_for_pv(struct dm_pool *mem, struct pv_map *pvm,
|
||||
struct list *pe_ranges)
|
||||
{
|
||||
struct pe_range *aa;
|
||||
@@ -125,7 +124,7 @@ static int _create_all_areas_for_pv(struct pool *mem, struct pv_map *pvm,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _create_maps(struct pool *mem, struct list *pvs, struct list *pvms)
|
||||
static int _create_maps(struct dm_pool *mem, struct list *pvs, struct list *pvms)
|
||||
{
|
||||
struct pv_map *pvm;
|
||||
struct pv_list *pvl;
|
||||
@@ -134,7 +133,7 @@ static int _create_maps(struct pool *mem, struct list *pvs, struct list *pvms)
|
||||
if (!(pvl->pv->status & ALLOCATABLE_PV))
|
||||
continue;
|
||||
|
||||
if (!(pvm = pool_zalloc(mem, sizeof(*pvm)))) {
|
||||
if (!(pvm = dm_pool_zalloc(mem, sizeof(*pvm)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -156,12 +155,12 @@ static int _create_maps(struct pool *mem, struct list *pvs, struct list *pvms)
|
||||
/*
|
||||
* Create list of PV areas available for this particular allocation
|
||||
*/
|
||||
struct list *create_pv_maps(struct pool *mem, struct volume_group *vg,
|
||||
struct list *create_pv_maps(struct dm_pool *mem, struct volume_group *vg,
|
||||
struct list *allocatable_pvs)
|
||||
{
|
||||
struct list *pvms;
|
||||
|
||||
if (!(pvms = pool_zalloc(mem, sizeof(*pvms)))) {
|
||||
if (!(pvms = dm_pool_zalloc(mem, sizeof(*pvms)))) {
|
||||
log_error("create_pv_maps alloc failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -171,7 +170,7 @@ struct list *create_pv_maps(struct pool *mem, struct volume_group *vg,
|
||||
if (!_create_maps(mem, allocatable_pvs, pvms)) {
|
||||
log_error("Couldn't create physical volume maps in %s",
|
||||
vg->name);
|
||||
pool_free(mem, pvms);
|
||||
dm_pool_free(mem, pvms);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
#define _LVM_PV_MAP_H
|
||||
|
||||
#include "metadata.h"
|
||||
#include "bitset.h"
|
||||
#include "pool.h"
|
||||
|
||||
/*
|
||||
* The in core rep. only stores a mapping from
|
||||
@@ -46,7 +44,7 @@ struct pv_map {
|
||||
/*
|
||||
* Find intersection between available_pvs and free space in VG
|
||||
*/
|
||||
struct list *create_pv_maps(struct pool *mem, struct volume_group *vg,
|
||||
struct list *create_pv_maps(struct dm_pool *mem, struct volume_group *vg,
|
||||
struct list *allocatable_pvs);
|
||||
|
||||
void consume_pv_area(struct pv_area *area, uint32_t to_go);
|
||||
|
||||
@@ -22,7 +22,6 @@ struct config_tree;
|
||||
struct lv_segment;
|
||||
struct formatter;
|
||||
struct config_node;
|
||||
struct hash_table;
|
||||
struct dev_manager;
|
||||
|
||||
/* Feature flags */
|
||||
@@ -32,12 +31,14 @@ struct dev_manager;
|
||||
#define SEG_SNAPSHOT 0x00000008
|
||||
#define SEG_FORMAT1_SUPPORT 0x00000010
|
||||
#define SEG_VIRTUAL 0x00000020
|
||||
#define SEG_CANNOT_BE_ZEROED 0x00000040
|
||||
|
||||
#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 seg_cannot_be_zeroed(seg) ((seg)->segtype->flags & SEG_CANNOT_BE_ZEROED ? 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)
|
||||
@@ -62,16 +63,15 @@ struct segtype_handler {
|
||||
uint32_t *area_count);
|
||||
int (*text_import) (struct lv_segment * seg,
|
||||
const struct config_node * sn,
|
||||
struct hash_table * pv_hash);
|
||||
struct dm_hash_table * pv_hash);
|
||||
int (*merge_segments) (struct lv_segment * seg1,
|
||||
struct lv_segment * seg2);
|
||||
int (*compose_target_line) (struct dev_manager * dm, struct pool * mem,
|
||||
struct config_tree * cft,
|
||||
void **target_state,
|
||||
struct lv_segment * seg, char *params,
|
||||
size_t paramsize, const char **target,
|
||||
int *pos, uint32_t *pvmove_mirror_count);
|
||||
int (*target_percent) (void **target_state, struct pool * mem,
|
||||
int (*add_target_line) (struct dev_manager *dm, struct dm_pool *mem,
|
||||
struct config_tree *cft, void **target_state,
|
||||
struct lv_segment *seg,
|
||||
struct dm_tree_node *node, uint64_t len,
|
||||
uint32_t *pvmove_mirror_count);
|
||||
int (*target_percent) (void **target_state, struct dm_pool * mem,
|
||||
struct config_tree * cft,
|
||||
struct lv_segment * seg, char *params,
|
||||
uint64_t *total_numerator,
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
#include "pool.h"
|
||||
#include "list.h"
|
||||
#include "toolcontext.h"
|
||||
#include "metadata.h"
|
||||
#include "segtype.h"
|
||||
@@ -46,6 +44,7 @@ static const char *_name(const struct lv_segment *seg)
|
||||
static void _display(const struct lv_segment *seg)
|
||||
{
|
||||
const char *size;
|
||||
uint32_t s;
|
||||
|
||||
log_print(" Mirrors\t\t%u", seg->area_count);
|
||||
log_print(" Mirror size\t\t%u", seg->area_len);
|
||||
@@ -61,8 +60,9 @@ static void _display(const struct lv_segment *seg)
|
||||
|
||||
log_print(" Mirror original:");
|
||||
display_stripe(seg, 0, " ");
|
||||
log_print(" Mirror destination:");
|
||||
display_stripe(seg, 1, " ");
|
||||
log_print(" Mirror destinations:");
|
||||
for (s = 1; s < seg->area_count; s++)
|
||||
display_stripe(seg, s, " ");
|
||||
log_print(" ");
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ static int _text_import_area_count(struct config_node *sn, uint32_t *area_count)
|
||||
}
|
||||
|
||||
static int _text_import(struct lv_segment *seg, const struct config_node *sn,
|
||||
struct hash_table *pv_hash)
|
||||
struct dm_hash_table *pv_hash)
|
||||
{
|
||||
const struct config_node *cn;
|
||||
char *logname = NULL;
|
||||
@@ -147,12 +147,12 @@ static int _text_export(const struct lv_segment *seg, struct formatter *f)
|
||||
}
|
||||
|
||||
#ifdef DEVMAPPER_SUPPORT
|
||||
static struct mirror_state *_init_target(struct pool *mem,
|
||||
static struct mirror_state *_init_target(struct dm_pool *mem,
|
||||
struct config_tree *cft)
|
||||
{
|
||||
struct mirror_state *mirr_state;
|
||||
|
||||
if (!(mirr_state = pool_alloc(mem, sizeof(*mirr_state)))) {
|
||||
if (!(mirr_state = dm_pool_alloc(mem, sizeof(*mirr_state)))) {
|
||||
log_error("struct mirr_state allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
@@ -165,91 +165,48 @@ static struct mirror_state *_init_target(struct pool *mem,
|
||||
return mirr_state;
|
||||
}
|
||||
|
||||
static int _compose_target_line(struct dev_manager *dm, struct pool *mem,
|
||||
struct config_tree *cft, void **target_state,
|
||||
struct lv_segment *seg, char *params,
|
||||
size_t paramsize, const char **target, int *pos,
|
||||
uint32_t *pvmove_mirror_count)
|
||||
{
|
||||
struct mirror_state *mirr_state;
|
||||
int mirror_status = MIRR_RUNNING;
|
||||
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);
|
||||
|
||||
mirr_state = *target_state;
|
||||
|
||||
/* mirror log_type #log_params [log_params]*
|
||||
* #mirrors [device offset]+
|
||||
*/
|
||||
if (seg->status & PVMOVE) {
|
||||
if (seg->extents_copied == seg->area_len) {
|
||||
mirror_status = MIRR_COMPLETED;
|
||||
start_area = 1;
|
||||
} else if ((*pvmove_mirror_count)++) {
|
||||
mirror_status = MIRR_DISABLED;
|
||||
areas = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (mirror_status != MIRR_RUNNING) {
|
||||
*target = "linear";
|
||||
} else {
|
||||
*target = "mirror";
|
||||
|
||||
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->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 ((ret = compose_log_line(dm, seg, params, paramsize, pos,
|
||||
areas, region_size)) <= 0) {
|
||||
stack;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return compose_areas_line(dm, seg, params, paramsize, pos, start_area,
|
||||
areas);
|
||||
}
|
||||
|
||||
static int _target_percent(void **target_state, struct pool *mem,
|
||||
static int _target_percent(void **target_state, struct dm_pool *mem,
|
||||
struct config_tree *cft, struct lv_segment *seg,
|
||||
char *params, uint64_t *total_numerator,
|
||||
uint64_t *total_denominator, float *percent)
|
||||
{
|
||||
struct mirror_state *mirr_state;
|
||||
uint64_t numerator, denominator;
|
||||
unsigned mirror_count, m;
|
||||
int used;
|
||||
char *pos = params;
|
||||
|
||||
if (!*target_state)
|
||||
*target_state = _init_target(mem, cft);
|
||||
|
||||
mirr_state = *target_state;
|
||||
|
||||
/* Status line: <#mirrors> (maj:min)+ <synced>/<total_regions> */
|
||||
log_debug("Mirror status: %s", params);
|
||||
if (sscanf(params, "%*d %*x:%*x %*x:%*x %" PRIu64
|
||||
"/%" PRIu64, &numerator, &denominator) != 2) {
|
||||
log_error("Failure parsing mirror status: %s", params);
|
||||
|
||||
if (sscanf(pos, "%u %n", &mirror_count, &used) != 1) {
|
||||
log_error("Failure parsing mirror status mirror count: %s",
|
||||
params);
|
||||
return 0;
|
||||
}
|
||||
pos += used;
|
||||
|
||||
for (m = 0; m < mirror_count; m++) {
|
||||
if (sscanf(pos, "%*x:%*x %n", &used) != 0) {
|
||||
log_error("Failure parsing mirror status devices: %s",
|
||||
params);
|
||||
return 0;
|
||||
}
|
||||
pos += used;
|
||||
}
|
||||
|
||||
if (sscanf(pos, "%" PRIu64 "/%" PRIu64 "%n", &numerator, &denominator,
|
||||
&used) != 2) {
|
||||
log_error("Failure parsing mirror status fraction: %s", params);
|
||||
return 0;
|
||||
}
|
||||
pos += used;
|
||||
|
||||
*total_numerator += numerator;
|
||||
*total_denominator += denominator;
|
||||
|
||||
@@ -259,13 +216,109 @@ static int _target_percent(void **target_state, struct pool *mem,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _add_log(struct dev_manager *dm, struct lv_segment *seg,
|
||||
struct dm_tree_node *node, uint32_t area_count, uint32_t region_size)
|
||||
{
|
||||
unsigned clustered = 0;
|
||||
char *log_dlid = NULL;
|
||||
|
||||
/*
|
||||
* Use clustered mirror log for non-exclusive activation
|
||||
* in clustered VG.
|
||||
*/
|
||||
if ((!(seg->lv->status & ACTIVATE_EXCL) &&
|
||||
(seg->lv->vg->status & CLUSTERED)))
|
||||
clustered = 1;
|
||||
|
||||
if (seg->log_lv &&
|
||||
!(log_dlid = build_dlid(dm, seg->log_lv->lvid.s, NULL))) {
|
||||
log_error("Failed to build uuid for log LV %s.",
|
||||
seg->log_lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME Add sync parm? */
|
||||
return dm_tree_node_add_mirror_target_log(node, region_size, clustered, log_dlid, area_count);
|
||||
}
|
||||
|
||||
static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
|
||||
struct config_tree *cft, void **target_state,
|
||||
struct lv_segment *seg,
|
||||
struct dm_tree_node *node, uint64_t len,
|
||||
uint32_t *pvmove_mirror_count)
|
||||
{
|
||||
struct mirror_state *mirr_state;
|
||||
uint32_t area_count = seg->area_count;
|
||||
int start_area = 0u;
|
||||
int mirror_status = MIRR_RUNNING;
|
||||
uint32_t region_size, region_max;
|
||||
int r;
|
||||
|
||||
if (!*target_state)
|
||||
*target_state = _init_target(mem, cft);
|
||||
|
||||
mirr_state = *target_state;
|
||||
|
||||
/*
|
||||
* For pvmove, only have one mirror segment RUNNING at once.
|
||||
* Segments before this are COMPLETED and use 2nd area.
|
||||
* Segments after this are DISABLED and use 1st area.
|
||||
*/
|
||||
if (seg->status & PVMOVE) {
|
||||
if (seg->extents_copied == seg->area_len) {
|
||||
mirror_status = MIRR_COMPLETED;
|
||||
start_area = 1;
|
||||
} else if ((*pvmove_mirror_count)++) {
|
||||
mirror_status = MIRR_DISABLED;
|
||||
area_count = 1;
|
||||
}
|
||||
/* else MIRR_RUNNING */
|
||||
}
|
||||
|
||||
if (mirror_status != MIRR_RUNNING) {
|
||||
if (!dm_tree_node_add_linear_target(node, len))
|
||||
return_0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
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->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 (!dm_tree_node_add_mirror_target(node, len))
|
||||
return_0;
|
||||
|
||||
if ((r = _add_log(dm, seg, node, area_count, region_size)) <= 0) {
|
||||
stack;
|
||||
return r;
|
||||
}
|
||||
|
||||
done:
|
||||
return add_areas_line(dm, seg, node, start_area, area_count);
|
||||
}
|
||||
|
||||
static int _target_present(void)
|
||||
{
|
||||
static int checked = 0;
|
||||
static int present = 0;
|
||||
|
||||
if (!checked)
|
||||
present = target_present("mirror");
|
||||
present = target_present("mirror", 1);
|
||||
|
||||
checked = 1;
|
||||
|
||||
@@ -275,7 +328,7 @@ static int _target_present(void)
|
||||
|
||||
static void _destroy(const struct segment_type *segtype)
|
||||
{
|
||||
dbg_free((void *) segtype);
|
||||
dm_free((void *) segtype);
|
||||
}
|
||||
|
||||
static struct segtype_handler _mirrored_ops = {
|
||||
@@ -285,7 +338,7 @@ static struct segtype_handler _mirrored_ops = {
|
||||
text_import:_text_import,
|
||||
text_export:_text_export,
|
||||
#ifdef DEVMAPPER_SUPPORT
|
||||
compose_target_line:_compose_target_line,
|
||||
add_target_line:_add_target_line,
|
||||
target_percent:_target_percent,
|
||||
target_present:_target_present,
|
||||
#endif
|
||||
@@ -299,7 +352,7 @@ struct segment_type *init_segtype(struct cmd_context *cmd);
|
||||
struct segment_type *init_segtype(struct cmd_context *cmd)
|
||||
#endif
|
||||
{
|
||||
struct segment_type *segtype = dbg_malloc(sizeof(*segtype));
|
||||
struct segment_type *segtype = dm_malloc(sizeof(*segtype));
|
||||
|
||||
if (!segtype) {
|
||||
stack;
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include "log.h"
|
||||
#include "dbg_malloc.h"
|
||||
#include "intl.h"
|
||||
#include "lvm-types.h"
|
||||
|
||||
#include <libdevmapper.h>
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user