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

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
       3                 :            :  *
       4                 :            :  * This file is part of LVM2.
       5                 :            :  *
       6                 :            :  * This copyrighted material is made available to anyone wishing to use,
       7                 :            :  * modify, copy, or redistribute it subject to the terms and conditions
       8                 :            :  * of the GNU Lesser General Public License v.2.1.
       9                 :            :  *
      10                 :            :  * You should have received a copy of the GNU Lesser General Public License
      11                 :            :  * along with this program; if not, write to the Free Software Foundation,
      12                 :            :  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      13                 :            :  */
      14                 :            : 
      15                 :            : #include "tools.h"
      16                 :            : #include "polldaemon.h"
      17                 :            : #include "lv_alloc.h"
      18                 :            : 
      19                 :            : struct lvconvert_params {
      20                 :            :         int snapshot;
      21                 :            :         int merge;
      22                 :            :         int zero;
      23                 :            : 
      24                 :            :         const char *origin;
      25                 :            :         const char *lv_name;
      26                 :            :         const char *lv_split_name;
      27                 :            :         const char *lv_name_full;
      28                 :            :         const char *vg_name;
      29                 :            :         int wait_completion;
      30                 :            :         int need_polling;
      31                 :            : 
      32                 :            :         uint32_t chunk_size;
      33                 :            :         uint32_t region_size;
      34                 :            : 
      35                 :            :         uint32_t mirrors;
      36                 :            :         sign_t mirrors_sign;
      37                 :            :         uint32_t keep_mimages;
      38                 :            :         uint32_t stripes;
      39                 :            :         uint32_t stripe_size;
      40                 :            : 
      41                 :            :         struct segment_type *segtype;
      42                 :            : 
      43                 :            :         alloc_policy_t alloc;
      44                 :            : 
      45                 :            :         int pv_count;
      46                 :            :         char **pvs;
      47                 :            :         struct dm_list *pvh;
      48                 :            :         struct dm_list *failed_pvs;
      49                 :            : 
      50                 :            :         struct logical_volume *lv_to_poll;
      51                 :            : };
      52                 :            : 
      53                 :          0 : static int _lvconvert_name_params(struct lvconvert_params *lp,
      54                 :            :                                   struct cmd_context *cmd,
      55                 :            :                                   int *pargc, char ***pargv)
      56                 :            : {
      57                 :            :         char *ptr;
      58                 :          0 :         const char *vg_name = NULL;
      59                 :            : 
      60         [ #  # ]:          0 :         if (lp->merge)
      61                 :          0 :                 return 1;
      62                 :            : 
      63         [ #  # ]:          0 :         if (lp->snapshot) {
      64         [ #  # ]:          0 :                 if (!*pargc) {
      65                 :          0 :                         log_error("Please specify a logical volume to act as "
      66                 :            :                                   "the snapshot origin.");
      67                 :          0 :                         return 0;
      68                 :            :                 }
      69                 :            : 
      70                 :          0 :                 lp->origin = *pargv[0];
      71                 :          0 :                 (*pargv)++, (*pargc)--;
      72         [ #  # ]:          0 :                 if (!(lp->vg_name = extract_vgname(cmd, lp->origin))) {
      73                 :          0 :                         log_error("The origin name should include the "
      74                 :            :                                   "volume group.");
      75                 :          0 :                         return 0;
      76                 :            :                 }
      77                 :            : 
      78                 :            :                 /* Strip the volume group from the origin */
      79         [ #  # ]:          0 :                 if ((ptr = strrchr(lp->origin, (int) '/')))
      80                 :          0 :                         lp->origin = ptr + 1;
      81                 :            :         }
      82                 :            : 
      83         [ #  # ]:          0 :         if (!*pargc) {
      84                 :          0 :                 log_error("Please provide logical volume path");
      85                 :          0 :                 return 0;
      86                 :            :         }
      87                 :            : 
      88                 :          0 :         lp->lv_name = lp->lv_name_full = (*pargv)[0];
      89                 :          0 :         (*pargv)++, (*pargc)--;
      90                 :            : 
      91   [ #  #  #  # ]:          0 :         if (strchr(lp->lv_name_full, '/') &&
         [ #  # ][ #  # ]
      92                 :          0 :             (vg_name = extract_vgname(cmd, lp->lv_name_full)) &&
      93                 :          0 :             lp->vg_name && strcmp(vg_name, lp->vg_name)) {
      94                 :          0 :                 log_error("Please use a single volume group name "
      95                 :            :                           "(\"%s\" or \"%s\")", vg_name, lp->vg_name);
      96                 :          0 :                 return 0;
      97                 :            :         }
      98                 :            : 
      99         [ #  # ]:          0 :         if (!lp->vg_name)
     100                 :          0 :                 lp->vg_name = vg_name;
     101                 :            : 
     102         [ #  # ]:          0 :         if (!validate_name(lp->vg_name)) {
     103                 :          0 :                 log_error("Please provide a valid volume group name");
     104                 :          0 :                 return 0;
     105                 :            :         }
     106                 :            : 
     107         [ #  # ]:          0 :         if ((ptr = strrchr(lp->lv_name_full, '/')))
     108                 :          0 :                 lp->lv_name = ptr + 1;
     109                 :            : 
     110         [ #  # ]:          0 :         if (!apply_lvname_restrictions(lp->lv_name))
     111                 :          0 :                 return_0;
     112                 :            : 
     113 [ #  # ][ #  # ]:          0 :         if (*pargc && lp->snapshot) {
     114                 :          0 :                 log_error("Too many arguments provided for snapshots");
     115                 :          0 :                 return 0;
     116                 :            :         }
     117                 :            : 
     118                 :          0 :         return 1;
     119                 :            : }
     120                 :            : 
     121                 :          0 : static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
     122                 :            :                         int argc, char **argv)
     123                 :            : {
     124                 :            :         int region_size;
     125                 :          0 :         int pagesize = lvm_getpagesize();
     126                 :            : 
     127                 :          0 :         memset(lp, 0, sizeof(*lp));
     128                 :            : 
     129 [ #  #  #  #  # :          0 :         if ((arg_count(cmd, snapshot_ARG) || arg_count(cmd, merge_ARG)) &&
          #  #  #  #  # ]
     130                 :          0 :             (arg_count(cmd, mirrorlog_ARG) || arg_count(cmd, mirrors_ARG) ||
     131                 :          0 :              arg_count(cmd, repair_ARG))) {
     132                 :          0 :                 log_error("--snapshot or --merge argument cannot be mixed "
     133                 :            :                           "with --mirrors, --repair or --log");
     134                 :          0 :                 return 0;
     135                 :            :         }
     136                 :            : 
     137         [ #  # ]:          0 :         if (!arg_count(cmd, background_ARG))
     138                 :          0 :                 lp->wait_completion = 1;
     139                 :            : 
     140         [ #  # ]:          0 :         if (arg_count(cmd, snapshot_ARG))
     141                 :          0 :                 lp->snapshot = 1;
     142                 :            : 
     143 [ #  # ][ #  # ]:          0 :         if (arg_count(cmd, snapshot_ARG) && arg_count(cmd, merge_ARG)) {
     144                 :          0 :                 log_error("--snapshot and --merge are mutually exclusive");
     145                 :          0 :                 return 0;
     146                 :            :         }
     147                 :            : 
     148 [ #  # ][ #  # ]:          0 :         if (arg_count(cmd, splitmirrors_ARG) && arg_count(cmd, mirrors_ARG)) {
     149                 :          0 :                 log_error("--mirrors and --splitmirrors are "
     150                 :            :                           "mutually exclusive");
     151                 :          0 :                 return 0;
     152                 :            :         }
     153                 :            : 
     154                 :            :         /*
     155                 :            :          * The '--splitmirrors n' argument is equivalent to '--mirrors -n'
     156                 :            :          * (note the minus sign), except that it signifies the additional
     157                 :            :          * intent to keep the mimage that is detached, rather than
     158                 :            :          * discarding it.
     159                 :            :          */
     160         [ #  # ]:          0 :         if (arg_count(cmd, splitmirrors_ARG)) {
     161         [ #  # ]:          0 :                 if (!arg_count(cmd, name_ARG)) {
     162                 :          0 :                         log_error("Please name the new logical volume using '--name'");
     163                 :          0 :                         return 0;
     164                 :            :                 }
     165                 :            : 
     166                 :          0 :                 lp->lv_split_name = arg_value(cmd, name_ARG);
     167         [ #  # ]:          0 :                 if (!apply_lvname_restrictions(lp->lv_split_name))
     168                 :          0 :                         return_0;
     169                 :            : 
     170                 :          0 :                 lp->keep_mimages = 1;
     171         [ #  # ]:          0 :                 if (arg_sign_value(cmd, mirrors_ARG, 0) == SIGN_MINUS) {
     172                 :          0 :                         log_error("Argument to --splitmirrors"
     173                 :            :                                   " cannot be negative");
     174                 :          0 :                         return 0;
     175                 :            :                 }
     176                 :          0 :                 lp->mirrors = arg_uint_value(cmd, splitmirrors_ARG, 0);
     177                 :          0 :                 lp->mirrors_sign = SIGN_MINUS;
     178         [ #  # ]:          0 :         } else if (arg_count(cmd, name_ARG)) {
     179                 :          0 :                 log_error("The 'name' argument is only valid"
     180                 :            :                           " with --splitmirrors");
     181                 :          0 :                 return 0;
     182                 :            :         }
     183                 :            : 
     184         [ #  # ]:          0 :         if (arg_count(cmd, merge_ARG))
     185                 :          0 :                 lp->merge = 1;
     186                 :            : 
     187         [ #  # ]:          0 :         if (arg_count(cmd, mirrors_ARG)) {
     188                 :            :                 /*
     189                 :            :                  * --splitmirrors has been chosen as the mechanism for
     190                 :            :                  * specifying the intent of detaching and keeping a mimage
     191                 :            :                  * versus an additional qualifying argument being added here.
     192                 :            :                  */
     193                 :          0 :                 lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 0);
     194                 :          0 :                 lp->mirrors_sign = arg_sign_value(cmd, mirrors_ARG, 0);
     195                 :            :         }
     196                 :            : 
     197                 :          0 :         lp->alloc = arg_uint_value(cmd, alloc_ARG, ALLOC_INHERIT);
     198                 :            : 
     199                 :            :         /* There are three types of lvconvert. */
     200         [ #  # ]:          0 :         if (lp->merge) {     /* Snapshot merge */
     201 [ #  # ][ #  #  :          0 :                 if (arg_count(cmd, regionsize_ARG) || arg_count(cmd, chunksize_ARG) ||
          #  #  #  #  #  
                #  #  # ]
     202                 :          0 :                     arg_count(cmd, zero_ARG) || arg_count(cmd, regionsize_ARG) ||
     203                 :          0 :                     arg_count(cmd, stripes_long_ARG) || arg_count(cmd, stripesize_ARG)) {
     204                 :          0 :                         log_error("Only --background and --interval are valid "
     205                 :            :                                   "arguments for snapshot merge");
     206                 :          0 :                         return 0;
     207                 :            :                 }
     208                 :            : 
     209         [ #  # ]:          0 :                 if (!(lp->segtype = get_segtype_from_string(cmd, "snapshot")))
     210                 :          0 :                         return_0;
     211                 :            : 
     212         [ #  # ]:          0 :         } else if (lp->snapshot) {   /* Snapshot creation from pre-existing cow */
     213         [ #  # ]:          0 :                 if (arg_count(cmd, regionsize_ARG)) {
     214                 :          0 :                         log_error("--regionsize is only available with mirrors");
     215                 :          0 :                         return 0;
     216                 :            :                 }
     217                 :            : 
     218 [ #  # ][ #  # ]:          0 :                 if (arg_count(cmd, stripesize_ARG) || arg_count(cmd, stripes_long_ARG)) {
     219                 :          0 :                         log_error("--stripes and --stripesize are only available with striped mirrors");
     220                 :          0 :                         return 0;
     221                 :            :                 }
     222                 :            : 
     223         [ #  # ]:          0 :                 if (arg_sign_value(cmd, chunksize_ARG, 0) == SIGN_MINUS) {
     224                 :          0 :                         log_error("Negative chunk size is invalid");
     225                 :          0 :                         return 0;
     226                 :            :                 }
     227                 :          0 :                 lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, 8);
     228   [ #  #  #  # ]:          0 :                 if (lp->chunk_size < 8 || lp->chunk_size > 1024 ||
                 [ #  # ]
     229                 :          0 :                     (lp->chunk_size & (lp->chunk_size - 1))) {
     230                 :          0 :                         log_error("Chunk size must be a power of 2 in the "
     231                 :            :                                   "range 4K to 512K");
     232                 :          0 :                         return 0;
     233                 :            :                 }
     234                 :          0 :                 log_verbose("Setting chunksize to %d sectors.", lp->chunk_size);
     235                 :            : 
     236         [ #  # ]:          0 :                 if (!(lp->segtype = get_segtype_from_string(cmd, "snapshot")))
     237                 :          0 :                         return_0;
     238                 :            : 
     239         [ #  # ]:          0 :                 lp->zero = strcmp(arg_str_value(cmd, zero_ARG,
     240                 :          0 :                                                 (lp->segtype->flags &
     241                 :            :                                                  SEG_CANNOT_BE_ZEROED) ?
     242                 :            :                                                 "n" : "y"), "n");
     243                 :            : 
     244                 :            :         } else {        /* Mirrors */
     245         [ #  # ]:          0 :                 if (arg_count(cmd, chunksize_ARG)) {
     246                 :          0 :                         log_error("--chunksize is only available with "
     247                 :            :                                   "snapshots");
     248                 :          0 :                         return 0;
     249                 :            :                 }
     250                 :            : 
     251         [ #  # ]:          0 :                 if (arg_count(cmd, zero_ARG)) {
     252                 :          0 :                         log_error("--zero is only available with snapshots");
     253                 :          0 :                         return 0;
     254                 :            :                 }
     255                 :            : 
     256                 :            :                 /*
     257                 :            :                  * --regionsize is only valid if converting an LV into a mirror.
     258                 :            :                  * Checked when we know the state of the LV being converted.
     259                 :            :                  */
     260                 :            : 
     261         [ #  # ]:          0 :                 if (arg_count(cmd, regionsize_ARG)) {
     262         [ #  # ]:          0 :                         if (arg_sign_value(cmd, regionsize_ARG, 0) ==
     263                 :            :                                     SIGN_MINUS) {
     264                 :          0 :                                 log_error("Negative regionsize is invalid");
     265                 :          0 :                                 return 0;
     266                 :            :                         }
     267                 :          0 :                         lp->region_size = arg_uint_value(cmd, regionsize_ARG, 0);
     268                 :            :                 } else {
     269                 :          0 :                         region_size = 2 * find_config_tree_int(cmd,
     270                 :            :                                                 "activation/mirror_region_size",
     271                 :            :                                                 DEFAULT_MIRROR_REGION_SIZE);
     272         [ #  # ]:          0 :                         if (region_size < 0) {
     273                 :          0 :                                 log_error("Negative regionsize in "
     274                 :            :                                           "configuration file is invalid");
     275                 :          0 :                                 return 0;
     276                 :            :                         }
     277                 :          0 :                         lp->region_size = region_size;
     278                 :            :                 }
     279                 :            : 
     280         [ #  # ]:          0 :                 if (lp->region_size % (pagesize >> SECTOR_SHIFT)) {
     281                 :          0 :                         log_error("Region size (%" PRIu32 ") must be "
     282                 :            :                                   "a multiple of machine memory "
     283                 :            :                                   "page size (%d)",
     284                 :            :                                   lp->region_size, pagesize >> SECTOR_SHIFT);
     285                 :          0 :                         return 0;
     286                 :            :                 }
     287                 :            : 
     288         [ #  # ]:          0 :                 if (lp->region_size & (lp->region_size - 1)) {
     289                 :          0 :                         log_error("Region size (%" PRIu32
     290                 :            :                                   ") must be a power of 2", lp->region_size);
     291                 :          0 :                         return 0;
     292                 :            :                 }
     293                 :            : 
     294         [ #  # ]:          0 :                 if (!lp->region_size) {
     295                 :          0 :                         log_error("Non-zero region size must be supplied.");
     296                 :          0 :                         return 0;
     297                 :            :                 }
     298                 :            : 
     299                 :            :                 /* Default is never striped, regardless of existing LV configuration. */
     300         [ #  # ]:          0 :                 if (!get_stripe_params(cmd, &lp->stripes, &lp->stripe_size)) {
     301                 :          0 :                         stack;
     302                 :          0 :                         return 0;
     303                 :            :                 }
     304                 :            : 
     305         [ #  # ]:          0 :                 if (!(lp->segtype = get_segtype_from_string(cmd, "mirror")))
     306                 :          0 :                         return_0;
     307                 :            :         }
     308                 :            : 
     309         [ #  # ]:          0 :         if (activation() && lp->segtype->ops->target_present &&
           [ #  #  #  # ]
     310                 :          0 :             !lp->segtype->ops->target_present(cmd, NULL, NULL)) {
     311                 :          0 :                 log_error("%s: Required device-mapper target(s) not "
     312                 :            :                           "detected in your kernel", lp->segtype->name);
     313                 :          0 :                 return 0;
     314                 :            :         }
     315                 :            : 
     316         [ #  # ]:          0 :         if (!_lvconvert_name_params(lp, cmd, &argc, &argv))
     317                 :          0 :                 return_0;
     318                 :            : 
     319                 :          0 :         lp->pv_count = argc;
     320                 :          0 :         lp->pvs = argv;
     321                 :          0 :         lp->failed_pvs = NULL;
     322                 :            : 
     323                 :          0 :         return 1;
     324                 :            : }
     325                 :            : 
     326                 :          0 : static struct volume_group *_get_lvconvert_vg(struct cmd_context *cmd,
     327                 :            :                                               const char *name,
     328                 :            :                                               const char *uuid __attribute((unused)))
     329                 :            : {
     330                 :          0 :         dev_close_all();
     331                 :            : 
     332   [ #  #  #  # ]:          0 :         if (name && !strchr(name, '/'))
     333                 :          0 :                 return vg_read_for_update(cmd, name, NULL, 0);
     334                 :            : 
     335                 :            :         /* 'name' is the full LV name; must extract_vgname() */
     336                 :          0 :         return vg_read_for_update(cmd, extract_vgname(cmd, name),
     337                 :            :                                   NULL, 0);
     338                 :            : }
     339                 :            : 
     340                 :          0 : static struct logical_volume *_get_lvconvert_lv(struct cmd_context *cmd __attribute((unused)),
     341                 :            :                                                 struct volume_group *vg,
     342                 :            :                                                 const char *name,
     343                 :            :                                                 const char *uuid,
     344                 :            :                                                 uint32_t lv_type __attribute((unused)))
     345                 :            : {
     346                 :          0 :         struct logical_volume *lv = find_lv(vg, name);
     347                 :            : 
     348   [ #  #  #  # ]:          0 :         if (!lv || (uuid && strcmp(uuid, (char *)&lv->lvid)))
                 [ #  # ]
     349                 :          0 :                 return NULL;
     350                 :            : 
     351                 :          0 :         return lv;
     352                 :            : }
     353                 :            : 
     354                 :          0 : static int _finish_lvconvert_mirror(struct cmd_context *cmd,
     355                 :            :                                     struct volume_group *vg,
     356                 :            :                                     struct logical_volume *lv,
     357                 :            :                                     struct dm_list *lvs_changed __attribute((unused)))
     358                 :            : {
     359                 :          0 :         int r = 0;
     360                 :            : 
     361         [ #  # ]:          0 :         if (!(lv->status & CONVERTING))
     362                 :          0 :                 return 1;
     363                 :            : 
     364         [ #  # ]:          0 :         if (!collapse_mirrored_lv(lv)) {
     365                 :          0 :                 log_error("Failed to remove temporary sync layer.");
     366                 :          0 :                 return 0;
     367                 :            :         }
     368                 :            : 
     369                 :          0 :         lv->status &= ~CONVERTING;
     370                 :            : 
     371                 :          0 :         log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
     372                 :            : 
     373         [ #  # ]:          0 :         if (!vg_write(vg))
     374                 :          0 :                 return_0;
     375                 :            : 
     376 [ #  # ][ #  # ]:          0 :         if (!suspend_lv(cmd, lv)) {
                 [ #  # ]
     377                 :          0 :                 log_error("Failed to lock %s", lv->name);
     378                 :          0 :                 vg_revert(vg);
     379                 :          0 :                 goto out;
     380                 :            :         }
     381                 :            : 
     382         [ #  # ]:          0 :         if (!vg_commit(vg)) {
     383 [ #  # ][ #  # ]:          0 :                 resume_lv(cmd, lv);
     384                 :          0 :                 goto_out;
     385                 :            :         }
     386                 :            : 
     387                 :          0 :         log_very_verbose("Updating \"%s\" in kernel", lv->name);
     388                 :            : 
     389   [ #  #  #  # ]:          0 :         if (!resume_lv(cmd, lv)) {
                 [ #  # ]
     390                 :          0 :                 log_error("Problem reactivating %s", lv->name);
     391                 :          0 :                 goto out;
     392                 :            :         }
     393                 :            : 
     394                 :          0 :         r = 1;
     395                 :          0 :         log_print("Logical volume %s converted.", lv->name);
     396                 :            : out:
     397                 :          0 :         backup(vg);
     398                 :          0 :         return r;
     399                 :            : }
     400                 :            : 
     401                 :          0 : static int _finish_lvconvert_merge(struct cmd_context *cmd,
     402                 :            :                                    struct volume_group *vg,
     403                 :            :                                    struct logical_volume *lv,
     404                 :            :                                    struct dm_list *lvs_changed __attribute((unused)))
     405                 :            : {
     406                 :          0 :         struct lv_segment *snap_seg = find_merging_cow(lv);
     407         [ #  # ]:          0 :         if (!snap_seg) {
     408                 :          0 :                 log_error("Logical volume %s has no merging snapshot.", lv->name);
     409                 :          0 :                 return 0;
     410                 :            :         }
     411                 :            : 
     412                 :          0 :         log_print("Merge of snapshot into logical volume %s has finished.", lv->name);
     413         [ #  # ]:          0 :         if (!lv_remove_single(cmd, snap_seg->cow, DONT_PROMPT)) {
     414                 :          0 :                 log_error("Could not remove snapshot %s merged into %s.",
     415                 :            :                           snap_seg->cow->name, lv->name);
     416                 :          0 :                 return 0;
     417                 :            :         }
     418                 :            : 
     419                 :          0 :         return 1;
     420                 :            : }
     421                 :            : 
     422                 :          0 : static progress_t _poll_merge_progress(struct cmd_context *cmd,
     423                 :            :                                        struct logical_volume *lv,
     424                 :            :                                        const char *name __attribute((unused)),
     425                 :            :                                        struct daemon_parms *parms)
     426                 :            : {
     427                 :          0 :         float percent = 0.0;
     428                 :            :         percent_range_t percent_range;
     429                 :            : 
     430         [ #  # ]:          0 :         if (!lv_snapshot_percent(lv, &percent, &percent_range)) {
     431                 :          0 :                 log_error("%s: Failed query for merging percentage. Aborting merge.", lv->name);
     432                 :          0 :                 return PROGRESS_CHECK_FAILED;
     433         [ #  # ]:          0 :         } else if (percent_range == PERCENT_INVALID) {
     434                 :          0 :                 log_error("%s: Merging snapshot invalidated. Aborting merge.", lv->name);
     435                 :          0 :                 return PROGRESS_CHECK_FAILED;
     436                 :            :         }
     437                 :            : 
     438         [ #  # ]:          0 :         if (parms->progress_display)
     439                 :          0 :                 log_print("%s: %s: %.1f%%", lv->name, parms->progress_title, percent);
     440                 :            :         else
     441                 :          0 :                 log_verbose("%s: %s: %.1f%%", lv->name, parms->progress_title, percent);
     442                 :            : 
     443         [ #  # ]:          0 :         if (percent_range == PERCENT_0)
     444                 :          0 :                 return PROGRESS_FINISHED_ALL;
     445                 :            : 
     446                 :          0 :         return PROGRESS_UNFINISHED;
     447                 :            : }
     448                 :            : 
     449                 :            : static struct poll_functions _lvconvert_mirror_fns = {
     450                 :            :         .get_copy_vg = _get_lvconvert_vg,
     451                 :            :         .get_copy_lv = _get_lvconvert_lv,
     452                 :            :         .poll_progress = poll_mirror_progress,
     453                 :            :         .finish_copy = _finish_lvconvert_mirror,
     454                 :            : };
     455                 :            : 
     456                 :            : static struct poll_functions _lvconvert_merge_fns = {
     457                 :            :         .get_copy_vg = _get_lvconvert_vg,
     458                 :            :         .get_copy_lv = _get_lvconvert_lv,
     459                 :            :         .poll_progress = _poll_merge_progress,
     460                 :            :         .finish_copy = _finish_lvconvert_merge,
     461                 :            : };
     462                 :            : 
     463                 :          0 : int lvconvert_poll(struct cmd_context *cmd, struct logical_volume *lv,
     464                 :            :                    unsigned background)
     465                 :            : {
     466                 :            :         /*
     467                 :            :          * FIXME allocate an "object key" structure with split
     468                 :            :          * out members (vg_name, lv_name, uuid, etc) and pass that
     469                 :            :          * around the lvconvert and polldaemon code
     470                 :            :          * - will avoid needless work, e.g. extract_vgname()
     471                 :            :          * - unfortunately there are enough overloaded "name" dragons in
     472                 :            :          *   the polldaemon, lvconvert, pvmove code that a comprehensive
     473                 :            :          *   audit/rework is needed
     474                 :            :          */
     475                 :          0 :         int len = strlen(lv->vg->name) + strlen(lv->name) + 2;
     476                 :          0 :         char *uuid = alloca(sizeof(lv->lvid));
     477                 :          0 :         char *lv_full_name = alloca(len);
     478                 :            : 
     479 [ #  # ][ #  # ]:          0 :         if (!uuid || !lv_full_name)
     480                 :          0 :                 return_0;
     481                 :            : 
     482         [ #  # ]:          0 :         if (!dm_snprintf(lv_full_name, len, "%s/%s", lv->vg->name, lv->name))
     483                 :          0 :                 return_0;
     484                 :            : 
     485                 :          0 :         memcpy(uuid, &lv->lvid, sizeof(lv->lvid));
     486                 :            : 
     487         [ #  # ]:          0 :         if (!lv_is_merging_origin(lv))
     488                 :          0 :                 return poll_daemon(cmd, lv_full_name, uuid, background, 0,
     489                 :            :                                    &_lvconvert_mirror_fns, "Converted");
     490                 :            :         else
     491                 :          0 :                 return poll_daemon(cmd, lv_full_name, uuid, background, 0,
     492                 :            :                                    &_lvconvert_merge_fns, "Merged");
     493                 :            : }
     494                 :            : 
     495                 :          0 : static int _insert_lvconvert_layer(struct cmd_context *cmd,
     496                 :            :                                    struct logical_volume *lv)
     497                 :            : {
     498                 :            :         char *format, *layer_name;
     499                 :            :         size_t len;
     500                 :            :         int i;
     501                 :            : 
     502                 :            :         /*
     503                 :            :          * We would like to give the same number for this layer
     504                 :            :          * and the newly added mimage.
     505                 :            :          * However, LV name of newly added mimage is determined *after*
     506                 :            :          * the LV name of this layer is determined.
     507                 :            :          *
     508                 :            :          * So, use generate_lv_name() to generate mimage name first
     509                 :            :          * and take the number from it.
     510                 :            :          */
     511                 :            : 
     512                 :          0 :         len = strlen(lv->name) + 32;
     513         [ #  # ]:          0 :         if (!(format = alloca(len)) ||
     514                 :          0 :             !(layer_name = alloca(len)) ||
     515                 :          0 :             dm_snprintf(format, len, "%s_mimage_%%d", lv->name) < 0) {
     516                 :          0 :                 log_error("lvconvert: layer name allocation failed.");
     517                 :          0 :                 return 0;
     518                 :            :         }
     519                 :            : 
     520 [ #  # ][ #  # ]:          0 :         if (!generate_lv_name(lv->vg, format, layer_name, len) ||
     521                 :          0 :             sscanf(layer_name, format, &i) != 1) {
     522                 :          0 :                 log_error("lvconvert: layer name generation failed.");
     523                 :          0 :                 return 0;
     524                 :            :         }
     525                 :            : 
     526         [ #  # ]:          0 :         if (dm_snprintf(layer_name, len, MIRROR_SYNC_LAYER "_%d", i) < 0) {
     527                 :          0 :                 log_error("layer name allocation failed.");
     528                 :          0 :                 return 0;
     529                 :            :         }
     530                 :            : 
     531         [ #  # ]:          0 :         if (!insert_layer_for_lv(cmd, lv, 0, layer_name)) {
     532                 :          0 :                 log_error("Failed to insert resync layer");
     533                 :          0 :                 return 0;
     534                 :            :         }
     535                 :            : 
     536                 :          0 :         return 1;
     537                 :            : }
     538                 :            : 
     539                 :          0 : static int _area_missing(struct lv_segment *lvseg, int s)
     540                 :            : {
     541         [ #  # ]:          0 :         if (seg_type(lvseg, s) == AREA_LV) {
     542         [ #  # ]:          0 :                 if (seg_lv(lvseg, s)->status & PARTIAL_LV)
     543                 :          0 :                         return 1;
     544   [ #  #  #  # ]:          0 :         } else if ((seg_type(lvseg, s) == AREA_PV) &&
     545                 :          0 :                    (is_missing_pv(seg_pv(lvseg, s))))
     546                 :          0 :                 return 1;
     547                 :            : 
     548                 :          0 :         return 0;
     549                 :            : }
     550                 :            : 
     551                 :            : /* FIXME we want to handle mirror stacks here... */
     552                 :          0 : static int _failed_mirrors_count(struct logical_volume *lv)
     553                 :            : {
     554                 :            :         struct lv_segment *lvseg;
     555                 :          0 :         int ret = 0;
     556                 :            :         int s;
     557                 :            : 
     558         [ #  # ]:          0 :         dm_list_iterate_items(lvseg, &lv->segments) {
     559         [ #  # ]:          0 :                 if (!seg_is_mirrored(lvseg))
     560                 :          0 :                         return -1;
     561         [ #  # ]:          0 :                 for (s = 0; s < lvseg->area_count; s++)
     562         [ #  # ]:          0 :                         if (_area_missing(lvseg, s))
     563                 :          0 :                                 ret++;
     564                 :            :         }
     565                 :            : 
     566                 :          0 :         return ret;
     567                 :            : }
     568                 :            : 
     569                 :          0 : static struct dm_list *_failed_pv_list(struct volume_group *vg)
     570                 :            : {
     571                 :            :         struct dm_list *failed_pvs;
     572                 :            :         struct pv_list *pvl, *new_pvl;
     573                 :            : 
     574         [ #  # ]:          0 :         if (!(failed_pvs = dm_pool_alloc(vg->vgmem, sizeof(*failed_pvs)))) {
     575                 :          0 :                 log_error("Allocation of list of failed_pvs failed.");
     576                 :          0 :                 return_NULL;
     577                 :            :         }
     578                 :            : 
     579                 :          0 :         dm_list_init(failed_pvs);
     580                 :            : 
     581         [ #  # ]:          0 :         dm_list_iterate_items(pvl, &vg->pvs) {
     582         [ #  # ]:          0 :                 if (!is_missing_pv(pvl->pv))
     583                 :          0 :                         continue;
     584                 :            : 
     585                 :            :                 /* 
     586                 :            :                  * Finally, --repair will remove empty PVs.
     587                 :            :                  * But we only want remove these which are output of repair,
     588                 :            :                  * Do not count these which are already empty here.
     589                 :            :                  * FIXME: code should traverse PV in LV not in whole VG.
     590                 :            :                  * FIXME: layer violation? should it depend on vgreduce --removemising?
     591                 :            :                  */
     592         [ #  # ]:          0 :                 if (pvl->pv->pe_alloc_count == 0)
     593                 :          0 :                         continue;
     594                 :            : 
     595         [ #  # ]:          0 :                 if (!(new_pvl = dm_pool_alloc(vg->vgmem, sizeof(*new_pvl)))) {
     596                 :          0 :                         log_error("Allocation of failed_pvs list entry failed.");
     597                 :          0 :                         return_NULL;
     598                 :            :                 }
     599                 :          0 :                 new_pvl->pv = pvl->pv;
     600                 :          0 :                 dm_list_add(failed_pvs, &new_pvl->list);
     601                 :            :         }
     602                 :            : 
     603                 :          0 :         return failed_pvs;
     604                 :            : }
     605                 :            : 
     606                 :            : /*
     607                 :            :  * Walk down the stacked mirror LV to the original mirror LV.
     608                 :            :  */
     609                 :          0 : static struct logical_volume *_original_lv(struct logical_volume *lv)
     610                 :            : {
     611                 :          0 :         struct logical_volume *next_lv = lv, *tmp_lv;
     612                 :            : 
     613         [ #  # ]:          0 :         while ((tmp_lv = find_temporary_mirror(next_lv)))
     614                 :          0 :                 next_lv = tmp_lv;
     615                 :            : 
     616                 :          0 :         return next_lv;
     617                 :            : }
     618                 :            : 
     619                 :          0 : static void _lvconvert_mirrors_repair_ask(struct cmd_context *cmd,
     620                 :            :                                           int failed_log, int failed_mirrors,
     621                 :            :                                           int *replace_log, int *replace_mirrors)
     622                 :            : {
     623                 :          0 :         const char *leg_policy = NULL, *log_policy = NULL;
     624                 :            : 
     625                 :          0 :         int force = arg_count(cmd, force_ARG);
     626                 :          0 :         int yes = arg_count(cmd, yes_ARG);
     627                 :            : 
     628                 :          0 :         *replace_log = *replace_mirrors = 1;
     629                 :            : 
     630         [ #  # ]:          0 :         if (arg_count(cmd, use_policies_ARG)) {
     631                 :          0 :                 leg_policy = find_config_tree_str(cmd,
     632                 :            :                                         "activation/mirror_image_fault_policy", NULL);
     633         [ #  # ]:          0 :                 if (!leg_policy)
     634                 :          0 :                         leg_policy = find_config_tree_str(cmd,
     635                 :            :                                         "activation/mirror_device_fault_policy",
     636                 :            :                                         DEFAULT_MIRROR_DEVICE_FAULT_POLICY);
     637                 :          0 :                 log_policy = find_config_tree_str(cmd,
     638                 :            :                                         "activation/mirror_log_fault_policy",
     639                 :            :                                         DEFAULT_MIRROR_LOG_FAULT_POLICY);
     640                 :          0 :                 *replace_mirrors = strcmp(leg_policy, "remove");
     641                 :          0 :                 *replace_log = strcmp(log_policy, "remove");
     642                 :          0 :                 return;
     643                 :            :         }
     644                 :            : 
     645         [ #  # ]:          0 :         if (yes)
     646                 :          0 :                 return;
     647                 :            : 
     648         [ #  # ]:          0 :         if (force != PROMPT) {
     649                 :          0 :                 *replace_log = *replace_mirrors = 0;
     650                 :          0 :                 return;
     651                 :            :         }
     652                 :            : 
     653   [ #  #  #  # ]:          0 :         if (failed_log &&
     654                 :          0 :             yes_no_prompt("Attempt to replace failed mirror log? [y/n]: ") == 'n') {
     655                 :          0 :                 *replace_log = 0;
     656                 :            :         }
     657                 :            : 
     658   [ #  #  #  # ]:          0 :         if (failed_mirrors &&
     659                 :            :             yes_no_prompt("Attempt to replace failed mirror images "
     660                 :          0 :                           "(requires full device resync)? [y/n]: ") == 'n') {
     661                 :          0 :                 *replace_mirrors = 0;
     662                 :            :         }
     663                 :            : }
     664                 :            : 
     665                 :            : /*
     666                 :            :  * _get_log_count
     667                 :            :  * @lv: the mirror LV
     668                 :            :  *
     669                 :            :  * Get the number of on-disk copies of the log.
     670                 :            :  *  0  = 'core'
     671                 :            :  *  1  = 'disk'
     672                 :            :  *  2+ = 'mirrored'
     673                 :            :  */
     674                 :          0 : static int _get_log_count(struct logical_volume *lv)
     675                 :            : {
     676                 :            :         struct logical_volume *log_lv;
     677                 :            : 
     678                 :          0 :         log_lv = first_seg(_original_lv(lv))->log_lv;
     679         [ #  # ]:          0 :         if (!log_lv)
     680                 :          0 :                 return 0;
     681                 :            : 
     682                 :          0 :         return lv_mirror_count(log_lv);
     683                 :            : }
     684                 :            : 
     685                 :          0 : static int _lv_update_log_type(struct cmd_context *cmd,
     686                 :            :                                struct lvconvert_params *lp,
     687                 :            :                                struct logical_volume *lv,
     688                 :            :                                struct dm_list *operable_pvs,
     689                 :            :                                int log_count)
     690                 :            : {
     691                 :            :         uint32_t region_size;
     692                 :            :         int old_log_count;
     693                 :            :         struct logical_volume *original_lv;
     694                 :            :         struct logical_volume *log_lv;
     695                 :            : 
     696                 :          0 :         old_log_count = _get_log_count(lv);
     697         [ #  # ]:          0 :         if (old_log_count == log_count)
     698                 :          0 :                 return 1;
     699                 :            : 
     700                 :          0 :         original_lv = _original_lv(lv);
     701                 :          0 :         region_size = adjusted_mirror_region_size(lv->vg->extent_size,
     702                 :            :                                                   lv->le_count,
     703                 :            :                                                   lp->region_size);
     704                 :            : 
     705                 :            :         /* Add a log where there is none */
     706         [ #  # ]:          0 :         if (!old_log_count) {
     707         [ #  # ]:          0 :                 if (!add_mirror_log(cmd, original_lv, log_count,
     708                 :            :                                     region_size, operable_pvs, lp->alloc))
     709                 :          0 :                         return_0;
     710                 :          0 :                 return 1;
     711                 :            :         }
     712                 :            : 
     713                 :            :         /* Remove an existing log completely */
     714         [ #  # ]:          0 :         if (!log_count) {
     715         [ #  # ]:          0 :                 if (!remove_mirror_log(cmd, original_lv, operable_pvs))
     716                 :          0 :                         return_0;
     717                 :          0 :                 return 1;
     718                 :            :         }
     719                 :            : 
     720                 :          0 :         log_lv = first_seg(original_lv)->log_lv;
     721                 :            : 
     722                 :            :         /* Adding redundancy to the log */
     723         [ #  # ]:          0 :         if (old_log_count < log_count) {
     724                 :          0 :                 log_error("Adding log redundancy not supported yet.");
     725                 :          0 :                 log_error("Try converting the log to 'core' first.");
     726                 :          0 :                 return_0;
     727                 :            :         }
     728                 :            : 
     729                 :            :         /* Reducing redundancy of the log */
     730                 :          0 :         return remove_mirror_images(log_lv, log_count, operable_pvs, 1U);
     731                 :            : }
     732                 :            : 
     733                 :            : /*
     734                 :            :  * Reomove missing and empty PVs from VG, if are also in provided list
     735                 :            :  */
     736                 :          0 : static void _remove_missing_empty_pv(struct volume_group *vg, struct dm_list *remove_pvs)
     737                 :            : {
     738                 :            :         struct pv_list *pvl, *pvl_vg, *pvlt;
     739                 :          0 :         int removed = 0;
     740                 :            : 
     741         [ #  # ]:          0 :         if (!remove_pvs)
     742                 :          0 :                 return;
     743                 :            : 
     744         [ #  # ]:          0 :         dm_list_iterate_items(pvl, remove_pvs) {
     745         [ #  # ]:          0 :                 dm_list_iterate_items_safe(pvl_vg, pvlt, &vg->pvs) {
     746   [ #  #  #  # ]:          0 :                         if (!id_equal(&pvl->pv->id, &pvl_vg->pv->id) ||
                 [ #  # ]
     747                 :          0 :                             !is_missing_pv(pvl_vg->pv) ||
     748                 :          0 :                             pvl_vg->pv->pe_alloc_count != 0)
     749                 :          0 :                                 continue;
     750                 :            : 
     751                 :            :                         /* FIXME: duplication of vgreduce code, move this to library */
     752                 :          0 :                         vg->free_count -= pvl_vg->pv->pe_count;
     753                 :          0 :                         vg->extent_count -= pvl_vg->pv->pe_count;
     754                 :          0 :                         vg->pv_count--;
     755                 :          0 :                         dm_list_del(&pvl_vg->list);
     756                 :            : 
     757                 :          0 :                         removed++;
     758                 :            :                 }
     759                 :            :         }
     760                 :            : 
     761         [ #  # ]:          0 :         if (removed) {
     762 [ #  # ][ #  # ]:          0 :                 if (!vg_write(vg) || !vg_commit(vg)) {
     763                 :          0 :                         stack;
     764                 :          0 :                         return;
     765                 :            :                 }
     766                 :            : 
     767                 :          0 :                 log_warn("%d missing and now unallocated Physical Volumes removed from VG.", removed);
     768                 :            :         }
     769                 :            : }
     770                 :            : 
     771                 :            : /*
     772                 :            :  * _lvconvert_mirrors_parse_params
     773                 :            :  *
     774                 :            :  * This function performs the following:
     775                 :            :  *  1) Gets the old values of mimage and log counts
     776                 :            :  *  2) Parses the CLI args to find the new desired values
     777                 :            :  *  3) Adjusts 'lp->mirrors' to the appropriate absolute value.
     778                 :            :  *     (Remember, 'lp->mirrors' is specified in terms of the number of "copies"
     779                 :            :  *      vs. the number of mimages.  It can also be a relative value.)
     780                 :            :  *  4) Sets 'lp->need_polling' if collapsing
     781                 :            :  *  5) Validates other mirror params
     782                 :            :  *
     783                 :            :  * Returns: 1 on success, 0 on error
     784                 :            :  */
     785                 :          0 : static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd,
     786                 :            :                                            struct logical_volume *lv,
     787                 :            :                                            struct lvconvert_params *lp,
     788                 :            :                                            uint32_t *old_mimage_count,
     789                 :            :                                            uint32_t *old_log_count,
     790                 :            :                                            uint32_t *new_mimage_count,
     791                 :            :                                            uint32_t *new_log_count)
     792                 :            : {
     793                 :          0 :         int repair = arg_count(cmd, repair_ARG);
     794                 :            :         const char *mirrorlog;
     795                 :          0 :         *old_mimage_count = lv_mirror_count(lv);
     796                 :          0 :         *old_log_count = _get_log_count(lv);
     797                 :            : 
     798                 :            :         /*
     799                 :            :          * Collapsing a stack of mirrors:
     800                 :            :          *
     801                 :            :          * If called with no argument, try collapsing the resync layers
     802                 :            :          */
     803 [ #  #  #  #  # :          0 :         if (!arg_count(cmd, mirrors_ARG) && !arg_count(cmd, mirrorlog_ARG) &&
          #  #  #  #  # ]
                 [ #  # ]
     804                 :          0 :             !arg_count(cmd, corelog_ARG) && !arg_count(cmd, regionsize_ARG) &&
     805                 :          0 :             !arg_count(cmd, splitmirrors_ARG) && !repair) {
     806                 :          0 :                 *new_mimage_count = *old_mimage_count;
     807                 :          0 :                 *new_log_count = *old_log_count;
     808                 :            : 
     809 [ #  # ][ #  # ]:          0 :                 if (find_temporary_mirror(lv) || (lv->status & CONVERTING))
     810                 :          0 :                         lp->need_polling = 1;
     811                 :          0 :                 return 1;
     812                 :            :         }
     813                 :            : 
     814         [ #  # ]:          0 :         if ((arg_count(cmd, mirrors_ARG) && repair) ||
           [ #  #  #  # ]
           [ #  #  #  # ]
                 [ #  # ]
     815                 :          0 :             (arg_count(cmd, mirrorlog_ARG) && repair) ||
     816                 :          0 :             (arg_count(cmd, corelog_ARG) && repair)) {
     817                 :          0 :                 log_error("--repair cannot be used with --mirrors, --mirrorlog,"
     818                 :            :                           " or --corelog");
     819                 :          0 :                 return 0;
     820                 :            :         }
     821                 :            : 
     822 [ #  # ][ #  # ]:          0 :         if (arg_count(cmd, mirrorlog_ARG) && arg_count(cmd, corelog_ARG)) {
     823                 :          0 :                 log_error("--mirrorlog and --corelog are incompatible");
     824                 :          0 :                 return 0;
     825                 :            :         }
     826                 :            : 
     827                 :            :         /*
     828                 :            :          * Adjusting mimage count?
     829                 :            :          */
     830 [ #  # ][ #  # ]:          0 :         if (!arg_count(cmd, mirrors_ARG) && !arg_count(cmd, splitmirrors_ARG))
     831                 :          0 :                 lp->mirrors = *old_mimage_count;
     832         [ #  # ]:          0 :         else if (lp->mirrors_sign == SIGN_PLUS)
     833                 :          0 :                 lp->mirrors = *old_mimage_count + lp->mirrors;
     834         [ #  # ]:          0 :         else if (lp->mirrors_sign == SIGN_MINUS)
     835                 :          0 :                 lp->mirrors = *old_mimage_count - lp->mirrors;
     836                 :            :         else
     837                 :          0 :                 lp->mirrors += 1;
     838                 :            : 
     839                 :          0 :         *new_mimage_count = lp->mirrors;
     840                 :            : 
     841                 :            :         /* Too many mimages? */
     842         [ #  # ]:          0 :         if (lp->mirrors > DEFAULT_MIRROR_MAX_IMAGES) {
     843                 :          0 :                 log_error("Only up to %d images in mirror supported currently.",
     844                 :            :                           DEFAULT_MIRROR_MAX_IMAGES);
     845                 :          0 :                 return 0;
     846                 :            :         }
     847                 :            : 
     848                 :            :         /* Did the user try to subtract more legs than available? */
     849         [ #  # ]:          0 :         if (lp->mirrors < 1) {
     850                 :          0 :                 log_error("Logical volume %s only has %" PRIu32 " mirrors.",
     851                 :            :                           lv->name, *old_mimage_count);
     852                 :          0 :                 return 0;
     853                 :            :         }
     854                 :            : 
     855                 :            :         /*
     856                 :            :          * FIXME: It would be nice to say what we are adjusting to, but
     857                 :            :          * I really don't know whether to specify the # of copies or mimages.
     858                 :            :          */
     859         [ #  # ]:          0 :         if (*old_mimage_count != *new_mimage_count)
     860                 :          0 :                 log_verbose("Adjusting mirror image count of %s", lv->name);
     861                 :            : 
     862                 :            :         /*
     863                 :            :          * Adjust log type
     864                 :            :          *
     865                 :            :          * If we are converting from a mirror to another mirror or simply
     866                 :            :          * changing the log type, we start by assuming they want the log
     867                 :            :          * type the same and then parse the given args.  OTOH, If we are
     868                 :            :          * converting from linear to mirror, then we start from the default
     869                 :            :          * position that the user would like a 'disk' log.
     870                 :            :          */
     871         [ #  # ]:          0 :         *new_log_count = (*old_mimage_count > 1) ? *old_log_count : 1;
     872 [ #  # ][ #  # ]:          0 :         if (!arg_count(cmd, corelog_ARG) && !arg_count(cmd, mirrorlog_ARG))
     873                 :          0 :                 return 1;
     874                 :            : 
     875         [ #  # ]:          0 :         if (arg_count(cmd, corelog_ARG))
     876                 :          0 :                 *new_log_count = 0;
     877                 :            : 
     878         [ #  # ]:          0 :         mirrorlog = arg_str_value(cmd, mirrorlog_ARG,
     879                 :          0 :                                   !*new_log_count ? "core" : DEFAULT_MIRRORLOG);
     880                 :            : 
     881         [ #  # ]:          0 :         if (!strcmp("mirrored", mirrorlog))
     882                 :          0 :                 *new_log_count = 2;
     883         [ #  # ]:          0 :         else if (!strcmp("disk", mirrorlog))
     884                 :          0 :                 *new_log_count = 1;
     885         [ #  # ]:          0 :         else if (!strcmp("core", mirrorlog))
     886                 :          0 :                 *new_log_count = 0;
     887                 :            :         else {
     888                 :          0 :                 log_error("Unknown mirrorlog type: %s", mirrorlog);
     889                 :          0 :                 return 0;
     890                 :            :         }
     891                 :            : 
     892                 :          0 :         log_verbose("Setting logging type to %s", mirrorlog);
     893                 :            : 
     894                 :            :         /*
     895                 :            :          * Region size must not change on existing mirrors
     896                 :            :          */
     897 [ #  #  #  #  # :          0 :         if (arg_count(cmd, regionsize_ARG) && (lv->status & MIRRORED) &&
                      # ]
     898                 :          0 :             (lp->region_size != first_seg(lv)->region_size)) {
     899                 :          0 :                 log_error("Mirror log region size cannot be changed on "
     900                 :            :                           "an existing mirror.");
     901                 :          0 :                 return 0;
     902                 :            :         }
     903                 :            : 
     904                 :            :         /*
     905                 :            :          * For the most part, we cannot handle multi-segment mirrors. Bail out
     906                 :            :          * early if we have encountered one.
     907                 :            :          */
     908 [ #  # ][ #  # ]:          0 :         if ((lv->status & MIRRORED) && dm_list_size(&lv->segments) != 1) {
     909                 :          0 :                 log_error("Logical volume %s has multiple "
     910                 :            :                           "mirror segments.", lv->name);
     911                 :          0 :                 return 0;
     912                 :            :         }
     913                 :            : 
     914                 :          0 :         return 1;
     915                 :            : }
     916                 :            : 
     917                 :            : /*
     918                 :            :  * _lvconvert_mirrors_aux
     919                 :            :  *
     920                 :            :  * Add/remove mirror images and adjust log type.  'operable_pvs'
     921                 :            :  * are the set of PVs open to removal or allocation - depending
     922                 :            :  * on the operation being performed.
     923                 :            :  *
     924                 :            :  * If 'allocation_failures_ok' is set, and there is a failure to
     925                 :            :  * convert due to space, success will be returned.
     926                 :            :  */
     927                 :          0 : static int _lvconvert_mirrors_aux(struct cmd_context *cmd,
     928                 :            :                                   struct logical_volume *lv,
     929                 :            :                                   struct lvconvert_params *lp,
     930                 :            :                                   struct dm_list *operable_pvs,
     931                 :            :                                   uint32_t new_mimage_count,
     932                 :            :                                   uint32_t new_log_count,
     933                 :            :                                   int allocation_failures_ok)
     934                 :            : {
     935                 :            :         uint32_t region_size;
     936                 :            :         struct lv_segment *seg;
     937                 :            :         struct logical_volume *layer_lv;
     938                 :          0 :         uint32_t old_mimage_count = lv_mirror_count(lv);
     939                 :          0 :         uint32_t old_log_count = _get_log_count(lv);
     940                 :          0 :         int failure_code = (allocation_failures_ok) ? 1 : 0;
     941                 :            : 
     942   [ #  #  #  # ]:          0 :         if ((lp->mirrors == 1) && !(lv->status & MIRRORED)) {
     943                 :          0 :                 log_error("Logical volume %s is already not mirrored.",
     944                 :            :                           lv->name);
     945                 :          0 :                 return 1;
     946                 :            :         }
     947                 :            : 
     948                 :          0 :         region_size = adjusted_mirror_region_size(lv->vg->extent_size,
     949                 :            :                                                   lv->le_count,
     950                 :            :                                                   lp->region_size);
     951                 :            : 
     952         [ #  # ]:          0 :         if (!operable_pvs)
     953                 :          0 :                 operable_pvs = lp->pvh;
     954                 :            : 
     955                 :          0 :         seg = first_seg(lv);
     956                 :            : 
     957                 :            :         /*
     958                 :            :          * Up-convert from linear to mirror
     959                 :            :          */
     960         [ #  # ]:          0 :         if (!(lv->status & MIRRORED)) {
     961                 :            :                 /* FIXME Share code with lvcreate */
     962                 :            : 
     963                 :            :                 /*
     964                 :            :                  * FIXME should we give not only lp->pvh, but also all PVs
     965                 :            :                  * currently taken by the mirror? Would make more sense from
     966                 :            :                  * user perspective.
     967                 :            :                  */
     968         [ #  # ]:          0 :                 if (!lv_add_mirrors(cmd, lv, new_mimage_count - 1, lp->stripes,
     969                 :            :                                     lp->stripe_size, region_size, new_log_count, operable_pvs,
     970                 :            :                                     lp->alloc, MIRROR_BY_LV)) {
     971                 :          0 :                         stack;
     972                 :          0 :                         return failure_code;
     973                 :            :                 }
     974         [ #  # ]:          0 :                 if (lp->wait_completion)
     975                 :          0 :                         lp->need_polling = 1;
     976                 :            : 
     977                 :          0 :                 goto out;
     978                 :            :         }
     979                 :            : 
     980                 :            :         /*
     981                 :            :          * Up-convert m-way mirror to n-way mirror
     982                 :            :          */
     983         [ #  # ]:          0 :         if (new_mimage_count > old_mimage_count) {
     984         [ #  # ]:          0 :                 if (lv->status & MIRROR_NOTSYNCED) {
     985                 :          0 :                         log_error("Can't add mirror to out-of-sync mirrored "
     986                 :            :                                   "LV: use lvchange --resync first.");
     987                 :          0 :                         return 0;
     988                 :            :                 }
     989                 :            : 
     990                 :            :                 /*
     991                 :            :                  * We allow snapshots of mirrors, but for now, we
     992                 :            :                  * do not allow up converting mirrors that are under
     993                 :            :                  * snapshots.  The layering logic is somewhat complex,
     994                 :            :                  * and preliminary test show that the conversion can't
     995                 :            :                  * seem to get the correct %'age of completion.
     996                 :            :                  */
     997         [ #  # ]:          0 :                 if (lv_is_origin(lv)) {
     998                 :          0 :                         log_error("Can't add additional mirror images to "
     999                 :            :                                   "mirrors that are under snapshots");
    1000                 :          0 :                         return failure_code;
    1001                 :            :                 }
    1002                 :            : 
    1003                 :            :                 /*
    1004                 :            :                  * Log addition/removal should be done before the layer
    1005                 :            :                  * insertion to make the end result consistent with
    1006                 :            :                  * linear-to-mirror conversion.
    1007                 :            :                  */
    1008         [ #  # ]:          0 :                 if (!_lv_update_log_type(cmd, lp, lv,
    1009                 :            :                                          operable_pvs, new_log_count)) {
    1010                 :          0 :                         stack;
    1011                 :          0 :                         return failure_code;
    1012                 :            :                 }
    1013                 :            : 
    1014                 :            :                 /* Insert a temporary layer for syncing,
    1015                 :            :                  * only if the original lv is using disk log. */
    1016 [ #  # ][ #  # ]:          0 :                 if (seg->log_lv && !_insert_lvconvert_layer(cmd, lv)) {
    1017                 :          0 :                         log_error("Failed to insert resync layer");
    1018                 :          0 :                         return 0;
    1019                 :            :                 }
    1020                 :            : 
    1021                 :            :                 /* FIXME: can't have multiple mlogs. force corelog. */
    1022         [ #  # ]:          0 :                 if (!lv_add_mirrors(cmd, lv,
    1023                 :            :                                     new_mimage_count - old_mimage_count, lp->stripes, lp->stripe_size,
    1024                 :            :                                     region_size, 0U, operable_pvs, lp->alloc,
    1025                 :            :                                     MIRROR_BY_LV)) {
    1026                 :          0 :                         layer_lv = seg_lv(first_seg(lv), 0);
    1027 [ #  #  #  #  # :          0 :                         if (!remove_layer_from_lv(lv, layer_lv) ||
          #  #  #  #  #  
                   #  # ]
    1028         [ #  # ]:          0 :                             !deactivate_lv(cmd, layer_lv) ||
    1029                 :          0 :                             !lv_remove(layer_lv) || !vg_write(lv->vg) ||
    1030                 :          0 :                             !vg_commit(lv->vg)) {
    1031                 :          0 :                                 log_error("ABORTING: Failed to remove "
    1032                 :            :                                           "temporary mirror layer %s.",
    1033                 :            :                                           layer_lv->name);
    1034                 :          0 :                                 log_error("Manual cleanup with vgcfgrestore "
    1035                 :            :                                           "and dmsetup may be required.");
    1036                 :          0 :                                 return 0;
    1037                 :            :                         }
    1038                 :          0 :                         stack;
    1039                 :          0 :                         return failure_code;
    1040                 :            :                 }
    1041         [ #  # ]:          0 :                 if (seg->log_lv)
    1042                 :          0 :                         lv->status |= CONVERTING;
    1043                 :          0 :                 lp->need_polling = 1;
    1044                 :            : 
    1045                 :          0 :                 goto out_skip_log_convert;
    1046                 :            :         }
    1047                 :            : 
    1048                 :            :         /*
    1049                 :            :          * Down-convert (reduce # of mimages).
    1050                 :            :          */
    1051         [ #  # ]:          0 :         if (new_mimage_count < old_mimage_count) {
    1052                 :          0 :                 uint32_t nmc = old_mimage_count - new_mimage_count;
    1053 [ #  # ][ #  # ]:          0 :                 uint32_t nlc = (!new_log_count || lp->mirrors == 1) ? 1U : 0U;
    1054                 :            : 
    1055                 :            :                 /* FIXME: We did nlc used to be calculated that way? */
    1056                 :            : 
    1057                 :            :                 /* Reduce number of mirrors */
    1058         [ #  # ]:          0 :                 if (lp->keep_mimages) {
    1059         [ #  # ]:          0 :                         if (!lv_split_mirror_images(lv, lp->lv_split_name,
    1060                 :            :                                                     nmc, operable_pvs))
    1061                 :          0 :                                 return 0;
    1062         [ #  # ]:          0 :                 } else if (!lv_remove_mirrors(cmd, lv, nmc, nlc,
    1063                 :            :                                               operable_pvs, 0))
    1064                 :          0 :                         return_0;
    1065                 :            : 
    1066                 :            :                 goto out; /* Just in case someone puts code between */
    1067                 :            :         }
    1068                 :            : 
    1069                 :            : out:
    1070                 :            :         /*
    1071                 :            :          * Converting the log type
    1072                 :            :          */
    1073         [ #  # ]:          0 :         if (old_log_count != new_log_count) {
    1074         [ #  # ]:          0 :                 if (!_lv_update_log_type(cmd, lp, lv,
    1075                 :            :                                          operable_pvs, new_log_count)) {
    1076                 :          0 :                         stack;
    1077                 :          0 :                         return failure_code;
    1078                 :            :                 }
    1079                 :            :         }
    1080                 :            : 
    1081                 :            : out_skip_log_convert:
    1082                 :            : 
    1083                 :          0 :         log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
    1084                 :            : 
    1085         [ #  # ]:          0 :         if (!vg_write(lv->vg))
    1086                 :          0 :                 return_0;
    1087                 :            : 
    1088 [ #  # ][ #  # ]:          0 :         if (!suspend_lv(cmd, lv)) {
                 [ #  # ]
    1089                 :          0 :                 log_error("Failed to lock %s", lv->name);
    1090                 :          0 :                 vg_revert(lv->vg);
    1091                 :          0 :                 goto out;
    1092                 :            :         }
    1093                 :            : 
    1094         [ #  # ]:          0 :         if (!vg_commit(lv->vg)) {
    1095 [ #  # ][ #  # ]:          0 :                 if (!resume_lv(cmd, lv))
                 [ #  # ]
    1096                 :          0 :                         stack;
    1097                 :          0 :                 goto_out;
    1098                 :            :         }
    1099                 :            : 
    1100                 :          0 :         log_very_verbose("Updating \"%s\" in kernel", lv->name);
    1101                 :            : 
    1102   [ #  #  #  # ]:          0 :         if (!resume_lv(cmd, lv)) {
                 [ #  # ]
    1103                 :          0 :                 log_error("Problem reactivating %s", lv->name);
    1104                 :          0 :                 goto out;
    1105                 :            :         }
    1106                 :            : 
    1107                 :          0 :         return 1;
    1108                 :            : }
    1109                 :            : 
    1110                 :            : /*
    1111                 :            :  * _lvconvert_mirrors_repair
    1112                 :            :  *
    1113                 :            :  * This function operates in two phases.  First, all of the bad
    1114                 :            :  * devices are removed from the mirror.  Then, if desired by the
    1115                 :            :  * user, the devices are replaced.
    1116                 :            :  *
    1117                 :            :  * 'old_mimage_count' and 'old_log_count' are there so we know
    1118                 :            :  * what to convert to after the removal of devices.
    1119                 :            :  */
    1120                 :          0 : static int _lvconvert_mirrors_repair(struct cmd_context *cmd,
    1121                 :            :                                      struct logical_volume *lv,
    1122                 :            :                                      struct lvconvert_params *lp,
    1123                 :            :                                      uint32_t old_mimage_count,
    1124                 :            :                                      uint32_t old_log_count)
    1125                 :            : {
    1126                 :          0 :         int failed_log = 0;
    1127                 :          0 :         int failed_mirrors = 0;
    1128                 :          0 :         int replace_log = 0;
    1129                 :          0 :         int replace_mirrors = 0;
    1130                 :            :         uint32_t new_log_count;
    1131                 :          0 :         struct dm_list *failed_pvs = NULL;
    1132                 :            :         struct logical_volume *log_lv;
    1133                 :            : 
    1134                 :          0 :         cmd->handles_missing_pvs = 1;
    1135                 :          0 :         cmd->partial_activation = 1;
    1136                 :          0 :         lp->need_polling = 0;
    1137                 :            : 
    1138         [ #  # ]:          0 :         if (!(lv->status & PARTIAL_LV)) {
    1139                 :          0 :                 log_error("%s is consistent. Nothing to repair.", lv->name);
    1140                 :          0 :                 return 1;
    1141                 :            :         }
    1142                 :            : 
    1143                 :            :         /*
    1144                 :            :          * Count the failed mimages - negative if 'lv' is not a mirror
    1145                 :            :          */
    1146         [ #  # ]:          0 :         if ((failed_mirrors = _failed_mirrors_count(lv)) < 0)
    1147                 :          0 :                 return_0;
    1148                 :            : 
    1149                 :          0 :         lp->mirrors = old_mimage_count - failed_mirrors;
    1150                 :            : 
    1151         [ #  # ]:          0 :         if (lp->mirrors != old_mimage_count)
    1152                 :          0 :                 log_error("Mirror status: %d of %d images failed.",
    1153                 :            :                           failed_mirrors, old_mimage_count);
    1154                 :            : 
    1155                 :            :         /*
    1156                 :            :          * Count the failed log devices
    1157                 :            :          */
    1158                 :          0 :         new_log_count = old_log_count;
    1159                 :          0 :         log_lv = first_seg(lv)->log_lv;
    1160         [ #  # ]:          0 :         if (log_lv) {
    1161                 :          0 :                 new_log_count = lv_mirror_count(log_lv);
    1162         [ #  # ]:          0 :                 if (log_lv->status & PARTIAL_LV) {
    1163                 :          0 :                         failed_log = 1;
    1164         [ #  # ]:          0 :                         if (log_lv->status & MIRRORED)
    1165                 :          0 :                                 new_log_count -= _failed_mirrors_count(log_lv);
    1166                 :            :                         else
    1167                 :          0 :                                 new_log_count = 0;
    1168                 :            :                 }
    1169                 :            :         }
    1170         [ #  # ]:          0 :         if (old_log_count != new_log_count)
    1171         [ #  # ]:          0 :                 log_error("Mirror log status: %d of %d images failed%s",
    1172                 :            :                           old_log_count - new_log_count, old_log_count,
    1173                 :            :                           (!new_log_count) ? " - switching to core" : "");
    1174                 :            : 
    1175                 :            :         /*
    1176                 :            :          * Find out our policies
    1177                 :            :          */
    1178                 :          0 :         _lvconvert_mirrors_repair_ask(cmd, failed_log, failed_mirrors,
    1179                 :            :                                       &replace_log, &replace_mirrors);
    1180                 :            : 
    1181                 :            :         /*
    1182                 :            :          * First phase - remove faulty devices
    1183                 :            :          */
    1184         [ #  # ]:          0 :         if (!(failed_pvs = _failed_pv_list(lv->vg)))
    1185                 :          0 :                 return_0;
    1186                 :            : 
    1187                 :            :         /*
    1188                 :            :          * We must adjust the log first, or the entire mirror
    1189                 :            :          * will get stuck during a suspend.
    1190                 :            :          */
    1191         [ #  # ]:          0 :         if (!_lv_update_log_type(cmd, lp, lv, failed_pvs, new_log_count))
    1192                 :          0 :                 return 0;
    1193                 :            : 
    1194         [ #  # ]:          0 :         if (!_lvconvert_mirrors_aux(cmd, lv, lp, failed_pvs,
    1195                 :            :                                     lp->mirrors, new_log_count, 0))
    1196                 :          0 :                 return 0;
    1197                 :            : 
    1198                 :            :         /*
    1199                 :            :          * Second phase - replace faulty devices
    1200                 :            :          *
    1201                 :            :          * FIXME: It would be nice to do this all in one step, but
    1202                 :            :          *        for simplicity, we replace mimages first and then
    1203                 :            :          *        work on the log.
    1204                 :            :          */
    1205 [ #  # ][ #  # ]:          0 :         if (replace_mirrors && (old_mimage_count != lp->mirrors)) {
    1206                 :          0 :                 lp->mirrors = old_mimage_count;
    1207         [ #  # ]:          0 :                 if (!_lvconvert_mirrors_aux(cmd, lv, lp, NULL,
    1208                 :            :                                             old_mimage_count, new_log_count, 1))
    1209                 :          0 :                         return 0;
    1210                 :            :         }
    1211                 :            : 
    1212                 :          0 :         log_lv = first_seg(lv)->log_lv;
    1213   [ #  #  #  # ]:          0 :         if (replace_log && (old_log_count != new_log_count)) {
    1214                 :            :                 /*
    1215                 :            :                  * If we are up-converting the log from linear to
    1216                 :            :                  * mirrored, then we must use '_lvconvert_mirrors_aux'
    1217                 :            :                  */
    1218 [ #  # ][ #  # ]:          0 :                 if ((new_log_count == 1) && (old_log_count > 1)) {
    1219         [ #  # ]:          0 :                         if (!_lvconvert_mirrors_aux(cmd, log_lv, lp, NULL,
    1220                 :            :                                                     old_log_count, 0, 1))
    1221                 :          0 :                                 return 0;
    1222         [ #  # ]:          0 :                 } else if (!_lv_update_log_type(cmd, lp, lv,
    1223                 :            :                                                 lp->pvh, new_log_count))
    1224                 :          0 :                         return 0;
    1225                 :            :         }
    1226                 :            : 
    1227                 :          0 :         return 1;
    1228                 :            : }
    1229                 :            : 
    1230                 :            : /*
    1231                 :            :  * _lvconvert_mirrors
    1232                 :            :  *
    1233                 :            :  * Determine what is being done.  Are we doing a conversion, repair, or
    1234                 :            :  * collapsing a stack?  Once determined, call helper functions.
    1235                 :            :  */
    1236                 :          0 : static int _lvconvert_mirrors(struct cmd_context *cmd,
    1237                 :            :                               struct logical_volume *lv,
    1238                 :            :                               struct lvconvert_params *lp)
    1239                 :            : {
    1240                 :          0 :         int repair = arg_count(cmd, repair_ARG);
    1241                 :            :         uint32_t old_mimage_count;
    1242                 :            :         uint32_t old_log_count;
    1243                 :            :         uint32_t new_mimage_count;
    1244                 :            :         uint32_t new_log_count;
    1245                 :            : 
    1246                 :            :         /* Adjust mimage and/or log count */
    1247         [ #  # ]:          0 :         if (!_lvconvert_mirrors_parse_params(cmd, lv, lp,
    1248                 :            :                                              &old_mimage_count, &old_log_count,
    1249                 :            :                                              &new_mimage_count, &new_log_count))
    1250                 :          0 :                 return 0;
    1251                 :            : 
    1252                 :            :         /* Nothing to do?  (Probably finishing collapse.) */
    1253 [ #  # ][ #  # ]:          0 :         if ((old_mimage_count == new_mimage_count) &&
                 [ #  # ]
    1254                 :          0 :             (old_log_count == new_log_count) && !repair)
    1255                 :          0 :                 return 1;
    1256                 :            : 
    1257         [ #  # ]:          0 :         if (repair)
    1258                 :          0 :                 return _lvconvert_mirrors_repair(cmd, lv, lp,
    1259                 :            :                                                  old_mimage_count,
    1260                 :            :                                                  old_log_count);
    1261                 :            : 
    1262         [ #  # ]:          0 :         if (!_lvconvert_mirrors_aux(cmd, lv, lp, NULL,
    1263                 :            :                                     new_mimage_count, new_log_count, 0))
    1264                 :          0 :                 return 0;
    1265                 :            : 
    1266         [ #  # ]:          0 :         if (!lp->need_polling)
    1267                 :          0 :                 log_print("Logical volume %s converted.", lv->name);
    1268                 :            : 
    1269                 :          0 :         backup(lv->vg);
    1270                 :          0 :         return 1;
    1271                 :            : }
    1272                 :            : 
    1273                 :          0 : static int lvconvert_snapshot(struct cmd_context *cmd,
    1274                 :            :                               struct logical_volume *lv,
    1275                 :            :                               struct lvconvert_params *lp)
    1276                 :            : {
    1277                 :            :         struct logical_volume *org;
    1278                 :          0 :         int r = 0;
    1279                 :            : 
    1280         [ #  # ]:          0 :         if (!(org = find_lv(lv->vg, lp->origin))) {
    1281                 :          0 :                 log_error("Couldn't find origin volume '%s'.", lp->origin);
    1282                 :          0 :                 return 0;
    1283                 :            :         }
    1284                 :            : 
    1285         [ #  # ]:          0 :         if (org == lv) {
    1286                 :          0 :                 log_error("Unable to use \"%s\" as both snapshot and origin.",
    1287                 :            :                           lv->name);
    1288                 :          0 :                 return 0;
    1289                 :            :         }
    1290                 :            : 
    1291 [ #  # ][ #  # ]:          0 :         if (org->status & (LOCKED|PVMOVE|MIRRORED) || lv_is_cow(org)) {
    1292 [ #  # ][ #  # ]:          0 :                 log_error("Unable to create a snapshot of a %s LV.",
                 [ #  # ]
    1293                 :            :                           org->status & LOCKED ? "locked" :
    1294                 :            :                           org->status & PVMOVE ? "pvmove" :
    1295                 :            :                           org->status & MIRRORED ? "mirrored" :
    1296                 :            :                           "snapshot");
    1297                 :          0 :                 return 0;
    1298                 :            :         }
    1299                 :            : 
    1300 [ #  # ][ #  # ]:          0 :         if (!lp->zero || !(lv->status & LVM_WRITE))
    1301                 :          0 :                 log_warn("WARNING: \"%s\" not zeroed", lv->name);
    1302         [ #  # ]:          0 :         else if (!set_lv(cmd, lv, UINT64_C(0), 0)) {
    1303                 :          0 :                 log_error("Aborting. Failed to wipe snapshot "
    1304                 :            :                           "exception store.");
    1305                 :          0 :                 return 0;
    1306                 :            :         }
    1307                 :            : 
    1308 [ #  # ][ #  # ]:          0 :         if (!deactivate_lv(cmd, lv)) {
                 [ #  # ]
    1309                 :          0 :                 log_error("Couldn't deactivate LV %s.", lv->name);
    1310                 :          0 :                 return 0;
    1311                 :            :         }
    1312                 :            : 
    1313         [ #  # ]:          0 :         if (!vg_add_snapshot(org, lv, NULL, org->le_count, lp->chunk_size)) {
    1314                 :          0 :                 log_error("Couldn't create snapshot.");
    1315                 :          0 :                 return 0;
    1316                 :            :         }
    1317                 :            : 
    1318                 :            :         /* store vg on disk(s) */
    1319         [ #  # ]:          0 :         if (!vg_write(lv->vg))
    1320                 :          0 :                 return_0;
    1321                 :            : 
    1322 [ #  # ][ #  # ]:          0 :         if (!suspend_lv(cmd, org)) {
                 [ #  # ]
    1323                 :          0 :                 log_error("Failed to suspend origin %s", org->name);
    1324                 :          0 :                 vg_revert(lv->vg);
    1325                 :          0 :                 goto out;
    1326                 :            :         }
    1327                 :            : 
    1328         [ #  # ]:          0 :         if (!vg_commit(lv->vg))
    1329                 :          0 :                 goto_out;
    1330                 :            : 
    1331 [ #  # ][ #  # ]:          0 :         if (!resume_lv(cmd, org)) {
                 [ #  # ]
    1332                 :          0 :                 log_error("Problem reactivating origin %s", org->name);
    1333                 :          0 :                 goto out;
    1334                 :            :         }
    1335                 :            : 
    1336                 :          0 :         log_print("Logical volume %s converted to snapshot.", lv->name);
    1337                 :          0 :         r = 1;
    1338                 :            : out:
    1339                 :          0 :         backup(lv->vg);
    1340                 :          0 :         return r;
    1341                 :            : }
    1342                 :            : 
    1343                 :          0 : static int lvconvert_merge(struct cmd_context *cmd,
    1344                 :            :                            struct logical_volume *lv,
    1345                 :            :                            struct lvconvert_params *lp)
    1346                 :            : {
    1347                 :          0 :         int r = 0;
    1348                 :          0 :         int merge_on_activate = 0;
    1349                 :          0 :         struct logical_volume *origin = origin_from_cow(lv);
    1350                 :          0 :         struct lv_segment *cow_seg = find_cow(lv);
    1351                 :            :         struct lvinfo info;
    1352                 :            : 
    1353                 :            :         /* Check if merge is possible */
    1354         [ #  # ]:          0 :         if (lv_is_merging_cow(lv)) {
    1355                 :          0 :                 log_error("Snapshot %s is already merging", lv->name);
    1356                 :          0 :                 return 0;
    1357                 :            :         }
    1358         [ #  # ]:          0 :         if (lv_is_merging_origin(origin)) {
    1359                 :          0 :                 log_error("Snapshot %s is already merging into the origin",
    1360                 :            :                           find_merging_cow(origin)->cow->name);
    1361                 :          0 :                 return 0;
    1362                 :            :         }
    1363                 :            : 
    1364                 :            :         /*
    1365                 :            :          * Prevent merge with open device(s) as it would likely lead
    1366                 :            :          * to application/filesystem failure.  Merge on origin's next
    1367                 :            :          * activation if either the origin or snapshot LV are currently
    1368                 :            :          * open.
    1369                 :            :          *
    1370                 :            :          * FIXME testing open_count is racey; snapshot-merge target's
    1371                 :            :          * constructor and DM should prevent appropriate devices from
    1372                 :            :          * being open.
    1373                 :            :          */
    1374         [ #  # ]:          0 :         if (lv_info(cmd, origin, &info, 1, 0)) {
    1375         [ #  # ]:          0 :                 if (info.open_count) {
    1376                 :          0 :                         log_error("Can't merge over open origin volume");
    1377                 :          0 :                         merge_on_activate = 1;
    1378                 :            :                 }
    1379                 :            :         }
    1380         [ #  # ]:          0 :         if (lv_info(cmd, lv, &info, 1, 0)) {
    1381         [ #  # ]:          0 :                 if (info.open_count) {
    1382                 :          0 :                         log_print("Can't merge when snapshot is open");
    1383                 :          0 :                         merge_on_activate = 1;
    1384                 :            :                 }
    1385                 :            :         }
    1386                 :            : 
    1387                 :          0 :         init_snapshot_merge(cow_seg, origin);
    1388                 :            : 
    1389                 :            :         /* store vg on disk(s) */
    1390         [ #  # ]:          0 :         if (!vg_write(lv->vg))
    1391                 :          0 :                 return_0;
    1392                 :            : 
    1393         [ #  # ]:          0 :         if (merge_on_activate) {
    1394                 :            :                 /* commit vg but skip starting the merge */
    1395         [ #  # ]:          0 :                 if (!vg_commit(lv->vg))
    1396                 :          0 :                         return_0;
    1397                 :          0 :                 r = 1;
    1398                 :          0 :                 log_print("Merging of snapshot %s will start "
    1399                 :            :                           "next activation.", lv->name);
    1400                 :          0 :                 goto out;
    1401                 :            :         }
    1402                 :            : 
    1403                 :            :         /* Perform merge */
    1404 [ #  # ][ #  # ]:          0 :         if (!suspend_lv(cmd, origin)) {
                 [ #  # ]
    1405                 :          0 :                 log_error("Failed to suspend origin %s", origin->name);
    1406                 :          0 :                 vg_revert(lv->vg);
    1407                 :          0 :                 goto out;
    1408                 :            :         }
    1409                 :            : 
    1410         [ #  # ]:          0 :         if (!vg_commit(lv->vg)) {
    1411 [ #  # ][ #  # ]:          0 :                 if (!resume_lv(cmd, origin))
                 [ #  # ]
    1412                 :          0 :                         stack;
    1413                 :          0 :                 goto_out;
    1414                 :            :         }
    1415                 :            : 
    1416 [ #  # ][ #  # ]:          0 :         if (!resume_lv(cmd, origin)) {
                 [ #  # ]
    1417                 :          0 :                 log_error("Failed to reactivate origin %s", origin->name);
    1418                 :          0 :                 goto out;
    1419                 :            :         }
    1420                 :            : 
    1421                 :          0 :         lp->need_polling = 1;
    1422                 :          0 :         lp->lv_to_poll = origin;
    1423                 :            : 
    1424                 :          0 :         r = 1;
    1425                 :          0 :         log_print("Merging of volume %s started.", lv->name);
    1426                 :            : out:
    1427                 :          0 :         backup(lv->vg);
    1428                 :          0 :         return r;
    1429                 :            : }
    1430                 :            : 
    1431                 :          0 : static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
    1432                 :            :                              void *handle)
    1433                 :            : {
    1434                 :          0 :         struct lvconvert_params *lp = handle;
    1435                 :            : 
    1436         [ #  # ]:          0 :         if (lv->status & LOCKED) {
    1437                 :          0 :                 log_error("Cannot convert locked LV %s", lv->name);
    1438                 :          0 :                 return ECMD_FAILED;
    1439                 :            :         }
    1440                 :            : 
    1441 [ #  # ][ #  # ]:          0 :         if (lv_is_cow(lv) && !lp->merge) {
    1442                 :          0 :                 log_error("Can't convert snapshot logical volume \"%s\"",
    1443                 :            :                           lv->name);
    1444                 :          0 :                 return ECMD_FAILED;
    1445                 :            :         }
    1446                 :            : 
    1447         [ #  # ]:          0 :         if (lv->status & PVMOVE) {
    1448                 :          0 :                 log_error("Unable to convert pvmove LV %s", lv->name);
    1449                 :          0 :                 return ECMD_FAILED;
    1450                 :            :         }
    1451                 :            : 
    1452 [ #  # ][ #  # ]:          0 :         if (arg_count(cmd, repair_ARG) && !(lv->status & MIRRORED)) {
    1453         [ #  # ]:          0 :                 if (arg_count(cmd, use_policies_ARG))
    1454                 :          0 :                         return ECMD_PROCESSED; /* nothing to be done here */
    1455                 :          0 :                 log_error("Can't repair non-mirrored LV \"%s\".", lv->name);
    1456                 :          0 :                 return ECMD_FAILED;
    1457                 :            :         }
    1458                 :            : 
    1459         [ #  # ]:          0 :         if (lp->merge) {
    1460         [ #  # ]:          0 :                 if (!lv_is_cow(lv)) {
    1461                 :          0 :                         log_error("Logical volume \"%s\" is not a snapshot",
    1462                 :            :                                   lv->name);
    1463                 :          0 :                         return ECMD_FAILED;
    1464                 :            :                 }
    1465         [ #  # ]:          0 :                 if (!archive(lv->vg)) {
    1466                 :          0 :                         stack;
    1467                 :          0 :                         return ECMD_FAILED;
    1468                 :            :                 }
    1469         [ #  # ]:          0 :                 if (!lvconvert_merge(cmd, lv, lp)) {
    1470                 :          0 :                         stack;
    1471                 :          0 :                         return ECMD_FAILED;
    1472                 :            :                 }
    1473         [ #  # ]:          0 :         } else if (lp->snapshot) {
    1474         [ #  # ]:          0 :                 if (lv->status & MIRRORED) {
    1475                 :          0 :                         log_error("Unable to convert mirrored LV \"%s\" into a snapshot.", lv->name);
    1476                 :          0 :                         return ECMD_FAILED;
    1477                 :            :                 }
    1478         [ #  # ]:          0 :                 if (!archive(lv->vg)) {
    1479                 :          0 :                         stack;
    1480                 :          0 :                         return ECMD_FAILED;
    1481                 :            :                 }
    1482         [ #  # ]:          0 :                 if (!lvconvert_snapshot(cmd, lv, lp)) {
    1483                 :          0 :                         stack;
    1484                 :          0 :                         return ECMD_FAILED;
    1485                 :            :                 }
    1486 [ #  # ][ #  # ]:          0 :         } else if (arg_count(cmd, mirrors_ARG) || (lv->status & MIRRORED)) {
    1487         [ #  # ]:          0 :                 if (!archive(lv->vg)) {
    1488                 :          0 :                         stack;
    1489                 :          0 :                         return ECMD_FAILED;
    1490                 :            :                 }
    1491         [ #  # ]:          0 :                 if (!_lvconvert_mirrors(cmd, lv, lp)) {
    1492                 :          0 :                         stack;
    1493                 :          0 :                         return ECMD_FAILED;
    1494                 :            :                 }
    1495                 :            : 
    1496                 :            :                 /* If repairing and using policies, remove missing PVs from VG */
    1497 [ #  # ][ #  # ]:          0 :                 if (arg_count(cmd, repair_ARG) && arg_count(cmd, use_policies_ARG))
    1498                 :          0 :                         _remove_missing_empty_pv(lv->vg, lp->failed_pvs);
    1499                 :            :         }
    1500                 :            : 
    1501                 :          0 :         return ECMD_PROCESSED;
    1502                 :            : }
    1503                 :            : 
    1504                 :            : /*
    1505                 :            :  * FIXME move to toollib along with the rest of the drop/reacquire
    1506                 :            :  * VG locking that is used by lvconvert_merge_single()
    1507                 :            :  */
    1508                 :          0 : static struct logical_volume *get_vg_lock_and_logical_volume(struct cmd_context *cmd,
    1509                 :            :                                                              const char *vg_name,
    1510                 :            :                                                              const char *lv_name)
    1511                 :            : {
    1512                 :            :         /*
    1513                 :            :          * Returns NULL if the requested LV doesn't exist;
    1514                 :            :          * otherwise the caller must vg_release(lv->vg)
    1515                 :            :          * - it is also up to the caller to unlock_vg() as needed
    1516                 :            :          */
    1517                 :            :         struct volume_group *vg;
    1518                 :          0 :         struct logical_volume* lv = NULL;
    1519                 :            : 
    1520                 :          0 :         vg = _get_lvconvert_vg(cmd, vg_name, NULL);
    1521         [ #  # ]:          0 :         if (vg_read_error(vg)) {
    1522                 :          0 :                 vg_release(vg);
    1523                 :          0 :                 log_error("ABORTING: Can't reread VG for %s", vg_name);
    1524                 :          0 :                 return NULL;
    1525                 :            :         }
    1526                 :            : 
    1527         [ #  # ]:          0 :         if (!(lv = _get_lvconvert_lv(cmd, vg, lv_name, NULL, 0))) {
    1528                 :          0 :                 log_error("ABORTING: Can't find LV %s in VG %s", lv_name, vg_name);
    1529                 :          0 :                 unlock_and_release_vg(cmd, vg, vg_name);
    1530                 :          0 :                 return NULL;
    1531                 :            :         }
    1532                 :            : 
    1533                 :          0 :         return lv;
    1534                 :            : }
    1535                 :            : 
    1536                 :          0 : static int poll_logical_volume(struct cmd_context *cmd, struct logical_volume *lv,
    1537                 :            :                                int wait_completion)
    1538                 :            : {
    1539                 :            :         struct lvinfo info;
    1540                 :            : 
    1541 [ #  # ][ #  # ]:          0 :         if (!lv_info(cmd, lv, &info, 1, 0) || !info.exists) {
    1542                 :          0 :                 log_print("Conversion starts after activation.");
    1543                 :          0 :                 return ECMD_PROCESSED;
    1544                 :            :         }
    1545                 :          0 :         return lvconvert_poll(cmd, lv, wait_completion ? 0 : 1U);
    1546                 :            : }
    1547                 :            : 
    1548                 :          0 : static int lvconvert_single(struct cmd_context *cmd, struct lvconvert_params *lp)
    1549                 :            : {
    1550                 :          0 :         struct logical_volume *lv = NULL;
    1551                 :          0 :         int ret = ECMD_FAILED;
    1552                 :          0 :         int saved_ignore_suspended_devices = ignore_suspended_devices();
    1553                 :            : 
    1554         [ #  # ]:          0 :         if (arg_count(cmd, repair_ARG)) {
    1555                 :          0 :                 init_ignore_suspended_devices(1);
    1556                 :          0 :                 cmd->handles_missing_pvs = 1;
    1557                 :            :         }
    1558                 :            : 
    1559                 :          0 :         lv = get_vg_lock_and_logical_volume(cmd, lp->vg_name, lp->lv_name);
    1560         [ #  # ]:          0 :         if (!lv)
    1561                 :          0 :                 goto_out;
    1562                 :            : 
    1563         [ #  # ]:          0 :         if (lp->pv_count) {
    1564         [ #  # ]:          0 :                 if (!(lp->pvh = create_pv_list(cmd->mem, lv->vg, lp->pv_count,
    1565                 :            :                                               lp->pvs, 0)))
    1566                 :          0 :                         goto_bad;
    1567                 :            :         } else
    1568                 :          0 :                 lp->pvh = &lv->vg->pvs;
    1569                 :            : 
    1570                 :          0 :         lp->lv_to_poll = lv;
    1571                 :          0 :         ret = _lvconvert_single(cmd, lv, lp);
    1572                 :            : bad:
    1573                 :          0 :         unlock_vg(cmd, lp->vg_name);
    1574                 :            : 
    1575   [ #  #  #  # ]:          0 :         if (ret == ECMD_PROCESSED && lp->need_polling)
    1576                 :          0 :                 ret = poll_logical_volume(cmd, lp->lv_to_poll,
    1577                 :            :                                           lp->wait_completion);
    1578                 :            : 
    1579                 :          0 :         vg_release(lv->vg);
    1580                 :            : out:
    1581                 :          0 :         init_ignore_suspended_devices(saved_ignore_suspended_devices);
    1582                 :          0 :         return ret;
    1583                 :            : }
    1584                 :            : 
    1585                 :          0 : static int lvconvert_merge_single(struct cmd_context *cmd, struct logical_volume *lv,
    1586                 :            :                                   void *handle)
    1587                 :            : {
    1588                 :          0 :         struct lvconvert_params *lp = handle;
    1589                 :          0 :         const char *vg_name = NULL;
    1590                 :          0 :         struct logical_volume *refreshed_lv = NULL;
    1591                 :            :         int ret;
    1592                 :            : 
    1593                 :            :         /*
    1594                 :            :          * FIXME can't trust lv's VG to be current given that caller
    1595                 :            :          * is process_each_lv() -- poll_logical_volume() may have
    1596                 :            :          * already updated the VG's metadata in an earlier iteration.
    1597                 :            :          * - preemptively drop the VG lock, as is needed for
    1598                 :            :          *   poll_logical_volume(), refresh LV (and VG in the process).
    1599                 :            :          */
    1600                 :          0 :         vg_name = lv->vg->name;
    1601                 :          0 :         unlock_vg(cmd, vg_name);
    1602                 :          0 :         refreshed_lv = get_vg_lock_and_logical_volume(cmd, vg_name, lv->name);
    1603         [ #  # ]:          0 :         if (!refreshed_lv)
    1604                 :          0 :                 return ECMD_FAILED;
    1605                 :            : 
    1606                 :          0 :         lp->lv_to_poll = refreshed_lv;
    1607                 :          0 :         ret = _lvconvert_single(cmd, refreshed_lv, lp);
    1608                 :            : 
    1609   [ #  #  #  # ]:          0 :         if (ret == ECMD_PROCESSED && lp->need_polling) {
    1610                 :            :                 /*
    1611                 :            :                  * Must drop VG lock, because lvconvert_poll() needs it,
    1612                 :            :                  * then reacquire it after polling completes
    1613                 :            :                  */
    1614                 :          0 :                 unlock_vg(cmd, vg_name);
    1615                 :            : 
    1616                 :          0 :                 ret = poll_logical_volume(cmd, lp->lv_to_poll,
    1617                 :            :                                           lp->wait_completion);
    1618                 :            : 
    1619                 :            :                 /* use LCK_VG_WRITE to match lvconvert()'s READ_FOR_UPDATE */
    1620         [ #  # ]:          0 :                 if (!lock_vol(cmd, vg_name, LCK_VG_WRITE)) {
    1621                 :          0 :                         log_error("ABORTING: Can't relock VG for %s "
    1622                 :            :                                   "after polling finished", vg_name);
    1623                 :          0 :                         ret = ECMD_FAILED;
    1624                 :            :                 }
    1625                 :            :         }
    1626                 :            : 
    1627                 :          0 :         vg_release(refreshed_lv->vg);
    1628                 :            : 
    1629                 :          0 :         return ret;
    1630                 :            : }
    1631                 :            : 
    1632                 :          0 : int lvconvert(struct cmd_context * cmd, int argc, char **argv)
    1633                 :            : {
    1634                 :            :         struct lvconvert_params lp;
    1635                 :            : 
    1636         [ #  # ]:          0 :         if (!_read_params(&lp, cmd, argc, argv)) {
    1637                 :          0 :                 stack;
    1638                 :          0 :                 return EINVALID_CMD_LINE;
    1639                 :            :         }
    1640                 :            : 
    1641         [ #  # ]:          0 :         if (lp.merge)
    1642                 :          0 :                 return process_each_lv(cmd, argc, argv, READ_FOR_UPDATE, &lp,
    1643                 :            :                                        &lvconvert_merge_single);
    1644                 :            : 
    1645                 :          0 :         return lvconvert_single(cmd, &lp);
    1646                 :            : }

Generated by: LCOV version 1.8