4 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
7 * This file is part of LVM2.
9 * This copyrighted material is made available to anyone wishing to use,
10 * modify, copy, or redistribute it subject to the terms and conditions
11 * of the GNU Lesser General Public License v.2.1.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "format-text.h"
20 #include "import-export.h"
25 #include "toolcontext.h"
26 #include "lvm-string.h"
37 #include <sys/param.h>
42 static struct mda_header
*_raw_read_mda_header(const struct format_type
*fmt
,
43 struct device_area
*dev_area
);
45 static struct format_instance
*_text_create_text_instance(const struct format_type
46 *fmt
, const char *vgname
,
50 struct text_fid_context
{
51 char *raw_metadata_buf
;
52 uint32_t raw_metadata_buf_size
;
62 struct device_area dev_area
;
66 char *path_live
; /* Path to file holding live metadata */
67 char *path_edit
; /* Path to file holding edited metadata */
68 char *desc
; /* Description placed inside file */
72 * NOTE: Currently there can be only one vg per text file.
75 static int _text_vg_setup(struct format_instance
*fid
__attribute((unused
)),
76 struct volume_group
*vg
)
78 if (vg
->extent_size
& (vg
->extent_size
- 1)) {
79 log_error("Extent size must be power of 2");
86 static uint64_t _mda_free_sectors_raw(struct metadata_area
*mda
)
88 struct mda_context
*mdac
= (struct mda_context
*) mda
->metadata_locn
;
90 return mdac
->free_sectors
;
93 static uint64_t _mda_total_sectors_raw(struct metadata_area
*mda
)
95 struct mda_context
*mdac
= (struct mda_context
*) mda
->metadata_locn
;
97 return mdac
->area
.size
>> SECTOR_SHIFT
;
101 * Check if metadata area belongs to vg
103 static int _mda_in_vg_raw(struct format_instance
*fid
__attribute((unused
)),
104 struct volume_group
*vg
, struct metadata_area
*mda
)
106 struct mda_context
*mdac
= (struct mda_context
*) mda
->metadata_locn
;
109 dm_list_iterate_items(pvl
, &vg
->pvs
)
110 if (pvl
->pv
->dev
== mdac
->area
.dev
)
117 * For circular region between region_start and region_start + region_size,
118 * back up one SECTOR_SIZE from 'region_ptr' and return the value.
119 * This allows reverse traversal through text metadata area to find old
123 * region_start: start of the region (bytes)
124 * region_size: size of the region (bytes)
125 * region_ptr: pointer within the region (bytes)
126 * NOTE: region_start <= region_ptr <= region_start + region_size
128 static uint64_t _get_prev_sector_circular(uint64_t region_start
,
129 uint64_t region_size
,
132 if (region_ptr
>= region_start
+ SECTOR_SIZE
)
133 return region_ptr
- SECTOR_SIZE
;
135 return (region_start
+ region_size
- SECTOR_SIZE
);
139 * Analyze a metadata area for old metadata records in the circular buffer.
140 * This function just looks through and makes a first pass at the data in
141 * the sectors for particular things.
142 * FIXME: do something with each metadata area (try to extract vg, write
143 * raw data to file, etc)
145 static int _pv_analyze_mda_raw (const struct format_type
* fmt
,
146 struct metadata_area
*mda
)
148 struct mda_header
*mdah
;
149 struct raw_locn
*rlocn
;
152 uint64_t prev_sector
, prev_sector2
;
153 uint64_t latest_mrec_offset
;
160 struct device_area
*area
;
161 struct mda_context
*mdac
;
164 mdac
= (struct mda_context
*) mda
->metadata_locn
;
166 log_print("Found text metadata area: offset=%" PRIu64
", size=%"
167 PRIu64
, mdac
->area
.start
, mdac
->area
.size
);
170 if (!dev_open(area
->dev
))
173 if (!(mdah
= _raw_read_mda_header(fmt
, area
)))
176 rlocn
= mdah
->raw_locns
;
179 * The device area includes the metadata header as well as the
180 * records, so remove the metadata header from the start and size
182 area_start
= area
->start
+ MDA_HEADER_SIZE
;
183 area_size
= area
->size
- MDA_HEADER_SIZE
;
184 latest_mrec_offset
= rlocn
->offset
+ area
->start
;
187 * Start searching at rlocn (point of live metadata) and go
190 prev_sector
= _get_prev_sector_circular(area_start
, area_size
,
192 offset
= prev_sector
;
196 while (prev_sector
!= latest_mrec_offset
) {
197 prev_sector2
= prev_sector
;
198 prev_sector
= _get_prev_sector_circular(area_start
, area_size
,
200 if (prev_sector
> prev_sector2
)
203 * FIXME: for some reason, the whole metadata region from
204 * area->start to area->start+area->size is not used.
205 * Only ~32KB seems to contain valid metadata records
206 * (LVM2 format - format_text). As a result, I end up with
207 * "maybe_config_section" returning true when there's no valid
208 * metadata in a sector (sectors with all nulls).
210 if (!(buf
= dm_pool_alloc(fmt
->cmd
->mem
, size
+ size2
)))
213 if (!dev_read_circular(area
->dev
, offset
, size
,
214 offset2
, size2
, buf
))
218 * FIXME: We could add more sophisticated metadata detection
220 if (maybe_config_section(buf
, size
+ size2
)) {
221 /* FIXME: Validate region, pull out timestamp?, etc */
222 /* FIXME: Do something with this region */
223 log_verbose ("Found LVM2 metadata record at "
224 "offset=%"PRIu64
", size=%"PRIsize_t
", "
225 "offset2=%"PRIu64
" size2=%"PRIsize_t
,
226 offset
, size
, offset2
, size2
);
227 offset
= prev_sector
;
232 * Not a complete metadata record, assume we have
233 * metadata and just increase the size and offset.
234 * Start the second region if the previous sector is
235 * wrapping around towards the end of the disk.
237 if (prev_sector
> offset
) {
238 offset2
= prev_sector
;
239 size2
+= SECTOR_SIZE
;
241 offset
= prev_sector
;
245 dm_pool_free(fmt
->cmd
->mem
, buf
);
252 dm_pool_free(fmt
->cmd
->mem
, buf
);
253 if (!dev_close(area
->dev
))
260 static int _text_lv_setup(struct format_instance
*fid
__attribute((unused
)),
261 struct logical_volume
*lv
)
263 /******** FIXME Any LV size restriction?
264 uint64_t max_size = UINT_MAX;
266 if (lv->size > max_size) {
267 char *dummy = display_size(max_size);
268 log_error("logical volumes cannot be larger than %s", dummy);
274 if (!*lv
->lvid
.s
&& !lvid_create(&lv
->lvid
, &lv
->vg
->id
)) {
275 log_error("Random lvid creation failed for %s/%s.",
276 lv
->vg
->name
, lv
->name
);
283 static void _xlate_mdah(struct mda_header
*mdah
)
287 mdah
->version
= xlate32(mdah
->version
);
288 mdah
->start
= xlate64(mdah
->start
);
289 mdah
->size
= xlate64(mdah
->size
);
291 rl
= &mdah
->raw_locns
[0];
293 rl
->checksum
= xlate32(rl
->checksum
);
294 rl
->offset
= xlate64(rl
->offset
);
295 rl
->size
= xlate64(rl
->size
);
300 static struct mda_header
*_raw_read_mda_header(const struct format_type
*fmt
,
301 struct device_area
*dev_area
)
303 struct mda_header
*mdah
;
305 if (!(mdah
= dm_pool_alloc(fmt
->cmd
->mem
, MDA_HEADER_SIZE
))) {
306 log_error("struct mda_header allocation failed");
310 if (!dev_read(dev_area
->dev
, dev_area
->start
, MDA_HEADER_SIZE
, mdah
))
313 if (mdah
->checksum_xl
!= xlate32(calc_crc(INITIAL_CRC
, mdah
->magic
,
315 sizeof(mdah
->checksum_xl
)))) {
316 log_error("Incorrect metadata area header checksum");
322 if (strncmp((char *)mdah
->magic
, FMTT_MAGIC
, sizeof(mdah
->magic
))) {
323 log_error("Wrong magic number in metadata area header");
327 if (mdah
->version
!= FMTT_VERSION
) {
328 log_error("Incompatible metadata area header version: %d",
333 if (mdah
->start
!= dev_area
->start
) {
334 log_error("Incorrect start sector in metadata area header: %"
335 PRIu64
, mdah
->start
);
342 dm_pool_free(fmt
->cmd
->mem
, mdah
);
346 static int _raw_write_mda_header(const struct format_type
*fmt
,
348 uint64_t start_byte
, struct mda_header
*mdah
)
350 strncpy((char *)mdah
->magic
, FMTT_MAGIC
, sizeof(mdah
->magic
));
351 mdah
->version
= FMTT_VERSION
;
352 mdah
->start
= start_byte
;
355 mdah
->checksum_xl
= xlate32(calc_crc(INITIAL_CRC
, mdah
->magic
,
357 sizeof(mdah
->checksum_xl
)));
359 if (!dev_write(dev
, start_byte
, MDA_HEADER_SIZE
, mdah
))
365 static struct raw_locn
*_find_vg_rlocn(struct device_area
*dev_area
,
366 struct mda_header
*mdah
,
371 char vgnamebuf
[NAME_LEN
+ 2] __attribute((aligned(8)));
372 struct raw_locn
*rlocn
, *rlocn_precommitted
;
373 struct lvmcache_info
*info
;
375 rlocn
= mdah
->raw_locns
; /* Slot 0 */
376 rlocn_precommitted
= rlocn
+ 1; /* Slot 1 */
378 /* Should we use precommitted metadata? */
379 if (*precommitted
&& rlocn_precommitted
->size
&&
380 (rlocn_precommitted
->offset
!= rlocn
->offset
)) {
381 rlocn
= rlocn_precommitted
;
385 /* FIXME Loop through rlocns two-at-a-time. List null-terminated. */
386 /* FIXME Ignore if checksum incorrect!!! */
387 if (!dev_read(dev_area
->dev
, dev_area
->start
+ rlocn
->offset
,
388 sizeof(vgnamebuf
), vgnamebuf
))
391 if (!strncmp(vgnamebuf
, vgname
, len
= strlen(vgname
)) &&
392 (isspace(vgnamebuf
[len
]) || vgnamebuf
[len
] == '{')) {
397 if ((info
= info_from_pvid(dev_area
->dev
->pvid
, 0)))
398 lvmcache_update_vgname_and_id(info
, FMT_TEXT_ORPHAN_VG_NAME
,
399 FMT_TEXT_ORPHAN_VG_NAME
, 0, NULL
);
405 * Determine offset for uncommitted metadata
407 static uint64_t _next_rlocn_offset(struct raw_locn
*rlocn
,
408 struct mda_header
*mdah
)
411 /* Find an empty slot */
412 /* FIXME Assume only one VG per mdah for now */
413 return MDA_HEADER_SIZE
;
415 /* Start of free space - round up to next sector; circular */
416 return ((rlocn
->offset
+ rlocn
->size
+
417 (SECTOR_SIZE
- rlocn
->size
% SECTOR_SIZE
) -
418 MDA_HEADER_SIZE
) % (mdah
->size
- MDA_HEADER_SIZE
))
422 static int _raw_holds_vgname(struct format_instance
*fid
,
423 struct device_area
*dev_area
, const char *vgname
)
427 struct mda_header
*mdah
;
429 if (!dev_open(dev_area
->dev
))
432 if (!(mdah
= _raw_read_mda_header(fid
->fmt
, dev_area
)))
435 if (_find_vg_rlocn(dev_area
, mdah
, vgname
, &noprecommit
))
438 if (!dev_close(dev_area
->dev
))
444 static struct volume_group
*_vg_read_raw_area(struct format_instance
*fid
,
446 struct device_area
*area
,
449 struct volume_group
*vg
= NULL
;
450 struct raw_locn
*rlocn
;
451 struct mda_header
*mdah
;
456 if (!dev_open(area
->dev
))
459 if (!(mdah
= _raw_read_mda_header(fid
->fmt
, area
)))
462 if (!(rlocn
= _find_vg_rlocn(area
, mdah
, vgname
, &precommitted
))) {
463 log_debug("VG %s not found on %s", vgname
, dev_name(area
->dev
));
467 if (rlocn
->offset
+ rlocn
->size
> mdah
->size
)
468 wrap
= (uint32_t) ((rlocn
->offset
+ rlocn
->size
) - mdah
->size
);
470 if (wrap
> rlocn
->offset
) {
471 log_error("VG %s metadata too large for circular buffer",
477 if (!(vg
= text_vg_import_fd(fid
, NULL
, area
->dev
,
478 (off_t
) (area
->start
+ rlocn
->offset
),
479 (uint32_t) (rlocn
->size
- wrap
),
480 (off_t
) (area
->start
+ MDA_HEADER_SIZE
),
481 wrap
, calc_crc
, rlocn
->checksum
, &when
,
484 log_debug("Read %s %smetadata (%u) from %s at %" PRIu64
" size %"
485 PRIu64
, vg
->name
, precommitted
? "pre-commit " : "",
486 vg
->seqno
, dev_name(area
->dev
),
487 area
->start
+ rlocn
->offset
, rlocn
->size
);
490 vg
->status
|= PRECOMMITTED
;
493 if (!dev_close(area
->dev
))
499 static struct volume_group
*_vg_read_raw(struct format_instance
*fid
,
501 struct metadata_area
*mda
)
503 struct mda_context
*mdac
= (struct mda_context
*) mda
->metadata_locn
;
505 return _vg_read_raw_area(fid
, vgname
, &mdac
->area
, 0);
508 static struct volume_group
*_vg_read_precommit_raw(struct format_instance
*fid
,
510 struct metadata_area
*mda
)
512 struct mda_context
*mdac
= (struct mda_context
*) mda
->metadata_locn
;
514 return _vg_read_raw_area(fid
, vgname
, &mdac
->area
, 1);
517 static int _vg_write_raw(struct format_instance
*fid
, struct volume_group
*vg
,
518 struct metadata_area
*mda
)
520 struct mda_context
*mdac
= (struct mda_context
*) mda
->metadata_locn
;
521 struct text_fid_context
*fidtc
= (struct text_fid_context
*) fid
->private;
522 struct raw_locn
*rlocn
;
523 struct mda_header
*mdah
;
526 uint64_t new_wrap
= 0, old_wrap
= 0, new_end
;
530 /* Ignore any mda on a PV outside the VG. vgsplit relies on this */
531 dm_list_iterate_items(pvl
, &vg
->pvs
) {
532 if (pvl
->pv
->dev
== mdac
->area
.dev
) {
541 if (!dev_open(mdac
->area
.dev
))
544 if (!(mdah
= _raw_read_mda_header(fid
->fmt
, &mdac
->area
)))
547 rlocn
= _find_vg_rlocn(&mdac
->area
, mdah
, vg
->name
, &noprecommit
);
548 mdac
->rlocn
.offset
= _next_rlocn_offset(rlocn
, mdah
);
550 if (!fidtc
->raw_metadata_buf
&&
551 !(fidtc
->raw_metadata_buf_size
=
552 text_vg_export_raw(vg
, "", &fidtc
->raw_metadata_buf
))) {
553 log_error("VG %s metadata writing failed", vg
->name
);
557 mdac
->rlocn
.size
= fidtc
->raw_metadata_buf_size
;
559 if (mdac
->rlocn
.offset
+ mdac
->rlocn
.size
> mdah
->size
)
560 new_wrap
= (mdac
->rlocn
.offset
+ mdac
->rlocn
.size
) - mdah
->size
;
562 if (rlocn
&& (rlocn
->offset
+ rlocn
->size
> mdah
->size
))
563 old_wrap
= (rlocn
->offset
+ rlocn
->size
) - mdah
->size
;
565 new_end
= new_wrap
? new_wrap
+ MDA_HEADER_SIZE
:
566 mdac
->rlocn
.offset
+ mdac
->rlocn
.size
;
568 if ((new_wrap
&& old_wrap
) ||
569 (rlocn
&& (new_wrap
|| old_wrap
) && (new_end
> rlocn
->offset
)) ||
570 (mdac
->rlocn
.size
>= mdah
->size
)) {
571 log_error("VG %s metadata too large for circular buffer",
576 log_debug("Writing %s metadata to %s at %" PRIu64
" len %" PRIu64
,
577 vg
->name
, dev_name(mdac
->area
.dev
), mdac
->area
.start
+
578 mdac
->rlocn
.offset
, mdac
->rlocn
.size
- new_wrap
);
580 /* Write text out, circularly */
581 if (!dev_write(mdac
->area
.dev
, mdac
->area
.start
+ mdac
->rlocn
.offset
,
582 (size_t) (mdac
->rlocn
.size
- new_wrap
),
583 fidtc
->raw_metadata_buf
))
587 log_debug("Writing metadata to %s at %" PRIu64
" len %" PRIu64
,
588 dev_name(mdac
->area
.dev
), mdac
->area
.start
+
589 MDA_HEADER_SIZE
, new_wrap
);
591 if (!dev_write(mdac
->area
.dev
,
592 mdac
->area
.start
+ MDA_HEADER_SIZE
,
594 fidtc
->raw_metadata_buf
+
595 mdac
->rlocn
.size
- new_wrap
))
599 mdac
->rlocn
.checksum
= calc_crc(INITIAL_CRC
, fidtc
->raw_metadata_buf
,
600 (uint32_t) (mdac
->rlocn
.size
-
603 mdac
->rlocn
.checksum
= calc_crc(mdac
->rlocn
.checksum
,
604 fidtc
->raw_metadata_buf
+
606 new_wrap
, (uint32_t) new_wrap
);
612 if (!dev_close(mdac
->area
.dev
))
615 if (fidtc
->raw_metadata_buf
) {
616 dm_free(fidtc
->raw_metadata_buf
);
617 fidtc
->raw_metadata_buf
= NULL
;
624 static int _vg_commit_raw_rlocn(struct format_instance
*fid
,
625 struct volume_group
*vg
,
626 struct metadata_area
*mda
,
629 struct mda_context
*mdac
= (struct mda_context
*) mda
->metadata_locn
;
630 struct text_fid_context
*fidtc
= (struct text_fid_context
*) fid
->private;
631 struct mda_header
*mdah
;
632 struct raw_locn
*rlocn
;
638 /* Ignore any mda on a PV outside the VG. vgsplit relies on this */
639 dm_list_iterate_items(pvl
, &vg
->pvs
) {
640 if (pvl
->pv
->dev
== mdac
->area
.dev
) {
649 if (!(mdah
= _raw_read_mda_header(fid
->fmt
, &mdac
->area
)))
652 if (!(rlocn
= _find_vg_rlocn(&mdac
->area
, mdah
, vg
->name
, &noprecommit
))) {
653 mdah
->raw_locns
[0].offset
= 0;
654 mdah
->raw_locns
[0].size
= 0;
655 mdah
->raw_locns
[0].checksum
= 0;
656 mdah
->raw_locns
[1].offset
= 0;
657 mdah
->raw_locns
[1].size
= 0;
658 mdah
->raw_locns
[1].checksum
= 0;
659 mdah
->raw_locns
[2].offset
= 0;
660 mdah
->raw_locns
[2].size
= 0;
661 mdah
->raw_locns
[2].checksum
= 0;
662 rlocn
= &mdah
->raw_locns
[0];
668 /* If not precommitting, wipe the precommitted rlocn */
669 mdah
->raw_locns
[1].offset
= 0;
670 mdah
->raw_locns
[1].size
= 0;
671 mdah
->raw_locns
[1].checksum
= 0;
674 /* Is there new metadata to commit? */
675 if (mdac
->rlocn
.size
) {
676 rlocn
->offset
= mdac
->rlocn
.offset
;
677 rlocn
->size
= mdac
->rlocn
.size
;
678 rlocn
->checksum
= mdac
->rlocn
.checksum
;
679 log_debug("%sCommitting %s metadata (%u) to %s header at %"
680 PRIu64
, precommit
? "Pre-" : "", vg
->name
, vg
->seqno
,
681 dev_name(mdac
->area
.dev
), mdac
->area
.start
);
683 log_debug("Wiping pre-committed %s metadata from %s "
684 "header at %" PRIu64
, vg
->name
,
685 dev_name(mdac
->area
.dev
), mdac
->area
.start
);
687 if (!_raw_write_mda_header(fid
->fmt
, mdac
->area
.dev
, mdac
->area
.start
,
689 dm_pool_free(fid
->fmt
->cmd
->mem
, mdah
);
690 log_error("Failed to write metadata area header");
698 if (!dev_close(mdac
->area
.dev
))
700 if (fidtc
->raw_metadata_buf
) {
701 dm_free(fidtc
->raw_metadata_buf
);
702 fidtc
->raw_metadata_buf
= NULL
;
709 static int _vg_commit_raw(struct format_instance
*fid
, struct volume_group
*vg
,
710 struct metadata_area
*mda
)
712 return _vg_commit_raw_rlocn(fid
, vg
, mda
, 0);
715 static int _vg_precommit_raw(struct format_instance
*fid
,
716 struct volume_group
*vg
,
717 struct metadata_area
*mda
)
719 return _vg_commit_raw_rlocn(fid
, vg
, mda
, 1);
722 /* Close metadata area devices */
723 static int _vg_revert_raw(struct format_instance
*fid
, struct volume_group
*vg
,
724 struct metadata_area
*mda
)
726 struct mda_context
*mdac
= (struct mda_context
*) mda
->metadata_locn
;
730 /* Ignore any mda on a PV outside the VG. vgsplit relies on this */
731 dm_list_iterate_items(pvl
, &vg
->pvs
) {
732 if (pvl
->pv
->dev
== mdac
->area
.dev
) {
741 /* Wipe pre-committed metadata */
742 mdac
->rlocn
.size
= 0;
743 return _vg_commit_raw_rlocn(fid
, vg
, mda
, 0);
746 static int _vg_remove_raw(struct format_instance
*fid
, struct volume_group
*vg
,
747 struct metadata_area
*mda
)
749 struct mda_context
*mdac
= (struct mda_context
*) mda
->metadata_locn
;
750 struct mda_header
*mdah
;
751 struct raw_locn
*rlocn
;
755 if (!dev_open(mdac
->area
.dev
))
758 if (!(mdah
= _raw_read_mda_header(fid
->fmt
, &mdac
->area
)))
761 if (!(rlocn
= _find_vg_rlocn(&mdac
->area
, mdah
, vg
->name
, &noprecommit
))) {
762 rlocn
= &mdah
->raw_locns
[0];
763 mdah
->raw_locns
[1].offset
= 0;
770 if (!_raw_write_mda_header(fid
->fmt
, mdac
->area
.dev
, mdac
->area
.start
,
772 dm_pool_free(fid
->fmt
->cmd
->mem
, mdah
);
773 log_error("Failed to write metadata area header");
780 if (!dev_close(mdac
->area
.dev
))
786 static struct volume_group
*_vg_read_file_name(struct format_instance
*fid
,
788 const char *read_path
)
790 struct volume_group
*vg
;
794 if (!(vg
= text_vg_import_file(fid
, read_path
, &when
, &desc
)))
798 * Currently you can only have a single volume group per
799 * text file (this restriction may remain). We need to
800 * check that it contains the correct volume group.
802 if (vgname
&& strcmp(vgname
, vg
->name
)) {
803 dm_pool_free(fid
->fmt
->cmd
->mem
, vg
);
804 log_error("'%s' does not contain volume group '%s'.",
808 log_debug("Read volume group %s from %s", vg
->name
, read_path
);
813 static struct volume_group
*_vg_read_file(struct format_instance
*fid
,
815 struct metadata_area
*mda
)
817 struct text_context
*tc
= (struct text_context
*) mda
->metadata_locn
;
819 return _vg_read_file_name(fid
, vgname
, tc
->path_live
);
822 static struct volume_group
*_vg_read_precommit_file(struct format_instance
*fid
,
824 struct metadata_area
*mda
)
826 struct text_context
*tc
= (struct text_context
*) mda
->metadata_locn
;
827 struct volume_group
*vg
;
829 if ((vg
= _vg_read_file_name(fid
, vgname
, tc
->path_edit
)))
830 vg
->status
|= PRECOMMITTED
;
832 vg
= _vg_read_file_name(fid
, vgname
, tc
->path_live
);
837 static int _vg_write_file(struct format_instance
*fid
__attribute((unused
)),
838 struct volume_group
*vg
, struct metadata_area
*mda
)
840 struct text_context
*tc
= (struct text_context
*) mda
->metadata_locn
;
845 char temp_file
[PATH_MAX
], temp_dir
[PATH_MAX
];
847 slash
= strrchr(tc
->path_edit
, '/');
850 strcpy(temp_dir
, ".");
851 else if (slash
- tc
->path_edit
< PATH_MAX
) {
852 strncpy(temp_dir
, tc
->path_edit
,
853 (size_t) (slash
- tc
->path_edit
));
854 temp_dir
[slash
- tc
->path_edit
] = '\0';
857 log_error("Text format failed to determine directory.");
861 if (!create_temp_name(temp_dir
, temp_file
, sizeof(temp_file
), &fd
,
862 &vg
->cmd
->rand_seed
)) {
863 log_error("Couldn't create temporary text file name.");
867 if (!(fp
= fdopen(fd
, "w"))) {
868 log_sys_error("fdopen", temp_file
);
870 log_sys_error("fclose", temp_file
);
874 log_debug("Writing %s metadata to %s", vg
->name
, temp_file
);
876 if (!text_vg_export_file(vg
, tc
->desc
, fp
)) {
877 log_error("Failed to write metadata to %s.", temp_file
);
879 log_sys_error("fclose", temp_file
);
883 if (fsync(fd
) && (errno
!= EROFS
) && (errno
!= EINVAL
)) {
884 log_sys_error("fsync", tc
->path_edit
);
886 log_sys_error("fclose", tc
->path_edit
);
890 if (lvm_fclose(fp
, tc
->path_edit
))
893 if (rename(temp_file
, tc
->path_edit
)) {
894 log_debug("Renaming %s to %s", temp_file
, tc
->path_edit
);
895 log_error("%s: rename to %s failed: %s", temp_file
,
896 tc
->path_edit
, strerror(errno
));
903 static int _vg_commit_file_backup(struct format_instance
*fid
__attribute((unused
)),
904 struct volume_group
*vg
,
905 struct metadata_area
*mda
)
907 struct text_context
*tc
= (struct text_context
*) mda
->metadata_locn
;
910 log_verbose("Test mode: Skipping committing %s metadata (%u)",
911 vg
->name
, vg
->seqno
);
912 if (unlink(tc
->path_edit
)) {
913 log_debug("Unlinking %s", tc
->path_edit
);
914 log_sys_error("unlink", tc
->path_edit
);
918 log_debug("Committing %s metadata (%u)", vg
->name
, vg
->seqno
);
919 log_debug("Renaming %s to %s", tc
->path_edit
, tc
->path_live
);
920 if (rename(tc
->path_edit
, tc
->path_live
)) {
921 log_error("%s: rename to %s failed: %s", tc
->path_edit
,
922 tc
->path_live
, strerror(errno
));
927 sync_dir(tc
->path_edit
);
932 static int _vg_commit_file(struct format_instance
*fid
, struct volume_group
*vg
,
933 struct metadata_area
*mda
)
935 struct text_context
*tc
= (struct text_context
*) mda
->metadata_locn
;
937 char new_name
[PATH_MAX
];
940 if (!_vg_commit_file_backup(fid
, vg
, mda
))
944 if ((slash
= strrchr(tc
->path_live
, '/')))
947 slash
= tc
->path_live
;
949 if (strcmp(slash
, vg
->name
)) {
950 len
= slash
- tc
->path_live
;
951 strncpy(new_name
, tc
->path_live
, len
);
952 strcpy(new_name
+ len
, vg
->name
);
953 log_debug("Renaming %s to %s", tc
->path_live
, new_name
);
955 log_verbose("Test mode: Skipping rename");
957 if (rename(tc
->path_live
, new_name
)) {
958 log_error("%s: rename to %s failed: %s",
959 tc
->path_live
, new_name
,
970 static int _vg_remove_file(struct format_instance
*fid
__attribute((unused
)),
971 struct volume_group
*vg
__attribute((unused
)),
972 struct metadata_area
*mda
)
974 struct text_context
*tc
= (struct text_context
*) mda
->metadata_locn
;
976 if (path_exists(tc
->path_edit
) && unlink(tc
->path_edit
)) {
977 log_sys_error("unlink", tc
->path_edit
);
981 if (path_exists(tc
->path_live
) && unlink(tc
->path_live
)) {
982 log_sys_error("unlink", tc
->path_live
);
986 sync_dir(tc
->path_live
);
991 static int _scan_file(const struct format_type
*fmt
)
993 struct dirent
*dirent
;
995 struct dm_list
*dir_list
;
998 struct volume_group
*vg
;
999 struct format_instance
*fid
;
1000 char path
[PATH_MAX
];
1003 dir_list
= &((struct mda_lists
*) fmt
->private)->dirs
;
1005 dm_list_iterate_items(dl
, dir_list
) {
1006 if (!(d
= opendir(dl
->dir
))) {
1007 log_sys_error("opendir", dl
->dir
);
1010 while ((dirent
= readdir(d
)))
1011 if (strcmp(dirent
->d_name
, ".") &&
1012 strcmp(dirent
->d_name
, "..") &&
1013 (!(tmp
= strstr(dirent
->d_name
, ".tmp")) ||
1014 tmp
!= dirent
->d_name
+ strlen(dirent
->d_name
)
1016 vgname
= dirent
->d_name
;
1017 if (dm_snprintf(path
, PATH_MAX
, "%s/%s",
1018 dl
->dir
, vgname
) < 0) {
1019 log_error("Name too long %s/%s",
1024 /* FIXME stat file to see if it's changed */
1025 fid
= _text_create_text_instance(fmt
, NULL
, NULL
,
1027 if ((vg
= _vg_read_file_name(fid
, vgname
,
1029 /* FIXME Store creation host in vg */
1030 lvmcache_update_vg(vg
, 0);
1034 log_sys_error("closedir", dl
->dir
);
1040 const char *vgname_from_mda(const struct format_type
*fmt
,
1041 struct device_area
*dev_area
, struct id
*vgid
,
1042 uint32_t *vgstatus
, char **creation_host
,
1043 uint64_t *mda_free_sectors
)
1045 struct raw_locn
*rlocn
;
1046 struct mda_header
*mdah
;
1048 const char *vgname
= NULL
;
1049 unsigned int len
= 0;
1050 char buf
[NAME_LEN
+ 1] __attribute((aligned(8)));
1051 char uuid
[64] __attribute((aligned(8)));
1052 uint64_t buffer_size
, current_usage
;
1054 if (mda_free_sectors
)
1055 *mda_free_sectors
= ((dev_area
->size
- MDA_HEADER_SIZE
) / 2) >> SECTOR_SHIFT
;
1057 if (!dev_open(dev_area
->dev
))
1060 if (!(mdah
= _raw_read_mda_header(fmt
, dev_area
)))
1063 /* FIXME Cope with returning a list */
1064 rlocn
= mdah
->raw_locns
;
1067 * If no valid offset, do not try to search for vgname
1072 /* Do quick check for a vgname */
1073 if (!dev_read(dev_area
->dev
, dev_area
->start
+ rlocn
->offset
,
1077 while (buf
[len
] && !isspace(buf
[len
]) && buf
[len
] != '{' &&
1078 len
< (NAME_LEN
- 1))
1083 /* Ignore this entry if the characters aren't permissible */
1084 if (!validate_name(buf
))
1087 /* We found a VG - now check the metadata */
1088 if (rlocn
->offset
+ rlocn
->size
> mdah
->size
)
1089 wrap
= (uint32_t) ((rlocn
->offset
+ rlocn
->size
) - mdah
->size
);
1091 if (wrap
> rlocn
->offset
) {
1092 log_error("%s: metadata too large for circular buffer",
1093 dev_name(dev_area
->dev
));
1098 if (!(vgname
= text_vgname_import(fmt
, dev_area
->dev
,
1099 (off_t
) (dev_area
->start
+
1101 (uint32_t) (rlocn
->size
- wrap
),
1102 (off_t
) (dev_area
->start
+
1104 wrap
, calc_crc
, rlocn
->checksum
,
1105 vgid
, vgstatus
, creation_host
)))
1108 /* Ignore this entry if the characters aren't permissible */
1109 if (!validate_name(vgname
)) {
1114 if (!id_write_format(vgid
, uuid
, sizeof(uuid
))) {
1119 log_debug("%s: Found metadata at %" PRIu64
" size %" PRIu64
1120 " (in area at %" PRIu64
" size %" PRIu64
1122 dev_name(dev_area
->dev
), dev_area
->start
+ rlocn
->offset
,
1123 rlocn
->size
, dev_area
->start
, dev_area
->size
, vgname
, uuid
);
1125 if (mda_free_sectors
) {
1126 current_usage
= (rlocn
->size
+ SECTOR_SIZE
- UINT64_C(1)) -
1127 (rlocn
->size
+ SECTOR_SIZE
- UINT64_C(1)) % SECTOR_SIZE
;
1128 buffer_size
= mdah
->size
- MDA_HEADER_SIZE
;
1130 if (current_usage
* 2 >= buffer_size
)
1131 *mda_free_sectors
= UINT64_C(0);
1133 *mda_free_sectors
= ((buffer_size
- 2 * current_usage
) / 2) >> SECTOR_SHIFT
;
1137 if (!dev_close(dev_area
->dev
))
1143 static int _scan_raw(const struct format_type
*fmt
)
1145 struct raw_list
*rl
;
1146 struct dm_list
*raw_list
;
1148 struct volume_group
*vg
;
1149 struct format_instance fid
;
1153 raw_list
= &((struct mda_lists
*) fmt
->private)->raws
;
1156 dm_list_init(&fid
.metadata_areas
);
1158 dm_list_iterate_items(rl
, raw_list
) {
1159 /* FIXME We're reading mdah twice here... */
1160 if ((vgname
= vgname_from_mda(fmt
, &rl
->dev_area
, &vgid
, &vgstatus
,
1162 if ((vg
= _vg_read_raw_area(&fid
, vgname
,
1164 lvmcache_update_vg(vg
, 0);
1171 static int _text_scan(const struct format_type
*fmt
)
1173 return (_scan_file(fmt
) & _scan_raw(fmt
));
1176 /* For orphan, creates new mdas according to policy.
1177 Always have an mda between end-of-label and pe_align() boundary */
1178 static int _mda_setup(const struct format_type
*fmt
,
1179 uint64_t pe_start
, uint64_t pe_end
,
1180 int pvmetadatacopies
,
1181 uint64_t pvmetadatasize
, struct dm_list
*mdas
,
1182 struct physical_volume
*pv
,
1183 struct volume_group
*vg
__attribute((unused
)))
1185 uint64_t mda_adjustment
, disk_size
, alignment
, alignment_offset
;
1186 uint64_t start1
, mda_size1
; /* First area - start of disk */
1187 uint64_t start2
, mda_size2
; /* Second area - end of disk */
1188 uint64_t wipe_size
= 8 << SECTOR_SHIFT
;
1189 size_t pagesize
= lvm_getpagesize();
1191 if (!pvmetadatacopies
)
1194 alignment
= pv
->pe_align
<< SECTOR_SHIFT
;
1195 alignment_offset
= pv
->pe_align_offset
<< SECTOR_SHIFT
;
1196 disk_size
= pv
->size
<< SECTOR_SHIFT
;
1197 pe_start
<<= SECTOR_SHIFT
;
1198 pe_end
<<= SECTOR_SHIFT
;
1200 if (pe_end
> disk_size
) {
1201 log_error("Physical extents end beyond end of device %s!",
1206 /* Requested metadatasize */
1207 mda_size1
= pvmetadatasize
<< SECTOR_SHIFT
;
1209 /* Place mda straight after label area at start of disk */
1210 start1
= LABEL_SCAN_SIZE
;
1212 /* Unless the space available is tiny, round to PAGE_SIZE boundary */
1213 if ((!pe_start
&& !pe_end
) ||
1214 ((pe_start
> start1
) && (pe_start
- start1
>= MDA_SIZE_MIN
))) {
1215 mda_adjustment
= start1
% pagesize
;
1217 start1
+= (pagesize
- mda_adjustment
);
1220 /* Round up to pe_align boundary */
1221 mda_adjustment
= (mda_size1
+ start1
) % alignment
;
1222 if (mda_adjustment
) {
1223 mda_size1
+= (alignment
- mda_adjustment
);
1224 /* Revert if it's now too large */
1225 if (start1
+ mda_size1
> disk_size
)
1226 mda_size1
-= (alignment
- mda_adjustment
);
1229 /* Add pe_align_offset if on pe_align boundary */
1230 if (alignment_offset
&&
1231 (((start1
+ mda_size1
) % alignment
) == 0)) {
1232 mda_size1
+= alignment_offset
;
1233 /* Revert if it's now too large */
1234 if (start1
+ mda_size1
> disk_size
)
1235 mda_size1
-= alignment_offset
;
1238 /* Ensure it's not going to be bigger than the disk! */
1239 if (start1
+ mda_size1
> disk_size
) {
1240 log_warn("WARNING: metadata area fills disk leaving no "
1241 "space for data on %s.", pv_dev_name(pv
));
1242 /* Leave some free space for rounding */
1243 /* Avoid empty data area as could cause tools problems */
1244 mda_size1
= disk_size
- start1
- alignment
* 2;
1245 if (start1
+ mda_size1
> disk_size
) {
1246 log_error("Insufficient space for first mda on %s",
1250 /* Round up to pe_align boundary */
1251 mda_adjustment
= (mda_size1
+ start1
) % alignment
;
1253 mda_size1
+= (alignment
- mda_adjustment
);
1254 /* Only have 1 mda in this case */
1255 pvmetadatacopies
= 1;
1258 /* If we already have PEs, avoid overlap */
1259 if (pe_start
|| pe_end
) {
1260 if (pe_start
<= start1
)
1262 else if (start1
+ mda_size1
> pe_start
)
1263 mda_size1
= pe_start
- start1
;
1266 /* FIXME If creating new mdas, wipe them! */
1268 if (!add_mda(fmt
, fmt
->cmd
->mem
, mdas
, pv
->dev
, start1
,
1272 if (!dev_set((struct device
*) pv
->dev
, start1
,
1273 (size_t) (mda_size1
>
1274 wipe_size
? : mda_size1
), 0)) {
1275 log_error("Failed to wipe new metadata area");
1279 if (pvmetadatacopies
== 1)
1284 /* A second copy at end of disk */
1285 mda_size2
= pvmetadatasize
<< SECTOR_SHIFT
;
1287 /* Ensure it's not going to be bigger than the disk! */
1288 if (mda_size2
> disk_size
)
1289 mda_size2
= disk_size
- start1
- mda_size1
;
1291 mda_adjustment
= (disk_size
- mda_size2
) % alignment
;
1293 mda_size2
+= mda_adjustment
;
1295 start2
= disk_size
- mda_size2
;
1297 /* If we already have PEs, avoid overlap */
1298 if (pe_start
|| pe_end
) {
1299 if (start2
< pe_end
) {
1300 mda_size2
-= (pe_end
- start2
);
1305 /* If we already have a first mda, avoid overlap */
1307 if (start2
< start1
+ mda_size1
) {
1308 mda_size2
-= (start1
+ mda_size1
- start2
);
1309 start2
= start1
+ mda_size1
;
1311 /* No room for any PEs here now! */
1315 if (!add_mda(fmt
, fmt
->cmd
->mem
, mdas
, pv
->dev
, start2
,
1316 mda_size2
)) return 0;
1317 if (!dev_set(pv
->dev
, start2
,
1318 (size_t) (mda_size1
>
1319 wipe_size
? : mda_size1
), 0)) {
1320 log_error("Failed to wipe new metadata area");
1329 /* Only for orphans */
1330 /* Set label_sector to -1 if rewriting existing label into same sector */
1331 /* If mdas is supplied it overwrites existing mdas e.g. used with pvcreate */
1332 static int _text_pv_write(const struct format_type
*fmt
, struct physical_volume
*pv
,
1333 struct dm_list
*mdas
, int64_t label_sector
)
1335 struct label
*label
;
1336 struct lvmcache_info
*info
;
1337 struct mda_context
*mdac
;
1338 struct metadata_area
*mda
;
1339 char buf
[MDA_HEADER_SIZE
] __attribute((aligned(8)));
1340 struct mda_header
*mdah
= (struct mda_header
*) buf
;
1341 uint64_t adjustment
;
1342 struct data_area_list
*da
;
1344 /* FIXME Test mode don't update cache? */
1346 if (!(info
= lvmcache_add(fmt
->labeller
, (char *) &pv
->id
, pv
->dev
,
1347 FMT_TEXT_ORPHAN_VG_NAME
, NULL
, 0)))
1349 label
= info
->label
;
1351 if (label_sector
!= -1)
1352 label
->sector
= label_sector
;
1354 info
->device_size
= pv
->size
<< SECTOR_SHIFT
;
1357 /* If mdas supplied, use them regardless of existing ones, */
1358 /* otherwise retain existing ones */
1361 del_mdas(&info
->mdas
);
1363 dm_list_init(&info
->mdas
);
1364 dm_list_iterate_items(mda
, mdas
) {
1365 mdac
= mda
->metadata_locn
;
1366 log_debug("Creating metadata area on %s at sector %"
1367 PRIu64
" size %" PRIu64
" sectors",
1368 dev_name(mdac
->area
.dev
),
1369 mdac
->area
.start
>> SECTOR_SHIFT
,
1370 mdac
->area
.size
>> SECTOR_SHIFT
);
1371 add_mda(fmt
, NULL
, &info
->mdas
, mdac
->area
.dev
,
1372 mdac
->area
.start
, mdac
->area
.size
);
1374 /* FIXME Temporary until mda creation supported by tools */
1375 } else if (!info
->mdas
.n
) {
1376 dm_list_init(&info
->mdas
);
1380 * If no pe_start supplied but PV already exists,
1381 * get existing value; use-cases include:
1382 * - pvcreate on PV without prior pvremove
1383 * - vgremove on VG with PV(s) that have pe_start=0 (hacked cfg)
1387 dm_list_iterate_items(da
, &info
->das
)
1388 pv
->pe_start
= da
->disk_locn
.offset
>> SECTOR_SHIFT
;
1389 del_das(&info
->das
);
1391 dm_list_init(&info
->das
);
1395 * FIXME: ideally a pre-existing pe_start seen in .pv_write
1396 * would always be preserved BUT 'pvcreate on PV without prior pvremove'
1397 * could easily cause the pe_start to overlap with the first mda!
1400 log_very_verbose("%s: preserving pe_start=%lu",
1401 pv_dev_name(pv
), pv
->pe_start
);
1402 goto preserve_pe_start
;
1407 * If pe_start is still unset, set it to first aligned
1408 * sector after any metadata areas that begin before pe_start.
1410 if (!pv
->pe_start
) {
1411 pv
->pe_start
= pv
->pe_align
;
1412 if (pv
->pe_align_offset
)
1413 pv
->pe_start
+= pv
->pe_align_offset
;
1415 dm_list_iterate_items(mda
, &info
->mdas
) {
1416 mdac
= (struct mda_context
*) mda
->metadata_locn
;
1417 if (pv
->dev
== mdac
->area
.dev
&&
1418 ((mdac
->area
.start
<= (pv
->pe_start
<< SECTOR_SHIFT
)) ||
1419 (mdac
->area
.start
<= lvm_getpagesize() &&
1420 pv
->pe_start
< (lvm_getpagesize() >> SECTOR_SHIFT
))) &&
1421 (mdac
->area
.start
+ mdac
->area
.size
>
1422 (pv
->pe_start
<< SECTOR_SHIFT
))) {
1423 pv
->pe_start
= (mdac
->area
.start
+ mdac
->area
.size
)
1425 /* Adjust pe_start to: (N * pe_align) + pe_align_offset */
1428 (pv
->pe_start
- pv
->pe_align_offset
) % pv
->pe_align
;
1430 pv
->pe_start
+= pv
->pe_align
- adjustment
;
1432 log_very_verbose("%s: setting pe_start=%" PRIu64
1433 " (orig_pe_start=%" PRIu64
", "
1434 "pe_align=%lu, pe_align_offset=%lu, "
1435 "adjustment=%" PRIu64
")",
1436 pv_dev_name(pv
), pv
->pe_start
,
1438 pv
->pe_start
-= pv
->pe_align
- adjustment
:
1440 pv
->pe_align
, pv
->pe_align_offset
, adjustment
);
1444 if (pv
->pe_start
>= pv
->size
) {
1445 log_error("Data area is beyond end of device %s!",
1450 /* FIXME: preserve_pe_start: */
1452 (NULL
, &info
->das
, pv
->pe_start
<< SECTOR_SHIFT
, UINT64_C(0)))
1455 if (!dev_open(pv
->dev
))
1458 dm_list_iterate_items(mda
, &info
->mdas
) {
1459 mdac
= mda
->metadata_locn
;
1460 memset(&buf
, 0, sizeof(buf
));
1461 mdah
->size
= mdac
->area
.size
;
1462 if (!_raw_write_mda_header(fmt
, mdac
->area
.dev
,
1463 mdac
->area
.start
, mdah
)) {
1464 if (!dev_close(pv
->dev
))
1470 if (!label_write(pv
->dev
, label
)) {
1475 if (!dev_close(pv
->dev
))
1481 static int _add_raw(struct dm_list
*raw_list
, struct device_area
*dev_area
)
1483 struct raw_list
*rl
;
1485 /* Already present? */
1486 dm_list_iterate_items(rl
, raw_list
) {
1487 /* FIXME Check size/overlap consistency too */
1488 if (rl
->dev_area
.dev
== dev_area
->dev
&&
1489 rl
->dev_area
.start
== dev_area
->start
)
1493 if (!(rl
= dm_malloc(sizeof(struct raw_list
)))) {
1494 log_error("_add_raw allocation failed");
1497 memcpy(&rl
->dev_area
, dev_area
, sizeof(*dev_area
));
1498 dm_list_add(raw_list
, &rl
->list
);
1503 static int _get_pv_if_in_vg(struct lvmcache_info
*info
,
1504 struct physical_volume
*pv
)
1506 if (info
->vginfo
&& info
->vginfo
->vgname
&&
1507 !is_orphan_vg(info
->vginfo
->vgname
) &&
1508 get_pv_from_vg_by_id(info
->fmt
, info
->vginfo
->vgname
,
1509 info
->vginfo
->vgid
, info
->dev
->pvid
, pv
))
1515 static int _populate_pv_fields(struct lvmcache_info
*info
,
1516 struct physical_volume
*pv
,
1517 int scan_label_only
)
1519 struct data_area_list
*da
;
1521 /* Have we already cached vgname? */
1522 if (!scan_label_only
&& _get_pv_if_in_vg(info
, pv
))
1525 /* Perform full scan (just the first time) and try again */
1526 if (!scan_label_only
&& !memlock() && !full_scan_done()) {
1527 lvmcache_label_scan(info
->fmt
->cmd
, 2);
1529 if (_get_pv_if_in_vg(info
, pv
))
1534 pv
->dev
= info
->dev
;
1535 pv
->fmt
= info
->fmt
;
1536 pv
->size
= info
->device_size
>> SECTOR_SHIFT
;
1537 pv
->vg_name
= FMT_TEXT_ORPHAN_VG_NAME
;
1538 memcpy(&pv
->id
, &info
->dev
->pvid
, sizeof(pv
->id
));
1540 /* Currently only support exactly one data area */
1541 if (dm_list_size(&info
->das
) != 1) {
1542 log_error("Must be exactly one data area (found %d) on PV %s",
1543 dm_list_size(&info
->das
), dev_name(info
->dev
));
1547 dm_list_iterate_items(da
, &info
->das
)
1548 pv
->pe_start
= da
->disk_locn
.offset
>> SECTOR_SHIFT
;
1553 static int _text_pv_read(const struct format_type
*fmt
, const char *pv_name
,
1554 struct physical_volume
*pv
, struct dm_list
*mdas
,
1555 int scan_label_only
)
1557 struct label
*label
;
1559 struct lvmcache_info
*info
;
1560 struct metadata_area
*mda
, *mda_new
;
1561 struct mda_context
*mdac
, *mdac_new
;
1563 if (!(dev
= dev_cache_get(pv_name
, fmt
->cmd
->filter
)))
1566 if (!(label_read(dev
, &label
, UINT64_C(0))))
1568 info
= (struct lvmcache_info
*) label
->info
;
1570 if (!_populate_pv_fields(info
, pv
, scan_label_only
))
1576 /* Add copy of mdas to supplied list */
1577 dm_list_iterate_items(mda
, &info
->mdas
) {
1578 mdac
= (struct mda_context
*) mda
->metadata_locn
;
1579 if (!(mda_new
= dm_pool_alloc(fmt
->cmd
->mem
, sizeof(*mda_new
)))) {
1580 log_error("metadata_area allocation failed");
1583 if (!(mdac_new
= dm_pool_alloc(fmt
->cmd
->mem
, sizeof(*mdac_new
)))) {
1584 log_error("metadata_area allocation failed");
1587 memcpy(mda_new
, mda
, sizeof(*mda
));
1588 memcpy(mdac_new
, mdac
, sizeof(*mdac
));
1589 mda_new
->metadata_locn
= mdac_new
;
1590 dm_list_add(mdas
, &mda_new
->list
);
1596 static void _text_destroy_instance(struct format_instance
*fid
__attribute((unused
)))
1601 static void _free_dirs(struct dm_list
*dir_list
)
1603 struct dm_list
*dl
, *tmp
;
1605 dm_list_iterate_safe(dl
, tmp
, dir_list
) {
1611 static void _free_raws(struct dm_list
*raw_list
)
1613 struct dm_list
*rl
, *tmp
;
1615 dm_list_iterate_safe(rl
, tmp
, raw_list
) {
1621 static void _text_destroy(const struct format_type
*fmt
)
1624 _free_dirs(&((struct mda_lists
*) fmt
->private)->dirs
);
1625 _free_raws(&((struct mda_lists
*) fmt
->private)->raws
);
1626 dm_free(fmt
->private);
1629 dm_free((void *)fmt
);
1632 static struct metadata_area_ops _metadata_text_file_ops
= {
1633 .vg_read
= _vg_read_file
,
1634 .vg_read_precommit
= _vg_read_precommit_file
,
1635 .vg_write
= _vg_write_file
,
1636 .vg_remove
= _vg_remove_file
,
1637 .vg_commit
= _vg_commit_file
1640 static struct metadata_area_ops _metadata_text_file_backup_ops
= {
1641 .vg_read
= _vg_read_file
,
1642 .vg_write
= _vg_write_file
,
1643 .vg_remove
= _vg_remove_file
,
1644 .vg_commit
= _vg_commit_file_backup
1647 static struct metadata_area_ops _metadata_text_raw_ops
= {
1648 .vg_read
= _vg_read_raw
,
1649 .vg_read_precommit
= _vg_read_precommit_raw
,
1650 .vg_write
= _vg_write_raw
,
1651 .vg_remove
= _vg_remove_raw
,
1652 .vg_precommit
= _vg_precommit_raw
,
1653 .vg_commit
= _vg_commit_raw
,
1654 .vg_revert
= _vg_revert_raw
,
1655 .mda_free_sectors
= _mda_free_sectors_raw
,
1656 .mda_total_sectors
= _mda_total_sectors_raw
,
1657 .mda_in_vg
= _mda_in_vg_raw
,
1658 .pv_analyze_mda
= _pv_analyze_mda_raw
,
1661 /* pvmetadatasize in sectors */
1663 * pe_start goal: FIXME -- reality of .pv_write complexity undermines this goal
1664 * - In cases where a pre-existing pe_start is provided (pvcreate --restorefile
1665 * and vgconvert): pe_start must not be changed (so pv->pe_start = pe_start).
1666 * - In cases where pe_start is 0: leave pv->pe_start as 0 and defer the
1667 * setting of pv->pe_start to .pv_write
1669 static int _text_pv_setup(const struct format_type
*fmt
,
1670 uint64_t pe_start
, uint32_t extent_count
,
1671 uint32_t extent_size
, unsigned long data_alignment
,
1672 unsigned long data_alignment_offset
,
1673 int pvmetadatacopies
,
1674 uint64_t pvmetadatasize
, struct dm_list
*mdas
,
1675 struct physical_volume
*pv
, struct volume_group
*vg
)
1677 struct metadata_area
*mda
, *mda_new
, *mda2
;
1678 struct mda_context
*mdac
, *mdac_new
, *mdac2
;
1679 struct dm_list
*pvmdas
;
1680 struct lvmcache_info
*info
;
1682 uint64_t pe_end
= 0;
1683 unsigned mda_count
= 0;
1684 uint64_t mda_size2
= 0;
1687 /* FIXME Cope with pvchange */
1688 /* FIXME Merge code with _text_create_text_instance */
1690 /* If new vg, add any further mdas on this PV to the fid's mda list */
1692 /* Iterate through all mdas on this PV */
1693 if ((info
= info_from_pvid(pv
->dev
->pvid
, 0))) {
1694 pvmdas
= &info
->mdas
;
1695 dm_list_iterate_items(mda
, pvmdas
) {
1698 (struct mda_context
*) mda
->metadata_locn
;
1700 /* FIXME Check it isn't already in use */
1702 /* Reduce usable device size */
1704 mda_size2
= mdac
->area
.size
>> SECTOR_SHIFT
;
1706 /* Ensure it isn't already on list */
1708 dm_list_iterate_items(mda2
, mdas
) {
1710 &_metadata_text_raw_ops
) continue;
1712 (struct mda_context
*)
1713 mda2
->metadata_locn
;
1715 (&mdac2
->area
, &mdac
->area
,
1716 sizeof(mdac
->area
))) {
1724 if (!(mda_new
= dm_pool_alloc(fmt
->cmd
->mem
,
1728 if (!(mdac_new
= dm_pool_alloc(fmt
->cmd
->mem
,
1729 sizeof(*mdac_new
))))
1731 /* FIXME multiple dev_areas inside area */
1732 memcpy(mda_new
, mda
, sizeof(*mda
));
1733 memcpy(mdac_new
, mdac
, sizeof(*mdac
));
1734 mda_new
->metadata_locn
= mdac_new
;
1735 dm_list_add(mdas
, &mda_new
->list
);
1739 /* FIXME Cope with genuine pe_count 0 */
1741 /* If missing, estimate pv->size from file-based metadata */
1742 if (!pv
->size
&& pv
->pe_count
)
1743 pv
->size
= pv
->pe_count
* (uint64_t) vg
->extent_size
+
1744 pv
->pe_start
+ mda_size2
;
1746 /* Recalculate number of extents that will fit */
1747 if (!pv
->pe_count
) {
1748 pe_count
= (pv
->size
- pv
->pe_start
- mda_size2
) /
1750 if (pe_count
> UINT32_MAX
) {
1751 log_error("PV %s too large for extent size %s.",
1753 display_size(vg
->cmd
, (uint64_t) vg
->extent_size
));
1756 pv
->pe_count
= (uint32_t) pe_count
;
1759 /* Unlike LVM1, we don't store this outside a VG */
1760 /* FIXME Default from config file? vgextend cmdline flag? */
1761 pv
->status
|= ALLOCATABLE_PV
;
1764 pv
->pe_start
= pe_start
;
1766 if (!data_alignment
)
1767 data_alignment
= find_config_tree_int(pv
->fmt
->cmd
,
1768 "devices/data_alignment",
1771 if (set_pe_align(pv
, data_alignment
) != data_alignment
&&
1773 log_warn("WARNING: %s: Overriding data alignment to "
1774 "%lu sectors (requested %lu sectors)",
1775 pv_dev_name(pv
), pv
->pe_align
, data_alignment
);
1777 if (set_pe_align_offset(pv
, data_alignment_offset
) != data_alignment_offset
&&
1778 data_alignment_offset
)
1779 log_warn("WARNING: %s: Overriding data alignment offset to "
1780 "%lu sectors (requested %lu sectors)",
1781 pv_dev_name(pv
), pv
->pe_align_offset
, data_alignment_offset
);
1783 if (pv
->pe_align
< pv
->pe_align_offset
) {
1784 log_error("%s: pe_align (%lu sectors) must not be less "
1785 "than pe_align_offset (%lu sectors)",
1786 pv_dev_name(pv
), pv
->pe_align
, pv
->pe_align_offset
);
1791 * This initialization has a side-effect of allowing
1792 * orphaned PVs to be created with the proper alignment.
1793 * Setting pv->pe_start here circumvents .pv_write's
1794 * "pvcreate on PV without prior pvremove" retreival of
1795 * the PV's previous pe_start.
1796 * - Without this you get actual != expected pe_start
1797 * failures in the testsuite.
1799 if (!pe_start
&& pv
->pe_start
< pv
->pe_align
)
1800 pv
->pe_start
= pv
->pe_align
;
1803 pe_end
= pe_start
+ extent_count
* extent_size
- 1;
1804 if (!_mda_setup(fmt
, pe_start
, pe_end
, pvmetadatacopies
,
1805 pvmetadatasize
, mdas
, pv
, vg
))
1812 /* NULL vgname means use only the supplied context e.g. an archive file */
1813 static struct format_instance
*_text_create_text_instance(const struct format_type
1814 *fmt
, const char *vgname
,
1818 struct format_instance
*fid
;
1819 struct text_fid_context
*fidtc
;
1820 struct metadata_area
*mda
, *mda_new
;
1821 struct mda_context
*mdac
, *mdac_new
;
1822 struct dir_list
*dl
;
1823 struct raw_list
*rl
;
1824 struct dm_list
*dir_list
, *raw_list
, *mdas
;
1825 char path
[PATH_MAX
];
1826 struct lvmcache_vginfo
*vginfo
;
1827 struct lvmcache_info
*info
;
1829 if (!(fid
= dm_pool_alloc(fmt
->cmd
->mem
, sizeof(*fid
)))) {
1830 log_error("Couldn't allocate format instance object.");
1834 if (!(fidtc
= (struct text_fid_context
*)
1835 dm_pool_zalloc(fmt
->cmd
->mem
,sizeof(*fidtc
)))) {
1836 log_error("Couldn't allocate text_fid_context.");
1840 fidtc
->raw_metadata_buf
= NULL
;
1841 fid
->private = (void *) fidtc
;
1844 dm_list_init(&fid
->metadata_areas
);
1847 if (!(mda
= dm_pool_alloc(fmt
->cmd
->mem
, sizeof(*mda
))))
1849 mda
->ops
= &_metadata_text_file_backup_ops
;
1850 mda
->metadata_locn
= context
;
1851 dm_list_add(&fid
->metadata_areas
, &mda
->list
);
1853 dir_list
= &((struct mda_lists
*) fmt
->private)->dirs
;
1855 dm_list_iterate_items(dl
, dir_list
) {
1856 if (dm_snprintf(path
, PATH_MAX
, "%s/%s",
1857 dl
->dir
, vgname
) < 0) {
1858 log_error("Name too long %s/%s", dl
->dir
,
1863 context
= create_text_context(fmt
->cmd
, path
, NULL
);
1864 if (!(mda
= dm_pool_alloc(fmt
->cmd
->mem
, sizeof(*mda
))))
1866 mda
->ops
= &_metadata_text_file_ops
;
1867 mda
->metadata_locn
= context
;
1868 dm_list_add(&fid
->metadata_areas
, &mda
->list
);
1871 raw_list
= &((struct mda_lists
*) fmt
->private)->raws
;
1873 dm_list_iterate_items(rl
, raw_list
) {
1874 /* FIXME Cache this; rescan below if some missing */
1875 if (!_raw_holds_vgname(fid
, &rl
->dev_area
, vgname
))
1878 if (!(mda
= dm_pool_alloc(fmt
->cmd
->mem
, sizeof(*mda
))))
1881 if (!(mdac
= dm_pool_alloc(fmt
->cmd
->mem
, sizeof(*mdac
))))
1883 mda
->metadata_locn
= mdac
;
1884 /* FIXME Allow multiple dev_areas inside area */
1885 memcpy(&mdac
->area
, &rl
->dev_area
, sizeof(mdac
->area
));
1886 mda
->ops
= &_metadata_text_raw_ops
;
1887 /* FIXME MISTAKE? mda->metadata_locn = context; */
1888 dm_list_add(&fid
->metadata_areas
, &mda
->list
);
1891 /* Scan PVs in VG for any further MDAs */
1892 lvmcache_label_scan(fmt
->cmd
, 0);
1893 if (!(vginfo
= vginfo_from_vgname(vgname
, vgid
)))
1895 dm_list_iterate_items(info
, &vginfo
->infos
) {
1897 dm_list_iterate_items(mda
, mdas
) {
1899 (struct mda_context
*) mda
->metadata_locn
;
1901 /* FIXME Check it holds this VG */
1902 if (!(mda_new
= dm_pool_alloc(fmt
->cmd
->mem
,
1906 if (!(mdac_new
= dm_pool_alloc(fmt
->cmd
->mem
,
1907 sizeof(*mdac_new
))))
1909 /* FIXME multiple dev_areas inside area */
1910 memcpy(mda_new
, mda
, sizeof(*mda
));
1911 memcpy(mdac_new
, mdac
, sizeof(*mdac
));
1912 mda_new
->metadata_locn
= mdac_new
;
1913 dm_list_add(&fid
->metadata_areas
, &mda_new
->list
);
1916 /* FIXME Check raw metadata area count - rescan if required */
1923 void *create_text_context(struct cmd_context
*cmd
, const char *path
,
1926 struct text_context
*tc
;
1929 if ((tmp
= strstr(path
, ".tmp")) && (tmp
== path
+ strlen(path
) - 4)) {
1930 log_error("%s: Volume group filename may not end in .tmp",
1935 if (!(tc
= dm_pool_alloc(cmd
->mem
, sizeof(*tc
))))
1938 if (!(tc
->path_live
= dm_pool_strdup(cmd
->mem
, path
)))
1941 if (!(tc
->path_edit
= dm_pool_alloc(cmd
->mem
, strlen(path
) + 5)))
1944 sprintf(tc
->path_edit
, "%s.tmp", path
);
1949 if (!(tc
->desc
= dm_pool_strdup(cmd
->mem
, desc
)))
1955 dm_pool_free(cmd
->mem
, tc
);
1957 log_error("Couldn't allocate text format context object.");
1961 static struct format_handler _text_handler
= {
1963 .pv_read
= _text_pv_read
,
1964 .pv_setup
= _text_pv_setup
,
1965 .pv_write
= _text_pv_write
,
1966 .vg_setup
= _text_vg_setup
,
1967 .lv_setup
= _text_lv_setup
,
1968 .create_instance
= _text_create_text_instance
,
1969 .destroy_instance
= _text_destroy_instance
,
1970 .destroy
= _text_destroy
1973 static int _add_dir(const char *dir
, struct dm_list
*dir_list
)
1975 struct dir_list
*dl
;
1977 if (dm_create_dir(dir
)) {
1978 if (!(dl
= dm_malloc(sizeof(struct dm_list
) + strlen(dir
) + 1))) {
1979 log_error("_add_dir allocation failed");
1982 log_very_verbose("Adding text format metadata dir: %s", dir
);
1983 strcpy(dl
->dir
, dir
);
1984 dm_list_add(dir_list
, &dl
->list
);
1991 static int _get_config_disk_area(struct cmd_context
*cmd
,
1992 struct config_node
*cn
, struct dm_list
*raw_list
)
1994 struct device_area dev_area
;
1998 if (!(cn
= cn
->child
)) {
1999 log_error("Empty metadata disk_area section of config file");
2003 if (!get_config_uint64(cn
, "start_sector", &dev_area
.start
)) {
2004 log_error("Missing start_sector in metadata disk_area section "
2008 dev_area
.start
<<= SECTOR_SHIFT
;
2010 if (!get_config_uint64(cn
, "size", &dev_area
.size
)) {
2011 log_error("Missing size in metadata disk_area section "
2015 dev_area
.size
<<= SECTOR_SHIFT
;
2017 if (!get_config_str(cn
, "id", &id_str
)) {
2018 log_error("Missing uuid in metadata disk_area section "
2023 if (!id_read_format(&id
, id_str
)) {
2024 log_error("Invalid uuid in metadata disk_area section "
2025 "of config file: %s", id_str
);
2029 if (!(dev_area
.dev
= device_from_pvid(cmd
, &id
))) {
2030 char buffer
[64] __attribute((aligned(8)));
2032 if (!id_write_format(&id
, buffer
, sizeof(buffer
)))
2033 log_error("Couldn't find device.");
2035 log_error("Couldn't find device with uuid '%s'.",
2041 return _add_raw(raw_list
, &dev_area
);
2044 struct format_type
*create_text_format(struct cmd_context
*cmd
)
2046 struct format_type
*fmt
;
2047 struct config_node
*cn
;
2048 struct config_value
*cv
;
2049 struct mda_lists
*mda_lists
;
2051 if (!(fmt
= dm_malloc(sizeof(*fmt
))))
2055 fmt
->ops
= &_text_handler
;
2056 fmt
->name
= FMT_TEXT_NAME
;
2057 fmt
->alias
= FMT_TEXT_ALIAS
;
2058 fmt
->orphan_vg_name
= ORPHAN_VG_NAME(FMT_TEXT_NAME
);
2059 fmt
->features
= FMT_SEGMENTS
| FMT_MDAS
| FMT_TAGS
| FMT_PRECOMMIT
|
2060 FMT_UNLIMITED_VOLS
| FMT_RESIZE_PV
|
2061 FMT_UNLIMITED_STRIPESIZE
;
2063 if (!(mda_lists
= dm_malloc(sizeof(struct mda_lists
)))) {
2064 log_error("Failed to allocate dir_list");
2069 dm_list_init(&mda_lists
->dirs
);
2070 dm_list_init(&mda_lists
->raws
);
2071 mda_lists
->file_ops
= &_metadata_text_file_ops
;
2072 mda_lists
->raw_ops
= &_metadata_text_raw_ops
;
2073 fmt
->private = (void *) mda_lists
;
2075 if (!(fmt
->labeller
= text_labeller_create(fmt
))) {
2076 log_error("Couldn't create text label handler.");
2081 if (!(label_register_handler(FMT_TEXT_NAME
, fmt
->labeller
))) {
2082 log_error("Couldn't register text label handler.");
2087 if ((cn
= find_config_tree_node(cmd
, "metadata/dirs"))) {
2088 for (cv
= cn
->v
; cv
; cv
= cv
->next
) {
2089 if (cv
->type
!= CFG_STRING
) {
2090 log_error("Invalid string in config file: "
2095 if (!_add_dir(cv
->v
.str
, &mda_lists
->dirs
)) {
2096 log_error("Failed to add %s to text format "
2097 "metadata directory list ", cv
->v
.str
);
2103 if ((cn
= find_config_tree_node(cmd
, "metadata/disk_areas"))) {
2104 for (cn
= cn
->child
; cn
; cn
= cn
->sib
) {
2105 if (!_get_config_disk_area(cmd
, cn
, &mda_lists
->raws
))
2110 log_very_verbose("Initialised format: %s", fmt
->name
);
2115 _free_dirs(&mda_lists
->dirs
);