Branch data Line data Source code
1 : : /*
2 : : * Copyright (C) 2001-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 "metadata.h"
18 : : #include "import-export.h"
19 : : #include "lvm-string.h"
20 : :
21 : : /*
22 : : * Bitsets held in the 'status' flags get
23 : : * converted into arrays of strings.
24 : : */
25 : : struct flag {
26 : : const uint64_t mask;
27 : : const char *description;
28 : : int kind;
29 : : };
30 : :
31 : : static const struct flag _vg_flags[] = {
32 : : {EXPORTED_VG, "EXPORTED", STATUS_FLAG},
33 : : {RESIZEABLE_VG, "RESIZEABLE", STATUS_FLAG},
34 : : {PVMOVE, "PVMOVE", STATUS_FLAG},
35 : : {LVM_READ, "READ", STATUS_FLAG},
36 : : {LVM_WRITE, "WRITE", STATUS_FLAG},
37 : : {CLUSTERED, "CLUSTERED", STATUS_FLAG},
38 : : {SHARED, "SHARED", STATUS_FLAG},
39 : : {PARTIAL_VG, NULL, 0},
40 : : {PRECOMMITTED, NULL, 0},
41 : : {0, NULL, 0}
42 : : };
43 : :
44 : : static const struct flag _pv_flags[] = {
45 : : {ALLOCATABLE_PV, "ALLOCATABLE", STATUS_FLAG},
46 : : {EXPORTED_VG, "EXPORTED", STATUS_FLAG},
47 : : {MISSING_PV, "MISSING", COMPATIBLE_FLAG},
48 : : {0, NULL, 0}
49 : : };
50 : :
51 : : static const struct flag _lv_flags[] = {
52 : : {LVM_READ, "READ", STATUS_FLAG},
53 : : {LVM_WRITE, "WRITE", STATUS_FLAG},
54 : : {FIXED_MINOR, "FIXED_MINOR", STATUS_FLAG},
55 : : {VISIBLE_LV, "VISIBLE", STATUS_FLAG},
56 : : {PVMOVE, "PVMOVE", STATUS_FLAG},
57 : : {LOCKED, "LOCKED", STATUS_FLAG},
58 : : {MIRROR_NOTSYNCED, "NOTSYNCED", STATUS_FLAG},
59 : : {MIRROR_IMAGE, NULL, 0},
60 : : {MIRROR_LOG, NULL, 0},
61 : : {MIRRORED, NULL, 0},
62 : : {VIRTUAL, NULL, 0},
63 : : {SNAPSHOT, NULL, 0},
64 : : {MERGING, NULL, 0},
65 : : {ACTIVATE_EXCL, NULL, 0},
66 : : {CONVERTING, NULL, 0},
67 : : {PARTIAL_LV, NULL, 0},
68 : : {POSTORDER_FLAG, NULL, 0},
69 : : {VIRTUAL_ORIGIN, NULL, 0},
70 : : {REPLICATOR, NULL, 0},
71 : : {REPLICATOR_LOG, NULL, 0},
72 : : {0, NULL, 0}
73 : : };
74 : :
75 : 0 : static const struct flag *_get_flags(int type)
76 : : {
77 [ # # # # ]: 0 : switch (type & ~STATUS_FLAG) {
78 : : case VG_FLAGS:
79 : 0 : return _vg_flags;
80 : :
81 : : case PV_FLAGS:
82 : 0 : return _pv_flags;
83 : :
84 : : case LV_FLAGS:
85 : 0 : return _lv_flags;
86 : : }
87 : :
88 : 0 : log_error("Unknown flag set requested.");
89 : 0 : return NULL;
90 : : }
91 : :
92 : : /*
93 : : * Converts a bitset to an array of string values,
94 : : * using one of the tables defined at the top of
95 : : * the file.
96 : : */
97 : 0 : int print_flags(uint64_t status, int type, char *buffer, size_t size)
98 : : {
99 : 0 : int f, first = 1;
100 : : const struct flag *flags;
101 : :
102 [ # # ]: 0 : if (!(flags = _get_flags(type)))
103 : 0 : return_0;
104 : :
105 [ # # ]: 0 : if (!emit_to_buffer(&buffer, &size, "["))
106 : 0 : return 0;
107 : :
108 [ # # ]: 0 : for (f = 0; flags[f].mask; f++) {
109 [ # # ]: 0 : if (status & flags[f].mask) {
110 : 0 : status &= ~flags[f].mask;
111 : :
112 [ # # ]: 0 : if ((type & STATUS_FLAG) != flags[f].kind)
113 : 0 : continue;
114 : :
115 : : /* Internal-only flag? */
116 [ # # ]: 0 : if (!flags[f].description)
117 : 0 : continue;
118 : :
119 [ # # ]: 0 : if (!first) {
120 [ # # ]: 0 : if (!emit_to_buffer(&buffer, &size, ", "))
121 : 0 : return 0;
122 : : } else
123 : 0 : first = 0;
124 : :
125 [ # # ]: 0 : if (!emit_to_buffer(&buffer, &size, "\"%s\"",
126 : 0 : flags[f].description))
127 : 0 : return 0;
128 : : }
129 : : }
130 : :
131 [ # # ]: 0 : if (!emit_to_buffer(&buffer, &size, "]"))
132 : 0 : return 0;
133 : :
134 [ # # ]: 0 : if (status)
135 : 0 : log_error("Metadata inconsistency: Not all flags successfully "
136 : : "exported.");
137 : :
138 : 0 : return 1;
139 : : }
140 : :
141 : 0 : int read_flags(uint64_t *status, int type, struct config_value *cv)
142 : : {
143 : : int f;
144 : 0 : uint64_t s = UINT64_C(0);
145 : : const struct flag *flags;
146 : :
147 [ # # ]: 0 : if (!(flags = _get_flags(type)))
148 : 0 : return_0;
149 : :
150 [ # # ]: 0 : if (cv->type == CFG_EMPTY_ARRAY)
151 : 0 : goto out;
152 : :
153 [ # # ]: 0 : while (cv) {
154 [ # # ]: 0 : if (cv->type != CFG_STRING) {
155 : 0 : log_error("Status value is not a string.");
156 : 0 : return 0;
157 : : }
158 : :
159 [ # # ]: 0 : for (f = 0; flags[f].description; f++)
160 [ # # ]: 0 : if (!strcmp(flags[f].description, cv->v.str)) {
161 : 0 : s |= flags[f].mask;
162 : 0 : break;
163 : : }
164 : :
165 [ # # ][ # # ]: 0 : if (type == VG_FLAGS && !strcmp(cv->v.str, "PARTIAL")) {
166 : : /*
167 : : * Exception: We no longer write this flag out, but it
168 : : * might be encountered in old backup files, so restore
169 : : * it in that case. It is never part of live metadata
170 : : * though, so only vgcfgrestore needs to be concerned
171 : : * by this case.
172 : : */
173 : 0 : s |= PARTIAL_VG;
174 [ # # ][ # # ]: 0 : } else if (!flags[f].description && (type & STATUS_FLAG)) {
175 : 0 : log_error("Unknown status flag '%s'.", cv->v.str);
176 : 0 : return 0;
177 : : }
178 : :
179 : 0 : cv = cv->next;
180 : : }
181 : :
182 : : out:
183 : 0 : *status |= s;
184 : 0 : return 1;
185 : : }
|