Skip to content

Commit

Permalink
Support duplicate volume names in target-mount (#397)
Browse files Browse the repository at this point in the history
  • Loading branch information
Schamper authored Sep 22, 2023
1 parent fb4eef4 commit ae90905
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 4 deletions.
18 changes: 14 additions & 4 deletions dissect/target/tools/mount.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from dissect.target.helpers.mount import DissectMount

HAS_FUSE = True
except ImportError:
except Exception:
HAS_FUSE = False

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -51,12 +51,22 @@ def main():
fname = f"disks/disk_{i}"
vfs.map_file_fh(fname, d)

vnames = {}
for i, v in enumerate(t.volumes):
fname = f"volumes/{v.name or f'volume_{i}'}"
vfs.map_file_fh(fname, v)
basename = f"{v.name or f'volume_{i}'}"
fname = basename

j = 1
while fname in vnames:
fname = f"{basename}_{j}"
j += 1

vnames[v] = fname
vnames.setdefault(basename, []).append(v)
vfs.map_file_fh(f"volumes/{fname}", v)

for i, fs in enumerate(t.filesystems):
fname = f"filesystems/{fs.volume.name if fs.volume else f'fs_{i}'}"
fname = f"filesystems/{vnames[fs.volume] if fs.volume else f'fs_{i}'}"
vfs.mount(fname, fs)

# This is kinda silly because fusepy will convert this back into string arguments
Expand Down
44 changes: 44 additions & 0 deletions tests/test_tools_mount.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from io import BytesIO
from unittest.mock import patch

import pytest

from dissect.target.filesystem import VirtualFilesystem
from dissect.target.target import Target
from dissect.target.tools.mount import main as target_mount
from dissect.target.volume import Volume


def test_duplicate_volume_name(mock_target: Target, monkeypatch: pytest.MonkeyPatch) -> None:
with monkeypatch.context() as m:
m.setattr("sys.argv", ["target-mount", "mock-target", "mock-mount"])
m.setattr("dissect.target.tools.mount.HAS_FUSE", True)

with patch("dissect.target.tools.mount.Target") as MockTarget, patch(
"dissect.target.tools.mount.FUSE", create=True
) as MockFUSE, patch("dissect.target.tools.mount.DissectMount", create=True) as MockDissectMount:
MockTarget.open.return_value = mock_target

mock_target.volumes.add(Volume(BytesIO(), 1, 0, 0, None, name="first"))
mock_target.volumes.add(Volume(BytesIO(), 2, 0, 0, None, name="second"))
mock_target.volumes.add(Volume(BytesIO(), 3, 0, 0, None, name="second_1"))
mock_target.volumes.add(Volume(BytesIO(), 4, 0, 0, None, name="second"))

mock_fs = VirtualFilesystem()
mock_fs.volume = mock_target.volumes[1]
mock_target.filesystems.add(mock_fs)
mock_fs = VirtualFilesystem()
mock_fs.volume = mock_target.volumes[2]
mock_target.filesystems.add(mock_fs)
mock_fs = VirtualFilesystem()
mock_fs.volume = mock_target.volumes[3]
mock_target.filesystems.add(mock_fs)

target_mount()

MockFUSE.assert_called_once()
MockDissectMount.assert_called_once()
vfs = MockDissectMount.call_args[0][0]

assert vfs.listdir("/volumes") == ["first", "second", "second_1", "second_2"]
assert vfs.listdir("/filesystems") == ["second", "second_1", "second_2"]

0 comments on commit ae90905

Please sign in to comment.