Skip to content

Commit 48f17d8

Browse files
Path for zfs diff bug and add move V feature
zfs diff has an issue that spaces in file names are replaced with \0040. Added patch to correct this condition. Also added feature to have a move flag for diffs (V). By default zfs diff returns R for Rename and Move but new flag on get_diffs allows for distinction between rename (R) and move (V).
1 parent d7649f5 commit 48f17d8

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ See examples folder for code examples
133133
# - + The path has been created
134134
# - M The path has been modified
135135
# - R The path has been renamed
136+
# - V The path has moved
137+
# get_move - Derrive the V flag for paths that have moved.
138+
# By default zfs returns R for renamed and moved paths.
136139
```
137140

138141
### `<Snapshot>.snap_path`

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "zfslib"
3-
version = "0.12.0"
3+
version = "0.13.0"
44
description = "ZFS Utilities For Python3"
55
license = "MIT"
66
authors = ["Timothy C. Quinn"]

src/zfslib/zfslib.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,8 @@ def __init__(self, pool, name, parent=None):
578578
# - + The path has been created
579579
# - M The path has been modified
580580
# - R The path has been renamed
581-
def get_diffs(self, snap_from, snap_to=None, include=None, exclude=None, file_type=None, chg_type=None):
581+
# - V The path has been moved
582+
def get_diffs(self, snap_from, snap_to=None, include=None, exclude=None, file_type=None, chg_type=None, get_move:bool=False):
582583
self.assertHaveMounts()
583584
assert self.mounted, "Cannot get diffs for Unmounted Dataset. Verify mounted flag on Dataset before calling"
584585

@@ -597,6 +598,7 @@ def __tv(k, v):
597598
if isinstance(v, list): return v
598599
raise AssertionError(f"{k} can only be a str or list. Got: {type(v)}")
599600

601+
if chg_type == 'V': get_move = True
600602

601603
file_type = __tv('file_type', file_type)
602604
chg_type = __tv('chg_type', chg_type)
@@ -631,7 +633,7 @@ def __row(s):
631633
for i, row in enumerate(rows):
632634
# if i == 429:
633635
# print("HERE")
634-
d = Diff(row, snap_left, snap_right)
636+
d = Diff(row, snap_left, snap_right, get_move=get_move)
635637
if d.path_full.find('(on_delete_queue)') > 0:
636638
# It looks to be an artefact of ZFS that does not actually exist in FS
637639
# https://github.com/openzfs/zfs/blob/master/lib/libzfs/libzfs_diff.c
@@ -798,8 +800,9 @@ class Diff():
798800
,'+': 'The path has been created'
799801
,'M': 'The path has been modified'
800802
,'R': 'The path has been renamed'
803+
,'V': 'The path has been moved'
801804
}
802-
def __init__(self, row, snap_left, snap_right):
805+
def __init__(self, row, snap_left, snap_right, get_move:bool=False):
803806
self.no_from_snap=False
804807
self.to_present=False
805808
if isinstance(snap_left, str) and snap_left == '(na-first)':
@@ -829,6 +832,13 @@ def __init__(self, row, snap_left, snap_right):
829832
else:
830833
raise Exception(f"Unexpected len: {len(row)}. Row = {row}")
831834

835+
# Derrive Move change type
836+
if get_move and chg_type == 'R' and path_new is not None:
837+
chg_type = 'V'
838+
839+
# Fix issue related to https://github.com/openzfs/zfs/issues/6318
840+
path = path.replace("\\0040", " ")
841+
832842
chg_time = datetime.fromtimestamp(int(inode_ts[:inode_ts.find('.')]))
833843
self.chg_ts = inode_ts
834844
self.chg_time = chg_time
@@ -871,7 +881,7 @@ def _get_snap_path_right(self):
871881
if self.to_present:
872882
return self.path_full
873883
snap_path = self.snap_right.snap_path
874-
path_full = self.path_full_new if self.chg_type == 'R' else self.path_full
884+
path_full = self.path_full_new if self.chg_type in ('R','V') else self.path_full
875885
return "{}{}".format(snap_path, path_full.replace(self.snap_left.dataset.mountpoint, ''))
876886
snap_path_right = property(_get_snap_path_right)
877887

0 commit comments

Comments
 (0)