2 commits - src/client.c src/client_cmd.c src/sanlock.h tests/Makefile tests/sanlk_path.c
by David Teigland
src/client.c | 56 +++++++++++++++++-----
src/client_cmd.c | 17 +++++-
src/sanlock.h | 7 ++
tests/Makefile | 17 ++++--
tests/sanlk_path.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 202 insertions(+), 25 deletions(-)
New commits:
commit fb4b2cbcc76f48d8da1af9d6f6da00e438b95d8e
Author: David Teigland <teigland(a)redhat.com>
Date: Fri Sep 21 10:32:15 2012 -0500
sanlock: print escape chars in path from status
Signed-off-by: David Teigland <teigland(a)redhat.com>
diff --git a/src/client_cmd.c b/src/client_cmd.c
index ee96ae2..069f75f 100644
--- a/src/client_cmd.c
+++ b/src/client_cmd.c
@@ -73,14 +73,22 @@ static void status_client(struct sanlk_state *st, char *str, int debug)
print_debug(str, st->str_len);
}
+/* TODO: when path strings are exported, through status or inquire, we
+ should export into a malloced buffer the size of the standard chars
+ plus extra esc chars. */
+
static void status_lockspace(struct sanlk_state *st, char *str, char *bin, int debug)
{
struct sanlk_lockspace *ls = (struct sanlk_lockspace *)bin;
+ char path[SANLK_PATH_LEN + 1];
+
+ memset(path, 0, sizeof(path));
+ sanlock_path_export(path, ls->host_id_disk.path, sizeof(path));
printf("s %.48s:%llu:%s:%llu\n",
ls->name,
(unsigned long long)ls->host_id,
- ls->host_id_disk.path,
+ path,
(unsigned long long)ls->host_id_disk.offset);
if (st->str_len && debug)
@@ -91,6 +99,7 @@ static void status_resource(struct sanlk_state *st, char *str, char *bin, int de
{
struct sanlk_resource *res = (struct sanlk_resource *)bin;
struct sanlk_disk *disk;
+ char path[SANLK_PATH_LEN + 1];
int i;
printf("r %.48s:%.48s", res->lockspace_name, res->name);
@@ -98,8 +107,10 @@ static void status_resource(struct sanlk_state *st, char *str, char *bin, int de
for (i = 0; i < res->num_disks; i++) {
disk = (struct sanlk_disk *)(bin + sizeof(struct sanlk_resource) + i * sizeof(struct sanlk_disk));
- printf(":%s:%llu",
- disk->path, (unsigned long long)disk->offset);
+ memset(path, 0, sizeof(path));
+ sanlock_path_export(path, disk->path, sizeof(path));
+
+ printf(":%s:%llu", path, (unsigned long long)disk->offset);
}
if (res->flags & SANLK_RES_SHARED)
diff --git a/src/sanlock.h b/src/sanlock.h
index 457ab7a..8446ebe 100644
--- a/src/sanlock.h
+++ b/src/sanlock.h
@@ -18,7 +18,8 @@
#define SANLK_NAME_LEN 48
-/* max disk path length, includes terminating \0 byte */
+/* max disk path length, includes terminating \0 byte, and escape chars,
+ i.e. the strlen with esc chars inserted must still be less than 1024. */
#define SANLK_PATH_LEN 1024
commit 47bd55e66ae8b043136d10a99e8ebbff9d53bdc1
Author: Federico Simoncelli <fsimonce(a)redhat.com>
Date: Fri Sep 21 10:13:42 2012 -0400
sanlock: expose sanlock path import and export utils
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
diff --git a/src/client.c b/src/client.c
index e8b61be..3c7287e 100644
--- a/src/client.c
+++ b/src/client.c
@@ -238,28 +238,56 @@ int sanlock_init(struct sanlk_lockspace *ls,
/* src has colons unescaped, dst should have them escaped with backslash */
-static void copy_path_out(char *dst, char *src)
+size_t sanlock_path_export(char *dst, const char *src, size_t dstlen)
{
- int i, j = 0;
+ size_t j = 0, escaped = 0;
+ const char *p = src;
+
+ while (j < dstlen) {
+ if (*p == ':' || *p == '\\') {
+ if (!escaped) {
+ dst[j] = '\\', escaped = 1;
+ goto next_loop;
+ }
+
+ escaped = 0;
+ }
+
+ dst[j] = *p;
- for (i = 0; i < strlen(src); i++) {
- if (src[i] == ':')
- dst[j++] = '\\';
- dst[j++] = src[i];
+ if (*p == '\0') return j; /* success */
+ p++;
+
+ next_loop:
+ j++;
}
+
+ return 0;
}
/* src has colons escaped with backslash, dst should have backslash removed */
-static void copy_path_in(char *dst, char *src)
+size_t sanlock_path_import(char *dst, const char *src, size_t dstlen)
{
- int i, j = 0;
+ size_t j = 0;
+ const char *p = src;
- for (i = 0; i < strlen(src); i++) {
- if (src[i] == '\\')
- continue;
- dst[j++] = src[i];
+ while (j < dstlen) {
+ if (*p == '\\')
+ goto next_loop;
+
+ dst[j] = *p;
+
+ if (*p == '\0')
+ return j;
+
+ j++;
+
+ next_loop:
+ p++;
}
+
+ return 0;
}
int sanlock_register(void)
@@ -636,7 +664,7 @@ int sanlock_res_to_str(struct sanlk_resource *res, char **str_ret)
for (d = 0; d < res->num_disks; d++) {
memset(path, 0, sizeof(path));
- copy_path_out(path, res->disks[d].path);
+ sanlock_path_export(path, res->disks[d].path, sizeof(path));
ret = snprintf(str + pos, len - pos, ":%s:%llu", path,
(unsigned long long)res->disks[d].offset);
@@ -946,7 +974,7 @@ int sanlock_str_to_lockspace(char *str, struct sanlk_lockspace *ls)
if (host_id)
ls->host_id = atoll(host_id);
if (path)
- copy_path_in(ls->host_id_disk.path, path);
+ sanlock_path_import(ls->host_id_disk.path, path, sizeof(ls->host_id_disk.path));
if (offset)
ls->host_id_disk.offset = atoll(offset);
diff --git a/src/sanlock.h b/src/sanlock.h
index e36c40e..457ab7a 100644
--- a/src/sanlock.h
+++ b/src/sanlock.h
@@ -91,5 +91,7 @@ struct sanlk_lockspace {
struct sanlk_disk host_id_disk;
};
-#endif
+size_t sanlock_path_export(char *dst, const char *src, size_t dstlen);
+size_t sanlock_path_import(char *dst, const char *src, size_t dstlen);
+#endif
diff --git a/tests/Makefile b/tests/Makefile
index 838ad23..28f5d21 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -2,11 +2,13 @@ TARGET1 = devcount
TARGET2 = sanlk_load
TARGET3 = sanlk_client
TARGET4 = killpath
+TARGET5 = sanlk_path
SOURCE1 = devcount.c
SOURCE2 = sanlk_load.c
SOURCE3 = sanlk_client.c
SOURCE4 = killpath.c
+SOURCE5 = sanlk_path.c
CFLAGS += -D_GNU_SOURCE -g \
-Wall \
@@ -29,20 +31,23 @@ CFLAGS += -D_GNU_SOURCE -g \
LDFLAGS = -lrt -laio -lblkid -lsanlock
-all: $(TARGET1) $(TARGET2) $(TARGET3) $(TARGET4)
+all: $(TARGET1) $(TARGET2) $(TARGET3) $(TARGET4) $(TARGET5)
$(TARGET1): $(SOURCE1)
- $(CC) $(CFLAGS) $(LDFLAGS) $(SOURCE1) -o $@ -L. -L../src
+ $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ -L. -I../src -L../src
$(TARGET2): $(SOURCE2)
- $(CC) $(CFLAGS) $(LDFLAGS) $(SOURCE2) -o $@ -L. -L../src
+ $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ -L. -I../src -L../src
$(TARGET3): $(SOURCE3)
- $(CC) $(CFLAGS) $(LDFLAGS) $(SOURCE3) -o $@ -L. -L../src
+ $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ -L. -I../src -L../src
$(TARGET4): $(SOURCE4)
- $(CC) $(CFLAGS) $(LDFLAGS) $(SOURCE4) -o $@ -L. -L../src
+ $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ -L. -I../src -L../src
+
+$(TARGET5): $(SOURCE5)
+ $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ -L. -I../src -L../src
clean:
- rm -f *.o *.so *.so.* $(TARGET) $(TARGET2) $(TARGET3) $(TARGET4)
+ rm -f *.o *.so *.so.* $(TARGET) $(TARGET2) $(TARGET3) $(TARGET4) $(TARGET5)
diff --git a/tests/sanlk_path.c b/tests/sanlk_path.c
new file mode 100644
index 0000000..f9d8f6f
--- /dev/null
+++ b/tests/sanlk_path.c
@@ -0,0 +1,130 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "sanlock.h"
+#include "sanlock_resource.h"
+
+#define DSTMAXSIZE 1024
+
+static int __test_passed = 0;
+
+#define check_perror(expression, fmt, args...) \
+if (expression) { \
+ __test_passed++; \
+} \
+else { \
+ fprintf(stderr, "%s:%i " fmt "\n", __FILE__, __LINE__, ##args); \
+ exit(1); \
+}
+
+void test_sanlock_path_export(void)
+{
+ int rv, dst_len;
+ char dst_str[DSTMAXSIZE];
+ const char *src_str, *dst_exp;
+
+ /* regular behavior, no escapes */
+ src_str = "Hello World";
+ dst_exp = src_str;
+ dst_len = strlen(dst_exp);
+
+ memset(dst_str, 'X', DSTMAXSIZE);
+
+ /* destination too short */
+ rv = sanlock_path_export(dst_str, src_str, dst_len);
+ check_perror(rv == 0, "sanlock_path_export wrong return code: %u", rv);
+ check_perror(dst_str[dst_len] == 'X',
+ "sanlock_path_export buffer overflow");
+
+ /* destination long enough */
+ rv = sanlock_path_export(dst_str, src_str, dst_len + 1);
+ check_perror(rv == dst_len,
+ "sanlock_path_export wrong return code: %u", rv);
+ check_perror(dst_str[dst_len] == '\0',
+ "sanlock_path_import destination not terminated");
+ check_perror(!strncmp(dst_str, dst_exp, dst_len),
+ "sanlock_path_export destination is different");
+
+ /* special behavior, escapes */
+ src_str = "Hello World:";
+ dst_exp = "Hello World\\:";
+ dst_len = strlen(dst_exp);
+
+ memset(dst_str, 'X', DSTMAXSIZE);
+
+ /* destination too short */
+ rv = sanlock_path_export(dst_str, src_str, dst_len);
+ check_perror(rv == 0, "sanlock_path_export wrong return code: %u", rv);
+ check_perror(dst_str[dst_len] == 'X',
+ "sanlock_path_export buffer overflow");
+
+ /* destination long enough */
+ rv = sanlock_path_export(dst_str, src_str, dst_len + 1);
+ check_perror(rv == dst_len,
+ "sanlock_path_export wrong return code: %u", rv);
+ check_perror(dst_str[dst_len] == '\0',
+ "sanlock_path_import destination not terminated");
+ check_perror(!strncmp(dst_str, dst_exp, dst_len),
+ "sanlock_path_export destination is different");
+}
+
+void test_sanlock_path_import(void)
+{
+ int rv, dst_len;
+ char dst_str[DSTMAXSIZE];
+ const char *src_str, *dst_exp;
+
+ /* regular behavior, no escapes */
+ src_str = "Hello World";
+ dst_exp = src_str;
+ dst_len = strlen(dst_exp);
+
+ memset(dst_str, 'X', DSTMAXSIZE);
+
+ /* destination too short */
+ rv = sanlock_path_import(dst_str, src_str, dst_len);
+ check_perror(rv == 0, "sanlock_path_import wrong return code: %u", rv);
+ check_perror(dst_str[dst_len] == 'X',
+ "sanlock_path_import buffer overflow");
+
+ /* destination long enough */
+ rv = sanlock_path_import(dst_str, src_str, dst_len + 1);
+ check_perror(rv == dst_len,
+ "sanlock_path_import wrong return code: %u", rv);
+ check_perror(dst_str[dst_len] == '\0',
+ "sanlock_path_import destination not terminated");
+ check_perror(!strncmp(dst_str, dst_exp, dst_len),
+ "sanlock_path_import destination is different");
+
+ /* special behavior, escapes */
+ src_str = "Hello World\\:";
+ dst_exp = "Hello World:";
+ dst_len = strlen(dst_exp);
+
+ memset(dst_str, 'X', DSTMAXSIZE);
+
+ /* destination too short */
+ rv = sanlock_path_import(dst_str, src_str, dst_len);
+ check_perror(rv == 0, "sanlock_path_import wrong return code: %u", rv);
+ check_perror(dst_str[dst_len] == 'X',
+ "sanlock_path_import buffer overflow");
+
+ /* destination long enough */
+ rv = sanlock_path_import(dst_str, src_str, dst_len + 1);
+ check_perror(rv == dst_len,
+ "sanlock_path_import wrong return code: %u", rv);
+ check_perror(dst_str[dst_len] == '\0',
+ "sanlock_path_import destination not terminated");
+ check_perror(!strncmp(dst_str, dst_exp, dst_len),
+ "sanlock_path_import destination is different");
+}
+
+int main(int argc, char *argv[])
+{
+ test_sanlock_path_export();
+ test_sanlock_path_import();
+ printf("OK, %i tests sucessfully passed.\n", __test_passed);
+ return 0;
+}
11 years, 7 months
[PATCH] sanlock: expose sanlock path import and export utils
by Federico Simoncelli
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
src/client.c | 56 +++++++++++++++++------
src/sanlock.h | 4 +-
tests/Makefile | 17 ++++--
tests/sanlk_path.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 186 insertions(+), 21 deletions(-)
create mode 100644 tests/sanlk_path.c
diff --git a/src/client.c b/src/client.c
index e8b61be..3c7287e 100644
--- a/src/client.c
+++ b/src/client.c
@@ -238,28 +238,56 @@ int sanlock_init(struct sanlk_lockspace *ls,
/* src has colons unescaped, dst should have them escaped with backslash */
-static void copy_path_out(char *dst, char *src)
+size_t sanlock_path_export(char *dst, const char *src, size_t dstlen)
{
- int i, j = 0;
+ size_t j = 0, escaped = 0;
+ const char *p = src;
+
+ while (j < dstlen) {
+ if (*p == ':' || *p == '\\') {
+ if (!escaped) {
+ dst[j] = '\\', escaped = 1;
+ goto next_loop;
+ }
+
+ escaped = 0;
+ }
+
+ dst[j] = *p;
- for (i = 0; i < strlen(src); i++) {
- if (src[i] == ':')
- dst[j++] = '\\';
- dst[j++] = src[i];
+ if (*p == '\0') return j; /* success */
+ p++;
+
+ next_loop:
+ j++;
}
+
+ return 0;
}
/* src has colons escaped with backslash, dst should have backslash removed */
-static void copy_path_in(char *dst, char *src)
+size_t sanlock_path_import(char *dst, const char *src, size_t dstlen)
{
- int i, j = 0;
+ size_t j = 0;
+ const char *p = src;
- for (i = 0; i < strlen(src); i++) {
- if (src[i] == '\\')
- continue;
- dst[j++] = src[i];
+ while (j < dstlen) {
+ if (*p == '\\')
+ goto next_loop;
+
+ dst[j] = *p;
+
+ if (*p == '\0')
+ return j;
+
+ j++;
+
+ next_loop:
+ p++;
}
+
+ return 0;
}
int sanlock_register(void)
@@ -636,7 +664,7 @@ int sanlock_res_to_str(struct sanlk_resource *res, char **str_ret)
for (d = 0; d < res->num_disks; d++) {
memset(path, 0, sizeof(path));
- copy_path_out(path, res->disks[d].path);
+ sanlock_path_export(path, res->disks[d].path, sizeof(path));
ret = snprintf(str + pos, len - pos, ":%s:%llu", path,
(unsigned long long)res->disks[d].offset);
@@ -946,7 +974,7 @@ int sanlock_str_to_lockspace(char *str, struct sanlk_lockspace *ls)
if (host_id)
ls->host_id = atoll(host_id);
if (path)
- copy_path_in(ls->host_id_disk.path, path);
+ sanlock_path_import(ls->host_id_disk.path, path, sizeof(ls->host_id_disk.path));
if (offset)
ls->host_id_disk.offset = atoll(offset);
diff --git a/src/sanlock.h b/src/sanlock.h
index e36c40e..457ab7a 100644
--- a/src/sanlock.h
+++ b/src/sanlock.h
@@ -91,5 +91,7 @@ struct sanlk_lockspace {
struct sanlk_disk host_id_disk;
};
-#endif
+size_t sanlock_path_export(char *dst, const char *src, size_t dstlen);
+size_t sanlock_path_import(char *dst, const char *src, size_t dstlen);
+#endif
diff --git a/tests/Makefile b/tests/Makefile
index 838ad23..28f5d21 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -2,11 +2,13 @@ TARGET1 = devcount
TARGET2 = sanlk_load
TARGET3 = sanlk_client
TARGET4 = killpath
+TARGET5 = sanlk_path
SOURCE1 = devcount.c
SOURCE2 = sanlk_load.c
SOURCE3 = sanlk_client.c
SOURCE4 = killpath.c
+SOURCE5 = sanlk_path.c
CFLAGS += -D_GNU_SOURCE -g \
-Wall \
@@ -29,20 +31,23 @@ CFLAGS += -D_GNU_SOURCE -g \
LDFLAGS = -lrt -laio -lblkid -lsanlock
-all: $(TARGET1) $(TARGET2) $(TARGET3) $(TARGET4)
+all: $(TARGET1) $(TARGET2) $(TARGET3) $(TARGET4) $(TARGET5)
$(TARGET1): $(SOURCE1)
- $(CC) $(CFLAGS) $(LDFLAGS) $(SOURCE1) -o $@ -L. -L../src
+ $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ -L. -I../src -L../src
$(TARGET2): $(SOURCE2)
- $(CC) $(CFLAGS) $(LDFLAGS) $(SOURCE2) -o $@ -L. -L../src
+ $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ -L. -I../src -L../src
$(TARGET3): $(SOURCE3)
- $(CC) $(CFLAGS) $(LDFLAGS) $(SOURCE3) -o $@ -L. -L../src
+ $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ -L. -I../src -L../src
$(TARGET4): $(SOURCE4)
- $(CC) $(CFLAGS) $(LDFLAGS) $(SOURCE4) -o $@ -L. -L../src
+ $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ -L. -I../src -L../src
+
+$(TARGET5): $(SOURCE5)
+ $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ -L. -I../src -L../src
clean:
- rm -f *.o *.so *.so.* $(TARGET) $(TARGET2) $(TARGET3) $(TARGET4)
+ rm -f *.o *.so *.so.* $(TARGET) $(TARGET2) $(TARGET3) $(TARGET4) $(TARGET5)
diff --git a/tests/sanlk_path.c b/tests/sanlk_path.c
new file mode 100644
index 0000000..f9d8f6f
--- /dev/null
+++ b/tests/sanlk_path.c
@@ -0,0 +1,130 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "sanlock.h"
+#include "sanlock_resource.h"
+
+#define DSTMAXSIZE 1024
+
+static int __test_passed = 0;
+
+#define check_perror(expression, fmt, args...) \
+if (expression) { \
+ __test_passed++; \
+} \
+else { \
+ fprintf(stderr, "%s:%i " fmt "\n", __FILE__, __LINE__, ##args); \
+ exit(1); \
+}
+
+void test_sanlock_path_export(void)
+{
+ int rv, dst_len;
+ char dst_str[DSTMAXSIZE];
+ const char *src_str, *dst_exp;
+
+ /* regular behavior, no escapes */
+ src_str = "Hello World";
+ dst_exp = src_str;
+ dst_len = strlen(dst_exp);
+
+ memset(dst_str, 'X', DSTMAXSIZE);
+
+ /* destination too short */
+ rv = sanlock_path_export(dst_str, src_str, dst_len);
+ check_perror(rv == 0, "sanlock_path_export wrong return code: %u", rv);
+ check_perror(dst_str[dst_len] == 'X',
+ "sanlock_path_export buffer overflow");
+
+ /* destination long enough */
+ rv = sanlock_path_export(dst_str, src_str, dst_len + 1);
+ check_perror(rv == dst_len,
+ "sanlock_path_export wrong return code: %u", rv);
+ check_perror(dst_str[dst_len] == '\0',
+ "sanlock_path_import destination not terminated");
+ check_perror(!strncmp(dst_str, dst_exp, dst_len),
+ "sanlock_path_export destination is different");
+
+ /* special behavior, escapes */
+ src_str = "Hello World:";
+ dst_exp = "Hello World\\:";
+ dst_len = strlen(dst_exp);
+
+ memset(dst_str, 'X', DSTMAXSIZE);
+
+ /* destination too short */
+ rv = sanlock_path_export(dst_str, src_str, dst_len);
+ check_perror(rv == 0, "sanlock_path_export wrong return code: %u", rv);
+ check_perror(dst_str[dst_len] == 'X',
+ "sanlock_path_export buffer overflow");
+
+ /* destination long enough */
+ rv = sanlock_path_export(dst_str, src_str, dst_len + 1);
+ check_perror(rv == dst_len,
+ "sanlock_path_export wrong return code: %u", rv);
+ check_perror(dst_str[dst_len] == '\0',
+ "sanlock_path_import destination not terminated");
+ check_perror(!strncmp(dst_str, dst_exp, dst_len),
+ "sanlock_path_export destination is different");
+}
+
+void test_sanlock_path_import(void)
+{
+ int rv, dst_len;
+ char dst_str[DSTMAXSIZE];
+ const char *src_str, *dst_exp;
+
+ /* regular behavior, no escapes */
+ src_str = "Hello World";
+ dst_exp = src_str;
+ dst_len = strlen(dst_exp);
+
+ memset(dst_str, 'X', DSTMAXSIZE);
+
+ /* destination too short */
+ rv = sanlock_path_import(dst_str, src_str, dst_len);
+ check_perror(rv == 0, "sanlock_path_import wrong return code: %u", rv);
+ check_perror(dst_str[dst_len] == 'X',
+ "sanlock_path_import buffer overflow");
+
+ /* destination long enough */
+ rv = sanlock_path_import(dst_str, src_str, dst_len + 1);
+ check_perror(rv == dst_len,
+ "sanlock_path_import wrong return code: %u", rv);
+ check_perror(dst_str[dst_len] == '\0',
+ "sanlock_path_import destination not terminated");
+ check_perror(!strncmp(dst_str, dst_exp, dst_len),
+ "sanlock_path_import destination is different");
+
+ /* special behavior, escapes */
+ src_str = "Hello World\\:";
+ dst_exp = "Hello World:";
+ dst_len = strlen(dst_exp);
+
+ memset(dst_str, 'X', DSTMAXSIZE);
+
+ /* destination too short */
+ rv = sanlock_path_import(dst_str, src_str, dst_len);
+ check_perror(rv == 0, "sanlock_path_import wrong return code: %u", rv);
+ check_perror(dst_str[dst_len] == 'X',
+ "sanlock_path_import buffer overflow");
+
+ /* destination long enough */
+ rv = sanlock_path_import(dst_str, src_str, dst_len + 1);
+ check_perror(rv == dst_len,
+ "sanlock_path_import wrong return code: %u", rv);
+ check_perror(dst_str[dst_len] == '\0',
+ "sanlock_path_import destination not terminated");
+ check_perror(!strncmp(dst_str, dst_exp, dst_len),
+ "sanlock_path_import destination is different");
+}
+
+int main(int argc, char *argv[])
+{
+ test_sanlock_path_export();
+ test_sanlock_path_import();
+ printf("OK, %i tests sucessfully passed.\n", __test_passed);
+ return 0;
+}
--
1.7.1
11 years, 7 months
Branch 'fence_sanlock' - 2 commits - fence_sanlock/fence_sanlock.in fence_sanlock/fence_sanlockd.c
by David Teigland
fence_sanlock/fence_sanlock.in | 48 +++++-------
fence_sanlock/fence_sanlockd.c | 160 ++++++++++++++++++++++++++++++++++++-----
2 files changed, 167 insertions(+), 41 deletions(-)
New commits:
commit 401d1830a7c0ba31789ee35d25d71aa5dc3a8889
Author: David Teigland <teigland(a)redhat.com>
Date: Thu Sep 20 17:16:06 2012 -0500
fence_sanlockd: allow options to be delayed
When fence_sanlockd is started with -w, it will
wait for fence_sanlockd -s to send it the
-i and -p options.
Signed-off-by: David Teigland <teigland(a)redhat.com>
diff --git a/fence_sanlock/fence_sanlockd.c b/fence_sanlock/fence_sanlockd.c
index e491ded..7f62e0a 100644
--- a/fence_sanlock/fence_sanlockd.c
+++ b/fence_sanlock/fence_sanlockd.c
@@ -60,8 +60,9 @@
#define RUN_DIR "/var/run/fence_sanlockd"
static char *prog_name = (char *)"fence_sanlockd";
-static int shutdown;
+
static int we_are_victim;
+static int shutdown;
static int daemon_debug;
static int our_host_id;
static char path[PATH_MAX];
@@ -70,6 +71,13 @@ static struct sanlk_resource *r;
static struct sanlk_disk disk;
static char rdbuf[sizeof(struct sanlk_resource) + sizeof(struct sanlk_disk)];
static char lockfile_path[PATH_MAX];
+static char fifo_path[PATH_MAX];
+static char fifo_line[PATH_MAX];
+static char key1[PATH_MAX];
+static char key2[PATH_MAX];
+static char val1[PATH_MAX];
+static char val2[PATH_MAX];
+
struct client {
int used;
@@ -258,17 +266,105 @@ static int setup_signals(void)
return 0;
}
+static int wait_options(void)
+{
+ int fd, rv;
+
+ snprintf(fifo_path, PATH_MAX-1, "%s/prog_name.fifo", RUN_DIR);
+
+ rv = mkfifo(fifo_path, (S_IRUSR | S_IWUSR));
+ if (rv && errno != EEXIST) {
+ log_error("wait_options mkfifo error %d %s", errno, fifo_path);
+ return -1;
+ }
+
+ fd = open(fifo_path, O_RDONLY|O_CLOEXEC);
+ if (fd < 0) {
+ log_error("wait_options fifo open error %d %s", errno, fifo_path);
+ unlink(fifo_path);
+ return -1;
+ }
+
+ reread:
+ memset(fifo_line, 0, sizeof(fifo_line));
+
+ rv = read(fd, fifo_line, sizeof(fifo_line));
+ if (rv < 0) {
+ log_error("wait_options read error %d", errno);
+ goto out;
+ }
+
+ rv = sscanf(fifo_line, "%s %s %s %s", key1, val1, key2, val2);
+ if (rv != 4) {
+ log_error("wait_options scan error %d", rv);
+ goto reread;
+ }
+
+ if (strcmp(key1, "-p") || strcmp(key2, "-i")) {
+ log_error("wait_options args error");
+ goto reread;
+ }
+
+ strncpy(path, val1, PATH_MAX-1);
+ our_host_id = atoi(val2);
+
+ if (!our_host_id || our_host_id > MAX_HOSTS) {
+ log_error("wait_options invalid host_id");
+ goto reread;
+ }
+
+ if (!path[0]) {
+ log_error("wait_options invalid path");
+ goto reread;
+ }
+
+ log_debug("wait_options -p %s -i %d", path, our_host_id);
+ out:
+ close(fd);
+ unlink(fifo_path);
+ return 0;
+}
+
+static int send_options(void)
+{
+ int fd, rv;
+
+ snprintf(fifo_path, PATH_MAX-1, "%s/prog_name.fifo", RUN_DIR);
+
+ fd = open(fifo_path, O_WRONLY|O_CLOEXEC);
+ if (fd < 0) {
+ fprintf(stderr, "fifo open error %d %s\n", errno, fifo_path);
+ return -1;
+ }
+
+ memset(fifo_line, 0, sizeof(fifo_line));
+
+ snprintf(fifo_line, PATH_MAX-1, "-p %s -i %d", path, our_host_id);
+
+ rv = write(fd, fifo_line, sizeof(fifo_line));
+ if (rv < 0) {
+ fprintf(stderr, "fifo write error %d\n", errno);
+ } else {
+ rv = 0;
+ }
+
+ close(fd);
+ return rv;
+}
+
static void print_usage(void)
{
printf("Usage:\n");
- printf("fence_sanlockd -p <path> -i <host_id>\n");
+ printf("fence_sanlockd [options]\n");
printf("\n");
printf("Options:\n");
- printf(" -D Enable debugging to stderr and don't fork\n");
- printf(" -p <path> Path to shared storage with sanlock leases\n");
- printf(" -i <host_id> Local sanlock host_id\n");
- printf(" -h Print this help, then exit\n");
- printf(" -V Print program version information, then exit\n");
+ printf(" -D Enable debugging to stderr and don't fork\n");
+ printf(" -p <path> Path to shared storage with sanlock leases\n");
+ printf(" -i <host_id> Local sanlock host_id (1-%d)\n", MAX_HOSTS);
+ printf(" -w Wait for fence_sanlockd -s to send options (p,i)\n");
+ printf(" -s Send options (p,i) to waiting fence_sanlockd -w\n");
+ printf(" -h Print this help, then exit\n");
+ printf(" -V Print program version information, then exit\n");
}
int main(int argc, char *argv[])
@@ -278,13 +374,14 @@ int main(int argc, char *argv[])
uint64_t live_time, now;
int poll_timeout;
int sleep_seconds;
+ int send_opts = 0, wait_opts = 0;
int cont = 1;
int optchar;
int sock, con, rv, i;
int align;
while (cont) {
- optchar = getopt(argc, argv, "Dp:i:hV");
+ optchar = getopt(argc, argv, "Dp:i:hVws");
switch (optchar) {
case 'D':
@@ -295,6 +392,17 @@ int main(int argc, char *argv[])
break;
case 'i':
our_host_id = atoi(optarg);
+ if (our_host_id > MAX_HOSTS) {
+ fprintf(stderr, "invalid host_id %d, use 1-%d\n",
+ our_host_id, MAX_HOSTS);
+ exit(1);
+ }
+ break;
+ case 'w':
+ wait_opts = 1;
+ break;
+ case 's':
+ send_opts = 1;
break;
case 'h':
print_usage();
@@ -312,18 +420,21 @@ int main(int argc, char *argv[])
};
}
- if (!our_host_id || our_host_id > MAX_HOSTS) {
- daemon_debug = 1;
- log_error("-i %d invalid, our_host_id must be between 1 and %d", our_host_id, MAX_HOSTS);
+ if (wait_opts && send_opts) {
+ fprintf(stderr, "-w and -s options cannot be used together\n");
exit(1);
}
- if (!path[0]) {
- daemon_debug = 1;
- log_error("path arg required");
+ if (!wait_opts && (!our_host_id || !path[0])) {
+ fprintf(stderr, "-i and -p options required\n");
exit(1);
}
+ if (send_opts) {
+ rv = send_options();
+ return rv;
+ }
+
if (!daemon_debug) {
if (daemon(0, 0) < 0) {
fprintf(stderr, "cannot fork daemon\n");
@@ -341,6 +452,12 @@ int main(int argc, char *argv[])
if (rv < 0)
goto out_lockfile;
+ if (wait_opts) {
+ rv = wait_options();
+ if (rv < 0)
+ goto out_lockfile;
+ }
+
con = wdmd_connect();
if (con < 0) {
log_error("wdmd connect error %d", con);
commit 0a80be08c4f85b9e1ab1c9db7911def51e213faf
Author: David Teigland <teigland(a)redhat.com>
Date: Thu Sep 20 14:06:00 2012 -0500
fence_sanlock: variable alignment
- make lease size depend on disk sector size
- clarify fence_sanlock read_leader behavior
Signed-off-by: David Teigland <teigland(a)redhat.com>
diff --git a/fence_sanlock/fence_sanlock.in b/fence_sanlock/fence_sanlock.in
index a6f9178..f43acc2 100755
--- a/fence_sanlock/fence_sanlock.in
+++ b/fence_sanlock/fence_sanlock.in
@@ -165,35 +165,24 @@ EOF
return 0
}
-get_leader_info() {
+read_leader() {
+ # verify storage has been initialized
+
leader=$(sanlock direct read_leader -r fence:h$host_id:$path:$offset 2>&1)
[ "$?" != 0 ] && {
- echo "Unable to read $path"
+ echo "Error: unable to read $path"
return 1
}
- timestamp="$(echo "$leader" | grep ^timestamp | awk '{print $NF}')"
-
- [ -z "$timestamp" ] && {
- echo "Unable to determine timestamp"
- return 1
- }
-
- return 0
-}
-
-verify_path() {
- # verify storage has been initialized
-
- get_leader_info || return 1
-
magic="$(echo "$leader" | grep magic | awk '{print $NF}')"
+
[ -z "$magic" ] && {
- echo "Unable to determine $path sanlock magic"
+ echo "Error: no sanlock magic number at $path:$offset"
return 1
}
+
[ "$magic" != "0x6152010" ] && {
- echo "Error: $path magic $magic does not match sanlock magic 0x6152010"
+ echo "Error: invalid sanlock magic number $magic at $path:$offset"
return 1
}
@@ -201,7 +190,7 @@ verify_path() {
}
action_on() {
- verify_path || return 1
+ read_leader || return 1
[ -z "$(pidof fence_sanlockd)" ] && {
daemonerr="$(fence_sanlockd -p $path -i $host_id 2>&1)"
@@ -245,11 +234,12 @@ action_on() {
}
action_off() {
- verify_path || return 1
+ read_leader || return 1
owner_id="$(echo "$leader" | grep owner_id | awk '{print $NF}')"
owner_gen="$(echo "$leader" | grep owner_gen | awk '{print $NF}')"
ver="$(echo "$leader" | grep lver | awk '{print $NF}')"
+ timestamp="$(echo "$leader" | grep ^timestamp | awk '{print $NF}')"
# lease is released, so host is off
[ "$timestamp" = 0 ] && {
@@ -308,7 +298,7 @@ action_off() {
# reacquired cleanly by the victim host (same host_id, new
# generation), we can quit with success
- get_leader_info || return 1
+ read_leader || return 1
tmp_id="$(echo "$leader" | grep owner_id | awk '{print $NF}')"
tmp_gen="$(echo "$leader" | grep owner_gen | awk '{print $NF}')"
@@ -328,7 +318,9 @@ action_off() {
}
action_status() {
- verify_path || return 1
+ read_leader || return 1
+
+ timestamp="$(echo "$leader" | grep ^timestamp | awk '{print $NF}')"
# lease is released, so host is "off"
[ "$timestamp" = 0 ] && {
@@ -351,7 +343,7 @@ sanlock_init() {
echo -n "Initializing $max_hosts sanlock host leases on $path: "
for host_id in $(seq 1 $max_hosts); do
- offset=$((host_id * 1048576))
+ offset=$((host_id * $align))
sanlock direct init -r fence:h$host_id:$path:$offset \
> /dev/null 2>/dev/null || \
{ echo "error $? for host $host_id" && return 1; }
@@ -365,16 +357,22 @@ sanlock_init() {
# check actions and options compatibility
# all actions beside metadata needs storage
+
[ "$action" != "metadata" ] && {
[ -z "$path" ] && {
echo "storage path argument required"
exit 1
}
+
# all actions beside sanlock_init needs host_id
[ "$action" != "sanlock_init" ] && [ -z "$host_id" ] && {
echo "host_id argument required"
exit 1
}
+
+ # FIXME: add direct align command to sanlock
+ # align="&(sanlock direct align $path)"
+ align=1048576
}
# verify host_id parameter
@@ -383,7 +381,7 @@ sanlock_init() {
echo "host_id must be between 1 and $max_hosts"
exit 1
fi
- offset=$((host_id * 1048576))
+ offset=$((host_id * $align))
}
case "$action" in
diff --git a/fence_sanlock/fence_sanlockd.c b/fence_sanlock/fence_sanlockd.c
index ea7ffdc..e491ded 100644
--- a/fence_sanlock/fence_sanlockd.c
+++ b/fence_sanlock/fence_sanlockd.c
@@ -28,11 +28,11 @@
#include "sanlock.h"
#include "sanlock_admin.h"
#include "sanlock_resource.h"
+#include "sanlock_direct.h"
#include "wdmd.h"
/*
* TODO:
- * handle 4k disk blocks using sanlock_align()
* variable i/o timeouts?
*
* shutdown: how/when does SIGTERM happen?
@@ -67,6 +67,7 @@ static int our_host_id;
static char path[PATH_MAX];
static struct sanlk_lockspace ls;
static struct sanlk_resource *r;
+static struct sanlk_disk disk;
static char rdbuf[sizeof(struct sanlk_resource) + sizeof(struct sanlk_disk)];
static char lockfile_path[PATH_MAX];
@@ -280,6 +281,7 @@ int main(int argc, char *argv[])
int cont = 1;
int optchar;
int sock, con, rv, i;
+ int align;
while (cont) {
optchar = getopt(argc, argv, "Dp:i:hV");
@@ -369,6 +371,15 @@ int main(int argc, char *argv[])
goto out_refcount;
}
+ memset(&disk, 0, sizeof(disk));
+ sprintf(disk.path, "%s", path);
+
+ align = sanlock_direct_align(&disk);
+ if (align < 0) {
+ log_error("direct_align error %d", align);
+ goto out_refcount;
+ }
+
memset(&ls, 0, sizeof(ls));
sprintf(ls.host_id_disk.path, "%s", path);
strcpy(ls.name, "fence");
@@ -389,7 +400,7 @@ int main(int argc, char *argv[])
strcpy(r->lockspace_name, "fence");
sprintf(r->name, "h%d", our_host_id);
sprintf(r->disks[0].path, "%s", path);
- r->disks[0].offset = our_host_id * 1048576;
+ r->disks[0].offset = our_host_id * align;
r->num_disks = 1;
log_debug("acquire begin");
11 years, 7 months
Changes to 'wdmd-script'
by David Teigland
New branch 'wdmd-script' available with the following commits:
commit fd94edfb41221f41acfffad469caca07321d8ee9
Author: David Teigland <teigland(a)redhat.com>
Date: Wed Sep 19 15:15:05 2012 -0500
wdmd: new script handling
Rewrite the code for using test scripts,
enabled by -S 1. Also added dumping
daemon state by wdmd --dump.
Signed-off-by: David Teigland <teigland(a)redhat.com>
11 years, 7 months
Branch 'fence_sanlock' - fence_sanlock/fence_sanlock.in fence_sanlock/fence_sanlockd.c
by David Teigland
fence_sanlock/fence_sanlock.in | 147 +++++++++++++++++++++++++----------------
fence_sanlock/fence_sanlockd.c | 22 +++---
2 files changed, 104 insertions(+), 65 deletions(-)
New commits:
commit e467b2092ade617fa0ed107a614fdac0259c0ec5
Author: David Teigland <teigland(a)redhat.com>
Date: Tue Sep 18 13:47:00 2012 -0500
fence_sanlock: various fixes and changes
- change device arg name to path
- add some metadata descriptions
- in off, make request after first acquire fails
- in off, always success after acquire works
- in off, check if victim re-acquired cleanly
- in off, check if already off at start
- in status, use ^timestamp
Signed-off-by: David Teigland <teigland(a)redhat.com>
diff --git a/fence_sanlock/fence_sanlock.in b/fence_sanlock/fence_sanlock.in
index 1cea274..1140880 100755
--- a/fence_sanlock/fence_sanlock.in
+++ b/fence_sanlock/fence_sanlock.in
@@ -30,10 +30,10 @@
# </unfence>
# </clusternode>
#
-# <fencedevice name="wd" agent="fence_sanlock" device="/dev/fence_sanlock/leases"/>
+# <fencedevice name="wd" agent="fence_sanlock" path="/dev/fence_sanlock/leases"/>
# setup (one time only):
-# fence_sanlock sanlock_init $device
+# fence_sanlock -o sanlock_init -p $path
#
# startup:
# service wdmd start
@@ -44,7 +44,7 @@
max_hosts=128
opts=
action=
-device=
+path=
host_id=
offset=
@@ -56,14 +56,14 @@ help() {
echo "Options:"
echo " -o <action> Action: off (default), on, status or metadata"
echo " (sanlock specific actions: sanlock_init)"
- echo " -d <path> sanlock shared storage for leases"
+ echo " -p <path> sanlock shared storage for leases"
echo " -i <num> sanlock host_id of node to operate on"
echo " -h Print this help, then exit"
echo " -V Print program version information, then exit"
echo ""
echo "stdin options:"
echo " action=<action>"
- echo " device=<path>"
+ echo " path=<path>"
echo " host_id=<num>"
}
@@ -74,8 +74,8 @@ cli_options() {
action=$2
shift
;;
- -d)
- device=$2
+ -p)
+ path=$2
shift
;;
-i)
@@ -103,8 +103,8 @@ stdin_options() {
action)
action=$val
;;
- device)
- device=$val
+ path)
+ path=$val
;;
host_id)
host_id=$val
@@ -117,7 +117,7 @@ stdin_options() {
if [ $# -eq 0 ]; then
stdin_options
else
- opts=$(getopt n:o:d:i:hV $@)
+ opts=$(getopt n:o:p:i:hV $@)
if [ "$?" != 0 ]; then
help
exit 1
@@ -125,13 +125,15 @@ else
cli_options $opts
fi
-# FIXME: Dave to review descriptions
metadata() {
cat << EOF
<?xml version="1.0" ?>
-<resource-agent name="fence_sanlock" shortdesc="Fence agent for sanlock shared storage" >
+<resource-agent name="fence_sanlock" shortdesc="Fence agent for watchdog and shared storage">
<longdesc>
-fence_sanlock is ... add long description here.
+fence_sanlock is an i/o fencing agent that uses the watchdog device to
+reset nodes. Shared storage (block or file) is used by sanlock to ensure
+that fenced nodes are reset, and to notify partitioned nodes that they
+need to be reset.
</longdesc>
<vendor-url>http://www.redhat.com/</vendor-url>
<parameters>
@@ -140,15 +142,15 @@ fence_sanlock is ... add long description here.
<content type="string" default="off" />
<shortdesc lang="en">Fencing Action</shortdesc>
</parameter>
- <parameter name="device" unique="0" required="1">
- <getopt mixed="-d <action>" />
+ <parameter name="path" unique="0" required="1">
+ <getopt mixed="-p <action>" />
<content type="string" />
- <shortdesc lang="en">Path to sanlock shared storage device</shortdesc>
+ <shortdesc lang="en">Path to sanlock shared storage</shortdesc>
</parameter>
<parameter name="host_id" unique="0" required="1">
<getopt mixed="-i <action>" />
<content type="string" />
- <shortdesc lang="en">Path to sanlock shared storage device</shortdesc>
+ <shortdesc lang="en">Host id for sanlock (1-128)</shortdesc>
</parameter>
</parameters>
<actions>
@@ -163,31 +165,31 @@ EOF
return 0
}
-verify_device() {
- # verify device has been initialized
+verify_path() {
+ # verify storage has been initialized
- leader=$(sanlock direct read_leader -r fence:h$host_id:$device:$offset 2>&1)
+ leader=$(sanlock direct read_leader -r fence:h$host_id:$path:$offset 2>&1)
[ "$?" != 0 ] && {
- echo "Unable to read $device information"
+ echo "Unable to read $path"
return 1
}
magic="$(echo "$leader" | grep magic | awk '{print $NF}')"
[ -z "$magic" ] && {
- echo "Unable to determine $device sanlock magic"
+ echo "Unable to determine $path sanlock magic"
return 1
}
[ "$magic" != "0x6152010" ] && {
- echo "Error: $device magic does not match sanlock magic"
+ echo "Error: $path magic $magic does not match sanlock magic 0x6152010"
return 1
}
return 0
}
action_on() {
- verify_device || return 1
+ verify_path || return 1
[ -z "$(pidof fence_sanlockd)" ] && {
- daemonerr="$(fence_sanlockd -d $device -i $host_id 2>&1)"
+ daemonerr="$(fence_sanlockd -p $path -i $host_id 2>&1)"
[ "$?" != 0 ] && {
echo "Unable to execute fence_sanlockd. Error:"
echo "$daemonerr"
@@ -199,7 +201,7 @@ action_on() {
# it can take minutes, and we can't allow fence_tool join
# until this is complete
- while ! sanlock client status | grep -q fence:h$host_id:$device:$offset; do
+ while ! sanlock client status | grep -q fence:h$host_id:$path:$offset; do
# FIXME: check that r is really done being acquired?
# just appearing in output may not be enough
@@ -210,60 +212,97 @@ action_on() {
}
action_off() {
- verify_device || return 1
+ verify_path || return 1
owner_id="$(echo "$leader" | grep owner_id | awk '{print $NF}')"
owner_gen="$(echo "$leader" | grep owner_gen | awk '{print $NF}')"
ver="$(echo "$leader" | grep lver | awk '{print $NF}')"
+ timestamp="$(echo "$leader" | grep ^timestamp | awk '{print $NF}')"
- # owner_id should equal host_id
- [ "$owner_id" != "$host_id" ] && {
- echo "Error: owner_id $owner_id does not match host_id $host_id"
+ [ -z "$timestamp" ] && {
+ echo "Unable to determine timestamp"
return 1
}
- sanlock client request -r fence:h$host_id:$device:$offset:$((ver + 1)) -f 2 > /dev/null 2>&1
- [ "$?" != 0 ] && {
- echo "Unable to send sanlock client request"
+ # lease is released, so host is off
+ [ "$timestamp" = 0 ] && {
+ return 0
+ }
+
+ # owner_id should equal host_id
+ [ "$owner_id" != "$host_id" ] && {
+ echo "victim lease $host_id owned by $owner_id:$owner_gen"
return 1
}
pid="$(pidof fence_sanlockd)"
[ -z "$pid" ] && {
- echo "Unable to determine fence_sanlockd pin"
+ echo "Unable to determine fence_sanlockd pid"
return 1
}
+ loop=0
+
# FIXME: should this loop have a retry limit?
while :
do
- sanlock client acquire -r fence:h$host_id:$device:$offset -p $pid
+ loop=$(($loop+1))
+
+ sanlock client acquire -r fence:h$host_id:$path:$offset -p $pid
[ "$?" = 0 ] && {
# fence success
- sanlock client release -r fence:h$host_id:$device:$offset -p $pid
+ sanlock client release -r fence:h$host_id:$path:$offset -p $pid
[ "$?" != 0 ] && {
- # FIXME: what should we do here?
- echo "Unable to release lock?"
- #return 1
+ echo "release $host_id error $?"
}
- break;
+ return 0
}
- sleep 5
+ if [ "$loop" = 1 ]; then
+
+ # acquire probably failed because the victim is
+ # still alive and renewing its lease, (we could
+ # verify that by checking the error code, but the
+ # error codes are currently messed up due to
+ # negation). use a request on the victim's lease
+ # to tell it that it's being fenced and needs to
+ # reset. the -f 2 causes SIGUSR1 to be sent to
+ # fence_sanlockd on the victim.
+
+ sanlock client request -r fence:h$host_id:$path:$offset:$((ver + 1)) -f 2 > /dev/null 2>&1
+ [ "$?" != 0 ] && {
+ echo "request $host_id error $?"
+ }
+ fi
+
+ sleep 10
+
+ # Reread the leader; if the victim's lease has been
+ # reacquired cleanly by the victim host (same host_id, new
+ # generation), we can quit with success
- # FIXME: there probably some errors here where we should just fail
+ leader=$(sanlock direct read_leader -r fence:h$host_id:$path:$offset 2>&1)
+ tmp_id="$(echo "$leader" | grep owner_id | awk '{print $NF}')"
+ tmp_gen="$(echo "$leader" | grep owner_gen | awk '{print $NF}')"
- # FIXME: we should probably reread the leader, and if it's been
- # reacquired cleanly by the host, I think we can quit with success
+ if [ "$owner_id" -eq "$tmp_id" ] && [ "$owner_gen" -lt "$tmp_gen" ]; then
+ echo "victim $owner_id:$owner_gen reacquired lease gen $tmp_gen"
+ return 0
+ fi
+
+ if [ "$owner_id" -ne "$tmp_id" ]; then
+ echo "victim $owner_id:$owner_gen acquired by $tmp_id:$tmp_gen"
+ return 1
+ fi
done
return 0
}
action_status() {
- verify_device || return 1
+ verify_path || return 1
- timestamp="$(echo "$leader" | grep timestamp | awk '{print $NF}')"
+ timestamp="$(echo "$leader" | grep ^timestamp | awk '{print $NF}')"
[ -z "$timestamp" ] && {
echo "Unable to determine timestamp"
@@ -282,17 +321,17 @@ action_status() {
}
sanlock_init() {
- # initialize lease device
- echo -n "Initializing lease device $device: "
- sanlock direct init -s fence:0:$device:0 \
+ # initialize lease path
+ echo -n "Initializing fence sanlock lockspace on $path: "
+ sanlock direct init -s fence:0:$path:0 \
> /dev/null 2>/dev/null || \
{ echo "error $?" && return 1; }
echo "ok"
- echo -n "Initializing host leases: "
+ echo -n "Initializing $max_hosts sanlock host leases on $path: "
for host_id in $(seq 1 $max_hosts); do
offset=$((host_id * 1048576))
- sanlock direct init -r fence:h$host_id:$device:$offset \
+ sanlock direct init -r fence:h$host_id:$path:$offset \
> /dev/null 2>/dev/null || \
{ echo "error $? for host $host_id" && return 1; }
done
@@ -304,10 +343,10 @@ sanlock_init() {
[ -z "$action" ] && action=off
# check actions and options compatibility
-# all actions beside metadata needs device
+# all actions beside metadata needs storage
[ "$action" != "metadata" ] && {
- [ -z "$device" ] && {
- echo "device argument required"
+ [ -z "$path" ] && {
+ echo "storage path argument required"
exit 1
}
# all actions beside sanlock_init needs host_id
diff --git a/fence_sanlock/fence_sanlockd.c b/fence_sanlock/fence_sanlockd.c
index 6a0de61..ea7ffdc 100644
--- a/fence_sanlock/fence_sanlockd.c
+++ b/fence_sanlock/fence_sanlockd.c
@@ -42,7 +42,7 @@
* start before cman and stop after cman. In future
* we could have the init script start the daemon,
* but that would also require a new config scheme
- * since we wouldn't be getting the device and host_id
+ * since we wouldn't be getting the path and host_id
* from cluster.conf via fence_node.
*
* simplest would be to have cman init just send us
@@ -64,7 +64,7 @@ static int shutdown;
static int we_are_victim;
static int daemon_debug;
static int our_host_id;
-static char device[PATH_MAX];
+static char path[PATH_MAX];
static struct sanlk_lockspace ls;
static struct sanlk_resource *r;
static char rdbuf[sizeof(struct sanlk_resource) + sizeof(struct sanlk_disk)];
@@ -260,11 +260,11 @@ static int setup_signals(void)
static void print_usage(void)
{
printf("Usage:\n");
- printf("fence_sanlockd -d <device> -i <host_id>\n");
+ printf("fence_sanlockd -p <path> -i <host_id>\n");
printf("\n");
printf("Options:\n");
printf(" -D Enable debugging to stderr and don't fork\n");
- printf(" -d <path> Path to shared storage with sanlock leases\n");
+ printf(" -p <path> Path to shared storage with sanlock leases\n");
printf(" -i <host_id> Local sanlock host_id\n");
printf(" -h Print this help, then exit\n");
printf(" -V Print program version information, then exit\n");
@@ -282,14 +282,14 @@ int main(int argc, char *argv[])
int sock, con, rv, i;
while (cont) {
- optchar = getopt(argc, argv, "Dd:i:hV");
+ optchar = getopt(argc, argv, "Dp:i:hV");
switch (optchar) {
case 'D':
daemon_debug = 1;
break;
- case 'd':
- strcpy(device, optarg);
+ case 'p':
+ strcpy(path, optarg);
break;
case 'i':
our_host_id = atoi(optarg);
@@ -316,9 +316,9 @@ int main(int argc, char *argv[])
exit(1);
}
- if (!device[0]) {
+ if (!path[0]) {
daemon_debug = 1;
- log_error("device arg required");
+ log_error("path arg required");
exit(1);
}
@@ -370,7 +370,7 @@ int main(int argc, char *argv[])
}
memset(&ls, 0, sizeof(ls));
- sprintf(ls.host_id_disk.path, "%s", device);
+ sprintf(ls.host_id_disk.path, "%s", path);
strcpy(ls.name, "fence");
ls.host_id = our_host_id;
@@ -388,7 +388,7 @@ int main(int argc, char *argv[])
r = (struct sanlk_resource *)&rdbuf;
strcpy(r->lockspace_name, "fence");
sprintf(r->name, "h%d", our_host_id);
- sprintf(r->disks[0].path, "%s", device);
+ sprintf(r->disks[0].path, "%s", path);
r->disks[0].offset = our_host_id * 1048576;
r->num_disks = 1;
11 years, 7 months
Changes to 'fence_sanlock'
by David Teigland
New branch 'fence_sanlock' available with the following commits:
commit 51b228a549e15b098b598786a9bfd3d7cfb7fd99
Author: David Teigland <teigland(a)redhat.com>
Date: Fri Sep 14 10:31:37 2012 -0500
fence_sanlock: new code
A fence agent that uses /dev/watchdog to reset hosts.
Per-host sanlock leases on shared storage are used:
- for hosts to detect that they are being fenced by
someone if they haven't actually failed
- for hosts to verify that fenced hosts have been
reset by seeing their host_id leases expire (not
be renewed on disk)
- for hosts to know how long to wait after fencing
before they can proceed, based on acquiring the
expired lease of the fenced host
Signed-off-by: David Teigland <teigland(a)redhat.com>
11 years, 7 months