Skip to content

Commit 77cc0f1

Browse files
authored
Merge pull request #542 from ddiss/libfuse3
lklfuse: migrate to libfuse3
2 parents ab9b0d4 + fc0d27b commit 77cc0f1

File tree

3 files changed

+126
-81
lines changed

3 files changed

+126
-81
lines changed

Diff for: tools/lkl/Makefile.autoconf

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ define posix_host
8282
$(if $(filter $(1),elf64-littleaarch64),$(call aarch64_host))
8383
$(if $(filter yes,$(dpdk)),$(call virtio_net_dpdk))
8484
$(if $(filter yes,$(vde)),$(call virtio_net_vde))
85-
$(if $(strip $(call find_include,fuse.h)),$(call set_autoconf_var,FUSE,y))
85+
$(if $(strip $(call find_include,fuse3/fuse.h)),$(call set_autoconf_var,FUSE,y))
8686
$(if $(strip $(call find_include,archive.h)),$(call set_autoconf_var,ARCHIVE,y))
8787
$(if $(strip $(call find_include,linux/if_tun.h)),$(call set_autoconf_var,VIRTIO_NET_MACVTAP,y))
8888
$(if $(filter $(1),elf64-x86-64-freebsd),$(call set_autoconf_var,NEEDS_LARGP,y))

Diff for: tools/lkl/Targets

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ LDFLAGS_lib/hijack/liblkl-zpoline-$(LKL_HOST_CONFIG_POSIX) += -shared -nodefault
1414
LDLIBS_lib/hijack/liblkl-zpoline-$(LKL_HOST_CONFIG_POSIX) += -ldl -lc
1515

1616
progs-$(LKL_HOST_CONFIG_FUSE) += lklfuse
17-
LDLIBS_lklfuse-y := -lfuse
17+
LDLIBS_lklfuse-y := -lfuse3
1818

1919
progs-$(LKL_HOST_CONFIG_ARCHIVE) += fs2tar
2020
LDLIBS_fs2tar-y := -larchive

Diff for: tools/lkl/lklfuse.c

+124-79
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
#include <string.h>
88
#include <errno.h>
99
#include <unistd.h>
10-
#define FUSE_USE_VERSION 26
11-
#include <fuse.h>
12-
#include <fuse/fuse_opt.h>
13-
#include <fuse/fuse_lowlevel.h>
10+
#define FUSE_USE_VERSION 35
11+
#include <fuse3/fuse.h>
12+
#include <fuse3/fuse_opt.h>
13+
#include <fuse3/fuse_lowlevel.h>
1414
#include <lkl.h>
1515
#include <lkl_host.h>
1616

17-
#define LKLFUSE_VERSION "0.1"
17+
#define LKLFUSE_VERSION "0.3"
1818

1919
struct lklfuse {
2020
const char *file;
@@ -63,7 +63,7 @@ static void usage(void)
6363
"lklfuse options:\n"
6464
" -o log=FILE log file\n"
6565
" -o type=fstype filesystem type\n"
66-
" -o mb=memory in mb ammount of memory to allocate\n"
66+
" -o mb=memory amount of memory to allocate in MB (default: 64)\n"
6767
" -o part=parition partition to mount\n"
6868
" -o ro open file read-only\n"
6969
" -o opts=options mount options (use \\ to escape , and =)\n"
@@ -88,7 +88,9 @@ static int lklfuse_opt_proc(void *data, const char *arg, int key,
8888

8989
case KEY_HELP:
9090
usage();
91-
fuse_opt_add_arg(args, "-ho");
91+
/* suppress fuse usage */
92+
args->argv[0] = "";
93+
fuse_opt_add_arg(args, "-h");
9294
fuse_main(args->argc, args->argv, NULL, NULL);
9395
exit(1);
9496

@@ -124,31 +126,24 @@ static void lklfuse_xlat_stat(const struct lkl_stat *in, struct stat *st)
124126
st->st_ctim.tv_nsec = in->st_ctime_nsec;
125127
}
126128

127-
static int lklfuse_fgetattr(const char *path, struct stat *st,
128-
struct fuse_file_info *fi)
129+
static int lklfuse_getattr(const char *path, struct stat *st,
130+
struct fuse_file_info *fi)
129131
{
130132
long ret;
131133
struct lkl_stat lkl_stat;
132134

133-
ret = lkl_sys_fstat(fi->fh, &lkl_stat);
134-
if (ret)
135-
return ret;
136-
137-
lklfuse_xlat_stat(&lkl_stat, st);
138-
return 0;
139-
}
140-
141-
static int lklfuse_getattr(const char *path, struct stat *st)
142-
{
143-
long ret;
144-
struct lkl_stat lkl_stat;
145-
146-
ret = lkl_sys_lstat(path, &lkl_stat);
147-
if (ret)
148-
return ret;
135+
/*
136+
* With nullpath_ok, path will be provided only if the struct
137+
* fuse_file_info argument is NULL.
138+
*/
139+
if (fi)
140+
ret = lkl_sys_fstat(fi->fh, &lkl_stat);
141+
else
142+
ret = lkl_sys_lstat(path, &lkl_stat);
143+
if (!ret)
144+
lklfuse_xlat_stat(&lkl_stat, st);
149145

150-
lklfuse_xlat_stat(&lkl_stat, st);
151-
return 0;
146+
return ret;
152147
}
153148

154149
static int lklfuse_readlink(const char *path, char *buf, size_t len)
@@ -193,31 +188,56 @@ static int lklfuse_symlink(const char *oldname, const char *newname)
193188
}
194189

195190

196-
static int lklfuse_rename(const char *oldname, const char *newname)
191+
static int lklfuse_rename(const char *oldname, const char *newname,
192+
unsigned int flags)
197193
{
198-
return lkl_sys_rename(oldname, newname);
194+
/* libfuse: *flags* may be `RENAME_EXCHANGE` or `RENAME_NOREPLACE` */
195+
return lkl_sys_renameat2(LKL_AT_FDCWD, oldname, LKL_AT_FDCWD, newname,
196+
flags);
199197
}
200198

201199
static int lklfuse_link(const char *oldname, const char *newname)
202200
{
203201
return lkl_sys_link(oldname, newname);
204202
}
205203

206-
static int lklfuse_chmod(const char *path, mode_t mode)
204+
static int lklfuse_chmod(const char *path, mode_t mode,
205+
struct fuse_file_info *fi)
207206
{
208-
return lkl_sys_chmod(path, mode);
209-
}
207+
int ret;
210208

209+
if (fi)
210+
ret = lkl_sys_fchmod(fi->fh, mode);
211+
else
212+
ret = lkl_sys_fchmodat(LKL_AT_FDCWD, path, mode);
211213

212-
static int lklfuse_chown(const char *path, uid_t uid, gid_t gid)
214+
return ret;
215+
}
216+
217+
static int lklfuse_chown(const char *path, uid_t uid, gid_t gid,
218+
struct fuse_file_info *fi)
213219
{
214-
return lkl_sys_fchownat(LKL_AT_FDCWD, path, uid, gid,
220+
int ret;
221+
222+
if (fi)
223+
ret = lkl_sys_fchown(fi->fh, uid, gid);
224+
else
225+
ret = lkl_sys_fchownat(LKL_AT_FDCWD, path, uid, gid,
215226
LKL_AT_SYMLINK_NOFOLLOW);
227+
return ret;
216228
}
217229

218-
static int lklfuse_truncate(const char *path, off_t off)
230+
static int lklfuse_truncate(const char *path, off_t off,
231+
struct fuse_file_info *fi)
219232
{
220-
return lkl_sys_truncate(path, off);
233+
int ret;
234+
235+
if (fi)
236+
ret = lkl_sys_ftruncate(fi->fh, off);
237+
else
238+
ret = lkl_sys_truncate(path, off);
239+
240+
return ret;
221241
}
222242

223243
static int lklfuse_open3(const char *path, bool create, mode_t mode,
@@ -397,7 +417,8 @@ static int lklfuse_opendir(const char *path, struct fuse_file_info *fi)
397417
* Introduced in version 2.3
398418
*/
399419
static int lklfuse_readdir(const char *path, void *buf, fuse_fill_dir_t fill,
400-
off_t off, struct fuse_file_info *fi)
420+
off_t off, struct fuse_file_info *fi,
421+
enum fuse_readdir_flags flags)
401422
{
402423
struct lkl_dir *dir = (struct lkl_dir *)(uintptr_t)fi->fh;
403424
struct lkl_linux_dirent64 *de;
@@ -408,7 +429,7 @@ static int lklfuse_readdir(const char *path, void *buf, fuse_fill_dir_t fill,
408429
st.st_ino = de->d_ino;
409430
st.st_mode = de->d_type << 12;
410431

411-
if (fill(buf, de->d_name, &st, 0))
432+
if (fill(buf, de->d_name, &st, 0, 0))
412433
break;
413434
}
414435

@@ -442,17 +463,24 @@ static int lklfuse_access(const char *path, int mode)
442463
return lkl_sys_access(path, mode);
443464
}
444465

445-
static int lklfuse_utimens(const char *path, const struct timespec tv[2])
466+
static int lklfuse_utimens(const char *path, const struct timespec tv[2],
467+
struct fuse_file_info *fi)
446468
{
447-
struct lkl_timespec ts[2];
448-
449-
ts[0].tv_sec = tv[0].tv_sec;
450-
ts[0].tv_nsec = tv[0].tv_nsec;
451-
ts[1].tv_sec = tv[0].tv_sec;
452-
ts[1].tv_nsec = tv[0].tv_nsec;
453-
454-
return lkl_sys_utimensat(-1, path, (struct __lkl__kernel_timespec *)ts,
455-
LKL_AT_SYMLINK_NOFOLLOW);
469+
int ret;
470+
struct lkl_timespec ts[2] = {
471+
{ .tv_sec = tv[0].tv_sec, .tv_nsec = tv[0].tv_nsec },
472+
{ .tv_sec = tv[1].tv_sec, .tv_nsec = tv[1].tv_nsec },
473+
};
474+
475+
if (fi)
476+
ret = lkl_sys_utimensat(fi->fh, NULL,
477+
(struct __lkl__kernel_timespec *)ts,
478+
0);
479+
else
480+
ret = lkl_sys_utimensat(-1, path,
481+
(struct __lkl__kernel_timespec *)ts,
482+
LKL_AT_SYMLINK_NOFOLLOW);
483+
return ret;
456484
}
457485

458486
static int lklfuse_fallocate(const char *path, int mode, off_t offset,
@@ -461,10 +489,14 @@ static int lklfuse_fallocate(const char *path, int mode, off_t offset,
461489
return lkl_sys_fallocate(fi->fh, mode, offset, len);
462490
}
463491

492+
static void *lklfuse_init(struct fuse_conn_info *conn, struct fuse_config *cfg)
493+
{
494+
cfg->nullpath_ok = 1;
495+
return NULL;
496+
}
497+
464498
const struct fuse_operations lklfuse_ops = {
465-
.flag_nullpath_ok = 1,
466-
.flag_nopath = 1,
467-
.flag_utime_omit_ok = 1,
499+
.init = lklfuse_init,
468500

469501
.getattr = lklfuse_getattr,
470502
.readlink = lklfuse_readlink,
@@ -495,7 +527,6 @@ const struct fuse_operations lklfuse_ops = {
495527
.fsyncdir = lklfuse_fsyncdir,
496528
.access = lklfuse_access,
497529
.create = lklfuse_create,
498-
.fgetattr = lklfuse_fgetattr,
499530
/* .lock, */
500531
.utimens = lklfuse_utimens,
501532
/* .bmap, */
@@ -511,13 +542,30 @@ static int start_lkl(void)
511542
{
512543
long ret;
513544
char mpoint[32];
545+
struct timespec walltime;
546+
struct lkl_timespec ts;
514547

515548
ret = lkl_start_kernel("mem=%dM", lklfuse.mb);
516549
if (ret) {
517550
fprintf(stderr, "can't start kernel: %s\n", lkl_strerror(ret));
518551
goto out;
519552
}
520553

554+
/* forward host walltime to lkl */
555+
ret = clock_gettime(CLOCK_REALTIME, &walltime);
556+
if (ret < 0)
557+
goto out_halt;
558+
559+
ts = (struct lkl_timespec){ .tv_sec = walltime.tv_sec,
560+
.tv_nsec = walltime.tv_nsec };
561+
ret = lkl_sys_clock_settime(LKL_CLOCK_REALTIME,
562+
(struct __lkl__kernel_timespec *)&ts);
563+
if (ret < 0) {
564+
fprintf(stderr, "lkl_sys_clock_settime() failed: %s\n",
565+
lkl_strerror(ret));
566+
goto out_halt;
567+
}
568+
521569
ret = lkl_mount_dev(lklfuse.disk_id, lklfuse.part, lklfuse.type,
522570
lklfuse.ro ? LKL_MS_RDONLY : 0, lklfuse.opts,
523571
mpoint, sizeof(mpoint));
@@ -563,11 +611,10 @@ static void stop_lkl(void)
563611
int main(int argc, char **argv)
564612
{
565613
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
566-
struct fuse_chan *ch;
614+
struct fuse_cmdline_opts cli_opts;
567615
struct fuse *fuse;
568616
struct stat st;
569-
char *mnt;
570-
int fg, mt, ret;
617+
int ret;
571618

572619
if (fuse_opt_parse(&args, &lklfuse, lklfuse_opts, lklfuse_opt_proc))
573620
return 1;
@@ -577,12 +624,12 @@ int main(int argc, char **argv)
577624
return 1;
578625
}
579626

580-
if (fuse_parse_cmdline(&args, &mnt, &mt, &fg))
627+
if (fuse_parse_cmdline(&args, &cli_opts))
581628
return 1;
582629

583-
ret = stat(mnt, &st);
630+
ret = stat(cli_opts.mountpoint, &st);
584631
if (ret) {
585-
perror(mnt);
632+
perror(cli_opts.mountpoint);
586633
goto out_free;
587634
}
588635

@@ -608,49 +655,47 @@ int main(int argc, char **argv)
608655

609656
lklfuse.disk_id = ret;
610657

611-
ch = fuse_mount(mnt, &args);
612-
if (!ch) {
658+
fuse = fuse_new(&args, &lklfuse_ops, sizeof(lklfuse_ops), NULL);
659+
if (!fuse) {
613660
ret = -1;
614661
goto out_close_disk;
615662
}
616663

617-
fuse = fuse_new(ch, &args, &lklfuse_ops, sizeof(lklfuse_ops), NULL);
618-
if (!fuse) {
619-
ret = -1;
620-
goto out_fuse_unmount;
621-
}
664+
ret = fuse_set_signal_handlers(fuse_get_session(fuse));
665+
if (ret < 0)
666+
goto out_fuse_destroy;
667+
668+
ret = fuse_mount(fuse, cli_opts.mountpoint);
669+
if (ret < 0)
670+
goto out_remove_signals;
622671

623672
fuse_opt_free_args(&args);
624673

625-
if (fuse_daemonize(fg) ||
626-
fuse_set_signal_handlers(fuse_get_session(fuse))) {
627-
ret = -1;
628-
goto out_fuse_destroy;
629-
}
674+
ret = fuse_daemonize(cli_opts.foreground);
675+
if (ret < 0)
676+
goto out_fuse_unmount;
630677

631678
ret = start_lkl();
632679
if (ret) {
633680
ret = -1;
634-
goto out_remove_signals;
681+
goto out_fuse_unmount;
635682
}
636683

637-
if (mt)
684+
if (!cli_opts.singlethread)
638685
fprintf(stderr, "warning: multithreaded mode not supported\n");
639686

640687
ret = fuse_loop(fuse);
641688

642689
stop_lkl();
643690

691+
out_fuse_unmount:
692+
fuse_unmount(fuse);
693+
644694
out_remove_signals:
645695
fuse_remove_signal_handlers(fuse_get_session(fuse));
646696

647-
out_fuse_unmount:
648-
if (ch)
649-
fuse_unmount(mnt, ch);
650-
651697
out_fuse_destroy:
652-
if (fuse)
653-
fuse_destroy(fuse);
698+
fuse_destroy(fuse);
654699

655700
out_lkl_cleanup:
656701
lkl_cleanup();
@@ -659,7 +704,7 @@ int main(int argc, char **argv)
659704
close(lklfuse.disk.fd);
660705

661706
out_free:
662-
free(mnt);
707+
free(cli_opts.mountpoint);
663708

664709
return ret < 0 ? 1 : 0;
665710
}

0 commit comments

Comments
 (0)