1/*	$NetBSD$	*/
2
3/*
4 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
6 *
7 * This file is part of LVM2.
8 *
9 * This copyrighted material is made available to anyone wishing to use,
10 * modify, copy, or redistribute it subject to the terms and conditions
11 * of the GNU Lesser General Public License v.2.1.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16 */
17
18#ifndef _LVM_LOCKING_H
19#define _LVM_LOCKING_H
20
21#include "uuid.h"
22#include "config.h"
23
24int init_locking(int type, struct cmd_context *cmd);
25void fin_locking(void);
26void reset_locking(void);
27int vg_write_lock_held(void);
28int locking_is_clustered(void);
29
30int remote_lock_held(const char *vol);
31
32/*
33 * LCK_VG:
34 *   Lock/unlock on-disk volume group data.
35 *   Use VG_ORPHANS to lock all orphan PVs.
36 *   Use VG_GLOBAL as a global lock and to wipe the internal cache.
37 *   char *vol holds volume group name.
38 *   Set the LCK_CACHE flag to invalidate 'vol' in the internal cache.
39 *   If more than one lock needs to be held simultaneously, they must be
40 *   acquired in alphabetical order of 'vol' (to avoid deadlocks).
41 *
42 * LCK_LV:
43 *   Lock/unlock an individual logical volume
44 *   char *vol holds lvid
45 */
46int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags);
47
48/*
49 * Internal locking representation.
50 *   LCK_VG: Uses prefix V_ unless the vol begins with # (i.e. #global or #orphans)
51 *           or the LCK_CACHE flag is set when it uses the prefix P_.
52 * If LCK_CACHE is set, we do not take out a real lock.
53 */
54
55/*
56 * Does the LVM1 driver have this VG active?
57 */
58int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
59
60/*
61 * Lock type - these numbers are the same as VMS and the IBM DLM
62 */
63#define LCK_TYPE_MASK	0x00000007U
64
65#define LCK_NULL	0x00000000U	/* LCK$_NLMODE */
66#define LCK_READ	0x00000001U	/* LCK$_CRMODE */
67					/* LCK$_CWMODE */
68#define LCK_PREAD       0x00000003U	/* LCK$_PRMODE */
69#define LCK_WRITE	0x00000004U	/* LCK$_PWMODE */
70#define LCK_EXCL	0x00000005U	/* LCK$_EXMODE */
71#define LCK_UNLOCK      0x00000006U	/* This is ours */
72
73/*
74 * Lock scope
75 */
76#define LCK_SCOPE_MASK	0x00000008U
77#define LCK_VG		0x00000000U
78#define LCK_LV		0x00000008U
79
80/*
81 * Lock bits
82 */
83#define LCK_NONBLOCK	0x00000010U	/* Don't block waiting for lock? */
84#define LCK_HOLD	0x00000020U	/* Hold lock when lock_vol returns? */
85#define LCK_LOCAL	0x00000040U	/* Don't propagate to other nodes */
86#define LCK_CLUSTER_VG	0x00000080U	/* VG is clustered */
87#define LCK_CACHE	0x00000100U	/* Operation on cache only using P_ lock */
88
89/*
90 * Additional lock bits for cluster communication
91 */
92#define LCK_PARTIAL_MODE        0x00000001U	/* Partial activation? */
93#define LCK_MIRROR_NOSYNC_MODE	0x00000002U	/* Mirrors don't require sync */
94#define LCK_DMEVENTD_MONITOR_MODE	0x00000004U	/* Register with dmeventd */
95#define LCK_CONVERT		0x00000008U	/* Convert existing lock */
96
97/*
98 * Special cases of VG locks.
99 */
100#define VG_ORPHANS	"#orphans"
101#define VG_GLOBAL	"#global"
102
103/*
104 * Common combinations
105 */
106#define LCK_NONE		(LCK_VG | LCK_NULL)
107
108#define LCK_VG_READ		(LCK_VG | LCK_READ | LCK_HOLD)
109#define LCK_VG_WRITE		(LCK_VG | LCK_WRITE | LCK_HOLD)
110#define LCK_VG_UNLOCK		(LCK_VG | LCK_UNLOCK)
111#define LCK_VG_DROP_CACHE	(LCK_VG | LCK_WRITE | LCK_CACHE)
112#define LCK_VG_BACKUP		(LCK_VG | LCK_CACHE)
113
114#define LCK_LV_EXCLUSIVE	(LCK_LV | LCK_EXCL)
115#define LCK_LV_SUSPEND		(LCK_LV | LCK_WRITE)
116#define LCK_LV_RESUME		(LCK_LV | LCK_UNLOCK)
117#define LCK_LV_ACTIVATE		(LCK_LV | LCK_READ)
118#define LCK_LV_DEACTIVATE	(LCK_LV | LCK_NULL)
119
120#define LCK_MASK (LCK_TYPE_MASK | LCK_SCOPE_MASK)
121
122#define LCK_LV_CLUSTERED(lv)	\
123	(vg_is_clustered((lv)->vg) ? LCK_CLUSTER_VG : 0)
124
125#define lock_lv_vol(cmd, lv, flags)	\
126	lock_vol(cmd, (lv)->lvid.s, flags | LCK_LV_CLUSTERED(lv))
127
128#define unlock_vg(cmd, vol)	lock_vol(cmd, vol, LCK_VG_UNLOCK)
129#define unlock_and_release_vg(cmd, vg, vol) \
130	do { \
131		unlock_vg(cmd, vol); \
132		vg_release(vg); \
133	} while (0)
134
135#define resume_lv(cmd, lv)	lock_lv_vol(cmd, lv, LCK_LV_RESUME)
136#define suspend_lv(cmd, lv)	lock_lv_vol(cmd, lv, LCK_LV_SUSPEND | LCK_HOLD)
137#define deactivate_lv(cmd, lv)	lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE)
138#define activate_lv(cmd, lv)	lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD)
139#define activate_lv_excl(cmd, lv)	\
140				lock_lv_vol(cmd, lv, LCK_LV_EXCLUSIVE | LCK_HOLD)
141#define activate_lv_local(cmd, lv)	\
142	lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL)
143#define deactivate_lv_local(cmd, lv)	\
144	lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE | LCK_LOCAL)
145#define drop_cached_metadata(vg)	\
146	lock_vol((vg)->cmd, (vg)->name, LCK_VG_DROP_CACHE)
147#define remote_backup_metadata(vg)	\
148	lock_vol((vg)->cmd, (vg)->name, LCK_VG_BACKUP)
149
150/* Process list of LVs */
151int suspend_lvs(struct cmd_context *cmd, struct dm_list *lvs);
152int resume_lvs(struct cmd_context *cmd, struct dm_list *lvs);
153int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs, unsigned exclusive);
154
155/* Interrupt handling */
156void sigint_clear(void);
157void sigint_allow(void);
158void sigint_restore(void);
159int sigint_caught(void);
160
161#endif
162