~brightbox/ubuntu/raring/lvm2/fix-for-1076304

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
}