Commit Graph

35 Commits

Author SHA1 Message Date
David Disseldorp
29e4402a82 lklfuse: add lock parameter to avoid duplicate mounts
This lock-while-mounted behaviour is similar to what QEMU does, and can
help avoid duplicate mounts.
Allowing for an explicit lock path that differs from the filesystem
image / block device path was intentional, to ensure non-flock
supporting filesystems can still be used. Also, there are cases where
a block device and partition (e.g. sda and sda1) can both provide access
to the same filesystem image, in which case an FS-ID based lock would
make sense.

Signed-off-by: David Disseldorp <ddiss@suse.de>
2025-07-04 14:01:17 +10:00
David Disseldorp
727e896158 lklfuse: add lseek hook
This allows for SEEK_HOLE / SEEK_DATA, e.g.
/run/lklfuse-sda# xfs_io -f ./seekme
xfs_io> truncate 1M
xfs_io> statx -m all
  fd.path = "./seekme"
  fd.flags = non-sync,non-direct,read-write
  stat.ino = 136
  stat.type = regular file
  stat.size = 1048576
  stat.blocks = 0
  xfs_io> pwrite 100K 1k
  wrote 1024/1024 bytes at offset 102400
  1 KiB, 1 ops; 0.0002 sec (3.439 MiB/sec and 3521.1268 ops/sec)
  xfs_io> pwrite 512K 1k
  wrote 1024/1024 bytes at offset 524288
  1 KiB, 1 ops; 0.0002 sec (4.585 MiB/sec and 4694.8357 ops/sec)
  xfs_io> seek -d 0
  Whence  Result
  DATA    102400
  xfs_io> seek -h 102400
  Whence  Result
  HOLE    106496
  xfs_io> seek -d 106496
  Whence  Result
  DATA    524288

Signed-off-by: David Disseldorp <ddiss@suse.de>
2025-02-28 21:09:50 +11:00
David Disseldorp
88de85c21c lklfuse: add copy_file_range hook
The copy_file_range() syscall allows filesystems to optimize a copy
workload by using reflinks or server-side offload. It can be triggered
via e.g.
	xfs_io -f -c "copy_range copysrc" copydest

Without this hook, (kernel) fuse currently falls back to manual
read/write via splice_copy_file_range().

Signed-off-by: David Disseldorp <ddiss@suse.de>
2025-02-28 21:08:11 +11:00
David Disseldorp
d8aedcd3bc lklfuse: fallback to read-only mount on EACCES
This matches the behaviour of Linux mount helper, e.g.
  mount("/dev/loop0p1", "/mnt", "iso9660", 0, NULL) = -1 EACCES
  mount("/dev/loop0p1", "/mnt", "iso9660", MS_RDONLY, NULL) = 0
  WARNING: source write-protected, mounted read-only.

Signed-off-by: David Disseldorp <ddiss@suse.de>
2025-02-21 23:05:14 +11:00
David Disseldorp
0692c1e050 lkl: fix 32-bit timespec casts
On 32-bit architectures, struct lkl_timespec is 2*sizeof(long) while
__lkl__kernel_timespec is 2*sizeof(long long); casting these pointer
types is unsafe.

Fixes: 3d4047ac9a ("lkl: follow up fixes after v5.1 merge (y2038)")
Signed-off-by: David Disseldorp <ddiss@suse.de>
2025-02-06 09:47:30 +11:00
David Disseldorp
b42cf5fbc6 lklfuse: map more open flags
Proper open flag semantics are important for some applications and tests
such as xfstests generic/130 (for O_TRUNCATE). Pass all open flags from
fuse through to the corresponding LKL open syscall, with the exception
of O_CREAT, O_EXCL and O_NOCTTY, which fuse handles internally. Other
flags may also be filtered out by fuse.

Signed-off-by: David Disseldorp <ddiss@suse.de>
2024-06-27 14:31:57 +10:00
David Disseldorp
72b7ed239e lklfuse: parse mount flags
Generic VFS mount options are normally parsed by the mount binary and
mapped to MS_X mount flags. lklfuse should do the same for kernel mount
options.
This implementation includes a simple string -> flag map, with
corresponding inverted noX flags.

Signed-off-by: David Disseldorp <ddiss@suse.de>
2024-06-27 14:26:10 +10:00
David Disseldorp
b8618cd3c6 lklfuse: enable fuse_config.use_ino
lkl provides valid st_ino values via the getattr and readdir hooks, so
it makes sense to have fuse use them.

Signed-off-by: David Disseldorp <ddiss@suse.de>
2024-06-04 14:32:52 +10:00
David Disseldorp
d00ad61db9 lklfuse: disable fuse lookup and attr caches
As found by xfstests generic/002, fuse attr caching appears to be broken
in that it doesn't invalidate/update st_nlink following a link or
unlink, instead returning a stale value.
Regardless, there's no need to enable fuse caching, given that lkl
provides its own regular dcache.

Signed-off-by: David Disseldorp <ddiss@suse.de>
2024-06-04 05:56:45 +02:00
David Disseldorp
fc0d27b8b3 lklfuse: update to libfuse3
Update to the new libfuse3 API, which has a number of attractive
features for lkl:
- an lseek() hook with SEEK_DATA / SEEK_HOLE
- copy_file_range()
- RENAME_NOREPLACE and RENAME_EXCHANGE.

Aside from passing through the rename flags, the remaining features
still need to be added to lklfuse. This commit attempts to be a direct
switch over to the new API.

The last upstream release of libfuse2 was in 2019 (2.9.9), so it makes
sense to upgrade regardless of the new functionality.

Signed-off-by: David Disseldorp <ddiss@suse.de>
2024-05-30 20:04:01 +10:00
David Disseldorp
71ef8cc489 lklfuse: set lkl clock time to the host walltime
This ensures that file times aren't stuck around Epoch.

Signed-off-by: David Disseldorp <ddiss@suse.de>
2024-05-30 17:25:01 +10:00
David Disseldorp
3c57c3108e lklfuse: fix utimens mtime
The utimens array layout is { atime, mtime } but in copying the values
from timespec to lkl_timespec, fuse source array offset 0 (atime) is
used for both lkl_timespec atime and mtime values.

Signed-off-by: David Disseldorp <ddiss@suse.de>
2024-05-30 17:25:01 +10:00
David Disseldorp
925c6f7f35 lklfuse: show default for --mb
Fix a typo while there.

Signed-off-by: David Disseldorp <ddiss@suse.de>
2024-05-30 17:25:01 +10:00
Octavian Purdila
8d3b903199 lkl: add init and cleanup APIs
Add new APIs for LKL initialization and cleanup in preparation for
KASAN support:

 * lkl_init - should be called before any other LKL API

 * lkl_cleanup - should be called after lkl_sys_halt and once called
   no other LKL APIs can be issued until lkl_init is called again

This change is not API backwards compatible. All LKL applications need
to be changed to call lkl_init() and update the lkl_start_kernel()
call to match the new function prototype.

Signed-off-by: Octavian Purdila <tavip@google.com>
2022-11-27 07:59:03 +00:00
Hajime Tazaki
3d4047ac9a lkl: follow up fixes after v5.1 merge (y2038)
This commit fixups the 32-bit compat syscall to properly work under new
time_t 64bit environment.

Signed-off-by: Hajime Tazaki <thehajime@gmail.com>
2019-08-09 08:53:08 +09:00
Rafael Gieschke
db9dea36fc lkl tools: lklfuse: Fix lchown(2) on symlinks
Resolving symlinks on `chown()` calls will have already been handled when
the call reaches the FUSE layer. Thus, `chown()` actually has to be
treated as `lchown()` internally.

Test (before patch):

```
truncate --size 10M test.raw
mkfs.ext4 test.raw
mkdir mnt
lklfuse -d -o type=ext4 test.raw mnt
cd mnt
ln -s missing-dest test

chown 100:100 test
 # chown: cannot dereference 'test': No such file or directory

 # readlink /test 4097
 #    unique: 247, success, outsize: 28
 # unique: 248, opcode: LOOKUP (1), nodeid: 1, insize: 53, pid: 2201
 # LOOKUP /missing-dest
 # getattr /missing-dest
 #    unique: 248, error: -2 (No such file or directory), outsize: 16

chown 100:100 test -h
 # chown: changing ownership of 'test': No such file or directory

 # chown /test 100 100
 #    unique: 253, error: -2 (No such file or directory), outsize: 16
```

Signed-off-by: Rafael Gieschke <rafael.gieschke@rz.uni-freiburg.de>
2018-12-31 02:16:19 +01:00
Quentin Anglade
aafdcdbdb5 lkl tools: lklfuse: add read-only option in help
Signed-off-by: Quentin Anglade <quentin.anglade@objectif-libre.com>
2018-08-20 09:59:39 +02:00
Hajime Tazaki
bc3fe96d34 lkl: add LKL_HIJACK_BOOT_CMDLINE option to configure boot cmdline
This patch changes the API of lkl_start_kernel().  The memsize parameter
is now able to specify via this env variable with "mem=100M" string.

Also this patch includes 2 API incompatibility.

1. lkl_start_kernel() now doesn't have memsize argument
2. LKL_HIJACK_NET_IP=dhcp is now obsolted - use ip=dhpc in
LKL_HIJACK_BOOT_CMDLINE instead.

Signed-off-by: Hajime Tazaki <thehajime@gmail.com>
2017-02-10 17:45:55 +09:00
Octavian Purdila
63befd1d0a lkl tools: add support for mounting partitions
This patch adds support for mounting partitions to various LKL fs
tools.

Signed-off-by: Octavian Purdila <tavi@cs.pub.ro>
2016-12-14 19:02:34 +02:00
Octavian Purdila
22ca35119e lkl tools: lib: fs: add parition parameter to mount and umount APIs
This adds support for mounting and unmounting for disk partitions.

NOTE: this patch breaks the user APIs.

Signed-off-by: Octavian Purdila <tavi@cs.pub.ro>
2016-12-14 18:33:22 +02:00
Octavian Purdila
5c74652f85 lkl tools: lklfuse: disabled multihreaded mode
We can't properly support it because multithreading LKL leaks threads
and the number of concurrent threads is limited to the maximum numbers
of interrupts (64 on 64bit systems, 32 otherwise).

Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
2016-08-19 16:30:59 +03:00
Octavian Purdila
685882ffcd lkl tools: lklfuse: add support for mount options
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
2016-08-15 19:03:39 +03:00
Adygzhy Ondar
e05e51a987 lkl: Convert union lkl_disk to struct, add lkl_disk_remove function 2016-06-07 12:19:37 +03:00
Kaho Ng
4db2ab5ed3 lklfuse: call fuse_umount() first, then follow by fuse_destroy(). 2016-03-09 21:50:44 +08:00
Octavian Purdila
26c335e57d lkl: avoid colisions with common system headers defines
Some system headers defines use unprotected global defines such as
sa_handler which collides with the names of LKL structure fields.

Define them in uapi/asm/syscalls.h so that they are replaced by the
headers install scripts.

Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
2016-02-09 12:14:43 +02:00
Octavian Purdila
b8b21e562c lkl tools: fix utimens
lklfuse_utimens doesn't call utimensat with the AT_SYMLINK_NOFOLLOW
flag.

This makes untar fail if it extracts a symlink before its target and
attempts to set the mtime. lklfuse will follow the broken link and
return ENOENT.

Upper layers translate utimensat on a symlink to the link or the target
depending on the flags before calling utimens on the VFS, which is why
FUSE does not receive the flags.

Simple repro that fails in an lklfuse mount:

ln -s bad link
touch --no-dereference link
This bug originates in older FUSE examples, and has been fixed:

http://marc.info/?l=fuse-devel&m=130902410132197&w=2
http://unix.stackexchange.com/questions/89886/modify-date-of-symlink-on-bindfs

This fixes github issue #60.

Reported-by: Ryan Hitchman <hitchmanr@gmail.com>
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
2016-02-04 20:41:52 +02:00
Octavian Purdila
d1a92bfa44 lkl tools: rename lkl_disk_backstore to lkl_disk
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
2016-01-06 06:56:41 +02:00
Octavian Purdila
5c865ecdee lkl: rework system call numbers and stub generation
Use asm-generic system call numbers instead of redefining them and use
the __SYSCALL macro to initialize the system call table.

System call stubs are now generated automatically by gathering the
SYSCALL_DEFINE() macros and inserting them in uapi/asm/syscalls.h with
the headers_install.py script.

This patch also changes the way we deal with 64/32 bit specific system
calls (e.g. newstatfs vfs statfs64). Instead of always forcing defining
the *64 version use wrappers in the host library headers.

Note that this change breaks the library APIs.

Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
2015-12-04 00:40:40 +02:00
Octavian Purdila
1cb1cf9e76 lkl tools: lklfuse: add memory command line parameter
Allow the user to specify how much memory to allocate for LKL. Also
remove a debug printf.

Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
2015-11-19 21:32:39 +02:00
Octavian Purdila
4a0c6b4aa5 lkl tools: lklfuse: fix segfault when started in background
Because we open the disk file image after fuse_daemonize (which
changes the current directory) opening the disk file failed if the
filename was not absolute.

Also, the error path was wrong after commit 407679a460 (lkl tools:
lklfuse: initialize lkl after going in the background) which caused a
lkl syscall to be issued even though lkl was not started.

To fix this issue and to allow better error report we now open the
disk file image before fuse_daemonize().

Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
2015-11-19 20:36:01 +02:00
Octavian Purdila
407679a460 lkl tools: lklfuse: initialize lkl after going in the background
This fixes an issue where fuse blocks every filesystem request is
lklfuse is not started in the background.

Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
2015-11-17 23:51:25 +02:00
Conrad Meyer
30be53e544 lkl tools: lklfuse: Add fgetattr, create FUSE calls
Comment the remaining methods in the FUSE vtable.

Signed-off-by: Conrad Meyer <cem@FreeBSD.org>
2015-11-13 13:53:46 +02:00
Conrad Meyer
ce68a0cc7f lkl tools: Fix compiler warnings
cptofs.c: In function ‘main’:
cptofs.c:429:2: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
  if (disk_id < 0) {

fs2tar.c:355:2: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
  if (disk_id < 0) {
  ^
tests/boot.c: In function ‘printk’:
tests/boot.c:54:8: error: ignoring return value of ‘write’, declared with attribute warn_unused_result [-Werror=unused-result]
   write(STDOUT_FILENO, str, len);
        ^
lib/posix-host.c: In function ‘print’:
lib/posix-host.c:20:7: error: ignoring return value of ‘write’, declared with attribute warn_unused_result [-Werror=unused-result]
  write(STDOUT_FILENO, str, len);

lib/fs.c: In function ‘lkl_mount_dev’:
lib/fs.c:72:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  if (mnt_str_len < sizeof("/mnt/xxxxxxxx"))
                  ^
lib/utils.c: In function ‘lkl_strerror’:
lib/utils.c:147:10: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  if (err >= sizeof(lkl_err_strings) / sizeof(const char *))

lib/virtio.c: In function ‘virtio_read’:
lib/virtio.c:216:19: warning: ‘val’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  *(uint32_t *)res = htole32(val);

lklfuse.c: In function ‘lklfuse_readlink’:
lklfuse.c:136:10: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  if (ret == len)
          ^
lklfuse.c: In function ‘lklfuse_read’:
lklfuse.c:234:23: warning: signed and unsigned type in conditional expression [-Wsign-compare]
  return ret < 0 ? ret : orig_size - size;
                       ^
lklfuse.c: In function ‘lklfuse_write’:
lklfuse.c:253:23: warning: signed and unsigned type in conditional expression [-Wsign-compare]
  return ret < 0 ? ret : orig_size - size;

Signed-off-by: Conrad Meyer <cem@FreeBSD.org>
[Octavian: change lkl_mount_dev to take unsigned int size arg, squashed into single commit]
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
2015-11-11 21:16:06 +02:00
Conrad Meyer
5ee93e6452 lkl: sys_statfs64 takes a middle size parameter
Signed-off-by: Conrad Meyer <cem@FreeBSD.org>
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
2015-11-11 21:01:43 +02:00
Octavian Purdila
2a3cf55c0f lkl tools: add lklfuse
Add a simple fuse based program that can mount filesystem in userspace
using LKL.

Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
2015-11-08 06:27:29 +02:00