1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00
lvm2/tools/pvcreate.c
Peter Rajnoha b778653f03 pv_header_extension: add support for writing PV header extension (flags & Embedding Area)
The PV header extension information (PV header extension version, flags
and list of Embedding Area locations) is stored just beyond the PV header base.

When calculating the Embedding Area start value (ea_start), the same logic is
used as when calculating the pe_start value for Data Area - the value must
follow exactly the same alignment restrictions for its start value
(the alignment detected automatically or provided via command line using
the --dataalignment and --dataalignmentoffset arguments).

The Embedding Area is placed at the very start of the PV, starting at
ea_start. The Data Area starting at pe_start is placed next. The pe_start is
still properly aligned. Due to the pe_start alignment, it's possible that the
resulting Embedding Area size (ea_size) ends up bigger in size than requested
(but never less than requested).
2013-02-26 11:28:00 +01:00

132 lines
3.7 KiB
C

/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "tools.h"
#include "metadata-exported.h"
/*
* Intial sanity checking of recovery-related command-line arguments.
* These args are: --restorefile, --uuid, and --physicalvolumesize
*
* Output arguments:
* pp: structure allocated by caller, fields written / validated here
*/
static int pvcreate_restore_params_validate(struct cmd_context *cmd,
int argc, char **argv,
struct pvcreate_params *pp)
{
const char *uuid = NULL;
struct volume_group *vg;
struct pv_list *existing_pvl;
if (arg_count(cmd, restorefile_ARG) && !arg_count(cmd, uuidstr_ARG)) {
log_error("--uuid is required with --restorefile");
return 0;
}
if (!arg_count(cmd, restorefile_ARG) && arg_count(cmd, uuidstr_ARG)) {
if (!arg_count(cmd, norestorefile_ARG) &&
find_config_tree_bool(cmd,
"devices/require_restorefile_with_uuid",
DEFAULT_REQUIRE_RESTOREFILE_WITH_UUID)) {
log_error("--restorefile is required with --uuid");
return 0;
}
}
if (arg_count(cmd, uuidstr_ARG) && argc != 1) {
log_error("Can only set uuid on one volume at once");
return 0;
}
if (arg_count(cmd, uuidstr_ARG)) {
uuid = arg_str_value(cmd, uuidstr_ARG, "");
if (!id_read_format(&pp->rp.id, uuid))
return 0;
pp->rp.idp = &pp->rp.id;
lvmcache_seed_infos_from_lvmetad(cmd); /* need to check for UUID dups */
}
if (arg_count(cmd, restorefile_ARG)) {
pp->rp.restorefile = arg_str_value(cmd, restorefile_ARG, "");
/* The uuid won't already exist */
if (!(vg = backup_read_vg(cmd, NULL, pp->rp.restorefile))) {
log_error("Unable to read volume group from %s",
pp->rp.restorefile);
return 0;
}
if (!(existing_pvl = find_pv_in_vg_by_uuid(vg, pp->rp.idp))) {
release_vg(vg);
log_error("Can't find uuid %s in backup file %s",
uuid, pp->rp.restorefile);
return 0;
}
pp->rp.ea_start = pv_ea_start(existing_pvl->pv);
pp->rp.ea_size = pv_ea_size(existing_pvl->pv);
pp->rp.pe_start = pv_pe_start(existing_pvl->pv);
pp->rp.extent_size = pv_pe_size(existing_pvl->pv);
pp->rp.extent_count = pv_pe_count(existing_pvl->pv);
release_vg(vg);
}
if (arg_sign_value(cmd, physicalvolumesize_ARG, SIGN_NONE) == SIGN_MINUS) {
log_error("Physical volume size may not be negative");
return 0;
}
pp->size = arg_uint64_value(cmd, physicalvolumesize_ARG, UINT64_C(0));
if (arg_count(cmd, restorefile_ARG) || arg_count(cmd, uuidstr_ARG))
pp->zero = 0;
return 1;
}
int pvcreate(struct cmd_context *cmd, int argc, char **argv)
{
int i;
int ret = ECMD_PROCESSED;
struct pvcreate_params pp;
struct physical_volume *pv;
pvcreate_params_set_defaults(&pp);
if (!pvcreate_restore_params_validate(cmd, argc, argv, &pp)) {
return EINVALID_CMD_LINE;
}
if (!pvcreate_params_validate(cmd, argc, argv, &pp)) {
return EINVALID_CMD_LINE;
}
for (i = 0; i < argc; i++) {
if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE)) {
log_error("Can't get lock for orphan PVs");
return ECMD_FAILED;
}
dm_unescape_colons_and_at_signs(argv[i], NULL, NULL);
if (!(pv = pvcreate_single(cmd, argv[i], &pp, 1))) {
stack;
ret = ECMD_FAILED;
}
unlock_vg(cmd, VG_ORPHANS);
if (sigint_caught())
return ret;
}
return ret;
}