1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-18 10:04:20 +03:00
lvm2/lib/locking/locking.h
Dave Wysochanski 3de6df8410 Enforce an alphabetical lock ordering for vgname locks.
Add a new constraint that vgname locks must be obtained in
alphabetical order.  At this point, we have test coverage for
the 3 commands affected - vgsplit, vgmerge, and vgrename.
Tests have been updated to cover these commands.
Going forward any command or library call that must obtain
more than one vgname lock must do so in alphabetical order.
Future patches will update lvm2app to enforce this ordering.


Author: Dave Wysochanski <dwysocha@redhat.com>
2009-09-02 21:34:11 +00:00

159 lines
5.1 KiB
C

/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 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
*/
#ifndef _LVM_LOCKING_H
#define _LVM_LOCKING_H
#include "uuid.h"
#include "config.h"
int init_locking(int type, struct cmd_context *cmd);
void fin_locking(void);
void reset_locking(void);
int vg_write_lock_held(void);
int locking_is_clustered(void);
int remote_lock_held(const char *vol);
/*
* LCK_VG:
* 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.
* Set the LCK_CACHE flag to invalidate 'vol' in the internal cache.
* If more than one lock needs to be held simultaneously, they must be
* acquired in alphabetical order of 'vol' (to avoid deadlocks).
*
* LCK_LV:
* Lock/unlock an individual logical volume
* char *vol holds lvid
*/
int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags);
/*
* 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.
*/
/*
* Does the LVM1 driver have this VG active?
*/
int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
/*
* Lock type - these numbers are the same as VMS and the IBM DLM
*/
#define LCK_TYPE_MASK 0x00000007U
#define LCK_NULL 0x00000000U /* LCK$_NLMODE */
#define LCK_READ 0x00000001U /* LCK$_CRMODE */
/* LCK$_CWMODE */
#define LCK_PREAD 0x00000003U /* LCK$_PRMODE */
#define LCK_WRITE 0x00000004U /* LCK$_PWMODE */
#define LCK_EXCL 0x00000005U /* LCK$_EXMODE */
#define LCK_UNLOCK 0x00000006U /* This is ours */
/*
* Lock scope
*/
#define LCK_SCOPE_MASK 0x00000008U
#define LCK_VG 0x00000000U
#define LCK_LV 0x00000008U
/*
* Lock bits
*/
#define LCK_NONBLOCK 0x00000010U /* Don't block waiting for lock? */
#define LCK_HOLD 0x00000020U /* Hold lock when lock_vol returns? */
#define LCK_LOCAL 0x00000040U /* Don't propagate to other nodes */
#define LCK_CLUSTER_VG 0x00000080U /* VG is clustered */
#define LCK_CACHE 0x00000100U /* Operation on cache only using P_ lock */
/*
* Additional lock bits for cluster communication
*/
#define LCK_PARTIAL_MODE 0x00000001U /* Partial activation? */
#define LCK_MIRROR_NOSYNC_MODE 0x00000002U /* Mirrors don't require sync */
#define LCK_DMEVENTD_MONITOR_MODE 0x00000004U /* Register with dmeventd */
/*
* Special cases of VG locks.
*/
#define VG_ORPHANS "#orphans"
#define VG_GLOBAL "#global"
/*
* Common combinations
*/
#define LCK_NONE (LCK_VG | LCK_NULL)
#define LCK_VG_READ (LCK_VG | LCK_READ | LCK_HOLD)
#define LCK_VG_WRITE (LCK_VG | LCK_WRITE | LCK_HOLD)
#define LCK_VG_UNLOCK (LCK_VG | LCK_UNLOCK)
#define LCK_VG_DROP_CACHE (LCK_VG | LCK_WRITE | LCK_CACHE)
#define LCK_VG_BACKUP (LCK_VG | LCK_CACHE)
#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)
#define LCK_LV_CLUSTERED(lv) \
(vg_is_clustered((lv)->vg) ? LCK_CLUSTER_VG : 0)
#define lock_lv_vol(cmd, lv, flags) \
lock_vol(cmd, (lv)->lvid.s, flags | LCK_LV_CLUSTERED(lv))
#define unlock_vg(cmd, vol) lock_vol(cmd, vol, LCK_VG_UNLOCK)
#define unlock_and_release_vg(cmd, vg, vol) \
do { \
unlock_vg(cmd, vol); \
vg_release(vg); \
} while (0)
#define resume_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_RESUME)
#define suspend_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_SUSPEND | LCK_HOLD)
#define deactivate_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE)
#define activate_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD)
#define activate_lv_excl(cmd, lv) \
lock_lv_vol(cmd, lv, LCK_LV_EXCLUSIVE | LCK_HOLD)
#define activate_lv_local(cmd, lv) \
lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL)
#define deactivate_lv_local(cmd, lv) \
lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE | LCK_LOCAL)
#define drop_cached_metadata(vg) \
lock_vol((vg)->cmd, (vg)->name, LCK_VG_DROP_CACHE)
#define remote_backup_metadata(vg) \
lock_vol((vg)->cmd, (vg)->name, LCK_VG_BACKUP)
/* Process list of LVs */
int suspend_lvs(struct cmd_context *cmd, struct dm_list *lvs);
int resume_lvs(struct cmd_context *cmd, struct dm_list *lvs);
int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs, unsigned exclusive);
/* Interrupt handling */
void sigint_clear(void);
void sigint_allow(void);
void sigint_restore(void);
int sigint_caught(void);
#endif