src/client_cmd.c | 38 ++++++++++++++++++++++++++------------
src/client_cmd.h | 2 +-
src/cmd.c | 17 +++++++++++++----
src/log.c | 42 ++++++++++++++++++++++++++++++------------
src/log.h | 2 +-
src/main.c | 2 +-
src/sanlock_internal.h | 2 +-
7 files changed, 73 insertions(+), 32 deletions(-)
New commits:
commit 0b2e562ff5f5a719cbb320868d8a7629dac4cc0e
Author: David Teigland <teigland(a)redhat.com>
Date: Fri Sep 16 13:08:10 2011 -0500
sanlock: fix log_dump
and make it more efficient
diff --git a/src/client_cmd.c b/src/client_cmd.c
index 119149f..2662122 100644
--- a/src/client_cmd.c
+++ b/src/client_cmd.c
@@ -470,15 +470,22 @@ int sanlock_host_status(int debug, char *lockspace_name)
return rv;
}
-int sanlock_log_dump(void)
+int sanlock_log_dump(int max_size)
{
struct sm_header h;
- char buf[4096];
+ char *buf;
int fd, rv;
+ buf = malloc(max_size);
+ if (!buf)
+ return -ENOMEM;
+ memset(buf, 0, max_size);
+
fd = send_command(SM_CMD_LOG_DUMP, 0);
- if (fd < 0)
+ if (fd < 0) {
+ free(buf);
return fd;
+ }
memset(&h, 0, sizeof(h));
@@ -492,20 +499,27 @@ int sanlock_log_dump(void)
goto out;
}
+ if (h.data <= 0 || h.data > max_size)
+ goto out;
- while (1) {
- memset(buf, 0, sizeof(buf));
-
- rv = recv(fd, buf, sizeof(buf) - 1, MSG_WAITALL);
-
- if (rv > 0)
- printf("%s", buf);
- else
- break;
+ rv = recv(fd, buf, h.data, MSG_WAITALL);
+ if (rv < 0) {
+ rv = -errno;
+ goto out;
}
+ if (!rv) {
+ rv = -1;
+ goto out;
+ }
+
+ printf("%s", buf);
printf("\n");
+
+ if (rv != h.data)
+ printf("partial dump %d of %d\n", rv, h.data);
out:
close(fd);
+ free(buf);
return rv;
}
diff --git a/src/client_cmd.h b/src/client_cmd.h
index dceb7ca..6759c93 100644
--- a/src/client_cmd.h
+++ b/src/client_cmd.h
@@ -11,7 +11,7 @@
int sanlock_status(int debug, char sort_arg);
int sanlock_host_status(int debug, char *lockspace_name);
-int sanlock_log_dump(void);
+int sanlock_log_dump(int max_size);
int sanlock_shutdown(void);
#endif
diff --git a/src/cmd.c b/src/cmd.c
index bbab319..97c4eba 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -1196,13 +1196,15 @@ static int print_state_daemon(char *str)
"io_timeout=%d "
"id_renewal=%d "
"id_renewal_fail=%d "
- "id_renewal_warn=%d",
+ "id_renewal_warn=%d "
+ "monotime=%llu",
our_host_name_global,
main_task.use_aio,
main_task.io_timeout_seconds,
main_task.id_renewal_seconds,
main_task.id_renewal_fail_seconds,
- main_task.id_renewal_warn_seconds);
+ main_task.id_renewal_warn_seconds,
+ (unsigned long long)monotime());
return strlen(str) + 1;
}
@@ -1537,11 +1539,18 @@ static void cmd_host_status(int fd, struct sm_header *h_recv)
free(status);
}
+static char send_log_dump[LOG_DUMP_SIZE];
+
static void cmd_log_dump(int fd, struct sm_header *h_recv)
{
- send(fd, h_recv, sizeof(struct sm_header), MSG_DONTWAIT);
+ int len;
+
+ copy_log_dump(send_log_dump, &len);
+
+ h_recv->data = len;
- write_log_dump(fd);
+ send(fd, h_recv, sizeof(struct sm_header), MSG_NOSIGNAL);
+ send(fd, send_log_dump, len, MSG_NOSIGNAL);
}
static void cmd_restrict(int ci, int fd, struct sm_header *h_recv)
diff --git a/src/log.c b/src/log.c
index 72b424f..7513152 100644
--- a/src/log.c
+++ b/src/log.c
@@ -33,7 +33,7 @@ static pthread_t thread_handle;
static pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t log_cond = PTHREAD_COND_INITIALIZER;
-static char log_dump[SM_LOG_DUMP_SIZE];
+static char log_dump[LOG_DUMP_SIZE];
static unsigned int log_point;
static unsigned int log_wrap;
@@ -42,9 +42,9 @@ struct entry {
char str[LOG_STR_LEN];
};
-#define SM_LOG_DEFAULT_ENTRIES 4096
+#define LOG_DEFAULT_ENTRIES 4096
static struct entry *log_ents;
-static unsigned int log_num_ents = SM_LOG_DEFAULT_ENTRIES;
+static unsigned int log_num_ents = LOG_DEFAULT_ENTRIES;
static unsigned int log_head_ent; /* add at head */
static unsigned int log_tail_ent; /* remove from tail */
static unsigned int log_dropped;
@@ -62,10 +62,21 @@ static void _log_save_dump(int level GNUC_UNUSED, int len)
{
int i;
+ if (len < LOG_DUMP_SIZE - log_point) {
+ memcpy(log_dump+log_point, log_str, len);
+ log_point += len;
+
+ if (log_point == LOG_DUMP_SIZE) {
+ log_point = 0;
+ log_wrap = 1;
+ }
+ return;
+ }
+
for (i = 0; i < len; i++) {
log_dump[log_point++] = log_str[i];
- if (log_point == SM_LOG_DUMP_SIZE) {
+ if (log_point == LOG_DUMP_SIZE) {
log_point = 0;
log_wrap = 1;
}
@@ -175,17 +186,24 @@ static void write_dropped(int level, int num)
write_entry(level, str);
}
-void write_log_dump(int fd)
+void copy_log_dump(char *buf, int *len)
{
- pthread_mutex_lock(&log_mutex);
-
- if (log_wrap)
- send(fd, log_dump + log_point, SM_LOG_DUMP_SIZE - log_point, MSG_DONTWAIT);
+ int tail_len;
- log_dump[log_point] = '\0';
-
- send(fd, log_dump, log_point, MSG_DONTWAIT);
+ pthread_mutex_lock(&log_mutex);
+ if (!log_wrap && !log_point) {
+ *len = 0;
+ } else if (log_wrap) {
+ tail_len = LOG_DUMP_SIZE - log_point;
+ memcpy(buf, log_dump+log_point, tail_len);
+ if (log_point)
+ memcpy(buf+tail_len, log_dump, log_point);
+ *len = LOG_DUMP_SIZE;
+ } else {
+ memcpy(buf, log_dump, log_point-1);
+ *len = log_point-1;
+ }
pthread_mutex_unlock(&log_mutex);
}
diff --git a/src/log.h b/src/log.h
index 8661eb0..63168eb 100644
--- a/src/log.h
+++ b/src/log.h
@@ -14,7 +14,7 @@ void log_level(uint32_t space_id, uint32_t token_id, char *name_in, int
level, c
int setup_logging(void);
void close_logging(void);
-void write_log_dump(int fd);
+void copy_log_dump(char *buf, int *len);
#define log_debug(fmt, args...) log_level(0, 0, NULL, LOG_DEBUG, fmt,
##args)
#define log_space(space, fmt, args...) log_level(space->space_id, 0, NULL,
LOG_DEBUG, fmt, ##args)
diff --git a/src/main.c b/src/main.c
index 3034f47..e5aa9c6 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1708,7 +1708,7 @@ static int do_client(void)
break;
case ACT_LOG_DUMP:
- rv = sanlock_log_dump();
+ rv = sanlock_log_dump(LOG_DUMP_SIZE);
break;
case ACT_SHUTDOWN:
diff --git a/src/sanlock_internal.h b/src/sanlock_internal.h
index 24ceb2f..46e2b36 100644
--- a/src/sanlock_internal.h
+++ b/src/sanlock_internal.h
@@ -35,7 +35,7 @@
#define DEFAULT_MAX_HOSTS 2000
-#define SM_LOG_DUMP_SIZE (1024*1024)
+#define LOG_DUMP_SIZE (1024*1024)
/* this is just the path to the executable, not full command line */