Implement bookmark copying

This feature allows copying existing bookmarks using

    zfs bookmark fs#target fs#newbookmark

There are some niche use cases for such functionality,
e.g. when using bookmarks as markers for replication progress.

Copying redaction bookmarks produces a normal bookmark that
cannot be used for redacted send (we are not duplicating
the redaction object).

ZCP support for bookmarking (both creation and copying) will be
implemented in a separate patch based on this work.

Overview:

- Terminology:
    - source = existing snapshot or bookmark
    - new/bmark = new bookmark
- Implement bookmark copying in `dsl_bookmark.c`
  - create new bookmark node
  - copy source's `zbn_phys` to new's `zbn_phys`
  - zero-out redaction object id in copy
- Extend existing bookmark ioctl nvlist schema to accept
  bookmarks as sources
  - => `dsl_bookmark_create_nvl_validate` is authoritative
- use `dsl_dataset_is_before` check for both snapshot
  and bookmark sources
- Adjust CLI
  - refactor shortname expansion logic in `zfs_do_bookmark`
- Update man pages
  - warn about redaction bookmark handling
- Add test cases
  - CLI
  - pyyzfs libzfs_core bindings

Reviewed-by: Matt Ahrens <matt@delphix.com>
Reviewed-by: Paul Dagnelie <pcd@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Christian Schwarz <me@cschwarz.com>
Closes #9571
This commit is contained in:
Christian Schwarz
2019-11-10 23:24:14 -08:00
committed by Brian Behlendorf
parent 7b49bbc816
commit a73f361fdb
19 changed files with 672 additions and 142 deletions
+8 -5
View File
@@ -25,6 +25,7 @@
* Copyright (c) 2017 Datto Inc.
* Copyright 2017 RackTop Systems.
* Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
* Copyright (c) 2019, 2020 by Christian Schwarz. All rights reserved.
*/
/*
@@ -1127,11 +1128,13 @@ lzc_rollback_to(const char *fsname, const char *snapname)
}
/*
* Creates bookmarks.
* Creates new bookmarks from existing snapshot or bookmark.
*
* The bookmarks nvlist maps from name of the bookmark (e.g. "pool/fs#bmark") to
* the name of the snapshot (e.g. "pool/fs@snap"). All the bookmarks and
* snapshots must be in the same pool.
* The bookmarks nvlist maps from the full name of the new bookmark to
* the full name of the source snapshot or bookmark.
* All the bookmarks and snapshots must be in the same pool.
* The new bookmarks names must be unique.
* => see function dsl_bookmark_create_nvl_validate
*
* The returned results nvlist will have an entry for each bookmark that failed.
* The value will be the (int32) error code.
@@ -1146,7 +1149,7 @@ lzc_bookmark(nvlist_t *bookmarks, nvlist_t **errlist)
int error;
char pool[ZFS_MAX_DATASET_NAME_LEN];
/* determine the pool name */
/* determine pool name from first bookmark */
elem = nvlist_next_nvpair(bookmarks, NULL);
if (elem == NULL)
return (0);