mirror of
git://sourceware.org/git/lvm2.git
synced 2026-01-08 16:32:48 +03:00
Compare commits
20 Commits
dm_v1_01_0
...
old-dm_v1_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
becc320e62 | ||
|
|
7666ed57d1 | ||
|
|
5e61d0955e | ||
|
|
e8a4662ae7 | ||
|
|
a48da3bd3b | ||
|
|
5f1a5d7b99 | ||
|
|
3e28a9db8f | ||
|
|
ebf6071d77 | ||
|
|
47a35fb9fb | ||
|
|
48e88aba44 | ||
|
|
b85f99c140 | ||
|
|
0a5e0e1f71 | ||
|
|
85dc22ebb7 | ||
|
|
5c21526009 | ||
|
|
14dff1cefc | ||
|
|
39fbb844f9 | ||
|
|
ca4e0c973a | ||
|
|
ecb42bee80 | ||
|
|
674ed2a9f3 | ||
|
|
252daf9717 |
26
WHATS_NEW
26
WHATS_NEW
@@ -1,5 +1,26 @@
|
||||
Version 2.01.11 -
|
||||
==============================
|
||||
Version 2.01.14 -
|
||||
================================
|
||||
Fix pool format handler to work with pv segment code
|
||||
|
||||
Version 2.01.13 - 13th July 2005
|
||||
================================
|
||||
Fix pvmove segment splitting.
|
||||
Abstract vg_validate.
|
||||
Only make one attempt at contiguous allocation.
|
||||
Fix lvm1 format metadata read.
|
||||
Fix lvm1 format non-mirror lvcreate.
|
||||
|
||||
Version 2.01.12 - 14th June 2005
|
||||
================================
|
||||
Various allocation-related pvmove fixes.
|
||||
Log an error if clvmd can't resolve a host name got from CCS.
|
||||
Fix potential spin loop in clvmd.
|
||||
|
||||
Version 2.01.11 - 13th June 2005
|
||||
================================
|
||||
Added lvmconf.sh.
|
||||
Use matchpathcon mode parameter.
|
||||
Don't defer closing dead FDs in clvmd.
|
||||
Remove hard-coded 64k text metadata writing restriction.
|
||||
Make VG name restrictions consistent.
|
||||
Introduce lvconvert. So far only removes mirror images.
|
||||
@@ -36,7 +57,6 @@ Version 2.01.11 -
|
||||
lv_reduce tidying.
|
||||
Remove some unnecessary parameters.
|
||||
Introduce seg_is macros.
|
||||
Don't defer closing dead FDs in clvmd.
|
||||
|
||||
Version 2.01.10 - 3rd May 2005
|
||||
==============================
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
Version 1.01.04 - 2 Aug 2005
|
||||
=============================
|
||||
Fix dmsetup ls -j and status --target with empty table.
|
||||
|
||||
Version 1.01.03 - 13 Jun 2005
|
||||
=============================
|
||||
Use matchpathcon mode parameter.
|
||||
|
||||
@@ -944,7 +944,13 @@ static int get_all_cluster_nodes()
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUGLOG("node %s has clvm disabled\n", nodename);
|
||||
if (!clvmflag) {
|
||||
DEBUGLOG("node %s has clvm disabled\n", nodename);
|
||||
}
|
||||
else {
|
||||
DEBUGLOG("Cannot resolve host name %s\n", nodename);
|
||||
log_err("Cannot resolve host name %s\n", nodename);
|
||||
}
|
||||
}
|
||||
free(nodename);
|
||||
}
|
||||
|
||||
@@ -512,6 +512,10 @@ static void main_loop(int local_sock, int cmd_timeout)
|
||||
FD_ZERO(&in);
|
||||
for (thisfd = &local_client_head; thisfd != NULL;
|
||||
thisfd = thisfd->next) {
|
||||
|
||||
if (thisfd->removeme)
|
||||
continue;
|
||||
|
||||
/* if the cluster is not quorate then don't listen for new requests */
|
||||
if ((thisfd->type != LOCAL_RENDEZVOUS &&
|
||||
thisfd->type != LOCAL_SOCK) || quorate)
|
||||
|
||||
@@ -28,7 +28,7 @@ else
|
||||
LIB_SHARED = libdmeventdnoop.so
|
||||
endif
|
||||
|
||||
LDFLAGS += -ldl -ldevmapper -lpthread -lmultilog
|
||||
LDFLAGS += -ldl -ldevmapper -lmultilog
|
||||
|
||||
include ../make.tmpl
|
||||
|
||||
@@ -36,11 +36,11 @@ libdmeventdnoop.so: noop.o
|
||||
|
||||
dmevent: dmevent.o $(interfacedir)/libdevmapper.$(LIB_SUFFIX) $(top_srcdir)/lib/event/libdmevent.$(LIB_SUFFIX)
|
||||
$(CC) -o $@ dmevent.o $(LDFLAGS) \
|
||||
-L$(interfacedir) -L$(DESTDIR)/lib -L$(top_srcdir)/lib/event -L$(top_srcdir)/multilog -ldmevent $(LIBS)
|
||||
-L$(interfacedir) -L$(DESTDIR)/lib -L$(top_srcdir)/lib/event -L$(top_srcdir)/multilog $(LIBS)
|
||||
|
||||
dmeventd: dmeventd.o $(interfacedir)/libdevmapper.$(LIB_SUFFIX) $(top_srcdir)/lib/event/libdmevent.$(LIB_SUFFIX)
|
||||
$(CC) -o $@ dmeventd.o $(LDFLAGS) \
|
||||
-L$(interfacedir) -L$(DESTDIR)/lib -L$(top_srcdir)/lib/event -L$(top_srcdir)/multilog -ldmevent $(LIBS)
|
||||
-L$(interfacedir) -L$(DESTDIR)/lib -L$(top_srcdir)/lib/event -L$(top_srcdir)/multilog -lpthread -ldmevent $(LIBS)
|
||||
|
||||
install: $(INSTALL_TYPE)
|
||||
|
||||
|
||||
@@ -26,12 +26,24 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
static enum event_type events = ALL_ERRORS; /* All until we can distinguish. */
|
||||
static char default_dso_name[] = "noop"; /* default DSO is noop */
|
||||
static int default_reg = 1; /* default action is register */
|
||||
static uint32_t timeout;
|
||||
|
||||
struct event_ops {
|
||||
int (*dm_register_for_event)(char *dso_name, char *device,
|
||||
enum event_type event_types);
|
||||
int (*dm_unregister_for_event)(char *dso_name, char *device,
|
||||
enum event_type event_types);
|
||||
int (*dm_get_registered_device)(char **dso_name, char **device,
|
||||
enum event_type *event_types, int next);
|
||||
int (*dm_set_event_timeout)(char *device, uint32_t time);
|
||||
int (*dm_get_event_timeout)(char *device, uint32_t *time);
|
||||
};
|
||||
|
||||
/* Display help. */
|
||||
static void print_usage(char *name)
|
||||
{
|
||||
@@ -102,8 +114,35 @@ static int parse_argv(int argc, char **argv, char **dso_name_arg,
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int lookup_symbol(void *dl, void **symbol, const char *name)
|
||||
{
|
||||
if ((*symbol = dlsym(dl, name)))
|
||||
return 1;
|
||||
|
||||
fprintf(stderr, "error looking up %s symbol: %s\n", name, dlerror());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lookup_symbols(void *dl, struct event_ops *e)
|
||||
{
|
||||
return lookup_symbol(dl, (void *) &e->dm_register_for_event,
|
||||
"dm_register_for_event") &&
|
||||
lookup_symbol(dl, (void *) &e->dm_unregister_for_event,
|
||||
"dm_unregister_for_event") &&
|
||||
lookup_symbol(dl, (void *) &e->dm_get_registered_device,
|
||||
"dm_get_registered_device") &&
|
||||
lookup_symbol(dl, (void *) &e->dm_set_event_timeout,
|
||||
"dm_set_event_timeout") &&
|
||||
lookup_symbol(dl, (void *) &e->dm_get_event_timeout,
|
||||
"dm_get_event_timeout");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
void *dl;
|
||||
struct event_ops e;
|
||||
int list = 0, next = 0, ret, reg = default_reg;
|
||||
char *device, *device_arg = NULL, *dso_name, *dso_name_arg = NULL;
|
||||
|
||||
@@ -128,15 +167,22 @@ int main(int argc, char **argv)
|
||||
multilog_add_type(standard, NULL);
|
||||
multilog_init_verbose(standard, _LOG_DEBUG);
|
||||
|
||||
if (!(dl = dlopen("libdmevent.so", RTLD_NOW))){
|
||||
fprintf(stderr, "Cannot dlopen libdmevent.so: %s\n", dlerror());
|
||||
goto out;
|
||||
}
|
||||
if (!(lookup_symbols(dl, &e)))
|
||||
goto out;
|
||||
if (list) {
|
||||
while (1) {
|
||||
if ((ret= dm_get_registered_device(&dso_name, &device,
|
||||
&events, next)))
|
||||
if ((ret= e.dm_get_registered_device(&dso_name,
|
||||
&device,
|
||||
&events, next)))
|
||||
break;
|
||||
printf("%s %s 0x%x", dso_name, device, events);
|
||||
if (events & TIMEOUT){
|
||||
if ((ret = dm_get_event_timeout(device,
|
||||
&timeout))) {
|
||||
if ((ret = e.dm_get_event_timeout(device,
|
||||
&timeout))) {
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
@@ -153,14 +199,14 @@ int main(int argc, char **argv)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((ret = reg ? dm_register_for_event(dso_name, device, events) :
|
||||
dm_unregister_for_event(dso_name, device, events))) {
|
||||
if ((ret = reg ? e.dm_register_for_event(dso_name, device, events) :
|
||||
e.dm_unregister_for_event(dso_name, device, events))) {
|
||||
fprintf(stderr, "Failed to %sregister %s: %s\n",
|
||||
reg ? "": "un", device, strerror(-ret));
|
||||
ret = EXIT_FAILURE;
|
||||
} else {
|
||||
if (reg && (events & TIMEOUT) &&
|
||||
((ret = dm_set_event_timeout(device, timeout)))){
|
||||
((ret = e.dm_set_event_timeout(device, timeout)))){
|
||||
fprintf(stderr, "Failed to set timeout for %s: %s\n",
|
||||
device, strerror(-ret));
|
||||
ret = EXIT_FAILURE;
|
||||
|
||||
@@ -803,7 +803,7 @@ int compose_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
(seg_pv(seg, s)->pe_start +
|
||||
(esize * seg_pe(seg, s))),
|
||||
trailing_space);
|
||||
else {
|
||||
else if (seg_type(seg, s) == AREA_LV) {
|
||||
if (!(dl = hash_lookup(dm->layers,
|
||||
seg_lv(seg, s)->lvid.s))) {
|
||||
log_error("device layer %s missing from hash",
|
||||
@@ -822,6 +822,10 @@ int compose_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
"%s %" PRIu64 "%s", devbuf,
|
||||
esize * seg_le(seg, s),
|
||||
trailing_space);
|
||||
} else {
|
||||
log_error("Internal error: Unassigned area found in LV %s.",
|
||||
seg->lv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tw < 0) {
|
||||
@@ -1243,6 +1247,7 @@ static int _expand_vanilla(struct dev_manager *dm, struct logical_volume *lv,
|
||||
|
||||
/* Add dependencies for any LVs that segments refer to */
|
||||
list_iterate_items(seg, &lv->segments) {
|
||||
// When do we need? _set_flag(dl, REMOVE) on the log?
|
||||
if (seg->log_lv &&
|
||||
!str_list_add(dm->mem, &dl->pre_create,
|
||||
_build_dlid(dm->mem, seg->log_lv->lvid.s,
|
||||
@@ -1250,7 +1255,6 @@ static int _expand_vanilla(struct dev_manager *dm, struct logical_volume *lv,
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
// FIXME Check we don't want NOPROPAGATE here
|
||||
|
||||
for (s = 0; s < seg->area_count; s++) {
|
||||
if (seg_type(seg, s) != AREA_LV)
|
||||
@@ -1262,7 +1266,10 @@ static int _expand_vanilla(struct dev_manager *dm, struct logical_volume *lv,
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ? if (seg_lv(seg, s)->status & PVMOVE)
|
||||
_set_flag(dl, NOPROPAGATE);
|
||||
// When do we need? _set_flag(dl, REMOVE)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ static int _mk_link(const char *dev_dir, const char *vg_name,
|
||||
}
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
if (!set_selinux_context(lv_path)) {
|
||||
if (!set_selinux_context(lv_path, S_IFLNK)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -247,6 +247,8 @@ static int _insert_dev(const char *path, dev_t d)
|
||||
|
||||
/* Generate pretend device numbers for loopfiles */
|
||||
if (!d) {
|
||||
if (hash_lookup(_cache.names, path))
|
||||
return 1;
|
||||
d = ++loopfile_count;
|
||||
loopfile = 1;
|
||||
}
|
||||
@@ -627,6 +629,10 @@ struct device *dev_cache_get(const char *name, struct dev_filter *f)
|
||||
if (!d) {
|
||||
_insert(name, 0);
|
||||
d = (struct device *) hash_lookup(_cache.names, name);
|
||||
if (!d) {
|
||||
_full_scan(0);
|
||||
d = (struct device *) hash_lookup(_cache.names, name);
|
||||
}
|
||||
}
|
||||
|
||||
return (d && (!f || (d->flags & DEV_REGULAR) ||
|
||||
|
||||
@@ -471,7 +471,9 @@ void display_stripe(const struct lv_segment *seg, uint32_t s, const char *pre)
|
||||
log_print("%sLogical extents\t%d to %d", pre,
|
||||
seg_le(seg, s),
|
||||
seg_le(seg, s) + seg->area_len - 1);
|
||||
|
||||
break;
|
||||
case AREA_UNASSIGNED:
|
||||
log_print("%sUnassigned area", pre);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -241,7 +241,7 @@ int import_vg(struct pool *mem,
|
||||
|
||||
vg->extent_size = vgd->pe_size;
|
||||
vg->extent_count = vgd->pe_total;
|
||||
vg->free_count = vgd->pe_total - vgd->pe_allocated;
|
||||
vg->free_count = vgd->pe_total;
|
||||
vg->max_lv = vgd->lv_max;
|
||||
vg->max_pv = vgd->pv_max;
|
||||
vg->alloc = ALLOC_NORMAL;
|
||||
@@ -395,7 +395,7 @@ int export_extents(struct disk_list *dl, uint32_t lv_num,
|
||||
return 0;
|
||||
}
|
||||
if (seg_type(seg, s) != AREA_PV) {
|
||||
log_error("LV stripe found in LV %s: "
|
||||
log_error("Non-PV stripe found in LV %s: "
|
||||
"unsupported by format1", lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ static int _read_vg_pds(const struct format_type *fmt, struct pool *mem,
|
||||
uint32_t *devcount)
|
||||
{
|
||||
struct lvmcache_info *info;
|
||||
struct pool_list *pl;
|
||||
struct pool_list *pl = NULL;
|
||||
struct pool *tmpmem;
|
||||
|
||||
uint32_t sp_count = 0;
|
||||
|
||||
@@ -45,7 +45,7 @@ int import_pool_vg(struct volume_group *vg, struct pool *mem, struct list *pls)
|
||||
get_pool_vg_uuid(&vg->id, &pl->pd);
|
||||
vg->extent_size = POOL_PE_SIZE;
|
||||
vg->status |= LVM_READ | LVM_WRITE | CLUSTERED | SHARED;
|
||||
vg->free_count = 0;
|
||||
vg->free_count = vg->extent_count;
|
||||
vg->max_lv = 1;
|
||||
vg->max_pv = POOL_MAX_DEVICES;
|
||||
vg->alloc = ALLOC_NORMAL;
|
||||
|
||||
@@ -480,6 +480,9 @@ int out_areas(struct formatter *f, const struct lv_segment *seg,
|
||||
seg_lv(seg, s)->name,
|
||||
seg_le(seg, s),
|
||||
(s == seg->area_count - 1) ? "" : ",");
|
||||
break;
|
||||
case AREA_UNASSIGNED:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -364,10 +364,6 @@ int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Adjust extent counts in the pv and vg.
|
||||
*/
|
||||
seg->lv->vg->free_count -= seg->area_len;
|
||||
} else if ((lv1 = find_lv(seg->lv->vg, cv->v.str))) {
|
||||
set_lv_segment_area_lv(seg, s, lv1, cv->next->v.i,
|
||||
flags);
|
||||
|
||||
@@ -37,6 +37,10 @@ int set_lv_segment_area_pv(struct lv_segment *seg, uint32_t area_num,
|
||||
void set_lv_segment_area_lv(struct lv_segment *seg, uint32_t area_num,
|
||||
struct logical_volume *lv, uint32_t le,
|
||||
uint32_t flags);
|
||||
int move_lv_segment_area(struct lv_segment *seg_to, uint32_t area_to,
|
||||
struct lv_segment *seg_from, uint32_t area_from);
|
||||
void release_lv_segment_area(struct lv_segment *seg, uint32_t s,
|
||||
uint32_t area_reduction);
|
||||
|
||||
struct alloc_handle;
|
||||
struct alloc_handle *allocate_extents(struct volume_group *vg,
|
||||
|
||||
@@ -125,6 +125,74 @@ struct lv_segment *alloc_snapshot_seg(struct logical_volume *lv,
|
||||
return seg;
|
||||
}
|
||||
|
||||
void release_lv_segment_area(struct lv_segment *seg, uint32_t s,
|
||||
uint32_t area_reduction)
|
||||
{
|
||||
if (seg_type(seg, s) == AREA_UNASSIGNED)
|
||||
return;
|
||||
|
||||
if (seg_type(seg, s) == AREA_PV) {
|
||||
release_pv_segment(seg_pvseg(seg, s), area_reduction);
|
||||
return;
|
||||
}
|
||||
|
||||
if (seg_lv(seg, s)->status & MIRROR_IMAGE) {
|
||||
lv_reduce(seg_lv(seg, s), area_reduction);
|
||||
return;
|
||||
}
|
||||
|
||||
if (area_reduction == seg->area_len) {
|
||||
seg_lv(seg, s) = NULL;
|
||||
seg_le(seg, s) = 0;
|
||||
seg_type(seg, s) = AREA_UNASSIGNED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Move a segment area from one segment to another
|
||||
*/
|
||||
int move_lv_segment_area(struct lv_segment *seg_to, uint32_t area_to,
|
||||
struct lv_segment *seg_from, uint32_t area_from)
|
||||
{
|
||||
struct physical_volume *pv;
|
||||
struct logical_volume *lv;
|
||||
uint32_t pe, le;
|
||||
|
||||
switch (seg_type(seg_from, area_from)) {
|
||||
case AREA_PV:
|
||||
pv = seg_pv(seg_from, area_from);
|
||||
pe = seg_pe(seg_from, area_from);
|
||||
|
||||
release_lv_segment_area(seg_from, area_from,
|
||||
seg_from->area_len);
|
||||
release_lv_segment_area(seg_to, area_to, seg_to->area_len);
|
||||
|
||||
if (!set_lv_segment_area_pv(seg_to, area_to, pv, pe)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AREA_LV:
|
||||
lv = seg_lv(seg_from, area_from);
|
||||
le = seg_le(seg_from, area_from);
|
||||
|
||||
release_lv_segment_area(seg_from, area_from,
|
||||
seg_from->area_len);
|
||||
release_lv_segment_area(seg_to, area_to, seg_to->area_len);
|
||||
|
||||
set_lv_segment_area_lv(seg_to, area_to, lv, le, 0);
|
||||
|
||||
break;
|
||||
|
||||
case AREA_UNASSIGNED:
|
||||
release_lv_segment_area(seg_to, area_to, seg_to->area_len);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Link part of a PV to an LV segment.
|
||||
*/
|
||||
@@ -132,7 +200,6 @@ int set_lv_segment_area_pv(struct lv_segment *seg, uint32_t area_num,
|
||||
struct physical_volume *pv, uint32_t pe)
|
||||
{
|
||||
seg->area[area_num].type = AREA_PV;
|
||||
pv->pe_alloc_count += seg->area_len;
|
||||
|
||||
if (!(seg_pvseg(seg, area_num) =
|
||||
assign_peg_to_lvseg(pv, pe, seg->area_len, seg, area_num))) {
|
||||
@@ -175,24 +242,19 @@ static int _lv_segment_reduce(struct lv_segment *seg, uint32_t reduction)
|
||||
} else
|
||||
area_reduction = reduction;
|
||||
|
||||
for (s = 0; s < seg->area_count; s++)
|
||||
release_lv_segment_area(seg, s, area_reduction);
|
||||
|
||||
seg->len -= reduction;
|
||||
seg->area_len -= area_reduction;
|
||||
|
||||
for (s = 0; s < seg->area_count; s++) {
|
||||
if (seg_type(seg, s) == AREA_PV) {
|
||||
release_pv_segment(seg_pvseg(seg, s), area_reduction);
|
||||
seg->lv->vg->free_count += area_reduction;
|
||||
} else if (seg_lv(seg, s)->status & MIRROR_IMAGE)
|
||||
lv_reduce(seg_lv(seg, s), area_reduction);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Entry point for all LV reductions in size.
|
||||
*/
|
||||
int lv_reduce(struct logical_volume *lv, uint32_t extents)
|
||||
static int _lv_reduce(struct logical_volume *lv, uint32_t extents, int delete)
|
||||
{
|
||||
struct lv_list *lvl;
|
||||
struct lv_segment *seg;
|
||||
@@ -225,6 +287,9 @@ int lv_reduce(struct logical_volume *lv, uint32_t extents)
|
||||
lv->le_count -= extents;
|
||||
lv->size = (uint64_t) lv->le_count * lv->vg->extent_size;
|
||||
|
||||
if (!delete)
|
||||
return 1;
|
||||
|
||||
/* Remove the LV if it is now empty */
|
||||
if (!lv->le_count) {
|
||||
if (!(lvl = find_lv_in_vg(lv->vg, lv->name))) {
|
||||
@@ -244,6 +309,19 @@ int lv_reduce(struct logical_volume *lv, uint32_t extents)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Empty an LV
|
||||
*/
|
||||
int lv_empty(struct logical_volume *lv)
|
||||
{
|
||||
return _lv_reduce(lv, 0, lv->le_count);
|
||||
}
|
||||
|
||||
int lv_reduce(struct logical_volume *lv, uint32_t extents)
|
||||
{
|
||||
return _lv_reduce(lv, extents, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Completely remove an LV.
|
||||
*/
|
||||
@@ -406,8 +484,6 @@ static int _setup_alloced_segment(struct logical_volume *lv, uint32_t status,
|
||||
lv->le_count += extents;
|
||||
lv->size += (uint64_t) extents *lv->vg->extent_size;
|
||||
|
||||
lv->vg->free_count -= aa[0].len * area_count;
|
||||
|
||||
if (segtype_is_mirrored(segtype))
|
||||
lv->status |= MIRRORED;
|
||||
|
||||
@@ -624,8 +700,8 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
|
||||
|
||||
/* Only allocate log_area the first time around */
|
||||
if (ix + ix_offset < ah->area_count +
|
||||
(ah->log_count && !ah->log_area.len) ?
|
||||
ah->log_count : 0)
|
||||
((ah->log_count && !ah->log_area.len) ?
|
||||
ah->log_count : 0))
|
||||
/* FIXME With ALLOC_ANYWHERE, need to split areas */
|
||||
break;
|
||||
|
||||
@@ -645,7 +721,7 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
} while (*allocated != needed && can_split);
|
||||
} while (!contiguous && *allocated != needed && can_split);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -912,8 +988,6 @@ int lv_add_log_segment(struct alloc_handle *ah, struct logical_volume *log_lv)
|
||||
log_lv->le_count += ah->log_area.len;
|
||||
log_lv->size += (uint64_t) log_lv->le_count *log_lv->vg->extent_size;
|
||||
|
||||
log_lv->vg->free_count--;
|
||||
|
||||
if (log_lv->vg->fid->fmt->ops->lv_setup &&
|
||||
!log_lv->vg->fid->fmt->ops->lv_setup(log_lv->vg->fid, log_lv)) {
|
||||
stack;
|
||||
|
||||
@@ -86,7 +86,12 @@ int check_lv_segments(struct logical_volume *lv)
|
||||
}
|
||||
|
||||
for (s = 0; s < seg->area_count; s++) {
|
||||
if (seg_type(seg, s) == AREA_PV) {
|
||||
if (seg_type(seg, s) == AREA_UNASSIGNED) {
|
||||
log_error("LV %s: segment %u has unassigned "
|
||||
"area %u.",
|
||||
lv->name, seg_count, s);
|
||||
r = 0;
|
||||
} else if (seg_type(seg, s) == AREA_PV) {
|
||||
if (!seg_pvseg(seg, s) ||
|
||||
seg_pvseg(seg, s)->lvseg != seg ||
|
||||
seg_pvseg(seg, s)->lv_area != s) {
|
||||
@@ -104,6 +109,7 @@ int check_lv_segments(struct logical_volume *lv)
|
||||
lv->name, seg_count, s);
|
||||
r = 0;
|
||||
}
|
||||
/* FIXME I don't think this ever holds?
|
||||
if (seg_le(seg, s) != le) {
|
||||
log_error("LV %s: segment %u has "
|
||||
"inconsistent LV area %u "
|
||||
@@ -111,6 +117,7 @@ int check_lv_segments(struct logical_volume *lv)
|
||||
lv->name, seg_count, s);
|
||||
r = 0;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,12 +197,13 @@ static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
|
||||
break;
|
||||
|
||||
case AREA_PV:
|
||||
if (!assign_peg_to_lvseg(seg_pv(seg, s),
|
||||
if (!(seg_pvseg(split_seg, s) =
|
||||
assign_peg_to_lvseg(seg_pv(seg, s),
|
||||
seg_pe(seg, s) +
|
||||
seg->area_len,
|
||||
seg_pvseg(seg, s)->len -
|
||||
seg->area_len,
|
||||
split_seg, s)) {
|
||||
split_seg, s))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -205,9 +213,8 @@ static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
|
||||
seg_pe(split_seg, s));
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error("Unrecognised segment type %u",
|
||||
seg_type(seg, s));
|
||||
case AREA_UNASSIGNED:
|
||||
log_error("Unassigned area %u found in segment", s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -240,5 +247,10 @@ int lv_split_segment(struct logical_volume *lv, uint32_t le)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!vg_validate(lv->vg)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -465,9 +465,9 @@ int vg_change_pesize(struct cmd_context *cmd, struct volume_group *vg,
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
log_error("Unrecognised segment type "
|
||||
"%u", seg_type(seg, s));
|
||||
case AREA_UNASSIGNED:
|
||||
log_error("Unassigned area %u found in "
|
||||
"segment", s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -697,14 +697,8 @@ int vg_remove(struct volume_group *vg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* After vg_write() returns success,
|
||||
* caller MUST call either vg_commit() or vg_revert()
|
||||
*/
|
||||
int vg_write(struct volume_group *vg)
|
||||
int vg_validate(struct volume_group *vg)
|
||||
{
|
||||
struct list *mdah;
|
||||
struct metadata_area *mda;
|
||||
struct lv_list *lvl;
|
||||
|
||||
if (!check_pv_segments(vg)) {
|
||||
@@ -721,6 +715,23 @@ int vg_write(struct volume_group *vg)
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* After vg_write() returns success,
|
||||
* caller MUST call either vg_commit() or vg_revert()
|
||||
*/
|
||||
int vg_write(struct volume_group *vg)
|
||||
{
|
||||
struct list *mdah;
|
||||
struct metadata_area *mda;
|
||||
|
||||
if (!vg_validate(vg)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vg->status & PARTIAL_VG) {
|
||||
log_error("Cannot change metadata for partial volume group %s",
|
||||
vg->name);
|
||||
@@ -1045,7 +1056,27 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
|
||||
struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
|
||||
int *consistent)
|
||||
{
|
||||
return _vg_read(cmd, vgname, consistent, 0);
|
||||
struct volume_group *vg;
|
||||
struct lv_list *lvl;
|
||||
|
||||
if (!(vg = _vg_read(cmd, vgname, consistent, 0)))
|
||||
return NULL;
|
||||
|
||||
if (!check_pv_segments(vg)) {
|
||||
log_error("Internal error: PV segments corrupted in %s.",
|
||||
vg->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_iterate_items(lvl, &vg->lvs) {
|
||||
if (!check_lv_segments(lvl->lv)) {
|
||||
log_error("Internal error: LV segments corrupted in %s.",
|
||||
lvl->lv->name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return vg;
|
||||
}
|
||||
|
||||
struct volume_group *vg_read_precommitted(struct cmd_context *cmd,
|
||||
|
||||
@@ -81,6 +81,7 @@ typedef enum {
|
||||
} alloc_policy_t;
|
||||
|
||||
typedef enum {
|
||||
AREA_UNASSIGNED = 0,
|
||||
AREA_PV,
|
||||
AREA_LV
|
||||
} area_type_t;
|
||||
@@ -390,6 +391,7 @@ struct format_handler {
|
||||
/*
|
||||
* Utility functions
|
||||
*/
|
||||
int vg_validate(struct volume_group *vg);
|
||||
int vg_write(struct volume_group *vg);
|
||||
int vg_commit(struct volume_group *vg);
|
||||
int vg_revert(struct volume_group *vg);
|
||||
@@ -443,9 +445,12 @@ struct logical_volume *lv_create_empty(struct format_instance *fi,
|
||||
int import,
|
||||
struct volume_group *vg);
|
||||
|
||||
/* Entry point for all LV extent reductions */
|
||||
/* Reduce the size of an LV by extents */
|
||||
int lv_reduce(struct logical_volume *lv, uint32_t extents);
|
||||
|
||||
/* Empty an LV prior to deleting it */
|
||||
int lv_empty(struct logical_volume *lv);
|
||||
|
||||
/* Entry point for all LV extent allocations */
|
||||
int lv_extend(struct logical_volume *lv,
|
||||
struct segment_type *segtype,
|
||||
@@ -534,7 +539,6 @@ int vg_add_snapshot(struct format_instance *fid, const char *name,
|
||||
|
||||
int vg_remove_snapshot(struct logical_volume *cow);
|
||||
|
||||
|
||||
/*
|
||||
* Mirroring functions
|
||||
*/
|
||||
@@ -547,6 +551,9 @@ int create_mirror_layers(struct alloc_handle *ah,
|
||||
uint32_t status,
|
||||
uint32_t region_size,
|
||||
struct logical_volume *log_lv);
|
||||
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors);
|
||||
int remove_all_mirror_images(struct logical_volume *lv);
|
||||
|
||||
int insert_pvmove_mirrors(struct cmd_context *cmd,
|
||||
struct logical_volume *lv_mirr,
|
||||
struct list *source_pvl,
|
||||
|
||||
@@ -171,6 +171,8 @@ int insert_pvmove_mirrors(struct cmd_context *cmd,
|
||||
struct lv_segment *seg;
|
||||
struct lv_list *lvl;
|
||||
struct pv_list *pvl;
|
||||
struct physical_volume *pv;
|
||||
uint32_t pe;
|
||||
int lv_used = 0;
|
||||
uint32_t s, start_le, extent_count = 0u;
|
||||
struct segment_type *segtype;
|
||||
@@ -270,18 +272,19 @@ int insert_pvmove_mirrors(struct cmd_context *cmd,
|
||||
lv_used = 1;
|
||||
}
|
||||
|
||||
pv = seg_pv(seg, s);
|
||||
pe = seg_pe(seg, s);
|
||||
log_very_verbose("Moving %s:%u-%u of %s/%s",
|
||||
dev_name(pvl->pv->dev),
|
||||
seg_pe(seg, s),
|
||||
seg_pe(seg, s) +
|
||||
seg->area_len - 1,
|
||||
pe, pe + seg->area_len - 1,
|
||||
lv->vg->name, lv->name);
|
||||
|
||||
start_le = lv_mirr->le_count;
|
||||
/* FIXME Clean this up */
|
||||
release_lv_segment_area(seg, s, seg->area_len);
|
||||
if (!lv_extend(lv_mirr, segtype, 1,
|
||||
seg->area_len, 0u, seg->area_len,
|
||||
seg_pv(seg, s),
|
||||
seg_pe(seg, s),
|
||||
pv, pe,
|
||||
PVMOVE, allocatable_pvs,
|
||||
alloc)) {
|
||||
log_error("Unable to allocate "
|
||||
@@ -355,22 +358,22 @@ int remove_pvmove_mirrors(struct volume_group *vg,
|
||||
else
|
||||
c = 0;
|
||||
|
||||
if (!set_lv_segment_area_pv(seg, s,
|
||||
seg_pv(mir_seg, c),
|
||||
seg_pe(mir_seg, c))) {
|
||||
if (!move_lv_segment_area(seg, s, mir_seg, c)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Replace mirror with old area */
|
||||
release_lv_segment_area(mir_seg, !c, mir_seg->area_len);
|
||||
|
||||
/* Replace mirror with error segment */
|
||||
if (!
|
||||
(mir_seg->segtype =
|
||||
get_segtype_from_string(vg->cmd,
|
||||
"striped"))) {
|
||||
log_error("Missing striped segtype");
|
||||
"error"))) {
|
||||
log_error("Missing error segtype");
|
||||
return 0;
|
||||
}
|
||||
mir_seg->area_count = 1;
|
||||
mir_seg->area_count = 0;
|
||||
|
||||
/* FIXME Assumes only one pvmove at a time! */
|
||||
lv1->status &= ~LOCKED;
|
||||
@@ -381,6 +384,10 @@ int remove_pvmove_mirrors(struct volume_group *vg,
|
||||
|
||||
}
|
||||
|
||||
if (!lv_empty(lv_mirr)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -392,7 +399,7 @@ const char *get_pvmove_pvname_from_lv_mirr(struct logical_volume *lv_mirr)
|
||||
list_iterate_items(seg, &lv_mirr->segments) {
|
||||
if (!seg_is_mirrored(seg))
|
||||
continue;
|
||||
if (seg->area[0].type != AREA_PV)
|
||||
if (seg_type(seg, 0) != AREA_PV)
|
||||
continue;
|
||||
return dev_name(seg_dev(seg, 0));
|
||||
}
|
||||
@@ -433,7 +440,7 @@ struct logical_volume *find_pvmove_lv(struct volume_group *vg,
|
||||
|
||||
/* Check segment origins point to pvname */
|
||||
list_iterate_items(seg, &lv->segments) {
|
||||
if (seg->area[0].type != AREA_PV)
|
||||
if (seg_type(seg, 0) != AREA_PV)
|
||||
continue;
|
||||
if (seg_dev(seg, 0) != dev)
|
||||
continue;
|
||||
|
||||
@@ -100,6 +100,11 @@ static int _pv_split_segment(struct physical_volume *pv, struct pv_segment *peg,
|
||||
|
||||
list_add_h(&peg->list, &peg_new->list);
|
||||
|
||||
if (peg->lvseg) {
|
||||
peg->pv->pe_alloc_count -= peg_new->len;
|
||||
peg->lvseg->lv->vg->free_count += peg_new->len;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -162,14 +167,24 @@ struct pv_segment *assign_peg_to_lvseg(struct physical_volume *pv,
|
||||
peg->lvseg = seg;
|
||||
peg->lv_area = area_num;
|
||||
|
||||
peg->pv->pe_alloc_count += area_len;
|
||||
peg->lvseg->lv->vg->free_count -= area_len;
|
||||
|
||||
return peg;
|
||||
}
|
||||
|
||||
int release_pv_segment(struct pv_segment *peg, uint32_t area_reduction)
|
||||
{
|
||||
peg->pv->pe_alloc_count -= area_reduction;
|
||||
if (!peg->lvseg) {
|
||||
log_error("release_pv_segment with unallocated segment: "
|
||||
"%s PE %" PRIu32, dev_name(peg->pv->dev), peg->pe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (peg->lvseg->area_len == area_reduction) {
|
||||
peg->pv->pe_alloc_count -= area_reduction;
|
||||
peg->lvseg->lv->vg->free_count += area_reduction;
|
||||
|
||||
if (!peg->lvseg->area_len) {
|
||||
peg->lvseg = NULL;
|
||||
peg->lv_area = 0;
|
||||
|
||||
@@ -178,7 +193,8 @@ int release_pv_segment(struct pv_segment *peg, uint32_t area_reduction)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!pv_split_segment(peg->pv, peg->pe + peg->lvseg->area_len)) {
|
||||
if (!pv_split_segment(peg->pv, peg->pe + peg->lvseg->area_len -
|
||||
area_reduction)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -18,27 +18,28 @@
|
||||
|
||||
#include <selinux/selinux.h>
|
||||
|
||||
int set_selinux_context(const char *path)
|
||||
int set_selinux_context(const char *path, mode_t mode)
|
||||
{
|
||||
security_context_t scontext;
|
||||
|
||||
if (is_selinux_enabled() <= 0)
|
||||
return 1;
|
||||
|
||||
if (matchpathcon(path, 0, &scontext) < 0) {
|
||||
log_sys_error("matchpathcon", path);
|
||||
if (matchpathcon(path, mode, &scontext) < 0) {
|
||||
log_error("%s: matchpathcon %07o failed: %s", path, mode,
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_very_verbose("Setting SELinux context for %s to %s",
|
||||
log_very_verbose("Setting SELinux context for %s to %s.",
|
||||
path, scontext);
|
||||
|
||||
if ((lsetfilecon(path, scontext) < 0) && (errno != ENOTSUP)) {
|
||||
log_sys_error("lsetfilecon", path);
|
||||
free(scontext);
|
||||
freecon(scontext);
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(scontext);
|
||||
freecon(scontext);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#ifndef _LVM_SELINUX_H
|
||||
#define _LVM_SELINUX_H
|
||||
|
||||
int set_selinux_context(const char * path);
|
||||
#include <sys/types.h>
|
||||
|
||||
int set_selinux_context(const char * path, mode_t mode);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -163,8 +163,8 @@ static int _devices_disp(struct report_handle *rh, struct field *field,
|
||||
name = dev_name(seg_dev(seg, s));
|
||||
extent = seg_pe(seg, s);
|
||||
break;
|
||||
default:
|
||||
name = "unknown";
|
||||
case AREA_UNASSIGNED:
|
||||
name = "unassigned";
|
||||
extent = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,8 @@ static int _segments_compatible(struct lv_segment *first,
|
||||
/* FIXME Relax this to first area type != second area type */
|
||||
/* plus the additional AREA_LV checks needed */
|
||||
if ((first->area[s].type != AREA_PV) ||
|
||||
(second->area[s].type != AREA_PV)) return 0;
|
||||
(second->area[s].type != AREA_PV))
|
||||
return 0;
|
||||
|
||||
width = first->area_len;
|
||||
|
||||
|
||||
2702
po/lvm2.po
2702
po/lvm2.po
File diff suppressed because it is too large
Load Diff
@@ -757,13 +757,16 @@ static int _status(int argc, char **argv, void *data)
|
||||
if (!dm_task_run(dmt))
|
||||
goto out;
|
||||
|
||||
if (!name)
|
||||
name = (char *) dm_task_get_name(dmt);
|
||||
|
||||
/* Fetch targets and print 'em */
|
||||
do {
|
||||
next = dm_get_next_target(dmt, next, &start, &length,
|
||||
&target_type, ¶ms);
|
||||
/* Skip if target type doesn't match */
|
||||
if (_switches[TARGET_ARG] && target_type &&
|
||||
strcmp(target_type, _target))
|
||||
if (_switches[TARGET_ARG] &&
|
||||
(!target_type || strcmp(target_type, _target)))
|
||||
continue;
|
||||
if (ls_only) {
|
||||
if (!_switches[EXEC_ARG] || !_command ||
|
||||
|
||||
@@ -497,7 +497,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lp->mirrors && !(vg->fid->fmt->features & FMT_SEGMENTS)) {
|
||||
if (lp->mirrors > 1 && !(vg->fid->fmt->features & FMT_SEGMENTS)) {
|
||||
log_error("Metadata does not support mirroring.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -170,6 +170,14 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
|
||||
log_print("Skipping mirror LV %s", lv->name);
|
||||
continue;
|
||||
}
|
||||
if (lv->status & MIRROR_LOG) {
|
||||
log_print("Skipping mirror log LV %s", lv->name);
|
||||
continue;
|
||||
}
|
||||
if (lv->status & MIRROR_IMAGE) {
|
||||
log_print("Skipping mirror image LV %s", lv->name);
|
||||
continue;
|
||||
}
|
||||
if (lv->status & LOCKED) {
|
||||
log_print("Skipping locked LV %s", lv->name);
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user