parent
16c5db6b2c
commit
b62e9fc67b
@ -0,0 +1,145 @@
|
|||||||
|
#include "webfused/mountpoint_factory.h"
|
||||||
|
#include "webfused/log/log.h"
|
||||||
|
|
||||||
|
#include <webfuse/adapter/mountpoint.h>
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define WFD_FILESYSTEM_DEFAULT_CAPACITY 16
|
||||||
|
|
||||||
|
struct wfd_filesystem
|
||||||
|
{
|
||||||
|
char * name;
|
||||||
|
char * mount_point;
|
||||||
|
bool in_use;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wfd_mountpoint_factory
|
||||||
|
{
|
||||||
|
struct wfd_filesystem * filesystems;
|
||||||
|
size_t capacity;
|
||||||
|
size_t count;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct wfd_filesystem *
|
||||||
|
wfd_mountpoint_factory_find(
|
||||||
|
struct wfd_mountpoint_factory * factory,
|
||||||
|
char const * name)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < factory->count; i++)
|
||||||
|
{
|
||||||
|
struct wfd_filesystem * filesystem = &(factory->filesystems[i]);
|
||||||
|
if (0 == strcmp(name, filesystem->name))
|
||||||
|
{
|
||||||
|
return filesystem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wfd_mountpoint_factory_release_mountpoint(
|
||||||
|
void * user_data)
|
||||||
|
{
|
||||||
|
bool * in_use = user_data;
|
||||||
|
*in_use = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wfd_mountpoint_factory *
|
||||||
|
wfd_mountpoint_factory_create(void)
|
||||||
|
{
|
||||||
|
struct wfd_mountpoint_factory * factory = malloc(sizeof(struct wfd_mountpoint_factory));
|
||||||
|
factory->filesystems = malloc(sizeof(struct wfd_filesystem) * WFD_FILESYSTEM_DEFAULT_CAPACITY);
|
||||||
|
factory->count = 0;
|
||||||
|
factory->capacity = WFD_FILESYSTEM_DEFAULT_CAPACITY;
|
||||||
|
|
||||||
|
return factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wfd_mountpoint_factory_dispose(
|
||||||
|
struct wfd_mountpoint_factory * factory)
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < factory->count; i++)
|
||||||
|
{
|
||||||
|
struct wfd_filesystem * filesystem = &(factory->filesystems[i]);
|
||||||
|
free(filesystem->name);
|
||||||
|
free(filesystem->mount_point);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(factory->filesystems);
|
||||||
|
free(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wfd_mountpoint_factory_add_filesystem(
|
||||||
|
struct wfd_mountpoint_factory * factory,
|
||||||
|
char const * name,
|
||||||
|
char const * mount_point)
|
||||||
|
{
|
||||||
|
bool result = (NULL == wfd_mountpoint_factory_find(factory, name));
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
WFD_ERROR("mount_point already defined: \'%s\'", mount_point);
|
||||||
|
}
|
||||||
|
|
||||||
|
char * path = NULL;
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
mkdir(mount_point, 0755);
|
||||||
|
path = realpath(mount_point, NULL);
|
||||||
|
if (NULL == path)
|
||||||
|
{
|
||||||
|
WFD_ERROR("invalid mount_point: \'%s\'", mount_point);
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
if (factory->count >= factory->capacity)
|
||||||
|
{
|
||||||
|
factory->capacity *= 2;
|
||||||
|
factory->filesystems = realloc(factory->filesystems,
|
||||||
|
sizeof(struct wfd_filesystem) * factory->capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wfd_filesystem * actual = &(factory->filesystems[factory->count]);
|
||||||
|
actual->name = strdup(name);
|
||||||
|
actual->mount_point = path;
|
||||||
|
actual->in_use = false;
|
||||||
|
factory->count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern struct wf_mountpoint *
|
||||||
|
wfd_mountpoint_factory_create_mountpoint(
|
||||||
|
char const * filesystem,
|
||||||
|
void * user_data)
|
||||||
|
{
|
||||||
|
struct wfd_mountpoint_factory * factory = user_data;
|
||||||
|
struct wfd_filesystem * fs = wfd_mountpoint_factory_find(factory, filesystem);
|
||||||
|
if (NULL == fs)
|
||||||
|
{
|
||||||
|
WFD_INFO("failed to create mountpoint: filesystem \'%s\' not found", filesystem);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs->in_use)
|
||||||
|
{
|
||||||
|
WFD_INFO("failed to create mountpoint: filesystem \'%s\' already in use", filesystem);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs->in_use = true;
|
||||||
|
struct wf_mountpoint * result = wf_mountpoint_create(fs->mount_point);
|
||||||
|
wf_mountpoint_set_userdata(result,
|
||||||
|
&fs->in_use, &wfd_mountpoint_factory_release_mountpoint);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef WFD_MOUNTPOINT_FACTORY_H
|
||||||
|
#define WFD_MOUNTPOINT_FACTORY_H
|
||||||
|
|
||||||
|
#include "webfuse/adapter/mountpoint_factory.h"
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#include <stdbool.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct wfd_mountpoint_factory;
|
||||||
|
|
||||||
|
extern struct wfd_mountpoint_factory *
|
||||||
|
wfd_mountpoint_factory_create(void);
|
||||||
|
|
||||||
|
extern void
|
||||||
|
wfd_mountpoint_factory_dispose(
|
||||||
|
struct wfd_mountpoint_factory * factory);
|
||||||
|
|
||||||
|
extern bool
|
||||||
|
wfd_mountpoint_factory_add_filesystem(
|
||||||
|
struct wfd_mountpoint_factory * factory,
|
||||||
|
char const * name,
|
||||||
|
char const * mount_point);
|
||||||
|
|
||||||
|
extern struct wf_mountpoint *
|
||||||
|
wfd_mountpoint_factory_create_mountpoint(
|
||||||
|
char const * filesystem,
|
||||||
|
void * user_data);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,135 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include "webfused/mountpoint_factory.h"
|
||||||
|
#include <webfuse/adapter/mountpoint.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
TEST(mountpoint_factory, create)
|
||||||
|
{
|
||||||
|
wfd_mountpoint_factory * factory = wfd_mountpoint_factory_create();
|
||||||
|
ASSERT_NE(nullptr, factory);
|
||||||
|
|
||||||
|
wfd_mountpoint_factory_dispose(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(mountpiont_factory, add_filesystem)
|
||||||
|
{
|
||||||
|
wfd_mountpoint_factory * factory = wfd_mountpoint_factory_create();
|
||||||
|
ASSERT_NE(nullptr, factory);
|
||||||
|
|
||||||
|
bool success = wfd_mountpoint_factory_add_filesystem(factory, "test", "/tmp/webfused_test");
|
||||||
|
ASSERT_TRUE(success);
|
||||||
|
|
||||||
|
wfd_mountpoint_factory_dispose(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(mountpiont_factory, add_filesystem_fail_to_add_twice)
|
||||||
|
{
|
||||||
|
wfd_mountpoint_factory * factory = wfd_mountpoint_factory_create();
|
||||||
|
ASSERT_NE(nullptr, factory);
|
||||||
|
|
||||||
|
bool success = wfd_mountpoint_factory_add_filesystem(factory, "test", "/tmp/webfused_test");
|
||||||
|
ASSERT_TRUE(success);
|
||||||
|
|
||||||
|
success = wfd_mountpoint_factory_add_filesystem(factory, "test", "/tmp/webfused_test");
|
||||||
|
ASSERT_FALSE(success);
|
||||||
|
|
||||||
|
wfd_mountpoint_factory_dispose(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(mountpiont_factory, add_filesystem_multi)
|
||||||
|
{
|
||||||
|
wfd_mountpoint_factory * factory = wfd_mountpoint_factory_create();
|
||||||
|
ASSERT_NE(nullptr, factory);
|
||||||
|
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 24; i++)
|
||||||
|
{
|
||||||
|
char name[10];
|
||||||
|
snprintf(name, 10, "test_%zu", i);
|
||||||
|
bool success = wfd_mountpoint_factory_add_filesystem(factory, name, "/tmp/webfused_test");
|
||||||
|
ASSERT_TRUE(success) << i;
|
||||||
|
}
|
||||||
|
|
||||||
|
wfd_mountpoint_factory_dispose(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(mountpiont_factory, add_filesystem_fail_invalid_path)
|
||||||
|
{
|
||||||
|
wfd_mountpoint_factory * factory = wfd_mountpoint_factory_create();
|
||||||
|
ASSERT_NE(nullptr, factory);
|
||||||
|
|
||||||
|
bool success = wfd_mountpoint_factory_add_filesystem(factory, "test", "/do/not/allow/nested/paths");
|
||||||
|
ASSERT_FALSE(success);
|
||||||
|
|
||||||
|
wfd_mountpoint_factory_dispose(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(mountpiont_factory, create_mountpoint)
|
||||||
|
{
|
||||||
|
wfd_mountpoint_factory * factory = wfd_mountpoint_factory_create();
|
||||||
|
ASSERT_NE(nullptr, factory);
|
||||||
|
|
||||||
|
bool success = wfd_mountpoint_factory_add_filesystem(factory, "test", "/tmp/webfuse_test");
|
||||||
|
ASSERT_TRUE(success);
|
||||||
|
|
||||||
|
wf_mountpoint * mountpoint = wfd_mountpoint_factory_create_mountpoint("test", factory);
|
||||||
|
ASSERT_NE(nullptr, mountpoint);
|
||||||
|
ASSERT_STREQ("/tmp/webfuse_test", wf_mountpoint_get_path(mountpoint));
|
||||||
|
|
||||||
|
wf_mountpoint_dispose(mountpoint);
|
||||||
|
wfd_mountpoint_factory_dispose(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(mountpiont_factory, create_mountpoint_fail_already_in_use)
|
||||||
|
{
|
||||||
|
wfd_mountpoint_factory * factory = wfd_mountpoint_factory_create();
|
||||||
|
ASSERT_NE(nullptr, factory);
|
||||||
|
|
||||||
|
bool success = wfd_mountpoint_factory_add_filesystem(factory, "test", "/tmp/webfuse_test");
|
||||||
|
ASSERT_TRUE(success);
|
||||||
|
|
||||||
|
wf_mountpoint * mountpoint = wfd_mountpoint_factory_create_mountpoint("test", factory);
|
||||||
|
ASSERT_NE(nullptr, mountpoint);
|
||||||
|
ASSERT_STREQ("/tmp/webfuse_test", wf_mountpoint_get_path(mountpoint));
|
||||||
|
|
||||||
|
wf_mountpoint * mountpoint2 = wfd_mountpoint_factory_create_mountpoint("test", factory);
|
||||||
|
ASSERT_EQ(nullptr, mountpoint2);
|
||||||
|
|
||||||
|
wf_mountpoint_dispose(mountpoint);
|
||||||
|
wfd_mountpoint_factory_dispose(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(mountpiont_factory, create_mountpoint_fail_unknown_filesystem)
|
||||||
|
{
|
||||||
|
wfd_mountpoint_factory * factory = wfd_mountpoint_factory_create();
|
||||||
|
ASSERT_NE(nullptr, factory);
|
||||||
|
|
||||||
|
bool success = wfd_mountpoint_factory_add_filesystem(factory, "test", "/tmp/webfuse_test");
|
||||||
|
ASSERT_TRUE(success);
|
||||||
|
|
||||||
|
wf_mountpoint * mountpoint = wfd_mountpoint_factory_create_mountpoint("unkown", factory);
|
||||||
|
ASSERT_EQ(nullptr, mountpoint);
|
||||||
|
|
||||||
|
wfd_mountpoint_factory_dispose(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(mountpiont_factory, create_mountpoint_multi)
|
||||||
|
{
|
||||||
|
wfd_mountpoint_factory * factory = wfd_mountpoint_factory_create();
|
||||||
|
ASSERT_NE(nullptr, factory);
|
||||||
|
|
||||||
|
bool success = wfd_mountpoint_factory_add_filesystem(factory, "test", "/tmp/webfuse_test");
|
||||||
|
ASSERT_TRUE(success);
|
||||||
|
|
||||||
|
for(int i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
wf_mountpoint * mountpoint = wfd_mountpoint_factory_create_mountpoint("test", factory);
|
||||||
|
ASSERT_NE(nullptr, mountpoint) << i;
|
||||||
|
ASSERT_STREQ("/tmp/webfuse_test", wf_mountpoint_get_path(mountpoint)) << i;
|
||||||
|
|
||||||
|
wf_mountpoint_dispose(mountpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
wfd_mountpoint_factory_dispose(factory);
|
||||||
|
}
|
Loading…
Reference in new issue