36 #include <linux/limits.h> 37 #include <sys/sendfile.h> 38 #include <sys/utsname.h> 60 #define DEFAULT_IN_FILE_NAME "/sys/kernel/debug/motr/trace/buffer" 61 #define DEFAULT_OUT_FILE_NAME "/var/log/motr/m0trace.bin" 62 #define MOTR_KO_CORE_IN_FILE_NAME "/sys/kernel/debug/motr/core" 63 #define MOTR_KO_CORE_OUT_FILE_NAME "/var/log/motr/m0tr_ko.img" 108 #define log_err(fmt, ...) plog(LOG_ERR, fmt, ## __VA_ARGS__) 109 #define log_warn(fmt, ...) plog(LOG_WARNING, fmt, ## __VA_ARGS__) 110 #define log_info(fmt, ...) plog(LOG_INFO, fmt, ## __VA_ARGS__) 111 #define log_debug(fmt, ...) plog(LOG_DEBUG, fmt, ## __VA_ARGS__) 116 static char buf[8 * 1024];
128 buf[
sizeof buf - 1] =
'\0';
137 log_debug(
"%s: signum %d\n", __func__, signum);
148 n = read(ifd,
buf,
sizeof buf);
149 if (
n !=
sizeof buf) {
150 log_err(
"failed to read trace header from '%s' file (got %zd" 151 " bytes instead of %zu bytes)\n",
159 log_err(
"invalid trace header MAGIC value\n");
178 int *ofd,
const char *ofname)
187 if (
n !=
header->tbh_header_size) {
188 log_err(
"failed to write trace header to output file '%s': %s\n",
189 ofname, strerror(errno));
197 log_err(
"fsync(2) failed on output file '%s': %s",
198 ofname, strerror(errno));
216 log_err(
"failed to write trace data to output file" 226 log_err(
"fsync(2) failed on output file '%s': %s",
241 log_err(
"invalid trace buffer pointer (out of range)\n");
252 struct stat log_stat;
258 if (time_of_last_check == 0)
267 rc = fstat(*fd_ptr, &log_stat);
270 log_err(
"failed to get stat info for '%s' file: %s\n",
276 log_debug(
"log size is %.2fMB, log rotation is needed\n",
277 (
float)log_stat.st_size / 1024 / 1024);
302 log_err(
"failed to rename log file '%s' => '%s': %s\n",
309 S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
311 log_err(
"failed to open output file '%s': %s\n",
316 log_debug(
"new output log fd %d\n", ofd);
323 if (
rctx->log_fd > 0)
328 log_debug(
"original log has been rotated\n");
334 const char *last_log;
338 log_debug(
"log rotation thread started\n");
362 if (access(last_log, F_OK) == 0) {
363 rc = unlink(last_log);
365 log_err(
"failed to remove oldest log file '%s':" 366 " %s\n", last_log, strerror(errno));
376 log_err(
"failed to rename log file" 377 " '%s' => '%s': %s\n",
387 log_debug(
"log rotation thread stopped\n");
397 const char *logbuf_end = logbuf + logheader->
tbh_buf_size;
429 if (curpos == oldpos) {
431 if (timeo > idle_timeo)
436 log_warn(
"trace data processing interrupted by" 437 " a signal, exiting\n");
444 if (curpos > oldpos) {
472 log_err(
"invalid valude for -k option, it should be <= %u\n",
492 static char buf[4 * 1024 * 1024];
497 log_err(
"failed to open input file '%s': %s\n",
504 S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
506 log_err(
"failed to open output file '%s': %s\n",
511 while ((
nr = read(ifd,
buf,
sizeof buf)) > 0) {
512 nw = write(ofd,
buf,
nr);
514 log_err(
"failed to write data to '%s' file: %s\n",
522 log_err(
"failed to read data from '%s' file: %s\n",
532 log_debug(
"m0tr.ko core image saved into '%s'\n",
537 int main(
int argc,
char *argv[])
548 int32_t monitor_cycles = 0;
550 struct sigaction old_sa;
551 struct sigaction sa = {
553 .sa_flags = SA_SIGINFO,
567 log_err(
"failed to initialize libmotr\n");
575 "input file name, if none is provided, then " 577 LAMBDA(
void, (
const char *str) {
582 "output file name, if none is provided, then " 584 LAMBDA(
void, (
const char *str) {
589 "output file name for m0tr.ko core image, if none is provided" 591 " it has effect only if -K option is also specified",
592 LAMBDA(
void, (
const char *str) {
597 "daemon mode - run in the background, implies -L (log errors" 602 "save m0tr.ko core image into a file, specified by -O option" 603 " (this option has no effect as it's 'on' by default, it has" 604 " been kept for backward compatibility, it's superseded by" 609 "discards action of '-K' option, i.e. don't save m0tr.ko" 610 " core image into a file",
616 LAMBDA(
void, (int64_t lvl) {
621 "log information into syslog instead of STDERR (by default" 626 "output trace file size in MB, when it's reached, log rotation" 627 " is performed; if set to 0 then rotation is disabled, default" 634 "number of logs to keep in log rotation, default is 6",
635 LAMBDA(
void, (int64_t k) {
640 "monitor trace buffer file creation each second during" 641 " specified period of time (in seconds)",
642 LAMBDA(
void, (int64_t k) {
647 "pipe mode - run in foreground, output to STDOUT and disable" 658 M0_FLAGARG(
'f',
"do fsync after writing each chunk of trace data",
668 openlog(
progname, LOG_NOWAIT | LOG_CONS, LOG_DAEMON);
676 err(EX_OSERR,
"failed to switch to daemon mode");
679 rc = sigaction(SIGTERM, &sa, &old_sa);
680 rc |= sigaction(SIGQUIT, &sa,
NULL);
681 rc |= sigaction(SIGINT, &sa,
NULL);
683 log_err(
"failed to set SIGTERM/SIGQUIT/SIGINT handler\n");
699 while (monitor_cycles-- > 0) {
709 log_err(
"failed to open input file '%s': %s\n",
720 S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
722 log_err(
"failed to open output file '%s': %s\n",
730 if (logheader ==
NULL)
735 if (logheader == MAP_FAILED) {
736 log_err(
"failed to mmap trace buffer header from '%s': %s\n",
743 if (logbuf == MAP_FAILED) {
744 log_err(
"failed to mmap trace buffer from '%s': %s\n",
753 rotator_data.
log_fd = ofd;
762 log_err(
"failed to start log rotation thread\n");
static bool rotation_enabled
#define M0_GETOPTS(progname, argc, argv,...)
static uint32_t max_log_size
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
#define M0_FLAGARG(ch, desc, ptr)
M0_INTERNAL int struct dentry struct kstat * stat
#define MOTR_KO_CORE_IN_FILE_NAME
static int process_trace_buffer(int *ofd_ptr, const struct m0_trace_buf_header *logheader, const char *logbuf)
int m0_thread_join(struct m0_thread *q)
#define MOTR_KO_CORE_OUT_FILE_NAME
#define log_debug(fmt,...)
enum m0_trace_level level
static const char * output_file_name
static struct m0_mutex write_data_mutex
#define DEFAULT_IN_FILE_NAME
static void wake_up_rotator_thread(enum lr_action a)
enum m0_md_lustre_logrec_type __attribute__
#define M0_THREAD_INIT(thread, TYPE, init, func, arg, namefmt,...)
int m0_init(struct m0 *instance)
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
void sig_term_quit_int_handler(int signum, siginfo_t *siginfo, void *uctx)
M0_INTERNAL void m0_cond_init(struct m0_cond *cond, struct m0_mutex *mutex)
#define M0_VOIDARG(ch, desc, func)
static uint32_t keep_logs
#define M0_NUMBERARG(ch, desc, func)
struct m0_reqh_context rctx
#define M0_STRINGARG(ch, desc, func)
static int init_log_names(void)
static enum lr_action rotator_action
M0_INTERNAL void m0_cond_fini(struct m0_cond *cond)
static const char * output_kore_file_name
m0_time_t m0_time_now(void)
void m0_node_uuid_string_set(const char *uuid)
static void log_rotator_thread(struct rotator_ctx *rctx)
static volatile bool stop_processing
void m0_thread_fini(struct m0_thread *q)
M0_INTERNAL void m0_cond_signal(struct m0_cond *cond)
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
static const char * progname
static const struct m0_trace_buf_header * read_trace_buf_header(int ifd)
static struct m0_cond rotator_cond
#define DEFAULT_OUT_FILE_NAME
uint64_t m0_time_seconds(const m0_time_t time)
#define log_info(fmt,...)
static void plog(int level, const char *format,...) __attribute__((format(printf
static int64_t m0_atomic64_get(const struct m0_atomic64 *a)
M0_INTERNAL void m0_cond_wait(struct m0_cond *cond)
static int write_trace_header(const struct m0_trace_buf_header *header, int *ofd, const char *ofname)
#define log_warn(fmt,...)
const struct m0_trace_buf_header * log_header
m0_time_t m0_time_sub(const m0_time_t t1, const m0_time_t t2)
static char log_names[MAX_LOG_NAMES][PATH_MAX]
static bool is_log_rotation_needed(int *fd_ptr)
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
static uint32_t log_rotation_dealy
static struct m0 instance
static int rotate_original_log(struct rotator_ctx *rctx)
static struct m0_mutex rotator_mutex
struct m0t1fs_filedata * fd
static bool fsync_enabled
static const char * get_cur_pos(const struct m0_trace_buf_header *logheader, const char *logbuf)
M0_INTERNAL void m0_trace_set_mmapped_buffer(bool val)
int main(int argc, char *argv[])
static const char * input_file_name
static int write_trace_data(int *fd_ptr, const void *buf, size_t size)
int m0_nanosleep(const m0_time_t req, m0_time_t *rem)