pmxcfs: auto-format code base using clang-format

through the new format target, throw in the cpg-test file manually
while at it.

One can transform a file using this style also by CLI only, like for
example:

clang-format -i --style="{BasedOnStyle: llvm, IndentWidth: 4,
   ColumnLimit: 100, AlignAfterOpenBracket: BlockIndent,
   BinPackParameters: false}" FILE1 FILE2 ...

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
Thomas Lamprecht 2025-06-02 20:30:48 +02:00
parent 483f4ea14d
commit 00f25e13b8
33 changed files with 9034 additions and 10156 deletions

View file

@ -22,218 +22,196 @@
#include <config.h>
#endif /* HAVE_CONFIG_H */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <glib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "cfs-utils.h"
#include "cfs-plug.h"
#include "cfs-utils.h"
static struct cfs_operations cfs_ops;
static cfs_plug_t *cfs_plug_func_lookup_plug(cfs_plug_t *plug, char **path)
{
g_return_val_if_fail(plug != NULL, NULL);
g_return_val_if_fail(plug->ops == &cfs_ops, NULL);
static cfs_plug_t *cfs_plug_func_lookup_plug(cfs_plug_t *plug, char **path) {
g_return_val_if_fail(plug != NULL, NULL);
g_return_val_if_fail(plug->ops == &cfs_ops, NULL);
return (!*path || !(*path)[0]) ? plug : NULL;
return (!*path || !(*path)[0]) ? plug : NULL;
}
static void cfs_plug_func_destroy(cfs_plug_t *plug)
{
g_return_if_fail(plug != NULL);
g_return_if_fail(plug->ops == &cfs_ops);
static void cfs_plug_func_destroy(cfs_plug_t *plug) {
g_return_if_fail(plug != NULL);
g_return_if_fail(plug->ops == &cfs_ops);
cfs_plug_func_t *fplug = (cfs_plug_func_t *)plug;
cfs_plug_func_t *fplug = (cfs_plug_func_t *)plug;
cfs_debug("enter cfs_plug_func_destroy %s", plug->name);
cfs_debug("enter cfs_plug_func_destroy %s", plug->name);
if (fplug->data)
g_free(fplug->data);
if (fplug->data)
g_free(fplug->data);
g_free(plug->name);
g_free(plug->name);
g_free(plug);
g_free(plug);
}
static int
cfs_plug_func_getattr(
cfs_plug_t *plug,
const char *path,
struct stat *stbuf)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(stbuf != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_func_getattr(cfs_plug_t *plug, const char *path, struct stat *stbuf) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(stbuf != NULL, PARAM_CHECK_ERRNO);
cfs_debug("enter cfs_plug_func_getattr %s", path);
cfs_debug("enter cfs_plug_func_getattr %s", path);
cfs_plug_func_t *fplug = (cfs_plug_func_t *)plug;
cfs_plug_func_t *fplug = (cfs_plug_func_t *)plug;
memset(stbuf, 0, sizeof(struct stat));
memset(stbuf, 0, sizeof(struct stat));
g_rw_lock_writer_lock(&fplug->data_rw_lock);
if (fplug->data)
g_free(fplug->data);
g_rw_lock_writer_lock(&fplug->data_rw_lock);
if (fplug->data)
g_free(fplug->data);
fplug->data = fplug->update_callback(plug);
fplug->data = fplug->update_callback(plug);
stbuf->st_size = fplug->data ? strlen(fplug->data) : 0;
stbuf->st_size = fplug->data ? strlen(fplug->data) : 0;
g_rw_lock_writer_unlock(&fplug->data_rw_lock);
g_rw_lock_writer_unlock(&fplug->data_rw_lock);
stbuf->st_mode = fplug->mode;
stbuf->st_nlink = 1;
stbuf->st_mode = fplug->mode;
stbuf->st_nlink = 1;
return 0;
return 0;
}
static int
cfs_plug_func_read(
cfs_plug_t *plug,
const char *path,
char *buf,
size_t size,
off_t offset,
struct fuse_file_info *fi)
{
(void) fi;
static int cfs_plug_func_read(
cfs_plug_t *plug,
const char *path,
char *buf,
size_t size,
off_t offset,
struct fuse_file_info *fi
) {
(void)fi;
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
cfs_plug_func_t *fplug = (cfs_plug_func_t *)plug;
cfs_plug_func_t *fplug = (cfs_plug_func_t *)plug;
g_rw_lock_reader_lock(&fplug->data_rw_lock);
char *data = fplug->data;
g_rw_lock_reader_lock(&fplug->data_rw_lock);
char *data = fplug->data;
cfs_debug("enter cfs_plug_func_read %s", data);
cfs_debug("enter cfs_plug_func_read %s", data);
if (!data) {
g_rw_lock_reader_unlock(&fplug->data_rw_lock);
return 0;
}
if (!data) {
g_rw_lock_reader_unlock(&fplug->data_rw_lock);
return 0;
}
int len = strlen(data);
int len = strlen(data);
if (offset < len) {
if (offset + size > len)
size = len - offset;
memcpy(buf, data + offset, size);
} else {
size = 0;
}
g_rw_lock_reader_unlock(&fplug->data_rw_lock);
if (offset < len) {
if (offset + size > len)
size = len - offset;
memcpy(buf, data + offset, size);
} else {
size = 0;
}
g_rw_lock_reader_unlock(&fplug->data_rw_lock);
return size;
return size;
}
static int
cfs_plug_func_write(
cfs_plug_t *plug,
const char *path,
const char *buf,
size_t size,
off_t offset,
struct fuse_file_info *fi)
{
(void) fi;
static int cfs_plug_func_write(
cfs_plug_t *plug,
const char *path,
const char *buf,
size_t size,
off_t offset,
struct fuse_file_info *fi
) {
(void)fi;
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
cfs_debug("enter cfs_plug_func_write");
cfs_debug("enter cfs_plug_func_write");
cfs_plug_func_t *fplug = (cfs_plug_func_t *)plug;
cfs_plug_func_t *fplug = (cfs_plug_func_t *)plug;
if (offset != 0 || !fplug->write_callback)
return -EIO;
if (offset != 0 || !fplug->write_callback)
return -EIO;
return fplug->write_callback(plug, buf, size);
return fplug->write_callback(plug, buf, size);
}
static int
cfs_plug_func_truncate(
cfs_plug_t *plug,
const char *path,
off_t size)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_func_truncate(cfs_plug_t *plug, const char *path, off_t size) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
cfs_plug_func_t *fplug = (cfs_plug_func_t *)plug;
cfs_plug_func_t *fplug = (cfs_plug_func_t *)plug;
if (fplug->write_callback)
return 0;
if (fplug->write_callback)
return 0;
return -EIO;
return -EIO;
}
static int
cfs_plug_func_open(
cfs_plug_t *plug,
const char *path,
struct fuse_file_info *fi)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(fi != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_func_open(cfs_plug_t *plug, const char *path, struct fuse_file_info *fi) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(fi != NULL, PARAM_CHECK_ERRNO);
cfs_debug("enter cfs_plug_func_open %s", path);
cfs_debug("enter cfs_plug_func_open %s", path);
return 0;
return 0;
}
static struct cfs_operations cfs_ops = {
.getattr = cfs_plug_func_getattr,
.read = cfs_plug_func_read,
.write = cfs_plug_func_write,
.truncate = cfs_plug_func_truncate,
.open = cfs_plug_func_open,
.getattr = cfs_plug_func_getattr,
.read = cfs_plug_func_read,
.write = cfs_plug_func_write,
.truncate = cfs_plug_func_truncate,
.open = cfs_plug_func_open,
};
cfs_plug_func_t *cfs_plug_func_new(
const char *name,
mode_t mode,
cfs_plug_func_update_data_fn_t update_callback,
cfs_plug_func_write_data_fn_t write_callback
) {
g_return_val_if_fail(name != NULL, NULL);
g_return_val_if_fail(update_callback != NULL, NULL);
cfs_plug_func_t *
cfs_plug_func_new(
const char *name,
mode_t mode,
cfs_plug_func_update_data_fn_t update_callback,
cfs_plug_func_write_data_fn_t write_callback)
{
g_return_val_if_fail(name != NULL, NULL);
g_return_val_if_fail(update_callback != NULL, NULL);
cfs_plug_func_t *fplug = g_new0(cfs_plug_func_t, 1);
cfs_plug_func_t *fplug = g_new0(cfs_plug_func_t, 1);
fplug->plug.ops = &cfs_ops;
fplug->plug.ops = &cfs_ops;
fplug->plug.lookup_plug = cfs_plug_func_lookup_plug;
fplug->plug.destroy_plug = cfs_plug_func_destroy;
fplug->plug.lookup_plug = cfs_plug_func_lookup_plug;
fplug->plug.destroy_plug = cfs_plug_func_destroy;
fplug->plug.name = g_strdup(name);
fplug->plug.name = g_strdup(name);
fplug->update_callback = update_callback;
fplug->write_callback = write_callback;
if (!write_callback)
mode = mode & ~0222;
fplug->update_callback = update_callback;
fplug->write_callback = write_callback;
if (!write_callback)
mode = mode & ~0222;
fplug->mode = S_IFREG | mode;
fplug->mode = S_IFREG | mode;
return fplug;
return fplug;
}

View file

@ -22,117 +22,110 @@
#include <config.h>
#endif /* HAVE_CONFIG_H */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <glib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "cfs-utils.h"
#include "cfs-plug.h"
#include "cfs-utils.h"
#include "status.h"
static struct cfs_operations cfs_ops;
static cfs_plug_t *cfs_plug_link_lookup_plug(cfs_plug_t *plug, char **path)
{
g_return_val_if_fail(plug != NULL, NULL);
g_return_val_if_fail(plug->ops == &cfs_ops, NULL);
static cfs_plug_t *cfs_plug_link_lookup_plug(cfs_plug_t *plug, char **path) {
g_return_val_if_fail(plug != NULL, NULL);
g_return_val_if_fail(plug->ops == &cfs_ops, NULL);
return (!*path || !(*path)[0]) ? plug : NULL;
return (!*path || !(*path)[0]) ? plug : NULL;
}
static int cfs_plug_link_getattr(cfs_plug_t *plug, const char *path, struct stat *stbuf)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(stbuf != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_link_getattr(cfs_plug_t *plug, const char *path, struct stat *stbuf) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(stbuf != NULL, PARAM_CHECK_ERRNO);
cfs_debug("enter cfs_plug_link_getattr %s", path);
cfs_debug("enter cfs_plug_link_getattr %s", path);
memset(stbuf, 0, sizeof(struct stat));
memset(stbuf, 0, sizeof(struct stat));
if (cfs_is_quorate()) {
stbuf->st_mode = S_IFLNK | 0777;
} else {
stbuf->st_mode = S_IFLNK | 0555;
}
if (cfs_is_quorate()) {
stbuf->st_mode = S_IFLNK | 0777;
} else {
stbuf->st_mode = S_IFLNK | 0555;
}
stbuf->st_nlink = 1;
stbuf->st_nlink = 1;
return 0;
return 0;
}
static int cfs_plug_link_readlink(cfs_plug_t *plug, const char *path, char *buf, size_t max)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_link_readlink(cfs_plug_t *plug, const char *path, char *buf, size_t max) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
cfs_debug("enter cfs_plug_link_readlink %s", path);
cfs_debug("enter cfs_plug_link_readlink %s", path);
int ret = -EACCES;
int ret = -EACCES;
cfs_plug_link_t *lnk = (cfs_plug_link_t *)plug;
cfs_plug_link_t *lnk = (cfs_plug_link_t *)plug;
if (!lnk->symlink)
goto ret;
if (!lnk->symlink)
goto ret;
strncpy(buf, lnk->symlink, max);
if (max > 0)
buf[max - 1]= '\0';
ret = 0;
strncpy(buf, lnk->symlink, max);
if (max > 0)
buf[max - 1] = '\0';
ret = 0;
ret:
return ret;
return ret;
}
static void cfs_plug_link_destroy(cfs_plug_t *plug)
{
g_return_if_fail(plug != NULL);
g_return_if_fail(plug->ops == &cfs_ops);
static void cfs_plug_link_destroy(cfs_plug_t *plug) {
g_return_if_fail(plug != NULL);
g_return_if_fail(plug->ops == &cfs_ops);
cfs_plug_link_t *lnk = (cfs_plug_link_t *)plug;
cfs_plug_link_t *lnk = (cfs_plug_link_t *)plug;
cfs_debug("enter cfs_plug_link_destroy %s", plug->name);
cfs_debug("enter cfs_plug_link_destroy %s", plug->name);
g_free(plug->name);
g_free(plug->name);
g_free(lnk->symlink);
g_free(lnk->symlink);
g_free(plug);
g_free(plug);
}
static struct cfs_operations cfs_ops = {
.getattr = cfs_plug_link_getattr,
.readlink = cfs_plug_link_readlink,
.getattr = cfs_plug_link_getattr,
.readlink = cfs_plug_link_readlink,
};
cfs_plug_link_t *cfs_plug_link_new(const char *name, const char *symlink) {
g_return_val_if_fail(name != NULL, NULL);
g_return_val_if_fail(symlink != NULL, NULL);
cfs_plug_link_t *cfs_plug_link_new(const char *name, const char *symlink)
{
g_return_val_if_fail(name != NULL, NULL);
g_return_val_if_fail(symlink != NULL, NULL);
cfs_plug_link_t *lnk = g_new0(cfs_plug_link_t, 1);
cfs_plug_link_t *lnk = g_new0(cfs_plug_link_t, 1);
lnk->plug.ops = &cfs_ops;
lnk->plug.ops = &cfs_ops;
lnk->plug.lookup_plug = cfs_plug_link_lookup_plug;
lnk->plug.destroy_plug = cfs_plug_link_destroy;
lnk->plug.lookup_plug = cfs_plug_link_lookup_plug;
lnk->plug.destroy_plug = cfs_plug_link_destroy;
lnk->plug.name = g_strdup(name);
lnk->plug.name = g_strdup(name);
lnk->symlink = g_strdup(symlink);
lnk->symlink = g_strdup(symlink);
return lnk;
return lnk;
}

View file

@ -22,506 +22,471 @@
#include <config.h>
#endif /* HAVE_CONFIG_H */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <glib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <arpa/inet.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "cfs-utils.h"
#include "cfs-plug-memdb.h"
#include "cfs-utils.h"
#include "dcdb.h"
#include "status.h"
static struct cfs_operations cfs_ops;
// FIXME: remove openvz stuff for 7.x
static gboolean
name_is_openvz_script(
const char *name,
guint32 *vmid_ret)
{
if (!name)
return FALSE;
static gboolean name_is_openvz_script(const char *name, guint32 *vmid_ret) {
if (!name)
return FALSE;
guint32 vmid = 0;
char *end = NULL;
guint32 vmid = 0;
char *end = NULL;
if (name[0] == 'v' && name[1] == 'p' && name[2] == 's') {
end = (char *)name + 3;
} else {
if (name[0] < '1' || name[0] > '9')
return FALSE;
if (name[0] == 'v' && name[1] == 'p' && name[2] == 's') {
end = (char *)name + 3;
} else {
if (name[0] < '1' || name[0] > '9')
return FALSE;
vmid = strtoul(name, &end, 10);
}
vmid = strtoul(name, &end, 10);
}
if (!end || end[0] != '.')
return FALSE;
if (!end || end[0] != '.')
return FALSE;
end++;
end++;
gboolean res = FALSE;
gboolean res = FALSE;
if (end[0] == 'm' && strcmp(end, "mount") == 0)
res = TRUE;
if (end[0] == 'm' && strcmp(end, "mount") == 0)
res = TRUE;
if (end[0] == 'u' && strcmp(end, "umount") == 0)
res = TRUE;
if (end[0] == 'u' && strcmp(end, "umount") == 0)
res = TRUE;
if (end[0] == 's' &&
(strcmp(end, "start") == 0 || strcmp(end, "stop") == 0))
res = TRUE;
if (end[0] == 's' && (strcmp(end, "start") == 0 || strcmp(end, "stop") == 0))
res = TRUE;
if (end[0] == 'p' &&
(strcmp(end, "premount") == 0 || strcmp(end, "postumount") == 0))
res = TRUE;
if (end[0] == 'p' && (strcmp(end, "premount") == 0 || strcmp(end, "postumount") == 0))
res = TRUE;
if (res && vmid_ret)
*vmid_ret = vmid;
if (res && vmid_ret)
*vmid_ret = vmid;
return res;
return res;
}
static void tree_entry_stat(memdb_tree_entry_t *te, struct stat *stbuf, gboolean quorate)
{
g_return_if_fail(te != NULL);
g_return_if_fail(stbuf != NULL);
static void tree_entry_stat(memdb_tree_entry_t *te, struct stat *stbuf, gboolean quorate) {
g_return_if_fail(te != NULL);
g_return_if_fail(stbuf != NULL);
if (te->type == DT_DIR) {
stbuf->st_mode = S_IFDIR | (quorate ? 0777 : 0555);
stbuf->st_nlink = 2;
} else {
stbuf->st_mode = S_IFREG | (quorate ? 0666 : 0444);
stbuf->st_nlink = 1;
// FIXME: remove openvz stuff for 7.x
if (name_is_openvz_script(te->name, NULL)) {
stbuf->st_mode |= S_IXUSR;
}
}
stbuf->st_size = te->size;
stbuf->st_blocks =
(stbuf->st_size + MEMDB_BLOCKSIZE -1)/MEMDB_BLOCKSIZE;
stbuf->st_atime = te->mtime;
stbuf->st_mtime = te->mtime;
stbuf->st_ctime = te->mtime;
if (te->type == DT_DIR) {
stbuf->st_mode = S_IFDIR | (quorate ? 0777 : 0555);
stbuf->st_nlink = 2;
} else {
stbuf->st_mode = S_IFREG | (quorate ? 0666 : 0444);
stbuf->st_nlink = 1;
// FIXME: remove openvz stuff for 7.x
if (name_is_openvz_script(te->name, NULL)) {
stbuf->st_mode |= S_IXUSR;
}
}
stbuf->st_size = te->size;
stbuf->st_blocks = (stbuf->st_size + MEMDB_BLOCKSIZE - 1) / MEMDB_BLOCKSIZE;
stbuf->st_atime = te->mtime;
stbuf->st_mtime = te->mtime;
stbuf->st_ctime = te->mtime;
}
static int cfs_plug_memdb_getattr(cfs_plug_t *plug, const char *path, struct stat *stbuf)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(stbuf != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_memdb_getattr(cfs_plug_t *plug, const char *path, struct stat *stbuf) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(stbuf != NULL, PARAM_CHECK_ERRNO);
memset(stbuf, 0, sizeof(struct stat));
memset(stbuf, 0, sizeof(struct stat));
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
memdb_tree_entry_t *te = memdb_getattr(mdb->memdb, path);
memdb_tree_entry_t *te = memdb_getattr(mdb->memdb, path);
if (te) {
tree_entry_stat(te, stbuf, cfs_is_quorate());
memdb_tree_entry_free(te);
return 0;
}
if (te) {
tree_entry_stat(te, stbuf, cfs_is_quorate());
memdb_tree_entry_free(te);
return 0;
}
return -ENOENT;
return -ENOENT;
}
static int cfs_plug_memdb_readdir(
cfs_plug_t *plug,
const char *path,
void *buf,
fuse_fill_dir_t filler,
off_t offset,
struct fuse_file_info *fi)
{
(void) offset;
(void) fi;
cfs_plug_t *plug,
const char *path,
void *buf,
fuse_fill_dir_t filler,
off_t offset,
struct fuse_file_info *fi
) {
(void)offset;
(void)fi;
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(filler != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(filler != NULL, PARAM_CHECK_ERRNO);
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
GList *dirlist = memdb_readdir(mdb->memdb, path);
GList *dirlist = memdb_readdir(mdb->memdb, path);
if (dirlist) {
if (dirlist) {
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
struct stat stbuf;
memset(&stbuf, 0, sizeof(struct stat));
GList *l = dirlist;
while (l) {
memdb_tree_entry_t *te = (memdb_tree_entry_t *)l->data;
struct stat stbuf;
memset(&stbuf, 0, sizeof(struct stat));
tree_entry_stat(te, &stbuf, 0);
filler(buf, te->name, &stbuf, 0);
l = g_list_next(l);
}
GList *l = dirlist;
while (l) {
memdb_tree_entry_t *te = (memdb_tree_entry_t *)l->data;
memdb_dirlist_free(dirlist);
}
tree_entry_stat(te, &stbuf, 0);
filler(buf, te->name, &stbuf, 0);
l = g_list_next(l);
}
return 0;
memdb_dirlist_free(dirlist);
}
return 0;
}
static int cfs_plug_memdb_open(cfs_plug_t *plug, const char *path, struct fuse_file_info *fi)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(fi != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_memdb_open(cfs_plug_t *plug, const char *path, struct fuse_file_info *fi) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(fi != NULL, PARAM_CHECK_ERRNO);
memdb_tree_entry_t *te;
memdb_tree_entry_t *te;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
if ((te = memdb_getattr(mdb->memdb, path))) {
memdb_tree_entry_free(te);
} else
return -ENOENT;
if ((te = memdb_getattr(mdb->memdb, path))) {
memdb_tree_entry_free(te);
} else
return -ENOENT;
return 0;
return 0;
}
static int cfs_plug_memdb_read(
cfs_plug_t *plug,
const char *path,
char *buf,
size_t size,
off_t offset,
struct fuse_file_info *fi)
{
(void) fi;
cfs_plug_t *plug,
const char *path,
char *buf,
size_t size,
off_t offset,
struct fuse_file_info *fi
) {
(void)fi;
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
int len;
gpointer data = NULL;
int len;
gpointer data = NULL;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
len = memdb_read(mdb->memdb, path, &data);
if (len < 0)
return len;
len = memdb_read(mdb->memdb, path, &data);
if (len < 0)
return len;
if (offset < len) {
if (offset + size > len)
size = len - offset;
memcpy(buf, (uint8_t *) data + offset, size);
} else {
size = 0;
}
if (offset < len) {
if (offset + size > len)
size = len - offset;
memcpy(buf, (uint8_t *)data + offset, size);
} else {
size = 0;
}
if (data)
g_free(data);
if (data)
g_free(data);
return size;
return size;
}
static int cfs_plug_memdb_write(
cfs_plug_t *plug,
const char *path,
const char *buf,
size_t size,
off_t offset,
struct fuse_file_info *fi)
{
(void) fi;
cfs_plug_t *plug,
const char *path,
const char *buf,
size_t size,
off_t offset,
struct fuse_file_info *fi
) {
(void)fi;
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
int res;
int res;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
if (mdb->dfsm) {
res = dcdb_send_fuse_message(mdb->dfsm, DCDB_MESSAGE_CFS_WRITE, path, NULL, buf,
size, offset, 0);
} else {
uint32_t ctime = time(NULL);
res = memdb_write(mdb->memdb, path, 0, ctime, buf, size, offset, 0);
}
if (mdb->dfsm) {
res = dcdb_send_fuse_message(
mdb->dfsm, DCDB_MESSAGE_CFS_WRITE, path, NULL, buf, size, offset, 0
);
} else {
uint32_t ctime = time(NULL);
res = memdb_write(mdb->memdb, path, 0, ctime, buf, size, offset, 0);
}
return res;
return res;
}
static int cfs_plug_memdb_truncate(cfs_plug_t *plug, const char *path, off_t size)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_memdb_truncate(cfs_plug_t *plug, const char *path, off_t size) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
int res;
int res;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
if (mdb->dfsm) {
res = dcdb_send_fuse_message(mdb->dfsm, DCDB_MESSAGE_CFS_WRITE, path, NULL, NULL,
0, size, 1);
} else {
uint32_t ctime = time(NULL);
res = memdb_write(mdb->memdb, path, 0, ctime, NULL, 0, size, 1);
}
if (mdb->dfsm) {
res =
dcdb_send_fuse_message(mdb->dfsm, DCDB_MESSAGE_CFS_WRITE, path, NULL, NULL, 0, size, 1);
} else {
uint32_t ctime = time(NULL);
res = memdb_write(mdb->memdb, path, 0, ctime, NULL, 0, size, 1);
}
return res;
return res;
}
static int cfs_plug_memdb_create (
cfs_plug_t *plug,
const char *path,
mode_t mode,
struct fuse_file_info *fi)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(fi != NULL, PARAM_CHECK_ERRNO);
static int
cfs_plug_memdb_create(cfs_plug_t *plug, const char *path, mode_t mode, struct fuse_file_info *fi) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(fi != NULL, PARAM_CHECK_ERRNO);
int res;
int res;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
if (mdb->dfsm) {
res = dcdb_send_fuse_message(mdb->dfsm, DCDB_MESSAGE_CFS_CREATE, path,
NULL, NULL, 0, 0, 0);
} else {
uint32_t ctime = time(NULL);
if (mdb->dfsm) {
res = dcdb_send_fuse_message(mdb->dfsm, DCDB_MESSAGE_CFS_CREATE, path, NULL, NULL, 0, 0, 0);
} else {
uint32_t ctime = time(NULL);
res = memdb_create(mdb->memdb, path, 0, ctime);
}
res = memdb_create(mdb->memdb, path, 0, ctime);
}
return res;
return res;
}
static int cfs_plug_memdb_mkdir(cfs_plug_t *plug, const char *path, mode_t mode)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_memdb_mkdir(cfs_plug_t *plug, const char *path, mode_t mode) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
int res;
int res;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
if (mdb->dfsm) {
res = dcdb_send_fuse_message(mdb->dfsm, DCDB_MESSAGE_CFS_MKDIR, path,
NULL, NULL, 0, 0, 0);
} else {
uint32_t ctime = time(NULL);
res = memdb_mkdir(mdb->memdb, path, 0, ctime);
}
if (mdb->dfsm) {
res = dcdb_send_fuse_message(mdb->dfsm, DCDB_MESSAGE_CFS_MKDIR, path, NULL, NULL, 0, 0, 0);
} else {
uint32_t ctime = time(NULL);
res = memdb_mkdir(mdb->memdb, path, 0, ctime);
}
return res;
return res;
}
static int cfs_plug_memdb_rmdir(cfs_plug_t *plug, const char *path)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_memdb_rmdir(cfs_plug_t *plug, const char *path) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
int res;
int res;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
if (mdb->dfsm) {
res = dcdb_send_fuse_message(mdb->dfsm, DCDB_MESSAGE_CFS_DELETE, path,
NULL, NULL, 0, 0, 0);
} else {
uint32_t ctime = time(NULL);
res = memdb_delete(mdb->memdb, path, 0, ctime);
}
if (mdb->dfsm) {
res = dcdb_send_fuse_message(mdb->dfsm, DCDB_MESSAGE_CFS_DELETE, path, NULL, NULL, 0, 0, 0);
} else {
uint32_t ctime = time(NULL);
res = memdb_delete(mdb->memdb, path, 0, ctime);
}
return res;
return res;
}
static int cfs_plug_memdb_rename(cfs_plug_t *plug, const char *from, const char *to)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(from != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(to != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_memdb_rename(cfs_plug_t *plug, const char *from, const char *to) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(from != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(to != NULL, PARAM_CHECK_ERRNO);
int res;
int res;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
if (mdb->dfsm) {
res = dcdb_send_fuse_message(mdb->dfsm, DCDB_MESSAGE_CFS_RENAME, from, to,
NULL, 0, 0, 0);
} else {
uint32_t ctime = time(NULL);
res = memdb_rename(mdb->memdb, from, to, 0, ctime);
}
if (mdb->dfsm) {
res = dcdb_send_fuse_message(mdb->dfsm, DCDB_MESSAGE_CFS_RENAME, from, to, NULL, 0, 0, 0);
} else {
uint32_t ctime = time(NULL);
res = memdb_rename(mdb->memdb, from, to, 0, ctime);
}
return res;
return res;
}
static int cfs_plug_memdb_unlink(cfs_plug_t *plug, const char *path)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_memdb_unlink(cfs_plug_t *plug, const char *path) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
int res;
int res;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
if (mdb->dfsm) {
res = dcdb_send_fuse_message(mdb->dfsm, DCDB_MESSAGE_CFS_DELETE, path,
NULL, NULL, 0, 0, 0);
} else {
uint32_t ctime = time(NULL);
res = memdb_delete(mdb->memdb, path, 0, ctime);
}
if (mdb->dfsm) {
res = dcdb_send_fuse_message(mdb->dfsm, DCDB_MESSAGE_CFS_DELETE, path, NULL, NULL, 0, 0, 0);
} else {
uint32_t ctime = time(NULL);
res = memdb_delete(mdb->memdb, path, 0, ctime);
}
return res;
return res;
}
static int cfs_plug_memdb_utimens(
cfs_plug_t *plug,
const char *path,
const struct timespec tv[2])
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(tv != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_memdb_utimens(cfs_plug_t *plug, const char *path, const struct timespec tv[2]) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(tv != NULL, PARAM_CHECK_ERRNO);
int res;
int res;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
res = -EIO;
res = -EIO;
memdb_tree_entry_t *te = memdb_getattr(mdb->memdb, path);
uint32_t mtime = tv[1].tv_sec;
memdb_tree_entry_t *te = memdb_getattr(mdb->memdb, path);
uint32_t mtime = tv[1].tv_sec;
gboolean unlock_req = FALSE;
guchar csum[32];
gboolean unlock_req = FALSE;
guchar csum[32];
if (te && mtime == 0 && te->type == DT_DIR &&
path_is_lockdir(path)) {
unlock_req = TRUE;
}
if (te && mtime == 0 && te->type == DT_DIR && path_is_lockdir(path)) {
unlock_req = TRUE;
}
if (mdb->dfsm) {
if (unlock_req && memdb_tree_entry_csum(te, csum))
dcdb_send_unlock(mdb->dfsm, path, csum, TRUE);
res = dcdb_send_fuse_message(mdb->dfsm, DCDB_MESSAGE_CFS_MTIME, path,
NULL, NULL, 0, mtime, 0);
} else {
uint32_t ctime = time(NULL);
if (unlock_req && memdb_tree_entry_csum(te, csum) &&
memdb_lock_expired(mdb->memdb, path, csum)) {
res = memdb_delete(mdb->memdb, path, 0, ctime);
} else {
res = memdb_mtime(mdb->memdb, path, 0, mtime);
}
}
if (mdb->dfsm) {
if (unlock_req && memdb_tree_entry_csum(te, csum))
dcdb_send_unlock(mdb->dfsm, path, csum, TRUE);
memdb_tree_entry_free(te);
res = dcdb_send_fuse_message(
mdb->dfsm, DCDB_MESSAGE_CFS_MTIME, path, NULL, NULL, 0, mtime, 0
);
} else {
uint32_t ctime = time(NULL);
if (unlock_req && memdb_tree_entry_csum(te, csum) &&
memdb_lock_expired(mdb->memdb, path, csum)) {
res = memdb_delete(mdb->memdb, path, 0, ctime);
} else {
res = memdb_mtime(mdb->memdb, path, 0, mtime);
}
}
return res;
memdb_tree_entry_free(te);
return res;
}
static int cfs_plug_memdb_statfs(cfs_plug_t *plug, const char *path, struct statvfs *stbuf)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(stbuf != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_memdb_statfs(cfs_plug_t *plug, const char *path, struct statvfs *stbuf) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(stbuf != NULL, PARAM_CHECK_ERRNO);
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
cfs_plug_memdb_t *mdb = (cfs_plug_memdb_t *)plug;
return memdb_statfs(mdb->memdb, stbuf);
return memdb_statfs(mdb->memdb, stbuf);
}
static void cfs_plug_memdb_destroy(cfs_plug_t *plug)
{
g_return_if_fail(plug != NULL);
g_return_if_fail(plug->ops == &cfs_ops);
g_free(plug->name);
static void cfs_plug_memdb_destroy(cfs_plug_t *plug) {
g_return_if_fail(plug != NULL);
g_return_if_fail(plug->ops == &cfs_ops);
g_free(plug);
g_free(plug->name);
g_free(plug);
}
static cfs_plug_t *cfs_plug_memdb_lookup_plug(cfs_plug_t *plug, char **path)
{
g_return_val_if_fail(plug != NULL, NULL);
g_return_val_if_fail(plug->ops == &cfs_ops, NULL);
static cfs_plug_t *cfs_plug_memdb_lookup_plug(cfs_plug_t *plug, char **path) {
g_return_val_if_fail(plug != NULL, NULL);
g_return_val_if_fail(plug->ops == &cfs_ops, NULL);
return plug;
return plug;
}
static struct cfs_operations cfs_ops = {
.getattr = cfs_plug_memdb_getattr,
.readdir = cfs_plug_memdb_readdir,
.open = cfs_plug_memdb_open,
.create = cfs_plug_memdb_create,
.read = cfs_plug_memdb_read,
.write = cfs_plug_memdb_write,
.truncate = cfs_plug_memdb_truncate,
.unlink = cfs_plug_memdb_unlink,
.mkdir = cfs_plug_memdb_mkdir,
.rmdir = cfs_plug_memdb_rmdir,
.rename = cfs_plug_memdb_rename,
.utimens = cfs_plug_memdb_utimens,
.statfs = cfs_plug_memdb_statfs,
.getattr = cfs_plug_memdb_getattr,
.readdir = cfs_plug_memdb_readdir,
.open = cfs_plug_memdb_open,
.create = cfs_plug_memdb_create,
.read = cfs_plug_memdb_read,
.write = cfs_plug_memdb_write,
.truncate = cfs_plug_memdb_truncate,
.unlink = cfs_plug_memdb_unlink,
.mkdir = cfs_plug_memdb_mkdir,
.rmdir = cfs_plug_memdb_rmdir,
.rename = cfs_plug_memdb_rename,
.utimens = cfs_plug_memdb_utimens,
.statfs = cfs_plug_memdb_statfs,
#ifdef HAS_CFS_PLUG_MEMDB_LOCK
.lock = cfs_plug_memdb_lock,
.lock = cfs_plug_memdb_lock,
#endif
};
cfs_plug_memdb_t *cfs_plug_memdb_new(
const char *name,
memdb_t *memdb,
dfsm_t *dfsm)
{
g_return_val_if_fail(name != NULL, NULL);
g_return_val_if_fail(memdb != NULL, NULL);
cfs_plug_memdb_t *cfs_plug_memdb_new(const char *name, memdb_t *memdb, dfsm_t *dfsm) {
g_return_val_if_fail(name != NULL, NULL);
g_return_val_if_fail(memdb != NULL, NULL);
cfs_plug_memdb_t *mdb = g_new0(cfs_plug_memdb_t, 1);
cfs_plug_memdb_t *mdb = g_new0(cfs_plug_memdb_t, 1);
g_return_val_if_fail(mdb != NULL, NULL);
g_return_val_if_fail(mdb != NULL, NULL);
mdb->plug.ops = &cfs_ops;
mdb->plug.ops = &cfs_ops;
mdb->plug.lookup_plug = cfs_plug_memdb_lookup_plug;
mdb->plug.lookup_plug = cfs_plug_memdb_lookup_plug;
mdb->plug.destroy_plug = cfs_plug_memdb_destroy;
mdb->plug.destroy_plug = cfs_plug_memdb_destroy;
mdb->plug.name = g_strdup(name);
mdb->plug.name = g_strdup(name);
mdb->memdb = memdb;
mdb->memdb = memdb;
mdb->dfsm = dfsm;
mdb->dfsm = dfsm;
return mdb;
return mdb;
}

View file

@ -21,23 +21,19 @@
#ifndef _PVE_CFS_PLUG_MEMDB_H_
#define _PVE_CFS_PLUG_MEMDB_H_
#include <unistd.h>
#include <fcntl.h>
#include "cfs-plug.h"
#include <fcntl.h>
#include <unistd.h>
#include "dfsm.h"
#include "memdb.h"
typedef struct {
cfs_plug_t plug;
memdb_t *memdb;
dfsm_t *dfsm;
cfs_plug_t plug;
memdb_t *memdb;
dfsm_t *dfsm;
} cfs_plug_memdb_t;
cfs_plug_memdb_t *cfs_plug_memdb_new(
const char *name,
memdb_t *memdb,
dfsm_t *dfsm);
cfs_plug_memdb_t *cfs_plug_memdb_new(const char *name, memdb_t *memdb, dfsm_t *dfsm);
#endif /* _PVE_CFS_PLUG_MEMDB_H_ */

View file

@ -22,532 +22,515 @@
#include <config.h>
#endif /* HAVE_CONFIG_H */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <glib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "cfs-utils.h"
#include "cfs-plug.h"
#include "cfs-utils.h"
static struct cfs_operations cfs_ops;
static cfs_plug_t *cfs_plug_base_lookup_plug(cfs_plug_t *plug, char **path)
{
g_return_val_if_fail(plug != NULL, NULL);
g_return_val_if_fail(plug->ops == &cfs_ops, NULL);
g_return_val_if_fail(path != NULL, NULL);
static cfs_plug_t *cfs_plug_base_lookup_plug(cfs_plug_t *plug, char **path) {
g_return_val_if_fail(plug != NULL, NULL);
g_return_val_if_fail(plug->ops == &cfs_ops, NULL);
g_return_val_if_fail(path != NULL, NULL);
cfs_plug_base_t *bplug = (cfs_plug_base_t *)plug;
cfs_plug_base_t *bplug = (cfs_plug_base_t *)plug;
g_return_val_if_fail(bplug->entries != NULL, NULL);
g_return_val_if_fail(bplug->entries != NULL, NULL);
cfs_debug("cfs_plug_base_lookup_plug %s", *path);
cfs_debug("cfs_plug_base_lookup_plug %s", *path);
if (!*path || !(*path)[0])
return plug;
if (!*path || !(*path)[0])
return plug;
char *name = strsep(path, "/");
char *name = strsep(path, "/");
cfs_debug("cfs_plug_base_lookup_plug name = %s new path = %s", name, *path);
cfs_debug("cfs_plug_base_lookup_plug name = %s new path = %s", name, *path);
cfs_plug_t *sub;
cfs_plug_t *sub;
if (!(sub = (cfs_plug_t *)g_hash_table_lookup(bplug->entries, name))) {
/* revert strsep modification */
if (*path) (*path)[-1] = '/';
*path = name;
return plug;
}
if (!(sub = (cfs_plug_t *)g_hash_table_lookup(bplug->entries, name))) {
/* revert strsep modification */
if (*path)
(*path)[-1] = '/';
*path = name;
return plug;
}
if ((sub = sub->lookup_plug(sub, path)))
return sub;
if ((sub = sub->lookup_plug(sub, path)))
return sub;
*path = NULL;
return NULL;
*path = NULL;
return NULL;
}
static int cfs_plug_base_getattr(cfs_plug_t *plug, const char *path, struct stat *stbuf)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(stbuf != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_base_getattr(cfs_plug_t *plug, const char *path, struct stat *stbuf) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(stbuf != NULL, PARAM_CHECK_ERRNO);
cfs_debug("enter cfs_plug_base_getattr %s", path);
cfs_debug("enter cfs_plug_base_getattr %s", path);
int ret = -EACCES;
int ret = -EACCES;
memset(stbuf, 0, sizeof(struct stat));
memset(stbuf, 0, sizeof(struct stat));
if (*path) {
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
if (*path) {
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
if (base && base->ops && base->ops->getattr)
ret = base->ops->getattr(base, path, stbuf);
goto ret;
}
if (base && base->ops && base->ops->getattr)
ret = base->ops->getattr(base, path, stbuf);
goto ret;
}
stbuf->st_mode = S_IFDIR | 0777;
stbuf->st_nlink = 2;
ret = 0;
stbuf->st_mode = S_IFDIR | 0777;
stbuf->st_nlink = 2;
ret = 0;
ret:
cfs_debug("leave cfs_plug_base_getattr %s", path);
return ret;
cfs_debug("leave cfs_plug_base_getattr %s", path);
return ret;
}
struct hash_filler {
void *buf;
GHashTable *entries;
fuse_fill_dir_t filler;
void *buf;
GHashTable *entries;
fuse_fill_dir_t filler;
};
static int tmp_hash_filler (
void *buf,
const char *name,
const struct stat *stbuf,
off_t off) {
static int tmp_hash_filler(void *buf, const char *name, const struct stat *stbuf, off_t off) {
struct hash_filler *hf = (struct hash_filler *)buf;
struct hash_filler *hf = (struct hash_filler *)buf;
if (hf->entries && g_hash_table_lookup(hf->entries, name))
return 0;
if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
return 0;
if (hf->entries && g_hash_table_lookup(hf->entries, name))
return 0;
hf->filler(hf->buf, name, stbuf, off);
if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
return 0;
return 0;
hf->filler(hf->buf, name, stbuf, off);
return 0;
}
static int cfs_plug_base_readdir(cfs_plug_t *plug, const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi)
{
(void) offset;
(void) fi;
static int cfs_plug_base_readdir(
cfs_plug_t *plug,
const char *path,
void *buf,
fuse_fill_dir_t filler,
off_t offset,
struct fuse_file_info *fi
) {
(void)offset;
(void)fi;
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(filler != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(filler != NULL, PARAM_CHECK_ERRNO);
cfs_plug_base_t *bplug = (cfs_plug_base_t *)plug;
cfs_plug_base_t *bplug = (cfs_plug_base_t *)plug;
cfs_debug("enter cfs_plug_base_readdir %s", path);
cfs_debug("enter cfs_plug_base_readdir %s", path);
int ret = -EACCES;
int ret = -EACCES;
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
if (!path[0]) {
GHashTableIter iter;
gpointer key, value;
if (!path[0]) {
GHashTableIter iter;
gpointer key, value;
g_hash_table_iter_init (&iter, bplug->entries);
g_hash_table_iter_init(&iter, bplug->entries);
while (g_hash_table_iter_next (&iter, &key, &value)) {
filler(buf, key, NULL, 0);
}
}
while (g_hash_table_iter_next(&iter, &key, &value)) {
filler(buf, key, NULL, 0);
}
}
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
if (base && base->ops && base->ops->readdir) {
struct hash_filler hf = {
.buf = buf,
.filler = filler,
.entries = NULL
};
if (base && base->ops && base->ops->readdir) {
struct hash_filler hf = {.buf = buf, .filler = filler, .entries = NULL};
if (!path[0])
hf.entries = bplug->entries;
if (!path[0])
hf.entries = bplug->entries;
ret = base->ops->readdir(base, path, &hf, tmp_hash_filler, 0, fi);
ret = base->ops->readdir(base, path, &hf, tmp_hash_filler, 0, fi);
} else {
ret = 0;
}
return ret;
} else {
ret = 0;
}
return ret;
}
static int cfs_plug_base_mkdir(cfs_plug_t *plug, const char *path, mode_t mode)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_base_mkdir(cfs_plug_t *plug, const char *path, mode_t mode) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
cfs_debug("enter cfs_plug_base_mkdir %s", path);
cfs_debug("enter cfs_plug_base_mkdir %s", path);
int ret = -EACCES;
int ret = -EACCES;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
if (*path && base && base->ops && base->ops->mkdir)
ret = base->ops->mkdir(base, path, mode);
if (*path && base && base->ops && base->ops->mkdir)
ret = base->ops->mkdir(base, path, mode);
return ret;
return ret;
}
static int cfs_plug_base_rmdir(cfs_plug_t *plug, const char *path)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_base_rmdir(cfs_plug_t *plug, const char *path) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
cfs_debug("enter cfs_plug_base_rmdir %s", path);
cfs_debug("enter cfs_plug_base_rmdir %s", path);
int ret = -EACCES;
int ret = -EACCES;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
if (*path && base && base->ops && base->ops->rmdir)
ret = base->ops->rmdir(base, path);
if (*path && base && base->ops && base->ops->rmdir)
ret = base->ops->rmdir(base, path);
return ret;
return ret;
}
static int cfs_plug_base_rename(cfs_plug_t *plug, const char *from, const char *to)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(from != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(to != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_base_rename(cfs_plug_t *plug, const char *from, const char *to) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(from != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(to != NULL, PARAM_CHECK_ERRNO);
cfs_debug("enter cfs_plug_base_rename from %s to %s", from, to);
cfs_debug("enter cfs_plug_base_rename from %s to %s", from, to);
int ret = -EACCES;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
int ret = -EACCES;
if (base && base->ops && base->ops->rename)
ret = base->ops->rename(base, from, to);
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
return ret;
if (base && base->ops && base->ops->rename)
ret = base->ops->rename(base, from, to);
return ret;
}
static int cfs_plug_base_open(cfs_plug_t *plug, const char *path, struct fuse_file_info *fi)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(fi != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_base_open(cfs_plug_t *plug, const char *path, struct fuse_file_info *fi) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(fi != NULL, PARAM_CHECK_ERRNO);
cfs_debug("enter cfs_plug_base_open %s", path);
cfs_debug("enter cfs_plug_base_open %s", path);
int ret = -EACCES;
int ret = -EACCES;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
if (base && base->ops && base->ops->open)
ret = base->ops->open(base, path, fi);
if (base && base->ops && base->ops->open)
ret = base->ops->open(base, path, fi);
return ret;
return ret;
}
static int cfs_plug_base_read(cfs_plug_t *plug, const char *path, char *buf,
size_t size, off_t offset, struct fuse_file_info *fi)
{
(void) fi;
static int cfs_plug_base_read(
cfs_plug_t *plug,
const char *path,
char *buf,
size_t size,
off_t offset,
struct fuse_file_info *fi
) {
(void)fi;
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(fi != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(fi != NULL, PARAM_CHECK_ERRNO);
cfs_debug("enter cfs_plug_base_read %s %zu %jd", path, size, offset);
cfs_debug("enter cfs_plug_base_read %s %zu %jd", path, size, offset);
int ret = -EACCES;
int ret = -EACCES;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
if (base && base->ops && base->ops->read)
ret = base->ops->read(base, path, buf, size, offset, fi);
if (base && base->ops && base->ops->read)
ret = base->ops->read(base, path, buf, size, offset, fi);
return ret;
return ret;
}
static int cfs_plug_base_write(cfs_plug_t *plug, const char *path, const char *buf,
size_t size, off_t offset, struct fuse_file_info *fi)
{
(void) fi;
static int cfs_plug_base_write(
cfs_plug_t *plug,
const char *path,
const char *buf,
size_t size,
off_t offset,
struct fuse_file_info *fi
) {
(void)fi;
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(fi != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(fi != NULL, PARAM_CHECK_ERRNO);
cfs_debug("enter cfs_plug_base_write %s %zu %jd", path, size, offset);
cfs_debug("enter cfs_plug_base_write %s %zu %jd", path, size, offset);
int ret = -EACCES;
int ret = -EACCES;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
if (base && base->ops && base->ops->write)
ret = base->ops->write(base, path, buf, size, offset, fi);
if (base && base->ops && base->ops->write)
ret = base->ops->write(base, path, buf, size, offset, fi);
return ret;
return ret;
}
static int cfs_plug_base_truncate(cfs_plug_t *plug, const char *path, off_t size)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_base_truncate(cfs_plug_t *plug, const char *path, off_t size) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
cfs_debug("enter cfs_plug_base_truncate %s %jd", path, size);
cfs_debug("enter cfs_plug_base_truncate %s %jd", path, size);
int ret = -EACCES;
int ret = -EACCES;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
if (base && base->ops && base->ops->truncate)
ret = base->ops->truncate(base, path, size);
if (base && base->ops && base->ops->truncate)
ret = base->ops->truncate(base, path, size);
return ret;
return ret;
}
static int cfs_plug_base_create(cfs_plug_t *plug, const char *path, mode_t mode,
struct fuse_file_info *fi)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(fi != NULL, PARAM_CHECK_ERRNO);
static int
cfs_plug_base_create(cfs_plug_t *plug, const char *path, mode_t mode, struct fuse_file_info *fi) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(fi != NULL, PARAM_CHECK_ERRNO);
cfs_debug("enter cfs_plug_base_create %s", path);
cfs_debug("enter cfs_plug_base_create %s", path);
int ret = -EACCES;
int ret = -EACCES;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
if (base && base->ops && base->ops->create)
ret = base->ops->create(base, path, mode, fi);
if (base && base->ops && base->ops->create)
ret = base->ops->create(base, path, mode, fi);
return ret;
return ret;
}
static int cfs_plug_base_unlink(cfs_plug_t *plug, const char *path)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_base_unlink(cfs_plug_t *plug, const char *path) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
cfs_debug("enter cfs_plug_base_unlink %s", path);
cfs_debug("enter cfs_plug_base_unlink %s", path);
int ret = -EACCES;
int ret = -EACCES;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
if (base && base->ops && base->ops->unlink)
ret = base->ops->unlink(base, path);
if (base && base->ops && base->ops->unlink)
ret = base->ops->unlink(base, path);
return ret;
return ret;
}
static int cfs_plug_base_readlink(cfs_plug_t *plug, const char *path, char *buf, size_t max)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_base_readlink(cfs_plug_t *plug, const char *path, char *buf, size_t max) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(buf != NULL, PARAM_CHECK_ERRNO);
cfs_debug("enter cfs_plug_base_readlink %s", path);
cfs_debug("enter cfs_plug_base_readlink %s", path);
int ret = -EACCES;
int ret = -EACCES;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
if (base && base->ops && base->ops->readlink)
ret = base->ops->readlink(base, path, buf, max);
if (base && base->ops && base->ops->readlink)
ret = base->ops->readlink(base, path, buf, max);
return ret;
return ret;
}
static int cfs_plug_base_utimens(cfs_plug_t *plug, const char *path, const struct timespec tv[2])
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(tv != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_base_utimens(cfs_plug_t *plug, const char *path, const struct timespec tv[2]) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(tv != NULL, PARAM_CHECK_ERRNO);
cfs_debug("enter cfs_plug_utimes %s", path);
cfs_debug("enter cfs_plug_utimes %s", path);
int ret = -EACCES;
int ret = -EACCES;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
if (base && base->ops && base->ops->utimens)
ret = base->ops->utimens(base, path, tv);
if (base && base->ops && base->ops->utimens)
ret = base->ops->utimens(base, path, tv);
return ret;
return ret;
}
static int cfs_plug_base_statfs(cfs_plug_t *plug, const char *path, struct statvfs *stbuf)
{
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(stbuf != NULL, PARAM_CHECK_ERRNO);
static int cfs_plug_base_statfs(cfs_plug_t *plug, const char *path, struct statvfs *stbuf) {
g_return_val_if_fail(plug != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(plug->ops == &cfs_ops, PARAM_CHECK_ERRNO);
g_return_val_if_fail(path != NULL, PARAM_CHECK_ERRNO);
g_return_val_if_fail(stbuf != NULL, PARAM_CHECK_ERRNO);
cfs_debug("enter cfs_plug_base_statfs %s", path);
cfs_debug("enter cfs_plug_base_statfs %s", path);
int ret = -EACCES;
int ret = -EACCES;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
cfs_plug_t *base = ((cfs_plug_base_t *)plug)->base;
if (base && base->ops && base->ops->statfs)
ret = base->ops->statfs(base, path, stbuf);
if (base && base->ops && base->ops->statfs)
ret = base->ops->statfs(base, path, stbuf);
return ret;
return ret;
}
static gboolean plug_remove_func(
gpointer key,
gpointer value,
gpointer user_data)
{
cfs_plug_t *plug = (cfs_plug_t *)value;
static gboolean plug_remove_func(gpointer key, gpointer value, gpointer user_data) {
cfs_plug_t *plug = (cfs_plug_t *)value;
if (plug && plug->destroy_plug)
plug->destroy_plug(plug);
if (plug && plug->destroy_plug)
plug->destroy_plug(plug);
return TRUE;
return TRUE;
}
static void cfs_plug_base_destroy(cfs_plug_t *plug)
{
g_return_if_fail(plug != NULL);
g_return_if_fail(plug->ops == &cfs_ops);
static void cfs_plug_base_destroy(cfs_plug_t *plug) {
g_return_if_fail(plug != NULL);
g_return_if_fail(plug->ops == &cfs_ops);
cfs_plug_base_t *bplug = (cfs_plug_base_t *)plug;
cfs_plug_base_t *bplug = (cfs_plug_base_t *)plug;
cfs_debug("enter cfs_plug_base_destroy %s", plug->name);
cfs_debug("enter cfs_plug_base_destroy %s", plug->name);
if (bplug->entries) {
g_hash_table_foreach_remove(bplug->entries, plug_remove_func, NULL);
g_hash_table_destroy(bplug->entries);
}
if (bplug->entries) {
g_hash_table_foreach_remove(bplug->entries, plug_remove_func, NULL);
g_hash_table_destroy(bplug->entries);
}
if (bplug->base && bplug->base->destroy_plug) {
bplug->base->destroy_plug(bplug->base);
}
if (bplug->base && bplug->base->destroy_plug) {
bplug->base->destroy_plug(bplug->base);
}
g_free(plug->name);
g_free(plug->name);
g_free(plug);
g_free(plug);
}
static void cfs_plug_base_start_workers(cfs_plug_t *plug)
{
g_return_if_fail(plug != NULL);
g_return_if_fail(plug->ops == &cfs_ops);
static void cfs_plug_base_start_workers(cfs_plug_t *plug) {
g_return_if_fail(plug != NULL);
g_return_if_fail(plug->ops == &cfs_ops);
cfs_plug_base_t *bplug = (cfs_plug_base_t *)plug;
GHashTableIter iter;
gpointer key, value;
cfs_plug_base_t *bplug = (cfs_plug_base_t *)plug;
GHashTableIter iter;
gpointer key, value;
g_hash_table_iter_init (&iter, bplug->entries);
g_hash_table_iter_init(&iter, bplug->entries);
while (g_hash_table_iter_next (&iter, &key, &value)) {
while (g_hash_table_iter_next(&iter, &key, &value)) {
cfs_plug_t *p = (cfs_plug_t *)value;
if (p->start_workers)
p->start_workers(p);
cfs_plug_t *p = (cfs_plug_t *)value;
}
if (bplug->base && bplug->base->start_workers) {
bplug->base->start_workers(bplug->base);
}
if (p->start_workers)
p->start_workers(p);
}
if (bplug->base && bplug->base->start_workers) {
bplug->base->start_workers(bplug->base);
}
}
static void cfs_plug_base_stop_workers(cfs_plug_t *plug)
{
g_return_if_fail(plug != NULL);
g_return_if_fail(plug->ops == &cfs_ops);
static void cfs_plug_base_stop_workers(cfs_plug_t *plug) {
g_return_if_fail(plug != NULL);
g_return_if_fail(plug->ops == &cfs_ops);
cfs_plug_base_t *bplug = (cfs_plug_base_t *)plug;
GHashTableIter iter;
gpointer key, value;
cfs_plug_base_t *bplug = (cfs_plug_base_t *)plug;
GHashTableIter iter;
gpointer key, value;
g_hash_table_iter_init (&iter, bplug->entries);
g_hash_table_iter_init(&iter, bplug->entries);
if (bplug->base && bplug->base->stop_workers) {
bplug->base->stop_workers(bplug->base);
}
if (bplug->base && bplug->base->stop_workers) {
bplug->base->stop_workers(bplug->base);
}
while (g_hash_table_iter_next (&iter, &key, &value)) {
while (g_hash_table_iter_next(&iter, &key, &value)) {
cfs_plug_t *p = (cfs_plug_t *)value;
if (p->stop_workers)
p->stop_workers(p);
cfs_plug_t *p = (cfs_plug_t *)value;
}
if (p->stop_workers)
p->stop_workers(p);
}
}
static struct cfs_operations cfs_ops = {
.getattr = cfs_plug_base_getattr,
.create = cfs_plug_base_create,
.open = cfs_plug_base_open,
.read = cfs_plug_base_read,
.write = cfs_plug_base_write,
.truncate = cfs_plug_base_truncate,
.unlink = cfs_plug_base_unlink,
.readdir = cfs_plug_base_readdir,
.mkdir = cfs_plug_base_mkdir,
.rmdir = cfs_plug_base_rmdir,
.rename = cfs_plug_base_rename,
.readlink = cfs_plug_base_readlink,
.utimens = cfs_plug_base_utimens,
.statfs = cfs_plug_base_statfs,
.getattr = cfs_plug_base_getattr,
.create = cfs_plug_base_create,
.open = cfs_plug_base_open,
.read = cfs_plug_base_read,
.write = cfs_plug_base_write,
.truncate = cfs_plug_base_truncate,
.unlink = cfs_plug_base_unlink,
.readdir = cfs_plug_base_readdir,
.mkdir = cfs_plug_base_mkdir,
.rmdir = cfs_plug_base_rmdir,
.rename = cfs_plug_base_rename,
.readlink = cfs_plug_base_readlink,
.utimens = cfs_plug_base_utimens,
.statfs = cfs_plug_base_statfs,
};
cfs_plug_base_t *cfs_plug_base_new(const char *name, cfs_plug_t *base)
{
g_return_val_if_fail(name != NULL, NULL);
g_return_val_if_fail(base != NULL, NULL);
cfs_plug_base_t *cfs_plug_base_new(const char *name, cfs_plug_t *base) {
g_return_val_if_fail(name != NULL, NULL);
g_return_val_if_fail(base != NULL, NULL);
cfs_plug_base_t *plug = g_new0(cfs_plug_base_t, 1);
cfs_plug_base_t *plug = g_new0(cfs_plug_base_t, 1);
plug->plug.lookup_plug = cfs_plug_base_lookup_plug;
plug->plug.destroy_plug = cfs_plug_base_destroy;
plug->plug.start_workers = cfs_plug_base_start_workers;
plug->plug.stop_workers = cfs_plug_base_stop_workers;
plug->plug.lookup_plug = cfs_plug_base_lookup_plug;
plug->plug.destroy_plug = cfs_plug_base_destroy;
plug->plug.start_workers = cfs_plug_base_start_workers;
plug->plug.stop_workers = cfs_plug_base_stop_workers;
plug->entries = g_hash_table_new(g_str_hash, g_str_equal);
plug->entries = g_hash_table_new(g_str_hash, g_str_equal);
plug->plug.name = g_strdup(name);
plug->plug.name = g_strdup(name);
plug->plug.ops = &cfs_ops;
plug->plug.ops = &cfs_ops;
plug->base = base;
plug->base = base;
return plug;
return plug;
}
void cfs_plug_base_insert(cfs_plug_base_t *bplug, cfs_plug_t *sub)
{
g_return_if_fail(bplug != NULL);
g_return_if_fail(sub != NULL);
g_return_if_fail(sub->name != NULL);
void cfs_plug_base_insert(cfs_plug_base_t *bplug, cfs_plug_t *sub) {
g_return_if_fail(bplug != NULL);
g_return_if_fail(sub != NULL);
g_return_if_fail(sub->name != NULL);
g_hash_table_replace(bplug->entries, sub->name, sub);
g_hash_table_replace(bplug->entries, sub->name, sub);
}

View file

@ -27,8 +27,8 @@
#include <errno.h>
#include <fuse.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define PARAM_CHECK_ERRNO -EREMOTEIO
@ -36,59 +36,53 @@
typedef struct cfs_plug cfs_plug_t;
struct cfs_operations {
int (*getattr) (cfs_plug_t *, const char *, struct stat *);
int (*readlink) (cfs_plug_t *, const char *, char *, size_t);
int (*mkdir) (cfs_plug_t *, const char *, mode_t);
int (*unlink) (cfs_plug_t *, const char *);
int (*rmdir) (cfs_plug_t *, const char *);
int (*rename) (cfs_plug_t *, const char *, const char *);
int (*truncate) (cfs_plug_t *, const char *, off_t);
int (*open) (cfs_plug_t *, const char *, struct fuse_file_info *);
int (*read) (cfs_plug_t *, const char *, char *, size_t, off_t,
struct fuse_file_info *);
int (*write) (cfs_plug_t *, const char *, const char *, size_t, off_t,
struct fuse_file_info *);
int (*readdir) (cfs_plug_t *, const char *, void *, fuse_fill_dir_t, off_t,
struct fuse_file_info *);
int (*create) (cfs_plug_t *, const char *, mode_t, struct fuse_file_info *);
int (*utimens) (cfs_plug_t *, const char *, const struct timespec tv[2]);
int (*statfs) (cfs_plug_t *, const char *, struct statvfs *);
int (*getattr)(cfs_plug_t *, const char *, struct stat *);
int (*readlink)(cfs_plug_t *, const char *, char *, size_t);
int (*mkdir)(cfs_plug_t *, const char *, mode_t);
int (*unlink)(cfs_plug_t *, const char *);
int (*rmdir)(cfs_plug_t *, const char *);
int (*rename)(cfs_plug_t *, const char *, const char *);
int (*truncate)(cfs_plug_t *, const char *, off_t);
int (*open)(cfs_plug_t *, const char *, struct fuse_file_info *);
int (*read)(cfs_plug_t *, const char *, char *, size_t, off_t, struct fuse_file_info *);
int (*write)(cfs_plug_t *, const char *, const char *, size_t, off_t, struct fuse_file_info *);
int (*readdir)(cfs_plug_t *, const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *);
int (*create)(cfs_plug_t *, const char *, mode_t, struct fuse_file_info *);
int (*utimens)(cfs_plug_t *, const char *, const struct timespec tv[2]);
int (*statfs)(cfs_plug_t *, const char *, struct statvfs *);
};
struct cfs_plug {
struct cfs_operations *ops;
cfs_plug_t *(*lookup_plug)(cfs_plug_t *plug, char **path);
void (*destroy_plug) (cfs_plug_t *plug);
void (*start_workers) (cfs_plug_t *plug);
void (*stop_workers) (cfs_plug_t *plug);
struct cfs_operations *ops;
cfs_plug_t *(*lookup_plug)(cfs_plug_t *plug, char **path);
void (*destroy_plug)(cfs_plug_t *plug);
void (*start_workers)(cfs_plug_t *plug);
void (*stop_workers)(cfs_plug_t *plug);
char *name;
char *name;
};
typedef struct {
cfs_plug_t plug;
cfs_plug_t *base;
GHashTable *entries;
cfs_plug_t plug;
cfs_plug_t *base;
GHashTable *entries;
} cfs_plug_base_t;
typedef struct {
cfs_plug_t plug;
char *symlink;
cfs_plug_t plug;
char *symlink;
} cfs_plug_link_t;
typedef char *(*cfs_plug_func_update_data_fn_t)(cfs_plug_t *plug);
typedef int (*cfs_plug_func_write_data_fn_t)(
cfs_plug_t *plug,
const char *buf,
size_t size);
typedef int (*cfs_plug_func_write_data_fn_t)(cfs_plug_t *plug, const char *buf, size_t size);
typedef struct {
cfs_plug_t plug;
char *data;
GRWLock data_rw_lock;
mode_t mode;
cfs_plug_func_update_data_fn_t update_callback;
cfs_plug_func_write_data_fn_t write_callback;
cfs_plug_t plug;
char *data;
GRWLock data_rw_lock;
mode_t mode;
cfs_plug_func_update_data_fn_t update_callback;
cfs_plug_func_write_data_fn_t write_callback;
} cfs_plug_func_t;
cfs_plug_base_t *cfs_plug_base_new(const char *name, cfs_plug_t *base);
@ -96,10 +90,10 @@ void cfs_plug_base_insert(cfs_plug_base_t *base, cfs_plug_t *sub);
cfs_plug_link_t *cfs_plug_link_new(const char *name, const char *symlink);
cfs_plug_func_t *cfs_plug_func_new(
const char *name,
mode_t mode,
cfs_plug_func_update_data_fn_t update_callback,
cfs_plug_func_write_data_fn_t write_callback);
const char *name,
mode_t mode,
cfs_plug_func_update_data_fn_t update_callback,
cfs_plug_func_write_data_fn_t write_callback
);
#endif /* _PVE_CFS_PLUG_H_ */

View file

@ -22,310 +22,284 @@
#include <config.h>
#endif /* HAVE_CONFIG_H */
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <utime.h>
#include <sys/stat.h>
#include <glib.h>
#include <qb/qblog.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <utime.h>
#include "cfs-utils.h"
static const char * hexchar = "0123456789abcdef";
static const char *hexchar = "0123456789abcdef";
/* convert utf8 to json and syslog compatible ascii */
void
utf8_to_ascii(
char *buf,
int bufsize,
const char *msg,
gboolean quotequote)
{
g_return_if_fail(buf != NULL);
void utf8_to_ascii(char *buf, int bufsize, const char *msg, gboolean quotequote) {
g_return_if_fail(buf != NULL);
*buf = 0;
*buf = 0;
g_return_if_fail(bufsize > 10);
g_return_if_fail(bufsize > 10);
const char *p = msg;
char *d = buf;
char *end = buf + bufsize - 7;
const char *p = msg;
char *d = buf;
char *end = buf + bufsize - 7;
if (!g_utf8_validate(msg, -1, NULL)) {
while (*p && d < end) {
char c = *p++;
if (c == 34 && quotequote) {
*d++ = '\\';
*d++ = '"';
} else if (c >= 0 && c < 32) {
*d++ = '#';
*d++ = '0';
*(d+1) = hexchar[c % 10]; c = c / 10;
*d = hexchar[c % 10];
d += 2;
} else if (c >= 32 && c < 127) {
*d++ = c;
} else {
*d++ = '?';
}
}
*d = 0;
return;
}
if (!g_utf8_validate(msg, -1, NULL)) {
while (*p && d < end) {
char c = *p++;
if (c == 34 && quotequote) {
*d++ = '\\';
*d++ = '"';
} else if (c >= 0 && c < 32) {
*d++ = '#';
*d++ = '0';
*(d + 1) = hexchar[c % 10];
c = c / 10;
*d = hexchar[c % 10];
d += 2;
} else if (c >= 32 && c < 127) {
*d++ = c;
} else {
*d++ = '?';
}
}
*d = 0;
return;
}
while (*p && d < end) {
gunichar u = g_utf8_get_char(p);
if (u == 34 && quotequote) {
*d++ = '\\';
*d++ = '"';
} else if (u < 32 || u == 127) {
*d++ = '#';
*(d+2) = hexchar[u % 10]; u = u / 10;
*(d+1) = hexchar[u % 10]; u = u / 10;
*d = hexchar[u % 10];
d += 3;
} else if (u < 127) {
*d++ = u;
} else if (u < 65536) {
*d++ = '\\';
*d++ = 'u';
*(d+3) = hexchar[u&0xf]; u = u >> 4;
*(d+2) = hexchar[u&0xf]; u = u >> 4;
*(d+1) = hexchar[u&0xf]; u = u >> 4;
*d = hexchar[u&0xf];
d += 4;
} else {
/* we simply ignore this */
}
p = g_utf8_next_char(p);
}
*d = 0;
while (*p && d < end) {
gunichar u = g_utf8_get_char(p);
if (u == 34 && quotequote) {
*d++ = '\\';
*d++ = '"';
} else if (u < 32 || u == 127) {
*d++ = '#';
*(d + 2) = hexchar[u % 10];
u = u / 10;
*(d + 1) = hexchar[u % 10];
u = u / 10;
*d = hexchar[u % 10];
d += 3;
} else if (u < 127) {
*d++ = u;
} else if (u < 65536) {
*d++ = '\\';
*d++ = 'u';
*(d + 3) = hexchar[u & 0xf];
u = u >> 4;
*(d + 2) = hexchar[u & 0xf];
u = u >> 4;
*(d + 1) = hexchar[u & 0xf];
u = u >> 4;
*d = hexchar[u & 0xf];
d += 4;
} else {
/* we simply ignore this */
}
p = g_utf8_next_char(p);
}
*d = 0;
}
void
cfs_log(
const gchar *log_domain,
GLogLevelFlags log_level,
const char *file,
int line,
const char *func,
const gchar *format,
...)
{
gint level;
void cfs_log(
const gchar *log_domain,
GLogLevelFlags log_level,
const char *file,
int line,
const char *func,
const gchar *format,
...
) {
gint level;
switch (log_level & G_LOG_LEVEL_MASK) {
case G_LOG_LEVEL_ERROR:
level=LOG_ERR;
break;
case G_LOG_LEVEL_CRITICAL:
level=LOG_CRIT;
break;
case G_LOG_LEVEL_WARNING:
level=LOG_WARNING;
break;
case G_LOG_LEVEL_MESSAGE:
level=LOG_NOTICE;
break;
case G_LOG_LEVEL_INFO:
level=LOG_INFO;
break;
case G_LOG_LEVEL_DEBUG:
level=LOG_DEBUG;
if (!cfs.debug)
return;
break;
default:
level=LOG_INFO;
}
switch (log_level & G_LOG_LEVEL_MASK) {
case G_LOG_LEVEL_ERROR:
level = LOG_ERR;
break;
case G_LOG_LEVEL_CRITICAL:
level = LOG_CRIT;
break;
case G_LOG_LEVEL_WARNING:
level = LOG_WARNING;
break;
case G_LOG_LEVEL_MESSAGE:
level = LOG_NOTICE;
break;
case G_LOG_LEVEL_INFO:
level = LOG_INFO;
break;
case G_LOG_LEVEL_DEBUG:
level = LOG_DEBUG;
if (!cfs.debug)
return;
break;
default:
level = LOG_INFO;
}
va_list args;
va_list args;
va_start (args, format);
char *orgmsg = g_strdup_vprintf (format, args);
va_end (args);
va_start(args, format);
char *orgmsg = g_strdup_vprintf(format, args);
va_end(args);
char msg[8192];
utf8_to_ascii(msg, sizeof(msg), orgmsg, FALSE);
char msg[8192];
utf8_to_ascii(msg, sizeof(msg), orgmsg, FALSE);
uint32_t tag = g_quark_from_string(log_domain);
uint32_t tag = g_quark_from_string(log_domain);
qb_log_from_external_source(func, file, "%s", level, line, tag, msg);
qb_log_from_external_source(func, file, "%s", level, line, tag, msg);
g_free(orgmsg);
g_free(orgmsg);
}
guint64
cluster_config_version(
const gpointer config_data,
gsize config_length)
{
GRegex *regex;
GMatchInfo *match_info;
guint64 version = 0;
guint64 cluster_config_version(const gpointer config_data, gsize config_length) {
GRegex *regex;
GMatchInfo *match_info;
guint64 version = 0;
regex = g_regex_new ("config_version\\s*:\\s*(\\d+)", 0, 0, NULL);
g_regex_match_full(regex, config_data, config_length, 0, 0, &match_info, NULL);
if (g_match_info_matches (match_info)) {
gchar *word = g_match_info_fetch (match_info, 1);
if (strlen(word)) {
version = strtoull(word, NULL, 10);
}
g_free (word);
}
g_match_info_free (match_info);
g_regex_unref (regex);
regex = g_regex_new("config_version\\s*:\\s*(\\d+)", 0, 0, NULL);
g_regex_match_full(regex, config_data, config_length, 0, 0, &match_info, NULL);
if (g_match_info_matches(match_info)) {
gchar *word = g_match_info_fetch(match_info, 1);
if (strlen(word)) {
version = strtoull(word, NULL, 10);
}
g_free(word);
}
g_match_info_free(match_info);
g_regex_unref(regex);
return version;
return version;
}
ssize_t
safe_read(
int fd,
char *buf,
size_t count)
{
ssize_t n;
ssize_t safe_read(int fd, char *buf, size_t count) {
ssize_t n;
do {
n = read(fd, buf, count);
} while (n < 0 && errno == EINTR);
do {
n = read(fd, buf, count);
} while (n < 0 && errno == EINTR);
return n;
return n;
}
gboolean
full_write(
int fd,
const char *buf,
size_t len)
{
while (len > 0) {
ssize_t n;
do {
n = write(fd, buf, len);
} while (n < 0 && errno == EINTR);
if (n < 0)
break;
buf += n;
len -= n;
}
gboolean full_write(int fd, const char *buf, size_t len) {
while (len > 0) {
ssize_t n;
do {
n = write(fd, buf, len);
} while (n < 0 && errno == EINTR);
return (len == 0);
if (n < 0)
break;
buf += n;
len -= n;
}
return (len == 0);
}
gboolean
atomic_write_file(
const char *filename,
gconstpointer data,
size_t len,
mode_t mode,
gid_t gid)
{
g_return_val_if_fail(filename != NULL, FALSE);
g_return_val_if_fail(len == 0 || data != NULL, FALSE);
gboolean
atomic_write_file(const char *filename, gconstpointer data, size_t len, mode_t mode, gid_t gid) {
g_return_val_if_fail(filename != NULL, FALSE);
g_return_val_if_fail(len == 0 || data != NULL, FALSE);
gboolean res = TRUE;
gboolean res = TRUE;
char *tmp_name = g_strdup_printf ("%s.XXXXXX", filename);
int fd = mkstemp(tmp_name);
if (fd == -1) {
cfs_critical("Failed to create file '%s': %s", tmp_name, g_strerror(errno));
res = FALSE;
goto ret;
}
char *tmp_name = g_strdup_printf("%s.XXXXXX", filename);
int fd = mkstemp(tmp_name);
if (fd == -1) {
cfs_critical("Failed to create file '%s': %s", tmp_name, g_strerror(errno));
res = FALSE;
goto ret;
}
if (fchown(fd, 0, gid) == -1) {
cfs_critical("Failed to change group of file '%s': %s", tmp_name, g_strerror(errno));
close(fd);
goto fail;
}
if (fchown(fd, 0, gid) == -1) {
cfs_critical("Failed to change group of file '%s': %s", tmp_name, g_strerror(errno));
close(fd);
goto fail;
}
if (fchmod(fd, mode) == -1) {
cfs_critical("Failed to change mode of file '%s': %s", tmp_name, g_strerror(errno));
close(fd);
goto fail;
}
if (fchmod(fd, mode) == -1) {
cfs_critical("Failed to change mode of file '%s': %s", tmp_name, g_strerror(errno));
close(fd);
goto fail;
}
if (len && !full_write(fd, data, len)) {
cfs_critical("Failed to write file '%s': %s", tmp_name, g_strerror(errno));
close(fd);
goto fail;
}
if (len && !full_write(fd, data, len)) {
cfs_critical("Failed to write file '%s': %s", tmp_name, g_strerror(errno));
close(fd);
goto fail;
}
if (close(fd) == -1) {
cfs_critical("Failed to close file '%s': %s", tmp_name, g_strerror(errno));
goto fail;
}
if (close(fd) == -1) {
cfs_critical("Failed to close file '%s': %s", tmp_name, g_strerror(errno));
goto fail;
}
if (rename(tmp_name, filename) == -1) {
cfs_critical("Failed to rename file from '%s' to '%s': %s",
tmp_name, filename, g_strerror(errno));
goto fail;
}
if (rename(tmp_name, filename) == -1) {
cfs_critical(
"Failed to rename file from '%s' to '%s': %s", tmp_name, filename, g_strerror(errno)
);
goto fail;
}
ret:
g_free (tmp_name);
g_free(tmp_name);
return res;
return res;
fail:
unlink(tmp_name);
unlink(tmp_name);
res = FALSE;
res = FALSE;
goto ret;
goto ret;
}
gboolean
path_is_private(const char *path)
{
while (*path == '/') path++;
gboolean path_is_private(const char *path) {
while (*path == '/')
path++;
if ((strncmp(path, "priv", 4) == 0) && (path[4] == 0 || path[4] == '/')) {
return TRUE;
} else {
if (strncmp(path, "nodes/", 6) == 0) {
const char *tmp = path + 6;
while(*tmp && *tmp != '/') tmp++;
if (*tmp == '/' &&
(strncmp(tmp, "/priv", 5) == 0) &&
(tmp[5] == 0 || tmp[5] == '/')) {
return TRUE;
}
}
}
return FALSE;
if ((strncmp(path, "priv", 4) == 0) && (path[4] == 0 || path[4] == '/')) {
return TRUE;
} else {
if (strncmp(path, "nodes/", 6) == 0) {
const char *tmp = path + 6;
while (*tmp && *tmp != '/')
tmp++;
if (*tmp == '/' && (strncmp(tmp, "/priv", 5) == 0) && (tmp[5] == 0 || tmp[5] == '/')) {
return TRUE;
}
}
}
return FALSE;
}
gboolean
path_is_lxc_conf(const char *path)
{
while (*path == '/') path++;
gboolean path_is_lxc_conf(const char *path) {
while (*path == '/')
path++;
if (strncmp(path, "nodes/", 6) == 0) {
const char *tmp = path + 6;
while(*tmp && *tmp != '/') tmp++;
if (*tmp == '/' &&
(strncmp(tmp, "/lxc", 4) == 0) &&
(tmp[4] == 0 || tmp[4] == '/')) {
return TRUE;
}
}
return FALSE;
if (strncmp(path, "nodes/", 6) == 0) {
const char *tmp = path + 6;
while (*tmp && *tmp != '/')
tmp++;
if (*tmp == '/' && (strncmp(tmp, "/lxc", 4) == 0) && (tmp[4] == 0 || tmp[4] == '/')) {
return TRUE;
}
}
return FALSE;
}
gboolean path_is_lockdir(const char *path) {
while (*path == '/')
path++;
gboolean
path_is_lockdir(const char *path)
{
while (*path == '/') path++;
return (strncmp(path, "priv/lock/", 10) == 0) && path[10];
return (strncmp(path, "priv/lock/", 10) == 0) && path[10];
}

View file

@ -25,98 +25,77 @@
#include <config.h>
#endif /* HAVE_CONFIG_H */
#include <stdint.h>
#include <glib.h>
#include <fcntl.h>
#include <glib.h>
#include <stdint.h>
#define HOST_CLUSTER_CONF_FN "/etc/corosync/corosync.conf"
#define CFS_PID_FN "/var/run/pve-cluster.pid"
#define VARLIBDIR "/var/lib/pve-cluster"
#define RUNDIR "/run/pve-cluster"
#define CFS_MAX(a, b) (((a) > (b)) ? (a) : (b))
#define CFS_MIN(a, b) (((a) < (b)) ? (a) : (b))
#define CFS_MAX(a, b) (((a) > (b)) ? (a) : (b))
#define CFS_MIN(a, b) (((a) < (b)) ? (a) : (b))
typedef struct {
char *nodename;
char *ip;
gid_t gid;
int debug;
char *nodename;
char *ip;
gid_t gid;
int debug;
} cfs_t;
extern cfs_t cfs;
void
utf8_to_ascii(
char *buf,
int bufsize,
const char *msg,
gboolean quotequote);
void utf8_to_ascii(char *buf, int bufsize, const char *msg, gboolean quotequote);
void
cfs_log(
const gchar *log_domain,
GLogLevelFlags log_level,
const char *file,
int line,
const char *func,
const gchar *format,
...) G_GNUC_PRINTF (6, 7);
void cfs_log(
const gchar *log_domain,
GLogLevelFlags log_level,
const char *file,
int line,
const char *func,
const gchar *format,
...
) G_GNUC_PRINTF(6, 7);
void ipc_log_fn(
const char *file,
int32_t line,
int32_t severity,
const char *msg);
void ipc_log_fn(const char *file, int32_t line, int32_t severity, const char *msg);
#define cfs_debug(...) \
G_STMT_START { \
if (cfs.debug) \
cfs_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, __FILE__, __LINE__, G_STRFUNC, __VA_ARGS__); \
} \
G_STMT_END
#define cfs_debug(...) G_STMT_START { \
if (cfs.debug) \
cfs_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, __FILE__, __LINE__, G_STRFUNC, __VA_ARGS__); \
} G_STMT_END
#define cfs_dom_debug(domain, ...) \
G_STMT_START { \
if (cfs.debug) \
cfs_log(domain, G_LOG_LEVEL_DEBUG, __FILE__, __LINE__, G_STRFUNC, __VA_ARGS__); \
} \
G_STMT_END
#define cfs_dom_debug(domain, ...) G_STMT_START { \
if (cfs.debug) \
cfs_log(domain, G_LOG_LEVEL_DEBUG, __FILE__, __LINE__, G_STRFUNC, __VA_ARGS__); \
} G_STMT_END
#define cfs_critical(...) \
cfs_log(G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, __FILE__, __LINE__, G_STRFUNC, __VA_ARGS__)
#define cfs_dom_critical(domain, ...) \
cfs_log(domain, G_LOG_LEVEL_CRITICAL, __FILE__, __LINE__, G_STRFUNC, __VA_ARGS__)
#define cfs_message(...) \
cfs_log(G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, __FILE__, __LINE__, G_STRFUNC, __VA_ARGS__)
#define cfs_dom_message(domain, ...) \
cfs_log(domain, G_LOG_LEVEL_MESSAGE, __FILE__, __LINE__, G_STRFUNC, __VA_ARGS__)
#define cfs_critical(...) cfs_log(G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, __FILE__, __LINE__, G_STRFUNC, __VA_ARGS__)
#define cfs_dom_critical(domain, ...) cfs_log(domain, G_LOG_LEVEL_CRITICAL, __FILE__, __LINE__, G_STRFUNC, __VA_ARGS__)
#define cfs_message(...) cfs_log(G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, __FILE__, __LINE__, G_STRFUNC, __VA_ARGS__)
#define cfs_dom_message(domain, ...) cfs_log(domain, G_LOG_LEVEL_MESSAGE, __FILE__, __LINE__, G_STRFUNC, __VA_ARGS__)
guint64 cluster_config_version(const gpointer config_data, gsize config_length);
guint64
cluster_config_version(
const gpointer config_data,
gsize config_length);
ssize_t safe_read(int fd, char *buf, size_t count);
ssize_t
safe_read(
int fd,
char *buf,
size_t count);
gboolean
full_write(
int fd,
const char *buf,
size_t len);
gboolean
atomic_write_file(
const char *filename,
gconstpointer data,
size_t len,
mode_t mode,
gid_t gid);
gboolean full_write(int fd, const char *buf, size_t len);
gboolean
path_is_private(const char *path);
atomic_write_file(const char *filename, gconstpointer data, size_t len, mode_t mode, gid_t gid);
gboolean
path_is_lxc_conf(const char *path);
gboolean path_is_private(const char *path);
gboolean
path_is_lockdir(const char *path);
gboolean path_is_lxc_conf(const char *path);
gboolean path_is_lockdir(const char *path);
#endif /* _PVE_CFS_UTILS_H_ */

View file

@ -18,18 +18,17 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <errno.h>
#include <string.h>
#include <check.h>
#include <errno.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "cfs-utils.h"
#include "status.h"
#include "memdb.h"
#include "status.h"
#if CHECK_MAJOR_VERSION == 0 && CHECK_MINOR_VERSION <= 10
#define _TEST_TYPE TFun
@ -38,272 +37,249 @@
#endif
cfs_t cfs = {
.debug = 0,
.nodename = "testnode",
.debug = 0,
.nodename = "testnode",
};
#define TESTDB "/tmp/test.db"
static memdb_t *memdb;
static void
setup(void)
{
unlink(TESTDB);
memdb = memdb_open(TESTDB);
ck_assert (memdb != NULL);
static void setup(void) {
unlink(TESTDB);
memdb = memdb_open(TESTDB);
ck_assert(memdb != NULL);
struct statvfs stbuf;
ck_assert(memdb_statfs(memdb, &stbuf) == 0);
struct statvfs stbuf;
ck_assert(memdb_statfs(memdb, &stbuf) == 0);
int count = stbuf.f_files - stbuf.f_ffree;
ck_assert(count == 1);
}
void
teardown(void)
{
ck_assert (memdb != NULL);
memdb_close(memdb);
int count = stbuf.f_files - stbuf.f_ffree;
ck_assert(count == 1);
}
START_TEST(test_indextest1)
{
char namebuf[100];
void teardown(void) {
ck_assert(memdb != NULL);
time_t ctime = 1234;
int testsize = 1024*32;
gchar *testdata = g_malloc0(testsize);
memdb_close(memdb);
}
for (int i = 0; i < 100; i++) {
sprintf(namebuf, "testfile%d", i);
START_TEST(test_indextest1) {
char namebuf[100];
ck_assert(memdb_create(memdb, namebuf, 0, ctime) == 0);
ck_assert(memdb_write(memdb, namebuf, 0, ctime, testdata, testsize, 0, 0) == testsize);
}
time_t ctime = 1234;
int testsize = 1024 * 32;
gchar *testdata = g_malloc0(testsize);
struct statvfs stbuf;
ck_assert(memdb_statfs(memdb, &stbuf) == 0);
for (int i = 0; i < 100; i++) {
sprintf(namebuf, "testfile%d", i);
int count = stbuf.f_files - stbuf.f_ffree;
ck_assert(count == 101);
ck_assert(memdb_create(memdb, namebuf, 0, ctime) == 0);
ck_assert(memdb_write(memdb, namebuf, 0, ctime, testdata, testsize, 0, 0) == testsize);
}
memdb_index_t *idx = memdb_encode_index(memdb->index, memdb->root);
ck_assert(idx != NULL);
ck_assert(idx->version == 201);
ck_assert(idx->last_inode == 200);
ck_assert(idx->writer == 0);
ck_assert(idx->size == 101);
ck_assert(idx->bytes == (101*40 + sizeof( memdb_index_t)));
struct statvfs stbuf;
ck_assert(memdb_statfs(memdb, &stbuf) == 0);
GChecksum *sha256 = g_checksum_new(G_CHECKSUM_SHA256);
ck_assert(sha256 != NULL);
g_checksum_update(sha256, (unsigned char *)idx, idx->bytes);
const char *csum = g_checksum_get_string(sha256);
ck_assert_msg(
strcmp(csum, "913fd95015af9d93f10dd51ba2a7bb11351bcfe040be21e95fcba834adc3ec10") == 0,
"wrong idx checksum %s",
csum
);
g_free(idx);
g_free(testdata);
int count = stbuf.f_files - stbuf.f_ffree;
ck_assert(count == 101);
memdb_index_t *idx = memdb_encode_index(memdb->index, memdb->root);
ck_assert(idx != NULL);
ck_assert(idx->version == 201);
ck_assert(idx->last_inode == 200);
ck_assert(idx->writer == 0);
ck_assert(idx->size == 101);
ck_assert(idx->bytes == (101 * 40 + sizeof(memdb_index_t)));
GChecksum *sha256 = g_checksum_new(G_CHECKSUM_SHA256);
ck_assert(sha256 != NULL);
g_checksum_update(sha256, (unsigned char *)idx, idx->bytes);
const char *csum = g_checksum_get_string(sha256);
ck_assert_msg(
strcmp(csum, "913fd95015af9d93f10dd51ba2a7bb11351bcfe040be21e95fcba834adc3ec10") == 0,
"wrong idx checksum %s", csum
);
g_free(idx);
g_free(testdata);
}
END_TEST
START_TEST (test_dirtest1)
{
const char *dn = "/dir1";
const char *sdn = "/dir1/sdir1";
time_t ctime = 1234;
START_TEST(test_dirtest1) {
const char *dn = "/dir1";
const char *sdn = "/dir1/sdir1";
time_t ctime = 1234;
ck_assert(memdb_mkdir(memdb, sdn, 0, ctime) == -ENOENT);
ck_assert(memdb_delete(memdb, dn, 0, ctime) == -ENOENT);
ck_assert(memdb_mkdir(memdb, sdn, 0, ctime) == -ENOENT);
ck_assert(memdb_delete(memdb, dn, 0, ctime) == -ENOENT);
ck_assert(memdb_mkdir(memdb, dn, 0, ctime) == 0);
ck_assert(memdb_mkdir(memdb, dn, 0, ctime) == -EEXIST);
ck_assert(memdb_mkdir(memdb, sdn, 0, ctime) == 0);
ck_assert(memdb_mkdir(memdb, sdn, 0, ctime) == -EEXIST);
ck_assert(memdb_delete(memdb, dn, 0, ctime) == -ENOTEMPTY);
ck_assert(memdb_delete(memdb, sdn, 0, ctime) == 0);
ck_assert(memdb_delete(memdb, dn, 0, ctime) == 0);
ck_assert(memdb_mkdir(memdb, dn, 0, ctime) == 0);
ck_assert(memdb_mkdir(memdb, dn, 0, ctime) == -EEXIST);
ck_assert(memdb_mkdir(memdb, sdn, 0, ctime) == 0);
ck_assert(memdb_mkdir(memdb, sdn, 0, ctime) == -EEXIST);
ck_assert(memdb_delete(memdb, dn, 0, ctime) == -ENOTEMPTY);
ck_assert(memdb_delete(memdb, sdn, 0, ctime) == 0);
ck_assert(memdb_delete(memdb, dn, 0, ctime) == 0);
}
END_TEST
START_TEST (test_filetest1)
{
const char *dn = "/dir1";
const char *fn = "/dir1/f1";
time_t ctime = 1234;
gpointer data;
START_TEST(test_filetest1) {
const char *dn = "/dir1";
const char *fn = "/dir1/f1";
time_t ctime = 1234;
gpointer data;
char buf[1024];
memset(buf, 0, sizeof(buf));
char buf[1024];
memset(buf, 0, sizeof(buf));
ck_assert(memdb_read(memdb, fn, &data) == -ENOENT);
ck_assert(memdb_read(memdb, fn, &data) == -ENOENT);
ck_assert(memdb_mkdir(memdb, dn, 0, ctime) == 0);
ck_assert(memdb_mkdir(memdb, dn, 0, ctime) == 0);
ck_assert(memdb_read(memdb, fn, &data) == -ENOENT);
ck_assert(memdb_read(memdb, fn, &data) == -ENOENT);
ck_assert(memdb_write(memdb, fn, 0, ctime, buf, sizeof(buf), 0, 0) == -ENOENT);
ck_assert(memdb_write(memdb, fn, 0, ctime, buf, sizeof(buf), 0, 0) == -ENOENT);
ck_assert(memdb_create(memdb, fn, 0, ctime) == 0);
ck_assert(memdb_create(memdb, fn, 0, ctime) == 0);
ck_assert(memdb_write(memdb, fn, 0, ctime, buf, sizeof(buf), 0, 0) == sizeof(buf));
ck_assert(memdb_write(memdb, fn, 0, ctime, buf, sizeof(buf), 0, 0) == sizeof(buf));
ck_assert(memdb_read(memdb, fn, &data) == sizeof(buf));
ck_assert(memdb_read(memdb, fn, &data) == sizeof(buf));
ck_assert(memcmp(buf, data, sizeof(buf)) == 0);
ck_assert(memcmp(buf, data, sizeof(buf)) == 0);
g_free(data);
g_free(data);
ck_assert(memdb_write(memdb, fn, 0, ctime, "0123456789", 10, 0, 1) == 10);
ck_assert(memdb_read(memdb, fn, &data) == 10);
g_free(data);
ck_assert(memdb_write(memdb, fn, 0, ctime, "0123456789", 10, 0, 1) == 10);
ck_assert(memdb_write(memdb, fn, 0, ctime, "X", 1, 3, 0) == 1);
ck_assert(memdb_read(memdb, fn, &data) == 10);
g_free(data);
ck_assert(memdb_write(memdb, fn, 0, ctime, "X", 1, 6, 0) == 1);
ck_assert(memdb_write(memdb, fn, 0, ctime, "X", 1, 3, 0) == 1);
ck_assert(memdb_read(memdb, fn, &data) == 10);
ck_assert(memdb_write(memdb, fn, 0, ctime, "X", 1, 6, 0) == 1);
ck_assert(strncmp(data, "012X45X789", 10) == 0);
g_free(data);
ck_assert(memdb_read(memdb, fn, &data) == 10);
ck_assert(memdb_delete(memdb, fn, 0, ctime) == 0);
ck_assert(strncmp(data, "012X45X789", 10) == 0);
g_free(data);
ck_assert(memdb_delete(memdb, fn, 0, ctime) == -ENOENT);
ck_assert(memdb_delete(memdb, fn, 0, ctime) == 0);
ck_assert(memdb_delete(memdb, dn, 0, ctime) == 0);
ck_assert(memdb_delete(memdb, fn, 0, ctime) == -ENOENT);
ck_assert(memdb_delete(memdb, dn, 0, ctime) == 0);
}
END_TEST
/* Nornmaly, parent inode number is always less than contained inode,
* but this is not allways the case. A simple move can destroy that
* ordering. This code test the placeholder algorithm in
* but this is not allways the case. A simple move can destroy that
* ordering. This code test the placeholder algorithm in
* bdb_backend_load_index()
*/
START_TEST (test_loaddb1)
{
time_t ctime = 1234;
START_TEST(test_loaddb1) {
time_t ctime = 1234;
ck_assert(memdb_mkdir(memdb, "dir1", 0, ctime) == 0);
ck_assert(memdb_mkdir(memdb, "dir1", 0, ctime) == 0);
ck_assert(memdb_create(memdb, "dir1/file1", 0, ctime) == 0);
ck_assert(memdb_create(memdb, "dir1/file1", 0, ctime) == 0);
ck_assert(memdb_create(memdb, "dir1/file2", 0, ctime) == 0);
ck_assert(memdb_create(memdb, "dir1/file2", 0, ctime) == 0);
ck_assert(memdb_mkdir(memdb, "dir2", 0, ctime) == 0);
ck_assert(memdb_mkdir(memdb, "dir2", 0, ctime) == 0);
ck_assert(memdb_rename(memdb, "dir1/file1", "dir2/file1", 0, ctime) == 0);
ck_assert(memdb_rename(memdb, "dir1/file1", "dir2/file1", 0, ctime) == 0);
ck_assert(memdb_rename(memdb, "dir1/file2", "dir2/file2", 0, ctime) == 0);
ck_assert(memdb_rename(memdb, "dir1/file2", "dir2/file2", 0, ctime) == 0);
ck_assert(memdb_create(memdb, "dir2/file1", 0, ctime) == -EEXIST);
ck_assert(memdb_create(memdb, "dir2/file1", 0, ctime) == -EEXIST);
ck_assert(memdb_create(memdb, "dir2/file2", 0, ctime) == -EEXIST);
ck_assert(memdb_create(memdb, "dir2/file2", 0, ctime) == -EEXIST);
//memdb_dump(memdb);
// memdb_dump(memdb);
memdb_close(memdb);
memdb_close(memdb);
memdb = memdb_open(TESTDB);
ck_assert (memdb != NULL);
memdb = memdb_open(TESTDB);
ck_assert(memdb != NULL);
ck_assert(memdb_create(memdb, "dir2/file1", 0, ctime) == -EEXIST);
ck_assert(memdb_create(memdb, "dir2/file1", 0, ctime) == -EEXIST);
ck_assert(memdb_create(memdb, "dir2/file2", 0, ctime) == -EEXIST);
//memdb_dump(memdb);
ck_assert(memdb_create(memdb, "dir2/file2", 0, ctime) == -EEXIST);
// memdb_dump(memdb);
}
END_TEST
START_TEST (test_loaddb2)
{
time_t ctime = 1234;
START_TEST(test_loaddb2) {
time_t ctime = 1234;
ck_assert(memdb_mkdir(memdb, "dir1", 0, ctime) == 0);
ck_assert(memdb_mkdir(memdb, "dir1", 0, ctime) == 0);
ck_assert(memdb_mkdir(memdb, "dir1/sd1", 0, ctime) == 0);
ck_assert(memdb_mkdir(memdb, "dir1/sd1", 0, ctime) == 0);
ck_assert(memdb_create(memdb, "dir1/file1", 0, ctime) == 0);
ck_assert(memdb_create(memdb, "dir1/file1", 0, ctime) == 0);
ck_assert(memdb_create(memdb, "dir1/file2", 0, ctime) == 0);
ck_assert(memdb_create(memdb, "dir1/file2", 0, ctime) == 0);
ck_assert(memdb_mkdir(memdb, "dir2", 0, ctime) == 0);
ck_assert(memdb_mkdir(memdb, "dir2", 0, ctime) == 0);
ck_assert(memdb_rename(memdb, "dir1/sd1", "dir2/sd1", 0, ctime) == 0);
ck_assert(memdb_rename(memdb, "dir1/sd1", "dir2/sd1", 0, ctime) == 0);
ck_assert(memdb_rename(memdb, "dir1/file1", "dir2/sd1/file1", 0, ctime) == 0);
ck_assert(memdb_rename(memdb, "dir1/file1", "dir2/sd1/file1", 0, ctime) == 0);
ck_assert(memdb_rename(memdb, "dir1/file2", "dir2/sd1/file2", 0, ctime) == 0);
ck_assert(memdb_rename(memdb, "dir1/file2", "dir2/sd1/file2", 0, ctime) == 0);
ck_assert(memdb_create(memdb, "dir2/file3", 0, ctime) == 0);
ck_assert(memdb_create(memdb, "dir2/file3", 0, ctime) == 0);
ck_assert(memdb_mkdir(memdb, "dir2/sd1", 0, ctime) == -EEXIST);
ck_assert(memdb_mkdir(memdb, "dir2/sd1", 0, ctime) == -EEXIST);
//memdb_dump(memdb);
// memdb_dump(memdb);
memdb_close(memdb);
memdb_close(memdb);
memdb = memdb_open(TESTDB);
ck_assert (memdb != NULL);
memdb = memdb_open(TESTDB);
ck_assert(memdb != NULL);
ck_assert(memdb_mkdir(memdb, "dir2/sd1", 0, ctime) == -EEXIST);
//memdb_dump(memdb);
ck_assert(memdb_mkdir(memdb, "dir2/sd1", 0, ctime) == -EEXIST);
// memdb_dump(memdb);
}
END_TEST
static void
add_test(
Suite *s,
_TEST_TYPE tf,
const char *name)
{
TCase *tc = tcase_create (name);
tcase_add_checked_fixture (tc, setup, teardown);
tcase_add_test (tc, tf);
suite_add_tcase (s, tc);
static void add_test(Suite *s, _TEST_TYPE tf, const char *name) {
TCase *tc = tcase_create(name);
tcase_add_checked_fixture(tc, setup, teardown);
tcase_add_test(tc, tf);
suite_add_tcase(s, tc);
}
static Suite *
memdb_suite(void)
{
Suite *s = suite_create ("memdb");
static Suite *memdb_suite(void) {
Suite *s = suite_create("memdb");
add_test(s, test_dirtest1, "dirtest1");
add_test(s, test_dirtest1, "dirtest1");
add_test(s, test_filetest1, "filetest1");
add_test(s, test_indextest1, "indextest1");
add_test(s, test_loaddb1, "loaddb1");
add_test(s, test_loaddb2, "loaddb2");
return s;
add_test(s, test_filetest1, "filetest1");
add_test(s, test_indextest1, "indextest1");
add_test(s, test_loaddb1, "loaddb1");
add_test(s, test_loaddb2, "loaddb2");
return s;
}
int
main(void)
{
int number_failed;
int main(void) {
int number_failed;
cfs_status_init();
cfs_status_init();
Suite *s = memdb_suite();
SRunner *sr = srunner_create(s);
srunner_run_all(sr, CK_NORMAL);
number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
Suite *s = memdb_suite();
SRunner *sr = srunner_create(s);
srunner_run_all(sr, CK_NORMAL);
number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}

View file

@ -18,7 +18,6 @@
*/
/* see "man cmap_overview" and "man cmap_keys" */
#define G_LOG_DOMAIN "confdb"
@ -29,11 +28,11 @@
#include <config.h>
#endif /* HAVE_CONFIG_H */
#include <stdlib.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <glib.h>
#include <corosync/cmap.h>
@ -42,321 +41,297 @@
#include "status.h"
typedef struct {
cmap_handle_t handle;
cmap_track_handle_t track_nodelist_handle;
cmap_track_handle_t track_version_handle;
gboolean changes;
cmap_handle_t handle;
cmap_track_handle_t track_nodelist_handle;
cmap_track_handle_t track_version_handle;
gboolean changes;
} cs_private_t;
static cs_error_t
cmap_read_clusternodes(
cmap_handle_t handle,
cfs_clinfo_t *clinfo)
{
cs_error_t result;
cmap_iter_handle_t iter;
static cs_error_t cmap_read_clusternodes(cmap_handle_t handle, cfs_clinfo_t *clinfo) {
cs_error_t result;
cmap_iter_handle_t iter;
result = cmap_iter_init(handle, "nodelist.node.", &iter);
if (result != CS_OK) {
cfs_critical("cmap_iter_init failed %d", result);
return result;
}
result = cmap_iter_init(handle, "nodelist.node.", &iter);
if (result != CS_OK) {
cfs_critical("cmap_iter_init failed %d", result);
return result;
}
cmap_value_types_t type;
char key_name[CMAP_KEYNAME_MAXLEN + 1];
size_t value_len;
cmap_value_types_t type;
char key_name[CMAP_KEYNAME_MAXLEN + 1];
size_t value_len;
int last_id = -1;
uint32_t nodeid = 0;
uint32_t votes = 0;
char *name = NULL;
int last_id = -1;
uint32_t nodeid = 0;
uint32_t votes = 0;
char *name = NULL;
while ((result = cmap_iter_next(handle, iter, key_name, &value_len, &type)) == CS_OK) {
int id;
char subkey[CMAP_KEYNAME_MAXLEN + 1];
if (sscanf(key_name, "nodelist.node.%d.%s", &id, subkey) != 2) continue;
while ((result = cmap_iter_next(handle, iter, key_name, &value_len, &type)) == CS_OK) {
int id;
char subkey[CMAP_KEYNAME_MAXLEN + 1];
if (sscanf(key_name, "nodelist.node.%d.%s", &id, subkey) != 2)
continue;
if (id != last_id) {
if (name && nodeid) {
cfs_clnode_t *clnode = cfs_clnode_new(name, nodeid, votes);
cfs_clinfo_add_node(clinfo, clnode);
}
last_id = id;
free(name);
name = NULL;
nodeid = 0;
votes = 0;
}
if (strcmp(subkey, "nodeid") == 0) {
if ((result = cmap_get_uint32(handle, key_name, &nodeid)) != CS_OK) {
cfs_critical("cmap_get %s failed %d", key_name, result);
}
} else if (strcmp(subkey, "quorum_votes") == 0) {
if ((result = cmap_get_uint32(handle, key_name, &votes)) != CS_OK) {
cfs_critical("cmap_get %s failed %d", key_name, result);
}
} else if (strcmp(subkey, "ring0_addr") == 0) {
// prefering the 'name' subkey over 'ring0_addr', needed for RRP
// and when using a IP address for ring0_addr
if (name == NULL &&
(result = cmap_get_string(handle, key_name, &name)) != CS_OK) {
cfs_critical("cmap_get %s failed %d", key_name, result);
}
} else if (strcmp(subkey, "name") == 0) {
free(name);
name = NULL;
if ((result = cmap_get_string(handle, key_name, &name)) != CS_OK) {
cfs_critical("cmap_get %s failed %d", key_name, result);
}
}
}
if (name && nodeid) {
cfs_clnode_t *clnode = cfs_clnode_new(name, nodeid, votes);
cfs_clinfo_add_node(clinfo, clnode);
}
free(name);
result = cmap_iter_finalize(handle, iter);
if (result != CS_OK) {
cfs_critical("cmap_iter_finalize failed %d", result);
return result;
}
return result;
}
static cs_error_t
cmap_read_config(cmap_handle_t handle)
{
cs_error_t result;
uint64_t config_version = 0;
result = cmap_get_uint64(handle, "totem.config_version", &config_version);
if (result != CS_OK) {
cfs_critical("cmap_get totem.config_version failed %d", result);
// optional, do not throw error
}
char *clustername = NULL;
result = cmap_get_string(handle, "totem.cluster_name", &clustername);
if (result != CS_OK) {
cfs_critical("cmap_get totem.cluster_name failed %d", result);
return result;
}
cfs_clinfo_t *clinfo = cfs_clinfo_new(clustername, config_version);
g_free(clustername);
result = cmap_read_clusternodes(handle, clinfo);
if (result == CS_OK) {
cfs_status_set_clinfo(clinfo);
} else {
cfs_clinfo_destroy(clinfo);
}
return result;
}
static gboolean
service_cmap_finalize(
cfs_service_t *service,
gpointer context)
{
g_return_val_if_fail(service != NULL, FALSE);
g_return_val_if_fail(context != NULL, FALSE);
cs_private_t *private = (cs_private_t *)context;
cmap_handle_t handle = private->handle;
cs_error_t result;
if (private->track_nodelist_handle) {
result = cmap_track_delete(handle, private->track_nodelist_handle);
if (result != CS_OK) {
cfs_critical("cmap_track_delete nodelist failed: %d", result);
if (id != last_id) {
if (name && nodeid) {
cfs_clnode_t *clnode = cfs_clnode_new(name, nodeid, votes);
cfs_clinfo_add_node(clinfo, clnode);
}
private->track_nodelist_handle = 0;
}
if (private->track_version_handle) {
result = cmap_track_delete(handle, private->track_version_handle);
if (result != CS_OK) {
cfs_critical("cmap_track_delete version failed: %d", result);
}
private->track_version_handle = 0;
last_id = id;
free(name);
name = NULL;
nodeid = 0;
votes = 0;
}
result = cmap_finalize(handle);
private->handle = 0;
if (result != CS_OK) {
cfs_critical("cmap_finalize failed: %d", result);
return FALSE;
}
if (strcmp(subkey, "nodeid") == 0) {
if ((result = cmap_get_uint32(handle, key_name, &nodeid)) != CS_OK) {
cfs_critical("cmap_get %s failed %d", key_name, result);
}
} else if (strcmp(subkey, "quorum_votes") == 0) {
if ((result = cmap_get_uint32(handle, key_name, &votes)) != CS_OK) {
cfs_critical("cmap_get %s failed %d", key_name, result);
}
} else if (strcmp(subkey, "ring0_addr") == 0) {
// prefering the 'name' subkey over 'ring0_addr', needed for RRP
// and when using a IP address for ring0_addr
if (name == NULL && (result = cmap_get_string(handle, key_name, &name)) != CS_OK) {
cfs_critical("cmap_get %s failed %d", key_name, result);
}
} else if (strcmp(subkey, "name") == 0) {
free(name);
name = NULL;
if ((result = cmap_get_string(handle, key_name, &name)) != CS_OK) {
cfs_critical("cmap_get %s failed %d", key_name, result);
}
}
}
return TRUE;
if (name && nodeid) {
cfs_clnode_t *clnode = cfs_clnode_new(name, nodeid, votes);
cfs_clinfo_add_node(clinfo, clnode);
}
free(name);
result = cmap_iter_finalize(handle, iter);
if (result != CS_OK) {
cfs_critical("cmap_iter_finalize failed %d", result);
return result;
}
return result;
}
static void
track_callback(
static cs_error_t cmap_read_config(cmap_handle_t handle) {
cs_error_t result;
uint64_t config_version = 0;
result = cmap_get_uint64(handle, "totem.config_version", &config_version);
if (result != CS_OK) {
cfs_critical("cmap_get totem.config_version failed %d", result);
// optional, do not throw error
}
char *clustername = NULL;
result = cmap_get_string(handle, "totem.cluster_name", &clustername);
if (result != CS_OK) {
cfs_critical("cmap_get totem.cluster_name failed %d", result);
return result;
}
cfs_clinfo_t *clinfo = cfs_clinfo_new(clustername, config_version);
g_free(clustername);
result = cmap_read_clusternodes(handle, clinfo);
if (result == CS_OK) {
cfs_status_set_clinfo(clinfo);
} else {
cfs_clinfo_destroy(clinfo);
}
return result;
}
static gboolean service_cmap_finalize(cfs_service_t *service, gpointer context) {
g_return_val_if_fail(service != NULL, FALSE);
g_return_val_if_fail(context != NULL, FALSE);
cs_private_t *private = (cs_private_t *)context;
cmap_handle_t handle = private->handle;
cs_error_t result;
if (private->track_nodelist_handle) {
result = cmap_track_delete(handle, private->track_nodelist_handle);
if (result != CS_OK) {
cfs_critical("cmap_track_delete nodelist failed: %d", result);
}
private->track_nodelist_handle = 0;
}
if (private->track_version_handle) {
result = cmap_track_delete(handle, private->track_version_handle);
if (result != CS_OK) {
cfs_critical("cmap_track_delete version failed: %d", result);
}
private->track_version_handle = 0;
}
result = cmap_finalize(handle);
private->handle = 0;
if (result != CS_OK) {
cfs_critical("cmap_finalize failed: %d", result);
return FALSE;
}
return TRUE;
}
static void track_callback(
cmap_handle_t cmap_handle,
cmap_track_handle_t cmap_track_handle,
int32_t event,
const char *key_name,
struct cmap_notify_value new_value,
struct cmap_notify_value old_value,
void *context)
{
g_return_if_fail(context != NULL);
void *context
) {
g_return_if_fail(context != NULL);
cs_private_t *private = (cs_private_t *)context;
cs_private_t *private = (cs_private_t *)context;
cfs_debug("track_callback %s %d\n", key_name, event);
cfs_debug("track_callback %s %d\n", key_name, event);
private->changes = TRUE;
private->changes = TRUE;
}
static int service_cmap_initialize(cfs_service_t *service, gpointer context) {
g_return_val_if_fail(service != NULL, FALSE);
g_return_val_if_fail(context != NULL, FALSE);
static int
service_cmap_initialize(
cfs_service_t *service,
gpointer context)
{
g_return_val_if_fail(service != NULL, FALSE);
g_return_val_if_fail(context != NULL, FALSE);
cs_private_t *private = (cs_private_t *)context;
cs_private_t *private = (cs_private_t *)context;
// fixme: do not copy (use pointer)
cmap_handle_t handle = private->handle;
cs_error_t result;
// fixme: do not copy (use pointer)
cmap_handle_t handle = private->handle;
cs_error_t result;
if (!private->handle) {
if (!private->handle) {
result = cmap_initialize(&handle);
if (result != CS_OK) {
cfs_critical("cmap_initialize failed: %d", result);
private->handle = 0;
return -1;
}
result = cmap_initialize(&handle);
if (result != CS_OK) {
cfs_critical("cmap_initialize failed: %d", result);
private->handle = 0;
return -1;
}
result = cmap_context_set(handle, private);
if (result != CS_OK) {
cfs_critical("cmap_context_set failed: %d", result);
cmap_finalize(handle);
private->handle = 0;
return -1;
}
result = cmap_context_set(handle, private);
if (result != CS_OK) {
cfs_critical("cmap_context_set failed: %d", result);
cmap_finalize(handle);
private->handle = 0;
return -1;
}
private->handle = handle;
}
private->handle = handle;
}
result = cmap_track_add(
handle, "nodelist.node.",
CMAP_TRACK_PREFIX | CMAP_TRACK_ADD | CMAP_TRACK_DELETE | CMAP_TRACK_MODIFY, track_callback,
context, &private->track_nodelist_handle
);
result = cmap_track_add(handle, "nodelist.node.",
CMAP_TRACK_PREFIX|CMAP_TRACK_ADD|CMAP_TRACK_DELETE|CMAP_TRACK_MODIFY,
track_callback, context, &private->track_nodelist_handle);
if (result == CS_OK) {
result = cmap_track_add(
handle, "totem.config_version", CMAP_TRACK_ADD | CMAP_TRACK_DELETE | CMAP_TRACK_MODIFY,
track_callback, context, &private->track_version_handle
);
}
if (result == CS_OK) {
result = cmap_track_add(handle, "totem.config_version",
CMAP_TRACK_ADD|CMAP_TRACK_DELETE|CMAP_TRACK_MODIFY,
track_callback, context, &private->track_version_handle);
}
if (result == CS_ERR_LIBRARY || result == CS_ERR_BAD_HANDLE) {
cfs_critical("cmap_track_changes failed: %d - closing handle", result);
cmap_finalize(handle);
private->handle = 0;
return -1;
} else if (result != CS_OK) {
cfs_critical("cmap_track_changes failed: %d - trying again", result);
return -1;
}
if (result == CS_ERR_LIBRARY || result == CS_ERR_BAD_HANDLE) {
cfs_critical("cmap_track_changes failed: %d - closing handle", result);
cmap_finalize(handle);
private->handle = 0;
return -1;
} else if (result != CS_OK) {
cfs_critical("cmap_track_changes failed: %d - trying again", result);
return -1;
}
int cmap_fd = -1;
if ((result = cmap_fd_get(handle, &cmap_fd)) != CS_OK) {
cfs_critical("confdb_fd_get failed %d - trying again", result);
return -1;
}
int cmap_fd = -1;
if ((result = cmap_fd_get(handle, &cmap_fd)) != CS_OK) {
cfs_critical("confdb_fd_get failed %d - trying again", result);
return -1;
}
cmap_read_config(handle);
cmap_read_config(handle);
return cmap_fd;
return cmap_fd;
}
static gboolean
service_cmap_dispatch(
cfs_service_t *service,
gpointer context)
{
g_return_val_if_fail(service != NULL, FALSE);
g_return_val_if_fail(context != NULL, FALSE);
static gboolean service_cmap_dispatch(cfs_service_t *service, gpointer context) {
g_return_val_if_fail(service != NULL, FALSE);
g_return_val_if_fail(context != NULL, FALSE);
cs_private_t *private = (cs_private_t *)context;
cmap_handle_t handle = private->handle;
cs_private_t *private = (cs_private_t *)context;
cmap_handle_t handle = private->handle;
cs_error_t result;
cs_error_t result;
private->changes = FALSE;
int retries = 0;
private->changes = FALSE;
int retries = 0;
loop:
result = cmap_dispatch(handle, CS_DISPATCH_ALL);
if (result == CS_ERR_TRY_AGAIN) {
usleep(100000);
++retries;
if ((retries % 100) == 0)
cfs_message("cmap_dispatch retry %d", retries);
goto loop;
}
result = cmap_dispatch(handle, CS_DISPATCH_ALL);
if (result == CS_ERR_TRY_AGAIN) {
usleep(100000);
++retries;
if ((retries % 100) == 0)
cfs_message("cmap_dispatch retry %d", retries);
goto loop;
}
if (result == CS_OK || result == CS_ERR_TRY_AGAIN) {
if (result == CS_OK || result == CS_ERR_TRY_AGAIN) {
if (private->changes) {
result = cmap_read_config(handle);
if (private->changes) {
result = cmap_read_config(handle);
private->changes = FALSE;
private->changes = FALSE;
if (result == CS_OK)
return TRUE;
}
} else {
cfs_critical("cmap_dispatch failed: %d", result);
}
if (result == CS_OK)
return TRUE;
}
} else {
cfs_critical("cmap_dispatch failed: %d", result);
}
cmap_finalize(handle);
private->handle = 0;
return FALSE;
cmap_finalize(handle);
private->handle = 0;
return FALSE;
}
static cfs_service_callbacks_t cfs_confdb_callbacks = {
.cfs_service_initialize_fn = service_cmap_initialize,
.cfs_service_finalize_fn = service_cmap_finalize,
.cfs_service_dispatch_fn = service_cmap_dispatch,
.cfs_service_initialize_fn = service_cmap_initialize,
.cfs_service_finalize_fn = service_cmap_finalize,
.cfs_service_dispatch_fn = service_cmap_dispatch,
};
cfs_service_t *
service_confdb_new(void)
{
cfs_service_t *service;
cfs_service_t *service_confdb_new(void) {
cfs_service_t *service;
cs_private_t *private = g_new0(cs_private_t, 1);
if (!private)
return NULL;
cs_private_t *private = g_new0(cs_private_t, 1);
if (!private)
return NULL;
service = cfs_service_new(&cfs_confdb_callbacks, G_LOG_DOMAIN, private);
service = cfs_service_new(&cfs_confdb_callbacks, G_LOG_DOMAIN, private);
return service;
return service;
}
void
service_confdb_destroy(cfs_service_t *service)
{
g_return_if_fail(service != NULL);
void service_confdb_destroy(cfs_service_t *service) {
g_return_if_fail(service != NULL);
cs_private_t *private =
(cs_private_t *)cfs_service_get_context(service);
cs_private_t *private = (cs_private_t *)cfs_service_get_context(service);
g_free(private);
g_free(service);
g_free(private);
g_free(service);
}

View file

@ -27,7 +27,6 @@
cfs_service_t *service_confdb_new(void);
void service_confdb_destroy(
cfs_service_t *service);
void service_confdb_destroy(cfs_service_t *service);
#endif /* _PVE_CONFDB_H_ */

View file

@ -20,81 +20,75 @@
without starting pmxcfs/fuse
*/
#include <check.h>
#include <dirent.h>
#include <errno.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <errno.h>
#include <string.h>
#include <check.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include "cfs-utils.h"
#include "status.h"
#include "memdb.h"
#include "status.h"
cfs_t cfs = {
.debug = 0,
.nodename = "dummy",
.debug = 0,
.nodename = "dummy",
};
static memdb_t *memdb;
static void
usage_error(void)
{
fprintf(stderr, "Usage: create_pmxcfs_db /a/dir /a/filename.db\n");
exit(-1);
static void usage_error(void) {
fprintf(stderr, "Usage: create_pmxcfs_db /a/dir /a/filename.db\n");
exit(-1);
}
int
main(int argc, char *argv[])
{
cfs_status_init();
int main(int argc, char *argv[]) {
cfs_status_init();
if (argc != 3) {
usage_error();
}
if (argc != 3) {
usage_error();
}
const char *dir_name = argv[1];
const char *dbfile = argv[2];
const char *dir_name = argv[1];
const char *dbfile = argv[2];
DIR *dh = opendir(dir_name);
if (!dh) {
perror("unable to open dir");
exit(-1);
}
memdb = memdb_open(dbfile);
DIR *dh = opendir(dir_name);
if (!dh) {
perror("unable to open dir");
exit(-1);
}
memdb = memdb_open(dbfile);
struct dirent *de;
time_t ctime = time(NULL);
struct dirent *de;
time_t ctime = time(NULL);
while((de = readdir(dh))) {
if (de->d_type != DT_REG) {
continue;
}
while ((de = readdir(dh))) {
if (de->d_type != DT_REG) {
continue;
}
char *cdata = NULL;
gsize clen = 0;
char *fn = g_strdup_printf("%s/%s", dir_name, de->d_name);
if (g_file_get_contents(fn, &cdata, &clen, NULL)) {
//printf("FOUND %ld %s\n", clen, fn);
if (memdb_create(memdb, de->d_name, 0, ctime) != 0) {
fprintf(stderr, "memdb_create '%s' failed\n", de->d_name);
exit(-1);
}
if (memdb_write(memdb, de->d_name, 0, ctime, cdata, clen, 0, 1) != clen) {
fprintf(stderr, "memdb_write '%s' failed\n", de->d_name);
exit(-1);
}
char *cdata = NULL;
gsize clen = 0;
char *fn = g_strdup_printf("%s/%s", dir_name, de->d_name);
if (g_file_get_contents(fn, &cdata, &clen, NULL)) {
// printf("FOUND %ld %s\n", clen, fn);
if (memdb_create(memdb, de->d_name, 0, ctime) != 0) {
fprintf(stderr, "memdb_create '%s' failed\n", de->d_name);
exit(-1);
}
if (memdb_write(memdb, de->d_name, 0, ctime, cdata, clen, 0, 1) != clen) {
fprintf(stderr, "memdb_write '%s' failed\n", de->d_name);
exit(-1);
}
}
g_free(fn);
}
}
g_free(fn);
}
memdb_close(memdb);
memdb_close(memdb);
closedir(dh);
closedir(dh);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -29,42 +29,36 @@
#define DCDB_CPG_GROUP_NAME "pve_dcdb_v1"
/* please increase protocol version if you want to stop older nodes */
#define DCDB_PROTOCOL_VERSION 1
#define DCDB_VERIFY_TIME (60*60)
#define DCDB_VERIFY_TIME (60 * 60)
typedef enum {
DCDB_MESSAGE_CFS_WRITE = 1,
DCDB_MESSAGE_CFS_MKDIR = 2,
DCDB_MESSAGE_CFS_DELETE = 3,
DCDB_MESSAGE_CFS_RENAME = 4,
DCDB_MESSAGE_CFS_CREATE = 5,
DCDB_MESSAGE_CFS_MTIME = 6,
DCDB_MESSAGE_CFS_UNLOCK_REQUEST = 7,
DCDB_MESSAGE_CFS_UNLOCK = 8,
DCDB_MESSAGE_CFS_WRITE = 1,
DCDB_MESSAGE_CFS_MKDIR = 2,
DCDB_MESSAGE_CFS_DELETE = 3,
DCDB_MESSAGE_CFS_RENAME = 4,
DCDB_MESSAGE_CFS_CREATE = 5,
DCDB_MESSAGE_CFS_MTIME = 6,
DCDB_MESSAGE_CFS_UNLOCK_REQUEST = 7,
DCDB_MESSAGE_CFS_UNLOCK = 8,
} dcdb_message_t;
#define DCDB_VALID_MESSAGE_TYPE(mt) (mt >= DCDB_MESSAGE_CFS_WRITE && mt <= DCDB_MESSAGE_CFS_UNLOCK)
dfsm_t *dcdb_new(memdb_t *memdb);
void dcdb_sync_corosync_conf(
memdb_t *memdb,
gboolean notify_corosync);
void dcdb_sync_corosync_conf(memdb_t *memdb, gboolean notify_corosync);
int dcdb_send_fuse_message(
dfsm_t *dfsm,
dcdb_message_t msg_type,
const char *path,
const char *to,
const char *buf,
guint32 size,
guint32 offset,
guint32 flags);
dfsm_t *dfsm,
dcdb_message_t msg_type,
const char *path,
const char *to,
const char *buf,
guint32 size,
guint32 offset,
guint32 flags
);
void
dcdb_send_unlock(
dfsm_t *dfsm,
const char *path,
const guchar csum[32],
gboolean request);
void dcdb_send_unlock(dfsm_t *dfsm, const char *path, const guchar csum[32], gboolean request);
#endif /* _PVE_DCDB_H_ */

File diff suppressed because it is too large Load diff

View file

@ -29,18 +29,18 @@
typedef struct dfsm dfsm_t;
typedef struct {
uint32_t nodeid;
uint32_t pid;
gpointer state;
unsigned int state_len;
gboolean synced;
uint32_t nodeid;
uint32_t pid;
gpointer state;
unsigned int state_len;
gboolean synced;
} dfsm_node_info_t;
typedef struct {
int node_count;
gpointer data; /* app can use that */
dfsm_node_info_t *local;
dfsm_node_info_t nodes[];
int node_count;
gpointer data; /* app can use that */
dfsm_node_info_t *local;
dfsm_node_info_t nodes[];
} dfsm_sync_info_t;
/* return values:
@ -48,41 +48,34 @@ typedef struct {
* res > 0 ... OK, continue
*/
typedef int (*dfsm_deliver_fn_t)(
dfsm_t *dfsm,
gpointer data,
int *res_ptr,
uint32_t nodeid,
uint32_t pid,
uint16_t msgtype,
uint32_t msg_time,
const void *msg,
size_t msg_len);
dfsm_t *dfsm,
gpointer data,
int *res_ptr,
uint32_t nodeid,
uint32_t pid,
uint16_t msgtype,
uint32_t msg_time,
const void *msg,
size_t msg_len
);
typedef void (*dfsm_confchg_fn_t)(
dfsm_t *dfsm,
gpointer data,
const struct cpg_address *member_list,
size_t member_list_entries);
dfsm_t *dfsm, gpointer data, const struct cpg_address *member_list, size_t member_list_entries
);
/* return values:
* res == NULL ... serious error, leave group
* res != NULL ... OK, continue
*/
typedef gpointer (*dfsm_get_state_fn_t)(
dfsm_t *dfsm,
gpointer data,
unsigned int *res_len);
typedef gpointer (*dfsm_get_state_fn_t)(dfsm_t *dfsm, gpointer data, unsigned int *res_len);
typedef gboolean (*dfsm_checksum_fn_t)(
dfsm_t *dfsm,
gpointer data,
unsigned char *csum,
size_t csum_len);
dfsm_t *dfsm, gpointer data, unsigned char *csum, size_t csum_len
);
typedef int (*dfsm_process_state_update_fn_t)(
dfsm_t *dfsm,
gpointer data,
dfsm_sync_info_t *syncinfo);
dfsm_t *dfsm, gpointer data, dfsm_sync_info_t *syncinfo
);
typedef void (*dfsm_synced_fn_t)(dfsm_t *dfsm);
@ -91,111 +84,78 @@ typedef void (*dfsm_synced_fn_t)(dfsm_t *dfsm);
* res >= 0 ... OK
*/
typedef int (*dfsm_process_update_fn_t)(
dfsm_t *dfsm,
gpointer data,
dfsm_sync_info_t *syncinfo,
uint32_t nodeid,
uint32_t pid,
const void *msg,
size_t msg_len);
dfsm_t *dfsm,
gpointer data,
dfsm_sync_info_t *syncinfo,
uint32_t nodeid,
uint32_t pid,
const void *msg,
size_t msg_len
);
typedef struct {
dfsm_deliver_fn_t dfsm_deliver_fn;
dfsm_confchg_fn_t dfsm_confchg_fn;
dfsm_get_state_fn_t dfsm_get_state_fn;
dfsm_process_state_update_fn_t dfsm_process_state_update_fn;
dfsm_process_state_update_fn_t dfsm_commit_fn;
dfsm_process_state_update_fn_t dfsm_cleanup_fn;
dfsm_process_update_fn_t dfsm_process_update_fn;
dfsm_checksum_fn_t dfsm_checksum_fn;
dfsm_synced_fn_t dfsm_synced_fn;
dfsm_deliver_fn_t dfsm_deliver_fn;
dfsm_confchg_fn_t dfsm_confchg_fn;
dfsm_get_state_fn_t dfsm_get_state_fn;
dfsm_process_state_update_fn_t dfsm_process_state_update_fn;
dfsm_process_state_update_fn_t dfsm_commit_fn;
dfsm_process_state_update_fn_t dfsm_cleanup_fn;
dfsm_process_update_fn_t dfsm_process_update_fn;
dfsm_checksum_fn_t dfsm_checksum_fn;
dfsm_synced_fn_t dfsm_synced_fn;
} dfsm_callbacks_t;
typedef struct {
uint64_t msgcount;
int result; /* we only have integer results for now */
int processed;
uint64_t msgcount;
int result; /* we only have integer results for now */
int processed;
} dfsm_result_t;
dfsm_t *
dfsm_new(
gpointer data,
const char *group_name,
const char *log_domain,
guint32 protocol_version,
dfsm_callbacks_t *callbacks);
dfsm_t *dfsm_new(
gpointer data,
const char *group_name,
const char *log_domain,
guint32 protocol_version,
dfsm_callbacks_t *callbacks
);
void
dfsm_destroy(dfsm_t *dfsm);
void dfsm_destroy(dfsm_t *dfsm);
cs_error_t
dfsm_initialize(dfsm_t *dfsm, int *fd);
cs_error_t dfsm_initialize(dfsm_t *dfsm, int *fd);
gboolean
dfsm_finalize(dfsm_t *dfsm);
gboolean dfsm_finalize(dfsm_t *dfsm);
cs_error_t
dfsm_join(dfsm_t *dfsm);
cs_error_t dfsm_join(dfsm_t *dfsm);
cs_error_t
dfsm_leave(dfsm_t *dfsm);
cs_error_t dfsm_leave(dfsm_t *dfsm);
cs_error_t
dfsm_dispatch(
dfsm_t *dfsm,
cs_dispatch_flags_t dispatch_types);
cs_error_t dfsm_dispatch(dfsm_t *dfsm, cs_dispatch_flags_t dispatch_types);
gboolean
dfsm_restartable(dfsm_t *dfsm);
gboolean dfsm_restartable(dfsm_t *dfsm);
gboolean
dfsm_is_initialized(dfsm_t *dfsm);
gboolean dfsm_is_initialized(dfsm_t *dfsm);
void
dfsm_set_errormode(dfsm_t *dfsm);
void dfsm_set_errormode(dfsm_t *dfsm);
cs_error_t
dfsm_send_message(
dfsm_t *dfsm,
uint16_t msgtype,
struct iovec *iov,
int len);
cs_error_t dfsm_send_message(dfsm_t *dfsm, uint16_t msgtype, struct iovec *iov, int len);
/* only call this from another thread - else you get blocked forever */
cs_error_t
dfsm_send_message_sync(
dfsm_t *dfsm,
uint16_t msgtype,
struct iovec *iov,
int len,
dfsm_result_t *rp);
cs_error_t dfsm_send_message_sync(
dfsm_t *dfsm, uint16_t msgtype, struct iovec *iov, int len, dfsm_result_t *rp
);
cs_error_t
dfsm_send_update(
dfsm_t *dfsm,
struct iovec *iov,
unsigned int len);
cs_error_t dfsm_send_update(dfsm_t *dfsm, struct iovec *iov, unsigned int len);
cs_error_t
dfsm_send_update_complete(dfsm_t *dfsm);
cs_error_t dfsm_send_update_complete(dfsm_t *dfsm);
gboolean
dfsm_lowest_nodeid(dfsm_t *dfsm);
gboolean dfsm_lowest_nodeid(dfsm_t *dfsm);
gboolean
dfsm_nodeid_is_local(
dfsm_t *dfsm,
uint32_t nodeid,
uint32_t pid);
gboolean dfsm_nodeid_is_local(dfsm_t *dfsm, uint32_t nodeid, uint32_t pid);
cs_error_t
dfsm_verify_request(dfsm_t *dfsm);
cs_error_t dfsm_verify_request(dfsm_t *dfsm);
cfs_service_t *
service_dfsm_new(dfsm_t *dfsm);
void
service_dfsm_destroy(cfs_service_t *service);
cfs_service_t *service_dfsm_new(dfsm_t *dfsm);
void service_dfsm_destroy(cfs_service_t *service);
#endif /* _PVE_DFSM_H_ */

File diff suppressed because it is too large Load diff

View file

@ -22,104 +22,73 @@
#define _PVE_LOGGER_H_
#define CLOG_MAX_ENTRY_SIZE 4096
#define CLOG_DEFAULT_SIZE (8192*16)
#define CLOG_DEFAULT_SIZE (8192 * 16)
typedef struct clog_base clog_base_t;
typedef struct clusterlog clusterlog_t;
typedef struct {
uint32_t prev;
uint32_t next;
uint32_t uid; /* unique id */
uint32_t time;
uint64_t node_digest;
uint64_t ident_digest;
uint32_t pid;
uint8_t priority;
uint8_t node_len;
uint8_t ident_len;
uint8_t tag_len;
uint32_t msg_len;
char data[];
uint32_t prev;
uint32_t next;
uint32_t uid; /* unique id */
uint32_t time;
uint64_t node_digest;
uint64_t ident_digest;
uint32_t pid;
uint8_t priority;
uint8_t node_len;
uint8_t ident_len;
uint8_t tag_len;
uint32_t msg_len;
char data[];
} clog_entry_t;
clusterlog_t *
clusterlog_new(void);
clusterlog_t *clusterlog_new(void);
void
clusterlog_destroy(clusterlog_t *cl);
void clusterlog_destroy(clusterlog_t *cl);
gpointer
clusterlog_get_state(
clusterlog_t *cl,
unsigned int *res_len);
gpointer clusterlog_get_state(clusterlog_t *cl, unsigned int *res_len);
void
clusterlog_add(
clusterlog_t *cl,
const char *ident,
const char *tag,
uint32_t pid,
uint8_t priority,
const gchar *format,
...) G_GNUC_PRINTF (6, 7);
void clusterlog_add(
clusterlog_t *cl,
const char *ident,
const char *tag,
uint32_t pid,
uint8_t priority,
const gchar *format,
...
) G_GNUC_PRINTF(6, 7);
void
clusterlog_insert(
clusterlog_t *cl,
const clog_entry_t *entry);
void clusterlog_insert(clusterlog_t *cl, const clog_entry_t *entry);
void
clusterlog_dump(
clusterlog_t *cl,
GString *str,
const char *user,
guint max_entries);
void clusterlog_dump(clusterlog_t *cl, GString *str, const char *user, guint max_entries);
clog_base_t *
clusterlog_merge(
clusterlog_t *cl,
clog_base_t **clog,
int count,
int local_index);
clog_base_t *clusterlog_merge(clusterlog_t *cl, clog_base_t **clog, int count, int local_index);
clog_base_t *
clog_new(uint32_t size);
clog_base_t *clog_new(uint32_t size);
uint32_t
clog_size(clog_base_t *clog);
uint32_t clog_size(clog_base_t *clog);
void
clog_dump(clog_base_t *clog);
void clog_dump(clog_base_t *clog);
void
clog_dump_json(
clog_base_t *clog,
GString *str,
const char *ident,
guint max_entries);
void clog_dump_json(clog_base_t *clog, GString *str, const char *ident, guint max_entries);
clog_base_t *
clog_sort(clog_base_t *clog);
clog_base_t *clog_sort(clog_base_t *clog);
uint32_t
clog_pack(
clog_entry_t *buffer,
const char *node,
const char *ident,
const char *tag,
uint32_t pid,
time_t logtime,
uint8_t priority,
const char *msg);
uint32_t clog_pack(
clog_entry_t *buffer,
const char *node,
const char *ident,
const char *tag,
uint32_t pid,
time_t logtime,
uint8_t priority,
const char *msg
);
uint32_t
clog_entry_size(const clog_entry_t *entry);
uint32_t clog_entry_size(const clog_entry_t *entry);
void
clog_copy(
clog_base_t *clog,
const clog_entry_t *entry);
void clog_copy(clog_base_t *clog, const clog_entry_t *entry);
#endif /* _PVE_LOGGER_H_ */

View file

@ -19,46 +19,47 @@
*/
#define _XOPEN_SOURCE /* glibc2 needs this */
#include <time.h> /* for strptime */
#include <time.h> /* for strptime */
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <sys/types.h>
#include <sys/syslog.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>
#include <sys/syslog.h>
#include <sys/types.h>
#include <unistd.h>
#include "cfs-utils.h"
#include "logger.h"
cfs_t cfs = {
.debug = 0,
.nodename = "testnode",
.debug = 0,
.nodename = "testnode",
};
int main(void) {
int
main(void)
{
uint32_t pid = getpid();
uint32_t pid = getpid();
#if 1
clusterlog_t *cl3 = clusterlog_new();
clusterlog_t *cl3 = clusterlog_new();
clog_entry_t *entry = (clog_entry_t *)alloca(CLOG_MAX_ENTRY_SIZE);
clog_pack(entry, cfs.nodename, "root", "cluster", pid, time(NULL), LOG_INFO, "starting cluster log");
clusterlog_insert(cl3, entry);
clog_entry_t *entry = (clog_entry_t *)alloca(CLOG_MAX_ENTRY_SIZE);
clog_pack(
entry, cfs.nodename, "root", "cluster", pid, time(NULL), LOG_INFO, "starting cluster log"
);
clusterlog_insert(cl3, entry);
for (int i = 0; i < 5000; i++) {
clusterlog_add(cl3, "user1", "TESTDOMAIN1", pid, LOG_INFO,
"test user1 ä message asdasd d dsgfdfgdgdg dgg dgdg %d", i);
}
for (int i = 0; i < 5000; i++) {
clusterlog_add(
cl3, "user1", "TESTDOMAIN1", pid, LOG_INFO,
"test user1 ä message asdasd d dsgfdfgdgdg dgg dgdg %d", i
);
}
#if 0
for (int i = 0; i < 5000; i++) {
@ -69,22 +70,21 @@ main(void)
}
#endif
//clog_dump(cl3->base);
// clog_dump(cl3->base);
clusterlog_destroy(cl3);
clusterlog_destroy(cl3);
exit(0);
exit(0);
#endif
clusterlog_t *cl1 = clusterlog_new();
clusterlog_t *cl1 = clusterlog_new();
for (int i = 0; i < 5; i++) {
clusterlog_add(cl1, "user1", "TESTDOMAIN1", pid, LOG_INFO,
"test user1 message asdasd %d", i);
}
for (int i = 0; i < 5; i++) {
clusterlog_add(
cl1, "user1", "TESTDOMAIN1", pid, LOG_INFO, "test user1 message asdasd %d", i
);
}
#if 0
for (int i = 0; i < 5; i++) {
@ -93,13 +93,14 @@ main(void)
}
#endif
clusterlog_t *cl2 = clusterlog_new();
clusterlog_t *cl2 = clusterlog_new();
#if 1
for (int i = 0; i < 5; i++) {
clusterlog_add(cl2, "user3", "TESTDOMAIN2", pid, LOG_INFO,
"test user3 message asdasd %d", i);
}
for (int i = 0; i < 5; i++) {
clusterlog_add(
cl2, "user3", "TESTDOMAIN2", pid, LOG_INFO, "test user3 message asdasd %d", i
);
}
#endif
#if 0

View file

@ -19,38 +19,38 @@
*/
#define _XOPEN_SOURCE /* glibc2 needs this */
#include <time.h> /* for strptime */
#include <time.h> /* for strptime */
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <sys/types.h>
#include <sys/syslog.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>
#include <sys/syslog.h>
#include <sys/types.h>
#include <unistd.h>
#include "cfs-utils.h"
#include "logger.h"
struct clog_base {
uint32_t size;
uint32_t cpos;
char data[];
uint32_t size;
uint32_t cpos;
char data[];
};
struct clusterlog {
GHashTable *dedup;
GMutex mutex;
clog_base_t *base;
GHashTable *dedup;
GMutex mutex;
clog_base_t *base;
};
cfs_t cfs = {
.debug = 0,
.nodename = "testnode",
.debug = 0,
.nodename = "testnode",
};
void get_state(clusterlog_t *cl) {
@ -58,46 +58,56 @@ void get_state(clusterlog_t *cl) {
clusterlog_get_state(cl, &res_len);
}
void insert(clusterlog_t *cl) {
uint32_t pid = getpid();
clog_entry_t *entry = (clog_entry_t *)alloca(CLOG_MAX_ENTRY_SIZE);
clog_pack(entry, cfs.nodename, "root", "cluster", pid, time(NULL), LOG_INFO, "short");
clusterlog_insert(cl, entry);
uint32_t pid = getpid();
clog_entry_t *entry = (clog_entry_t *)alloca(CLOG_MAX_ENTRY_SIZE);
clog_pack(entry, cfs.nodename, "root", "cluster", pid, time(NULL), LOG_INFO, "short");
clusterlog_insert(cl, entry);
}
void insert2(clusterlog_t *cl) {
uint32_t pid = getpid();
clog_entry_t *entry = (clog_entry_t *)alloca(CLOG_MAX_ENTRY_SIZE);
clog_pack(entry, cfs.nodename, "root", "cluster", pid, time(NULL), LOG_INFO, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
clusterlog_insert(cl, entry);
uint32_t pid = getpid();
clog_entry_t *entry = (clog_entry_t *)alloca(CLOG_MAX_ENTRY_SIZE);
clog_pack(
entry, cfs.nodename, "root", "cluster", pid, time(NULL), LOG_INFO,
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaa"
);
clusterlog_insert(cl, entry);
}
int
main(void)
{
uint32_t pid = getpid();
int main(void) {
uint32_t pid = getpid();
clusterlog_t *cl3 = clusterlog_new();
clusterlog_t *cl3 = clusterlog_new();
clog_entry_t *entry = (clog_entry_t *)alloca(CLOG_MAX_ENTRY_SIZE);
clog_pack(entry, cfs.nodename, "root", "cluster", pid, time(NULL), LOG_INFO, "starting cluster log");
clusterlog_insert(cl3, entry);
clog_entry_t *entry = (clog_entry_t *)alloca(CLOG_MAX_ENTRY_SIZE);
clog_pack(
entry, cfs.nodename, "root", "cluster", pid, time(NULL), LOG_INFO, "starting cluster log"
);
clusterlog_insert(cl3, entry);
for (int i = 0; i < 184; i++) {
insert2(cl3);
}
for (int i = 0; i < 184; i++) {
insert2(cl3);
}
for (int i = 0; i < 1629; i++) {
insert(cl3);
}
for (int i = 0; i < 1629; i++) {
insert(cl3);
}
GString *outbuf = g_string_new(NULL);
GString *outbuf = g_string_new(NULL);
// all of these segfault if they don't handle wrap-arounds pointing to already overwritten entries
clusterlog_dump(cl3, outbuf, NULL, 8192);
clog_dump(cl3->base);
get_state(cl3);
// all of these segfault if they don't handle wrap-arounds pointing to already overwritten
// entries
clusterlog_dump(cl3, outbuf, NULL, 8192);
clog_dump(cl3->base);
get_state(cl3);
clusterlog_destroy(cl3);
clusterlog_destroy(cl3);
}

View file

@ -24,355 +24,319 @@
#include <config.h>
#endif /* HAVE_CONFIG_H */
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <utime.h>
#include <sys/stat.h>
#include <glib.h>
#include <syslog.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <syslog.h>
#include <unistd.h>
#include <utime.h>
#include "cfs-utils.h"
#include "loop.h"
struct cfs_service {
qb_loop_t *qbloop;
const char *log_domain;
cfs_service_callbacks_t *callbacks;
gboolean restartable;
gpointer context;
gboolean initialized;
int errcount;
time_t last_init;
enum qb_loop_priority priority;
time_t period;
time_t last_timeout;
qb_loop_t *qbloop;
const char *log_domain;
cfs_service_callbacks_t *callbacks;
gboolean restartable;
gpointer context;
gboolean initialized;
int errcount;
time_t last_init;
enum qb_loop_priority priority;
time_t period;
time_t last_timeout;
};
struct cfs_loop {
GThread *worker;
gboolean server_started;
gboolean stop_worker_flag;
GCond server_started_cond;
GCond server_stopped_cond;
GMutex server_started_mutex;
qb_loop_t *qbloop;
struct fuse *fuse;
GList *services;
GThread *worker;
gboolean server_started;
gboolean stop_worker_flag;
GCond server_started_cond;
GCond server_stopped_cond;
GMutex server_started_mutex;
qb_loop_t *qbloop;
struct fuse *fuse;
GList *services;
};
gboolean
cfs_service_set_timer(
cfs_service_t *service,
time_t period)
{
g_return_val_if_fail(service != NULL, FALSE);
gboolean cfs_service_set_timer(cfs_service_t *service, time_t period) {
g_return_val_if_fail(service != NULL, FALSE);
service->period = period;
service->period = period;
return TRUE;
return TRUE;
}
gpointer
cfs_service_get_context(cfs_service_t *service)
{
g_return_val_if_fail(service != NULL, NULL);
gpointer cfs_service_get_context(cfs_service_t *service) {
g_return_val_if_fail(service != NULL, NULL);
return service->context;
return service->context;
}
void
cfs_service_set_restartable(
cfs_service_t *service,
gboolean restartable)
{
g_return_if_fail(service != NULL);
void cfs_service_set_restartable(cfs_service_t *service, gboolean restartable) {
g_return_if_fail(service != NULL);
service->restartable = restartable;
service->restartable = restartable;
}
cfs_service_t *
cfs_service_new(
cfs_service_callbacks_t *callbacks,
const char *log_domain,
gpointer context)
{
g_return_val_if_fail(callbacks != NULL, NULL);
g_return_val_if_fail(callbacks->cfs_service_initialize_fn != NULL, NULL);
g_return_val_if_fail(callbacks->cfs_service_finalize_fn != NULL, NULL);
g_return_val_if_fail(callbacks->cfs_service_dispatch_fn != NULL, NULL);
cfs_service_new(cfs_service_callbacks_t *callbacks, const char *log_domain, gpointer context) {
g_return_val_if_fail(callbacks != NULL, NULL);
g_return_val_if_fail(callbacks->cfs_service_initialize_fn != NULL, NULL);
g_return_val_if_fail(callbacks->cfs_service_finalize_fn != NULL, NULL);
g_return_val_if_fail(callbacks->cfs_service_dispatch_fn != NULL, NULL);
cfs_service_t *service = g_new0(cfs_service_t, 1);
if(!service)
return NULL;
if (log_domain)
service->log_domain = log_domain;
else
service->log_domain = G_LOG_DOMAIN;
cfs_service_t *service = g_new0(cfs_service_t, 1);
if (!service)
return NULL;
service->callbacks = callbacks;
if (log_domain)
service->log_domain = log_domain;
else
service->log_domain = G_LOG_DOMAIN;
service->restartable = TRUE;
service->callbacks = callbacks;
service->context = context;
service->restartable = TRUE;
return service;
service->context = context;
return service;
}
cfs_loop_t *
cfs_loop_new(struct fuse *fuse)
{
cfs_loop_t *loop = g_new0(cfs_loop_t, 1);
cfs_loop_t *cfs_loop_new(struct fuse *fuse) {
cfs_loop_t *loop = g_new0(cfs_loop_t, 1);
g_mutex_init(&loop->server_started_mutex);
g_cond_init(&loop->server_started_cond);
g_cond_init(&loop->server_stopped_cond);
if (!(loop->qbloop = qb_loop_create())) {
cfs_critical("cant create event loop");
g_free(loop);
return NULL;
}
g_mutex_init(&loop->server_started_mutex);
g_cond_init(&loop->server_started_cond);
g_cond_init(&loop->server_stopped_cond);
loop->fuse = fuse;
if (!(loop->qbloop = qb_loop_create())) {
cfs_critical("cant create event loop");
g_free(loop);
return NULL;
}
return loop;
loop->fuse = fuse;
return loop;
}
void
cfs_loop_destroy(cfs_loop_t *loop)
{
g_return_if_fail(loop != NULL);
void cfs_loop_destroy(cfs_loop_t *loop) {
g_return_if_fail(loop != NULL);
if (loop->qbloop)
qb_loop_destroy(loop->qbloop);
if (loop->qbloop)
qb_loop_destroy(loop->qbloop);
if(loop->services)
g_list_free(loop->services);
if (loop->services)
g_list_free(loop->services);
g_mutex_clear(&loop->server_started_mutex);
g_cond_clear(&loop->server_started_cond);
g_cond_clear(&loop->server_stopped_cond);
g_mutex_clear(&loop->server_started_mutex);
g_cond_clear(&loop->server_started_cond);
g_cond_clear(&loop->server_stopped_cond);
g_free(loop);
g_free(loop);
}
gboolean
cfs_loop_add_service(
cfs_loop_t *loop,
cfs_service_t *service,
enum qb_loop_priority priority)
{
g_return_val_if_fail(loop != NULL, FALSE);
g_return_val_if_fail(service != NULL, FALSE);
g_return_val_if_fail(service->log_domain != NULL, FALSE);
gboolean
cfs_loop_add_service(cfs_loop_t *loop, cfs_service_t *service, enum qb_loop_priority priority) {
g_return_val_if_fail(loop != NULL, FALSE);
g_return_val_if_fail(service != NULL, FALSE);
g_return_val_if_fail(service->log_domain != NULL, FALSE);
service->priority = priority;
service->qbloop = loop->qbloop;
service->priority = priority;
service->qbloop = loop->qbloop;
loop->services = g_list_append(loop->services, service);
loop->services = g_list_append(loop->services, service);
return TRUE;
return TRUE;
}
static int32_t
poll_dispatch_fn(
int32_t fd,
int32_t revents,
void *data)
{
cfs_service_t *service = (cfs_service_t *)data;
static int32_t poll_dispatch_fn(int32_t fd, int32_t revents, void *data) {
cfs_service_t *service = (cfs_service_t *)data;
if (!service->callbacks->cfs_service_dispatch_fn(service, service->context)) {
qb_loop_poll_del(service->qbloop, fd);
service->initialized = FALSE;
service->errcount = 0;
if (!service->callbacks->cfs_service_dispatch_fn(service, service->context)) {
qb_loop_poll_del(service->qbloop, fd);
service->initialized = FALSE;
service->errcount = 0;
if (!service->restartable)
service->callbacks->cfs_service_finalize_fn(service, service->context);
return -1;
}
if (!service->restartable)
service->callbacks->cfs_service_finalize_fn(service, service->context);
return 0;
return -1;
}
return 0;
}
static void
service_timer_job(void *data)
{
g_return_if_fail(data != NULL);
static void service_timer_job(void *data) {
g_return_if_fail(data != NULL);
cfs_loop_t *loop = (cfs_loop_t *)data;
qb_loop_t *qbloop = loop->qbloop;
cfs_loop_t *loop = (cfs_loop_t *)data;
qb_loop_t *qbloop = loop->qbloop;
gboolean terminate = FALSE;
g_mutex_lock (&loop->server_started_mutex);
gboolean terminate = FALSE;
if (loop->stop_worker_flag) {
cfs_debug ("got terminate request");
qb_loop_stop(qbloop);
loop->server_started = 0;
g_cond_signal (&loop->server_stopped_cond);
terminate = TRUE;
} else if (!loop->server_started) {
loop->server_started = 1;
g_cond_signal (&loop->server_started_cond);
}
g_mutex_unlock (&loop->server_started_mutex);
g_mutex_lock(&loop->server_started_mutex);
if (terminate)
return;
GList *l = loop->services;
while (l) {
cfs_service_t *service = (cfs_service_t *)l->data;
l = g_list_next(l);
if (loop->stop_worker_flag) {
cfs_debug("got terminate request");
qb_loop_stop(qbloop);
loop->server_started = 0;
g_cond_signal(&loop->server_stopped_cond);
terminate = TRUE;
} else if (!loop->server_started) {
loop->server_started = 1;
g_cond_signal(&loop->server_started_cond);
}
if (!service->initialized)
continue;
g_mutex_unlock(&loop->server_started_mutex);
time_t ctime = time(NULL);
if (service->period && service->callbacks->cfs_service_timer_fn &&
((ctime - service->last_timeout) >= service->period)) {
service->last_timeout = ctime;
service->callbacks->cfs_service_timer_fn(service, service->context);
}
}
if (terminate)
return;
qb_loop_timer_handle th;
qb_loop_timer_add(qbloop, QB_LOOP_LOW, 1000000000, data, service_timer_job, &th);
GList *l = loop->services;
while (l) {
cfs_service_t *service = (cfs_service_t *)l->data;
l = g_list_next(l);
if (!service->initialized)
continue;
time_t ctime = time(NULL);
if (service->period && service->callbacks->cfs_service_timer_fn &&
((ctime - service->last_timeout) >= service->period)) {
service->last_timeout = ctime;
service->callbacks->cfs_service_timer_fn(service, service->context);
}
}
qb_loop_timer_handle th;
qb_loop_timer_add(qbloop, QB_LOOP_LOW, 1000000000, data, service_timer_job, &th);
}
static void
service_start_job(void *data)
{
g_return_if_fail(data != NULL);
static void service_start_job(void *data) {
g_return_if_fail(data != NULL);
cfs_loop_t *loop = (cfs_loop_t *)data;
qb_loop_t *qbloop = loop->qbloop;
cfs_loop_t *loop = (cfs_loop_t *)data;
qb_loop_t *qbloop = loop->qbloop;
gboolean terminate = FALSE;
g_mutex_lock (&loop->server_started_mutex);
terminate = loop->stop_worker_flag;
g_mutex_unlock (&loop->server_started_mutex);
gboolean terminate = FALSE;
g_mutex_lock(&loop->server_started_mutex);
terminate = loop->stop_worker_flag;
g_mutex_unlock(&loop->server_started_mutex);
if (terminate)
return;
if (terminate)
return;
GList *l = loop->services;
time_t ctime = time(NULL);
GList *l = loop->services;
time_t ctime = time(NULL);
while (l) {
cfs_service_t *service = (cfs_service_t *)l->data;
l = g_list_next(l);
while (l) {
cfs_service_t *service = (cfs_service_t *)l->data;
l = g_list_next(l);
if (service->restartable && !service->initialized &&
((ctime - service->last_init) > 5)) {
int fd = service->callbacks->cfs_service_initialize_fn(service, service->context);
service->last_init = ctime;
if (service->restartable && !service->initialized && ((ctime - service->last_init) > 5)) {
int fd = service->callbacks->cfs_service_initialize_fn(service, service->context);
service->last_init = ctime;
if (fd >= 0) {
service->initialized = TRUE;
service->errcount = 0;
if (fd >= 0) {
service->initialized = TRUE;
service->errcount = 0;
int res;
if ((res = qb_loop_poll_add(qbloop, service->priority, fd, POLLIN,
service, poll_dispatch_fn)) != 0) {
cfs_critical("qb_loop_poll_add failed: %s - disabling service",
g_strerror(-res));
service->initialized = FALSE;
service->restartable = FALSE;
service->callbacks->cfs_service_finalize_fn(service, service->context);
}
} else {
if (!service->errcount)
cfs_dom_critical(service->log_domain, "can't initialize service");
service->errcount++;
}
}
}
int res;
if ((res = qb_loop_poll_add(
qbloop, service->priority, fd, POLLIN, service, poll_dispatch_fn
)) != 0) {
cfs_critical(
"qb_loop_poll_add failed: %s - disabling service", g_strerror(-res)
);
service->initialized = FALSE;
service->restartable = FALSE;
service->callbacks->cfs_service_finalize_fn(service, service->context);
}
} else {
if (!service->errcount)
cfs_dom_critical(service->log_domain, "can't initialize service");
service->errcount++;
}
}
}
qb_loop_timer_handle th;
qb_loop_timer_add(qbloop, QB_LOOP_LOW, 1000000000, data, service_start_job, &th);
qb_loop_timer_handle th;
qb_loop_timer_add(qbloop, QB_LOOP_LOW, 1000000000, data, service_start_job, &th);
}
static gpointer
cfs_loop_worker_thread(gpointer data)
{
g_return_val_if_fail(data != NULL, NULL);
static gpointer cfs_loop_worker_thread(gpointer data) {
g_return_val_if_fail(data != NULL, NULL);
cfs_loop_t *loop = (cfs_loop_t *)data;
qb_loop_t *qbloop = loop->qbloop;
cfs_loop_t *loop = (cfs_loop_t *)data;
qb_loop_t *qbloop = loop->qbloop;
GList *l;
time_t ctime = time(NULL);
l = loop->services;
while (l) {
cfs_service_t *service = (cfs_service_t *)l->data;
l = g_list_next(l);
service->last_timeout = ctime;
}
GList *l;
time_t ctime = time(NULL);
l = loop->services;
while (l) {
cfs_service_t *service = (cfs_service_t *)l->data;
l = g_list_next(l);
service->last_timeout = ctime;
}
qb_loop_timer_handle th;
qb_loop_timer_add(qbloop, QB_LOOP_LOW, 10000000, loop, service_start_job, &th);
qb_loop_timer_handle th;
qb_loop_timer_add(qbloop, QB_LOOP_LOW, 10000000, loop, service_start_job, &th);
qb_loop_timer_add(qbloop, QB_LOOP_LOW, 1000000000, loop, service_timer_job, &th);
qb_loop_timer_add(qbloop, QB_LOOP_LOW, 1000000000, loop, service_timer_job, &th);
cfs_debug("start loop");
qb_loop_run(qbloop);
cfs_debug("start loop");
cfs_debug("end loop");
qb_loop_run(qbloop);
l = loop->services;
while (l) {
cfs_service_t *service = (cfs_service_t *)l->data;
l = g_list_next(l);
service->callbacks->cfs_service_finalize_fn(service, service->context);
}
cfs_debug("end loop");
return NULL;
l = loop->services;
while (l) {
cfs_service_t *service = (cfs_service_t *)l->data;
l = g_list_next(l);
service->callbacks->cfs_service_finalize_fn(service, service->context);
}
return NULL;
}
gboolean
cfs_loop_start_worker(cfs_loop_t *loop)
{
g_return_val_if_fail(loop != NULL, FALSE);
gboolean cfs_loop_start_worker(cfs_loop_t *loop) {
g_return_val_if_fail(loop != NULL, FALSE);
loop->worker = g_thread_new("cfs_loop", cfs_loop_worker_thread, loop);
g_mutex_lock (&loop->server_started_mutex);
while (!loop->server_started)
g_cond_wait (&loop->server_started_cond, &loop->server_started_mutex);
g_mutex_unlock (&loop->server_started_mutex);
cfs_debug("worker started");
return TRUE;
loop->worker = g_thread_new("cfs_loop", cfs_loop_worker_thread, loop);
g_mutex_lock(&loop->server_started_mutex);
while (!loop->server_started)
g_cond_wait(&loop->server_started_cond, &loop->server_started_mutex);
g_mutex_unlock(&loop->server_started_mutex);
cfs_debug("worker started");
return TRUE;
}
void
cfs_loop_stop_worker(cfs_loop_t *loop)
{
g_return_if_fail(loop != NULL);
void cfs_loop_stop_worker(cfs_loop_t *loop) {
g_return_if_fail(loop != NULL);
cfs_debug("cfs_loop_stop_worker");
cfs_debug("cfs_loop_stop_worker");
g_mutex_lock (&loop->server_started_mutex);
loop->stop_worker_flag = TRUE;
while (loop->server_started)
g_cond_wait (&loop->server_stopped_cond, &loop->server_started_mutex);
g_mutex_unlock (&loop->server_started_mutex);
g_mutex_lock(&loop->server_started_mutex);
loop->stop_worker_flag = TRUE;
while (loop->server_started)
g_cond_wait(&loop->server_stopped_cond, &loop->server_started_mutex);
g_mutex_unlock(&loop->server_started_mutex);
if (loop->worker) {
g_thread_join(loop->worker);
loop->worker = NULL;
}
if (loop->worker) {
g_thread_join(loop->worker);
loop->worker = NULL;
}
}

View file

@ -23,70 +23,49 @@
#define FUSE_USE_VERSION 26
#include <glib.h>
#include <fuse.h>
#include <glib.h>
#include <qb/qbdefs.h>
#include <qb/qbutil.h>
#include <qb/qbloop.h>
#include <qb/qbutil.h>
typedef struct cfs_loop cfs_loop_t;
typedef struct cfs_service cfs_service_t;
typedef int (*cfs_service_initialize_fn_t)(
cfs_service_t *service,
gpointer context);
typedef int (*cfs_service_initialize_fn_t)(cfs_service_t *service, gpointer context);
typedef gboolean (*cfs_service_finalize_fn_t)(
cfs_service_t *service,
gpointer context);
typedef gboolean (*cfs_service_finalize_fn_t)(cfs_service_t *service, gpointer context);
typedef gboolean (*cfs_service_dispatch_fn_t)(
cfs_service_t *service,
gpointer context);
typedef gboolean (*cfs_service_dispatch_fn_t)(cfs_service_t *service, gpointer context);
typedef void (*cfs_service_timer_fn_t)(
cfs_service_t *service,
gpointer context);
typedef void (*cfs_service_timer_fn_t)(cfs_service_t *service, gpointer context);
typedef struct {
cfs_service_initialize_fn_t cfs_service_initialize_fn;
cfs_service_finalize_fn_t cfs_service_finalize_fn;
cfs_service_dispatch_fn_t cfs_service_dispatch_fn;
cfs_service_timer_fn_t cfs_service_timer_fn;
cfs_service_initialize_fn_t cfs_service_initialize_fn;
cfs_service_finalize_fn_t cfs_service_finalize_fn;
cfs_service_dispatch_fn_t cfs_service_dispatch_fn;
cfs_service_timer_fn_t cfs_service_timer_fn;
} cfs_service_callbacks_t;
cfs_service_t *cfs_service_new(
cfs_service_callbacks_t *callbacks,
const char *log_domain,
gpointer context);
cfs_service_t *
cfs_service_new(cfs_service_callbacks_t *callbacks, const char *log_domain, gpointer context);
gpointer cfs_service_get_context(
cfs_service_t *service);
gpointer cfs_service_get_context(cfs_service_t *service);
gboolean cfs_service_set_timer(
cfs_service_t *service,
time_t period);
gboolean cfs_service_set_timer(cfs_service_t *service, time_t period);
void cfs_service_set_restartable(
cfs_service_t *service,
gboolean restartable);
void cfs_service_set_restartable(cfs_service_t *service, gboolean restartable);
cfs_loop_t *cfs_loop_new(struct fuse *fuse);
void cfs_loop_destroy(
cfs_loop_t *loop);
void cfs_loop_destroy(cfs_loop_t *loop);
gboolean cfs_loop_add_service(
cfs_loop_t *loop,
cfs_service_t *service,
enum qb_loop_priority priority);
gboolean
cfs_loop_add_service(cfs_loop_t *loop, cfs_service_t *service, enum qb_loop_priority priority);
gboolean cfs_loop_start_worker(
cfs_loop_t *loop);
void cfs_loop_stop_worker(
cfs_loop_t *loop);
gboolean cfs_loop_start_worker(cfs_loop_t *loop);
void cfs_loop_stop_worker(cfs_loop_t *loop);
#endif /* _PVE_LOOP_H_ */

File diff suppressed because it is too large Load diff

View file

@ -21,240 +21,156 @@
#ifndef _PVE_MEMDB_H_
#define _PVE_MEMDB_H_
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <sys/statvfs.h>
#define MEMDB_MAX_FILE_SIZE (1024 * 1024) // 1 MiB
#define MEMDB_MAX_FILE_SIZE (1024 * 1024) // 1 MiB
#define MEMDB_MAX_FSSIZE (128 * 1024 * 1024) // 128 MiB
#define MEMDB_MAX_INODES (256 * 1024) // 256k
#define MEMDB_MAX_INODES (256 * 1024) // 256k
#define MEMDB_BLOCKSIZE 4096
#define MEMDB_BLOCKS ((MEMDB_MAX_FSSIZE + MEMDB_BLOCKSIZE - 1)/MEMDB_BLOCKSIZE)
#define MEMDB_BLOCKS ((MEMDB_MAX_FSSIZE + MEMDB_BLOCKSIZE - 1) / MEMDB_BLOCKSIZE)
typedef struct memdb_tree_entry memdb_tree_entry_t;
struct memdb_tree_entry {
guint64 parent;
guint64 inode;
guint64 version;
guint32 writer;
guint32 mtime;
guint32 size;
char type; /* DT_REG .. regular file, DT_DIR ... directory */
union {
GHashTable *entries;
gpointer value;
} data;
char name[];
guint64 parent;
guint64 inode;
guint64 version;
guint32 writer;
guint32 mtime;
guint32 size;
char type; /* DT_REG .. regular file, DT_DIR ... directory */
union {
GHashTable *entries;
gpointer value;
} data;
char name[];
};
typedef struct {
guint64 inode;
char digest[32]; /* SHA256 digest */
guint64 inode;
char digest[32]; /* SHA256 digest */
} memdb_index_extry_t;
typedef struct {
guint64 version;
guint64 last_inode;
guint32 writer;
guint32 mtime;
guint32 size; /* number of entries */
guint32 bytes; /* total bytes allocated */
memdb_index_extry_t entries[];
guint64 version;
guint64 last_inode;
guint32 writer;
guint32 mtime;
guint32 size; /* number of entries */
guint32 bytes; /* total bytes allocated */
memdb_index_extry_t entries[];
} memdb_index_t;
typedef struct db_backend db_backend_t;
typedef struct {
char *path;
guint32 ltime;
guchar csum[32];
char *path;
guint32 ltime;
guchar csum[32];
} memdb_lock_info_t;
typedef struct {
char *dbfilename;
gboolean errors;
memdb_tree_entry_t *root;
GHashTable *index; /* map version ==> memdb_tree_entry */
GHashTable *locks; /* contains memdb_lock_info_t */
GMutex mutex;
db_backend_t *bdb;
char *dbfilename;
gboolean errors;
memdb_tree_entry_t *root;
GHashTable *index; /* map version ==> memdb_tree_entry */
GHashTable *locks; /* contains memdb_lock_info_t */
GMutex mutex;
db_backend_t *bdb;
} memdb_t;
memdb_t *
memdb_open(const char *dbfilename);
memdb_t *memdb_open(const char *dbfilename);
void
memdb_close(memdb_t *memdb);
void memdb_close(memdb_t *memdb);
gboolean memdb_checkpoint(memdb_t *memdb);
gboolean memdb_recreate_vmlist(memdb_t *memdb);
gboolean memdb_lock_expired(memdb_t *memdb, const char *path, const guchar csum[32]);
void memdb_update_locks(memdb_t *memdb);
int memdb_statfs(memdb_t *memdb, struct statvfs *stbuf);
int memdb_mkdir(memdb_t *memdb, const char *path, guint32 writer, guint32 mtime);
int memdb_mtime(memdb_t *memdb, const char *path, guint32 writer, guint32 mtime);
GList *memdb_readdir(memdb_t *memdb, const char *path);
void memdb_dirlist_free(GList *dirlist);
void tree_entry_debug(memdb_tree_entry_t *te);
void tree_entry_print(memdb_tree_entry_t *te);
memdb_tree_entry_t *memdb_tree_entry_new(const char *name);
memdb_tree_entry_t *memdb_tree_entry_copy(memdb_tree_entry_t *te, gboolean with_data);
void memdb_tree_entry_free(memdb_tree_entry_t *te);
int memdb_delete(memdb_t *memdb, const char *path, guint32 writer, guint32 mtime);
int memdb_read(memdb_t *memdb, const char *path, gpointer *data_ret);
int memdb_read_nolock(memdb_t *memdb, const char *path, gpointer *data_ret);
int memdb_create(memdb_t *memdb, const char *path, guint32 writer, guint32 mtime);
int memdb_write(
memdb_t *memdb,
const char *path,
guint32 writer,
guint32 mtime,
gconstpointer data,
size_t count,
off_t offset,
gboolean truncate
);
memdb_tree_entry_t *memdb_getattr(memdb_t *memdb, const char *path);
int memdb_rename(memdb_t *memdb, const char *from, const char *to, guint32 writer, guint32 mtime);
void memdb_dump(memdb_t *memdb);
gboolean
memdb_checkpoint(memdb_t *memdb);
memdb_compute_checksum(GHashTable *index, memdb_tree_entry_t *root, guchar *csum, size_t csum_len);
gboolean
memdb_recreate_vmlist(memdb_t *memdb);
memdb_index_t *memdb_encode_index(GHashTable *index, memdb_tree_entry_t *root);
gboolean
memdb_lock_expired(
memdb_t *memdb,
const char *path,
const guchar csum[32]);
void memdb_dump_index(memdb_index_t *idx);
void
memdb_update_locks(memdb_t *memdb);
memdb_index_t *memdb_index_copy(memdb_index_t *idx);
int
memdb_statfs(
memdb_t *memdb,
struct statvfs *stbuf);
gboolean memdb_tree_entry_csum(memdb_tree_entry_t *te, guchar csum[32]);
int
memdb_mkdir(
memdb_t *memdb,
const char *path,
guint32 writer,
guint32 mtime);
db_backend_t *bdb_backend_open(const char *filename, memdb_tree_entry_t *root, GHashTable *index);
int
memdb_mtime(
memdb_t *memdb,
const char *path,
guint32 writer,
guint32 mtime);
void bdb_backend_close(db_backend_t *bdb);
GList *
memdb_readdir(
memdb_t *memdb,
const char *path);
void
memdb_dirlist_free(GList *dirlist);
void
tree_entry_debug(memdb_tree_entry_t *te);
void
tree_entry_print(memdb_tree_entry_t *te);
memdb_tree_entry_t *
memdb_tree_entry_new(const char *name);
memdb_tree_entry_t *
memdb_tree_entry_copy(
memdb_tree_entry_t *te,
gboolean with_data);
void
memdb_tree_entry_free(memdb_tree_entry_t *te);
int
memdb_delete(
memdb_t *memdb,
const char *path,
guint32 writer,
guint32 mtime);
int
memdb_read(
memdb_t *memdb,
const char *path,
gpointer *data_ret);
int
memdb_read_nolock(
memdb_t *memdb,
const char *path,
gpointer *data_ret);
int
memdb_create(
memdb_t *memdb,
const char *path,
guint32 writer,
guint32 mtime);
int
memdb_write(
memdb_t *memdb,
const char *path,
guint32 writer,
guint32 mtime,
gconstpointer data,
size_t count,
off_t offset,
gboolean truncate);
memdb_tree_entry_t *
memdb_getattr(
memdb_t *memdb,
const char *path);
int
memdb_rename(
memdb_t *memdb,
const char *from,
const char *to,
guint32 writer,
guint32 mtime);
void
memdb_dump (
memdb_t *memdb);
gboolean
memdb_compute_checksum(
GHashTable *index,
memdb_tree_entry_t *root,
guchar *csum,
size_t csum_len);
memdb_index_t *
memdb_encode_index(
GHashTable *index,
memdb_tree_entry_t *root);
void
memdb_dump_index (memdb_index_t *idx);
memdb_index_t *
memdb_index_copy(memdb_index_t *idx);
gboolean
memdb_tree_entry_csum(
memdb_tree_entry_t *te,
guchar csum[32]);
db_backend_t *
bdb_backend_open(
const char *filename,
memdb_tree_entry_t *root,
GHashTable *index);
void
bdb_backend_close(db_backend_t *bdb);
int
bdb_backend_write(
db_backend_t *bdb,
guint64 inode,
guint64 parent,
guint64 version,
guint32 writer,
guint32 mtime,
guint32 size,
char type,
char *name,
gpointer value,
guint64 delete_inode);
gboolean
bdb_backend_commit_update(
memdb_t *memdb,
memdb_index_t *master,
memdb_index_t *slave,
GList *inodes);
int bdb_backend_write(
db_backend_t *bdb,
guint64 inode,
guint64 parent,
guint64 version,
guint32 writer,
guint32 mtime,
guint32 size,
char type,
char *name,
gpointer value,
guint64 delete_inode
);
gboolean bdb_backend_commit_update(
memdb_t *memdb, memdb_index_t *master, memdb_index_t *slave, GList *inodes
);
#endif /* _PVE_MEMDB_H_ */

File diff suppressed because it is too large Load diff

View file

@ -24,11 +24,11 @@
#include <config.h>
#endif /* HAVE_CONFIG_H */
#include <stdlib.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <glib.h>
#include <corosync/quorum.h>
@ -37,183 +37,173 @@
#include "status.h"
typedef struct {
quorum_handle_t handle;
quorum_handle_t handle;
} qs_private_t;
static void quorum_notification_fn(
quorum_handle_t handle,
uint32_t quorate,
uint64_t ring_id,
uint32_t view_list_entries,
uint32_t *view_list)
{
cs_error_t result;
quorum_handle_t handle,
uint32_t quorate,
uint64_t ring_id,
uint32_t view_list_entries,
uint32_t *view_list
) {
cs_error_t result;
cfs_debug("quorum notification called, quorate = %d, "
"number of nodes = %d", quorate, view_list_entries);
cfs_debug(
"quorum notification called, quorate = %d, "
"number of nodes = %d",
quorate, view_list_entries
);
qs_private_t *private = NULL;
qs_private_t *private = NULL;
result = quorum_context_get(handle, (gconstpointer *)&private);
if (result != CS_OK || !private) {
cfs_critical("quorum_context_get error: %d (%p)", result, (void *) private);
return;
}
result = quorum_context_get(handle, (gconstpointer *)&private);
if (result != CS_OK || !private) {
cfs_critical("quorum_context_get error: %d (%p)", result, (void *)private);
return;
}
cfs_set_quorate(quorate, FALSE);
cfs_set_quorate(quorate, FALSE);
}
static quorum_callbacks_t quorum_callbacks = {
.quorum_notify_fn = quorum_notification_fn,
.quorum_notify_fn = quorum_notification_fn,
};
static gboolean service_quorum_finalize(
cfs_service_t *service,
gpointer context)
{
g_return_val_if_fail(service != NULL, FALSE);
g_return_val_if_fail(context != NULL, FALSE);
static gboolean service_quorum_finalize(cfs_service_t *service, gpointer context) {
g_return_val_if_fail(service != NULL, FALSE);
g_return_val_if_fail(context != NULL, FALSE);
qs_private_t *private = (qs_private_t *)context;
quorum_handle_t handle = private->handle;
qs_private_t *private = (qs_private_t *)context;
quorum_handle_t handle = private->handle;
cs_error_t result;
cs_error_t result;
cfs_set_quorate(0, TRUE);
cfs_set_quorate(0, TRUE);
result = quorum_finalize(handle);
private->handle = 0;
if (result != CS_OK) {
cfs_critical("quorum_finalize failed: %d", result);
return FALSE;
}
result = quorum_finalize(handle);
private->handle = 0;
if (result != CS_OK) {
cfs_critical("quorum_finalize failed: %d", result);
return FALSE;
}
return TRUE;
return TRUE;
}
static int service_quorum_initialize(
cfs_service_t *service,
gpointer context)
{
g_return_val_if_fail(service != NULL, FALSE);
g_return_val_if_fail(context != NULL, FALSE);
static int service_quorum_initialize(cfs_service_t *service, gpointer context) {
g_return_val_if_fail(service != NULL, FALSE);
g_return_val_if_fail(context != NULL, FALSE);
qs_private_t *private = (qs_private_t *)context;
qs_private_t *private = (qs_private_t *)context;
quorum_handle_t handle = private->handle;
cs_error_t result;
quorum_handle_t handle = private->handle;
cs_error_t result;
if (!private->handle) {
uint32_t quorum_type;
result = quorum_initialize(&handle, &quorum_callbacks, &quorum_type);
if (result != CS_OK) {
cfs_critical("quorum_initialize failed: %d", result);
goto err_reset_handle;
}
if (!private->handle) {
if (quorum_type != QUORUM_SET) {
cfs_critical("quorum_initialize returned wrong quorum_type: %d", quorum_type);
goto err_finalize;
}
uint32_t quorum_type;
result = quorum_context_set(handle, private);
if (result != CS_OK) {
cfs_critical("quorum_context_set failed: %d", result);
goto err_finalize;
}
result = quorum_initialize(&handle, &quorum_callbacks, &quorum_type);
if (result != CS_OK) {
cfs_critical("quorum_initialize failed: %d", result);
goto err_reset_handle;
}
private->handle = handle;
}
if (quorum_type != QUORUM_SET) {
cfs_critical("quorum_initialize returned wrong quorum_type: %d", quorum_type);
goto err_finalize;
}
result = quorum_trackstart(handle, CS_TRACK_CHANGES);
if (result == CS_ERR_LIBRARY || result == CS_ERR_BAD_HANDLE) {
cfs_critical("quorum_trackstart failed: %d - closing handle", result);
goto err_finalize;
} else if (result != CS_OK) {
cfs_critical("quorum_trackstart failed: %d - trying again", result);
return -1;
}
int quorum_fd = -1;
if ((result = quorum_fd_get(handle, &quorum_fd)) != CS_OK) {
cfs_critical("quorum_fd_get failed %d - trying again", result);
return -1;
}
result = quorum_context_set(handle, private);
if (result != CS_OK) {
cfs_critical("quorum_context_set failed: %d", result);
goto err_finalize;
}
return quorum_fd;
private->handle = handle;
}
err_finalize:
cfs_set_quorate(0, FALSE);
quorum_finalize(handle);
err_reset_handle:
private->handle = 0;
return -1;
result = quorum_trackstart(handle, CS_TRACK_CHANGES);
if (result == CS_ERR_LIBRARY || result == CS_ERR_BAD_HANDLE) {
cfs_critical("quorum_trackstart failed: %d - closing handle", result);
goto err_finalize;
} else if (result != CS_OK) {
cfs_critical("quorum_trackstart failed: %d - trying again", result);
return -1;
}
int quorum_fd = -1;
if ((result = quorum_fd_get(handle, &quorum_fd)) != CS_OK) {
cfs_critical("quorum_fd_get failed %d - trying again", result);
return -1;
}
return quorum_fd;
err_finalize:
cfs_set_quorate(0, FALSE);
quorum_finalize(handle);
err_reset_handle:
private
->handle = 0;
return -1;
}
static gboolean service_quorum_dispatch(
cfs_service_t *service,
gpointer context)
{
g_return_val_if_fail(service != NULL, FALSE);
g_return_val_if_fail(context != NULL, FALSE);
static gboolean service_quorum_dispatch(cfs_service_t *service, gpointer context) {
g_return_val_if_fail(service != NULL, FALSE);
g_return_val_if_fail(context != NULL, FALSE);
qs_private_t *private = (qs_private_t *)context;
quorum_handle_t handle = private->handle;
qs_private_t *private = (qs_private_t *)context;
quorum_handle_t handle = private->handle;
cs_error_t result;
cs_error_t result;
int retries = 0;
int retries = 0;
loop:
result = quorum_dispatch(handle, CS_DISPATCH_ALL);
if (result == CS_ERR_TRY_AGAIN) {
usleep(100000);
++retries;
if ((retries % 100) == 0)
cfs_message("quorum_dispatch retry %d", retries);
goto loop;
}
result = quorum_dispatch(handle, CS_DISPATCH_ALL);
if (result == CS_ERR_TRY_AGAIN) {
usleep(100000);
++retries;
if ((retries % 100) == 0)
cfs_message("quorum_dispatch retry %d", retries);
goto loop;
}
if (result == CS_OK || result == CS_ERR_TRY_AGAIN)
return TRUE;
if (result == CS_OK || result == CS_ERR_TRY_AGAIN)
return TRUE;
cfs_critical("quorum_dispatch failed: %d", result);
cfs_critical("quorum_dispatch failed: %d", result);
cfs_set_quorate(0, FALSE);
quorum_finalize(handle);
private->handle = 0;
return FALSE;
cfs_set_quorate(0, FALSE);
quorum_finalize(handle);
private->handle = 0;
return FALSE;
}
static cfs_service_callbacks_t cfs_quorum_callbacks = {
.cfs_service_initialize_fn = service_quorum_initialize,
.cfs_service_finalize_fn = service_quorum_finalize,
.cfs_service_dispatch_fn = service_quorum_dispatch,
.cfs_service_initialize_fn = service_quorum_initialize,
.cfs_service_finalize_fn = service_quorum_finalize,
.cfs_service_dispatch_fn = service_quorum_dispatch,
};
cfs_service_t *service_quorum_new(void)
{
cfs_service_t *service;
cfs_service_t *service_quorum_new(void) {
cfs_service_t *service;
qs_private_t *private = g_new0(qs_private_t, 1);
if (!private)
return NULL;
qs_private_t *private = g_new0(qs_private_t, 1);
if (!private)
return NULL;
service = cfs_service_new(&cfs_quorum_callbacks, G_LOG_DOMAIN, private);
service = cfs_service_new(&cfs_quorum_callbacks, G_LOG_DOMAIN, private);
return service;
return service;
}
void service_quorum_destroy(cfs_service_t *service)
{
g_return_if_fail(service != NULL);
void service_quorum_destroy(cfs_service_t *service) {
g_return_if_fail(service != NULL);
qs_private_t *private =
(qs_private_t *)cfs_service_get_context(service);
qs_private_t *private = (qs_private_t *)cfs_service_get_context(service);
g_free(private);
g_free(service);
g_free(private);
g_free(service);
}

View file

@ -27,7 +27,6 @@
cfs_service_t *service_quorum_new(void);
void service_quorum_destroy(
cfs_service_t *service);
void service_quorum_destroy(cfs_service_t *service);
#endif /* _PVE_QUORUM_H_ */

File diff suppressed because it is too large Load diff

View file

@ -21,9 +21,7 @@
#ifndef _PVE_IPCS_H_
#define _PVE_IPCS_H_
gboolean server_start(memdb_t *memdb);
void server_stop(void);
#endif /* _PVE_IPCS_H_ */

File diff suppressed because it is too large Load diff

View file

@ -32,138 +32,75 @@
#define VMTYPE_OPENVZ 2
#define VMTYPE_LXC 3
#define CFS_MAX_STATUS_SIZE (32*1024)
#define CFS_MAX_STATUS_SIZE (32 * 1024)
typedef struct cfs_clnode cfs_clnode_t;
typedef struct cfs_clinfo cfs_clinfo_t;
void
cfs_status_init(void);
void cfs_status_init(void);
void
cfs_status_cleanup(void);
void cfs_status_cleanup(void);
dfsm_t *
cfs_status_dfsm_new(void);
dfsm_t *cfs_status_dfsm_new(void);
void
cfs_cluster_log(clog_entry_t *entry);
void cfs_cluster_log(clog_entry_t *entry);
void
cfs_cluster_log_dump(
GString *str,
const char *user,
guint max_entries);
void cfs_cluster_log_dump(GString *str, const char *user, guint max_entries);
void
cfs_rrd_dump(GString *str);
void cfs_rrd_dump(GString *str);
int
cfs_status_set(
const char *key,
gpointer data,
size_t len);
int cfs_status_set(const char *key, gpointer data, size_t len);
void
cfs_status_set_clinfo(
cfs_clinfo_t *clinfo);
void cfs_status_set_clinfo(cfs_clinfo_t *clinfo);
void
cfs_status_set_vmlist(
GHashTable *vmlist);
void cfs_status_set_vmlist(GHashTable *vmlist);
cfs_clnode_t *
cfs_clnode_new(
const char *name,
uint32_t nodeid,
uint32_t votes);
cfs_clnode_t *cfs_clnode_new(const char *name, uint32_t nodeid, uint32_t votes);
void
cfs_clnode_destroy(
cfs_clnode_t *clnode);
void cfs_clnode_destroy(cfs_clnode_t *clnode);
cfs_clinfo_t *
cfs_clinfo_new(
const char *cluster_name,
uint32_t cman_version);
cfs_clinfo_t *cfs_clinfo_new(const char *cluster_name, uint32_t cman_version);
gboolean
cfs_clinfo_destroy(
cfs_clinfo_t *clinfo);
gboolean cfs_clinfo_destroy(cfs_clinfo_t *clinfo);
gboolean
cfs_clinfo_add_node(
cfs_clinfo_t *clinfo,
cfs_clnode_t *clnode);
gboolean cfs_clinfo_add_node(cfs_clinfo_t *clinfo, cfs_clnode_t *clnode);
void
cfs_set_quorate(
uint32_t quorate,
gboolean quiet);
void cfs_set_quorate(uint32_t quorate, gboolean quiet);
gboolean
cfs_is_quorate(void);
gboolean cfs_is_quorate(void);
GHashTable *
vmlist_hash_new(void);
GHashTable *vmlist_hash_new(void);
gboolean
vmlist_hash_insert_vm(
GHashTable *vmlist,
int vmtype,
guint32 vmid,
const char *nodename,
gboolean replace);
gboolean vmlist_hash_insert_vm(
GHashTable *vmlist, int vmtype, guint32 vmid, const char *nodename, gboolean replace
);
void
vmlist_register_vm(
int vmtype,
guint32 vmid,
const char *nodename);
void vmlist_register_vm(int vmtype, guint32 vmid, const char *nodename);
void
vmlist_delete_vm(
guint32 vmid);
void vmlist_delete_vm(guint32 vmid);
gboolean
vmlist_vm_exists(
guint32 vmid);
gboolean vmlist_vm_exists(guint32 vmid);
gboolean
vmlist_different_vm_exists(
int vmtype,
guint32 vmid,
const char *nodename);
gboolean vmlist_different_vm_exists(int vmtype, guint32 vmid, const char *nodename);
void
record_memdb_change(const char *path);
void record_memdb_change(const char *path);
void
record_memdb_reload(void);
void record_memdb_reload(void);
int cfs_create_status_msg(GString *str, const char *nodename, const char *key);
int
cfs_create_status_msg(
GString *str,
const char *nodename,
const char *key);
int cfs_create_version_msg(GString *str);
int
cfs_create_version_msg(
GString *str);
int cfs_create_vmlist_msg(GString *str);
int
cfs_create_vmlist_msg(
GString *str);
int cfs_create_memberlist_msg(GString *str);
int
cfs_create_memberlist_msg(
GString *str);
int cfs_create_guest_conf_property_msg(
GString *str, memdb_t *memdb, const char *prop, uint32_t vmid
);
int
cfs_create_guest_conf_property_msg(GString *str, memdb_t *memdb, const char *prop, uint32_t vmid);
int
cfs_create_guest_conf_properties_msg(GString *str, memdb_t *memdb, const char **props, uint8_t num_props, uint32_t vmid);
int cfs_create_guest_conf_properties_msg(
GString *str, memdb_t *memdb, const char **props, uint8_t num_props, uint32_t vmid
);
#endif /* _PVE_STATUS_H_ */

View file

@ -6,7 +6,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -21,8 +21,8 @@
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@ -31,147 +31,149 @@
static int cpg_mode_leave;
static void my_cpg_deliver_callback (
cpg_handle_t handle,
const struct cpg_name *groupName,
uint32_t nodeid,
uint32_t pid,
void *msg,
size_t msg_len)
{
printf("got message form %d/%d\n", nodeid, pid);
static void my_cpg_deliver_callback(
cpg_handle_t handle,
const struct cpg_name *groupName,
uint32_t nodeid,
uint32_t pid,
void *msg,
size_t msg_len
) {
printf("got message form %d/%d\n", nodeid, pid);
cpg_mode_leave = 1;
cpg_mode_leave = 1;
return;
return;
}
static void my_cpg_confchg_callback (
cpg_handle_t handle,
const struct cpg_name *groupName,
const struct cpg_address *member_list, size_t member_list_entries,
const struct cpg_address *left_list, size_t left_list_entries,
const struct cpg_address *joined_list, size_t joined_list_entries)
{
int i;
static void my_cpg_confchg_callback(
cpg_handle_t handle,
const struct cpg_name *groupName,
const struct cpg_address *member_list,
size_t member_list_entries,
const struct cpg_address *left_list,
size_t left_list_entries,
const struct cpg_address *joined_list,
size_t joined_list_entries
) {
int i;
printf("cpg_confchg_callback %ld joined, %ld left, %ld members\n",
joined_list_entries, left_list_entries, member_list_entries);
printf(
"cpg_confchg_callback %ld joined, %ld left, %ld members\n", joined_list_entries,
left_list_entries, member_list_entries
);
for (i = 0; i < member_list_entries; i++) {
printf("cpg member %d/%d\n", member_list[i].nodeid, member_list[i].pid);
}
for (i = 0; i < member_list_entries; i++) {
printf("cpg member %d/%d\n", member_list[i].nodeid, member_list[i].pid);
}
/* send update message */
char *inbuf = "This is just a test message\n";
struct iovec iov;
iov.iov_base = inbuf;
iov.iov_len = strlen(inbuf)+1;
/* send update message */
char *inbuf = "This is just a test message\n";
struct iovec iov;
iov.iov_base = inbuf;
iov.iov_len = strlen(inbuf) + 1;
cs_error_t result;
cs_error_t result;
loop:
result = cpg_mcast_joined(handle, CPG_TYPE_AGREED, &iov, 1);
if (result == CS_ERR_TRY_AGAIN) {
usleep(1000);
printf("cpg_send_message retry");
goto loop;
}
if (result != CS_OK)
printf("cpg_send_message failed: %d\n", result);
result = cpg_mcast_joined(handle, CPG_TYPE_AGREED, &iov, 1);
if (result == CS_ERR_TRY_AGAIN) {
usleep(1000);
printf("cpg_send_message retry");
goto loop;
}
if (result != CS_OK)
printf("cpg_send_message failed: %d\n", result);
}
static cpg_callbacks_t callbacks = {
.cpg_deliver_fn = my_cpg_deliver_callback,
.cpg_confchg_fn = my_cpg_confchg_callback,
.cpg_deliver_fn = my_cpg_deliver_callback,
.cpg_confchg_fn = my_cpg_confchg_callback,
};
int main(int argc, char *argv[]) {
struct cpg_name group_name;
char *gn = "TESTGROUP";
strcpy(group_name.value, gn);
group_name.length = strlen(gn) + 1;
int main(int argc, char *argv[])
{
struct cpg_name group_name;
char *gn = "TESTGROUP";
strcpy(group_name.value, gn);
group_name.length = strlen(gn) + 1;
cs_error_t result;
cpg_handle_t handle;
cs_error_t result;
cpg_handle_t handle;
start:
printf("starting cpgtest\n");
printf("starting cpgtest\n");
cpg_mode_leave = 0;
handle = 0;
cpg_mode_leave = 0;
printf("calling cpg_initialize\n");
result = cpg_initialize(&handle, &callbacks);
if (result != CS_OK) {
printf("cpg_initialize failed: %d\n", result);
goto retry;
}
handle = 0;
printf("calling cpg_join\n");
while ((result = cpg_join(handle, &group_name)) == CS_ERR_TRY_AGAIN) {
printf("cpg_join returned %d\n", result);
sleep (1);
}
printf("calling cpg_initialize\n");
result = cpg_initialize(&handle, &callbacks);
if (result != CS_OK) {
printf("cpg_initialize failed: %d\n", result);
goto retry;
}
if (result != CS_OK) {
printf("cpg_join failed: %d\n", result);
exit(-1);
}
printf("calling cpg_join\n");
while ((result = cpg_join(handle, &group_name)) == CS_ERR_TRY_AGAIN) {
printf("cpg_join returned %d\n", result);
sleep(1);
}
fd_set read_fds;
FD_ZERO(&read_fds);
int cpg_fd;
if (result != CS_OK) {
printf("cpg_join failed: %d\n", result);
exit(-1);
}
cpg_fd_get(handle, &cpg_fd);
fd_set read_fds;
FD_ZERO(&read_fds);
int cpg_fd;
printf("starting main loop\n");
cpg_fd_get(handle, &cpg_fd);
do {
FD_SET(cpg_fd, &read_fds);
struct timeval timeout = { 1, 0};
result = select(cpg_fd + 1, &read_fds, 0, 0, &timeout);
printf("starting main loop\n");
if (result == -1) {
printf("select error: %d\n", result);
break;
}
if (result > 0) {
do {
FD_SET(cpg_fd, &read_fds);
struct timeval timeout = {1, 0};
result = select(cpg_fd + 1, &read_fds, 0, 0, &timeout);
if (FD_ISSET(cpg_fd, &read_fds)) {
cs_error_t res = cpg_dispatch(handle, CS_DISPATCH_ALL);
if (res != CS_OK) {
printf("cpg_dispatch failed: %d\n", res);
break;
}
}
}
if (result == -1) {
printf("select error: %d\n", result);
break;
}
if (result > 0) {
if (cpg_mode_leave)
break;
if (FD_ISSET(cpg_fd, &read_fds)) {
cs_error_t res = cpg_dispatch(handle, CS_DISPATCH_ALL);
if (res != CS_OK) {
printf("cpg_dispatch failed: %d\n", res);
break;
}
}
}
} while(1);
if (cpg_mode_leave)
break;
} while (1);
retry:
printf("end loop - trying to restart\n");
printf("end loop - trying to restart\n");
usleep (1000);
usleep(1000);
if (handle) {
if (handle) {
result = cpg_finalize(handle);
if (result != CS_OK) {
printf("cpg_finalize failed: %d\n", result);
exit(-1);
}
}
result = cpg_finalize(handle);
if (result != CS_OK) {
printf("cpg_finalize failed: %d\n", result);
exit(-1);
}
}
goto start;
goto start;
exit(0);
exit(0);
}