Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[V0.10] Move to fuse3 #3284

Open
wants to merge 4 commits into
base: v0.10
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ FreeBSD_task:
freebsd_instance:
image_family: freebsd-13-3
prepare_script:
- pkg install -y $SSL git autoconf automake libtool pkgconf opus jpeg-turbo fdk-aac pixman libX11 libXfixes libXrandr nasm fusefs-libs check imlib2 freetype2 cmocka
- pkg install -y $SSL git autoconf automake libtool pkgconf opus jpeg-turbo fdk-aac pixman libX11 libXfixes libXrandr nasm fusefs-libs3 check imlib2 freetype2 cmocka
- git submodule update --init --recursive
configure_script:
- ./bootstrap
Expand Down
4 changes: 2 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -440,8 +440,8 @@ fi
# checking for fuse
if test "x$enable_fuse" = "xyes"
then
PKG_CHECK_MODULES([FUSE], [fuse >= 2.6], [],
[AC_MSG_ERROR([please install libfuse-dev or fuse-devel])])
PKG_CHECK_MODULES([FUSE], [fuse3 >= 3.1.0], [],
[AC_MSG_ERROR([please install libfuse3-dev or fuse3-devel])])
fi

# checking for fdk aac
Expand Down
2 changes: 1 addition & 1 deletion scripts/install_xrdp_build_dependencies_with_apt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ in
PACKAGES="$PACKAGES \
$PACKAGES_AMD64_MIN \
$LIBFREETYPE_DEV \
libfuse-dev \
libfuse3-dev \
libjpeg-dev \
libmp3lame-dev \
libfdk-aac-dev \
Expand Down
2 changes: 1 addition & 1 deletion sesman/chansrv/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ AM_CPPFLAGS = \
CHANSRV_EXTRA_LIBS =

if XRDP_FUSE
AM_CPPFLAGS += -DXRDP_FUSE $(FUSE_CFLAGS) -DFUSE_USE_VERSION=26
AM_CPPFLAGS += -DXRDP_FUSE $(FUSE_CFLAGS) -DFUSE_USE_VERSION=30
CHANSRV_EXTRA_LIBS += $(FUSE_LIBS)
endif

Expand Down
214 changes: 120 additions & 94 deletions sesman/chansrv/chansrv_fuse.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,15 @@ int xfuse_path_in_xfuse_fs(const char *path)
#include "list.h"
#include "file.h"

/* Check for FUSE features we may wish to use
*
* Note that FUSE_VERSION might be more useful for some features than
* FUSE_USE_VERSION
*/
#if FUSE_VERSION >= FUSE_MAKE_VERSION(3,7)
#define FUSE_SET_LOG_FUNC_AVAILABLE
#endif

#ifndef EREMOTEIO
#define EREMOTEIO EIO
#endif
Expand Down Expand Up @@ -325,15 +334,14 @@ extern struct config_chansrv *g_cfg; /* in chansrv.c */
static struct list *g_req_list = 0;
static struct xfs_fs *g_xfs; /* an inst of xrdp file system */
static ino_t g_clipboard_inum; /* inode of clipboard dir */
static char *g_mount_point = 0; /* our FUSE mount point */
static struct fuse_lowlevel_ops g_xfuse_ops; /* setup FUSE callbacks */
static int g_xfuse_inited = 0; /* true when FUSE is inited */
static struct fuse_chan *g_ch = 0;
static struct fuse_session *g_se = 0;
static char *g_buffer = 0;
static int g_fd = 0;
static tintptr g_bufsize = 0;

// For the below, see the source for the fuse_session_loop() function
static struct fuse_buf g_buffer =
{
.mem = NULL
};

/* forward declarations for internal access */
static int xfuse_init_xrdp_fs(void);
Expand Down Expand Up @@ -362,7 +370,8 @@ static void xfuse_cb_unlink(fuse_req_t req, fuse_ino_t parent,

static void xfuse_cb_rename(fuse_req_t req,
fuse_ino_t old_parent, const char *old_name,
fuse_ino_t new_parent, const char *new_name);
fuse_ino_t new_parent, const char *new_name,
unsigned int flags);

/* Whether to create a dir of file depends on whether S_IFDIR is set in the
mode field */
Expand Down Expand Up @@ -496,9 +505,9 @@ xfuse_init(void)
return 1;
}

if (g_ch != 0)
if (g_se != 0)
{
LOG_DEVEL(LOG_LEVEL_ERROR, "g_ch is not zero");
LOG_DEVEL(LOG_LEVEL_ERROR, "g_se is not zero");
return -1;
}

Expand Down Expand Up @@ -604,15 +613,18 @@ xfuse_init(void)
g_xfuse_ops.releasedir = xfuse_cb_releasedir;

fuse_opt_add_arg(&args, "xrdp-chansrv");
fuse_opt_add_arg(&args, g_fuse_root_path);
fuse_opt_add_arg(&args, "-o");
fuse_opt_add_arg(&args, "fsname=xrdp-chansrv");
//fuse_opt_add_arg(&args, "-s"); /* single threaded mode */
//fuse_opt_add_arg(&args, "-d"); /* debug mode */

if (xfuse_init_lib(&args))
{
fuse_opt_free_args(&args);
xfuse_deinit();
return -1;
}
fuse_opt_free_args(&args);

g_xfuse_inited = 1;
return 0;
Expand All @@ -627,30 +639,18 @@ xfuse_init(void)
int
xfuse_deinit(void)
{
if (g_ch != 0)
{
fuse_session_remove_chan(g_ch);
fuse_unmount(g_mount_point, g_ch);
g_ch = 0;
}

if (g_se != 0)
if (g_se != NULL)
{
fuse_session_unmount(g_se);
fuse_session_destroy(g_se);
g_se = 0;
g_se = NULL;
}

if (g_buffer != 0)
{
g_free(g_buffer);
g_buffer = 0;
}
free(g_buffer.mem);
g_buffer.mem = NULL;

if (g_req_list != 0)
{
list_delete(g_req_list);
g_req_list = 0;
}
list_delete(g_req_list);
g_req_list = 0;

xfuse_deinit_xrdp_fs();

Expand All @@ -665,35 +665,28 @@ xfuse_deinit(void)
*****************************************************************************/
int xfuse_check_wait_objs(void)
{
struct fuse_chan *tmpch;
int rval;

if (g_ch == 0)
{
return 0;
}

if (g_sck_can_recv(g_fd, 0))
if (g_se != NULL)
{
tmpch = g_ch;

rval = fuse_chan_recv(&tmpch, g_buffer, g_bufsize);
if (rval == -EINTR)
if (g_sck_can_recv(fuse_session_fd(g_se), 0))
{
return -1;
}
int rval = fuse_session_receive_buf(g_se, &g_buffer);
if (rval == -EINTR)
{
return -1;
}

if (rval == -ENODEV)
{
return -1;
}
if (rval == -ENODEV)
{
return -1;
}

if (rval <= 0)
{
return -1;
}
if (rval <= 0)
{
return -1;
}

fuse_session_process(g_se, g_buffer, rval, tmpch);
fuse_session_process_buf(g_se, &g_buffer);
}
}

return 0;
Expand All @@ -707,18 +700,12 @@ int xfuse_check_wait_objs(void)

int xfuse_get_wait_objs(tbus *objs, int *count, int *timeout)
{
int lcount;

if (g_ch == 0)
if (g_se != NULL)
{
return 0;
objs[*count] = fuse_session_fd(g_se);
++(*count);
}

lcount = *count;
objs[lcount] = g_fd;
lcount++;
*count = lcount;

return 0;
}

Expand Down Expand Up @@ -894,51 +881,84 @@ int xfuse_file_contents_size(int stream_id, int file_size)
** **
*****************************************************************************/

/*****************************************************************************/
/**
* FUSE logging function
*
* Used to get errors from FUSE for the log file
* @param fuse_log_level Logging level understood by FUSE
* @param fmt Logging format string
* @param ap Arguments for above
*/
#ifdef FUSE_SET_LOG_FUNC_AVAILABLE
static void
xfuse_log_func(enum fuse_log_level fuse_log_level, const char *fmt, va_list ap)
{
char msg[512];
enum logLevels level;
switch (fuse_log_level)
{
case FUSE_LOG_ERR:
level = LOG_LEVEL_ERROR;
break;

case FUSE_LOG_WARNING:
level = LOG_LEVEL_WARNING;
break;

case FUSE_LOG_NOTICE:
case FUSE_LOG_INFO:
level = LOG_LEVEL_INFO;
break;

case FUSE_LOG_DEBUG:
level = LOG_LEVEL_DEBUG;
break;

default:
level = LOG_LEVEL_ALWAYS;
break;
}

vsnprintf(msg, sizeof(msg), fmt, ap);
LOG(level, "%s", msg);
}
#endif //FUSE_SET_LOG_FUNC_AVAILABLE

/**
* Initialize FUSE library
*
* @return 0 on success, -1 on failure
*****************************************************************************/

static int xfuse_init_lib(struct fuse_args *args)
{
if (fuse_parse_cmdline(args, &g_mount_point, 0, 0) < 0)
int rv = -1;

#ifdef FUSE_SET_LOG_FUNC_AVAILABLE
fuse_set_log_func(xfuse_log_func);
#endif

g_se = fuse_session_new(args, &g_xfuse_ops, sizeof(g_xfuse_ops), 0);
if (g_se == NULL)
{
LOG(LOG_LEVEL_ERROR, "fuse_parse_cmdline() failed");
fuse_opt_free_args(args);
return -1;
LOG(LOG_LEVEL_ERROR, "fuse_session_new() failed");
}

if ((g_ch = fuse_mount(g_mount_point, args)) == 0)
else if (fuse_session_mount(g_se, g_fuse_root_path) != 0)
{
LOG(LOG_LEVEL_ERROR, "FUSE mount on %s failed."
" If %s is already mounted, you must first unmount it",
g_mount_point, g_mount_point);
fuse_opt_free_args(args);
return -1;
g_fuse_root_path, g_fuse_root_path);
fuse_session_destroy(g_se);
g_se = NULL;
}

g_se = fuse_lowlevel_new(args, &g_xfuse_ops, sizeof(g_xfuse_ops), 0);
if (g_se == 0)
else
{
LOG(LOG_LEVEL_ERROR, "fuse_lowlevel_new() failed");
fuse_unmount(g_mount_point, g_ch);
g_ch = 0;
fuse_opt_free_args(args);
return -1;
g_req_list = list_create();
g_req_list->auto_free = 1;
rv = 0;
}

fuse_opt_free_args(args);
fuse_session_add_chan(g_se, g_ch);
g_bufsize = fuse_chan_bufsize(g_ch);

g_buffer = g_new0(char, g_bufsize);
g_fd = fuse_chan_fd(g_ch);

g_req_list = list_create();
g_req_list->auto_free = 1;

return 0;
return rv;
}

/**
Expand Down Expand Up @@ -1934,16 +1954,22 @@ static void xfuse_cb_unlink(fuse_req_t req, fuse_ino_t parent,

static void xfuse_cb_rename(fuse_req_t req,
fuse_ino_t old_parent, const char *old_name,
fuse_ino_t new_parent, const char *new_name)
fuse_ino_t new_parent, const char *new_name,
unsigned int flags)
{
XFS_INODE *old_xinode;
XFS_INODE *new_parent_xinode;

LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: old_parent=%ld old_name=%s new_parent=%ld new_name=%s",
old_parent, old_name, new_parent, new_name);

if (strlen(old_name) > XFS_MAXFILENAMELEN ||
strlen(new_name) > XFS_MAXFILENAMELEN)
// renameat2() flags (in stdio.h) are not supported
if (flags != 0)
{
fuse_reply_err(req, EINVAL);
}
else if (strlen(old_name) > XFS_MAXFILENAMELEN ||
strlen(new_name) > XFS_MAXFILENAMELEN)
{
fuse_reply_err(req, ENAMETOOLONG);
}
Expand Down