mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
71671778ab
This is common code for handling PV create/remove that can be shared by pvcreate/vgcreate/vgextend/pvremove. This does not change any commands to use the new code. - Pull out the hidden equivalent of process_each_pv into an actual top level process_each_pv. - Pull the prompts to the top level, and do not run any prompts while locks are held. The orphan lock is reacquired after any prompts are done, and the devices being created are checked for any change made while the lock was not held. Previously, pvcreate_vol() was the shared function for creating a PV for pvcreate, vgcreate, vgextend. Now, it will be toollib function pvcreate_each_device(). pvcreate_vol() was called effectively as a helper, from within vgcreate and vgextend code paths. pvcreate_each_device() will be called at the same level as other process_each functions. One of the main problems with pvcreate_vol() is that it included a hidden equivalent of process_each_pv for each device being created: pvcreate_vol() -> _pvcreate_check() -> find_pv_by_name() -> get_pvs() -> get_pvs_internal() -> _get_pvs() -> get_vgids() -> /* equivalent to process_each_pv */ dm_list_iterate_items(vgids) vg = vg_read_internal() dm_list_iterate_items(&vg->pvs) pvcreate_each_device() reorganizes the code so that each-VG-each-PV loop is done once, and uses the standard process_each_pv function at the top level of the function.
119 lines
3.1 KiB
C
119 lines
3.1 KiB
C
/*
|
|
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
|
* Copyright (C) 2004-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "tools.h"
|
|
|
|
static int _pvdisplay_single(struct cmd_context *cmd,
|
|
struct volume_group *vg,
|
|
struct physical_volume *pv,
|
|
struct processing_handle *handle __attribute__((unused)))
|
|
{
|
|
const char *pv_name = pv_dev_name(pv);
|
|
int ret = ECMD_PROCESSED;
|
|
uint64_t size;
|
|
|
|
if (is_orphan(pv))
|
|
size = pv_size(pv);
|
|
else
|
|
size = (uint64_t)(pv_pe_count(pv) - pv_pe_alloc_count(pv)) *
|
|
pv_pe_size(pv);
|
|
|
|
if (arg_count(cmd, short_ARG)) {
|
|
log_print("Device \"%s\" has a capacity of %s", pv_name,
|
|
display_size(cmd, size));
|
|
goto out;
|
|
}
|
|
|
|
if (pv_status(pv) & EXPORTED_VG)
|
|
log_print_unless_silent("Physical volume \"%s\" of volume group \"%s\" "
|
|
"is exported", pv_name, pv_vg_name(pv));
|
|
|
|
if (is_orphan(pv))
|
|
log_print_unless_silent("\"%s\" is a new physical volume of \"%s\"",
|
|
pv_name, display_size(cmd, size));
|
|
|
|
if (arg_count(cmd, colon_ARG)) {
|
|
pvdisplay_colons(pv);
|
|
goto out;
|
|
}
|
|
|
|
pvdisplay_full(cmd, pv, NULL);
|
|
|
|
if (arg_count(cmd, maps_ARG))
|
|
pvdisplay_segments(pv);
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
int pvdisplay(struct cmd_context *cmd, int argc, char **argv)
|
|
{
|
|
int lock_global = 0;
|
|
int ret;
|
|
|
|
if (arg_count(cmd, columns_ARG)) {
|
|
if (arg_count(cmd, colon_ARG) || arg_count(cmd, maps_ARG) ||
|
|
arg_count(cmd, short_ARG)) {
|
|
log_error("Incompatible options selected");
|
|
return EINVALID_CMD_LINE;
|
|
}
|
|
return pvs(cmd, argc, argv);
|
|
}
|
|
|
|
if (arg_count(cmd, aligned_ARG) ||
|
|
arg_count(cmd, all_ARG) ||
|
|
arg_count(cmd, binary_ARG) ||
|
|
arg_count(cmd, noheadings_ARG) ||
|
|
arg_count(cmd, options_ARG) ||
|
|
arg_count(cmd, separator_ARG) ||
|
|
arg_count(cmd, sort_ARG) ||
|
|
arg_count(cmd, unbuffered_ARG)) {
|
|
log_error("Incompatible options selected");
|
|
return EINVALID_CMD_LINE;
|
|
}
|
|
|
|
if (arg_count(cmd, colon_ARG) && arg_count(cmd, maps_ARG)) {
|
|
log_error("Option -c not allowed with option -m");
|
|
return EINVALID_CMD_LINE;
|
|
}
|
|
|
|
if (arg_count(cmd, colon_ARG) && arg_count(cmd, short_ARG)) {
|
|
log_error("Option -c is not allowed with option -s");
|
|
return EINVALID_CMD_LINE;
|
|
}
|
|
|
|
/*
|
|
* If the lock_type is LCK_VG_READ (used only in reporting commands),
|
|
* we lock VG_GLOBAL to enable use of metadata cache.
|
|
* This can pause alongide pvscan or vgscan process for a while.
|
|
*/
|
|
if (!lvmetad_active()) {
|
|
lock_global = 1;
|
|
if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_READ, NULL)) {
|
|
log_error("Unable to obtain global lock.");
|
|
return ECMD_FAILED;
|
|
}
|
|
}
|
|
|
|
ret = process_each_pv(cmd, argc, argv, NULL,
|
|
arg_is_set(cmd, all_ARG), 0,
|
|
NULL, _pvdisplay_single);
|
|
|
|
if (lock_global)
|
|
unlock_vg(cmd, VG_GLOBAL);
|
|
|
|
return ret;
|
|
}
|