Home | History | Annotate | Line # | Download | only in metadata
snapshot_manip.c revision 1.1.1.1.2.1
      1  1.1.1.1.2.1   jym /*	$NetBSD: snapshot_manip.c,v 1.1.1.1.2.1 2009/05/13 18:52:43 jym Exp $	*/
      2          1.1  haad 
      3          1.1  haad /*
      4          1.1  haad  * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
      5          1.1  haad  * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
      6          1.1  haad  *
      7          1.1  haad  * This file is part of LVM2.
      8          1.1  haad  *
      9          1.1  haad  * This copyrighted material is made available to anyone wishing to use,
     10          1.1  haad  * modify, copy, or redistribute it subject to the terms and conditions
     11          1.1  haad  * of the GNU Lesser General Public License v.2.1.
     12          1.1  haad  *
     13          1.1  haad  * You should have received a copy of the GNU Lesser General Public License
     14          1.1  haad  * along with this program; if not, write to the Free Software Foundation,
     15          1.1  haad  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     16          1.1  haad  */
     17          1.1  haad 
     18          1.1  haad #include "lib.h"
     19          1.1  haad #include "metadata.h"
     20          1.1  haad #include "toolcontext.h"
     21          1.1  haad #include "lv_alloc.h"
     22          1.1  haad 
     23          1.1  haad int lv_is_origin(const struct logical_volume *lv)
     24          1.1  haad {
     25          1.1  haad 	return lv->origin_count ? 1 : 0;
     26          1.1  haad }
     27          1.1  haad 
     28          1.1  haad int lv_is_cow(const struct logical_volume *lv)
     29          1.1  haad {
     30          1.1  haad 	return lv->snapshot ? 1 : 0;
     31          1.1  haad }
     32          1.1  haad 
     33          1.1  haad int lv_is_visible(const struct logical_volume *lv)
     34          1.1  haad {
     35          1.1  haad 	if (lv_is_cow(lv))
     36          1.1  haad 		return lv_is_visible(find_cow(lv)->lv);
     37          1.1  haad 
     38          1.1  haad 	return lv->status & VISIBLE_LV ? 1 : 0;
     39          1.1  haad }
     40          1.1  haad 
     41  1.1.1.1.2.1   jym int lv_is_displayable(const struct logical_volume *lv)
     42  1.1.1.1.2.1   jym {
     43  1.1.1.1.2.1   jym 	if (lv->status & SNAPSHOT)
     44  1.1.1.1.2.1   jym 		return 0;
     45  1.1.1.1.2.1   jym 
     46  1.1.1.1.2.1   jym 	return (lv->status & VISIBLE_LV) || lv_is_cow(lv) ? 1 : 0;
     47  1.1.1.1.2.1   jym }
     48  1.1.1.1.2.1   jym 
     49          1.1  haad /* Given a cow LV, return the snapshot lv_segment that uses it */
     50          1.1  haad struct lv_segment *find_cow(const struct logical_volume *lv)
     51          1.1  haad {
     52          1.1  haad 	return lv->snapshot;
     53          1.1  haad }
     54          1.1  haad 
     55          1.1  haad /* Given a cow LV, return its origin */
     56          1.1  haad struct logical_volume *origin_from_cow(const struct logical_volume *lv)
     57          1.1  haad {
     58          1.1  haad 	return lv->snapshot->origin;
     59          1.1  haad }
     60          1.1  haad 
     61          1.1  haad int vg_add_snapshot(const char *name, struct logical_volume *origin,
     62          1.1  haad 		    struct logical_volume *cow, union lvid *lvid,
     63          1.1  haad 		    uint32_t extent_count, uint32_t chunk_size)
     64          1.1  haad {
     65          1.1  haad 	struct logical_volume *snap;
     66          1.1  haad 	struct lv_segment *seg;
     67          1.1  haad 
     68          1.1  haad 	/*
     69          1.1  haad 	 * Is the cow device already being used ?
     70          1.1  haad 	 */
     71          1.1  haad 	if (lv_is_cow(cow)) {
     72          1.1  haad 		log_err("'%s' is already in use as a snapshot.", cow->name);
     73          1.1  haad 		return 0;
     74          1.1  haad 	}
     75          1.1  haad 
     76          1.1  haad 	if (cow == origin) {
     77          1.1  haad 		log_error("Snapshot and origin LVs must differ.");
     78          1.1  haad 		return 0;
     79          1.1  haad 	}
     80          1.1  haad 
     81          1.1  haad 	if (!(snap = lv_create_empty(name ? name : "snapshot%d",
     82          1.1  haad 				     lvid, LVM_READ | LVM_WRITE | VISIBLE_LV,
     83          1.1  haad 				     ALLOC_INHERIT, 1, origin->vg)))
     84          1.1  haad 		return_0;
     85          1.1  haad 
     86          1.1  haad 	snap->le_count = extent_count;
     87          1.1  haad 
     88          1.1  haad 	if (!(seg = alloc_snapshot_seg(snap, 0, 0)))
     89          1.1  haad 		return_0;
     90          1.1  haad 
     91          1.1  haad 	seg->chunk_size = chunk_size;
     92          1.1  haad 	seg->origin = origin;
     93          1.1  haad 	seg->cow = cow;
     94          1.1  haad 	seg->lv->status |= SNAPSHOT;
     95          1.1  haad 
     96          1.1  haad 	origin->origin_count++;
     97          1.1  haad 	origin->vg->snapshot_count++;
     98          1.1  haad 	origin->vg->lv_count--;
     99          1.1  haad 	cow->snapshot = seg;
    100          1.1  haad 
    101          1.1  haad 	cow->status &= ~VISIBLE_LV;
    102          1.1  haad 
    103          1.1  haad 	dm_list_add(&origin->snapshot_segs, &seg->origin_list);
    104          1.1  haad 
    105          1.1  haad 	return 1;
    106          1.1  haad }
    107          1.1  haad 
    108          1.1  haad int vg_remove_snapshot(struct logical_volume *cow)
    109          1.1  haad {
    110          1.1  haad 	dm_list_del(&cow->snapshot->origin_list);
    111          1.1  haad 	cow->snapshot->origin->origin_count--;
    112          1.1  haad 
    113          1.1  haad 	if (!lv_remove(cow->snapshot->lv)) {
    114          1.1  haad 		log_error("Failed to remove internal snapshot LV %s",
    115          1.1  haad 			  cow->snapshot->lv->name);
    116          1.1  haad 		return 0;
    117          1.1  haad 	}
    118          1.1  haad 
    119          1.1  haad 	cow->snapshot = NULL;
    120          1.1  haad 
    121          1.1  haad 	cow->vg->snapshot_count--;
    122          1.1  haad 	cow->vg->lv_count++;
    123          1.1  haad 	cow->status |= VISIBLE_LV;
    124          1.1  haad 
    125          1.1  haad 	return 1;
    126          1.1  haad }
    127