]> sourceware.org Git - lvm2.git/blame - lib/format1/format1.c
thin: fix recent commits
[lvm2.git] / lib / format1 / format1.c
CommitLineData
3840b20a 1/*
67cdbd7e 2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
ee54e437 3 * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
3840b20a 4 *
6606c3ae
AK
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
be684599 9 * of the GNU Lesser General Public License v.2.1.
6606c3ae 10 *
be684599 11 * You should have received a copy of the GNU Lesser General Public License
6606c3ae
AK
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
3840b20a
JT
14 */
15
d1d9800e 16#include "lib.h"
3840b20a 17#include "disk-rep.h"
df89b641 18#include "limits.h"
aa290eb2 19#include "display.h"
60274aba 20#include "toolcontext.h"
d1d9800e
AK
21#include "lvm1-label.h"
22#include "format1.h"
c4ddb31a 23#include "segtype.h"
980d2d86 24#include "pv_alloc.h"
3840b20a 25
a381c45a 26/* VG consistency checks */
980d2d86 27static int _check_vgs(struct dm_list *pvs, struct volume_group *vg)
3840b20a 28{
2c44337b 29 struct dm_list *pvh, *t;
3cfae6cf 30 struct disk_list *dl = NULL;
a381c45a
AK
31 struct disk_list *first = NULL;
32
8ef2b021
AK
33 uint32_t pv_count = 0;
34 uint32_t exported = 0;
35 int first_time = 1;
f53c6aa6 36
f53c6aa6
AK
37 /*
38 * If there are exported and unexported PVs, ignore exported ones.
39 * This means an active VG won't be affected if disks are inserted
40 * bearing an exported VG with the same name.
7d68b080 41 */
2c44337b 42 dm_list_iterate_items(dl, pvs) {
8ef2b021 43 if (first_time) {
f53c6aa6 44 exported = dl->pvd.pv_status & VG_EXPORTED;
8ef2b021 45 first_time = 0;
f53c6aa6
AK
46 continue;
47 }
48
49 if (exported != (dl->pvd.pv_status & VG_EXPORTED)) {
50 /* Remove exported PVs */
2c44337b
AK
51 dm_list_iterate_safe(pvh, t, pvs) {
52 dl = dm_list_item(pvh, struct disk_list);
f53c6aa6 53 if (dl->pvd.pv_status & VG_EXPORTED)
2c44337b 54 dm_list_del(pvh);
f53c6aa6
AK
55 }
56 break;
57 }
58 }
59
f53c6aa6 60 /* Remove any PVs with VG structs that differ from the first */
2c44337b
AK
61 dm_list_iterate_safe(pvh, t, pvs) {
62 dl = dm_list_item(pvh, struct disk_list);
f53c6aa6 63
83545752 64 if (!first)
a381c45a 65 first = dl;
2107f482 66
0a5e4a14 67 else if (memcmp(&first->vgd, &dl->vgd, sizeof(first->vgd))) {
1176eb25
AK
68 log_error("VG data differs between PVs %s and %s",
69 dev_name(first->dev), dev_name(dl->dev));
397b239b
AK
70 log_debug("VG data on %s: %s %s %" PRIu32 " %" PRIu32
71 " %" PRIu32 " %" PRIu32 " %" PRIu32 " %"
72 PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32
73 " %" PRIu32 " %" PRIu32 " %" PRIu32 " %"
74 PRIu32 " %" PRIu32 " %" PRIu32,
75 dev_name(first->dev), first->vgd.vg_uuid,
76 first->vgd.vg_name_dummy,
77 first->vgd.vg_number, first->vgd.vg_access,
78 first->vgd.vg_status, first->vgd.lv_max,
79 first->vgd.lv_cur, first->vgd.lv_open,
80 first->vgd.pv_max, first->vgd.pv_cur,
81 first->vgd.pv_act, first->vgd.dummy,
82 first->vgd.vgda, first->vgd.pe_size,
83 first->vgd.pe_total, first->vgd.pe_allocated,
84 first->vgd.pvg_total);
85 log_debug("VG data on %s: %s %s %" PRIu32 " %" PRIu32
86 " %" PRIu32 " %" PRIu32 " %" PRIu32 " %"
87 PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32
88 " %" PRIu32 " %" PRIu32 " %" PRIu32 " %"
89 PRIu32 " %" PRIu32 " %" PRIu32,
90 dev_name(dl->dev), dl->vgd.vg_uuid,
91 dl->vgd.vg_name_dummy, dl->vgd.vg_number,
92 dl->vgd.vg_access, dl->vgd.vg_status,
93 dl->vgd.lv_max, dl->vgd.lv_cur,
94 dl->vgd.lv_open, dl->vgd.pv_max,
95 dl->vgd.pv_cur, dl->vgd.pv_act, dl->vgd.dummy,
96 dl->vgd.vgda, dl->vgd.pe_size,
97 dl->vgd.pe_total, dl->vgd.pe_allocated,
98 dl->vgd.pvg_total);
2c44337b 99 dm_list_del(pvh);
3840b20a
JT
100 return 0;
101 }
a381c45a
AK
102 pv_count++;
103 }
104
105 /* On entry to fn, list known to be non-empty */
4c22730b 106 if (pv_count != first->vgd.pv_cur) {
f53c6aa6 107 log_error("%d PV(s) found for VG %s: expected %d",
4c22730b 108 pv_count, first->pvd.vg_name, first->vgd.pv_cur);
980d2d86 109 vg->status |= PARTIAL_VG;
3840b20a
JT
110 }
111
3840b20a
JT
112 return 1;
113}
114
980d2d86
MB
115static int _fix_partial_vg(struct volume_group *vg, struct dm_list *pvs)
116{
117 uint32_t extent_count = 0;
118 struct disk_list *dl;
119 struct dm_list *pvh;
120 struct pv_list *pvl;
b0485a99
MB
121 struct lv_list *ll;
122 struct lv_segment *seg;
123
124 /*
125 * FIXME: code should remap missing segments to error segment.
126 * Also current mapping code allocates 1 segment per missing extent.
127 * For now bail out completely - allocated structures are not complete
128 */
129 dm_list_iterate_items(ll, &vg->lvs)
130 dm_list_iterate_items(seg, &ll->lv->segments) {
131
132 /* area_count is always 1 here, s == 0 */
133 if (seg_type(seg, 0) != AREA_PV)
134 continue;
135
136 if (seg_pv(seg, 0))
137 continue;
138
139 log_error("Partial mode support for missing lvm1 PVs and "
140 "partially available LVs is currently not implemented.");
141 return 0;
142 }
980d2d86
MB
143
144 dm_list_iterate(pvh, pvs) {
145 dl = dm_list_item(pvh, struct disk_list);
146 extent_count += dl->pvd.pe_total;
147 }
148
149 /* FIXME: move this to one place to pv_manip */
150 if (!(pvl = dm_pool_zalloc(vg->vgmem, sizeof(*pvl))) ||
151 !(pvl->pv = dm_pool_zalloc(vg->vgmem, sizeof(*pvl->pv))))
152 return_0;
153
b0485a99
MB
154 /* Use vg uuid with replaced first chars to "missing" as missing PV UUID */
155 memcpy(&pvl->pv->id.uuid, vg->id.uuid, sizeof(pvl->pv->id.uuid));
156 memcpy(&pvl->pv->id.uuid, "missing", 7);
157
980d2d86
MB
158 if (!(pvl->pv->vg_name = dm_pool_strdup(vg->vgmem, vg->name)))
159 goto_out;
160 memcpy(&pvl->pv->vgid, &vg->id, sizeof(vg->id));
161 pvl->pv->status |= MISSING_PV;
162 dm_list_init(&pvl->pv->tags);
163 dm_list_init(&pvl->pv->segments);
164
165 pvl->pv->pe_size = vg->extent_size;
166 pvl->pv->pe_count = vg->extent_count - extent_count;
167 if (!alloc_pv_segment_whole_pv(vg->vgmem, pvl->pv))
168 goto_out;
169
170 add_pvl_to_vgs(vg, pvl);
171 log_debug("%s: partial VG, allocated missing PV using %d extents.",
172 vg->name, pvl->pv->pe_count);
173
174 return 1;
175out:
176 dm_pool_free(vg->vgmem, pvl);
177 return 0;
178}
179
3019419e
ZK
180static struct volume_group *_format1_vg_read(struct format_instance *fid,
181 const char *vg_name,
5b613cff
AK
182 struct metadata_area *mda __attribute__((unused)),
183 int single_device __attribute__((unused)))
3840b20a 184{
3019419e 185 struct volume_group *vg;
e15559aa 186 struct disk_list *dl;
3019419e
ZK
187 DM_LIST_INIT(pvs);
188
189 /* Strip dev_dir if present */
530efdb5
ZK
190 if (vg_name)
191 vg_name = strip_dir(vg_name, fid->fmt->cmd->dev_dir);
3019419e
ZK
192
193 if (!(vg = alloc_vg("format1_vg_read", fid->fmt->cmd, NULL)))
194 return_NULL;
e15559aa 195
3019419e
ZK
196 if (!read_pvs_in_vg(fid->fmt, vg_name, fid->fmt->cmd->filter,
197 vg->vgmem, &pvs))
4f2f566b 198 goto_bad;
3840b20a 199
3019419e 200 if (dm_list_empty(&pvs))
4f2f566b 201 goto_bad;
e15559aa 202
1307ddf4 203 vg_set_fid(vg, fid);
f5f84431 204
3019419e 205 if (!_check_vgs(&pvs, vg))
4f2f566b 206 goto_bad;
83545752 207
3019419e 208 dl = dm_list_item(pvs.n, struct disk_list);
f53c6aa6 209
3019419e 210 if (!import_vg(vg->vgmem, vg, dl))
4f2f566b 211 goto_bad;
3840b20a 212
3019419e 213 if (!import_pvs(fid->fmt, vg->vgmem, vg, &pvs))
4f2f566b 214 goto_bad;
3840b20a 215
3019419e 216 if (!import_lvs(vg->vgmem, vg, &pvs))
4f2f566b 217 goto_bad;
3840b20a 218
3019419e 219 if (!import_extents(fid->fmt->cmd, vg, &pvs))
4f2f566b 220 goto_bad;
812efa0f 221
3019419e 222 if (!import_snapshots(vg->vgmem, vg, &pvs))
4f2f566b 223 goto_bad;
0a9f8bcf 224
980d2d86 225 /* Fix extents counts by adding missing PV if partial VG */
3019419e 226 if ((vg->status & PARTIAL_VG) && !_fix_partial_vg(vg, &pvs))
980d2d86
MB
227 goto_bad;
228
3840b20a
JT
229 return vg;
230
8e1d5615 231bad:
874a4fd8 232 release_vg(vg);
3019419e 233
8e1d5615 234 return NULL;
3840b20a
JT
235}
236
a0313876 237static struct disk_list *_flatten_pv(struct format_instance *fid,
2262b320 238 struct dm_pool *mem, struct volume_group *vg,
83545752 239 struct physical_volume *pv,
5238b63f 240 const char *dev_dir)
df765ac1 241{
2262b320 242 struct disk_list *dl = dm_pool_alloc(mem, sizeof(*dl));
721128e8 243
c51b9fff
AK
244 if (!dl)
245 return_NULL;
87e8aeca
JT
246
247 dl->mem = mem;
248 dl->dev = pv->dev;
249
2c44337b
AK
250 dm_list_init(&dl->uuids);
251 dm_list_init(&dl->lvds);
87e8aeca 252
a0313876 253 if (!export_pv(fid->fmt->cmd, mem, vg, &dl->pvd, pv) ||
0a5e4a14 254 !export_vg(&dl->vgd, vg) ||
83545752 255 !export_uuids(dl, vg) ||
d1d9800e 256 !export_lvs(dl, vg, pv, dev_dir) || !calculate_layout(dl)) {
2262b320 257 dm_pool_free(mem, dl);
c51b9fff 258 return_NULL;
87e8aeca
JT
259 }
260
261 return dl;
df765ac1
JT
262}
263
2262b320 264static int _flatten_vg(struct format_instance *fid, struct dm_pool *mem,
25b73380 265 struct volume_group *vg,
2c44337b 266 struct dm_list *pvds, const char *dev_dir,
6b6a344e 267 struct dev_filter *filter)
df765ac1 268{
87e8aeca 269 struct pv_list *pvl;
df765ac1
JT
270 struct disk_list *data;
271
2c44337b 272 dm_list_iterate_items(pvl, &vg->pvs) {
c51b9fff
AK
273 if (!(data = _flatten_pv(fid, mem, vg, pvl->pv, dev_dir)))
274 return_0;
df765ac1 275
2c44337b 276 dm_list_add(pvds, &data->list);
df765ac1 277 }
ab47fb66 278
5238b63f
AK
279 export_numbers(pvds, vg);
280 export_pv_act(pvds);
ece1fe83 281
c51b9fff
AK
282 if (!export_vg_number(fid, pvds, vg->name, filter))
283 return_0;
6b6a344e 284
df765ac1
JT
285 return 1;
286}
287
8a2fc586 288static int _format1_vg_write(struct format_instance *fid, struct volume_group *vg,
08f1ddea 289 struct metadata_area *mda __attribute__((unused)))
df765ac1 290{
8e1d5615 291 struct dm_pool *mem = dm_pool_create("lvm1 vg_write", VG_MEMPOOL_CHUNK);
2c44337b 292 struct dm_list pvds;
df765ac1
JT
293 int r = 0;
294
c51b9fff
AK
295 if (!mem)
296 return_0;
df765ac1 297
2c44337b 298 dm_list_init(&pvds);
e3de4ba8 299
25b73380
AK
300 r = (_flatten_vg(fid, mem, vg, &pvds, fid->fmt->cmd->dev_dir,
301 fid->fmt->cmd->filter) &&
302 write_disks(fid->fmt, &pvds));
d1d9800e 303
7284f3f9 304 lvmcache_update_vg(vg, 0);
2262b320 305 dm_pool_destroy(mem);
df765ac1
JT
306 return r;
307}
3840b20a 308
8a2fc586 309static int _format1_pv_read(const struct format_type *fmt, const char *pv_name,
30581623 310 struct physical_volume *pv, int scan_label_only __attribute__((unused)))
47bd2984 311{
2262b320 312 struct dm_pool *mem = dm_pool_create("lvm1 pv_read", 1024);
47bd2984 313 struct disk_list *dl;
b1713d28 314 struct device *dev;
25b73380 315 int r = 0;
47bd2984 316
d1d9800e 317 log_very_verbose("Reading physical volume data %s from disk", pv_name);
8f8a968d 318
c51b9fff
AK
319 if (!mem)
320 return_0;
47bd2984 321
c51b9fff
AK
322 if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter)))
323 goto_out;
b1713d28 324
c51b9fff
AK
325 if (!(dl = read_disk(fmt, dev, mem, NULL)))
326 goto_out;
47bd2984 327
c51b9fff
AK
328 if (!import_pv(fmt, fmt->cmd->mem, dl->dev, NULL, pv, &dl->pvd, &dl->vgd))
329 goto_out;
47bd2984 330
d1d9800e 331 pv->fmt = fmt;
25b73380
AK
332
333 r = 1;
47bd2984 334
25b73380 335 out:
2262b320 336 dm_pool_destroy(mem);
25b73380 337 return r;
47bd2984
JT
338}
339
617b900d
PR
340static int _format1_pv_initialise(const struct format_type * fmt,
341 int64_t label_sector __attribute__((unused)),
342 uint64_t pe_start,
343 uint32_t extent_count,
344 uint32_t extent_size,
345 unsigned long data_alignment __attribute__((unused)),
346 unsigned long data_alignment_offset __attribute__((unused)),
347 struct physical_volume * pv)
c8ca2a29 348{
a45f546f
AK
349 if (pv->size > MAX_PV_SIZE)
350 pv->size--;
f48d3bcb 351 if (pv->size > MAX_PV_SIZE) {
d1d9800e 352 log_error("Physical volumes cannot be bigger than %s",
72b2cb61 353 display_size(fmt->cmd, (uint64_t) MAX_PV_SIZE));
f48d3bcb
HM
354 return 0;
355 }
356
d1d9800e
AK
357 /* Nothing more to do if extent size isn't provided */
358 if (!extent_size)
a45f546f 359 return 1;
e1d93eb4 360
88835ab6
JT
361 /*
362 * This works out pe_start and pe_count.
363 */
c51b9fff
AK
364 if (!calculate_extent_count(pv, extent_size, extent_count, pe_start))
365 return_0;
88835ab6 366
d1d9800e 367 /* Retain existing extent locations exactly */
d1d9800e
AK
368 if (((pe_start || extent_count) && (pe_start != pv->pe_start)) ||
369 (extent_count && (extent_count != pv->pe_count))) {
370 log_error("Metadata would overwrite physical extents");
371 return 0;
372 }
373
75559040
JT
374 return 1;
375}
376
617b900d 377static int _format1_pv_setup(const struct format_type *fmt,
617b900d 378 struct physical_volume *pv,
4b8f066c 379 struct volume_group *vg)
617b900d
PR
380{
381 return _format1_pv_initialise(fmt, -1, 0, 0, vg->extent_size, 0, 0, pv);
382}
383
8a2fc586 384static int _format1_lv_setup(struct format_instance *fid, struct logical_volume *lv)
2fe9b138 385{
df89b641
HM
386 uint64_t max_size = UINT_MAX;
387
ab053ad6 388 if (!*lv->lvid.s)
fee16e10 389 lvid_from_lvnum(&lv->lvid, &lv->vg->id, find_free_lvnum(lv));
187cf4c9 390
ff783e52 391 if (lv->le_count > MAX_LE_TOTAL) {
1176eb25
AK
392 log_error("logical volumes cannot contain more than "
393 "%d extents.", MAX_LE_TOTAL);
2fe9b138
JT
394 return 0;
395 }
df89b641 396 if (lv->size > max_size) {
4c64ed4c 397 log_error("logical volumes cannot be larger than %s",
72b2cb61 398 display_size(fid->fmt->cmd, max_size));
df89b641
HM
399 return 0;
400 }
2fe9b138
JT
401
402 return 1;
403}
404
17ad2b11 405static int _format1_pv_write(const struct format_type *fmt, struct physical_volume *pv)
11d9c9f2 406{
2262b320 407 struct dm_pool *mem;
de9acc04 408 struct disk_list *dl;
2c44337b 409 struct dm_list pvs;
914c9723 410 struct lvmcache_info *info;
3cac20f8
AK
411 int pe_count, pe_size, pe_start;
412 int r = 1;
de9acc04 413
914c9723 414 if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev,
c51b9fff
AK
415 pv->vg_name, NULL, 0)))
416 return_0;
4675e4f1 417
8e5f7cf3
PR
418 lvmcache_update_pv(info, pv, fmt);
419 lvmcache_del_mdas(info);
dae08226 420 lvmcache_del_das(info);
d1d9800e 421
2c44337b 422 dm_list_init(&pvs);
de9acc04 423
3cac20f8
AK
424 pe_count = pv->pe_count;
425 pe_size = pv->pe_size;
426 pe_start = pv->pe_start;
427
cd77c5a7 428 /* Ensure any residual PE structure is gone */
25b73380 429 pv->pe_size = pv->pe_count = 0;
ee37789b 430 pv->pe_start = LVM1_PE_ALIGN;
cd77c5a7 431
c51b9fff
AK
432 if (!(mem = dm_pool_create("lvm1 pv_write", 1024)))
433 return_0;
de9acc04 434
4f2f566b
AK
435 if (!(dl = dm_pool_alloc(mem, sizeof(*dl))))
436 goto_bad;
437
de9acc04
JT
438 dl->mem = mem;
439 dl->dev = pv->dev;
3cac20f8
AK
440 dm_list_init(&dl->uuids);
441 dm_list_init(&dl->lvds);
de9acc04 442
4f2f566b
AK
443 if (!export_pv(fmt->cmd, mem, NULL, &dl->pvd, pv))
444 goto_bad;
de9acc04 445
f7ff4d00
HM
446 /* must be set to be able to zero gap after PV structure in
447 dev_write in order to make other disk tools happy */
448 dl->pvd.pv_on_disk.base = METADATA_BASE;
449 dl->pvd.pv_on_disk.size = PV_SIZE;
ee37789b 450 dl->pvd.pe_on_disk.base = LVM1_PE_ALIGN << SECTOR_SHIFT;
f7ff4d00 451
2c44337b 452 dm_list_add(&pvs, &dl->list);
4f2f566b
AK
453 if (!write_disks(fmt, &pvs))
454 goto_bad;
de9acc04 455
3cac20f8 456 goto out;
de9acc04 457
25b73380 458 bad:
3cac20f8
AK
459 r = 0;
460
461 out:
462 pv->pe_size = pe_size;
463 pv->pe_count = pe_count;
464 pv->pe_start = pe_start;
465
2262b320 466 dm_pool_destroy(mem);
3cac20f8 467 return r;
11d9c9f2
JT
468}
469
8a2fc586 470static int _format1_vg_setup(struct format_instance *fid, struct volume_group *vg)
8a482590
JT
471{
472 /* just check max_pv and max_lv */
12bb377f 473 if (!vg->max_lv || vg->max_lv >= MAX_LV)
df2e0dc7 474 vg->max_lv = MAX_LV - 1;
8a482590 475
12bb377f 476 if (!vg->max_pv || vg->max_pv >= MAX_PV)
df2e0dc7 477 vg->max_pv = MAX_PV - 1;
8a482590 478
aa290eb2 479 if (vg->extent_size > MAX_PE_SIZE || vg->extent_size < MIN_PE_SIZE) {
aa290eb2 480 log_error("Extent size must be between %s and %s",
72b2cb61
AK
481 display_size(fid->fmt->cmd, (uint64_t) MIN_PE_SIZE),
482 display_size(fid->fmt->cmd, (uint64_t) MAX_PE_SIZE));
aa290eb2 483
aa290eb2
AK
484 return 0;
485 }
486
487 if (vg->extent_size % MIN_PE_SIZE) {
aa290eb2 488 log_error("Extent size must be multiple of %s",
72b2cb61 489 display_size(fid->fmt->cmd, (uint64_t) MIN_PE_SIZE));
aa290eb2
AK
490 return 0;
491 }
492
493 /* Redundant? */
494 if (vg->extent_size & (vg->extent_size - 1)) {
495 log_error("Extent size must be power of 2");
496 return 0;
497 }
498
8a482590
JT
499 return 1;
500}
11d9c9f2 501
08f1ddea 502static int _format1_segtype_supported(struct format_instance *fid __attribute__((unused)),
72b2cb61 503 const struct segment_type *segtype)
68eb9e3b 504{
c51b9fff
AK
505 if (!(segtype->flags & SEG_FORMAT1_SUPPORT))
506 return_0;
68eb9e3b
AK
507
508 return 1;
509}
510
d1d9800e 511static struct metadata_area_ops _metadata_format1_ops = {
72b2cb61
AK
512 .vg_read = _format1_vg_read,
513 .vg_write = _format1_vg_write,
d1d9800e
AK
514};
515
8a2fc586 516static struct format_instance *_format1_create_instance(const struct format_type *fmt,
88129db5 517 const struct format_instance_ctx *fic)
25b73380
AK
518{
519 struct format_instance *fid;
520 struct metadata_area *mda;
521
56f5b12e 522 if (!(fid = alloc_fid(fmt, fic)))
c51b9fff 523 return_NULL;
25b73380 524
25b73380 525 /* Define a NULL metadata area */
ff447941 526 if (!(mda = dm_pool_zalloc(fid->mem, sizeof(*mda)))) {
a1bec4e6
PR
527 log_error("Unable to allocate metadata area structure "
528 "for lvm1 format");
a1bec4e6 529 goto bad;
25b73380
AK
530 }
531
d1d9800e 532 mda->ops = &_metadata_format1_ops;
25b73380 533 mda->metadata_locn = NULL;
637ac19e 534 mda->status = 0;
f55a20eb 535 dm_list_add(&fid->metadata_areas_in_use, &mda->list);
25b73380
AK
536
537 return fid;
a1bec4e6
PR
538
539bad:
540 dm_pool_destroy(fid->mem);
541 return NULL;
25b73380
AK
542}
543
a1bec4e6 544static void _format1_destroy_instance(struct format_instance *fid)
3840b20a 545{
a1bec4e6
PR
546 if (--fid->ref_count <= 1)
547 dm_pool_destroy(fid->mem);
721128e8
JT
548}
549
9d9de35d 550static void _format1_destroy(struct format_type *fmt)
25b73380 551{
52f2f3ea
ZK
552 if (fmt->orphan_vg)
553 free_orphan_vg(fmt->orphan_vg);
6e41729e 554
9d9de35d 555 dm_free(fmt);
25b73380 556}
721128e8 557
2107f482 558static struct format_handler _format1_ops = {
72b2cb61 559 .pv_read = _format1_pv_read,
617b900d 560 .pv_initialise = _format1_pv_initialise,
72b2cb61
AK
561 .pv_setup = _format1_pv_setup,
562 .pv_write = _format1_pv_write,
563 .lv_setup = _format1_lv_setup,
564 .vg_setup = _format1_vg_setup,
565 .segtype_supported = _format1_segtype_supported,
566 .create_instance = _format1_create_instance,
567 .destroy_instance = _format1_destroy_instance,
568 .destroy = _format1_destroy,
2107f482 569};
b892f8ec 570
d1d9800e
AK
571#ifdef LVM1_INTERNAL
572struct format_type *init_lvm1_format(struct cmd_context *cmd)
573#else /* Shared */
b896caa1 574struct format_type *init_format(struct cmd_context *cmd);
d1d9800e
AK
575struct format_type *init_format(struct cmd_context *cmd)
576#endif
2107f482 577{
2262b320 578 struct format_type *fmt = dm_malloc(sizeof(*fmt));
6e41729e
PR
579 struct format_instance_ctx fic;
580 struct format_instance *fid;
721128e8 581
f9411bb2
ZK
582 if (!fmt) {
583 log_error("Failed to allocate format1 format type structure.");
584 return NULL;
585 }
721128e8 586
25b73380
AK
587 fmt->cmd = cmd;
588 fmt->ops = &_format1_ops;
589 fmt->name = FMT_LVM1_NAME;
d1d9800e 590 fmt->alias = NULL;
bb097a97 591 fmt->orphan_vg_name = FMT_LVM1_ORPHAN_VG_NAME;
b4068515
AK
592 fmt->features = FMT_RESTRICTED_LVIDS | FMT_ORPHAN_ALLOCATABLE |
593 FMT_RESTRICTED_READAHEAD;
25b73380 594 fmt->private = NULL;
721128e8 595
dae08226
PR
596 dm_list_init(&fmt->mda_ops);
597
d1d9800e
AK
598 if (!(fmt->labeller = lvm1_labeller_create(fmt))) {
599 log_error("Couldn't create lvm1 label handler.");
ee54e437 600 dm_free(fmt);
d1d9800e
AK
601 return NULL;
602 }
603
604 if (!(label_register_handler(FMT_LVM1_NAME, fmt->labeller))) {
605 log_error("Couldn't register lvm1 label handler.");
ee54e437
ZK
606 fmt->labeller->ops->destroy(fmt->labeller);
607 dm_free(fmt);
d1d9800e
AK
608 return NULL;
609 }
610
e22fddbf 611 if (!(fmt->orphan_vg = alloc_vg("format1_orphan", cmd, fmt->orphan_vg_name))) {
6e41729e 612 log_error("Couldn't create lvm1 orphan VG.");
f9411bb2 613 dm_free(fmt);
6e41729e
PR
614 return NULL;
615 }
f9411bb2 616
b719e3d3 617 fic.type = FMT_INSTANCE_AUX_MDAS;
6e41729e
PR
618 fic.context.vg_ref.vg_name = fmt->orphan_vg_name;
619 fic.context.vg_ref.vg_id = NULL;
f9411bb2 620
6e41729e 621 if (!(fid = _format1_create_instance(fmt, &fic))) {
f9411bb2
ZK
622 _format1_destroy(fmt);
623 return_NULL;
6e41729e 624 }
f9411bb2 625
6e41729e
PR
626 vg_set_fid(fmt->orphan_vg, fid);
627
19d1e710
AK
628 log_very_verbose("Initialised format: %s", fmt->name);
629
25b73380 630 return fmt;
3840b20a 631}
This page took 0.169659 seconds and 5 git commands to generate.