1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-12-24 16:23:50 +03:00

Compare commits

..

1971 Commits

Author SHA1 Message Date
Alasdair Kergon
2d0b95cd49 pre-release 2010-08-18 20:57:10 +00:00
Peter Rajnoha
e2bc7a277e Fix dm-mod autoloading logic to not assume control node is set correctly.
We can't rely on the fact that udev should prepare the node with right major
and minor number to trigger the module autoloading. We have to take into
account that the node could be missing or it could exist with improper
major and minor number assigned (e.g. from previous kernel versions in
an environment with static nodes and without udev). Make any corrections
if needed!
2010-08-18 13:11:56 +00:00
Jonathan Earl Brassow
adbd3e478b Fix for bug 596453: multiple mirror image failures cause lvm repair...
The lvm repair issues I believe are the superficial symptoms of this
bug - there are worse issues that are not as clearly seen.  From my
inline comments:
* If the mirror was successfully recovered, we want to always
* force every machine to write to all devices - otherwise,
* corruption will occur.  Here's how:
*    Node1 suffers a failure and marks a region out-of-sync
*    Node2 attempts a write, gets by is_remote_recovering,
*          and queries the sync status of the region - finding
*          it out-of-sync.
*    Node2 thinks the write should be a nosync write, but it
*          hasn't suffered the drive failure that Node1 has yet.
*          It then issues a generic_make_request directly to
*          the primary image only - which is exactly the device
*          that has suffered the failure.
*    Node2 suffers a lost write - which completely bypasses the
*          mirror layer because it had gone through generic_m_r.
*    The file system will likely explode at this point due to
*    I/O errors.  If it wasn't the primary that failed, it is
*    easily possible in this case to issue writes to just one
*    of the remaining images - also leaving the mirror inconsistent.
*
* We let in_sync() return 1 in a cluster regardless of what is
* in the bitmap once recovery has successfully completed on a
* mirror.  This ensures the mirroring code will continue to
* attempt to write to all mirror images.  The worst that can
* happen for reads is that additional read attempts may be
* taken.
2010-08-17 23:56:23 +00:00
Alasdair Kergon
7b0804c22f Attempt to fix buildbot failure in t-lvconvert-mirror.sh due to failing to
wait for mirror to get into sync before running subsequent command.
2010-08-17 22:01:41 +00:00
Alasdair Kergon
47dfe904ab Use 'SINGLENODE' instead of 'dead' in clvmd singlenode messages.
Ignore snapshots when performing mirror recovery beneath an origin.
Pass LCK_ORIGIN_ONLY flag around cluster.
Add suspend_lv_origin and resume_lv_origin using LCK_ORIGIN_ONLY.
2010-08-17 19:25:05 +00:00
Alasdair Kergon
7f5b44b423 Allow internal suspend and resume of origin without its snapshots. 2010-08-17 16:25:32 +00:00
Alasdair Kergon
c16ca69070 Fix dev_manager_transient to access -real device not snapshot-origin. (brassow)
Another reminder why cloning functions impedes maintenance.
2010-08-17 01:51:12 +00:00
Alasdair Kergon
394c628931 Monitor origin -real device below snapshot instead of overlay device. (brassow) 2010-08-17 01:16:41 +00:00
Alasdair Kergon
43695024af Don't really change monitoring status when in test mode. 2010-08-16 23:29:09 +00:00
Mike Snitzer
1678de7f51 Add some v1 to v2 metadata upgrade testing. 2010-08-16 23:21:20 +00:00
Alasdair Kergon
063436c82b Various small cleanups and fixes related to monitoring. 2010-08-16 22:54:35 +00:00
Alasdair Kergon
59585550a7 Remove superfluous NULL pointer tests before dm_free from dmeventd. 2010-08-16 18:19:46 +00:00
Jonathan Earl Brassow
51e294c501 Fix for bug 612291: dm devices of split off mirror images are not removed
DM devices were not handled properly on nodes in a cluster that were not
where the splitmirrors command was issued.  This was happening because
suspend_lv/resume_lv were being used in a place where activate_lv should
have been used.

When the suspend/resume are issued on (effectively) new LVs, their
'resource' (UUID) is not located in the lv_hash.  Thus, both operations
turn into no-ops.  You can see this from the output of clvmd from one
of the remote nodes:
<snip>
do_suspend_lv, lock not already held
<snip>
do_resume_lv, lock not already held

'activate_lv' enjoins the other nodes in the cluster to process the lock
and activate the new LV.  clvmd output from remote node as follows:
do_lock_lv: resource 'zMseY7CBuO3Ty09vXlplPAHzD0Y0CovjrTdv0R1VcwggMwPdYhutHErRcwm5Nd2S', cmd = 0x19 LCK_LV_ACTIVATE (READ|LV|NONBLOCK), flags = 0x84 (DMEVENTD_MONITOR ), memlock = 1
sync_lock: 'zMseY7CBuO3Ty09vXlplPAHzD0Y0CovjrTdv0R1VcwggMwPdYhutHErRcwm5Nd2S' mode:1 flags=1
sync_lock: returning lkid 27b0001

Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
Reviewed-by: Petr Rockai <prockai@redhat.com>
2010-08-16 18:02:14 +00:00
Alasdair Kergon
22ffec640d set DEFAULT_RUN_DIR (missed from earlier checkin?) 2010-08-16 17:49:26 +00:00
Peter Rajnoha
7ab3c4c091 WHATS_NEW_DM 2010-08-16 11:22:08 +00:00
Peter Rajnoha
19934a59b2 dm-mod autoloading support is in kernel 2.6.36 actually. 2010-08-16 11:13:18 +00:00
Peter Rajnoha
f3645e3f4b Fix udev rules to support udev database content generated by older rules.
This can happen with older rules (without support for synthesized events)
that are still part of initrd while using new udev rules in the system itself.

The consequence was that new udev rules incorrectly assumed that not having
DM_UDEV_PRIMARY_SOURCE_FLAG set always means the uevent is synthesized and
inappropriate (device is still not properly activated) and so it should be
ignored. However, initrd is not updated automatically while updating the
libdevmapper/udev rules in the system and so we end up with the rules not
detecting and setting crucial parts in the initrd environment and the rules
in the system that rely on the information that should have been stored in
udev db (which is incorrect in this configuration, of course).

The overall consequence is that the update of libdevmapper/lvm2 without
regenerating the initrd could end up with a boot failure! Ignoring the event
means removing any existing symlinks in /dev!

To fix this, increase udev rules version to make a difference. So from now on,
mark rules without proper support for synthesized events as
DM_UDEV_RULES_VSN="1" and 2 (or higher) if that support is included.
2010-08-12 13:41:18 +00:00
Peter Rajnoha
d818035d3a Reinstate detection of inappropriate uevent with DISK_RO set and suppress it.
We still need to detect this one! We're not so strict with CHANGE events as
with the ADD events while applying filters in the rules so this one would
pass and it would process the rules prematurely (because it appears *before*
the actual CHANGE event used when resuming a DM device while setting read-only
state at the same time).
2010-08-12 13:07:08 +00:00
Fabio M. Di Nitto
0cce8cfbaa Fix clvmd init script return code when executed as non-root user.
clvmd daemon itself does the right thing when invoked as non-root, by
returning 4.

The patch removes the use daemon function from
/etc/rc.d/init.d/functions that´s unnecessary and has th bad habit to
mask the return codes from the real daemon.

Add a simple and generic check to see if clvmd is executed by root or not.

Our stop/reload/restart paths in the init script are complex and not all
the tools involved in the process are guaranteed to return 4 if executed
by non-root against a process that´s running as root (for example kill
-TERM will return -1 and parsing the output to catch the error is
suboptimal at best).

https://bugzilla.redhat.com/show_bug.cgi?id=553381
2010-08-12 09:14:59 +00:00
Mike Snitzer
3e132d71f5 fix t-pvcreate-operation-md.sh to require kernel.org Linux >= 2.6.33 for
the final alignment_offset check.  In the future, might look to check
for the RHEL6 kernel too.
2010-08-12 04:56:05 +00:00
Mike Snitzer
2b3a4adff8 Change default alignment of pe_start to 1MB.
The new standard in the storage industry is to default alignment of data
areas to 1MB.  fdisk, parted, and mdadm have all been updated to this
default.

Update LVM to align the PV's data area start (pe_start) to 1MB.  This
provides a more useful default than the previous default of 64K (which
generally ended up being a 192K pe_start once the first metadata area
was created).

Before this patch:
# pvs -o name,vg_mda_size,pe_start
  PV         VMdaSize  1st PE
  /dev/sdd     188.00k 192.00k

After this patch:
# pvs -o name,vg_mda_size,pe_start
  PV         VMdaSize  1st PE
  /dev/sdd    1020.00k   1.00m

The heuristic for setting the default alignment for LVM data areas is:
- If the default value (1MB) is a multiple of the detected alignment
  then just use the default.
- Otherwise, use the detected value.

In practice this means we'll almost always use 1MB -- that is unless:
- the alignment was explicitly specified with --dataalignment
- or MD's full stripe width, or the {minimum,optimal}_io_size exceeds
  1MB
- or the specified/detected value is not a power-of-2
2010-08-12 04:11:48 +00:00
Mike Snitzer
de49d45568 Require --restorefile when using pvcreate --uuid.
Introduce --norestorefile to allow user to override the new requirement.

This can also be overridden with "devices/require_restorefile_with_uuid"
in lvm.conf -- however the default is 1.

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2010-08-12 04:08:59 +00:00
Peter Rajnoha
de5337b187 WHATS_NEW_DM 2010-08-11 13:12:31 +00:00
Peter Rajnoha
f0e82e4473 Recognise and give preference to md device partitions (blkext major).
We can already detect MD devices internally. But when using MD partitions,
these have "block extended major" (blkext) assigned (259). Blkext major
is also used in general, so we need to check whether the original device
is an MD device actually.
2010-08-11 12:14:23 +00:00
Petr Rockai
5a00c29f8a Update WHATS_NEW. 2010-08-09 14:06:03 +00:00
Petr Rockai
dd5d9aa6bc Never scan internal LVM devices. 2010-08-09 14:05:16 +00:00
Joe Thornber
40f03c4c2c [REGEX] fix a long standing off-by-one error (found by valgrind-pool) 2010-08-09 10:58:27 +00:00
Joe Thornber
1aaf8d589f [MM] Make valgrind aware of the pool allocators
./configure with --enable-valgrind-pool to enable this.
2010-08-09 10:56:01 +00:00
Joe Thornber
1b87c6ade7 [REGEX] fix bug in matcher that was causing segfault with chars of 0x80 and over. 2010-08-09 10:30:52 +00:00
Joe Thornber
d52e9c7704 [REGEX] Parse regexes that contain chars with value > 0x80
This is a long standing issue.  Fixed by casting a char value to
unsigned char before using it as an index into a bitset.
2010-08-09 10:29:42 +00:00
Joe Thornber
9c7425eee4 [REGEX] add a unit test for regexes containing chars with value over x80 2010-08-09 10:27:31 +00:00
Joe Thornber
7cd8b4410e [REGEX] matcher_t unit test now takes a flag to turn on fingerprinting 2010-08-09 10:23:54 +00:00
Jonathan Earl Brassow
c63e78714a Fix for bug 619221 - log device splitting regression
An incorrect fix on July 13, 2010 for an annoyance has caused a regression.
The offending check-in was part of the 2.02.71 release of LVM.  That
check-in caused any PVs specified on the command line to be ignored when
performing a mirror split.

This patch reverses the aforementioned check-in (solving the regressions)
and posits a new solution to the list reversal problem.  The original
problem was that we would always take the lowest mimage LVs from a mirror
when performing a split, but what we really want is to take the highest
mimage LVs.  This patch accomplishes that by working through the list in
reverse order - choosing the higher numbered mimages first.  (This also
reduces the amount of processing necessary.)

Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
Reviewed-by: Takahiro Yasui <takahiro.yasui@hds.com>
2010-08-06 15:38:32 +00:00
Jonathan Earl Brassow
2b34836c61 A misunderstanding of the return value of 'dm_bit' has been causing a data
corruption bug in cmirror.  'dm_bit' is only ever used as a boolean operation
within LVM, but it can return a range of values.  If the bit is set, a power of
2 is returned.  If the bit is unset, 0 is returned.

'log_test_bit' (a function in the cluster mirror log daemon code) has switched
to using the dm bit operations in rhel6.  There are two places in the daemon
code where 'log_test_bit' is not used merely as a boolean, but rather the
return value is used as the return value for the log functions 'is_clean' and
'in_sync' - having assumed that 'dm_bit' was returning 0 or 1 only.

One place the 'in_sync' function is utilized is in 'dm_rh_get_state' - a
function that informs the mirroring code how to treat I/O and which devices to
read/write from.  'dm_rh_get_state' was checking if the return value of
'in_sync' was 1 to determine if the region was DM_RH_CLEAN.  Since 'dm_bit'
(and by extension 'log_test_bit' and 'in_sync') was returning powers of 2,
DM_RH_CLEAN was rarely being reported as it should have been.  Thinking the
region was out-of-sync, the mirroring code would write only to the primary
device.  When the primary device was failed, all of those writes were lost -
leaving the entire mirror corrupted.
2010-08-04 18:18:18 +00:00
Petr Rockai
32d1d7b23f Reduce severity of the "mirror transient status" log message (this was never
intended to be a log_error).
2010-08-04 15:55:03 +00:00
Mike Snitzer
e7773faa8d Require logical volume(s) to be explicitly named for lvconvert --merge. 2010-08-03 20:22:31 +00:00
Mike Snitzer
b7c2a2b709 Avoid changing aligned pe_start as a side-effect of very verbose logging. 2010-08-03 18:19:42 +00:00
Peter Rajnoha
67ef389a69 Use built-in rules for device aliases: block/ < dm- < disk/ < mapper/ < other. 2010-08-03 13:39:27 +00:00
Zdenek Kabelac
7c1903a0c3 Fix 'void*' arithmetic warnings in dbg_malloc.c.
Use more readable char[idx] access instead of *char+idx access.
2010-08-03 13:24:07 +00:00
Zdenek Kabelac
c8563cac0a Fix 'void*' arithmetic warning in some functions from libdm-iface.c. 2010-08-03 13:16:21 +00:00
Zdenek Kabelac
42c4a7757d Fix const warning in dev_manager_info() and _dev_manager_lv_rmnodes(). 2010-08-03 13:13:01 +00:00
Zdenek Kabelac
8b007b358e Fix constness warning in archive_file structure from archive.c. 2010-08-03 13:09:21 +00:00
Zdenek Kabelac
5cd2cfc203 Use void parameter for function definition. 2010-08-03 13:06:35 +00:00
Zdenek Kabelac
a7ca42cb22 Wait for node creation before displaying debug info in dmsetup.
Readahead check needs to see created node - so wait till udev gets in sync.
2010-08-03 13:04:32 +00:00
Zdenek Kabelac
f562bcedef Clean generated files .exported_symbols_generated, example.conf for distclean. 2010-08-03 13:00:45 +00:00
Zdenek Kabelac
a8dc5260b7 Fix return status 0 for "dmsetup info -c -o help".
Solution returns success for _report_init when help is passed,
and caller needs to check for _report existance.
2010-08-03 12:56:00 +00:00
Peter Rajnoha
d33d0b01bf Add check for kernel semaphore support and disable udev_sync if not available.
udev_sync feature requires semaphores (part of System V IPC) to be configured
in kernel (CONFIG_SYSVIPC). Check whether it is supported and if not, give
a warning message and disable udev synchronisation code automatically to
avoid any further error states and associated problems.

One should use the kernel with System V IPC support enabled or libdevmapper
with udev_sync feature disabled.
2010-08-03 07:56:03 +00:00
Jonathan Earl Brassow
4a5195c38a Taka's fix for handling failure of all mirrored log devices and
all but one mirror leg.

<patch header>
To handle a double failure of a mirrored log, Jon's two patches are
commited, however, lvconvert command can't still handle an error
when mirror leg and mirrored log got failure at the same time.

  [Patch]: Handle both devices of a mirrored log failing (bug 607347)
  posted: https://www.redhat.com/archives/lvm-devel/2010-July/msg00009.html
  commit: https://www.redhat.com/archives/lvm-devel/2010-July/msg00027.html

  [Patch]: Handle both devices of a mirrored log failing (bug 607347) -
           additional fix
  posted: https://www.redhat.com/archives/lvm-devel/2010-July/msg00093.html
  commit: https://www.redhat.com/archives/lvm-devel/2010-July/msg00101.html

In the second patch, the target type of mirrored log is replaced with
error target when remove_log is set to 1, but this procedure should be
also used in other cases such as the number of mirror leg is 1. This
patch relocates the procedure to the main path.

In addition, I added following three changes.

- Removed tmp_orphan_lvs handling procedure
  It seems that _delete_lv() can handle detached_log_lv properly
  without adding mirror legs in mirrored log to tmp_orphan_lvs.
  Therefore, I removed the procedure.

- Removed vg_write()/vg_commit()
  Metadata is saved by vg_write()/vg_commit() just after detached_log_lv
  is handled. Therefore, I removed vg_write()/vg_commit().

- With Jon's second patch, we think that we don't have to call
  remove_mirror_log() in _lv_update_mirrored_log() because will be
  handled remove_mirror_images() in _lvconvert_mirrors_repaire().
</patch header>

Signed-off-by: Takahiro Yasui <takahiro.yasui@hds.com>
Reviewed-by: Petr Rockai <prockai@redhat.com>
Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
2010-08-02 21:07:40 +00:00
Jonathan Earl Brassow
0864378250 Disallow mirrored logs in cluster mirrors.
The cluster log daemon (cmirrord) is not multi-threaded and
can handle only one request at a time.  When a log is stacked
on top of a mirror (which itself contains a 'core' log), it
creates a situation that cannot be solved without threading.

When the top level mirror issues a "resume", the log daemon
attempts to read from the log device to retrieve the log
state.  However, the log is a mirror which, before issuing
the read, attempts to determine the 'sync' status of the
region of the mirror which is to be read.  This sync status
request cannot be completed by the daemon because it is
blocked on a read I/O to the very mirror requesting the
sync status.
2010-08-02 19:03:45 +00:00
Alasdair Kergon
855e4aac41 Fix lib.device-mapper to wait for include too 2010-08-02 13:56:34 +00:00
Zdenek Kabelac
5f8a3896dc Minor speedup of lock test -
Instead of waiting for flock process finish kill the flock process.
2010-08-02 13:23:01 +00:00
Zdenek Kabelac
903bfcaf4b Add shell function to trim spaces.
Test values as "$val" to avoid weird results when spaces are in output.
2010-08-02 13:20:50 +00:00
Zdenek Kabelac
fcf46a9a42 Using count=0 is sufficient for creation of zeroed files. 2010-08-02 13:18:42 +00:00
Zdenek Kabelac
1d1db98a2e Visually better align lines which are executed as a result of true
or false result of previous command.
2010-08-02 13:18:01 +00:00
Zdenek Kabelac
51c8e01575 Do not use VPATH in include/Makefile 2010-08-02 13:17:03 +00:00
Alasdair Kergon
b87c774102 revert the 'Base' change - that wasn't the cause of the problem 2010-08-02 12:57:04 +00:00
Alasdair Kergon
6aa05bdc37 Fix exported_symbols generation to use standard compiler arguments. 2010-08-02 12:44:21 +00:00
Alasdair Kergon
4abee1da76 Use #include <> not "" in lvm2app.h which gets installed on the system. 2010-08-02 12:23:01 +00:00
Alasdair Kergon
2106e8f031 Make liblvm.device-mapper wait for include file generation. 2010-08-02 12:10:35 +00:00
Alasdair Kergon
4befd355b3 Drop explicit 'Base' version from exported symbols. 2010-07-31 14:13:59 +00:00
Alasdair Kergon
a544f403a2 Fix configure to supply DEFAULT_RUN_DIR to Makefiles. 2010-07-31 00:43:41 +00:00
Takahiro Yasui
8f1afa1766 Fix wrong number of mirror log at allocate policy
With mirror_log_fault_policy of 'remove' and mirror_image_fault_policy
of 'allocate', the log type of the mirror volume is converted from
'disk' or 'mirrored' to 'core' when all mirror legs but one in a mirror
volume broke.

Keep new_log_count as a number of valid log devices by using log_count
variable for a temporary usage in the first phase of error recovery
in _lvconvert_mirrors_repair().

Signed-off-by: Takahiro Yasui <takahiro.yasui@hds.com>
Reviewed-by: Petr Rockai <prockai@redhat.com>
2010-07-30 17:50:15 +00:00
Dave Wysochanski
c0789ae1b4 Remove irrelevant comments relating to vg_mda_copies. 2010-07-30 16:47:27 +00:00
Alasdair Kergon
9934a167a2 post-release 2010-07-28 21:58:08 +00:00
Alasdair Kergon
798ffad9a9 Never use clvmd singlenode unless explicitly requested with -Isinglenode. 2010-07-28 14:01:40 +00:00
Alasdair Kergon
fb3b7f2274 Change clvmd to communicate with lvm via a socket in /var/run/lvm. (mbroz)
https://bugzilla.redhat.com/show_bug.cgi?id=614248 [CVE-2010-2526]
2010-07-28 13:55:42 +00:00
Alasdair Kergon
23dd62ec54 add copyright notices to new files 2010-07-28 12:20:38 +00:00
Alasdair Kergon
a1affa1dc3 day+1 2010-07-28 11:49:42 +00:00
Alasdair Kergon
23633cf632 . 2010-07-28 10:44:29 +00:00
Peter Rajnoha
472bd55757 Revert unsuccessful table load preparation in combined "create, load and resume" scenario.
There was missing "revert" call in _create_and_load_v4 fn while the preparation
for table load ends up with failure in create/load/resume sequence. Otherwise
we could end up with a device being created, but not table-loaded nor resumed.

Even though the table is not loaded and the device is not resumed at this
stage, we still need to synchronize with udev when calling the revert
"remove" ioctl - there's still a remove uevent generated! The "revert"
code does exactly that.
2010-07-28 10:30:28 +00:00
Alasdair Kergon
2de4f65474 pre-release 2010-07-27 22:52:19 +00:00
Alasdair Kergon
38befc5ded . 2010-07-27 21:57:37 +00:00
Alasdair Kergon
5f9d855d3e Fix dm_create_lockfile error paths - incorrectly unlinked in-use lockfile.
(Jan Friesse)
2010-07-27 21:56:14 +00:00
Petr Rockai
3c5d941945 Do not create a clustered volume group in t-nomda-missing. 2010-07-27 21:08:32 +00:00
Petr Rockai
2f54dbd28c Make vgck warn about missing PVs. 2010-07-27 20:05:29 +00:00
Jonathan Earl Brassow
b2b6c18db3 Initial import of document describing LVM's policies
surrounding device faults/failures.
2010-07-26 20:31:53 +00:00
Dave Wysochanski
33e7126ba5 Remove unneeded "active" variable in vgchange_monitoring(). 2010-07-26 19:03:29 +00:00
Dave Wysochanski
2ab98aa919 Clarify help text for vg_mda_count. 2010-07-21 19:44:25 +00:00
Jonathan Earl Brassow
9ba875e502 Building without the '--enable-cmirrord' option means that
CMIRRORD_PIDFILE is not defined.  This makes the build fail.
Therefore, we need to conditionalize the check for cmirrord
based on if CMIRRORD_PIDFILE is defined.
2010-07-21 15:21:24 +00:00
Petr Rockai
2dcdb807f8 Don't fail t-pvcreate-operation-md if mdadm is broken. 2010-07-21 14:12:47 +00:00
Jonathan Earl Brassow
56fe3c6176 It's not enough to check for the kernel module in the case of cluster
mirrors, we must also check that the log daemon (cmirrord) is running.
The log module can be auto-loaded, but the daemon cannot be
"auto-started".  Failing to check for the daemon produces cryptic
messages that customers have a hard time deciphering.  (The system
messages do report that the log daemon is not running, but people
don't seem to find this message easily.)

Here are examples of what is printed when the module is available,
but the log daemon has not been started.

[root@bp-01 LVM2]# lvcreate -m1 -l1 -n lv vg
  Shared cluster mirrors are not available.

[root@bp-01 LVM2]# lvcreate -m1 -l1 -n lv vg -v
    Setting logging type to disk
    Finding volume group "vg"
    Archiving volume group "vg" metadata (seqno 3).
    Creating logical volume lv
    Executing: /sbin/modprobe dm-log-userspace
    Cluster mirror log daemon is not running
  Shared cluster mirrors are not available.
    Creating volume group backup "/etc/lvm/backup/vg" (seqno 4).
2010-07-21 13:40:21 +00:00
Alasdair Kergon
321b26f3d4 update configure 2010-07-21 12:54:21 +00:00
Joe Thornber
ad37ab272a [REGEX] calculate dfa states on demand 2010-07-21 12:09:12 +00:00
Joe Thornber
d5feddb0a0 [REGEX] remove the state_queue structure.
Instead we just have a 'next' field in the dfa_state.
2010-07-21 12:02:51 +00:00
Joe Thornber
88ae26178c [REGEX] factor _calc_state() out of _calc_states() 2010-07-21 12:00:53 +00:00
Joe Thornber
e06357084e [REGEX] reduce the number of charset nodes that are produced 2010-07-21 11:58:49 +00:00
Joe Thornber
2e52c46165 [REGEX] another matcher_t test with a larger set of regexes, only interested in the fingerprint 2010-07-21 11:52:46 +00:00
Joe Thornber
a82cf6080e [REPORT-GENERATORS] cut down stylsheet.css to what we actually use 2010-07-21 10:00:38 +00:00
Joe Thornber
78f321b32c [REGEX] add a fingerprinting facility to allow test code to compare dfas 2010-07-20 15:32:07 +00:00
Joe Thornber
3113200309 [UNIT-TEST] test for recent dm_bit_and() function 2010-07-20 15:28:22 +00:00
Joe Thornber
4a854b2927 [UNIT-TESTS] add test for the recent dm_bitset_equal() function 2010-07-20 15:26:43 +00:00
Joe Thornber
a5e61545e4 Add a unit test for the recent changes to dm_bit_get_next() 2010-07-20 15:25:39 +00:00
Joe Thornber
17a259e894 Wire the regex tests up to the reports 2010-07-20 15:21:32 +00:00
Joe Thornber
f5fb224254 Move tests from old-tests/regex to unit-tests/regex. unit-tests will
contain tests that currently work.
2010-07-20 15:18:57 +00:00
Joe Thornber
fe07d17374 Report generators for unit tests and memory checks. Configure with
--enable-testing.
2010-07-20 14:38:44 +00:00
Jonathan Earl Brassow
8d983d6f2d Fix for bug 614164: No check for existing name when splitting mirror
The user could use the same name as an existing LV when specifying a
name for an LV split off from a mirror.  This causes all sorts of
issues.
2010-07-13 22:24:39 +00:00
Jonathan Earl Brassow
2c028990b4 Fix reversal of LV list before performing a split mirror.
When splitting off mirror images from a mirror, we always take
LVs from the end of a list.  For example, if the mirror sub-devices
are lv_mimage_[012], we should select lv_mimage_2 if splitting off
one image.  However, lv_mimage_0 was being selected instead.

The problem came from calling '_move_removable_mimages_to_end'
when it was unnecessary to do so.  When the user /does/ specify
specific devices to be removed, this function properly moved the
appropriate LVs to the end of the list for extraction.  However,
if the user /doesn't/ give any specific PVs, the function should
do nothing.  '_move_removable_mimages_to_end' was keying off of
whether 'removable_pvs' was NULL or not and this value was
improperly being populated with the set of all available PVs.
This was causing '_move_removable_mimages_to_end' to completely
reverse the list, which in turn caused us to extract the
hithertofore front-of-the-list LVs.
2010-07-13 22:04:36 +00:00
Jonathan Earl Brassow
35af86cef2 Fix for bug 612311: Split of linear provides no error msg
An unhandled condition allowed the command to terminate
cleanly without a warning.  Added a check for the
'--splitmirrors' argument to allow execution to the lower
level function that has the check to see if the user is
trying to split a linear device.  You should now see a
message if you try to use --splitmirrors on a linear device.
2010-07-13 21:53:07 +00:00
Jonathan Earl Brassow
659f47f76a Fix for bugs: 612248 & 612291 Split mirror issues
The main problem with these bugs was that the newly split
off LV was not being suspended properly.  This meant that
the memlock count was not being balanced, the DM devices
were not being renamed, and some DM devices which should
have been removed were not.

I've also renamed some of the variables and added comments
to make things clearer as to what is going on.  (I can break
this patch in two if it means easier review.)
2010-07-13 21:48:16 +00:00
Dave Wysochanski
b489acb578 Minor man page updates related to metadataignore and vgmetadatacopies.
pvchange: Add --metadataignore description
vgchange: Fix minor formatting
pvcreate: Update metadataignore description to refer to pvchange
lvm.conf: Refer to pvcreate and pvchange for metadata options.
2010-07-13 15:04:23 +00:00
Fabio M. Di Nitto
e34342c1f3 Add dm_create_lockfile to libdm to handle pidfiles for all daemons.
Switch dmeventd to use dm_create_lockfile and drop duplicate code.
Allow clvmd pidfile to be configurable.
Switch cmirrord and clvmd to use dm_create_lockfile.
2010-07-13 13:51:01 +00:00
Dave Wysochanski
1f6952ba81 More comment updates in lvm2app.h. 2010-07-12 18:29:31 +00:00
Dave Wysochanski
d2f48d07bb Update comments about memory handling in lvm2app.h. 2010-07-12 18:12:23 +00:00
Peter Rajnoha
e9306bead5 Addendum for previous patch - show VG/LV name everywhere so the messages
are consistent.
2010-07-12 12:38:35 +00:00
Peter Rajnoha
a3bdff883b Add more verbose messages while checking volume_list and hosttags settings.
This should bring less confusion when there are some settings left and
people just forgot about it and then they run into problems. These messages
should give them a hint of what's really going on.
2010-07-12 11:37:49 +00:00
Jonathan Earl Brassow
ddedf42d21 Failed to test for the case where a log was requested to be removed
even though there was no log.  A simple run through the in-tree test
suite would have caught this.  :(

-               if (lv_is_mirrored(detached_log_lv) &&
+               if (detached_log_lv && lv_is_mirrored(detached_log_lv) &&

Also, made some cosmetic changes suggested by kabi after my last check-in
(e.g. s/return 0/return_0/ and adding an error message).
2010-07-09 17:57:51 +00:00
Dave Wysochanski
b3e684d1fe Update WHATS_NEW 2010-07-09 17:01:11 +00:00
Dave Wysochanski
b3a13b17cb Add log_error when strdup fails in {vg|lv}_change_tag().
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-07-09 16:57:44 +00:00
Dave Wysochanski
90b4fce199 Remove unnecessary list of includes in liblvm files.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-07-09 16:57:34 +00:00
Alasdair Kergon
2d3164a59f Use __attribute__ consistently throughout. 2010-07-09 15:34:40 +00:00
Alasdair Kergon
37ee12b2eb Fix redundant declarations and always compile with -Wredundant-decls. 2010-07-09 15:26:41 +00:00
Alasdair Kergon
d8d4a1d694 Remove superfluous fn prototypes. 2010-07-09 15:21:10 +00:00
Jonathan Earl Brassow
0b18937cbe Finish fix for bug 607347: failing both redundant mirror log legs...
A previous check-in added logic to handle the case where both images
of a mirrored log failed.  It solved the problem by simply removing
the log entirely - leaving the parent mirror with a 'core' log.  This
worked for most cases.  However, if there was a small delay between
the failures of the two mirrored log devices, the mirror would hang,
LVM would hang, and no additional LVM commands could be issued.

When the first leg of the log fails, it signals the need for repair.
Before 'lvconvert --repair' is run by dmeventd, the second leg fails.
'lvconvert' would see both devices as failed and try to remove the
log entirely.  When it came time to suspend the parent mirror to
update the configuration, the suspend would hang because it couldn't
get any I/O through the mirrored log, which was plugged waiting for
corrective action.  The solution is to replace the log with an error
target to clear any pending writes before removing it.  This allows
the parent mirror to suspend and make the proper changes.
2010-07-09 15:08:12 +00:00
Dave Wysochanski
264091a239 Pass metadataignore to pv_create, pv_setup, _mda_setup, and add_mda.
Pass metadataignore through PV creation / setup paths.
As a result of this cleanup, we can remove the unnecessary setting
of mda_ignore bits inside pvcreate_single(), after call to pv_create.
For now, just set metadataignore to '0' in some places.  This is
equivalent to the prior functionality, although the 0 is given
by the caller not hardcoded in _mda_setup() call.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-07-08 18:24:29 +00:00
Dave Wysochanski
d324fd94df Init mda->list in mda_copy.
This patch should be no functional change as all callers initialize
mda->list.
2010-07-08 17:41:46 +00:00
Zdenek Kabelac
15352cd86e Fix format string from patch apply mistake 2010-07-08 14:47:46 +00:00
Zdenek Kabelac
69ca87abad Revert previous commit as it would return also for incorrect syntax. 2010-07-08 14:29:26 +00:00
Zdenek Kabelac
e0c8e7c740 Update for dmsetup 2010-07-08 13:35:55 +00:00
Zdenek Kabelac
8a9f96b21c Set return value 0 for 'dmsetup -c -o help' 2010-07-08 13:31:03 +00:00
Zdenek Kabelac
bfb05107e3 Small update of memlock debug messages.
Gives slightly better alligned lines for reading.
2010-07-08 13:05:27 +00:00
Zdenek Kabelac
1e699db631 Do not log backtrace in valid _lv_resume() code path 2010-07-08 12:24:04 +00:00
Zdenek Kabelac
f3953f9a15 Minor optimalization of _test_word.
Skip ffs() if  (test >> bit) is 0.
2010-07-08 12:16:16 +00:00
Zdenek Kabelac
7c7f889b1e Cleanups for configure:
Indent updates.
 Use AC_HELP_STRING for help string.
 Start help string with lower letter.
 Add [] around some default values i.e. [TYPE=internal].
 Skip some "" around shell assigment when not needed.
 Fix typo --with-device-gid=UID string.
2010-07-08 12:02:48 +00:00
Dave Wysochanski
f437c92b00 Shorten prompt for pvchange and vgextend. 2010-07-07 21:30:07 +00:00
Dave Wysochanski
44dd5c38e2 Add --force to pvchange, and allow override of prompt involving metadataignore.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-07-07 19:14:57 +00:00
Dave Wysochanski
e0132ef4cb Add prompt if using --metadataignore argument with vgmetadatacopies.
When using vgmetadatacopies value other than "umanaged" (0), prompt
the user if the usage of --metadataignore would change the value of
vgmetadatacopies.  The main 2 cases are:
1) pvchange --metadataignore
2) vgextend --metadataignore

We leave the prompt check in the tools, and do not change anything
if the user says 'n'.

Examples:
vgextend --metadataignore y vgtest /dev/loop0
Setting metadataignore will override preferred number of copies of VG vgtest metadata.
Are you sure? [y/n]: y
  No physical volume label read from /dev/loop0
  Physical volume "/dev/loop0" successfully created
  Volume group "vgtest" successfully extended

pvchange --metadataignore y /dev/loop3
Setting metadataignore on /dev/loop3 will override preferred number of copies of VG vgtest metadata.
Are you sure? [y/n]: y
  WARNING: Changing preferred number of copies of VG vgtest metadata from 3 to 2
  Physical volume "/dev/loop3" changed
  1 physical volume changed / 0 physical volumes not changed

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-07-07 19:02:50 +00:00
Dave Wysochanski
94cb2db723 Add warning to vgextend and pvchange if metadataignore given on cmdline.
Warn the user then change the value of vg_mda_copies.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-07-07 18:59:45 +00:00
Dave Wysochanski
52cf11338e Test failed commit of mda on new pv - failed vgextend.
Test the auto-repair capability when we fail committing to an mda
on a new pv adding to a vg.  This test should fail until we fix
the auto-repair in this case.
2010-07-07 14:43:57 +00:00
Peter Rajnoha
c4cce91dce Use "nowatch" udev rule for known inappropriate devices.
For now, this is just a precaution. Normally, all the other (non-dm) rules
should check DM_UDEV_DISABLE_OTHER_RULES_FLAG and therefore avoid setting
any inotify watches as well. But let's make sure.

Support for final assignment of the "nowatch" rule (the use of ":=") will
appear in next udev release, v160. This should also work in previous udev
versions but the setting won't be sealed so any further OPTIONS="watch" will
always prevail there.

We may want to add more specific "nowatch" rules later if needed.
2010-07-07 11:22:46 +00:00
Alasdair Kergon
23aa1c6524 Adjust auto-metadata repair and caching logic to try to cope with empty mdas.
- If a PV contained empty mdas, the auto-recovery code was not kicking in.
- The 'inconsistent' state was getting lost when metadata was cached so
  recovery didn't kick in.  But leave the behaviour alone when using
  precommitted metadata because of a warning in a confusing FIXME.

In my testing, pvs and vgs didn't repair inconsistent metadata like they
used to do.  (How many other tools fail similarly now?)

And there should be no need to cache inconsistent metadata because it is
supposed to get repaired under the protection of a write lock immediately it is
discovered.

This code is in need of a redesign based on first principles.
I still see bugs in this code and this commit is risky.
2010-07-07 02:53:16 +00:00
Alasdair Kergon
9de129d5b2 post-release 2010-07-07 02:37:28 +00:00
Alasdair Kergon
9d4cb8e97a . 2010-07-07 02:24:05 +00:00
Alasdair Kergon
c1589415f0 fix code in 2nd mda unignore loop to match 1st loop 2010-07-06 20:09:38 +00:00
Alasdair Kergon
389cbc3686 s/flags/mda/ 2010-07-06 17:29:50 +00:00
Alasdair Kergon
2508b4000b shorten mesg 2010-07-06 17:27:32 +00:00
Alasdair Kergon
e5164acc9c fix jumbled args in 'Adjusting' message 2010-07-06 17:26:08 +00:00
Jonathan Earl Brassow
71ee58b6bb Fix for bug 607347: failing both redundant mirror log legs...
Rather than attempting to remove all the images of a mirrored
log volume via remove_mirror_images, simply remove the log
if all its devices have failed.

Taka was the first to report that there is still an outstanding
issue with handling this case.  I've managed to reproduce it
only very rarely, and am still working on identifying the problem.
Failing to handle the problem rarely is better than not handling
the scenario at all, so I'm checking this in.
2010-07-06 17:02:03 +00:00
Alasdair Kergon
3512a6ad0b pre-release 2010-07-06 16:49:38 +00:00
Alasdair Kergon
b02de599a0 Fix dmlosetup snprintf %llu compiler warning. 2010-07-05 22:56:31 +00:00
Alasdair Kergon
38c6e8faf6 Randomly select which mdas to use or ignore.
Add some missing standard configure.in checks.
2010-07-05 22:23:15 +00:00
Alasdair Kergon
431ca070a4 Add parentheses to some libdevmapper.h macro arguments. 2010-07-05 22:22:43 +00:00
Alasdair Kergon
ed2630dce5 Add printf format attributes to yes_no_prompt & dm_{sn,as}printf and fix a calle 2010-07-02 21:16:50 +00:00
Petr Rockai
5a2c9c9cee . 2010-07-02 17:44:17 +00:00
Dave Wysochanski
a7184430f1 Minor changes to man pages for --metadataignore.
Move the definition from pvchange to pvcreate - the location of
other metadata options.
2010-07-02 17:05:22 +00:00
Alasdair Kergon
2e83fee74c remove unneeded header 2010-07-02 10:25:16 +00:00
Alasdair Kergon
bbe29582cb Always pass unsuspended dm devices through persistent filter to other filters.
Move test for suspended dm devices ahead of other filters.
2010-07-02 02:09:57 +00:00
Milan Broz
76470d9608 Fix another segfault in clvmd -R if no response from daemon received.
Missed the same problem in another function...
2010-07-01 21:46:09 +00:00
Milan Broz
715c4ca4cd Remove superfluous suspended device counter from clvmd.
Moreover, in current mirror handling, when it calls activate
on removed but suspended detached log this counter drops below zero
and confuses debug log.
2010-07-01 21:23:47 +00:00
Alasdair Kergon
c097423d77 Fix lvm shell crash when input is entirely whitespace. (Xinwei Hu) 2010-07-01 11:04:58 +00:00
Alasdair Kergon
54637fa44d Move dmeventd man page from install_lvm2 to install_device-mapper. (1.02.50) 2010-07-01 10:57:03 +00:00
Petr Rockai
c192e88bcd Restore the "removemissing" behaviour of lvconvert --repair --use-policies. 2010-07-01 10:10:52 +00:00
Dave Wysochanski
19a12b28bc Update metadata-balance test for --vgmetadatacopies 0.
Should be equivalent to "unmanaged".
2010-06-30 22:22:00 +00:00
Petr Rockai
d55a7f18b0 . 2010-06-30 21:58:13 +00:00
Petr Rockai
4008a5fbf9 Maintain memlock balance in clvmd.
When a mirror is being downconverted in a cluster, a series of suspends and
resumes is executed.

With the change to using UUIDs in dev_manager instead of names, the behaviour
has changed with regards to including an _mlog in the deptree of a logical
volume. In the old (pre-UUID-enabled) code, the _mlog would appear in a deptree
of any volume purely based on a name match: a linear volume foo would include
foo_mlog in its dependencies if that happened to exist. This behaviour was
fixed and the mlog is now only included for mirrors.

By a coincidence, this mlog bug had been hiding a different bug in clvmd. When
a mirror is being dismantled (and converted to a linear volume), it is first
suspended as a whole, then later resumed in parts. Nevertheless, the overall
memlock balance is maintained in this operation. The problem kicks in, because
even though the mirror log was suspended as part of the mirror, when the
dismantled mirror is resumed again, it is no longer a mirror and therefore the
mirror log stays suspended. This would not be a problem in itself, since
_delete_lv (from metadata/mirror.c) is called on it subsequently, which does an
activate/deactivate cycle and removes the LV. The activate/deactivate cycle
correctly prompts clvmd to resume the device: however, in doing this, it will
issue an unpaired resume operation (the suspend that caused the mirror log to
be suspended is paired with resuming the dismantled mirror later). We have
concluded that the path in clvmd should never affect memlock_count, since there
should never be an unmatched explicit suspend preceding this resume.
2010-06-30 21:40:27 +00:00
Alasdair Kergon
e260f729da Fix --[vg]metadatacopies arg processing 2010-06-30 20:21:03 +00:00
Alasdair Kergon
17cffe2bf9 improve vgmetadatacopies unmanaged message 2010-06-30 20:03:52 +00:00
Dave Wysochanski
d1b068a68a Check for missing_pv in vg_remove loop.
If a pv is missing, we should just skip it rather than checking the
device size and failing the vgremove.
2010-06-30 19:55:43 +00:00
Alasdair Kergon
a5053f6ada more mda ignore cleanups 2010-06-30 19:28:35 +00:00
Dave Wysochanski
261a3e7e78 Refactor vg_remove_check to place pv removal into separate function. 2010-06-30 18:03:52 +00:00
Alasdair Kergon
36e28d4b4b more metadataignore message/code cleanup 2010-06-30 17:13:05 +00:00
Alasdair Kergon
cbc562a636 Update partial mode warning message. 2010-06-30 16:43:09 +00:00
Alasdair Kergon
51c4e1ea4b revert that 2010-06-30 14:54:29 +00:00
Alasdair Kergon
c8f03c38fe suppress useless compiler warning 2010-06-30 14:52:29 +00:00
Alasdair Kergon
4107d4d24d post-release 2010-06-30 14:50:32 +00:00
Dave Wysochanski
f0c79d95f5 Only attempt to guarantee 1 mda ignored if there's at least one mda in the vg. 2010-06-30 14:48:07 +00:00
Alasdair Kergon
d13b495217 Only attempt to guarantee 1 mda ignored if there's at least one mda in the vg. 2010-06-30 14:27:40 +00:00
Alasdair Kergon
549e1dfb0d pre-release 2010-06-30 14:04:15 +00:00
Milan Broz
e260ecef0b Fix vgremove to allow removal of VG with missing PVs. (2.02.52) 2010-06-30 14:01:39 +00:00
Alasdair Kergon
b16b4d92a7 Improve various log messages. 2010-06-30 13:51:11 +00:00
Dave Wysochanski
c2584edbdb Update nightly tests for vgextend --metadataignore. 2010-06-30 13:11:12 +00:00
Dave Wysochanski
aa00196b6f Update nightly tests for vgextend --metadataignore. 2010-06-30 13:04:59 +00:00
Dave Wysochanski
75e3996d36 Add --metadataignore to vgextend and man pages. 2010-06-30 13:03:48 +00:00
Dave Wysochanski
d50f13b90d Add pvmetadatacopies to lvm.conf and pvcreate man pages. 2010-06-30 12:49:28 +00:00
Dave Wysochanski
652e9c00c5 Update pvcreate tests for --metadataignore. 2010-06-30 12:17:55 +00:00
Dave Wysochanski
fdcf749779 Add --metadataignore to pvcreate.
Allow metadataignore flag to be passed in to pvcreate.
Ideally, more refactoring of the mda allocation / initialization
is warranted, but for now, we just add another parameter to 'add_mda'
to take an existing mda ignored flag.  We need to do this or pv_write
loses the state of the mda 'ignored' flag before copying and writing
to disk.
2010-06-30 12:17:24 +00:00
Dave Wysochanski
ed38f47f23 Improve logging for setting --vgmetadatacopies.
Example of logging:
metadata/metadata.c:1127     Setting mda_copies = 3 on vg vgtest
metadata/pv_manip.c:296         /dev/loop2 0:      0     25: NULL(0:0)
metadata/pv_manip.c:296         /dev/loop3 0:      0     25: NULL(0:0)
metadata/pv_manip.c:296         /dev/loop4 0:      0     25: NULL(0:0)
metadata/metadata.c:1072     Adjusting ignored mdas on vg vgtest, vg_mda_used_count=5, vg_mda_copies=3
metadata/metadata.c:1015     Setting ignore flag for 2 mdas on vg vgtest
metadata/metadata.c:4151     Setting mda ignored flag for metadata_locn /dev/loop2.
metadata/metadata.c:4151     Setting mda ignored flag for metadata_locn /dev/loop3.
2010-06-29 22:41:28 +00:00
Dave Wysochanski
3b0585be3b Improve logging for metadata ignore by printing device name.
Print device name when setting or clearing metadata ignore bit.
Example:
label/label.c:160       /dev/loop2: lvm2 label detected
cache/lvmcache.c:1136         lvmcache: /dev/loop2: now in VG #orphans_lvm2 (#orphans_lvm2)
metadata/metadata.c:4142     Setting mda ignored flag for metadata_locn /dev/loop2.
format_text/text_label.c:318     Skipping mda with ignored flag on device /dev/loop2 at offset 4096
2010-06-29 22:37:32 +00:00
Dave Wysochanski
ebe1a8080c Add some log_verbose debug statements related to metadataignore.
Logging isn't ideal, especially for mda_set_ignore.  Ideally we'd
like to display the device name and offset in this case but this
requires a bit more work and a per-format 'mda_description' function
pointer definition (we don't have access to mda_context in
metadata.c).
2010-06-29 22:25:58 +00:00
Dave Wysochanski
593bb6470b Move code into pv_change_metadataignore library function.
In preparation to call this from both pvcreate as well as pvchange,
move the guts of metadataignore into a library function.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-29 21:32:44 +00:00
Dave Wysochanski
6ce45042ef Add error message if backup_to_file fails because of empty in_use mdas list. 2010-06-29 15:03:59 +00:00
Dave Wysochanski
f615e84381 Add more initializations of 'mda->flags' field.
Mda allocation needs refactored into a single function but as an
interim step, ensure mda->flags is initialized properly.
2010-06-29 14:52:56 +00:00
Dave Wysochanski
bfaf1a4ecc Attempt to fix intermittent failure with non-debug configured vgcfgbackup.
There's an intermittent failure with vgcfgbackup that seems to have been
introduced with the metadataignore / vgmetadatacopies patchset.
Intermittent failures are often the result of uninitialized data,
so this patch calls zalloc in a few places it might matter.
2010-06-29 13:29:53 +00:00
Dave Wysochanski
bc1a30f542 Update WHATS_NEW for --metadataignore and --vgmetadatacopies changes. 2010-06-29 12:06:14 +00:00
Dave Wysochanski
28e0d5dd64 Update t-covercmd pvck to take proper device argument. 2010-06-28 21:49:31 +00:00
Dave Wysochanski
ffdd12841e Fix compile warning in vgchange.c regarding mda_copies initialization. 2010-06-28 21:35:00 +00:00
Dave Wysochanski
4b660a89d9 Update tests to handle phase 2 (vg based) metadata balance.
Test vgcreate/vgchange --vgmetadatacopies, vgextend, vgreduce,
vgsplit, vgmerge.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:40:27 +00:00
Dave Wysochanski
48386caec5 Update example.conf.in to describe vgmetadatacopies.
Update example.conf to describe vgmetadatacopies.  Provide an
explanation for the '0' ("unmanaged") value.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:40:15 +00:00
Dave Wysochanski
996360df6b Allow 'all' and 'unmanaged' values for --vgmetadatacopies.
Allowing an 'all' and 'unmanaged' value is more intuitive, and
provides a simple way for users to get back to original LVM behavior
of metadata written to all PVs in the volume group.

If the user requests "--vgmetadatacopies unmanaged", this instructs
LVM not to manage the ignore bits to achieve a specific number of
metadata copies in the volume group.  The user is free to use
"pvchange --metadataignore" to control the mdas on a per-PV basis.
If the user requests "--vgmetadatacopies all", this instructs LVM
to do 2 things: 1) clear all ignore bits, and 2) set the "unmanaged"
policy going forward.

Internally, we use the special MAX_UINT32 value to indicate 'all'.
This 'just' works since it's the largest value possible for the
field and so all 'ignore' bits on all mdas in the VG will get
cleared inside _vg_metadata_balance().  However, after we've
called the _vg_metadata_balance function, we check for the special
'all' value, and if set, we write the "unmanaged" value into the
metadata.  As such, the 'all' value is never written to disk.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:40:01 +00:00
Dave Wysochanski
fe260a26ed Ensure --metadatacopies parameter gets interpreted based on command.
Now that we have both --pvmetadatacopies and --vgmetadatacopies,
we need to make sure --metadatacopies gets interpreted correctly.

For pv commands, --metadatacopies should imply --pvmetadatacopies,
and for vg commands, --vgmetadatacopies.

Note: this will change the behavior of vgcreate with --metadatacopies
to be a synonym for --vgmetadatacopies.  Previously, --metadatacopies
would apply to any PVs given with vgcreate that needed an implicit
pvcreate.  As a result, one small change is needed to one of the nightly
tests - t-vgcreate-usage.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:39:39 +00:00
Dave Wysochanski
457bc4fb63 Add --vgmetadatacopies to vgsplit man page and command.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:39:24 +00:00
Dave Wysochanski
eeb7ce60ae Update _vgmerge_single() to move fid->metadata_areas_ignored.
When vgmerge is called we move the mdas from the source to the
destination.  With metadata balancing we now have another mda
list, fid->metadata_areas_ignored, so move the mdas on this list
as well.

This patch should not matter as the code is written today.  However
we include it for completeness in the case that _vgmerge_single()
is refactored and/or moved into a library function.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:39:08 +00:00
Dave Wysochanski
e52586db1c Update check in vg_split_mdas to account for ignored mdas list.
The check in vg_split_mdas will trigger an error if the 'from' vg
list is empty.  However, this might be ok in some instances now
that we have ignored mdas.  Relax this check so an error is triggered
only in the case where there's truly no more mdas in the 'from'
vg.

One example of where this makes a difference is with vgreduce.
If we try to vgreduce a PV with un-ignored mdas, this should trigger
the balancing function to un-ignore mdas on another PV in the VG.
However, we don't get to vg_write() before we fail because this
list size check fails, and we see an error message indicating:
"Cannot remove final metadata area ..."

Another example is with vgsplit into a new VG, where the PVs
being moved contain all ignored mdas.  We must move the mdas on
fid->metadata_areas_ignored from 'vg_from' to 'vg_to'.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:38:56 +00:00
Dave Wysochanski
6cb9642200 Ensure fid mda lists are populated correctly during vgextend.
The vgextend path calls add_pv_to_vg().  Inside add_pv_to_vg(),
we must ensure we pass the correct mdas list into pv_setup(), as
copies of mdas are placed on the vg->fid list.  If we don't place
the mdas on the correct vg->fid list, the various counts may be
incorrect and the metadata balance algorithm will not work when
called from vg_write() path.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:38:39 +00:00
Dave Wysochanski
7ebd46ee53 Add --vgmetadatacopies to vgcreate man page, command, and lvm.conf.
Allow parsing of --vgmetadatacopies for vgcreate.  Accept
--metadatacopies as a synonym for --vgmetadatacopies.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:38:23 +00:00
Dave Wysochanski
d575dfe440 Set vg_mda_copies when pvchange --metadataignore is given.
When a user explicitly sets a new mda ignore value for a PV, we
should update vg_mda_copies accordingly.  When the VG is written
out, the user would not want the new ignore state to get lost as
a result of the vg_mda_copies value and logic in the vg_write
path.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:38:06 +00:00
Dave Wysochanski
074c1880ff Implement _vg_adjust_ignored_mdas and call from vg_write() path.
Compare the value of the newly added vg_mda_copies field
(--vgmetadatacopies parameter) with the current count of
in-use mdas and ignoring or unignoring mdas as necessary to
get to the target count.  Also, as a safety check before
returning, ensure we have at least one mda enabled.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:37:54 +00:00
Dave Wysochanski
b53c1011fc Update vgchange tool to accept --vgmetadatacopies.
Update logic in vgchange to handle --vgmetadatacopies, allow
--metadatacopies as a synonym to --vgmetadatacopies,
and add these parameters to args.h and commands.h
Forbit both --vgmetadatacopies and --metadatacopies as only
one allowed.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:37:37 +00:00
Dave Wysochanski
11f35d31d9 Add vg_mda_copies display field to 'vgs' command.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:37:23 +00:00
Dave Wysochanski
36d07a5cea Make vg->mda_copies persistent in on disk vg metadata.
This patch adds the ability to read/write the vg->mda_copies values
from/to the vg metadata.

If we read the VG metadata and this field does not exist, we set
mda_copies to the default value of 0.  Later in the code, we use
this special '0' value to indicate a disable of metadata balancing.
This should preserve existing LVM behavior and ensure metadata balancing
can be turned off should the need arise.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:37:10 +00:00
Dave Wysochanski
12910a5a29 Add vg get/set methods for VG metadata copies.
This patch adds the get and partially implemented set function.
The 'set' function should probably ignore or un-ignore metadata areas
based on new values.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:36:56 +00:00
Dave Wysochanski
eb93c134a7 Add mda_copies to VG structures and initialization.
Add a field to struct volume_group to later implement metadata
balancing:
- mda_copies: target # of non-ignored mdas in the VG; default 0 (do
not control pv 'ignore mdas' bit.

This patch just adds the parameter to the structures with the default
values but does not modify any commands.  Should be no functional change.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:36:37 +00:00
Dave Wysochanski
493ad74331 Define vgmetadatacopies in vgchange man page.
This patch adds a vgmetadatacopies parameter for metadata balancing.
This parameter provides a simple way for users to create a policy for
placing metadata on PVs automatically by LVM.  The behavior is implemented
inside LVM by managing the 'ignore' mda bits.  We chose the name
'vgmetadatacopies' as this is a natural extension to the existing parameter
'pvmetadatacopies' / 'metadatacopies' in pvcreate.

This is a first step at VG parameter based metadata balancing.  Most users
will probably want to state that they want a certain number of PVs to contain
metadata, and they may be less concerned about a specific number of metadata
copies in the volume group.  However, for default values (pvmetadatacopies
is 1 by default), the number of metadatacopies in the volume group, and the
number of PVs with metadata are the same.  In the future we could add
vgmetadatacopiespvs to define more specifically the number of pvs in the
VG that contain metadata, but for now we start with this parameter.

Another possible future extension would be to define a specific pv tag
to mark the set of PVs that should be used for metadata balancing.  This
tag based approach could be used in conjunction with 'vgmetadatacopies'.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:36:18 +00:00
Dave Wysochanski
a563816d3a Add tests for phase 1 of metadata balance - manage per-PV ignore bit.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:36:06 +00:00
Dave Wysochanski
43526902ae Before committing each mda, arrange mdas so ignored mdas get committed first.
Arrange mdas so mdas that are to be ignored come first.  This is an
optimization that ensures consistency on disk for the longest period of time.
This was noted by agk in review of the v4 patchset of pvchange-based mda
balance.

Note the following example for an explanation of the background:
Assume the initial state on disk is as follows:
PV0 (v1, non-ignored)
PV1 (v1, non-ignored)
PV2 (v1, non-ignored)
PV3 (v1, non-ignored)

If we did not sort the list, we would have a commit sequence something like
this:
PV0 (v2, non-ignored)
PV1 (v2, ignored)
PV2 (v2, ignored)
PV3 (v2, non-ignored)

After the commit of PV0's mdas, we'd have an on-disk state like this:
PV0 (v2, non-ignored)
PV1 (v1, non-ignored)
PV2 (v1, non-ignored)
PV3 (v1, non-ignored)

This is an inconsistent state of the disk. If the machine fails, the next
time it was brought back up, the auto-correct mechanism in vg_read would
update the metadata on PV1-PV3.  However, if possible we try to avoid
inconsistent on-disk states.  Clearly, because we did not sort, we have
a greater chance of on-disk inconsistency - from the time the commit of
PV0 is complete until the time PV3 is complete.

We could improve the amount of time the on-disk state is consistent by simply
sorting the commit order as follows:
PV1 (v2, ignored)
PV2 (v2, ignored)
PV0 (v2, non-ignored)
PV3 (v2, non-ignored)

Thus, after the first PV is committed (in this case PV1), on-disk we would
have:
PV0 (v1, non-ignored)
PV1 (v2, ignored)
PV2 (v1, non-ignored)
PV3 (v1, non-ignored)

This is clearly a consistent state.  PV1 will be read but the mda will be
ignored.  All other PVs contain v1 metadata, and no auto-correct will be
required.  In fact, if we commit all PVs with ignored mdas first, we'll
only have an inconsistent state when we start writing non-ignored PVs,
and thus the chances we'll get an inconsistent state on disk is much
less with the sorted method.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:35:49 +00:00
Dave Wysochanski
b6ec0f9b92 Refactor vg_commit() to add _vg_commit_mdas().
Factor out calling mda->ops->vg_commit() for each mda.
No functional change.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:35:33 +00:00
Dave Wysochanski
4e7f1a3a9d Update _vg_read and _text_create_text_instance to use fid_add_mda[s].
When we are constructing the vg, we may need to adjust the list of
metadata_areas if there are ignored mdas.  At label read time, we
do not read the metadata of ignored mdas, and as a result, they do
not get placed on vg->fid->metadata_areas inside _text_create_text_instance
since lvmcache does not have these areas attached to vginfo->infos.
However, when we're checking the pvids inside _vg_read, after having
read another metadata area from another PV, we do have the opportunity
to update the metadata_area and metadata_areas_ignored lists based
on the read metadata_area.  We need accurate mda lists for the reporting
functions that count the ignored mdas, as well as general correctness
of mda balancing.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:35:17 +00:00
Dave Wysochanski
50e879ef56 Use mdas_empty_or_ignored() in place of checks for empty mda list.
With the addition of ignored mdas, we replace all checks for an empty
mda list with a new function to look for either an empty mda list or
ignored mdas.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:34:58 +00:00
Dave Wysochanski
06468b9049 Add mdas_empty_or_ignored() helper function.
Add a helper function to consolidate checking for an empty mdas list
or ignored mdas.  Ignored mdas should behave almost identically to
an empty mda list - the metadata areas should not be read or written
to.  This function will make it easier to implement metadata balancing
and easier to track pvs with an empty mda list or ignored mdas.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:34:40 +00:00
Dave Wysochanski
2bdbceca91 Implement ignore of mda if bit set by skipping r/w of metadata.
We implement ignore of an mda at label_read time by checking for
the ignore bit, and then skipping the reading of the vgname and
other information in the metadata.  This will have an effect similar
to a PV found with no mdas.  Thus, it will look like an orphan in the
cache until we scan the rest of the system and find a PV with
metadata, and the mda will not be on the vg->fid->metadata_areas
list so no read/writes will be done to the metadata area.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:34:24 +00:00
Dave Wysochanski
d34d85efdd Update pvchange, pvs and vgs man pages for metadata ignore.
Explain --metadataignore argument to pvchange, add new fields to pvs / vgs.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:34:12 +00:00
Dave Wysochanski
7e3278ae8f Add --metadataignore to pvchange, allowing for ignoring of metadata areas.
This patch just modifies pvchange to call the underlying ignore
functions for mdas.  Ensure special cases do not reflect changes
in metadata (PVs with 0 mdas, setting ignored when already ignored,
clearing ignored when not ignored).

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:33:58 +00:00
Dave Wysochanski
bca7c09e6c Define new functions and vgs/pvs fields related to mda ignore.
Define a new pvs field, pv_mda_used_count, and a new vgs field,
vg_mda_used_count to match the existing pv_mda_count and vg_mda_count.
These new fields count the number of mdas that have the 'ignored' bit
clear (they are in use on the PV / VG).  Also define various supporting
functions to implement the counting as well as setting the ignored
flag and determining if an mda is ignored.  These high level functions
call into the lower level location independent mda ignore functions
defined by earlier patches.

Note that counting ignored mdas in a vg requires traversing both lists
and checking for the ignored bit on the mda.  The count of 'ignored'
mdas then is defined by having the bit set, not by which list the mda
is on.  The list does determine whether LVM actually does read/write to
the mda, though we must count the bits in order to return accurate numbers
for the various counts.  Also, pv_mda_set_ignored must search both vg
lists for ignored mda.  If the state changes and needs to be committed
to disk, the ignored mda will be on the non-ignored list.

Note also in pv_mda_set_ignored(), we must properly manage the mda lists.
If we change the ignored state of an mda, we must change any mdas on
vg->fid->metadata_areas that correspond to this pv.  Also, we may
need to allocate a copy of the mda, as is done when fid->metadata_areas
is populated from _vg_read(), if we are un-ignoring an ignored mda.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:33:44 +00:00
Dave Wysochanski
2e163858fc Add metadata_areas_ignored list and functions to manage ignored mdas.
Add a second mda list, metadata_areas_ignored to fid, and a couple
functions, fid_add_mda() and fid_add_mdas() to help manage the lists.

These functions are needed to properly count the ignored mdas and
manage the lists attached to the 'fid' and ultimately the 'vg'.

Ensure metadata_areas_ignored is initialized in other formats, even
if the list is never used.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:33:22 +00:00
Dave Wysochanski
0ad2a4c72f Rename fid->metadata_areas to fid->metadata_areas_in_use.
Rename the metadata_areas list to an 'in_use' list to prepare for
future 'ignored' list.
2010-06-28 20:32:44 +00:00
Dave Wysochanski
b69ca133af Use vg_mda_count() in vgdisplay.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:32:21 +00:00
Dave Wysochanski
d4f0f090c0 Add mda location specific mda_copy constructor.
Because of the way mdas are handled internally, where a PV in a VG
has mdas on both info->mdas and vg->fid->metadata_areas list, we
need a location independent copy constructor for struct
metadata_area.  Break up the existing format-text specific copy
constructor into a format independent piece and a format dependent
piece.

This function is necessary to properly implement pv_set_mda_ignored().

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Reviewed-by: Alasdair G Kergon <agk@redhat.com>
2010-06-28 20:31:59 +00:00
Dave Wysochanski
e56f421490 Add mda_locns_match() internal library function for mapping pv/device to VG mda.
A metadata_area is defined independent of the location.  One downside
is that there is no obvious mapping from a pv to an mda.  For a PV in
a VG, we need a way to start with a PV and end up with an MDA, if we
are to manage mdas starting with a device/pv.  This function provides
us a way to go down the list of PVs on a VG, and identify which ones
match a particular PV.

I'm not entirely happy with this approach, but it does fit into the
existing structures in a reasonable way.

An alternative solution might be to refactor the VG - PV interface such
that mdas are a list tied to a PV.  However, this seemed a bit tricky since
a PV does not come into existence until after the list of mdas is
constructed (see _vg_read() - we create a 'fid' and attach mdas to it,
then we go through them and attach pvs).

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Reviewed-by: Alasdair G Kergon <agk@redhat.com>
2010-06-28 20:31:38 +00:00
Dave Wysochanski
c9b93bf65a Ensure in-memory state matches on-disk state of mda ignore bit.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:31:18 +00:00
Dave Wysochanski
9b8ce15725 Allow raw_read_mda_header to be called from text_label.c.
We'd like to pass in mda_header to vgname_from_mda().  In order to
do this, we need to call raw_read_mda_header() from text_label.c,
_text_read(), which gets called from the label_read() path, and
peers into the metadata and update vginfo cache.  We should check
the disable bit here, and if set, not peer into the vg metadata,
thus reducing the I/O to disk.

In the process, move vgname_from_mda() to layout.h, since the fn
only gets called from format_text code, and we need the mda_header
definition from the private layout.h.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:31:01 +00:00
Dave Wysochanski
014e7daa36 Move dev_open/dev_close outside vgname_from_mda().
Refactor vgname_from_mda() so caller must open/close the device.
Should be no functional change.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:30:46 +00:00
Dave Wysochanski
306e3b86f1 Move dev_open / dev_close outside _vg_read_raw_area().
This refactoring moves the device open/close up one level to the caller of
_vg_read_raw_area().  Should be no functional change and facilitate future
changes related to metadata balancing.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:30:30 +00:00
Dave Wysochanski
ce7cf5f46b Add location independent flag and functions to ignore mdas.
First we add a 'flags' field to the location independent
metadata_area structure, and a MDA_IGNORE flag.  The
mda_is_ignored and mda_set_ignored functions are added to
manage the flag.  Adding the flag and functions gives a
library interface to ignore metadata areas independent of
the underlying location (disk, file, etc).  The location
specific read/write functions must then handle the specifics
of what this flag means to the location.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Reviewed-by: Alasdair G Kergon <agk@redhat.com>
2010-06-28 20:30:14 +00:00
Dave Wysochanski
3c3b5e0dbf Add text format specific 'rlocn' ignore flag and access functions.
Adding a flag to the 'rlocn' structure in the mda header of the
text format allows us to flip a bit to ignore an area on disk that
stores the metadata via the text format specific mda_header.
This patch defines the flag and access functions to manage the flag.
Other patches will manage the ignore on a format-independent basis,
by using a flag in the metadata_area structure.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:29:57 +00:00
Dave Wysochanski
0fc136fcc7 Change 'filler' to 'flags' in on-disk 'raw_locn' structure.
Future patches will make use of a specific flag in the on-disk 'raw_locn'
structure to enable/disable metadata areas, and facilitate metadata
balancing.

Note that 'filler' is always set to '0' (see add_mda() - memset),
so use of this area as a non-zero flags field is a safe way to
provide future code features.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-06-28 20:29:42 +00:00
Petr Rockai
80328439be Minor shell style cleanup. 2010-06-28 19:13:33 +00:00
Petr Rockai
3c649de483 Refactor the handles_missing_pv logic in lvchange. 2010-06-28 19:10:16 +00:00
Jonathan Earl Brassow
184ca578a0 Fix for bz608048 from Taka...
The same region size is used for both mirror volume and mirrored
log volume, but when the physical extent size is bigger than region size,
the size of mirror leg for mirrored log is smaller than the region size
and lvcreate command fails.

This patch adjusts a region size of mirrored log to a smaller value of
region size or physical extent size.

[This patch ensures that the region_size of the mirrored log does not
exceed the size of the mirrored log itself, which would violate the
kernel constraint: (region_size <= ti->len).]

Signed-off-by: Takahiro Yasui <takahiro.yasui@hds.com>
Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
2010-06-28 14:19:41 +00:00
Alasdair Kergon
3643acadac generate liblvm2cmd exported symbols too 2010-06-25 18:23:10 +00:00
Alasdair Kergon
1c78aa19ff Generate liblvm2app and libdevmapper exported symbols from header files.
Detection is simply by prefix - dm_ or lvm_ - and any additional symbols needed
but not detected this way are placed in .exported_symbols.
2010-06-25 18:17:38 +00:00
Alasdair Kergon
a64fec0722 actually, let's keep these in same order as in header 2010-06-25 12:21:47 +00:00
Alasdair Kergon
962811198f Update liblvm2app exported symbols.
Add Makefile target to generate current list of lvm2app.h functions.
2010-06-25 12:19:52 +00:00
Zdenek Kabelac
378c3b1641 Fix typo reported in Debian bugzilla #586043 2010-06-24 08:36:57 +00:00
Zdenek Kabelac
34c937510d Preload libc locale messages.
Preload libc.mo file for localized lvm before taking memory lock - this way
we prevent disk access for some error paths in libdm, that prints localized
errno messages while they are still in memory locked state.
2010-06-24 08:29:30 +00:00
Zdenek Kabelac
e924e9cfb2 Add few missing information about what is this script doing.
(based upon Debian bugzilla suggestion)
2010-06-24 08:18:54 +00:00
Petr Rockai
8f0fa65379 Add a test of wait_for_locks behaviour (adapted from an original by Dave). 2010-06-24 07:57:54 +00:00
Jonathan Earl Brassow
00268c1b82 update WHATS_NEW file with entry for simultaneous mirror image and
mirrored log image fault-handling fix.
2010-06-23 21:01:42 +00:00
Jonathan Earl Brassow
7ab37c0ffc Committing Taka's patch... He found a problem during
the failure of a device that contained both a image of
a mirror and an image of the mirrored log.  The order
of the handling of those faults was important (and
wrong), this patch corrects that.

Patch-From: Takahiro Yasui <tyasui@redhat.com>
2010-06-23 20:32:29 +00:00
Alasdair Kergon
4cae37c340 post-release 2010-06-23 19:35:11 +00:00
Alasdair Kergon
63f8ad01b2 pre-release 2010-06-23 17:48:41 +00:00
Alasdair Kergon
1a6159aca5 In some C++ standards, typeof is not reserved. 2010-06-23 17:03:14 +00:00
Peter Rajnoha
60e9c014a2 Fix udev rules to handle spurious events properly.
We can use DM_UDEV_PRIMARY_SOURCE_FLAG to identify the spurious events
and use it as an indication that the device has already been activated before
(and hence we can find this property in udev database).

WARNING: This change requires udev startup script to preserve udev database
from initrd. All the information stored there during activation of devices
is important for the initial "udevadm trigger --action=add" call that is
used in udev startup script. If not done this way, udev startup script needs
to define DM_UDEV_PRIMARY_SOURCE_FLAG=1 property for any ADD events it uses.
2010-06-23 17:00:32 +00:00
Milan Broz
8f3295456d Fix clvmd init script status
- s/Active clustred VG/clustered VG/ (only LV can be active)

- print only active LVs (not all) in status command
(In the lvdisplay form /dev/vg/lv.)

For now, still use awk (already used in clustered_vgs).

https://bugzilla.redhat.com/show_bug.cgi?id=598495
2010-06-23 16:24:13 +00:00
Mike Snitzer
78df2efac2 Use more standard naming for PVs and VG in vgimportclone example. 2010-06-23 16:12:30 +00:00
Mike Snitzer
546357eaeb Cleanup sentences of the example provided in the vgimportclone man page
(motivated by a patch that Debian was carrying).
2010-06-23 14:15:55 +00:00
Jonathan Earl Brassow
50552f3fd5 The function that runs to compress a stacked mirror after
converting from 2-way to 3-way mirror (collapse_mirrored_lv)
was calling '_remove_mirror_images' with the 'remove_log'
parameter set.  When the code was put in to fix 599898 to
honor log parameters during conversion, this argument was
suddenly being honored.  Thus, when someone would convert from
a 2-way to 3-way mirror, the log would get removed.

'collapse_mirrored_lv' should not be calling '_remove_mirror_images'
with 'remove_log' set.
2010-06-23 13:57:26 +00:00
Zdenek Kabelac
7d62ac4b34 Fix typo: "INTERNAL ERROR" -> "INTERNAL_ERROR"
Author: Xinwei Hu
        xwhu at novell dot com
2010-06-23 12:54:46 +00:00
Alasdair Kergon
beb14c3fa7 Add lv_path to reports to offer full /dev pathname. 2010-06-23 12:32:08 +00:00
Zdenek Kabelac
a15d3d8dcc Fix typo: premitted -> permitted
Signed-off-by: Takahiro Yasui<tyasui@redhat.com>
2010-06-23 10:22:59 +00:00
Zdenek Kabelac
9c7755c862 Better WHATS_NEW message - as we still have not fixed 'make exec_prefix' build 2010-06-23 10:21:00 +00:00
Milan Broz
866553e76f Fix "allocated" warning typo. 2010-06-22 21:10:53 +00:00
Dave Wysochanski
f8f2be527f Add device name to output of error messages in raw_read_mda_header().
It would be helpful if we had the device name when something like
a mda_header checksum error occurs.

Before:
./tools/lvm pvs -opv_name,vg_name,uuid,mda_count,pv_mda_count_ignored,vg_mda_count,vg_mda_count_ignored,vg_mda_copies
  Incorrect metadata area header checksum
  PV         VG      PV UUID                                #PMda #PMdaIgn #VMda #VMdaIgn #VMdaCps
  /dev/loop0 vgtest2 sVv26t-gjpb-Rcau-uBDO-Cx04-GbRR-6Ssq7e     2        0     4        0        4
  /dev/loop1 vgtest2 zXWStT-qE8F-mbkc-RfgH-aytv-mptF-Y5Ce09     2        0     4        0        4
  /dev/loop2         riCpK9-9G8r-LlIp-i2oh-mb3N-CUzk-u5YpuR     1        0     0        0        0
  /dev/loop3 vgtest  tQCUjm-rmyd-i92d-4eeE-UYBW-v1vQ-kRaA17     2        0     4        2        0
  /dev/loop4 vgtest  ZRvpeI-p8F1-ccVW-BBac-xhl1-aGXU-CbP0oo     2        2     4        2        0

After:
./tools/lvm pvs -opv_name,vg_name,uuid,mda_count,pv_mda_count_ignored,vg_mda_count,vg_mda_count_ignored,vg_mda_copies
  Incorrect metadata area header checksum on /dev/loop2 at offset 4096
  PV         VG      PV UUID                                #PMda #PMdaIgn #VMda #VMdaIgn #VMdaCps
  /dev/loop0 vgtest2 sVv26t-gjpb-Rcau-uBDO-Cx04-GbRR-6Ssq7e     2        0     4        0        4
  /dev/loop1 vgtest2 zXWStT-qE8F-mbkc-RfgH-aytv-mptF-Y5Ce09     2        0     4        0        4
  /dev/loop2         riCpK9-9G8r-LlIp-i2oh-mb3N-CUzk-u5YpuR     1        0     0        0        0
  /dev/loop3 vgtest  tQCUjm-rmyd-i92d-4eeE-UYBW-v1vQ-kRaA17     2        0     4        2        0
  /dev/loop4 vgtest  ZRvpeI-p8F1-ccVW-BBac-xhl1-aGXU-CbP0oo     2        2     4        2        0
2010-06-22 19:18:27 +00:00
Milan Broz
88880e1f89 Use flexible data[] in cmirrord request to prevent abort in runtime size checks. 2010-06-22 13:11:29 +00:00
Zdenek Kabelac
3cce4419c2 Adding section number for lvm.conf manpages. 2010-06-22 07:34:34 +00:00
Jonathan Earl Brassow
bc59859a59 Mirrors can be layered - as in the case of an converting 2-way
to 3-way mirror.  When conversion operations are performed on
these types of mirrors, log options can be confused/ignored.

In the case of a converting 3-way mirror, we have a top-level
2-way corelog mirror whose legs are 1) a 2-way disk-log mirror
and 2) a linear device.  If we wish to convert this 3-way mirror
to a 2-way mirror, the linear device is removed and the extra
top layer is eliminated.  If we also wished to convert the disk
log to a core log in the same step, ambiguity creeps in.  It is
somewhat obvious what the user wants - a 2-way mirror with a
corelog.  However, looking at the top level mirror before
compression, it seems that the mirror already has a core log.
This is why the operation seemed to fail.

This patch simply re-evaluates what mirrored_seg points to after
a compression and then considers the log argument.

This is a fix for bug 599898.
2010-06-21 16:12:33 +00:00
Jonathan Earl Brassow
ecf06d3a49 Add error checking for calls to sprintf - it can fail for more
reasons than just 'out-of-space'.
2010-06-21 16:07:06 +00:00
Alasdair Kergon
d48af1520d Various cleanups following recent commits. 2010-06-21 15:56:57 +00:00
Milan Broz
aa9797fa3c Let running clvmd process time to reexec.
Because execve stops the command loop,
we never receive response (only socket close) for clvmd -S,
so waiting for response here makes no sense.

But if the calling process (clvmd -S)  exits too early, connection
is closed from client side, clvmd takes this as an error and
never run restart code.

Ugly hack(TM).
2010-06-21 10:45:15 +00:00
Peter Rajnoha
44a82780b9 Use early udev synchronisation and update of dev nodes for clustered mirrors.
When using clustered mirrors, we need device nodes to be created during
processing of device tree, not at its end like we normally do (we need to
access the nodes in cmirror prematurely). Therefore we use a new flag called
"immediate_dev_node" stored in deptree's load_properties struct to instruct the
device tree processing code to immediately synchronize with udev and flush all
stacked node operations so the nodes are prepared for use.

For now, the immediate_dev_node is used for clustered mirrors during
processing the dm_tree_preload_children code only. We can add more later if
needed.
2010-06-21 08:54:32 +00:00
Jonathan Earl Brassow
c76681596e daemons/cmirrord/functions.c (part of cmirrord) was referencing
linux/kdev_t.h even though it wasn't needed.  Strangely, it seems
to be causing problems on various architectures (i686) in the
function daemons/cmirrord/functions.c:disk_status_info()->sprintf.

I'm not sure why this is a problem since none of the macros in
kdev_t.h are used in that code, but it certainly doesn't hurt to
pull an unnecessary header and it seems to fix the problem.
2010-06-18 20:58:04 +00:00
Zdenek Kabelac
3ce8520c5e Add man pages for lvmconf and unsupported lvmsadc and lvmsar tools. 2010-06-18 10:19:29 +00:00
Milan Broz
01f5823ee4 Fix exit code when requesting help using documented -o help option.
IOW fix lvs -o help
...
  Command failed with status code 5.
2010-06-17 13:15:51 +00:00
Milan Broz
c7ec3c65f4 Clean up cluster lock mode and flags definition.
Code is mixing up internal DLM and LVM definitions of lock
modes and flags.

OpenAIS and singlenode locking do not depend on DLM but
code currently cannot be compiled without libdlm.h!

LCK_* flags is LVM abstraction, used through all the code.
Only low-level backend (clvmd-cman etc) should use DLM definitions,
also this code should do all needed conversions.

Because there are two DLM flags used in generic code
(NOQUEUE, CONVERT) we define it similar way like lock modes.
(So all needed binary-compatible flags are on one place in locking.h)

(Further code cleaning still needed, though:-)
2010-06-17 12:48:54 +00:00
Zdenek Kabelac
d01b8d03db Add man page for dmeventd
(inspired by patch from Danny Rawlins, monster.romster at gmail dot com)
2010-06-17 12:14:43 +00:00
Zdenek Kabelac
41ff900c99 Update lvresize/extend/reduce manpages with --nofsck, --resizefs options 2010-06-17 11:25:43 +00:00
Milan Broz
9ca07f4298 Fix lvm2cmd example in documentation. 2010-06-16 13:03:48 +00:00
Milan Broz
0e93522190 Remove C++ private keyword from headers.
Add extern C definition for libdevmapper, lvm2app and lvm2cmd.
2010-06-16 13:01:25 +00:00
Zdenek Kabelac
ebd1d49150 Use "" instead of <> for configure.h and libdevmapper.h
Move configure.h as the first header for clvmd source files.
2010-06-15 11:00:44 +00:00
Zdenek Kabelac
057462c4e6 Update WHATS_NEW for last commit 2010-06-07 14:39:18 +00:00
Zdenek Kabelac
b5e36cb96b Fix wrong usage of exec_prefix from previous patch introducing LVM_PATH define
Introduce lvm_exec_prefix with resolved exec_prefix.
(using same ac_default_prefix as for CLVMD_PATH)
Use lvm_exec_prefix instead of dmeventd_prefix (fixes missing ac_default_prefix)

Note: This patch is rather hot-fix as currently generate code
does not create correct code for make exec_prefix=
2010-06-07 14:31:59 +00:00
Milan Broz
f58ca71942 Fix segfault in clvmd -R if no response from daemon received. 2010-06-07 13:52:52 +00:00
Alasdair Kergon
262a39dfd0 post-release 2010-06-07 10:25:43 +00:00
Alasdair Kergon
d531d56dbb pre-release 2010-06-04 17:23:49 +00:00
Milan Broz
8b78a832fa Fix restart of clvmd using -S switch
- allocate environment dynamically (still missing some limit?)
 - try to recover, if destroy failed (do not destroy lvm here) and free memory
 - check strdup() return codes
 - report failure to log
 - do not print NULL in exclusive lock loop
2010-06-04 12:59:30 +00:00
Milan Broz
8c19b52bda Fix clvmd initscript restart command to start clvmd if not yet running. 2010-06-03 21:03:53 +00:00
Zdenek Kabelac
a7237281ea Use INSTALL_DIR to create directories 2010-06-03 13:52:21 +00:00
Zdenek Kabelac
0b6ee2252c Use absolute paths in commands
clvmd restart does not work at all if clvmd binary is not in current
dir.
2010-06-03 13:50:26 +00:00
Milan Broz
a9ffbb0803 Require partial option in lvchange --refresh for partials LVs.
We must not refresh LV if some PVs are missing and partial activation
was not requested.

Fixes https://bugzilla.redhat.com/show_bug.cgi?id=598886
2010-06-03 12:45:05 +00:00
Dave Wysochanski
224457fb0f Revert _init_rand() to reset errno - restores original init behavior. 2010-06-01 21:47:57 +00:00
Dave Wysochanski
cacbf14d8e Do not fail lvm_init() if init_logging() generates an errno.
Revert to original behavior of lvm commands if init_logging() generated an
errno.  Fixes rhbz 592967.
2010-06-01 21:46:29 +00:00
Alasdair Kergon
b00dc7153a Don't merge unchanged persistent cache file before dumping if tool scanned. 2010-06-01 19:02:12 +00:00
Peter Rajnoha
9dbad2f74d Add support for dm-mod module autoload.
A kernel patch is on its way for 2.6.35 adding support for dm-mod module
autoload. Udev v155 and higher is able to read static node information given
in modules.devname (extracted by depmod before) and will create such nodes
at its start. The first access to such node will load the module automatically
(directly in kernel) before the actual read/write operation is processed.
2010-06-01 16:08:13 +00:00
Peter Rajnoha
97617cfc76 Fix incorrect memory pool deallocation while using vg_read for files.
We create a separate pool "lvm2 vg_read" for vg_read and we don't use
cmd->mem anymore.
2010-06-01 12:08:50 +00:00
Mike Snitzer
735cac19f2 Add --type parameter description to the lvcreate man page. 2010-05-28 03:50:15 +00:00
Mike Snitzer
3755951091 Document 'clear' in dmsetup man page. 2010-05-27 19:00:14 +00:00
Peter Rajnoha
60af6fb0a2 Use expected union semun for arguments in selected semaphore operations.
This is standard and expected use. It also prevents errors related with
misalignment of the arguments for semaphore operations on some architectures.
2010-05-27 15:02:56 +00:00
Zdenek Kabelac
333cf73ceb Fix copy&paste detection of kernel release version.
Add log_error to avoid return_0 without log_error.
2010-05-25 08:40:36 +00:00
Alasdair Kergon
bc653452a7 Replace strncmp kernel version number checks with proper ones 2010-05-24 23:11:34 +00:00
Alasdair Kergon
ca92b9a5f0 Avoid selecting names under /dev/block if there is an alternative. 2010-05-24 22:53:48 +00:00
Milan Broz
afe102c0fe Fix topology test after last changes to not leak loop devices. 2010-05-24 19:27:38 +00:00
Alasdair Kergon
fa7fa300e3 Choose between clustered log versions based on kernel version.
Add fixmes for broken strcmp.
2010-05-24 17:46:47 +00:00
Milan Broz
3c2b019578 Use mv -f for replace config in test. 2010-05-24 17:19:50 +00:00
Milan Broz
87003ba5b1 Replace lvm.conf instead of truncating it. 2010-05-24 17:18:05 +00:00
Petr Rockai
bf7d3d2208 t-lvconvert-repair-transient hangs on .33 and on RHEL6 kernel -> disable 2010-05-24 16:33:21 +00:00
Alasdair Kergon
4e553333d9 Update clustered log kernel module name to log-userspace. 2010-05-24 16:30:15 +00:00
Petr Rockai
954df8f3d7 Account for mirror transient status when doing lvconvert --repair. 2010-05-24 15:32:20 +00:00
Petr Rockai
078573dc2c Skip t-pvcreate-operation-md if mdadm fails to create the required device. 2010-05-24 15:28:45 +00:00
Zdenek Kabelac
c4655582e6 Update Copyright date for resently modifed files 2010-05-24 09:04:27 +00:00
Zdenek Kabelac
360f97c31d Replicator: update activate code for vgchange
Activate only the first replicator-dev LV, that activates all other
related LVs from Replicator. In case of error during this activation,
it will not retry again for other heads (less confusing error log).
2010-05-24 09:03:39 +00:00
Zdenek Kabelac
f20300cc8b Replicator: add replicator to dtree
Adding all replicator related LVs to dtree.
Start of one replicator_dev initiate start of all other related.
2010-05-24 09:01:05 +00:00
Zdenek Kabelac
f687bd63b8 Replicator: VG with cmd_missing_vgs does not generate output
Do not print message if missing VG is found.
2010-05-24 08:59:29 +00:00
Mikulas Patocka
b68340f6d9 Fix scripts/relpath.awk to work with mawk
length(array) is specific to GNU awk and doesn't work in mawk.
Use a return value of "split" function to indicate array size, this is
supported in both gawk and mawk.

This patch fixes the following errors during "make install" when mawk is
installed as a default awk.

mawk: scripts/relpath.awk: line 25: illegal reference to array from
mawk: scripts/relpath.awk: line 25: illegal reference to array to
mawk: scripts/relpath.awk: line 27: illegal reference to array from
mawk: scripts/relpath.awk: line 32: illegal reference to array to

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
2010-05-21 15:28:16 +00:00
Zdenek Kabelac
c5eb266a80 Replicator: update _create_partial_dtree()
Adding function _add_partial_replicator_to_dtree() to create
partial tree for Replicator target.

Using dm_tree_node_set_presuspend_node() for Replicator.
2010-05-21 14:47:58 +00:00
Zdenek Kabelac
04f3cea84a Replicator: activate checks for missing vgs
Activation needs to have all remote VGs locked to pass for replicator.
So if activated LV is replicator-dev LV - read all remote VGs.
2010-05-21 14:34:01 +00:00
Zdenek Kabelac
c1fe5092c3 Replicator: lock_lv_vol() finds missing VGs
Find and check for all needed VGs before calling lock_vol().
2010-05-21 14:29:49 +00:00
Zdenek Kabelac
5257248ed9 Replicator: use cmd_vg for process_each_lv_in_vg()
As for _process_one_vg() we need similar retry loop for
process_each_lv_in_vg(). This patch retries to process
failed LVs with reopened VGs.

Patch does not add any extra repeated invocations if there is not
found any missing VG during LV processing.
2010-05-21 14:15:39 +00:00
Zdenek Kabelac
780010a268 Replicator: use cmd_vg list for _process_one_vg()
Patch modifes behavior of _process_one_vg().

In the first pass vg_read() collectis for replicator sorted list of
additional VGs during lock_vol().
If any other VG is needed by the replicator and it is not yet opened
then next iteration loop is taken with all collected VGs.

Flag vg->cmd_missing_vgs detects missing VGs.
2010-05-21 14:11:13 +00:00
Zdenek Kabelac
8571d54f61 Replicator: add read and release VGs for rsites
Add functions to read and release remote VGs for replicator sites
in activation context.
2010-05-21 14:07:16 +00:00
Zdenek Kabelac
13fed1e445 Add toolcontext.h header file. 2010-05-21 13:34:09 +00:00
Zdenek Kabelac
2179ff624c Remove files from wrong directory 2010-05-21 13:18:25 +00:00
Zdenek Kabelac
8b3434061e Right directory name for replicator files.
My local CVS was placing file in slightly different directory by using
obsolete files.
2010-05-21 13:17:20 +00:00
Zdenek Kabelac
68a6a348b5 Hmm - fixing cvs import mistake 2010-05-21 13:14:02 +00:00
Zdenek Kabelac
d8659175cd Replicator: add find_replicator_vgs
Adding find_replicator_vgs() function to find all needed
VGs for replicator-dev LV.

This function is later called before taking lock_vol().
2010-05-21 12:55:25 +00:00
Zdenek Kabelac
1431ddad9c Replicator: add sorted cmd_vg list
Introduce struct cmd_vg to store information about needed
volume group name, vgid, flags and the pointer to opened VG.

Keep VGs list in alphabetical order for locking order.

Introduce functions:
cmd_vg_add() add new cmd_vg entry.
cmd_vg_lookup() search cmd_vgs for vg_name.
cmd_vg_read() open VGs in cmd_vgs list.
cmd_vg_release() close VGs in reversed order.
2010-05-21 12:52:01 +00:00
Zdenek Kabelac
5f860775c8 Replicator: extend volume_group with list of VGs and flag
Add pointer to linked list of opened VGs. List temporarily keeps
the information about needed or locked and opened VGs for replicator target.

Also add cmd_missing_vgs flag information for quick check and
also for possible continuos process_each_lv() usage where we need
to detect whether failure has been caused by missing VG or
some other reason.
2010-05-21 12:47:46 +00:00
Zdenek Kabelac
65f5ed533f Replicator: extend _lv_each_dependency() with dependencies for Replicator devices 2010-05-21 12:45:18 +00:00
Zdenek Kabelac
c4276aad11 Replicator: check replicator segment
Check for possible problems within replicator structures.
Used also by vg_validate.
2010-05-21 12:43:02 +00:00
Zdenek Kabelac
d4ae0dedf2 Replicator: new files for Replicator target 2010-05-21 12:40:05 +00:00
Zdenek Kabelac
312a15d24e Replicator: base lvm2 support
Adding configure.in support for Replicators.
Adding basic lib lvm support for Replicators.
Adding flags REPLICATOR and REPLICATOR_LOG.
Adding segments SEG_REPLICATOR and SEG_REPLICATOR_DEV.
Adding basic methods for handling replicator metadata.
2010-05-21 12:36:30 +00:00
Zdenek Kabelac
bc1024812a Replicator: check open_count for parents of presuspend_node
For deactivation of Replicator check in advance that all heads
have open_count == 0. For this presuspend_node is used as all
head nodes are linking this control node.
2010-05-21 12:30:35 +00:00
Zdenek Kabelac
451be927a8 Replicator: support deactivate of replicator-dev nodes
Introducing dm_tree_node_set_presuspend_node() for presuspending child
node (i.e. replicator control target) before deactivation of parent node
(i.e. replicator-dev target).

This patch presents no functional change to current dtree - only
replicator target currently sets presuspend node for dev nodes.
2010-05-21 12:27:02 +00:00
Zdenek Kabelac
4839e5d913 Replicator: libdm support
Introducing new API calls:
dm_tree_node_add_replicator_target()
dm_tree_node_add_replicator_dev_target().

Define new typedef dm_replicator_mode_t.
2010-05-21 12:24:15 +00:00
Zdenek Kabelac
874d697f4c API change for args of process_each_lv_in_vg()
Patch adds failed_lvnames to the list of parameters for process_each_lv_in_vg().
If the list is not NULL it will be filled with LV names of failing LVs
during function execution.

Application could later reiterate only on failed LVs.
2010-05-21 12:21:51 +00:00
Zdenek Kabelac
f80cbe8c33 Return ECMD_FAILED for break in process_each_lv() and process_each_segment_in_lv() 2010-05-21 12:19:22 +00:00
Alasdair Kergon
154a7af5ee post-release 2010-05-20 23:21:53 +00:00
Alasdair Kergon
cea69ab9d0 Fix $(INSTALL_SCRIPT) 2010-05-20 22:54:58 +00:00
Alasdair Kergon
6b3f81e647 backup->cache 2010-05-20 22:32:44 +00:00
Alasdair Kergon
fbee662499 pre-release 2010-05-20 22:27:26 +00:00
Alasdair Kergon
eedf87f891 If unable to obtain snapshot percentage leave value blank on reports. 2010-05-20 22:24:33 +00:00
Alasdair Kergon
89cb3a410a Add make install_initscripts 2010-05-20 14:45:14 +00:00
Alasdair Kergon
ae1ec1b418 Add install_system_dirs makefile target.
Add configure options for system and locking directories.
2010-05-20 13:47:21 +00:00
Alasdair Kergon
c357c91b7d Generate example.conf so default lvm.conf contents can be configured. 2010-05-20 11:45:56 +00:00
Alasdair Kergon
b3f073c48c Install lvmconf script by default.
Remove unnecessary versioned dmeventd plugin symlinks.
2010-05-20 11:20:35 +00:00
Dave Wysochanski
cd8ffd8725 Remove another pvchange hack involving orphan VG names.
Unnecessary as a result of recent changes.
2010-05-19 15:34:10 +00:00
Dave Wysochanski
bbe4a85be1 Remove hack in pvchange to unlock orphan VG.
With agk's recent changes, the lock/unlock APIs can properly handle
orphan VG names.
2010-05-19 13:21:09 +00:00
Dave Wysochanski
7e6f58c0a9 Fix warnings with conversion of uuid.
More cleanup of uuid casting / structures is needed but for now just
cast like the rest of the code.
2010-05-19 12:12:47 +00:00
Dave Wysochanski
275654210d Update WHATS_NEW 2010-05-19 11:57:05 +00:00
Dave Wysochanski
f649252de9 Test lvm_vgname_from_{pvid|device}. 2010-05-19 11:53:30 +00:00
Dave Wysochanski
d3ce80e544 Add lvm2app interfaces to lookup a vgname from a pvid and pvname.
lvm2app forces applications to start with a volume group name,
open the volume group, then operate on individual pvs.  In some
cases the application may want to start with a device name rather
than the volume group name.  Today, if an application wants to
do this, it must iterate through all the volume groups to find
the volume group that the specific device is attached to.
These new interfaces allow the application to avoid such overhead.
Bump the lvm2app version number to 3.
2010-05-19 11:53:12 +00:00
Dave Wysochanski
ea956b4f6c Update pvchange to always obtain a vg handle for each pv to process.
Earlier patches added some infrastructure to lookup a vgname from
a pvname.  We now can cleanup some of the pvchange and other code
by requiring callers that want to modify some pv property:
1) lookup the vgname by the pvname
2) use the vgname to obtain a vg handle
3) get the pv handle from the vg handle

This should work going forward and be a much cleaner interface,
as we move away from pvs as standalone objects.
2010-05-19 11:53:00 +00:00
Dave Wysochanski
ada4c61860 Add find_vgname_from_{pvname|pvid} functions.
Some commands start with a pvname, but we'd like to force users to
start with a vg handle to obtain a pv handle.  Our best option seems
to be providing a way to look up the vgname from the pvname, and then
require them to use vg_read/vg_open.

In addition to the pvname lookup function, this patch also provides a
lookup by pvid.  The lookup by pvid can be used in conjunction with
lvmcache_get_pvids to process all pvs in the system.

The pvid find function first calls lvmcache_vgname_from_pvid, which may
cause the label to be read if it is not in the cache.  If the vgname is
returned is an orphan, we then check to see if there are metadata areas,
and if not, we scan every PV on the system by calling scan_vgs_for_pvs().
In most cases we should not need to do this, and by using the info->mdas
count, we avoid calling pv_read() as prior code did.  So this patch is a
bit cleaner and should allow us to refactor more of the pv code.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-05-19 11:52:37 +00:00
Dave Wysochanski
9bcaa94756 Add lvmcache_vgname_from_pvid().
Add lvmcache function to lookup a vgname from a pvid.
2010-05-19 11:52:21 +00:00
Dave Wysochanski
49a81e190e Add pvid_from_devname() lvmcache function.
Add supporting function for mappings from devname -> pvid -> vgname.
2010-05-19 11:52:07 +00:00
Alasdair Kergon
5303eca8fa Add is_global_vg and split out from is_orphan_vg. 2010-05-19 02:36:33 +00:00
Alasdair Kergon
1b37183e74 Validate orphan and VG_GLOBAL lock order too. 2010-05-19 02:08:50 +00:00
Alasdair Kergon
09f17bf72d Note that orphan lock is always obtained last 2010-05-19 01:49:08 +00:00
Alasdair Kergon
449ffc7b05 Accept orphan VG names as parameters to lock_vol() and related functions. 2010-05-19 01:16:40 +00:00
Alasdair Kergon
bea9cf6725 Use is_orphan_vg in place of hard-coded prefix tests. 2010-05-19 00:52:55 +00:00
Alasdair Kergon
a0c7ead88f post-release 2010-05-17 20:18:13 +00:00
Alasdair Kergon
3eb97ffa25 pre-release 2010-05-17 18:39:01 +00:00
Fabio M. Di Nitto
48d651f492 Fix clvmd init script stop function to not deactive non-clustered volume groups.
https://bugzilla.redhat.com/show_bug.cgi?id=592362
2010-05-17 03:18:27 +00:00
Jonathan Earl Brassow
0d272a6964 Disallow toggling the cluster attribute of a volume group if there
are active mirrors or snapshots.

We don't have the mechanisms in place to change the device-mapper
tables for those targets that have behavioral differences between
cluster and single machine instances.  Allowing users to change
the attribute but not changing the target's behavior can lead to
data corruption.

The following bugs are fixed/avoided by this patch:
235123 - vgchange -c [ny] do not change target types when necessary
289331 - RFE: switching from cluster domain to local domain needs to deactivate volume somehow
289541 - when changing from local to cluster, volumes can not appear to be deactivated
2010-05-14 15:19:42 +00:00
Alasdair Kergon
578c4098e6 Use -d to control level of messages sent to syslog by dmeventd.
Change -d to -f to run dmeventd in foreground.
(mornfall)
2010-05-14 14:56:39 +00:00
Alasdair Kergon
c34cb6adcf Fix static build. 2010-05-14 13:36:56 +00:00
Zdenek Kabelac
cb5d05fd34 For lcov target there is no need to include source file dependencies 2010-05-14 13:32:36 +00:00
Milan Broz
5899d9b442 Another one internal device layer fix... 2010-05-14 12:39:52 +00:00
Milan Broz
40026b0762 Fix empty layer detection is scan devices. 2010-05-14 12:30:43 +00:00
Milan Broz
83b4f8366a Fix device_is_usable to properly detect only internal LV names. 2010-05-14 12:03:32 +00:00
Zdenek Kabelac
8e50c4e4bb Use /bin/bash for scripts with bashisms 2010-05-14 11:33:20 +00:00
Milan Broz
2b129732b0 Skip also special lvm devices in scan (if ignore suspended is used).
This should avoid various races between dmeventd on multiple nodes
in cluster where one node already repairing device and another
run full scan and locks the device.
2010-05-13 18:38:38 +00:00
Milan Broz
8cf86745c2 Do not print encryption key in message debug output. 2010-05-13 13:31:30 +00:00
Milan Broz
5ee39f1a1d Currently if clvmd is running and user issues vgscan,
the device cache file is dumped both in vgscan and clvmd process.

Unfortunately, clvmd calls lvmcache_label_scan,
it properly destroys persistent filter, but during
persistent_filter_dump it merges old cache content back!

This causes that change in filters is not properly propagated
into device cache after vgscan on cluster.
(Only new devices are added.)

https://bugzilla.redhat.com/show_bug.cgi?id=591861
2010-05-13 13:04:03 +00:00
Petr Rockai
8c998ebbed Chop up the big t-lvconvert-mirror-basic loop across 4 separate test scripts
(and use sourcing to avoid code duplication).
2010-05-12 13:15:38 +00:00
Petr Rockai
e2eb9b24b7 Run tests in alphabetical (and thus stable across machines) order. 2010-05-12 11:59:46 +00:00
Petr Rockai
374e3502fe Bump the debug.log level from 4 to 9 (the numbering is different from verbose). 2010-05-12 11:58:51 +00:00
Petr Rockai
1ad6e72ade Revert the "repeat failed tests with -vvvv" feature. Instead, dump debug logs
to a file using log/file, with log/overwrite set and dump this file in
STACKTRACE. The overall effect is that only the command that ran last before
the failure has been triggered will get its debug output logged. This is
similar to how we treat coredumps.
2010-05-12 11:23:16 +00:00
Petr Rockai
d7eaafe9c1 A fairly extensive refactor of the mirror testing code. The exhaustive
lvconvert testing is now in its own test, t-lvconvert-mirror-basic ... it
doesn't do anything fancy but it does run lvconvert through a lot of
combinations.

I have also merged the remaining t-mirror-lvconvert tests into
t-lvconvert-mirror and abolished the former. The latter will be split again
later into more thematic divisions. (The previous split was rather arbitrary,
may I even say random...)
2010-05-12 10:08:35 +00:00
Petr Rockai
2400150734 Revert the huge device creation in t-lvconvert-mirror and downgrade the
race-induced failure to a warning, until we have a better fix for this.
2010-05-12 06:09:22 +00:00
Petr Rockai
8ad2a270f4 Add a test for activation in presence of missing devices. This partially covers
the robustness requirements for system startup that we have.
2010-05-12 06:02:28 +00:00
Petr Rockai
73a006403f Rename t-partial-activate to t-activate-partial (more activation tests coming). 2010-05-12 05:59:24 +00:00
Petr Rockai
a3513577f0 The "should" testing utility should actually only give a warning when the
command fails.
2010-05-12 05:55:42 +00:00
Petr Rockai
29ad12df51 Improve the "check" testing utility: slightly refactor and provide
active/inactive checks.
2010-05-12 05:55:08 +00:00
Jonathan Earl Brassow
e0dd25f92b If we are checking if '--nosync' was called with the mirror argument,
then let's also check if '--mirrorlog' was called with the mirror
argument.
2010-05-11 21:40:11 +00:00
Zdenek Kabelac
81c155b465 Add pkgconfigdir for placement of .pc files
Use easily overideable make install pkgconfigdir variable.
2010-05-11 08:57:02 +00:00
Zdenek Kabelac
ae11cc6731 Switch to use Requires.private for devmapper.pc and lvm2app.pc
Use Requires.private: instead of Libs.private:
Use UDEV_PC and SELINUX_PC for Require.private:

It looks like usage of Requires.private is prefered from Libs.private.
However pkg-config documentation is really poor here. But here is
short outcome:

There is a difference in Libs.private: and Requires.private: where
we specify libselinux instead of  -lselinux -lsepol.

We leave resolving of query like 'pkg-config --libs --static devmapper'
on taking proper selinux and udev libs to their .pc files instead of
hardcoding them into our .pc file which is might give incorrect answer.
- i.e. dependency of libselinux package might change and we may return
wrong list of linked libraries.

http://bugs.freedesktop.org/show_bug.cgi?id=4738
http://err.no/personal/blog/tech/2008-03-25-18-07_pkg-config,_sonames_and_Requires.private
2010-05-11 08:54:11 +00:00
Zdenek Kabelac
b0b0c853c7 Add UDEV_PC and SELINUX_PC substituted variables 2010-05-11 08:48:43 +00:00
Zdenek Kabelac
8701c4f50c Use Require.private: field for devmapper-event.pc
Move devmapper to Require.private: field and remove unneeded libs
from Libs.private: as they are dependencies of devmapper library.
2010-05-11 08:47:02 +00:00
Zdenek Kabelac
627d5adc63 Skip unneeded 'cat' command execution. 2010-05-11 08:43:18 +00:00
Zdenek Kabelac
7a5a31888a Plugins do not use pthread or lvm2cmd directly.
Plugins are using pthread and lvm2cmd libraries indirectly
through devmapper-event-lvm2, so link only with libraries used by them.
2010-05-11 08:41:58 +00:00
Zdenek Kabelac
3d64743851 Link libdevmapper-event.so with libdevmapper.so.
For now using $(LIBS) for a list of linked libraries to $(LIB_SHARED) library.
2010-05-11 08:38:10 +00:00
Zdenek Kabelac
16d704877d Link liblvm2cmd.so with devmapper-event and devmapper libs.
and remove generic %.so: %.a target.
2010-05-11 08:34:38 +00:00
Zdenek Kabelac
3e320285a1 Headerfile <pthread.h> is no longer needed here 2010-05-11 08:32:22 +00:00
Alasdair Kergon
3215d89e97 Fix truncated total size displayed by pvscan. 2010-05-07 15:24:17 +00:00
Petr Rockai
b7983d4fe2 Add a basic test for dmeventd triggering lvconvert --repair. Needs improvement. 2010-05-06 19:01:26 +00:00
Petr Rockai
6120f4c507 Add some basic provisions for automated testing of dmeventd. 2010-05-06 18:54:51 +00:00
Peter Rajnoha
ac24748b47 Add new --sysinit option for vgchange and lvchange.
A shortcut for --ignorelockingfailure, --ignoremonitoring, --poll n options
and LVM_SUPPRESS_LOCKING_FAILURE_MESSAGES environment variable used all at
once in initialisation scripts (e.g. rc.sysinit or initrd).
2010-05-06 11:15:55 +00:00
Zdenek Kabelac
4c449886f6 Add dm_list_splice() to join two lists. 2010-05-06 10:10:15 +00:00
Zdenek Kabelac
cd3475a8cb Install plugins to subdirs
Target install_dm_plugin installs files to libdir/device-mapper.
Target install_lvm2_plugin installs files to libdir/lvm2.

Both targets creates relative links to libdir to keep the code
compatible with current dlopen handling.

Once we will be able to read plugins from subdir, links
could be removed.
2010-05-06 10:07:46 +00:00
Petr Rockai
03c5c5fbe7 What's new. 2010-05-05 22:38:31 +00:00
Petr Rockai
9d3faa4753 Suppress duplicate error messages about read failures and missing devices. 2010-05-05 22:37:52 +00:00
Peter Rajnoha
20399b50d6 Specify exactly which ioctl doesn't have a cookie set (for better debugging). 2010-05-03 22:08:38 +00:00
Peter Rajnoha
93c1312901 Synchronize "remove" dm task while reverting unsuccessful "create" dm task
(with table provided).

This remove ioctl generates udev events like any other hence it needs to be
synchronized properly as well. Also, add dm task type in debug log when
setting a cookie (for better debugging).
2010-05-03 21:06:53 +00:00
Alasdair Kergon
4bde7fc926 post-release 2010-04-30 15:48:38 +00:00
Alasdair Kergon
68086fdde4 typo 2010-04-30 14:51:58 +00:00
Alasdair Kergon
005ad96068 pre-release 2010-04-30 14:49:42 +00:00
Petr Rockai
6c1beb94dc Add a "should" alongside "not" to the test utilities. When a "should" command
fails, the test will carry on but will issue a warning. The harness detects
such warnings from tests and marks tests that passed with warnings with a
special status.
2010-04-30 14:33:39 +00:00
Alasdair Kergon
fa0ec772d5 change awk path 2010-04-30 13:58:08 +00:00
Peter Rajnoha
661e73d9a6 And be consistent with return code as well (previous commit). 2010-04-30 13:47:11 +00:00
Peter Rajnoha
db85b2ddc7 Don't run any complex initialisation for the "version" lvm2 command.
We can use it even in read-only environment where a try to initialise
file-based locking fails (not to mention other processing related with
lvm2 init). Simply, we want to output the version only, nothing else.
And this should always work.
2010-04-30 13:28:44 +00:00
Zdenek Kabelac
4f732b1989 Initialise _vginfos list staticaly so there is no problem with using uninitialised
variables in case, lvmcache_destory() is called without lvmcache_init().
2010-04-30 12:54:31 +00:00
Zdenek Kabelac
78b8276111 Release pools for regex if there is error during processing
(fixes error messages about unreleased pools).
2010-04-30 12:37:04 +00:00
Zdenek Kabelac
6ef6b6af40 Show string with invalid pattern
and start error message with capital letter.
2010-04-30 12:31:32 +00:00
Alasdair Kergon
f45bbeb497 . 2010-04-29 01:48:19 +00:00
Alasdair Kergon
4eb71369ed . 2010-04-29 01:45:30 +00:00
Alasdair Kergon
bc11c3a1d7 Remove no-longer-used arg_ptr_value.
Fix -M and --type to use strings not pointers that change on config refresh.
2010-04-29 01:38:12 +00:00
Jonathan Earl Brassow
dd8ac54678 Test all combinations of mirror conversion, both while the LV
is active and while it is in-active.

+for i in $(seq 0 4); do
+       for j in $(seq 0 4); do
+               for k in core disk mirrored; do
+                       for l in core disk mirrored; do

The testing code still needs some improvement.  I'd like to add
the ability to test specifying the PVs to be added/removed during
a convert.  It will also be important to test partial PV
specification during down converts (i.e. request to remove more
mirror images than we have provided PVs for).
2010-04-28 17:46:34 +00:00
Jonathan Earl Brassow
15d7886699 Don't attempt to convert the log type of an LV if the LV
is not a mirror.
2010-04-28 17:41:30 +00:00
Peter Rajnoha
68c7b86df1 Add support for new IMPORT{db} udev rule.
This rule appeared in udev v152 and it helps us to support spurious events
where we didn't have any flags set (events originated in udevadm trigger
or the watch rule). These flags are important to direct the rule application.
Now, with the help of this rule, we can regenerate old udev db content.
To implement this correctly, we need to flag all proper DM udev events with
DM_UDEV_PRIMARY_SOURCE_FLAG. That happens automatically for all ioctls
generating events originated in libdevmapper.
2010-04-28 13:37:36 +00:00
Zdenek Kabelac
6c8454e4e2 Small indent change 2010-04-28 12:23:11 +00:00
Jonathan Earl Brassow
a249779692 Fix comment from last commit. Additionally, there is no need
to put a comment into the WHATS_NEW file if it is a regression
that was created and fixed inside the same release window.
2010-04-27 15:26:58 +00:00
Jonathan Earl Brassow
876b6416ab Patch to fix bug 586021 and mantain historical behavior of
being able to remove more images from a mirror than the
number of PVs directly specified for removal.

The effort to fix bug 581611 corrected a bug that was unnoticed
at the time.  The loop in _remove_mirror_images that looks over
the specified PVs was allowing devices that were previously
counted and moved to the end of the list to be double-counted.
This resulted in the number of devices needed for removal always
being satisfied - even if the user did not specify enough PVs
for removal to satisfy the request.  When 581611 was fixed, this
double-counting no longer took place and the result was to remove
only the minimum of the number of PVs specified or the number
that was asked to be removed.

By simply always setting 'new_area_count' (as used to be done
only in the else statement), we return to the previous behavior.
Indeed, this is exactly what the double-counting was allowing
to happen before the fix of 581611.
2010-04-27 14:57:49 +00:00
Alasdair Kergon
1e5d79dce1 Mention how to get PV to LV mappings. 2010-04-27 13:34:56 +00:00
Alasdair Kergon
bd8eec0a1e Fix lvconvert error message when existing mirrored LV is not found. 2010-04-26 18:31:58 +00:00
Alasdair Kergon
e7075c4366 add comments 2010-04-26 18:12:40 +00:00
Peter Rajnoha
532834cbc2 Also include udev libs in libdevmapper.pc when udev_sync is enabled. 2010-04-26 09:05:50 +00:00
Mike Snitzer
d5857e6d48 Disallow the direct removal of a merging snapshot.
Allow lv_remove_with_dependencies() to know the top-level LV that was
requested to be removed (otherwise it recurses and we lose context).

A merging snapshot cannot be removed directly but the associated origin
can be.  Disallow removal of a merging snapshot unless the associated
origin is also being removed.
2010-04-23 19:27:10 +00:00
Mike Snitzer
b004ea2d7f Remove redundant check in _lvs_single now that the caller
(process_each_lv_in_vg) provides it.

Also, removing this check from _lvs_single now allows displaying hidden
LVs that are specifically named on the command line.
2010-04-23 19:10:20 +00:00
Peter Rajnoha
205ca4f8a7 Set appropriate udev flags for reserved LVs.
There's no need for foreign udev rules to touch LVM reserved devices
(snapshot, pvmove, _mlog, _mimage, _vorigin) even if they happen to
be visible. The same applies for /dev/disk content - no need to create
any content for these devices (and so no need to run any "blkid" etc.).
This also prevents setting any inotify "watch" from udev rules on such
devices that is a source of race conditions (the rules need to honor
DM_UDEV_DISABLE_OTHER_RULES_FLAG for this to work though).
2010-04-23 14:16:32 +00:00
Mike Snitzer
4a76f5c764 When removing a snapshot avoid preloading the origin if the
snapshot-merge target is not active.
2010-04-23 02:57:39 +00:00
Alasdair Kergon
a32e8441d0 don't optimise anything with TARGET_TRANS to avoid intefering with the matcher's counting 2010-04-22 23:09:18 +00:00
Alasdair Kergon
4d6089c042 Cache bitset locations to speed up _calc_states. (kabi) 2010-04-22 20:35:24 +00:00
Alasdair Kergon
7929929979 avoid ORs rightmost 2010-04-22 20:15:00 +00:00
Alasdair Kergon
9ba50046cf Move regex printing code from test to main tree (may use in debug messages).
Yet another optimiser fix attempt.
2010-04-22 17:42:38 +00:00
Jonathan Earl Brassow
aa3bdb1911 The following tests in the testsuite have race conditions:
1) Test that the primary mirror image cannot be removed while
   the mirror set is sync'ing.
2) Test that you cannot start a second mirror up-convert while
   one is already in progress.

The trouble is that if the sync/conversion finishes before the
tests occur, the tests will fail by why of success where there
should have been failure.  This means the sync/conversion must
happen very quickly, but this is possible because the test
mirrors we are creating are so small.

In order to decrease the likelyhood of these test failing (or
more correctly, failing to test the right thing), I've increase
the size of the mirrors.  It will still be remotely possible that
the tests will fail (by way of failing to test the right thing).
If this continues to happen, more involved mechanisms will need
to be put in place.  (Perhaps these will still be created, but
this change should be a remedy until that time.)
2010-04-22 15:39:40 +00:00
Alasdair Kergon
5ce8c9ae77 Don't walk rightmost through NULL pointers. 2010-04-22 14:33:14 +00:00
Alasdair Kergon
9d8d6b1d18 Fix rightmost rotation, and use LEFT and RIGHT to make symmetry more obvious. 2010-04-22 13:42:34 +00:00
Alasdair Kergon
52b8978a47 fix leftmost rotation 2010-04-22 13:18:27 +00:00
Alasdair Kergon
442fd05339 isprint 2010-04-22 03:42:00 +00:00
Alasdair Kergon
4c952f0af4 Still not satisfactory... 2010-04-22 03:24:24 +00:00
Alasdair Kergon
cf90b03ce4 add -r to print out closer to original regex format 2010-04-22 03:12:01 +00:00
Jonathan Earl Brassow
d4de2a7aa4 Disallow the addition of mirror images while a mirror up-convert
is already occurring.  The addition of new legs can be retried
once the current conversion is complete.
2010-04-21 14:04:24 +00:00
Jonathan Earl Brassow
e37b173f13 Disallow the primary mirror image from being removed when the
mirror is not in-sync.  This restriction is not extended to
repair operations (i.e. it will not limit what 'lvconvert --repair'
can do).
2010-04-21 13:55:08 +00:00
Zdenek Kabelac
b5d88e683f Make matcher_t and parse_t compilable
These two old-test/regex utils are usable for testing output of regex
processing at core level. For getting them usable configure need to create
Makefile. This is currently disable by default.
2010-04-21 08:01:51 +00:00
Alasdair Kergon
23dd4773d4 Add a regex optimisation pass for shared character prefixes. 2010-04-20 22:31:22 +00:00
Mike Snitzer
b7af7c9c43 Re-enable t-topology-support.sh
Reintroduce split teardown (teardown() calls teardown_devs()) because
t-topology-support.sh only needs the teardown_devs() subset of the full
teardown() between each iteration of the topology tests -- in particular
the $TESTDIR must not get removed between each topology test iteration.

prepare_loop() must return if prepare_scsi_debug_dev() already
established $LOOP.

Also fix (and simplify) the unsafe scsi-debug device discovery in
prepare_scsi_debug_dev().
2010-04-20 18:18:59 +00:00
Milan Broz
9d3955daf2 Remove -n argument from vgcfgrestore.
This is old lvm1 syntax, because arguments changed
from PVs to VGs compatibility is broken already.

name_ARG is not used in code.
2010-04-20 18:17:56 +00:00
Dave Wysochanski
063083a203 Add device creation to basic nightly test.
Ensure we can create devices for use in tests before running the real
tests.  This may in various cases, and may involve machine configuration
rather than a failure in some specific test.
For example, if a test is run with LVM_TEST_DIR=/tmp, selinux is enabled,
and the default security context is set to "<<none>>" for /tmp, all the
tests will fail, unable to create devices, since dmsetup will fail, a
result of machpathcon() returning an error code.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-04-20 15:19:36 +00:00
Christine Caulfield
46886164dd Add -S command to clvmd, so it can restart itself and still
preserve exlusive LV locks.
2010-04-20 14:07:37 +00:00
Alasdair Kergon
ea04c0775c Add dm_bitset_equal to libdevmapper. 2010-04-20 13:58:22 +00:00
Alasdair Kergon
d29aa4764e typo in comment 2010-04-20 12:18:31 +00:00
Alasdair Kergon
203d1d8371 Move function up file 2010-04-20 12:14:28 +00:00
Alasdair Kergon
2eb4099563 missed files from last commit 2010-04-20 10:58:18 +00:00
Mike Snitzer
7cd66377ef Add additional test to start the snapshot merge (which had just failed
because an FS was mounted -- origin was still open).
2010-04-19 22:44:42 +00:00
Alasdair Kergon
1f9d50fa3f Add dm_bit_and. (ejt) 2010-04-19 21:23:01 +00:00
Alasdair Kergon
be29e5ab62 fix last commit 2010-04-19 21:10:20 +00:00
Alasdair Kergon
24d8818933 Simplify dm_bitset_create. (ejt) 2010-04-19 21:08:32 +00:00
Alasdair Kergon
803380c203 Speed up dm_bit_get_next with ffs(). 2010-04-19 17:17:55 +00:00
Dave Wysochanski
1569059b2b Change lvm2app version number from 1 to 2.
This version number change reflects the memory handling change
for string-based pv/vg/lv string based attributes.
In addition, when adding support for tags, I forgot to increase
the version number.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-04-19 15:24:00 +00:00
Dave Wysochanski
8fb6bd930b Use vg->vgmem to allocate vg/lv/pv string properties instead of dm_malloc/fr
Everywhere else in the API the caller can rely on lvm2app taking care of
memory allocation and free, so make the 'name' and 'uuid' properties of a
vg/lv/pv use the vg handle to allocate memory.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-04-19 15:22:24 +00:00
Alasdair Kergon
c7cc4b7ac2 Change daemon lock filename from lvm2_monitor to lvm2-monitor for consistency. 2010-04-15 19:15:03 +00:00
Zdenek Kabelac
201d0e940b Install symbolic .so links with relative paths between usrlibdir and libdir. 2010-04-15 15:12:20 +00:00
Zdenek Kabelac
3fcd56034a Fix double DESTDIR usage for infodir and mandir. 2010-04-15 15:09:35 +00:00
Zdenek Kabelac
51d222469c Added awk script relpath.awk to calculate relative paths. 2010-04-15 15:06:26 +00:00
Alasdair Kergon
742d1e9424 post-release 2010-04-14 21:47:48 +00:00
Alasdair Kergon
a04f401227 touch file 2010-04-14 20:03:46 +00:00
Alasdair Kergon
62699dc3fd fix broken 'make install' for lvm_dump.sh 2010-04-14 20:03:15 +00:00
Alasdair Kergon
01645a7eae pre-release 2010-04-14 18:54:37 +00:00
Alasdair Kergon
b17939f74e pre-release 2010-04-14 18:53:04 +00:00
Alasdair Kergon
aa60387ecc . 2010-04-14 18:10:30 +00:00
Alasdair Kergon
4b801e21e3 pre-release 2010-04-14 17:50:49 +00:00
Dave Wysochanski
c198ca0285 Add missing readline linkage to lvm2app test. 2010-04-14 16:13:34 +00:00
Petr Rockai
a312fc8eb9 What's new. 2010-04-14 13:52:20 +00:00
Petr Rockai
10b62fb0e8 Allow incomplete mirror restore in lvconvert --repair upon insufficient space. 2010-04-14 13:51:58 +00:00
Peter Rajnoha
2c12325d63 Do not reset position in metadata ring buffer on vgrename and vgcfgrestore.
We should write metadata into next position in the ring buffer while calling
vgrename and vgcfgrestore. At this code level (_vg_write_raw), we were not able
to determine if this is a rename or not. If yes, then accompanying VG structure
passed here has a new name set, not the old one.

When looking for a location where to put metadata next, we were given a NULL
value because of failed VG name comparison (in _find_vg_rlocn) between the
name in existing metadata and metadata we're just about to write.

This resets the position in the ring buffer, overwriting any existing metadata
(and also incorrectly updates the cache to "orphan" afterwards).

This patch just adds old_name item in struct volume_group that we can check and use
if necessary and detect renames at lower layers as well.

The same applies for vgcfgrestore, but here we're using a special value of
old_name, an empty string, to disable the check with existing metadata totally.
2010-04-14 13:09:16 +00:00
Peter Rajnoha
2d8b9935a1 Allow VGs with active LVs to be renamed. 2010-04-14 13:03:06 +00:00
Peter Rajnoha
647d948562 Use UUIDs instead of names while processing event handlers.
Internally, we used DM names instead of UUIDs while processing event
handlers. This caused problems while trying to vgrename a VG with active LVs
where the names are being changed and so the devices were not found then.
The patch also contains a little bit of refactoring, moving "build_dlid" code
found in dev_manager.c to "build_dm_uuid", now in lvm-string.c (so we have
build_dm_uuid and build_dm_name at one place).
2010-04-14 13:01:38 +00:00
Petr Rockai
73d1626ddc SIGTERM testing clvmd before SIGKILL-ing it. 2010-04-14 12:04:23 +00:00
Alasdair Kergon
b7445913cc Only pass visible LVs to tools in cmdline VG name/tag expansions without -a 2010-04-14 02:19:49 +00:00
Alasdair Kergon
6f7ca25c9b Use typedefs for toollib process_each functions. 2010-04-13 23:57:41 +00:00
Dave Wysochanski
4487c42de2 Fix teardown in t-pvcreate-operation-md.sh nightly test. 2010-04-13 21:42:44 +00:00
Zdenek Kabelac
bfbad87685 Add error diagnostic for setenv failure. 2010-04-13 20:54:57 +00:00
Zdenek Kabelac
65f0ca65f1 Use C locales and use_mlockall for clvmd.
Use same steps for clvmd as for dmeventd - using C locales to avoid reading
large mmaps and use mlockall() for threaded version.
2010-04-13 19:54:16 +00:00
Dave Wysochanski
d0720d5638 Update WHATS_NEW 2010-04-13 18:18:54 +00:00
Dave Wysochanski
5d7fd71373 Add pv->vg to solidify link between a pv and a vg.
lvm2app needs a link back to the vg in order to use the vg handle for
memory allocations as well as other things.  This patch adds the field
to struct physical_volume, and sets pv->vg when reading a vg from disk or
extending a vg by using the helper function previously added,
add_pvl_to_vgs().  Moves and renames are handled with separate code
inside move_pv() and vgmerge().  Add pv->vg check to vg_validate().

A NULL value in pv->vg signifies membership in the orphan VG.
Note though in the case of pv_read() on a device with metadatacopies == 0,
more devices may need to be read for an authoritative answer.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-04-13 17:26:36 +00:00
Dave Wysochanski
efe3e72ed0 Use del_pvl_from_vgs() in vgreduce paths.
Somehow these got missed in earlier patches.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-04-13 17:26:20 +00:00
Dave Wysochanski
85f56aef97 Call add_pvl_to_vgs() and del_pvl_from_vgs() from more places.
Now that we have library functions to add/delete a pv from the vg->pvs
list, call them from everywhere.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-04-13 17:26:03 +00:00
Dave Wysochanski
5ac0fdd924 Add del_pvl_from_vgs() and move prototypes into metadata-exported.h
Add a delete function to manage the vg->pvs list.

NOTE: It may be possible to do further cleanup to these add/del functions
by passing a 'pv' as input instead of 'pv_list'.  The pv_list is used for
functions which do allocations (lvcreate) while other places in the code
just manage a list of 'pv' (e.g. import functions, vgextend, etc).

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-04-13 17:25:44 +00:00
Dave Wysochanski
b33c7a4597 Move increment of vg->pv_count from import_pool_vg() to import_pool_pvs().
Move the increment of vg->pv_count next to the place where we add to
vg->pvs.  It looks safe to do this since the only caller of import_pool_vg()
calls import_pool_pvs() immediately afterward, and there is no way
import_pool_vg() can fail (always returns 1).  However, if there's a
memory allocation failure inside import_pool_pvs(), we will end up with
a different count in vg->pv_count that with the original code.  In any
case, vg->pv_count should be as close to dm_list_size(&vg->pvs) as
possible, as is the case everywhere else in the code.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-04-13 17:25:26 +00:00
Dave Wysochanski
788b9bfdc7 Remove unnecessary parameter from import_pool_pvs().
The dm_list * parameter is unnecessary since we are passing in 'vg'
and the only caller of import_pool_pvs() passes '&vg->pvs' in the
dm_list * parameter.  Just use vg->pvs directly in the function.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-04-13 17:25:13 +00:00
Jonathan Earl Brassow
41cc3b216d Arguments to the --mirrorlog option are described in the synopsis as
{core|disk|mirrored}.  However, under the options section they are
described as {core|disk} - even though the 'mirrored' argument is
described.

s/'{core|disk}'/'{core|disk|mirrored}'/
2010-04-13 16:13:08 +00:00
Milan Broz
dcb7878842 Mask LCK_HOLD flag in cluster VG locks for compatibility reasons. 2010-04-13 14:36:24 +00:00
Petr Rockai
b5e83471bc Add check_cluster and check_local targets in addition to just "check". 2010-04-13 13:28:52 +00:00
Petr Rockai
bfdc05ec71 Process all core dumps that exist upon a test failure (this would hopefully
include eg. clvmd cores, apart from the usual lvm ones).
2010-04-13 08:01:53 +00:00
Petr Rockai
1d7ecbe9a0 Fix a reversed exit status from test harness. 2010-04-13 07:34:19 +00:00
Petr Rockai
9e30a829d5 Optionally disable the verbose repeat of a failed test (export
LVM_TEST_NOVERBOSE=1).
2010-04-13 07:33:34 +00:00
Petr Rockai
698dfbf953 Disable the rather-dangerous prepare_scsi_debug_dev in the testsuite. 2010-04-13 07:02:14 +00:00
Petr Rockai
83fbb1ec11 Make it easy to run just a subset of tests by saying make check T="regex". 2010-04-13 06:45:53 +00:00
Petr Rockai
19d0f2b57c Fix t-lvcreate-usage, as lvcreate ... -i1 no longer prints "Redundant stripes
argument: default is 1".
2010-04-13 06:25:08 +00:00
Petr Rockai
05d40b3142 For the testsuite, set a default polling interval to 0 in lvm.conf. Cuts down
testing time considerably.
2010-04-13 06:24:20 +00:00
Alasdair Kergon
d94fc9ce62 Add --stripes to lvconvert too. 2010-04-13 01:54:32 +00:00
Alasdair Kergon
ba9550f473 Add activation/polling_interval to lvm.conf as --interval default. 2010-04-13 01:43:56 +00:00
Petr Rockai
28e1e7fd07 More testsuite helpers for check.sh. 2010-04-12 19:33:58 +00:00
Petr Rockai
904e38837e Absorb t-mirror-lvconvert-usage into t-lvconvert-mirror. 2010-04-12 19:32:58 +00:00
Petr Rockai
697c5de267 Explode t-mirror-basic into a number of smaller tests. 2010-04-12 19:16:24 +00:00
Petr Rockai
bfa9c7bcfb Add a new helper script for the testsuite, that makes checking for various
(lvm) properties easier and produces nicer output.
2010-04-12 19:02:59 +00:00
Petr Rockai
2f81a05ce5 Do not pollute /tmp with testing byproducts. 2010-04-12 19:00:23 +00:00
Alasdair Kergon
7b994976e3 Don't ignore error if resuming any LV fails in resume_lvs.
Skip closing persistent filter cache file if open failed.
2010-04-12 11:52:53 +00:00
Zdenek Kabelac
662d1021e6 Update install rules for udev.
Fix unwanted modification of $(top_builddir)/make.tmpl.

Using dependency rules to install rules for udev.
There is minor problem, with concurent usage of builddir
and srcdir could lead to missuse of 10-dm.rules which
could be found in VPATH from different builddir.
However current solution uses intermediate target so
the generated 10-dm.rules exists only for short period of time
during make install execution.
2010-04-09 21:44:28 +00:00
Zdenek Kabelac
2db34bd266 INSTALL rules updates
Patch is inspired by Debian's extra patch.

- removes OWNER & GROUP make vars they are parts of INSTALL command.
- adds INSTALL_PROGRAM for executable, uses $(INSTALL)
- adds INSTALL_DATA for non-executable data, uses ($INSTALL)
- adds INSTALL_WDATA for writable non-executable data, uses ($INSTALL)
- adds configure option --enable-write_install - to support
  installatin of writable files used by distribution
- replaces usage of ifeq @LIB_SUFFIX@ with $(LIB_SUFFIX)
- installs .a files from static builds without executable flag
- installs .a files to $(usrlibdir) instead of $(libdir)
- installs all static binaries to $(staticdir)
- create .so links for devel package in $(usrlibdir) instead of
  $(libdir)
- makes .so and .so.LIB_VERSION files within builddir
- removes VERSIONED_SHLIB and created versioned LIB_SHARED automagicaly
- install LIB_SHARED via install_lib_shared target
- install plugins via install_lib_shared_plugin target
- prints whole 'install' command during installation instead of less
  informative "Installing  $(something) $(somewhere)"
- install multiple man pages with one INSTALL command
- use DISTCLEAN_TARGETS instead of creating multiple distclean targets
2010-04-09 21:42:48 +00:00
Zdenek Kabelac
f3491d93a0 Use vpath instead of VPATH.
Usage of VPATH makes troubles when used within $(builddir).
Not only source files are being found through VPATH,
but targets as well. (make --debug=v)

Thus if user builds the code in $(srcdir) and also in some $(builddir)
he gets mangled results as some generated files (i.e. .export.sym)
are 'reused' from $(srcdir) instead of $(builddir).

This patch switches to use vpath were we could explicitly name
suffixes that should be looked via vpath - we must take care,
we do not generate files with these suffixes:
.c, .in, .po, .exported_symbols
2010-04-09 21:34:25 +00:00
Alasdair Kergon
337abee8f8 Permit mimage LVs to be striped in lvcreate and lvresize. 2010-04-09 01:00:10 +00:00
Dave Wysochanski
34573cf6a5 Check for duplicate paths (pvids) on the commandline of vgcreate.
A user specifying duplicate paths on the cmdline of vgcreate will
get a message similar to the following:
vgcreate vgtest2 /dev/loop3 /dev/loop5
  Found duplicate PV jk1lXsKzwyOKlXq6bhaFFKMQQ06oPgu8: using /dev/loop5 not /dev/loop3
  Found duplicate PV jk1lXsKzwyOKlXq6bhaFFKMQQ06oPgu8: using /dev/loop3 not /dev/loop5
  Internal error: Duplicate PV id jk1lXs-Kzwy-OKlX-q6bh-aFFK-MQQ0-6oPgu8 detected for /dev/loop3 in vgtest2.

This is caught by vg_validate(), but it would be good to find
this condition earlier in the vgcreate code.  add_pv_to_vg()
currently checks by pvname, but does not look for duplcate pvids.
This patch adds the check for duplicate pvids and results in new
error output as follows:
vgcreate vgtest2 /dev/loop3 /dev/loop5
  Found duplicate PV jk1lXsKzwyOKlXq6bhaFFKMQQ06oPgu8: using /dev/loop5 not /dev/loop3
  Found duplicate PV jk1lXsKzwyOKlXq6bhaFFKMQQ06oPgu8: using /dev/loop3 not /dev/loop5
  Physical volume '/dev/loop5 (jk1lXs-Kzwy-OKlX-q6bh-aFFK-MQQ0-6oPgu8)' listed more than once.
  Unable to add physical volume '/dev/loop5' to volume group 'vgtest2'.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-04-08 15:18:35 +00:00
Zdenek Kabelac
491ef790c2 Add cleandir target.
Using non-recursive cleandir target for resursive distclean and clean.
Avoids duplicated clean invocation during distclean.
Indent $(RM) parameters.
2010-04-08 09:15:37 +00:00
Alasdair Kergon
2e9ae681c5 And another test that should have been failing - normal allocation policy
does not put stripes on the same disk as each other!
2010-04-08 01:58:06 +00:00
Alasdair Kergon
a02f7ab0cb another incorrect test that should have been failing before 2010-04-08 01:43:46 +00:00
Alasdair Kergon
e0b190c111 missing ?: 2010-04-08 00:56:26 +00:00
Alasdair Kergon
56fa3ac1b0 suppress bogus compiler warning 2010-04-08 00:52:41 +00:00
Alasdair Kergon
5bcbeca8e7 Fix pvmove allocation to take existing parallel stripes into account.
When moving parts of striped LVs, pvmove wouldn't care about leaving you with
two stripes on the same disk.  Now --alloc anywhere is needed for that.
(Tried and gave up on two alternative approaches before the one committed here.)
2010-04-08 00:28:57 +00:00
Alasdair Kergon
adc1729212 Only fail if the top-level LV fails to be deactivated - allow deactivation
of its dependencies to fail.
2010-04-07 23:51:34 +00:00
Petr Rockai
fd7ae0cdf4 Don't forget to cd into $TESTDIR in test-utils.sh / prepare_testdir. 2010-04-07 21:38:01 +00:00
Alasdair Kergon
fdef9679b6 Issue a message if the new type of deactivation failure happens.
If this can happen during 'normal' operations, I need to know.
2010-04-07 21:25:09 +00:00
Petr Rockai
dcecda51d8 Fix a mis-override of $PWD in test-utils.sh. 2010-04-07 21:19:20 +00:00
Alasdair Kergon
687603a144 Fix incorrect removal of symlinks after LV deactivation fails. 2010-04-07 20:04:41 +00:00
Petr Rockai
acb04c003e Set ulimit -c to unlimited to allow coredumps to be collected and analysed in
the testsuite.
2010-04-07 16:04:22 +00:00
Petr Rockai
86b10089aa Avoid spurious skips in the testsuite due to obsoleted
dmsetup_has_dm_devdir_support_.
2010-04-07 16:00:19 +00:00
Milan Broz
7b030379ec Wipe dm-ioctl parameters in memory after use. 2010-04-07 15:57:20 +00:00
Petr Rockai
5e8c230d1f Refactor the test utilities, dropping the legacy test-lib.sh and curtailing
lvm-utils.sh. Clears up lots of unused code, should have little observable
impact (it does change test directory layout slightly).
2010-04-07 14:46:26 +00:00
Petr Rockai
8c2890cf1d In test harness, use fwrite(3) in place of write(2) to avoid mixing fd-level
and FILE-level IO on stdout.
2010-04-07 09:48:11 +00:00
Petr Rockai
8e9da71c32 Keep the testsuite stats correct in spite of failed-test repetition. 2010-04-07 09:41:33 +00:00
Petr Rockai
13deb51d3e Move a fragile testcase toward the end of t-mirror-lvconvert.sh. 2010-04-06 23:04:45 +00:00
Petr Rockai
2c9ffffdca Put back the `lvconvert -m+1 --mirrorlog disk' test in t-lvconvert-mirror.sh. 2010-04-06 22:22:26 +00:00
Alasdair Kergon
13a9bce647 disable another broken check in a test 2010-04-06 18:13:43 +00:00
Alasdair Kergon
dbb3cfe05e Fix is_partitioned_dev not to attempt to reopen device. 2010-04-06 17:36:41 +00:00
Alasdair Kergon
674baa8143 Disable broken test. 2010-04-06 16:30:53 +00:00
Christine Caulfield
db482f3e1c Fix a thread race in clvmd that could cause lockups on very busy systems 2010-04-06 15:29:30 +00:00
Alasdair Kergon
6a5a0222d7 Display PVs created during tests 2010-04-06 14:25:07 +00:00
Zdenek Kabelac
4512267bf1 Using 'not' if the test 'should' fail. 2010-04-06 14:24:13 +00:00
Dave Wysochanski
54555a6fab Update WHATS_NEW 2010-04-06 14:07:11 +00:00
Dave Wysochanski
ae2353caf8 Add add_pvl_to_vgs() - helper function to add a pv to a vg list.
Small refactor of main places in the code where a pv is added to a
vg into a small function which adds the pv to the list and updates
the vg counts.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-04-06 14:04:54 +00:00
Dave Wysochanski
4eae19ed75 Refactor format1 vg->pvs list add and vg->pv_count.
Refactor adding to the vg->pvs list and incrementing the count, which
will allow further refactoring.  Should be no functional change.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-04-06 14:04:20 +00:00
Dave Wysochanski
e6ec837203 Refactor _read_pv() code that updates vg->extent_count and vg->free_count.
Simple refactor to mov code that updates the vg extent counts from a
single pv's counts close to the code that adds a pv to vg->pvs and
updates vg->pv_count.  No functional change.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-04-06 14:04:03 +00:00
Dave Wysochanski
b37f7c4b7b Add pv to vg->pvs after check for maximum value of vg->extent_count.
In add_pv_to_vg(), we should only add the pv to vg->pvs after all
internal checks have passed.  The check for vg->extent_count exeeding
maximum was after we added the pv to the list, so this function could
return a state of vg->pvs that did not reflect other parameters such
as vg->pv_count.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-04-06 14:03:43 +00:00
Zdenek Kabelac
4b8340327c As lcov module is not installed with GD.pm dependency we need
to check for presence of this module and avoid using --frames
option for genhtml in this case.

Fix arg list for AC_PATH_PROG for lcov and genhtml.
(detecting empty LCOV and GENHTML string in Makefiles).
2010-04-06 11:53:53 +00:00
Zdenek Kabelac
92e4442d4a Distcleanup config files only in toplevel directory.
Do not execute 'rm -r' with empty $(DISTCLEAN_DIRS).
lvm-version.h is already cleaned with subtarget distcleaning.
Always distcleanup lcov_reports*.
2010-04-06 09:54:11 +00:00
Zdenek Kabelac
2517f9adf2 Fix lcov target
Patch fixes generation of coverage files for dmeventd and adds support for clvmd.
Path names are stripped, so the the html looks better.
Frames 'previews' is enabled for generated pages.
Using top_srcdir was wrong here - though we still can't easily use builddir.
Requiers using shell variables before execution of binaries build outside
of srcdir.
2010-04-06 09:50:07 +00:00
Alasdair Kergon
9bad64ff72 remove compiler warning 2010-04-02 01:35:34 +00:00
Alasdair Kergon
d1b147e2bb A few more log_error to log_warn changes for mirrors. 2010-04-01 14:54:37 +00:00
Zdenek Kabelac
1b7730c76a Better debug message for Un/Locked memory size. 2010-04-01 14:53:47 +00:00
Alasdair Kergon
28801f7470 temporarily downgrade the 'open while suspended' error till we fix it properly 2010-04-01 14:30:51 +00:00
Alasdair Kergon
f4c43c11c9 Try to fix tracking of whether or not log extents need allocating. 2010-04-01 13:58:13 +00:00
Zdenek Kabelac
fde4a8e1b5 Set ret value to success initially. 2010-04-01 13:43:12 +00:00
Alasdair Kergon
abb193533c Avoid endless loop if lv->segments list is corrupted 2010-04-01 13:08:06 +00:00
Alasdair Kergon
775fac97d3 initialise log_allocated to 0 2010-04-01 12:29:07 +00:00
Alasdair Kergon
3963c01760 Limit number of error messages when checking LV segments. 2010-04-01 12:14:20 +00:00
Alasdair Kergon
1e01a63685 Improve vg_validate to detect some loops in lists. 2010-04-01 11:45:36 +00:00
Alasdair Kergon
235ca704b1 Improve vg_validate to detect some loops in lists. 2010-04-01 11:43:24 +00:00
Alasdair Kergon
5685ba7918 Change most remaining log_error WARNING messages to log_warn. 2010-04-01 10:34:09 +00:00
Petr Rockai
f0d1c085b9 Do not pass NULL to setenv in the test harness. 2010-03-31 23:11:12 +00:00
Zdenek Kabelac
45490081c7 Missed to convert T -> SCRIPTS 2010-03-31 23:05:20 +00:00
Petr Rockai
a3503d13e5 Re-run failing tests with log/verbose=4 (-vvvv) to help with debugging. 2010-03-31 22:18:17 +00:00
Alasdair Kergon
3ed4d07d3a remove unused var 2010-03-31 20:39:51 +00:00
Alasdair Kergon
06e0023c2c Attempt to fix non-ALLOC_ANYWHERE allocation code after recent changes broke
The preference given to the PVs with the largest free areas.
2010-03-31 20:26:04 +00:00
Milan Broz
b22e0a3ecb Always use blocking lock for VGs and orphan locks.
Because we have now strong rule for lock ordering:
 - VG locks must be taken in alphabetical order
 - ORPHAN locks must be the last
vgs_locked() is now not needed.

This fixes problem with orphan locking, e.g.
vgremove VG1    |    vgremove VG2
lock(VG1)       |    lock(VG2)
lock(ORPHAN)    |    lock(ORPHAN) -> fail, non-blocking

https://bugzilla.redhat.com/show_bug.cgi?id=578413

(More similar places in code.)
2010-03-31 17:23:56 +00:00
Milan Broz
0802006ea7 Fix all segments memory is allocated from vg private mempool.
Physical segments were still allocated from global
command context mempool.

This leads to very high memory usage when
activating large VG (vgchange).
(Memory usage was about 2G when >3000LVs).

Fix it by properly using vg->vgmem private pool,
so all the memory is released early.

New memory pool parameter is needed here for pv_split_segment
function.

Also fix the same problem in some minor allocations
(vg description, lv segment split).
2010-03-31 17:23:18 +00:00
Milan Broz
29a21d1627 Do not traverse PV segment list twice.
In addition to previous patch, we really do not need
to search for segment which was just allocated in
split request.

Make pv_split_segment function return newly allocated
(split) segment also.

(So after this patch, there is only one user
of slow find_peg_by_pe).
2010-03-31 17:22:26 +00:00
Milan Broz
a0074aa07e Optimise PV segments search.
The function find_peg_by_pe is incredibly inefficient
for Pvs with many segments.

In shiny future there should be binary (or interval) tree
instead of sorted linked list (volunteers?).

Anyway, for now, we can use dirty trick here to optimise this case:

 - Allocations are usually applied from the beginning
 of PV (we have no alloocation policy which allocates areas
 "backwards")

 - The only user of find_peg_by_pe is pv_split_segment()
 call. In *most* cases it need to split *last* PV segment.

So if we search sorted pv segment list backwards, we
hit the requested segment immediatelly.

This patch applies this tiny change.
(and saves >30% of processing time when >3000LVs segments are on one PV!)

To discourage using this inefficient function from other code,
it is moved to pv_manip.c and used static for now:-)
2010-03-31 17:21:40 +00:00
Milan Broz
4e8859d851 Remove vg_validate call when parsing cached metadata.
vg_validate call is an adept to optimisation, it is very
ineeficient and slow.

Anyway, we should call it only before writing data to disk.

The call in lvmcache was just temporary validation,
we realy do not need to revalidate cached metadata
every time.
(Actually, I added that there just to prove that cache works
properly and forgot to remove it.)

Patch removes it from lvmcache completely, this can hit only
internal bug in export function (and this bug must
be detected in any vg_write call anyway before).
2010-03-31 17:20:44 +00:00
Milan Broz
562ae607d2 Use hash table for quick lv reference when reading metadata.
The _read_vg uses already hash for PVs to optimise
reading of large VGs and avoiding repeated PV list traversing.

Use the same aproach to speed up parsing VG with many LVs.
2010-03-31 17:20:02 +00:00
Mikulas Patocka
2426656b07 A missing space in the error message.
Add missing parentheses to an error message

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
2010-03-31 12:06:30 +00:00
Mikulas Patocka
898d3c655d Don't kill the parent if debugging.
If dmeventd runs with -d flag, it doesn't fork into backgroud.
The command kill(getppid(), SIGTERM) attempts to kill the parent dmeventd
process, however, if there is no parent, it kills whatever process spawned
dmeventd. In case of debugging with gdb, the parent is gdb, thus
kill(getppid(), SIGTERM) kills the debugger.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
2010-03-31 12:01:49 +00:00
Zdenek Kabelac
855e554051 Update for make install. 2010-03-31 07:43:41 +00:00
Zdenek Kabelac
4aac2c543b Install generated 10-dm.rules from builddir.
Patch just check whether file is generated in builddir otherwise srcdir file
is used.
2010-03-31 07:40:20 +00:00
Zdenek Kabelac
78024e7be6 Use .commands created in builddir for symlink installation. 2010-03-31 07:37:16 +00:00
Jonathan Earl Brassow
18f0009a41 We only need one extent for the mirror log. So, when specifying
the devices on which to place the individual mirror parts, we can
specify the log devices as $dev:x instead of $dev:x-y.
2010-03-31 03:56:25 +00:00
Jonathan Earl Brassow
1cf64de2bf For the mirror repair tests, we should use --ignoremonitoring because
we are running the repair manually.  If we don't ignore, then dmeventd
and the manually run repair can collide.  (We should still get clean
results in such a case, but it makes it harder to validate the test
results.)
2010-03-31 02:36:03 +00:00
Zdenek Kabelac
b1d6be8ec6 Update for dmeventd changes. 2010-03-30 14:44:57 +00:00
Zdenek Kabelac
137a25906d Count only readable size for memlock stats.
As we mlock() only readable pages, makes statistics only
for readable bytes.
2010-03-30 14:41:58 +00:00
Zdenek Kabelac
2b298cbb32 Update memlock
Code moves initilization of stats values to _memlock_maps().
For dmeventd we need to use mlockall() - so avoid reading config value
and go with _use_mlockall code path.

Patch assumes dmeventd uses C locales!
Patch needs the call or memlock_inc_daemon() before memlock_inc()
(which is our common use case).

Some minor code cleanup patch for _un/_lock_mem_if_needed().
2010-03-30 14:41:23 +00:00
Zdenek Kabelac
5361b5de37 Force C locale
As we need to use mlockall() enforce "C" locales for dmeventd.
2010-03-30 14:40:30 +00:00
Zdenek Kabelac
f1fee292e4 Updated syslog messages
Use our common '.' end format for syslog messages.
2010-03-30 14:39:55 +00:00
Zdenek Kabelac
9c9b1f5bc8 Release pool in the same reversed order
and with lowered priority after _memlock_dec.
2010-03-30 14:38:56 +00:00
Zdenek Kabelac
7e64d04db1 Fix resouce leak in error path
If the error path of _register_for_event() calls _free_thread_status()
_lib_put() call is missing.
To make thing simpler move this _lib_put() into common error path code.
2010-03-30 14:37:28 +00:00
Zdenek Kabelac
2355f677fb Remove mlockall() form dmeventd
As the header file <sys/mman.h> was not included in dmeventd.c
thus missed definition of MCL_CURRENT so this patch only makes
it obvious we were not locking memory here.

This patch has no functional change.
Later part of this patch set handles mlockall() via memlock_inc_daemon().
2010-03-30 14:35:40 +00:00
Alasdair Kergon
e42bb91382 Fix --alloc contiguous policy only to allocate one set of parallel areas. 2010-03-29 17:59:46 +00:00
Petr Rockai
28aa06675f Work around a problem in t-mirror-lvconvert: different PV order on the
commandline of lvconvert can lead to allocation failures even if enough space
is available. A separate testcase demonstrating the problem will follow.
2010-03-29 16:50:27 +00:00
Petr Rockai
6e86d0bb03 Enforce distinct-PV allocation of snapshot/origin pairs in vgsplit test. 2010-03-29 16:40:51 +00:00
Mike Snitzer
4342431e39 Do not allow {vg|lv}change --ignoremonitoring if on clustered VG.
clvmd does not propagate DMEVENTD_MONITOR_IGNORE.

Update get_activation_monitoring_mode() to check if the VG that the
LV is being activated in is clustered.  If so, skip it.

Any get_activation_monitoring_mode() error will cause the associated LV
(or VG) to be skipped during activation.  Both vgchange_single() and
lvchange_single(), which call get_activation_monitoring_mode(), are
called by their respective process_each_..() method.
2010-03-29 16:09:40 +00:00
Zdenek Kabelac
7452298131 Fix also error code from clean:
And fix previous commit which missed test.
2010-03-29 15:53:11 +00:00
Zdenek Kabelac
e4be66b1ac Oops, avoid returning errors from shell to makefile for builddir == srcdir 2010-03-29 15:39:25 +00:00
Zdenek Kabelac
f829547a13 Avoid modification of .in files outside man directory.
(i.e. this rule actually tried to change ../make.tmpl in some cases and
left this file completely broken)
2010-03-29 14:22:00 +00:00
Zdenek Kabelac
ea64fe3b51 Split long line in Makefile and keep $abs_top_buildir as shell variable
within init.sh.
2010-03-29 14:19:42 +00:00
Zdenek Kabelac
f293d0b951 Fixing another set of distclean problems where we left some generated files
in clvmd, dmevend, man, tests.

Don't include dependency files for clow and cscope.out targets

Improve dependency tracking for dmeventd and liblvm2cmd sources.
2010-03-29 14:17:59 +00:00
Zdenek Kabelac
1967fd2429 Update cflow file generation - support build dir and use $(top_srcdir)
to obtain sources. Create make.tmpl target for
simplier generation of cflow files with the help of
CFLOW_LIST, CFLOW_LIST_TARGET, CFLOW_TARGET.
Still cflow usage is not perfect.
2010-03-29 14:11:17 +00:00
Zdenek Kabelac
0fec0340c2 distclean fixes
Move daemons/ and lib/ subtargets to their Makefiles so we don't get
double cleanup error during execution of distclean target.
Instead of duplicating clean target inside distclean target,
just use it as a subtarget and avoid add duplicating code.
2010-03-29 14:09:25 +00:00
Zdenek Kabelac
bed67320b1 Use $(top_srcdir) for sources and add cscope.out to distclean targets. 2010-03-29 14:07:56 +00:00
Zdenek Kabelac
8544e24770 Add $(LIB_STATIC) to TARGETS so it's cleaned in the same way
as other libraries in project.
Add dmeventd.gcda dmeventd.gcno to CLEAN_TARGETS.
2010-03-29 14:07:01 +00:00
Zdenek Kabelac
727b7b7e8c Avoid hard sed replacement - i.e. quick test change in make.tmpl
could avoid recofiguration steps in same debug cases.
2010-03-29 14:06:06 +00:00
Zdenek Kabelac
bd39789144 Fixing compilation warning: implicit declaration of function ‘umask’ 2010-03-29 14:05:17 +00:00
Petr Rockai
eb10fc962b When a scsi_debug modprobe fails, skip the test instead of failing it. 2010-03-28 15:52:04 +00:00
Jonathan Earl Brassow
3318c41356 Add ability to create mirrored logs for mirror LVs.
This check-in enables the 'mirrored' log type.  It can be specified
by using the '--mirrorlog' option as follows:
#> lvcreate -m1 --mirrorlog mirrored -L 5G -n lv vg

I've also included a couple updates to the testsuite.  These updates
include tests for the new log type, and some fixes to some of the
*lvconvert* tests.
2010-03-26 22:15:43 +00:00
Mike Snitzer
dc2c0b1d51 Use a real socket for singlenode clvmd to fix clvmd's high cpu load. 2010-03-26 15:45:36 +00:00
Mike Snitzer
1de8da23f5 Fix clvmd cluster propagation of dmeventd monitoring mode.
clvmd's do_lock_lv() already properly controls dmeventd monitoring based
on LCK_DMEVENTD_MONITOR_MODE in lock_flags -- though one small fix was
needed for this to work: _lock_for_cluster() must treat
dmeventd_monitor_mode()'s return as a tri-state value.

Also cleanup do_lock_lv() to:
- explicitly init_dmeventd_monitor() based on LCK_DMEVENTD_MONITOR_MODE
- no longer reset init_dmeventd_monitor() to default at the end of
  do_lock_lv() -- it is unnecessary
2010-03-26 15:40:13 +00:00
Zdenek Kabelac
340fa684af Updates .so links for plugins 2010-03-26 13:21:28 +00:00
Alasdair Kergon
34f06fa400 Allow ALLOC_ANYWHERE to split contiguous areas. 2010-03-25 21:19:26 +00:00
Alasdair Kergon
5b5337e4af . 2010-03-25 18:22:39 +00:00
Alasdair Kergon
d01de820d7 Use INTERNAL_ERROR definition consistently in internal error messages. 2010-03-25 18:22:04 +00:00
Alasdair Kergon
5aeea69c01 Add some assertions to allocation code. 2010-03-25 18:16:54 +00:00
Alasdair Kergon
8f6c0b24d8 more diagnostics 2010-03-25 12:16:17 +00:00
Alasdair Kergon
b8eddf1bdc more diagnostics 2010-03-25 12:14:14 +00:00
Alasdair Kergon
1469dc216a add debug mesg 2010-03-25 11:57:16 +00:00
Alasdair Kergon
3306ae2f42 . 2010-03-25 11:48:54 +00:00
Alasdair Kergon
a89db8e69c add debug mesgs and attempt to control which device is used for log as perhaps intended 2010-03-25 11:47:00 +00:00
Alasdair Kergon
8c6f06eb34 add debug output and attempt to control which device gets log as intended perhaps 2010-03-25 11:42:17 +00:00
Alasdair Kergon
fe3ed2b871 improve a few comments in last check-in 2010-03-25 02:40:09 +00:00
Alasdair Kergon
71cb3fc201 Introduce pv_area_used into allocation algorithm and add debug messages.
This is the next preparatory step towards better --alloc anywhere
support and is not intended to break anything that currently works so
please report any problems - segfaults, bogus data in the new debug
messages, or if the code now chooses bizarre allocation layouts.
2010-03-25 02:31:48 +00:00
Mike Snitzer
f9554c7d27 Revert having clvmd consult the lvm.conf "activation/monitoring".
Correctly implementing the intent of this change requires more
analysis.
2010-03-24 22:25:11 +00:00
Zdenek Kabelac
384f2fc38b Move declaration of struct dm_info info to declaration block. 2010-03-24 11:36:48 +00:00
Mike Snitzer
cd50107ae1 Improve activation monitoring option processing
. Add "monitoring" option to "activation" section of lvm.conf
. Have clvmd consult the lvm.conf "activation/monitoring" too.
. Introduce toollib.c:get_activation_monitoring_mode().
. Error out when both --monitor and --ignoremonitoring are provided.
. Add --monitor and --ignoremonitoring support to lvcreate.  Update
  lvcreate man page accordingly.
. Clarify that '--monitor' controls the start and stop of monitoring in
  the {vg,lv}change man pages.

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2010-03-23 22:30:18 +00:00
Petr Rockai
94466645ee Also honour abort_on_internal_errors when log_fn is set. 2010-03-23 18:18:49 +00:00
Peter Rajnoha
1acb442f60 UDEV_SYNC_SUPPORT, not UDEV_SYNC! 2010-03-23 15:13:03 +00:00
Alasdair Kergon
cff0a562fd Allow dynamic extension of array of areas selected as allocation candidates. 2010-03-23 15:07:55 +00:00
Peter Rajnoha
299db29482 Export and use only valid cookie value in test suite. 2010-03-23 14:47:35 +00:00
Peter Rajnoha
cc5045d8ca Autoreconf.
(Strictly require libudev if udev_sync is used)
2010-03-23 14:44:42 +00:00
Peter Rajnoha
940c32c5dd Strictly require libudev if udev_sync is used.
This prevents some confusion when libudev was not found so udev_sync was disabled
automatically. Configure was successful though giving only a tiny warning.

Also, if "dmsetup udevcreatecookie" is used, never return 0x000000 as a result if
udev is not running and keep the output blank.
2010-03-23 14:43:18 +00:00
Peter Rajnoha
14ad41a065 Add support for ioctl's DM_UEVENT_GENERATED_FLAG.
We need to know whether we should wait for any uevent or not when
using udev_sync. A kernel patch was posted recently that changed the
way uevents are sent on dm device resume - it is sent only if the
device has been suspended before. There's also a new DM_UEVENT_GENERATED_FLAG
in the ioctl to notify userspace whether the event was generated.

If the uevent was not generated (e.g. the situation where the device is
*not* suspended and we call a resume), we just call dm_udev_complete
explicitly from within libdevmapper itself to prevent infinite waiting
while trying to synchronise with udev processing.
2010-03-23 14:38:37 +00:00
Alasdair Kergon
7eaf1f294d Avoid duplicate definitions. 2010-03-23 14:35:08 +00:00
Zdenek Kabelac
eb7692743f Remove const modifier for struct volume_group* from process_each_lv_in_vg().
Content of this pointer is not const during this function.
2010-03-23 14:24:04 +00:00
Mike Snitzer
7aa470c8d0 Don't allow resizing of internal logical volumes.
Prevent lvresize from being able to resize internal LVs: mirror legs
(*_mimage_*), mirror log (*_mlog), snapshot placeholder LVs (snapshot*)
and others.  Resizing these would leads to unexpected metadata and
sometimes crashes (in case of growing snapshot*).
2010-03-20 03:44:04 +00:00
Alasdair Kergon
4237ca85f5 Fix libdevmapper-event pkgconfig version string to match libdevmapper. 2010-03-19 18:33:55 +00:00
Dave Wysochanski
99cdfa1e71 Update WHATS_NEW for last checkin. 2010-03-18 17:32:25 +00:00
Dave Wysochanski
39f92f3cfd Avoid scanning all pvs in the system if operating on a device with mdas.
When we pv_read() a device that has an orphan vgname, we might need to scan
the system to be sure this is true.  However, if the PV has mdas, there's
no way possible for it to have an orphan vgname unless it is a true orphan.
Some areas of the code were optimized to take advantage of this fact, while
others were not (we would still do the expensive scan if a device had mdas
but had an orphan VG).

This patch unifies the code so that every place we are operating on such
a PV, we skip the expensive scan if there are mdas.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Acked-by: Petr Rockai <prockai@redhat.com>
Acked-by: Alasdair G Kergon <agk@redhat.com>
2010-03-18 17:29:12 +00:00
Alasdair Kergon
9cc29191d4 autoreconf & add missing WHATS_NEW entry 2010-03-18 13:24:35 +00:00
Petr Rockai
de33332491 Run both locking_type 1 and 3 tests (forgot to uncomment locking_type 1 before
last checkin).
2010-03-18 09:28:42 +00:00
Petr Rockai
f9ddafdc21 Skip locking_type 3 tests instead of failing when system-wide clvmd is running. 2010-03-18 09:27:39 +00:00
Petr Rockai
fdefd5eff9 Add infrastructure for running the functional testsuite with locking_type set
to 3, using a local (singlenode) clvmd.
2010-03-18 09:19:30 +00:00
Dave Wysochanski
e9e5dbb628 Add pvchange -u --all to testsuite.
This can be an interesting test case when using PVs with --metadatacopies 0.
2010-03-17 17:02:01 +00:00
Mike Snitzer
0e57141bb5 testsuite: get stacktrace if test drops core
Requires lvm be built with debugging (-g).
Also requires 'ulimit -c' be non-zero (to drop core file).
2010-03-17 14:55:28 +00:00
Milan Broz
842a3664f0 Disable long living process flag in lvm2app.
This option should be configurable, but for now
do not set it at all.

(lvm2app is used in udisks probers and there
cac cause several nasty races when trying to update
lvmcache during rescan.)
2010-03-17 14:45:28 +00:00
Milan Broz
6cf89391b6 Fix pvcreate device check.
If user try to vgcreate or vgextend non-existent VG,
these messages appears:

# vgcreate xxx /dev/xxx
  Internal error: Volume Group xxx was not unlocked
  Device /dev/xxx not found (or ignored by filtering).
  Unable to add physical volume '/dev/xxx' to volume group 'xxx'.
  Internal error: Attempt to unlock unlocked VG xxx.

(the same with existing VG and non-existing PV & vgextend)
# vgextend vg_test /dev/xxx
...

It is caused because code tries to "refresh" cache if
md filter is switched on using cache destroy.

But we can change filters and rescan even without this
machinery now, just use refresh_filters
(and reset md filter afterwards).

(Patch also  discovers cache alias bug in vgsplit test,
fix it by using better filter line.)
2010-03-17 14:44:18 +00:00
Alasdair Kergon
ca5fd21509 Suppress repeated errors about the same missing PV uuids.
Bypass full device scans when using internally-cached VG metadata.
2010-03-17 02:11:18 +00:00
Alasdair Kergon
d14471e44d fix last checkin 2010-03-16 19:06:57 +00:00
Alasdair Kergon
5197fd72c4 Only do one full device scan during each read of text format metadata. 2010-03-16 17:30:00 +00:00
Alasdair Kergon
c17ac96509 Remove unnecessary full_scan parameter from get_vgids and get_vgnames calls. 2010-03-16 16:57:03 +00:00
Alasdair Kergon
4acb30c464 replace existing_pv with existing_pvl 2010-03-16 15:48:27 +00:00
Alasdair Kergon
d61f611adc Look up missing PVs by uuid not dev_name in _pvs_single to avoid invalid stat.
Make find_pv_in_vg_by_uuid() return same type as related functions.
2010-03-16 15:30:48 +00:00
Alasdair Kergon
b19719801b Introduce is_missing_pv(). 2010-03-16 14:37:38 +00:00
Milan Broz
83a2bc8ec4 Fix clvmd Makefile to not overwrite LIBS from template definition 2010-03-16 08:47:46 +00:00
Alasdair Kergon
aab6f07d14 post-release 2010-03-09 14:01:47 +00:00
Alasdair Kergon
db8748cefd pre-release cleanups 2010-03-09 13:42:28 +00:00
Alasdair Kergon
23b3f55bfb pre-release 2010-03-09 13:13:07 +00:00
Alasdair Kergon
e6573a9bed some missing debug messages 2010-03-09 12:31:51 +00:00
Zdenek Kabelac
d6a19426c7 Update comments for selecting maps
Use dm_snprintf and check result whether we create correct /proc path name
2010-03-09 10:25:50 +00:00
Alasdair Kergon
9426d45cde . 2010-03-09 03:20:12 +00:00
Alasdair Kergon
48d0cd3564 Misc cleanups in the new mlock code, incl. improving some variable names
& messages; using more statics (for now) to avoid redundant
recalculation; validating config file just once on loading; keeping maps
file open.
2010-03-09 03:16:11 +00:00
Zdenek Kabelac
89f61acf2c Use mlock() only on 'r' memory maps 2010-03-08 17:14:21 +00:00
Milan Broz
985d87b5eb Add --help dmsetup option as the synonym for help command. 2010-03-08 16:05:07 +00:00
Milan Broz
0be2dfefdb Add --showkeys parameter description into dmsetup man page.
Also fix minor warning (-c is parameter) in man page formatting.
2010-03-08 16:04:32 +00:00
Zdenek Kabelac
89f30d2df7 Unconditionaly ignore also Virtual Dynamically-linked Shared Object
(VDSO on 32bit is VSyscall on 64bit)
It seems it could be locked on 64bit kernels running 32bit binaries,
but it makes troubles on real 32bit machines where mlock() returns
error when trying to lock such map area. (0xffffe000)
Behavior of mlockall() seems to be similar.
2010-03-08 15:55:52 +00:00
Zdenek Kabelac
0b648ce87b Use '_' prefix for local static variable. 2010-03-05 15:14:03 +00:00
Zdenek Kabelac
0c897ecefd mlockall() -> mlock()
This patch adds a new implementation of locking function instead
of mlockall() that may lock way too much memory (>100MB).
New function instead uses mlock() system call and selectively locks
memory areas from /proc/self/maps trying to avoid locking areas
unused during lock-ed state.

Patch also adds struct cmd_context to all memlock() calls to have
access to configuration.

For backward compatibility functionality of mlockall()
is preserved with "activation/use_mlockall" flag.

As a simple check, locking and unlocking counts the amount of memory
and compares whether values are matching.
2010-03-05 14:48:33 +00:00
zkabelac
f2a6d937a6 Use UDEV_LIBS, and link -ludev only when needed. 2010-03-04 12:12:34 +00:00
zkabelac
76f4498303 Use DL_LIBS, remove -ldl from global LIBS and link -ldl only when needed. 2010-03-04 12:10:40 +00:00
zkabelac
5451f79f55 This patch add SELINUX_LIBS and STATIC_LIBS variables.
For static builds dependency for SELinux libs is not handled by 'ar'.
Till better solution is found, for static builds STATIC_LIBS is used.

Patch updates SELinux detection to use 3rd & 4th parameter for Success/Fail.
Also removes detection of pthread from this check as we know which
version of libdevmapper we are going to link with lvm after merge.

SELinux header check moved to the SELinux test code.
2010-03-04 12:08:26 +00:00
zkabelac
4e69ed9c98 Removes -rdynamic from linking of lvm.static and dmeventd.static. 2010-03-04 12:03:54 +00:00
zkabelac
75f55c758c Pthread linking change
Create new substituted variable PTHREAD_LIBS and link this library
only with tools/libs which really needs it - i.e. dmeventd.

Check for libpthread only for builds with clvmd or dmeventd.

Remove variable LIB_PTHREAD
2010-03-04 11:21:05 +00:00
zkabelac
f9d1b67e86 Readline linking update
Modify linking of readline library. Create new  substituted varible
READLINE_LIBS - readline library is linked ONLY with tools that really use
it - i.e. lvm. (Static lvm does not use readlin).
Previous behaviour put this library into the variable LIBS and thus
linked it with all created object files of lvm project (i.e. plugins...).

READLINE detection is simplified.

Termcap library is linked in only if readline library doesn't have its own
dependency (i.e. old distributions).
2010-03-04 11:19:15 +00:00
zkabelac
04ecf25522 Introduce LVMINTERNAL_LIBS
Keep dependency libraries for liblvm-internal in one place.
2010-03-04 11:12:39 +00:00
zkabelac
52b51b70eb As fsadm is installed by default - it's a common practice to rather
print help text in '--disable' form for such case.
2010-03-04 11:09:08 +00:00
zkabelac
3fdc1390fe This patch moves inclusion of the make.tmpl before DEFS modification,
so it goes in the same order on the compilation line.
(i.e. HAVE_CONFIG_H goes first)
2010-03-04 09:56:56 +00:00
zkabelac
f309bd12c7 Use consistently $() instead of ${} for all Makefile variables,
thought both usage forms are correct.
2010-03-04 09:56:01 +00:00
zkabelac
d388f94c7f Replace CFLOW_CMD only in make.tmpl and use it as variable elsewhere. 2010-03-04 09:53:08 +00:00
zkabelac
0f878a226d Use $(top_builddir) for inclusion of make.tmpl in Makefiles. 2010-03-04 09:51:37 +00:00
zkabelac
a38f899d7e Use datarootdir and fix warning during configure process:
config.status: WARNING:  'make.tmpl.in' seems to ignore the --datarootdir setting.
2010-03-04 09:48:19 +00:00
zkabelac
6c09d7b60c Usage of AC_PROG_SED and AC_PROG_MKDIR_P requires autoconf version 2.61. 2010-03-04 09:46:38 +00:00
Mike Snitzer
8cb8f65010 Handle a misaligned device that reports a -1 alignment_offset.
The kernel's blk_stack_limits() function may flag a device as
'misaligned'.  If it does the alignment_offset will be -1.

Update set_pe_align_offset() to accommodate this corner case.
2010-03-02 21:56:14 +00:00
Alasdair Kergon
49437d9a07 Extend core allocation code in preparation for mirrored log areas. 2010-03-01 20:00:20 +00:00
fabbione
69962eae7c - fix whitespaces all over (tabs/spaces)
- increase timeout to 30 secs (on Chrissie request)
- source both cluster and clvmd for options (like all the other cluster
  init scripts)
- add clustered_vgs and _lvs commodity fns
- move rh_status* fns at the top, so they can be reused
- heavily cleanup start and stop fns from redundant code and unnecessary
  loops
- improve output from different operations
- make the init script lsb compliant
- don´t force kill of the daemon, send only a TERM signal and then wait
for it to exit
- Resolves rhbz#533247
2010-02-26 13:07:43 +00:00
Milan Broz
c440f39874 Remove lvs_in_vg_activated_by_uuid_only call.
There is no difference from lvs_in_vg_activated now,
convert all users to this call.
2010-02-24 20:01:40 +00:00
Milan Broz
40090be220 Always query device by uuid only.
lvm2 devices have always UUID set even if imported from lvm1 metadata.

Patch removes name argument from dev_manager_info call and converts
all activation related calls to use query by UUID.

Also it simplifies mknode call (which is the only user on mknodes parameter).
2010-02-24 20:00:56 +00:00
Dave Wysochanski
281a92bf74 Update WHATS_NEW. 2010-02-24 18:21:15 +00:00
Dave Wysochanski
bbacb7fff0 Add Doxygen file for lvm2app to generate documentation from lvm2app.h.
A simple Doxygen file for lvm2app documentation.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-02-24 18:16:54 +00:00
Dave Wysochanski
cccdc3eea0 Update doxygen comments for lvm2app.h.
Fix add/remove tag function headers.
Fix a lot of little problems with doxygen comments.
Clarify the basic objects and their handles, and place functions with their
appropriate handles/objects.
All this cleanup moves automatic documentation of lvm2app much closer to being
useful as official documentation.  In the future I will add some examples
and plan to build the examples as part of the unit tests.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-02-24 18:16:44 +00:00
Dave Wysochanski
aa9c970f97 Update lvm2app interactive unit test for vg/lv tags.
Simple test of vg/lv tag addition/deletion.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-02-24 18:16:35 +00:00
Dave Wysochanski
4f81adb3c9 Add lvm_lv_get_tags(), lvm_lv_add_tag(), and lvm_lv_remove_tag().
Add lvm2app functions to manage LV tags.
For lvm_lv_get_tags(), we return a list of tags, similar to other
functions that return lists.  An empty list is returned if there
are no tags.  NULL is returned if there is a problem obtaining
the list of tags.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-02-24 18:16:26 +00:00
Dave Wysochanski
b8f75d74ae Add lvm_vg_get_tags(), lvm_vg_add_tag(), and lvm_vg_remove_tag().
Add lvm2app functions to manage VG tags.
For lvm_vg_get_tags(), we return a list of tags, similar to other
functions that return lists.  An empty list is returned if there
are no VG tags.  NULL is returned if there is a problem obtaining
the list of tags.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-02-24 18:16:18 +00:00
Dave Wysochanski
befffd65bf Add tag_list_copy() supporting function inside lvm2app.
Add a supporting function to copy a list of internal tags to lvm2app list.
We need to put this here because of the lvm_str_list_t type which we export
in lvm2app.h.  If we didn't export this type, we could put this in the
internal library and use struct str_list.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-02-24 18:16:10 +00:00
Dave Wysochanski
610cd1a531 Add dm_pool_strdup to allocate memory and copy a tag in {lv|vg}_change_tag()
We need to allocate memory for the tag and copy the tag value before we
add it to the list of tags.  We could put this inside lvm2app since the
tools keep their memory around until vg_write/vg_commit is called, but
we put it inside the internal library to minimize code in lvm2app.
We need to copy the tag passed in by the caller to ensure the lifetime of
the memory until the {vg|lv} handle is released.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-02-24 18:15:57 +00:00
Dave Wysochanski
08d06030dc Refactor lvchange_tag() to call lv_change_tag() library function.
Similar refactoring to vgchange - pull out common parts and put into
library function for reuse.  Should be no functional change.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-02-24 18:15:49 +00:00
Dave Wysochanski
083687d0fd Refactor vgcreate to call new vg_change_tag() function.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-02-24 18:15:40 +00:00
Dave Wysochanski
f874581701 Refactor _vgchange_tag() to vg_change_tag() library function.
Pull out common code to be called from tools as well as lvm2app.
Leave archive() at tool level so we can use from vgcreate
as well as vgchange.  Should be no functional change.
- add stack macro in vgchange

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-02-24 18:15:05 +00:00
Petr Rockai
e66d76ac5a Add _mlog devices to dependency trees using UUID, not name, in activation. 2010-02-23 15:49:52 +00:00
Petr Rockai
5d7ad8ae75 Relax a check on blkid exit value, which seems to be different in different
versions. Fixes a spurious test failure introduced with -o pipefail.
2010-02-22 14:47:55 +00:00
Mike Snitzer
99ab428344 Do not reload origin again in lv_remove_single() if it had a merging
snapshot.  vg_remove_snapshot() will have already performed the required
reload.
2010-02-17 23:36:45 +00:00
Mike Snitzer
eaef92b02f Refactor snapshot-merge deptree and device removal to support info-by-uuid
Add a merging snapshot to the deptree, using the "error" target, rather
than avoid adding it entirely.  This allows proper cleanup of the -cow
device without having to rename the -cow to use the origin's name as a
prefix.

Move the preloading of the origin LV, after a merge, from
lv_remove_single() to vg_remove_snapshot().  Having vg_remove_snapshot()
preload the origin allows the -cow device to be released so that it can
be removed via deactivate_lv().  lv_remove_single()'s deactivate_lv()
reliably removes the -cow device because the associated snapshot LV,
that is to be removed when a snapshot-merge completes, is always added
to the deptree (and kernel -- via "error" target).

Now when the snapshot LV is removed both the -cow and -real devices
get removed using uuid rather than device name.  This paves the way
for us to switch over to info-by-uuid queries.

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2010-02-17 22:59:46 +00:00
Petr Rockai
4982eabe07 In testsuite, catch also failures that happen in the middle of a pipeline. 2010-02-17 15:41:28 +00:00
Dave Wysochanski
c66ce519f4 Add nightly test to cover vg/lv tags add/delete.
Simple nightly test coverage for adding / deleting lv/vg tags via
create and change functions.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-02-16 17:49:18 +00:00
Dave Wysochanski
e74208778d Add get_{pv|vg|lv}_field() nightly test helper functions.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-02-16 17:48:46 +00:00
Alasdair Kergon
67a0635e75 use lvm2app to refer to library now 2010-02-16 01:14:34 +00:00
Alasdair Kergon
def0511361 post-release 2010-02-16 00:27:01 +00:00
Alasdair Kergon
29b8138482 pre-release 2010-02-15 23:53:15 +00:00
zkabelac
c6ee487cfc Update 2010-02-15 20:32:27 +00:00
zkabelac
1a6df48bd0 Use dm_report_field_int32 instead of dm_report_field_uint64 for printing '-1' 2010-02-15 20:27:33 +00:00
Dave Wysochanski
6cdf300933 Update lvm2app.h comments to remove hidden VG comment list vgnames/vgids.
Peter recently fixed lvm_list_vg_names() and lvm_list_vg_uuids() so they
no longer return hidden names.  Remove the comment in lvm2app.h.
2010-02-15 19:55:49 +00:00
zkabelac
5365974d6c * update for last 3 commits 2010-02-15 18:42:51 +00:00
zkabelac
f1acefd241 Fix dm_report_field_uint64 to really use 64bit.
(function is currently not in use)
2010-02-15 18:36:48 +00:00
zkabelac
079fec6c5a Cleanup float arithmetic gcc warning. 2010-02-15 18:35:06 +00:00
zkabelac
14258c93de * add more 'const' - fixes gcc constness warning 2010-02-15 18:34:00 +00:00
Peter Rajnoha
03315d77f1 Add LVM_SUPPRESS_LOCKING_FAILURE_MESSAGES environment variable to suppress error
and warning mesages while --ignorelockingfailure is used.
2010-02-15 16:46:56 +00:00
Peter Rajnoha
34843e7d6c Remove hard-coded rule to skip _mimage devices in 11-dm-lvm.rules.
There's a tiny period of time when the _mimage device is visible during
downconversion from mirror to linear. Since it is visible, we need to
create the symlinks, otherwise warning messages will be issued about udev
not creating those symlinks. We have to rely on udev flags completely.
2010-02-15 16:38:22 +00:00
Peter Rajnoha
4efa67c4ec Update man page for dmsetup: --udevcookie, udevcreatecookie and udevreleasecookie. 2010-02-15 16:32:24 +00:00
Peter Rajnoha
2419c1c540 Use udev transactions in testsuite. 2010-02-15 16:30:13 +00:00
Peter Rajnoha
34055f40ac Don't use LVM_UDEV_DISABLE_CHECKING environment variable anymore.
Set the state automatically based on udev and libdevmapper dev path comparison.
If these paths differ, disable udev checking.
2010-02-15 16:26:48 +00:00
Peter Rajnoha
276d32973f Several changes in dmsetup and libdevmapper:
- add DM_UDEV_DISABLE_LIBRARY_FALLBACK udev flag to rely on udev only

 - export dm_udev_create_cookie function to create new cookies on demand

 - add --udevcookie, udevcreatecookie and udevreleasecookie for dmsetup
   (to support "udev transactions" where one cookie value can be used for
    several dmsetup calls)

 - don't use DM_UDEV_DISABLE_CHECKING env. var. anymore and set the state
   automatically (based on udev and libdevmapper dev path comparison)
2010-02-15 16:21:33 +00:00
Peter Rajnoha
f3c51a049d Rename "stat" to "status" in dmeventd_snapshot.c.
Otherwise "warning: declaration of ‘stat’ shadows a global declaration"
will appear because it shadows "stat" from stat.h.
2010-02-15 12:55:20 +00:00
Dave Wysochanski
21573cd4f0 Update simple lvm2app unit test for new size apis.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-02-14 03:23:07 +00:00
Dave Wysochanski
f25325f4bb Export lvm_pv_get_size(), lvm_pv_get_free(), lvm_pv_get_dev_size in lvm2app.
We add these exports to show the pv_size and pv_free and dev_size
fields.
Fixes rhbz561423.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-02-14 03:21:37 +00:00
Dave Wysochanski
5b12edfb34 Fix off by 512 sizes for lvm2app.
Internally we store sizes in sectors, but lvm2app exports sizes
in bytes.  We could get fancier and allow units configuration but
this fix should do for now.

Fixes rhbz561422.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2010-02-14 03:21:06 +00:00
Mike Snitzer
4697026132 Add 'fail_if_percent_unsupported' arg to _percent() and _percent_run(). 2010-02-10 15:56:20 +00:00
Mike Snitzer
6c39b8f4f0 Add 'fail_if_percent_unsupported' arg to _percent() and _percent_run().
We unfortunately don't yet _know_, in dev_manager_snapshot_percent(), if
a snapshot-merge target is active (activation is deferred if dev is
open); so we can't short-circuit origin devices based purely on existing
LVM LV attributes.

Set 'fail_if_percent_unsupported' in dev_manager_snapshot_percent() for
a merging origin LV, otherwise passing unsupported LV types to _percent
will lead to a default successful return with percent_range as
PERCENT_100.

For a merging origin, PERCENT_100 will result in a polldaemon that runs
infinitely (because completion is PERCENT_0).
2010-02-10 14:38:24 +00:00
Mike Snitzer
4a9af35527 Remove false "failed to find tree node for <lv>" error from _cached_info().
When activating a merging origin it is valid, and expected, to not have
a node in the deptree for both the origin and its merging snapshot.  The
_cached_info() caller is only concerned with whether a device is open.
If there isn't a node in the tree the associated device is definitely
not open.
2010-02-08 23:28:06 +00:00
Petr Rockai
881056af0b Make lvconvert --repair --use-policies exit with success when no action is needed. 2010-02-06 07:44:16 +00:00
Mike Snitzer
e5df490d5e Add multiple snapshot lv 'lvconvert --merge @tag' support via process_each_lv(). 2010-02-05 22:50:56 +00:00
Mike Snitzer
7c0d6057c5 Switch lvconvert_single() over to using get_vg_lock_and_logical_volume()
This change was deferred to help ease the review of previous refactoring
related to using process_each_lv() for lvconvert's merge support.  Not
that doing so _really_ helped but...

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2010-02-05 22:47:22 +00:00
Mike Snitzer
3e5a54a791 lvconvert --merge @tag support
Switch lvconvert's --merge code over to using process_each_lv().  Doing
so adds support for a single 'lvconvert --merge' to start merging
multiple LVs (which includes @tag expansion).

Add 'lvconvert --merge @tag' testing to test/t-snapshot-merge.sh

Adjust man/lvconvert.8.in to reflect these expanded capabilities.

The lvconvert.c implementation requires rereading the VG each iteration
of process_each_lv().  Otherwise a stale VG instance associated with
the LV passed to lvconvert_single_merge() would result in stale VG
metadata being written back out to disk.  This overwrote new metadata
that was written when a previous snapshot LV finished merging (via
lvconvert_poll).  This is only an issue when merging multiple LVs that
share the same VG (a single VG is typical for most LVM configurations on
system disks).

In the end this new support is very useful for performing a "system
rollback" that requires multiple snapshot LVs be merged to their
respective origin LV.

The yum-utils 'fs-snapshot' plugin tags all snapshot LVs that it creates
with a common 'snapshot_tag' that is unique to the yum transaction.
Rolling back a yum transaction, that created LVM snapshots with the tag
'yum_20100129133223', is as simple as:
  lvconvert --merge @yum_20100129133223

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2010-02-05 22:44:37 +00:00
Mike Snitzer
dbfd6e0d12 Prepare for _get_lvconvert_vg() reuse as part of a larger lvconvert.c
refactoring.

Document the need to cleanup the "name" args passed around polldaemon,
lvconvert and pvmove.  It is quite a mess.

Annotate the unused nature of the existing poll_fns->get_copy_vg
methods' 'uuid' arg.
2010-02-05 22:40:49 +00:00
Jonathan Earl Brassow
f607a0a0a6 Adding a new mimage (leg/copy) to a mirror behaves differently
depending on if the mirror has a 'core' or 'disk' log.  When there
is a disk log, the new leg is added by stacking a new mirror on
top of the old (one leg is the old mirror and the other leg is the newly
added device).  When the log is a 'core' log, the new leg is simply added
to the existing mirror and all the devices are re-synced.

The logic that handles collapsing the stacked 'disk' log mirror was
having the effect of causing 'core' logged mirrors to begin resync'ing
for a second time.  I have used the 'CONVERTING' flag to indicate that
a mirror is converting by way of stacking.  This is no longer set for
up-converting core logs.  The final 'collapse' logic can safely be skipped
for 'core' log mirrors - getting rid of the second resync.

Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
2010-02-05 21:49:16 +00:00
Peter Rajnoha
b15ada28ed This is related to liblvm and its lvm_list_vg_names() and lvm_list_vg_uuids() functions
where we should not expose internal VG names/uuids (the ones with "#" prefix )through the
interface. Otherwise, we could end up with library users opening internal VGs which will
initiate locking mechanism that won't be cleaned up properly.

"#orphans_{lvm1, lvm2, pool}" names are treated in a special way, they are truncated first
to "orphans" and this is used as a part of the lock name then (e.g. while calling lvm_vg_open()).
When library user calls lvm_vg_close(), the original name "orphans_{lvm1, lvm2, pool}"
is used directly and therefore no unlock occurs.

We should exclude internal VG names and uuids in the lists provided by lvmcache:
lvmcache_get_vgids() and lvmcache_get_vgnames().
2010-02-03 14:08:39 +00:00
Mike Snitzer
6610f9bdbc Add %ORIGIN support to lv{create,extend,reduce,resize} --extents option
Allow the number of logical extents to be expressed (for a snapshot) as
a percentage of the total space in the Origin Logical Volume with the
suffix %ORIGIN.

Update the relevant man pages accordingly.  Eliminate inconsistencies
between the man pages and tools/commands.h

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2010-02-03 03:58:08 +00:00
Mike Snitzer
5f87626377 move WHATS_NEW entries whose changes were made after 2.02.60 to 2.02.61 2010-02-02 17:48:30 +00:00
Dave Wysochanski
54834a1761 Add copy constructor for struct metadata_area.
Clean up cut&paste code with proper copy constructor.
2010-02-02 16:26:34 +00:00
Alasdair Kergon
adf7081163 Remove pointless versioned symlinks to dmeventd plugin libraries. 2010-02-02 14:09:17 +00:00
Alasdair Kergon
a50b7c55d3 Fix dmeventd snapshot plugin build dependency. 2010-02-02 14:03:50 +00:00
Christine Caulfield
f4f171e04d Make clvmd -V return zero status rather than 1. 2010-02-02 08:54:29 +00:00
Dave Wysochanski
d5ea20a6eb Remove unnecessary "dmsetup resume" after "dmsetup create".
It is not necessary to resume after a create since the create will
create the table and make it active.
2010-02-01 19:43:22 +00:00
Jonathan Earl Brassow
5584f2ae46 Was using dm_list_iterate_items when I should have been using
*_safe.  This had the effect of segfaulting the log daemon when
converting a mirror from one log type to another.

Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
2010-01-27 22:28:05 +00:00
Milan Broz
b79d8b1ff0 Fix pvmove abort when temporary mirror fails to be cluster-aware.
When activation of pvmove mirror fails on cluster, some nodes
still possibly succeeded in activation.

 - Explicitly deactivate that mirror to be sure
 - properly pair suspend/resume calls to not cause memory lock problems in clvmd

Code cannot simply call _finish_pvmove on cluster in this situation, because
changed LVs are suspended twice (causing memory inbalance) and also temporary
mirror is activated when it is not expected (and we know that it failed already).

Patch prepares special function which remove temporary mirror references from
metadata and then resumes changed LVs.
2010-01-27 13:29:11 +00:00
Milan Broz
1c33c0027f Always query device by using uuid only and not name in clvmd.
Otherwise confusion with the device of the same name
(but different UUID, e.g. non-lvm device) can happen.
2010-01-27 13:23:57 +00:00
Milan Broz
aef0a98840 Add some missing vg_revrts calls when pvmove aborts. 2010-01-26 08:01:18 +00:00
Milan Broz
9d23a04c0e Unlock shared lock if activation calls failed.
Clvmd should unlock new lock if activation in device-mapper fails.
2010-01-26 08:00:02 +00:00
Milan Broz
453bab220b Fix return code of info callbacks.
In dev_manager_info 0 means error and 1 info is returned,
not that device exists (that value is part of info struct).

Fix query by uuid only (no name) which returns 0 when device
does not exist.
2010-01-26 07:58:23 +00:00
Alasdair Kergon
448f8c4240 pre-release 2010-01-23 02:14:30 +00:00
Mike Snitzer
5a414c6ad1 Default to checking LV's progress before waiting in _wait_for_single_lv.
Support "wait before testing" using '+' in pvmove and lvconvert
interval.  Doing so overrides the new default of sleeping after checking
the LV's progress.

Sleeping before checking progress can lead to extraneous polldaemons
being left running.  These polldaemons would have otherwise exited had
they checked before sleeping.  Checking progress before sleeping helps
workaround the subtly unreliable nature of "finished" state checking
in _percent_run.

Update test/t-mirror-names.sh to use '+' when providing its lvconvert
interval.
2010-01-22 21:59:42 +00:00
Jonathan Earl Brassow
65a942f01f a little more information for the cmirrord man page 2010-01-22 21:48:17 +00:00
Milan Broz
6df32fed62 Fix syntax error in cmirror init script
- break cannot be used here
 - remove CLVMDOPTS
 - add echo to stop call
2010-01-22 16:19:38 +00:00
Mike Snitzer
1199b48cd7 Eliminate extra ioctls just to check open_count in _add_new_lv_to_dtree.
DM >= 4.7.0 always returns open_count so just use the associated nodes'
existing info.

Introduce _cached_info() to get an LV's cached info.
2010-01-22 15:40:31 +00:00
Milan Broz
c493f56e1b Document undocumented commits which fixed some bugs.
Go WHATS_NEW!
2010-01-22 14:33:33 +00:00
Mike Snitzer
2e65b8ce5f Removed inactive_table check from _lv_has_target_type. This check
doesn't offer any benefit (that I can recall) and testing validates
that.
2010-01-22 13:28:54 +00:00
Milan Broz
42a6d954d3 Switch memory debugging off for now if compiled with dmeventd,
functions are not thread-safe in debug mode.
2010-01-22 13:20:32 +00:00
Milan Broz
8f73b4c3ae Fix syslog prefix in the first message (dmeventd->lvm). 2010-01-22 12:48:58 +00:00
Milan Broz
adcd06fccb Fix exported symbols for lvm2 dmeventd wrapper. 2010-01-22 12:38:16 +00:00
Milan Broz
c40380f72a Move error message to locking constructor and print
more descriptive message if locking fails instead of
"Locking type -1 initialisation failed."

Use read-only locking instead of misleading ignorelocking option
in message.
2010-01-22 09:45:29 +00:00
Alasdair Kergon
8e44e884a2 post-release 2010-01-22 01:09:09 +00:00
Alasdair Kergon
e2368be912 missing header 2010-01-22 00:43:28 +00:00
Alasdair Kergon
7986fd4db7 fix lib include 2010-01-22 00:18:37 +00:00
Alasdair Kergon
6107f4a02a pre-release 2010-01-21 23:55:17 +00:00
Alasdair Kergon
2ce63814e9 Add libdevmapper-event-lvm2.so to serialise dmeventd plugin liblvm2cmd use. 2010-01-21 22:15:45 +00:00
Dave Wysochanski
8ba508f8f7 Call _alloc_pv() inside _pv_read() and clean up error paths.
We should be consistent with pv constructors so call _alloc_pv()
here as we do from pv_create().
2010-01-21 21:09:23 +00:00
Dave Wysochanski
2100490424 Remove useless memory allocation for pv->vg_name in _alloc_pv().
All this seems to do is provide a memory leak so remove it.
The only caller of _alloc_pv() later explicitly sets
pv->vg_name = fmt->orphan_vg_name so clearly this allocation
should be removed.  I also saw no where in the code where
strncpy was used to assign pv->vg_name - only direct assignments
and strdup's.
2010-01-21 21:04:44 +00:00
Dave Wysochanski
7e7639e39a Correct 'void *' usage in pvcreate_single.
Remove needless cast.
2010-01-21 21:04:20 +00:00
zkabelac
3555d0ecd5 Log entry for the last lvmcmdline.c commit 2010-01-21 17:14:18 +00:00
zkabelac
ecb9a01cfa Reset released pointer and counters.
DSO is currently not dl_close-ing pluing during it is unregister handling,
so clear structure and related counter, so there are no memory problems.
Futher fixes are needed.
2010-01-21 13:41:39 +00:00
Mike Snitzer
ca352ebfba Preload the origin prior to suspend IFF snapshot(s) still exist after a
merge completes.  This narrows the scope of this "hack" (which still
needs a proper fix within the deptree).

This stops dmeventd from trying to access snapshot devices that were
already removed.
2010-01-20 21:53:10 +00:00
Jonathan Earl Brassow
29c73eb67b Fill in a little more on the man page for cmirrord 2010-01-20 15:17:25 +00:00
Alasdair Kergon
2a598ff24d Deal with a few more compiler warnings. 2010-01-20 02:43:19 +00:00
Mike Snitzer
f6d5837e5e Add t-topology-support.sh and t-snapshot-merge.sh tests. 2010-01-19 23:02:04 +00:00
Mike Snitzer
dac8cee72c add test/t-snapshot-merge.sh to provide coverage of snapshot-merge support 2010-01-19 22:55:00 +00:00
Alasdair Kergon
e01a2f8324 Remove mknod() and add FIXMEs.
In the udev-world, this function should work differently.
2010-01-19 18:21:03 +00:00
Alasdair Kergon
a092ccb82b remove more compiler warnings
add FIXMEs for incomplete write()s
2010-01-19 17:24:29 +00:00
Mike Snitzer
e894d07b92 test/t-topology-support.sh requires scsi_debug from >= 2.6.31 2010-01-19 17:06:50 +00:00
Alasdair Kergon
befef6eb00 remove no-longer-used header 2010-01-19 17:04:05 +00:00
Alasdair Kergon
162224979d remove no-longer-used files 2010-01-19 17:01:17 +00:00
Mike Snitzer
a90f6e2dda Add a common way to establish a scsi_debug-based 4K drive for use by an
LVM2 test (rather than using the traditional loop device).

prepare_scsi_debug_dev currently assumes exclussive access to the
scsi_debug module.  Any script that tries to use prepare_scsi_debug_dev
when scsi_debug is unavailable or already loaded into the kernel will be
skipped.

t-topology-support.sh shows how prepare_scsi_debug_dev function can be
used repeatedly (within a script) to test LVM2 ontop of a ramdisk-based
SCSI device w/ arbitrary scsi_debug features.
2010-01-19 16:44:57 +00:00
Mike Snitzer
e449bfd741 update test/t-pvcreate-operation-md.sh attempt loading raid0.ko if raid0
isn't already available (in /proc/mdstat).

switch to requiring 2.6.33 for the alignment_offset tests; 2.6.{31,32}
alignment_offset values aren't reliable.  2.6.33 _should_ have mkp's
alignment_offset fixes but so far it doesn't (as of 2.6.33-rc4).
2010-01-19 15:59:34 +00:00
Alasdair Kergon
8ecc1eb99d Signal handling FIXMEs.
A few integer type changes.
2010-01-19 15:58:45 +00:00
Milan Broz
1fb910411e Never scan suspended devices in clvmd.
For mirror repair (and similar tasks) it can happen that full
device rescan is issued from clvmd.

Because code can be in the middle of repair (calling suspend)
clvmd should never try to scan suspended devices
(otherwise it causes deadlock).

Also code must not change ignore_suspended_device flag when
doing refresh_filters (called from lvmcache scan code).
2010-01-19 13:25:00 +00:00
Alasdair Kergon
3141b86d01 And more fixes for cmirror build. 2010-01-19 02:04:33 +00:00
Alasdair Kergon
f8ff64c87e more build fixes 2010-01-19 01:10:46 +00:00
Alasdair Kergon
c71b834aad Clean up include files. 2010-01-18 21:07:24 +00:00
Jonathan Earl Brassow
a78e7d0287 Fix some compiler warnings. 2010-01-18 20:58:50 +00:00
Alasdair Kergon
09cf0fe6b9 Misc compilation clean-ups. 2010-01-18 20:08:44 +00:00
Mike Snitzer
13713bc147 Change dev_manager_mirror_percent()'s 'struct logical_volume *' to be
'const'.  Be consistent with its use (and dev_manager_snapshot_percent()).

Pass 'lv' from dev_manager_snapshot_percent() to _percent() to
_percent_run().  _percent_run() always dereferenced 'lv' (when
initializing segh) even though it may have been NULL (as was the case
until now for dev_manager_snapshot_percent()).

If a "snapshot-origin" LV (snapshot-merge whose merge was deferred
becuase it was open) was passed to _percent_run() it would always return
100%.

Update _percent_run() to NOT return PERCENT_100 et. al. if
->target_percent() wasn't ever called and supplied 'lv' is a merging
origin.  A default return of 100% does not work for snapshot-merge.

Also tweak a related lvconvert log_error() to include "Aborting merge."
2010-01-15 22:58:25 +00:00
Jonathan Earl Brassow
9c17cf4edf Use tabs, not spaces. 2010-01-15 21:48:03 +00:00
Jonathan Earl Brassow
938b25b986 Initial version of the cmirrord init script
Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
2010-01-15 20:47:52 +00:00
Jonathan Earl Brassow
040b76f1e6 initial cmirrord man page
Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
2010-01-15 20:24:04 +00:00
Jonathan Earl Brassow
66226207ce Make the intermachine communication structures architecture independant
to allow for mixed architecture clusters.

Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
2010-01-15 19:49:35 +00:00
Jonathan Earl Brassow
999b4168c1 When moving the cluster log server into the LVM tree, the in memory
bitmap tracking was switched from the e2fsprogs implementation to
the device-mapper implementation (dm_bitset_t).  The latter has a
leading uin32_t field designed to hold the number of bits that are
being tracked.  The code was not properly handling this change in
all places.  Specifically, when getting the bitmap to/from disk.

Endian adjustments will likely need to be made on the accounting
field as well, since bitmaps are passed between machines on
start-up.

Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
2010-01-15 18:48:24 +00:00
Mike Snitzer
9bfc452487 Detect case of both merging_store and cow_store supplied in
_snap_text_import().
2010-01-15 17:46:08 +00:00
Mike Snitzer
df675ed9fb Improve target type compatibility checking in _percent_run().
Add 'target_status_compatible' method to 'struct segtype_handler'.
2010-01-15 16:35:26 +00:00
Jonathan Earl Brassow
4a13ae4c95 udpate WHATS_NEW* 2010-01-15 16:18:14 +00:00
Jonathan Earl Brassow
5287c71d68 At some point "clustered_[core|disk]" was changed to "clustered-[core|disk]".
This patch makes the log server recognise the new format.

Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
2010-01-15 16:03:19 +00:00
Jonathan Earl Brassow
827f1a3d30 Off-by-one count was causing not all the mirror table parameters
that were necessary to be passed on to userspace.

The cluster mirror table (log portion only) used to look like this:
        clustered-disk <parm_count> <disk> <region_size> <uuid> \
                        [[no]sync] [block_on_error]
Now it looks like this:
        userspace <parm_count> <uuid> clustered-disk <disk> <region_size> \
                        [[no]sync]

So, there is one extra argument in the latter case - this was
unaccounted for.

Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
2010-01-15 16:00:23 +00:00
Alasdair Kergon
f6d95e19c4 post-release 2010-01-14 14:42:06 +00:00
Alasdair Kergon
3eb93f161f Note some problems still to be addressed. 2010-01-14 14:39:57 +00:00
Alasdair Kergon
801eff0c52 pre-release 2010-01-14 14:02:34 +00:00
zkabelac
c1993e76c2 Update entry for few previous gcc cleanup commits. 2010-01-14 10:19:43 +00:00
zkabelac
c23f56b9cb Cleanup const compiler warning 2010-01-14 10:17:12 +00:00
zkabelac
44e17e2aa9 Cleanup gcc warning: cast discards qualifiers from pointer target type
API of the library should remain the same as the 'const' is not
mangled into the function name in C.
2010-01-14 10:15:23 +00:00
zkabelac
84758667c1 Cleanup gcc warning: cast from function call of type 'struct dm_list *'
to non-matching type 'long unsigned int'

Casting pointer to long and back to pointer could be easily
handled with just pointer arithmetic.
2010-01-14 10:12:44 +00:00
zkabelac
8c71113cd6 Cleanup gcc warning: null argument where non-null required (arg.2)
As the const declaration of execvp is a bit weird, using local
dmeventdpath string.
2010-01-14 10:11:26 +00:00
zkabelac
79ba99811c Move initialization of the 'cmd' member of the struct alloc_handle
before the first potentional return.
2010-01-14 10:09:42 +00:00
zkabelac
55a664d6fd lvol%d is generated for NULL name in lv_create_empty().
So just avoid code duplication.
2010-01-14 10:08:03 +00:00
Mike Snitzer
b4affd607d update WHATS_NEW and WHATS_NEW_DM to include snapshot-merge changes 2010-01-13 21:48:39 +00:00
Milan Broz
c7007c98d7 Fix clvmd automatic target module loading crash. 2010-01-13 17:40:17 +00:00
Mike Snitzer
fa684a97da Rename segment and lv status flag from SNAPSHOT_MERGE to MERGING.
Eliminate 'merging_snapshot' from 'struct logical_volume' and just use
'snapshot' for origin lv's reference to the merging snapshot; also set
MERGING in the origin lv's status.
2010-01-13 01:56:18 +00:00
Mike Snitzer
cad03afc54 Add snapshot merge wrappers to abstract the associations and flags used
to represent merging origin and snapshot volumes.
2010-01-13 01:55:43 +00:00
Mike Snitzer
fe6d782751 Update lvconvert manpage for snapshot --merge 2010-01-13 01:55:05 +00:00
Mike Snitzer
dfe517cfbe Merge on activate support.
If either the origin or snapshot that is to be merged is open the merge
will not start; only the merge metadata will be written.  The merge will
start on the next activation of the origin (or via lvchange --refresh)
IFF both the origin and snapshot are closed.

Merge on activate is particularly important if we want to merge over a
mounted filesystem that cannot be unmounted (until next boot) --- for
example root.
2010-01-13 01:54:34 +00:00
Mike Snitzer
46ab95f24c When turning merging origin into non-merging origin, there is bad sequence:
snapshots are suspended, new origin is created, snapshots are resumed, new
origin is resumed.  So it allocates memory while suspended.

To fix it, move vg_commit after suspend_lv, so that the suspend code will
treat it as precommitted vg and will preload new origin prior to suspend.

NOTE: agk doesn't like this "hack"; need to revisit and fix
2010-01-13 01:52:58 +00:00
Mike Snitzer
9a57ea4c4a Reload origin if merging has stopped. 2010-01-13 01:51:45 +00:00
Mike Snitzer
5fc98ffa69 Start background polling of merging stores on:
- lvchange -ay or vgchange -ay.
- lvchange --refresh or vgchange --refresh.
2010-01-13 01:50:34 +00:00
Mike Snitzer
814eb397e1 Background poll for lvconvert --merge command.
The merging snapshot is removed when the merge finishes.
2010-01-13 01:49:52 +00:00
Mike Snitzer
77f030956c When there is merging snapshot, report percentage on the origin LV.
Because the snapshot LV will be hidden this is needed so the user can
see merging progress with "lvs" command.
2010-01-13 01:49:22 +00:00
Mike Snitzer
ab7ad3451d Report merging snapshot as 'S' instead of 's':
This is useful for when the snapshot is still active and merging hasn't
started yet; it shows a merge is pending.  Once merging starts the
merging snapshot will be hidden but can still be displayed with 'lvs -a'

Report snapshot origin with merging snapshot as 'O' instead of 'o':
Before merge starts this shows that a merge is pending.  While merging
the snapshot will be hidden, 'O' enables a user to see that there is a
snapshot merging.
2010-01-13 01:48:38 +00:00
Mike Snitzer
1107f82824 Do not allow merging over mounted logical volumes.
When preserving origin, check that the snapshot is not mounted.
2010-01-13 01:47:18 +00:00
Mike Snitzer
2bc2378033 Add --merge support to lvconvert to start merging a snapshot into its
origin, example usage:  lvconvert --merge vg/snaplv
2010-01-13 01:45:15 +00:00
Mike Snitzer
676e214f34 Merging device is loaded with "-cow" suffix and with base name of the
origin.  This is needed so that "-cow" device can be found and removed
when lvremove is performed.
2010-01-13 01:44:37 +00:00
Mike Snitzer
7df1ccbf91 Conditionally push down either the "snapshot-origin" or
"snapshot-merge" target based on whether the LV is a merging snapshot.

When activating a snapshot-merge target do not attempt to monitor the
LV for events; the polldaemon will monitor the snapshot as it is
merged.

Allow "snapshot-merge" target's usage to be parsed via standard
"snapshot" methods.

NOTE: follow on fixes to the _percent_run change are still needed
2010-01-13 01:43:32 +00:00
Mike Snitzer
82d3ee5454 Add support for "snapshot-merge" target.
Introduces new libdevmapper function dm_tree_node_add_snapshot_merge_target

Verifies that the kernel (dm-snapshot) provides the 'snapshot-merge'
target.

Activate origin LV as snapshot-merge target.  Using snapshot-origin
target would be pointless because the origin contains volatile data
while a merge is in progress.

Because snapshot-merge target is activated in place of the
snapshot-origin target it must be resumed after all other snapshots
(just like snapshot-origin does) --- otherwise small window for data
corruption would exist.

Ideally the merging snapshot would not be activated at all but if it is
to be activated (because snapshot was already active) it _must_ be done
after the snapshot-merge.  This insures that DM's snapshot-merge target
will perform exception handover in the proper order (new->resume before
old->resume).  DM's snapshot-merge does support handover if the reverse
sequence is used (old->resume before new->resume) but DM will fail to
resume the old snapshot; leaving it suspended.

To insure the proper activation sequence dm_tree_activate_children() was
updated to accommodate an additional 'activation_priority' level.  All
regular snapshots are 0, snapshot-merge is 1, and merging snapshot is 2.
2010-01-13 01:39:44 +00:00
Mike Snitzer
fcb6fb00e0 Add 'SNAPSHOT_MERGE' lv_segment 'status' flag.
Make 'merging_snapshot' pointer that points from the origin to the
segment that represents the merging snapshot.

Import/export 'merging_store' metadata.

Do not allow creating snapshots while another snapshot is merging.
Snapshot created in this state would certainly contain invalid data.

NOTE: patches at the end of this series will remove 'merging_snapshot'
and will introduce helpful wrappers and cleanups.
2010-01-13 01:35:49 +00:00
Alasdair Kergon
4e09e6ca10 Fix allocation code not to stop at the first area of a PV that fits.
This spurious 'break' has been here since this code was first committed
in June 2005 and stopped the algorithm behaving as described in the
comment above it and rendered the variable 'already_found_one' useless.
2010-01-12 20:53:20 +00:00
Alasdair Kergon
af6dd44048 post-release 2010-01-12 14:46:59 +00:00
Alasdair Kergon
d30ec9fd1e pre-release 2010-01-12 14:39:07 +00:00
Alasdair Kergon
16ee54ad23 disable 'redundant' tests 2010-01-12 14:19:46 +00:00
Alasdair Kergon
627409ec38 Revert so-called "redundant" log until after next release. 2010-01-12 14:00:51 +00:00
Alasdair Kergon
4ead572462 . 2010-01-11 21:44:36 +00:00
Alasdair Kergon
42783a54db Add missing items to WHATS_NEW files.
Continue to use 'field' to describe reporting elements.
2010-01-11 21:28:04 +00:00
Jonathan Earl Brassow
84763527c5 Add new test cases for mirrors that are under snapshots. 2010-01-11 21:27:49 +00:00
Jonathan Earl Brassow
1744c1c2ba Testsuite updates and fixes for recently added features.
1. Found bug in 'redundant log' implementation that caused
   problems when converting a linear that spanned multiple
   devices to a mirror (wasn't checking for NULL value of
   provided parameter in _alloc_parallel_area)

2. Testsuite was failing to perform tests when 'not' modifier
   was used.  This allowed a couple issues to slip through.
   Added a 'not_sh' modifier that negates tests performed by
   functions defined in the shell source file.

3. Was initializing a variable to far down, which cause
   previously set value to be overridden.  (This was the
   result of the collision of the "redundant log" and
   lvconvert fix patches.)
2010-01-11 21:20:19 +00:00
Alasdair Kergon
7ef5fbdbe6 Use _LOG_FATAL when aborting on an internal error. 2010-01-11 20:41:39 +00:00
Alasdair Kergon
b1482c52b7 Internal errors triggering abort cannot be suppressed. (kabi) 2010-01-11 20:30:32 +00:00
Mike Snitzer
7b0d61b96d Only allow one return from poll_daemon(). If a child polldaemon was
successfully created it must _exit() once it completes.

Update _become_daemon() to differentiate between a failed fork() and a
successful fork().

Added lvm_return_code() to lvmcmdline.[ch]
2010-01-11 19:19:17 +00:00
Mike Snitzer
951b974c4d remove errant comment fragment 2010-01-11 19:12:25 +00:00
Mike Snitzer
975b3c3428 Reset _vgs_locked in lvmcache_init()
Upon successful fork(), _become_daemon() must assert that the locks that
are currently held belong to the parent, not the child.  All of the
child's internal state saying 'this process holds a lock' has to be
reset.

A proper lvmcache_locking_reset() should follow later.
2010-01-11 19:08:18 +00:00
Jonathan Earl Brassow
f0420012e6 Found 2 problems with my previous check-in:
date: 2010/01/07 20:42:55;  author: jbrassow;  state: Exp;  lines: +11 -0
 The patch fixes some lvconvert issues (WRT mirror <-> mirror).

1) 'exisiting_mirrors' and 'lp->mirrors' where taken to be in 'n-1'
   notation (i.e a 2-way mirror is '1' and a linear is '0'), but the
   variables were in 'n' notation.
2) After adding the redundant mirror log support, I was calculating
   log_count by looking at the mirror log LV, but didn't take into
   account the fact that there could be no mirror log!

Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
2010-01-11 17:13:45 +00:00
Peter Rajnoha
30e5413e2b Substitute UDEV_SYNC value for use in the other files and show a warning message when libudev not found and using udev_sync. 2010-01-11 15:59:54 +00:00
Peter Rajnoha
5077a1bb83 Show a warning message when libudev not found and we're using --enable-udev_sync.
Just to emphasize what one can expect - we won't be able to get udev state
and we will consider that udev is not running at all.
2010-01-11 15:51:44 +00:00
Peter Rajnoha
a8ed16de33 Define {DM, LVM}_UDEV_DISABLE_CHECKING=1 env. variables for tests.
We need to disable udev checking for our tests since they use their own
location for device nodes and symlinks.
2010-01-11 15:48:49 +00:00
Peter Rajnoha
ee0a4914d5 Enable udev_sync and udev_rules in lvm.conf by default while running tests. 2010-01-11 15:43:19 +00:00
Peter Rajnoha
8b70a0d0b7 Add support to disable udev checking: LVM_UDEV_DISABLE_CHECKING=1 env. var.
LVM_UDEV_DISABLE_CHECKING=1 applies for /dev/<vgname> content only.
We still need to define DM_UDEV_DISABLE_CHECKING=1 for /dev/mapper content.
2010-01-11 15:40:03 +00:00
Peter Rajnoha
8e7c6b60fb Add support to disable udev checking: DM_UDEV_DISABLE_CHECKING=1 env. variable.
Sometimes it is really needed to switch off udev checking and the warnings we show when
we detect that udev has not done its job right - the messages like "Udev should have done
this and that. Falling back to direct node creation/removal. " etc.

This would be especially handy while setting DM_DEV_DIR env var that could be set to a
different location than standard /dev (udev can't create nodes/symlinks out of that one
directory that is configured into udevd). The exact same situation happens while we're
running our tests.
2010-01-11 15:36:24 +00:00
Mike Snitzer
fbb0bb63e7 remove unused variable 'i' that was recently introduced in lv_add_segment 2010-01-10 20:44:09 +00:00
Jonathan Earl Brassow
46dc1b6e99 update comment 2010-01-08 23:06:36 +00:00
Jonathan Earl Brassow
82b34e06f2 Add the new mirror log type "redundant". The options are now:
--mirrorlog core: in-memory log
--mirrorlog disk: persistent log
--mirrorlog redundant: redundant persistent log

Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
2010-01-08 22:32:35 +00:00
Jonathan Earl Brassow
bc178df8f0 udpate WHATS_NEW file for --splitmirror checkin 2010-01-08 22:28:54 +00:00
Jonathan Earl Brassow
d5a3de5a97 This patch adds the capability to split off a mirror legs.
It is pretty much the same as reducing the number of
mirror legs, but we just don't delete them afterwards.

The following command line interface is enforced:
  prompt> lvconvert --splitmirror <n> -n <name> <VG>/<LV>
where 'n' is the number of images to split off, and
where 'name' is the name of the newly split off logical volume.

If more than one leg is split off, a new mirror will be the
result.  The newly split off mirror will have a 'core' log.
Example:
[root@bp-01 LVM2]# !lvs
lvs -a -o name,copy_percent,devices
  LV            Copy%  Devices
  lv            100.00 lv_mimage_0(0),lv_mimage_1(0),lv_mimage_2(0),lv_mimage_3(0)
  [lv_mimage_0]        /dev/sdb1(0)
  [lv_mimage_1]        /dev/sdc1(0)
  [lv_mimage_2]        /dev/sdd1(0)
  [lv_mimage_3]        /dev/sde1(0)
  [lv_mlog]            /dev/sdi1(0)
[root@bp-01 LVM2]# lvconvert --splitmirrors 2 --name split vg/lv /dev/sd[ce]1
  Logical volume lv converted.
[root@bp-01 LVM2]# !lvs
lvs -a -o name,copy_percent,devices
  LV               Copy%  Devices
  lv               100.00 lv_mimage_0(0),lv_mimage_2(0)
  [lv_mimage_0]           /dev/sdb1(0)
  [lv_mimage_2]           /dev/sdd1(0)
  [lv_mlog]               /dev/sdi1(0)
  split            100.00 split_mimage_0(0),split_mimage_1(0)
  [split_mimage_0]        /dev/sde1(0)
  [split_mimage_1]        /dev/sdc1(0)

It can be seen that '--splitmirror <n>' is exactly the same
as '--mirrors -<n>' (note the minus sign), except there is the
additional notion to keep the image being detached from the
mirror instead of just throwing it away.

Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
2010-01-08 22:00:31 +00:00
Mike Snitzer
b8774d7aac Change background polldaemon's process name to "(lvm2)".
Made .update_metadata optional in 'struct poll_functions' definitions;
eliminated _update_lvconvert_mirror() stub.

Tweak a mirror-specific error message in the generic polldaemon code.

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2010-01-08 21:53:07 +00:00
Petr Rockai
891246562f Allow vgremove of a VG with PVs missing. 2010-01-08 14:03:54 +00:00
Petr Rockai
e53a955115 In lvconvert --repair --use-policies, for the allocate policies, return success
even if allocation fails, as long as the downconversion or corelog conversion
succeeded.
2010-01-08 13:04:10 +00:00
zkabelac
1ec6812246 orig_status preserves 64bit status. 2010-01-08 10:50:11 +00:00
Jonathan Earl Brassow
e896691b0f - forgot to update WHATS_NEW along with bug fix for keeping
log type consistent when using lvconvert to change the
  number of mirror images.
2010-01-07 20:55:01 +00:00
Jonathan Earl Brassow
fbe92a13c0 The patch fixes some lvconvert issues (WRT mirror <-> mirror).
The default log option for a mirror is 'disk'.  If the log
type is not explicitly stated on the command line when
converting from an X-way mirror to a Y-way mirror, 'disk'
is chosen.  So, if you have a 'core' log mirror and you
convert, your result will contain a 'disk' log.

This patch remembers what the old log type was.  If the
user is merely trying to switch the number of mirror
images, the log type is now kept the same.

There is one historical behaviour I left in place...
If you have a 2-way, core-log mirror and you use lvconvert to
specify you want a 2-way mirror - without specifying the
log type - you will get a 2-way, disk-log mirror.

Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
Informal-IRC-ACK-by: agk
2010-01-07 20:42:55 +00:00
Peter Rajnoha
94a434e9e7 Always set environment variables for an LVM2 device in 11-dm-lvm.rules.
This way we can still use DM_LV_NAME, DM_VG_NAME and DM_LV_LAYER in all
the other rules.
2010-01-07 20:01:55 +00:00
Peter Rajnoha
e829c626da Add activation/udev_rules config option in lvm.conf.
Add dm_tree_add_dev_with_udev_flags to provide wider support for udev flags.
2010-01-07 19:54:21 +00:00
Peter Rajnoha
837adeea7f Add --noudevrules option for dmsetup to disable /dev node management by udev. 2010-01-07 19:45:12 +00:00
zkabelac
65d6350d36 Add few const modifiers. 2010-01-07 14:47:57 +00:00
zkabelac
ba99186951 Use macro outsize() with check for error return value. 2010-01-07 14:46:51 +00:00
zkabelac
b3975f5098 Export function out_text_with_comment() and add outfc() macro that checks
for error.
2010-01-07 14:45:28 +00:00
zkabelac
b90f909289 Add macros outsize() for out_size() and outhint() for out_hint() that check
for errors in a similar way as outf() for out_text().
2010-01-07 14:40:46 +00:00
zkabelac
d098e4def6 Use offsetof() macro and avoid defining dummy static union for FIELD() macro.
Makes it compilable by clang compiler.
2010-01-07 14:37:11 +00:00
zkabelac
835b0d9f62 Error message prints unrecognized key. 2010-01-07 14:32:44 +00:00
zkabelac
9fea2798e3 Show all fields for 'dmsetup info -c -o all'. 2010-01-07 14:30:47 +00:00
zkabelac
394cae5d21 Just add '.' at the end of error message. 2010-01-07 14:29:53 +00:00
zkabelac
7996aae5e9 Fix typo fsdam -> fsadm (closes bug 552721) 2010-01-07 09:42:51 +00:00
Mike Snitzer
9788b9d7a9 . update documentation for --poll in the vgchange and lvchange man pages
. add high-level --poll FIXMEs to vgchange.c and lvchange.c
2010-01-06 19:08:58 +00:00
Milan Broz
6f5e1c3d73 Rename mirror_device_fault_policy to mirror_image_fault policy 2010-01-06 13:27:06 +00:00
Milan Broz
d4421b12ba Remove empty "repaired" devices if empty in lvconvert.
The logic was that lvconvert repair volumes, marking
PV as MISSING and following vgreduce --removemissing
removes these missing devices.

Previously dmeventd mirror DSO removed all LV and PV
from VG by simply relying on
vgreduce --removemissing --force.

Now, there are two subsequent calls:
lvconvert --repair --use-policies
vgreduce --removemissing

So the VG is locked twice, opening space for all races
between other running lvm processes. If the PV reappears
with old metadata on it (so the winner performs autorepair,
if locking VG for update) the situation is even worse.


Patch simply adds removemissing PV functionality into
lvconcert BUT ONLY if running with --repair and --use-policies
and removing only these empty missing PVs which are
involved in repair.
(This combination is expected to run only from dmeventd.)
2010-01-06 13:26:21 +00:00
Milan Broz
099b03f038 Use fixed buffer to prevent stack overflow in persistent filter dump. 2010-01-06 13:25:36 +00:00
Mike Snitzer
f84d2eeec9 update WHATS_NEW and WHATS_NEW_DM with previous commits' changes 2010-01-05 21:32:59 +00:00
Mike Snitzer
f02531802c Use snapshot metadata usage to determine if snapshot is empty
Version >= 1.8.0 of the DM snapshot target appends metadata sectors used
to a snapshot's status.  This patch allows LVM2 to accurately determine
if the snapshot store is empty.  Knowing when a snapshot store is empty
is important in the context of snapshot-merge (means merge is complete).

Also update LVM2 to be aware of the possibility for "Merge failed" in
the snapshot-merge target's status.

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2010-01-05 21:14:04 +00:00
Mike Snitzer
375cb5c31d Add missing 'stack;' for all activate_lv and deactivate_lv callers.
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2010-01-05 21:08:34 +00:00
Mike Snitzer
8f2ba4ec3c Add missing 'stack;' for all suspend_lv and resume_lv callers.
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2010-01-05 21:07:31 +00:00
Mike Snitzer
9935d1183a Return error to dm_tree_deactivate_children() callers.
Otherwise deactivate_lv can fail silently.

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2010-01-05 21:06:26 +00:00
Mike Snitzer
aff8e77bec Return error to dm_tree_suspend_children() callers.
Otherwise suspend_lv and its variants can fail silently.

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2010-01-05 21:05:40 +00:00
Mike Snitzer
c9fd743c65 Return error to dm_tree_preload_children() and
dm_tree_activate_children() callers.

Otherwise resume_lv and its variants can fail silently.

Catching these failures is especially important now that dm targets like
crypt and snapshot-merge can fail in .preresume

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2010-01-05 21:04:37 +00:00
Mike Snitzer
7a4fa925fc Add a [--poll {y|n}] flag to vgchange and lvchange to control whether
the background polldaemon is allowed to start.  It can be used
standalone or in conjunction with --refresh or --available y.

Control over when the background polldaemon starts will be particularly
important for snapshot-merge of a root filesystem.

Dracut will be updated to activate all LVs with: --poll n

The lvm2-monitor initscript will start polling with: --poll y

NOTE: Because we currently have no way of knowing if a background
polldaemon is active for a given LV the following limitations exist and
have been deemed acceptable:
1) it is not possible to stop an active polldaemon; so the lvm2-monitor
   initscript doesn't stop running polldaemon(s)
2) redundant polldaemon instances will be started for all specified LVs
   if vgchange or lvchange are repeatedly used with '--poll y'

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2010-01-05 20:56:51 +00:00
Milan Broz
ff442c1e28 Propagate commit and revert metadata event to other nodes in cluster.
This patch tries to correctly track changes in lvmcache related to commit/revert.

For vg_commit: if there is cached precommitted metadata, after successfull commit
these metadata must be tracked as committed.

For vg_revert: remote nodes must drop precommitted metadata and its flag in lvmcache.

(N.B. Patch do not touch LV locks here in any way.)

All this machinery is needed to properly solve remote node cache invalidaton which
cause several problems recently observed.
2010-01-05 16:09:33 +00:00
Milan Broz
5cedaa972a Proper mask lock mode for vg lock.
Lock mode is int masked by LCK_TYPE_MASK, always.

Patch also remove uneccessary masking lock flag on sender side,
if masking is needed, it is don on client side already.
2010-01-05 16:07:56 +00:00
Milan Broz
2c8f647e0c Add possibility to handle precommitted metadata in lvmcache.
- Add drop_precommitted flag to force drop precommitted metadata
 - add lvmcache_commit_metadata() which upgrades precommitted metadata in cache

No functional change in this patch - just preparation for following change.
2010-01-05 16:06:42 +00:00
Milan Broz
3be5edae0e Move processing of VG locks to separate function (similar to LV locks).
And print some debugging info.

No functional change in this patch.
2010-01-05 16:05:12 +00:00
Milan Broz
1078f24d5a Properly decode flags even for VG locks.
And decode flags in humar readable form in client.
And clean some trailing whitespaces.

No functional change in this patch (only debugging messages changed).
2010-01-05 16:03:37 +00:00
Milan Broz
c02cc5321a Do not set precommitted flag in cache when precommitted metadata does not exist.
The use_precommitted flag indicates, that we want to use precommitted metadata
(used in suspend call to preload table with precommitted data).

But if there are no such data, committed metadata are read but the cache
still contains that precommitted flag.

(The problem is that later possible drop_metadata call will not invalidate
device in cache.)

The wrong precommitted state is stored in on remote nodes during normal
suspend/resume cycle _without_ vg_write/commit.

Use the PRECOMMITTED status flag here instead (which is always set if using
precommited metadata here).
2010-01-05 16:01:22 +00:00
Milan Broz
e60a7ff1d0 Resume volumes in reverse order to preserve memlock pairing.
If renaming snapshot with virtual origin, the origin is renamed too.
But the code must resume LVs in reverse order to properly
pair memlock (in cluster locking).

(The resume of snapshot resumes origin too and later resume
is ignored otherwise.)
2010-01-05 15:58:11 +00:00
Milan Broz
91de7311d7 Fix previous vgcreate commit to not call unpaired unlock. 2009-12-28 18:34:45 +00:00
Milan Broz
e357c9fc0c Explicitly use non-clustered vgcreate in test.
(So the tests can run under cluster locking and do not require
cluster mirror or snapshots.)

Add vgscan before block device readahead change
(flush long running process - clvmd - dev cache.)
2009-12-28 18:33:04 +00:00
Milan Broz
ec4daa5936 Drop metadata cache after device was autorepaired and removed from VG.
All long running processes must reload metadata when some
device becomes orphan after repair.
2009-12-18 12:45:41 +00:00
Milan Broz
2743fb9771 Remove missing flag if PV reappeared and is empty.
When PV device reappears with old metadata, it is
always updated to new version byt atutomatic metadata
repair.

Remove missing flag if device is empty.

If device contains allocated extents, issue warning that
user must remove volumes and re-add this PV before
manipulating with this volume.

This partially solves bug 547842 when one PV (log) is failed,
dmeventd removes that device and later this device reappears and
is wrongly added into VG marked missing.
2009-12-18 12:44:20 +00:00
Petr Rockai
88c4802bdc Revert another unintended change that snuck in. 2009-12-17 15:59:53 +00:00
Petr Rockai
a47e422715 Fix removal of multiple devices from a mirror (+ regression test). 2009-12-17 15:38:29 +00:00
Petr Rockai
3a9ab631e5 Also clean up MISSING devices in --removemissing --force in vgreduce. 2009-12-17 13:54:46 +00:00
Petr Rockai
9ca5118a68 Revert unintended change that slipped in with last checkin. 2009-12-16 19:26:20 +00:00
Petr Rockai
d6053080f8 #define an INTERNAL_ERROR macro and use it throughout LVM. 2009-12-16 19:22:11 +00:00
zkabelac
b1f8076da0 Cleanup returns for void functions. 2009-12-11 13:16:37 +00:00
zkabelac
abc760c8e4 Destroy allocated mempool in _vg_read_orphans() error path. 2009-12-11 13:14:44 +00:00
zkabelac
0331a34d58 Fix unlocking vg in some pvresize and toollib error paths. 2009-12-11 13:11:56 +00:00
zkabelac
98af0ba143 Fix coredump and memory leak for 'dmsetup help -c' 2009-12-11 13:04:30 +00:00
Jonathan Earl Brassow
157810ea3d s/=/==/ Typo was causing sub test to always return success. 2009-12-10 22:06:15 +00:00
Milan Broz
448e4251f8 Call explicitly suspend for temporary mirror layer.
The memlock_inc() fix is wrong, memlock count is not
propagated to long living process (clvmd) and just
it underflow there.
Also suspend is needed to pre-load precommited metadata
on other nodes (remapping to error taget in this case).

With explicit suspend we generate lock request and code
can update memlock count.

(Infinitely "locked" memory caused that fs_unlock() was not
called properly and on cluster nodes remains
old links in /dev/mapper for not active devices.)

(N.B. failing of suspend call here is not handled as fatal
error - the LV is going to be removed later anyway.)
2009-12-09 19:53:39 +00:00
Milan Broz
81ce20d616 Use more descriptive variable name for temporary layer lv. 2009-12-09 19:43:39 +00:00
Milan Broz
3e9ab41e76 Fix missing include. 2009-12-09 19:30:56 +00:00
Milan Broz
a3c8fbc6b6 Allow manipulation with precommited metadata even when a PV is missing.
The new recovery code first tries to repair LV and then removes failed PV
from VG. It means that during operation there can be VG with PV missing,
and vg_read code handles it like not consistent VG.

We already allows returning "inconsistent" commited metadata,
for mirror repair we need this for precommited too.
(The suspend call prepares precommited metadata to inactive table on
other cluster nodes.)

"Inconsistent" here means - correct metadata, just with some metadata areas
not found (obviously on missing or failed PVs).
2009-12-09 19:29:04 +00:00
Milan Broz
e9dc6880af Add memlock information to do_lock_lv debug output.
This helps a lot to detect that something strange happened.
2009-12-09 19:01:27 +00:00
Milan Broz
25fb2c4fb6 Never ever use distributed lock for LV in non-clustered VG.
The LV locks make sense only for clustered LVs.

Properly check cluster flag and never issue cluster lock here.

There are several places in code, where it is already checked, this
patch add this check to all needed calls.

In previous code the lock behaviour was inconsistent,
for example, the pre/post callback can take lock even for local volume,
but deactivate call do not released this lock and it remains held forever.

The local LV lock request now just let run the underlying activation code
on local node, the same process like in local locking.

(Again, this is important for new mirror repair calls, here for local
mirrors but with cluster locking enabled.)
2009-12-09 19:00:16 +00:00
Milan Broz
97d28ae4d7 Allow implicit lock conversion for pre/post callbacks.
This is unnoticed regression from commit 31672ff60e

The pre/post callback need to convert lock always, local node
is going to modify metadata in this case, it it fails conversion,
the call is ignored.

Also it fixes bug when the lock is not yet held, we cannot set LKF_CONVERT
in this case, it will fail because this lock do not exist.

Note that the automatic conversion is still disabled in activate
call, so the original fix (reactivation of exlusive LV) should
be still in place.
2009-12-09 18:55:53 +00:00
Milan Broz
b5bad15dae Allow implicit "convert" to the same lock mode.
(Code already not fail if unlocking not locked resource.)

This is needed in pre/post lock_lv call, where we can
request the same lock on local node becuase of suspend call.
2009-12-09 18:45:12 +00:00
Milan Broz
3098ef4a6e Get rid of magic masks in cluster locking code - clvmd part.
- do_command and lock_vg expect flags (no change here)

Bug fixes:
- lock_vg should check for NONBLOCK on lock_cmd, flags have this bit masked-out

- do_pre/post_command expect do not mask flag at all, this causes that
the code inside is never run! (see following patches, these functions
expect plain command without flags)
2009-12-09 18:42:02 +00:00
Milan Broz
e354b1210e Get rid of magic masks in cluster locking code.
Patch should not cause any problems, only real change is
removing LCK_LOCAL bit from lock type flag, it is never used there.
(LCK_LOCAL is part arg[1] bits anyway.)
2009-12-09 18:28:27 +00:00
Milan Broz
895b6ff719 Get rid of hardcoded 0xffdf cluster lock flag.
There is hidded change - the upper flags (0xffff0000)
and now not cleared, but there are unused anyway.
2009-12-09 18:16:38 +00:00
Milan Broz
0a22655ff3 Remove newly created log volume if initial deactivation fails.
If there is problem deactivate LV and
_init_mirror_log is called with remove_on_failure = 1,
remove the newly created log LV from metadata.

(This can happen if there is active device with the same name
but different UUID.)

The main reason for this "workaround" patch is to
 - do not keep _mlog volume in metadata, so user can repeat the action
 - print better error message describing the real problem

# lvcreate -m 2 -n lv1 -l 1 --nosync vg_bar
  WARNING: New mirror won't be synchronised. Don't read what you didn't write!
  /dev/vg_bar/lv1_mlog: not found: device not cleared
  Aborting. Failed to wipe mirror log.
  Error locking on node bar-01: Input/output error
  Unable to deactivate mirror log LV. Manual intervention required.
  Failed to create mirror log.

# lvcreate -m 2 -n lv1 -l 1 --nosync vg_bar
  WARNING: New mirror won't be synchronised. Don't read what you didn't write!
  Aborting. Unable to deactivate mirror log.
  Failed to initialise mirror log.
2009-12-09 18:09:52 +00:00
Dave Wysochanski
8def378b5e Fix activated/deactivated log_verbose message
I see "Deactivated" message when I activate and "Activated" message when
I deactivate.  The code uses "activate" as boolean but it can be any one
of the enum values from CHANGE_AY, CHANGE_AN, CHANGE_AE, etc.

Signed-off-by: Malahal Naineni <malahal@us.ibm.com>
Acked-by: Dave Wysochanski <dwysocha@redhat.com>
2009-12-07 19:32:28 +00:00
Peter Rajnoha
7ab8b44b6c Disable udev rules on change event with DISK_RO=1.
There's a new change udev event generated since kernel 2.6.32 that
notifies userspace about a change in read-only attribute for block
devices (with DISK_RO=1 environment variable set).

We need to detect this and disable the rule application so the
meaning of this change event is not interchanged with the regular
change event used while resuming/renaming DM devices.

If there's anybody awaiting this notification in foreign rules,
he can still check for this env var and do the appropriate actions
separately.
2009-12-07 12:03:47 +00:00
Dave Wysochanski
335fe09d70 Update a few more uint64_t's related to the 64-bit status change.
At this point they probably do not matter but going forward they
may - depends on future patches for replicator, etc.  I think
these probably got missed because they were 'flags' so I changed
the name to 'status' to be consistent.  So the on-disk
things 'flags' and the in structure 'status' (bits).
NOTE: WHATS_NEW already has entry for this in current release.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Acked-by: Mike Snitzer <snitzer@redhat.com>
2009-12-04 17:48:32 +00:00
Peter Rajnoha
523a7ed7d3 WHATS_NEW for previous commit. 2009-12-04 14:26:22 +00:00
Peter Rajnoha
f69e8e3606 Give better message for pvmove when all data on source PV is skipped. 2009-12-04 14:03:18 +00:00
Milan Broz
3516797b49 Fix memory lock imbalance in lv_suspend if already suspended.
pvmove suspends all moved LVs + pvmoveX mirrored LV itself.

This suspends even underlying pvmoveX and following explicit
suspend call is just noop.

But in resume the pvmoveX volume is no longer underlying
device for moved LVs, so it performs full resume with memlock
decrease.

Code must call memlock_inc() if suspend is requested, volume
is already suspended and error is not requested.
2009-12-03 19:23:40 +00:00
Milan Broz
1683e94f0c Fix pvmove test mode to not fail and do not poll.
Test mode should not fail nor try to poll non-existent devices.
2009-12-03 19:22:24 +00:00
Milan Broz
1d249195a4 Print error if VG already exist.
This test have to be moved because of new vg read error handling.
2009-12-03 19:20:48 +00:00
Milan Broz
2f7ee08288 Fix tools to report error when stopped by user.
(And do not produce internal error message.)
2009-12-03 19:18:33 +00:00
zkabelac
e0772fb301 minor indent change 2009-12-03 10:01:30 +00:00
zkabelac
78bdbce2fd skip cast from (void*) 2009-12-03 09:59:54 +00:00
zkabelac
5a5fed28fa minor whitespace indentation 2009-12-03 09:58:30 +00:00
Dave Wysochanski
5818b6efb8 Add tests to check for readahead value in lvcreate. 2009-12-03 01:48:05 +00:00
Dave Wysochanski
53a66492e8 Fix setting of readahead in lvcreate.
The default comes from the configuration settings, with possible
commandline override.
2009-12-03 01:47:33 +00:00
Milan Broz
b17ddc26c0 Fix memory leak in lv_info_by_lvid
The lv_from_lvid calls internally vg_read(),
we must release vg structure afterwards.

Code is called only from clvmd.
2009-12-01 19:10:23 +00:00
Petr Rockai
b7e19d2fe3 If aborting due to an internal error, always print the message causing this. 2009-12-01 13:54:27 +00:00
Petr Rockai
d8130a99b4 Optionally abort on internal errors (and leverage this option in the
testsuite). (This is showing a problem in the pvmove test for me, so I expect
the tests to start failing -- this needs to be fixed separately though.)
2009-11-30 17:17:11 +00:00
Petr Rockai
8c654aeebe The sourcedir instances of the test scripts are not PHONY. 2009-11-30 16:58:53 +00:00
Petr Rockai
bad318d451 Don't fail in the builddir == srcdir case, though. (testsuite) 2009-11-30 16:56:42 +00:00
Petr Rockai
11d2997e44 Fix test/api to work with srcdir != builddir. 2009-11-30 15:12:34 +00:00
Petr Rockai
2d75d2e76e More fixes for the testsuite in the $(builddir) != $(srcdir) situation. 2009-11-30 14:59:26 +00:00
Milan Broz
6074f58641 Do not allow creating mirrors of more than 8 images.
This is kernel limitation in all kernel versions,
so better detect this early.
2009-11-27 14:35:38 +00:00
Milan Broz
48de09c279 Use locking_type 3 (compiled in cluster locking) in lvmconf. 2009-11-27 14:32:16 +00:00
Dave Wysochanski
032c2cb462 Remove unnecessary / duplicate dm_list macros and functions.
These are no longer used by anyone.  The dm_list defines are all in
libdevmapper.h and libdm/datastruct/list.c contains any function definitions.
There is some code in "old-tests" that still use this but this code is not
being maintained.

Thanks to Zdenek for spotting this.
2009-11-25 20:44:07 +00:00
Alasdair Kergon
2008367883 Log failure type and recognise type 'F' (flush) in dmeventd mirror plugin. 2009-11-25 15:59:07 +00:00
Mike Snitzer
165d88cfd8 Switch status from 32-bit to 64-bit
The physical_volume, volume_group, logical_volume and lv_segment
structures' 'status' member is now uint64_t.

The alignment of these structures was also audited to remove holes.  The
movement of some members in 'volume_group' and 'lv_segment' eliminates
holes.  The 'physical_volume' structure still has one 4-byte hole after
'pe_size'; the other structures no longer have any holes.  Each
structures' size has not changed.
2009-11-24 22:55:55 +00:00
Alasdair Kergon
0c0e1fbbeb Post-release.
Fingers crossed this one's more successful that the last one!
2009-11-24 19:04:23 +00:00
Alasdair Kergon
3559e20dab . 2009-11-24 18:54:23 +00:00
Alasdair Kergon
e400f6eab9 pre-release 2009-11-24 18:26:08 +00:00
Milan Broz
cffffe0c2e Add missing vg_release to pvs and pvdisplay to fix memory leak. 2009-11-24 17:07:09 +00:00
Milan Broz
70fcdb495a Do not try to unlock VG which is not locked.
If the vg_read() returned error, no lock was taken,
so always call vg_release().

Otherwise this can happen because of missing FAILED_*:

# vgchange -a y x --ignorelockingfailure
  Volume group "x" not found
  Internal error: Attempt to unlock unlocked VG x
2009-11-24 16:13:02 +00:00
Milan Broz
c1b2049df9 Move persistent filter dump to more appropriate place.
After context_refresh is cache empty, the cache flush
does nothing.

Call it after lvmcache full rescan if running from
log lived process.
2009-11-24 16:11:37 +00:00
Milan Broz
f6cabc78c0 Refresh device filters before full device rescan in lvmcache.
The sysfs filter initialise hash of available devices using
scan of /sys/block. We need to refresh even this hash
when performing full scan otherwise the newly appeared
device could be rejected, because there is no entry
in sysfs filter.

This easily could happen when attaching new device
to cluster node. (Only force refresh of context
in clvmd -R works here now).

Unfortunately consequences of this are much worse,
missing device part on that node is replaced with missing segment
(even when no partial arg is selected) and this directly
lead to data corruption.

See https://bugzilla.redhat.com/show_bug.cgi?id=538515

Simply fix it by refreshing device filters in lvmcache
before performing the full device scan.
2009-11-24 16:10:25 +00:00
Milan Broz
b8526452b5 Return error status if vgchange fails to activate some volume.
(on one node a storage connection failed):

# vgchange -a y vg_bar ; echo $?
  Error locking on node bar-02: Refusing activation of partial LV lv1. Use --partial to override.
    1 logical volume(s) in volume group "vg_bar" now active
    0

So activation fails on one node, error is correctly printed but
status code is wrong.

This patch fixes the top level (vgchange) to return proper code
(and print # of activated LVs).

(lvchange returns error properly here.)
2009-11-24 16:08:49 +00:00
Milan Broz
a1cefb3e17 Fix memory lock imbalance in locking code.
(This affects only cluster locking because only cluster
locking module set LCK_PRE_MEMLOCK.)

With currect code you get
# vgchange -a n
  Internal error: _memlock_count has dropped below 0.
when using cluster locking.

It is caused by _unlock_memory calls here

  if ((flags & (LCK_SCOPE_MASK | LCK_TYPE_MASK)) == LCK_LV_RESUME)
     memlock_dec();

Unfortunately it is also (wrongly) called in immediate unlock
(when LCK_HOLD is not set) from lock_vol
(LCK_UNLOCK is misinterpreted as LCK_LV_RESUME).

Avoid this by comparing original flags and provide memlock
code type of operation (suspend/resume).
2009-11-23 10:55:14 +00:00
Milan Broz
def0f38f3d Revert vg_read_internal change, clvmd cannot use vg_read now. (2.02.55) 2009-11-23 10:44:50 +00:00
Alasdair Kergon
58a8b00086 post-release 2009-11-19 19:53:58 +00:00
Alasdair Kergon
50a27398b0 . 2009-11-19 19:42:57 +00:00
Alasdair Kergon
eab7cba1f3 pre-release 2009-11-19 19:00:34 +00:00
Petr Rockai
83774ba6ae Add a basic test for snapshots of mirrors, thanks to Jon Brassow. 2009-11-19 13:55:40 +00:00
Petr Rockai
ab700b4ea3 In case we refuse to continue due to missing PVs, print a hint about using
vgreduce --removemissing to remedy the situation.
2009-11-19 13:44:37 +00:00
Petr Rockai
bf7936d494 The double resume in remove_mirror_images does not happen *always*. Only call
memlock_inc() when it actually does happen.
2009-11-19 13:42:38 +00:00
Petr Rockai
14f627329d Un-export vg_read_internal. 2009-11-19 12:13:37 +00:00
Petr Rockai
829c996611 Add a missing #include (fix compiler warning). 2009-11-19 12:09:53 +00:00
Petr Rockai
dff2e8ecb4 Fix the dmeventd LD_LIBRARY_PATH in the testsuite. 2009-11-19 12:01:39 +00:00
Petr Rockai
7c79b1c7c5 What's new. 2009-11-19 01:17:01 +00:00
Petr Rockai
a390fac356 Fix another bug in memlock handling, this time the "global" dmeventd memlock
was preventing device scans in lvconvert --repair running from inside dmeventd.
2009-11-19 01:11:57 +00:00
Petr Rockai
9a43e67347 Add an extra memlock_inc() to _remove_mirror_images to properly balance
reference counting (see code comment for details).
2009-11-18 18:23:46 +00:00
Petr Rockai
b0d08c572a Issue an Internal error message whenever _memlock_count drops below 0. 2009-11-18 18:22:32 +00:00
Milan Broz
ee4eb0aa6f Never activate hidden volumes directly in vgchange.
All hidden (not visible) volumes should be activated through
other visible volumes.

(There are already exceptions like snapshot, mirror log and image,
which should be cleaned one day...)

This solves problems for future types of hidden volumes,
which can have special meaning and must not be activated implicitly
(e.g. key store volume).
2009-11-18 17:20:18 +00:00
Milan Broz
07e27cac02 Fix pvmove region_size overflow for very large PVs.
Fixes problem reported in
https://www.redhat.com/archives/dm-devel/2009-November/msg00104.html

The region size multiplication can overflow when using 32bit integer.
2009-11-18 16:48:10 +00:00
Milan Broz
cdc905cc16 Fix install_device-mapper Makefile target to not build dmeventd plugins. 2009-11-13 12:48:01 +00:00
Peter Rajnoha
88b0c82a0d Support udev flags even when udev_sync is disabled or not compiled in.
This provides better support for environments where udev rules are installed
but udev_sync is not compiled in (however, using udev_sync is highly
recommended). It also provides consistent and expected functionality even
when '--noudevsync' option is used.

There is still requirement for kernel >= 2.6.31 for the flags to work though
(it uses DM cookies to pass the flags into the kernel and set them in udev
event environment that we can read in udev rules).
2009-11-13 12:43:21 +00:00
Peter Rajnoha
01d3349587 Remove 'last_rule' from udev rules.
'last_rule' option has been removed from udev (version >= 147).

From now on, we require foreign rules to check and honor
ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG} instead. Foreign
rules should be skipped totally when this flag is set.
2009-11-13 12:33:27 +00:00
Alasdair Kergon
cf7f096db7 . 2009-11-06 01:40:59 +00:00
Alasdair Kergon
21ed352ac5 Add support for querying a device's inactive table.
Currently this data is invisible to userspace.
Requires dm >= 4.16 (likely to be in linux 2.6.33).
2009-11-06 00:43:08 +00:00
Milan Broz
f8a4f79277 Fix compilation warning:
activate/dev_manager.c:362: warning: combined_percent_range may be used uninitialized in this function
2009-11-04 14:56:35 +00:00
Milan Broz
16d385ac6a Fix lvcreate processing of %PVS argument.
- fix missing unlocking of VG
lvcreate -l 100%PVS -n lv1 vg_test
  Please specify physical volume(s) with %PVS
  Internal error: Volume Group vg_test was not unlocked

- if no PVS specified, use all available

Fix segfault if %PVS in lvresize without PVs list.
2009-11-04 14:47:27 +00:00
zkabelac
3dc1945b44 minor code comment update 2009-11-04 12:39:56 +00:00
Dave Wysochanski
3c7db9e986 Remove old, and now incorrect, vgextend man page description of pvcreate options. 2009-11-03 15:58:02 +00:00
Alasdair Kergon
44e1f095d1 Tidy some uses of arg_count and introduce arg_is_set. 2009-11-03 15:50:42 +00:00
zkabelac
90c39b8371 Update for outnl and indent functions 2009-11-03 11:17:46 +00:00
zkabelac
17b7944ac2 Export functions out_inc_indent(), out_dec_indent() for creating
indented metadata lines.

Macro outnl() is using exported out_newline() instead of direct
call f->fn(), that required the visibility of the internal
struct formatter.
2009-11-03 11:00:46 +00:00
zkabelac
bbf486f890 Add fflush for the case the log is redirected to the buffered file.
Without this patch it have not been obvious, why the application
waits on the stdin as the prompt might be still buffered in memory.
2009-11-03 10:50:57 +00:00
Alasdair Kergon
20faa956a8 Fix hash lookup segfault when keys compared are different lengths. 2009-11-03 00:45:35 +00:00
Petr Rockai
74a4e04185 Rudimentary support for running testsuite in a builddir != srcdir situation. 2009-11-02 15:16:21 +00:00
Dave Wysochanski
b102455b57 Rename validate_vg_create_params to vgcreate_params_validate. 2009-11-01 20:05:17 +00:00
Dave Wysochanski
c2235a0baa Rename fill_vg_create_params to vgcreate_params_set_from_args.
Rename fill_vg_create_params to vgcreate_params_set_from_args and remove
vg_name parameter from function (caller must set before calling function).
2009-11-01 20:03:24 +00:00
Dave Wysochanski
c36d2b02a3 Add vgcreate_params_set_defaults().
Add function to set default vgcreate parameters based on existing VG or
internal defaults.  Should be no functional change.
2009-11-01 20:02:32 +00:00
Dave Wysochanski
4eb8d86346 Rename pvcreate_params processing functions to better match <object><action>.
Rename fill_default_pvcreate_params to pvcreate_params_set_defaults.
Rename pvcreate_validate_restore_params to pvcreate_restore_params_validate.
Rename pvcreate_validate_params to pvcreate_params_validate.
2009-11-01 19:51:54 +00:00
Peter Rajnoha
1b33fbf98b More cleanup in udev rules:
- add copyright notice for 10-dm.rules.in,

 - set DM_UDEV_DISABLE_{DISK, OTHER}_RULES_FLAG in 11-dm-lvm.rules directly
   for inappropriate and non-top-level subdevices in case we use older kernels
   where DM_COOKIE is not used (and therefore there are no flags passed from
   the LVM process itself). This applies for older kernels (version < 2.6.31),

 - remove unnecessary filters in 95-dm-notify.rules - the DM_COOKIE env var
   itself is set for change/remove udev events and for DM devices only so
   there's no need to double-check this.
2009-11-01 18:01:31 +00:00
Dave Wysochanski
3f74391b87 Update vgsplit to call vg_set_clustered(). 2009-10-31 17:43:57 +00:00
Dave Wysochanski
93c954dae1 Update vgcreate to call vg_set_clustered(). 2009-10-31 17:39:22 +00:00
Dave Wysochanski
f736563a7a Add vg_set_clustered() - move logic from vgchange.
Similar to other vg_set_* functions, we create a vg_set_clustered() function
which does a few checks and sets a flag.  This is where we check for
any limitations of clusters.
2009-10-31 17:30:52 +00:00
Dave Wysochanski
0350c4f0f6 Add vg_mda_count library function. 2009-10-31 17:26:13 +00:00
Dave Wysochanski
0c0caf0272 Add to vgcreate and vgextend nightly tests. 2009-10-31 16:43:07 +00:00
Alasdair Kergon
9abd966a80 Insert some missing stack macros into activation code. 2009-10-30 13:07:49 +00:00
Milan Broz
a1dbd7156c Recognise DRBD device part and handle it similar to MD devices.
The DRBD uses underlying device so code should prefer top
device if duplicate is found.

Patch also introduce
        dev_subsystem_part_major and dev_subsytem_name
functions to easily handle all these replication susbystems
and not hardcode md_major call.

See https://bugzilla.redhat.com/show_bug.cgi?id=530881
for full problem description.
2009-10-27 17:00:44 +00:00
Alasdair Kergon
b74e5b870c post-release 2009-10-27 01:13:20 +00:00
Alasdair Kergon
bcb021296f . 2009-10-27 00:52:45 +00:00
Alasdair Kergon
dcf907f36d add copyright lines 2009-10-26 22:42:07 +00:00
Alasdair Kergon
972b11e39e pre-release 2009-10-26 21:56:23 +00:00
Peter Rajnoha
10fffe842b Cleanup of previous commit with latest changes in udev support code. 2009-10-26 21:38:35 +00:00
Dave Wysochanski
963cf98df1 Document --all option in man pages, cleanup {pv|vg|lv}{s|display} man pages.
Option --all is only partially documented currently, so document in all
commands.  Also make {pv|vg|lv}{display|s} man pages consistent with help
output.  Remove ununsed 'disk_ARG' parameter.  Leave --trustcache out of
the man page output.  Update --units argument to show all possible units.
2009-10-26 14:37:09 +00:00
Peter Rajnoha
0f64ddf2fb Several changes to udev support code:
- we have these levels when the udev rules are processed:
   10-dm.rules --> [11-dm-<subsystem>.rules] --> [12-dm-permissions.rules] -->
   13-dm-disk.rules --> [...all the other foreign rules...] --> 95-dm-notify.rules

 - each level can be disabled now by
   DM_UDEV_DISABLE_{DM, SUBSYSTEM, DISK, OTHER}_RULES_FLAG

 - add DM_UDEV_DISABLE_DM_RULES_FLAG to disable 10-dm.rules

 - add DM_UDEV_DISABLE_OTHER_RULES_FLAG to disable all the other (non-dm) rules.
   We cutoff these rules by using the 'last_rule', so this one should really be
   used with great care and in well-founded situations. We use this for lvm's
   hidden and layer devices now.

 - add a parameter for add_dev_node, rm_dev_node and rename_dev_node so it's
   possible to switch on/off udev checks

 - use DM_UDEV_DISABLE_DM_RULES_FLAG and DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG
   if there's no cookie set and we have resume, remove and rename ioctl.
   This could happen when someone uses the libdevmapper that is compiled with
   udev_sync but the software does not make use of it. This way we can switch
   off the rules and fallback to libdevmapper node creation so there's no
   udev/libdevmapper race.
2009-10-26 14:29:33 +00:00
Peter Rajnoha
3fa82818b9 Rename 11-lvm.rules to 11-dm-lvm.rules and 12-dm-disk.rules to 13-dm-disk.rules. 2009-10-26 14:04:31 +00:00
Dave Wysochanski
c48ba4464c Update lvcreate/lvconvert man pages to explain PhysicalVolume parameter.
Addresses rhbz 500177.
2009-10-26 13:41:13 +00:00
Alasdair Kergon
2d1118a26f Permit snapshots of mirrors. (brassow) 2009-10-26 10:01:56 +00:00
Dave Wysochanski
53560b8e0b Minor fix to vgcreate/vgextend man pages for PHYSICAL DEVICE OPTIONS. 2009-10-26 02:36:29 +00:00
Alasdair Kergon
3f647cdf32 Cleanup mimagetmp LV if allocation fails for new lvconvert mimage. 2009-10-23 01:24:17 +00:00
Alasdair Kergon
9a0dc6d522 Fix clvmd segfault when refresh_toolcontext fails. (brassow, bz 506986) 2009-10-22 17:45:23 +00:00
Alasdair Kergon
c819525e81 Remember to clear 'global lock held during cache refresh' state after use. 2009-10-22 17:33:09 +00:00
Peter Rajnoha
4024ad5eb2 Add manpage entry for dmsetup udevflags. 2009-10-22 13:12:20 +00:00
Peter Rajnoha
2c0df9552f Use udev flags in the rules and cleanup the rules:
- remove default permissions set in 95-dm-notify.rules (and add a hint in 12-dm-permissions.rules to set it by the user directly)
 - add multipath DM_ACTION=="PATH_FAILED" filter
 - remove unnecessary filters in the headers of the rules (we can simply use DM_UDEV_RULES_VSN instead)
 - fix symlink priorities in /dev/disk/ (snapshot volumes have low priority for FS UUID symlinks so it will not overwrite symlinks for the origin)
2009-10-22 13:11:33 +00:00
Peter Rajnoha
9359586fde Use udev flags support in LVM and provide dm_tree_add_new_dev_with_udev_flags wrapper for dm_tree_add_new_dev. 2009-10-22 13:00:07 +00:00
Peter Rajnoha
68069c70e1 Add udev flags support in libdevmapper and provide 'dmsetup udevflags' command to decode them. 2009-10-22 12:55:47 +00:00
Alasdair Kergon
6a00ceeb66 . 2009-10-22 11:25:46 +00:00
Petr Rockai
8143f55488 Only announce mirror monitoring to syslog after initialisation succeeds. 2009-10-22 10:40:41 +00:00
Petr Rockai
03e03fb7a1 Fix the "const discarded" warnings introduced in the unknown segment patch. 2009-10-22 10:38:07 +00:00
Jonathan Earl Brassow
b13b8c1882 Clarify message:
"  Mirror status: 1/2 images failed."

Half of an image?  Half of the images?  No, 1 of 2 images.
2009-10-21 22:19:39 +00:00
Petr Rockai
02a2afb64f Handle metadata with unknown segment types more gracefully. 2009-10-16 17:41:49 +00:00
Jonathan Earl Brassow
ae8e907d72 I saw this in a bug report:
[root@xxxx-01 ~]# lvconvert -m 1 --corelog VG/cmirror
  Unable to convert the log of inactive cluster mirror cmirror

I've tried to clean-up the message a little more, so the name
of the mirror stands out more while preserving the sense that
it's not a problem with the specific device, but the fact that
it is inactive that is causing the problem.

New msg:
  Unable to convert the log of an inactive cluster mirror, cmirror
2009-10-14 14:55:44 +00:00
fabbione
f042834068 configure.in: don't set default file owner and group
Per discussion on lvm-devel mailing list and part of debian patch set,
don't set defaults for owner and group, since nobody seems to use them, and
still allow override.
2009-10-14 04:10:41 +00:00
Alasdair Kergon
63130374b9 Attempt to build dmeventd.static. 2009-10-13 02:35:26 +00:00
Alasdair Kergon
ac01d56747 More build cleanups (linker parameter ordering). 2009-10-13 01:31:10 +00:00
fabbione
6f751afae4 Disable realtime support by default.
This code is used only in a under development feature and it's not used
anywhere in the tree.

Allow to build it conditionally.
2009-10-12 16:59:20 +00:00
Christine Caulfield
8fd85fb6e6 Make clvmd return 0 on success rather than 1. 2009-10-12 08:33:30 +00:00
fabbione
1dbfe1e856 Merge Debian patch 05 debian: keep libdm-abi consistent.
This appears to be the only user visible feature that can change libdm ABI
at build time.

Thanks to Bastian Blank for the patch.
2009-10-12 04:06:42 +00:00
Alasdair Kergon
d3fd4c0381 Extra libs must be appended, not defined first. 2009-10-09 16:04:54 +00:00
Alasdair Kergon
0e20e05795 linking parms missing from o->so conversion. 2009-10-09 15:55:31 +00:00
Dave Wysochanski
3bb0dc03af Cleanup comment and some whitespace. 2009-10-06 16:00:38 +00:00
Dave Wysochanski
4257485ff2 Add --pvmetadatacopies as a synonym for --metadatacopies in various commands.
Going forward, we would like to allow users to specify the total
number of metadatacopies in a VG rather than on a per-PV basis.  In
order to facilitate that, introduce --pvmetadatacopes to replace
--metadatacopies everywhere.  We still allow --metadatacopies for
pv commands, but require --pvmetadatacopies for vg commands.
Eventually we will introduce --vgmetadatacopies.  Once we do that,
we should either deprecate --metadatacopies or make it a synonym based
on the command (pvmetadatacopies for pv commands, and vgmetadatacopies
for vg commands).  The latter option would likely just require a simple
'strncpy' check against cmd->command->name to qualify the merge_synonym
call.

Update nightly tests to cover the pvmetadatacopies synonym.

Note that this patch is the result of an eariler review comment for
the implicit pvcreate patches.  Should apply cleanly on top of the
implicit pvcreate patches (I applied after patch 10/10 in that series).

NOTE: This patch will require --pvmetadatacopies for vgconvert as
--metadatacopies is no longer accepted.
2009-10-05 20:55:56 +00:00
Dave Wysochanski
f69b7a58f2 Add --pvmetadatacopies as a synonym for --metadatacopies in various commands.
Going forward, we would like to allow users to specify the total
number of metadatacopies in a VG rather than on a per-PV basis.  In
order to facilitate that, introduce --pvmetadatacopes to replace
--metadatacopies everywhere.  We still allow --metadatacopies for
pv commands, but require --pvmetadatacopies for vg commands.
Eventually we will introduce --vgmetadatacopies.  Once we do that,
we should either deprecate --metadatacopies or make it a synonym based
on the command (pvmetadatacopies for pv commands, and vgmetadatacopies
for vg commands).  The latter option would likely just require a simple
'strncpy' check against cmd->command->name to qualify the merge_synonym
call.

Update nightly tests to cover the pvmetadatacopies synonym.

Note that this patch is the result of an eariler review comment for
the implicit pvcreate patches.  Should apply cleanly on top of the
implicit pvcreate patches (I applied after patch 10/10 in that series).

NOTE: This patch will require --pvmetadatacopies for vgconvert as
--metadatacopies is no longer accepted.
2009-10-05 20:53:41 +00:00
Dave Wysochanski
fd4fe42013 Update help messages for vgextend / vgcreate to mention PHYSICAL DEVICE OPTIONS. 2009-10-05 20:22:58 +00:00
Dave Wysochanski
930820b738 Add implicit tests for implicit pvcreate during vgcreate and vgextend.
Update tests and WHATS_NEW for implicit pvcreate support.
2009-10-05 20:04:40 +00:00
Dave Wysochanski
06cc081ca2 Update vgcreate and vgextend man pages to clarify implicit pvcreate.
vgcreate and vgextend now implicitly call pvcreate on devices not
currently initialized for LVM use.  Previously these commands would
fail with an error, so clarify the new behavior in the man page.
2009-10-05 20:04:21 +00:00
Dave Wysochanski
ee9bf16d1a Add implicit pvcreate support to vgcreate and vgextend.
Adds implicit pvcreate support when calling vgcreate or vgextend with
device paths that are not yet PVs.  This changes the behavior of vgcreate
and vgextend from failing with an error message to implicitly pvcreating.
2009-10-05 20:04:08 +00:00
Dave Wysochanski
f08e65fd04 Move pvcreate_validate_params into toollib to allow calling from mutiple tools.
For implicit pvcreate support, we need to call this from vgcreate and vgextend,
so move it into toollib.
2009-10-05 20:03:54 +00:00
Dave Wysochanski
877de45d6e Refactor vgcreate/vgextend validation of vgname/pvname(s).
Decrement argc and increment argv in a consistent way to allow for later
code-sharing.  Should be no functional change.
2009-10-05 20:03:37 +00:00
Dave Wysochanski
5a4813d336 Refactor pvcreate - split pvcreate_validate_params into recovery/non-recovery.
Split pvcreate_validate_params into recovery and non-recovery parameters.
This is necessary so we can call the non-recovery validate function from
vgextend / vgcreate.  Note in the pvcreate tool case, we must call the
recovery validation function first (see treatment of pe_start and --zero),
and that we add a call to fill_default_pvcreate_params before the validation
functions.
2009-10-05 20:03:25 +00:00
Dave Wysochanski
6dc818deb1 Allow calling fill_default_pvcreate_params from tools.
We need defaults for pvcreate_params at a higher level - this will
allow us to use a common function from the tools to take defaults,
then fill in any non-defaults from the commandline.

Future patches will refactor vgcreate/vgextend to call this function
if one or more pvcreate parameters are given on the commandline.
2009-10-05 20:03:08 +00:00
Dave Wysochanski
4b2bf06873 Add pvcreate_params to vg_extend.
Another refactoring for implicit pvcreate support.  We need to get
the pvcreate parameters somehow to the vg_extend routine.  Options
seemed to be:
1. Attach the parameters to struct volume_group.  I personally
did not like this idea in most cases, though one could make an
agrument why it might be ok at least for some of the parameters
(e.g. metadatacopies).
2. Pass them in to the extend routine.  This second route seemed
to be the best approach given the constraints.

Future patches will parse the command line and fill in the actual
values for the pvcreate_single call.
Should be no functional change.
2009-10-05 20:02:48 +00:00
Dave Wysochanski
839af3e90e Add pvcreate_params to vg_extend_single_pv.
Should be no functional change.  If this parameter is set to NULL, just fail
the extend if the device is not already a PV.  If non-NULL, try pvcreate_single
before failing.  Note that pvcreate_single() handles the log_error in case
of failure so we just return 0 if pvcreate_single() fails.
2009-10-05 20:02:30 +00:00
Dave Wysochanski
c059cdd0f2 Refactor vg_extend - add vg_extend_single_pv.
Simple refactor to setup future changes related to implicit pvcreates.
Should be no functional change.
2009-10-05 20:02:04 +00:00
Alasdair Kergon
0ba837e163 More makefile cleaning up and fixing. (gentoo) 2009-10-05 13:46:00 +00:00
Alasdair Kergon
1ddcf370a7 Correct example.conf to indicate that lvm2 not lvm1 is the default format.
Remove an unused stray LVM1_SUPPORT ifdef.
2009-10-05 12:44:20 +00:00
Alasdair Kergon
e0559e4fda Only include selinux libs in libdevmapper.pc when selinux build enabled. 2009-10-05 12:11:30 +00:00
Alasdair Kergon
eeefbfd38d Allow for a build directory separate from the source. 2009-10-02 19:10:31 +00:00
Zdeněk Kabeláč
60ba4943ec Update distclean target for rename clogd to cmirrord. (2.02.52) 2009-10-02 11:41:54 +00:00
Zdeněk Kabeláč
ba4ac17425 Remove daemons/clogd from distclean dirs (replaced with cmirrord) 2009-10-02 11:35:25 +00:00
Zdeněk Kabeláč
3965d3ba83 Run distclean also for daemons/cmirrord 2009-10-02 09:47:11 +00:00
Christine Caulfield
3435f24770 Add LCK_CONVERT flag I missed on the last checkin. 2009-10-01 14:15:34 +00:00
Christine Caulfield
31672ff60e Stop clvmd from automatically doing lock conversions. Now, if a lock
is granted at one mode and an attempt to convert it wthout the LCK_CONVERT
flag set then it will return errno=EBUSY.

This fixes a pretty bad bug in which an LV could be activated exclusively on
one node and lvchange -ay on another would convert it to shared!

It might break some things in other areas, but I doubt it.
2009-10-01 14:14:17 +00:00
Alasdair Kergon
6e619f8927 Add percent_range to copy_percent too. 2009-10-01 01:04:27 +00:00
Alasdair Kergon
2ccdb165e3 Introduce percent_range_t and centralise snapshot full/mirror in-sync checks. 2009-10-01 00:35:29 +00:00
Alasdair Kergon
db8eab04e3 Make poll_mirror_progress a function that can be replaced. 2009-09-30 18:15:06 +00:00
Alasdair Kergon
4e2e8954dc Factor out poll_mirror_progress and introduce progress_t. 2009-09-30 17:43:51 +00:00
Dave Wysochanski
a25fe81b9e Update nightly tests to deal with unit changes.
Now uppercase letters imply Si units, so use lowercase everywhere.
We could stay with uppercase, but then we'd have to deal with rounding, etc.
Also, some output / error messages change slightly (instead of "GB" we're
now saying "GiB").
One test enhancement might be to add some new tests for the units changes
but for now let's just get the test back to passing.
2009-09-30 16:13:53 +00:00
Alasdair Kergon
bce3ac2c73 Distinguish between powers of 1000 and powers of 1024 in unit suffixes. 2009-09-30 14:19:00 +00:00
Peter Rajnoha
52b70fbbfa Just a cleanup from previous commit. We don't need pvname local var in _activate_lvs_in_vg anymore... 2009-09-30 12:05:25 +00:00
Alasdair Kergon
08b540dd78 look up pvmove by pvmove LV when PVMOVE flag is set 2009-09-29 20:33:49 +00:00
Alasdair Kergon
22e91979bb Don't attempt to restart pvmoves when deactivating LVs in vgchange.
Restart lvconverts in vgchange by sharing lv_spawn_background_polling.
2009-09-29 20:22:35 +00:00
Alasdair Kergon
e3730ecfc3 Generalise polldaemon code by changing mirror-specific variable names. 2009-09-29 19:35:26 +00:00
Alasdair Kergon
9cfc9b3ee2 Don't attempt to deactivate an LV if any of its snapshots are in use. 2009-09-29 18:50:28 +00:00
Milan Broz
c0ff3805c8 Return fail if lv_deactivate did not removed device from kernel.
lv_deactivate now returns always success, because tree deactivation
functions (see dm_tree_deactivate_children) always returns success.

Because code should return failure in lv_deactivate at least,
fix it by checking for device existence after real deactivation call.

(After discussion this was prefered solution to dm tree function rewrite
which affects snapshots and mirrors.)
2009-09-29 15:17:54 +00:00
Dave Wysochanski
49ebd19ab1 Trivial cleanup to lvcreate man page - use virtualsize in example.
virtualsize replaced virtualoriginsize but the example was never updated.
2009-09-29 15:11:06 +00:00
Alasdair Kergon
79bcc98e9b Provide alternative implementation of obsolete siginterrupt(). 2009-09-28 21:23:02 +00:00
Alasdair Kergon
a58980fe82 Consolidate LV allocation into alloc_lv(). 2009-09-28 17:46:15 +00:00
Alasdair Kergon
fe67a86a5f Treat input units of both 's' and 'S' as 512-byte sectors. (2.02.49)
's' and 'S' are special suffixes representing sectors and are always 512 bytes,
regardless of whether you're using powers of 1000 or 1024.
2009-09-28 16:36:03 +00:00
Alasdair Kergon
4d85bb13d1 Add global/si_unit_consistency to enable cleaned-up use of units in output.
Add configure --enable-units-compat to set si_unit_consistency off by default.

Use standard output units for 'PE Size' and 'Stripe size' in pv/lvdisplay.
2009-09-28 16:23:44 +00:00
Alasdair Kergon
0501c06745 post-release 2009-09-26 00:42:47 +00:00
Alasdair Kergon
abb2e6ea9b Fix log fn prototype. 2009-09-26 00:29:13 +00:00
Alasdair Kergon
a99a30d720 missing dm_snprintf 2009-09-25 19:06:05 +00:00
Alasdair Kergon
0670c8f60f pre-release 2009-09-25 18:30:27 +00:00
Alasdair Kergon
dfdcb92f3d pre-release 2009-09-25 18:30:26 +00:00
Alasdair Kergon
bc9b5706e9 ensure dm_strdup succeeds 2009-09-25 18:19:09 +00:00
Alasdair Kergon
64c37a20d1 remove unused var & rename fn 2009-09-25 18:13:17 +00:00
Alasdair Kergon
6d2d4f72ac Handle any path supplied to dm_task_set_name() by looking up in /dev/mapper. 2009-09-25 18:08:04 +00:00
Peter Rajnoha
4c151970e6 Use the same default umask for /dev dirs (DM_DEV_DIR_UMASK). 2009-09-25 11:58:00 +00:00
Peter Rajnoha
e65e815aae Add more hints in 12-dm-permissions.rules. Add 'dmsetup splitname' and 'y|--yes' to dmsetup manpage. 2009-09-23 12:52:52 +00:00
Jonathan Earl Brassow
db3fb23de4 '_emit_areas_line' returns 1 for success and 0 for failure. This always
confuses me, so I've added a comment at the top of the function to
remind me of this.

I also found that 'mirror_emit_segment_line' was returning 0 (return_0)
on failure /and/ success.  It now returns 1 for success and 0 for failure -
just like '_emit_areas_line' and its calling function, '_emit_segment_line'.
2009-09-22 16:26:59 +00:00
Zdeněk Kabeláč
5c9adc4052 Minor replace of of ${top_srcdir} with $(top_srcdir) for lcov target 2009-09-22 13:32:39 +00:00
Peter Rajnoha
b8c8c29ee4 Add some advisory comments for users in 12-dm-permissions.rules. 2009-09-22 12:03:32 +00:00
Alasdair Kergon
47c0c71e19 Fix dmeventd _temporary_log_fn parameters. (2.02.50) 2009-09-17 10:37:23 +00:00
Alasdair Kergon
7d26a86071 Enable dmeventd monitoring section of config file by default. 2009-09-16 23:48:41 +00:00
Alasdair Kergon
556d880951 drop -ing suffix 2009-09-16 23:40:19 +00:00
Alasdair Kergon
4ee50ed6de Update lvm2_monitoring script. 2009-09-16 23:22:40 +00:00
Dave Wysochanski
b1b5a9d8fa Fix lvm2app test to run under test/api subdirectory only when configured. 2009-09-15 19:59:04 +00:00
Dave Wysochanski
62d8848bee Add vg_is_resizeable() and cleanup references.
Clean up VG_RESIZEABLE flag by creating vg_is_resizeable().
Update comment - we no longer have ALLOW_RESIZEABLE.
Also use vg_is_exported() in one place missed by earlier patch.
Should be no functional change.
2009-09-15 18:35:13 +00:00
Alasdair Kergon
c63b16cf75 Remove test/api which should only be under 'make test'. 2009-09-15 15:37:12 +00:00
Alasdair Kergon
d32a6f15bf post-release 2009-09-15 13:54:28 +00:00
Alasdair Kergon
918abadb6c pre-release cleanup 2009-09-15 13:49:10 +00:00
Alasdair Kergon
7f5adb135d missing (C) reminders 2009-09-15 12:51:28 +00:00
Alasdair Kergon
b1ce301520 dm release cleanup 2009-09-15 11:41:38 +00:00
Alasdair Kergon
cd93201e46 pre-release 2009-09-15 10:57:16 +00:00
Dave Wysochanski
c9aaf5fb24 Fix process_each_vg / _process_one_vg when vg_read() returns FAILED_LOCKING.
Remove the checks for vg_read_error() in most of the tools callback
functions and instead make the check in _process_one_vg() more general.

In all but vgcfgbackup, we do not want to proceed if we get any error
from vg_read().  In vgcfgbackup's case, we may proceed if the backup
is to proceed with inconsistent VGs.  This is a special case though,
and we mark it with the READ_ALLOW_INCONSISTENT flag passed to
process_each_vg (and subsequently to _process_one_vg).

NOTE: More cleanup is needed in the vg_read_error() path cases.
This patch is a start.
2009-09-15 01:38:59 +00:00
Alasdair Kergon
fdf1e32962 More cmirror makefile fixes from Fabio. 2009-09-14 22:57:46 +00:00
Dave Wysochanski
36d336618e Fix build failure when enabling dmeventd and applib.
This patch fixes a build with options similar to the following:
./configure --enable-debug --enable-applib --enable-dmeventd --enable-cmdlib
2009-09-14 22:56:27 +00:00
Alasdair Kergon
013f27e3e6 Add lots of missing stack debug messages to tools.
Make readonly locking available as locking type 4.
Fix readonly locking to permit writeable global locks (for vgscan). (2.02.49)
2009-09-14 22:47:49 +00:00
Dave Wysochanski
1b3f8a4c18 Use vg_is_exported(vg) macro everywhere.
This patch is all just cleanup and no other patch depends on it.
Replace explicit dereference and check with vg_is_exported().
Update a few copyrights and remove unnecessary whitespace.
Should be no functional change.
2009-09-14 19:44:15 +00:00
Dave Wysochanski
dd8ef51fa1 Add most relevant vg_attr fields as lvm2app 'get' functions.
Of the vgs field vg_attr, a few of the most likely to be used attributes
are clustered, exported, and partial.  This patch adds the following 3
functions:
uint64_t lvm_vg_is_clustered(const vg_t vg)
uint64_t lvm_vg_is_exported(const vg_t vg)
uint64_t lvm_vg_is_partial(const vg_t vg)
2009-09-14 19:43:11 +00:00
Dave Wysochanski
11e8d26606 Update lvm and vgs man pages to clarify 'partial' is a VG missing PVs. 2009-09-14 19:42:13 +00:00
Dave Wysochanski
1e954bc8ef Add max_pv and max_lv vg 'get' lvm2app exports. 2009-09-14 15:45:23 +00:00
Milan Broz
720eb0e91c Do not run mdadm tests if MD module is not loaded. 2009-09-13 19:28:00 +00:00
Peter Rajnoha
106763ef9a Move dm_cookie_supported check into dm_udev_get_sync_supprt function.
We don't have to call dm_cookie_supported with dm_udev_get_sync_support
this way. Also, it's necessary for the current code to work properly on
systems without cookie support (older kernels).
2009-09-11 16:11:25 +00:00
Peter Rajnoha
10019a9d96 Add manpage entry for dmsetup's udevcomplete_all and udevcookies commands. 2009-09-11 16:06:31 +00:00
Peter Rajnoha
4515bcf289 Several changes in udev rules:
- add DM_UDEV_RULES_VSN to provide a variable to be checked for in the other
  rules (e.g. to check that DM rules are actually installed, we can alternate
  functionality in the other rules based on this information, also we have
  versioning support for the rules)
- set proper sbin path for dmsetup and blkid, /sbin first, then /usr/sbin.
  This is necessary for anaconda to work properly.
- add 'last_rule' for cryptsetup's temporary devices (symlinks in /dev/mapper
  only)
2009-09-11 16:05:20 +00:00
Peter Rajnoha
aa8728a2ab Add one define that is necessary for older (experimental) libudev to work. 2009-09-11 15:57:51 +00:00
Peter Rajnoha
f2d3b3661b Check that udev is running and set internal state appropriately. 2009-09-11 15:56:06 +00:00
Peter Rajnoha
24b598b1be Add libudev configuration check. 2009-09-11 15:55:07 +00:00
Peter Rajnoha
0d98ee8916 Add y|--yes option for dmsetup to provide a default 'YES' answer to questions. 2009-09-11 15:53:57 +00:00
Peter Rajnoha
3eca5ad9a1 Fix Makefile to take into account dmsetup's reconfiguration. 2009-09-11 15:52:22 +00:00
Dave Wysochanski
ed2465fd30 Update lvm2app unit test vgtest - fix remove bug.
We now must commit to disk after lvm_vg_remove().
2009-09-04 19:17:46 +00:00
Dave Wysochanski
6d21e61889 Fix path to test/api/vgtest in nightly testsuite. 2009-09-04 14:26:16 +00:00
Dave Wysochanski
983312d14d Remove 'test' interative api unit tests from 'TARGET' line.
The test/api directory TARGET line will be reserved for non-interactive
unit tests.  Building the interactive test can still be done with "make test"
from the test/api dir.
2009-09-04 13:49:02 +00:00
Dave Wysochanski
2e1271fe36 Add lvm2app.sh to nightly testsuite.
More tests to come but for now just call into vgtest.
Fix warning in vgtest.c
2009-09-04 12:54:23 +00:00
Dave Wysochanski
15e53c9839 Restore umask when device node creation fails.
Author: Florian Zumbiehl <florz@florz.de>
Acked-by: Dave Wysochanski <dwysocha@redhat.com>
2009-09-03 21:51:26 +00:00
Dave Wysochanski
115d48497e Add daemons/cmirrord files to git - somehow got messed up with cvs rename.
When clogd was renamed to cmirrord, somehow git got the remove of the old
files but not the add of the new files.  This patch adds the new files.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-09-04 20:44:58 +02:00
Dave Wysochanski
a31948f3b7 Fix path to test/api/vgtest in nightly testsuite. 2009-09-04 14:26:16 +00:00
Dave Wysochanski
a12106eb52 Remove 'test' interative api unit tests from 'TARGET' line.
The test/api directory TARGET line will be reserved for non-interactive
unit tests.  Building the interactive test can still be done with "make test"
from the test/api dir.
2009-09-04 13:49:02 +00:00
Dave Wysochanski
dd9f42172f Add lvm2app.sh to nightly testsuite.
More tests to come but for now just call into vgtest.
Fix warning in vgtest.c
2009-09-04 12:54:23 +00:00
Dave Wysochanski
3d8e149668 Restore umask when device node creation fails.
Author: Florian Zumbiehl <florz@florz.de>
Acked-by: Dave Wysochanski <dwysocha@redhat.com>
2009-09-03 21:51:26 +00:00
Petr Rockai
f557647525 Do not override the distclean target in liblvm's Makefile, it annoys make and
the make.tmpl-included distclean should work better anyway.
2009-09-03 18:19:07 +00:00
Dave Wysochanski
1efaf2cde0 Update lvm2app vgtest to take vgname and devices as parameters. 2009-09-03 17:13:46 +00:00
Dave Wysochanski
202aea4dda Update lvm_vg_write() to handle the deferred commit of lvm_vg_write().
Now that we've refactored the internal library functions that do the
vg_remove, we can handle the deferred commit of a lvm_vg_remove() inside
lvm_vg_write().  This makes the VG create/remove API more consistent in
terms of disk commits - they now both require an lvm_vg_write() to commit
the create or remove to disk.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:40:10 +00:00
Dave Wysochanski
eaefa1ac5d Update vg_remove_single_* functions to use the removed_pvs list.
Now that we've split vg_remove_single into two routines, in the first routine
that only manipulates memory, we move the PVs from the vg->pvs list to the
vg->removed_pvs list.  Then later, we iterate through this list to write the
removed PVs to disk, which removes them from the volume group and places them
into the internal ORPHAN VG.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:39:49 +00:00
Dave Wysochanski
fd49174b1a Split vg_remove_single into 2 functions - the second part commits to disk.
Split vg_remove_single into vg_remove_check (mandatory checks before
vgremove) and vg_remove (do actual remove by committing to disk).

In liblvm, we'd like to provide an consistent API that allows multiple
changes in memory, then let lvm_vg_write() control the commit to disk.  In
some cases (for example, lvresize calls fsadm) this may not be possible.
However, since we are using an object model and dividing things into small
operations, the most logical model seems to be the lvm_vg_write model, and
handling the special cases as they arrive.  So as best as possible
we move towards this end.

A possible optimization would be to consolidate vg_remove (committing)
code with vgreduce code.  A second possible optimization is making vgreduce
of the last device equivalent to vgremove.  Today, lvm_vg_reduce fails if
vgreduce is called with the last device, but from an object model perspective
we could view this as equivalent to vgremove and allow it.  My gut feel is
we do not want to do this though.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:39:29 +00:00
Dave Wysochanski
342605bb44 Rename internal library function vg_remove to vg_remove_mdas.
Later patches should consolidate the vgremove / vgreduce functions but for
now let's clarify what vg_remove actually does by changing the name.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:39:07 +00:00
Dave Wysochanski
a9851f5e95 Enforce an alphabetical lock ordering for vgname locks.
Add a new constraint that vgname locks must be obtained in
alphabetical order.  At this point, we have test coverage for
the 3 commands affected - vgsplit, vgmerge, and vgrename.
Tests have been updated to cover these commands.
Going forward any command or library call that must obtain
more than one vgname lock must do so in alphabetical order.
Future patches will update lvm2app to enforce this ordering.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:34:11 +00:00
Dave Wysochanski
848b39b5a0 Update vgrename to take into account vgname lock ordering.
Should be no functional change.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:29:40 +00:00
Dave Wysochanski
de372ce095 Refactor vgrename into vg_rename_old and vg_rename_new.
Should be no functional change.
Will allow us to reorder lock obtaining if needed.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:29:23 +00:00
Dave Wysochanski
8bbae4b10b Change vgmerge behavior to open/lock first vg based on alphabetical ordering.
This enforces our alphabetical lock ordering rules for vgmerge.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:28:43 +00:00
Dave Wysochanski
cff2eda198 Refactor vgmerge - combine _vgmerge_to and _vgmerge_from into _vgmerge_vg_read.
These functions are identical so should be no functional change.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:28:27 +00:00
Dave Wysochanski
7a75b47da6 Refactor vgmerge - create _vgmerge_from and _vgmerge_to.
These functions are really identical but for clarity I made them separate
functions in this patch.

Should be no functional change.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:28:10 +00:00
Dave Wysochanski
79430340e5 Refactor vgmerge - introduce lock_vg_from_first flag.
Should be no functional change.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:27:55 +00:00
Dave Wysochanski
4494c25df7 Change vgsplit behavior to open/lock first vg based on alphabetical ordering.
If the destination vgname comes before the source vgname, we must open the
destination first because of the locking rules.  Thus, do a strcmp and set
the flag based on the comparison.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:27:39 +00:00
Dave Wysochanski
763d659ee2 Refactor vgsplit - reorder _vgsplit_from and _vgsplit_to based on flag.
Slight functional change.  If we open the destination first, we cannot
know the 'fmt'.  In this case we use the default metadata type unless
the user has specified -M on the cmdline.  If not, in most cases this
is fine since we use the LVM2 default metadata type.  However, if the
user is specifying a non-default metadata type (e.g. lvm1) and the order
of the names is such that we have to open the destination (vg_to) first,
we have a problem.  So in this case, we require the use of -M and vgsplit
will fail with an error if not.  I've updated the man page to recommend
the usage of -M in this case.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:27:22 +00:00
Dave Wysochanski
54086f86d2 Refactor vgsplit: _vgsplit_from or _vgsplit_to failure cleanup depends on order.
Should be no functional change.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:27:05 +00:00
Dave Wysochanski
9195a23c95 Refactor vgsplit - create _vgsplit_from function to open source vg.
Should be no functional change and allows future reorder of source and dest
vgs.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:26:50 +00:00
Dave Wysochanski
739ba0fbcc Refactor vgsplit - create _vgsplit_to function which creates or opens dest vg.
Move the creating/opening of the destination vg into its own function so later
we can reorder the source / destination vg opening based on the alphabetical
lock order rule.

Should be no functional change but code is a bit tricky.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:26:34 +00:00
Dave Wysochanski
93ac41e917 Refactor vgsplit - add 'lock_vg_from_first' flag.
Introduce 'lock_vg_from_first' flag to retain which vg was locked first.
Should be no functional change.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:26:18 +00:00
Dave Wysochanski
1928af2a42 Refactor vgsplit - remove bad2 label.
No functional change.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:26:01 +00:00
Dave Wysochanski
45e6585e77 Refactor vgsplit to move existing_vg logic in a separate 'if' statement.
This will aid in future refactorings and allow for us to reorder the source
and destination vg based on alphabetical names.
Should be no functional change.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:25:44 +00:00
Dave Wysochanski
8d6fbe1a89 Fix vgsplit test to require -M on ordering of vgnames. 2009-09-02 19:38:53 +00:00
Alasdair Kergon
375b420c35 clogd->cmirrord 2009-09-02 19:32:37 +00:00
Dave Wysochanski
887b48bd1d Add alphabetical vgname ordering tests for vgsplit, vgmerge, vgrename. 2009-09-02 18:31:11 +00:00
Alasdair Kergon
0794a2e526 rename clogd dir to cmirrord 2009-09-02 17:36:46 +00:00
Petr Rockai
a859e44630 Implement write lock prioritisation for file locking and make it default. 2009-09-02 14:47:39 +00:00
fabbione
1c1a248277 Fix cmirrod build directory while we wait to do a proper rename of the
directory and move files.
2009-09-02 11:49:03 +00:00
fabbione
e0e2165c8e Drop clogd Makefile from CVS since it's always autogenerated from Makefile.in
at configure time.
2009-09-01 19:13:38 +00:00
fabbione
957f8315e3 Fix --with-clvmd=all to deal with the case where no cluster managers are available.
Also simplify the check by removing an unnecessary variable and update
configure messages.
2009-09-01 19:11:45 +00:00
fabbione
d279ed7dd6 Remove unwanted Makefiles and don't purge lvm2.po that's
under RCS.
2009-09-01 18:11:14 +00:00
Christine Caulfield
827480b9d6 Add some code to clvmd to look in the corosync confdb to see what cluster
interface it should be using, it can still be overriden with -I.

If corosync isn't running or there is no information then the usual
checking will happen.

This code only builds if corosync is available.
2009-09-01 09:48:01 +00:00
Alasdair Kergon
1a0af097a6 change clogd to cmirrord
make pidfile locn configurable
2009-08-28 20:51:40 +00:00
Alasdair Kergon
d408fc2864 Rewrite clvmd configuration code. 2009-08-28 19:22:05 +00:00
Jonathan Earl Brassow
bba03eef2f cluster log daemon (clogd): Adjust for kernel CTR arg reordering
We have moved the internally generated mirror-device-size
parameter from the end of the CTR string to the begining.
This change adjusts for that.
2009-08-28 05:27:09 +00:00
Milan Broz
352f7d7f2b Fix global locking in PV reporting commands (2.02.49). 2009-08-24 11:37:20 +00:00
Milan Broz
0f07768d6b Fix uuid warning in pvcreate to use terminated (and dash formatted) UUID string.
# pvcreate -u udwxr7-BoKY-EeKM-r033-xK6o-4og7-F13sGi /dev/sdc
   uuid udwxr7BoKYEeKMr033xK6o4og7F13sGi|��� already in use on "/dev/sdb1"
 is now
# pvcreate -u udwxr7-BoKY-EeKM-r033-xK6o-4og7-F13sGi /dev/sdc
   uuid udwxr7-BoKY-EeKM-r033-xK6o-4og7-F13sGi already in use on "/dev/sdb1"
2009-08-20 07:03:02 +00:00
snitzer
a6a2be6e37 Fix pvcreate on a partition (regressed in 2.02.51).
Eliminate busy loop during pvcreate of a "normal" partition.
_md_sysfs_attribute_snprintf() would busy loop if the device it was
given was not a blkext-based MD partition.

Rather than being cute with a busy-loop prone 'goto check_md_major' in
_md_sysfs_attribute_snprintf(): explicitly check if the provided device
is a blkext-based partition (blkext_major()); and then check that the
get_primary_dev() determined parent is an MD device (md_major()).
2009-08-19 15:34:33 +00:00
Peter Rajnoha
e840cc8b91 Use new blkid instead of vol_id in udev rules.
Thanks to Daniel Mierswa for reminding us.
2009-08-14 14:37:46 +00:00
Jonathan Earl Brassow
ff17105386 Cluster log server (clogd): Add new build files.
Might be a good idea to add the new files to the repository.  :(
2009-08-13 20:51:41 +00:00
Jonathan Earl Brassow
d82f7b9205 configure script: A couple unwanted changes snuck in.
Previously while messing around with 'configure.in' and autoconf,
I changed a couple lines that I didn't want in the final check-in.
2009-08-13 20:23:01 +00:00
Jonathan Earl Brassow
01b09aab43 mirror table generating code: Properly handle 'block_on_errors' and 'cluster' features
The device-mapper mirror CTR table has been changing over time.  This has
now been corrected to handle the old and new methods for invoking the
'block_on_errors' and 'cluster' features.  (The code that does this was
accidentally committed in the previous check-in.  This check-in finishes
the job.)
2009-08-13 19:36:04 +00:00
Dave Wysochanski
f0153d801e Fix error paths for vgcfgrestore when locking fails. 2009-08-13 17:16:38 +00:00
Jonathan Earl Brassow
319b2d8f32 update WHATS_NEW 2009-08-13 16:36:49 +00:00
Jonathan Earl Brassow
419675cd2b cluster log daemon (clogd): Add to LVM build system
This check-in includes the touch-ups, make file changes, copyrights,
and other necessities to include the cluster log daemon into the
build system.

[autoconf still needs to be run to generate the 'configure' and
'Makefile' files.]
2009-08-13 16:34:07 +00:00
Jonathan Earl Brassow
9dd273626a Cluster log daemon (clogd): use LVM bitops in place of ext2 bitops
Eliminate dependency on outside library, since the same functionality
exists in our tree.

[It is important that the bitops work in the same way, as the bitmaps
must remain backwards compatible.  I haven't tested every architecture,
but the x86* archs work.  My test involved using the old ext2fsprogs
bitops, memcpy'ing the bits over to the LVM bitset array and ensuring
that only the bits set via the old methods were set.]
2009-08-13 16:31:01 +00:00
Petr Rockai
2997acf9dc Make lvchange --refresh only take a read lock on volume group. 2009-08-13 14:27:32 +00:00
Petr Rockai
1ee9677b8a Refactor file locking, lifting the flock wrapper code into separate
functions. Also fixes a bug, where a nonblocking lock could, in certain race
situations, succeed without actually obtaining the lock.
2009-08-13 13:23:51 +00:00
Dave Wysochanski
9c14c897f5 Update WHATS_NEW 2009-08-13 12:19:30 +00:00
Dave Wysochanski
dc3e37956b Make lvm2app pv_t handle definition consistent with lvm_t.
This patch update pv_t handle to be consistent with lvm_t - define as a pointer
to internal struct physical_volume.

Author: Dave Wysochanski <dwysocha@redhat.com>
2009-08-13 12:18:15 +00:00
Dave Wysochanski
eb283dcbc6 Make lvm2app lv_t handle definition consistent with lvm_t.
This patch update lv_t handle to be consistent with lvm_t - define as a pointer
to internal struct logical_volume.

Author: Dave Wysochanski <dwysocha@redhat.com>
2009-08-13 12:17:32 +00:00
Dave Wysochanski
fec2b39df3 Make lvm2app vg_t handle definition consistent with lvm_t.
This patch update vg_t handle to be consistent with lvm_t - define as a pointer
to internal struct volume_group.

Author: Dave Wysochanski <dwysocha@redhat.com>
2009-08-13 12:16:45 +00:00
Dave Wysochanski
1e1b8cc2d5 Update WHATS_NEW for recent checkins. 2009-08-13 12:04:01 +00:00
Dave Wysochanski
8a902d7e58 Fix vgextend error path - if ORPHAN lock fails, unlock and release vg.
Full changes
- Fix vgextend error path when lock_vol(VG_ORPHANS) fails
- Move lock_vol(VG_ORPHANS) before archive(vg) - safe & simpler error paths
- Remove legacy comment/code that no longer applies

Found in review - Milan Broz <mbroz@redhat.com>
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-08-13 12:03:46 +00:00
Christine Caulfield
1a0d994305 Fix compilation warning in clvmd.c 2009-08-13 10:39:41 +00:00
Dave Wysochanski
597986b711 Update man pages to clarify usage of PE ranges.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-08-10 17:23:04 +00:00
Dave Wysochanski
ba0a843482 Remove useless _pv_write wrapper. 2009-08-10 17:15:01 +00:00
Dave Wysochanski
0ad0f9e094 Update test/api/test.c to call lvm_vg_create and lvm_vg_remove.
Also fix a couple bugs.
2009-08-07 21:22:37 +00:00
Alasdair Kergon
f93a548fe2 post-release 2009-08-06 19:32:26 +00:00
Alasdair Kergon
84b0920fe0 pre-release 2009-08-06 17:08:01 +00:00
Alasdair Kergon
a3d7f70d45 pre-release 2009-08-06 16:30:34 +00:00
Peter Rajnoha
99b7ce7bf5 Fix semaphore includes in dmsetup for udev sync. 2009-08-06 15:56:50 +00:00
Peter Rajnoha
819e3b9661 Remove 11-dm-permissions.rules (is now in 12-dm-permissions.rules). 2009-08-06 15:28:05 +00:00
Peter Rajnoha
cac468586a Rename template rule file 11-dm-permissions.rules to 12-dm-permissions.rules. 2009-08-06 15:10:58 +00:00
Peter Rajnoha
afc8c05f7f Add 'udevcookies' command for dmsetup. 2009-08-06 15:05:10 +00:00
Peter Rajnoha
886e528490 Add 'udevcomplete_all' command for dmsetup. Export DM_COOKIE_MAGIC in libdevmapper.h. 2009-08-06 15:04:30 +00:00
Peter Rajnoha
06691a0794 Fix failure situations in dm_task_run for udev sync. 2009-08-06 15:02:01 +00:00
Peter Rajnoha
c61da238e1 Detect udev problems in _rename_dev_node. 2009-08-06 15:00:25 +00:00
Alasdair Kergon
e07419b4ba Additional logging 2009-08-05 19:50:08 +00:00
Christine Caulfield
cecc0e9dc8 Fix locking in clvmd
The changes to remove LCK_NONBLOCK from the LVM locks broke clvmd because the
code was clearly wrong but working anyway! The constant was being masked rather
than the variable that was supposed to match against it.
2009-08-05 14:18:35 +00:00
Peter Rajnoha
4d4d7c1fb3 Forgotten '%s' in one of _mk_link warning messages. 2009-08-05 09:12:44 +00:00
Alasdair Kergon
e50e7ee119 detect udev mk_link problems 2009-08-04 21:44:20 +00:00
snitzer
0d15d01b45 Added basic pvcreate --dataalignmentoffset testing to t-pvcreate-usage.sh
Added topology testing via new test/t-pvcreate-operation-md.sh
- requires mdadm and rawhide kernel for full test coverage
2009-08-04 16:02:39 +00:00
Peter Rajnoha
7972728e7c Add --noudevsync option for relevant LVM tools. 2009-08-04 15:55:43 +00:00
Peter Rajnoha
d4d430ee80 Add --noudevsync option for relevant LVM tools. 2009-08-04 15:53:04 +00:00
Alasdair Kergon
b2155fde1a Add activation/udev_sync to lvm.conf. 2009-08-04 15:36:13 +00:00
Peter Rajnoha
0033b9eeb5 '--noudevsync' -- update relevant man pages 2009-08-04 08:09:52 +00:00
Peter Rajnoha
3d25b06fbc Fix a typo in udev rule (splitname, NOT namesplit) 2009-08-04 08:05:06 +00:00
Alasdair Kergon
32752bc3dd Add default udev rules.
Update dm-ioctl.h comments.
2009-08-03 18:44:54 +00:00
Alasdair Kergon
f1fd43b61c Add udev checks. 2009-08-03 18:33:08 +00:00
Alasdair Kergon
38fda754a1 Add warnings to check udev did what it was meant to. 2009-08-03 18:31:53 +00:00
Alasdair Kergon
dc4e40a2f6 Only create LV symlinks on ACTIVATE not PRELOAD.
(This is the udev behaviour - but does this change break anything?)
2009-08-03 18:09:25 +00:00
Alasdair Kergon
9abda62c5b Manage without dm_udev_cleanup? 2009-08-03 18:01:45 +00:00
Dave Wysochanski
cd5c37fe1c Move FIXME from user visible lvm2app.h to lvm_vg.c
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-08-03 12:11:45 +00:00
Alasdair Kergon
bce8cac1f4 cleanup some ignored return values & 'stack's 2009-08-03 11:20:15 +00:00
Alasdair Kergon
4171d0c301 deal with error-related FIXMEs 2009-08-03 11:01:26 +00:00
Alasdair Kergon
2edd956853 lvchange --noudevsync 2009-08-03 10:58:40 +00:00
Petr Rockai
d77b03d6c9 Make lvconvert honour log mirror options combined with downconversion.
(RHBZ 463272)
2009-08-02 21:59:21 +00:00
Petr Rockai
4d5a88661f Slightly refactor mirror log conversions in lvconvert. 2009-08-02 21:56:29 +00:00
Petr Rockai
0b9b1ccd0b Add test for RHBZ 481793 (passing, thanks to vg_read changes checked in
previously).
2009-08-02 21:45:45 +00:00
Petr Rockai
d5ef8e037d Allow LV suspend while --ignorelockingfailure is in force. 2009-08-02 21:03:09 +00:00
Petr Rockai
fd09a32d5e Update synopsis in lvconvert manpage to mention --repair. 2009-08-02 21:01:51 +00:00
snitzer
afc5de69d4 Fix error handling of device-related stat() calls to be ENOENT aware.
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2009-08-01 17:14:52 +00:00
snitzer
2adec6ef66 Retrieve MD sysfs attributes for MD partitions
Rename private _primary_dev() to a public get_primary_dev() and reuse it
to allow retrieval of the MD sysfs attributes (raid level, etc) for MD
partitions.

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2009-08-01 17:11:02 +00:00
snitzer
5829d87313 Improve ability to lookup primary device associated with a partition
Improve lib/device/device.c:_primary_dev()'s ability to look up the
primary device associated with all partitions; including blkext
(e.g. partitions directly on MD).  The same will also work for obscure
sysfs paths; e.g.: paths with mangled names like the HP cciss driver
uses: /sys/block/cciss!c0d0/cciss!c0d0p1/

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2009-08-01 17:09:48 +00:00
snitzer
4422423315 Add devices/data_alignment_detection to lvm.conf.
Adds 'data_alignment_detection' config option to the devices section of
lvm.conf.  If your kernel provides topology information in sysfs (linux
>= 2.6.31) for the Physical Volume, the start of data area will be
aligned on a multiple of the ’minimum_io_size’ or ’optimal_io_size’
exposed in sysfs.

minimum_io_size is used if optimal_io_size is undefined (0).  If both
md_chunk_alignment and data_alignment_detection are enabled the result
of data_alignment_detection is used.

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2009-08-01 17:08:43 +00:00
snitzer
6c88b6c660 Add devices/data_alignment_offset_detection to lvm.conf.
If the pvcreate --dataalignmentoffset option is not specified the start
of a PV's aligned data area will be shifted by the associated
'alignment_offset' exposed in sysfs (unless
devices/data_alignment_offset_detection is disabled in lvm.conf).

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2009-08-01 17:07:36 +00:00
Alasdair Kergon
ccca1401ae dummy makefile for now to keep builds happy 2009-07-31 18:41:19 +00:00
Alasdair Kergon
39270f9647 Set cookies in activation code and wait for udev to complete processing. 2009-07-31 18:30:31 +00:00
Alasdair Kergon
3b6a147653 Add udevcomplete and --noudevwait to dmsetup. 2009-07-31 17:51:45 +00:00
Alasdair Kergon
fd69075a8b another fixme 2009-07-31 16:57:06 +00:00
Alasdair Kergon
dfed228991 Add libdevmapper functions to support synchronisation with udev. 2009-07-31 15:53:11 +00:00
snitzer
5403c6122c Fix compile warnings from recently added log_very_verbose() in _text_pv_write() 2009-07-31 14:23:06 +00:00
Alasdair Kergon
ec76533493 configure --udevdir 2009-07-31 13:31:53 +00:00
Alasdair Kergon
fbdc356b7c add not-yet-working udev options 2009-07-31 11:51:23 +00:00
Alasdair Kergon
709e1afd31 Prepare for udev synchronisation code. (options don't work yet) 2009-07-31 11:49:53 +00:00
snitzer
217bbd0dcb Disable the "new pe_start policy"
Documented which use-cases force the reinstatement of the nuanced
handling of pe_start.  As soon as orphan PVs are eliminated much of this
will no longer be a concern ('preserve_pe_start' can be reenabled in
.pv_setup).

Added defensive 'if (pv->pe_align)' check in _text_pv_write()'s pe_start
loop.
2009-07-30 21:15:17 +00:00
snitzer
e32f9edc3d Revert 'preserve_pe_start' related code in _text_pv_setup
If pv_setup was given a non-zero pe_start it would short-circuit
establishing a default pv->pe_align.  pv->pe_align=0 would result
in a divide by zero in _mda_setup().  'vgconvert -M2 $vgname' hit this.

.pv_write still properly preserves pe_start if it was supplied.
2009-07-30 18:40:22 +00:00
snitzer
282029eb45 Add --dataalignmentoffset to pvcreate to shift start of aligned data area
Adds pe_align_offset to 'struct physical_volume'; is initialized with
set_pe_align_offset().  After pe_start is established pe_align_offset is
added to it.

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2009-07-30 17:45:28 +00:00
snitzer
0ae88174b8 Preserve pe_start in .pv_setup and .pv_write if pe_start was supplied.
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2009-07-30 17:42:33 +00:00
snitzer
42fdc445d0 Remove legacy support for preserving pe_start if a PV already has data
areas.

This preserved pe_start would quickly be readjusted to follow the first
mda anyway.  An example use-case that hit this code path is: running
pvcreate on an already existing PV _without_ a preceeding pvremove.

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2009-07-30 17:41:01 +00:00
snitzer
48416fcdc1 Fix _mda_setup() to not check first mda's size before pe_align rounding.
Without this fix rounding the end of the first mda to a pe_align
boundary could silently exceed the disk_size.

Final 'if (start1 + mda_size1 > disk_size)' block serves as a safety
net.

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2009-07-30 17:19:31 +00:00
snitzer
5dab79f1c7 Formalize pe_start policy as split between .pv_setup and .pv_write.
Document existing pe_start policy.
Fix issue in _text_pv_setup() where existing pe_start case could have
the pv->pe_start set to pv->pe_align even though pe_start shouldn't ever
change.

vgconvert and pvcreate have a facility to preserve the existing start
of the on-disk data extents, known as pe_start.
They indicate this by passing the existing value to the pvsetup function
which must preserve it.

This patch avoids one particular case where the value could get
changed incorrectly now that the alignment settings are configurable.

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2009-07-30 17:18:03 +00:00
Christine Caulfield
cfe2d71862 Document the -I option to clvmd 2009-07-30 13:32:38 +00:00
Alasdair Kergon
db03ac1596 corosync not cman... 2009-07-30 12:31:45 +00:00
Alasdair Kergon
36a1405360 Fix configure script to handle multiple clvmd selections. 2009-07-30 12:25:42 +00:00
Alasdair Kergon
85d1fe36e1 Fix lvm2app.pc installation filename. 2009-07-29 19:24:11 +00:00
Dave Wysochanski
0148ff5ea2 Don't include lvm-version.h in exported liblvm file!
Move include of lvm-version.h into lvm_base.c where it belongs.
2009-07-29 18:38:27 +00:00
Dave Wysochanski
89f096d68e Remove unneeded struct on return from lvm_lv_create_linear.
Results in compile warning.
2009-07-29 16:47:53 +00:00
Alasdair Kergon
db9a15e2fa renamed include files 2009-07-29 14:06:31 +00:00
Alasdair Kergon
84ae15e8d1 Remove pv_t, vg_t & lv_t handles from lib. Only liblvm uses them.
Rename lvm.h to lvm2app.h for now.
2009-07-29 13:26:01 +00:00
Jonathan Earl Brassow
f69451140f Remove old custom list macros and replace with libdevmapper list
macros.
2009-07-28 21:14:12 +00:00
Alasdair Kergon
ca897d8d15 post-release 2009-07-28 20:47:40 +00:00
Alasdair Kergon
4cacc0ee7d \n 2009-07-28 20:41:41 +00:00
Alasdair Kergon
93148f9334 clean up a bit for release 2009-07-28 19:32:26 +00:00
Alasdair Kergon
9ae2f02842 pre-release 2009-07-28 17:22:07 +00:00
Alasdair Kergon
bc63df367d pre-release 2009-07-28 17:07:48 +00:00
Jonathan Earl Brassow
3f76b672f2 Making adjustments to go along with the changes to the kernel.
A patch to the kernel, adding the 'luid' field to dm_ulog_request,
will allow us to properly identify log instances.  We will now
be able to definitively identify which logs are to be removed/
suspended/resumed.  This replaces the old faulty behavior of
assuming the logs were the same if they had the same UUID and
incrementing/decrementing a reference count.
2009-07-28 15:55:50 +00:00
Dave Wysochanski
c79f1d5f37 Add doxygen mainpage tag to lvm.h 2009-07-28 15:33:59 +00:00
Dave Wysochanski
db023c4448 Add an open_mode to the vg struct for liblvm - enforce read / write semantics.
For now, a simple way to enforce the read/write semantics is to just save the
open mode of the VG.  If the caller uses lvm_vg_create, the mode is write.
The caller using lvm_vg_open can use either read or write to open the VG.
Once we have this, we enforce the permissions on each API call and don't allow
a caller to modify a VG that has not been opened properly.

This may be better combined with the locking mode, but I view that as future
cleanup, past this initial release.  The intial release should enforce the
basic object semantics though, as described in the lvm.h file.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-28 15:14:56 +00:00
Dave Wysochanski
48f66c5cb4 Update interactive unit test - fix silly vg_close error. 2009-07-28 14:12:29 +00:00
Dave Wysochanski
f54cd61ba6 Update interactive unit test for liblvm - add vg_write, general cleanup. 2009-07-28 13:49:28 +00:00
Dave Wysochanski
011ec46dae Add lvm_vg_get_seqno, updating lvm.h and unit test.
Adding the ability to get the seqno is important for an application to
determine if something has changed in a VG.  Otherwise, the only way to
know is to open the VG with write permission and hold the handle.
2009-07-28 13:17:04 +00:00
Dave Wysochanski
6c91562aa9 Update lvm.h - remove remaining FIXMEs, note limitations of a few functions.
Almost done...
2009-07-28 13:16:40 +00:00
Dave Wysochanski
a3ce036dc0 Fix lvm.h formatting. 2009-07-28 12:19:58 +00:00
Dave Wysochanski
c82ecd6656 Add lvm_library_get_version() and update unit tests to display version. 2009-07-28 11:03:28 +00:00
Dave Wysochanski
7ce37c9842 Use dm_malloc and dm_free in liblvm instead of malloc/free. 2009-07-28 09:56:48 +00:00
Dave Wysochanski
6e4baa664d Rename lvm_create to lvm_init and lvm_destroy to lvm_quit. 2009-07-28 09:16:18 +00:00
Dave Wysochanski
59ffb010c4 Update lvm.h to address feeback.
This addresses a a large amount of Alasdair's review.  Subsequent patches
will address remaining issues.
Addressed:
// FIXME Mention that's also required on error.
// FIXME Be consistent in terminology.  It's called "system_dir" then last sentence says "system directory setting".  Is it referring to "system_dir" there or something else?
// FIXME Mention it frees all resources and cannot be used subsequently?
// FIXME What does "any system configuration" mean?
// FIXME Expand on that explanation a bit, now that we know what the other fns look like.
// FIXME Not sure about that - it needs to scan sometimes.  "will not" or "might not" ?
// FIXME: That's a FIXME in the code!!!
// FIXME What does "copied" mean in this context???
// FIXME Say what struct the returned struct dm_list is a list of...
// FIXME "This API" ?  This function creates an object in memory?
// FIXME This function commits the Volume Group object referenced by the VG handle to disk?
// FIXME Where is "Name" defined?  Absolute pathname?

Outstanding:
// FIXME Version function first?  No structs or handles needed for that.
// FIXME Sort out this alignment.  "Set an" directly below "system_dir" looks awful.  Indent differently?  More blank lines?
// FIXME Check how doxygen processes this.  E.g. "return: LVM handle.  You must use lvm_error() to check there were no errors and confirm that the handle is valid for passing to other functions."
// FIXME Find a better name.  lvm_init.
// FIXME Consider renaming according to the new name for lvm_create.
// FIXME Please can we use dm_malloc throughout?
2009-07-28 00:36:58 +00:00
Dave Wysochanski
2edb216b24 Add warning to lvm.h stating API development in progress. 2009-07-27 21:13:54 +00:00
Dave Wysochanski
7835e2a762 Update WHATS_NEW for latest liblvm changes 2009-07-27 21:10:30 +00:00
Dave Wysochanski
f8c9d0c018 Remove unnecessary \n's from log_error in liblvm. 2009-07-27 21:03:15 +00:00
Dave Wysochanski
2965b52563 Add config_reload and config_override to test.c, change prompt.
PV         PV UUID                                VG
  /dev/loop1 A95EvV-iqmb-ZFuJ-u8MV-Npwn-wlc2-Ul1Mnn vg1
  /dev/loop0 R16FDG-OmoS-HNGt-LSZY-OAlC-7qeU-t2gztp vg1
lvm> config_override loop0
Success overriding LVM configuration
lvm> config_reload
Success reloading LVM configuration
lvm> vg_open vg1
Couldn't find device with uuid 'A95EvV-iqmb-ZFuJ-u8MV-Npwn-wlc2-Ul1Mnn'.
Success opening vg vg1
lvm> vg_close vg1
lvm> quit

Maybe a bug in lvm_vg_open for missing pvs but the filter seems to work.

Change prompt from "lvm>" to "liblvm>".

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-27 21:02:51 +00:00
Dave Wysochanski
05762487ff Update return code for lvm_config_reload. 2009-07-27 21:02:35 +00:00
Dave Wysochanski
b2380fcc48 Add lvm_config_override - allow caller to override config, similar to --config.
Allowing the caller to override the LVM configuration with an API will
enable them to use things such as device filters.
While very flexible, there is some danger to this API in that it will
make it harder to debug setups that have a changing config and deduce
what might have happened.  At some point we may want to limit the scope
of this API but for now it is as open as the --config option to lvm commands.

Update exported symbols.  When I renamed lvm_reload_config to lvm_config_reload
I forgot to rename so I renamed that one here.

This I believe is the last liblvm API for now.  ;-)

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-27 21:02:17 +00:00
Dave Wysochanski
40ec4f631c Rename _override_settings into override_config_tree_from_string and move.
Move _override_settings from tools/lvmcmdline.c into lib/config/config.c
and export so we can re-use in liblvm.
2009-07-27 21:01:56 +00:00
Dave Wysochanski
f9238f838c Refactor _override_settings to take the new config string as input.
We will re-use this function from liblvm.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-27 21:01:36 +00:00
Dave Wysochanski
3dd756c2c1 Add skeletons of lvm_lv_resize and lvm_pv_resize - not yet implemented.
These lower-priority interfaces are not currently implemented in liblvm
but are on the TODO list in the near term.

Author: Thomas Woerner <twoerner@redhat.com>
Acked-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-27 21:00:50 +00:00
Dave Wysochanski
a92bdc094d Update test/api/test.c to include lvm_vg_reduce and lvm_vg_extend.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-27 17:45:21 +00:00
Dave Wysochanski
9b367aa0a1 Update test/api/vgtest.c to include lvm_vg_reduce.
Signed-off-by: Thomas Woerner <twoerner@redhat.com>
Acked-by: Dave Wysochanski <dwysocha@redhat.com>


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-27 17:44:58 +00:00
Dave Wysochanski
2201a47d95 Add lvm_vg_reduce to liblvm2app
Extend lvm_vg_write to remove pvs removed in lvm_vg_reduce. The lvm
volume_group internal structure removed_pvs is used for that. The list is
empty afterwards.

Add new test for vg->pvs emptyness to lvm_vg_write to prevent to write empty
vgs. This is needed because of lvm_vg_reduce and lv_vg_create, which creates
empty vgs.

Signed-off-by: Thomas Woerner <twoerner@redhat.com>
Acked-by: Dave Wysochanski <dwysocha@redhat.com>


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-27 17:44:29 +00:00
Dave Wysochanski
bdb578fda2 Add vg_reduce to metadata.c and metadata-exported.h
This function behaves a little bit different than vg_reduce_single, because
it allowes to remove even the latest pv. This has been done to be consistent
to lvm_vg_create, which creates an empty vg.

removed_pvs has been added to the volume_group struct. vg_reduce adds remove
pvs to this list to be able to commit the changes for the pvs in lvm_vg_comm
in liblvm2app.

Initialize removed_pvs list in format-specific volume_group constructors.
Ideally, we should have a base constructor here that initializes the general
non-format specific members of struct volume_group.  But until then, there
are multiple places to initialize these members.  Maybe a better patch would
be a base constructor patch for struct volume_group.  That is more work
though.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Signed-off-by: Thomas Woerner <twoerner@redhat.com>


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-27 17:43:39 +00:00
Dave Wysochanski
6765f24184 Update error return and comments for lvm_list_vg_names/uuids.
The two liblvm functions that return a list of vgnames and vguuids use
cmd->mem to allocate the list.  Make it clear to the caller that this
memory will be freed when the LVM handle is freed.

Clean up and clarify the return value of the functions.  In the
case of a memory allocation error, add a couple log_errnos to the internal
code, and make it clear that memory allocation returns a NULL pointer.
If there are no VGs in the system, the list returned is an empty list.

Make a note of the fact that currently we return hidden VG names, how
these can be detected (always start with "#"), and that they should
not be used.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-27 11:00:17 +00:00
Dave Wysochanski
5ec0df6fe1 Rename lvm_reload_config to lvm_config_reload.
The general naming scheme for most liblvm APIs is:
lvm_<object>_<action>

As there are likely to be other things to do on the lvm 'config' object
(i.e. lvm_config_set_device_filter), we should use consistent naming.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-27 10:18:51 +00:00
Dave Wysochanski
594fbed146 Update display.c to use vg_free(vg) instead of duplicating the calculation.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-27 10:18:31 +00:00
Dave Wysochanski
20e2e324e1 More liblvm header file cleanups.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-27 08:28:13 +00:00
Dave Wysochanski
f33e774f4b Update WHATS_NEW for latest liblvm changes 2009-07-26 22:19:14 +00:00
Dave Wysochanski
dbdce70a8e Update test/api/test.c to display lvm_lv_is_active and lvm_lv_is_suspended.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 20:59:02 +00:00
Dave Wysochanski
b41f609fe4 Update test/api/test.c to call lv_deactivate and lv_activate.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 20:58:38 +00:00
Dave Wysochanski
424f396e42 Add lvm_lv_is_active and lvm_lv_is_suspended.
Return whether an LV is active in the kernel (live table) or suspended
(table suspend).


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 20:58:11 +00:00
Dave Wysochanski
b1c01d2ac9 Implement lvm_lv_activate and lvm_lv_deactivate liblvm calls.
Limited implementation but other types of activation should probably have
separate calls.  We also currently do not handle pvmoves or lvconverts.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 20:57:37 +00:00
Dave Wysochanski
fed21338fc Update test/api/*.c to use consistent liblvm error returns.
For now, liblvm will return -1 (fail) / 0 (success) or
NULL (fail) / non-NULL (success).  Upon failure, lvm_errno and
lvm_errmsg should be used to determine the precise error.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 20:29:56 +00:00
Dave Wysochanski
987fe8b638 Update a few liblvm calls with log_errno.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 20:29:28 +00:00
Dave Wysochanski
535c4372ca Update liblvm status return codes to be consistent.
For now, we use the following scheme.
For APIs that return an int, success is 0, fail is -1.
APIs that return handles, success is non-NULL, fail is NULL.
At this early stage, liblvm error handling mechanism is subject to change,
but for now we go with this simple scheme consistent with system
programming.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 20:28:59 +00:00
Dave Wysochanski
ac1f36ae76 A few more lvm.h updates that got missed.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 16:49:52 +00:00
Dave Wysochanski
b1442a1a97 Rename lvm_scan_vgs to lvm_scan.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 16:44:05 +00:00
Dave Wysochanski
6628e7769e Update lvm.h - comments describing function behavior, divide into sections.
Hard to divide into smaller patches because of the moving around and
commenting, so just put in the new file diffs.  We will review and can
update as necessary.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 16:35:57 +00:00
Dave Wysochanski
5fadbc7f97 Update lvm.h handle and handle list comments.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 16:11:58 +00:00
Dave Wysochanski
095026b459 Rename lvm_vg_get_free to lvm_vg_get_free_size.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 16:06:46 +00:00
Dave Wysochanski
496c8d01fa Rename lvm_list_vg_ids to lvm_list_vg_uuids.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 16:06:21 +00:00
Dave Wysochanski
63574298ce Rename lvm_vg_get_free_count to lvm_vg_get_free_extent_count.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 16:05:49 +00:00
Dave Wysochanski
8c1a5f033e Update test/api/test.c to call lvm_lv_remove.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 14:37:15 +00:00
Dave Wysochanski
7e3141512a Add lvm_vg_remove_lv liblvm function.
Add a very simple version of lvm_vg_remove_lv.
Since we currently can only create linear LVs, this simple remove function
is adequate.  We must refactor lvremove_single a bit.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 14:36:52 +00:00
Dave Wysochanski
c4510327d4 Update test/api/test.c - correct list_vg_names and list_vg_ids.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 13:08:00 +00:00
Dave Wysochanski
88fc2bb3e1 Update test/api/test.c for liblvm 'get' functions.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 13:07:41 +00:00
Dave Wysochanski
75a6913f4e Add most all liblvm 'get' functions needed for anaconda.
Add the most straightforward 'get' functions required for anaconda.
These are the ones that return simple uint64_t values.
The other more complex ones involve the lv_attr bits.  These will
come in a separate patch series since each lv_attr bit will be returned
in a separate API instred of returning the string and requiring the
user to parse it.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 13:06:59 +00:00
Dave Wysochanski
97472070c3 Use vg_size in vg_set_extent_size.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 12:41:36 +00:00
Dave Wysochanski
5d4fd6055e Refactor a few report field calculations into separate functions.
For liblvm 'get' functions, we should share code with the reporting functions.
This means we need common code to return the values for the fields.
In this patch we refactor a few of the fields needed in liblvm.
Unfortunately, for the simple fields that do derefernces of structure
members (for example, vg_extent_count), we cannot call the common function
from the reporting infrastructure without more refactoring.  The reason is
that the dereference of the simple fields is done deep inside the reporting
code (to get the generic "data" pointer), and the display function is a
generic 'size32' function.  We can fix these issues later with more
refactoring.

Should be no functional change and the testsuite should cover any possible
regressions.  The only fields in the report affected by this patch are:
vg_size, vg_free, and pv_mda_count.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 12:41:09 +00:00
Dave Wysochanski
83f4e5b457 Rename vg_size to vgsize to avoid naming conflicts.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 12:40:27 +00:00
Dave Wysochanski
1523a4953f Update WHATS_NEW for recent checkins 2009-07-26 11:21:32 +00:00
Dave Wysochanski
429139be78 Update test/api/test.c to call lvm_vg_create_lv_linear.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 02:35:47 +00:00
Dave Wysochanski
0307c0366a Update test/api/test.c to handle read/write open modes.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 02:35:19 +00:00
Dave Wysochanski
f698db8346 Add lvm_vg_create_lv_linear liblvm function.
Create a default linear logical volume from a volume group.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 02:34:36 +00:00
Dave Wysochanski
b690ccfc20 Move extents_from_size from lvcreate into internal library so we can reuse.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 02:34:09 +00:00
Dave Wysochanski
86e97d9f87 Move _lvcreate into the internal library and rename to lv_create_single.
After some refactorings, we can now move the bulk of _lvcreate into the
internal library, and we can call from liblvm.  In the future, we should
refactor lv_create_single further, probably by segtype, to reduce the
size of struct lvcreate_params.  For now this is a reasonable refactor
and allows us to re-use the function from liblvm.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 02:33:35 +00:00
Dave Wysochanski
4a7a570953 Move pvs and pv_count fields from lvcreate_params to lvcreate_cmdline_params.
No functional change.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 02:32:50 +00:00
Dave Wysochanski
0b1ce57fd1 Comment lvcreate_params struct.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 02:32:26 +00:00
Dave Wysochanski
eb39bfad81 Move 'size' from lvcreate_params into lvcreate_cmdline_params.
The main _lvcreate function should deal with extents - the 'size' parameter
is just an intermediate step.
Should be no functional change.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 02:32:00 +00:00
Dave Wysochanski
77533a2090 Move percent_t from struct lvcreate_params to struct lvcreate_cmdline_params.
Create a new structure, lvcreate_cmdline_params, to store parameters only
relevant for the cmdline, not the library call to lvcreate.
Should be no functional change.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 02:31:41 +00:00
Dave Wysochanski
414bc9cc44 Refactor extents calculations / updates in _lvcreate.
Move extents calculation adjustments into their own local functions
right after we read the vg.  This calculation really is not part of
the LV create function but is rather an adjustment to the parameters
based on what is given on the cmdline.  So we move it outside the main
_lvcreate.

Should be no functional change.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 02:31:18 +00:00
Dave Wysochanski
180d55d135 Refactor _lvcreate - move *_ARG into _lvcreate_params and get 'cmd' from 'vg'.
A couple simple refactorings of _lvcreate - should be no functional change.
Move tags_ARG parsing into _lvcreate_params.  Also use lp->voriginsize
instread of arg_count().  These refactorings make it easier to move the
bulk of _lvcreate into the library.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 02:30:57 +00:00
Dave Wysochanski
458baea830 Remove use of void * from pvcreate_single.
We should use struct pvcreate_params to utilize compiler typechecking.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 02:02:22 +00:00
Dave Wysochanski
aaeec65415 Update lvm_vg_extend to do an implicit pvcreate on the device.
Although the tools do not currently do this, we update lvm_vg_extend
to do an implicit pvcreate on an uninitialized device.  The tools will
soon be refactored to do this as well, but more work is needed in the
tools.  For now we update lvm_vg_extend since this is the behavior
required by liblvm.
With this change, the simple liblvm unit test, test/api/vgtest.c
should pass whether or not the device is initialized.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 01:54:40 +00:00
Dave Wysochanski
3a821c040e Move ORPHAN_VG lock outside pvcreate_single.
The implicit pvcreate require either moving the ORPHAN_VG lock outside
pvcreate_single or somehow having the function know or detect whether
the ORPHAN_VG lock is already held.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 01:54:20 +00:00
Dave Wysochanski
31fdb438bb Change pvcreate_single to return pv_t and update function description.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 01:53:57 +00:00
Dave Wysochanski
8db00f063d Allow pvcreate_single to be called with NULL for default pvcreate params.
Passing NULL for pvcreate parameters gives you default parameters for
pvcreate_single.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 01:53:30 +00:00
Dave Wysochanski
8cca58b800 Move bulk of pvcreate logic into library.
In preparation for implicit pvcreate during vgcreate / vgextend,
move bulk of pvcreate logic inside library.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 01:53:09 +00:00
Dave Wysochanski
9f2e60598d Remove unneeded pv_create wrapper function.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-26 01:52:19 +00:00
Alasdair Kergon
78af10f81b Add global/wait_for_locks to lvm.conf so blocking on locks can be disabled. 2009-07-24 23:28:55 +00:00
Alasdair Kergon
025ac59005 remove no-longer-needed NONBLOCK 2009-07-24 18:26:42 +00:00
Alasdair Kergon
2b9605e8f5 All LV locks are non-blocking so remove LCK_NONBLOCK from separate macros. 2009-07-24 18:15:06 +00:00
Dave Wysochanski
333091a0d3 Eliminate compile warning introduced by previous commit. 2009-07-24 15:15:26 +00:00
Dave Wysochanski
012ff9982c Update lvm_vg_extend() to obtain VG_ORPHAN.
vg_extend() no longer obtains VG_OPHAN so we must do so in liblvm function.
We still have the race in liblvm but we will address this problem later.
2009-07-24 15:12:50 +00:00
Dave Wysochanski
887e1d5d61 Revert previous patch that moved VG_ORPHAN lock inside vg_extend.
We must hold the VG_ORPHAN lock until we commit to disk.  Otherwise,
we risk a race condition on vgcreate / vgextend.  Reverts the following
commit:

commit 72a41480ba
Author: Dave Wysochanski <dwysocha@redhat.com>
Date:   Fri Jul 10 20:09:21 2009 +0000

    Move orphan lock obtain/release inside vg_extend().

    With this change we now have vgcreate/vgextend liblvm functions.
    Note that this changes the lock order of the following functions as the
    orphan lock is now obtained first.  With our policy of non-blocking
    second locks, this should not be a problem.

    Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-24 15:01:43 +00:00
Dave Wysochanski
3aca463e7e Add tests for lvm_vg_name_list, lvm_vg_id_list and lvm_scan_vgs.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-24 12:51:32 +00:00
Dave Wysochanski
b7255dac54 Add lvm_scan_vgs liblvm fn to scan the system for LVM metadata.
The lvm_list_vg_{names|ids} functions do not do a scan so we provide
a liblvm function that does a scan.

Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-24 12:48:21 +00:00
Dave Wysochanski
a3158f498f Add lvm_list_vg_names and lvm_list_vg_ids liblvm functions.
These functions provide the capability of enumerating all vgnames and
vgids in the system.  They do not do a scan of the system.

Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-24 12:47:15 +00:00
Dave Wysochanski
95ff997d1d Remove redundant validate_name in vgreduce.
This check is now done in vg_read_for_update, thanks to mornfall.
Should be no functional change.

Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-24 11:13:36 +00:00
Dave Wysochanski
80520d4ed7 Update test/api/test.c to not segfault if null lists of pvs/lvs returned.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-24 04:15:30 +00:00
Dave Wysochanski
1fbf5728e1 Update WHATS_NEW for liblvm commits 2009-07-23 23:55:01 +00:00
Dave Wysochanski
216b6b3efd Update test/api/test.c for simple tests involving pv/vg/lv name/uuid attributes.
Tests the following APIs:
- lvm_{pv|vg|lv}_get_{name|uuid}()
- lvm_{lvs|pvs}_in_vg()

Example:
lvm> vg_open VolGroup00
Success opening vg VolGroup00
lvm> vg_list_lvs VolGroup00
LVs in VG VolGroup00:
VolGroup00/LogVol00 (bFO4EU-UaDu-iuMm-N6BA-xcZc-nm3u-J5K5lu)
VolGroup00/LogVol01 (BHGsPK-PwzY-kye0-MEWa-a67z-BiYE-03ZjwM)
lvm> vg_list_pvs VolGroup00
PVs in VG VolGroup00:
/dev/sda2 (Be91pt-CqT0-4YJE-nGI6-Oisz-hy0N-l9CHgn)

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Acked-by: Thomas Woerner <twoerner@redhat.com>
2009-07-23 23:40:50 +00:00
Dave Wysochanski
557f287005 Add lvm_{pv|vg|lv}_get_{uuid|name}.
Caller must free the memory of the uuid / name returned.
This may not be the best memory management policy since it may lead to
memory leaks if the caller has code like this:
if (!lvm_vg_get_name(vg))

Maybe we don't care - if we do we can use pools tied to handles later
or some other scheme.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Acked-by: Thomas Woerner <twoerner@redhat.com>
2009-07-23 23:40:05 +00:00
Dave Wysochanski
7548112578 Add lvm_vg_list_{pvs|lvs} - return lists of pv/lv handles for a vg.
- Use vgmem pool to allocate a list of lvm_*_list structs
- Allocate a new list each call (list may have changed since last call)
- Add to liblvm's exported symbols

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Acked-by: Thomas Woerner <twoerner@redhat.com>
2009-07-23 23:39:02 +00:00
Dave Wysochanski
323685d4c9 Add list structure definitions for liblvm objects.
- pv_t, vg_t, lv_t
- include libdevmapper.h: needed for struct dm_list

These list structures will be needed in later APIs to return a list of
handles to one object, given another object.  For example, lvm_vg_list_lvs()
will return a list of LV handles (lv_t's) given a VG handle (vg_t).  We
need a structure to do this so we define the LV structure, as well as the
other structures at this point.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-23 23:37:24 +00:00
Dave Wysochanski
4900b15a65 Remove lvseg_t and pvseg_t typedefs from liblvm/lvm.h.
We do not need lvseg and pvseg for now.  If we need we will add back
later.
2009-07-23 23:36:20 +00:00
Alasdair Kergon
adc02e52ad check in the correct pkgconfig file 2009-07-23 01:41:53 +00:00
Dave Wysochanski
4bc79321a7 Update lvm_vg_create to use NULL / non-NULL return for the time being.
Some of the error interface is still TBD.  Rather than exporting a lot
of codes, etc, just use a simple pass / fail.  The allows our unit test
to not segfault if trying to create a VG that already exists.
2009-07-23 01:20:22 +00:00
Dave Wysochanski
c0d270947f Add a couple lvm_vg_open() calls to vgtest.c. 2009-07-22 22:25:30 +00:00
Dave Wysochanski
8b4677dca3 Add lvm_vg_open() to open an existing VG for reading or writing.
lvm_vg_open() calls internal vg_read() function which is the entry point
for reading an existing VG.  In addition to the mode, we include a 'flags'
parameter for future extensions.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-22 22:24:16 +00:00
Alasdair Kergon
44482a809e Add liblvm2app Makefile installation targets.
Add liblvm pkgconfig file.
2009-07-22 21:09:13 +00:00
Alasdair Kergon
90d8fab02e fix dir in generated file list for cflow 2009-07-22 20:29:56 +00:00
Alasdair Kergon
337d248c5d Use newly-independent LVM_LIBAPI in liblvm soname. E.g. liblvm2app.so.2.1. 2009-07-22 20:12:14 +00:00
Alasdair Kergon
62a636c887 Add an API version number, LVM_LIBAPI, to the VERSION string. 2009-07-22 20:01:28 +00:00
Dave Wysochanski
bbd12ca7aa Update api/test/vgtest.c error handling.
Reverts some of my 'cleanup' from last night.  For now we will use pass/fail
on API calls (either 'int' return or NULL/non-NULL handle), then use
lvm_errno() to get more specific errors.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-22 16:49:54 +00:00
Dave Wysochanski
02f858e5c9 Update test/api/vgtest.c to use lvm_errno and lvm_errmsg.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-22 03:13:57 +00:00
Dave Wysochanski
536a126886 Fix lvm_vg_close() when locking fails.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-22 03:13:35 +00:00
Dave Wysochanski
2a42fdea85 Export lvm_errno and lvm_errmsg in liblvm.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-22 03:13:13 +00:00
mpatocka
eb77e55fe6 Pass struct cmd_context as a first argument to init_multiple_segtypes.
Remove redundant assignment seglib.cmd = cmd (done already at the beginning
of the function).

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
2009-07-21 20:00:02 +00:00
Jonathan Earl Brassow
edd643b226 After rebasing the cluster logging code, adjustments need to be
made to compensate for the changes in the kernel-side component
that recently went upstream.  (Things like: renamed structures,
removal of structure fields, and changes to arguments passed
between userspace and kernel.)
2009-07-21 15:34:53 +00:00
Jonathan Earl Brassow
4f7f3b5a50 Rebasing the cluster log daemon code from the most current
sources in the 'cluster' tree.  There have been a number of
bug fixes and I don't want to loose them.
2009-07-21 15:32:13 +00:00
Dave Wysochanski
1b611e7cd8 Fix build environment of test/api: Make it usable for more than one test case.
Author: Thomas Woerner <twoerner@redhat.com>
Committer: Dave Wysochanski <dwysocha@redhat.com>
2009-07-21 13:51:05 +00:00
Alasdair Kergon
5454ec8f9b Return EINVALID_CMD_LINE not success when invalid VG name format is used. 2009-07-21 11:10:49 +00:00
Dave Wysochanski
d2d528d214 Rename test/api/vgcreate.c to vgtest.c to reduce filename conflicts in tree.
Signed-off-by: Thomas Woerner <twoerner@redhat.com>
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-21 10:46:45 +00:00
Dave Wysochanski
a00d4b7845 Fix compile warnings in vgcreate liblvm api unit test case.
Use const and PRIu64.

Signed-off-by: Thomas Woerner <twoerner@redhat.com>
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>


Author: Thomas Woerner <twoerner@redhat.com>
Committer: Dave Wysochanski <dwysocha@redhat.com>
2009-07-21 10:41:47 +00:00
snitzer
0eeefc4c0d Cast MINOR() in _md_sysfs_attribute_snprintf()'s dm_snprintf() call. 2009-07-20 18:44:13 +00:00
snitzer
0d8600ed6d Cast MAJOR() and MINOR() to int when used with "%d" in dm_snprintf() call.
Fixes SEGV in _md_sysfs_attribute_snprintf() on 32-bit systems.
2009-07-20 18:33:16 +00:00
Dave Wysochanski
35cf511d45 Remove 'is already' message from vg_set_* functions.
These messages are unnecessary in the set functions.  We check for this
condition and print a message in the vgchange tool but not the library
functions.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-16 20:18:16 +00:00
Alasdair Kergon
b88fe43808 Fix so only log_error and log_fatal set EUNCLASSIFIED. 2009-07-16 13:13:33 +00:00
Dave Wysochanski
9c72fc1d2b Remove extraneous messages for extent_size and alloc_policy upon vgcreate.
When converting to the new liblvm functions, the vgcreate code path
changed to create a new vg, then set values.  As a result of this
change, and the fact that we give a user a message if they try to
set the same value of a VG attribute (extent_size, alloc_policy, etc),
you'll see these 2 extraneous "is already" messages with vgcreate:
tools/lvm vgcreate vg2 /dev/loop2
  Physical extent size of VG vg2 is already 4.00 MB
  Volume group allocation policy is already normal
  Volume group "vg2" successfully created

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-16 03:25:26 +00:00
Dave Wysochanski
e176789891 Change default errno value to 0 (no error) and add prototypes in lvm.h
Since we are using errno values, we should use '0' as a default value
which indicates a non-error, rather than defining some made-up default
value that is not defined in errno.  If we need to deviate from errno
values, this will most likely indicate a flaw in our design.

Add prototypes for lvm_errno and lvm_errmsg inside lvm.h and provide
a basic description of their function.  This fixes a couple compile
warnings.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-16 03:07:45 +00:00
Alasdair Kergon
5e3369aba3 Add log_errno to set a specific errno and replace log_error in due course. 2009-07-16 00:52:06 +00:00
Alasdair Kergon
7b0fcd79a0 Add lvm_errno and lvm_errmsg to liblvm to obtain failure information.
Change create_toolcontext to still return an object if it fails part-way.
Add EUNCLASSIFIED (-1) as the default LVM errno code.
2009-07-16 00:36:59 +00:00
Alasdair Kergon
0ed40c04c7 Store any errno and error messages issued while processing each command.
(Enabled by default while we test it, but in due course we'll only store
the error messages when we need to.)
2009-07-15 23:57:54 +00:00
Alasdair Kergon
7da36611dc Use log_error macro consistently throughout in place of log_err. 2009-07-15 20:02:46 +00:00
Alasdair Kergon
49aeee3017 Revert broken commit:
2009-07-15 06:10:51  Un-export vg_read_internal.

lvm-functions.c:774: warning: implicit declaration of function 'vg_read_internal'
2009-07-15 17:26:26 +00:00
Alasdair Kergon
571cd5a94f post-release 2009-07-15 15:38:41 +00:00
Alasdair Kergon
a044570365 pre-release 2009-07-15 15:16:48 +00:00
Alasdair Kergon
c18595ce31 pre-release clarification 2009-07-15 14:59:14 +00:00
Alasdair Kergon
a06d6839e1 New LOG_MESG macro to fix file/line number logging for memory leaks after
LOG_LINENO macro was added.
2009-07-15 14:18:38 +00:00
Alasdair Kergon
22ba3c7b41 pre-release 2009-07-15 13:20:06 +00:00
Dave Wysochanski
e84ecd9e42 Fix memory leak in process_each_pv path.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-15 12:22:59 +00:00
Dave Wysochanski
db5e7962c9 Fix memory leak in _process_one_vg error path.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-15 12:15:36 +00:00
Petr Rockai
4782f379e2 Fix warning. 2009-07-15 06:11:25 +00:00
Petr Rockai
8762b5aad4 Un-export vg_read_internal. 2009-07-15 06:10:51 +00:00
Petr Rockai
147d76d2aa Fix bad prototype from previous checkin. 2009-07-15 05:57:11 +00:00
Petr Rockai
a5aedfee75 Port process_each_pv to new vg_read. 2009-07-15 05:50:22 +00:00
Petr Rockai
2a4c743edd Remove lockingfailed().
We provide a lock type that behaves like no_locking, but is not
  clustered. Moreover, it also forbids any write locks. This magically (and
  consistently) prevents use of clustered VGs, or changing local VGs with
  --ignorelockingfailure. As a bonus, we can remove the special hacks in a few
  places. Of course, people looking for trouble can always set their locking_type
  to 0 to override.
2009-07-15 05:49:47 +00:00
Petr Rockai
a9d820ed2f Take just a read lock when activating in lvchange. 2009-07-15 05:48:36 +00:00
Petr Rockai
fa059a59a8 Refuse to open VG with MISSING_PVs for update unless handles_missing_pvs is set. 2009-07-15 05:47:55 +00:00
Dave Wysochanski
dc8f5ef279 Check for certain vg_read errors in _process_one_vg iterator.
In _process_one_vg, we should never proceed if the VG read fails with certain
conditions.  If we cannot allocate or construct the volume_group structure,
we should not proceed - this is true regardless of the tool calling the
iterator.  In other cases, when the volume group structure is constructed but
there is some error (PVs missing, metadata corrupted, etc), some tools may
want to process the VG while others may not.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-15 05:23:19 +00:00
Dave Wysochanski
e5e30dc73d Fix FAILED_INCONSISTENT case in vg_backup_single - typeo on 'if' condition.
In vg_backup_single, we should error out if we vg_read_error(vg) and the
error code we received was anything other than FAILED_INCONSISTENT.
Original code contained an error because C operator precedence.
Note - this was part of the vg_read() so no WHATS_NEW entry neceesary.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-15 03:30:04 +00:00
Dave Wysochanski
ae94917e76 Fix pvremove test breakage.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-14 19:59:41 +00:00
Dave Wysochanski
fedb3704f3 Fix vgck and vgremove segfault if non-existent vg given.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-14 19:37:18 +00:00
Dave Wysochanski
ea18f8e19b Add a few negative tests which should fail cleanly if pv, vg, lvs don't exist.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-14 19:35:35 +00:00
Milan Broz
cd93b0470b Enable use of new multi-segment registration for static registration too.
so it allows this use:

#ifdef MYNEWSEG_INTERNAL
        if (!init_mynewseg_segtypes(&seglib))
                        return 0;
#endif
2009-07-14 12:17:14 +00:00
Alasdair Kergon
4665b5aecf Exclude VG_GLOBAL from vg_write_lock_held so scans open devs read-only again. (mbroz) 2009-07-14 11:01:26 +00:00
Dave Wysochanski
1f9b9c6235 Add liblvm test case for creating of a vg.
liblvm unit test case uses the following APIs:
- lvm_create, lvm_destroy
- lvm_vg_create, lvm_vg_extend, lvm_vg_set_extent_size, lvm_vg_write,
lvm_vg_remove, lvm_vg_close

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Acked-by: Alasdair G Kergon <agk@redhat.com>
2009-07-14 03:08:56 +00:00
Dave Wysochanski
3f4c43456f Add VG APIs to liblvm/.exported_symbols.
Add the following VG APIs to liblvm/.exported_symbols:
-lvm_reload_config
-lvm_vg_create
-lvm_vg_extend
-lvm_vg_set_extent_size
-lvm_vg_write
-lvm_vg_close
-lvm_vg_remove

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Acked-by: Alasdair G Kergon <agk@redhat.com>
2009-07-14 03:02:44 +00:00
Dave Wysochanski
10a3ba33a5 Add lvm_vg_* APIs to create and modify VGs.
Add some liblvm APIs for VGs.  Most of these APIs simply call into the internal
liblvm library.  Ideally we should call the liblvm functions directly from
the tools.  However, until we convert more of the code to liblvm functions,
things like the cmd_context will get in the way.  For now just implement the
liblvm functions as wrappers around the internal functions, with a little
error checking and return code handling.  We put all these vg APIs into a
new file, lvm_vg.c

The following APIs are implemented:
lvm_vg_create, lvm_vg_extend, lvm_vg_set_extent_size, lvm_vg_write,
lvm_vg_remove, lvm_vg_close.

Still TODO:
- cleanup error handling by using lvm_errno() and related APIs
- cleanup naming / clarify which functions commit to disk vs not
- implement more 'set' functions
- decide on 'set' / 'change' nomenclature

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Acked-by: Alasdair G Kergon <agk@redhat.com>
2009-07-14 03:02:14 +00:00
Dave Wysochanski
db0beacf02 Add default cmd->cmd_line initialization for liblvm lvm_create().
This needs initialized to non-NULL before using the archive() call.
Normally this is set to the cmdline string when lvm is called from a tool.
We could think about using it in another way, as a potential audit trail
of liblvm calls, or just leave it set to the default "liblvm", similar to
what clvmd does.  For now, just set it to "liblvm".

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Acked-by: Alasdair G Kergon <agk@redhat.com>
2009-07-14 03:01:18 +00:00
Dave Wysochanski
a07023d613 Define handles to liblvm objects for pv, vg, lv, lvseg, pvseg.
Define the 5 main liblvm objects to be the pv, vg, lv, lvseg, and pvseg.
We need handles defined to all these objects in order for liblvm to be
equivalent to the reporting commands pvs, vgs, and lvs.

- move vg_t, lv_t, and pv_t from metadata-exported.h into lvm.h
- move lv_segment and pv_segment forward declarations into lvm.h
- add lvseg_t and pvseg_t to lvm.h

NOTE: We currently have an inconsistency in handle definitions.
lvm_t is defined as a pointer, while these other handles are just
structures.  We should pick one scheme and be consistent - perhaps
define all handles as pointers (this is what I've seen elsewhere).

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Acked-by: Alasdair G Kergon <agk@redhat.com>
2009-07-14 03:00:30 +00:00
Dave Wysochanski
900c634af1 Remove READ_REQUIRE_RESIZEABLE flag from vg_read() interface - no users.
The checks for RESIZEABLE_VG should now be inside the various functions that
have to do such operations.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Acked-by: Alasdair G Kergon <agk@redhat.com>
2009-07-14 02:19:19 +00:00
Dave Wysochanski
48d9b570b9 Remove READ_REQUIRE_RESIZEABLE flag from vgsplit.
Remove READ_REQUIRE_RESIZEABLE flag from vgsplit similar to the removal from
vgextend.  Move the check inside the functions that actually move pvs from
one vg structure to another.  Should be no functional change.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Acked-by: Alasdair G Kergon <agk@redhat.com>
2009-07-14 02:16:05 +00:00
Dave Wysochanski
207ddca859 Refactor vgsplit - move move_pvs_used_by_lv and move_pv inside library.
In the future we may export these functions or something like them in liblvm
For now this helps in cleaning up the checks for RESIZEABLE since we can
use the internal library function vg_bad_status_bits.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Acked-by: Alasdair G Kergon <agk@redhat.com>
2009-07-14 02:15:21 +00:00
Dave Wysochanski
823b00705e Remove READ_REQUIRE_RESIZEABLE from vgextend by moving check inside vg_extend.
Move the check for the RESIZEABLE flag inside the vg_extend function.
When we consolidated the vg locking, reading, and status flag checking,
we tied the check for the RESIZEABLE flag to the vg_read() call.  The problem
with this is you cannot know what other APIs the application my or may not
call after a vg_read() call.  Thus the READ_REQUIRE_RESIZEABLE flag is not
really ideal - ideally we should be checking for this flag on a specific
operation, not inside the vg_read() call.  This patch moves one check inside
the library.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Acked-by: Alasdair G Kergon <agk@redhat.com>
2009-07-14 02:14:04 +00:00
mpatocka
4fb0ddedc7 WHATS_NEW 2009-07-13 23:16:17 +00:00
mpatocka
31b3571d31 Change exit() to _exit() in the child process. exit flushes stdio file buffers,
_exit doesn't. If there were some open files, an error in exec and subsequent
exit() would cause the buffers to be flushed twice.

Example:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main()
{
	printf("buu");
	if (!fork()) {
		execl("/bin/true-not-exists", "/bin/true", NULL);
		exit(1);
	}
	wait(NULL);
	return 0;
}

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com

---
 daemons/dmeventd/libdevmapper-event.c |    2 +-
 lib/misc/lvm-exec.c                   |    2 +-
 test/harness.c                        |    3 ++-
 tools/dmsetup.c                       |    2 +-
 4 files changed, 5 insertions(+), 4 deletions(-)
2009-07-13 21:26:41 +00:00
mpatocka
ee373a2721 Suppress warning on 64-bit big-endian computers (Sparc 64).
xlate64 produces unsigned long long type, but PRIu64 is defined
to accept argument unsigned long type (on 64-bit machines).

On existing machines, both types have the same size, so it works,
but it is still wrong and produces a warning.

Fix it by using a cast to uint64_t --- according to the standard,
PRIu64 argument matches type uint64_t.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
2009-07-13 21:23:48 +00:00
Alasdair Kergon
685bc7ae83 Make cmd->cmd_line const. 2009-07-13 19:49:48 +00:00
Petr Rockai
bc6772282f Get rid of the mdadm presence check in t-000-basic: no actual test uses
it. When we need mdadm in the tests, we can easily do 'which mdadm || exit 200'
to skip the test.
2009-07-13 12:42:26 +00:00
Alasdair Kergon
d0d0c1e5e5 Fix dev name mismatch in vgcreate man page example. 2009-07-13 11:25:35 +00:00
Dave Wysochanski
1ed598ada6 Remove unused code vg_lock_and_read() and related flags.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-10 21:19:37 +00:00
Dave Wysochanski
b003ae7270 Update WHATS_NEW for vgremove and ORPAHN_LOCK refactoring 2009-07-10 20:16:15 +00:00
Dave Wysochanski
18a4a3e21c Change lock ordering of vgcfgrestore to be consistent with other tools.
Orphan lock is now obtained second and released first, and all tools
are consistent in this regard.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-10 20:10:18 +00:00
Dave Wysochanski
72a41480ba Move orphan lock obtain/release inside vg_extend().
With this change we now have vgcreate/vgextend liblvm functions.
Note that this changes the lock order of the following functions as the
orphan lock is now obtained first.  With our policy of non-blocking
second locks, this should not be a problem.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-10 20:09:21 +00:00
Dave Wysochanski
6e221abda6 Move orphan lock inside vg_remove_single.
Move the vg orphan lock inside vg_remove_single, now a complete liblvm
function.  Note that this changes the order of the locks - originally
VG_ORPHAN was obtained first, then the vgname lock.  With the current
policy of non-blocking second locks, this could mean we get a failure
obtaining the orphan lock.  In the case of a vg with lvs being removed,
this could result in the lvs being removed but not the vg.  Such a
scenario could have happened prior though with a different failure.
Other tools were examined for side-effects, and no major problems
were noted.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-10 20:08:37 +00:00
Dave Wysochanski
e7d8b84581 Remove force parameter from vg_remove_single, now the liblvm function.
Move check for active LVs outside of library function.  The vgremove
liblvm function function will fail if there are active LVs.  It will
be the application's responsibility to check this condition and remove
the LVs individually before calling vgremove.  Note also that we've
duplicated the EXPORTED_VG check in vgremove_single (tools) and
vg_remove_single (library).  Duplication seemed the only option here
since we don't want to do the automatic removal of LVs (in the tools)
if the vg is exported, and we still need to protect the library call
from removal if the vg is exported.

We still need to deal with the ORPHAN lock but vg_remove_single is now
very close to our liblvm function.

TODO: Refactor lvremove in a similar way.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-10 20:07:02 +00:00
Dave Wysochanski
7a84430e84 Remove unnecessary parameters from vg_remove_single().
Use vg_t instead of struct volume_group.
Should be no functional change.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-10 20:05:29 +00:00
Alasdair Kergon
7e7274b002 Add dm_log_with_errno and dm_log_with_errno_init, deprecating the old
Change plog to use dm_log_with_errno unless deprecated dm_log_init was used.
Rename plog macro to LOG_LINE and use in dm_dump_memory_debug.
2009-07-10 09:59:37 +00:00
snitzer
e27183d54f Check MD devices for a partition table during device scan. 2009-07-09 22:50:45 +00:00
snitzer
f49c31ddb2 Add extended device (blkext) and MD partition (mdp) types to filters.
Both types were added with a 'max_partitions' of 1 because these devices
are _not_ partitionable (they are the partitions).
2009-07-09 22:34:02 +00:00
Milan Broz
ac959238aa Fix and precise metadata read errors for segment areas. 2009-07-09 11:29:41 +00:00
Milan Broz
563b6561a5 Fix confusing metadata syntax error messages.
If there is syntax error in metadata, it now prints messages
like:
  Couldn't read 'start_extent' for segment 'extent_count'.
  Couldn't read all logical volumes for volume group vg_test.

The segment specification is wrong and confusing.

Patch fixes it by introducing "parent" member in config_node which
points to parent section and config_parent_name function, which
provides pointer to node section name.

Also it adds several LV references where possible.
2009-07-09 11:29:00 +00:00
Milan Broz
bc26690cbf Fix segment import functions to print segment name and logical volume name. 2009-07-09 11:28:09 +00:00
Dave Wysochanski
4f56896f60 Update WHATS_NEW for recent vgcreate changes 2009-07-09 10:19:07 +00:00
Dave Wysochanski
5158d34c2d Change vg_create() to take only minimal parameters and obtain a lock.
vg_t *vg_create(struct cmd_context *cmd, const char *vg_name);
This is the first step towards the API called to create a VG.
Call vg_lock_newname() inside this function.  Use _vg_make_handle()
where possible.
Now we have 2 ways to construct a volume group:
1) vg_read: Used when constructing an existing VG from disks
2) vg_create: Used when constructing a new VG
Both of these interfaces obtain a lock, and return a vg_t *.
The usage of _vg_make_handle() inside vg_create() doesn't fit
perfectly but it's ok for now.  Needs some cleanup though and I've
noted "FIXME" in the code.

Add the new vg_create() plus vg 'set' functions for non-default
VG parameters in the following tools:
- vgcreate: Fairly straightforward refactoring.  We just moved
vg_lock_newname inside vg_create so we check the return via
vg_read_error.
- vgsplit: The refactoring here is a bit more tricky.  Originally
we called vg_lock_newname and depending on the error code, we either
read the existing vg or created the new one.  Now vg_create()
calls vg_lock_newname, so we first try to create the VG.  If this
fails with FAILED_EXIST, we can then do the vg_read.  If the
create succeeds, we check the input parameters and set any new
values on the VG.

TODO in future patches:
1. The VG_ORPHAN lock needs some thought.  We may want to treat
this as any other VG, and require the application to obtain a handle
and pass it to other API calls (for example, vg_extend).  Or,
we may find that hiding the VG_ORPHAN lock inside other APIs is
the way to go.  I thought of placing the VG_ORPHAN lock inside
vg_create() and tying it to the vg handle, but was not certain
this was the right approach.
2. Cleanup error paths. Integrate vg_read_error() with vg_create and
vg_read* error codes and/or the new error APIs.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-09 10:09:33 +00:00
Dave Wysochanski
5c63f0b7e3 Add vg_set_alloc_policy() liblvm function and move vgchange logic inside.
NOTE: vg_set_alloc_policy() returns success if you try to set a value that
is already stored.  The behavior of vgchange is the same though - it fails.
There is a fixme noted in the code about this inconsistency, which should
be resolved if possible.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-09 10:08:54 +00:00
Dave Wysochanski
1b3fa825f3 Add vg_set_max_pv() liblvm function and move vgchange logic inside.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-09 10:07:47 +00:00
Dave Wysochanski
ef182f4b64 Add vg_set_max_lv() liblvm function and move vgchange logic inside.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-09 10:06:00 +00:00
Dave Wysochanski
b706479c9b Rename vg_change_pesize to vg_set_extent_size and use vg_t.
In liblvm, we will reserve the word 'change' to mean an API that
both sets one or more values, and commits to disk.  This will be
consistent with the LVM commandline.  The existing vg_change_pesize()
function does not commit to disk, but just changes the extent_size
and ensures all internal structures are updated.  This logic should
be contained in a function that sets the value.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-09 10:04:52 +00:00
Dave Wysochanski
751c4fe7ef Remove unused 'cmd' from vg_change_pesize().
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-09 10:03:37 +00:00
Dave Wysochanski
d09baef532 Update vg_change_pesize() to contain all validity checks.
It would be nice to have one function that does all the validation
and setting of the VG's pesize.  However, currently some checks
are in the higher-level function _vgchange_pesize(), and some
checks are in the lower function vg_change_pesize().
This patch moves most of the higher-level checks inside
vg_change_pesize.  In one case a failure return code is
changed from ECMD_FAILED to EINVALID_CMD_LINE.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-09 10:02:15 +00:00
Dave Wysochanski
778244e436 Add defines for default vgcreate parameters. 2009-07-09 10:00:36 +00:00
Dave Wysochanski
f6cf83aebf Update t-vgcreate-usage.sh to check for default vg properties. 2009-07-09 08:50:55 +00:00
Dave Wysochanski
e6901382a6 Fix memory leak in vgsplit when re-reading the VG.
Call vg_release() before re-reading the vg.
Remove vgsplit whitespace and update copyright.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-09 05:40:59 +00:00
Dave Wysochanski
75c22b585e . 2009-07-08 22:22:12 +00:00
Dave Wysochanski
5018d3b5cb Make exit paths more robust when some init function fails.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-08 22:18:32 +00:00
Dave Wysochanski
9eeacf2cfc Refactor a couple log_error() statements in prep for larger log_error() patch.
Part of twoerner's log_error() patches.

Signed-off-by: Thomas Woerner <twoerner@redhat.com>
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-08 18:15:51 +00:00
Dave Wysochanski
9c25d59b82 Add t-lvm-init.sh - test lvm init routines and error paths. 2009-07-08 18:14:47 +00:00
Dave Wysochanski
4550133c81 Fix segfault in persistent_filter_dump() if lvm init fails.
Just return_0 in persistent_filter_dump() if passed a NULL filter;
2009-07-08 18:13:32 +00:00
Dave Wysochanski
8a5921e4bc Make destroy_toolcontext() better able to handle NULL pointers.
Part of twoerner's log_error() patches.

Signed-off-by: Thomas Woerner <twoerner@redhat.com>
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-08 18:12:08 +00:00
Dave Wysochanski
470aa36c91 Update WHATS_NEW for vgread cleanup 2009-07-08 14:41:00 +00:00
Dave Wysochanski
1fbcff5fcc Remove unneeded LOCK_NONBLOCKING from vg_read() API.
Remove unneeded LOCK_NONBLOCKING from vg_read() API and tools that
use it.  We no longer need this flag anywhere since we now automatically
set LCK_NONBLOCK inside lock_vol() if vgs_locked().
For further details, see:
commit d52b3fd3fe
Author: Dave Wysochanski <dwysocha@redhat.com>
Date:   Wed May 13 13:02:52 2009 +0000

    Remove NON_BLOCKING lock flag from tools and set a policy to auto-set.

    As a simplification to the tools and further liblvm, this patch pushes
    the setting of NON_BLOCKING lock flag inside the lock_vol() call.
    The policy we set is if any existing VGs are currently locked, we
    set the NON_BLOCKING flag.

At some point it may make sense to add this flag back if we get an
RFE from a liblvm user, but for now let's keep it as simple as
possible.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-08 14:33:17 +00:00
Dave Wysochanski
6fb06af9ff Remove READ_CHECK_EXISTENCE and vg_might_exist().
Remove READ_CHECK_EXISTENCE and vg_might_exist().
This flag and API is no longer used now that we have a separate
API to check for existence.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-08 14:31:17 +00:00
Dave Wysochanski
62941d65a9 Remove unneeded LOCK_KEEP from vg_read() interface.
Remove unneeded LOCK_KEEP from vg_read() interface.
Update comment to clarify cases where _vg_lock_and_read() may return
with an error but the lock held.  Would be nice to make the vg_read()
interface consistent with regards to lock held and error behavior.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-08 14:28:30 +00:00
Dave Wysochanski
18fe170698 Remove LOCK_KEEP and READ_CHECK_EXISTENCE from vgsplit.
Remove LOCK_KEEP and READ_CHECK_EXISTENCE from vgsplit.
These flags are no longer necessary.  We now check for existence
in a differnet function, and it is not necessary to keep the lock.
Removing these flags simplifies the new vg_read() interface.
After this patch, we can fully remove LOCK_KEEP.
READ_CHECK_EXISTENCE needs a bit more work before full removal.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-08 14:27:37 +00:00
Alasdair Kergon
c2cd4d5d15 Permit several segment types to be registered by a single shared object. 2009-07-08 12:36:01 +00:00
snitzer
69da2ac0c7 Continue to make --units and --size consistent (in code and man pages):
Update units_to_bytes() to support (S)ectors: 500 bytes.
- 500 byte (S)ectors is of questionable value but it adds to consistency
  if a user happens to use --units S.  This seems better than an error.

Updated test/t-covercmd.sh to test --units [hS]

Document the units that can be displayed via --units uniformly.
- (p)etabytes and (e)xabytes were missing in pvs, vgs and lvs man pages.

Made lvreduce man page "... in units of megabytes." consistent (with the
lvextend and lvresize man pages).
2009-07-07 19:28:57 +00:00
Alasdair Kergon
e08e69719d . 2009-07-07 17:19:38 +00:00
Alasdair Kergon
5628024d45 Fix whitespace in linear target line to fix identical table line detection.
(only tested with linear so far)
2009-07-07 16:36:05 +00:00
Dave Wysochanski
9d46d25d03 Fix compile warning in lvmcmdline.c - use C99 PRIu64 for uint64_t.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-07 01:51:00 +00:00
Dave Wysochanski
836326f31e Fix vg_read() error paths to properly release upon vg_read_error().
Fix vg_read() error paths to properly release upon vg_read_error().
Note that in the iterator paths (process_each_*()), we release
inside the iterator so no individual cleanup is needed.  However there
are a number of other places we missed the cleanup.  Proper cleanup
when vg_read_error() is true should be calling vg_release(vg), since
there should be no locks held if we get an error (except in certain
special cases, which IMO we should work to remove from the code).

Unfortunately the testsuite is unable to detect these types of memory
leaks.  Most of them can be easily seen if you try an operation
(e.g. lvcreate) with a volume group that does not exist.  Error
message looks like this:
  Volume group "vg2" not found
  You have a memory leak (not released memory pool):
   [0x1975eb8]
  You have a memory leak (not released memory pool):
   [0x1975eb8]


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-07-07 01:18:35 +00:00
snitzer
34fe80f9d9 Reword the WHATS_NEW commandline sizes update. 2009-07-06 19:17:15 +00:00
snitzer
15ae133662 Allow commandline sizes to be specified in terms of bytes and sectors.
Update the man pages to document size units uniformly.
2009-07-06 19:13:26 +00:00
snitzer
c405a5d5b3 Use the MD device's stripe-width, instead of chunk_size, to align the
data blocks of a Physical Volume that is placed directly upon an MD
device.
2009-07-06 19:04:24 +00:00
Alasdair Kergon
7acff3b938 Add device number to more log messages during activation. 2009-07-03 12:45:55 +00:00
Alasdair Kergon
7099be8f44 clarification 2009-07-03 11:04:06 +00:00
Dave Wysochanski
86e8c36a75 Update WHATS_NEW for vg_read commits 2009-07-01 17:23:10 +00:00
Dave Wysochanski
bc6fe86faa Fix t-inconsistent-metadata.sh.
Sun May  3 13:25:10 CEST 2009  Petr Rockai <me@mornfall.net>
  * All tools now handle inconsistent metadata the same way.

Rebase 6/26/09
2009-07-01 17:06:04 +00:00
Dave Wysochanski
3bcab11310 Add lvmcache_init() to polldaemon initialization.
Signed-off-by: Petr Rockai <me@mornfall.net>
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
2009-07-01 17:05:12 +00:00
Dave Wysochanski
3c8b92675f Convert vgsplit to use vg_read_for_update.
Sun May  3 13:12:28 CEST 2009  Petr Rockai <me@mornfall.net>
  * Convert vgsplit to use vg_read_for_update.


Author: Petr Rockai <prockai@redhat.com>
Committer: Dave Wysochanski <dwysocha@redhat.com>
2009-07-01 17:04:21 +00:00
Dave Wysochanski
0f19d74cb1 Don't segfault in vg_release when vg->cmd is NULL.
Sun May  3 13:06:14 CEST 2009  Petr Rockai <me@mornfall.net>
  * Don't segfault in vg_release when vg->cmd is NULL.


Author: Petr Rockai <prockai@redhat.com>
Committer: Dave Wysochanski <dwysocha@redhat.com>
2009-07-01 17:03:38 +00:00
Dave Wysochanski
d796a2a768 Convert vgrename to vg_read_for_update.
Sun May  3 12:54:28 CEST 2009  Petr Rockai <me@mornfall.net>
  * Convert vgrename to vg_read_for_update.

Rebased 6/26/2009 - Dave W.

Author: Petr Rockai <prockai@redhat.com>
Committer: Dave Wysochanski <dwysocha@redhat.com>
2009-07-01 17:02:18 +00:00
Dave Wysochanski
f962adbb52 Convert vgreduce to use vg_read_for_update.
Sun May  3 12:50:58 CEST 2009  Petr Rockai <me@mornfall.net>
  * Convert vgreduce to use vg_read_for_update.

Rebased 6/26/2009 - Dave W.
2009-07-01 17:01:46 +00:00
Dave Wysochanski
3479d0ee30 Rework the toollib interface (process_each_*) on top of new vg_read.
Sun May  3 12:32:30 CEST 2009  Petr Rockai <me@mornfall.net>
  * Rework the toollib interface (process_each_*) on top of new vg_read.

Rebased 6/26/09 by Dave W.
- Add skipping message to process_each_lv
- Remove inconsistent_t.
2009-07-01 17:00:50 +00:00
Dave Wysochanski
70a0590ece Convert the straight instances of vg_lock_and_read to new vg_read(_for_update).
Sun May  3 11:40:51 CEST 2009  Petr Rockai <me@mornfall.net>
  * Convert the straight instances of vg_lock_and_read to new vg_read(_for_update).

Rebased 6/26/09 by Dave W.
2009-07-01 16:59:37 +00:00
Alasdair Kergon
8414c57026 post-release 2009-07-01 09:31:46 +00:00
Alasdair Kergon
ae2e7f0603 update date 2009-06-30 18:41:47 +00:00
Alasdair Kergon
7177c3b393 pre-release tidy up 2009-06-30 18:39:31 +00:00
Dave Wysochanski
11f40ba93b Fix incomplete revert for lvconvert. 2009-06-26 11:29:06 +00:00
Alasdair Kergon
273511037a pre-release 2009-06-26 10:57:30 +00:00
Alasdair Kergon
56d64f23bf revert last patch - let's do a release first 2009-06-26 10:55:57 +00:00
Dave Wysochanski
cfbeca5e65 Convert the straight instances of vg_lock_and_read to new vg_read(_for_update).
Sun May  3 11:40:51 CEST 2009  Petr Rockai <me@mornfall.net>
  * Convert the straight instances of vg_lock_and_read to new vg_read(_for_update).


Author: Petr Rockai <prockai@redhat.com>
Committer: Dave Wysochanski <dwysocha@redhat.com>
2009-06-26 09:47:36 +00:00
Alasdair Kergon
aaf9b56084 Abort if automatic metadata correction fails when reading VG to update it. 2009-06-26 09:19:13 +00:00
Alasdair Kergon
e0a953e27e Abort operation if automatic metadata correction in lvconvert fails. 2009-06-26 09:03:59 +00:00
Milan Broz
f7c1e5f60d Fix backward compatibility for major:minor query.
Is an application uses query and set major:minor
to device, it should not fallback to default major by default.

Add new function whoich allows that (and use it in lvm2).
2009-06-17 20:55:24 +00:00
Milan Broz
84bf81ac31 Properly destroy toolcontext.
(fixes previous commit)
2009-06-17 20:54:20 +00:00
snitzer
6a67a8c574 Various vgimportclone fixes:
- validate the specified device is a PV and that it is in a VG
- automatically enable DEBUG (-d) if >= 4 -v instances were supplied
- preserve TMP_LVM_SYSTEM_DIR if it contains an lvm.conf and -d was
  specified
- fix handling of special-case where PV is listed as "unknown device"
- more descriptive error when a PV is missing ("unknown device")
- unset LVM_SYSTEM_DIR if it was not originally set
- skip final vgscan if no changes were made
2009-06-17 15:47:01 +00:00
Dave Wysochanski
0fad9eaee4 Cleanup pvs, vgs, and lvs "-o" section in man pages (rhbz 500861).
http://bugzilla.redhat.com/show_bug.cgi?id=500861
- Update list of fields/columns for each command (a few missing).
- Update list order to match "-o help" output (easier to verify field list)
- Add "{pv|vg|lv}_all" description.
- Move "-o help" sentence above column/field list.

New sample man page for lvs (pvs and vgs are similar):
       -o, --options
              Comma-separated ordered list of columns.  Precede the list  with  ’+’  to  append  to  the
              default selection of columns instead of replacing it.

              Use  -o  lv_all to select all logical volume columns, and -o seg_all to select all logical
              segment columns.

              Use -o help to view the full list of columns available.

              Column names  include:  lv_uuid,  lv_name,  lv_attr,  lv_major,  lv_minor,  lv_read_ahead,
              lv_kernel_major,  lv_kernel_minor,  lv_kernel_read_ahead, lv_size, seg_count, origin, ori-
              gin_size, snap_percent, copy_percent, move_pv, convert_lv, lv_tags,  mirror_log,  modules,
              segtype,  stripes,  stripesize,  regionsize, chunksize, seg_start, seg_start_pe, seg_size,
              seg_tags, seg_pe_ranges, devices.

              With --segments, any "seg_" prefixes  are  optional;  otherwise  any  "lv_"  prefixes  are
              optional.  Columns mentioned in vgs (8) can also be chosen.

              The lv_attr bits are:
2009-06-15 17:09:32 +00:00
Milan Broz
d64d33ed07 Add WHATS_NEW items. 2009-06-15 15:09:02 +00:00
Petr Rockai
0e8fdf49d0 - Ignore suspended devices during repair (Milan).
- Call vgreduce --removemissing (without --force) automatically to clean up bad
  PVs (Milan).
2009-06-15 14:47:39 +00:00
Milan Broz
f147256697 Suggest use lvchange --resync when up converting not yet synced mirror. 2009-06-15 13:43:15 +00:00
Milan Broz
dbe275ce72 Do not fork daemon when dmeventd cannot be found. 2009-06-15 12:29:41 +00:00
Milan Broz
649cd608c1 Destroy toolcontext on exit in clvmd (fixes memory pool leaks). 2009-06-15 12:15:23 +00:00
Milan Broz
87c63e995b Fix lvconvert to not poll mirror if no conversion in progress. 2009-06-15 12:08:59 +00:00
Milan Broz
cd49c5bf66 Fix memory leaks in toolcontext error path.
E.g.
 # vgscan
  Parse error at byte 2360 (line 54): expected a value
  Failed to load config file /etc/lvm/lvm.conf
You have a memory leak (not released memory pool):
 [0x818c788] library (12 bytes)

...
2009-06-15 11:56:31 +00:00
Milan Broz
c3ca9468d1 Fix WHATS_NEW - Allow metadata correction even when PVs are missing. 2009-06-12 08:34:15 +00:00
Milan Broz
89576aa2c1 Re-instate partial activation support in clustered mode. (mornfall) 2009-06-12 08:30:19 +00:00
Petr Rockai
630dbab749 Allow metadata correction even when PVs are missing. 2009-06-10 20:17:32 +00:00
Dave Wysochanski
8e95a2a603 In the new _vg_read_for_update(), we always do the check for CLUSTERED vg
status flag after reading the volume group.  Thus, no need to set the flag
in vg_read() or clear it later before calling _vg_bad_status_bits().

Also, add back in the !lockingfailed() as part of the CLUSTERED flag check.
It's unclear why it was removed when the check was moved from
_vg_bad_status_bits() to inside _vg_lock_and_read().
There was an open question about the last check in the 'if' stmt for
lockingfailed() with a previous patch submitted.  However, I would
defer that right now as it is a separate item and this patch should
be no functional change by including the !lockingfailed().

Petr acked this patch on 5/26 I just forgot to check it in.

Acked-by: Petr Rockai <prockai@redhat.com>
2009-06-10 16:14:40 +00:00
Petr Rockai
6a1c94d48d Complain when lvconvert --repair is used on non-mirror LV. 2009-06-10 15:27:57 +00:00
Milan Broz
578a9a3332 Fix compiler warning. 2009-06-10 11:21:10 +00:00
Milan Broz
122fe8a20d Unlock VG in recover_vg if metadata read failed. 2009-06-10 11:15:29 +00:00
Milan Broz
d32f607aba Unlock vg when requested automatic update failed.
(fixes previous commit)
2009-06-10 10:15:28 +00:00
Milan Broz
25d9591416 Support crypt segment in libdevmapper tree.
- it can support multiple segments, but note that
to work properly, correct IV (initialization vector)
offset parameter must be set properly.

Because most usage of IV start offset is when we join
several crypto segments together (so iv_offset is the segment
start offset), DM_CRYPT_IV_DEFAULT is defined to simplify
the process.

Function accepts the string in cipher agrument (already
including chainmode and iv type; chainmode and iv parameters are NULL
in this case) or user can provide split parameters which will
join into dm-crypt cipher specification "cipher-chainmode-iv".

All these parameters must be supplied in correct dm-crypt format.
2009-06-09 16:10:20 +00:00
Zdeněk Kabeláč
33f41cc68b Use 'lvm lvresize' instead of 'lvresize' in fsadm.
Do not use '-n' realine option in fsadm for busybox compatiblity.
2009-06-09 15:31:36 +00:00
Dave Wysochanski
d8bee53822 Update WHATS_NEW 2009-06-09 14:43:59 +00:00
Dave Wysochanski
0866f47904 Update vgsplit to use new vg_reserve_newname() function. 2009-06-09 14:31:20 +00:00
Dave Wysochanski
d230325569 Update vgcreate to use new vg_lock_newname(). 2009-06-09 14:30:44 +00:00
Dave Wysochanski
8e7930a604 Update vgrename to use vg_lock_newname. 2009-06-09 14:30:16 +00:00
Dave Wysochanski
1dde89db69 Add vg_lock_newname() library function.
Various tools need to check for existence of a VG before doing something
(vgsplit, vgrename, vgcreate).  Currently we don't have an interface to
check for existence, but the existence check is part of the vg_read* call(s).
This patch is an attempt to pull out some of that functionality into a
separate function, and hopefully simplify our vg_read interface, and
move those patches along.

vg_lock_newname() is only concerned about checking whether a vg exists in
the system.  Unfortunately, we cannot just scan the system, but we must first
obtain a lock.  Since we are reserving a vgname, we take a WRITE lock on
the vgname.  Once obtained, we scan the system to ensure the name does
not exist.  The return codes and behavior is in the function header.
You might think of this function as similar to an open() call with
O_CREAT and O_EXCL flags (returns failure with -EEXIST if file already
exists).

NOTE: I think including the word "lock" in the function name is important,
as it clearly states the function obtains a lock and makes the code more
readable, especially when it comes to cleanup / unlocking.  The ultimate
function name is somewhat open for debate though so later we may rename.
2009-06-09 14:29:10 +00:00
Milan Broz
350d0a6495 Fix the same readahead rounding in lvcreate.
(fixes previous commit)
2009-06-06 22:06:54 +00:00
Milan Broz
42e922d587 Round readahead more inteligently and print warning.
Round readahead at least to one page up.
Print warning instead of verbose message.
2009-06-06 22:00:20 +00:00
Milan Broz
57c002f324 Fix various problems in tests
- PPC uses 64k page, some caculations are wrong in tests
- file utility is buggy on PPC and cannot detect swap, use blkid instead
- read ahead is quietly rounded down according to page size
(for now use some common divisor value in test)
2009-06-06 16:40:39 +00:00
Milan Broz
e5fb684ac1 Suspend virtual origin before real snapshot.
Because preload of table for snapshot can produce snapshot
metadata (in kernel cow header) read.

Code should suspend origin first to avoid possible deadlock
when preloading (thus calling snapshot in-kernel constructor)
for origin with suspended cow device.

(fixes previous commit)
2009-06-06 16:37:15 +00:00
Milan Broz
84abdc7b2d Fix double releasing of vg when repairing of vg is requested.
Several commands calls process_each_vg() and in provided
callback it explicitly recovers VG if inconsistent.
(vgchange, vgconvert, vgscan)

It means that old VG is released and reread  but the function
above (process_one_vg) tries to unlock and release old VG.

Patch moves the repair logic into _process_one_vg() function.

It always tries to read vg (even inconsistent) and then decides
what to do according new defined parameter.

Also patch unifies inconsistent error messages.

The only slight change if for vgremove command, where
it now tries to repair VG before it removes if force arg is given.
(It works similar way before, just the order of operation changed).
2009-06-05 20:00:52 +00:00
Dave Wysochanski
db79a4a14b Add vgrename test to check for existence of new vg. 2009-06-05 10:42:22 +00:00
Alasdair Kergon
f1b30c5aff test commit 2009-06-04 13:23:10 +00:00
Alasdair Kergon
4db2593801 test commit 2009-06-04 13:16:49 +00:00
Alasdair Kergon
ad685d2153 test commit 2009-06-04 13:11:58 +00:00
Milan Broz
cf9dd7cf5e Use lvconvert --repair instead of vgreduce in mirror dmeventd DSO (mornfall)
Introduce lvconvert --use_policies (mornfall)
2009-06-04 12:01:15 +00:00
Alasdair Kergon
f10d82dc30 Add splitname. 2009-06-03 20:44:42 +00:00
Alasdair Kergon
5ec942fb2a Add subsystem, vg_name, lv_name, lv_layer fields to dmsetup reports. 2009-06-03 18:35:39 +00:00
Christine Caulfield
2897cfb556 Fix clvmd-corosync to match the new corosync API. 2009-06-03 13:42:02 +00:00
Milan Broz
5484869af9 WHATS_NEW! 2009-06-03 11:49:05 +00:00
Alasdair Kergon
90cc3a0f05 Make mempool optional in dm_split_lvm_name() 2009-06-03 11:40:23 +00:00
Milan Broz
99e45f71c2 Build shared parts with 'make' command (mpatocka)
When some parts of lvm are built as shared libraries (for example with
--with-snapshots=shared), the 'make' command does not build these parts.
The shared parts are built with 'make install' command.

This bug can be seen if you go to 'lib' subdirectory and type 'make'.
If you type 'make', the shared libraries are not built, if you type
'make all', the shared libraries are built.

The reason for the bug is the line $(SUBDIRS): $(LIB_STATIC)
If make is executed without any arguments, it makes the first target
in the Makefile. If the first target is '$(SUBDIRS): $(LIB_STATIC)',
it only builds static libraries.

This patch moves '$(SUBDIRS): $(LIB_STATIC)' after
include $(top_srcdir)/make.tmpl. make.tmpl contains the 'all' target
as its first target, so 'make' will be equivalent to 'make all' and
shared libraries will be build with 'make' command.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
2009-06-03 11:31:06 +00:00
Milan Broz
488d246ada Fix rename of active snapshot with virtual origin.
Code must suspend/resume virtual origin too when renaming
snaphsot otherwise in kernel old name remains.
2009-06-01 15:55:06 +00:00
Milan Broz
8189910b5a Fix convert polling to ignore LV with different UUID.
When mirror convert polling is started (mainly as backgound process,
in lvchange -a y or in lvconvert itself) it tries to read VG
and LV identified by its name.

Unfortunatelly, the VG can have already different LV under the same name,
and various more or less funny things can happen (note that
_finish_lvconvert_mirror suspends the volume for example).

(the typical example is our testing script which continuously recreates
LVs under the same name in the same VG.)

This patch adds optional uuid parameter which helps to properly
select the monitoring object. For lvconvert polling it is set to LV UUID
and both _get_lvconvert_vg and _get_lvconvert_lv uses it to read proper VG/LV.

(In the pvmove case it is NULL, here we poll for physical volume name).
2009-06-01 14:43:27 +00:00
Milan Broz
de317b8e01 Fix log allocation segfault (fix previous commits).
If there is no free area for log, code should break the loop.
(Otherwise it uses uninitializes areas later.)

Easily reproducible using lvconvert --repair
 - kill device with log
 - run lvconvert --repair vg/lv (with no PV usable for log)
2009-06-01 14:23:38 +00:00
Milan Broz
436cf94595 Fix readahead calculation problems.
During vgreduce is failed mirror image replaced with error segment,
this segmant type has always area_count == 0.
Current code expects that there is at least one area with device,
patch fixes it by additional check (fixes segfault during vgreduce).

Also do not calculate readahead in every lv_info call, we only need
to cache PV readahead before activation calls which locks memory.
2009-06-01 12:43:31 +00:00
Alasdair Kergon
145c999762 Remove verbose 'visited' messages. 2009-05-30 01:54:29 +00:00
Alasdair Kergon
c82b46032a Handle multi-extent mirror log allocation when smallest PV has only 1 extent. 2009-05-30 00:09:27 +00:00
snitzer
cf9fa94eaa Fix 'service-default-enabled' rpmlint in clvmd initscript 2009-05-29 18:54:48 +00:00
snitzer
d5139fef22 Fix rpmlint in clvmd initscript
Added missing LSB stanza lines.
Added reload capability.
Remaining warning (incoherent-init-script-name) is not relevant.
2009-05-29 18:34:10 +00:00
Alasdair Kergon
f8964db41c When creating new LV, double-check that name is not already in use. 2009-05-28 01:59:37 +00:00
Alasdair Kergon
052169695c Remove /dev/vgname/lvname symlink automatically if LV is no longer visible. 2009-05-28 01:11:29 +00:00
Alasdair Kergon
f9a8a94fd1 Rename internal vorigin LV to match visible LV. 2009-05-28 00:29:14 +00:00
Alasdair Kergon
880d9bb33f Suppress 'removed' messages displayed when internal LVs are removed.
Fix lvchange -a and -p for sparse LVs.
Fix lvcreate --virtualsize to activate the new device immediately.
2009-05-27 18:19:21 +00:00
Alasdair Kergon
68aa3eb1b9 Make --snapshot optional with lvcreate --virtualsize.
Generalise --virtualoriginsize to --virtualsize.
2009-05-27 16:30:29 +00:00
Alasdair Kergon
39dbb9dad8 Skip virtual origins in process_each_lv_in_vg(). (mbroz) 2009-05-27 13:23:41 +00:00
Alasdair Kergon
ac7acf2441 Fix counting of virtual origin LVs in vg_validate. (mbroz) 2009-05-27 13:19:34 +00:00
Alasdair Kergon
87ce5770b7 0->NULL (mbroz) 2009-05-27 13:07:37 +00:00
Alasdair Kergon
24f3c8c29e Attempt to load dm-zero module if zero target needed but not present. (mbroz) 2009-05-27 13:05:53 +00:00
Alasdair Kergon
cf578d50ec post-release 2009-05-22 15:23:10 +00:00
Milan Broz
6c2e4110ad Temporary disable one of lvconvert tests. 2009-05-22 14:56:17 +00:00
Alasdair Kergon
01280bbd06 Rename liblvm.so to liblvm2app.so and use configure --enable-applib. 2009-05-22 14:44:59 +00:00
Alasdair Kergon
0f1b7a527b Reinstate version in liblvm2cmd.so soname. (2.02.44) 2009-05-21 11:11:29 +00:00
Alasdair Kergon
965c7e1200 Pre-release cleanups. 2009-05-21 03:04:52 +00:00
Alasdair Kergon
abea4f481c Missing entries. 2009-05-20 22:44:10 +00:00
Alasdair Kergon
71191eae5c Revert:
Use lvconvert --repair in dmeventd mirror DSO.
for now.

It replaces bad behaviour in one set of circumstances with bad behaviour
in a different set.  We think the behaviour needs to be more configurable.
2009-05-20 22:24:48 +00:00
Milan Broz
03d4efc5c0 Fix locking query compatibility with old external locking libraries. 2009-05-20 12:58:03 +00:00
Milan Broz
22c38019b2 Fix readahead test. 2009-05-20 11:27:14 +00:00
Milan Broz
7cd8194c99 Use readahead of underlying device and not default (smaller) one.
When we are stacking LV over device, which has for some reason
increased read_ahead (e.g. MD RAID), the read_ahead hint
for libdevmapper is wrong (it is zero).

If the calculated read_ahead hint is zero, patch uses read_ahead of underlying device
(if first segment is PV) when setting DM_READ_AHEAD_MINIMUM_FLAG.

Because we are using dev-cache, it also store this value to cache for future use
(if several LVs are over one PV, BLKRAGET is called only once for underlying device.)

This should fix all the reamining problems with readahead mismatch reported
for DM over MD configurations (and similar cases).
2009-05-20 11:09:49 +00:00
Milan Broz
b4747ad67f Use lock query instead of activate_lv_excl
- switch lvremove to not force activate volume when removing
 - ditto for force resync

 - fix some wrong return codes in lvchange_resync()
2009-05-20 09:55:33 +00:00
Milan Broz
bb6db55686 Use suspend with flush when device size was changed during table preload.
This allows online mirror resize, also removes condition to preventing
code to do this.
2009-05-20 09:52:37 +00:00
Dave Wysochanski
244cd8f94f Add test - lvconvert from linear (on multiple PVs) to mirror. 2009-05-19 15:47:50 +00:00
Milan Broz
ba856910e0 Add infrastructure for queriying for remote locks.
Current code, when need to ensure that volume is not
active on remote node, it need to try to exclusive
activate volume.

Patch adds simple clvmd command which queries all nodes
for lock for given resource.

The lock type is returned in reply in text.

(But code currently uses CR and EX modes only.)
2009-05-19 10:38:58 +00:00
Milan Broz
d00e023894 Fix lvconvert check for multiple-segment mirrors (mornfall) 2009-05-19 10:27:47 +00:00
Milan Broz
86b4b128a9 Use lvconvert --repair in dmeventd DSO (mornfall)
This means two things:

1) Non-mirrored LVs will be no longer affected by mirror monitoring. (Before,
if you had a LV that went partially missing on a VG where a mirror leg failed,
this LV would be removed automatically by dmeventd... Probably not an
unrecoverable dataloss bug, but still quite unpleasant.)

2) If enough parallel PV space is available at the time of the mirror failure,
the failed devices will be automatically replaced using this spare space. Which
(and whether) free space may be used is still not configurable, but is a
planned feature. Since it is relatively easy to undo the action by converting
the mirror manually, I don't consider this to be a showstopper. In fact, I
think the compromise is much better than what we have now.
2009-05-19 10:25:16 +00:00
Milan Broz
35bd06a9a0 Fix compilation warning. 2009-05-19 10:12:41 +00:00
Milan Broz
bdc7574fd5 If pvmove fails activating mirror volume, try restore to previous state.
pvmove now keep suspended devices if temporary mirror creation fails.

We can try to restore previous state if it is first attempt to activate
pvmove (code basically run the same code as --abort automatically).
2009-05-19 09:51:02 +00:00
Milan Broz
a7cac2463c Use PV UUID in hash for device name when exporting metadata.
Currently code uses pv_dev_name() for hash when getting internal
"pvX" name.

This produce corrupted metadata if PVs are missing, pv->dev
is NULL and all these missing devices returns one name
(using "unknown device" for all missing devices as hash key).
2009-05-19 09:48:32 +00:00
Milan Broz
474bc8823e vgcfgrestore should not quietly fail when backup file has missing PVs.
(fixes previous commit: Fix segfault for vgcfgrestore on VG with missing PVs.)
2009-05-19 09:45:33 +00:00
snitzer
95f6b0c06e Add vgimportclone and install it and the man page by default. 2009-05-14 16:46:12 +00:00
Milan Broz
dc205333cd Check max_lv on only place and force the check only for new volume.
We can temporarily violate max_lv during mirror conversion etc.

(If the operation fails, orphan mirror images are visible to administrator
for manual remove for example. Not that this should ever happen:-)

Force limit only for lvcreate (and vg merge) command.

Patch also adds simple max_lv tests into testsuite
2009-05-13 21:29:10 +00:00
Milan Broz
4de96ea715 Remove unneeded import parameter from lv_create_empty. 2009-05-13 21:28:31 +00:00
Milan Broz
c94f02648c Merge lv_is_displayable and lv_is_visible.
Displayable and visible is the same thing.

volumes_count(vg) is now vg_visible_lvs() and always
returns number of LVs from user perspective.
2009-05-13 21:27:43 +00:00
Milan Broz
2ba0dd20fb Introduce lv_set_visible & lv_set_invisible and use lv_is_visible always.
The vg->lv_count parameter now includes always number of visible
logical volumes.

Note that virtual snapshot volume (snapshotX) is never visible,
but it is stored in metadata with visible flag.
2009-05-13 21:26:45 +00:00
Milan Broz
389dc22856 Fix lv_is_visible to handle virtual origin.
Snapshot is visible if its origin is marked visible,
or if the origin is virtual.
2009-05-13 21:25:45 +00:00
Milan Broz
823c8af1ab Introduce link_lv_to_vg and unlink_lv_from_vg functions.
link_lv_to_vg and unlink_lv_from_vg are the only functions
for adding/removing logical volume from volume group.

Only these function should manipulate with vg->lvs list.
2009-05-13 21:25:01 +00:00
Milan Broz
286562d202 Tidy format1 import LV function.
Later patch initializes lv->vg after the LV structure is prepared,
so pass through cmd context and do not use vg->cmd here.
Also move LV id calculation (which uses lv->vg too).

Also properly free memory pool if operation fails.
2009-05-13 21:24:12 +00:00
Milan Broz
b83a1876ba Remove vg->lv_count and use counter function.
This should not cause problems but simplifies code a lot.

(the volumes_count is merged and renamed with lvs_visible
function by following patch.)
2009-05-13 21:22:57 +00:00
Milan Broz
ed2a931ae3 Fix snapshot segment import to not use duplicate segments & replace.
The snapshot segment (snapshotX) is created twice
during the text metadata segment processing.

This can cause temporary violation of max_lv count.

Simplify the code, snapshot segment is properly initialized
in init_snapshot_seg function now and do not need to be replaced
by vg_add_snapshot call.

The vg_add_snapshot() is now usefull only for adding new
snapshot and it shares the same initialization function.

The snapshot name is always generated, name paramater can be
removed from function call.
2009-05-13 21:21:58 +00:00
Dave Wysochanski
f77190f477 Update test-utils to cope with ":" in device names and allow configurable names. 2009-05-13 19:18:47 +00:00
Zdeněk Kabeláč
2d3335fa48 Do not query nonexistent devices for readahead. 2009-05-13 14:13:54 +00:00
Dave Wysochanski
d52b3fd3fe Remove NON_BLOCKING lock flag from tools and set a policy to auto-set.
As a simplification to the tools and further liblvm, this patch pushes
the setting of NON_BLOCKING lock flag inside the lock_vol() call.
The policy we set is if any existing VGs are currently locked, we
set the NON_BLOCKING flag.

Should be no functional change.
2009-05-13 13:02:52 +00:00
Alasdair Kergon
5a945afdc6 better variable name for snapshot counting 2009-05-13 01:48:18 +00:00
Milan Broz
8b65ad0237 Remove snapshot_count from VG and use function instead. 2009-05-12 19:12:09 +00:00
Milan Broz
6d74246c91 Fix first_seg() call for empty segment list.
The seg variable is temporary variable for list iterator,
code cannot expect that after iteration it remains NULL
(it contains non-NULL pointer here id list is empty).

Patch fixes first_seg function so it now correctly returns NULL
for empty segment list.
2009-05-12 19:09:21 +00:00
Dave Wysochanski
9d81c953c3 Update t-read-ahead.sh to validate lv_read_ahead and lv_kernel_read_ahead.
- check default values
- check active/inactive values
2009-05-11 16:17:12 +00:00
Milan Broz
97e41de23f Fix previous commit (scripts/Makefile targets order) 2009-05-11 10:35:00 +00:00
Milan Broz
d57543b220 Introduce lvm2_install target.
Buildsystem support device-mapper only install,
but generic install tagret includes both dm+lvm2.

For distribution which uses separate install_device-mapper,
there is no way how to install lvm2 only
(so after installing lvm2 for packaging purposes
built system must remove installed device-mapper files).

Fix it by allowing lvm2_install target, similarily like
install_cluster for clvmd.

(install = install_device-mapper + install_lvm2)
2009-05-11 10:28:45 +00:00
Milan Broz
13cd91bffb Fix device-mapper static build targets.
dmsetup.static is not built and cleaned properly
if running only device-mapper install/build.
2009-05-11 10:13:28 +00:00
Milan Broz
2d170dfed8 Do not use generic install if running install_device-mapper.
It propagates into subdirs which includes DSOs which requires
lvm2 build (only install_device-mapper should propagate there).
2009-05-11 10:12:35 +00:00
Dave Wysochanski
744ac0eb81 Add test for seg_start, seg_count, seg_start_pe 2009-05-11 03:37:34 +00:00
Petr Rockai
057983ce3e Update WHATS_NEW wrt a recent patch. 2009-05-09 13:47:03 +00:00
Dave Wysochanski
aadc34ab4d Update tests for region_size. 2009-05-08 21:50:20 +00:00
Dave Wysochanski
d9c4af46ed Add tests to check pv_mda_size and vg_mda_size. 2009-05-08 06:10:45 +00:00
Dave Wysochanski
cdd0024bad Add tests to check vgcreate --physicalextentsize and field vg_extent_size. 2009-05-08 05:15:52 +00:00
Dave Wysochanski
6e331c523f Validate chunksize and originsize for snapshots. 2009-05-08 04:24:52 +00:00
Milan Broz
f7712c77b8 Fix PV datalign when for values starting prior to MDA area.
The dataalign value must always be aligned according
to MDA area.
The currect code checks if calculated value collides with
MDA area but not if the value is so small that it is
located before MDA starts.

Unfortunatelly there can be also MDA in the end of the device.

The patch adds simple check to avoid this miscalculation.
Patch expects that first MDA always starts on <= pagesize boundary
(this is true for all allowed label sector parameters).
2009-05-07 12:11:50 +00:00
Milan Broz
fd436c316a Use zalloc in initialization of device manager (to zero pvmove mirror count). 2009-05-07 12:01:21 +00:00
Dave Wysochanski
7120f7df54 Update columns.h comment. 2009-05-06 15:25:23 +00:00
Dave Wysochanski
1d30bf8af4 Fixup whitespace. 2009-04-29 20:14:21 +00:00
Dave Wysochanski
40c70e12dd Fixup whitespace. 2009-04-29 20:11:46 +00:00
Dave Wysochanski
31b6eb916f Use liblvm.so instead of .a 2009-04-28 19:08:25 +00:00
Dave Wysochanski
09e7a582de Fix error path in vg_make_handle().
Enter the error condition if either of the allocations fail, and
don't use dm_pool_zalloc if dm_pool_create fails.
2009-04-28 17:46:47 +00:00
Peter Rajnoha
b8aec00dee Fix wrong arg in lv_is_virtual_origin call while creating snapshots. 2009-04-26 08:12:12 +00:00
Alasdair Kergon
174f5a3a49 Add sparse devices: lvcreate -s --virtualoriginsize (hidden zero origin).
Add lvs origin_size field.
Fix linux configure --enable-debug to exclude -O2.

Still a few rough edges, but hopefully usable now:
  lvcreate -s vg1 -L 100M --virtualoriginsize 1T
2009-04-25 01:17:59 +00:00
Alasdair Kergon
758d469679 Fix linux configure --enable-debug to exclude -O2. 2009-04-24 21:44:15 +00:00
Milan Broz
542bdaa740 Fix pool leak in lvmcache_read_vg error path.
(Introduced in previous patches.)
2009-04-24 12:03:55 +00:00
Peter Rajnoha
14bd66805e Fix segfault when using -U, -G and -M options in dmsetup. 2009-04-24 11:30:49 +00:00
Petr Rockai
01c2d76c54 Avoid scanning non-PV devices in functional tests, otherwise lvconvert --repair
breaks for some reason -- possibly needs investagation, but this should fix it
in the meantime.
2009-04-24 08:00:48 +00:00
Petr Rockai
40cd0b1dd2 Implement, test and document (first iteration of) lvconvert --repair. 2009-04-23 16:56:21 +00:00
Petr Rockai
5dad791818 Refuse adding missing PVs in create_pv_list in toollib when allocatable_only is
requested.
2009-04-23 16:45:30 +00:00
Petr Rockai
3743a6858b A more thorough PV equality test (that also copes better with MISSING_PVs) in
_is_mirror_image_removable.
2009-04-23 16:43:01 +00:00
Petr Rockai
409a8d3678 Do not include MISSING_PVs in allocation maps. 2009-04-23 16:41:27 +00:00
Dave Wysochanski
94084178d9 Update columns.h comment to describe macro args. 2009-04-23 16:27:58 +00:00
Alasdair Kergon
3c80245275 fix typo reported by "A. Costa" <agcosta@gis.net> 2009-04-23 12:20:15 +00:00
Milan Broz
16c4b2a572 Fix vgreduce --removemissing failure exit code. 2009-04-22 17:00:28 +00:00
Dave Wysochanski
0cf1e72ed1 Remove some trailing whitespace so git won't complain. 2009-04-22 12:46:25 +00:00
Milan Broz
029346d322 Clean a lot of extra extra whitespaces. 2009-04-22 10:38:16 +00:00
Milan Broz
9e959f9bdd Fix remote metadata backup for clvmd
Run backup of metadata on remote nodes in the
same place like local node - when calling backup().

Introduce backup_locally() which calls only
local backup if needed.

Remote backup is now trigerred by LCK_VG_BACKUP flag
combination (special VG lock).

This lock type will call check_current_backup()
(including backup_locally() call) and updates
metadata on all nodes.

(Patch fixes non-functional remote backup,
current call during VG lock never triggers.)
2009-04-22 09:39:45 +00:00
Milan Broz
3ec8c63e28 Alloc PV internal structure from VG mempool if possible. 2009-04-22 09:31:30 +00:00
Jonathan Earl Brassow
ceeb1eca9d - Updating cluster log with latest code changes/bug fixes before
altering to new kernel structures.
2009-04-21 19:16:22 +00:00
Milan Broz
5800560602 Move metadata backup call after vg_commit.
The backup() call store metadata from memory.

But in cluster backup() call performs
remote nodes metadata backup and it reads data from disk.

For metadata backup consistency,
patch moves all backup() calls after vg_commit.

(Moreover, some tools already do that this way.)
2009-04-21 14:31:57 +00:00
Milan Broz
a840a56e02 Tidy lv_hash[_lock] use inside clvmd.
- Rename unlock_all to destroy_lvhash,
this function is called in cluster shutdown
unlocks everything and clean up allocated info space.

 - Tidy lv_hash_lock use
.
Except adding free(lvi) in lv_has destructror
there is no functional change.
2009-04-21 13:11:28 +00:00
Milan Broz
8704f4e24e Fix pvseg report for orphan PVs and other devices.
If user requests report attribute from PVSEG type
and PV is orphan (or all devices is set), the report
is empty.

Try for example (when only orphan PV are present)
 #pvs
 #pvs -o +devices
# pvs /dev/sdb1
  PV         VG   Fmt  Attr PSize  PFree
    /dev/sdb1       lvm2 --   46.58G 46.58G
# pvs -o +devices /dev/sdb1
(no output)

The problem is caused by empty pv->segments list.

Fix it by providing fake segment here (similar to fake structures
in _pvsegs_sub_single() calls.
2009-04-21 12:59:18 +00:00
Milan Broz
459a5a5b1f Fix pvs -a for segmented output
# pvs -a -o devices
   Volume group name (null) has invalid characters
   Skipping volume group (null)

...
_pvsegs_sub_single creates fake vg, we need to check
that pv is real here.
2009-04-21 12:57:31 +00:00
Dave Wysochanski
afc28c54ac Add libdevmapper to test/api building. 2009-04-20 20:46:06 +00:00
Milan Broz
6772b45ea6 Add MMC device type to filters. 2009-04-16 10:16:14 +00:00
Milan Broz
7defd4dab0 Fix dmsetup.static build. 2009-04-15 14:42:27 +00:00
Milan Broz
db326a14b3 Properly release VG memory pool in all CLI tools. 2009-04-10 10:01:38 +00:00
Milan Broz
0abf2e237e Properly release VG memory pool in metadata manipulation code. 2009-04-10 10:01:08 +00:00
Milan Broz
d3a2b52363 Properly release VG memory pool in archiver code. 2009-04-10 10:00:37 +00:00
Milan Broz
de81594179 Properly release VG memory pool in activation code and clvmd. 2009-04-10 10:00:04 +00:00
Milan Broz
06bdf8b461 Introduce memory pool per volume group.
Since now, all code reading volume group is responsible for releasing
the memory allocated by calling vg_release(vg).
(For simplicity of use, vg_releae can be called for vg == NULL,
the same logic like free(NULL)).

Also providing simple macro for unlocking & releasing in one step,
tools usualy uses this approach.

The global memory pool (cmd->mem) should be used only for global
physical volume operations.

This patch have to be applied with all subsequent patches to complete
memory pool per vg logic.

Using separate memory pool has quite bit memory saving impact when
using large VGs, this is mainly needed when we have to use
preallocated and locked memory (and should not overflow from that
memory space).
2009-04-10 09:59:18 +00:00
Milan Broz
d784303591 Helper function to catch memory pool leaks. 2009-04-10 09:56:58 +00:00
Milan Broz
52d2c31427 Properly copy the whole pv structure for later use.
The all_pvs list, used in vg_read, should make its own private
copy of pv structures, otherwise (when vg will use its own pool)
it will point to released memory pool.
The same applies for get_pvs() call.

Patch adds pv_list copy helper and adds explicit memory pool
parameter into _copy_pv.

(Please note that all these helper functions cannot guarantee that
vg related fields are valid - proper vg read & lock must be used
if it is requested.)
2009-04-10 09:56:00 +00:00
Milan Broz
9bc8e56458 Always return exit error status when locking of volume group fails. 2009-04-10 09:54:36 +00:00
Milan Broz
489c728793 Fix mirror log convert validation question. 2009-04-10 09:53:42 +00:00
Zdeněk Kabeláč
01eaadfa53 Avoid referencing files from DESTDIR during build process 2009-04-08 14:08:05 +00:00
Zdeněk Kabeláč
dddd2f9202 Do not create some dm and lvm static librarie when they are not requested
by configure option
Add dependency for static dmeventd library
2009-04-08 14:04:35 +00:00
Milan Broz
31709134c9 Enable use of cached metadata for pvs & pvdisplay.
Currently PV commands, which performs full device scan, repeatly
re-reads PVs and scans for all devices.

This behaviour can lead to OOM for large VG.

This patch allows using internal metadata cache for pvs & pvdisplay,
so the commands scan the PVs only once.
(We have to use VG_GLOBAL otherwise cache is invalidated on every
VG unlock in process_single PV call.)
2009-04-08 12:53:20 +00:00
Alasdair Kergon
456efad714 Add missing 'device-mapper' internal subdir build dependency. 2009-04-07 22:53:48 +00:00
Milan Broz
2112fc571a Use pv from newly read_vg to avoid possible use of not initialized memory.
If the vg in process_each_segment_in_pv is NULL, the pv struct
can be incomplete (for example lv_segs are not copied in get_pvs()
call).

We need use the new pv from just read-in volume group.

(The same code is in pvdisplay already.)
2009-04-07 10:22:14 +00:00
Milan Broz
0c4379ff0f Fix memory pool leak.
Call the alloc_destory call always after finishing operation
with handle otherwise it will leak a memory pool.

Also fix return code in lv_extend.
2009-04-07 10:20:28 +00:00
Dave Wysochanski
a690b36478 Fix whitespace in t-mdata-strings.sh
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-04-03 14:23:17 +00:00
taka
6f5ed95f71 Save and restore the previous logging level when log level is changed. 2009-04-02 21:34:41 +00:00
taka
251ee5f5a2 Fix error message when archive initialization fails. 2009-04-02 20:46:11 +00:00
Milan Broz
9ab1d88a91 Fix debug pool grow object to properly support delta=0
(It prints garbage for some reports)
2009-04-02 15:02:18 +00:00
Milan Broz
5d3d9f57fe Allocate new pv->vg_name from pool, it can be destroyed later.
(The mempool rename will be used later by vg private mempools)
2009-04-02 15:01:11 +00:00
Milan Broz
0889882255 Do not use pointer from released memory pool (cmd->cmd_line). 2009-04-02 14:59:48 +00:00
Christine Caulfield
2a1f78f95a Make sure clvmd-corosync releases the lockspace when it exits.
patch from Xinwei Hu
2009-04-01 07:51:05 +00:00
Milan Broz
6faaa1a0cc Add some more special chars for device name test. 2009-03-31 17:30:47 +00:00
Milan Broz
77dd12a028 fix some issues when compiling with -D DEBUG_POOL
- fix compilation issues
- fix wrong pool object maipulation (lvm dumpconfig triggers assert)
- second iteration in loop _log_parallel_areas operates on non-existing object
2009-03-26 09:25:18 +00:00
Milan Broz
6a954445f1 Fix segfault for vgcfgrestore on VG with missing PVs. 2009-03-24 13:16:34 +00:00
Christine Caulfield
9500e898c6 Block SIGINT & SIGTERM in clvmd subthreads so they don't delay shutdown.
Patch from Xinwei Hu, Thanks
2009-03-24 11:49:15 +00:00
taka
c5989d4350 Restore log_suppress state when metadata backup file is up-to-date.
Author: Takahiro Yasui <tyasui@redhat.com>
2009-03-23 22:57:27 +00:00
taka
8f782be41d Remove old metadata backup file after renaming vg.
Author: Takahiro Yasui <tyasui@redhat.com>
2009-03-23 22:29:06 +00:00
taka
afcc447a64 Fix size and error message of memory allocation at backup initialization.
Author: Takahiro Yasui <tyasui@redhat.com>
2009-03-23 21:56:32 +00:00
taka
8cfcba83ae Fix error message when adding metadata directory to internal list fails.
Author: Takahiro Yasui <tyasui@redhat.com>
2009-03-23 21:13:37 +00:00
Petr Rockai
a8315726ce Missed file from previous checkin. 2009-03-17 14:40:00 +00:00
Petr Rockai
da668c80b2 Some extra (paranoid) checks on dev_is_{md,swap} result. 2009-03-17 14:00:58 +00:00
Petr Rockai
55455ac21f Detect and wipe swap signatures in pvcreate. 2009-03-17 13:59:56 +00:00
Dave Wysochanski
74adacf96a Fix some clean rules, fix previous distclean checkin.
In libdm/Makefile.in, we need to cleanup the symlink properly.
Adding to CLEAN_TARGETS seemed like the simplest way to do this
in the current build framework.  We could redo dependencies for
VERSIONED_SHLIB, but for now just add to CLEAN_TARGETS.

For scripts/Makefile.in, we should be adding to DISTCLEAN_TARGETS.
The generic rule in make.tmpl.in takes care of the cleanup.

Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Author: Takahiro Yasui <tyasui@redhat.com>
2009-03-16 20:00:10 +00:00
Dave Wysochanski
a384b41308 Fix some distclean rules.
By gnu coding stds, 'distclean' should remove all files generated
by ./configure in addition to what 'clean' does.

Author: Takahiro Yasui <tyasui@redhat.com>
2009-03-16 18:28:04 +00:00
Milan Broz
048a329afc Fix warning in previous commit. 2009-03-16 15:19:29 +00:00
Milan Broz
3c3d16e794 Fix lv_count when manipulating with snapshots and max_lv is set.
Patch fixes these problems:
 - during the snapshot creation process, it needs create 2 LVs,
   one is cow, second becomes snapshot.
   If the code fails in vg_add_snapshot, code lvcreate will not remove
   LV cow volume.

 - if max_lv is set and VG contains snapshot, it can happen that
   during the activation lv_count is temporarily increased over the limit
   and VG metadata are not properly processed
   see https://bugzilla.redhat.com/show_bug.cgi?id=490298

 - vgcfgrestore alows restore with max_lv set to lower valuer that actual
   LV count. This later leads to situation that max_lv is completely ignored.

 - vgck doesn't call vg_validate(). It should at least try:-)

Signed-off-by: Milan Broz <mbroz@redhat.com>
2009-03-16 14:34:57 +00:00
Dave Wysochanski
d95b544dfd Remove unnecessary includes in lvm_base.c.
We would like to declare our handles pv_t, vg_t, and lv_t in
the external library header lvm.h.  However, these are already
defined in metadata-exported.h for the use of some of the
in-progress liblvm APIs.  Thus, we cannot both define
them in lvm.h and include metadata-exported.h in the external
library C files.  We could use preprocessor tricks (#ifndef)
but for now we just avoid the include.
2009-03-10 15:38:46 +00:00
Milan Broz
5d9ea7b91b Fix clvmd build after liblvm commit. 2009-03-10 12:10:12 +00:00
Dave Wysochanski
500289229a Fix error messages when PV uuid or pe_start reading fails.
Author: Takahiro Yasui <tyasui@redhat.com>
Committer: Dave Wysochanski <dwysocha@redhat.com>
2009-03-09 15:42:10 +00:00
Dave Wysochanski
21d62387ae Add missing liblvm/.exported_symbols 2009-03-08 18:58:53 +00:00
Dave Wysochanski
3bbfb30dcb Fix liblvm version symlink. 2009-03-08 18:10:39 +00:00
Dave Wysochanski
819fbc6ed5 Remove unnecessary linker flags for liblvm. 2009-03-08 17:29:26 +00:00
Dave Wysochanski
53e7c8fa34 Add DSO generation for new LVM application library.
Fix test/api/test build.
2009-03-08 17:06:55 +00:00
Dave Wysochanski
35d13cad96 Move lvm.h from lib to liblvm. 2009-03-06 22:49:48 +00:00
Dave Wysochanski
c190fc702e Add new liblvm build directory and move lvm_base.c.
The original liblvm.a has been moved to liblvm-internal.a.
We now use liblvm.a for the new application library and build
it inside liblvm directory.

Change dependencies so tools depend on liblvm application library,
and application library depends on liblvm internal.
2009-03-06 16:19:52 +00:00
Dave Wysochanski
cd0ed7b509 Rename liblvm to liblvm-internal.
Make preparation for using liblvm for new application library.
2009-03-06 16:17:28 +00:00
Christine Caulfield
24af685db1 Fix unlocks in clvmd-corosync.
The DLM unlock returns EUNLOCK in the lksb on success, not 0
2009-03-06 11:29:38 +00:00
Milan Broz
d7553ded6c Fix possible increasing in memory allocation if refreshing_context
(for example when CLVMD_CMD_LOCK_VG for is called during vgscan).

If clvmd calls LV lock, it calls
    /* clean the pool for another command */
	dm_pool_empty(cmd->mem);
to clean up memory pool after command.

Unfortunately, do_refresh_cache() do not call this
and because during it operation it allocates some memory,
the pool increases.

Also do_refresh_cache should use lvm_lock
(it manipulates with lvm internal data).

The same applies for lvm_backup command.

Signed-off-by: Milan Broz <mbroz@redhat.com>
2009-03-05 16:25:35 +00:00
Alasdair Kergon
884d5a7fc8 post-release 2009-03-03 18:25:05 +00:00
Milan Broz
a920074468 vgname_from_mda now tries to parse for vgname even
if rlocn not defined (there is no metadata area).

In most cases it fails in validate_name(),
unfortunately there are situatuions, when
validate_name is ok and later code fails with
checksum error.

Reproducer:

# dd if=/dev/zero of=/dev/loop0

# pvcreate --metadatasize 637k /dev/loop0
  Physical volume "/dev/loop0" successfully created

# pvs /dev/loop0
  /dev/loop0: Checksum error
      PV         VG   Fmt  Attr PSize PFree
        /dev/loop0      lvm2 --   1.00M 1.00M

Signed-off-by: Milan Broz <mbroz@redhat.com>

-
2009-03-03 16:35:32 +00:00
Alasdair Kergon
5ab342e298 pre-release 2009-03-03 13:03:03 +00:00
Alasdair Kergon
c99f525821 Fix last check-ins: seg can be NULL. 2009-02-28 20:04:24 +00:00
Alasdair Kergon
dff004d695 . 2009-02-28 19:43:42 +00:00
Alasdair Kergon
6f53e4b536 Attempt cleanup in child before execing new binary in exec_cmd() 2009-02-28 00:54:06 +00:00
Alasdair Kergon
9d3fe84135 . 2009-02-27 23:55:15 +00:00
Alasdair Kergon
e5f7ae3878 fsadm cleanups & release prep 2009-02-27 23:40:11 +00:00
Alasdair Kergon
97162d9a53 autoreconf (using fedora 10 for this now) 2009-02-25 23:33:30 +00:00
Milan Broz
d0b99cb260 pe_start can be overwritten in VG metadata, so it is not PV label-only field. 2009-02-25 23:31:06 +00:00
Milan Broz
fa22cc2e20 Try to avoid full rescan if label scan is enough. 2009-02-25 23:29:06 +00:00
Alasdair Kergon
9904255490 Use pkgconfig to obtain corosync library details during configuration. (kabi) 2009-02-25 22:41:12 +00:00
Christine Caulfield
f75c15b477 Fix error returns in clvmd-corosync interface to DLM.
Thanks to Xinwei Hu for spotting this.
2009-02-25 14:33:00 +00:00
Dave Wysochanski
9404dcab69 Update vgchange and vgmknodes man pages to include --refresh.
Author: Dave Wysochanski <dwysocha@redhat.com>
2009-02-25 13:17:40 +00:00
Zdeněk Kabeláč
c4d4403955 Fixed bug where lvresize option -t was not properly passed to fsadm.
Using argv[] list in exec_cmd() to allow more params for external commands.
Fsadm does not allow checking mounted filesystem.
Fsadm no longer accepts 'any other key' as 'no' answer to y/n.
Fsadm improved handling of command line options.
2009-02-24 15:48:00 +00:00
twoerner
a0bb2dc907 Fix include/.symlinks for lvm2.h to lvm.h renaming
Author: Thomas Woerner <twoerner@redhat.com>
2009-02-24 13:13:56 +00:00
twoerner
ed774a5691 Added files lib/lvm.h and lib/lvm_base.c:
New structure lvm (used as an alias to cmd_context), new type definition lvm_t
for the lvm handle. Added functions lvm_create, lvm_destroy and
lvm_reload_config using the new handle.

Modified test/api/test.c:
Use new lvm.h header file and lvm_t handle.

Removed lib/lvm2.h


Author: Thomas Woerner <twoerner@redhat.com>
2009-02-24 13:03:45 +00:00
Milan Broz
78cedddbde Fix validation of dataalignment value introduced in previous commit. 2009-02-23 16:53:42 +00:00
Alasdair Kergon
3640dc2fa3 Move tools/version.h to lib/misc/lvm-version.h.
Split LVM_VERSION into MAJOR, MINOR, PATCHLEVEL, RELEASE and RELEASE_DATE.
2009-02-22 22:11:58 +00:00
Alasdair Kergon
d3c619e3d3 Add system_dir parameter to create_toolcontext() and call it system_dir
everywhere for consistency.
2009-02-22 21:14:37 +00:00
Milan Broz
c158759c11 Comment out pvcreate pagesize alignment test for now. 2009-02-22 19:32:28 +00:00
Alasdair Kergon
b49362420c Add --dataalignment to pvcreate to specify alignment of data area. (mbroz)
This patch is not fully tested and leaves some related bugs unfixed.

Intended behaviour of the code now:

  pe_start in the lvm2 format PV label header is set only by pvcreate (or
vgconvert -M2) and then preserved in *all* operations thereafter.

  In some specialist cases, after the PV is added to a VG, the pe_start
field in the VG metadata may hold a different value and if so, it
overrides the other one for as long as the PV is in such a VG.

  Currently, the field storing the size of the data area in the PV label
header always holds 0.  As it only has meaning in the context of a
volume group, it is calculated whenever the PV is added to a VG (and can
be derived from extent_size and pe_count in the VG metadata).
2009-02-22 19:00:26 +00:00
Alasdair Kergon
aab76646ee Fix interrupt unblocking after vgcreate, for example: drop_cached_metadata()
previously left _vg_lock_count incremented.
Other locks are always held during drop_cached_metadata() so there's no
need to increment+decrement it.
2009-02-22 16:13:57 +00:00
Alasdair Kergon
259245d412 Provide da and mda locations in debug message when writing text format label. 2009-02-20 23:19:28 +00:00
Alasdair Kergon
717180a8eb Mention the restriction on file descriptors at invocation on the lvm man page. 2009-02-20 01:47:02 +00:00
Petr Rockai
12811483be In testsuite's not.c, print a notice when program dies of a fatal signal. 2009-02-17 19:37:28 +00:00
Petr Rockai
822aa2a352 Fix test output collection in harness.c. 2009-02-17 19:36:16 +00:00
Alasdair Kergon
9d788d4d9c Index cached vgmetadata by vgid not vgname to cope with duplicate vgnames. (dwyso) 2009-02-17 18:56:41 +00:00
Milan Broz
d405cb8dd9 Fix lvm.static build dependence (to properly propagate changes in libdevmapper). 2009-02-17 11:07:59 +00:00
Petr Rockai
5d3e57094a Only fail when tests have failed, but not when they have been just skipped. 2009-02-16 16:49:21 +00:00
Alasdair Kergon
e28d3f8cbd If kernel supports only one dm major number, use in place of any supplied.
No longer require kernel and metadata major numbers to match.
2009-02-12 20:42:07 +00:00
Petr Rockai
182494a5b7 Re-implement the test harness in C. This lets us pass through signals and
trigger proper test teardown upon harness interrupt or termination. I also
tweaked the output somewhat while I was at it...
2009-02-12 19:54:45 +00:00
Christine Caulfield
9487820c32 Add a fully-functional get_cluster_name() to clvmd corosync interface. 2009-02-11 10:13:20 +00:00
Christine Caulfield
03d00c16f8 Remove duplicate cpg_initialize from clvmd startup. 2009-02-10 13:22:18 +00:00
Christine Caulfield
57a38a00d9 Add option to /etc/sysconfig/cluster to select cluster type for clvmd. 2009-02-10 11:53:33 +00:00
Christine Caulfield
779b8679fd Allow clvmd to start up if its lockspace already exists. 2009-02-10 11:52:40 +00:00
Milan Broz
d0143d6f3e Separate PV label attributes which do not need parse metadata when reporting.
When reporting explicitly label attributes (pv_uuid for example), we do not
need to read metadata.

This patch separate the label fileds and removes scan_vgs_for_pvs
in process_each_pv() if not needed.

(There should be no user visible change in output.)
2009-02-09 09:45:49 +00:00
Zdeněk Kabeláč
7917c3fc15 Remove external dependency on the 'cut' command in fsadm 2009-02-06 14:28:06 +00:00
Milan Broz
81de913b77 Fix pvs segfault when pv mda attributes requested for not available PV. 2009-02-06 12:41:51 +00:00
Zdeněk Kabeláč
0e3798cadb add support for ext4 resize in fsadm 2009-02-04 12:47:05 +00:00
Dave Wysochanski
7447482608 Move locking_type reading inside init_locking().
No functional change.
2009-02-03 16:23:19 +00:00
Dave Wysochanski
f9b185caa5 Rename get_vgs() to get_vgnames() and clarify related error messages.
get_vgs() really returns a list of vgnames.  In the future we will use
get_vgs() to return a list of vg structures, similar to get_pvs().
2009-02-03 16:19:25 +00:00
Christine Caulfield
4761ce4b45 Allow clvmd to be built with all cluster managers & select one on cmdline. 2009-02-02 14:34:24 +00:00
Christine Caulfield
9f31af4c20 Mention --with-clvmd=corosync in ./configure 2009-01-29 15:23:15 +00:00
Alasdair Kergon
ab448cdb57 Add as-yet-unused vg_read_error() and vg_might_exist(). (mornfall) 2009-01-27 01:48:47 +00:00
Alasdair Kergon
22c4076818 Introduce as-yet-unused replacement vg_read() and vg_read_for_update()
functions.  (mornfall)
2009-01-27 00:40:44 +00:00
Alasdair Kergon
6e8bd97709 Replace internal vg_check_status() implementation. (mornfall) 2009-01-26 22:42:59 +00:00
Alasdair Kergon
7dd128a1a8 Properly enforce cluster locking in as-yet-unused _vg_lock_and_read. (mornfall) 2009-01-26 22:22:07 +00:00
Alasdair Kergon
dfd422a386 Introduce as-yet-unused _vg_lock_and_read() and associated header file
definitions.
2009-01-26 22:13:22 +00:00
Alasdair Kergon
6f434cd94a Rename vg_read() to vg_read_internal(). (mornfall) 2009-01-26 19:01:32 +00:00
Alasdair Kergon
a82f2fec18 post-release 2009-01-26 14:46:08 +00:00
Alasdair Kergon
234115f384 and another one missing 2009-01-26 14:40:06 +00:00
Alasdair Kergon
c522618a4b Add stuff people missed. 2009-01-26 13:34:07 +00:00
Alasdair Kergon
1c65c56970 pre-release 2009-01-26 13:14:22 +00:00
Christine Caulfield
c6cff13038 Add a corosync/DLM cluster service to clvmd.
It's not integrated in the configure system yet though.
2009-01-22 10:21:12 +00:00
Milan Broz
f25b101161 Use tools.h in for lvm-static. 2009-01-20 20:37:41 +00:00
Dave Wysochanski
6a866e208f Add --unquoted to pvs, vgs, lvs man pages. 2009-01-20 17:39:07 +00:00
Dave Wysochanski
11b1e5abd7 Add missing --segments to pvs man pg. 2009-01-20 17:27:11 +00:00
Dave Wysochanski
f44c387988 Add --nameprefixes to pvs, vgs, lvs man pages. 2009-01-20 17:10:44 +00:00
Milan Broz
b6629080ee Fix problems with static build
- compiler warning (missing header)

 - configure should set static flag early to be able
   use STATIC_LINK flag during configure script
2009-01-20 17:07:53 +00:00
Dave Wysochanski
4022dd564b Add --rows option to pvs, vgs, lvs man pages. 2009-01-20 16:55:24 +00:00
Dave Wysochanski
c848ce66c5 Rename _parse_options() to _parse_fields() for naming consistency.
In libdm, we only ever use 'fields', while the tools use 'options' and
'fields' interchangeably.

Ideally it would be good to use 'fields' consistently everywhere.
However, 'options' most likely comes from the tool commandline '-o' and
'--options' which cannot be changed.
2009-01-19 20:53:35 +00:00
Dave Wysochanski
26b4c34778 Add skeleton of fsadm nightly test but skip (doesn't work yet). 2009-01-15 17:14:38 +00:00
Dave Wysochanski
7eff83d689 Fix fsadm lvresize for filesystem block sizes != 1024.
Fixes rhbz 480022.
2009-01-15 14:44:48 +00:00
Petr Rockai
125fb7fbdb A C implementation of "not" that handles fatal signals rather more
intelligently than the shell implementation. C code by Jaroslav Stava.

I have done a rudimentary review and checked that tests still pass.
2009-01-12 18:45:44 +00:00
Alasdair Kergon
01be5511e5 ...and a few more uninitialised dummy fields. 2009-01-10 17:21:17 +00:00
Alasdair Kergon
4b45c6e35a More fields can cause segfaults with orphans.
Fix these by populating the dummy VG struct more completely.
2009-01-10 17:09:40 +00:00
Dave Wysochanski
7f831c1f4d Fix pvs segfault when run with orphan PV and vg_mda_size or vg_mda_free fields
We display '0' for these fields now in this case.  Ideally these values are
undefined for an orphan PV but today there is no way to specify undefined
with display functions such as _size64_disp().
2009-01-10 15:04:28 +00:00
Petr Rockai
d6778847c9 Fix some checks in lvm-utils.sh. Note that "$(test ...)" is always empty, since
"test" never prints anything. Therefore, "return $(test ...)" is equivalent to
just "return;" which means success in sh (same as return 0). We can however,
thanks to set -e, use "test foo = bar" as an assertion.

PS: test a == b is invalid syntax. It is either = or -eq: = is textual and -eq
is numeric comparison.
2009-01-10 12:19:41 +00:00
Alasdair Kergon
9a96645b53 Add <report_type>_all to help text. 2009-01-10 03:14:24 +00:00
Alasdair Kergon
ffa1b19e26 Add an "all" field which expands to all fields of the report type.
For example in LVM2, "pv_all" gives all PV fields.
"seg_all" gives all LV segment fields.

"all" gives all fields of the final report type.  I think this is more
useful than just adding the current prefix.

So "lvs -o seg_all" gives all the LV segment fields, whilst
"lvs --segments -o all" adds in LV and VG fields too.

"lvs -o all -O vg_name" has report type LVS+VGS so includes all LV and all
VG fields.
2009-01-10 03:01:35 +00:00
Alasdair Kergon
6f98b140a8 Display a 'dev_size' of zero for missing devices in reports. 2009-01-10 02:43:51 +00:00
Dave Wysochanski
e83d1a26e6 Add pv_mda_size to pvs and vg_mda_size to vgs. 2009-01-09 22:48:22 +00:00
Dave Wysochanski
b237d68c47 Add pv_mda_size to 'pvs' and vg_mda_size to 'vgs'.
Reports the size of the smallest metadata area in a PV or a VG.
Useful to confirm pvcreate --metadatasize or pvmetadatasize setting in
/etc/lvm/lvm.conf file.

NOTE: Actual value in these fields will most always differ from that
given in pvcreate options due to rounding and alignment effects.
2009-01-09 22:44:33 +00:00
Petr Rockai
1027762816 Document current state of inconsistent metadata behaviour of a few commands in
a test. Should make changes to the !consistent bits of code easier. To be
expanded.
2009-01-09 10:16:57 +00:00
Jonathan Earl Brassow
42893fc3bd Initial import of the cluster log daemon from the 'cluster' repository.
There is a rudimentary make file in place so people can build by hand
from 'LVM2/daemons/clogd'.  It is not hooked into the main build system
yet.  I am checking this in to provide people better access to the
source code.

There is still work to be done to make better use of existing code in
the LVM repository.  (list.h could be removed in favor of existing list
implementations, for example.  Logging might also be removed in favor
of what is already in the tree.)

I will probably defer updating WHATS_NEW_DM until this code is linked
into the main build system (unless otherwise instructed).
2009-01-08 17:12:33 +00:00
prajnoha
a479761be5 Add checks for device names in dmsetup and show proper error messages.
Checks added for DM device names to allow only names < DM_NAME_LEN,
otherwise a part of lengthy name would be silently ignored and could
cause confusion while using dmsetup. Also, the name should not contain
'/' character, if it is used in context of creating a new device
or renaming the existing one (because we do not consider full path
to devices, they do not exist in filesystem yet) and appropriate error
messages are shown.
2009-01-07 12:17:40 +00:00
Milan Broz
6d7265d966 Fix lvmdump /sys listing to include virtual devices directory. 2009-01-06 18:02:57 +00:00
Milan Broz
32048b7658 Fix "Calculate mirror log size" commit, the le_count should be always set. 2009-01-06 17:24:21 +00:00
prajnoha
08f79c6b93 Add "--refresh" functionality to vgchange and vgmknodes. 2008-12-22 09:04:35 +00:00
prajnoha
699a2268d6 Add "--refresh" functionality to vgchange and vgmknodes. 2008-12-22 09:00:51 +00:00
Alasdair Kergon
410f9c485e lvm2cmdline.h:31: warning: declaration of `is_static' shadows a global declaration 2008-12-19 18:51:02 +00:00
Milan Broz
8561e5e38e Do not issue write behind lv size.
pvcreate $DEV
vgcreate -s 1k vg_test $DEV
lvcreate -l 1 -n lv1 vg_test
..
/dev/vg_test/lv1: write failed after 1024 of 4096 at 0: No space left on device

Just check for maximum write size in set_lv.
2008-12-19 15:26:01 +00:00
Milan Broz
17617fe839 Calculate mirror log size instead of hardcoding 1 extent size.
It fails for 1k PE now.

Patch adds log_region_size into allocation habdle struct
and use it in _alloc_parallel_area() for proper log size calculation
instead of hardcoded 1 extent - which can fail.

Reproducer for incorrect log size calculation:
        DEV=/dev/sd[bcd]

        pvcreate $DEV
        vgcreate -s 1k vg_test $DEV
        lvcreate -m1 -L 12M -n mirr vg_test

https://bugzilla.redhat.com/show_bug.cgi?id=477040

The log size calculation is mostly copied from kernel code.
2008-12-19 15:24:52 +00:00
Milan Broz
7f4173ab22 Fail add tree node when requested major/minor is used.
Check for major/minor collision is added in _add_dev_to_dtree()
where we already read info by uuid,
so in the case of requesting major/minor it queries device-mapper
by major/minor for device availability.

Fixes https://bugzilla.redhat.com/show_bug.cgi?id=204992
2008-12-19 15:23:03 +00:00
prajnoha
84236edaf8 Fix incorrect return value in help function. 2008-12-19 14:43:02 +00:00
prajnoha
370dc2d727 Fix vgrename using UUID in case there are VGs with the same name. 2008-12-19 14:22:48 +00:00
Dave Wysochanski
211b07a2e2 Create global is_static() to eliminate from the library init function.
Very simple / crude method of removing 'is_static' from initialization.
Why should we require an application tell us whether it is linked
statically or dynamically to libLVM?  If the application is linked
statically, but libraries exist and dlopen() calls succeed, why
do we care if it's statically linked?
2008-12-18 05:27:17 +00:00
Dave Wysochanski
9f67ba6a38 Remove struct arg * from struct cmd_context and create_toolcontext().
This allows us to remove one argument from create_toolcontext() and
moves it closer to a generic library init function.

In the arg_*() functions, we just use _the_args() directly.
For now we leave the first parameter to these
arg_*() functions (struct cmd_context *) because
of the number of files involved in removing the
parameter.
2008-12-17 16:46:45 +00:00
Dave Wysochanski
03798fd604 Move arg_* functions from toollib.c to lvmcmdline.c.
In preparation for removing cmd->args.
IMO, it makes more sense to put these accessor functions
in the same location as the static array _the_args.
Next patch will update arg_* functions to use _the_args[]
directly and remove cmd->args.
2008-12-17 16:45:32 +00:00
Milan Broz
7bb4897b9f Remove status=noxfer from test, not all dd versions support this (RHEL4 for example). 2008-12-16 20:02:52 +00:00
Dave Wysochanski
4b0e97e666 Rename 'cmd' to 'clvmd_cmd' to remove ambiguity.
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Acked-by: James Cameron <james.cameron@hp.com>
Acked-by: Alasdair G Kergon <agk@redhat.com>
2008-12-16 12:30:39 +00:00
Dave Wysochanski
5b655dd4cd Fix segfault when invalid field given in reporting commands.
Problem is dm_report_init() may return NULL and subsequent call to
dm_report_set_output_field_name_prefix() doesn't handle NULL value.

Example:
	pvs --nameprefixes --rows --unquoted --noheadings -opv_name,fred
  Logical Volume Fields
  ---------------------
    lv_uuid              - Unique identifier
    lv_name              - Name.  LVs created for internal use are enclosed in brackets.
 ...

  Physical Volume Segment Fields
  ------------------------------
    pvseg_start          - Physical Extent number of start of segment.
    pvseg_size           - Number of extents in segment.

  Unrecognised field: fred
Segmentation fault
2008-12-15 13:30:45 +00:00
Alasdair Kergon
023a61c0e5 Use dm_snprintf to avoid duplicating the snprintf compatibility code. 2008-12-12 18:45:58 +00:00
Dave Wysochanski
38cc6383b7 Create _init_globals() and call from bottom of create_toolcontext().
Move init_full_scan_done(0) and init_mirror_in_sync(0) from init_lvm()
after call to create_toolcontext() to _init_globals(), called from bottom
of create_toolcontext().  No functional change.

Author: Dave Wysochanski <dwysocha@redhat.com>
Acked-by: James Cameron <james.cameron@hp.com>
Acked-by: Alasdair G Kergon <agk@redhat.com>
2008-12-12 03:30:41 +00:00
Zdeněk Kabeláč
77ac863bb8 Replace _dm_snprintf with EMIT_PARAMS macro for creating target lines 2008-12-11 16:25:51 +00:00
Dave Wysochanski
fdab219755 *** empty log message *** 2008-12-11 13:45:28 +00:00
Dave Wysochanski
f31e8d08cd Move initialization of cmd->fmt into init_formats().
init_formats() sets up the command formats, and currently sets cmd->fmt_backup
but does not set cmd->fmt to a default value.  This seems incorrect so we
set it to cmd->default_settings.fmt before returning.

The call we remove here may set cmd->fmt based on a command line setting.
But it is safe to remove this, because the only caller of init_lvm() that
cares about the cmdline override is the cmdline tools (clvmd does not care),
called from lvm2_main().  After lvm2_main() calls init_lvm(), it later calls
lvm_run_command().  In lvm_run_command(), we have a call to _apply_settings(),
which has the identical assignment of cmd->fmt that this patch removes.
2008-12-11 03:36:16 +00:00
Dave Wysochanski
224c8ec0fa Remove redundant init_msg_prefix() and init_cmd_name().
This is very obvious - _init_logging() makes the identical init_msg_prefix()
and init_cmd_name() calls with cmd->default_settings so these calls are
clearly redundant after calling create_toolcontext().
2008-12-11 03:34:43 +00:00
Dave Wysochanski
309c19ef63 Remove redundant set_activation() call after create_toolcontext() calls.
Very similar argument to removal of init_debug() and other calls.

create_toolcontext() calls _process_config() which sets
cmd->default_settings.activation, then calls
set_activation(cmd->default_settings.activation).  Later, create_toolcontext()
sets cmd->current_settings = cmd->default_settings.  So these calls
set_activation(cmd->current_settings.activation) are redundant.
2008-12-11 03:34:12 +00:00
Dave Wysochanski
13aad7e8b4 Remove backup_enable() calls after create_toolcontext() calls.
Identical argument to previous patch which removed archive_enable() calls.
We add a new parameter to backup_init() which sets the enable value based
on the cmd->default_settings.backup value.  This value was used to set
cmd->current_settings.backup, used in the removed backup_enable() call.
2008-12-11 03:33:35 +00:00
Dave Wysochanski
6f36d0d06c Remove archive_enable() calls after create_toolcontext() calls.
_init_backup() calls archive_init(), which originally set 'enabled' to
a hardcoded '1' value.  This seems incorrect based on my read of other
areas of the code so here we add a 'enabled' paramter to archive_init().
We pass in cmd->default_settings.archive, which is obtained from the
config tree.  Later in create_toolcontext, cmd->current_settings is
set to cmd->default_settings.  The archive_enable() call we remove
here was using cmd->current_settings to set the 'archive' enable
value.  The final value of cmd->archive_params->enabled should thus
be equivalent to the original code.
2008-12-11 03:32:56 +00:00
Dave Wysochanski
76d734a4bd Move init_test() from _apply_settings into _init_logging().
This one we actually need to move.  _init_logging() is called from
    create_toolcontext(), which makes this call:
        /* Test mode */
        cmd->default_settings.test =
            find_config_tree_int(cmd, "global/test", 0);

But it does not call init_test().  So we need an init_test() somewhere.
The most logical place is to put it inside _init_logging(), since this
is where the config value is read and default_settings are set.  Placing
the init_test() call here matches what is done with other variables and
seems to make sense.
2008-12-11 03:31:47 +00:00
Dave Wysochanski
b14f29b5b7 Remove handles_missing_pvs assignment after call to create_toolcontext().
This variable is set at the top of create_toolcontext() to 0.
Nothing later in create_toolcontext() changes the value.
In init_lvm(), nothing between create_toolcontext() call and this assignment
changes the value.  Thus, the assignment is redundant.
2008-12-11 03:31:10 +00:00
Dave Wysochanski
c57b30e342 Remove init_verbose() calls immediately after create_toolcontext() calls.
The rationale for removing init_verbose() call is very similar to removing
init_debug() call.  create_toolcontext() calls _init_logging() which
makes these calls:
        /* Verbose level for tty output */
        cmd->default_settings.verbose =
            find_config_tree_int(cmd, "log/verbose", DEFAULT_VERBOSE);
        init_verbose(cmd->default_settings.verbose + VERBOSE_BASE_LEVEL);

And being that create_toolcontext() copies default_settings into
current_settings at the bottom, the init_verbose() call we are removing:
        init_verbose(cmd->current_settings.verbose + VERBOSE_BASE_LEVEL);

is redundant.
2008-12-11 03:30:19 +00:00
Dave Wysochanski
f6023a7c76 Remove init_debug() calls immediately after create_toolcontext() call.
We can safely remove because create_toolcontext() calls _init_logging(),
which makes these calls:
        /* Debug level for log file output */
        cmd->default_settings.debug =
            find_config_tree_int(cmd, "log/level", DEFAULT_LOGLEVEL);
        init_debug(cmd->default_settings.debug);

Then at the bottom of create_toolcontext() we do this:
        cmd->current_settings = cmd->default_settings;

So the call we are removing from init_lvm() functions (clvmd and lvmcmdline):
        init_debug(cmd->current_settings.debug);

Just sets the value of debug based on 'cmd->current_settings.debug'.
Since cmd->current_settings is equivalent to cmd->default_settings, and
init_debug() was called with cmd->default_settings, the call we remove is
redundant.
2008-12-11 03:29:37 +00:00
Dave Wysochanski
6357a2d9b8 Replace _apply_settings() after create_toolcontext() with equivalent inline.
Subsequent patches will refactor / remove each of these lines, as many of
them are redundant when called immediately after create_toolcontext().
2008-12-11 03:28:54 +00:00
Zdeněk Kabeláč
7e3a1a8b18 operate on test subdirectory instead on main /dev 2008-12-10 16:16:53 +00:00
Zdeněk Kabeláč
5f1b8f71f3 add simple test for dev node usability (detect devices mounted with nodev) 2008-12-10 16:15:41 +00:00
Dave Wysochanski
cca8bb9092 Add liblvm interactive test infrastructure to build. 2008-12-07 19:37:07 +00:00
Dave Wysochanski
647314d3cc Make _init_rand() thread safe - use rand_r() instead of rand().
Use good entropy for seed value if possible.
2008-12-07 04:27:56 +00:00
Dave Wysochanski
30e6773617 Add generic function to read /dev/urandom, used in uuid calculation. 2008-12-07 04:23:37 +00:00
Dave Wysochanski
08774dc558 Fix test-utils.h for rhel4 backward compatability.
for losetup, break out of the loop when successful setup of loop device,
and only look at 7 loop devices (default loop module setting)
for blockdev, use old option if new one is not available
2008-12-05 05:03:23 +00:00
prajnoha
481618826d Added displayable_lvs_in_vg and lv_is_displayable functions to deal with
the counts of visible LVs from user's perspective consistently throughout
the code.
2008-12-04 15:54:26 +00:00
Dave Wysochanski
befcada36a Fix vgcreate race which could allow two parallel vgcreates to succeed,
with the second vgcreate overwriting the first.

Obtain lock before calling vg_create(), which checks for existence of vgname
and fails if it already exists.
2008-12-01 20:14:33 +00:00
Alasdair Kergon
b71bf9332c Fix uninitialised lv_count in vgdisplay -c 2008-12-01 17:38:35 +00:00
Alasdair Kergon
1303c93139 Suppress 'duplicate PV' message when it's only a cache update not a real
duplicate.
2008-11-28 15:51:40 +00:00
Alasdair Kergon
29c8c75492 Don't skip updating pvid hash when lvmcache_info struct got swapped. 2008-11-27 18:13:50 +00:00
Alasdair Kergon
862d83c691 Add tinfo to termcap search path for pld-linux. 2008-11-24 13:33:16 +00:00
Christine Caulfield
f18eeb4da8 Fix a starup race in clvmd that could result in huge waits for the first command to be processed. 2008-11-21 13:48:00 +00:00
Alasdair Kergon
d40fed016f generate init script 2008-11-19 20:14:24 +00:00
Alasdair Kergon
76dc3ddf56 regenerate 2008-11-19 19:34:32 +00:00
Alasdair Kergon
d80d9a4c4e Generate clvmd init script at configuration time for Red Hat-based distros. 2008-11-19 19:33:25 +00:00
Alasdair Kergon
281ee1c2bf post-release (retrospective) 2008-11-19 14:14:51 +00:00
Zdeněk Kabeláč
65e976198e daemons depends on liblvm2cmd - fixes parallel builds 2008-11-18 13:16:03 +00:00
Zdeněk Kabeláč
a0d668e850 fix missing const char* 2008-11-18 10:13:23 +00:00
Dave Wysochanski
f7d624e684 Fix "lvremove -f vgname" when vgname contains snapshots.
Prior to this patch, "lvremove -f vgname" would fail if vgname contained
one or more snapshot LVs.  Now this passes, but has a side-effect.
If you issue "lvremove vgname" where vgname contains one or more snaps,
you will get an extra "y/n" prompt to remove the same snapshot.
Example:
$ lvs
  LV     VG     Attr   LSize  Origin Snap%  Move Log Copy%  Convert
  lvsnap vgtest swi-a- 16.00M lvtest   0.05
  lvtest vgtest owi-a- 64.00M
$ lvremove vgtest
Do you really want to remove active logical volume "lvsnap"? [y/n]: n
  Logical volume "lvsnap" not removed
Do you really want to remove active logical volume "lvsnap"? [y/n]: n
  Logical volume "lvsnap" not removed
  Command failed with status code 5.

Fixing this will most likely require modification of the iterator
function, process_each_lvs_in_vg() to iterate over snaps in some
cases (e.g. lvs, vgdisplay -v) but not in others (lvremove).
2008-11-17 18:20:13 +00:00
Alasdair Kergon
f5c395adb2 some makefile fixes for liblvm2cmd & remove some hardcoded .so 2008-11-14 20:59:56 +00:00
Dave Wysochanski
09192b4d6e More man page cleanup - convert "+/-" to "+|-" 2008-11-12 15:16:58 +00:00
Dave Wysochanski
74ec3783e7 Make man pages consistent with either-or options (use "|" everywhere). 2008-11-12 15:01:35 +00:00
Zdeněk Kabeláč
1c38ce8245 cleaner const char* usage for last_path_component() 2008-11-12 09:53:33 +00:00
Zdeněk Kabeláč
702cfe15be minor compiler warning fix for function declaration prototype 2008-11-12 09:49:06 +00:00
Zdeněk Kabeláč
54d790828f removed redundant redeclaration of init_indent() and init_msg_prefix() from lvm-logging.h 2008-11-12 09:41:44 +00:00
Zdeněk Kabeláč
aff35fea29 * minor compilator warning fix for improper function declaration. 2008-11-12 09:30:52 +00:00
Petr Rockai
25a82bcbe3 Add a bunch of sub-tests aimed at testing various bugzillas, by jstava. 2008-11-11 15:46:15 +00:00
Petr Rockai
cb58100587 Import a bunch of new tests by jstava. Mostly everything pass, they however
tend to expose the lvremove -ff vg ordering bug.
2008-11-11 15:29:24 +00:00
Alasdair Kergon
9fbe96fd7c clarify 2008-11-10 21:26:06 +00:00
Alasdair Kergon
98cd400443 no need for libdevmapper.h on system any more 2008-11-10 21:25:45 +00:00
Petr Rockai
873e699f6d Include libdm in lcov reports. 2008-11-10 14:04:12 +00:00
Petr Rockai
9a8f6c824f Fix t-pool-labels to pass again after the vgdisplay error return fix from
last Friday.
2008-11-10 13:44:01 +00:00
Milan Broz
a98888ad07 Fix lvm2.static build. 2008-11-10 13:41:43 +00:00
Petr Rockai
db98500b72 Minor code and documentation cleanups and changes by jstava. 2008-11-10 12:43:35 +00:00
Petr Rockai
3feee09cfe add bz264241 check
remove lvconvert progress notifications (-i100)
(by jstava)
2008-11-10 12:41:52 +00:00
Alasdair Kergon
4a1cd0d391 First test release of the merged code base. 2008-11-10 12:39:50 +00:00
Petr Rockai
edb5071d3b bz429342 lvcreate --nosync
bz192865 lvconvert logtype of an inactive mirror lv
(both by jstava)
2008-11-10 12:37:53 +00:00
Petr Rockai
e9509aa5e6 Add bz186013 check -- lvcreate rejects an invalid regionsize (jstava). 2008-11-10 12:37:03 +00:00
Petr Rockai
5e6ca1b72d Use separate locking directory for each of the tests, as they never share a
volume group, or physical devices for that matter. Hopefully fixes occasional
test errors due to locking failures. Patch by jstava.
2008-11-10 12:36:23 +00:00
Petr Rockai
543bf2ffbd Explicitly check after lvremove -ff vg that it did its job. By jstava. 2008-11-10 12:32:00 +00:00
Dave Wysochanski
15a7a4c38b Fix lvhange and lvcreate man pages to properly describe permissions option.
James Youngman <jay@gnu.org>
2008-11-07 19:23:52 +00:00
Dave Wysochanski
640d07bf35 Fix vgdisplay return code and exit status. 2008-11-07 19:02:47 +00:00
Petr Rockai
e5ecc2b942 Set LD_LIBRARY_PATH in init.sh, as it is required to run dmsetup now as well,
which otherwise picks up the system version of libdevmapper, which is a pretty
bad idea.
2008-11-07 01:30:03 +00:00
Alasdair Kergon
cfd8fe40f4 quick review of docs
Note that we'll continue to use WHATS_NEW_DM for device-mapper changes
until we can switch to unified version numbering.
2008-11-04 17:49:22 +00:00
Alasdair Kergon
abba6e0642 make install_device-mapper 2008-11-04 17:25:32 +00:00
Alasdair Kergon
ec94fb89a2 clvmd 2008-11-04 16:41:47 +00:00
Alasdair Kergon
bb167efa7b dmeventd 2008-11-04 15:55:27 +00:00
Alasdair Kergon
2a550ef96d more fixes 2008-11-04 15:07:45 +00:00
Alasdair Kergon
03ed7d73fc more missing bits 2008-11-04 14:57:06 +00:00
Petr Rockai
446852db3b Fix typo. 2008-11-04 14:38:53 +00:00
Petr Rockai
7c90b57e87 Also report the tests that have been skipped, at the end of harness.sh. 2008-11-04 14:37:51 +00:00
Petr Rockai
6339e2588b Use $(abs_top_builddir) instead of @DMDIR@ and update paths appropriately. 2008-11-04 14:37:10 +00:00
Alasdair Kergon
af6687405b more tweaks for dmeventd - not finished yet 2008-11-03 23:01:21 +00:00
Alasdair Kergon
a2bfad1c29 Right, a simple build (without options) is working again. 2008-11-03 22:14:30 +00:00
Alasdair Kergon
645aa55abc add list fns 2008-11-03 20:03:00 +00:00
Alasdair Kergon
05329c885a more tweaking to get things to compile - dmlib.h for log fns, list.h 2008-11-03 18:59:59 +00:00
Alasdair Kergon
b3fed93a74 Rename a couple of variables that matched function names. 2008-11-03 16:26:27 +00:00
Alasdair Kergon
2c6fad0ea7 autoreconf 2008-11-01 20:48:50 +00:00
Alasdair Kergon
57854c2231 Use simple x.y.z library version in libdevmapper.pc 2008-11-01 20:48:09 +00:00
Alasdair Kergon
a8cf4293e0 autoreconf 2008-11-01 02:20:06 +00:00
Alasdair Kergon
ba70dce803 further progress 2008-11-01 02:19:19 +00:00
Alasdair Kergon
5b4c3ace56 export DM_LIB_VERSION 2008-11-01 01:43:31 +00:00
Alasdair Kergon
2ade7a15e2 add libdevmapper-event.h 2008-10-31 22:41:51 +00:00
Alasdair Kergon
e83f71d678 autoreconf 2008-10-31 22:34:42 +00:00
Alasdair Kergon
412c91cb6b no DMDIR 2008-10-31 22:33:55 +00:00
Alasdair Kergon
aa44167319 dm+lvm2 macros 2008-10-31 22:32:54 +00:00
Alasdair Kergon
dd5700e8b3 dmeventd plugins move 2008-10-31 22:29:44 +00:00
Alasdair Kergon
ef7fc430d7 drop configure --with-dmdir 2008-10-31 22:22:04 +00:00
Alasdair Kergon
f1bcb6c634 autoreconf 2008-10-31 22:12:55 +00:00
Alasdair Kergon
4a4eb17d08 first attempt at merging configure 2008-10-31 22:06:09 +00:00
Alasdair Kergon
8afc267c68 libdevmapper version - will change once the merger's settled in 2008-10-31 21:55:40 +00:00
Alasdair Kergon
6457ab31b6 remove ancient debian dir 2008-10-31 12:25:54 +00:00
Alasdair Kergon
306dfa2043 Add dm-logging.h ready for libdevmapper. 2008-10-30 17:54:12 +00:00
Alasdair Kergon
424bdade0b drop explicit libdevmapper.h 2008-10-30 17:52:06 +00:00
Alasdair Kergon
10857e3321 separate lvm-globals 2008-10-30 17:40:00 +00:00
Alasdair Kergon
85a4e47879 Separate out globals from the logging code. 2008-10-30 17:39:00 +00:00
Alasdair Kergon
759e49f025 Split out lvm-logging.h from log.h. 2008-10-30 17:27:28 +00:00
Alasdair Kergon
43924e31b8 Split out dm-logging.h from log.h 2008-10-30 17:24:04 +00:00
Alasdair Kergon
3b34fcf59f Add libdm subdir to begin merging the device-mapper tree. 2008-10-30 15:31:33 +00:00
Alasdair Kergon
ba7253eaf7 Use lvm-types.h 2008-10-30 15:11:16 +00:00
Alasdair Kergon
be23682a30 post-release 2008-10-26 10:40:50 +00:00
Alasdair Kergon
3a5dce4c92 pre-release 2008-10-26 10:33:34 +00:00
Alasdair Kergon
22d7e60d0e Accept locking fallback_to_* options in the global section as documented. 2008-10-24 01:16:16 +00:00
Alasdair Kergon
5752156c9e Fix temp table activation in mirror conversions not to happen in other cmds.
Fix temp table in mirror conversions to use always-present error not zero.
2008-10-23 11:21:04 +00:00
Alasdair Kergon
a30215a530 post-release 2008-10-17 17:48:10 +00:00
Alasdair Kergon
f9c8c1b964 pre-release 2008-10-17 17:42:08 +00:00
Alasdair Kergon
5650f67ef5 Use temp table to set device size when converting mirrors.
(Avoids having same mirror table loaded twice concurrently by first
using a 'zero' table to set the size of the device so when mirror
table is preloaded it doesn't have to be activated immediately.)
2008-10-17 10:57:15 +00:00
Alasdair Kergon
5ec25dfb94 In resume_mirror_images replace activate_lv with resume_lv as workaround.
(The resume has the side-effect of resuming all of the original
mirror's sub-lvs in addition to the new 'error' target middle layer.)
2008-10-17 10:50:14 +00:00
Alasdair Kergon
ef16682725 Avoid overwriting in-use on-disk text metadata by forgetting MDA_HEADER_SIZE. (Edward Allcutt) 2008-10-17 00:55:46 +00:00
Petr Rockai
883486cc67 Re-indent test-utils.sh consistently, using tabs. 2008-10-14 19:48:01 +00:00
Petr Rockai
f367f9b747 Conversion of last 2 tests to use test-utils.sh, by jstava. 2008-10-14 19:41:12 +00:00
Milan Broz
a3d987fa73 Fix snapshot monitoring library to not cancel monitoring invalid snapshot.
snapshot DSO unregistered itself when snapshot changed state to invalid.

This can cause a race (and several timeouts), when for example another snapshot
is added and in the middle of operation (suspend/resume) the monitoring thread
unregister itself.

Fix it by keeping the snapshot monitored after invalidation - just reset
threshold to not really print any messages to syslog.
2008-10-13 12:06:30 +00:00
Alasdair Kergon
2d48685673 . 2008-10-09 10:47:37 +00:00
Alasdair Kergon
9b21ace1e9 Generate man pages from templates and include version. (romster) 2008-10-08 12:50:13 +00:00
Alasdair Kergon
be2c03fa96 Add usrlibdir & usrsbindir to configure. 2008-10-07 19:11:59 +00:00
Alasdair Kergon
f5585e9252 Add usrsbindir to configure. 2008-10-07 19:08:46 +00:00
Petr Rockai
4d534dd7e4 Add a workaround for missing losetup -s by jstava, and a print a stacktrace
on errors (also by jstava). Currently requires bash, a fix for that may come
later -- explicitly using bash to run tests in the meantime.
2008-10-06 16:55:30 +00:00
Petr Rockai
c8584e1cce More test conversions by jstava. Make check still passes. 2008-10-06 16:47:07 +00:00
Alasdair Kergon
84a1de464c Fix conversion of md chunk size into sectors. 2008-10-03 14:22:18 +00:00
Alasdair Kergon
3966f3d319 device->devices 2008-10-01 22:48:26 +00:00
Petr Rockai
e6166cf711 Make harness.sh exit with non-zero status when tests fail. 2008-09-30 21:45:42 +00:00
Petr Rockai
2285712834 Cosmetic: get rid of trailing garbage on comments in t-vgslpit-usage.sh. 2008-09-30 21:43:55 +00:00
Petr Rockai
53cb6128e8 Improve harness.sh output: also mention failing test's name near the end of its
output. Avoids the need to scroll back just to see which failing test you are
looking at.
2008-09-30 21:43:16 +00:00
Alasdair Kergon
8c317baf19 Free text metadata buffer after a failure writing it. 2008-09-30 20:37:52 +00:00
Petr Rockai
8cac933c71 Fix [ a = b ] usage in t-vgsplit-operation: string comparison is '=', not '=='. 2008-09-30 18:29:10 +00:00
Petr Rockai
03e61a4bf8 Conversion of t-vgsplit-operation.sh by jstava. 2008-09-30 17:56:54 +00:00
Petr Rockai
71446a76b2 Fix a syntax error in one of the scripts, introduced by last commit. 2008-09-30 17:50:56 +00:00
Petr Rockai
28db8d6c7c More test conversions, all of these are by jstava. 2008-09-30 17:47:34 +00:00
Petr Rockai
786e33d7d5 Port over t-vgreduce-usage. Should fix testsuite hangs where pvremove -ff would
have waited for input on certain test failures.
2008-09-30 17:17:04 +00:00
Petr Rockai
b140d6c50e Convert t-vgsplit-usage.sh to use the new test-utils.sh. Original conversion by
jstava. Lvm1 testing restored by mornfall.
2008-09-30 15:20:09 +00:00
Petr Rockai
64a95abdee Convert t-pvremove-usage to use the new test-utils.sh. 2008-09-30 13:19:56 +00:00
Petr Rockai
57f926be17 Update test/Makefile.in to use the new harness for calling tests. 2008-09-29 16:07:02 +00:00
Petr Rockai
4933b67959 Add a test for reappearing lost PVs causing endless metadata correction
updates. (A problem Milan fixed recently.)
2008-09-29 16:06:10 +00:00
Petr Rockai
370b4f1b9e Add a simple test for partial activation. 2008-09-29 16:04:57 +00:00
Petr Rockai
f3b7baa84e Update a bunch of tests to use functionality from test-utils.sh. 2008-09-29 16:02:50 +00:00
Petr Rockai
eafdb2c807 Export testlib_cleanup_ from test-lib.sh, which is needed for test-utils.sh to
be able to call proper EXIT traps.
2008-09-29 16:00:53 +00:00
Petr Rockai
a91fa821ab Import new test utilities and a test harness. 2008-09-29 15:59:19 +00:00
Milan Broz
37ef162cda Fix misleading error message when there is no allocatable extents in VG. 2008-09-29 09:59:10 +00:00
Milan Broz
770928acfc Fix handling of PVs which reappeared with old metadata version. 2008-09-25 15:59:10 +00:00
Milan Broz
d0f3570219 Try to fix possible infinite loop in dependency tree walking (by mornfall). 2008-09-25 15:57:02 +00:00
Milan Broz
3d07c2605f Fix mirror DSO to call vgreduce with proper parameters. 2008-09-25 15:52:29 +00:00
Milan Broz
c350798528 Fix validation of --minor and --major in lvcreate to require -My always. 2008-09-24 16:32:51 +00:00
Alasdair Kergon
6bc3cc0bec . 2008-09-19 18:31:20 +00:00
Alasdair Kergon
2e3e5fcc81 suppress warning if old value found for now 2008-09-19 18:26:41 +00:00
Milan Broz
dfdb10f6de Add more vgreduce tests. (Jaroslav Stava) 2008-09-19 16:12:25 +00:00
Milan Broz
5cbe5909eb Fix vgreduce test, now requires --force flag. (Jaroslav Stava) 2008-09-19 16:10:46 +00:00
Alasdair Kergon
04d52b450b fix last release 2008-09-19 15:44:03 +00:00
Alasdair Kergon
a586a89547 . 2008-09-19 07:18:03 +00:00
Alasdair Kergon
1905eacf15 rename var 2008-09-19 07:12:45 +00:00
Alasdair Kergon
858ec0d740 revert unexplained removal of a '<backtrace>' message 2008-09-19 07:03:23 +00:00
Alasdair Kergon
76cfd406ca pre-release 2008-09-19 06:48:48 +00:00
Alasdair Kergon
9dbaad859d . 2008-09-19 06:44:54 +00:00
Alasdair Kergon
95d43e17b3 Improve the way VGs with PVs missing are handled so manual intervention
is required in fewer circumstances.  (mornfall)
2008-09-19 06:42:00 +00:00
Alasdair Kergon
09a2dff8de Add device/md_chunk_alignment to lvm.conf 2008-09-19 05:33:37 +00:00
Alasdair Kergon
57208f879a adjust pe_align for md chunk size 2008-09-19 05:19:09 +00:00
Alasdair Kergon
149638431d remove unsed var 2008-09-19 04:30:02 +00:00
Alasdair Kergon
30d2940c67 Pass struct physical_volume to pe_align. 2008-09-19 04:28:58 +00:00
Alasdair Kergon
5ee86fc5d0 remove unused var 2008-09-19 03:45:34 +00:00
Alasdair Kergon
a03d0e2c3f Store sysfs location in struct cmd_context. 2008-09-19 03:42:37 +00:00
Alasdair Kergon
8bd367d58d fix last patch return code 2008-09-19 00:20:39 +00:00
Alasdair Kergon
bc633e03aa Fix last checkin - tested wrong dnode. 2008-09-18 22:55:33 +00:00
Alasdair Kergon
797d0f1ef1 post-release 2008-09-18 20:09:51 +00:00
Alasdair Kergon
1be3e86aa0 Avoid shuffling remaining mirror images when removing one, retaining primary. 2008-09-18 19:56:50 +00:00
Alasdair Kergon
e56dd38021 Add missing LV error target activation in _remove_mirror_images. 2008-09-18 19:09:47 +00:00
Alasdair Kergon
410904bef1 Prevent resizing an LV while lvconvert is using it. 2008-09-18 18:51:58 +00:00
Alasdair Kergon
026cc120e7 Only resume devices in dm_tree_preload_children if size changes. 2008-09-18 18:34:53 +00:00
Alasdair Kergon
ef2fda05cf Avoid repeatedly wiping cache while VG_GLOBAL is held in vgscan & pvscan. 2008-09-16 18:05:11 +00:00
Alasdair Kergon
92277e3ae2 revert unnecessary 'stack's 2008-09-15 17:06:55 +00:00
Milan Broz
fbc34d70b0 Fix pvresize to not allow resize if PV has two metadata areas.
If the PV has two metadata areas, second one is located at the end of the device.

Do not allow resize of PV or second metadata area can be overwritten.
(The check was active only for orphan PVs.)
2008-09-12 15:26:45 +00:00
Milan Broz
91dcddbdf7 Do not scan for lvm1 entries in /proc if not running 2.4 kernel.
(LVM1 is only present in 2.4 kernel.)
2008-09-10 10:14:59 +00:00
Alasdair Kergon
874f42ad6c Extend deptree buffers so the largest possible device numbers fit. 2008-09-02 12:16:07 +00:00
Milan Broz
1989ef4ebc Fix setting of volume limit count if converting to lvm1 format.
Fixes problem when after downconvert to lvm1 VG is broken:

# lvcreate -n lv1 -l 4 vg_test
  Invalid LV in extent map (PV /dev/sdb1, PE 0, LV 0, LE 0)
  ...
2008-08-29 13:41:21 +00:00
Dave Wysochanski
4f4c72c065 Add ctype.h header file to silence compile warning on 'isdigit'.
uuid/uuid.c:86: warning: implicit declaration of function 'isdigit'
2008-08-29 00:49:46 +00:00
Milan Broz
666cc72661 Fix vgconvert logical volume id metadata validation.
If volume group is downconverted to lvm1 format,
check if lvid has supported format for conversion to lv_num in lvm1.
2008-08-28 18:41:51 +00:00
Milan Broz
4524e8f5c9 format1: Not detecing label on disc is not error, remove <backtrace> from debug log
(happens when you explicitly use -M 1)
2008-08-28 13:41:46 +00:00
Milan Broz
bd07a29886 Not detecing label on disc is not error, remove <backtrace> from debug log
and report it only if device cannot be read.
2008-08-28 13:28:13 +00:00
Milan Broz
a0d865492e fix vgreduce tests to detect partial command failure (Jaroslav Stava) 2008-08-28 11:20:49 +00:00
Milan Broz
de27790de8 add vgcreate rejects repeated invocation test
add vgcreate fails when the only pv has --metadatacopies 0 test
(by Jaroslav Stava)
2008-08-28 11:09:58 +00:00
Milan Broz
9c910b7be2 add vgrename by uuid test (Jaroslav Stava)
fix vgsplit rejects last mda copy test (Jaroslav Stava)
2008-08-28 10:59:10 +00:00
Milan Broz
7f23ab94e2 Fix lvmdump metadata gather option (-m) to work correctly. (Jaroslav Stava) 2008-08-28 10:40:44 +00:00
Milan Broz
77dc036c8f Add pvremove usage test (Jaroslav Stava) 2008-08-28 10:24:55 +00:00
Milan Broz
aa6e8d82ce - fix environment variable prefix to LVM (this is not GIT:-)
- add lvcreate rejects repeated invocation test
- fix pvs metadata test for partial failure test
- add pvchange reject --addtag to lvm1 pv test

(All fixes by Jaroslav Stava)
2008-08-28 10:07:34 +00:00
Dave Wysochanski
3010285bb3 Fix symbolic link creation in test infrastructure.
Original code would create "*.so" symbolic links if there were no actual
files ending in "so".  The second iteration would then cause an error
in the test logs.
2008-08-21 14:33:48 +00:00
Zdeněk Kabeláč
aaad3252f8 fail testcase for failed commands inside the for loop 2008-08-20 13:34:33 +00:00
Milan Broz
9065f534d8 Fix allocation bug in text metadata format write error path.
Function _text_pv_write doesn't use memory pool but static buffer,
call dm_pool_free in error path in _raw_write_mda_header is wrong.

Move pool free only to path where is the memory pool used.
2008-08-16 09:46:55 +00:00
Zdeněk Kabeláč
52361c94e5 valid parameter for lvchange -p is 'rw' 2008-08-13 14:28:17 +00:00
Zdeněk Kabeláč
798be60fef added test for coverage improvement
added test for metadata type 1
2008-08-13 13:49:07 +00:00
Zdeněk Kabeláč
6294154b15 get lv_list properly from vg->lst and fix compiler warning 2008-08-13 13:42:35 +00:00
Milan Broz
6594fe077d Fix vgcfgbackup to properly check filename if template is used. 2008-08-13 12:44:24 +00:00
Milan Broz
582706cde6 add tests for pvchange and vgreduce usage (Jaroslav Stava) 2008-08-12 10:04:31 +00:00
Milan Broz
6537cbdc17 test vgsplit: reject to give away pv with the last mda copy (Jaroslav Stava) 2008-08-12 10:01:56 +00:00
Zdeněk Kabeláč
53959459bb * more strict const 2008-08-07 14:02:32 +00:00
Zdeněk Kabeláč
22d6121099 added const modifiers
switched const char* to  const char[] elements to save few relocation entries
2008-08-07 14:01:17 +00:00
Zdeněk Kabeláč
48d7f6f2f4 added const and saved relocation entry 2008-08-07 13:59:49 +00:00
Zdeněk Kabeláč
9fd4ddc490 configure aborts if lcov or genhtml are missing with --enable-profiling 2008-08-05 14:29:38 +00:00
Zdeněk Kabeláč
a4d2fddbb2 add test for pool labels gfs
add test for metadatacopies0 and snapshot manipulation
2008-08-05 12:33:41 +00:00
Zdeněk Kabeláč
c54a3f2721 put dmeventd into the LD_LIBRARY_PATH for lvm-wrapper 2008-08-05 12:32:08 +00:00
Zdeněk Kabeláč
04c0dba697 vgremove tries to remove lv snapshot first.
Added function lv_remove_with_dependencies().
2008-08-05 12:05:26 +00:00
Zdeněk Kabeláč
5406e3b7c5 avoid endless option parsing loop
add support for lvm verbose operation -vvvv
add dlsym path to the test config file
2008-08-05 11:39:54 +00:00
Zdeněk Kabeláč
6b624b7d00 * parse error output for 'auto' keyword 2008-08-04 09:15:15 +00:00
Alasdair Kergon
2d364d4d80 Improve file descriptor leak detection to display likely culprit and filename. 2008-08-01 19:51:27 +00:00
Zdeněk Kabeláč
1f27bf3774 disable mdadm test-case until a better solution is found 2008-08-01 15:44:53 +00:00
Alasdair Kergon
d30a2653b5 remove now-redundant slash-stripping 2008-07-31 15:38:52 +00:00
Alasdair Kergon
3086822cd2 Change clustered mirror kernel module name from cmirror to dm-log-clustered. 2008-07-31 14:43:39 +00:00
Alasdair Kergon
2c08336490 Avoid looping forever in _pv_analyze_mda_raw used by pvck. 2008-07-31 13:07:01 +00:00
Alasdair Kergon
5936ac58c2 Change lvchange exit status to indicate if any part of the operation failed. 2008-07-31 13:03:01 +00:00
Alasdair Kergon
ded77e3f5c remove unused mdas variable 2008-07-31 12:40:52 +00:00
Alasdair Kergon
8a29df0a6c fix pvremove for pvs without mdas 2008-07-31 12:38:31 +00:00
Alasdair Kergon
9db22babaf Fix pvchange to handle PVs without mdas. 2008-07-31 12:28:51 +00:00
Alasdair Kergon
c318c5ed61 Refactor _text_pv_read and always return mda list if requested. 2008-07-31 10:50:18 +00:00
Dave Wysochanski
61243c65cd Add pvcreate tests to verify failure on md array detection. 2008-07-29 21:05:20 +00:00
Dave Wysochanski
4a5d5cb462 Fix trivial typo in pvcreate man page. 2008-07-29 18:35:00 +00:00
Dave Wysochanski
cbf1447ebd Refactor pvcreate - simplify return codes. 2008-07-25 14:59:51 +00:00
Dave Wysochanski
30104441bf Refactor pvcreate - --yes argument 2008-07-25 14:45:24 +00:00
Dave Wysochanski
b4a70804f0 Refactor pvcreate - --force parameter. 2008-07-25 14:36:55 +00:00
Dave Wysochanski
74f6707bde Refactor pvcreate - use '0' for no --uuid or --restorefile options. 2008-07-25 14:12:29 +00:00
Jim Meyering
223eb8c84d configure: regenerate 2008-07-25 08:00:40 +00:00
Jim Meyering
107d000606 Avoid compiler warnings (provoked by new configure.in bug) on RHEL5.
Do not override the default action of AC_CHECK_LIB([readline],...
(i.e., leave the ACTION-IF-FOUND parameter blank) so that the
subsequent check for rl_completion_matches can use -lreadline.

Also, replace AC_CHECK_FUNC+AC_DEFINE with an equivalent AC_CHECK_FUNCS call.
2008-07-25 08:00:18 +00:00
Dave Wysochanski
43e05607af Refactor pvcreate - move uuid and restorefile options. 2008-07-25 00:30:57 +00:00
Dave Wysochanski
55793452d5 Add pvcreate tests for uuid and restorefile. 2008-07-24 17:33:40 +00:00
Alasdair Kergon
686ba37255 . 2008-07-24 15:39:47 +00:00
Alasdair Kergon
03ed19dad5 reinstate lost FIXME
- only if kernel gives the info, not to be worked out in userspace
- with lvm.conf option to enable/disable the check
2008-07-24 15:25:09 +00:00
Jim Meyering
ad2b6e5de1 configure: regenerate 2008-07-24 14:54:26 +00:00
Jim Meyering
767676d6ff Don't make configure fail when readline library is not available. 2008-07-24 14:54:06 +00:00
Dave Wysochanski
bc7a54c615 Remove dead code, is_lvm_partition() - no functional change.
This code does nothing.  The function is #defined to 1 which ensures the only
two if statements referencing it will never be true.
2008-07-23 19:46:33 +00:00
Dave Wysochanski
1bda393678 Refactor pvcreate - move labelsector parameter parsing & validation. 2008-07-23 19:29:58 +00:00
Dave Wysochanski
bb5495c6bd Refactor pvcreate - divide parameter parsing & validation from create logic.
Move size (setphysicalvolumesize option), metadatacopies and metadatasize
validation.
2008-07-21 19:27:22 +00:00
Dave Wysochanski
484f905749 Refactor pvcreate to divide parameter parsing & validation from create logic. 2008-07-21 19:26:33 +00:00
Dave Wysochanski
e0d61a4336 Add more pvcreate tests to validate writing lvm2 label using --labelsector. 2008-07-21 18:50:10 +00:00
Dave Wysochanski
e643a16ba5 Refactor _lvcreate() - no functional change. 2008-07-17 15:19:42 +00:00
Dave Wysochanski
98fadec2b6 Only use lvm2 metadata for now. 2008-07-17 04:03:04 +00:00
Dave Wysochanski
14f464ecb0 Update pvcreate and vgsplit tests.
Add more pvcreate tests.
Start handling lvm1 and lvm2 metadata and metadatacopies=0,1.
2008-07-17 03:17:01 +00:00
Dave Wysochanski
2ecdaf9bd4 Add pvcreate sanity tests, check for label_write() failure in _text_pv_write().
Failure to check for label_write() return code caused the following test
to indicate it passed when it really failed:
pvcreate rejects labelsector > 1000000000000
2008-07-16 21:32:38 +00:00
Alasdair Kergon
707c898f66 Fix pvchange -M1 -u to preserve existing extent locations when there's a VG. 2008-07-16 10:46:12 +00:00
Alasdair Kergon
69e4400774 Cease recognising snapshot-in-use percentages returned by early development kernels. 2008-07-15 00:25:52 +00:00
Petr Rockai
695efde68d Fix gcc warnings. 2008-07-11 09:19:54 +00:00
Petr Rockai
0c4b769011 Add "flags" metadata field (akin to "status") for backward-compatible flags.
The "status" field is treated as it ever has been, unknown flags there are
treated as fatal metadata errors. However, in the "flags" field, any unknown
flags will be ignored and silently dropped. This improves
backward-compatibility possibilities. (Any versions without support for this
new "flag" field will drop the field altogether, which is same as ignoring all
the flags there.)
2008-07-10 11:30:57 +00:00
Alasdair Kergon
e53eff0634 . 2008-07-10 09:50:23 +00:00
Petr Rockai
6c75243a06 Add #include <signal.h> to dmeventd.c, fixes compilation on NetBSD. 2008-07-09 13:26:07 +00:00
Petr Rockai
efde37880b Fix dmeventd regression where mirror and snapshot monitoring libraries
failed to link against liblvm2cmd.

Dmeventd DSOs *require* lvm2cmd to be linked in.

For the future:
1) AC_SUBST does not create Makefile variables, only @foo@-style substitutions
2) When using `test', whitespace around `=' is essential:
    test a=b is true, as is test a=a
2008-07-09 09:59:42 +00:00
Alasdair Kergon
7d8f6381be post-release 2008-06-27 22:35:22 +00:00
Alasdair Kergon
3c361e3393 pre-release 2008-06-27 21:56:35 +00:00
Alasdair Kergon
8440ecef5e Enable readline by default if available. 2008-06-27 19:57:27 +00:00
Alasdair Kergon
6401f1b1c9 tweak lcov configuration/makefiles 2008-06-27 19:24:17 +00:00
Zdeněk Kabeláč
7487a7c988 Added generation of the versioned libdevmapper-event.so for LVM's test 2008-06-27 15:36:51 +00:00
Zdeněk Kabeláč
f44584fa10 extended configure with --enable-profiling for compiling code with gcov info
extended Makefile with targets:
  cov-reset - reset counters
  cov       - generete report to covhtml subdirectory
  covd      - generate report to covhtml-DATE-TIME subdirectory
2008-06-27 15:35:09 +00:00
Alasdair Kergon
7b32165614 Fix up cache for PVs without mdas after consistent VG metadata is processed. 2008-06-27 15:18:31 +00:00
Alasdair Kergon
b0dc94d187 Update validation of safe mirror log type conversions in lvconvert. (brassow) 2008-06-26 23:05:11 +00:00
Alasdair Kergon
0383c4e1d8 Fix lvconvert to disallow snapshot and mirror combinations. (mpatocka) 2008-06-26 21:38:58 +00:00
Alasdair Kergon
a8c5758222 Underline longer report help text headings. 2008-06-25 19:52:52 +00:00
Alasdair Kergon
a7fabfd8cb Fix reporting of LV fields alongside unallocated PV segments. 2008-06-25 16:52:27 +00:00
Dave Wysochanski
5d5b575d16 Test script cleanup. 2008-06-25 16:51:26 +00:00
Alasdair Kergon
ac1373653c post-release 2008-06-25 14:44:00 +00:00
518 changed files with 59589 additions and 19716 deletions

34
INSTALL
View File

@@ -1,44 +1,30 @@
LVM2 installation
=================
Installation
============
1) Install device-mapper
Ensure the device-mapper has been installed on the machine.
The device-mapper should be in the kernel (look for 'device-mapper'
messages in the kernel logs) and /usr/include/libdevmapper.h
and libdevmapper.so should be present.
The device-mapper is available from:
ftp://ftp.sistina.com/pub/LVM2/device-mapper/
2) Generate custom makefiles.
1) Generate custom makefiles.
Run the 'configure' script from the top directory.
If you wish to use the built-in LVM2 shell and have GNU readline
installed (http://www.gnu.org/directory/readline.html) use:
./configure --enable-readline
If you don't want to include the LVM1 backwards-compatibility code use:
./configure --with-lvm1=none
To separate the LVM1 support into a shared library loaded by lvm.conf use:
./configure --with-lvm1=shared
Use ./configure --help to see other options.
3) Build and install LVM2.
2) Build and install.
Run 'make install' from the top directory.
Run 'make' from the top directory to build everything you configured.
Run 'make install' to build and install everything you configured.
If you only want the device-mapper libraries and tools use
'make device-mapper' or 'make install_device-mapper'.
4) Create a configuration file
3) If using LVM2, create a configuration file.
The tools will work fine without a configuration file being
present, but you ought to review the example file in doc/example.conf.
For example, specifying the devices that LVM2 is to use can
make the tools run more efficiently - and avoid scanning /dev/cdrom!
Please also refer to the WHATS_NEW file and the manual pages for the
individual commands.

View File

@@ -1,6 +1,6 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
# Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
@@ -14,60 +14,143 @@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
top_builddir = @top_builddir@
SUBDIRS = doc include man scripts
ifeq ("@UDEV_RULES@", "yes")
SUBDIRS += udev
endif
ifeq ("@INTL@", "yes")
SUBDIRS += po
endif
SUBDIRS += lib tools daemons
SUBDIRS += lib tools daemons libdm
ifeq ("@DMEVENTD@", "yes")
SUBDIRS += dmeventd
ifeq ("@APPLIB@", "yes")
SUBDIRS += liblvm
endif
ifeq ($(MAKECMDGOALS),distclean)
SUBDIRS += daemons/clvmd \
dmeventd \
lib/format1 \
lib/format_pool \
lib/locking \
lib/mirror \
lib/snapshot \
test \
po
DISTCLEAN_TARGETS += lib/misc/configure.h
SUBDIRS = doc include man scripts \
lib tools daemons libdm \
udev po liblvm test/api test
endif
DISTCLEAN_DIRS += lcov_reports*
DISTCLEAN_TARGETS += config.cache config.log config.status make.tmpl
include make.tmpl
daemons: lib
lib: include
tools: lib
dmeventd: tools
po: tools daemons dmeventd
libdm: include
lib: libdm
liblvm: lib
daemons: lib tools
tools: lib device-mapper
po: tools daemons
lib.device-mapper: include.device-mapper
libdm.device-mapper: include.device-mapper
liblvm.device-mapper: include.device-mapper
daemons.device-mapper: libdm.device-mapper
tools.device-mapper: libdm.device-mapper
device-mapper: tools.device-mapper daemons.device-mapper man.device-mapper
ifeq ("@INTL@", "yes")
lib.pofile: include.pofile
tools.pofile: lib.pofile
daemons.pofile: lib.pofile
dmeventd.pofile: tools.pofile
po.pofile: tools.pofile daemons.pofile dmeventd.pofile
po.pofile: tools.pofile daemons.pofile
pofile: po.pofile
endif
ifneq ("@CFLOW_CMD@", "")
tools.cflow: lib.cflow
cflow: tools.cflow
ifneq ("$(CFLOW_CMD)", "")
tools.cflow: libdm.cflow lib.cflow
daemons.cflow: tools.cflow
cflow: include.cflow
endif
ifneq ("@CSCOPE_CMD@", "")
cscope.out: tools
@CSCOPE_CMD@ -b -R
cscope.out:
@CSCOPE_CMD@ -b -R -s$(top_srcdir)
all: cscope.out
endif
DISTCLEAN_TARGETS += cscope.out
check: all
$(MAKE) -C test all
check check_cluster check_local: all
$(MAKE) -C test $(@)
install_system_dirs:
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_SYS_DIR)
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_ARCHIVE_DIR)
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_BACKUP_DIR)
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_CACHE_DIR)
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_LOCK_DIR)
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_RUN_DIR)
$(INSTALL_ROOT_DATA) /dev/null $(DESTDIR)$(DEFAULT_CACHE_DIR)/.cache
install_initscripts:
$(MAKE) -C scripts install_initscripts
LCOV_TRACES = libdm.info lib.info tools.info \
daemons/dmeventd.info daemons/clvmd.info
CLEAN_TARGETS += $(LCOV_TRACES)
ifneq ("$(LCOV)", "")
.PHONY: lcov-reset lcov lcov-dated $(LCOV_TRACES)
ifeq ($(MAKECMDGOALS),lcov-dated)
LCOV_REPORTS_DIR := lcov_reports-$(shell date +%Y%m%d%k%M%S)
lcov-dated: lcov
else
LCOV_REPORTS_DIR := lcov_reports
endif
lcov-reset:
$(LCOV) --zerocounters $(addprefix -d , $(basename $(LCOV_TRACES)))
# maybe use subdirs processing to create tracefiles...
$(LCOV_TRACES):
$(LCOV) -b $(top_srcdir)/$(basename $@) \
-d $(basename $@) -c -o - | $(SED) \
-e "s/\(dmeventd_lvm.[ch]\)/plugins\/lvm2\/\1/" \
-e "s/\(dmeventd_mirror.c\)/plugins\/mirror\/\1/" \
-e "s/\(dmeventd_snapshot.c\)/plugins\/snapshot\/\1/" \
>$@
ifneq ("$(GENHTML)", "")
lcov: $(LCOV_TRACES)
$(RM) -r $(LCOV_REPORTS_DIR)
$(MKDIR_P) $(LCOV_REPORTS_DIR)
for i in $(LCOV_TRACES); do \
test -s $$i && lc="$$lc $$i"; \
done; \
test -z "$$lc" || $(GENHTML) -p @abs_top_builddir@ \
-o $(LCOV_REPORTS_DIR) $$lc
endif
endif
ifeq ("$(TESTING)", "yes")
# testing and report generation
RUBY=ruby1.9 -Ireport-generators/lib -Ireport-generators/test
.PHONEY: unit-test ruby-test test-programs
# FIXME: put dependencies on libdm and liblvm
test-programs:
cd unit-tests/regex && $(MAKE)
cd unit-tests/datastruct && $(MAKE)
cd unit-tests/mm && $(MAKE)
unit-test: test-programs
$(RUBY) report-generators/unit_test.rb $(shell find . -name TESTS)
$(RUBY) report-generators/title_page.rb
memcheck: test-programs
$(RUBY) report-generators/memcheck.rb $(shell find . -name TESTS)
$(RUBY) report-generators/title_page.rb
ruby-test:
$(RUBY) report-generators/test/ts.rb
endif

18
README
View File

@@ -1,23 +1,27 @@
This directory contains LVM2, the new version of the userland LVM
tools designed for the new device-mapper for the Linux kernel.
This tree contains the LVM2 and device-mapper tools and libraries.
The device-mapper needs to be installed before compiling these LVM2 tools.
For more information about LVM2 read the WHATS_NEW file.
For more information about LVM2 read the changelog in the WHATS_NEW file.
Installation instructions are in INSTALL.
There is no warranty - see COPYING and COPYING.LIB.
Tarballs are available from:
ftp://sources.redhat.com/pub/lvm2/
ftp://sources.redhat.com/pub/dm/
To access the CVS tree use:
cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm2 login
CVS password: cvs
cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm2 co LVM2
Mailing list for discussion/bug reports etc.
Mailing list for general discussion related to LVM2:
linux-lvm@redhat.com
Subscribe from https://www.redhat.com/mailman/listinfo/linux-lvm
Mailing list for LVM2 development, patches and commits:
lvm-devel@redhat.com
Subscribe from https://www.redhat.com/mailman/listinfo/linux-lvm
Mailing list for device-mapper development, including kernel patches
and multipath-tools:
dm-devel@redhat.com
Subscribe from https://www.redhat.com/mailman/listinfo/dm-devel

View File

@@ -1 +1 @@
2.02.39-cvs (2008-06-11)
2.02.73(2)-cvs (2010-09-18)

1
VERSION_DM Normal file
View File

@@ -0,0 +1 @@
1.02.54-cvs (2010-08-18)

932
WHATS_NEW
View File

@@ -1,5 +1,931 @@
Version 2.02.39 -
Version 2.02.73 - 18th August 2010
==================================
Fix potential for corruption during cluster mirror device failure.
Use 'SINGLENODE' instead of 'dead' in clvmd singlenode messages.
Ignore snapshots when performing mirror recovery beneath an origin.
Pass LCK_ORIGIN_ONLY flag around cluster.
Add suspend_lv_origin and resume_lv_origin using LCK_ORIGIN_ONLY.
Allow internal suspend and resume of origin without its snapshots.
Fix dev_manager_transient to access -real device not snapshot-origin.
Monitor origin -real device below snapshot instead of overlay device.
Don't really change monitoring status when in test mode.
Fix some exit statuses when starting/stopping monitoring fails.
Enable snapshot monitoring by default when dmeventd is enabled.
Move cloned libdevmapper-event client code from segments into lib/activate.
Fix 'lvconvert --splitmirrors' in cluster operation.
Fix clvmd init script exit code to return 4 when executed as non-root user.
Change default alignment of pe_start to 1MB.
Add --norestorefile option to pvcreate.
Require --restorefile when using pvcreate --uuid.
Recognise and give preference to md device partitions (blkext major).
Never scan internal LVM devices.
Don't ignore user-specified PVs in split-mirror operations. (2.02.71)
Fix data corruption bug in cluster mirrors.
Require logical volume(s) to be explicitly named for lvconvert --merge.
Avoid changing aligned pe_start as a side-effect of very verbose logging.
Use built-in rule for device aliases: block/ < dm- < disk/ < mapper/ < other.
Fix const warning in dev_manager_info() and _dev_manager_lv_rmnodes().
Fix const warning in archive_file structure from archive.c.
Clean generated files .exported_symbols_generated, example.conf for distclean.
Handle failure of all mirrored log devices and all but one mirror leg.
Disallow 'mirrored' log type for cluster mirrors.
Do not use VPATH in include/Makefile.
Fix exported_symbols generation to use standard compiler arguments.
Use #include <> not "" in lvm2app.h which gets installed on the system.
Make lib and liblvm.device-mapper wait for include file generation.
Fix configure to supply DEFAULT_RUN_DIR to Makefiles.
Fix allocation of wrong number of mirror logs with 'remove' fault policy.
Version 2.02.72 - 28th July 2010 [CVE-2010-2526]
=================================================
Change clvmd to communicate with lvm2 via a socket in /var/run/lvm.
Return controlled error if clvmd is run by non-root user.
Add configure --default-run-dir for /var/run/lvm.
Never use clvmd singlenode unless explicitly requested with -Isinglenode.
Version 2.02.71 - 28th July 2010
================================
Document LVM fault handling in doc/lvm_fault_handling.txt.
Make vgck warn about missing PVs.
Clarify help text for vg_mda_count.
Check if cluster log daemon is running before allowing cmirror create.
Add unit-tests dir.
Add configure --enable-testing and reports and report-generators dirs.
Correct LV list order used by lvconvert when splitting a mirror.
Check if LV with specified name already exists when splitting a mirror.
Fix suspend/resume logic for LVs resulting from splitting a mirror.
Update pvcreate, {pv|vg}change, and lvm.conf man pages about metadataignore.
Switch cmirrord and clvmd to use dm_create_lockfile.
Allow clvmd pidfile to be configurable.
Update comments about memory handling in lvm2app.h.
Add more verbose messages while checking volume_list and hosttags settings.
Add log_error when strdup fails in {vg|lv}_change_tag().
Remove unnecessary includes in liblvm files.
Use __attribute__ consistently throughout.
Fix redundant declarations and always compile with -Wredundant-decls.
Fix possible hang when all mirror images of a mirrored log fail.
Pass metadataignore to pv_create, pv_setup, _mda_setup, and add_mda.
Init mda->list in mda_copy.
Do not log backtrace in valid _lv_resume() code path.
Cleanup help strings in configure.in.
Prompt if metadataignore with vgextend or pvchange would adjust vg_mda_copies.
Adjust vg_mda_copies if metadataignore given with vgextend or pvchange.
Adjust auto-metadata repair and caching logic to try to cope with empty mdas.
Version 2.02.70 - 6th July 2010
===============================
Remove log directly if all mirror images of a mirrored log fail.
Randomly select which mdas to use or ignore.
Add some missing standard configure.in checks.
Add printf format attributes to yes_no_prompt and fix a caller.
Always pass unsuspended dm devices through persistent filter to other filters.
Move test for suspended dm devices ahead of other filters.
Fix another segfault in clvmd -R if no response from daemon. (2.02.68)
Remove superfluous suspended device counter from clvmd.
Fix lvm shell crash when input is entirely whitespace.
Update partial mode warning message.
Preserve memlock balance in clvmd when activation triggers a resume.
Restore the removemissing behaviour of lvconvert --repair --use-policies.
Version 2.02.69 - 30th June 2010
================================
Fix vgremove to allow removal of VG with missing PVs. (2.02.52)
Add metadata/vgmetadatacopies to lvm.conf.
Add --metadataignore to pvcreate and vgextend.
Add vg_mda_copies, pv_mda_used_count and vg_mda_used_count to reports.
Describe --vgmetadatacopies in lvm.conf and other man pages.
Add --[vg]metadatacopies to select number of mdas to use in a VG.
Make the metadata ignore bit control read/write metadata areas in a PV.
Add pvchange --metadataignore to set or clear a metadata ignore bit.
Refactor metadata code to prepare for --metadataignore / --vgmetadatacopies.
Ensure region_size of mirrored log does not exceed its full size.
Generate liblvm2app exported symbols from header file.
Preload libc locale messages to prevent reading it in memory locked state.
Fix handling of simultaneous mirror image and mirrored log image failure.
Version 2.02.68 - 23rd June 2010
================================
Fix clvmd initscript status to print only active clustered LVs.
Add lv_path to reports to offer full /dev pathname.
Fix typo in warning message about missing device with allocated data areas.
Add device name and offset to raw_read_mda_header error messages.
Honour log argument when down-converting stacked mirror.
Sleep to workaround clvmd -S race: socket closed early and server drops cmd.
Use early udev synchronisation and update of dev nodes for clustered mirrors.
Remove incorrect inclusion of kdev_t.h from cmirrord/functions.h.
Add man pages for lvmconf and non-existent lvmsadc and lvmsar tools.
Exit successfully when using -o help (but not -o +help) with LVM reports.
Do not use internal DLM lock definitions in generic LVM2 clvmd code.
Add --force, --nofsck and --resizefs to lvresize/extend/reduce man pages.
Fix lvm2cmd example in documentation.
Allow use of lvm2app and lvm2cmd headers in C++ code.
Remove unused #includes from clvmd files and introduce clvmd-common.h.
Move common inclusions to clvmd-common.h.
Use #include "" for libdevmapper.h and configure.h throughout tree.
Fix LVM_PATH expansion when exec_prefix=NONE. (2.02.67)
Fix segfault in clvmd -R if no response from daemon received.
Version 2.02.67 - 4th June 2010
===============================
Handle failed restart of clvmd using -S switch properly.
Fix clvmd initscript restart command to start clvmd if not yet running.
Use built-in absolute paths in clvmd (clvmd restart and PV and LV queries).
Require partial option in lvchange --refresh for partial LVs.
Do not fail lvm_init() if init_logging() or _init_rand() generates an errno.
Don't merge unchanged persistent cache file before dumping if tool scanned.
Fix incorrect memory pool deallocation while using vg_read for files.
Add --type parameter description to the lvcreate man page.
Replace strncmp kernel version number checks with proper ones.
Avoid selecting names under /dev/block if there is an alternative.
Update clustered log kernel module name to log-userspace for 2.6.31 onwards.
Add replicators' LVs to dtree for activation.
Supress activation message if there is a missing replicator VG.
Fix scripts/relpath.awk to work in mawk
Extend lock_vol to check for missing replicator VGs first.
Update _process_one_vg and process_each_lv_in_vg to populate cmd_vg.
Add cmd_vg structure and associated functions for replicator.
Extend _lv_each_dependency() to handle replicator dependencies.
Add check_replicator_segment() to catch internal replicator errors.
Initial support for replicator metadata.
Extend process_each_lv_in_vg() to provide list of failed lvnames.
Consistently return ECMD_FAILED if process_each_*lv() is interrupted.
Version 2.02.66 - 20th May 2010
===============================
If unable to obtain snapshot percentage leave value blank on reports.
Add install_system_dirs and install_initscripts makefile targets.
Add configure options for system and locking directories.
Generate example.conf so default lvm.conf contents can be configured.
Install lvmconf script by default.
Remove unnecessary versioned dmeventd plugin symlinks.
Add tests for lvm_vgname_from_{pvid|device}.
Add lvm2app interfaces to lookup a vgname from a pvid and pvname.
Update pvchange to always obtain a vg handle for each pv to process.
Add find_vgname_from_{pvname|pvid} functions.
Add pvid_from_devname and lvmcache_vgname_from_pvid lvmcache functions.
Validate orphan and VG_GLOBAL lock order too.
Accept orphan VG names as parameters to lock_vol() and related functions.
Use is_orphan_vg in place of hard-coded prefix tests and add is_global_vg.
Version 2.02.65 - 17th May 2010
===============================
Fix clvmd init script never to deactivate non-clustered volume groups.
Disallow vgchange --clustered if there are active mirrors or snapshots.
Introduce lv_is_mirrored.
Use /bin/bash for scripts with bashisms.
Skip internal lvm devices in scan if ignore_suspended_devices is set.
Do not merge old device cache after we run full scan. (2.02.56)
Add pkgconfigdir Makefile variable for make install override.
Configure pkgconfig udev and selinux dependencies.
Switch Libs.private to Requires.private in devmapper.pc and lvm2app.pc.
Use pkgconfig Requires.private for devmapper-event.pc.
Add libdevmapper to linked libdevmapper-event.so.
Link liblvm2cmd.so with libdevmapper-event and libdevmapper.
Fix truncated total size displayed by pvscan.
Add new --sysinit compound option to vgchange and lvchange.
Drop duplicate errors for read failures and missing devices to verbose level.
Use $(libdir)/lvm2 with make install_lvm2_plugin.
Use $(libdir)/device-mapper with make install_dm_plugin.
Add dm_list_splice() function to join two lists together.
Version 2.02.64 - 30th April 2010
=================================
Avoid pointless initialisation when the 'version' command is run directly.
Fix memory leak for invalid regex pattern input.
Display invalid regex pattern for filter configuration in case of error.
Remove no-longer-used arg_ptr_value.
Fix -M and --type to use strings, not pointers that change on config refresh.
Fix lvconvert error message when existing mirrored LV is not found.
Set appropriate udev flags for reserved LVs.
Disallow the direct removal of a merging snapshot.
Don't preload the origin when removing a snapshot whose merge is pending.
Disallow the addition of mirror images while a conversion is happening.
Disallow primary mirror image removal when mirror is not in-sync.
Remove obsolete --name parameter from vgcfgrestore.
Add -S command to clvmd to restart the daemon preserving exclusive locks.
Increment lvm2app version from 1 to 2 (memory allocation changes).
Change lvm2app memory alloc/free for pv/vg/lv properties.
Change daemon lock filename from lvm2_monitor to lvm2-monitor for consistency.
Install symbolic .so links with relative paths between usrlibdir and libdir.
Add awk script relpath.awk to calculate paths for relative symlinks.
Use @AWK@ in makefiles.
Fix double DESTDIR usage for infodir and mandir.
Version 2.02.63 - 14th April 2010
=================================
Rename lvm_dump.sh to lvmdump.sh.
Allow incomplete mirror restore in lvconvert --repair upon insufficient space.
Do not reset position in metadata ring buffer on vgrename and vgcfgrestore.
Allow VGs with active LVs to be renamed.
Use UUIDs instead of names while processing event handlers.
Only pass visible LVs to tools in cmdline VG name/tag expansions without -a.
Use typedefs for toollib process_each functions.
Use C locales and use_mlockall for clvmd.
Refactor code related to vg->pvs list and add pv->vg link.
Mask LCK_HOLD flag in cluster VG locks for backwards compatibility.
Add activation/polling_interval to lvm.conf as --interval default.
Don't ignore error if resuming any LV fails in resume_lvs.
Skip closing persistent filter cache file if open failed.
Install .a and .so links into $(usrlibdir).
Add --enable-write_install options to install user-writable files.
Use INSTALL_PROGRAM/DATA/WDATA target.
Switch from using VPATH to vpath in Makefiles.
Permit mimage LVs to be striped in lvcreate, lvresize and lvconvert.
Fix pvmove allocation to take existing parallel stripes into account.
Add pvmove_source_seg to struct lv_segment.
Fix incorrect removal of symlinks after LV deactivation fails.
Fix is_partitioned_dev not to attempt to reopen device.
Fix another thread race in clvmd.
Refactor management of vg->pvs list.
Fix lcov rules and generate better coverage report.
Improve vg_validate to detect some loops in lists.
Change most remaining log_error WARNING messages to log_warn.
Always use blocking lock for VGs and orphan locks.
Allocate all memory for segments from private VG mempool.
Return newly allocated PV segment after segment split.
Optimise searching PV segments for seeking the most recently-added.
Remove vg_validate call when parsing cached metadata.
Use hash table of LVs to speed up parsing of text metadata with many LVs.
Fix two vg_validate messages, adding whitespace and parentheses.
When dmeventd is not forking because of -d flag, don't kill parent process.
Fix 'make install' when $(builddir) is different from $(srcdir).
Fix dso resource leak in error path of dmeventd.
Use C locales and use_mlockall for dmeventd.
Fix --alloc contiguous policy only to allocate one set of parallel areas.
Do not allow {vg|lv}change --ignoremonitoring if on clustered VG.
Improved dependency tracking for dmeventd and liblvm2cmd sources.
Improved Makefile rules for distclean and cflow targets.
Add ability to create mirrored logs for mirror LVs.
Fix clvmd cluster propagation of dmeventd monitoring mode.
Allow ALLOC_ANYWHERE to split contiguous areas.
Use INTERNAL_ERROR for internal errors throughout tree.
Add some assertions to allocation code.
Introduce pv_area_used into allocation algorithm and add debug messages.
Add activation/monitoring to lvm.conf.
Add --monitor and --ignoremonitoring to lvcreate.
Allow dynamic extension of array of areas selected as allocation candidates.
Export and use only valid cookie value in test suite.
Remove const modifier for struct volume_group* from process_each_lv_in_vg().
Don't allow resizing of internal logical volumes.
Fix libdevmapper-event pkgconfig version string to match libdevmapper.
Avoid scanning all pvs in the system if operating on a device with mdas.
Add configure --with-clvmd=singlenode to use clvmd w/o cluster infrastructure.
Get stacktrace if testsuite test drops core and lvm was built with debugging.
Disable long living process flag in lvm2app.
Fix pvcreate device md filter check.
Suppress repeated errors about the same missing PV uuids.
Bypass full device scans when using internally-cached VG metadata.
Only do one full device scan during each read of text format metadata.
Remove unnecessary full_scan parameter from get_vgids and get_vgnames calls.
Look up missing PVs by uuid not dev_name in _pvs_single to avoid invalid stat.
Make find_pv_in_vg_by_uuid() return same type as related functions.
Introduce is_missing_pv().
Fix clvmd Makefile to not overwrite LIBS from template definition.
Version 2.02.62 - 9th March 2010
================================
Add use_mlockall and mlock_filter to activation section of lvm.conf.
Add default alternative to mlockall using mlock to reduce pinned memory size.
Remove -rdynamic from static builds.
Update checks for pthread, readline & selinux libs and link only when needed.
Introduce makefile vars UDEV_LIBS, DL_LIBS, SELINUX_LIBS, STATIC_LIBS.
Introduce makefile vars LVMINTERNAL_LIBS, READLINE_LIBS, PTHREAD_LIBS.
Toggle configure help to print --disable-fsadm.
Use $() instead of ${} consistently for all Makefile variables.
Replace CFLOW_CMD only in make.tmpl and use it as variable elsewhere.
Use $(top_builddir) for inclusion of make.tmpl in Makefiles.
Fix autoconf warning about ignored datarootdir.
Increase AC_PREREQ version to 2.61 (for AC_PROC_SED, AC_PROG_MKDIR_P).
Handle misaligned devices that report alignment_offset of -1.
Extend core allocation code in preparation for mirrored log areas.
Rewrite clvmd init script.
Remove lvs_in_vg_activated_by_uuid_only call.
No longer fall back to looking up active devices by name if uuid not found.
Don't touch /dev in vgmknodes if activation is disabled.
Update lvm2app.h Doxygen comments and add lvm2app Doxygen config file.
Update nightly tests and lvm2app unit tests to cover tags.
Add lvm2app functions lvm_{vg|lv}_{get|add|remove}_tag() functions.
Add dm_pool_strdup to allocate and copy memory in tag library function.
Refactor vgcreate, vgchange, and lvchange for tag library function.
Refactor snapshot-merge deptree and device removal to support info-by-uuid.
Version 2.02.61 - 15th February 2010
====================================
Fix some consts and floating point gcc warnings.
Fix dm_report_field_uint64 function to accept 64-bit ints.
Change readhead display to use 32-bit -1 const instead of 64-bit.
Add LVM_SUPPRESS_LOCKING_FAILURE_MESSAGES environment variable.
Remove hard-coding that skipped _mimage devices from 11-dm-lvm.rules.
Use udev transactions in test suite.
Set udev state automatically instead of using LVM_UDEV_DISABLE_CHECKING.
Add lvm_pv_get_size, lvm_pv_get_free and lvm_pv_get_dev_size to lvm2app.
Change lvm2app to return all sizes in bytes as documented (not sectors).
Add 'fail_if_percent_unsupported' arg to _percent and _percent_run.
Remove false "failed to find tree node" error when activating merging origin.
Exit with success when lvconvert --repair --use-policies performs no action.
Accept a list of LVs with 'lvconvert --merge @tag' using process_each_lv.
Avoid unnecessary second resync when adding mimage to core-logged mirror.
Exclude internal VG names and uuids from lists returned through lvm2app.
Add %ORIGIN support to lv{create,extend,reduce,resize} --extents.
Add _mda_copy to clone a struct metadata_area.
Remove pointless versioned symlinks to dmeventd plugin libraries.
Fix dmeventd snapshot plugin build dependency.
Make clvmd -V return status zero.
Remove unnecessary 'dmsetup resume' following 'dmsetup create' in tests.
Fix cmirrord segfault in clog_cpg list processing when converting mirror log.
Deactivate temporary pvmove mirror cluster-wide when activating it fails.
Always query device by uuid and not name in clvmd.
Add missing metadata vg_reverts in pvmove error paths.
Unlock shared lock in clvmd if activation calls fail.
Return success from dev_manager_info with non-existent uuid if ioctl succeeds.
Version 2.02.60 - 23rd January 2010
===================================
Extend cmirrord man page.
Sleep before first progress check if pvmove/lvconvert interval has prefix '+'.
Default to checking progress before waiting in _wait_for_single_lv.
Fix cmirror initscript (including syntax error).
Eliminate avoidable ioctls for checking open_count in _add_new_lv_to_dtree.
Disable memory debugging if dmeventd is configured. (Not thread-safe.)
Fix first log message prefix in syslog for dmeventd plugins.
Fix exported symbols names for dmeventd lvm2 wrapper plugin.
Make failed locking initialisation messages more descriptive.
Version 2.02.59 - 21st January 2010
===================================
Add libdevmapper-event-lvm2.so to serialise dmeventd plugin liblvm2cmd use.
Cleanup memory initialization and freeing in pv_read() and pv_create().
Clear pointer and counters after their release in _fin_commands().
Stop dmeventd trying to access already-removed snapshots.
Remove (fallback) /dev mknod from cmirrord.
Add t-topology-support.sh and t-snapshot-merge.sh tests.
Fix clvmd to never scan suspended devices.
Fix dmeventd build outside source tree.
Assorted cmirror code changes to remove various compiler warnings.
Fix detection of completed snapshot merge.
Add Red Hat cmirror initscript (unfinished).
Add cmirrord man page (incomplete).
Make cluster log communication structures architecture independant.
Fix cluster log in-memory bitmap handling.
Improve snapshot merge metadata import validation.
Improve target type compatibility checking in _percent_run().
Add 'target_status_compatible' method to 'struct segtype_handler'.
Change underscore to hyphen in table line for clustered log type.
Version 2.02.58 - 14th January 2010
===================================
Cleanup some minor gcc warnings.
Add --merge to lvconvert to merge a snapshot into its origin.
Fix clvmd automatic target module loading crash (no reset_locking fn).
Fix allocation code not to stop at the first area of a PV that fits.
Version 2.02.57 - 12th January 2010
===================================
Ensure exactly one process returns from poll_daemon(), never two.
Reset _vgs_locked in lvmcache_init() in child after forking.
Define {DM, LVM}_UDEV_DISABLE_CHECKING=1 environment variables during tests.
Enable udev_sync and udev_rules in lvm.conf by default while running tests.
If LVM_UDEV_DISABLE_CHECKING in set in environment, disable udev warnings.
Add --splitmirrors to lvconvert to split off part of a mirror.
Change background polldaemon's process name to "(lvm2)".
Allow vgremove to remove a VG with PVs missing after a prompt.
Return success in lvconvert --repair --use-policies on failed allocation.
Keep log type consistent when changing mirror image count.
Always set environment variables for an LVM2 device in 11-dm-lvm.rules.
Add activation/udev_rules config option in lvm.conf.
Add consts to text metadata flag structs.
Add macros outfc, outsize, outhint and function out_text_with_comment.
Reimplement report FIELD macro using offsetof instead of static structs.
Fix fsadm man page typo (fsdam).
Rename mirror_device_fault_policy to mirror_image_fault policy.
Remove empty PV devices if lvconvert --repair is using defined policies.
Use fixed buffer to prevent stack overflow in persistent filter dump.
Use extended status of new kernel snapshot target 1.8.0 to detect when empty.
Insert stack macros in suspend_lv, resume_lv & (de)activate_lv callers.
Add --poll flag to vgchange and lvchange to control background daemon launch.
Propagate metadata commit and revert notifications to other cluster nodes.
Use proper mask for VG lock mode in clvmd.
Allow precommitted metadata to be dropped from lvmcache.
Move processing of VG locks to separate function in clvmd.
Properly decode all flags in clvmd messages including VG locks.
Properly handle precommitted cache flag when only committed metadata present.
Resume renamed volumes in reverse order to preserve memlock pairing.
Drop cached metadata after device was auto-repaired and removed from VG.
Clear MISSING_PV flag if PV reappeared and is empty.
Fix removal of multiple devices from a mirror.
Also clean up PVs flagged as missing in vgreduce --removemissing --force.
Introduce INTERNAL_ERROR macro for error messages and use throughout.
Remove superfluous returns from void functions.
Destroy allocated mempool in _vg_read_orphans() error path.
Fix some pvresize and toollib error paths with missing VG releases/unlocks.
Explicitly call suspend for temporary mirror layer.
Allow use of precommitted metadata when a PV is missing.
Add memlock information to do_lock_lv debug output.
Always bypass calls to remote cluster nodes for non-clustered VGs.
Permit implicit cluster lock conversion in pre/post callbacks on local node.
Permit implicit cluster lock conversion to the lock mode already held.
Fix lock flag masking in clvmd so intended code paths get invoked.
Replace magic masks in cluster locking code by defined masks.
Remove newly-created mirror log from metadata if initial deactivation fails.
Correct activated or deactivated text in vgchange summary message.
Improve pvmove error message when all source LVs are skipped.
Fix memlock imbalance in lv_suspend if already suspended.
Fix pvmove test mode not to poll (and fail).
Fix vgcreate error message if VG already exists.
Fix tools to use log_error when aborted due to user response to prompt.
Fix ignored readahead setting in lvcreate --readahead.
Fix clvmd memory leak in lv_info_by_lvid by calling release_vg.
If aborting due to internal error, always send that message to stderr.
Add global/abort_on_internal_errors to lvm.conf to assist testing.
Fix test Makefiles when builddir and srcdir differ.
Impose limit of 8 mirror images to match the in-kernel kcopyd restriction.
Use locking_type 3 (compiled in) for lvmconf --enable-cluster.
Remove list.c and list.h with no-longer-used dm_list macros and functions.
Log failure type and recognise type 'F' (flush) in dmeventd mirror plugin.
Extend internal PV/VG/LV/segment status variables from 32-bit to 64-bit.
Version 2.02.56 - 24th November 2009
====================================
Add missing vg_release to pvs and pvdisplay to fix memory leak.
Do not try to unlock VG which is not locked in _process_one_vg.
Move is_long_lived persistent_filter_dump to happen after every full scan.
Refresh device filters before full device rescan in lvmcache.
Return error status if vgchange fails to activate some volume.
Fix suspend/resume lock type test causing unbalanced memory locking.
Revert vg_read_internal change as clvmd was not ready for vg_read. (2.02.55)
Version 2.02.55 - 19th November 2009
====================================
Fix deadlock when changing mirrors due to unpaired memlock refcount changes.
Use separate memlock counter for dmeventd handlers to permit device scanning.
Directly restrict vgchange to activating visible LVs.
Fix pvmove region_size overflow for very large PVs.
Fix lvcreate and lvresize %PVS argument always to use sensible total size.
Tidy some uses of arg_count and introduce arg_is_set.
Export outnl and indent functions for modules.
Flush stdout after yes/no prompt.
Update vgsplit and vgcreate to use vg_set_clustered.
Add vg_mda_count and vg_set_clustered library functions.
Add more vgcreate and vgsplit nightly tests.
Insert some missing stack macros into activation code.
Recognise DRBD devices and handle them like md devices.
Version 2.02.54 - 26th October 2009
===================================
Update lvcreate/lvconvert man pages to explain PhysicalVolume parameter.
Document --all option in man pages, cleanup {pv|vg|lv}{s|display} man pages.
Permit snapshots of mirrors.
Cleanup mimagetmp LV if allocation fails for new lvconvert mimage.
Fix clvmd segfault when refresh_toolcontext fails.
Remember to clear 'global lock held during cache refresh' state after use.
Use udev flags support in LVM and apply various fixes to udev rules.
Delay announcing mirror monitoring to syslog until initialisation succeeded.
Handle metadata with unknown segment types more gracefully.
Set default owner and group to null.
Add dmeventd.static to the build.
Disable realtime support code by default.
Make clvmd return 0 on success rather than 1.
Add --pvmetadatacopies for pvcreate, vgcreate, vgextend, vgconvert.
Add implict pvcreate support to vgcreate and vgextend.
Correct example.conf to indicate that lvm2 not lvm1 is the default format.
Remove an unused stray LVM1_SUPPORT ifdef.
Only include selinux libs in libdevmapper.pc when selinux build enabled.
Allow for a build directory separate from the source.
Update distclean target for rename clogd to cmirrord. (2.02.52)
Only do lock conversions in clvmd if we are explicitly asked for one.
Introduce percent_range_t and centralise snapshot full/mirror in-sync checks.
Factor out poll_mirror_progress and introduce progress_t.
Distinguish between powers of 1000 and powers of 1024 in unit suffixes.
Restart lvconverts in vgchange by sharing lv_spawn_background_polling.
Generalise polldaemon code by changing mirror-specific variable names.
Don't attempt to deactivate an LV if any of its snapshots are in use.
Return error if lv_deactivate fails to remove device from kernel.
Provide alternative implementation of obsolete siginterrupt().
Consolidate LV allocation into alloc_lv().
Treat input units of both 's' and 'S' as 512-byte sectors. (2.02.49)
Use standard output units for 'PE Size' and 'Stripe size' in pv/lvdisplay.
Add configure --enable-units-compat to set si_unit_consistency off by default.
Add global/si_unit_consistency to enable cleaned-up use of units in output.
Version 2.02.53 - 25th September 2009
=====================================
Create any directories in /dev with DM_DEV_DIR_UMASK (022).
Enable dmeventd monitoring section of config file by default.
Update lvm2 monitoring script to lvm2_monitoring_init_red_hat.in.
Fix lvm2app test to run under test/api subdirectory only when configured.
Add vg_is_resizeable() and cleanup reference to VG_RESIZEABLE.
Version 2.02.52 - 15th September 2009
=====================================
Update _process_one_vg to cleanup properly after vg_read_error.
Add lots of missing stack debug messages to tools.
Make readonly locking available as locking type 4.
Fix readonly locking to permit writeable global locks (for vgscan). (2.02.49)
Add DM_UDEV_RULES_VSN environment variable to udev rules.
Update vgsplit, vgmerge, and vgrename to obey new vgname ordering rules.
Make lvm2app pv_t, lv_t, vg_t handle definitions consistent with lvm_t.
Enforce an alphabetical lock ordering on vgname locking.
Prioritise write locks over read locks by default for file locking.
Add local lock files with suffix ':aux' to serialise locking requests.
Fix global locking in PV reporting commands (2.02.49).
Fix pvcreate string termination in duplicate uuid warning message.
Don't loop reading sysfs with pvcreate on a non-blkext partition (2.02.51).
Fix vgcfgrestore error paths when locking fails (2.02.49).
Update Makefile distclean target.
Add libudev configuration check.
Make clvmd check corosync to see what cluster interface it should use.
Add clvmd autodetection check and cleanup related configure messages.
Rewrite clvmd configuration code to cope with all combinations of libs.
Added configure --enable-cmirrord to build the cluster mirror log daemon.
Rename clogd to cmirrord.
Make lvchange --refresh only take a read lock on volume group.
Fix race where non-blocking file locks could be granted in error.
Fix vgextend error path - if ORPHAN lock fails, unlock / release vg (2.02.49).
Fix compile warning in clvmd.
Clarify use of PE ranges in lv{convert|create|extend|resize} man pages.
Remove useless _pv_write wrapper.
Add lvm2app.sh to tests conditional upon configure --enable-applib.
Add lvm_vg_is_clustered, lvm_vg_is_exported, and lvm_vg_is_partial.
Update lvm_vg_remove to require lvm_vg_write to commit remove to disk.
Update test/api/test.c to call lvm_vg_create and lvm_vg_remove.
Version 2.02.51 - 6th August 2009
=================================
Fix locking in clvmd (2.02.50).
Add --noudevsync option for relevant LVM tools.
Add activation/udev_sync to lvm.conf.
Only change LV symlinks on ACTIVATE not PRELOAD.
Make lvconvert honour log mirror options combined with downconversion.
Allow LV suspend while --ignorelockingfailure is in force.
Update synopsis in lvconvert manpage to mention --repair.
Set cookies in activation code and wait for udev to complete processing.
Added configure --enable-udev_rules --enable-udev_sync.
Added configure --with-udev-prefix --with-udevdir.
Added udev dir to hold udev rules.
Add devices/data_alignment_detection to lvm.conf.
Add devices/data_alignment_offset_detection to lvm.conf.
Add --dataalignmentoffset to pvcreate to shift start of aligned data area.
Fix _mda_setup() to not check first mda's size before pe_align rounding.
Document -I option of clvmd in the man page.
Fix configure script to handle multiple clvmd selections.
Fix lvm2app.pc installation filename.
Remove pv_t, vg_t & lv_t handles from lib. Only liblvm uses them.
Rename lvm.h to lvm2app.h for now.
Version 2.02.50 - 28th July 2009
================================
Change test/api/test.c prompt so it's not confused with the main lvm prompt.
Update liblvm unit tests in test/api to cover latest liblvm changes.
Add unimplemented lvm_lv_resize and lvm_pv_resize skeletons to liblvm.
Add lvm_library_get_version to liblvm.
Add lvm_config_override to liblvm to allow caller to override LVM config.
Add lvm_lv_is_active and lvm_lv_is_suspended to liblvm.
Add lvm_lv_activate and lvm_lv_deactivate to liblvm.
Add lvm_scan, lvm_vg_reduce and lvm_vg_remove_lv to liblvm.
Add functions to get numeric properties to liblvm.
Add lvm_{pv|vg|lv}_get_{name|uuid} to liblvm.
Add lvm_vg_list_pvs and lvm_vg_list_lvs to liblvm.
Add lvm_vg_open and lvm_vg_create_lv_linear to liblvm.
Add lvm_list_vg_names/uuids to liblvm.
Add lvm_errno and lvm_errmsg to liblvm to obtain failure information.
Rename lvm_create/destroy to lvm_init/quit.
Rename lvm_reload_config to lvm_config_reload.
Refactor _override_settings to use new override_config_tree_from_string.
Add vg_reduce to metadata.c and metadata-exported.h.
Update lvm.h to clarify API behavior and return codes.
Update lvm_vg_extend to do an implicit pvcreate on the device.
Update display.c to use vg_free(vg) instead of duplicating the calculation.
Refactor vg_size, vg_free, and pv_mda_count field calculations for liblvm.
Refactor pvcreate and lvcreate for liblvm.
Add global/wait_for_locks to lvm.conf so blocking for locks can be disabled.
All LV locks are non-blocking so remove LCK_NONBLOCK from separate macros.
Fix race condition with vgcreate and vgextend on same device (2.02.49).
Remove redundant validate_name call from vgreduce.
Remove unused handles lvseg, pvseg inside liblvm/lvm.h.
Add liblvm2app Makefile installation targets.
Add liblvm pkgconfig file.
Use newly-independent LVM_LIBAPI in liblvm soname. E.g. liblvm2app.so.2.1.
Add an API version number, LVM_LIBAPI, to the VERSION string for liblvm.
Pass a pointer to struct cmd_context to init_multiple_segtypes
Return EINVALID_CMD_LINE not success when invalid VG name format is used.
Remove unnecessary messages after vgcreate/vgsplit refactor (2.02.49).
Add log_errno to set a specific errno and replace log_error in due course.
Change create_toolcontext to still return an object if it fails part-way.
Add EUNCLASSIFIED (-1) as the default LVM errno code.
Store any errno and error messages issued while processing each command.
Use log_error macro consistently throughout in place of log_err.
Version 2.02.49 - 15th July 2009
================================
Add readonly locking type to replace implementation of --ignorelockingfailure.
Exclude VG_GLOBAL from vg_write_lock_held so scans open devs read-only again.
Add unit test case for liblvm VG create/delete APIs.
Add liblvm APIs to implement creation and deletion of VGs.
Initialize cmd->cmd_line to "liblvm" in new liblvm library.
Place handles to liblvm objects for pv, vg, lv, lvseg, pvseg inside lvm.h.
Refactor vgsplit and vgextend to remove READ_REQUIRE_RESIZEABLE flag.
Use _exit() not exit() after forking to avoid flushing libc buffers twice.
Add cast to log_info arg in _find_labeller to avoid Sparc64 warning.
Make cmd->cmd_line const.
Fix dev name mismatch in vgcreate man page example.
Refactor vg_remove_single for use in liblvm.
Make all tools use consistent lock ordering obtaining VG_ORPHAN lock second.
Check md devices for a partition table during device scan.
Add extended device (blkext) and md partition (mdp) types to filters.
Make text metadata read errors for segment areas more precise.
Fix text segment metadata read errors to mention correct segment name.
Include segment and LV names in text segment import error messages.
Add parent node to config_node structure.
Update vgsplit and vgcreate to call new vg_create and 'set' functions.
Change vg_create to take minimal parameters, obtain a lock, and return vg_t.
Refactor vgchange extent_size, max_lv, max_pv, and alloc_policy for liblvm.
Update t-vgcreate-usage.sh to test for default vg properties.
Fix memory leak in vgsplit when re-reading the vg.
Make various exit/cleanup paths more robust after lvm init failures.
Use LCK_NONBLOCK implicitly instead of explicit vg_read() flag.
Remove unnecessary locking and existence tests from new vg_read() interface.
Permit several segment types to be registered by a single shared object.
Update the man pages to document size units uniformly.
Allow commandline sizes to be specified in terms of bytes and sectors.
Update 'md_chunk_alignment' to use stripe-width to align PV data area.
Update test/t-inconsistent-metadata.sh to match new vg_read interface.
Add lvmcache_init() to polldaemon initialization.
Convert tools to use new vg_read / vg_read_for_update.
Fix segfault in vg_release when vg->cmd is NULL.
Version 2.02.48 - 30th June 2009
================================
Abort if automatic metadata correction fails when reading VG to update it.
Explicitly request fallback to default major number in device mapper.
Ignore suspended devices during repair.
Call vgreduce --removemissing automatically to fix missing PVs in dmeventd.
Suggest using lvchange --resync when adding leg to not-yet-synced mirror.
Destroy toolcontext on clvmd exit to avoid memory pool leaks.
Fix lvconvert not to poll mirror if no conversion in progress.
Fix memory leaks in toolcontext error path.
Reinstate partial activation support in clustered mode. (2.02.40)
Allow metadata correction even when PVs are missing.
Use 'lvm lvresize' instead of 'lvresize' in fsadm.
Do not use '-n' realine option in fsadm for busybox compatiblity.
Add vg_lock_newname() library function for vgrename, vgsplit and vgcreate.
Round up requested readahead to at least one page and print warning.
Try to repair vg before actual vgremove when force flag provided.
Fix possible double release of VG after recovery.
Add parameter to process_each_vg specifying what to do with inconsistent VG.
Unify error messages when processing inconsistent volume group.
Use lvconvert --repair instead of vgreduce in mirror dmeventd DSO.
Introduce lvconvert --use_policies (repair policy according to lvm.conf).
Update clvmd-corosync to match new corosync API.
Fix lib Makefile to include any shared libraries in default target.
Fix rename of active snapshot with virtual origin.
Fix convert polling to ignore LV with different UUID.
Cache underlying device readahead only before activation calls.
Fix segfault when calculating readahead on missing device in vgreduce.
Remove verbose 'visited' messages.
Handle multi-extent mirror log allocation when smallest PV has only 1 extent.
Add LSB standard headers and functions (incl. reload) to clvmd initscript.
When creating new LV, double-check that name is not already in use.
Remove /dev/vgname/lvname symlink automatically if LV is no longer visible.
Rename internal vorigin LV to match visible LV.
Suppress 'removed' messages displayed when internal LVs are removed.
Fix lvchange -a and -p for sparse LVs.
Fix lvcreate --virtualsize to activate the new device immediately.
Make --snapshot optional with lvcreate --virtualsize.
Generalise --virtualoriginsize to --virtualsize.
Skip virtual origins in process_each_lv_in_vg() without --all.
Fix counting of virtual origin LVs in vg_validate.
Attempt to load dm-zero module if zero target needed but not present.
Version 2.02.47 - 22nd May 2009
===============================
Rename liblvm.so to liblvm2app.so and use configure --enable-applib.
Reinstate version in liblvm2cmd.so soname. (2.02.44)
Version 2.02.46 - 21st May 2009
===============================
Inherit readahead setting from underlying devices during activation.
Detect LVs active on remote nodes by querying locks if supported.
Enable online resizing of mirrors.
Use suspend with flush when device size was changed during table preload.
Implement query_resource_fn for cluster_locking.
Support query_resource_fn in locking modules.
Introduce CLVMD_CMD_LOCK_QUERY command for clvmd.
Fix pvmove to revert operation if temporary mirror creation fails.
Fix metadata export for VG with missing PVs.
Add vgimportclone and install it and the man page by default.
Force max_lv restriction only for newly created LV.
Remove unneeded import parameter from lv_create_empty.
Merge lv_is_displayable and lv_is_visible functions.
Introduce lv_set_visible & lv_set_hidden functions.
Fix lv_is_visible to handle virtual origin.
Introduce link_lv_to_vg and unlink_lv_from_vg functions.
Remove lv_count from VG and use counter function instead.
Fix snapshot segment import to not use duplicate segments & replace.
Do not query nonexistent devices for readahead.
Remove NON_BLOCKING lock flag from tools and set a policy to auto-set.
Remove snapshot_count from VG and use function instead.
Fix first_seg() call for empty segment list.
Add install_lvm2 makefile target to install only the LVM2 components.
Reject missing PVs from allocation in toollib.
Fix PV datalignment for values starting prior to MDA area. (2.02.45)
Add sparse devices: lvcreate -s --virtualoriginsize (hidden zero origin).
Fix minimum width of devices column in reports.
Add lvs origin_size field.
Fix linux configure --enable-debug to exclude -O2.
Implement lvconvert --repair for repairing partially-failed mirrors.
Fix vgreduce --removemissing failure exit code.
Fix remote metadata backup for clvmd.
Introduce unlock_and_release_vg macro.
Introduce vg_release() to be called to free every struct volume_group.
Alloc PV internal structure from VG mempool if possible.
Fix metadata backup to run after vg_commit always.
Tidy clvmd volume lock cache functions.
Fix pvs report for orphan PVs when segment attributes are requested.
Fix pvs -a output to not read volume groups from non-PV devices.
Add MMC (mmcblk) device type to filters.
Introduce memory pools per volume group (to reduce memory for large VGs).
Use copy of PV structure when manipulating global PV lists.
Always return exit error status when locking of volume group fails.
Fix mirror log convert validation question.
Avoid referencing files from DESTDIR during build process.
Avoid creating some static libraries unless configured --enable-static_link.
Enable use of cached metadata for pvs and pvdisplay commands.
Add missing 'device-mapper' internal subdir build dependency.
Fix memory leak in mirror allocation code.
Save and restore the previous logging level when log level is changed.
Fix error message when archive initialization fails.
Make sure clvmd-corosync releases the lockspace when it exits.
Fix segfault for vgcfgrestore on VG with missing PVs.
Block SIGTERM & SIGINT in clvmd subthreads.
Detect and conditionally wipe swapspace signatures in pvcreate.
Fix maximal volume count check for snapshots if max_lv set for volume group.
Fix lvcreate to remove unused cow volume if the snapshot creation fails.
Fix error messages when PV uuid or pe_start reading fails.
Build new liblvm application-level library.
Rename liblvm.a to liblvm-internal.a.
Flush memory pool and fix locking in clvmd refresh and backup command.
Fix unlocks in clvmd-corosync. (2.02.45)
Fix error message when adding metadata directory to internal list fails.
Fix size and error message of memory allocation at backup initialization.
Remove old metadata backup file after renaming VG.
Restore log_suppress state when metadata backup file is up-to-date.
Version 2.02.45 - 3rd March 2009
================================
Avoid scanning empty metadata areas for VG names.
Attempt proper clean up in child before executing new binary in exec_cmd().
Do not scan devices if reporting only attributes from PV label.
Use pkgconfig to obtain corosync library details during configuration.
Fix error returns in clvmd-corosync interface to DLM.
Add --refresh to vgchange and vgmknodes man pages.
Pass --test from lvresize to fsadm as --dry-run.
Supply argv[] list to exec_cmd() to allow for variable number of parameters.
Prevent fsadm from checking mounted filesystems.
No longer treats any other key as 'no' when prompting in fsadm.
Tidy fsadm command line processing.
Add lib/lvm.h and lib/lvm_base.c for the new library interface.
Move tools/version.h to lib/misc/lvm-version.h.
Split LVM_VERSION into MAJOR, MINOR, PATCHLEVEL, RELEASE and RELEASE_DATE.
Add system_dir parameter to create_toolcontext().
Add --dataalignment to pvcreate to specify alignment of data area.
Exclude LCK_CACHE locks from _vg_lock_count, fixing interrupt unblocking.
Provide da and mda locations in debug message when writing text format label.
Mention the restriction on file descriptors at invocation on the lvm man page.
Index cached vgmetadata by vgid not vgname to cope with duplicate vgnames.
No longer require kernel and metadata major numbers to match.
Add a fully-functional get_cluster_name() to clvmd corosync interface.
Remove duplicate cpg_initialize from clvmd startup.
Add option to /etc/sysconfig/cluster to select cluster type for clvmd.
Allow clvmd to start up if its lockspace already exists.
Separate PV label attributes which do not need parse metadata when reporting.
Remove external dependency on the 'cut' command from fsadm.
Fix pvs segfault when pv mda attributes requested for not available PV.
Add fsadm support for reszing ext4 filesysystems.
Move locking_type reading inside init_locking().
Rename get_vgs() to get_vgnames() and clarify related error messages.
Allow clvmd to be built with all cluster managers & select one on cmdline.
Mention --with-clvmd=corosync in ./configure.
Replace internal vg_check_status() implementation.
Rename vg_read() to vg_read_internal().
Version 2.02.44 - 26th January 2009
===================================
Fix --enable-static_link after the recent repository changes.
Add corosync/DLM cluster interface to clvmd.
Add --nameprefixes, --unquoted, --rows to pvs, vgs, lvs man pages.
Fix lvresize size conversion for fsadm when block size is not 1K.
Fix pvs segfault when run with orphan PV and some VG fields.
Display a 'dev_size' of zero for missing devices in reports.
Add pv_mda_size to pvs and vg_mda_size to vgs.
Fix lvmdump /sys listing to include virtual devices directory.
Add "--refresh" functionality to vgchange and vgmknodes.
Avoid exceeding LV size when wiping device.
Calculate mirror log size instead of using 1 extent.
Ensure requested device number is available before activating with it.
Fix incorrect exit status from 'help <command>'.
Fix vgrename using UUID if there are VGs with identical names.
Fix segfault when invalid field given in reporting commands.
Move is_static from cmd to global is_static().
Refactor init_lvm() for lvmcmdline and clvmd.
Add liblvm interactive test infrastructure to build.
Add skeleton lvm2.h file in preparation for a shared library interface.
Use better random seed value in temp file creation.
Add read_urandom to read /dev/urandom. Use in uuid calculation.
Use displayable_lvs_in_vg and lv_is_displayable for consistency throughout.
Fix race in vgcreate that would result in second caller overwriting first.
Fix uninitialised lv_count in vgdisplay -c.
Don't skip updating pvid hash when lvmcache_info struct got swapped.
Add tinfo to termcap search path for pld-linux.
Fix startup race in clvmd.
Generate Red Hat clvmd startup script at config time with correct paths.
Fix clvmd & dmeventd builds after tree restructuring.
Cope with snapshot dependencies when removing a whole VG with lvremove.
Make man pages and tool help text consistent using | for alternative options.
Version 2.02.43 - 10th November 2008
====================================
Merge device-mapper into the lvm2 tree.
Correct prototype for --permission on lvchange and lvcreate man pages.
Exit with non-zero status from vgdisplay if couldn't show any requested VG.
Move list.c into libdevmapper and rename functions.
Rename a couple of variables that matched function names.
Use simplified x.y.z version number in libdevmapper.pc.
Remove ancient debian directory.
Split out lvm-logging.h from log.h and lvm-globals.[ch] from log.[ch].
Version 2.02.42 - 26th October 2008
===================================
Accept locking fallback_to_* options in the global section as documented.
Fix temp table activation in mirror conversions not to happen in other cmds.
Fix temp table in mirror conversions to use always-present error not zero.
Version 2.02.41 - 17th October 2008
===================================
Use temp table to set device size when converting mirrors.
In resume_mirror_images replace activate_lv with resume_lv as workaround.
Avoid overwriting in-use on-disk text metadata by forgetting MDA_HEADER_SIZE.
Fix snapshot monitoring library to not cancel monitoring invalid snapshot.
Generate man pages from templates and include version.
Add usrlibdir and usrsbindir to configure.
Fix conversion of md chunk size into sectors.
Free text metadata buffer after a failure writing it.
Fix misleading error message when there are no allocatable extents in VG.
Fix handling of PVs which reappeared with old metadata version.
Fix mirror DSO to call vgreduce with proper parameters.
Fix validation of --minor and --major in lvcreate to require -My always.
Fix release: clvmd build, vgreduce consolidate & tests, /dev/ioerror warning.
Version 2.02.40 - 19th September 2008
=====================================
Allow lvremove to remove LVs from VGs with missing PVs.
In VG with PVs missing, by default allow activation of LVs that are complete.
Track PARTIAL_LV and MISSING_PV flags internally.
Require --force with --removemissing in vgreduce to remove partial LVs.
No longer write out PARTIAL flag into metadata backups.
Treat new default activation/missing_stripe_filler "error" as an error target.
Remove internal partial_mode.
Add devices/md_chunk_alignment to lvm.conf.
Pass struct physical_volume to pe_align and adjust for md chunk size.
Store sysfs location in struct cmd_context.
Avoid shuffling remaining mirror images when removing one, retaining primary.
Add missing LV error target activation in _remove_mirror_images.
Prevent resizing an LV while lvconvert is using it.
Avoid repeatedly wiping cache while VG_GLOBAL is held in vgscan & pvscan.
Fix pvresize to not allow resize if PV has two metadata areas.
Fix setting of volume limit count if converting to lvm1 format.
Fix vgconvert logical volume id metadata validation.
Fix lvmdump metadata gather option (-m) to work correctly.
Fix allocation bug in text metadata format write error path.
Fix vgcfgbackup to properly check filename if template is used.
configure aborts if lcov or genhtml are missing with --enable-profiling
vgremove tries to remove lv snapshot first.
Added function lv_remove_with_dependencies().
Improve file descriptor leak detection to display likely culprit and filename.
Change clustered mirror kernel module name from cmirror to dm-log-clustered.
Avoid looping forever in _pv_analyze_mda_raw used by pvck.
Change lvchange exit status to indicate if any part of the operation failed.
Fix pvchange and pvremove to handle PVs without mdas.
Refactor _text_pv_read and always return mda list if requested.
Fix configure to work w/o readline unless --enable-readline used. (2.02.39)
Remove is_lvm_partition template which has not yet been coded.
Refactor pvcreate to separate parameter parsing from validation logic.
Check for label_write() failure in _text_pv_write().
Add pvcreate tests and update vgsplit tests to handle lvm1 and lvm2 metadata.
Fix pvchange -M1 -u to preserve existing extent locations when there's a VG.
Cease recognising snapshot-in-use percentages returned by early devt kernels.
Add backward-compatible flags field to on-disk format_text metadata.
Fix dmeventd monitoring libraries to link against liblvm2cmd again. (2.02.39)
Version 2.02.39 - 27th June 2008
================================
Enable readline by default if available.
Update autoconf to 2008-01-16.
Add $DISTCLEAN_DIRS to make.tmpl.in.
Create coverage reports with --enable-profiling and make lcov or lcov-dated.
Fix up cache for PVs without mdas after consistent VG metadata is processed.
Update validation of safe mirror log type conversions in lvconvert.
Fix lvconvert to disallow snapshot and mirror combinations.
Fix reporting of LV fields alongside unallocated PV segments.
Add --unquoted and --rows to reporting tools.
Add and use uninitialized_var() macro to suppress invalid compiler warnings.
Introduce enum for md minor sb version to suppress compiler warning.
@@ -9,12 +935,12 @@ Version 2.02.39 -
Fix and improve readahead 'auto' calculation for stripe_size.
Fix lvchange output for -r auto setting if auto is already set.
Add test case for readahead.
Fix ambiguous use of identifier error_message_produced.
Avoid ambiguous use of identifier error_message_produced.
Begin syncing configure.in for merge/unification with device-mapper.
Fix add_mirror_images not to dereference uninitialized log_lv upon failure.
Don't call openlog for every debug line output by clvmd.
Add --force to lvextend and lvresize.
Fix vgchange to not activate mirror leg and log volumes directly.
Fix vgchange not to activate component mirror volumes directly.
Fix test directory clean up in make distclean.
Version 2.02.38 - 11th June 2008

View File

@@ -1,3 +1,212 @@
Version 1.02.54 - 18th August 2010
==================================
Fix dm-mod autoloading logic to not assume control node is set correctly.
Add dmeventd/executable to lvm.conf to test alternative dmeventd.
Export dm_event_handler_set_dmeventd_path to override built-in dmeventd path.
Generate libdevmapper-event exported symbols.
Remove superfluous NULL pointer tests before dm_free from dmeventd.
Assume dm-mod autoloading support is in kernel 2.6.36 and higher, not 2.6.35.
Fix udev rules to support udev database content generated by older rules.
Reinstate detection of inappropriate uevent with DISK_RO set and suppress it.
Fix regex ttree off-by-one error.
Add --enable-valgrind-pool to configure.
Fix segfault in regex matcher with characters of ordinal value > 127.
Fix 'void*' arithmetic warnings in dbg_malloc.c and libdm-iface.c.
Wait for node creation before displaying debug info in dmsetup.
Fix return status 0 for "dmsetup info -c -o help".
Add check for kernel semaphore support and disable udev_sync if not available.
Version 1.02.53 - 28th July 2010
================================
Revert failed table load preparation after "create, load and resume".
Switch dmeventd to use dm_create_lockfile and drop duplicate code.
Add dm_create_lockfile to libdm to handle pidfiles for all daemons.
Replace lookup with next in struct dfa_state & calculate states on demand.
Improve the regex matcher, reducing the number of charset nodes used.
Add dm_regex_fingerprint to facilitate regex testing.
Skip ffs(0) in _test_word in bitset functions.
Use "nowatch" udev rule for inappropriate devices.
Version 1.02.52 - 6th July 2010
===============================
Fix dmlosetup snprintf %llu compiler warning.
Add parentheses to some libdevmapper.h macro arguments.
Add printf format attributes to dm_{sn,as}printf and fix a caller.
Move dmeventd man page from install_lvm2 to install_device-mapper. (1.02.50)
Version 1.02.51 - 30th June 2010
================================
Generate libdevmapper exported symbols from header file.
Version 1.02.50 - 23rd June 2010
================================
Fix INTERNAL_ERROR typo in ioctl iface unknown task message.
Fix udev rules to handle spurious events properly.
Use C99 [] not [0] in dm_ulog_request struct to avoid abort when fortified.
Allow use of devmapper header file in C++ mode (extern "C" and __typeof__).
Add dmeventd man page.
Version 1.02.49 - 4th June 2010
===============================
Support autoloading of dm-mod module for kernels from 2.6.35.
Document 'clear' in dmsetup man page.
Fix semctl parameter (union) to avoid misaligned parameter on some arches.
Add dm_tree_node_set_presuspend_node() to presuspend child when deactivating.
Initial support for replicator target.
Version 1.02.48 - 17th May 2010
================================
Use -d to control level of messages sent to syslog by dmeventd.
Change -d to -f to run dmeventd in foreground.
Do not print encryption key in message debug output (cryptsetup luksResume).
Fix dmeventd static build library dependencies.
Fix udev flags on remove in create_and_load error path.
Version 1.02.47 - 30th April 2010
=================================
Add support for new IMPORT{db} udev rule.
Add DM_UDEV_PRIMARY_SOURCE_FLAG udev flag to recognize proper DM events.
Also include udev libs in libdevmapper.pc when udev_sync is enabled.
Cache bitset locations to speed up _calc_states.
Add a regex optimisation pass for shared prefixes and suffixes.
Add dm_bit_and and dm_bitset_equal to libdevmapper.
Simplify dm_bitset_create.
Speed up dm_bit_get_next with ffs().
Version 1.02.46 - 14th April 2010
=================================
Change dm_tree_deactivate_children to fail if device is open.
Wipe memory buffers for dm-ioctl parameters before releasing.
Strictly require libudev if udev_sync is used.
Add support for ioctl's DM_UEVENT_GENERATED_FLAG.
Version 1.02.45 - 9th March 2010
================================
Add --showkeys parameter description to dmsetup man page.
Add --help option as synonym for help command.
Version 1.02.44 - 15th February 2010
====================================
Add DM_UDEV_DISABLE_LIBRARY_FALLBACK udev flag to rely on udev only.
Export dm_udev_create_cookie function to create new cookies on demand.
Add --udevcookie, udevcreatecookie and udevreleasecookie to dmsetup.
Set udev state automatically instead of using DM_UDEV_DISABLE_CHECKING.
Version 1.02.43 - 21st January 2010
===================================
Remove bitset, hash and pool headers superceded by libdevmapper.h.
Fix off-by-one error causing bad cluster mirror table construction.
Version 1.02.42 - 14th January 2010
===================================
Add support for the "snapshot-merge" kernel target (2.6.33-rc1).
Introduce a third activation_priority level in dm_tree_activate_children.
Version 1.02.41 - 12th January 2010
===================================
If DM_UDEV_DISABLE_CHECKING is set in environment, disable udev warnings.
Add dm_tree_add_dev_with_udev_flags to provide wider support for udev flags.
Add --noudevrules option for dmsetup to disable /dev node management by udev.
Fix 'dmsetup info -c -o all' to show all fields.
Return errors if dm_tree_*_children functions fail.
Fix coredump and memory leak for 'dmsetup help -c'.
Disable udev rules for change events with DISK_RO set.
Version 1.02.40 - 19th November 2009
====================================
Fix install_device-mapper Makefile target to not build dmeventd plugins.
Support udev flags even when udev_sync is disabled or not compiled in.
Remove 'last_rule' from udev rules: honour DM_UDEV_DISABLE_OTHER_RULES_FLAG.
Add dmsetup --inactive support.
Add dm_task_query_inactive_table to libdevmapper for kernel driver >= 4.16.
Fix hash lookup segfault when keys compared are different lengths.
Version 1.02.39 - 26th October 2009
===================================
Remove strict default permissions for DM devices from 95-dm-notify.rules.
Add dmsetup udevflags command to decode udev flags in given cookie value.
Support udev flags in libdevmapper incl. dm_tree_add_new_dev_with_udev_flags.
Make libdm ABI consistent when built with/without selinux support.
Version 1.02.38 - 25th September 2009
=====================================
Export DM_DEV_DIR_UMASK, the default umask for /dev directories created.
Handle any path supplied to dm_task_set_name by looking up in /dev/mapper.
Add several examples to 12-dm-permissions.rules.
Add splitname and --yes to dmsetup man page.
Fix _mirror_emit_segment_line return code.
Fix dmeventd _temporary_log_fn parameters. (2.02.50)
Version 1.02.37 - 15th September 2009
=====================================
Add dmsetup manpage entries for udevcomplete_all and udevcookies.
Check udev is running when processing cookies and retain state internally.
Add y|--yes option to dmsetup for default 'yes' answer to prompts.
Fix tools Makefile to process dmsetup sources separately.
Restore umask when device node creation fails.
Check kernel vsn to use 'block_on_error' or 'handle_errors' in mirror table.
Add dm-log-userspace.h to tree for cmirrord builds.
Version 1.02.36 - 6th August 2009
=================================
Add udevcookies, udevcomplete, udevcomplete_all and --noudevwait to dmsetup.
Add libdevmapper functions to support synchronisation with udev.
Version 1.02.35 - 28th July 2009
================================
Add LOG_LINE_WITH_ERRNO macro.
Use log_error macro consistently throughout in place of log_err.
Version 1.02.34 - 15th July 2009
================================
Use _exit() not exit() after forking to avoid flushing libc buffers twice.
Rename plog macro to LOG_LINE & add LOG_MESG variant for dm_dump_memory_debug.
Change plog to use dm_log_with_errno unless deprecated dm_log_init was used.
Add dm_log_with_errno and dm_log_with_errno_init, deprecating the old fns.
Fix whitespace in linear target line to fix identical table line detection.
Add device number to more log messages during activation.
Version 1.02.33 - 30th June 2009
================================
Don't fallback to default major number: use dm_task_set_major_minor. (1.02.31)
Do not fork daemon when dmeventd cannot be found.
Add crypt target handling to libdevmapper tree nodes.
Add splitname command to dmsetup.
Add subsystem, vg_name, lv_name, lv_layer fields to dmsetup reports.
Make mempool optional in dm_split_lvm_name().
Version 1.02.32 - 21st May 2009
===============================
Only generate libdevmapper.a when configured to link statically.
Export dm_tree_node_size_changed() from libdevmapper.
Propagate the table size_changed property up the dm device tree.
Detect failure to free memory pools when releasing the library.
Fix segfault when getopt processes dmsetup -U, -G and -M options.
Version 1.02.31 - 3rd March 2009
================================
If kernel supports only one dm major number, use in place of any supplied.
Version 1.02.30 - 26th January 2009
====================================
Add "all" field to reports expanding to all fields of report type.
Enforce device name length and character limitations in libdm.
Replace _dm_snprintf with EMIT_PARAMS macro for creating target lines.
Version 1.02.29 - 10th November 2008
====================================
Merge device-mapper into the LVM2 tree.
Split out dm-logging.h from log.h.
Use lvm-types.h.
Add usrsbindir to configure.
Version 1.02.28 - 18th September 2008
=====================================
Only resume devices in dm_tree_preload_children if size changes.
Extend deptree buffers so the largest possible device numbers fit.
Generate versioned libdevmapper-event.so.
Underline longer report help text headings.
Version 1.02.27 - 25th June 2008
================================
Align struct memblock in dbg_malloc for sparc.

60
autoconf/config.guess vendored
View File

@@ -1,10 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
# Inc.
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
# Free Software Foundation, Inc.
timestamp='2006-07-02'
timestamp='2008-01-23'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -56,8 +56,8 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -161,6 +161,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
@@ -329,7 +330,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
i86pc:SunOS:5.*:*)
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
@@ -531,7 +532,7 @@ EOF
echo rs6000-ibm-aix3.2
fi
exit ;;
*:AIX:*:[45])
*:AIX:*:[456])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
@@ -780,7 +781,7 @@ EOF
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
i*:MINGW*:*)
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:windows32*:*)
@@ -790,12 +791,18 @@ EOF
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
x86:Interix*:[3456]*)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
EM64T:Interix*:[3456]*)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
*:Interix*:[3456]*)
case ${UNAME_MACHINE} in
x86)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
EM64T | authenticamd)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
IA64)
echo ia64-unknown-interix${UNAME_RELEASE}
exit ;;
esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
@@ -829,7 +836,14 @@ EOF
echo ${UNAME_MACHINE}-pc-minix
exit ;;
arm*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
echo ${UNAME_MACHINE}-unknown-linux-gnu
else
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
fi
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
@@ -950,6 +964,9 @@ EOF
x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu
exit ;;
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
@@ -1208,6 +1225,15 @@ EOF
SX-6:SUPER-UX:*:*)
echo sx6-nec-superux${UNAME_RELEASE}
exit ;;
SX-7:SUPER-UX:*:*)
echo sx7-nec-superux${UNAME_RELEASE}
exit ;;
SX-8:SUPER-UX:*:*)
echo sx8-nec-superux${UNAME_RELEASE}
exit ;;
SX-8R:SUPER-UX:*:*)
echo sx8r-nec-superux${UNAME_RELEASE}
exit ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit ;;
@@ -1458,9 +1484,9 @@ This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
and
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
If the version you run ($0) is already up to date, please
send the following data and any information you think might be

66
autoconf/config.sub vendored
View File

@@ -1,10 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
# Inc.
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
# Free Software Foundation, Inc.
timestamp='2006-09-20'
timestamp='2008-01-16'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -72,8 +72,8 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -245,12 +245,12 @@ case $basic_machine in
| bfin \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| fr30 | frv \
| fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | mcore \
| maxq | mb | microblaze | mcore | mep \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
@@ -324,7 +324,7 @@ case $basic_machine in
| clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
@@ -369,10 +369,14 @@ case $basic_machine in
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
| xstormy16-* | xtensa-* \
| xstormy16-* | xtensa*-* \
| ymp-* \
| z8k-*)
;;
# Recognize the basic CPU types without company name, with glob match.
xtensa*)
basic_machine=$basic_machine-unknown
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
386bsd)
@@ -443,6 +447,14 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
blackfin)
basic_machine=bfin-unknown
os=-linux
;;
blackfin-*)
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
c90)
basic_machine=c90-cray
os=-unicos
@@ -475,8 +487,8 @@ case $basic_machine in
basic_machine=craynv-cray
os=-unicosmp
;;
cr16c)
basic_machine=cr16c-unknown
cr16)
basic_machine=cr16-unknown
os=-elf
;;
crds | unos)
@@ -668,6 +680,14 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
;;
m68knommu-*)
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
m88k-omron*)
basic_machine=m88k-omron
;;
@@ -683,6 +703,10 @@ case $basic_machine in
basic_machine=i386-pc
os=-mingw32
;;
mingw32ce)
basic_machine=arm-unknown
os=-mingw32ce
;;
miniframe)
basic_machine=m68000-convergent
;;
@@ -809,6 +833,14 @@ case $basic_machine in
basic_machine=i860-intel
os=-osf
;;
parisc)
basic_machine=hppa-unknown
os=-linux
;;
parisc-*)
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
pbd)
basic_machine=sparc-tti
;;
@@ -925,6 +957,9 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
sh5el)
basic_machine=sh5le-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
@@ -1014,6 +1049,10 @@ case $basic_machine in
basic_machine=tic6x-unknown
os=-coff
;;
tile*)
basic_machine=tile-unknown
os=-linux-gnu
;;
tx39)
basic_machine=mipstx39-unknown
;;
@@ -1219,7 +1258,7 @@ case $os in
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers*)
| -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1414,6 +1453,9 @@ case $basic_machine in
m68*-cisco)
os=-aout
;;
mep-*)
os=-elf
;;
mips*-cisco)
os=-elf
;;

13694
configure vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
#
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
# Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
@@ -13,11 +13,31 @@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
top_builddir = @top_builddir@
.PHONY: dmeventd clvmd cmirrord
ifneq ("@CLVMD@", "none")
SUBDIRS = clvmd
endif
include $(top_srcdir)/make.tmpl
ifeq ("@BUILD_CMIRRORD@", "yes")
SUBDIRS += cmirrord
endif
ifeq ("@BUILD_DMEVENTD@", "yes")
SUBDIRS += dmeventd
ifneq ("$(CFLOW_CMD)", "")
daemons.cflow: dmeventd.cflow
endif
endif
ifeq ($(MAKECMDGOALS),distclean)
SUBDIRS = clvmd cmirrord dmeventd
endif
include $(top_builddir)/make.tmpl
ifeq ("@BUILD_DMEVENTD@", "yes")
device-mapper: dmeventd.device-mapper
endif

View File

@@ -13,7 +13,24 @@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
top_builddir = @top_builddir@
CCS_LIBS = @CCS_LIBS@
CCS_CFLAGS = @CCS_CFLAGS@
CMAN_LIBS = @CMAN_LIBS@
CMAN_CFLAGS = @CMAN_CFLAGS@
CONFDB_LIBS = @CONFDB_LIBS@
CONFDB_CFLAGS = @CONFDB_CFLAGS@
CPG_LIBS = @CPG_LIBS@
CPG_CFLAGS = @CPG_CFLAGS@
DLM_LIBS = @DLM_LIBS@
DLM_CFLAGS = @DLM_CFLAGS@
GULM_LIBS = @GULM_LIBS@
GULM_CFLAGS = @GULM_CFLAGS@
QUORUM_LIBS = @QUORUM_LIBS@
QUORUM_CFLAGS = @QUORUM_CFLAGS@
SALCK_LIBS = @SALCK_LIBS@
SALCK_CFLAGS = @SALCK_CFLAGS@
SOURCES = \
clvmd-command.c \
@@ -21,78 +38,80 @@ SOURCES = \
lvm-functions.c \
refresh_clvmd.c
ifeq ("@CLVMD@", "gulm")
GULM = yes
endif
ifeq ("@CLVMD@", "cman")
CMAN = yes
endif
ifeq ("@CLVMD@", "openais")
OPENAIS = yes
GULM = no
CMAN = no
endif
ifeq ("@CLVMD@", "all")
GULM = yes
CMAN = yes
OPENAIS = no
endif
ifeq ("@DEBUG@", "yes")
DEFS += -DDEBUG
endif
ifeq ("$(GULM)", "yes")
ifneq (,$(findstring gulm,, "@CLVMD@,"))
SOURCES += clvmd-gulm.c tcp-comms.c
LMLIBS += -lccs -lgulm
LMLIBS += $(CCS_LIBS) $(GULM_LIBS)
CFLAGS += $(CCS_CFLAGS) $(GULM_CFLAGS)
DEFS += -DUSE_GULM
endif
ifeq ("$(CMAN)", "yes")
ifneq (,$(findstring cman,, "@CLVMD@,"))
SOURCES += clvmd-cman.c
LMLIBS += -ldlm -lcman
LMLIBS += $(CMAN_LIBS) $(CONFDB_LIBS) $(DLM_LIBS)
CFLAGS += $(CMAN_CFLAGS) $(CONFDB_CFLAGS) $(DLM_CFLAGS)
DEFS += -DUSE_CMAN
endif
ifeq ("$(OPENAIS)", "yes")
ifneq (,$(findstring openais,, "@CLVMD@,"))
SOURCES += clvmd-openais.c
LMLIBS += -lSaLck -lcpg
LMLIBS += $(CONFDB_LIBS) $(CPG_LIBS) $(SALCK_LIBS)
CFLAGS += $(CONFDB_CFLAGS) $(CPG_CFLAGS) $(SALCK_CFLAGS)
DEFS += -DUSE_OPENAIS
endif
ifneq (,$(findstring corosync,, "@CLVMD@,"))
SOURCES += clvmd-corosync.c
LMLIBS += $(CONFDB_LIBS) $(CPG_LIBS) $(DLM_LIBS) $(QUORUM_LIBS)
CFLAGS += $(CONFDB_CFLAGS) $(CPG_CFLAGS) $(DLM_CFLAGS) $(QUORUM_CFLAGS)
DEFS += -DUSE_COROSYNC
endif
ifneq (,$(findstring singlenode,, &quot;@CLVMD@,&quot;))
SOURCES += clvmd-singlenode.c
DEFS += -DUSE_SINGLENODE
endif
ifeq ($(MAKECMDGOALS),distclean)
SOURCES += clvmd-gulm.c tcp-comms.c
SOURCES += clvmd-cman.c
SOURCES += clvmd-openais.c
SOURCES += clvmd-corosync.c
SOURCES += clvmd-singlenode.c
endif
TARGETS = \
clvmd
LVMLIBS = -llvm -lpthread
LVMLIBS = $(LVMINTERNAL_LIBS)
ifeq ("@DMEVENTD@", "yes")
LVMLIBS += -ldevmapper-event
endif
include $(top_builddir)/make.tmpl
LVMLIBS += -ldevmapper
LIBS += $(PTHREAD_LIBS)
DEFS += -D_REENTRANT
CFLAGS += -fno-strict-aliasing
include $(top_srcdir)/make.tmpl
INSTALL_TARGETS = \
install_clvmd
clvmd: $(OBJECTS) $(top_srcdir)/lib/liblvm.a
$(CC) -o clvmd $(OBJECTS) $(CFLAGS) $(LDFLAGS) \
clvmd: $(OBJECTS) $(top_builddir)/lib/liblvm-internal.a
$(CC) $(CFLAGS) $(LDFLAGS) -o clvmd $(OBJECTS) \
$(LVMLIBS) $(LMLIBS) $(LIBS)
.PHONY: install_clvmd
install_clvmd: $(TARGETS)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) clvmd \
$(sbindir)/clvmd
$(INSTALL_PROGRAM) -D clvmd $(usrsbindir)/clvmd
install: $(INSTALL_TARGETS)
install_cluster: $(INSTALL_TARGETS)

View File

@@ -22,6 +22,8 @@
#ifndef _CLVM_H
#define _CLVM_H
#include "configure.h"
struct clvm_header {
uint8_t cmd; /* See below */
uint8_t flags; /* See below */
@@ -45,9 +47,8 @@ struct clvm_header {
#define CLVMD_FLAG_SYSTEMLV 2 /* Data in system LV under my node name */
#define CLVMD_FLAG_NODEERRS 4 /* Reply has errors in node-specific portion */
/* Name of the local socket to communicate between libclvm and clvmd */
//static const char CLVMD_SOCKNAME[]="/var/run/clvmd";
static const char CLVMD_SOCKNAME[] = "\0clvmd";
/* Name of the local socket to communicate between lvm and clvmd */
static const char CLVMD_SOCKNAME[]= DEFAULT_RUN_DIR "/clvmd.sock";
/* Internal commands & replies */
#define CLVMD_CMD_REPLY 1
@@ -62,10 +63,12 @@ static const char CLVMD_SOCKNAME[] = "\0clvmd";
/* Lock/Unlock commands */
#define CLVMD_CMD_LOCK_LV 50
#define CLVMD_CMD_LOCK_VG 51
#define CLVMD_CMD_LOCK_QUERY 52
/* Misc functions */
#define CLVMD_CMD_REFRESH 40
#define CLVMD_CMD_GET_CLUSTERNAME 41
#define CLVMD_CMD_SET_DEBUG 42
#define CLVMD_CMD_VG_BACKUP 43
#define CLVMD_CMD_RESTART 44
#endif

View File

@@ -17,34 +17,19 @@
* CMAN communication layer for clvmd.
*/
#include "clvmd-common.h"
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/utsname.h>
#include <syslog.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <getopt.h>
#include <errno.h>
#include <libdevmapper.h>
#include <libdlm.h>
#include "clvmd-comms.h"
#include "clvm.h"
#include "log.h"
#include "clvmd.h"
#include "lvm-functions.h"
#include <libdlm.h>
#include <syslog.h>
#define LOCKSPACE_NAME "clvmd"
struct clvmd_node
@@ -106,8 +91,13 @@ static int _init_cluster(void)
/* Create a lockspace for LV & VG locks to live in */
lockspace = dlm_create_lockspace(LOCKSPACE_NAME, 0600);
if (!lockspace) {
syslog(LOG_ERR, "Unable to create lockspace for CLVM: %m");
return -1;
if (errno == EEXIST) {
lockspace = dlm_open_lockspace(LOCKSPACE_NAME);
}
if (!lockspace) {
syslog(LOG_ERR, "Unable to create lockspace for CLVM: %m");
return -1;
}
}
dlm_ls_pthread_init(lockspace);
DEBUGLOG("DLM initialisation complete\n");
@@ -254,7 +244,7 @@ static void _add_up_node(const char *csid)
static void _cluster_closedown()
{
unlock_all();
destroy_lvhash();
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
cman_finish(c_handle);
}

View File

@@ -50,33 +50,22 @@
*/
#include <pthread.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <string.h>
#include <stddef.h>
#include <unistd.h>
#include <errno.h>
#include <libdevmapper.h>
#include <libdlm.h>
#include "clvmd-common.h"
#include <pthread.h>
#include "list.h"
#include "locking.h"
#include "log.h"
#include "lvm-functions.h"
#include "clvmd-comms.h"
#include "clvm.h"
#include "clvmd.h"
#include "lvm-functions.h"
#include "locking.h"
#include <sys/utsname.h>
extern debug_t debug;
extern struct cluster_ops *clops;
static int restart_clvmd(void);
/* This is where all the real work happens:
NOTE: client will be NULL when this is executed on a remote node */
@@ -87,6 +76,7 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
int arglen = msglen - sizeof(struct clvm_header) - strlen(msg->node);
int status = 0;
char *lockname;
const char *locktype;
struct utsname nodeinfo;
unsigned char lock_cmd;
unsigned char lock_flags;
@@ -115,20 +105,17 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
break;
case CLVMD_CMD_LOCK_VG:
lock_cmd = args[0];
lock_flags = args[1];
lockname = &args[2];
/* Check to see if the VG is in use by LVM1 */
status = do_check_lvm1(lockname);
/* P_#global causes a full cache refresh */
if (!strcmp(lockname, "P_" VG_GLOBAL))
do_refresh_cache();
else
drop_metadata(lockname + 2);
do_lock_vg(lock_cmd, lock_flags, lockname);
break;
case CLVMD_CMD_LOCK_LV:
/* This is the biggie */
lock_cmd = args[0] & 0x3F;
lock_cmd = args[0] & (LCK_NONBLOCK | LCK_HOLD | LCK_SCOPE_MASK | LCK_TYPE_MASK);
lock_flags = args[1];
lockname = &args[2];
status = do_lock_lv(lock_cmd, lock_flags, lockname);
@@ -141,6 +128,14 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
}
break;
case CLVMD_CMD_LOCK_QUERY:
lockname = &args[2];
if (buflen < 3)
return EIO;
if ((locktype = do_lock_query(lockname)))
*retlen = 1 + snprintf(*buf, buflen, "%s", locktype);
break;
case CLVMD_CMD_REFRESH:
do_refresh_cache();
break;
@@ -149,6 +144,10 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
debug = args[0];
break;
case CLVMD_CMD_RESTART:
restart_clvmd();
break;
case CLVMD_CMD_GET_CLUSTERNAME:
status = clops->get_cluster_name(*buf, buflen);
if (!status)
@@ -156,7 +155,11 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
break;
case CLVMD_CMD_VG_BACKUP:
lvm_do_backup(&args[2]);
/*
* Do not run backup on local node, caller should do that.
*/
if (!client)
lvm_do_backup(&args[2]);
break;
default:
@@ -180,6 +183,7 @@ static int lock_vg(struct local_client *client)
(struct clvm_header *) client->bits.localsock.cmd;
unsigned char lock_cmd;
unsigned char lock_flags;
int lock_mode;
char *args = header->node + strlen(header->node) + 1;
int lkid;
int status = 0;
@@ -198,12 +202,13 @@ static int lock_vg(struct local_client *client)
client->bits.localsock.private = (void *)lock_hash;
}
lock_cmd = args[0] & 0x3F;
lock_cmd = args[0] & (LCK_NONBLOCK | LCK_HOLD | LCK_SCOPE_MASK | LCK_TYPE_MASK);
lock_mode = ((int)lock_cmd & LCK_TYPE_MASK);
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) {
if (lock_mode == LCK_UNLOCK) {
lkid = (int)(long)dm_hash_lookup(lock_hash, lockname);
if (lkid == 0)
@@ -217,11 +222,9 @@ static int lock_vg(struct local_client *client)
}
else {
/* Read locks need to be PR; other modes get passed through */
if ((lock_cmd & LCK_TYPE_MASK) == LCK_READ) {
lock_cmd &= ~LCK_TYPE_MASK;
lock_cmd |= LCK_PREAD;
}
status = sync_lock(lockname, (int)lock_cmd, (lock_flags & LCK_NONBLOCK) ? LKF_NOQUEUE : 0, &lkid);
if (lock_mode == LCK_READ)
lock_mode = LCK_PREAD;
status = sync_lock(lockname, lock_mode, (lock_cmd & LCK_NONBLOCK) ? LCKF_NOQUEUE : 0, &lkid);
if (status)
status = errno;
else
@@ -248,7 +251,7 @@ int do_pre_command(struct local_client *client)
switch (header->cmd) {
case CLVMD_CMD_TEST:
status = sync_lock("CLVMD_TEST", LKM_EXMODE, 0, &lockid);
status = sync_lock("CLVMD_TEST", LCK_EXCL, 0, &lockid);
client->bits.localsock.private = (void *)(long)lockid;
break;
@@ -271,6 +274,8 @@ int do_pre_command(struct local_client *client)
case CLVMD_CMD_GET_CLUSTERNAME:
case CLVMD_CMD_SET_DEBUG:
case CLVMD_CMD_VG_BACKUP:
case CLVMD_CMD_LOCK_QUERY:
case CLVMD_CMD_RESTART:
break;
default:
@@ -301,6 +306,7 @@ int do_post_command(struct local_client *client)
case CLVMD_CMD_LOCK_VG:
case CLVMD_CMD_VG_BACKUP:
case CLVMD_CMD_LOCK_QUERY:
/* Nothing to do here */
break;
@@ -336,3 +342,72 @@ void cmd_client_cleanup(struct local_client *client)
client->bits.localsock.private = 0;
}
}
static int restart_clvmd(void)
{
char **argv = NULL;
char *debug_arg = NULL, *lv_name;
int i, argc = 0, max_locks = 0;
struct dm_hash_node *hn = NULL;
DEBUGLOG("clvmd restart requested\n");
/* Count exclusively-open LVs */
hn = NULL;
do {
hn = get_next_excl_lock(hn, &lv_name);
if (lv_name)
max_locks++;
} while (hn && *lv_name);
/* clvmd + locks (-E uuid) + debug (-d X) + NULL */
argv = malloc((max_locks * 2 + 4) * sizeof(*argv));
if (!argv)
goto_out;
/*
* Build the command-line
*/
argv[argc++] = strdup("clvmd");
if (!argv[0])
goto_out;
/* Propogate debug options */
if (debug) {
if (!(debug_arg = malloc(16)) ||
snprintf(debug_arg, 16, "-d%d", (int)debug) < 0)
goto_out;
argv[argc++] = debug_arg;
}
/* Now add the exclusively-open LVs */
do {
hn = get_next_excl_lock(hn, &lv_name);
if (lv_name) {
argv[argc] = strdup("-E");
if (!argv[argc++])
goto_out;
argv[argc] = strdup(lv_name);
if (!argv[argc++])
goto_out;
DEBUGLOG("excl lock: %s\n", lv_name);
hn = get_next_excl_lock(hn, &lv_name);
}
} while (hn && *lv_name);
argv[argc++] = NULL;
/* Exec new clvmd */
/* NOTE: This will fail when downgrading! */
execve(CLVMD_PATH, argv, NULL);
out:
/* We failed */
DEBUGLOG("Restart of clvmd failed.\n");
for (i = 0; i < argc && argv[i]; i++)
free(argv[i]);
free(argv);
return 0;
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2010 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* This file must be included first by every clvmd source file.
*/
#ifndef _LVM_CLVMD_COMMON_H
#define _LVM_CLVMD_COMMON_H
#include "configure.h"
#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include "libdevmapper.h"
#include "lvm-logging.h"
#include <unistd.h>
#include <sys/stat.h>
#endif

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -77,7 +77,7 @@ struct cluster_ops *init_cman_cluster(void);
#ifdef USE_OPENAIS
# include <openais/saAis.h>
# include <openais/totem/totem.h>
# include <corosync/totem/totem.h>
# define OPENAIS_CSID_LEN (sizeof(int))
# define OPENAIS_MAX_CLUSTER_MESSAGE MESSAGE_SIZE_MAX
# define OPENAIS_MAX_CLUSTER_MEMBER_NAME_LEN SA_MAX_NAME_LENGTH
@@ -93,5 +93,33 @@ struct cluster_ops *init_cman_cluster(void);
struct cluster_ops *init_openais_cluster(void);
#endif
#ifdef USE_COROSYNC
# include <corosync/corotypes.h>
# define COROSYNC_CSID_LEN (sizeof(int))
# define COROSYNC_MAX_CLUSTER_MESSAGE 65535
# define COROSYNC_MAX_CLUSTER_MEMBER_NAME_LEN CS_MAX_NAME_LENGTH
# ifndef MAX_CLUSTER_MEMBER_NAME_LEN
# define MAX_CLUSTER_MEMBER_NAME_LEN CS_MAX_NAME_LENGTH
# endif
# ifndef CMAN_MAX_CLUSTER_MESSAGE
# define CMAN_MAX_CLUSTER_MESSAGE 65535
# endif
# ifndef MAX_CSID_LEN
# define MAX_CSID_LEN sizeof(int)
# endif
struct cluster_ops *init_corosync_cluster(void);
#endif
#ifdef USE_SINGLENODE
# define SINGLENODE_CSID_LEN (sizeof(int))
# ifndef MAX_CLUSTER_MEMBER_NAME_LEN
# define MAX_CLUSTER_MEMBER_NAME_LEN 64
# endif
# define SINGLENODE_MAX_CLUSTER_MESSAGE 65535
# ifndef MAX_CSID_LEN
# define MAX_CSID_LEN sizeof(int)
# endif
struct cluster_ops *init_singlenode_cluster(void);
#endif
#endif

View File

@@ -0,0 +1,626 @@
/*
* Copyright (C) 2009 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* This provides the interface between clvmd and corosync/DLM as the cluster
* and lock manager.
*/
#include "clvmd-common.h"
#include <pthread.h>
#include "clvm.h"
#include "clvmd-comms.h"
#include "clvmd.h"
#include "lvm-functions.h"
#include "locking.h"
#include <corosync/cpg.h>
#include <corosync/quorum.h>
#include <corosync/confdb.h>
#include <libdlm.h>
#include <syslog.h>
/* Timeout value for several corosync calls */
#define LOCKSPACE_NAME "clvmd"
static void corosync_cpg_deliver_callback (cpg_handle_t handle,
const struct cpg_name *groupName,
uint32_t nodeid,
uint32_t pid,
void *msg,
size_t msg_len);
static void corosync_cpg_confchg_callback(cpg_handle_t handle,
const struct cpg_name *groupName,
const struct cpg_address *member_list, size_t member_list_entries,
const struct cpg_address *left_list, size_t left_list_entries,
const struct cpg_address *joined_list, size_t joined_list_entries);
static void _cluster_closedown(void);
/* Hash list of nodes in the cluster */
static struct dm_hash_table *node_hash;
/* Number of active nodes */
static int num_nodes;
static unsigned int our_nodeid;
static struct local_client *cluster_client;
/* Corosync handles */
static cpg_handle_t cpg_handle;
static quorum_handle_t quorum_handle;
/* DLM Handle */
static dlm_lshandle_t *lockspace;
static struct cpg_name cpg_group_name;
/* Corosync callback structs */
cpg_callbacks_t corosync_cpg_callbacks = {
.cpg_deliver_fn = corosync_cpg_deliver_callback,
.cpg_confchg_fn = corosync_cpg_confchg_callback,
};
quorum_callbacks_t quorum_callbacks = {
.quorum_notify_fn = NULL,
};
struct node_info
{
enum {NODE_UNKNOWN, NODE_DOWN, NODE_UP, NODE_CLVMD} state;
int nodeid;
};
/* Set errno to something approximating the right value and return 0 or -1 */
static int cs_to_errno(cs_error_t err)
{
switch(err)
{
case CS_OK:
return 0;
case CS_ERR_LIBRARY:
errno = EINVAL;
break;
case CS_ERR_VERSION:
errno = EINVAL;
break;
case CS_ERR_INIT:
errno = EINVAL;
break;
case CS_ERR_TIMEOUT:
errno = ETIME;
break;
case CS_ERR_TRY_AGAIN:
errno = EAGAIN;
break;
case CS_ERR_INVALID_PARAM:
errno = EINVAL;
break;
case CS_ERR_NO_MEMORY:
errno = ENOMEM;
break;
case CS_ERR_BAD_HANDLE:
errno = EINVAL;
break;
case CS_ERR_BUSY:
errno = EBUSY;
break;
case CS_ERR_ACCESS:
errno = EPERM;
break;
case CS_ERR_NOT_EXIST:
errno = ENOENT;
break;
case CS_ERR_NAME_TOO_LONG:
errno = ENAMETOOLONG;
break;
case CS_ERR_EXIST:
errno = EEXIST;
break;
case CS_ERR_NO_SPACE:
errno = ENOSPC;
break;
case CS_ERR_INTERRUPT:
errno = EINTR;
break;
case CS_ERR_NAME_NOT_FOUND:
errno = ENOENT;
break;
case CS_ERR_NO_RESOURCES:
errno = ENOMEM;
break;
case CS_ERR_NOT_SUPPORTED:
errno = EOPNOTSUPP;
break;
case CS_ERR_BAD_OPERATION:
errno = EINVAL;
break;
case CS_ERR_FAILED_OPERATION:
errno = EIO;
break;
case CS_ERR_MESSAGE_ERROR:
errno = EIO;
break;
case CS_ERR_QUEUE_FULL:
errno = EXFULL;
break;
case CS_ERR_QUEUE_NOT_AVAILABLE:
errno = EINVAL;
break;
case CS_ERR_BAD_FLAGS:
errno = EINVAL;
break;
case CS_ERR_TOO_BIG:
errno = E2BIG;
break;
case CS_ERR_NO_SECTIONS:
errno = ENOMEM;
break;
default:
errno = EINVAL;
break;
}
return -1;
}
static char *print_corosync_csid(const char *csid)
{
static char buf[128];
int id;
memcpy(&id, csid, sizeof(int));
sprintf(buf, "%d", id);
return buf;
}
static void corosync_cpg_deliver_callback (cpg_handle_t handle,
const struct cpg_name *groupName,
uint32_t nodeid,
uint32_t pid,
void *msg,
size_t msg_len)
{
int target_nodeid;
memcpy(&target_nodeid, msg, COROSYNC_CSID_LEN);
DEBUGLOG("%u got message from nodeid %d for %d. len %zd\n",
our_nodeid, nodeid, target_nodeid, msg_len-4);
if (nodeid != our_nodeid)
if (target_nodeid == our_nodeid || target_nodeid == 0)
process_message(cluster_client, (char *)msg+COROSYNC_CSID_LEN,
msg_len-COROSYNC_CSID_LEN, (char*)&nodeid);
}
static void corosync_cpg_confchg_callback(cpg_handle_t handle,
const struct cpg_name *groupName,
const struct cpg_address *member_list, size_t member_list_entries,
const struct cpg_address *left_list, size_t left_list_entries,
const struct cpg_address *joined_list, size_t joined_list_entries)
{
int i;
struct node_info *ninfo;
DEBUGLOG("confchg callback. %zd joined, %zd left, %zd members\n",
joined_list_entries, left_list_entries, member_list_entries);
for (i=0; i<joined_list_entries; i++) {
ninfo = dm_hash_lookup_binary(node_hash,
(char *)&joined_list[i].nodeid,
COROSYNC_CSID_LEN);
if (!ninfo) {
ninfo = malloc(sizeof(struct node_info));
if (!ninfo) {
break;
}
else {
ninfo->nodeid = joined_list[i].nodeid;
dm_hash_insert_binary(node_hash,
(char *)&ninfo->nodeid,
COROSYNC_CSID_LEN, ninfo);
}
}
ninfo->state = NODE_CLVMD;
}
for (i=0; i<left_list_entries; i++) {
ninfo = dm_hash_lookup_binary(node_hash,
(char *)&left_list[i].nodeid,
COROSYNC_CSID_LEN);
if (ninfo)
ninfo->state = NODE_DOWN;
}
for (i=0; i<member_list_entries; i++) {
if (member_list[i].nodeid == 0) continue;
ninfo = dm_hash_lookup_binary(node_hash,
(char *)&member_list[i].nodeid,
COROSYNC_CSID_LEN);
if (!ninfo) {
ninfo = malloc(sizeof(struct node_info));
if (!ninfo) {
break;
}
else {
ninfo->nodeid = member_list[i].nodeid;
dm_hash_insert_binary(node_hash,
(char *)&ninfo->nodeid,
COROSYNC_CSID_LEN, ninfo);
}
}
ninfo->state = NODE_CLVMD;
}
num_nodes = member_list_entries;
}
static int _init_cluster(void)
{
cs_error_t err;
node_hash = dm_hash_create(100);
err = cpg_initialize(&cpg_handle,
&corosync_cpg_callbacks);
if (err != CS_OK) {
syslog(LOG_ERR, "Cannot initialise Corosync CPG service: %d",
err);
DEBUGLOG("Cannot initialise Corosync CPG service: %d", err);
return cs_to_errno(err);
}
err = quorum_initialize(&quorum_handle,
&quorum_callbacks);
if (err != CS_OK) {
syslog(LOG_ERR, "Cannot initialise Corosync quorum service: %d",
err);
DEBUGLOG("Cannot initialise Corosync quorum service: %d", err);
return cs_to_errno(err);
}
/* Create a lockspace for LV & VG locks to live in */
lockspace = dlm_create_lockspace(LOCKSPACE_NAME, 0600);
if (!lockspace) {
if (errno == EEXIST) {
lockspace = dlm_open_lockspace(LOCKSPACE_NAME);
}
if (!lockspace) {
syslog(LOG_ERR, "Unable to create lockspace for CLVM: %m");
quorum_finalize(quorum_handle);
return -1;
}
}
dlm_ls_pthread_init(lockspace);
DEBUGLOG("DLM initialisation complete\n");
/* Connect to the clvmd group */
strcpy((char *)cpg_group_name.value, "clvmd");
cpg_group_name.length = strlen((char *)cpg_group_name.value);
err = cpg_join(cpg_handle, &cpg_group_name);
if (err != CS_OK) {
cpg_finalize(cpg_handle);
quorum_finalize(quorum_handle);
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
syslog(LOG_ERR, "Cannot join clvmd process group");
DEBUGLOG("Cannot join clvmd process group: %d\n", err);
return cs_to_errno(err);
}
err = cpg_local_get(cpg_handle,
&our_nodeid);
if (err != CS_OK) {
cpg_finalize(cpg_handle);
quorum_finalize(quorum_handle);
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
syslog(LOG_ERR, "Cannot get local node id\n");
return cs_to_errno(err);
}
DEBUGLOG("Our local node id is %d\n", our_nodeid);
DEBUGLOG("Connected to Corosync\n");
return 0;
}
static void _cluster_closedown(void)
{
DEBUGLOG("cluster_closedown\n");
destroy_lvhash();
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
cpg_finalize(cpg_handle);
quorum_finalize(quorum_handle);
}
static void _get_our_csid(char *csid)
{
memcpy(csid, &our_nodeid, sizeof(int));
}
/* Corosync doesn't really have nmode names so we
just use the node ID in hex instead */
static int _csid_from_name(char *csid, const char *name)
{
int nodeid;
struct node_info *ninfo;
if (sscanf(name, "%x", &nodeid) == 1) {
ninfo = dm_hash_lookup_binary(node_hash, csid, COROSYNC_CSID_LEN);
if (ninfo)
return nodeid;
}
return -1;
}
static int _name_from_csid(const char *csid, char *name)
{
struct node_info *ninfo;
ninfo = dm_hash_lookup_binary(node_hash, csid, COROSYNC_CSID_LEN);
if (!ninfo)
{
sprintf(name, "UNKNOWN %s", print_corosync_csid(csid));
return -1;
}
sprintf(name, "%x", ninfo->nodeid);
return 0;
}
static int _get_num_nodes()
{
DEBUGLOG("num_nodes = %d\n", num_nodes);
return num_nodes;
}
/* Node is now known to be running a clvmd */
static void _add_up_node(const char *csid)
{
struct node_info *ninfo;
ninfo = dm_hash_lookup_binary(node_hash, csid, COROSYNC_CSID_LEN);
if (!ninfo) {
DEBUGLOG("corosync_add_up_node no node_hash entry for csid %s\n",
print_corosync_csid(csid));
return;
}
DEBUGLOG("corosync_add_up_node %d\n", ninfo->nodeid);
ninfo->state = NODE_CLVMD;
return;
}
/* Call a callback for each node, so the caller knows whether it's up or down */
static int _cluster_do_node_callback(struct local_client *master_client,
void (*callback)(struct local_client *,
const char *csid, int node_up))
{
struct dm_hash_node *hn;
struct node_info *ninfo;
int somedown = 0;
dm_hash_iterate(hn, node_hash)
{
char csid[COROSYNC_CSID_LEN];
ninfo = dm_hash_get_data(node_hash, hn);
memcpy(csid, dm_hash_get_key(node_hash, hn), COROSYNC_CSID_LEN);
DEBUGLOG("down_callback. node %d, state = %d\n", ninfo->nodeid,
ninfo->state);
if (ninfo->state != NODE_DOWN)
callback(master_client, csid, ninfo->state == NODE_CLVMD);
if (ninfo->state != NODE_CLVMD)
somedown = -1;
}
return somedown;
}
/* Real locking */
static int _lock_resource(const char *resource, int mode, int flags, int *lockid)
{
struct dlm_lksb lksb;
int err;
DEBUGLOG("lock_resource '%s', flags=%d, mode=%d\n", resource, flags, mode);
if (flags & LKF_CONVERT)
lksb.sb_lkid = *lockid;
err = dlm_ls_lock_wait(lockspace,
mode,
&lksb,
flags,
resource,
strlen(resource),
0,
NULL, NULL, NULL);
if (err != 0)
{
DEBUGLOG("dlm_ls_lock returned %d\n", errno);
return err;
}
if (lksb.sb_status != 0)
{
DEBUGLOG("dlm_ls_lock returns lksb.sb_status %d\n", lksb.sb_status);
errno = lksb.sb_status;
return -1;
}
DEBUGLOG("lock_resource returning %d, lock_id=%x\n", err, lksb.sb_lkid);
*lockid = lksb.sb_lkid;
return 0;
}
static int _unlock_resource(const char *resource, int lockid)
{
struct dlm_lksb lksb;
int err;
DEBUGLOG("unlock_resource: %s lockid: %x\n", resource, lockid);
lksb.sb_lkid = lockid;
err = dlm_ls_unlock_wait(lockspace,
lockid,
0,
&lksb);
if (err != 0)
{
DEBUGLOG("Unlock returned %d\n", err);
return err;
}
if (lksb.sb_status != EUNLOCK)
{
DEBUGLOG("dlm_ls_unlock_wait returns lksb.sb_status: %d\n", lksb.sb_status);
errno = lksb.sb_status;
return -1;
}
return 0;
}
static int _is_quorate()
{
int quorate;
if (quorum_getquorate(quorum_handle, &quorate) == CS_OK)
return quorate;
else
return 0;
}
static int _get_main_cluster_fd(void)
{
int select_fd;
cpg_fd_get(cpg_handle, &select_fd);
return select_fd;
}
static int _cluster_fd_callback(struct local_client *fd, char *buf, int len,
const char *csid,
struct local_client **new_client)
{
cluster_client = fd;
*new_client = NULL;
cpg_dispatch(cpg_handle, CS_DISPATCH_ONE);
return 1;
}
static int _cluster_send_message(const void *buf, int msglen, const char *csid,
const char *errtext)
{
struct iovec iov[2];
cs_error_t err;
int target_node;
if (csid)
memcpy(&target_node, csid, COROSYNC_CSID_LEN);
else
target_node = 0;
iov[0].iov_base = &target_node;
iov[0].iov_len = sizeof(int);
iov[1].iov_base = (char *)buf;
iov[1].iov_len = msglen;
err = cpg_mcast_joined(cpg_handle, CPG_TYPE_AGREED, iov, 2);
return cs_to_errno(err);
}
/*
* We are not necessarily connected to a Red Hat Cluster system,
* but if we are, this returns the cluster name from cluster.conf.
* I've used confdb rather than ccs to reduce the inter-package
* dependancies as well as to allow people to set a cluster name
* for themselves even if they are not running on RH cluster.
*/
static int _get_cluster_name(char *buf, int buflen)
{
confdb_handle_t handle;
int result;
size_t namelen = buflen;
hdb_handle_t cluster_handle;
confdb_callbacks_t callbacks = {
.confdb_key_change_notify_fn = NULL,
.confdb_object_create_change_notify_fn = NULL,
.confdb_object_delete_change_notify_fn = NULL
};
/* This is a default in case everything else fails */
strncpy(buf, "Corosync", buflen);
/* Look for a cluster name in confdb */
result = confdb_initialize (&handle, &callbacks);
if (result != CS_OK)
return 0;
result = confdb_object_find_start(handle, OBJECT_PARENT_HANDLE);
if (result != CS_OK)
goto out;
result = confdb_object_find(handle, OBJECT_PARENT_HANDLE, (void *)"cluster", strlen("cluster"), &cluster_handle);
if (result != CS_OK)
goto out;
result = confdb_key_get(handle, cluster_handle, (void *)"name", strlen("name"), buf, &namelen);
if (result != CS_OK)
goto out;
buf[namelen] = '\0';
out:
confdb_finalize(handle);
return 0;
}
static struct cluster_ops _cluster_corosync_ops = {
.cluster_init_completed = NULL,
.cluster_send_message = _cluster_send_message,
.name_from_csid = _name_from_csid,
.csid_from_name = _csid_from_name,
.get_num_nodes = _get_num_nodes,
.cluster_fd_callback = _cluster_fd_callback,
.get_main_cluster_fd = _get_main_cluster_fd,
.cluster_do_node_callback = _cluster_do_node_callback,
.is_quorate = _is_quorate,
.get_our_csid = _get_our_csid,
.add_up_node = _add_up_node,
.reread_config = NULL,
.cluster_closedown = _cluster_closedown,
.get_cluster_name = _get_cluster_name,
.sync_lock = _lock_resource,
.sync_unlock = _unlock_resource,
};
struct cluster_ops *init_corosync_cluster(void)
{
if (!_init_cluster())
return &_cluster_corosync_ops;
else
return NULL;
}

View File

@@ -1,13 +1,20 @@
/******************************************************************************
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved.
** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
**
*******************************************************************************
******************************************************************************/
/*
* Copyright (C) 2002-2003 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* This provides the interface between clvmd and gulm as the cluster
/*
* This provides the interface between clvmd and gulm as the cluster
* and lock manager.
*
* It also provides the "liblm" functions too as it's hard (and pointless)
@@ -17,36 +24,27 @@
* on the cluster nodes. That is done in tcp-comms.c
*/
#include "clvmd-common.h"
#include <pthread.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <stddef.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <utmpx.h>
#include <syslog.h>
#include <assert.h>
#include <libdevmapper.h>
#include <ccs.h>
#include <libgulm.h>
#include "list.h"
#include "locking.h"
#include "log.h"
#include "clvm.h"
#include "clvmd-comms.h"
#include "lvm-functions.h"
@@ -249,7 +247,7 @@ static void _cluster_closedown(void)
{
DEBUGLOG("cluster_closedown\n");
in_shutdown = 1;
unlock_all();
destroy_lvhash();
lg_lock_logout(gulm_if);
lg_core_logout(gulm_if);
lg_release(gulm_if);
@@ -733,7 +731,7 @@ static int _lock_resource(char *resource, int mode, int flags, int *lockid)
pthread_mutex_lock(&lwait.mutex);
/* This needs to be converted from DLM/LVM2 value for GULM */
if (flags & LKF_NOQUEUE) flags = lg_lock_flag_Try;
if (flags & LCKF_NOQUEUE) flags = lg_lock_flag_Try;
dm_hash_insert(lock_hash, resource, &lwait);
DEBUGLOG("lock_resource '%s', flags=%d, mode=%d\n", resource, flags, mode);
@@ -951,7 +949,7 @@ static int get_all_cluster_nodes()
}
else {
DEBUGLOG("Cannot resolve host name %s\n", nodename);
log_err("Cannot resolve host name %s\n", nodename);
log_error("Cannot resolve host name %s\n", nodename);
}
}
free(nodename);

View File

@@ -1,7 +1,3 @@
/* DLM constant that clvmd uses as a generic NONBLOCK lock flag */
#define LKF_NOQUEUE 1
extern int get_next_node_csid(void **context, char *csid);
extern void add_down_node(char *csid);
extern int gulm_fd(void);

View File

@@ -1,47 +1,35 @@
/******************************************************************************
*******************************************************************************
**
** Copyright (C) 2007 Red Hat, Inc. All rights reserved.
**
*******************************************************************************
******************************************************************************/
/* This provides the interface between clvmd and OpenAIS as the cluster
* and lock manager.
/*
* Copyright (C) 2007-2009 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* This provides the interface between clvmd and OpenAIS as the cluster
* and lock manager.
*/
#include "clvmd-common.h"
#include <pthread.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <stddef.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <utmpx.h>
#include <syslog.h>
#include <assert.h>
#include <libdevmapper.h>
#include <openais/saAis.h>
#include <openais/saLck.h>
#include <openais/cpg.h>
#include "list.h"
#include <corosync/corotypes.h>
#include <corosync/cpg.h>
#include "locking.h"
#include "log.h"
#include "clvm.h"
#include "clvmd-comms.h"
#include "lvm-functions.h"
@@ -50,17 +38,18 @@
/* Timeout value for several openais calls */
#define TIMEOUT 10
static void cpg_deliver_callback (cpg_handle_t handle,
struct cpg_name *groupName,
static void openais_cpg_deliver_callback (cpg_handle_t handle,
const struct cpg_name *groupName,
uint32_t nodeid,
uint32_t pid,
void *msg,
int msg_len);
static void cpg_confchg_callback(cpg_handle_t handle,
struct cpg_name *groupName,
struct cpg_address *member_list, int member_list_entries,
struct cpg_address *left_list, int left_list_entries,
struct cpg_address *joined_list, int joined_list_entries);
size_t msg_len);
static void openais_cpg_confchg_callback(cpg_handle_t handle,
const struct cpg_name *groupName,
const struct cpg_address *member_list, size_t member_list_entries,
const struct cpg_address *left_list, size_t left_list_entries,
const struct cpg_address *joined_list, size_t joined_list_entries);
static void _cluster_closedown(void);
/* Hash list of nodes in the cluster */
@@ -82,9 +71,9 @@ static SaLckHandleT lck_handle;
static struct cpg_name cpg_group_name;
/* Openais callback structs */
cpg_callbacks_t cpg_callbacks = {
.cpg_deliver_fn = cpg_deliver_callback,
.cpg_confchg_fn = cpg_confchg_callback,
cpg_callbacks_t openais_cpg_callbacks = {
.cpg_deliver_fn = openais_cpg_deliver_callback,
.cpg_confchg_fn = openais_cpg_confchg_callback,
};
struct node_info
@@ -192,7 +181,7 @@ static int ais_to_errno(SaAisErrorT err)
return -1;
}
static char *print_csid(const char *csid)
static char *print_openais_csid(const char *csid)
{
static char buf[128];
int id;
@@ -227,12 +216,12 @@ static int add_internal_client(int fd, fd_callback_t callback)
return 0;
}
static void cpg_deliver_callback (cpg_handle_t handle,
struct cpg_name *groupName,
static void openais_cpg_deliver_callback (cpg_handle_t handle,
const struct cpg_name *groupName,
uint32_t nodeid,
uint32_t pid,
void *msg,
int msg_len)
size_t msg_len)
{
int target_nodeid;
@@ -247,11 +236,11 @@ static void cpg_deliver_callback (cpg_handle_t handle,
msg_len-OPENAIS_CSID_LEN, (char*)&nodeid);
}
static void cpg_confchg_callback(cpg_handle_t handle,
struct cpg_name *groupName,
struct cpg_address *member_list, int member_list_entries,
struct cpg_address *left_list, int left_list_entries,
struct cpg_address *joined_list, int joined_list_entries)
static void openais_cpg_confchg_callback(cpg_handle_t handle,
const struct cpg_name *groupName,
const struct cpg_address *member_list, size_t member_list_entries,
const struct cpg_address *left_list, size_t left_list_entries,
const struct cpg_address *joined_list, size_t joined_list_entries)
{
int i;
struct node_info *ninfo;
@@ -327,7 +316,7 @@ static int _init_cluster(void)
lock_hash = dm_hash_create(10);
err = cpg_initialize(&cpg_handle,
&cpg_callbacks);
&openais_cpg_callbacks);
if (err != SA_AIS_OK) {
syslog(LOG_ERR, "Cannot initialise OpenAIS CPG service: %d",
err);
@@ -339,7 +328,7 @@ static int _init_cluster(void)
NULL,
&ver);
if (err != SA_AIS_OK) {
cpg_initialize(&cpg_handle, &cpg_callbacks);
cpg_initialize(&cpg_handle, &openais_cpg_callbacks);
syslog(LOG_ERR, "Cannot initialise OpenAIS lock service: %d",
err);
DEBUGLOG("Cannot initialise OpenAIS lock service: %d\n\n", err);
@@ -379,7 +368,7 @@ static int _init_cluster(void)
static void _cluster_closedown(void)
{
DEBUGLOG("cluster_closedown\n");
unlock_all();
destroy_lvhash();
saLckFinalize(lck_handle);
cpg_finalize(cpg_handle);
@@ -412,7 +401,7 @@ static int _name_from_csid(const char *csid, char *name)
ninfo = dm_hash_lookup_binary(node_hash, csid, OPENAIS_CSID_LEN);
if (!ninfo)
{
sprintf(name, "UNKNOWN %s", print_csid(csid));
sprintf(name, "UNKNOWN %s", print_openais_csid(csid));
return -1;
}
@@ -434,7 +423,7 @@ static void _add_up_node(const char *csid)
ninfo = dm_hash_lookup_binary(node_hash, csid, OPENAIS_CSID_LEN);
if (!ninfo) {
DEBUGLOG("openais_add_up_node no node_hash entry for csid %s\n",
print_csid(csid));
print_openais_csid(csid));
return;
}

View File

@@ -0,0 +1,281 @@
/*
* Copyright (C) 2009 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "clvmd-common.h"
#include <pthread.h>
#include "locking.h"
#include "clvm.h"
#include "clvmd-comms.h"
#include "lvm-functions.h"
#include "clvmd.h"
#include <sys/un.h>
#include <sys/socket.h>
#include <fcntl.h>
static const char SINGLENODE_CLVMD_SOCKNAME[] = DEFAULT_RUN_DIR "/clvmd_singlenode.sock";
static int listen_fd = -1;
static void close_comms(void)
{
if (listen_fd != -1 && close(listen_fd))
stack;
(void)unlink(SINGLENODE_CLVMD_SOCKNAME);
listen_fd = -1;
}
static int init_comms(void)
{
struct sockaddr_un addr;
mode_t old_mask;
close_comms();
old_mask = umask(0077);
listen_fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (listen_fd < 0) {
DEBUGLOG("Can't create local socket: %s\n", strerror(errno));
goto error;
}
/* Set Close-on-exec */
fcntl(listen_fd, F_SETFD, 1);
memset(&addr, 0, sizeof(addr));
memcpy(addr.sun_path, SINGLENODE_CLVMD_SOCKNAME,
sizeof(SINGLENODE_CLVMD_SOCKNAME));
addr.sun_family = AF_UNIX;
if (bind(listen_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
DEBUGLOG("Can't bind local socket: %s\n", strerror(errno));
goto error;
}
if (listen(listen_fd, 10) < 0) {
DEBUGLOG("Can't listen local socket: %s\n", strerror(errno));
goto error;
}
umask(old_mask);
return 0;
error:
umask(old_mask);
close_comms();
return -1;
}
static int _init_cluster(void)
{
int r;
r = init_comms();
if (r)
return r;
DEBUGLOG("Single-node cluster initialised.\n");
return 0;
}
static void _cluster_closedown(void)
{
close_comms();
DEBUGLOG("cluster_closedown\n");
destroy_lvhash();
}
static void _get_our_csid(char *csid)
{
int nodeid = 1;
memcpy(csid, &nodeid, sizeof(int));
}
static int _csid_from_name(char *csid, const char *name)
{
return 1;
}
static int _name_from_csid(const char *csid, char *name)
{
sprintf(name, "SINGLENODE");
return 0;
}
static int _get_num_nodes(void)
{
return 1;
}
/* Node is now known to be running a clvmd */
static void _add_up_node(const char *csid)
{
}
/* Call a callback for each node, so the caller knows whether it's up or down */
static int _cluster_do_node_callback(struct local_client *master_client,
void (*callback)(struct local_client *,
const char *csid, int node_up))
{
return 0;
}
int _lock_file(const char *file, uint32_t flags);
static int *_locks = NULL;
static char **_resources = NULL;
static int _lock_max = 1;
static pthread_mutex_t _lock_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Real locking */
static int _lock_resource(const char *resource, int mode, int flags, int *lockid)
{
int *_locks_1;
char **_resources_1;
int i, j;
DEBUGLOG("lock_resource '%s', flags=%d, mode=%d\n",
resource, flags, mode);
retry:
pthread_mutex_lock(&_lock_mutex);
/* look for an existing lock for this resource */
for (i = 1; i < _lock_max; ++i) {
if (!_resources[i])
break;
if (!strcmp(_resources[i], resource)) {
if ((_locks[i] & LCK_WRITE) || (_locks[i] & LCK_EXCL)) {
DEBUGLOG("%s already write/exclusively locked...\n", resource);
goto maybe_retry;
}
if ((mode & LCK_WRITE) || (mode & LCK_EXCL)) {
DEBUGLOG("%s already locked and WRITE/EXCL lock requested...\n",
resource);
goto maybe_retry;
}
}
}
if (i == _lock_max) { /* out of lock slots, extend */
_locks_1 = dm_realloc(_locks, 2 * _lock_max * sizeof(int));
if (!_locks_1)
return 1; /* fail */
_locks = _locks_1;
_resources_1 = dm_realloc(_resources, 2 * _lock_max * sizeof(char *));
if (!_resources_1) {
/* _locks may get realloc'd twice, but that should be safe */
return 1; /* fail */
}
_resources = _resources_1;
/* clear the new resource entries */
for (j = _lock_max; j < 2 * _lock_max; ++j)
_resources[j] = NULL;
_lock_max = 2 * _lock_max;
}
/* resource is not currently locked, grab it */
*lockid = i;
_locks[i] = mode;
_resources[i] = dm_strdup(resource);
DEBUGLOG("%s locked -> %d\n", resource, i);
pthread_mutex_unlock(&_lock_mutex);
return 0;
maybe_retry:
pthread_mutex_unlock(&_lock_mutex);
if (!(flags & LCK_NONBLOCK)) {
usleep(10000);
goto retry;
}
return 1; /* fail */
}
static int _unlock_resource(const char *resource, int lockid)
{
DEBUGLOG("unlock_resource: %s lockid: %x\n", resource, lockid);
if(!_resources[lockid]) {
DEBUGLOG("(%s) %d not locked\n", resource, lockid);
return 1;
}
if(strcmp(_resources[lockid], resource)) {
DEBUGLOG("%d has wrong resource (requested %s, got %s)\n",
lockid, resource, _resources[lockid]);
return 1;
}
dm_free(_resources[lockid]);
_resources[lockid] = 0;
return 0;
}
static int _is_quorate(void)
{
return 1;
}
static int _get_main_cluster_fd(void)
{
return listen_fd;
}
static int _cluster_fd_callback(struct local_client *fd, char *buf, int len,
const char *csid,
struct local_client **new_client)
{
return 1;
}
static int _cluster_send_message(const void *buf, int msglen,
const char *csid,
const char *errtext)
{
return 0;
}
static int _get_cluster_name(char *buf, int buflen)
{
strncpy(buf, "localcluster", buflen);
buf[buflen - 1] = 0;
return 0;
}
static struct cluster_ops _cluster_singlenode_ops = {
.cluster_init_completed = NULL,
.cluster_send_message = _cluster_send_message,
.name_from_csid = _name_from_csid,
.csid_from_name = _csid_from_name,
.get_num_nodes = _get_num_nodes,
.cluster_fd_callback = _cluster_fd_callback,
.get_main_cluster_fd = _get_main_cluster_fd,
.cluster_do_node_callback = _cluster_do_node_callback,
.is_quorate = _is_quorate,
.get_our_csid = _get_our_csid,
.add_up_node = _add_up_node,
.reread_config = NULL,
.cluster_closedown = _cluster_closedown,
.get_cluster_name = _get_cluster_name,
.sync_lock = _lock_resource,
.sync_unlock = _unlock_resource,
};
struct cluster_ops *init_singlenode_cluster(void)
{
if (!_init_cluster())
return &_cluster_singlenode_ops;
else
return NULL;
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -17,37 +17,28 @@
* CLVMD: Cluster LVM daemon
*/
#include "clvmd-common.h"
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/utsname.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdarg.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <getopt.h>
#include <syslog.h>
#include <errno.h>
#include <limits.h>
#include <libdlm.h>
#include "clvmd-comms.h"
#include "lvm-functions.h"
#include "clvm.h"
#include "version.h"
#include "clvmd.h"
#include "lvm-functions.h"
#include "lvm-version.h"
#include "refresh_clvmd.h"
#include "list.h"
#include "log.h"
#ifdef HAVE_COROSYNC_CONFDB_H
#include <corosync/confdb.h>
#endif
#include <fcntl.h>
#include <netinet/in.h>
#include <signal.h>
#include <stddef.h>
#include <syslog.h>
#include <sys/un.h>
#include <sys/utsname.h>
#ifndef TRUE
#define TRUE 1
@@ -75,7 +66,7 @@ static unsigned max_cluster_member_name_len;
/* Structure of items on the LVM thread list */
struct lvm_thread_cmd {
struct list list;
struct dm_list list;
struct local_client *client;
struct clvm_header *msg;
@@ -85,12 +76,17 @@ struct lvm_thread_cmd {
unsigned short xid;
};
struct lvm_startup_params {
int using_gulm;
char **argv;
};
debug_t debug;
static pthread_t lvm_thread;
static pthread_mutex_t lvm_thread_mutex;
static pthread_cond_t lvm_thread_cond;
static pthread_mutex_t lvm_start_mutex;
static struct list lvm_cmd_head;
static struct dm_list lvm_cmd_head;
static volatile sig_atomic_t quit = 0;
static volatile sig_atomic_t reread_config = 0;
static int child_pipe[2];
@@ -103,6 +99,10 @@ static int child_pipe[2];
#define DFAIL_TIMEOUT 5
#define SUCCESS 0
typedef enum {IF_AUTO, IF_CMAN, IF_GULM, IF_OPENAIS, IF_COROSYNC, IF_SINGLENODE} if_type_t;
typedef void *(lvm_pthread_fn_t)(void*);
/* Prototypes for code further down */
static void sigusr2_handler(int sig);
static void sighup_handler(int sig);
@@ -123,6 +123,7 @@ static void process_remote_command(struct clvm_header *msg, int msglen, int fd,
static int process_reply(const struct clvm_header *msg, int msglen,
const char *csid);
static int open_local_sock(void);
static void close_local_sock(int local_socket);
static int check_local_clvmd(void);
static struct local_client *find_client(int clientid);
static void main_loop(int local_sock, int cmd_timeout);
@@ -131,7 +132,7 @@ static int check_all_clvmds_running(struct local_client *client);
static int local_rendezvous_callback(struct local_client *thisfd, char *buf,
int len, const char *csid,
struct local_client **new_client);
static void *lvm_thread_fn(void *);
static void lvm_thread_fn(void *) __attribute__ ((noreturn));
static int add_to_lvmqueue(struct local_client *client, struct clvm_header *msg,
int msglen, const char *csid);
static int distribute_command(struct local_client *thisfd);
@@ -139,6 +140,8 @@ static void hton_clvm(struct clvm_header *hdr);
static void ntoh_clvm(struct clvm_header *hdr);
static void add_reply_to_list(struct local_client *client, int status,
const char *csid, const char *buf, int len);
static if_type_t parse_cluster_interface(char *ifname);
static if_type_t get_cluster_type(void);
static void usage(char *prog, FILE *file)
{
@@ -150,9 +153,27 @@ static void usage(char *prog, FILE *file)
fprintf(file, " -d Set debug level\n");
fprintf(file, " If starting clvmd then don't fork, run in the foreground\n");
fprintf(file, " -R Tell all running clvmds in the cluster to reload their device cache\n");
fprintf(file, " -S Restart clvmd, preserving exclusive locks\n");
fprintf(file, " -C Sets debug level (from -d) on all clvmd instances clusterwide\n");
fprintf(file, " -t<secs> Command timeout (default 60 seconds)\n");
fprintf(file, " -T<secs> Startup timeout (default none)\n");
fprintf(file, " -I<cmgr> Cluster manager (default: auto)\n");
fprintf(file, " Available cluster managers: ");
#ifdef USE_COROSYNC
fprintf(file, "corosync ");
#endif
#ifdef USE_CMAN
fprintf(file, "cman ");
#endif
#ifdef USE_OPENAIS
fprintf(file, "openais ");
#endif
#ifdef USE_GULM
fprintf(file, "gulm ");
#endif
#ifdef USE_SINGLENODE
fprintf(file, "singlenode");
#endif
fprintf(file, "\n");
}
@@ -199,44 +220,50 @@ static const char *decode_cmd(unsigned char cmdl)
const char *command;
switch (cmdl) {
case CLVMD_CMD_TEST:
command = "TEST";
case CLVMD_CMD_TEST:
command = "TEST";
break;
case CLVMD_CMD_LOCK_VG:
command = "LOCK_VG";
case CLVMD_CMD_LOCK_VG:
command = "LOCK_VG";
break;
case CLVMD_CMD_LOCK_LV:
command = "LOCK_LV";
case CLVMD_CMD_LOCK_LV:
command = "LOCK_LV";
break;
case CLVMD_CMD_REFRESH:
command = "REFRESH";
case CLVMD_CMD_REFRESH:
command = "REFRESH";
break;
case CLVMD_CMD_SET_DEBUG:
command = "SET_DEBUG";
case CLVMD_CMD_SET_DEBUG:
command = "SET_DEBUG";
break;
case CLVMD_CMD_GET_CLUSTERNAME:
case CLVMD_CMD_GET_CLUSTERNAME:
command = "GET_CLUSTERNAME";
break;
case CLVMD_CMD_VG_BACKUP:
command = "VG_BACKUP";
case CLVMD_CMD_VG_BACKUP:
command = "VG_BACKUP";
break;
case CLVMD_CMD_REPLY:
command = "REPLY";
case CLVMD_CMD_REPLY:
command = "REPLY";
break;
case CLVMD_CMD_VERSION:
command = "VERSION";
case CLVMD_CMD_VERSION:
command = "VERSION";
break;
case CLVMD_CMD_GOAWAY:
command = "GOAWAY";
case CLVMD_CMD_GOAWAY:
command = "GOAWAY";
break;
case CLVMD_CMD_LOCK:
command = "LOCK";
case CLVMD_CMD_LOCK:
command = "LOCK";
break;
case CLVMD_CMD_UNLOCK:
command = "UNLOCK";
case CLVMD_CMD_UNLOCK:
command = "UNLOCK";
break;
default:
command = "unknown";
case CLVMD_CMD_LOCK_QUERY:
command = "LOCK_QUERY";
break;
case CLVMD_CMD_RESTART:
command = "RESTART";
break;
default:
command = "unknown";
break;
}
@@ -245,14 +272,38 @@ static const char *decode_cmd(unsigned char cmdl)
return buf;
}
static void remove_lockfile(void)
{
unlink(CLVMD_PIDFILE);
}
/*
* clvmd require dm-ioctl capability for operation
*/
static void check_permissions(void)
{
if (getuid() || geteuid()) {
log_error("Cannot run as a non-root user.");
/*
* Fail cleanly here if not run as root, instead of failing
* later when attempting a root-only operation
* Preferred exit code from an initscript for this.
*/
exit(4);
}
}
int main(int argc, char *argv[])
{
int local_sock;
struct local_client *newfd;
struct utsname nodeinfo;
struct lvm_startup_params lvm_params;
signed char opt;
int cmd_timeout = DEFAULT_CMD_TIMEOUT;
int start_timeout = 0;
if_type_t cluster_iface = IF_AUTO;
sigset_t ss;
int using_gulm = 0;
int debug_opt = 0;
@@ -261,7 +312,7 @@ int main(int argc, char *argv[])
/* Deal with command-line arguments */
opterr = 0;
optind = 0;
while ((opt = getopt(argc, argv, "?vVhd::t:RT:C")) != EOF) {
while ((opt = getopt(argc, argv, "?vVhd::t:RST:CI:E:")) != EOF) {
switch (opt) {
case 'h':
usage(argv[0], stdout);
@@ -272,7 +323,12 @@ int main(int argc, char *argv[])
exit(0);
case 'R':
return refresh_clvmd();
check_permissions();
return refresh_clvmd(1)==1?0:1;
case 'S':
check_permissions();
return restart_clvmd(clusterwide_opt)==1?0:1;
case 'C':
clusterwide_opt = 1;
@@ -294,6 +350,9 @@ int main(int argc, char *argv[])
exit(1);
}
break;
case 'I':
cluster_iface = parse_cluster_interface(optarg);
break;
case 'T':
start_timeout = atoi(optarg);
if (start_timeout <= 0) {
@@ -308,26 +367,44 @@ int main(int argc, char *argv[])
printf("Protocol version: %d.%d.%d\n",
CLVMD_MAJOR_VERSION, CLVMD_MINOR_VERSION,
CLVMD_PATCH_VERSION);
exit(1);
exit(0);
break;
}
}
check_permissions();
/* Setting debug options on an existing clvmd */
if (debug_opt && !check_local_clvmd()) {
/* Sending to stderr makes no sense for a detached daemon */
if (debug == DEBUG_STDERR)
debug = DEBUG_SYSLOG;
return debug_clvmd(debug, clusterwide_opt);
return debug_clvmd(debug, clusterwide_opt)==1?0:1;
}
/*
* Switch to C locale to avoid reading large locale-archive file
* used by some glibc (on some distributions it takes over 100MB).
* Daemon currently needs to use mlockall().
*/
if (setenv("LANG", "C", 1))
perror("Cannot set LANG to C");
/* Fork into the background (unless requested not to) */
if (debug != DEBUG_STDERR) {
be_daemon(start_timeout);
}
/* Create pidfile */
if (dm_create_lockfile(CLVMD_PIDFILE) == 0) {
DEBUGLOG("clvmd: unable to create lockfile\n");
exit(1);
}
atexit(remove_lockfile);
DEBUGLOG("CLVMD started\n");
/* Open the Unix socket we listen for commands on.
@@ -346,21 +423,26 @@ int main(int argc, char *argv[])
signal(SIGHUP, sighup_handler);
signal(SIGPIPE, SIG_IGN);
/* Block SIGUSR2 in the main process */
/* Block SIGUSR2/SIGINT/SIGTERM in process */
sigemptyset(&ss);
sigaddset(&ss, SIGUSR2);
sigaddset(&ss, SIGINT);
sigaddset(&ss, SIGTERM);
sigprocmask(SIG_BLOCK, &ss, NULL);
/* Initialise the LVM thread variables */
list_init(&lvm_cmd_head);
dm_list_init(&lvm_cmd_head);
pthread_mutex_init(&lvm_thread_mutex, NULL);
pthread_cond_init(&lvm_thread_cond, NULL);
pthread_mutex_init(&lvm_start_mutex, NULL);
init_lvhash();
/* Start the cluster interface */
if (cluster_iface == IF_AUTO)
cluster_iface = get_cluster_type();
#ifdef USE_CMAN
if ((clops = init_cman_cluster())) {
if ((cluster_iface == IF_AUTO || cluster_iface == IF_CMAN) && (clops = init_cman_cluster())) {
max_csid_len = CMAN_MAX_CSID_LEN;
max_cluster_message = CMAN_MAX_CLUSTER_MESSAGE;
max_cluster_member_name_len = CMAN_MAX_NODENAME_LEN;
@@ -369,7 +451,7 @@ int main(int argc, char *argv[])
#endif
#ifdef USE_GULM
if (!clops)
if ((clops = init_gulm_cluster())) {
if ((cluster_iface == IF_AUTO || cluster_iface == IF_GULM) && (clops = init_gulm_cluster())) {
max_csid_len = GULM_MAX_CSID_LEN;
max_cluster_message = GULM_MAX_CLUSTER_MESSAGE;
max_cluster_member_name_len = GULM_MAX_CLUSTER_MEMBER_NAME_LEN;
@@ -377,15 +459,33 @@ int main(int argc, char *argv[])
syslog(LOG_NOTICE, "Cluster LVM daemon started - connected to GULM");
}
#endif
#ifdef USE_COROSYNC
if (!clops)
if (((cluster_iface == IF_AUTO || cluster_iface == IF_COROSYNC) && (clops = init_corosync_cluster()))) {
max_csid_len = COROSYNC_CSID_LEN;
max_cluster_message = COROSYNC_MAX_CLUSTER_MESSAGE;
max_cluster_member_name_len = COROSYNC_MAX_CLUSTER_MEMBER_NAME_LEN;
syslog(LOG_NOTICE, "Cluster LVM daemon started - connected to Corosync");
}
#endif
#ifdef USE_OPENAIS
if (!clops)
if ((clops = init_openais_cluster())) {
if ((cluster_iface == IF_AUTO || cluster_iface == IF_OPENAIS) && (clops = init_openais_cluster())) {
max_csid_len = OPENAIS_CSID_LEN;
max_cluster_message = OPENAIS_MAX_CLUSTER_MESSAGE;
max_cluster_member_name_len = OPENAIS_MAX_CLUSTER_MEMBER_NAME_LEN;
syslog(LOG_NOTICE, "Cluster LVM daemon started - connected to OpenAIS");
}
#endif
#ifdef USE_SINGLENODE
if (!clops)
if (cluster_iface == IF_SINGLENODE && (clops = init_singlenode_cluster())) {
max_csid_len = SINGLENODE_CSID_LEN;
max_cluster_message = SINGLENODE_MAX_CLUSTER_MESSAGE;
max_cluster_member_name_len = MAX_CLUSTER_MEMBER_NAME_LEN;
syslog(LOG_NOTICE, "Cluster LVM daemon started - running in single-node mode");
}
#endif
if (!clops) {
DEBUGLOG("Can't initialise cluster interface\n");
@@ -418,8 +518,13 @@ int main(int argc, char *argv[])
/* This needs to be started after cluster initialisation
as it may need to take out locks */
DEBUGLOG("starting LVM thread\n");
pthread_create(&lvm_thread, NULL, lvm_thread_fn,
(void *)(long)using_gulm);
/* Don't let anyone else to do work until we are started */
pthread_mutex_lock(&lvm_start_mutex);
lvm_params.using_gulm = using_gulm;
lvm_params.argv = argv;
pthread_create(&lvm_thread, NULL, (lvm_pthread_fn_t*)lvm_thread_fn,
(void *)&lvm_params);
/* Tell the rest of the cluster our version number */
/* CMAN can do this immediately, gulm needs to wait until
@@ -438,6 +543,9 @@ int main(int argc, char *argv[])
/* Do some work */
main_loop(local_sock, cmd_timeout);
close_local_sock(local_sock);
destroy_lvm();
return 0;
}
@@ -478,6 +586,10 @@ static int local_rendezvous_callback(struct local_client *thisfd, char *buf,
close(client_fd);
return 1;
}
if (fcntl(client_fd, F_SETFD, 1))
DEBUGLOG("setting CLOEXEC on client fd failed: %s\n", strerror(errno));
newfd->fd = client_fd;
newfd->type = LOCAL_SOCK;
newfd->xid = 0;
@@ -631,6 +743,11 @@ static void main_loop(int local_sock, int cmd_timeout)
{
DEBUGLOG("Using timeout of %d seconds\n", cmd_timeout);
sigset_t ss;
sigemptyset(&ss);
sigaddset(&ss, SIGINT);
sigaddset(&ss, SIGTERM);
pthread_sigmask(SIG_UNBLOCK, &ss, NULL);
/* Main loop */
while (!quit) {
fd_set in;
@@ -770,7 +887,6 @@ static void main_loop(int local_sock, int cmd_timeout)
closedown:
clops->cluster_closedown();
close(local_sock);
}
static __attribute__ ((noreturn)) void wait_for_child(int c_pipe, int timeout)
@@ -1104,6 +1220,12 @@ static int read_from_local_sock(struct local_client *thisfd)
}
DEBUGLOG("creating pipe, [%d, %d]\n", comms_pipe[0],
comms_pipe[1]);
if (fcntl(comms_pipe[0], F_SETFD, 1))
DEBUGLOG("setting CLOEXEC on pipe[0] failed: %s\n", strerror(errno));
if (fcntl(comms_pipe[1], F_SETFD, 1))
DEBUGLOG("setting CLOEXEC on pipe[1] failed: %s\n", strerror(errno));
newfd->fd = comms_pipe[0];
newfd->removeme = 0;
newfd->type = THREAD_PIPE;
@@ -1446,7 +1568,8 @@ static __attribute__ ((noreturn)) void *pre_and_post_thread(void *arg)
DEBUGLOG("Waiting to do post command - state = %d\n",
client->bits.localsock.state);
if (client->bits.localsock.state != POST_COMMAND) {
if (client->bits.localsock.state != POST_COMMAND &&
!client->bits.localsock.finished) {
pthread_cond_wait(&client->bits.localsock.cond,
&client->bits.localsock.mutex);
}
@@ -1747,14 +1870,11 @@ static int process_work_item(struct lvm_thread_cmd *cmd)
/*
* Routine that runs in the "LVM thread".
*/
static __attribute__ ((noreturn)) void *lvm_thread_fn(void *arg)
static void lvm_thread_fn(void *arg)
{
struct list *cmdl, *tmp;
struct dm_list *cmdl, *tmp;
sigset_t ss;
int using_gulm = (int)(long)arg;
/* Don't let anyone else to do work until we are started */
pthread_mutex_lock(&lvm_start_mutex);
struct lvm_startup_params *lvm_params = arg;
DEBUGLOG("LVM thread function started\n");
@@ -1765,7 +1885,7 @@ static __attribute__ ((noreturn)) void *lvm_thread_fn(void *arg)
pthread_sigmask(SIG_BLOCK, &ss, NULL);
/* Initialise the interface to liblvm */
init_lvm(using_gulm);
init_clvm(lvm_params->using_gulm, lvm_params->argv);
/* Allow others to get moving */
pthread_mutex_unlock(&lvm_start_mutex);
@@ -1775,15 +1895,15 @@ static __attribute__ ((noreturn)) void *lvm_thread_fn(void *arg)
DEBUGLOG("LVM thread waiting for work\n");
pthread_mutex_lock(&lvm_thread_mutex);
if (list_empty(&lvm_cmd_head))
if (dm_list_empty(&lvm_cmd_head))
pthread_cond_wait(&lvm_thread_cond, &lvm_thread_mutex);
list_iterate_safe(cmdl, tmp, &lvm_cmd_head) {
dm_list_iterate_safe(cmdl, tmp, &lvm_cmd_head) {
struct lvm_thread_cmd *cmd;
cmd =
list_struct_base(cmdl, struct lvm_thread_cmd, list);
list_del(&cmd->list);
dm_list_struct_base(cmdl, struct lvm_thread_cmd, list);
dm_list_del(&cmd->list);
pthread_mutex_unlock(&lvm_thread_mutex);
process_work_item(cmd);
@@ -1833,7 +1953,7 @@ static int add_to_lvmqueue(struct local_client *client, struct clvm_header *msg,
("add_to_lvmqueue: cmd=%p. client=%p, msg=%p, len=%d, csid=%p, xid=%d\n",
cmd, client, msg, msglen, csid, cmd->xid);
pthread_mutex_lock(&lvm_thread_mutex);
list_add(&lvm_cmd_head, &cmd->list);
dm_list_add(&lvm_cmd_head, &cmd->list);
pthread_cond_signal(&lvm_thread_cond);
pthread_mutex_unlock(&lvm_thread_mutex);
@@ -1865,23 +1985,35 @@ static int check_local_clvmd(void)
return ret;
}
static void close_local_sock(int local_socket)
{
if (local_socket != -1 && close(local_socket))
stack;
if (CLVMD_SOCKNAME[0] != '\0' && unlink(CLVMD_SOCKNAME))
stack;
}
/* Open the local socket, that's the one we talk to libclvm down */
static int open_local_sock()
{
int local_socket;
int local_socket = -1;
struct sockaddr_un sockaddr;
mode_t old_mask;
close_local_sock(local_socket);
old_mask = umask(0077);
/* Open local socket */
if (CLVMD_SOCKNAME[0] != '\0')
unlink(CLVMD_SOCKNAME);
local_socket = socket(PF_UNIX, SOCK_STREAM, 0);
if (local_socket < 0) {
log_error("Can't create local socket: %m");
return -1;
goto error;
}
/* Set Close-on-exec & non-blocking */
fcntl(local_socket, F_SETFD, 1);
if (fcntl(local_socket, F_SETFD, 1))
DEBUGLOG("setting CLOEXEC on local_socket failed: %s\n", strerror(errno));
fcntl(local_socket, F_SETFL, fcntl(local_socket, F_GETFL, 0) | O_NONBLOCK);
memset(&sockaddr, 0, sizeof(sockaddr));
@@ -1889,18 +2021,19 @@ static int open_local_sock()
sockaddr.sun_family = AF_UNIX;
if (bind(local_socket, (struct sockaddr *) &sockaddr, sizeof(sockaddr))) {
log_error("can't bind local socket: %m");
close(local_socket);
return -1;
goto error;
}
if (listen(local_socket, 1) != 0) {
log_error("listen local: %m");
close(local_socket);
return -1;
goto error;
}
if (CLVMD_SOCKNAME[0] != '\0')
chmod(CLVMD_SOCKNAME, 0600);
umask(old_mask);
return local_socket;
error:
close_local_sock(local_socket);
umask(old_mask);
return -1;
}
void process_message(struct local_client *client, const char *buf, int len,
@@ -1994,3 +2127,78 @@ int sync_unlock(const char *resource, int lockid)
return clops->sync_unlock(resource, lockid);
}
static if_type_t parse_cluster_interface(char *ifname)
{
if_type_t iface = IF_AUTO;
if (!strcmp(ifname, "auto"))
iface = IF_AUTO;
if (!strcmp(ifname, "cman"))
iface = IF_CMAN;
if (!strcmp(ifname, "gulm"))
iface = IF_GULM;
if (!strcmp(ifname, "openais"))
iface = IF_OPENAIS;
if (!strcmp(ifname, "corosync"))
iface = IF_COROSYNC;
if (!strcmp(ifname, "singlenode"))
iface = IF_SINGLENODE;
return iface;
}
/*
* Try and find a cluster system in corosync's objdb, if it is running. This is
* only called if the command-line option is not present, and if it fails
* we still try the interfaces in order.
*/
static if_type_t get_cluster_type()
{
#ifdef HAVE_COROSYNC_CONFDB_H
confdb_handle_t handle;
if_type_t type = IF_AUTO;
int result;
char buf[255];
size_t namelen = sizeof(buf);
hdb_handle_t cluster_handle;
hdb_handle_t clvmd_handle;
confdb_callbacks_t callbacks = {
.confdb_key_change_notify_fn = NULL,
.confdb_object_create_change_notify_fn = NULL,
.confdb_object_delete_change_notify_fn = NULL
};
result = confdb_initialize (&handle, &callbacks);
if (result != CS_OK)
return type;
result = confdb_object_find_start(handle, OBJECT_PARENT_HANDLE);
if (result != CS_OK)
goto out;
result = confdb_object_find(handle, OBJECT_PARENT_HANDLE, (void *)"cluster", strlen("cluster"), &cluster_handle);
if (result != CS_OK)
goto out;
result = confdb_object_find_start(handle, cluster_handle);
if (result != CS_OK)
goto out;
result = confdb_object_find(handle, cluster_handle, (void *)"clvmd", strlen("clvmd"), &clvmd_handle);
if (result != CS_OK)
goto out;
result = confdb_key_get(handle, clvmd_handle, (void *)"interface", strlen("interface"), buf, &namelen);
if (result != CS_OK)
goto out;
buf[namelen] = '\0';
type = parse_cluster_interface(buf);
DEBUGLOG("got interface type '%s' from confdb\n", buf);
out:
confdb_finalize(handle);
return type;
#else
return IF_AUTO;
#endif
}

View File

@@ -20,9 +20,6 @@
#define CLVMD_MINOR_VERSION 2
#define CLVMD_PATCH_VERSION 1
/* Name of the cluster LVM admin lock */
#define ADMIN_LOCK_NAME "CLVMD_ADMIN"
/* Default time (in seconds) we will wait for all remote commands to execute
before declaring them dead */
#define DEFAULT_CMD_TIMEOUT 60

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -13,27 +13,10 @@
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <pthread.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <string.h>
#include <stddef.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <syslog.h>
#include <assert.h>
#include <libdevmapper.h>
#include <libdlm.h>
#include "clvmd-common.h"
#include <pthread.h>
#include "list.h"
#include "lvm-types.h"
#include "clvm.h"
#include "clvmd-comms.h"
@@ -43,26 +26,24 @@
/* LVM2 headers */
#include "toolcontext.h"
#include "lvmcache.h"
#include "log.h"
#include "lvm-globals.h"
#include "activate.h"
#include "locking.h"
#include "archiver.h"
#include "defaults.h"
#include "memlock.h"
#include <syslog.h>
static struct cmd_context *cmd = NULL;
static struct dm_hash_table *lv_hash = NULL;
static pthread_mutex_t lv_hash_lock;
static pthread_mutex_t lvm_lock;
static char last_error[1024];
static int suspended = 0;
struct lv_info {
int lock_id;
int lock_mode;
};
#define LCK_MASK (LCK_TYPE_MASK | LCK_SCOPE_MASK)
static const char *decode_locking_cmd(unsigned char cmdl)
{
static char buf[128];
@@ -71,23 +52,23 @@ static const char *decode_locking_cmd(unsigned char cmdl)
const char *command;
switch (cmdl & LCK_TYPE_MASK) {
case LCK_NULL:
type = "NULL";
case LCK_NULL:
type = "NULL";
break;
case LCK_READ:
type = "READ";
case LCK_READ:
type = "READ";
break;
case LCK_PREAD:
type = "PREAD";
case LCK_PREAD:
type = "PREAD";
break;
case LCK_WRITE:
type = "WRITE";
case LCK_WRITE:
type = "WRITE";
break;
case LCK_EXCL:
type = "EXCL";
case LCK_EXCL:
type = "EXCL";
break;
case LCK_UNLOCK:
type = "UNLOCK";
case LCK_UNLOCK:
type = "UNLOCK";
break;
default:
type = "unknown";
@@ -95,34 +76,35 @@ static const char *decode_locking_cmd(unsigned char cmdl)
}
switch (cmdl & LCK_SCOPE_MASK) {
case LCK_VG:
scope = "VG";
case LCK_VG:
scope = "VG";
command = "LCK_VG";
break;
case LCK_LV:
scope = "LV";
case LCK_LV:
scope = "LV";
switch (cmdl & LCK_MASK) {
case LCK_LV_EXCLUSIVE & LCK_MASK:
command = "LCK_LV_EXCLUSIVE";
break;
case LCK_LV_SUSPEND & LCK_MASK:
command = "LCK_LV_SUSPEND";
break;
case LCK_LV_RESUME & LCK_MASK:
command = "LCK_LV_RESUME";
break;
case LCK_LV_ACTIVATE & LCK_MASK:
command = "LCK_LV_ACTIVATE";
break;
case LCK_LV_DEACTIVATE & LCK_MASK:
command = "LCK_LV_DEACTIVATE";
break;
default:
command = "unknown";
break;
}
break;
default:
scope = "unknown";
break;
}
switch (cmdl & LCK_MASK) {
case LCK_LV_EXCLUSIVE & LCK_MASK:
command = "LCK_LV_EXCLUSIVE";
break;
case LCK_LV_SUSPEND & LCK_MASK:
command = "LCK_LV_SUSPEND";
break;
case LCK_LV_RESUME & LCK_MASK:
command = "LCK_LV_RESUME";
break;
case LCK_LV_ACTIVATE & LCK_MASK:
command = "LCK_LV_ACTIVATE";
break;
case LCK_LV_DEACTIVATE & LCK_MASK:
command = "LCK_LV_DEACTIVATE";
break;
default:
command = "unknown";
break;
}
@@ -140,11 +122,19 @@ static const char *decode_locking_cmd(unsigned char cmdl)
static const char *decode_flags(unsigned char flags)
{
static char buf[128];
int len;
sprintf(buf, "0x%x (%s%s%s)", flags,
flags & LCK_PARTIAL_MODE ? "PARTIAL " : "",
flags & LCK_MIRROR_NOSYNC_MODE ? "MIRROR_NOSYNC " : "",
flags & LCK_DMEVENTD_MONITOR_MODE ? "DMEVENTD_MONITOR " : "");
len = sprintf(buf, "0x%x ( %s%s%s%s%s)", flags,
flags & LCK_PARTIAL_MODE ? "PARTIAL_MODE|" : "",
flags & LCK_MIRROR_NOSYNC_MODE ? "MIRROR_NOSYNC|" : "",
flags & LCK_DMEVENTD_MONITOR_MODE ? "DMEVENTD_MONITOR|" : "",
flags & LCK_ORIGIN_ONLY_MODE ? "ORIGIN_ONLY|" : "",
flags & LCK_CONVERT ? "CONVERT|" : "");
if (len > 1)
buf[len - 2] = ' ';
else
buf[0] = '\0';
return buf;
}
@@ -154,52 +144,108 @@ char *get_last_lvm_error()
return last_error;
}
/* Return the mode a lock is currently held at (or -1 if not held) */
static int get_current_lock(char *resource)
/*
* Hash lock info helpers
*/
static struct lv_info *lookup_info(const char *resource)
{
struct lv_info *lvi;
pthread_mutex_lock(&lv_hash_lock);
lvi = dm_hash_lookup(lv_hash, resource);
pthread_mutex_unlock(&lv_hash_lock);
if (lvi) {
return lvi;
}
static void insert_info(const char *resource, struct lv_info *lvi)
{
pthread_mutex_lock(&lv_hash_lock);
dm_hash_insert(lv_hash, resource, lvi);
pthread_mutex_unlock(&lv_hash_lock);
}
static void remove_info(const char *resource)
{
pthread_mutex_lock(&lv_hash_lock);
dm_hash_remove(lv_hash, resource);
pthread_mutex_unlock(&lv_hash_lock);
}
/*
* Return the mode a lock is currently held at (or -1 if not held)
*/
static int get_current_lock(char *resource)
{
struct lv_info *lvi;
if ((lvi = lookup_info(resource)))
return lvi->lock_mode;
} else {
return -1;
}
return -1;
}
void init_lvhash()
{
/* Create hash table for keeping LV locks & status */
lv_hash = dm_hash_create(100);
pthread_mutex_init(&lv_hash_lock, NULL);
pthread_mutex_init(&lvm_lock, NULL);
}
/* Called at shutdown to tidy the lockspace */
void unlock_all()
void destroy_lvhash()
{
struct dm_hash_node *v;
struct lv_info *lvi;
char *resource;
int status;
pthread_mutex_lock(&lv_hash_lock);
dm_hash_iterate(v, lv_hash) {
struct lv_info *lvi = dm_hash_get_data(lv_hash, v);
sync_unlock(dm_hash_get_key(lv_hash, v), lvi->lock_id);
dm_hash_iterate(v, lv_hash) {
lvi = dm_hash_get_data(lv_hash, v);
resource = dm_hash_get_key(lv_hash, v);
if ((status = sync_unlock(resource, lvi->lock_id)))
DEBUGLOG("unlock_all. unlock failed(%d): %s\n",
status, strerror(errno));
free(lvi);
}
dm_hash_destroy(lv_hash);
lv_hash = NULL;
pthread_mutex_unlock(&lv_hash_lock);
}
/* Gets a real lock and keeps the info in the hash table */
int hold_lock(char *resource, int mode, int flags)
static int hold_lock(char *resource, int mode, int flags)
{
int status;
int saved_errno;
struct lv_info *lvi;
flags &= LKF_NOQUEUE; /* Only LKF_NOQUEUE is valid here */
/* Mask off invalid options */
flags &= LCKF_NOQUEUE | LCKF_CONVERT;
pthread_mutex_lock(&lv_hash_lock);
lvi = dm_hash_lookup(lv_hash, resource);
pthread_mutex_unlock(&lv_hash_lock);
lvi = lookup_info(resource);
if (lvi && lvi->lock_mode == mode) {
DEBUGLOG("hold_lock, lock mode %d already held\n", mode);
return 0;
}
/* Only allow explicit conversions */
if (lvi && !(flags & LCKF_CONVERT)) {
errno = EBUSY;
return -1;
}
if (lvi) {
/* Already exists - convert it */
status =
sync_lock(resource, mode, LKF_CONVERT | flags,
&lvi->lock_id);
sync_lock(resource, mode, flags, &lvi->lock_id);
saved_errno = errno;
if (!status)
lvi->lock_mode = mode;
@@ -215,33 +261,28 @@ int hold_lock(char *resource, int mode, int flags)
return -1;
lvi->lock_mode = mode;
status = sync_lock(resource, mode, flags, &lvi->lock_id);
status = sync_lock(resource, mode, flags & ~LCKF_CONVERT, &lvi->lock_id);
saved_errno = errno;
if (status) {
free(lvi);
DEBUGLOG("hold_lock. lock at %d failed: %s\n", mode,
strerror(errno));
} else {
pthread_mutex_lock(&lv_hash_lock);
dm_hash_insert(lv_hash, resource, lvi);
pthread_mutex_unlock(&lv_hash_lock);
}
} else
insert_info(resource, lvi);
errno = saved_errno;
}
return status;
}
/* Unlock and remove it from the hash table */
int hold_unlock(char *resource)
static int hold_unlock(char *resource)
{
struct lv_info *lvi;
int status;
int saved_errno;
pthread_mutex_lock(&lv_hash_lock);
lvi = dm_hash_lookup(lv_hash, resource);
pthread_mutex_unlock(&lv_hash_lock);
if (!lvi) {
if (!(lvi = lookup_info(resource))) {
DEBUGLOG("hold_unlock, lock not already held\n");
return 0;
}
@@ -249,9 +290,7 @@ int hold_unlock(char *resource)
status = sync_unlock(resource, lvi->lock_id);
saved_errno = errno;
if (!status) {
pthread_mutex_lock(&lv_hash_lock);
dm_hash_remove(lv_hash, resource);
pthread_mutex_unlock(&lv_hash_lock);
remove_info(resource);
free(lvi);
} else {
DEBUGLOG("hold_unlock. unlock failed(%d): %s\n", status,
@@ -279,7 +318,8 @@ static int do_activate_lv(char *resource, unsigned char lock_flags, int mode)
/* Is it already open ? */
oldmode = get_current_lock(resource);
if (oldmode == mode) {
if (oldmode == mode && (lock_flags & LCK_CLUSTER_VG)) {
DEBUGLOG("do_activate_lv, lock already held at %d\n", oldmode);
return 0; /* Nothing to do */
}
@@ -291,14 +331,18 @@ static int do_activate_lv(char *resource, unsigned char lock_flags, int mode)
return 0; /* Success, we did nothing! */
/* Do we need to activate exclusively? */
if ((activate_lv == 2) || (mode == LKM_EXMODE)) {
if ((activate_lv == 2) || (mode == LCK_EXCL)) {
exclusive = 1;
mode = LKM_EXMODE;
mode = LCK_EXCL;
}
/* Try to get the lock if it's a clustered volume group */
/*
* Try to get the lock if it's a clustered volume group.
* Use lock conversion only if requested, to prevent implicit conversion
* of exclusive lock to shared one during activation.
*/
if (lock_flags & LCK_CLUSTER_VG) {
status = hold_lock(resource, mode, LKF_NOQUEUE);
status = hold_lock(resource, mode, LCKF_NOQUEUE | (lock_flags & LCK_CONVERT ? LCKF_CONVERT:0));
if (status) {
/* Return an LVM-sensible error for this.
* Forcing EIO makes the upper level return this text
@@ -313,60 +357,68 @@ static int do_activate_lv(char *resource, unsigned char lock_flags, int mode)
}
/* If it's suspended then resume it */
if (!lv_info_by_lvid(cmd, resource, &lvi, 0, 0))
return EIO;
if (!lv_info_by_lvid(cmd, resource, 0, &lvi, 0, 0))
goto error;
if (lvi.suspended)
if (!lv_resume(cmd, resource))
return EIO;
if (lvi.suspended) {
memlock_inc(cmd);
if (!lv_resume(cmd, resource, 0)) {
memlock_dec(cmd);
goto error;
}
}
/* Now activate it */
if (!lv_activate(cmd, resource, exclusive))
return EIO;
goto error;
return 0;
error:
if (oldmode == -1 || oldmode != mode)
(void)hold_unlock(resource);
return EIO;
}
/* Resume the LV if it was active */
static int do_resume_lv(char *resource)
static int do_resume_lv(char *resource, unsigned char lock_flags)
{
int oldmode;
/* Is it open ? */
oldmode = get_current_lock(resource);
if (oldmode == -1) {
if (oldmode == -1 && (lock_flags & LCK_CLUSTER_VG)) {
DEBUGLOG("do_resume_lv, lock not already held\n");
return 0; /* We don't need to do anything */
}
if (!lv_resume_if_active(cmd, resource))
if (!lv_resume_if_active(cmd, resource, (lock_flags & LCK_ORIGIN_ONLY_MODE) ? 1 : 0))
return EIO;
return 0;
}
/* Suspend the device if active */
static int do_suspend_lv(char *resource)
static int do_suspend_lv(char *resource, unsigned char lock_flags)
{
int oldmode;
struct lvinfo lvi;
unsigned origin_only = (lock_flags & LCK_ORIGIN_ONLY_MODE) ? 1 : 0;
/* Is it open ? */
oldmode = get_current_lock(resource);
if (oldmode == -1) {
DEBUGLOG("do_suspend_lv, lock held at %d\n", oldmode);
if (oldmode == -1 && (lock_flags & LCK_CLUSTER_VG)) {
DEBUGLOG("do_suspend_lv, lock not already held\n");
return 0; /* Not active, so it's OK */
}
/* Only suspend it if it exists */
if (!lv_info_by_lvid(cmd, resource, &lvi, 0, 0))
if (!lv_info_by_lvid(cmd, resource, origin_only, &lvi, 0, 0))
return EIO;
if (lvi.exists && !lv_suspend_if_active(cmd, resource, origin_only))
return EIO;
if (lvi.exists) {
if (!lv_suspend_if_active(cmd, resource)) {
return EIO;
}
}
return 0;
}
@@ -394,54 +446,72 @@ static int do_deactivate_lv(char *resource, unsigned char lock_flags)
return 0;
}
const char *do_lock_query(char *resource)
{
int mode;
const char *type = NULL;
mode = get_current_lock(resource);
switch (mode) {
case LCK_NULL: type = "NL"; break;
case LCK_READ: type = "CR"; break;
case LCK_PREAD:type = "PR"; break;
case LCK_WRITE:type = "PW"; break;
case LCK_EXCL: type = "EX"; break;
}
DEBUGLOG("do_lock_query: resource '%s', mode %i (%s)\n", resource, mode, type ?: "?");
return type;
}
/* This is the LOCK_LV part that happens on all nodes in the cluster -
it is responsible for the interaction with device-mapper and LVM */
int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
{
int status = 0;
DEBUGLOG("do_lock_lv: resource '%s', cmd = %s, flags = %s\n",
resource, decode_locking_cmd(command), decode_flags(lock_flags));
DEBUGLOG("do_lock_lv: resource '%s', cmd = %s, flags = %s, memlock = %d\n",
resource, decode_locking_cmd(command), decode_flags(lock_flags), memlock());
pthread_mutex_lock(&lvm_lock);
if (!cmd->config_valid || config_files_changed(cmd)) {
/* Reinitialise various settings inc. logging, filters */
if (do_refresh_cache()) {
log_error("Updated config file invalid. Aborting.");
pthread_mutex_unlock(&lvm_lock);
return EINVAL;
}
}
if (lock_flags & LCK_PARTIAL_MODE)
init_partial(1);
pthread_mutex_lock(&lvm_lock);
if (lock_flags & LCK_MIRROR_NOSYNC_MODE)
init_mirror_in_sync(1);
if (!(lock_flags & LCK_DMEVENTD_MONITOR_MODE))
if (lock_flags & LCK_DMEVENTD_MONITOR_MODE)
init_dmeventd_monitor(1);
else
init_dmeventd_monitor(0);
switch (command) {
cmd->partial_activation = (lock_flags & LCK_PARTIAL_MODE) ? 1 : 0;
/* clvmd should never try to read suspended device */
init_ignore_suspended_devices(1);
switch (command & LCK_MASK) {
case LCK_LV_EXCLUSIVE:
status = do_activate_lv(resource, lock_flags, LKM_EXMODE);
status = do_activate_lv(resource, lock_flags, LCK_EXCL);
break;
case LCK_LV_SUSPEND:
status = do_suspend_lv(resource);
if (!status)
suspended++;
status = do_suspend_lv(resource, lock_flags);
break;
case LCK_UNLOCK:
case LCK_LV_RESUME: /* if active */
status = do_resume_lv(resource);
if (!status)
suspended--;
status = do_resume_lv(resource, lock_flags);
break;
case LCK_LV_ACTIVATE:
status = do_activate_lv(resource, lock_flags, LKM_CRMODE);
status = do_activate_lv(resource, lock_flags, LCK_READ);
break;
case LCK_LV_DEACTIVATE:
@@ -454,20 +524,16 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
break;
}
if (lock_flags & LCK_PARTIAL_MODE)
init_partial(0);
if (lock_flags & LCK_MIRROR_NOSYNC_MODE)
init_mirror_in_sync(0);
if (!(lock_flags & LCK_DMEVENTD_MONITOR_MODE))
init_dmeventd_monitor(DEFAULT_DMEVENTD_MONITOR);
cmd->partial_activation = 0;
/* clean the pool for another command */
dm_pool_empty(cmd->mem);
pthread_mutex_unlock(&lvm_lock);
DEBUGLOG("Command return is %d\n", status);
DEBUGLOG("Command return is %d, memlock is %d\n", status, memlock());
return status;
}
@@ -477,12 +543,14 @@ int pre_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
/* Nearly all the stuff happens cluster-wide. Apart from SUSPEND. Here we get the
lock out on this node (because we are the node modifying the metadata)
before suspending cluster-wide.
LCKF_CONVERT is used always, local node is going to modify metadata
*/
if (command == LCK_LV_SUSPEND) {
if ((command & (LCK_SCOPE_MASK | LCK_TYPE_MASK)) == LCK_LV_SUSPEND &&
(lock_flags & LCK_CLUSTER_VG)) {
DEBUGLOG("pre_lock_lv: resource '%s', cmd = %s, flags = %s\n",
resource, decode_locking_cmd(command), decode_flags(lock_flags));
if (hold_lock(resource, LKM_PWMODE, LKF_NOQUEUE))
if (hold_lock(resource, LCK_WRITE, LCKF_NOQUEUE | LCKF_CONVERT))
return errno;
}
return 0;
@@ -493,9 +561,11 @@ int post_lock_lv(unsigned char command, unsigned char lock_flags,
char *resource)
{
int status;
unsigned origin_only = (lock_flags & LCK_ORIGIN_ONLY_MODE) ? 1 : 0;
/* Opposite of above, done on resume after a metadata update */
if (command == LCK_LV_RESUME) {
if ((command & (LCK_SCOPE_MASK | LCK_TYPE_MASK)) == LCK_LV_RESUME &&
(lock_flags & LCK_CLUSTER_VG)) {
int oldmode;
DEBUGLOG
@@ -504,22 +574,20 @@ int post_lock_lv(unsigned char command, unsigned char lock_flags,
/* If the lock state is PW then restore it to what it was */
oldmode = get_current_lock(resource);
if (oldmode == LKM_PWMODE) {
if (oldmode == LCK_WRITE) {
struct lvinfo lvi;
pthread_mutex_lock(&lvm_lock);
status = lv_info_by_lvid(cmd, resource, &lvi, 0, 0);
status = lv_info_by_lvid(cmd, resource, origin_only, &lvi, 0, 0);
pthread_mutex_unlock(&lvm_lock);
if (!status)
return EIO;
if (lvi.exists) {
if (hold_lock(resource, LKM_CRMODE, 0))
if (hold_lock(resource, LCK_READ, LCKF_CONVERT))
return errno;
} else {
if (hold_unlock(resource))
return errno;
}
} else if (hold_unlock(resource))
return errno;
}
}
return 0;
@@ -537,28 +605,37 @@ int do_check_lvm1(const char *vgname)
int do_refresh_cache()
{
int ret;
DEBUGLOG("Refreshing context\n");
log_notice("Refreshing context");
ret = refresh_toolcontext(cmd);
init_full_scan_done(0);
lvmcache_label_scan(cmd, 2);
pthread_mutex_lock(&lvm_lock);
return ret==1?0:-1;
if (!refresh_toolcontext(cmd)) {
pthread_mutex_unlock(&lvm_lock);
return -1;
}
init_full_scan_done(0);
init_ignore_suspended_devices(1);
lvmcache_label_scan(cmd, 2);
dm_pool_empty(cmd->mem);
pthread_mutex_unlock(&lvm_lock);
return 0;
}
/* Only called at gulm startup. Drop any leftover VG or P_orphan locks
that might be hanging around if we died for any reason
*/
static void drop_vg_locks()
static void drop_vg_locks(void)
{
char vg[128];
char line[255];
FILE *vgs =
popen
("lvm pvs --config 'log{command_names=0 prefix=\"\"}' --nolocking --noheadings -o vg_name", "r");
(LVM_PATH " pvs --config 'log{command_names=0 prefix=\"\"}' --nolocking --noheadings -o vg_name", "r");
sync_unlock("P_" VG_ORPHANS, LCK_EXCL);
sync_unlock("P_" VG_GLOBAL, LCK_EXCL);
@@ -589,29 +666,85 @@ static void drop_vg_locks()
}
/*
* Drop lvmcache metadata
* Handle VG lock - drop metadata or update lvmcache state
*/
void drop_metadata(const char *vgname)
void do_lock_vg(unsigned char command, unsigned char lock_flags, char *resource)
{
DEBUGLOG("Dropping metadata for VG %s\n", vgname);
uint32_t lock_cmd = command;
char *vgname = resource + 2;
DEBUGLOG("do_lock_vg: resource '%s', cmd = %s, flags = %s, memlock = %d\n",
resource, decode_locking_cmd(command), decode_flags(lock_flags), memlock());
/* P_#global causes a full cache refresh */
if (!strcmp(resource, "P_" VG_GLOBAL)) {
do_refresh_cache();
return;
}
lock_cmd &= (LCK_SCOPE_MASK | LCK_TYPE_MASK | LCK_HOLD);
/*
* Check if LCK_CACHE should be set. All P_ locks except # are cache related.
*/
if (strncmp(resource, "P_#", 3) && !strncmp(resource, "P_", 2))
lock_cmd |= LCK_CACHE;
pthread_mutex_lock(&lvm_lock);
lvmcache_drop_metadata(vgname);
switch (lock_cmd) {
case LCK_VG_COMMIT:
DEBUGLOG("vg_commit notification for VG %s\n", vgname);
lvmcache_commit_metadata(vgname);
break;
case LCK_VG_REVERT:
DEBUGLOG("vg_revert notification for VG %s\n", vgname);
lvmcache_drop_metadata(vgname, 1);
break;
case LCK_VG_DROP_CACHE:
default:
DEBUGLOG("Invalidating cached metadata for VG %s\n", vgname);
lvmcache_drop_metadata(vgname, 0);
}
pthread_mutex_unlock(&lvm_lock);
}
/*
* Compare the uuid with the list of exclusive locks that clvmd
* held before it was restarted, so we can get the right kind
* of lock now we are restarting.
*/
static int was_ex_lock(char *uuid, char **argv)
{
int optnum = 0;
char *opt = argv[optnum];
while (opt) {
if (strcmp(opt, "-E") == 0) {
opt = argv[++optnum];
if (opt && (strcmp(opt, uuid) == 0)) {
DEBUGLOG("Lock %s is exclusive\n", uuid);
return 1;
}
}
opt = argv[++optnum];
}
return 0;
}
/*
* Ideally, clvmd should be started before any LVs are active
* but this may not be the case...
* I suppose this also comes in handy if clvmd crashes, not that it would!
*/
static void *get_initial_state()
static void *get_initial_state(char **argv)
{
int lock_mode;
char lv[64], vg[64], flags[25], vg_flags[25];
char uuid[65];
char line[255];
FILE *lvs =
popen
("lvm lvs --config 'log{command_names=0 prefix=\"\"}' --nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr,vg_attr",
(LVM_PATH " lvs --config 'log{command_names=0 prefix=\"\"}' --nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr,vg_attr",
"r");
if (!lvs)
@@ -641,8 +774,15 @@ static void *get_initial_state()
memcpy(&uuid[58], &lv[32], 6);
uuid[64] = '\0';
lock_mode = LCK_READ;
/* Look for this lock in the list of EX locks
we were passed on the command-line */
if (was_ex_lock(uuid, argv))
lock_mode = LCK_EXCL;
DEBUGLOG("getting initial lock for %s\n", uuid);
hold_lock(uuid, LKM_CRMODE, LKF_NOQUEUE);
hold_lock(uuid, lock_mode, LCKF_NOQUEUE);
}
}
}
@@ -651,7 +791,7 @@ static void *get_initial_state()
return NULL;
}
static void lvm2_log_fn(int level, const char *file, int line,
static void lvm2_log_fn(int level, const char *file, int line, int dm_errno,
const char *message)
{
@@ -660,7 +800,7 @@ static void lvm2_log_fn(int level, const char *file, int line,
We need to NULL the function ptr otherwise it will just call
back into here! */
init_log_fn(NULL);
print_log(level, file, line, "%s", message);
print_log(level, file, line, dm_errno, "%s", message);
init_log_fn(lvm2_log_fn);
/*
@@ -675,7 +815,7 @@ static void lvm2_log_fn(int level, const char *file, int line,
}
/* This checks some basic cluster-LVM configuration stuff */
static void check_config()
static void check_config(void)
{
int locking_type;
@@ -698,61 +838,94 @@ static void check_config()
log_error("locking_type not set correctly in lvm.conf, cluster operations will not work.");
}
void init_lvhash()
{
/* Create hash table for keeping LV locks & status */
lv_hash = dm_hash_create(100);
pthread_mutex_init(&lv_hash_lock, NULL);
pthread_mutex_init(&lvm_lock, NULL);
}
/* Backups up the LVM metadata if it's changed */
void lvm_do_backup(const char *vgname)
{
struct volume_group * vg;
int consistent = 0;
DEBUGLOG("Triggering backup of VG metadata for %s. suspended=%d\n", vgname, suspended);
DEBUGLOG("Triggering backup of VG metadata for %s.\n", vgname);
vg = vg_read(cmd, vgname, NULL /*vgid*/, &consistent);
if (vg) {
if (consistent)
check_current_backup(vg);
}
else {
pthread_mutex_lock(&lvm_lock);
vg = vg_read_internal(cmd, vgname, NULL /*vgid*/, &consistent);
if (vg && consistent)
check_current_backup(vg);
else
log_error("Error backing up metadata, can't find VG for group %s", vgname);
}
vg_release(vg);
dm_pool_empty(cmd->mem);
pthread_mutex_unlock(&lvm_lock);
}
struct dm_hash_node *get_next_excl_lock(struct dm_hash_node *v, char **name)
{
struct lv_info *lvi;
*name = NULL;
if (!v)
v = dm_hash_get_first(lv_hash);
do {
if (v) {
lvi = dm_hash_get_data(lv_hash, v);
DEBUGLOG("Looking for EX locks. found %x mode %d\n", lvi->lock_id, lvi->lock_mode);
if (lvi->lock_mode == LCK_EXCL) {
*name = dm_hash_get_key(lv_hash, v);
}
v = dm_hash_get_next(lv_hash, v);
}
} while (v && !*name);
if (*name)
DEBUGLOG("returning EXclusive UUID %s\n", *name);
return v;
}
/* Called to initialise the LVM context of the daemon */
int init_lvm(int using_gulm)
int init_clvm(int using_gulm, char **argv)
{
if (!(cmd = create_toolcontext(NULL, 0, 1))) {
if (!(cmd = create_toolcontext(1, NULL))) {
log_error("Failed to allocate command context");
return 0;
}
if (stored_errno()) {
destroy_toolcontext(cmd);
return 0;
}
/* Use LOG_DAEMON for syslog messages instead of LOG_USER */
init_syslog(LOG_DAEMON);
openlog("clvmd", LOG_PID, LOG_DAEMON);
init_debug(cmd->current_settings.debug);
init_verbose(cmd->current_settings.verbose + VERBOSE_BASE_LEVEL);
set_activation(cmd->current_settings.activation);
archive_enable(cmd, cmd->current_settings.archive);
backup_enable(cmd, cmd->current_settings.backup);
cmd->cmd_line = (char *)"clvmd";
cmd->cmd_line = "clvmd";
/* Check lvm.conf is setup for cluster-LVM */
check_config();
init_ignore_suspended_devices(1);
/* Remove any non-LV locks that may have been left around */
if (using_gulm)
drop_vg_locks();
get_initial_state();
get_initial_state(argv);
/* Trap log messages so we can pass them back to the user */
init_log_fn(lvm2_log_fn);
memlock_inc_daemon(cmd);
return 1;
}
void destroy_lvm(void)
{
if (cmd) {
memlock_dec_daemon(cmd);
destroy_toolcontext(cmd);
}
cmd = NULL;
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -22,17 +22,19 @@ extern int pre_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
char *resource);
extern int do_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
char *resource);
extern const char *do_lock_query(char *resource);
extern int post_lock_lv(unsigned char lock_cmd, unsigned char lock_flags,
char *resource);
extern int do_check_lvm1(const char *vgname);
extern int do_refresh_cache(void);
extern int init_lvm(int using_gulm);
extern int init_clvm(int using_gulm, char **argv);
extern void destroy_lvm(void);
extern void init_lvhash(void);
extern void destroy_lvhash(void);
extern void lvm_do_backup(const char *vgname);
extern int hold_unlock(char *resource);
extern int hold_lock(char *resource, int mode, int flags);
extern void unlock_all(void);
extern char *get_last_lvm_error(void);
extern void drop_metadata(const char *vgname);
extern void do_lock_vg(unsigned char command, unsigned char lock_flags,
char *resource);
extern struct dm_hash_node *get_next_excl_lock(struct dm_hash_node *v, char **name);
#endif

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -14,22 +14,17 @@
*/
/*
* Tell all clvmds in a cluster to refresh their toolcontext
*
* Send a command to a running clvmd from the command-line
*/
#include "clvmd-common.h"
#include "clvm.h"
#include "refresh_clvmd.h"
#include <stddef.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <unistd.h>
#include <libdevmapper.h>
#include <stdint.h>
#include <stdio.h>
#include <limits.h>
#include "clvm.h"
#include "refresh_clvmd.h"
typedef struct lvm_response {
char node[255];
@@ -80,7 +75,7 @@ static int _open_local_sock(void)
}
/* Send a request and return the status */
static int _send_request(const char *inbuf, int inlen, char **retbuf)
static int _send_request(const char *inbuf, int inlen, char **retbuf, int no_response)
{
char outbuf[PIPE_BUF];
struct clvm_header *outheader = (struct clvm_header *) outbuf;
@@ -97,6 +92,8 @@ static int _send_request(const char *inbuf, int inlen, char **retbuf)
fprintf(stderr, "Error writing data to clvmd: %s", strerror(errno));
return 0;
}
if (no_response)
return 1;
/* Get the response */
reread:
@@ -181,7 +178,7 @@ static void _build_header(struct clvm_header *head, int cmd, const char *node,
* Send a message to a(or all) node(s) in the cluster and wait for replies
*/
static int _cluster_request(char cmd, const char *node, void *data, int len,
lvm_response_t ** response, int *num)
lvm_response_t ** response, int *num, int no_response)
{
char outbuf[sizeof(struct clvm_header) + len + strlen(node) + 1];
char *inptr;
@@ -204,8 +201,8 @@ static int _cluster_request(char cmd, const char *node, void *data, int len,
memcpy(head->node + strlen(head->node) + 1, data, len);
status = _send_request(outbuf, sizeof(struct clvm_header) +
strlen(head->node) + len, &retbuf);
if (!status)
strlen(head->node) + len, &retbuf, no_response);
if (!status || no_response)
goto out;
/* Count the number of responses we got */
@@ -284,16 +281,16 @@ static int _cluster_free_request(lvm_response_t * response, int num)
return 1;
}
int refresh_clvmd()
int refresh_clvmd(int all_nodes)
{
int num_responses;
char args[1]; // No args really.
lvm_response_t *response;
lvm_response_t *response = NULL;
int saved_errno;
int status;
int i;
status = _cluster_request(CLVMD_CMD_REFRESH, "*", args, 0, &response, &num_responses);
status = _cluster_request(CLVMD_CMD_REFRESH, all_nodes?"*":".", args, 0, &response, &num_responses, 0);
/* If any nodes were down then display them and return an error */
for (i = 0; i < num_responses; i++) {
@@ -320,12 +317,31 @@ int refresh_clvmd()
return status;
}
int restart_clvmd(int all_nodes)
{
int dummy, status;
status = _cluster_request(CLVMD_CMD_RESTART, all_nodes?"*":".", NULL, 0, NULL, &dummy, 1);
/*
* FIXME: we cannot receive response, clvmd re-exec before it.
* but also should not close socket too early (the whole rq is dropped then).
* FIXME: This should be handled this way:
* - client waits for RESTART ack (and socket close)
* - server restarts
* - client checks that server is ready again (VERSION command?)
*/
usleep(500000);
return status;
}
int debug_clvmd(int level, int clusterwide)
{
int num_responses;
char args[1];
const char *nodes;
lvm_response_t *response;
lvm_response_t *response = NULL;
int saved_errno;
int status;
int i;
@@ -336,7 +352,7 @@ int debug_clvmd(int level, int clusterwide)
else
nodes = ".";
status = _cluster_request(CLVMD_CMD_SET_DEBUG, nodes, args, 1, &response, &num_responses);
status = _cluster_request(CLVMD_CMD_SET_DEBUG, nodes, args, 1, &response, &num_responses, 0);
/* If any nodes were down then display them and return an error */
for (i = 0; i < num_responses; i++) {

View File

@@ -13,6 +13,7 @@
*/
int refresh_clvmd(void);
int refresh_clvmd(int all_nodes);
int restart_clvmd(int all_nodes);
int debug_clvmd(int level, int clusterwide);

View File

@@ -1,40 +1,41 @@
/******************************************************************************
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 2002-2003 All rights reserved.
** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
**
*******************************************************************************
******************************************************************************/
/*
* Copyright (C) 2002-2003 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* This provides the inter-clvmd communications for a system without CMAN.
There is a listening TCP socket which accepts new connections in the
normal way.
It can also make outgoing connnections to the other clvmd nodes.
*/
/*
* This provides the inter-clvmd communications for a system without CMAN.
* There is a listening TCP socket which accepts new connections in the
* normal way.
* It can also make outgoing connnections to the other clvmd nodes.
*/
#include "clvmd-common.h"
#include <pthread.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <string.h>
#include <stddef.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <syslog.h>
#include <netdb.h>
#include <assert.h>
#include <libdevmapper.h>
#include "clvm.h"
#include "clvmd-comms.h"

View File

@@ -0,0 +1,38 @@
#
# Copyright (C) 2009-2010 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
CPG_LIBS = @CPG_LIBS@
CPG_CFLAGS = @CPG_CFLAGS@
SACKPT_LIBS = @SACKPT_LIBS@
SACKPT_CFLAGS = @SACKPT_CFLAGS@
SOURCES = clogd.c cluster.c compat.c functions.c link_mon.c local.c logging.c
TARGETS = cmirrord
include $(top_builddir)/make.tmpl
LIBS += -ldevmapper
LMLIBS += $(CPG_LIBS) $(SACKPT_LIBS)
CFLAGS += $(CPG_CFLAGS) $(SACKPT_CFLAGS)
cmirrord: $(OBJECTS) $(top_builddir)/lib/liblvm-internal.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) \
$(LVMLIBS) $(LMLIBS) $(LIBS)
install: $(TARGETS)
$(INSTALL_PROGRAM) -D cmirrord $(usrsbindir)/cmirrord

232
daemons/cmirrord/clogd.c Normal file
View File

@@ -0,0 +1,232 @@
/*
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "logging.h"
#include "common.h"
#include "functions.h"
#include "link_mon.h"
#include "local.h"
#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
static volatile sig_atomic_t exit_now = 0;
/* FIXME Review signal handling. Should be volatile sig_atomic_t */
static sigset_t signal_mask;
static volatile sig_atomic_t signal_received;
static void process_signals(void);
static void daemonize(void);
static void init_all(void);
static void cleanup_all(void);
int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
{
daemonize();
init_all();
/* Parent can now exit, we're ready to handle requests */
kill(getppid(), SIGTERM);
LOG_PRINT("Starting cmirrord:");
LOG_PRINT(" Built: "__DATE__" "__TIME__"\n");
LOG_DBG(" Compiled with debugging.");
while (!exit_now) {
links_monitor();
links_issue_callbacks();
process_signals();
}
exit(EXIT_SUCCESS);
}
/*
* parent_exit_handler: exit the parent
* @sig: the signal
*
*/
static void parent_exit_handler(int sig __attribute__((unused)))
{
exit_now = 1;
}
static void sig_handler(int sig)
{
/* FIXME Races - don't touch signal_mask here. */
sigaddset(&signal_mask, sig);
signal_received = 1;
}
static void process_signal(int sig){
int r = 0;
switch(sig) {
case SIGINT:
case SIGQUIT:
case SIGTERM:
case SIGHUP:
r += log_status();
break;
case SIGUSR1:
case SIGUSR2:
log_debug();
/*local_debug();*/
cluster_debug();
return;
default:
LOG_PRINT("Unknown signal received... ignoring");
return;
}
if (!r) {
LOG_DBG("No current cluster logs... safe to exit.");
cleanup_all();
exit(EXIT_SUCCESS);
}
LOG_ERROR("Cluster logs exist. Refusing to exit.");
}
static void process_signals(void)
{
int x;
if (!signal_received)
return;
signal_received = 0;
for (x = 1; x < _NSIG; x++) {
if (sigismember(&signal_mask, x)) {
sigdelset(&signal_mask, x);
process_signal(x);
}
}
}
static void remove_lockfile(void)
{
unlink(CMIRRORD_PIDFILE);
}
/*
* daemonize
*
* Performs the steps necessary to become a daemon.
*/
static void daemonize(void)
{
int pid;
int status;
signal(SIGTERM, &parent_exit_handler);
pid = fork();
if (pid < 0) {
LOG_ERROR("Unable to fork()");
exit(EXIT_FAILURE);
}
if (pid) {
/* Parent waits here for child to get going */
while (!waitpid(pid, &status, WNOHANG) && !exit_now);
if (exit_now)
exit(EXIT_SUCCESS);
switch (WEXITSTATUS(status)) {
case EXIT_LOCKFILE:
LOG_ERROR("Failed to create lockfile");
LOG_ERROR("Process already running?");
break;
case EXIT_KERNEL_SOCKET:
LOG_ERROR("Unable to create netlink socket");
break;
case EXIT_KERNEL_BIND:
LOG_ERROR("Unable to bind to netlink socket");
break;
case EXIT_KERNEL_SETSOCKOPT:
LOG_ERROR("Unable to setsockopt on netlink socket");
break;
case EXIT_CLUSTER_CKPT_INIT:
LOG_ERROR("Unable to initialize checkpoint service");
LOG_ERROR("Has the cluster infrastructure been started?");
break;
case EXIT_FAILURE:
LOG_ERROR("Failed to start: Generic error");
break;
default:
LOG_ERROR("Failed to start: Unknown error");
break;
}
exit(EXIT_FAILURE);
}
setsid();
chdir("/");
umask(0);
close(0); close(1); close(2);
open("/dev/null", O_RDONLY); /* reopen stdin */
open("/dev/null", O_WRONLY); /* reopen stdout */
open("/dev/null", O_WRONLY); /* reopen stderr */
LOG_OPEN("cmirrord", LOG_PID, LOG_DAEMON);
if (dm_create_lockfile(CMIRRORD_PIDFILE) == 0)
exit(EXIT_LOCKFILE);
atexit(remove_lockfile);
/* FIXME Replace with sigaction. (deprecated) */
signal(SIGINT, &sig_handler);
signal(SIGQUIT, &sig_handler);
signal(SIGTERM, &sig_handler);
signal(SIGHUP, &sig_handler);
signal(SIGPIPE, SIG_IGN);
signal(SIGUSR1, &sig_handler);
signal(SIGUSR2, &sig_handler);
sigemptyset(&signal_mask);
signal_received = 0;
}
/*
* init_all
*
* Initialize modules. Exit on failure.
*/
static void init_all(void)
{
int r;
if ((r = init_local()) ||
(r = init_cluster())) {
exit(r);
}
}
/*
* cleanup_all
*
* Clean up before exiting
*/
static void cleanup_all(void)
{
cleanup_local();
cleanup_cluster();
}

1661
daemons/cmirrord/cluster.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,76 @@
/*
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* 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
*/
#ifndef _LVM_CLOG_CLUSTER_H
#define _LVM_CLOG_CLUSTER_H
#include "dm-log-userspace.h"
#include "libdevmapper.h"
#define DM_ULOG_RESPONSE 0x1000U /* in last byte of 32-bit value */
#define DM_ULOG_CHECKPOINT_READY 21
#define DM_ULOG_MEMBER_JOIN 22
/*
* There is other information in addition to what can
* be found in the dm_ulog_request structure that we
* need for processing. 'clog_request' is the wrapping
* structure we use to make the additional fields
* available.
*/
struct clog_request {
/*
* If we don't use a union, the structure size will
* vary between 32-bit and 64-bit machines. So, we
* pack two 64-bit version numbers in there to force
* the size of the structure to be the same.
*
* The two version numbers also help us with endian
* issues. The first is always little endian, while
* the second is in native format of the sending
* machine. If the two are equal, there is no need
* to do endian conversions.
*/
union {
uint64_t version[2]; /* LE version and native version */
struct dm_list list;
} u;
/*
* 'originator' is the machine from which the requests
* was made.
*/
uint32_t originator;
/*
* 'pit_server' is the "point-in-time" server for the
* request. (I.e. The machine that was the server at
* the time the request was issued - only important during
* startup.
*/
uint32_t pit_server;
/*
* The request from the kernel that is being processed
*/
struct dm_ulog_request u_rq;
};
int init_cluster(void);
void cleanup_cluster(void);
void cluster_debug(void);
int create_cluster_cpg(char *uuid, uint64_t luid);
int destroy_cluster_cpg(char *uuid);
int cluster_send(struct clog_request *rq);
#endif /* _LVM_CLOG_CLUSTER_H */

33
daemons/cmirrord/common.h Normal file
View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* 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
*/
#ifndef _LVM_CLOG_COMMON_H
#define _LVM_CLOG_COMMON_H
/*
* If there are problems when forking off to become a daemon,
* the child will exist with one of these codes. This allows
* the parent to know the reason for the failure and print it
* to the launching terminal.
*
* #define EXIT_SUCCESS 0 (from stdlib.h)
* #define EXIT_FAILURE 1 (from stdlib.h)
*/
#define EXIT_LOCKFILE 2
#define EXIT_KERNEL_SOCKET 3 /* Failed netlink socket create */
#define EXIT_KERNEL_BIND 4
#define EXIT_KERNEL_SETSOCKOPT 5
#define EXIT_CLUSTER_CKPT_INIT 6 /* Failed to init checkpoint */
#define EXIT_QUEUE_NOMEM 7
#define DM_ULOG_REQUEST_SIZE 1024
#endif /* _LVM_CLOG_COMMON_H */

210
daemons/cmirrord/compat.c Normal file
View File

@@ -0,0 +1,210 @@
/*
* Copyright (C) 2010 Red Hat, Inc. All rights reserved.
*
* 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.
*/
#include "logging.h"
#include "cluster.h"
#include "compat.h"
#include "xlate.h"
#include <errno.h>
/*
* Older versions of the log daemon communicate with different
* versions of the inter-machine communication structure, which
* varies in size and fields. The older versions append the
* standard upstream version of the structure to every request.
* COMPAT_OFFSET is where the upstream structure starts.
*/
#define COMPAT_OFFSET 256
static void v5_data_endian_switch(struct clog_request *rq, int to_network __attribute__((unused)))
{
int i, end;
int64_t *pi64;
uint64_t *pu64;
uint32_t rq_type = rq->u_rq.request_type & ~DM_ULOG_RESPONSE;
if (rq->u_rq.request_type & DM_ULOG_RESPONSE) {
switch (rq_type) {
case DM_ULOG_CTR:
case DM_ULOG_DTR:
LOG_ERROR("Invalid response type in endian switch");
exit(EXIT_FAILURE);
case DM_ULOG_PRESUSPEND:
case DM_ULOG_POSTSUSPEND:
case DM_ULOG_RESUME:
case DM_ULOG_FLUSH:
case DM_ULOG_MARK_REGION:
case DM_ULOG_CLEAR_REGION:
case DM_ULOG_SET_REGION_SYNC:
case DM_ULOG_CHECKPOINT_READY:
case DM_ULOG_MEMBER_JOIN:
case DM_ULOG_STATUS_INFO:
case DM_ULOG_STATUS_TABLE:
/* No outbound data */
break;
case DM_ULOG_GET_REGION_SIZE:
case DM_ULOG_GET_SYNC_COUNT:
pu64 = (uint64_t *)rq->u_rq.data;
*pu64 = xlate64(*pu64);
break;
case DM_ULOG_IS_CLEAN:
case DM_ULOG_IN_SYNC:
pi64 = (int64_t *)rq->u_rq.data;
*pi64 = xlate64(*pi64);
break;
case DM_ULOG_GET_RESYNC_WORK:
case DM_ULOG_IS_REMOTE_RECOVERING:
pi64 = (int64_t *)rq->u_rq.data;
pu64 = ((uint64_t *)rq->u_rq.data) + 1;
*pi64 = xlate64(*pi64);
*pu64 = xlate64(*pu64);
break;
default:
LOG_ERROR("Unknown request type, %u", rq_type);
return;
}
} else {
switch (rq_type) {
case DM_ULOG_CTR:
case DM_ULOG_DTR:
LOG_ERROR("Invalid request type in endian switch");
exit(EXIT_FAILURE);
case DM_ULOG_PRESUSPEND:
case DM_ULOG_POSTSUSPEND:
case DM_ULOG_RESUME:
case DM_ULOG_GET_REGION_SIZE:
case DM_ULOG_FLUSH:
case DM_ULOG_GET_RESYNC_WORK:
case DM_ULOG_GET_SYNC_COUNT:
case DM_ULOG_STATUS_INFO:
case DM_ULOG_STATUS_TABLE:
case DM_ULOG_CHECKPOINT_READY:
case DM_ULOG_MEMBER_JOIN:
/* No incoming data */
break;
case DM_ULOG_IS_CLEAN:
case DM_ULOG_IN_SYNC:
case DM_ULOG_IS_REMOTE_RECOVERING:
pu64 = (uint64_t *)rq->u_rq.data;
*pu64 = xlate64(*pu64);
break;
case DM_ULOG_MARK_REGION:
case DM_ULOG_CLEAR_REGION:
end = rq->u_rq.data_size/sizeof(uint64_t);
pu64 = (uint64_t *)rq->u_rq.data;
for (i = 0; i < end; i++)
pu64[i] = xlate64(pu64[i]);
break;
case DM_ULOG_SET_REGION_SYNC:
pu64 = (uint64_t *)rq->u_rq.data;
pi64 = ((int64_t *)rq->u_rq.data) + 1;
*pu64 = xlate64(*pu64);
*pi64 = xlate64(*pi64);
break;
default:
LOG_ERROR("Unknown request type, %u", rq_type);
exit(EXIT_FAILURE);
}
}
}
static int v5_endian_to_network(struct clog_request *rq)
{
int size;
struct dm_ulog_request *u_rq = &rq->u_rq;
size = sizeof(*rq) + u_rq->data_size;
u_rq->error = xlate32(u_rq->error);
u_rq->seq = xlate32(u_rq->seq);
u_rq->request_type = xlate32(u_rq->request_type);
u_rq->data_size = xlate64(u_rq->data_size);
rq->originator = xlate32(rq->originator);
v5_data_endian_switch(rq, 1);
return size;
}
int clog_request_to_network(struct clog_request *rq)
{
int r;
/* FIXME: Remove this safety check */
if (rq->u.version[0] != xlate64(rq->u.version[1])) {
LOG_ERROR("Programmer error: version[0] must be LE");
exit(EXIT_FAILURE);
}
/*
* Are we already running in the endian mode we send
* over the wire?
*/
if (rq->u.version[0] == rq->u.version[1])
return 0;
r = v5_endian_to_network(rq);
if (r < 0)
return r;
return 0;
}
static int v5_endian_from_network(struct clog_request *rq)
{
int size;
struct dm_ulog_request *u_rq = &rq->u_rq;
u_rq->error = xlate32(u_rq->error);
u_rq->seq = xlate32(u_rq->seq);
u_rq->request_type = xlate32(u_rq->request_type);
u_rq->data_size = xlate64(u_rq->data_size);
rq->originator = xlate32(rq->originator);
size = sizeof(*rq) + u_rq->data_size;
v5_data_endian_switch(rq, 0);
return size;
}
int clog_request_from_network(void *data, size_t data_len)
{
uint64_t *vp = data;
uint64_t version = xlate64(vp[0]);
uint64_t unconverted_version = vp[1];
struct clog_request *rq = data;
switch (version) {
case 5: /* Upstream */
if (version == unconverted_version)
return 0;
break;
case 4: /* RHEL 5.[45] */
case 3: /* RHEL 5.3 */
case 2: /* RHEL 5.2 */
/* FIXME: still need to account for payload */
if (data_len < (COMPAT_OFFSET + sizeof(*rq)))
return -ENOSPC;
rq = (struct clog_request *)((char *)data + COMPAT_OFFSET);
break;
default:
LOG_ERROR("Unable to process cluster message: "
"Incompatible version");
return -EINVAL;
}
v5_endian_from_network(rq);
return 0;
}

25
daemons/cmirrord/compat.h Normal file
View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) 2010 Red Hat, Inc. All rights reserved.
*
* 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.
*/
#ifndef _LVM_CLOG_COMPAT_H
#define _LVM_CLOG_COMPAT_H
/*
* The intermachine communication structure version are:
* 0: Unused
* 1: Never in the wild
* 2: RHEL 5.2
* 3: RHEL 5.3
* 4: RHEL 5.4, RHEL 5.5
* 5: RHEL 6, Current Upstream Format
*/
#define CLOG_TFR_VERSION 5
int clog_request_to_network(struct clog_request *rq);
int clog_request_from_network(void *data, size_t data_len);
#endif /* _LVM_CLOG_COMPAT_H */

1938
daemons/cmirrord/functions.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* 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
*/
#ifndef _LVM_CLOG_FUNCTIONS_H
#define _LVM_CLOG_FUNCTIONS_H
#include "dm-log-userspace.h"
#include "cluster.h"
#define LOG_RESUMED 1
#define LOG_SUSPENDED 2
int local_resume(struct dm_ulog_request *rq);
int cluster_postsuspend(char *, uint64_t);
int do_request(struct clog_request *rq, int server);
int push_state(const char *uuid, uint64_t luid,
const char *which, char **buf, uint32_t debug_who);
int pull_state(const char *uuid, uint64_t luid,
const char *which, char *buf, int size);
int log_get_state(struct dm_ulog_request *rq);
int log_status(void);
void log_debug(void);
#endif /* _LVM_CLOG_FUNCTIONS_H */

151
daemons/cmirrord/link_mon.c Normal file
View File

@@ -0,0 +1,151 @@
/*
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* 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 "logging.h"
#include "link_mon.h"
#include <errno.h>
#include <poll.h>
#include <stdlib.h>
struct link_callback {
int fd;
const char *name;
void *data;
int (*callback)(void *data);
struct link_callback *next;
};
static unsigned used_pfds = 0;
static unsigned free_pfds = 0;
static struct pollfd *pfds = NULL;
static struct link_callback *callbacks = NULL;
int links_register(int fd, const char *name, int (*callback)(void *data), void *data)
{
unsigned i;
struct link_callback *lc;
for (i = 0; i < used_pfds; i++) {
if (fd == pfds[i].fd) {
LOG_ERROR("links_register: Duplicate file descriptor");
return -EINVAL;
}
}
lc = malloc(sizeof(*lc));
if (!lc)
return -ENOMEM;
lc->fd = fd;
lc->name = name;
lc->data = data;
lc->callback = callback;
if (!free_pfds) {
struct pollfd *tmp;
tmp = realloc(pfds, sizeof(struct pollfd) * ((used_pfds*2) + 1));
if (!tmp) {
free(lc);
return -ENOMEM;
}
pfds = tmp;
free_pfds = used_pfds + 1;
}
free_pfds--;
pfds[used_pfds].fd = fd;
pfds[used_pfds].events = POLLIN;
pfds[used_pfds].revents = 0;
used_pfds++;
lc->next = callbacks;
callbacks = lc;
LOG_DBG("Adding %s/%d", lc->name, lc->fd);
LOG_DBG(" used_pfds = %u, free_pfds = %u",
used_pfds, free_pfds);
return 0;
}
int links_unregister(int fd)
{
unsigned i;
struct link_callback *p, *c;
for (i = 0; i < used_pfds; i++)
if (fd == pfds[i].fd) {
/* entire struct is copied (overwritten) */
pfds[i] = pfds[used_pfds - 1];
used_pfds--;
free_pfds++;
}
for (p = NULL, c = callbacks; c; p = c, c = c->next)
if (fd == c->fd) {
LOG_DBG("Freeing up %s/%d", c->name, c->fd);
LOG_DBG(" used_pfds = %u, free_pfds = %u",
used_pfds, free_pfds);
if (p)
p->next = c->next;
else
callbacks = c->next;
free(c);
break;
}
return 0;
}
int links_monitor(void)
{
unsigned i;
int r;
for (i = 0; i < used_pfds; i++) {
pfds[i].revents = 0;
}
r = poll(pfds, used_pfds, -1);
if (r <= 0)
return r;
r = 0;
/* FIXME: handle POLLHUP */
for (i = 0; i < used_pfds; i++)
if (pfds[i].revents & POLLIN) {
LOG_DBG("Data ready on %d", pfds[i].fd);
/* FIXME: Add this back return 1;*/
r++;
}
return r;
}
int links_issue_callbacks(void)
{
unsigned i;
struct link_callback *lc;
for (i = 0; i < used_pfds; i++)
if (pfds[i].revents & POLLIN)
for (lc = callbacks; lc; lc = lc->next)
if (pfds[i].fd == lc->fd) {
LOG_DBG("Issuing callback on %s/%d",
lc->name, lc->fd);
lc->callback(lc->data);
break;
}
return 0;
}

View File

@@ -0,0 +1,20 @@
/*
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* 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
*/
#ifndef _LVM_CLOG_LINK_MON_H
#define _LVM_CLOG_LINK_MON_H
int links_register(int fd, const char *name, int (*callback)(void *data), void *data);
int links_unregister(int fd);
int links_monitor(void);
int links_issue_callbacks(void);
#endif /* _LVM_CLOG_LINK_MON_H */

416
daemons/cmirrord/local.c Normal file
View File

@@ -0,0 +1,416 @@
/*
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* 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 "logging.h"
#include "common.h"
#include "functions.h"
#include "link_mon.h"
#include "local.h"
#include <errno.h>
#include <sys/socket.h>
#include <linux/connector.h>
#include <linux/netlink.h>
#include <unistd.h>
#ifndef CN_IDX_DM
/* Kernel 2.6.31 is required to run this code */
#define CN_IDX_DM 0x7 /* Device Mapper */
#define CN_VAL_DM_USERSPACE_LOG 0x1
#endif
static int cn_fd; /* Connector (netlink) socket fd */
static char recv_buf[2048];
static char send_buf[2048];
/* FIXME: merge this function with kernel_send_helper */
static int kernel_ack(uint32_t seq, int error)
{
int r;
struct nlmsghdr *nlh = (struct nlmsghdr *)send_buf;
struct cn_msg *msg = NLMSG_DATA(nlh);
if (error < 0) {
LOG_ERROR("Programmer error: error codes must be positive");
return -EINVAL;
}
memset(send_buf, 0, sizeof(send_buf));
nlh->nlmsg_seq = 0;
nlh->nlmsg_pid = getpid();
nlh->nlmsg_type = NLMSG_DONE;
nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct cn_msg));
nlh->nlmsg_flags = 0;
msg->len = 0;
msg->id.idx = CN_IDX_DM;
msg->id.val = CN_VAL_DM_USERSPACE_LOG;
msg->seq = seq;
msg->ack = error;
r = send(cn_fd, nlh, NLMSG_LENGTH(sizeof(struct cn_msg)), 0);
/* FIXME: do better error processing */
if (r <= 0)
return -EBADE;
return 0;
}
/*
* kernel_recv
* @rq: the newly allocated request from kernel
*
* Read requests from the kernel and allocate space for the new request.
* If there is no request from the kernel, *rq is NULL.
*
* This function is not thread safe due to returned stack pointer. In fact,
* the returned pointer must not be in-use when this function is called again.
*
* Returns: 0 on success, -EXXX on error
*/
static int kernel_recv(struct clog_request **rq)
{
int r = 0;
ssize_t len;
char *foo;
struct cn_msg *msg;
struct dm_ulog_request *u_rq;
struct nlmsghdr *nlmsg_h;
*rq = NULL;
memset(recv_buf, 0, sizeof(recv_buf));
len = recv(cn_fd, recv_buf, sizeof(recv_buf), 0);
if (len < 0) {
LOG_ERROR("Failed to recv message from kernel");
r = -errno;
goto fail;
}
nlmsg_h = (struct nlmsghdr *)recv_buf;
switch (nlmsg_h->nlmsg_type) {
case NLMSG_ERROR:
LOG_ERROR("Unable to recv message from kernel: NLMSG_ERROR");
r = -EBADE;
goto fail;
case NLMSG_DONE:
msg = (struct cn_msg *)NLMSG_DATA((struct nlmsghdr *)recv_buf);
len -= (ssize_t)sizeof(struct nlmsghdr);
if (len < (ssize_t)sizeof(struct cn_msg)) {
LOG_ERROR("Incomplete request from kernel received");
r = -EBADE;
goto fail;
}
if (msg->len > DM_ULOG_REQUEST_SIZE) {
LOG_ERROR("Not enough space to receive kernel request (%d/%d)",
msg->len, DM_ULOG_REQUEST_SIZE);
r = -EBADE;
goto fail;
}
if (!msg->len)
LOG_ERROR("Zero length message received");
len -= (ssize_t)sizeof(struct cn_msg);
if (len < msg->len)
LOG_ERROR("len = %zd, msg->len = %" PRIu16, len, msg->len);
msg->data[msg->len] = '\0'; /* Cleaner way to ensure this? */
u_rq = (struct dm_ulog_request *)msg->data;
if (!u_rq->request_type) {
LOG_DBG("Bad transmission, requesting resend [%u]",
msg->seq);
r = -EAGAIN;
if (kernel_ack(msg->seq, EAGAIN)) {
LOG_ERROR("Failed to NACK kernel transmission [%u]",
msg->seq);
r = -EBADE;
}
}
/*
* Now we've got sizeof(struct cn_msg) + sizeof(struct nlmsghdr)
* worth of space that precede the request structure from the
* kernel. Since that space isn't going to be used again, we
* can take it for our purposes; rather than allocating a whole
* new structure and doing a memcpy.
*
* We should really make sure 'clog_request' doesn't grow
* beyond what is available to us, but we need only check it
* once... perhaps at compile time?
*/
foo = (char *)u_rq;
foo -= (sizeof(struct clog_request) - sizeof(struct dm_ulog_request));
*rq = (struct clog_request *) foo;
/* Clear the wrapper container fields */
memset(*rq, 0, (size_t)((char *)u_rq - (char *)(*rq)));
break;
default:
LOG_ERROR("Unknown nlmsg_type");
r = -EBADE;
}
fail:
if (r)
*rq = NULL;
return (r == -EAGAIN) ? 0 : r;
}
static int kernel_send_helper(void *data, uint16_t out_size)
{
int r;
struct nlmsghdr *nlh;
struct cn_msg *msg;
memset(send_buf, 0, sizeof(send_buf));
nlh = (struct nlmsghdr *)send_buf;
nlh->nlmsg_seq = 0; /* FIXME: Is this used? */
nlh->nlmsg_pid = getpid();
nlh->nlmsg_type = NLMSG_DONE;
nlh->nlmsg_len = NLMSG_LENGTH(out_size + sizeof(struct cn_msg));
nlh->nlmsg_flags = 0;
msg = NLMSG_DATA(nlh);
memcpy(msg->data, data, out_size);
msg->len = out_size;
msg->id.idx = CN_IDX_DM;
msg->id.val = CN_VAL_DM_USERSPACE_LOG;
msg->seq = 0;
r = send(cn_fd, nlh, NLMSG_LENGTH(out_size + sizeof(struct cn_msg)), 0);
/* FIXME: do better error processing */
if (r <= 0)
return -EBADE;
return 0;
}
/*
* do_local_work
*
* Any processing errors are placed in the 'rq'
* structure to be reported back to the kernel.
* It may be pointless for this function to
* return an int.
*
* Returns: 0 on success, -EXXX on failure
*/
static int do_local_work(void *data __attribute__((unused)))
{
int r;
struct clog_request *rq;
struct dm_ulog_request *u_rq = NULL;
r = kernel_recv(&rq);
if (r)
return r;
if (!rq)
return 0;
u_rq = &rq->u_rq;
LOG_DBG("[%s] Request from kernel received: [%s/%u]",
SHORT_UUID(u_rq->uuid), RQ_TYPE(u_rq->request_type),
u_rq->seq);
switch (u_rq->request_type) {
case DM_ULOG_CTR:
case DM_ULOG_DTR:
case DM_ULOG_GET_REGION_SIZE:
case DM_ULOG_IN_SYNC:
case DM_ULOG_GET_SYNC_COUNT:
case DM_ULOG_STATUS_INFO:
case DM_ULOG_STATUS_TABLE:
case DM_ULOG_PRESUSPEND:
/* We do not specify ourselves as server here */
r = do_request(rq, 0);
if (r)
LOG_DBG("Returning failed request to kernel [%s]",
RQ_TYPE(u_rq->request_type));
r = kernel_send(u_rq);
if (r)
LOG_ERROR("Failed to respond to kernel [%s]",
RQ_TYPE(u_rq->request_type));
break;
case DM_ULOG_RESUME:
/*
* Resume is a special case that requires a local
* component to join the CPG, and a cluster component
* to handle the request.
*/
r = local_resume(u_rq);
if (r) {
LOG_DBG("Returning failed request to kernel [%s]",
RQ_TYPE(u_rq->request_type));
r = kernel_send(u_rq);
if (r)
LOG_ERROR("Failed to respond to kernel [%s]",
RQ_TYPE(u_rq->request_type));
break;
}
/* ELSE, fall through */
case DM_ULOG_IS_CLEAN:
case DM_ULOG_FLUSH:
case DM_ULOG_MARK_REGION:
case DM_ULOG_GET_RESYNC_WORK:
case DM_ULOG_SET_REGION_SYNC:
case DM_ULOG_IS_REMOTE_RECOVERING:
case DM_ULOG_POSTSUSPEND:
r = cluster_send(rq);
if (r) {
u_rq->data_size = 0;
u_rq->error = r;
kernel_send(u_rq);
}
break;
case DM_ULOG_CLEAR_REGION:
r = kernel_ack(u_rq->seq, 0);
r = cluster_send(rq);
if (r) {
/*
* FIXME: store error for delivery on flush
* This would allow us to optimize MARK_REGION
* too.
*/
}
break;
default:
LOG_ERROR("Invalid log request received (%u), ignoring.",
u_rq->request_type);
return 0;
}
if (r && !u_rq->error)
u_rq->error = r;
return r;
}
/*
* kernel_send
* @u_rq: result to pass back to kernel
*
* This function returns the u_rq structure
* (containing the results) to the kernel.
* It then frees the structure.
*
* WARNING: should the structure be freed if
* there is an error? I vote 'yes'. If the
* kernel doesn't get the response, it should
* resend the request.
*
* Returns: 0 on success, -EXXX on failure
*/
int kernel_send(struct dm_ulog_request *u_rq)
{
int r;
uint16_t size;
if (!u_rq)
return -EINVAL;
size = (uint16_t)(sizeof(struct dm_ulog_request) + u_rq->data_size);
if (!u_rq->data_size && !u_rq->error) {
/* An ACK is all that is needed */
/* FIXME: add ACK code */
} else if (size > DM_ULOG_REQUEST_SIZE) {
/*
* If we gotten here, we've already overrun
* our allotted space somewhere.
*
* We must do something, because the kernel
* is waiting for a response.
*/
LOG_ERROR("Not enough space to respond to server");
u_rq->error = -ENOSPC;
size = sizeof(struct dm_ulog_request);
}
r = kernel_send_helper(u_rq, size);
if (r)
LOG_ERROR("Failed to send msg to kernel.");
return r;
}
/*
* init_local
*
* Initialize kernel communication socket (netlink)
*
* Returns: 0 on success, values from common.h on failure
*/
int init_local(void)
{
int r = 0;
unsigned opt;
struct sockaddr_nl addr;
cn_fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
if (cn_fd < 0)
return EXIT_KERNEL_SOCKET;
/* memset to fix valgrind complaint */
memset(&addr, 0, sizeof(struct sockaddr_nl));
addr.nl_family = AF_NETLINK;
addr.nl_groups = CN_IDX_DM;
addr.nl_pid = 0;
r = bind(cn_fd, (struct sockaddr *) &addr, sizeof(addr));
if (r < 0) {
close(cn_fd);
return EXIT_KERNEL_BIND;
}
opt = addr.nl_groups;
r = setsockopt(cn_fd, 270, NETLINK_ADD_MEMBERSHIP, &opt, sizeof(opt));
if (r) {
close(cn_fd);
return EXIT_KERNEL_SETSOCKOPT;
}
/*
r = fcntl(cn_fd, F_SETFL, FNDELAY);
*/
links_register(cn_fd, "local", do_local_work, NULL);
return 0;
}
/*
* cleanup_local
*
* Clean up before exiting
*/
void cleanup_local(void)
{
links_unregister(cn_fd);
close(cn_fd);
}

20
daemons/cmirrord/local.h Normal file
View File

@@ -0,0 +1,20 @@
/*
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* 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
*/
#ifndef _LVM_CLOG_LOCAL_H
#define _LVM_CLOG_LOCAL_H
int init_local(void);
void cleanup_local(void);
int kernel_send(struct dm_ulog_request *rq);
#endif /* _LVM_CLOG_LOCAL_H */

View File

@@ -0,0 +1,57 @@
/*
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* 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 "logging.h"
const char *__rq_types_off_by_one[] = {
"DM_ULOG_CTR",
"DM_ULOG_DTR",
"DM_ULOG_PRESUSPEND",
"DM_ULOG_POSTSUSPEND",
"DM_ULOG_RESUME",
"DM_ULOG_GET_REGION_SIZE",
"DM_ULOG_IS_CLEAN",
"DM_ULOG_IN_SYNC",
"DM_ULOG_FLUSH",
"DM_ULOG_MARK_REGION",
"DM_ULOG_CLEAR_REGION",
"DM_ULOG_GET_RESYNC_WORK",
"DM_ULOG_SET_REGION_SYNC",
"DM_ULOG_GET_SYNC_COUNT",
"DM_ULOG_STATUS_INFO",
"DM_ULOG_STATUS_TABLE",
"DM_ULOG_IS_REMOTE_RECOVERING",
NULL
};
int log_tabbing = 0;
int log_is_open = 0;
/*
* Variables for various conditional logging
*/
#ifdef MEMB
int log_membership_change = 1;
#else
int log_membership_change = 0;
#endif
#ifdef CKPT
int log_checkpoint = 1;
#else
int log_checkpoint = 0;
#endif
#ifdef RESEND
int log_resend_requests = 1;
#else
int log_resend_requests = 0;
#endif

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* 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
*/
#ifndef _LVM_CLOG_LOGGING_H
#define _LVM_CLOG_LOGGING_H
#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include "configure.h"
#include <stdio.h>
#include <stdint.h>
#include <syslog.h>
/* SHORT_UUID - print last 8 chars of a string */
#define SHORT_UUID(x) (strlen(x) > 8) ? ((x) + (strlen(x) - 8)) : (x)
extern const char *__rq_types_off_by_one[];
#define RQ_TYPE(x) __rq_types_off_by_one[(x) - 1]
extern int log_tabbing;
extern int log_is_open;
extern int log_membership_change;
extern int log_checkpoint;
extern int log_resend_requests;
#define LOG_OPEN(ident, option, facility) do { \
openlog(ident, option, facility); \
log_is_open = 1; \
} while (0)
#define LOG_CLOSE(void) do { \
log_is_open = 0; \
closelog(); \
} while (0)
#define LOG_OUTPUT(level, f, arg...) do { \
int __i; \
char __buffer[16]; \
FILE *fp = (level > LOG_NOTICE) ? stderr : stdout; \
if (log_is_open) { \
for (__i = 0; (__i < log_tabbing) && (__i < 15); __i++) \
__buffer[__i] = '\t'; \
__buffer[__i] = '\0'; \
syslog(level, "%s" f "\n", __buffer, ## arg); \
} else { \
for (__i = 0; __i < log_tabbing; __i++) \
fprintf(fp, "\t"); \
fprintf(fp, f "\n", ## arg); \
} \
} while (0)
#ifdef DEBUG
#define LOG_DBG(f, arg...) LOG_OUTPUT(LOG_DEBUG, f, ## arg)
#else /* DEBUG */
#define LOG_DBG(f, arg...)
#endif /* DEBUG */
#define LOG_COND(__X, f, arg...) do {\
if (__X) { \
LOG_OUTPUT(LOG_NOTICE, f, ## arg); \
} \
} while (0)
#define LOG_PRINT(f, arg...) LOG_OUTPUT(LOG_NOTICE, f, ## arg)
#define LOG_ERROR(f, arg...) LOG_OUTPUT(LOG_ERR, f, ## arg)
#endif /* _LVM_CLOG_LOGGING_H */

View File

@@ -1,19 +0,0 @@
dm_event_handler_create
dm_event_handler_destroy
dm_event_handler_set_dso
dm_event_handler_set_dev_name
dm_event_handler_set_uuid
dm_event_handler_set_major
dm_event_handler_set_minor
dm_event_handler_set_event_mask
dm_event_handler_get_dso
dm_event_handler_get_devname
dm_event_handler_get_uuid
dm_event_handler_get_major
dm_event_handler_get_minor
dm_event_handler_get_event_mask
dm_event_register_handler
dm_event_unregister_handler
dm_event_get_registered_device
dm_event_handler_set_timeout
dm_event_handler_get_timeout

View File

@@ -1,5 +1,5 @@
#
# Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
# Copyright (C) 2005-2010 Red Hat, Inc. All rights reserved.
#
# This file is part of the device-mapper userspace tools.
#
@@ -13,71 +13,96 @@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
top_builddir = @top_builddir@
SOURCES = libdevmapper-event.c
LIB_STATIC = libdevmapper-event.a
ifeq ("@LIB_SUFFIX@","dylib")
LIB_SHARED = libdevmapper-event.dylib
else
LIB_SHARED = libdevmapper-event.so
endif
SOURCES2 = dmeventd.c
TARGETS = dmeventd
CLEAN_TARGETS = dmeventd.o
include ../make.tmpl
.PHONY: install_lib_dynamic install_lib_static install_include \
install_pkgconfig install_dmeventd_dynamic install_dmeventd_static \
install_lib install_dmeventd
LDFLAGS += -ldl -ldevmapper -lpthread
CLDFLAGS += -ldl -ldevmapper -lpthread
INSTALL_DMEVENTD_TARGETS = install_dmeventd_dynamic
INSTALL_LIB_TARGETS = install_lib_dynamic
LIB_NAME = libdevmapper-event
ifeq ("@STATIC_LINK@", "yes")
LIB_STATIC = $(LIB_NAME).a
TARGETS += $(LIB_STATIC) dmeventd.static
INSTALL_DMEVENTD_TARGETS += install_dmeventd_static
INSTALL_LIB_TARGETS += install_lib_static
endif
LIB_VERSION = $(LIB_VERSION_DM)
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
CLEAN_TARGETS = dmeventd.static $(LIB_NAME).a
ifneq ($(MAKECMDGOALS),device-mapper)
SUBDIRS+=plugins
endif
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
CFLOW_TARGET = dmeventd
EXPORTED_HEADER = $(srcdir)/libdevmapper-event.h
EXPORTED_FN_PREFIX = dm_event
include $(top_builddir)/make.tmpl
all: device-mapper
device-mapper: $(TARGETS)
LIBS += -ldevmapper
LVMLIBS += -ldevmapper-event $(PTHREAD_LIBS)
dmeventd: $(LIB_SHARED) dmeventd.o
$(CC) -o $@ dmeventd.o $(CFLAGS) $(LDFLAGS) \
-L. -ldevmapper-event $(LIBS) -rdynamic
$(CC) $(CFLAGS) $(LDFLAGS) -L. -o $@ dmeventd.o \
$(DL_LIBS) $(LVMLIBS) $(LIBS) -rdynamic
.PHONY: install_dynamic install_static install_include \
install_pkgconfig install_dmeventd
INSTALL_TYPE = install_dynamic
ifeq ("@STATIC_LINK@", "yes")
INSTALL_TYPE += install_static
endif
dmeventd.static: $(LIB_STATIC) dmeventd.o $(interfacebuilddir)/libdevmapper.a
$(CC) $(CFLAGS) $(LDFLAGS) -static -L. -L$(interfacebuilddir) -o $@ \
dmeventd.o $(DL_LIBS) $(LVMLIBS) $(LIBS) $(STATIC_LIBS)
ifeq ("@PKGCONFIG@", "yes")
INSTALL_TYPE += install_pkgconfig
INSTALL_LIB_TARGETS += install_pkgconfig
endif
install: $(INSTALL_TYPE) install_include install_dmeventd
ifneq ("$(CFLOW_CMD)", "")
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
-include $(top_builddir)/libdm/libdevmapper.cflow
-include $(top_builddir)/lib/liblvm-internal.cflow
-include $(top_builddir)/lib/liblvm2cmd.cflow
-include $(top_builddir)/daemons/dmeventd/$(LIB_NAME).cflow
-include $(top_builddir)/daemons/dmeventd/plugins/mirror/$(LIB_NAME)-lvm2mirror.cflow
endif
install_include:
$(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper-event.h \
$(includedir)/libdevmapper-event.h
install_include: $(srcdir)/libdevmapper-event.h
$(INSTALL_DATA) -D $< $(includedir)/$(<F)
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_pkgconfig: libdevmapper-event.pc
$(INSTALL_DATA) -D $< $(pkgconfigdir)/devmapper-event.pc
install_dmeventd: dmeventd
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< $(sbindir)/$<
install_lib_dynamic: install_lib_shared
install_pkgconfig:
$(INSTALL) -D $(OWNER) $(GROUP) -m 444 libdevmapper-event.pc \
$(usrlibdir)/pkgconfig/devmapper-event.pc
install_lib_static: $(LIB_STATIC)
$(INSTALL_DATA) -D $< $(usrlibdir)/$(<F)
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
install_lib: $(INSTALL_LIB_TARGETS)
.PHONY: distclean_lib distclean
install_dmeventd_dynamic: dmeventd
$(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
distclean_lib:
$(RM) libdevmapper-event.pc
install_dmeventd_static: dmeventd.static
$(INSTALL_PROGRAM) -D $< $(staticdir)/$(<F)
distclean: distclean_lib
install_dmeventd: $(INSTALL_DMEVENTD_TARGETS)
install: install_include install_lib install_dmeventd
install_device-mapper: install_include install_lib install_dmeventd
DISTCLEAN_TARGETS += libdevmapper-event.pc .exported_symbols_generated

View File

@@ -22,10 +22,9 @@
#include "configure.h"
#include "libdevmapper.h"
#include "libdevmapper-event.h"
#include "list.h"
#include "dmeventd.h"
//#include "libmultilog.h"
#include "log.h"
#include "dm-logging.h"
#include <dlfcn.h>
#include <errno.h>
@@ -36,6 +35,7 @@
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <signal.h>
#include <arpa/inet.h> /* for htonl, ntohl */
#ifdef linux
@@ -54,14 +54,13 @@
static volatile sig_atomic_t _exit_now = 0; /* set to '1' when signal is given to exit */
static volatile sig_atomic_t _thread_registries_empty = 1; /* registries are empty initially */
static int _debug = 0;
/* List (un)link macros. */
#define LINK(x, head) list_add(head, &(x)->list)
#define LINK(x, head) dm_list_add(head, &(x)->list)
#define LINK_DSO(dso) LINK(dso, &_dso_registry)
#define LINK_THREAD(thread) LINK(thread, &_thread_registry)
#define UNLINK(x) list_del(&(x)->list)
#define UNLINK(x) dm_list_del(&(x)->list)
#define UNLINK_DSO(x) UNLINK(x)
#define UNLINK_THREAD(x) UNLINK(x)
@@ -98,9 +97,12 @@ static pthread_mutex_t _global_mutex;
#define DEBUGLOG(fmt, args...) _debuglog(fmt, ## args)
int dmeventd_debug = 0;
static int _foreground = 0;
/* Data kept about a DSO. */
struct dso_data {
struct list list;
struct dm_list list;
char *dso_name; /* DSO name (eg, "evms", "dmraid", "lvm2"). */
@@ -142,7 +144,7 @@ struct dso_data {
int (*unregister_device)(const char *device, const char *uuid,
int major, int minor, void **user);
};
static LIST_INIT(_dso_registry);
static DM_LIST_INIT(_dso_registry);
/* Structure to keep parsed register variables from client message. */
struct message_data {
@@ -167,7 +169,7 @@ struct message_data {
* occurs and the event processing function of the DSO gets called.
*/
struct thread_status {
struct list list;
struct dm_list list;
pthread_t thread;
@@ -188,14 +190,14 @@ struct thread_status {
struct dm_task *current_task;
time_t next_time;
uint32_t timeout;
struct list timeout_list;
struct dm_list timeout_list;
void *dso_private; /* dso per-thread status variable */
};
static LIST_INIT(_thread_registry);
static LIST_INIT(_thread_registry_unused);
static DM_LIST_INIT(_thread_registry);
static DM_LIST_INIT(_thread_registry_unused);
static int _timeout_running;
static LIST_INIT(_timeout_registry);
static DM_LIST_INIT(_timeout_registry);
static pthread_mutex_t _timeout_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t _timeout_cond = PTHREAD_COND_INITIALIZER;
@@ -204,7 +206,7 @@ static void _debuglog(const char *fmt, ...)
time_t P;
va_list ap;
if (!_debug)
if (!_foreground)
return;
va_start(ap,fmt);
@@ -238,13 +240,15 @@ static struct thread_status *_alloc_thread_status(struct message_data *data,
ret->dso_data = dso_data;
ret->events = data->events.field;
ret->timeout = data->timeout.secs;
list_init(&ret->timeout_list);
dm_list_init(&ret->timeout_list);
return ret;
}
static void _lib_put(struct dso_data *data);
static void _free_thread_status(struct thread_status *thread)
{
_lib_put(thread->dso_data);
if (thread->current_task)
dm_task_destroy(thread->current_task);
dm_free(thread->device.uuid);
@@ -323,13 +327,10 @@ static int _fetch_string(char **ptr, char **src, const int delimiter)
/* Free message memory. */
static void _free_message(struct message_data *message_data)
{
if (message_data->id)
dm_free(message_data->id);
if (message_data->dso_name)
dm_free(message_data->dso_name);
dm_free(message_data->id);
dm_free(message_data->dso_name);
if (message_data->device_uuid)
dm_free(message_data->device_uuid);
dm_free(message_data->device_uuid);
}
@@ -390,26 +391,6 @@ static int _unlock_mutex(void)
return pthread_mutex_unlock(&_global_mutex);
}
/* Store pid in pidfile. */
static int _storepid(int lf)
{
int len;
char pid[8];
if ((len = snprintf(pid, sizeof(pid), "%u\n", getpid())) < 0)
return 0;
if (len > (int) sizeof(pid))
len = (int) sizeof(pid);
if (write(lf, pid, (size_t) len) != len)
return 0;
fsync(lf);
return 1;
}
/* Check, if a device exists. */
static int _fill_device_data(struct thread_status *ts)
{
@@ -458,7 +439,7 @@ static struct thread_status *_lookup_thread_status(struct message_data *data)
{
struct thread_status *thread;
list_iterate_items(thread, &_thread_registry)
dm_list_iterate_items(thread, &_thread_registry)
if (!strcmp(data->device_uuid, thread->device.uuid))
return thread;
@@ -472,14 +453,14 @@ static void _exit_dm_lib(void)
dm_lib_exit();
}
static void _exit_timeout(void *unused __attribute((unused)))
static void _exit_timeout(void *unused __attribute__((unused)))
{
_timeout_running = 0;
pthread_mutex_unlock(&_timeout_mutex);
}
/* Wake up monitor threads every so often. */
static void *_timeout_thread(void *unused __attribute((unused)))
static void *_timeout_thread(void *unused __attribute__((unused)))
{
struct timespec timeout;
time_t curr_time;
@@ -488,13 +469,13 @@ static void *_timeout_thread(void *unused __attribute((unused)))
pthread_cleanup_push(_exit_timeout, NULL);
pthread_mutex_lock(&_timeout_mutex);
while (!list_empty(&_timeout_registry)) {
while (!dm_list_empty(&_timeout_registry)) {
struct thread_status *thread;
timeout.tv_sec = 0;
curr_time = time(NULL);
list_iterate_items_gen(thread, &_timeout_registry, timeout_list) {
dm_list_iterate_items_gen(thread, &_timeout_registry, timeout_list) {
if (thread->next_time <= curr_time) {
thread->next_time = curr_time + thread->timeout;
pthread_kill(thread->thread, SIGALRM);
@@ -521,8 +502,8 @@ static int _register_for_timeout(struct thread_status *thread)
thread->next_time = time(NULL) + thread->timeout;
if (list_empty(&thread->timeout_list)) {
list_add(&_timeout_registry, &thread->timeout_list);
if (dm_list_empty(&thread->timeout_list)) {
dm_list_add(&_timeout_registry, &thread->timeout_list);
if (_timeout_running)
pthread_cond_signal(&_timeout_cond);
}
@@ -542,9 +523,9 @@ static int _register_for_timeout(struct thread_status *thread)
static void _unregister_for_timeout(struct thread_status *thread)
{
pthread_mutex_lock(&_timeout_mutex);
if (!list_empty(&thread->timeout_list)) {
list_del(&thread->timeout_list);
list_init(&thread->timeout_list);
if (!dm_list_empty(&thread->timeout_list)) {
dm_list_del(&thread->timeout_list);
dm_list_init(&thread->timeout_list);
}
pthread_mutex_unlock(&_timeout_mutex);
}
@@ -697,7 +678,7 @@ static void _monitor_unregister(void *arg)
}
/* we may have been relinked to unused registry since we were
called, so check that */
list_iterate_items(thread_iter, &_thread_registry_unused)
dm_list_iterate_items(thread_iter, &_thread_registry_unused)
if (thread_iter == thread) {
thread->status = DM_THREAD_DONE;
_unlock_mutex();
@@ -838,7 +819,7 @@ static struct dso_data *_lookup_dso(struct message_data *data)
{
struct dso_data *dso_data, *ret = NULL;
list_iterate_items(dso_data, &_dso_registry)
dm_list_iterate_items(dso_data, &_dso_registry)
if (!strcmp(data->dso_name, dso_data->dso_name)) {
_lib_get(dso_data);
ret = dso_data;
@@ -1067,8 +1048,7 @@ static int _registered_device(struct message_data *message_data,
&& (thread->events)) ? thread->events : thread->
events | DM_EVENT_REGISTRATION_PENDING;
if (msg->data)
dm_free(msg->data);
dm_free(msg->data);
msg->size = dm_asprintf(&(msg->data), fmt, id, dso, dev, events);
@@ -1109,7 +1089,7 @@ static int _get_registered_dev(struct message_data *message_data, int next)
_lock_mutex();
/* Iterate list of threads checking if we want a particular one. */
list_iterate_items(thread, &_thread_registry)
dm_list_iterate_items(thread, &_thread_registry)
if (_want_registered_device(message_data->dso_name,
message_data->device_uuid,
thread)) {
@@ -1132,10 +1112,10 @@ static int _get_registered_dev(struct message_data *message_data, int next)
thread = hit;
while (1) {
if (list_end(&_thread_registry, &thread->list))
if (dm_list_end(&_thread_registry, &thread->list))
goto out;
thread = list_item(thread->list.n, struct thread_status);
thread = dm_list_item(thread->list.n, struct thread_status);
if (_want_registered_device(message_data->dso_name, NULL, thread)) {
hit = thread;
break;
@@ -1178,8 +1158,7 @@ static int _get_timeout(struct message_data *message_data)
struct thread_status *thread;
struct dm_event_daemon_message *msg = message_data->msg;
if (msg->data)
dm_free(msg->data);
dm_free(msg->data);
_lock_mutex();
if ((thread = _lookup_thread_status(message_data))) {
@@ -1303,8 +1282,7 @@ static int _client_read(struct dm_event_fifos *fifos,
}
if (bytes != size) {
if (msg->data)
dm_free(msg->data);
dm_free(msg->data);
msg->data = NULL;
msg->size = 0;
}
@@ -1432,19 +1410,18 @@ static void _process_request(struct dm_event_fifos *fifos)
if (!_client_write(fifos, &msg))
stack;
if (msg.data)
dm_free(msg.data);
dm_free(msg.data);
}
static void _cleanup_unused_threads(void)
{
int ret;
struct list *l;
struct dm_list *l;
struct thread_status *thread;
_lock_mutex();
while ((l = list_first(&_thread_registry_unused))) {
thread = list_item(l, struct thread_status);
while ((l = dm_list_first(&_thread_registry_unused))) {
thread = dm_list_item(l, struct thread_status);
if (thread->processing)
break; /* cleanup on the next round */
@@ -1469,7 +1446,7 @@ static void _cleanup_unused_threads(void)
break;
}
list_del(l);
dm_list_del(l);
syslog(LOG_ERR,
"thread can't be on unused list unless !thread->events");
thread->status = DM_THREAD_RUNNING;
@@ -1479,9 +1456,8 @@ static void _cleanup_unused_threads(void)
}
if (thread->status == DM_THREAD_DONE) {
list_del(l);
dm_list_del(l);
pthread_join(thread->thread, NULL);
_lib_put(thread->dso_data);
_free_thread_status(thread);
}
}
@@ -1489,7 +1465,7 @@ static void _cleanup_unused_threads(void)
_unlock_mutex();
}
static void _sig_alarm(int signum __attribute((unused)))
static void _sig_alarm(int signum __attribute__((unused)))
{
pthread_testcancel();
}
@@ -1521,7 +1497,7 @@ static void _init_thread_signals(void)
* Set the global variable which the process should
* be watching to determine when to exit.
*/
static void _exit_handler(int sig __attribute((unused)))
static void _exit_handler(int sig __attribute__((unused)))
{
/*
* We exit when '_exit_now' is set.
@@ -1538,23 +1514,6 @@ static void _exit_handler(int sig __attribute((unused)))
}
static int _lock_pidfile(void)
{
int lf;
char pidfile[] = DMEVENTD_PIDFILE;
if ((lf = open(pidfile, O_CREAT | O_RDWR, 0644)) < 0)
exit(EXIT_OPEN_PID_FAILURE);
if (flock(lf, LOCK_EX | LOCK_NB) < 0)
exit(EXIT_LOCKFILE_INUSE);
if (!_storepid(lf))
exit(EXIT_FAILURE);
return 0;
}
#ifdef linux
/*
* Protection against OOM killer if kernel supports it
@@ -1586,6 +1545,11 @@ static int _set_oom_adj(int val)
}
#endif
static void remove_lockfile(void)
{
unlink(DMEVENTD_PIDFILE);
}
static void _daemonize(void)
{
int child_status;
@@ -1623,12 +1587,8 @@ static void _daemonize(void)
/* Problem with child. Determine what it is by exit code */
switch (WEXITSTATUS(child_status)) {
case EXIT_LOCKFILE_INUSE:
fprintf(stderr, "Another dmeventd daemon is already running\n");
break;
case EXIT_DESC_CLOSE_FAILURE:
case EXIT_DESC_OPEN_FAILURE:
case EXIT_OPEN_PID_FAILURE:
case EXIT_FIFO_FAILURE:
case EXIT_CHDIR_FAILURE:
default:
@@ -1661,11 +1621,12 @@ static void _daemonize(void)
static void usage(char *prog, FILE *file)
{
fprintf(file, "Usage:\n");
fprintf(file, "%s [Vhd]\n", prog);
fprintf(file, "%s [-V] [-h] [-d] [-d] [-d] [-f]\n", prog);
fprintf(file, "\n");
fprintf(file, " -V Show version of dmeventd\n");
fprintf(file, " -h Show this help information\n");
fprintf(file, " -d Don't fork, run in the foreground\n");
fprintf(file, " -d Log debug messages to syslog (-d, -dd, -ddd)\n");
fprintf(file, " -f Don't fork, run in the foreground\n");
fprintf(file, "\n");
}
@@ -1679,7 +1640,7 @@ int main(int argc, char *argv[])
opterr = 0;
optind = 0;
while ((opt = getopt(argc, argv, "?hVd")) != EOF) {
while ((opt = getopt(argc, argv, "?fhVd")) != EOF) {
switch (opt) {
case 'h':
usage(argv[0], stdout);
@@ -1687,8 +1648,11 @@ int main(int argc, char *argv[])
case '?':
usage(argv[0], stderr);
exit(0);
case 'f':
_foreground++;
break;
case 'd':
_debug++;
dmeventd_debug++;
break;
case 'V':
printf("dmeventd version: %s\n", DM_LIB_VERSION);
@@ -1697,12 +1661,23 @@ int main(int argc, char *argv[])
}
}
if (!_debug)
/*
* Switch to C locale to avoid reading large locale-archive file
* used by some glibc (on some distributions it takes over 100MB).
* Daemon currently needs to use mlockall().
*/
if (setenv("LANG", "C", 1))
perror("Cannot set LANG to C");
if (!_foreground)
_daemonize();
openlog("dmeventd", LOG_PID, LOG_DAEMON);
_lock_pidfile(); /* exits if failure */
if (dm_create_lockfile(DMEVENTD_PIDFILE) == 0)
exit(EXIT_FAILURE);
atexit(remove_lockfile);
/* Set the rest of the signals to cause '_exit_now' to be set */
signal(SIGINT, &_exit_handler);
@@ -1725,23 +1700,19 @@ int main(int argc, char *argv[])
pthread_mutex_init(&_global_mutex, NULL);
#ifdef MCL_CURRENT
if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1)
exit(EXIT_FAILURE);
#endif
if ((ret = _open_fifos(&fifos)))
exit(EXIT_FIFO_FAILURE);
/* Signal parent, letting them know we are ready to go. */
kill(getppid(), SIGTERM);
if (!_foreground)
kill(getppid(), SIGTERM);
syslog(LOG_NOTICE, "dmeventd ready for processing.");
while (!_exit_now) {
_process_request(&fifos);
_cleanup_unused_threads();
if (!list_empty(&_thread_registry)
|| !list_empty(&_thread_registry_unused))
if (!dm_list_empty(&_thread_registry)
|| !dm_list_empty(&_thread_registry_unused))
_thread_registries_empty = 0;
else
_thread_registries_empty = 1;
@@ -1749,9 +1720,6 @@ int main(int argc, char *argv[])
_exit_dm_lib();
#ifdef MCL_CURRENT
munlockall();
#endif
pthread_mutex_destroy(&_global_mutex);
syslog(LOG_NOTICE, "dmeventd shutting down.");

View File

@@ -56,10 +56,10 @@ struct dm_event_fifos {
/* EXIT_SUCCESS 0 -- stdlib.h */
/* EXIT_FAILURE 1 -- stdlib.h */
#define EXIT_LOCKFILE_INUSE 2
/* EXIT_LOCKFILE_INUSE 2 -- obsoleted */
#define EXIT_DESC_CLOSE_FAILURE 3
#define EXIT_DESC_OPEN_FAILURE 4
#define EXIT_OPEN_PID_FAILURE 5
/* EXIT_OPEN_PID_FAILURE 5 -- obsoleted */
#define EXIT_FIFO_FAILURE 6
#define EXIT_CHDIR_FAILURE 7

View File

@@ -12,7 +12,7 @@
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "dmlib.h"
#include "libdevmapper-event.h"
//#include "libmultilog.h"
#include "dmeventd.h"
@@ -35,6 +35,8 @@ static int _sequence_nr = 0;
struct dm_event_handler {
char *dso;
char *dmeventd_path;
char *dev_name;
char *uuid;
@@ -47,10 +49,8 @@ struct dm_event_handler {
static void _dm_event_handler_clear_dev_info(struct dm_event_handler *dmevh)
{
if (dmevh->dev_name)
dm_free(dmevh->dev_name);
if (dmevh->uuid)
dm_free(dmevh->uuid);
dm_free(dmevh->dev_name);
dm_free(dmevh->uuid);
dmevh->dev_name = dmevh->uuid = NULL;
dmevh->major = dmevh->minor = 0;
}
@@ -62,6 +62,7 @@ struct dm_event_handler *dm_event_handler_create(void)
if (!(dmevh = dm_malloc(sizeof(*dmevh))))
return NULL;
dmevh->dmeventd_path = NULL;
dmevh->dso = dmevh->dev_name = dmevh->uuid = NULL;
dmevh->major = dmevh->minor = 0;
dmevh->mask = 0;
@@ -73,17 +74,30 @@ struct dm_event_handler *dm_event_handler_create(void)
void dm_event_handler_destroy(struct dm_event_handler *dmevh)
{
_dm_event_handler_clear_dev_info(dmevh);
if (dmevh->dso)
dm_free(dmevh->dso);
dm_free(dmevh->dso);
dm_free(dmevh->dmeventd_path);
dm_free(dmevh);
}
int dm_event_handler_set_dmeventd_path(struct dm_event_handler *dmevh, const char *dmeventd_path)
{
if (!dmeventd_path) /* noop */
return 0;
dm_free(dmevh->dmeventd_path);
dmevh->dmeventd_path = dm_strdup(dmeventd_path);
if (!dmevh->dmeventd_path)
return -ENOMEM;
return 0;
}
int dm_event_handler_set_dso(struct dm_event_handler *dmevh, const char *path)
{
if (!path) /* noop */
return 0;
if (dmevh->dso)
dm_free(dmevh->dso);
dm_free(dmevh->dso);
dmevh->dso = dm_strdup(path);
if (!dmevh->dso)
@@ -113,7 +127,7 @@ int dm_event_handler_set_uuid(struct dm_event_handler *dmevh, const char *uuid)
_dm_event_handler_clear_dev_info(dmevh);
dmevh->uuid = dm_strdup(uuid);
if (!dmevh->dev_name)
if (!dmevh->uuid)
return -ENOMEM;
return 0;
}
@@ -259,8 +273,7 @@ static int _daemon_read(struct dm_event_fifos *fifos,
}
if (bytes != size) {
if (msg->data)
dm_free(msg->data);
dm_free(msg->data);
msg->data = NULL;
}
@@ -366,8 +379,7 @@ static int _daemon_talk(struct dm_event_fifos *fifos,
do {
if (msg->data)
dm_free(msg->data);
dm_free(msg->data);
msg->data = 0;
if (!_daemon_read(fifos, msg)) {
@@ -393,11 +405,13 @@ static int _daemon_talk(struct dm_event_fifos *fifos,
*
* Returns: 1 on success, 0 otherwise
*/
static int _start_daemon(struct dm_event_fifos *fifos)
static int _start_daemon(char *dmeventd_path, struct dm_event_fifos *fifos)
{
int pid, ret = 0;
int status;
struct stat statbuf;
char default_dmeventd_path[] = DMEVENTD_PATH;
char *args[] = { dmeventd_path ? : default_dmeventd_path, NULL };
if (stat(fifos->client_path, &statbuf))
goto start_server;
@@ -425,14 +439,20 @@ static int _start_daemon(struct dm_event_fifos *fifos)
start_server:
/* server is not running */
if (!strncmp(DMEVENTD_PATH, "/", 1) && stat(DMEVENTD_PATH, &statbuf)) {
log_error("Unable to find dmeventd.");
return_0;
}
pid = fork();
if (pid < 0)
log_error("Unable to fork.");
else if (!pid) {
execvp(DMEVENTD_PATH, NULL);
exit(EXIT_FAILURE);
execvp(args[0], args);
_exit(EXIT_FAILURE);
} else {
if (waitpid(pid, &status, 0) < 0)
log_error("Unable to start dmeventd: %s",
@@ -447,17 +467,19 @@ static int _start_daemon(struct dm_event_fifos *fifos)
}
/* Initialize client. */
static int _init_client(struct dm_event_fifos *fifos)
static int _init_client(char *dmeventd_path, struct dm_event_fifos *fifos)
{
/* FIXME? Is fifo the most suitable method? Why not share
comms/daemon code with something else e.g. multipath? */
/* init fifos */
memset(fifos, 0, sizeof(*fifos));
/* FIXME Make these either configurable or depend directly on dmeventd_path */
fifos->client_path = DM_EVENT_FIFO_CLIENT;
fifos->server_path = DM_EVENT_FIFO_SERVER;
if (!_start_daemon(fifos)) {
if (!_start_daemon(dmeventd_path, fifos)) {
stack;
return 0;
}
@@ -542,22 +564,21 @@ failed:
}
/* Handle the event (de)registration call and return negative error codes. */
static int _do_event(int cmd, struct dm_event_daemon_message *msg,
static int _do_event(int cmd, char *dmeventd_path, struct dm_event_daemon_message *msg,
const char *dso_name, const char *dev_name,
enum dm_event_mask evmask, uint32_t timeout)
{
int ret;
struct dm_event_fifos fifos;
if (!_init_client(&fifos)) {
if (!_init_client(dmeventd_path, &fifos)) {
stack;
return -ESRCH;
}
ret = _daemon_talk(&fifos, msg, DM_EVENT_CMD_HELLO, 0, 0, 0, 0);
if (msg->data)
dm_free(msg->data);
dm_free(msg->data);
msg->data = 0;
if (!ret)
@@ -584,7 +605,7 @@ int dm_event_register_handler(const struct dm_event_handler *dmevh)
uuid = dm_task_get_uuid(dmt);
if ((err = _do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, &msg,
if ((err = _do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, dmevh->dmeventd_path, &msg,
dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
log_error("%s: event registration failed: %s",
dm_task_get_name(dmt),
@@ -592,8 +613,7 @@ int dm_event_register_handler(const struct dm_event_handler *dmevh)
ret = 0;
}
if (msg.data)
dm_free(msg.data);
dm_free(msg.data);
dm_task_destroy(dmt);
@@ -614,7 +634,7 @@ int dm_event_unregister_handler(const struct dm_event_handler *dmevh)
uuid = dm_task_get_uuid(dmt);
if ((err = _do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, &msg,
if ((err = _do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, dmevh->dmeventd_path, &msg,
dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
log_error("%s: event deregistration failed: %s",
dm_task_get_name(dmt),
@@ -622,8 +642,7 @@ int dm_event_unregister_handler(const struct dm_event_handler *dmevh)
ret = 0;
}
if (msg.data)
dm_free(msg.data);
dm_free(msg.data);
dm_task_destroy(dmt);
@@ -680,6 +699,7 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
enum dm_event_mask reply_mask = 0;
struct dm_task *dmt = NULL;
struct dm_event_daemon_message msg = { 0, 0, NULL };
struct dm_info info;
if (!(dmt = _get_device_info(dmevh))) {
stack;
@@ -689,7 +709,7 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
uuid = dm_task_get_uuid(dmt);
if (!(ret = _do_event(next ? DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE :
DM_EVENT_CMD_GET_REGISTERED_DEVICE,
DM_EVENT_CMD_GET_REGISTERED_DEVICE, dmevh->dmeventd_path,
&msg, dmevh->dso, uuid, dmevh->mask, 0))) {
/* FIXME this will probably horribly break if we get
ill-formatted reply */
@@ -702,10 +722,8 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
dm_task_destroy(dmt);
dmt = NULL;
if (msg.data) {
dm_free(msg.data);
msg.data = NULL;
}
dm_free(msg.data);
msg.data = NULL;
_dm_event_handler_clear_dev_info(dmevh);
dmevh->uuid = dm_strdup(reply_uuid);
@@ -722,15 +740,11 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
dm_event_handler_set_dso(dmevh, reply_dso);
dm_event_handler_set_event_mask(dmevh, reply_mask);
if (reply_dso) {
dm_free(reply_dso);
reply_dso = NULL;
}
dm_free(reply_dso);
reply_dso = NULL;
if (reply_uuid) {
dm_free(reply_uuid);
reply_uuid = NULL;
}
dm_free(reply_uuid);
reply_uuid = NULL;
dmevh->dev_name = dm_strdup(dm_task_get_name(dmt));
if (!dmevh->dev_name) {
@@ -738,7 +752,6 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
goto fail;
}
struct dm_info info;
if (!dm_task_get_info(dmt, &info)) {
ret = -1;
goto fail;
@@ -752,12 +765,9 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
return ret;
fail:
if (msg.data)
dm_free(msg.data);
if (reply_dso)
dm_free(reply_dso);
if (reply_uuid)
dm_free(reply_uuid);
dm_free(msg.data);
dm_free(reply_dso);
dm_free(reply_uuid);
_dm_event_handler_clear_dev_info(dmevh);
if (dmt)
dm_task_destroy(dmt);

View File

@@ -55,12 +55,17 @@ void dm_event_handler_destroy(struct dm_event_handler *dmevh);
/*
* Path of shared library to handle events.
*
* All of dso, device_name and uuid strings are duplicated, you do not
* need to keep the pointers valid after the call succeeds. Thes may
* return -ENOMEM though.
* All of dmeventd, dso, device_name and uuid strings are duplicated so
* you do not need to keep the pointers valid after the call succeeds.
* They may return -ENOMEM though.
*/
int dm_event_handler_set_dso(struct dm_event_handler *dmevh, const char *path);
/*
* Path of dmeventd binary.
*/
int dm_event_handler_set_dmeventd_path(struct dm_event_handler *dmevh, const char *dmeventd_path);
/*
* Identify the device to monitor by exactly one of device_name, uuid or
* device number. String arguments are duplicated, see above.

View File

@@ -5,8 +5,7 @@ includedir=@includedir@
Name: devmapper-event
Description: device-mapper event library
Version: @DM_LIB_VERSION@
Requires: devmapper
Version: @DM_LIB_PATCHLEVEL@
Cflags: -I${includedir}
Libs: -L${libdir} -ldevmapper-event
Libs.private: -lpthread -ldl
Requires.private: devmapper

View File

@@ -14,9 +14,12 @@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
top_builddir = @top_builddir@
SUBDIRS += mirror snapshot
SUBDIRS += lvm2 mirror snapshot
include $(top_srcdir)/make.tmpl
include $(top_builddir)/make.tmpl
mirror: lvm2
snapshot: lvm2

View File

@@ -0,0 +1,6 @@
dmeventd_lvm2_init
dmeventd_lvm2_exit
dmeventd_lvm2_lock
dmeventd_lvm2_unlock
dmeventd_lvm2_pool
dmeventd_lvm2_run

View File

@@ -0,0 +1,31 @@
#
# Copyright (C) 2010 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
CLDFLAGS += -L$(top_builddir)/tools
SOURCES = dmeventd_lvm.c
LIB_SHARED = libdevmapper-event-lvm2.$(LIB_SUFFIX)
LIB_VERSION = $(LIB_VERSION_LVM)
include $(top_builddir)/make.tmpl
LIBS += @LVM2CMD_LIB@ -ldevmapper $(PTHREAD_LIBS)
install_lvm2: install_lib_shared
install: install_lvm2

View File

@@ -0,0 +1,152 @@
/*
* Copyright (C) 2010 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "log.h"
#include "lvm2cmd.h"
#include "errors.h"
#include "libdevmapper-event.h"
#include "dmeventd_lvm.h"
#include <pthread.h>
#include <syslog.h>
extern int dmeventd_debug;
/*
* register_device() is called first and performs initialisation.
* Only one device may be registered or unregistered at a time.
*/
static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER;
/*
* Number of active registrations.
*/
static int _register_count = 0;
static struct dm_pool *_mem_pool = NULL;
static void *_lvm_handle = NULL;
/*
* Currently only one event can be processed at a time.
*/
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
/*
* FIXME Do not pass things directly to syslog, rather use the existing logging
* facilities to sort logging ... however that mechanism needs to be somehow
* configurable and we don't have that option yet
*/
static void _temporary_log_fn(int level,
const char *file __attribute__((unused)),
int line __attribute__((unused)),
int dm_errno __attribute__((unused)),
const char *message)
{
level &= ~(_LOG_STDERR | _LOG_ONCE);
switch (level) {
case _LOG_DEBUG:
if (dmeventd_debug >= 3)
syslog(LOG_DEBUG, "%s", message);
break;
case _LOG_INFO:
if (dmeventd_debug >= 2)
syslog(LOG_INFO, "%s", message);
break;
case _LOG_NOTICE:
if (dmeventd_debug >= 1)
syslog(LOG_NOTICE, "%s", message);
break;
case _LOG_WARN:
syslog(LOG_WARNING, "%s", message);
break;
case _LOG_ERR:
syslog(LOG_ERR, "%s", message);
break;
default:
syslog(LOG_CRIT, "%s", message);
}
}
void dmeventd_lvm2_lock(void)
{
if (pthread_mutex_trylock(&_event_mutex)) {
syslog(LOG_NOTICE, "Another thread is handling an event. Waiting...");
pthread_mutex_lock(&_event_mutex);
}
}
void dmeventd_lvm2_unlock(void)
{
pthread_mutex_unlock(&_event_mutex);
}
int dmeventd_lvm2_init(void)
{
int r = 0;
pthread_mutex_lock(&_register_mutex);
/*
* Need some space for allocations. 1024 should be more
* than enough for what we need (device mapper name splitting)
*/
if (!_mem_pool && !(_mem_pool = dm_pool_create("mirror_dso", 1024)))
goto out;
if (!_lvm_handle) {
lvm2_log_fn(_temporary_log_fn);
if (!(_lvm_handle = lvm2_init())) {
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
goto out;
}
/* FIXME Temporary: move to dmeventd core */
lvm2_run(_lvm_handle, "_memlock_inc");
}
_register_count++;
r = 1;
out:
pthread_mutex_unlock(&_register_mutex);
return r;
}
void dmeventd_lvm2_exit(void)
{
pthread_mutex_lock(&_register_mutex);
if (!--_register_count) {
lvm2_run(_lvm_handle, "_memlock_dec");
lvm2_exit(_lvm_handle);
_lvm_handle = NULL;
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
}
pthread_mutex_unlock(&_register_mutex);
}
struct dm_pool *dmeventd_lvm2_pool(void)
{
return _mem_pool;
}
int dmeventd_lvm2_run(const char *cmdline)
{
return lvm2_run(_lvm_handle, cmdline);
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (C) 2010 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Wrappers around liblvm2cmd functions for dmeventd plug-ins.
*
* liblvm2cmd is not thread-safe so the locking in this library helps dmeventd
* threads to co-operate in sharing a single instance.
*
* FIXME Either support this properly as a generic liblvm2cmd wrapper or make
* liblvm2cmd thread-safe so this can go away.
*/
#include "libdevmapper.h"
#ifndef _DMEVENTD_LVMWRAP_H
#define _DMEVENTD_LVMWRAP_H
int dmeventd_lvm2_init(void);
void dmeventd_lvm2_exit(void);
int dmeventd_lvm2_run(const char *cmdline);
void dmeventd_lvm2_lock(void);
void dmeventd_lvm2_unlock(void);
struct dm_pool *dmeventd_lvm2_pool(void);
#endif /* _DMEVENTD_LVMWRAP_H */

View File

@@ -1,6 +1,6 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2005, 2008 Red Hat, Inc. All rights reserved.
# Copyright (C) 2004-2005, 2008-2010 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
@@ -14,22 +14,24 @@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
top_builddir = @top_builddir@
INCLUDES += -I${top_srcdir}/tools
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper $(LVM2CMD_LIB)
INCLUDES += -I$(top_srcdir)/tools -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
CLDFLAGS += -L$(top_builddir)/tools -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
SOURCES = dmeventd_mirror.c
ifeq ("@LIB_SUFFIX@","dylib")
LIB_SHARED = libdevmapper-event-lvm2mirror.dylib
else
LIB_SHARED = libdevmapper-event-lvm2mirror.so
endif
LIB_NAME = libdevmapper-event-lvm2mirror
LIB_SHARED = $(LIB_NAME).$(LIB_SUFFIX)
LIB_VERSION = $(LIB_VERSION_LVM)
include $(top_srcdir)/make.tmpl
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
install: libdevmapper-event-lvm2mirror.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/$<.$(LIB_VERSION)
$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<
include $(top_builddir)/make.tmpl
LIBS += -ldevmapper-event-lvm2 -ldevmapper
install_lvm2: install_dm_plugin
install: install_lvm2

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005 Red Hat, Inc. All rights reserved.
* Copyright (C) 2005-2010 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -12,43 +12,51 @@
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lvm2cmd.h"
#include "lib.h"
#include <libdevmapper.h>
#include <libdevmapper-event.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include "lvm2cmd.h"
#include "errors.h"
#include "libdevmapper-event.h"
#include "dmeventd_lvm.h"
#include <syslog.h> /* FIXME Replace syslog with multilog */
/* FIXME Missing openlog? */
/* FIXME Replace most syslogs with log_error() style messages and add complete context. */
/* FIXME Reformat to 80 char lines. */
#define ME_IGNORE 0
#define ME_INSYNC 1
#define ME_FAILURE 2
/*
* register_device() is called first and performs initialisation.
* Only one device may be registered or unregistered at a time.
*/
static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER;
static int _process_status_code(const char status_code, const char *dev_name,
const char *dev_type, int r)
{
/*
* A => Alive - No failures
* D => Dead - A write failure occurred leaving mirror out-of-sync
* F => Flush failed.
* S => Sync - A sychronization failure occurred, mirror out-of-sync
* R => Read - A read failure occurred, mirror data unaffected
* U => Unclassified failure (bug)
*/
if (status_code == 'F') {
syslog(LOG_ERR, "%s device %s flush failed.",
dev_type, dev_name);
r = ME_FAILURE;
} else if (status_code == 'S')
syslog(LOG_ERR, "%s device %s sync failed.",
dev_type, dev_name);
else if (status_code == 'R')
syslog(LOG_ERR, "%s device %s read failed.",
dev_type, dev_name);
else if (status_code != 'A') {
syslog(LOG_ERR, "%s device %s has failed (%c).",
dev_type, dev_name, status_code);
r = ME_FAILURE;
}
/*
* Number of active registrations.
*/
static int _register_count = 0;
static struct dm_pool *_mem_pool = NULL;
static void *_lvm_handle = NULL;
/*
* Currently only one event can be processed at a time.
*/
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
return r;
}
static int _get_mirror_event(char *params)
{
@@ -89,17 +97,14 @@ static int _get_mirror_event(char *params)
/* Check for bad mirror devices */
for (i = 0; i < num_devs; i++)
if (dev_status_str[i] == 'D') {
syslog(LOG_ERR, "Mirror device, %s, has failed.\n", args[i]);
r = ME_FAILURE;
}
r = _process_status_code(dev_status_str[i], args[i],
i ? "Secondary mirror" : "Primary mirror", r);
/* Check for bad disk log device */
if (log_argc > 1 && log_status_str[0] == 'D') {
syslog(LOG_ERR, "Log device, %s, has failed.\n",
args[2 + num_devs + log_argc]);
r = ME_FAILURE;
}
if (log_argc > 1)
r = _process_status_code(log_status_str[0],
args[2 + num_devs + log_argc],
"Log", r);
if (r == ME_FAILURE)
goto out;
@@ -114,27 +119,15 @@ static int _get_mirror_event(char *params)
goto out_parse;
out:
if (args)
dm_free(args);
dm_free(args);
return r;
out_parse:
if (args)
dm_free(args);
dm_free(args);
syslog(LOG_ERR, "Unable to parse mirror status string.");
return ME_IGNORE;
}
static void _temporary_log_fn(int level, const char *file __attribute((unused)),
int line __attribute((unused)),
const char *format)
{
if (!strncmp(format, "WARNING: ", 9) && (level < 5))
syslog(LOG_CRIT, "%s", format);
else
syslog(LOG_DEBUG, "%s", format);
}
static int _remove_failed_devices(const char *device)
{
int r;
@@ -145,29 +138,35 @@ static int _remove_failed_devices(const char *device)
if (strlen(device) > 200) /* FIXME Use real restriction */
return -ENAMETOOLONG; /* FIXME These return code distinctions are not used so remove them! */
if (!dm_split_lvm_name(_mem_pool, device, &vg, &lv, &layer)) {
syslog(LOG_ERR, "Unable to determine VG name from %s",
if (!dm_split_lvm_name(dmeventd_lvm2_pool(), device, &vg, &lv, &layer)) {
syslog(LOG_ERR, "Unable to determine VG name from %s.",
device);
return -ENOMEM; /* FIXME Replace with generic error return - reason for failure has already got logged */
}
/* strip off the mirror component designations */
layer = strstr(lv, "_mlog");
if (layer)
*layer = '\0';
/* FIXME Is any sanity-checking required on %s? */
if (CMD_SIZE <= snprintf(cmd_str, CMD_SIZE, "vgreduce --config devices{ignore_suspended_devices=1} --removemissing %s", vg)) {
if (CMD_SIZE <= snprintf(cmd_str, CMD_SIZE, "lvconvert --config devices{ignore_suspended_devices=1} --repair --use-policies %s/%s", vg, lv)) {
/* this error should be caught above, but doesn't hurt to check again */
syslog(LOG_ERR, "Unable to form LVM command: Device name too long");
dm_pool_empty(_mem_pool); /* FIXME: not safe with multiple threads */
syslog(LOG_ERR, "Unable to form LVM command: Device name too long.");
return -ENAMETOOLONG; /* FIXME Replace with generic error return - reason for failure has already got logged */
}
r = lvm2_run(_lvm_handle, cmd_str);
r = dmeventd_lvm2_run(cmd_str);
dm_pool_empty(_mem_pool); /* FIXME: not safe with multiple threads */
return (r == 1) ? 0 : -1;
syslog(LOG_INFO, "Repair of mirrored LV %s/%s %s.", vg, lv,
(r == ECMD_PROCESSED) ? "finished successfully" : "failed");
return (r == ECMD_PROCESSED) ? 0 : -1;
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute((unused)),
void **unused __attribute((unused)))
enum dm_event_mask event __attribute__((unused)),
void **unused __attribute__((unused)))
{
void *next = NULL;
uint64_t start, length;
@@ -175,21 +174,19 @@ void process_event(struct dm_task *dmt,
char *params;
const char *device = dm_task_get_name(dmt);
if (pthread_mutex_trylock(&_event_mutex)) {
syslog(LOG_NOTICE, "Another thread is handling an event. Waiting...");
pthread_mutex_lock(&_event_mutex);
}
dmeventd_lvm2_lock();
do {
next = dm_get_next_target(dmt, next, &start, &length,
&target_type, &params);
if (!target_type) {
syslog(LOG_INFO, "%s mapping lost.\n", device);
syslog(LOG_INFO, "%s mapping lost.", device);
continue;
}
if (strcmp(target_type, "mirror")) {
syslog(LOG_INFO, "%s has unmirrored portion.\n", device);
syslog(LOG_INFO, "%s has unmirrored portion.", device);
continue;
}
@@ -199,13 +196,13 @@ void process_event(struct dm_task *dmt,
_part_ of the device is in sync
Also, this is not an error
*/
syslog(LOG_NOTICE, "%s is now in-sync\n", device);
syslog(LOG_NOTICE, "%s is now in-sync.", device);
break;
case ME_FAILURE:
syslog(LOG_ERR, "Device failure in %s\n", device);
syslog(LOG_ERR, "Device failure in %s.", device);
if (_remove_failed_devices(device))
/* FIXME Why are all the error return codes unused? Get rid of them? */
syslog(LOG_ERR, "Failed to remove faulty devices in %s\n",
syslog(LOG_ERR, "Failed to remove faulty devices in %s.",
device);
/* Should check before warning user that device is now linear
else
@@ -217,73 +214,32 @@ void process_event(struct dm_task *dmt,
break;
default:
/* FIXME Provide value then! */
syslog(LOG_INFO, "Unknown event received.\n");
syslog(LOG_INFO, "Unknown event received.");
}
} while (next);
pthread_mutex_unlock(&_event_mutex);
dmeventd_lvm2_unlock();
}
int register_device(const char *device,
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
void **unused __attribute((unused)))
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **unused __attribute__((unused)))
{
int r = 0;
pthread_mutex_lock(&_register_mutex);
syslog(LOG_INFO, "Monitoring mirror device %s for events\n", device);
/*
* Need some space for allocations. 1024 should be more
* than enough for what we need (device mapper name splitting)
*/
if (!_mem_pool && !(_mem_pool = dm_pool_create("mirror_dso", 1024)))
goto out;
if (!_lvm_handle) {
lvm2_log_fn(_temporary_log_fn);
if (!(_lvm_handle = lvm2_init())) {
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
goto out;
}
lvm2_log_level(_lvm_handle, LVM2_LOG_SUPPRESS);
/* FIXME Temporary: move to dmeventd core */
lvm2_run(_lvm_handle, "_memlock_inc");
}
_register_count++;
r = 1;
out:
pthread_mutex_unlock(&_register_mutex);
int r = dmeventd_lvm2_init();
syslog(LOG_INFO, "Monitoring mirror device %s for events.", device);
return r;
}
int unregister_device(const char *device,
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
void **unused __attribute((unused)))
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **unused __attribute__((unused)))
{
pthread_mutex_lock(&_register_mutex);
syslog(LOG_INFO, "No longer monitoring mirror device %s for events\n",
syslog(LOG_INFO, "No longer monitoring mirror device %s for events.",
device);
if (!--_register_count) {
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
lvm2_run(_lvm_handle, "_memlock_dec");
lvm2_exit(_lvm_handle);
_lvm_handle = NULL;
}
pthread_mutex_unlock(&_register_mutex);
dmeventd_lvm2_exit();
return 1;
}

View File

@@ -1,6 +1,6 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
# Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
#
# This file is part of the LVM2.
#
@@ -14,22 +14,20 @@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
top_builddir = @top_builddir@
INCLUDES += -I${top_srcdir}/tools
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper $(LVM2CMD_LIB)
INCLUDES += -I$(top_srcdir)/tools -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
CLDFLAGS += -L$(top_builddir)/tools -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
SOURCES = dmeventd_snapshot.c
ifeq ("@LIB_SUFFIX@","dylib")
LIB_SHARED = libdevmapper-event-lvm2snapshot.dylib
else
LIB_SHARED = libdevmapper-event-lvm2snapshot.so
endif
LIB_SHARED = libdevmapper-event-lvm2snapshot.$(LIB_SUFFIX)
LIB_VERSION = $(LIB_VERSION_LVM)
include $(top_srcdir)/make.tmpl
include $(top_builddir)/make.tmpl
install: libdevmapper-event-lvm2snapshot.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/$<.$(LIB_VERSION)
$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<
LIBS += -ldevmapper-event-lvm2 -ldevmapper
install_lvm2: install_dm_plugin
install: install_lvm2

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2008 Red Hat, Inc. All rights reserved.
* Copyright (C) 2007-2010 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -12,18 +12,14 @@
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "libdevmapper.h"
#include "libdevmapper-event.h"
#include "lvm2cmd.h"
#include "lvm-string.h"
#include "lib.h"
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include "lvm2cmd.h"
#include "errors.h"
#include "libdevmapper-event.h"
#include "dmeventd_lvm.h"
#include "lvm-string.h"
#include <syslog.h> /* FIXME Replace syslog with multilog */
/* FIXME Missing openlog? */
@@ -33,41 +29,15 @@
/* Further warnings at 85%, 90% and 95% fullness. */
#define WARNING_STEP 5
static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER;
/*
* Number of active registrations.
*/
static int _register_count = 0;
static struct dm_pool *_mem_pool = NULL;
static void *_lvm_handle = NULL;
struct snap_status {
int invalid;
int used;
int max;
};
/*
* Currently only one event can be processed at a time.
*/
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
static void _temporary_log_fn(int level,
const char *file __attribute((unused)),
int line __attribute((unused)),
const char *format)
{
if (!strncmp(format, "WARNING: ", 9) && (level < 5))
syslog(LOG_CRIT, "%s", format);
else
syslog(LOG_DEBUG, "%s", format);
}
/* FIXME possibly reconcile this with target_percent when we gain
access to regular LVM library here. */
static void _parse_snapshot_params(char *params, struct snap_status *stat)
static void _parse_snapshot_params(char *params, struct snap_status *status)
{
char *p;
/*
@@ -75,10 +45,10 @@ static void _parse_snapshot_params(char *params, struct snap_status *stat)
* Invalid -- snapshot invalidated
* Unknown -- status unknown
*/
stat->used = stat->max = 0;
status->used = status->max = 0;
if (!strncmp(params, "Invalid", 7)) {
stat->invalid = 1;
status->invalid = 1;
return;
}
@@ -95,37 +65,19 @@ static void _parse_snapshot_params(char *params, struct snap_status *stat)
*p = '\0';
p++;
stat->used = atoi(params);
stat->max = atoi(p);
}
/* send unregister command to itself */
static void _unregister_self(struct dm_task *dmt)
{
const char *name = dm_task_get_name(dmt);
struct dm_event_handler *dmevh;
if (!(dmevh = dm_event_handler_create()))
return;
if (dm_event_handler_set_dev_name(dmevh, name))
goto fail;
dm_event_handler_set_event_mask(dmevh, DM_EVENT_ALL_ERRORS|DM_EVENT_TIMEOUT);
dm_event_unregister_handler(dmevh);
fail:
dm_event_handler_destroy(dmevh);
status->used = atoi(params);
status->max = atoi(p);
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute((unused)),
enum dm_event_mask event __attribute__((unused)),
void **private)
{
void *next = NULL;
uint64_t start, length;
char *target_type = NULL;
char *params;
struct snap_status stat = { 0 };
struct snap_status status = { 0 };
const char *device = dm_task_get_name(dmt);
int percent, *percent_warning = (int*)private;
@@ -133,100 +85,56 @@ void process_event(struct dm_task *dmt,
if (!*percent_warning)
return;
if (pthread_mutex_trylock(&_event_mutex)) {
syslog(LOG_NOTICE, "Another thread is handling an event. Waiting...");
pthread_mutex_lock(&_event_mutex);
}
dmeventd_lvm2_lock();
dm_get_next_target(dmt, next, &start, &length, &target_type, &params);
if (!target_type)
goto out;
_parse_snapshot_params(params, &stat);
_parse_snapshot_params(params, &status);
/*
* If the snapshot has been invalidated or we failed to parse
* the status string. Report the full status string to syslog.
*/
if (stat.invalid || !stat.max) {
if (status.invalid || !status.max) {
syslog(LOG_ERR, "Snapshot %s changed state to: %s\n", device, params);
_unregister_self(dmt);
*percent_warning = 0;
goto out;
}
percent = 100 * stat.used / stat.max;
percent = 100 * status.used / status.max;
if (percent >= *percent_warning) {
syslog(LOG_WARNING, "Snapshot %s is now %i%% full.\n", device, percent);
/* Print warning on the next multiple of WARNING_STEP. */
*percent_warning = (percent / WARNING_STEP) * WARNING_STEP + WARNING_STEP;
}
out:
pthread_mutex_unlock(&_event_mutex);
dmeventd_lvm2_unlock();
}
int register_device(const char *device,
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **private)
{
int r = 0;
int *percent_warning = (int*)private;
pthread_mutex_lock(&_register_mutex);
/*
* Need some space for allocations. 1024 should be more
* than enough for what we need (device mapper name splitting)
*/
if (!_mem_pool && !(_mem_pool = dm_pool_create("snapshot_dso", 1024)))
goto out;
int r = dmeventd_lvm2_init();
*percent_warning = WARNING_THRESH; /* Print warning if snapshot is full */
if (!_lvm_handle) {
lvm2_log_fn(_temporary_log_fn);
if (!(_lvm_handle = lvm2_init())) {
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
goto out;
}
lvm2_log_level(_lvm_handle, LVM2_LOG_SUPPRESS);
/* FIXME Temporary: move to dmeventd core */
lvm2_run(_lvm_handle, "_memlock_inc");
}
syslog(LOG_INFO, "Monitoring snapshot %s\n", device);
_register_count++;
r = 1;
out:
pthread_mutex_unlock(&_register_mutex);
return r;
}
int unregister_device(const char *device,
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
void **unused __attribute((unused)))
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **unused __attribute__((unused)))
{
pthread_mutex_lock(&_register_mutex);
syslog(LOG_INFO, "No longer monitoring snapshot %s\n",
device);
if (!--_register_count) {
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
lvm2_run(_lvm_handle, "_memlock_dec");
lvm2_exit(_lvm_handle);
_lvm_handle = NULL;
}
pthread_mutex_unlock(&_register_mutex);
dmeventd_lvm2_exit();
return 1;
}

View File

@@ -1,6 +0,0 @@
LVM2 requires the device-mapper kernel module (dm-mod). This is
available as a kernel patch for 2.4 (in kernel-patch-device-mapper), and
is distributed with linux 2.5 and above. The LVM1 kernel module (lvm-mod)
will not work with lvm2 packages. dm-mod and lvm-mod may both be loaded
in the kernel at the same time with no problems. Without dm-mod, this
package is pretty useless.

82
debian/changelog vendored
View File

@@ -1,82 +0,0 @@
lvm2 (1.95.15-1) unstable; urgency=low
* New upstream release.
* Remove undocumented manpage symlinks.
* Update description to be more informative. (Closes: #173499)
* Add kernel-patch-device-mapper suggestion.
* Update standards version.
-- Andres Salomon <dilinger@mp3revolution.net> Sun, 16 Feb 2002 04:21:26 -0400
lvm2 (1.95.11-1) unstable; urgency=low
* New upstream release. (Closes: #171436)
* Removed TODO and INTRO from debian/docs; added WHATS_NEW.
* Remove vgcfgrestore.8 undocumented symlink.
* Added a README.Debian, mentioning the device-mapper kernel module
requirement that lvm2 has. (Closes: #171674, #163020)
* Get rid of debian/conffiles (debhelper's smart enough to figure that out).
* debian/copyright fix to appease lintian.
* Fix typo in tools/commands.h that caused /usr/sbin/; to be created.
-- Andres Salomon <dilinger@mp3revolution.net> Mon, 9 Dec 2002 02:51:02 -0400
lvm2 (1.95.10-2) unstable; urgency=low
* Fix software raid problems by ensuring lvm init script runs after
raidtools init script. (Closes: #152569)
-- Andres Salomon <dilinger@mp3revolution.net> Tue, 3 Sep 2002 04:05:43 -0400
lvm2 (1.95.10-1) unstable; urgency=low
* New upstream release (Beta 3.2).
* Change all references to /dev/device-mapper/control to
/dev/mapper/control.
-- Andres Salomon <dilinger@mp3revolution.net> Sun, 1 Sep 2002 18:55:12 -0400
lvm2 (0.95.05-3) unstable; urgency=low
* Get rid of awk dependency in init script. (Closes: #146257)
-- Andres Salomon <dilinger@mp3revolution.net> Sun, 12 May 2002 04:39:06 -0500
lvm2 (0.95.05-2) unstable; urgency=low
* Use ${shlibs:Depends} in Depends.
* Get rid of postinst/postrm scripts, use debhelper's init script instead.
* Add Conflicts against lvm10, lvm-common.
* Fix endian issues on big-endian machines.
-- Andres Salomon <dilinger@mp3revolution.net> Thu, 2 May 2002 23:53:53 -0500
lvm2 (0.95.05-1) unstable; urgency=low
* New release (Beta2).
-- Andres Salomon <dilinger@mp3revolution.net> Thu, 25 Apr 2002 00:37:41 -0500
lvm2 (0.95.04cvs20020306-1) unstable; urgency=low
* CVS updated.
* Convert from debian native package.
-- Andres Salomon <dilinger@mp3revolution.net> Wed, 6 Mar 2002 00:43:21 -0500
lvm2 (0.95.04cvs20020304) unstable; urgency=low
* CVS updated.
* Enhance init script; create devmapper control device, etc.
* Add dmsetup as a suggestion.
* Add /etc/lvm/lvm.conf conffile.
* Add undocumented(7) for the commands missing manpages.
-- Andres Salomon <dilinger@mp3revolution.net> Mon, 4 Mar 2002 04:51:26 -0500
lvm2 (0.95.02cvs20020220) unstable; urgency=low
* Initial Release.
-- Andres Salomon <dilinger@mp3revolution.net> Wed, 20 Feb 2002 03:17:25 -0500

24
debian/control vendored
View File

@@ -1,24 +0,0 @@
Source: lvm2
Section: admin
Priority: optional
Maintainer: Andres Salomon <dilinger@mp3revolution.net>
Build-Depends: debhelper (>> 3.0.0), libdevmapper-dev (>= 0.96.04), libreadline4-dev
Standards-Version: 3.5.8.0
Package: lvm2
Architecture: any
Depends: ${shlibs:Depends}
Conflicts: lvm10, lvm-common
Replaces: lvm10, lvm-common
Provides: lvm-binaries
Suggests: dmsetup, kernel-patch-device-mapper
Description: The Linux Logical Volume Manager
This is LVM2, the rewrite of The Linux Logical Volume Manager. LVM
supports enterprise level volume management of disk and disk subsystems
by grouping arbitrary disks into volume groups. The total capacity of
volume groups can be allocated to logical volumes, which are accessed as
regular block devices.
.
LVM2 is currently stable, but has some unimplemented features (most notably,
pvmove and e2fsadm). It is not yet recommended for production use. It is
backwards-compatible with LVM1 (lvm10), and requires Linux kernel 2.4.

25
debian/copyright vendored
View File

@@ -1,25 +0,0 @@
This package was debianized by Andres Salomon <dilinger@mp3revolution.net> on
Wed, 20 Feb 2002 03:17:25 -0500.
It was downloaded from http://www.sistina.com/products_lvm.htm
Upstream Author: LVM Development Team
Copyright (c) 2001-2002 LVM Development Team
LVM2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
LVM2 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
On Debian systems, the full text of the GPL can be found in
/usr/share/common-licenses/GPL

4
debian/dirs vendored
View File

@@ -1,4 +0,0 @@
etc/lvm
usr/share/man/man5
usr/share/man/man8
sbin

5
debian/docs vendored
View File

@@ -1,5 +0,0 @@
BUGS
README
VERSION
WHATS_NEW
doc/*

64
debian/init.d vendored
View File

@@ -1,64 +0,0 @@
#! /bin/sh
#
# lvm2 This script handles LVM2 initialization/shutdown.
#
# Written by Andres Salomon <dilinger@mp3revolution.net>.
#
PATH=/sbin:/bin:/usr/sbin:/usr/bin
NAME=lvm2
DESC=LVM
test -x /sbin/vgchange || exit 0
modprobe dm-mod >/dev/null 2>&1
# Create necessary files in /dev for device-mapper
create_devfiles() {
DIR="/dev/mapper"
FILE="$DIR/control"
major=$(grep "[0-9] misc$" /proc/devices | sed 's/[ ]\+misc//')
minor=$(grep "[0-9] device-mapper$" /proc/misc | sed 's/[ ]\+device-mapper//')
if test ! -d $DIR; then
mkdir --mode=755 $DIR >/dev/null 2>&1
fi
if test ! -c $FILE -a ! -z "$minor"; then
mknod --mode=600 $FILE c $major $minor >/dev/null 2>&1
fi
}
case "$1" in
start)
echo -n "Initializing $DESC: "
create_devfiles
vgchange -a y
# # Mount all LVM devices
# for vg in $( vgchange -a y 2>/dev/null | grep active | awk -F\" '{print $2}' ); do
# MTPT=$( grep $vg /etc/fstab | awk '{print $2}' )
# mount $MTPT
# done
echo "$NAME."
;;
stop)
echo -n "Shutting down $DESC: "
# We don't really try all that hard to shut it down; far too many
# things that can keep it from successfully shutting down.
vgchange -a n
echo "$NAME."
;;
restart|force-reload)
echo -n "Restarting $DESC: "
vgchange -a n
sleep 1
vgchange -a y
echo "$NAME."
;;
*)
echo "Usage: /etc/init.d/$NAME {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0

26
debian/manpages vendored
View File

@@ -1,26 +0,0 @@
debian/lvm2/usr/share/man/man5/lvm.conf.5
debian/lvm2/usr/share/man/man8/lvchange.8
debian/lvm2/usr/share/man/man8/lvcreate.8
debian/lvm2/usr/share/man/man8/lvdisplay.8
debian/lvm2/usr/share/man/man8/lvextend.8
debian/lvm2/usr/share/man/man8/lvm.8
debian/lvm2/usr/share/man/man8/lvmchange.8
debian/lvm2/usr/share/man/man8/lvreduce.8
debian/lvm2/usr/share/man/man8/lvremove.8
debian/lvm2/usr/share/man/man8/lvrename.8
debian/lvm2/usr/share/man/man8/lvscan.8
debian/lvm2/usr/share/man/man8/pvchange.8
debian/lvm2/usr/share/man/man8/pvcreate.8
debian/lvm2/usr/share/man/man8/pvdisplay.8
debian/lvm2/usr/share/man/man8/pvscan.8
debian/lvm2/usr/share/man/man8/vgcfgbackup.8
debian/lvm2/usr/share/man/man8/vgchange.8
debian/lvm2/usr/share/man/man8/vgck.8
debian/lvm2/usr/share/man/man8/vgcreate.8
debian/lvm2/usr/share/man/man8/vgdisplay.8
debian/lvm2/usr/share/man/man8/vgextend.8
debian/lvm2/usr/share/man/man8/vgmerge.8
debian/lvm2/usr/share/man/man8/vgreduce.8
debian/lvm2/usr/share/man/man8/vgremove.8
debian/lvm2/usr/share/man/man8/vgrename.8
debian/lvm2/usr/share/man/man8/vgscan.8

119
debian/rules vendored
View File

@@ -1,119 +0,0 @@
#!/usr/bin/make -f
# Sample debian/rules that uses debhelper.
# GNU copyright 1997 by Joey Hess.
#
# This version is for a hypothetical package that builds an
# architecture-dependant package, as well as an architecture-independent
# package.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
# This is the debhelper compatibility version to use.
export DH_COMPAT=3
# These are used for cross-compiling and for saving the configure script
# from having to guess our platform (since we know it already)
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
CFLAGS += -g
endif
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
INSTALL_PROGRAM += -s
endif
configure: configure-stamp
configure-stamp:
dh_testdir
# Add here commands to configure the package.
./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/ --mandir=\$${prefix}/usr/share/man --infodir=\$${prefix}/usr/share/info
touch configure-stamp
build-arch: configure-stamp build-arch-stamp
build-arch-stamp:
dh_testdir
# Add here command to compile/build the package.
$(MAKE)
touch build-arch-stamp
build-indep: configure-stamp build-indep-stamp
build-indep-stamp:
dh_testdir
# Add here command to compile/build the arch indep package.
# It's ok not to do anything here, if you don't need to build
# anything for this package.
#/usr/bin/docbook-to-man debian/lvm2.sgml > lvm2.1
touch build-indep-stamp
build: build-arch build-indep
clean:
dh_testdir
dh_testroot
rm -f build-stamp configure-stamp
# Add here commands to clean up after the build process.
-$(MAKE) distclean
-test -r /usr/share/misc/config.sub && \
cp -f /usr/share/misc/config.sub config.sub
-test -r /usr/share/misc/config.guess && \
cp -f /usr/share/misc/config.guess config.guess
dh_clean
install: DH_OPTIONS=
install: build
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
# Add here commands to install the package into debian/lvm2.
$(MAKE) install prefix=$(CURDIR)/debian/lvm2
install -m 0644 doc/example.conf debian/lvm2/etc/lvm/lvm.conf
# Build architecture-independent files here.
# Pass -i to all debhelper commands in this target to reduce clutter.
binary-indep: build install
# nada.
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
# dh_installdebconf
dh_installdocs
dh_installexamples
# dh_installlogrotate -a
# dh_installemacsen -a
# dh_installpam -a
# dh_installmime -a
dh_installinit --update-rcd-params="start 26 S . start 50 0 6 ."
dh_installcron
dh_installman
dh_installinfo
dh_installchangelogs
dh_strip
dh_link
dh_compress
dh_fixperms
dh_makeshlibs
dh_installdeb
# dh_perl -a
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install configure

View File

@@ -1,3 +0,0 @@
process_event
register_device
unregister_device

View File

@@ -1,35 +0,0 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2005, 2008 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
INCLUDES += -I${top_srcdir}/tools
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper $(LVM2CMD_LIB)
SOURCES = dmeventd_mirror.c
ifeq ("@LIB_SUFFIX@","dylib")
LIB_SHARED = libdevmapper-event-lvm2mirror.dylib
else
LIB_SHARED = libdevmapper-event-lvm2mirror.so
endif
include $(top_srcdir)/make.tmpl
install: libdevmapper-event-lvm2mirror.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/$<.$(LIB_VERSION)
$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<

View File

@@ -1,289 +0,0 @@
/*
* Copyright (C) 2005 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU 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 "lvm2cmd.h"
#include <libdevmapper.h>
#include <libdevmapper-event.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <syslog.h> /* FIXME Replace syslog with multilog */
/* FIXME Missing openlog? */
#define ME_IGNORE 0
#define ME_INSYNC 1
#define ME_FAILURE 2
/*
* register_device() is called first and performs initialisation.
* Only one device may be registered or unregistered at a time.
*/
static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER;
/*
* Number of active registrations.
*/
static int _register_count = 0;
static struct dm_pool *_mem_pool = NULL;
static void *_lvm_handle = NULL;
/*
* Currently only one event can be processed at a time.
*/
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
static int _get_mirror_event(char *params)
{
int i, r = ME_INSYNC;
char **args = NULL;
char *dev_status_str;
char *log_status_str;
char *sync_str;
char *p = NULL;
int log_argc, num_devs;
/*
* dm core parms: 0 409600 mirror
* Mirror core parms: 2 253:4 253:5 400/400
* New-style failure params: 1 AA
* New-style log params: 3 cluster 253:3 A
* or 3 disk 253:3 A
* or 1 core
*/
/* number of devices */
if (!dm_split_words(params, 1, 0, &p))
goto out_parse;
if (!(num_devs = atoi(p)))
goto out_parse;
p += strlen(p) + 1;
/* devices names + "400/400" + "1 AA" + 1 or 3 log parms + NULL */
args = dm_malloc((num_devs + 7) * sizeof(char *));
if (!args || dm_split_words(p, num_devs + 7, 0, args) < num_devs + 5)
goto out_parse;
dev_status_str = args[2 + num_devs];
log_argc = atoi(args[3 + num_devs]);
log_status_str = args[3 + num_devs + log_argc];
sync_str = args[num_devs];
/* Check for bad mirror devices */
for (i = 0; i < num_devs; i++)
if (dev_status_str[i] == 'D') {
syslog(LOG_ERR, "Mirror device, %s, has failed.\n", args[i]);
r = ME_FAILURE;
}
/* Check for bad disk log device */
if (log_argc > 1 && log_status_str[0] == 'D') {
syslog(LOG_ERR, "Log device, %s, has failed.\n",
args[2 + num_devs + log_argc]);
r = ME_FAILURE;
}
if (r == ME_FAILURE)
goto out;
p = strstr(sync_str, "/");
if (p) {
p[0] = '\0';
if (strcmp(sync_str, p+1))
r = ME_IGNORE;
p[0] = '/';
} else
goto out_parse;
out:
if (args)
dm_free(args);
return r;
out_parse:
if (args)
dm_free(args);
syslog(LOG_ERR, "Unable to parse mirror status string.");
return ME_IGNORE;
}
static void _temporary_log_fn(int level, const char *file __attribute((unused)),
int line __attribute((unused)),
const char *format)
{
if (!strncmp(format, "WARNING: ", 9) && (level < 5))
syslog(LOG_CRIT, "%s", format);
else
syslog(LOG_DEBUG, "%s", format);
}
static int _remove_failed_devices(const char *device)
{
int r;
#define CMD_SIZE 256 /* FIXME Use system restriction */
char cmd_str[CMD_SIZE];
char *vg = NULL, *lv = NULL, *layer = NULL;
if (strlen(device) > 200) /* FIXME Use real restriction */
return -ENAMETOOLONG; /* FIXME These return code distinctions are not used so remove them! */
if (!dm_split_lvm_name(_mem_pool, device, &vg, &lv, &layer)) {
syslog(LOG_ERR, "Unable to determine VG name from %s",
device);
return -ENOMEM; /* FIXME Replace with generic error return - reason for failure has already got logged */
}
/* FIXME Is any sanity-checking required on %s? */
if (CMD_SIZE <= snprintf(cmd_str, CMD_SIZE, "vgreduce --config devices{ignore_suspended_devices=1} --removemissing %s", vg)) {
/* this error should be caught above, but doesn't hurt to check again */
syslog(LOG_ERR, "Unable to form LVM command: Device name too long");
dm_pool_empty(_mem_pool); /* FIXME: not safe with multiple threads */
return -ENAMETOOLONG; /* FIXME Replace with generic error return - reason for failure has already got logged */
}
r = lvm2_run(_lvm_handle, cmd_str);
dm_pool_empty(_mem_pool); /* FIXME: not safe with multiple threads */
return (r == 1) ? 0 : -1;
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute((unused)),
void **unused __attribute((unused)))
{
void *next = NULL;
uint64_t start, length;
char *target_type = NULL;
char *params;
const char *device = dm_task_get_name(dmt);
if (pthread_mutex_trylock(&_event_mutex)) {
syslog(LOG_NOTICE, "Another thread is handling an event. Waiting...");
pthread_mutex_lock(&_event_mutex);
}
do {
next = dm_get_next_target(dmt, next, &start, &length,
&target_type, &params);
if (!target_type) {
syslog(LOG_INFO, "%s mapping lost.\n", device);
continue;
}
if (strcmp(target_type, "mirror")) {
syslog(LOG_INFO, "%s has unmirrored portion.\n", device);
continue;
}
switch(_get_mirror_event(params)) {
case ME_INSYNC:
/* FIXME: all we really know is that this
_part_ of the device is in sync
Also, this is not an error
*/
syslog(LOG_NOTICE, "%s is now in-sync\n", device);
break;
case ME_FAILURE:
syslog(LOG_ERR, "Device failure in %s\n", device);
if (_remove_failed_devices(device))
/* FIXME Why are all the error return codes unused? Get rid of them? */
syslog(LOG_ERR, "Failed to remove faulty devices in %s\n",
device);
/* Should check before warning user that device is now linear
else
syslog(LOG_NOTICE, "%s is now a linear device.\n",
device);
*/
break;
case ME_IGNORE:
break;
default:
/* FIXME Provide value then! */
syslog(LOG_INFO, "Unknown event received.\n");
}
} while (next);
pthread_mutex_unlock(&_event_mutex);
}
int register_device(const char *device,
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
void **unused __attribute((unused)))
{
int r = 0;
pthread_mutex_lock(&_register_mutex);
syslog(LOG_INFO, "Monitoring mirror device %s for events\n", device);
/*
* Need some space for allocations. 1024 should be more
* than enough for what we need (device mapper name splitting)
*/
if (!_mem_pool && !(_mem_pool = dm_pool_create("mirror_dso", 1024)))
goto out;
if (!_lvm_handle) {
lvm2_log_fn(_temporary_log_fn);
if (!(_lvm_handle = lvm2_init())) {
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
goto out;
}
lvm2_log_level(_lvm_handle, LVM2_LOG_SUPPRESS);
/* FIXME Temporary: move to dmeventd core */
lvm2_run(_lvm_handle, "_memlock_inc");
}
_register_count++;
r = 1;
out:
pthread_mutex_unlock(&_register_mutex);
return r;
}
int unregister_device(const char *device,
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
void **unused __attribute((unused)))
{
pthread_mutex_lock(&_register_mutex);
syslog(LOG_INFO, "No longer monitoring mirror device %s for events\n",
device);
if (!--_register_count) {
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
lvm2_run(_lvm_handle, "_memlock_dec");
lvm2_exit(_lvm_handle);
_lvm_handle = NULL;
}
pthread_mutex_unlock(&_register_mutex);
return 1;
}

View File

@@ -1,3 +0,0 @@
process_event
register_device
unregister_device

View File

@@ -1,35 +0,0 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
#
# This file is part of the LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
INCLUDES += -I${top_srcdir}/tools
CLDFLAGS += -L${top_srcdir}/tools -ldevmapper $(LVM2CMD_LIB)
SOURCES = dmeventd_snapshot.c
ifeq ("@LIB_SUFFIX@","dylib")
LIB_SHARED = libdevmapper-event-lvm2snapshot.dylib
else
LIB_SHARED = libdevmapper-event-lvm2snapshot.so
endif
include $(top_srcdir)/make.tmpl
install: libdevmapper-event-lvm2snapshot.$(LIB_SUFFIX)
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
$(libdir)/$<.$(LIB_VERSION)
$(LN_S) -f $<.$(LIB_VERSION) $(libdir)/$<

View File

@@ -1,232 +0,0 @@
/*
* Copyright (C) 2007-2008 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "libdevmapper.h"
#include "libdevmapper-event.h"
#include "lvm2cmd.h"
#include "lvm-string.h"
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <syslog.h> /* FIXME Replace syslog with multilog */
/* FIXME Missing openlog? */
/* First warning when snapshot is 80% full. */
#define WARNING_THRESH 80
/* Further warnings at 85%, 90% and 95% fullness. */
#define WARNING_STEP 5
static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER;
/*
* Number of active registrations.
*/
static int _register_count = 0;
static struct dm_pool *_mem_pool = NULL;
static void *_lvm_handle = NULL;
struct snap_status {
int invalid;
int used;
int max;
};
/*
* Currently only one event can be processed at a time.
*/
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
static void _temporary_log_fn(int level,
const char *file __attribute((unused)),
int line __attribute((unused)),
const char *format)
{
if (!strncmp(format, "WARNING: ", 9) && (level < 5))
syslog(LOG_CRIT, "%s", format);
else
syslog(LOG_DEBUG, "%s", format);
}
/* FIXME possibly reconcile this with target_percent when we gain
access to regular LVM library here. */
static void _parse_snapshot_params(char *params, struct snap_status *stat)
{
char *p;
/*
* xx/xx -- fractions used/max
* Invalid -- snapshot invalidated
* Unknown -- status unknown
*/
stat->used = stat->max = 0;
if (!strncmp(params, "Invalid", 7)) {
stat->invalid = 1;
return;
}
/*
* When we return without setting non-zero max, the parent is
* responsible for reporting errors.
*/
if (!strncmp(params, "Unknown", 7))
return;
if (!(p = strstr(params, "/")))
return;
*p = '\0';
p++;
stat->used = atoi(params);
stat->max = atoi(p);
}
/* send unregister command to itself */
static void _unregister_self(struct dm_task *dmt)
{
const char *name = dm_task_get_name(dmt);
struct dm_event_handler *dmevh;
if (!(dmevh = dm_event_handler_create()))
return;
if (dm_event_handler_set_dev_name(dmevh, name))
goto fail;
dm_event_handler_set_event_mask(dmevh, DM_EVENT_ALL_ERRORS|DM_EVENT_TIMEOUT);
dm_event_unregister_handler(dmevh);
fail:
dm_event_handler_destroy(dmevh);
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute((unused)),
void **private)
{
void *next = NULL;
uint64_t start, length;
char *target_type = NULL;
char *params;
struct snap_status stat = { 0 };
const char *device = dm_task_get_name(dmt);
int percent, *percent_warning = (int*)private;
/* No longer monitoring, waiting for remove */
if (!*percent_warning)
return;
if (pthread_mutex_trylock(&_event_mutex)) {
syslog(LOG_NOTICE, "Another thread is handling an event. Waiting...");
pthread_mutex_lock(&_event_mutex);
}
dm_get_next_target(dmt, next, &start, &length, &target_type, &params);
if (!target_type)
goto out;
_parse_snapshot_params(params, &stat);
/*
* If the snapshot has been invalidated or we failed to parse
* the status string. Report the full status string to syslog.
*/
if (stat.invalid || !stat.max) {
syslog(LOG_ERR, "Snapshot %s changed state to: %s\n", device, params);
_unregister_self(dmt);
*percent_warning = 0;
goto out;
}
percent = 100 * stat.used / stat.max;
if (percent >= *percent_warning) {
syslog(LOG_WARNING, "Snapshot %s is now %i%% full.\n", device, percent);
/* Print warning on the next multiple of WARNING_STEP. */
*percent_warning = (percent / WARNING_STEP) * WARNING_STEP + WARNING_STEP;
}
out:
pthread_mutex_unlock(&_event_mutex);
}
int register_device(const char *device,
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
void **private)
{
int r = 0;
int *percent_warning = (int*)private;
pthread_mutex_lock(&_register_mutex);
/*
* Need some space for allocations. 1024 should be more
* than enough for what we need (device mapper name splitting)
*/
if (!_mem_pool && !(_mem_pool = dm_pool_create("snapshot_dso", 1024)))
goto out;
*percent_warning = WARNING_THRESH; /* Print warning if snapshot is full */
if (!_lvm_handle) {
lvm2_log_fn(_temporary_log_fn);
if (!(_lvm_handle = lvm2_init())) {
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
goto out;
}
lvm2_log_level(_lvm_handle, LVM2_LOG_SUPPRESS);
/* FIXME Temporary: move to dmeventd core */
lvm2_run(_lvm_handle, "_memlock_inc");
}
syslog(LOG_INFO, "Monitoring snapshot %s\n", device);
_register_count++;
r = 1;
out:
pthread_mutex_unlock(&_register_mutex);
return r;
}
int unregister_device(const char *device,
const char *uuid __attribute((unused)),
int major __attribute((unused)),
int minor __attribute((unused)),
void **unused __attribute((unused)))
{
pthread_mutex_lock(&_register_mutex);
syslog(LOG_INFO, "No longer monitoring snapshot %s\n",
device);
if (!--_register_count) {
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
lvm2_run(_lvm_handle, "_memlock_dec");
lvm2_exit(_lvm_handle);
_lvm_handle = NULL;
}
pthread_mutex_unlock(&_register_mutex);
return 1;
}

View File

@@ -1,5 +1,5 @@
#
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
# Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
@@ -13,17 +13,19 @@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
top_builddir = @top_builddir@
CONFSRC=example.conf
CONFDEST=lvm.conf
include $(top_srcdir)/make.tmpl
include $(top_builddir)/make.tmpl
install:
install_lvm2: $(CONFSRC)
@if [ ! -e $(confdir)/$(CONFDEST) ]; then \
echo "Installing $(CONFSRC) as $(confdir)/$(CONFDEST)"; \
@INSTALL@ -D $(OWNER) $(GROUP) -m 644 $(CONFSRC) \
$(confdir)/$(CONFDEST); \
echo "$(INSTALL_WDATA) -D $< $(confdir)/$(CONFDEST)"; \
$(INSTALL_WDATA) -D $< $(confdir)/$(CONFDEST); \
fi
install: install_lvm2
DISTCLEAN_TARGETS += $(CONFSRC)

View File

@@ -1,10 +1,10 @@
# This is an example configuration file for the LVM2 system.
# It contains the default settings that would be used if there was no
# /etc/lvm/lvm.conf file.
# @DEFAULT_SYS_DIR@/lvm.conf file.
#
# Refer to 'man lvm.conf' for further information including the file layout.
#
# To put this file in a different directory and override /etc/lvm set
# To put this file in a different directory and override @DEFAULT_SYS_DIR@ set
# the environment variable LVM_SYSTEM_DIR before running the tools.
@@ -66,12 +66,12 @@ devices {
# The results of the filtering are cached on disk to avoid
# rescanning dud devices (which can take a very long time).
# By default this cache is stored in the /etc/lvm/cache directory
# By default this cache is stored in the @DEFAULT_SYS_DIR@/@DEFAULT_CACHE_SUBDIR@ directory
# in a file called '.cache'.
# It is safe to delete the contents: the tools regenerate it.
# (The old setting 'cache' is still respected if neither of
# these new ones is present.)
cache_dir = "/etc/lvm/cache"
cache_dir = "@DEFAULT_SYS_DIR@/@DEFAULT_CACHE_SUBDIR@"
cache_file_prefix = ""
# You can turn off writing this cache file by setting this to 0.
@@ -86,18 +86,53 @@ devices {
# If sysfs is mounted (2.6 kernels) restrict device scanning to
# the block devices it believes are valid.
# 1 enables; 0 disables.
sysfs_scan = 1
sysfs_scan = 1
# By default, LVM2 will ignore devices used as components of
# software RAID (md) devices by looking for md superblocks.
# 1 enables; 0 disables.
md_component_detection = 1
# By default, if a PV is placed directly upon an md device, LVM2
# will align its data blocks with the md device's stripe-width.
# 1 enables; 0 disables.
md_chunk_alignment = 1
# By default, the start of a PV's data area will be a multiple of
# the 'minimum_io_size' or 'optimal_io_size' exposed in sysfs.
# - minimum_io_size - the smallest request the device can perform
# w/o incurring a read-modify-write penalty (e.g. MD's chunk size)
# - optimal_io_size - the device's preferred unit of receiving I/O
# (e.g. MD's stripe width)
# minimum_io_size is used if optimal_io_size is undefined (0).
# If md_chunk_alignment is enabled, that detects the optimal_io_size.
# This setting takes precedence over md_chunk_alignment.
# 1 enables; 0 disables.
data_alignment_detection = 1
# Alignment (in KB) of start of data area when creating a new PV.
# If a PV is placed directly upon an md device and md_chunk_alignment or
# data_alignment_detection is enabled this parameter is ignored.
# Set to 0 for the default alignment of 1MB or page size, if larger.
data_alignment = 0
# By default, the start of the PV's aligned data area will be shifted by
# the 'alignment_offset' exposed in sysfs. This offset is often 0 but
# may be non-zero; e.g.: certain 4KB sector drives that compensate for
# windows partitioning will have an alignment_offset of 3584 bytes
# (sector 7 is the lowest aligned logical block, the 4KB sectors start
# at LBA -1, and consequently sector 63 is aligned on a 4KB boundary).
# 1 enables; 0 disables.
data_alignment_offset_detection = 1
# If, while scanning the system for PVs, LVM2 encounters a device-mapper
# device that has its I/O suspended, it waits for it to become accessible.
# Set this to 1 to skip such devices. This should only be needed
# in recovery situations.
ignore_suspended_devices = 0
# Allow use of pvcreate --uuid without requiring --restorefile.
require_restorefile_with_uuid = 1
}
# This section that allows you to configure the nature of the
@@ -124,7 +159,7 @@ log {
# There are 6 syslog-like log levels currently in use - 2 to 7 inclusive.
# 7 is the most verbose (LOG_DEBUG).
level = 0
# Format of output messages
# Whether or not (1 or 0) to indent messages according to their severity
indent = 1
@@ -160,7 +195,7 @@ backup {
# Where shall we keep it ?
# Remember to back up this directory regularly!
backup_dir = "/etc/lvm/backup"
backup_dir = "@DEFAULT_SYS_DIR@/@DEFAULT_BACKUP_SUBDIR@"
# Should we maintain an archive of old metadata configurations.
# Use 1 for Yes; 0 for No.
@@ -169,8 +204,8 @@ backup {
# Where should archived files go ?
# Remember to back up this directory regularly!
archive_dir = "/etc/lvm/archive"
archive_dir = "@DEFAULT_SYS_DIR@/@DEFAULT_ARCHIVE_SUBDIR@"
# What is the minimum number of archive files you wish to keep ?
retain_min = 10
@@ -188,7 +223,7 @@ shell {
# Miscellaneous global LVM2 settings
global {
# The file creation mask for any files and directories created.
# Interpreted as octal if the first digit is zero.
umask = 077
@@ -204,6 +239,13 @@ global {
# Default value for --units argument
units = "h"
# Since version 2.02.54, the tools distinguish between powers of
# 1024 bytes (e.g. KiB, MiB, GiB) and powers of 1000 bytes (e.g.
# KB, MB, GB).
# If you have scripts that depend on the old behaviour, set this to 0
# temporarily until you update them.
si_unit_consistency = 1
# Whether or not to communicate with the kernel device-mapper.
# Set to 0 if you want to use the tools to manipulate LVM metadata
# without activating any logical volumes.
@@ -223,8 +265,8 @@ global {
# The default metadata format that commands should use - "lvm1" or "lvm2".
# The command line override is -M1 or -M2.
# Defaults to "lvm1" if compiled in, else "lvm2".
# format = "lvm1"
# Defaults to "lvm2".
# format = "lvm2"
# Location of proc filesystem
proc = "/proc"
@@ -234,8 +276,13 @@ global {
# if LVM2 commands get run concurrently).
# Type 2 uses the external shared library locking_library.
# Type 3 uses built-in clustered locking.
# Type 4 uses read-only locking which forbids any operations that might
# change metadata.
locking_type = 1
# Set to 0 to fail when a lock request cannot be satisfied immediately.
wait_for_locks = 1
# If using external locking (type 2) and initialisation fails,
# with this set to 1 an attempt will be made to use the built-in
# clustered locking.
@@ -251,7 +298,16 @@ global {
# Local non-LV directory that holds file-based locks while commands are
# in progress. A directory like /tmp that may get wiped on reboot is OK.
locking_dir = "/var/lock/lvm"
locking_dir = "@DEFAULT_LOCK_DIR@"
# Whenever there are competing read-only and read-write access requests for
# a volume group's metadata, instead of always granting the read-only
# requests immediately, delay them to allow the read-write requests to be
# serviced. Without this setting, write access may be stalled by a high
# volume of read-only requests.
# NB. This option only affects locking_type = 1 viz. local file-based
# locking.
prioritise_write_locks = 1
# Other entries can go here to allow you to load shared libraries
# e.g. if support for LVM1 metadata was compiled as a shared library use
@@ -263,14 +319,37 @@ global {
# The external locking library to load if locking_type is set to 2.
# locking_library = "liblvm2clusterlock.so"
# Treat any internal errors as fatal errors, aborting the process that
# encountered the internal error. Please only enable for debugging.
abort_on_internal_errors = 0
}
activation {
# Device used in place of missing stripes if activating incomplete volume.
# For now, you need to set this up yourself first (e.g. with 'dmsetup')
# For example, you could make it return I/O errors using the 'error'
# target or make it return zeros.
missing_stripe_filler = "/dev/ioerror"
# Set to 0 to disable udev synchronisation (if compiled into the binaries).
# Processes will not wait for notification from udev.
# They will continue irrespective of any possible udev processing
# in the background. You should only use this if udev is not running
# or has rules that ignore the devices LVM2 creates.
# The command line argument --nodevsync takes precedence over this setting.
# If set to 1 when udev is not running, and there are LVM2 processes
# waiting for udev, run 'dmsetup udevcomplete_all' manually to wake them up.
udev_sync = 1
# Set to 0 to disable the udev rules installed by LVM2 (if built with
# --enable-udev_rules). LVM2 will then manage the /dev nodes and symlinks
# for active logical volumes directly itself.
# N.B. Manual intervention may be required if this setting is changed
# while any logical volumes are active.
udev_rules = 1
# How to fill in missing stripes if activating an incomplete volume.
# Using "error" will make inaccessible parts of the device return
# I/O errors on access. You can instead use a device path, in which
# case, that device will be used to in place of missing stripes.
# But note that using anything other than "error" with mirrored
# or snapshotted volumes is likely to result in data corruption.
missing_stripe_filler = "error"
# How much stack (in KB) to reserve for use while devices suspended
reserved_stack = 256
@@ -304,8 +383,10 @@ activation {
# A disk log ensures that a mirror does not need to be re-synced
# (all copies made the same) every time a machine reboots or crashes.
#
# In the event of a failure, the specified policy will be used to
# determine what happens:
# In the event of a failure, the specified policy will be used to determine
# what happens. This applies to automatic repairs (when the mirror is being
# monitored by dmeventd) and to manual lvconvert --repair when
# --use-policies is given.
#
# "remove" - Simply remove the faulty device and run without it. If
# the log device fails, the mirror would convert to using
@@ -325,23 +406,43 @@ activation {
# will preserve the mirror characteristic of the device.
# This policy acts like "remove" if no suitable device and
# space can be allocated for the replacement.
# Currently this is not implemented properly and behaves
# similarly to:
#
# "allocate_anywhere" - Operates like "allocate", but it does not
# require that the new space being allocated be on a
# device is not part of the mirror. For a log device
# failure, this could mean that the log is allocated on
# the same device as a mirror device. For a mirror
# device, this could mean that the mirror device is
# allocated on the same device as another mirror device.
# This policy would not be wise for mirror devices
# because it would break the redundant nature of the
# mirror. This policy acts like "remove" if no suitable
# device and space can be allocated for the replacement.
# "allocate_anywhere" - Not yet implemented. Useful to place the log device
# temporarily on same physical volume as one of the mirror
# images. This policy is not recommended for mirror devices
# since it would break the redundant nature of the mirror. This
# policy acts like "remove" if no suitable device and space can
# be allocated for the replacement.
mirror_log_fault_policy = "allocate"
mirror_device_fault_policy = "remove"
mirror_image_fault_policy = "remove"
# While activating devices, I/O to devices being (re)configured is
# suspended, and as a precaution against deadlocks, LVM2 needs to pin
# any memory it is using so it is not paged out. Groups of pages that
# are known not to be accessed during activation need not be pinned
# into memory. Each string listed in this setting is compared against
# each line in /proc/self/maps, and the pages corresponding to any
# lines that match are not pinned. On some systems locale-archive was
# found to make up over 80% of the memory used by the process.
# mlock_filter = [ "locale/locale-archive", "gconv/gconv-modules.cache" ]
# Set to 1 to revert to the default behaviour prior to version 2.02.62
# which used mlockall() to pin the whole process's memory while activating
# devices.
use_mlockall = 0
# Monitoring is enabled by default when activating logical volumes.
# Set to 0 to disable monitoring or use the --ignoremonitoring option.
monitoring = 1
# When pvmove or lvconvert must wait for the kernel to finish
# synchronising or merging data, they check and report progress
# at intervals of this number of seconds. The default is 15 seconds.
# If this is set to 0 and there is only one thing to wait for, there
# are no progress reports, but the process is awoken immediately the
# operation is complete.
polling_interval = 15
}
@@ -358,6 +459,19 @@ activation {
# pvmetadatacopies = 1
# Default number of copies of metadata to maintain for each VG.
# If set to a non-zero value, LVM automatically chooses which of
# the available metadata areas to use to achieve the requested
# number of copies of the VG metadata. If you set a value larger
# than the the total number of metadata areas available then
# metadata is stored in them all.
# The default value of 0 ("unmanaged") disables this automatic
# management and allows you to control which metadata areas
# are used at the individual PV level using 'pvchange
# --metadataignore y/n'.
# vgmetadatacopies = 0
# Approximate default size of on-disk metadata areas in sectors.
# You should increase this if you have large volume groups or
# you want to retain a large on-disk history of your metadata changes.
@@ -382,7 +496,7 @@ activation {
# Event daemon
#
# dmeventd {
dmeventd {
# mirror_library is the library used when monitoring a mirror device.
#
# "libdevmapper-event-lvm2mirror.so" attempts to recover from
@@ -390,15 +504,18 @@ activation {
# reconfigures a mirror as necessary. If no mirror library is
# provided, mirrors are not monitored through dmeventd.
# mirror_library = "libdevmapper-event-lvm2mirror.so"
mirror_library = "libdevmapper-event-lvm2mirror.so"
# snapshot_library is the library used when monitoring a snapshot device.
#
# "libdevmapper-event-lvm2snapshot.so" monitors the filling of
# snapshots and emits a warning through syslog, when the use of
# snapshot exceedes 80%. The warning is repeated when 85%, 90% and
# 95% of the snapshot are filled.
# snapshots and emits a warning through syslog when the use of
# the snapshot exceeds 80%. The warning is repeated when 85%, 90% and
# 95% of the snapshot is filled.
# snapshot_library = "libdevmapper-event-lvm2snapshot.so"
#}
snapshot_library = "libdevmapper-event-lvm2snapshot.so"
# Full path of the dmeventd binary.
#
# executable = "@DMEVENTD_PATH@"
}

View File

@@ -13,9 +13,11 @@
*/
#include "lvm2cmd.h"
#include <stdio.h>
/* All output gets passed to this function line-by-line */
void test_log_fn(int level, const char *file, int line, const char *format)
void test_log_fn(int level, const char *file, int line,
int dm_errno, const char *format)
{
/* Extract and process output here rather than printing it */

221
doc/lvm_fault_handling.txt Normal file
View File

@@ -0,0 +1,221 @@
LVM device fault handling
=========================
Introduction
------------
This document is to serve as the definitive source for information
regarding the policies and procedures surrounding device failures
in LVM. It codifies LVM's responses to device failures as well as
the responsibilities of administrators.
Device failures can be permanent or transient. A permanent failure
is one where a device becomes inaccessible and will never be
revived. A transient failure is a failure that can be recovered
from (e.g. a power failure, intermittent network outage, block
relocation, etc). The policies for handling both types of failures
is described herein.
Available Operations During a Device Failure
--------------------------------------------
When there is a device failure, LVM behaves somewhat differently because
only a subset of the available devices will be found for the particular
volume group. The number of operations available to the administrator
is diminished. It is not possible to create new logical volumes while
PVs cannot be accessed, for example. Operations that create, convert, or
resize logical volumes are disallowed, such as:
- lvcreate
- lvresize
- lvreduce
- lvextend
- lvconvert (unless '--repair' is used)
Operations that activate, deactivate, remove, report, or repair logical
volumes are allowed, such as:
- lvremove
- vgremove (will remove all LVs, but not the VG until consistent)
- pvs
- vgs
- lvs
- lvchange -a [yn]
- vgchange -a [yn]
Operations specific to the handling of failed devices are allowed and
are as follows:
- 'vgreduce --removemissing <VG>': This action is designed to remove
the reference of a failed device from the LVM metadata stored on the
remaining devices. If there are (portions of) logical volumes on the
failed devices, the ability of the operation to proceed will depend
on the type of logical volumes found. If an image (i.e leg or side)
of a mirror is located on the device, that image/leg of the mirror
is eliminated along with the failed device. The result of such a
mirror reduction could be a no-longer-redundant linear device. If
a linear, stripe, or snapshot device is located on the failed device
the command will not proceed without a '--force' option. The result
of using the '--force' option is the entire removal and complete
loss of the non-redundant logical volume. Once this operation is
complete, the volume group will again have a complete and consistent
view of the devices it contains. Thus, all operations will be
permitted - including creation, conversion, and resizing operations.
- 'lvconvert --repair <VG/LV>': This action is designed specifically
to operate on mirrored logical volumes. It is used on logical volumes
individually and does not remove the faulty device from the volume
group. If, for example, a failed device happened to contain the
images of four distinct mirrors, it would be necessary to run
'lvconvert --repair' on each of them. The ultimate result is to leave
the faulty device in the volume group, but have no logical volumes
referencing it. In addition to removing mirror images that reside
on failed devices, 'lvconvert --repair' can also replace the failed
device if there are spare devices available in the volume group. The
user is prompted whether to simply remove the failed portions of the
mirror or to also allocate a replacement, if run from the command-line.
Optionally, the '--use-policies' flag can be specified which will
cause the operation not to prompt the user, but instead respect
the policies outlined in the LVM configuration file - usually,
/etc/lvm/lvm.conf. Once this operation is complete, mirrored logical
volumes will be consistent and I/O will be allowed to continue.
However, the volume group will still be inconsistent - due to the
refernced-but-missing device/PV - and operations will still be
restricted to the aformentioned actions until either the device is
restored or 'vgreduce --removemissing' is run.
Device Revival (transient failures):
------------------------------------
During a device failure, the above section describes what limitations
a user can expect. However, if the device returns after a period of
time, what to expect will depend on what has happened during the time
period when the device was failed. If no automated actions (described
below) or user actions were necessary or performed, then no change in
operations or logical volume layout will occur. However, if an
automated action or one of the aforementioned repair commands was
manually run, the returning device will be perceived as having stale
LVM metadata. In this case, the user can expect to see a warning
concerning inconsistent metadata. The metadata on the returning
device will be automatically replaced with the latest copy of the
LVM metadata - restoring consistency. Note, while most LVM commands
will automatically update the metadata on a restored devices, the
following possible exceptions exist:
- pvs (when it does not read/update VG metadata)
Automated Target Response to Failures:
--------------------------------------
The only LVM target type (i.e. "personality") that has an automated
response to failures is a mirrored logical volume. The other target
types (linear, stripe, snapshot, etc) will simply propagate the failure.
[A snapshot becomes invalid if its underlying device fails, but the
origin will remain valid - presuming the origin device has not failed.]
There are three types of errors that a mirror can suffer - read, write,
and resynchronization errors. Each is described in depth below.
Mirror read failures:
If a mirror is 'in-sync' (i.e. all images have been initialized and
are identical), a read failure will only produce a warning. Data is
simply pulled from one of the other images and the fault is recorded.
Sometimes - like in the case of bad block relocation - read errors can
be recovered from by the storage hardware. Therefore, it is up to the
user to decide whether to reconfigure the mirror and remove the device
that caused the error. Managing the composition of a mirror is done with
'lvconvert' and removing a device from a volume group can be done with
'vgreduce'.
If a mirror is not 'in-sync', a read failure will produce an I/O error.
This error will propagate all the way up to the applications above the
logical volume (e.g. the file system). No automatic intervention will
take place in this case either. It is up to the user to decide what
can be done/salvaged in this senario. If the user is confident that the
images of the mirror are the same (or they are willing to simply attempt
to retreive whatever data they can), 'lvconvert' can be used to eliminate
the failed image and proceed.
Mirror resynchronization errors:
A resynchronization error is one that occurs when trying to initialize
all mirror images to be the same. It can happen due to a failure to
read the primary image (the image considered to have the 'good' data), or
due to a failure to write the secondary images. This type of failure
only produces a warning, and it is up to the user to take action in this
case. If the error is transient, the user can simply reactivate the
mirrored logical volume to make another attempt at resynchronization.
If attempts to finish resynchronization fail, 'lvconvert' can be used to
remove the faulty device from the mirror.
TODO...
Some sort of response to this type of error could be automated.
Since this document is the definitive source for how to handle device
failures, the process should be defined here. If the process is defined
but not implemented, it should be noted as such. One idea might be to
make a single attempt to suspend/resume the mirror in an attempt to
redo the sync operation that failed. On the other hand, if there is
a permanent failure, it may simply be best to wait for the user or the
automated response that is sure to follow from a write failure.
...TODO
Mirror write failures:
When a write error occurs on a mirror constituent device, an attempt
to handle the failure is automatically made. This is done by calling
'lvconvert --repair --use-policies'. The policies implied by this
command are set in the LVM configuration file. They are:
- mirror_log_fault_policy: This defines what action should be taken
if the device containing the log fails. The available options are
"remove" and "allocate". Either of these options will cause the
faulty log device to be removed from the mirror. The "allocate"
policy will attempt the further action of trying to replace the
failed disk log by using space that might be available in the
volume group. If the allocation fails (or the "remove" policy
is specified), the mirror log will be maintained in memory. Should
the machine be rebooted or the logical volume deactivated, a
complete resynchronization of the mirror will be necessary upon
the follow activation - such is the nature of a mirror with a 'core'
log. The default policy for handling log failures is "allocate".
The service disruption incurred by replacing the failed log is
negligible, while the benefits of having persistent log is
pronounced.
- mirror_image_fault_policy: This defines what action should be taken
if a device containing an image fails. Again, the available options
are "remove" and "allocate". Both of these options will cause the
faulty image device to be removed - adjusting the logical volume
accordingly. For example, if one image of a 2-way mirror fails, the
mirror will be converted to a linear device. If one image of a
3-way mirror fails, the mirror will be converted to a 2-way mirror.
The "allocate" policy takes the further action of trying to replace
the failed image using space that is available in the volume group.
Replacing a failed mirror image will incure the cost of
resynchronizing - degrading the performance of the mirror. The
default policy for handling an image failure is "remove". This
allows the mirror to still function, but gives the administrator the
choice of when to incure the extra performance costs of replacing
the failed image.
TODO...
The appropriate time to take permanent corrective action on a mirror
should be driven by policy. There should be a directive that takes
a time or percentage argument. Something like the following:
- mirror_fault_policy_WHEN = "10sec"/"10%"
A time value would signal the amount of time to wait for transient
failures to resolve themselves. The percentage value would signal the
amount a mirror could become out-of-sync before the faulty device is
removed.
A mirror cannot be used unless /some/ corrective action is taken,
however. One option is to replace the failed mirror image with an
error target, forgo the use of 'handle_errors', and simply let the
out-of-sync regions accumulate and be tracked by the log. Mirrors
that have more than 2 images would have to "stack" to perform the
tracking, as each failed image would have to be associated with a
log. If the failure is transient, the device would replace the
error target that was holding its spot and the log that was tracking
the deltas would be used to quickly restore the portions that changed.
One unresolved issue with the above scheme is how to know which
regions of the mirror are out-of-sync when a problem occurs. When
a write failure occurs in the kernel, the log will contain those
regions that are not in-sync. If the log is a disk log, that log
could continue to be used to track differences. However, if the
log was a core log - or if the log device failed at the same time
as an image device - there would be no way to determine which
regions are out-of-sync to begin with as we start to track the
deltas for the failed image. I don't have a solution for this
problem other than to only be able to handle errors in this way
if conditions are right. These issues will have to be ironed out
before proceeding. This could be another case, where it is better
to handle failures in the kernel by allowing the kernel to store
updates in various metadata areas.
...TODO

View File

@@ -1,52 +0,0 @@
../daemons/clvmd/clvm.h
../lib/activate/activate.h
../lib/activate/targets.h
../lib/cache/lvmcache.h
../lib/commands/errors.h
../lib/commands/toolcontext.h
../lib/config/config.h
../lib/config/defaults.h
../lib/datastruct/btree.h
../lib/datastruct/list.h
../lib/datastruct/lvm-types.h
../lib/datastruct/str_list.h
../lib/device/dev-cache.h
../lib/device/device.h
../lib/display/display.h
../lib/filters/filter-composite.h
../lib/filters/filter-md.h
../lib/filters/filter-persistent.h
../lib/filters/filter-regex.h
../lib/filters/filter-sysfs.h
../lib/filters/filter.h
../lib/format1/format1.h
../lib/format_pool/format_pool.h
../lib/format_text/archiver.h
../lib/format_text/format-text.h
../lib/format_text/text_export.h
../lib/format_text/text_import.h
../lib/label/label.h
../lib/locking/locking.h
../lib/log/log.h
../lib/metadata/lv_alloc.h
../lib/metadata/metadata.h
../lib/metadata/metadata-exported.h
../lib/metadata/pv_alloc.h
../lib/metadata/segtype.h
../lib/mm/memlock.h
../lib/mm/xlate.h
../lib/misc/configure.h
../lib/misc/crc.h
../lib/misc/intl.h
../lib/misc/util.h
../lib/misc/last-path-component.h
../lib/misc/lib.h
../lib/misc/lvm-exec.h
../lib/misc/lvm-file.h
../lib/misc/lvm-string.h
../lib/misc/lvm-wrappers.h
../lib/misc/sharedlib.h
../lib/report/report.h
../lib/uuid/uuid.h
../po/pogen.h
../tools/version.h

62
include/.symlinks.in Normal file
View File

@@ -0,0 +1,62 @@
@top_srcdir@/daemons/clvmd/clvm.h
@top_srcdir@/daemons/dmeventd/libdevmapper-event.h
@top_srcdir@/liblvm/lvm2app.h
@top_srcdir@/lib/activate/activate.h
@top_srcdir@/lib/activate/targets.h
@top_srcdir@/lib/cache/lvmcache.h
@top_srcdir@/lib/commands/errors.h
@top_srcdir@/lib/commands/toolcontext.h
@top_srcdir@/lib/config/config.h
@top_srcdir@/lib/config/defaults.h
@top_srcdir@/lib/datastruct/btree.h
@top_srcdir@/lib/datastruct/lvm-types.h
@top_srcdir@/lib/datastruct/str_list.h
@top_srcdir@/lib/device/dev-cache.h
@top_srcdir@/lib/device/device.h
@top_srcdir@/lib/display/display.h
@top_srcdir@/lib/filters/filter-composite.h
@top_srcdir@/lib/filters/filter-md.h
@top_srcdir@/lib/filters/filter-persistent.h
@top_srcdir@/lib/filters/filter-regex.h
@top_srcdir@/lib/filters/filter-sysfs.h
@top_srcdir@/lib/filters/filter.h
@top_srcdir@/lib/format1/format1.h
@top_srcdir@/lib/format_pool/format_pool.h
@top_srcdir@/lib/format_text/archiver.h
@top_srcdir@/lib/format_text/format-text.h
@top_srcdir@/lib/format_text/text_export.h
@top_srcdir@/lib/format_text/text_import.h
@top_srcdir@/lib/label/label.h
@top_srcdir@/lib/locking/locking.h
@top_srcdir@/lib/log/log.h
@top_srcdir@/lib/log/lvm-logging.h
@top_srcdir@/lib/metadata/lv_alloc.h
@top_srcdir@/lib/metadata/metadata.h
@top_srcdir@/lib/metadata/metadata-exported.h
@top_srcdir@/lib/metadata/pv_alloc.h
@top_srcdir@/lib/metadata/segtype.h
@top_srcdir@/lib/mm/memlock.h
@top_srcdir@/lib/mm/xlate.h
@top_builddir@/lib/misc/configure.h
@top_srcdir@/lib/misc/crc.h
@top_srcdir@/lib/misc/intl.h
@top_srcdir@/lib/misc/util.h
@top_srcdir@/lib/misc/last-path-component.h
@top_srcdir@/lib/misc/lib.h
@top_srcdir@/lib/misc/lvm-exec.h
@top_srcdir@/lib/misc/lvm-file.h
@top_srcdir@/lib/misc/lvm-globals.h
@top_srcdir@/lib/misc/lvm-string.h
@top_builddir@/lib/misc/lvm-version.h
@top_srcdir@/lib/misc/lvm-wrappers.h
@top_srcdir@/lib/misc/sharedlib.h
@top_srcdir@/lib/report/report.h
@top_srcdir@/lib/uuid/uuid.h
@top_srcdir@/libdm/libdevmapper.h
@top_srcdir@/libdm/misc/dm-ioctl.h
@top_srcdir@/libdm/misc/dm-logging.h
@top_srcdir@/libdm/misc/dm-log-userspace.h
@top_srcdir@/libdm/misc/dmlib.h
@top_srcdir@/libdm/misc/kdev_t.h
@top_srcdir@/po/pogen.h
@top_srcdir@/tools/lvm2cmd.h

View File

@@ -16,30 +16,35 @@ SHELL = /bin/sh
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
top_builddir = @top_builddir@
LN_S = @LN_S@
.PHONY: clean distclean all install pofile install_cluster
.PHONY: clean distclean all install pofile install_cluster install_device-mapper
all: .symlinks_created
.symlinks_created: .symlinks
.symlinks_created: .symlinks
find . -maxdepth 1 -type l -exec $(RM) \{\} \;
for i in `cat .symlinks`; do $(LN_S) $$i ; done
for i in `cat $<`; do $(LN_S) $$i ; done
touch $@
distclean:
find . -maxdepth 1 -type l -exec $(RM) \{\} \;
$(RM) Makefile .include_symlinks .symlinks_created
$(RM) Makefile .include_symlinks .symlinks_created .symlinks
pofile: all
device-mapper: all
clean:
install:
install_cluster:
cflow:
install_device-mapper:
install_lvm2:
cflow: all

View File

@@ -1,6 +1,6 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
# Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
@@ -14,7 +14,7 @@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
top_builddir = @top_builddir@
ifeq ("@LVM1@", "shared")
SUBDIRS = format1
@@ -32,20 +32,25 @@ ifeq ("@MIRRORS@", "shared")
SUBDIRS += mirror
endif
ifeq ("@REPLICATORS@", "shared")
SUBDIRS += replicator
endif
SOURCES =\
activate/activate.c \
cache/lvmcache.c \
commands/toolcontext.c \
config/config.c \
datastruct/btree.c \
datastruct/list.c \
datastruct/str_list.c \
device/dev-cache.c \
device/dev-io.c \
device/dev-md.c \
device/dev-swap.c \
device/device.c \
display/display.c \
error/errseg.c \
unknown/unknown.c \
filters/filter-composite.c \
filters/filter-persistent.c \
filters/filter-regex.c \
@@ -61,6 +66,7 @@ SOURCES =\
format_text/import_vsn1.c \
format_text/tags.c \
format_text/text_label.c \
freeseg/freeseg.c \
label/label.c \
locking/file_locking.c \
locking/locking.c \
@@ -72,14 +78,15 @@ SOURCES =\
metadata/mirror.c \
metadata/pv_manip.c \
metadata/pv_map.c \
metadata/replicator_manip.c \
metadata/segtype.c \
metadata/snapshot_manip.c \
misc/crc.c \
misc/lvm-exec.c \
misc/lvm-file.c \
misc/lvm-globals.c \
misc/lvm-string.c \
misc/lvm-wrappers.c \
misc/timestamp.c \
misc/util.c \
mm/memlock.c \
report/report.c \
@@ -87,6 +94,11 @@ SOURCES =\
uuid/uuid.c \
zero/zero.c
ifeq ("@HAVE_REALTIME@", "yes")
SOURCES +=\
misc/timestamp.c
endif
ifeq ("@LVM1@", "internal")
SOURCES +=\
format1/disk-rep.c \
@@ -122,6 +134,10 @@ ifeq ("@MIRRORS@", "internal")
SOURCES += mirror/mirrored.c
endif
ifeq ("@REPLICATORS@", "internal")
SOURCES += replicator/replicator.c
endif
ifeq ("@DEVMAPPER@", "yes")
SOURCES +=\
activate/dev_manager.c \
@@ -135,21 +151,28 @@ ifeq ("@HAVE_LIBDL@", "yes")
endif
ifeq ("@DMEVENTD@", "yes")
CLDFLAGS += -ldevmapper-event
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd
LIBS += -ldevmapper-event
endif
LIB_STATIC = liblvm.a
LIB_NAME = liblvm-internal
LIB_STATIC = $(LIB_NAME).a
ifeq ($(MAKECMDGOALS),distclean)
SUBDIRS =\
format1 \
format_pool \
snapshot \
mirror \
replicator \
locking
endif
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
include $(top_builddir)/make.tmpl
$(SUBDIRS): $(LIB_STATIC)
CLEAN_TARGETS += liblvm.cflow
include $(top_srcdir)/make.tmpl
liblvm.cflow: $(SOURCES)
set -e; (echo -n "SOURCES += "; \
echo $(SOURCES) | \
sed "s/^/ /;s/ / $(top_srcdir)\/lib\//g;s/$$//"; \
) > $@
cflow: liblvm.cflow
DISTCLEAN_TARGETS += misc/configure.h misc/lvm-version.h

File diff suppressed because it is too large Load Diff

View File

@@ -40,22 +40,23 @@ int driver_version(char *version, size_t size);
int library_version(char *version, size_t size);
int lvm1_present(struct cmd_context *cmd);
int module_present(const char *target_name);
int target_present(const char *target_name, int use_modprobe);
int module_present(struct cmd_context *cmd, const char *target_name);
int target_present(struct cmd_context *cmd, const char *target_name,
int use_modprobe);
int target_version(const char *target_name, uint32_t *maj,
uint32_t *min, uint32_t *patchlevel);
uint32_t *min, uint32_t *patchlevel);
int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg,
struct list *modules);
struct dm_list *modules);
int list_lv_modules(struct dm_pool *mem, const struct logical_volume *lv,
struct list *modules);
struct dm_list *modules);
void activation_release(void);
void activation_exit(void);
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_suspend(struct cmd_context *cmd, const char *lvid_s); */
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only);
int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only);
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only);
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);
@@ -66,9 +67,10 @@ 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(struct cmd_context *cmd, const struct logical_volume *lv, struct lvinfo *info,
int lv_info(struct cmd_context *cmd, const struct logical_volume *lv,
unsigned origin_only, struct lvinfo *info,
int with_open_count, int with_read_ahead);
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only,
struct lvinfo *info, int with_open_count, int with_read_ahead);
/*
@@ -77,24 +79,38 @@ int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
int *activate_lv);
int lv_check_transient(struct logical_volume *lv);
/*
* Returns 1 if percent has been set, else 0.
*/
int lv_snapshot_percent(const struct logical_volume *lv, float *percent);
int lv_snapshot_percent(const struct logical_volume *lv, float *percent,
percent_range_t *percent_range);
int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv,
int wait, float *percent, uint32_t *event_nr);
int wait, float *percent, percent_range_t *percent_range,
uint32_t *event_nr);
/*
* Return number of LVs in the VG that are active.
*/
int lvs_in_vg_activated(struct volume_group *vg);
int lvs_in_vg_activated_by_uuid_only(struct volume_group *vg);
int lvs_in_vg_opened(const struct volume_group *vg);
int lv_is_active(struct logical_volume *lv);
int monitor_dev_for_events(struct cmd_context *cmd,
struct logical_volume *lv, int do_reg);
int lv_has_target_type(struct dm_pool *mem, struct logical_volume *lv,
const char *layer, const char *target_type);
int monitor_dev_for_events(struct cmd_context *cmd, struct logical_volume *lv,
unsigned origin_only, int do_reg);
#ifdef DMEVENTD
# include "libdevmapper-event.h"
char *get_monitor_dso_path(struct cmd_context *cmd, const char *libpath);
int target_registered_with_dmeventd(struct cmd_context *cmd, const char *libpath,
struct logical_volume *lv, int *pending);
int target_register_events(struct cmd_context *cmd, const char *dso, struct logical_volume *lv,
int evmask __attribute__((unused)), int set, int timeout);
#endif
/*
* Returns 1 if PV has a dependency tree that uses anything in VG.
@@ -105,6 +121,6 @@ int pv_uses_vg(struct physical_volume *pv,
/*
* Returns 1 if mapped device is not suspended.
*/
int device_is_usable(dev_t dev);
int device_is_usable(struct device *dev);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -16,6 +16,8 @@
#ifndef _LVM_DEV_MANAGER_H
#define _LVM_DEV_MANAGER_H
#include "metadata-exported.h"
struct logical_volume;
struct volume_group;
struct cmd_context;
@@ -38,24 +40,27 @@ 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 dm_pool *mem, const char *name,
const struct logical_volume *lv,
int mknodes, int with_open_count, int with_read_ahead,
int dev_manager_info(struct dm_pool *mem, const struct logical_volume *lv,
const char *layer,
int with_open_count, int with_read_ahead,
struct dm_info *info, uint32_t *read_ahead);
int dev_manager_snapshot_percent(struct dev_manager *dm,
const struct logical_volume *lv,
float *percent);
float *percent,
percent_range_t *percent_range);
int dev_manager_mirror_percent(struct dev_manager *dm,
struct logical_volume *lv, int wait,
float *percent, uint32_t *event_nr);
const struct logical_volume *lv, int wait,
float *percent, percent_range_t *percent_range,
uint32_t *event_nr);
int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv,
int lockfs);
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv);
int dev_manager_preload(struct dev_manager *dm, struct logical_volume *lv);
unsigned origin_only, int lockfs, int flush_required);
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv, unsigned origin_only);
int dev_manager_preload(struct dev_manager *dm, struct logical_volume *lv,
unsigned origin_only, int *flush_required);
int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv);
int dev_manager_transient(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(const struct logical_volume *lv);
/*
* Put the desired changes into effect.

View File

@@ -29,6 +29,7 @@
static int _mk_dir(const char *dev_dir, const char *vg_name)
{
char vg_path[PATH_MAX];
mode_t old_umask;
if (dm_snprintf(vg_path, sizeof(vg_path), "%s%s",
dev_dir, vg_name) == -1) {
@@ -41,10 +42,14 @@ static int _mk_dir(const char *dev_dir, const char *vg_name)
return 1;
log_very_verbose("Creating directory %s", vg_path);
old_umask = umask(DM_DEV_DIR_UMASK);
if (mkdir(vg_path, 0777)) {
log_sys_error("mkdir", vg_path);
umask(old_umask);
return 0;
}
umask(old_umask);
return 1;
}
@@ -103,11 +108,11 @@ static void _rm_blks(const char *dir)
}
static int _mk_link(const char *dev_dir, const char *vg_name,
const char *lv_name, const char *dev)
const char *lv_name, const char *dev, int check_udev)
{
char lv_path[PATH_MAX], link_path[PATH_MAX], lvm1_group_path[PATH_MAX];
char vg_path[PATH_MAX];
struct stat buf;
struct stat buf, buf_lp;
if (dm_snprintf(vg_path, sizeof(vg_path), "%s%s",
dev_dir, vg_name) == -1) {
@@ -161,12 +166,34 @@ static int _mk_link(const char *dev_dir, const char *vg_name,
return 0;
}
if (dm_udev_get_sync_support() && udev_checking() && check_udev) {
/* Check udev created the correct link. */
if (!stat(link_path, &buf_lp) &&
!stat(lv_path, &buf)) {
if (buf_lp.st_rdev == buf.st_rdev)
return 1;
else
log_warn("Symlink %s that should have been "
"created by udev does not have "
"correct target. Falling back to "
"direct link creation", lv_path);
} else
log_warn("Symlink %s that should have been "
"created by udev could not be checked "
"for its correctness. Falling back to "
"direct link creation.", lv_path);
}
log_very_verbose("Removing %s", lv_path);
if (unlink(lv_path) < 0) {
log_sys_error("unlink", lv_path);
return 0;
}
}
} else if (dm_udev_get_sync_support() && udev_checking() && check_udev)
log_warn("The link %s should had been created by udev "
"but it was not found. Falling back to "
"direct link creation.", lv_path);
log_very_verbose("Linking %s -> %s", lv_path, link_path);
if (symlink(link_path, lv_path) < 0) {
@@ -174,16 +201,14 @@ static int _mk_link(const char *dev_dir, const char *vg_name,
return 0;
}
#ifdef HAVE_SELINUX
if (!dm_set_selinux_context(lv_path, S_IFLNK))
return_0;
#endif
return 1;
}
static int _rm_link(const char *dev_dir, const char *vg_name,
const char *lv_name)
const char *lv_name, int check_udev)
{
struct stat buf;
char lv_path[PATH_MAX];
@@ -194,9 +219,14 @@ static int _rm_link(const char *dev_dir, const char *vg_name,
return 0;
}
if (lstat(lv_path, &buf) || !S_ISLNK(buf.st_mode)) {
if (errno == ENOENT)
return 1;
if (lstat(lv_path, &buf) && errno == ENOENT)
return 1;
else if (dm_udev_get_sync_support() && udev_checking() && check_udev)
log_warn("The link %s should have been removed by udev "
"but it is still present. Falling back to "
"direct link removal.", lv_path);
if (!S_ISLNK(buf.st_mode)) {
log_error("%s not symbolic link - not removing", lv_path);
return 0;
}
@@ -218,36 +248,38 @@ typedef enum {
static int _do_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
const char *lv_name, const char *dev,
const char *old_lv_name)
const char *old_lv_name, int check_udev)
{
switch (type) {
case FS_ADD:
if (!_mk_dir(dev_dir, vg_name) ||
!_mk_link(dev_dir, vg_name, lv_name, dev))
!_mk_link(dev_dir, vg_name, lv_name, dev, check_udev))
return_0;
break;
case FS_DEL:
if (!_rm_link(dev_dir, vg_name, lv_name) ||
if (!_rm_link(dev_dir, vg_name, lv_name, check_udev) ||
!_rm_dir(dev_dir, vg_name))
return_0;
break;
/* FIXME Use rename() */
case FS_RENAME:
if (old_lv_name && !_rm_link(dev_dir, vg_name, old_lv_name))
if (old_lv_name && !_rm_link(dev_dir, vg_name, old_lv_name,
check_udev))
stack;
if (!_mk_link(dev_dir, vg_name, lv_name, dev))
if (!_mk_link(dev_dir, vg_name, lv_name, dev, check_udev))
stack;
}
return 1;
}
static LIST_INIT(_fs_ops);
static DM_LIST_INIT(_fs_ops);
struct fs_op_parms {
struct list list;
struct dm_list list;
fs_op_t type;
int check_udev;
char *dev_dir;
char *vg_name;
char *lv_name;
@@ -265,7 +297,7 @@ static void _store_str(char **pos, char **ptr, const char *str)
static int _stack_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
const char *lv_name, const char *dev,
const char *old_lv_name)
const char *old_lv_name, int check_udev)
{
struct fs_op_parms *fsp;
size_t len = strlen(dev_dir) + strlen(vg_name) + strlen(lv_name) +
@@ -279,6 +311,7 @@ static int _stack_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
pos = fsp->names;
fsp->type = type;
fsp->check_udev = check_udev;
_store_str(&pos, &fsp->dev_dir, dev_dir);
_store_str(&pos, &fsp->vg_name, vg_name);
@@ -286,60 +319,71 @@ static int _stack_fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
_store_str(&pos, &fsp->dev, dev);
_store_str(&pos, &fsp->old_lv_name, old_lv_name);
list_add(&_fs_ops, &fsp->list);
dm_list_add(&_fs_ops, &fsp->list);
return 1;
}
static void _pop_fs_ops(void)
{
struct list *fsph, *fspht;
struct dm_list *fsph, *fspht;
struct fs_op_parms *fsp;
list_iterate_safe(fsph, fspht, &_fs_ops) {
fsp = list_item(fsph, struct fs_op_parms);
dm_list_iterate_safe(fsph, fspht, &_fs_ops) {
fsp = dm_list_item(fsph, struct fs_op_parms);
_do_fs_op(fsp->type, fsp->dev_dir, fsp->vg_name, fsp->lv_name,
fsp->dev, fsp->old_lv_name);
list_del(&fsp->list);
fsp->dev, fsp->old_lv_name, fsp->check_udev);
dm_list_del(&fsp->list);
dm_free(fsp);
}
}
static int _fs_op(fs_op_t type, const char *dev_dir, const char *vg_name,
const char *lv_name, const char *dev, const char *old_lv_name)
const char *lv_name, const char *dev, const char *old_lv_name,
int check_udev)
{
if (memlock()) {
if (!_stack_fs_op(type, dev_dir, vg_name, lv_name, dev,
old_lv_name))
old_lv_name, check_udev))
return_0;
return 1;
}
return _do_fs_op(type, dev_dir, vg_name, lv_name, dev, old_lv_name);
return _do_fs_op(type, dev_dir, vg_name, lv_name, dev,
old_lv_name, check_udev);
}
int fs_add_lv(const struct logical_volume *lv, const char *dev)
{
return _fs_op(FS_ADD, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
dev, "");
dev, "", lv->vg->cmd->current_settings.udev_rules);
}
int fs_del_lv(const struct logical_volume *lv)
{
return _fs_op(FS_DEL, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
"", "");
"", "", lv->vg->cmd->current_settings.udev_rules);
}
int fs_del_lv_byname(const char *dev_dir, const char *vg_name, const char *lv_name)
int fs_del_lv_byname(const char *dev_dir, const char *vg_name,
const char *lv_name, int check_udev)
{
return _fs_op(FS_DEL, dev_dir, vg_name, lv_name, "", "");
return _fs_op(FS_DEL, dev_dir, vg_name, lv_name, "", "", check_udev);
}
int fs_rename_lv(struct logical_volume *lv,
const char *dev, const char *old_name)
int fs_rename_lv(struct logical_volume *lv, const char *dev,
const char *old_vgname, const char *old_lvname)
{
return _fs_op(FS_RENAME, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
dev, old_name);
if (strcmp(old_vgname, lv->vg->name)) {
return
(_fs_op(FS_DEL, lv->vg->cmd->dev_dir, old_vgname,
old_lvname, "", "", lv->vg->cmd->current_settings.udev_rules) &&
_fs_op(FS_ADD, lv->vg->cmd->dev_dir, lv->vg->name,
lv->name, dev, "", lv->vg->cmd->current_settings.udev_rules));
}
else
return _fs_op(FS_RENAME, lv->vg->cmd->dev_dir, lv->vg->name, lv->name,
dev, old_lvname, lv->vg->cmd->current_settings.udev_rules);
}
void fs_unlock(void)

View File

@@ -25,9 +25,10 @@
*/
int fs_add_lv(const struct logical_volume *lv, const char *dev);
int fs_del_lv(const struct logical_volume *lv);
int fs_del_lv_byname(const char *dev_dir, const char *vg_name, const char *lv_name);
int fs_rename_lv(struct logical_volume *lv,
const char *dev, const char *old_name);
int fs_del_lv_byname(const char *dev_dir, const char *vg_name,
const char *lv_name, int check_udev);
int fs_rename_lv(struct logical_volume *lv, const char *dev,
const char *old_vgname, const char *old_lvname);
void fs_unlock(void);
#endif

View File

@@ -29,6 +29,4 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
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

428
lib/cache/lvmcache.c vendored
View File

@@ -20,6 +20,7 @@
#include "locking.h"
#include "metadata.h"
#include "filter.h"
#include "filter-persistent.h"
#include "memlock.h"
#include "str_list.h"
#include "format-text.h"
@@ -30,7 +31,7 @@ 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 DM_LIST_INIT(_vginfos);
static int _scanning_in_progress = 0;
static int _has_scanned = 0;
static int _vgs_locked = 0;
@@ -38,7 +39,13 @@ static int _vg_global_lock_held = 0; /* Global lock held when cache wiped? */
int lvmcache_init(void)
{
list_init(&_vginfos);
/*
* FIXME add a proper lvmcache_locking_reset() that
* resets the cache so no previous locks are locked
*/
_vgs_locked = 0;
dm_list_init(&_vginfos);
if (!(_vgname_hash = dm_hash_create(128)))
return 0;
@@ -52,8 +59,15 @@ int lvmcache_init(void)
if (!(_lock_hash = dm_hash_create(128)))
return 0;
if (_vg_global_lock_held)
/*
* Reinitialising the cache clears the internal record of
* which locks are held. The global lock can be held during
* this operation so its state must be restored afterwards.
*/
if (_vg_global_lock_held) {
lvmcache_lock_vgname(VG_GLOBAL, 0);
_vg_global_lock_held = 0;
}
return 1;
}
@@ -71,11 +85,20 @@ static void _free_cached_vgmetadata(struct lvmcache_vginfo *vginfo)
log_debug("Metadata cache: VG %s wiped.", vginfo->vgname);
}
static void _store_metadata(struct lvmcache_vginfo *vginfo,
struct volume_group *vg, unsigned precommitted)
/*
* Cache VG metadata against the vginfo with matching vgid.
*/
static void _store_metadata(struct volume_group *vg, unsigned precommitted)
{
char uuid[64] __attribute__((aligned(8)));
struct lvmcache_vginfo *vginfo;
int size;
if (!(vginfo = vginfo_from_vgid((const char *)&vg->id))) {
stack;
return;
}
if (vginfo->vgmetadata)
_free_cached_vgmetadata(vginfo);
@@ -86,8 +109,14 @@ static void _store_metadata(struct lvmcache_vginfo *vginfo,
vginfo->precommitted = precommitted;
log_debug("Metadata cache: VG %s stored (%d bytes%s).", vginfo->vgname,
size, precommitted ? ", precommitted" : "");
if (!id_write_format((const struct id *)vginfo->vgid, uuid, sizeof(uuid))) {
stack;
return;
}
log_debug("Metadata cache: VG %s (%s) stored (%d bytes%s).",
vginfo->vgname, uuid, size,
precommitted ? ", precommitted" : "");
}
static void _update_cache_info_lock_state(struct lvmcache_info *info,
@@ -97,9 +126,10 @@ static void _update_cache_info_lock_state(struct lvmcache_info *info,
int was_locked = (info->status & CACHE_LOCKED) ? 1 : 0;
/*
* Cache becomes invalid whenever lock state changes
* Cache becomes invalid whenever lock state changes unless
* exclusive VG_GLOBAL is held (i.e. while scanning).
*/
if (was_locked != locked) {
if (!vgname_is_locked(VG_GLOBAL) && (was_locked != locked)) {
info->status |= CACHE_INVALID;
*cached_vgmetadata_valid = 0;
}
@@ -116,7 +146,7 @@ static void _update_cache_vginfo_lock_state(struct lvmcache_vginfo *vginfo,
struct lvmcache_info *info;
int cached_vgmetadata_valid = 1;
list_iterate_items(info, &vginfo->infos)
dm_list_iterate_items(info, &vginfo->infos)
_update_cache_info_lock_state(info, locked,
&cached_vgmetadata_valid);
@@ -134,7 +164,7 @@ static void _update_cache_lock_state(const char *vgname, int locked)
_update_cache_vginfo_lock_state(vginfo, locked);
}
static void _drop_metadata(const char *vgname)
static void _drop_metadata(const char *vgname, int drop_precommitted)
{
struct lvmcache_vginfo *vginfo;
struct lvmcache_info *info;
@@ -148,29 +178,104 @@ static void _drop_metadata(const char *vgname)
* already invalidated the PV labels (before caching it)
* and we must not do it again.
*/
if (!drop_precommitted && vginfo->precommitted && !vginfo->vgmetadata)
log_error(INTERNAL_ERROR "metadata commit (or revert) missing before "
"dropping metadata from cache.");
if (!vginfo->precommitted)
list_iterate_items(info, &vginfo->infos)
if (drop_precommitted || !vginfo->precommitted)
dm_list_iterate_items(info, &vginfo->infos)
info->status |= CACHE_INVALID;
_free_cached_vgmetadata(vginfo);
}
void lvmcache_drop_metadata(const char *vgname)
/*
* Remote node uses this to upgrade precommited metadata to commited state
* when receives vg_commit notification.
* (Note that devices can be suspended here, if so, precommited metadata are already read.)
*/
void lvmcache_commit_metadata(const char *vgname)
{
struct lvmcache_vginfo *vginfo;
if (!(vginfo = vginfo_from_vgname(vgname, NULL)))
return;
if (vginfo->precommitted) {
log_debug("Precommitted metadata cache: VG %s upgraded to committed.",
vginfo->vgname);
vginfo->precommitted = 0;
}
}
void lvmcache_drop_metadata(const char *vgname, int drop_precommitted)
{
/* For VG_ORPHANS, we need to invalidate all labels on orphan PVs. */
if (!strcmp(vgname, VG_ORPHANS)) {
_drop_metadata(FMT_TEXT_ORPHAN_VG_NAME);
_drop_metadata(FMT_LVM1_ORPHAN_VG_NAME);
_drop_metadata(FMT_POOL_ORPHAN_VG_NAME);
_drop_metadata(FMT_TEXT_ORPHAN_VG_NAME, 0);
_drop_metadata(FMT_LVM1_ORPHAN_VG_NAME, 0);
_drop_metadata(FMT_POOL_ORPHAN_VG_NAME, 0);
/* Indicate that PVs could now be missing from the cache */
init_full_scan_done(0);
} else
_drop_metadata(vgname);
} else if (!vgname_is_locked(VG_GLOBAL))
_drop_metadata(vgname, drop_precommitted);
}
void lvmcache_lock_vgname(const char *vgname, int read_only __attribute((unused)))
/*
* Ensure vgname2 comes after vgname1 alphabetically.
* Orphan locks come last.
* VG_GLOBAL comes first.
*/
static int _vgname_order_correct(const char *vgname1, const char *vgname2)
{
if (is_global_vg(vgname1))
return 1;
if (is_global_vg(vgname2))
return 0;
if (is_orphan_vg(vgname1))
return 0;
if (is_orphan_vg(vgname2))
return 1;
if (strcmp(vgname1, vgname2) < 0)
return 1;
return 0;
}
/*
* Ensure VG locks are acquired in alphabetical order.
*/
int lvmcache_verify_lock_order(const char *vgname)
{
struct dm_hash_node *n;
const char *vgname2;
if (!_lock_hash)
return_0;
dm_hash_iterate(n, _lock_hash) {
if (!dm_hash_get_data(_lock_hash, n))
return_0;
vgname2 = dm_hash_get_key(_lock_hash, n);
if (!_vgname_order_correct(vgname2, vgname)) {
log_errno(EDEADLK, INTERNAL_ERROR "VG lock %s must "
"be requested before %s, not after.",
vgname, vgname2);
return_0;
}
}
return 1;
}
void lvmcache_lock_vgname(const char *vgname, int read_only __attribute__((unused)))
{
if (!_lock_hash && !lvmcache_init()) {
log_error("Internal cache initialisation failed");
@@ -178,9 +283,9 @@ void lvmcache_lock_vgname(const char *vgname, int read_only __attribute((unused)
}
if (dm_hash_lookup(_lock_hash, vgname))
log_error("Internal error: Nested locking attempted on VG %s.",
log_error(INTERNAL_ERROR "Nested locking attempted on VG %s.",
vgname);
if (!dm_hash_insert(_lock_hash, vgname, (void *) 1))
log_error("Cache locking failure for %s", vgname);
@@ -195,13 +300,13 @@ int vgname_is_locked(const char *vgname)
if (!_lock_hash)
return 0;
return dm_hash_lookup(_lock_hash, vgname) ? 1 : 0;
return dm_hash_lookup(_lock_hash, is_orphan_vg(vgname) ? VG_ORPHANS : vgname) ? 1 : 0;
}
void lvmcache_unlock_vgname(const char *vgname)
{
if (!dm_hash_lookup(_lock_hash, vgname))
log_error("Internal error: Attempt to unlock unlocked VG %s.",
log_error(INTERNAL_ERROR "Attempt to unlock unlocked VG %s.",
vgname);
_update_cache_lock_state(vgname, 0);
@@ -225,14 +330,14 @@ static void _vginfo_attach_info(struct lvmcache_vginfo *vginfo,
return;
info->vginfo = vginfo;
list_add(&vginfo->infos, &info->list);
dm_list_add(&vginfo->infos, &info->list);
}
static void _vginfo_detach_info(struct lvmcache_info *info)
{
if (!list_empty(&info->list)) {
list_del(&info->list);
list_init(&info->list);
if (!dm_list_empty(&info->list)) {
dm_list_del(&info->list);
dm_list_init(&info->list);
}
info->vginfo = NULL;
@@ -266,32 +371,32 @@ const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid)
struct lvmcache_vginfo *vginfo;
struct lvmcache_info *info;
struct label *label;
struct list *devh, *tmp;
struct list devs;
struct dm_list *devh, *tmp;
struct dm_list devs;
struct device_list *devl;
char vgid_found[ID_LEN + 1] __attribute((aligned(8)));
char vgid_found[ID_LEN + 1] __attribute__((aligned(8)));
if (!(vginfo = vginfo_from_vgname(vgname, vgid)))
return NULL;
/* This function is normally called before reading metadata so
* we check cached labels here. Unfortunately vginfo is volatile. */
list_init(&devs);
list_iterate_items(info, &vginfo->infos) {
dm_list_init(&devs);
dm_list_iterate_items(info, &vginfo->infos) {
if (!(devl = dm_malloc(sizeof(*devl)))) {
log_error("device_list element allocation failed");
return NULL;
}
devl->dev = info->dev;
list_add(&devs, &devl->list);
dm_list_add(&devs, &devl->list);
}
memcpy(vgid_found, vginfo->vgid, sizeof(vgid_found));
list_iterate_safe(devh, tmp, &devs) {
devl = list_item(devh, struct device_list);
dm_list_iterate_safe(devh, tmp, &devs) {
devl = dm_list_item(devh, struct device_list);
label_read(devl->dev, &label, UINT64_C(0));
list_del(&devl->list);
dm_list_del(&devl->list);
dm_free(devl);
}
@@ -306,7 +411,7 @@ const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid)
struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid)
{
struct lvmcache_vginfo *vginfo;
char id[ID_LEN + 1] __attribute((aligned(8)));
char id[ID_LEN + 1] __attribute__((aligned(8)));
if (!_vgid_hash || !vgid)
return NULL;
@@ -361,7 +466,7 @@ static int _vginfo_is_valid(struct lvmcache_vginfo *vginfo)
struct lvmcache_info *info;
/* Invalid if any info is invalid */
list_iterate_items(info, &vginfo->infos)
dm_list_iterate_items(info, &vginfo->infos)
if (!_info_is_valid(info))
return 0;
@@ -373,7 +478,7 @@ static int _vginfo_is_invalid(struct lvmcache_vginfo *vginfo)
{
struct lvmcache_info *info;
list_iterate_items(info, &vginfo->infos)
dm_list_iterate_items(info, &vginfo->infos)
if (_info_is_valid(info))
return 0;
@@ -387,7 +492,7 @@ static int _vginfo_is_invalid(struct lvmcache_vginfo *vginfo)
struct lvmcache_info *info_from_pvid(const char *pvid, int valid_only)
{
struct lvmcache_info *info;
char id[ID_LEN + 1] __attribute((aligned(8)));
char id[ID_LEN + 1] __attribute__((aligned(8)));
if (!_pvid_hash || !pvid)
return NULL;
@@ -404,6 +509,27 @@ struct lvmcache_info *info_from_pvid(const char *pvid, int valid_only)
return info;
}
char *lvmcache_vgname_from_pvid(struct cmd_context *cmd, const char *pvid)
{
struct lvmcache_info *info;
char *vgname;
if (!device_from_pvid(cmd, (struct id *)pvid, NULL)) {
log_error("Couldn't find device with uuid %s.", pvid);
return NULL;
}
info = info_from_pvid(pvid, 0);
if (!info)
return_NULL;
if (!(vgname = dm_pool_strdup(cmd->mem, info->vginfo->vgname))) {
log_errno(ENOMEM, "vgname allocation failed");
return NULL;
}
return vgname;
}
static void _rescan_entry(struct lvmcache_info *info)
{
struct label *label;
@@ -444,6 +570,11 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
goto out;
}
if (full_scan == 2 && !refresh_filters(cmd)) {
log_error("refresh filters failed");
goto out;
}
if (!(iter = dev_iter_create(cmd->filter, (full_scan == 2) ? 1 : 0))) {
log_error("dev_iter creation failed");
goto out;
@@ -457,11 +588,18 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
_has_scanned = 1;
/* Perform any format-specific scanning e.g. text files */
list_iterate_items(fmt, &cmd->formats) {
dm_list_iterate_items(fmt, &cmd->formats) {
if (fmt->ops->scan && !fmt->ops->scan(fmt))
goto out;
}
/*
* If we are a long-lived process, write out the updated persistent
* device cache for the benefit of short-lived processes.
*/
if (full_scan == 2 && cmd->is_long_lived && cmd->dump_filter)
persistent_filter_dump(cmd->filter, 0);
r = 1;
out:
@@ -498,14 +636,14 @@ struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted)
(!precommitted && vginfo->precommitted && !memlock()))
return NULL;
if (!(fid = vginfo->fmt->ops->create_instance(vginfo->fmt,
vginfo->vgname,
vgid, NULL)))
if (!(fid = vginfo->fmt->ops->create_instance(vginfo->fmt,
vginfo->vgname,
vgid, NULL)))
return_NULL;
if (!(vg = import_vg_from_buffer(vginfo->vgmetadata, fid)) ||
!vg_validate(vg)) {
if (!(vg = import_vg_from_buffer(vginfo->vgmetadata, fid))) {
_free_cached_vgmetadata(vginfo);
vg_release(vg);
return_NULL;
}
@@ -515,19 +653,23 @@ struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted)
return vg;
}
struct list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan)
struct dm_list *lvmcache_get_vgids(struct cmd_context *cmd,
int include_internal)
{
struct list *vgids;
struct dm_list *vgids;
struct lvmcache_vginfo *vginfo;
lvmcache_label_scan(cmd, full_scan);
lvmcache_label_scan(cmd, 0);
if (!(vgids = str_list_create(cmd->mem))) {
log_error("vgids list allocation failed");
return NULL;
}
list_iterate_items(vginfo, &_vginfos) {
dm_list_iterate_items(vginfo, &_vginfos) {
if (!include_internal && is_orphan_vg(vginfo->vgname))
continue;
if (!str_list_add(cmd->mem, vgids,
dm_pool_strdup(cmd->mem, vginfo->vgid))) {
log_error("strlist allocation failed");
@@ -538,22 +680,26 @@ struct list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan)
return vgids;
}
struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan)
struct dm_list *lvmcache_get_vgnames(struct cmd_context *cmd,
int include_internal)
{
struct list *vgnames;
struct dm_list *vgnames;
struct lvmcache_vginfo *vginfo;
lvmcache_label_scan(cmd, full_scan);
lvmcache_label_scan(cmd, 0);
if (!(vgnames = str_list_create(cmd->mem))) {
log_error("vgnames list allocation failed");
log_errno(ENOMEM, "vgnames list allocation failed");
return NULL;
}
list_iterate_items(vginfo, &_vginfos) {
dm_list_iterate_items(vginfo, &_vginfos) {
if (!include_internal && is_orphan_vg(vginfo->vgname))
continue;
if (!str_list_add(cmd->mem, vgnames,
dm_pool_strdup(cmd->mem, vginfo->vgname))) {
log_error("strlist allocation failed");
log_errno(ENOMEM, "strlist allocation failed");
return NULL;
}
}
@@ -561,10 +707,10 @@ struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan)
return vgnames;
}
struct list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
struct dm_list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
const char *vgid)
{
struct list *pvids;
struct dm_list *pvids;
struct lvmcache_vginfo *vginfo;
struct lvmcache_info *info;
@@ -576,7 +722,7 @@ struct list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
if (!(vginfo = vginfo_from_vgname(vgname, vgid)))
return pvids;
list_iterate_items(info, &vginfo->infos) {
dm_list_iterate_items(info, &vginfo->infos) {
if (!str_list_add(cmd->mem, pvids,
dm_pool_strdup(cmd->mem, info->dev->pvid))) {
log_error("strlist allocation failed");
@@ -587,7 +733,8 @@ struct list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
return pvids;
}
struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid,
unsigned *scan_done_once)
{
struct label *label;
struct lvmcache_info *info;
@@ -612,10 +759,12 @@ struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
}
}
if (memlock())
if (memlock() || (scan_done_once && *scan_done_once))
return NULL;
lvmcache_label_scan(cmd, 2);
if (scan_done_once)
*scan_done_once = 1;
/* Try again */
if ((info = info_from_pvid((char *) pvid, 0))) {
@@ -629,6 +778,25 @@ struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid)
return NULL;
}
const char *pvid_from_devname(struct cmd_context *cmd,
const char *devname)
{
struct device *dev;
struct label *label;
if (!(dev = dev_cache_get(devname, cmd->filter))) {
log_error("%s: Couldn't find device. Check your filters?",
devname);
return NULL;
}
if (!(label_read(dev, &label, UINT64_C(0))))
return NULL;
return dev->pvid;
}
static int _free_vginfo(struct lvmcache_vginfo *vginfo)
{
struct lvmcache_vginfo *primary_vginfo, *vginfo2;
@@ -663,7 +831,7 @@ static int _free_vginfo(struct lvmcache_vginfo *vginfo)
vginfo_from_vgid(vginfo->vgid) == vginfo)
dm_hash_remove(_vgid_hash, vginfo->vgid);
list_del(&vginfo->list);
dm_list_del(&vginfo->list);
dm_free(vginfo);
@@ -680,7 +848,7 @@ static int _drop_vginfo(struct lvmcache_info *info, struct lvmcache_vginfo *vgin
/* vginfo still referenced? */
if (!vginfo || is_orphan_vg(vginfo->vgname) ||
!list_empty(&vginfo->infos))
!dm_list_empty(&vginfo->infos))
return 1;
if (!_free_vginfo(vginfo))
@@ -706,11 +874,14 @@ void lvmcache_del(struct lvmcache_info *info)
static int _lvmcache_update_pvid(struct lvmcache_info *info, const char *pvid)
{
if (!strcmp(info->dev->pvid, pvid))
/*
* Nothing to do if already stored with same pvid.
*/
if (((dm_hash_lookup(_pvid_hash, pvid)) == info) &&
!strcmp(info->dev->pvid, pvid))
return 1;
if (*info->dev->pvid) {
if (*info->dev->pvid)
dm_hash_remove(_pvid_hash, info->dev->pvid);
}
strncpy(info->dev->pvid, pvid, sizeof(info->dev->pvid));
if (!dm_hash_insert(_pvid_hash, pvid, info)) {
log_error("_lvmcache_update: pvid insertion failed: %s", pvid);
@@ -759,10 +930,10 @@ static int _insert_vginfo(struct lvmcache_vginfo *new_vginfo, const char *vgid,
struct lvmcache_vginfo *primary_vginfo)
{
struct lvmcache_vginfo *last_vginfo = primary_vginfo;
char uuid_primary[64] __attribute((aligned(8)));
char uuid_new[64] __attribute((aligned(8)));
char uuid_primary[64] __attribute__((aligned(8)));
char uuid_new[64] __attribute__((aligned(8)));
int use_new = 0;
/* Pre-existing VG takes precedence. Unexported VG takes precedence. */
if (primary_vginfo) {
if (!id_write_format((const struct id *)vgid, uuid_new, sizeof(uuid_new)))
@@ -782,37 +953,37 @@ static int _insert_vginfo(struct lvmcache_vginfo *new_vginfo, const char *vgid,
*/
if (!(primary_vginfo->status & EXPORTED_VG) &&
(vgstatus & EXPORTED_VG))
log_error("WARNING: Duplicate VG name %s: "
"Existing %s takes precedence over "
"exported %s", new_vginfo->vgname,
uuid_primary, uuid_new);
log_warn("WARNING: Duplicate VG name %s: "
"Existing %s takes precedence over "
"exported %s", new_vginfo->vgname,
uuid_primary, uuid_new);
else if ((primary_vginfo->status & EXPORTED_VG) &&
!(vgstatus & EXPORTED_VG)) {
log_error("WARNING: Duplicate VG name %s: "
"%s takes precedence over exported %s",
new_vginfo->vgname, uuid_new,
uuid_primary);
log_warn("WARNING: Duplicate VG name %s: "
"%s takes precedence over exported %s",
new_vginfo->vgname, uuid_new,
uuid_primary);
use_new = 1;
} else if (primary_vginfo->creation_host &&
!strcmp(primary_vginfo->creation_host,
primary_vginfo->fmt->cmd->hostname))
log_error("WARNING: Duplicate VG name %s: "
"Existing %s (created here) takes precedence "
"over %s", new_vginfo->vgname, uuid_primary,
uuid_new);
log_warn("WARNING: Duplicate VG name %s: "
"Existing %s (created here) takes precedence "
"over %s", new_vginfo->vgname, uuid_primary,
uuid_new);
else if (!primary_vginfo->creation_host && creation_host) {
log_error("WARNING: Duplicate VG name %s: "
"%s (with creation_host) takes precedence over %s",
new_vginfo->vgname, uuid_new,
uuid_primary);
log_warn("WARNING: Duplicate VG name %s: "
"%s (with creation_host) takes precedence over %s",
new_vginfo->vgname, uuid_new,
uuid_primary);
use_new = 1;
} else if (creation_host &&
!strcmp(creation_host,
primary_vginfo->fmt->cmd->hostname)) {
log_error("WARNING: Duplicate VG name %s: "
"%s (created here) takes precedence over %s",
new_vginfo->vgname, uuid_new,
uuid_primary);
log_warn("WARNING: Duplicate VG name %s: "
"%s (created here) takes precedence over %s",
new_vginfo->vgname, uuid_new,
uuid_primary);
use_new = 1;
}
@@ -845,6 +1016,7 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
{
struct lvmcache_vginfo *vginfo, *primary_vginfo, *orphan_vginfo;
struct lvmcache_info *info2, *info3;
char mdabuf[32];
// struct lvmcache_vginfo *old_vginfo, *next;
if (!vgname || (info && info->vginfo && !strcmp(info->vginfo->vgname, vgname)))
@@ -902,7 +1074,7 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
log_error("cache vgname alloc failed for %s", vgname);
return 0;
}
list_init(&vginfo->infos);
dm_list_init(&vginfo->infos);
/*
* If we're scanning and there's an invalidated entry, remove it.
@@ -910,15 +1082,20 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
*/
while ((primary_vginfo = vginfo_from_vgname(vgname, NULL)) &&
_scanning_in_progress && _vginfo_is_invalid(primary_vginfo))
list_iterate_items_safe(info2, info3, &primary_vginfo->infos) {
dm_list_iterate_items_safe(info2, info3, &primary_vginfo->infos) {
orphan_vginfo = vginfo_from_vgname(primary_vginfo->fmt->orphan_vg_name, NULL);
_drop_vginfo(info2, primary_vginfo);
_vginfo_attach_info(orphan_vginfo, info2);
log_debug("lvmcache: %s: now in VG %s%s%s%s",
if (info2->mdas.n)
sprintf(mdabuf, " with %u mdas",
dm_list_size(&info2->mdas));
else
mdabuf[0] = '\0';
log_debug("lvmcache: %s: now in VG %s%s%s%s%s",
dev_name(info2->dev),
vgname, orphan_vginfo->vgid[0] ? " (" : "",
orphan_vginfo->vgid[0] ? orphan_vginfo->vgid : "",
orphan_vginfo->vgid[0] ? ")" : "");
orphan_vginfo->vgid[0] ? ")" : "", mdabuf);
}
if (!_insert_vginfo(vginfo, vgid, vgstatus, creation_host,
@@ -929,9 +1106,9 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
}
/* Ensure orphans appear last on list_iterate */
if (is_orphan_vg(vgname))
list_add(&_vginfos, &vginfo->list);
dm_list_add(&_vginfos, &vginfo->list);
else
list_add_h(&_vginfos, &vginfo->list);
dm_list_add_h(&_vginfos, &vginfo->list);
/***
}
***/
@@ -947,13 +1124,17 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
/* FIXME Check consistency of list! */
vginfo->fmt = fmt;
if (info)
log_debug("lvmcache: %s: now in VG %s%s%s%s",
if (info) {
if (info->mdas.n)
sprintf(mdabuf, " with %u mdas", dm_list_size(&info->mdas));
else
mdabuf[0] = '\0';
log_debug("lvmcache: %s: now in VG %s%s%s%s%s",
dev_name(info->dev),
vgname, vginfo->vgid[0] ? " (" : "",
vginfo->vgid[0] ? vginfo->vgid : "",
vginfo->vgid[0] ? ")" : "");
else
vginfo->vgid[0] ? ")" : "", mdabuf);
} else
log_debug("lvmcache: initialised VG %s", vgname);
return 1;
@@ -1009,14 +1190,15 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
uint32_t vgstatus, const char *creation_host)
{
if (!vgname && !info->vginfo) {
log_error("Internal error: NULL vgname handed to cache");
log_error(INTERNAL_ERROR "NULL vgname handed to cache");
/* FIXME Remove this */
vgname = info->fmt->orphan_vg_name;
vgid = vgname;
}
/* If PV without mdas is already in a real VG, don't make it orphan */
if (is_orphan_vg(vgname) && info->vginfo && !list_size(&info->mdas) &&
if (is_orphan_vg(vgname) && info->vginfo &&
mdas_empty_or_ignored(&info->mdas) &&
!is_orphan_vg(info->vginfo->vgname) && memlock())
return 1;
@@ -1037,12 +1219,11 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
{
struct pv_list *pvl;
struct lvmcache_info *info;
struct lvmcache_vginfo *vginfo;
char pvid_s[ID_LEN + 1] __attribute((aligned(8)));
char pvid_s[ID_LEN + 1] __attribute__((aligned(8)));
pvid_s[sizeof(pvid_s) - 1] = '\0';
list_iterate_items(pvl, &vg->pvs) {
dm_list_iterate_items(pvl, &vg->pvs) {
strncpy(pvid_s, (char *) &pvl->pv->id, sizeof(pvid_s) - 1);
/* FIXME Could pvl->pv->dev->pvid ever be different? */
if ((info = info_from_pvid(pvid_s, 0)) &&
@@ -1053,9 +1234,8 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
}
/* store text representation of vg to cache */
if (vg->cmd->current_settings.cache_vgmetadata &&
(vginfo = vginfo_from_vgname(vg->name, NULL)))
_store_metadata(vginfo, vg, precommitted);
if (vg->cmd->current_settings.cache_vgmetadata)
_store_metadata(vg, precommitted);
return 1;
}
@@ -1067,7 +1247,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
{
struct label *label;
struct lvmcache_info *existing, *info;
char pvid_s[ID_LEN + 1] __attribute((aligned(8)));
char pvid_s[ID_LEN + 1] __attribute__((aligned(8)));
if (!_vgname_hash && !lvmcache_init()) {
log_error("Internal cache initialisation failed");
@@ -1090,16 +1270,17 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
label->info = info;
info->label = label;
list_init(&info->list);
dm_list_init(&info->list);
info->dev = dev;
} else {
if (existing->dev != dev) {
/* Is the existing entry a duplicate pvid e.g. md ? */
if (MAJOR(existing->dev->dev) == md_major() &&
MAJOR(dev->dev) != md_major()) {
if (dev_subsystem_part_major(existing->dev) &&
!dev_subsystem_part_major(dev)) {
log_very_verbose("Ignoring duplicate PV %s on "
"%s - using md %s",
"%s - using %s %s",
pvid, dev_name(dev),
dev_subsystem_name(existing->dev),
dev_name(existing->dev));
return NULL;
} else if (dm_is_dm_major(MAJOR(existing->dev->dev)) &&
@@ -1109,11 +1290,12 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
pvid, dev_name(dev),
dev_name(existing->dev));
return NULL;
} else if (MAJOR(existing->dev->dev) != md_major() &&
MAJOR(dev->dev) == md_major())
} else if (!dev_subsystem_part_major(existing->dev) &&
dev_subsystem_part_major(dev))
log_very_verbose("Duplicate PV %s on %s - "
"using md %s", pvid,
"using %s %s", pvid,
dev_name(existing->dev),
dev_subsystem_name(existing->dev),
dev_name(dev));
else if (!dm_is_dm_major(MAJOR(existing->dev->dev)) &&
dm_is_dm_major(MAJOR(dev->dev)))
@@ -1125,11 +1307,15 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
//else if (dm_is_dm_major(MAJOR(existing->dev->dev)) &&
//dm_is_dm_major(MAJOR(dev->dev)))
//
else
else if (!strcmp(pvid_s, existing->dev->pvid))
log_error("Found duplicate PV %s: using %s not "
"%s", pvid, dev_name(dev),
dev_name(existing->dev));
}
if (strcmp(pvid_s, existing->dev->pvid))
log_debug("Updating pvid cache to %s (%s) from %s (%s)",
pvid_s, dev_name(dev),
existing->dev->pvid, dev_name(existing->dev));
/* Switch over to new preferred device */
existing->dev = dev;
info = existing;
@@ -1199,7 +1385,7 @@ static void _lvmcache_destroy_lockname(struct dm_hash_node *n)
if (!strcmp(vgname, VG_GLOBAL))
_vg_global_lock_held = 1;
else
log_error("Internal error: Volume Group %s was not unlocked",
log_error(INTERNAL_ERROR "Volume Group %s was not unlocked",
dm_hash_get_key(_lock_hash, n));
}
@@ -1235,9 +1421,9 @@ void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans)
_lock_hash = NULL;
}
if (!list_empty(&_vginfos))
log_error("Internal error: _vginfos list should be empty");
list_init(&_vginfos);
if (!dm_list_empty(&_vginfos))
log_error(INTERNAL_ERROR "_vginfos list should be empty");
dm_list_init(&_vginfos);
if (retain_orphans)
init_lvmcache_orphans(cmd);

37
lib/cache/lvmcache.h vendored
View File

@@ -19,9 +19,10 @@
#include "dev-cache.h"
#include "uuid.h"
#include "label.h"
#include "locking.h"
#define ORPHAN_PREFIX "#"
#define ORPHAN_VG_NAME(fmt) ORPHAN_PREFIX "orphans_" fmt
#define ORPHAN_PREFIX VG_ORPHANS
#define ORPHAN_VG_NAME(fmt) ORPHAN_PREFIX "_" fmt
#define CACHE_INVALID 0x00000001
#define CACHE_LOCKED 0x00000002
@@ -35,8 +36,8 @@ struct volume_group;
/* One per VG */
struct lvmcache_vginfo {
struct list list; /* Join these vginfos together */
struct list infos; /* List head for lvmcache_infos */
struct dm_list list; /* Join these vginfos together */
struct dm_list infos; /* List head for lvmcache_infos */
const struct format_type *fmt;
char *vgname; /* "" == orphan */
uint32_t status;
@@ -50,9 +51,9 @@ struct lvmcache_vginfo {
/* One per device */
struct lvmcache_info {
struct list list; /* Join VG members together */
struct list mdas; /* list head for metadata areas */
struct list das; /* list head for data areas */
struct dm_list list; /* Join VG members together */
struct dm_list mdas; /* list head for metadata areas */
struct dm_list das; /* list head for data areas */
struct lvmcache_vginfo *vginfo; /* NULL == unknown */
struct label *label;
const struct format_type *fmt;
@@ -84,6 +85,7 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted);
void lvmcache_lock_vgname(const char *vgname, int read_only);
void lvmcache_unlock_vgname(const char *vgname);
int lvmcache_verify_lock_order(const char *vgname);
/* Queries */
const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid);
@@ -92,24 +94,31 @@ struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname,
struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid);
struct lvmcache_info *info_from_pvid(const char *pvid, int valid_only);
const char *vgname_from_vgid(struct dm_pool *mem, const char *vgid);
struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid);
struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid,
unsigned *scan_done_once);
const char *pvid_from_devname(struct cmd_context *cmd,
const char *dev_name);
char *lvmcache_vgname_from_pvid(struct cmd_context *cmd, const char *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 */
struct list *lvmcache_get_vgnames(struct cmd_context *cmd, int full_scan);
/* If include_internal is not set, return only proper vg names. */
struct dm_list *lvmcache_get_vgnames(struct cmd_context *cmd,
int include_internal);
/* Returns list of struct str_lists containing pool-allocated copy of vgids */
/* Set full_scan to 1 to reread every filtered device label */
struct list *lvmcache_get_vgids(struct cmd_context *cmd, int full_scan);
/* If include_internal is not set, return only proper vg ids. */
struct dm_list *lvmcache_get_vgids(struct cmd_context *cmd,
int include_internal);
/* Returns list of struct str_lists containing pool-allocated copy of pvids */
struct list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
struct dm_list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
const char *vgid);
/* Returns cached volume group metadata. */
struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted);
void lvmcache_drop_metadata(const char *vgname);
void lvmcache_drop_metadata(const char *vgname, int drop_precommitted);
void lvmcache_commit_metadata(const char *vgname);
#endif

View File

@@ -21,4 +21,6 @@
#define EINVALID_CMD_LINE 3
#define ECMD_FAILED 5
/* FIXME Also returned by cmdlib. */
#endif

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -64,7 +64,7 @@ static int _get_env_vars(struct cmd_context *cmd)
/* Set to "" to avoid using any system directory */
if ((e = getenv("LVM_SYSTEM_DIR"))) {
if (dm_snprintf(cmd->sys_dir, sizeof(cmd->sys_dir),
if (dm_snprintf(cmd->system_dir, sizeof(cmd->system_dir),
"%s", e) < 0) {
log_error("LVM_SYSTEM_DIR environment variable "
"is too long.");
@@ -75,6 +75,49 @@ static int _get_env_vars(struct cmd_context *cmd)
return 1;
}
static void _get_sysfs_dir(struct cmd_context *cmd)
{
static char proc_mounts[PATH_MAX];
static char *split[4], buffer[PATH_MAX + 16];
FILE *fp;
char *sys_mnt = NULL;
cmd->sysfs_dir[0] = '\0';
if (!*cmd->proc_dir) {
log_debug("No proc filesystem found: skipping sysfs detection");
return;
}
if (dm_snprintf(proc_mounts, sizeof(proc_mounts),
"%s/mounts", cmd->proc_dir) < 0) {
log_error("Failed to create /proc/mounts string for sysfs detection");
return;
}
if (!(fp = fopen(proc_mounts, "r"))) {
log_sys_error("_get_sysfs_dir: fopen %s", proc_mounts);
return;
}
while (fgets(buffer, sizeof(buffer), fp)) {
if (dm_split_words(buffer, 4, 0, split) == 4 &&
!strcmp(split[2], "sysfs")) {
sys_mnt = split[1];
break;
}
}
if (fclose(fp))
log_sys_error("fclose", proc_mounts);
if (!sys_mnt) {
log_error("Failed to find sysfs mount point");
return;
}
strncpy(cmd->sysfs_dir, sys_mnt, sizeof(cmd->sysfs_dir));
}
static void _init_logging(struct cmd_context *cmd)
{
int append = 1;
@@ -104,7 +147,9 @@ static void _init_logging(struct cmd_context *cmd)
/* Log message formatting */
init_indent(find_config_tree_int(cmd, "log/indent",
DEFAULT_INDENT));
DEFAULT_INDENT));
init_abort_on_internal_errors(find_config_tree_int(cmd, "global/abort_on_internal_errors",
DEFAULT_ABORT_ON_INTERNAL_ERRORS));
cmd->default_settings.msg_prefix = find_config_tree_str(cmd,
"log/prefix",
@@ -119,6 +164,7 @@ static void _init_logging(struct cmd_context *cmd)
/* Test mode */
cmd->default_settings.test =
find_config_tree_int(cmd, "global/test", 0);
init_test(cmd->default_settings.test);
/* Settings for logging to file */
if (find_config_tree_int(cmd, "log/overwrite", DEFAULT_OVERWRITE))
@@ -146,14 +192,19 @@ static void _init_logging(struct cmd_context *cmd)
/* Tell device-mapper about our logging */
#ifdef DEVMAPPER_SUPPORT
dm_log_init(print_log);
dm_log_with_errno_init(print_log);
#endif
reset_log_duplicated();
reset_lvm_errno(1);
}
static int _process_config(struct cmd_context *cmd)
{
mode_t old_umask;
const char *read_ahead;
struct stat st;
const struct config_node *cn;
struct config_value *cv;
/* umask */
cmd->default_settings.umask = find_config_tree_int(cmd,
@@ -184,11 +235,15 @@ static int _process_config(struct cmd_context *cmd)
}
if (*cmd->proc_dir && !dir_exists(cmd->proc_dir)) {
log_error("WARNING: proc dir %s not found - some checks will be bypassed",
cmd->proc_dir);
log_warn("WARNING: proc dir %s not found - some checks will be bypassed",
cmd->proc_dir);
cmd->proc_dir[0] = '\0';
}
/* FIXME Use global value of sysfs_dir everywhere instead cmd->sysfs_dir. */
_get_sysfs_dir(cmd);
set_sysfs_dir_path(cmd->sysfs_dir);
/* activation? */
cmd->default_settings.activation = find_config_tree_int(cmd,
"global/activation",
@@ -218,6 +273,47 @@ static int _process_config(struct cmd_context *cmd)
return 0;
}
cmd->default_settings.udev_rules = find_config_tree_int(cmd,
"activation/udev_rules",
DEFAULT_UDEV_RULES);
cmd->default_settings.udev_sync = find_config_tree_int(cmd,
"activation/udev_sync",
DEFAULT_UDEV_SYNC);
cmd->stripe_filler = find_config_tree_str(cmd,
"activation/missing_stripe_filler",
DEFAULT_STRIPE_FILLER);
/* FIXME Missing error code checks from the stats, not log_warn?, notify if setting overridden, delay message/check till it is actually used (eg consider if lvm shell - file could appear later after this check)? */
if (!strcmp(cmd->stripe_filler, "/dev/ioerror") &&
stat(cmd->stripe_filler, &st))
cmd->stripe_filler = "error";
if (strcmp(cmd->stripe_filler, "error")) {
if (stat(cmd->stripe_filler, &st)) {
log_warn("WARNING: activation/missing_stripe_filler = \"%s\" "
"is invalid,", cmd->stripe_filler);
log_warn(" stat failed: %s", strerror(errno));
log_warn("Falling back to \"error\" missing_stripe_filler.");
cmd->stripe_filler = "error";
} else if (!S_ISBLK(st.st_mode)) {
log_warn("WARNING: activation/missing_stripe_filler = \"%s\" "
"is not a block device.", cmd->stripe_filler);
log_warn("Falling back to \"error\" missing_stripe_filler.");
cmd->stripe_filler = "error";
}
}
cmd->si_unit_consistency = find_config_tree_int(cmd,
"global/si_unit_consistency",
DEFAULT_SI_UNIT_CONSISTENCY);
if ((cn = find_config_tree_node(cmd, "activation/mlock_filter")))
for (cv = cn->v; cv; cv = cv->next)
if ((cv->type != CFG_STRING) || !cv->v.str[0])
log_error("Ignoring invalid activation/mlock_filter entry in config file");
return 1;
}
@@ -322,7 +418,7 @@ static int _load_config_file(struct cmd_context *cmd, const char *tag)
filler = "_";
if (dm_snprintf(config_file, sizeof(config_file), "%s/lvm%s%s.conf",
cmd->sys_dir, filler, tag) < 0) {
cmd->system_dir, filler, tag) < 0) {
log_error("LVM_SYSTEM_DIR or tag was too long");
return 0;
}
@@ -340,7 +436,7 @@ static int _load_config_file(struct cmd_context *cmd, const char *tag)
/* Is there a config file? */
if (stat(config_file, &info) == -1) {
if (errno == ENOENT) {
list_add(&cmd->config_files, &cfl->list);
dm_list_add(&cmd->config_files, &cfl->list);
goto out;
}
log_sys_error("stat", config_file);
@@ -355,7 +451,7 @@ static int _load_config_file(struct cmd_context *cmd, const char *tag)
return 0;
}
list_add(&cmd->config_files, &cfl->list);
dm_list_add(&cmd->config_files, &cfl->list);
out:
if (*tag)
@@ -371,7 +467,7 @@ static int _load_config_file(struct cmd_context *cmd, const char *tag)
static int _init_lvm_conf(struct cmd_context *cmd)
{
/* No config file if LVM_SYSTEM_DIR is empty */
if (!*cmd->sys_dir) {
if (!*cmd->system_dir) {
if (!(cmd->cft = create_config_tree(NULL, 0))) {
log_error("Failed to create config tree");
return 0;
@@ -391,7 +487,7 @@ static int _init_tag_configs(struct cmd_context *cmd)
struct str_list *sl;
/* Tag list may grow while inside this loop */
list_iterate_items(sl, &cmd->tags) {
dm_list_iterate_items(sl, &cmd->tags) {
if (!_load_config_file(cmd, sl->str))
return_0;
}
@@ -411,7 +507,7 @@ static int _merge_config_files(struct cmd_context *cmd)
}
}
list_iterate_items(cfl, &cmd->config_files) {
dm_list_iterate_items(cfl, &cmd->config_files) {
/* Merge all config trees into cmd->cft using merge/tag rules */
if (!merge_config_tree(cmd, cmd->cft, cfl->cft))
return_0;
@@ -422,10 +518,10 @@ static int _merge_config_files(struct cmd_context *cmd)
static void _destroy_tags(struct cmd_context *cmd)
{
struct list *slh, *slht;
struct dm_list *slh, *slht;
list_iterate_safe(slh, slht, &cmd->tags) {
list_del(slh);
dm_list_iterate_safe(slh, slht, &cmd->tags) {
dm_list_del(slh);
}
}
@@ -433,7 +529,7 @@ int config_files_changed(struct cmd_context *cmd)
{
struct config_tree_list *cfl;
list_iterate_items(cfl, &cmd->config_files) {
dm_list_iterate_items(cfl, &cmd->config_files) {
if (config_file_changed(cfl->cft))
return 1;
}
@@ -445,16 +541,18 @@ static void _destroy_tag_configs(struct cmd_context *cmd)
{
struct config_tree_list *cfl;
if (cmd->cft && cmd->cft->root) {
dm_list_iterate_items(cfl, &cmd->config_files) {
if (cfl->cft == cmd->cft)
cmd->cft = NULL;
destroy_config_tree(cfl->cft);
}
if (cmd->cft) {
destroy_config_tree(cmd->cft);
cmd->cft = NULL;
}
list_iterate_items(cfl, &cmd->config_files) {
destroy_config_tree(cfl->cft);
}
list_init(&cmd->config_files);
dm_list_init(&cmd->config_files);
}
static int _init_dev_cache(struct cmd_context *cmd)
@@ -534,7 +632,7 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
*/
if (find_config_tree_bool(cmd, "devices/sysfs_scan",
DEFAULT_SYSFS_SCAN)) {
if ((filters[nr_filt] = sysfs_filter_create(cmd->proc_dir)))
if ((filters[nr_filt] = sysfs_filter_create(cmd->sysfs_dir)))
nr_filt++;
}
@@ -545,14 +643,14 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
else if (!(filters[nr_filt++] = regex_filter_create(cn->v))) {
log_error("Failed to create regex device filter");
return NULL;
goto err;
}
/* device type filter. Required. */
cn = find_config_tree_node(cmd, "devices/types");
if (!(filters[nr_filt++] = lvm_type_filter_create(cmd->proc_dir, cn))) {
log_error("Failed to create lvm type filter");
return NULL;
goto err;
}
/* md component filter. Optional, non-critical. */
@@ -566,6 +664,11 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
/* Only build a composite filter if we really need it. */
return (nr_filt == 1) ?
filters[0] : composite_filter_create(nr_filt, filters);
err:
nr_filt--; /* skip NULL */
while (nr_filt-- > 0)
filters[nr_filt]->destroy(filters[nr_filt]);
return NULL;
}
static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache)
@@ -592,7 +695,7 @@ static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache
if (cache_dir || cache_file_prefix) {
if (dm_snprintf(cache_file, sizeof(cache_file),
"%s%s%s/%s.cache",
cache_dir ? "" : cmd->sys_dir,
cache_dir ? "" : cmd->system_dir,
cache_dir ? "" : "/",
cache_dir ? : DEFAULT_CACHE_SUBDIR,
cache_file_prefix ? : DEFAULT_CACHE_FILE_PREFIX) < 0) {
@@ -602,7 +705,7 @@ static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache
} else if (!(dev_cache = find_config_tree_str(cmd, "devices/cache", NULL)) &&
(dm_snprintf(cache_file, sizeof(cache_file),
"%s/%s/%s.cache",
cmd->sys_dir, DEFAULT_CACHE_SUBDIR,
cmd->system_dir, DEFAULT_CACHE_SUBDIR,
DEFAULT_CACHE_FILE_PREFIX) < 0)) {
log_error("Persistent cache filename too long.");
return 0;
@@ -620,7 +723,7 @@ static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache
if (find_config_tree_int(cmd, "devices/write_cache_state", 1))
cmd->dump_filter = 1;
if (!*cmd->sys_dir)
if (!*cmd->system_dir)
cmd->dump_filter = 0;
/*
@@ -639,6 +742,19 @@ static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache
return 1;
}
struct format_type *get_format_by_name(struct cmd_context *cmd, const char *format)
{
struct format_type *fmt;
dm_list_iterate_items(fmt, &cmd->formats)
if (!strcasecmp(fmt->name, format) ||
!strcasecmp(fmt->name + 3, format) ||
(fmt->alias && !strcasecmp(fmt->alias, format)))
return fmt;
return NULL;
}
static int _init_formats(struct cmd_context *cmd)
{
const char *format;
@@ -655,19 +771,19 @@ static int _init_formats(struct cmd_context *cmd)
if (!(fmt = init_lvm1_format(cmd)))
return 0;
fmt->library = NULL;
list_add(&cmd->formats, &fmt->list);
dm_list_add(&cmd->formats, &fmt->list);
#endif
#ifdef POOL_INTERNAL
if (!(fmt = init_pool_format(cmd)))
return 0;
fmt->library = NULL;
list_add(&cmd->formats, &fmt->list);
dm_list_add(&cmd->formats, &fmt->list);
#endif
#ifdef HAVE_LIBDL
/* Load any formats in shared libs if not static */
if (!cmd->is_static &&
if (!is_static() &&
(cn = find_config_tree_node(cmd, "global/format_libraries"))) {
struct config_value *cv;
@@ -694,7 +810,7 @@ static int _init_formats(struct cmd_context *cmd)
if (!(fmt = init_format_fn(cmd)))
return 0;
fmt->library = lib;
list_add(&cmd->formats, &fmt->list);
dm_list_add(&cmd->formats, &fmt->list);
}
}
#endif
@@ -702,17 +818,18 @@ static int _init_formats(struct cmd_context *cmd)
if (!(fmt = create_text_format(cmd)))
return 0;
fmt->library = NULL;
list_add(&cmd->formats, &fmt->list);
dm_list_add(&cmd->formats, &fmt->list);
cmd->fmt_backup = fmt;
format = find_config_tree_str(cmd, "global/format",
DEFAULT_FORMAT);
list_iterate_items(fmt, &cmd->formats) {
dm_list_iterate_items(fmt, &cmd->formats) {
if (!strcasecmp(fmt->name, format) ||
(fmt->alias && !strcasecmp(fmt->alias, format))) {
cmd->default_settings.fmt = fmt;
cmd->default_settings.fmt_name = fmt->name;
cmd->fmt = fmt;
return 1;
}
}
@@ -725,16 +842,64 @@ int init_lvmcache_orphans(struct cmd_context *cmd)
{
struct format_type *fmt;
list_iterate_items(fmt, &cmd->formats)
dm_list_iterate_items(fmt, &cmd->formats)
if (!lvmcache_add_orphan_vginfo(fmt->orphan_vg_name, fmt))
return_0;
return 1;
}
struct segtype_library {
struct cmd_context *cmd;
void *lib;
const char *libname;
};
int lvm_register_segtype(struct segtype_library *seglib,
struct segment_type *segtype)
{
struct segment_type *segtype2;
segtype->library = seglib->lib;
segtype->cmd = seglib->cmd;
dm_list_iterate_items(segtype2, &seglib->cmd->segtypes) {
if (strcmp(segtype2->name, segtype->name))
continue;
log_error("Duplicate segment type %s: "
"unloading shared library %s",
segtype->name, seglib->libname);
segtype->ops->destroy(segtype);
return 0;
}
dm_list_add(&seglib->cmd->segtypes, &segtype->list);
return 1;
}
static int _init_single_segtype(struct cmd_context *cmd,
struct segtype_library *seglib)
{
struct segment_type *(*init_segtype_fn) (struct cmd_context *);
struct segment_type *segtype;
if (!(init_segtype_fn = dlsym(seglib->lib, "init_segtype"))) {
log_error("Shared library %s does not contain segment type "
"functions", seglib->libname);
return 0;
}
if (!(segtype = init_segtype_fn(seglib->cmd)))
return_0;
return lvm_register_segtype(seglib, segtype);
}
static int _init_segtypes(struct cmd_context *cmd)
{
struct segment_type *segtype;
struct segtype_library seglib = { .cmd = cmd };
#ifdef HAVE_LIBDL
const struct config_node *cn;
@@ -743,41 +908,50 @@ static int _init_segtypes(struct cmd_context *cmd)
if (!(segtype = init_striped_segtype(cmd)))
return 0;
segtype->library = NULL;
list_add(&cmd->segtypes, &segtype->list);
dm_list_add(&cmd->segtypes, &segtype->list);
if (!(segtype = init_zero_segtype(cmd)))
return 0;
segtype->library = NULL;
list_add(&cmd->segtypes, &segtype->list);
dm_list_add(&cmd->segtypes, &segtype->list);
if (!(segtype = init_error_segtype(cmd)))
return 0;
segtype->library = NULL;
list_add(&cmd->segtypes, &segtype->list);
dm_list_add(&cmd->segtypes, &segtype->list);
if (!(segtype = init_free_segtype(cmd)))
return 0;
segtype->library = NULL;
dm_list_add(&cmd->segtypes, &segtype->list);
#ifdef SNAPSHOT_INTERNAL
if (!(segtype = init_snapshot_segtype(cmd)))
return 0;
segtype->library = NULL;
list_add(&cmd->segtypes, &segtype->list);
dm_list_add(&cmd->segtypes, &segtype->list);
#endif
#ifdef MIRRORED_INTERNAL
if (!(segtype = init_mirrored_segtype(cmd)))
return 0;
segtype->library = NULL;
list_add(&cmd->segtypes, &segtype->list);
dm_list_add(&cmd->segtypes, &segtype->list);
#endif
#ifdef REPLICATOR_INTERNAL
if (!init_replicator_segtype(&seglib))
return 0;
#endif
#ifdef HAVE_LIBDL
/* Load any formats in shared libs unless static */
if (!cmd->is_static &&
if (!is_static() &&
(cn = find_config_tree_node(cmd, "global/segment_libraries"))) {
struct config_value *cv;
struct segment_type *(*init_segtype_fn) (struct cmd_context *);
void *lib;
struct segment_type *segtype2;
int (*init_multiple_segtypes_fn) (struct cmd_context *,
struct segtype_library *);
for (cv = cn->v; cv; cv = cv->next) {
if (cv->type != CFG_STRING) {
@@ -785,32 +959,37 @@ static int _init_segtypes(struct cmd_context *cmd)
"global/segment_libraries");
return 0;
}
if (!(lib = load_shared_library(cmd, cv->v.str,
seglib.libname = cv->v.str;
if (!(seglib.lib = load_shared_library(cmd,
seglib.libname,
"segment type", 0)))
return_0;
if (!(init_segtype_fn = dlsym(lib, "init_segtype"))) {
log_error("Shared library %s does not contain "
"segment type functions", cv->v.str);
dlclose(lib);
return 0;
}
if (!(segtype = init_segtype_fn(cmd)))
return 0;
segtype->library = lib;
list_add(&cmd->segtypes, &segtype->list);
list_iterate_items(segtype2, &cmd->segtypes) {
if ((segtype == segtype2) ||
strcmp(segtype2->name, segtype->name))
continue;
log_error("Duplicate segment type %s: "
"unloading shared library %s",
segtype->name, cv->v.str);
list_del(&segtype->list);
segtype->ops->destroy(segtype);
dlclose(lib);
if ((init_multiple_segtypes_fn =
dlsym(seglib.lib, "init_multiple_segtypes"))) {
if (dlsym(seglib.lib, "init_segtype"))
log_warn("WARNING: Shared lib %s has "
"conflicting init fns. Using"
" init_multiple_segtypes().",
seglib.libname);
} else
init_multiple_segtypes_fn =
_init_single_segtype;
if (!init_multiple_segtypes_fn(cmd, &seglib)) {
struct dm_list *sgtl, *tmp;
log_error("init_multiple_segtypes() failed: "
"Unloading shared library %s",
seglib.libname);
dm_list_iterate_safe(sgtl, tmp, &cmd->segtypes) {
segtype = dm_list_item(sgtl, struct segment_type);
if (segtype->library == seglib.lib) {
dm_list_del(&segtype->list);
segtype->ops->destroy(segtype);
}
}
dlclose(seglib.lib);
return_0;
}
}
}
@@ -847,10 +1026,10 @@ static int _init_backup(struct cmd_context *cmd)
char default_dir[PATH_MAX];
const char *dir;
if (!cmd->sys_dir) {
if (!cmd->system_dir) {
log_warn("WARNING: Metadata changes will NOT be backed up");
backup_init(cmd, "");
archive_init(cmd, "", 0, 0);
backup_init(cmd, "", 0);
archive_init(cmd, "", 0, 0, 0);
return 1;
}
@@ -866,18 +1045,19 @@ static int _init_backup(struct cmd_context *cmd)
DEFAULT_ARCHIVE_NUMBER);
if (dm_snprintf
(default_dir, sizeof(default_dir), "%s/%s", cmd->sys_dir,
(default_dir, sizeof(default_dir), "%s/%s", cmd->system_dir,
DEFAULT_ARCHIVE_SUBDIR) == -1) {
log_err("Couldn't create default archive path '%s/%s'.",
cmd->sys_dir, DEFAULT_ARCHIVE_SUBDIR);
log_error("Couldn't create default archive path '%s/%s'.",
cmd->system_dir, DEFAULT_ARCHIVE_SUBDIR);
return 0;
}
dir = find_config_tree_str(cmd, "backup/archive_dir",
default_dir);
if (!archive_init(cmd, dir, days, min)) {
log_debug("backup_init failed.");
if (!archive_init(cmd, dir, days, min,
cmd->default_settings.archive)) {
log_debug("archive_init failed.");
return 0;
}
@@ -887,16 +1067,16 @@ static int _init_backup(struct cmd_context *cmd)
DEFAULT_BACKUP_ENABLED);
if (dm_snprintf
(default_dir, sizeof(default_dir), "%s/%s", cmd->sys_dir,
(default_dir, sizeof(default_dir), "%s/%s", cmd->system_dir,
DEFAULT_BACKUP_SUBDIR) == -1) {
log_err("Couldn't create default backup path '%s/%s'.",
cmd->sys_dir, DEFAULT_BACKUP_SUBDIR);
log_error("Couldn't create default backup path '%s/%s'.",
cmd->system_dir, DEFAULT_BACKUP_SUBDIR);
return 0;
}
dir = find_config_tree_str(cmd, "backup/backup_dir", default_dir);
if (!backup_init(cmd, dir)) {
if (!backup_init(cmd, dir, cmd->default_settings.backup)) {
log_debug("backup_init failed.");
return 0;
}
@@ -904,9 +1084,27 @@ static int _init_backup(struct cmd_context *cmd)
return 1;
}
static void _init_rand(struct cmd_context *cmd)
{
if (read_urandom(&cmd->rand_seed, sizeof(cmd->rand_seed))) {
reset_lvm_errno(1);
return;
}
cmd->rand_seed = (unsigned) time(NULL) + (unsigned) getpid();
reset_lvm_errno(1);
}
static void _init_globals(struct cmd_context *cmd)
{
init_full_scan_done(0);
init_mirror_in_sync(0);
}
/* Entry point */
struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static,
unsigned is_long_lived)
struct cmd_context *create_toolcontext(unsigned is_long_lived,
const char *system_dir)
{
struct cmd_context *cmd;
@@ -928,99 +1126,109 @@ struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static,
return NULL;
}
memset(cmd, 0, sizeof(*cmd));
cmd->args = the_args;
cmd->is_static = is_static;
cmd->is_long_lived = is_long_lived;
cmd->handles_missing_pvs = 0;
cmd->handles_unknown_segments = 0;
cmd->hosttags = 0;
list_init(&cmd->formats);
list_init(&cmd->segtypes);
list_init(&cmd->tags);
list_init(&cmd->config_files);
dm_list_init(&cmd->formats);
dm_list_init(&cmd->segtypes);
dm_list_init(&cmd->tags);
dm_list_init(&cmd->config_files);
strcpy(cmd->sys_dir, DEFAULT_SYS_DIR);
/* FIXME Make this configurable? */
reset_lvm_errno(1);
/*
* Environment variable LVM_SYSTEM_DIR overrides this below.
*/
if (system_dir)
strncpy(cmd->system_dir, system_dir, sizeof(cmd->system_dir) - 1);
else
strcpy(cmd->system_dir, DEFAULT_SYS_DIR);
if (!_get_env_vars(cmd))
goto error;
goto_out;
/* Create system directory if it doesn't already exist */
if (*cmd->sys_dir && !dm_create_dir(cmd->sys_dir)) {
if (*cmd->system_dir && !dm_create_dir(cmd->system_dir)) {
log_error("Failed to create LVM2 system dir for metadata backups, config "
"files and internal cache.");
log_error("Set environment variable LVM_SYSTEM_DIR to alternative location "
"or empty string.");
goto error;
goto out;
}
if (!(cmd->libmem = dm_pool_create("library", 4 * 1024))) {
log_error("Library memory pool creation failed");
goto error;
goto out;
}
if (!_init_lvm_conf(cmd))
goto error;
goto_out;
_init_logging(cmd);
if (!_init_hostname(cmd))
goto error;
goto_out;
if (!_init_tags(cmd, cmd->cft))
goto error;
goto_out;
if (!_init_tag_configs(cmd))
goto error;
goto_out;
if (!_merge_config_files(cmd))
goto error;
goto_out;
if (!_process_config(cmd))
goto error;
goto_out;
if (!_init_dev_cache(cmd))
goto error;
goto_out;
if (!_init_filters(cmd, 1))
goto error;
goto_out;
if (!(cmd->mem = dm_pool_create("command", 4 * 1024))) {
log_error("Command memory pool creation failed");
goto error;
goto out;
}
memlock_init(cmd);
if (!_init_formats(cmd))
goto error;
goto_out;
if (!init_lvmcache_orphans(cmd))
goto error;
goto_out;
if (!_init_segtypes(cmd))
goto error;
goto_out;
if (!_init_backup(cmd))
goto error;
goto_out;
_init_rand(cmd);
_init_globals(cmd);
cmd->default_settings.cache_vgmetadata = 1;
cmd->current_settings = cmd->default_settings;
cmd->config_valid = 1;
out:
return cmd;
error:
dm_free(cmd);
return NULL;
}
static void _destroy_formats(struct list *formats)
static void _destroy_formats(struct cmd_context *cmd, struct dm_list *formats)
{
struct list *fmtl, *tmp;
struct dm_list *fmtl, *tmp;
struct format_type *fmt;
void *lib;
list_iterate_safe(fmtl, tmp, formats) {
fmt = list_item(fmtl, struct format_type);
list_del(&fmt->list);
dm_list_iterate_safe(fmtl, tmp, formats) {
fmt = dm_list_item(fmtl, struct format_type);
dm_list_del(&fmt->list);
lib = fmt->library;
fmt->ops->destroy(fmt);
#ifdef HAVE_LIBDL
@@ -1030,24 +1238,53 @@ static void _destroy_formats(struct list *formats)
}
}
static void _destroy_segtypes(struct list *segtypes)
static void _destroy_segtypes(struct dm_list *segtypes)
{
struct list *sgtl, *tmp;
struct dm_list *sgtl, *tmp;
struct segment_type *segtype;
void *lib;
list_iterate_safe(sgtl, tmp, segtypes) {
segtype = list_item(sgtl, struct segment_type);
list_del(&segtype->list);
dm_list_iterate_safe(sgtl, tmp, segtypes) {
segtype = dm_list_item(sgtl, struct segment_type);
dm_list_del(&segtype->list);
lib = segtype->library;
segtype->ops->destroy(segtype);
#ifdef HAVE_LIBDL
if (lib)
/*
* If no segtypes remain from this library, close it.
*/
if (lib) {
struct segment_type *segtype2;
dm_list_iterate_items(segtype2, segtypes)
if (segtype2->library == lib)
goto skip_dlclose;
dlclose(lib);
skip_dlclose:
;
}
#endif
}
}
int refresh_filters(struct cmd_context *cmd)
{
int r, saved_ignore_suspended_devices = ignore_suspended_devices();
if (cmd->filter) {
cmd->filter->destroy(cmd->filter);
cmd->filter = NULL;
}
r = _init_filters(cmd, 0);
/*
* During repair code must not reset suspended flag.
*/
init_ignore_suspended_devices(saved_ignore_suspended_devices);
return r;
}
int refresh_toolcontext(struct cmd_context *cmd)
{
log_verbose("Reloading config files");
@@ -1061,7 +1298,7 @@ int refresh_toolcontext(struct cmd_context *cmd)
lvmcache_destroy(cmd, 0);
label_exit();
_destroy_segtypes(&cmd->segtypes);
_destroy_formats(&cmd->formats);
_destroy_formats(cmd, &cmd->formats);
if (cmd->filter) {
cmd->filter->destroy(cmd->filter);
cmd->filter = NULL;
@@ -1106,38 +1343,38 @@ int refresh_toolcontext(struct cmd_context *cmd)
if (!_init_segtypes(cmd))
return 0;
/*
* If we are a long-lived process, write out the updated persistent
* device cache for the benefit of short-lived processes.
*/
if (cmd->is_long_lived && cmd->dump_filter)
persistent_filter_dump(cmd->filter);
cmd->config_valid = 1;
reset_lvm_errno(1);
return 1;
}
void destroy_toolcontext(struct cmd_context *cmd)
{
if (cmd->dump_filter)
persistent_filter_dump(cmd->filter);
persistent_filter_dump(cmd->filter, 1);
archive_exit(cmd);
backup_exit(cmd);
lvmcache_destroy(cmd, 0);
label_exit();
_destroy_segtypes(&cmd->segtypes);
_destroy_formats(&cmd->formats);
cmd->filter->destroy(cmd->filter);
dm_pool_destroy(cmd->mem);
_destroy_formats(cmd, &cmd->formats);
if (cmd->filter)
cmd->filter->destroy(cmd->filter);
if (cmd->mem)
dm_pool_destroy(cmd->mem);
dev_cache_exit();
_destroy_tags(cmd);
_destroy_tag_configs(cmd);
dm_pool_destroy(cmd->libmem);
if (cmd->libmem)
dm_pool_destroy(cmd->libmem);
dm_free(cmd);
release_log_memory();
activation_exit();
reset_log_duplicated();
fin_log();
fin_syslog();
reset_lvm_errno(0);
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -34,9 +34,11 @@ struct config_info {
int archive; /* should we archive ? */
int backup; /* should we backup ? */
int read_ahead; /* DM_READ_AHEAD_NONE or _AUTO */
int udev_rules;
int udev_sync;
int cache_vgmetadata;
const char *msg_prefix;
struct format_type *fmt;
const char *fmt_name;
uint64_t unit_factor;
int cmd_name; /* Show command name? */
mode_t umask;
@@ -57,22 +59,25 @@ struct cmd_context {
const struct format_type *fmt; /* Current format to use by default */
struct format_type *fmt_backup; /* Format to use for backups */
struct list formats; /* Available formats */
struct list segtypes; /* Available segment types */
struct dm_list formats; /* Available formats */
struct dm_list segtypes; /* Available segment types */
const char *hostname;
const char *kernel_vsn;
char *cmd_line;
unsigned rand_seed;
const char *cmd_line;
struct command *command;
struct arg *args;
char **argv;
unsigned is_static; /* Static binary? */
unsigned is_long_lived; /* Optimises persistent_filter handling */
unsigned is_long_lived:1; /* Optimises persistent_filter handling */
unsigned handles_missing_pvs:1;
unsigned handles_unknown_segments:1;
unsigned partial_activation:1;
unsigned si_unit_consistency:1;
struct dev_filter *filter;
int dump_filter; /* Dump filter when exiting? */
struct list config_files;
struct dm_list config_files;
int config_valid;
struct config_tree *cft;
struct config_tree *cft_override;
@@ -81,20 +86,30 @@ struct cmd_context {
struct archive_params *archive_params;
struct backup_params *backup_params;
const char *stripe_filler;
/* List of defined tags */
struct list tags;
struct dm_list tags;
int hosttags;
char sys_dir[PATH_MAX];
char system_dir[PATH_MAX];
char dev_dir[PATH_MAX];
char proc_dir[PATH_MAX];
char sysfs_dir[PATH_MAX]; /* FIXME Use global value instead. */
};
struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static, unsigned is_long_lived);
/*
* system_dir may be NULL to use the default value.
* The environment variable LVM_SYSTEM_DIR always takes precedence.
*/
struct cmd_context *create_toolcontext(unsigned is_long_lived,
const char *system_dir);
void destroy_toolcontext(struct cmd_context *cmd);
int refresh_toolcontext(struct cmd_context *cmd);
int refresh_filters(struct cmd_context *cmd);
int config_files_changed(struct cmd_context *cmd);
int init_lvmcache_orphans(struct cmd_context *cmd);
struct format_type *get_format_by_name(struct cmd_context *cmd, const char *format);
#endif

View File

@@ -71,6 +71,8 @@ struct cs {
struct output_line {
FILE *fp;
struct dm_pool *mem;
putline_fn putline;
void *putline_baton;
};
static void _get_token(struct parser *p, int tok_prev);
@@ -80,8 +82,8 @@ static struct config_node *_section(struct parser *p);
static struct config_value *_value(struct parser *p);
static struct config_value *_type(struct parser *p);
static int _match_aux(struct parser *p, int t);
static struct config_value *_create_value(struct parser *p);
static struct config_node *_create_node(struct parser *p);
static struct config_value *_create_value(struct dm_pool *mem);
static struct config_node *_create_node(struct dm_pool *mem);
static char *_dup_tok(struct parser *p);
static const int sep = '/';
@@ -157,7 +159,7 @@ static int _parse_config_file(struct parser *p, struct config_tree *cft)
return 1;
}
struct config_tree *create_config_tree_from_string(struct cmd_context *cmd __attribute((unused)),
struct config_tree *create_config_tree_from_string(struct cmd_context *cmd __attribute__((unused)),
const char *config_settings)
{
struct cs *c;
@@ -186,6 +188,17 @@ struct config_tree *create_config_tree_from_string(struct cmd_context *cmd __att
return cft;
}
int override_config_tree_from_string(struct cmd_context *cmd,
const char *config_settings)
{
if (!(cmd->cft_override = create_config_tree_from_string(cmd,config_settings))) {
log_error("Failed to set overridden configuration entries.");
return 1;
}
return 0;
}
int read_config_fd(struct config_tree *cft, struct device *dev,
off_t offset, size_t size, off_t offset2, size_t size2,
checksum_fn_t checksum_fn, uint32_t checksum)
@@ -282,8 +295,10 @@ int read_config_file(struct config_tree *cft)
if (!(c->dev = dev_create_file(c->filename, NULL, NULL, 1)))
return_0;
if (!dev_open_flags(c->dev, O_RDONLY, 0, 0))
if (!dev_open_flags(c->dev, O_RDONLY, 0, 0)) {
c->dev = 0;
return_0;
}
}
r = read_config_fd(cft, c->dev, 0, (size_t) info.st_size, 0, 0,
@@ -392,10 +407,14 @@ static int _line_end(struct output_line *outline)
}
line = dm_pool_end_object(outline->mem);
if (!outline->fp)
log_print("%s", line);
else
fprintf(outline->fp, "%s\n", line);
if (outline->putline)
outline->putline(line, outline->putline_baton);
else {
if (!outline->fp)
log_print("%s", line);
else
fprintf(outline->fp, "%s\n", line);
}
return 1;
}
@@ -434,7 +453,7 @@ static int _write_value(struct output_line *outline, struct config_value *v)
return 1;
}
static int _write_config(struct config_node *n, int only_one,
static int _write_config(const struct config_node *n, int only_one,
struct output_line *outline, int level)
{
char space[MAX_INDENT + 1];
@@ -457,9 +476,9 @@ static int _write_config(struct config_node *n, int only_one,
line_append(" {");
if (!_line_end(outline))
return_0;
_write_config(n->child, 0, outline, level + 1);
if (!_line_start(outline))
return_0;
_write_config(n->child, 0, outline, level + 1);
line_append("%s}", space);
} else {
/* it's a value */
@@ -487,6 +506,21 @@ static int _write_config(struct config_node *n, int only_one,
return 1;
}
int write_config_node(const struct config_node *cn, putline_fn putline, void *baton)
{
struct output_line outline;
outline.fp = NULL;
outline.mem = dm_pool_create("config_line", 1024);
outline.putline = putline;
outline.putline_baton = baton;
if (!_write_config(cn, 0, &outline, 0)) {
dm_pool_destroy(outline.mem);
return_0;
}
dm_pool_destroy(outline.mem);
return 1;
}
int write_config_file(struct config_tree *cft, const char *file,
int argc, char **argv)
{
@@ -494,6 +528,7 @@ int write_config_file(struct config_tree *cft, const char *file,
int r = 1;
struct output_line outline;
outline.fp = NULL;
outline.putline = NULL;
if (!file)
file = "stdout";
@@ -546,6 +581,7 @@ static struct config_node *_file(struct parser *p)
root = n;
else
l->sib = n;
n->parent = root;
l = n;
}
return root;
@@ -555,7 +591,7 @@ static struct config_node *_section(struct parser *p)
{
/* IDENTIFIER SECTION_B_CHAR VALUE* SECTION_E_CHAR */
struct config_node *root, *n, *l = NULL;
if (!(root = _create_node(p)))
if (!(root = _create_node(p->mem)))
return_0;
if (!(root->key = _dup_tok(p)))
@@ -573,6 +609,7 @@ static struct config_node *_section(struct parser *p)
root->child = n;
else
l->sib = n;
n->parent = root;
l = n;
}
match(TOK_SECTION_E);
@@ -609,7 +646,7 @@ static struct config_value *_value(struct parser *p)
* Special case for an empty array.
*/
if (!h) {
if (!(h = _create_value(p)))
if (!(h = _create_value(p->mem)))
return NULL;
h->type = CFG_EMPTY_ARRAY;
@@ -624,7 +661,7 @@ static struct config_value *_value(struct parser *p)
static struct config_value *_type(struct parser *p)
{
/* [+-]{0,1}[0-9]+ | [0-9]*\.[0-9]* | ".*" */
struct config_value *v = _create_value(p);
struct config_value *v = _create_value(p->mem);
if (!v)
return NULL;
@@ -820,9 +857,9 @@ static void _eat_space(struct parser *p)
/*
* memory management
*/
static struct config_value *_create_value(struct parser *p)
static struct config_value *_create_value(struct dm_pool *mem)
{
struct config_value *v = dm_pool_alloc(p->mem, sizeof(*v));
struct config_value *v = dm_pool_alloc(mem, sizeof(*v));
if (v)
memset(v, 0, sizeof(*v));
@@ -830,9 +867,9 @@ static struct config_value *_create_value(struct parser *p)
return v;
}
static struct config_node *_create_node(struct parser *p)
static struct config_node *_create_node(struct dm_pool *mem)
{
struct config_node *n = dm_pool_alloc(p->mem, sizeof(*n));
struct config_node *n = dm_pool_alloc(mem, sizeof(*n));
if (n)
memset(n, 0, sizeof(*n));
@@ -876,9 +913,9 @@ static struct config_node *_find_config_node(const struct config_node *cn,
if (!cn_found)
cn_found = cn;
else
log_error("WARNING: Ignoring duplicate"
" config node: %s ("
"seeking %s)", cn->key, path);
log_warn("WARNING: Ignoring duplicate"
" config node: %s ("
"seeking %s)", cn->key, path);
}
cn = cn->sib;
@@ -1011,7 +1048,7 @@ float find_config_tree_float(struct cmd_context *cmd, const char *path,
return _find_config_float(cmd->cft_override ? cmd->cft_override->root : NULL, cmd->cft->root, path, fail);
}
static int _str_in_array(const char *str, const char *values[])
static int _str_in_array(const char *str, const char * const values[])
{
int i;
@@ -1024,9 +1061,8 @@ static int _str_in_array(const char *str, const char *values[])
static int _str_to_bool(const char *str, int fail)
{
static const char *_true_values[] = { "y", "yes", "on", "true", NULL };
static const char *_false_values[] =
{ "n", "no", "off", "false", NULL };
const char * const _true_values[] = { "y", "yes", "on", "true", NULL };
const char * const _false_values[] = { "n", "no", "off", "false", NULL };
if (_str_in_array(str, _true_values))
return 1;
@@ -1166,7 +1202,7 @@ static void _merge_section(struct config_node *cn1, struct config_node *cn2)
}
}
static int _match_host_tags(struct list *tags, struct config_node *tn)
static int _match_host_tags(struct dm_list *tags, struct config_node *tn)
{
struct config_value *tv;
const char *str;
@@ -1252,6 +1288,10 @@ static unsigned _count_tokens(const char *str, unsigned len, int type)
return count_chars(str, len, c);
}
const char *config_parent_name(const struct config_node *n)
{
return (n->parent ? n->parent->key : "(root)");
}
/*
* Heuristic function to make a quick guess as to whether a text
* region probably contains a valid config "section". (Useful for
@@ -1276,8 +1316,38 @@ unsigned maybe_config_section(const char *str, unsigned len)
begin_count = _count_tokens(str, len, TOK_SECTION_B);
end_count = _count_tokens(str, len, TOK_SECTION_E);
if (begin_count && end_count && (begin_count - end_count == 0))
if (begin_count && end_count && (begin_count == end_count))
return 1;
else
return 0;
}
static struct config_value *_clone_config_value(struct dm_pool *mem, const struct config_value *v)
{
if (!v)
return NULL;
struct config_value *new = _create_value(mem);
new->type = v->type;
if (v->type == CFG_STRING)
new->v.str = dm_pool_strdup(mem, v->v.str);
else
new->v = v->v;
new->next = _clone_config_value(mem, v->next);
return new;
}
struct config_node *clone_config_node(struct dm_pool *mem, const struct config_node *cn,
int siblings)
{
if (!cn)
return NULL;
struct config_node *new = _create_node(mem);
new->key = dm_pool_strdup(mem, cn->key);
new->child = clone_config_node(mem, cn->child, 1);
new->v = _clone_config_value(mem, cn->v);
if (siblings)
new->sib = clone_config_node(mem, cn->sib, siblings);
else
new->sib = NULL;
return new;
}

View File

@@ -40,7 +40,7 @@ struct config_value {
struct config_node {
char *key;
struct config_node *sib, *child;
struct config_node *parent, *sib, *child;
struct config_value *v;
};
@@ -49,13 +49,15 @@ struct config_tree {
};
struct config_tree_list {
struct list list;
struct dm_list list;
struct config_tree *cft;
};
struct config_tree *create_config_tree(const char *filename, int keep_open);
struct config_tree *create_config_tree_from_string(struct cmd_context *cmd,
const char *config_settings);
int override_config_tree_from_string(struct cmd_context *cmd,
const char *config_settings);
void destroy_config_tree(struct config_tree *cft);
typedef uint32_t (*checksum_fn_t) (uint32_t initial, const void *buf, uint32_t size);
@@ -67,6 +69,10 @@ int read_config_fd(struct config_tree *cft, struct device *dev,
int read_config_file(struct config_tree *cft);
int write_config_file(struct config_tree *cft, const char *file,
int argc, char **argv);
typedef int (*putline_fn)(const char *line, void *baton);
int write_config_node(const struct config_node *cn, putline_fn putline, void *baton);
time_t config_file_timestamp(struct config_tree *cft);
int config_file_changed(struct config_tree *cft);
int merge_config_tree(struct cmd_context *cmd, struct config_tree *cft,
@@ -110,4 +116,8 @@ int get_config_str(const struct config_node *cn, const char *path,
unsigned maybe_config_section(const char *str, unsigned len);
const char *config_parent_name(const struct config_node *n);
struct config_node *clone_config_node(struct dm_pool *mem, const struct config_node *cn,
int siblings);
#endif

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -16,34 +16,41 @@
#ifndef _LVM_DEFAULTS_H
#define _LVM_DEFAULTS_H
#define DEFAULT_PE_ALIGN 2048
#define DEFAULT_ARCHIVE_ENABLED 1
#define DEFAULT_BACKUP_ENABLED 1
#define DEFAULT_ARCHIVE_SUBDIR "archive"
#define DEFAULT_BACKUP_SUBDIR "backup"
#define DEFAULT_CACHE_SUBDIR "cache"
#define DEFAULT_CACHE_FILE_PREFIX ""
#define DEFAULT_ARCHIVE_DAYS 30
#define DEFAULT_ARCHIVE_NUMBER 10
#define DEFAULT_SYS_DIR "/etc/lvm"
#define DEFAULT_DEV_DIR "/dev"
#define DEFAULT_PROC_DIR "/proc"
#define DEFAULT_SYSFS_SCAN 1
#define DEFAULT_MD_COMPONENT_DETECTION 1
#define DEFAULT_MD_CHUNK_ALIGNMENT 1
#define DEFAULT_IGNORE_SUSPENDED_DEVICES 1
#define DEFAULT_REQUIRE_RESTOREFILE_WITH_UUID 1
#define DEFAULT_DATA_ALIGNMENT_OFFSET_DETECTION 1
#define DEFAULT_DATA_ALIGNMENT_DETECTION 1
#define DEFAULT_LOCK_DIR "/var/lock/lvm"
#define DEFAULT_LOCKING_LIB "liblvm2clusterlock.so"
#define DEFAULT_FALLBACK_TO_LOCAL_LOCKING 1
#define DEFAULT_FALLBACK_TO_CLUSTERED_LOCKING 1
#define DEFAULT_WAIT_FOR_LOCKS 1
#define DEFAULT_PRIORITISE_WRITE_LOCKS 1
#define DEFAULT_USE_MLOCKALL 0
#define DEFAULT_MIRRORLOG "disk"
#define DEFAULT_MIRROR_LOG_FAULT_POLICY "allocate"
#define DEFAULT_MIRROR_DEV_FAULT_POLICY "remove"
#define DEFAULT_MIRROR_IMAGE_FAULT_POLICY "remove"
#define DEFAULT_MIRROR_MAX_IMAGES 8 /* limited by kernel DM_KCOPYD_MAX_REGIONS */
#define DEFAULT_DMEVENTD_MIRROR_LIB "libdevmapper-event-lvm2mirror.so"
#define DEFAULT_DMEVENTD_SNAPSHOT_LIB "libdevmapper-event-lvm2snapshot.so"
#define DEFAULT_DMEVENTD_MONITOR 1
#define DEFAULT_BACKGROUND_POLLING 1
#define DEFAULT_UMASK 0077
@@ -53,18 +60,23 @@
# define DEFAULT_FALLBACK_TO_LVM1 0
#endif
#ifdef LVM1_SUPPORT
# define DEFAULT_FORMAT "lvm1"
#else
# define DEFAULT_FORMAT "lvm2"
#endif
#define DEFAULT_FORMAT "lvm2"
#define DEFAULT_STRIPESIZE 64 /* KB */
#define DEFAULT_PVMETADATAIGNORE 0
#define DEFAULT_PVMETADATAIGNORE_STR "n"
#define DEFAULT_PVMETADATASIZE 255
#define DEFAULT_PVMETADATACOPIES 1
#define DEFAULT_VGMETADATACOPIES 0
#define DEFAULT_LABELSECTOR UINT64_C(1)
#define DEFAULT_READ_AHEAD "auto"
#define DEFAULT_UDEV_RULES 1
#define DEFAULT_UDEV_SYNC 0
#define DEFAULT_EXTENT_SIZE 4096 /* In KB */
#define DEFAULT_MAX_PV 0
#define DEFAULT_MAX_LV 0
#define DEFAULT_ALLOC_POLICY ALLOC_NORMAL
#define DEFAULT_CLUSTERED 0
#define DEFAULT_MSG_PREFIX " "
#define DEFAULT_CMD_NAME 0
@@ -78,10 +90,15 @@
#define DEFAULT_VERBOSE 0
#define DEFAULT_LOGLEVEL 0
#define DEFAULT_INDENT 1
#define DEFAULT_ABORT_ON_INTERNAL_ERRORS 0
#define DEFAULT_UNITS "h"
#define DEFAULT_SUFFIX 1
#define DEFAULT_HOSTTAGS 0
#ifndef DEFAULT_SI_UNIT_CONSISTENCY
# define DEFAULT_SI_UNIT_CONSISTENCY 1
#endif
#ifdef DEVMAPPER_SUPPORT
# define DEFAULT_ACTIVATION 1
# define DEFAULT_RESERVED_MEMORY 8192
@@ -91,7 +108,7 @@
# define DEFAULT_ACTIVATION 0
#endif
#define DEFAULT_STRIPE_FILLER "/dev/ioerror"
#define DEFAULT_STRIPE_FILLER "error"
#define DEFAULT_MIRROR_REGION_SIZE 512 /* KB */
#define DEFAULT_INTERVAL 15
@@ -125,4 +142,7 @@
#define DEFAULT_SEGS_SORT "vg_name,lv_name,seg_start"
#define DEFAULT_PVSEGS_SORT "pv_name,pvseg_start"
#define DEFAULT_MIRROR_DEVICE_FAULT_POLICY "remove"
#define DEFAULT_MIRROR_LOG_FAULT_POLICY "allocate"
#endif /* _LVM_DEFAULTS_H */

View File

@@ -1,145 +0,0 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
/*
* Initialise a list before use.
* The list head's next and previous pointers point back to itself.
*/
void list_init(struct list *head)
{
head->n = head->p = head;
}
/*
* Insert an element before 'head'.
* If 'head' is the list head, this adds an element to the end of the list.
*/
void list_add(struct list *head, struct list *elem)
{
assert(head->n);
elem->n = head;
elem->p = head->p;
head->p->n = elem;
head->p = elem;
}
/*
* Insert an element after 'head'.
* If 'head' is the list head, this adds an element to the front of the list.
*/
void list_add_h(struct list *head, struct list *elem)
{
assert(head->n);
elem->n = head->n;
elem->p = head;
head->n->p = elem;
head->n = elem;
}
/*
* Delete an element from its list.
* Note that this doesn't change the element itself - it may still be safe
* to follow its pointers.
*/
void list_del(struct list *elem)
{
elem->n->p = elem->p;
elem->p->n = elem->n;
}
/*
* Remove an element from existing list and insert before 'head'.
*/
void list_move(struct list *head, struct list *elem)
{
list_del(elem);
list_add(head, elem);
}
/*
* Is the list empty?
*/
int list_empty(const struct list *head)
{
return head->n == head;
}
/*
* Is this the first element of the list?
*/
int list_start(const struct list *head, const struct list *elem)
{
return elem->p == head;
}
/*
* Is this the last element of the list?
*/
int list_end(const struct list *head, const struct list *elem)
{
return elem->n == head;
}
/*
* Return first element of the list or NULL if empty
*/
struct list *list_first(const struct list *head)
{
return (list_empty(head) ? NULL : head->n);
}
/*
* Return last element of the list or NULL if empty
*/
struct list *list_last(const struct list *head)
{
return (list_empty(head) ? NULL : head->p);
}
/*
* Return the previous element of the list, or NULL if we've reached the start.
*/
struct list *list_prev(const struct list *head, const struct list *elem)
{
return (list_start(head, elem) ? NULL : elem->p);
}
/*
* Return the next element of the list, or NULL if we've reached the end.
*/
struct list *list_next(const struct list *head, const struct list *elem)
{
return (list_end(head, elem) ? NULL : elem->n);
}
/*
* Return the number of elements in a list by walking it.
*/
unsigned int list_size(const struct list *head)
{
unsigned int s = 0;
const struct list *v;
list_iterate(v, head)
s++;
return s;
}

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