aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-thin.c
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2012-06-02 19:30:01 -0400
committerAlasdair G Kergon <agk@redhat.com>2012-06-02 19:30:01 -0400
commitcc8394d86f045b86ff303d3c9e4ce47d97148951 (patch)
treead37143c9709f523fb2ca9fc5ac9de75e9a011f9 /drivers/md/dm-thin.c
parenta24c25696b7133dd534d7a9436e576af79d9ce3b (diff)
dm thin: provide userspace access to pool metadata
This patch implements two new messages that can be sent to the thin pool target allowing it to take a snapshot of the _metadata_. This, read-only snapshot can be accessed by userland, concurrently with the live target. Only one metadata snapshot can be held at a time. The pool's status line will give the block location for the current msnap. Since version 0.1.5 of the userland thin provisioning tools, the thin_dump program displays the msnap as follows: thin_dump -m <msnap root> <metadata dev> Available here: https://github.com/jthornber/thin-provisioning-tools Now that userland can access the metadata we can do various things that have traditionally been kernel side tasks: i) Incremental backups. By using metadata snapshots we can work out what blocks have changed over time. Combined with data snapshots we can ensure the data doesn't change while we back it up. A short proof of concept script can be found here: https://github.com/jthornber/thinp-test-suite/blob/master/incremental_backup_example.rb ii) Migration of thin devices from one pool to another. iii) Merging snapshots back into an external origin. iv) Asyncronous replication. Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-thin.c')
-rw-r--r--drivers/md/dm-thin.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index db1b041ce975..37fdaf81bd1f 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -2284,6 +2284,36 @@ static int process_set_transaction_id_mesg(unsigned argc, char **argv, struct po
2284 return 0; 2284 return 0;
2285} 2285}
2286 2286
2287static int process_reserve_metadata_snap_mesg(unsigned argc, char **argv, struct pool *pool)
2288{
2289 int r;
2290
2291 r = check_arg_count(argc, 1);
2292 if (r)
2293 return r;
2294
2295 r = dm_pool_reserve_metadata_snap(pool->pmd);
2296 if (r)
2297 DMWARN("reserve_metadata_snap message failed.");
2298
2299 return r;
2300}
2301
2302static int process_release_metadata_snap_mesg(unsigned argc, char **argv, struct pool *pool)
2303{
2304 int r;
2305
2306 r = check_arg_count(argc, 1);
2307 if (r)
2308 return r;
2309
2310 r = dm_pool_release_metadata_snap(pool->pmd);
2311 if (r)
2312 DMWARN("release_metadata_snap message failed.");
2313
2314 return r;
2315}
2316
2287/* 2317/*
2288 * Messages supported: 2318 * Messages supported:
2289 * create_thin <dev_id> 2319 * create_thin <dev_id>
@@ -2291,6 +2321,8 @@ static int process_set_transaction_id_mesg(unsigned argc, char **argv, struct po
2291 * delete <dev_id> 2321 * delete <dev_id>
2292 * trim <dev_id> <new_size_in_sectors> 2322 * trim <dev_id> <new_size_in_sectors>
2293 * set_transaction_id <current_trans_id> <new_trans_id> 2323 * set_transaction_id <current_trans_id> <new_trans_id>
2324 * reserve_metadata_snap
2325 * release_metadata_snap
2294 */ 2326 */
2295static int pool_message(struct dm_target *ti, unsigned argc, char **argv) 2327static int pool_message(struct dm_target *ti, unsigned argc, char **argv)
2296{ 2328{
@@ -2310,6 +2342,12 @@ static int pool_message(struct dm_target *ti, unsigned argc, char **argv)
2310 else if (!strcasecmp(argv[0], "set_transaction_id")) 2342 else if (!strcasecmp(argv[0], "set_transaction_id"))
2311 r = process_set_transaction_id_mesg(argc, argv, pool); 2343 r = process_set_transaction_id_mesg(argc, argv, pool);
2312 2344
2345 else if (!strcasecmp(argv[0], "reserve_metadata_snap"))
2346 r = process_reserve_metadata_snap_mesg(argc, argv, pool);
2347
2348 else if (!strcasecmp(argv[0], "release_metadata_snap"))
2349 r = process_release_metadata_snap_mesg(argc, argv, pool);
2350
2313 else 2351 else
2314 DMWARN("Unrecognised thin pool target message received: %s", argv[0]); 2352 DMWARN("Unrecognised thin pool target message received: %s", argv[0]);
2315 2353
@@ -2369,7 +2407,7 @@ static int pool_status(struct dm_target *ti, status_type_t type,
2369 if (r) 2407 if (r)
2370 return r; 2408 return r;
2371 2409
2372 r = dm_pool_get_held_metadata_root(pool->pmd, &held_root); 2410 r = dm_pool_get_metadata_snap(pool->pmd, &held_root);
2373 if (r) 2411 if (r)
2374 return r; 2412 return r;
2375 2413
@@ -2465,7 +2503,7 @@ static struct target_type pool_target = {
2465 .name = "thin-pool", 2503 .name = "thin-pool",
2466 .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE | 2504 .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE |
2467 DM_TARGET_IMMUTABLE, 2505 DM_TARGET_IMMUTABLE,
2468 .version = {1, 1, 0}, 2506 .version = {1, 2, 0},
2469 .module = THIS_MODULE, 2507 .module = THIS_MODULE,
2470 .ctr = pool_ctr, 2508 .ctr = pool_ctr,
2471 .dtr = pool_dtr, 2509 .dtr = pool_dtr,