* after filtering, multiple output can be used simultaneously
*/
struct _virLogOutput {
- bool logVersion;
+ bool logInitMessage;
void *data;
virLogOutputFunc f;
virLogCloseFunc c;
goto cleanup;
}
ret = virLogNbOutputs++;
- virLogOutputs[ret].logVersion = true;
+ virLogOutputs[ret].logInitMessage = true;
virLogOutputs[ret].f = f;
virLogOutputs[ret].c = c;
virLogOutputs[ret].data = data;
return virLogFormatString(msg, 0, NULL, VIR_LOG_INFO, VIR_LOG_VERSION_STRING);
}
+/* Similar to virGetHostname() but avoids use of error
+ * reporting APIs or logging APIs, to prevent recursion
+ */
+static int
+virLogHostnameString(const char **rawmsg,
+ char **msg)
+{
+ char *hostname = virGetHostnameQuiet();
+ char *hoststr;
+
+ if (!hostname)
+ return -1;
+
+ if (virAsprintfQuiet(&hoststr, "hostname: %s", hostname) < 0) {
+ VIR_FREE(hostname);
+ return -1;
+ }
+
+ if (virLogFormatString(msg, 0, NULL, VIR_LOG_INFO, hoststr) < 0) {
+ VIR_FREE(hoststr);
+ return -1;
+ }
+ *rawmsg = hoststr;
+ return 0;
+}
+
static void
virLogSourceUpdate(virLogSourcePtr source)
const char *fmt,
va_list vargs)
{
- static bool logVersionStderr = true;
+ static bool logInitMessageStderr = true;
char *str = NULL;
char *msg = NULL;
char timestamp[VIR_TIME_STRING_BUFLEN];
*/
for (i = 0; i < virLogNbOutputs; i++) {
if (priority >= virLogOutputs[i].priority) {
- if (virLogOutputs[i].logVersion) {
- const char *rawver;
- char *ver = NULL;
- if (virLogVersionString(&rawver, &ver) >= 0)
+ if (virLogOutputs[i].logInitMessage) {
+ const char *rawinitmsg;
+ char *initmsg = NULL;
+ if (virLogVersionString(&rawinitmsg, &initmsg) >= 0)
+ virLogOutputs[i].f(&virLogSelf, VIR_LOG_INFO,
+ __FILE__, __LINE__, __func__,
+ timestamp, NULL, 0, rawinitmsg, initmsg,
+ virLogOutputs[i].data);
+ VIR_FREE(initmsg);
+ if (virLogHostnameString(&rawinitmsg, &initmsg) >= 0)
virLogOutputs[i].f(&virLogSelf, VIR_LOG_INFO,
__FILE__, __LINE__, __func__,
- timestamp, NULL, 0, rawver, ver,
+ timestamp, NULL, 0, rawinitmsg, initmsg,
virLogOutputs[i].data);
- VIR_FREE(ver);
- virLogOutputs[i].logVersion = false;
+ VIR_FREE(initmsg);
+ virLogOutputs[i].logInitMessage = false;
}
virLogOutputs[i].f(source, priority,
filename, linenr, funcname,
}
}
if (virLogNbOutputs == 0) {
- if (logVersionStderr) {
- const char *rawver;
- char *ver = NULL;
- if (virLogVersionString(&rawver, &ver) >= 0)
+ if (logInitMessageStderr) {
+ const char *rawinitmsg;
+ char *initmsg = NULL;
+ if (virLogVersionString(&rawinitmsg, &initmsg) >= 0)
+ virLogOutputToFd(&virLogSelf, VIR_LOG_INFO,
+ __FILE__, __LINE__, __func__,
+ timestamp, NULL, 0, rawinitmsg, initmsg,
+ (void *) STDERR_FILENO);
+ VIR_FREE(initmsg);
+ if (virLogHostnameString(&rawinitmsg, &initmsg) >= 0)
virLogOutputToFd(&virLogSelf, VIR_LOG_INFO,
__FILE__, __LINE__, __func__,
- timestamp, NULL, 0, rawver, ver,
+ timestamp, NULL, 0, rawinitmsg, initmsg,
(void *) STDERR_FILENO);
- VIR_FREE(ver);
- logVersionStderr = false;
+ VIR_FREE(initmsg);
+ logInitMessageStderr = false;
}
virLogOutputToFd(source, priority,
filename, linenr, funcname,
* we got from getaddrinfo(). Return the value from gethostname()
* and hope for the best.
*/
-char *virGetHostname(void)
+static char *
+virGetHostnameImpl(bool quiet)
{
int r;
- char hostname[HOST_NAME_MAX+1], *result;
+ char hostname[HOST_NAME_MAX+1], *result = NULL;
struct addrinfo hints, *info;
r = gethostname(hostname, sizeof(hostname));
if (r == -1) {
- virReportSystemError(errno,
- "%s", _("failed to determine host name"));
+ if (!quiet)
+ virReportSystemError(errno,
+ "%s", _("failed to determine host name"));
return NULL;
}
NUL_TERMINATE(hostname);
* string as-is; it's up to callers to check whether "localhost"
* is allowed.
*/
- ignore_value(VIR_STRDUP(result, hostname));
+ ignore_value(VIR_STRDUP_QUIET(result, hostname));
goto cleanup;
}
hints.ai_family = AF_UNSPEC;
r = getaddrinfo(hostname, NULL, &hints, &info);
if (r != 0) {
- VIR_WARN("getaddrinfo failed for '%s': %s",
- hostname, gai_strerror(r));
- ignore_value(VIR_STRDUP(result, hostname));
+ if (!quiet)
+ VIR_WARN("getaddrinfo failed for '%s': %s",
+ hostname, gai_strerror(r));
+ ignore_value(VIR_STRDUP_QUIET(result, hostname));
goto cleanup;
}
* localhost. Ignore the canonicalized name and just return the
* original hostname
*/
- ignore_value(VIR_STRDUP(result, hostname));
+ ignore_value(VIR_STRDUP_QUIET(result, hostname));
else
/* Caller frees this string. */
- ignore_value(VIR_STRDUP(result, info->ai_canonname));
+ ignore_value(VIR_STRDUP_QUIET(result, info->ai_canonname));
freeaddrinfo(info);
cleanup:
+ if (!result)
+ virReportOOMError();
return result;
}
+char *
+virGetHostname(void)
+{
+ return virGetHostnameImpl(false);
+}
+
+
+char *
+virGetHostnameQuiet(void)
+{
+ return virGetHostnameImpl(true);
+}
+
+
char *
virGetUserDirectory(void)
{