[prev in list] [next in list] [prev in thread] [next in thread] 

List:       sanlock-devel
Subject:    src/direct_lib.c src/diskio.c src/diskio.h src/host_id.c src/host_id.h src/main.c src/paxos_lease.c
From:       teigland () fedoraproject ! org (David Teigland)
Date:       2011-04-20 22:35:24
Message-ID: 20110420223524.3D6FA12026F () lists ! fedorahosted ! org
[Download RAW message or body]

 src/direct_lib.c       |   11 +---------
 src/diskio.c           |   20 +++++++++++++++++++
 src/diskio.h           |    1 
 src/host_id.c          |   41 ++++++++++++++++++---------------------
 src/host_id.h          |    2 -
 src/main.c             |   17 ++++++++++++++--
 src/paxos_lease.c      |   51 +++++++++++++++++++++++++++++++++++++++----------
 src/paxos_lease.h      |    5 +++-
 src/sanlock_internal.h |    2 +
 src/sanlock_rv.h       |    2 +
 src/token_manager.c    |    6 ++++-
 11 files changed, 112 insertions(+), 46 deletions(-)

New commits:
commit 4292a8dd2fefd8cb950e77f3b459524bd456e3fa
Author: David Teigland <teigland at redhat.com>
Date:   Wed Apr 20 17:31:11 2011 -0500

    sanlock: fix host_id reads from paxos_acquire
    
    the threads doing paxos_acquire were copying the host_id_disk,
    including fd's, and reading the host_id disk using those fd's,
    (in use by the host_id thread) instead of opening the host_id
    disk themselves to read from.  This probably explains why the
    host_id leader reads sometimes returned the wrong data.
    
    Also add -R and -Q options to enable renewal debugging and
    quiet acquire failure messages.

diff --git a/src/direct_lib.c b/src/direct_lib.c
index 09503cc..2c168ee 100644
--- a/src/direct_lib.c
+++ b/src/direct_lib.c
@@ -23,16 +23,9 @@ void log_level(int space_id GNUC_UNUSED, int token_id GNUC_UNUSED,
 {
 }
 
-int host_id_leader_read(struct timeout *ti GNUC_UNUSED,
-                        char *space_name GNUC_UNUSED,
-			uint64_t host_id GNUC_UNUSED,
-                        struct leader_record *leader_ret GNUC_UNUSED);
+int host_id_disk_info(char *name GNUC_UNUSED, struct sync_disk *disk GNUC_UNUSED);
 
-int host_id_leader_read(struct timeout *ti GNUC_UNUSED,
-                        char *space_name GNUC_UNUSED,
-			uint64_t host_id GNUC_UNUSED,
-                        struct leader_record *leader_ret GNUC_UNUSED)
+int host_id_disk_info(char *name GNUC_UNUSED, struct sync_disk *disk GNUC_UNUSED)
 {
 	return -1;
 }
-
diff --git a/src/diskio.c b/src/diskio.c
index 78a5fee..d55f40f 100644
--- a/src/diskio.c
+++ b/src/diskio.c
@@ -74,6 +74,26 @@ void close_disks(struct sync_disk *disks, int num_disks)
 		close(disks[d].fd);
 }
 
+int open_disks_fd(struct sync_disk *disks, int num_disks)
+{
+	struct sync_disk *disk;
+	int num_opens = 0;
+	int d, fd;
+
+	for (d = 0; d < num_disks; d++) {
+		disk = &disks[d];
+		fd = open(disk->path, O_RDWR | O_DIRECT | O_SYNC, 0);
+		if (fd < 0) {
+			log_error("open error %d %s", fd, disk->path);
+			continue;
+		}
+
+		disk->fd = fd;
+		num_opens++;
+	}
+	return num_opens;
+}
+
 /* return number of opened disks */
 
 int open_disks(struct sync_disk *disks, int num_disks)
diff --git a/src/diskio.h b/src/diskio.h
index 24d55a3..3ec3b27 100644
--- a/src/diskio.h
+++ b/src/diskio.h
@@ -11,6 +11,7 @@
 
 void close_disks(struct sync_disk *disks, int num_disks);
 int open_disks(struct sync_disk *disks, int num_disks);
+int open_disks_fd(struct sync_disk *disks, int num_disks);
 
 int write_sector(const struct sync_disk *disk, uint64_t sector_nr,
 		 const char *data, int data_len, int io_timeout_seconds,
diff --git a/src/host_id.c b/src/host_id.c
index 2ac381b..fcd9b8b 100644
--- a/src/host_id.c
+++ b/src/host_id.c
@@ -102,23 +102,20 @@ int get_space_info(char *space_name, struct space *sp_out)
 	return rv;
 }
 
-int host_id_leader_read(struct timeout *ti,
-			char *space_name, uint64_t host_id,
-			struct leader_record *leader_ret)
+int host_id_disk_info(char *name, struct sync_disk *disk)
 {
 	struct space space;
 	int rv;
 
-	rv = get_space_info(space_name, &space);
-	if (rv < 0)
-		return rv;
-
-	rv = delta_lease_leader_read(ti, &space.host_id_disk, space_name,
-				     host_id, leader_ret, "host_id");
-	if (rv < 0)
-		return rv;
+	pthread_mutex_lock(&spaces_mutex);
+	rv = _get_space_info(name, &space);
+	if (!rv) {
+		memcpy(disk, &space.host_id_disk, sizeof(struct sync_disk));
+		disk->fd = -1;
+	}
+	pthread_mutex_unlock(&spaces_mutex);
 
-	return 0;
+	return rv;
 }
 
 /*
@@ -146,10 +143,10 @@ int host_id_check(struct space *sp)
 			  gap, (unsigned long long)last_success);
 	}
 
-	/*
-	log_space(sp, "host_id_check good %d %llu",
-		  gap, (unsigned long long)last_success);
-	*/
+	if (com.debug_renew > 1) {
+		log_space(sp, "host_id_check good %d %llu",
+		  	  gap, (unsigned long long)last_success);
+	}
 
 	return 1;
 }
@@ -248,12 +245,12 @@ static void *host_id_thread(void *arg_in)
 			gap = last_success - sp->lease_status.renewal_last_success;
 			sp->lease_status.renewal_last_success = last_success;
 
-			/*
-			log_space(sp, "host_id %llu renewed %llu len %d interval %d",
-				  (unsigned long long)host_id,
-				  (unsigned long long)last_success,
-				  delta_length, gap);
-			*/
+			if (com.debug_renew) {
+				log_space(sp, "host_id %llu renewed %llu len %d interval %d",
+					  (unsigned long long)host_id,
+					  (unsigned long long)last_success,
+					  delta_length, gap);
+			}
 
 			if (!sp->thread_stop)
 				update_watchdog_file(sp, last_success);
diff --git a/src/host_id.h b/src/host_id.h
index ae230c8..f8e551d 100644
--- a/src/host_id.h
+++ b/src/host_id.h
@@ -12,7 +12,7 @@
 int print_space_state(struct space *sp, char *str);
 int _get_space_info(char *space_name, struct space *sp_out);
 int get_space_info(char *space_name, struct space *sp_out);
-int host_id_leader_read(struct timeout *ti, char *space_name, uint64_t host_id, \
struct leader_record *leader_ret); +int host_id_disk_info(char *name, struct \
sync_disk *disk);  int host_id_check(struct space *sp);
 int add_space(struct space *sp);
 int rem_space(char *name, struct sync_disk *disk, uint64_t host_id);
diff --git a/src/main.c b/src/main.c
index d5e3067..d30dd00 100644
--- a/src/main.c
+++ b/src/main.c
@@ -920,8 +920,13 @@ static void *cmd_acquire_thread(void *args_in)
 
 		rv = acquire_token(token, acquire_lver, new_num_hosts);
 		if (rv < 0) {
-			log_errot(token, "cmd_acquire %d,%d,%d paxos_lease %d",
-				  cl_ci, cl_fd, cl_pid, rv);
+			if (rv == SANLK_LIVE_LEADER && com.quiet_fail) {
+				log_token(token, "cmd_acquire %d,%d,%d paxos_lease %d",
+					  cl_ci, cl_fd, cl_pid, rv);
+			} else {
+				log_errot(token, "cmd_acquire %d,%d,%d paxos_lease %d",
+					  cl_ci, cl_fd, cl_pid, rv);
+			}
 			result = rv;
 			goto done;
 		}
@@ -2273,6 +2278,8 @@ static void print_usage(void)
 	printf("\n");
 	printf("daemon\n");
 	printf("  -D			debug: no fork and print all logging to stderr\n");
+	printf("  -R <num>		debug renewal: log debug info about renewals\n");
+	printf("  -Q <num>		quiet error messages for common lock contention\n");
 	printf("  -L <level>		write logging at level and up to logfile (-1 none)\n");
 	printf("  -S <level>		write logging at level and up to syslog (-1 none)\n");
 	printf("  -w <num>		use watchdog through wdmd (1 yes, 0 no, default %d)\n", \
DEFAULT_USE_WATCHDOG); @@ -2488,6 +2495,12 @@ static int read_command_line(int argc, \
char *argv[])  optionarg = argv[i];
 
 		switch (optchar) {
+		case 'Q':
+			com.quiet_fail = atoi(optionarg);
+			break;
+		case 'R':
+			com.debug_renew = atoi(optionarg);
+			break;
 		case 'L':
 			log_logfile_priority = atoi(optionarg);
 			break;
diff --git a/src/paxos_lease.c b/src/paxos_lease.c
index a11e020..d882706 100644
--- a/src/paxos_lease.c
+++ b/src/paxos_lease.c
@@ -26,6 +26,7 @@
 #include "log.h"
 #include "crc32c.h"
 #include "host_id.h"
+#include "delta_lease.h"
 #include "paxos_lease.h"
 
 /*
@@ -658,7 +659,7 @@ static int write_new_leader(struct timeout *ti,
  */
 
 int paxos_lease_acquire(struct timeout *ti,
-			struct token *token, int force,
+			struct token *token, uint32_t flags,
 		        struct leader_record *leader_ret,
 		        uint64_t acquire_lver,
 		        int new_num_hosts)
@@ -666,19 +667,20 @@ int paxos_lease_acquire(struct timeout *ti,
 	struct leader_record prev_leader;
 	struct leader_record new_leader;
 	struct leader_record host_id_leader;
+	struct sync_disk host_id_disk;
 	struct paxos_dblock dblock;
 	time_t start;
 	uint64_t last_timestamp = 0;
-	int error;
+	int error, rv, disk_open = 0;
 
-	log_token(token, "paxos_acquire begin lver %llu force %d",
-		  (unsigned long long)acquire_lver, force);
+	log_token(token, "paxos_acquire begin lver %llu flags %x",
+		  (unsigned long long)acquire_lver, flags);
 
 	error = paxos_lease_leader_read(ti, token, &prev_leader, "paxos_acquire");
 	if (error < 0)
 		goto out;
 
-	if (force)
+	if (flags & PAXOS_ACQUIRE_FORCE)
 		goto run;
 
 	if (prev_leader.timestamp == LEASE_FREE) {
@@ -703,12 +705,31 @@ int paxos_lease_acquire(struct timeout *ti,
 	log_token(token, "paxos_acquire check owner_id %llu",
 		  (unsigned long long)prev_leader.owner_id);
 
+	memset(&host_id_disk, 0, sizeof(host_id_disk));
+
+	rv = host_id_disk_info(prev_leader.space_name, &host_id_disk);
+	if (rv < 0) {
+		log_errot(token, "paxos_acquire no lockspace info %.48s",
+			  prev_leader.space_name);
+		error = SANLK_BAD_SPACE_NAME;
+		goto out;
+	}
+
+	disk_open = open_disks_fd(&host_id_disk, 1);
+	if (disk_open != 1) {
+		log_errot(token, "paxos_acquire cannot open host_id_disk");
+		error = SANLK_BAD_SPACE_DISK;
+		goto out;
+	}
+
 	start = time(NULL);
 
 	while (1) {
-		error = host_id_leader_read(ti, prev_leader.space_name,
-					    prev_leader.owner_id,
-					    &host_id_leader);
+		error = delta_lease_leader_read(ti, &host_id_disk,
+						prev_leader.space_name,
+						prev_leader.owner_id,
+						&host_id_leader,
+						"paxos_acquire");
 		if (error < 0) {
 			log_errot(token, "paxos_acquire host_id %llu read %d",
 				  (unsigned long long)prev_leader.owner_id,
@@ -782,8 +803,13 @@ int paxos_lease_acquire(struct timeout *ti,
 		/* the owner is renewing its host_id so it's alive */
 
 		if (last_timestamp && (host_id_leader.timestamp != last_timestamp)) {
-			log_errot(token, "paxos_acquire host_id %llu alive",
-				  (unsigned long long)prev_leader.owner_id);
+			if (flags & PAXOS_ACQUIRE_QUIET_FAIL) {
+				log_token(token, "paxos_acquire host_id %llu alive",
+					  (unsigned long long)prev_leader.owner_id);
+			} else {
+				log_errot(token, "paxos_acquire host_id %llu alive",
+					  (unsigned long long)prev_leader.owner_id);
+			}
 			error = SANLK_LIVE_LEADER;
 			goto out;
 		}
@@ -857,8 +883,13 @@ int paxos_lease_acquire(struct timeout *ti,
 		goto out;
 
 	memcpy(leader_ret, &new_leader, sizeof(struct leader_record));
+
  out:
 	log_token(token, "paxos_acquire done %d", error);
+
+	if (disk_open)
+		close_disks(&host_id_disk, 1);
+
 	return error;
 }
 
diff --git a/src/paxos_lease.h b/src/paxos_lease.h
index b384561..89eca2b 100644
--- a/src/paxos_lease.h
+++ b/src/paxos_lease.h
@@ -9,12 +9,15 @@
 #ifndef __PAXOS_LEASE_H__
 #define __PAXOS_LEASE_H__
 
+#define PAXOS_ACQUIRE_FORCE		0x00000001
+#define PAXOS_ACQUIRE_QUIET_FAIL	0x00000002
+
 uint32_t leader_checksum(struct leader_record *lr);
 int majority_disks(struct token *token, int num);
 int paxos_lease_leader_read(struct timeout *ti,
 			    struct token *token, struct leader_record *leader_ret,
 			    const char *caller);
-int paxos_lease_acquire(struct timeout *ti, struct token *token, int force,
+int paxos_lease_acquire(struct timeout *ti, struct token *token, uint32_t flags,
 		        struct leader_record *leader_ret,
 		        uint64_t acquire_lver,
 		        int new_num_hosts);
diff --git a/src/sanlock_internal.h b/src/sanlock_internal.h
index f2bbbe3..f8c4e2f 100644
--- a/src/sanlock_internal.h
+++ b/src/sanlock_internal.h
@@ -268,6 +268,8 @@ struct command_line {
 	int type;				/* COM_ */
 	int action;				/* ACT_ */
 	int debug;
+	int debug_renew;
+	int quiet_fail;
 	int use_watchdog;
 	int high_priority;
 	int uid;				/* -U */
diff --git a/src/sanlock_rv.h b/src/sanlock_rv.h
index 53c6c4f..614e08c 100644
--- a/src/sanlock_rv.h
+++ b/src/sanlock_rv.h
@@ -40,5 +40,7 @@
 #define SANLK_REACQUIRE_LVER	-227
 #define SANLK_BAD_LOCKSPACE	-228
 #define SANLK_OTHER_OWNER	-229
+#define SANLK_BAD_SPACE_NAME	-230
+#define SANLK_BAD_SPACE_DISK	-231
 
 #endif
diff --git a/src/token_manager.c b/src/token_manager.c
index 3b19a5d..1d215ff 100644
--- a/src/token_manager.c
+++ b/src/token_manager.c
@@ -123,8 +123,12 @@ int acquire_token(struct token *token, uint64_t acquire_lver,
 {
 	struct leader_record leader_ret;
 	int rv;
+	uint32_t flags = 0;
 
-	rv = paxos_lease_acquire(&to, token, 0, &leader_ret, acquire_lver,
+	if (com.quiet_fail)
+		flags |= PAXOS_ACQUIRE_QUIET_FAIL;
+
+	rv = paxos_lease_acquire(&to, token, flags, &leader_ret, acquire_lver,
 				 new_num_hosts);
 
 	token->acquire_result = rv;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic