mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-16 07:08:07 +02:00
nm-manager: add 'metered' property
This introduces a global metered property which makes easier for clients to obtain the metered status of the current primary connection.
This commit is contained in:
parent
bd4e1f37f8
commit
04d5804dd5
9 changed files with 141 additions and 2 deletions
|
|
@ -335,6 +335,14 @@
|
||||||
</tp:docstring>
|
</tp:docstring>
|
||||||
</property>
|
</property>
|
||||||
|
|
||||||
|
<property name="Metered" type="u" access="read" tp:type="NM_METERED">
|
||||||
|
<tp:docstring>
|
||||||
|
Wheter the connectivity is metered. This is equivalent to the
|
||||||
|
metered property of the device associated with the primary
|
||||||
|
connection.
|
||||||
|
</tp:docstring>
|
||||||
|
</property>
|
||||||
|
|
||||||
<property name="ActivatingConnection" type="o" access="read">
|
<property name="ActivatingConnection" type="o" access="read">
|
||||||
<tp:docstring>
|
<tp:docstring>
|
||||||
The object path of an active connection that is currently
|
The object path of an active connection that is currently
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ enum {
|
||||||
PROP_CONNECTIONS,
|
PROP_CONNECTIONS,
|
||||||
PROP_HOSTNAME,
|
PROP_HOSTNAME,
|
||||||
PROP_CAN_MODIFY,
|
PROP_CAN_MODIFY,
|
||||||
|
PROP_METERED,
|
||||||
|
|
||||||
LAST_PROP
|
LAST_PROP
|
||||||
};
|
};
|
||||||
|
|
@ -1871,6 +1872,7 @@ get_property (GObject *object, guint prop_id,
|
||||||
case PROP_PRIMARY_CONNECTION:
|
case PROP_PRIMARY_CONNECTION:
|
||||||
case PROP_ACTIVATING_CONNECTION:
|
case PROP_ACTIVATING_CONNECTION:
|
||||||
case PROP_DEVICES:
|
case PROP_DEVICES:
|
||||||
|
case PROP_METERED:
|
||||||
g_object_get_property (G_OBJECT (NM_CLIENT_GET_PRIVATE (object)->manager),
|
g_object_get_property (G_OBJECT (NM_CLIENT_GET_PRIVATE (object)->manager),
|
||||||
pspec->name, value);
|
pspec->name, value);
|
||||||
break;
|
break;
|
||||||
|
|
@ -2143,6 +2145,20 @@ nm_client_class_init (NMClientClass *client_class)
|
||||||
G_PARAM_READABLE |
|
G_PARAM_READABLE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NMClient:metered:
|
||||||
|
*
|
||||||
|
* Whether the connectivity is metered.
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
**/
|
||||||
|
g_object_class_install_property
|
||||||
|
(object_class, PROP_METERED,
|
||||||
|
g_param_spec_uint (NM_CLIENT_METERED, "", "",
|
||||||
|
0, G_MAXUINT32, NM_METERED_UNKNOWN,
|
||||||
|
G_PARAM_READABLE |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ G_BEGIN_DECLS
|
||||||
#define NM_CLIENT_CONNECTIONS "connections"
|
#define NM_CLIENT_CONNECTIONS "connections"
|
||||||
#define NM_CLIENT_HOSTNAME "hostname"
|
#define NM_CLIENT_HOSTNAME "hostname"
|
||||||
#define NM_CLIENT_CAN_MODIFY "can-modify"
|
#define NM_CLIENT_CAN_MODIFY "can-modify"
|
||||||
|
#define NM_CLIENT_METERED "metered"
|
||||||
|
|
||||||
#define NM_CLIENT_DEVICE_ADDED "device-added"
|
#define NM_CLIENT_DEVICE_ADDED "device-added"
|
||||||
#define NM_CLIENT_DEVICE_REMOVED "device-removed"
|
#define NM_CLIENT_DEVICE_REMOVED "device-removed"
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ typedef struct {
|
||||||
NMConnectivityState connectivity;
|
NMConnectivityState connectivity;
|
||||||
NMActiveConnection *primary_connection;
|
NMActiveConnection *primary_connection;
|
||||||
NMActiveConnection *activating_connection;
|
NMActiveConnection *activating_connection;
|
||||||
|
NMMetered metered;
|
||||||
|
|
||||||
GCancellable *perm_call_cancellable;
|
GCancellable *perm_call_cancellable;
|
||||||
GHashTable *permissions;
|
GHashTable *permissions;
|
||||||
|
|
@ -102,6 +103,7 @@ enum {
|
||||||
PROP_PRIMARY_CONNECTION,
|
PROP_PRIMARY_CONNECTION,
|
||||||
PROP_ACTIVATING_CONNECTION,
|
PROP_ACTIVATING_CONNECTION,
|
||||||
PROP_DEVICES,
|
PROP_DEVICES,
|
||||||
|
PROP_METERED,
|
||||||
|
|
||||||
LAST_PROP
|
LAST_PROP
|
||||||
};
|
};
|
||||||
|
|
@ -179,6 +181,7 @@ init_dbus (NMObject *object)
|
||||||
{ NM_MANAGER_PRIMARY_CONNECTION, &priv->primary_connection, NULL, NM_TYPE_ACTIVE_CONNECTION },
|
{ NM_MANAGER_PRIMARY_CONNECTION, &priv->primary_connection, NULL, NM_TYPE_ACTIVE_CONNECTION },
|
||||||
{ NM_MANAGER_ACTIVATING_CONNECTION, &priv->activating_connection, NULL, NM_TYPE_ACTIVE_CONNECTION },
|
{ NM_MANAGER_ACTIVATING_CONNECTION, &priv->activating_connection, NULL, NM_TYPE_ACTIVE_CONNECTION },
|
||||||
{ NM_MANAGER_DEVICES, &priv->devices, NULL, NM_TYPE_DEVICE, "device" },
|
{ NM_MANAGER_DEVICES, &priv->devices, NULL, NM_TYPE_DEVICE, "device" },
|
||||||
|
{ NM_MANAGER_METERED, &priv->metered },
|
||||||
{ NULL },
|
{ NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1537,6 +1540,9 @@ get_property (GObject *object,
|
||||||
case PROP_DEVICES:
|
case PROP_DEVICES:
|
||||||
g_value_take_boxed (value, _nm_utils_copy_object_array (nm_manager_get_devices (self)));
|
g_value_take_boxed (value, _nm_utils_copy_object_array (nm_manager_get_devices (self)));
|
||||||
break;
|
break;
|
||||||
|
case PROP_METERED:
|
||||||
|
g_value_set_uint (value, priv->metered);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
|
@ -1669,6 +1675,19 @@ nm_manager_class_init (NMManagerClass *manager_class)
|
||||||
G_TYPE_PTR_ARRAY,
|
G_TYPE_PTR_ARRAY,
|
||||||
G_PARAM_READABLE |
|
G_PARAM_READABLE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
/**
|
||||||
|
* NMManager:metered:
|
||||||
|
*
|
||||||
|
* Whether the connectivity is metered.
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
**/
|
||||||
|
g_object_class_install_property
|
||||||
|
(object_class, PROP_METERED,
|
||||||
|
g_param_spec_uint (NM_MANAGER_METERED, "", "",
|
||||||
|
0, G_MAXUINT32, NM_METERED_UNKNOWN,
|
||||||
|
G_PARAM_READABLE |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ G_BEGIN_DECLS
|
||||||
#define NM_MANAGER_PRIMARY_CONNECTION "primary-connection"
|
#define NM_MANAGER_PRIMARY_CONNECTION "primary-connection"
|
||||||
#define NM_MANAGER_ACTIVATING_CONNECTION "activating-connection"
|
#define NM_MANAGER_ACTIVATING_CONNECTION "activating-connection"
|
||||||
#define NM_MANAGER_DEVICES "devices"
|
#define NM_MANAGER_DEVICES "devices"
|
||||||
|
#define NM_MANAGER_METERED "metered"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NMObject parent;
|
NMObject parent;
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,7 @@ enum {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
DEVICE_CHANGED,
|
DEVICE_CHANGED,
|
||||||
|
DEVICE_METERED_CHANGED,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
static guint signals[LAST_SIGNAL] = { 0 };
|
static guint signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
@ -401,6 +402,18 @@ device_master_changed (GObject *object,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
device_metered_changed (GObject *object,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
NMActiveConnection *self = (NMActiveConnection *) user_data;
|
||||||
|
NMDevice *device = NM_DEVICE (object);
|
||||||
|
|
||||||
|
g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self));
|
||||||
|
g_signal_emit (self, signals[DEVICE_METERED_CHANGED], 0, nm_device_get_metered (device));
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
nm_active_connection_set_device (NMActiveConnection *self, NMDevice *device)
|
nm_active_connection_set_device (NMActiveConnection *self, NMDevice *device)
|
||||||
{
|
{
|
||||||
|
|
@ -427,6 +440,8 @@ nm_active_connection_set_device (NMActiveConnection *self, NMDevice *device)
|
||||||
G_CALLBACK (device_state_changed), self);
|
G_CALLBACK (device_state_changed), self);
|
||||||
g_signal_connect (device, "notify::master",
|
g_signal_connect (device, "notify::master",
|
||||||
G_CALLBACK (device_master_changed), self);
|
G_CALLBACK (device_master_changed), self);
|
||||||
|
g_signal_connect (device, "notify::" NM_DEVICE_METERED,
|
||||||
|
G_CALLBACK (device_metered_changed), self);
|
||||||
|
|
||||||
if (!priv->assumed) {
|
if (!priv->assumed) {
|
||||||
priv->pending_activation_id = g_strdup_printf ("activation::%p", (void *)self);
|
priv->pending_activation_id = g_strdup_printf ("activation::%p", (void *)self);
|
||||||
|
|
@ -837,6 +852,7 @@ _device_cleanup (NMActiveConnection *self)
|
||||||
if (priv->device) {
|
if (priv->device) {
|
||||||
g_signal_handlers_disconnect_by_func (priv->device, G_CALLBACK (device_state_changed), self);
|
g_signal_handlers_disconnect_by_func (priv->device, G_CALLBACK (device_state_changed), self);
|
||||||
g_signal_handlers_disconnect_by_func (priv->device, G_CALLBACK (device_master_changed), self);
|
g_signal_handlers_disconnect_by_func (priv->device, G_CALLBACK (device_master_changed), self);
|
||||||
|
g_signal_handlers_disconnect_by_func (priv->device, G_CALLBACK (device_metered_changed), self);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->pending_activation_id) {
|
if (priv->pending_activation_id) {
|
||||||
|
|
@ -1042,6 +1058,14 @@ nm_active_connection_class_init (NMActiveConnectionClass *ac_class)
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
G_TYPE_NONE, 2, NM_TYPE_DEVICE, NM_TYPE_DEVICE);
|
G_TYPE_NONE, 2, NM_TYPE_DEVICE, NM_TYPE_DEVICE);
|
||||||
|
|
||||||
|
signals[DEVICE_METERED_CHANGED] =
|
||||||
|
g_signal_new (NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED,
|
||||||
|
G_OBJECT_CLASS_TYPE (object_class),
|
||||||
|
G_SIGNAL_RUN_FIRST,
|
||||||
|
G_STRUCT_OFFSET (NMActiveConnectionClass, device_metered_changed),
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
G_TYPE_NONE, 1, G_TYPE_UINT);
|
||||||
|
|
||||||
nm_dbus_manager_register_exported_type (nm_dbus_manager_get (),
|
nm_dbus_manager_register_exported_type (nm_dbus_manager_get (),
|
||||||
G_TYPE_FROM_CLASS (ac_class),
|
G_TYPE_FROM_CLASS (ac_class),
|
||||||
&dbus_glib_nm_active_connection_object_info);
|
&dbus_glib_nm_active_connection_object_info);
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,8 @@
|
||||||
#define NM_ACTIVE_CONNECTION_INT_MASTER_READY "int-master-ready"
|
#define NM_ACTIVE_CONNECTION_INT_MASTER_READY "int-master-ready"
|
||||||
|
|
||||||
/* Internal signals*/
|
/* Internal signals*/
|
||||||
#define NM_ACTIVE_CONNECTION_DEVICE_CHANGED "device-changed"
|
#define NM_ACTIVE_CONNECTION_DEVICE_CHANGED "device-changed"
|
||||||
|
#define NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED "device-metered-changed"
|
||||||
|
|
||||||
struct _NMActiveConnection {
|
struct _NMActiveConnection {
|
||||||
GObject parent;
|
GObject parent;
|
||||||
|
|
@ -78,6 +79,9 @@ typedef struct {
|
||||||
void (*device_changed) (NMActiveConnection *connection,
|
void (*device_changed) (NMActiveConnection *connection,
|
||||||
NMDevice *new_device,
|
NMDevice *new_device,
|
||||||
NMDevice *old_device);
|
NMDevice *old_device);
|
||||||
|
|
||||||
|
void (*device_metered_changed) (NMActiveConnection *connection,
|
||||||
|
NMMetered new_value);
|
||||||
} NMActiveConnectionClass;
|
} NMActiveConnectionClass;
|
||||||
|
|
||||||
GType nm_active_connection_get_type (void);
|
GType nm_active_connection_get_type (void);
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,7 @@ typedef struct {
|
||||||
guint ac_cleanup_id;
|
guint ac_cleanup_id;
|
||||||
NMActiveConnection *primary_connection;
|
NMActiveConnection *primary_connection;
|
||||||
NMActiveConnection *activating_connection;
|
NMActiveConnection *activating_connection;
|
||||||
|
NMMetered metered;
|
||||||
|
|
||||||
GSList *devices;
|
GSList *devices;
|
||||||
NMState state;
|
NMState state;
|
||||||
|
|
@ -230,6 +231,7 @@ enum {
|
||||||
PROP_PRIMARY_CONNECTION_TYPE,
|
PROP_PRIMARY_CONNECTION_TYPE,
|
||||||
PROP_ACTIVATING_CONNECTION,
|
PROP_ACTIVATING_CONNECTION,
|
||||||
PROP_DEVICES,
|
PROP_DEVICES,
|
||||||
|
PROP_METERED,
|
||||||
|
|
||||||
/* Not exported */
|
/* Not exported */
|
||||||
PROP_HOSTNAME,
|
PROP_HOSTNAME,
|
||||||
|
|
@ -654,6 +656,30 @@ find_best_device_state (NMManager *manager)
|
||||||
return best_state;
|
return best_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nm_manager_update_metered (NMManager *manager)
|
||||||
|
{
|
||||||
|
NMManagerPrivate *priv;
|
||||||
|
NMDevice *device;
|
||||||
|
NMMetered value = NM_METERED_UNKNOWN;
|
||||||
|
|
||||||
|
g_return_if_fail (NM_IS_MANAGER (manager));
|
||||||
|
priv = NM_MANAGER_GET_PRIVATE (manager);
|
||||||
|
|
||||||
|
if (priv->primary_connection) {
|
||||||
|
device = nm_active_connection_get_device (priv->primary_connection);
|
||||||
|
if (device)
|
||||||
|
value = nm_device_get_metered (device);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != priv->metered) {
|
||||||
|
priv->metered = value;
|
||||||
|
nm_log_dbg (LOGD_CORE, "New manager metered value: %d",
|
||||||
|
(int) priv->metered);
|
||||||
|
g_object_notify (G_OBJECT (manager), NM_MANAGER_METERED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nm_manager_update_state (NMManager *manager)
|
nm_manager_update_state (NMManager *manager)
|
||||||
{
|
{
|
||||||
|
|
@ -4055,6 +4081,14 @@ firmware_dir_changed (GFileMonitor *monitor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
connection_metered_changed (GObject *object,
|
||||||
|
NMMetered metered,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
nm_manager_update_metered (NM_MANAGER (user_data));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
policy_default_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
|
policy_default_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
|
||||||
{
|
{
|
||||||
|
|
@ -4077,11 +4111,23 @@ policy_default_device_changed (GObject *object, GParamSpec *pspec, gpointer user
|
||||||
ac = NULL;
|
ac = NULL;
|
||||||
|
|
||||||
if (ac != priv->primary_connection) {
|
if (ac != priv->primary_connection) {
|
||||||
g_clear_object (&priv->primary_connection);
|
if (priv->primary_connection) {
|
||||||
|
g_signal_handlers_disconnect_by_func (priv->primary_connection,
|
||||||
|
G_CALLBACK (connection_metered_changed),
|
||||||
|
self);
|
||||||
|
g_clear_object (&priv->primary_connection);
|
||||||
|
}
|
||||||
|
|
||||||
priv->primary_connection = ac ? g_object_ref (ac) : NULL;
|
priv->primary_connection = ac ? g_object_ref (ac) : NULL;
|
||||||
|
|
||||||
|
if (priv->primary_connection) {
|
||||||
|
g_signal_connect (priv->primary_connection, NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED,
|
||||||
|
G_CALLBACK (connection_metered_changed), self);
|
||||||
|
}
|
||||||
nm_log_dbg (LOGD_CORE, "PrimaryConnection now %s", ac ? nm_active_connection_get_id (ac) : "(none)");
|
nm_log_dbg (LOGD_CORE, "PrimaryConnection now %s", ac ? nm_active_connection_get_id (ac) : "(none)");
|
||||||
g_object_notify (G_OBJECT (self), NM_MANAGER_PRIMARY_CONNECTION);
|
g_object_notify (G_OBJECT (self), NM_MANAGER_PRIMARY_CONNECTION);
|
||||||
g_object_notify (G_OBJECT (self), NM_MANAGER_PRIMARY_CONNECTION_TYPE);
|
g_object_notify (G_OBJECT (self), NM_MANAGER_PRIMARY_CONNECTION_TYPE);
|
||||||
|
nm_manager_update_metered (self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4649,6 +4695,8 @@ nm_manager_init (NMManager *manager)
|
||||||
|
|
||||||
/* Update timestamps in active connections */
|
/* Update timestamps in active connections */
|
||||||
priv->timestamp_update_id = g_timeout_add_seconds (300, (GSourceFunc) periodic_update_active_connection_timestamps, manager);
|
priv->timestamp_update_id = g_timeout_add_seconds (300, (GSourceFunc) periodic_update_active_connection_timestamps, manager);
|
||||||
|
|
||||||
|
priv->metered = NM_METERED_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -4733,6 +4781,9 @@ get_property (GObject *object, guint prop_id,
|
||||||
}
|
}
|
||||||
g_value_take_boxed (value, array);
|
g_value_take_boxed (value, array);
|
||||||
break;
|
break;
|
||||||
|
case PROP_METERED:
|
||||||
|
g_value_set_uint (value, priv->metered);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
|
@ -5011,6 +5062,20 @@ nm_manager_class_init (NMManagerClass *manager_class)
|
||||||
G_PARAM_READABLE |
|
G_PARAM_READABLE |
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NMManager:metered:
|
||||||
|
*
|
||||||
|
* Whether the connectivity is metered.
|
||||||
|
*
|
||||||
|
* Since: 1.2
|
||||||
|
**/
|
||||||
|
g_object_class_install_property
|
||||||
|
(object_class, PROP_METERED,
|
||||||
|
g_param_spec_uint (NM_MANAGER_METERED, "", "",
|
||||||
|
0, G_MAXUINT32, NM_METERED_UNKNOWN,
|
||||||
|
G_PARAM_READABLE |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
signals[DEVICE_ADDED] =
|
signals[DEVICE_ADDED] =
|
||||||
g_signal_new ("device-added",
|
g_signal_new ("device-added",
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@
|
||||||
#define NM_MANAGER_PRIMARY_CONNECTION_TYPE "primary-connection-type"
|
#define NM_MANAGER_PRIMARY_CONNECTION_TYPE "primary-connection-type"
|
||||||
#define NM_MANAGER_ACTIVATING_CONNECTION "activating-connection"
|
#define NM_MANAGER_ACTIVATING_CONNECTION "activating-connection"
|
||||||
#define NM_MANAGER_DEVICES "devices"
|
#define NM_MANAGER_DEVICES "devices"
|
||||||
|
#define NM_MANAGER_METERED "metered"
|
||||||
|
|
||||||
/* Not exported */
|
/* Not exported */
|
||||||
#define NM_MANAGER_HOSTNAME "hostname"
|
#define NM_MANAGER_HOSTNAME "hostname"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue