~brightbox/ubuntu/raring/lvm2/fix-for-1076304

« back to all changes in this revision

Viewing changes to lib/snapshot/snapshot.c

  • Committer: Bazaar Package Importer
  • Author(s): James Westby
  • Date: 2008-07-01 16:39:18 UTC
  • mto: This revision was merged to the branch mainline in revision 35.
  • Revision ID: james.westby@ubuntu.com-20080701163918-lzcg5lpcdyivgo9v
Tags: upstream-2.02.39
ImportĀ upstreamĀ versionĀ 2.02.39

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.  
3
 
 * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
 
2
 * Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
 
3
 * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
4
4
 *
5
5
 * This file is part of LVM2.
6
6
 *
7
7
 * This copyrighted material is made available to anyone wishing to use,
8
8
 * modify, copy, or redistribute it subject to the terms and conditions
9
 
 * of the GNU General Public License v.2.
 
9
 * of the GNU Lesser General Public License v.2.1.
10
10
 *
11
 
 * You should have received a copy of the GNU General Public License
 
11
 * You should have received a copy of the GNU Lesser General Public License
12
12
 * along with this program; if not, write to the Free Software Foundation,
13
13
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
14
14
 */
21
21
#include "config.h"
22
22
#include "activate.h"
23
23
#include "str_list.h"
 
24
#ifdef DMEVENTD
 
25
#  include "sharedlib.h"
 
26
#  include <libdevmapper-event.h>
 
27
#endif
24
28
 
25
29
static const char *_snap_name(const struct lv_segment *seg)
26
30
{
69
73
                return 0;
70
74
        }
71
75
 
72
 
        if (!vg_add_snapshot(seg->lv->vg->fid, seg->lv->name, org, cow,
73
 
                             &seg->lv->lvid, seg->len, chunk_size)) {
74
 
                stack;
75
 
                return 0;
76
 
        }
 
76
        if (!vg_add_snapshot(seg->lv->name, org, cow,
 
77
                             &seg->lv->lvid, seg->len, chunk_size))
 
78
                return_0;
77
79
 
78
80
        return 1;
79
81
}
98
100
        float percent2;
99
101
        uint64_t numerator, denominator;
100
102
 
101
 
        if (index(params, '/')) {
 
103
        if (strchr(params, '/')) {
102
104
                if (sscanf(params, "%" PRIu64 "/%" PRIu64,
103
105
                           &numerator, &denominator) == 2) {
104
106
                        *total_numerator += numerator;
112
114
        return 1;
113
115
}
114
116
 
115
 
static int _snap_target_present(const struct lv_segment *seg __attribute((unused)))
 
117
static int _snap_target_present(const struct lv_segment *seg __attribute((unused)),
 
118
                                unsigned *attributes __attribute((unused)))
116
119
{
117
120
        static int _snap_checked = 0;
118
121
        static int _snap_present = 0;
125
128
 
126
129
        return _snap_present;
127
130
}
 
131
 
 
132
#ifdef DMEVENTD
 
133
static int _get_snapshot_dso_path(struct cmd_context *cmd, char **dso)
 
134
{
 
135
        char *path;
 
136
        const char *libpath;
 
137
 
 
138
        if (!(path = dm_pool_alloc(cmd->mem, PATH_MAX))) {
 
139
                log_error("Failed to allocate dmeventd library path.");
 
140
                return 0;
 
141
        }
 
142
 
 
143
        libpath = find_config_tree_str(cmd, "dmeventd/snapshot_library", NULL);
 
144
        if (!libpath)
 
145
                return 0;
 
146
 
 
147
        get_shared_library_path(cmd, libpath, path, PATH_MAX);
 
148
 
 
149
        *dso = path;
 
150
 
 
151
        return 1;
 
152
}
 
153
 
 
154
static struct dm_event_handler *_create_dm_event_handler(const char *dmname,
 
155
                                                         const char *dso,
 
156
                                                         const int timeout,
 
157
                                                         enum dm_event_mask mask)
 
158
{
 
159
        struct dm_event_handler *dmevh;
 
160
 
 
161
        if (!(dmevh = dm_event_handler_create()))
 
162
                return_0;
 
163
 
 
164
       if (dm_event_handler_set_dso(dmevh, dso))
 
165
                goto fail;
 
166
 
 
167
        if (dm_event_handler_set_dev_name(dmevh, dmname))
 
168
                goto fail;
 
169
 
 
170
        dm_event_handler_set_timeout(dmevh, timeout);
 
171
        dm_event_handler_set_event_mask(dmevh, mask);
 
172
        return dmevh;
 
173
 
 
174
fail:
 
175
        dm_event_handler_destroy(dmevh);
 
176
        return NULL;
 
177
}
 
178
 
 
179
static int _target_registered(struct lv_segment *seg, int *pending)
 
180
{
 
181
        char *dso, *name;
 
182
        struct logical_volume *lv;
 
183
        struct volume_group *vg;
 
184
        enum dm_event_mask evmask = 0;
 
185
        struct dm_event_handler *dmevh;
 
186
 
 
187
        lv = seg->lv;
 
188
        vg = lv->vg;
 
189
 
 
190
        *pending = 0;
 
191
        if (!_get_snapshot_dso_path(vg->cmd, &dso))
 
192
                return_0;
 
193
 
 
194
        if (!(name = build_dm_name(vg->cmd->mem, vg->name, seg->cow->name, NULL)))
 
195
                return_0;
 
196
 
 
197
        if (!(dmevh = _create_dm_event_handler(name, dso, 0, DM_EVENT_ALL_ERRORS)))
 
198
                return_0;
 
199
 
 
200
        if (dm_event_get_registered_device(dmevh, 0)) {
 
201
                dm_event_handler_destroy(dmevh);
 
202
                return 0;
 
203
        }
 
204
 
 
205
        evmask = dm_event_handler_get_event_mask(dmevh);
 
206
        if (evmask & DM_EVENT_REGISTRATION_PENDING) {
 
207
                *pending = 1;
 
208
                evmask &= ~DM_EVENT_REGISTRATION_PENDING;
 
209
        }
 
210
 
 
211
        dm_event_handler_destroy(dmevh);
 
212
 
 
213
        return evmask;
 
214
}
 
215
 
 
216
/* FIXME This gets run while suspended and performs banned operations. */
 
217
static int _target_set_events(struct lv_segment *seg,
 
218
                              int events __attribute((unused)), int set)
 
219
{
 
220
        char *dso, *name;
 
221
        struct volume_group *vg = seg->lv->vg;
 
222
        struct dm_event_handler *dmevh;
 
223
        int r;
 
224
 
 
225
        if (!_get_snapshot_dso_path(vg->cmd, &dso))
 
226
                return_0;
 
227
 
 
228
        if (!(name = build_dm_name(vg->cmd->mem, vg->name, seg->cow->name, NULL)))
 
229
                return_0;
 
230
 
 
231
        /* FIXME: make timeout configurable */
 
232
        if (!(dmevh = _create_dm_event_handler(name, dso, 10,
 
233
                DM_EVENT_ALL_ERRORS|DM_EVENT_TIMEOUT)))
 
234
                return_0;
 
235
 
 
236
        r = set ? dm_event_register_handler(dmevh) : dm_event_unregister_handler(dmevh);
 
237
        dm_event_handler_destroy(dmevh);
 
238
        if (!r)
 
239
                return_0;
 
240
 
 
241
        log_info("%s %s for events", set ? "Registered" : "Unregistered", name);
 
242
 
 
243
        return 1;
 
244
}
 
245
 
 
246
static int _target_register_events(struct lv_segment *seg,
 
247
                                   int events)
 
248
{
 
249
        return _target_set_events(seg, events, 1);
 
250
}
 
251
 
 
252
static int _target_unregister_events(struct lv_segment *seg,
 
253
                                     int events)
 
254
{
 
255
        return _target_set_events(seg, events, 0);
 
256
}
 
257
 
 
258
#endif /* DMEVENTD */
128
259
#endif
129
260
 
130
261
static int _snap_modules_needed(struct dm_pool *mem,
131
 
                                const struct lv_segment *seg,
 
262
                                const struct lv_segment *seg __attribute((unused)),
132
263
                                struct list *modules)
133
264
{
134
265
        if (!str_list_add(mem, modules, "snapshot")) {
151
282
#ifdef DEVMAPPER_SUPPORT
152
283
        .target_percent = _snap_target_percent,
153
284
        .target_present = _snap_target_present,
 
285
#ifdef DMEVENTD
 
286
        .target_monitored = _target_registered,
 
287
        .target_monitor_events = _target_register_events,
 
288
        .target_unmonitor_events = _target_unregister_events,
 
289
#endif
154
290
#endif
155
291
        .modules_needed = _snap_modules_needed,
156
292
        .destroy = _snap_destroy,
164
300
#endif
165
301
{
166
302
        struct segment_type *segtype = dm_malloc(sizeof(*segtype));
 
303
#ifdef DMEVENTD
 
304
        char *dso;
 
305
#endif
167
306
 
168
 
        if (!segtype) {
169
 
                stack;
170
 
                return NULL;
171
 
        }
 
307
        if (!segtype)
 
308
                return_NULL;
172
309
 
173
310
        segtype->cmd = cmd;
174
311
        segtype->ops = &_snapshot_ops;
176
313
        segtype->private = NULL;
177
314
        segtype->flags = SEG_SNAPSHOT;
178
315
 
 
316
#ifdef DMEVENTD
 
317
        if (_get_snapshot_dso_path(cmd, &dso))
 
318
                segtype->flags |= SEG_MONITORED;
 
319
#endif
179
320
        log_very_verbose("Initialised segtype: %s", segtype->name);
180
321
 
181
322
        return segtype;