qga: add an optional qemu-ga.conf system configuration
Learn to configure the agent with a system configuration. This may simplify command-line handling, especially when the blacklist is long. Among the other benefits, this may standardize the configuration of an init service (instead of distro-specific init keys/files) Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com> Reviewed-by: Denis V. Lunev <den@openvz.org> * removed unecessary keyfile != NULL prior to free Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
This commit is contained in:
parent
d4c8a5d49e
commit
e236d060cb
84
qga/main.c
84
qga/main.c
@ -56,6 +56,7 @@
|
|||||||
#define QGA_FSFREEZE_HOOK_DEFAULT CONFIG_QEMU_CONFDIR "/fsfreeze-hook"
|
#define QGA_FSFREEZE_HOOK_DEFAULT CONFIG_QEMU_CONFDIR "/fsfreeze-hook"
|
||||||
#endif
|
#endif
|
||||||
#define QGA_SENTINEL_BYTE 0xFF
|
#define QGA_SENTINEL_BYTE 0xFF
|
||||||
|
#define QGA_CONF_DEFAULT CONFIG_QEMU_CONFDIR G_DIR_SEPARATOR_S "qemu-ga.conf"
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
const char *state_dir;
|
const char *state_dir;
|
||||||
@ -931,14 +932,78 @@ typedef struct GAConfig {
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
const char *service;
|
const char *service;
|
||||||
#endif
|
#endif
|
||||||
|
gchar *bliststr; /* blacklist may point to this string */
|
||||||
GList *blacklist;
|
GList *blacklist;
|
||||||
int daemonize;
|
int daemonize;
|
||||||
GLogLevelFlags log_level;
|
GLogLevelFlags log_level;
|
||||||
} GAConfig;
|
} GAConfig;
|
||||||
|
|
||||||
static GAConfig *config_parse(int argc, char **argv)
|
static void config_load(GAConfig *config)
|
||||||
|
{
|
||||||
|
GError *gerr = NULL;
|
||||||
|
GKeyFile *keyfile;
|
||||||
|
|
||||||
|
/* read system config */
|
||||||
|
keyfile = g_key_file_new();
|
||||||
|
if (!g_key_file_load_from_file(keyfile, QGA_CONF_DEFAULT, 0, &gerr)) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (g_key_file_has_key(keyfile, "general", "daemon", NULL)) {
|
||||||
|
config->daemonize =
|
||||||
|
g_key_file_get_boolean(keyfile, "general", "daemon", &gerr);
|
||||||
|
}
|
||||||
|
if (g_key_file_has_key(keyfile, "general", "method", NULL)) {
|
||||||
|
config->method =
|
||||||
|
g_key_file_get_string(keyfile, "general", "method", &gerr);
|
||||||
|
}
|
||||||
|
if (g_key_file_has_key(keyfile, "general", "path", NULL)) {
|
||||||
|
config->channel_path =
|
||||||
|
g_key_file_get_string(keyfile, "general", "path", &gerr);
|
||||||
|
}
|
||||||
|
if (g_key_file_has_key(keyfile, "general", "logfile", NULL)) {
|
||||||
|
config->log_filepath =
|
||||||
|
g_key_file_get_string(keyfile, "general", "logfile", &gerr);
|
||||||
|
}
|
||||||
|
if (g_key_file_has_key(keyfile, "general", "pidfile", NULL)) {
|
||||||
|
config->pid_filepath =
|
||||||
|
g_key_file_get_string(keyfile, "general", "pidfile", &gerr);
|
||||||
|
}
|
||||||
|
#ifdef CONFIG_FSFREEZE
|
||||||
|
if (g_key_file_has_key(keyfile, "general", "fsfreeze-hook", NULL)) {
|
||||||
|
config->fsfreeze_hook =
|
||||||
|
g_key_file_get_string(keyfile,
|
||||||
|
"general", "fsfreeze-hook", &gerr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (g_key_file_has_key(keyfile, "general", "statedir", NULL)) {
|
||||||
|
config->state_dir =
|
||||||
|
g_key_file_get_string(keyfile, "general", "statedir", &gerr);
|
||||||
|
}
|
||||||
|
if (g_key_file_has_key(keyfile, "general", "verbose", NULL) &&
|
||||||
|
g_key_file_get_boolean(keyfile, "general", "verbose", &gerr)) {
|
||||||
|
/* enable all log levels */
|
||||||
|
config->log_level = G_LOG_LEVEL_MASK;
|
||||||
|
}
|
||||||
|
if (g_key_file_has_key(keyfile, "general", "blacklist", NULL)) {
|
||||||
|
config->bliststr =
|
||||||
|
g_key_file_get_string(keyfile, "general", "blacklist", &gerr);
|
||||||
|
config->blacklist = g_list_concat(config->blacklist,
|
||||||
|
split_list(config->bliststr, ","));
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
g_key_file_free(keyfile);
|
||||||
|
if (gerr &&
|
||||||
|
!(gerr->domain == G_FILE_ERROR && gerr->code == G_FILE_ERROR_NOENT)) {
|
||||||
|
g_critical("error loading configuration from path: %s, %s",
|
||||||
|
QGA_CONF_DEFAULT, gerr->message);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
g_clear_error(&gerr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void config_parse(GAConfig *config, int argc, char **argv)
|
||||||
{
|
{
|
||||||
GAConfig *config = g_new0(GAConfig, 1);
|
|
||||||
const char *sopt = "hVvdm:p:l:f:F::b:s:t:D";
|
const char *sopt = "hVvdm:p:l:f:F::b:s:t:D";
|
||||||
int opt_ind = 0, ch;
|
int opt_ind = 0, ch;
|
||||||
const struct option lopt[] = {
|
const struct option lopt[] = {
|
||||||
@ -966,23 +1031,29 @@ static GAConfig *config_parse(int argc, char **argv)
|
|||||||
while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
|
while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'm':
|
case 'm':
|
||||||
|
g_free(config->method);
|
||||||
config->method = g_strdup(optarg);
|
config->method = g_strdup(optarg);
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
|
g_free(config->channel_path);
|
||||||
config->channel_path = g_strdup(optarg);
|
config->channel_path = g_strdup(optarg);
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
|
g_free(config->log_filepath);
|
||||||
config->log_filepath = g_strdup(optarg);
|
config->log_filepath = g_strdup(optarg);
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
|
g_free(config->pid_filepath);
|
||||||
config->pid_filepath = g_strdup(optarg);
|
config->pid_filepath = g_strdup(optarg);
|
||||||
break;
|
break;
|
||||||
#ifdef CONFIG_FSFREEZE
|
#ifdef CONFIG_FSFREEZE
|
||||||
case 'F':
|
case 'F':
|
||||||
|
g_free(config->fsfreeze_hook);
|
||||||
config->fsfreeze_hook = g_strdup(optarg ?: QGA_FSFREEZE_HOOK_DEFAULT);
|
config->fsfreeze_hook = g_strdup(optarg ?: QGA_FSFREEZE_HOOK_DEFAULT);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case 't':
|
case 't':
|
||||||
|
g_free(config->state_dir);
|
||||||
config->state_dir = g_strdup(optarg);
|
config->state_dir = g_strdup(optarg);
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
@ -1042,8 +1113,6 @@ static GAConfig *config_parse(int argc, char **argv)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return config;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void config_free(GAConfig *config)
|
static void config_free(GAConfig *config)
|
||||||
@ -1053,6 +1122,7 @@ static void config_free(GAConfig *config)
|
|||||||
g_free(config->pid_filepath);
|
g_free(config->pid_filepath);
|
||||||
g_free(config->state_dir);
|
g_free(config->state_dir);
|
||||||
g_free(config->channel_path);
|
g_free(config->channel_path);
|
||||||
|
g_free(config->bliststr);
|
||||||
#ifdef CONFIG_FSFREEZE
|
#ifdef CONFIG_FSFREEZE
|
||||||
g_free(config->fsfreeze_hook);
|
g_free(config->fsfreeze_hook);
|
||||||
#endif
|
#endif
|
||||||
@ -1200,13 +1270,13 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int ret = EXIT_SUCCESS;
|
int ret = EXIT_SUCCESS;
|
||||||
GAState *s = g_new0(GAState, 1);
|
GAState *s = g_new0(GAState, 1);
|
||||||
GAConfig *config;
|
GAConfig *config = g_new0(GAConfig, 1);
|
||||||
|
|
||||||
module_call_init(MODULE_INIT_QAPI);
|
module_call_init(MODULE_INIT_QAPI);
|
||||||
|
|
||||||
init_dfl_pathnames();
|
init_dfl_pathnames();
|
||||||
|
config_load(config);
|
||||||
config = config_parse(argc, argv);
|
config_parse(config, argc, argv);
|
||||||
|
|
||||||
if (config->pid_filepath == NULL) {
|
if (config->pid_filepath == NULL) {
|
||||||
config->pid_filepath = g_strdup(dfl_pathnames.pidfile);
|
config->pid_filepath = g_strdup(dfl_pathnames.pidfile);
|
||||||
|
Loading…
Reference in New Issue
Block a user