~ubuntu-branches/ubuntu/breezy/lvm2/breezy

« back to all changes in this revision

Viewing changes to lib/snapshot/snapshot.c

  • Committer: Bazaar Package Importer
  • Author(s): Patrick Caulfield
  • Date: 2004-11-03 09:37:56 UTC
  • Revision ID: james.westby@ubuntu.com-20041103093756-jt0nj8z0v8k1lyiv
Tags: upstream-2.00.25
ImportĀ upstreamĀ versionĀ 2.00.25

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.  
 
3
 * Copyright (C) 2004 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 General Public License v.2.
 
10
 *
 
11
 * You should have received a copy of the GNU 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 "pool.h"
 
18
#include "list.h"
 
19
#include "toolcontext.h"
 
20
#include "metadata.h"
 
21
#include "segtype.h"
 
22
#include "text_export.h"
 
23
#include "config.h"
 
24
#include "activate.h"
 
25
 
 
26
static const char *_name(const struct lv_segment *seg)
 
27
{
 
28
        return seg->segtype->name;
 
29
}
 
30
 
 
31
static int _text_import(struct lv_segment *seg, const struct config_node *sn,
 
32
                        struct hash_table *pv_hash)
 
33
{
 
34
        uint32_t chunk_size;
 
35
        const char *org_name, *cow_name;
 
36
        struct logical_volume *org, *cow;
 
37
 
 
38
        seg->lv->status |= SNAPSHOT;
 
39
 
 
40
        if (!get_config_uint32(sn, "chunk_size", &chunk_size)) {
 
41
                log_error("Couldn't read chunk size for snapshot.");
 
42
                return 0;
 
43
        }
 
44
 
 
45
        log_suppress(1);
 
46
 
 
47
        if (!(cow_name = find_config_str(sn, "cow_store", NULL))) {
 
48
                log_suppress(0);
 
49
                log_error("Snapshot cow storage not specified.");
 
50
                return 0;
 
51
        }
 
52
 
 
53
        if (!(org_name = find_config_str(sn, "origin", NULL))) {
 
54
                log_suppress(0);
 
55
                log_error("Snapshot origin not specified.");
 
56
                return 0;
 
57
        }
 
58
 
 
59
        log_suppress(0);
 
60
 
 
61
        if (!(cow = find_lv(seg->lv->vg, cow_name))) {
 
62
                log_error("Unknown logical volume specified for "
 
63
                          "snapshot cow store.");
 
64
                return 0;
 
65
        }
 
66
 
 
67
        if (!(org = find_lv(seg->lv->vg, org_name))) {
 
68
                log_error("Unknown logical volume specified for "
 
69
                          "snapshot origin.");
 
70
                return 0;
 
71
        }
 
72
 
 
73
        if (!vg_add_snapshot(org, cow, 1, &seg->lv->lvid.id[1], chunk_size)) {
 
74
                stack;
 
75
                return 0;
 
76
        }
 
77
 
 
78
        return 1;
 
79
}
 
80
 
 
81
static int _text_export(const struct lv_segment *seg, struct formatter *f)
 
82
{
 
83
        outf(f, "chunk_size = %u", seg->chunk_size);
 
84
        outf(f, "origin = \"%s\"", seg->origin->name);
 
85
        outf(f, "cow_store = \"%s\"", seg->cow->name);
 
86
 
 
87
        return 1;
 
88
}
 
89
 
 
90
#ifdef DEVMAPPER_SUPPORT
 
91
static int _target_percent(void **target_state, struct pool *mem,
 
92
                           struct config_tree *cft, struct lv_segment *seg,
 
93
                           char *params, uint64_t *total_numerator,
 
94
                           uint64_t *total_denominator, float *percent)
 
95
{
 
96
        float percent2;
 
97
        uint64_t numerator, denominator;
 
98
 
 
99
        if (index(params, '/')) {
 
100
                if (sscanf(params, "%" PRIu64 "/%" PRIu64,
 
101
                           &numerator, &denominator) == 2) {
 
102
                        *total_numerator += numerator;
 
103
                        *total_denominator += denominator;
 
104
                }
 
105
        } else if (sscanf(params, "%f", &percent2) == 1) {
 
106
                *percent += percent2;
 
107
                *percent /= 2;
 
108
        }
 
109
 
 
110
        return 1;
 
111
}
 
112
 
 
113
static int _target_present(void)
 
114
{
 
115
        static int checked = 0;
 
116
        static int present = 0;
 
117
 
 
118
        if (!checked)
 
119
                present = target_present("snapshot") &&
 
120
                    target_present("snapshot-origin");
 
121
 
 
122
        checked = 1;
 
123
 
 
124
        return present;
 
125
}
 
126
#endif
 
127
 
 
128
static void _destroy(const struct segment_type *segtype)
 
129
{
 
130
        dbg_free((void *) segtype);
 
131
}
 
132
 
 
133
static struct segtype_handler _snapshot_ops = {
 
134
        name:_name,
 
135
        text_import:_text_import,
 
136
        text_export:_text_export,
 
137
#ifdef DEVMAPPER_SUPPORT
 
138
        target_percent:_target_percent,
 
139
        target_present:_target_present,
 
140
#endif
 
141
        destroy:_destroy,
 
142
};
 
143
 
 
144
#ifdef SNAPSHOT_INTERNAL
 
145
struct segment_type *init_snapshot_segtype(struct cmd_context *cmd)
 
146
#else                           /* Shared */
 
147
struct segment_type *init_segtype(struct cmd_context *cmd);
 
148
struct segment_type *init_segtype(struct cmd_context *cmd)
 
149
#endif
 
150
{
 
151
        struct segment_type *segtype = dbg_malloc(sizeof(*segtype));
 
152
 
 
153
        if (!segtype) {
 
154
                stack;
 
155
                return NULL;
 
156
        }
 
157
 
 
158
        segtype->cmd = cmd;
 
159
        segtype->ops = &_snapshot_ops;
 
160
        segtype->name = "snapshot";
 
161
        segtype->private = NULL;
 
162
        segtype->flags = SEG_SNAPSHOT;
 
163
 
 
164
        log_very_verbose("Initialised segtype: %s", segtype->name);
 
165
 
 
166
        return segtype;
 
167
}