src/direct.c | 127 ++++++++++++++++++++++++++++++++++++++++---------
src/main.c | 43 +++++++++++++++-
src/sanlock_direct.h | 18 +++++-
src/sanlock_internal.h | 2
4 files changed, 160 insertions(+), 30 deletions(-)
New commits:
commit f74858fbe8aa50240f0267d5c503fdf7a7eab31c
Author: David Teigland <teigland(a)redhat.com>
Date: Tue Apr 12 16:39:57 2011 -0500
sanlock: read_id and live_id commands
sanlock direct read_id -- read and print the state of a host_id
sanlock direct live_id -- monitor and print the liveness of a host_id
diff --git a/src/direct.c b/src/direct.c
index 6bd10e7..c7aeeed 100644
--- a/src/direct.c
+++ b/src/direct.c
@@ -131,27 +131,28 @@ int sanlock_direct_release(void)
return do_paxos_action();
}
-static int do_delta_action(void)
+static int do_delta_action(int action, struct sanlk_lockspace *ls,
+ struct leader_record *leader_ret)
{
struct leader_record leader;
struct sync_disk sd;
struct space space;
int rv;
- if (!com.lockspace.name[0])
+ if (!ls->name[0])
return -1;
- if (!com.lockspace.host_id_disk.path[0])
+ if (!ls->host_id_disk.path[0])
return -1;
- if (!com.lockspace.host_id)
+ if (!ls->host_id)
return -1;
/* for log_space in delta functions */
memset(&space, 0, sizeof(space));
memset(&sd, 0, sizeof(struct sync_disk));
- memcpy(&sd, &com.lockspace.host_id_disk, sizeof(struct sanlk_disk));
+ memcpy(&sd, &ls->host_id_disk, sizeof(struct sanlk_disk));
rv = open_disks(&sd, 1);
if (rv != 1) {
@@ -159,35 +160,47 @@ static int do_delta_action(void)
return -1;
}
- switch (com.action) {
+ switch (action) {
case ACT_ACQUIRE_ID:
rv = delta_lease_acquire(&space, &sd,
- com.lockspace.name,
- com.lockspace.host_id,
- com.lockspace.host_id,
+ ls->name,
+ ls->host_id,
+ ls->host_id,
&leader);
break;
case ACT_RENEW_ID:
rv = delta_lease_renew(&space, &sd,
- com.lockspace.name,
- com.lockspace.host_id,
- com.lockspace.host_id,
+ ls->name,
+ ls->host_id,
+ ls->host_id,
&leader);
break;
case ACT_RELEASE_ID:
rv = delta_lease_leader_read(&sd,
- com.lockspace.name,
- com.lockspace.host_id,
+ ls->name,
+ ls->host_id,
&leader);
if (rv < 0)
return rv;
rv = delta_lease_release(&space, &sd,
- com.lockspace.name,
- com.lockspace.host_id,
+ ls->name,
+ ls->host_id,
&leader, &leader);
break;
+ case ACT_READ_ID:
+ rv = delta_lease_leader_read(&sd,
+ ls->name,
+ ls->host_id,
+ &leader);
+ break;
}
+ if (rv == DP_OK)
+ rv = 0;
+
+ if (leader_ret)
+ memcpy(leader_ret, &leader, sizeof(struct leader_record));
+
return rv;
}
@@ -198,19 +211,89 @@ static int do_delta_action(void)
* sanlock client add_lockspace|rem_lockspace -s LOCKSPACE
*/
-int sanlock_direct_acquire_id(void)
+int sanlock_direct_acquire_id(struct sanlk_lockspace *ls)
+{
+ return do_delta_action(ACT_ACQUIRE_ID, ls, NULL);
+}
+
+int sanlock_direct_release_id(struct sanlk_lockspace *ls)
+{
+ return do_delta_action(ACT_RELEASE_ID, ls, NULL);
+}
+
+int sanlock_direct_renew_id(struct sanlk_lockspace *ls)
{
- return do_delta_action();
+ return do_delta_action(ACT_RENEW_ID, ls, NULL);
}
-int sanlock_direct_release_id(void)
+int sanlock_direct_read_id(struct sanlk_lockspace *ls,
+ uint64_t *timestamp,
+ uint64_t *owner_id,
+ uint64_t *owner_generation)
{
- return do_delta_action();
+ struct leader_record leader;
+ int rv;
+
+ memset(&leader, 0, sizeof(struct leader_record));
+
+ rv = do_delta_action(ACT_READ_ID, ls, &leader);
+
+ *timestamp = leader.timestamp;
+ *owner_id = leader.owner_id;
+ *owner_generation = leader.owner_generation;
+
+ return rv;
}
-int sanlock_direct_renew_id(void)
+int sanlock_direct_live_id(struct sanlk_lockspace *ls,
+ uint64_t *timestamp,
+ uint64_t *owner_id,
+ uint64_t *owner_generation,
+ int *live)
{
- return do_delta_action();
+ struct leader_record leader_begin;
+ struct leader_record leader;
+ time_t start;
+ int rv;
+
+ rv = do_delta_action(ACT_READ_ID, ls, &leader_begin);
+ if (rv < 0)
+ return rv;
+
+ start = time(NULL);
+
+ while (1) {
+ sleep(1);
+
+ rv = do_delta_action(ACT_READ_ID, ls, &leader);
+ if (rv < 0)
+ return rv;
+
+ if (leader.timestamp != leader_begin.timestamp) {
+ *live = 1;
+ break;
+ }
+
+ if (leader.owner_id != leader_begin.owner_id) {
+ *live = 2;
+ break;
+ }
+
+ if (leader.owner_generation != leader_begin.owner_generation) {
+ *live = 3;
+ break;
+ }
+
+ if (time(NULL) - start > to.host_id_timeout_seconds) {
+ *live = 0;
+ break;
+ }
+ }
+
+ *timestamp = leader.timestamp;
+ *owner_id = leader.owner_id;
+ *owner_generation = leader.owner_generation;
+ return 0;
}
/*
diff --git a/src/main.c b/src/main.c
index 3063dc6..f40fbef 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2211,6 +2211,8 @@ static void print_usage(void)
printf(" acquire_id acquire a host_id lease\n");
printf(" release_id release a host_id lease\n");
printf(" renew_id renew a host_id lease\n");
+ printf(" read_id read a host_id lease, print the state\n");
+ printf(" live_id monitor a host_id lease for liveness\n");
printf("\n");
printf("daemon\n");
printf(" -D debug: no fork and print all logging to stderr\n");
@@ -2274,7 +2276,7 @@ static void print_usage(void)
printf(" -i <num> host_id of local host\n");
printf(" -g <num> host_id generation of local host\n");
printf("\n");
- printf("direct acquire_id|renew_id|release_id -s LOCKSPACE\n");
+ printf("direct acquire_id|renew_id|release_id|read_id|live_id -s
LOCKSPACE\n");
printf(" -a <num> use async io (1 yes, 0 no)\n");
printf("\n");
@@ -2384,6 +2386,10 @@ static int read_command_line(int argc, char *argv[])
com.action = ACT_RELEASE_ID;
else if (!strcmp(act, "renew_id"))
com.action = ACT_RENEW_ID;
+ else if (!strcmp(act, "read_id"))
+ com.action = ACT_READ_ID;
+ else if (!strcmp(act, "live_id"))
+ com.action = ACT_LIVE_ID;
else {
log_tool("direct action \"%s\" is unknown", act);
exit(EXIT_FAILURE);
@@ -2651,6 +2657,8 @@ static int do_client(void)
static int do_direct(void)
{
+ uint64_t timestamp, owner_id, owner_generation;
+ int live;
int rv;
switch (com.action) {
@@ -2671,15 +2679,42 @@ static int do_direct(void)
break;
case ACT_ACQUIRE_ID:
- rv = sanlock_direct_acquire_id();
+ rv = sanlock_direct_acquire_id(&com.lockspace);
break;
case ACT_RELEASE_ID:
- rv = sanlock_direct_release_id();
+ rv = sanlock_direct_release_id(&com.lockspace);
break;
case ACT_RENEW_ID:
- rv = sanlock_direct_renew_id();
+ rv = sanlock_direct_renew_id(&com.lockspace);
+ break;
+
+ case ACT_READ_ID:
+ rv = sanlock_direct_read_id(&com.lockspace,
+ ×tamp,
+ &owner_id,
+ &owner_generation);
+
+ log_tool("result %d timestamp %llu owner_id %llu owner_generation %llu",
+ rv,
+ (unsigned long long)timestamp,
+ (unsigned long long)owner_id,
+ (unsigned long long)owner_generation);
+ break;
+
+ case ACT_LIVE_ID:
+ rv = sanlock_direct_live_id(&com.lockspace,
+ ×tamp,
+ &owner_id,
+ &owner_generation,
+ &live);
+
+ log_tool("result %d live %d timestamp %llu owner_id %llu owner_generation
%llu",
+ rv, live,
+ (unsigned long long)timestamp,
+ (unsigned long long)owner_id,
+ (unsigned long long)owner_generation);
break;
default:
diff --git a/src/sanlock_direct.h b/src/sanlock_direct.h
index d14c19c..e997216 100644
--- a/src/sanlock_direct.h
+++ b/src/sanlock_direct.h
@@ -13,9 +13,19 @@ int sanlock_direct_init(void);
int sanlock_direct_dump(void);
int sanlock_direct_acquire(void);
int sanlock_direct_release(void);
-int sanlock_direct_migrate(void);
-int sanlock_direct_acquire_id(void);
-int sanlock_direct_release_id(void);
-int sanlock_direct_renew_id(void);
+int sanlock_direct_acquire_id(struct sanlk_lockspace *ls);
+int sanlock_direct_release_id(struct sanlk_lockspace *ls);
+int sanlock_direct_renew_id(struct sanlk_lockspace *ls);
+
+int sanlock_direct_read_id(struct sanlk_lockspace *ls,
+ uint64_t *timestamp,
+ uint64_t *owner_id,
+ uint64_t *owner_generation);
+
+int sanlock_direct_live_id(struct sanlk_lockspace *ls,
+ uint64_t *timestamp,
+ uint64_t *owner_id,
+ uint64_t *owner_generation,
+ int *live);
#endif
diff --git a/src/sanlock_internal.h b/src/sanlock_internal.h
index 0fa14e5..88cabe1 100644
--- a/src/sanlock_internal.h
+++ b/src/sanlock_internal.h
@@ -308,6 +308,8 @@ enum {
ACT_ACQUIRE_ID,
ACT_RELEASE_ID,
ACT_RENEW_ID,
+ ACT_READ_ID,
+ ACT_LIVE_ID,
ACT_INIT,
ACT_DUMP,
};