Commit graph

748 commits

Author SHA1 Message Date
Thomas Waldmann
f5d2e67129 whitespace changes by coala 2017-06-06 04:46:15 +02:00
Thomas Waldmann
fed5873e29 remove attic dependency of the tests, fixes #2505
attic.tar.gz contains a repo + corresponding keyfile - all the
upgrader module tests need.

.tar.gz because the .tar was 20x bigger.
2017-06-06 04:26:48 +02:00
TW
88669611b1 Merge pull request #2615 from ThomasWaldmann/suppress-timestamp-future-errmsg
tests: suppress tar's future timestamp warning
2017-06-05 16:59:12 +02:00
Thomas Waldmann
4e6c56538a test: suppress tar's future timestamp warning
in this case, it is expected as we archived a file with such a ts.
2017-06-05 15:43:13 +02:00
Marian Beermann
909f099b1a algorithms.checksums: work around GCC 4.4 bug by disabling CLMUL
Also disabling this code path for 4.5; 4.6 was tested iirc.
2017-06-05 15:07:49 +02:00
TW
50bcd7843d recreate: keep timestamps as in original archive, fixes #2384 (#2607)
the timestamps of the recreated archive (in the archive metadata and
also in the manifest) are now as they were for the original archive.

they are important metadata about the archive contents and should
therefore be kept "as is".

note: when using -v --stats, the timestamps shown there for recreate
      are about the recreate start/end/duration.
2017-06-05 09:59:17 +02:00
enkore
60811fc2ce Merge pull request #2593 from enkore/issue/2384.1
recreate: if single archive is not processed, exit 2
2017-06-04 23:01:20 +02:00
Thomas Waldmann
ffcf6b76b6 DEFAULT_SEGMENTS_PER_DIR = 1000
prettier increments for the directory names.
2017-06-03 21:54:41 +02:00
TW
a2d08e3186 Merge pull request #2575 from edgimar/master
patterns: don't recurse with ! / --exclude for pf:, fixes #2509
2017-06-03 21:47:11 +02:00
Mark Edgington
fd0215c3c2 patterns: don't recurse with !/--exclude for path-prefix (pf:)
Fixes issue #2509
2017-06-03 12:13:32 -04:00
Marian Beermann
8ad309ae2a recreate: if single archive is not processed, exit 2 2017-06-03 15:47:01 +02:00
Marian Beermann
8dfe2a8080 remote: show path in PathNotAllowed
not 100 % sure whether "if old_server" is required, so let's play it safe.
1.0 -> 1.1 server is no problem.
2017-06-03 15:07:08 +02:00
Marian Beermann
07fbba4ee9 serve: add --restrict-to-repository 2017-06-03 15:07:08 +02:00
Marian Beermann
5af66dbb12 cache sync: add more refcount tests 2017-06-03 15:02:27 +02:00
Marian Beermann
4faaa7d1fa RepositoryCache: abort on data corruption 2017-06-03 12:27:35 +02:00
Marian Beermann
b544af2af1 RepositoryCache: checksum decrypted cache 2017-06-03 12:23:23 +02:00
Marian Beermann
54e023c75a repository: add complementary index corruption test 2017-06-02 21:44:45 +02:00
Marian Beermann
2e067a7ae8 repository: add refcount corruption test 2017-06-02 21:44:45 +02:00
Marian Beermann
f61ee038d0 repository: checksum index and hints 2017-06-02 21:44:45 +02:00
Marian Beermann
5b3667b617 cache sync: macros in all-caps 2017-06-02 19:31:56 +02:00
Marian Beermann
795cdfc9ab cache sync: move stat initialization to main unpack 2017-06-02 19:30:53 +02:00
Marian Beermann
cb98cb838d fuse: fix read(2) caching data in metadata cache
The OS page cache is responsible for handling this and is much more
empowered to do a good job at that than Borg.
2017-06-02 17:43:15 +02:00
Marian Beermann
67b97f2223 cache sync: cleanup progress handling, unused parameters 2017-06-02 17:43:15 +02:00
Marian Beermann
7f04e00ba2 testsuite: add TestRepositoryCache 2017-06-02 17:43:15 +02:00
Marian Beermann
835b0e5ee0 cache sync/remote: compressed, decrypted cache 2017-06-02 17:43:15 +02:00
Marian Beermann
c786a5941e CacheSynchronizer: redo as quasi FSM on top of unpack.h
This is a (relatively) simple state machine running in the
data callbacks invoked by the msgpack unpacking stack machine
(the same machine is used in msgpack-c and msgpack-python,
changes are minor and cosmetic, e.g. removal of msgpack_unpack_object,
removal of the C++ template thus porting to C and so on).

Compared to the previous solution this has multiple advantages
- msgpack-c dependency is removed
- this approach is faster and requires fewer and smaller
  memory allocations

Testability of the two solutions does not differ in my
professional opinion(tm).

Two other changes were rolled up; _hashindex.c can be compiled
without Python.h again (handy for fuzzing and testing);
a "small" bug in the cache sync was fixed which allocated too
large archive indices, leading to excessive archive.chunks.d
disk usage (that actually gave me an idea).
2017-06-02 17:43:15 +02:00
Marian Beermann
bf895950ac RepositoryCache: limit cache size
Unbounded cache size is inacceptable.

I don't see why a full-fledged repository needs to be used here, either,
since this cache requires none of the consistency or durability guarantees
made by it (and bought with a performance impact).

A notable issue is that posix_fadvise is slow (for some reason) on tmpfs,
which could eat 30-35 % of the total CPU time of a cache sync.
2017-06-02 17:43:15 +02:00
Marian Beermann
167875b753 cache sync: fix n^2 behaviour in lookup_name 2017-06-02 17:43:14 +02:00
Marian Beermann
9f8b967a6f cache sync: initialize master index to known capacity 2017-06-02 17:43:14 +02:00
Marian Beermann
740898d83b CacheSynchronizer 2017-06-02 17:43:14 +02:00
Marian Beermann
6c91a750d1 algorithms: rename crc32 to checksums 2017-06-01 21:26:42 +02:00
Marian Beermann
0221e31058 file_integrity: use xxh64 2017-06-01 21:26:42 +02:00
enkore
23d591c1c3 Merge pull request #2565 from enkore/issue/2517
Implement storage quotas
2017-06-01 14:39:17 +02:00
Marian Beermann
bcf4b4492b testsuite: add test for parse_storage_quota 2017-05-31 20:28:17 +02:00
Marian Beermann
4e6a771ee7 BORG_PASSCOMMAND: use same cmd-string splitting as BORG_RSH 2017-05-31 19:41:17 +02:00
enkore
349a4ade7c Merge pull request #2568 from enkore/issue/1101.integration.cache
1101.integration.cache
2017-05-31 19:34:43 +02:00
TuXicc
578b76af3a Added BORG_PASSCOMMAND environment variable (#2573) 2017-05-31 19:25:21 +02:00
Marian Beermann
f8b48dc8d7 remote: propagate Error.traceback correctly 2017-05-31 18:48:48 +02:00
Marian Beermann
4edf77788d Implement storage quotas 2017-05-31 18:36:03 +02:00
Marian Beermann
9032aa062b testsuite: simplify ArchiverCorruptionTestCase 2017-05-31 18:08:20 +02:00
Marian Beermann
0a5d9b6f7c cache sync: close archive chunks file before renaming 2017-05-31 18:06:28 +02:00
Marian Beermann
d35d388d9c cache integrity: handle interference from old versions 2017-05-25 17:44:01 +02:00
Marian Beermann
50ac9d914d testsuite: add ArchiverCorruptionTestCase 2017-05-25 17:44:01 +02:00
Marian Beermann
83bca02a4e file_integrity: hash_part: mix length into state 2017-05-25 17:44:01 +02:00
Marian Beermann
d463dd89aa hashindex: read/write: use hash_part for HashHeader 2017-05-25 17:44:01 +02:00
Marian Beermann
f59affe585 cache: fix possible printf issue with archive names in sync 2017-05-25 17:44:01 +02:00
Marian Beermann
addd7addfe cache: chunks.archive.d: autofix corruption 2017-05-25 17:44:01 +02:00
Marian Beermann
1dfe693003 cache: integrity checking in archive.chunks.d 2017-05-25 16:28:46 +02:00
Marian Beermann
2b518b7188 cache: add integrity checking of chunks and files caches 2017-05-25 16:28:46 +02:00
Marian Beermann
06cf15cc6d hashindex: read/write: accept file-like objects for path 2017-05-25 14:04:41 +02:00
Marian Beermann
39051ac5f1 file_integrity: split in IntegrityCheckedFile + Detached variant 2017-05-25 14:04:41 +02:00
Marian Beermann
38ed9a20af key file names: limit to 100 characters (not bytes) 2017-05-25 12:36:45 +02:00
Marian Beermann
4b8a04b5e7 key file names: remove colons from host name 2017-05-25 12:32:42 +02:00
enkore
2dcbe02e5a Merge pull request #2528 from ThomasWaldmann/follow-symlinks
document follow_symlinks requirements, check libc, fixes #2507
2017-05-25 09:26:09 +02:00
Marian Beermann
573d728f7a init: don't allow creating nested repositories 2017-05-25 00:36:50 +02:00
TW
9d82db1851 Merge pull request #2539 from RonnyPfannschmidt/avoid-repacakaging-pitfall
fail in borg package if version metadata is completely broken
2017-05-23 15:19:57 +02:00
Ronny Pfannschmidt
53d0f1fd02 fail in borg package if version metadata is completely broken
this helps to fail early when people do badly done scm based repackaging
2017-05-23 14:36:40 +02:00
Thomas Waldmann
0d406e7baf use _host to store host/ipv4/ipv6
for ipv6, it includes the outer square brackets.

the host property strips any outer square brackets.
2017-05-23 03:09:57 +02:00
Benedikt Neuffer
d99aff1276 ipv6 address support
also: Location: more informative exception when parsing fails
2017-05-23 02:08:44 +02:00
Thomas Waldmann
6f81d24324 remove unused no_lchflags_because 2017-05-22 17:54:43 +02:00
Thomas Waldmann
efec00b39c use stat with follow_symlinks=False
should be equivalent to using os.lstat() before.
2017-05-22 17:54:42 +02:00
Thomas Waldmann
094376a8ad require and use chown with follow_symlinks=False
should be equivalent to using os.lchown() before.
2017-05-22 17:54:42 +02:00
Thomas Waldmann
b484c79bc2 document follow_symlinks requirements, check libc, fixes #2507 2017-05-22 17:54:42 +02:00
enkore
58791583d9 Merge pull request #2530 from enkore/f/compact-revisit@2
Repository compaction docs
2017-05-22 13:55:04 +02:00
Marian Beermann
869ab1a47b mount: do pre-mount checks before opening repository 2017-05-22 13:29:38 +02:00
Marian Beermann
8e24ddae06 increase DEFAULT_SEGMENTS_PER_DIR to 2000 2017-05-22 12:31:52 +02:00
enkore
dc02c79e97 Merge pull request #2546 from enkore/issue/2543
docs: add systemd warning regarding placeholders
2017-05-21 17:45:34 +02:00
Marian Beermann
384d7635a4 docs: add systemd warning regarding placeholders 2017-05-21 17:22:29 +02:00
edgimar
ed14181cc1 add test for preserved intermediate folder permissions (#2477)
This tests whether the permissions metadata is preserved when a folder is excluded but still recursed into to find a matching file in a subfolder.
2017-05-21 17:18:56 +02:00
Marian Beermann
e689d8f2f6 mount: check llfuse is installed before asking for passphrase 2017-05-21 11:24:09 +02:00
Marian Beermann
85aabeb9c7 testsuite: call setup_logging after destroying logging config 2017-05-20 22:55:17 +02:00
Marian Beermann
58edbe15f4 xattr: document API 2017-05-20 18:50:10 +02:00
Marian Beermann
c6309b148b fuse: fix crash if empty (None) xattr is read 2017-05-20 18:50:10 +02:00
enkore
5db667881a Merge pull request #2500 from enkore/issue/2487
Verify most operations against securitymanager
2017-05-20 16:00:49 +02:00
Marian Beermann
c23e1e28c6 use assert_secure for all commands that use the manifest
This already excludes the debug commands that we wouldn't want this on.
2017-05-20 14:58:17 +02:00
Marian Beermann
482b65eaea cache: extract CacheConfig class 2017-05-20 14:58:17 +02:00
Marian Beermann
97e9603531 implement --debug-topic for remote servers 2017-05-20 12:55:03 +02:00
Marian Beermann
b3b555395c remote: clarify remote log handling comments 2017-05-20 12:55:03 +02:00
Marian Beermann
5f4d97ff2b remote: restore "Remote:" prefix (as used in 1.0.x) 2017-05-20 12:54:57 +02:00
Marian Beermann
18a2902c9c rpc negotiate: enable v3 log protocol only for supported clients
avoid seeing JSON log output when a 1.1.0b<5 client talks to a
1.1.0b>6 server.
2017-05-20 12:54:48 +02:00
Marian Beermann
fc105b49b1 fix --progress and logging in general for remote 2017-05-20 12:54:48 +02:00
Marian Beermann
9778c103ef serve: fix incorrect type of exception_short for Errors 2017-05-17 16:27:52 +02:00
Marian Beermann
042a4b960b export-tar: test strip-components and hardlinks for partial export 2017-05-17 11:04:20 +02:00
Marian Beermann
293324810b introduce popen_with_error_handling to handle common user errors
(without tracebacks)
2017-05-17 10:54:39 +02:00
enkore
52fab07b3b Merge pull request #2510 from enkore/issue/2473
Add --debug-profile option
2017-05-17 00:10:14 +02:00
enkore
5788219ff4 borg export-tar (#2519) 2017-05-17 00:09:41 +02:00
Marian Beermann
6d6ae65be3 replace external script with "borg debug convert-profile" 2017-05-16 23:30:43 +02:00
Thomas Waldmann
d15c3f2d85 do not test logger name, fixes #2504
looks like PyInstaller modifies the module names.
2017-05-16 21:14:27 +02:00
Marian Beermann
a07463c96a --debug-profile: use msgpack instead of marshal by default 2017-05-16 20:52:18 +02:00
Marian Beermann
4c441c75b1 Implement --debug-profile 2017-05-16 20:52:18 +02:00
Marian Beermann
c831985bba CommonOptions: add unit test 2017-05-16 19:35:15 +02:00
Marian Beermann
150ace13cd init: document --encryption as required 2017-05-16 19:05:54 +02:00
Marian Beermann
b9efdb2ce3 refactor CommonOptions as a reusable class 2017-05-15 17:16:44 +02:00
Marian Beermann
2ab5df0217 support common options on mid-level commands (borg *key* export) 2017-05-15 17:16:27 +02:00
Marian Beermann
d5edb011f0 support common options 2017-05-14 18:45:20 +02:00
enkore
820066da5d Implement IntegrityCheckedFile (#2502)
Implement IntegrityCheckedFile

This is based on much earlier work from October 2016 by me, but is
overall simplified and changed terminology (from "signing" to
hashing and integrity checking).

See #1688 for the full history.
2017-05-12 21:38:31 +02:00
Marian Beermann
a16d81271a key: add round-trip test 2017-05-12 20:49:17 +02:00
Marian Beermann
848df38d08 Rename Key.passphrase_protected -> logically_encrypted & document 2017-05-12 20:36:23 +02:00
Marian Beermann
cad49b844e key: authenticated mode = not passphrase protected 2017-05-12 20:35:18 +02:00
enkore
9e6b8f67b9 serve: ignore --append-only when creating a repository (#2501) 2017-05-12 20:34:45 +02:00
enkore
6cd7d415ca hashindex: Use Python I/O (#2496)
- Preparation for #1688 / #1101
- Support hash indices >2 GB
- Better error reporting
2017-05-09 21:30:14 +02:00
enkore
c805adc267 Merge pull request #2489 from enkore/issue/2169
consider repokey w/o passphrase == unencrypted
2017-05-08 08:57:15 +02:00
enkore
badc79c323 Merge pull request #2488 from enkore/issue/2439
list: --json-lines for archive contents
2017-05-07 22:31:58 +02:00
Marian Beermann
1daab244c6 testsuite.archiver: normalise pytest.raises vs. assert_raises 2017-05-07 22:21:40 +02:00
Marian Beermann
d964101eb5 consider repokey w/o passphrase == unencrypted 2017-05-07 22:13:49 +02:00
Marian Beermann
be9a94c22c list: add test for handling of --json/--json-lines 2017-05-07 22:04:25 +02:00
TW
06a4e722a5 Merge pull request #2486 from enkore/f/common-progress
make --progress a common option
2017-05-06 23:08:42 +02:00
enkore
85df969c34 Merge pull request #2485 from enkore/issue/2469.2
fix --exclude and --exclude-from recursing into directories
2017-05-06 14:39:13 +02:00
Marian Beermann
a719097611 add test case for --log-json 2017-05-05 16:05:12 +02:00
Marian Beermann
2a22f93e44 list: JSON lines output for archive contents 2017-05-05 15:49:56 +02:00
Marian Beermann
bd8186f901 make --progress a common option
everything that touches the repository can take a long time and display
progress information, from compaction to replaying segments.
2017-05-05 15:12:23 +02:00
Marian Beermann
4d9fd6d13f fix --exclude and --exclude-from recursing into directories 2017-05-05 14:55:01 +02:00
Marian Beermann
ba5d6693f9 --json: fix encryption[mode] not being the cmdline name 2017-05-05 14:38:21 +02:00
Marian Beermann
a976e11a63 create crypto package with key, keymanager, low_level 2017-05-02 20:49:27 +02:00
Marian Beermann
956b50b29c move chunker to borg.algorithms 2017-05-02 19:15:01 +02:00
Marian Beermann
390aa76c72 move blake2 to borg/algorithms 2017-05-02 18:53:54 +02:00
Marian Beermann
fa381ffcbe create package borg.algorithms with borg.algorithms.crc32 module 2017-05-02 18:53:54 +02:00
Marian Beermann
ef4cdfacae patterns: use set literal instead of set([]) 2017-05-01 22:20:34 +02:00
Marian Beermann
c5e3232187 patterns: explicate translate source 2017-05-01 22:20:34 +02:00
Marian Beermann
580496b592 create patterns module 2017-05-01 22:20:33 +02:00
enkore
65bdeb47ca Merge pull request #2404 from ThomasWaldmann/limit-y2038
embrace y2038 issue to support 32bit platforms
2017-04-29 23:36:18 +02:00
Thomas Waldmann
d949d6bc7c fix invalid param issue in benchmarks
fixes CID1431887
2017-04-29 03:00:59 +02:00
enkore
c43cfb708f Merge pull request #2432 from ThomasWaldmann/beyond-repair
more clear exception if borg check does not help, fixes #2427
2017-04-28 16:06:54 +02:00
enkore
6109d223ee Merge pull request #2443 from ThomasWaldmann/verify-data-defect-chunk-processing
verify_data: fix IntegrityError handling for defect chunks, fixes #2442
2017-04-28 10:50:23 +02:00
Thomas Waldmann
f0188449c3 add hint about chunker params to borg upgrade docs, fixes #2421 2017-04-25 22:47:18 +02:00
Thomas Waldmann
ca6257dd48 clarify borg upgrade docs, fixes #2436 2017-04-25 22:21:58 +02:00
Thomas Waldmann
28b0700437 verify_data: fix IntegrityError handling for defect chunks, fixes #2442
just getting data from the repo can already raise IntegrityErrors
in LoggedIO, so we need to catch them also.

see also the code a few lines above where this is done in the same way.
2017-04-25 15:48:16 +02:00
Thomas Waldmann
de76a6b821 embrace y2038 issue to support 32bit platforms 2017-04-24 18:50:33 +02:00
TW
6f47b797f9 Merge pull request #2322 from edgimar/master
allow excluding parent and including child, fixes #2314
2017-04-23 12:58:10 +02:00
Thomas Waldmann
697942cd01 be more clear that this is a "beyond repair" case, fixes #2427 2017-04-20 19:54:45 +02:00
Marian Beermann
7b519e4769 platform.linux: get rid of "resource" module 2017-04-19 11:31:40 +02:00
Mark Edgington
798127f636 allow excluding parent and including child, fixes #2314
This fixes the problem raised by issue #2314 by requiring that each root
subtree be fully traversed.

The problem occurs when a patterns file excludes a parent directory P later
in the file, but earlier in the file a subdirectory S of P is included.
Because a tree is processed recursively with a depth-first search, P is
processed before S is.  Previously, if P was excluded, then S would not even
be considered.  Now, it is possible to recurse into P nonetheless, while not
adding P (as a directory entry) to the archive.

With this commit, a `-` in a patterns-file will allow an excluded directory
to be searched for matching descendants.  If the old behavior is desired, it
can be achieved by using a `!` in place of the `-`.

The following is a list of specific changes made by this commit:

 * renamed InclExclPattern named-tuple -> CmdTuple (with names 'val' and 'cmd'), since it is used more generally for commands, and not only for representing patterns.
 * represent commands as IECommand enum types (RootPath, PatternStyle, Include, Exclude, ExcludeNoRecurse)
 * archiver: Archiver.build_matcher() paths arg renamed -> include_paths to prevent confusion as to whether the list of paths are to be included or excluded.
 * helpers: PatternMatcher has recurse_dir attribute that is used to communicate whether an excluded dir should be recursed (used by Archiver._process())
 * archiver: Archiver.build_matcher() now only returns a PatternMatcher instance, and not an include_patterns list -- this list is now created and housed within the PatternMatcher instance, and can be accessed from there.
 * moved operation of finding unmatched patterns from Archiver to PatternMatcher.get_unmatched_include_patterns()
 * added / modified some documentation of code
 * renamed _PATTERN_STYLES -> _PATTERN_CLASSES since "style" is ambiguous and this helps clarify that the set contains classes and not instances.
 * have PatternBase subclass instances store whether excluded dirs are to be recursed.  Because PatternBase objs are created corresponding to each +, -, ! command it is necessary to differentiate - from ! within these objects.
 * add test for '!' exclusion rule (which doesn't recurse)
2017-04-12 12:06:18 -04:00
TW
9ae4bf023e Merge pull request #2188 from rciorba/hashindex_test
add extra test for the hashindex
2017-04-09 20:47:00 +02:00
Patrick Goering
f64f432e51 catch exception for os.link when hardlinks are not supported 2017-04-08 17:10:02 +02:00
Radu Ciorba
9f31dba7b5 cleanup the test and add more checks 2017-04-07 16:00:34 +03:00
Radu Ciorba
8c2064cc5a add extra test for the hashindex
Insert a few keys, delete some of them, check we still have
the values we expect, check the deleted ones aren't there.
2017-04-07 16:00:34 +03:00
Marian Beermann
03ed4d31ca recreate: expand placeholders 2017-04-06 11:37:55 +02:00
Thomas Waldmann
c7256abd84 borg rename: expand placeholders, fixes #2386 2017-04-06 01:03:24 +02:00
enkore
736a815972 Merge pull request #2342 from ThomasWaldmann/generic-hardlinks
Generic hardlinks
2017-04-05 14:34:29 +02:00
enkore
7255e3b298 Merge pull request #2387 from enkore/f/placeholders-internals
placeholders: deny access to internals and other unspecified stuff
2017-04-05 14:10:30 +02:00
enkore
9a1c1e90c1 Merge pull request #2375 from enkore/buhdf
BORG_HOSTNAME_IS_UNIQUE=yes by default.
2017-04-05 14:09:58 +02:00
Thomas Waldmann
155f38c233 remove comment about strange hardlink_masters term
(maybe revisit this later, this is not in scope of the generic hardlinks refactor)
2017-04-05 13:56:57 +02:00
Marian Beermann
cc24fa2064 format_line: whitelist instead of checking against blacklist 2017-04-05 13:51:20 +02:00
Thomas Waldmann
8f769a9b24 implement and use hardlinkable() helper 2017-04-05 13:38:27 +02:00
Thomas Waldmann
cb86bda413 extract: implement extract_helper context manager
Most code of the CM is just moved 1:1 from the regular file block.

Use the CM for regular files, FIFOs and devices, but not for:
- directories (can not have hardlinks)
- symlinks (we can not support hardlinked symlinks)
2017-04-05 13:36:09 +02:00
Thomas Waldmann
cda7465038 extract: indent code, no semantics change
prepare for a extract_helper context manager

(some changes may seem superfluous, but see the following changesets)
2017-04-05 13:36:00 +02:00
Thomas Waldmann
3cc1cdd2ed extract: refactor hardlinks related code
prepare for a extract_helper context manager

(some changes may seem superfluous, but see the following changesets)
2017-04-05 13:03:58 +02:00
Thomas Waldmann
23cc679617 no hardlinking for directories and symlinks
- nlink > 1 for dirs does not mean hardlinking
  (at least not everywhere, wondering how apple does it)
- we can not archive hardlinked symlinks due to item.source dual-use,
  see issue #2343.

likely nobody uses this anyway.
2017-04-05 13:03:53 +02:00
Thomas Waldmann
1f6dc55eab simplify char/block device file dispatching 2017-04-05 13:01:04 +02:00
Thomas Waldmann
9478e8abd0 support hardlinks via create_helper context manager
also: reduce code duplication
2017-04-05 12:58:25 +02:00