2009-07-14 07:02:14 +04:00
/*
* Copyright ( C ) 2008 , 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 "lib.h"
# include "toolcontext.h"
2010-07-09 20:57:34 +04:00
# include "metadata.h"
2009-07-14 07:02:14 +04:00
# include "archiver.h"
# include "locking.h"
2009-07-24 16:48:21 +04:00
# include "lvmcache.h"
2010-02-24 21:16:18 +03:00
# include "lvm_misc.h"
2010-12-15 02:20:58 +03:00
# include "lvm2app.h"
2009-07-26 05:54:40 +04:00
2010-02-24 21:16:18 +03:00
int lvm_vg_add_tag ( vg_t vg , const char * tag )
{
if ( vg_read_error ( vg ) )
return - 1 ;
if ( ! vg_check_write_mode ( vg ) )
return - 1 ;
if ( ! vg_change_tag ( vg , tag , 1 ) )
return - 1 ;
return 0 ;
}
int lvm_vg_remove_tag ( vg_t vg , const char * tag )
{
if ( vg_read_error ( vg ) )
return - 1 ;
if ( ! vg_check_write_mode ( vg ) )
return - 1 ;
if ( ! vg_change_tag ( vg , tag , 0 ) )
return - 1 ;
return 0 ;
}
2009-08-13 16:16:45 +04:00
vg_t lvm_vg_create ( lvm_t libh , const char * vg_name )
2009-07-14 07:02:14 +04:00
{
2009-08-13 16:16:45 +04:00
struct volume_group * vg ;
2009-07-23 05:20:22 +04:00
vg = vg_create ( ( struct cmd_context * ) libh , vg_name ) ;
/* FIXME: error handling is still TBD */
if ( vg_read_error ( vg ) ) {
2010-12-08 23:50:48 +03:00
free_vg ( vg ) ;
2009-07-23 05:20:22 +04:00
return NULL ;
}
2009-07-28 19:14:56 +04:00
vg - > open_mode = ' w ' ;
2009-08-13 16:16:45 +04:00
return ( vg_t ) vg ;
2009-07-14 07:02:14 +04:00
}
2009-08-13 16:16:45 +04:00
int lvm_vg_extend ( vg_t vg , const char * device )
2009-07-14 07:02:14 +04:00
{
2009-10-06 00:03:08 +04:00
struct pvcreate_params pp ;
2009-07-14 07:02:14 +04:00
if ( vg_read_error ( vg ) )
2009-07-27 00:28:59 +04:00
return - 1 ;
2009-07-14 07:02:14 +04:00
2009-07-28 19:14:56 +04:00
if ( ! vg_check_write_mode ( vg ) )
return - 1 ;
2009-07-24 19:12:50 +04:00
if ( ! lock_vol ( vg - > cmd , VG_ORPHANS , LCK_VG_WRITE ) ) {
log_error ( " Can't get lock for orphan PVs " ) ;
2009-07-27 00:28:59 +04:00
return - 1 ;
2009-07-24 19:12:50 +04:00
}
2009-11-01 22:51:54 +03:00
pvcreate_params_set_defaults ( & pp ) ;
2011-02-18 17:47:28 +03:00
if ( ! vg_extend ( vg , 1 , & device , & pp ) ) {
2009-07-24 19:12:50 +04:00
unlock_vg ( vg - > cmd , VG_ORPHANS ) ;
2009-07-27 00:28:59 +04:00
return - 1 ;
2009-07-24 19:12:50 +04:00
}
/*
* FIXME : Either commit to disk , or keep holding VG_ORPHANS and
* release in lvm_vg_close ( ) .
*/
unlock_vg ( vg - > cmd , VG_ORPHANS ) ;
2009-07-27 00:28:59 +04:00
return 0 ;
2009-07-14 07:02:14 +04:00
}
2009-08-13 16:16:45 +04:00
int lvm_vg_reduce ( vg_t vg , const char * device )
2009-07-27 21:44:29 +04:00
{
if ( vg_read_error ( vg ) )
return - 1 ;
2009-07-28 19:14:56 +04:00
if ( ! vg_check_write_mode ( vg ) )
return - 1 ;
2009-07-27 21:44:29 +04:00
2011-02-18 17:47:28 +03:00
if ( ! vg_reduce ( vg , device ) )
2009-07-27 21:44:29 +04:00
return - 1 ;
return 0 ;
}
2009-08-13 16:16:45 +04:00
int lvm_vg_set_extent_size ( vg_t vg , uint32_t new_size )
2009-07-14 07:02:14 +04:00
{
if ( vg_read_error ( vg ) )
2009-07-27 00:28:59 +04:00
return - 1 ;
2009-07-28 19:14:56 +04:00
if ( ! vg_check_write_mode ( vg ) )
return - 1 ;
2009-07-14 07:02:14 +04:00
2010-02-16 03:27:01 +03:00
if ( ! vg_set_extent_size ( vg , new_size / SECTOR_SIZE ) )
2009-07-27 00:28:59 +04:00
return - 1 ;
2009-07-14 07:02:14 +04:00
return 0 ;
}
2009-08-13 16:16:45 +04:00
int lvm_vg_write ( vg_t vg )
2009-07-14 07:02:14 +04:00
{
2009-07-27 21:44:29 +04:00
struct pv_list * pvl ;
2009-07-14 07:02:14 +04:00
if ( vg_read_error ( vg ) )
2009-07-27 00:28:59 +04:00
return - 1 ;
2009-07-28 19:14:56 +04:00
if ( ! vg_check_write_mode ( vg ) )
return - 1 ;
2009-07-14 07:02:14 +04:00
2009-07-27 21:44:29 +04:00
if ( dm_list_empty ( & vg - > pvs ) ) {
2009-09-03 01:40:10 +04:00
if ( ! vg_remove ( vg ) )
return - 1 ;
return 0 ;
2009-07-27 21:44:29 +04:00
}
if ( ! dm_list_empty ( & vg - > removed_pvs ) ) {
if ( ! lock_vol ( vg - > cmd , VG_ORPHANS , LCK_VG_WRITE ) ) {
log_error ( " Can't get lock for orphan PVs " ) ;
return 0 ;
}
}
2009-07-27 00:28:59 +04:00
if ( ! archive ( vg ) )
return - 1 ;
2009-07-14 07:02:14 +04:00
/* Store VG on disk(s) */
2009-07-27 00:28:59 +04:00
if ( ! vg_write ( vg ) | | ! vg_commit ( vg ) )
return - 1 ;
2009-07-27 21:44:29 +04:00
if ( ! dm_list_empty ( & vg - > removed_pvs ) ) {
dm_list_iterate_items ( pvl , & vg - > removed_pvs ) {
pv_write_orphan ( vg - > cmd , pvl - > pv ) ;
2011-04-01 17:44:51 +04:00
pv_set_fid ( pvl - > pv , NULL ) ;
2009-07-27 21:44:29 +04:00
/* FIXME: do pvremove / label_remove()? */
}
dm_list_init ( & vg - > removed_pvs ) ;
unlock_vg ( vg - > cmd , VG_ORPHANS ) ;
}
2009-07-14 07:02:14 +04:00
return 0 ;
}
2009-08-13 16:16:45 +04:00
int lvm_vg_close ( vg_t vg )
2009-07-14 07:02:14 +04:00
{
2009-07-22 07:13:35 +04:00
if ( vg_read_error ( vg ) = = FAILED_LOCKING )
2010-12-08 23:50:48 +03:00
free_vg ( vg ) ;
2009-07-22 07:13:35 +04:00
else
2010-12-08 23:50:48 +03:00
unlock_and_free_vg ( vg - > cmd , vg , vg - > name ) ;
2009-07-27 00:28:59 +04:00
return 0 ;
2009-07-14 07:02:14 +04:00
}
2009-08-13 16:16:45 +04:00
int lvm_vg_remove ( vg_t vg )
2009-07-14 07:02:14 +04:00
{
if ( vg_read_error ( vg ) )
2009-07-27 00:28:59 +04:00
return - 1 ;
2009-07-28 19:14:56 +04:00
if ( ! vg_check_write_mode ( vg ) )
return - 1 ;
2009-07-14 07:02:14 +04:00
2009-09-03 01:39:29 +04:00
if ( ! vg_remove_check ( vg ) )
return - 1 ;
2010-06-30 22:03:52 +04:00
vg_remove_pvs ( vg ) ;
2009-07-14 07:02:14 +04:00
return 0 ;
}
2009-07-23 02:24:16 +04:00
2009-08-13 16:16:45 +04:00
vg_t lvm_vg_open ( lvm_t libh , const char * vgname , const char * mode ,
2009-07-23 02:24:16 +04:00
uint32_t flags )
{
uint32_t internal_flags = 0 ;
2009-08-13 16:16:45 +04:00
struct volume_group * vg ;
2009-07-23 02:24:16 +04:00
if ( ! strncmp ( mode , " w " , 1 ) )
internal_flags | = READ_FOR_UPDATE ;
else if ( strncmp ( mode , " r " , 1 ) ) {
log_errno ( EINVAL , " Invalid VG open mode " ) ;
return NULL ;
}
vg = vg_read ( ( struct cmd_context * ) libh , vgname , NULL , internal_flags ) ;
if ( vg_read_error ( vg ) ) {
/* FIXME: use log_errno either here in inside vg_read */
2010-12-08 23:50:48 +03:00
free_vg ( vg ) ;
2009-07-23 02:24:16 +04:00
return NULL ;
}
2009-07-28 19:14:56 +04:00
/* FIXME: combine this with locking ? */
vg - > open_mode = mode [ 0 ] ;
2009-07-23 02:24:16 +04:00
2009-08-13 16:16:45 +04:00
return ( vg_t ) vg ;
2009-07-23 02:24:16 +04:00
}
2009-07-24 03:39:02 +04:00
2009-08-13 16:16:45 +04:00
struct dm_list * lvm_vg_list_pvs ( vg_t vg )
2009-07-24 03:39:02 +04:00
{
struct dm_list * list ;
pv_list_t * pvs ;
struct pv_list * pvl ;
if ( dm_list_empty ( & vg - > pvs ) )
return NULL ;
if ( ! ( list = dm_pool_zalloc ( vg - > vgmem , sizeof ( * list ) ) ) ) {
2009-07-28 01:03:15 +04:00
log_errno ( ENOMEM , " Memory allocation fail for dm_list. " ) ;
2009-07-24 03:39:02 +04:00
return NULL ;
}
dm_list_init ( list ) ;
dm_list_iterate_items ( pvl , & vg - > pvs ) {
if ( ! ( pvs = dm_pool_zalloc ( vg - > vgmem , sizeof ( * pvs ) ) ) ) {
2009-07-27 00:29:28 +04:00
log_errno ( ENOMEM ,
2009-07-28 01:03:15 +04:00
" Memory allocation fail for lvm_pv_list. " ) ;
2009-07-24 03:39:02 +04:00
return NULL ;
}
pvs - > pv = pvl - > pv ;
dm_list_add ( list , & pvs - > list ) ;
}
return list ;
}
2009-08-13 16:16:45 +04:00
struct dm_list * lvm_vg_list_lvs ( vg_t vg )
2009-07-24 03:39:02 +04:00
{
struct dm_list * list ;
lv_list_t * lvs ;
struct lv_list * lvl ;
if ( dm_list_empty ( & vg - > lvs ) )
return NULL ;
if ( ! ( list = dm_pool_zalloc ( vg - > vgmem , sizeof ( * list ) ) ) ) {
2009-07-28 01:03:15 +04:00
log_errno ( ENOMEM , " Memory allocation fail for dm_list. " ) ;
2009-07-24 03:39:02 +04:00
return NULL ;
}
dm_list_init ( list ) ;
dm_list_iterate_items ( lvl , & vg - > lvs ) {
if ( ! ( lvs = dm_pool_zalloc ( vg - > vgmem , sizeof ( * lvs ) ) ) ) {
2009-07-27 00:29:28 +04:00
log_errno ( ENOMEM ,
2009-07-28 01:03:15 +04:00
" Memory allocation fail for lvm_lv_list. " ) ;
2009-07-24 03:39:02 +04:00
return NULL ;
}
lvs - > lv = lvl - > lv ;
dm_list_add ( list , & lvs - > list ) ;
}
return list ;
}
2009-07-24 03:40:05 +04:00
2010-02-24 21:16:18 +03:00
struct dm_list * lvm_vg_get_tags ( const vg_t vg )
{
return tag_list_copy ( vg - > vgmem , & vg - > tags ) ;
}
2009-08-13 16:16:45 +04:00
uint64_t lvm_vg_get_seqno ( const vg_t vg )
2009-07-28 17:17:04 +04:00
{
return vg_seqno ( vg ) ;
}
2009-09-14 23:43:11 +04:00
uint64_t lvm_vg_is_clustered ( const vg_t vg )
{
return vg_is_clustered ( vg ) ;
}
uint64_t lvm_vg_is_exported ( const vg_t vg )
{
return vg_is_exported ( vg ) ;
}
uint64_t lvm_vg_is_partial ( const vg_t vg )
{
return ( vg_missing_pv_count ( vg ) ! = 0 ) ;
}
2009-07-26 17:06:59 +04:00
/* FIXME: invalid handle? return INTMAX? */
2009-08-13 16:16:45 +04:00
uint64_t lvm_vg_get_size ( const vg_t vg )
2009-07-26 17:06:59 +04:00
{
2010-02-16 03:27:01 +03:00
return SECTOR_SIZE * vg_size ( vg ) ;
2009-07-26 17:06:59 +04:00
}
2009-08-13 16:16:45 +04:00
uint64_t lvm_vg_get_free_size ( const vg_t vg )
2009-07-26 17:06:59 +04:00
{
2010-02-16 03:27:01 +03:00
return SECTOR_SIZE * vg_free ( vg ) ;
2009-07-26 17:06:59 +04:00
}
2009-08-13 16:16:45 +04:00
uint64_t lvm_vg_get_extent_size ( const vg_t vg )
2009-07-26 17:06:59 +04:00
{
2010-02-16 03:27:01 +03:00
return SECTOR_SIZE * vg_extent_size ( vg ) ;
2009-07-26 17:06:59 +04:00
}
2009-08-13 16:16:45 +04:00
uint64_t lvm_vg_get_extent_count ( const vg_t vg )
2009-07-26 17:06:59 +04:00
{
return vg_extent_count ( vg ) ;
}
2009-08-13 16:16:45 +04:00
uint64_t lvm_vg_get_free_extent_count ( const vg_t vg )
2009-07-26 17:06:59 +04:00
{
return vg_free_count ( vg ) ;
}
2009-08-13 16:16:45 +04:00
uint64_t lvm_vg_get_pv_count ( const vg_t vg )
2009-07-26 17:06:59 +04:00
{
return vg_pv_count ( vg ) ;
2009-09-14 19:45:23 +04:00
}
uint64_t lvm_vg_get_max_pv ( const vg_t vg )
{
return vg_max_pv ( vg ) ;
}
uint64_t lvm_vg_get_max_lv ( const vg_t vg )
{
return vg_max_lv ( vg ) ;
2009-07-26 17:06:59 +04:00
}
2010-04-19 19:22:24 +04:00
const char * lvm_vg_get_uuid ( const vg_t vg )
2009-07-24 03:40:05 +04:00
{
2010-09-30 18:07:47 +04:00
return vg_uuid_dup ( vg ) ;
2009-07-24 03:40:05 +04:00
}
2010-04-19 19:22:24 +04:00
const char * lvm_vg_get_name ( const vg_t vg )
2009-07-24 03:40:05 +04:00
{
2010-04-19 19:22:24 +04:00
return dm_pool_strndup ( vg - > vgmem , ( const char * ) vg - > name , NAME_LEN + 1 ) ;
2009-07-24 03:40:05 +04:00
}
2009-07-24 16:47:15 +04:00
2010-10-25 18:08:43 +04:00
struct lvm_property_value lvm_vg_get_property ( const vg_t vg , const char * name )
{
2010-11-17 23:12:39 +03:00
return get_property ( NULL , vg , NULL , NULL , NULL , name ) ;
2010-10-25 18:08:43 +04:00
}
2010-11-17 22:16:05 +03:00
int lvm_vg_set_property ( const vg_t vg , const char * name ,
struct lvm_property_value * value )
{
return set_property ( NULL , vg , NULL , name , value ) ;
}
2009-07-24 16:47:15 +04:00
struct dm_list * lvm_list_vg_names ( lvm_t libh )
{
2010-03-16 19:57:03 +03:00
return get_vgnames ( ( struct cmd_context * ) libh , 0 ) ;
2009-07-24 16:47:15 +04:00
}
2009-07-26 20:06:21 +04:00
struct dm_list * lvm_list_vg_uuids ( lvm_t libh )
2009-07-24 16:47:15 +04:00
{
2010-03-16 19:57:03 +03:00
return get_vgids ( ( struct cmd_context * ) libh , 0 ) ;
2009-07-24 16:47:15 +04:00
}
2009-07-24 16:48:21 +04:00
2009-08-03 16:11:45 +04:00
/*
* FIXME : Elaborate on when to use , side - effects , . cache file , etc
*/
2009-07-26 20:44:05 +04:00
int lvm_scan ( lvm_t libh )
2009-07-24 16:48:21 +04:00
{
2009-07-27 00:28:59 +04:00
if ( ! lvmcache_label_scan ( ( struct cmd_context * ) libh , 2 ) )
return - 1 ;
return 0 ;
2009-07-24 16:48:21 +04:00
}