1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-10-06 11:33:14 +03:00

Compare commits

..

50 Commits

Author SHA1 Message Date
Alasdair Kergon
990af7548a Increment version. 2002-05-31 19:33:30 +00:00
Alasdair Kergon
a38aefdfc8 Add vgsplit. 2002-05-31 19:30:51 +00:00
Alasdair Kergon
3bcb12e7d1 Tidy/fix segment rounding. 2002-05-31 19:29:43 +00:00
Alasdair Kergon
7904ecb462 Tidy 2002-05-31 19:28:37 +00:00
Alasdair Kergon
9ba4d45109 Remember to update VG free_count when reducing size of an LV. 2002-05-30 16:08:19 +00:00
Alasdair Kergon
56b8afe19d Fix vgcfgrestore segfault (wrong variable used). 2002-05-30 16:03:26 +00:00
Alasdair Kergon
f7aed9a94c update 2002-05-27 13:00:18 +00:00
AJ Lewis
e12a7e881d o fix changed function names 2002-05-23 14:13:21 +00:00
Alasdair Kergon
5afb65325d Fix LVM1 backwards compatibility issue when LV with a low LV number is deleted. 2002-05-23 11:37:51 +00:00
Joe Thornber
135f520f32 o Remove ext3 incompatibility bug
o	Mention 2.4.18 VM problem
2002-05-23 08:20:44 +00:00
Andres Salomon
bc251f4ff6 update for .08 2002-05-23 07:49:25 +00:00
Alasdair Kergon
b8769751f6 Rename; add some FIXMEs. 2002-05-22 14:03:45 +00:00
Alasdair Kergon
eff96d839e Revert to standard linux macros (for correct behaviour on rare architectures). 2002-05-21 12:37:07 +00:00
Alasdair Kergon
aa34c23807 Update version. 2002-05-21 12:14:05 +00:00
Andres Salomon
195acdac8c ack, missing include 2002-05-19 04:11:34 +00:00
Andres Salomon
903e03c56c update create_dir() comment 2002-05-19 03:52:38 +00:00
Andres Salomon
0892767b8a support recursive mkdir in create_dir() 2002-05-19 03:46:34 +00:00
Andres Salomon
83ebfa772c synch w/ -3 "oh shit" release 2002-05-14 03:56:40 +00:00
Joe Thornber
1583641322 Drop the default chunk size for snapshots down to 8k 2002-05-13 15:14:21 +00:00
Alasdair Kergon
9510e2c256 Rewrite missing/corrupt metadata in more cases. 2002-05-13 12:38:54 +00:00
AJ Lewis
a9dbabe07e o the _status fxns now take more arguments - this way i don't get the
preparsed status info, shove it all into a string, and then parse it
   again to get the info back out (which is what i was doing before)
 o basically that's it...i like this *much* better than the previous
   method and i think it makes the _status fxn more flexible if we need
   to use it to get other info out.
2002-05-10 16:06:06 +00:00
Alasdair Kergon
12884008fa Import snapshot status & persistence + indent etc. 2002-05-10 15:25:38 +00:00
AJ Lewis
02543bad1c o Actually read snapshot percentage from the kernel - what a pain! :)
o Not sure if the code in dev_manager is really optimal, but it works..
   will look at adjusting it a bit now.
 o I *think* it works right when one snapshot if full but others aren't,
   but I haven't really been able to test it because the full snapshot
   somehow resets itself and weird things start happening to the system...
2002-05-09 21:17:57 +00:00
Alasdair Kergon
a8c56a5251 Remove a no-op. 2002-05-09 12:03:55 +00:00
AJ Lewis
4e5a855f3f o header should only be printed once... 2002-05-08 17:58:52 +00:00
AJ Lewis
7e497a951e o Added function find_snapshots to snapshot_manip.c that returns a list
of snapshots whose origin is the lv passed in.
 o Used this new function to make lvdisplay properly display all snapshots
   attached to a origin.
2002-05-08 16:57:46 +00:00
Joe Thornber
cd08eabbfa i) Put back chunksize_ARG for lvcreate. 2002-05-08 14:36:10 +00:00
Alasdair Kergon
f7e62d9f81 Always call init_log() to initialise logging defaults. 2002-05-08 12:26:45 +00:00
Andres Salomon
9a3761e86e implement our own swabbing functions, instead of relying on the kernel's. 2002-05-07 15:28:59 +00:00
Alasdair Kergon
3619a68693 log/{prefix,command_names} use defaults.h & reset between shell cmds 2002-05-07 13:00:01 +00:00
Alasdair Kergon
efaf3c3bf9 Default values for some display output settings 2002-05-07 12:50:01 +00:00
Alasdair Kergon
0e4e6a6f67 Tweaks 2002-05-07 12:47:11 +00:00
Andres Salomon
42458e6278 updated. 2002-05-07 06:13:03 +00:00
Andres Salomon
41ec995377 Make lvm2 compile on big endian archs; use the kernel/glibc's endian
conversion stuff, instead of implementing our own.  Tested on a little
endian system (x86); I'll let the debian handle big endian testing.  :)
2002-05-07 05:54:14 +00:00
AJ Lewis
4f37599326 o Will now correctly remove expired achive files from the system when
archive_vg is called.
 o Added a #define to the top of the file - not sure if this is the
   appropriate place for it though
2002-05-03 19:28:07 +00:00
Patrick Caulfield
4144520e5c Add features to get table/status & wait for next event. 2002-05-03 11:55:58 +00:00
Andres Salomon
6c4800546c forgot to add Conflicts against lvm1 packages 2002-05-03 04:57:49 +00:00
Andres Salomon
733733c8a7 updated for 0.95.05-2. 2002-05-03 04:43:46 +00:00
Andres Salomon
2aa67cc946 ditto 2002-05-03 04:43:24 +00:00
Andres Salomon
9385981a9d dh_installinit makes a perfectly find postrm script.. 2002-05-03 04:13:02 +00:00
Alasdair Kergon
fff780035d Update. 2002-04-30 17:13:43 +00:00
Alasdair Kergon
46127e673d Some partial VG support with format_text. 2002-04-30 17:12:37 +00:00
Alasdair Kergon
70df59b224 get_vgs must check for text format VGs when no lvm1 format VGs present 2002-04-30 12:27:13 +00:00
AJ Lewis
0fdbaa803f o Updated *display output for LVM1 compatibility
o There is still a bit missing
   + all are missing the {PV,VG,LV} # - that is not applicable in LVM2
   + pvdisplay doesn't show how many LVs are contained on it
   + much of the snapshot information isn't available for lvdisplay
 o Look at the code for other potiential FIXMEs  :)
2002-04-29 21:43:14 +00:00
Heinz Mauelshagen
6af1830eff Changed DEFAULT_PV and DEFAULT_LV to 256 (has been fixed in LVM1 before) 2002-04-25 10:53:58 +00:00
Andres Salomon
6f860e2bd5 Updated for new release 2002-04-25 06:12:07 +00:00
Alasdair Kergon
20a492f7ee Update example config 2002-04-24 18:41:02 +00:00
Alasdair Kergon
63875e7591 Merge with text format branch.
Lots of changes/very little testing so far => there'll be bugs!

Use 'vgcreate -M text' to create a volume group with its metadata stored
in text files.  Text format metadata changes should be reasonably atomic,
with a (basic) automatic recovery mechanism if the system crashes while a
change is in progress.

Add a metadata section to lvm.conf to specify multiple directories if
you want (recommended) to keep multiple copies of the metadata (eg on
different filesystems).

e.g. metadata {
        dirs = ["/etc/lvm/metadata1","/usr/local/lvm/metadata2"]
}

Plenty of refinements still in the pipeline.
2002-04-24 18:20:51 +00:00
Patrick Caulfield
0ad98cabde add setlocale() call so that localisation of things like number entry
and display will work correctly.
2002-04-24 10:42:09 +00:00
Joe Thornber
668879d2e1 o Stop printing errors if flushing fails (could be an unconfigured device). 2002-04-24 08:37:34 +00:00
108 changed files with 3364 additions and 2088 deletions

3
BUGS
View File

@@ -1 +1,2 @@
LVM2's device-mapper driver and ext3 are incompatible at the moment.
Snapshots under 2.4.18 can deadlock due to a bug in the VM system.
2.4.19-pre8 is fine.

View File

@@ -1 +1 @@
0.95.05-cvs (2002-04-23)
1.95.10-cvs (2002-05-31)

27
debian/changelog vendored
View File

@@ -1,3 +1,30 @@
lvm2 (1.95.08-1) unstable; urgency=low
* New upstream release (Beta3).
-- Andres Salomon <dilinger@mp3revolution.net> Thu, 23 May 2002 03:46:37 -0500
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.

3
debian/control vendored
View File

@@ -7,7 +7,8 @@ Standards-Version: 3.5.2
Package: lvm2
Architecture: any
Depends: libdevmapper0
Depends: ${shlibs:Depends}
Conflicts: lvm10, lvm-common
Replaces: lvm10, lvm-common
Provides: lvm-binaries
Suggests: dmsetup

4
debian/docs vendored
View File

@@ -3,6 +3,4 @@ INTRO
README
TODO
VERSION
doc/example.conf
doc/pvmove_outline.txt
doc/testing.txt
doc/*

13
debian/init.d vendored
View File

@@ -16,8 +16,8 @@ modprobe dm-mod >/dev/null 2>&1
create_devfiles() {
DIR="/dev/device-mapper"
FILE="$DIR/control"
major=$(awk '$2 ~ /^misc$/ {print $1}' /proc/devices)
minor=$(awk "\$2 ~ /^$DM_NAME\$/ {print \$1}" /proc/misc)
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
@@ -33,12 +33,6 @@ case "$1" in
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)
@@ -56,8 +50,7 @@ case "$1" in
echo "$NAME."
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|force-reload}" >&2
echo "Usage: /etc/init.d/$NAME {start|stop|restart|force-reload}" >&2
exit 1
;;
esac

49
debian/postinst vendored
View File

@@ -1,49 +0,0 @@
#! /bin/sh
# postinst script for lvm2
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postinst> `configure' <most-recently-configured-version>
# * <old-postinst> `abort-upgrade' <new version>
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
# <new-version>
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
# <failed-install-package> <version> `removing'
# <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
#
# quoting from the policy:
# Any necessary prompting should almost always be confined to the
# post-installation script, and should be protected with a conditional
# so that unnecessary prompting doesn't happen if a package's
# installation fails and the `postinst' is called with `abort-upgrade',
# `abort-remove' or `abort-deconfigure'.
case "$1" in
configure)
update-rc.d lvm2 start 25 S . start 50 0 6 . >/dev/null
/etc/init.d/lvm2 start
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0

39
debian/postrm vendored
View File

@@ -1,39 +0,0 @@
#! /bin/sh
# postrm script for lvm2
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postrm> `remove'
# * <postrm> `purge'
# * <old-postrm> `upgrade' <new-version>
# * <new-postrm> `failed-upgrade' <old-version>
# * <new-postrm> `abort-install'
# * <new-postrm> `abort-install' <old-version>
# * <new-postrm> `abort-upgrade' <old-version>
# * <disappearer's-postrm> `disappear' <r>overwrit>r> <new-version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
purge)
rm -f /etc/init.d/lvm2
update-rc.d lvm2 remove >/dev/null
;;
remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
;;
*)
echo "postrm called with unknown argument \`$1'" >&2
exit 1
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0

2
debian/rules vendored
View File

@@ -98,7 +98,7 @@ binary-arch: build install
# dh_installemacsen -a
# dh_installpam -a
# dh_installmime -a
dh_installinit -n
dh_installinit --update-rcd-params="start 25 S . start 50 0 6 ."
dh_installcron
dh_installman
dh_installinfo

View File

@@ -122,6 +122,12 @@ shell {
history_size = 100
}
# Metadata settings
metadata {
# List of directories holding copies of text format metadata
dirs = [ "/etc/lvm/metadata" ]
}
# Miscellaneous global settings
global {
@@ -136,4 +142,11 @@ global {
# will be made. Equivalent to having the -t option on every
# command. Defaults to off.
test = 0
# Default metadata format commands use - "lvm1" (default) or "text"
format = "lvm1"
# Location of proc filesystem
proc = "/proc"
}

View File

@@ -1,101 +0,0 @@
/*
* Copyright (C) 2002 Sistina Software (UK) Limited.
*
* This file is released under the LGPL.
*/
#include "ll-activate.h"
#include "lvm-string.h"
#include "log.h"
#include <libdevmapper.h>
/*
* Emit a target for a given segment.
* FIXME: tidy this function.
*/
static int _emit_target(struct dm_task *dmt, struct stripe_segment *seg)
{
char params[1024];
uint64_t esize = seg->lv->vg->extent_size;
uint32_t s, stripes = seg->stripes;
int w = 0, tw = 0, error = 0;
const char *no_space =
"Insufficient space to write target parameters.";
char *filler = "/dev/ioerror";
char *target;
if (stripes == 1) {
if (!seg->area[0].pv) {
target = "error";
error = 1;
}
else
target = "linear";
}
if (stripes > 1) {
target = "striped";
tw = lvm_snprintf(params, sizeof(params), "%u %u ",
stripes, seg->stripe_size);
if (tw < 0) {
log_err(no_space);
return 0;
}
w = tw;
}
if (!error) {
for (s = 0; s < stripes; s++, w += tw) {
if (!seg->area[s].pv)
tw = lvm_snprintf(
params + w, sizeof(params) - w,
"%s 0%s", filler,
s == (stripes - 1) ? "" : " ");
else
tw = lvm_snprintf(
params + w, sizeof(params) - w,
"%s %" PRIu64 "%s",
dev_name(seg->area[s].pv->dev),
(seg->area[s].pv->pe_start +
(esize * seg->area[s].pe)),
s == (stripes - 1) ? "" : " ");
if (tw < 0) {
log_err(no_space);
return 0;
}
}
}
log_very_verbose("Adding target: %" PRIu64 " %" PRIu64 " %s %s",
esize * seg->le, esize * seg->len,
target, params);
if (!dm_task_add_target(dmt, esize * seg->le, esize * seg->len,
target, params)) {
stack;
return 0;
}
return 1;
}
int device_populate_lv(struct dm_task *dmt, struct logical_volume *lv)
{
struct list *segh;
struct stripe_segment *seg;
log_very_verbose("Generating devmapper table for %s", lv->name);
list_iterate(segh, &lv->segments) {
seg = list_item(segh, struct stripe_segment);
if (!_emit_target(dmt, seg)) {
log_error("Unable to build table for '%s'", lv->name);
return 0;
}
}
return 1;
}

View File

@@ -75,6 +75,27 @@ int lv_info(struct logical_volume *lv, struct dm_info *info)
return r;
}
/*
* Returns 1 if percent set, else 0 on failure.
*/
int lv_snapshot_percent(struct logical_volume *lv, float *percent)
{
int r;
struct dev_manager *dm;
if (!(dm = dev_manager_create(lv->vg->name))) {
stack;
return 0;
}
if (!(r = dev_manager_snapshot_percent(dm, lv, percent)))
stack;
dev_manager_destroy(dm);
return r;
}
static int _lv_active(struct logical_volume *lv)
{
struct dm_info info;
@@ -189,24 +210,18 @@ static struct logical_volume *_lv_from_lvid(struct cmd_context *cmd,
struct lv_list *lvl;
struct volume_group *vg;
union lvid *lvid;
char *vgname;
lvid = (union lvid *) lvid_s;
/* FIXME Change vgread to accept vgid directly - can't rely on cache */
if (!(vgname = vgname_from_vgid(cmd, &lvid->id[0]))) {
log_very_verbose("Finding volume group for uuid %s", lvid_s);
if (!(vg = vg_read_by_vgid(cmd, lvid->id[0].uuid))) {
log_error("Volume group for uuid not found: %s", lvid_s);
return NULL;
}
log_verbose("Finding volume group \"%s\"", vgname);
if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vgname))) {
log_error("Volume group \"%s\" doesn't exist", vgname);
return NULL;
}
log_verbose("Found volume group \"%s\"", vg->name);
if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vgname);
log_error("Volume group \"%s\" is exported", vg->name);
return NULL;
}

View File

@@ -16,6 +16,10 @@ int library_version(char *version, size_t size);
* Returns 1 if info structure has been populated, else 0.
*/
int lv_info(struct logical_volume *lv, struct dm_info *info);
/*
* Returns 1 if percent has been set, else 0.
*/
int lv_snapshot_percent(struct logical_volume *lv, float *percent);
/*
* These should eventually use config file

View File

@@ -329,6 +329,69 @@ static int _info(const char *name, const char *uuid, struct dm_info *info,
return 0;
}
/* FIXME Interface must cope with multiple targets */
static int _status_run(const char *name, const char *uuid,
unsigned long long *s, unsigned long long *l,
char **t, uint32_t t_size, char **p, uint32_t p_size)
{
int r = 0;
struct dm_task *dmt;
void *next = NULL;
unsigned long long start, length;
char *type = NULL;
char *params = NULL;
if (!(dmt = _setup_task(name, uuid, DM_DEVICE_STATUS))) {
stack;
return 0;
}
if (!dm_task_run(dmt)) {
stack;
goto out;
}
do {
next = dm_get_next_target(dmt, next, &start, &length,
&type, &params);
if (type) {
*s = start;
*l = length;
/* Make sure things are null terminated */
strncpy(*t, type, t_size);
(*t)[t_size - 1] = '\0';
strncpy(*p, params, p_size);
(*p)[p_size - 1] = '\0';
r = 1;
/* FIXME Cope with multiple targets! */
break;
}
} while (next);
out:
dm_task_destroy(dmt);
return r;
}
static int _status(const char *name, const char *uuid,
unsigned long long *start, unsigned long long *length,
char **type, uint32_t type_size, char **params,
uint32_t param_size)
{
if (uuid && *uuid && _status_run(NULL, uuid, start, length, type,
type_size, params, param_size)
&& *params)
return 1;
if (name && _status_run(name, NULL, start, length, type, type_size,
params, param_size))
return 1;
return 0;
}
static int _rename(struct dev_manager *dm, struct dev_layer *dl, char *newname)
{
int r = 1;
@@ -538,7 +601,7 @@ static int _emit_target(struct dm_task *dmt, struct stripe_segment *seg)
}
for (s = 0; s < stripes; s++, w += tw) {
if (!seg->area[s].pv)
if (!seg->area[s].pv || !seg->area[s].pv->dev)
tw = lvm_snprintf(params + w, sizeof(params) - w,
"%s 0%s", filler,
s == (stripes - 1) ? "" : " ");
@@ -729,6 +792,56 @@ int dev_manager_info(struct dev_manager *dm, struct logical_volume *lv,
return 1;
}
int dev_manager_snapshot_percent(struct dev_manager *dm,
struct logical_volume *lv, float *percent)
{
char *name, *type, *params;
unsigned long long start, length;
/* FIXME: Use #defines - & move allocations into _status_run ? */
uint32_t type_size = 32;
uint32_t param_size = 32;
if (!(type = pool_alloc(dm->mem, sizeof(*type) * type_size))) {
stack;
return 0;
}
if (!(params = pool_alloc(dm->mem, sizeof(*params) * param_size))) {
stack;
return 0;
}
/*
* Build a name for the top layer.
*/
if (!(name = _build_name(dm->mem, lv->vg->name, lv->name, NULL))) {
stack;
return 0;
}
/*
* Try and get some info on this device.
*/
log_debug("Getting device status for %s", name);
if (!(_status(name, lv->lvid.s, &start, &length, &type, type_size,
&params, param_size))) {
stack;
return 0;
}
/* FIXME Ensure this is a *snapshot* target with percentage! */
/* FIXME pool_free ? */
/* If the snapshot isn't available, percent will be -1 */
*percent = -1;
if (!params)
return 0;
return sscanf(params, "%f", percent);
}
static struct dev_layer *_create_dev(struct dev_manager *dm, char *name,
char *dlid)
{
@@ -1413,9 +1526,10 @@ static int _remove_lvs(struct dev_manager *dm, struct logical_volume *lv)
/* Remove any snapshots with given origin */
list_iterate(sh, active_head) {
active = list_item(sh, struct lv_list)->lv;
if ((s = find_cow(active)) && s->origin == lv)
if ((s = find_cow(active)) && s->origin == lv) {
_remove_lv(active_head, active);
}
}
_remove_lv(active_head, lv);
@@ -1427,9 +1541,10 @@ static int _remove_lvs(struct dev_manager *dm, struct logical_volume *lv)
/* Was this the last active snapshot with this origin? */
list_iterate(sh, active_head) {
active = list_item(sh, struct lv_list)->lv;
if ((s = find_cow(active)) && s->origin == old_origin)
if ((s = find_cow(active)) && s->origin == old_origin) {
return 1;
}
}
return _add_lvs(dm->mem, &dm->reload_list, old_origin);
}

View File

@@ -27,11 +27,12 @@ void dev_manager_destroy(struct dev_manager *dm);
*/
int dev_manager_info(struct dev_manager *dm, struct logical_volume *lv,
struct dm_info *info);
int dev_manager_snapshot_percent(struct dev_manager *dm,
struct logical_volume *lv, float *percent);
int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv);
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv);
int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv);
/*
* Put the desired changes into effect.
*/

View File

@@ -1,31 +0,0 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
*
* This file is released under the GPL.
*/
#ifndef DMFS_INTERFACE_H
#define DMFS_INTERFACE_H
struct dmfs;
struct dmfs *dmfs_create(void);
void dmfs_destroy(struct dmfs *dm);
int dmfs_dev_is_present(struct dmfs *dm, const char *dev);
int dmfs_dev_is_active(struct dmfs *dm, const char *dev);
int dmfs_table_is_present(struct dmfs *dm, const char *dev, const char *table);
int dmfs_table_is_active(struct dmfs *dm, const char *dev, const char *table);
int dmfs_dev_create(struct dmfs *dm, const char *name);
int dmfs_dev_load_table(struct dmfs *dm, const char *dev,
const char *table, const char *file);
int dmfs_dev_drop_table(struct dmfs *dm, const char *dev, const char *table);
int dmfs_dev_activate_table(struct dmfs *dm, const char *dev,
const char *table);
int dmfs_dev_deactivate(struct dmfs *dm, const char *dev);
#endif

View File

@@ -18,7 +18,11 @@ struct cmd_context {
/* format handler allocates all objects from here */
struct pool *mem;
struct format_instance *fid;
struct format_type *fmt; /* Current format to use by default */
/* FIXME Move into dynamic list */
struct format_type *fmt1; /* Format1 */
struct format_type *fmtt; /* Format_text */
char *cmd_line;
char *dev_dir;

View File

@@ -68,7 +68,6 @@ static char *_dup_tok(struct parser *p);
} \
} while(0);
static int _tok_match(const char *str, const char *b, const char *e)
{
while (*str && (b != e)) {
@@ -79,7 +78,6 @@ static int _tok_match(const char *str, const char *b, const char *e)
return !(*str || (b != e));
}
/*
* public interface
*/
@@ -128,13 +126,18 @@ int read_config(struct config_file *cf, const char *file)
return 0;
}
if (info.st_size == 0) {
log_verbose("%s is empty", file);
return 1;
}
if ((fd = open(file, O_RDONLY)) < 0) {
log_sys_error("open", file);
return 0;
}
p->fb = mmap((caddr_t) 0, info.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (p->fb == MAP_FAILED) {
if (p->fb == (caddr_t) (-1)) {
log_sys_error("mmap", file);
close(fd);
return 0;
@@ -434,8 +437,16 @@ static void _get_token(struct parser *p)
case '.':
p->t = TOK_FLOAT;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
p->te++;
while (p->te != p->fe) {
if (*p->te == '.') {
@@ -525,8 +536,7 @@ struct config_node *find_config_node(struct config_node *cn,
path++;
/* find the end of this segment */
for (e = path; *e && (*e != sep); e++)
;
for (e = path; *e && (*e != sep); e++) ;
/* hunt for the node */
while (cn) {
@@ -547,13 +557,13 @@ struct config_node *find_config_node(struct config_node *cn,
return cn;
}
const char *
find_config_str(struct config_node *cn,
const char *find_config_str(struct config_node *cn,
const char *path, char sep, const char *fail)
{
struct config_node *n = find_config_node(cn, path, sep);
if (n && n->v->type == CFG_STRING) {
if (*n->v->v.str)
log_very_verbose("Setting %s to %s", path, n->v->v.str);
return n->v->v.str;
}
@@ -610,7 +620,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};
static const char *_false_values[] =
{ "n", "no", "off", "false", NULL };
if (_str_in_array(str, _true_values))
return 1;
@@ -671,4 +682,3 @@ int get_config_uint64(struct config_node *cn, const char *path,
*result = (uint64_t) n->v->v.i;
return 1;
}

View File

@@ -26,6 +26,12 @@
#define DEFAULT_UMASK 0077
#define DEFAULT_FORMAT "lvm1"
#define DEFAULT_MSG_PREFIX " "
#define DEFAULT_CMD_NAME 0
#ifdef READLINE_SUPPORT
#define DEFAULT_MAX_HISTORY 100
#endif

View File

@@ -40,8 +40,7 @@ static uint32_t _shuffle(uint32_t k)
#if 1
return ((k & 0xff) << 24 |
(k & 0xff00) << 8 |
(k & 0xff0000) >> 8 |
(k & 0xff000000) >> 24);
(k & 0xff0000) >> 8 | (k & 0xff000000) >> 24);
#else
return k;
#endif

View File

@@ -4,7 +4,6 @@
* This file is released under the LGPL.
*/
#include "dbg_malloc.h"
#include "hash.h"
#include "log.h"
@@ -26,19 +25,27 @@ static unsigned char _nums[] = {
1, 14, 110, 25, 97, 174, 132, 119, 138, 170, 125, 118, 27, 233, 140, 51,
87, 197, 177, 107, 234, 169, 56, 68, 30, 7, 173, 73, 188, 40, 36, 65,
49, 213, 104, 190, 57, 211, 148, 223, 48, 115, 15, 2, 67, 186, 210, 28,
12,181,103, 70, 22, 58, 75, 78,183,167,238,157,124,147,172,144,
12, 181, 103, 70, 22, 58, 75, 78, 183, 167, 238, 157, 124, 147, 172,
144,
176, 161, 141, 86, 60, 66, 128, 83, 156, 241, 79, 46, 168, 198, 41, 254,
178, 85,253,237,250,154,133, 88, 35,206, 95,116,252,192, 54,221,
178, 85, 253, 237, 250, 154, 133, 88, 35, 206, 95, 116, 252, 192, 54,
221,
102, 218, 255, 240, 82, 106, 158, 201, 61, 3, 89, 9, 42, 155, 159, 93,
166, 80, 50, 34, 175, 195, 100, 99, 26, 150, 16, 145, 4, 33, 8, 189,
121, 64, 77, 72,208,245,130,122,143, 55,105,134, 29,164,185,194,
193,239,101,242, 5,171,126, 11, 74, 59,137,228,108,191,232,139,
121, 64, 77, 72, 208, 245, 130, 122, 143, 55, 105, 134, 29, 164, 185,
194,
193, 239, 101, 242, 5, 171, 126, 11, 74, 59, 137, 228, 108, 191, 232,
139,
6, 24, 81, 20, 127, 17, 91, 92, 251, 151, 225, 207, 21, 98, 113, 112,
84,226, 18,214,199,187, 13, 32, 94,220,224,212,247,204,196, 43,
249,236, 45,244,111,182,153,136,129, 90,217,202, 19,165,231, 71,
230,142, 96,227, 62,179,246,114,162, 53,160,215,205,180, 47,109,
84, 226, 18, 214, 199, 187, 13, 32, 94, 220, 224, 212, 247, 204, 196,
43,
249, 236, 45, 244, 111, 182, 153, 136, 129, 90, 217, 202, 19, 165, 231,
71,
230, 142, 96, 227, 62, 179, 246, 114, 162, 53, 160, 215, 205, 180, 47,
109,
44, 38, 31, 149, 135, 0, 216, 52, 63, 23, 37, 69, 39, 117, 146, 184,
163,200,222,235,248,243,219, 10,152,131,123,229,203, 76,120,209
163, 200, 222, 235, 248, 243, 219, 10, 152, 131, 123, 229, 203, 76, 120,
209
};
static struct hash_node *_create_node(const char *str)
@@ -223,4 +230,3 @@ struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n)
unsigned int h = _hash(n->key) & (t->num_slots - 1);
return n->next ? n->next : _next_slot(t, h + 1);
}

View File

@@ -46,7 +46,6 @@ static struct {
} _cache;
#define _alloc(x) pool_alloc(_cache.mem, (x))
#define _free(x) pool_free(_cache.mem, (x))
@@ -342,7 +341,6 @@ const char *dev_name_confirmed(struct device *dev)
return dev_name(dev);
}
struct device *dev_cache_get(const char *name, struct dev_filter *f)
{
struct stat buf;
@@ -399,4 +397,3 @@ struct device *dev_iter_get(struct dev_iter *iter)
return NULL;
}

View File

@@ -93,13 +93,14 @@ int dev_open(struct device *dev, int flags)
return 0;
}
dev->flags = 0;
return 1;
}
static void _flush(int fd)
{
if (ioctl(fd, BLKFLSBUF, 0))
log_error("couldn't flush device.");
ioctl(fd, BLKFLSBUF, 0);
}
int dev_close(struct device *dev)
@@ -110,6 +111,7 @@ int dev_close(struct device *dev)
return 0;
}
if (dev->flags & DEV_ACCESSED_W)
_flush(dev->fd);
if (close(dev->fd))
@@ -202,6 +204,8 @@ int64_t dev_write(struct device *dev, uint64_t offset,
return 0;
}
dev->flags |= DEV_ACCESSED_W;
return _write(fd, buffer, len);
}
@@ -238,6 +242,8 @@ int dev_zero(struct device *dev, uint64_t offset, int64_t len)
}
}
dev->flags |= DEV_ACCESSED_W;
/* FIXME: Always display error */
return (len == 0);
}

View File

@@ -38,8 +38,6 @@
#include <linux/major.h>
#include <linux/genhd.h>
#if 0
int _get_partition_type(struct dev_filter *filter, struct device *d);

View File

@@ -10,6 +10,8 @@
#include "lvm-types.h"
#include "list.h"
#define DEV_ACCESSED_W 0x00000001 /* Device written to? */
/*
* All devices in LVM will be represented by one of these.
* pointer comparisons are valid.
@@ -20,6 +22,7 @@ struct device {
/* private */
int fd;
uint32_t flags;
};
struct device_list {
@@ -44,7 +47,8 @@ int dev_zero(struct device *dev, uint64_t offset, int64_t len);
static inline const char *dev_name(struct device *dev) {
return list_item(dev->aliases.n, struct str_list)->str;
return (dev) ? list_item(dev->aliases.n, struct str_list)->str :
"unknown device";
}
/* Return a valid device name from the alias list; NULL otherwise */

View File

@@ -83,8 +83,8 @@ void pvdisplay_colons(struct physical_volume *pv)
/* FIXME pv->lv_cur, Remove? */
pv->pe_size / 2,
pv->pe_count,
pv->pe_count - pv->pe_allocated,
pv->pe_allocated, *uuid ? uuid : "none");
pv->pe_count - pv->pe_alloc_count,
pv->pe_alloc_count, *uuid ? uuid : "none");
return;
}
@@ -104,6 +104,18 @@ void pvdisplay_full(struct physical_volume *pv)
return;
}
/* Compat */
if(!pv->pe_size) {
size = display_size((uint64_t) pv->size / 2, SIZE_SHORT);
log_print("\"%s\" is a new physical volume of %s", dev_name(pv->dev), size);
dbg_free(size);
return;
}
set_cmd_name("");
init_msg_prefix("");
/****** FIXME Do we really need this conditional here? */
log_print("--- %sPhysical volume ---", pv->pe_size ? "" : "NEW ");
log_print("PV Name %s", dev_name(pv->dev));
log_print("VG Name %s%s", pv->vg_name,
@@ -114,12 +126,14 @@ void pvdisplay_full(struct physical_volume *pv)
size1 = display_size((pv->size - pv->pe_count * pv->pe_size)
/ 2, SIZE_SHORT);
/******** FIXME display LVM on-disk data size
/******** FIXME display LVM on-disk data size - static for now...
size2 = display_size(pv->size / 2, SIZE_SHORT);
********/
log_print("PV Size %s" " / not usable %s", /* [LVM: %s]", */
size, size1); /* , size2); */
log_print("PV Size %s [%llu secs]" " / not "
"usable %s [LVM: %s]",
size, (uint64_t) pv->size, size1, "151 KB");
/* , size2); */
dbg_free(size1);
/* dbg_free(size2); */
@@ -127,24 +141,27 @@ void pvdisplay_full(struct physical_volume *pv)
log_print("PV Size %s", size);
dbg_free(size);
/******** FIXME anytime this *isn't* available? */
log_print("PV Status available");
/*********FIXME Anything use this?
log_print("PV# %u", pv->pv_number);
**********/
pe_free = pv->pe_count - pv->pe_allocated;
pe_free = pv->pe_count - pv->pe_alloc_count;
if (pv->pe_count && (pv->status & ALLOCATABLE_PV))
log_print("Allocatable yes %s",
(!pe_free && pv->pe_count) ? "(but full)" : "");
else
log_print("Allocatable NO");
/*********FIXME
log_print("Cur LV %u", pv->lv_cur);
*********/
/*********FIXME Erm...where is this stored?
log_print("Cur LV %u", vg->lv_count);
*/
log_print("PE Size (KByte) %" PRIu64, pv->pe_size / 2);
log_print("Total PE %u", pv->pe_count);
log_print("Free PE %" PRIu64, pe_free);
log_print("Allocated PE %u", pv->pe_allocated);
log_print("Allocated PE %u", pv->pe_alloc_count);
#ifdef LVM_FUTURE
printf("Stale PE %u", pv->pe_stale);
@@ -156,7 +173,8 @@ void pvdisplay_full(struct physical_volume *pv)
return;
}
int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg, struct physical_volume *pv)
int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg,
struct physical_volume *pv)
{
if (!pv)
return 0;
@@ -166,12 +184,14 @@ int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg, struct phy
log_print("PV Status %sallocatable",
(pv->status & ALLOCATABLE_PV) ? "" : "NOT ");
log_print("Total PE / Free PE %u / %u",
pv->pe_count, pv->pe_count - pv->pe_allocated);
pv->pe_count, pv->pe_count - pv->pe_alloc_count);
log_print(" ");
return 0;
}
void lvdisplay_colons(struct logical_volume *lv)
{
int inkernel;
@@ -183,16 +203,13 @@ void lvdisplay_colons(struct logical_volume *lv)
lv->vg->name,
lv->name,
lv->vg->name,
(lv->status & (LVM_READ | LVM_WRITE)) >> 8,
inkernel ? 1 : 0,
(lv->status & (LVM_READ | LVM_WRITE)) >> 8, inkernel ? 1 : 0,
/* FIXME lv->lv_number, */
inkernel ? info.open_count : 0, lv->size, lv->le_count,
/* FIXME Add num allocated to struct! lv->lv_allocated_le, */
((lv->status & ALLOC_STRICT) +
(lv->status & ALLOC_CONTIGUOUS) * 2), lv->read_ahead,
inkernel ? info.major : -1,
inkernel ? info.minor : -1
);
inkernel ? info.major : -1, inkernel ? info.minor : -1);
return;
}
@@ -204,6 +221,11 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv)
int inkernel;
char uuid[64];
struct snapshot *snap;
struct stripe_segment *seg;
struct list *lvseg;
struct logical_volume *origin;
float snap_percent;
int snap_active;
if (!id_write_format(&lv->lvid.id[1], uuid, sizeof(uuid))) {
stack;
@@ -212,78 +234,68 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv)
inkernel = lv_info(lv, &info) && info.exists;
set_cmd_name("");
init_msg_prefix("");
log_print("--- Logical volume ---");
log_print("LV Name %s%s/%s", lv->vg->cmd->dev_dir,
lv->vg->name, lv->name);
log_print("VG Name %s", lv->vg->name);
/* Not in LVM1 format
log_print("LV UUID %s", uuid);
**/
log_print("LV Write Access %s",
(lv->status & LVM_WRITE) ? "read/write" : "read only");
if ((snap = find_cow(lv)))
log_print("Snapshot of %s", snap->origin->name);
/* see if this LV is an origin for a snapshot */
if ((snap = find_origin(lv))) {
struct list *slh, *snaplist = find_snapshots(lv);
/******* FIXME Snapshot
if (lv->status & (LVM_SNAPSHOT_ORG | LVM_SNAPSHOT)) {
if (lvm_tab_vg_read_with_pv_and_lv(vg_name, &vg) < 0) {
ret = -LVM_ELV_SHOW_VG_READ_WITH_PV_AND_LV;
goto lv_show_end;
log_print("LV snapshot status source of");
list_iterate(slh, snaplist) {
snap = list_item(slh, struct snapshot_list)->snapshot;
snap_active = lv_snapshot_percent(snap->cow,
&snap_percent);
log_print(" %s%s/%s [%s]",
lv->vg->cmd->dev_dir, lv->vg->name,
snap->cow->name,
(snap_active > 0) ? "active" : "INACTIVE");
}
printf("LV snapshot status ");
if (vg_check_active(vg_name) == TRUE) {
vg_t *vg_core;
if ((ret = vg_status_with_pv_and_lv(vg_name, &vg_core)) == 0) {
lv_t *lv_ptr =
vg_core->
lv[lv_get_index_by_name(vg_core, lv->lv_name)];
if (lv_ptr->lv_access & LV_SNAPSHOT) {
if (lv_ptr->lv_status & LV_ACTIVE)
printf("active ");
else
printf("INACTIVE ");
/* reset so we don't try to use this to display other snapshot
* related information. */
snap = NULL;
snap_active = 0;
}
if (lv_ptr->lv_access & LV_SNAPSHOT_ORG) {
printf("source of\n");
while (lv_ptr->lv_snapshot_next != NULL) {
lv_ptr = lv_ptr->lv_snapshot_next;
printf(" %s [%s]\n",
lv_ptr->lv_name,
(lv_ptr->
lv_status & LV_ACTIVE) ? "active" :
"INACTIVE");
/* Check to see if this LV is a COW target for a snapshot */
else if ((snap = find_cow(lv))) {
snap_active = lv_snapshot_percent(lv, &snap_percent);
log_print("LV snapshot status %s destination for %s%s/%s",
(snap_active > 0) ? "active" : "INACTIVE",
lv->vg->cmd->dev_dir, lv->vg->name,
snap->origin->name);
}
vg_free(vg_core, TRUE);
} else {
printf("destination for %s\n",
lv_ptr->lv_snapshot_org->lv_name);
}
}
} else {
printf("INACTIVE ");
if (lv->lv_access & LV_SNAPSHOT_ORG)
printf("original\n");
else
printf("snapshot\n");
}
}
***********/
if (inkernel && info.suspended)
log_print("LV Status suspended");
else
log_print("LV Status %savailable",
inkernel ? "" : "NOT ");
!inkernel || (snap && (snap_active < 1))
? "NOT " : "");
/********* FIXME lv_number
/********* FIXME lv_number - not sure that we're going to bother with this
log_print("LV # %u", lv->lv_number + 1);
************/
/* LVM1 lists the number of LVs open in this field, therefore, so do we. */
log_print("# open %u", lvs_in_vg_opened(lv->vg));
/* We're not going to use this count ATM, 'cause it's not what LVM1 does
if (inkernel)
log_print("# open %u", info.open_count);
*/
/********
#ifdef LVM_FUTURE
printf("Mirror copies %u\n", lv->lv_mirror_copies);
@@ -296,49 +308,57 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv)
#endif
********/
size = display_size(lv->size / 2, SIZE_SHORT);
if(snap)
origin = snap->origin;
else
origin = lv;
size = display_size(origin->size / 2, SIZE_SHORT);
log_print("LV Size %s", size);
dbg_free(size);
log_print("Current LE %u", lv->le_count);
log_print("Current LE %u", origin->le_count);
/********** FIXME allocation
log_print("Allocated LE %u", lv->allocated_le);
**********/
/********** FIXME allocation - is there anytime the allocated LEs will not
* equal the current LEs? */
log_print("Allocated LE %u", origin->le_count);
/**********/
/********** FIXME Snapshot
if (lv->lv_access & LV_SNAPSHOT) {
printf("snapshot chunk size %s\n",
(dummy = lvm_show_size(lv->lv_chunk_size / 2, SHORT)));
dbg_free(dummy);
dummy = NULL;
if (lv->lv_remap_end > 0) {
lv_remap_ptr = lv->lv_remap_ptr;
if (lv_remap_ptr > lv->lv_remap_end)
lv_remap_ptr = lv->lv_remap_end;
dummy = lvm_show_size(lv_remap_ptr *
lv->lv_chunk_size / 2, SHORT);
dummy1 = lvm_show_size(lv->lv_remap_end *
lv->lv_chunk_size / 2, SHORT);
printf("Allocated to snapshot %.2f%% [%s/%s]\n",
(float) lv_remap_ptr * 100 / lv->lv_remap_end,
dummy, dummy1);
dbg_free(dummy);
dbg_free(dummy1);
dummy =
lvm_show_size((vg->
lv[lv_get_index_by_number
(vg,
lv->lv_number)]->lv_size -
lv->lv_remap_end * lv->lv_chunk_size) / 2,
SHORT);
printf("Allocated to COW-table %s\n", dummy);
dbg_free(dummy);
list_iterate(lvseg, &lv->segments) {
seg = list_item(lvseg, struct stripe_segment);
if(seg->stripes > 1) {
log_print("Stripes %u", seg->stripes);
log_print("Stripe size (KByte) %u",
seg->stripe_size/2);
}
/* only want the first segment for LVM1 format output */
break;
}
******************/
if(snap) {
float fused, fsize;
if(snap_percent == -1)
snap_percent=100;
size = display_size(snap->chunk_size / 2, SIZE_SHORT);
log_print("snapshot chunk size %s", size);
dbg_free(size);
size = display_size(lv->size / 2, SIZE_SHORT);
sscanf(size, "%f", &fsize);
fused = fsize * ( snap_percent / 100 );
log_print("Allocated to snapshot %2.2f%% [%2.2f/%s]",
snap_percent, fused, size);
dbg_free(size);
/* FIXME: Think this'll make them wonder?? */
log_print("Allocated to COW-table %s", "00.01 KB");
}
/** Not in LVM1 format output **
log_print("Segments %u", list_size(&lv->segments));
***/
/********* FIXME Stripes & stripesize for each segment
log_print("Stripe size (KByte) %u", lv->stripesize / 2);
@@ -433,8 +453,6 @@ int lvdisplay_segments(struct logical_volume *lv)
return 1;
}
void vgdisplay_extents(struct volume_group *vg)
{
return;
@@ -445,10 +463,27 @@ void vgdisplay_full(struct volume_group *vg)
uint32_t access;
char *s1;
char uuid[64];
uint32_t active_pvs;
struct list *pvlist;
set_cmd_name("");
init_msg_prefix("");
/* get the number of active PVs */
if(vg->status & PARTIAL_VG) {
active_pvs=0;
list_iterate(pvlist, &(vg->pvs)) {
active_pvs++;
}
}
else
active_pvs=vg->pv_count;
log_print("--- Volume group ---");
log_print("VG Name %s", vg->name);
/****** Not in LVM1 output, so we aren't outputing it here:
log_print("System ID %s", vg->system_id);
*******/
access = vg->status & (LVM_READ | LVM_WRITE);
log_print("VG Access %s%s%s%s",
access == (LVM_READ | LVM_WRITE) ? "read/write" : "",
@@ -456,33 +491,28 @@ void vgdisplay_full(struct volume_group *vg)
access == LVM_WRITE ? "write" : "",
access == 0 ? "error" : "");
log_print("VG Status %s%sresizable",
vg->status & EXPORTED_VG ? "exported/" : "",
vg->status & EXPORTED_VG ? "exported/" : "available/",
vg->status & RESIZEABLE_VG ? "" : "NOT ");
/******* FIXME vg number
log_print ("VG # %u\n", vg->vg_number);
********/
if (vg->status & CLUSTERED) {
log_print("Clustered yes");
log_print("Shared %s",
vg->status & SHARED ? "yes" : "no");
}
/****** FIXME VG # - we aren't implementing this because people should
* use the UUID for this anyway
log_print("VG # %u", vg->vg_number);
*******/
log_print("MAX LV %u", vg->max_lv);
log_print("Cur LV %u", vg->lv_count);
/****** FIXME Open LVs
log_print ( "Open LV %u", vg->lv_open);
*******/
/****** FIXME Max LV Size
log_print ( "MAX LV Size %s",
( s1 = display_size ( LVM_LV_SIZE_MAX(vg) / 2, SIZE_SHORT)));
free ( s1);
*********/
log_print("Open LV %u", lvs_in_vg_opened(vg));
log_print("MAX LV Size 256 TB");
log_print("Max PV %u", vg->max_pv);
log_print("Cur PV %u", vg->pv_count);
/******* FIXME act PVs
log_print ( "Act PV %u", vg->pv_act);
*********/
log_print("Act PV %u", active_pvs);
s1 = display_size((uint64_t) vg->extent_count * (vg->extent_size / 2), SIZE_SHORT);
s1 =
display_size((uint64_t) vg->extent_count * (vg->extent_size / 2),
SIZE_SHORT);
log_print("VG Size %s", s1);
dbg_free(s1);
@@ -492,15 +522,16 @@ void vgdisplay_full(struct volume_group *vg)
log_print("Total PE %u", vg->extent_count);
s1 =
display_size(((uint64_t)
s1 = display_size(((uint64_t)
vg->extent_count - vg->free_count) *
(vg->extent_size / 2), SIZE_SHORT);
log_print("Alloc PE / Size %u / %s",
vg->extent_count - vg->free_count, s1);
dbg_free(s1);
s1 = display_size((uint64_t) vg->free_count * (vg->extent_size / 2), SIZE_SHORT);
s1 =
display_size((uint64_t) vg->free_count * (vg->extent_size / 2),
SIZE_SHORT);
log_print("Free PE / Size %u / %s", vg->free_count, s1);
dbg_free(s1);

View File

@@ -36,7 +36,6 @@ static void _destroy(struct dev_filter *f)
dbg_free(f);
}
struct dev_filter *composite_filter_create(int n, ...)
{
struct dev_filter **filters = dbg_malloc(sizeof(*filters) * (n + 1));

View File

@@ -128,8 +128,7 @@ static int _build_matcher(struct rfilter *rf, struct config_value *val)
* the matcher gives.
*/
for (v = val, i = count - 1; v; v = v->next, i--)
if (!_extract_pattern(scratch, v->v.str,
regex, rf->accept, i)) {
if (!_extract_pattern(scratch, v->v.str, regex, rf->accept, i)) {
log_info("invalid filter pattern");
goto out;
}
@@ -137,8 +136,8 @@ static int _build_matcher(struct rfilter *rf, struct config_value *val)
/*
* build the matcher.
*/
if (!(rf->engine = matcher_create(rf->mem,
(const char **) regex, count)))
if (!(rf->engine = matcher_create(rf->mem, (const char **) regex,
count)))
stack;
r = 1;
@@ -225,4 +224,3 @@ struct dev_filter *regex_filter_create(struct config_value *patterns)
pool_destroy(mem);
return NULL;
}

View File

@@ -124,7 +124,8 @@ static int *scan_proc_dev(const char *proc)
int *max_partitions_by_major;
if (!(max_partitions_by_major = dbg_malloc(sizeof (int) * NUMBER_OF_MAJORS))) {
if (!(max_partitions_by_major =
dbg_malloc(sizeof(int) * NUMBER_OF_MAJORS))) {
log_error("Filter failed to allocate max_partitions_by_major");
return NULL;
}

View File

@@ -21,7 +21,7 @@
#ifndef _LVM_FILTER_H
#define _LVM_FILTER_H
struct dev_filter *lvm_type_filter_create(const char *);
struct dev_filter *lvm_type_filter_create(const char *proc);
void lvm_type_filter_destroy(struct dev_filter *f);

View File

@@ -265,8 +265,7 @@ static void _munge_exported_vg(struct disk_list *data)
int l, s;
/* Return if PV not in a VG or VG not exported */
if ((!*data->pvd.vg_name) ||
!(data->vgd.vg_status & VG_EXPORTED))
if ((!*data->pvd.vg_name) || !(data->vgd.vg_status & VG_EXPORTED))
return;
l = strlen(data->pvd.vg_name);
@@ -277,23 +276,24 @@ static void _munge_exported_vg(struct disk_list *data)
data->pvd.pv_status |= VG_EXPORTED;
}
static struct disk_list *__read_disk(struct device *dev, struct pool *mem,
static struct disk_list *__read_disk(struct format_type *fmt,
struct device *dev, struct pool *mem,
const char *vg_name)
{
struct disk_list *data = pool_alloc(mem, sizeof(*data));
struct disk_list *dl = pool_alloc(mem, sizeof(*dl));
const char *name = dev_name(dev);
if (!data) {
if (!dl) {
stack;
return NULL;
}
data->dev = dev;
data->mem = mem;
list_init(&data->uuids);
list_init(&data->lvds);
dl->dev = dev;
dl->mem = mem;
list_init(&dl->uuids);
list_init(&dl->lvds);
if (!read_pvd(dev, &data->pvd)) {
if (!read_pvd(dev, &dl->pvd)) {
stack;
goto bad;
}
@@ -301,60 +301,60 @@ static struct disk_list *__read_disk(struct device *dev, struct pool *mem,
/*
* is it an orphan ?
*/
if (!*data->pvd.vg_name) {
log_very_verbose("%s is not a member of any VG", name);
if (!*dl->pvd.vg_name) {
log_very_verbose("%s is not a member of any format1 VG", name);
/* Update VG cache */
vgcache_add(data->pvd.vg_name, NULL, dev);
vgcache_add(dl->pvd.vg_name, NULL, dev, fmt);
return (vg_name) ? NULL : data;
return (vg_name) ? NULL : dl;
}
if (!_read_vgd(data)) {
if (!_read_vgd(dl)) {
log_error("Failed to read VG data from PV (%s)", name);
goto bad;
}
/* If VG is exported, set VG name back to the real name */
_munge_exported_vg(data);
_munge_exported_vg(dl);
/* Update VG cache with what we found */
vgcache_add(data->pvd.vg_name, data->vgd.vg_uuid, dev);
vgcache_add(dl->pvd.vg_name, dl->vgd.vg_uuid, dev, fmt);
if (vg_name && strcmp(vg_name, data->pvd.vg_name)) {
if (vg_name && strcmp(vg_name, dl->pvd.vg_name)) {
log_very_verbose("%s is not a member of the VG %s",
name, vg_name);
goto bad;
}
if (!_read_uuids(data)) {
if (!_read_uuids(dl)) {
log_error("Failed to read PV uuid list from %s", name);
goto bad;
}
if (!_read_lvs(data)) {
if (!_read_lvs(dl)) {
log_error("Failed to read LV's from %s", name);
goto bad;
}
if (!_read_extents(data)) {
if (!_read_extents(dl)) {
log_error("Failed to read extents from %s", name);
goto bad;
}
log_very_verbose("Found %s in %sVG %s", name,
(data->vgd.vg_status & VG_EXPORTED) ? "exported " : "",
data->pvd.vg_name);
(dl->vgd.vg_status & VG_EXPORTED) ? "exported " : "",
dl->pvd.vg_name);
return data;
return dl;
bad:
pool_free(data->mem, data);
pool_free(dl->mem, dl);
return NULL;
}
struct disk_list *read_disk(struct device *dev, struct pool *mem,
const char *vg_name)
struct disk_list *read_disk(struct format_type *fmt, struct device *dev,
struct pool *mem, const char *vg_name)
{
struct disk_list *r;
@@ -363,7 +363,7 @@ struct disk_list *read_disk(struct device *dev, struct pool *mem,
return NULL;
}
r = __read_disk(dev, mem, vg_name);
r = __read_disk(fmt, dev, mem, vg_name);
if (!dev_close(dev))
stack;
@@ -400,8 +400,9 @@ static void _add_pv_to_list(struct list *head, struct disk_list *data)
* We keep track of the first object allocated form the pool
* so we can free off all the memory if something goes wrong.
*/
int read_pvs_in_vg(const char *vg_name, struct dev_filter *filter,
struct pool *mem, struct list *head)
int read_pvs_in_vg(struct format_type *fmt, const char *vg_name,
struct dev_filter *filter, struct pool *mem,
struct list *head)
{
struct dev_iter *iter;
struct device *dev;
@@ -413,7 +414,7 @@ int read_pvs_in_vg(const char *vg_name, struct dev_filter *filter,
if ((pvdh = vgcache_find(vg_name))) {
list_iterate(pvdh2, pvdh) {
dev = list_item(pvdh2, struct pvdev_list)->dev;
if (!(data = read_disk(dev, mem, vg_name)))
if (!(data = read_disk(fmt, dev, mem, vg_name)))
break;
_add_pv_to_list(head, data);
}
@@ -421,8 +422,7 @@ int read_pvs_in_vg(const char *vg_name, struct dev_filter *filter,
/* Did we find the whole VG? */
if (!vg_name || !*vg_name ||
(data && *data->pvd.vg_name &&
list_size(head) == data->vgd.pv_cur))
return 1;
list_size(head) == data->vgd.pv_cur)) return 1;
/* Something changed. Remove the hints. */
list_init(head);
@@ -436,7 +436,7 @@ int read_pvs_in_vg(const char *vg_name, struct dev_filter *filter,
/* Otherwise do a complete scan */
for (dev = dev_iter_get(iter); dev; dev = dev_iter_get(iter)) {
if ((data = read_disk(dev, mem, vg_name))) {
if ((data = read_disk(fmt, dev, mem, vg_name))) {
_add_pv_to_list(head, data);
}
}
@@ -500,7 +500,7 @@ static int _write_lvd(struct device *dev, ulong pos, struct lv_disk *disk)
static int _write_lvs(struct disk_list *data)
{
struct list *lvh;
ulong pos;
ulong pos, offset;
pos = data->pvd.lv_on_disk.base;
@@ -513,10 +513,15 @@ static int _write_lvs(struct disk_list *data)
list_iterate(lvh, &data->lvds) {
struct lvd_list *ll = list_item(lvh, struct lvd_list);
if (!_write_lvd(data->dev, pos, &ll->lvd))
fail;
offset = sizeof(struct lv_disk) * ll->lvd.lv_number;
if (offset + sizeof(struct lv_disk) >
data->pvd.lv_on_disk.size) {
log_error("lv_number %d too large", ll->lvd.lv_number);
return 0;
}
pos += sizeof(struct lv_disk);
if (!_write_lvd(data->dev, pos + offset, &ll->lvd))
fail;
}
return 1;
@@ -573,7 +578,7 @@ static int _write_pvd(struct disk_list *data)
/*
* assumes the device has been opened.
*/
static int __write_all_pvd(struct disk_list *data)
static int __write_all_pvd(struct format_type *fmt, struct disk_list *data)
{
const char *pv_name = dev_name(data->dev);
@@ -582,18 +587,19 @@ static int __write_all_pvd(struct disk_list *data)
return 0;
}
vgcache_add(data->pvd.vg_name, data->vgd.vg_uuid, data->dev);
vgcache_add(data->pvd.vg_name, data->vgd.vg_uuid, data->dev, fmt);
/*
* Stop here for orphan pv's.
*/
if (data->pvd.vg_name[0] == '\0') {
if (!test_mode())
vgcache_add(data->pvd.vg_name, NULL, data->dev);
vgcache_add(data->pvd.vg_name, NULL, data->dev, fmt);
return 1;
}
if (!test_mode())
vgcache_add(data->pvd.vg_name, data->vgd.vg_uuid, data->dev);
vgcache_add(data->pvd.vg_name, data->vgd.vg_uuid, data->dev,
fmt);
if (!_write_vgd(data)) {
log_error("Failed to write VG data to %s", pv_name);
@@ -621,7 +627,7 @@ static int __write_all_pvd(struct disk_list *data)
/*
* opens the device and hands to the above fn.
*/
static int _write_all_pvd(struct disk_list *data)
static int _write_all_pvd(struct format_type *fmt, struct disk_list *data)
{
int r;
@@ -630,7 +636,7 @@ static int _write_all_pvd(struct disk_list *data)
return 0;
}
r = __write_all_pvd(data);
r = __write_all_pvd(fmt, data);
if (!dev_close(data->dev))
stack;
@@ -643,14 +649,14 @@ static int _write_all_pvd(struct disk_list *data)
* little sanity checking, so make sure correct
* data is passed to here.
*/
int write_disks(struct list *pvs)
int write_disks(struct format_type *fmt, struct list *pvs)
{
struct list *pvh;
struct disk_list *dl;
list_iterate(pvh, pvs) {
dl = list_item(pvh, struct disk_list);
if (!(_write_all_pvd(dl)))
if (!(_write_all_pvd(fmt, dl)))
fail;
log_very_verbose("Successfully wrote data to %s",

View File

@@ -168,7 +168,6 @@ struct disk_list {
* Layout constants.
*/
#define METADATA_ALIGN 4096UL
#define PE_ALIGN (65536UL / SECTOR_SIZE)
#define METADATA_BASE 0UL
#define PV_SIZE 1024UL
@@ -188,13 +187,14 @@ int calculate_extent_count(struct physical_volume *pv);
*/
int read_pvd(struct device *dev, struct pv_disk *pvd);
struct disk_list *read_disk(struct device *dev, struct pool *mem,
const char *vg_name);
struct disk_list *read_disk(struct format_type *fmt, struct device *dev,
struct pool *mem, const char *vg_name);
int read_pvs_in_vg(const char *vg_name, struct dev_filter *filter,
int read_pvs_in_vg(struct format_type *fmt, const char *vg_name,
struct dev_filter *filter,
struct pool *mem, struct list *results);
int write_disks(struct list *pvds);
int write_disks(struct format_type *fmt, struct list *pvds);
/*
@@ -223,7 +223,8 @@ int export_extents(struct disk_list *dl, int lv_num,
struct logical_volume *lv,
struct physical_volume *pv);
int import_pvs(struct pool *mem, struct volume_group *vg,
int import_pvs(struct format_instance *fid, struct pool *mem,
struct volume_group *vg,
struct list *pvds, struct list *results, int *count);
int import_lvs(struct pool *mem, struct volume_group *vg,
@@ -241,10 +242,10 @@ void export_numbers(struct list *pvds, struct volume_group *vg);
void export_pv_act(struct list *pvds);
/* blech */
int get_free_vg_number(struct dev_filter *filter, const char *candidate_vg,
int *result);
int export_vg_number(struct list *pvds, const char *vg_name,
struct dev_filter *filter);
int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,
const char *candidate_vg, int *result);
int export_vg_number(struct format_instance *fid, struct list *pvds,
const char *vg_name, struct dev_filter *filter);
#endif

View File

@@ -50,7 +50,6 @@ static int _check_vgs(struct list *pvs, int *partial)
}
}
/* Remove any PVs with VG structs that differ from the first */
list_iterate_safe(pvh, t, pvs) {
dl = list_item(pvh, struct disk_list);
@@ -83,10 +82,10 @@ static int _check_vgs(struct list *pvs, int *partial)
return 1;
}
static struct volume_group *_build_vg(struct cmd_context *cmd,
static struct volume_group *_build_vg(struct format_instance *fid,
struct list *pvs)
{
struct pool *mem = cmd->mem;
struct pool *mem = fid->fmt->cmd->mem;
struct volume_group *vg = pool_alloc(mem, sizeof(*vg));
struct disk_list *dl;
int partial;
@@ -99,7 +98,9 @@ static struct volume_group *_build_vg(struct cmd_context *cmd,
memset(vg, 0, sizeof(*vg));
vg->cmd = cmd;
vg->cmd = fid->fmt->cmd;
vg->fid = fid;
vg->seqno = 0;
list_init(&vg->pvs);
list_init(&vg->lvs);
list_init(&vg->snapshots);
@@ -112,7 +113,7 @@ static struct volume_group *_build_vg(struct cmd_context *cmd,
if (!import_vg(mem, vg, dl, partial))
goto bad;
if (!import_pvs(mem, vg, pvs, &vg->pvs, &vg->pv_count))
if (!import_pvs(fid, mem, vg, pvs, &vg->pvs, &vg->pv_count))
goto bad;
if (!import_lvs(mem, vg, pvs))
@@ -132,8 +133,8 @@ static struct volume_group *_build_vg(struct cmd_context *cmd,
return NULL;
}
static struct volume_group *_vg_read(struct format_instance *fi,
const char *vg_name)
static struct volume_group *_vg_read(struct format_instance *fid,
const char *vg_name, void *mda)
{
struct pool *mem = pool_create(1024 * 10);
struct list pvs;
@@ -146,14 +147,15 @@ static struct volume_group *_vg_read(struct format_instance *fi,
}
/* Strip dev_dir if present */
vg_name = strip_dir(vg_name, fi->cmd->dev_dir);
vg_name = strip_dir(vg_name, fid->fmt->cmd->dev_dir);
if (!read_pvs_in_vg(vg_name, fi->cmd->filter, mem, &pvs)) {
if (!read_pvs_in_vg
(fid->fmt, vg_name, fid->fmt->cmd->filter, mem, &pvs)) {
stack;
goto bad;
}
if (!(vg = _build_vg(fi->cmd, &pvs))) {
if (!(vg = _build_vg(fid, &pvs))) {
stack;
goto bad;
}
@@ -193,7 +195,8 @@ static struct disk_list *_flatten_pv(struct pool *mem, struct volume_group *vg,
return dl;
}
static int _flatten_vg(struct pool *mem, struct volume_group *vg,
static int _flatten_vg(struct format_instance *fid, struct pool *mem,
struct volume_group *vg,
struct list *pvds, const char *dev_dir,
struct dev_filter *filter)
{
@@ -215,7 +218,7 @@ static int _flatten_vg(struct pool *mem, struct volume_group *vg,
export_numbers(pvds, vg);
export_pv_act(pvds);
if (!export_vg_number(pvds, vg->name, filter)) {
if (!export_vg_number(fid, pvds, vg->name, filter)) {
stack;
return 0;
}
@@ -223,7 +226,8 @@ static int _flatten_vg(struct pool *mem, struct volume_group *vg,
return 1;
}
static int _vg_write(struct format_instance *fi, struct volume_group *vg)
static int _vg_write(struct format_instance *fid, struct volume_group *vg,
void *mdl)
{
struct pool *mem = pool_create(1024 * 10);
struct list pvds;
@@ -234,65 +238,58 @@ static int _vg_write(struct format_instance *fi, struct volume_group *vg)
return 0;
}
if (vg->status & PARTIAL_VG) {
log_error("Cannot change metadata for partial volume group %s",
vg->name);
return 0;
}
list_init(&pvds);
r = (_flatten_vg(mem, vg, &pvds, fi->cmd->dev_dir, fi->cmd->filter) &&
write_disks(&pvds));
r = (_flatten_vg(fid, mem, vg, &pvds, fid->fmt->cmd->dev_dir,
fid->fmt->cmd->filter) &&
write_disks(fid->fmt, &pvds));
pool_destroy(mem);
return r;
}
static struct physical_volume *_pv_read(struct format_instance *fi,
const char *name)
int _pv_read(struct format_type *fmt, const char *name,
struct physical_volume *pv)
{
struct pool *mem = pool_create(1024);
struct physical_volume *pv = NULL;
struct disk_list *dl;
struct device *dev;
int r = 0;
log_very_verbose("Reading physical volume data %s from disk", name);
if (!mem) {
stack;
return NULL;
return 0;
}
if (!(dev = dev_cache_get(name, fi->cmd->filter))) {
if (!(dev = dev_cache_get(name, fmt->cmd->filter))) {
stack;
goto out;
}
if (!(dl = read_disk(dev, mem, NULL))) {
if (!(dl = read_disk(fmt, dev, mem, NULL))) {
stack;
goto out;
}
if (!(pv = pool_alloc(fi->cmd->mem, sizeof(*pv)))) {
if (!import_pv(fmt->cmd->mem, dl->dev, NULL, pv, &dl->pvd)) {
stack;
goto out;
}
if (!import_pv(fi->cmd->mem, dl->dev, NULL, pv, &dl->pvd)) {
stack;
pool_free(fi->cmd->mem, pv);
pv = NULL;
}
pv->fid = fmt->ops->create_instance(fmt, NULL, NULL);
r = 1;
out:
pool_destroy(mem);
return pv;
return r;
}
static struct list *_get_pvs(struct format_instance *fi)
static struct list *_get_pvs(struct format_type *fmt, struct list *results)
{
struct pool *mem = pool_create(1024 * 10);
struct list pvs, *results;
struct list pvs;
uint32_t count;
if (!mem) {
@@ -300,21 +297,14 @@ static struct list *_get_pvs(struct format_instance *fi)
return NULL;
}
if (!(results = pool_alloc(fi->cmd->mem, sizeof(*results)))) {
stack;
pool_destroy(mem);
return NULL;
}
list_init(&pvs);
list_init(results);
if (!read_pvs_in_vg(NULL, fi->cmd->filter, mem, &pvs)) {
if (!read_pvs_in_vg(fmt, NULL, fmt->cmd->filter, mem, &pvs)) {
stack;
goto bad;
}
if (!import_pvs(fi->cmd->mem, NULL, &pvs, results, &count)) {
if (!import_pvs(NULL, fmt->cmd->mem, NULL, &pvs, results, &count)) {
stack;
goto bad;
}
@@ -323,7 +313,6 @@ static struct list *_get_pvs(struct format_instance *fi)
return results;
bad:
pool_free(fi->cmd->mem, results);
pool_destroy(mem);
return NULL;
}
@@ -342,22 +331,22 @@ static int _find_vg_name(struct list *names, const char *vg)
return 0;
}
static struct list *_get_vgs(struct format_instance *fi)
static struct list *_get_vgs(struct format_type *fmt, struct list *names)
{
struct list *pvh;
struct list *pvs, *names = pool_alloc(fi->cmd->mem, sizeof(*names));
struct list *pvs;
struct name_list *nl;
if (!names) {
stack;
return NULL;
if (!(pvs = pool_alloc(fmt->cmd->mem, sizeof(*pvs)))) {
log_error("PV list allocation failed");
goto err;
}
list_init(names);
list_init(pvs);
if (!(pvs = _get_pvs(fi))) {
if (!_get_pvs(fmt, pvs)) {
stack;
goto bad;
goto err;
}
list_iterate(pvh, pvs) {
@@ -367,31 +356,30 @@ static struct list *_get_vgs(struct format_instance *fi)
_find_vg_name(names, pvl->pv->vg_name))
continue;
if (!(nl = pool_alloc(fi->cmd->mem, sizeof(*nl)))) {
if (!(nl = pool_alloc(fmt->cmd->mem, sizeof(*nl)))) {
stack;
goto bad;
goto err;
}
if (!(nl->name = pool_strdup(fi->cmd->mem,
pvl->pv->vg_name))) {
if (!(nl->name = pool_strdup(fmt->cmd->mem, pvl->pv->vg_name))) {
stack;
goto bad;
goto err;
}
list_add(names, &nl->list);
}
if (list_empty(names))
goto bad;
pool_free(fmt->cmd->mem, pvs);
return names;
bad:
pool_free(fi->cmd->mem, names);
err:
pool_free(fmt->cmd->mem, pvs);
return NULL;
}
static int _pv_setup(struct format_instance *fi, struct physical_volume *pv,
static int _pv_setup(struct format_instance *fid, struct physical_volume *pv,
struct volume_group *vg)
{
/* setup operations for the PV structure */
@@ -438,11 +426,7 @@ static int _find_free_lvnum(struct logical_volume *lv)
return i;
}
/*
* Validate/populate LV structure for format1.
* Supplied LV structure can be for a new LV or for an already-existing one.
*/
static int _lv_setup(struct format_instance *fi, struct logical_volume *lv)
static int _lv_setup(struct format_instance *fid, struct logical_volume *lv)
{
uint64_t max_size = UINT_MAX;
@@ -464,7 +448,8 @@ static int _lv_setup(struct format_instance *fi, struct logical_volume *lv)
return 1;
}
static int _pv_write(struct format_instance *fi, struct physical_volume *pv)
static int _pv_write(struct format_instance *fid, struct physical_volume *pv,
void *mdl)
{
struct pool *mem;
struct disk_list *dl;
@@ -472,14 +457,15 @@ static int _pv_write(struct format_instance *fi, struct physical_volume *pv)
list_init(&pvs);
if (*pv->vg_name || pv->pe_allocated ) {
if (*pv->vg_name || pv->pe_alloc_count) {
log_error("Assertion failed: can't _pv_write non-orphan PV "
"(in VG %s)", pv->vg_name);
return 0;
}
/* Ensure any residual PE structure is gone */
pv->pe_size = pv->pe_count = pv->pe_start = 0;
pv->pe_size = pv->pe_count = 0;
pv->pe_start = PE_ALIGN;
if (!(mem = pool_create(1024))) {
stack;
@@ -502,9 +488,10 @@ static int _pv_write(struct format_instance *fi, struct physical_volume *pv)
dev_write in order to make other disk tools happy */
dl->pvd.pv_on_disk.base = METADATA_BASE;
dl->pvd.pv_on_disk.size = PV_SIZE;
dl->pvd.pe_on_disk.base = PE_ALIGN * SECTOR_SIZE;
list_add(&pvs, &dl->list);
if (!write_disks(&pvs)) {
if (!write_disks(fid->fmt, &pvs)) {
stack;
goto bad;
}
@@ -517,7 +504,7 @@ static int _pv_write(struct format_instance *fi, struct physical_volume *pv)
return 0;
}
int _vg_setup(struct format_instance *fi, struct volume_group *vg)
int _vg_setup(struct format_instance *fid, struct volume_group *vg)
{
/* just check max_pv and max_lv */
if (vg->max_lv >= MAX_LV)
@@ -555,11 +542,42 @@ int _vg_setup(struct format_instance *fi, struct volume_group *vg)
return 1;
}
void _destroy(struct format_instance *fi)
struct format_instance *_create_instance(struct format_type *fmt,
const char *vgname, void *private)
{
dbg_free(fi);
struct format_instance *fid;
struct metadata_area *mda;
if (!(fid = pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
stack;
return NULL;
}
fid->fmt = fmt;
list_init(&fid->metadata_areas);
/* Define a NULL metadata area */
if (!(mda = pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
stack;
pool_free(fmt->cmd->mem, fid);
return NULL;
}
mda->metadata_locn = NULL;
list_add(&fid->metadata_areas, &mda->list);
return fid;
}
void _destroy_instance(struct format_instance *fid)
{
return;
}
void _destroy(struct format_type *fmt)
{
dbg_free(fmt);
}
static struct format_handler _format1_ops = {
get_vgs: _get_vgs,
@@ -571,21 +589,25 @@ static struct format_handler _format1_ops = {
vg_read: _vg_read,
vg_setup: _vg_setup,
vg_write: _vg_write,
create_instance:_create_instance,
destroy_instance:_destroy_instance,
destroy: _destroy,
};
struct format_instance *create_lvm1_format(struct cmd_context *cmd)
struct format_type *create_lvm1_format(struct cmd_context *cmd)
{
struct format_instance *fi = dbg_malloc(sizeof(*fi));
struct format_type *fmt = dbg_malloc(sizeof(*fmt));
if (!fi) {
if (!fmt) {
stack;
return NULL;
}
fi->cmd = cmd;
fi->ops = &_format1_ops;
fi->private = NULL;
fmt->cmd = cmd;
fmt->ops = &_format1_ops;
fmt->name = FMT_LVM1_NAME;
fmt->features = 0;
fmt->private = NULL;
return fi;
return fmt;
}

View File

@@ -9,6 +9,6 @@
#include "metadata.h"
struct format_instance *create_lvm1_format(struct cmd_context *cmd);
struct format_type *create_lvm1_format(struct cmd_context *cmd);
#endif

View File

@@ -75,7 +75,7 @@ int import_pv(struct pool *mem, struct device *dev,
pv->pe_size = pvd->pe_size;
pv->pe_start = pvd->pe_start;
pv->pe_count = pvd->pe_total;
pv->pe_allocated = pvd->pe_allocated;
pv->pe_alloc_count = pvd->pe_allocated;
return 1;
}
@@ -174,15 +174,14 @@ int export_pv(struct pool *mem, struct volume_group *vg,
pvd->lv_cur = 0; /* this is set when exporting the lv list */
pvd->pe_size = pv->pe_size;
pvd->pe_total = pv->pe_count;
pvd->pe_allocated = pv->pe_allocated;
pvd->pe_allocated = pv->pe_alloc_count;
pvd->pe_start = pv->pe_start;
return 1;
}
int import_vg(struct pool *mem,
struct volume_group *vg, struct disk_list *dl,
int partial)
struct volume_group *vg, struct disk_list *dl, int partial)
{
struct vg_disk *vgd = &dl->vgd;
memcpy(vg->id.uuid, vgd->vg_uuid, ID_LEN);
@@ -359,8 +358,7 @@ void export_lv(struct lv_disk *lvd, struct volume_group *vg,
}
int export_extents(struct disk_list *dl, int lv_num,
struct logical_volume *lv,
struct physical_volume *pv)
struct logical_volume *lv, struct physical_volume *pv)
{
struct list *segh;
struct pe_disk *ped;
@@ -386,7 +384,8 @@ int export_extents(struct disk_list *dl, int lv_num,
return 1;
}
int import_pvs(struct pool *mem, struct volume_group *vg,
int import_pvs(struct format_instance *fid, struct pool *mem,
struct volume_group *vg,
struct list *pvds, struct list *results, int *count)
{
struct list *pvdh;
@@ -409,6 +408,7 @@ int import_pvs(struct pool *mem, struct volume_group *vg,
return 0;
}
pvl->pv->fid = fid;
list_add(results, &pvl->list);
(*count)++;
}
@@ -442,8 +442,7 @@ static struct logical_volume *_add_lv(struct pool *mem,
return lv;
}
int import_lvs(struct pool *mem, struct volume_group *vg,
struct list *pvds)
int import_lvs(struct pool *mem, struct volume_group *vg, struct list *pvds)
{
struct disk_list *dl;
struct lvd_list *ll;
@@ -617,8 +616,7 @@ int import_snapshots(struct pool *mem, struct volume_group *vg,
continue;
/* insert the snapshot */
if (!vg_add_snapshot(org, cow, 1,
lvd->lv_chunk_size)) {
if (!vg_add_snapshot(org, cow, 1, lvd->lv_chunk_size)) {
log_err("Couldn't add snapshot.");
return 0;
}
@@ -628,8 +626,6 @@ int import_snapshots(struct pool *mem, struct volume_group *vg,
return 1;
}
int export_uuids(struct disk_list *dl, struct volume_group *vg)
{
struct uuid_list *ul;
@@ -688,14 +684,14 @@ void export_pv_act(struct list *pvds)
}
}
int export_vg_number(struct list *pvds, const char *vg_name,
struct dev_filter *filter)
int export_vg_number(struct format_instance *fid, struct list *pvds,
const char *vg_name, struct dev_filter *filter)
{
struct list *pvdh;
struct disk_list *dl;
int vg_num;
if (!get_free_vg_number(filter, vg_name, &vg_num)) {
if (!get_free_vg_number(fid, filter, vg_name, &vg_num)) {
stack;
return 0;
}
@@ -707,4 +703,3 @@ int export_vg_number(struct list *pvds, const char *vg_name,
return 1;
}

View File

@@ -266,8 +266,7 @@ static int _read_stripes(struct pool *mem, struct lv_map *lvm)
if (lvm->lv->le_count % lvm->stripes) {
log_error("Number of stripes (%u) incompatible "
"with logical extent count (%u) for %s",
lvm->stripes, lvm->lv->le_count,
lvm->lv->name);
lvm->stripes, lvm->lv->le_count, lvm->lv->name);
}
len = lvm->lv->le_count / lvm->stripes;

View File

@@ -8,7 +8,6 @@
#include "log.h"
#include "dbg_malloc.h"
/*
* Only works with powers of 2.
*/
@@ -103,7 +102,6 @@ int calculate_layout(struct disk_list *dl)
return 1;
}
/*
* It may seem strange to have a struct physical_volume in here,
* but the number of extents that can fit on a disk *is* metadata
@@ -133,11 +131,10 @@ int calculate_extent_count(struct physical_volume *pv)
return 0;
}
do {
pvd->pe_total--;
_calc_simple_layout(pvd);
end = ((pvd->pe_on_disk.base + pvd->pe_on_disk.size + \
end = ((pvd->pe_on_disk.base + pvd->pe_on_disk.size +
SECTOR_SIZE - 1) / SECTOR_SIZE);
pvd->pe_start = _round_up(end, PE_ALIGN);

View File

@@ -38,8 +38,7 @@ static int _can_handle(struct labeller *l, struct device *dev)
return r;
}
static int _write(struct labeller *l,
struct device *dev, struct label *label)
static int _write(struct labeller *l, struct device *dev, struct label *label)
{
_not_supported("write");
return 0;
@@ -118,7 +117,6 @@ static void _destroy(struct labeller *l)
dbg_free(l);
}
struct label_ops _lvm1_ops = {
can_handle: _can_handle,
write: _write,

View File

@@ -15,8 +15,8 @@
* Put in separate file so it wouldn't contaminate
* other code.
*/
int get_free_vg_number(struct dev_filter *filter, const char *candidate_vg,
int *result)
int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,
const char *candidate_vg, int *result)
{
struct list *pvh;
struct list all_pvs;
@@ -31,7 +31,7 @@ int get_free_vg_number(struct dev_filter *filter, const char *candidate_vg,
return 0;
}
if (!read_pvs_in_vg(NULL, filter, mem, &all_pvs)) {
if (!read_pvs_in_vg(fid->fmt, NULL, filter, mem, &all_pvs)) {
stack;
goto out;
}
@@ -40,8 +40,7 @@ int get_free_vg_number(struct dev_filter *filter, const char *candidate_vg,
list_iterate(pvh, &all_pvs) {
dl = list_item(pvh, struct disk_list);
if (!*dl->pvd.vg_name ||
!strcmp(dl->pvd.vg_name, candidate_vg))
if (!*dl->pvd.vg_name || !strcmp(dl->pvd.vg_name, candidate_vg))
continue;
numbers[dl->vgd.vg_number] = 1;

View File

@@ -23,6 +23,7 @@
#include <fcntl.h>
#include <time.h>
#define SECS_PER_DAY 86400 /* 24*60*60 */
/*
* The format instance is given a directory path upon creation.
@@ -36,7 +37,6 @@
* Backup files that have expired will be removed.
*/
/*
* A list of these is built up for our volume group. Ordered
* with the least recent at the head.
@@ -48,7 +48,6 @@ struct archive_file {
int index;
};
/*
* Extract vg name and version number from a filename.
*/
@@ -138,6 +137,7 @@ static struct list *_scan_archive(struct pool *mem,
list_init(results);
/* Sort fails beyond 5-digit indexes */
if ((count = scandir(dir, &dirent, NULL, alphasort)) < 0) {
log_err("Couldn't scan archive directory.");
return 0;
@@ -149,8 +149,8 @@ static struct list *_scan_archive(struct pool *mem,
continue;
/* check the name is the correct format */
if (!_split_vg(dirent[i]->d_name, vg_name,
sizeof(vg_name), &index))
if (!_split_vg(dirent[i]->d_name, vg_name, sizeof(vg_name),
&index))
continue;
/* is it the vg we're interested in ? */
@@ -188,11 +188,50 @@ static struct list *_scan_archive(struct pool *mem,
return results;
}
static void _remove_expired(struct list *archives, uint32_t archives_size,
uint32_t retain_days, uint32_t min_archive)
{
struct list *bh;
struct archive_file *bf;
struct stat sb;
time_t retain_time;
/* Make sure there are enough archives to even bother looking for
* expired ones... */
if (archives_size <= min_archive)
return;
/* Convert retain_days into the time after which we must retain */
retain_time = time(NULL) - (time_t) retain_days * SECS_PER_DAY;
/* Assume list is ordered oldest first (by index) */
list_iterate(bh, archives) {
bf = list_item(bh, struct archive_file);
/* Get the mtime of the file and unlink if too old */
if (stat(bf->path, &sb)) {
log_sys_error("stat", bf->path);
continue;
}
if (sb.st_mtime > retain_time)
return;
log_very_verbose("Expiring archive %s", bf->path);
if (unlink(bf->path))
log_sys_error("unlink", bf->path);
/* Don't delete any more if we've reached the minimum */
if (--archives_size <= min_archive)
return;
}
}
int archive_vg(struct volume_group *vg,
const char *dir, const char *desc,
uint32_t retain_days, uint32_t min_archive)
{
int i, fd;
int i, fd, renamed = 0;
unsigned int index = 0;
struct archive_file *last;
FILE *fp = NULL;
@@ -231,7 +270,6 @@ int archive_vg(struct volume_group *vg,
if (list_empty(archives))
index = 0;
else {
last = list_item(archives->p, struct archive_file);
index = last->index + 1;
@@ -239,36 +277,51 @@ int archive_vg(struct volume_group *vg,
for (i = 0; i < 10; i++) {
if (lvm_snprintf(archive_name, sizeof(archive_name),
"%s/%s_%05d.vg",
dir, vg->name, index) < 0) {
log_err("archive file name too long.");
"%s/%s_%05d.vg", dir, vg->name, index) < 0) {
log_error("Archive file name too long.");
return 0;
}
if (lvm_rename(temp_file, archive_name))
if ((renamed = lvm_rename(temp_file, archive_name)))
break;
index++;
}
if (!renamed)
log_error("Archive rename failed for %s", temp_file);
_remove_expired(archives, list_size(archives) + renamed, retain_days,
min_archive);
return 1;
}
static void _display_archive(struct cmd_context *cmd, struct uuid_map *um,
struct archive_file *af)
{
struct volume_group *vg;
struct volume_group *vg = NULL;
struct format_instance *tf;
time_t when;
char *desc;
void *context;
log_print("path:\t\t%s", af->path);
if (!(context = create_text_context(cmd->fmtt, af->path, NULL)) ||
!(tf = cmd->fmtt->ops->create_instance(cmd->fmtt, NULL, context))) {
log_error("Couldn't create text instance object.");
return;
}
/*
* Read the archive file to ensure that it is valid, and
* retrieve the archive time and description.
*/
if (!(vg = text_vg_import(cmd, af->path, um, &when, &desc))) {
/* FIXME Use variation on _vg_read */
if (!(vg = text_vg_import(tf, af->path, um, &when, &desc))) {
log_print("Unable to read archive file.");
tf->fmt->ops->destroy_instance(tf);
return;
}
@@ -276,6 +329,7 @@ static void _display_archive(struct cmd_context *cmd, struct uuid_map *um,
log_print("time:\t\t%s", ctime(&when));
pool_free(cmd->mem, vg);
tf->fmt->ops->destroy_instance(tf);
}
int archive_list(struct cmd_context *cmd, struct uuid_map *um,

View File

@@ -16,7 +16,6 @@
#include <stdarg.h>
#include <time.h>
/*
* The first half of this file deals with
* exporting the vg, ie. writing it to a file.
@@ -34,8 +33,7 @@ struct formatter {
/*
* Formatting functions.
*/
static void _out_size(struct formatter *f, uint64_t size,
const char *fmt, ...)
static void _out_size(struct formatter *f, uint64_t size, const char *fmt, ...)
__attribute__ ((format(printf, 3, 4)));
static void _out_hint(struct formatter *f, const char *fmt, ...)
@@ -44,7 +42,6 @@ static void _out_hint(struct formatter *f, const char *fmt, ...)
static void _out(struct formatter *f, const char *fmt, ...)
__attribute__ ((format(printf, 2, 3)));
#define MAX_INDENT 5
static void _inc_indent(struct formatter *f)
{
@@ -134,8 +131,7 @@ static int _sectors_to_units(uint64_t sectors, char *buffer, size_t s)
* Appends a comment giving a size in more easily
* readable form (eg, 4M instead of 8096).
*/
static void _out_size(struct formatter *f, uint64_t size,
const char *fmt, ...)
static void _out_size(struct formatter *f, uint64_t size, const char *fmt, ...)
{
char buffer[64];
va_list ap;
@@ -200,6 +196,7 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
_out(f, "id = \"%s\"", buffer);
_out(f, "seqno = %u", vg->seqno);
if (!print_flags(vg->status, VG_FLAGS, buffer, sizeof(buffer))) {
stack;
return 0;
@@ -219,12 +216,11 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
* Get the pv%d name from the formatters hash
* table.
*/
static inline const char *
_get_pv_name(struct formatter *f, struct physical_volume *pv)
static inline const char *_get_pv_name(struct formatter *f,
struct physical_volume *pv)
{
return (pv) ? (const char *)
hash_lookup(f->pv_names, dev_name(pv->dev)) :
"Missing";
hash_lookup(f->pv_names, dev_name(pv->dev)) : "Missing";
}
static int _print_pvs(struct formatter *f, struct volume_group *vg)
@@ -259,8 +255,7 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
_out_hint(f, "device = \"%s\"", dev_name(pv->dev));
_nl(f);
if (!print_flags(pv->status, PV_FLAGS,
buffer, sizeof(buffer))) {
if (!print_flags(pv->status, PV_FLAGS, buffer, sizeof(buffer))) {
stack;
return 0;
}
@@ -362,8 +357,7 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg)
_out(f, "id = \"%s\"", buffer);
if (!print_flags(lv->status, LV_FLAGS,
buffer, sizeof(buffer))) {
if (!print_flags(lv->status, LV_FLAGS, buffer, sizeof(buffer))) {
stack;
return 0;
}
@@ -448,8 +442,7 @@ static int _print_snapshots(struct formatter *f, struct volume_group *vg)
* 'pv2' etc. This function builds a hash table
* to enable a quick lookup from device -> name.
*/
static int _build_pv_names(struct formatter *f,
struct volume_group *vg)
static int _build_pv_names(struct formatter *f, struct volume_group *vg)
{
int count = 0;
struct list *pvh;
@@ -469,8 +462,7 @@ static int _build_pv_names(struct formatter *f,
list_iterate(pvh, &vg->pvs) {
pv = list_item(pvh, struct pv_list)->pv;
if (lvm_snprintf(buffer, sizeof(buffer),
"pv%d", count++) < 0) {
if (lvm_snprintf(buffer, sizeof(buffer), "pv%d", count++) < 0) {
stack;
goto bad;
}
@@ -516,7 +508,6 @@ int text_vg_export(FILE *fp, struct volume_group *vg, const char *desc)
stack;
goto out;
}
#define fail do {stack; goto out;} while(0)
if (!_print_header(f, vg, desc))

View File

@@ -15,11 +15,14 @@
#include "display.h"
#include "dbg_malloc.h"
#include "toolcontext.h"
#include "vgcache.h"
#include "lvm-string.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/file.h>
#include <limits.h>
#include <dirent.h>
/* Arbitrary limits copied from format1/disk_rep.h */
#define MAX_PV 256
@@ -27,16 +30,21 @@
#define MAX_VG 99
#define MAX_PV_SIZE ((uint32_t) -1) /* 2TB in sectors - 1 */
struct dir_list {
struct list list;
char dir[0];
};
struct text_context {
char *path_live; /* Path to file holding live metadata */
char *path_edit; /* Path to file holding edited metadata */
char *desc; /* Description placed inside file */
};
/*
* NOTE: Currently there can be only one vg per file.
*/
struct text_c {
char *path;
char *desc;
struct uuid_map *um;
};
static int _pv_setup(struct format_instance *fi, struct physical_volume *pv,
struct volume_group *vg)
{
@@ -61,6 +69,11 @@ static int _vg_setup(struct format_instance *fi, struct volume_group *vg)
if (vg->max_pv >= MAX_PV)
vg->max_pv = MAX_PV - 1;
if (vg->extent_size & (vg->extent_size - 1)) {
log_error("Extent size must be power of 2");
return 0;
}
return 1;
}
@@ -68,6 +81,9 @@ static int _lv_setup(struct format_instance *fi, struct logical_volume *lv)
{
uint64_t max_size = UINT_MAX;
if (!*lv->lvid.s)
lvid_create(&lv->lvid, &lv->vg->id);
if (lv->size > max_size) {
char *dummy = display_size(max_size, SIZE_SHORT);
log_error("logical volumes cannot be larger than %s", dummy);
@@ -79,14 +95,15 @@ static int _lv_setup(struct format_instance *fi, struct logical_volume *lv)
}
static struct volume_group *_vg_read(struct format_instance *fi,
const char *vg_name)
const char *vgname, void *mdl)
{
struct text_c *tc = (struct text_c *) fi->private;
struct text_context *tc = (struct text_context *) mdl;
struct volume_group *vg;
time_t when;
char *desc;
if (!(vg = text_vg_import(fi->cmd, tc->path, tc->um, &when, &desc))) {
if (!(vg = text_vg_import(fi, tc->path_live, fi->fmt->cmd->um, &when,
&desc))) {
stack;
return NULL;
}
@@ -96,32 +113,33 @@ static struct volume_group *_vg_read(struct format_instance *fi,
* text file (this restriction may remain). We need to
* check that it contains the correct volume group.
*/
if (strcmp(vg_name, vg->name)) {
pool_free(fi->cmd->mem, vg);
if (strcmp(vgname, vg->name)) {
pool_free(fi->fmt->cmd->mem, vg);
log_err("'%s' does not contain volume group '%s'.",
tc->path, vg_name);
tc->path_live, vgname);
return NULL;
}
return vg;
}
static int _vg_write(struct format_instance *fi, struct volume_group *vg)
static int _vg_write(struct format_instance *fi, struct volume_group *vg,
void *mdl)
{
struct text_c *tc = (struct text_c *) fi->private;
struct text_context *tc = (struct text_context *) mdl;
FILE *fp;
int fd;
char *slash;
char temp_file[PATH_MAX], temp_dir[PATH_MAX];
slash = rindex(tc->path, '/');
slash = rindex(tc->path_edit, '/');
if (slash == 0)
strcpy(temp_dir, ".");
else if (slash - tc->path < PATH_MAX) {
strncpy(temp_dir, tc->path, slash - tc->path);
temp_dir[slash - tc->path] = '\0';
else if (slash - tc->path_edit < PATH_MAX) {
strncpy(temp_dir, tc->path_edit, slash - tc->path_edit);
temp_dir[slash - tc->path_edit] = '\0';
} else {
log_error("Text format failed to determine directory.");
@@ -145,113 +163,196 @@ static int _vg_write(struct format_instance *fi, struct volume_group *vg)
return 0;
}
if (fclose(fp)) {
log_sys_error("fclose", tc->path);
if (fsync(fd)) {
log_sys_error("fsync", tc->path_edit);
fclose(fp);
return 0;
}
if (rename(temp_file, tc->path)) {
log_error("%s: rename to %s failed: %s", temp_file, tc->path,
strerror(errno));
if (fclose(fp)) {
log_sys_error("fclose", tc->path_edit);
return 0;
}
if (rename(temp_file, tc->path_edit)) {
log_error("%s: rename to %s failed: %s", temp_file,
tc->path_edit, strerror(errno));
return 0;
}
return 1;
}
static struct list *_get_vgs(struct format_instance *fi)
static int _pv_commit(struct format_instance *fi, struct physical_volume *pv,
void *mdl)
{
struct text_c *tc = (struct text_c *) fi->private;
struct list *names = pool_alloc(fi->cmd->mem, sizeof(*names));
// struct text_context *tc = (struct text_context *) mdl;
return 1;
}
static int _vg_commit(struct format_instance *fi, struct volume_group *vg,
void *mdl)
{
struct text_context *tc = (struct text_context *) mdl;
if (rename(tc->path_edit, tc->path_live)) {
log_error("%s: rename to %s failed: %s", tc->path_edit,
tc->path_edit, strerror(errno));
return 0;
}
sync();
return 1;
}
static int _vg_remove(struct format_instance *fi, struct volume_group *vg,
void *mdl)
{
struct text_context *tc = (struct text_context *) mdl;
if (path_exists(tc->path_edit) && unlink(tc->path_edit)) {
log_sys_error("unlink", tc->path_edit);
return 0;
}
if (path_exists(tc->path_live) && unlink(tc->path_live)) {
log_sys_error("unlink", tc->path_live);
return 0;
}
sync();
return 1;
}
/* Add vgname to list if it's not already there */
static int _add_vgname(struct format_type *fmt, struct list *names,
char *vgname)
{
struct list *nlh;
struct name_list *nl;
struct volume_group *vg;
char *slash;
char *vgname;
if (!names) {
list_iterate(nlh, names) {
nl = list_item(nlh, struct name_list);
if (!strcmp(vgname, nl->name))
return 1;
}
vgcache_add(vgname, NULL, NULL, fmt);
if (!(nl = pool_alloc(fmt->cmd->mem, sizeof(*nl)))) {
stack;
return NULL;
return 0;
}
list_init(names);
/* Determine the VG name from the file name */
slash = rindex(tc->path, '/');
if (slash) {
vgname = pool_alloc(fi->cmd->mem, strlen(slash));
strcpy(vgname, slash + 1);
} else {
vgname = pool_alloc(fi->cmd->mem, strlen(tc->path) + 1);
strcpy(vgname, tc->path);
if (!(nl->name = pool_strdup(fmt->cmd->mem, vgname))) {
log_error("strdup %s failed", vgname);
return 0;
}
vg = _vg_read(fi, vgname);
if (vg) {
pool_free(fi->cmd->mem, vg);
if (!(nl = pool_alloc(fi->cmd->mem, sizeof(*nl)))) {
stack;
goto bad;
}
nl->name = vgname;
list_add(names, &nl->list);
return 1;
}
static struct list *_get_vgs(struct format_type *fmt, struct list *names)
{
struct dirent *dirent;
struct dir_list *dl;
struct list *dlh, *dir_list;
char *tmp;
DIR *d;
dir_list = (struct list *) fmt->private;
list_iterate(dlh, dir_list) {
dl = list_item(dlh, struct dir_list);
if (!(d = opendir(dl->dir))) {
log_sys_error("opendir", dl->dir);
continue;
}
while ((dirent = readdir(d)))
if (strcmp(dirent->d_name, ".") &&
strcmp(dirent->d_name, "..") &&
(!(tmp = strstr(dirent->d_name, ".tmp")) ||
tmp != dirent->d_name + strlen(dirent->d_name)
- 4))
if (!_add_vgname(fmt, names, dirent->d_name))
return NULL;
if (closedir(d))
log_sys_error("closedir", dl->dir);
}
return names;
bad:
pool_free(fi->cmd->mem, names);
return NULL;
}
static struct list *_get_pvs(struct format_instance *fi)
static struct list *_get_pvs(struct format_type *fmt, struct list *results)
{
struct pv_list *pvl;
struct pv_list *pvl, *rhl;
struct list *vgh;
struct list *pvh;
struct list *results = pool_alloc(fi->cmd->mem, sizeof(*results));
struct list *vgs = _get_vgs(fi);
list_init(results);
list_iterate(vgh, vgs) {
struct volume_group *vg;
struct list *names = pool_alloc(fmt->cmd->mem, sizeof(*names));
struct list *rh;
struct name_list *nl;
struct volume_group *vg;
nl = list_item(vgh, struct name_list);
vg = _vg_read(fi, nl->name);
if (vg) {
list_iterate(pvh, &vg->pvs) {
struct pv_list *vgpv =
list_item(pvh, struct pv_list);
pvl = pool_alloc(fi->cmd->mem, sizeof(*pvl));
if (!pvl) {
list_init(names);
if (!_get_vgs(fmt, names)) {
stack;
goto bad;
}
/* ?? do we need to clone the pv structure...really? Nah. */
pvl->pv = vgpv->pv;
list_add(results, &pvl->list);
}
}
}
return results;
bad:
pool_free(fi->cmd->mem, vgs);
return NULL;
}
static int _pv_write(struct format_instance *fi, struct physical_volume *pv)
list_iterate(vgh, names) {
nl = list_item(vgh, struct name_list);
if (!(vg = vg_read(fmt->cmd, nl->name))) {
log_error("format_text: _get_pvs failed to read VG %s",
nl->name);
continue;
}
/* FIXME Use temp hash! */
list_iterate(pvh, &vg->pvs) {
pvl = list_item(pvh, struct pv_list);
/* If in use, remove from list of orphans */
list_iterate(rh, results) {
rhl = list_item(rh, struct pv_list);
if (id_equal(&rhl->pv->id, &pvl->pv->id)) {
if (*rhl->pv->vg_name)
log_err("PV %s in two VGs "
"%s and %s",
dev_name(rhl->pv->dev),
rhl->pv->vg_name,
vg->name);
else
memcpy(&rhl->pv, &pvl->pv,
sizeof(struct
physical_volume));
}
}
}
}
pool_free(fmt->cmd->mem, names);
return results;
}
static int _pv_write(struct format_instance *fi, struct physical_volume *pv,
void *mdl)
{
/* No on-disk PV structure change required! */
/* FIXME vgcache could be wrong */
return 1;
//return (fi->fmt->cmd->fmt1->ops->pv_write(fi, pv, NULL));
/*** FIXME Not required?
struct volume_group *vg;
struct list *pvh;
vg = _vg_read(fi, pv->vg_name);
/* Find the PV in this VG */
// Find the PV in this VG
if (vg) {
list_iterate(pvh, &vg->pvs) {
struct pv_list *vgpv = list_item(pvh, struct pv_list);
@@ -260,85 +361,190 @@ static int _pv_write(struct format_instance *fi, struct physical_volume *pv)
vgpv->pv->status = pv->status;
vgpv->pv->size = pv->size;
/* Not sure if it's worth doing these */
// Not sure if it's worth doing these
vgpv->pv->pe_size = pv->pe_size;
vgpv->pv->pe_count = pv->pe_count;
vgpv->pv->pe_start = pv->pe_start;
vgpv->pv->pe_allocated = pv->pe_allocated;
vgpv->pv->pe_alloc_count = pv->pe_alloc_count;
/* Write it back */
// Write it back
_vg_write(fi, vg);
pool_free(fi->cmd->mem, vg);
pool_free(fi->fmt->cmd->mem, vg);
return 1;
}
}
pool_free(fi->cmd->mem, vg);
pool_free(fi->fmt->cmd->mem, vg);
}
/* Can't handle PVs not in a VG */
// Can't handle PVs not in a VG
return 0;
***/
}
static int _pv_read(struct format_type *fmt, const char *pv_name,
struct physical_volume *pv)
{
struct pv_list *pvl;
struct list *vgh;
struct list *pvh;
struct list *names = pool_alloc(fmt->cmd->mem, sizeof(*names));
struct name_list *nl;
struct volume_group *vg;
struct id *id;
/* FIXME Push up to pv_read */
if (!(id = uuid_map_lookup_label(fmt->cmd->mem, fmt->cmd->um, pv_name))) {
stack;
return 0;
}
static struct physical_volume *_pv_read(struct format_instance *fi,
const char *pv_name)
{
struct list *vgs = _get_vgs(fi);
struct list *vgh;
struct list *pvh;
struct physical_volume *pv;
list_init(names);
if (!_get_vgs(fmt, names)) {
stack;
return 0;
}
/* Look for the PV */
list_iterate(vgh, vgs) {
struct volume_group *vg;
struct name_list *nl;
list_iterate(vgh, names) {
nl = list_item(vgh, struct name_list);
vg = _vg_read(fi, nl->name);
if (vg) {
if (!(vg = vg_read(fmt->cmd, nl->name))) {
log_error("format_text: _pv_read failed to read VG %s",
nl->name);
return 0;
}
list_iterate(pvh, &vg->pvs) {
struct pv_list *vgpv =
list_item(pvh, struct pv_list);
if (!strcmp(dev_name(vgpv->pv->dev), pv_name)) {
pv = pool_alloc(fi->cmd->mem,
sizeof(*pv));
if (!pv) {
stack;
pool_free(fi->cmd->mem, vg);
return NULL;
pvl = list_item(pvh, struct pv_list);
if (id_equal(&pvl->pv->id, id)) {
memcpy(pv, pvl->pv, sizeof(*pv));
break;
}
/* Memberwise copy */
*pv = *vgpv->pv;
pv->vg_name =
pool_alloc(fi->cmd->mem,
strlen(vgpv->pv->
vg_name) + 1);
if (!pv->vg_name) {
stack;
pool_free(fi->cmd->mem, vg);
return NULL;
}
strcpy(pv->vg_name, vgpv->pv->vg_name);
pool_free(fi->cmd->mem, vg);
return pv;
}
}
pool_free(fi->cmd->mem, vg);
}
}
return NULL;
pool_free(fmt->cmd->mem, names);
return 1;
}
static void _destroy(struct format_instance *fi)
static void _destroy_instance(struct format_instance *fid)
{
struct text_c *tc = (struct text_c *) fi->private;
return;
}
dbg_free(tc->path);
dbg_free(tc->desc);
dbg_free(tc);
dbg_free(fi);
static void _free_dirs(struct list *dir_list)
{
struct list *dl, *tmp;
list_iterate_safe(dl, tmp, dir_list) {
list_del(dl);
dbg_free(dl);
}
}
static void _destroy(struct format_type *fmt)
{
if (fmt->private) {
_free_dirs((struct list *) fmt->private);
dbg_free(fmt->private);
}
dbg_free(fmt);
}
static struct format_instance *_create_text_instance(struct format_type *fmt,
const char *vgname,
void *context)
{
struct format_instance *fid;
struct metadata_area *mda;
struct dir_list *dl;
struct list *dlh, *dir_list;
char path[PATH_MAX];
if (!(fid = pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
log_error("Couldn't allocate format instance object.");
return NULL;
}
fid->fmt = fmt;
list_init(&fid->metadata_areas);
if (!vgname) {
if (!(mda = pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
stack;
return NULL;
}
mda->metadata_locn = context;
list_add(&fid->metadata_areas, &mda->list);
} else {
dir_list = (struct list *) fmt->private;
list_iterate(dlh, dir_list) {
dl = list_item(dlh, struct dir_list);
if (lvm_snprintf(path, PATH_MAX, "%s/%s",
dl->dir, vgname) < 0) {
log_error("Name too long %s/%s", dl->dir,
vgname);
return NULL;
}
context = create_text_context(fmt, path, NULL);
if (!(mda = pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
stack;
return NULL;
}
mda->metadata_locn = context;
list_add(&fid->metadata_areas, &mda->list);
}
}
return fid;
}
void *create_text_context(struct format_type *fmt, const char *path,
const char *desc)
{
struct text_context *tc;
char *tmp;
if ((tmp = strstr(path, ".tmp")) && (tmp == path + strlen(path) - 4)) {
log_error("%s: Volume group filename may not end in .tmp",
path);
return NULL;
}
if (!(tc = pool_alloc(fmt->cmd->mem, sizeof(*tc)))) {
stack;
return NULL;
}
if (!(tc->path_live = pool_strdup(fmt->cmd->mem, path))) {
stack;
goto no_mem;
}
if (!(tc->path_edit = pool_alloc(fmt->cmd->mem, strlen(path) + 5))) {
stack;
goto no_mem;
}
sprintf(tc->path_edit, "%s.tmp", path);
if (!desc)
desc = "";
if (!(tc->desc = pool_strdup(fmt->cmd->mem, desc))) {
stack;
goto no_mem;
}
return (void *) tc;
no_mem:
pool_free(fmt->cmd->mem, tc);
log_err("Couldn't allocate text format context object.");
return NULL;
}
static struct format_handler _text_handler = {
@@ -347,62 +553,86 @@ static struct format_handler _text_handler = {
pv_read: _pv_read,
pv_setup: _pv_setup,
pv_write: _pv_write,
pv_commit: _pv_commit,
vg_setup: _vg_setup,
lv_setup: _lv_setup,
vg_read: _vg_read,
vg_write: _vg_write,
vg_remove: _vg_remove,
vg_commit: _vg_commit,
create_instance:_create_text_instance,
destroy_instance:_destroy_instance,
destroy: _destroy
};
struct format_instance *text_format_create(struct cmd_context *cmd,
const char *file,
struct uuid_map *um,
const char *desc)
static int _add_dir(const char *dir, struct list *dir_list)
{
struct format_instance *fi;
char *path, *d;
struct text_c *tc;
struct dir_list *dl;
if (!(fi = dbg_malloc(sizeof(*fi)))) {
stack;
goto no_mem;
if (create_dir(dir)) {
if (!(dl = dbg_malloc(sizeof(struct list) + strlen(dir) + 1))) {
log_error("_add_dir allocation failed");
return 0;
}
strcpy(dl->dir, dir);
list_add(dir_list, &dl->list);
return 1;
}
if (!(path = dbg_strdup(file))) {
stack;
goto no_mem;
return 0;
}
if (!(d = dbg_strdup(desc))) {
struct format_type *create_text_format(struct cmd_context *cmd)
{
struct format_type *fmt;
struct config_node *cn;
struct config_value *cv;
struct list *dir_list;
if (!(fmt = dbg_malloc(sizeof(*fmt)))) {
stack;
goto no_mem;
}
if (!(tc = dbg_malloc(sizeof(*tc)))) {
stack;
goto no_mem;
}
tc->path = path;
tc->desc = d;
tc->um = um;
fi->cmd = cmd;
fi->ops = &_text_handler;
fi->private = tc;
return fi;
no_mem:
if (fi)
dbg_free(fi);
if (path)
dbg_free(path);
if (d)
dbg_free(path);
log_err("Couldn't allocate text format object.");
return NULL;
}
fmt->cmd = cmd;
fmt->ops = &_text_handler;
fmt->name = FMT_TEXT_NAME;
fmt->features = FMT_SEGMENTS;
if (!(dir_list = dbg_malloc(sizeof(struct list)))) {
log_error("Failed to allocate dir_list");
return NULL;
}
list_init(dir_list);
fmt->private = (void *) dir_list;
if (!(cn = find_config_node(cmd->cf->root, "metadata/dirs", '/'))) {
log_verbose("metadata/dirs not in config file: Defaulting "
"to /etc/lvm/metadata");
_add_dir("/etc/lvm/metadata", dir_list);
return fmt;
}
for (cv = cn->v; cv; cv = cv->next) {
if (cv->type != CFG_STRING) {
log_error("Invalid string in config file: "
"metadata/dirs");
goto err;
}
if (!_add_dir(cv->v.str, dir_list)) {
log_error("Failed to add %s to internal device cache",
cv->v.str);
goto err;
}
}
return fmt;
err:
_free_dirs(dir_list);
dbg_free(fmt);
return NULL;
}

View File

@@ -32,9 +32,8 @@ int archive_list(struct cmd_context *cmd, struct uuid_map *um,
/*
* The text format can read and write a volume_group to a file.
*/
struct format_instance *text_format_create(struct cmd_context *cmd,
const char *file,
struct uuid_map *um,
struct format_type *create_text_format(struct cmd_context *cmd);
void *create_text_context(struct format_type *fmt, const char *path,
const char *desc);
#endif

View File

@@ -25,7 +25,8 @@ int read_flags(uint32_t *status, int type, struct config_value *cv);
int text_vg_export(FILE *fp, struct volume_group *vg, const char *desc);
struct volume_group *text_vg_import(struct cmd_context *cmd, const char *file,
struct volume_group *text_vg_import(struct format_instance *fid,
const char *file,
struct uuid_map *um,
time_t *when, char **desc);

View File

@@ -12,11 +12,10 @@
#include "hash.h"
#include "toolcontext.h"
typedef int (*section_fn)(struct pool *mem,
typedef int (*section_fn) (struct format_instance * fid, struct pool * mem,
struct volume_group * vg, struct config_node * pvn,
struct config_node *vgn, struct hash_table *pv_hash,
struct uuid_map *um);
struct config_node * vgn,
struct hash_table * pv_hash, struct uuid_map * um);
#define _read_int32(root, path, result) \
get_config_uint32(root, path, '/', result)
@@ -50,11 +49,10 @@ static int _read_id(struct id *id, struct config_node *cn, const char *path)
return 1;
}
static int _read_pv(struct pool *mem,
static int _read_pv(struct format_instance *fid, struct pool *mem,
struct volume_group *vg, struct config_node *pvn,
struct config_node *vgn,
struct hash_table *pv_hash,
struct uuid_map *um)
struct hash_table *pv_hash, struct uuid_map *um)
{
struct physical_volume *pv;
struct pv_list *pvl;
@@ -93,12 +91,14 @@ static int _read_pv(struct pool *mem,
if (!(pv->dev = uuid_map_lookup(um, &pv->id))) {
char buffer[64];
if (!id_write_format(&pv->id, buffer, sizeof(buffer))) {
if (!id_write_format(&pv->id, buffer, sizeof(buffer)))
log_err("Couldn't find device.");
return 0;
}
else
log_err("Couldn't find device with uuid '%s'.", buffer);
if (partial_mode())
vg->status |= PARTIAL_VG;
else
return 0;
}
@@ -134,7 +134,8 @@ static int _read_pv(struct pool *mem,
pv->pe_size = vg->extent_size;
pv->size = pv->pe_size * (uint64_t) pv->pe_count;
pv->pe_allocated = 0;
pv->pe_alloc_count = 0;
pv->fid = fid;
vg->pv_count++;
list_add(&vg->pvs, &pvl->list);
@@ -178,8 +179,7 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
}
if (!_read_int32(sn, "stripes", &stripes)) {
log_err("Couldn't read 'stripes' for segment '%s'.",
sn->key);
log_err("Couldn't read 'stripes' for segment '%s'.", sn->key);
return 0;
}
@@ -241,8 +241,7 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
if (!(pv = hash_lookup(pv_hash, cv->v.str))) {
log_err("Couldn't find physical volume '%s' for "
"segment '%s'.",
cn->v->v.str ? cn->v->v.str : "NULL",
seg_name);
cn->v->v.str ? cn->v->v.str : "NULL", seg_name);
return 0;
}
@@ -264,7 +263,7 @@ static int _read_segment(struct pool *mem, struct volume_group *vg,
* Adjust the extent counts in the pv and vg.
*/
allocated = seg->len / seg->stripes;
pv->pe_allocated += allocated;
pv->pe_alloc_count += allocated;
vg->free_count -= allocated;
}
@@ -336,7 +335,7 @@ static int _read_segments(struct pool *mem, struct volume_group *vg,
return 1;
}
static int _read_lv(struct pool *mem,
static int _read_lv(struct format_instance *fid, struct pool *mem,
struct volume_group *vg, struct config_node *lvn,
struct config_node *vgn, struct hash_table *pv_hash,
struct uuid_map *um)
@@ -367,8 +366,7 @@ static int _read_lv(struct pool *mem,
/* FIXME: read full lvid */
if (!_read_id(&lv->lvid.id[1], lvn, "id")) {
log_err("Couldn't read uuid for logical volume %s.",
lv->name);
log_err("Couldn't read uuid for logical volume %s.", lv->name);
return 0;
}
@@ -410,7 +408,7 @@ static int _read_lv(struct pool *mem,
return 1;
}
static int _read_snapshot(struct pool *mem,
static int _read_snapshot(struct format_instance *fid, struct pool *mem,
struct volume_group *vg, struct config_node *sn,
struct config_node *vgn, struct hash_table *pv_hash,
struct uuid_map *um)
@@ -459,12 +457,12 @@ static int _read_snapshot(struct pool *mem,
return 1;
}
static int _read_sections(const char *section, section_fn fn,
static int _read_sections(struct format_instance *fid,
const char *section, section_fn fn,
struct pool *mem,
struct volume_group *vg, struct config_node *vgn,
struct hash_table *pv_hash,
struct uuid_map *um,
int optional)
struct uuid_map *um, int optional)
{
struct config_node *n;
@@ -478,7 +476,7 @@ static int _read_sections(const char *section, section_fn fn,
}
for (n = n->child; n; n = n->sib) {
if (!fn(mem, vg, n, vgn, pv_hash, um)) {
if (!fn(fid, mem, vg, n, vgn, pv_hash, um)) {
stack;
return 0;
}
@@ -487,18 +485,17 @@ static int _read_sections(const char *section, section_fn fn,
return 1;
}
static struct volume_group *_read_vg(struct cmd_context *cmd,
static struct volume_group *_read_vg(struct format_instance *fid,
struct config_file *cf,
struct uuid_map *um)
{
struct config_node *vgn, *cn;
struct volume_group *vg;
struct hash_table *pv_hash = NULL;
struct pool *mem = cmd->mem;
struct pool *mem = fid->fmt->cmd->mem;
/* skip any top-level values */
for (vgn = cf->root; (vgn && vgn->v); vgn = vgn->sib)
;
for (vgn = cf->root; (vgn && vgn->v); vgn = vgn->sib) ;
if (!vgn) {
log_err("Couldn't find volume group in file.");
@@ -509,7 +506,11 @@ static struct volume_group *_read_vg(struct cmd_context *cmd,
stack;
return NULL;
}
vg->cmd = cmd;
vg->cmd = fid->fmt->cmd;
/* FIXME Determine format type from file contents */
/* eg Set to instance of fmt1 here if reading a format1 backup? */
vg->fid = fid;
if (!(vg->name = pool_strdup(mem, vgn->key))) {
stack;
@@ -532,8 +533,12 @@ static struct volume_group *_read_vg(struct cmd_context *cmd,
}
if (!_read_id(&vg->id, vgn, "id")) {
log_err("Couldn't read uuid for volume group %s.",
vg->name);
log_err("Couldn't read uuid for volume group %s.", vg->name);
goto bad;
}
if (!_read_int32(vgn, "seqno", &vg->seqno)) {
log_err("Couldn't read 'seqno' for volume group %s.", vg->name);
goto bad;
}
@@ -582,7 +587,7 @@ static struct volume_group *_read_vg(struct cmd_context *cmd,
}
list_init(&vg->pvs);
if (!_read_sections("physical_volumes", _read_pv, mem, vg,
if (!_read_sections(fid, "physical_volumes", _read_pv, mem, vg,
vgn, pv_hash, um, 0)) {
log_err("Couldn't find all physical volumes for volume "
"group %s.", vg->name);
@@ -590,7 +595,7 @@ static struct volume_group *_read_vg(struct cmd_context *cmd,
}
list_init(&vg->lvs);
if (!_read_sections("logical_volumes", _read_lv, mem, vg,
if (!_read_sections(fid, "logical_volumes", _read_lv, mem, vg,
vgn, pv_hash, um, 1)) {
log_err("Couldn't read all logical volumes for volume "
"group %s.", vg->name);
@@ -598,7 +603,7 @@ static struct volume_group *_read_vg(struct cmd_context *cmd,
}
list_init(&vg->snapshots);
if (!_read_sections("snapshots", _read_snapshot, mem, vg,
if (!_read_sections(fid, "snapshots", _read_snapshot, mem, vg,
vgn, pv_hash, um, 1)) {
log_err("Couldn't read all snapshots for volume group %s.",
vg->name);
@@ -607,6 +612,11 @@ static struct volume_group *_read_vg(struct cmd_context *cmd,
hash_destroy(pv_hash);
if (vg->status & PARTIAL_VG) {
vg->status &= ~LVM_WRITE;
vg->status |= LVM_READ;
}
/*
* Finished.
*/
@@ -633,7 +643,7 @@ static void _read_desc(struct pool *mem,
*when = u;
}
struct volume_group *text_vg_import(struct cmd_context *cmd,
struct volume_group *text_vg_import(struct format_instance *fid,
const char *file,
struct uuid_map *um,
time_t * when, char **desc)
@@ -654,14 +664,12 @@ struct volume_group *text_vg_import(struct cmd_context *cmd,
goto out;
}
if (!(vg = _read_vg(cmd, cf, um))) {
if (!(vg = _read_vg(fid, cf, um))) {
stack;
goto out;
}
vg->cmd = cmd;
_read_desc(cmd->mem, cf, when, desc);
_read_desc(fid->fmt->cmd->mem, cf, when, desc);
out:
destroy_config_file(cf);

View File

@@ -21,7 +21,6 @@ struct labeller_i {
static struct list _labellers;
static struct labeller_i *_alloc_li(const char *name, struct labeller *l)
{
struct labeller_i *li;
@@ -45,7 +44,6 @@ static void _free_li(struct labeller_i *li)
dbg_free(li);
}
int label_init(void)
{
list_init(&_labellers);

View File

@@ -27,8 +27,7 @@
#define BLOCK_SIZE 512
/* This is just the "struct lvm2_label" with the data pointer removed */
struct label_ondisk
{
struct label_ondisk {
uint32_t magic;
uint32_t crc;
uint64_t label1_loc;
@@ -40,17 +39,16 @@ struct label_ondisk
char disk_type[32];
};
struct filter_private
{
struct filter_private {
void *mem;
char disk_type[32];
uint32_t version[3];
int version_match;
};
/* Calculate CRC32 of a buffer */
static uint32_t crc32(uint32_t initial, const unsigned char *databuf, size_t datalen)
static uint32_t crc32(uint32_t initial, const unsigned char *databuf,
size_t datalen)
{
static const u_int crctab[] = {
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
@@ -74,25 +72,34 @@ static uint32_t calc_crc(struct label_ondisk *label, char *data)
uint32_t crcval = 0xffffffff;
crcval = crc32(crcval, (char *) &label->magic, sizeof(label->magic));
crcval = crc32(crcval, (char *)&label->label1_loc, sizeof(label->label1_loc));
crcval = crc32(crcval, (char *)&label->label2_loc, sizeof(label->label2_loc));
crcval = crc32(crcval, (char *)&label->datalen, sizeof(label->datalen));
crcval = crc32(crcval, (char *)&label->version, sizeof(label->version));
crcval = crc32(crcval, (char *)label->disk_type, strlen(label->disk_type));
crcval =
crc32(crcval, (char *) &label->label1_loc,
sizeof(label->label1_loc));
crcval =
crc32(crcval, (char *) &label->label2_loc,
sizeof(label->label2_loc));
crcval =
crc32(crcval, (char *) &label->datalen, sizeof(label->datalen));
crcval =
crc32(crcval, (char *) &label->version, sizeof(label->version));
crcval =
crc32(crcval, (char *) label->disk_type, strlen(label->disk_type));
crcval = crc32(crcval, (char *) data, label->datalen);
return crcval;
}
/* Calculate the locations we should find the labels in */
static inline void get_label_locations(uint64_t size, uint32_t sectsize, long *first, long *second)
static inline void get_label_locations(uint64_t size, uint32_t sectsize,
long *first, long *second)
{
*first = sectsize;
*second = size * BLOCK_SIZE - sectsize;
}
/* Read a label off disk */
static int lvm2_label_read(struct labeller *l, struct device *dev, struct label **label)
static int lvm2_label_read(struct labeller *l, struct device *dev,
struct label **label)
{
uint64_t size;
uint32_t sectsize;
@@ -112,8 +119,7 @@ static int lvm2_label_read(struct labeller *l, struct device *dev, struct label
return 0;
block = dbg_malloc(sectsize);
if (!block)
{
if (!block) {
stack;
return 0;
}
@@ -121,11 +127,9 @@ static int lvm2_label_read(struct labeller *l, struct device *dev, struct label
get_label_locations(size, sectsize, &offset[0], &offset[1]);
/* If the first label is bad then use the second */
for (iter = 0; iter <= 1; iter++)
{
for (iter = 0; iter <= 1; iter++) {
status = dev_read(dev, offset[iter], sectsize, block);
if (status)
{
if (status) {
struct label *incore;
int i;
int found_nul;
@@ -146,48 +150,54 @@ static int lvm2_label_read(struct labeller *l, struct device *dev, struct label
continue;
incore = dbg_malloc(sizeof(struct label));
if (incore == NULL)
{
if (incore == NULL) {
return 0;
}
/* Copy and convert endianness */
strncpy(incore->volume_type, ondisk->disk_type, sizeof(incore->volume_type));
strncpy(incore->volume_type, ondisk->disk_type,
sizeof(incore->volume_type));
incore->version[0] = xlate32(ondisk->version[0]);
incore->version[1] = xlate32(ondisk->version[1]);
incore->version[2] = xlate32(ondisk->version[2]);
incore->extra_len = xlate16(ondisk->datalen);
incore->extra_info = block + sizeof(struct label_ondisk);
incore->extra_info =
block + sizeof(struct label_ondisk);
/* Make sure datalen is a sensible size too */
if (incore->extra_len > sectsize)
continue;
/* Check Crc */
if (xlate32(ondisk->crc) != calc_crc(ondisk, incore->extra_info))
{
log_error("Crc %d on device %s does not match. got %x, expected %x",
iter, dev_name(dev), xlate32(ondisk->crc), calc_crc(ondisk, incore->extra_info));
if (xlate32(ondisk->crc) !=
calc_crc(ondisk, incore->extra_info)) {
log_error
("Crc %d on device %s does not match. got %x, expected %x",
iter, dev_name(dev), xlate32(ondisk->crc),
calc_crc(ondisk, incore->extra_info));
continue;
}
/* Check label locations match our view of the device */
if (xlate64(ondisk->label1_loc) != offset[0])
log_error("Label 1 location is wrong in label %d - check block size of the device\n",
log_error
("Label 1 location is wrong in label %d - check block size of the device\n",
iter);
if (xlate64(ondisk->label2_loc) != offset[1])
log_error("Label 2 location is wrong in label %d - the size of the device must have changed\n",
log_error
("Label 2 location is wrong in label %d - the size of the device must have changed\n",
iter);
/* Copy to user's data area */
*label = incore;
incore->extra_info = dbg_malloc(incore->extra_len);
if (!incore->extra_info)
{
if (!incore->extra_info) {
stack;
return 0;
}
memcpy(incore->extra_info, block + sizeof(struct label_ondisk), incore->extra_len);
memcpy(incore->extra_info,
block + sizeof(struct label_ondisk),
incore->extra_len);
dbg_free(block);
dev_close(dev);
@@ -202,7 +212,8 @@ static int lvm2_label_read(struct labeller *l, struct device *dev, struct label
}
/* Write a label to a device */
static int lvm2_label_write(struct labeller *l, struct device *dev, struct label *label)
static int lvm2_label_write(struct labeller *l, struct device *dev,
struct label *label)
{
uint64_t size;
uint32_t sectsize;
@@ -222,8 +233,7 @@ static int lvm2_label_write(struct labeller *l, struct device *dev, struct label
return 0;
block = dbg_malloc(sizeof(struct label_ondisk) + label->extra_len);
if (!block)
{
if (!block) {
stack;
return 0;
}
@@ -239,32 +249,37 @@ static int lvm2_label_write(struct labeller *l, struct device *dev, struct label
ondisk->label1_loc = xlate64(offset[0]);
ondisk->label2_loc = xlate64(offset[1]);
ondisk->datalen = xlate16(label->extra_len);
strncpy(ondisk->disk_type, label->volume_type, sizeof(ondisk->disk_type));
memcpy(block+sizeof(struct label_ondisk), label->extra_info, label->extra_len);
strncpy(ondisk->disk_type, label->volume_type,
sizeof(ondisk->disk_type));
memcpy(block + sizeof(struct label_ondisk), label->extra_info,
label->extra_len);
ondisk->crc = xlate32(calc_crc(ondisk, label->extra_info));
/* Write metadata to disk */
if (!dev_open(dev, O_RDWR))
{
if (!dev_open(dev, O_RDWR)) {
dbg_free(block);
return 0;
}
status1 = dev_write(dev, offset[0], sizeof(struct label_ondisk) + label->extra_len, block);
status1 =
dev_write(dev, offset[0],
sizeof(struct label_ondisk) + label->extra_len, block);
if (!status1)
log_error("Error writing label 1\n");
/* Write another at the end of the device */
status2 = dev_write(dev, offset[1], sizeof(struct label_ondisk) + label->extra_len, block);
if (!status2)
{
status2 =
dev_write(dev, offset[1],
sizeof(struct label_ondisk) + label->extra_len, block);
if (!status2) {
char zerobuf[sizeof(struct label_ondisk)];
log_error("Error writing label 2\n");
/* Wipe the first label so it doesn't get confusing */
memset(zerobuf, 0, sizeof(struct label_ondisk));
if (!dev_write(dev, offset[0], sizeof(struct label_ondisk), zerobuf))
log_error("Error erasing label 1\n");
if (!dev_write
(dev, offset[0], sizeof(struct label_ondisk),
zerobuf)) log_error("Error erasing label 1\n");
}
dbg_free(block);
@@ -273,8 +288,6 @@ static int lvm2_label_write(struct labeller *l, struct device *dev, struct label
return ((status1 != 0) && (status2 != 0));
}
/* Return 1 for Yes, 0 for No */
static int lvm2_is_labelled(struct labeller *l, struct device *dev)
{
@@ -282,7 +295,8 @@ static int lvm2_is_labelled(struct labeller *l, struct device *dev)
int status;
status = lvm2_label_read(l, dev, &label);
if (status) label_free(label);
if (status)
label_free(label);
return status;
}
@@ -296,12 +310,9 @@ static int _accept_format(struct dev_filter *f, struct device *dev)
status = lvm2_label_read(NULL, dev, &l);
if (status)
{
if (strcmp(l->volume_type, fp->disk_type) == 0)
{
switch (fp->version_match)
{
if (status) {
if (strcmp(l->volume_type, fp->disk_type) == 0) {
switch (fp->version_match) {
case VERSION_MATCH_EQUAL:
if (l->version[0] == fp->version[0] &&
l->version[1] == fp->version[1] &&
@@ -342,7 +353,9 @@ static void _destroy(struct dev_filter *f)
}
/* A filter to find devices with a particular label type on them */
struct dev_filter *lvm2_label_format_filter_create(char *disk_type, uint32_t version[3], int match_type)
struct dev_filter *lvm2_label_format_filter_create(char *disk_type,
uint32_t version[3],
int match_type)
{
struct pool *mem;
struct filter_private *fp;
@@ -442,15 +455,13 @@ static int lvm2_labels_match(struct labeller *l, struct device *dev)
/* Allocate some space for the blocks we are going to read in */
block1 = dbg_malloc(sectsize);
if (!block1)
{
if (!block1) {
stack;
return 0;
}
block2 = dbg_malloc(sectsize);
if (!block2)
{
if (!block2) {
stack;
dbg_free(block1);
return 0;
@@ -510,8 +521,7 @@ static int lvm2_label_remove(struct labeller *l, struct device *dev)
if (!dev_get_sectsize(dev, &sectsize))
return 0;
if (!dev_open(dev, O_RDWR))
{
if (!dev_open(dev, O_RDWR)) {
dbg_free(block);
return 0;
}
@@ -538,8 +548,7 @@ static void lvm2_label_destroy(struct labeller *l)
{
}
static struct label_ops handler_ops =
{
static struct label_ops handler_ops = {
can_handle: lvm2_is_labelled,
write: lvm2_label_write,
remove: lvm2_label_remove,
@@ -548,8 +557,7 @@ static struct label_ops handler_ops =
destroy: lvm2_label_destroy,
};
static struct labeller this_labeller =
{
static struct labeller this_labeller = {
private: NULL,
ops: &handler_ops,
};

View File

@@ -12,12 +12,12 @@
#include "dbg_malloc.h"
#include "log.h"
#include "label.h"
#include "pool.h"
struct uuid_map {
struct dev_filter *filter;
};
struct uuid_map *uuid_map_create(struct dev_filter *devices)
{
struct uuid_map *um;
@@ -67,4 +67,33 @@ struct device *uuid_map_lookup(struct uuid_map *um, struct id *id)
return dev;
}
struct id *uuid_map_lookup_label(struct pool *mem, struct uuid_map *um,
const char *name)
{
struct device *dev;
struct label *lab;
struct id *id;
if (!(dev = dev_cache_get(name, um->filter))) {
stack;
return NULL;
}
if (!label_read(dev, &lab)) {
stack;
return NULL;
}
if (!(id = pool_alloc(mem, sizeof(*id)))) {
stack;
label_destroy(lab);
return NULL;
}
memcpy(id, &lab->id, sizeof(*id));
label_destroy(lab);
return id;
}
#endif

View File

@@ -9,6 +9,7 @@
#include "uuid.h"
#include "dev-cache.h"
#include "pool.h"
/*
* Holds a mapping from uuid -> device.
@@ -22,5 +23,7 @@ void uuid_map_destroy(struct uuid_map *um);
* Find the device with a particular uuid.
*/
struct device *uuid_map_lookup(struct uuid_map *um, struct id *id);
struct id *uuid_map_lookup_label(struct pool *mem, struct uuid_map *um,
const char *name);
#endif

View File

@@ -26,10 +26,12 @@
static void *locking_module = NULL;
static void (*end_fn) (void) = NULL;
static int (*lock_fn)(struct cmd_context *cmd, const char *resource, int flags) = NULL;
static int (*lock_fn) (struct cmd_context * cmd, const char *resource,
int flags) = NULL;
static int (*init_fn) (int type, struct config_file * cf) = NULL;
static int lock_resource(struct cmd_context *cmd, const char *resource, int flags)
static int lock_resource(struct cmd_context *cmd, const char *resource,
int flags)
{
if (lock_fn)
return lock_fn(cmd, resource, flags);
@@ -37,7 +39,6 @@ static int lock_resource(struct cmd_context *cmd, const char *resource, int flag
return 0;
}
static void fin_external_locking(void)
{
if (end_fn)
@@ -54,9 +55,8 @@ int init_external_locking(struct locking_type *locking, struct config_file *cf)
{
char _lock_lib[PATH_MAX];
if (locking_module)
{
log_error("External locking already initialised\n");
if (locking_module) {
log_error("External locking already initialised");
return 1;
}
locking->lock_resource = lock_resource;
@@ -67,27 +67,23 @@ int init_external_locking(struct locking_type *locking, struct config_file *cf)
'/', "lvm2_locking.so"),
sizeof(_lock_lib));
/* If there is a module_dir in the config file then
look for the locking module in there first and then
using the normal dlopen(3) mechanism of looking
down LD_LIBRARY_PATH and /lib, /usr/lib.
If course, if the library name starts with a slash then
just use the name... */
if (_lock_lib[0] != '/')
{
if (_lock_lib[0] != '/') {
struct stat st;
char _lock_lib1[PATH_MAX];
lvm_snprintf(_lock_lib1, sizeof(_lock_lib1),
"%s/%s",
find_config_str(cf->root, "global/module_dir",
'/', "RUBBISH"),
_lock_lib);
'/', "RUBBISH"), _lock_lib);
/* Does it exist ? */
if (stat(_lock_lib1, &st) == 0)
{
if (stat(_lock_lib1, &st) == 0) {
strcpy(_lock_lib, _lock_lib1);
}
}
@@ -95,9 +91,9 @@ int init_external_locking(struct locking_type *locking, struct config_file *cf)
log_very_verbose("Opening locking library %s", _lock_lib);
locking_module = dlopen(_lock_lib, RTLD_LAZY);
if (!locking_module)
{
log_error("Unable to open external locking module %s\n", _lock_lib);
if (!locking_module) {
log_error("Unable to open external locking module %s",
_lock_lib);
return 0;
}
@@ -107,9 +103,9 @@ int init_external_locking(struct locking_type *locking, struct config_file *cf)
end_fn = dlsym(locking_module, "end_locking");
/* Are they all there ? */
if (!end_fn || !init_fn || !lock_fn)
{
log_error("shared library %s does not contain locking functions\n", _lock_lib);
if (!end_fn || !init_fn || !lock_fn) {
log_error ("Shared library %s does not contain locking "
"functions", _lock_lib);
dlclose(locking_module);
return 0;
}

View File

@@ -197,6 +197,10 @@ int lock_resource(struct cmd_context *cmd, const char *resource, int flags)
return 0;
break;
case LCK_LV:
/* Skip if driver isn't loaded */
/* FIXME Use /proc/misc instead? */
if (!driver_version(NULL, 0))
return 1;
switch (flags & LCK_TYPE_MASK) {
case LCK_UNLOCK:
if (!lv_resume_if_active(cmd, resource))

View File

@@ -25,7 +25,7 @@ static void _get_extents(struct stripe_segment *seg)
for (s = 0; s < seg->stripes; s++) {
pv = seg->area[s].pv;
count = seg->len / seg->stripes;
pv->pe_allocated += count;
pv->pe_alloc_count += count;
}
}
@@ -38,8 +38,8 @@ static void _put_extents(struct stripe_segment *seg)
pv = seg->area[s].pv;
count = seg->len / seg->stripes;
assert(pv->pe_allocated >= count);
pv->pe_allocated -= count;
assert(pv->pe_alloc_count >= count);
pv->pe_alloc_count -= count;
}
}
@@ -143,8 +143,7 @@ static int _alloc_striped(struct logical_volume *lv,
if (index < stripes) {
log_error("Insufficient allocatable extents suitable "
"for striping for logical volume "
"%s: %u required",
lv->name, lv->le_count);
"%s: %u required", lv->name, lv->le_count);
goto out;
}
@@ -164,7 +163,6 @@ static int _alloc_striped(struct logical_volume *lv,
return r;
}
/*
* The heart of the allocation code. This function takes a
* pv_area and allocates it to the lv. If the lv doesn't need
@@ -435,7 +433,7 @@ struct logical_volume *lv_create(struct format_instance *fi,
goto bad;
}
if (fi->ops->lv_setup && !fi->ops->lv_setup(fi, lv)) {
if (fi->fmt->ops->lv_setup && !fi->fmt->ops->lv_setup(fi, lv)) {
stack;
goto bad;
}
@@ -460,8 +458,7 @@ int lv_reduce(struct format_instance *fi,
uint32_t count = extents;
for (segh = lv->segments.p;
(segh != &lv->segments) && count;
segh = segh->p) {
(segh != &lv->segments) && count; segh = segh->p) {
seg = list_item(segh, struct stripe_segment);
if (seg->len <= count) {
@@ -480,8 +477,9 @@ int lv_reduce(struct format_instance *fi,
lv->le_count -= extents;
lv->size = (uint64_t) lv->le_count * lv->vg->extent_size;
lv->vg->free_count += extents;
if (fi->ops->lv_setup && !fi->ops->lv_setup(fi, lv)) {
if (fi->fmt->ops->lv_setup && !fi->fmt->ops->lv_setup(fi, lv)) {
stack;
return 0;
}
@@ -492,8 +490,7 @@ int lv_reduce(struct format_instance *fi,
int lv_extend(struct format_instance *fi,
struct logical_volume *lv,
uint32_t stripes, uint32_t stripe_size,
uint32_t extents,
struct list *acceptable_pvs)
uint32_t extents, struct list *acceptable_pvs)
{
uint32_t old_le_count = lv->le_count;
uint64_t old_size = lv->size;
@@ -501,8 +498,6 @@ int lv_extend(struct format_instance *fi,
lv->le_count += extents;
lv->size += (uint64_t) extents *lv->vg->extent_size;
/* FIXME: Format1 must ensure stripes is consistent with 1st seg */
if (!_allocate(lv->vg, lv, acceptable_pvs, old_le_count,
stripes, stripe_size)) {
lv->le_count = old_le_count;
@@ -516,7 +511,7 @@ int lv_extend(struct format_instance *fi,
return 0;
}
if (fi->ops->lv_setup && !fi->ops->lv_setup(fi, lv)) {
if (fi->fmt->ops->lv_setup && !fi->fmt->ops->lv_setup(fi, lv)) {
stack;
return 0;
}

View File

@@ -12,6 +12,7 @@
#include "toolcontext.h"
#include "lvm-string.h"
#include "uuid.h"
#include "vgcache.h"
#include <string.h>
@@ -20,7 +21,7 @@ int _add_pv_to_vg(struct format_instance *fi, struct volume_group *vg,
{
struct pv_list *pvl;
struct physical_volume *pv;
struct pool *mem = fi->cmd->mem;
struct pool *mem = fi->fmt->cmd->mem;
log_verbose("Adding physical volume '%s' to volume group '%s'",
pv_name, vg->name);
@@ -30,7 +31,7 @@ int _add_pv_to_vg(struct format_instance *fi, struct volume_group *vg,
return 0;
}
if (!(pv = fi->ops->pv_read(fi, pv_name))) {
if (!(pv = pv_read(fi->fmt->cmd, pv_name))) {
log_error("Failed to read existing physical volume '%s'",
pv_name);
return 0;
@@ -50,16 +51,20 @@ int _add_pv_to_vg(struct format_instance *fi, struct volume_group *vg,
/* Units of 512-byte sectors */
pv->pe_size = vg->extent_size;
/* FIXME Do proper rounding-up alignment? */
/* Reserved space for label; this holds 0 for PVs created by LVM1 */
if (pv->pe_start < PE_ALIGN)
pv->pe_start = PE_ALIGN;
/*
* The next two fields should be corrected
* by fi->pv_setup.
*/
pv->pe_start = 0;
pv->pe_count = pv->size / pv->pe_size;
pv->pe_count = (pv->size - pv->pe_start) / pv->pe_size;
pv->pe_allocated = 0;
pv->pe_alloc_count = 0;
if (!fi->ops->pv_setup(fi, pv, vg)) {
if (!fi->fmt->ops->pv_setup(fi, pv, vg)) {
log_error("Format-specific setup of physical volume '%s' "
"failed.", pv_name);
return 0;
@@ -113,42 +118,43 @@ const char *strip_dir(const char *vg_name, const char *dev_dir)
return vg_name;
}
struct volume_group *vg_create(struct format_instance *fi, const char *vg_name,
struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name,
uint32_t extent_size, int max_pv, int max_lv,
int pv_count, char **pv_names)
{
struct volume_group *vg;
struct pool *mem = fi->cmd->mem;
struct pool *mem = cmd->mem;
if (!(vg = pool_alloc(mem, sizeof (*vg)))) {
if (!(vg = pool_zalloc(mem, sizeof(*vg)))) {
stack;
return NULL;
}
/* is this vg name already in use ? */
init_partial(1);
if (fi->ops->vg_read(fi, vg_name)) {
if (vg_read(cmd, vg_name)) {
log_err("A volume group called '%s' already exists.", vg_name);
goto bad;
}
init_partial(0);
if (!id_create(&vg->id)) {
log_err("Couldn't create uuid for volume group '%s'.",
vg_name);
log_err("Couldn't create uuid for volume group '%s'.", vg_name);
goto bad;
}
/* Strip dev_dir if present */
vg_name = strip_dir(vg_name, fi->cmd->dev_dir);
vg_name = strip_dir(vg_name, cmd->dev_dir);
vg->cmd = fi->cmd;
vg->cmd = cmd;
if (!(vg->name = pool_strdup(mem, vg_name))) {
stack;
goto bad;
}
vg->seqno = 0;
vg->status = (RESIZEABLE_VG | LVM_READ | LVM_WRITE);
vg->system_id = pool_alloc(mem, NAME_LEN);
*vg->system_id = '\0';
@@ -169,14 +175,20 @@ struct volume_group *vg_create(struct format_instance *fi, const char *vg_name,
vg->snapshot_count = 0;
list_init(&vg->snapshots);
if (!fi->ops->vg_setup(fi, vg)) {
if (!(vg->fid = cmd->fmt->ops->create_instance(cmd->fmt, vg_name,
NULL))) {
log_error("Failed to create format instance");
goto bad;
}
if (!vg->fid->fmt->ops->vg_setup(vg->fid, vg)) {
log_error("Format specific setup of volume group '%s' failed.",
vg_name);
goto bad;
}
/* attach the pv's */
if (!vg_extend(fi, vg, pv_count, pv_names))
if (!vg_extend(vg->fid, vg, pv_count, pv_names))
goto bad;
return vg;
@@ -186,12 +198,11 @@ struct volume_group *vg_create(struct format_instance *fi, const char *vg_name,
return NULL;
}
struct physical_volume *pv_create(struct format_instance *fi,
struct physical_volume *pv_create(struct format_instance *fid,
const char *name,
struct id *id,
uint64_t size)
struct id *id, uint64_t size)
{
struct pool *mem = fi->cmd->mem;
struct pool *mem = fid->fmt->cmd->mem;
struct physical_volume *pv = pool_alloc(mem, sizeof(*pv));
if (!pv) {
@@ -204,7 +215,7 @@ struct physical_volume *pv_create(struct format_instance *fi,
else
memcpy(&pv->id, id, sizeof(*id));
if (!(pv->dev = dev_cache_get(name, fi->cmd->filter))) {
if (!(pv->dev = dev_cache_get(name, fid->fmt->cmd->filter))) {
log_error("%s: Couldn't find device.", name);
goto bad;
}
@@ -240,9 +251,10 @@ struct physical_volume *pv_create(struct format_instance *fi,
pv->pe_size = 0;
pv->pe_start = 0;
pv->pe_count = 0;
pv->pe_allocated = 0;
pv->pe_alloc_count = 0;
pv->fid = fid;
if (!fi->ops->pv_setup(fi, pv, NULL)) {
if (!fid->fmt->ops->pv_setup(fid, pv, NULL)) {
log_error("%s: Format-specific setup of physical volume "
"failed.", name);
goto bad;
@@ -324,3 +336,249 @@ struct physical_volume *find_pv(struct volume_group *vg, struct device *dev)
return NULL;
}
int vg_remove(struct volume_group *vg)
{
struct list *mdah;
void *mdl;
if (!vg->fid->fmt->ops->vg_remove)
return 1;
/* FIXME Improve recovery situation? */
/* Remove each copy of the metadata */
list_iterate(mdah, &vg->fid->metadata_areas) {
mdl = list_item(mdah, struct metadata_area)->metadata_locn;
if (!vg->fid->fmt->ops->vg_remove(vg->fid, vg, mdl)) {
stack;
return 0;
}
}
return 1;
}
int vg_write(struct volume_group *vg)
{
struct list *mdah;
void *mdl;
if (vg->status & PARTIAL_VG) {
log_error("Cannot change metadata for partial volume group %s",
vg->name);
return 0;
}
vg->seqno++;
/* Write to each copy of the metadata area */
list_iterate(mdah, &vg->fid->metadata_areas) {
mdl = list_item(mdah, struct metadata_area)->metadata_locn;
if (!vg->fid->fmt->ops->vg_write(vg->fid, vg, mdl)) {
stack;
return 0;
}
}
if (!vg->fid->fmt->ops->vg_commit)
return 1;
/* Commit to each copy of the metadata area */
list_iterate(mdah, &vg->fid->metadata_areas) {
mdl = list_item(mdah, struct metadata_area)->metadata_locn;
if (!vg->fid->fmt->ops->vg_commit(vg->fid, vg, mdl)) {
stack;
return 0;
}
}
return 1;
}
struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name)
{
struct format_instance *fid;
struct format_type *fmt;
struct volume_group *vg, *correct_vg;
struct list *mdah, *names;
void *mdl;
int inconsistent = 0, first_time = 1;
/* create format instance with appropriate metadata area */
if (!(fmt = vgcache_find_format(vg_name))) {
/* Do full scan */
if (!(names = get_vgs(cmd))) {
stack;
return NULL;
}
pool_free(cmd->mem, names);
if (!(fmt = vgcache_find_format(vg_name))) {
stack;
return NULL;
}
}
if (!(fid = fmt->ops->create_instance(fmt, vg_name, NULL))) {
log_error("Failed to create format instance");
return NULL;
}
/* Ensure contents of all metadata areas match - else do recovery */
list_iterate(mdah, &fid->metadata_areas) {
mdl = list_item(mdah, struct metadata_area)->metadata_locn;
if (!(vg = fid->fmt->ops->vg_read(fid, vg_name, mdl))) {
inconsistent = 1;
continue;
}
if (first_time) {
correct_vg = vg;
first_time = 0;
continue;
}
if (correct_vg->seqno != vg->seqno) {
inconsistent = 1;
if (vg->seqno > correct_vg->seqno)
correct_vg = vg;
}
}
/* Failed to find VG */
if (first_time) {
stack;
return NULL;
}
if (inconsistent) {
log_print("Inconsistent metadata copies found - updating "
"to use version %u", correct_vg->seqno);
if (!vg_write(correct_vg)) {
log_error("Automatic metadata correction failed");
return NULL;
}
}
vgcache_add(vg_name, correct_vg->id.uuid, NULL, fmt);
return correct_vg;
}
struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid)
{
char *vgname;
struct list *vgs, *vgh;
struct volume_group *vg;
if (!(vgs = get_vgs(cmd))) {
log_error("vg_read_by_vgid: get_vgs failed");
return NULL;
}
list_iterate(vgh, vgs) {
vgname = list_item(vgh, struct name_list)->name;
if ((vg = vg_read(cmd, vgname)) &&
!strncmp(vg->id.uuid, vgid, ID_LEN)) return vg;
}
pool_free(cmd->mem, vgs);
return NULL;
}
/* FIXME Use label functions instead of PV functions? */
struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name)
{
struct physical_volume *pv;
if (!(pv = pool_zalloc(cmd->mem, sizeof(*pv)))) {
log_error("pv_list allocation for '%s' failed", pv_name);
return 0;
}
/* Member of a format1 VG? */
if (!(cmd->fmt1->ops->pv_read(cmd->fmt1, pv_name, pv))) {
log_error("Failed to read existing physical volume '%s'",
pv_name);
return 0;
}
/* Member of a format_text VG? */
if (!(cmd->fmtt->ops->pv_read(cmd->fmtt, pv_name, pv))) {
log_error("Failed to read existing physical volume '%s'",
pv_name);
return 0;
}
if (!pv->size)
return NULL;
else
return pv;
}
struct list *get_vgs(struct cmd_context *cmd)
{
struct list *names;
if (!(names = pool_alloc(cmd->mem, sizeof(*names)))) {
log_error("VG name list allocation failed");
return NULL;
}
list_init(names);
if (!cmd->fmt1->ops->get_vgs(cmd->fmt1, names) ||
!cmd->fmtt->ops->get_vgs(cmd->fmtt, names) ||
list_empty(names)) {
pool_free(cmd->mem, names);
return NULL;
}
return names;
}
struct list *get_pvs(struct cmd_context *cmd)
{
struct list *results;
if (!(results = pool_alloc(cmd->mem, sizeof(*results)))) {
log_error("PV list allocation failed");
return NULL;
}
list_init(results);
/* fmtt modifies fmt1 output */
if (!cmd->fmt1->ops->get_pvs(cmd->fmt1, results) ||
!cmd->fmtt->ops->get_pvs(cmd->fmtt, results)) {
pool_free(cmd->mem, results);
return NULL;
}
return results;
}
int pv_write(struct cmd_context *cmd, struct physical_volume *pv)
{
struct list *mdah;
void *mdl;
/* Write to each copy of the metadata area */
list_iterate(mdah, &pv->fid->metadata_areas) {
mdl = list_item(mdah, struct metadata_area)->metadata_locn;
if (!pv->fid->fmt->ops->pv_write(pv->fid, pv, mdl)) {
stack;
return 0;
}
}
if (!pv->fid->fmt->ops->pv_commit)
return 1;
/* Commit to each copy of the metadata area */
list_iterate(mdah, &pv->fid->metadata_areas) {
mdl = list_item(mdah, struct metadata_area)->metadata_locn;
if (!pv->fid->fmt->ops->pv_commit(pv->fid, pv, mdl)) {
stack;
return 0;
}
}
return 1;
}

View File

@@ -23,6 +23,7 @@
#define STRIPE_SIZE_MIN ( PAGE_SIZE/SECTOR_SIZE) /* PAGESIZE in sectors */
#define STRIPE_SIZE_MAX ( 512L * 1024 / SECTOR_SIZE) /* 512 KB in sectors */
#define PV_MIN_SIZE ( 512L * 1024 / SECTOR_SIZE) /* 512 KB in sectors */
#define PE_ALIGN (65536UL / SECTOR_SIZE) /* PE alignment */
/* Various flags */
@@ -51,10 +52,15 @@
#define ALLOC_STRICT 0x00002000 /* LV */
#define ALLOC_CONTIGUOUS 0x00004000 /* LV */
#define FMT_SEGMENTS 0x00000001 /* Arbitrary segment parameters? */
#define FMT_TEXT_NAME "text"
#define FMT_LVM1_NAME "lvm1"
struct physical_volume {
struct id id;
struct device *dev;
struct format_instance *fid;
char *vg_name;
uint32_t status;
@@ -64,13 +70,33 @@ struct physical_volume {
uint64_t pe_size;
uint64_t pe_start;
uint32_t pe_count;
uint32_t pe_allocated; /* FIXME: change the name to alloc_count ? */
uint32_t pe_alloc_count;
};
struct cmd_context;
struct format_type {
struct cmd_context *cmd;
struct format_handler *ops;
const char *name;
uint32_t features;
void *private;
};
struct metadata_area {
struct list list;
void *metadata_locn;
};
struct format_instance {
struct format_type *fmt;
struct list metadata_areas; /* e.g. metadata locations */
};
struct volume_group {
struct cmd_context *cmd;
struct format_instance *fid;
uint32_t seqno; /* Metadata sequence number */
struct id id;
char *name;
@@ -159,11 +185,6 @@ struct snapshot_list {
struct snapshot *snapshot;
};
struct format_instance {
struct cmd_context *cmd;
struct format_handler *ops;
void *private;
};
/*
@@ -173,18 +194,19 @@ struct format_handler {
/*
* Returns a name_list of vg's.
*/
struct list *(*get_vgs)(struct format_instance *fi);
struct list *(*get_vgs)(struct format_type *fmt, struct list *names);
/*
* Returns pv_list of fully-populated pv structures.
*/
struct list *(*get_pvs)(struct format_instance *fi);
struct list *(*get_pvs)(struct format_type *fmt, struct list *results);
/*
* Return PV with given path.
*/
struct physical_volume *(*pv_read)(struct format_instance *fi,
const char *pv_name);
int (*pv_read)(struct format_type *fmt,
const char *pv_name,
struct physical_volume *pv);
/*
* Tweak an already filled out a pv ready for importing into a
@@ -197,8 +219,10 @@ struct format_handler {
* Write a PV structure to disk. Fails if the PV is in a VG ie
* pv->vg_name must be null.
*/
int (*pv_write)(struct format_instance *fi,
struct physical_volume *pv);
int (*pv_write)(struct format_instance *fi, struct physical_volume *pv,
void *mdl);
int (*pv_commit)(struct format_instance *fid,
struct physical_volume *pv, void *mdl);
/*
* Tweak an already filled out a lv eg, check there
@@ -211,13 +235,16 @@ struct format_handler {
* specific.
*/
int (*vg_setup)(struct format_instance *fi, struct volume_group *vg);
int (*vg_remove)(struct format_instance *fi, struct volume_group *vg,
void *mdl);
/*
* The name may be prefixed with the dev_dir from the
* job_context.
* mdl is the metadata location to use
*/
struct volume_group *(*vg_read)(struct format_instance *fi,
const char *vg_name);
const char *vg_name, void *mdl);
/*
* Write out complete VG metadata. You must ensure internal
@@ -233,25 +260,50 @@ struct format_handler {
* in the volume_group structure it is handed. Note: format1
* does read all pv's currently.
*/
int (*vg_write)(struct format_instance *fi, struct volume_group *vg);
int (*vg_write)(struct format_instance *fid, struct volume_group *vg,
void *mdl);
int (*vg_commit)(struct format_instance *fid, struct volume_group *vg,
void *mdl);
/*
* Create format instance with a particular metadata area
*/
struct format_instance *(*create_instance)(struct format_type *fmt,
const char *vgname,
void *context);
/*
* Destructor for this object.
* Destructor for format instance
*/
void (*destroy)(struct format_instance *fi);
void (*destroy_instance)(struct format_instance *fid);
/*
* Destructor for format type
*/
void (*destroy)(struct format_type *fmt);
};
/*
* Utility functions
*/
int vg_write(struct volume_group *vg);
struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name);
struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid);
struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name);
struct list *get_pvs(struct cmd_context *cmd);
struct list *get_vgs(struct cmd_context *cmd);
int pv_write(struct cmd_context *cmd, struct physical_volume *pv);
struct physical_volume *pv_create(struct format_instance *fi,
const char *name,
struct id *id,
uint64_t size);
struct volume_group *vg_create(struct format_instance *fi, const char *name,
struct volume_group *vg_create(struct cmd_context *cmd, const char *name,
uint32_t extent_size, int max_pv, int max_lv,
int pv_count, char **pv_names);
int vg_remove(struct volume_group *vg);
/*
* This needs the format instance to check the
@@ -341,6 +393,8 @@ int lv_is_origin(struct logical_volume *lv);
int lv_is_cow(struct logical_volume *lv);
struct snapshot *find_cow(struct logical_volume *lv);
struct snapshot *find_origin(struct logical_volume *lv);
struct list *find_snapshots(struct logical_volume *lv);
int vg_add_snapshot(struct logical_volume *origin,
struct logical_volume *cow,

View File

@@ -36,6 +36,20 @@ int lv_is_cow(struct logical_volume *lv)
return 0;
}
struct snapshot *find_origin(struct logical_volume *lv)
{
struct list *slh;
struct snapshot *s;
list_iterate(slh, &lv->vg->snapshots) {
s = list_item(slh, struct snapshot_list)->snapshot;
if (s->origin == lv)
return s;
}
return NULL;
}
struct snapshot *find_cow(struct logical_volume *lv)
{
struct list *slh;
@@ -50,10 +64,40 @@ struct snapshot *find_cow(struct logical_volume *lv)
return NULL;
}
struct list *find_snapshots(struct logical_volume *lv)
{
struct list *slh;
struct list *snaplist;
struct snapshot *s;
struct snapshot_list *newsl;
struct pool *mem = lv->vg->cmd->mem;
if (!(snaplist = pool_alloc(mem, sizeof(*snaplist)))) {
log_error("snapshot name list allocation failed");
return NULL;
}
list_init(snaplist);
list_iterate(slh, &lv->vg->snapshots) {
s = list_item(slh, struct snapshot_list)->snapshot;
if (!(s->origin == lv))
continue;
if (!(newsl = pool_alloc(mem, sizeof(*newsl)))) {
log_error("snapshot_list structure allocation failed");
pool_free(mem, snaplist);
return NULL;
}
newsl->snapshot = s;
list_add(snaplist, &newsl->list);
}
return snaplist;
}
int vg_add_snapshot(struct logical_volume *origin,
struct logical_volume *cow,
int persistent,
uint32_t chunk_size)
int persistent, uint32_t chunk_size)
{
struct snapshot *s;
struct snapshot_list *sl;

View File

@@ -7,6 +7,7 @@
#include "log.h"
#include "lvm-file.h"
#include "lvm-string.h"
#include "dbg_malloc.h"
#include <stdlib.h>
#include <unistd.h>
@@ -128,7 +129,37 @@ int dir_exists(const char *path)
return 1;
}
/* FIXME: Make this create directories recursively */
static int _create_dir_recursive(const char *dir)
{
char *orig, *s;
int rc;
log_verbose("Creating directory \"%s\"", dir);
/* Create parent directories */
orig = s = dbg_strdup(dir);
while ((s = strchr(s, '/')) != NULL) {
*s = '\0';
if (*orig) {
rc = mkdir(orig, 0777);
if (rc < 0 && errno != EEXIST) {
log_sys_error("mkdir", orig);
dbg_free(orig);
return 0;
}
}
*s++ = '/';
}
dbg_free(orig);
/* Create final directory */
rc = mkdir(dir, 0777);
if (rc < 0 && errno != EEXIST) {
log_sys_error("mkdir", dir);
return 0;
}
return 1;
}
int create_dir(const char *dir)
{
struct stat info;
@@ -136,13 +167,8 @@ int create_dir(const char *dir)
if (!*dir)
return 1;
if (stat(dir, &info) < 0) {
log_verbose("Creating directory \"%s\"", dir);
if (!mkdir(dir, 0777))
return 1;
log_sys_error("mkdir", dir);
return 0;
}
if (stat(dir, &info) < 0)
return _create_dir_recursive(dir);
if (S_ISDIR(info.st_mode))
return 1;

View File

@@ -28,7 +28,7 @@ int dir_exists(const char *path);
int is_empty_dir(const char *dir);
/*
* Create directory (but not recursively) if necessary
* Return 1 if directory exists on return, else 0
* Create directory (recursively) if necessary. Return 1
* if directory was successfully created (or already exists), else 0.
*/
int create_dir(const char *dir);

View File

@@ -26,7 +26,8 @@ static struct {
unsigned int blocks, mblocks;
unsigned int bytes, mbytes;
} _mem_stats = {0, 0, 0, 0};
} _mem_stats = {
0, 0, 0, 0};
static struct memblock *_head = 0;
static struct memblock *_tail = 0;

View File

@@ -225,7 +225,8 @@ struct chunk *_new_chunk(struct pool *p, size_t s)
p->spare_chunk = 0;
} else {
if (!(c = dbg_malloc(s))) {
log_err("Out of memory. Requested %" PRIuPTR " bytes.", s);
log_err("Out of memory. Requested %" PRIuPTR " bytes.",
s);
return NULL;
}
@@ -238,4 +239,3 @@ struct chunk *_new_chunk(struct pool *p, size_t s)
return c;
}

View File

@@ -1,32 +1,17 @@
/*
* Copyright (C) 2001 Sistina Software (UK) Limited.
*
* This file is released under the GPL.
* This file is released under the LGPL.
*
*/
#ifndef _LVM_XLATE_H
#define _LVM_XLATE_H
/* FIXME: finish these as inlines */
#include <asm/byteorder.h>
uint16_t shuffle16(uint16_t n);
uint32_t shuffle32(uint32_t n);
uint64_t shuffle64(uint64_t n);
/* xlate functions move data between core and disk */
#if __BYTE_ORDER == __BIG_ENDIAN
# define xlate16(x) shuffle16(x)
# define xlate32(x) shuffle32(x)
# define xlate64(x) shuffle64(x)
#elif __BYTE_ORDER == __LITTLE_ENDIAN
# define xlate16(x) (x)
# define xlate32(x) (x)
# define xlate64(x) (x)
#else
# error "__BYTE_ORDER must be defined as __LITTLE_ENDIAN or __BIG_ENDIAN"
#endif
#define xlate16(x) __cpu_to_le16((x));
#define xlate32(x) __cpu_to_le32((x));
#define xlate64(x) __cpu_to_le64((x));
#endif

View File

@@ -221,13 +221,13 @@ static int _calc_states(struct matcher *m, struct rx_node *rx)
for (a = 0; a < 256; a++) {
/* iterate through all the states in firstpos */
for (i = bit_get_first(dfa_bits);
i >=0;
i = bit_get_next(dfa_bits, i)) {
i >= 0; i = bit_get_next(dfa_bits, i)) {
if (bit(m->nodes[i]->charset, a)) {
if (a == TARGET_TRANS)
dfa->final = m->nodes[i]->final;
bit_union(bs, bs, m->nodes[i]->followpos);
bit_union(bs, bs,
m->nodes[i]->followpos);
set_bits = 1;
}
}
@@ -238,7 +238,9 @@ static int _calc_states(struct matcher *m, struct rx_node *rx)
/* push */
ldfa = _create_dfa_state(m->mem);
ttree_insert(tt, bs + 1, ldfa);
tmp = _create_state_queue(m->scratch, ldfa, bs);
tmp =
_create_state_queue(m->scratch,
ldfa, bs);
if (!h)
h = t = tmp;
else {
@@ -260,8 +262,7 @@ static int _calc_states(struct matcher *m, struct rx_node *rx)
return 1;
}
struct matcher *matcher_create(struct pool *mem,
const char **patterns, int num)
struct matcher *matcher_create(struct pool *mem, const char **patterns, int num)
{
char *all, *ptr;
int i, len = 0;
@@ -293,8 +294,7 @@ struct matcher *matcher_create(struct pool *mem,
}
for (i = 0; i < num; i++) {
ptr += sprintf(ptr, "(.*(%s)%c)", patterns[i],
TARGET_TRANS);
ptr += sprintf(ptr, "(.*(%s)%c)", patterns[i], TARGET_TRANS);
if (i < (num - 1))
*ptr++ = '|';
}

View File

@@ -12,7 +12,6 @@
#include <stdlib.h>
#include <stdio.h>
struct parse_sp { /* scratch pad for the parsing process */
struct pool *mem;
int type; /* token type, 0 indicates a charset */
@@ -21,10 +20,8 @@ struct parse_sp { /* scratch pad for the parsing process */
const char *rx_end; /* 1pte for the expression being parsed */
};
static struct rx_node *_or_term(struct parse_sp *ps);
/*
* Get the next token from the regular expression.
* Returns: 1 success, 0 end of input, -1 error.
@@ -59,9 +56,15 @@ static int _get_token(struct parse_sp *ps)
/* an escaped character */
ptr++;
switch (*ptr) {
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'n':
c = '\n';
break;
case 'r':
c = '\r';
break;
case 't':
c = '\t';
break;
default:
c = *ptr;
}
@@ -152,9 +155,15 @@ static int _get_token(struct parse_sp *ps)
ps->cursor = ptr + 1;
bit_clear_all(ps->charset);
switch (*ptr) {
case 'n': bit_set(ps->charset, (int) '\n'); break;
case 'r': bit_set(ps->charset, (int) '\r'); break;
case 't': bit_set(ps->charset, (int) '\t'); break;
case 'n':
bit_set(ps->charset, (int) '\n');
break;
case 'r':
bit_set(ps->charset, (int) '\r');
break;
case 't':
bit_set(ps->charset, (int) '\t');
break;
default:
bit_set(ps->charset, (int) *ptr);
}

View File

@@ -74,7 +74,6 @@ int ttree_insert(struct ttree *tt, unsigned int *key, void *data)
} while (*c && count);
if (!*c) {
count++;

View File

@@ -19,6 +19,14 @@ static unsigned char _c[] =
static int _built_inverse;
static unsigned char _inverse_c[256];
int lvid_create(union lvid *lvid, struct id *vgid)
{
memcpy(lvid->id, vgid, sizeof(*lvid->id));
id_create(&lvid->id[1]);
return 1;
}
int lvid_from_lvnum(union lvid *lvid, struct id *vgid, int lv_num)
{
int i;

View File

@@ -28,6 +28,7 @@ union lvid {
int lvid_from_lvnum(union lvid *lvid, struct id *vgid, int lv_num);
int lvnum_from_lvid(union lvid *lvid);
int lvid_create(union lvid *lvid, struct id *vgid);
int id_create(struct id *id);
int id_valid(struct id *id);
int id_equal(struct id *lhs, struct id *rhs);

View File

@@ -50,6 +50,22 @@ struct list *vgcache_find(const char *vg_name)
return &vgn->pvdevs;
}
struct format_type *vgcache_find_format(const char *vg_name)
{
struct vgname_entry *vgn;
if (!_vghash)
return NULL;
if (!vg_name)
vg_name = all_devices;
if (!(vgn = hash_lookup(_vghash, vg_name)))
return NULL;
return vgn->fmt;
}
struct list *vgcache_find_by_vgid(const char *vgid)
{
struct vgname_entry *vgn;
@@ -78,7 +94,8 @@ void vgcache_del_orphan(struct device *dev)
}
}
int vgcache_add_entry(const char *vg_name, const char *vgid, struct device *dev)
int vgcache_add_entry(const char *vg_name, const char *vgid, struct device *dev,
struct format_type *fmt)
{
const char *pv_name;
struct vgname_entry *vgn;
@@ -92,6 +109,7 @@ int vgcache_add_entry(const char *vg_name, const char *vgid, struct device *dev)
}
memset(vgn, 0, sizeof(struct vgname_entry));
vgn->fmt = fmt;
pvdevs = &vgn->pvdevs;
list_init(pvdevs);
@@ -104,18 +122,25 @@ int vgcache_add_entry(const char *vg_name, const char *vgid, struct device *dev)
log_error("vgcache_add: VG hash insertion failed");
return 0;
}
} else if (!(vgn = hash_lookup(_vghash, vg_name))) {
log_error("vgcache_add: VG name entry %s not found", vg_name);
return 0;
}
if (vgid && strncmp(vgid, vgn->vgid, ID_LEN)) {
hash_remove(_vgidhash, vgn->vgid);
if (vgid) {
memcpy(vgn->vgid, vgid, ID_LEN);
vgn->vgid[ID_LEN] = '\0';
if (!hash_insert(_vgidhash, vgn->vgid, vgn)) {
log_error("vgcache_add: vgid hash insertion "
"failed");
log_error("vgcache_add: vgid hash insertion " "failed");
return 0;
}
}
}
if (!dev)
return 1;
list_iterate(pvdh, pvdevs) {
pvdev = list_item(pvdh, struct pvdev_list);
@@ -150,21 +175,25 @@ int vgcache_add_entry(const char *vg_name, const char *vgid, struct device *dev)
}
/* vg_name of "\0" is an orphan PV; NULL means only add to all_devices */
int vgcache_add(const char *vg_name, const char *vgid, struct device *dev)
int vgcache_add(const char *vg_name, const char *vgid, struct device *dev,
struct format_type *fmt)
{
if (!_vghash && !vgcache_init())
return 0;
/* If orphan PV remove it */
if (vg_name && !*vg_name)
if (dev && vg_name && !*vg_name)
vgcache_del_orphan(dev);
/* Add PV if vg_name supplied */
if (vg_name && *vg_name && !vgcache_add_entry(vg_name, vgid, dev))
if (vg_name && *vg_name && !vgcache_add_entry(vg_name, vgid, dev, fmt))
return 0;
/* Always add to all_devices */
return vgcache_add_entry(all_devices, NULL, dev);
/* Add to all_devices */
if (dev)
return vgcache_add_entry(all_devices, NULL, dev, fmt);
return 1;
}
void vgcache_destroy_entry(struct vgname_entry *vgn)
@@ -208,7 +237,6 @@ void vgcache_del(const char *vg_name)
vgcache_destroy_entry(vgn);
}
void vgcache_del_by_vgid(const char *vgid)
{
struct vgname_entry *vgn;
@@ -230,7 +258,6 @@ void vgcache_del_by_vgid(const char *vgid)
vgcache_destroy_entry(vgn);
}
void vgcache_destroy()
{
if (_vghash) {
@@ -266,4 +293,3 @@ char *vgname_from_vgid(struct cmd_context *cmd, struct id *vgid)
return pool_strdup(cmd->mem, vgn->vgname);
}

View File

@@ -19,6 +19,7 @@ struct vgname_entry {
struct list pvdevs;
char *vgname;
char vgid[ID_LEN + 1];
struct format_type *fmt;
};
struct pvdev_list {
@@ -31,13 +32,15 @@ void vgcache_destroy();
/* Return list of PVs in named VG */
struct list *vgcache_find(const char *vg_name);
struct format_type *vgcache_find_format(const char *vg_name);
struct list *vgcache_find_by_vgid(const char *vgid);
/* FIXME Temporary function */
char *vgname_from_vgid(struct cmd_context *cmd, struct id *vgid);
/* Add/delete a device */
int vgcache_add(const char *vg_name, const char *vgid, struct device *dev);
int vgcache_add(const char *vg_name, const char *vgid, struct device *dev,
struct format_type *fmt);
void vgcache_del(const char *vg_name);
#endif

View File

@@ -35,9 +35,19 @@ static char *dm_cmd_list[] = {
"info",
"deps",
"rename",
"version"
"version",
"status",
"table",
"waitevent"
};
static void *_align(void *ptr, unsigned int a)
{
register unsigned long align = --a;
return (void *) (((unsigned long) ptr + align) & ~align);
}
void dm_task_destroy(struct dm_task *dmt)
{
struct target *t, *n;
@@ -74,6 +84,49 @@ int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size)
return 1;
}
void *dm_get_next_target(struct dm_task *dmt, void *next,
uint64_t *start, uint64_t *length,
char **target_type, char **params)
{
struct target *t = (struct target *) next;
if (!t)
t = dmt->head;
if (!t)
return NULL;
*start = t->start;
*length = t->length;
*target_type = t->type;
*params = t->params;
return t->next;
}
/* Unmarshall the target info returned from a status call */
static int _unmarshal_status(struct dm_task *dmt, struct dm_ioctl *dmi)
{
char *outbuf = (char *) dmi + sizeof(struct dm_ioctl);
char *outptr = outbuf;
int i;
for (i = 0; i < dmi->target_count; i++) {
struct dm_target_spec *spec = (struct dm_target_spec *) outptr;
if (!dm_task_add_target(dmt, spec->sector_start, spec->length,
spec->target_type,
outptr + sizeof(*spec)))
return 0;
outptr += sizeof(struct dm_target_spec);
outptr += strlen(outptr) + 1;
_align(outptr, ALIGNMENT);
}
return 1;
}
int dm_task_get_info(struct dm_task *dmt, struct dm_info *info)
{
if (!dmt->dmi)
@@ -121,8 +174,8 @@ int dm_task_set_newname(struct dm_task *dmt, const char *newname)
return 1;
}
struct target *create_target(uint64_t start,
uint64_t len, const char *type, const char *params)
struct target *create_target(uint64_t start, uint64_t len, const char *type,
const char *params)
{
struct target *t = malloc(sizeof(*t));
@@ -154,13 +207,6 @@ struct target *create_target(uint64_t start,
return NULL;
}
static void *_align(void *ptr, unsigned int a)
{
register unsigned long align = --a;
return (void *) (((unsigned long) ptr + align) & ~align);
}
static void *_add_target(struct target *t, void *out, void *end)
{
void *out_sp = out;
@@ -334,6 +380,19 @@ int dm_task_run(struct dm_task *dmt)
command = DM_VERSION;
break;
case DM_DEVICE_STATUS:
command = DM_GET_STATUS;
break;
case DM_DEVICE_TABLE:
dmi->flags |= DM_STATUS_TABLE_FLAG;
command = DM_GET_STATUS;
break;
case DM_DEVICE_WAITEVENT:
command = DM_WAIT_EVENT;
break;
default:
log_error("Internal error: unknown device-mapper task %d",
dmt->type);
@@ -360,6 +419,12 @@ int dm_task_run(struct dm_task *dmt)
case DM_DEVICE_RENAME:
rename_dev_node(dmt->dev_name, dmt->newname);
break;
case DM_DEVICE_STATUS:
case DM_DEVICE_TABLE:
if (!_unmarshal_status(dmt, dmi))
goto bad;
break;
}
dmt->dmi = dmi;

View File

@@ -44,6 +44,10 @@ enum {
DM_DEVICE_RENAME,
DM_DEVICE_VERSION,
DM_DEVICE_STATUS,
DM_DEVICE_TABLE,
DM_DEVICE_WAITEVENT
};
struct dm_task;
@@ -91,6 +95,11 @@ int dm_task_add_target(struct dm_task *dmt,
uint64_t start,
uint64_t size, const char *ttype, const char *params);
/* Use this to retrive target information returned from a STATUS call */
void *dm_get_next_target(struct dm_task *dmt,
void *next, uint64_t *start, uint64_t *length,
char **target_type, char **params);
/*
* Call this to actually run the ioctl.
*/

View File

@@ -52,7 +52,8 @@ SOURCES=\
vgreduce.c \
vgremove.c \
vgrename.c \
vgscan.c
vgscan.c \
vgsplit.c
TARGETS=\
.commands \

View File

@@ -157,6 +157,7 @@ static int __backup(struct volume_group *vg)
struct format_instance *tf;
char name[PATH_MAX];
char *desc;
void *context;
if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 0))) {
stack;
@@ -172,15 +173,19 @@ static int __backup(struct volume_group *vg)
log_verbose("Creating volume group backup \"%s\"", name);
if (!(tf = text_format_create(vg->cmd, name, vg->cmd->um, desc))) {
if (!(context = create_text_context(vg->cmd->fmtt, name, desc)) ||
!(tf = vg->cmd->fmtt->ops->create_instance(vg->cmd->fmtt, NULL,
context))) {
stack;
return 0;
}
if (!(r = tf->ops->vg_write(tf, vg)))
if (!(r = tf->fmt->ops->vg_write(tf, vg, context)) ||
!(r = tf->fmt->ops->vg_commit(tf, vg, context)))
stack;
tf->ops->destroy(tf);
tf->fmt->ops->destroy_instance(tf);
return r;
}
@@ -227,16 +232,19 @@ static struct volume_group *_read_vg(struct cmd_context *cmd,
{
struct volume_group *vg;
struct format_instance *tf;
void *context;
if (!(tf = text_format_create(cmd, file, cmd->um, cmd->cmd_line))) {
if (!(context = create_text_context(cmd->fmtt, file,
cmd->cmd_line)) ||
!(tf = cmd->fmtt->ops->create_instance(cmd->fmtt, NULL, context))) {
log_error("Couldn't create text format object.");
return NULL;
}
if (!(vg = tf->ops->vg_read(tf, vg_name)))
if (!(vg = tf->fmt->ops->vg_read(tf, vg_name, context)))
stack;
tf->ops->destroy(tf);
tf->fmt->ops->destroy_instance(tf);
return vg;
}
@@ -264,7 +272,15 @@ int backup_restore_from_file(struct cmd_context *cmd, const char *vg_name,
/*
* Write the vg.
*/
if (!cmd->fid->ops->vg_write(cmd->fid, vg)) {
/* FIXME How do I find what format to write out the VG in? */
/* Must store the format type inside the backup? */
if (!(vg->fid = cmd->fmt1->ops->create_instance(cmd->fmt1, NULL, NULL))) {
log_error("Failed to allocate format1 instance");
return 0;
}
if (!vg_write(vg)) {
stack;
return 0;
}

View File

@@ -46,6 +46,7 @@ arg(list_ARG, 'l', "list", NULL)
arg(size_ARG, 'L', "size", size_arg)
arg(logicalextent_ARG, 'L', "logicalextent", int_arg_with_sign)
arg(persistent_ARG, 'M', "persistent", yes_no_arg)
arg(metadatatype_ARG, 'M', "metadatatype", metadatatype_arg)
arg(minor_ARG, 'm', "minor", minor_arg)
arg(maps_ARG, 'm', "maps", NULL)
arg(name_ARG, 'n', "name", string_arg)

View File

@@ -87,9 +87,8 @@ xx(lvcreate,
"\t[--version]\n"
"\tVolumeGroupName [PhysicalVolumePath...]\n\n",
autobackup_ARG, chunksize_ARG,
contiguous_ARG, extents_ARG, minor_ARG, name_ARG,
permission_ARG, persistent_ARG, readahead_ARG, size_ARG,
autobackup_ARG, chunksize_ARG, contiguous_ARG, extents_ARG, minor_ARG,
name_ARG, permission_ARG, persistent_ARG, readahead_ARG, size_ARG,
snapshot_ARG, stripes_ARG, stripesize_ARG, test_ARG, zero_ARG)
xx(lvdisplay,
@@ -227,10 +226,11 @@ xx(lvscan,
"\t[-d|--debug] " "\n"
"\t[-D|--disk]" "\n"
"\t[-h|--help] " "\n"
"\t[-P|--partial] " "\n"
"\t[-v|--verbose] " "\n"
"\t[--version]\n",
blockdevice_ARG, disk_ARG)
blockdevice_ARG, disk_ARG, partial_ARG)
xx(pvchange,
"Change attributes of physical volume(s)",
@@ -328,12 +328,13 @@ xx(pvscan,
"\t[-d|--debug] " "\n"
"\t{-e|--exported | -n/--novolumegroup} " "\n"
"\t[-h|--help]" "\n"
"\t[-P|--partial] " "\n"
"\t[-s|--short] " "\n"
"\t[-u|--uuid] " "\n"
"\t[-v|--verbose] " "\n"
"\t[--version]\n",
exported_ARG, novolumegroup_ARG, short_ARG, uuid_ARG)
exported_ARG, novolumegroup_ARG, partial_ARG, short_ARG, uuid_ARG)
xx(vgcfgbackup,
"Backup volume group configuration(s)",
@@ -393,9 +394,10 @@ xx(vgcreate,
"vgcreate" "\n"
"\t[-A|--autobackup {y|n}] " "\n"
"\t[-d|--debug]" "\n"
"\t[-l|--maxlogicalvolumes MaxLogicalVolumes]" "\n"
"\t[-p|--maxphysicalvolumes MaxPhysicalVolumes] " "\n"
"\t[-h|--help]" "\n"
"\t[-l|--maxlogicalvolumes MaxLogicalVolumes]" "\n"
"\t[-M|--metadatatype lvm1/text] " "\n"
"\t[-p|--maxphysicalvolumes MaxPhysicalVolumes] " "\n"
"\t[-s|--physicalextentsize PhysicalExtentSize[kKmMgGtT]] " "\n"
"\t[-t|--test] " "\n"
"\t[-v|--verbose]" "\n"
@@ -403,7 +405,7 @@ xx(vgcreate,
"\tVolumeGroupName PhysicalVolume [PhysicalVolume...]\n",
autobackup_ARG, maxlogicalvolumes_ARG, maxphysicalvolumes_ARG,
physicalextentsize_ARG, test_ARG)
metadatatype_ARG, physicalextentsize_ARG, test_ARG)
xx(vgdisplay,
"Display volume group information",
@@ -520,7 +522,9 @@ xx(vgscan,
"vgscan "
"\t[-d/--debug]\n"
"\t[-h/-?/--help]\n"
"\t[-v/--verbose]\n" )
"\t[-P/--partial] " "\n"
"\t[-v/--verbose]\n" ,
partial_ARG)
xx(vgsplit,
"Move physical volumes into a new volume group",
@@ -529,13 +533,14 @@ xx(vgsplit,
"\t[-d|--debug] " "\n"
"\t[-h|--help] " "\n"
"\t[-l|--list]" "\n"
"\t[-M|--metadatatype lvm1/text] " "\n"
"\t[-t|--test] " "\n"
"\t[-v|--verbose] " "\n"
"\t[--version]" "\n"
"\tExistingVolumeGroupName NewVolumeGroupName" "\n"
"\tPhysicalVolumePath [PhysicalVolumePath...]\n",
autobackup_ARG, list_ARG, test_ARG)
autobackup_ARG, list_ARG, metadatatype_ARG, test_ARG)
xx(version,
"Display software and driver version information",

View File

@@ -227,6 +227,53 @@ static int _resume(int argc, char **argv)
return _simple(DM_DEVICE_RESUME, argv[1]);
}
static int _wait(int argc, char **argv)
{
return _simple(DM_DEVICE_WAITEVENT, argv[1]);
}
static int _status(int argc, char **argv)
{
int r = 0;
struct dm_task *dmt;
void *next = NULL;
uint64_t start, length;
char *target_type = NULL;
char *params;
int cmd;
if (!strcmp(argv[0], "status"))
cmd = DM_DEVICE_STATUS;
else
cmd = DM_DEVICE_TABLE;
if (!(dmt = dm_task_create(cmd)))
return 0;
if (!dm_task_set_name(dmt, argv[1]))
goto out;
if (!dm_task_run(dmt))
goto out;
/* Fetch targets and print 'em */
do {
next = dm_get_next_target(dmt, next, &start, &length,
&target_type, &params);
if (target_type) {
printf("%"PRIu64" %"PRIu64" %s %s\n",
start, length, target_type, params);
}
} while (next);
r = 1;
out:
dm_task_destroy(dmt);
return r;
}
static int _info(int argc, char **argv)
{
int r = 0;
@@ -345,6 +392,9 @@ static struct command _commands[] = {
{"info", "<dev_name>", 1, 1, _info},
{"deps", "<dev_name>", 1, 1, _deps},
{"rename", "<dev_name> <new_name>", 2, 2, _rename},
{"status", "<dev_name>", 1, 1, _status},
{"table", "<dev_name>", 1, 1, _status},
{"wait", "<dev_name>", 1, 1, _wait},
{"version", "", 0, 0, _version},
{NULL, NULL, 0, 0, NULL}
};

View File

@@ -159,7 +159,7 @@ static int lvchange_permission(struct cmd_context *cmd,
}
log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
if (!cmd->fid->ops->vg_write(cmd->fid, lv->vg)) {
if (!(lv->vg)) {
/* FIXME: Attempt reversion? */
unlock_lv(cmd, lv->lvid.s);
return 0;
@@ -248,7 +248,7 @@ static int lvchange_contiguous(struct cmd_context *cmd,
}
log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
if (!cmd->fid->ops->vg_write(cmd->fid, lv->vg)) {
if (!vg_write(lv->vg)) {
/* FIXME: Attempt reversion? */
unlock_lv(cmd, lv->lvid.s);
return 0;
@@ -296,7 +296,7 @@ static int lvchange_readahead(struct cmd_context *cmd,
}
log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
if (!cmd->fid->ops->vg_write(cmd->fid, lv->vg)) {
if (!vg_write(lv->vg)) {
/* FIXME: Attempt reversion? */
unlock_lv(cmd, lv->lvid.s);
return 0;
@@ -348,7 +348,7 @@ static int lvchange_persistent(struct cmd_context *cmd,
}
log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
if (!cmd->fid->ops->vg_write(cmd->fid, lv->vg)) {
if (!vg_write(lv->vg)) {
/* FIXME: Attempt reversion? */
unlock_lv(cmd, lv->lvid.s);
return 0;

View File

@@ -36,8 +36,7 @@ struct lvcreate_params {
};
static int _read_name_params(struct lvcreate_params *lp,
struct cmd_context *cmd, int *pargc,
char ***pargv)
struct cmd_context *cmd, int *pargc, char ***pargv)
{
int argc = *pargc;
char **argv = *pargv, *ptr;
@@ -56,7 +55,7 @@ static int _read_name_params(struct lvcreate_params *lp,
lp->origin = argv[0];
(*pargv)++, (*pargc)--;
if (!(lp->vg_name = extract_vgname(cmd->fid, lp->origin))) {
if (!(lp->vg_name = extract_vgname(cmd, lp->origin))) {
log_err("The origin name should include the "
"volume group.");
return 0;
@@ -72,8 +71,7 @@ static int _read_name_params(struct lvcreate_params *lp,
* environment.
*/
if (!argc) {
if (!(lp->vg_name =
extract_vgname(cmd->fid, lp->lv_name))) {
if (!(lp->vg_name = extract_vgname(cmd, lp->lv_name))) {
log_err("Please provide a volume group name");
return 0;
}
@@ -85,7 +83,7 @@ static int _read_name_params(struct lvcreate_params *lp,
*/
if (lp->lv_name && strchr(lp->lv_name, '/')) {
if (!(lp->vg_name =
extract_vgname(cmd->fid, lp->lv_name)))
extract_vgname(cmd, lp->lv_name)))
return 0;
if (strcmp(lp->vg_name, argv[0])) {
@@ -109,8 +107,7 @@ static int _read_name_params(struct lvcreate_params *lp,
}
static int _read_size_params(struct lvcreate_params *lp,
struct cmd_context *cmd, int *pargc,
char ***pargv)
struct cmd_context *cmd, int *pargc, char ***pargv)
{
/*
* There are two mutually exclusive ways of specifying
@@ -195,7 +192,7 @@ static int _read_params(struct lvcreate_params *lp, struct cmd_context *cmd,
* Set the defaults.
*/
memset(lp, 0, sizeof(*lp));
lp->chunk_size = 2 * arg_int_value(cmd, chunksize_ARG, 32);
lp->chunk_size = 2 * arg_int_value(cmd, chunksize_ARG, 8);
log_verbose("setting chunksize to %d sectors.", lp->chunk_size);
if (!_read_name_params(lp, cmd, &argc, &argv) ||
@@ -311,7 +308,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
/* does VG exist? */
log_verbose("Finding volume group \"%s\"", lp->vg_name);
if (!(vg = cmd->fid->ops->vg_read(cmd->fid, lp->vg_name))) {
if (!(vg = vg_read(cmd, lp->vg_name))) {
log_error("Volume group \"%s\" doesn't exist", lp->vg_name);
return 0;
}
@@ -382,7 +379,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
return 0;
}
if (!(lv = lv_create(cmd->fid, lp->lv_name, status,
if (!(lv = lv_create(vg->fid, lp->lv_name, status,
lp->stripes, lp->stripe_size, lp->extents,
vg, pvh))) return 0;
@@ -401,7 +398,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
return 0;
/* store vg on disk(s) */
if (!cmd->fid->ops->vg_write(cmd->fid, vg))
if (!vg_write(vg))
return 0;
if (!lock_vol(cmd, lv->lvid.s, LCK_LV_ACTIVATE))
@@ -429,7 +426,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
}
/* store vg on disk(s) */
if (!cmd->fid->ops->vg_write(cmd->fid, vg))
if (!vg_write(vg))
return 0;
if (!unlock_lv(cmd, org->lvid.s)) {

View File

@@ -22,6 +22,7 @@
#include <ctype.h>
#include <time.h>
#include <stdlib.h>
#include <locale.h>
#ifdef READLINE_SUPPORT
#include <readline/readline.h>
@@ -65,10 +66,14 @@ struct config_info {
int verbose;
int test;
int syslog;
const char *msg_prefix;
int cmd_name; /* Show command name? */
int archive; /* should we archive ? */
int backup; /* should we backup ? */
struct format_type *fmt;
mode_t umask;
};
@@ -186,6 +191,20 @@ int yes_no_arg(struct arg *a)
return 1;
}
int metadatatype_arg(struct arg *a)
{
if (!strcasecmp(a->value, cmd->fmtt->name))
a->ptr = cmd->fmtt;
else if (!strcasecmp(a->value, cmd->fmt1->name))
a->ptr = cmd->fmt1;
else
return 0;
return 1;
}
int _get_int_arg(struct arg *a, char **ptr)
{
char *val;
@@ -572,11 +591,11 @@ int version(struct cmd_context *cmd, int argc, char **argv)
{
char version[80];
log_error("LVM version: %s", LVM_VERSION);
log_print("LVM version: %s", LVM_VERSION);
if (library_version(version, sizeof(version)))
log_error("Library version: %s", version);
log_print("Library version: %s", version);
if (driver_version(version, sizeof(version)))
log_error("Driver version: %s", version);
log_print("Driver version: %s", version);
return ECMD_PROCESSED;
}
@@ -665,8 +684,13 @@ static void _use_settings(struct config_info *settings)
init_verbose(settings->verbose);
init_test(settings->test);
init_msg_prefix(_default_settings.msg_prefix);
init_cmd_name(_default_settings.cmd_name);
archive_enable(settings->archive);
backup_enable(settings->backup);
cmd->fmt = arg_ptr_value(cmd, metadatatype_ARG, settings->fmt);
}
static char *_copy_command_line(struct pool *mem, int argc, char **argv)
@@ -793,7 +817,7 @@ static void __init_log(struct config_file *cf)
{
char *open_mode = "a";
const char *log_file, *prefix;
const char *log_file;
_default_settings.syslog =
find_config_int(cf->root, "log/syslog", '/', 1);
@@ -812,10 +836,15 @@ static void __init_log(struct config_file *cf)
init_verbose(_default_settings.verbose);
init_indent(find_config_int(cf->root, "log/indent", '/', 1));
if ((prefix = find_config_str(cf->root, "log/prefix", '/', 0)))
init_msg_prefix(prefix);
init_cmd_name(find_config_int(cf->root, "log/command_names", '/', 0));
_default_settings.msg_prefix = find_config_str(cf->root, "log/prefix",
'/', DEFAULT_MSG_PREFIX);
init_msg_prefix(_default_settings.msg_prefix);
_default_settings.cmd_name = find_config_int(cf->root,
"log/command_names", '/',
DEFAULT_CMD_NAME);
init_cmd_name(_default_settings.cmd_name);
_default_settings.test = find_config_int(cf->root, "global/test",
'/', 0);
@@ -1046,8 +1075,12 @@ static int init(void)
{
struct stat info;
char config_file[PATH_MAX] = "";
const char *format;
mode_t old_umask;
if (!setlocale(LC_ALL, ""))
log_error("setlocale failed");
if (!_get_env_vars())
return 0;
@@ -1078,15 +1111,13 @@ static int init(void)
return 0;
}
if (stat(config_file, &info) != -1) {
/* we've found a config file */
if (!read_config(cmd->cf, config_file)) {
if (stat(config_file, &info) != -1 &&
!read_config(cmd->cf, config_file)) {
log_error("Failed to load config file %s", config_file);
return 0;
}
__init_log(cmd->cf);
}
_default_settings.umask = find_config_int(cmd->cf->root,
"global/umask", '/',
@@ -1137,9 +1168,20 @@ static int init(void)
return 0;
}
if (!(cmd->fid = create_lvm1_format(cmd)))
/* FIXME Replace with list, dynamic libs etc. */
if (!(cmd->fmt1 = create_lvm1_format(cmd)))
return 0;
if (!(cmd->fmtt = create_text_format(cmd)))
return 0;
format = find_config_str(cmd->cf->root, "global/format", '/',
DEFAULT_FORMAT);
if (!strcasecmp(format, "text"))
_default_settings.fmt = cmd->fmtt;
else /* "lvm1" */
_default_settings.fmt = cmd->fmt1;
_use_settings(&_default_settings);
return 1;
}
@@ -1159,7 +1201,8 @@ static void fin(void)
if (_dump_filter)
persistent_filter_dump(cmd->filter);
cmd->fid->ops->destroy(cmd->fid);
cmd->fmt1->ops->destroy(cmd->fmt1);
cmd->fmtt->ops->destroy(cmd->fmtt);
cmd->filter->destroy(cmd->filter);
pool_destroy(cmd->mem);
vgcache_destroy();

View File

@@ -44,7 +44,7 @@ int lvmdiskscan(struct cmd_context *cmd, int argc, char **argv)
/* Do scan */
for (dev = dev_iter_get(iter); dev; dev = dev_iter_get(iter)) {
/* Try if it is a PV first */
if ((pv = cmd->fid->ops->pv_read(cmd->fid, dev_name(dev)))) {
if ((pv = pv_read(cmd, dev_name(dev)))) {
if (!dev_get_size(dev, &size)) {
log_error("Couldn't get size of \"%s\"",
dev_name(dev));

View File

@@ -50,13 +50,10 @@ static int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv)
return ECMD_FAILED;
}
if (!lv_info(lv, &info)) {
stack;
return ECMD_FAILED;
}
if (lv_info(lv, &info)) {
if (info.open_count) {
log_error("Can't remove open logical volume \"%s\"", lv->name);
log_error("Can't remove open logical volume \"%s\"",
lv->name);
return ECMD_FAILED;
}
@@ -69,6 +66,7 @@ static int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv)
return 0;
}
}
}
if (!archive(vg))
return ECMD_FAILED;
@@ -94,7 +92,7 @@ static int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv)
}
/* store it on disks */
if (!cmd->fid->ops->vg_write(cmd->fid, vg))
if (vg_write(vg))
return ECMD_FAILED;
backup(vg);

View File

@@ -39,13 +39,13 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv)
lv_name_old = argv[0];
lv_name_new = argv[1];
if (!(vg_name = extract_vgname(cmd->fid, lv_name_old))) {
if (!(vg_name = extract_vgname(cmd, lv_name_old))) {
log_error("Please provide a volume group name");
return EINVALID_CMD_LINE;
}
if (strchr(lv_name_new, '/') &&
(vg_name_new = extract_vgname(cmd->fid, lv_name_new)) &&
(vg_name_new = extract_vgname(cmd, lv_name_new)) &&
strcmp(vg_name, vg_name_new)) {
log_error("Logical volume names must "
"have the same volume group (\"%s\" or \"%s\")",
@@ -91,7 +91,7 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
}
if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) {
if (!(vg = vg_read(cmd, vg_name))) {
log_error("Volume group \"%s\" doesn't exist", vg_name);
goto error;
}
@@ -133,7 +133,7 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv)
}
log_verbose("Writing out updated volume group");
if (!(cmd->fid->ops->vg_write(cmd->fid, vg)))
if (!vg_write(vg))
goto lverror;
unlock_lv(cmd, lv->lvid.s);
@@ -147,7 +147,6 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv)
return 0;
lverror:
unlock_lv(cmd, lv->lvid.s);

View File

@@ -27,8 +27,9 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
struct dm_info info;
uint32_t extents = 0;
uint32_t size = 0;
uint32_t stripes = 0, stripesize = 0;
uint32_t stripes = 0, stripesize = 0, stripesize_extents = 0;
uint32_t seg_stripes = 0, seg_stripesize = 0, seg_size = 0;
uint32_t extents_used = 0;
uint32_t size_rest;
sign_t sign = SIGN_NONE;
char *lv_name, *vg_name;
@@ -76,16 +77,6 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
}
if (arg_count(cmd, stripes_ARG)) {
log_print("Varied striping not yet supported. Ignoring.");
/* FUTURE stripes = arg_int_value(cmd,stripes_ARG, 1); */
}
if (arg_count(cmd, stripesize_ARG)) {
log_print("Varied stripesize not yet supported. Ignoring.");
/* FUTURE stripesize = 2 * arg_int_value(cmd,stripesize_ARG, 0); */
}
if (!argc) {
log_error("Please provide the logical volume name");
return EINVALID_CMD_LINE;
@@ -95,7 +86,7 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
argv++;
argc--;
if (!(vg_name = extract_vgname(cmd->fid, lv_name))) {
if (!(vg_name = extract_vgname(cmd, lv_name))) {
log_error("Please provide a volume group name");
return EINVALID_CMD_LINE;
}
@@ -110,7 +101,7 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
}
if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) {
if (!(vg = vg_read(cmd, vg_name))) {
log_error("Volume group %s doesn't exist", vg_name);
goto error;
}
@@ -132,6 +123,20 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
goto error;
}
if (arg_count(cmd, stripes_ARG)) {
if (vg->fid->fmt->features & FMT_SEGMENTS)
stripes = arg_int_value(cmd, stripes_ARG, 1);
else
log_print("Varied striping not supported. Ignoring.");
}
if (arg_count(cmd, stripesize_ARG)) {
if (vg->fid->fmt->features & FMT_SEGMENTS)
stripesize = 2 * arg_int_value(cmd, stripesize_ARG, 0);
else
log_print("Varied stripesize not supported. Ignoring.");
}
lv = lvl->lv;
if (size) {
@@ -179,6 +184,8 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
goto error_cmdline;
}
seg_size = extents - lv->le_count;
/* If extending, find stripes, stripesize & size of last segment */
if (extents > lv->le_count &&
!(stripes == 1 || (stripes > 1 && stripesize))) {
@@ -205,15 +212,22 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
if (!stripes)
stripes = seg_stripes;
if (!stripesize && stripes > 1)
if (!stripesize && stripes > 1) {
if (seg_stripesize) {
log_print("Using stripesize of last segment "
"%dKB", seg_stripesize / 2);
stripesize = seg_stripesize;
seg_size = extents - lv->le_count;
} else {
log_print("Using default stripesize %dKB",
STRIPE_SIZE_DEFAULT);
stripesize = 2 * STRIPE_SIZE_DEFAULT;
}
}
}
/* If reducing, find stripes, stripesize & size of last segment */
if (extents < lv->le_count) {
uint32_t extents_used = 0;
extents_used = 0;
if (stripes || stripesize)
log_error("Ignoring stripes and stripesize arguments "
@@ -240,12 +254,22 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
stripes = seg_stripes;
}
if ((size_rest = seg_size % stripes)) {
log_print("Rounding size (%d extents) down to stripe boundary "
"size of last segment (%d extents)", extents,
extents - size_rest);
if (stripes > 1 && !stripesize) {
log_error("Stripesize for striped segment should not be 0!");
goto error_cmdline;
}
if ((stripes > 1)) {
if (!(stripesize_extents = stripesize / vg->extent_size))
stripesize_extents = 1;
if ((size_rest = seg_size % (stripes * stripesize_extents))) {
log_print("Rounding size (%d extents) down to stripe "
"boundary size for segment (%d extents)",
extents, extents - size_rest);
extents = extents - size_rest;
}
}
if (extents == lv->le_count) {
log_error("New size (%d extents) matches existing size "
@@ -277,14 +301,15 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
if (argc)
log_print("Ignoring PVs on command line when reducing");
if (!lv_info(lv, &info)) {
stack;
memset(&info, 0, sizeof(info));
if (!lv_info(lv, &info) && driver_version(NULL, 0)) {
log_error("lv_info failed: aborting");
goto error;
}
if (info.exists) {
dummy =
display_size((uint64_t)
dummy = display_size((uint64_t)
extents * (vg->extent_size / 2),
SIZE_SHORT);
log_print("WARNING: Reducing active%s logical volume "
@@ -308,7 +333,7 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
if (!archive(vg))
goto error;
if (!lv_reduce(cmd->fid, lv, lv->le_count - extents))
if (!lv_reduce(vg->fid, lv, lv->le_count - extents))
goto error;
}
@@ -332,7 +357,7 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
log_print("Extending logical volume %s to %s", lv_name, dummy);
dbg_free(dummy);
if (!lv_extend(cmd->fid, lv, stripes, stripesize,
if (!lv_extend(vg->fid, lv, stripes, stripesize,
extents - lv->le_count, pvh))
goto error;
}
@@ -343,7 +368,7 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
}
/* store vg on disk(s) */
if (!cmd->fid->ops->vg_write(cmd->fid, vg)) {
if (!vg_write(vg)) {
/* FIXME: Attempt reversion? */
unlock_lv(cmd, lv->lvid.s);
goto error;

View File

@@ -52,7 +52,7 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
log_verbose("Using physical volume(s) on command line");
for (; opt < argc; opt++) {
pv_name = argv[opt];
if (!(pv = cmd->fid->ops->pv_read(cmd->fid, pv_name))) {
if (!(pv = pv_read(cmd, pv_name))) {
log_error
("Failed to read physical volume \"%s\"",
pv_name);
@@ -63,7 +63,7 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
}
} else {
log_verbose("Scanning for physical volume names");
if (!(pvs = cmd->fid->ops->get_pvs(cmd->fid))) {
if (!(pvs = get_pvs(cmd))) {
return ECMD_FAILED;
}
@@ -103,7 +103,7 @@ int pvchange_single(struct cmd_context *cmd, struct physical_volume *pv)
return ECMD_FAILED;
}
if (!(vg = cmd->fid->ops->vg_read(cmd->fid, pv->vg_name))) {
if (!(vg = vg_read(cmd, pv->vg_name))) {
unlock_vg(cmd, pv->vg_name);
log_error("Unable to find volume group of \"%s\"",
pv_name);
@@ -163,7 +163,7 @@ int pvchange_single(struct cmd_context *cmd, struct physical_volume *pv)
log_verbose("Updating physical volume \"%s\"", pv_name);
if (*pv->vg_name) {
if (!(cmd->fid->ops->vg_write(cmd->fid, vg))) {
if (!vg_write(vg)) {
unlock_vg(cmd, pv->vg_name);
log_error("Failed to store physical volume \"%s\" in "
"volume group \"%s\"", pv_name, vg->name);
@@ -172,7 +172,7 @@ int pvchange_single(struct cmd_context *cmd, struct physical_volume *pv)
backup(vg);
unlock_vg(cmd, pv->vg_name);
} else {
if (!(cmd->fid->ops->pv_write(cmd->fid, pv))) {
if (!(pv_write(cmd, pv))) {
log_error("Failed to store physical volume \"%s\"",
pv_name);
return 0;

View File

@@ -39,7 +39,7 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name)
}
/* is there a pv here already */
if (!(pv = cmd->fid->ops->pv_read(cmd->fid, name)))
if (!(pv = pv_read(cmd, name)))
return 1;
/* orphan ? */
@@ -75,6 +75,7 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name)
static void pvcreate_single(struct cmd_context *cmd, const char *pv_name)
{
struct physical_volume *pv;
struct format_instance *fid;
struct id id, *idp = NULL;
char *uuid;
uint64_t size = 0;
@@ -96,7 +97,13 @@ static void pvcreate_single(struct cmd_context *cmd, const char *pv_name)
return;
size = arg_int64_value(cmd, physicalvolumesize_ARG, 0) * 2;
if (!(pv = pv_create(cmd->fid, pv_name, idp, size))) {
/* FIXME Use config file/cmd line to specify format */
if (!(fid = cmd->fmt1->ops->create_instance(cmd->fmt1, NULL, NULL))) {
log_error("Failed to create format1 instance");
return;
}
if (!(pv = pv_create(fid, pv_name, idp, size))) {
log_error("Failed to setup physical volume \"%s\"", pv_name);
return;
}
@@ -106,7 +113,7 @@ static void pvcreate_single(struct cmd_context *cmd, const char *pv_name)
log_very_verbose("Writing physical volume data to disk \"%s\"",
pv_name);
if (!(cmd->fid->ops->pv_write(cmd->fid, pv))) {
if (!(pv_write(cmd, pv))) {
log_error("Failed to write physical volume \"%s\"", pv_name);
return;
}

View File

@@ -38,7 +38,7 @@ int pvdisplay(struct cmd_context *cmd, int argc, char **argv)
log_very_verbose("Using physical volume(s) on command line");
for (; opt < argc; opt++) {
if (!(pv = cmd->fid->ops->pv_read(cmd->fid, argv[opt]))) {
if (!(pv = pv_read(cmd, argv[opt]))) {
log_error("Failed to read physical "
"volume \"%s\"", argv[opt]);
continue;
@@ -47,7 +47,7 @@ int pvdisplay(struct cmd_context *cmd, int argc, char **argv)
}
} else {
log_verbose("Scanning for physical volume names");
if (!(pvs = cmd->fid->ops->get_pvs(cmd->fid)))
if (!(pvs = get_pvs(cmd)))
return ECMD_FAILED;
list_iterate(pvh, pvs)
@@ -67,7 +67,7 @@ void pvdisplay_single(struct cmd_context *cmd, struct physical_volume *pv)
if (!*pv->vg_name)
size = pv->size;
else
size = (pv->pe_count - pv->pe_allocated) * pv->pe_size;
size = (pv->pe_count - pv->pe_alloc_count) * pv->pe_size;
if (arg_count(cmd, short_ARG)) {
sz = display_size(size / 2, SIZE_SHORT);
@@ -112,7 +112,7 @@ void pvdisplay_single(struct cmd_context *cmd, struct physical_volume *pv)
return;
/******* FIXME
if (pv->pe_allocated) {
if (pv->pe_alloc_count) {
if (!(pv->pe = pv_read_pe(pv_name, pv)))
goto pvdisplay_device_out;
if (!(lvs = pv_read_lvs(pv))) {

View File

@@ -57,7 +57,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
persistent_filter_wipe(cmd->filter);
log_verbose("Walking through all physical volumes");
if (!(pvs = cmd->fid->ops->get_pvs(cmd->fid)))
if (!(pvs = get_pvs(cmd)))
return ECMD_FAILED;
/* eliminate exported/new if required */
@@ -65,8 +65,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
pvl = list_item(pvh, struct pv_list);
pv = pvl->pv;
if (
(arg_count(cmd, exported_ARG)
if ((arg_count(cmd, exported_ARG)
&& !(pv->status & EXPORTED_VG))
|| (arg_count(cmd, novolumegroup_ARG) && (*pv->vg_name))) {
list_del(&pvl->list);
@@ -90,7 +89,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
size_new += pv->size;
size_total += pv->size;
} else
size_total += (pv->pe_count - pv->pe_allocated)
size_total += (pv->pe_count - pv->pe_alloc_count)
* pv->pe_size;
}
@@ -192,7 +191,7 @@ void pvscan_display_single(struct cmd_context *cmd, struct physical_volume *pv)
display_size(pv->pe_count *
pv->pe_size / 2,
SIZE_SHORT)),
(s2 = display_size((pv->pe_count - pv->pe_allocated)
(s2 = display_size((pv->pe_count - pv->pe_alloc_count)
* pv->pe_size / 2, SIZE_SHORT)));
dbg_free(s1);
dbg_free(s2);
@@ -201,12 +200,13 @@ void pvscan_display_single(struct cmd_context *cmd, struct physical_volume *pv)
sprintf(vg_tmp_name, "%s", pv->vg_name);
log_print
("PV %-*s VG %-*s [%s / %s free]", pv_max_name_len,
("PV %-*s VG %-*s %s [%s / %s free]", pv_max_name_len,
pv_tmp_name, vg_max_name_len, vg_tmp_name,
pv->fid ? pv->fid->fmt->name : " ",
(s1 = display_size(pv->pe_count * pv->pe_size / 2, SIZE_SHORT)),
(s2 =
display_size((pv->pe_count - pv->pe_allocated) * pv->pe_size / 2,
SIZE_SHORT)));
display_size((pv->pe_count - pv->pe_alloc_count) * pv->pe_size /
2, SIZE_SHORT)));
dbg_free(s1);
dbg_free(s2);

View File

@@ -13,5 +13,4 @@ int pvdata(struct cmd_context *cmd, int argc, char **argv) unimplemented
int pvmove(struct cmd_context *cmd, int argc, char **argv) unimplemented
int pvresize(struct cmd_context *cmd, int argc, char **argv) unimplemented
int vgmknodes(struct cmd_context *cmd, int argc, char **argv) unimplemented
int vgsplit(struct cmd_context *cmd, int argc, char **argv) unimplemented

View File

@@ -57,7 +57,7 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv,
char *lv_name = argv[opt];
/* does VG exist? */
if (!(vg_name = extract_vgname(cmd->fid, lv_name))) {
if (!(vg_name = extract_vgname(cmd, lv_name))) {
if (ret_max < ECMD_FAILED)
ret_max = ECMD_FAILED;
continue;
@@ -68,7 +68,7 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv,
log_error("Can't lock %s: skipping", vg_name);
continue;
}
if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) {
if (!(vg = vg_read(cmd, vg_name))) {
log_error("Volume group \"%s\" doesn't exist",
vg_name);
if (ret_max < ECMD_FAILED)
@@ -102,7 +102,7 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv,
}
} else {
log_verbose("Finding all logical volumes");
if (!(vgs = cmd->fid->ops->get_vgs(cmd->fid))) {
if (!(vgs = get_vgs(cmd))) {
log_error("No volume groups found");
return ECMD_FAILED;
}
@@ -112,7 +112,7 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv,
log_error("Can't lock %s: skipping", vg_name);
continue;
}
if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) {
if (!(vg = vg_read(cmd, vg_name))) {
log_error("Volume group \"%s\" not found",
vg_name);
if (ret_max < ECMD_FAILED)
@@ -144,11 +144,19 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
struct list *vgs;
char *vg_name;
char *dev_dir = cmd->dev_dir;
if (argc) {
log_verbose("Using volume group(s) on command line");
for (; opt < argc; opt++) {
vg_name = argv[opt];
if (!strncmp(vg_name, dev_dir, strlen(dev_dir)))
vg_name += strlen(dev_dir);
if (strchr(vg_name, '/')) {
log_error("Invalid volume group name: %s",
vg_name);
continue;
}
if (!lock_vol(cmd, vg_name, lock_type)) {
log_error("Can't lock %s: skipping", vg_name);
continue;
@@ -159,7 +167,7 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
}
} else {
log_verbose("Finding all volume groups");
if (!(vgs = cmd->fid->ops->get_vgs(cmd->fid))) {
if (!(vgs = get_vgs(cmd))) {
log_error("No volume groups found");
return ECMD_FAILED;
}
@@ -247,11 +255,11 @@ int is_valid_chars(char *n)
return 1;
}
char *extract_vgname(struct format_instance *fi, char *lv_name)
char *extract_vgname(struct cmd_context *cmd, char *lv_name)
{
char *vg_name = lv_name;
char *st;
char *dev_dir = fi->cmd->dev_dir;
char *dev_dir = cmd->dev_dir;
/* Path supplied? */
if (vg_name && strchr(vg_name, '/')) {
@@ -267,7 +275,7 @@ char *extract_vgname(struct format_instance *fi, char *lv_name)
return 0;
}
vg_name = pool_strdup(fi->cmd->mem, vg_name);
vg_name = pool_strdup(cmd->mem, vg_name);
if (!vg_name) {
log_error("Allocation of vg_name failed");
return 0;
@@ -277,7 +285,7 @@ char *extract_vgname(struct format_instance *fi, char *lv_name)
return vg_name;
}
if (!(vg_name = default_vgname(fi))) {
if (!(vg_name = default_vgname(cmd))) {
if (lv_name)
log_error("Path required for Logical Volume \"%s\"",
lv_name);
@@ -287,10 +295,10 @@ char *extract_vgname(struct format_instance *fi, char *lv_name)
return vg_name;
}
char *default_vgname(struct format_instance *fi)
char *default_vgname(struct cmd_context *cmd)
{
char *vg_path;
char *dev_dir = fi->cmd->dev_dir;
char *dev_dir = cmd->dev_dir;
/* Take default VG from environment? */
vg_path = getenv("LVM_VG_NAME");
@@ -307,7 +315,7 @@ char *default_vgname(struct format_instance *fi)
return 0;
}
return pool_strdup(fi->cmd->mem, vg_path);
return pool_strdup(cmd->mem, vg_path);
}
struct list *create_pv_list(struct pool *mem,
@@ -332,7 +340,7 @@ struct list *create_pv_list(struct pool *mem,
return NULL;
}
if (pvl->pv->pe_count == pvl->pv->pe_allocated) {
if (pvl->pv->pe_count == pvl->pv->pe_alloc_count) {
log_err("No free extents on physical volume \"%s\"",
argv[i]);
continue;

View File

@@ -54,8 +54,8 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
int is_valid_chars(char *n);
char *default_vgname(struct format_instance *fi);
char *extract_vgname(struct format_instance *fi, char *lv_name);
char *default_vgname(struct cmd_context *cmd);
char *extract_vgname(struct cmd_context *cmd, char *lv_name);
/*
* Builds a list of pv's from the names in argv. Used in

View File

@@ -4,8 +4,8 @@
* This file is released under the LGPL.
*/
#ifndef _LVM_LVM_H
#define _LVM_LVM_H
#ifndef _LVM_TOOLS_H
#define _LVM_TOOLS_H
#include "pool.h"
#include "dbg_malloc.h"
@@ -75,6 +75,7 @@ struct arg {
uint32_t i_value;
uint64_t i64_value;
sign_t sign;
void *ptr;
};
/* a register of the lvm commands */
@@ -98,6 +99,7 @@ int int_arg_with_sign(struct arg *a);
int minor_arg(struct arg *a);
int string_arg(struct arg *a);
int permission_arg(struct arg *a);
int metadatatype_arg(struct arg *a);
char yes_no_prompt(const char *prompt, ...);
@@ -129,6 +131,11 @@ static inline uint64_t arg_int64_value(struct cmd_context *cmd, int a,
return arg_count(cmd, a) ? cmd->args[a].i64_value : def;
}
static inline void *arg_ptr_value(struct cmd_context *cmd, int a, void *def)
{
return arg_count(cmd, a) ? cmd->args[a].ptr : def;
}
static inline sign_t arg_sign_value(struct cmd_context *cmd, int a, sign_t def)
{
return arg_count(cmd, a) ? cmd->args[a].sign : def;

View File

@@ -12,17 +12,21 @@ static int _backup_to_file(const char *file, struct volume_group *vg)
{
int r;
struct format_instance *tf;
void *context;
if (!(tf = text_format_create(vg->cmd, file, vg->cmd->um,
vg->cmd->cmd_line))) {
if (!(context = create_text_context(vg->cmd->fmtt, file,
vg->cmd->cmd_line)) ||
!(tf = vg->cmd->fmtt->ops->create_instance(vg->cmd->fmtt, NULL,
context))) {
log_error("Couldn't create backup object.");
return 0;
}
if (!(r = tf->ops->vg_write(tf, vg)))
if (!(r = tf->fmt->ops->vg_write(tf, vg, context)) ||
!(r = tf->fmt->ops->vg_commit(tf, vg, context)))
stack;
tf->ops->destroy(tf);
tf->fmt->ops->destroy_instance(tf);
return r;
}
@@ -31,7 +35,7 @@ static int vg_backup_single(struct cmd_context *cmd, const char *vg_name)
struct volume_group *vg;
log_verbose("Checking for volume group \"%s\"", vg_name);
if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) {
if (!(vg = vg_read(cmd, vg_name))) {
log_error("Volume group \"%s\" not found", vg_name);
return ECMD_FAILED;
}

View File

@@ -78,7 +78,7 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name)
{
struct volume_group *vg;
if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) {
if (!(vg = vg_read(cmd, vg_name))) {
log_error("Unable to find volume group \"%s\"", vg_name);
return ECMD_FAILED;
}
@@ -158,7 +158,7 @@ void vgchange_resizeable(struct cmd_context *cmd, struct volume_group *vg)
else
vg->status &= ~RESIZEABLE_VG;
if (!cmd->fid->ops->vg_write(cmd->fid, vg))
if (!vg_write(vg))
return;
backup(vg);
@@ -190,7 +190,7 @@ void vgchange_logicalvolume(struct cmd_context *cmd, struct volume_group *vg)
vg->max_lv = max_lv;
if (!cmd->fid->ops->vg_write(cmd->fid, vg))
if (!vg_write(vg))
return;
backup(vg);

View File

@@ -33,7 +33,7 @@ static int vgck_single(struct cmd_context *cmd, const char *vg_name)
log_verbose("Checking volume group \"%s\"", vg_name);
if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) {
if (!(vg = vg_read(cmd, vg_name))) {
log_error("Volume group \"%s\" not found", vg_name);
return ECMD_FAILED;
}

View File

@@ -21,8 +21,8 @@
#include "tools.h"
/* FIXME From config file? */
#define DEFAULT_PV 255
#define DEFAULT_LV 255
#define DEFAULT_PV 256
#define DEFAULT_LV 256
#define DEFAULT_EXTENT 4096 /* In KB */
@@ -80,7 +80,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
}
/* Create the new VG */
if (!(vg = vg_create(cmd->fid, vg_name, extent_size, max_pv, max_lv,
if (!(vg = vg_create(cmd, vg_name, extent_size, max_pv, max_lv,
argc - 1, argv + 1)))
return ECMD_FAILED;
@@ -110,7 +110,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
}
/* Store VG on disk(s) */
if (!cmd->fid->ops->vg_write(cmd->fid, vg)) {
if (!vg_write(vg)) {
unlock_vg(cmd, vg_name);
unlock_vg(cmd, "");
return ECMD_FAILED;

View File

@@ -70,7 +70,7 @@ static int vgdisplay_single(struct cmd_context *cmd, const char *vg_name)
/* FIXME Do the active check here if activevolumegroups_ARG ? */
log_very_verbose("Finding volume group \"%s\"", vg_name);
if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) {
if (!(vg = vg_read(cmd, vg_name))) {
log_error("Volume group \"%s\" doesn't exist", vg_name);
return ECMD_FAILED;
}

View File

@@ -41,7 +41,7 @@ static int vgexport_single(struct cmd_context *cmd, const char *vg_name)
{
struct volume_group *vg;
if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) {
if (!(vg = vg_read(cmd, vg_name))) {
log_error("Unable to find volume group \"%s\"", vg_name);
goto error;
}
@@ -67,7 +67,7 @@ static int vgexport_single(struct cmd_context *cmd, const char *vg_name)
vg->status |= EXPORTED_VG;
if (!cmd->fid->ops->vg_write(cmd->fid, vg))
if (!vg_write(vg))
goto error;
backup(vg);

View File

@@ -52,7 +52,7 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv)
goto error;
}
if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) {
if (!(vg = vg_read(cmd, vg_name))) {
log_error("Volume group \"%s\" not found.", vg_name);
goto error;
}
@@ -83,7 +83,7 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv)
goto error;
/* extend vg */
if (!vg_extend(cmd->fid, vg, argc, argv))
if (!vg_extend(vg->fid, vg, argc, argv))
goto error;
/* ret > 0 */
@@ -91,7 +91,7 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv)
"physical volumes", vg_name, argc);
/* store vg on disk(s) */
if (!cmd->fid->ops->vg_write(cmd->fid, vg))
if (!vg_write(vg))
goto error;
backup(vg);

View File

@@ -41,7 +41,7 @@ static int vgimport_single(struct cmd_context *cmd, const char *vg_name)
{
struct volume_group *vg;
if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) {
if (!(vg = vg_read(cmd, vg_name))) {
log_error("Unable to find exported volume group \"%s\"",
vg_name);
goto error;
@@ -62,7 +62,7 @@ static int vgimport_single(struct cmd_context *cmd, const char *vg_name)
vg->status &= ~EXPORTED_VG;
if (!cmd->fid->ops->vg_write(cmd->fid, vg))
if (!vg_write(vg))
goto error;
backup(vg);

View File

@@ -65,7 +65,7 @@ int vgmerge_single(struct cmd_context *cmd, const char *vg_name_to,
return ECMD_FAILED;
}
if (!(vg_to = cmd->fid->ops->vg_read(cmd->fid, vg_name_to))) {
if (!(vg_to = vg_read(cmd, vg_name_to))) {
log_error("Volume group \"%s\" doesn't exist", vg_name_to);
unlock_vg(cmd, vg_name_to);
return ECMD_FAILED;
@@ -90,7 +90,7 @@ int vgmerge_single(struct cmd_context *cmd, const char *vg_name_to,
return ECMD_FAILED;
}
if (!(vg_from = cmd->fid->ops->vg_read(cmd->fid, vg_name_from))) {
if (!(vg_from = vg_read(cmd, vg_name_from))) {
log_error("Volume group \"%s\" doesn't exist", vg_name_from);
goto error;
}
@@ -182,7 +182,7 @@ int vgmerge_single(struct cmd_context *cmd, const char *vg_name_to,
/* store it on disks */
log_verbose("Writing out updated volume group");
if (!(cmd->fid->ops->vg_write(cmd->fid, vg_to))) {
if (!vg_write(vg_to)) {
goto error;
}

View File

@@ -56,7 +56,7 @@ int vgreduce(struct cmd_context *cmd, int argc, char **argv)
return ECMD_FAILED;
}
if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) {
if (!(vg = vg_read(cmd, vg_name))) {
log_error("Volume group \"%s\" doesn't exist", vg_name);
unlock_vg(cmd, vg_name);
return ECMD_FAILED;
@@ -112,12 +112,12 @@ static int vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
struct pv_list *pvl;
const char *name = dev_name(pv->dev);
if (pv->pe_allocated) {
if (pv->pe_alloc_count) {
log_error("Physical volume \"%s\" still in use", name);
return ECMD_FAILED;
}
/********* FIXME: Is this unnecessary after checking pe_allocated?
/********* FIXME: Is this unnecessary after checking pe_alloc_count?
if (pv->lv_cur > 0) {
log_error ("can't reduce volume group \"%s\" by used physical volume \"%s\"", vg_name, error_pv_name);
}
@@ -141,16 +141,16 @@ static int vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
*pv->vg_name = '\0';
vg->pv_count--;
vg->free_count -= pv->pe_count - pv->pe_allocated;
vg->free_count -= pv->pe_count - pv->pe_alloc_count;
vg->extent_count -= pv->pe_count;
if (!(cmd->fid->ops->vg_write(cmd->fid, vg))) {
if (!vg_write(vg)) {
log_error("Removal of physical volume \"%s\" from "
"\"%s\" failed", name, vg->name);
return ECMD_FAILED;
}
if (!cmd->fid->ops->pv_write(cmd->fid, pv)) {
if (!pv_write(cmd, pv)) {
log_error("Failed to clear metadata from physical "
"volume \"%s\" "
"after removal from \"%s\"", name, vg->name);

View File

@@ -48,7 +48,7 @@ static int vgremove_single(struct cmd_context *cmd, const char *vg_name)
int ret = 0;
log_verbose("Checking for volume group \"%s\"", vg_name);
if (!(vg = cmd->fid->ops->vg_read(cmd->fid, vg_name))) {
if (!(vg = vg_read(cmd, vg_name))) {
log_error("Volume group \"%s\" doesn't exist", vg_name);
return ECMD_FAILED;
}
@@ -73,12 +73,10 @@ static int vgremove_single(struct cmd_context *cmd, const char *vg_name)
if (!archive(vg))
return ECMD_FAILED;
/************ FIXME
if (vg_remove_dir_and_group_and_nodes(vg_name) < 0) {
log_error("removing special files of volume group \"%s\"",
vg_name);
if (!vg_remove(vg)) {
log_error("vg_remove %s failed", vg_name);
return ECMD_FAILED;
}
*************/
/* init physical volumes */
list_iterate(pvh, &vg->pvs) {
@@ -86,7 +84,7 @@ static int vgremove_single(struct cmd_context *cmd, const char *vg_name)
log_verbose("Removing physical volume \"%s\" from "
"volume group \"%s\"", dev_name(pv->dev), vg_name);
*pv->vg_name = '\0';
if (!(cmd->fid->ops->pv_write(cmd->fid, pv))) {
if (!pv_write(cmd, pv)) {
log_error("Failed to remove physical volume \"%s\""
" from volume group \"%s\"",
dev_name(pv->dev), vg_name);

Some files were not shown because too many files have changed in this diff Show More