mirror of
https://github.com/zrepl/zrepl.git
synced 2025-06-19 17:27:46 +02:00
zfs: bookmark / replication cursor: handle spaces in ds names correctly
fixes #131
This commit is contained in:
parent
7d9a1b7eae
commit
ab38f24198
@ -24,35 +24,36 @@ func ZFSGetReplicationCursor(fs *DatasetPath) (*FilesystemVersion, error) {
|
|||||||
|
|
||||||
func ZFSSetReplicationCursor(fs *DatasetPath, snapname string) (guid uint64, err error) {
|
func ZFSSetReplicationCursor(fs *DatasetPath, snapname string) (guid uint64, err error) {
|
||||||
snapPath := fmt.Sprintf("%s@%s", fs.ToString(), snapname)
|
snapPath := fmt.Sprintf("%s@%s", fs.ToString(), snapname)
|
||||||
|
debug("replication cursor: snap path %q", snapPath)
|
||||||
propsSnap, err := zfsGet(snapPath, []string{"createtxg", "guid"}, sourceAny)
|
propsSnap, err := zfsGet(snapPath, []string{"createtxg", "guid"}, sourceAny)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, errors.Wrap(err, "zfs: replication cursor: get snapshot createtxg")
|
||||||
}
|
}
|
||||||
snapGuid, err := strconv.ParseUint(propsSnap.Get("guid"), 10, 64)
|
snapGuid, err := strconv.ParseUint(propsSnap.Get("guid"), 10, 64)
|
||||||
bookmarkPath := fmt.Sprintf("%s#%s", fs.ToString(), ReplicationCursorBookmarkName)
|
bookmarkPath := fmt.Sprintf("%s#%s", fs.ToString(), ReplicationCursorBookmarkName)
|
||||||
propsBookmark, err := zfsGet(bookmarkPath, []string{"createtxg"}, sourceAny)
|
propsBookmark, err := zfsGet(bookmarkPath, []string{"createtxg"}, sourceAny)
|
||||||
_, bookmarkNotExistErr := err.(*DatasetDoesNotExist)
|
_, bookmarkNotExistErr := err.(*DatasetDoesNotExist)
|
||||||
if err != nil && !bookmarkNotExistErr {
|
if err != nil && !bookmarkNotExistErr {
|
||||||
return 0, err
|
return 0, errors.Wrap(err, "zfs: replication cursor: get bookmark txg")
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
bookmarkTxg, err := strconv.ParseUint(propsBookmark.Get("createtxg"), 10, 64)
|
bookmarkTxg, err := strconv.ParseUint(propsBookmark.Get("createtxg"), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, errors.Wrap(err, "cannot parse bookmark createtxg")
|
return 0, errors.Wrap(err, "zfs: replication cursor: parse bookmark createtxg")
|
||||||
}
|
}
|
||||||
snapTxg, err := strconv.ParseUint(propsSnap.Get("createtxg"), 10, 64)
|
snapTxg, err := strconv.ParseUint(propsSnap.Get("createtxg"), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, errors.Wrap(err, "cannot parse snapshot createtxg")
|
return 0, errors.Wrap(err, "zfs: replication cursor: parse snapshot createtxg")
|
||||||
}
|
}
|
||||||
if snapTxg < bookmarkTxg {
|
if snapTxg < bookmarkTxg {
|
||||||
return 0, errors.New("replication cursor can only be advanced, not set back")
|
return 0, errors.New("zfs: replication cursor: can only be advanced, not set back")
|
||||||
}
|
}
|
||||||
if err := ZFSDestroy(bookmarkPath); err != nil { // FIXME make safer by using new temporary bookmark, then rename, possible with channel programs
|
if err := ZFSDestroy(bookmarkPath); err != nil { // FIXME make safer by using new temporary bookmark, then rename, possible with channel programs
|
||||||
return 0, err
|
return 0, errors.Wrap(err, "zfs: replication cursor: destroy current cursor")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := ZFSBookmark(fs, snapname, ReplicationCursorBookmarkName); err != nil {
|
if err := ZFSBookmark(fs, snapname, ReplicationCursorBookmarkName); err != nil {
|
||||||
return 0, err
|
return 0, errors.Wrapf(err, "zfs: replication cursor: create bookmark")
|
||||||
}
|
}
|
||||||
return snapGuid, nil
|
return snapGuid, nil
|
||||||
}
|
}
|
||||||
|
@ -924,7 +924,7 @@ func ZFSGet(fs *DatasetPath, props []string) (*ZFSProperties, error) {
|
|||||||
return zfsGet(fs.ToString(), props, sourceAny)
|
return zfsGet(fs.ToString(), props, sourceAny)
|
||||||
}
|
}
|
||||||
|
|
||||||
var zfsGetDatasetDoesNotExistRegexp = regexp.MustCompile(`^cannot open '(\S+)': (dataset does not exist|no such pool or dataset)`)
|
var zfsGetDatasetDoesNotExistRegexp = regexp.MustCompile(`^cannot open '([^)]+)': (dataset does not exist|no such pool or dataset)`)
|
||||||
|
|
||||||
type DatasetDoesNotExist struct {
|
type DatasetDoesNotExist struct {
|
||||||
Path string
|
Path string
|
||||||
@ -1080,6 +1080,8 @@ func ZFSBookmark(fs *DatasetPath, snapshot, bookmark string) (err error) {
|
|||||||
snapname := zfsBuildSnapName(fs, snapshot)
|
snapname := zfsBuildSnapName(fs, snapshot)
|
||||||
bookmarkname := zfsBuildBookmarkName(fs, bookmark)
|
bookmarkname := zfsBuildBookmarkName(fs, bookmark)
|
||||||
|
|
||||||
|
debug("bookmark: %q %q", snapname, bookmarkname)
|
||||||
|
|
||||||
cmd := exec.Command(ZFS_BINARY, "bookmark", snapname, bookmarkname)
|
cmd := exec.Command(ZFS_BINARY, "bookmark", snapname, bookmarkname)
|
||||||
|
|
||||||
stderr := bytes.NewBuffer(make([]byte, 0, 1024))
|
stderr := bytes.NewBuffer(make([]byte, 0, 1024))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user