mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-10 16:58:47 +03:00
o pvcreate --uuid to specify the uuid (required before using vgcfgrestore
onto a new device). uuid specified must not already exist on the system. o More message tidying. o When checking for label, only read PV metadata. o Add ataraid. [Needs moving into config/defaults files.]
This commit is contained in:
parent
d2b0e8b1c3
commit
add7dc2d5a
@ -51,6 +51,7 @@ static device_info_t device_info[] = {
|
||||
{"ida", 16}, /* Compaq SMART2 */
|
||||
{"cciss", 16}, /* Compaq CCISS array */
|
||||
{"ubd", 16}, /* User-mode virtual block device */
|
||||
{"ataraid", 16}, /* ATA Raid */
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
|
@ -129,13 +129,27 @@ static int _munge_formats(struct pv_disk *pvd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _read_pvd(struct disk_list *data)
|
||||
int read_pvd(struct device *dev, struct pv_disk *pvd)
|
||||
{
|
||||
struct pv_disk *pvd = &data->pvd;
|
||||
if (dev_read(data->dev, 0, sizeof(*pvd), pvd) != sizeof(*pvd))
|
||||
fail;
|
||||
if (dev_read(dev, 0, sizeof(*pvd), pvd) != sizeof(*pvd)) {
|
||||
log_debug("Failed to read PV data from %s", dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
_xlate_pvd(pvd);
|
||||
|
||||
if (pvd->id[0] != 'H' || pvd->id[1] != 'M') {
|
||||
log_very_verbose("%s does not have a valid PV identifier",
|
||||
dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_munge_formats(pvd)) {
|
||||
log_very_verbose("Unknown metadata version %d found on %s",
|
||||
pvd->version, dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -255,20 +269,8 @@ static struct disk_list *__read_disk(struct device *dev, struct pool *mem,
|
||||
list_init(&data->uuids);
|
||||
list_init(&data->lvds);
|
||||
|
||||
if (!_read_pvd(data)) {
|
||||
log_debug("Failed to read PV data from %s", name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (data->pvd.id[0] != 'H' || data->pvd.id[1] != 'M') {
|
||||
log_very_verbose("%s does not have a valid PV identifier",
|
||||
name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!_munge_formats(&data->pvd)) {
|
||||
log_very_verbose("Unknown metadata version %d found on %s",
|
||||
data->pvd.version, name);
|
||||
if (!read_pvd(dev, &data->pvd)) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
|
@ -178,6 +178,8 @@ int calculate_extent_count(struct physical_volume *pv);
|
||||
* Low level io routines which read/write
|
||||
* disk_lists.
|
||||
*/
|
||||
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);
|
||||
|
||||
|
@ -6,11 +6,14 @@
|
||||
|
||||
#include "lvm1_label.h"
|
||||
#include "dbg_malloc.h"
|
||||
#include "pool.h"
|
||||
#include "disk-rep.h"
|
||||
#include "log.h"
|
||||
#include "label.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
static void _not_supported(const char *op)
|
||||
{
|
||||
log_err("The '%s' operation is not supported for the lvm1 labeller.",
|
||||
@ -19,12 +22,20 @@ static void _not_supported(const char *op)
|
||||
|
||||
static int _can_handle(struct labeller *l, struct device *dev)
|
||||
{
|
||||
struct pool *mem = (struct pool *) l->private;
|
||||
struct disk_list *dl;
|
||||
struct pv_disk pvd;
|
||||
int r;
|
||||
|
||||
dl = read_disk(dev, mem, NULL);
|
||||
pool_empty(mem);
|
||||
return dl ? 1 : 0;
|
||||
if (!dev_open(dev, O_RDONLY)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = read_pvd(dev, &pvd);
|
||||
|
||||
if (!dev_close(dev))
|
||||
stack;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _write(struct labeller *l,
|
||||
@ -40,7 +51,7 @@ static int _remove(struct labeller *l, struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct label *_to_label(struct disk_list *dl)
|
||||
static struct label *_to_label(struct pv_disk *pvd)
|
||||
{
|
||||
struct label *l;
|
||||
struct lvm_label_info *info;
|
||||
@ -50,12 +61,12 @@ static struct label *_to_label(struct disk_list *dl)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(info = (struct lvm_label_info *) dbg_strdup(dl->pvd.vg_name))) {
|
||||
if (!(info = (struct lvm_label_info *) dbg_strdup(pvd->vg_name))) {
|
||||
dbg_free(l);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(&l->id, &dl->pvd.pv_uuid, sizeof(l->id));
|
||||
memcpy(&l->id, &pvd->pv_uuid, sizeof(l->id));
|
||||
strcpy(l->volume_type, "lvm");
|
||||
l->version[0] = 1;
|
||||
l->version[0] = 0;
|
||||
@ -65,14 +76,22 @@ static struct label *_to_label(struct disk_list *dl)
|
||||
return l;
|
||||
}
|
||||
|
||||
static int _read(struct labeller *l,
|
||||
struct device *dev, struct label **label)
|
||||
static int _read(struct labeller *l, struct device *dev, struct label **label)
|
||||
{
|
||||
struct pool *mem = (struct pool *) l->private;
|
||||
struct disk_list *dl;
|
||||
struct pv_disk pvd;
|
||||
int r = 0;
|
||||
|
||||
if (!(dl = read_disk(dev, mem, NULL))) {
|
||||
if (!dev_open(dev, O_RDONLY)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = read_pvd(dev, &pvd);
|
||||
|
||||
if (!dev_close(dev))
|
||||
stack;
|
||||
|
||||
if (!r) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@ -80,13 +99,12 @@ static int _read(struct labeller *l,
|
||||
/*
|
||||
* Convert the disk_list into a label structure.
|
||||
*/
|
||||
if ((*label = _to_label(dl)))
|
||||
r = 1;
|
||||
else
|
||||
if (!(*label = _to_label(&pvd))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pool_empty(mem);
|
||||
return r;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _destroy_label(struct labeller *l, struct label *label)
|
||||
@ -97,8 +115,6 @@ static void _destroy_label(struct labeller *l, struct label *label)
|
||||
|
||||
static void _destroy(struct labeller *l)
|
||||
{
|
||||
struct pool *mem = (struct pool *) l->private;
|
||||
pool_destroy(mem);
|
||||
dbg_free(l);
|
||||
}
|
||||
|
||||
@ -116,21 +132,14 @@ struct label_ops _lvm1_ops = {
|
||||
struct labeller *lvm1_labeller_create(void)
|
||||
{
|
||||
struct labeller *l;
|
||||
struct pool *mem;
|
||||
|
||||
if (!(l = dbg_malloc(sizeof(*l)))) {
|
||||
log_err("Couldn't allocate labeller object.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(mem = pool_create(256))) {
|
||||
log_err("Couldn't create pool object for labeller.");
|
||||
dbg_free(l);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
l->ops = &_lvm1_ops;
|
||||
l->private = mem;
|
||||
l->private = NULL;
|
||||
|
||||
return l;
|
||||
}
|
||||
|
@ -439,22 +439,26 @@ static struct volume_group *_read_vg(struct pool *mem, struct config_file *cf,
|
||||
|
||||
vgn = vgn->child;
|
||||
if (!_read_id(&vg->id, vgn, "id")) {
|
||||
log_err("Couldn't read uuid for volume group.");
|
||||
log_err("Couldn't read uuid for volume group %s.",
|
||||
vg->name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(cn = find_config_node(vgn, "status", '/'))) {
|
||||
log_err("Couldn't find status flags for volume group.");
|
||||
log_err("Couldn't find status flags for volume group %s.",
|
||||
vg->name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(read_flags(&vg->status, VG_FLAGS, cn->v))) {
|
||||
log_err("Couldn't read status flags for volume group.");
|
||||
log_err("Couldn't read status flags for volume group %s.",
|
||||
vg->name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!_read_int32(vgn, "extent_size", &vg->extent_size)) {
|
||||
log_err("Couldn't read extent size for volume group.");
|
||||
log_err("Couldn't read extent size for volume group %s.",
|
||||
vg->name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
@ -464,12 +468,14 @@ static struct volume_group *_read_vg(struct pool *mem, struct config_file *cf,
|
||||
*/
|
||||
|
||||
if (!_read_int32(vgn, "max_lv", &vg->max_lv)) {
|
||||
log_err("Couldn't read 'max_lv' for volume group.");
|
||||
log_err("Couldn't read 'max_lv' for volume group %s.",
|
||||
vg->name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!_read_int32(vgn, "max_pv", &vg->max_pv)) {
|
||||
log_err("Couldn't read 'max_pv' for volume group.");
|
||||
log_err("Couldn't read 'max_pv' for volume group %s.",
|
||||
vg->name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
@ -485,8 +491,8 @@ static struct volume_group *_read_vg(struct pool *mem, struct config_file *cf,
|
||||
list_init(&vg->pvs);
|
||||
if (!_read_sections("physical_volumes", _read_pv, mem, vg,
|
||||
vgn, pv_hash, um)) {
|
||||
log_err("Couldn't read all physical volumes for volume "
|
||||
"group.");
|
||||
log_err("Couldn't find all physical volumes for volume "
|
||||
"group %s.", vg->name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
@ -494,7 +500,7 @@ static struct volume_group *_read_vg(struct pool *mem, struct config_file *cf,
|
||||
if (!_read_sections("logical_volumes", _read_lv, mem, vg,
|
||||
vgn, pv_hash, um)) {
|
||||
log_err("Couldn't read all logical volumes for volume "
|
||||
"group.");
|
||||
"group %s.", vg->name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
@ -526,12 +532,14 @@ struct volume_group *text_vg_import(struct cmd_context *cmd,
|
||||
}
|
||||
|
||||
if (!read_config(cf, file)) {
|
||||
log_err("Couldn't read volume group file.");
|
||||
log_error("Couldn't read volume group file.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(vg = _read_vg(cmd->mem, cf, um)))
|
||||
if (!(vg = _read_vg(cmd->mem, cf, um))) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
|
||||
vg->cmd = cmd;
|
||||
|
||||
|
@ -185,7 +185,9 @@ struct volume_group *vg_create(struct format_instance *fi, const char *vg_name,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct physical_volume *pv_create(struct format_instance *fi, const char *name)
|
||||
struct physical_volume *pv_create(struct format_instance *fi,
|
||||
const char *name,
|
||||
struct id *id)
|
||||
{
|
||||
struct pool *mem = fi->cmd->mem;
|
||||
struct physical_volume *pv = pool_alloc(mem, sizeof (*pv));
|
||||
@ -195,7 +197,11 @@ struct physical_volume *pv_create(struct format_instance *fi, const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
id_create(&pv->id);
|
||||
if (!id)
|
||||
id_create(&pv->id);
|
||||
else
|
||||
memcpy(&pv->id, id, sizeof(*id));
|
||||
|
||||
if (!(pv->dev = dev_cache_get(name, fi->cmd->filter))) {
|
||||
log_err("Couldn't find device '%s'", name);
|
||||
goto bad;
|
||||
|
@ -233,7 +233,8 @@ struct format_handler {
|
||||
* Utility functions
|
||||
*/
|
||||
struct physical_volume *pv_create(struct format_instance *fi,
|
||||
const char *name);
|
||||
const char *name,
|
||||
struct id *id);
|
||||
|
||||
struct volume_group *vg_create(struct format_instance *fi, const char *name,
|
||||
uint32_t extent_size, int max_pv, int max_lv,
|
||||
|
@ -36,13 +36,19 @@ to add
|
||||
.I PhysicalVolume
|
||||
to an existing volume group.
|
||||
.SH OPTIONS
|
||||
See \fBlvm\fP for common options.
|
||||
See \fBlvm\fP(8) for common options.
|
||||
.TP
|
||||
.BR \-f ", " \-\-force
|
||||
Force the creation without any confirmation. You can not recreate
|
||||
(reinitialize) a physical volume belonging to an existing volume group.
|
||||
In an emergency you can override this behaviour with -ff. In no case
|
||||
case can you initialize an active physical volume with this command.
|
||||
In an emergency you can override this behaviour with -ff.
|
||||
.TP
|
||||
.BR \-u ", " \-\-uuid " uuid"
|
||||
Specify the uuid for the device.
|
||||
Without this option, \fBpvcreate\fP generates a random uuid.
|
||||
All of your physical volumes must have unique uuids.
|
||||
You need to use this option to restore a backup of LVM metadata onto
|
||||
a replacement device - see \fBvgcfgrestore\fP(8).
|
||||
.TP
|
||||
.BR \-y ", " \-\-yes
|
||||
Answer yes to all questions.
|
||||
@ -54,4 +60,5 @@ SCSI disk for later use by LVM:
|
||||
.sp
|
||||
.SH SEE ALSO
|
||||
.BR lvm "(8), " vgcreate "(8), " vgextend "(8), " lvcreate "(8), "
|
||||
.BR cfdisk "(8), " fdisk "(8), " losetup "(8), " mdadd "(8)"
|
||||
.BR cfdisk "(8), " fdisk "(8), " losetup "(8), " mdadd "(8), "
|
||||
.BR vgcfgrestore "(8)"
|
||||
|
@ -60,6 +60,7 @@ arg(snapshot_ARG, 's', "snapshot", NULL)
|
||||
arg(short_ARG, 's', "short", NULL)
|
||||
arg(test_ARG, 't', "test", NULL)
|
||||
arg(uuid_ARG, 'u', "uuid", NULL)
|
||||
arg(uuidstr_ARG, 'u', "uuid", string_arg)
|
||||
arg(uuidlist_ARG, 'U', "uuidlist", NULL)
|
||||
arg(verbose_ARG, 'v', "verbose", NULL)
|
||||
arg(volumegroup_ARG, 'V', "volumegroup", NULL)
|
||||
|
@ -261,11 +261,12 @@ xx(pvcreate,
|
||||
"\t[-h|--help] " "\n"
|
||||
"\t[-y|--yes]" "\n"
|
||||
"\t[-t|--test] " "\n"
|
||||
"\t[-u|--uuid uuid] " "\n"
|
||||
"\t[-v|--verbose] " "\n"
|
||||
"\t[--version] " "\n"
|
||||
"\tPhysicalVolume [PhysicalVolume...]\n",
|
||||
|
||||
force_ARG, test_ARG, yes_ARG)
|
||||
force_ARG, test_ARG, uuidstr_ARG, yes_ARG)
|
||||
|
||||
xx(pvdata,
|
||||
"Display the on-disk metadata for physical volume(s)",
|
||||
|
@ -77,11 +77,26 @@ static int pvcreate_check(const char *name)
|
||||
static void pvcreate_single(const char *pv_name)
|
||||
{
|
||||
struct physical_volume *pv;
|
||||
struct id id, *idp = NULL;
|
||||
char *uuid;
|
||||
struct device *dev;
|
||||
|
||||
if (arg_count(uuidstr_ARG)) {
|
||||
uuid = arg_str_value(uuidstr_ARG,"");
|
||||
if (!id_read_format(&id, uuid))
|
||||
return;
|
||||
if ((dev = uuid_map_lookup(the_um, &id))) {
|
||||
log_error("uuid %s already in use on %s", uuid,
|
||||
dev_name(dev));
|
||||
return;
|
||||
}
|
||||
idp = &id;
|
||||
}
|
||||
|
||||
if (!pvcreate_check(pv_name))
|
||||
return;
|
||||
|
||||
if (!(pv = pv_create(fid, pv_name))) {
|
||||
if (!(pv = pv_create(fid, pv_name, idp))) {
|
||||
log_err("Failed to setup physical volume %s", pv_name);
|
||||
return;
|
||||
}
|
||||
@ -107,6 +122,11 @@ int pvcreate(int argc, char **argv)
|
||||
return EINVALID_CMD_LINE;
|
||||
}
|
||||
|
||||
if (arg_count(uuidstr_ARG) && argc != 1) {
|
||||
log_error("Can only set uuid on one volume at once");
|
||||
return EINVALID_CMD_LINE;
|
||||
}
|
||||
|
||||
if (arg_count(yes_ARG) && !arg_count(force_ARG)) {
|
||||
log_error("Option y can only be given with option f");
|
||||
return EINVALID_CMD_LINE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user