2011-08-11 09:00:20 +04:00
/*
2015-10-10 17:58:31 +03:00
* Copyright ( C ) 2005 - 2015 Red Hat , Inc . All rights reserved .
2011-08-11 09:00:20 +04:00
*
* 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 "dmeventd_lvm.h"
2015-10-10 17:58:31 +03:00
# include "libdevmapper-event.h"
2015-10-13 12:28:57 +03:00
struct dso_state {
struct dm_pool * mem ;
char cmd_lvscan [ 512 ] ;
char cmd_lvconvert [ 512 ] ;
int failed ;
} ;
2015-10-10 17:58:31 +03:00
DM_EVENT_LOG_FN ( " raid " )
2011-08-11 09:00:20 +04:00
/* FIXME Reformat to 80 char lines. */
2015-10-13 12:37:14 +03:00
static int _process_raid_event ( struct dso_state * state , char * params , const char * device )
2011-12-06 23:30:15 +04:00
{
2015-10-13 12:37:14 +03:00
struct dm_status_raid * status ;
const char * d ;
2014-07-21 06:33:21 +04:00
2015-10-13 12:37:14 +03:00
if ( ! dm_get_status_raid ( state - > mem , params , & status ) ) {
2015-10-09 22:57:48 +03:00
log_error ( " Failed to process status line for %s. " , device ) ;
2015-10-13 12:37:14 +03:00
return 0 ;
2011-08-11 09:00:20 +04:00
}
2015-10-22 11:38:40 +03:00
if ( ( d = strchr ( status - > dev_health , ' D ' ) ) ) {
if ( state - > failed )
goto out ; /* already reported */
2015-10-13 12:37:14 +03:00
log_error ( " Device #%d of %s array, %s, has failed. " ,
2015-10-22 10:57:44 +03:00
( int ) ( d - status - > dev_health ) ,
status - > raid_type , device ) ;
2015-10-13 12:37:14 +03:00
state - > failed = 1 ;
if ( ! dmeventd_lvm2_run_with_lock ( state - > cmd_lvscan ) )
2015-10-22 11:38:40 +03:00
log_warn ( " WARNING: Re-scan of RAID device %s failed. " , device ) ;
2015-10-13 12:37:14 +03:00
/* if repair goes OK, report success even if lvscan has failed */
if ( ! dmeventd_lvm2_run_with_lock ( state - > cmd_lvconvert ) ) {
log_info ( " Repair of RAID device %s failed. " , device ) ;
dm_pool_free ( state - > mem , status ) ;
return 0 ;
2011-08-11 09:00:20 +04:00
}
2015-10-13 12:37:14 +03:00
} else {
state - > failed = 0 ;
log_info ( " %s array, %s, is %s in-sync. " ,
status - > raid_type , device ,
( status - > insync_regions = = status - > total_regions ) ? " now " : " not " ) ;
2011-08-11 09:00:20 +04:00
}
2015-10-22 11:38:40 +03:00
out :
2015-10-13 12:37:14 +03:00
dm_pool_free ( state - > mem , status ) ;
2011-08-11 09:00:20 +04:00
2015-10-13 12:37:14 +03:00
return 1 ;
2011-08-11 09:00:20 +04:00
}
void process_event ( struct dm_task * dmt ,
enum dm_event_mask event __attribute__ ( ( unused ) ) ,
2015-10-12 12:40:51 +03:00
void * * user )
2011-08-11 09:00:20 +04:00
{
2015-10-13 12:37:14 +03:00
struct dso_state * state = * user ;
2011-08-11 09:00:20 +04:00
void * next = NULL ;
uint64_t start , length ;
char * target_type = NULL ;
char * params ;
const char * device = dm_task_get_name ( dmt ) ;
do {
next = dm_get_next_target ( dmt , next , & start , & length ,
& target_type , & params ) ;
if ( ! target_type ) {
2015-10-09 22:57:48 +03:00
log_info ( " %s mapping lost. " , device ) ;
2011-08-11 09:00:20 +04:00
continue ;
}
if ( strcmp ( target_type , " raid " ) ) {
2015-10-09 22:57:48 +03:00
log_info ( " %s has non-raid portion. " , device ) ;
2011-08-11 09:00:20 +04:00
continue ;
}
2015-10-13 12:37:14 +03:00
if ( ! _process_raid_event ( state , params , device ) )
2015-10-09 22:57:48 +03:00
log_error ( " Failed to process event for %s. " ,
device ) ;
2011-08-11 09:00:20 +04:00
} while ( next ) ;
}
int register_device ( const char * device ,
const char * uuid __attribute__ ( ( unused ) ) ,
int major __attribute__ ( ( unused ) ) ,
int minor __attribute__ ( ( unused ) ) ,
2015-10-12 12:40:51 +03:00
void * * user )
2011-08-11 09:00:20 +04:00
{
2015-10-13 12:28:57 +03:00
struct dso_state * state ;
if ( ! dmeventd_lvm2_init_with_pool ( " raid_state " , state ) )
goto_bad ;
if ( ! dmeventd_lvm2_command ( state - > mem , state - > cmd_lvscan , sizeof ( state - > cmd_lvscan ) ,
" lvscan --cache " , device ) | |
! dmeventd_lvm2_command ( state - > mem , state - > cmd_lvconvert , sizeof ( state - > cmd_lvconvert ) ,
" lvconvert --config devices{ignore_suspended_devices=1} "
" --repair --use-policies " , device ) ) {
dmeventd_lvm2_exit_with_pool ( state ) ;
goto_bad ;
}
* user = state ;
2011-12-22 20:37:01 +04:00
2015-10-09 22:57:48 +03:00
log_info ( " Monitoring RAID device %s for events. " , device ) ;
2011-12-22 20:37:01 +04:00
return 1 ;
2015-10-13 12:28:57 +03:00
bad :
log_error ( " Failed to monitor RAID %s. " , device ) ;
return 0 ;
2011-08-11 09:00:20 +04:00
}
int unregister_device ( const char * device ,
const char * uuid __attribute__ ( ( unused ) ) ,
int major __attribute__ ( ( unused ) ) ,
int minor __attribute__ ( ( unused ) ) ,
2015-10-12 12:40:51 +03:00
void * * user )
2011-08-11 09:00:20 +04:00
{
2015-10-13 12:28:57 +03:00
struct dso_state * state = * user ;
dmeventd_lvm2_exit_with_pool ( state ) ;
2015-10-09 22:57:48 +03:00
log_info ( " No longer monitoring RAID device %s for events. " ,
device ) ;
2011-12-22 20:37:01 +04:00
2011-08-11 09:00:20 +04:00
return 1 ;
}