LCOV - code coverage report
Current view: top level - misc/kabi/lvm2.git/lib/locking - locking.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 75 247 30.4 %
Date: 2010-04-13 Functions: 11 22 50.0 %
Branches: 37 204 18.1 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
       3                 :            :  * Copyright (C) 2004-2007 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 "locking.h"
      18                 :            : #include "locking_types.h"
      19                 :            : #include "lvm-string.h"
      20                 :            : #include "activate.h"
      21                 :            : #include "toolcontext.h"
      22                 :            : #include "memlock.h"
      23                 :            : #include "defaults.h"
      24                 :            : #include "lvmcache.h"
      25                 :            : 
      26                 :            : #include <assert.h>
      27                 :            : #include <signal.h>
      28                 :            : #include <sys/stat.h>
      29                 :            : #include <limits.h>
      30                 :            : #include <unistd.h>
      31                 :            : 
      32                 :            : static struct locking_type _locking;
      33                 :            : static sigset_t _oldset;
      34                 :            : 
      35                 :            : static int _vg_lock_count = 0;          /* Number of locks held */
      36                 :            : static int _vg_write_lock_held = 0;     /* VG write lock held? */
      37                 :            : static int _signals_blocked = 0;
      38                 :            : static int _blocking_supported = 0;
      39                 :            : 
      40                 :            : static volatile sig_atomic_t _sigint_caught = 0;
      41                 :            : static volatile sig_atomic_t _handler_installed;
      42                 :            : static struct sigaction _oldhandler;
      43                 :            : static int _oldmasked;
      44                 :            : 
      45                 :            : typedef enum {
      46                 :            :         LV_NOOP,
      47                 :            :         LV_SUSPEND,
      48                 :            :         LV_RESUME
      49                 :            : } lv_operation_t;
      50                 :            : 
      51                 :          0 : static void _catch_sigint(int unused __attribute__((unused)))
      52                 :            : {
      53                 :          0 :         _sigint_caught = 1;
      54                 :          0 : }
      55                 :            : 
      56                 :          0 : int sigint_caught(void) {
      57                 :          0 :         return _sigint_caught;
      58                 :            : }
      59                 :            : 
      60                 :          1 : void sigint_clear(void)
      61                 :            : {
      62                 :          1 :         _sigint_caught = 0;
      63                 :          1 : }
      64                 :            : 
      65                 :            : /*
      66                 :            :  * Temporarily allow keyboard interrupts to be intercepted and noted;
      67                 :            :  * saves interrupt handler state for sigint_restore().  Users should
      68                 :            :  * use the sigint_caught() predicate to check whether interrupt was
      69                 :            :  * requested and act appropriately.  Interrupt flags are never
      70                 :            :  * cleared automatically by this code, but the tools clear the flag
      71                 :            :  * before running each command in lvm_run_command().  All other places
      72                 :            :  * where the flag needs to be cleared need to call sigint_clear().
      73                 :            :  */
      74                 :            : 
      75                 :          0 : void sigint_allow(void)
      76                 :            : {
      77                 :            :         struct sigaction handler;
      78                 :            :         sigset_t sigs;
      79                 :            : 
      80                 :            :         /*
      81                 :            :          * Do not overwrite the backed-up handler data -
      82                 :            :          * just increase nesting count.
      83                 :            :          */
      84         [ #  # ]:          0 :         if (_handler_installed) {
      85                 :          0 :                 _handler_installed++;
      86                 :          0 :                 return;
      87                 :            :         }
      88                 :            : 
      89                 :            :         /* Grab old sigaction for SIGINT: shall not fail. */
      90                 :          0 :         sigaction(SIGINT, NULL, &handler);
      91                 :          0 :         handler.sa_flags &= ~SA_RESTART; /* Clear restart flag */
      92                 :          0 :         handler.sa_handler = _catch_sigint;
      93                 :            : 
      94                 :          0 :         _handler_installed = 1;
      95                 :            : 
      96                 :            :         /* Override the signal handler: shall not fail. */
      97                 :          0 :         sigaction(SIGINT, &handler, &_oldhandler);
      98                 :            : 
      99                 :            :         /* Unmask SIGINT.  Remember to mask it again on restore. */
     100                 :          0 :         sigprocmask(0, NULL, &sigs);
     101         [ #  # ]:          0 :         if ((_oldmasked = sigismember(&sigs, SIGINT))) {
     102                 :          0 :                 sigdelset(&sigs, SIGINT);
     103                 :          0 :                 sigprocmask(SIG_SETMASK, &sigs, NULL);
     104                 :            :         }
     105                 :            : }
     106                 :            : 
     107                 :          0 : void sigint_restore(void)
     108                 :            : {
     109         [ #  # ]:          0 :         if (!_handler_installed)
     110                 :          0 :                 return;
     111                 :            : 
     112         [ #  # ]:          0 :         if (_handler_installed > 1) {
     113                 :          0 :                 _handler_installed--;
     114                 :          0 :                 return;
     115                 :            :         }
     116                 :            : 
     117                 :            :         /* Nesting count went down to 0. */
     118                 :          0 :         _handler_installed = 0;
     119                 :            : 
     120         [ #  # ]:          0 :         if (_oldmasked) {
     121                 :            :                 sigset_t sigs;
     122                 :          0 :                 sigprocmask(0, NULL, &sigs);
     123                 :          0 :                 sigaddset(&sigs, SIGINT);
     124                 :          0 :                 sigprocmask(SIG_SETMASK, &sigs, NULL);
     125                 :            :         }
     126                 :            : 
     127                 :          0 :         sigaction(SIGINT, &_oldhandler, NULL);
     128                 :            : }
     129                 :            : 
     130                 :          2 : static void _block_signals(uint32_t flags __attribute((unused)))
     131                 :            : {
     132                 :            :         sigset_t set;
     133                 :            : 
     134         [ -  + ]:          2 :         if (_signals_blocked)
     135                 :          0 :                 return;
     136                 :            : 
     137         [ -  + ]:          2 :         if (sigfillset(&set)) {
     138                 :          0 :                 log_sys_error("sigfillset", "_block_signals");
     139                 :          0 :                 return;
     140                 :            :         }
     141                 :            : 
     142         [ -  + ]:          2 :         if (sigprocmask(SIG_SETMASK, &set, &_oldset)) {
     143                 :          0 :                 log_sys_error("sigprocmask", "_block_signals");
     144                 :          0 :                 return;
     145                 :            :         }
     146                 :            : 
     147                 :          2 :         _signals_blocked = 1;
     148                 :            : }
     149                 :            : 
     150                 :          2 : static void _unblock_signals(void)
     151                 :            : {
     152                 :            :         /* Don't unblock signals while any locks are held */
     153 [ +  - ][ -  + ]:          2 :         if (!_signals_blocked || _vg_lock_count)
     154                 :          0 :                 return;
     155                 :            : 
     156         [ -  + ]:          2 :         if (sigprocmask(SIG_SETMASK, &_oldset, NULL)) {
     157                 :          0 :                 log_sys_error("sigprocmask", "_block_signals");
     158                 :          0 :                 return;
     159                 :            :         }
     160                 :            : 
     161                 :          2 :         _signals_blocked = 0;
     162                 :            : }
     163                 :            : 
     164                 :          2 : static void _lock_memory(struct cmd_context *cmd, lv_operation_t lv_op)
     165                 :            : {
     166         [ +  - ]:          2 :         if (!(_locking.flags & LCK_PRE_MEMLOCK))
     167                 :          2 :                 return;
     168                 :            : 
     169         [ #  # ]:          0 :         if (lv_op == LV_SUSPEND)
     170                 :          2 :                 memlock_inc(cmd);
     171                 :            : }
     172                 :            : 
     173                 :          2 : static void _unlock_memory(struct cmd_context *cmd, lv_operation_t lv_op)
     174                 :            : {
     175         [ +  - ]:          2 :         if (!(_locking.flags & LCK_PRE_MEMLOCK))
     176                 :          2 :                 return;
     177                 :            : 
     178         [ #  # ]:          0 :         if (lv_op == LV_RESUME)
     179                 :          2 :                 memlock_dec(cmd);
     180                 :            : }
     181                 :            : 
     182                 :          0 : void reset_locking(void)
     183                 :            : {
     184                 :          0 :         int was_locked = _vg_lock_count;
     185                 :            : 
     186                 :          0 :         _vg_lock_count = 0;
     187                 :          0 :         _vg_write_lock_held = 0;
     188                 :            : 
     189         [ #  # ]:          0 :         if (_locking.reset_locking)
     190                 :          0 :                 _locking.reset_locking();
     191                 :            : 
     192         [ #  # ]:          0 :         if (was_locked)
     193                 :          0 :                 _unblock_signals();
     194                 :          0 : }
     195                 :            : 
     196                 :          2 : static void _update_vg_lock_count(const char *resource, uint32_t flags)
     197                 :            : {
     198                 :            :         /* Ignore locks not associated with updating VG metadata */
     199 [ +  - ][ +  - ]:          2 :         if ((flags & LCK_SCOPE_MASK) != LCK_VG ||
                 [ +  - ]
     200                 :          2 :             (flags & LCK_CACHE) ||
     201                 :          2 :             !strcmp(resource, VG_GLOBAL))
     202                 :          2 :                 return;
     203                 :            : 
     204         [ #  # ]:          0 :         if ((flags & LCK_TYPE_MASK) == LCK_UNLOCK)
     205                 :          0 :                 _vg_lock_count--;
     206                 :            :         else
     207                 :          0 :                 _vg_lock_count++;
     208                 :            : 
     209                 :            :         /* We don't bother to reset this until all VG locks are dropped */
     210         [ #  # ]:          0 :         if ((flags & LCK_TYPE_MASK) == LCK_WRITE)
     211                 :          0 :                 _vg_write_lock_held = 1;
     212         [ #  # ]:          0 :         else if (!_vg_lock_count)
     213                 :          2 :                 _vg_write_lock_held = 0;
     214                 :            : }
     215                 :            : 
     216                 :            : /*
     217                 :            :  * Select a locking type
     218                 :            :  * type: locking type; if < 0, then read config tree value
     219                 :            :  */
     220                 :          1 : int init_locking(int type, struct cmd_context *cmd)
     221                 :            : {
     222                 :          1 :         int suppress_messages = 0;
     223                 :            : 
     224 [ -  + ][ #  # ]:          1 :         if (ignorelockingfailure() && getenv("LVM_SUPPRESS_LOCKING_FAILURE_MESSAGES"))
     225                 :          0 :                 suppress_messages = 1;
     226                 :            : 
     227         [ +  - ]:          1 :         if (type < 0)
     228                 :          1 :                 type = find_config_tree_int(cmd, "global/locking_type", 1);
     229                 :            : 
     230                 :          1 :         _blocking_supported = find_config_tree_int(cmd,
     231                 :            :             "global/wait_for_locks", DEFAULT_WAIT_FOR_LOCKS);
     232                 :            : 
     233 [ -  +  -  -  - :          1 :         switch (type) {
                      - ]
     234                 :            :         case 0:
     235                 :          0 :                 init_no_locking(&_locking, cmd);
     236                 :          0 :                 log_warn("WARNING: Locking disabled. Be careful! "
     237                 :            :                           "This could corrupt your metadata.");
     238                 :          0 :                 return 1;
     239                 :            : 
     240                 :            :         case 1:
     241         [ +  - ]:          1 :                 log_very_verbose("%sFile-based locking selected.",
     242                 :            :                                  _blocking_supported ? "" : "Non-blocking ");
     243                 :            : 
     244         [ -  + ]:          1 :                 if (!init_file_locking(&_locking, cmd)) {
     245         [ #  # ]:          0 :                         log_error_suppress(suppress_messages,
     246                 :            :                                            "File-based locking initialisation failed.");
     247                 :          0 :                         break;
     248                 :            :                 }
     249                 :          1 :                 return 1;
     250                 :            : 
     251                 :            : #ifdef HAVE_LIBDL
     252                 :            :         case 2:
     253         [ #  # ]:          0 :                 if (!is_static()) {
     254                 :          0 :                         log_very_verbose("External locking selected.");
     255         [ #  # ]:          0 :                         if (init_external_locking(&_locking, cmd))
     256                 :          0 :                                 return 1;
     257                 :            :                 }
     258         [ #  # ]:          0 :                 if (!find_config_tree_int(cmd, "locking/fallback_to_clustered_locking",
     259                 :            :                             find_config_tree_int(cmd, "global/fallback_to_clustered_locking",
     260                 :            :                                                  DEFAULT_FALLBACK_TO_CLUSTERED_LOCKING))) {
     261                 :          0 :                         log_error("External locking initialisation failed.");
     262                 :          0 :                         break;
     263                 :            :                 }
     264                 :            : #endif
     265                 :            : 
     266                 :            : #ifdef CLUSTER_LOCKING_INTERNAL
     267                 :          0 :                 log_very_verbose("Falling back to internal clustered locking.");
     268                 :            :                 /* Fall through */
     269                 :            : 
     270                 :            :         case 3:
     271                 :          0 :                 log_very_verbose("Cluster locking selected.");
     272         [ #  # ]:          0 :                 if (!init_cluster_locking(&_locking, cmd)) {
     273         [ #  # ]:          0 :                         log_error_suppress(suppress_messages,
     274                 :            :                                            "Internal cluster locking initialisation failed.");
     275                 :          0 :                         break;
     276                 :            :                 }
     277                 :          0 :                 return 1;
     278                 :            : #endif
     279                 :            : 
     280                 :            :         case 4:
     281                 :          0 :                 log_verbose("Read-only locking selected. "
     282                 :            :                             "Only read operations permitted.");
     283         [ #  # ]:          0 :                 if (!init_readonly_locking(&_locking, cmd))
     284                 :          0 :                         break;
     285                 :          0 :                 return 1;
     286                 :            : 
     287                 :            :         default:
     288                 :          0 :                 log_error("Unknown locking type requested.");
     289                 :          0 :                 return 0;
     290                 :            :         }
     291                 :            : 
     292         [ #  # ]:          0 :         if ((type == 2 || type == 3) &&
           [ #  #  #  # ]
     293                 :            :             find_config_tree_int(cmd, "locking/fallback_to_local_locking",
     294                 :            :                     find_config_tree_int(cmd, "global/fallback_to_local_locking",
     295                 :          0 :                                          DEFAULT_FALLBACK_TO_LOCAL_LOCKING))) {
     296         [ #  # ]:          0 :                 log_warn_suppress(suppress_messages, "WARNING: Falling back to local file-based locking.");
     297         [ #  # ]:          0 :                 log_warn_suppress(suppress_messages,
     298                 :            :                                   "Volume Groups with the clustered attribute will "
     299                 :            :                                   "be inaccessible.");
     300         [ #  # ]:          0 :                 if (init_file_locking(&_locking, cmd))
     301                 :          0 :                         return 1;
     302                 :            :                 else
     303         [ #  # ]:          0 :                         log_error_suppress(suppress_messages,
     304                 :            :                                            "File-based locking initialisation failed.");
     305                 :            :         }
     306                 :            : 
     307         [ #  # ]:          0 :         if (!ignorelockingfailure())
     308                 :          0 :                 return 0;
     309                 :            : 
     310                 :          0 :         log_verbose("Locking disabled - only read operations permitted.");
     311                 :          0 :         init_readonly_locking(&_locking, cmd);
     312                 :            : 
     313                 :          1 :         return 1;
     314                 :            : }
     315                 :            : 
     316                 :          1 : void fin_locking(void)
     317                 :            : {
     318                 :          1 :         _locking.fin_locking();
     319                 :          1 : }
     320                 :            : 
     321                 :            : /*
     322                 :            :  * Does the LVM1 driver know of this VG name?
     323                 :            :  */
     324                 :          2 : int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname)
     325                 :            : {
     326                 :            :         struct stat info;
     327                 :            :         char path[PATH_MAX];
     328                 :            : 
     329                 :            :         /* We'll allow operations on orphans */
     330         [ +  - ]:          2 :         if (is_orphan_vg(vgname))
     331                 :          2 :                 return 1;
     332                 :            : 
     333                 :            :         /* LVM1 is only present in 2.4 kernels. */
     334         [ #  # ]:          0 :         if (strncmp(cmd->kernel_vsn, "2.4.", 4))
     335                 :          0 :                 return 1;
     336                 :            : 
     337         [ #  # ]:          0 :         if (dm_snprintf(path, sizeof(path), "%s/lvm/VGs/%s", cmd->proc_dir,
     338                 :            :                          vgname) < 0) {
     339                 :          0 :                 log_error("LVM1 proc VG pathname too long for %s", vgname);
     340                 :          0 :                 return 0;
     341                 :            :         }
     342                 :            : 
     343         [ #  # ]:          0 :         if (stat(path, &info) == 0) {
     344                 :          0 :                 log_error("%s exists: Is the original LVM driver using "
     345                 :            :                           "this volume group?", path);
     346                 :          0 :                 return 0;
     347 [ #  # ][ #  # ]:          0 :         } else if (errno != ENOENT && errno != ENOTDIR) {
     348                 :          0 :                 log_sys_error("stat", path);
     349                 :          0 :                 return 0;
     350                 :            :         }
     351                 :            : 
     352                 :          2 :         return 1;
     353                 :            : }
     354                 :            : 
     355                 :            : /*
     356                 :            :  * VG locking is by VG name.
     357                 :            :  * FIXME This should become VG uuid.
     358                 :            :  */
     359                 :          2 : static int _lock_vol(struct cmd_context *cmd, const char *resource,
     360                 :            :                      uint32_t flags, lv_operation_t lv_op)
     361                 :            : {
     362                 :          2 :         int ret = 0;
     363                 :            : 
     364                 :          2 :         _block_signals(flags);
     365                 :          2 :         _lock_memory(cmd, lv_op);
     366                 :            : 
     367         [ -  + ]:          2 :         assert(resource);
     368                 :            : 
     369         [ -  + ]:          2 :         if (!*resource) {
     370                 :          0 :                 log_error(INTERNAL_ERROR "Use of P_orphans is deprecated.");
     371                 :          0 :                 return 0;
     372                 :            :         }
     373                 :            : 
     374 [ +  - ][ -  + ]:          2 :         if (*resource == '#' && (flags & LCK_CACHE)) {
     375                 :          0 :                 log_error(INTERNAL_ERROR "P_%s referenced", resource);
     376                 :          0 :                 return 0;
     377                 :            :         }
     378                 :            : 
     379         [ +  - ]:          2 :         if ((ret = _locking.lock_resource(cmd, resource, flags))) {
     380 [ +  - ][ +  - ]:          2 :                 if ((flags & LCK_SCOPE_MASK) == LCK_VG &&
     381                 :          2 :                     !(flags & LCK_CACHE)) {
     382         [ +  + ]:          2 :                         if ((flags & LCK_TYPE_MASK) == LCK_UNLOCK)
     383                 :          1 :                                 lvmcache_unlock_vgname(resource);
     384                 :            :                         else
     385                 :          1 :                                 lvmcache_lock_vgname(resource, (flags & LCK_TYPE_MASK)
     386                 :            :                                                                 == LCK_READ);
     387                 :            :                 }
     388                 :            : 
     389                 :          2 :                 _update_vg_lock_count(resource, flags);
     390                 :            :         } else
     391                 :          0 :                 stack;
     392                 :            : 
     393                 :          2 :         _unlock_memory(cmd, lv_op);
     394                 :          2 :         _unblock_signals();
     395                 :            : 
     396                 :          2 :         return ret;
     397                 :            : }
     398                 :            : 
     399                 :          2 : int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags)
     400                 :            : {
     401                 :            :         char resource[258] __attribute((aligned(8)));
     402                 :            :         lv_operation_t lv_op;
     403                 :            : 
     404      [ -  -  + ]:          2 :         switch (flags & (LCK_SCOPE_MASK | LCK_TYPE_MASK)) {
     405                 :            :                 case LCK_LV_SUSPEND:
     406                 :          0 :                                 lv_op = LV_SUSPEND;
     407                 :          0 :                                 break;
     408                 :            :                 case LCK_LV_RESUME:
     409                 :          0 :                                 lv_op = LV_RESUME;
     410                 :          0 :                                 break;
     411                 :          2 :                 default:        lv_op = LV_NOOP;
     412                 :            :         }
     413                 :            : 
     414                 :            : 
     415         [ -  + ]:          2 :         if (flags == LCK_NONE) {
     416                 :          0 :                 log_debug(INTERNAL_ERROR "%s: LCK_NONE lock requested", vol);
     417                 :          0 :                 return 1;
     418                 :            :         }
     419                 :            : 
     420      [ +  -  - ]:          2 :         switch (flags & LCK_SCOPE_MASK) {
     421                 :            :         case LCK_VG:
     422                 :            :                 /*
     423                 :            :                  * VG locks alphabetical, ORPHAN lock last
     424                 :            :                  */
     425         [ -  + ]:          2 :                 if (!_blocking_supported)
     426                 :          0 :                         flags |= LCK_NONBLOCK;
     427                 :            : 
     428 [ -  + ][ #  # ]:          2 :                 if (vol[0] != '#' &&
           [ #  #  #  # ]
     429                 :          0 :                     ((flags & LCK_TYPE_MASK) != LCK_UNLOCK) &&
     430                 :          0 :                     (!(flags & LCK_CACHE)) &&
     431                 :          0 :                     !lvmcache_verify_lock_order(vol))
     432                 :          0 :                         return 0;
     433                 :            : 
     434                 :            :                 /* Lock VG to change on-disk metadata. */
     435                 :            :                 /* If LVM1 driver knows about the VG, it can't be accessed. */
     436         [ -  + ]:          2 :                 if (!check_lvm1_vg_inactive(cmd, vol))
     437                 :          0 :                         return 0;
     438                 :          2 :                 break;
     439                 :            :         case LCK_LV:
     440                 :            :                 /* All LV locks are non-blocking. */
     441                 :          0 :                 flags |= LCK_NONBLOCK;
     442                 :          0 :                 break;
     443                 :            :         default:
     444                 :          0 :                 log_error("Unrecognised lock scope: %d",
     445                 :            :                           flags & LCK_SCOPE_MASK);
     446                 :          0 :                 return 0;
     447                 :            :         }
     448                 :            : 
     449                 :          2 :         strncpy(resource, vol, sizeof(resource));
     450                 :            : 
     451         [ -  + ]:          2 :         if (!_lock_vol(cmd, resource, flags, lv_op))
     452                 :          0 :                 return 0;
     453                 :            : 
     454                 :            :         /*
     455                 :            :          * If a real lock was acquired (i.e. not LCK_CACHE),
     456                 :            :          * perform an immediate unlock unless LCK_HOLD was requested.
     457                 :            :          */
     458 [ +  - ][ +  + ]:          2 :         if (!(flags & LCK_CACHE) && !(flags & LCK_HOLD) &&
                 [ -  + ]
     459                 :          1 :             ((flags & LCK_TYPE_MASK) != LCK_UNLOCK)) {
     460         [ #  # ]:          0 :                 if (!_lock_vol(cmd, resource,
     461                 :          0 :                                (flags & ~LCK_TYPE_MASK) | LCK_UNLOCK, lv_op))
     462                 :          0 :                         return 0;
     463                 :            :         }
     464                 :            : 
     465                 :          2 :         return 1;
     466                 :            : }
     467                 :            : 
     468                 :            : /* Unlock list of LVs */
     469                 :          0 : int resume_lvs(struct cmd_context *cmd, struct dm_list *lvs)
     470                 :            : {
     471                 :            :         struct lv_list *lvl;
     472                 :          0 :         int r = 1;
     473                 :            : 
     474         [ #  # ]:          0 :         dm_list_iterate_items(lvl, lvs)
     475 [ #  # ][ #  # ]:          0 :                 if (!resume_lv(cmd, lvl->lv)) {
                 [ #  # ]
     476                 :          0 :                         r = 0;
     477                 :          0 :                         stack;
     478                 :            :                 }
     479                 :            : 
     480                 :          0 :         return r;
     481                 :            : }
     482                 :            : 
     483                 :            : /* Lock a list of LVs */
     484                 :          0 : int suspend_lvs(struct cmd_context *cmd, struct dm_list *lvs)
     485                 :            : {
     486                 :            :         struct dm_list *lvh;
     487                 :            :         struct lv_list *lvl;
     488                 :            : 
     489         [ #  # ]:          0 :         dm_list_iterate_items(lvl, lvs) {
     490 [ #  # ][ #  # ]:          0 :                 if (!suspend_lv(cmd, lvl->lv)) {
                 [ #  # ]
     491                 :          0 :                         log_error("Failed to suspend %s", lvl->lv->name);
     492         [ #  # ]:          0 :                         dm_list_uniterate(lvh, lvs, &lvl->list) {
     493                 :          0 :                                 lvl = dm_list_item(lvh, struct lv_list);
     494 [ #  # ][ #  # ]:          0 :                                 if (!resume_lv(cmd, lvl->lv))
                 [ #  # ]
     495                 :          0 :                                         stack;
     496                 :            :                         }
     497                 :            : 
     498                 :          0 :                         return 0;
     499                 :            :                 }
     500                 :            :         }
     501                 :            : 
     502                 :          0 :         return 1;
     503                 :            : }
     504                 :            : 
     505                 :            : /* Lock a list of LVs */
     506                 :          0 : int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs, unsigned exclusive)
     507                 :            : {
     508                 :            :         struct dm_list *lvh;
     509                 :            :         struct lv_list *lvl;
     510                 :            : 
     511         [ #  # ]:          0 :         dm_list_iterate_items(lvl, lvs) {
     512         [ #  # ]:          0 :                 if (!exclusive) {
     513 [ #  # ][ #  # ]:          0 :                         if (!activate_lv(cmd, lvl->lv)) {
                 [ #  # ]
     514                 :          0 :                                 log_error("Failed to activate %s", lvl->lv->name);
     515                 :          0 :                                 return 0;
     516                 :            :                         }
     517 [ #  # ][ #  # ]:          0 :                 } else if (!activate_lv_excl(cmd, lvl->lv)) {
                 [ #  # ]
     518                 :          0 :                         log_error("Failed to activate %s", lvl->lv->name);
     519         [ #  # ]:          0 :                         dm_list_uniterate(lvh, lvs, &lvl->list) {
     520                 :          0 :                                 lvl = dm_list_item(lvh, struct lv_list);
     521 [ #  # ][ #  # ]:          0 :                                 if (!activate_lv(cmd, lvl->lv))
                 [ #  # ]
     522                 :          0 :                                         stack;
     523                 :            :                         }
     524                 :          0 :                         return 0;
     525                 :            :                 }
     526                 :            :         }
     527                 :            : 
     528                 :          0 :         return 1;
     529                 :            : }
     530                 :            : 
     531                 :          0 : int vg_write_lock_held(void)
     532                 :            : {
     533                 :          0 :         return _vg_write_lock_held;
     534                 :            : }
     535                 :            : 
     536                 :          0 : int locking_is_clustered(void)
     537                 :            : {
     538                 :          0 :         return (_locking.flags & LCK_CLUSTERED) ? 1 : 0;
     539                 :            : }
     540                 :            : 
     541                 :          0 : int remote_lock_held(const char *vol)
     542                 :            : {
     543                 :          0 :         int mode = LCK_NULL;
     544                 :            : 
     545         [ #  # ]:          0 :         if (!locking_is_clustered())
     546                 :          0 :                 return 0;
     547                 :            : 
     548         [ #  # ]:          0 :         if (!_locking.query_resource)
     549                 :          0 :                 return -1;
     550                 :            : 
     551                 :            :         /*
     552                 :            :          * If an error occured, expect that volume is active
     553                 :            :          */
     554         [ #  # ]:          0 :         if (!_locking.query_resource(vol, &mode)) {
     555                 :          0 :                 stack;
     556                 :          0 :                 return 1;
     557                 :            :         }
     558                 :            : 
     559                 :          0 :         return mode == LCK_NULL ? 0 : 1;
     560                 :            : }

Generated by: LCOV version 1.8