1
by Patrick Caulfield
Import upstream version 2.00.25 |
1 |
/*
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
2 |
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
1.2.11
by Bastian Blank
Import upstream version 2.02.88 |
3 |
* Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
4 |
*
|
5 |
* This file is part of LVM2.
|
|
6 |
*
|
|
7 |
* This copyrighted material is made available to anyone wishing to use,
|
|
8 |
* modify, copy, or redistribute it subject to the terms and conditions
|
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
9 |
* of the GNU Lesser General Public License v.2.1.
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
10 |
*
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
11 |
* You should have received a copy of the GNU Lesser General Public License
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
12 |
* along with this program; if not, write to the Free Software Foundation,
|
13 |
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
14 |
*/
|
|
15 |
||
16 |
#include "lib.h" |
|
17 |
#include "lvmcache.h" |
|
18 |
#include "toolcontext.h" |
|
19 |
#include "dev-cache.h" |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
20 |
#include "locking.h" |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
21 |
#include "metadata.h" |
22 |
#include "filter.h" |
|
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
23 |
#include "filter-persistent.h" |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
24 |
#include "memlock.h" |
25 |
#include "str_list.h" |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
26 |
#include "format-text.h" |
27 |
#include "format_pool.h" |
|
28 |
#include "format1.h" |
|
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
29 |
#include "config.h" |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
30 |
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
31 |
#include "lvmetad.h" |
32 |
||
33 |
#define CACHE_INVALID 0x00000001
|
|
34 |
#define CACHE_LOCKED 0x00000002
|
|
35 |
||
36 |
/* One per device */
|
|
37 |
struct lvmcache_info { |
|
38 |
struct dm_list list; /* Join VG members together */ |
|
39 |
struct dm_list mdas; /* list head for metadata areas */ |
|
40 |
struct dm_list das; /* list head for data areas */ |
|
41 |
struct lvmcache_vginfo *vginfo; /* NULL == unknown */ |
|
42 |
struct label *label; |
|
43 |
const struct format_type *fmt; |
|
44 |
struct device *dev; |
|
45 |
uint64_t device_size; /* Bytes */ |
|
46 |
uint32_t status; |
|
47 |
};
|
|
48 |
||
49 |
/* One per VG */
|
|
50 |
struct lvmcache_vginfo { |
|
51 |
struct dm_list list; /* Join these vginfos together */ |
|
52 |
struct dm_list infos; /* List head for lvmcache_infos */ |
|
53 |
const struct format_type *fmt; |
|
54 |
char *vgname; /* "" == orphan */ |
|
55 |
uint32_t status; |
|
56 |
char vgid[ID_LEN + 1]; |
|
57 |
char _padding[7]; |
|
58 |
struct lvmcache_vginfo *next; /* Another VG with same name? */ |
|
59 |
char *creation_host; |
|
60 |
size_t vgmetadata_size; |
|
61 |
char *vgmetadata; /* Copy of VG metadata as format_text string */ |
|
62 |
struct dm_config_tree *cft; /* Config tree created from vgmetadata */ |
|
63 |
/* Lifetime is directly tied to vgmetadata */
|
|
64 |
struct volume_group *cached_vg; |
|
65 |
unsigned holders; |
|
66 |
unsigned vg_use_count; /* Counter of vg reusage */ |
|
67 |
unsigned precommitted; /* Is vgmetadata live or precommitted? */ |
|
68 |
};
|
|
69 |
||
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
70 |
static struct dm_hash_table *_pvid_hash = NULL; |
71 |
static struct dm_hash_table *_vgid_hash = NULL; |
|
72 |
static struct dm_hash_table *_vgname_hash = NULL; |
|
73 |
static struct dm_hash_table *_lock_hash = NULL; |
|
1.2.7
by Bastian Blank
Import upstream version 2.02.64 |
74 |
static DM_LIST_INIT(_vginfos); |
1.1.9
by James Westby
Import upstream version 2.02.39 |
75 |
static int _scanning_in_progress = 0; |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
76 |
static int _has_scanned = 0; |
77 |
static int _vgs_locked = 0; |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
78 |
static int _vg_global_lock_held = 0; /* Global lock held when cache wiped? */ |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
79 |
|
80 |
int lvmcache_init(void) |
|
81 |
{
|
|
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
82 |
/*
|
83 |
* FIXME add a proper lvmcache_locking_reset() that
|
|
84 |
* resets the cache so no previous locks are locked
|
|
85 |
*/
|
|
86 |
_vgs_locked = 0; |
|
87 |
||
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
88 |
dm_list_init(&_vginfos); |
89 |
||
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
90 |
if (!(_vgname_hash = dm_hash_create(128))) |
91 |
return 0; |
|
92 |
||
93 |
if (!(_vgid_hash = dm_hash_create(128))) |
|
94 |
return 0; |
|
95 |
||
96 |
if (!(_pvid_hash = dm_hash_create(128))) |
|
97 |
return 0; |
|
98 |
||
99 |
if (!(_lock_hash = dm_hash_create(128))) |
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
100 |
return 0; |
101 |
||
1.2.5
by Bastian Blank
Import upstream version 2.02.54 |
102 |
/*
|
103 |
* Reinitialising the cache clears the internal record of
|
|
104 |
* which locks are held. The global lock can be held during
|
|
105 |
* this operation so its state must be restored afterwards.
|
|
106 |
*/
|
|
107 |
if (_vg_global_lock_held) { |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
108 |
lvmcache_lock_vgname(VG_GLOBAL, 0); |
1.2.5
by Bastian Blank
Import upstream version 2.02.54 |
109 |
_vg_global_lock_held = 0; |
110 |
}
|
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
111 |
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
112 |
lvmetad_init(); |
113 |
||
1
by Patrick Caulfield
Import upstream version 2.00.25 |
114 |
return 1; |
115 |
}
|
|
116 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
117 |
void lvmcache_seed_infos_from_lvmetad(struct cmd_context *cmd) |
118 |
{
|
|
119 |
if (!lvmetad_active() || _has_scanned) |
|
120 |
return; |
|
121 |
||
122 |
if (!lvmetad_pv_list_to_lvmcache(cmd)) { |
|
123 |
stack; |
|
124 |
return; |
|
125 |
}
|
|
126 |
||
127 |
_has_scanned = 1; |
|
128 |
};
|
|
129 |
||
130 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
131 |
/* Volume Group metadata cache functions */
|
132 |
static void _free_cached_vgmetadata(struct lvmcache_vginfo *vginfo) |
|
133 |
{
|
|
134 |
if (!vginfo || !vginfo->vgmetadata) |
|
135 |
return; |
|
136 |
||
137 |
dm_free(vginfo->vgmetadata); |
|
138 |
||
139 |
vginfo->vgmetadata = NULL; |
|
140 |
||
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
141 |
/* Release also cached config tree */
|
142 |
if (vginfo->cft) { |
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
143 |
dm_config_destroy(vginfo->cft); |
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
144 |
vginfo->cft = NULL; |
145 |
}
|
|
146 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
147 |
log_debug("Metadata cache: VG %s wiped.", vginfo->vgname); |
1.2.11
by Bastian Blank
Import upstream version 2.02.88 |
148 |
|
149 |
release_vg(vginfo->cached_vg); |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
150 |
}
|
151 |
||
1.2.2
by Bastian Blank
Import upstream version 2.02.51 |
152 |
/*
|
153 |
* Cache VG metadata against the vginfo with matching vgid.
|
|
154 |
*/
|
|
155 |
static void _store_metadata(struct volume_group *vg, unsigned precommitted) |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
156 |
{
|
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
157 |
char uuid[64] __attribute__((aligned(8))); |
1.2.2
by Bastian Blank
Import upstream version 2.02.51 |
158 |
struct lvmcache_vginfo *vginfo; |
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
159 |
char *data; |
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
160 |
size_t size; |
1.1.9
by James Westby
Import upstream version 2.02.39 |
161 |
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
162 |
if (!(vginfo = lvmcache_vginfo_from_vgid((const char *)&vg->id))) { |
1.2.2
by Bastian Blank
Import upstream version 2.02.51 |
163 |
stack; |
164 |
return; |
|
165 |
}
|
|
166 |
||
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
167 |
if (!(size = export_vg_to_buffer(vg, &data))) { |
1.1.9
by James Westby
Import upstream version 2.02.39 |
168 |
stack; |
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
169 |
_free_cached_vgmetadata(vginfo); |
1.1.9
by James Westby
Import upstream version 2.02.39 |
170 |
return; |
171 |
}
|
|
172 |
||
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
173 |
/* Avoid reparsing of the same data string */
|
174 |
if (vginfo->vgmetadata && vginfo->vgmetadata_size == size && |
|
175 |
strcmp(vginfo->vgmetadata, data) == 0) |
|
176 |
dm_free(data); |
|
177 |
else { |
|
178 |
_free_cached_vgmetadata(vginfo); |
|
179 |
vginfo->vgmetadata_size = size; |
|
180 |
vginfo->vgmetadata = data; |
|
181 |
}
|
|
182 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
183 |
vginfo->precommitted = precommitted; |
184 |
||
1.2.2
by Bastian Blank
Import upstream version 2.02.51 |
185 |
if (!id_write_format((const struct id *)vginfo->vgid, uuid, sizeof(uuid))) { |
186 |
stack; |
|
187 |
return; |
|
188 |
}
|
|
189 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
190 |
log_debug("Metadata cache: VG %s (%s) stored (%" PRIsize_t " bytes%s).", |
1.2.2
by Bastian Blank
Import upstream version 2.02.51 |
191 |
vginfo->vgname, uuid, size, |
192 |
precommitted ? ", precommitted" : ""); |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
193 |
}
|
194 |
||
195 |
static void _update_cache_info_lock_state(struct lvmcache_info *info, |
|
196 |
int locked, |
|
197 |
int *cached_vgmetadata_valid) |
|
198 |
{
|
|
199 |
int was_locked = (info->status & CACHE_LOCKED) ? 1 : 0; |
|
200 |
||
201 |
/*
|
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
202 |
* Cache becomes invalid whenever lock state changes unless
|
203 |
* exclusive VG_GLOBAL is held (i.e. while scanning).
|
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
204 |
*/
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
205 |
if (!lvmcache_vgname_is_locked(VG_GLOBAL) && (was_locked != locked)) { |
1.1.9
by James Westby
Import upstream version 2.02.39 |
206 |
info->status |= CACHE_INVALID; |
207 |
*cached_vgmetadata_valid = 0; |
|
208 |
}
|
|
209 |
||
210 |
if (locked) |
|
211 |
info->status |= CACHE_LOCKED; |
|
212 |
else
|
|
213 |
info->status &= ~CACHE_LOCKED; |
|
214 |
}
|
|
215 |
||
216 |
static void _update_cache_vginfo_lock_state(struct lvmcache_vginfo *vginfo, |
|
217 |
int locked) |
|
218 |
{
|
|
219 |
struct lvmcache_info *info; |
|
220 |
int cached_vgmetadata_valid = 1; |
|
221 |
||
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
222 |
dm_list_iterate_items(info, &vginfo->infos) |
1.1.9
by James Westby
Import upstream version 2.02.39 |
223 |
_update_cache_info_lock_state(info, locked, |
224 |
&cached_vgmetadata_valid); |
|
225 |
||
226 |
if (!cached_vgmetadata_valid) |
|
227 |
_free_cached_vgmetadata(vginfo); |
|
228 |
}
|
|
229 |
||
230 |
static void _update_cache_lock_state(const char *vgname, int locked) |
|
231 |
{
|
|
232 |
struct lvmcache_vginfo *vginfo; |
|
233 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
234 |
if (!(vginfo = lvmcache_vginfo_from_vgname(vgname, NULL))) |
1.1.9
by James Westby
Import upstream version 2.02.39 |
235 |
return; |
236 |
||
237 |
_update_cache_vginfo_lock_state(vginfo, locked); |
|
238 |
}
|
|
239 |
||
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
240 |
static void _drop_metadata(const char *vgname, int drop_precommitted) |
1.1.9
by James Westby
Import upstream version 2.02.39 |
241 |
{
|
242 |
struct lvmcache_vginfo *vginfo; |
|
243 |
struct lvmcache_info *info; |
|
244 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
245 |
if (!(vginfo = lvmcache_vginfo_from_vgname(vgname, NULL))) |
1.1.9
by James Westby
Import upstream version 2.02.39 |
246 |
return; |
247 |
||
248 |
/*
|
|
249 |
* Invalidate cached PV labels.
|
|
250 |
* If cached precommitted metadata exists that means we
|
|
251 |
* already invalidated the PV labels (before caching it)
|
|
252 |
* and we must not do it again.
|
|
253 |
*/
|
|
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
254 |
if (!drop_precommitted && vginfo->precommitted && !vginfo->vgmetadata) |
255 |
log_error(INTERNAL_ERROR "metadata commit (or revert) missing before " |
|
256 |
"dropping metadata from cache."); |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
257 |
|
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
258 |
if (drop_precommitted || !vginfo->precommitted) |
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
259 |
dm_list_iterate_items(info, &vginfo->infos) |
1.1.9
by James Westby
Import upstream version 2.02.39 |
260 |
info->status |= CACHE_INVALID; |
261 |
||
262 |
_free_cached_vgmetadata(vginfo); |
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
263 |
|
264 |
/* VG revert */
|
|
265 |
if (drop_precommitted) |
|
266 |
vginfo->precommitted = 0; |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
267 |
}
|
268 |
||
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
269 |
/*
|
270 |
* Remote node uses this to upgrade precommited metadata to commited state
|
|
271 |
* when receives vg_commit notification.
|
|
272 |
* (Note that devices can be suspended here, if so, precommited metadata are already read.)
|
|
273 |
*/
|
|
274 |
void lvmcache_commit_metadata(const char *vgname) |
|
275 |
{
|
|
276 |
struct lvmcache_vginfo *vginfo; |
|
277 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
278 |
if (!(vginfo = lvmcache_vginfo_from_vgname(vgname, NULL))) |
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
279 |
return; |
280 |
||
281 |
if (vginfo->precommitted) { |
|
282 |
log_debug("Precommitted metadata cache: VG %s upgraded to committed.", |
|
283 |
vginfo->vgname); |
|
284 |
vginfo->precommitted = 0; |
|
285 |
}
|
|
286 |
}
|
|
287 |
||
288 |
void lvmcache_drop_metadata(const char *vgname, int drop_precommitted) |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
289 |
{
|
290 |
/* For VG_ORPHANS, we need to invalidate all labels on orphan PVs. */
|
|
291 |
if (!strcmp(vgname, VG_ORPHANS)) { |
|
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
292 |
_drop_metadata(FMT_TEXT_ORPHAN_VG_NAME, 0); |
293 |
_drop_metadata(FMT_LVM1_ORPHAN_VG_NAME, 0); |
|
294 |
_drop_metadata(FMT_POOL_ORPHAN_VG_NAME, 0); |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
295 |
|
296 |
/* Indicate that PVs could now be missing from the cache */
|
|
297 |
init_full_scan_done(0); |
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
298 |
} else if (!lvmcache_vgname_is_locked(VG_GLOBAL)) |
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
299 |
_drop_metadata(vgname, drop_precommitted); |
1.1.9
by James Westby
Import upstream version 2.02.39 |
300 |
}
|
301 |
||
1.2.3
by Bastian Blank
Import upstream version 2.02.52 |
302 |
/*
|
303 |
* Ensure vgname2 comes after vgname1 alphabetically.
|
|
1.2.8
by Bastian Blank
Import upstream version 2.02.66 |
304 |
* Orphan locks come last.
|
305 |
* VG_GLOBAL comes first.
|
|
1.2.3
by Bastian Blank
Import upstream version 2.02.52 |
306 |
*/
|
307 |
static int _vgname_order_correct(const char *vgname1, const char *vgname2) |
|
308 |
{
|
|
1.2.8
by Bastian Blank
Import upstream version 2.02.66 |
309 |
if (is_global_vg(vgname1)) |
310 |
return 1; |
|
311 |
||
312 |
if (is_global_vg(vgname2)) |
|
313 |
return 0; |
|
314 |
||
315 |
if (is_orphan_vg(vgname1)) |
|
316 |
return 0; |
|
317 |
||
318 |
if (is_orphan_vg(vgname2)) |
|
1.2.3
by Bastian Blank
Import upstream version 2.02.52 |
319 |
return 1; |
320 |
||
321 |
if (strcmp(vgname1, vgname2) < 0) |
|
322 |
return 1; |
|
323 |
||
324 |
return 0; |
|
325 |
}
|
|
326 |
||
327 |
/*
|
|
328 |
* Ensure VG locks are acquired in alphabetical order.
|
|
329 |
*/
|
|
330 |
int lvmcache_verify_lock_order(const char *vgname) |
|
331 |
{
|
|
332 |
struct dm_hash_node *n; |
|
333 |
const char *vgname2; |
|
334 |
||
335 |
if (!_lock_hash) |
|
336 |
return_0; |
|
337 |
||
338 |
dm_hash_iterate(n, _lock_hash) { |
|
339 |
if (!dm_hash_get_data(_lock_hash, n)) |
|
340 |
return_0; |
|
341 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
342 |
if (!(vgname2 = dm_hash_get_key(_lock_hash, n))) { |
343 |
log_error(INTERNAL_ERROR "VG lock %s hits NULL.", |
|
344 |
vgname); |
|
345 |
return 0; |
|
346 |
}
|
|
1.2.3
by Bastian Blank
Import upstream version 2.02.52 |
347 |
|
348 |
if (!_vgname_order_correct(vgname2, vgname)) { |
|
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
349 |
log_errno(EDEADLK, INTERNAL_ERROR "VG lock %s must " |
1.2.3
by Bastian Blank
Import upstream version 2.02.52 |
350 |
"be requested before %s, not after.", |
351 |
vgname, vgname2); |
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
352 |
return 0; |
1.2.3
by Bastian Blank
Import upstream version 2.02.52 |
353 |
}
|
354 |
}
|
|
355 |
||
356 |
return 1; |
|
357 |
}
|
|
358 |
||
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
359 |
void lvmcache_lock_vgname(const char *vgname, int read_only __attribute__((unused))) |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
360 |
{
|
361 |
if (!_lock_hash && !lvmcache_init()) { |
|
362 |
log_error("Internal cache initialisation failed"); |
|
363 |
return; |
|
364 |
}
|
|
365 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
366 |
if (dm_hash_lookup(_lock_hash, vgname)) |
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
367 |
log_error(INTERNAL_ERROR "Nested locking attempted on VG %s.", |
1.1.9
by James Westby
Import upstream version 2.02.39 |
368 |
vgname); |
1.2.3
by Bastian Blank
Import upstream version 2.02.52 |
369 |
|
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
370 |
if (!dm_hash_insert(_lock_hash, vgname, (void *) 1)) |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
371 |
log_error("Cache locking failure for %s", vgname); |
372 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
373 |
_update_cache_lock_state(vgname, 1); |
374 |
||
375 |
if (strcmp(vgname, VG_GLOBAL)) |
|
376 |
_vgs_locked++; |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
377 |
}
|
378 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
379 |
int lvmcache_vgname_is_locked(const char *vgname) |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
380 |
{
|
381 |
if (!_lock_hash) |
|
382 |
return 0; |
|
383 |
||
1.2.8
by Bastian Blank
Import upstream version 2.02.66 |
384 |
return dm_hash_lookup(_lock_hash, is_orphan_vg(vgname) ? VG_ORPHANS : vgname) ? 1 : 0; |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
385 |
}
|
386 |
||
387 |
void lvmcache_unlock_vgname(const char *vgname) |
|
388 |
{
|
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
389 |
if (!dm_hash_lookup(_lock_hash, vgname)) |
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
390 |
log_error(INTERNAL_ERROR "Attempt to unlock unlocked VG %s.", |
1.1.9
by James Westby
Import upstream version 2.02.39 |
391 |
vgname); |
392 |
||
393 |
_update_cache_lock_state(vgname, 0); |
|
394 |
||
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
395 |
dm_hash_remove(_lock_hash, vgname); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
396 |
|
397 |
/* FIXME Do this per-VG */
|
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
398 |
if (strcmp(vgname, VG_GLOBAL) && !--_vgs_locked) |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
399 |
dev_close_all(); |
400 |
}
|
|
401 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
402 |
int lvmcache_vgs_locked(void) |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
403 |
{
|
404 |
return _vgs_locked; |
|
405 |
}
|
|
406 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
407 |
static void _vginfo_attach_info(struct lvmcache_vginfo *vginfo, |
408 |
struct lvmcache_info *info) |
|
409 |
{
|
|
410 |
if (!vginfo) |
|
411 |
return; |
|
412 |
||
413 |
info->vginfo = vginfo; |
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
414 |
dm_list_add(&vginfo->infos, &info->list); |
1.1.9
by James Westby
Import upstream version 2.02.39 |
415 |
}
|
416 |
||
417 |
static void _vginfo_detach_info(struct lvmcache_info *info) |
|
418 |
{
|
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
419 |
if (!dm_list_empty(&info->list)) { |
420 |
dm_list_del(&info->list); |
|
421 |
dm_list_init(&info->list); |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
422 |
}
|
423 |
||
424 |
info->vginfo = NULL; |
|
425 |
}
|
|
426 |
||
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
427 |
/* If vgid supplied, require a match. */
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
428 |
struct lvmcache_vginfo *lvmcache_vginfo_from_vgname(const char *vgname, const char *vgid) |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
429 |
{
|
430 |
struct lvmcache_vginfo *vginfo; |
|
431 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
432 |
if (!vgname) |
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
433 |
return lvmcache_vginfo_from_vgid(vgid); |
1.1.9
by James Westby
Import upstream version 2.02.39 |
434 |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
435 |
if (!_vgname_hash) |
436 |
return NULL; |
|
437 |
||
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
438 |
if (!(vginfo = dm_hash_lookup(_vgname_hash, vgname))) |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
439 |
return NULL; |
440 |
||
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
441 |
if (vgid) |
1.1.9
by James Westby
Import upstream version 2.02.39 |
442 |
do
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
443 |
if (!strncmp(vgid, vginfo->vgid, ID_LEN)) |
444 |
return vginfo; |
|
445 |
while ((vginfo = vginfo->next)); |
|
446 |
||
1
by Patrick Caulfield
Import upstream version 2.00.25 |
447 |
return vginfo; |
448 |
}
|
|
449 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
450 |
const struct format_type *lvmcache_fmt_from_vgname(struct cmd_context *cmd, |
451 |
const char *vgname, const char *vgid, |
|
452 |
unsigned revalidate_labels) |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
453 |
{
|
454 |
struct lvmcache_vginfo *vginfo; |
|
1.1.3
by Fabio M. Di Nitto
Import upstream version 2.01.14 |
455 |
struct lvmcache_info *info; |
456 |
struct label *label; |
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
457 |
struct dm_list *devh, *tmp; |
458 |
struct dm_list devs; |
|
1.1.3
by Fabio M. Di Nitto
Import upstream version 2.01.14 |
459 |
struct device_list *devl; |
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
460 |
struct volume_group *vg; |
461 |
const struct format_type *fmt; |
|
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
462 |
char vgid_found[ID_LEN + 1] __attribute__((aligned(8))); |
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
463 |
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
464 |
if (!(vginfo = lvmcache_vginfo_from_vgname(vgname, vgid))) { |
465 |
if (!lvmetad_active()) |
|
466 |
return NULL; /* too bad */ |
|
467 |
/* If we don't have the info but we have lvmetad, we can ask
|
|
468 |
* there before failing. */
|
|
469 |
if ((vg = lvmetad_vg_lookup(cmd, vgname, vgid))) { |
|
470 |
fmt = vg->fid->fmt; |
|
471 |
release_vg(vg); |
|
472 |
return fmt; |
|
473 |
}
|
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
474 |
return NULL; |
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
475 |
}
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
476 |
|
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
477 |
/*
|
478 |
* If this function is called repeatedly, only the first one needs to revalidate.
|
|
479 |
*/
|
|
480 |
if (!revalidate_labels) |
|
481 |
goto out; |
|
482 |
||
483 |
/*
|
|
484 |
* This function is normally called before reading metadata so
|
|
485 |
* we check cached labels here. Unfortunately vginfo is volatile.
|
|
486 |
*/
|
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
487 |
dm_list_init(&devs); |
488 |
dm_list_iterate_items(info, &vginfo->infos) { |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
489 |
if (!(devl = dm_malloc(sizeof(*devl)))) { |
490 |
log_error("device_list element allocation failed"); |
|
491 |
return NULL; |
|
492 |
}
|
|
1.1.3
by Fabio M. Di Nitto
Import upstream version 2.01.14 |
493 |
devl->dev = info->dev; |
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
494 |
dm_list_add(&devs, &devl->list); |
1.1.3
by Fabio M. Di Nitto
Import upstream version 2.01.14 |
495 |
}
|
496 |
||
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
497 |
memcpy(vgid_found, vginfo->vgid, sizeof(vgid_found)); |
498 |
||
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
499 |
dm_list_iterate_safe(devh, tmp, &devs) { |
500 |
devl = dm_list_item(devh, struct device_list); |
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
501 |
(void) label_read(devl->dev, &label, UINT64_C(0)); |
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
502 |
dm_list_del(&devl->list); |
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
503 |
dm_free(devl); |
1.1.3
by Fabio M. Di Nitto
Import upstream version 2.01.14 |
504 |
}
|
505 |
||
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
506 |
/* If vginfo changed, caller needs to rescan */
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
507 |
if (!(vginfo = lvmcache_vginfo_from_vgname(vgname, vgid_found)) || |
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
508 |
strncmp(vginfo->vgid, vgid_found, ID_LEN)) |
509 |
return NULL; |
|
510 |
||
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
511 |
out: |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
512 |
return vginfo->fmt; |
513 |
}
|
|
514 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
515 |
struct lvmcache_vginfo *lvmcache_vginfo_from_vgid(const char *vgid) |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
516 |
{
|
517 |
struct lvmcache_vginfo *vginfo; |
|
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
518 |
char id[ID_LEN + 1] __attribute__((aligned(8))); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
519 |
|
520 |
if (!_vgid_hash || !vgid) |
|
521 |
return NULL; |
|
522 |
||
523 |
/* vgid not necessarily NULL-terminated */
|
|
524 |
strncpy(&id[0], vgid, ID_LEN); |
|
525 |
id[ID_LEN] = '\0'; |
|
526 |
||
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
527 |
if (!(vginfo = dm_hash_lookup(_vgid_hash, id))) |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
528 |
return NULL; |
529 |
||
530 |
return vginfo; |
|
531 |
}
|
|
532 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
533 |
const char *lvmcache_vgname_from_vgid(struct dm_pool *mem, const char *vgid) |
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
534 |
{
|
535 |
struct lvmcache_vginfo *vginfo; |
|
1.1.7
by Scott James Remnant
Import upstream version 2.02.24 |
536 |
const char *vgname = NULL; |
537 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
538 |
if ((vginfo = lvmcache_vginfo_from_vgid(vgid))) |
1.1.7
by Scott James Remnant
Import upstream version 2.02.24 |
539 |
vgname = vginfo->vgname; |
540 |
||
541 |
if (mem && vgname) |
|
542 |
return dm_pool_strdup(mem, vgname); |
|
543 |
||
544 |
return vgname; |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
545 |
}
|
546 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
547 |
static int _info_is_valid(struct lvmcache_info *info) |
548 |
{
|
|
549 |
if (info->status & CACHE_INVALID) |
|
550 |
return 0; |
|
551 |
||
552 |
/*
|
|
553 |
* The caller must hold the VG lock to manipulate metadata.
|
|
554 |
* In a cluster, remote nodes sometimes read metadata in the
|
|
555 |
* knowledge that the controlling node is holding the lock.
|
|
556 |
* So if the VG appears to be unlocked here, it should be safe
|
|
557 |
* to use the cached value.
|
|
558 |
*/
|
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
559 |
if (info->vginfo && !lvmcache_vgname_is_locked(info->vginfo->vgname)) |
1.1.9
by James Westby
Import upstream version 2.02.39 |
560 |
return 1; |
561 |
||
562 |
if (!(info->status & CACHE_LOCKED)) |
|
563 |
return 0; |
|
564 |
||
565 |
return 1; |
|
566 |
}
|
|
567 |
||
568 |
static int _vginfo_is_valid(struct lvmcache_vginfo *vginfo) |
|
569 |
{
|
|
570 |
struct lvmcache_info *info; |
|
571 |
||
572 |
/* Invalid if any info is invalid */
|
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
573 |
dm_list_iterate_items(info, &vginfo->infos) |
1.1.9
by James Westby
Import upstream version 2.02.39 |
574 |
if (!_info_is_valid(info)) |
575 |
return 0; |
|
576 |
||
577 |
return 1; |
|
578 |
}
|
|
579 |
||
580 |
/* vginfo is invalid if it does not contain at least one valid info */
|
|
581 |
static int _vginfo_is_invalid(struct lvmcache_vginfo *vginfo) |
|
582 |
{
|
|
583 |
struct lvmcache_info *info; |
|
584 |
||
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
585 |
dm_list_iterate_items(info, &vginfo->infos) |
1.1.9
by James Westby
Import upstream version 2.02.39 |
586 |
if (_info_is_valid(info)) |
587 |
return 0; |
|
588 |
||
589 |
return 1; |
|
590 |
}
|
|
591 |
||
592 |
/*
|
|
593 |
* If valid_only is set, data will only be returned if the cached data is
|
|
594 |
* known still to be valid.
|
|
595 |
*/
|
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
596 |
struct lvmcache_info *lvmcache_info_from_pvid(const char *pvid, int valid_only) |
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
597 |
{
|
598 |
struct lvmcache_info *info; |
|
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
599 |
char id[ID_LEN + 1] __attribute__((aligned(8))); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
600 |
|
601 |
if (!_pvid_hash || !pvid) |
|
602 |
return NULL; |
|
603 |
||
604 |
strncpy(&id[0], pvid, ID_LEN); |
|
605 |
id[ID_LEN] = '\0'; |
|
606 |
||
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
607 |
if (!(info = dm_hash_lookup(_pvid_hash, id))) |
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
608 |
return NULL; |
609 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
610 |
if (valid_only && !_info_is_valid(info)) |
611 |
return NULL; |
|
612 |
||
1
by Patrick Caulfield
Import upstream version 2.00.25 |
613 |
return info; |
614 |
}
|
|
615 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
616 |
const char *lvmcache_vgname_from_info(struct lvmcache_info *info) |
617 |
{
|
|
618 |
if (info->vginfo) |
|
619 |
return info->vginfo->vgname; |
|
620 |
return NULL; |
|
621 |
}
|
|
622 |
||
1.2.8
by Bastian Blank
Import upstream version 2.02.66 |
623 |
char *lvmcache_vgname_from_pvid(struct cmd_context *cmd, const char *pvid) |
624 |
{
|
|
625 |
struct lvmcache_info *info; |
|
626 |
char *vgname; |
|
627 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
628 |
if (!lvmcache_device_from_pvid(cmd, (const struct id *)pvid, NULL, NULL)) { |
1.2.8
by Bastian Blank
Import upstream version 2.02.66 |
629 |
log_error("Couldn't find device with uuid %s.", pvid); |
630 |
return NULL; |
|
631 |
}
|
|
632 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
633 |
info = lvmcache_info_from_pvid(pvid, 0); |
1.2.8
by Bastian Blank
Import upstream version 2.02.66 |
634 |
if (!info) |
635 |
return_NULL; |
|
636 |
||
637 |
if (!(vgname = dm_pool_strdup(cmd->mem, info->vginfo->vgname))) { |
|
638 |
log_errno(ENOMEM, "vgname allocation failed"); |
|
639 |
return NULL; |
|
640 |
}
|
|
641 |
return vgname; |
|
642 |
}
|
|
643 |
||
1
by Patrick Caulfield
Import upstream version 2.00.25 |
644 |
static void _rescan_entry(struct lvmcache_info *info) |
645 |
{
|
|
646 |
struct label *label; |
|
647 |
||
648 |
if (info->status & CACHE_INVALID) |
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
649 |
(void) label_read(info->dev, &label, UINT64_C(0)); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
650 |
}
|
651 |
||
652 |
static int _scan_invalid(void) |
|
653 |
{
|
|
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
654 |
dm_hash_iter(_pvid_hash, (dm_hash_iterate_fn) _rescan_entry); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
655 |
|
656 |
return 1; |
|
657 |
}
|
|
658 |
||
659 |
int lvmcache_label_scan(struct cmd_context *cmd, int full_scan) |
|
660 |
{
|
|
661 |
struct label *label; |
|
662 |
struct dev_iter *iter; |
|
663 |
struct device *dev; |
|
664 |
struct format_type *fmt; |
|
665 |
||
666 |
int r = 0; |
|
667 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
668 |
if (lvmetad_active()) |
669 |
return 1; |
|
670 |
||
1
by Patrick Caulfield
Import upstream version 2.00.25 |
671 |
/* Avoid recursion when a PVID can't be found! */
|
672 |
if (_scanning_in_progress) |
|
673 |
return 0; |
|
674 |
||
675 |
_scanning_in_progress = 1; |
|
676 |
||
677 |
if (!_vgname_hash && !lvmcache_init()) { |
|
678 |
log_error("Internal cache initialisation failed"); |
|
679 |
goto out; |
|
680 |
}
|
|
681 |
||
682 |
if (_has_scanned && !full_scan) { |
|
683 |
r = _scan_invalid(); |
|
684 |
goto out; |
|
685 |
}
|
|
686 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
687 |
if (full_scan == 2 && (cmd->filter && !cmd->filter->use_count) && !refresh_filters(cmd)) |
688 |
goto_out; |
|
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
689 |
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
690 |
if (!cmd->filter || !(iter = dev_iter_create(cmd->filter, (full_scan == 2) ? 1 : 0))) { |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
691 |
log_error("dev_iter creation failed"); |
692 |
goto out; |
|
693 |
}
|
|
694 |
||
695 |
while ((dev = dev_iter_get(iter))) |
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
696 |
(void) label_read(dev, &label, UINT64_C(0)); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
697 |
|
698 |
dev_iter_destroy(iter); |
|
699 |
||
700 |
_has_scanned = 1; |
|
701 |
||
702 |
/* Perform any format-specific scanning e.g. text files */
|
|
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
703 |
if (cmd->independent_metadata_areas) |
704 |
dm_list_iterate_items(fmt, &cmd->formats) |
|
705 |
if (fmt->ops->scan && !fmt->ops->scan(fmt, NULL)) |
|
706 |
goto out; |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
707 |
|
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
708 |
/*
|
709 |
* If we are a long-lived process, write out the updated persistent
|
|
710 |
* device cache for the benefit of short-lived processes.
|
|
711 |
*/
|
|
712 |
if (full_scan == 2 && cmd->is_long_lived && cmd->dump_filter) |
|
1.2.8
by Bastian Blank
Import upstream version 2.02.66 |
713 |
persistent_filter_dump(cmd->filter, 0); |
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
714 |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
715 |
r = 1; |
716 |
||
717 |
out: |
|
718 |
_scanning_in_progress = 0; |
|
719 |
||
720 |
return r; |
|
721 |
}
|
|
722 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
723 |
struct volume_group *lvmcache_get_vg(struct cmd_context *cmd, const char *vgname, |
724 |
const char *vgid, unsigned precommitted) |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
725 |
{
|
726 |
struct lvmcache_vginfo *vginfo; |
|
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
727 |
struct volume_group *vg = NULL; |
1.1.9
by James Westby
Import upstream version 2.02.39 |
728 |
struct format_instance *fid; |
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
729 |
struct format_instance_ctx fic; |
1.1.9
by James Westby
Import upstream version 2.02.39 |
730 |
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
731 |
/*
|
732 |
* We currently do not store precommitted metadata in lvmetad at
|
|
733 |
* all. This means that any request for precommitted metadata is served
|
|
734 |
* using the classic scanning mechanics, and read from disk or from
|
|
735 |
* lvmcache.
|
|
736 |
*/
|
|
737 |
if (lvmetad_active() && !precommitted) { |
|
738 |
/* Still serve the locally cached VG if available */
|
|
739 |
if (vgid && (vginfo = lvmcache_vginfo_from_vgid(vgid)) && |
|
740 |
vginfo->vgmetadata && (vg = vginfo->cached_vg)) |
|
741 |
goto out; |
|
742 |
return lvmetad_vg_lookup(cmd, vgname, vgid); |
|
743 |
}
|
|
744 |
||
745 |
if (!vgid || !(vginfo = lvmcache_vginfo_from_vgid(vgid)) || !vginfo->vgmetadata) |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
746 |
return NULL; |
747 |
||
748 |
if (!_vginfo_is_valid(vginfo)) |
|
749 |
return NULL; |
|
750 |
||
751 |
/*
|
|
752 |
* Don't return cached data if either:
|
|
753 |
* (i) precommitted metadata is requested but we don't have it cached
|
|
754 |
* - caller should read it off disk;
|
|
755 |
* (ii) live metadata is requested but we have precommitted metadata cached
|
|
756 |
* and no devices are suspended so caller may read it off disk.
|
|
757 |
*
|
|
758 |
* If live metadata is requested but we have precommitted metadata cached
|
|
759 |
* and devices are suspended, we assume this precommitted metadata has
|
|
760 |
* already been preloaded and committed so it's OK to return it as live.
|
|
761 |
* Note that we do not clear the PRECOMMITTED flag.
|
|
762 |
*/
|
|
763 |
if ((precommitted && !vginfo->precommitted) || |
|
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
764 |
(!precommitted && vginfo->precommitted && !critical_section())) |
1.1.9
by James Westby
Import upstream version 2.02.39 |
765 |
return NULL; |
766 |
||
1.2.11
by Bastian Blank
Import upstream version 2.02.88 |
767 |
/* Use already-cached VG struct when available */
|
768 |
if ((vg = vginfo->cached_vg)) |
|
769 |
goto out; |
|
770 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
771 |
fic.type = FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS; |
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
772 |
fic.context.vg_ref.vg_name = vginfo->vgname; |
773 |
fic.context.vg_ref.vg_id = vgid; |
|
774 |
if (!(fid = vginfo->fmt->ops->create_instance(vginfo->fmt, &fic))) |
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
775 |
return_NULL; |
776 |
||
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
777 |
/* Build config tree from vgmetadata, if not yet cached */
|
778 |
if (!vginfo->cft && |
|
779 |
!(vginfo->cft = |
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
780 |
dm_config_from_string(vginfo->vgmetadata))) |
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
781 |
goto_bad; |
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
782 |
|
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
783 |
if (!(vg = import_vg_from_config_tree(vginfo->cft, fid))) |
784 |
goto_bad; |
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
785 |
|
1.2.11
by Bastian Blank
Import upstream version 2.02.88 |
786 |
/* Cache VG struct for reuse */
|
787 |
vginfo->cached_vg = vg; |
|
788 |
vginfo->holders = 1; |
|
789 |
vginfo->vg_use_count = 0; |
|
790 |
vg->vginfo = vginfo; |
|
791 |
||
792 |
if (!dm_pool_lock(vg->vgmem, detect_internal_vg_cache_corruption())) |
|
793 |
goto_bad; |
|
794 |
||
795 |
out: |
|
796 |
vginfo->holders++; |
|
797 |
vginfo->vg_use_count++; |
|
798 |
log_debug("Using cached %smetadata for VG %s with %u holder(s).", |
|
799 |
vginfo->precommitted ? "pre-committed " : "", |
|
800 |
vginfo->vgname, vginfo->holders); |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
801 |
|
802 |
return vg; |
|
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
803 |
|
804 |
bad: |
|
805 |
_free_cached_vgmetadata(vginfo); |
|
806 |
return NULL; |
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
807 |
}
|
808 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
809 |
// #if 0
|
810 |
int lvmcache_vginfo_holders_dec_and_test_for_zero(struct lvmcache_vginfo *vginfo) |
|
1.2.11
by Bastian Blank
Import upstream version 2.02.88 |
811 |
{
|
812 |
log_debug("VG %s decrementing %d holder(s) at %p.", |
|
813 |
vginfo->cached_vg->name, vginfo->holders, vginfo->cached_vg); |
|
814 |
||
815 |
if (--vginfo->holders) |
|
816 |
return 0; |
|
817 |
||
818 |
if (vginfo->vg_use_count > 1) |
|
819 |
log_debug("VG %s reused %d times.", |
|
820 |
vginfo->cached_vg->name, vginfo->vg_use_count); |
|
821 |
||
822 |
/* Debug perform crc check only when it's been used more then once */
|
|
823 |
if (!dm_pool_unlock(vginfo->cached_vg->vgmem, |
|
824 |
detect_internal_vg_cache_corruption() && |
|
825 |
(vginfo->vg_use_count > 1))) |
|
826 |
stack; |
|
827 |
||
828 |
vginfo->cached_vg->vginfo = NULL; |
|
829 |
vginfo->cached_vg = NULL; |
|
830 |
||
831 |
return 1; |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
832 |
}
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
833 |
// #endif
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
834 |
|
1.2.7
by Bastian Blank
Import upstream version 2.02.64 |
835 |
struct dm_list *lvmcache_get_vgids(struct cmd_context *cmd, |
836 |
int include_internal) |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
837 |
{
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
838 |
struct dm_list *vgids; |
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
839 |
struct lvmcache_vginfo *vginfo; |
840 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
841 |
// TODO plug into lvmetad here automagically?
|
1.2.7
by Bastian Blank
Import upstream version 2.02.64 |
842 |
lvmcache_label_scan(cmd, 0); |
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
843 |
|
844 |
if (!(vgids = str_list_create(cmd->mem))) { |
|
845 |
log_error("vgids list allocation failed"); |
|
846 |
return NULL; |
|
847 |
}
|
|
848 |
||
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
849 |
dm_list_iterate_items(vginfo, &_vginfos) { |
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
850 |
if (!include_internal && is_orphan_vg(vginfo->vgname)) |
851 |
continue; |
|
852 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
853 |
if (!str_list_add(cmd->mem, vgids, |
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
854 |
dm_pool_strdup(cmd->mem, vginfo->vgid))) { |
855 |
log_error("strlist allocation failed"); |
|
856 |
return NULL; |
|
857 |
}
|
|
858 |
}
|
|
859 |
||
860 |
return vgids; |
|
861 |
}
|
|
862 |
||
1.2.7
by Bastian Blank
Import upstream version 2.02.64 |
863 |
struct dm_list *lvmcache_get_vgnames(struct cmd_context *cmd, |
864 |
int include_internal) |
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
865 |
{
|
866 |
struct dm_list *vgnames; |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
867 |
struct lvmcache_vginfo *vginfo; |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
868 |
|
1.2.7
by Bastian Blank
Import upstream version 2.02.64 |
869 |
lvmcache_label_scan(cmd, 0); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
870 |
|
871 |
if (!(vgnames = str_list_create(cmd->mem))) { |
|
1.2.2
by Bastian Blank
Import upstream version 2.02.51 |
872 |
log_errno(ENOMEM, "vgnames list allocation failed"); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
873 |
return NULL; |
874 |
}
|
|
875 |
||
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
876 |
dm_list_iterate_items(vginfo, &_vginfos) { |
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
877 |
if (!include_internal && is_orphan_vg(vginfo->vgname)) |
878 |
continue; |
|
879 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
880 |
if (!str_list_add(cmd->mem, vgnames, |
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
881 |
dm_pool_strdup(cmd->mem, vginfo->vgname))) { |
1.2.2
by Bastian Blank
Import upstream version 2.02.51 |
882 |
log_errno(ENOMEM, "strlist allocation failed"); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
883 |
return NULL; |
884 |
}
|
|
885 |
}
|
|
886 |
||
887 |
return vgnames; |
|
888 |
}
|
|
889 |
||
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
890 |
struct dm_list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname, |
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
891 |
const char *vgid) |
892 |
{
|
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
893 |
struct dm_list *pvids; |
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
894 |
struct lvmcache_vginfo *vginfo; |
895 |
struct lvmcache_info *info; |
|
896 |
||
897 |
if (!(pvids = str_list_create(cmd->mem))) { |
|
898 |
log_error("pvids list allocation failed"); |
|
899 |
return NULL; |
|
900 |
}
|
|
901 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
902 |
if (!(vginfo = lvmcache_vginfo_from_vgname(vgname, vgid))) |
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
903 |
return pvids; |
904 |
||
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
905 |
dm_list_iterate_items(info, &vginfo->infos) { |
1.1.9
by James Westby
Import upstream version 2.02.39 |
906 |
if (!str_list_add(cmd->mem, pvids, |
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
907 |
dm_pool_strdup(cmd->mem, info->dev->pvid))) { |
908 |
log_error("strlist allocation failed"); |
|
909 |
return NULL; |
|
910 |
}
|
|
911 |
}
|
|
912 |
||
913 |
return pvids; |
|
914 |
}
|
|
915 |
||
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
916 |
static struct device *_device_from_pvid(const struct id *pvid, |
917 |
uint64_t *label_sector) |
|
918 |
{
|
|
919 |
struct lvmcache_info *info; |
|
920 |
struct label *label; |
|
921 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
922 |
if ((info = lvmcache_info_from_pvid((const char *) pvid, 0))) { |
923 |
if (lvmetad_active()) { |
|
924 |
if (info->label && label_sector) |
|
925 |
*label_sector = info->label->sector; |
|
926 |
return info->dev; |
|
927 |
}
|
|
928 |
||
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
929 |
if (label_read(info->dev, &label, UINT64_C(0))) { |
930 |
info = (struct lvmcache_info *) label->info; |
|
931 |
if (id_equal(pvid, (struct id *) &info->dev->pvid)) { |
|
932 |
if (label_sector) |
|
933 |
*label_sector = label->sector; |
|
934 |
return info->dev; |
|
935 |
}
|
|
936 |
}
|
|
937 |
}
|
|
938 |
return NULL; |
|
939 |
}
|
|
940 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
941 |
struct device *lvmcache_device_from_pvid(struct cmd_context *cmd, const struct id *pvid, |
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
942 |
unsigned *scan_done_once, uint64_t *label_sector) |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
943 |
{
|
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
944 |
struct device *dev; |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
945 |
|
946 |
/* Already cached ? */
|
|
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
947 |
dev = _device_from_pvid(pvid, label_sector); |
948 |
if (dev) |
|
949 |
return dev; |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
950 |
|
951 |
lvmcache_label_scan(cmd, 0); |
|
952 |
||
953 |
/* Try again */
|
|
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
954 |
dev = _device_from_pvid(pvid, label_sector); |
955 |
if (dev) |
|
956 |
return dev; |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
957 |
|
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
958 |
if (critical_section() || (scan_done_once && *scan_done_once)) |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
959 |
return NULL; |
960 |
||
1.1.3
by Fabio M. Di Nitto
Import upstream version 2.01.14 |
961 |
lvmcache_label_scan(cmd, 2); |
1.2.7
by Bastian Blank
Import upstream version 2.02.64 |
962 |
if (scan_done_once) |
963 |
*scan_done_once = 1; |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
964 |
|
965 |
/* Try again */
|
|
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
966 |
dev = _device_from_pvid(pvid, label_sector); |
967 |
if (dev) |
|
968 |
return dev; |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
969 |
|
970 |
return NULL; |
|
971 |
}
|
|
972 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
973 |
const char *lvmcache_pvid_from_devname(struct cmd_context *cmd, |
1.2.8
by Bastian Blank
Import upstream version 2.02.66 |
974 |
const char *devname) |
975 |
{
|
|
976 |
struct device *dev; |
|
977 |
struct label *label; |
|
978 |
||
979 |
if (!(dev = dev_cache_get(devname, cmd->filter))) { |
|
980 |
log_error("%s: Couldn't find device. Check your filters?", |
|
981 |
devname); |
|
982 |
return NULL; |
|
983 |
}
|
|
984 |
||
985 |
if (!(label_read(dev, &label, UINT64_C(0)))) |
|
986 |
return NULL; |
|
987 |
||
988 |
return dev->pvid; |
|
989 |
}
|
|
990 |
||
991 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
992 |
static int _free_vginfo(struct lvmcache_vginfo *vginfo) |
993 |
{
|
|
994 |
struct lvmcache_vginfo *primary_vginfo, *vginfo2; |
|
995 |
int r = 1; |
|
996 |
||
997 |
_free_cached_vgmetadata(vginfo); |
|
998 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
999 |
vginfo2 = primary_vginfo = lvmcache_vginfo_from_vgname(vginfo->vgname, NULL); |
1.1.9
by James Westby
Import upstream version 2.02.39 |
1000 |
|
1001 |
if (vginfo == primary_vginfo) { |
|
1002 |
dm_hash_remove(_vgname_hash, vginfo->vgname); |
|
1003 |
if (vginfo->next && !dm_hash_insert(_vgname_hash, vginfo->vgname, |
|
1004 |
vginfo->next)) { |
|
1005 |
log_error("_vgname_hash re-insertion for %s failed", |
|
1006 |
vginfo->vgname); |
|
1007 |
r = 0; |
|
1008 |
}
|
|
1009 |
} else do |
|
1010 |
if (vginfo2->next == vginfo) { |
|
1011 |
vginfo2->next = vginfo->next; |
|
1012 |
break; |
|
1013 |
}
|
|
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
1014 |
while ((vginfo2 = vginfo2->next)); |
1015 |
||
1016 |
dm_free(vginfo->vgname); |
|
1017 |
dm_free(vginfo->creation_host); |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1018 |
|
1019 |
if (*vginfo->vgid && _vgid_hash && |
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
1020 |
lvmcache_vginfo_from_vgid(vginfo->vgid) == vginfo) |
1.1.9
by James Westby
Import upstream version 2.02.39 |
1021 |
dm_hash_remove(_vgid_hash, vginfo->vgid); |
1022 |
||
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1023 |
dm_list_del(&vginfo->list); |
1.1.9
by James Westby
Import upstream version 2.02.39 |
1024 |
|
1025 |
dm_free(vginfo); |
|
1026 |
||
1027 |
return r; |
|
1028 |
}
|
|
1029 |
||
1030 |
/*
|
|
1031 |
* vginfo must be info->vginfo unless info is NULL
|
|
1032 |
*/
|
|
1033 |
static int _drop_vginfo(struct lvmcache_info *info, struct lvmcache_vginfo *vginfo) |
|
1034 |
{
|
|
1035 |
if (info) |
|
1036 |
_vginfo_detach_info(info); |
|
1037 |
||
1038 |
/* vginfo still referenced? */
|
|
1039 |
if (!vginfo || is_orphan_vg(vginfo->vgname) || |
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1040 |
!dm_list_empty(&vginfo->infos)) |
1.1.9
by James Westby
Import upstream version 2.02.39 |
1041 |
return 1; |
1042 |
||
1043 |
if (!_free_vginfo(vginfo)) |
|
1044 |
return_0; |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1045 |
|
1046 |
return 1; |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1047 |
}
|
1048 |
||
1049 |
/* Unused
|
|
1050 |
void lvmcache_del(struct lvmcache_info *info)
|
|
1051 |
{
|
|
1052 |
if (info->dev->pvid[0] && _pvid_hash)
|
|
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
1053 |
dm_hash_remove(_pvid_hash, info->dev->pvid);
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1054 |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1055 |
_drop_vginfo(info, info->vginfo);
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1056 |
|
1057 |
info->label->labeller->ops->destroy_label(info->label->labeller,
|
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1058 |
info->label);
|
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
1059 |
dm_free(info);
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1060 |
|
1061 |
return;
|
|
1062 |
} */
|
|
1063 |
||
1064 |
static int _lvmcache_update_pvid(struct lvmcache_info *info, const char *pvid) |
|
1065 |
{
|
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1066 |
/*
|
1067 |
* Nothing to do if already stored with same pvid.
|
|
1068 |
*/
|
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
1069 |
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1070 |
if (((dm_hash_lookup(_pvid_hash, pvid)) == info) && |
1071 |
!strcmp(info->dev->pvid, pvid)) |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1072 |
return 1; |
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1073 |
if (*info->dev->pvid) |
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
1074 |
dm_hash_remove(_pvid_hash, info->dev->pvid); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1075 |
strncpy(info->dev->pvid, pvid, sizeof(info->dev->pvid)); |
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
1076 |
if (!dm_hash_insert(_pvid_hash, pvid, info)) { |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1077 |
log_error("_lvmcache_update: pvid insertion failed: %s", pvid); |
1078 |
return 0; |
|
1079 |
}
|
|
1080 |
||
1081 |
return 1; |
|
1082 |
}
|
|
1083 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
1084 |
/*
|
1085 |
* vginfo must be info->vginfo unless info is NULL (orphans)
|
|
1086 |
*/
|
|
1087 |
static int _lvmcache_update_vgid(struct lvmcache_info *info, |
|
1088 |
struct lvmcache_vginfo *vginfo, |
|
1089 |
const char *vgid) |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1090 |
{
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1091 |
if (!vgid || !vginfo || |
1092 |
!strncmp(vginfo->vgid, vgid, ID_LEN)) |
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1093 |
return 1; |
1094 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
1095 |
if (vginfo && *vginfo->vgid) |
1096 |
dm_hash_remove(_vgid_hash, vginfo->vgid); |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1097 |
if (!vgid) { |
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
1098 |
/* FIXME: unreachable code path */
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1099 |
log_debug("lvmcache: %s: clearing VGID", info ? dev_name(info->dev) : vginfo->vgname); |
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1100 |
return 1; |
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1101 |
}
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1102 |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1103 |
strncpy(vginfo->vgid, vgid, ID_LEN); |
1104 |
vginfo->vgid[ID_LEN] = '\0'; |
|
1105 |
if (!dm_hash_insert(_vgid_hash, vginfo->vgid, vginfo)) { |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1106 |
log_error("_lvmcache_update: vgid hash insertion failed: %s", |
1.1.9
by James Westby
Import upstream version 2.02.39 |
1107 |
vginfo->vgid); |
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1108 |
return 0; |
1109 |
}
|
|
1110 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
1111 |
if (!is_orphan_vg(vginfo->vgname)) |
1112 |
log_debug("lvmcache: %s: setting %s VGID to %s", |
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
1113 |
(info) ? dev_name(info->dev) : "", |
1114 |
vginfo->vgname, vginfo->vgid); |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1115 |
|
1116 |
return 1; |
|
1117 |
}
|
|
1118 |
||
1119 |
static int _insert_vginfo(struct lvmcache_vginfo *new_vginfo, const char *vgid, |
|
1120 |
uint32_t vgstatus, const char *creation_host, |
|
1121 |
struct lvmcache_vginfo *primary_vginfo) |
|
1122 |
{
|
|
1123 |
struct lvmcache_vginfo *last_vginfo = primary_vginfo; |
|
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
1124 |
char uuid_primary[64] __attribute__((aligned(8))); |
1125 |
char uuid_new[64] __attribute__((aligned(8))); |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1126 |
int use_new = 0; |
1.2.3
by Bastian Blank
Import upstream version 2.02.52 |
1127 |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1128 |
/* Pre-existing VG takes precedence. Unexported VG takes precedence. */
|
1129 |
if (primary_vginfo) { |
|
1130 |
if (!id_write_format((const struct id *)vgid, uuid_new, sizeof(uuid_new))) |
|
1131 |
return_0; |
|
1132 |
||
1133 |
if (!id_write_format((const struct id *)&primary_vginfo->vgid, uuid_primary, |
|
1134 |
sizeof(uuid_primary))) |
|
1135 |
return_0; |
|
1136 |
||
1137 |
/*
|
|
1138 |
* If Primary not exported, new exported => keep
|
|
1139 |
* Else Primary exported, new not exported => change
|
|
1140 |
* Else Primary has hostname for this machine => keep
|
|
1141 |
* Else Primary has no hostname, new has one => change
|
|
1142 |
* Else New has hostname for this machine => change
|
|
1143 |
* Else Keep primary.
|
|
1144 |
*/
|
|
1145 |
if (!(primary_vginfo->status & EXPORTED_VG) && |
|
1146 |
(vgstatus & EXPORTED_VG)) |
|
1.2.7
by Bastian Blank
Import upstream version 2.02.64 |
1147 |
log_warn("WARNING: Duplicate VG name %s: " |
1148 |
"Existing %s takes precedence over "
|
|
1149 |
"exported %s", new_vginfo->vgname, |
|
1150 |
uuid_primary, uuid_new); |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1151 |
else if ((primary_vginfo->status & EXPORTED_VG) && |
1152 |
!(vgstatus & EXPORTED_VG)) { |
|
1.2.7
by Bastian Blank
Import upstream version 2.02.64 |
1153 |
log_warn("WARNING: Duplicate VG name %s: " |
1154 |
"%s takes precedence over exported %s", |
|
1155 |
new_vginfo->vgname, uuid_new, |
|
1156 |
uuid_primary); |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1157 |
use_new = 1; |
1158 |
} else if (primary_vginfo->creation_host && |
|
1159 |
!strcmp(primary_vginfo->creation_host, |
|
1160 |
primary_vginfo->fmt->cmd->hostname)) |
|
1.2.7
by Bastian Blank
Import upstream version 2.02.64 |
1161 |
log_warn("WARNING: Duplicate VG name %s: " |
1162 |
"Existing %s (created here) takes precedence "
|
|
1163 |
"over %s", new_vginfo->vgname, uuid_primary, |
|
1164 |
uuid_new); |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1165 |
else if (!primary_vginfo->creation_host && creation_host) { |
1.2.7
by Bastian Blank
Import upstream version 2.02.64 |
1166 |
log_warn("WARNING: Duplicate VG name %s: " |
1167 |
"%s (with creation_host) takes precedence over %s", |
|
1168 |
new_vginfo->vgname, uuid_new, |
|
1169 |
uuid_primary); |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1170 |
use_new = 1; |
1171 |
} else if (creation_host && |
|
1172 |
!strcmp(creation_host, |
|
1173 |
primary_vginfo->fmt->cmd->hostname)) { |
|
1.2.7
by Bastian Blank
Import upstream version 2.02.64 |
1174 |
log_warn("WARNING: Duplicate VG name %s: " |
1175 |
"%s (created here) takes precedence over %s", |
|
1176 |
new_vginfo->vgname, uuid_new, |
|
1177 |
uuid_primary); |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1178 |
use_new = 1; |
1179 |
}
|
|
1180 |
||
1181 |
if (!use_new) { |
|
1182 |
while (last_vginfo->next) |
|
1183 |
last_vginfo = last_vginfo->next; |
|
1184 |
last_vginfo->next = new_vginfo; |
|
1185 |
return 1; |
|
1186 |
}
|
|
1187 |
||
1188 |
dm_hash_remove(_vgname_hash, primary_vginfo->vgname); |
|
1189 |
}
|
|
1190 |
||
1191 |
if (!dm_hash_insert(_vgname_hash, new_vginfo->vgname, new_vginfo)) { |
|
1192 |
log_error("cache_update: vg hash insertion failed: %s", |
|
1193 |
new_vginfo->vgname); |
|
1194 |
return 0; |
|
1195 |
}
|
|
1196 |
||
1197 |
if (primary_vginfo) |
|
1198 |
new_vginfo->next = primary_vginfo; |
|
1199 |
||
1200 |
return 1; |
|
1201 |
}
|
|
1202 |
||
1203 |
static int _lvmcache_update_vgname(struct lvmcache_info *info, |
|
1204 |
const char *vgname, const char *vgid, |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1205 |
uint32_t vgstatus, const char *creation_host, |
1206 |
const struct format_type *fmt) |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1207 |
{
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1208 |
struct lvmcache_vginfo *vginfo, *primary_vginfo, *orphan_vginfo; |
1209 |
struct lvmcache_info *info2, *info3; |
|
1210 |
char mdabuf[32]; |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1211 |
// struct lvmcache_vginfo *old_vginfo, *next;
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1212 |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1213 |
if (!vgname || (info && info->vginfo && !strcmp(info->vginfo->vgname, vgname))) |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1214 |
return 1; |
1215 |
||
1216 |
/* Remove existing vginfo entry */
|
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1217 |
if (info) |
1218 |
_drop_vginfo(info, info->vginfo); |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1219 |
|
1220 |
/* Get existing vginfo or create new one */
|
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
1221 |
if (!(vginfo = lvmcache_vginfo_from_vgname(vgname, vgid))) { |
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1222 |
/*** FIXME - vginfo ends up duplicated instead of renamed.
|
1223 |
// Renaming? This lookup fails.
|
|
1224 |
if ((vginfo = vginfo_from_vgid(vgid))) {
|
|
1225 |
next = vginfo->next;
|
|
1226 |
old_vginfo = vginfo_from_vgname(vginfo->vgname, NULL);
|
|
1227 |
if (old_vginfo == vginfo) {
|
|
1228 |
dm_hash_remove(_vgname_hash, old_vginfo->vgname);
|
|
1229 |
if (old_vginfo->next) {
|
|
1230 |
if (!dm_hash_insert(_vgname_hash, old_vginfo->vgname, old_vginfo->next)) {
|
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1231 |
log_error("vg hash re-insertion failed: %s",
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1232 |
old_vginfo->vgname);
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1233 |
return 0;
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1234 |
}
|
1235 |
}
|
|
1236 |
} else do {
|
|
1237 |
if (old_vginfo->next == vginfo) {
|
|
1238 |
old_vginfo->next = vginfo->next;
|
|
1239 |
break;
|
|
1240 |
}
|
|
1241 |
} while ((old_vginfo = old_vginfo->next));
|
|
1242 |
vginfo->next = NULL;
|
|
1243 |
||
1244 |
dm_free(vginfo->vgname);
|
|
1245 |
if (!(vginfo->vgname = dm_strdup(vgname))) {
|
|
1246 |
log_error("cache vgname alloc failed for %s", vgname);
|
|
1247 |
return 0;
|
|
1248 |
}
|
|
1249 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
1250 |
// Rename so can assume new name does not already exist
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1251 |
if (!dm_hash_insert(_vgname_hash, vginfo->vgname, vginfo->next)) {
|
1252 |
log_error("vg hash re-insertion failed: %s",
|
|
1253 |
vginfo->vgname);
|
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1254 |
return 0;
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1255 |
}
|
1256 |
} else {
|
|
1257 |
***/
|
|
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
1258 |
if (!(vginfo = dm_zalloc(sizeof(*vginfo)))) { |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1259 |
log_error("lvmcache_update_vgname: list alloc failed"); |
1260 |
return 0; |
|
1261 |
}
|
|
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
1262 |
if (!(vginfo->vgname = dm_strdup(vgname))) { |
1263 |
dm_free(vginfo); |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1264 |
log_error("cache vgname alloc failed for %s", vgname); |
1265 |
return 0; |
|
1266 |
}
|
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1267 |
dm_list_init(&vginfo->infos); |
1.1.9
by James Westby
Import upstream version 2.02.39 |
1268 |
|
1269 |
/*
|
|
1270 |
* If we're scanning and there's an invalidated entry, remove it.
|
|
1271 |
* Otherwise we risk bogus warnings of duplicate VGs.
|
|
1272 |
*/
|
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
1273 |
while ((primary_vginfo = lvmcache_vginfo_from_vgname(vgname, NULL)) && |
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
1274 |
_scanning_in_progress && _vginfo_is_invalid(primary_vginfo)) { |
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
1275 |
orphan_vginfo = lvmcache_vginfo_from_vgname(primary_vginfo->fmt->orphan_vg_name, NULL); |
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
1276 |
if (!orphan_vginfo) { |
1277 |
log_error(INTERNAL_ERROR "Orphan vginfo %s lost from cache.", |
|
1278 |
primary_vginfo->fmt->orphan_vg_name); |
|
1279 |
dm_free(vginfo->vgname); |
|
1280 |
dm_free(vginfo); |
|
1281 |
return 0; |
|
1282 |
}
|
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1283 |
dm_list_iterate_items_safe(info2, info3, &primary_vginfo->infos) { |
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
1284 |
_vginfo_detach_info(info2); |
1.1.9
by James Westby
Import upstream version 2.02.39 |
1285 |
_vginfo_attach_info(orphan_vginfo, info2); |
1286 |
if (info2->mdas.n) |
|
1287 |
sprintf(mdabuf, " with %u mdas", |
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1288 |
dm_list_size(&info2->mdas)); |
1.1.9
by James Westby
Import upstream version 2.02.39 |
1289 |
else
|
1290 |
mdabuf[0] = '\0'; |
|
1291 |
log_debug("lvmcache: %s: now in VG %s%s%s%s%s", |
|
1292 |
dev_name(info2->dev), |
|
1293 |
vgname, orphan_vginfo->vgid[0] ? " (" : "", |
|
1294 |
orphan_vginfo->vgid[0] ? orphan_vginfo->vgid : "", |
|
1295 |
orphan_vginfo->vgid[0] ? ")" : "", mdabuf); |
|
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
1296 |
}
|
1297 |
||
1298 |
if (!_drop_vginfo(NULL, primary_vginfo)) |
|
1299 |
return_0; |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1300 |
}
|
1301 |
||
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1302 |
if (!_insert_vginfo(vginfo, vgid, vgstatus, creation_host, |
1303 |
primary_vginfo)) { |
|
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
1304 |
dm_free(vginfo->vgname); |
1305 |
dm_free(vginfo); |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1306 |
return 0; |
1307 |
}
|
|
1308 |
/* Ensure orphans appear last on list_iterate */
|
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1309 |
if (is_orphan_vg(vgname)) |
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1310 |
dm_list_add(&_vginfos, &vginfo->list); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1311 |
else
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1312 |
dm_list_add_h(&_vginfos, &vginfo->list); |
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1313 |
/***
|
1314 |
}
|
|
1315 |
***/
|
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1316 |
}
|
1317 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
1318 |
if (info) |
1319 |
_vginfo_attach_info(vginfo, info); |
|
1320 |
else if (!_lvmcache_update_vgid(NULL, vginfo, vgid)) /* Orphans */ |
|
1321 |
return_0; |
|
1322 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
1323 |
_update_cache_vginfo_lock_state(vginfo, lvmcache_vgname_is_locked(vgname)); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1324 |
|
1325 |
/* FIXME Check consistency of list! */
|
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1326 |
vginfo->fmt = fmt; |
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1327 |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1328 |
if (info) { |
1329 |
if (info->mdas.n) |
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1330 |
sprintf(mdabuf, " with %u mdas", dm_list_size(&info->mdas)); |
1.1.9
by James Westby
Import upstream version 2.02.39 |
1331 |
else
|
1332 |
mdabuf[0] = '\0'; |
|
1333 |
log_debug("lvmcache: %s: now in VG %s%s%s%s%s", |
|
1334 |
dev_name(info->dev), |
|
1335 |
vgname, vginfo->vgid[0] ? " (" : "", |
|
1336 |
vginfo->vgid[0] ? vginfo->vgid : "", |
|
1337 |
vginfo->vgid[0] ? ")" : "", mdabuf); |
|
1338 |
} else |
|
1339 |
log_debug("lvmcache: initialised VG %s", vgname); |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1340 |
|
1341 |
return 1; |
|
1342 |
}
|
|
1343 |
||
1344 |
static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstatus, |
|
1345 |
const char *creation_host) |
|
1346 |
{
|
|
1347 |
if (!info || !info->vginfo) |
|
1348 |
return 1; |
|
1349 |
||
1350 |
if ((info->vginfo->status & EXPORTED_VG) != (vgstatus & EXPORTED_VG)) |
|
1351 |
log_debug("lvmcache: %s: VG %s %s exported", |
|
1352 |
dev_name(info->dev), info->vginfo->vgname, |
|
1353 |
vgstatus & EXPORTED_VG ? "now" : "no longer"); |
|
1354 |
||
1355 |
info->vginfo->status = vgstatus; |
|
1356 |
||
1357 |
if (!creation_host) |
|
1358 |
return 1; |
|
1359 |
||
1360 |
if (info->vginfo->creation_host && !strcmp(creation_host, |
|
1361 |
info->vginfo->creation_host)) |
|
1362 |
return 1; |
|
1363 |
||
1364 |
if (info->vginfo->creation_host) |
|
1365 |
dm_free(info->vginfo->creation_host); |
|
1366 |
||
1367 |
if (!(info->vginfo->creation_host = dm_strdup(creation_host))) { |
|
1368 |
log_error("cache creation host alloc failed for %s", |
|
1369 |
creation_host); |
|
1370 |
return 0; |
|
1371 |
}
|
|
1372 |
||
1373 |
log_debug("lvmcache: %s: VG %s: Set creation host to %s.", |
|
1374 |
dev_name(info->dev), info->vginfo->vgname, creation_host); |
|
1375 |
||
1376 |
return 1; |
|
1377 |
}
|
|
1378 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
1379 |
int lvmcache_add_orphan_vginfo(const char *vgname, struct format_type *fmt) |
1380 |
{
|
|
1381 |
if (!_lock_hash && !lvmcache_init()) { |
|
1382 |
log_error("Internal cache initialisation failed"); |
|
1383 |
return 0; |
|
1384 |
}
|
|
1385 |
||
1386 |
return _lvmcache_update_vgname(NULL, vgname, vgname, 0, "", fmt); |
|
1387 |
}
|
|
1388 |
||
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1389 |
int lvmcache_update_vgname_and_id(struct lvmcache_info *info, |
1390 |
const char *vgname, const char *vgid, |
|
1391 |
uint32_t vgstatus, const char *creation_host) |
|
1392 |
{
|
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1393 |
if (!vgname && !info->vginfo) { |
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
1394 |
log_error(INTERNAL_ERROR "NULL vgname handed to cache"); |
1.1.9
by James Westby
Import upstream version 2.02.39 |
1395 |
/* FIXME Remove this */
|
1396 |
vgname = info->fmt->orphan_vg_name; |
|
1397 |
vgid = vgname; |
|
1398 |
}
|
|
1399 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
1400 |
/* When using lvmetad, the PV could not have become orphaned. */
|
1401 |
if (lvmetad_active() && is_orphan_vg(vgname) && info->vginfo) |
|
1402 |
return 1; |
|
1403 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
1404 |
/* If PV without mdas is already in a real VG, don't make it orphan */
|
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
1405 |
if (is_orphan_vg(vgname) && info->vginfo && |
1406 |
mdas_empty_or_ignored(&info->mdas) && |
|
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
1407 |
!is_orphan_vg(info->vginfo->vgname) && critical_section()) |
1.1.9
by James Westby
Import upstream version 2.02.39 |
1408 |
return 1; |
1409 |
||
1410 |
/* If moving PV from orphan to real VG, always mark it valid */
|
|
1411 |
if (!is_orphan_vg(vgname)) |
|
1412 |
info->status &= ~CACHE_INVALID; |
|
1413 |
||
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1414 |
if (!_lvmcache_update_vgname(info, vgname, vgid, vgstatus, |
1.1.9
by James Westby
Import upstream version 2.02.39 |
1415 |
creation_host, info->fmt) || |
1416 |
!_lvmcache_update_vgid(info, info->vginfo, vgid) || |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1417 |
!_lvmcache_update_vgstatus(info, vgstatus, creation_host)) |
1418 |
return_0; |
|
1.1.3
by Fabio M. Di Nitto
Import upstream version 2.01.14 |
1419 |
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1420 |
return 1; |
1421 |
}
|
|
1422 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
1423 |
int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted) |
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1424 |
{
|
1.1.3
by Fabio M. Di Nitto
Import upstream version 2.01.14 |
1425 |
struct pv_list *pvl; |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1426 |
struct lvmcache_info *info; |
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
1427 |
char pvid_s[ID_LEN + 1] __attribute__((aligned(8))); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1428 |
|
1429 |
pvid_s[sizeof(pvid_s) - 1] = '\0'; |
|
1430 |
||
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1431 |
dm_list_iterate_items(pvl, &vg->pvs) { |
1.1.3
by Fabio M. Di Nitto
Import upstream version 2.01.14 |
1432 |
strncpy(pvid_s, (char *) &pvl->pv->id, sizeof(pvid_s) - 1); |
1433 |
/* FIXME Could pvl->pv->dev->pvid ever be different? */
|
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
1434 |
if ((info = lvmcache_info_from_pvid(pvid_s, 0)) && |
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1435 |
!lvmcache_update_vgname_and_id(info, vg->name, |
1436 |
(char *) &vg->id, |
|
1437 |
vg->status, NULL)) |
|
1438 |
return_0; |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1439 |
}
|
1440 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
1441 |
/* store text representation of vg to cache */
|
1.2.2
by Bastian Blank
Import upstream version 2.02.51 |
1442 |
if (vg->cmd->current_settings.cache_vgmetadata) |
1443 |
_store_metadata(vg, precommitted); |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1444 |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1445 |
return 1; |
1446 |
}
|
|
1447 |
||
1448 |
struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid, |
|
1449 |
struct device *dev, |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1450 |
const char *vgname, const char *vgid, |
1451 |
uint32_t vgstatus) |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1452 |
{
|
1453 |
struct label *label; |
|
1454 |
struct lvmcache_info *existing, *info; |
|
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
1455 |
char pvid_s[ID_LEN + 1] __attribute__((aligned(8))); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1456 |
|
1457 |
if (!_vgname_hash && !lvmcache_init()) { |
|
1458 |
log_error("Internal cache initialisation failed"); |
|
1459 |
return NULL; |
|
1460 |
}
|
|
1461 |
||
1.2.10
by Bastian Blank
Import upstream version 2.02.86 |
1462 |
strncpy(pvid_s, pvid, sizeof(pvid_s) - 1); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1463 |
pvid_s[sizeof(pvid_s) - 1] = '\0'; |
1464 |
||
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
1465 |
if (!(existing = lvmcache_info_from_pvid(pvid_s, 0)) && |
1466 |
!(existing = lvmcache_info_from_pvid(dev->pvid, 0))) { |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1467 |
if (!(label = label_create(labeller))) |
1468 |
return_NULL; |
|
1.2.9
by Bastian Blank
Import upstream version 2.02.84 |
1469 |
if (!(info = dm_zalloc(sizeof(*info)))) { |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1470 |
log_error("lvmcache_info allocation failed"); |
1471 |
label_destroy(label); |
|
1472 |
return NULL; |
|
1473 |
}
|
|
1474 |
||
1475 |
label->info = info; |
|
1476 |
info->label = label; |
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1477 |
dm_list_init(&info->list); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1478 |
info->dev = dev; |
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
1479 |
|
1480 |
lvmcache_del_mdas(info); |
|
1481 |
lvmcache_del_das(info); |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1482 |
} else { |
1483 |
if (existing->dev != dev) { |
|
1484 |
/* Is the existing entry a duplicate pvid e.g. md ? */
|
|
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
1485 |
if (dev_subsystem_part_major(existing->dev) && |
1486 |
!dev_subsystem_part_major(dev)) { |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1487 |
log_very_verbose("Ignoring duplicate PV %s on " |
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
1488 |
"%s - using %s %s", |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1489 |
pvid, dev_name(dev), |
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
1490 |
dev_subsystem_name(existing->dev), |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1491 |
dev_name(existing->dev)); |
1492 |
return NULL; |
|
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
1493 |
} else if (dm_is_dm_major(MAJOR(existing->dev->dev)) && |
1494 |
!dm_is_dm_major(MAJOR(dev->dev))) { |
|
1.1.4
by Matthias Klose
Import upstream version 2.01.15 |
1495 |
log_very_verbose("Ignoring duplicate PV %s on " |
1496 |
"%s - using dm %s", |
|
1497 |
pvid, dev_name(dev), |
|
1498 |
dev_name(existing->dev)); |
|
1499 |
return NULL; |
|
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
1500 |
} else if (!dev_subsystem_part_major(existing->dev) && |
1501 |
dev_subsystem_part_major(dev)) |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1502 |
log_very_verbose("Duplicate PV %s on %s - " |
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
1503 |
"using %s %s", pvid, |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1504 |
dev_name(existing->dev), |
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
1505 |
dev_subsystem_name(existing->dev), |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1506 |
dev_name(dev)); |
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
1507 |
else if (!dm_is_dm_major(MAJOR(existing->dev->dev)) && |
1508 |
dm_is_dm_major(MAJOR(dev->dev))) |
|
1.1.4
by Matthias Klose
Import upstream version 2.01.15 |
1509 |
log_very_verbose("Duplicate PV %s on %s - " |
1510 |
"using dm %s", pvid, |
|
1511 |
dev_name(existing->dev), |
|
1512 |
dev_name(dev)); |
|
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
1513 |
/* FIXME If both dm, check dependencies */
|
1514 |
//else if (dm_is_dm_major(MAJOR(existing->dev->dev)) &&
|
|
1515 |
//dm_is_dm_major(MAJOR(dev->dev)))
|
|
1516 |
//
|
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1517 |
else if (!strcmp(pvid_s, existing->dev->pvid)) |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1518 |
log_error("Found duplicate PV %s: using %s not " |
1519 |
"%s", pvid, dev_name(dev), |
|
1520 |
dev_name(existing->dev)); |
|
1521 |
}
|
|
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1522 |
if (strcmp(pvid_s, existing->dev->pvid)) |
1523 |
log_debug("Updating pvid cache to %s (%s) from %s (%s)", |
|
1524 |
pvid_s, dev_name(dev), |
|
1525 |
existing->dev->pvid, dev_name(existing->dev)); |
|
1.1.4
by Matthias Klose
Import upstream version 2.01.15 |
1526 |
/* Switch over to new preferred device */
|
1527 |
existing->dev = dev; |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1528 |
info = existing; |
1529 |
/* Has labeller changed? */
|
|
1530 |
if (info->label->labeller != labeller) { |
|
1531 |
label_destroy(info->label); |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1532 |
if (!(info->label = label_create(labeller))) |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1533 |
/* FIXME leaves info without label! */
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1534 |
return_NULL; |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1535 |
info->label->info = info; |
1536 |
}
|
|
1537 |
label = info->label; |
|
1538 |
}
|
|
1539 |
||
1540 |
info->fmt = (const struct format_type *) labeller->private; |
|
1541 |
info->status |= CACHE_INVALID; |
|
1542 |
||
1543 |
if (!_lvmcache_update_pvid(info, pvid_s)) { |
|
1544 |
if (!existing) { |
|
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
1545 |
dm_free(info); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1546 |
label_destroy(label); |
1547 |
}
|
|
1548 |
return NULL; |
|
1549 |
}
|
|
1550 |
||
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1551 |
if (!lvmcache_update_vgname_and_id(info, vgname, vgid, vgstatus, NULL)) { |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1552 |
if (!existing) { |
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
1553 |
dm_hash_remove(_pvid_hash, pvid_s); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1554 |
strcpy(info->dev->pvid, ""); |
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
1555 |
dm_free(info); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1556 |
label_destroy(label); |
1557 |
}
|
|
1558 |
return NULL; |
|
1559 |
}
|
|
1560 |
||
1561 |
return info; |
|
1562 |
}
|
|
1563 |
||
1564 |
static void _lvmcache_destroy_entry(struct lvmcache_info *info) |
|
1565 |
{
|
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1566 |
_vginfo_detach_info(info); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1567 |
strcpy(info->dev->pvid, ""); |
1568 |
label_destroy(info->label); |
|
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
1569 |
dm_free(info); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1570 |
}
|
1571 |
||
1572 |
static void _lvmcache_destroy_vgnamelist(struct lvmcache_vginfo *vginfo) |
|
1573 |
{
|
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1574 |
struct lvmcache_vginfo *next; |
1575 |
||
1576 |
do { |
|
1577 |
next = vginfo->next; |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1578 |
if (!_free_vginfo(vginfo)) |
1579 |
stack; |
|
1.1.6
by Michael Vogt
Import upstream version 2.02.06 |
1580 |
} while ((vginfo = next)); |
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1581 |
}
|
1582 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
1583 |
static void _lvmcache_destroy_lockname(struct dm_hash_node *n) |
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1584 |
{
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1585 |
char *vgname; |
1586 |
||
1587 |
if (!dm_hash_get_data(_lock_hash, n)) |
|
1588 |
return; |
|
1589 |
||
1590 |
vgname = dm_hash_get_key(_lock_hash, n); |
|
1591 |
||
1592 |
if (!strcmp(vgname, VG_GLOBAL)) |
|
1593 |
_vg_global_lock_held = 1; |
|
1594 |
else
|
|
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
1595 |
log_error(INTERNAL_ERROR "Volume Group %s was not unlocked", |
1.1.9
by James Westby
Import upstream version 2.02.39 |
1596 |
dm_hash_get_key(_lock_hash, n)); |
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1597 |
}
|
1598 |
||
1.1.9
by James Westby
Import upstream version 2.02.39 |
1599 |
void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans) |
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1600 |
{
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1601 |
struct dm_hash_node *n; |
1.1.3
by Fabio M. Di Nitto
Import upstream version 2.01.14 |
1602 |
log_verbose("Wiping internal VG cache"); |
1603 |
||
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1604 |
_has_scanned = 0; |
1605 |
||
1606 |
if (_vgid_hash) { |
|
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
1607 |
dm_hash_destroy(_vgid_hash); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1608 |
_vgid_hash = NULL; |
1609 |
}
|
|
1610 |
||
1611 |
if (_pvid_hash) { |
|
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
1612 |
dm_hash_iter(_pvid_hash, (dm_hash_iterate_fn) _lvmcache_destroy_entry); |
1613 |
dm_hash_destroy(_pvid_hash); |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1614 |
_pvid_hash = NULL; |
1615 |
}
|
|
1616 |
||
1617 |
if (_vgname_hash) { |
|
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
1618 |
dm_hash_iter(_vgname_hash, |
1619 |
(dm_hash_iterate_fn) _lvmcache_destroy_vgnamelist); |
|
1620 |
dm_hash_destroy(_vgname_hash); |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1621 |
_vgname_hash = NULL; |
1622 |
}
|
|
1623 |
||
1624 |
if (_lock_hash) { |
|
1.1.9
by James Westby
Import upstream version 2.02.39 |
1625 |
dm_hash_iterate(n, _lock_hash) |
1626 |
_lvmcache_destroy_lockname(n); |
|
1.1.5
by Michael Vogt
Import upstream version 2.02.02 |
1627 |
dm_hash_destroy(_lock_hash); |
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1628 |
_lock_hash = NULL; |
1629 |
}
|
|
1630 |
||
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1631 |
if (!dm_list_empty(&_vginfos)) |
1.2.6
by Bastian Blank
Import upstream version 2.02.62 |
1632 |
log_error(INTERNAL_ERROR "_vginfos list should be empty"); |
1.2.1
by Bastian Blank
Import upstream version 2.02.44 |
1633 |
dm_list_init(&_vginfos); |
1.1.9
by James Westby
Import upstream version 2.02.39 |
1634 |
|
1635 |
if (retain_orphans) |
|
1.2.12
by Bastian Blank
Import upstream version 2.02.95 |
1636 |
if (!init_lvmcache_orphans(cmd)) |
1637 |
stack; |
|
1638 |
}
|
|
1639 |
||
1640 |
int lvmcache_pvid_is_locked(const char *pvid) { |
|
1641 |
struct lvmcache_info *info; |
|
1642 |
info = lvmcache_info_from_pvid(pvid, 0); |
|
1643 |
if (!info || !info->vginfo) |
|
1644 |
return 0; |
|
1645 |
||
1646 |
return lvmcache_vgname_is_locked(info->vginfo->vgname); |
|
1647 |
}
|
|
1648 |
||
1649 |
int lvmcache_fid_add_mdas(struct lvmcache_info *info, struct format_instance *fid, |
|
1650 |
const char *id, int id_len) |
|
1651 |
{
|
|
1652 |
return fid_add_mdas(fid, &info->mdas, id, id_len); |
|
1653 |
}
|
|
1654 |
||
1655 |
int lvmcache_fid_add_mdas_pv(struct lvmcache_info *info, struct format_instance *fid) |
|
1656 |
{
|
|
1657 |
return lvmcache_fid_add_mdas(info, fid, info->dev->pvid, ID_LEN); |
|
1658 |
}
|
|
1659 |
||
1660 |
int lvmcache_fid_add_mdas_vg(struct lvmcache_vginfo *vginfo, struct format_instance *fid) |
|
1661 |
{
|
|
1662 |
struct lvmcache_info *info; |
|
1663 |
dm_list_iterate_items(info, &vginfo->infos) { |
|
1664 |
if (!lvmcache_fid_add_mdas_pv(info, fid)) |
|
1665 |
return_0; |
|
1666 |
}
|
|
1667 |
return 1; |
|
1668 |
}
|
|
1669 |
||
1670 |
static int _get_pv_if_in_vg(struct lvmcache_info *info, |
|
1671 |
struct physical_volume *pv) |
|
1672 |
{
|
|
1673 |
char vgname[NAME_LEN + 1]; |
|
1674 |
char vgid[ID_LEN + 1]; |
|
1675 |
||
1676 |
if (info->vginfo && info->vginfo->vgname && |
|
1677 |
!is_orphan_vg(info->vginfo->vgname)) { |
|
1678 |
/*
|
|
1679 |
* get_pv_from_vg_by_id() may call
|
|
1680 |
* lvmcache_label_scan() and drop cached
|
|
1681 |
* vginfo so make a local copy of string.
|
|
1682 |
*/
|
|
1683 |
strcpy(vgname, info->vginfo->vgname); |
|
1684 |
memcpy(vgid, info->vginfo->vgid, sizeof(vgid)); |
|
1685 |
||
1686 |
if (get_pv_from_vg_by_id(info->fmt, vgname, vgid, |
|
1687 |
info->dev->pvid, pv)) |
|
1688 |
return 1; |
|
1689 |
}
|
|
1690 |
||
1691 |
return 0; |
|
1692 |
}
|
|
1693 |
||
1694 |
int lvmcache_populate_pv_fields(struct lvmcache_info *info, |
|
1695 |
struct physical_volume *pv, |
|
1696 |
int scan_label_only) |
|
1697 |
{
|
|
1698 |
struct data_area_list *da; |
|
1699 |
||
1700 |
/* Have we already cached vgname? */
|
|
1701 |
if (!scan_label_only && _get_pv_if_in_vg(info, pv)) |
|
1702 |
return 1; |
|
1703 |
||
1704 |
/* Perform full scan (just the first time) and try again */
|
|
1705 |
if (!scan_label_only && !critical_section() && !full_scan_done()) { |
|
1706 |
lvmcache_label_scan(info->fmt->cmd, 2); |
|
1707 |
||
1708 |
if (_get_pv_if_in_vg(info, pv)) |
|
1709 |
return 1; |
|
1710 |
}
|
|
1711 |
||
1712 |
/* Orphan */
|
|
1713 |
pv->dev = info->dev; |
|
1714 |
pv->fmt = info->fmt; |
|
1715 |
pv->size = info->device_size >> SECTOR_SHIFT; |
|
1716 |
pv->vg_name = FMT_TEXT_ORPHAN_VG_NAME; |
|
1717 |
memcpy(&pv->id, &info->dev->pvid, sizeof(pv->id)); |
|
1718 |
||
1719 |
/* Currently only support exactly one data area */
|
|
1720 |
if (dm_list_size(&info->das) != 1) { |
|
1721 |
log_error("Must be exactly one data area (found %d) on PV %s", |
|
1722 |
dm_list_size(&info->das), dev_name(info->dev)); |
|
1723 |
return 0; |
|
1724 |
}
|
|
1725 |
||
1726 |
dm_list_iterate_items(da, &info->das) |
|
1727 |
pv->pe_start = da->disk_locn.offset >> SECTOR_SHIFT; |
|
1728 |
||
1729 |
return 1; |
|
1730 |
}
|
|
1731 |
||
1732 |
int lvmcache_check_format(struct lvmcache_info *info, const struct format_type *fmt) |
|
1733 |
{
|
|
1734 |
if (info->fmt != fmt) { |
|
1735 |
log_error("PV %s is a different format (seqno %s)", |
|
1736 |
dev_name(info->dev), info->fmt->name); |
|
1737 |
return 0; |
|
1738 |
}
|
|
1739 |
return 1; |
|
1740 |
}
|
|
1741 |
||
1742 |
void lvmcache_del_mdas(struct lvmcache_info *info) |
|
1743 |
{
|
|
1744 |
if (info->mdas.n) |
|
1745 |
del_mdas(&info->mdas); |
|
1746 |
dm_list_init(&info->mdas); |
|
1747 |
}
|
|
1748 |
||
1749 |
void lvmcache_del_das(struct lvmcache_info *info) |
|
1750 |
{
|
|
1751 |
if (info->das.n) |
|
1752 |
del_das(&info->das); |
|
1753 |
dm_list_init(&info->das); |
|
1754 |
}
|
|
1755 |
||
1756 |
int lvmcache_add_mda(struct lvmcache_info *info, struct device *dev, |
|
1757 |
uint64_t start, uint64_t size, unsigned ignored) |
|
1758 |
{
|
|
1759 |
return add_mda(info->fmt, NULL, &info->mdas, dev, start, size, ignored); |
|
1760 |
}
|
|
1761 |
||
1762 |
int lvmcache_add_da(struct lvmcache_info *info, uint64_t start, uint64_t size) |
|
1763 |
{
|
|
1764 |
return add_da(NULL, &info->das, start, size); |
|
1765 |
}
|
|
1766 |
||
1767 |
||
1768 |
void lvmcache_update_pv(struct lvmcache_info *info, struct physical_volume *pv, |
|
1769 |
const struct format_type *fmt) |
|
1770 |
{
|
|
1771 |
info->device_size = pv->size << SECTOR_SHIFT; |
|
1772 |
info->fmt = fmt; |
|
1773 |
}
|
|
1774 |
||
1775 |
int lvmcache_update_das(struct lvmcache_info *info, struct physical_volume *pv) |
|
1776 |
{
|
|
1777 |
struct data_area_list *da; |
|
1778 |
if (info->das.n) { |
|
1779 |
if (!pv->pe_start) |
|
1780 |
dm_list_iterate_items(da, &info->das) |
|
1781 |
pv->pe_start = da->disk_locn.offset >> SECTOR_SHIFT; |
|
1782 |
del_das(&info->das); |
|
1783 |
} else |
|
1784 |
dm_list_init(&info->das); |
|
1785 |
||
1786 |
if (!add_da(NULL, &info->das, pv->pe_start << SECTOR_SHIFT, 0 /*pv->size << SECTOR_SHIFT*/)) |
|
1787 |
return_0; |
|
1788 |
||
1789 |
return 1; |
|
1790 |
}
|
|
1791 |
||
1792 |
int lvmcache_foreach_pv(struct lvmcache_vginfo *vginfo, |
|
1793 |
int (*fun)(struct lvmcache_info *, void *), |
|
1794 |
void *baton) |
|
1795 |
{
|
|
1796 |
struct lvmcache_info *info; |
|
1797 |
dm_list_iterate_items(info, &vginfo->infos) { |
|
1798 |
if (!fun(info, baton)) |
|
1799 |
return_0; |
|
1800 |
}
|
|
1801 |
||
1802 |
return 1; |
|
1803 |
}
|
|
1804 |
||
1805 |
int lvmcache_foreach_mda(struct lvmcache_info *info, |
|
1806 |
int (*fun)(struct metadata_area *, void *), |
|
1807 |
void *baton) |
|
1808 |
{
|
|
1809 |
struct metadata_area *mda; |
|
1810 |
dm_list_iterate_items(mda, &info->mdas) { |
|
1811 |
if (!fun(mda, baton)) |
|
1812 |
return_0; |
|
1813 |
}
|
|
1814 |
||
1815 |
return 1; |
|
1816 |
}
|
|
1817 |
||
1818 |
int lvmcache_mda_count(struct lvmcache_info *info) |
|
1819 |
{
|
|
1820 |
return dm_list_size(&info->mdas); |
|
1821 |
}
|
|
1822 |
||
1823 |
int lvmcache_foreach_da(struct lvmcache_info *info, |
|
1824 |
int (*fun)(struct disk_locn *, void *), |
|
1825 |
void *baton) |
|
1826 |
{
|
|
1827 |
struct data_area_list *da; |
|
1828 |
dm_list_iterate_items(da, &info->das) { |
|
1829 |
if (!fun(&da->disk_locn, baton)) |
|
1830 |
return_0; |
|
1831 |
}
|
|
1832 |
||
1833 |
return 1; |
|
1834 |
}
|
|
1835 |
||
1836 |
/*
|
|
1837 |
* The lifetime of the label returned is tied to the lifetime of the
|
|
1838 |
* lvmcache_info which is the same as lvmcache itself.
|
|
1839 |
*/
|
|
1840 |
struct label *lvmcache_get_label(struct lvmcache_info *info) { |
|
1841 |
return info->label; |
|
1842 |
}
|
|
1843 |
||
1844 |
void lvmcache_make_valid(struct lvmcache_info *info) { |
|
1845 |
info->status &= ~CACHE_INVALID; |
|
1846 |
}
|
|
1847 |
||
1848 |
uint64_t lvmcache_device_size(struct lvmcache_info *info) { |
|
1849 |
return info->device_size; |
|
1850 |
}
|
|
1851 |
||
1852 |
void lvmcache_set_device_size(struct lvmcache_info *info, uint64_t size) { |
|
1853 |
info->device_size = size; |
|
1854 |
}
|
|
1855 |
||
1856 |
struct device *lvmcache_device(struct lvmcache_info *info) { |
|
1857 |
return info->dev; |
|
1858 |
}
|
|
1859 |
||
1860 |
int lvmcache_is_orphan(struct lvmcache_info *info) { |
|
1861 |
if (!info->vginfo) |
|
1862 |
return 1; /* FIXME? */ |
|
1863 |
return is_orphan_vg(info->vginfo->vgname); |
|
1864 |
}
|
|
1865 |
||
1866 |
int lvmcache_vgid_is_cached(const char *vgid) { |
|
1867 |
struct lvmcache_vginfo *vginfo; |
|
1868 |
||
1869 |
if (lvmetad_active()) |
|
1870 |
return 1; |
|
1871 |
||
1872 |
vginfo = lvmcache_vginfo_from_vgid(vgid); |
|
1873 |
||
1874 |
if (!vginfo || !vginfo->vgname) |
|
1875 |
return 0; |
|
1876 |
||
1877 |
if (is_orphan_vg(vginfo->vgname)) |
|
1878 |
return 0; |
|
1879 |
||
1880 |
return 1; |
|
1881 |
}
|
|
1882 |
||
1883 |
/*
|
|
1884 |
* Return true iff it is impossible to find out from this info alone whether the
|
|
1885 |
* PV in question is or is not an orphan.
|
|
1886 |
*/
|
|
1887 |
int lvmcache_uncertain_ownership(struct lvmcache_info *info) { |
|
1888 |
return mdas_empty_or_ignored(&info->mdas); |
|
1889 |
}
|
|
1890 |
||
1891 |
int lvmcache_smallest_mda_size(struct lvmcache_info *info) |
|
1892 |
{
|
|
1893 |
return find_min_mda_size(&info->mdas); |
|
1894 |
}
|
|
1895 |
||
1896 |
const struct format_type *lvmcache_fmt(struct lvmcache_info *info) { |
|
1897 |
return info->fmt; |
|
1
by Patrick Caulfield
Import upstream version 2.00.25 |
1898 |
}
|