Tizen 2.1 base
[external/device-mapper.git] / lib / format1 / lvm1-label.c
1 /*
2  * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
3  * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
4  *
5  * This file is part of LVM2.
6  *
7  * This copyrighted material is made available to anyone wishing to use,
8  * modify, copy, or redistribute it subject to the terms and conditions
9  * of the GNU Lesser General Public License v.2.1.
10  *
11  * You should have received a copy of the GNU Lesser General Public License
12  * along with this program; if not, write to the Free Software Foundation,
13  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
14  */
15
16 #include "lib.h"
17 #include "lvm1-label.h"
18 #include "disk-rep.h"
19 #include "label.h"
20 #include "metadata.h"
21 #include "xlate.h"
22 #include "format1.h"
23
24 #include <sys/stat.h>
25 #include <fcntl.h>
26
27 static void _not_supported(const char *op)
28 {
29         log_error("The '%s' operation is not supported for the lvm1 labeller.",
30                   op);
31 }
32
33 static int _lvm1_can_handle(struct labeller *l __attribute__((unused)), void *buf, uint64_t sector)
34 {
35         struct pv_disk *pvd = (struct pv_disk *) buf;
36         uint32_t version;
37
38         /* LVM1 label must always be in first sector */
39         if (sector)
40                 return 0;
41
42         version = xlate16(pvd->version);
43
44         if (pvd->id[0] == 'H' && pvd->id[1] == 'M' &&
45             (version == 1 || version == 2))
46                 return 1;
47
48         return 0;
49 }
50
51 static int _lvm1_write(struct label *label __attribute__((unused)), void *buf __attribute__((unused)))
52 {
53         _not_supported("write");
54         return 0;
55 }
56
57 static int _lvm1_read(struct labeller *l, struct device *dev, void *buf,
58                  struct label **label)
59 {
60         struct pv_disk *pvd = (struct pv_disk *) buf;
61         struct vg_disk vgd;
62         struct lvmcache_info *info;
63         const char *vgid = FMT_LVM1_ORPHAN_VG_NAME;
64         const char *vgname = FMT_LVM1_ORPHAN_VG_NAME;
65         unsigned exported = 0;
66
67         munge_pvd(dev, pvd);
68
69         if (*pvd->vg_name) {
70                 if (!read_vgd(dev, &vgd, pvd))
71                         return_0;
72                 vgid = (char *) vgd.vg_uuid;
73                 vgname = (char *) pvd->vg_name;
74                 exported = pvd->pv_status & VG_EXPORTED;
75         }
76
77         if (!(info = lvmcache_add(l, (char *)pvd->pv_uuid, dev, vgname, vgid,
78                                   exported)))
79                 return_0;
80         *label = info->label;
81
82         info->device_size = xlate32(pvd->pv_size) << SECTOR_SHIFT;
83         dm_list_init(&info->mdas);
84
85         info->status &= ~CACHE_INVALID;
86
87         return 1;
88 }
89
90 static int _lvm1_initialise_label(struct labeller *l __attribute__((unused)), struct label *label)
91 {
92         strcpy(label->type, "LVM1");
93
94         return 1;
95 }
96
97 static void _lvm1_destroy_label(struct labeller *l __attribute__((unused)), struct label *label __attribute__((unused)))
98 {
99 }
100
101 static void _lvm1_destroy(struct labeller *l)
102 {
103         dm_free(l);
104 }
105
106 struct label_ops _lvm1_ops = {
107         .can_handle = _lvm1_can_handle,
108         .write = _lvm1_write,
109         .read = _lvm1_read,
110         .verify = _lvm1_can_handle,
111         .initialise_label = _lvm1_initialise_label,
112         .destroy_label = _lvm1_destroy_label,
113         .destroy = _lvm1_destroy,
114 };
115
116 struct labeller *lvm1_labeller_create(struct format_type *fmt)
117 {
118         struct labeller *l;
119
120         if (!(l = dm_malloc(sizeof(*l)))) {
121                 log_error("Couldn't allocate labeller object.");
122                 return NULL;
123         }
124
125         l->ops = &_lvm1_ops;
126         l->private = (const void *) fmt;
127
128         return l;
129 }