1 /* $NetBSD: lvm-functions.c,v 1.1.1.3 2009/12/02 00:27:06 haad Exp $ */
2
3 /*
4 * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
5 * Copyright (C) 2004-2009 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 General Public License v.2.
12 *
13 * You should have received a copy of the GNU 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 #define _GNU_SOURCE
19 #define _FILE_OFFSET_BITS 64
20
21 #include <configure.h>
22 #include <pthread.h>
23 #include <sys/types.h>
24 #include <sys/utsname.h>
25 #include <sys/ioctl.h>
26 #include <sys/socket.h>
27 #include <sys/stat.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <stdint.h>
31 #include <fcntl.h>
32 #include <string.h>
33 #include <stddef.h>
34 #include <stdint.h>
35 #include <unistd.h>
36 #include <errno.h>
37 #include <syslog.h>
38 #include <assert.h>
39 #include <libdevmapper.h>
40 #include <libdlm.h>
41
42 #include "lvm-types.h"
43 #include "clvm.h"
44 #include "clvmd-comms.h"
45 #include "clvmd.h"
46 #include "lvm-functions.h"
47
48 /* LVM2 headers */
49 #include "toolcontext.h"
50 #include "lvmcache.h"
51 #include "lvm-logging.h"
52 #include "lvm-globals.h"
53 #include "activate.h"
54 #include "locking.h"
55 #include "archiver.h"
56 #include "defaults.h"
57
58 static struct cmd_context *cmd = NULL;
59 static struct dm_hash_table *lv_hash = NULL;
60 static pthread_mutex_t lv_hash_lock;
61 static pthread_mutex_t lvm_lock;
62 static char last_error[1024];
63 static int suspended = 0;
64
65 struct lv_info {
66 int lock_id;
67 int lock_mode;
68 };
69
decode_locking_cmd(unsigned char cmdl)70 static const char *decode_locking_cmd(unsigned char cmdl)
71 {
72 static char buf[128];
73 const char *type;
74 const char *scope;
75 const char *command;
76
77 switch (cmdl & LCK_TYPE_MASK) {
78 case LCK_NULL:
79 type = "NULL";
80 break;
81 case LCK_READ:
82 type = "READ";
83 break;
84 case LCK_PREAD:
85 type = "PREAD";
86 break;
87 case LCK_WRITE:
88 type = "WRITE";
89 break;
90 case LCK_EXCL:
91 type = "EXCL";
92 break;
93 case LCK_UNLOCK:
94 type = "UNLOCK";
95 break;
96 default:
97 type = "unknown";
98 break;
99 }
100
101 switch (cmdl & LCK_SCOPE_MASK) {
102 case LCK_VG:
103 scope = "VG";
104 break;
105 case LCK_LV:
106 scope = "LV";
107 break;
108 default:
109 scope = "unknown";
110 break;
111 }
112
113 switch (cmdl & LCK_MASK) {
114 case LCK_LV_EXCLUSIVE & LCK_MASK:
115 command = "LCK_LV_EXCLUSIVE";
116 break;
117 case LCK_LV_SUSPEND & LCK_MASK:
118 command = "LCK_LV_SUSPEND";
119 break;
120 case LCK_LV_RESUME & LCK_MASK:
121 command = "LCK_LV_RESUME";
122 break;
123 case LCK_LV_ACTIVATE & LCK_MASK:
124 command = "LCK_LV_ACTIVATE";
125 break;
126 case LCK_LV_DEACTIVATE & LCK_MASK:
127 command = "LCK_LV_DEACTIVATE";
128 break;
129 default:
130 command = "unknown";
131 break;
132 }
133
134 sprintf(buf, "0x%x %s (%s|%s%s%s%s%s%s)", cmdl, command, type, scope,
135 cmdl & LCK_NONBLOCK ? "|NONBLOCK" : "",
136 cmdl & LCK_HOLD ? "|HOLD" : "",
137 cmdl & LCK_LOCAL ? "|LOCAL" : "",
138 cmdl & LCK_CLUSTER_VG ? "|CLUSTER_VG" : "",
139 cmdl & LCK_CACHE ? "|CACHE" : "");
140
141 return buf;
142 }
143
decode_flags(unsigned char flags)144 static const char *decode_flags(unsigned char flags)
145 {
146 static char buf[128];
147
148 sprintf(buf, "0x%x (%s%s%s%s)", flags,
149 flags & LCK_PARTIAL_MODE ? "PARTIAL_MODE " : "",
150 flags & LCK_MIRROR_NOSYNC_MODE ? "MIRROR_NOSYNC " : "",
151 flags & LCK_DMEVENTD_MONITOR_MODE ? "DMEVENTD_MONITOR " : "",
152 flags & LCK_CONVERT ? "CONVERT " : "");
153
154 return buf;
155 }
156
get_last_lvm_error()157 char *get_last_lvm_error()
158 {
159 return last_error;
160 }
161
162 /*
163 * Hash lock info helpers
164 */
lookup_info(const char * resource)165 static struct lv_info *lookup_info(const char *resource)
166 {
167 struct lv_info *lvi;
168
169 pthread_mutex_lock(&lv_hash_lock);
170 lvi = dm_hash_lookup(lv_hash, resource);
171 pthread_mutex_unlock(&lv_hash_lock);
172
173 return lvi;
174 }
175
insert_info(const char * resource,struct lv_info * lvi)176 static void insert_info(const char *resource, struct lv_info *lvi)
177 {
178 pthread_mutex_lock(&lv_hash_lock);
179 dm_hash_insert(lv_hash, resource, lvi);
180 pthread_mutex_unlock(&lv_hash_lock);
181 }
182
remove_info(const char * resource)183 static void remove_info(const char *resource)
184 {
185 pthread_mutex_lock(&lv_hash_lock);
186 dm_hash_remove(lv_hash, resource);
187 pthread_mutex_unlock(&lv_hash_lock);
188 }
189
190 /*
191 * Return the mode a lock is currently held at (or -1 if not held)
192 */
get_current_lock(char * resource)193 static int get_current_lock(char *resource)
194 {
195 struct lv_info *lvi;
196
197 if ((lvi = lookup_info(resource)))
198 return lvi->lock_mode;
199
200 return -1;
201 }
202
203
init_lvhash()204 void init_lvhash()
205 {
206 /* Create hash table for keeping LV locks & status */
207 lv_hash = dm_hash_create(100);
208 pthread_mutex_init(&lv_hash_lock, NULL);
209 pthread_mutex_init(&lvm_lock, NULL);
210 }
211
212 /* Called at shutdown to tidy the lockspace */
destroy_lvhash()213 void destroy_lvhash()
214 {
215 struct dm_hash_node *v;
216 struct lv_info *lvi;
217 char *resource;
218 int status;
219
220 pthread_mutex_lock(&lv_hash_lock);
221
222 dm_hash_iterate(v, lv_hash) {
223 lvi = dm_hash_get_data(lv_hash, v);
224 resource = dm_hash_get_key(lv_hash, v);
225
226 if ((status = sync_unlock(resource, lvi->lock_id)))
227 DEBUGLOG("unlock_all. unlock failed(%d): %s\n",
228 status, strerror(errno));
229 free(lvi);
230 }
231
232 dm_hash_destroy(lv_hash);
233 lv_hash = NULL;
234
235 pthread_mutex_unlock(&lv_hash_lock);
236 }
237
238 /* Gets a real lock and keeps the info in the hash table */
hold_lock(char * resource,int mode,int flags)239 int hold_lock(char *resource, int mode, int flags)
240 {
241 int status;
242 int saved_errno;
243 struct lv_info *lvi;
244
245 /* Mask off invalid options */
246 flags &= LKF_NOQUEUE | LKF_CONVERT;
247
248 lvi = lookup_info(resource);
249
250 /* Only allow explicit conversions */
251 if (lvi && !(flags & LKF_CONVERT)) {
252 errno = EBUSY;
253 return -1;
254 }
255 if (lvi) {
256 /* Already exists - convert it */
257 status =
258 sync_lock(resource, mode, flags, &lvi->lock_id);
259 saved_errno = errno;
260 if (!status)
261 lvi->lock_mode = mode;
262
263 if (status) {
264 DEBUGLOG("hold_lock. convert to %d failed: %s\n", mode,
265 strerror(errno));
266 }
267 errno = saved_errno;
268 } else {
269 lvi = malloc(sizeof(struct lv_info));
270 if (!lvi)
271 return -1;
272
273 lvi->lock_mode = mode;
274 status = sync_lock(resource, mode, flags, &lvi->lock_id);
275 saved_errno = errno;
276 if (status) {
277 free(lvi);
278 DEBUGLOG("hold_lock. lock at %d failed: %s\n", mode,
279 strerror(errno));
280 } else
281 insert_info(resource, lvi);
282
283 errno = saved_errno;
284 }
285 return status;
286 }
287
288 /* Unlock and remove it from the hash table */
hold_unlock(char * resource)289 int hold_unlock(char *resource)
290 {
291 struct lv_info *lvi;
292 int status;
293 int saved_errno;
294
295 if (!(lvi = lookup_info(resource))) {
296 DEBUGLOG("hold_unlock, lock not already held\n");
297 return 0;
298 }
299
300 status = sync_unlock(resource, lvi->lock_id);
301 saved_errno = errno;
302 if (!status) {
303 remove_info(resource);
304 free(lvi);
305 } else {
306 DEBUGLOG("hold_unlock. unlock failed(%d): %s\n", status,
307 strerror(errno));
308 }
309
310 errno = saved_errno;
311 return status;
312 }
313
314 /* Watch the return codes here.
315 liblvm API functions return 1(true) for success, 0(false) for failure and don't set errno.
316 libdlm API functions return 0 for success, -1 for failure and do set errno.
317 These functions here return 0 for success or >0 for failure (where the retcode is errno)
318 */
319
320 /* Activate LV exclusive or non-exclusive */
do_activate_lv(char * resource,unsigned char lock_flags,int mode)321 static int do_activate_lv(char *resource, unsigned char lock_flags, int mode)
322 {
323 int oldmode;
324 int status;
325 int activate_lv;
326 int exclusive = 0;
327 struct lvinfo lvi;
328
329 /* Is it already open ? */
330 oldmode = get_current_lock(resource);
331 if (oldmode == mode) {
332 return 0; /* Nothing to do */
333 }
334
335 /* Does the config file want us to activate this LV ? */
336 if (!lv_activation_filter(cmd, resource, &activate_lv))
337 return EIO;
338
339 if (!activate_lv)
340 return 0; /* Success, we did nothing! */
341
342 /* Do we need to activate exclusively? */
343 if ((activate_lv == 2) || (mode == LKM_EXMODE)) {
344 exclusive = 1;
345 mode = LKM_EXMODE;
346 }
347
348 /* Try to get the lock if it's a clustered volume group */
349 if (lock_flags & LCK_CLUSTER_VG) {
350 status = hold_lock(resource, mode, LKF_NOQUEUE | (lock_flags & LCK_CONVERT?LKF_CONVERT:0));
351 if (status) {
352 /* Return an LVM-sensible error for this.
353 * Forcing EIO makes the upper level return this text
354 * rather than the strerror text for EAGAIN.
355 */
356 if (errno == EAGAIN) {
357 sprintf(last_error, "Volume is busy on another node");
358 errno = EIO;
359 }
360 return errno;
361 }
362 }
363
364 /* If it's suspended then resume it */
365 if (!lv_info_by_lvid(cmd, resource, &lvi, 0, 0))
366 return EIO;
367
368 if (lvi.suspended)
369 if (!lv_resume(cmd, resource))
370 return EIO;
371
372 /* Now activate it */
373 if (!lv_activate(cmd, resource, exclusive))
374 return EIO;
375
376 return 0;
377 }
378
379 /* Resume the LV if it was active */
do_resume_lv(char * resource)380 static int do_resume_lv(char *resource)
381 {
382 int oldmode;
383
384 /* Is it open ? */
385 oldmode = get_current_lock(resource);
386 if (oldmode == -1) {
387 DEBUGLOG("do_resume_lv, lock not already held\n");
388 return 0; /* We don't need to do anything */
389 }
390
391 if (!lv_resume_if_active(cmd, resource))
392 return EIO;
393
394 return 0;
395 }
396
397 /* Suspend the device if active */
do_suspend_lv(char * resource)398 static int do_suspend_lv(char *resource)
399 {
400 int oldmode;
401 struct lvinfo lvi;
402
403 /* Is it open ? */
404 oldmode = get_current_lock(resource);
405 if (oldmode == -1) {
406 DEBUGLOG("do_suspend_lv, lock held at %d\n", oldmode);
407 return 0; /* Not active, so it's OK */
408 }
409
410 /* Only suspend it if it exists */
411 if (!lv_info_by_lvid(cmd, resource, &lvi, 0, 0))
412 return EIO;
413
414 if (lvi.exists) {
415 if (!lv_suspend_if_active(cmd, resource)) {
416 return EIO;
417 }
418 }
419 return 0;
420 }
421
do_deactivate_lv(char * resource,unsigned char lock_flags)422 static int do_deactivate_lv(char *resource, unsigned char lock_flags)
423 {
424 int oldmode;
425 int status;
426
427 /* Is it open ? */
428 oldmode = get_current_lock(resource);
429 if (oldmode == -1 && (lock_flags & LCK_CLUSTER_VG)) {
430 DEBUGLOG("do_deactivate_lock, lock not already held\n");
431 return 0; /* We don't need to do anything */
432 }
433
434 if (!lv_deactivate(cmd, resource))
435 return EIO;
436
437 if (lock_flags & LCK_CLUSTER_VG) {
438 status = hold_unlock(resource);
439 if (status)
440 return errno;
441 }
442
443 return 0;
444 }
445
do_lock_query(char * resource)446 const char *do_lock_query(char *resource)
447 {
448 int mode;
449 const char *type = NULL;
450
451 mode = get_current_lock(resource);
452 switch (mode) {
453 case LKM_NLMODE: type = "NL"; break;
454 case LKM_CRMODE: type = "CR"; break;
455 case LKM_CWMODE: type = "CW"; break;
456 case LKM_PRMODE: type = "PR"; break;
457 case LKM_PWMODE: type = "PW"; break;
458 case LKM_EXMODE: type = "EX"; break;
459 }
460
461 DEBUGLOG("do_lock_query: resource '%s', mode %i (%s)\n", resource, mode, type ?: "?");
462
463 return type;
464 }
465
466 /* This is the LOCK_LV part that happens on all nodes in the cluster -
467 it is responsible for the interaction with device-mapper and LVM */
do_lock_lv(unsigned char command,unsigned char lock_flags,char * resource)468 int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
469 {
470 int status = 0;
471
472 DEBUGLOG("do_lock_lv: resource '%s', cmd = %s, flags = %s\n",
473 resource, decode_locking_cmd(command), decode_flags(lock_flags));
474
475 if (!cmd->config_valid || config_files_changed(cmd)) {
476 /* Reinitialise various settings inc. logging, filters */
477 if (do_refresh_cache()) {
478 log_error("Updated config file invalid. Aborting.");
479 return EINVAL;
480 }
481 }
482
483 pthread_mutex_lock(&lvm_lock);
484 if (lock_flags & LCK_MIRROR_NOSYNC_MODE)
485 init_mirror_in_sync(1);
486
487 if (!(lock_flags & LCK_DMEVENTD_MONITOR_MODE))
488 init_dmeventd_monitor(0);
489
490 cmd->partial_activation = (lock_flags & LCK_PARTIAL_MODE) ? 1 : 0;
491
492 switch (command & LCK_MASK) {
493 case LCK_LV_EXCLUSIVE:
494 status = do_activate_lv(resource, lock_flags, LKM_EXMODE);
495 break;
496
497 case LCK_LV_SUSPEND:
498 status = do_suspend_lv(resource);
499 if (!status)
500 suspended++;
501 break;
502
503 case LCK_UNLOCK:
504 case LCK_LV_RESUME: /* if active */
505 status = do_resume_lv(resource);
506 if (!status)
507 suspended--;
508 break;
509
510 case LCK_LV_ACTIVATE:
511 status = do_activate_lv(resource, lock_flags, LKM_CRMODE);
512 break;
513
514 case LCK_LV_DEACTIVATE:
515 status = do_deactivate_lv(resource, lock_flags);
516 break;
517
518 default:
519 DEBUGLOG("Invalid LV command 0x%x\n", command);
520 status = EINVAL;
521 break;
522 }
523
524 if (lock_flags & LCK_MIRROR_NOSYNC_MODE)
525 init_mirror_in_sync(0);
526
527 if (!(lock_flags & LCK_DMEVENTD_MONITOR_MODE))
528 init_dmeventd_monitor(DEFAULT_DMEVENTD_MONITOR);
529
530 cmd->partial_activation = 0;
531
532 /* clean the pool for another command */
533 dm_pool_empty(cmd->mem);
534 pthread_mutex_unlock(&lvm_lock);
535
536 DEBUGLOG("Command return is %d\n", status);
537 return status;
538 }
539
540 /* Functions to do on the local node only BEFORE the cluster-wide stuff above happens */
pre_lock_lv(unsigned char command,unsigned char lock_flags,char * resource)541 int pre_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
542 {
543 /* Nearly all the stuff happens cluster-wide. Apart from SUSPEND. Here we get the
544 lock out on this node (because we are the node modifying the metadata)
545 before suspending cluster-wide.
546 */
547 if (command == LCK_LV_SUSPEND) {
548 DEBUGLOG("pre_lock_lv: resource '%s', cmd = %s, flags = %s\n",
549 resource, decode_locking_cmd(command), decode_flags(lock_flags));
550
551 if (hold_lock(resource, LKM_PWMODE, LKF_NOQUEUE| (lock_flags & LCK_CONVERT?LKF_CONVERT:0)))
552 return errno;
553 }
554 return 0;
555 }
556
557 /* Functions to do on the local node only AFTER the cluster-wide stuff above happens */
post_lock_lv(unsigned char command,unsigned char lock_flags,char * resource)558 int post_lock_lv(unsigned char command, unsigned char lock_flags,
559 char *resource)
560 {
561 int status;
562
563 /* Opposite of above, done on resume after a metadata update */
564 if (command == LCK_LV_RESUME) {
565 int oldmode;
566
567 DEBUGLOG
568 ("post_lock_lv: resource '%s', cmd = %s, flags = %s\n",
569 resource, decode_locking_cmd(command), decode_flags(lock_flags));
570
571 /* If the lock state is PW then restore it to what it was */
572 oldmode = get_current_lock(resource);
573 if (oldmode == LKM_PWMODE) {
574 struct lvinfo lvi;
575
576 pthread_mutex_lock(&lvm_lock);
577 status = lv_info_by_lvid(cmd, resource, &lvi, 0, 0);
578 pthread_mutex_unlock(&lvm_lock);
579 if (!status)
580 return EIO;
581
582 if (lvi.exists) {
583 if (hold_lock(resource, LKM_CRMODE, lock_flags & LCK_CONVERT?LKF_CONVERT:0))
584 return errno;
585 } else {
586 if (hold_unlock(resource))
587 return errno;
588 }
589 }
590 }
591 return 0;
592 }
593
594 /* Check if a VG is in use by LVM1 so we don't stomp on it */
do_check_lvm1(const char * vgname)595 int do_check_lvm1(const char *vgname)
596 {
597 int status;
598
599 status = check_lvm1_vg_inactive(cmd, vgname);
600
601 return status == 1 ? 0 : EBUSY;
602 }
603
do_refresh_cache()604 int do_refresh_cache()
605 {
606 DEBUGLOG("Refreshing context\n");
607 log_notice("Refreshing context");
608
609 pthread_mutex_lock(&lvm_lock);
610
611 if (!refresh_toolcontext(cmd)) {
612 pthread_mutex_unlock(&lvm_lock);
613 return -1;
614 }
615
616 init_full_scan_done(0);
617 lvmcache_label_scan(cmd, 2);
618 dm_pool_empty(cmd->mem);
619
620 pthread_mutex_unlock(&lvm_lock);
621
622 return 0;
623 }
624
625
626 /* Only called at gulm startup. Drop any leftover VG or P_orphan locks
627 that might be hanging around if we died for any reason
628 */
drop_vg_locks()629 static void drop_vg_locks()
630 {
631 char vg[128];
632 char line[255];
633 FILE *vgs =
634 popen
635 ("lvm pvs --config 'log{command_names=0 prefix=\"\"}' --nolocking --noheadings -o vg_name", "r");
636
637 sync_unlock("P_" VG_ORPHANS, LCK_EXCL);
638 sync_unlock("P_" VG_GLOBAL, LCK_EXCL);
639
640 if (!vgs)
641 return;
642
643 while (fgets(line, sizeof(line), vgs)) {
644 char *vgend;
645 char *vgstart;
646
647 if (line[strlen(line)-1] == '\n')
648 line[strlen(line)-1] = '\0';
649
650 vgstart = line + strspn(line, " ");
651 vgend = vgstart + strcspn(vgstart, " ");
652 *vgend = '\0';
653
654 if (strncmp(vgstart, "WARNING:", 8) == 0)
655 continue;
656
657 sprintf(vg, "V_%s", vgstart);
658 sync_unlock(vg, LCK_EXCL);
659
660 }
661 if (fclose(vgs))
662 DEBUGLOG("vgs fclose failed: %s\n", strerror(errno));
663 }
664
665 /*
666 * Drop lvmcache metadata
667 */
drop_metadata(const char * vgname)668 void drop_metadata(const char *vgname)
669 {
670 DEBUGLOG("Dropping metadata for VG %s\n", vgname);
671 pthread_mutex_lock(&lvm_lock);
672 lvmcache_drop_metadata(vgname);
673 pthread_mutex_unlock(&lvm_lock);
674 }
675
676 /*
677 * Ideally, clvmd should be started before any LVs are active
678 * but this may not be the case...
679 * I suppose this also comes in handy if clvmd crashes, not that it would!
680 */
get_initial_state()681 static void *get_initial_state()
682 {
683 char lv[64], vg[64], flags[25], vg_flags[25];
684 char uuid[65];
685 char line[255];
686 FILE *lvs =
687 popen
688 ("lvm lvs --config 'log{command_names=0 prefix=\"\"}' --nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr,vg_attr",
689 "r");
690
691 if (!lvs)
692 return NULL;
693
694 while (fgets(line, sizeof(line), lvs)) {
695 if (sscanf(line, "%s %s %s %s\n", vg, lv, flags, vg_flags) == 4) {
696
697 /* States: s:suspended a:active S:dropped snapshot I:invalid snapshot */
698 if (strlen(vg) == 38 && /* is is a valid UUID ? */
699 (flags[4] == 'a' || flags[4] == 's') && /* is it active or suspended? */
700 vg_flags[5] == 'c') { /* is it clustered ? */
701 /* Convert hyphen-separated UUIDs into one */
702 memcpy(&uuid[0], &vg[0], 6);
703 memcpy(&uuid[6], &vg[7], 4);
704 memcpy(&uuid[10], &vg[12], 4);
705 memcpy(&uuid[14], &vg[17], 4);
706 memcpy(&uuid[18], &vg[22], 4);
707 memcpy(&uuid[22], &vg[27], 4);
708 memcpy(&uuid[26], &vg[32], 6);
709 memcpy(&uuid[32], &lv[0], 6);
710 memcpy(&uuid[38], &lv[7], 4);
711 memcpy(&uuid[42], &lv[12], 4);
712 memcpy(&uuid[46], &lv[17], 4);
713 memcpy(&uuid[50], &lv[22], 4);
714 memcpy(&uuid[54], &lv[27], 4);
715 memcpy(&uuid[58], &lv[32], 6);
716 uuid[64] = '\0';
717
718 DEBUGLOG("getting initial lock for %s\n", uuid);
719 hold_lock(uuid, LKM_CRMODE, LKF_NOQUEUE);
720 }
721 }
722 }
723 if (fclose(lvs))
724 DEBUGLOG("lvs fclose failed: %s\n", strerror(errno));
725 return NULL;
726 }
727
lvm2_log_fn(int level,const char * file,int line,int dm_errno,const char * message)728 static void lvm2_log_fn(int level, const char *file, int line, int dm_errno,
729 const char *message)
730 {
731
732 /* Send messages to the normal LVM2 logging system too,
733 so we get debug output when it's asked for.
734 We need to NULL the function ptr otherwise it will just call
735 back into here! */
736 init_log_fn(NULL);
737 print_log(level, file, line, dm_errno, "%s", message);
738 init_log_fn(lvm2_log_fn);
739
740 /*
741 * Ignore non-error messages, but store the latest one for returning
742 * to the user.
743 */
744 if (level != _LOG_ERR && level != _LOG_FATAL)
745 return;
746
747 strncpy(last_error, message, sizeof(last_error));
748 last_error[sizeof(last_error)-1] = '\0';
749 }
750
751 /* This checks some basic cluster-LVM configuration stuff */
check_config()752 static void check_config()
753 {
754 int locking_type;
755
756 locking_type = find_config_tree_int(cmd, "global/locking_type", 1);
757
758 if (locking_type == 3) /* compiled-in cluster support */
759 return;
760
761 if (locking_type == 2) { /* External library, check name */
762 const char *libname;
763
764 libname = find_config_tree_str(cmd, "global/locking_library",
765 "");
766 if (strstr(libname, "liblvm2clusterlock.so"))
767 return;
768
769 log_error("Incorrect LVM locking library specified in lvm.conf, cluster operations may not work.");
770 return;
771 }
772 log_error("locking_type not set correctly in lvm.conf, cluster operations will not work.");
773 }
774
775 /* Backups up the LVM metadata if it's changed */
lvm_do_backup(const char * vgname)776 void lvm_do_backup(const char *vgname)
777 {
778 struct volume_group * vg;
779 int consistent = 0;
780
781 DEBUGLOG("Triggering backup of VG metadata for %s. suspended=%d\n", vgname, suspended);
782
783 pthread_mutex_lock(&lvm_lock);
784
785 vg = vg_read_internal(cmd, vgname, NULL /*vgid*/, &consistent);
786
787 if (vg && consistent)
788 check_current_backup(vg);
789 else
790 log_error("Error backing up metadata, can't find VG for group %s", vgname);
791
792 vg_release(vg);
793 dm_pool_empty(cmd->mem);
794
795 pthread_mutex_unlock(&lvm_lock);
796 }
797
798 /* Called to initialise the LVM context of the daemon */
init_lvm(int using_gulm)799 int init_lvm(int using_gulm)
800 {
801 if (!(cmd = create_toolcontext(1, NULL))) {
802 log_error("Failed to allocate command context");
803 return 0;
804 }
805
806 if (stored_errno()) {
807 destroy_toolcontext(cmd);
808 return 0;
809 }
810
811 /* Use LOG_DAEMON for syslog messages instead of LOG_USER */
812 init_syslog(LOG_DAEMON);
813 openlog("clvmd", LOG_PID, LOG_DAEMON);
814 cmd->cmd_line = "clvmd";
815
816 /* Check lvm.conf is setup for cluster-LVM */
817 check_config();
818
819 /* Remove any non-LV locks that may have been left around */
820 if (using_gulm)
821 drop_vg_locks();
822
823 get_initial_state();
824
825 /* Trap log messages so we can pass them back to the user */
826 init_log_fn(lvm2_log_fn);
827
828 return 1;
829 }
830
destroy_lvm(void)831 void destroy_lvm(void)
832 {
833 if (cmd)
834 destroy_toolcontext(cmd);
835 cmd = NULL;
836 }
837