Skip to content

Instantly share code, notes, and snippets.

@tuxillo
Created December 31, 2013 13:00
Show Gist options
  • Save tuxillo/8196437 to your computer and use it in GitHub Desktop.
Save tuxillo/8196437 to your computer and use it in GitHub Desktop.
diff --git a/lib/libhammer/Makefile b/lib/libhammer/Makefile
index e306021..d88ff51 100644
--- a/lib/libhammer/Makefile
+++ b/lib/libhammer/Makefile
@@ -1,7 +1,7 @@
# DragonflyBSD Makefile
LIB= hammer
-SRCS= crc32.c info.c misc.c stats.c
+SRCS= crc32.c info.c misc.c stats.c config.c
INCS= libhammer.h
SRCS+= crc32.c
diff --git a/lib/libhammer/config.c b/lib/libhammer/config.c
new file mode 100644
index 0000000..038107f
--- /dev/null
+++ b/lib/libhammer/config.c
@@ -0,0 +1,192 @@
+ /*
+ * Copyright (c) 2013 The DragonFly Project. All rights reserved.
+ *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Matthew Dillon <[email protected]>
+ * by Antonio Huete Jimenez <[email protected]>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific, prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <sys/param.h>
+
+#include "libhammer.h"
+
+static int
+str2idx(const char *opt)
+{
+ if (strcmp("snapshots", opt) == 0)
+ return snapshots_cfg;
+ else if (strcmp("prune", opt) == 0)
+ return prune_cfg;
+ else if (strcmp("rebalance", opt) == 0)
+ return rebalance_cfg;
+ else if (strcmp("dedup", opt) == 0)
+ return dedup_cfg;
+ else if (strcmp("reblock", opt) == 0)
+ return reblock_cfg;
+ else if (strcmp("recopy", opt) == 0)
+ return recopy_cfg;
+ else
+ return -1;
+}
+
+static int
+text_to_config(char *text, libhammer_pfs_config_t config)
+{
+ char *line, *tok, *tok2;
+ int i;
+ int idx;
+
+ while ((line = strsep(&text, "\n")) != NULL) {
+ if (line[0] != '#') {
+ tok = strsep(&line, WS);
+ idx = str2idx(tok);
+ config->opts[idx].optname = tok;
+ /*
+ * Attempt to extract all the arguments for the
+ * current option being parsed. Since there can
+ * be multiple spaces between the option and its
+ * arguments, multiple strsep() calls are needed
+ * when that is detected.
+ */
+ for (i = 0; i < LIBHAMMER_MAXOPTARGS; i++) {
+ tok2 = strsep(&line, WS);
+ while (tok2 && tok2[0] == '\0')
+ tok2 = strsep(&line, WS);
+ if (!tok2)
+ break;
+ config->opts[idx].args[i] = tok2;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int
+config_to_text(const libhammer_pfs_config_t config, char *ctext)
+{
+ return 0;
+}
+
+static int
+config_from_file(const char *path, libhammer_pfs_config_t config, size_t len)
+{
+ FILE *fp = NULL;
+ char *buf, *text;
+ int error;
+ int n;
+
+ /* Non-absolute snapshots path not allowed */
+ if (path[0] != '/')
+ return -1;
+
+ buf = _libhammer_malloc(MAXPATHLEN);
+ snprintf(buf, MAXPATHLEN - 1, "%s/config", path);
+
+ fp = fopen(path, "r");
+ if (fp == NULL) {
+ free(buf);
+ return -1;
+ }
+
+ text = _libhammer_malloc(len); /* Zero'ed by calloc() */
+ n = fread(text, 1, len - 1, fp);
+ if (n > 0)
+ text_to_config(text, config);
+ else
+ error = -1;
+
+ fclose(fp);
+ free(text);
+ free(buf);
+
+ return error;
+}
+
+int
+libhammer_get_config(libhammer_pfsinfo_t pfsi, libhammer_pfs_config_t config)
+{
+ struct hammer_ioc_config hcfg;
+ char *dirpath = NULL;
+ int error = 0;
+ int fd;
+
+ if (pfsi == NULL)
+ return -1;
+
+ dirpath = _libhammer_malloc(MAXPATHLEN);
+ if (pfsi->mountedon)
+ strlcpy(dirpath, pfsi->mountedon, MAXPATHLEN - 1);
+ else
+ libhammer_get_pfspath(pfsi, dirpath);
+
+ /*
+ * HAMMER filesystems version < 3 did not include the configuration
+ * in the metadata but in a file in the snapshot directory.
+ */
+ if (pfsi->version < 3) {
+ error = config_from_file(pfsi->snapshots, config,
+ sizeof(hcfg.config.text));
+ if (error)
+ goto out;
+ } else {
+ /* HAMMER version >= 3*/
+ if ((fd = open(dirpath, O_RDONLY)) == -1) {
+ error = -1;
+ goto out;
+ }
+ if (ioctl(fd, HAMMERIOC_GET_CONFIG, hcfg) < 0) {
+ close(fd);
+ error = -1;
+ goto out;
+ }
+ text_to_config(hcfg.config.text, config);
+ close(fd);
+ }
+
+
+out:
+ if (dirpath)
+ free(dirpath);
+
+ return (error);
+}
+
+int
+libhammer_set_config(libhammer_pfsinfo_t pfsi, libhammer_pfs_config_t config)
+{
+ return 0;
+}
diff --git a/lib/libhammer/libhammer.h b/lib/libhammer/libhammer.h
index 5271466..e9563d3 100644
--- a/lib/libhammer/libhammer.h
+++ b/lib/libhammer/libhammer.h
@@ -72,8 +72,32 @@
#define FLAG_BADCHILDPARENT 0x0008
#define FLAG_BADMIRRORTID 0x0010
+#define LIBHAMMER_MAXCFGOPTS 6
+#define LIBHAMMER_MAXOPTARGS 3
+
/*
- * Hammer information system structures
+ * HAMMER configuration related info.
+ */
+enum libhammer_cfglist {
+ snapshots_cfg,
+ prune_cfg,
+ rebalance_cfg,
+ dedup_cfg,
+ reblock_cfg,
+ recopy_cfg
+};
+
+struct libhammer_pfs_confopt {
+ char *optname;
+ char *args[LIBHAMMER_MAXOPTARGS];
+};
+
+typedef struct libhammer_pfs_config {
+ struct libhammer_pfs_confopt opts[LIBHAMMER_MAXCFGOPTS];
+} *libhammer_pfs_config_t;
+
+/*
+ * HAMMER information system structures
*/
struct libhammer_head {
int32_t error;
@@ -94,6 +118,8 @@ typedef struct libhammer_pfsinfo {
uuid_t unique_uuid; /* unique uuid of this master/slave */
TAILQ_ENTRY(libhammer_pfsinfo) entries;
+ libhammer_pfs_config_t config;
+
hammer_tid_t beg_tid; /* Earliest TID with full history */
hammer_tid_t end_tid; /* Current synchronisation TID */
@@ -169,6 +195,8 @@ int libhammer_io_stats(struct libhammer_io_stats *);
char *libhammer_find_pfs_mount(int, uuid_t, int);
void *_libhammer_malloc(size_t);
void libhammer_get_pfspath(libhammer_pfsinfo_t, char *);
+int libhammer_get_config(libhammer_pfsinfo_t, libhammer_pfs_config_t);
+int libhammer_set_config(libhammer_pfsinfo_t, libhammer_pfs_config_t);
__END_DECLS
static __inline libhammer_pfsinfo_t
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment