From 317181e8ea1b3406919b946ca5524f8b9f34817d Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Wed, 4 Sep 2019 15:59:18 +0100 Subject: Introduce callback for logging Introduce an API for custom log handler functions. This allows libfuse applications to send messages to syslog(3) or other logging systems. See include/fuse_log.h for details. Convert libfuse from fprintf(stderr, ...) to log_fuse(level, ...). Most messages are error messages with FUSE_LOG_ERR log level. There are also some debug messages which now use the FUSE_LOG_DEBUG log level. Note that lib/mount_util.c is used by both libfuse and fusermount3. Since fusermount3 does not link against libfuse, we cannot call fuse_log() from lib/mount_util.c. This file will continue to use fprintf(stderr, ...) until someone figures out how to split it up. Signed-off-by: Stefan Hajnoczi --- ChangeLog.rst | 7 +++ include/fuse_common.h | 1 + include/fuse_log.h | 74 +++++++++++++++++++++++++ include/meson.build | 2 +- lib/cuse_lowlevel.c | 30 +++++----- lib/fuse.c | 149 +++++++++++++++++++++++++------------------------- lib/fuse_i.h | 2 + lib/fuse_log.c | 41 ++++++++++++++ lib/fuse_loop_mt.c | 14 ++--- lib/fuse_lowlevel.c | 94 +++++++++++++++---------------- lib/fuse_opt.c | 9 +-- lib/fuse_signals.c | 4 +- lib/helper.c | 10 ++-- lib/meson.build | 3 +- lib/modules/iconv.c | 8 +-- lib/modules/subdir.c | 8 +-- lib/mount.c | 20 +++---- lib/mount_bsd.c | 2 +- 18 files changed, 303 insertions(+), 175 deletions(-) create mode 100644 include/fuse_log.h create mode 100644 lib/fuse_log.c diff --git a/ChangeLog.rst b/ChangeLog.rst index aa7842a..d46fe29 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -1,3 +1,10 @@ +Unreleased Changes +================== + +* Added custom log message handler function support so that libfuse + applications can direct messages to syslog(3) or other logging systems. + stderr remains the default. See `fuse_log.h` for the new API. + libfuse 3.6.2 (2019-07-09) ========================== diff --git a/include/fuse_common.h b/include/fuse_common.h index 0809441..2d686b2 100644 --- a/include/fuse_common.h +++ b/include/fuse_common.h @@ -15,6 +15,7 @@ #define FUSE_COMMON_H_ #include "fuse_opt.h" +#include "fuse_log.h" #include #include diff --git a/include/fuse_log.h b/include/fuse_log.h new file mode 100644 index 0000000..df43697 --- /dev/null +++ b/include/fuse_log.h @@ -0,0 +1,74 @@ +/* + FUSE: Filesystem in Userspace + Copyright (C) 2019 Red Hat, Inc. + + This program can be distributed under the terms of the GNU LGPLv2. + See the file COPYING.LIB. +*/ + +#ifndef FUSE_LOG_H_ +#define FUSE_LOG_H_ + +/** @file + * + * This file defines the logging interface of FUSE + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Log severity level + * + * These levels correspond to syslog(2) log levels since they are widely used. + */ +enum fuse_log_level { + FUSE_LOG_EMERG, + FUSE_LOG_ALERT, + FUSE_LOG_CRIT, + FUSE_LOG_ERR, + FUSE_LOG_WARNING, + FUSE_LOG_NOTICE, + FUSE_LOG_INFO, + FUSE_LOG_DEBUG +}; + +/** + * Log message handler function. + * + * This function must be thread-safe. It may be called from any libfuse + * function, including fuse_parse_cmdline() and other functions invoked before + * a FUSE filesystem is created. + * + * Install a custom log message handler function using fuse_set_log_func(). + * + * @param level log severity level + * @param fmt sprintf-style format string including newline + * @param ap format string arguments + */ +typedef void (*fuse_log_func_t)(enum fuse_log_level level, + const char *fmt, va_list ap); + +/** + * Install a custom log handler function. + * + * Log messages are emitted by libfuse functions to report errors and debug + * information. Messages are printed to stderr by default but this can be + * overridden by installing a custom log message handler function. + * + * The log message handler function is global and affects all FUSE filesystems + * created within this process. + * + * @param func a custom log message handler function or NULL to revert to + * the default + */ +void fuse_set_log_func(fuse_log_func_t func); + +#ifdef __cplusplus +} +#endif + +#endif /* FUSE_LOG_H_ */ diff --git a/include/meson.build b/include/meson.build index 55cb6f7..bf67197 100644 --- a/include/meson.build +++ b/include/meson.build @@ -1,4 +1,4 @@ libfuse_headers = [ 'fuse.h', 'fuse_common.h', 'fuse_lowlevel.h', - 'fuse_opt.h', 'cuse_lowlevel.h' ] + 'fuse_opt.h', 'cuse_lowlevel.h', 'fuse_log.h' ] install_headers(libfuse_headers, subdir: 'fuse3') diff --git a/lib/cuse_lowlevel.c b/lib/cuse_lowlevel.c index 019b20f..9917b64 100644 --- a/lib/cuse_lowlevel.c +++ b/lib/cuse_lowlevel.c @@ -122,14 +122,14 @@ static struct cuse_data *cuse_prep_data(const struct cuse_info *ci, NULL); if (dev_info_len > CUSE_INIT_INFO_MAX) { - fprintf(stderr, "cuse: dev_info (%zu) too large, limit=%u\n", + fuse_log(FUSE_LOG_ERR, "cuse: dev_info (%zu) too large, limit=%u\n", dev_info_len, CUSE_INIT_INFO_MAX); return NULL; } cd = calloc(1, sizeof(*cd) + dev_info_len); if (!cd) { - fprintf(stderr, "cuse: failed to allocate cuse_data\n"); + fuse_log(FUSE_LOG_ERR, "cuse: failed to allocate cuse_data\n"); return NULL; } @@ -203,8 +203,8 @@ void cuse_lowlevel_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) (void) nodeid; if (se->debug) { - fprintf(stderr, "CUSE_INIT: %u.%u\n", arg->major, arg->minor); - fprintf(stderr, "flags=0x%08x\n", arg->flags); + fuse_log(FUSE_LOG_DEBUG, "CUSE_INIT: %u.%u\n", arg->major, arg->minor); + fuse_log(FUSE_LOG_DEBUG, "flags=0x%08x\n", arg->flags); } se->conn.proto_major = arg->major; se->conn.proto_minor = arg->minor; @@ -212,14 +212,14 @@ void cuse_lowlevel_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) se->conn.want = 0; if (arg->major < 7) { - fprintf(stderr, "cuse: unsupported protocol version: %u.%u\n", + fuse_log(FUSE_LOG_ERR, "cuse: unsupported protocol version: %u.%u\n", arg->major, arg->minor); fuse_reply_err(req, EPROTO); return; } if (bufsize < FUSE_MIN_READ_BUFFER) { - fprintf(stderr, "cuse: warning: buffer size too small: %zu\n", + fuse_log(FUSE_LOG_ERR, "cuse: warning: buffer size too small: %zu\n", bufsize); bufsize = FUSE_MIN_READ_BUFFER; } @@ -242,14 +242,14 @@ void cuse_lowlevel_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) outarg.dev_minor = cd->dev_minor; if (se->debug) { - fprintf(stderr, " CUSE_INIT: %u.%u\n", + fuse_log(FUSE_LOG_DEBUG, " CUSE_INIT: %u.%u\n", outarg.major, outarg.minor); - fprintf(stderr, " flags=0x%08x\n", outarg.flags); - fprintf(stderr, " max_read=0x%08x\n", outarg.max_read); - fprintf(stderr, " max_write=0x%08x\n", outarg.max_write); - fprintf(stderr, " dev_major=%u\n", outarg.dev_major); - fprintf(stderr, " dev_minor=%u\n", outarg.dev_minor); - fprintf(stderr, " dev_info: %.*s\n", cd->dev_info_len, + fuse_log(FUSE_LOG_DEBUG, " flags=0x%08x\n", outarg.flags); + fuse_log(FUSE_LOG_DEBUG, " max_read=0x%08x\n", outarg.max_read); + fuse_log(FUSE_LOG_DEBUG, " max_write=0x%08x\n", outarg.max_write); + fuse_log(FUSE_LOG_DEBUG, " dev_major=%u\n", outarg.dev_major); + fuse_log(FUSE_LOG_DEBUG, " dev_minor=%u\n", outarg.dev_minor); + fuse_log(FUSE_LOG_DEBUG, " dev_info: %.*s\n", cd->dev_info_len, cd->dev_info); } @@ -303,9 +303,9 @@ struct fuse_session *cuse_lowlevel_setup(int argc, char *argv[], fd = open(devname, O_RDWR); if (fd == -1) { if (errno == ENODEV || errno == ENOENT) - fprintf(stderr, "cuse: device not found, try 'modprobe cuse' first\n"); + fuse_log(FUSE_LOG_ERR, "cuse: device not found, try 'modprobe cuse' first\n"); else - fprintf(stderr, "cuse: failed to open %s: %s\n", + fuse_log(FUSE_LOG_ERR, "cuse: failed to open %s: %s\n", devname, strerror(errno)); goto err_se; } diff --git a/lib/fuse.c b/lib/fuse.c index 317abac..229e139 100755 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -214,12 +214,12 @@ static int fuse_register_module(const char *name, mod = calloc(1, sizeof(struct fuse_module)); if (!mod) { - fprintf(stderr, "fuse: failed to allocate module\n"); + fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate module\n"); return -1; } mod->name = strdup(name); if (!mod->name) { - fprintf(stderr, "fuse: failed to allocate module name\n"); + fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate module name\n"); free(mod); return -1; } @@ -256,19 +256,19 @@ static int fuse_load_so_module(const char *module) tmp = malloc(strlen(module) + 64); if (!tmp) { - fprintf(stderr, "fuse: memory allocation failed\n"); + fuse_log(FUSE_LOG_ERR, "fuse: memory allocation failed\n"); return -1; } sprintf(tmp, "libfusemod_%s.so", module); so = calloc(1, sizeof(struct fusemod_so)); if (!so) { - fprintf(stderr, "fuse: failed to allocate module so\n"); + fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate module so\n"); goto out; } so->handle = dlopen(tmp, RTLD_NOW); if (so->handle == NULL) { - fprintf(stderr, "fuse: dlopen(%s) failed: %s\n", + fuse_log(FUSE_LOG_ERR, "fuse: dlopen(%s) failed: %s\n", tmp, dlerror()); goto out_free_so; } @@ -276,7 +276,7 @@ static int fuse_load_so_module(const char *module) sprintf(tmp, "fuse_module_%s_factory", module); *(void**)(&factory) = dlsym(so->handle, tmp); if (factory == NULL) { - fprintf(stderr, "fuse: symbol <%s> not found in module: %s\n", + fuse_log(FUSE_LOG_ERR, "fuse: symbol <%s> not found in module: %s\n", tmp, dlerror()); goto out_dlclose; } @@ -481,7 +481,8 @@ static void free_slab(struct fuse *f, struct node_slab *slab) list_del(&slab->list); res = munmap(slab, f->pagesize); if (res == -1) - fprintf(stderr, "fuse warning: munmap(%p) failed\n", slab); + fuse_log(FUSE_LOG_WARNING, "fuse warning: munmap(%p) failed\n", + slab); } static void free_node_mem(struct fuse *f, struct node *node) @@ -540,7 +541,7 @@ static struct node *get_node(struct fuse *f, fuse_ino_t nodeid) { struct node *node = get_node_nocheck(f, nodeid); if (!node) { - fprintf(stderr, "fuse internal error: node %llu not found\n", + fuse_log(FUSE_LOG_ERR, "fuse internal error: node %llu not found\n", (unsigned long long) nodeid); abort(); } @@ -754,7 +755,7 @@ static void unhash_name(struct fuse *f, struct node *node) remerge_name(f); return; } - fprintf(stderr, + fuse_log(FUSE_LOG_ERR, "fuse internal error: unable to unhash node: %llu\n", (unsigned long long) node->nodeid); abort(); @@ -819,7 +820,7 @@ static int hash_name(struct fuse *f, struct node *node, fuse_ino_t parentid, static void delete_node(struct fuse *f, struct node *node) { if (f->conf.debug) - fprintf(stderr, "DELETE: %llu\n", + fuse_log(FUSE_LOG_DEBUG, "DELETE: %llu\n", (unsigned long long) node->nodeid); assert(node->treelock == 0); @@ -1165,10 +1166,10 @@ static void debug_path(struct fuse *f, const char *msg, fuse_ino_t nodeid, wnode = lookup_node(f, nodeid, name); if (wnode) { - fprintf(stderr, "%s %llu (w)\n", + fuse_log(FUSE_LOG_DEBUG, "%s %llu (w)\n", msg, (unsigned long long) wnode->nodeid); } else { - fprintf(stderr, "%s %llu\n", + fuse_log(FUSE_LOG_DEBUG, "%s %llu\n", msg, (unsigned long long) nodeid); } } @@ -1479,7 +1480,7 @@ static int rename_node(struct fuse *f, fuse_ino_t olddir, const char *oldname, if (newnode != NULL) { if (hide) { - fprintf(stderr, "fuse: hidden file got created during hiding\n"); + fuse_log(FUSE_LOG_ERR, "fuse: hidden file got created during hiding\n"); err = -EBUSY; goto out; } @@ -1632,7 +1633,7 @@ int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf, if (fs->op.getattr) { if (fs->debug) { char buf[10]; - fprintf(stderr, "getattr[%s] %s\n", + fuse_log(FUSE_LOG_DEBUG, "getattr[%s] %s\n", file_info_string(fi, buf, sizeof(buf)), path); } @@ -1648,7 +1649,7 @@ int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath, fuse_get_context()->private_data = fs->user_data; if (fs->op.rename) { if (fs->debug) - fprintf(stderr, "rename %s %s 0x%x\n", oldpath, newpath, + fuse_log(FUSE_LOG_DEBUG, "rename %s %s 0x%x\n", oldpath, newpath, flags); return fs->op.rename(oldpath, newpath, flags); @@ -1662,7 +1663,7 @@ int fuse_fs_unlink(struct fuse_fs *fs, const char *path) fuse_get_context()->private_data = fs->user_data; if (fs->op.unlink) { if (fs->debug) - fprintf(stderr, "unlink %s\n", path); + fuse_log(FUSE_LOG_DEBUG, "unlink %s\n", path); return fs->op.unlink(path); } else { @@ -1675,7 +1676,7 @@ int fuse_fs_rmdir(struct fuse_fs *fs, const char *path) fuse_get_context()->private_data = fs->user_data; if (fs->op.rmdir) { if (fs->debug) - fprintf(stderr, "rmdir %s\n", path); + fuse_log(FUSE_LOG_DEBUG, "rmdir %s\n", path); return fs->op.rmdir(path); } else { @@ -1688,7 +1689,7 @@ int fuse_fs_symlink(struct fuse_fs *fs, const char *linkname, const char *path) fuse_get_context()->private_data = fs->user_data; if (fs->op.symlink) { if (fs->debug) - fprintf(stderr, "symlink %s %s\n", linkname, path); + fuse_log(FUSE_LOG_DEBUG, "symlink %s %s\n", linkname, path); return fs->op.symlink(linkname, path); } else { @@ -1701,7 +1702,7 @@ int fuse_fs_link(struct fuse_fs *fs, const char *oldpath, const char *newpath) fuse_get_context()->private_data = fs->user_data; if (fs->op.link) { if (fs->debug) - fprintf(stderr, "link %s %s\n", oldpath, newpath); + fuse_log(FUSE_LOG_DEBUG, "link %s %s\n", oldpath, newpath); return fs->op.link(oldpath, newpath); } else { @@ -1715,7 +1716,7 @@ int fuse_fs_release(struct fuse_fs *fs, const char *path, fuse_get_context()->private_data = fs->user_data; if (fs->op.release) { if (fs->debug) - fprintf(stderr, "release%s[%llu] flags: 0x%x\n", + fuse_log(FUSE_LOG_DEBUG, "release%s[%llu] flags: 0x%x\n", fi->flush ? "+flush" : "", (unsigned long long) fi->fh, fi->flags); @@ -1733,13 +1734,13 @@ int fuse_fs_opendir(struct fuse_fs *fs, const char *path, int err; if (fs->debug) - fprintf(stderr, "opendir flags: 0x%x %s\n", fi->flags, + fuse_log(FUSE_LOG_DEBUG, "opendir flags: 0x%x %s\n", fi->flags, path); err = fs->op.opendir(path, fi); if (fs->debug && !err) - fprintf(stderr, " opendir[%llu] flags: 0x%x %s\n", + fuse_log(FUSE_LOG_DEBUG, " opendir[%llu] flags: 0x%x %s\n", (unsigned long long) fi->fh, fi->flags, path); return err; @@ -1756,13 +1757,13 @@ int fuse_fs_open(struct fuse_fs *fs, const char *path, int err; if (fs->debug) - fprintf(stderr, "open flags: 0x%x %s\n", fi->flags, + fuse_log(FUSE_LOG_DEBUG, "open flags: 0x%x %s\n", fi->flags, path); err = fs->op.open(path, fi); if (fs->debug && !err) - fprintf(stderr, " open[%llu] flags: 0x%x %s\n", + fuse_log(FUSE_LOG_DEBUG, " open[%llu] flags: 0x%x %s\n", (unsigned long long) fi->fh, fi->flags, path); return err; @@ -1792,7 +1793,7 @@ int fuse_fs_read_buf(struct fuse_fs *fs, const char *path, int res; if (fs->debug) - fprintf(stderr, + fuse_log(FUSE_LOG_DEBUG, "read[%llu] %zu bytes from %llu flags: 0x%x\n", (unsigned long long) fi->fh, size, (unsigned long long) off, fi->flags); @@ -1822,12 +1823,12 @@ int fuse_fs_read_buf(struct fuse_fs *fs, const char *path, } if (fs->debug && res >= 0) - fprintf(stderr, " read[%llu] %zu bytes from %llu\n", + fuse_log(FUSE_LOG_DEBUG, " read[%llu] %zu bytes from %llu\n", (unsigned long long) fi->fh, fuse_buf_size(*bufp), (unsigned long long) off); if (res >= 0 && fuse_buf_size(*bufp) > size) - fprintf(stderr, "fuse: read too many bytes\n"); + fuse_log(FUSE_LOG_ERR, "fuse: read too many bytes\n"); if (res < 0) return res; @@ -1846,7 +1847,7 @@ int fuse_fs_read(struct fuse_fs *fs, const char *path, char *mem, size_t size, int res; if (fs->debug) - fprintf(stderr, + fuse_log(FUSE_LOG_DEBUG, "read[%llu] %zu bytes from %llu flags: 0x%x\n", (unsigned long long) fi->fh, size, (unsigned long long) off, fi->flags); @@ -1867,12 +1868,12 @@ int fuse_fs_read(struct fuse_fs *fs, const char *path, char *mem, size_t size, } if (fs->debug && res >= 0) - fprintf(stderr, " read[%llu] %u bytes from %llu\n", + fuse_log(FUSE_LOG_DEBUG, " read[%llu] %u bytes from %llu\n", (unsigned long long) fi->fh, res, (unsigned long long) off); if (res >= 0 && res > (int) size) - fprintf(stderr, "fuse: read too many bytes\n"); + fuse_log(FUSE_LOG_ERR, "fuse: read too many bytes\n"); return res; } else { @@ -1891,7 +1892,7 @@ int fuse_fs_write_buf(struct fuse_fs *fs, const char *path, assert(buf->idx == 0 && buf->off == 0); if (fs->debug) - fprintf(stderr, + fuse_log(FUSE_LOG_DEBUG, "write%s[%llu] %zu bytes to %llu flags: 0x%x\n", fi->writepage ? "page" : "", (unsigned long long) fi->fh, @@ -1931,12 +1932,12 @@ out_free: } out: if (fs->debug && res >= 0) - fprintf(stderr, " write%s[%llu] %u bytes to %llu\n", + fuse_log(FUSE_LOG_DEBUG, " write%s[%llu] %u bytes to %llu\n", fi->writepage ? "page" : "", (unsigned long long) fi->fh, res, (unsigned long long) off); if (res > (int) size) - fprintf(stderr, "fuse: wrote too many bytes\n"); + fuse_log(FUSE_LOG_ERR, "fuse: wrote too many bytes\n"); return res; } else { @@ -1960,7 +1961,7 @@ int fuse_fs_fsync(struct fuse_fs *fs, const char *path, int datasync, fuse_get_context()->private_data = fs->user_data; if (fs->op.fsync) { if (fs->debug) - fprintf(stderr, "fsync[%llu] datasync: %i\n", + fuse_log(FUSE_LOG_DEBUG, "fsync[%llu] datasync: %i\n", (unsigned long long) fi->fh, datasync); return fs->op.fsync(path, datasync, fi); @@ -1975,7 +1976,7 @@ int fuse_fs_fsyncdir(struct fuse_fs *fs, const char *path, int datasync, fuse_get_context()->private_data = fs->user_data; if (fs->op.fsyncdir) { if (fs->debug) - fprintf(stderr, "fsyncdir[%llu] datasync: %i\n", + fuse_log(FUSE_LOG_DEBUG, "fsyncdir[%llu] datasync: %i\n", (unsigned long long) fi->fh, datasync); return fs->op.fsyncdir(path, datasync, fi); @@ -1990,7 +1991,7 @@ int fuse_fs_flush(struct fuse_fs *fs, const char *path, fuse_get_context()->private_data = fs->user_data; if (fs->op.flush) { if (fs->debug) - fprintf(stderr, "flush[%llu]\n", + fuse_log(FUSE_LOG_DEBUG, "flush[%llu]\n", (unsigned long long) fi->fh); return fs->op.flush(path, fi); @@ -2004,7 +2005,7 @@ int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf) fuse_get_context()->private_data = fs->user_data; if (fs->op.statfs) { if (fs->debug) - fprintf(stderr, "statfs %s\n", path); + fuse_log(FUSE_LOG_DEBUG, "statfs %s\n", path); return fs->op.statfs(path, buf); } else { @@ -2020,7 +2021,7 @@ int fuse_fs_releasedir(struct fuse_fs *fs, const char *path, fuse_get_context()->private_data = fs->user_data; if (fs->op.releasedir) { if (fs->debug) - fprintf(stderr, "releasedir[%llu] flags: 0x%x\n", + fuse_log(FUSE_LOG_DEBUG, "releasedir[%llu] flags: 0x%x\n", (unsigned long long) fi->fh, fi->flags); return fs->op.releasedir(path, fi); @@ -2037,7 +2038,7 @@ int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf, fuse_get_context()->private_data = fs->user_data; if (fs->op.readdir) { if (fs->debug) { - fprintf(stderr, "readdir%s[%llu] from %llu\n", + fuse_log(FUSE_LOG_DEBUG, "readdir%s[%llu] from %llu\n", (flags & FUSE_READDIR_PLUS) ? "plus" : "", (unsigned long long) fi->fh, (unsigned long long) off); @@ -2057,7 +2058,7 @@ int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode, int err; if (fs->debug) - fprintf(stderr, + fuse_log(FUSE_LOG_DEBUG, "create flags: 0x%x %s 0%o umask=0%03o\n", fi->flags, path, mode, fuse_get_context()->umask); @@ -2065,7 +2066,7 @@ int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode, err = fs->op.create(path, mode, fi); if (fs->debug && !err) - fprintf(stderr, " create[%llu] flags: 0x%x %s\n", + fuse_log(FUSE_LOG_DEBUG, " create[%llu] flags: 0x%x %s\n", (unsigned long long) fi->fh, fi->flags, path); return err; @@ -2080,7 +2081,7 @@ int fuse_fs_lock(struct fuse_fs *fs, const char *path, fuse_get_context()->private_data = fs->user_data; if (fs->op.lock) { if (fs->debug) - fprintf(stderr, "lock[%llu] %s %s start: %llu len: %llu pid: %llu\n", + fuse_log(FUSE_LOG_DEBUG, "lock[%llu] %s %s start: %llu len: %llu pid: %llu\n", (unsigned long long) fi->fh, (cmd == F_GETLK ? "F_GETLK" : (cmd == F_SETLK ? "F_SETLK" : @@ -2107,7 +2108,7 @@ int fuse_fs_flock(struct fuse_fs *fs, const char *path, if (fs->debug) { int xop = op & ~LOCK_NB; - fprintf(stderr, "lock[%llu] %s%s\n", + fuse_log(FUSE_LOG_DEBUG, "lock[%llu] %s%s\n", (unsigned long long) fi->fh, xop == LOCK_SH ? "LOCK_SH" : (xop == LOCK_EX ? "LOCK_EX" : @@ -2127,7 +2128,7 @@ int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid, if (fs->op.chown) { if (fs->debug) { char buf[10]; - fprintf(stderr, "chown[%s] %s %lu %lu\n", + fuse_log(FUSE_LOG_DEBUG, "chown[%s] %s %lu %lu\n", file_info_string(fi, buf, sizeof(buf)), path, (unsigned long) uid, (unsigned long) gid); } @@ -2144,7 +2145,7 @@ int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size, if (fs->op.truncate) { if (fs->debug) { char buf[10]; - fprintf(stderr, "truncate[%s] %llu\n", + fuse_log(FUSE_LOG_DEBUG, "truncate[%s] %llu\n", file_info_string(fi, buf, sizeof(buf)), (unsigned long long) size); } @@ -2161,7 +2162,7 @@ int fuse_fs_utimens(struct fuse_fs *fs, const char *path, if (fs->op.utimens) { if (fs->debug) { char buf[10]; - fprintf(stderr, "utimens[%s] %s %li.%09lu %li.%09lu\n", + fuse_log(FUSE_LOG_DEBUG, "utimens[%s] %s %li.%09lu %li.%09lu\n", file_info_string(fi, buf, sizeof(buf)), path, tv[0].tv_sec, tv[0].tv_nsec, tv[1].tv_sec, tv[1].tv_nsec); @@ -2177,7 +2178,7 @@ int fuse_fs_access(struct fuse_fs *fs, const char *path, int mask) fuse_get_context()->private_data = fs->user_data; if (fs->op.access) { if (fs->debug) - fprintf(stderr, "access %s 0%o\n", path, mask); + fuse_log(FUSE_LOG_DEBUG, "access %s 0%o\n", path, mask); return fs->op.access(path, mask); } else { @@ -2191,7 +2192,7 @@ int fuse_fs_readlink(struct fuse_fs *fs, const char *path, char *buf, fuse_get_context()->private_data = fs->user_data; if (fs->op.readlink) { if (fs->debug) - fprintf(stderr, "readlink %s %lu\n", path, + fuse_log(FUSE_LOG_DEBUG, "readlink %s %lu\n", path, (unsigned long) len); return fs->op.readlink(path, buf, len); @@ -2206,7 +2207,7 @@ int fuse_fs_mknod(struct fuse_fs *fs, const char *path, mode_t mode, fuse_get_context()->private_data = fs->user_data; if (fs->op.mknod) { if (fs->debug) - fprintf(stderr, "mknod %s 0%o 0x%llx umask=0%03o\n", + fuse_log(FUSE_LOG_DEBUG, "mknod %s 0%o 0x%llx umask=0%03o\n", path, mode, (unsigned long long) rdev, fuse_get_context()->umask); @@ -2221,7 +2222,7 @@ int fuse_fs_mkdir(struct fuse_fs *fs, const char *path, mode_t mode) fuse_get_context()->private_data = fs->user_data; if (fs->op.mkdir) { if (fs->debug) - fprintf(stderr, "mkdir %s 0%o umask=0%03o\n", + fuse_log(FUSE_LOG_DEBUG, "mkdir %s 0%o umask=0%03o\n", path, mode, fuse_get_context()->umask); return fs->op.mkdir(path, mode); @@ -2236,7 +2237,7 @@ int fuse_fs_setxattr(struct fuse_fs *fs, const char *path, const char *name, fuse_get_context()->private_data = fs->user_data; if (fs->op.setxattr) { if (fs->debug) - fprintf(stderr, "setxattr %s %s %lu 0x%x\n", + fuse_log(FUSE_LOG_DEBUG, "setxattr %s %s %lu 0x%x\n", path, name, (unsigned long) size, flags); return fs->op.setxattr(path, name, value, size, flags); @@ -2251,7 +2252,7 @@ int fuse_fs_getxattr(struct fuse_fs *fs, const char *path, const char *name, fuse_get_context()->private_data = fs->user_data; if (fs->op.getxattr) { if (fs->debug) - fprintf(stderr, "getxattr %s %s %lu\n", + fuse_log(FUSE_LOG_DEBUG, "getxattr %s %s %lu\n", path, name, (unsigned long) size); return fs->op.getxattr(path, name, value, size); @@ -2266,7 +2267,7 @@ int fuse_fs_listxattr(struct fuse_fs *fs, const char *path, char *list, fuse_get_context()->private_data = fs->user_data; if (fs->op.listxattr) { if (fs->debug) - fprintf(stderr, "listxattr %s %lu\n", + fuse_log(FUSE_LOG_DEBUG, "listxattr %s %lu\n", path, (unsigned long) size); return fs->op.listxattr(path, list, size); @@ -2281,7 +2282,7 @@ int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize, fuse_get_context()->private_data = fs->user_data; if (fs->op.bmap) { if (fs->debug) - fprintf(stderr, "bmap %s blocksize: %lu index: %llu\n", + fuse_log(FUSE_LOG_DEBUG, "bmap %s blocksize: %lu index: %llu\n", path, (unsigned long) blocksize, (unsigned long long) *idx); @@ -2296,7 +2297,7 @@ int fuse_fs_removexattr(struct fuse_fs *fs, const char *path, const char *name) fuse_get_context()->private_data = fs->user_data; if (fs->op.removexattr) { if (fs->debug) - fprintf(stderr, "removexattr %s %s\n", path, name); + fuse_log(FUSE_LOG_DEBUG, "removexattr %s %s\n", path, name); return fs->op.removexattr(path, name); } else { @@ -2311,7 +2312,7 @@ int fuse_fs_ioctl(struct fuse_fs *fs, const char *path, unsigned int cmd, fuse_get_context()->private_data = fs->user_data; if (fs->op.ioctl) { if (fs->debug) - fprintf(stderr, "ioctl[%llu] 0x%x flags: 0x%x\n", + fuse_log(FUSE_LOG_DEBUG, "ioctl[%llu] 0x%x flags: 0x%x\n", (unsigned long long) fi->fh, cmd, flags); return fs->op.ioctl(path, cmd, arg, fi, flags, data); @@ -2328,14 +2329,14 @@ int fuse_fs_poll(struct fuse_fs *fs, const char *path, int res; if (fs->debug) - fprintf(stderr, "poll[%llu] ph: %p, events 0x%x\n", + fuse_log(FUSE_LOG_DEBUG, "poll[%llu] ph: %p, events 0x%x\n", (unsigned long long) fi->fh, ph, fi->poll_events); res = fs->op.poll(path, fi, ph, reventsp); if (fs->debug && !res) - fprintf(stderr, " poll[%llu] revents: 0x%x\n", + fuse_log(FUSE_LOG_DEBUG, " poll[%llu] revents: 0x%x\n", (unsigned long long) fi->fh, *reventsp); return res; @@ -2349,7 +2350,7 @@ int fuse_fs_fallocate(struct fuse_fs *fs, const char *path, int mode, fuse_get_context()->private_data = fs->user_data; if (fs->op.fallocate) { if (fs->debug) - fprintf(stderr, "fallocate %s mode %x, offset: %llu, length: %llu\n", + fuse_log(FUSE_LOG_DEBUG, "fallocate %s mode %x, offset: %llu, length: %llu\n", path, mode, (unsigned long long) offset, @@ -2369,7 +2370,7 @@ ssize_t fuse_fs_copy_file_range(struct fuse_fs *fs, const char *path_in, fuse_get_context()->private_data = fs->user_data; if (fs->op.copy_file_range) { if (fs->debug) - fprintf(stderr, "copy_file_range from %s:%llu to " + fuse_log(FUSE_LOG_DEBUG, "copy_file_range from %s:%llu to " "%s:%llu, length: %llu\n", path_in, (unsigned long long) off_in, @@ -2520,7 +2521,7 @@ static int lookup_path(struct fuse *f, fuse_ino_t nodeid, if (res == 0) { res = do_lookup(f, nodeid, name, e); if (res == 0 && f->conf.debug) { - fprintf(stderr, " NODEID: %llu\n", + fuse_log(FUSE_LOG_DEBUG, " NODEID: %llu\n", (unsigned long long) e->ino); } } @@ -2543,7 +2544,7 @@ static struct fuse_context_i *fuse_create_context(struct fuse *f) abort. If memory is so low that the context cannot be allocated, there's not much hope for the filesystem anyway */ - fprintf(stderr, "fuse: failed to allocate thread specific data\n"); + fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate thread specific data\n"); abort(); } pthread_setspecific(fuse_context_key, c); @@ -2567,7 +2568,7 @@ static int fuse_create_context_key(void) if (!fuse_context_ref) { err = pthread_key_create(&fuse_context_key, fuse_freecontext); if (err) { - fprintf(stderr, "fuse: failed to create thread specific key: %s\n", + fuse_log(FUSE_LOG_ERR, "fuse: failed to create thread specific key: %s\n", strerror(err)); pthread_mutex_unlock(&fuse_context_lock); return -1; @@ -2680,7 +2681,7 @@ static void fuse_lib_lookup(fuse_req_t req, fuse_ino_t parent, pthread_mutex_lock(&f->lock); if (len == 1) { if (f->conf.debug) - fprintf(stderr, "LOOKUP-DOT\n"); + fuse_log(FUSE_LOG_DEBUG, "LOOKUP-DOT\n"); dot = get_node_nocheck(f, parent); if (dot == NULL) { pthread_mutex_unlock(&f->lock); @@ -2690,7 +2691,7 @@ static void fuse_lib_lookup(fuse_req_t req, fuse_ino_t parent, dot->refctr++; } else { if (f->conf.debug) - fprintf(stderr, "LOOKUP-DOTDOT\n"); + fuse_log(FUSE_LOG_DEBUG, "LOOKUP-DOTDOT\n"); parent = get_node(f, parent)->parent->nodeid; } pthread_mutex_unlock(&f->lock); @@ -2702,7 +2703,7 @@ static void fuse_lib_lookup(fuse_req_t req, fuse_ino_t parent, if (!err) { struct fuse_intr_data d; if (f->conf.debug) - fprintf(stderr, "LOOKUP %s\n", path); + fuse_log(FUSE_LOG_DEBUG, "LOOKUP %s\n", path); fuse_prepare_interrupt(f, req, &d); err = lookup_path(f, parent, name, path, &e, NULL); if (err == -ENOENT && f->conf.negative_timeout != 0.0) { @@ -2724,7 +2725,7 @@ static void fuse_lib_lookup(fuse_req_t req, fuse_ino_t parent, static void do_forget(struct fuse *f, fuse_ino_t ino, uint64_t nlookup) { if (f->conf.debug) - fprintf(stderr, "FORGET %llu/%llu\n", (unsigned long long)ino, + fuse_log(FUSE_LOG_DEBUG, "FORGET %llu/%llu\n", (unsigned long long)ino, (unsigned long long) nlookup); forget_node(f, ino, nlookup); } @@ -2792,7 +2793,7 @@ int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode, if (fs->op.chmod) { if (fs->debug) { char buf[10]; - fprintf(stderr, "chmod[%s] %s %llo\n", + fuse_log(FUSE_LOG_DEBUG, "chmod[%s] %s %llo\n", file_info_string(fi, buf, sizeof(buf)), path, (unsigned long long) mode); } @@ -4765,13 +4766,13 @@ struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size, struct fuse_fs *fs; if (sizeof(struct fuse_operations) < op_size) { - fprintf(stderr, "fuse: warning: library too old, some operations may not not work\n"); + fuse_log(FUSE_LOG_ERR, "fuse: warning: library too old, some operations may not not work\n"); op_size = sizeof(struct fuse_operations); } fs = (struct fuse_fs *) calloc(1, sizeof(struct fuse_fs)); if (!fs) { - fprintf(stderr, "fuse: failed to allocate fuse_fs object\n"); + fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate fuse_fs object\n"); return NULL; } @@ -4786,7 +4787,7 @@ static int node_table_init(struct node_table *t) t->size = NODE_TABLE_MIN_SIZE; t->array = (struct node **) calloc(1, sizeof(struct node *) * t->size); if (t->array == NULL) { - fprintf(stderr, "fuse: memory allocation failed\n"); + fuse_log(FUSE_LOG_ERR, "fuse: memory allocation failed\n"); return -1; } t->use = 0; @@ -4838,7 +4839,7 @@ struct fuse *fuse_new_31(struct fuse_args *args, f = (struct fuse *) calloc(1, sizeof(struct fuse)); if (f == NULL) { - fprintf(stderr, "fuse: failed to allocate fuse object\n"); + fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate fuse object\n"); goto out; } @@ -4916,7 +4917,7 @@ struct fuse *fuse_new_31(struct fuse_args *args, goto out_free_fs; if (f->conf.debug) { - fprintf(stderr, "nullpath_ok: %i\n", f->conf.nullpath_ok); + fuse_log(FUSE_LOG_DEBUG, "nullpath_ok: %i\n", f->conf.nullpath_ok); } /* Trace topmost layer by default */ @@ -4933,7 +4934,7 @@ struct fuse *fuse_new_31(struct fuse_args *args, root = alloc_node(f); if (root == NULL) { - fprintf(stderr, "fuse: memory allocation failed\n"); + fuse_log(FUSE_LOG_ERR, "fuse: memory allocation failed\n"); goto out_free_id_table; } if (lru_enabled(f)) { diff --git a/lib/fuse_i.h b/lib/fuse_i.h index d38b630..4883ef6 100644 --- a/lib/fuse_i.h +++ b/lib/fuse_i.h @@ -131,6 +131,8 @@ struct fuse *fuse_new_31(struct fuse_args *args, const struct fuse_operations *o int fuse_loop_mt_32(struct fuse *f, struct fuse_loop_config *config); int fuse_session_loop_mt_32(struct fuse_session *se, struct fuse_loop_config *config); +void fuse_log(enum fuse_log_level level, const char *fmt, ...); + #define FUSE_MAX_MAX_PAGES 256 #define FUSE_DEFAULT_MAX_PAGES_PER_REQ 32 diff --git a/lib/fuse_log.c b/lib/fuse_log.c new file mode 100644 index 0000000..09178e4 --- /dev/null +++ b/lib/fuse_log.c @@ -0,0 +1,41 @@ +/* + FUSE: Filesystem in Userspace + Copyright (C) 2019 Red Hat, Inc. + + Logging API. + + This program can be distributed under the terms of the GNU LGPLv2. + See the file COPYING.LIB +*/ + +#include "fuse_log.h" +#include "fuse_i.h" + +#include +#include + +static void default_log_func( + __attribute__(( unused )) enum fuse_log_level level, + const char *fmt, va_list ap) +{ + vfprintf(stderr, fmt, ap); +} + +static fuse_log_func_t log_func = default_log_func; + +void fuse_set_log_func(fuse_log_func_t func) +{ + if (!func) + func = default_log_func; + + log_func = func; +} + +void fuse_log(enum fuse_log_level level, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + log_func(level, fmt, ap); + va_end(ap); +} diff --git a/lib/fuse_loop_mt.c b/lib/fuse_loop_mt.c index 83f1641..445e9a0 100644 --- a/lib/fuse_loop_mt.c +++ b/lib/fuse_loop_mt.c @@ -58,7 +58,7 @@ static struct fuse_chan *fuse_chan_new(int fd) { struct fuse_chan *ch = (struct fuse_chan *) malloc(sizeof(*ch)); if (ch == NULL) { - fprintf(stderr, "fuse: failed to allocate channel\n"); + fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate channel\n"); return NULL; } @@ -201,7 +201,7 @@ int fuse_start_thread(pthread_t *thread_id, void *(*func)(void *), void *arg) pthread_attr_init(&attr); stack_size = getenv(ENVNAME_THREAD_STACK); if (stack_size && pthread_attr_setstacksize(&attr, atoi(stack_size))) - fprintf(stderr, "fuse: invalid stack size: %s\n", stack_size); + fuse_log(FUSE_LOG_ERR, "fuse: invalid stack size: %s\n", stack_size); /* Disallow signal reception in worker threads */ sigemptyset(&newset); @@ -214,7 +214,7 @@ int fuse_start_thread(pthread_t *thread_id, void *(*func)(void *), void *arg) pthread_sigmask(SIG_SETMASK, &oldset, NULL); pthread_attr_destroy(&attr); if (res != 0) { - fprintf(stderr, "fuse: error creating thread: %s\n", + fuse_log(FUSE_LOG_ERR, "fuse: error creating thread: %s\n", strerror(res)); return -1; } @@ -235,7 +235,7 @@ static struct fuse_chan *fuse_clone_chan(struct fuse_mt *mt) #endif clonefd = open(devname, O_RDWR | O_CLOEXEC); if (clonefd == -1) { - fprintf(stderr, "fuse: failed to open %s: %s\n", devname, + fuse_log(FUSE_LOG_ERR, "fuse: failed to open %s: %s\n", devname, strerror(errno)); return NULL; } @@ -244,7 +244,7 @@ static struct fuse_chan *fuse_clone_chan(struct fuse_mt *mt) masterfd = mt->se->fd; res = ioctl(clonefd, FUSE_DEV_IOC_CLONE, &masterfd); if (res == -1) { - fprintf(stderr, "fuse: failed to clone device fd: %s\n", + fuse_log(FUSE_LOG_ERR, "fuse: failed to clone device fd: %s\n", strerror(errno)); close(clonefd); return NULL; @@ -262,7 +262,7 @@ static int fuse_loop_start_thread(struct fuse_mt *mt) struct fuse_worker *w = malloc(sizeof(struct fuse_worker)); if (!w) { - fprintf(stderr, "fuse: failed to allocate worker structure\n"); + fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate worker structure\n"); return -1; } memset(w, 0, sizeof(struct fuse_worker)); @@ -274,7 +274,7 @@ static int fuse_loop_start_thread(struct fuse_mt *mt) w->ch = fuse_clone_chan(mt); if(!w->ch) { /* Don't attempt this again */ - fprintf(stderr, "fuse: trying to continue " + fuse_log(FUSE_LOG_ERR, "fuse: trying to continue " "without -o clone_fd.\n"); mt->clone_fd = 0; } diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index 918893e..f7fbc8f 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -150,7 +150,7 @@ static struct fuse_req *fuse_ll_alloc_req(struct fuse_session *se) req = (struct fuse_req *) calloc(1, sizeof(struct fuse_req)); if (req == NULL) { - fprintf(stderr, "fuse: failed to allocate request\n"); + fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate request\n"); } else { req->se = se; req->ctr = 1; @@ -170,15 +170,15 @@ static int fuse_send_msg(struct fuse_session *se, struct fuse_chan *ch, out->len = iov_length(iov, count); if (se->debug) { if (out->unique == 0) { - fprintf(stderr, "NOTIFY: code=%d length=%u\n", + fuse_log(FUSE_LOG_DEBUG, "NOTIFY: code=%d length=%u\n", out->error, out->len); } else if (out->error) { - fprintf(stderr, + fuse_log(FUSE_LOG_DEBUG, " unique: %llu, error: %i (%s), outsize: %i\n", (unsigned long long) out->unique, out->error, strerror(-out->error), out->len); } else { - fprintf(stderr, + fuse_log(FUSE_LOG_DEBUG, " unique: %llu, success, outsize: %i\n", (unsigned long long) out->unique, out->len); } @@ -207,7 +207,7 @@ int fuse_send_reply_iov_nofree(fuse_req_t req, int error, struct iovec *iov, struct fuse_out_header out; if (error <= -1000 || error > 0) { - fprintf(stderr, "fuse: bad error value: %i\n", error); + fuse_log(FUSE_LOG_ERR, "fuse: bad error value: %i\n", error); error = -ERANGE; } @@ -601,11 +601,11 @@ static int read_back(int fd, char *buf, size_t len) res = read(fd, buf, len); if (res == -1) { - fprintf(stderr, "fuse: internal error: failed to read back from pipe: %s\n", strerror(errno)); + fuse_log(FUSE_LOG_ERR, "fuse: internal error: failed to read back from pipe: %s\n", strerror(errno)); return -EIO; } if (res != len) { - fprintf(stderr, "fuse: internal error: short read back from pipe: %i from %zi\n", res, len); + fuse_log(FUSE_LOG_ERR, "fuse: internal error: short read back from pipe: %i from %zi\n", res, len); return -EIO; } return 0; @@ -714,7 +714,7 @@ static int fuse_send_data_iov(struct fuse_session *se, struct fuse_chan *ch, if (res != headerlen) { res = -EIO; - fprintf(stderr, "fuse: short vmsplice to pipe: %u/%zu\n", res, + fuse_log(FUSE_LOG_ERR, "fuse: short vmsplice to pipe: %u/%zu\n", res, headerlen); goto clear_pipe; } @@ -807,7 +807,7 @@ static int fuse_send_data_iov(struct fuse_session *se, struct fuse_chan *ch, out->len = headerlen + len; if (se->debug) { - fprintf(stderr, + fuse_log(FUSE_LOG_DEBUG, " unique: %llu, success, outsize: %i (splice)\n", (unsigned long long) out->unique, out->len); } @@ -826,7 +826,7 @@ static int fuse_send_data_iov(struct fuse_session *se, struct fuse_chan *ch, } if (res != out->len) { res = -EIO; - fprintf(stderr, "fuse: short splice from pipe: %u/%u\n", + fuse_log(FUSE_LOG_ERR, "fuse: short splice from pipe: %u/%u\n", res, out->len); goto clear_pipe; } @@ -1396,7 +1396,7 @@ static void do_write_buf(fuse_req_t req, fuse_ino_t nodeid, const void *inarg, sizeof(struct fuse_write_in); } if (bufv.buf[0].size < arg->size) { - fprintf(stderr, "fuse: do_write_buf: buffer size too small\n"); + fuse_log(FUSE_LOG_ERR, "fuse: do_write_buf: buffer size too small\n"); fuse_reply_err(req, EIO); goto out; } @@ -1724,7 +1724,7 @@ static void do_interrupt(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) (void) nodeid; if (se->debug) - fprintf(stderr, "INTERRUPT: %llu\n", + fuse_log(FUSE_LOG_DEBUG, "INTERRUPT: %llu\n", (unsigned long long) arg->unique); req->u.i.unique = arg->unique; @@ -1877,10 +1877,10 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) (void) nodeid; if (se->debug) { - fprintf(stderr, "INIT: %u.%u\n", arg->major, arg->minor); + fuse_log(FUSE_LOG_DEBUG, "INIT: %u.%u\n", arg->major, arg->minor); if (arg->major == 7 && arg->minor >= 6) { - fprintf(stderr, "flags=0x%08x\n", arg->flags); - fprintf(stderr, "max_readahead=0x%08x\n", + fuse_log(FUSE_LOG_DEBUG, "flags=0x%08x\n", arg->flags); + fuse_log(FUSE_LOG_DEBUG, "max_readahead=0x%08x\n", arg->max_readahead); } } @@ -1894,7 +1894,7 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) outarg.minor = FUSE_KERNEL_MINOR_VERSION; if (arg->major < 7) { - fprintf(stderr, "fuse: unsupported protocol version: %u.%u\n", + fuse_log(FUSE_LOG_ERR, "fuse: unsupported protocol version: %u.%u\n", arg->major, arg->minor); fuse_reply_err(req, EPROTO); return; @@ -1991,7 +1991,7 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) se->conn.time_gran = 1; if (bufsize < FUSE_MIN_READ_BUFFER) { - fprintf(stderr, "fuse: warning: buffer size too small: %zu\n", + fuse_log(FUSE_LOG_ERR, "fuse: warning: buffer size too small: %zu\n", bufsize); bufsize = FUSE_MIN_READ_BUFFER; } @@ -2005,7 +2005,7 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) se->op.init(se->userdata, &se->conn); if (se->conn.want & (~se->conn.capable)) { - fprintf(stderr, "fuse: error: filesystem requested capabilities " + fuse_log(FUSE_LOG_ERR, "fuse: error: filesystem requested capabilities " "0x%x that are not supported by kernel, aborting.\n", se->conn.want & (~se->conn.capable)); fuse_reply_err(req, EPROTO); @@ -2016,7 +2016,7 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) unsigned max_read_mo = get_max_read(se->mo); if (se->conn.max_read != max_read_mo) { - fprintf(stderr, "fuse: error: init() and fuse_session_new() " + fuse_log(FUSE_LOG_ERR, "fuse: error: init() and fuse_session_new() " "requested different maximum read size (%u vs %u)\n", se->conn.max_read, max_read_mo); fuse_reply_err(req, EPROTO); @@ -2080,16 +2080,16 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) outarg.time_gran = se->conn.time_gran; if (se->debug) { - fprintf(stderr, " INIT: %u.%u\n", outarg.major, outarg.minor); - fprintf(stderr, " flags=0x%08x\n", outarg.flags); - fprintf(stderr, " max_readahead=0x%08x\n", + fuse_log(FUSE_LOG_DEBUG, " INIT: %u.%u\n", outarg.major, outarg.minor); + fuse_log(FUSE_LOG_DEBUG, " flags=0x%08x\n", outarg.flags); + fuse_log(FUSE_LOG_DEBUG, " max_readahead=0x%08x\n", outarg.max_readahead); - fprintf(stderr, " max_write=0x%08x\n", outarg.max_write); - fprintf(stderr, " max_background=%i\n", + fuse_log(FUSE_LOG_DEBUG, " max_write=0x%08x\n", outarg.max_write); + fuse_log(FUSE_LOG_DEBUG, " max_background=%i\n", outarg.max_background); - fprintf(stderr, " congestion_threshold=%i\n", + fuse_log(FUSE_LOG_DEBUG, " congestion_threshold=%i\n", outarg.congestion_threshold); - fprintf(stderr, " time_gran=%u\n", + fuse_log(FUSE_LOG_DEBUG, " time_gran=%u\n", outarg.time_gran); } if (arg->minor < 5) @@ -2326,7 +2326,7 @@ static void fuse_ll_retrieve_reply(struct fuse_notify_req *nreq, sizeof(struct fuse_notify_retrieve_in); if (bufv.buf[0].size < arg->size) { - fprintf(stderr, "fuse: retrieve reply: buffer size too small\n"); + fuse_log(FUSE_LOG_ERR, "fuse: retrieve reply: buffer size too small\n"); fuse_reply_none(req); goto out; } @@ -2489,11 +2489,11 @@ static int fuse_ll_copy_from_pipe(struct fuse_bufvec *dst, { ssize_t res = fuse_buf_copy(dst, src, 0); if (res < 0) { - fprintf(stderr, "fuse: copy from pipe: %s\n", strerror(-res)); + fuse_log(FUSE_LOG_ERR, "fuse: copy from pipe: %s\n", strerror(-res)); return res; } if ((size_t)res < fuse_buf_size(dst)) { - fprintf(stderr, "fuse: copy from pipe: short read\n"); + fuse_log(FUSE_LOG_ERR, "fuse: copy from pipe: short read\n"); return -1; } return 0; @@ -2525,7 +2525,7 @@ void fuse_session_process_buf_int(struct fuse_session *se, mbuf = malloc(tmpbuf.buf[0].size); if (mbuf == NULL) { - fprintf(stderr, "fuse: failed to allocate header\n"); + fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate header\n"); goto clear_pipe; } tmpbuf.buf[0].mem = mbuf; @@ -2540,7 +2540,7 @@ void fuse_session_process_buf_int(struct fuse_session *se, } if (se->debug) { - fprintf(stderr, + fuse_log(FUSE_LOG_DEBUG, "unique: %llu, opcode: %s (%i), nodeid: %llu, insize: %zu, pid: %u\n", (unsigned long long) in->unique, opname((enum fuse_opcode) in->opcode), in->opcode, @@ -2757,7 +2757,7 @@ int fuse_session_receive_buf_int(struct fuse_session *se, struct fuse_buf *buf, } if (res < sizeof(struct fuse_in_header)) { - fprintf(stderr, "short splice from fuse device\n"); + fuse_log(FUSE_LOG_ERR, "short splice from fuse device\n"); return -EIO; } @@ -2780,7 +2780,7 @@ int fuse_session_receive_buf_int(struct fuse_session *se, struct fuse_buf *buf, if (!buf->mem) { buf->mem = malloc(se->bufsize); if (!buf->mem) { - fprintf(stderr, + fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate read buffer\n"); return -ENOMEM; } @@ -2791,13 +2791,13 @@ int fuse_session_receive_buf_int(struct fuse_session *se, struct fuse_buf *buf, res = fuse_buf_copy(&dst, &src, 0); if (res < 0) { - fprintf(stderr, "fuse: copy from pipe: %s\n", + fuse_log(FUSE_LOG_ERR, "fuse: copy from pipe: %s\n", strerror(-res)); fuse_ll_clear_pipe(se); return res; } if (res < tmpbuf.size) { - fprintf(stderr, "fuse: copy from pipe: short read\n"); + fuse_log(FUSE_LOG_ERR, "fuse: copy from pipe: short read\n"); fuse_ll_clear_pipe(se); return -EIO; } @@ -2817,7 +2817,7 @@ fallback: if (!buf->mem) { buf->mem = malloc(se->bufsize); if (!buf->mem) { - fprintf(stderr, + fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate read buffer\n"); return -ENOMEM; } @@ -2849,7 +2849,7 @@ restart: return -err; } if ((size_t) res < sizeof(struct fuse_in_header)) { - fprintf(stderr, "short read on fuse device\n"); + fuse_log(FUSE_LOG_ERR, "short read on fuse device\n"); return -EIO; } @@ -2867,18 +2867,18 @@ struct fuse_session *fuse_session_new(struct fuse_args *args, struct mount_opts *mo; if (sizeof(struct fuse_lowlevel_ops) < op_size) { - fprintf(stderr, "fuse: warning: library too old, some operations may not work\n"); + fuse_log(FUSE_LOG_ERR, "fuse: warning: library too old, some operations may not work\n"); op_size = sizeof(struct fuse_lowlevel_ops); } if (args->argc == 0) { - fprintf(stderr, "fuse: empty argv passed to fuse_session_new().\n"); + fuse_log(FUSE_LOG_ERR, "fuse: empty argv passed to fuse_session_new().\n"); return NULL; } se = (struct fuse_session *) calloc(1, sizeof(struct fuse_session)); if (se == NULL) { - fprintf(stderr, "fuse: failed to allocate fuse object\n"); + fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate fuse object\n"); goto out1; } se->fd = -1; @@ -2904,19 +2904,19 @@ struct fuse_session *fuse_session_new(struct fuse_args *args, if(args->argc == 1 && args->argv[0][0] == '-') { - fprintf(stderr, "fuse: warning: argv[0] looks like an option, but " + fuse_log(FUSE_LOG_ERR, "fuse: warning: argv[0] looks like an option, but " "will be ignored\n"); } else if (args->argc != 1) { int i; - fprintf(stderr, "fuse: unknown option(s): `"); + fuse_log(FUSE_LOG_ERR, "fuse: unknown option(s): `"); for(i = 1; i < args->argc-1; i++) - fprintf(stderr, "%s ", args->argv[i]); - fprintf(stderr, "%s'\n", args->argv[i]); + fuse_log(FUSE_LOG_ERR, "%s ", args->argv[i]); + fuse_log(FUSE_LOG_ERR, "%s'\n", args->argv[i]); goto out4; } if (se->debug) - fprintf(stderr, "FUSE library version: %s\n", PACKAGE_VERSION); + fuse_log(FUSE_LOG_DEBUG, "FUSE library version: %s\n", PACKAGE_VERSION); se->bufsize = FUSE_MAX_MAX_PAGES * getpagesize() + FUSE_BUFFER_HEADER_SIZE; @@ -2929,7 +2929,7 @@ struct fuse_session *fuse_session_new(struct fuse_args *args, err = pthread_key_create(&se->pipe_key, fuse_ll_pipe_destructor); if (err) { - fprintf(stderr, "fuse: failed to create thread specific key: %s\n", + fuse_log(FUSE_LOG_ERR, "fuse: failed to create thread specific key: %s\n", strerror(err)); goto out5; } @@ -2976,7 +2976,7 @@ int fuse_session_mount(struct fuse_session *se, const char *mountpoint) fd = fuse_mnt_parse_fuse_fd(mountpoint); if (fd != -1) { if (fcntl(fd, F_GETFD) == -1) { - fprintf(stderr, + fuse_log(FUSE_LOG_ERR, "fuse: Invalid file descriptor /dev/fd/%u\n", fd); return -1; diff --git a/lib/fuse_opt.c b/lib/fuse_opt.c index f6cae4f..93066b9 100644 --- a/lib/fuse_opt.c +++ b/lib/fuse_opt.c @@ -10,6 +10,7 @@ */ #include "config.h" +#include "fuse_i.h" #include "fuse_opt.h" #include "fuse_misc.h" @@ -47,7 +48,7 @@ void fuse_opt_free_args(struct fuse_args *args) static int alloc_failed(void) { - fprintf(stderr, "fuse: memory allocation failed\n"); + fuse_log(FUSE_LOG_ERR, "fuse: memory allocation failed\n"); return -1; } @@ -99,7 +100,7 @@ int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg) static int next_arg(struct fuse_opt_context *ctx, const char *opt) { if (ctx->argctr + 1 >= ctx->argc) { - fprintf(stderr, "fuse: missing argument after `%s'\n", opt); + fuse_log(FUSE_LOG_ERR, "fuse: missing argument after `%s'\n", opt); return -1; } ctx->argctr++; @@ -217,7 +218,7 @@ static int process_opt_param(void *var, const char *format, const char *param, *s = copy; } else { if (sscanf(param, format, var) != 1) { - fprintf(stderr, "fuse: invalid parameter in option `%s'\n", arg); + fuse_log(FUSE_LOG_ERR, "fuse: invalid parameter in option `%s'\n", arg); return -1; } } @@ -336,7 +337,7 @@ static int process_option_group(struct fuse_opt_context *ctx, const char *opts) char *copy = strdup(opts); if (!copy) { - fprintf(stderr, "fuse: memory allocation failed\n"); + fuse_log(FUSE_LOG_ERR, "fuse: memory allocation failed\n"); return -1; } res = process_real_option_group(ctx, copy); diff --git a/lib/fuse_signals.c b/lib/fuse_signals.c index e6f7112..4271947 100644 --- a/lib/fuse_signals.c +++ b/lib/fuse_signals.c @@ -24,7 +24,7 @@ static void exit_handler(int sig) if (fuse_instance) { fuse_session_exit(fuse_instance); if(sig <= 0) { - fprintf(stderr, "assertion error: signal value <= 0\n"); + fuse_log(FUSE_LOG_ERR, "assertion error: signal value <= 0\n"); abort(); } fuse_instance->error = sig; @@ -79,7 +79,7 @@ int fuse_set_signal_handlers(struct fuse_session *se) void fuse_remove_signal_handlers(struct fuse_session *se) { if (fuse_instance != se) - fprintf(stderr, + fuse_log(FUSE_LOG_ERR, "fuse: fuse_remove_signal_handlers: unknown session\n"); else fuse_instance = NULL; diff --git a/lib/helper.c b/lib/helper.c index 5b80c6e..64ff7ad 100644 --- a/lib/helper.c +++ b/lib/helper.c @@ -154,14 +154,14 @@ static int fuse_helper_opt_proc(void *data, const char *arg, int key, char mountpoint[PATH_MAX] = ""; if (realpath(arg, mountpoint) == NULL) { - fprintf(stderr, + fuse_log(FUSE_LOG_ERR, "fuse: bad mount point `%s': %s\n", arg, strerror(errno)); return -1; } return fuse_opt_add_opt(&opts->mountpoint, mountpoint); } else { - fprintf(stderr, "fuse: invalid argument `%s'\n", arg); + fuse_log(FUSE_LOG_ERR, "fuse: invalid argument `%s'\n", arg); return -1; } @@ -186,7 +186,7 @@ static int add_default_subtype(const char *progname, struct fuse_args *args) subtype_opt = (char *) malloc(strlen(basename) + 64); if (subtype_opt == NULL) { - fprintf(stderr, "fuse: memory allocation failed\n"); + fuse_log(FUSE_LOG_ERR, "fuse: memory allocation failed\n"); return -1; } #ifdef __FreeBSD__ @@ -307,7 +307,7 @@ int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op, if (!opts.show_help && !opts.mountpoint) { - fprintf(stderr, "error: no mountpoint specified\n"); + fuse_log(FUSE_LOG_ERR, "error: no mountpoint specified\n"); res = 2; goto out1; } @@ -411,7 +411,7 @@ struct fuse_conn_info_opts* fuse_parse_conn_info_opts(struct fuse_args *args) opts = calloc(1, sizeof(struct fuse_conn_info_opts)); if(opts == NULL) { - fprintf(stderr, "calloc failed\n"); + fuse_log(FUSE_LOG_ERR, "calloc failed\n"); return NULL; } if(fuse_opt_parse(args, opts, conn_info_opt_spec, NULL) == -1) { diff --git a/lib/meson.build b/lib/meson.build index e27feab..28f0aee 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -1,7 +1,8 @@ libfuse_sources = ['fuse.c', 'fuse_i.h', 'fuse_loop.c', 'fuse_loop_mt.c', 'fuse_lowlevel.c', 'fuse_misc.h', 'fuse_opt.c', 'fuse_signals.c', 'buffer.c', 'cuse_lowlevel.c', - 'helper.c', 'modules/subdir.c', 'mount_util.c' ] + 'helper.c', 'modules/subdir.c', 'mount_util.c', + 'fuse_log.c' ] if host_machine.system().startswith('linux') libfuse_sources += [ 'mount.c' ] diff --git a/lib/modules/iconv.c b/lib/modules/iconv.c index 84f4236..431d02c 100644 --- a/lib/modules/iconv.c +++ b/lib/modules/iconv.c @@ -659,7 +659,7 @@ static struct fuse_fs *iconv_new(struct fuse_args *args, ic = calloc(1, sizeof(struct iconv)); if (ic == NULL) { - fprintf(stderr, "fuse-iconv: memory allocation failed\n"); + fuse_log(FUSE_LOG_ERR, "fuse-iconv: memory allocation failed\n"); return NULL; } @@ -667,7 +667,7 @@ static struct fuse_fs *iconv_new(struct fuse_args *args, goto out_free; if (!next[0] || next[1]) { - fprintf(stderr, "fuse-iconv: exactly one next filesystem required\n"); + fuse_log(FUSE_LOG_ERR, "fuse-iconv: exactly one next filesystem required\n"); goto out_free; } @@ -678,13 +678,13 @@ static struct fuse_fs *iconv_new(struct fuse_args *args, old = strdup(setlocale(LC_CTYPE, "")); ic->tofs = iconv_open(from, to); if (ic->tofs == (iconv_t) -1) { - fprintf(stderr, "fuse-iconv: cannot convert from %s to %s\n", + fuse_log(FUSE_LOG_ERR, "fuse-iconv: cannot convert from %s to %s\n", to, from); goto out_free; } ic->fromfs = iconv_open(to, from); if (ic->tofs == (iconv_t) -1) { - fprintf(stderr, "fuse-iconv: cannot convert from %s to %s\n", + fuse_log(FUSE_LOG_ERR, "fuse-iconv: cannot convert from %s to %s\n", from, to); goto out_iconv_close_to; } diff --git a/lib/modules/subdir.c b/lib/modules/subdir.c index f84d8c1..23f58f8 100644 --- a/lib/modules/subdir.c +++ b/lib/modules/subdir.c @@ -633,7 +633,7 @@ static struct fuse_fs *subdir_new(struct fuse_args *args, d = calloc(1, sizeof(struct subdir)); if (d == NULL) { - fprintf(stderr, "fuse-subdir: memory allocation failed\n"); + fuse_log(FUSE_LOG_ERR, "fuse-subdir: memory allocation failed\n"); return NULL; } @@ -641,19 +641,19 @@ static struct fuse_fs *subdir_new(struct fuse_args *args, goto out_free; if (!next[0] || next[1]) { - fprintf(stderr, "fuse-subdir: exactly one next filesystem required\n"); + fuse_log(FUSE_LOG_ERR, "fuse-subdir: exactly one next filesystem required\n"); goto out_free; } if (!d->base) { - fprintf(stderr, "fuse-subdir: missing 'subdir' option\n"); + fuse_log(FUSE_LOG_ERR, "fuse-subdir: missing 'subdir' option\n"); goto out_free; } if (d->base[0] && d->base[strlen(d->base)-1] != '/') { char *tmp = realloc(d->base, strlen(d->base) + 2); if (!tmp) { - fprintf(stderr, "fuse-subdir: memory allocation failed\n"); + fuse_log(FUSE_LOG_ERR, "fuse-subdir: memory allocation failed\n"); goto out_free; } d->base = tmp; diff --git a/lib/mount.c b/lib/mount.c index 7a18c11..979f8d9 100644 --- a/lib/mount.c +++ b/lib/mount.c @@ -175,7 +175,7 @@ static void set_mount_flag(const char *s, int *flags) return; } } - fprintf(stderr, "fuse: internal error, can't find mount flag\n"); + fuse_log(FUSE_LOG_ERR, "fuse: internal error, can't find mount flag\n"); abort(); } @@ -248,7 +248,7 @@ static int receive_fd(int fd) cmsg = CMSG_FIRSTHDR(&msg); if (cmsg->cmsg_type != SCM_RIGHTS) { - fprintf(stderr, "got control message of unknown type %d\n", + fuse_log(FUSE_LOG_ERR, "got control message of unknown type %d\n", cmsg->cmsg_type); return -1; } @@ -312,7 +312,7 @@ static int fuse_mount_fusermount(const char *mountpoint, struct mount_opts *mo, int rv; if (!mountpoint) { - fprintf(stderr, "fuse: missing mountpoint parameter\n"); + fuse_log(FUSE_LOG_ERR, "fuse: missing mountpoint parameter\n"); return -1; } @@ -393,13 +393,13 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo, int res; if (!mnt) { - fprintf(stderr, "fuse: missing mountpoint parameter\n"); + fuse_log(FUSE_LOG_ERR, "fuse: missing mountpoint parameter\n"); return -1; } res = stat(mnt, &stbuf); if (res == -1) { - fprintf(stderr ,"fuse: failed to access mountpoint %s: %s\n", + fuse_log(FUSE_LOG_ERR, "fuse: failed to access mountpoint %s: %s\n", mnt, strerror(errno)); return -1; } @@ -413,9 +413,9 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo, fd = open(devname, O_RDWR | O_CLOEXEC); if (fd == -1) { if (errno == ENODEV || errno == ENOENT) - fprintf(stderr, "fuse: device not found, try 'modprobe fuse' first\n"); + fuse_log(FUSE_LOG_ERR, "fuse: device not found, try 'modprobe fuse' first\n"); else - fprintf(stderr, "fuse: failed to open %s: %s\n", + fuse_log(FUSE_LOG_ERR, "fuse: failed to open %s: %s\n", devname, strerror(errno)); return -1; } @@ -435,7 +435,7 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo, type = malloc((mo->subtype ? strlen(mo->subtype) : 0) + 32); if (!type || !source) { - fprintf(stderr, "fuse: failed to allocate memory\n"); + fuse_log(FUSE_LOG_ERR, "fuse: failed to allocate memory\n"); goto out_close; } @@ -471,10 +471,10 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo, int errno_save = errno; if (mo->blkdev && errno == ENODEV && !fuse_mnt_check_fuseblk()) - fprintf(stderr, + fuse_log(FUSE_LOG_ERR, "fuse: 'fuseblk' support missing\n"); else - fprintf(stderr, "fuse: mount failed: %s\n", + fuse_log(FUSE_LOG_ERR, "fuse: mount failed: %s\n", strerror(errno_save)); } diff --git a/lib/mount_bsd.c b/lib/mount_bsd.c index cbd3ced..f731cb6 100644 --- a/lib/mount_bsd.c +++ b/lib/mount_bsd.c @@ -161,7 +161,7 @@ static int fuse_mount_core(const char *mountpoint, const char *opts) fd = strtol(fdnam, &ep, 10); if (*ep != '\0') { - fprintf(stderr, "invalid value given in FUSE_DEV_FD\n"); + fuse_log(FUSE_LOG_ERR, "invalid value given in FUSE_DEV_FD\n"); return -1; } -- cgit v1.2.3