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

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
       3                 :            :  * Copyright (C) 2004-2006 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 "locking.h"
      19                 :            : #include "toolcontext.h"
      20                 :            : #include "lv_alloc.h"
      21                 :            : 
      22                 :          0 : int lv_is_origin(const struct logical_volume *lv)
      23                 :            : {
      24                 :          0 :         return lv->origin_count ? 1 : 0;
      25                 :            : }
      26                 :            : 
      27                 :          0 : int lv_is_cow(const struct logical_volume *lv)
      28                 :            : {
      29 [ #  # ][ #  # ]:          0 :         return (!lv_is_origin(lv) && lv->snapshot) ? 1 : 0;
      30                 :            : }
      31                 :            : 
      32                 :          0 : int lv_is_visible(const struct logical_volume *lv)
      33                 :            : {
      34         [ #  # ]:          0 :         if (lv->status & SNAPSHOT)
      35                 :          0 :                 return 0;
      36                 :            : 
      37         [ #  # ]:          0 :         if (lv_is_cow(lv)) {
      38         [ #  # ]:          0 :                 if (lv_is_virtual_origin(origin_from_cow(lv)))
      39                 :          0 :                         return 1;
      40                 :            : 
      41         [ #  # ]:          0 :                 if (lv_is_merging_cow(lv))
      42                 :          0 :                         return 0;
      43                 :            : 
      44                 :          0 :                 return lv_is_visible(origin_from_cow(lv));
      45                 :            :         }
      46                 :            : 
      47                 :          0 :         return lv->status & VISIBLE_LV ? 1 : 0;
      48                 :            : }
      49                 :            : 
      50                 :          0 : int lv_is_virtual_origin(const struct logical_volume *lv)
      51                 :            : {
      52                 :          0 :         return (lv->status & VIRTUAL_ORIGIN) ? 1 : 0;
      53                 :            : }
      54                 :            : 
      55                 :          0 : int lv_is_merging_origin(const struct logical_volume *origin)
      56                 :            : {
      57                 :          0 :         return (origin->status & MERGING) ? 1 : 0;
      58                 :            : }
      59                 :            : 
      60                 :          0 : struct lv_segment *find_merging_cow(const struct logical_volume *origin)
      61                 :            : {
      62         [ #  # ]:          0 :         if (!lv_is_merging_origin(origin))
      63                 :          0 :                 return NULL;
      64                 :            : 
      65                 :          0 :         return find_cow(origin);
      66                 :            : }
      67                 :            : 
      68                 :          0 : int lv_is_merging_cow(const struct logical_volume *snapshot)
      69                 :            : {
      70                 :            :         /* checks lv_segment's status to see if cow is merging */
      71                 :          0 :         return (find_cow(snapshot)->status & MERGING) ? 1 : 0;
      72                 :            : }
      73                 :            : 
      74                 :            : /* Given a cow LV, return the snapshot lv_segment that uses it */
      75                 :          0 : struct lv_segment *find_cow(const struct logical_volume *lv)
      76                 :            : {
      77                 :          0 :         return lv->snapshot;
      78                 :            : }
      79                 :            : 
      80                 :            : /* Given a cow LV, return its origin */
      81                 :          0 : struct logical_volume *origin_from_cow(const struct logical_volume *lv)
      82                 :            : {
      83                 :          0 :         return lv->snapshot->origin;
      84                 :            : }
      85                 :            : 
      86                 :          0 : void init_snapshot_seg(struct lv_segment *seg, struct logical_volume *origin,
      87                 :            :                        struct logical_volume *cow, uint32_t chunk_size, int merge)
      88                 :            : {
      89                 :          0 :         seg->chunk_size = chunk_size;
      90                 :          0 :         seg->origin = origin;
      91                 :          0 :         seg->cow = cow;
      92                 :            : 
      93                 :          0 :         lv_set_hidden(cow);
      94                 :            : 
      95                 :          0 :         cow->snapshot = seg;
      96                 :            : 
      97                 :          0 :         origin->origin_count++;
      98                 :            : 
      99                 :            :         /* FIXME Assumes an invisible origin belongs to a sparse device */
     100         [ #  # ]:          0 :         if (!lv_is_visible(origin))
     101                 :          0 :                 origin->status |= VIRTUAL_ORIGIN;
     102                 :            : 
     103                 :          0 :         seg->lv->status |= (SNAPSHOT | VIRTUAL);
     104         [ #  # ]:          0 :         if (merge)
     105                 :          0 :                 init_snapshot_merge(seg, origin);
     106                 :            : 
     107                 :          0 :         dm_list_add(&origin->snapshot_segs, &seg->origin_list);
     108                 :          0 : }
     109                 :            : 
     110                 :          0 : void init_snapshot_merge(struct lv_segment *cow_seg,
     111                 :            :                          struct logical_volume *origin)
     112                 :            : {
     113                 :            :         /*
     114                 :            :          * Even though lv_is_visible(cow_seg->lv) returns 0,
     115                 :            :          * the cow_seg->lv (name: snapshotX) is _not_ hidden;
     116                 :            :          * this is part of the lvm2 snapshot fiction.  Must
     117                 :            :          * clear VISIBLE_LV directly (lv_set_visible can't)
     118                 :            :          * - cow_seg->lv->status is used to control whether 'lv'
     119                 :            :          *   (with user provided snapshot LV name) is visible
     120                 :            :          * - this also enables vg_validate() to succeed with
     121                 :            :          *   merge metadata (cow_seg->lv is now "internal")
     122                 :            :          */
     123                 :          0 :         cow_seg->lv->status &= ~VISIBLE_LV;
     124                 :          0 :         cow_seg->status |= MERGING;
     125                 :          0 :         origin->snapshot = cow_seg;
     126                 :          0 :         origin->status |= MERGING;
     127                 :          0 : }
     128                 :            : 
     129                 :          0 : void clear_snapshot_merge(struct logical_volume *origin)
     130                 :            : {
     131                 :            :         /* clear merge attributes */
     132                 :          0 :         origin->snapshot->status &= ~MERGING;
     133                 :          0 :         origin->snapshot = NULL;
     134                 :          0 :         origin->status &= ~MERGING;
     135                 :          0 : }
     136                 :            : 
     137                 :          0 : int vg_add_snapshot(struct logical_volume *origin,
     138                 :            :                     struct logical_volume *cow, union lvid *lvid,
     139                 :            :                     uint32_t extent_count, uint32_t chunk_size)
     140                 :            : {
     141                 :            :         struct logical_volume *snap;
     142                 :            :         struct lv_segment *seg;
     143                 :            : 
     144                 :            :         /*
     145                 :            :          * Is the cow device already being used ?
     146                 :            :          */
     147         [ #  # ]:          0 :         if (lv_is_cow(cow)) {
     148                 :          0 :                 log_error("'%s' is already in use as a snapshot.", cow->name);
     149                 :          0 :                 return 0;
     150                 :            :         }
     151                 :            : 
     152         [ #  # ]:          0 :         if (cow == origin) {
     153                 :          0 :                 log_error("Snapshot and origin LVs must differ.");
     154                 :          0 :                 return 0;
     155                 :            :         }
     156                 :            : 
     157         [ #  # ]:          0 :         if (!(snap = lv_create_empty("snapshot%d",
     158                 :            :                                      lvid, LVM_READ | LVM_WRITE | VISIBLE_LV,
     159                 :            :                                      ALLOC_INHERIT, origin->vg)))
     160                 :          0 :                 return_0;
     161                 :            : 
     162                 :          0 :         snap->le_count = extent_count;
     163                 :            : 
     164         [ #  # ]:          0 :         if (!(seg = alloc_snapshot_seg(snap, 0, 0)))
     165                 :          0 :                 return_0;
     166                 :            : 
     167                 :          0 :         init_snapshot_seg(seg, origin, cow, chunk_size, 0);
     168                 :            : 
     169                 :          0 :         return 1;
     170                 :            : }
     171                 :            : 
     172                 :          0 : int vg_remove_snapshot(struct logical_volume *cow)
     173                 :            : {
     174                 :          0 :         int preload_origin = 0;
     175                 :          0 :         struct logical_volume *origin = origin_from_cow(cow);
     176                 :            : 
     177                 :          0 :         dm_list_del(&cow->snapshot->origin_list);
     178                 :          0 :         origin->origin_count--;
     179         [ #  # ]:          0 :         if (find_merging_cow(origin) == find_cow(cow)) {
     180                 :          0 :                 clear_snapshot_merge(origin);
     181                 :            :                 /*
     182                 :            :                  * preload origin to:
     183                 :            :                  * - allow proper release of -cow
     184                 :            :                  * - avoid allocations with other devices suspended
     185                 :            :                  *   when transitioning from "snapshot-merge" to
     186                 :            :                  *   "snapshot-origin after a merge completes.
     187                 :            :                  */
     188                 :          0 :                 preload_origin = 1;
     189                 :            :         }
     190                 :            : 
     191         [ #  # ]:          0 :         if (!lv_remove(cow->snapshot->lv)) {
     192                 :          0 :                 log_error("Failed to remove internal snapshot LV %s",
     193                 :            :                           cow->snapshot->lv->name);
     194                 :          0 :                 return 0;
     195                 :            :         }
     196                 :            : 
     197                 :          0 :         cow->snapshot = NULL;
     198                 :          0 :         lv_set_visible(cow);
     199                 :            : 
     200         [ #  # ]:          0 :         if (preload_origin) {
     201         [ #  # ]:          0 :                 if (!vg_write(origin->vg))
     202                 :          0 :                         return_0;
     203 [ #  # ][ #  # ]:          0 :                 if (!suspend_lv(origin->vg->cmd, origin)) {
                 [ #  # ]
     204                 :          0 :                         log_error("Failed to refresh %s without snapshot.",
     205                 :            :                                   origin->name);
     206                 :          0 :                         return 0;
     207                 :            :                 }
     208         [ #  # ]:          0 :                 if (!vg_commit(origin->vg))
     209                 :          0 :                         return_0;
     210 [ #  # ][ #  # ]:          0 :                 if (!resume_lv(origin->vg->cmd, origin)) {
                 [ #  # ]
     211                 :          0 :                         log_error("Failed to resume %s.", origin->name);
     212                 :          0 :                         return 0;
     213                 :            :                 }
     214                 :            :         }
     215                 :            : 
     216                 :          0 :         return 1;
     217                 :            : }

Generated by: LCOV version 1.8