2012-02-28 22:23:56 +04:00
/*
* Copyright ( C ) 2012 Red Hat , Inc .
*
* 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
*/
2012-02-23 17:11:07 +04:00
# include "lib.h"
# include "toolcontext.h"
# include "metadata.h"
# include "device.h"
# include "lvmetad.h"
# include "lvmcache.h"
# include "lvmetad-client.h"
# include "format-text.h" // TODO for disk_locn, used as a DA representation
2012-08-13 21:44:10 +04:00
# include "crc.h"
2012-02-23 17:11:07 +04:00
static daemon_handle _lvmetad ;
2012-08-13 21:44:10 +04:00
static int _lvmetad_use = 0 ;
static int _lvmetad_connected = 0 ;
2012-02-23 17:11:07 +04:00
2012-08-13 21:44:10 +04:00
static char * _lvmetad_token = NULL ;
static const char * _lvmetad_socket = NULL ;
static struct cmd_context * _lvmetad_cmd = NULL ;
void lvmetad_disconnect ( void )
{
2012-10-30 00:39:46 +04:00
if ( _lvmetad_connected )
daemon_close ( _lvmetad ) ;
2012-08-13 21:44:10 +04:00
_lvmetad_connected = 0 ;
_lvmetad_cmd = NULL ;
}
void lvmetad_init ( struct cmd_context * cmd )
2012-02-23 17:11:07 +04:00
{
2014-01-24 18:59:38 +04:00
if ( ! _lvmetad_use & & ! access ( getenv ( " LVM_LVMETAD_PIDFILE " ) ? : LVMETAD_PIDFILE , F_OK ) )
2012-10-30 00:39:46 +04:00
log_warn ( " WARNING: lvmetad is running but disabled. "
" Restart lvmetad before enabling it! " ) ;
_lvmetad_cmd = cmd ;
}
2013-02-05 19:48:48 +04:00
static void _lvmetad_connect ( void )
2012-10-30 00:39:46 +04:00
{
2013-01-05 03:22:30 +04:00
if ( ! _lvmetad_use | | ! _lvmetad_socket | | _lvmetad_connected )
return ;
_lvmetad = lvmetad_open ( _lvmetad_socket ) ;
if ( _lvmetad . socket_fd > = 0 & & ! _lvmetad . error ) {
2013-01-08 02:30:29 +04:00
log_debug_lvmetad ( " Successfully connected to lvmetad on fd %d. " ,
_lvmetad . socket_fd ) ;
2013-01-05 03:22:30 +04:00
_lvmetad_connected = 1 ;
2012-02-23 17:11:07 +04:00
}
}
2013-01-05 03:22:30 +04:00
void lvmetad_connect_or_warn ( void )
2012-10-12 04:48:39 +04:00
{
2013-01-05 03:22:30 +04:00
if ( ! _lvmetad_use )
return ;
2012-10-30 00:39:46 +04:00
if ( ! _lvmetad_connected )
_lvmetad_connect ( ) ;
2013-01-05 03:22:30 +04:00
if ( ( _lvmetad . socket_fd < 0 | | _lvmetad . error ) )
2012-10-12 13:16:38 +04:00
log_warn ( " WARNING: Failed to connect to lvmetad: %s. Falling back to internal scanning. " ,
strerror ( _lvmetad . error ) ) ;
2012-10-12 04:48:39 +04:00
}
2013-11-26 17:51:23 +04:00
int lvmetad_used ( void )
{
return _lvmetad_use ;
}
int lvmetad_socket_present ( void )
{
const char * socket = _lvmetad_socket ? : LVMETAD_SOCKET ;
int r ;
if ( ( r = access ( socket , F_OK ) ) & & errno ! = ENOENT )
log_sys_error ( " lvmetad_socket_present " , " " ) ;
return ! r ;
}
2012-08-13 21:44:10 +04:00
int lvmetad_active ( void )
{
2012-10-30 00:39:46 +04:00
if ( ! _lvmetad_use )
return 0 ;
2013-01-05 03:22:30 +04:00
2012-10-30 00:39:46 +04:00
if ( ! _lvmetad_connected )
_lvmetad_connect ( ) ;
2013-01-05 03:22:30 +04:00
if ( ( _lvmetad . socket_fd < 0 | | _lvmetad . error ) )
2013-01-08 02:30:29 +04:00
log_debug_lvmetad ( " Failed to connect to lvmetad: %s. " , strerror ( _lvmetad . error ) ) ;
2013-01-05 03:22:30 +04:00
2012-10-30 00:39:46 +04:00
return _lvmetad_connected ;
2012-08-13 21:44:10 +04:00
}
void lvmetad_set_active ( int active )
{
_lvmetad_use = active ;
}
2013-01-05 04:35:50 +04:00
/*
* Use a crc of the strings in the filter as the lvmetad token .
*/
2012-08-13 21:44:10 +04:00
void lvmetad_set_token ( const struct dm_config_value * filter )
{
2012-10-12 12:15:30 +04:00
int ft = 0 ;
2012-08-13 21:44:10 +04:00
if ( _lvmetad_token )
dm_free ( _lvmetad_token ) ;
2012-10-12 12:15:30 +04:00
2012-08-13 21:44:10 +04:00
while ( filter & & filter - > type = = DM_CFG_STRING ) {
ft = calc_crc ( ft , ( const uint8_t * ) filter - > v . str , strlen ( filter - > v . str ) ) ;
filter = filter - > next ;
}
2012-10-12 12:15:30 +04:00
2012-08-13 21:44:10 +04:00
if ( ! dm_asprintf ( & _lvmetad_token , " filter:%u " , ft ) )
log_warn ( " WARNING: Failed to set lvmetad token. Out of memory? " ) ;
}
2012-10-12 18:50:38 +04:00
void lvmetad_release_token ( void )
{
dm_free ( _lvmetad_token ) ;
_lvmetad_token = NULL ;
}
2012-08-13 21:44:10 +04:00
void lvmetad_set_socket ( const char * sock )
{
_lvmetad_socket = sock ;
}
2012-08-11 12:37:28 +04:00
static daemon_reply _lvmetad_send ( const char * id , . . . )
{
va_list ap ;
2012-10-12 12:15:30 +04:00
daemon_reply repl ;
2012-08-13 21:44:10 +04:00
daemon_request req ;
int try = 0 ;
2012-08-11 12:37:28 +04:00
2012-08-13 21:44:10 +04:00
retry :
req = daemon_request_make ( id ) ;
if ( _lvmetad_token )
daemon_request_extend ( req , " token = %s " , _lvmetad_token , NULL ) ;
va_start ( ap , id ) ;
2012-08-11 12:37:28 +04:00
daemon_request_extend_v ( req , ap ) ;
2012-08-13 21:44:10 +04:00
va_end ( ap ) ;
2012-08-11 12:37:28 +04:00
repl = daemon_send ( _lvmetad , req ) ;
daemon_request_destroy ( req ) ;
2012-10-08 14:21:36 +04:00
if ( ! repl . error & & ! strcmp ( daemon_reply_str ( repl , " response " , " " ) , " token_mismatch " ) & &
2014-02-26 18:11:00 +04:00
try < 60 & & ! test_mode ( ) ) {
/*
* If another process is trying to scan , they might have the
* same future token id and it ' s better to wait and avoid doing
* the work multiple times . For the case the future token is
* different , the wait is randomized so that multiple waiting
* processes do not start scanning all at once .
*
* If the token is mismatched because of global_filter changes ,
* we re - scan immediately , but if we lose the potential race for
* the update , we back off for a short while ( 0.2 - 2 seconds ) and
* try again .
*/
if ( ! strcmp ( daemon_reply_str ( repl , " expected " , " " ) , " update in progress " ) | | try % 5 )
usleep ( 50000 + random ( ) % 450000 ) ; /* 0.05 - 0.5s */
else
/* If the re-scan fails here, we try again later. */
lvmetad_pvscan_all_devs ( _lvmetad_cmd , NULL ) ;
+ + try ;
daemon_reply_destroy ( repl ) ;
goto retry ;
2012-08-13 21:44:10 +04:00
}
2012-08-11 12:37:28 +04:00
return repl ;
}
2013-01-05 03:45:22 +04:00
static int _token_update ( void )
{
2013-02-05 19:48:48 +04:00
daemon_reply repl ;
2013-01-08 02:30:29 +04:00
log_debug_lvmetad ( " Sending updated token to lvmetad: %s " , _lvmetad_token ? : " <NONE> " ) ;
2013-02-05 19:48:48 +04:00
repl = _lvmetad_send ( " token_update " , NULL ) ;
2013-01-05 03:45:22 +04:00
if ( repl . error | | strcmp ( daemon_reply_str ( repl , " response " , " " ) , " OK " ) ) {
daemon_reply_destroy ( repl ) ;
return 0 ;
}
daemon_reply_destroy ( repl ) ;
return 1 ;
}
2012-02-23 17:11:07 +04:00
/*
* Helper ; evaluate the reply from lvmetad , check for errors , print diagnostics
2012-03-03 00:46:36 +04:00
* and return a summary success / failure exit code .
*
* If found is set , * found indicates whether or not device exists ,
* and missing device is not treated as an error .
2012-02-23 17:11:07 +04:00
*/
2012-03-03 00:46:36 +04:00
static int _lvmetad_handle_reply ( daemon_reply reply , const char * action , const char * object ,
int * found )
{
if ( reply . error ) {
log_error ( " Request to %s %s%sin lvmetad gave response %s. " ,
action , object , * object ? " " : " " , strerror ( reply . error ) ) ;
2012-02-23 17:11:07 +04:00
return 0 ;
}
2012-03-03 00:46:36 +04:00
/* All OK? */
if ( ! strcmp ( daemon_reply_str ( reply , " response " , " " ) , " OK " ) ) {
if ( found )
* found = 1 ;
return 1 ;
}
/* Unknown device permitted? */
if ( found & & ! strcmp ( daemon_reply_str ( reply , " response " , " " ) , " unknown " ) ) {
2013-01-05 04:35:50 +04:00
log_very_verbose ( " Request to %s %s%sin lvmetad did not find any matching object. " ,
2012-03-03 00:46:36 +04:00
action , object , * object ? " " : " " ) ;
* found = 0 ;
return 1 ;
}
log_error ( " Request to %s %s%sin lvmetad gave response %s. Reason: %s " ,
action , object , * object ? " " : " " ,
daemon_reply_str ( reply , " response " , " <missing> " ) ,
daemon_reply_str ( reply , " reason " , " <missing> " ) ) ;
return 0 ;
2012-02-23 17:11:07 +04:00
}
static int _read_mda ( struct lvmcache_info * info ,
struct format_type * fmt ,
const struct dm_config_node * cn )
{
struct metadata_area_ops * ops ;
2012-02-23 21:59:32 +04:00
dm_list_iterate_items ( ops , & fmt - > mda_ops )
2012-02-23 17:11:07 +04:00
if ( ops - > mda_import_text & & ops - > mda_import_text ( info , cn ) )
return 1 ;
2012-02-23 21:59:32 +04:00
2012-02-23 17:11:07 +04:00
return 0 ;
}
2014-01-08 05:51:23 +04:00
static struct lvmcache_info * _pv_populate_lvmcache ( struct cmd_context * cmd ,
struct dm_config_node * cn ,
dev_t fallback )
2012-02-23 17:11:07 +04:00
{
2013-01-05 03:45:22 +04:00
struct device * dev ;
2012-02-23 21:59:32 +04:00
struct id pvid , vgid ;
char mda_id [ 32 ] ;
char da_id [ 32 ] ;
int i = 0 ;
struct dm_config_node * mda = NULL ;
struct dm_config_node * da = NULL ;
uint64_t offset , size ;
struct lvmcache_info * info ;
2012-02-23 17:11:07 +04:00
const char * pvid_txt = dm_config_find_str ( cn - > child , " id " , NULL ) ,
* vgid_txt = dm_config_find_str ( cn - > child , " vgid " , NULL ) ,
* vgname = dm_config_find_str ( cn - > child , " vgname " , NULL ) ,
* fmt_name = dm_config_find_str ( cn - > child , " format " , NULL ) ;
dev_t devt = dm_config_find_int ( cn - > child , " device " , 0 ) ;
2012-03-02 00:04:44 +04:00
uint64_t devsize = dm_config_find_int64 ( cn - > child , " dev_size " , 0 ) ,
label_sector = dm_config_find_int64 ( cn - > child , " label_sector " , 0 ) ;
2012-02-23 17:11:07 +04:00
struct format_type * fmt = fmt_name ? get_format_by_name ( cmd , fmt_name ) : NULL ;
if ( ! fmt ) {
2012-03-02 20:58:41 +04:00
log_error ( " PV %s not recognised. Is the device missing? " , pvid_txt ) ;
2012-02-23 21:59:32 +04:00
return NULL ;
2012-02-23 17:11:07 +04:00
}
2013-01-05 03:45:22 +04:00
dev = dev_cache_get_by_devt ( devt , cmd - > filter ) ;
if ( ! dev & & fallback )
dev = dev_cache_get_by_devt ( fallback , cmd - > filter ) ;
2012-02-23 17:11:07 +04:00
2013-01-05 03:45:22 +04:00
if ( ! dev ) {
2012-03-02 20:58:41 +04:00
log_error ( " No device found for PV %s. " , pvid_txt ) ;
2012-02-23 21:59:32 +04:00
return NULL ;
2012-02-23 17:11:07 +04:00
}
if ( ! pvid_txt | | ! id_read_format ( & pvid , pvid_txt ) ) {
2012-03-02 20:58:41 +04:00
log_error ( " Missing or ill-formatted PVID for PV: %s. " , pvid_txt ) ;
2012-02-23 21:59:32 +04:00
return NULL ;
2012-02-23 17:11:07 +04:00
}
2012-12-14 19:45:15 +04:00
if ( vgid_txt ) {
if ( ! id_read_format ( & vgid , vgid_txt ) )
return_NULL ;
} else
2012-02-23 17:11:07 +04:00
strcpy ( ( char * ) & vgid , fmt - > orphan_vg_name ) ;
if ( ! vgname )
vgname = fmt - > orphan_vg_name ;
2013-01-05 03:45:22 +04:00
if ( ! ( info = lvmcache_add ( fmt - > labeller , ( const char * ) & pvid , dev ,
2012-04-10 16:26:27 +04:00
vgname , ( const char * ) & vgid , 0 ) ) )
return_NULL ;
2012-02-23 17:11:07 +04:00
lvmcache_get_label ( info ) - > sector = label_sector ;
2013-11-18 20:53:45 +04:00
lvmcache_get_label ( info ) - > dev = dev ;
2012-02-23 17:11:07 +04:00
lvmcache_set_device_size ( info , devsize ) ;
lvmcache_del_das ( info ) ;
lvmcache_del_mdas ( info ) ;
2013-05-28 14:37:22 +04:00
lvmcache_del_bas ( info ) ;
2012-02-23 17:11:07 +04:00
do {
sprintf ( mda_id , " mda%d " , i ) ;
mda = dm_config_find_node ( cn - > child , mda_id ) ;
if ( mda )
_read_mda ( info , fmt , mda ) ;
+ + i ;
} while ( mda ) ;
i = 0 ;
do {
sprintf ( da_id , " da%d " , i ) ;
da = dm_config_find_node ( cn - > child , da_id ) ;
if ( da ) {
if ( ! dm_config_get_uint64 ( da - > child , " offset " , & offset ) ) return_0 ;
if ( ! dm_config_get_uint64 ( da - > child , " size " , & size ) ) return_0 ;
lvmcache_add_da ( info , offset , size ) ;
}
+ + i ;
} while ( da ) ;
2013-02-14 19:04:35 +04:00
i = 0 ;
do {
sprintf ( da_id , " ea%d " , i ) ;
da = dm_config_find_node ( cn - > child , da_id ) ;
2013-02-27 13:36:49 +04:00
if ( da ) {
if ( ! dm_config_get_uint64 ( da - > child , " offset " , & offset ) ) return_0 ;
if ( ! dm_config_get_uint64 ( da - > child , " size " , & size ) ) return_0 ;
2013-05-28 14:37:22 +04:00
lvmcache_add_ba ( info , offset , size ) ;
2013-02-27 13:36:49 +04:00
}
+ + i ;
2013-02-14 19:04:35 +04:00
} while ( da ) ;
2012-02-23 17:11:07 +04:00
return info ;
}
struct volume_group * lvmetad_vg_lookup ( struct cmd_context * cmd , const char * vgname , const char * vgid )
{
2012-02-23 21:59:32 +04:00
struct volume_group * vg = NULL ;
daemon_reply reply ;
2013-01-16 14:12:22 +04:00
int found ;
2012-02-23 21:59:32 +04:00
char uuid [ 64 ] ;
2014-01-08 05:51:23 +04:00
struct format_instance * fid = NULL ;
2012-02-23 21:59:32 +04:00
struct format_instance_ctx fic ;
struct dm_config_node * top ;
2013-01-16 14:12:22 +04:00
const char * name , * diag_name ;
2012-02-23 21:59:32 +04:00
const char * fmt_name ;
struct format_type * fmt ;
struct dm_config_node * pvcn ;
struct pv_list * pvl ;
struct lvmcache_info * info ;
2012-08-13 21:44:10 +04:00
if ( ! lvmetad_active ( ) )
2012-02-23 17:11:07 +04:00
return NULL ;
if ( vgid ) {
2012-02-27 15:32:48 +04:00
if ( ! id_write_format ( ( const struct id * ) vgid , uuid , sizeof ( uuid ) ) )
2012-08-17 14:04:52 +04:00
return_NULL ;
2013-01-08 02:30:29 +04:00
log_debug_lvmetad ( " Asking lvmetad for VG %s (%s) " , uuid , vgname ? : " name unknown " ) ;
2012-08-11 12:37:28 +04:00
reply = _lvmetad_send ( " vg_lookup " , " uuid = %s " , uuid , NULL ) ;
2013-01-16 14:12:22 +04:00
diag_name = uuid ;
2012-02-23 17:11:07 +04:00
} else {
2013-04-19 23:19:54 +04:00
if ( ! vgname ) {
2012-02-23 17:11:07 +04:00
log_error ( INTERNAL_ERROR " VG name required (VGID not available) " ) ;
2013-06-15 01:17:28 +04:00
reply = _lvmetad_send ( " vg_lookup " , " name = %s " , " MISSING " , NULL ) ;
2013-04-19 23:19:54 +04:00
goto out ;
}
2013-01-08 02:30:29 +04:00
log_debug_lvmetad ( " Asking lvmetad for VG %s " , vgname ) ;
2012-08-11 12:37:28 +04:00
reply = _lvmetad_send ( " vg_lookup " , " name = %s " , vgname , NULL ) ;
2013-01-16 14:12:22 +04:00
diag_name = vgname ;
2012-02-23 17:11:07 +04:00
}
2013-01-16 14:12:22 +04:00
if ( _lvmetad_handle_reply ( reply , " lookup VG " , diag_name , & found ) & & found ) {
2012-02-23 17:11:07 +04:00
2012-06-21 14:43:31 +04:00
if ( ! ( top = dm_config_find_node ( reply . cft - > root , " metadata " ) ) ) {
log_error ( INTERNAL_ERROR " metadata config node not found. " ) ;
goto out ;
}
2012-02-23 21:59:32 +04:00
name = daemon_reply_str ( reply , " name " , NULL ) ;
2012-02-23 17:11:07 +04:00
/* fall back to lvm2 if we don't know better */
2012-02-23 21:59:32 +04:00
fmt_name = dm_config_find_str ( top , " metadata/format " , " lvm2 " ) ;
if ( ! ( fmt = get_format_by_name ( cmd , fmt_name ) ) ) {
2012-02-23 17:11:07 +04:00
log_error ( INTERNAL_ERROR
" We do not know the format (%s) reported by lvmetad. " ,
fmt_name ) ;
2012-03-03 01:24:37 +04:00
goto out ;
2012-02-23 17:11:07 +04:00
}
fic . type = FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS ;
fic . context . vg_ref . vg_name = name ;
fic . context . vg_ref . vg_id = vgid ;
if ( ! ( fid = fmt - > ops - > create_instance ( fmt , & fic ) ) )
2012-03-03 01:24:37 +04:00
goto_out ;
2012-02-23 17:11:07 +04:00
2012-03-02 02:52:59 +04:00
if ( ( pvcn = dm_config_find_node ( top , " metadata/physical_volumes " ) ) )
for ( pvcn = pvcn - > child ; pvcn ; pvcn = pvcn - > sib )
_pv_populate_lvmcache ( cmd , pvcn , 0 ) ;
2012-02-23 17:11:07 +04:00
top - > key = name ;
2012-03-02 02:52:59 +04:00
if ( ! ( vg = import_vg_from_config_tree ( reply . cft , fid ) ) )
2012-03-03 01:24:37 +04:00
goto_out ;
2012-02-23 17:11:07 +04:00
dm_list_iterate_items ( pvl , & vg - > pvs ) {
2012-02-23 21:59:32 +04:00
if ( ( info = lvmcache_info_from_pvid ( ( const char * ) & pvl - > pv - > id , 0 ) ) ) {
2012-02-23 17:11:07 +04:00
pvl - > pv - > label_sector = lvmcache_get_label ( info ) - > sector ;
pvl - > pv - > dev = lvmcache_device ( info ) ;
2013-04-03 13:10:52 +04:00
if ( ! pvl - > pv - > dev )
pvl - > pv - > status | = MISSING_PV ;
2012-03-03 01:24:37 +04:00
if ( ! lvmcache_fid_add_mdas_pv ( info , fid ) ) {
vg = NULL ;
goto_out ; /* FIXME error path */
}
2013-04-03 13:10:52 +04:00
} else
pvl - > pv - > status | = MISSING_PV ; /* probably missing */
2012-02-23 17:11:07 +04:00
}
lvmcache_update_vg ( vg , 0 ) ;
2013-04-03 13:10:52 +04:00
vg_mark_partial_lvs ( vg , 1 ) ;
2012-02-23 17:11:07 +04:00
}
2012-03-03 01:24:37 +04:00
out :
2014-01-08 05:51:23 +04:00
if ( ! vg & & fid )
fid - > fmt - > ops - > destroy_instance ( fid ) ;
2012-02-23 17:11:07 +04:00
daemon_reply_destroy ( reply ) ;
2012-03-03 01:24:37 +04:00
2012-02-23 17:11:07 +04:00
return vg ;
}
struct _fixup_baton {
int i ;
int find ;
int ignore ;
} ;
static int _fixup_ignored ( struct metadata_area * mda , void * baton ) {
struct _fixup_baton * b = baton ;
if ( b - > i = = b - > find )
mda_set_ignored ( mda , b - > ignore ) ;
b - > i + + ;
return 1 ;
}
2012-08-11 12:37:28 +04:00
int lvmetad_vg_update ( struct volume_group * vg )
{
2012-02-23 21:59:32 +04:00
daemon_reply reply ;
struct dm_hash_node * n ;
struct metadata_area * mda ;
char mda_id [ 128 ] , * num ;
struct pv_list * pvl ;
struct lvmcache_info * info ;
2012-02-23 23:03:48 +04:00
struct _fixup_baton baton ;
2012-02-23 21:59:32 +04:00
2012-02-23 17:11:07 +04:00
if ( ! vg )
return 0 ;
2012-02-23 21:59:32 +04:00
2012-08-13 21:44:10 +04:00
if ( ! lvmetad_active ( ) | | test_mode ( ) )
2012-02-23 17:11:07 +04:00
return 1 ; /* fake it */
2014-03-01 01:40:00 +04:00
if ( ! vg - > cft_precommitted ) {
log_error ( INTERNAL_ERROR " VG update without precommited " ) ;
return 0 ;
}
2012-02-23 17:11:07 +04:00
2013-01-08 02:30:29 +04:00
log_debug_lvmetad ( " Sending lvmetad updated metadata for VG %s (seqno % " PRIu32 " ) " , vg - > name , vg - > seqno ) ;
2012-08-11 12:37:28 +04:00
reply = _lvmetad_send ( " vg_update " , " vgname = %s " , vg - > name ,
2014-03-01 01:40:00 +04:00
" metadata = %t " , vg - > cft_precommitted , NULL ) ;
2012-02-23 17:11:07 +04:00
2012-03-03 00:46:36 +04:00
if ( ! _lvmetad_handle_reply ( reply , " update VG " , vg - > name , NULL ) ) {
daemon_reply_destroy ( reply ) ;
2012-02-23 17:11:07 +04:00
return 0 ;
2012-03-03 00:46:36 +04:00
}
2012-02-23 17:11:07 +04:00
2012-03-03 01:24:37 +04:00
daemon_reply_destroy ( reply ) ;
2012-02-23 21:59:32 +04:00
n = ( vg - > fid & & vg - > fid - > metadata_areas_index ) ?
2012-02-23 17:11:07 +04:00
dm_hash_get_first ( vg - > fid - > metadata_areas_index ) : NULL ;
while ( n ) {
2012-02-23 21:59:32 +04:00
mda = dm_hash_get_data ( vg - > fid - > metadata_areas_index , n ) ;
2012-02-23 17:11:07 +04:00
strcpy ( mda_id , dm_hash_get_key ( vg - > fid - > metadata_areas_index , n ) ) ;
if ( ( num = strchr ( mda_id , ' _ ' ) ) ) {
* num = 0 ;
+ + num ;
2012-02-23 21:59:32 +04:00
if ( ( info = lvmcache_info_from_pvid ( mda_id , 0 ) ) ) {
2012-02-23 23:03:48 +04:00
memset ( & baton , 0 , sizeof ( baton ) ) ;
2012-02-23 21:59:32 +04:00
baton . find = atoi ( num ) ;
baton . ignore = mda_is_ignored ( mda ) ;
2012-02-23 17:11:07 +04:00
lvmcache_foreach_mda ( info , _fixup_ignored , & baton ) ;
2012-02-23 21:59:32 +04:00
}
2012-02-23 17:11:07 +04:00
}
n = dm_hash_get_next ( vg - > fid - > metadata_areas_index , n ) ;
}
dm_list_iterate_items ( pvl , & vg - > pvs ) {
/* NB. the PV fmt pointer is sometimes wrong during vgconvert */
2012-10-13 22:51:07 +04:00
if ( pvl - > pv - > dev & & ! lvmetad_pv_found ( & pvl - > pv - > id , pvl - > pv - > dev ,
2012-02-23 17:11:07 +04:00
vg - > fid ? vg - > fid - > fmt : pvl - > pv - > fmt ,
2012-06-27 16:59:34 +04:00
pvl - > pv - > label_sector , NULL , NULL ) )
2012-02-23 17:11:07 +04:00
return 0 ;
}
return 1 ;
}
int lvmetad_vg_remove ( struct volume_group * vg )
{
2012-02-23 21:59:32 +04:00
char uuid [ 64 ] ;
daemon_reply reply ;
2012-03-03 00:46:36 +04:00
int result ;
2012-02-23 21:59:32 +04:00
2012-08-13 21:44:10 +04:00
if ( ! lvmetad_active ( ) | | test_mode ( ) )
2012-02-23 17:11:07 +04:00
return 1 ; /* just fake it */
2012-02-23 21:59:32 +04:00
2012-02-27 15:32:48 +04:00
if ( ! id_write_format ( & vg - > id , uuid , sizeof ( uuid ) ) )
return_0 ;
2013-01-08 02:30:29 +04:00
log_debug_lvmetad ( " Telling lvmetad to remove VGID %s (%s) " , uuid , vg - > name ) ;
2012-08-11 12:37:28 +04:00
reply = _lvmetad_send ( " vg_remove " , " uuid = %s " , uuid , NULL ) ;
2012-03-03 00:46:36 +04:00
result = _lvmetad_handle_reply ( reply , " remove VG " , vg - > name , NULL ) ;
daemon_reply_destroy ( reply ) ;
return result ;
2012-02-23 17:11:07 +04:00
}
2012-03-03 00:46:36 +04:00
int lvmetad_pv_lookup ( struct cmd_context * cmd , struct id pvid , int * found )
2012-02-23 17:11:07 +04:00
{
2012-02-23 21:59:32 +04:00
char uuid [ 64 ] ;
daemon_reply reply ;
2012-03-03 00:46:36 +04:00
int result = 0 ;
2012-02-23 21:59:32 +04:00
struct dm_config_node * cn ;
2012-08-13 21:44:10 +04:00
if ( ! lvmetad_active ( ) )
2012-02-23 17:11:07 +04:00
return_0 ;
2012-02-27 15:32:48 +04:00
if ( ! id_write_format ( & pvid , uuid , sizeof ( uuid ) ) )
return_0 ;
2012-02-23 17:11:07 +04:00
2013-01-08 02:30:29 +04:00
log_debug_lvmetad ( " Asking lvmetad for PV %s " , uuid ) ;
2012-08-11 12:37:28 +04:00
reply = _lvmetad_send ( " pv_lookup " , " uuid = %s " , uuid , NULL ) ;
2012-03-03 00:46:36 +04:00
if ( ! _lvmetad_handle_reply ( reply , " lookup PV " , " " , found ) )
goto_out ;
if ( found & & ! * found )
goto out_success ;
2012-02-23 17:11:07 +04:00
2012-03-02 02:52:59 +04:00
if ( ! ( cn = dm_config_find_node ( reply . cft - > root , " physical_volume " ) ) )
2012-03-03 00:46:36 +04:00
goto_out ;
2012-03-02 02:52:59 +04:00
else if ( ! _pv_populate_lvmcache ( cmd , cn , 0 ) )
2012-03-03 00:46:36 +04:00
goto_out ;
2012-02-23 17:11:07 +04:00
2012-03-03 00:46:36 +04:00
out_success :
result = 1 ;
out :
2012-02-23 17:11:07 +04:00
daemon_reply_destroy ( reply ) ;
2012-03-03 00:46:36 +04:00
2012-02-23 17:11:07 +04:00
return result ;
}
2012-03-03 00:46:36 +04:00
int lvmetad_pv_lookup_by_dev ( struct cmd_context * cmd , struct device * dev , int * found )
2012-02-23 17:11:07 +04:00
{
2012-03-03 00:46:36 +04:00
int result = 0 ;
2012-02-23 21:59:32 +04:00
daemon_reply reply ;
struct dm_config_node * cn ;
2012-08-13 21:44:10 +04:00
if ( ! lvmetad_active ( ) )
2012-02-23 17:11:07 +04:00
return_0 ;
2013-01-08 02:30:29 +04:00
log_debug_lvmetad ( " Asking lvmetad for PV on %s " , dev_name ( dev ) ) ;
2012-09-09 23:57:59 +04:00
reply = _lvmetad_send ( " pv_lookup " , " device = % " PRId64 , ( int64_t ) dev - > dev , NULL ) ;
2012-03-03 00:46:36 +04:00
if ( ! _lvmetad_handle_reply ( reply , " lookup PV " , dev_name ( dev ) , found ) )
goto_out ;
if ( found & & ! * found )
goto out_success ;
2012-02-23 17:11:07 +04:00
2012-02-23 21:59:32 +04:00
cn = dm_config_find_node ( reply . cft - > root , " physical_volume " ) ;
2012-03-03 00:46:36 +04:00
if ( ! cn | | ! _pv_populate_lvmcache ( cmd , cn , dev - > dev ) )
goto_out ;
2012-02-23 17:11:07 +04:00
2012-03-03 00:46:36 +04:00
out_success :
result = 1 ;
out :
2012-02-23 17:11:07 +04:00
daemon_reply_destroy ( reply ) ;
return result ;
}
int lvmetad_pv_list_to_lvmcache ( struct cmd_context * cmd )
{
2012-02-23 21:59:32 +04:00
daemon_reply reply ;
struct dm_config_node * cn ;
2012-08-13 21:44:10 +04:00
if ( ! lvmetad_active ( ) )
2012-02-28 22:23:56 +04:00
return 1 ;
2012-02-23 17:11:07 +04:00
2013-01-08 02:30:29 +04:00
log_debug_lvmetad ( " Asking lvmetad for complete list of known PVs " ) ;
2012-08-11 12:37:28 +04:00
reply = _lvmetad_send ( " pv_list " , NULL ) ;
2012-03-03 00:46:36 +04:00
if ( ! _lvmetad_handle_reply ( reply , " list PVs " , " " , NULL ) ) {
daemon_reply_destroy ( reply ) ;
2012-02-23 17:11:07 +04:00
return_0 ;
}
2012-03-02 02:52:59 +04:00
if ( ( cn = dm_config_find_node ( reply . cft - > root , " physical_volumes " ) ) )
for ( cn = cn - > child ; cn ; cn = cn - > sib )
_pv_populate_lvmcache ( cmd , cn , 0 ) ;
2012-02-23 17:11:07 +04:00
daemon_reply_destroy ( reply ) ;
2012-03-03 00:46:36 +04:00
2012-02-23 17:11:07 +04:00
return 1 ;
}
int lvmetad_vg_list_to_lvmcache ( struct cmd_context * cmd )
{
2012-02-23 21:59:32 +04:00
struct volume_group * tmp ;
struct id vgid ;
const char * vgid_txt ;
daemon_reply reply ;
struct dm_config_node * cn ;
2012-08-13 21:44:10 +04:00
if ( ! lvmetad_active ( ) )
2012-02-28 22:23:56 +04:00
return 1 ;
2012-02-23 17:11:07 +04:00
2013-01-08 02:30:29 +04:00
log_debug_lvmetad ( " Asking lvmetad for complete list of known VGs " ) ;
2012-08-11 12:37:28 +04:00
reply = _lvmetad_send ( " vg_list " , NULL ) ;
2012-03-03 00:46:36 +04:00
if ( ! _lvmetad_handle_reply ( reply , " list VGs " , " " , NULL ) ) {
daemon_reply_destroy ( reply ) ;
2012-02-23 17:11:07 +04:00
return_0 ;
}
2012-03-02 02:52:59 +04:00
if ( ( cn = dm_config_find_node ( reply . cft - > root , " volume_groups " ) ) )
for ( cn = cn - > child ; cn ; cn = cn - > sib ) {
vgid_txt = cn - > key ;
if ( ! id_read_format ( & vgid , vgid_txt ) ) {
stack ;
continue ;
}
2012-02-23 17:11:07 +04:00
2012-03-02 02:52:59 +04:00
/* the call to lvmetad_vg_lookup will poke the VG into lvmcache */
tmp = lvmetad_vg_lookup ( cmd , NULL , ( const char * ) & vgid ) ;
release_vg ( tmp ) ;
}
2012-02-23 17:11:07 +04:00
daemon_reply_destroy ( reply ) ;
return 1 ;
}
2013-02-14 19:04:35 +04:00
struct _extract_dl_baton {
2012-02-23 17:11:07 +04:00
int i ;
2012-08-11 12:37:28 +04:00
struct dm_config_tree * cft ;
struct dm_config_node * pre_sib ;
2012-02-23 17:11:07 +04:00
} ;
2012-08-11 12:37:28 +04:00
static int _extract_mda ( struct metadata_area * mda , void * baton )
2012-02-23 17:11:07 +04:00
{
2013-02-14 19:04:35 +04:00
struct _extract_dl_baton * b = baton ;
2012-08-11 12:37:28 +04:00
struct dm_config_node * cn ;
char id [ 32 ] ;
2012-02-23 17:11:07 +04:00
if ( ! mda - > ops - > mda_export_text ) /* do nothing */
return 1 ;
2012-12-14 21:58:18 +04:00
( void ) dm_snprintf ( id , 32 , " mda%d " , b - > i ) ;
2012-08-11 12:37:28 +04:00
if ( ! ( cn = make_config_node ( b - > cft , id , b - > cft - > root , b - > pre_sib ) ) )
return 0 ;
if ( ! mda - > ops - > mda_export_text ( mda , b - > cft , cn ) )
return 0 ;
2012-02-23 17:11:07 +04:00
b - > i + + ;
2012-08-11 12:37:28 +04:00
b - > pre_sib = cn ; /* for efficiency */
return 1 ;
2012-02-23 17:11:07 +04:00
}
2013-02-14 19:04:35 +04:00
static int _extract_disk_location ( const char * name , struct disk_locn * dl , void * baton )
2012-02-23 17:11:07 +04:00
{
2013-02-14 19:04:35 +04:00
struct _extract_dl_baton * b = baton ;
2012-08-11 12:37:28 +04:00
struct dm_config_node * cn ;
char id [ 32 ] ;
2012-02-23 21:59:32 +04:00
2013-02-14 19:04:35 +04:00
if ( ! dl )
2012-02-23 17:11:07 +04:00
return 1 ;
2013-02-27 13:36:49 +04:00
( void ) dm_snprintf ( id , 32 , " %s%d " , name , b - > i ) ;
2012-08-11 12:37:28 +04:00
if ( ! ( cn = make_config_node ( b - > cft , id , b - > cft - > root , b - > pre_sib ) ) )
return 0 ;
2012-09-09 23:57:59 +04:00
if ( ! config_make_nodes ( b - > cft , cn , NULL ,
2013-02-14 19:04:35 +04:00
" offset = % " PRId64 , ( int64_t ) dl - > offset ,
" size = % " PRId64 , ( int64_t ) dl - > size ,
2012-09-09 23:57:59 +04:00
NULL ) )
2012-08-11 12:37:28 +04:00
return 0 ;
2012-02-23 17:11:07 +04:00
b - > i + + ;
2012-08-11 12:37:28 +04:00
b - > pre_sib = cn ; /* for efficiency */
2012-02-23 21:59:32 +04:00
2012-02-23 17:11:07 +04:00
return 1 ;
}
2013-02-14 19:04:35 +04:00
static int _extract_da ( struct disk_locn * da , void * baton )
{
return _extract_disk_location ( " da " , da , baton ) ;
}
2013-05-28 14:37:22 +04:00
static int _extract_ba ( struct disk_locn * ba , void * baton )
2013-02-14 19:04:35 +04:00
{
2013-05-28 14:37:22 +04:00
return _extract_disk_location ( " ba " , ba , baton ) ;
2013-02-14 19:04:35 +04:00
}
2012-08-11 12:37:28 +04:00
static int _extract_mdas ( struct lvmcache_info * info , struct dm_config_tree * cft ,
struct dm_config_node * pre_sib )
2012-02-23 17:11:07 +04:00
{
2013-02-14 19:04:35 +04:00
struct _extract_dl_baton baton = { . i = 0 , . cft = cft , . pre_sib = NULL } ;
2012-02-23 21:59:32 +04:00
2012-08-11 12:37:28 +04:00
if ( ! lvmcache_foreach_mda ( info , & _extract_mda , & baton ) )
return 0 ;
2012-02-23 17:11:07 +04:00
baton . i = 0 ;
2012-08-11 12:37:28 +04:00
if ( ! lvmcache_foreach_da ( info , & _extract_da , & baton ) )
return 0 ;
2013-02-27 13:36:49 +04:00
baton . i = 0 ;
2013-05-28 14:37:22 +04:00
if ( ! lvmcache_foreach_ba ( info , & _extract_ba , & baton ) )
2013-02-14 19:04:35 +04:00
return 0 ;
2012-02-23 21:59:32 +04:00
2012-08-11 12:37:28 +04:00
return 1 ;
2012-02-23 17:11:07 +04:00
}
2013-01-05 03:45:22 +04:00
int lvmetad_pv_found ( const struct id * pvid , struct device * dev , const struct format_type * fmt ,
2012-06-27 16:59:34 +04:00
uint64_t label_sector , struct volume_group * vg , activation_handler handler )
2012-02-23 17:11:07 +04:00
{
2012-02-23 21:59:32 +04:00
char uuid [ 64 ] ;
daemon_reply reply ;
struct lvmcache_info * info ;
2012-08-11 12:37:28 +04:00
struct dm_config_tree * pvmeta , * vgmeta ;
2014-03-14 15:07:41 +04:00
const char * status , * vgname , * vgid ;
2014-03-14 13:44:14 +04:00
int64_t changed ;
2012-03-03 00:46:36 +04:00
int result ;
2012-02-23 21:59:32 +04:00
2012-08-13 21:44:10 +04:00
if ( ! lvmetad_active ( ) | | test_mode ( ) )
2012-02-23 17:11:07 +04:00
return 1 ;
2012-10-13 22:51:07 +04:00
if ( ! id_write_format ( pvid , uuid , sizeof ( uuid ) ) )
2012-02-27 15:32:48 +04:00
return_0 ;
2012-02-23 17:11:07 +04:00
2012-08-11 12:37:28 +04:00
pvmeta = dm_config_create ( ) ;
if ( ! pvmeta )
return_0 ;
2012-10-15 02:44:31 +04:00
info = lvmcache_info_from_pvid ( ( const char * ) pvid , 0 ) ;
2012-08-11 12:37:28 +04:00
if ( ! ( pvmeta - > root = make_config_node ( pvmeta , " pv " , NULL , NULL ) ) ) {
dm_config_destroy ( pvmeta ) ;
return_0 ;
}
if ( ! config_make_nodes ( pvmeta , pvmeta - > root , NULL ,
2013-01-05 03:45:22 +04:00
" device = % " PRId64 , ( int64_t ) dev - > dev ,
2012-09-09 23:57:59 +04:00
" dev_size = % " PRId64 , ( int64_t ) ( info ? lvmcache_device_size ( info ) : 0 ) ,
2012-08-11 12:37:28 +04:00
" format = %s " , fmt - > name ,
2012-09-09 23:57:59 +04:00
" label_sector = % " PRId64 , ( int64_t ) label_sector ,
2012-08-11 12:37:28 +04:00
" id = %s " , uuid ,
NULL ) )
{
dm_config_destroy ( pvmeta ) ;
2012-02-23 17:11:07 +04:00
return_0 ;
2012-02-26 12:49:40 +04:00
}
2012-08-11 12:37:28 +04:00
if ( info )
/* FIXME A more direct route would be much preferable. */
_extract_mdas ( info , pvmeta , pvmeta - > root ) ;
2012-02-23 17:11:07 +04:00
if ( vg ) {
2013-03-17 19:25:12 +04:00
if ( ! ( vgmeta = export_vg_to_config_tree ( vg ) ) ) {
2012-08-11 12:37:28 +04:00
dm_config_destroy ( pvmeta ) ;
2012-02-28 15:09:06 +04:00
return_0 ;
}
2013-01-08 02:30:29 +04:00
log_debug_lvmetad ( " Telling lvmetad to store PV %s (%s) in VG %s " , dev_name ( dev ) , uuid , vg - > name ) ;
2012-08-11 12:37:28 +04:00
reply = _lvmetad_send ( " pv_found " ,
" pvmeta = %t " , pvmeta ,
" vgname = %s " , vg - > name ,
" metadata = %t " , vgmeta ,
NULL ) ;
dm_config_destroy ( vgmeta ) ;
2012-02-23 17:11:07 +04:00
} else {
2013-01-05 04:35:50 +04:00
/*
* There is no VG metadata stored on this PV .
* It might or might not be an orphan .
*/
2013-01-08 02:30:29 +04:00
log_debug_lvmetad ( " Telling lvmetad to store PV %s (%s) " , dev_name ( dev ) , uuid ) ;
2012-08-11 12:37:28 +04:00
reply = _lvmetad_send ( " pv_found " , " pvmeta = %t " , pvmeta , NULL ) ;
2012-02-23 17:11:07 +04:00
}
2012-08-11 12:37:28 +04:00
dm_config_destroy ( pvmeta ) ;
2012-03-03 00:46:36 +04:00
result = _lvmetad_handle_reply ( reply , " update PV " , uuid , NULL ) ;
2012-06-27 16:59:34 +04:00
2012-09-20 01:45:51 +04:00
if ( vg & & result & &
( daemon_reply_int ( reply , " seqno_after " , - 1 ) ! = vg - > seqno | |
daemon_reply_int ( reply , " seqno_after " , - 1 ) ! = daemon_reply_int ( reply , " seqno_before " , - 1 ) ) )
log_warn ( " WARNING: Inconsistent metadata found for VG %s " , vg - > name ) ;
2012-06-27 16:59:34 +04:00
if ( result & & handler ) {
status = daemon_reply_str ( reply , " status " , " <missing> " ) ;
2014-03-14 15:07:41 +04:00
vgname = daemon_reply_str ( reply , " vgname " , " <missing> " ) ;
2012-12-12 15:51:28 +04:00
vgid = daemon_reply_str ( reply , " vgid " , " <missing> " ) ;
2014-03-14 13:44:14 +04:00
changed = daemon_reply_int ( reply , " changed " , 0 ) ;
2012-06-27 16:59:34 +04:00
if ( ! strcmp ( status , " partial " ) )
2014-03-14 15:07:41 +04:00
handler ( _lvmetad_cmd , vgname , vgid , 1 , changed , CHANGE_AAY ) ;
2012-06-27 16:59:34 +04:00
else if ( ! strcmp ( status , " complete " ) )
2014-03-14 15:07:41 +04:00
handler ( _lvmetad_cmd , vgname , vgid , 0 , changed , CHANGE_AAY ) ;
2012-06-27 16:59:34 +04:00
else if ( ! strcmp ( status , " orphan " ) )
;
else
log_error ( " Request to %s %s in lvmetad gave status %s. " ,
" update PV " , uuid , status ) ;
}
2012-03-03 00:46:36 +04:00
daemon_reply_destroy ( reply ) ;
return result ;
2012-02-23 17:11:07 +04:00
}
2013-01-05 03:45:22 +04:00
int lvmetad_pv_gone ( dev_t devno , const char * pv_name , activation_handler handler )
2012-02-23 17:11:07 +04:00
{
2012-03-14 21:15:22 +04:00
daemon_reply reply ;
2012-03-03 00:46:36 +04:00
int result ;
int found ;
2012-08-13 21:44:10 +04:00
if ( ! lvmetad_active ( ) | | test_mode ( ) )
2012-02-26 12:49:40 +04:00
return 1 ;
2012-06-27 16:59:34 +04:00
/*
* TODO : automatic volume deactivation takes place here * before *
* all cached info is gone - call handler . Also , consider
* integrating existing deactivation script that deactivates
* the whole stack from top to bottom ( not yet upstream ) .
*/
2013-01-08 02:30:29 +04:00
log_debug_lvmetad ( " Telling lvmetad to forget any PV on %s " , pv_name ) ;
2013-01-05 03:45:22 +04:00
reply = _lvmetad_send ( " pv_gone " , " device = % " PRId64 , ( int64_t ) devno , NULL ) ;
2012-03-03 00:46:36 +04:00
result = _lvmetad_handle_reply ( reply , " drop PV " , pv_name , & found ) ;
/* We don't care whether or not the daemon had the PV cached. */
2012-02-23 17:11:07 +04:00
2012-03-03 00:46:36 +04:00
daemon_reply_destroy ( reply ) ;
return result ;
2012-03-02 20:58:41 +04:00
}
2012-06-27 16:59:34 +04:00
int lvmetad_pv_gone_by_dev ( struct device * dev , activation_handler handler )
2012-03-02 20:58:41 +04:00
{
2012-06-27 16:59:34 +04:00
return lvmetad_pv_gone ( dev - > dev , dev_name ( dev ) , handler ) ;
2012-02-23 17:11:07 +04:00
}
/*
2012-03-02 22:09:46 +04:00
* The following code implements pvscan - - cache .
2012-02-23 17:11:07 +04:00
*/
2012-09-10 00:05:59 +04:00
struct _lvmetad_pvscan_baton {
2012-02-23 17:11:07 +04:00
struct volume_group * vg ;
struct format_instance * fid ;
} ;
2012-09-10 00:05:59 +04:00
static int _lvmetad_pvscan_single ( struct metadata_area * mda , void * baton )
2012-02-23 17:11:07 +04:00
{
2012-09-10 00:05:59 +04:00
struct _lvmetad_pvscan_baton * b = baton ;
2012-02-29 06:35:35 +04:00
struct volume_group * this = mda - > ops - > vg_read ( b - > fid , " " , mda , 1 ) ;
2012-03-03 02:44:31 +04:00
/* FIXME Also ensure contents match etc. */
2012-02-26 17:42:50 +04:00
if ( ! b - > vg | | this - > seqno > b - > vg - > seqno )
2012-02-23 17:11:07 +04:00
b - > vg = this ;
2012-02-26 17:42:50 +04:00
else if ( b - > vg )
release_vg ( this ) ;
2012-02-29 06:35:35 +04:00
2012-02-23 17:11:07 +04:00
return 1 ;
}
2012-09-10 00:05:59 +04:00
int lvmetad_pvscan_single ( struct cmd_context * cmd , struct device * dev ,
2012-06-27 16:59:34 +04:00
activation_handler handler )
2012-02-23 17:11:07 +04:00
{
2012-02-23 21:59:32 +04:00
struct label * label ;
struct lvmcache_info * info ;
2012-09-10 00:05:59 +04:00
struct _lvmetad_pvscan_baton baton ;
2012-02-23 21:59:32 +04:00
/* Create a dummy instance. */
struct format_instance_ctx fic = { . type = 0 } ;
2012-02-23 17:11:07 +04:00
if ( ! lvmetad_active ( ) ) {
log_error ( " Cannot proceed since lvmetad is not active. " ) ;
return 0 ;
}
if ( ! label_read ( dev , & label , 0 ) ) {
config: add silent mode
Accept -q as the short form of --quiet.
Suppress non-essential standard output if -q is given twice.
Treat log/silent in lvm.conf as equivalent to -qq.
Review all log_print messages and change some to
log_print_unless_silent.
When silent, the following commands still produce output:
dumpconfig, lvdisplay, lvmdiskscan, lvs, pvck, pvdisplay,
pvs, version, vgcfgrestore -l, vgdisplay, vgs.
[Needs checking.]
Non-essential messages are shifted from log level 4 to log level 5
for syslog and lvm2_log_fn purposes.
2012-08-25 23:35:48 +04:00
log_print_unless_silent ( " No PV label found on %s. " , dev_name ( dev ) ) ;
2012-06-27 16:59:34 +04:00
if ( ! lvmetad_pv_gone_by_dev ( dev , handler ) )
2012-03-02 20:58:41 +04:00
goto_bad ;
2012-02-23 17:11:07 +04:00
return 1 ;
}
2012-02-23 21:59:32 +04:00
info = ( struct lvmcache_info * ) label - > info ;
2012-02-23 17:11:07 +04:00
baton . vg = NULL ;
2014-01-08 06:13:13 +04:00
baton . fid = lvmcache_fmt ( info ) - > ops - > create_instance ( lvmcache_fmt ( info ) , & fic ) ;
2012-02-23 17:11:07 +04:00
2012-06-21 15:43:55 +04:00
if ( ! baton . fid )
goto_bad ;
2014-01-08 06:13:13 +04:00
if ( baton . fid - > fmt - > features & FMT_OBSOLETE ) {
log_error ( " WARNING: Ignoring obsolete format of metadata (%s) on device %s when using lvmetad " ,
baton . fid - > fmt - > name , dev_name ( dev ) ) ;
2013-12-15 19:31:35 +04:00
lvmcache_fmt ( info ) - > ops - > destroy_instance ( baton . fid ) ;
return 0 ;
}
2014-01-08 06:13:13 +04:00
lvmcache_foreach_mda ( info , _lvmetad_pvscan_single , & baton ) ;
/*
* LVM1 VGs have no MDAs and lvmcache_foreach_mda isn ' t worth fixing
* to use pseudo - mdas for PVs .
* Note that the single_device parameter also gets ignored and this code
* can scan further devices .
*/
if ( ! baton . vg & & ! ( baton . fid - > fmt - > features & FMT_MDAS ) )
baton . vg = ( ( struct metadata_area * ) dm_list_first ( & baton . fid - > metadata_areas_in_use ) ) - > ops - > vg_read ( baton . fid , lvmcache_vgname_from_info ( info ) , NULL , 1 ) ;
2012-10-10 23:49:40 +04:00
2012-02-26 17:42:50 +04:00
if ( ! baton . vg )
lvmcache_fmt ( info ) - > ops - > destroy_instance ( baton . fid ) ;
2012-02-23 17:11:07 +04:00
/*
* NB . If this command failed and we are relying on lvmetad to have an
* * exact * image of the system , the lvmetad instance that went out of
* sync needs to be killed .
*/
2012-10-13 22:51:07 +04:00
if ( ! lvmetad_pv_found ( ( const struct id * ) & dev - > pvid , dev , lvmcache_fmt ( info ) ,
2012-06-27 16:59:34 +04:00
label - > sector , baton . vg , handler ) ) {
2012-03-02 20:58:41 +04:00
release_vg ( baton . vg ) ;
goto_bad ;
}
2012-02-23 17:11:07 +04:00
release_vg ( baton . vg ) ;
return 1 ;
2012-03-02 20:58:41 +04:00
bad :
2012-02-23 17:11:07 +04:00
/* FIXME kill lvmetad automatically if we can */
log_error ( " Update of lvmetad failed. This is a serious problem. \n "
" It is strongly recommended that you restart lvmetad immediately. " ) ;
return 0 ;
}
2012-08-13 21:44:10 +04:00
2012-09-10 00:05:59 +04:00
int lvmetad_pvscan_all_devs ( struct cmd_context * cmd , activation_handler handler )
2012-08-13 21:44:10 +04:00
{
struct dev_iter * iter ;
struct device * dev ;
2012-09-20 01:18:28 +04:00
daemon_reply reply ;
2012-08-13 21:44:10 +04:00
int r = 1 ;
2012-10-08 14:21:36 +04:00
char * future_token ;
2012-10-15 14:44:19 +04:00
int was_silent ;
2012-08-13 21:44:10 +04:00
2012-10-30 00:39:46 +04:00
if ( ! lvmetad_active ( ) ) {
log_error ( " Cannot proceed since lvmetad is not active. " ) ;
return 0 ;
}
2012-08-13 21:44:10 +04:00
if ( ! ( iter = dev_iter_create ( cmd - > lvmetad_filter , 1 ) ) ) {
log_error ( " dev_iter creation failed " ) ;
return 0 ;
}
2012-10-08 14:21:36 +04:00
future_token = _lvmetad_token ;
_lvmetad_token = ( char * ) " update in progress " ;
if ( ! _token_update ( ) ) {
2012-10-13 21:19:50 +04:00
dev_iter_destroy ( iter ) ;
2012-10-08 14:21:36 +04:00
_lvmetad_token = future_token ;
return 0 ;
}
2013-01-08 02:30:29 +04:00
log_debug_lvmetad ( " Telling lvmetad to clear its cache " ) ;
2012-09-20 01:18:28 +04:00
reply = _lvmetad_send ( " pv_clear_all " , NULL ) ;
2013-01-05 04:35:50 +04:00
if ( ! _lvmetad_handle_reply ( reply , " clear info about all PVs " , " " , NULL ) )
2012-09-20 01:18:28 +04:00
r = 0 ;
daemon_reply_destroy ( reply ) ;
2012-10-15 14:44:19 +04:00
was_silent = silent_mode ( ) ;
init_silent ( 1 ) ;
2012-08-13 21:44:10 +04:00
while ( ( dev = dev_iter_get ( iter ) ) ) {
2013-07-01 18:30:12 +04:00
if ( sigint_caught ( ) ) {
2012-08-13 21:44:10 +04:00
r = 0 ;
2013-07-01 18:30:12 +04:00
stack ;
2012-08-13 21:44:10 +04:00
break ;
2013-07-01 18:30:12 +04:00
}
if ( ! lvmetad_pvscan_single ( cmd , dev , handler ) )
r = 0 ;
2012-08-13 21:44:10 +04:00
}
2012-10-15 14:44:19 +04:00
init_silent ( was_silent ) ;
2012-08-13 21:44:10 +04:00
dev_iter_destroy ( iter ) ;
2012-10-08 14:21:36 +04:00
_lvmetad_token = future_token ;
if ( ! _token_update ( ) )
return 0 ;
2012-08-13 21:44:10 +04:00
return r ;
}