mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-01 01:15:19 +00:00
* src/virsh.c: added a logging option to a file based on
Nobuhiro Itou patch * src/xen_internal.c: small TODO comment from Atsushi SAKAI Daniel
This commit is contained in:
parent
ec3835d330
commit
7eed474dd3
@ -1,3 +1,9 @@
|
||||
Wed Jun 6 14:22:36 CEST 2007 Daniel Veillard <veillard@redhat.com>
|
||||
|
||||
* src/virsh.c: added a logging option to a file based on
|
||||
Nobuhiro Itou patch
|
||||
* src/xen_internal.c: small TODO comment from Atsushi SAKAI
|
||||
|
||||
Wed Jun 6 09:20:23 CEST 2007 Daniel Veillard <veillard@redhat.com>
|
||||
|
||||
* po/*: merge all po from Red Hat/Fedora translations, and
|
||||
|
176
src/virsh.c
176
src/virsh.c
@ -30,6 +30,8 @@
|
||||
#include <fcntl.h>
|
||||
#include <locale.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
@ -57,6 +59,33 @@ static char *progname;
|
||||
((((int) ((T)->tv_sec - (U)->tv_sec)) * 1000000.0 + \
|
||||
((int) ((T)->tv_usec - (U)->tv_usec))) / 1000.0)
|
||||
|
||||
/**
|
||||
* The log configuration
|
||||
*/
|
||||
#define MSG_BUFFER 4096
|
||||
#define SIGN_NAME "virsh"
|
||||
#define DIR_MODE (S_IWUSR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) /* 0755 */
|
||||
#define FILE_MODE (S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH) /* 0644 */
|
||||
#define LOCK_MODE (S_IWUSR | S_IRUSR) /* 0600 */
|
||||
#define LVL_DEBUG "DEBUG"
|
||||
#define LVL_INFO "INFO"
|
||||
#define LVL_NOTICE "NOTICE"
|
||||
#define LVL_WARNING "WARNING"
|
||||
#define LVL_ERROR "ERROR"
|
||||
|
||||
/**
|
||||
* vshErrorLevel:
|
||||
*
|
||||
* Indicates the level of an log message
|
||||
*/
|
||||
typedef enum {
|
||||
VSH_ERR_DEBUG = 0,
|
||||
VSH_ERR_INFO,
|
||||
VSH_ERR_NOTICE,
|
||||
VSH_ERR_WARNING,
|
||||
VSH_ERR_ERROR
|
||||
} vshErrorLevel;
|
||||
|
||||
/*
|
||||
* The error handler for virtsh
|
||||
*/
|
||||
@ -176,6 +205,8 @@ typedef struct __vshControl {
|
||||
int readonly; /* connect readonly (first time only, not
|
||||
* during explicit connect command)
|
||||
*/
|
||||
char *logfile; /* log file name */
|
||||
int log_fd; /* log file descriptor */
|
||||
} __vshControl;
|
||||
|
||||
|
||||
@ -186,6 +217,9 @@ static void vshError(vshControl * ctl, int doexit, const char *format, ...)
|
||||
static int vshInit(vshControl * ctl);
|
||||
static int vshDeinit(vshControl * ctl);
|
||||
static void vshUsage(vshControl * ctl, const char *cmdname);
|
||||
static void vshOpenLogFile(vshControl *ctl);
|
||||
static void vshOutputLogFile(vshControl *ctl, int log_level, const char *format, va_list ap);
|
||||
static void vshCloseLogFile(vshControl *ctl);
|
||||
|
||||
static int vshParseArgv(vshControl * ctl, int argc, char **argv);
|
||||
|
||||
@ -3365,6 +3399,10 @@ vshDebug(vshControl * ctl, int level, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
vshOutputLogFile(ctl, VSH_ERR_DEBUG, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (level > ctl->debug)
|
||||
return;
|
||||
|
||||
@ -3392,6 +3430,10 @@ vshError(vshControl * ctl, int doexit, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
vshOutputLogFile(ctl, VSH_ERR_ERROR, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (doexit)
|
||||
fprintf(stderr, _("%s: error: "), progname);
|
||||
else
|
||||
@ -3459,6 +3501,8 @@ vshInit(vshControl * ctl)
|
||||
|
||||
ctl->uid = getuid();
|
||||
|
||||
vshOpenLogFile(ctl);
|
||||
|
||||
/* set up the library error handler */
|
||||
virSetErrorFunc(NULL, virshErrorHandler);
|
||||
|
||||
@ -3478,6 +3522,128 @@ vshInit(vshControl * ctl)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* vshOpenLogFile:
|
||||
*
|
||||
* Open log file.
|
||||
*/
|
||||
static void
|
||||
vshOpenLogFile(vshControl *ctl)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (ctl->logfile == NULL)
|
||||
return;
|
||||
|
||||
/* check log file */
|
||||
if (stat(ctl->logfile, &st) == -1) {
|
||||
switch (errno) {
|
||||
case ENOENT:
|
||||
break;
|
||||
default:
|
||||
vshError(ctl, TRUE, _("failed to get the log file information"));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!S_ISREG(st.st_mode)) {
|
||||
vshError(ctl, TRUE, _("the log path is not a file"));
|
||||
}
|
||||
}
|
||||
|
||||
/* log file open */
|
||||
if ((ctl->log_fd = open(ctl->logfile, O_WRONLY | O_APPEND | O_CREAT | O_SYNC, FILE_MODE)) < 0) {
|
||||
vshError(ctl, TRUE, _("failed to open the log file. check the log file path"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* vshOutputLogFile:
|
||||
*
|
||||
* Outputting an error to log file.
|
||||
*/
|
||||
static void
|
||||
vshOutputLogFile(vshControl *ctl, int log_level, const char *msg_format, va_list ap)
|
||||
{
|
||||
char msg_buf[MSG_BUFFER];
|
||||
const char *lvl = "";
|
||||
struct timeval stTimeval;
|
||||
struct tm *stTm;
|
||||
|
||||
if (ctl->log_fd == -1)
|
||||
return;
|
||||
|
||||
/**
|
||||
* create log format
|
||||
*
|
||||
* [YYYY.MM.DD HH:MM:SS SIGNATURE PID] LOG_LEVEL message
|
||||
*/
|
||||
gettimeofday(&stTimeval, NULL);
|
||||
stTm = localtime(&stTimeval.tv_sec);
|
||||
snprintf(msg_buf, sizeof(msg_buf),
|
||||
"[%d.%02d.%02d %02d:%02d:%02d ",
|
||||
(1900 + stTm->tm_year),
|
||||
(1 + stTm->tm_mon),
|
||||
(stTm->tm_mday),
|
||||
(stTm->tm_hour),
|
||||
(stTm->tm_min),
|
||||
(stTm->tm_sec));
|
||||
snprintf(msg_buf + strlen(msg_buf), sizeof(msg_buf) - strlen(msg_buf),
|
||||
"%s] ", SIGN_NAME);
|
||||
switch (log_level) {
|
||||
case VSH_ERR_DEBUG:
|
||||
lvl = LVL_DEBUG;
|
||||
break;
|
||||
case VSH_ERR_INFO:
|
||||
lvl = LVL_INFO;
|
||||
break;
|
||||
case VSH_ERR_NOTICE:
|
||||
lvl = LVL_INFO;
|
||||
break;
|
||||
case VSH_ERR_WARNING:
|
||||
lvl = LVL_WARNING;
|
||||
break;
|
||||
case VSH_ERR_ERROR:
|
||||
lvl = LVL_ERROR;
|
||||
break;
|
||||
default:
|
||||
lvl = LVL_DEBUG;
|
||||
break;
|
||||
}
|
||||
snprintf(msg_buf + strlen(msg_buf), sizeof(msg_buf) - strlen(msg_buf),
|
||||
"%s ", lvl);
|
||||
vsnprintf(msg_buf + strlen(msg_buf), sizeof(msg_buf) - strlen(msg_buf),
|
||||
msg_format, ap);
|
||||
|
||||
if (msg_buf[strlen(msg_buf) - 1] != '\n')
|
||||
snprintf(msg_buf + strlen(msg_buf), sizeof(msg_buf) - strlen(msg_buf), "\n");
|
||||
|
||||
/* write log */
|
||||
if (write(ctl->log_fd, msg_buf, strlen(msg_buf)) == -1) {
|
||||
vshCloseLogFile(ctl);
|
||||
vshError(ctl, FALSE, _("failed to write the log file"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* vshCloseLogFile:
|
||||
*
|
||||
* Close log file.
|
||||
*/
|
||||
static void
|
||||
vshCloseLogFile(vshControl *ctl)
|
||||
{
|
||||
/* log file close */
|
||||
if (ctl->log_fd >= 0) {
|
||||
close(ctl->log_fd);
|
||||
ctl->log_fd = -1;
|
||||
}
|
||||
|
||||
if (ctl->logfile) {
|
||||
free(ctl->logfile);
|
||||
ctl->logfile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------
|
||||
* Readline stuff
|
||||
* -----------------
|
||||
@ -3601,6 +3767,8 @@ vshReadlineInit(void)
|
||||
static int
|
||||
vshDeinit(vshControl * ctl)
|
||||
{
|
||||
vshCloseLogFile(ctl);
|
||||
|
||||
if (ctl->conn) {
|
||||
if (virConnectClose(ctl->conn) != 0) {
|
||||
ctl->conn = NULL; /* prevent recursive call from vshError() */
|
||||
@ -3629,6 +3797,7 @@ vshUsage(vshControl * ctl, const char *cmdname)
|
||||
" -h | --help this help\n"
|
||||
" -q | --quiet quiet mode\n"
|
||||
" -t | --timing print timing information\n"
|
||||
" -l | --log <file> output logging to file\n"
|
||||
" -v | --version program version\n\n"
|
||||
" commands (non interactive mode):\n"), progname);
|
||||
|
||||
@ -3663,6 +3832,7 @@ vshParseArgv(vshControl * ctl, int argc, char **argv)
|
||||
{"version", 0, 0, 'v'},
|
||||
{"connect", 1, 0, 'c'},
|
||||
{"readonly", 0, 0, 'r'},
|
||||
{"log", 1, 0, 'l'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@ -3705,7 +3875,7 @@ vshParseArgv(vshControl * ctl, int argc, char **argv)
|
||||
end = end ? : argc;
|
||||
|
||||
/* standard (non-command) options */
|
||||
while ((arg = getopt_long(end, argv, "d:hqtc:vr", opt, &idx)) != -1) {
|
||||
while ((arg = getopt_long(end, argv, "d:hqtc:vrl:", opt, &idx)) != -1) {
|
||||
switch (arg) {
|
||||
case 'd':
|
||||
ctl->debug = atoi(optarg);
|
||||
@ -3728,6 +3898,9 @@ vshParseArgv(vshControl * ctl, int argc, char **argv)
|
||||
case 'r':
|
||||
ctl->readonly = TRUE;
|
||||
break;
|
||||
case 'l':
|
||||
ctl->logfile = vshStrdup(ctl, optarg);
|
||||
break;
|
||||
default:
|
||||
vshError(ctl, TRUE,
|
||||
_("unsupported option '-%c'. See --help."), arg);
|
||||
@ -3794,6 +3967,7 @@ main(int argc, char **argv)
|
||||
|
||||
memset(ctl, 0, sizeof(vshControl));
|
||||
ctl->imode = TRUE; /* default is interactive mode */
|
||||
ctl->log_fd = -1; /* Initialize log file descriptor */
|
||||
|
||||
if ((defaultConn = getenv("VIRSH_DEFAULT_CONNECT_URI"))) {
|
||||
ctl->name = strdup(defaultConn);
|
||||
|
@ -1016,6 +1016,7 @@ xenHypervisorGetSchedulerType(virDomainPtr domain, int *nparams)
|
||||
/*
|
||||
* Support only dom_interface_version >=5
|
||||
* (Xen3.1.0 or later)
|
||||
* TODO: check on Xen 3.0.3
|
||||
*/
|
||||
if (dom_interface_version < 5) {
|
||||
virXenErrorFunc(VIR_ERR_NO_XEN, __FUNCTION__,
|
||||
|
Loading…
x
Reference in New Issue
Block a user