1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-10-27 18:55:19 +03:00

debug: add new envvar

Add support for 2 new envvars for internal lvm2 test suite
(though it could be possible usable for other cases)

LVM_LOG_FILE_EPOCH

Whether to add 'epoch' extension that consist from
the envvar 'string' + pid + starttime in kernel units
obtained from /proc/self/stat.

LVM_LOG_FILE_UNLINK_STATUS

Whether to unlink the log depending on return status value,
so if the command is successful the log is automatically
deleted.

API is still for now experimental to catch various issue.
This commit is contained in:
Zdenek Kabelac 2015-04-20 10:04:18 +02:00
parent de4791c052
commit 5723a7cd7e
3 changed files with 69 additions and 2 deletions

View File

@ -18,10 +18,12 @@
#include "memlock.h"
#include "defaults.h"
#include <stdio.h>
#include <stdarg.h>
#include <syslog.h>
static FILE *_log_file;
static char _log_file_path[PATH_MAX];
static struct device _log_dev;
static struct dm_str_list _log_dev_alias;
@ -52,11 +54,48 @@ void init_log_fn(lvm2_log_fn_t log_fn)
_lvm2_log_fn = NULL;
}
/*
* Support envvar LVM_LOG_FILE_EPOCH and allow to attach
* extra keyword to openned log file. After this word pid
* and starttime (in kernel units, read from /proc/self/stat
* is automatically attached.
* If command/daemon forks multiple times, it could create multiple
* log files ensure, there are no overwrites.
*/
void init_log_file(const char *log_file, int append)
{
const char *open_mode = append ? "a" : "w";
static const char statfile[] = "/proc/self/stat";
const char *env;
int pid;
long long starttime;
FILE *st;
if (!(_log_file = fopen(log_file, open_mode))) {
_log_file_path[0] = '\0';
if ((env = getenv("LVM_LOG_FILE_EPOCH"))) {
if (!(st = fopen(statfile, "r")))
log_sys_error("fopen", statfile);
else if (fscanf(st, "%d %*s %*c %*d %*d %*d %*d " /* tty_nr */
"%*d %*u %*u %*u %*u " /* mjflt */
"%*u %*u %*u %*d %*d " /* cstim */
"%*d %*d %*d %*d " /* itrealvalue */
"%llu", &pid, &starttime) != 2) {
log_warn("WARNING: Cannot parse content of %s.", statfile);
} else {
if (fclose(st))
log_sys_debug("fclose", statfile);
if (dm_snprintf(_log_file_path, sizeof(_log_file_path),
"%s_%s_%d_%lld", log_file, env, pid, starttime) < 0) {
log_warn("WARNING: Debug log file path is too long for epoch.");
_log_file_path[0] = '\0';
} else {
log_file = _log_file_path;
append = 1; /* force */
}
}
}
if (!(_log_file = fopen(log_file, append ? "a" : "w"))) {
log_sys_error("fopen", log_file);
return;
}
@ -64,6 +103,31 @@ void init_log_file(const char *log_file, int append)
_log_to_file = 1;
}
/*
* Unlink the log file depeding on command's return value
*
* When envvar LVM_LOG_FILE_UNLINK_STATUS is set, compare
* resulting status with this string.
*
* It's possible to specify 2 variants - having it equal to
* a single number or having it different from a single number.
*
* i.e. LVM_LOG_FILE_UNLINK_STATUS="!1" # delete when ret != 1.
*/
void unlink_log_file(int ret)
{
const char *env;
if (_log_file_path[0] &&
(env = getenv("LVM_LOG_FILE_UNLINK_STATUS")) &&
((env[0] == '!' && atoi(env + 1) != ret) ||
(atoi(env) == ret))) {
if (unlink(_log_file_path))
log_sys_error("unlink", _log_file_path);
_log_file_path[0] = '\0';
}
}
void init_log_direct(const char *log_file, int append)
{
int open_flags = append ? 0 : O_TRUNC;

View File

@ -40,6 +40,7 @@ void init_indent(int indent);
void init_msg_prefix(const char *prefix);
void init_log_file(const char *log_file, int append);
void unlink_log_file(int ret);
void init_log_direct(const char *log_file, int append);
void init_log_while_suspended(int log_while_suspended);
void init_abort_on_internal_errors(int fatal);

View File

@ -1561,6 +1561,8 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
int lvm_return_code(int ret)
{
unlink_log_file(ret);
return (ret == ECMD_PROCESSED ? 0 : ret);
}