Initial import of binutils 2.22 on the new vendor branch
[dragonfly.git] / contrib / lvm2 / dist / lib / format_text / format-text.c
1 /*      $NetBSD: format-text.c,v 1.1.1.3 2009/12/02 00:26:32 haad Exp $ */
2
3 /*
4  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5  * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
6  *
7  * This file is part of LVM2.
8  *
9  * This copyrighted material is made available to anyone wishing to use,
10  * modify, copy, or redistribute it subject to the terms and conditions
11  * of the GNU Lesser General Public License v.2.1.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; if not, write to the Free Software Foundation,
15  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16  */
17
18 #include "lib.h"
19 #include "format-text.h"
20 #include "import-export.h"
21 #include "device.h"
22 #include "lvm-file.h"
23 #include "config.h"
24 #include "display.h"
25 #include "toolcontext.h"
26 #include "lvm-string.h"
27 #include "uuid.h"
28 #include "layout.h"
29 #include "crc.h"
30 #include "xlate.h"
31 #include "label.h"
32 #include "memlock.h"
33 #include "lvmcache.h"
34
35 #include <unistd.h>
36 #include <sys/file.h>
37 #include <sys/param.h>
38 #include <limits.h>
39 #include <dirent.h>
40 #include <ctype.h>
41
42 static struct mda_header *_raw_read_mda_header(const struct format_type *fmt,
43                                                struct device_area *dev_area);
44
45 static struct format_instance *_text_create_text_instance(const struct format_type
46                                                      *fmt, const char *vgname,
47                                                      const char *vgid,
48                                                      void *context);
49
50 struct text_fid_context {
51         char *raw_metadata_buf;
52         uint32_t raw_metadata_buf_size;
53 };
54
55 struct dir_list {
56         struct dm_list list;
57         char dir[0];
58 };
59
60 struct raw_list {
61         struct dm_list list;
62         struct device_area dev_area;
63 };
64
65 struct text_context {
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 */
69 };
70
71 /*
72  * NOTE: Currently there can be only one vg per text file.
73  */
74
75 static int _text_vg_setup(struct format_instance *fid __attribute((unused)),
76                           struct volume_group *vg)
77 {
78         if (vg->extent_size & (vg->extent_size - 1)) {
79                 log_error("Extent size must be power of 2");
80                 return 0;
81         }
82
83         return 1;
84 }
85
86 static uint64_t _mda_free_sectors_raw(struct metadata_area *mda)
87 {
88         struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
89
90         return mdac->free_sectors;
91 }
92
93 static uint64_t _mda_total_sectors_raw(struct metadata_area *mda)
94 {
95         struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
96
97         return mdac->area.size >> SECTOR_SHIFT;
98 }
99
100 /*
101  * Check if metadata area belongs to vg
102  */
103 static int _mda_in_vg_raw(struct format_instance *fid __attribute((unused)),
104                              struct volume_group *vg, struct metadata_area *mda)
105 {
106         struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
107         struct pv_list *pvl;
108
109         dm_list_iterate_items(pvl, &vg->pvs)
110                 if (pvl->pv->dev == mdac->area.dev)
111                         return 1;
112
113         return 0;
114 }
115
116 /*
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
120  * metadata.
121  *
122  * Parameters:
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
127  */
128 static uint64_t _get_prev_sector_circular(uint64_t region_start,
129                                           uint64_t region_size,
130                                           uint64_t region_ptr)
131 {
132         if (region_ptr >= region_start + SECTOR_SIZE)
133                 return region_ptr - SECTOR_SIZE;
134         else
135                 return (region_start + region_size - SECTOR_SIZE);
136 }
137
138 /*
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)
144  */
145 static int _pv_analyze_mda_raw (const struct format_type * fmt,
146                                 struct metadata_area *mda)
147 {
148         struct mda_header *mdah;
149         struct raw_locn *rlocn;
150         uint64_t area_start;
151         uint64_t area_size;
152         uint64_t prev_sector, prev_sector2;
153         uint64_t latest_mrec_offset;
154         int i;
155         uint64_t offset;
156         uint64_t offset2;
157         size_t size;
158         size_t size2;
159         char *buf=NULL;
160         struct device_area *area;
161         struct mda_context *mdac;
162         int r=0;
163
164         mdac = (struct mda_context *) mda->metadata_locn;
165
166         log_print("Found text metadata area: offset=%" PRIu64 ", size=%"
167                   PRIu64, mdac->area.start, mdac->area.size);
168         area = &mdac->area;
169
170         if (!dev_open(area->dev))
171                 return_0;
172
173         if (!(mdah = _raw_read_mda_header(fmt, area)))
174                 goto_out;
175
176         rlocn = mdah->raw_locns;
177
178         /*
179          * The device area includes the metadata header as well as the
180          * records, so remove the metadata header from the start and size
181          */
182         area_start = area->start + MDA_HEADER_SIZE;
183         area_size = area->size - MDA_HEADER_SIZE;
184         latest_mrec_offset = rlocn->offset + area->start;
185
186         /*
187          * Start searching at rlocn (point of live metadata) and go
188          * backwards.
189          */
190         prev_sector = _get_prev_sector_circular(area_start, area_size,
191                                                latest_mrec_offset);
192         offset = prev_sector;
193         size = SECTOR_SIZE;
194         offset2 = size2 = 0;
195         i = 0;
196         while (prev_sector != latest_mrec_offset) {
197                 prev_sector2 = prev_sector;
198                 prev_sector = _get_prev_sector_circular(area_start, area_size,
199                                                         prev_sector);
200                 if (prev_sector > prev_sector2)
201                         goto_out;
202                 /*
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).
209                  */
210                 if (!(buf = dm_pool_alloc(fmt->cmd->mem, size + size2)))
211                         goto_out;
212
213                 if (!dev_read_circular(area->dev, offset, size,
214                                        offset2, size2, buf))
215                         goto_out;
216
217                 /*
218                  * FIXME: We could add more sophisticated metadata detection
219                  */
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;
228                         size = SECTOR_SIZE;
229                         offset2 = size2 = 0;
230                 } else {
231                         /*
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.
236                          */
237                         if (prev_sector > offset) {
238                                 offset2 = prev_sector;
239                                 size2 += SECTOR_SIZE;
240                         } else {
241                                 offset = prev_sector;
242                                 size += SECTOR_SIZE;
243                         }
244                 }
245                 dm_pool_free(fmt->cmd->mem, buf);
246                 buf = NULL;
247         }
248
249         r = 1;
250  out:
251         if (buf)
252                 dm_pool_free(fmt->cmd->mem, buf);
253         if (!dev_close(area->dev))
254                 stack;
255         return r;
256 }
257
258
259
260 static int _text_lv_setup(struct format_instance *fid __attribute((unused)),
261                           struct logical_volume *lv)
262 {
263 /******** FIXME Any LV size restriction?
264         uint64_t max_size = UINT_MAX;
265
266         if (lv->size > max_size) {
267                 char *dummy = display_size(max_size);
268                 log_error("logical volumes cannot be larger than %s", dummy);
269                 dm_free(dummy);
270                 return 0;
271         }
272 */
273
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);
277                 return 0;
278         }
279
280         return 1;
281 }
282
283 static void _xlate_mdah(struct mda_header *mdah)
284 {
285         struct raw_locn *rl;
286
287         mdah->version = xlate32(mdah->version);
288         mdah->start = xlate64(mdah->start);
289         mdah->size = xlate64(mdah->size);
290
291         rl = &mdah->raw_locns[0];
292         while (rl->offset) {
293                 rl->checksum = xlate32(rl->checksum);
294                 rl->offset = xlate64(rl->offset);
295                 rl->size = xlate64(rl->size);
296                 rl++;
297         }
298 }
299
300 static struct mda_header *_raw_read_mda_header(const struct format_type *fmt,
301                                                struct device_area *dev_area)
302 {
303         struct mda_header *mdah;
304
305         if (!(mdah = dm_pool_alloc(fmt->cmd->mem, MDA_HEADER_SIZE))) {
306                 log_error("struct mda_header allocation failed");
307                 return NULL;
308         }
309
310         if (!dev_read(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, mdah))
311                 goto_bad;
312
313         if (mdah->checksum_xl != xlate32(calc_crc(INITIAL_CRC, mdah->magic,
314                                                   MDA_HEADER_SIZE -
315                                                   sizeof(mdah->checksum_xl)))) {
316                 log_error("Incorrect metadata area header checksum");
317                 goto bad;
318         }
319
320         _xlate_mdah(mdah);
321
322         if (strncmp((char *)mdah->magic, FMTT_MAGIC, sizeof(mdah->magic))) {
323                 log_error("Wrong magic number in metadata area header");
324                 goto bad;
325         }
326
327         if (mdah->version != FMTT_VERSION) {
328                 log_error("Incompatible metadata area header version: %d",
329                           mdah->version);
330                 goto bad;
331         }
332
333         if (mdah->start != dev_area->start) {
334                 log_error("Incorrect start sector in metadata area header: %"
335                           PRIu64, mdah->start);
336                 goto bad;
337         }
338
339         return mdah;
340
341 bad:
342         dm_pool_free(fmt->cmd->mem, mdah);
343         return NULL;
344 }
345
346 static int _raw_write_mda_header(const struct format_type *fmt,
347                                  struct device *dev,
348                                  uint64_t start_byte, struct mda_header *mdah)
349 {
350         strncpy((char *)mdah->magic, FMTT_MAGIC, sizeof(mdah->magic));
351         mdah->version = FMTT_VERSION;
352         mdah->start = start_byte;
353
354         _xlate_mdah(mdah);
355         mdah->checksum_xl = xlate32(calc_crc(INITIAL_CRC, mdah->magic,
356                                              MDA_HEADER_SIZE -
357                                              sizeof(mdah->checksum_xl)));
358
359         if (!dev_write(dev, start_byte, MDA_HEADER_SIZE, mdah))
360                 return_0;
361
362         return 1;
363 }
364
365 static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
366                                        struct mda_header *mdah,
367                                        const char *vgname,
368                                        int *precommitted)
369 {
370         size_t len;
371         char vgnamebuf[NAME_LEN + 2] __attribute((aligned(8)));
372         struct raw_locn *rlocn, *rlocn_precommitted;
373         struct lvmcache_info *info;
374
375         rlocn = mdah->raw_locns;        /* Slot 0 */
376         rlocn_precommitted = rlocn + 1; /* Slot 1 */
377
378         /* Should we use precommitted metadata? */
379         if (*precommitted && rlocn_precommitted->size &&
380             (rlocn_precommitted->offset != rlocn->offset)) {
381                 rlocn = rlocn_precommitted;
382         } else
383                 *precommitted = 0;
384
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))
389                 goto_bad;
390
391         if (!strncmp(vgnamebuf, vgname, len = strlen(vgname)) &&
392             (isspace(vgnamebuf[len]) || vgnamebuf[len] == '{')) {
393                 return rlocn;
394         }
395
396       bad:
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);
400
401         return NULL;
402 }
403
404 /*
405  * Determine offset for uncommitted metadata
406  */
407 static uint64_t _next_rlocn_offset(struct raw_locn *rlocn,
408                                    struct mda_header *mdah)
409 {
410         if (!rlocn)
411                 /* Find an empty slot */
412                 /* FIXME Assume only one VG per mdah for now */
413                 return MDA_HEADER_SIZE;
414
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))
419                + MDA_HEADER_SIZE;
420 }
421
422 static int _raw_holds_vgname(struct format_instance *fid,
423                              struct device_area *dev_area, const char *vgname)
424 {
425         int r = 0;
426         int noprecommit = 0;
427         struct mda_header *mdah;
428
429         if (!dev_open(dev_area->dev))
430                 return_0;
431
432         if (!(mdah = _raw_read_mda_header(fid->fmt, dev_area)))
433                 return_0;
434
435         if (_find_vg_rlocn(dev_area, mdah, vgname, &noprecommit))
436                 r = 1;
437
438         if (!dev_close(dev_area->dev))
439                 stack;
440
441         return r;
442 }
443
444 static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
445                                               const char *vgname,
446                                               struct device_area *area,
447                                               int precommitted)
448 {
449         struct volume_group *vg = NULL;
450         struct raw_locn *rlocn;
451         struct mda_header *mdah;
452         time_t when;
453         char *desc;
454         uint32_t wrap = 0;
455
456         if (!dev_open(area->dev))
457                 return_NULL;
458
459         if (!(mdah = _raw_read_mda_header(fid->fmt, area)))
460                 goto_out;
461
462         if (!(rlocn = _find_vg_rlocn(area, mdah, vgname, &precommitted))) {
463                 log_debug("VG %s not found on %s", vgname, dev_name(area->dev));
464                 goto out;
465         }
466
467         if (rlocn->offset + rlocn->size > mdah->size)
468                 wrap = (uint32_t) ((rlocn->offset + rlocn->size) - mdah->size);
469
470         if (wrap > rlocn->offset) {
471                 log_error("VG %s metadata too large for circular buffer",
472                           vg->name);
473                 goto out;
474         }
475
476         /* FIXME 64-bit */
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,
482                                      &desc)))
483                 goto_out;
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);
488
489         if (precommitted)
490                 vg->status |= PRECOMMITTED;
491
492       out:
493         if (!dev_close(area->dev))
494                 stack;
495
496         return vg;
497 }
498
499 static struct volume_group *_vg_read_raw(struct format_instance *fid,
500                                          const char *vgname,
501                                          struct metadata_area *mda)
502 {
503         struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
504
505         return _vg_read_raw_area(fid, vgname, &mdac->area, 0);
506 }
507
508 static struct volume_group *_vg_read_precommit_raw(struct format_instance *fid,
509                                                    const char *vgname,
510                                                    struct metadata_area *mda)
511 {
512         struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
513
514         return _vg_read_raw_area(fid, vgname, &mdac->area, 1);
515 }
516
517 static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
518                          struct metadata_area *mda)
519 {
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;
524         struct pv_list *pvl;
525         int r = 0;
526        uint64_t new_wrap = 0, old_wrap = 0, new_end;
527         int found = 0;
528         int noprecommit = 0;
529
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) {
533                         found = 1;
534                         break;
535                 }
536         }
537
538         if (!found)
539                 return 1;
540
541         if (!dev_open(mdac->area.dev))
542                 return_0;
543
544         if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area)))
545                 goto_out;
546
547         rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit);
548         mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah);
549
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);
554                 goto out;
555         }
556
557         mdac->rlocn.size = fidtc->raw_metadata_buf_size;
558
559         if (mdac->rlocn.offset + mdac->rlocn.size > mdah->size)
560                 new_wrap = (mdac->rlocn.offset + mdac->rlocn.size) - mdah->size;
561
562         if (rlocn && (rlocn->offset + rlocn->size > mdah->size))
563                 old_wrap = (rlocn->offset + rlocn->size) - mdah->size;
564
565         new_end = new_wrap ? new_wrap + MDA_HEADER_SIZE :
566                             mdac->rlocn.offset + mdac->rlocn.size;
567
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",
572                           vg->name);
573                 goto out;
574         }
575
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);
579
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))
584                 goto_out;
585
586         if (new_wrap) {
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);
590
591                 if (!dev_write(mdac->area.dev,
592                                mdac->area.start + MDA_HEADER_SIZE,
593                                (size_t) new_wrap,
594                                fidtc->raw_metadata_buf +
595                                mdac->rlocn.size - new_wrap))
596                         goto_out;
597         }
598
599         mdac->rlocn.checksum = calc_crc(INITIAL_CRC, fidtc->raw_metadata_buf,
600                                         (uint32_t) (mdac->rlocn.size -
601                                                     new_wrap));
602         if (new_wrap)
603                 mdac->rlocn.checksum = calc_crc(mdac->rlocn.checksum,
604                                                 fidtc->raw_metadata_buf +
605                                                 mdac->rlocn.size -
606                                                 new_wrap, (uint32_t) new_wrap);
607
608         r = 1;
609
610       out:
611         if (!r) {
612                 if (!dev_close(mdac->area.dev))
613                         stack;
614
615                 if (fidtc->raw_metadata_buf) {
616                         dm_free(fidtc->raw_metadata_buf);
617                         fidtc->raw_metadata_buf = NULL;
618                 }
619         }
620
621         return r;
622 }
623
624 static int _vg_commit_raw_rlocn(struct format_instance *fid,
625                                 struct volume_group *vg,
626                                 struct metadata_area *mda,
627                                 int precommit)
628 {
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;
633         struct pv_list *pvl;
634         int r = 0;
635         int found = 0;
636         int noprecommit = 0;
637
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) {
641                         found = 1;
642                         break;
643                 }
644         }
645
646         if (!found)
647                 return 1;
648
649         if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area)))
650                 goto_out;
651
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];
663         }
664
665         if (precommit)
666                 rlocn++;
667         else {
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;
672         }
673
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);
682         } else
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);
686
687         if (!_raw_write_mda_header(fid->fmt, mdac->area.dev, mdac->area.start,
688                                    mdah)) {
689                 dm_pool_free(fid->fmt->cmd->mem, mdah);
690                 log_error("Failed to write metadata area header");
691                 goto out;
692         }
693
694         r = 1;
695
696       out:
697         if (!precommit) {
698                 if (!dev_close(mdac->area.dev))
699                         stack;
700                 if (fidtc->raw_metadata_buf) {
701                         dm_free(fidtc->raw_metadata_buf);
702                         fidtc->raw_metadata_buf = NULL;
703                 }
704         }
705
706         return r;
707 }
708
709 static int _vg_commit_raw(struct format_instance *fid, struct volume_group *vg,
710                           struct metadata_area *mda)
711 {
712         return _vg_commit_raw_rlocn(fid, vg, mda, 0);
713 }
714
715 static int _vg_precommit_raw(struct format_instance *fid,
716                              struct volume_group *vg,
717                              struct metadata_area *mda)
718 {
719         return _vg_commit_raw_rlocn(fid, vg, mda, 1);
720 }
721
722 /* Close metadata area devices */
723 static int _vg_revert_raw(struct format_instance *fid, struct volume_group *vg,
724                           struct metadata_area *mda)
725 {
726         struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
727         struct pv_list *pvl;
728         int found = 0;
729
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) {
733                         found = 1;
734                         break;
735                 }
736         }
737
738         if (!found)
739                 return 1;
740
741         /* Wipe pre-committed metadata */
742         mdac->rlocn.size = 0;
743         return _vg_commit_raw_rlocn(fid, vg, mda, 0);
744 }
745
746 static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
747                           struct metadata_area *mda)
748 {
749         struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
750         struct mda_header *mdah;
751         struct raw_locn *rlocn;
752         int r = 0;
753         int noprecommit = 0;
754
755         if (!dev_open(mdac->area.dev))
756                 return_0;
757
758         if (!(mdah = _raw_read_mda_header(fid->fmt, &mdac->area)))
759                 goto_out;
760
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;
764         }
765
766         rlocn->offset = 0;
767         rlocn->size = 0;
768         rlocn->checksum = 0;
769
770         if (!_raw_write_mda_header(fid->fmt, mdac->area.dev, mdac->area.start,
771                                    mdah)) {
772                 dm_pool_free(fid->fmt->cmd->mem, mdah);
773                 log_error("Failed to write metadata area header");
774                 goto out;
775         }
776
777         r = 1;
778
779       out:
780         if (!dev_close(mdac->area.dev))
781                 stack;
782
783         return r;
784 }
785
786 static struct volume_group *_vg_read_file_name(struct format_instance *fid,
787                                                const char *vgname,
788                                                const char *read_path)
789 {
790         struct volume_group *vg;
791         time_t when;
792         char *desc;
793
794         if (!(vg = text_vg_import_file(fid, read_path, &when, &desc)))
795                 return_NULL;
796
797         /*
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.
801          */
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'.",
805                           read_path, vgname);
806                 return NULL;
807         } else
808                 log_debug("Read volume group %s from %s", vg->name, read_path);
809
810         return vg;
811 }
812
813 static struct volume_group *_vg_read_file(struct format_instance *fid,
814                                           const char *vgname,
815                                           struct metadata_area *mda)
816 {
817         struct text_context *tc = (struct text_context *) mda->metadata_locn;
818
819         return _vg_read_file_name(fid, vgname, tc->path_live);
820 }
821
822 static struct volume_group *_vg_read_precommit_file(struct format_instance *fid,
823                                                     const char *vgname,
824                                                     struct metadata_area *mda)
825 {
826         struct text_context *tc = (struct text_context *) mda->metadata_locn;
827         struct volume_group *vg;
828
829         if ((vg = _vg_read_file_name(fid, vgname, tc->path_edit)))
830                 vg->status |= PRECOMMITTED;
831         else
832                 vg = _vg_read_file_name(fid, vgname, tc->path_live);
833
834         return vg;
835 }
836
837 static int _vg_write_file(struct format_instance *fid __attribute((unused)),
838                           struct volume_group *vg, struct metadata_area *mda)
839 {
840         struct text_context *tc = (struct text_context *) mda->metadata_locn;
841
842         FILE *fp;
843         int fd;
844         char *slash;
845         char temp_file[PATH_MAX], temp_dir[PATH_MAX];
846
847         slash = strrchr(tc->path_edit, '/');
848
849         if (slash == 0)
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';
855
856         } else {
857                 log_error("Text format failed to determine directory.");
858                 return 0;
859         }
860
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.");
864                 return 0;
865         }
866
867         if (!(fp = fdopen(fd, "w"))) {
868                 log_sys_error("fdopen", temp_file);
869                 if (close(fd))
870                         log_sys_error("fclose", temp_file);
871                 return 0;
872         }
873
874         log_debug("Writing %s metadata to %s", vg->name, temp_file);
875
876         if (!text_vg_export_file(vg, tc->desc, fp)) {
877                 log_error("Failed to write metadata to %s.", temp_file);
878                 if (fclose(fp))
879                         log_sys_error("fclose", temp_file);
880                 return 0;
881         }
882
883         if (fsync(fd) && (errno != EROFS) && (errno != EINVAL)) {
884                 log_sys_error("fsync", tc->path_edit);
885                 if (fclose(fp))
886                         log_sys_error("fclose", tc->path_edit);
887                 return 0;
888         }
889
890         if (lvm_fclose(fp, tc->path_edit))
891                 return_0;
892
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));
897                 return 0;
898         }
899
900         return 1;
901 }
902
903 static int _vg_commit_file_backup(struct format_instance *fid __attribute((unused)),
904                                   struct volume_group *vg,
905                                   struct metadata_area *mda)
906 {
907         struct text_context *tc = (struct text_context *) mda->metadata_locn;
908
909         if (test_mode()) {
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);
915                         return 0;
916                 }
917         } else {
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));
923                         return 0;
924                 }
925         }
926
927         sync_dir(tc->path_edit);
928
929         return 1;
930 }
931
932 static int _vg_commit_file(struct format_instance *fid, struct volume_group *vg,
933                            struct metadata_area *mda)
934 {
935         struct text_context *tc = (struct text_context *) mda->metadata_locn;
936         char *slash;
937         char new_name[PATH_MAX];
938         size_t len;
939
940         if (!_vg_commit_file_backup(fid, vg, mda))
941                 return 0;
942
943         /* vgrename? */
944         if ((slash = strrchr(tc->path_live, '/')))
945                 slash = slash + 1;
946         else
947                 slash = tc->path_live;
948
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);
954                 if (test_mode())
955                         log_verbose("Test mode: Skipping rename");
956                 else {
957                         if (rename(tc->path_live, new_name)) {
958                                 log_error("%s: rename to %s failed: %s",
959                                           tc->path_live, new_name,
960                                           strerror(errno));
961                                 sync_dir(new_name);
962                                 return 0;
963                         }
964                 }
965         }
966
967         return 1;
968 }
969
970 static int _vg_remove_file(struct format_instance *fid __attribute((unused)),
971                            struct volume_group *vg __attribute((unused)),
972                            struct metadata_area *mda)
973 {
974         struct text_context *tc = (struct text_context *) mda->metadata_locn;
975
976         if (path_exists(tc->path_edit) && unlink(tc->path_edit)) {
977                 log_sys_error("unlink", tc->path_edit);
978                 return 0;
979         }
980
981         if (path_exists(tc->path_live) && unlink(tc->path_live)) {
982                 log_sys_error("unlink", tc->path_live);
983                 return 0;
984         }
985
986         sync_dir(tc->path_live);
987
988         return 1;
989 }
990
991 static int _scan_file(const struct format_type *fmt)
992 {
993         struct dirent *dirent;
994         struct dir_list *dl;
995         struct dm_list *dir_list;
996         char *tmp;
997         DIR *d;
998         struct volume_group *vg;
999         struct format_instance *fid;
1000         char path[PATH_MAX];
1001         char *vgname;
1002
1003         dir_list = &((struct mda_lists *) fmt->private)->dirs;
1004
1005         dm_list_iterate_items(dl, dir_list) {
1006                 if (!(d = opendir(dl->dir))) {
1007                         log_sys_error("opendir", dl->dir);
1008                         continue;
1009                 }
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)
1015                              - 4)) {
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",
1020                                                   dl->dir, vgname);
1021                                         break;
1022                                 }
1023
1024                                 /* FIXME stat file to see if it's changed */
1025                                 fid = _text_create_text_instance(fmt, NULL, NULL,
1026                                                             NULL);
1027                                 if ((vg = _vg_read_file_name(fid, vgname,
1028                                                              path)))
1029                                         /* FIXME Store creation host in vg */
1030                                         lvmcache_update_vg(vg, 0);
1031                         }
1032
1033                 if (closedir(d))
1034                         log_sys_error("closedir", dl->dir);
1035         }
1036
1037         return 1;
1038 }
1039
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)
1044 {
1045         struct raw_locn *rlocn;
1046         struct mda_header *mdah;
1047         uint32_t wrap = 0;
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;
1053
1054         if (mda_free_sectors)
1055                 *mda_free_sectors = ((dev_area->size - MDA_HEADER_SIZE) / 2) >> SECTOR_SHIFT;
1056
1057         if (!dev_open(dev_area->dev))
1058                 return_NULL;
1059
1060         if (!(mdah = _raw_read_mda_header(fmt, dev_area)))
1061                 goto_out;
1062
1063         /* FIXME Cope with returning a list */
1064         rlocn = mdah->raw_locns;
1065
1066         /*
1067          * If no valid offset, do not try to search for vgname
1068          */
1069         if (!rlocn->offset)
1070                 goto out;
1071
1072         /* Do quick check for a vgname */
1073         if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
1074                       NAME_LEN, buf))
1075                 goto_out;
1076
1077         while (buf[len] && !isspace(buf[len]) && buf[len] != '{' &&
1078                len < (NAME_LEN - 1))
1079                 len++;
1080
1081         buf[len] = '\0';
1082
1083         /* Ignore this entry if the characters aren't permissible */
1084         if (!validate_name(buf))
1085                 goto_out;
1086
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);
1090
1091         if (wrap > rlocn->offset) {
1092                 log_error("%s: metadata too large for circular buffer",
1093                           dev_name(dev_area->dev));
1094                 goto out;
1095         }
1096
1097         /* FIXME 64-bit */
1098         if (!(vgname = text_vgname_import(fmt, dev_area->dev,
1099                                           (off_t) (dev_area->start +
1100                                                    rlocn->offset),
1101                                           (uint32_t) (rlocn->size - wrap),
1102                                           (off_t) (dev_area->start +
1103                                                    MDA_HEADER_SIZE),
1104                                           wrap, calc_crc, rlocn->checksum,
1105                                           vgid, vgstatus, creation_host)))
1106                 goto_out;
1107
1108         /* Ignore this entry if the characters aren't permissible */
1109         if (!validate_name(vgname)) {
1110                 vgname = NULL;
1111                 goto_out;
1112         }
1113
1114         if (!id_write_format(vgid, uuid, sizeof(uuid))) {
1115                 vgname = NULL;
1116                 goto_out;
1117         }
1118
1119         log_debug("%s: Found metadata at %" PRIu64 " size %" PRIu64
1120                   " (in area at %" PRIu64 " size %" PRIu64
1121                   ") for %s (%s)",
1122                   dev_name(dev_area->dev), dev_area->start + rlocn->offset,
1123                   rlocn->size, dev_area->start, dev_area->size, vgname, uuid);
1124
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;
1129
1130                 if (current_usage * 2 >= buffer_size)
1131                         *mda_free_sectors = UINT64_C(0);
1132                 else
1133                         *mda_free_sectors = ((buffer_size - 2 * current_usage) / 2) >> SECTOR_SHIFT;
1134         }
1135
1136       out:
1137         if (!dev_close(dev_area->dev))
1138                 stack;
1139
1140         return vgname;
1141 }
1142
1143 static int _scan_raw(const struct format_type *fmt)
1144 {
1145         struct raw_list *rl;
1146         struct dm_list *raw_list;
1147         const char *vgname;
1148         struct volume_group *vg;
1149         struct format_instance fid;
1150         struct id vgid;
1151         uint32_t vgstatus;
1152
1153         raw_list = &((struct mda_lists *) fmt->private)->raws;
1154
1155         fid.fmt = fmt;
1156         dm_list_init(&fid.metadata_areas);
1157
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,
1161                                               NULL, NULL))) {
1162                         if ((vg = _vg_read_raw_area(&fid, vgname,
1163                                                     &rl->dev_area, 0)))
1164                                 lvmcache_update_vg(vg, 0);
1165                 }
1166         }
1167
1168         return 1;
1169 }
1170
1171 static int _text_scan(const struct format_type *fmt)
1172 {
1173         return (_scan_file(fmt) & _scan_raw(fmt));
1174 }
1175
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)))
1184 {
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();
1190
1191         if (!pvmetadatacopies)
1192                 return 1;
1193
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;
1199
1200         if (pe_end > disk_size) {
1201                 log_error("Physical extents end beyond end of device %s!",
1202                           pv_dev_name(pv));
1203                 return 0;
1204         }
1205
1206         /* Requested metadatasize */
1207         mda_size1 = pvmetadatasize << SECTOR_SHIFT;
1208
1209         /* Place mda straight after label area at start of disk */
1210         start1 = LABEL_SCAN_SIZE;
1211
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;
1216                 if (mda_adjustment)
1217                         start1 += (pagesize - mda_adjustment);
1218         }
1219
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);
1227         }
1228
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;
1236         }
1237
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",
1247                                   pv_dev_name(pv));
1248                         return 0;
1249                 }
1250                 /* Round up to pe_align boundary */
1251                 mda_adjustment = (mda_size1 + start1) % alignment;
1252                 if (mda_adjustment)
1253                         mda_size1 += (alignment - mda_adjustment);
1254                 /* Only have 1 mda in this case */
1255                 pvmetadatacopies = 1;
1256         }
1257
1258         /* If we already have PEs, avoid overlap */
1259         if (pe_start || pe_end) {
1260                 if (pe_start <= start1)
1261                         mda_size1 = 0;
1262                 else if (start1 + mda_size1 > pe_start)
1263                         mda_size1 = pe_start - start1;
1264         }
1265
1266         /* FIXME If creating new mdas, wipe them! */
1267         if (mda_size1) {
1268                 if (!add_mda(fmt, fmt->cmd->mem, mdas, pv->dev, start1,
1269                              mda_size1))
1270                         return 0;
1271
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");
1276                         return 0;
1277                 }
1278
1279                 if (pvmetadatacopies == 1)
1280                         return 1;
1281         } else
1282                 start1 = 0;
1283
1284         /* A second copy at end of disk */
1285         mda_size2 = pvmetadatasize << SECTOR_SHIFT;
1286
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;
1290
1291         mda_adjustment = (disk_size - mda_size2) % alignment;
1292         if (mda_adjustment)
1293                 mda_size2 += mda_adjustment;
1294
1295         start2 = disk_size - mda_size2;
1296
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);
1301                         start2 = pe_end;
1302                 }
1303         }
1304
1305         /* If we already have a first mda, avoid overlap */
1306         if (mda_size1) {
1307                 if (start2 < start1 + mda_size1) {
1308                         mda_size2 -= (start1 + mda_size1 - start2);
1309                         start2 = start1 + mda_size1;
1310                 }
1311                 /* No room for any PEs here now! */
1312         }
1313
1314         if (mda_size2) {
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");
1321                         return 0;
1322                 }
1323         } else
1324                 return 0;
1325
1326         return 1;
1327 }
1328
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)
1334 {
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;
1343
1344         /* FIXME Test mode don't update cache? */
1345
1346         if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev,
1347                                   FMT_TEXT_ORPHAN_VG_NAME, NULL, 0)))
1348                 return_0;
1349         label = info->label;
1350
1351         if (label_sector != -1)
1352                 label->sector = label_sector;
1353
1354         info->device_size = pv->size << SECTOR_SHIFT;
1355         info->fmt = fmt;
1356
1357         /* If mdas supplied, use them regardless of existing ones, */
1358         /* otherwise retain existing ones */
1359         if (mdas) {
1360                 if (info->mdas.n)
1361                         del_mdas(&info->mdas);
1362                 else
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);
1373                 }
1374                 /* FIXME Temporary until mda creation supported by tools */
1375         } else if (!info->mdas.n) {
1376                 dm_list_init(&info->mdas);
1377         }
1378
1379         /*
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)
1384          */
1385         if (info->das.n) {
1386                 if (!pv->pe_start)
1387                         dm_list_iterate_items(da, &info->das)
1388                                 pv->pe_start = da->disk_locn.offset >> SECTOR_SHIFT;
1389                 del_das(&info->das);
1390         } else
1391                 dm_list_init(&info->das);
1392
1393 #if 0
1394         /*
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!
1398          */
1399         if (pv->pe_start) {
1400                 log_very_verbose("%s: preserving pe_start=%lu",
1401                                  pv_dev_name(pv), pv->pe_start);
1402                 goto preserve_pe_start;
1403         }
1404 #endif
1405
1406         /*
1407          * If pe_start is still unset, set it to first aligned
1408          * sector after any metadata areas that begin before pe_start.
1409          */
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;
1414         }
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)
1424                             >> SECTOR_SHIFT;
1425                         /* Adjust pe_start to: (N * pe_align) + pe_align_offset */
1426                         if (pv->pe_align) {
1427                                 adjustment =
1428                                 (pv->pe_start - pv->pe_align_offset) % pv->pe_align;
1429                                 if (adjustment)
1430                                         pv->pe_start += pv->pe_align - adjustment;
1431
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,
1437                                          (adjustment ?
1438                                           pv->pe_start -= pv->pe_align - adjustment :
1439                                           pv->pe_start),
1440                                          pv->pe_align, pv->pe_align_offset, adjustment);
1441                         }
1442                 }
1443         }
1444         if (pv->pe_start >= pv->size) {
1445                 log_error("Data area is beyond end of device %s!",
1446                           pv_dev_name(pv));
1447                 return 0;
1448         }
1449
1450         /* FIXME: preserve_pe_start: */
1451         if (!add_da
1452             (NULL, &info->das, pv->pe_start << SECTOR_SHIFT, UINT64_C(0)))
1453                 return_0;
1454
1455         if (!dev_open(pv->dev))
1456                 return_0;
1457
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))
1465                                 stack;
1466                         return_0;
1467                 }
1468         }
1469
1470         if (!label_write(pv->dev, label)) {
1471                 dev_close(pv->dev);
1472                 return_0;
1473         }
1474
1475         if (!dev_close(pv->dev))
1476                 return_0;
1477
1478         return 1;
1479 }
1480
1481 static int _add_raw(struct dm_list *raw_list, struct device_area *dev_area)
1482 {
1483         struct raw_list *rl;
1484
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)
1490                         return 1;
1491         }
1492
1493         if (!(rl = dm_malloc(sizeof(struct raw_list)))) {
1494                 log_error("_add_raw allocation failed");
1495                 return 0;
1496         }
1497         memcpy(&rl->dev_area, dev_area, sizeof(*dev_area));
1498         dm_list_add(raw_list, &rl->list);
1499
1500         return 1;
1501 }
1502
1503 static int _get_pv_if_in_vg(struct lvmcache_info *info,
1504                             struct physical_volume *pv)
1505 {
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))
1510                 return 1;
1511
1512         return 0;
1513 }
1514
1515 static int _populate_pv_fields(struct lvmcache_info *info,
1516                                struct physical_volume *pv,
1517                                int scan_label_only)
1518 {
1519         struct data_area_list *da;
1520
1521         /* Have we already cached vgname? */
1522         if (!scan_label_only && _get_pv_if_in_vg(info, pv))
1523                 return 1;
1524
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);
1528
1529                 if (_get_pv_if_in_vg(info, pv))
1530                         return 1;
1531         }
1532
1533         /* Orphan */
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));
1539
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));
1544                 return 0;
1545         }
1546
1547         dm_list_iterate_items(da, &info->das)
1548                 pv->pe_start = da->disk_locn.offset >> SECTOR_SHIFT;
1549
1550         return 1;
1551 }
1552
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)
1556 {
1557         struct label *label;
1558         struct device *dev;
1559         struct lvmcache_info *info;
1560         struct metadata_area *mda, *mda_new;
1561         struct mda_context *mdac, *mdac_new;
1562
1563         if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter)))
1564                 return_0;
1565
1566         if (!(label_read(dev, &label, UINT64_C(0))))
1567                 return_0;
1568         info = (struct lvmcache_info *) label->info;
1569
1570         if (!_populate_pv_fields(info, pv, scan_label_only))
1571                 return 0;
1572
1573         if (!mdas)
1574                 return 1;
1575
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");
1581                         return 0;
1582                 }
1583                 if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem, sizeof(*mdac_new)))) {
1584                         log_error("metadata_area allocation failed");
1585                         return 0;
1586                 }
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);
1591         }
1592
1593         return 1;
1594 }
1595
1596 static void _text_destroy_instance(struct format_instance *fid __attribute((unused)))
1597 {
1598         return;
1599 }
1600
1601 static void _free_dirs(struct dm_list *dir_list)
1602 {
1603         struct dm_list *dl, *tmp;
1604
1605         dm_list_iterate_safe(dl, tmp, dir_list) {
1606                 dm_list_del(dl);
1607                 dm_free(dl);
1608         }
1609 }
1610
1611 static void _free_raws(struct dm_list *raw_list)
1612 {
1613         struct dm_list *rl, *tmp;
1614
1615         dm_list_iterate_safe(rl, tmp, raw_list) {
1616                 dm_list_del(rl);
1617                 dm_free(rl);
1618         }
1619 }
1620
1621 static void _text_destroy(const struct format_type *fmt)
1622 {
1623         if (fmt->private) {
1624                 _free_dirs(&((struct mda_lists *) fmt->private)->dirs);
1625                 _free_raws(&((struct mda_lists *) fmt->private)->raws);
1626                 dm_free(fmt->private);
1627         }
1628
1629         dm_free((void *)fmt);
1630 }
1631
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
1638 };
1639
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
1645 };
1646
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,
1659 };
1660
1661 /* pvmetadatasize in sectors */
1662 /*
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
1668  */
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)
1676 {
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;
1681         int found;
1682         uint64_t pe_end = 0;
1683         unsigned mda_count = 0;
1684         uint64_t mda_size2 = 0;
1685         uint64_t pe_count;
1686
1687         /* FIXME Cope with pvchange */
1688         /* FIXME Merge code with _text_create_text_instance */
1689
1690         /* If new vg, add any further mdas on this PV to the fid's mda list */
1691         if (vg) {
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) {
1696                                 mda_count++;
1697                                 mdac =
1698                                     (struct mda_context *) mda->metadata_locn;
1699
1700                                 /* FIXME Check it isn't already in use */
1701
1702                                 /* Reduce usable device size */
1703                                 if (mda_count > 1)
1704                                         mda_size2 = mdac->area.size >> SECTOR_SHIFT;
1705
1706                                 /* Ensure it isn't already on list */
1707                                 found = 0;
1708                                 dm_list_iterate_items(mda2, mdas) {
1709                                         if (mda2->ops !=
1710                                             &_metadata_text_raw_ops) continue;
1711                                         mdac2 =
1712                                             (struct mda_context *)
1713                                             mda2->metadata_locn;
1714                                         if (!memcmp
1715                                             (&mdac2->area, &mdac->area,
1716                                              sizeof(mdac->area))) {
1717                                                 found = 1;
1718                                                 break;
1719                                         }
1720                                 }
1721                                 if (found)
1722                                         continue;
1723
1724                                 if (!(mda_new = dm_pool_alloc(fmt->cmd->mem,
1725                                                            sizeof(*mda_new))))
1726                                         return_0;
1727
1728                                 if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem,
1729                                                             sizeof(*mdac_new))))
1730                                         return_0;
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);
1736                         }
1737                 }
1738
1739                 /* FIXME Cope with genuine pe_count 0 */
1740
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;
1745
1746                 /* Recalculate number of extents that will fit */
1747                 if (!pv->pe_count) {
1748                         pe_count = (pv->size - pv->pe_start - mda_size2) /
1749                                    vg->extent_size;
1750                         if (pe_count > UINT32_MAX) {
1751                                 log_error("PV %s too large for extent size %s.",
1752                                           pv_dev_name(pv),
1753                                           display_size(vg->cmd, (uint64_t) vg->extent_size));
1754                                 return 0;
1755                         }
1756                         pv->pe_count = (uint32_t) pe_count;
1757                 }
1758
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;
1762         } else {
1763                 if (pe_start)
1764                         pv->pe_start = pe_start;
1765
1766                 if (!data_alignment)
1767                         data_alignment = find_config_tree_int(pv->fmt->cmd,
1768                                                       "devices/data_alignment",
1769                                                       0) * 2;
1770
1771                 if (set_pe_align(pv, data_alignment) != data_alignment &&
1772                     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);
1776
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);
1782
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);
1787                         return 0;
1788                 }
1789
1790                 /*
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.
1798                  */
1799                 if (!pe_start && pv->pe_start < pv->pe_align)
1800                         pv->pe_start = pv->pe_align;
1801
1802                 if (extent_count)
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))
1806                         return_0;
1807         }
1808
1809         return 1;
1810 }
1811
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,
1815                                                      const char *vgid,
1816                                                      void *context)
1817 {
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;
1828
1829         if (!(fid = dm_pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
1830                 log_error("Couldn't allocate format instance object.");
1831                 return NULL;
1832         }
1833
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.");
1837                 return NULL;
1838         }
1839
1840         fidtc->raw_metadata_buf = NULL;
1841         fid->private = (void *) fidtc;
1842
1843         fid->fmt = fmt;
1844         dm_list_init(&fid->metadata_areas);
1845
1846         if (!vgname) {
1847                 if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda))))
1848                         return_NULL;
1849                 mda->ops = &_metadata_text_file_backup_ops;
1850                 mda->metadata_locn = context;
1851                 dm_list_add(&fid->metadata_areas, &mda->list);
1852         } else {
1853                 dir_list = &((struct mda_lists *) fmt->private)->dirs;
1854
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,
1859                                           vgname);
1860                                 return NULL;
1861                         }
1862
1863                         context = create_text_context(fmt->cmd, path, NULL);
1864                         if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda))))
1865                                 return_NULL;
1866                         mda->ops = &_metadata_text_file_ops;
1867                         mda->metadata_locn = context;
1868                         dm_list_add(&fid->metadata_areas, &mda->list);
1869                 }
1870
1871                 raw_list = &((struct mda_lists *) fmt->private)->raws;
1872
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))
1876                                 continue;
1877
1878                         if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda))))
1879                                 return_NULL;
1880
1881                         if (!(mdac = dm_pool_alloc(fmt->cmd->mem, sizeof(*mdac))))
1882                                 return_NULL;
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);
1889                 }
1890
1891                 /* Scan PVs in VG for any further MDAs */
1892                 lvmcache_label_scan(fmt->cmd, 0);
1893                 if (!(vginfo = vginfo_from_vgname(vgname, vgid)))
1894                         goto_out;
1895                 dm_list_iterate_items(info, &vginfo->infos) {
1896                         mdas = &info->mdas;
1897                         dm_list_iterate_items(mda, mdas) {
1898                                 mdac =
1899                                     (struct mda_context *) mda->metadata_locn;
1900
1901                                 /* FIXME Check it holds this VG */
1902                                 if (!(mda_new = dm_pool_alloc(fmt->cmd->mem,
1903                                                            sizeof(*mda_new))))
1904                                         return_NULL;
1905
1906                                 if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem,
1907                                                             sizeof(*mdac_new))))
1908                                         return_NULL;
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);
1914                         }
1915                 }
1916                 /* FIXME Check raw metadata area count - rescan if required */
1917         }
1918
1919       out:
1920         return fid;
1921 }
1922
1923 void *create_text_context(struct cmd_context *cmd, const char *path,
1924                           const char *desc)
1925 {
1926         struct text_context *tc;
1927         char *tmp;
1928
1929         if ((tmp = strstr(path, ".tmp")) && (tmp == path + strlen(path) - 4)) {
1930                 log_error("%s: Volume group filename may not end in .tmp",
1931                           path);
1932                 return NULL;
1933         }
1934
1935         if (!(tc = dm_pool_alloc(cmd->mem, sizeof(*tc))))
1936                 return_NULL;
1937
1938         if (!(tc->path_live = dm_pool_strdup(cmd->mem, path)))
1939                 goto_bad;
1940
1941         if (!(tc->path_edit = dm_pool_alloc(cmd->mem, strlen(path) + 5)))
1942                 goto_bad;
1943
1944         sprintf(tc->path_edit, "%s.tmp", path);
1945
1946         if (!desc)
1947                 desc = "";
1948
1949         if (!(tc->desc = dm_pool_strdup(cmd->mem, desc)))
1950                 goto_bad;
1951
1952         return (void *) tc;
1953
1954       bad:
1955         dm_pool_free(cmd->mem, tc);
1956
1957         log_error("Couldn't allocate text format context object.");
1958         return NULL;
1959 }
1960
1961 static struct format_handler _text_handler = {
1962         .scan = _text_scan,
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
1971 };
1972
1973 static int _add_dir(const char *dir, struct dm_list *dir_list)
1974 {
1975         struct dir_list *dl;
1976
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");
1980                         return 0;
1981                 }
1982                 log_very_verbose("Adding text format metadata dir: %s", dir);
1983                 strcpy(dl->dir, dir);
1984                 dm_list_add(dir_list, &dl->list);
1985                 return 1;
1986         }
1987
1988         return 0;
1989 }
1990
1991 static int _get_config_disk_area(struct cmd_context *cmd,
1992                                  struct config_node *cn, struct dm_list *raw_list)
1993 {
1994         struct device_area dev_area;
1995         char *id_str;
1996         struct id id;
1997
1998         if (!(cn = cn->child)) {
1999                 log_error("Empty metadata disk_area section of config file");
2000                 return 0;
2001         }
2002
2003         if (!get_config_uint64(cn, "start_sector", &dev_area.start)) {
2004                 log_error("Missing start_sector in metadata disk_area section "
2005                           "of config file");
2006                 return 0;
2007         }
2008         dev_area.start <<= SECTOR_SHIFT;
2009
2010         if (!get_config_uint64(cn, "size", &dev_area.size)) {
2011                 log_error("Missing size in metadata disk_area section "
2012                           "of config file");
2013                 return 0;
2014         }
2015         dev_area.size <<= SECTOR_SHIFT;
2016
2017         if (!get_config_str(cn, "id", &id_str)) {
2018                 log_error("Missing uuid in metadata disk_area section "
2019                           "of config file");
2020                 return 0;
2021         }
2022
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);
2026                 return 0;
2027         }
2028
2029         if (!(dev_area.dev = device_from_pvid(cmd, &id))) {
2030                 char buffer[64] __attribute((aligned(8)));
2031
2032                 if (!id_write_format(&id, buffer, sizeof(buffer)))
2033                         log_error("Couldn't find device.");
2034                 else
2035                         log_error("Couldn't find device with uuid '%s'.",
2036                                   buffer);
2037
2038                 return 0;
2039         }
2040
2041         return _add_raw(raw_list, &dev_area);
2042 }
2043
2044 struct format_type *create_text_format(struct cmd_context *cmd)
2045 {
2046         struct format_type *fmt;
2047         struct config_node *cn;
2048         struct config_value *cv;
2049         struct mda_lists *mda_lists;
2050
2051         if (!(fmt = dm_malloc(sizeof(*fmt))))
2052                 return_NULL;
2053
2054         fmt->cmd = cmd;
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;
2062
2063         if (!(mda_lists = dm_malloc(sizeof(struct mda_lists)))) {
2064                 log_error("Failed to allocate dir_list");
2065                 dm_free(fmt);
2066                 return NULL;
2067         }
2068
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;
2074
2075         if (!(fmt->labeller = text_labeller_create(fmt))) {
2076                 log_error("Couldn't create text label handler.");
2077                 dm_free(fmt);
2078                 return NULL;
2079         }
2080
2081         if (!(label_register_handler(FMT_TEXT_NAME, fmt->labeller))) {
2082                 log_error("Couldn't register text label handler.");
2083                 dm_free(fmt);
2084                 return NULL;
2085         }
2086
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: "
2091                                           "metadata/dirs");
2092                                 goto err;
2093                         }
2094
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);
2098                                 goto err;
2099                         }
2100                 }
2101         }
2102
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))
2106                                 goto err;
2107                 }
2108         }
2109
2110         log_very_verbose("Initialised format: %s", fmt->name);
2111
2112         return fmt;
2113
2114       err:
2115         _free_dirs(&mda_lists->dirs);
2116
2117         dm_free(fmt);
2118         return NULL;
2119 }