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

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2009-2010 Red Hat, Inc. All rights reserved.
       3                 :            :  *
       4                 :            :  * This file is part of LVM2.
       5                 :            :  *
       6                 :            :  * This copyrighted material is made available to anyone wishing to use,
       7                 :            :  * modify, copy, or redistribute it subject to the terms and conditions
       8                 :            :  * of the GNU Lesser General Public License v.2.1.
       9                 :            :  *
      10                 :            :  * You should have received a copy of the GNU Lesser General Public License
      11                 :            :  * along with this program; if not, write to the Free Software Foundation,
      12                 :            :  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      13                 :            :  */
      14                 :            : 
      15                 :            : #include <inttypes.h>
      16                 :            : #include <sys/types.h>
      17                 :            : #include "libdevmapper.h"
      18                 :            : #include "lvm-types.h"
      19                 :            : 
      20                 :            : #include "activate.h"
      21                 :            : #include "archiver.h"
      22                 :            : #include "defaults.h"
      23                 :            : #include "label.h"
      24                 :            : #include "lib.h"
      25                 :            : #include "locking.h"
      26                 :            : #include "lv_alloc.h"
      27                 :            : #include "lvm-string.h"
      28                 :            : #include "metadata.h"
      29                 :            : #include "segtype.h"
      30                 :            : #include "str_list.h"
      31                 :            : #include "toolcontext.h"
      32                 :            : 
      33                 :            : /* Add lv as replicator_dev device */
      34                 :          0 : int replicator_dev_add_rimage(struct replicator_device *rdev,
      35                 :            :                               struct logical_volume *lv)
      36                 :            : {
      37 [ #  # ][ #  # ]:          0 :         if (!lv || !rdev)
      38                 :          0 :                 return_0;
      39                 :          0 :         log_verbose("try add_rimage");
      40                 :            : 
      41         [ #  # ]:          0 :         if (lv_is_rimage(lv)) {
      42                 :          0 :                 log_error("Logical volume %s is already part of other "
      43                 :            :                           "replicator.", lv->name);
      44                 :          0 :                 return 0;
      45                 :            :         }
      46                 :            : 
      47         [ #  # ]:          0 :         if (rdev->lv) {
      48                 :          0 :                 log_error("Logical volume %s can not be attached to an "
      49                 :            :                           "already defined replicator_device", lv->name);
      50                 :          0 :                 return 0;
      51                 :            :         }
      52                 :            : 
      53                 :          0 :         lv_set_hidden(lv);
      54                 :          0 :         lv->rdevice = rdev;
      55                 :          0 :         rdev->lv = lv;
      56                 :            : 
      57                 :          0 :         return add_seg_to_segs_using_this_lv(lv, rdev->replicator_dev);
      58                 :            : }
      59                 :            : 
      60                 :            : /* Remove lv from replicator_dev device */
      61                 :          0 : struct logical_volume *replicator_dev_remove_rimage(struct replicator_device *rdev)
      62                 :            : {
      63                 :            :         struct logical_volume *lv;
      64                 :            : 
      65 [ #  # ][ #  # ]:          0 :         if (!rdev || !rdev->lv)
      66                 :          0 :                 return_NULL;
      67                 :            : 
      68                 :          0 :         lv = rdev->lv;
      69         [ #  # ]:          0 :         if (!remove_seg_from_segs_using_this_lv(lv, rdev->replicator_dev))
      70                 :          0 :                 return_NULL;
      71                 :            : 
      72                 :            :         /* FIXME: - check for site references */
      73                 :          0 :         rdev->lv = NULL;
      74                 :          0 :         lv->rdevice = NULL;
      75                 :          0 :         lv_set_visible(lv);
      76                 :            : 
      77                 :          0 :         return lv;
      78                 :            : }
      79                 :            : 
      80                 :          0 : int replicator_dev_add_slog(struct replicator_device *rdev,
      81                 :            :                             struct logical_volume *slog)
      82                 :            : {
      83 [ #  # ][ #  # ]:          0 :         if (!slog || !rdev)
      84                 :          0 :                 return_0;
      85                 :            : 
      86         [ #  # ]:          0 :         if (rdev->slog) {
      87                 :          0 :                 log_error("Replicator device in site %s already has sync log.",
      88                 :            :                           rdev->rsite->name);
      89                 :          0 :                 return 0;
      90                 :            :         }
      91                 :            : 
      92         [ #  # ]:          0 :         if (slog->rdevice) {
      93                 :          0 :                 log_error("Sync log %s is already used by replicator %s.",
      94                 :            :                           slog->name, slog->rdevice->rsite->replicator->name);
      95                 :          0 :                 return 0;
      96                 :            :         }
      97                 :            : 
      98                 :          0 :         lv_set_hidden(slog);
      99                 :          0 :         slog->rdevice = rdev;
     100                 :          0 :         rdev->slog = slog;
     101                 :            : 
     102                 :          0 :         return add_seg_to_segs_using_this_lv(slog, rdev->replicator_dev);
     103                 :            : }
     104                 :            : 
     105                 :          0 : struct logical_volume *replicator_dev_remove_slog(struct replicator_device *rdev)
     106                 :            : {
     107                 :            :         struct logical_volume *lv;
     108                 :            : 
     109         [ #  # ]:          0 :         if (!rdev)
     110                 :          0 :                 return_NULL;
     111                 :            : 
     112                 :          0 :         lv = rdev->slog;
     113         [ #  # ]:          0 :         if (!lv) {
     114                 :          0 :                 log_error("Replicator device in site %s does not have sync log.",
     115                 :            :                           rdev->rsite->name);
     116                 :          0 :                 return NULL;
     117                 :            :         }
     118                 :            : 
     119         [ #  # ]:          0 :         if (!remove_seg_from_segs_using_this_lv(lv, rdev->replicator_dev))
     120                 :          0 :                 return_NULL;
     121                 :            : 
     122                 :          0 :         rdev->slog = NULL;
     123                 :          0 :         lv->rdevice = NULL;
     124                 :          0 :         lv_set_visible(lv);
     125                 :            : 
     126                 :          0 :         return lv;
     127                 :            : }
     128                 :            : 
     129                 :          0 : int replicator_add_replicator_dev(struct logical_volume *replicator_lv,
     130                 :            :                                   struct lv_segment *replicator_dev_seg)
     131                 :            : {
     132         [ #  # ]:          0 :         if (!replicator_lv)
     133                 :          0 :                 return_0;
     134                 :            : 
     135         [ #  # ]:          0 :         if (!(replicator_lv->status & REPLICATOR)) {
     136                 :          0 :                 dm_list_init(&replicator_lv->rsites);
     137                 :          0 :                 lv_set_hidden(replicator_lv);
     138                 :          0 :                 replicator_lv->status |= REPLICATOR;
     139                 :            :         }
     140                 :            : 
     141         [ #  # ]:          0 :         if (!replicator_dev_seg)
     142                 :          0 :                 return 1;
     143                 :            : 
     144         [ #  # ]:          0 :         if (replicator_dev_seg->replicator) {
     145                 :          0 :                 log_error("Replicator device %s is already part of replicator.",
     146                 :            :                           replicator_dev_seg->lv->name);
     147                 :          0 :                 return 0;
     148                 :            :         }
     149                 :            : 
     150                 :          0 :         replicator_dev_seg->replicator = replicator_lv;
     151                 :            : 
     152                 :          0 :         return add_seg_to_segs_using_this_lv(replicator_lv, replicator_dev_seg);
     153                 :            : }
     154                 :            : 
     155                 :            : /**
     156                 :            :  * Returns rimage ?? lv upon succeful detach of device
     157                 :            :  * entire LV entry should be removed by this crootall ??
     158                 :            :  */
     159                 :          0 : struct logical_volume *replicator_remove_replicator_dev(struct lv_segment *replicator_dev_seg)
     160                 :            : {
     161                 :          0 :         struct logical_volume *lv = NULL;
     162                 :            : 
     163                 :          0 :         log_error("FIXME: not implemented.");
     164                 :            : #if 0
     165                 :            :         /* FIXME: - this is going to be complex.... */
     166                 :            :         if (!replicator_dev_seg)
     167                 :            :                 return_NULL;
     168                 :            : 
     169                 :            :         /* if slog or rimage - exit */
     170                 :            : 
     171                 :            :         if (!remove_seg_from_segs_using_this_lv(lv, replicator_seg))
     172                 :            :                 return_NULL;
     173                 :            : 
     174                 :            :         replicator_seg->rlog_lv = NULL;
     175                 :            :         lv->status &= ~REPLICATOR_LOG;
     176                 :            :         lv_set_visible(lv);
     177                 :            : #endif
     178                 :            : 
     179                 :          0 :         return lv;
     180                 :            : }
     181                 :            : 
     182                 :          0 : int replicator_add_rlog(struct lv_segment *replicator_seg,
     183                 :            :                         struct logical_volume *rlog_lv)
     184                 :            : {
     185         [ #  # ]:          0 :         if (!rlog_lv)
     186                 :          0 :                 return_0;
     187                 :            : 
     188         [ #  # ]:          0 :         if (rlog_lv->status & REPLICATOR_LOG) {
     189                 :          0 :                 log_error("Rlog device %s is already used.", rlog_lv->name);
     190                 :          0 :                 return 0;
     191                 :            :         }
     192                 :            : 
     193                 :          0 :         lv_set_hidden(rlog_lv);
     194                 :          0 :         rlog_lv->status |= REPLICATOR_LOG;
     195                 :          0 :         replicator_seg->rlog_lv = rlog_lv;
     196                 :            : 
     197                 :          0 :         return add_seg_to_segs_using_this_lv(rlog_lv, replicator_seg);
     198                 :            : }
     199                 :            : 
     200                 :          0 : struct logical_volume *replicator_remove_rlog(struct lv_segment *replicator_seg)
     201                 :            : {
     202                 :            :         struct logical_volume *lv;
     203                 :            : 
     204         [ #  # ]:          0 :         if (!replicator_seg)
     205                 :          0 :                 return_0;
     206                 :            : 
     207         [ #  # ]:          0 :         if (!(lv = replicator_seg->rlog_lv)) {
     208                 :          0 :                 log_error("Replog segment %s does not have rlog.",
     209                 :            :                           replicator_seg->lv->name);
     210                 :          0 :                 return NULL;
     211                 :            :         }
     212                 :            : 
     213         [ #  # ]:          0 :         if (!remove_seg_from_segs_using_this_lv(lv, replicator_seg))
     214                 :          0 :                 return_NULL;
     215                 :            : 
     216                 :          0 :         replicator_seg->rlog_lv = NULL;
     217                 :          0 :         lv->status &= ~REPLICATOR_LOG;
     218                 :          0 :         lv_set_visible(lv);
     219                 :            : 
     220                 :          0 :         return lv;
     221                 :            : }
     222                 :            : 
     223                 :            : 
     224                 :            : #if 0
     225                 :            : /*
     226                 :            :  * Create new LV to pretend the original LV
     227                 :            :  * this target will have a 'replicator' segment
     228                 :            :  */
     229                 :            : int lv_add_replicator(struct logical_volume *origin, const char *rep_suffix)
     230                 :            : {
     231                 :            :         struct logical_volume *rep_lv;
     232                 :            :         char *name;
     233                 :            :         size_t slen;
     234                 :            : 
     235                 :            :         if (!(name = strstr(origin->name, rep_suffix))) {
     236                 :            :                 log_error("Failed to find replicator suffix %s in LV name %s",
     237                 :            :                           rep_suffix, origin->name);
     238                 :            :                 return 0;
     239                 :            :         }
     240                 :            :         slen = (size_t)(name - origin->name);
     241                 :            :         name = alloca(slen + 1);
     242                 :            :         memcpy(name, origin->name, slen);
     243                 :            :         name[slen] = 0;
     244                 :            : 
     245                 :            :         if ((rep_lv = find_lv(origin->vg, name))) {
     246                 :            :                 rep_lv->status |= VIRTUAL;
     247                 :            :                 log_very_verbose("Found already created lv  %s     le:%" PRIu32,
     248                 :            :                                  rep_lv->name, rep_lv->le_count);
     249                 :            :                 return 1;
     250                 :            :         }
     251                 :            : 
     252                 :            :         if (!(rep_lv = lv_create_empty(name, &origin->lvid,
     253                 :            :                                        LVM_READ | LVM_WRITE | VISIBLE_LV,
     254                 :            :                                        ALLOC_INHERIT, origin->vg)))
     255                 :            :                 return_0;
     256                 :            : 
     257                 :            :         log_very_verbose("Created empty lv  %s      %s le:%" PRIu32,
     258                 :            :                          rep_lv->name, origin->name, origin->le_count);
     259                 :            : 
     260                 :            :         if (!lv_add_virtual_segment(rep_lv, 0, origin->le_count,
     261                 :            :                                     get_segtype_from_string(origin->vg->cmd,
     262                 :            :                                                             "error")))
     263                 :            :                 return_0;
     264                 :            : 
     265                 :            :         rep_lv->status |= VIRTUAL;
     266                 :            :         return 1;
     267                 :            : }
     268                 :            : 
     269                 :            : int lv_remove_replicator(struct logical_volume *lv)
     270                 :            : {
     271                 :            :         return 1;
     272                 :            : }
     273                 :            : #endif
     274                 :            : 
     275                 :            : /*
     276                 :            :  * Check all replicator structures:
     277                 :            :  *  only non-clustered vg for replicator
     278                 :            :  *  only one segment in replicator LV
     279                 :            :  *  site has correct combination of operation_mode parameters
     280                 :            :  *  site and devices have correct index numbers
     281                 :            :  *  duplicate site names, site indexes, device names, device indexes
     282                 :            :  */
     283                 :          0 : int replicator_check_segment(const struct lv_segment *rseg)
     284                 :            : {
     285                 :            :         struct replicator_site *rsite, *rsiteb;
     286                 :            :         struct replicator_device *rdev, *rdevb;
     287                 :          0 :         struct logical_volume *lv = rseg->lv;
     288                 :          0 :         int r = 1;
     289                 :            : 
     290         [ #  # ]:          0 :         if (vg_is_clustered(lv->vg)) {
     291                 :          0 :                 log_error("Volume Group %s of replicator %s is clustered",
     292                 :            :                           lv->vg->name, lv->name);
     293                 :          0 :                 return 0;
     294                 :            :         }
     295                 :            : 
     296         [ #  # ]:          0 :         if (dm_list_size(&lv->segments) != 1) {
     297                 :          0 :                 log_error("Replicator %s segment size %d != 1",
     298                 :            :                           lv->name, dm_list_size(&lv->segments));
     299                 :          0 :                 return 0;
     300                 :            :         }
     301                 :            : 
     302         [ #  # ]:          0 :         dm_list_iterate_items(rsite, &lv->rsites) {
     303         [ #  # ]:          0 :                 if (rsite->op_mode == DM_REPLICATOR_SYNC) {
     304         [ #  # ]:          0 :                         if (rsite->fall_behind_timeout) {
     305                 :          0 :                                 log_error("Defined fall_behind_timeout="
     306                 :            :                                           "%d for sync replicator %s/%s.",
     307                 :            :                                           rsite->fall_behind_timeout, lv->name,
     308                 :            :                                           rsite->name);
     309                 :          0 :                                 r = 0;
     310                 :            :                         }
     311         [ #  # ]:          0 :                         if (rsite->fall_behind_ios) {
     312                 :          0 :                                 log_error("Defined fall_behind_ios="
     313                 :            :                                           "%d for sync replicator %s/%s.",
     314                 :            :                                           rsite->fall_behind_ios, lv->name, rsite->name);
     315                 :          0 :                                 r = 0;
     316                 :            :                         }
     317         [ #  # ]:          0 :                         if (rsite->fall_behind_data) {
     318                 :          0 :                                 log_error("Defined fall_behind_data="
     319                 :            :                                           "%" PRIu64 " for sync replicator %s/%s.",
     320                 :            :                                           rsite->fall_behind_data, lv->name, rsite->name);
     321                 :          0 :                                 r = 0;
     322                 :            :                         }
     323                 :            :                 } else {
     324 [ #  # ][ #  # ]:          0 :                         if (rsite->fall_behind_timeout && rsite->fall_behind_ios) {
     325                 :          0 :                                 log_error("Defined fall_behind_timeout and"
     326                 :            :                                           " fall_behind_ios for async replicator %s/%s.",
     327                 :            :                                           lv->name, rsite->name);
     328                 :          0 :                                 r = 0;
     329                 :            :                         }
     330 [ #  # ][ #  # ]:          0 :                         if (rsite->fall_behind_timeout && rsite->fall_behind_data) {
     331                 :          0 :                                 log_error("Defined fall_behind_timeout and"
     332                 :            :                                           " fall_behind_data for async replicator %s/%s.",
     333                 :            :                                           lv->name, rsite->name);
     334                 :          0 :                                 r = 0;
     335                 :            :                         }
     336 [ #  # ][ #  # ]:          0 :                         if (rsite->fall_behind_ios && rsite->fall_behind_data) {
     337                 :          0 :                                 log_error("Defined fall_behind_ios and"
     338                 :            :                                           " fall_behind_data for async replicator %s/%s.",
     339                 :            :                                           lv->name, rsite->name);
     340                 :          0 :                                 r = 0;
     341                 :            :                         }
     342 [ #  # ][ #  # ]:          0 :                         if (!rsite->fall_behind_ios && !rsite->fall_behind_data &&
                 [ #  # ]
     343                 :          0 :                             !rsite->fall_behind_timeout) {
     344                 :          0 :                                 log_error("fall_behind_timeout,"
     345                 :            :                                           " fall_behind_ios and fall_behind_data are"
     346                 :            :                                           " undefined for async replicator %s/%s.",
     347                 :            :                                           lv->name, rsite->name);
     348                 :          0 :                                 r = 0;
     349                 :            :                         }
     350                 :            :                 }
     351         [ #  # ]:          0 :                 dm_list_iterate_items(rsiteb, &lv->rsites) {
     352         [ #  # ]:          0 :                         if (rsite == rsiteb)
     353                 :          0 :                                 break;
     354         [ #  # ]:          0 :                         if (strcasecmp(rsite->name, rsiteb->name) == 0) {
     355                 :          0 :                                 log_error("Duplicate site name"
     356                 :            :                                           " %s detected for replicator %s.",
     357                 :            :                                           rsite->name, lv->name);
     358                 :          0 :                                 r = 0;
     359                 :            :                         }
     360 [ #  # ][ #  # ]:          0 :                         if ((rsite->vg_name && rsiteb->vg_name &&
         [ #  # ][ #  # ]
                 [ #  # ]
     361                 :          0 :                              strcasecmp(rsite->vg_name, rsiteb->vg_name) == 0) ||
     362                 :          0 :                             (!rsite->vg_name && !rsiteb->vg_name)) {
     363         [ #  # ]:          0 :                                 log_error("Duplicate VG name"
     364                 :            :                                           " %s detected for replicator %s.",
     365                 :            :                                           (rsite->vg_name) ? rsite->vg_name : "<local>",
     366                 :            :                                           lv->name);
     367                 :          0 :                                 r = 0;
     368                 :            :                         }
     369         [ #  # ]:          0 :                         if (rsite->site_index == rsiteb->site_index) {
     370                 :          0 :                                 log_error("Duplicate site index"
     371                 :            :                                           " %d detected for replicator %s/%s.",
     372                 :            :                                           rsite->site_index, lv->name,
     373                 :            :                                           rsite->name);
     374                 :          0 :                                 r = 0;
     375                 :            :                         }
     376         [ #  # ]:          0 :                         if (rsite->site_index > rseg->rsite_index_highest) {
     377                 :          0 :                                 log_error("Site index %d > %d"
     378                 :            :                                           " (too high) for replicator %s/%s.",
     379                 :            :                                           rsite->site_index,
     380                 :            :                                           rseg->rsite_index_highest,
     381                 :            :                                           lv->name, rsite->name);
     382                 :          0 :                                 r = 0;
     383                 :            :                         }
     384                 :            :                 }
     385                 :            : 
     386         [ #  # ]:          0 :                 dm_list_iterate_items(rdev, &rsite->rdevices) {
     387         [ #  # ]:          0 :                         dm_list_iterate_items(rdevb, &rsite->rdevices) {
     388         [ #  # ]:          0 :                                 if (rdev == rdevb)
     389                 :          0 :                                         break;
     390 [ #  # ][ #  # ]:          0 :                                 if (rdev->slog && (rdev->slog == rdevb->slog)) {
     391                 :          0 :                                         log_error("Duplicate "
     392                 :            :                                                   "sync log %s detected for "
     393                 :            :                                                   "replicator %s.",
     394                 :            :                                                   rdev->slog->name, lv->name);
     395                 :          0 :                                         r = 0;
     396                 :            :                                 }
     397         [ #  # ]:          0 :                                 if (strcasecmp(rdev->name, rdevb->name) == 0) {
     398                 :          0 :                                         log_error("Duplicate "
     399                 :            :                                                   "device name %s detected "
     400                 :            :                                                   "for replicator %s.",
     401                 :            :                                                   rdev->name, lv->name);
     402                 :          0 :                                         r = 0;
     403                 :            :                                 }
     404         [ #  # ]:          0 :                                 if (rdev->device_index == rdevb->device_index) {
     405                 :          0 :                                         log_error("Duplicate "
     406                 :            :                                                   "device index %" PRId64
     407                 :            :                                                   " detected for replicator "
     408                 :            :                                                   "%s/%s.", rdev->device_index,
     409                 :            :                                                   lv->name, rsite->name);
     410                 :          0 :                                         r = 0;
     411                 :            :                                 }
     412         [ #  # ]:          0 :                                 if (rdev->device_index > rseg->rdevice_index_highest) {
     413                 :          0 :                                         log_error("Device index %" PRIu64 " > %"
     414                 :            :                                                   PRIu64 " (too high) for replicator %s/%s.",
     415                 :            :                                                   rdev->device_index,
     416                 :            :                                                   rseg->rdevice_index_highest,
     417                 :            :                                                   lv->name, rsite->name);
     418                 :          0 :                                         r = 0;
     419                 :            :                                 }
     420                 :            :                         }
     421                 :            :                 }
     422                 :            :         }
     423                 :            : 
     424                 :          0 :         return r;
     425                 :            : }
     426                 :            : 
     427                 :            : /**
     428                 :            :  * Is this segment part of active replicator
     429                 :            :  */
     430                 :          0 : int lv_is_active_replicator_dev(const struct logical_volume *lv)
     431                 :            : {
     432 [ #  # ][ #  # ]:          0 :         return ((lv->status & REPLICATOR) &&
         [ #  # ][ #  # ]
     433                 :          0 :                 lv->rdevice &&
     434                 :          0 :                 lv->rdevice->rsite &&
     435                 :          0 :                 lv->rdevice->rsite->state == REPLICATOR_STATE_ACTIVE);
     436                 :            : }
     437                 :            : 
     438                 :            : /**
     439                 :            :  * Is this LV replicator control device
     440                 :            :  */
     441                 :          0 : int lv_is_replicator(const struct logical_volume *lv)
     442                 :            : {
     443 [ #  #  #  #  # :          0 :         return ((lv->status & REPLICATOR) &&
                      # ]
     444                 :          0 :                 !dm_list_empty(&lv->segments) &&
     445                 :          0 :                 seg_is_replicator(first_seg(lv)));
     446                 :            : }
     447                 :            : 
     448                 :            : /**
     449                 :            :  * Is this LV replicator device
     450                 :            :  */
     451                 :          0 : int lv_is_replicator_dev(const struct logical_volume *lv)
     452                 :            : {
     453 [ #  #  #  #  # :          0 :         return ((lv->status & REPLICATOR) &&
                      # ]
     454                 :          0 :                 !dm_list_empty(&lv->segments) &&
     455                 :          0 :                 seg_is_replicator_dev(first_seg(lv)));
     456                 :            : }
     457                 :            : 
     458                 :            : /**
     459                 :            :  * Is this LV replicated origin lv
     460                 :            :  */
     461                 :          0 : int lv_is_rimage(const struct logical_volume *lv)
     462                 :            : {
     463 [ #  # ][ #  # ]:          0 :         return (lv->rdevice && lv->rdevice->lv == lv);
     464                 :            : }
     465                 :            : 
     466                 :            : /**
     467                 :            :  * Is this LV rlog
     468                 :            :  */
     469                 :          0 : int lv_is_rlog(const struct logical_volume *lv)
     470                 :            : {
     471                 :          0 :         return (lv->status & REPLICATOR_LOG);
     472                 :            : }
     473                 :            : 
     474                 :            : /**
     475                 :            :  * Is this LV sync log
     476                 :            :  */
     477                 :          0 : int lv_is_slog(const struct logical_volume *lv)
     478                 :            : {
     479 [ #  # ][ #  # ]:          0 :         return (lv->rdevice && lv->rdevice->slog == lv);
     480                 :            : }
     481                 :            : 
     482                 :            : /**
     483                 :            :  * Returns first replicator-dev in site in case the LV is replicator-dev,
     484                 :            :  * NULL otherwise
     485                 :            :  */
     486                 :          0 : struct logical_volume *first_replicator_dev(const struct logical_volume *lv)
     487                 :            : {
     488                 :            :         struct replicator_device *rdev;
     489                 :            :         struct replicator_site *rsite;
     490                 :            : 
     491         [ #  # ]:          0 :         if (lv_is_replicator_dev(lv))
     492         [ #  # ]:          0 :                 dm_list_iterate_items(rsite, &first_seg(lv)->replicator->rsites) {
     493         [ #  # ]:          0 :                         dm_list_iterate_items(rdev, &rsite->rdevices)
     494                 :          0 :                                 return rdev->replicator_dev->lv;
     495                 :          0 :                         break;
     496                 :            :                 }
     497                 :            : 
     498                 :          0 :         return NULL;
     499                 :            : }
     500                 :            : 
     501                 :            : /**
     502                 :            :  * Add VG to sorted VGs list
     503                 :            :  *
     504                 :            :  * Maintain the alphabeticaly ordered list, avoid duplications.
     505                 :            :  *
     506                 :            :  * \return
     507                 :            :  * Returns newly created or already present vgs_list entry.
     508                 :            :  * Returns NULL in error case.
     509                 :            :  */
     510                 :          0 : struct vgs_list *vgs_list_add(struct dm_pool *mem,
     511                 :            :                               struct dm_list *list,
     512                 :            :                               const char *vg_name,
     513                 :            :                               const char *vgid,
     514                 :            :                               uint32_t flags)
     515                 :            : {
     516                 :            :         struct vgs_list *vgsl, *ins;
     517                 :            : 
     518                 :            :         /* Is already in the list ? */
     519         [ #  # ]:          0 :         if ((vgsl = vgs_list_lookup(list, vg_name)))
     520                 :          0 :                 return vgsl;
     521                 :            : 
     522         [ #  # ]:          0 :         if (!(vgsl = dm_pool_alloc(mem, sizeof(*vgsl)))) {
     523                 :          0 :                 log_error("Allocation of vgs_list failed.");
     524                 :          0 :                 return NULL;
     525                 :            :         }
     526                 :            : 
     527         [ #  # ]:          0 :         if (!(vgsl->vg_name = dm_pool_strdup(mem, vg_name))) {
     528                 :          0 :                 dm_pool_free(mem, vgsl);
     529                 :          0 :                 log_error("Allocation of vg_name failed.");
     530                 :          0 :                 return NULL;
     531                 :            :         }
     532                 :            : 
     533   [ #  #  #  # ]:          0 :         if (vgid &&
     534                 :          0 :             !(vgsl->vgid = dm_pool_strdup(mem, vgid))) {
     535                 :          0 :                 dm_pool_free(mem, vgsl);
     536                 :          0 :                 log_error("Allocation of vgid failed.");
     537                 :          0 :                 return NULL;
     538                 :            :         } else
     539                 :          0 :                 vgsl->vgid = NULL;
     540                 :            : 
     541                 :          0 :         vgsl->flags = flags;
     542                 :          0 :         vgsl->vg = NULL;
     543         [ #  # ]:          0 :         dm_list_iterate_items(ins, list)
     544         [ #  # ]:          0 :                 if (strcmp(vg_name, ins->vg_name) < 0) {
     545                 :          0 :                         list = &ins->list;
     546                 :          0 :                         break;
     547                 :            :                 }
     548                 :            : 
     549                 :          0 :         dm_list_add(list, &vgsl->list);
     550                 :            : 
     551                 :          0 :         return vgsl;
     552                 :            : }
     553                 :            : 
     554                 :            : /**
     555                 :            :  * Find vgs_list with given vg_name in VGs list.
     556                 :            :  *
     557                 :            :  * \param list
     558                 :            :  * List of vgs_list elements.
     559                 :            :  * \param vg_name
     560                 :            :  * Name of VG to be found.
     561                 :            :  * \return
     562                 :            :  * Returns vgs_list element with VG if vg_name is found.
     563                 :            :  * Returns NULL if vg_name is not found.
     564                 :            :  */
     565                 :          0 : struct vgs_list *vgs_list_lookup(struct dm_list *l, const char *vg_name)
     566                 :            : {
     567                 :            :         struct vgs_list *vgsl;
     568                 :            : 
     569         [ #  # ]:          0 :         dm_list_iterate_items(vgsl, l)
     570         [ #  # ]:          0 :                 if (!strcmp(vg_name, vgsl->vg_name))
     571                 :          0 :                         return vgsl;
     572                 :            : 
     573                 :          0 :         return NULL;
     574                 :            : }
     575                 :            : 
     576                 :            : /**
     577                 :            :  * Read and lock multiple VGs stored in vgs_list alphabeticaly.
     578                 :            :  * On the success list is spliced to vgs_vg->vg vgs list and left
     579                 :            :  * UNINITIALIZED and shall NOT be used until calling vgs_list_release().
     580                 :            :  *
     581                 :            :  * \param list
     582                 :            :  * Contains list of vgs_list entries.
     583                 :            :  * \param vgs_vg
     584                 :            :  * Contains master VGs list.
     585                 :            :  *
     586                 :            :  * \return
     587                 :            :  * Returns 1 if all VG in vgs_list are correctly openned and locked.
     588                 :            :  * Returns 0 if there is some problem with any VG.
     589                 :            :  * 
     590                 :            :  * (Needed to allow support for FAILED_INCONSISTENT)
     591                 :            :  */
     592                 :          0 : int vgs_list_read(struct cmd_context *cmd, struct dm_list *list,
     593                 :            :                   struct vgs_list *vgs_vg)
     594                 :            : {
     595                 :            :         struct vgs_list *vgsl;
     596                 :            : 
     597                 :            :         /* Iterate through alphabeticaly ordered VGs list */
     598         [ #  # ]:          0 :         dm_list_iterate_items(vgsl, list) {
     599                 :          0 :                 vgsl->vg = vg_read(cmd, vgsl->vg_name, vgsl->vgid, vgsl->flags);
     600         [ #  # ]:          0 :                 if (vg_read_error(vgsl->vg)) {
     601                 :          0 :                         log_debug("Failed to vg_read %s", vgsl->vg_name);
     602                 :          0 :                         return 0;
     603                 :            :                 }
     604                 :            :         }
     605                 :            : 
     606                 :          0 :         dm_list_init(&vgs_vg->vg->vgs);
     607                 :          0 :         dm_list_splice(list, &vgs_vg->vg->vgs);
     608                 :            : 
     609                 :          0 :         return 1;
     610                 :            : }
     611                 :            : 
     612                 :            : /**
     613                 :            :  * Release opened and locked VGs from list.
     614                 :            :  * List is spliced back from vgs_vg to list.
     615                 :            :  *
     616                 :            :  * \param list
     617                 :            :  * Contains list of vgs_list entries.
     618                 :            :  * \param vgs_vg
     619                 :            :  * Contains master VG with vgs list of active VGs.
     620                 :            :  */
     621                 :          0 : void vgs_list_release(struct dm_list *list, struct vgs_list *vgs_vg)
     622                 :            : {
     623                 :            :         struct vgs_list *vgsl;
     624                 :            : 
     625         [ #  # ]:          0 :         if (!vg_read_error(vgs_vg->vg)) {
     626                 :          0 :                 dm_list_init(list);
     627                 :          0 :                 dm_list_splice(&vgs_vg->vg->vgs, list);
     628                 :            :         }
     629                 :            : 
     630         [ #  # ]:          0 :         dm_list_iterate_back_items(vgsl, list) {
     631         [ #  # ]:          0 :                 if (vg_read_error(vgsl->vg))
     632                 :          0 :                         vg_release(vgsl->vg);
     633                 :            :                 else
     634                 :          0 :                         unlock_and_release_vg(vgsl->vg->cmd, vgsl->vg, vgsl->vg_name);
     635                 :          0 :                 vgsl->vg = NULL;
     636                 :            :         }
     637                 :          0 : }
     638                 :            : 
     639                 :            : /**
     640                 :            :  * Find all needed remote VGs for processing given LV.
     641                 :            :  * Missing VGs are added to VG's vgs list.
     642                 :            :  */
     643                 :          0 : int find_replicator_vgs(struct logical_volume *lv)
     644                 :            : {
     645                 :            :         struct replicator_site *rsite;
     646                 :          0 :         int ret = 1;
     647                 :            : 
     648         [ #  # ]:          0 :         if (!lv_is_replicator_dev(lv))
     649                 :          0 :                 return 1;
     650                 :            : 
     651         [ #  # ]:          0 :         dm_list_iterate_items(rsite, &first_seg(lv)->replicator->rsites) {
     652   [ #  #  #  # ]:          0 :                 if (!rsite->vg_name ||
     653                 :          0 :                     vgs_list_lookup(&lv->vg->vgs, rsite->vg_name))
     654                 :          0 :                         continue;
     655                 :          0 :                 ret = 0;
     656                 :            :                 /* Using cmd memory pool for list allocation */
     657         [ #  # ]:          0 :                 if (!vgs_list_add(lv->vg->cmd->mem, &lv->vg->vgs,
     658                 :            :                                       rsite->vg_name, NULL, 0)) {
     659                 :          0 :                         lv->vg->missing_vgs = 0; /* do not retry */
     660                 :          0 :                         stack;
     661                 :          0 :                         break;
     662                 :            :                 }
     663                 :            : 
     664                 :          0 :                 log_debug("VG: %s added as missing.", rsite->vg_name);
     665                 :          0 :                 lv->vg->missing_vgs++;
     666                 :            :         }
     667                 :            : 
     668                 :          0 :         return ret;
     669                 :            : }
     670                 :            : 
     671                 :            : /**
     672                 :            :  * Resolve all remote VGs from replicators' sites
     673                 :            :  * This function is used in activation context and needs all VGs already locked
     674                 :            :  */
     675                 :          0 : int lv_read_replicator_vgs(struct logical_volume *lv)
     676                 :            : {
     677                 :            :         struct replicator_device *rdev;
     678                 :            :         struct replicator_site *rsite;
     679                 :            :         struct volume_group *vg;
     680                 :            : 
     681         [ #  # ]:          0 :         if (!lv_is_replicator_dev(lv))
     682                 :          0 :                 return 1;
     683                 :            : 
     684         [ #  # ]:          0 :         dm_list_iterate_items(rsite, &first_seg(lv)->replicator->rsites) {
     685         [ #  # ]:          0 :                 if (!rsite->vg_name)
     686                 :          0 :                         continue;
     687                 :          0 :                 vg = vg_read(lv->vg->cmd, rsite->vg_name, 0, 0); // READ_WITHOUT_LOCK
     688         [ #  # ]:          0 :                 if (vg_read_error(vg)) {
     689                 :          0 :                         log_error("Unable to read volume group %s",
     690                 :            :                                   rsite->vg_name);
     691                 :          0 :                         goto bad;
     692                 :            :                 }
     693                 :          0 :                 rsite->vg = vg;
     694                 :            :                 /* CHECKME: handling missing LVs needs to be better */
     695         [ #  # ]:          0 :                 dm_list_iterate_items(rdev, &rsite->rdevices)
     696         [ #  # ]:          0 :                         if (!(rdev->lv = find_lv(vg, rdev->name))) {
     697                 :          0 :                                 log_error("Unable to find %s in volume group %s",
     698                 :            :                                           rdev->name, rsite->vg_name);
     699                 :          0 :                                 goto bad;
     700                 :            :                         }
     701                 :            :         }
     702                 :            : 
     703                 :          0 :         return 1;
     704                 :            : bad:
     705                 :          0 :         lv_release_replicator_vgs(lv);
     706                 :          0 :         return 0;
     707                 :            : }
     708                 :            : 
     709                 :            : /**
     710                 :            :  * Release all VG resources taken by replicators' sites
     711                 :            :  * This function is used in activation context and needs all VGs already locked
     712                 :            :  */
     713                 :          0 : void lv_release_replicator_vgs(struct logical_volume *lv)
     714                 :            : {
     715                 :            :         struct replicator_site *rsite;
     716                 :            : 
     717         [ #  # ]:          0 :         if (!lv_is_replicator_dev(lv))
     718                 :          0 :                 return;
     719                 :            : 
     720         [ #  # ]:          0 :         dm_list_iterate_back_items(rsite, &first_seg(lv)->replicator->rsites)
     721 [ #  # ][ #  # ]:          0 :                 if (rsite->vg_name && rsite->vg) {
     722                 :          0 :                         vg_release(rsite->vg);
     723                 :          0 :                         rsite->vg = NULL;
     724                 :            :                 }
     725                 :            : }
     726                 :            : 
     727                 :          0 : static int _write_replicator_header(struct cmd_context *cmd, struct logical_volume *lv)
     728                 :            : {
     729                 :          0 :         return 0;
     730                 :            : }
     731                 :            : 
     732                 :            : /*
     733                 :            :  * Initialize log contents
     734                 :            :  *
     735                 :            :  * log_name = "mirror log", "replicator log"
     736                 :            :  */
     737                 :          0 : static int _init_log(struct cmd_context *cmd,
     738                 :            :                      struct logical_volume *log_lv, int in_sync,
     739                 :            :                      struct dm_list *tags, int remove_on_failure,
     740                 :            :                      const char *log_name,
     741                 :            :                      int (*write_header) (struct cmd_context *cmd,
     742                 :            :                                           struct logical_volume *lv))
     743                 :            : {
     744                 :            :         struct str_list *sl;
     745                 :            :         struct lvinfo info;
     746                 :          0 :         uint64_t orig_status = log_lv->status;
     747                 :          0 :         int was_active = 0;
     748                 :            : 
     749 [ #  # ][ #  # ]:          0 :         if (!activation() && in_sync) {
     750                 :          0 :                 log_error("Aborting. Unable to create in-sync %s "
     751                 :            :                           "while activation is disabled.", log_name);
     752                 :          0 :                 return 0;
     753                 :            :         }
     754                 :            : 
     755                 :            :         /* If the LV is active, deactivate it first. */
     756 [ #  # ][ #  # ]:          0 :         if (lv_info(cmd, log_lv, &info, 0, 0) && info.exists) {
     757 [ #  # ][ #  # ]:          0 :                 (void)deactivate_lv(cmd, log_lv);
     758                 :            :                 /*
     759                 :            :                  * FIXME: workaround to fail early
     760                 :            :                  * Ensure that log is really deactivated because deactivate_lv
     761                 :            :                  * on cluster do not fail if there is log_lv with different UUID.
     762                 :            :                  */
     763 [ #  # ][ #  # ]:          0 :                 if (lv_info(cmd, log_lv, &info, 0, 0) && info.exists) {
     764                 :          0 :                         log_error("Aborting. Unable to deactivate %s.",
     765                 :            :                                   log_name);
     766                 :          0 :                         goto revert_new_lv;
     767                 :            :                 }
     768                 :          0 :                 was_active = 1;
     769                 :            :         }
     770                 :            : 
     771                 :            :         /* Temporary make it visible for set_lv() */
     772                 :          0 :         lv_set_visible(log_lv);
     773                 :            : 
     774                 :            :         /* Temporary tag mirror log for activation */
     775         [ #  # ]:          0 :         dm_list_iterate_items(sl, tags)
     776         [ #  # ]:          0 :                 if (!str_list_add(cmd->mem, &log_lv->tags, sl->str)) {
     777                 :          0 :                         log_error("Aborting. Unable to tag %s.", log_name);
     778                 :          0 :                         goto activate_lv;
     779                 :            :                 }
     780                 :            : 
     781                 :            :         /* store mirror log on disk(s) */
     782 [ #  # ][ #  # ]:          0 :         if (!vg_write(log_lv->vg) || !vg_commit(log_lv->vg))
     783                 :            :                 goto activate_lv;
     784                 :            : 
     785                 :          0 :         backup(log_lv->vg);
     786                 :            : 
     787   [ #  #  #  # ]:          0 :         if (!activate_lv(cmd, log_lv)) {
                 [ #  # ]
     788                 :          0 :                 log_error("Aborting. Failed to activate %s.", log_name);
     789                 :          0 :                 goto revert_new_lv;
     790                 :            :         }
     791                 :            : 
     792                 :            :         /* Remove the temporary tags */
     793         [ #  # ]:          0 :         dm_list_iterate_items(sl, tags)
     794         [ #  # ]:          0 :                 if (!str_list_del(&log_lv->tags, sl->str))
     795                 :          0 :                         log_error("Failed to remove tag %s from %s.",
     796                 :            :                                   log_name, sl->str);
     797                 :            : 
     798 [ #  # ][ #  # ]:          0 :         if (activation() && !set_lv(cmd, log_lv, log_lv->size,
                 [ #  # ]
     799                 :            :                                     in_sync ? -1 : 0)) {
     800                 :          0 :                 log_error("Aborting. Failed to wipe %s.", log_name);
     801                 :          0 :                 goto deactivate_and_revert_new_lv;
     802                 :            :         }
     803                 :            : 
     804 [ #  # ][ #  # ]:          0 :         if (activation() && !write_header(cmd, log_lv)) { /* FIXME */
     805                 :          0 :                 log_error("Aborting. Failed to write %s header.", log_name);
     806                 :          0 :                 goto deactivate_and_revert_new_lv;
     807                 :            :         }
     808                 :            : 
     809 [ #  # ][ #  # ]:          0 :         if (!deactivate_lv(cmd, log_lv)) {
                 [ #  # ]
     810                 :          0 :                 log_error("Aborting. Failed to deactivate %s. "
     811                 :            :                           "Manual intervention required.", log_name);
     812                 :          0 :                 return 0;
     813                 :            :         }
     814                 :            : 
     815                 :          0 :         lv_set_hidden(log_lv);
     816                 :            : 
     817   [ #  #  #  # ]:          0 :         if (was_active && !activate_lv(cmd, log_lv))
         [ #  # ][ #  # ]
     818                 :          0 :                 return_0;
     819                 :            : 
     820                 :          0 :         return 1;
     821                 :            : 
     822                 :            : deactivate_and_revert_new_lv:
     823 [ #  # ][ #  # ]:          0 :         if (!deactivate_lv(cmd, log_lv)) {
                 [ #  # ]
     824                 :          0 :                 log_error("Unable to deactivate %s LV. "
     825                 :            :                           "Manual intervention required.", log_name);
     826                 :          0 :                 return 0;
     827                 :            :         }
     828                 :            : 
     829                 :            : revert_new_lv:
     830                 :          0 :         log_lv->status = orig_status;
     831                 :            : 
     832         [ #  # ]:          0 :         dm_list_iterate_items(sl, tags)
     833         [ #  # ]:          0 :                 if (!str_list_del(&log_lv->tags, sl->str))
     834                 :          0 :                         log_error("Failed to remove tag %s from %s.",
     835                 :            :                                   log_name, sl->str);
     836                 :            : 
     837 [ #  # ][ #  # ]:          0 :         if (remove_on_failure && !lv_remove(log_lv)) {
     838                 :          0 :                 log_error("Manual intervention may be required to remove "
     839                 :            :                           "abandoned log LV before retrying.");
     840                 :          0 :                 return 0;
     841                 :            :         }
     842                 :            : 
     843 [ #  # ][ #  # ]:          0 :         if (!vg_write(log_lv->vg) || !vg_commit(log_lv->vg))
     844                 :          0 :                 log_error("Manual intervention may be required to "
     845                 :            :                           "remove/restore abandoned log LV before retrying.");
     846                 :            :         else
     847                 :          0 :                 backup(log_lv->vg);
     848                 :            : 
     849                 :            : activate_lv:
     850 [ #  # ][ #  # ]:          0 :         if (was_active && !remove_on_failure && !activate_lv(cmd, log_lv))
         [ #  # ][ #  # ]
                 [ #  # ]
     851                 :          0 :                 return_0;
     852                 :            : 
     853                 :          0 :         return 0;
     854                 :            : }
     855                 :            : 
     856                 :          0 : static int _init_replicator_log(struct cmd_context *cmd,
     857                 :            :                                 struct logical_volume *log_lv, int in_sync,
     858                 :            :                                 struct dm_list *tags, int remove_on_failure)
     859                 :            : {
     860         [ #  # ]:          0 :         if (!_init_log(cmd, log_lv, in_sync, tags, remove_on_failure,
     861                 :            :                        "replicator log", _write_replicator_header))
     862                 :          0 :                 return_0;
     863                 :            : 
     864                 :          0 :         return 1;
     865                 :            : }
     866                 :            : 
     867                 :          0 : static int _init_replicator_sync_log(struct cmd_context *cmd,
     868                 :            :                                      struct logical_volume *log_lv, int in_sync,
     869                 :            :                                      struct dm_list *tags, int remove_on_failure)
     870                 :            : {
     871         [ #  # ]:          0 :         if (!_init_log(cmd, log_lv, in_sync, tags, remove_on_failure,
     872                 :            :                        "sync log", _write_replicator_header))
     873                 :          0 :                 return_0;
     874                 :            : 
     875                 :          0 :         return 1;
     876                 :            : }
     877                 :            : 
     878                 :            : //!_init_repliator_log(lv->vg->cmd, first_seg(lv)->log_lv,
     879                 :            : //                                    1, &lv->tags, 0)) {
     880                 :            : 
     881                 :            : /* can be shared */
     882                 :          0 : static struct logical_volume *_create_log(struct logical_volume *lv,
     883                 :            :                                           struct alloc_handle *ah,
     884                 :            :                                           alloc_policy_t alloc,
     885                 :            :                                           const char *lv_name,
     886                 :            :                                           const char *suffix)
     887                 :            : {
     888                 :            :         struct logical_volume *log_lv;
     889                 :            :         char *log_name;
     890                 :            :         size_t len;
     891                 :            : 
     892                 :          0 :         len = strlen(lv_name) + 32;
     893                 :          0 :         if (!(log_name = alloca(len))) {
     894                 :            :                 log_error("log_name allocation failed.");
     895                 :            :                 return NULL;
     896                 :            :         }
     897                 :            : 
     898         [ #  # ]:          0 :         if (dm_snprintf(log_name, len, "%s%s", lv_name, suffix) < 0) {
     899                 :          0 :                 log_error("log_name allocation failed.");
     900                 :          0 :                 return NULL;
     901                 :            :         }
     902                 :            : 
     903         [ #  # ]:          0 :         if (!(log_lv = lv_create_empty(log_name, NULL,
     904                 :            :                                        VISIBLE_LV | LVM_READ | LVM_WRITE,
     905                 :            :                                        alloc, lv->vg)))
     906                 :          0 :                 return_NULL;
     907                 :            : 
     908         [ #  # ]:          0 :         if (!lv_add_log_segment(ah, 0, log_lv, MIRROR_LOG))
     909                 :          0 :                 return_NULL;
     910                 :            : 
     911                 :          0 :         return log_lv;
     912                 :            : }
     913                 :            : 
     914                 :          0 : static struct logical_volume *_set_up_replicator_log(struct cmd_context *cmd,
     915                 :            :                                                      struct alloc_handle *ah,
     916                 :            :                                                      struct logical_volume *lv,
     917                 :            :                                                      uint32_t log_size __attribute((unused)),
     918                 :            :                                                      alloc_policy_t alloc,
     919                 :            :                                                      int in_sync)
     920                 :            : {
     921                 :            :         struct logical_volume *log_lv;
     922                 :            :         const char *suffix, *c;
     923                 :            :         char *lv_name;
     924                 :            :         size_t len;
     925                 :            :         struct lv_segment *seg;
     926                 :            : 
     927                 :          0 :         init_mirror_in_sync(in_sync);
     928                 :            : 
     929                 :            :         /* Replicator log name is lv_name + suffix, determined as the following:
     930                 :            :          *   1. suffix is:
     931                 :            :          *        o "_rlog" for the original replicator LV.
     932                 :            :          *        o "_rlogtmp_%d" for temporary mirror LV,
     933                 :            :          *   2. lv_name is:
     934                 :            :          *        o lv->name, if the log is temporary
     935                 :            :          *        o otherwise, the top-level LV name
     936                 :            :          */
     937                 :          0 :         seg = first_seg(lv);
     938   [ #  #  #  # ]:          0 :         if (seg_type(seg, 0) == AREA_LV &&
     939                 :          0 :             strstr(seg_lv(seg, 0)->name, MIRROR_SYNC_LAYER)) {
     940                 :          0 :                 lv_name = lv->name;
     941                 :          0 :                 suffix = "_rlogtmp_%d";
     942         [ #  # ]:          0 :         } else if ((c = strstr(lv->name, MIRROR_SYNC_LAYER))) {
     943                 :          0 :                 len = (size_t)(c - lv->name + 1);
     944         [ #  # ]:          0 :                 if (!(lv_name = alloca(len)) ||
     945                 :          0 :                     !dm_snprintf(lv_name, len, "%s", lv->name)) {
     946                 :          0 :                         log_error("replicator log name allocation failed");
     947                 :          0 :                         return 0;
     948                 :            :                 }
     949                 :          0 :                 suffix = "_rlog";
     950                 :            :         } else {
     951                 :          0 :                 lv_name = lv->name;
     952                 :          0 :                 suffix = "_rlog";
     953                 :            :         }
     954                 :            : 
     955         [ #  # ]:          0 :         if (!(log_lv = _create_log(lv, ah, alloc, lv_name, suffix))) {
     956                 :          0 :                 log_error("Failed to create replicator log.");
     957                 :          0 :                 return NULL;
     958                 :            :         }
     959                 :            : 
     960         [ #  # ]:          0 :         if (!_init_replicator_log(cmd, log_lv, in_sync, &lv->tags, 1)) {
     961                 :          0 :                 log_error("Failed to initialise replicator log.");
     962                 :          0 :                 return NULL;
     963                 :            :         }
     964                 :            : 
     965                 :          0 :         return log_lv;
     966                 :            : }
     967                 :            : 
     968                 :            : 
     969                 :          0 : int add_replicator_log(struct cmd_context *cmd, struct logical_volume *lv,
     970                 :            :                        uint32_t log_size, struct dm_list *allocatable_pvs,
     971                 :            :                        alloc_policy_t alloc)
     972                 :            : {
     973                 :            :         struct alloc_handle *ah;
     974                 :            :         const struct segment_type *segtype;
     975                 :            :         struct dm_list *parallel_areas;
     976                 :            :         float sync_percent;
     977                 :            :         percent_range_t percent_range;
     978                 :            :         int in_sync;
     979                 :            :         struct logical_volume *log_lv;
     980                 :            :         struct lvinfo info;
     981                 :          0 :         int r = 0;
     982                 :            : 
     983                 :          0 :         log_error("ADDREPLICATORLOG   size %d", log_size);
     984                 :            : 
     985         [ #  # ]:          0 :         if (dm_list_size(&lv->segments) != 1) {
     986                 :          0 :                 log_error("Multiple-segment replicator log is not supported");
     987                 :          0 :                 return 0;
     988                 :            :         }
     989                 :            : 
     990                 :            :         /*
     991                 :            :          * We are unable to convert the log of inactive cluster replictors
     992                 :            :          */
     993 [ #  # ][ #  # ]:          0 :         if (vg_is_clustered(lv->vg) &&
                 [ #  # ]
     994                 :            :             !(lv_info(cmd, lv, &info, 0, 0) && info.exists)) {
     995                 :          0 :                 log_error("Unable to convert the log of inactive "
     996                 :            :                           "cluster mirror %s", lv->name);
     997                 :          0 :                 return 0;
     998                 :            :         }
     999                 :            : 
    1000         [ #  # ]:          0 :         if (!(parallel_areas = build_parallel_areas_from_lv(cmd, lv, 0)))
    1001                 :          0 :                 return_0;
    1002                 :            : 
    1003         [ #  # ]:          0 :         if (!(segtype = get_segtype_from_string(cmd, "replicator")))
    1004                 :          0 :                 return_0;
    1005                 :            : 
    1006         [ #  # ]:          0 :         if (activation() && segtype->ops->target_present &&
           [ #  #  #  # ]
    1007                 :          0 :             !segtype->ops->target_present(cmd, NULL, NULL)) {
    1008                 :          0 :                 log_error("%s: Required device-mapper target(s) not "
    1009                 :            :                           "detected in your kernel", segtype->name);
    1010                 :          0 :                 return 0;
    1011                 :            :         }
    1012                 :            : 
    1013                 :            :         /* allocate destination extents */
    1014                 :          0 :         ah = allocate_extents(lv->vg, NULL, segtype,
    1015                 :            :                               0, 0, 1, log_size, 0,
    1016                 :            :                               allocatable_pvs, alloc, parallel_areas);
    1017         [ #  # ]:          0 :         if (!ah) {
    1018                 :          0 :                 log_error("Unable to allocate extents for replicator log.");
    1019                 :          0 :                 return 0;
    1020                 :            :         }
    1021                 :            : 
    1022                 :            :         /* check sync status */
    1023                 :            : //      if (lv_mirror_percent(cmd, lv, 0, &sync_percent, &percent_range,
    1024                 :            : //                            NULL) &&
    1025                 :            : //          (percent_range == PERCENT_100))
    1026                 :            : //              in_sync = 1;
    1027                 :            : //      else
    1028                 :          0 :                 in_sync = 0;
    1029                 :            : 
    1030         [ #  # ]:          0 :         if (!(log_lv = _set_up_replicator_log(cmd, ah, lv, log_size,
    1031                 :            :                                               alloc, in_sync)))
    1032                 :          0 :                 goto_out;
    1033                 :            : 
    1034         [ #  # ]:          0 :         if (!attach_mirror_log(first_seg(lv), log_lv))
    1035                 :          0 :                 goto_out;
    1036                 :            : 
    1037                 :          0 :         r = 1;
    1038                 :            : out:
    1039                 :          0 :         alloc_destroy(ah);
    1040                 :          0 :         return r;
    1041                 :            : }

Generated by: LCOV version 1.8