LCOV - code coverage report
Current view: top level - misc/kabi/lvm2.git/tools - lvchange.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 0 413 0.0 %
Date: 2010-04-13 Functions: 0 12 0.0 %
Branches: 0 492 0.0 %

           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 "tools.h"
      17                 :            : 
      18                 :          0 : static int lvchange_permission(struct cmd_context *cmd,
      19                 :            :                                struct logical_volume *lv)
      20                 :            : {
      21                 :            :         uint32_t lv_access;
      22                 :            :         struct lvinfo info;
      23                 :          0 :         int r = 0;
      24                 :            : 
      25                 :          0 :         lv_access = arg_uint_value(cmd, permission_ARG, 0);
      26                 :            : 
      27   [ #  #  #  # ]:          0 :         if ((lv_access & LVM_WRITE) && (lv->status & LVM_WRITE)) {
      28                 :          0 :                 log_error("Logical volume \"%s\" is already writable",
      29                 :            :                           lv->name);
      30                 :          0 :                 return 0;
      31                 :            :         }
      32                 :            : 
      33 [ #  # ][ #  # ]:          0 :         if (!(lv_access & LVM_WRITE) && !(lv->status & LVM_WRITE)) {
      34                 :          0 :                 log_error("Logical volume \"%s\" is already read only",
      35                 :            :                           lv->name);
      36                 :          0 :                 return 0;
      37                 :            :         }
      38                 :            : 
      39         [ #  # ]:          0 :         if ((lv->status & MIRRORED) && (vg_is_clustered(lv->vg)) &&
           [ #  #  #  # ]
                 [ #  # ]
      40                 :          0 :             lv_info(cmd, lv, &info, 0, 0) && info.exists) {
      41                 :          0 :                 log_error("Cannot change permissions of mirror \"%s\" "
      42                 :            :                           "while active.", lv->name);
      43                 :          0 :                 return 0;
      44                 :            :         }
      45                 :            : 
      46         [ #  # ]:          0 :         if (lv_access & LVM_WRITE) {
      47                 :          0 :                 lv->status |= LVM_WRITE;
      48                 :          0 :                 log_verbose("Setting logical volume \"%s\" read/write",
      49                 :            :                             lv->name);
      50                 :            :         } else {
      51                 :          0 :                 lv->status &= ~LVM_WRITE;
      52                 :          0 :                 log_verbose("Setting logical volume \"%s\" read-only",
      53                 :            :                             lv->name);
      54                 :            :         }
      55                 :            : 
      56                 :          0 :         log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
      57         [ #  # ]:          0 :         if (!vg_write(lv->vg))
      58                 :          0 :                 return_0;
      59                 :            : 
      60 [ #  # ][ #  # ]:          0 :         if (!suspend_lv(cmd, lv)) {
                 [ #  # ]
      61                 :          0 :                 log_error("Failed to lock %s", lv->name);
      62                 :          0 :                 vg_revert(lv->vg);
      63                 :          0 :                 goto out;
      64                 :            :         }
      65                 :            : 
      66         [ #  # ]:          0 :         if (!vg_commit(lv->vg)) {
      67 [ #  # ][ #  # ]:          0 :                 if (!resume_lv(cmd, lv))
                 [ #  # ]
      68                 :          0 :                         stack;
      69                 :          0 :                 goto_out;
      70                 :            :         }
      71                 :            : 
      72                 :          0 :         log_very_verbose("Updating permissions for \"%s\" in kernel", lv->name);
      73   [ #  #  #  # ]:          0 :         if (!resume_lv(cmd, lv)) {
                 [ #  # ]
      74                 :          0 :                 log_error("Problem reactivating %s", lv->name);
      75                 :          0 :                 goto out;
      76                 :            :         }
      77                 :            : 
      78                 :          0 :         r = 1;
      79                 :            : out:
      80                 :          0 :         backup(lv->vg);
      81                 :          0 :         return r;
      82                 :            : }
      83                 :            : 
      84                 :          0 : static int lvchange_monitoring(struct cmd_context *cmd,
      85                 :            :                                struct logical_volume *lv)
      86                 :            : {
      87                 :            :         struct lvinfo info;
      88                 :            : 
      89 [ #  # ][ #  # ]:          0 :         if (!lv_info(cmd, lv, &info, 0, 0) || !info.exists) {
      90                 :          0 :                 log_error("Logical volume, %s, is not active", lv->name);
      91                 :          0 :                 return 0;
      92                 :            :         }
      93                 :            : 
      94                 :            :         /* do not monitor pvmove lv's */
      95         [ #  # ]:          0 :         if (lv->status & PVMOVE)
      96                 :          0 :                 return 1;
      97                 :            : 
      98   [ #  #  #  # ]:          0 :         if ((dmeventd_monitor_mode() != DMEVENTD_MONITOR_IGNORE) &&
      99                 :          0 :             !monitor_dev_for_events(cmd, lv, dmeventd_monitor_mode()))
     100                 :          0 :                 stack;
     101                 :            : 
     102                 :          0 :         return 1;
     103                 :            : }
     104                 :            : 
     105                 :          0 : static int lvchange_background_polling(struct cmd_context *cmd,
     106                 :            :                                        struct logical_volume *lv)
     107                 :            : {
     108                 :            :         struct lvinfo info;
     109                 :            : 
     110 [ #  # ][ #  # ]:          0 :         if (!lv_info(cmd, lv, &info, 0, 0) || !info.exists) {
     111                 :          0 :                 log_error("Logical volume, %s, is not active", lv->name);
     112                 :          0 :                 return 0;
     113                 :            :         }
     114                 :            : 
     115         [ #  # ]:          0 :         if (background_polling())
     116                 :          0 :                 lv_spawn_background_polling(cmd, lv);
     117                 :            : 
     118                 :          0 :         return 1;
     119                 :            : }
     120                 :            : 
     121                 :          0 : static int lvchange_availability(struct cmd_context *cmd,
     122                 :            :                                  struct logical_volume *lv)
     123                 :            : {
     124                 :            :         int activate;
     125                 :            : 
     126                 :          0 :         activate = arg_uint_value(cmd, available_ARG, 0);
     127                 :            : 
     128         [ #  # ]:          0 :         if (activate == CHANGE_ALN) {
     129                 :          0 :                 log_verbose("Deactivating logical volume \"%s\" locally",
     130                 :            :                             lv->name);
     131   [ #  #  #  # ]:          0 :                 if (!deactivate_lv_local(cmd, lv))
                 [ #  # ]
     132                 :          0 :                         return_0;
     133         [ #  # ]:          0 :         } else if (activate == CHANGE_AN) {
     134                 :          0 :                 log_verbose("Deactivating logical volume \"%s\"", lv->name);
     135   [ #  #  #  # ]:          0 :                 if (!deactivate_lv(cmd, lv))
                 [ #  # ]
     136                 :          0 :                         return_0;
     137                 :            :         } else {
     138 [ #  # ][ #  # ]:          0 :                 if (lv_is_origin(lv) || (activate == CHANGE_AE)) {
     139                 :          0 :                         log_verbose("Activating logical volume \"%s\" "
     140                 :            :                                     "exclusively", lv->name);
     141   [ #  #  #  # ]:          0 :                         if (!activate_lv_excl(cmd, lv))
                 [ #  # ]
     142                 :          0 :                                 return_0;
     143         [ #  # ]:          0 :                 } else if (activate == CHANGE_ALY) {
     144                 :          0 :                         log_verbose("Activating logical volume \"%s\" locally",
     145                 :            :                                     lv->name);
     146   [ #  #  #  # ]:          0 :                         if (!activate_lv_local(cmd, lv))
                 [ #  # ]
     147                 :          0 :                                 return_0;
     148                 :            :                 } else {
     149                 :          0 :                         log_verbose("Activating logical volume \"%s\"",
     150                 :            :                                     lv->name);
     151   [ #  #  #  # ]:          0 :                         if (!activate_lv(cmd, lv))
                 [ #  # ]
     152                 :          0 :                                 return_0;
     153                 :            :                 }
     154                 :            : 
     155         [ #  # ]:          0 :                 if (background_polling())
     156                 :          0 :                         lv_spawn_background_polling(cmd, lv);
     157                 :            :         }
     158                 :            : 
     159                 :          0 :         return 1;
     160                 :            : }
     161                 :            : 
     162                 :          0 : static int lvchange_refresh(struct cmd_context *cmd, struct logical_volume *lv)
     163                 :            : {
     164                 :          0 :         log_verbose("Refreshing logical volume \"%s\" (if active)", lv->name);
     165                 :          0 :         return lv_refresh(cmd, lv);
     166                 :            : }
     167                 :            : 
     168                 :          0 : static int lvchange_resync(struct cmd_context *cmd,
     169                 :            :                               struct logical_volume *lv)
     170                 :            : {
     171                 :          0 :         int active = 0;
     172                 :            :         int monitored;
     173                 :            :         struct lvinfo info;
     174                 :            :         struct logical_volume *log_lv;
     175                 :            : 
     176         [ #  # ]:          0 :         if (!(lv->status & MIRRORED)) {
     177                 :          0 :                 log_error("Unable to resync %s because it is not mirrored.",
     178                 :            :                           lv->name);
     179                 :          0 :                 return 1;
     180                 :            :         }
     181                 :            : 
     182         [ #  # ]:          0 :         if (lv->status & PVMOVE) {
     183                 :          0 :                 log_error("Unable to resync pvmove volume %s", lv->name);
     184                 :          0 :                 return 0;
     185                 :            :         }
     186                 :            : 
     187         [ #  # ]:          0 :         if (lv->status & LOCKED) {
     188                 :          0 :                 log_error("Unable to resync locked volume %s", lv->name);
     189                 :          0 :                 return 0;
     190                 :            :         }
     191                 :            : 
     192         [ #  # ]:          0 :         if (lv_info(cmd, lv, &info, 1, 0)) {
     193         [ #  # ]:          0 :                 if (info.open_count) {
     194                 :          0 :                         log_error("Can't resync open logical volume \"%s\"",
     195                 :            :                                   lv->name);
     196                 :          0 :                         return 0;
     197                 :            :                 }
     198                 :            : 
     199         [ #  # ]:          0 :                 if (info.exists) {
     200   [ #  #  #  # ]:          0 :                         if (!arg_count(cmd, yes_ARG) &&
     201                 :            :                             yes_no_prompt("Do you really want to deactivate "
     202                 :            :                                           "logical volume %s to resync it? [y/n]: ",
     203                 :          0 :                                           lv->name) == 'n') {
     204                 :          0 :                                 log_error("Logical volume \"%s\" not resynced",
     205                 :            :                                           lv->name);
     206                 :          0 :                                 return 0;
     207                 :            :                         }
     208                 :            : 
     209         [ #  # ]:          0 :                         if (sigint_caught())
     210                 :          0 :                                 return 0;
     211                 :            : 
     212                 :          0 :                         active = 1;
     213                 :            :                 }
     214                 :            :         }
     215                 :            : 
     216                 :            :         /* Activate exclusively to ensure no nodes still have LV active */
     217                 :          0 :         monitored = dmeventd_monitor_mode();
     218                 :          0 :         init_dmeventd_monitor(0);
     219                 :            : 
     220   [ #  #  #  # ]:          0 :         if (!deactivate_lv(cmd, lv)) {
                 [ #  # ]
     221                 :          0 :                 log_error("Unable to deactivate %s for resync", lv->name);
     222                 :          0 :                 return 0;
     223                 :            :         }
     224                 :            : 
     225 [ #  # ][ #  # ]:          0 :         if (vg_is_clustered(lv->vg) && lv_is_active(lv)) {
     226                 :          0 :                 log_error("Can't get exclusive access to clustered volume %s",
     227                 :            :                           lv->name);
     228                 :          0 :                 return 0;
     229                 :            :         }
     230                 :            : 
     231                 :          0 :         init_dmeventd_monitor(monitored);
     232                 :            : 
     233                 :          0 :         log_lv = first_seg(lv)->log_lv;
     234                 :            : 
     235 [ #  # ][ #  # ]:          0 :         log_very_verbose("Starting resync of %s%s%s mirror \"%s\"",
                 [ #  # ]
     236                 :            :                          (active) ? "active " : "",
     237                 :            :                          vg_is_clustered(lv->vg) ? "clustered " : "",
     238                 :            :                          (log_lv) ? "disk-logged" : "core-logged",
     239                 :            :                          lv->name);
     240                 :            : 
     241                 :            :         /*
     242                 :            :          * If this mirror has a core log (i.e. !log_lv),
     243                 :            :          * then simply deactivating/activating will cause
     244                 :            :          * it to reset the sync status.  We only need to
     245                 :            :          * worry about persistent logs.
     246                 :            :          */
     247   [ #  #  #  # ]:          0 :         if (!log_lv && !(lv->status & MIRROR_NOTSYNCED)) {
     248 [ #  # ][ #  # ]:          0 :                 if (active && !activate_lv(cmd, lv)) {
         [ #  # ][ #  # ]
     249                 :          0 :                         log_error("Failed to reactivate %s to resynchronize "
     250                 :            :                                   "mirror", lv->name);
     251                 :          0 :                         return 0;
     252                 :            :                 }
     253                 :          0 :                 return 1;
     254                 :            :         }
     255                 :            : 
     256                 :          0 :         lv->status &= ~MIRROR_NOTSYNCED;
     257                 :            : 
     258         [ #  # ]:          0 :         if (log_lv) {
     259                 :            :                 /* Separate mirror log so we can clear it */
     260                 :          0 :                 detach_mirror_log(first_seg(lv));
     261                 :            : 
     262         [ #  # ]:          0 :                 if (!vg_write(lv->vg)) {
     263                 :          0 :                         log_error("Failed to write intermediate VG metadata.");
     264         [ #  # ]:          0 :                         if (!attach_mirror_log(first_seg(lv), log_lv))
     265                 :          0 :                                 stack;
     266 [ #  # ][ #  # ]:          0 :                         if (active && !activate_lv(cmd, lv))
         [ #  # ][ #  # ]
     267                 :          0 :                                 stack;
     268                 :          0 :                         return 0;
     269                 :            :                 }
     270                 :            : 
     271         [ #  # ]:          0 :                 if (!vg_commit(lv->vg)) {
     272                 :          0 :                         log_error("Failed to commit intermediate VG metadata.");
     273         [ #  # ]:          0 :                         if (!attach_mirror_log(first_seg(lv), log_lv))
     274                 :          0 :                                 stack;
     275 [ #  # ][ #  # ]:          0 :                         if (active && !activate_lv(cmd, lv))
         [ #  # ][ #  # ]
     276                 :          0 :                                 stack;
     277                 :          0 :                         return 0;
     278                 :            :                 }
     279                 :            : 
     280                 :          0 :                 backup(lv->vg);
     281                 :            : 
     282   [ #  #  #  # ]:          0 :                 if (!activate_lv(cmd, log_lv)) {
                 [ #  # ]
     283                 :          0 :                         log_error("Unable to activate %s for mirror log resync",
     284                 :            :                                   log_lv->name);
     285                 :          0 :                         return 0;
     286                 :            :                 }
     287                 :            : 
     288                 :          0 :                 log_very_verbose("Clearing log device %s", log_lv->name);
     289         [ #  # ]:          0 :                 if (!set_lv(cmd, log_lv, log_lv->size, 0)) {
     290                 :          0 :                         log_error("Unable to reset sync status for %s", lv->name);
     291   [ #  #  #  # ]:          0 :                         if (!deactivate_lv(cmd, log_lv))
                 [ #  # ]
     292                 :          0 :                                 log_error("Failed to deactivate log LV after "
     293                 :            :                                           "wiping failed");
     294                 :          0 :                         return 0;
     295                 :            :                 }
     296                 :            : 
     297 [ #  # ][ #  # ]:          0 :                 if (!deactivate_lv(cmd, log_lv)) {
                 [ #  # ]
     298                 :          0 :                         log_error("Unable to deactivate log LV %s after wiping "
     299                 :            :                                   "for resync", log_lv->name);
     300                 :          0 :                         return 0;
     301                 :            :                 }
     302                 :            : 
     303                 :            :                 /* Put mirror log back in place */
     304         [ #  # ]:          0 :                 if (!attach_mirror_log(first_seg(lv), log_lv))
     305                 :          0 :                         stack;
     306                 :            :         }
     307                 :            : 
     308                 :          0 :         log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
     309   [ #  #  #  # ]:          0 :         if (!vg_write(lv->vg) || !vg_commit(lv->vg)) {
     310                 :          0 :                 log_error("Failed to update metadata on disk.");
     311                 :          0 :                 return 0;
     312                 :            :         }
     313                 :            : 
     314 [ #  # ][ #  # ]:          0 :         if (active && !activate_lv(cmd, lv)) {
         [ #  # ][ #  # ]
     315                 :          0 :                 log_error("Failed to reactivate %s after resync", lv->name);
     316                 :          0 :                 return 0;
     317                 :            :         }
     318                 :            : 
     319                 :          0 :         return 1;
     320                 :            : }
     321                 :            : 
     322                 :          0 : static int lvchange_alloc(struct cmd_context *cmd, struct logical_volume *lv)
     323                 :            : {
     324                 :          0 :         int want_contiguous = 0;
     325                 :            :         alloc_policy_t alloc;
     326                 :            : 
     327                 :          0 :         want_contiguous = strcmp(arg_str_value(cmd, contiguous_ARG, "n"), "n");
     328         [ #  # ]:          0 :         alloc = want_contiguous ? ALLOC_CONTIGUOUS : ALLOC_INHERIT;
     329                 :          0 :         alloc = arg_uint_value(cmd, alloc_ARG, alloc);
     330                 :            : 
     331         [ #  # ]:          0 :         if (alloc == lv->alloc) {
     332                 :          0 :                 log_error("Allocation policy of logical volume \"%s\" is "
     333                 :            :                           "already %s", lv->name, get_alloc_string(alloc));
     334                 :          0 :                 return 0;
     335                 :            :         }
     336                 :            : 
     337                 :          0 :         lv->alloc = alloc;
     338                 :            : 
     339                 :            :         /* FIXME If contiguous, check existing extents already are */
     340                 :            : 
     341                 :          0 :         log_verbose("Setting contiguous allocation policy for \"%s\" to %s",
     342                 :            :                     lv->name, get_alloc_string(alloc));
     343                 :            : 
     344                 :          0 :         log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
     345                 :            : 
     346                 :            :         /* No need to suspend LV for this change */
     347   [ #  #  #  # ]:          0 :         if (!vg_write(lv->vg) || !vg_commit(lv->vg))
     348                 :          0 :                 return_0;
     349                 :            : 
     350                 :          0 :         backup(lv->vg);
     351                 :            : 
     352                 :          0 :         return 1;
     353                 :            : }
     354                 :            : 
     355                 :          0 : static int lvchange_readahead(struct cmd_context *cmd,
     356                 :            :                               struct logical_volume *lv)
     357                 :            : {
     358                 :          0 :         unsigned read_ahead = 0;
     359                 :          0 :         unsigned pagesize = (unsigned) lvm_getpagesize() >> SECTOR_SHIFT;
     360                 :          0 :         int r = 0;
     361                 :            : 
     362                 :          0 :         read_ahead = arg_uint_value(cmd, readahead_ARG, 0);
     363                 :            : 
     364   [ #  #  #  # ]:          0 :         if (read_ahead != DM_READ_AHEAD_AUTO &&
         [ #  # ][ #  # ]
     365                 :          0 :             (lv->vg->fid->fmt->features & FMT_RESTRICTED_READAHEAD) &&
     366                 :            :             (read_ahead < 2 || read_ahead > 120)) {
     367                 :          0 :                 log_error("Metadata only supports readahead values between 2 and 120.");
     368                 :          0 :                 return 0;
     369                 :            :         }
     370                 :            : 
     371 [ #  # ][ #  # ]:          0 :         if (read_ahead != DM_READ_AHEAD_AUTO &&
                 [ #  # ]
     372                 :          0 :             read_ahead != DM_READ_AHEAD_NONE && read_ahead % pagesize) {
     373         [ #  # ]:          0 :                 if (read_ahead < pagesize)
     374                 :          0 :                         read_ahead = pagesize;
     375                 :            :                 else
     376                 :          0 :                         read_ahead = (read_ahead / pagesize) * pagesize;
     377                 :          0 :                 log_warn("WARNING: Overriding readahead to %u sectors, a multiple "
     378                 :            :                             "of %uK page size.", read_ahead, pagesize >> 1);
     379                 :            :         }
     380                 :            : 
     381         [ #  # ]:          0 :         if (lv->read_ahead == read_ahead) {
     382         [ #  # ]:          0 :                 if (read_ahead == DM_READ_AHEAD_AUTO)
     383                 :          0 :                         log_error("Read ahead is already auto for \"%s\"", lv->name);
     384                 :            :                 else
     385                 :          0 :                         log_error("Read ahead is already %u for \"%s\"",
     386                 :            :                                   read_ahead, lv->name);
     387                 :          0 :                 return 0;
     388                 :            :         }
     389                 :            : 
     390                 :          0 :         lv->read_ahead = read_ahead;
     391                 :            : 
     392                 :          0 :         log_verbose("Setting read ahead to %u for \"%s\"", read_ahead,
     393                 :            :                     lv->name);
     394                 :            : 
     395                 :          0 :         log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
     396         [ #  # ]:          0 :         if (!vg_write(lv->vg))
     397                 :          0 :                 return_0;
     398                 :            : 
     399 [ #  # ][ #  # ]:          0 :         if (!suspend_lv(cmd, lv)) {
                 [ #  # ]
     400                 :          0 :                 log_error("Failed to lock %s", lv->name);
     401                 :          0 :                 vg_revert(lv->vg);
     402                 :          0 :                 goto out;
     403                 :            :         }
     404                 :            : 
     405         [ #  # ]:          0 :         if (!vg_commit(lv->vg)) {
     406 [ #  # ][ #  # ]:          0 :                 if (!resume_lv(cmd, lv))
                 [ #  # ]
     407                 :          0 :                         stack;
     408                 :          0 :                 goto_out;
     409                 :            :         }
     410                 :            : 
     411                 :          0 :         log_very_verbose("Updating permissions for \"%s\" in kernel", lv->name);
     412   [ #  #  #  # ]:          0 :         if (!resume_lv(cmd, lv)) {
                 [ #  # ]
     413                 :          0 :                 log_error("Problem reactivating %s", lv->name);
     414                 :          0 :                 goto out;
     415                 :            :         }
     416                 :            : 
     417                 :          0 :         r = 1;
     418                 :            : out:
     419                 :          0 :         backup(lv->vg);
     420                 :          0 :         return r;
     421                 :            : }
     422                 :            : 
     423                 :          0 : static int lvchange_persistent(struct cmd_context *cmd,
     424                 :            :                                struct logical_volume *lv)
     425                 :            : {
     426                 :            :         struct lvinfo info;
     427                 :          0 :         int active = 0;
     428                 :            : 
     429         [ #  # ]:          0 :         if (!strcmp(arg_str_value(cmd, persistent_ARG, "n"), "n")) {
     430         [ #  # ]:          0 :                 if (!(lv->status & FIXED_MINOR)) {
     431                 :          0 :                         log_error("Minor number is already not persistent "
     432                 :            :                                   "for \"%s\"", lv->name);
     433                 :          0 :                         return 0;
     434                 :            :                 }
     435                 :          0 :                 lv->status &= ~FIXED_MINOR;
     436                 :          0 :                 lv->minor = -1;
     437                 :          0 :                 lv->major = -1;
     438                 :          0 :                 log_verbose("Disabling persistent device number for \"%s\"",
     439                 :            :                             lv->name);
     440                 :            :         } else {
     441 [ #  # ][ #  # ]:          0 :                 if (!arg_count(cmd, minor_ARG) && lv->minor < 0) {
     442                 :          0 :                         log_error("Minor number must be specified with -My");
     443                 :          0 :                         return 0;
     444                 :            :                 }
     445 [ #  # ][ #  # ]:          0 :                 if (!arg_count(cmd, major_ARG) && lv->major < 0) {
     446                 :          0 :                         log_error("Major number must be specified with -My");
     447                 :          0 :                         return 0;
     448                 :            :                 }
     449 [ #  # ][ #  # ]:          0 :                 if (lv_info(cmd, lv, &info, 0, 0) && info.exists)
     450                 :          0 :                         active = 1;
     451         [ #  # ]:          0 :                 if (active && !arg_count(cmd, force_ARG) &&
           [ #  #  #  # ]
     452                 :            :                     yes_no_prompt("Logical volume %s will be "
     453                 :            :                                   "deactivated temporarily. "
     454                 :          0 :                                   "Continue? [y/n]: ", lv->name) == 'n') {
     455                 :          0 :                         log_error("%s device number not changed.",
     456                 :            :                                   lv->name);
     457                 :          0 :                         return 0;
     458                 :            :                 }
     459                 :            : 
     460         [ #  # ]:          0 :                 if (sigint_caught())
     461                 :          0 :                         return 0;
     462                 :            : 
     463                 :          0 :                 log_verbose("Ensuring %s is inactive.", lv->name);
     464   [ #  #  #  # ]:          0 :                 if (!deactivate_lv(cmd, lv)) {
                 [ #  # ]
     465                 :          0 :                         log_error("%s: deactivation failed", lv->name);
     466                 :          0 :                         return 0;
     467                 :            :                 }
     468                 :          0 :                 lv->status |= FIXED_MINOR;
     469                 :          0 :                 lv->minor = arg_int_value(cmd, minor_ARG, lv->minor);
     470                 :          0 :                 lv->major = arg_int_value(cmd, major_ARG, lv->major);
     471                 :          0 :                 log_verbose("Setting persistent device number to (%d, %d) "
     472                 :            :                             "for \"%s\"", lv->major, lv->minor, lv->name);
     473                 :            : 
     474                 :            :         }
     475                 :            : 
     476                 :          0 :         log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
     477   [ #  #  #  # ]:          0 :         if (!vg_write(lv->vg) || !vg_commit(lv->vg))
     478                 :          0 :                 return_0;
     479                 :            : 
     480                 :          0 :         backup(lv->vg);
     481                 :            : 
     482         [ #  # ]:          0 :         if (active) {
     483                 :          0 :                 log_verbose("Re-activating logical volume \"%s\"", lv->name);
     484   [ #  #  #  # ]:          0 :                 if (!activate_lv(cmd, lv)) {
                 [ #  # ]
     485                 :          0 :                         log_error("%s: reactivation failed", lv->name);
     486                 :          0 :                         return 0;
     487                 :            :                 }
     488                 :            :         }
     489                 :            : 
     490                 :          0 :         return 1;
     491                 :            : }
     492                 :            : 
     493                 :          0 : static int lvchange_tag(struct cmd_context *cmd, struct logical_volume *lv,
     494                 :            :                         int arg)
     495                 :            : {
     496                 :            :         const char *tag;
     497                 :            : 
     498         [ #  # ]:          0 :         if (!(tag = arg_str_value(cmd, arg, NULL))) {
     499                 :          0 :                 log_error("Failed to get tag");
     500                 :          0 :                 return 0;
     501                 :            :         }
     502                 :            : 
     503         [ #  # ]:          0 :         if (!lv_change_tag(lv, tag, arg == addtag_ARG))
     504                 :          0 :                 return_0;
     505                 :            : 
     506                 :          0 :         log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
     507                 :            : 
     508                 :            :         /* No need to suspend LV for this change */
     509   [ #  #  #  # ]:          0 :         if (!vg_write(lv->vg) || !vg_commit(lv->vg))
     510                 :          0 :                 return_0;
     511                 :            : 
     512                 :          0 :         backup(lv->vg);
     513                 :            : 
     514                 :          0 :         return 1;
     515                 :            : }
     516                 :            : 
     517                 :          0 : static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
     518                 :            :                            void *handle __attribute((unused)))
     519                 :            : {
     520                 :          0 :         int doit = 0, docmds = 0;
     521                 :          0 :         int dmeventd_mode, archived = 0;
     522                 :            :         struct logical_volume *origin;
     523                 :            : 
     524 [ #  #  #  #  # :          0 :         if (!(lv->vg->status & LVM_WRITE) &&
          #  #  #  #  #  
                   #  # ]
     525                 :          0 :             (arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) ||
     526                 :          0 :              arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) ||
     527                 :          0 :              arg_count(cmd, alloc_ARG))) {
     528                 :          0 :                 log_error("Only -a permitted with read-only volume "
     529                 :            :                           "group \"%s\"", lv->vg->name);
     530                 :          0 :                 return EINVALID_CMD_LINE;
     531                 :            :         }
     532                 :            : 
     533 [ #  #  #  #  # :          0 :         if (lv_is_origin(lv) &&
          #  #  #  #  #  
                   #  # ]
     534                 :          0 :             (arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) ||
     535                 :          0 :              arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) ||
     536                 :          0 :              arg_count(cmd, alloc_ARG))) {
     537                 :          0 :                 log_error("Can't change logical volume \"%s\" under snapshot",
     538                 :            :                           lv->name);
     539                 :          0 :                 return ECMD_FAILED;
     540                 :            :         }
     541                 :            : 
     542         [ #  # ]:          0 :         if (lv_is_cow(lv) && !lv_is_virtual_origin(origin_from_cow(lv)) &&
           [ #  #  #  # ]
     543                 :          0 :             arg_count(cmd, available_ARG)) {
     544                 :          0 :                 log_error("Can't change snapshot logical volume \"%s\"",
     545                 :            :                           lv->name);
     546                 :          0 :                 return ECMD_FAILED;
     547                 :            :         }
     548                 :            : 
     549         [ #  # ]:          0 :         if (lv->status & PVMOVE) {
     550                 :          0 :                 log_error("Unable to change pvmove LV %s", lv->name);
     551         [ #  # ]:          0 :                 if (arg_count(cmd, available_ARG))
     552                 :          0 :                         log_error("Use 'pvmove --abort' to abandon a pvmove");
     553                 :          0 :                 return ECMD_FAILED;
     554                 :            :         }
     555                 :            : 
     556         [ #  # ]:          0 :         if (lv->status & MIRROR_LOG) {
     557                 :          0 :                 log_error("Unable to change mirror log LV %s directly", lv->name);
     558                 :          0 :                 return ECMD_FAILED;
     559                 :            :         }
     560                 :            : 
     561         [ #  # ]:          0 :         if (lv->status & MIRROR_IMAGE) {
     562                 :          0 :                 log_error("Unable to change mirror image LV %s directly",
     563                 :            :                           lv->name);
     564                 :          0 :                 return ECMD_FAILED;
     565                 :            :         }
     566                 :            : 
     567                 :            :         /* If LV is sparse, activate origin instead */
     568         [ #  # ]:          0 :         if (arg_count(cmd, available_ARG) && lv_is_cow(lv) &&
           [ #  #  #  # ]
     569                 :          0 :             lv_is_virtual_origin(origin = origin_from_cow(lv)))
     570                 :          0 :                 lv = origin;
     571                 :            : 
     572 [ #  # ][ #  # ]:          0 :         if (!(lv_is_visible(lv)) && !lv_is_virtual_origin(lv)) {
     573                 :          0 :                 log_error("Unable to change internal LV %s directly",
     574                 :            :                           lv->name);
     575                 :          0 :                 return ECMD_FAILED;
     576                 :            :         }
     577                 :            : 
     578         [ #  # ]:          0 :         if (!get_activation_monitoring_mode(cmd, lv->vg, &dmeventd_mode))
     579                 :          0 :                 return ECMD_FAILED;
     580                 :            : 
     581                 :          0 :         init_dmeventd_monitor(dmeventd_mode);
     582                 :            : 
     583                 :            :         /*
     584                 :            :          * FIXME: DEFAULT_BACKGROUND_POLLING should be "unspecified".
     585                 :            :          * If --poll is explicitly provided use it; otherwise polling
     586                 :            :          * should only be started if the LV is not already active. So:
     587                 :            :          * 1) change the activation code to say if the LV was actually activated
     588                 :            :          * 2) make polling of an LV tightly coupled with LV activation
     589                 :            :          */
     590                 :          0 :         init_background_polling(arg_int_value(cmd, poll_ARG,
     591                 :            :                                               DEFAULT_BACKGROUND_POLLING));
     592                 :            : 
     593                 :            :         /* access permission change */
     594         [ #  # ]:          0 :         if (arg_count(cmd, permission_ARG)) {
     595         [ #  # ]:          0 :                 if (!archive(lv->vg)) {
     596                 :          0 :                         stack;
     597                 :          0 :                         return ECMD_FAILED;
     598                 :            :                 }
     599                 :          0 :                 archived = 1;
     600                 :          0 :                 doit += lvchange_permission(cmd, lv);
     601                 :          0 :                 docmds++;
     602                 :            :         }
     603                 :            : 
     604                 :            :         /* allocation policy change */
     605 [ #  # ][ #  # ]:          0 :         if (arg_count(cmd, contiguous_ARG) || arg_count(cmd, alloc_ARG)) {
     606 [ #  # ][ #  # ]:          0 :                 if (!archived && !archive(lv->vg)) {
     607                 :          0 :                         stack;
     608                 :          0 :                         return ECMD_FAILED;
     609                 :            :                 }
     610                 :          0 :                 archived = 1;
     611                 :          0 :                 doit += lvchange_alloc(cmd, lv);
     612                 :          0 :                 docmds++;
     613                 :            :         }
     614                 :            : 
     615                 :            :         /* read ahead sector change */
     616         [ #  # ]:          0 :         if (arg_count(cmd, readahead_ARG)) {
     617 [ #  # ][ #  # ]:          0 :                 if (!archived && !archive(lv->vg)) {
     618                 :          0 :                         stack;
     619                 :          0 :                         return ECMD_FAILED;
     620                 :            :                 }
     621                 :          0 :                 archived = 1;
     622                 :          0 :                 doit += lvchange_readahead(cmd, lv);
     623                 :          0 :                 docmds++;
     624                 :            :         }
     625                 :            : 
     626                 :            :         /* persistent device number change */
     627         [ #  # ]:          0 :         if (arg_count(cmd, persistent_ARG)) {
     628 [ #  # ][ #  # ]:          0 :                 if (!archived && !archive(lv->vg)) {
     629                 :          0 :                         stack;
     630                 :          0 :                         return ECMD_FAILED;
     631                 :            :                 }
     632                 :          0 :                 archived = 1;
     633                 :          0 :                 doit += lvchange_persistent(cmd, lv);
     634                 :          0 :                 docmds++;
     635         [ #  # ]:          0 :                 if (sigint_caught()) {
     636                 :          0 :                         stack;
     637                 :          0 :                         return ECMD_FAILED;
     638                 :            :                 }
     639                 :            :         }
     640                 :            : 
     641                 :            :         /* add tag */
     642         [ #  # ]:          0 :         if (arg_count(cmd, addtag_ARG)) {
     643 [ #  # ][ #  # ]:          0 :                 if (!archived && !archive(lv->vg)) {
     644                 :          0 :                         stack;
     645                 :          0 :                         return ECMD_FAILED;
     646                 :            :                 }
     647                 :          0 :                 archived = 1;
     648                 :          0 :                 doit += lvchange_tag(cmd, lv, addtag_ARG);
     649                 :          0 :                 docmds++;
     650                 :            :         }
     651                 :            : 
     652                 :            :         /* del tag */
     653         [ #  # ]:          0 :         if (arg_count(cmd, deltag_ARG)) {
     654 [ #  # ][ #  # ]:          0 :                 if (!archived && !archive(lv->vg)) {
     655                 :          0 :                         stack;
     656                 :          0 :                         return ECMD_FAILED;
     657                 :            :                 }
     658                 :          0 :                 archived = 1;
     659                 :          0 :                 doit += lvchange_tag(cmd, lv, deltag_ARG);
     660                 :          0 :                 docmds++;
     661                 :            :         }
     662                 :            : 
     663         [ #  # ]:          0 :         if (doit)
     664                 :          0 :                 log_print("Logical volume \"%s\" changed", lv->name);
     665                 :            : 
     666         [ #  # ]:          0 :         if (arg_count(cmd, resync_ARG))
     667         [ #  # ]:          0 :                 if (!lvchange_resync(cmd, lv)) {
     668                 :          0 :                         stack;
     669                 :          0 :                         return ECMD_FAILED;
     670                 :            :                 }
     671                 :            : 
     672                 :            :         /* availability change */
     673         [ #  # ]:          0 :         if (arg_count(cmd, available_ARG)) {
     674         [ #  # ]:          0 :                 if (!lvchange_availability(cmd, lv)) {
     675                 :          0 :                         stack;
     676                 :          0 :                         return ECMD_FAILED;
     677                 :            :                 }
     678                 :            :         }
     679                 :            : 
     680         [ #  # ]:          0 :         if (arg_count(cmd, refresh_ARG))
     681         [ #  # ]:          0 :                 if (!lvchange_refresh(cmd, lv)) {
     682                 :          0 :                         stack;
     683                 :          0 :                         return ECMD_FAILED;
     684                 :            :                 }
     685                 :            : 
     686 [ #  #  #  #  # :          0 :         if (!arg_count(cmd, available_ARG) &&
                      # ]
     687                 :          0 :             !arg_count(cmd, refresh_ARG) &&
     688                 :          0 :             arg_count(cmd, monitor_ARG)) {
     689         [ #  # ]:          0 :                 if (!lvchange_monitoring(cmd, lv)) {
     690                 :          0 :                         stack;
     691                 :          0 :                         return ECMD_FAILED;
     692                 :            :                 }
     693                 :            :         }
     694                 :            : 
     695 [ #  #  #  #  # :          0 :         if (!arg_count(cmd, available_ARG) &&
                      # ]
     696                 :          0 :             !arg_count(cmd, refresh_ARG) &&
     697                 :          0 :             arg_count(cmd, poll_ARG)) {
     698         [ #  # ]:          0 :                 if (!lvchange_background_polling(cmd, lv)) {
     699                 :          0 :                         stack;
     700                 :          0 :                         return ECMD_FAILED;
     701                 :            :                 }
     702                 :            :         }
     703                 :            : 
     704         [ #  # ]:          0 :         if (doit != docmds) {
     705                 :          0 :                 stack;
     706                 :          0 :                 return ECMD_FAILED;
     707                 :            :         }
     708                 :            : 
     709                 :          0 :         return ECMD_PROCESSED;
     710                 :            : }
     711                 :            : 
     712                 :          0 : int lvchange(struct cmd_context *cmd, int argc, char **argv)
     713                 :            : {
     714 [ #  # ][ #  #  :          0 :         if (!arg_count(cmd, available_ARG) && !arg_count(cmd, contiguous_ARG)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     715                 :          0 :             && !arg_count(cmd, permission_ARG) && !arg_count(cmd, readahead_ARG)
     716                 :          0 :             && !arg_count(cmd, minor_ARG) && !arg_count(cmd, major_ARG)
     717                 :          0 :             && !arg_count(cmd, persistent_ARG) && !arg_count(cmd, addtag_ARG)
     718                 :          0 :             && !arg_count(cmd, deltag_ARG) && !arg_count(cmd, refresh_ARG)
     719                 :          0 :             && !arg_count(cmd, alloc_ARG) && !arg_count(cmd, monitor_ARG)
     720                 :          0 :             && !arg_count(cmd, poll_ARG) && !arg_count(cmd, resync_ARG)) {
     721                 :          0 :                 log_error("Need 1 or more of -a, -C, -j, -m, -M, -p, -r, "
     722                 :            :                           "--resync, --refresh, --alloc, --addtag, --deltag, "
     723                 :            :                           "--monitor or --poll");
     724                 :          0 :                 return EINVALID_CMD_LINE;
     725                 :            :         }
     726                 :            : 
     727                 :            :         int avail_only = /* i.e. only one of -a or --refresh is given */
     728 [ #  # ][ #  # ]:          0 :             !(arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     729                 :            :              arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) ||
     730                 :            :              arg_count(cmd, addtag_ARG) || arg_count(cmd, deltag_ARG) ||
     731                 :          0 :              arg_count(cmd, resync_ARG) || arg_count(cmd, alloc_ARG));
     732                 :            : 
     733 [ #  # ][ #  # ]:          0 :         if (arg_count(cmd, ignorelockingfailure_ARG) && !avail_only) {
     734                 :          0 :                 log_error("Only -a permitted with --ignorelockingfailure");
     735                 :          0 :                 return EINVALID_CMD_LINE;
     736                 :            :         }
     737                 :            : 
     738         [ #  # ]:          0 :         if (avail_only)
     739                 :          0 :                 cmd->handles_missing_pvs = 1;
     740                 :            : 
     741         [ #  # ]:          0 :         if (!argc) {
     742                 :          0 :                 log_error("Please give logical volume path(s)");
     743                 :          0 :                 return EINVALID_CMD_LINE;
     744                 :            :         }
     745                 :            : 
     746         [ #  # ]:          0 :         if ((arg_count(cmd, minor_ARG) || arg_count(cmd, major_ARG)) &&
           [ #  #  #  # ]
     747                 :          0 :             !arg_count(cmd, persistent_ARG)) {
     748                 :          0 :                 log_error("--major and --minor require -My");
     749                 :          0 :                 return EINVALID_CMD_LINE;
     750                 :            :         }
     751                 :            : 
     752 [ #  # ][ #  # ]:          0 :         if (arg_count(cmd, minor_ARG) && argc != 1) {
     753                 :          0 :                 log_error("Only give one logical volume when specifying minor");
     754                 :          0 :                 return EINVALID_CMD_LINE;
     755                 :            :         }
     756                 :            : 
     757 [ #  # ][ #  # ]:          0 :         if (arg_count(cmd, contiguous_ARG) && arg_count(cmd, alloc_ARG)) {
     758                 :          0 :                 log_error("Only one of --alloc and --contiguous permitted");
     759                 :          0 :                 return EINVALID_CMD_LINE;
     760                 :            :         }
     761                 :            : 
     762         [ #  # ]:          0 :         return process_each_lv(cmd, argc, argv,
     763                 :            :                                avail_only ? 0 : READ_FOR_UPDATE, NULL,
     764                 :            :                                &lvchange_single);
     765                 :            : }

Generated by: LCOV version 1.8