mirror of
git://sourceware.org/git/lvm2.git
synced 2025-02-25 21:57:45 +03:00
Cope better with LVM1 minor numbers & LV numbers.
This commit is contained in:
parent
207aa8a131
commit
fee16e1049
@ -15,6 +15,8 @@
|
||||
#define MAX_LV 256
|
||||
#define MAX_VG 99
|
||||
|
||||
#define LVM_BLK_MAJOR 58
|
||||
|
||||
#define MAX_PV_SIZE ((uint32_t) -1) /* 2TB in sectors - 1 */
|
||||
#define MIN_PE_SIZE (8192L >> SECTOR_SHIFT) /* 8 KB in sectors */
|
||||
#define MAX_PE_SIZE (16L * 1024L * (1024L >> SECTOR_SHIFT) * 1024L)
|
||||
|
@ -334,32 +334,12 @@ static int _pv_setup(const struct format_type *fmt,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint32_t _find_free_lvnum(struct logical_volume *lv)
|
||||
{
|
||||
int lvnum_used[MAX_LV];
|
||||
uint32_t i = 0;
|
||||
struct list *lvh;
|
||||
struct lv_list *lvl;
|
||||
|
||||
memset(&lvnum_used, 0, sizeof(lvnum_used));
|
||||
|
||||
list_iterate(lvh, &lv->vg->lvs) {
|
||||
lvl = list_item(lvh, struct lv_list);
|
||||
lvnum_used[lvnum_from_lvid(&lvl->lv->lvid)] = 1;
|
||||
}
|
||||
|
||||
while (lvnum_used[i])
|
||||
i++;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static int _lv_setup(struct format_instance *fid, struct logical_volume *lv)
|
||||
{
|
||||
uint64_t max_size = UINT_MAX;
|
||||
|
||||
if (!*lv->lvid.s)
|
||||
lvid_from_lvnum(&lv->lvid, &lv->vg->id, _find_free_lvnum(lv));
|
||||
lvid_from_lvnum(&lv->lvid, &lv->vg->id, find_free_lvnum(lv));
|
||||
|
||||
if (lv->le_count > MAX_LE_TOTAL) {
|
||||
log_error("logical volumes cannot contain more than "
|
||||
@ -550,7 +530,7 @@ struct format_type *init_format(struct cmd_context *cmd)
|
||||
fmt->ops = &_format1_ops;
|
||||
fmt->name = FMT_LVM1_NAME;
|
||||
fmt->alias = NULL;
|
||||
fmt->features = 0;
|
||||
fmt->features = FMT_RESTRICTED_LVIDS;
|
||||
fmt->private = NULL;
|
||||
|
||||
if (!(fmt->labeller = lvm1_labeller_create(fmt))) {
|
||||
|
@ -339,6 +339,8 @@ static void _export_lv(struct lv_disk *lvd, struct volume_group *vg,
|
||||
if (lv->status & FIXED_MINOR) {
|
||||
lvd->lv_status |= LV_PERSISTENT_MINOR;
|
||||
lvd->lv_dev = MKDEV(lv->major, lv->minor);
|
||||
} else {
|
||||
lvd->lv_dev = MKDEV(LVM_BLK_MAJOR, lvnum_from_lvid(&lv->lvid));
|
||||
}
|
||||
|
||||
lvd->lv_read_ahead = lv->read_ahead;
|
||||
|
@ -743,3 +743,26 @@ int lock_lvs(struct cmd_context *cmd, struct list *lvs, int flags)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t find_free_lvnum(struct logical_volume *lv)
|
||||
{
|
||||
int lvnum_used[MAX_RESTRICTED_LVS + 1];
|
||||
uint32_t i = 0;
|
||||
struct list *lvh;
|
||||
struct lv_list *lvl;
|
||||
int lvnum;
|
||||
|
||||
memset(&lvnum_used, 0, sizeof(lvnum_used));
|
||||
|
||||
list_iterate(lvh, &lv->vg->lvs) {
|
||||
lvl = list_item(lvh, struct lv_list);
|
||||
lvnum = lvnum_from_lvid(&lvl->lv->lvid);
|
||||
if (lvnum <= MAX_RESTRICTED_LVS)
|
||||
lvnum_used[lvnum] = 1;
|
||||
}
|
||||
|
||||
while (lvnum_used[i])
|
||||
i++;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#define STRIPE_SIZE_MAX ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
|
||||
#define PV_MIN_SIZE ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
|
||||
#define PE_ALIGN (65536UL >> SECTOR_SHIFT) /* PE alignment */
|
||||
#define MAX_RESTRICTED_LVS 255 /* Used by FMT_RESTRICTED_LVIDS */
|
||||
|
||||
/* Various flags */
|
||||
/* Note that the bits no longer necessarily correspond to LVM1 disk format */
|
||||
@ -50,6 +51,9 @@
|
||||
/* Format features flags */
|
||||
#define FMT_SEGMENTS 0x00000001 /* Arbitrary segment params? */
|
||||
#define FMT_MDAS 0x00000002 /* Proper metadata areas? */
|
||||
#define FMT_TAGS 0x00000004 /* Tagging? */
|
||||
#define FMT_UNLIMITED_VOLS 0x00000008 /* Unlimited PVs/LVs? */
|
||||
#define FMT_RESTRICTED_LVIDS 0x00000010 /* LVID <= 255 */
|
||||
|
||||
typedef enum {
|
||||
ALLOC_DEFAULT,
|
||||
@ -511,6 +515,8 @@ float pvmove_percent(struct logical_volume *lv_mirr);
|
||||
struct list *lvs_using_lv(struct cmd_context *cmd, struct volume_group *vg,
|
||||
struct logical_volume *lv);
|
||||
|
||||
uint32_t find_free_lvnum(struct logical_volume *lv);
|
||||
|
||||
static inline int validate_name(const char *n)
|
||||
{
|
||||
register char c;
|
||||
|
@ -25,6 +25,8 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
|
||||
void *handle)
|
||||
{
|
||||
struct physical_volume *pv, *existing_pv;
|
||||
struct logical_volume *lv;
|
||||
struct lv_list *lvl;
|
||||
uint64_t size = 0;
|
||||
struct list mdas;
|
||||
int pvmetadatacopies = 0;
|
||||
@ -32,6 +34,8 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
|
||||
uint64_t pe_end = 0, pe_start = 0;
|
||||
struct pv_list *pvl;
|
||||
int change_made = 0;
|
||||
struct lvinfo info;
|
||||
int active = 0;
|
||||
|
||||
if (!vg) {
|
||||
log_error("Unable to find volume group \"%s\"", vg_name);
|
||||
@ -88,6 +92,27 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
/* Attempt to change any LVIDs that are too big */
|
||||
if (cmd->fmt->features & FMT_RESTRICTED_LVIDS) {
|
||||
list_iterate_items(lvl, &vg->lvs) {
|
||||
lv = lvl->lv;
|
||||
if (lvnum_from_lvid(&lv->lvid) < MAX_RESTRICTED_LVS)
|
||||
continue;
|
||||
if (lv_info(lv, &info) && info.exists) {
|
||||
log_error("Logical volume %s must be "
|
||||
"deactivated before conversion.",
|
||||
lv->name);
|
||||
active++;
|
||||
continue;
|
||||
}
|
||||
lvid_from_lvnum(&lv->lvid, &lv->vg->id, find_free_lvnum(lv));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (active)
|
||||
return ECMD_FAILED;
|
||||
|
||||
list_iterate_items(pvl, &vg->pvs) {
|
||||
existing_pv = pvl->pv;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user