mirror of
https://git.sr.ht/~cismonx/bookmarkfs
synced 2025-07-26 02:58:52 +00:00
Compare commits
4 commits
6f2a00dd6f
...
f1451d206e
Author | SHA1 | Date | |
---|---|---|---|
|
f1451d206e | ||
|
303c934894 | ||
|
14b5a79147 | ||
|
1e5149cdc0 |
18 changed files with 81 additions and 108 deletions
|
@ -8,7 +8,7 @@ dnl This file is offered as-is, without any warranty.
|
|||
dnl
|
||||
|
||||
AC_PREREQ([2.70])
|
||||
AC_INIT([bookmarkfs], [0.1.1], [bug-bookmarkfs@nongnu.org])
|
||||
AC_INIT([bookmarkfs], [0.1.2], [bug-bookmarkfs@nongnu.org])
|
||||
AC_CONFIG_SRCDIR([bookmarkfs_util.pc.in])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
@end macro
|
||||
|
||||
@macro tcldoc {name, path}
|
||||
@uref{https://www.tcl.tk/man/tcl8.6.13/\path\, \name\}
|
||||
@uref{https://www.tcl.tk/man/tcl8.6.16/\path\, \name\}
|
||||
@end macro
|
||||
|
||||
@copying
|
||||
|
@ -106,22 +106,22 @@ for CI build logs.
|
|||
|
||||
Currently, BookmarkFS only runs on GNU/Linux and FreeBSD.
|
||||
|
||||
Although BookmarkFS sticks hard to POSIX and avoids using platform-specific
|
||||
Although BookmarkFS sticks hard to POSIX and avoids platform-specific
|
||||
features, porting it to other operating systems is not trivial.
|
||||
|
||||
The major pitfall is the @linuxdoc{FUSE, filesystems/fuse.html} dependency.
|
||||
Generally speaking, FUSE is Linux-only.
|
||||
FreeBSD partially implements the FUSE protocol in its kernel,
|
||||
to the extent that BookmarkFS is mostly usable.
|
||||
However, that's not the case for other operating systems.
|
||||
FUSE was originally Linux-only.
|
||||
Recent versions of the FreeBSD kernel partially implements the FUSE protocol,
|
||||
however, that's not the case for other operating systems.
|
||||
|
||||
For example, OpenBSD implements its own FUSE protocol,
|
||||
which is incompatible with the Linux one.
|
||||
OpenBSD does provide a libfuse-compatible library, however,
|
||||
it only covers the high-level API, while BookmarkFS uses the
|
||||
@uref{https://libfuse.github.io/doxygen/fuse__lowlevel_8h.html, low-level API}.
|
||||
|
||||
For a similar reason, @uref{https://github.com/winfsp/winfsp, WinFsp}
|
||||
won't work if you're trying to port BookmarkFS to Microsoft Windows.
|
||||
won't help much if you're trying to port BookmarkFS to Microsoft Windows.
|
||||
|
||||
Other notable portability issues:
|
||||
|
||||
|
@ -129,13 +129,10 @@ Other notable portability issues:
|
|||
@item Sandboxing
|
||||
Not all operating system kernels provide sandboxing mechanisms similar to
|
||||
Linux and FreeBSD.
|
||||
@xref{Sandboxing}.
|
||||
|
||||
If not supported, operations that require sandboxing should fail.
|
||||
Users should not be provided with a false sense of security.
|
||||
If they wish, they could pass a @option{-o no_sandbox} option to
|
||||
explicitly disable sandboxing.
|
||||
|
||||
Also @pxref{Sandboxing}.
|
||||
If unsupported, operations that require sandboxing should fail,
|
||||
unless sandboxing is explicitly disabled by the caller.
|
||||
@end table
|
||||
|
||||
|
||||
|
@ -255,32 +252,32 @@ access the files.
|
|||
@item -o ctime
|
||||
Maintain last status change time instead of last modification time.
|
||||
|
||||
Usually, a bookmark's ``modification time'' attribute behaves differently
|
||||
from both mtime and ctime.
|
||||
From a browser's perspective, the ``modification time'' attribute
|
||||
of a bookmark behaves differently from both mtime and ctime.
|
||||
In Chromium, for instance, when a bookmark is renamed, neither itself
|
||||
nor the parent directory changes timestamp accordingly.
|
||||
|
||||
BookmarkFS do not follow browser behavior here, and instead try to stay
|
||||
compatible with POSIX.
|
||||
In BookmarkFS, mtime behavior mostly stays compatible with POSIX,
|
||||
with a few caveats.
|
||||
Since a bookmark has only one ``modification time'' attribute instead of two,
|
||||
the user has to choose which one to maintain:
|
||||
|
||||
@table @asis
|
||||
@item Last modification time
|
||||
ctime only updates when mtime does.
|
||||
@item Last modification time (default)
|
||||
mtime updates normally; ctime value always follow mtime.
|
||||
|
||||
The kernel may automatically update and cache ctime,
|
||||
making it appear more ``correct'' than what we expect.
|
||||
However, this behavior should not be relied upon.
|
||||
|
||||
@item Last status change time
|
||||
ctime updates normally; mtime always updates when ctime does,
|
||||
ctime updates normally; mtime value always follow ctime,
|
||||
even if the file content is not modified.
|
||||
|
||||
This behavior may be inefficient, but makes applications that depend on ctime
|
||||
less fragile.
|
||||
@end table
|
||||
|
||||
The kernel may automatically update and cache ctime,
|
||||
making it more ``correct'' than what we expect.
|
||||
However, this behavior should not be relied upon.
|
||||
|
||||
@item -o eol
|
||||
Add a newline (ASCII LF character) to the end of each file.
|
||||
|
||||
|
@ -302,8 +299,8 @@ Do not use Landlock for sandboxing.
|
|||
This option is ignored on non-Linux platforms.
|
||||
|
||||
Without Landlock, sandboxing offers less security.
|
||||
However, Landlock is a rather new feature (requires kernel version 5.13
|
||||
or later), thus we provide an option to disable it separately.
|
||||
Nonetheless, we provide an option to disable it separately,
|
||||
since Landlock is a rather new feature (requires kernel version 5.13 or later).
|
||||
|
||||
@item -F
|
||||
Stay in the foreground, do not daemonize.
|
||||
|
@ -364,7 +361,7 @@ so that the user don't have to manually dismount the inactive filesystem.
|
|||
See @linuxmanpage{mount.fuse3, 8} for details.
|
||||
|
||||
This option is helpful when sandboxing is enabled, especially when
|
||||
the @option{-F} option is given, since a sandboxed process itself can neither
|
||||
given the @option{-F} option, since a sandboxed process itself can neither
|
||||
@linuxmanpage{umount, 2} nor fork-exec.
|
||||
|
||||
Currently, this option is not available on FreeBSD.
|
||||
|
@ -822,8 +819,8 @@ However, consecutive lookups and @code{readdir()}s should produce consistent
|
|||
results for that file, provided that it is not renamed or deleted.
|
||||
|
||||
Tag files behave differently from traditional hard links.
|
||||
If the original bookmark file is renamed or deleted,
|
||||
it may also change accordingly.
|
||||
If the associated bookmark file of a tag is renamed or deleted,
|
||||
it may change accordingly.
|
||||
It may even link to another file that was previously shadowed.
|
||||
Applications should tread lightly if they wish to cache tag directory entries.
|
||||
|
||||
|
@ -887,14 +884,13 @@ for web browser bookmarks.
|
|||
An unexpected internal error occurred, likely due to a bug in BookmarkFS,
|
||||
or a corruption in the bookmark storage.
|
||||
|
||||
When this error occurs, a log message describing the situation may be printed
|
||||
to the standard error of the filesystem daemon.
|
||||
Sometimes this error comes from the kernel-side FUSE implementation,
|
||||
and there's no error message.
|
||||
|
||||
Once this error occurs, behavior of any further operations on the filesystem
|
||||
is undefined.
|
||||
|
||||
A log message describing the situation may be printed to the standard error
|
||||
of the filesystem daemon.
|
||||
Sometimes the error comes from the kernel, and there's no error message.
|
||||
|
||||
@item ESTALE
|
||||
The file associated with the file descriptor no longer exists.
|
||||
|
||||
|
@ -1373,6 +1369,9 @@ Notable limitations:
|
|||
of a bookmark may affect that of other bookmarks,
|
||||
due to the way bookmarks are associated with the URLs.
|
||||
|
||||
@item For a similar reason, directory atime is not supported, since the atime
|
||||
attribute only exists on URLs, and directories are not associated with URLs.
|
||||
|
||||
@item The bookmark storage (SQLite database file) should be writable even if
|
||||
the BookmarkFS filesystem is mounted read-only, due to the limitations
|
||||
of WAL-mode.
|
||||
|
@ -1498,7 +1497,7 @@ Notable limitations:
|
|||
@itemize @bullet{}
|
||||
@item Does not scale well with large bookmark storage,
|
||||
since everything is kept in memory, and the entire JSON file has to be parsed
|
||||
whenever a reload is required.
|
||||
(with a parser known not to be fast) whenever a reload is required.
|
||||
|
||||
@item No support for tags (@pxref{Tags}) and keywords (@pxref{Keywords}),
|
||||
since Chromium does not have such concepts.
|
||||
|
@ -1729,7 +1728,7 @@ as well as a list of backend-specific options.
|
|||
Indicates that the function should print a version message.
|
||||
Mutually exclusive with @code{BOOKMARKFS_BACKEND_INFO_HELP}.
|
||||
|
||||
In addition to the version number, the version message may also contain
|
||||
In addition to the version number, the version message may contain
|
||||
dependency versions, compile-time options, and other information
|
||||
that can be used to determine a specific version of the backend.
|
||||
|
||||
|
@ -1970,7 +1969,7 @@ The pointer referring to the backend context.
|
|||
@subsection Enter Sandbox
|
||||
|
||||
The @code{backend_sandbox} function is called to instruct the backend to
|
||||
enter a sandboxed state where it has limited access to system resources,
|
||||
enter a sandboxed state, where it has limited access to system resources,
|
||||
thereby improving security.
|
||||
@xref{Sandboxing}.
|
||||
|
||||
|
@ -1979,10 +1978,10 @@ is @emph{not} set for this context.
|
|||
|
||||
Considering how sandboxing is usually implemented,
|
||||
it may be complicated or even impractical for multiple backend contexts
|
||||
to enter sandbox separately without affecting other ones.
|
||||
to enter sandbox separately without affecting one another.
|
||||
Thus it is guaranteed that, when launched from a frontend program like
|
||||
@command{mount.bookmarkfs}, only one backend context will be created
|
||||
throughout the lifetime of the process if sandboxing is ever needed.
|
||||
@command{mount.bookmarkfs} which requires sandboxing, only one
|
||||
backend context will be created throughout the lifetime of the process.
|
||||
|
||||
Type of the @code{backend_sandbox} function is defined as:
|
||||
|
||||
|
@ -4321,8 +4320,7 @@ it is incompatible with our sandboxing design.
|
|||
Implemented with the @code{EVFILT_VNODE} filter of @freebsdmanpage{kevent, 2}.
|
||||
|
||||
@item Fallback
|
||||
When no platform-specific filesystem watching mechanism is available,
|
||||
periodically checks the @code{st_ino} and @code{st_mtim} attributes
|
||||
Periodically checks the @code{st_ino} and @code{st_mtim} attributes
|
||||
of the watched file with @posixfuncmanpage{fstatat}.
|
||||
|
||||
This approach is less efficient than ``native'' implementations,
|
||||
|
|
|
@ -28,7 +28,7 @@ UTIL_LIBS_ =
|
|||
if BOOKMARKFS_UTIL
|
||||
UTIL_LIBS_ += libbookmarkfs_util.la
|
||||
else
|
||||
UTIL_LIBS_ += $(BOOKMARKFS_LIBS)
|
||||
UTIL_LIBS_ += $(BOOKMARKFS_UTIL_LIBS)
|
||||
endif # BOOKMARKFS_UTIL
|
||||
|
||||
BACKEND_SOURCES_ = backend_util.c lib.c xstd.c
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#define BOOKMARKFS_VER_MAJOR 0
|
||||
#define BOOKMARKFS_VER_MINOR 1
|
||||
#define BOOKMARKFS_VER_PATCH 1
|
||||
#define BOOKMARKFS_VER_PATCH 2
|
||||
|
||||
#define bookmarkfs_make_vernum(major, minor, patch) \
|
||||
( ((major) << 16) | ((minor) << 8) | ((patch) << 0) )
|
||||
|
|
|
@ -31,13 +31,13 @@ if BOOKMARKFS_MOUNT
|
|||
|
||||
check_fs_CPPFLAGS = -I$(top_srcdir)/src
|
||||
check_fs_LDADD =
|
||||
check_fs_SOURCES = check_fs.c
|
||||
check_fs_SOURCES = check_fs.c check_fs_dents.c check_fs_regrw.c \
|
||||
check_fs_times.c check_util.c
|
||||
|
||||
if BOOKMARKFS_UTIL
|
||||
check_fs_CPPFLAGS += -DHAVE_BOOKMARKFS_UTIL
|
||||
check_fs_LDADD += $(top_builddir)/src/libbookmarkfs_util.la
|
||||
check_fs_SOURCES += check_fs_regrw.c check_fs_dents.c check_util.c \
|
||||
check_fs_times.c
|
||||
check_fs_LDADD += $(top_builddir)/src/libbookmarkfs_util.la
|
||||
else
|
||||
check_fs_LDADD += $(BOOKMARKFS_UTIL_LIBS)
|
||||
endif # BOOKMARKFS_UTIL
|
||||
endif # BOOKMARKFS_MOUNT
|
||||
|
||||
|
|
|
@ -54,12 +54,10 @@ dispatch_subcmds (
|
|||
status = subcmd_ismount(argc, argv);
|
||||
} else if (0 == strcmp("sleep", cmd)) {
|
||||
status = subcmd_sleep(argc, argv);
|
||||
#ifdef HAVE_BOOKMARKFS_UTIL
|
||||
} else if (0 == strcmp("regrw", cmd)) {
|
||||
status = check_fs_regrw(argc, argv);
|
||||
} else if (0 == strcmp("dents", cmd)) {
|
||||
status = check_fs_dents(argc, argv);
|
||||
#endif
|
||||
} else if (0 == strcmp("times", cmd)) {
|
||||
status = check_fs_times(argc, argv);
|
||||
} else {
|
||||
|
|
|
@ -241,7 +241,7 @@ check_fs_dents (
|
|||
int argc,
|
||||
char *argv[]
|
||||
) {
|
||||
uint64_t seed_buf[4], *seed = NULL;
|
||||
char const *seed = NULL;
|
||||
int n = -1;
|
||||
|
||||
OPT_START(argc, argv, "n:s:")
|
||||
|
@ -250,10 +250,7 @@ check_fs_dents (
|
|||
break;
|
||||
}
|
||||
OPT_OPT('s') {
|
||||
if (0 != prng_seed_from_hex(seed_buf, optarg)) {
|
||||
return -1;
|
||||
}
|
||||
seed = seed_buf;
|
||||
seed = optarg;
|
||||
break;
|
||||
}
|
||||
OPT_END
|
||||
|
@ -268,7 +265,7 @@ check_fs_dents (
|
|||
}
|
||||
char const *path = argv[0];
|
||||
|
||||
if (0 != prng_seed(seed)) {
|
||||
if (0 != prng_seed_from_hex(seed)) {
|
||||
return -1;
|
||||
}
|
||||
int dirfd = open(path, O_RDONLY | O_DIRECTORY);
|
||||
|
|
|
@ -167,7 +167,7 @@ check_fs_regrw (
|
|||
int argc,
|
||||
char *argv[]
|
||||
) {
|
||||
uint64_t seed_buf[4], *seed = NULL;
|
||||
char const *seed = NULL;
|
||||
int file_max = -1;
|
||||
|
||||
OPT_START(argc, argv, "n:s:")
|
||||
|
@ -176,10 +176,7 @@ check_fs_regrw (
|
|||
break;
|
||||
}
|
||||
OPT_OPT('s') {
|
||||
if (0 != prng_seed_from_hex(seed_buf, optarg)) {
|
||||
return -1;
|
||||
}
|
||||
seed = seed_buf;
|
||||
seed = optarg;
|
||||
break;
|
||||
}
|
||||
OPT_END
|
||||
|
@ -194,7 +191,7 @@ check_fs_regrw (
|
|||
}
|
||||
char const *path = argv[0];
|
||||
|
||||
if (0 != prng_seed(seed)) {
|
||||
if (0 != prng_seed_from_hex(seed)) {
|
||||
return -1;
|
||||
}
|
||||
return do_check_fs_regrw(path, file_max);
|
||||
|
|
|
@ -153,7 +153,7 @@ check_fs_times (
|
|||
int argc,
|
||||
char *argv[]
|
||||
) {
|
||||
uint64_t seed_buf[4], *seed = NULL;
|
||||
char const *seed = NULL;
|
||||
int rounds = -1;
|
||||
|
||||
OPT_START(argc, argv, "r:s:")
|
||||
|
@ -162,10 +162,7 @@ check_fs_times (
|
|||
break;
|
||||
}
|
||||
OPT_OPT('s') {
|
||||
if (0 != prng_seed_from_hex(seed_buf, optarg)) {
|
||||
return -1;
|
||||
}
|
||||
seed = seed_buf;
|
||||
seed = optarg;
|
||||
break;
|
||||
}
|
||||
OPT_END
|
||||
|
@ -180,7 +177,7 @@ check_fs_times (
|
|||
}
|
||||
char const *path = argv[0];
|
||||
|
||||
if (0 != prng_seed(seed)) {
|
||||
if (0 != prng_seed_from_hex(seed)) {
|
||||
return -1;
|
||||
}
|
||||
int dirfd = open(path, O_RDONLY | O_DIRECTORY);
|
||||
|
|
|
@ -168,16 +168,13 @@ check_hashmap (
|
|||
int argc,
|
||||
char *argv[]
|
||||
) {
|
||||
uint64_t seed_buf[4], *seed = NULL;
|
||||
char const *seed = NULL;
|
||||
int size_exp = -1;
|
||||
int rounds = -1;
|
||||
|
||||
OPT_START(argc, argv, "s:n:r:")
|
||||
OPT_OPT('s') {
|
||||
if (0 != prng_seed_from_hex(seed_buf, optarg)) {
|
||||
return -1;
|
||||
}
|
||||
seed = seed_buf;
|
||||
seed = optarg;
|
||||
break;
|
||||
}
|
||||
OPT_OPT('n') {
|
||||
|
@ -199,7 +196,7 @@ check_hashmap (
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (0 != prng_seed(seed)) {
|
||||
if (0 != prng_seed_from_hex(seed)) {
|
||||
return -1;
|
||||
}
|
||||
return do_check_hashmap(1u << size_exp, rounds);
|
||||
|
|
|
@ -104,15 +104,12 @@ subcmd_prng (
|
|||
int argc,
|
||||
char *argv[]
|
||||
) {
|
||||
uint64_t seed_buf[4], *seed = NULL;
|
||||
char const *seed = NULL;
|
||||
int n = 0;
|
||||
|
||||
OPT_START(argc, argv, "s:n:")
|
||||
OPT_OPT('s') {
|
||||
if (0 != prng_seed_from_hex(seed_buf, optarg)) {
|
||||
return -1;
|
||||
}
|
||||
seed = seed_buf;
|
||||
seed = optarg;
|
||||
break;
|
||||
}
|
||||
OPT_OPT('n') {
|
||||
|
@ -121,7 +118,7 @@ subcmd_prng (
|
|||
}
|
||||
OPT_END
|
||||
|
||||
if (0 != prng_seed(seed)) {
|
||||
if (0 != prng_seed_from_hex(seed)) {
|
||||
return -1;
|
||||
}
|
||||
for (; n > 0; --n) {
|
||||
|
|
|
@ -27,17 +27,24 @@
|
|||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "prng.h"
|
||||
|
||||
int
|
||||
prng_seed_from_hex (
|
||||
uint64_t *buf,
|
||||
char const *str
|
||||
) {
|
||||
int cnt = sscanf(str,
|
||||
"%16" SCNx64 "%16" SCNx64 "%16" SCNx64 "%16" SCNx64,
|
||||
&buf[0], &buf[1], &buf[2], &buf[3]);
|
||||
if (cnt != 4) {
|
||||
log_printf("bad seed '%s'", str);
|
||||
return -1;
|
||||
uint64_t buf[4], *seed = NULL;
|
||||
|
||||
if (str != NULL) {
|
||||
int cnt = sscanf(str,
|
||||
"%16" SCNx64 "%16" SCNx64 "%16" SCNx64 "%16" SCNx64,
|
||||
&buf[0], &buf[1], &buf[2], &buf[3]);
|
||||
if (cnt != 4) {
|
||||
log_puts("bad prng seed");
|
||||
return -1;
|
||||
}
|
||||
seed = buf;
|
||||
log_printf("prng seed: '%s'", str);
|
||||
}
|
||||
return 0;
|
||||
return prng_seed(seed);
|
||||
}
|
||||
|
|
|
@ -73,7 +73,6 @@ check_watcher (
|
|||
|
||||
int
|
||||
prng_seed_from_hex (
|
||||
uint64_t *buf,
|
||||
char const *str
|
||||
);
|
||||
|
||||
|
|
|
@ -10,14 +10,10 @@ dnl
|
|||
AT_SETUP([fs: directory entries])
|
||||
AT_KEYWORDS([fs dents])
|
||||
|
||||
ATX_CHECK_FS_NEW_ANY(, [
|
||||
# requires PRNG
|
||||
ATX_FEAT_PREREQ([bookmarkfs-util])
|
||||
], [
|
||||
ATX_CHECK_FS_NEW_ANY(, , [
|
||||
ATX_RUN_REPEAT([8], [
|
||||
name=$(ath_fn_rand_u64_hex)
|
||||
seed=$(ath_fn_prng_seed)
|
||||
echo "prng seed: $seed"
|
||||
|
||||
mkdir $name
|
||||
ATX_RUN([
|
||||
|
|
|
@ -10,13 +10,9 @@ dnl
|
|||
AT_SETUP([fs: regular file read/write])
|
||||
AT_KEYWORDS([fs regrw])
|
||||
|
||||
ATX_CHECK_FS_NEW_ANY([file_max=524288], [
|
||||
# requires PRNG
|
||||
ATX_FEAT_PREREQ([bookmarkfs-util])
|
||||
], [
|
||||
ATX_CHECK_FS_NEW_ANY([file_max=524288], , [
|
||||
name=$(ath_fn_rand_u64_hex)
|
||||
seed=$(ath_fn_prng_seed)
|
||||
echo "prng seed: $seed"
|
||||
|
||||
ATX_RUN([
|
||||
check-fs regrw -n 524288 -s "$seed" $name
|
||||
|
|
|
@ -10,13 +10,9 @@ dnl
|
|||
AT_SETUP([fs: last access/modification times])
|
||||
AT_KEYWORDS([fs times])
|
||||
|
||||
ATX_CHECK_FS_NEW_ANY(, [
|
||||
# requires PRNG
|
||||
ATX_FEAT_PREREQ([bookmarkfs-util])
|
||||
], [
|
||||
ATX_CHECK_FS_NEW_ANY(, , [
|
||||
name=$(ath_fn_rand_u64_hex)
|
||||
seed=$(ath_fn_prng_seed)
|
||||
echo "prng seed: $seed"
|
||||
|
||||
mkdir $name
|
||||
ATX_RUN([
|
||||
|
|
|
@ -15,7 +15,6 @@ ATX_CHECK_LIB([
|
|||
if test -z "$seed"; then
|
||||
seed=$(ath_fn_prng_seed)
|
||||
fi
|
||||
echo "prng seed: $seed"
|
||||
|
||||
size="${CHECK_HASHMAP_DATA_SIZE}"
|
||||
if test -z "$size"; then
|
||||
|
|
|
@ -21,7 +21,6 @@ ATX_CHECK_LIB([
|
|||
ATX_RUN_REPEAT([16], [
|
||||
seed=$(ath_fn_prng_seed)
|
||||
count=32
|
||||
echo "prng seed: $seed"
|
||||
|
||||
num_1=$(gen_num $seed $count)
|
||||
num_2=$(gen_num $seed $count)
|
||||
|
|
Loading…
Add table
Reference in a new issue