Blame src/main.c

Packit Service 87a54e
/* SPDX-License-Identifier: GPL-2.0-or-later */
Packit 5756e2
/*
Packit 5756e2
 * Copyright (C) 2004 - 2017 Red Hat, Inc.
Packit 5756e2
 * Copyright (C) 2005 - 2008 Novell, Inc.
Packit 5756e2
 */
Packit 5756e2
Packit 5756e2
#include "nm-default.h"
Packit 5756e2
Packit 5756e2
#include <getopt.h>
Packit 5756e2
#include <locale.h>
Packit 5756e2
#include <stdlib.h>
Packit 5756e2
#include <signal.h>
Packit 5756e2
#include <unistd.h>
Packit 5756e2
#include <fcntl.h>
Packit 5756e2
#include <sys/stat.h>
Packit 5756e2
#include <sys/types.h>
Packit 5756e2
#include <sys/resource.h>
Packit 5756e2
Packit 5756e2
#include "main-utils.h"
Packit 5756e2
#include "nm-dbus-interface.h"
Packit 5756e2
#include "NetworkManagerUtils.h"
Packit 5756e2
#include "nm-manager.h"
Packit 5756e2
#include "platform/nm-linux-platform.h"
Packit 5756e2
#include "nm-dbus-manager.h"
Packit 5756e2
#include "devices/nm-device.h"
Packit 5756e2
#include "dhcp/nm-dhcp-manager.h"
Packit 5756e2
#include "nm-config.h"
Packit 5756e2
#include "nm-session-monitor.h"
Packit 5756e2
#include "nm-dispatcher.h"
Packit 5756e2
#include "settings/nm-settings.h"
Packit 5756e2
#include "nm-auth-manager.h"
Packit 5756e2
#include "nm-core-internal.h"
Packit 5756e2
#include "nm-dbus-object.h"
Packit 5756e2
#include "nm-connectivity.h"
Packit 5756e2
#include "dns/nm-dns-manager.h"
Packit 5756e2
#include "systemd/nm-sd.h"
Packit 5756e2
#include "nm-netns.h"
Packit 5756e2
Packit 5756e2
#if !defined(NM_DIST_VERSION)
Packit Service a1bd4f
    #define NM_DIST_VERSION VERSION
Packit 5756e2
#endif
Packit 5756e2
Packit Service a1bd4f
#define NM_DEFAULT_PID_FILE NMRUNDIR "/NetworkManager.pid"
Packit 5756e2
Packit 5756e2
#define CONFIG_ATOMIC_SECTION_PREFIXES ((char **) NULL)
Packit 5756e2
Packit Service a1bd4f
static GMainLoop *main_loop          = NULL;
Packit Service a1bd4f
static gboolean   configure_and_quit = FALSE;
Packit 5756e2
Packit 5756e2
static struct {
Packit Service a1bd4f
    gboolean show_version;
Packit Service a1bd4f
    gboolean print_config;
Packit Service a1bd4f
    gboolean become_daemon;
Packit Service a1bd4f
    gboolean g_fatal_warnings;
Packit Service a1bd4f
    gboolean run_from_build_dir;
Packit Service a1bd4f
    char *   opt_log_level;
Packit Service a1bd4f
    char *   opt_log_domains;
Packit Service a1bd4f
    char *   pidfile;
Packit 5756e2
} global_opt = {
Packit Service a1bd4f
    .become_daemon = TRUE,
Packit 5756e2
};
Packit 5756e2
Packit 5756e2
static void
Packit Service a1bd4f
_set_g_fatal_warnings(void)
Packit 5756e2
{
Packit Service a1bd4f
    GLogLevelFlags fatal_mask;
Packit 5756e2
Packit Service a1bd4f
    fatal_mask = g_log_set_always_fatal(G_LOG_FATAL_MASK);
Packit Service a1bd4f
    fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
Packit Service a1bd4f
    g_log_set_always_fatal(fatal_mask);
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
static void
Packit Service a1bd4f
_init_nm_debug(NMConfig *config)
Packit 5756e2
{
Packit Service a1bd4f
    gs_free char *debug = NULL;
Packit Service a1bd4f
    enum {
Packit Service a1bd4f
        D_RLIMIT_CORE    = (1 << 0),
Packit Service a1bd4f
        D_FATAL_WARNINGS = (1 << 1),
Packit Service a1bd4f
    };
Packit Service a1bd4f
    GDebugKey keys[] = {
Packit Service a1bd4f
        {"RLIMIT_CORE", D_RLIMIT_CORE},
Packit Service a1bd4f
        {"fatal-warnings", D_FATAL_WARNINGS},
Packit Service a1bd4f
    };
Packit Service a1bd4f
    guint       flags;
Packit Service a1bd4f
    const char *env = getenv("NM_DEBUG");
Packit Service a1bd4f
Packit Service a1bd4f
    debug = nm_config_data_get_value(nm_config_get_data_orig(config),
Packit Service a1bd4f
                                     NM_CONFIG_KEYFILE_GROUP_MAIN,
Packit Service a1bd4f
                                     NM_CONFIG_KEYFILE_KEY_MAIN_DEBUG,
Packit Service a1bd4f
                                     NM_CONFIG_GET_VALUE_NONE);
Packit Service a1bd4f
Packit Service a1bd4f
    flags = nm_utils_parse_debug_string(env, keys, G_N_ELEMENTS(keys));
Packit Service a1bd4f
    flags |= nm_utils_parse_debug_string(debug, keys, G_N_ELEMENTS(keys));
Packit Service a1bd4f
Packit Service a1bd4f
#if !defined(__SANITIZE_ADDRESS__)
Packit Service a1bd4f
    if (NM_FLAGS_HAS(flags, D_RLIMIT_CORE)) {
Packit Service a1bd4f
        /* only enable this, if explicitly requested, because it might
Packit Service a1bd4f
         * expose sensitive data. */
Packit Service a1bd4f
Packit Service a1bd4f
        struct rlimit limit = {
Packit Service a1bd4f
            .rlim_cur = RLIM_INFINITY,
Packit Service a1bd4f
            .rlim_max = RLIM_INFINITY,
Packit Service a1bd4f
        };
Packit Service a1bd4f
        setrlimit(RLIMIT_CORE, &limit);
Packit Service a1bd4f
    }
Packit 5756e2
#endif
Packit 5756e2
Packit Service a1bd4f
    if (NM_FLAGS_HAS(flags, D_FATAL_WARNINGS))
Packit Service a1bd4f
        _set_g_fatal_warnings();
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
void
Packit Service a1bd4f
nm_main_config_reload(int signal)
Packit 5756e2
{
Packit Service a1bd4f
    NMConfigChangeFlags reload_flags;
Packit Service a1bd4f
Packit Service a1bd4f
    switch (signal) {
Packit Service a1bd4f
    case SIGHUP:
Packit Service a1bd4f
        reload_flags = NM_CONFIG_CHANGE_CAUSE_SIGHUP;
Packit Service a1bd4f
        break;
Packit Service a1bd4f
    case SIGUSR1:
Packit Service a1bd4f
        reload_flags = NM_CONFIG_CHANGE_CAUSE_SIGUSR1;
Packit Service a1bd4f
        break;
Packit Service a1bd4f
    case SIGUSR2:
Packit Service a1bd4f
        reload_flags = NM_CONFIG_CHANGE_CAUSE_SIGUSR2;
Packit Service a1bd4f
        break;
Packit Service a1bd4f
    default:
Packit Service a1bd4f
        g_return_if_reached();
Packit Service a1bd4f
    }
Packit Service a1bd4f
Packit Service a1bd4f
    nm_log_info(LOGD_CORE, "reload configuration (signal %s)...", strsignal(signal));
Packit Service a1bd4f
Packit Service a1bd4f
    /* The signal handler thread is only installed after
Packit Service a1bd4f
     * creating NMConfig instance, and on shut down we
Packit Service a1bd4f
     * no longer run the mainloop (to reach this point).
Packit Service a1bd4f
     *
Packit Service a1bd4f
     * Hence, a NMConfig singleton instance must always be
Packit Service a1bd4f
     * available. */
Packit Service a1bd4f
    nm_config_reload(nm_config_get(), reload_flags, TRUE);
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
static void
Packit Service a1bd4f
manager_configure_quit(NMManager *manager, gpointer user_data)
Packit 5756e2
{
Packit Service a1bd4f
    nm_log_info(LOGD_CORE, "quitting now that startup is complete");
Packit Service a1bd4f
    g_main_loop_quit(main_loop);
Packit Service a1bd4f
    configure_and_quit = TRUE;
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
static int
Packit Service a1bd4f
print_config(NMConfigCmdLineOptions *config_cli)
Packit 5756e2
{
Packit Service a1bd4f
    gs_unref_object NMConfig *config = NULL;
Packit Service a1bd4f
    gs_free_error GError *error      = NULL;
Packit Service a1bd4f
    NMConfigData *        config_data;
Packit Service a1bd4f
    const char *const *   warnings;
Packit Service a1bd4f
Packit Service a1bd4f
    nm_logging_setup("OFF", "ALL", NULL, NULL);
Packit Service a1bd4f
Packit Service a1bd4f
    config = nm_config_new(config_cli, CONFIG_ATOMIC_SECTION_PREFIXES, &error);
Packit Service a1bd4f
    if (config == NULL) {
Packit Service a1bd4f
        fprintf(stderr, _("Failed to read configuration: %s\n"), error->message);
Packit Service a1bd4f
        return 7;
Packit Service a1bd4f
    }
Packit Service a1bd4f
Packit Service a1bd4f
    config_data = nm_config_get_data(config);
Packit Service a1bd4f
    fprintf(stdout,
Packit Service a1bd4f
            "# NetworkManager configuration: %s\n",
Packit Service a1bd4f
            nm_config_data_get_config_description(config_data));
Packit Service a1bd4f
    nm_config_data_log(config_data, "", "", nm_config_get_no_auto_default_file(config), stdout);
Packit Service a1bd4f
Packit Service a1bd4f
    warnings = nm_config_get_warnings(config);
Packit Service a1bd4f
    if (warnings && warnings[0])
Packit Service a1bd4f
        fprintf(stdout, "\n");
Packit Service a1bd4f
    for (; warnings && warnings[0]; warnings++)
Packit Service a1bd4f
        fprintf(stdout, "# WARNING: %s\n", warnings[0]);
Packit Service a1bd4f
Packit Service a1bd4f
    return 0;
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
static void
Packit Service a1bd4f
do_early_setup(int *argc, char **argv[], NMConfigCmdLineOptions *config_cli)
Packit 5756e2
{
Packit Service a1bd4f
    GOptionEntry options[] = {{"version",
Packit Service a1bd4f
                               'V',
Packit Service a1bd4f
                               0,
Packit Service a1bd4f
                               G_OPTION_ARG_NONE,
Packit Service a1bd4f
                               &global_opt.show_version,
Packit Service a1bd4f
                               N_("Print NetworkManager version and exit"),
Packit Service a1bd4f
                               NULL},
Packit Service a1bd4f
                              {"no-daemon",
Packit Service a1bd4f
                               'n',
Packit Service a1bd4f
                               G_OPTION_FLAG_REVERSE,
Packit Service a1bd4f
                               G_OPTION_ARG_NONE,
Packit Service a1bd4f
                               &global_opt.become_daemon,
Packit Service a1bd4f
                               N_("Don't become a daemon"),
Packit Service a1bd4f
                               NULL},
Packit Service a1bd4f
                              {"log-level",
Packit Service a1bd4f
                               0,
Packit Service a1bd4f
                               0,
Packit Service a1bd4f
                               G_OPTION_ARG_STRING,
Packit Service a1bd4f
                               &global_opt.opt_log_level,
Packit Service a1bd4f
                               N_("Log level: one of [%s]"),
Packit Service a1bd4f
                               "INFO"},
Packit Service a1bd4f
                              {"log-domains",
Packit Service a1bd4f
                               0,
Packit Service a1bd4f
                               0,
Packit Service a1bd4f
                               G_OPTION_ARG_STRING,
Packit Service a1bd4f
                               &global_opt.opt_log_domains,
Packit Service a1bd4f
                               N_("Log domains separated by ',': any combination of [%s]"),
Packit Service a1bd4f
                               "PLATFORM,RFKILL,WIFI"},
Packit Service a1bd4f
                              {"g-fatal-warnings",
Packit Service a1bd4f
                               0,
Packit Service a1bd4f
                               0,
Packit Service a1bd4f
                               G_OPTION_ARG_NONE,
Packit Service a1bd4f
                               &global_opt.g_fatal_warnings,
Packit Service a1bd4f
                               N_("Make all warnings fatal"),
Packit Service a1bd4f
                               NULL},
Packit Service a1bd4f
                              {"pid-file",
Packit Service a1bd4f
                               'p',
Packit Service a1bd4f
                               0,
Packit Service a1bd4f
                               G_OPTION_ARG_FILENAME,
Packit Service a1bd4f
                               &global_opt.pidfile,
Packit Service a1bd4f
                               N_("Specify the location of a PID file"),
Packit Service a1bd4f
                               NM_DEFAULT_PID_FILE},
Packit Service a1bd4f
                              {"run-from-build-dir",
Packit Service a1bd4f
                               0,
Packit Service a1bd4f
                               0,
Packit Service a1bd4f
                               G_OPTION_ARG_NONE,
Packit Service a1bd4f
                               &global_opt.run_from_build_dir,
Packit Service a1bd4f
                               "Run from build directory",
Packit Service a1bd4f
                               NULL},
Packit Service a1bd4f
                              {"print-config",
Packit Service a1bd4f
                               0,
Packit Service a1bd4f
                               0,
Packit Service a1bd4f
                               G_OPTION_ARG_NONE,
Packit Service a1bd4f
                               &global_opt.print_config,
Packit Service a1bd4f
                               N_("Print NetworkManager configuration and exit"),
Packit Service a1bd4f
                               NULL},
Packit Service a1bd4f
                              {NULL}};
Packit Service a1bd4f
Packit Service a1bd4f
    if (!nm_main_utils_early_setup(
Packit Service a1bd4f
            "NetworkManager",
Packit Service a1bd4f
            argc,
Packit Service a1bd4f
            argv,
Packit Service a1bd4f
            options,
Packit Service a1bd4f
            (void (*)(gpointer, GOptionContext *)) nm_config_cmd_line_options_add_to_entries,
Packit Service a1bd4f
            config_cli,
Packit Service a1bd4f
            _("NetworkManager monitors all network connections and automatically\nchooses the best "
Packit Service a1bd4f
              "connection to use.  It also allows the user to\nspecify wireless access points "
Packit Service a1bd4f
              "which wireless cards in the computer\nshould associate with.")))
Packit Service a1bd4f
        exit(1);
Packit Service a1bd4f
Packit Service a1bd4f
    global_opt.pidfile = global_opt.pidfile ?: g_strdup(NM_DEFAULT_PID_FILE);
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
static gboolean
Packit Service a1bd4f
_dbus_manager_init(NMConfig *config)
Packit 5756e2
{
Packit Service a1bd4f
    NMDBusManager *              busmgr;
Packit Service a1bd4f
    NMConfigConfigureAndQuitType c_a_q_type;
Packit Service a1bd4f
Packit Service a1bd4f
    busmgr = nm_dbus_manager_get();
Packit Service a1bd4f
Packit Service a1bd4f
    c_a_q_type = nm_config_get_configure_and_quit(config);
Packit Service a1bd4f
Packit Service a1bd4f
    if (c_a_q_type == NM_CONFIG_CONFIGURE_AND_QUIT_DISABLED)
Packit Service a1bd4f
        return nm_dbus_manager_acquire_bus(busmgr, TRUE);
Packit Service a1bd4f
Packit Service a1bd4f
    if (c_a_q_type == NM_CONFIG_CONFIGURE_AND_QUIT_ENABLED) {
Packit Service a1bd4f
        /* D-Bus is useless in configure and quit mode -- we're eventually dropping
Packit Service a1bd4f
         * off and potential clients would have no way of knowing whether we're
Packit Service a1bd4f
         * finished already or didn't start yet.
Packit Service a1bd4f
         *
Packit Service a1bd4f
         * But we still create a nm_dbus_manager_get_dbus_connection() D-Bus connection
Packit Service a1bd4f
         * so that we can talk to other services like firewalld. */
Packit Service a1bd4f
        return nm_dbus_manager_acquire_bus(busmgr, FALSE);
Packit Service a1bd4f
    }
Packit Service a1bd4f
Packit Service a1bd4f
    nm_assert(c_a_q_type == NM_CONFIG_CONFIGURE_AND_QUIT_INITRD);
Packit Service a1bd4f
    /* in initrd we don't have D-Bus at all. Don't even try to get the G_BUS_TYPE_SYSTEM
Packit Service a1bd4f
     * connection. And of course don't claim the D-Bus name. */
Packit Service a1bd4f
    return TRUE;
Packit 5756e2
}
Packit 5756e2
Packit 5756e2
/*
Packit 5756e2
 * main
Packit 5756e2
 *
Packit 5756e2
 */
Packit 5756e2
int
Packit Service a1bd4f
main(int argc, char *argv[])
Packit 5756e2
{
Packit Service a1bd4f
    gboolean      success = FALSE;
Packit Service a1bd4f
    NMManager *   manager = NULL;
Packit Service a1bd4f
    NMConfig *    config;
Packit Service a1bd4f
    gs_free_error GError *  error         = NULL;
Packit Service a1bd4f
    gboolean                wrote_pidfile = FALSE;
Packit Service a1bd4f
    char *                  bad_domains   = NULL;
Packit Service a1bd4f
    NMConfigCmdLineOptions *config_cli;
Packit Service a1bd4f
    guint                   sd_id                        = 0;
Packit Service a1bd4f
    GError *                error_invalid_logging_config = NULL;
Packit Service a1bd4f
    const char *const *     warnings;
Packit Service a1bd4f
    int                     errsv;
Packit Service a1bd4f
Packit Service a1bd4f
    /* Known to cause a possible deadlock upon GDBus initialization:
Packit Service a1bd4f
     * https://bugzilla.gnome.org/show_bug.cgi?id=674885 */
Packit Service a1bd4f
    g_type_ensure(G_TYPE_SOCKET);
Packit Service a1bd4f
    g_type_ensure(G_TYPE_DBUS_CONNECTION);
Packit Service a1bd4f
    g_type_ensure(NM_TYPE_DBUS_MANAGER);
Packit Service a1bd4f
Packit Service a1bd4f
    _nm_utils_is_manager_process = TRUE;
Packit Service a1bd4f
Packit Service a1bd4f
    main_loop = g_main_loop_new(NULL, FALSE);
Packit Service a1bd4f
Packit Service a1bd4f
    /* we determine a first-start (contrary to a restart during the same boot)
Packit Service a1bd4f
     * based on the existence of NM_CONFIG_DEVICE_STATE_DIR directory. */
Packit Service a1bd4f
    config_cli = nm_config_cmd_line_options_new(
Packit Service a1bd4f
        !g_file_test(NM_CONFIG_DEVICE_STATE_DIR, G_FILE_TEST_IS_DIR));
Packit Service a1bd4f
Packit Service a1bd4f
    do_early_setup(&argc, &argv, config_cli);
Packit Service a1bd4f
Packit Service a1bd4f
    if (global_opt.g_fatal_warnings)
Packit Service a1bd4f
        _set_g_fatal_warnings();
Packit Service a1bd4f
Packit Service a1bd4f
    if (global_opt.show_version) {
Packit Service a1bd4f
        fprintf(stdout, NM_DIST_VERSION "\n");
Packit Service a1bd4f
        exit(0);
Packit Service a1bd4f
    }
Packit Service a1bd4f
Packit Service a1bd4f
    if (global_opt.print_config) {
Packit Service a1bd4f
        int result;
Packit Service a1bd4f
Packit Service a1bd4f
        result = print_config(config_cli);
Packit Service a1bd4f
        nm_config_cmd_line_options_free(config_cli);
Packit Service a1bd4f
        exit(result);
Packit Service a1bd4f
    }
Packit Service a1bd4f
Packit Service a1bd4f
    nm_main_utils_ensure_root();
Packit Service a1bd4f
Packit Service a1bd4f
    nm_main_utils_ensure_not_running_pidfile(global_opt.pidfile);
Packit Service a1bd4f
Packit Service a1bd4f
    nm_main_utils_ensure_statedir();
Packit Service a1bd4f
    nm_main_utils_ensure_rundir();
Packit Service a1bd4f
Packit Service a1bd4f
    /* When running from the build directory, determine our build directory
Packit Service a1bd4f
     * base and set helper paths in the build tree */
Packit Service a1bd4f
    if (global_opt.run_from_build_dir) {
Packit Service a1bd4f
        char *path, *slash;
Packit Service a1bd4f
        int   g;
Packit Service a1bd4f
Packit Service a1bd4f
        /* exe is <basedir>/src/.libs/lt-NetworkManager, so chop off
Packit Service a1bd4f
         * the last three components */
Packit Service a1bd4f
        path = realpath("/proc/self/exe", NULL);
Packit Service a1bd4f
        g_assert(path != NULL);
Packit Service a1bd4f
        for (g = 0; g < 3; ++g) {
Packit Service a1bd4f
            slash = strrchr(path, '/');
Packit Service a1bd4f
            g_assert(slash != NULL);
Packit Service a1bd4f
            *slash = '\0';
Packit Service a1bd4f
        }
Packit Service a1bd4f
Packit Service a1bd4f
        /* don't free these strings, we need them for the entire
Packit Service a1bd4f
         * process lifetime */
Packit Service a1bd4f
        nm_dhcp_helper_path = g_strdup_printf("%s/src/dhcp/nm-dhcp-helper", path);
Packit Service a1bd4f
Packit Service a1bd4f
        g_free(path);
Packit Service a1bd4f
    }
Packit Service a1bd4f
Packit Service a1bd4f
    if (!nm_logging_setup(global_opt.opt_log_level,
Packit Service a1bd4f
                          global_opt.opt_log_domains,
Packit Service a1bd4f
                          &bad_domains,
Packit Service a1bd4f
                          &error)) {
Packit Service a1bd4f
        fprintf(stderr,
Packit Service a1bd4f
                _("%s.  Please use --help to see a list of valid options.\n"),
Packit Service a1bd4f
                error->message);
Packit Service a1bd4f
        exit(1);
Packit Service a1bd4f
    }
Packit Service a1bd4f
Packit Service a1bd4f
    /* Read the config file and CLI overrides */
Packit Service a1bd4f
    config = nm_config_setup(config_cli, CONFIG_ATOMIC_SECTION_PREFIXES, &error);
Packit Service a1bd4f
    nm_config_cmd_line_options_free(config_cli);
Packit Service a1bd4f
    config_cli = NULL;
Packit Service a1bd4f
    if (config == NULL) {
Packit Service a1bd4f
        fprintf(stderr, _("Failed to read configuration: %s\n"), error->message);
Packit Service a1bd4f
        exit(1);
Packit Service a1bd4f
    }
Packit Service a1bd4f
Packit Service a1bd4f
    _init_nm_debug(config);
Packit Service a1bd4f
Packit Service a1bd4f
    /* Initialize logging from config file *only* if not explicitly
Packit Service a1bd4f
     * specified by commandline.
Packit Service a1bd4f
     */
Packit Service a1bd4f
    if (global_opt.opt_log_level == NULL && global_opt.opt_log_domains == NULL) {
Packit Service a1bd4f
        if (!nm_logging_setup(nm_config_get_log_level(config),
Packit Service a1bd4f
                              nm_config_get_log_domains(config),
Packit Service a1bd4f
                              &bad_domains,
Packit Service a1bd4f
                              &error_invalid_logging_config)) {
Packit Service a1bd4f
            /* ignore error, and print the failure reason below.
Packit Service a1bd4f
             * Likewise, print about bad_domains below. */
Packit Service a1bd4f
        }
Packit Service a1bd4f
    }
Packit Service a1bd4f
Packit Service a1bd4f
    if (global_opt.become_daemon && !nm_config_get_is_debug(config)) {
Packit Service a1bd4f
        if (daemon(0, 0) < 0) {
Packit Service a1bd4f
            errsv = errno;
Packit Service a1bd4f
            fprintf(stderr,
Packit Service a1bd4f
                    _("Could not daemonize: %s [error %u]\n"),
Packit Service a1bd4f
                    nm_strerror_native(errsv),
Packit Service a1bd4f
                    errsv);
Packit Service a1bd4f
            exit(1);
Packit Service a1bd4f
        }
Packit Service a1bd4f
        wrote_pidfile = nm_main_utils_write_pidfile(global_opt.pidfile);
Packit Service a1bd4f
    }
Packit Service a1bd4f
Packit Service a1bd4f
    /* Set up unix signal handling - before creating threads, but after daemonizing! */
Packit Service a1bd4f
    nm_main_utils_setup_signals(main_loop);
Packit Service a1bd4f
Packit Service a1bd4f
    {
Packit Service a1bd4f
        gs_free char *v = NULL;
Packit Service a1bd4f
Packit Service a1bd4f
        v = nm_config_data_get_value(NM_CONFIG_GET_DATA_ORIG,
Packit Service a1bd4f
                                     NM_CONFIG_KEYFILE_GROUP_LOGGING,
Packit Service a1bd4f
                                     NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND,
Packit Service a1bd4f
                                     NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY);
Packit Service a1bd4f
        nm_logging_init(v, nm_config_get_is_debug(config));
Packit Service a1bd4f
    }
Packit Service a1bd4f
Packit Service a1bd4f
    nm_log_info(LOGD_CORE,
Packit Service 8f75d2
                "NetworkManager (version " NM_DIST_VERSION ") is starting... (%s%s)",
Packit Service 8f75d2
                nm_config_get_first_start(config) ? "for the first time" : "after a restart",
Packit Service 8f75d2
                NM_MORE_ASSERTS != 0 ? ", asserts:" G_STRINGIFY(NM_MORE_ASSERTS) : "");
Packit Service a1bd4f
Packit Service a1bd4f
    nm_log_info(LOGD_CORE,
Packit Service a1bd4f
                "Read config: %s",
Packit Service a1bd4f
                nm_config_data_get_config_description(nm_config_get_data(config)));
Packit Service a1bd4f
    nm_config_data_log(nm_config_get_data(config),
Packit Service a1bd4f
                       "CONFIG: ",
Packit Service a1bd4f
                       "  ",
Packit Service a1bd4f
                       nm_config_get_no_auto_default_file(config),
Packit Service a1bd4f
                       NULL);
Packit Service a1bd4f
Packit Service a1bd4f
    if (error_invalid_logging_config) {
Packit Service a1bd4f
        nm_log_warn(LOGD_CORE,
Packit Service a1bd4f
                    "config: invalid logging configuration: %s",
Packit Service a1bd4f
                    error_invalid_logging_config->message);
Packit Service a1bd4f
        g_clear_error(&error_invalid_logging_config);
Packit Service a1bd4f
    }
Packit Service a1bd4f
    if (bad_domains) {
Packit Service a1bd4f
        nm_log_warn(LOGD_CORE,
Packit Service a1bd4f
                    "config: invalid logging domains '%s' from %s",
Packit Service a1bd4f
                    bad_domains,
Packit Service a1bd4f
                    (global_opt.opt_log_level == NULL && global_opt.opt_log_domains == NULL)
Packit Service a1bd4f
                        ? "config file"
Packit Service a1bd4f
                        : "command line");
Packit Service a1bd4f
        nm_clear_g_free(&bad_domains);
Packit Service a1bd4f
    }
Packit Service a1bd4f
Packit Service a1bd4f
    warnings = nm_config_get_warnings(config);
Packit Service a1bd4f
    for (; warnings && *warnings; warnings++)
Packit Service a1bd4f
        nm_log_warn(LOGD_CORE, "config: %s", *warnings);
Packit Service a1bd4f
    nm_config_clear_warnings(config);
Packit Service a1bd4f
Packit Service a1bd4f
    /* the first access to State causes the file to be read (and possibly print a warning) */
Packit Service a1bd4f
    nm_config_state_get(config);
Packit Service a1bd4f
Packit Service a1bd4f
    nm_log_dbg(LOGD_CORE,
Packit Service a1bd4f
               "WEXT support is %s",
Packit 5756e2
#if HAVE_WEXT
Packit Service a1bd4f
               "enabled"
Packit 5756e2
#else
Packit Service a1bd4f
               "disabled"
Packit 5756e2
#endif
Packit Service a1bd4f
    );
Packit 5756e2
Packit Service a1bd4f
    if (!_dbus_manager_init(config))
Packit Service a1bd4f
        goto done_no_manager;
Packit 5756e2
Packit Service a1bd4f
    nm_linux_platform_setup();
Packit 5756e2
Packit Service a1bd4f
    NM_UTILS_KEEP_ALIVE(config, nm_netns_get(), "NMConfig-depends-on-NMNetns");
Packit 5756e2
Packit Service a1bd4f
    nm_auth_manager_setup(nm_config_data_get_main_auth_polkit(nm_config_get_data_orig(config)));
Packit 5756e2
Packit Service a1bd4f
    manager = nm_manager_setup();
Packit 5756e2
Packit Service a1bd4f
    nm_dbus_manager_start(nm_dbus_manager_get(), nm_manager_dbus_set_property_handle, manager);
Packit 5756e2
Packit Service a1bd4f
    g_signal_connect(manager,
Packit Service a1bd4f
                     NM_MANAGER_CONFIGURE_QUIT,
Packit Service a1bd4f
                     G_CALLBACK(manager_configure_quit),
Packit Service a1bd4f
                     config);
Packit 5756e2
Packit Service a1bd4f
    if (!nm_manager_start(manager, &error)) {
Packit Service a1bd4f
        nm_log_err(LOGD_CORE, "failed to initialize: %s", error->message);
Packit Service a1bd4f
        goto done;
Packit Service a1bd4f
    }
Packit 5756e2
Packit Service a1bd4f
    nm_platform_process_events(NM_PLATFORM_GET);
Packit 5756e2
Packit Service a1bd4f
    /* Make sure the loopback interface is up. If interface is down, we bring
Packit Service a1bd4f
     * it up and kernel will assign it link-local IPv4 and IPv6 addresses. If
Packit Service a1bd4f
     * it was already up, we assume is in clean state.
Packit Service a1bd4f
     *
Packit Service a1bd4f
     * TODO: it might be desirable to check the list of addresses and compare
Packit Service a1bd4f
     * it with a list of expected addresses (one of the protocol families
Packit Service a1bd4f
     * could be disabled). The 'lo' interface is sometimes used for assigning
Packit Service a1bd4f
     * global addresses so their availability doesn't depend on the state of
Packit Service a1bd4f
     * physical interfaces.
Packit Service a1bd4f
     */
Packit Service a1bd4f
    nm_log_dbg(LOGD_CORE, "setting up local loopback");
Packit Service a1bd4f
    nm_platform_link_set_up(NM_PLATFORM_GET, 1, NULL);
Packit 5756e2
Packit Service a1bd4f
    success = TRUE;
Packit 5756e2
Packit Service a1bd4f
    if (configure_and_quit == FALSE) {
Packit Service a1bd4f
        sd_id = nm_sd_event_attach_default();
Packit 5756e2
Packit Service a1bd4f
        g_main_loop_run(main_loop);
Packit Service a1bd4f
    }
Packit 5756e2
Packit 5756e2
done:
Packit 5756e2
Packit Service a1bd4f
    /* write the device-state to file. Note that we only persist the
Packit Service a1bd4f
     * state here. We don't bother updating the state as devices
Packit Service a1bd4f
     * change during regular operation. If NM is killed with SIGKILL,
Packit Service a1bd4f
     * it misses to update the state. */
Packit Service a1bd4f
    nm_manager_write_device_state_all(manager);
Packit 5756e2
Packit Service a1bd4f
    nm_manager_stop(manager);
Packit 5756e2
Packit Service a1bd4f
    nm_config_state_set(config, TRUE, TRUE);
Packit 5756e2
Packit Service a1bd4f
    nm_dns_manager_stop(nm_dns_manager_get());
Packit 5756e2
Packit Service a1bd4f
    nm_settings_kf_db_write(NM_SETTINGS_GET);
Packit 5756e2
Packit 5756e2
done_no_manager:
Packit Service a1bd4f
    if (global_opt.pidfile && wrote_pidfile)
Packit Service a1bd4f
        unlink(global_opt.pidfile);
Packit 5756e2
Packit Service a1bd4f
    nm_log_info(LOGD_CORE, "exiting (%s)", success ? "success" : "error");
Packit 5756e2
Packit Service a1bd4f
    nm_clear_g_source(&sd_id);
Packit 5756e2
Packit Service a1bd4f
    exit(success ? 0 : 1);
Packit 5756e2
}