2002-02-08 17:30:37 +03:00
/*
2004-03-30 23:35:44 +04:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2011-02-18 17:16:11 +03:00
* Copyright ( C ) 2004 - 2011 Red Hat , Inc . All rights reserved .
2002-02-08 17:30:37 +03:00
*
2004-03-30 23:35:44 +04:00
* This file is part of LVM2 .
2002-02-08 17:30:37 +03:00
*
2004-03-30 23:35:44 +04:00
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
2007-08-21 00:55:30 +04:00
* of the GNU Lesser General Public License v .2 .1 .
2004-03-30 23:35:44 +04:00
*
2007-08-21 00:55:30 +04:00
* You should have received a copy of the GNU Lesser General Public License
2004-03-30 23:35:44 +04:00
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
2002-02-08 17:30:37 +03:00
*/
2006-05-10 01:23:51 +04:00
# ifndef _LVM_LOCKING_H
# define _LVM_LOCKING_H
2002-02-08 17:30:37 +03:00
# include "uuid.h"
# include "config.h"
2013-03-18 00:29:58 +04:00
struct logical_volume ;
2010-05-06 15:15:55 +04:00
int init_locking ( int type , struct cmd_context * cmd , int suppress_messages ) ;
2002-02-08 17:30:37 +03:00
void fin_locking ( void ) ;
2003-05-06 16:03:13 +04:00
void reset_locking ( void ) ;
2003-11-21 22:54:40 +03:00
int vg_write_lock_held ( void ) ;
2005-03-22 01:55:12 +03:00
int locking_is_clustered ( void ) ;
2014-09-17 16:21:41 +04:00
int locking_supports_remote_queries ( void ) ;
2002-02-08 17:30:37 +03:00
2011-02-04 23:30:17 +03:00
int remote_lock_held ( const char * vol , int * exclusive ) ;
2009-05-19 14:38:58 +04:00
2002-02-08 17:30:37 +03:00
/*
2002-02-11 14:43:17 +03:00
* LCK_VG :
2008-05-09 23:26:58 +04:00
* Lock / unlock on - disk volume group data .
* Use VG_ORPHANS to lock all orphan PVs .
* Use VG_GLOBAL as a global lock and to wipe the internal cache .
* char * vol holds volume group name .
2010-01-05 19:09:33 +03:00
* Set LCK_CACHE flag when manipulating ' vol ' metadata in the internal cache .
* ( Like commit , revert or invalidate metadata . )
2009-09-03 01:34:11 +04:00
* If more than one lock needs to be held simultaneously , they must be
2010-05-19 05:49:08 +04:00
* acquired in alphabetical order of ' vol ' ( to avoid deadlocks ) , with
* VG_ORPHANS last .
2002-02-08 17:30:37 +03:00
*
2011-04-29 04:21:13 +04:00
* Use VG_SYNC_NAMES to ensure / dev is up - to - date for example , with udev ,
* by waiting for any asynchronous events issued to have completed .
2011-04-29 00:29:59 +04:00
*
2002-02-11 14:43:17 +03:00
* LCK_LV :
2002-02-08 17:30:37 +03:00
* Lock / unlock an individual logical volume
2002-03-11 18:08:39 +03:00
* char * vol holds lvid
2002-02-08 17:30:37 +03:00
*/
2014-09-22 17:50:07 +04:00
int lock_vol ( struct cmd_context * cmd , const char * vol , uint32_t flags , const struct logical_volume * lv ) ;
2002-02-08 17:30:37 +03:00
2008-05-09 23:26:58 +04:00
/*
* Internal locking representation .
* LCK_VG : Uses prefix V_ unless the vol begins with # ( i . e . # global or # orphans )
* or the LCK_CACHE flag is set when it uses the prefix P_ .
* If LCK_CACHE is set , we do not take out a real lock .
2010-01-05 19:09:33 +03:00
* NB In clustered situations , LCK_CACHE is not propagated directly to remote nodes .
* ( It can be deduced from lock name . )
2008-05-09 23:26:58 +04:00
*/
2002-11-01 22:57:25 +03:00
/*
* Does the LVM1 driver have this VG active ?
*/
int check_lvm1_vg_inactive ( struct cmd_context * cmd , const char * vgname ) ;
2002-02-08 17:30:37 +03:00
/*
2002-04-04 17:31:21 +04:00
* Lock type - these numbers are the same as VMS and the IBM DLM
2002-02-08 17:30:37 +03:00
*/
2007-08-22 18:38:18 +04:00
# define LCK_TYPE_MASK 0x00000007U
2002-04-04 17:31:21 +04:00
2012-04-24 16:17:12 +04:00
# define LCK_NULL 0x00000000U /* LCK$_NLMODE (Deactivate) */
# define LCK_READ 0x00000001U /* LCK$_CRMODE (Activate) */
2002-11-01 22:57:25 +03:00
/* LCK$_CWMODE */
2007-08-22 18:38:18 +04:00
# define LCK_PREAD 0x00000003U /* LCK$_PRMODE */
2012-04-24 16:17:12 +04:00
# define LCK_WRITE 0x00000004U /* LCK$_PWMODE (Suspend) */
# define LCK_EXCL 0x00000005U /* LCK$_EXMODE (Exclusive) */
# define LCK_UNLOCK 0x00000006U /* This is ours (Resume) */
2002-02-08 17:30:37 +03:00
2010-06-17 16:48:54 +04:00
/*
* Lock flags - these numbers are the same as DLM
*/
# define LCKF_NOQUEUE 0x00000001U /* LKF$_NOQUEUE */
# define LCKF_CONVERT 0x00000004U /* LKF$_CONVERT */
2002-02-08 17:30:37 +03:00
/*
* Lock scope
*/
2014-06-20 16:24:02 +04:00
# define LCK_SCOPE_MASK 0x00001008U
# define LCK_VG 0x00000000U /* Volume Group */
# define LCK_LV 0x00000008U /* Logical Volume */
# define LCK_ACTIVATION 0x00001000U /* Activation */
2002-02-08 17:30:37 +03:00
/*
2011-12-08 22:09:48 +04:00
* Lock bits .
* Bottom 8 bits except LCK_LOCAL form args [ 0 ] in cluster comms .
2002-02-08 17:30:37 +03:00
*/
2007-08-22 18:38:18 +04:00
# define LCK_NONBLOCK 0x00000010U /* Don't block waiting for lock? */
# define LCK_HOLD 0x00000020U /* Hold lock when lock_vol returns? */
2011-12-08 22:09:48 +04:00
# define LCK_CLUSTER_VG 0x00000080U /* VG is clustered */
2007-08-22 18:38:18 +04:00
# define LCK_LOCAL 0x00000040U /* Don't propagate to other nodes */
2012-01-21 09:29:51 +04:00
# define LCK_REMOTE 0x00000800U /* Propagate to remote nodes only */
2008-05-09 23:26:58 +04:00
# define LCK_CACHE 0x00000100U /* Operation on cache only using P_ lock */
2010-08-17 23:25:05 +04:00
# define LCK_ORIGIN_ONLY 0x00000200U /* Operation should bypass any snapshots */
2011-09-28 02:43:40 +04:00
# define LCK_REVERT 0x00000400U /* Revert any incomplete change */
2002-02-08 17:30:37 +03:00
2006-03-10 01:34:13 +03:00
/*
2010-08-17 23:25:05 +04:00
* Additional lock bits for cluster communication via args [ 1 ]
2006-03-10 01:34:13 +03:00
*/
2010-08-17 23:25:05 +04:00
# define LCK_PARTIAL_MODE 0x01 /* Partial activation? */
# define LCK_MIRROR_NOSYNC_MODE 0x02 /* Mirrors don't require sync */
# define LCK_DMEVENTD_MONITOR_MODE 0x04 /* Register with dmeventd */
2011-12-08 22:09:48 +04:00
/* Not yet used. */
2014-11-18 11:04:30 +03:00
# define LCK_CONVERT_MODE 0x08 /* Convert existing lock */
2011-12-08 22:09:48 +04:00
2011-06-02 01:16:55 +04:00
# define LCK_TEST_MODE 0x10 /* Test mode: No activation */
2011-12-03 15:34:35 +04:00
# define LCK_ORIGIN_ONLY_MODE 0x20 /* Same as above */
# define LCK_DMEVENTD_MONITOR_IGNORE 0x40 /* Whether to ignore dmeventd */
# define LCK_REVERT_MODE 0x80 /* Remove inactive tables */
2006-05-12 23:16:48 +04:00
2007-08-23 19:02:26 +04:00
/*
* Special cases of VG locks .
*/
# define VG_ORPHANS "#orphans"
# define VG_GLOBAL "#global"
2011-01-12 23:42:50 +03:00
# define VG_SYNC_NAMES "#sync_names"
2006-03-10 01:34:13 +03:00
2002-02-27 15:26:41 +03:00
/*
* Common combinations
*/
2007-11-16 00:30:52 +03:00
# define LCK_NONE (LCK_VG | LCK_NULL)
2007-11-15 05:55:22 +03:00
2014-06-20 16:24:02 +04:00
# define LCK_ACTIVATE_LOCK (LCK_ACTIVATION | LCK_WRITE | LCK_HOLD)
# define LCK_ACTIVATE_UNLOCK (LCK_ACTIVATION | LCK_UNLOCK)
2002-03-05 23:03:09 +03:00
# define LCK_VG_READ (LCK_VG | LCK_READ | LCK_HOLD)
# define LCK_VG_WRITE (LCK_VG | LCK_WRITE | LCK_HOLD)
2002-04-04 15:18:45 +04:00
# define LCK_VG_UNLOCK (LCK_VG | LCK_UNLOCK)
2008-04-15 18:46:19 +04:00
# define LCK_VG_DROP_CACHE (LCK_VG | LCK_WRITE | LCK_CACHE)
2010-01-05 19:09:33 +03:00
/* FIXME: LCK_HOLD abused here */
# define LCK_VG_COMMIT (LCK_VG | LCK_WRITE | LCK_CACHE | LCK_HOLD)
# define LCK_VG_REVERT (LCK_VG | LCK_READ | LCK_CACHE | LCK_HOLD)
2009-04-22 13:39:45 +04:00
# define LCK_VG_BACKUP (LCK_VG | LCK_CACHE)
2002-02-27 15:26:41 +03:00
2011-04-29 00:29:59 +04:00
# define LCK_VG_SYNC (LCK_NONE | LCK_CACHE)
# define LCK_VG_SYNC_LOCAL (LCK_NONE | LCK_CACHE | LCK_LOCAL)
2009-07-24 22:15:06 +04:00
# define LCK_LV_EXCLUSIVE (LCK_LV | LCK_EXCL)
# define LCK_LV_SUSPEND (LCK_LV | LCK_WRITE)
# define LCK_LV_RESUME (LCK_LV | LCK_UNLOCK)
# define LCK_LV_ACTIVATE (LCK_LV | LCK_READ)
# define LCK_LV_DEACTIVATE (LCK_LV | LCK_NULL)
# define LCK_MASK (LCK_TYPE_MASK | LCK_SCOPE_MASK)
2002-02-27 15:26:41 +03:00
2005-08-15 17:24:46 +04:00
# define LCK_LV_CLUSTERED(lv) \
2008-04-10 21:09:32 +04:00
( vg_is_clustered ( ( lv ) - > vg ) ? LCK_CLUSTER_VG : 0 )
2005-08-15 17:24:46 +04:00
# define lock_lv_vol(cmd, lv, flags) \
2010-05-21 18:29:49 +04:00
( find_replicator_vgs ( ( lv ) ) ? \
2013-03-18 00:29:58 +04:00
lock_vol ( cmd , ( lv ) - > lvid . s , flags | LCK_LV_CLUSTERED ( lv ) , lv ) : \
2010-05-21 18:29:49 +04:00
0 )
2005-08-15 17:24:46 +04:00
2014-06-20 16:24:02 +04:00
/*
* Activation locks are wrapped around activation commands that have to
* be processed atomically one - at - a - time .
* If a VG WRITE lock is held , an activation lock is redundant .
*
* FIXME Test and support this for thin and cache types .
* FIXME Add cluster support .
*/
# define lv_supports_activation_locking(lv) (!vg_is_clustered((lv)->vg) && !lv_is_thin_type(lv) && !lv_is_cache_type(lv))
# define lock_activation(cmd, lv) (vg_write_lock_held() && lv_supports_activation_locking(lv) ? 1 : lock_vol(cmd, (lv)->lvid.s, LCK_ACTIVATE_LOCK, lv))
# define unlock_activation(cmd, lv) (vg_write_lock_held() && lv_supports_activation_locking(lv) ? 1 : lock_vol(cmd, (lv)->lvid.s, LCK_ACTIVATE_UNLOCK, lv))
/*
* Place temporary exclusive ' activation ' lock around an LV locking operation
* to serialise it .
*/
# define lock_lv_vol_serially(cmd, lv, flags) \
( { \
int rr = 0 ; \
\
if ( lock_activation ( ( cmd ) , ( lv ) ) ) { \
rr = lock_lv_vol ( ( cmd ) , ( lv ) , ( flags ) ) ; \
unlock_activation ( ( cmd ) , ( lv ) ) ; \
} \
rr ; \
} )
2011-02-04 22:18:16 +03:00
# define unlock_vg(cmd, vol) \
do { \
if ( is_real_vg ( vol ) ) \
sync_dev_names ( cmd ) ; \
2013-03-18 00:29:58 +04:00
( void ) lock_vol ( cmd , vol , LCK_VG_UNLOCK , NULL ) ; \
2011-02-04 22:18:16 +03:00
} while ( 0 )
2011-08-11 00:25:29 +04:00
# define unlock_and_release_vg(cmd, vg, vol) \
2009-05-21 07:04:52 +04:00
do { \
unlock_vg ( cmd , vol ) ; \
2011-08-11 00:25:29 +04:00
release_vg ( vg ) ; \
2009-05-21 07:04:52 +04:00
} while ( 0 )
2004-03-26 23:49:35 +03:00
2014-06-20 16:24:02 +04:00
# define resume_lv(cmd, lv) \
( { \
int rr = lock_lv_vol ( ( cmd ) , ( lv ) , LCK_LV_RESUME ) ; \
unlock_activation ( ( cmd ) , ( lv ) ) ; \
rr ; \
} )
2010-08-17 23:25:05 +04:00
# define resume_lv_origin(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_RESUME | LCK_ORIGIN_ONLY)
2014-06-20 16:24:02 +04:00
# define revert_lv(cmd, lv) \
( { \
int rr = lock_lv_vol ( ( cmd ) , ( lv ) , LCK_LV_RESUME | LCK_REVERT ) ; \
\
unlock_activation ( ( cmd ) , ( lv ) ) ; \
rr ; \
} )
# define suspend_lv(cmd, lv) \
( lock_activation ( ( cmd ) , ( lv ) ) ? lock_lv_vol ( ( cmd ) , ( lv ) , LCK_LV_SUSPEND | LCK_HOLD ) : 0 )
2010-08-17 23:25:05 +04:00
# define suspend_lv_origin(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_SUSPEND | LCK_HOLD | LCK_ORIGIN_ONLY)
2014-06-20 16:24:02 +04:00
# define deactivate_lv(cmd, lv) lock_lv_vol_serially(cmd, lv, LCK_LV_DEACTIVATE)
2012-01-21 09:29:51 +04:00
2014-06-20 16:24:02 +04:00
# define activate_lv(cmd, lv) lock_lv_vol_serially(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD)
2012-01-21 09:29:51 +04:00
# define activate_lv_excl_local(cmd, lv) \
2014-06-20 16:24:02 +04:00
lock_lv_vol_serially ( cmd , lv , LCK_LV_EXCLUSIVE | LCK_HOLD | LCK_LOCAL )
2012-01-21 09:29:51 +04:00
# define activate_lv_excl_remote(cmd, lv) \
lock_lv_vol ( cmd , lv , LCK_LV_EXCLUSIVE | LCK_HOLD | LCK_REMOTE )
struct logical_volume ;
int activate_lv_excl ( struct cmd_context * cmd , struct logical_volume * lv ) ;
2005-08-15 16:00:04 +04:00
# define activate_lv_local(cmd, lv) \
2014-06-20 16:24:02 +04:00
lock_lv_vol_serially ( cmd , lv , LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL )
2005-08-15 16:00:04 +04:00
# define deactivate_lv_local(cmd, lv) \
2014-06-20 16:24:02 +04:00
lock_lv_vol_serially ( cmd , lv , LCK_LV_DEACTIVATE | LCK_LOCAL )
2008-04-15 18:46:19 +04:00
# define drop_cached_metadata(vg) \
2013-03-18 00:29:58 +04:00
lock_vol ( ( vg ) - > cmd , ( vg ) - > name , LCK_VG_DROP_CACHE , NULL )
2010-01-05 19:09:33 +03:00
# define remote_commit_cached_metadata(vg) \
2013-03-18 00:29:58 +04:00
lock_vol ( ( vg ) - > cmd , ( vg ) - > name , LCK_VG_COMMIT , NULL )
2010-01-05 19:09:33 +03:00
# define remote_revert_cached_metadata(vg) \
2013-03-18 00:29:58 +04:00
lock_vol ( ( vg ) - > cmd , ( vg ) - > name , LCK_VG_REVERT , NULL )
2009-04-22 13:39:45 +04:00
# define remote_backup_metadata(vg) \
2013-03-18 00:29:58 +04:00
lock_vol ( ( vg ) - > cmd , ( vg ) - > name , LCK_VG_BACKUP , NULL )
2011-04-29 00:29:59 +04:00
2011-02-18 17:16:11 +03:00
int sync_local_dev_names ( struct cmd_context * cmd ) ;
int sync_dev_names ( struct cmd_context * cmd ) ;
2004-05-05 16:03:07 +04:00
2004-03-26 23:49:35 +03:00
/* Process list of LVs */
2011-09-27 21:09:42 +04:00
struct volume_group ;
int suspend_lvs ( struct cmd_context * cmd , struct dm_list * lvs ,
struct volume_group * vg_to_revert ) ;
2008-11-04 01:14:30 +03:00
int resume_lvs ( struct cmd_context * cmd , struct dm_list * lvs ) ;
2011-09-28 02:43:40 +04:00
int revert_lvs ( struct cmd_context * cmd , struct dm_list * lvs ) ;
2008-11-04 01:14:30 +03:00
int activate_lvs ( struct cmd_context * cmd , struct dm_list * lvs , unsigned exclusive ) ;
2004-03-26 23:49:35 +03:00
2006-05-10 01:23:51 +04:00
# endif