Skip to content

Commit

Permalink
Merge pull request #6085 from yosefe/topic/tools-vfs-implement-mount-…
Browse files Browse the repository at this point in the history
…daemon-server-loop

TOOLS/VFS: Implement mount daemon server loop
  • Loading branch information
yosefe authored Jan 3, 2021
2 parents ad547a0 + 2937bf5 commit 0ce4ac8
Show file tree
Hide file tree
Showing 4 changed files with 500 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/tools/vfs/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ if HAVE_FUSE3
bin_PROGRAMS = ucx_vfs
ucx_vfs_CPPFLAGS = $(BASE_CPPFLAGS) $(FUSE3_CPPFLAGS)
ucx_vfs_CFLAGS = $(BASE_CFLAGS)
ucx_vfs_SOURCES = vfs_main.c
ucx_vfs_SOURCES = vfs_main.c vfs_server.c
noinst_HEADERS = vfs_daemon.h
ucx_vfs_LDADD = $(FUSE3_LIBS) \
$(top_builddir)/src/ucs/vfs/sock/libucs_vfs_sock.la
Expand Down
6 changes: 6 additions & 0 deletions src/tools/vfs/vfs_daemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,10 @@ typedef struct {
extern vfs_opts_t g_opts;
extern const char *vfs_action_names[];

int vfs_mount(int pid);

int vfs_unmount(int pid);

int vfs_server_loop(int listen_fd);

#endif
120 changes: 118 additions & 2 deletions src/tools/vfs/vfs_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,122 @@ static int vfs_run_fusermount(char **extra_argv)
return 0;
}

static void vfs_get_mountpoint(pid_t pid, char *mountpoint, size_t max_length)
{
snprintf(mountpoint, max_length, "%s/%d", g_opts.mountpoint_dir, pid);
}

static const char *vfs_get_process_name(int pid, char *buf, size_t max_length)
{
char procfs_comm[NAME_MAX];
size_t length;
FILE *file;
char *p;

/* open /proc/<pid>/comm to read command name */
snprintf(procfs_comm, sizeof(procfs_comm), "/proc/%d/comm", pid);
file = fopen(procfs_comm, "r");
if (file == NULL) {
goto err;
}

/* read command to buffer */
if (fgets(buf, max_length, file) == NULL) {
goto err_close;
}

/* remove trailing space/newline */
length = strlen(buf);
for (p = &buf[length - 1]; (p >= buf) && isspace(*p); --p) {
*p = '\0';
--length;
}

/* append process id */
snprintf(buf + length, max_length - length, "@pid:%d", pid);
goto out;

err_close:
fclose(file);
err:
snprintf(buf, max_length, "pid:%d", pid);
out:
return buf;
}

int vfs_mount(int pid)
{
char mountpoint[PATH_MAX];
char mountopts[1024];
char name[NAME_MAX];
int fuse_fd, ret;

/* Add common mount options:
* - File system name (source) : process name and pid
* - File system type : ucx_vfs
* - Enable permissions check : yes
* - Direct IO (no caching) : yes
*/
ret = snprintf(
mountopts, sizeof(mountopts),
"fsname=%s,subtype=ucx_vfs,default_permissions,direct_io%s%s",
vfs_get_process_name(pid, name, sizeof(name)),
(strlen(g_opts.mount_opts) > 0) ? "," : "", g_opts.mount_opts);
if (ret >= sizeof(mountopts)) {
return -ENOMEM;
}

/* Create the mount point directory, and ignore "already exists" error */
vfs_get_mountpoint(pid, mountpoint, sizeof(mountpoint));
ret = mkdir(mountpoint, S_IRWXU);
if ((ret < 0) && (errno != EEXIST)) {
ret = -errno;
vfs_error("failed to create directory '%s': %m", mountpoint);
return ret;
}

/* Mount a new FUSE filesystem in the mount point directory */
vfs_log("mounting directory '%s' with options '%s'", mountpoint, mountopts);
fuse_fd = fuse_open_channel(mountpoint, mountopts);
if (fuse_fd < 0) {
vfs_error("fuse_open_channel(%s,opts=%s) failed: %m", mountpoint,
mountopts);
return fuse_fd;
}

vfs_log("mounted directory '%s' with fd %d", mountpoint, fuse_fd);
return fuse_fd;
}

int vfs_unmount(int pid)
{
char mountpoint[PATH_MAX];
char *argv[5];
int ret;

/* Unmount FUSE file system */
vfs_get_mountpoint(pid, mountpoint, sizeof(mountpoint));
argv[0] = "-u";
argv[1] = "-z";
argv[2] = "--";
argv[3] = mountpoint;
argv[4] = NULL;
ret = vfs_run_fusermount(argv);
if (ret < 0) {
return ret;
}

/* Remove mount point directory */
vfs_log("removing directory '%s'", mountpoint);
ret = rmdir(mountpoint);
if (ret < 0) {
vfs_error("failed to remove directory '%s': %m", mountpoint);
return ret;
}

return 0;
}

static int vfs_unlink_socket(int silent_notexist)
{
int ret;
Expand Down Expand Up @@ -155,8 +271,8 @@ static int vfs_listen(int silent_addinuse_err)
goto out_unlink;
}

vfs_error("closing socket, TODO implement listening for connections");
close(listen_fd);
vfs_log("listening for connections on '%s'", g_sockaddr.sun_path);
ret = vfs_server_loop(listen_fd);

out_unlink:
vfs_unlink_socket(0);
Expand Down
Loading

0 comments on commit 0ce4ac8

Please sign in to comment.