xref: /dragonfly/contrib/lvm2/dist/daemons/clvmd/lvm-functions.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
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