Split libvirtd config file loading out into separate files

To enable creation of unit tests, split the libvirtd config file
loading code out into separate files.

* daemon/libvirtd.c: Delete config loading code / structs
* daemon/libvirtd-config.c, daemon/libvirtd-config.h: Config
  file loading APIs

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrange 2012-04-04 13:09:09 +01:00
parent 257191c9e4
commit db46f3cefe
4 changed files with 549 additions and 478 deletions

View File

@ -21,6 +21,7 @@ DAEMON_GENERATED = \
DAEMON_SOURCES = \
libvirtd.c libvirtd.h \
libvirtd-config.c libvirtd-config.h \
remote.c remote.h \
stream.c stream.h \
../src/remote/remote_protocol.c \

456
daemon/libvirtd-config.c Normal file
View File

@ -0,0 +1,456 @@
/*
* libvirtd.c: daemon start of day, guest process & i/o management
*
* Copyright (C) 2006-2012 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Daniel P. Berrange <berrange@redhat.com>
*/
#include <config.h>
#include "libvirtd-config.h"
#include "conf.h"
#include "memory.h"
#include "virterror_internal.h"
#include "logging.h"
#include "virnetserver.h"
#include "configmake.h"
#include "remote_protocol.h"
#include "remote_driver.h"
#define VIR_FROM_THIS VIR_FROM_CONF
/* Allocate an array of malloc'd strings from the config file, filename
* (used only in diagnostics), using handle "conf". Upon error, return -1
* and free any allocated memory. Otherwise, save the array in *list_arg
* and return 0.
*/
static int
remoteConfigGetStringList(virConfPtr conf, const char *key, char ***list_arg,
const char *filename)
{
char **list;
virConfValuePtr p = virConfGetValue (conf, key);
if (!p)
return 0;
switch (p->type) {
case VIR_CONF_STRING:
if (VIR_ALLOC_N(list, 2) < 0) {
VIR_ERROR(_("failed to allocate memory for %s config list"), key);
return -1;
}
list[0] = strdup (p->str);
list[1] = NULL;
if (list[0] == NULL) {
VIR_ERROR(_("failed to allocate memory for %s config list value"),
key);
VIR_FREE(list);
return -1;
}
break;
case VIR_CONF_LIST: {
int i, len = 0;
virConfValuePtr pp;
for (pp = p->list; pp; pp = pp->next)
len++;
if (VIR_ALLOC_N(list, 1+len) < 0) {
VIR_ERROR(_("failed to allocate memory for %s config list"), key);
return -1;
}
for (i = 0, pp = p->list; pp; ++i, pp = pp->next) {
if (pp->type != VIR_CONF_STRING) {
VIR_ERROR(_("remoteReadConfigFile: %s: %s:"
" must be a string or list of strings"),
filename, key);
VIR_FREE(list);
return -1;
}
list[i] = strdup (pp->str);
if (list[i] == NULL) {
int j;
for (j = 0 ; j < i ; j++)
VIR_FREE(list[j]);
VIR_FREE(list);
VIR_ERROR(_("failed to allocate memory for %s config list value"),
key);
return -1;
}
}
list[i] = NULL;
break;
}
default:
VIR_ERROR(_("remoteReadConfigFile: %s: %s:"
" must be a string or list of strings"),
filename, key);
return -1;
}
*list_arg = list;
return 0;
}
/* A helper function used by each of the following macros. */
static int
checkType (virConfValuePtr p, const char *filename,
const char *key, virConfType required_type)
{
if (p->type != required_type) {
VIR_ERROR(_("remoteReadConfigFile: %s: %s: invalid type:"
" got %s; expected %s"), filename, key,
virConfTypeName (p->type),
virConfTypeName (required_type));
return -1;
}
return 0;
}
/* If there is no config data for the key, #var_name, then do nothing.
If there is valid data of type VIR_CONF_STRING, and strdup succeeds,
store the result in var_name. Otherwise, (i.e. invalid type, or strdup
failure), give a diagnostic and "goto" the cleanup-and-fail label. */
#define GET_CONF_STR(conf, filename, var_name) \
do { \
virConfValuePtr p = virConfGetValue (conf, #var_name); \
if (p) { \
if (checkType (p, filename, #var_name, VIR_CONF_STRING) < 0) \
goto error; \
VIR_FREE(data->var_name); \
if (!(data->var_name = strdup (p->str))) { \
virReportOOMError(); \
goto error; \
} \
} \
} while (0)
/* Like GET_CONF_STR, but for integral values. */
#define GET_CONF_INT(conf, filename, var_name) \
do { \
virConfValuePtr p = virConfGetValue (conf, #var_name); \
if (p) { \
if (checkType (p, filename, #var_name, VIR_CONF_LONG) < 0) \
goto error; \
data->var_name = p->l; \
} \
} while (0)
static int remoteConfigGetAuth(virConfPtr conf, const char *key, int *auth, const char *filename) {
virConfValuePtr p;
p = virConfGetValue (conf, key);
if (!p)
return 0;
if (checkType (p, filename, key, VIR_CONF_STRING) < 0)
return -1;
if (!p->str)
return 0;
if (STREQ(p->str, "none")) {
*auth = VIR_NET_SERVER_SERVICE_AUTH_NONE;
#if HAVE_SASL
} else if (STREQ(p->str, "sasl")) {
*auth = VIR_NET_SERVER_SERVICE_AUTH_SASL;
#endif
} else if (STREQ(p->str, "polkit")) {
*auth = VIR_NET_SERVER_SERVICE_AUTH_POLKIT;
} else {
VIR_ERROR(_("remoteReadConfigFile: %s: %s: unsupported auth %s"),
filename, key, p->str);
return -1;
}
return 0;
}
int
daemonConfigFilePath(bool privileged, char **configfile)
{
if (privileged) {
if (!(*configfile = strdup(SYSCONFDIR "/libvirt/libvirtd.conf")))
goto no_memory;
} else {
char *userdir = NULL;
if (!(userdir = virGetUserDirectory(geteuid())))
goto error;
if (virAsprintf(configfile, "%s/.libvirt/libvirtd.conf", userdir) < 0) {
VIR_FREE(userdir);
goto no_memory;
}
VIR_FREE(userdir);
}
return 0;
no_memory:
virReportOOMError();
error:
return -1;
}
struct daemonConfig*
daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
{
struct daemonConfig *data;
char *localhost;
int ret;
if (VIR_ALLOC(data) < 0) {
virReportOOMError();
return NULL;
}
data->listen_tls = 1;
data->listen_tcp = 0;
if (!(data->tls_port = strdup(LIBVIRTD_TLS_PORT)))
goto no_memory;
if (!(data->tcp_port = strdup(LIBVIRTD_TCP_PORT)))
goto no_memory;
/* Only default to PolicyKit if running as root */
#if HAVE_POLKIT
if (privileged) {
data->auth_unix_rw = REMOTE_AUTH_POLKIT;
data->auth_unix_ro = REMOTE_AUTH_POLKIT;
} else {
#endif
data->auth_unix_rw = REMOTE_AUTH_NONE;
data->auth_unix_ro = REMOTE_AUTH_NONE;
#if HAVE_POLKIT
}
#endif
if (data->auth_unix_rw == REMOTE_AUTH_POLKIT)
data->unix_sock_rw_perms = strdup("0777"); /* Allow world */
else
data->unix_sock_rw_perms = strdup("0700"); /* Allow user only */
data->unix_sock_ro_perms = strdup("0777"); /* Always allow world */
if (!data->unix_sock_ro_perms ||
!data->unix_sock_rw_perms)
goto no_memory;
#if HAVE_SASL
data->auth_tcp = REMOTE_AUTH_SASL;
#else
data->auth_tcp = REMOTE_AUTH_NONE;
#endif
data->auth_tls = REMOTE_AUTH_NONE;
data->mdns_adv = 0;
data->min_workers = 5;
data->max_workers = 20;
data->max_clients = 20;
data->prio_workers = 5;
data->max_requests = 20;
data->max_client_requests = 5;
data->log_buffer_size = 64;
data->audit_level = 1;
data->audit_logging = 0;
data->keepalive_interval = 5;
data->keepalive_count = 5;
data->keepalive_required = 0;
localhost = virGetHostname(NULL);
if (localhost == NULL) {
/* we couldn't resolve the hostname; assume that we are
* running in disconnected operation, and report a less
* useful Avahi string
*/
ret = virAsprintf(&data->mdns_name, "Virtualization Host");
} else {
char *tmp;
/* Extract the host part of the potentially FQDN */
if ((tmp = strchr(localhost, '.')))
*tmp = '\0';
ret = virAsprintf(&data->mdns_name, "Virtualization Host %s",
localhost);
}
VIR_FREE(localhost);
if (ret < 0)
goto no_memory;
return data;
no_memory:
virReportOOMError();
daemonConfigFree(data);
return NULL;
}
void
daemonConfigFree(struct daemonConfig *data)
{
char **tmp;
if (!data)
return;
VIR_FREE(data->listen_addr);
VIR_FREE(data->tls_port);
VIR_FREE(data->tcp_port);
VIR_FREE(data->unix_sock_ro_perms);
VIR_FREE(data->unix_sock_rw_perms);
VIR_FREE(data->unix_sock_group);
VIR_FREE(data->unix_sock_dir);
VIR_FREE(data->mdns_name);
tmp = data->tls_allowed_dn_list;
while (tmp && *tmp) {
VIR_FREE(*tmp);
tmp++;
}
VIR_FREE(data->tls_allowed_dn_list);
tmp = data->sasl_allowed_username_list;
while (tmp && *tmp) {
VIR_FREE(*tmp);
tmp++;
}
VIR_FREE(data->sasl_allowed_username_list);
VIR_FREE(data->key_file);
VIR_FREE(data->ca_file);
VIR_FREE(data->cert_file);
VIR_FREE(data->crl_file);
VIR_FREE(data->log_filters);
VIR_FREE(data->log_outputs);
VIR_FREE(data);
}
/* Read the config file if it exists.
* Only used in the remote case, hence the name.
*/
int
daemonConfigLoad(struct daemonConfig *data,
const char *filename,
bool allow_missing)
{
virConfPtr conf;
if (allow_missing &&
access(filename, R_OK) == -1 &&
errno == ENOENT)
return 0;
conf = virConfReadFile (filename, 0);
if (!conf)
return -1;
GET_CONF_INT (conf, filename, listen_tcp);
GET_CONF_INT (conf, filename, listen_tls);
GET_CONF_STR (conf, filename, tls_port);
GET_CONF_STR (conf, filename, tcp_port);
GET_CONF_STR (conf, filename, listen_addr);
if (remoteConfigGetAuth(conf, "auth_unix_rw", &data->auth_unix_rw, filename) < 0)
goto error;
#if HAVE_POLKIT
/* Change default perms to be wide-open if PolicyKit is enabled.
* Admin can always override in config file
*/
if (data->auth_unix_rw == REMOTE_AUTH_POLKIT) {
VIR_FREE(data->unix_sock_rw_perms);
if (!(data->unix_sock_rw_perms = strdup("0777"))) {
virReportOOMError();
goto error;
}
}
#endif
if (remoteConfigGetAuth(conf, "auth_unix_ro", &data->auth_unix_ro, filename) < 0)
goto error;
if (remoteConfigGetAuth(conf, "auth_tcp", &data->auth_tcp, filename) < 0)
goto error;
if (remoteConfigGetAuth(conf, "auth_tls", &data->auth_tls, filename) < 0)
goto error;
GET_CONF_STR (conf, filename, unix_sock_group);
GET_CONF_STR (conf, filename, unix_sock_ro_perms);
GET_CONF_STR (conf, filename, unix_sock_rw_perms);
GET_CONF_STR (conf, filename, unix_sock_dir);
GET_CONF_INT (conf, filename, mdns_adv);
GET_CONF_STR (conf, filename, mdns_name);
GET_CONF_INT (conf, filename, tls_no_sanity_certificate);
GET_CONF_INT (conf, filename, tls_no_verify_certificate);
GET_CONF_STR (conf, filename, key_file);
GET_CONF_STR (conf, filename, cert_file);
GET_CONF_STR (conf, filename, ca_file);
GET_CONF_STR (conf, filename, crl_file);
if (remoteConfigGetStringList(conf, "tls_allowed_dn_list",
&data->tls_allowed_dn_list, filename) < 0)
goto error;
if (remoteConfigGetStringList(conf, "sasl_allowed_username_list",
&data->sasl_allowed_username_list, filename) < 0)
goto error;
GET_CONF_INT (conf, filename, min_workers);
GET_CONF_INT (conf, filename, max_workers);
GET_CONF_INT (conf, filename, max_clients);
GET_CONF_INT (conf, filename, prio_workers);
GET_CONF_INT (conf, filename, max_requests);
GET_CONF_INT (conf, filename, max_client_requests);
GET_CONF_INT (conf, filename, audit_level);
GET_CONF_INT (conf, filename, audit_logging);
GET_CONF_STR (conf, filename, host_uuid);
GET_CONF_INT (conf, filename, log_level);
GET_CONF_STR (conf, filename, log_filters);
GET_CONF_STR (conf, filename, log_outputs);
GET_CONF_INT (conf, filename, log_buffer_size);
GET_CONF_INT (conf, filename, keepalive_interval);
GET_CONF_INT (conf, filename, keepalive_count);
GET_CONF_INT (conf, filename, keepalive_required);
virConfFree (conf);
return 0;
error:
virConfFree (conf);
return -1;
}

91
daemon/libvirtd-config.h Normal file
View File

@ -0,0 +1,91 @@
/*
* libvirtd.c: daemon start of day, guest process & i/o management
*
* Copyright (C) 2006-2012 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Daniel P. Berrange <berrange@redhat.com>
*/
#ifndef __LIBVIRTD_CONFIG_H__
# define __LIBVIRTD_CONFIG_H__
# include "internal.h"
struct daemonConfig {
char *host_uuid;
int listen_tls;
int listen_tcp;
char *listen_addr;
char *tls_port;
char *tcp_port;
char *unix_sock_ro_perms;
char *unix_sock_rw_perms;
char *unix_sock_group;
char *unix_sock_dir;
int auth_unix_rw;
int auth_unix_ro;
int auth_tcp;
int auth_tls;
int mdns_adv;
char *mdns_name;
int tls_no_verify_certificate;
int tls_no_sanity_certificate;
char **tls_allowed_dn_list;
char **sasl_allowed_username_list;
char *key_file;
char *cert_file;
char *ca_file;
char *crl_file;
int min_workers;
int max_workers;
int max_clients;
int prio_workers;
int max_requests;
int max_client_requests;
int log_level;
char *log_filters;
char *log_outputs;
int log_buffer_size;
int audit_level;
int audit_logging;
int keepalive_interval;
unsigned int keepalive_count;
int keepalive_required;
};
int daemonConfigFilePath(bool privileged, char **configfile);
struct daemonConfig* daemonConfigNew(bool privileged);
void daemonConfigFree(struct daemonConfig *data);
int daemonConfigLoad(struct daemonConfig *data,
const char *filename,
bool allow_missing);
#endif /* __LIBVIRTD_CONFIG_H__ */

View File

@ -40,11 +40,11 @@
#define VIR_FROM_THIS VIR_FROM_QEMU
#include "libvirtd.h"
#include "libvirtd-config.h"
#include "util.h"
#include "uuid.h"
#include "remote_driver.h"
#include "conf.h"
#include "memory.h"
#include "conf.h"
#include "virnetlink.h"
@ -99,60 +99,6 @@ virNetSASLContextPtr saslCtxt = NULL;
virNetServerProgramPtr remoteProgram = NULL;
virNetServerProgramPtr qemuProgram = NULL;
struct daemonConfig {
char *host_uuid;
int listen_tls;
int listen_tcp;
char *listen_addr;
char *tls_port;
char *tcp_port;
char *unix_sock_ro_perms;
char *unix_sock_rw_perms;
char *unix_sock_group;
char *unix_sock_dir;
int auth_unix_rw;
int auth_unix_ro;
int auth_tcp;
int auth_tls;
int mdns_adv;
char *mdns_name;
int tls_no_verify_certificate;
int tls_no_sanity_certificate;
char **tls_allowed_dn_list;
char **sasl_allowed_username_list;
char *key_file;
char *cert_file;
char *ca_file;
char *crl_file;
int min_workers;
int max_workers;
int max_clients;
int prio_workers;
int max_requests;
int max_client_requests;
int log_level;
char *log_filters;
char *log_outputs;
int log_buffer_size;
int audit_level;
int audit_logging;
int keepalive_interval;
unsigned int keepalive_count;
int keepalive_required;
};
enum {
VIR_DAEMON_ERR_NONE = 0,
VIR_DAEMON_ERR_PIDFILE,
@ -592,155 +538,6 @@ static int daemonShutdownCheck(virNetServerPtr srv ATTRIBUTE_UNUSED,
}
/* Allocate an array of malloc'd strings from the config file, filename
* (used only in diagnostics), using handle "conf". Upon error, return -1
* and free any allocated memory. Otherwise, save the array in *list_arg
* and return 0.
*/
static int
remoteConfigGetStringList(virConfPtr conf, const char *key, char ***list_arg,
const char *filename)
{
char **list;
virConfValuePtr p = virConfGetValue (conf, key);
if (!p)
return 0;
switch (p->type) {
case VIR_CONF_STRING:
if (VIR_ALLOC_N(list, 2) < 0) {
VIR_ERROR(_("failed to allocate memory for %s config list"), key);
return -1;
}
list[0] = strdup (p->str);
list[1] = NULL;
if (list[0] == NULL) {
VIR_ERROR(_("failed to allocate memory for %s config list value"),
key);
VIR_FREE(list);
return -1;
}
break;
case VIR_CONF_LIST: {
int i, len = 0;
virConfValuePtr pp;
for (pp = p->list; pp; pp = pp->next)
len++;
if (VIR_ALLOC_N(list, 1+len) < 0) {
VIR_ERROR(_("failed to allocate memory for %s config list"), key);
return -1;
}
for (i = 0, pp = p->list; pp; ++i, pp = pp->next) {
if (pp->type != VIR_CONF_STRING) {
VIR_ERROR(_("remoteReadConfigFile: %s: %s:"
" must be a string or list of strings"),
filename, key);
VIR_FREE(list);
return -1;
}
list[i] = strdup (pp->str);
if (list[i] == NULL) {
int j;
for (j = 0 ; j < i ; j++)
VIR_FREE(list[j]);
VIR_FREE(list);
VIR_ERROR(_("failed to allocate memory for %s config list value"),
key);
return -1;
}
}
list[i] = NULL;
break;
}
default:
VIR_ERROR(_("remoteReadConfigFile: %s: %s:"
" must be a string or list of strings"),
filename, key);
return -1;
}
*list_arg = list;
return 0;
}
/* A helper function used by each of the following macros. */
static int
checkType (virConfValuePtr p, const char *filename,
const char *key, virConfType required_type)
{
if (p->type != required_type) {
VIR_ERROR(_("remoteReadConfigFile: %s: %s: invalid type:"
" got %s; expected %s"), filename, key,
virConfTypeName (p->type),
virConfTypeName (required_type));
return -1;
}
return 0;
}
/* If there is no config data for the key, #var_name, then do nothing.
If there is valid data of type VIR_CONF_STRING, and strdup succeeds,
store the result in var_name. Otherwise, (i.e. invalid type, or strdup
failure), give a diagnostic and "goto" the cleanup-and-fail label. */
#define GET_CONF_STR(conf, filename, var_name) \
do { \
virConfValuePtr p = virConfGetValue (conf, #var_name); \
if (p) { \
if (checkType (p, filename, #var_name, VIR_CONF_STRING) < 0) \
goto error; \
VIR_FREE(data->var_name); \
if (!(data->var_name = strdup (p->str))) { \
virReportOOMError(); \
goto error; \
} \
} \
} while (0)
/* Like GET_CONF_STR, but for integral values. */
#define GET_CONF_INT(conf, filename, var_name) \
do { \
virConfValuePtr p = virConfGetValue (conf, #var_name); \
if (p) { \
if (checkType (p, filename, #var_name, VIR_CONF_LONG) < 0) \
goto error; \
data->var_name = p->l; \
} \
} while (0)
static int remoteConfigGetAuth(virConfPtr conf, const char *key, int *auth, const char *filename) {
virConfValuePtr p;
p = virConfGetValue (conf, key);
if (!p)
return 0;
if (checkType (p, filename, key, VIR_CONF_STRING) < 0)
return -1;
if (!p->str)
return 0;
if (STREQ(p->str, "none")) {
*auth = VIR_NET_SERVER_SERVICE_AUTH_NONE;
#if HAVE_SASL
} else if (STREQ(p->str, "sasl")) {
*auth = VIR_NET_SERVER_SERVICE_AUTH_SASL;
#endif
} else if (STREQ(p->str, "polkit")) {
*auth = VIR_NET_SERVER_SERVICE_AUTH_POLKIT;
} else {
VIR_ERROR(_("remoteReadConfigFile: %s: %s: unsupported auth %s"),
filename, key, p->str);
return -1;
}
return 0;
}
/*
* Set up the logging environment
* By default if daemonized all errors go to the logfile libvirtd.log,
@ -830,280 +627,6 @@ error:
}
static int
daemonConfigFilePath(bool privileged, char **configfile)
{
if (privileged) {
if (!(*configfile = strdup(SYSCONFDIR "/libvirt/libvirtd.conf")))
goto no_memory;
} else {
char *userdir = NULL;
if (!(userdir = virGetUserDirectory(geteuid())))
goto error;
if (virAsprintf(configfile, "%s/.libvirt/libvirtd.conf", userdir) < 0) {
VIR_FREE(userdir);
goto no_memory;
}
VIR_FREE(userdir);
}
return 0;
no_memory:
virReportOOMError();
error:
return -1;
}
static void
daemonConfigFree(struct daemonConfig *data);
static struct daemonConfig*
daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
{
struct daemonConfig *data;
char *localhost;
int ret;
if (VIR_ALLOC(data) < 0) {
virReportOOMError();
return NULL;
}
data->listen_tls = 1;
data->listen_tcp = 0;
if (!(data->tls_port = strdup(LIBVIRTD_TLS_PORT)))
goto no_memory;
if (!(data->tcp_port = strdup(LIBVIRTD_TCP_PORT)))
goto no_memory;
/* Only default to PolicyKit if running as root */
#if HAVE_POLKIT
if (privileged) {
data->auth_unix_rw = REMOTE_AUTH_POLKIT;
data->auth_unix_ro = REMOTE_AUTH_POLKIT;
} else {
#endif
data->auth_unix_rw = REMOTE_AUTH_NONE;
data->auth_unix_ro = REMOTE_AUTH_NONE;
#if HAVE_POLKIT
}
#endif
if (data->auth_unix_rw == REMOTE_AUTH_POLKIT)
data->unix_sock_rw_perms = strdup("0777"); /* Allow world */
else
data->unix_sock_rw_perms = strdup("0700"); /* Allow user only */
data->unix_sock_ro_perms = strdup("0777"); /* Always allow world */
if (!data->unix_sock_ro_perms ||
!data->unix_sock_rw_perms)
goto no_memory;
#if HAVE_SASL
data->auth_tcp = REMOTE_AUTH_SASL;
#else
data->auth_tcp = REMOTE_AUTH_NONE;
#endif
data->auth_tls = REMOTE_AUTH_NONE;
data->mdns_adv = 0;
data->min_workers = 5;
data->max_workers = 20;
data->max_clients = 20;
data->prio_workers = 5;
data->max_requests = 20;
data->max_client_requests = 5;
data->log_buffer_size = 64;
data->audit_level = 1;
data->audit_logging = 0;
data->keepalive_interval = 5;
data->keepalive_count = 5;
data->keepalive_required = 0;
localhost = virGetHostname(NULL);
if (localhost == NULL) {
/* we couldn't resolve the hostname; assume that we are
* running in disconnected operation, and report a less
* useful Avahi string
*/
ret = virAsprintf(&data->mdns_name, "Virtualization Host");
} else {
char *tmp;
/* Extract the host part of the potentially FQDN */
if ((tmp = strchr(localhost, '.')))
*tmp = '\0';
ret = virAsprintf(&data->mdns_name, "Virtualization Host %s",
localhost);
}
VIR_FREE(localhost);
if (ret < 0)
goto no_memory;
return data;
no_memory:
virReportOOMError();
daemonConfigFree(data);
return NULL;
}
static void
daemonConfigFree(struct daemonConfig *data)
{
char **tmp;
if (!data)
return;
VIR_FREE(data->listen_addr);
VIR_FREE(data->tls_port);
VIR_FREE(data->tcp_port);
VIR_FREE(data->unix_sock_ro_perms);
VIR_FREE(data->unix_sock_rw_perms);
VIR_FREE(data->unix_sock_group);
VIR_FREE(data->unix_sock_dir);
VIR_FREE(data->mdns_name);
tmp = data->tls_allowed_dn_list;
while (tmp && *tmp) {
VIR_FREE(*tmp);
tmp++;
}
VIR_FREE(data->tls_allowed_dn_list);
tmp = data->sasl_allowed_username_list;
while (tmp && *tmp) {
VIR_FREE(*tmp);
tmp++;
}
VIR_FREE(data->sasl_allowed_username_list);
VIR_FREE(data->key_file);
VIR_FREE(data->ca_file);
VIR_FREE(data->cert_file);
VIR_FREE(data->crl_file);
VIR_FREE(data->log_filters);
VIR_FREE(data->log_outputs);
VIR_FREE(data);
}
/* Read the config file if it exists.
* Only used in the remote case, hence the name.
*/
static int
daemonConfigLoad(struct daemonConfig *data,
const char *filename,
bool allow_missing)
{
virConfPtr conf;
if (allow_missing &&
access(filename, R_OK) == -1 &&
errno == ENOENT)
return 0;
conf = virConfReadFile (filename, 0);
if (!conf)
return -1;
GET_CONF_INT (conf, filename, listen_tcp);
GET_CONF_INT (conf, filename, listen_tls);
GET_CONF_STR (conf, filename, tls_port);
GET_CONF_STR (conf, filename, tcp_port);
GET_CONF_STR (conf, filename, listen_addr);
if (remoteConfigGetAuth(conf, "auth_unix_rw", &data->auth_unix_rw, filename) < 0)
goto error;
#if HAVE_POLKIT
/* Change default perms to be wide-open if PolicyKit is enabled.
* Admin can always override in config file
*/
if (data->auth_unix_rw == REMOTE_AUTH_POLKIT) {
VIR_FREE(data->unix_sock_rw_perms);
if (!(data->unix_sock_rw_perms = strdup("0777"))) {
virReportOOMError();
goto error;
}
}
#endif
if (remoteConfigGetAuth(conf, "auth_unix_ro", &data->auth_unix_ro, filename) < 0)
goto error;
if (remoteConfigGetAuth(conf, "auth_tcp", &data->auth_tcp, filename) < 0)
goto error;
if (remoteConfigGetAuth(conf, "auth_tls", &data->auth_tls, filename) < 0)
goto error;
GET_CONF_STR (conf, filename, unix_sock_group);
GET_CONF_STR (conf, filename, unix_sock_ro_perms);
GET_CONF_STR (conf, filename, unix_sock_rw_perms);
GET_CONF_STR (conf, filename, unix_sock_dir);
GET_CONF_INT (conf, filename, mdns_adv);
GET_CONF_STR (conf, filename, mdns_name);
GET_CONF_INT (conf, filename, tls_no_sanity_certificate);
GET_CONF_INT (conf, filename, tls_no_verify_certificate);
GET_CONF_STR (conf, filename, key_file);
GET_CONF_STR (conf, filename, cert_file);
GET_CONF_STR (conf, filename, ca_file);
GET_CONF_STR (conf, filename, crl_file);
if (remoteConfigGetStringList(conf, "tls_allowed_dn_list",
&data->tls_allowed_dn_list, filename) < 0)
goto error;
if (remoteConfigGetStringList(conf, "sasl_allowed_username_list",
&data->sasl_allowed_username_list, filename) < 0)
goto error;
GET_CONF_INT (conf, filename, min_workers);
GET_CONF_INT (conf, filename, max_workers);
GET_CONF_INT (conf, filename, max_clients);
GET_CONF_INT (conf, filename, prio_workers);
GET_CONF_INT (conf, filename, max_requests);
GET_CONF_INT (conf, filename, max_client_requests);
GET_CONF_INT (conf, filename, audit_level);
GET_CONF_INT (conf, filename, audit_logging);
GET_CONF_STR (conf, filename, host_uuid);
GET_CONF_INT (conf, filename, log_level);
GET_CONF_STR (conf, filename, log_filters);
GET_CONF_STR (conf, filename, log_outputs);
GET_CONF_INT (conf, filename, log_buffer_size);
GET_CONF_INT (conf, filename, keepalive_interval);
GET_CONF_INT (conf, filename, keepalive_count);
GET_CONF_INT (conf, filename, keepalive_required);
virConfFree (conf);
return 0;
error:
virConfFree (conf);
return -1;
}
/* Display version information. */
static void
daemonVersion(const char *argv0)