LCOV - code coverage report
Current view: top level - misc/kabi/lvm2.git/lib/metadata - mirror.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 0 792 0.0 %
Date: 2010-04-13 Functions: 0 43 0.0 %
Branches: 0 684 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
       3                 :            :  * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
       4                 :            :  *
       5                 :            :  * This file is part of LVM2.
       6                 :            :  *
       7                 :            :  * This copyrighted material is made available to anyone wishing to use,
       8                 :            :  * modify, copy, or redistribute it subject to the terms and conditions
       9                 :            :  * of the GNU Lesser General Public License v.2.1.
      10                 :            :  *
      11                 :            :  * You should have received a copy of the GNU Lesser General Public License
      12                 :            :  * along with this program; if not, write to the Free Software Foundation,
      13                 :            :  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "lib.h"
      17                 :            : #include "metadata.h"
      18                 :            : #include "toolcontext.h"
      19                 :            : #include "segtype.h"
      20                 :            : #include "display.h"
      21                 :            : #include "archiver.h"
      22                 :            : #include "activate.h"
      23                 :            : #include "lv_alloc.h"
      24                 :            : #include "lvm-string.h"
      25                 :            : #include "str_list.h"
      26                 :            : #include "locking.h"  /* FIXME Should not be used in this file */
      27                 :            : #include "memlock.h"
      28                 :            : 
      29                 :            : #include "defaults.h" /* FIXME: should this be defaults.h? */
      30                 :            : 
      31                 :            : /* These are necessary for _write_log_header() */
      32                 :            : #include "xlate.h"
      33                 :            : #define MIRROR_MAGIC 0x4D695272
      34                 :            : #define MIRROR_DISK_VERSION 2
      35                 :            : 
      36                 :            : /* These are the flags that represent the mirror failure restoration policies */
      37                 :            : #define MIRROR_REMOVE            0
      38                 :            : #define MIRROR_ALLOCATE          1
      39                 :            : #define MIRROR_ALLOCATE_ANYWHERE 2
      40                 :            : 
      41                 :            : /*
      42                 :            :  * Returns true if the lv is temporary mirror layer for resync
      43                 :            :  */
      44                 :          0 : int is_temporary_mirror_layer(const struct logical_volume *lv)
      45                 :            : {
      46 [ #  # ][ #  # ]:          0 :         if (lv->status & MIRROR_IMAGE
                 [ #  # ]
      47                 :          0 :             && lv->status & MIRRORED
      48                 :          0 :             && !(lv->status & LOCKED))
      49                 :          0 :                 return 1;
      50                 :            : 
      51                 :          0 :         return 0;
      52                 :            : }
      53                 :            : 
      54                 :            : /*
      55                 :            :  * Return a temporary LV for resyncing added mirror image.
      56                 :            :  * Add other mirror legs to lvs list.
      57                 :            :  */
      58                 :          0 : struct logical_volume *find_temporary_mirror(const struct logical_volume *lv)
      59                 :            : {
      60                 :            :         struct lv_segment *seg;
      61                 :            : 
      62         [ #  # ]:          0 :         if (!(lv->status & MIRRORED))
      63                 :          0 :                 return NULL;
      64                 :            : 
      65                 :          0 :         seg = first_seg(lv);
      66                 :            : 
      67                 :            :         /* Temporary mirror is always area_num == 0 */
      68   [ #  #  #  # ]:          0 :         if (seg_type(seg, 0) == AREA_LV &&
      69                 :          0 :             is_temporary_mirror_layer(seg_lv(seg, 0)))
      70                 :          0 :                 return seg_lv(seg, 0);
      71                 :            : 
      72                 :          0 :         return NULL;
      73                 :            : }
      74                 :            : 
      75                 :            : /*
      76                 :            :  * Returns the number of mirrors of the LV
      77                 :            :  */
      78                 :          0 : uint32_t lv_mirror_count(const struct logical_volume *lv)
      79                 :            : {
      80                 :            :         struct lv_segment *seg;
      81                 :            :         uint32_t s, mirrors;
      82                 :            : 
      83         [ #  # ]:          0 :         if (!(lv->status & MIRRORED))
      84                 :          0 :                 return 1;
      85                 :            : 
      86                 :          0 :         seg = first_seg(lv);
      87                 :          0 :         mirrors = seg->area_count;
      88                 :            : 
      89         [ #  # ]:          0 :         for (s = 0; s < seg->area_count; s++) {
      90         [ #  # ]:          0 :                 if (seg_type(seg, s) != AREA_LV)
      91                 :          0 :                         continue;
      92         [ #  # ]:          0 :                 if (is_temporary_mirror_layer(seg_lv(seg, s)))
      93                 :          0 :                         mirrors += lv_mirror_count(seg_lv(seg, s)) - 1;
      94                 :            :         }
      95                 :            : 
      96                 :          0 :         return mirrors;
      97                 :            : }
      98                 :            : 
      99                 :          0 : struct lv_segment *find_mirror_seg(struct lv_segment *seg)
     100                 :            : {
     101                 :            :         struct lv_segment *mirror_seg;
     102                 :            : 
     103                 :          0 :         mirror_seg = get_only_segment_using_this_lv(seg->lv);
     104                 :            : 
     105         [ #  # ]:          0 :         if (!mirror_seg) {
     106                 :          0 :                 log_error("Failed to find mirror_seg for %s", seg->lv->name);
     107                 :          0 :                 return NULL;
     108                 :            :         }
     109                 :            : 
     110         [ #  # ]:          0 :         if (!seg_is_mirrored(mirror_seg)) {
     111                 :          0 :                 log_error("%s on %s is not a mirror segments",
     112                 :            :                           mirror_seg->lv->name, seg->lv->name);
     113                 :          0 :                 return NULL;
     114                 :            :         }
     115                 :            : 
     116                 :          0 :         return mirror_seg;
     117                 :            : }
     118                 :            : 
     119                 :            : /*
     120                 :            :  * Reduce the region size if necessary to ensure
     121                 :            :  * the volume size is a multiple of the region size.
     122                 :            :  */
     123                 :          0 : uint32_t adjusted_mirror_region_size(uint32_t extent_size, uint32_t extents,
     124                 :            :                                      uint32_t region_size)
     125                 :            : {
     126                 :            :         uint64_t region_max;
     127                 :            : 
     128                 :          0 :         region_max = (1 << (ffs((int)extents) - 1)) * (uint64_t) extent_size;
     129                 :            : 
     130 [ #  # ][ #  # ]:          0 :         if (region_max < UINT32_MAX && region_size > region_max) {
     131                 :          0 :                 region_size = (uint32_t) region_max;
     132                 :          0 :                 log_print("Using reduced mirror region size of %" PRIu32
     133                 :            :                           " sectors", region_size);
     134                 :            :         }
     135                 :            : 
     136                 :          0 :         return region_size;
     137                 :            : }
     138                 :            : 
     139                 :            : /*
     140                 :            :  * shift_mirror_images
     141                 :            :  * @mirrored_seg
     142                 :            :  * @mimage:  The position (index) of the image to move to the end
     143                 :            :  *
     144                 :            :  * When dealing with removal of legs, we often move a 'removable leg'
     145                 :            :  * to the back of the 'areas' array.  It is critically important not
     146                 :            :  * to simply swap it for the last area in the array.  This would have
     147                 :            :  * the affect of reordering the remaining legs - altering position of
     148                 :            :  * the primary.  So, we must shuffle all of the areas in the array
     149                 :            :  * to maintain their relative position before moving the 'removable
     150                 :            :  * leg' to the end.
     151                 :            :  *
     152                 :            :  * Short illustration of the problem:
     153                 :            :  *   - Mirror consists of legs A, B, C and we want to remove A
     154                 :            :  *   - We swap A and C and then remove A, leaving C, B
     155                 :            :  * This scenario is problematic in failure cases where A dies, because
     156                 :            :  * B becomes the primary.  If the above happens, we effectively throw
     157                 :            :  * away any changes made between the time of failure and the time of
     158                 :            :  * restructuring the mirror.
     159                 :            :  *
     160                 :            :  * So, any time we want to move areas to the end to be removed, use
     161                 :            :  * this function.
     162                 :            :  */
     163                 :          0 : int shift_mirror_images(struct lv_segment *mirrored_seg, unsigned mimage)
     164                 :            : {
     165                 :            :         int i;
     166                 :            :         struct lv_segment_area area;
     167                 :            : 
     168         [ #  # ]:          0 :         if (mimage >= mirrored_seg->area_count) {
     169                 :          0 :                 log_error("Invalid index (%u) of mirror image supplied "
     170                 :            :                           "to shift_mirror_images()", mimage);
     171                 :          0 :                 return 0;
     172                 :            :         }
     173                 :            : 
     174                 :          0 :         area = mirrored_seg->areas[mimage];
     175                 :            : 
     176                 :            :         /* Shift remaining images down to fill the hole */
     177         [ #  # ]:          0 :         for (i = mimage + 1; i < mirrored_seg->area_count; i++)
     178                 :          0 :                 mirrored_seg->areas[i-1] = mirrored_seg->areas[i];
     179                 :            : 
     180                 :            :         /* Place this one at the end */
     181                 :          0 :         mirrored_seg->areas[i-1] = area;
     182                 :            : 
     183                 :          0 :         return 1;
     184                 :            : }
     185                 :            : 
     186                 :            : /*
     187                 :            :  * This function writes a new header to the mirror log header to the lv
     188                 :            :  *
     189                 :            :  * Returns: 1 on success, 0 on failure
     190                 :            :  */
     191                 :          0 : static int _write_log_header(struct cmd_context *cmd, struct logical_volume *lv)
     192                 :            : {
     193                 :            :         struct device *dev;
     194                 :            :         char *name;
     195                 :            :         struct { /* The mirror log header */
     196                 :            :                 uint32_t magic;
     197                 :            :                 uint32_t version;
     198                 :            :                 uint64_t nr_regions;
     199                 :            :         } log_header;
     200                 :            : 
     201                 :          0 :         log_header.magic = xlate32(MIRROR_MAGIC);
     202                 :          0 :         log_header.version = xlate32(MIRROR_DISK_VERSION);
     203                 :          0 :         log_header.nr_regions = xlate64((uint64_t)-1);
     204                 :            : 
     205         [ #  # ]:          0 :         if (!(name = dm_pool_alloc(cmd->mem, PATH_MAX))) {
     206                 :          0 :                 log_error("Name allocation failed - log header not written (%s)",
     207                 :            :                         lv->name);
     208                 :          0 :                 return 0;
     209                 :            :         }
     210                 :            : 
     211         [ #  # ]:          0 :         if (dm_snprintf(name, PATH_MAX, "%s%s/%s", cmd->dev_dir,
     212                 :          0 :                          lv->vg->name, lv->name) < 0) {
     213                 :          0 :                 log_error("Name too long - log header not written (%s)", lv->name);
     214                 :          0 :                 return 0;
     215                 :            :         }
     216                 :            : 
     217                 :          0 :         log_verbose("Writing log header to device, %s", lv->name);
     218                 :            : 
     219         [ #  # ]:          0 :         if (!(dev = dev_cache_get(name, NULL))) {
     220                 :          0 :                 log_error("%s: not found: log header not written", name);
     221                 :          0 :                 return 0;
     222                 :            :         }
     223                 :            : 
     224         [ #  # ]:          0 :         if (!dev_open_quiet(dev))
     225                 :          0 :                 return 0;
     226                 :            : 
     227         [ #  # ]:          0 :         if (!dev_write(dev, UINT64_C(0), sizeof(log_header), &log_header)) {
     228                 :          0 :                 log_error("Failed to write log header to %s", name);
     229                 :          0 :                 dev_close_immediate(dev);
     230                 :          0 :                 return 0;
     231                 :            :         }
     232                 :            : 
     233                 :          0 :         dev_close_immediate(dev);
     234                 :            : 
     235                 :          0 :         return 1;
     236                 :            : }
     237                 :            : 
     238                 :            : /*
     239                 :            :  * Initialize mirror log contents
     240                 :            :  */
     241                 :          0 : static int _init_mirror_log(struct cmd_context *cmd,
     242                 :            :                             struct logical_volume *log_lv, int in_sync,
     243                 :            :                             struct dm_list *tags, int remove_on_failure)
     244                 :            : {
     245                 :            :         struct str_list *sl;
     246                 :            :         struct lvinfo info;
     247                 :          0 :         uint64_t orig_status = log_lv->status;
     248                 :          0 :         int was_active = 0;
     249                 :            : 
     250 [ #  # ][ #  # ]:          0 :         if (!activation() && in_sync) {
     251                 :          0 :                 log_error("Aborting. Unable to create in-sync mirror log "
     252                 :            :                           "while activation is disabled.");
     253                 :          0 :                 return 0;
     254                 :            :         }
     255                 :            : 
     256                 :            :         /* If the LV is active, deactivate it first. */
     257 [ #  # ][ #  # ]:          0 :         if (lv_info(cmd, log_lv, &info, 0, 0) && info.exists) {
     258 [ #  # ][ #  # ]:          0 :                 (void)deactivate_lv(cmd, log_lv);
     259                 :            :                 /*
     260                 :            :                  * FIXME: workaround to fail early
     261                 :            :                  * Ensure that log is really deactivated because deactivate_lv
     262                 :            :                  * on cluster do not fail if there is log_lv with different UUID.
     263                 :            :                  */
     264 [ #  # ][ #  # ]:          0 :                 if (lv_info(cmd, log_lv, &info, 0, 0) && info.exists) {
     265                 :          0 :                         log_error("Aborting. Unable to deactivate mirror log.");
     266                 :          0 :                         goto revert_new_lv;
     267                 :            :                 }
     268                 :          0 :                 was_active = 1;
     269                 :            :         }
     270                 :            : 
     271                 :            :         /* Temporary make it visible for set_lv() */
     272                 :          0 :         lv_set_visible(log_lv);
     273                 :            : 
     274                 :            :         /* Temporary tag mirror log for activation */
     275         [ #  # ]:          0 :         dm_list_iterate_items(sl, tags)
     276         [ #  # ]:          0 :                 if (!str_list_add(cmd->mem, &log_lv->tags, sl->str)) {
     277                 :          0 :                         log_error("Aborting. Unable to tag mirror log.");
     278                 :          0 :                         goto activate_lv;
     279                 :            :                 }
     280                 :            : 
     281                 :            :         /* store mirror log on disk(s) */
     282 [ #  # ][ #  # ]:          0 :         if (!vg_write(log_lv->vg) || !vg_commit(log_lv->vg))
     283                 :            :                 goto activate_lv;
     284                 :            : 
     285                 :          0 :         backup(log_lv->vg);
     286                 :            : 
     287   [ #  #  #  # ]:          0 :         if (!activate_lv(cmd, log_lv)) {
                 [ #  # ]
     288                 :          0 :                 log_error("Aborting. Failed to activate mirror log.");
     289                 :          0 :                 goto revert_new_lv;
     290                 :            :         }
     291                 :            : 
     292                 :            :         /* Remove the temporary tags */
     293         [ #  # ]:          0 :         dm_list_iterate_items(sl, tags)
     294         [ #  # ]:          0 :                 if (!str_list_del(&log_lv->tags, sl->str))
     295                 :          0 :                         log_error("Failed to remove tag %s from mirror log.",
     296                 :            :                                   sl->str);
     297                 :            : 
     298 [ #  # ][ #  # ]:          0 :         if (activation() && !set_lv(cmd, log_lv, log_lv->size,
                 [ #  # ]
     299                 :            :                                     in_sync ? -1 : 0)) {
     300                 :          0 :                 log_error("Aborting. Failed to wipe mirror log.");
     301                 :          0 :                 goto deactivate_and_revert_new_lv;
     302                 :            :         }
     303                 :            : 
     304 [ #  # ][ #  # ]:          0 :         if (activation() && !_write_log_header(cmd, log_lv)) {
     305                 :          0 :                 log_error("Aborting. Failed to write mirror log header.");
     306                 :          0 :                 goto deactivate_and_revert_new_lv;
     307                 :            :         }
     308                 :            : 
     309 [ #  # ][ #  # ]:          0 :         if (!deactivate_lv(cmd, log_lv)) {
                 [ #  # ]
     310                 :          0 :                 log_error("Aborting. Failed to deactivate mirror log. "
     311                 :            :                           "Manual intervention required.");
     312                 :          0 :                 return 0;
     313                 :            :         }
     314                 :            : 
     315                 :          0 :         lv_set_hidden(log_lv);
     316                 :            : 
     317   [ #  #  #  # ]:          0 :         if (was_active && !activate_lv(cmd, log_lv))
         [ #  # ][ #  # ]
     318                 :          0 :                 return_0;
     319                 :            : 
     320                 :          0 :         return 1;
     321                 :            : 
     322                 :            : deactivate_and_revert_new_lv:
     323 [ #  # ][ #  # ]:          0 :         if (!deactivate_lv(cmd, log_lv)) {
                 [ #  # ]
     324                 :          0 :                 log_error("Unable to deactivate mirror log LV. "
     325                 :            :                           "Manual intervention required.");
     326                 :          0 :                 return 0;
     327                 :            :         }
     328                 :            : 
     329                 :            : revert_new_lv:
     330                 :          0 :         log_lv->status = orig_status;
     331                 :            : 
     332         [ #  # ]:          0 :         dm_list_iterate_items(sl, tags)
     333         [ #  # ]:          0 :                 if (!str_list_del(&log_lv->tags, sl->str))
     334                 :          0 :                         log_error("Failed to remove tag %s from mirror log.",
     335                 :            :                                   sl->str);
     336                 :            : 
     337 [ #  # ][ #  # ]:          0 :         if (remove_on_failure && !lv_remove(log_lv)) {
     338                 :          0 :                 log_error("Manual intervention may be required to remove "
     339                 :            :                           "abandoned log LV before retrying.");
     340                 :          0 :                 return 0;
     341                 :            :         }
     342                 :            : 
     343 [ #  # ][ #  # ]:          0 :         if (!vg_write(log_lv->vg) || !vg_commit(log_lv->vg))
     344                 :          0 :                 log_error("Manual intervention may be required to "
     345                 :            :                           "remove/restore abandoned log LV before retrying.");
     346                 :            :         else
     347                 :          0 :                 backup(log_lv->vg);
     348                 :            : 
     349                 :            : activate_lv:
     350 [ #  # ][ #  # ]:          0 :         if (was_active && !remove_on_failure && !activate_lv(cmd, log_lv))
         [ #  # ][ #  # ]
                 [ #  # ]
     351                 :          0 :                 return_0;
     352                 :            : 
     353                 :          0 :         return 0;
     354                 :            : }
     355                 :            : 
     356                 :            : /*
     357                 :            :  * Delete independent/orphan LV, it must acquire lock.
     358                 :            :  */
     359                 :          0 : static int _delete_lv(struct logical_volume *mirror_lv, struct logical_volume *lv)
     360                 :            : {
     361                 :          0 :         struct cmd_context *cmd = mirror_lv->vg->cmd;
     362                 :            :         struct str_list *sl;
     363                 :            : 
     364                 :            :         /* Inherit tags - maybe needed for activation */
     365         [ #  # ]:          0 :         if (!str_list_match_list(&mirror_lv->tags, &lv->tags)) {
     366         [ #  # ]:          0 :                 dm_list_iterate_items(sl, &mirror_lv->tags)
     367         [ #  # ]:          0 :                         if (!str_list_add(cmd->mem, &lv->tags, sl->str)) {
     368                 :          0 :                                 log_error("Aborting. Unable to tag.");
     369                 :          0 :                                 return 0;
     370                 :            :                         }
     371                 :            : 
     372   [ #  #  #  # ]:          0 :                 if (!vg_write(mirror_lv->vg) ||
     373                 :          0 :                     !vg_commit(mirror_lv->vg)) {
     374                 :          0 :                         log_error("Intermediate VG commit for orphan volume failed.");
     375                 :          0 :                         return 0;
     376                 :            :                 }
     377                 :            :         }
     378                 :            : 
     379 [ #  # ][ #  # ]:          0 :         if (!activate_lv(cmd, lv))
                 [ #  # ]
     380                 :          0 :                 return_0;
     381                 :            : 
     382 [ #  # ][ #  # ]:          0 :         if (!deactivate_lv(cmd, lv))
                 [ #  # ]
     383                 :          0 :                 return_0;
     384                 :            : 
     385         [ #  # ]:          0 :         if (!lv_remove(lv))
     386                 :          0 :                 return_0;
     387                 :            : 
     388                 :          0 :         return 1;
     389                 :            : }
     390                 :            : 
     391                 :          0 : static int _merge_mirror_images(struct logical_volume *lv,
     392                 :            :                                 const struct dm_list *mimages)
     393                 :            : {
     394                 :          0 :         uint32_t addition = dm_list_size(mimages);
     395                 :            :         struct logical_volume **img_lvs;
     396                 :            :         struct lv_list *lvl;
     397                 :          0 :         int i = 0;
     398                 :            : 
     399         [ #  # ]:          0 :         if (!addition)
     400                 :          0 :                 return 1;
     401                 :            : 
     402                 :          0 :         if (!(img_lvs = alloca(sizeof(*img_lvs) * addition)))
     403                 :            :                 return_0;
     404                 :            : 
     405         [ #  # ]:          0 :         dm_list_iterate_items(lvl, mimages)
     406                 :          0 :                 img_lvs[i++] = lvl->lv;
     407                 :            : 
     408                 :          0 :         return lv_add_mirror_lvs(lv, img_lvs, addition,
     409                 :          0 :                                  MIRROR_IMAGE, first_seg(lv)->region_size);
     410                 :            : }
     411                 :            : 
     412                 :            : /* Unlink the relationship between the segment and its log_lv */
     413                 :          0 : struct logical_volume *detach_mirror_log(struct lv_segment *mirrored_seg)
     414                 :            : {
     415                 :            :         struct logical_volume *log_lv;
     416                 :            : 
     417         [ #  # ]:          0 :         if (!mirrored_seg->log_lv)
     418                 :          0 :                 return NULL;
     419                 :            : 
     420                 :          0 :         log_lv = mirrored_seg->log_lv;
     421                 :          0 :         mirrored_seg->log_lv = NULL;
     422                 :          0 :         lv_set_visible(log_lv);
     423                 :          0 :         log_lv->status &= ~MIRROR_LOG;
     424                 :          0 :         remove_seg_from_segs_using_this_lv(log_lv, mirrored_seg);
     425                 :            : 
     426                 :          0 :         return log_lv;
     427                 :            : }
     428                 :            : 
     429                 :            : /* Check if mirror image LV is removable with regard to given removable_pvs */
     430                 :          0 : static int _is_mirror_image_removable(struct logical_volume *mimage_lv,
     431                 :            :                                       struct dm_list *removable_pvs)
     432                 :            : {
     433                 :            :         struct physical_volume *pv;
     434                 :            :         struct lv_segment *seg;
     435                 :            :         int pv_found;
     436                 :            :         struct pv_list *pvl;
     437                 :            :         uint32_t s;
     438                 :            : 
     439         [ #  # ]:          0 :         dm_list_iterate_items(seg, &mimage_lv->segments) {
     440         [ #  # ]:          0 :                 for (s = 0; s < seg->area_count; s++) {
     441         [ #  # ]:          0 :                         if (seg_type(seg, s) != AREA_PV) {
     442                 :            :                                 /* FIXME Recurse for AREA_LV? */
     443                 :            :                                 /* Structure of seg_lv is unknown.
     444                 :            :                                  * Not removing this LV for safety. */
     445                 :          0 :                                 return 0;
     446                 :            :                         }
     447                 :            : 
     448                 :          0 :                         pv = seg_pv(seg, s);
     449                 :            : 
     450                 :          0 :                         pv_found = 0;
     451         [ #  # ]:          0 :                         dm_list_iterate_items(pvl, removable_pvs) {
     452         [ #  # ]:          0 :                                 if (id_equal(&pv->id, &pvl->pv->id)) {
     453                 :          0 :                                         pv_found = 1;
     454                 :          0 :                                         break;
     455                 :            :                                 }
     456 [ #  # ][ #  # ]:          0 :                                 if (pvl->pv->dev && pv->dev &&
                 [ #  # ]
     457                 :          0 :                                     pv->dev->dev == pvl->pv->dev->dev) {
     458                 :          0 :                                         pv_found = 1;
     459                 :          0 :                                         break;
     460                 :            :                                 }
     461                 :            :                         }
     462         [ #  # ]:          0 :                         if (!pv_found)
     463                 :          0 :                                 return 0;
     464                 :            :                 }
     465                 :            :         }
     466                 :            : 
     467                 :          0 :         return 1;
     468                 :            : }
     469                 :            : 
     470                 :            : /*
     471                 :            :  * _move_removable_mimages_to_end
     472                 :            :  *
     473                 :            :  * We always detach mimage LVs from the end of the areas array.
     474                 :            :  * This function will push 'count' mimages to the end of the array
     475                 :            :  * based on if their PVs are removable.
     476                 :            :  *
     477                 :            :  * This is an all or nothing function.  Either the user specifies
     478                 :            :  * enough removable PVs to satisfy count, or they don't specify
     479                 :            :  * any removable_pvs at all (in which case all PVs in the mirror
     480                 :            :  * are considered removable).
     481                 :            :  */
     482                 :          0 : static int _move_removable_mimages_to_end(struct logical_volume *lv,
     483                 :            :                                           uint32_t count,
     484                 :            :                                           struct dm_list *removable_pvs)
     485                 :            : {
     486                 :            :         int i, images;
     487                 :            :         struct logical_volume *sub_lv;
     488                 :          0 :         struct lv_segment *mirrored_seg = first_seg(lv);
     489                 :            : 
     490         [ #  # ]:          0 :         if (!removable_pvs)
     491                 :          0 :                 return 1;
     492                 :            : 
     493                 :            :         /*
     494                 :            :          * When we shift an image to the end, we must start from
     495                 :            :          * the begining of the list again.  We must visit the
     496                 :            :          * images up to the last one we just moved.
     497                 :            :          */
     498 [ #  # ][ #  # ]:          0 :         for (images = mirrored_seg->area_count; images && count; images--) {
     499         [ #  # ]:          0 :                 for (i = 0; i < images; i++) {
     500                 :          0 :                         sub_lv = seg_lv(mirrored_seg, i);
     501                 :            : 
     502   [ #  #  #  # ]:          0 :                         if (!is_temporary_mirror_layer(sub_lv) &&
     503                 :          0 :                             _is_mirror_image_removable(sub_lv, removable_pvs)) {
     504         [ #  # ]:          0 :                                 if (!shift_mirror_images(mirrored_seg, i))
     505                 :          0 :                                         return_0;
     506                 :          0 :                                 count--;
     507                 :          0 :                                 break;
     508                 :            :                         }
     509                 :            :                 }
     510                 :            : 
     511                 :            :                 /* Did we shift any images? */
     512         [ #  # ]:          0 :                 if (i == images)
     513                 :          0 :                         return 0;
     514                 :            :         }
     515                 :            : 
     516                 :          0 :         return !count;
     517                 :            : }
     518                 :            : 
     519                 :            : /*
     520                 :            :  * Split off 'split_count' legs from a mirror
     521                 :            :  *
     522                 :            :  * Returns: 0 on error, 1 on success
     523                 :            :  */
     524                 :          0 : static int _split_mirror_images(struct logical_volume *lv,
     525                 :            :                                 const char *split_name,
     526                 :            :                                 uint32_t split_count,
     527                 :            :                                 struct dm_list *removable_pvs)
     528                 :            : {
     529                 :            :         uint32_t i;
     530                 :          0 :         struct logical_volume *sub_lv, *new_lv = NULL;
     531                 :          0 :         struct logical_volume *detached_log_lv = NULL;
     532                 :          0 :         struct logical_volume *lv1 = NULL;
     533                 :          0 :         struct lv_segment *mirrored_seg = first_seg(lv);
     534                 :            :         struct dm_list split_images;
     535                 :            :         struct lv_list *lvl;
     536                 :            : 
     537         [ #  # ]:          0 :         if (!(lv->status & MIRRORED)) {
     538                 :          0 :                 log_error("Unable to split non-mirrored LV, %s",
     539                 :            :                           lv->name);
     540                 :          0 :                 return 0;
     541                 :            :         }
     542                 :            : 
     543         [ #  # ]:          0 :         if (!split_count) {
     544                 :          0 :                 log_error("split_count is zero!");
     545                 :          0 :                 return 0;
     546                 :            :         }
     547                 :            : 
     548                 :          0 :         log_verbose("Detaching %d images from mirror, %s",
     549                 :            :                     split_count, lv->name);
     550                 :            : 
     551         [ #  # ]:          0 :         if (!_move_removable_mimages_to_end(lv, split_count, removable_pvs)) {
     552                 :            :                 /*
     553                 :            :                  * FIXME: Allow incomplete specification of removable PVs?
     554                 :            :                  *
     555                 :            :                  * I am forcing the user to either specify no
     556                 :            :                  * removable PVs or all of them.  Should we allow
     557                 :            :                  * them to just specify some - making us pick the rest?
     558                 :            :                  */
     559                 :          0 :                 log_error("Insufficient removable PVs given"
     560                 :            :                           " to satisfy request");
     561                 :          0 :                 return 0;
     562                 :            :         }
     563                 :            : 
     564                 :          0 :         dm_list_init(&split_images);
     565         [ #  # ]:          0 :         for (i = 0; i < split_count; i++) {
     566                 :          0 :                 mirrored_seg->area_count--;
     567                 :          0 :                 sub_lv = seg_lv(mirrored_seg, mirrored_seg->area_count);
     568                 :            : 
     569                 :          0 :                 sub_lv->status &= ~MIRROR_IMAGE;
     570                 :          0 :                 lv_set_visible(sub_lv);
     571                 :          0 :                 release_lv_segment_area(mirrored_seg, mirrored_seg->area_count,
     572                 :            :                                         mirrored_seg->area_len);
     573                 :            : 
     574         [ #  # ]:          0 :                 if (!new_lv) {
     575                 :          0 :                         new_lv = sub_lv;
     576                 :          0 :                         new_lv->name = dm_pool_strdup(lv->vg->cmd->mem,
     577                 :            :                                                       split_name);
     578         [ #  # ]:          0 :                         if (!new_lv->name) {
     579                 :          0 :                                 log_error("Unable to rename newly split LV");
     580                 :          0 :                                 return 0;
     581                 :            :                         }
     582                 :            :                 } else {
     583                 :          0 :                         lvl = dm_pool_alloc(lv->vg->cmd->mem, sizeof(*lvl));
     584         [ #  # ]:          0 :                         if (!lvl) {
     585                 :          0 :                                 log_error("lv_list alloc failed");
     586                 :          0 :                                 return 0;
     587                 :            :                         }
     588                 :          0 :                         lvl->lv = sub_lv;
     589                 :          0 :                         dm_list_add(&split_images, &lvl->list);
     590                 :            :                 }
     591                 :            :         }
     592                 :            : 
     593         [ #  # ]:          0 :         if (!dm_list_empty(&split_images)) {
     594                 :          0 :                 size_t len = strlen(new_lv->name) + 32;
     595                 :          0 :                 char *layer_name, format[len];
     596                 :            : 
     597         [ #  # ]:          0 :                 if (!insert_layer_for_lv(lv->vg->cmd, new_lv,
     598                 :            :                                          0, "_mimage_%d")) {
     599                 :          0 :                         log_error("Failed to build new mirror, %s",
     600                 :            :                                   new_lv->name);
     601                 :          0 :                         return 0;
     602                 :            :                 }
     603                 :            : 
     604                 :          0 :                 first_seg(new_lv)->region_size = mirrored_seg->region_size;
     605                 :            : 
     606         [ #  # ]:          0 :                 dm_list_iterate_items(lvl, &split_images) {
     607                 :          0 :                         sub_lv = lvl->lv;
     608                 :            : 
     609                 :          0 :                         dm_snprintf(format, len, "%s_mimage_%%d",
     610                 :            :                                     new_lv->name);
     611                 :            : 
     612                 :          0 :                         layer_name = dm_pool_alloc(lv->vg->cmd->mem, len);
     613         [ #  # ]:          0 :                         if (!layer_name) {
     614                 :          0 :                                 log_error("Unable to allocate memory");
     615                 :          0 :                                 return 0;
     616                 :            :                         }
     617 [ #  # ][ #  # ]:          0 :                         if (!generate_lv_name(lv->vg, format, layer_name, len)||
     618                 :          0 :                             sscanf(layer_name, format, &i) != 1) {
     619                 :          0 :                                 log_error("Failed to generate new image names");
     620                 :          0 :                                 return 0;
     621                 :            :                         }
     622                 :          0 :                         sub_lv->name = layer_name;
     623                 :            :                 }
     624                 :            : 
     625         [ #  # ]:          0 :                 if (!_merge_mirror_images(new_lv, &split_images)) {
     626                 :          0 :                         log_error("Failed to group split "
     627                 :            :                                   "images into new mirror");
     628                 :          0 :                         return 0;
     629                 :            :                 }
     630                 :            : 
     631                 :            :                 /*
     632                 :            :                  * We don't allow splitting a mirror that is not in-sync,
     633                 :            :                  * so we can bring the newly split mirror up without a
     634                 :            :                  * resync.  (It will be a 'core' log mirror after all.)
     635                 :            :                  */
     636         [ #  # ]:          0 :                 init_mirror_in_sync(1);
     637                 :            :         }
     638                 :            : 
     639                 :            :         /* If no more mirrors, remove mirror layer */
     640         [ #  # ]:          0 :         if (mirrored_seg->area_count == 1) {
     641                 :          0 :                 lv1 = seg_lv(mirrored_seg, 0);
     642                 :          0 :                 lv1->status &= ~MIRROR_IMAGE;
     643                 :          0 :                 lv_set_visible(lv1);
     644                 :          0 :                 detached_log_lv = detach_mirror_log(mirrored_seg);
     645         [ #  # ]:          0 :                 if (!remove_layer_from_lv(lv, lv1))
     646                 :          0 :                         return_0;
     647                 :          0 :                 lv->status &= ~MIRRORED;
     648                 :          0 :                 lv->status &= ~MIRROR_NOTSYNCED;
     649                 :            :         }
     650                 :            : 
     651         [ #  # ]:          0 :         if (!vg_write(mirrored_seg->lv->vg)) {
     652                 :          0 :                 log_error("Intermediate VG metadata write failed.");
     653                 :          0 :                 return 0;
     654                 :            :         }
     655                 :            : 
     656 [ #  # ][ #  # ]:          0 :         if (!suspend_lv(mirrored_seg->lv->vg->cmd, mirrored_seg->lv)) {
                 [ #  # ]
     657                 :          0 :                 log_error("Failed to lock %s", mirrored_seg->lv->name);
     658                 :          0 :                 vg_revert(mirrored_seg->lv->vg);
     659                 :          0 :                 return 0;
     660                 :            :         }
     661                 :            : 
     662         [ #  # ]:          0 :         if (!vg_commit(mirrored_seg->lv->vg)) {
     663 [ #  # ][ #  # ]:          0 :                 resume_lv(mirrored_seg->lv->vg->cmd, mirrored_seg->lv);
     664                 :          0 :                 return 0;
     665                 :            :         }
     666                 :            : 
     667                 :          0 :         log_very_verbose("Updating \"%s\" in kernel", mirrored_seg->lv->name);
     668                 :            : 
     669                 :            :         /*
     670                 :            :          * If we have split off a mirror instead of linear (i.e. the
     671                 :            :          * split_images list is not empty), then we must perform a
     672                 :            :          * resume to get the mirror started.
     673                 :            :          */
     674   [ #  #  #  # ]:          0 :         if (!dm_list_empty(&split_images) && !resume_lv(lv->vg->cmd, new_lv)) {
         [ #  # ][ #  # ]
     675                 :          0 :                 log_error("Failed to resume newly split LV, %s", new_lv->name);
     676                 :          0 :                 return 0;
     677                 :            :         }
     678                 :            : 
     679                 :            :         /*
     680                 :            :          * Avoid having same mirror target loaded twice simultaneously by first
     681                 :            :          * resuming the removed LV which now contains an error segment.
     682                 :            :          * As it's now detached from mirrored_seg->lv we must resume it
     683                 :            :          * explicitly.
     684                 :            :          */
     685 [ #  # ][ #  # ]:          0 :         if (lv1 && !resume_lv(lv1->vg->cmd, lv1)) {
         [ #  # ][ #  # ]
     686                 :          0 :                 log_error("Problem resuming temporary LV, %s", lv1->name);
     687                 :          0 :                 return 0;
     688                 :            :         }
     689                 :            : 
     690 [ #  # ][ #  # ]:          0 :         if (!resume_lv(mirrored_seg->lv->vg->cmd, mirrored_seg->lv)) {
                 [ #  # ]
     691                 :          0 :                 log_error("Problem reactivating %s", mirrored_seg->lv->name);
     692                 :          0 :                 return 0;
     693                 :            :         }
     694                 :            : 
     695 [ #  # ][ #  # ]:          0 :         if (lv1 && !_delete_lv(lv, lv1))
     696                 :          0 :                 return_0;
     697                 :            : 
     698 [ #  # ][ #  # ]:          0 :         if (detached_log_lv && !_delete_lv(lv, detached_log_lv))
     699                 :          0 :                 return_0;
     700                 :            : 
     701                 :          0 :         log_very_verbose("%" PRIu32 " image(s) detached from %s",
     702                 :            :                          split_count, lv->name);
     703                 :            : 
     704                 :          0 :         return 1;
     705                 :            : }
     706                 :            : 
     707                 :            : /*
     708                 :            :  * Remove num_removed images from mirrored_seg
     709                 :            :  *
     710                 :            :  * Arguments:
     711                 :            :  *   num_removed:   the requested (maximum) number of mirrors to be removed
     712                 :            :  *   removable_pvs: if not NULL and list not empty, only mirrors using PVs
     713                 :            :  *                  in this list will be removed
     714                 :            :  *   remove_log:    if non-zero, log_lv will be removed
     715                 :            :  *                  (even if it's 0, log_lv will be removed if there is no
     716                 :            :  *                   mirror remaining after the removal)
     717                 :            :  *   collapse:      if non-zero, instead of removing, remove the temporary
     718                 :            :  *                  mirror layer and merge mirrors to the original LV.
     719                 :            :  *                  removable_pvs should be NULL and num_removed should be
     720                 :            :  *                  seg->area_count - 1.
     721                 :            :  *   removed:       if non NULL, the number of removed mirror images is set
     722                 :            :  *                  as a result
     723                 :            :  *
     724                 :            :  * If collapse is non-zero, <removed> is guaranteed to be equal to num_removed.
     725                 :            :  *
     726                 :            :  * Return values:
     727                 :            :  *   Failure (0) means something unexpected has happend and
     728                 :            :  *   the caller should abort.
     729                 :            :  *   Even if no mirror was removed (e.g. no LV matches to 'removable_pvs'),
     730                 :            :  *   returns success (1).
     731                 :            :  */
     732                 :          0 : static int _remove_mirror_images(struct logical_volume *lv,
     733                 :            :                                  uint32_t num_removed,
     734                 :            :                                  struct dm_list *removable_pvs,
     735                 :            :                                  unsigned remove_log, unsigned collapse,
     736                 :            :                                  uint32_t *removed)
     737                 :            : {
     738                 :            :         uint32_t m;
     739                 :            :         uint32_t s;
     740                 :            :         int removable_pvs_specified;
     741                 :            :         struct logical_volume *sub_lv;
     742                 :          0 :         struct logical_volume *detached_log_lv = NULL;
     743                 :          0 :         struct logical_volume *temp_layer_lv = NULL;
     744                 :          0 :         struct lv_segment *mirrored_seg = first_seg(lv);
     745                 :          0 :         uint32_t old_area_count = mirrored_seg->area_count;
     746                 :          0 :         uint32_t new_area_count = mirrored_seg->area_count;
     747                 :            :         struct lv_list *lvl;
     748                 :            :         struct dm_list tmp_orphan_lvs;
     749                 :            : 
     750   [ #  #  #  # ]:          0 :         removable_pvs_specified = (removable_pvs &&
     751                 :          0 :                                    !dm_list_empty(removable_pvs)) ? 1 : 0;
     752                 :            : 
     753         [ #  # ]:          0 :         if (removed)
     754                 :          0 :                 *removed = 0;
     755                 :            : 
     756         [ #  # ]:          0 :         log_very_verbose("Reducing mirror set from %" PRIu32 " to %"
     757                 :            :                          PRIu32 " image(s)%s.",
     758                 :            :                          old_area_count, old_area_count - num_removed,
     759                 :            :                          remove_log ? " and no log volume" : "");
     760                 :            : 
     761   [ #  #  #  # ]:          0 :         if (collapse &&
                 [ #  # ]
     762                 :          0 :             (removable_pvs_specified || (old_area_count - num_removed != 1))) {
     763                 :          0 :                 log_error("Incompatible parameters to _remove_mirror_images");
     764                 :          0 :                 return 0;
     765                 :            :         }
     766                 :            : 
     767                 :            :         /* Move removable_pvs to end of array */
     768         [ #  # ]:          0 :         if (removable_pvs_specified) {
     769 [ #  # ][ #  # ]:          0 :                 for (s = 0; s < mirrored_seg->area_count &&
     770                 :          0 :                             old_area_count - new_area_count < num_removed; s++) {
     771                 :          0 :                         sub_lv = seg_lv(mirrored_seg, s);
     772                 :            : 
     773   [ #  #  #  # ]:          0 :                         if (!is_temporary_mirror_layer(sub_lv) &&
     774                 :          0 :                             _is_mirror_image_removable(sub_lv, removable_pvs)) {
     775         [ #  # ]:          0 :                                 if (!shift_mirror_images(mirrored_seg, s))
     776                 :          0 :                                         return_0;
     777                 :          0 :                                 s--; /* adjust counter after shifting */
     778                 :          0 :                                 new_area_count--;
     779                 :            :                         }
     780                 :            :                 }
     781 [ #  # ][ #  # ]:          0 :                 if (num_removed && old_area_count == new_area_count)
     782                 :          0 :                         return 1;
     783                 :            :         } else
     784                 :          0 :                 new_area_count = old_area_count - num_removed;
     785                 :            : 
     786                 :            :         /* Remove mimage LVs from the segment */
     787                 :          0 :         dm_list_init(&tmp_orphan_lvs);
     788         [ #  # ]:          0 :         for (m = new_area_count; m < mirrored_seg->area_count; m++) {
     789                 :          0 :                 seg_lv(mirrored_seg, m)->status &= ~MIRROR_IMAGE;
     790                 :          0 :                 lv_set_visible(seg_lv(mirrored_seg, m));
     791         [ #  # ]:          0 :                 if (!(lvl = dm_pool_alloc(lv->vg->cmd->mem, sizeof(*lvl)))) {
     792                 :          0 :                         log_error("lv_list alloc failed");
     793                 :          0 :                         return 0;
     794                 :            :                 }
     795                 :          0 :                 lvl->lv = seg_lv(mirrored_seg, m);
     796                 :          0 :                 dm_list_add(&tmp_orphan_lvs, &lvl->list);
     797                 :          0 :                 release_lv_segment_area(mirrored_seg, m, mirrored_seg->area_len);
     798                 :            :         }
     799                 :          0 :         mirrored_seg->area_count = new_area_count;
     800                 :            : 
     801                 :            :         /* If no more mirrors, remove mirror layer */
     802                 :            :         /* As an exceptional case, if the lv is temporary layer,
     803                 :            :          * leave the LV as mirrored and let the lvconvert completion
     804                 :            :          * to remove the layer. */
     805 [ #  # ][ #  # ]:          0 :         if (new_area_count == 1 && !is_temporary_mirror_layer(lv)) {
     806                 :          0 :                 temp_layer_lv = seg_lv(mirrored_seg, 0);
     807                 :          0 :                 temp_layer_lv->status &= ~MIRROR_IMAGE;
     808                 :          0 :                 lv_set_visible(temp_layer_lv);
     809                 :          0 :                 detached_log_lv = detach_mirror_log(mirrored_seg);
     810         [ #  # ]:          0 :                 if (!remove_layer_from_lv(lv, temp_layer_lv))
     811                 :          0 :                         return_0;
     812                 :          0 :                 lv->status &= ~MIRRORED;
     813                 :          0 :                 lv->status &= ~MIRROR_NOTSYNCED;
     814 [ #  # ][ #  # ]:          0 :                 if (collapse && !_merge_mirror_images(lv, &tmp_orphan_lvs)) {
     815                 :          0 :                         log_error("Failed to add mirror images");
     816                 :          0 :                         return 0;
     817                 :            :                 }
     818         [ #  # ]:          0 :         } else if (new_area_count == 0) {
     819                 :          0 :                 log_very_verbose("All mimages of %s are gone", lv->name);
     820                 :            : 
     821                 :            :                 /* All mirror images are gone.
     822                 :            :                  * It can happen for vgreduce --removemissing. */
     823                 :          0 :                 detached_log_lv = detach_mirror_log(mirrored_seg);
     824                 :          0 :                 lv->status &= ~MIRRORED;
     825                 :          0 :                 lv->status &= ~MIRROR_NOTSYNCED;
     826         [ #  # ]:          0 :                 if (!replace_lv_with_error_segment(lv))
     827                 :          0 :                         return_0;
     828         [ #  # ]:          0 :         } else if (remove_log)
     829                 :          0 :                 detached_log_lv = detach_mirror_log(mirrored_seg);
     830                 :            : 
     831                 :            :         /*
     832                 :            :          * To successfully remove these unwanted LVs we need to
     833                 :            :          * remove the LVs from the mirror set, commit that metadata
     834                 :            :          * then deactivate and remove them fully.
     835                 :            :          */
     836                 :            : 
     837         [ #  # ]:          0 :         if (!vg_write(mirrored_seg->lv->vg)) {
     838                 :          0 :                 log_error("intermediate VG write failed.");
     839                 :          0 :                 return 0;
     840                 :            :         }
     841                 :            : 
     842 [ #  # ][ #  # ]:          0 :         if (!suspend_lv(mirrored_seg->lv->vg->cmd, mirrored_seg->lv)) {
                 [ #  # ]
     843                 :          0 :                 log_error("Failed to lock %s", mirrored_seg->lv->name);
     844                 :          0 :                 vg_revert(mirrored_seg->lv->vg);
     845                 :          0 :                 return 0;
     846                 :            :         }
     847                 :            : 
     848                 :            :         /* FIXME: second suspend should not be needed
     849                 :            :          * Explicitly suspend temporary LV
     850                 :            :          * This balance memlock_inc() calls with memlock_dec() in resume
     851                 :            :          * (both localy and in cluster) and also properly propagates precommited
     852                 :            :          * metadata into dm table on other nodes.
     853                 :            :          * (visible flag set causes the suspend is not properly propagated?)
     854                 :            :          */
     855 [ #  # ][ #  # ]:          0 :         if (temp_layer_lv && !suspend_lv(temp_layer_lv->vg->cmd, temp_layer_lv))
         [ #  # ][ #  # ]
     856                 :          0 :                 log_error("Problem suspending temporary LV %s", temp_layer_lv->name);
     857                 :            : 
     858         [ #  # ]:          0 :         if (!vg_commit(mirrored_seg->lv->vg)) {
     859 [ #  # ][ #  # ]:          0 :                 if (!resume_lv(mirrored_seg->lv->vg->cmd, mirrored_seg->lv))
                 [ #  # ]
     860                 :          0 :                         stack;
     861                 :          0 :                 return_0;
     862                 :            :         }
     863                 :            : 
     864                 :          0 :         log_very_verbose("Updating \"%s\" in kernel", mirrored_seg->lv->name);
     865                 :            : 
     866                 :            :         /*
     867                 :            :          * Avoid having same mirror target loaded twice simultaneously by first
     868                 :            :          * resuming the removed LV which now contains an error segment.
     869                 :            :          * As it's now detached from mirrored_seg->lv we must resume it
     870                 :            :          * explicitly.
     871                 :            :          */
     872   [ #  #  #  # ]:          0 :         if (temp_layer_lv && !resume_lv(temp_layer_lv->vg->cmd, temp_layer_lv)) {
         [ #  # ][ #  # ]
     873                 :          0 :                 log_error("Problem resuming temporary LV, %s", temp_layer_lv->name);
     874                 :          0 :                 return 0;
     875                 :            :         }
     876                 :            : 
     877 [ #  # ][ #  # ]:          0 :         if (!resume_lv(mirrored_seg->lv->vg->cmd, mirrored_seg->lv)) {
                 [ #  # ]
     878                 :          0 :                 log_error("Problem reactivating %s", mirrored_seg->lv->name);
     879                 :          0 :                 return 0;
     880                 :            :         }
     881                 :            : 
     882                 :            :         /* Save or delete the 'orphan' LVs */
     883         [ #  # ]:          0 :         if (!collapse) {
     884         [ #  # ]:          0 :                 dm_list_iterate_items(lvl, &tmp_orphan_lvs)
     885         [ #  # ]:          0 :                         if (!_delete_lv(lv, lvl->lv))
     886                 :          0 :                                 return_0;
     887                 :            :         }
     888                 :            : 
     889 [ #  # ][ #  # ]:          0 :         if (temp_layer_lv && !_delete_lv(lv, temp_layer_lv))
     890                 :          0 :                 return_0;
     891                 :            : 
     892 [ #  # ][ #  # ]:          0 :         if (detached_log_lv && !_delete_lv(lv, detached_log_lv))
     893                 :          0 :                 return_0;
     894                 :            : 
     895                 :            :         /* Mirror with only 1 area is 'in sync'. */
     896 [ #  # ][ #  # ]:          0 :         if (new_area_count == 1 && is_temporary_mirror_layer(lv)) {
     897   [ #  #  #  # ]:          0 :                 if (first_seg(lv)->log_lv &&
     898                 :          0 :                     !_init_mirror_log(lv->vg->cmd, first_seg(lv)->log_lv,
     899                 :            :                                       1, &lv->tags, 0)) {
     900                 :            :                         /* As a result, unnecessary sync may run after
     901                 :            :                          * collapsing. But safe.*/
     902                 :          0 :                         log_error("Failed to initialize log device");
     903                 :          0 :                         return_0;
     904                 :            :                 }
     905                 :            :         }
     906                 :            : 
     907         [ #  # ]:          0 :         if (removed)
     908                 :          0 :                 *removed = old_area_count - new_area_count;
     909                 :            : 
     910                 :          0 :         log_very_verbose("%" PRIu32 " image(s) removed from %s",
     911                 :            :                          old_area_count - num_removed, lv->name);
     912                 :            : 
     913                 :          0 :         return 1;
     914                 :            : }
     915                 :            : 
     916                 :            : /*
     917                 :            :  * Remove the number of mirror images from the LV
     918                 :            :  */
     919                 :          0 : int remove_mirror_images(struct logical_volume *lv, uint32_t num_mirrors,
     920                 :            :                          struct dm_list *removable_pvs, unsigned remove_log)
     921                 :            : {
     922                 :            :         uint32_t num_removed, removed_once, r;
     923                 :          0 :         uint32_t existing_mirrors = lv_mirror_count(lv);
     924                 :          0 :         struct logical_volume *next_lv = lv;
     925                 :            : 
     926                 :          0 :         num_removed = existing_mirrors - num_mirrors;
     927                 :            : 
     928                 :            :         /* num_removed can be 0 if the function is called just to remove log */
     929                 :            :         do {
     930         [ #  # ]:          0 :                 if (num_removed < first_seg(next_lv)->area_count)
     931                 :          0 :                         removed_once = num_removed;
     932                 :            :                 else
     933                 :          0 :                         removed_once = first_seg(next_lv)->area_count - 1;
     934                 :            : 
     935         [ #  # ]:          0 :                 if (!_remove_mirror_images(next_lv, removed_once,
     936                 :            :                                            removable_pvs, remove_log, 0, &r))
     937                 :          0 :                         return_0;
     938                 :            : 
     939         [ #  # ]:          0 :                 if (r < removed_once) {
     940                 :            :                         /* Some mirrors are removed from the temporary mirror,
     941                 :            :                          * but the temporary layer still exists.
     942                 :            :                          * Down the stack and retry for remainder. */
     943                 :          0 :                         next_lv = find_temporary_mirror(next_lv);
     944                 :            :                 }
     945                 :            : 
     946                 :          0 :                 num_removed -= r;
     947 [ #  # ][ #  # ]:          0 :         } while (next_lv && num_removed);
     948                 :            : 
     949         [ #  # ]:          0 :         if (num_removed) {
     950         [ #  # ]:          0 :                 if (num_removed == existing_mirrors - num_mirrors)
     951                 :          0 :                         log_error("No mirror images found using specified PVs.");
     952                 :            :                 else {
     953                 :          0 :                         log_error("%u images are removed out of requested %u.",
     954                 :            :                                   existing_mirrors - lv_mirror_count(lv),
     955                 :            :                                   existing_mirrors - num_mirrors);
     956                 :            :                 }
     957                 :          0 :                 return 0;
     958                 :            :         }
     959                 :            : 
     960                 :          0 :         return 1;
     961                 :            : }
     962                 :            : 
     963                 :          0 : static int _mirrored_lv_in_sync(struct logical_volume *lv)
     964                 :            : {
     965                 :            :         float sync_percent;
     966                 :            :         percent_range_t percent_range;
     967                 :            : 
     968         [ #  # ]:          0 :         if (!lv_mirror_percent(lv->vg->cmd, lv, 0, &sync_percent,
     969                 :            :                                &percent_range, NULL)) {
     970                 :          0 :                 log_error("Unable to determine mirror sync status of %s/%s.",
     971                 :            :                           lv->vg->name, lv->name);
     972                 :          0 :                 return 0;
     973                 :            :         }
     974                 :            : 
     975                 :          0 :         return (percent_range == PERCENT_100) ? 1 : 0;
     976                 :            : }
     977                 :            : 
     978                 :            : /*
     979                 :            :  * Collapsing temporary mirror layers.
     980                 :            :  *
     981                 :            :  * When mirrors are added to already-mirrored LV, a temporary mirror layer
     982                 :            :  * is inserted at the top of the stack to reduce resync work.
     983                 :            :  * The function will remove the intermediate layer and collapse the stack
     984                 :            :  * as far as mirrors are in-sync.
     985                 :            :  *
     986                 :            :  * The function is destructive: to remove intermediate mirror layers,
     987                 :            :  * VG metadata commits and suspend/resume are necessary.
     988                 :            :  */
     989                 :          0 : int collapse_mirrored_lv(struct logical_volume *lv)
     990                 :            : {
     991                 :            :         struct logical_volume *tmp_lv;
     992                 :            :         struct lv_segment *mirror_seg;
     993                 :            : 
     994         [ #  # ]:          0 :         while ((tmp_lv = find_temporary_mirror(lv))) {
     995                 :          0 :                 mirror_seg = find_mirror_seg(first_seg(tmp_lv));
     996         [ #  # ]:          0 :                 if (!mirror_seg) {
     997                 :          0 :                         log_error("Failed to find mirrored LV for %s",
     998                 :            :                                   tmp_lv->name);
     999                 :          0 :                         return 0;
    1000                 :            :                 }
    1001                 :            : 
    1002         [ #  # ]:          0 :                 if (!_mirrored_lv_in_sync(mirror_seg->lv)) {
    1003                 :          0 :                         log_verbose("Not collapsing %s: out-of-sync",
    1004                 :            :                                     mirror_seg->lv->name);
    1005                 :          0 :                         return 1;
    1006                 :            :                 }
    1007                 :            : 
    1008         [ #  # ]:          0 :                 if (!_remove_mirror_images(mirror_seg->lv,
    1009                 :            :                                            mirror_seg->area_count - 1,
    1010                 :            :                                            NULL, 1, 1, NULL)) {
    1011                 :          0 :                         log_error("Failed to release mirror images");
    1012                 :          0 :                         return 0;
    1013                 :            :                 }
    1014                 :            :         }
    1015                 :            : 
    1016                 :          0 :         return 1;
    1017                 :            : }
    1018                 :            : 
    1019                 :          0 : static int get_mirror_fault_policy(struct cmd_context *cmd __attribute((unused)),
    1020                 :            :                                    int log_policy)
    1021                 :            : {
    1022                 :            :         const char *policy;
    1023                 :            : 
    1024         [ #  # ]:          0 :         if (log_policy)
    1025                 :          0 :                 policy = find_config_str(NULL, "activation/mirror_log_fault_policy",
    1026                 :            :                                          DEFAULT_MIRROR_LOG_FAULT_POLICY);
    1027                 :            :         else {
    1028                 :          0 :                 policy = find_config_str(NULL, "activation/mirror_image_fault_policy",
    1029                 :            :                                          NULL);
    1030         [ #  # ]:          0 :                 if (!policy)
    1031                 :          0 :                         policy = find_config_str(NULL, "activation/mirror_device_fault_policy",
    1032                 :            :                                                  DEFAULT_MIRROR_IMAGE_FAULT_POLICY);
    1033                 :            :         }
    1034                 :            : 
    1035         [ #  # ]:          0 :         if (!strcmp(policy, "remove"))
    1036                 :          0 :                 return MIRROR_REMOVE;
    1037         [ #  # ]:          0 :         else if (!strcmp(policy, "allocate"))
    1038                 :          0 :                 return MIRROR_ALLOCATE;
    1039         [ #  # ]:          0 :         else if (!strcmp(policy, "allocate_anywhere"))
    1040                 :          0 :                 return MIRROR_ALLOCATE_ANYWHERE;
    1041                 :            : 
    1042         [ #  # ]:          0 :         if (log_policy)
    1043                 :          0 :                 log_error("Bad activation/mirror_log_fault_policy");
    1044                 :            :         else
    1045                 :          0 :                 log_error("Bad activation/mirror_device_fault_policy");
    1046                 :            : 
    1047                 :          0 :         return MIRROR_REMOVE;
    1048                 :            : }
    1049                 :            : 
    1050                 :          0 : static int get_mirror_log_fault_policy(struct cmd_context *cmd)
    1051                 :            : {
    1052                 :          0 :         return get_mirror_fault_policy(cmd, 1);
    1053                 :            : }
    1054                 :            : 
    1055                 :          0 : static int get_mirror_device_fault_policy(struct cmd_context *cmd)
    1056                 :            : {
    1057                 :          0 :         return get_mirror_fault_policy(cmd, 0);
    1058                 :            : }
    1059                 :            : 
    1060                 :            : /*
    1061                 :            :  * replace_mirror_images
    1062                 :            :  * @mirrored_seg: segment (which may be linear now) to restore
    1063                 :            :  * @num_mirrors: number of copies we should end up with
    1064                 :            :  * @replace_log: replace log if not present
    1065                 :            :  * @in_sync: was the original mirror in-sync?
    1066                 :            :  *
    1067                 :            :  * in_sync will be set to 0 if new mirror devices are being added
    1068                 :            :  * In other words, it is only useful if the log (and only the log)
    1069                 :            :  * is being restored.
    1070                 :            :  *
    1071                 :            :  * Returns: 0 on failure, 1 on reconfig, -1 if no reconfig done
    1072                 :            :  */
    1073                 :          0 : static int replace_mirror_images(struct lv_segment *mirrored_seg,
    1074                 :            :                                  uint32_t num_mirrors,
    1075                 :            :                                  int log_policy, int in_sync)
    1076                 :            : {
    1077                 :          0 :         int r = -1;
    1078                 :          0 :         struct logical_volume *lv = mirrored_seg->lv;
    1079                 :            : 
    1080                 :            :         /* FIXME: Use lvconvert rather than duplicating its code */
    1081                 :            : 
    1082         [ #  # ]:          0 :         if (mirrored_seg->area_count < num_mirrors) {
    1083                 :          0 :                 log_warn("WARNING: Failed to replace mirror device in %s/%s",
    1084                 :            :                          mirrored_seg->lv->vg->name, mirrored_seg->lv->name);
    1085                 :            : 
    1086   [ #  #  #  # ]:          0 :                 if ((mirrored_seg->area_count > 1) && !mirrored_seg->log_lv)
    1087                 :          0 :                         log_warn("WARNING: Use 'lvconvert -m %d %s/%s --corelog' to replace failed devices",
    1088                 :            :                                  num_mirrors - 1, lv->vg->name, lv->name);
    1089                 :            :                 else
    1090                 :          0 :                         log_warn("WARNING: Use 'lvconvert -m %d %s/%s' to replace failed devices",
    1091                 :            :                                  num_mirrors - 1, lv->vg->name, lv->name);
    1092                 :          0 :                 r = 0;
    1093                 :            : 
    1094                 :            :                 /* REMEMBER/FIXME: set in_sync to 0 if a new mirror device was added */
    1095                 :          0 :                 in_sync = 0;
    1096                 :            :         }
    1097                 :            : 
    1098                 :            :         /*
    1099                 :            :          * FIXME: right now, we ignore the allocation policy specified to
    1100                 :            :          * allocate the new log.
    1101                 :            :          */
    1102 [ #  # ][ #  # ]:          0 :         if ((mirrored_seg->area_count > 1) && !mirrored_seg->log_lv &&
                 [ #  # ]
    1103                 :            :             (log_policy != MIRROR_REMOVE)) {
    1104                 :          0 :                 log_warn("WARNING: Failed to replace mirror log device in %s/%s",
    1105                 :            :                          lv->vg->name, lv->name);
    1106                 :            : 
    1107                 :          0 :                 log_warn("WARNING: Use 'lvconvert -m %d %s/%s' to replace failed devices",
    1108                 :            :                          mirrored_seg->area_count - 1 , lv->vg->name, lv->name);
    1109                 :          0 :                 r = 0;
    1110                 :            :         }
    1111                 :            : 
    1112                 :          0 :         return r;
    1113                 :            : }
    1114                 :            : 
    1115                 :          0 : int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
    1116                 :            :                               struct dm_list *removable_pvs, unsigned remove_log)
    1117                 :            : {
    1118                 :            :         int r;
    1119                 :            :         int in_sync;
    1120                 :            :         int log_policy, dev_policy;
    1121                 :          0 :         uint32_t old_num_mirrors = mirrored_seg->area_count;
    1122                 :          0 :         int had_log = (mirrored_seg->log_lv) ? 1 : 0;
    1123                 :            : 
    1124                 :            :         /* was the mirror in-sync before problems? */
    1125                 :          0 :         in_sync = _mirrored_lv_in_sync(mirrored_seg->lv);
    1126                 :            : 
    1127                 :            :         /*
    1128                 :            :          * While we are only removing devices, we can have sync set.
    1129                 :            :          * Setting this is only useful if we are moving to core log
    1130                 :            :          * otherwise the disk log will contain the sync information
    1131                 :            :          */
    1132                 :          0 :         init_mirror_in_sync(in_sync);
    1133                 :            : 
    1134                 :          0 :         r = _remove_mirror_images(mirrored_seg->lv, old_num_mirrors - num_mirrors,
    1135                 :            :                                   removable_pvs, remove_log, 0, NULL);
    1136         [ #  # ]:          0 :         if (!r)
    1137                 :            :                 /* Unable to remove bad devices */
    1138                 :          0 :                 return 0;
    1139                 :            : 
    1140                 :          0 :         log_warn("WARNING: Bad device removed from mirror volume, %s/%s",
    1141                 :            :                   mirrored_seg->lv->vg->name, mirrored_seg->lv->name);
    1142                 :            : 
    1143                 :          0 :         log_policy = get_mirror_log_fault_policy(mirrored_seg->lv->vg->cmd);
    1144                 :          0 :         dev_policy = get_mirror_device_fault_policy(mirrored_seg->lv->vg->cmd);
    1145                 :            : 
    1146         [ #  # ]:          0 :         r = replace_mirror_images(mirrored_seg,
    1147                 :            :                                   (dev_policy != MIRROR_REMOVE) ?
    1148                 :            :                                   old_num_mirrors : num_mirrors,
    1149                 :            :                                   log_policy, in_sync);
    1150                 :            : 
    1151         [ #  # ]:          0 :         if (!r)
    1152                 :            :                 /* Failed to replace device(s) */
    1153                 :          0 :                 log_warn("WARNING: Unable to find substitute device for mirror volume, %s/%s",
    1154                 :            :                          mirrored_seg->lv->vg->name, mirrored_seg->lv->name);
    1155         [ #  # ]:          0 :         else if (r > 0)
    1156                 :            :                 /* Success in replacing device(s) */
    1157                 :          0 :                 log_warn("WARNING: Mirror volume, %s/%s restored - substitute for failed device found.",
    1158                 :            :                           mirrored_seg->lv->vg->name, mirrored_seg->lv->name);
    1159                 :            :         else
    1160                 :            :                 /* Bad device removed, but not replaced because of policy */
    1161         [ #  # ]:          0 :                 if (mirrored_seg->area_count == 1) {
    1162                 :          0 :                         log_warn("WARNING: Mirror volume, %s/%s converted to linear due to device failure.",
    1163                 :            :                                   mirrored_seg->lv->vg->name, mirrored_seg->lv->name);
    1164 [ #  # ][ #  # ]:          0 :                 } else if (had_log && !mirrored_seg->log_lv) {
    1165                 :          0 :                         log_warn("WARNING: Mirror volume, %s/%s disk log removed due to device failure.",
    1166                 :            :                                   mirrored_seg->lv->vg->name, mirrored_seg->lv->name);
    1167                 :            :                 }
    1168                 :            :         /*
    1169                 :            :          * If we made it here, we at least removed the bad device.
    1170                 :            :          * Consider this success.
    1171                 :            :          */
    1172                 :          0 :         return 1;
    1173                 :            : }
    1174                 :            : 
    1175                 :          0 : static int _create_mimage_lvs(struct alloc_handle *ah,
    1176                 :            :                               uint32_t num_mirrors,
    1177                 :            :                               uint32_t stripes,
    1178                 :            :                               uint32_t stripe_size,
    1179                 :            :                               struct logical_volume *lv,
    1180                 :            :                               struct logical_volume **img_lvs,
    1181                 :            :                               int log)
    1182                 :            : {
    1183                 :            :         uint32_t m;
    1184                 :            :         char *img_name;
    1185                 :            :         size_t len;
    1186                 :            :         
    1187                 :          0 :         len = strlen(lv->name) + 32;
    1188                 :          0 :         if (!(img_name = alloca(len))) {
    1189                 :            :                 log_error("img_name allocation failed. "
    1190                 :            :                           "Remove new LV and retry.");
    1191                 :            :                 return 0;
    1192                 :            :         }
    1193                 :            : 
    1194         [ #  # ]:          0 :         if (dm_snprintf(img_name, len, "%s_mimage_%%d", lv->name) < 0) {
    1195                 :          0 :                 log_error("img_name allocation failed. "
    1196                 :            :                           "Remove new LV and retry.");
    1197                 :          0 :                 return 0;
    1198                 :            :         }
    1199                 :            : 
    1200         [ #  # ]:          0 :         for (m = 0; m < num_mirrors; m++) {
    1201         [ #  # ]:          0 :                 if (!(img_lvs[m] = lv_create_empty(img_name,
    1202                 :            :                                              NULL, LVM_READ | LVM_WRITE,
    1203                 :            :                                              ALLOC_INHERIT, lv->vg))) {
    1204                 :          0 :                         log_error("Aborting. Failed to create mirror image LV. "
    1205                 :            :                                   "Remove new LV and retry.");
    1206                 :          0 :                         return 0;
    1207                 :            :                 }
    1208                 :            : 
    1209         [ #  # ]:          0 :                 if (log) {
    1210         [ #  # ]:          0 :                         if (!lv_add_log_segment(ah, m * stripes + 1, img_lvs[m], 0)) {
    1211                 :          0 :                                 log_error("Aborting. Failed to add mirror image segment "
    1212                 :            :                                           "to %s. Remove new LV and retry.",
    1213                 :            :                                           img_lvs[m]->name);
    1214                 :          0 :                                 return 0;
    1215                 :            :                         }
    1216                 :            :                 } else {
    1217         [ #  # ]:          0 :                         if (!lv_add_segment(ah, m * stripes, stripes, img_lvs[m],
    1218                 :          0 :                                             get_segtype_from_string(lv->vg->cmd,
    1219                 :            :                                                                     "striped"),
    1220                 :            :                                             stripe_size, 0, 0)) {
    1221                 :          0 :                                 log_error("Aborting. Failed to add mirror image segment "
    1222                 :            :                                           "to %s. Remove new LV and retry.",
    1223                 :            :                                           img_lvs[m]->name);
    1224                 :          0 :                                 return 0;
    1225                 :            :                         }
    1226                 :            :                 }
    1227                 :            :         }
    1228                 :            : 
    1229                 :          0 :         return 1;
    1230                 :            : }
    1231                 :            : 
    1232                 :            : /*
    1233                 :            :  * Remove mirrors from each segment.
    1234                 :            :  * 'new_mirrors' is the number of mirrors after the removal. '0' for linear.
    1235                 :            :  * If 'status_mask' is non-zero, the removal happens only when all segments
    1236                 :            :  * has the status bits on.
    1237                 :            :  */
    1238                 :          0 : int remove_mirrors_from_segments(struct logical_volume *lv,
    1239                 :            :                                  uint32_t new_mirrors, uint64_t status_mask)
    1240                 :            : {
    1241                 :            :         struct lv_segment *seg;
    1242                 :            :         uint32_t s;
    1243                 :            : 
    1244                 :            :         /* Check the segment params are compatible */
    1245         [ #  # ]:          0 :         dm_list_iterate_items(seg, &lv->segments) {
    1246         [ #  # ]:          0 :                 if (!seg_is_mirrored(seg)) {
    1247                 :          0 :                         log_error("Segment is not mirrored: %s:%" PRIu32,
    1248                 :            :                                   lv->name, seg->le);
    1249                 :          0 :                         return 0;
    1250         [ #  # ]:          0 :                 } if ((seg->status & status_mask) != status_mask) {
    1251                 :          0 :                         log_error("Segment status does not match: %s:%" PRIu32
    1252                 :            :                                   " status:0x%" PRIx64 "/0x%" PRIx64, lv->name, seg->le,
    1253                 :            :                                   seg->status, status_mask);
    1254                 :          0 :                         return 0;
    1255                 :            :                 }
    1256                 :            :         }
    1257                 :            : 
    1258                 :            :         /* Convert the segments */
    1259         [ #  # ]:          0 :         dm_list_iterate_items(seg, &lv->segments) {
    1260 [ #  # ][ #  # ]:          0 :                 if (!new_mirrors && seg->extents_copied == seg->area_len) {
    1261         [ #  # ]:          0 :                         if (!move_lv_segment_area(seg, 0, seg, 1))
    1262                 :          0 :                                 return_0;
    1263                 :            :                 }
    1264                 :            : 
    1265         [ #  # ]:          0 :                 for (s = new_mirrors + 1; s < seg->area_count; s++)
    1266                 :          0 :                         release_lv_segment_area(seg, s, seg->area_len);
    1267                 :            : 
    1268                 :          0 :                 seg->area_count = new_mirrors + 1;
    1269                 :            : 
    1270         [ #  # ]:          0 :                 if (!new_mirrors)
    1271                 :          0 :                         seg->segtype = get_segtype_from_string(lv->vg->cmd,
    1272                 :            :                                                                "striped");
    1273                 :            :         }
    1274                 :            : 
    1275                 :          0 :         return 1;
    1276                 :            : }
    1277                 :            : 
    1278                 :          0 : const char *get_pvmove_pvname_from_lv_mirr(struct logical_volume *lv_mirr)
    1279                 :            : {
    1280                 :            :         struct lv_segment *seg;
    1281                 :            : 
    1282         [ #  # ]:          0 :         dm_list_iterate_items(seg, &lv_mirr->segments) {
    1283         [ #  # ]:          0 :                 if (!seg_is_mirrored(seg))
    1284                 :          0 :                         continue;
    1285         [ #  # ]:          0 :                 if (seg_type(seg, 0) != AREA_PV)
    1286                 :          0 :                         continue;
    1287                 :          0 :                 return dev_name(seg_dev(seg, 0));
    1288                 :            :         }
    1289                 :            : 
    1290                 :          0 :         return NULL;
    1291                 :            : }
    1292                 :            : 
    1293                 :          0 : const char *get_pvmove_pvname_from_lv(struct logical_volume *lv)
    1294                 :            : {
    1295                 :            :         struct lv_segment *seg;
    1296                 :            :         uint32_t s;
    1297                 :            : 
    1298         [ #  # ]:          0 :         dm_list_iterate_items(seg, &lv->segments) {
    1299         [ #  # ]:          0 :                 for (s = 0; s < seg->area_count; s++) {
    1300         [ #  # ]:          0 :                         if (seg_type(seg, s) != AREA_LV)
    1301                 :          0 :                                 continue;
    1302                 :          0 :                         return get_pvmove_pvname_from_lv_mirr(seg_lv(seg, s));
    1303                 :            :                 }
    1304                 :            :         }
    1305                 :            : 
    1306                 :          0 :         return NULL;
    1307                 :            : }
    1308                 :            : 
    1309                 :          0 : struct logical_volume *find_pvmove_lv(struct volume_group *vg,
    1310                 :            :                                       struct device *dev,
    1311                 :            :                                       uint32_t lv_type)
    1312                 :            : {
    1313                 :            :         struct lv_list *lvl;
    1314                 :            :         struct logical_volume *lv;
    1315                 :            :         struct lv_segment *seg;
    1316                 :            : 
    1317                 :            :         /* Loop through all LVs */
    1318         [ #  # ]:          0 :         dm_list_iterate_items(lvl, &vg->lvs) {
    1319                 :          0 :                 lv = lvl->lv;
    1320                 :            : 
    1321         [ #  # ]:          0 :                 if (!(lv->status & lv_type))
    1322                 :          0 :                         continue;
    1323                 :            : 
    1324                 :            :                 /* Check segment origins point to pvname */
    1325         [ #  # ]:          0 :                 dm_list_iterate_items(seg, &lv->segments) {
    1326         [ #  # ]:          0 :                         if (seg_type(seg, 0) != AREA_PV)
    1327                 :          0 :                                 continue;
    1328         [ #  # ]:          0 :                         if (seg_dev(seg, 0) != dev)
    1329                 :          0 :                                 continue;
    1330                 :          0 :                         return lv;
    1331                 :            :                 }
    1332                 :            :         }
    1333                 :            : 
    1334                 :          0 :         return NULL;
    1335                 :            : }
    1336                 :            : 
    1337                 :          0 : struct logical_volume *find_pvmove_lv_from_pvname(struct cmd_context *cmd,
    1338                 :            :                                                   struct volume_group *vg,
    1339                 :            :                                                   const char *name,
    1340                 :            :                                                   const char *uuid __attribute((unused)),
    1341                 :            :                                                   uint32_t lv_type)
    1342                 :            : {
    1343                 :            :         struct physical_volume *pv;
    1344                 :            : 
    1345         [ #  # ]:          0 :         if (!(pv = find_pv_by_name(cmd, name)))
    1346                 :          0 :                 return_NULL;
    1347                 :            : 
    1348                 :          0 :         return find_pvmove_lv(vg, pv->dev, lv_type);
    1349                 :            : }
    1350                 :            : 
    1351                 :          0 : struct dm_list *lvs_using_lv(struct cmd_context *cmd, struct volume_group *vg,
    1352                 :            :                           struct logical_volume *lv)
    1353                 :            : {
    1354                 :            :         struct dm_list *lvs;
    1355                 :            :         struct logical_volume *lv1;
    1356                 :            :         struct lv_list *lvl, *lvl1;
    1357                 :            :         struct lv_segment *seg;
    1358                 :            :         uint32_t s;
    1359                 :            : 
    1360         [ #  # ]:          0 :         if (!(lvs = dm_pool_alloc(cmd->mem, sizeof(*lvs)))) {
    1361                 :          0 :                 log_error("lvs list alloc failed");
    1362                 :          0 :                 return NULL;
    1363                 :            :         }
    1364                 :            : 
    1365                 :          0 :         dm_list_init(lvs);
    1366                 :            : 
    1367                 :            :         /* Loop through all LVs except the one supplied */
    1368         [ #  # ]:          0 :         dm_list_iterate_items(lvl1, &vg->lvs) {
    1369                 :          0 :                 lv1 = lvl1->lv;
    1370         [ #  # ]:          0 :                 if (lv1 == lv)
    1371                 :          0 :                         continue;
    1372                 :            : 
    1373                 :            :                 /* Find whether any segment points at the supplied LV */
    1374         [ #  # ]:          0 :                 dm_list_iterate_items(seg, &lv1->segments) {
    1375         [ #  # ]:          0 :                         for (s = 0; s < seg->area_count; s++) {
    1376 [ #  # ][ #  # ]:          0 :                                 if (seg_type(seg, s) != AREA_LV ||
    1377                 :          0 :                                     seg_lv(seg, s) != lv)
    1378                 :          0 :                                         continue;
    1379         [ #  # ]:          0 :                                 if (!(lvl = dm_pool_alloc(cmd->mem, sizeof(*lvl)))) {
    1380                 :          0 :                                         log_error("lv_list alloc failed");
    1381                 :          0 :                                         return NULL;
    1382                 :            :                                 }
    1383                 :          0 :                                 lvl->lv = lv1;
    1384                 :          0 :                                 dm_list_add(lvs, &lvl->list);
    1385                 :          0 :                                 goto next_lv;
    1386                 :            :                         }
    1387                 :            :                 }
    1388                 :            :               next_lv:
    1389                 :            :                 ;
    1390                 :            :         }
    1391                 :            : 
    1392                 :          0 :         return lvs;
    1393                 :            : }
    1394                 :            : 
    1395                 :          0 : float copy_percent(struct logical_volume *lv_mirr,
    1396                 :            :                    percent_range_t *percent_range)
    1397                 :            : {
    1398                 :          0 :         uint32_t numerator = 0u, denominator = 0u;
    1399                 :            :         struct lv_segment *seg;
    1400                 :            : 
    1401         [ #  # ]:          0 :         dm_list_iterate_items(seg, &lv_mirr->segments) {
    1402                 :          0 :                 denominator += seg->area_len;
    1403                 :            : 
    1404 [ #  # ][ #  # ]:          0 :                 if (seg_is_mirrored(seg) && seg->area_count > 1)
    1405                 :          0 :                         numerator += seg->extents_copied;
    1406                 :            :                 else
    1407                 :          0 :                         numerator += seg->area_len;
    1408                 :            :         }
    1409                 :            : 
    1410 [ #  # ][ #  # ]:          0 :         if (!denominator || (numerator == denominator))
    1411                 :          0 :                 *percent_range = PERCENT_100;
    1412         [ #  # ]:          0 :         else if (numerator == 0)
    1413                 :          0 :                 *percent_range = PERCENT_0;
    1414                 :            :         else
    1415                 :          0 :                 *percent_range = PERCENT_0_TO_100;
    1416                 :            :                 
    1417         [ #  # ]:          0 :         return denominator ? (float) numerator *100 / denominator : 100.0;
    1418                 :            : }
    1419                 :            : 
    1420                 :            : /*
    1421                 :            :  * Fixup mirror pointers after single-pass segment import
    1422                 :            :  */
    1423                 :          0 : int fixup_imported_mirrors(struct volume_group *vg)
    1424                 :            : {
    1425                 :            :         struct lv_list *lvl;
    1426                 :            :         struct lv_segment *seg;
    1427                 :            : 
    1428         [ #  # ]:          0 :         dm_list_iterate_items(lvl, &vg->lvs) {
    1429         [ #  # ]:          0 :                 dm_list_iterate_items(seg, &lvl->lv->segments) {
    1430         [ #  # ]:          0 :                         if (seg->segtype !=
    1431                 :            :                             get_segtype_from_string(vg->cmd, "mirror"))
    1432                 :          0 :                                 continue;
    1433                 :            : 
    1434 [ #  # ][ #  # ]:          0 :                         if (seg->log_lv && !add_seg_to_segs_using_this_lv(seg->log_lv, seg))
    1435                 :          0 :                                 return_0;
    1436                 :            :                 }
    1437                 :            :         }
    1438                 :            : 
    1439                 :          0 :         return 1;
    1440                 :            : }
    1441                 :            : 
    1442                 :            : /*
    1443                 :            :  * Add mirrors to "linear" or "mirror" segments
    1444                 :            :  */
    1445                 :          0 : int add_mirrors_to_segments(struct cmd_context *cmd, struct logical_volume *lv,
    1446                 :            :                             uint32_t mirrors, uint32_t region_size,
    1447                 :            :                             struct dm_list *allocatable_pvs, alloc_policy_t alloc)
    1448                 :            : {
    1449                 :            :         struct alloc_handle *ah;
    1450                 :            :         const struct segment_type *segtype;
    1451                 :            :         struct dm_list *parallel_areas;
    1452                 :            :         uint32_t adjusted_region_size;
    1453                 :          0 :         int r = 1;
    1454                 :            : 
    1455         [ #  # ]:          0 :         if (!(parallel_areas = build_parallel_areas_from_lv(cmd, lv, 1)))
    1456                 :          0 :                 return_0;
    1457                 :            : 
    1458         [ #  # ]:          0 :         if (!(segtype = get_segtype_from_string(cmd, "mirror")))
    1459                 :          0 :                 return_0;
    1460                 :            : 
    1461                 :          0 :         adjusted_region_size = adjusted_mirror_region_size(lv->vg->extent_size,
    1462                 :            :                                                            lv->le_count,
    1463                 :            :                                                            region_size);
    1464                 :            : 
    1465         [ #  # ]:          0 :         if (!(ah = allocate_extents(lv->vg, NULL, segtype, 1, mirrors, 0, 0,
    1466                 :            :                                     lv->le_count, allocatable_pvs, alloc,
    1467                 :            :                                     parallel_areas))) {
    1468                 :          0 :                 log_error("Unable to allocate mirror extents for %s.", lv->name);
    1469                 :          0 :                 return 0;
    1470                 :            :         }
    1471                 :            : 
    1472         [ #  # ]:          0 :         if (!lv_add_mirror_areas(ah, lv, 0, adjusted_region_size)) {
    1473                 :          0 :                 log_error("Failed to add mirror areas to %s", lv->name);
    1474                 :          0 :                 r = 0;
    1475                 :            :         }
    1476                 :            : 
    1477                 :          0 :         alloc_destroy(ah);
    1478                 :          0 :         return r;
    1479                 :            : }
    1480                 :            : 
    1481                 :            : /*
    1482                 :            :  * Convert mirror log
    1483                 :            :  *
    1484                 :            :  * FIXME: Can't handle segment-by-segment mirror (like pvmove)
    1485                 :            :  */
    1486                 :          0 : int remove_mirror_log(struct cmd_context *cmd,
    1487                 :            :                       struct logical_volume *lv,
    1488                 :            :                       struct dm_list *removable_pvs)
    1489                 :            : {
    1490                 :            :         float sync_percent;
    1491                 :          0 :         percent_range_t percent_range = PERCENT_0;
    1492                 :            :         struct lvinfo info;
    1493                 :          0 :         struct volume_group *vg = lv->vg;
    1494                 :            : 
    1495                 :            :         /* Unimplemented features */
    1496         [ #  # ]:          0 :         if (dm_list_size(&lv->segments) != 1) {
    1497                 :          0 :                 log_error("Multiple-segment mirror is not supported");
    1498                 :          0 :                 return 0;
    1499                 :            :         }
    1500                 :            : 
    1501                 :            :         /* Had disk log, switch to core. */
    1502 [ #  # ][ #  # ]:          0 :         if (lv_info(cmd, lv, &info, 0, 0) && info.exists) {
    1503         [ #  # ]:          0 :                 if (!lv_mirror_percent(cmd, lv, 0, &sync_percent,
    1504                 :            :                                        &percent_range, NULL)) {
    1505                 :          0 :                         log_error("Unable to determine mirror sync status.");
    1506                 :          0 :                         return 0;
    1507                 :            :                 }
    1508         [ #  # ]:          0 :         } else if (vg_is_clustered(vg)) {
    1509                 :          0 :                 log_error("Unable to convert the log of an inactive "
    1510                 :            :                           "cluster mirror, %s", lv->name);
    1511                 :          0 :                 return 0;
    1512         [ #  # ]:          0 :         } else if (yes_no_prompt("Full resync required to convert "
    1513                 :            :                                  "inactive mirror %s to core log. "
    1514                 :            :                                  "Proceed? [y/n]: ") == 'y')
    1515                 :          0 :                 sync_percent = 0;
    1516                 :            :         else
    1517                 :          0 :                 return 0;
    1518                 :            : 
    1519         [ #  # ]:          0 :         if (percent_range == PERCENT_100)
    1520                 :          0 :                 init_mirror_in_sync(1);
    1521                 :            :         else {
    1522                 :            :                 /* A full resync will take place */
    1523                 :          0 :                 lv->status &= ~MIRROR_NOTSYNCED;
    1524                 :          0 :                 init_mirror_in_sync(0);
    1525                 :            :         }
    1526                 :            : 
    1527         [ #  # ]:          0 :         if (!remove_mirror_images(lv, lv_mirror_count(lv),
    1528                 :            :                                   removable_pvs, 1U))
    1529                 :          0 :                 return_0;
    1530                 :            : 
    1531                 :          0 :         return 1;
    1532                 :            : }
    1533                 :            : 
    1534                 :          0 : static struct logical_volume *_create_mirror_log(struct logical_volume *lv,
    1535                 :            :                                                  struct alloc_handle *ah,
    1536                 :            :                                                  alloc_policy_t alloc,
    1537                 :            :                                                  const char *lv_name,
    1538                 :            :                                                  const char *suffix)
    1539                 :            : {
    1540                 :            :         struct logical_volume *log_lv;
    1541                 :            :         char *log_name;
    1542                 :            :         size_t len;
    1543                 :            : 
    1544                 :          0 :         len = strlen(lv_name) + 32;
    1545                 :          0 :         if (!(log_name = alloca(len))) {
    1546                 :            :                 log_error("log_name allocation failed.");
    1547                 :            :                 return NULL;
    1548                 :            :         }
    1549                 :            : 
    1550         [ #  # ]:          0 :         if (dm_snprintf(log_name, len, "%s%s", lv_name, suffix) < 0) {
    1551                 :          0 :                 log_error("log_name allocation failed.");
    1552                 :          0 :                 return NULL;
    1553                 :            :         }
    1554                 :            : 
    1555         [ #  # ]:          0 :         if (!(log_lv = lv_create_empty(log_name, NULL,
    1556                 :            :                                        VISIBLE_LV | LVM_READ | LVM_WRITE,
    1557                 :            :                                        alloc, lv->vg)))
    1558                 :          0 :                 return_NULL;
    1559                 :            : 
    1560         [ #  # ]:          0 :         if (!lv_add_log_segment(ah, 0, log_lv, MIRROR_LOG))
    1561                 :          0 :                 return_NULL;
    1562                 :            : 
    1563                 :          0 :         return log_lv;
    1564                 :            : }
    1565                 :            : 
    1566                 :            : /*
    1567                 :            :  * Returns: 1 on success, 0 on error
    1568                 :            :  */
    1569                 :          0 : static int _form_mirror(struct cmd_context *cmd, struct alloc_handle *ah,
    1570                 :            :                         struct logical_volume *lv,
    1571                 :            :                         uint32_t mirrors, uint32_t stripes,
    1572                 :            :                         uint32_t stripe_size, uint32_t region_size, int log)
    1573                 :            : {
    1574                 :            :         struct logical_volume **img_lvs;
    1575                 :            : 
    1576                 :            :         /*
    1577                 :            :          * insert a mirror layer
    1578                 :            :          */
    1579   [ #  #  #  # ]:          0 :         if (dm_list_size(&lv->segments) != 1 ||
    1580                 :          0 :             seg_type(first_seg(lv), 0) != AREA_LV)
    1581         [ #  # ]:          0 :                 if (!insert_layer_for_lv(cmd, lv, 0, "_mimage_%d"))
    1582                 :          0 :                         return 0;
    1583                 :            : 
    1584                 :            :         /*
    1585                 :            :          * create mirror image LVs
    1586                 :            :          */
    1587                 :          0 :         if (!(img_lvs = alloca(sizeof(*img_lvs) * mirrors))) {
    1588                 :            :                 log_error("img_lvs allocation failed. "
    1589                 :            :                           "Remove new LV and retry.");
    1590                 :            :                 return 0;
    1591                 :            :         }
    1592                 :            : 
    1593         [ #  # ]:          0 :         if (!_create_mimage_lvs(ah, mirrors, stripes, stripe_size, lv, img_lvs, log))
    1594                 :          0 :                 return 0;
    1595                 :            : 
    1596         [ #  # ]:          0 :         if (!lv_add_mirror_lvs(lv, img_lvs, mirrors,
    1597                 :          0 :                                MIRROR_IMAGE | (lv->status & LOCKED),
    1598                 :            :                                region_size)) {
    1599                 :          0 :                 log_error("Aborting. Failed to add mirror segment. "
    1600                 :            :                           "Remove new LV and retry.");
    1601                 :          0 :                 return 0;
    1602                 :            :         }
    1603                 :            : 
    1604                 :          0 :         return 1;
    1605                 :            : }
    1606                 :            : 
    1607                 :          0 : static struct logical_volume *_set_up_mirror_log(struct cmd_context *cmd,
    1608                 :            :                                                  struct alloc_handle *ah,
    1609                 :            :                                                  struct logical_volume *lv,
    1610                 :            :                                                  uint32_t log_count,
    1611                 :            :                                                  uint32_t region_size,
    1612                 :            :                                                  alloc_policy_t alloc,
    1613                 :            :                                                  int in_sync)
    1614                 :            : {
    1615                 :            :         struct logical_volume *log_lv;
    1616                 :            :         const char *suffix, *c;
    1617                 :            :         char *lv_name;
    1618                 :            :         size_t len;
    1619                 :            :         struct lv_segment *seg;
    1620                 :            : 
    1621                 :          0 :         init_mirror_in_sync(in_sync);
    1622                 :            : 
    1623                 :            :         /* Mirror log name is lv_name + suffix, determined as the following:
    1624                 :            :          *   1. suffix is:
    1625                 :            :          *        o "_mlog" for the original mirror LV.
    1626                 :            :          *        o "_mlogtmp_%d" for temporary mirror LV,
    1627                 :            :          *   2. lv_name is:
    1628                 :            :          *        o lv->name, if the log is temporary
    1629                 :            :          *        o otherwise, the top-level LV name
    1630                 :            :          */
    1631                 :          0 :         seg = first_seg(lv);
    1632   [ #  #  #  # ]:          0 :         if (seg_type(seg, 0) == AREA_LV &&
    1633                 :          0 :             strstr(seg_lv(seg, 0)->name, MIRROR_SYNC_LAYER)) {
    1634                 :          0 :                 lv_name = lv->name;
    1635                 :          0 :                 suffix = "_mlogtmp_%d";
    1636         [ #  # ]:          0 :         } else if ((c = strstr(lv->name, MIRROR_SYNC_LAYER))) {
    1637                 :          0 :                 len = c - lv->name + 1;
    1638         [ #  # ]:          0 :                 if (!(lv_name = alloca(len)) ||
    1639                 :          0 :                     !dm_snprintf(lv_name, len, "%s", lv->name)) {
    1640                 :          0 :                         log_error("mirror log name allocation failed");
    1641                 :          0 :                         return 0;
    1642                 :            :                 }
    1643                 :          0 :                 suffix = "_mlog";
    1644                 :            :         } else {
    1645                 :          0 :                 lv_name = lv->name;
    1646                 :          0 :                 suffix = "_mlog";
    1647                 :            :         }
    1648                 :            : 
    1649         [ #  # ]:          0 :         if (!(log_lv = _create_mirror_log(lv, ah, alloc,
    1650                 :            :                                           (const char *) lv_name, suffix))) {
    1651                 :          0 :                 log_error("Failed to create mirror log.");
    1652                 :          0 :                 return NULL;
    1653                 :            :         }
    1654                 :            : 
    1655   [ #  #  #  # ]:          0 :         if ((log_count > 1) &&
    1656                 :          0 :             !_form_mirror(cmd, ah, log_lv, log_count-1, 1, 0, region_size, 1)) {
    1657                 :          0 :                 log_error("Failed to form mirrored log.");
    1658                 :          0 :                 return NULL;
    1659                 :            :         }
    1660                 :            : 
    1661         [ #  # ]:          0 :         if (!_init_mirror_log(cmd, log_lv, in_sync, &lv->tags, 1)) {
    1662                 :          0 :                 log_error("Failed to initialise mirror log.");
    1663                 :          0 :                 return NULL;
    1664                 :            :         }
    1665                 :            : 
    1666                 :          0 :         return log_lv;
    1667                 :            : }
    1668                 :            : 
    1669                 :          0 : int attach_mirror_log(struct lv_segment *seg, struct logical_volume *log_lv)
    1670                 :            : {
    1671                 :          0 :         seg->log_lv = log_lv;
    1672                 :          0 :         log_lv->status |= MIRROR_LOG;
    1673                 :          0 :         lv_set_hidden(log_lv);
    1674                 :          0 :         return add_seg_to_segs_using_this_lv(log_lv, seg);
    1675                 :            : }
    1676                 :            : 
    1677                 :          0 : int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
    1678                 :            :                    uint32_t log_count, uint32_t region_size,
    1679                 :            :                    struct dm_list *allocatable_pvs, alloc_policy_t alloc)
    1680                 :            : {
    1681                 :            :         struct alloc_handle *ah;
    1682                 :            :         const struct segment_type *segtype;
    1683                 :            :         struct dm_list *parallel_areas;
    1684                 :            :         float sync_percent;
    1685                 :            :         percent_range_t percent_range;
    1686                 :            :         int in_sync;
    1687                 :            :         struct logical_volume *log_lv;
    1688                 :            :         struct lvinfo info;
    1689                 :          0 :         int r = 0;
    1690                 :            : 
    1691         [ #  # ]:          0 :         if (dm_list_size(&lv->segments) != 1) {
    1692                 :          0 :                 log_error("Multiple-segment mirror is not supported");
    1693                 :          0 :                 return 0;
    1694                 :            :         }
    1695                 :            : 
    1696                 :            :         /*
    1697                 :            :          * We are unable to convert the log of inactive cluster mirrors
    1698                 :            :          * due to the inability to detect whether the mirror is active
    1699                 :            :          * on remote nodes (even though it is inactive on this node)
    1700                 :            :          */
    1701 [ #  # ][ #  # ]:          0 :         if (vg_is_clustered(lv->vg) &&
                 [ #  # ]
    1702                 :            :             !(lv_info(cmd, lv, &info, 0, 0) && info.exists)) {
    1703                 :          0 :                 log_error("Unable to convert the log of inactive "
    1704                 :            :                           "cluster mirror %s", lv->name);
    1705                 :          0 :                 return 0;
    1706                 :            :         }
    1707                 :            : 
    1708         [ #  # ]:          0 :         if (!(parallel_areas = build_parallel_areas_from_lv(cmd, lv, 0)))
    1709                 :          0 :                 return_0;
    1710                 :            : 
    1711         [ #  # ]:          0 :         if (!(segtype = get_segtype_from_string(cmd, "mirror")))
    1712                 :          0 :                 return_0;
    1713                 :            : 
    1714         [ #  # ]:          0 :         if (activation() && segtype->ops->target_present &&
           [ #  #  #  # ]
    1715                 :          0 :             !segtype->ops->target_present(cmd, NULL, NULL)) {
    1716                 :          0 :                 log_error("%s: Required device-mapper target(s) not "
    1717                 :            :                           "detected in your kernel", segtype->name);
    1718                 :          0 :                 return 0;
    1719                 :            :         }
    1720                 :            : 
    1721                 :            :         /* allocate destination extents */
    1722                 :          0 :         ah = allocate_extents(lv->vg, NULL, segtype,
    1723                 :            :                               0, 0, log_count, region_size, 0,
    1724                 :            :                               allocatable_pvs, alloc, parallel_areas);
    1725         [ #  # ]:          0 :         if (!ah) {
    1726                 :          0 :                 log_error("Unable to allocate extents for mirror log.");
    1727                 :          0 :                 return 0;
    1728                 :            :         }
    1729                 :            : 
    1730                 :            :         /* check sync status */
    1731   [ #  #  #  # ]:          0 :         if (lv_mirror_percent(cmd, lv, 0, &sync_percent, &percent_range,
    1732                 :          0 :                               NULL) &&
    1733                 :          0 :             (percent_range == PERCENT_100))
    1734                 :          0 :                 in_sync = 1;
    1735                 :            :         else
    1736                 :          0 :                 in_sync = 0;
    1737                 :            : 
    1738         [ #  # ]:          0 :         if (!(log_lv = _set_up_mirror_log(cmd, ah, lv, log_count,
    1739                 :            :                                           region_size, alloc, in_sync)))
    1740                 :          0 :                 goto_out;
    1741                 :            : 
    1742         [ #  # ]:          0 :         if (!attach_mirror_log(first_seg(lv), log_lv))
    1743                 :          0 :                 goto_out;
    1744                 :            : 
    1745                 :          0 :         r = 1;
    1746                 :            : out:
    1747                 :          0 :         alloc_destroy(ah);
    1748                 :          0 :         return r;
    1749                 :            : }
    1750                 :            : 
    1751                 :            : /*
    1752                 :            :  * Convert "linear" LV to "mirror".
    1753                 :            :  */
    1754                 :          0 : int add_mirror_images(struct cmd_context *cmd, struct logical_volume *lv,
    1755                 :            :                       uint32_t mirrors, uint32_t stripes,
    1756                 :            :                       uint32_t stripe_size, uint32_t region_size,
    1757                 :            :                       struct dm_list *allocatable_pvs, alloc_policy_t alloc,
    1758                 :            :                       uint32_t log_count)
    1759                 :            : {
    1760                 :            :         struct alloc_handle *ah;
    1761                 :            :         const struct segment_type *segtype;
    1762                 :            :         struct dm_list *parallel_areas;
    1763                 :          0 :         struct logical_volume *log_lv = NULL;
    1764                 :            : 
    1765                 :            :         /*
    1766                 :            :          * allocate destination extents
    1767                 :            :          */
    1768                 :            : 
    1769         [ #  # ]:          0 :         if (!(parallel_areas = build_parallel_areas_from_lv(cmd, lv, 0)))
    1770                 :          0 :                 return_0;
    1771                 :            : 
    1772         [ #  # ]:          0 :         if (!(segtype = get_segtype_from_string(cmd, "mirror")))
    1773                 :          0 :                 return_0;
    1774                 :            : 
    1775                 :          0 :         ah = allocate_extents(lv->vg, NULL, segtype,
    1776                 :            :                               stripes, mirrors, log_count, region_size, lv->le_count,
    1777                 :            :                               allocatable_pvs, alloc, parallel_areas);
    1778         [ #  # ]:          0 :         if (!ah) {
    1779                 :          0 :                 log_error("Unable to allocate extents for mirror(s).");
    1780                 :          0 :                 return 0;
    1781                 :            :         }
    1782                 :            : 
    1783                 :            :         /*
    1784                 :            :          * create and initialize mirror log
    1785                 :            :          */
    1786   [ #  #  #  # ]:          0 :         if (log_count &&
    1787                 :          0 :             !(log_lv = _set_up_mirror_log(cmd, ah, lv, log_count, region_size,
    1788                 :            :                                           alloc, mirror_in_sync()))) {
    1789                 :          0 :                 stack;
    1790                 :          0 :                 goto out_remove_images;
    1791                 :            :         }
    1792                 :            : 
    1793                 :            :         /* The log initialization involves vg metadata commit.
    1794                 :            :            So from here on, if failure occurs, the log must be explicitly
    1795                 :            :            removed and the updated vg metadata should be committed. */
    1796                 :            : 
    1797         [ #  # ]:          0 :         if (!_form_mirror(cmd, ah, lv, mirrors, stripes, stripe_size, region_size, 0))
    1798                 :          0 :                 goto out_remove_log;
    1799                 :            : 
    1800 [ #  # ][ #  # ]:          0 :         if (log_count && !attach_mirror_log(first_seg(lv), log_lv))
    1801                 :          0 :                 stack;
    1802                 :            : 
    1803                 :          0 :         alloc_destroy(ah);
    1804                 :          0 :         return 1;
    1805                 :            : 
    1806                 :            :   out_remove_log:
    1807         [ #  # ]:          0 :         if (log_lv) {
    1808 [ #  #  #  #  # :          0 :                 if (!lv_remove(log_lv) ||
                      # ]
    1809                 :          0 :                     !vg_write(log_lv->vg) ||
    1810                 :          0 :                     !vg_commit(log_lv->vg))
    1811                 :          0 :                         log_error("Manual intervention may be required to remove "
    1812                 :            :                                   "abandoned log LV before retrying.");
    1813                 :            :                 else
    1814                 :          0 :                         backup(log_lv->vg);
    1815                 :            :         }
    1816                 :            :   out_remove_images:
    1817                 :          0 :         alloc_destroy(ah);
    1818                 :          0 :         return 0;
    1819                 :            : }
    1820                 :            : 
    1821                 :            : /*
    1822                 :            :  * Generic interface for adding mirror and/or mirror log.
    1823                 :            :  * 'mirror' is the number of mirrors to be added.
    1824                 :            :  * 'pvs' is either allocatable pvs.
    1825                 :            :  */
    1826                 :          0 : int lv_add_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
    1827                 :            :                    uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
    1828                 :            :                    uint32_t region_size, uint32_t log_count,
    1829                 :            :                    struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags)
    1830                 :            : {
    1831 [ #  # ][ #  # ]:          0 :         if (!mirrors && !log_count) {
    1832                 :          0 :                 log_error("No conversion is requested");
    1833                 :          0 :                 return 0;
    1834                 :            :         }
    1835                 :            : 
    1836                 :            :         /* For corelog mirror, activation code depends on
    1837                 :            :          * the global mirror_in_sync status. As we are adding
    1838                 :            :          * a new mirror, it should be set as 'out-of-sync'
    1839                 :            :          * so that the sync starts. */
    1840                 :            :         /* However, MIRROR_SKIP_INIT_SYNC even overrides it. */
    1841         [ #  # ]:          0 :         if (flags & MIRROR_SKIP_INIT_SYNC)
    1842                 :          0 :                 init_mirror_in_sync(1);
    1843         [ #  # ]:          0 :         else if (!log_count)
    1844                 :          0 :                 init_mirror_in_sync(0);
    1845                 :            : 
    1846         [ #  # ]:          0 :         if (flags & MIRROR_BY_SEG) {
    1847         [ #  # ]:          0 :                 if (log_count) {
    1848                 :          0 :                         log_error("Persistent log is not supported on "
    1849                 :            :                                   "segment-by-segment mirroring");
    1850                 :          0 :                         return 0;
    1851                 :            :                 }
    1852         [ #  # ]:          0 :                 if (stripes > 1) {
    1853                 :          0 :                         log_error("Striped-mirroring is not supported on "
    1854                 :            :                                   "segment-by-segment mirroring");
    1855                 :          0 :                         return 0;
    1856                 :            :                 }
    1857                 :            : 
    1858                 :          0 :                 return add_mirrors_to_segments(cmd, lv, mirrors,
    1859                 :            :                                                region_size, pvs, alloc);
    1860         [ #  # ]:          0 :         } else if (flags & MIRROR_BY_LV) {
    1861         [ #  # ]:          0 :                 if (!mirrors)
    1862                 :          0 :                         return add_mirror_log(cmd, lv, log_count,
    1863                 :            :                                               region_size, pvs, alloc);
    1864                 :          0 :                 return add_mirror_images(cmd, lv, mirrors,
    1865                 :            :                                          stripes, stripe_size, region_size,
    1866                 :            :                                          pvs, alloc, log_count);
    1867                 :            :         }
    1868                 :            : 
    1869                 :          0 :         log_error("Unsupported mirror conversion type");
    1870                 :          0 :         return 0;
    1871                 :            : }
    1872                 :            : 
    1873                 :          0 : int lv_split_mirror_images(struct logical_volume *lv, const char *split_name,
    1874                 :            :                            uint32_t split_count, struct dm_list *removable_pvs)
    1875                 :            : {
    1876                 :            :         int r;
    1877                 :            : 
    1878                 :            :         /* Can't split a mirror that is not in-sync... unless force? */
    1879         [ #  # ]:          0 :         if (!_mirrored_lv_in_sync(lv)) {
    1880                 :          0 :                 log_error("Unable to split mirror that is not in-sync.");
    1881                 :          0 :                 return_0;
    1882                 :            :         }
    1883                 :            : 
    1884                 :            :         /*
    1885                 :            :          * FIXME: Generate default name when not supplied.
    1886                 :            :          *
    1887                 :            :          * If we were going to generate a default name, we would
    1888                 :            :          * do it here.  Better to wait for a decision on the form
    1889                 :            :          * of the default name when '--track_deltas' (the ability
    1890                 :            :          * to merge a split leg back in and only copy the changes)
    1891                 :            :          * is being implemented.  For now, we force the user to
    1892                 :            :          * come up with a name for their LV.
    1893                 :            :          */
    1894                 :          0 :         r = _split_mirror_images(lv, split_name, split_count, removable_pvs);
    1895         [ #  # ]:          0 :         if (!r)
    1896                 :          0 :                 return 0;
    1897                 :            : 
    1898                 :          0 :         return 1;
    1899                 :            : }
    1900                 :            : 
    1901                 :            : /*
    1902                 :            :  * Generic interface for removing mirror and/or mirror log.
    1903                 :            :  * 'mirror' is the number of mirrors to be removed.
    1904                 :            :  * 'pvs' is removable pvs.
    1905                 :            :  */
    1906                 :          0 : int lv_remove_mirrors(struct cmd_context *cmd __attribute((unused)),
    1907                 :            :                       struct logical_volume *lv,
    1908                 :            :                       uint32_t mirrors, uint32_t log_count, struct dm_list *pvs,
    1909                 :            :                       uint64_t status_mask)
    1910                 :            : {
    1911                 :            :         uint32_t new_mirrors;
    1912                 :            :         struct lv_segment *seg;
    1913                 :            : 
    1914 [ #  # ][ #  # ]:          0 :         if (!mirrors && !log_count) {
    1915                 :          0 :                 log_error("No conversion is requested");
    1916                 :          0 :                 return 0;
    1917                 :            :         }
    1918                 :            : 
    1919                 :          0 :         seg = first_seg(lv);
    1920         [ #  # ]:          0 :         if (!seg_is_mirrored(seg)) {
    1921                 :          0 :                 log_error("Not a mirror segment");
    1922                 :          0 :                 return 0;
    1923                 :            :         }
    1924                 :            : 
    1925         [ #  # ]:          0 :         if (lv_mirror_count(lv) <= mirrors) {
    1926                 :          0 :                 log_error("Removing more than existing: %d <= %d",
    1927                 :            :                           seg->area_count, mirrors);
    1928                 :          0 :                 return 0;
    1929                 :            :         }
    1930                 :          0 :         new_mirrors = lv_mirror_count(lv) - mirrors - 1;
    1931                 :            : 
    1932                 :            :         /* MIRROR_BY_LV */
    1933   [ #  #  #  # ]:          0 :         if (seg_type(seg, 0) == AREA_LV &&
    1934                 :          0 :             seg_lv(seg, 0)->status & MIRROR_IMAGE)
    1935         [ #  # ]:          0 :                 return remove_mirror_images(lv, new_mirrors + 1,
    1936                 :            :                                             pvs, log_count ? 1U : 0);
    1937                 :            : 
    1938                 :            :         /* MIRROR_BY_SEG */
    1939         [ #  # ]:          0 :         if (log_count) {
    1940                 :          0 :                 log_error("Persistent log is not supported on "
    1941                 :            :                           "segment-by-segment mirroring");
    1942                 :          0 :                 return 0;
    1943                 :            :         }
    1944                 :          0 :         return remove_mirrors_from_segments(lv, new_mirrors, status_mask);
    1945                 :            : }
    1946                 :            : 

Generated by: LCOV version 1.8