diff -r 183ad35bc411 include/libvirt/virterror.h --- a/include/libvirt/virterror.h Thu Jun 21 21:21:04 2007 -0400 +++ b/include/libvirt/virterror.h Thu Jun 21 21:21:05 2007 -0400 @@ -158,6 +158,30 @@ void virConnSetErrorFunc (virConnectPt virErrorFunc handler); int virConnCopyLastError (virConnectPtr conn, virErrorPtr to); +/** + * virLogLevel: + * + * Indicates the level of a log message + */ +typedef enum { + VIR_LOG_CRITICAL = 1, + VIR_LOG_ERROR, + VIR_LOG_WARN, + VIR_LOG_INFO, + VIR_LOG_DEBUG, +} virLogLevel; + + /** + * virLogFunc: + * @userData: user provided data for the log callback + * @level: virLogLevel constant for logging importance + * @msg: the message to be logged + */ + typedef void (*virLogFunc) (void *userData, int level, const char *msg); + + void virSetLogFunc(void *userData, + virLogFunc handler); + #ifdef __cplusplus } #endif diff -r 183ad35bc411 qemud/conf.c --- a/qemud/conf.c Thu Jun 21 21:21:04 2007 -0400 +++ b/qemud/conf.c Thu Jun 21 21:21:05 2007 -0400 @@ -372,14 +372,14 @@ static int qemudExtractVersionInfo(const if (errno == EINTR) { goto rewait; } - qemudLog(QEMUD_ERR, "Unexpected exit status from qemu %d pid %lu", got, (unsigned long)child); + __virLogMessage(VIR_LOG_ERROR, "Unexpected exit status from qemu %d pid %lu", got, (unsigned long)child); ret = -1; } /* Check & log unexpected exit status, but don't fail, * as there's really no need to throw an error if we did * actually read a valid version number above */ if (WEXITSTATUS(got) != 1) { - qemudLog(QEMUD_WARN, "Unexpected exit status '%d', qemu probably failed", got); + __virLogMessage(VIR_LOG_WARN, "Unexpected exit status '%d', qemu probably failed", got); } return ret; @@ -2189,13 +2189,13 @@ qemudReadFile(const char *path, int ret = 0; if (!(fh = fopen(path, "r"))) { - qemudLog(QEMUD_WARN, "Failed to open file '%s': %s", + __virLogMessage(VIR_LOG_WARN, "Failed to open file '%s': %s", path, strerror(errno)); goto error; } if (fstat(fileno(fh), &st) < 0) { - qemudLog(QEMUD_WARN, "Failed to stat file '%s': %s", + __virLogMessage(VIR_LOG_WARN, "Failed to stat file '%s': %s", path, strerror(errno)); goto error; } @@ -2206,12 +2206,12 @@ qemudReadFile(const char *path, } if (st.st_size >= maxlen) { - qemudLog(QEMUD_WARN, "File '%s' is too large", path); + __virLogMessage(VIR_LOG_WARN, "File '%s' is too large", path); goto error; } if ((ret = fread(buf, st.st_size, 1, fh)) != 1) { - qemudLog(QEMUD_WARN, "Failed to read config file '%s': %s", + __virLogMessage(VIR_LOG_WARN, "Failed to read config file '%s': %s", path, strerror(errno)); goto error; } @@ -2274,19 +2274,19 @@ checkLinkPointsTo(const char *checkLink, break; case EINVAL: - qemudLog(QEMUD_WARN, "Autostart file '%s' is not a symlink", + __virLogMessage(VIR_LOG_WARN, "Autostart file '%s' is not a symlink", checkLink); break; default: - qemudLog(QEMUD_WARN, "Failed to read autostart symlink '%s': %s", + __virLogMessage(VIR_LOG_WARN, "Failed to read autostart symlink '%s': %s", checkLink, strerror(errno)); break; } goto failed; } else if (n >= PATH_MAX) { - qemudLog(QEMUD_WARN, "Symlink '%s' contents too long to fit in buffer", + __virLogMessage(VIR_LOG_WARN, "Symlink '%s' contents too long to fit in buffer", checkLink); goto failed; } @@ -2303,7 +2303,7 @@ checkLinkPointsTo(const char *checkLink, dir[PATH_MAX] = '\0'; if (!(p = strrchr(dir, '/'))) { - qemudLog(QEMUD_WARN, "Symlink path '%s' is not absolute", checkLink); + __virLogMessage(VIR_LOG_WARN, "Symlink path '%s' is not absolute", checkLink); goto failed; } @@ -2313,7 +2313,7 @@ checkLinkPointsTo(const char *checkLink, *p = '\0'; if (qemudMakeConfigPath(dir, dest, NULL, tmp, PATH_MAX) < 0) { - qemudLog(QEMUD_WARN, "Path '%s/%s' is too long", dir, dest); + __virLogMessage(VIR_LOG_WARN, "Path '%s/%s' is too long", dir, dest); goto failed; } @@ -2323,14 +2323,14 @@ checkLinkPointsTo(const char *checkLink, /* canonicalize both paths */ if (!realpath(dest, real)) { - qemudLog(QEMUD_WARN, "Failed to expand path '%s' :%s", + __virLogMessage(VIR_LOG_WARN, "Failed to expand path '%s' :%s", dest, strerror(errno)); strncpy(real, dest, PATH_MAX); real[PATH_MAX] = '\0'; } if (!realpath(checkDest, checkReal)) { - qemudLog(QEMUD_WARN, "Failed to expand path '%s' :%s", + __virLogMessage(VIR_LOG_WARN, "Failed to expand path '%s' :%s", checkDest, strerror(errno)); strncpy(checkReal, checkDest, PATH_MAX); checkReal[PATH_MAX] = '\0'; @@ -2338,7 +2338,7 @@ checkLinkPointsTo(const char *checkLink, /* compare */ if (strcmp(checkReal, real) != 0) { - qemudLog(QEMUD_WARN, "Autostart link '%s' is not a symlink to '%s', ignoring", + __virLogMessage(VIR_LOG_WARN, "Autostart link '%s' is not a symlink to '%s', ignoring", checkLink, checkReal); goto failed; } @@ -2360,20 +2360,20 @@ qemudLoadConfig(struct qemud_driver *dri if (!(def = qemudParseVMDef(driver, xml, file))) { virErrorPtr err = virGetLastError(); - qemudLog(QEMUD_WARN, "Error parsing QEMU guest config '%s' : %s", + __virLogMessage(VIR_LOG_WARN, "Error parsing QEMU guest config '%s' : %s", path, err->message); return NULL; } if (!compareFileToNameSuffix(file, def->name, ".xml")) { - qemudLog(QEMUD_WARN, "QEMU guest config filename '%s' does not match guest name '%s'", + __virLogMessage(VIR_LOG_WARN, "QEMU guest config filename '%s' does not match guest name '%s'", path, def->name); qemudFreeVMDef(def); return NULL; } if (!(vm = qemudAssignVMDef(driver, def))) { - qemudLog(QEMUD_WARN, "Failed to load QEMU guest config '%s': out of memory", path); + __virLogMessage(VIR_LOG_WARN, "Failed to load QEMU guest config '%s': out of memory", path); qemudFreeVMDef(def); return NULL; } @@ -2400,20 +2400,20 @@ qemudLoadNetworkConfig(struct qemud_driv if (!(def = qemudParseNetworkDef(driver, xml, file))) { virErrorPtr err = virGetLastError(); - qemudLog(QEMUD_WARN, "Error parsing network config '%s' : %s", + __virLogMessage(VIR_LOG_WARN, "Error parsing network config '%s' : %s", path, err->message); return NULL; } if (!compareFileToNameSuffix(file, def->name, ".xml")) { - qemudLog(QEMUD_WARN, "Network config filename '%s' does not match network name '%s'", + __virLogMessage(VIR_LOG_WARN, "Network config filename '%s' does not match network name '%s'", path, def->name); qemudFreeNetworkDef(def); return NULL; } if (!(network = qemudAssignNetworkDef(driver, def))) { - qemudLog(QEMUD_WARN, "Failed to load network config '%s': out of memory", path); + __virLogMessage(VIR_LOG_WARN, "Failed to load network config '%s': out of memory", path); qemudFreeNetworkDef(def); return NULL; } @@ -2440,7 +2440,7 @@ int qemudScanConfigDir(struct qemud_driv if (!(dir = opendir(configDir))) { if (errno == ENOENT) return 0; - qemudLog(QEMUD_ERR, "Failed to open dir '%s': %s", + __virLogMessage(VIR_LOG_ERROR, "Failed to open dir '%s': %s", configDir, strerror(errno)); return -1; } @@ -2457,13 +2457,13 @@ int qemudScanConfigDir(struct qemud_driv continue; if (qemudMakeConfigPath(configDir, entry->d_name, NULL, path, PATH_MAX) < 0) { - qemudLog(QEMUD_WARN, "Config filename '%s/%s' is too long", + __virLogMessage(VIR_LOG_WARN, "Config filename '%s/%s' is too long", configDir, entry->d_name); continue; } if (qemudMakeConfigPath(autostartDir, entry->d_name, NULL, autostartLink, PATH_MAX) < 0) { - qemudLog(QEMUD_WARN, "Autostart link path '%s/%s' is too long", + __virLogMessage(VIR_LOG_WARN, "Autostart link path '%s/%s' is too long", autostartDir, entry->d_name); continue; } diff -r 183ad35bc411 qemud/driver.c --- a/qemud/driver.c Thu Jun 21 21:21:04 2007 -0400 +++ b/qemud/driver.c Thu Jun 21 21:21:05 2007 -0400 @@ -62,7 +62,7 @@ static int qemudSetCloseExec(int fd) { goto error; return 0; error: - qemudLog(QEMUD_ERR, "Failed to set close-on-exec file descriptor flag"); + __virLogMessage(VIR_LOG_ERROR, "Failed to set close-on-exec file descriptor flag"); return -1; } @@ -76,7 +76,7 @@ static int qemudSetNonBlock(int fd) { goto error; return 0; error: - qemudLog(QEMUD_ERR, "Failed to set non-blocking file descriptor flag"); + __virLogMessage(VIR_LOG_ERROR, "Failed to set non-blocking file descriptor flag"); return -1; } @@ -114,8 +114,8 @@ void qemudAutostartConfigs(struct qemud_ !qemudIsActiveNetwork(network) && qemudStartNetworkDaemon(driver, network) < 0) { virErrorPtr err = virGetLastError(); - qemudLog(QEMUD_ERR, "Failed to autostart network '%s': %s", - network->def->name, err->message); + __virLogMessage(VIR_LOG_ERROR, "Failed to autostart network '%s': %s", + network->def->name, err ? err->message : ""); } network = next; @@ -129,8 +129,8 @@ void qemudAutostartConfigs(struct qemud_ !qemudIsActiveVM(vm) && qemudStartVMDaemon(driver, vm) < 0) { virErrorPtr err = virGetLastError(); - qemudLog(QEMUD_ERR, "Failed to autostart VM '%s': %s", - vm->def->name, err->message); + __virLogMessage(VIR_LOG_ERROR, "Failed to autostart VM '%s': %s", + vm->def->name, err ? err->message : ""); } vm = next; @@ -157,7 +157,7 @@ int qemudStartup(void) { goto out_of_memory; } else { if (!(pw = getpwuid(uid))) { - qemudLog(QEMUD_ERR, "Failed to find user record for uid '%d': %s", + __virLogMessage(VIR_LOG_ERROR, "Failed to find user record for uid '%d': %s", uid, strerror(errno)); goto out_of_memory; } @@ -166,7 +166,7 @@ int qemudStartup(void) { goto snprintf_error; if (asprintf (&base, "%s/.libvirt/qemu", pw->pw_dir) == -1) { - qemudLog (QEMUD_ERR, "out of memory in asprintf"); + __virLogMessage (VIR_LOG_ERROR, "out of memory in asprintf"); goto out_of_memory; } } @@ -194,11 +194,11 @@ int qemudStartup(void) { return 0; snprintf_error: - qemudLog(QEMUD_ERR, "Resulting path to long for buffer in qemudInitPaths()"); + __virLogMessage(VIR_LOG_ERROR, "Resulting path to long for buffer in qemudInitPaths()"); return -1; out_of_memory: - qemudLog (QEMUD_ERR, "qemudStartup: out of memory"); + __virLogMessage (VIR_LOG_ERROR, "qemudStartup: out of memory"); if (base) free (base); free(qemu_driver); qemu_driver = NULL; @@ -208,8 +208,8 @@ int qemudReload(void) { int qemudReload(void) { qemudScanConfigs(qemu_driver); - if (qemu_driver->iptables) { - qemudLog(QEMUD_INFO, "Reloading iptables rules"); + if (qemu_driver->iptables) { + __virLogMessage(VIR_LOG_INFO, "Reloading iptables rules"); iptablesReloadRules(qemu_driver->iptables); } @@ -561,7 +561,7 @@ static int qemudWaitForMonitor(struct qe /* Log, but ignore failures to write logfile for VM */ if (errno == EINTR) goto retry; - qemudLog(QEMUD_WARN, "Unable to log VM console data: %s", + __virLogMessage(VIR_LOG_WARN, "Unable to log VM console data: %s", strerror(errno)); } @@ -666,15 +666,15 @@ int qemudStartVMDaemon(struct qemud_driv tmp = argv; while (*tmp) { if (write(vm->logfile, *tmp, strlen(*tmp)) < 0) - qemudLog(QEMUD_WARN, "Unable to write argv to logfile %d: %s", + __virLogMessage(VIR_LOG_WARN, "Unable to write argv to logfile %d: %s", errno, strerror(errno)); if (write(vm->logfile, " ", 1) < 0) - qemudLog(QEMUD_WARN, "Unable to write argv to logfile %d: %s", + __virLogMessage(VIR_LOG_WARN, "Unable to write argv to logfile %d: %s", errno, strerror(errno)); tmp++; } if (write(vm->logfile, "\n", 1) < 0) - qemudLog(QEMUD_WARN, "Unable to write argv to logfile %d: %s", + __virLogMessage(VIR_LOG_WARN, "Unable to write argv to logfile %d: %s", errno, strerror(errno)); if (qemudExec(argv, &vm->pid, &vm->stdout, &vm->stderr) == 0) { @@ -747,7 +747,7 @@ static int qemudVMData(struct qemud_driv /* Log, but ignore failures to write logfile for VM */ if (errno == EINTR) goto retry; - qemudLog(QEMUD_WARN, "Unable to log VM console data: %s", + __virLogMessage(VIR_LOG_WARN, "Unable to log VM console data: %s", strerror(errno)); } } @@ -760,7 +760,7 @@ int qemudShutdownVMDaemon(struct qemud_d if (!qemudIsActiveVM(vm)) return 0; - qemudLog(QEMUD_INFO, "Shutting down VM '%s'", vm->def->name); + __virLogMessage(VIR_LOG_INFO, "Shutting down VM '%s'", vm->def->name); kill(vm->pid, SIGTERM); @@ -771,7 +771,7 @@ int qemudShutdownVMDaemon(struct qemud_d virEventRemoveHandle(vm->stderr); if (close(vm->logfile) < 0) - qemudLog(QEMUD_WARN, "Unable to close logfile %d: %s", errno, strerror(errno)); + __virLogMessage(VIR_LOG_WARN, "Unable to close logfile %d: %s", errno, strerror(errno)); close(vm->stdout); close(vm->stderr); if (vm->monitor != -1) @@ -784,7 +784,7 @@ int qemudShutdownVMDaemon(struct qemud_d if (waitpid(vm->pid, NULL, WNOHANG) != vm->pid) { kill(vm->pid, SIGKILL); if (waitpid(vm->pid, NULL, 0) != vm->pid) { - qemudLog(QEMUD_WARN, "Got unexpected pid, damn"); + __virLogMessage(VIR_LOG_WARN, "Got unexpected pid, damn"); } } @@ -1221,13 +1221,13 @@ int qemudStartNetworkDaemon(struct qemud err_delbr1: if (network->def->ipAddress[0] && (err = brSetInterfaceUp(driver->brctl, network->bridge, 0))) { - qemudLog(QEMUD_WARN, "Failed to bring down bridge '%s' : %s", + __virLogMessage(VIR_LOG_WARN, "Failed to bring down bridge '%s' : %s", network->bridge, strerror(err)); } err_delbr: if ((err = brDeleteBridge(driver->brctl, network->bridge))) { - qemudLog(QEMUD_WARN, "Failed to delete bridge '%s' : %s\n", + __virLogMessage(VIR_LOG_WARN, "Failed to delete bridge '%s' : %s\n", network->bridge, strerror(err)); } @@ -1239,7 +1239,7 @@ int qemudShutdownNetworkDaemon(struct qe struct qemud_network *network) { int err; - qemudLog(QEMUD_INFO, "Shutting down network '%s'", network->def->name); + __virLogMessage(VIR_LOG_INFO, "Shutting down network '%s'", network->def->name); if (!qemudIsActiveNetwork(network)) return 0; @@ -1251,12 +1251,12 @@ int qemudShutdownNetworkDaemon(struct qe if (network->def->ipAddress[0] && (err = brSetInterfaceUp(driver->brctl, network->bridge, 0))) { - qemudLog(QEMUD_WARN, "Failed to bring down bridge '%s' : %s\n", + __virLogMessage(VIR_LOG_WARN, "Failed to bring down bridge '%s' : %s\n", network->bridge, strerror(err)); } if ((err = brDeleteBridge(driver->brctl, network->bridge))) { - qemudLog(QEMUD_WARN, "Failed to delete bridge '%s' : %s\n", + __virLogMessage(VIR_LOG_WARN, "Failed to delete bridge '%s' : %s\n", network->bridge, strerror(err)); } @@ -1264,7 +1264,7 @@ int qemudShutdownNetworkDaemon(struct qe waitpid(network->dnsmasqPid, NULL, WNOHANG) != network->dnsmasqPid) { kill(network->dnsmasqPid, SIGKILL); if (waitpid(network->dnsmasqPid, NULL, 0) != network->dnsmasqPid) - qemudLog(QEMUD_WARN, "Got unexpected pid for dnsmasq\n"); + __virLogMessage(VIR_LOG_WARN, "Got unexpected pid for dnsmasq\n"); } network->bridge[0] = '\0'; @@ -2084,7 +2084,7 @@ int qemudDomainUndefine(virDomainPtr dom return -1; if (unlink(vm->autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) - qemudLog(QEMUD_WARN, "Failed to delete autostart link '%s': %s", + __virLogMessage(VIR_LOG_WARN, "Failed to delete autostart link '%s': %s", vm->autostartLink, strerror(errno)); vm->configFile[0] = '\0'; @@ -2346,7 +2346,7 @@ int qemudNetworkUndefine(virNetworkPtr n return -1; if (unlink(network->autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) - qemudLog(QEMUD_WARN, "Failed to delete autostart link '%s': %s", + __virLogMessage(VIR_LOG_WARN, "Failed to delete autostart link '%s': %s", network->autostartLink, strerror(errno)); network->configFile[0] = '\0'; diff -r 183ad35bc411 qemud/iptables.c --- a/qemud/iptables.c Thu Jun 21 21:21:04 2007 -0400 +++ b/qemud/iptables.c Thu Jun 21 21:21:05 2007 -0400 @@ -36,6 +36,8 @@ #include #include +#include +#include "../src/internal.h" #include "internal.h" enum { @@ -578,7 +580,7 @@ iptRulesReload(iptRules *rules) rule->argv[rule->flipflop] = (char *) "--delete"; if ((retval = iptablesSpawn(WITH_ERRORS, rule->argv))) - qemudLog(QEMUD_WARN, "Failed to remove iptables rule '%s' from chain '%s' in table '%s': %s", + __virLogMessage(VIR_LOG_WARN, "Failed to remove iptables rule '%s' from chain '%s' in table '%s': %s", rule->rule, rules->chain, rules->table, strerror(errno)); rule->argv[rule->flipflop] = orig; @@ -586,12 +588,12 @@ iptRulesReload(iptRules *rules) if ((retval = iptablesAddRemoveChain(rules, REMOVE)) || (retval = iptablesAddRemoveChain(rules, ADD))) - qemudLog(QEMUD_WARN, "Failed to re-create chain '%s' in table '%s': %s", + __virLogMessage(VIR_LOG_WARN, "Failed to re-create chain '%s' in table '%s': %s", rules->chain, rules->table, strerror(retval)); for (i = 0; i < rules->nrules; i++) if ((retval = iptablesSpawn(WITH_ERRORS, rules->rules[i].argv))) - qemudLog(QEMUD_WARN, "Failed to add iptables rule '%s' to chain '%s' in table '%s': %s", + __virLogMessage(VIR_LOG_WARN, "Failed to add iptables rule '%s' to chain '%s' in table '%s': %s", rules->rules[i].rule, rules->chain, rules->table, strerror(retval)); } diff -r 183ad35bc411 qemud/qemud.c --- a/qemud/qemud.c Thu Jun 21 21:21:04 2007 -0400 +++ b/qemud/qemud.c Thu Jun 21 21:21:05 2007 -0400 @@ -262,6 +262,41 @@ static int qemudSetNonBlock(int fd) { return -1; } +static void qemudLogHandler(void *data ATTRIBUTE_UNUSED, + int level, const char *msg) +{ + if (godaemon) { + int sysprio = -1; + switch (level) { + case VIR_LOG_CRITICAL: + sysprio = LOG_CRIT; + break; + case VIR_LOG_ERROR: + sysprio = LOG_ERR; + break; + case VIR_LOG_WARN: + sysprio = LOG_WARNING; + break; + case VIR_LOG_INFO: + sysprio = LOG_INFO; + break; + case VIR_LOG_DEBUG: + sysprio = LOG_DEBUG; + break; + default: + break; + } + if (sysprio != -1) + syslog(sysprio, "%s", msg); + } else { + if ((level == VIR_LOG_DEBUG || + level == VIR_LOG_INFO) && + !verbose) + return; + fprintf(stderr, "%s\n", msg); + } +} + void qemudLog(int priority, const char *fmt, ...) { va_list args; @@ -708,6 +743,7 @@ static struct qemud_server *qemudInitial if (roSockname[0] != '\0' && qemudListenUnix(server, roSockname, 1) < 0) goto cleanup; + virSetLogFunc(NULL, qemudLogHandler); virStateInitialize(); if (!remote) /* qemud only */ { diff -r 183ad35bc411 qemud/uuid.c --- a/qemud/uuid.c Thu Jun 21 21:21:04 2007 -0400 +++ b/qemud/uuid.c Thu Jun 21 21:21:05 2007 -0400 @@ -32,7 +32,8 @@ #include #include -#include "internal.h" +#include +#include "../src/internal.h" static int virUUIDGenerateRandomBytes(unsigned char *buf, @@ -81,9 +82,9 @@ virUUIDGenerate(unsigned char *uuid) int err; if ((err = virUUIDGenerateRandomBytes(uuid, VIR_UUID_RAW_LEN))) - qemudLog(QEMUD_WARN, - "Falling back to pseudorandom UUID, " - "failed to generate random bytes: %s", strerror(err)); + __virLogMessage(VIR_LOG_WARN, + "Falling back to pseudorandom UUID, " + "failed to generate random bytes: %s", strerror(err)); return virUUIDGeneratePseudoRandomBytes(uuid, VIR_UUID_RAW_LEN); } diff -r 183ad35bc411 src/internal.h --- a/src/internal.h Thu Jun 21 21:21:04 2007 -0400 +++ b/src/internal.h Thu Jun 21 21:21:05 2007 -0400 @@ -189,6 +189,11 @@ void __virRaiseError(virConnectPtr conn, int int1, int int2, const char *msg, ...) ATTRIBUTE_FORMAT(printf, 12, 13); const char *__virErrorMsg(virErrorNumber error, const char *info); + +void __virLogMessage(int level, + const char *msg, + ...) + ATTRIBUTE_FORMAT(printf, 2, 3); /************************************************************************ * * diff -r 183ad35bc411 src/libvirt_sym.version --- a/src/libvirt_sym.version Thu Jun 21 21:21:04 2007 -0400 +++ b/src/libvirt_sym.version Thu Jun 21 21:21:05 2007 -0400 @@ -52,6 +52,7 @@ virConnCopyLastError; virConnResetLastError; virDefaultErrorFunc; + virSetLogFunc; virNodeGetInfo; virConnectGetCapabilities; diff -r 183ad35bc411 src/virterror.c --- a/src/virterror.c Thu Jun 21 21:21:04 2007 -0400 +++ b/src/virterror.c Thu Jun 21 21:21:05 2007 -0400 @@ -638,6 +638,34 @@ __virErrorMsg(virErrorNumber error, cons return (errmsg); } +static virLogFunc logHandler = NULL; +static void *logUserData = NULL; + +void virSetLogFunc(void *userData, + virLogFunc handler) { + logHandler = handler; + logUserData = userData; +} + + +void __virLogMessage(int level, + const char *msg, + ...) { + char *str; + + if (!logHandler) + return; + + VIR_GET_VAR_STR(msg, str); + + if (str) { + logHandler(logUserData, level, str); + free(str); + } else { + logHandler(logUserData, VIR_LOG_CRITICAL, _("Cannot allocate memory for formatting log message")); + } +} + /* * vim: set tabstop=4: * vim: set shiftwidth=4: