]> sourceware.org Git - lvm2.git/blame - lib/activate/activate.c
o Split struct io_space into:
[lvm2.git] / lib / activate / activate.c
CommitLineData
b1713d28
JT
1/*
2 * Copyright (C) 2001 Sistina Software (UK) Limited.
3 *
1b9fcf48 4 * This file is released under the LGPL.
b1713d28
JT
5 */
6
a381c45a 7#include "metadata.h"
b1713d28 8#include "activate.h"
f047219b 9#include "log.h"
b1713d28 10
f047219b 11#include <devmapper/libdevmapper.h>
ae2bb665 12
ab269099
JT
13static void _build_lv_name(char *buffer, size_t s, struct logical_volume *lv)
14{
15 snprintf(buffer, s, "%s_%s", lv->vg->name, lv->name);
16}
17
2ba80b43 18static struct dm_task *_setup_task(struct logical_volume *lv, int task)
37ed70b9
JT
19{
20 char name[128];
21 struct dm_task *dmt;
22
23 if (!(dmt = dm_task_create(task))) {
24 stack;
25 return NULL;
26 }
27
28 _build_lv_name(name, sizeof(name), lv);
29 dm_task_set_name(dmt, name);
30
31 return dmt;
32}
33
2ba80b43 34static struct dm_task *_info(struct logical_volume *lv)
37ed70b9 35{
37ed70b9
JT
36 struct dm_task *dmt;
37
38 if (!(dmt = _setup_task(lv, DM_DEVICE_INFO))) {
39 stack;
40 return 0;
41 }
42
43 if (!dm_task_run(dmt)) {
2ba80b43
JT
44 stack;
45 goto bad;
46 }
47
48 return dmt;
49
50 bad:
51 dm_task_destroy(dmt);
52 return NULL;
53}
54
94b8220f 55int lv_active(struct logical_volume *lv)
2ba80b43 56{
94b8220f 57 int r = -1;
2ba80b43
JT
58 struct dm_task *dmt;
59
60 if (!(dmt = _info(lv))) {
37ed70b9 61 stack;
94b8220f 62 return r;
37ed70b9
JT
63 }
64
94b8220f 65 if (!dm_task_exists(dmt, &r)) {
37ed70b9
JT
66 stack;
67 goto out;
68 }
69
37ed70b9
JT
70 out:
71 dm_task_destroy(dmt);
72 return r;
73}
74
94b8220f 75int lv_open_count(struct logical_volume *lv)
2ba80b43 76{
94b8220f 77 int r = -1;
2ba80b43
JT
78 struct dm_task *dmt;
79
80 if (!(dmt = _info(lv))) {
81 stack;
94b8220f 82 return r;
2ba80b43
JT
83 }
84
94b8220f 85 if (!dm_task_open_count(dmt, &r)) {
2ba80b43
JT
86 stack;
87 goto out;
88 }
89
2ba80b43
JT
90 out:
91 dm_task_destroy(dmt);
92 return r;
93}
94
80f9662b
JT
95/*
96 * Creates a target for the next contiguous run of
97 * extents.
98 */
99static int _emit_target(struct dm_task *dmt, struct logical_volume *lv,
100 unsigned int *ple)
101{
102 char params[1024];
103 unsigned int le = *ple;
104 uint64_t esize = lv->vg->extent_size;
105 int i, count = 0;
106 struct pe_specifier *pes, *first = NULL;
107
108 for (i = le; i < lv->le_count; i++) {
109 pes = lv->map + i;
110
111 if (!first)
112 first = pes;
113
114 else if (first->pv != pes->pv || first->pe != pes->pe + 1)
115 break; /* no longer contig. */
116
117 count++;
118 }
119
120 snprintf(params, sizeof(params), "%s %llu",
121 dev_name(first->pv->dev),
122 first->pv->pe_start + (esize * first->pe));
123
124 if (!dm_task_add_target(dmt, esize * le, esize * count,
125 "linear", params)) {
126 stack;
127 return 0;
128 }
129
130 *ple = i;
131 return 1;
132}
133
37ed70b9 134int _load(struct logical_volume *lv, int task)
b1713d28 135{
ae2bb665 136 int r = 0;
80f9662b 137 uint32_t le = 0;
ae2bb665 138 struct dm_task *dmt;
e15559aa 139
37ed70b9 140 if (!(dmt = _setup_task(lv, task))) {
ae2bb665
JT
141 stack;
142 return 0;
143 }
b1713d28 144
80f9662b
JT
145 /*
146 * Merge adjacent extents.
147 */
148 while (le < lv->le_count) {
149 if (!_emit_target(dmt, lv, &le)) {
150 log_err("unable to activate logical volume '%s'",
151 lv->name);
ae2bb665
JT
152 goto out;
153 }
ae2bb665
JT
154 }
155
f047219b 156 if (!(r = dm_task_run(dmt)))
ae2bb665
JT
157 stack;
158
159 out:
f047219b 160 dm_task_destroy(dmt);
ae2bb665 161 return r;
b1713d28 162}
a381c45a 163
37ed70b9
JT
164/* FIXME: Always display error msg */
165/* FIXME: Create dev entry if required */
166int lv_activate(struct logical_volume *lv)
0a5e4a14 167{
37ed70b9
JT
168 return _load(lv, DM_DEVICE_CREATE);
169}
170
171int _suspend(struct logical_volume *lv, int sus)
172{
173 int r;
174 struct dm_task *dmt;
175 int task = sus ? DM_DEVICE_SUSPEND : DM_DEVICE_RESUME;
176
177 if (!(dmt = _setup_task(lv, task))) {
178 stack;
179 return 0;
180 }
181
182 if (!(r = dm_task_run(dmt)))
183 log_err("Couldn't %s device '%s'", sus ? "suspend" : "resume",
184 lv->name);
185
186 dm_task_destroy(dmt);
187 return r;
188}
189
190int lv_reactivate(struct logical_volume *lv)
191{
192 int r;
193 if (!_suspend(lv, 1)) {
194 stack;
195 return 0;
196 }
0a5e4a14 197
37ed70b9 198 r = _load(lv, DM_DEVICE_RELOAD);
ae2bb665 199
37ed70b9
JT
200 if (!_suspend(lv, 0)) {
201 stack;
202 return 0;
203 }
0a5e4a14 204
37ed70b9 205 return r;
0a5e4a14
AK
206}
207
ae2bb665
JT
208int lv_deactivate(struct logical_volume *lv)
209{
f047219b 210 int r;
ab269099
JT
211 struct dm_task *dmt;
212
37ed70b9 213 if (!(dmt = _setup_task(lv, DM_DEVICE_REMOVE))) {
ae2bb665
JT
214 stack;
215 return 0;
216 }
217
f047219b 218 if (!(r = dm_task_run(dmt)))
ae2bb665
JT
219 stack;
220
ae2bb665
JT
221 dm_task_destroy(dmt);
222 return r;
223}
224
37ed70b9
JT
225int activate_lvs_in_vg(struct volume_group *vg)
226{
227 struct list *lvh;
228 struct logical_volume *lv;
94b8220f 229 int count = 0;
37ed70b9
JT
230
231 list_iterate(lvh, &vg->lvs) {
232 lv = &(list_item(lvh, struct lv_list)->lv);
233
94b8220f 234 count += (!lv_active(lv) && lv_activate(lv));
37ed70b9
JT
235 }
236
237 return count;
238}
239
ae2bb665
JT
240int lv_update_write_access(struct logical_volume *lv)
241{
242 return 0;
243}
244
a381c45a
AK
245int deactivate_lvs_in_vg(struct volume_group *vg)
246{
0a5e4a14 247 struct list *lvh;
37ed70b9 248 struct logical_volume *lv;
94b8220f 249 int count = 0;
37ed70b9
JT
250
251 list_iterate(lvh, &vg->lvs) {
252 lv = &(list_item(lvh, struct lv_list)->lv);
0a5e4a14 253
94b8220f 254 count += ((lv_active(lv) == 1) && lv_deactivate(lv));
37ed70b9 255 }
0a5e4a14 256
37ed70b9 257 return count;
a381c45a 258}
f047219b
AK
259
260int lvs_in_vg_activated(struct volume_group *vg)
261{
37ed70b9
JT
262 struct list *lvh;
263 struct logical_volume *lv;
94b8220f 264 int count = 0;
37ed70b9
JT
265
266 list_iterate(lvh, &vg->lvs) {
267 lv = &(list_item(lvh, struct lv_list)->lv);
268
94b8220f 269 count += (lv_active(lv) == 1);
37ed70b9
JT
270 }
271
272 return count;
f047219b 273}
2ba80b43
JT
274
275int lvs_in_vg_opened(struct volume_group *vg)
276{
277 struct list *lvh;
278 struct logical_volume *lv;
94b8220f 279 int count = 0;
2ba80b43
JT
280
281 list_iterate(lvh, &vg->lvs) {
282 lv = &(list_item(lvh, struct lv_list)->lv);
283
94b8220f 284 count += (lv_open_count(lv) == 1);
2ba80b43
JT
285 }
286
287 return count;
288}
289
This page took 0.058398 seconds and 5 git commands to generate.