merge: branch 'ff/down_on_shutdown'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1858
This commit is contained in:
Fernando Fernandez Mancera 2024-03-05 11:42:21 +01:00
commit d3086e8c79
23 changed files with 978 additions and 721 deletions

View file

@ -2813,8 +2813,8 @@ src_core_libNetworkManager_la_SOURCES = \
src/core/nm-priv-helper-call.h \
src/core/nm-keep-alive.c \
src/core/nm-keep-alive.h \
src/core/nm-sleep-monitor.c \
src/core/nm-sleep-monitor.h \
src/core/nm-power-monitor.c \
src/core/nm-power-monitor.h \
src/core/nm-types.h \
\
$(NULL)

View file

@ -510,7 +510,7 @@ fi
session_tracking="$(printf '%s' "${session_tracking}" | sed 's/^, //')"
AC_ARG_WITH(suspend-resume,
AS_HELP_STRING([--with-suspend-resume=upower|systemd|elogind|consolekit],
AS_HELP_STRING([--with-suspend-resume=systemd|elogind|consolekit],
[Build NetworkManager with specific suspend/resume support]))
if test "z$with_suspend_resume" = "z"; then
PKG_CHECK_EXISTS([libsystemd >= 209], [have_systemd_inhibit=yes],
@ -525,21 +525,13 @@ if test "z$with_suspend_resume" = "z"; then
# Use elogind if it's new enough
with_suspend_resume="elogind"
else
if test "$use_consolekit" = "yes"; then
# Use consolekit suspend if session tracking is consolekit
with_suspend_resume="consolekit"
else
# Fall back to upower
with_suspend_resume="upower"
fi
# Fallback to consolekit
with_suspend_resume="consolekit"
fi
fi
fi
case $with_suspend_resume in
upower)
AC_DEFINE([SUSPEND_RESUME_UPOWER], 1, [Define to 1 to use UPower suspend api])
;;
systemd)
PKG_CHECK_MODULES(SYSTEMD_INHIBIT, [libsystemd >= 209],,
[PKG_CHECK_MODULES(SYSTEMD_INHIBIT, [libsystemd-login >= 183])])
@ -554,7 +546,7 @@ case $with_suspend_resume in
AC_DEFINE([SUSPEND_RESUME_CONSOLEKIT], 1, [Define to 1 to use ConsoleKit2 suspend api])
;;
*)
AC_MSG_ERROR(--with-suspend-resume must be one of [upower, systemd, elogind, consolekit])
AC_MSG_ERROR(--with-suspend-resume must be one of [systemd, elogind, consolekit])
;;
esac

View file

@ -160,7 +160,7 @@ The diagram shows other objects on the right side:
- *SleepMonitor*: gets notifications for sleep and wake events by
registering to the available subsystem provided by the distro such
as systemd-logind, upower or ConsoleKit.
as systemd-logind or ConsoleKit.
- *SessionMonitor*: tracks which users have an active session by
using systemd-logind, elogind or ConsoleKit.

View file

@ -860,6 +860,10 @@ ipv6.ip6-privacy=0
<varlistentry>
<term><varname>connection.autoconnect-slaves</varname></term>
</varlistentry>
<varlistentry>
<term><varname>connection.down-on-poweroff</varname></term>
<listitem><para>Whether the connection will be brought down before the system is powered off.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>connection.mud-url</varname></term>
<listitem><para>If unspecified, MUD URL defaults to <literal>"none"</literal>.</para></listitem>

View file

@ -427,10 +427,8 @@ if suspend_resume == 'auto'
suspend_resume = 'systemd'
elif libelogind_dep.found()
suspend_resume = 'elogind'
elif session_tracking_consolekit
suspend_resume = 'consolekit'
else
suspend_resume = 'upower'
suspend_resume = 'consolekit'
endif
endif
@ -449,8 +447,6 @@ elif suspend_resume == 'elogind'
config_h.set('SUSPEND_RESUME_ELOGIND', true)
elif suspend_resume == 'consolekit'
config_h.set('SUSPEND_RESUME_CONSOLEKIT', true)
elif suspend_resume == 'upower'
config_h.set('SUSPEND_RESUME_UPOWER', true)
else
error('bug')
endif

View file

@ -13,7 +13,7 @@ option('modprobe', type: 'string', value: '', description: 'path to modprobe')
option('dist_version', type: 'string', value: '', description: 'Define the NM\'s distribution version string')
option('session_tracking_consolekit', type: 'boolean', value: true, description: 'Support consolekit session tracking')
option('session_tracking', type: 'combo', choices: ['systemd', 'elogind', 'no'], value: 'systemd', description: 'Compatibility option to choose one session tracking module')
option('suspend_resume', type: 'combo', choices: ['upower', 'systemd', 'elogind', 'consolekit', 'auto'], value: 'auto', description: 'Build NetworkManager with specific suspend/resume support')
option('suspend_resume', type: 'combo', choices: ['systemd', 'elogind', 'consolekit', 'auto'], value: 'auto', description: 'Build NetworkManager with specific suspend/resume support')
option('polkit', type: 'boolean', value: true, description: 'User auth-polkit configuration option.')
option('config_auth_polkit_default', type: 'combo', choices: ['default', 'true', 'false', 'root-only'], value: 'default', description: 'Default value for configuration main.auth-polkit.')
option('modify_system', type: 'boolean', value: false, description: 'Allow users to modify system connections')

View file

@ -171,7 +171,7 @@ libNetworkManager = static_library(
'nm-policy.c',
'nm-rfkill-manager.c',
'nm-session-monitor.c',
'nm-sleep-monitor.c',
'nm-power-monitor.c',
'nm-priv-helper-call.c',
),
dependencies: nm_deps,

View file

@ -46,7 +46,7 @@
#include "nm-priv-helper-call.h"
#include "nm-rfkill-manager.h"
#include "nm-session-monitor.h"
#include "nm-sleep-monitor.h"
#include "nm-power-monitor.h"
#include "settings/nm-settings-connection.h"
#include "settings/nm-settings.h"
#include "vpn/nm-vpn-manager.h"
@ -214,7 +214,7 @@ typedef struct {
NMVpnManager *vpn_manager;
NMSleepMonitor *sleep_monitor;
NMPowerMonitor *power_monitor;
NMAuthManager *auth_mgr;
@ -7128,7 +7128,7 @@ static gboolean
sleep_devices_add(NMManager *self, NMDevice *device, gboolean suspending)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self);
NMSleepMonitorInhibitorHandle *handle = NULL;
NMPowerMonitorInhibitorHandle *handle = NULL;
if (g_hash_table_lookup_extended(priv->sleep_devices, device, NULL, (gpointer *) &handle)) {
if (suspending) {
@ -7136,16 +7136,16 @@ sleep_devices_add(NMManager *self, NMDevice *device, gboolean suspending)
* Even if we had an old handle, it might be stale by now. */
g_hash_table_insert(priv->sleep_devices,
device,
nm_sleep_monitor_inhibit_take(priv->sleep_monitor));
nm_power_monitor_inhibit_take(priv->power_monitor));
if (handle)
nm_sleep_monitor_inhibit_release(priv->sleep_monitor, handle);
nm_power_monitor_inhibit_release(priv->power_monitor, handle);
}
return FALSE;
}
g_hash_table_insert(priv->sleep_devices,
g_object_ref(device),
suspending ? nm_sleep_monitor_inhibit_take(priv->sleep_monitor) : NULL);
suspending ? nm_power_monitor_inhibit_take(priv->power_monitor) : NULL);
g_signal_connect(device, "notify::" NM_DEVICE_STATE, G_CALLBACK(device_sleep_cb), self);
return TRUE;
}
@ -7154,13 +7154,13 @@ static gboolean
sleep_devices_remove(NMManager *self, NMDevice *device)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self);
NMSleepMonitorInhibitorHandle *handle;
NMPowerMonitorInhibitorHandle *handle;
if (!g_hash_table_lookup_extended(priv->sleep_devices, device, NULL, (gpointer *) &handle))
return FALSE;
if (handle)
nm_sleep_monitor_inhibit_release(priv->sleep_monitor, handle);
nm_power_monitor_inhibit_release(priv->power_monitor, handle);
/* Remove device from hash */
g_signal_handlers_disconnect_by_func(device, device_sleep_cb, self);
@ -7177,14 +7177,14 @@ sleep_devices_clear(NMManager *self)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self);
NMDevice *device;
NMSleepMonitorInhibitorHandle *handle;
NMPowerMonitorInhibitorHandle *handle;
GHashTableIter iter;
g_hash_table_iter_init(&iter, priv->sleep_devices);
while (g_hash_table_iter_next(&iter, (gpointer *) &device, (gpointer *) &handle)) {
g_signal_handlers_disconnect_by_func(device, device_sleep_cb, self);
if (handle)
nm_sleep_monitor_inhibit_release(priv->sleep_monitor, handle);
nm_power_monitor_inhibit_release(priv->power_monitor, handle);
g_object_unref(device);
g_hash_table_iter_remove(&iter);
}
@ -7215,6 +7215,33 @@ device_sleep_cb(NMDevice *device, GParamSpec *pspec, NMManager *self)
}
}
static void
_handle_device_takedown(NMManager *self,
NMDevice *device,
gboolean suspending,
gboolean is_shutdown)
{
nm_device_notify_sleeping(device);
if (nm_device_is_activating(device)
|| nm_device_get_state(device) == NM_DEVICE_STATE_ACTIVATED) {
_LOGD(LOGD_SUSPEND,
"%s: wait disconnection of device %s",
is_shutdown ? "shutdown" : "sleep",
nm_device_get_ip_iface(device));
if (sleep_devices_add(self, device, suspending))
nm_device_queue_state(device,
NM_DEVICE_STATE_DEACTIVATING,
NM_DEVICE_STATE_REASON_SLEEPING);
} else {
nm_device_set_unmanaged_by_flags(device,
NM_UNMANAGED_SLEEPING,
NM_UNMAN_FLAG_OP_SET_UNMANAGED,
NM_DEVICE_STATE_REASON_SLEEPING);
}
}
static void
do_sleep_wake(NMManager *self, gboolean sleeping_changed)
{
@ -7249,24 +7276,7 @@ do_sleep_wake(NMManager *self, gboolean sleeping_changed)
continue;
}
nm_device_notify_sleeping(device);
if (nm_device_is_activating(device)
|| nm_device_get_state(device) == NM_DEVICE_STATE_ACTIVATED) {
_LOGD(LOGD_SUSPEND,
"sleep: wait disconnection of device %s",
nm_device_get_ip_iface(device));
if (sleep_devices_add(self, device, suspending))
nm_device_queue_state(device,
NM_DEVICE_STATE_DEACTIVATING,
NM_DEVICE_STATE_REASON_SLEEPING);
} else {
nm_device_set_unmanaged_by_flags(device,
NM_UNMANAGED_SLEEPING,
NM_UNMAN_FLAG_OP_SET_UNMANAGED,
NM_DEVICE_STATE_REASON_SLEEPING);
}
_handle_device_takedown(self, device, suspending, FALSE);
}
} else {
_LOGD(LOGD_SUSPEND, "sleep: %s...", waking_from_suspend ? "waking up" : "re-enabling");
@ -7438,7 +7448,7 @@ impl_manager_sleep(NMDBusObject *obj,
}
static void
sleeping_cb(NMSleepMonitor *monitor, gboolean is_about_to_suspend, gpointer user_data)
sleeping_cb(NMPowerMonitor *monitor, gboolean is_about_to_suspend, gpointer user_data)
{
NMManager *self = user_data;
@ -7446,6 +7456,41 @@ sleeping_cb(NMSleepMonitor *monitor, gboolean is_about_to_suspend, gpointer user
_internal_sleep(self, is_about_to_suspend);
}
static void
shutdown_cb(NMPowerMonitor *monitor, gpointer user_data)
{
NMManager *self = user_data;
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self);
NMDevice *device;
_LOGT(LOGD_SUSPEND, "shutdown: received shutdown signal");
c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
NMSettingConnection *s_con;
gboolean take_down = FALSE;
s_con = nm_device_get_applied_setting(device, NM_META_SETTING_TYPE_CONNECTION);
if (!s_con)
continue;
if (nm_setting_connection_get_down_on_poweroff(s_con)
== NM_SETTING_CONNECTION_DOWN_ON_POWEROFF_YES)
take_down = TRUE;
else if (nm_setting_connection_get_down_on_poweroff(s_con)
== NM_SETTING_CONNECTION_DOWN_ON_POWEROFF_DEFAULT)
take_down = nm_config_data_get_connection_default_int64(
NM_CONFIG_GET_DATA,
NM_CON_DEFAULT("connection.down-on-poweroff"),
device,
NM_SETTING_CONNECTION_DOWN_ON_POWEROFF_NO,
NM_SETTING_CONNECTION_DOWN_ON_POWEROFF_YES,
NM_SETTING_CONNECTION_DOWN_ON_POWEROFF_NO);
if (take_down)
_handle_device_takedown(self, device, FALSE, TRUE);
}
}
static void
_internal_enable(NMManager *self, gboolean enable)
{
@ -8834,8 +8879,9 @@ nm_manager_init(NMManager *self)
priv->devcon_data_dict = g_hash_table_new(_devcon_data_hash, _devcon_data_equal);
/* sleep/wake handling */
priv->sleep_monitor = nm_sleep_monitor_new();
g_signal_connect(priv->sleep_monitor, NM_SLEEP_MONITOR_SLEEPING, G_CALLBACK(sleeping_cb), self);
priv->power_monitor = nm_power_monitor_new();
g_signal_connect(priv->power_monitor, NM_POWER_MONITOR_SLEEPING, G_CALLBACK(sleeping_cb), self);
g_signal_connect(priv->power_monitor, NM_POWER_MONITOR_SHUTDOWN, G_CALLBACK(shutdown_cb), self);
/* Listen for authorization changes */
priv->auth_mgr = g_object_ref(nm_auth_manager_get());
@ -9134,9 +9180,9 @@ dispose(GObject *object)
nm_clear_pointer(&priv->sleep_devices, g_hash_table_unref);
}
if (priv->sleep_monitor) {
g_signal_handlers_disconnect_by_func(priv->sleep_monitor, sleeping_cb, self);
g_clear_object(&priv->sleep_monitor);
if (priv->power_monitor) {
g_signal_handlers_disconnect_by_func(priv->power_monitor, sleeping_cb, self);
g_clear_object(&priv->power_monitor);
}
if (priv->fw_monitor) {

View file

@ -6,7 +6,7 @@
#include "src/core/nm-default-daemon.h"
#include "nm-sleep-monitor.h"
#include "nm-power-monitor.h"
#include <sys/stat.h>
#include <gio/gunixfdlist.h>
@ -15,24 +15,15 @@
#include "libnm-core-intern/nm-core-internal.h"
#include "NetworkManagerUtils.h"
#if defined(SUSPEND_RESUME_UPOWER)
#define SUSPEND_DBUS_NAME "org.freedesktop.UPower"
#define SUSPEND_DBUS_PATH "/org/freedesktop/UPower"
#define SUSPEND_DBUS_INTERFACE "org.freedesktop.UPower"
#define USE_UPOWER 1
#define _NMLOG_PREFIX_NAME "sleep-monitor-up"
#elif defined(SUSPEND_RESUME_SYSTEMD) || defined(SUSPEND_RESUME_ELOGIND)
#if defined(SUSPEND_RESUME_SYSTEMD) || defined(SUSPEND_RESUME_ELOGIND)
#define SUSPEND_DBUS_NAME "org.freedesktop.login1"
#define SUSPEND_DBUS_PATH "/org/freedesktop/login1"
#define SUSPEND_DBUS_INTERFACE "org.freedesktop.login1.Manager"
#define USE_UPOWER 0
#if defined(SUSPEND_RESUME_SYSTEMD)
#define _NMLOG_PREFIX_NAME "sleep-monitor-sd"
#define _NMLOG_PREFIX_NAME "power-monitor-sd"
#else
#define _NMLOG_PREFIX_NAME "sleep-monitor-el"
#define _NMLOG_PREFIX_NAME "power-monitor-el"
#endif
#elif defined(SUSPEND_RESUME_CONSOLEKIT)
@ -44,12 +35,11 @@
#define SUSPEND_DBUS_NAME "org.freedesktop.ConsoleKit"
#define SUSPEND_DBUS_PATH "/org/freedesktop/ConsoleKit/Manager"
#define SUSPEND_DBUS_INTERFACE "org.freedesktop.ConsoleKit.Manager"
#define USE_UPOWER 0
#define _NMLOG_PREFIX_NAME "sleep-monitor-ck"
#define _NMLOG_PREFIX_NAME "power-monitor-ck"
#else
#error define one of SUSPEND_RESUME_SYSTEMD, SUSPEND_RESUME_ELOGIND, SUSPEND_RESUME_CONSOLEKIT, or SUSPEND_RESUME_UPOWER
#error define one of SUSPEND_RESUME_SYSTEMD, SUSPEND_RESUME_ELOGIND, SUSPEND_RESUME_CONSOLEKIT
#endif
@ -57,12 +47,13 @@
enum {
SLEEPING,
SHUTDOWN,
LAST_SIGNAL,
};
static guint signals[LAST_SIGNAL] = {0};
struct _NMSleepMonitor {
struct _NMPowerMonitor {
GObject parent;
GDBusProxy *proxy;
@ -76,13 +67,14 @@ struct _NMSleepMonitor {
gulong sig_id_1;
gulong sig_id_2;
gulong sig_id_3;
};
struct _NMSleepMonitorClass {
struct _NMPowerMonitorClass {
GObjectClass parent;
};
G_DEFINE_TYPE(NMSleepMonitor, nm_sleep_monitor, G_TYPE_OBJECT);
G_DEFINE_TYPE(NMPowerMonitor, nm_power_monitor, G_TYPE_OBJECT);
/*****************************************************************************/
@ -91,28 +83,14 @@ G_DEFINE_TYPE(NMSleepMonitor, nm_sleep_monitor, G_TYPE_OBJECT);
/*****************************************************************************/
static void sleep_signal(NMSleepMonitor *self, gboolean is_about_to_suspend);
static void sleep_signal(NMPowerMonitor *self, gboolean is_about_to_suspend);
static void shutdown_signal(NMPowerMonitor *self);
/*****************************************************************************/
#if USE_UPOWER
static void
upower_sleeping_cb(GDBusProxy *proxy, gpointer user_data)
{
sleep_signal(user_data, TRUE);
}
static void
upower_resuming_cb(GDBusProxy *proxy, gpointer user_data)
{
sleep_signal(user_data, FALSE);
}
#else /* USE_UPOWER */
static void
drop_inhibitor(NMSleepMonitor *self, gboolean force)
drop_inhibitor(NMPowerMonitor *self, gboolean force)
{
if (!force && self->handles_active)
return;
@ -135,7 +113,7 @@ static void
inhibit_done(GObject *source, GAsyncResult *result, gpointer user_data)
{
GDBusProxy *proxy = G_DBUS_PROXY(source);
NMSleepMonitor *self = user_data;
NMPowerMonitor *self = user_data;
gs_free_error GError *error = NULL;
gs_unref_variant GVariant *res = NULL;
gs_unref_object GUnixFDList *fd_list = NULL;
@ -161,9 +139,9 @@ inhibit_done(GObject *source, GAsyncResult *result, gpointer user_data)
}
static void
take_inhibitor(NMSleepMonitor *self)
take_inhibitor(NMPowerMonitor *self)
{
g_return_if_fail(NM_IS_SLEEP_MONITOR(self));
g_return_if_fail(NM_IS_POWER_MONITOR(self));
g_return_if_fail(G_IS_DBUS_PROXY(self->proxy));
drop_inhibitor(self, TRUE);
@ -191,11 +169,17 @@ prepare_for_sleep_cb(GDBusProxy *proxy, gboolean is_about_to_suspend, gpointer d
sleep_signal(data, is_about_to_suspend);
}
static void
prepare_for_shutdown_cb(GDBusProxy *proxy, gpointer data)
{
shutdown_signal(data);
}
static void
name_owner_cb(GObject *object, GParamSpec *pspec, gpointer user_data)
{
GDBusProxy *proxy = G_DBUS_PROXY(object);
NMSleepMonitor *self = NM_SLEEP_MONITOR(user_data);
NMPowerMonitor *self = NM_POWER_MONITOR(user_data);
char *owner;
g_assert(proxy == self->proxy);
@ -207,59 +191,64 @@ name_owner_cb(GObject *object, GParamSpec *pspec, gpointer user_data)
drop_inhibitor(self, TRUE);
g_free(owner);
}
#endif /* USE_UPOWER */
static void
sleep_signal(NMSleepMonitor *self, gboolean is_about_to_suspend)
sleep_signal(NMPowerMonitor *self, gboolean is_about_to_suspend)
{
g_return_if_fail(NM_IS_SLEEP_MONITOR(self));
g_return_if_fail(NM_IS_POWER_MONITOR(self));
_LOGD("received %s signal", is_about_to_suspend ? "SLEEP" : "RESUME");
#if !USE_UPOWER
if (!is_about_to_suspend)
take_inhibitor(self);
#endif
g_signal_emit(self, signals[SLEEPING], 0, is_about_to_suspend);
#if !USE_UPOWER
if (is_about_to_suspend)
drop_inhibitor(self, FALSE);
#endif
}
static void
shutdown_signal(NMPowerMonitor *self)
{
g_return_if_fail(NM_IS_POWER_MONITOR(self));
_LOGD("received SHUTDOWN signal");
g_signal_emit(self, signals[SHUTDOWN], 0);
}
/**
* nm_sleep_monitor_inhibit_take:
* @self: the #NMSleepMonitor instance
* nm_power_monitor_inhibit_take:
* @self: the #NMPowerMonitor instance
*
* Prevent the release of inhibitor lock
*
* Returns: an inhibitor handle that must be returned via
* nm_sleep_monitor_inhibit_release().
* nm_power_monitor_inhibit_release().
**/
NMSleepMonitorInhibitorHandle *
nm_sleep_monitor_inhibit_take(NMSleepMonitor *self)
NMPowerMonitorInhibitorHandle *
nm_power_monitor_inhibit_take(NMPowerMonitor *self)
{
g_return_val_if_fail(NM_IS_SLEEP_MONITOR(self), NULL);
g_return_val_if_fail(NM_IS_POWER_MONITOR(self), NULL);
self->handles_active = g_slist_prepend(self->handles_active, NULL);
return (NMSleepMonitorInhibitorHandle *) self->handles_active;
return (NMPowerMonitorInhibitorHandle *) self->handles_active;
}
/**
* nm_sleep_monitor_inhibit_release:
* @self: the #NMSleepMonitor instance
* @handle: the #NMSleepMonitorInhibitorHandle inhibitor handle.
* nm_power_monitor_inhibit_release:
* @self: the #NMPowerMonitor instance
* @handle: the #NMPowerMonitorInhibitorHandle inhibitor handle.
*
* Allow again the release of inhibitor lock
**/
void
nm_sleep_monitor_inhibit_release(NMSleepMonitor *self, NMSleepMonitorInhibitorHandle *handle)
nm_power_monitor_inhibit_release(NMPowerMonitor *self, NMPowerMonitorInhibitorHandle *handle)
{
GSList *l;
g_return_if_fail(NM_IS_SLEEP_MONITOR(self));
g_return_if_fail(NM_IS_POWER_MONITOR(self));
g_return_if_fail(handle);
l = (GSList *) handle;
@ -273,13 +262,11 @@ nm_sleep_monitor_inhibit_release(NMSleepMonitor *self, NMSleepMonitorInhibitorHa
self->handles_active = g_slist_delete_link(self->handles_active, l);
#if !USE_UPOWER
drop_inhibitor(self, FALSE);
#endif
}
static void
on_proxy_acquired(GObject *object, GAsyncResult *res, NMSleepMonitor *self)
on_proxy_acquired(GObject *object, GAsyncResult *res, NMPowerMonitor *self)
{
GError *error = NULL;
GDBusProxy *proxy;
@ -294,18 +281,6 @@ on_proxy_acquired(GObject *object, GAsyncResult *res, NMSleepMonitor *self)
self->proxy = proxy;
g_clear_object(&self->cancellable);
#if USE_UPOWER
self->sig_id_1 = _nm_dbus_proxy_signal_connect(self->proxy,
"Sleeping",
NULL,
G_CALLBACK(upower_sleeping_cb),
self);
self->sig_id_2 = _nm_dbus_proxy_signal_connect(self->proxy,
"Resuming",
NULL,
G_CALLBACK(upower_resuming_cb),
self);
#else
self->sig_id_1 =
g_signal_connect(self->proxy, "notify::g-name-owner", G_CALLBACK(name_owner_cb), self);
self->sig_id_2 = _nm_dbus_proxy_signal_connect(self->proxy,
@ -313,6 +288,12 @@ on_proxy_acquired(GObject *object, GAsyncResult *res, NMSleepMonitor *self)
G_VARIANT_TYPE("(b)"),
G_CALLBACK(prepare_for_sleep_cb),
self);
self->sig_id_3 = _nm_dbus_proxy_signal_connect(self->proxy,
"PrepareForShutdown",
G_VARIANT_TYPE("(b)"),
G_CALLBACK(prepare_for_shutdown_cb),
self);
{
gs_free char *owner = NULL;
@ -320,13 +301,12 @@ on_proxy_acquired(GObject *object, GAsyncResult *res, NMSleepMonitor *self)
if (owner)
take_inhibitor(self);
}
#endif
}
/*****************************************************************************/
static void
nm_sleep_monitor_init(NMSleepMonitor *self)
nm_power_monitor_init(NMPowerMonitor *self)
{
self->inhibit_fd = -1;
self->cancellable = g_cancellable_new();
@ -342,34 +322,33 @@ nm_sleep_monitor_init(NMSleepMonitor *self)
self);
}
NMSleepMonitor *
nm_sleep_monitor_new(void)
NMPowerMonitor *
nm_power_monitor_new(void)
{
return g_object_new(NM_TYPE_SLEEP_MONITOR, NULL);
return g_object_new(NM_TYPE_POWER_MONITOR, NULL);
}
static void
dispose(GObject *object)
{
NMSleepMonitor *self = NM_SLEEP_MONITOR(object);
NMPowerMonitor *self = NM_POWER_MONITOR(object);
#if !USE_UPOWER
drop_inhibitor(self, TRUE);
#endif
nm_clear_g_cancellable(&self->cancellable);
if (self->proxy) {
nm_clear_g_signal_handler(self->proxy, &self->sig_id_1);
nm_clear_g_signal_handler(self->proxy, &self->sig_id_2);
nm_clear_g_signal_handler(self->proxy, &self->sig_id_3);
g_clear_object(&self->proxy);
}
G_OBJECT_CLASS(nm_sleep_monitor_parent_class)->dispose(object);
G_OBJECT_CLASS(nm_power_monitor_parent_class)->dispose(object);
}
static void
nm_sleep_monitor_class_init(NMSleepMonitorClass *klass)
nm_power_monitor_class_init(NMPowerMonitorClass *klass)
{
GObjectClass *gobject_class;
@ -377,8 +356,18 @@ nm_sleep_monitor_class_init(NMSleepMonitorClass *klass)
gobject_class->dispose = dispose;
signals[SLEEPING] = g_signal_new(NM_SLEEP_MONITOR_SLEEPING,
NM_TYPE_SLEEP_MONITOR,
signals[SLEEPING] = g_signal_new(NM_POWER_MONITOR_SLEEPING,
NM_TYPE_POWER_MONITOR,
G_SIGNAL_RUN_LAST,
0,
NULL,
NULL,
g_cclosure_marshal_VOID__BOOLEAN,
G_TYPE_NONE,
1,
G_TYPE_BOOLEAN);
signals[SHUTDOWN] = g_signal_new(NM_POWER_MONITOR_SHUTDOWN,
NM_TYPE_POWER_MONITOR,
G_SIGNAL_RUN_LAST,
0,
NULL,

View file

@ -0,0 +1,34 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2012 - 2016 Red Hat, Inc.
* Author: Matthias Clasen <mclasen@redhat.com>
*/
#ifndef __NETWORKMANAGER_POWER_MONITOR_H__
#define __NETWORKMANAGER_POWER_MONITOR_H__
#define NM_TYPE_POWER_MONITOR (nm_power_monitor_get_type())
#define NM_POWER_MONITOR(o) \
(_NM_G_TYPE_CHECK_INSTANCE_CAST((o), NM_TYPE_POWER_MONITOR, NMPowerMonitor))
#define NM_POWER_MONITOR_CLASS(k) \
(G_TYPE_CHECK_CLASS_CAST((k), NM_TYPE_POWER_MONITOR, NMPowerMonitorClass))
#define NM_POWER_MONITOR_GET_CLASS(o) \
(G_TYPE_INSTANCE_GET_CLASS((o), NM_TYPE_POWER_MONITOR, NMPowerMonitorClass))
#define NM_IS_POWER_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), NM_TYPE_POWER_MONITOR))
#define NM_IS_POWER_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), NM_TYPE_POWER_MONITOR))
#define NM_POWER_MONITOR_SLEEPING "sleeping"
#define NM_POWER_MONITOR_SHUTDOWN "shutdown"
typedef struct _NMPowerMonitorClass NMPowerMonitorClass;
GType nm_power_monitor_get_type(void) G_GNUC_CONST;
NMPowerMonitor *nm_power_monitor_new(void);
typedef struct _NMPowerMonitorInhibitorHandle NMPowerMonitorInhibitorHandle;
NMPowerMonitorInhibitorHandle *nm_power_monitor_inhibit_take(NMPowerMonitor *self);
void nm_power_monitor_inhibit_release(NMPowerMonitor *self, NMPowerMonitorInhibitorHandle *handle);
#endif /* __NETWORKMANAGER_POWER_MONITOR_H__ */

View file

@ -1,33 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2012 - 2016 Red Hat, Inc.
* Author: Matthias Clasen <mclasen@redhat.com>
*/
#ifndef __NETWORKMANAGER_SLEEP_MONITOR_H__
#define __NETWORKMANAGER_SLEEP_MONITOR_H__
#define NM_TYPE_SLEEP_MONITOR (nm_sleep_monitor_get_type())
#define NM_SLEEP_MONITOR(o) \
(_NM_G_TYPE_CHECK_INSTANCE_CAST((o), NM_TYPE_SLEEP_MONITOR, NMSleepMonitor))
#define NM_SLEEP_MONITOR_CLASS(k) \
(G_TYPE_CHECK_CLASS_CAST((k), NM_TYPE_SLEEP_MONITOR, NMSleepMonitorClass))
#define NM_SLEEP_MONITOR_GET_CLASS(o) \
(G_TYPE_INSTANCE_GET_CLASS((o), NM_TYPE_SLEEP_MONITOR, NMSleepMonitorClass))
#define NM_IS_SLEEP_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), NM_TYPE_SLEEP_MONITOR))
#define NM_IS_SLEEP_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), NM_TYPE_SLEEP_MONITOR))
#define NM_SLEEP_MONITOR_SLEEPING "sleeping"
typedef struct _NMSleepMonitorClass NMSleepMonitorClass;
GType nm_sleep_monitor_get_type(void) G_GNUC_CONST;
NMSleepMonitor *nm_sleep_monitor_new(void);
typedef struct _NMSleepMonitorInhibitorHandle NMSleepMonitorInhibitorHandle;
NMSleepMonitorInhibitorHandle *nm_sleep_monitor_inhibit_take(NMSleepMonitor *self);
void nm_sleep_monitor_inhibit_release(NMSleepMonitor *self, NMSleepMonitorInhibitorHandle *handle);
#endif /* __NETWORKMANAGER_SLEEP_MONITOR_H__ */

View file

@ -33,7 +33,7 @@ typedef struct _NMRfkillManager NMRfkillManager;
typedef struct _NMPacrunnerManager NMPacrunnerManager;
typedef struct _NMSessionMonitor NMSessionMonitor;
typedef struct _NMKeepAlive NMKeepAlive;
typedef struct _NMSleepMonitor NMSleepMonitor;
typedef struct _NMPowerMonitor NMPowerMonitor;
typedef struct _NMLldpListener NMLldpListener;
typedef struct _NMConfigDeviceStateData NMConfigDeviceStateData;

View file

@ -1958,6 +1958,7 @@ global:
nm_ethtool_optname_is_eee;
nm_setting_connection_get_autoconnect_ports;
nm_setting_connection_get_controller;
nm_setting_connection_get_down_on_poweroff;
nm_setting_connection_get_port_type;
nm_setting_generic_get_device_handler;
nm_setting_get_enum_property_type;
@ -1977,3 +1978,9 @@ global:
nm_sriov_eswitch_inline_mode_get_type;
nm_sriov_eswitch_mode_get_type;
} libnm_1_44_0;
libnm_1_48_0 {
global:
nm_setting_connection_down_on_poweroff_get_type;
nm_setting_connection_get_down_on_poweroff;
} libnm_1_46_0;

View file

@ -792,6 +792,10 @@
dbus-type="i"
gprop-type="gint"
/>
<property name="down-on-poweroff"
dbus-type="i"
gprop-type="gint"
/>
<property name="gateway-ping-timeout"
dbus-type="u"
gprop-type="guint"

View file

@ -73,7 +73,8 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMSettingConnection,
PROP_AUTH_RETRIES,
PROP_WAIT_DEVICE_TIMEOUT,
PROP_MUD_URL,
PROP_WAIT_ACTIVATION_DELAY, );
PROP_WAIT_ACTIVATION_DELAY,
PROP_DOWN_ON_POWEROFF, );
typedef struct {
GArray *permissions;
@ -89,6 +90,7 @@ typedef struct {
char *mud_url;
guint64 timestamp;
int autoconnect_ports;
int down_on_poweroff;
int metered;
gint32 autoconnect_priority;
gint32 autoconnect_retries;
@ -828,6 +830,26 @@ nm_setting_connection_get_wait_activation_delay(NMSettingConnection *setting)
return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->wait_activation_delay;
}
/**
* nm_setting_connection_get_down_on_poweroff:
* @setting: the #NMSettingConnection
*
* Returns the %NM_SETTING_CONNECTION_DOWN_ON_POWEROFF property.
*
* Returns: whether the connection will be brought down before the system
* is powered off.
*
* Since: 1.48
*/
NMSettingConnectionDownOnPoweroff
nm_setting_connection_get_down_on_poweroff(NMSettingConnection *setting)
{
g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting),
NM_SETTING_CONNECTION_DOWN_ON_POWEROFF_DEFAULT);
return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->down_on_poweroff;
}
/**
* nm_setting_connection_get_autoconnect_ports:
* @setting: the #NMSettingConnection
@ -3158,6 +3180,29 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass)
NMSettingConnectionPrivate,
wait_activation_delay);
/**
* NMSettingConnection:down-on-poweroff:
*
*
* Whether the connection will be brought down before the system is powered
* off. The default value is %NM_SETTING_CONNECTION_DOWN_ON_POWEROFF_DEFAULT. When
* the default value is specified, then the global value from
* NetworkManager configuration is looked up, if not set, it is considered
* as %NM_SETTING_CONNECTION_DOWN_ON_POWEROFF_NO.
*
* Since: 1.48
**/
_nm_setting_property_define_direct_enum(properties_override,
obj_properties,
NM_SETTING_CONNECTION_DOWN_ON_POWEROFF,
PROP_DOWN_ON_POWEROFF,
NM_TYPE_SETTING_CONNECTION_DOWN_ON_POWEROFF,
NM_SETTING_CONNECTION_DOWN_ON_POWEROFF_DEFAULT,
NM_SETTING_PARAM_NONE,
NULL,
NMSettingConnectionPrivate,
down_on_poweroff);
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
_nm_setting_class_commit(setting_class,

View file

@ -3962,7 +3962,7 @@ typedef struct {
typedef struct {
const char *name;
DiffKey keys[32];
DiffKey keys[33];
} DiffSetting;
#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
@ -4036,6 +4036,7 @@ test_connection_diff_a_only(void)
{NM_SETTING_CONNECTION_MUD_URL, NM_SETTING_DIFF_RESULT_IN_A},
{NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A},
{NM_SETTING_CONNECTION_WAIT_ACTIVATION_DELAY, NM_SETTING_DIFF_RESULT_IN_A},
{NM_SETTING_CONNECTION_DOWN_ON_POWEROFF, NM_SETTING_DIFF_RESULT_IN_A},
{NULL, NM_SETTING_DIFF_RESULT_UNKNOWN}}},
{NM_SETTING_WIRED_SETTING_NAME,
{

View file

@ -64,6 +64,7 @@ G_BEGIN_DECLS
#define NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT "wait-device-timeout"
#define NM_SETTING_CONNECTION_MUD_URL "mud-url"
#define NM_SETTING_CONNECTION_WAIT_ACTIVATION_DELAY "wait-activation-delay"
#define NM_SETTING_CONNECTION_DOWN_ON_POWEROFF "down-on-poweroff"
/* Types for property values */
/**
@ -158,6 +159,23 @@ typedef enum {
NM_SETTING_CONNECTION_DNS_OVER_TLS_YES = 2,
} NMSettingConnectionDnsOverTls;
/**
* NMSettingConnectionDownOnPoweroff:
* @NM_SETTING_CONNECTION_DOWN_ON_POWEROFF_DEFAULT: default value
* @NM_SETTING_CONNECTION_DOWN_ON_POWEROFF_NO: disable down-on-poweroff
* @NM_SETTING_CONNECTION_DOWN_ON_POWEROFF_YES: enable down-on-poweroff
*
* #NMSettingConnectionDownOnPoweroff indicates whether the connection will be
* brought down before the system is powered off.
*
* Since: 1.48
*/
typedef enum {
NM_SETTING_CONNECTION_DOWN_ON_POWEROFF_DEFAULT = -1,
NM_SETTING_CONNECTION_DOWN_ON_POWEROFF_NO = 0,
NM_SETTING_CONNECTION_DOWN_ON_POWEROFF_YES = 1,
} NMSettingConnectionDownOnPoweroff;
typedef struct _NMSettingConnectionClass NMSettingConnectionClass;
GType nm_setting_connection_get_type(void);
@ -254,6 +272,10 @@ gint32 nm_setting_connection_get_wait_device_timeout(NMSettingConnection *settin
NM_AVAILABLE_IN_1_40
gint32 nm_setting_connection_get_wait_activation_delay(NMSettingConnection *setting);
NM_AVAILABLE_IN_1_48
NMSettingConnectionDownOnPoweroff
nm_setting_connection_get_down_on_poweroff(NMSettingConnection *setting);
NM_AVAILABLE_IN_1_26
const char *nm_setting_connection_get_mud_url(NMSettingConnection *setting);

View file

@ -5663,6 +5663,9 @@ static const NMMetaPropertyInfo *const property_infos_CONNECTION[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_AUTOCONNECT_PORTS,
.property_type = &_pt_gobject_enum,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_DOWN_ON_POWEROFF,
.property_type = &_pt_gobject_ternary,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_SECONDARIES,
.describe_message =
N_("Enter secondary connections that should be activated when this connection is\n"

View file

@ -8,6 +8,7 @@
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES N_("Whether or not slaves of this connection should be automatically brought up when NetworkManager activates this connection. This only has a real effect for master connections. The properties \"autoconnect\", \"autoconnect-priority\" and \"autoconnect-retries\" are unrelated to this setting. The permitted values are: 0: leave slave connections untouched, 1: activate all the slave connections with this connection, -1: default. If -1 (default) is set, global connection.autoconnect-slaves is read to determine the real value. If it is default as well, this fallbacks to 0.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_CONTROLLER N_("Interface name of the controller device or UUID of the controller connection.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_DNS_OVER_TLS N_("Whether DNSOverTls (dns-over-tls) is enabled for the connection. DNSOverTls is a technology which uses TLS to encrypt dns traffic. The permitted values are: \"yes\" (2) use DNSOverTls and disabled fallback, \"opportunistic\" (1) use DNSOverTls but allow fallback to unencrypted resolution, \"no\" (0) don't ever use DNSOverTls. If unspecified \"default\" depends on the plugin used. Systemd-resolved uses global setting. This feature requires a plugin which supports DNSOverTls. Otherwise, the setting has no effect. One such plugin is dns-systemd-resolved.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_DOWN_ON_POWEROFF N_("Whether the connection will be brought down before the system is powered off. The default value is \"default\" (-1). When the default value is specified, then the global value from NetworkManager configuration is looked up, if not set, it is considered as \"no\" (0).")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT N_("If greater than zero, delay success of IP addressing until either the timeout is reached, or an IP gateway replies to a ping.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_ID N_("A human readable unique identifier for the connection, like \"Work Wi-Fi\" or \"T-Mobile 3G\".")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_INTERFACE_NAME N_("The name of the network interface this connection is bound to. If not set, then the connection can be attached to any interface of the appropriate type (subject to restrictions imposed by other settings). For software devices this specifies the name of the created device. For connection types where interface names cannot easily be made persistent (e.g. mobile broadband or USB Ethernet), this property should not be used. Setting this property restricts the interfaces a connection can be used with, and if interface names change or are reordered the connection may be applied to the wrong interface.")

View file

@ -678,6 +678,10 @@
nmcli-description="Whether or not ports of this connection should be automatically brought up when NetworkManager activates this connection. This only has a real effect for controller connections. The properties &quot;autoconnect&quot;, &quot;autoconnect-priority&quot; and &quot;autoconnect-retries&quot; are unrelated to this setting. The permitted values are: 0: leave port connections untouched, 1: activate all the port connections with this connection, -1: default. If -1 (default) is set, global connection.autoconnect-ports is read to determine the real value. If it is default as well, this fallbacks to 0."
format="choice (NMTernary)"
values="default (-1), false (0), true (1)" />
<property name="down-on-poweroff"
nmcli-description="Whether the connection will be brought down before the system is powered off. The default value is &quot;default&quot; (-1). When the default value is specified, then the global value from NetworkManager configuration is looked up, if not set, it is considered as &quot;no&quot; (0)."
format="ternary"
values="true/yes/on, false/no/off, default/unknown" />
<property name="secondaries"
nmcli-description="List of connection UUIDs that should be activated when the base connection itself is activated. Currently, only VPN connections are supported."
format="list of strings" />

View file

@ -502,12 +502,12 @@ NAME UUID TYPE DEVICE
con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet --
<<<
size: 1512
size: 1565
location: src/tests/client/test-client.py:test_002()/23
cmd: $NMCLI c s con-1
lang: C
returncode: 0
stdout: 1384 bytes
stdout: 1437 bytes
>>>
connection.id: con-1
connection.uuid: 5fcfd6d7-1e63-3332-8826-a7eda103792d
@ -528,6 +528,7 @@ connection.slave-type: --
connection.port-type: --
connection.autoconnect-slaves: -1 (default)
connection.autoconnect-ports: -1 (default)
connection.down-on-poweroff: -1 (default)
connection.secondaries: --
connection.gateway-ping-timeout: 0
connection.metered: unknown
@ -540,12 +541,12 @@ connection.wait-device-timeout: -1
connection.wait-activation-delay: -1
<<<
size: 1523
size: 1576
location: src/tests/client/test-client.py:test_002()/24
cmd: $NMCLI c s con-1
lang: pl_PL.UTF-8
returncode: 0
stdout: 1385 bytes
stdout: 1438 bytes
>>>
connection.id: con-1
connection.uuid: 5fcfd6d7-1e63-3332-8826-a7eda103792d
@ -566,6 +567,7 @@ connection.slave-type: --
connection.port-type: --
connection.autoconnect-slaves: -1 (default)
connection.autoconnect-ports: -1 (default)
connection.down-on-poweroff: -1 (default)
connection.secondaries: --
connection.gateway-ping-timeout: 0
connection.metered: nieznane

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff