]> sourceware.org Git - lvm2.git/blame - lib/activate/activate.c
Attempt to load missing targets using modprobe.
[lvm2.git] / lib / activate / activate.c
CommitLineData
b1713d28 1/*
6606c3ae
AK
2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
b1713d28 4 *
6606c3ae
AK
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 General Public License v.2.
10 *
11 * You should have received a copy of the GNU 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
b1713d28
JT
14 */
15
d1d9800e 16#include "lib.h"
a381c45a 17#include "metadata.h"
b1713d28 18#include "activate.h"
914c9723 19#include "memlock.h"
78125be9 20#include "display.h"
f7a14956 21#include "fs.h"
7d1552c9 22#include "lvm-file.h"
41b2fd5f 23#include "lvm-string.h"
413cc918 24#include "toolcontext.h"
de6c9183 25#include "dev_manager.h"
de17d760 26#include "str_list.h"
4922197a 27#include "config.h"
12137231
JT
28
29#include <limits.h>
5986ec94 30#include <fcntl.h>
914c9723 31#include <unistd.h>
12137231 32
6d52fb46 33#define _skip(fmt, args...) log_very_verbose("Skipping: " fmt , ## args)
b1713d28 34
7d1552c9
AK
35int lvm1_present(struct cmd_context *cmd)
36{
37 char path[PATH_MAX];
38
39 if (lvm_snprintf(path, sizeof(path), "%s/lvm/global", cmd->proc_dir)
40 < 0) {
41 log_error("LVM1 proc global snprintf failed");
42 return 0;
43 }
44
45 if (path_exists(path))
46 return 1;
47 else
48 return 0;
49}
50
199e490e
AK
51#ifndef DEVMAPPER_SUPPORT
52void set_activation(int act)
53{
f2046e0a
AK
54 static int warned = 0;
55
56 if (warned || !act)
57 return;
58
59 log_error("Compiled without libdevmapper support. "
60 "Can't enable activation.");
61
62 warned = 1;
199e490e
AK
63}
64int activation(void)
65{
66 return 0;
67}
68int library_version(char *version, size_t size)
69{
70 return 0;
71}
72int driver_version(char *version, size_t size)
73{
74 return 0;
75}
d1f4953a
AK
76int target_present(const char *target_name)
77{
78 return 0;
79}
e9c761b8
AK
80int lv_info(const struct logical_volume *lv, struct lvinfo *info,
81 int with_open_count)
199e490e
AK
82{
83 return 0;
84}
4bd9480d 85int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
e9c761b8 86 struct lvinfo *info, int with_open_count)
4bd9480d
AK
87{
88 return 0;
89}
199e490e
AK
90int lv_snapshot_percent(struct logical_volume *lv, float *percent)
91{
92 return 0;
93}
914c9723
AK
94int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
95 uint32_t *event_nr)
10b29b8d
AK
96{
97 return 0;
98}
199e490e
AK
99int lvs_in_vg_activated(struct volume_group *vg)
100{
101 return 0;
102}
103int lvs_in_vg_opened(struct volume_group *vg)
104{
105 return 0;
106}
658b5812
AK
107int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
108{
109 return 1;
110}
199e490e
AK
111int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
112{
113 return 1;
114}
658b5812
AK
115int lv_resume(struct cmd_context *cmd, const char *lvid_s)
116{
117 return 1;
118}
199e490e
AK
119int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
120{
121 return 1;
122}
123int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
124{
125 return 1;
126}
658b5812
AK
127int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
128 int *activate_lv)
129{
130 return 1;
131}
07d31831 132int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive)
199e490e
AK
133{
134 return 1;
135}
07d31831 136int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive)
658b5812
AK
137{
138 return 1;
139}
f7dd6d84
AK
140
141int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
142{
143 return 1;
144}
145
914c9723
AK
146void activation_exit(void)
147{
148 return;
149}
199e490e
AK
150
151#else /* DEVMAPPER_SUPPORT */
152
d1d9800e
AK
153static int _activation = 1;
154
8ef2b021 155void set_activation(int act)
d1d9800e 156{
8ef2b021 157 if (act == _activation)
d1d9800e
AK
158 return;
159
8ef2b021 160 _activation = act;
d1d9800e
AK
161 if (_activation)
162 log_verbose("Activation enabled. Device-mapper kernel "
163 "driver will be used.");
164 else
165 log_verbose("Activation disabled. No device-mapper "
166 "interaction will be attempted.");
167}
168
8ef2b021 169int activation(void)
d1d9800e
AK
170{
171 return _activation;
172}
173
de17d760
AK
174static int _passes_activation_filter(struct cmd_context *cmd,
175 struct logical_volume *lv)
176{
25579907 177 const struct config_node *cn;
de17d760
AK
178 struct config_value *cv;
179 char *str;
180 char path[PATH_MAX];
181
814643d8 182 if (!(cn = find_config_node(cmd->cft->root, "activation/volume_list"))) {
25579907 183 /* If no host tags defined, activate */
de17d760
AK
184 if (list_empty(&cmd->tags))
185 return 1;
186
187 /* If any host tag matches any LV or VG tag, activate */
188 if (str_list_match_list(&cmd->tags, &lv->tags) ||
189 str_list_match_list(&cmd->tags, &lv->vg->tags))
190 return 1;
191
192 /* Don't activate */
193 return 0;
194 }
195
196 for (cv = cn->v; cv; cv = cv->next) {
197 if (cv->type != CFG_STRING) {
198 log_error("Ignoring invalid string in config file "
199 "activation/volume_list");
200 continue;
201 }
202 str = cv->v.str;
203 if (!*str) {
204 log_error("Ignoring empty string in config file "
205 "activation/volume_list");
206 continue;
207 }
208
209 /* Tag? */
210 if (*str == '@') {
211 str++;
212 if (!*str) {
213 log_error("Ignoring empty tag in config file "
214 "activation/volume_list");
215 continue;
216 }
217 /* If any host tag matches any LV or VG tag, activate */
218 if (!strcmp(str, "*")) {
219 if (str_list_match_list(&cmd->tags, &lv->tags)
220 || str_list_match_list(&cmd->tags,
221 &lv->vg->tags))
222 return 1;
223 else
224 continue;
225 }
226 /* If supplied tag matches LV or VG tag, activate */
227 if (str_list_match_item(&lv->tags, str) ||
228 str_list_match_item(&lv->vg->tags, str))
229 return 1;
230 else
231 continue;
232 }
233 if (!index(str, '/')) {
234 /* vgname supplied */
235 if (!strcmp(str, lv->vg->name))
236 return 1;
237 else
238 continue;
239 }
240 /* vgname/lvname */
241 if (lvm_snprintf(path, sizeof(path), "%s/%s", lv->vg->name,
242 lv->name) < 0) {
243 log_error("lvm_snprintf error from %s/%s", lv->vg->name,
244 lv->name);
245 continue;
246 }
247 if (!strcmp(path, str))
248 return 1;
249 }
250
251 return 0;
252}
253
fae0c576
AK
254int library_version(char *version, size_t size)
255{
d1d9800e
AK
256 if (!activation())
257 return 0;
258
fae0c576
AK
259 if (!dm_get_library_version(version, size))
260 return 0;
261 return 1;
262}
263
fae0c576
AK
264int driver_version(char *version, size_t size)
265{
266 int r = 0;
267 struct dm_task *dmt;
268
d1d9800e
AK
269 if (!activation())
270 return 0;
271
fae0c576
AK
272 log_very_verbose("Getting driver version");
273 if (!(dmt = dm_task_create(DM_DEVICE_VERSION))) {
274 stack;
275 return 0;
276 }
277
278 if (!dm_task_run(dmt))
279 log_error("Failed to get driver version");
280
281 if (!dm_task_get_driver_version(dmt, version, size))
282 goto out;
283
284 r = 1;
285
2ed2a724 286 out:
fae0c576
AK
287 dm_task_destroy(dmt);
288
289 return r;
290}
291
d1f4953a
AK
292int target_present(const char *target_name)
293{
294 int r = 0;
295 struct dm_task *dmt;
296 struct dm_versions *target, *last_target;
297
298 if (!activation())
299 return 0;
300
301 log_very_verbose("Getting target version for %s", target_name);
302 if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS))) {
303 stack;
304 return 0;
305 }
306
307 if (!dm_task_run(dmt)) {
308 log_debug("Failed to get %s target version", target_name);
309 /* Assume this was because LIST_VERSIONS isn't supported */
310 return 1;
311 }
312
313 target = dm_task_get_versions(dmt);
314
315 do {
316 last_target = target;
317
318 if (!strcmp(target_name, target->name)) {
319 r = 1;
320 goto out;
321 }
322
323 target = (void *) target + target->next;
324 } while (last_target != target);
325
326 out:
327 dm_task_destroy(dmt);
328
329 return r;
330}
331
de6c9183
JT
332/*
333 * Returns 1 if info structure populated, else 0 on failure.
334 */
8c0388e4 335static int _lv_info(const struct logical_volume *lv, int mknodes,
e9c761b8 336 struct lvinfo *info, int with_open_count)
37ed70b9 337{
de6c9183
JT
338 int r;
339 struct dev_manager *dm;
199e490e 340 struct dm_info dminfo;
4a624ca0 341
d1d9800e
AK
342 if (!activation())
343 return 0;
344
4922197a 345 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
12137231 346 stack;
de6c9183 347 return 0;
12137231 348 }
4a624ca0 349
e9c761b8 350 if (!(r = dev_manager_info(dm, lv, mknodes, with_open_count, &dminfo)))
de6c9183 351 stack;
4a624ca0 352
199e490e
AK
353 info->exists = dminfo.exists;
354 info->suspended = dminfo.suspended;
355 info->open_count = dminfo.open_count;
356 info->major = dminfo.major;
357 info->minor = dminfo.minor;
358 info->read_only = dminfo.read_only;
359
de6c9183
JT
360 dev_manager_destroy(dm);
361 return r;
362}
a62ee8ad 363
e9c761b8
AK
364int lv_info(const struct logical_volume *lv, struct lvinfo *info,
365 int with_open_count)
8c0388e4 366{
e9c761b8 367 return _lv_info(lv, 0, info, with_open_count);
8c0388e4
AK
368}
369
4bd9480d 370int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
e9c761b8 371 struct lvinfo *info, int with_open_count)
4bd9480d
AK
372{
373 struct logical_volume *lv;
374
375 if (!(lv = lv_from_lvid(cmd, lvid_s)))
376 return 0;
377
e9c761b8 378 return _lv_info(lv, 0, info, with_open_count);
4bd9480d
AK
379}
380
1951dba9
AL
381/*
382 * Returns 1 if percent set, else 0 on failure.
383 */
c826c0d1 384int lv_snapshot_percent(struct logical_volume *lv, float *percent)
1951dba9
AL
385{
386 int r;
387 struct dev_manager *dm;
388
d1d9800e
AK
389 if (!activation())
390 return 0;
391
4922197a 392 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
1951dba9
AL
393 stack;
394 return 0;
395 }
396
c826c0d1 397 if (!(r = dev_manager_snapshot_percent(dm, lv, percent)))
1951dba9 398 stack;
c826c0d1 399
1951dba9
AL
400 dev_manager_destroy(dm);
401
402 return r;
403}
404
10b29b8d
AK
405/* FIXME Merge with snapshot_percent */
406int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
407 uint32_t *event_nr)
408{
409 int r;
410 struct dev_manager *dm;
b65b777d 411 struct lvinfo info;
10b29b8d
AK
412
413 if (!activation())
414 return 0;
415
e9c761b8 416 if (!lv_info(lv, &info, 0)) {
b65b777d
AK
417 stack;
418 return 0;
419 }
420
421 if (!info.exists)
422 return 0;
423
4922197a 424 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
10b29b8d
AK
425 stack;
426 return 0;
427 }
428
429 if (!(r = dev_manager_mirror_percent(dm, lv, wait, percent, event_nr)))
430 stack;
431
432 dev_manager_destroy(dm);
433
434 return r;
435}
436
41967a02 437static int _lv_active(struct logical_volume *lv)
2ba80b43 438{
199e490e 439 struct lvinfo info;
2ba80b43 440
e9c761b8 441 if (!lv_info(lv, &info, 0)) {
2ba80b43 442 stack;
de6c9183 443 return -1;
2ba80b43
JT
444 }
445
de6c9183 446 return info.exists;
2ba80b43
JT
447}
448
41967a02 449static int _lv_open_count(struct logical_volume *lv)
5986ec94 450{
199e490e 451 struct lvinfo info;
5986ec94 452
e9c761b8 453 if (!lv_info(lv, &info, 1)) {
5986ec94 454 stack;
de6c9183 455 return -1;
5986ec94
JT
456 }
457
de6c9183 458 return info.open_count;
5986ec94
JT
459}
460
8c013da4 461/* FIXME Need to detect and handle an lv rename */
658b5812 462static int _lv_activate_lv(struct logical_volume *lv)
b1713d28 463{
6d52fb46 464 int r;
de6c9183 465 struct dev_manager *dm;
b1713d28 466
4922197a 467 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
6d52fb46
JT
468 stack;
469 return 0;
ae2bb665
JT
470 }
471
0fe3a2c5 472 if (!(r = dev_manager_activate(dm, lv)))
6d52fb46 473 stack;
ae2bb665 474
de6c9183 475 dev_manager_destroy(dm);
ae2bb665 476 return r;
b1713d28 477}
a381c45a 478
be326a2f 479static int _lv_deactivate(struct logical_volume *lv)
0a5e4a14 480{
de6c9183
JT
481 int r;
482 struct dev_manager *dm;
37ed70b9 483
4922197a 484 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
6d52fb46
JT
485 stack;
486 return 0;
487 }
37ed70b9 488
de6c9183 489 if (!(r = dev_manager_deactivate(dm, lv)))
37ed70b9 490 stack;
37ed70b9 491
de6c9183
JT
492 dev_manager_destroy(dm);
493 return r;
37ed70b9
JT
494}
495
658b5812 496static int _lv_suspend_lv(struct logical_volume *lv)
4a624ca0 497{
20c5fcf7
AK
498 int r;
499 struct dev_manager *dm;
c2d72fd4 500
4922197a 501 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
37ed70b9
JT
502 stack;
503 return 0;
504 }
0a5e4a14 505
20c5fcf7 506 if (!(r = dev_manager_suspend(dm, lv)))
37ed70b9 507 stack;
0a5e4a14 508
20c5fcf7
AK
509 dev_manager_destroy(dm);
510 return r;
6d52fb46 511}
4a624ca0 512
8c013da4 513/*
f75c11ed 514 * These two functions return the number of visible LVs in the state,
8c013da4
AK
515 * or -1 on error.
516 */
f047219b
AK
517int lvs_in_vg_activated(struct volume_group *vg)
518{
60f13f01 519 struct lv_list *lvl;
94b8220f 520 int count = 0;
37ed70b9 521
d1d9800e
AK
522 if (!activation())
523 return 0;
524
60f13f01
AK
525 list_iterate_items(lvl, &vg->lvs) {
526 if (lvl->lv->status & VISIBLE_LV)
527 count += (_lv_active(lvl->lv) == 1);
37ed70b9
JT
528 }
529
530 return count;
f047219b 531}
2ba80b43
JT
532
533int lvs_in_vg_opened(struct volume_group *vg)
534{
60f13f01 535 struct lv_list *lvl;
94b8220f 536 int count = 0;
2ba80b43 537
d1d9800e
AK
538 if (!activation())
539 return 0;
540
60f13f01
AK
541 list_iterate_items(lvl, &vg->lvs) {
542 if (lvl->lv->status & VISIBLE_LV)
543 count += (_lv_open_count(lvl->lv) > 0);
2ba80b43
JT
544 }
545
546 return count;
547}
413cc918 548
658b5812
AK
549static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
550 int error_if_not_suspended)
413cc918
AK
551{
552 struct logical_volume *lv;
199e490e 553 struct lvinfo info;
413cc918 554
d1d9800e
AK
555 if (!activation())
556 return 1;
557
558 if (!(lv = lv_from_lvid(cmd, lvid_s)))
413cc918
AK
559 return 0;
560
20c5fcf7
AK
561 if (test_mode()) {
562 _skip("Suspending '%s'.", lv->name);
711f7fc6 563 return 1;
20c5fcf7
AK
564 }
565
e9c761b8 566 if (!lv_info(lv, &info, 0)) {
2ed2a724
AK
567 stack;
568 return 0;
569 }
41967a02 570
914c9723 571 if (!info.exists || info.suspended)
658b5812 572 return error_if_not_suspended ? 0 : 1;
914c9723
AK
573
574 memlock_inc();
658b5812 575 if (!_lv_suspend_lv(lv)) {
914c9723
AK
576 memlock_dec();
577 fs_unlock();
578 return 0;
579 }
8c013da4 580
413cc918
AK
581 return 1;
582}
583
658b5812
AK
584/* Returns success if the device is not active */
585int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
586{
587 return _lv_suspend(cmd, lvid_s, 0);
588}
589
590int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
591{
592 return _lv_suspend(cmd, lvid_s, 1);
593}
594
595static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
596 int error_if_not_active)
413cc918
AK
597{
598 struct logical_volume *lv;
199e490e 599 struct lvinfo info;
413cc918 600
d1d9800e
AK
601 if (!activation())
602 return 1;
603
604 if (!(lv = lv_from_lvid(cmd, lvid_s)))
413cc918
AK
605 return 0;
606
20c5fcf7
AK
607 if (test_mode()) {
608 _skip("Resuming '%s'.", lv->name);
711f7fc6 609 return 1;
20c5fcf7
AK
610 }
611
e9c761b8 612 if (!lv_info(lv, &info, 0)) {
2ed2a724
AK
613 stack;
614 return 0;
615 }
41967a02 616
914c9723 617 if (!info.exists || !info.suspended)
658b5812 618 return error_if_not_active ? 0 : 1;
914c9723 619
658b5812 620 if (!_lv_activate_lv(lv))
914c9723
AK
621 return 0;
622
623 memlock_dec();
624 fs_unlock();
413cc918
AK
625
626 return 1;
627}
628
658b5812
AK
629/* Returns success if the device is not active */
630int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
631{
632 return _lv_resume(cmd, lvid_s, 0);
633}
634
635int lv_resume(struct cmd_context *cmd, const char *lvid_s)
636{
637 return _lv_resume(cmd, lvid_s, 1);
638}
639
be326a2f 640int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
f4cbeaf0
AK
641{
642 struct logical_volume *lv;
199e490e 643 struct lvinfo info;
914c9723 644 int r;
f4cbeaf0 645
d1d9800e
AK
646 if (!activation())
647 return 1;
648
649 if (!(lv = lv_from_lvid(cmd, lvid_s)))
f4cbeaf0
AK
650 return 0;
651
20c5fcf7
AK
652 if (test_mode()) {
653 _skip("Deactivating '%s'.", lv->name);
711f7fc6 654 return 1;
20c5fcf7
AK
655 }
656
e9c761b8 657 if (!lv_info(lv, &info, 1)) {
2ed2a724
AK
658 stack;
659 return 0;
660 }
41967a02 661
914c9723
AK
662 if (!info.exists)
663 return 1;
f4cbeaf0 664
c1f50521 665 if (info.open_count && (lv->status & VISIBLE_LV)) {
0cf96f33
AK
666 log_error("LV %s/%s in use: not removing", lv->vg->name,
667 lv->name);
668 return 0;
669 }
670
914c9723
AK
671 memlock_inc();
672 r = _lv_deactivate(lv);
673 memlock_dec();
674 fs_unlock();
675
676 return r;
f4cbeaf0
AK
677}
678
658b5812
AK
679/* Test if LV passes filter */
680int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
681 int *activate_lv)
682{
683 struct logical_volume *lv;
684
685 if (!activation())
686 goto activate;
687
688 if (!(lv = lv_from_lvid(cmd, lvid_s)))
689 return 0;
690
691 if (!_passes_activation_filter(cmd, lv)) {
692 log_verbose("Not activating %s/%s due to config file settings",
693 lv->vg->name, lv->name);
694 *activate_lv = 0;
695 return 1;
696 }
697
698 activate:
699 *activate_lv = 1;
700 return 1;
701}
702
07d31831
AK
703static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
704 int exclusive, int filter)
f4cbeaf0
AK
705{
706 struct logical_volume *lv;
199e490e 707 struct lvinfo info;
914c9723 708 int r;
f4cbeaf0 709
d1d9800e
AK
710 if (!activation())
711 return 1;
712
713 if (!(lv = lv_from_lvid(cmd, lvid_s)))
f4cbeaf0
AK
714 return 0;
715
658b5812 716 if (filter && !_passes_activation_filter(cmd, lv)) {
de17d760
AK
717 log_verbose("Not activating %s/%s due to config file settings",
718 lv->vg->name, lv->name);
719 return 0;
720 }
721
20c5fcf7
AK
722 if (test_mode()) {
723 _skip("Activating '%s'.", lv->name);
711f7fc6 724 return 1;
20c5fcf7
AK
725 }
726
e9c761b8 727 if (!lv_info(lv, &info, 0)) {
2ed2a724
AK
728 stack;
729 return 0;
730 }
8c013da4 731
914c9723
AK
732 if (info.exists && !info.suspended)
733 return 1;
f4cbeaf0 734
07d31831
AK
735 if (exclusive)
736 lv->status |= ACTIVATE_EXCL;
737
914c9723 738 memlock_inc();
658b5812 739 r = _lv_activate_lv(lv);
914c9723
AK
740 memlock_dec();
741 fs_unlock();
742
743 return r;
f4cbeaf0 744}
199e490e 745
658b5812 746/* Activate LV */
07d31831 747int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive)
658b5812 748{
07d31831 749 return _lv_activate(cmd, lvid_s, exclusive, 0);
658b5812
AK
750}
751
752/* Activate LV only if it passes filter */
07d31831 753int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive)
658b5812 754{
07d31831 755 return _lv_activate(cmd, lvid_s, exclusive, 1);
658b5812
AK
756}
757
f7dd6d84
AK
758int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
759{
760 struct lvinfo info;
761 int r = 1;
762
8b076648 763 if (!lv) {
2262b320 764 r = dm_mknodes(NULL);
8b076648
AK
765 fs_unlock();
766 return r;
767 }
768
e9c761b8 769 if (!_lv_info(lv, 1, &info, 0)) {
f7dd6d84
AK
770 stack;
771 return 0;
772 }
773
774 if (info.exists)
f09fe0ad 775 r = dev_manager_lv_mknodes(lv);
f7dd6d84 776 else
f09fe0ad 777 r = dev_manager_lv_rmnodes(lv);
f7dd6d84
AK
778
779 fs_unlock();
780
781 return r;
782}
783
914c9723
AK
784void activation_exit(void)
785{
786 dev_manager_exit();
787}
199e490e 788#endif
This page took 0.201508 seconds and 5 git commands to generate.