src/client_admin.c | 4 -
src/client_resource.c | 44 +++++++++++++++
src/crc32c.c | 17 +-----
src/crc32c.h | 34 ------------
src/main.c | 136 +++++++++++++++++++++++++++++++++++++++++++++----
src/monotime.c | 8 ++
src/paxos_lease.c | 9 +--
src/sanlock_internal.h | 13 ----
src/sanlock_resource.h | 2
src/sanlock_sock.c | 8 ++
src/sanlock_sock.h | 12 ++++
src/task.c | 8 ++
src/token_manager.c | 45 ++++++++++++++++
src/token_manager.h | 3 +
wdmd/wdmd_sock.c | 8 ++
wdmd/wdmd_sock.h | 8 ++
16 files changed, 284 insertions(+), 75 deletions(-)
New commits:
commit aad12eec511f1ac442d7a6996db942959463a7e0
Author: David Teigland <teigland(a)redhat.com>
Date: Thu Aug 25 18:18:24 2011 -0500
sanlock/wdmd: add license header to files
diff --git a/src/monotime.c b/src/monotime.c
index 79e7a58..f76a716 100644
--- a/src/monotime.c
+++ b/src/monotime.c
@@ -1,3 +1,11 @@
+/*
+ * Copyright (C) 2010-2011 Red Hat, Inc. All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ */
+
#include <unistd.h>
#include <stdint.h>
#include <time.h>
diff --git a/src/sanlock_sock.c b/src/sanlock_sock.c
index dea7c34..5393017 100644
--- a/src/sanlock_sock.c
+++ b/src/sanlock_sock.c
@@ -1,3 +1,11 @@
+/*
+ * Copyright (C) 2010-2011 Red Hat, Inc. All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ */
+
#include <inttypes.h>
#include <unistd.h>
#include <stdio.h>
diff --git a/src/task.c b/src/task.c
index d54dabe..9635f92 100644
--- a/src/task.c
+++ b/src/task.c
@@ -1,3 +1,11 @@
+/*
+ * Copyright (C) 2010-2011 Red Hat, Inc. All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ */
+
#include <inttypes.h>
#include <unistd.h>
#include <stdio.h>
diff --git a/wdmd/wdmd_sock.c b/wdmd/wdmd_sock.c
index ef2923e..203c28e 100644
--- a/wdmd/wdmd_sock.c
+++ b/wdmd/wdmd_sock.c
@@ -1,3 +1,11 @@
+/*
+ * Copyright (C) 2010-2011 Red Hat, Inc. All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ */
+
#include <inttypes.h>
#include <unistd.h>
#include <stdio.h>
diff --git a/wdmd/wdmd_sock.h b/wdmd/wdmd_sock.h
index cf2f4b1..02c4c04 100644
--- a/wdmd/wdmd_sock.h
+++ b/wdmd/wdmd_sock.h
@@ -1,3 +1,11 @@
+/*
+ * Copyright (C) 2010-2011 Red Hat, Inc. All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ */
+
#ifndef __WDMD_SOCK_H__
#define __WDMD_SOCK_H__
commit 1786fc2d9fe2ca84a508cd8b4546ef9e55b38a6f
Author: David Teigland <teigland(a)redhat.com>
Date: Thu Aug 25 18:09:06 2011 -0500
sanlock: crc code tidying
- just use original license that was copied with the code
- remove the header
- change unsigned char const arg to uint8_t
diff --git a/src/crc32c.c b/src/crc32c.c
index 3edab07..6eaf703 100644
--- a/src/crc32c.c
+++ b/src/crc32c.c
@@ -1,11 +1,3 @@
-/*
- * Copyright (C) 2010-2011 Red Hat, Inc. All rights reserved.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
- */
-
/*
* Copied from the btrfs-progs source code, which...
* Copied from the kernel source code, lib/libcrc32c.c.
@@ -14,11 +6,9 @@
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
- *
*/
#include <unistd.h>
#include <stdint.h>
-#include "crc32c.h"
/*
* This is the CRC-32C table
@@ -101,11 +91,12 @@ static const uint32_t crc32c_table[256] = {
* crc using table.
*/
-uint32_t crc32c_le(uint32_t crc, unsigned char const *data, size_t length)
+uint32_t crc32c(uint32_t crc, uint8_t *data, size_t length);
+
+uint32_t crc32c(uint32_t crc, uint8_t *data, size_t length)
{
while (length--)
- crc =
- crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8);
+ crc = crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8);
return crc;
}
diff --git a/src/crc32c.h b/src/crc32c.h
deleted file mode 100644
index ae2a340..0000000
--- a/src/crc32c.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2010-2011 Red Hat, Inc. All rights reserved.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License v.2.
- */
-
-/*
- * Copyright (C) 2007 Red Hat. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License v2 as published by the Free Software Foundation.
- *
- * 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 GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 021110-1307, USA.
- */
-
-#ifndef __CRC32C__
-#define __CRC32C__
-
-uint32_t crc32c_le(uint32_t seed, unsigned char const *data, size_t length);
-
-#define crc32c(seed, data, length) crc32c_le(seed, (unsigned char const *)data, length)
-#endif
-
diff --git a/src/paxos_lease.c b/src/paxos_lease.c
index 1d9d7a3..570b5d7 100644
--- a/src/paxos_lease.c
+++ b/src/paxos_lease.c
@@ -25,11 +25,11 @@
#include "diskio.h"
#include "direct.h"
#include "log.h"
-#include "crc32c.h"
#include "host_id.h"
#include "delta_lease.h"
#include "paxos_lease.h"
+uint32_t crc32c(uint32_t crc, uint8_t *data, size_t length);
int get_rand(int a, int b);
struct request_record {
@@ -208,7 +208,7 @@ static int read_request(struct task *task,
static uint32_t dblock_checksum(struct paxos_dblock *pd)
{
- return crc32c((uint32_t)~1, (char *)pd, DBLOCK_CHECKSUM_LEN);
+ return crc32c((uint32_t)~1, (uint8_t *)pd, DBLOCK_CHECKSUM_LEN);
}
static int verify_dblock(struct token *token, struct paxos_dblock *pd)
@@ -566,7 +566,7 @@ static int run_ballot(struct task *task, struct token *token, int
num_hosts,
uint32_t leader_checksum(struct leader_record *lr)
{
- return crc32c((uint32_t)~1, (char *)lr, LEADER_CHECKSUM_LEN);
+ return crc32c((uint32_t)~1, (uint8_t *)lr, LEADER_CHECKSUM_LEN);
}
static void log_leader_error(int result,
commit 38496d10f78664727bf1f4419db2ed0980c6ee96
Author: David Teigland <teigland(a)redhat.com>
Date: Thu Aug 25 17:09:15 2011 -0500
sanlock: add request api/cmd
the actual implementation is not done
diff --git a/src/client_admin.c b/src/client_admin.c
index 94645ec..cb743b3 100644
--- a/src/client_admin.c
+++ b/src/client_admin.c
@@ -212,11 +212,11 @@ static int cmd_lockspace(int cmd, struct sanlk_lockspace *ls,
uint32_t flags)
rv = send_header(fd, cmd, flags, sizeof(struct sanlk_lockspace), 0, 0);
if (rv < 0)
- return rv;
+ goto out;
rv = send(fd, (void *)ls, sizeof(struct sanlk_lockspace), 0);
if (rv < 0) {
- rv = -1;
+ rv = -errno;
goto out;
}
diff --git a/src/client_resource.c b/src/client_resource.c
index 18f185f..0a02115 100644
--- a/src/client_resource.c
+++ b/src/client_resource.c
@@ -325,6 +325,50 @@ int sanlock_release(int sock, int pid, uint32_t flags, int
res_count,
return rv;
}
+int sanlock_request(uint32_t flags, uint32_t force_mode,
+ struct sanlk_resource *res)
+{
+ struct sm_header h;
+ int fd, rv, datalen;
+
+ datalen = sizeof(struct sanlk_resource) +
+ sizeof(struct sanlk_disk) * res->num_disks;
+
+ rv = connect_socket(&fd);
+ if (rv < 0)
+ return rv;
+
+ rv = send_header(fd, SM_CMD_REQUEST, flags, datalen, force_mode, 0);
+ if (rv < 0)
+ goto out;
+
+ rv = send(fd, res, sizeof(struct sanlk_resource), 0);
+ if (rv < 0) {
+ rv = -errno;
+ goto out;
+ }
+
+ rv = send(fd, res->disks, sizeof(struct sanlk_disk) * res->num_disks, 0);
+ if (rv < 0) {
+ rv = -errno;
+ goto out;
+ }
+
+ /* get result */
+
+ memset(&h, 0, sizeof(h));
+
+ rv = recv(fd, &h, sizeof(h), MSG_WAITALL);
+ if (rv != sizeof(h)) {
+ rv = -1;
+ goto out;
+ }
+ rv = (int)h.data;
+ out:
+ close(fd);
+ return rv;
+}
+
/*
* convert from struct sanlk_resource to string with format:
*
<lockspace_name>:<resource_name>:<path>:<offset>[:<path>:<offset>...]:<lver>
diff --git a/src/main.c b/src/main.c
index 3f0f448..6e0721a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1343,6 +1343,105 @@ static void cmd_inquire(struct task *task, struct cmd_args *ca)
client_resume(ca->ci_in);
}
+static void cmd_request(struct task *task, struct cmd_args *ca)
+{
+ struct sm_header h;
+ struct token *token;
+ struct sanlk_resource res;
+ uint64_t owner_id;
+ uint32_t force_mode;
+ int token_len, disks_len;
+ int j, fd, rv, result;
+
+ fd = client[ca->ci_in].fd;
+
+ force_mode = ca->header.data;
+
+ /* receiving and setting up token copied from cmd_acquire */
+
+ rv = recv(fd, &res, sizeof(struct sanlk_resource), MSG_WAITALL);
+ if (rv != sizeof(struct sanlk_resource)) {
+ log_error("cmd_request %d,%d recv %d %d",
+ ca->ci_in, fd, rv, errno);
+ result = -ENOTCONN;
+ goto reply;
+ }
+
+ if (!res.num_disks || res.num_disks > MAX_DISKS) {
+ result = -ERANGE;
+ goto reply;
+ }
+
+ disks_len = res.num_disks * sizeof(struct sync_disk);
+ token_len = sizeof(struct token) + disks_len;
+
+ token = malloc(token_len);
+ if (!token) {
+ result = -ENOMEM;
+ goto reply;
+ }
+
+ memset(token, 0, token_len);
+ token->disks = (struct sync_disk *)&token->r.disks[0]; /* shorthand */
+ token->r.num_disks = res.num_disks;
+ memcpy(token->r.lockspace_name, res.lockspace_name, SANLK_NAME_LEN);
+ memcpy(token->r.name, res.name, SANLK_NAME_LEN);
+
+ token->acquire_lver = res.lver;
+ token->acquire_data64 = res.data64;
+ token->acquire_data32 = res.data32;
+ token->acquire_flags = res.flags;
+
+ /*
+ * receive sanlk_disk's / sync_disk's
+ *
+ * WARNING: as a shortcut, this requires that sync_disk and
+ * sanlk_disk match; this is the reason for the pad fields
+ * in sanlk_disk (TODO: let these differ?)
+ */
+
+ rv = recv(fd, token->disks, disks_len, MSG_WAITALL);
+ if (rv != disks_len) {
+ free(token);
+ result = -ENOTCONN;
+ goto reply;
+ }
+
+ /* zero out pad1 and pad2, see WARNING above */
+ for (j = 0; j < token->r.num_disks; j++) {
+ token->disks[j].sector_size = 0;
+ token->disks[j].fd = -1;
+ }
+
+ log_debug("cmd_request %d,%d force_mode %u %.48s:%.48s:%.256s:%llu",
+ ca->ci_in, fd, force_mode,
+ token->r.lockspace_name,
+ token->r.name,
+ token->disks[0].path,
+ (unsigned long long)token->r.disks[0].offset);
+
+ result = request_token(task, token, force_mode, &owner_id);
+
+ if (result < 0)
+ goto reply;
+
+#if 0
+ host_bitmap_set(token, owner_id);
+#endif
+
+ reply:
+ free(token);
+ log_debug("cmd_request %d,%d done %d", ca->ci_in, fd, result);
+
+ memcpy(&h, &ca->header, sizeof(struct sm_header));
+ h.length = sizeof(h);
+ h.data = result;
+ h.data2 = 0;
+ send(fd, &h, sizeof(h), MSG_NOSIGNAL);
+
+ client_resume(ca->ci_in);
+}
+
static void cmd_add_lockspace(struct cmd_args *ca)
{
struct sm_header h;
@@ -1422,6 +1521,9 @@ static void call_cmd(struct task *task, struct cmd_args *ca)
case SM_CMD_INQUIRE:
cmd_inquire(task, ca);
break;
+ case SM_CMD_REQUEST:
+ cmd_request(task, ca);
+ break;
case SM_CMD_ADD_LOCKSPACE:
strcpy(client[ca->ci_in].owner_name, "add_lockspace");
cmd_add_lockspace(ca);
@@ -1770,7 +1872,10 @@ static void cmd_restrict(int ci, int fd, struct sm_header *h_recv)
send(fd, &h, sizeof(h), MSG_NOSIGNAL);
}
-static void process_cmd_thread_lockspace(int ci_in, struct sm_header *h_recv)
+/* cmd comes from a transient client/fd set up just to pass the cmd,
+ and is not being done on behalf of another registered client/fd */
+
+static void process_cmd_thread_unregistered(int ci_in, struct sm_header *h_recv)
{
struct cmd_args *ca;
struct sm_header h;
@@ -1784,12 +1889,7 @@ static void process_cmd_thread_lockspace(int ci_in, struct
sm_header *h_recv)
ca->ci_in = ci_in;
memcpy(&ca->header, h_recv, sizeof(struct sm_header));
- if (h_recv->cmd == SM_CMD_ADD_LOCKSPACE)
- strcpy(client[ci_in].owner_name, "add_lockspace");
- else if (h_recv->cmd == SM_CMD_REM_LOCKSPACE)
- strcpy(client[ci_in].owner_name, "rem_lockspace");
- else
- strcpy(client[ci_in].owner_name, "cmd_lockspace");
+ snprintf(client[ci_in].owner_name, SANLK_NAME_LEN, "cmd%d", h_recv->cmd);
rv = thread_pool_add_work(ca);
if (rv < 0)
@@ -1807,7 +1907,10 @@ static void process_cmd_thread_lockspace(int ci_in, struct
sm_header *h_recv)
close(client[ci_in].fd);
}
-static void process_cmd_thread_resource(int ci_in, struct sm_header *h_recv)
+/* cmd either comes from a registered client/fd,
+ or is targeting a registered client/fd */
+
+static void process_cmd_thread_registered(int ci_in, struct sm_header *h_recv)
{
struct cmd_args *ca;
struct sm_header h;
@@ -2024,10 +2127,11 @@ static void process_connection(int ci)
break;
case SM_CMD_ADD_LOCKSPACE:
case SM_CMD_REM_LOCKSPACE:
+ case SM_CMD_REQUEST:
rv = client_suspend(ci);
if (rv < 0)
return;
- process_cmd_thread_lockspace(ci, &h);
+ process_cmd_thread_unregistered(ci, &h);
break;
case SM_CMD_ACQUIRE:
case SM_CMD_RELEASE:
@@ -2037,7 +2141,7 @@ static void process_connection(int ci)
rv = client_suspend(ci);
if (rv < 0)
return;
- process_cmd_thread_resource(ci, &h);
+ process_cmd_thread_registered(ci, &h);
break;
default:
log_error("ci %d cmd %d unknown", ci, h.cmd);
@@ -2491,6 +2595,7 @@ static void print_usage(void)
printf("sanlock client acquire -r RESOURCE -p <pid>\n");
printf("sanlock client release -r RESOURCE -p <pid>\n");
printf("sanlock client inquire -p <pid>\n");
+ printf("sanlock client request -r RESOURCE\n");
printf("\n");
printf("sanlock direct <action> [-a 0|1] [-o 0|1]\n");
printf("sanlock direct init -s LOCKSPACE\n");
@@ -2594,6 +2699,8 @@ static int read_command_line(int argc, char *argv[])
com.action = ACT_RELEASE;
else if (!strcmp(act, "inquire"))
com.action = ACT_INQUIRE;
+ else if (!strcmp(act, "request"))
+ com.action = ACT_REQUEST;
else {
log_tool("client action \"%s\" is unknown", act);
exit(EXIT_FAILURE);
@@ -2715,6 +2822,9 @@ static int read_command_line(int argc, char *argv[])
case 'g':
com.local_host_generation = atoll(optionarg);
break;
+ case 'f':
+ com.force_mode = strtoul(optionarg, NULL, 0);
+ break;
case 's':
parse_arg_lockspace(optionarg); /* com.lockspace */
break;
@@ -2902,6 +3012,12 @@ static int do_client(void)
log_tool("\"%s\"", res_state);
break;
+ case ACT_REQUEST:
+ log_tool("request");
+ rv = sanlock_request(0, com.force_mode, com.res_args[0]);
+ log_tool("request done %d", rv);
+ break;
+
default:
log_tool("action not implemented");
rv = -1;
diff --git a/src/paxos_lease.c b/src/paxos_lease.c
index 2a65c60..1d9d7a3 100644
--- a/src/paxos_lease.c
+++ b/src/paxos_lease.c
@@ -34,7 +34,7 @@ int get_rand(int a, int b);
struct request_record {
uint64_t lver;
- uint8_t force_mode;
+ uint32_t force_mode;
};
#define DBLOCK_CHECKSUM_LEN 48 /* ends before checksum field */
@@ -190,7 +190,6 @@ static int read_leader(struct task *task,
return rv;
}
-
#if 0
static int read_request(struct task *task,
struct sync_disk *disk,
diff --git a/src/sanlock_internal.h b/src/sanlock_internal.h
index 0356807..7395805 100644
--- a/src/sanlock_internal.h
+++ b/src/sanlock_internal.h
@@ -138,17 +138,6 @@ struct space {
struct host_info host_info[DEFAULT_MAX_HOSTS];
};
-struct sm_header {
- uint32_t magic;
- uint32_t version;
- uint32_t cmd;
- uint32_t cmd_flags;
- uint32_t length;
- uint32_t seq;
- uint32_t data;
- uint32_t data2;
-};
-
/*
* Example of watchdog behavior when host_id renewals fail, assuming
* that sanlock cannot successfully kill the pids it is supervising that
@@ -502,6 +491,7 @@ struct command_line {
int num_hosts; /* -n */
int max_hosts; /* -m */
int res_count;
+ uint32_t force_mode;
char our_host_name[SANLK_NAME_LEN+1];
char *dump_path;
struct sanlk_lockspace lockspace; /* -s LOCKSPACE */
@@ -526,6 +516,7 @@ enum {
ACT_ACQUIRE,
ACT_RELEASE,
ACT_INQUIRE,
+ ACT_REQUEST,
ACT_ACQUIRE_ID,
ACT_RELEASE_ID,
ACT_RENEW_ID,
diff --git a/src/sanlock_resource.h b/src/sanlock_resource.h
index 11f9ace..dd1f878 100644
--- a/src/sanlock_resource.h
+++ b/src/sanlock_resource.h
@@ -37,6 +37,8 @@ int sanlock_release(int sock, int pid, uint32_t flags, int res_count,
int sanlock_inquire(int sock, int pid, uint32_t flags, int *res_count,
char **res_state);
+int sanlock_request(uint32_t flags, uint32_t force_mode,
+ struct sanlk_resource *res);
/*
* Functions to convert between string and struct resource formats.
diff --git a/src/sanlock_sock.h b/src/sanlock_sock.h
index 154665a..1afa4df 100644
--- a/src/sanlock_sock.h
+++ b/src/sanlock_sock.h
@@ -22,6 +22,18 @@ enum {
SM_CMD_RELEASE = 8,
SM_CMD_INQUIRE = 9,
SM_CMD_RESTRICT = 10,
+ SM_CMD_REQUEST = 11,
+};
+
+struct sm_header {
+ uint32_t magic;
+ uint32_t version;
+ uint32_t cmd; /* SM_CMD_ */
+ uint32_t cmd_flags;
+ uint32_t length;
+ uint32_t seq;
+ uint32_t data;
+ uint32_t data2;
};
#define SANLK_STATE_MAXSTR 4096
diff --git a/src/token_manager.c b/src/token_manager.c
index df5d632..977e74f 100644
--- a/src/token_manager.c
+++ b/src/token_manager.c
@@ -185,6 +185,51 @@ int release_token(struct task *task, struct token *token)
return rv; /* SANLK_OK */
}
+int request_token(struct task *task, struct token *token, uint32_t force_mode,
+ uint64_t *owner_id)
+{
+#if 0
+ struct leader_record leader;
+ struct request_record req;
+ int rv;
+
+ rv = open_disks(token->disks, token->r.num_disks);
+ if (!majority_disks(token, rv)) {
+ log_errot(token, "request open_disk error %s", token->disks[0].path);
+ return -ENODEV;
+ }
+
+ rv = paxos_lease_leader_read(task, token, &leader, "request");
+ if (rv < 0)
+ goto out;
+
+ if (leader.timestamp == LEASE_FREE) {
+ }
+
+ if (leader.lver >= token->acquire_lver) {
+ }
+
+ *owner_id = leader.owner_id;
+
+ rv = paxos_lease_request_read(task, token, &req);
+ if (rv < 0)
+ goto out;
+
+ if (req.lver >= token->acquire_lver) {
+ goto out;
+ }
+
+ req.lver = token->acquire_lver;
+ req.force_mode = force_mode;
+
+ rv = paxos_lease_request_write(task, token, &req);
+ out:
+ close_disks(token->disks, token->r.num_disks);
+ return rv;
+#endif
+ return -1;
+}
+
/* thread that releases tokens of pid's that die */
static void *async_release_thread(void *arg GNUC_UNUSED)
diff --git a/src/token_manager.h b/src/token_manager.h
index e860336..7825642 100644
--- a/src/token_manager.h
+++ b/src/token_manager.h
@@ -16,6 +16,9 @@ int release_token(struct task *task, struct token *token);
void release_token_async(struct token *token);
+int request_token(struct task *task, struct token *token, uint32_t force_mode,
+ uint64_t *owner_id);
+
int add_resource(struct token *token, int pid);
void del_resource(struct token *token);