1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-12-29 06:57:46 +03:00

Compare commits

..

16 Commits

Author SHA1 Message Date
Alasdair Kergon
897fc59f72 pre-release 2007-12-20 15:12:57 +00:00
Alasdair Kergon
947e44ae67 tweak usage text 2007-12-17 14:47:22 +00:00
Alasdair Kergon
e44843beba replace fsadm.c with fsadm.sh 2007-12-17 12:31:50 +00:00
Alasdair Kergon
147482ea69 Build changes to replace fsadm C program with shell script. 2007-12-17 12:23:24 +00:00
Alasdair Kergon
09091c5cf8 Append fields to report/pvsegs_cols_verbose.
Permit LV segment fields with PV segment reports.
  Add seg_start_pe and seg_pe_ranges to reports.
2007-12-14 21:53:02 +00:00
Alasdair Kergon
50827a5f69 more readahead node fixes/debug messages 2007-12-14 19:49:27 +00:00
Alasdair Kergon
2d6444c924 Fix deptree to pass new name to _resume_node after a rename. 2007-12-14 17:57:04 +00:00
Alasdair Kergon
1d2675d9aa Add node operation stack debug messages. 2007-12-14 17:26:09 +00:00
Alasdair Kergon
ad98990a8e Report error when empty device name passed to readahead functions. 2007-12-13 02:25:45 +00:00
Alasdair Kergon
8e58c143f2 post-release 2007-12-05 22:48:06 +00:00
Alasdair Kergon
556a4a2395 clarify 2007-12-05 22:45:56 +00:00
Alasdair Kergon
5be987b40f pre-release
N.B. This is a big release and some regressions are inevitable.
2007-12-05 22:19:24 +00:00
Alasdair Kergon
066bc35e69 export can_split parameter until rest of pvmove allocation restructuring gets done 2007-12-05 22:11:20 +00:00
Alasdair Kergon
403779437c round readahead to multiple of page size in tools 2007-12-05 19:24:32 +00:00
Alasdair Kergon
fb806f61d4 Fix minimum readahead debug message. 2007-12-05 18:57:34 +00:00
Alasdair Kergon
6ce306661c post-release 2007-12-05 17:14:30 +00:00
26 changed files with 2474 additions and 2814 deletions

View File

@@ -1 +1 @@
2.02.29-cvs (2007-08-24)
2.02.30-cvs (2007-12-05)

View File

@@ -1,5 +1,12 @@
Version 2.02.29 -
==================================
Version 2.02.30 -
===================================
Replace tools/fsadm with scripts/fsadm.sh.
Append fields to report/pvsegs_cols_verbose.
Permit LV segment fields with PV segment reports.
Add seg_start_pe and seg_pe_ranges to reports.
Version 2.02.29 - 5th December 2007
===================================
Make clvmd backup vg metadata on remote nodes.
Refactor pvmove allocation code.
Decode cluster locking state in log message.
@@ -36,14 +43,16 @@ Version 2.02.29 -
Add const attributes to pv accessor functions.
Refactor vg_add_snapshot() and lv_create_empty().
Handle new sysfs subsystem/block/devices directory structure.
Tests are run with LVM_SYSTEM_DIR pointing to private root and /dev dirs.
Run test with LVM_SYSTEM_DIR pointing to private root and /dev dirs.
Fix a bug in lvm_dump.sh checks for lvm/dmsetup binaries.
Fix underquotations in lvm_dump.sh.
Refactor lvcreate stripe and mirror parameter validation.
All tools: print --help output to stdout, not stderr.
After a diagnostic, suggest --help, rather than printing all --help output.
Print --help output to stdout, not stderr.
After a cmdline processing error, don't print help text but suggest --help.
Add %PVS extents option to lvresize, lvextend, and lvcreate.
Add 'make check' to run tests in new subdirectory 'test'.
Moved the obsolete test subdirectory to old-tests.
Cope with relative paths in configure --with-dmdir.
Remove no-longer-correct restrictions on PV arg count with stripes/mirrors.
Fix strdup memory leak in str_list_dup().
Link with -lpthread when static SELinux libraries require that.

View File

@@ -1,10 +1,18 @@
Version 1.02.24 - 20th December 2007
====================================
Fix deptree to pass new name to _resume_node after a rename.
Suppress other node operations if node is deleted.
Add node operation stack debug messages.
Report error when empty device name passed to readahead functions.
Fix minimum readahead debug message.
Version 1.02.23 - 5th December 2007
===================================
Update dm-ioctl.h after removal of compat code.
Add readahead support to libdevmapper and dmsetup.
Fix double free in a libdevmapper-event error path.
Fix configure --with-dmeventd-path substitution.
Allow a DM_DEV_DIR environment variable to override /dev.
Allow a DM_DEV_DIR environment variable to override /dev in dmsetup.
Create a libdevmapper.so.$LIB_VERSION symlink within the build tree.
Avoid static link failure with some SELinux libraries that require libpthread.
Remove obsolete dmfs code from tree and update INSTALL.

4329
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
##
## Copyright (C) 2000-2004 Sistina Software, Inc. All rights reserved.
## Copyright (C) 2004, 2007 Red Hat, Inc. All rights reserved.
## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
##
## This file is part of LVM2.
##
@@ -363,7 +363,7 @@ AC_MSG_RESULT($CMDLIB)
################################################################################
dnl -- Enable fsadm
AC_MSG_CHECKING(whether to build fsadm)
AC_MSG_CHECKING(whether to install fsadm)
AC_ARG_ENABLE(fsadm, [ --enable-fsadm Enable fsadm],
FSADM=$enableval)
AC_MSG_RESULT($FSADM)
@@ -558,11 +558,6 @@ if test x$CLVMD != xnone; then
AC_FUNC_SELECT_ARGTYPES
fi
if test x$FSADM = xyes; then
AC_CHECK_HEADERS(fstab.h sys/mount.h sys/vfs.h,,AC_MSG_ERROR(bailing out))
AC_CHECK_FUNCS(memmove,,AC_MSG_ERROR(bailing out))
fi
if test x$CLUSTER != xnone; then
AC_CHECK_HEADERS(sys/socket.h sys/un.h,,AC_MSG_ERROR(bailing out))
AC_CHECK_FUNCS(socket,,AC_MSG_ERROR(bailing out))
@@ -661,7 +656,6 @@ po/Makefile
scripts/Makefile
tools/Makefile
tools/version.h
tools/fsadm/Makefile
])
AC_OUTPUT

View File

@@ -952,10 +952,10 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
max_stripe_size = seg->stripe_size;
}
if (read_ahead == DM_READ_AHEAD_AUTO)
if (read_ahead == DM_READ_AHEAD_AUTO) {
read_ahead = max_stripe_size;
else
read_ahead_flags = DM_READ_AHEAD_MINIMUM_FLAG;
}
dm_tree_node_set_read_ahead(dnode, read_ahead, read_ahead_flags);

View File

@@ -113,7 +113,7 @@
#define DEFAULT_VGS_COLS_VERB "vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid"
#define DEFAULT_PVS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,dev_size,pv_uuid"
#define DEFAULT_SEGS_COLS_VERB "lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize"
#define DEFAULT_PVSEGS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"
#define DEFAULT_PVSEGS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size,lv_name,seg_start_pe,segtype,seg_pe_ranges"
#define DEFAULT_LVS_SORT "vg_name,lv_name"
#define DEFAULT_VGS_SORT "vg_name"

View File

@@ -50,6 +50,7 @@ struct alloc_handle *allocate_extents(struct volume_group *vg,
uint32_t extents,
struct list *allocatable_pvs,
alloc_policy_t alloc,
unsigned can_split,
struct list *parallel_areas);
int lv_add_segment(struct alloc_handle *ah,

View File

@@ -1055,13 +1055,13 @@ static int _allocate(struct alloc_handle *ah,
struct volume_group *vg,
struct logical_volume *lv,
uint32_t new_extents,
unsigned can_split,
struct list *allocatable_pvs)
{
struct pv_area **areas;
uint32_t allocated = lv ? lv->le_count : 0;
uint32_t old_allocated;
struct lv_segment *prev_lvseg = NULL;
unsigned can_split = 1; /* Are we allowed more than one segment? */
int r = 0;
struct list *pvms;
uint32_t areas_size;
@@ -1180,6 +1180,7 @@ struct alloc_handle *allocate_extents(struct volume_group *vg,
uint32_t extents,
struct list *allocatable_pvs,
alloc_policy_t alloc,
unsigned can_split,
struct list *parallel_areas)
{
struct alloc_handle *ah;
@@ -1208,7 +1209,7 @@ struct alloc_handle *allocate_extents(struct volume_group *vg,
if (!segtype_is_virtual(segtype) &&
!_allocate(ah, vg, lv, (lv ? lv->le_count : 0) + extents,
allocatable_pvs)) {
can_split, allocatable_pvs)) {
stack;
alloc_destroy(ah);
return NULL;
@@ -1403,16 +1404,18 @@ int lv_extend(struct logical_volume *lv,
uint32_t m;
struct alloc_handle *ah;
struct lv_segment *seg;
unsigned can_split = 1;
if (segtype_is_virtual(segtype))
return lv_add_virtual_segment(lv, status, extents, segtype);
/* FIXME Temporary restriction during code reorganisation */
if (mirrored_pv)
alloc = ALLOC_CONTIGUOUS;
can_split = 0;
if (!(ah = allocate_extents(lv->vg, lv, segtype, stripes, mirrors, 0,
extents, allocatable_pvs, alloc, NULL)))
extents, allocatable_pvs, alloc, can_split,
NULL)))
return_0;
if (mirrors < 2) {

View File

@@ -55,9 +55,6 @@
/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
/* Define to 1 if you have the <fstab.h> header file. */
#undef HAVE_FSTAB_H
/* Define to 1 if you have the `gethostname' function. */
#undef HAVE_GETHOSTNAME
@@ -291,9 +288,6 @@
/* Define to 1 if you have the <sys/utsname.h> header file. */
#undef HAVE_SYS_UTSNAME_H
/* Define to 1 if you have the <sys/vfs.h> header file. */
#undef HAVE_SYS_VFS_H
/* Define to 1 if you have the <sys/wait.h> header file. */
#undef HAVE_SYS_WAIT_H

View File

@@ -81,8 +81,10 @@ FIELD(SEGS, seg, NUM, "Region", region_size, 6, size32, "region_size", "For mirr
FIELD(SEGS, seg, NUM, "Chunk", list, 5, chunksize, "chunksize", "For snapshots, the unit of data used when tracking changes.")
FIELD(SEGS, seg, NUM, "Chunk", list, 5, chunksize, "chunk_size", "For snapshots, the unit of data used when tracking changes.")
FIELD(SEGS, seg, NUM, "Start", list, 5, segstart, "seg_start", "Offset within the LV to the start of the segment in current units.")
FIELD(SEGS, seg, NUM, "Start", list, 5, segstartpe, "seg_start_pe", "Offset within the LV to the start of the segment in physical extents.")
FIELD(SEGS, seg, NUM, "SSize", list, 5, segsize, "seg_size", "Size of segment in current units.")
FIELD(SEGS, seg, STR, "Seg Tags", tags, 8, tags, "seg_tags", "Tags, if any.")
FIELD(SEGS, seg, STR, "PE Ranges", list, 9, peranges, "seg_pe_ranges", "Ranges of Physical Extents of underlying devices in command line format.")
FIELD(SEGS, seg, STR, "Devices", list, 5, devices, "devices", "Underlying devices used with starting extent numbers.")
FIELD(PVSEGS, pvseg, NUM, "Start", pe, 5, uint32, "pvseg_start", "Physical Extent number of start of segment.")

View File

@@ -80,9 +80,8 @@ static int _dev_name_disp(struct dm_report *rh, struct dm_pool *mem __attribute(
return dm_report_field_string(rh, field, &name);
}
static int _devices_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private __attribute((unused)))
static int _format_pvsegs(struct dm_pool *mem, struct dm_report_field *field,
const void *data, int range_format)
{
const struct lv_segment *seg = (const struct lv_segment *) data;
unsigned int s;
@@ -115,19 +114,32 @@ static int _devices_disp(struct dm_report *rh __attribute((unused)), struct dm_p
return 0;
}
if (dm_snprintf(extent_str, sizeof(extent_str), "(%" PRIu32
")", extent) < 0) {
if (dm_snprintf(extent_str, sizeof(extent_str),
"%s%" PRIu32 "%s",
range_format ? ":" : "(", extent,
range_format ? "-" : ")") < 0) {
log_error("Extent number dm_snprintf failed");
return 0;
}
if (!dm_pool_grow_object(mem, extent_str, strlen(extent_str))) {
log_error("dm_pool_grow_object failed");
return 0;
}
if (range_format) {
if (dm_snprintf(extent_str, sizeof(extent_str),
"%" PRIu32, extent + seg->area_len - 1) < 0) {
log_error("Extent number dm_snprintf failed");
return 0;
}
if (!dm_pool_grow_object(mem, extent_str, strlen(extent_str))) {
log_error("dm_pool_grow_object failed");
return 0;
}
}
if ((s != seg->area_count - 1) &&
!dm_pool_grow_object(mem, ",", 1)) {
!dm_pool_grow_object(mem, range_format ? " " : ",", 1)) {
log_error("dm_pool_grow_object failed");
return 0;
}
@@ -143,6 +155,20 @@ static int _devices_disp(struct dm_report *rh __attribute((unused)), struct dm_p
return 1;
}
static int _devices_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private __attribute((unused)))
{
return _format_pvsegs(mem, field, data, 0);
}
static int _peranges_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private __attribute((unused)))
{
return _format_pvsegs(mem, field, data, 1);
}
static int _tags_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private __attribute((unused)))
@@ -613,6 +639,15 @@ static int _segstart_disp(struct dm_report *rh, struct dm_pool *mem,
return _size64_disp(rh, mem, field, &start, private);
}
static int _segstartpe_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
const struct lv_segment *seg = (const struct lv_segment *) data;
return dm_report_field_uint32(rh, field, &seg->le);
}
static int _segsize_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)

View File

@@ -300,6 +300,8 @@ static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor,
return 0;
}
log_debug("Created %s", path);
#ifdef HAVE_SELINUX
if (!dm_set_selinux_context(path, S_IFBLK))
return 0;
@@ -341,6 +343,8 @@ static int _rename_dev_node(const char *old_name, const char *new_name)
return 0;
}
log_debug("Renamed %s to %s", oldpath, newpath);
return 1;
}
@@ -359,6 +363,8 @@ static int _rm_dev_node(const char *dev_name)
return 0;
}
log_debug("Removed %s", path);
return 1;
}
@@ -382,6 +388,11 @@ int get_dev_node_read_ahead(const char *dev_name, uint32_t *read_ahead)
int fd;
long read_ahead_long;
if (!*dev_name) {
log_error("Empty device name passed to BLKRAGET");
return 0;
}
if ((fd = _open_dev_node(dev_name)) < 0)
return_0;
@@ -406,6 +417,11 @@ static int _set_read_ahead(const char *dev_name, uint32_t read_ahead)
int fd;
long read_ahead_long = (long) read_ahead;
if (!*dev_name) {
log_error("Empty device name passed to BLKRAGET");
return 0;
}
if ((fd = _open_dev_node(dev_name)) < 0)
return_0;
@@ -438,8 +454,8 @@ static int _set_dev_node_read_ahead(const char *dev_name, uint32_t read_ahead,
return_0;
if (current_read_ahead > read_ahead) {
log_debug("%s: read ahead %" PRIu32
" below minimum of %" PRIu32,
log_debug("%s: retaining kernel read ahead of %" PRIu32
" (requested %" PRIu32 ")",
dev_name, current_read_ahead, read_ahead);
return 1;
}
@@ -521,9 +537,23 @@ static int _stack_node_op(node_op_t type, const char *dev_name, uint32_t major,
uint32_t read_ahead_flags)
{
struct node_op_parms *nop;
struct list *noph, *nopht;
size_t len = strlen(dev_name) + strlen(old_name) + 2;
char *pos;
/*
* Ignore any outstanding operations on the node if deleting it
*/
if (type == NODE_DEL) {
list_iterate_safe(noph, nopht, &_node_ops) {
nop = list_item(noph, struct node_op_parms);
if (!strcmp(dev_name, nop->dev_name)) {
list_del(&nop->list);
dm_free(nop);
}
}
}
if (!(nop = dm_malloc(sizeof(*nop) + len))) {
log_error("Insufficient memory to stack mknod operation");
return 0;
@@ -565,18 +595,25 @@ static void _pop_node_ops(void)
int add_dev_node(const char *dev_name, uint32_t major, uint32_t minor,
uid_t uid, gid_t gid, mode_t mode)
{
log_debug("%s: Stacking NODE_ADD (%" PRIu32 ",%" PRIu32 ") %u:%u 0%o",
dev_name, major, minor, uid, gid, mode);
return _stack_node_op(NODE_ADD, dev_name, major, minor, uid, gid, mode,
"", 0, 0);
}
int rename_dev_node(const char *old_name, const char *new_name)
{
log_debug("%s: Stacking NODE_RENAME to %s", old_name, new_name);
return _stack_node_op(NODE_RENAME, new_name, 0, 0, 0, 0, 0, old_name,
0, 0);
}
int rm_dev_node(const char *dev_name)
{
log_debug("%s: Stacking NODE_DEL (replaces other stacked ops)", dev_name);
return _stack_node_op(NODE_DEL, dev_name, 0, 0, 0, 0, 0, "", 0, 0);
}
@@ -586,6 +623,9 @@ int set_dev_node_read_ahead(const char *dev_name, uint32_t read_ahead,
if (read_ahead == DM_READ_AHEAD_AUTO)
return 1;
log_debug("%s: Stacking NODE_READ_AHEAD %" PRIu32 " (flags=%" PRIu32
")", dev_name, read_ahead, read_ahead_flags);
return _stack_node_op(NODE_READ_AHEAD, dev_name, 0, 0, 0, 0, 0, "",
read_ahead, read_ahead_flags);
}

View File

@@ -1160,11 +1160,11 @@ int dm_tree_activate_children(struct dm_tree_node *dnode,
if (!child->info.inactive_table && !child->info.suspended)
continue;
if (!_resume_node(name, child->info.major, child->info.minor,
if (!_resume_node(child->name, child->info.major, child->info.minor,
child->props.read_ahead,
child->props.read_ahead_flags, &newinfo)) {
log_error("Unable to resume %s (%" PRIu32
":%" PRIu32 ")", name, child->info.major,
":%" PRIu32 ")", child->name, child->info.major,
child->info.minor);
continue;
}
@@ -1510,7 +1510,6 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
void *handle = NULL;
struct dm_tree_node *child;
struct dm_info newinfo;
const char *name;
/* Preload children first */
while ((child = dm_tree_next_child(&handle, dnode, 0))) {
@@ -1526,11 +1525,6 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
if (dm_tree_node_num_children(child, 0))
dm_tree_preload_children(child, uuid_prefix, uuid_prefix_len);
if (!(name = dm_tree_node_get_name(child))) {
stack;
continue;
}
/* FIXME Cope if name exists with no uuid? */
if (!child->info.exists) {
if (!_create_node(child)) {
@@ -1553,11 +1547,11 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
if (!child->info.inactive_table && !child->info.suspended)
continue;
if (!_resume_node(name, child->info.major, child->info.minor,
if (!_resume_node(child->name, child->info.major, child->info.minor,
child->props.read_ahead,
child->props.read_ahead_flags, &newinfo)) {
log_error("Unable to resume %s (%" PRIu32
":%" PRIu32 ")", name, child->info.major,
":%" PRIu32 ")", child->name, child->info.major,
child->info.minor);
continue;
}

View File

@@ -75,11 +75,10 @@ Change access permission to read-only or read/write.
.I \-r, \-\-readahead ReadAheadSectors|auto|none
Set read ahead sector count of this logical volume.
For volume groups with metadata in lvm1 format, this must
be a value between 2 and 120.
be a value between 2 and 120 sectors.
The default value is "auto" which allows the kernel to choose
a suitable value automatically.
"None" is equivalent to specifying zero.
N.B. This setting is currently disregarded and "auto" is always used.
.TP
.I \-\-refresh
If the logical volume is active, reload its metadata.

View File

@@ -125,7 +125,6 @@ be a value between 2 and 120.
The default value is "auto" which allows the kernel to choose
a suitable value automatically.
"None" is equivalent to specifying zero.
N.B. This setting is currently disregarded and "auto" is always used.
.TP
.I \-R, \-\-regionsize MirrorLogRegionSize
A mirror is divided into regions of this size (in MB), and the mirror log

View File

@@ -20,4 +20,6 @@ include $(top_srcdir)/make.tmpl
install:
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) lvm_dump.sh \
$(sbindir)/lvmdump
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) fsadm.sh \
$(sbindir)/fsadm

345
scripts/fsadm.sh Normal file
View File

@@ -0,0 +1,345 @@
#!/bin/sh
#
# Copyright (C) 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 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
#
# Author: Zdenek Kabelac <zkabelac@redhat.com>
#
# Script for resizing devices (usable for LVM resize)
#
# Needed utilities:
# mount, umount, grep, readlink, blockdev, blkid, fsck, xfs_check
#
# ext2/ext3: resize2fs, tune2fs
# reiserfs: resize_reiserfs, reiserfstune
# xfs: xfs_growfs, xfs_info
#
TOOL=fsadm
PATH=/sbin:/usr/sbin:/bin:/usr/sbin:$PATH
# utilities
TUNE_EXT=tune2fs
RESIZE_EXT=resize2fs
TUNE_REISER=reiserfstune
RESIZE_REISER=resize_reiserfs
TUNE_XFS=xfs_info
RESIZE_XFS=xfs_growfs
MOUNT=mount
UMOUNT=umount
MKDIR=mkdir
RM=rm
BLOCKDEV=blockdev
BLKID=blkid
GREP=grep
READLINK=readlink
FSCK=fsck
XFS_CHECK=xfs_check
YES=
DRY=0
VERB=0
FORCE=
EXTOFF=0
FSTYPE=unknown
VOLUME=unknown
TEMPDIR="${TMPDIR:-/tmp}/${TOOL}_${RANDOM}$$/m"
BLOCKSIZE=
BLOCKCOUNT=
MOUNTPOINT=
MOUNTED=
REMOUNT=
IFS_OLD=$IFS
tool_usage() {
echo "${TOOL}: Utility to resize or check the filesystem on a device"
echo
echo " ${TOOL} [options] check device"
echo " - Check the filesystem on device using fsck"
echo
echo " ${TOOL} [options] resize device [new_size[BKMGT]]"
echo " - Change the size of the filesystem on device to new_size"
echo
echo " Options:"
echo " -h | --help Show this help message"
echo " -v | --verbose Be verbose"
echo " -e | --ext-offline unmount filesystem before Ext2/3 resize"
echo " -f | --force Bypass sanity checks"
echo " -n | --dry-run Print commands without running them"
echo " -y | --yes Answer \"yes\" at any prompts"
echo
echo " new_size - Absolute number of filesystem blocks to be in the filesystem,"
echo " or an absolute size using a suffix (in powers of 1024)."
echo " If new_size is not supplied, the whole device is used."
exit
}
verbose() {
test "$VERB" -eq 1 && echo "$TOOL: $@" || true
}
error() {
echo "$TOOL: $@" >&2
cleanup 1
}
dry() {
verbose "Executing $@"
test "$DRY" -ne 0 && return 0
$@
}
cleanup() {
trap '' 2
# reset MOUNTPOINT - avoid recursion
test "$MOUNTPOINT" = "$TEMPDIR" && MOUNTPOINT="" temp_umount
if [ -n "$REMOUNT" ]; then
verbose "Remounting unmounted filesystem back"
dry $MOUNT "$VOLUME" "$MOUNTED"
fi
IFS=$IFS_OLD
trap 2
exit $1
}
# convert parameters from Mega/Kilo/Bytes/Blocks
# and print number of bytes
decode_size() {
case "$1" in
*[tT]) NEWSIZE=$(( ${1%[tT]} * 1099511627776 )) ;;
*[gG]) NEWSIZE=$(( ${1%[gG]} * 1073741824 )) ;;
*[mM]) NEWSIZE=$(( ${1%[mM]} * 1048576 )) ;;
*[kK]) NEWSIZE=$(( ${1%[kK]} * 1024 )) ;;
*[bB]) NEWSIZE=${1%[bB]} ;;
*) NEWSIZE=$(( $1 * $2 )) ;;
esac
#NEWBLOCKCOUNT=$(round_block_size $NEWSIZE $2)
NEWBLOCKCOUNT=$(( $NEWSIZE / $2 ))
}
# detect filesystem on the given device
# dereference device name if it is symbolic link
detect_fs() {
VOLUME=$($READLINK -e -n "$1")
# use /dev/null as cache file to be sure about the result
FSTYPE=$($BLKID -c /dev/null -o value -s TYPE "$VOLUME" || error "Cannot get FSTYPE of \"$VOLUME\"")
verbose "\"$FSTYPE\" filesystem found on \"$VOLUME\""
}
# check if the given device is already mounted and where
detect_mounted() {
MOUNTED=$($MOUNT | $GREP "$VOLUME")
MOUNTED=${MOUNTED##* on }
MOUNTED=${MOUNTED% type *} # allow type in the mount name
test -n "$MOUNTED"
}
# get the full size of device in bytes
detect_device_size() {
DEVSIZE=$($BLOCKDEV --getsize64 "$VOLUME") || error "Cannot read device \"$VOLUME\""
}
# round up $1 / $2
# could be needed to gaurantee 'at least given size'
# but it makes many troubles
round_up_block_size() {
echo $(( ($1 + $2 - 1) / $2 ))
}
temp_mount() {
dry $MKDIR -p -m 0000 "$TEMPDIR" || error "Failed to create $TEMPDIR"
dry $MOUNT "$VOLUME" "$TEMPDIR" || error "Failed to mount $TEMPDIR"
}
temp_umount() {
dry $UMOUNT "$TEMPDIR" && dry $RM -r "${TEMPDIR%%m}" || error "Failed to umount $TEMPDIR"
}
yes_no() {
echo -n "$@? [Y|n] "
if [ -n "$YES" ]; then
ANS="y"; echo -n $ANS
else
read -n 1 ANS
fi
test -n "$ANS" && echo
case "$ANS" in
"y" | "Y" | "" ) return 0 ;;
esac
return 1
}
try_umount() {
yes_no "Do you want to unmount \"$MOUNTED\"" && dry $UMOUNT "$MOUNTED" && return 0
error "Cannot proceed test with mounted filesystem \"$MOUNTED\""
}
validate_parsing() {
test -n "$BLOCKSIZE" -a -n "$BLOCKCOUNT" || error "Cannot parse $1 output"
}
####################################
# Resize ext2/ext3 filesystem
# - unmounted or mounted for upsize
# - unmounted for downsize
####################################
resize_ext() {
verbose "Parsing $TUNE_EXT -l \"$VOLUME\""
for i in $($TUNE_EXT -l "$VOLUME"); do
case "$i" in
"Block size"*) BLOCKSIZE=${i##* } ;;
"Block count"*) BLOCKCOUNT=${i##* } ;;
esac
done
validate_parsing $TUNE_EXT
decode_size $1 $BLOCKSIZE
FSFORCE=$FORCE
if [ $NEWBLOCKCOUNT -lt $BLOCKCOUNT -o $EXTOFF -eq 1 ]; then
detect_mounted && verbose "$RESIZE_EXT needs unmounted filesystem" && try_umount
REMOUNT=$MOUNTED
# CHECKME: after umount resize2fs requires fsck or -f flag.
FSFORCE="-f"
fi
verbose "Resizing \"$VOLUME\" $BLOCKCOUNT -> $NEWBLOCKCOUNT blocks ($NEWSIZE bytes, bs:$BLOCKSIZE)"
dry $RESIZE_EXT $FSFORCE "$VOLUME" $NEWBLOCKCOUNT
}
#############################
# Resize reiserfs filesystem
# - unmounted for upsize
# - unmounted for downsize
#############################
resize_reiser() {
detect_mounted
if [ -n "$MOUNTED" ]; then
verbose "ReiserFS resizes only unmounted filesystem"
try_umount
REMOUNT=$MOUNTED
fi
verbose "Parsing $TUNE_REISER \"$VOLUME\""
for i in $($TUNE_REISER "$VOLUME"); do
case "$i" in
"Blocksize"*) BLOCKSIZE=${i##*: } ;;
"Count of blocks"*) BLOCKCOUNT=${i##*: } ;;
esac
done
validate_parsing $TUNE_REISER
decode_size $1 $BLOCKSIZE
verbose "Resizing \"$VOLUME\" $BLOCKCOUNT -> $NEWBLOCKCOUNT blocks ($NEWSIZE bytes, bs: $NEWBLOCKCOUNT)"
if [ -n "$YES" ]; then
dry echo y | $RESIZE_REISER -s $NEWSIZE "$VOLUME"
else
dry $RESIZE_REISER -s $NEWSIZE "$VOLUME"
fi
}
########################
# Resize XFS filesystem
# - mounted for upsize
# - can not downsize
########################
resize_xfs() {
detect_mounted
MOUNTPOINT=$MOUNTED
if [ -z "$MOUNTED" ]; then
MOUNTPOINT=$TEMPDIR
temp_mount || error "Cannot mount Xfs filesystem"
fi
verbose "Parsing $TUNE_XFS \"$MOUNTPOINT\""
for i in $($TUNE_XFS "$MOUNTPOINT"); do
case "$i" in
"data"*) BLOCKSIZE=${i##*bsize=} ; BLOCKCOUNT=${i##*blocks=} ;;
esac
done
BLOCKSIZE=${BLOCKSIZE%%[^0-9]*}
BLOCKCOUNT=${BLOCKCOUNT%%[^0-9]*}
validate_parsing $TUNE_XFS
decode_size $1 $BLOCKSIZE
if [ $NEWBLOCKCOUNT -gt $BLOCKCOUNT ]; then
verbose "Resizing Xfs mounted on \"$MOUNTPOINT\" to fill device \"$VOLUME\""
dry $RESIZE_XFS $MOUNTPOINT
elif [ $NEWBLOCKCOUNT -eq $BLOCKCOUNT ]; then
verbose "Xfs filesystem already has the right size"
else
error "Xfs filesystem shrinking is unsupported"
fi
}
####################
# Resize filesystem
####################
resize() {
detect_fs "$1"
detect_device_size
verbose "Device \"$VOLUME\" has $DEVSIZE bytes"
# if the size parameter is missing use device size
NEWSIZE=$2
test -z $NEWSIZE && NEWSIZE=${DEVSIZE}b
trap cleanup 2
#IFS=$'\n' # don't use bash-ism ??
IFS="$(printf \"\\n\")" # needed for parsing output
case "$FSTYPE" in
"ext3"|"ext2") resize_ext $NEWSIZE ;;
"reiserfs") resize_reiser $NEWSIZE ;;
"xfs") resize_xfs $NEWSIZE ;;
*) error "Filesystem \"$FSTYPE\" on device \"$VOLUME\" is not supported by this tool" ;;
esac || error "Resize $FSTYPE failed"
cleanup
}
###################
# Check filesystem
###################
check() {
detect_fs "$1"
case "$FSTYPE" in
"xfs") dry $XFS_CHECK "$VOLUME" ;;
*) dry $FSCK $YES "$VOLUME" ;;
esac
}
#############################
# start point of this script
# - parsing parameters
#############################
if [ "$1" = "" ] ; then
tool_usage
fi
while [ "$1" != "" ]
do
case "$1" in
"-h"|"--help") tool_usage ;;
"-v"|"--verbose") VERB=1 ;;
"-n"|"--dry-run") DRY=1 ;;
"-f"|"--force") FORCE="-f" ;;
"-e"|"--ext-offline") EXTOFF=1 ;;
"-y"|"--yes") YES="-y" ;;
"check") shift; CHECK=$1 ;;
"resize") shift; RESIZE=$1; shift; NEWSIZE=$1 ;;
*) error "Wrong argument \"$1\". (see: $TOOL --help)"
esac
shift
done
if [ -n "$CHECK" ]; then
check "$CHECK"
elif [ -n "$RESIZE" ]; then
resize "$RESIZE" "$NEWSIZE"
else
error "Missing command. (see: $TOOL --help)"
fi

View File

@@ -16,10 +16,6 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
ifeq ("@FSADM@", "yes")
SUBDIRS += fsadm
endif
SOURCES =\
dumpconfig.c \
formats.c \

View File

@@ -1,31 +0,0 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
SOURCES = fsadm.c
TARGETS = fsadm
include $(top_srcdir)/make.tmpl
fsadm: $(OBJECTS)
$(CC) -o $@ $(CFLAGS) $(OBJECTS) -rdynamic
install: fsadm
$(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) fsadm \
$(sbindir)/fsadm

View File

@@ -1,347 +0,0 @@
/*
* Copyright (C) 2004 Red Hat GmbH. All rights reserved.
* Copyright (C) 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 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
*/
/*
* FIXME: pass smart resizer arguments through from lvresize
* (eg, for xfs_growfs)
*/
/* FIXME All funcs to return 0 on success or an error from errno.h on failure */
#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#define MAX_ARGS 8
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <inttypes.h>
#include <fstab.h>
#include <sys/mount.h>
#include <sys/vfs.h>
#include "util.h"
#include "last-path-component.h"
#define log_error(str, x...) fprintf(stderr, "%s(%u): " str "\n", __FILE__, __LINE__, x)
/* Filesystem related information */
struct fsinfo {
struct fstab *fsent;
struct statfs statfs;
uint64_t new_size;
const char *cmd;
};
static void _usage(const char *cmd)
{
log_error("Usage: %s [check <filesystem> | resize <filesystem> <size>]",
last_path_component(cmd));
}
/* FIXME Make this more robust - /proc, multiple mounts, TMPDIR + security etc. */
/* FIXME Ensure filesystem is not mounted anywhere before running fsck/resize */
/* Gather filesystem information (VFS type, special file and block size) */
static int _get_fsinfo(const char *file, struct fsinfo *fsinfo)
{
char *dir, template[] = "/tmp/fscmd_XXXXXX";
struct stat info;
int ret = 0;
if (stat(file, &info)) {
log_error("%s: stat failed: %s", file, strerror(errno));
return errno;
}
/* FIXME: are we limited to /etc/fstab entries ? */
if (!(fsinfo->fsent = info.st_rdev ? getfsspec(file) : getfsfile(file))) {
log_error("%s: getfsspec/getfsfile failed: "
"Missing from /etc/fstab?", file);
return EINVAL;
}
/* FIXME: any other way to retrieve fs blocksize avoiding mounting ? */
if (!(dir = (mkdtemp(template)))) {
log_error("%s: mkdtemp failed: %s", template, strerror(errno));
return errno;
}
if (mount(fsinfo->fsent->fs_spec, dir, fsinfo->fsent->fs_vfstype,
MS_RDONLY, NULL)) {
log_error("%s: mount %s failed: %s", fsinfo->fsent->fs_spec,
dir, strerror(errno));
ret = errno;
goto out;
}
if (statfs(dir, &fsinfo->statfs)) {
log_error("%s: statfs failed: %s", dir, strerror(errno));
ret = errno;
goto out1;
}
out1:
if (umount(dir))
log_error("%s: umount failed: %s", dir, strerror(errno));
out:
if (rmdir(dir))
log_error("%s: rmdir failed: %s", dir, strerror(errno));
return ret;
}
enum {
BLOCKS,
KILOBYTES
};
#define LEN 32 /* Length of temporary string */
/* Create size string in units of blocks or kilobytes
* (size expected in kilobytes)
*/
static char *_size_str(struct fsinfo *fsinfo, int unit)
{
uint64_t new_size = fsinfo->new_size;
static char s[LEN];
/* Avoid switch() as long as there's only 2 cases */
snprintf(s, LEN, "%" PRIu64,
unit == BLOCKS ? new_size / (fsinfo->statfs.f_bsize >> 10) :
new_size);
return s;
}
/* Allocate memory and store string updating string pointer */
static int _store(char **arg, char **str)
{
size_t len = 0;
char *s = *str;
while (*s && *s != '%' && *(s++) != ' ')
len++;
if ((*arg = (char *) malloc(len + 1))) {
strncpy(*arg, *str, len);
(*arg)[len] = '\0';
*str = s - 1;
return 0;
}
return 1;
}
/* Construct a new argument vector for the real external command */
static int _new_argv(char **new_argv, struct fsinfo *fsinfo)
{
int i = 0, b = 0, d = 0, k = 0, m = 0;
char *s1;
char *s = (char *) fsinfo->cmd;
if (!s || !strlen(s))
return 1;
do {
switch (*s) {
case ' ':
break;
case '%':
s++;
switch (tolower(*s)) {
case 'b':
s1 = _size_str(fsinfo, BLOCKS);
if (b++ + k || _store(&new_argv[i++], &s1))
goto error;
break;
case 'k':
s1 = _size_str(fsinfo, KILOBYTES);
if (b + k++ || _store(&new_argv[i++], &s1))
goto error;
break;
case 'd':
s1 = fsinfo->fsent->fs_spec;
if (d++ + m || _store(&new_argv[i++], &s1))
goto error;
break;
case 'm':
s1 = fsinfo->fsent->fs_file;
if (d + m++ || _store(&new_argv[i++], &s1))
goto error;
break;
default:
goto error;
}
break;
default:
if (_store(&new_argv[i++], &s))
goto error;
}
} while (*++s);
new_argv[i] = NULL;
return 0;
error:
new_argv[i] = NULL;
log_error("Failed constructing arguments for %s", s);
return EINVAL;
}
/*
* Get filesystem command arguments derived from a command definition string
*
* Command definition syntax: 'cmd [-option]{0,} [(option)argument]{0,}'
*
* (option)argument can be: '%{bdkm}'
*
* Command definition is parsed into argument strings of
* an argument vector with:
*
* %b replaced by the size in filesystem blocks
* %k replaced by the size in kilobytes
* %d replaced by the name of the device special of the LV
* %m replaced by the mountpoint of the filesystem
*
*/
static int _get_cmd(char *command, struct fsinfo *fsinfo)
{
const char *vfstype = fsinfo->fsent->fs_vfstype;
struct fscmd {
const char *vfstype;
const char *fsck;
const char *fsresize;
} fscmds[] = {
{ "ext2", "fsck -fy %d", "ext2resize %d %b"},
{"ext3", "fsck -fy %d", "ext2resize %d %b"},
{"reiserfs", "", "resize_reiserfs -s%k %d"},
{"xfs", "", "xfs_growfs -D %b %m"}, /* simple xfs grow */
{NULL, NULL, NULL},
}, *p = &fscmds[0];
for (; p->vfstype; p++) {
if (!strcmp(vfstype, p->vfstype)) {
if (!strcmp(command, "resize"))
fsinfo->cmd = p->fsresize;
else if (!strcmp(command, "check"))
fsinfo->cmd = p->fsck;
else {
log_error("Unrecognised command: %s", command);
return EINVAL;
}
break;
}
}
if (!fsinfo->cmd) {
log_error("%s: Unrecognised filesystem type", vfstype);
return EINVAL;
}
return 0;
}
/* Collapse multiple slashes */
static char *_collapse_slashes(char *path)
{
char *s = path;
/* Slight overhead but short ;) */
while ((s = strchr(s, '/')) && *(s + 1))
*(s + 1) == '/' ? memmove(s, s + 1, strlen(s)) : s++;
return path;
}
/* Free the argument array */
static void _free_argv(char **new_argv)
{
int i;
for (i = 0; new_argv[i]; i++)
free(new_argv[i]);
}
/*
* check/resize a filesystem
*/
int main(int argc, char **argv)
{
int ret = 0;
struct fsinfo fsinfo;
char *new_argv[MAX_ARGS];
char *command, *path;
if (argc < 3)
goto error;
command = argv[1];
path = _collapse_slashes(argv[2]);
if (!strcmp(command, "resize")) {
if (argc != 4)
goto error;
/* FIXME sanity checks */
fsinfo.new_size = strtoul(argv[3], NULL, 10);
} else if (argc != 3)
goto error;
/* Retrieve filesystem information (block size...) */
if ((ret = _get_fsinfo(path, &fsinfo))) {
log_error("Can't get filesystem information from %s", path);
return ret;
}
/* Get filesystem command info */
if ((ret = _get_cmd(command, &fsinfo))) {
log_error("Can't get filesystem command for %s", command);
return ret;
}
if (_new_argv(new_argv, &fsinfo))
return EINVAL;
if (!new_argv[0])
return 0;
execvp(new_argv[0], new_argv);
ret = errno;
log_error("%s: execvp %s failed", new_argv[0], strerror(errno));
_free_argv(new_argv);
return ret;
error:
_usage(argv[0]);
return EINVAL;
}

View File

@@ -372,6 +372,7 @@ static int lvchange_readahead(struct cmd_context *cmd,
struct logical_volume *lv)
{
unsigned read_ahead = 0;
unsigned pagesize = (unsigned) lvm_getpagesize() >> SECTOR_SHIFT;
read_ahead = arg_uint_value(cmd, readahead_ARG, 0);
@@ -382,6 +383,13 @@ static int lvchange_readahead(struct cmd_context *cmd,
return 0;
}
if (read_ahead != DM_READ_AHEAD_AUTO &&
read_ahead != DM_READ_AHEAD_NONE && read_ahead % pagesize) {
read_ahead = (read_ahead / pagesize) * pagesize;
log_verbose("Rounding down readahead to %u sectors, a multiple "
"of page size %u.", read_ahead, pagesize);
}
if (lv->read_ahead == read_ahead) {
log_error("Read ahead is already %u for \"%s\"",
read_ahead, lv->name);

View File

@@ -339,7 +339,7 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l
1, lp->mirrors - 1,
corelog ? 0U : 1U,
lv->le_count, lp->pvh, lp->alloc,
parallel_areas)))
1, parallel_areas)))
return_0;
lp->region_size = adjusted_mirror_region_size(lv->vg->extent_size,
@@ -385,7 +385,7 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l
if (!(ah = allocate_extents(lv->vg, NULL, lp->segtype, 0,
0, 1, 0, lp->pvh, lp->alloc,
parallel_areas))) {
1, parallel_areas))) {
stack;
return 0;
}

View File

@@ -333,6 +333,7 @@ static int _lvcreate_params(struct lvcreate_params *lp, struct cmd_context *cmd,
int argc, char **argv)
{
int contiguous;
unsigned pagesize;
memset(lp, 0, sizeof(*lp));
@@ -462,8 +463,17 @@ static int _lvcreate_params(struct lvcreate_params *lp, struct cmd_context *cmd,
/*
* Read ahead.
*/
if (arg_count(cmd, readahead_ARG))
if (arg_count(cmd, readahead_ARG)) {
lp->read_ahead = arg_uint_value(cmd, readahead_ARG, 0);
pagesize = lvm_getpagesize() >> SECTOR_SHIFT;
if (lp->read_ahead != DM_READ_AHEAD_AUTO &&
lp->read_ahead != DM_READ_AHEAD_NONE &&
lp->read_ahead % pagesize) {
lp->read_ahead = (lp->read_ahead / pagesize) * pagesize;
log_verbose("Rounding down readahead to %u sectors, a multiple "
"of page size %u.", lp->read_ahead, pagesize);
}
}
/*
* Permissions.
@@ -740,7 +750,7 @@ static int _lvcreate(struct cmd_context *cmd, struct volume_group *vg,
if (!(ah = allocate_extents(vg, NULL, lp->segtype, lp->stripes,
lp->mirrors, lp->corelog ? 0U : 1U,
lp->extents, pvh, lp->alloc, NULL)))
lp->extents, pvh, lp->alloc, 1, NULL)))
return_0;
lp->region_size = adjusted_mirror_region_size(vg->extent_size,

View File

@@ -161,6 +161,11 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
log_print("Skipping locked LV %s", lv->name);
continue;
}
/* FIXME Just insert the layer below - no allocation */
// This knows nothing about pvmove
// insert_layer_for_segments_on_pv(cmd, lv, source_pvl, lv_mirr, *lvs_changed)
// - for each lv segment using that pv
// - call new fn insert_internal_layer()
if (!insert_pvmove_mirrors(cmd, lv_mirr, source_pvl, lv,
allocatable_pvs, alloc,
*lvs_changed)) {
@@ -175,6 +180,10 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
return NULL;
}
/* FIXME Do allocation and convert to mirror */
// again, this knows nothing about pvmove: it's a normal lvconvert lv_mirr to mirror with in-core log
// - a flag passed in requires that parent segs get split after the allocation (with failure if not possible)
return lv_mirr;
}

View File

@@ -59,8 +59,10 @@ static int _pvsegs_sub_single(struct cmd_context *cmd __attribute((unused)),
struct pv_segment *pvseg, void *handle)
{
int ret = ECMD_PROCESSED;
struct lv_segment *seg = pvseg->lvseg;
if (!report_object(handle, vg, NULL, pvseg->pv, NULL, pvseg))
if (!report_object(handle, vg, seg ? seg->lv : NULL, pvseg->pv, seg,
pvseg))
ret = ECMD_FAILED;
return ret;
@@ -279,21 +281,22 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
report_type |= LVS;
if (report_type & PVSEGS)
report_type |= PVS;
if ((report_type & LVS) && (report_type & PVS)) {
if ((report_type & LVS) && (report_type & PVS) && !args_are_pvs) {
log_error("Can't report LV and PV fields at the same time");
dm_report_free(report_handle);
return 0;
}
/* Change report type if fields specified makes this necessary */
if (report_type & SEGS)
report_type = SEGS;
else if (report_type & LVS)
report_type = LVS;
else if (report_type & PVSEGS)
if ((report_type & PVSEGS) ||
(report_type & PVS) && (report_type & LVS))
report_type = PVSEGS;
else if (report_type & PVS)
report_type = PVS;
else if (report_type & SEGS)
report_type = SEGS;
else if (report_type & LVS)
report_type = LVS;
switch (report_type) {
case LVS: