"Fossies" - the Fresh Open Source Software archive 
Member "LVM/1.0.8/tools/vgextend.c" of archive lvm_1.0.8.tar.gz:
/*
* tools/vgextend.c
*
* Copyright (C) 1997 - 2002 Heinz Mauelshagen, Sistina Software
*
* April 1997
* May,June,September 1998
* January,October 1999
* February 2000
* February 2002
*
* LVM is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* LVM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LVM; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
/*
* Changelog
*
* 09/11/1997 - added lvmtab handling
* 09/05/1998 - check for volume group beeing extendable
* 16/05/1998 - added lvmtab checking
* 08/06/1998 - checked PV to PE size relation
* 27/06/1998 - changed lvm_tab_* calling convention
* 05/09/1998 - corrected some messages
* 15/01/1999 - avoided unecessary volume group exixtence check
* 06/10/1999 - implemented support for long options
* 15/02/2000 - use lvm_error()
* 23/01/2001 - added call to lvm_init (JT)
* 19/03/2001 - Improved the phrasing of error message
* 07/02/2002 - fixes for > 1TB support
*
*/
/*
* TODO
*
* - avoid pv_read_all_pv
*
*/
#include <lvm_user.h>
char *cmd = NULL;
#ifdef DEBUG
int opt_d = 0;
#endif
int main ( int argc, char **argv) {
int c = 0;
int np = 0;
int np_sav = 0;
int opt_A = 1;
int opt_A_set = 0;
int opt_v = 0;
int p = 0;
int ret = 0;
char *dummy = NULL;
char *error_pv_name = NULL;
char *vg_name = NULL;
vg_t *vg = NULL;
pv_t **pv = NULL;
char *options = "A:h?v" DEBUG_SHORT_OPTION;
struct option long_options[] = {
{ "autobackup", required_argument, NULL, 'A'},
DEBUG_LONG_OPTION
{ "help", no_argument, NULL, 'h'},
{ "verbose", no_argument, NULL, 'v'},
{ NULL, 0, NULL, 0},
};
/* lvm_init(argc, argv); */
cmd = basename ( argv[0]);
LVMTAB_CHECK;
while ( ( c = getopt_long ( argc, argv, options,
long_options, NULL)) != EOF) {
switch ( c) {
case 'A':
opt_A_set++;
if ( opt_A > 1) {
fprintf ( stderr, "%s -- A option already given\n\n", cmd);
return LVM_EINVALID_CMD_LINE;
}
if ( strcmp ( optarg, "y") == 0);
else if ( strcmp ( optarg, "n") == 0) opt_A = 0;
else {
fprintf ( stderr, "%s -- invalid option argument \"%s\"\n\n",
cmd, optarg);
return LVM_EINVALID_CMD_LINE;
}
break;
DEBUG_HANDLE_CASE_D;
case 'h':
case '?':
printf ( "\n%s (IOP %d)\n\n%s -- Volume Group Extend\n\n"
"Synopsis:\n"
"---------\n\n"
"%s\n"
"\t[-A/--autobackup y/n]\n"
DEBUG_HELP
"\t[-h/--help]\n"
"\t[-v/--verbose]\n"
"\tVolumeGroupName\n"
"\tPhysicalDevicePath [PhysicalDevicePath...]\n\n",
lvm_version, LVM_LIB_IOP_VERSION, cmd, cmd);
return 0;
break;
case 'v':
if ( opt_v > 0) {
fprintf ( stderr, "%s -- v option already given\n\n", cmd);
return LVM_EINVALID_CMD_LINE;
}
opt_v++;
break;
default:
fprintf ( stderr, "%s -- invalid command line option \"%c\"\n",
cmd, c);
return LVM_EINVALID_CMD_LINE;
}
}
CMD_MINUS_CHK;
LVM_CHECK_IOP;
LVM_LOCK ( 0);
CMD_CHECK_OPT_A_SET;
if ( optind == argc) {
fprintf ( stderr, "%s -- please enter a volume group name"
" and a physical volume path\n\n", cmd);
return LVM_EVGEXTEND_VG_MISSING;
}
vg_name = argv[optind];
if ( pv_create_kdev_t ( vg_name) != 0) {
fprintf ( stderr, "%s -- please enter a volume group name first\n\n",
cmd);
return LVM_EVGEXTEND_NO_VG_NAME;
}
optind++;
if ( optind == argc) {
fprintf ( stderr, "%s -- please enter a physical volume path\n\n", cmd);
return LVM_EVGEXTEND_PV_MISSING;
}
/* valid VG name? */
if ( opt_v > 0) printf ( "%s -- checking volume group name \"%s\"\n",
cmd, vg_name);
if ( vg_check_name ( vg_name) < 0) {
fprintf ( stderr, "%s -- invalid volume group name \"%s\"\n\n",
cmd, vg_name);
return LVM_EVGEXTEND_VG_CHECK_NAME;
}
if ( opt_v > 0) printf ( "%s -- checking volume group \"%s\" existence\n",
cmd, vg_name);
if ( lvm_tab_vg_check_exist ( vg_name, NULL) != TRUE) {
fprintf ( stderr, "%s -- volume group \"%s\" doesn't exist\n\n",
cmd, vg_name);
return LVM_EVGEXTEND_VG_CHECK_EXIST;
}
if ( opt_v > 0) printf ( "%s -- checking for inactivity of volume group\n",
cmd);
if ( vg_check_active ( vg_name) != TRUE) {
fprintf ( stderr, "%s -- ERROR: volume group \"%s\" must be active for "
"extension\n\n",
cmd, vg_name);
return LVM_EVGEXTEND_VG_CHECK_ACTIVE;
}
/* read complete VGDA */
if ( opt_v > 0) printf ( "%s -- reading data of volume group \"%s\" "
"from lvmtab\n",
cmd, vg_name);
if ( ( ret = lvm_tab_vg_read_with_pv_and_lv ( vg_name, &vg)) < 0) {
fprintf ( stderr, "%s -- ERROR \"%s\" can't extend;"
" couldn't get data of volume group \"%s\"\n\n",
cmd, lvm_error ( ret), vg_name);
return LVM_EVGEXTEND_VG_READ;
}
if ( ! ( vg->vg_status & VG_EXTENDABLE)) {
fprintf ( stderr, "%s -- ERROR: volume group \"%s\" is "
"not extendable\n\n",
cmd, vg_name);
return LVM_EVGEXTEND_NOT_EXTENDABLE;
}
printf ( "%s -- INFO: maximum logical volume size is %s\n",
cmd, ( dummy = lvm_show_size ( LVM_LV_SIZE_2TB ( vg) / 2, LONG)));
free ( dummy); dummy = NULL;
if ( vg->pv_cur >= vg->pv_max) {
fprintf ( stderr, "%s -- maximum physical volume count exceeded\n\n",
cmd);
return LVM_EVGEXTEND_PV_MAX;
}
/* read all PVs */
if ( opt_v > 0) printf ( "%s -- reading data for all physical volumes "
"from disk(s)\n", cmd);
if ( ( ret = pv_read_all_pv ( &pv, FALSE)) < 0) {
fprintf ( stderr, "%s -- ERROR \"%s\" can't extend;"
" couldn't read physical volume data\n\n",
cmd, lvm_error ( ret));
return LVM_EVGEXTEND_PV_READ_ALL_PV;
}
/* check, if PVs are all defined and new,
and extend them in VG structures */
if ( opt_v > 0) printf ( "%s -- extending VGDA structures of volume "
"group \"%s\"\n",
cmd, vg_name);
/* do the VGDA structure extension */
if ( ( ret = vg_setup_for_extend ( &argv[optind], argc - optind,
pv, vg, &error_pv_name)) < 0) {
if ( ret == -LVM_EVG_SETUP_FOR_EXTEND_PV_CHECK_NAME) {
fprintf ( stderr, "%s -- physical volume name \"%s\" is invalid\n\n",
cmd, argv[optind]);
} else if ( ret == -LVM_EVG_SETUP_FOR_EXTEND_MAX_PV) {
fprintf ( stderr, "%s -- ERROR: maximum physical volume count of "
"volume group \"%s\" exceeded\n\n",
cmd, vg_name);
} else if ( ret == -LVM_EVG_SETUP_FOR_EXTEND_PV_GET_SIZE) {
fprintf ( stderr, "%s -- ERROR: getting size of "
"physical volume \"%s\"\n\n",
cmd, error_pv_name);
} else if ( ret == -LVM_EVG_SETUP_FOR_EXTEND_PV_ALREADY) {
fprintf ( stderr, "%s -- ERROR: physical volume \"%s\" "
"already belongs to volume group \"%s\"\n\n",
cmd, error_pv_name, vg_name);
} else if ( ret == -LVM_EVG_SETUP_FOR_EXTEND_PV_CHECK_NEW) {
fprintf ( stderr, "%s -- ERROR: \"%s\" is not a new physical "
"volume\n\n",
cmd, error_pv_name);
} else if ( ret == -LVM_EVG_SETUP_FOR_EXTEND_PV_SIZE_REL) {
fprintf ( stderr, "%s -- ERROR: physical volume \"%s\" too small "
"for physical extent size of volume "
"group \"%s\"\n\n",
cmd, error_pv_name, vg_name);
} else if ( ret == -LVM_EVG_SETUP_FOR_EXTEND_NO_PV) {
fprintf ( stderr, "%s -- ERROR: no physical volumes usable to "
"extend volume group \"%s\"\n\n",
cmd, vg_name);
} else {
fprintf ( stderr, "%s -- ERROR \"%s\" setting up volume group "
"%s for extend\n\n",
cmd, lvm_error ( ret), vg_name);
}
return LVM_EVGEXTEND_VG_SETUP;
}
/* ret > 0 */
if ( opt_v > 0) printf ( "%s -- volume group \"%s\" will be extended by "
"%d new physical volumes\n",
cmd, vg_name, vg->pv_cur - ret);
lvm_dont_interrupt ( 0);
/* extend vg */
np = np_sav = ret;
for ( ; vg->pv[np] != NULL; np++) {
if ( opt_v > 0) printf ( "%s -- extending volume group \"%s\" by "
"physical volume \"%s\" in kernel\n",
cmd, vg_name, vg->pv[np]->pv_name);
if ( ( ret = vg_extend ( vg_name, vg->pv[np], vg)) < 0) {
fprintf ( stderr, "%s -- ERROR \"%s\" extending volume group "
"\"%s\" by physical volume \"%s\" in kernel\n",
cmd, lvm_error ( ret), vg_name, vg->pv[np]->pv_name);
for ( p = np_sav; p < np; p++) vg_reduce ( vg_name, vg->pv[p], vg);
return LVM_EVGEXTEND_VG_EXTEND;
}
}
/* store vg on disk(s) */
if ( opt_v > 0) printf ( "%s -- storing volume group data of "
"%s on disk(s)\n", cmd, vg_name);
if ( ( ret = vg_write_with_pv_and_lv ( vg)) < 0) {
fprintf ( stderr, "%s -- ERROR \"%s\" storing data of volume group "
"\"%s\" on disk(s)\n\n",
cmd, lvm_error ( ret), vg_name);
return LVM_EVGEXTEND_VG_WRITE;
}
if ( opt_v > 0) printf ( "%s -- changing lvmtab\n", cmd);
if ( vg_cfgbackup ( vg_name, LVMTAB_DIR, opt_v, vg) == 0 &&
opt_A > 0) {
printf ( "%s -- doing automatic backup of volume group \"%s\"\n",
cmd, vg_name);
vg_cfgbackup ( vg_name, VG_BACKUP_DIR, opt_v, vg);
} else {
printf ( "%s -- WARNING: you don't have an automatic backup of \"%s\"\n",
cmd, vg_name);
}
printf ( "%s -- volume group \"%s\" successfully extended\n", cmd, vg_name);
lvm_interrupt ();
LVM_UNLOCK ( 0);
if ( opt_v == 0) printf ( "\n");
return 0;
}