core: merge branch 'bg/sriov-async'

https://github.com/NetworkManager/NetworkManager/pull/268
This commit is contained in:
Beniamino Galvani 2019-05-28 10:35:57 +02:00
commit 3a4a09b669
5 changed files with 764 additions and 201 deletions

View file

@ -128,6 +128,15 @@ typedef struct {
int ifindex;
} DeleteOnDeactivateData;
typedef struct {
NMDevice *device;
GCancellable *cancellable;
NMPlatformAsyncCallback callback;
gpointer callback_data;
guint num_vfs;
NMTernary autoprobe;
} SriovOp;
typedef void (*AcdCallback) (NMDevice *, NMIP4Config **, gboolean);
typedef struct {
@ -575,13 +584,17 @@ typedef struct _NMDevicePrivate {
guint check_delete_unrealized_id;
struct {
SriovOp *pending; /* SR-IOV operation currently running */
SriovOp *next; /* next SR-IOV operation scheduled */
} sriov;
struct {
guint timeout_id;
guint refresh_rate_ms;
guint64 tx_bytes;
guint64 rx_bytes;
} stats;
} NMDevicePrivate;
G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, NM_TYPE_DBUS_OBJECT)
@ -4192,6 +4205,86 @@ nm_device_update_from_platform_link (NMDevice *self, const NMPlatformLink *plink
}
}
static void sriov_op_cb (GError *error, gpointer user_data);
static void
sriov_op_start (NMDevice *self, SriovOp *op)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
nm_assert (!priv->sriov.pending);
op->cancellable = g_cancellable_new ();
op->device = g_object_ref (self);
priv->sriov.pending = op;
nm_platform_link_set_sriov_params_async (nm_device_get_platform (self),
priv->ifindex,
op->num_vfs,
op->autoprobe,
sriov_op_cb,
op,
op->cancellable);
}
static void
sriov_op_cb (GError *error, gpointer user_data)
{
SriovOp *op = user_data;
gs_unref_object NMDevice *self = op->device;
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
nm_assert (op == priv->sriov.pending);
priv->sriov.pending = NULL;
if (op->callback)
op->callback (error, op->callback_data);
g_clear_object (&op->cancellable);
g_slice_free (SriovOp, op);
if (priv->sriov.next) {
sriov_op_start (self,
g_steal_pointer (&priv->sriov.next));
}
}
static void
sriov_op_queue (NMDevice *self,
guint num_vfs,
NMTernary autoprobe,
NMPlatformAsyncCallback callback,
gpointer callback_data)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
GError *error = NULL;
SriovOp *op;
op = g_slice_new0 (SriovOp);
op->num_vfs = num_vfs;
op->autoprobe = autoprobe;
op->callback = callback;
op->callback_data = callback_data;
if (priv->sriov.next) {
/* Cancel the next operation immediately */
if (priv->sriov.next->callback) {
nm_utils_error_set_cancelled (&error, FALSE, NULL);
priv->sriov.next->callback (error, priv->sriov.next->callback_data);
g_clear_error (&error);
}
g_slice_free (SriovOp, priv->sriov.next);
priv->sriov.next = NULL;
}
if (priv->sriov.pending) {
priv->sriov.next = op;
g_cancellable_cancel (priv->sriov.pending->cancellable);
} else
sriov_op_start (self, op);
}
static void
device_init_static_sriov_num_vfs (NMDevice *self)
{
@ -4206,10 +4299,8 @@ device_init_static_sriov_num_vfs (NMDevice *self)
self,
NULL);
num_vfs = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXINT32, -1);
if (num_vfs >= 0) {
nm_platform_link_set_sriov_params (nm_device_get_platform (self),
priv->ifindex, num_vfs, NM_TERNARY_DEFAULT);
}
if (num_vfs >= 0)
sriov_op_queue (self, num_vfs, NM_TERNARY_DEFAULT, NULL, NULL);
}
}
@ -4223,11 +4314,11 @@ config_changed (NMConfig *config,
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
if ( priv->state <= NM_DEVICE_STATE_DISCONNECTED
|| priv->state > NM_DEVICE_STATE_ACTIVATED)
|| priv->state > NM_DEVICE_STATE_ACTIVATED) {
priv->ignore_carrier = nm_config_data_get_ignore_carrier (config_data, self);
if (NM_FLAGS_HAS (changes, NM_CONFIG_CHANGE_VALUES))
device_init_static_sriov_num_vfs (self);
if (NM_FLAGS_HAS (changes, NM_CONFIG_CHANGE_VALUES))
device_init_static_sriov_num_vfs (self);
}
}
static void
@ -6265,6 +6356,41 @@ sriov_vf_config_to_platform (NMDevice *self,
return g_steal_pointer (&plat_vf);
}
static void
sriov_params_cb (GError *error, gpointer data)
{
NMDevice *self;
NMDevicePrivate *priv;
nm_auto_freev NMPlatformVF **plat_vfs = NULL;
nm_utils_user_data_unpack (data, &self, &plat_vfs);
if (nm_utils_error_is_cancelled (error, TRUE))
return;
priv = NM_DEVICE_GET_PRIVATE (self);
if (error) {
_LOGE (LOGD_DEVICE, "failed to set SR-IOV parameters: %s", error->message);
nm_device_state_changed (self,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED);
return;
}
if (!nm_platform_link_set_sriov_vfs (nm_device_get_platform (self),
priv->ifindex,
(const NMPlatformVF *const *) plat_vfs)) {
_LOGE (LOGD_DEVICE, "failed to apply SR-IOV VFs");
nm_device_state_changed (self,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED);
return;
}
nm_device_activate_schedule_stage2_device_config (self);
}
static NMActStageReturn
act_stage1_prepare (NMDevice *self, NMDeviceStateReason *out_failure_reason)
{
@ -6279,6 +6405,7 @@ act_stage1_prepare (NMDevice *self, NMDeviceStateReason *out_failure_reason)
gs_free_error GError *error = NULL;
NMSriovVF *vf;
NMTernary autoprobe;
gpointer *data;
autoprobe = nm_setting_sriov_get_autoprobe_drivers (s_sriov);
if (autoprobe == NM_TERNARY_DEFAULT) {
@ -6305,24 +6432,19 @@ act_stage1_prepare (NMDevice *self, NMDeviceStateReason *out_failure_reason)
}
}
if (!nm_platform_link_set_sriov_params (nm_device_get_platform (self),
priv->ifindex,
nm_setting_sriov_get_total_vfs (s_sriov),
autoprobe)) {
_LOGE (LOGD_DEVICE, "failed to apply SR-IOV parameters");
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED);
return NM_ACT_STAGE_RETURN_FAILURE;
}
if (!nm_platform_link_set_sriov_vfs (nm_device_get_platform (self),
priv->ifindex,
(const NMPlatformVF *const *) plat_vfs)) {
_LOGE (LOGD_DEVICE, "failed to apply SR-IOV VFs");
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED);
return NM_ACT_STAGE_RETURN_FAILURE;
}
/* When changing the number of VFs the kernel can block
* for very long time in the write to sysfs, especially
* if autoprobe-drivers is enabled. Do it asynchronously
* to avoid blocking the entire NM process.
*/
data = nm_utils_user_data_pack (self, g_steal_pointer (&plat_vfs));
sriov_op_queue (self,
nm_setting_sriov_get_total_vfs (s_sriov),
autoprobe,
sriov_params_cb,
data);
return NM_ACT_STAGE_RETURN_POSTPONE;
}
return NM_ACT_STAGE_RETURN_SUCCESS;
}
@ -14800,6 +14922,34 @@ ip6_managed_setup (NMDevice *self)
nm_device_sysctl_ip_conf_set (self, AF_INET6, "forwarding", "0");
}
static void
deactivate_ready (NMDevice *self, NMDeviceStateReason reason)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
if (priv->dispatcher.call_id)
return;
if (priv->sriov.pending)
return;
nm_assert (!priv->sriov.next);
nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, reason);
}
static void
sriov_deactivate_cb (GError *error, gpointer user_data)
{
NMDevice *self;
gpointer reason;
if (nm_utils_error_is_cancelled (error, TRUE))
return;
nm_utils_user_data_unpack (user_data, &self, &reason);
deactivate_ready (self, (NMDeviceStateReason) reason);
}
static void
deactivate_async_ready (NMDevice *self,
GError *error,
@ -14820,7 +14970,8 @@ deactivate_async_ready (NMDevice *self,
_LOGW (LOGD_DEVICE, "Deactivation failed: %s",
error->message);
}
nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, reason);
deactivate_ready (self, reason);
}
static void
@ -14833,7 +14984,7 @@ deactivate_dispatcher_complete (NMDispatcherCallId *call_id, gpointer user_data)
g_return_if_fail (call_id == priv->dispatcher.call_id);
g_return_if_fail (priv->dispatcher.post_state == NM_DEVICE_STATE_DISCONNECTED);
reason = priv->dispatcher.post_state_reason;
reason = priv->state_reason;
priv->dispatcher.call_id = NULL;
priv->dispatcher.post_state = NM_DEVICE_STATE_UNKNOWN;
@ -14849,7 +15000,7 @@ deactivate_dispatcher_complete (NMDispatcherCallId *call_id, gpointer user_data)
deactivate_async_ready,
GUINT_TO_POINTER (reason));
} else
nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, reason);
deactivate_ready (self, reason);
}
static void
@ -15062,12 +15213,6 @@ _set_state_full (NMDevice *self,
}
break;
case NM_DEVICE_STATE_DEACTIVATING:
if ( (s_sriov = nm_device_get_applied_setting (self, NM_TYPE_SETTING_SRIOV))
&& priv->ifindex > 0) {
nm_platform_link_set_sriov_params (nm_device_get_platform (self),
priv->ifindex, 0, NM_TERNARY_TRUE);
}
_cancel_activation (self);
/* We cache the ignore_carrier state to not react on config-reloads while the connection
@ -15089,6 +15234,15 @@ _set_state_full (NMDevice *self,
/* Just proceed on errors */
deactivate_dispatcher_complete (0, self);
}
if ( priv->ifindex > 0
&& (s_sriov = nm_device_get_applied_setting (self, NM_TYPE_SETTING_SRIOV))) {
sriov_op_queue (self,
0,
NM_TERNARY_TRUE,
sriov_deactivate_cb,
nm_utils_user_data_pack (self, (gpointer) reason));
}
}
nm_pacrunner_manager_remove_clear (&priv->pacrunner_conf_id);

View file

@ -4375,6 +4375,14 @@ _genl_sock (NMLinuxPlatform *platform)
} \
} G_STMT_END
/*****************************************************************************/
/* core sysctl-set functions can be called from a non-main thread.
* Hence, we require locking from nm-logging. Indicate that by
* setting NM_THREAD_SAFE_ON_MAIN_THREAD to zero. */
#undef NM_THREAD_SAFE_ON_MAIN_THREAD
#define NM_THREAD_SAFE_ON_MAIN_THREAD 0
static void
_log_dbg_sysctl_set_impl (NMPlatform *platform, const char *pathid, int dirfd, const char *path, const char *value)
{
@ -4385,18 +4393,18 @@ _log_dbg_sysctl_set_impl (NMPlatform *platform, const char *pathid, int dirfd, c
if (nm_utils_file_get_contents (dirfd, path, 1*1024*1024,
NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE,
&contents, NULL, &error) < 0) {
_LOGD ("sysctl: setting '%s' to '%s' (current value cannot be read: %s)", pathid, value_escaped, error->message);
_LOGD ("sysctl: setting '%s' to '%s' (current value cannot be read: %s)", pathid ?: path, value_escaped, error->message);
g_clear_error (&error);
return;
}
g_strstrip (contents);
if (nm_streq (contents, value))
_LOGD ("sysctl: setting '%s' to '%s' (current value is identical)", pathid, value_escaped);
_LOGD ("sysctl: setting '%s' to '%s' (current value is identical)", pathid ?: path, value_escaped);
else {
gs_free char *contents_escaped = g_strescape (contents, NULL);
_LOGD ("sysctl: setting '%s' to '%s' (current value is '%s')", pathid, value_escaped, contents_escaped);
_LOGD ("sysctl: setting '%s' to '%s' (current value is '%s')", pathid ?: path, value_escaped, contents_escaped);
}
g_free (contents);
}
@ -4409,9 +4417,12 @@ _log_dbg_sysctl_set_impl (NMPlatform *platform, const char *pathid, int dirfd, c
} G_STMT_END
static gboolean
sysctl_set (NMPlatform *platform, const char *pathid, int dirfd, const char *path, const char *value)
sysctl_set_internal (NMPlatform *platform,
const char *pathid,
int dirfd,
const char *path,
const char *value)
{
nm_auto_pop_netns NMPNetns *netns = NULL;
int fd, tries;
gssize nwrote;
gssize len;
@ -4419,17 +4430,7 @@ sysctl_set (NMPlatform *platform, const char *pathid, int dirfd, const char *pat
gs_free char *actual_free = NULL;
int errsv;
g_return_val_if_fail (path != NULL, FALSE);
g_return_val_if_fail (value != NULL, FALSE);
ASSERT_SYSCTL_ARGS (pathid, dirfd, path);
if (dirfd < 0) {
if (!nm_platform_netns_push (platform, &netns)) {
errno = ENETDOWN;
return FALSE;
}
pathid = path;
fd = open (path, O_WRONLY | O_TRUNC | O_CLOEXEC);
@ -4529,6 +4530,207 @@ sysctl_set (NMPlatform *platform, const char *pathid, int dirfd, const char *pat
return TRUE;
}
#undef NM_THREAD_SAFE_ON_MAIN_THREAD
#define NM_THREAD_SAFE_ON_MAIN_THREAD 1
/*****************************************************************************/
static gboolean
sysctl_set (NMPlatform *platform,
const char *pathid,
int dirfd,
const char *path,
const char *value)
{
nm_auto_pop_netns NMPNetns *netns = NULL;
g_return_val_if_fail (path, FALSE);
g_return_val_if_fail (value, FALSE);
ASSERT_SYSCTL_ARGS (pathid, dirfd, path);
if ( dirfd < 0
&& !nm_platform_netns_push (platform, &netns)) {
errno = ENETDOWN;
return FALSE;
}
return sysctl_set_internal (platform, pathid, dirfd, path, value);
}
typedef struct {
NMPlatform *platform;
char *pathid;
int dirfd;
char *path;
char **values;
GCancellable *cancellable;
NMPlatformAsyncCallback callback;
gpointer callback_data;
} SysctlAsyncInfo;
static void
sysctl_async_info_free (SysctlAsyncInfo *info)
{
g_object_unref (info->platform);
g_free (info->pathid);
if (info->dirfd >= 0)
nm_close (info->dirfd);
g_free (info->path);
g_strfreev (info->values);
g_object_unref (info->cancellable);
g_slice_free (SysctlAsyncInfo, info);
}
static void
sysctl_async_cb (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
NMPlatform *platform;
GTask *task = G_TASK (res);
SysctlAsyncInfo *info;
gs_free_error GError *error = NULL;
gs_free char *values_str = NULL;
info = g_task_get_task_data (task);
if (g_task_propagate_boolean (task, &error)) {
platform = info->platform;
_LOGD ("sysctl: successfully set-async '%s' to values '%s'",
info->pathid ?: info->path,
(values_str = g_strjoinv (", ", info->values)));
}
if (info->callback)
info->callback (error, info->callback_data);
}
static void
sysctl_async_thread_fn (GTask *task,
gpointer source_object,
gpointer task_data,
GCancellable *cancellable)
{
nm_auto_pop_netns NMPNetns *netns = NULL;
SysctlAsyncInfo *info = task_data;
GError *error = NULL;
char **value;
if (g_task_return_error_if_cancelled (task))
return;
if ( info->dirfd < 0
&& !nm_platform_netns_push (info->platform, &netns)) {
g_set_error_literal (&error,
NM_UTILS_ERROR,
NM_UTILS_ERROR_UNKNOWN,
"sysctl: failed changing namespace");
g_task_return_error (task, error);
return;
}
for (value = info->values; *value; value++) {
if (!sysctl_set_internal (info->platform,
info->pathid,
info->dirfd,
info->path,
*value)) {
g_set_error (&error,
NM_UTILS_ERROR,
NM_UTILS_ERROR_UNKNOWN,
"sysctl: failed setting '%s' to value '%s': %s",
info->pathid ?: info->path,
*value,
nm_strerror_native (errno));
g_task_return_error (task, error);
return;
}
if (g_task_return_error_if_cancelled (task))
return;
}
g_task_return_boolean (task, TRUE);
}
static void
sysctl_set_async_return_idle (gpointer user_data,
GCancellable *cancellable)
{
gs_unref_object NMPlatform *platform = NULL;
gs_free_error GError *cancelled_error = NULL;
gs_free_error GError *error = NULL;
NMPlatformAsyncCallback callback;
gpointer callback_data;
nm_utils_user_data_unpack (user_data, &platform, &callback, &callback_data, &error);
g_cancellable_set_error_if_cancelled (cancellable, &cancelled_error);
callback (cancelled_error ?: error, callback_data);
}
static void
sysctl_set_async (NMPlatform *platform,
const char *pathid,
int dirfd,
const char *path,
const char *const *values,
NMPlatformAsyncCallback callback,
gpointer data,
GCancellable *cancellable)
{
SysctlAsyncInfo *info;
GTask *task;
int dirfd_dup, errsv;
gpointer packed;
GError *error = NULL;
g_return_if_fail (platform);
g_return_if_fail (path);
g_return_if_fail (values && values[0]);
g_return_if_fail (cancellable);
g_return_if_fail (!data || callback);
ASSERT_SYSCTL_ARGS (pathid, dirfd, path);
if (dirfd >= 0) {
dirfd_dup = fcntl (dirfd, F_DUPFD_CLOEXEC, 0);
if (dirfd_dup < 0) {
if (!callback)
return;
errsv = errno;
g_set_error (&error,
NM_UTILS_ERROR,
NM_UTILS_ERROR_UNKNOWN,
"sysctl: failure duplicating directory fd: %s",
nm_strerror_native (errsv));
packed = nm_utils_user_data_pack (g_object_ref (platform),
callback,
data,
error);
nm_utils_invoke_on_idle (sysctl_set_async_return_idle,
packed,
cancellable);
return;
}
} else
dirfd_dup = -1;
info = g_slice_new0 (SysctlAsyncInfo);
info->platform = g_object_ref (platform);
info->pathid = g_strdup (pathid);
info->dirfd = dirfd_dup;
info->path = g_strdup (path);
info->values = g_strdupv ((char **) values);
info->callback = callback;
info->callback_data = data;
info->cancellable = g_object_ref (cancellable);
task = g_task_new (platform, cancellable, sysctl_async_cb, NULL);
g_task_set_task_data (task, info, (GDestroyNotify) sysctl_async_info_free);
g_task_set_return_on_cancel (task, FALSE);
g_task_run_in_thread (task, sysctl_async_thread_fn);
g_object_unref (task);
}
static GSList *sysctl_clear_cache_list;
void
@ -6612,35 +6814,74 @@ nla_put_failure:
g_return_val_if_reached (FALSE);
}
static gboolean
link_set_sriov_params (NMPlatform *platform,
int ifindex,
guint num_vfs,
NMTernary autoprobe)
static void
sriov_idle_cb (gpointer user_data,
GCancellable *cancellable)
{
gs_unref_object NMPlatform *platform = NULL;
gs_free_error GError *cancelled_error = NULL;
gs_free_error GError *error = NULL;
NMPlatformAsyncCallback callback;
gpointer callback_data;
g_cancellable_set_error_if_cancelled (cancellable, &cancelled_error);
nm_utils_user_data_unpack (user_data, &platform, &error, &callback, &callback_data);
callback (cancelled_error ?: error, callback_data);
}
static void
link_set_sriov_params_async (NMPlatform *platform,
int ifindex,
guint num_vfs,
NMTernary autoprobe,
NMPlatformAsyncCallback callback,
gpointer data,
GCancellable *cancellable)
{
nm_auto_pop_netns NMPNetns *netns = NULL;
gs_free_error GError *error = NULL;
nm_auto_close int dirfd = -1;
int current_autoprobe;
guint total;
guint i, total;
gint64 current_num;
char ifname[IFNAMSIZ];
gpointer packed;
const char *values[3];
char buf[64];
int errsv;
if (!nm_platform_netns_push (platform, &netns))
return FALSE;
g_return_if_fail (callback || !data);
g_return_if_fail (cancellable);
if (!nm_platform_netns_push (platform, &netns)) {
g_set_error_literal (&error,
NM_UTILS_ERROR,
NM_UTILS_ERROR_UNKNOWN,
"couldn't change namespace");
goto out_idle;
}
dirfd = nm_platform_sysctl_open_netdir (platform, ifindex, ifname);
if (!dirfd)
return FALSE;
if (!dirfd) {
g_set_error_literal (&error,
NM_UTILS_ERROR,
NM_UTILS_ERROR_UNKNOWN,
"couldn't open netdir");
goto out_idle;
}
total = nm_platform_sysctl_get_int_checked (platform,
NMP_SYSCTL_PATHID_NETDIR (dirfd,
ifname,
"device/sriov_totalvfs"),
10, 0, G_MAXUINT, 0);
if (errno)
return FALSE;
if (errno) {
g_set_error (&error,
NM_UTILS_ERROR,
NM_UTILS_ERROR_UNKNOWN,
"failed reading sriov_totalvfs value: %s",
nm_strerror_native (errno));
goto out_idle;
}
if (num_vfs > total) {
_LOGW ("link: %d only supports %u VFs (requested %u)", ifindex, total, num_vfs);
num_vfs = total;
@ -6672,23 +6913,7 @@ link_set_sriov_params (NMPlatform *platform,
if ( current_num == num_vfs
&& (autoprobe == NM_TERNARY_DEFAULT || current_autoprobe == autoprobe))
return TRUE;
if (current_num != 0) {
/* We need to destroy all other VFs before changing any value */
if (!nm_platform_sysctl_set (NM_PLATFORM_GET,
NMP_SYSCTL_PATHID_NETDIR (dirfd,
ifname,
"device/sriov_numvfs"),
"0")) {
errsv = errno;
_LOGW ("link: couldn't reset SR-IOV num_vfs: %s", nm_strerror_native (errsv));
return FALSE;
}
}
if (num_vfs == 0)
return TRUE;
goto out_idle;
if ( NM_IN_SET (autoprobe, NM_TERNARY_TRUE, NM_TERNARY_FALSE)
&& current_autoprobe != autoprobe
@ -6697,22 +6922,40 @@ link_set_sriov_params (NMPlatform *platform,
ifname,
"device/sriov_drivers_autoprobe"),
nm_sprintf_buf (buf, "%d", (int) autoprobe))) {
errsv = errno;
_LOGW ("link: couldn't set SR-IOV drivers-autoprobe to %d: %s", (int) autoprobe, nm_strerror_native (errsv));
return FALSE;
g_set_error (&error,
NM_UTILS_ERROR,
NM_UTILS_ERROR_UNKNOWN,
"couldn't set SR-IOV drivers-autoprobe to %d: %s",
(int) autoprobe, nm_strerror_native (errno));
goto out_idle;
}
if (!nm_platform_sysctl_set (NM_PLATFORM_GET,
NMP_SYSCTL_PATHID_NETDIR (dirfd,
ifname,
"device/sriov_numvfs"),
nm_sprintf_buf (buf, "%u", num_vfs))) {
errsv = errno;
_LOGW ("link: couldn't set SR-IOV num_vfs to %d: %s", num_vfs, nm_strerror_native (errsv));
return FALSE;
}
if (current_num == 0 && num_vfs == 0)
goto out_idle;
return TRUE;
i = 0;
if (current_num != 0)
values[i++] = "0";
if (num_vfs != 0)
values[i++] = nm_sprintf_bufa (32, "%u", num_vfs);
values[i++] = NULL;
sysctl_set_async (platform,
NMP_SYSCTL_PATHID_NETDIR (dirfd, ifname, "device/sriov_numvfs"),
values,
callback,
data,
cancellable);
return;
out_idle:
if (callback) {
packed = nm_utils_user_data_pack (g_object_ref (platform),
g_steal_pointer (&error),
callback,
data);
nm_utils_invoke_on_idle (sriov_idle_cb, packed, cancellable);
}
}
static gboolean
@ -8997,6 +9240,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
object_class->finalize = finalize;
platform_class->sysctl_set = sysctl_set;
platform_class->sysctl_set_async = sysctl_set_async;
platform_class->sysctl_get = sysctl_get;
platform_class->link_add = link_add;
@ -9020,7 +9264,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
platform_class->link_get_permanent_address = link_get_permanent_address;
platform_class->link_set_mtu = link_set_mtu;
platform_class->link_set_name = link_set_name;
platform_class->link_set_sriov_params = link_set_sriov_params;
platform_class->link_set_sriov_params_async = link_set_sriov_params_async;
platform_class->link_set_sriov_vfs = link_set_sriov_vfs;
platform_class->link_set_bridge_vlans = link_set_bridge_vlans;

View file

@ -481,6 +481,40 @@ nm_platform_sysctl_set (NMPlatform *self, const char *pathid, int dirfd, const c
return klass->sysctl_set (self, pathid, dirfd, path, value);
}
/**
* nm_platform_sysctl_set_async:
* @self: platform instance
* @pathid: if @dirfd is present, this must be the full path that is looked up
* @dirfd: optional file descriptor for parent directory for openat()
* @path: absolute option path
* @values: NULL-terminated array of strings to be written
* @callback: function called on termination
* @data: data passed to callback function
* @cancellable: to cancel the operation
*
* This function is intended to be used for writing values to sysctl-style
* virtual runtime configuration files. This includes not only /proc/sys
* but also for example /sys/class. The function does not block and returns
* immediately. The callback is always invoked, and asynchronously. The file
* is closed after writing each value and reopened to write the next one so
* that the function can be used safely on all /proc and /sys files,
* independently of how /proc/sys/kernel/sysctl_writes_strict is configured.
*/
void nm_platform_sysctl_set_async (NMPlatform *self,
const char *pathid,
int dirfd,
const char *path,
const char *const *values,
NMPlatformAsyncCallback callback,
gpointer data,
GCancellable *cancellable)
{
_CHECK_SELF_VOID (self, klass);
klass->sysctl_set_async (self, pathid, dirfd, path, values, callback, data, cancellable);
}
gboolean
nm_platform_sysctl_ip_conf_set_ipv6_hop_limit_safe (NMPlatform *self,
const char *iface,
@ -623,14 +657,14 @@ nm_platform_sysctl_get_int_checked (NMPlatform *self,
/*****************************************************************************/
char *
nm_platform_sysctl_ip_conf_get (NMPlatform *platform,
nm_platform_sysctl_ip_conf_get (NMPlatform *self,
int addr_family,
const char *ifname,
const char *property)
{
char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
return nm_platform_sysctl_get (platform,
return nm_platform_sysctl_get (self,
NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (addr_family,
buf,
ifname,
@ -638,7 +672,7 @@ nm_platform_sysctl_ip_conf_get (NMPlatform *platform,
}
gint64
nm_platform_sysctl_ip_conf_get_int_checked (NMPlatform *platform,
nm_platform_sysctl_ip_conf_get_int_checked (NMPlatform *self,
int addr_family,
const char *ifname,
const char *property,
@ -649,7 +683,7 @@ nm_platform_sysctl_ip_conf_get_int_checked (NMPlatform *platform,
{
char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
return nm_platform_sysctl_get_int_checked (platform,
return nm_platform_sysctl_get_int_checked (self,
NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (addr_family,
buf,
ifname,
@ -661,7 +695,7 @@ nm_platform_sysctl_ip_conf_get_int_checked (NMPlatform *platform,
}
gboolean
nm_platform_sysctl_ip_conf_set (NMPlatform *platform,
nm_platform_sysctl_ip_conf_set (NMPlatform *self,
int addr_family,
const char *ifname,
const char *property,
@ -669,7 +703,7 @@ nm_platform_sysctl_ip_conf_set (NMPlatform *platform,
{
char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
return nm_platform_sysctl_set (platform,
return nm_platform_sysctl_set (self,
NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (addr_family,
buf,
ifname,
@ -678,7 +712,7 @@ nm_platform_sysctl_ip_conf_set (NMPlatform *platform,
}
gboolean
nm_platform_sysctl_ip_conf_set_int64 (NMPlatform *platform,
nm_platform_sysctl_ip_conf_set_int64 (NMPlatform *self,
int addr_family,
const char *ifname,
const char *property,
@ -687,7 +721,7 @@ nm_platform_sysctl_ip_conf_set_int64 (NMPlatform *platform,
char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
char s[64];
return nm_platform_sysctl_set (platform,
return nm_platform_sysctl_set (self,
NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (addr_family,
buf,
ifname,
@ -1553,19 +1587,35 @@ nm_platform_link_supports_sriov (NMPlatform *self, int ifindex)
* @num_vfs: the number of VFs to create
* @autoprobe: the new autoprobe-drivers value (pass
* %NM_TERNARY_DEFAULT to keep current value)
* @callback: called when the operation finishes
* @callback_data: data passed to @callback
* @cancellable: cancellable to abort the operation
*
* Sets SR-IOV parameters asynchronously without
* blocking the main thread. The callback function is
* always invoked, and asynchronously.
*/
gboolean
nm_platform_link_set_sriov_params (NMPlatform *self,
int ifindex,
guint num_vfs,
NMTernary autoprobe)
void
nm_platform_link_set_sriov_params_async (NMPlatform *self,
int ifindex,
guint num_vfs,
NMTernary autoprobe,
NMPlatformAsyncCallback callback,
gpointer callback_data,
GCancellable *cancellable)
{
_CHECK_SELF (self, klass, FALSE);
_CHECK_SELF_VOID (self, klass);
g_return_val_if_fail (ifindex > 0, FALSE);
g_return_if_fail (ifindex > 0);
_LOG3D ("link: setting %u total VFs and autoprobe %d", num_vfs, (int) autoprobe);
return klass->link_set_sriov_params (self, ifindex, num_vfs, autoprobe);
klass->link_set_sriov_params_async (self,
ifindex,
num_vfs,
autoprobe,
callback,
callback_data,
cancellable);
}
gboolean
@ -3402,21 +3452,21 @@ nm_platform_ethtool_set_features (NMPlatform *self,
/*****************************************************************************/
const NMDedupMultiHeadEntry *
nm_platform_lookup_all (NMPlatform *platform,
nm_platform_lookup_all (NMPlatform *self,
NMPCacheIdType cache_id_type,
const NMPObject *obj)
{
return nmp_cache_lookup_all (nm_platform_get_cache (platform),
return nmp_cache_lookup_all (nm_platform_get_cache (self),
cache_id_type,
obj);
}
const NMDedupMultiEntry *
nm_platform_lookup_entry (NMPlatform *platform,
nm_platform_lookup_entry (NMPlatform *self,
NMPCacheIdType cache_id_type,
const NMPObject *obj)
{
return nmp_cache_lookup_entry_with_idx_type (nm_platform_get_cache (platform),
return nmp_cache_lookup_entry_with_idx_type (nm_platform_get_cache (self),
cache_id_type,
obj);
}

View file

@ -895,6 +895,8 @@ typedef enum {
} NMPlatformWireGuardChangePeerFlags;
typedef void (*NMPlatformAsyncCallback) (GError *error, gpointer user_data);
/*****************************************************************************/
typedef enum {
@ -953,64 +955,75 @@ struct _NMPlatform {
typedef struct {
GObjectClass parent;
gboolean (*sysctl_set) (NMPlatform *, const char *pathid, int dirfd, const char *path, const char *value);
char * (*sysctl_get) (NMPlatform *, const char *pathid, int dirfd, const char *path);
gboolean (*sysctl_set) (NMPlatform *self, const char *pathid, int dirfd, const char *path, const char *value);
void (*sysctl_set_async) (NMPlatform *self,
const char *pathid,
int dirfd,
const char *path,
const char *const *values,
NMPlatformAsyncCallback callback,
gpointer data,
GCancellable *cancellable);
char * (*sysctl_get) (NMPlatform *self, const char *pathid, int dirfd, const char *path);
int (*link_add) (NMPlatform *,
void (*refresh_all) (NMPlatform *self, NMPObjectType obj_type);
void (*process_events) (NMPlatform *self);
int (*link_add) (NMPlatform *self,
const char *name,
NMLinkType type,
const char *veth_peer,
const void *address,
size_t address_len,
const NMPlatformLink **out_link);
gboolean (*link_delete) (NMPlatform *, int ifindex);
gboolean (*link_refresh) (NMPlatform *, int ifindex);
gboolean (*link_set_netns) (NMPlatform *, int ifindex, int netns_fd);
void (*process_events) (NMPlatform *self);
gboolean (*link_set_up) (NMPlatform *, int ifindex, gboolean *out_no_firmware);
gboolean (*link_set_down) (NMPlatform *, int ifindex);
gboolean (*link_set_arp) (NMPlatform *, int ifindex);
gboolean (*link_set_noarp) (NMPlatform *, int ifindex);
gboolean (*link_delete) (NMPlatform *self, int ifindex);
gboolean (*link_refresh) (NMPlatform *self, int ifindex);
gboolean (*link_set_netns) (NMPlatform *self, int ifindex, int netns_fd);
gboolean (*link_set_up) (NMPlatform *self, int ifindex, gboolean *out_no_firmware);
gboolean (*link_set_down) (NMPlatform *self, int ifindex);
gboolean (*link_set_arp) (NMPlatform *self, int ifindex);
gboolean (*link_set_noarp) (NMPlatform *self, int ifindex);
const char *(*link_get_udi) (NMPlatform *self, int ifindex);
struct udev_device *(*link_get_udev_device) (NMPlatform *self, int ifindex);
int (*link_set_user_ipv6ll_enabled) (NMPlatform *, int ifindex, gboolean enabled);
gboolean (*link_set_token) (NMPlatform *, int ifindex, NMUtilsIPv6IfaceId iid);
int (*link_set_user_ipv6ll_enabled) (NMPlatform *self, int ifindex, gboolean enabled);
gboolean (*link_set_token) (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid);
gboolean (*link_get_permanent_address) (NMPlatform *,
gboolean (*link_get_permanent_address) (NMPlatform *self,
int ifindex,
guint8 *buf,
size_t *length);
int (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length);
int (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu);
gboolean (*link_set_name) (NMPlatform *, int ifindex, const char *name);
gboolean (*link_set_sriov_params) (NMPlatform *, int ifindex, guint num_vfs, int autoprobe);
int (*link_set_address) (NMPlatform *self, int ifindex, gconstpointer address, size_t length);
int (*link_set_mtu) (NMPlatform *self, int ifindex, guint32 mtu);
gboolean (*link_set_name) (NMPlatform *self, int ifindex, const char *name);
void (*link_set_sriov_params_async) (NMPlatform *self,
int ifindex,
guint num_vfs,
int autoprobe,
NMPlatformAsyncCallback callback,
gpointer callback_data,
GCancellable *cancellable);
gboolean (*link_set_sriov_vfs) (NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs);
gboolean (*link_set_bridge_vlans) (NMPlatform *self, int ifindex, gboolean on_master, const NMPlatformBridgeVlan *const *vlans);
char * (*link_get_physical_port_id) (NMPlatform *, int ifindex);
guint (*link_get_dev_id) (NMPlatform *, int ifindex);
gboolean (*link_get_wake_on_lan) (NMPlatform *, int ifindex);
gboolean (*link_get_driver_info) (NMPlatform *,
char * (*link_get_physical_port_id) (NMPlatform *self, int ifindex);
guint (*link_get_dev_id) (NMPlatform *self, int ifindex);
gboolean (*link_get_wake_on_lan) (NMPlatform *self, int ifindex);
gboolean (*link_get_driver_info) (NMPlatform *self,
int ifindex,
char **out_driver_name,
char **out_driver_version,
char **out_fw_version);
gboolean (*link_supports_carrier_detect) (NMPlatform *, int ifindex);
gboolean (*link_supports_vlans) (NMPlatform *, int ifindex);
gboolean (*link_supports_sriov) (NMPlatform *, int ifindex);
gboolean (*link_supports_carrier_detect) (NMPlatform *self, int ifindex);
gboolean (*link_supports_vlans) (NMPlatform *self, int ifindex);
gboolean (*link_supports_sriov) (NMPlatform *self, int ifindex);
gboolean (*link_enslave) (NMPlatform *, int master, int slave);
gboolean (*link_release) (NMPlatform *, int master, int slave);
gboolean (*link_enslave) (NMPlatform *self, int master, int slave);
gboolean (*link_release) (NMPlatform *self, int master, int slave);
gboolean (*link_can_assume) (NMPlatform *, int ifindex);
gboolean (*link_can_assume) (NMPlatform *self, int ifindex);
int (*link_wireguard_change) (NMPlatform *self,
int ifindex,
@ -1020,7 +1033,7 @@ typedef struct {
guint peers_len,
NMPlatformWireGuardChangeFlags change_flags);
gboolean (*vlan_add) (NMPlatform *, const char *name, int parent, int vlanid, guint32 vlanflags, const NMPlatformLink **out_link);
gboolean (*vlan_add) (NMPlatform *self, const char *name, int parent, int vlanid, guint32 vlanflags, const NMPlatformLink **out_link);
gboolean (*link_vlan_change) (NMPlatform *self,
int ifindex,
NMVlanFlags flags_mask,
@ -1031,81 +1044,79 @@ typedef struct {
gboolean egress_reset_all,
const NMVlanQosMapping *egress_map,
gsize n_egress_map);
gboolean (*link_vxlan_add) (NMPlatform *,
gboolean (*link_vxlan_add) (NMPlatform *self,
const char *name,
const NMPlatformLnkVxlan *props,
const NMPlatformLink **out_link);
gboolean (*link_gre_add) (NMPlatform *,
gboolean (*link_gre_add) (NMPlatform *self,
const char *name,
const NMPlatformLnkGre *props,
const NMPlatformLink **out_link);
gboolean (*link_ip6tnl_add) (NMPlatform *,
gboolean (*link_ip6tnl_add) (NMPlatform *self,
const char *name,
const NMPlatformLnkIp6Tnl *props,
const NMPlatformLink **out_link);
gboolean (*link_ip6gre_add) (NMPlatform *,
gboolean (*link_ip6gre_add) (NMPlatform *self,
const char *name,
const NMPlatformLnkIp6Tnl *props,
const NMPlatformLink **out_link);
gboolean (*link_ipip_add) (NMPlatform *,
gboolean (*link_ipip_add) (NMPlatform *self,
const char *name,
const NMPlatformLnkIpIp *props,
const NMPlatformLink **out_link);
gboolean (*link_macsec_add) (NMPlatform *,
gboolean (*link_macsec_add) (NMPlatform *self,
const char *name,
int parent,
const NMPlatformLnkMacsec *props,
const NMPlatformLink **out_link);
gboolean (*link_macvlan_add) (NMPlatform *,
gboolean (*link_macvlan_add) (NMPlatform *self,
const char *name,
int parent,
const NMPlatformLnkMacvlan *props,
const NMPlatformLink **out_link);
gboolean (*link_sit_add) (NMPlatform *,
gboolean (*link_sit_add) (NMPlatform *self,
const char *name,
const NMPlatformLnkSit *props,
const NMPlatformLink **out_link);
gboolean (*link_tun_add) (NMPlatform *platform,
gboolean (*link_tun_add) (NMPlatform *self,
const char *name,
const NMPlatformLnkTun *props,
const NMPlatformLink **out_link,
int *out_fd);
gboolean (*link_6lowpan_add) (NMPlatform *platform,
gboolean (*link_6lowpan_add) (NMPlatform *self,
const char *name,
int parent,
const NMPlatformLink **out_link);
gboolean (*infiniband_partition_add) (NMPlatform *, int parent, int p_key, const NMPlatformLink **out_link);
gboolean (*infiniband_partition_delete) (NMPlatform *, int parent, int p_key);
gboolean (*infiniband_partition_add) (NMPlatform *self, int parent, int p_key, const NMPlatformLink **out_link);
gboolean (*infiniband_partition_delete) (NMPlatform *self, int parent, int p_key);
gboolean (*wifi_get_capabilities) (NMPlatform *, int ifindex, NMDeviceWifiCapabilities *caps);
gboolean (*wifi_get_bssid) (NMPlatform *, int ifindex, guint8 *bssid);
guint32 (*wifi_get_frequency) (NMPlatform *, int ifindex);
int (*wifi_get_quality) (NMPlatform *, int ifindex);
guint32 (*wifi_get_rate) (NMPlatform *, int ifindex);
NM80211Mode (*wifi_get_mode) (NMPlatform *, int ifindex);
void (*wifi_set_mode) (NMPlatform *, int ifindex, NM80211Mode mode);
void (*wifi_set_powersave) (NMPlatform *, int ifindex, guint32 powersave);
guint32 (*wifi_find_frequency) (NMPlatform *, int ifindex, const guint32 *freqs);
void (*wifi_indicate_addressing_running) (NMPlatform *, int ifindex, gboolean running);
NMSettingWirelessWakeOnWLan (*wifi_get_wake_on_wlan) (NMPlatform *, int ifindex);
gboolean (*wifi_set_wake_on_wlan) (NMPlatform *, int ifindex, NMSettingWirelessWakeOnWLan wowl);
gboolean (*wifi_get_capabilities) (NMPlatform *self, int ifindex, NMDeviceWifiCapabilities *caps);
gboolean (*wifi_get_bssid) (NMPlatform *self, int ifindex, guint8 *bssid);
guint32 (*wifi_get_frequency) (NMPlatform *self, int ifindex);
int (*wifi_get_quality) (NMPlatform *self, int ifindex);
guint32 (*wifi_get_rate) (NMPlatform *self, int ifindex);
NM80211Mode (*wifi_get_mode) (NMPlatform *self, int ifindex);
void (*wifi_set_mode) (NMPlatform *self, int ifindex, NM80211Mode mode);
void (*wifi_set_powersave) (NMPlatform *self, int ifindex, guint32 powersave);
guint32 (*wifi_find_frequency) (NMPlatform *self, int ifindex, const guint32 *freqs);
void (*wifi_indicate_addressing_running) (NMPlatform *self, int ifindex, gboolean running);
NMSettingWirelessWakeOnWLan (*wifi_get_wake_on_wlan) (NMPlatform *self, int ifindex);
gboolean (*wifi_set_wake_on_wlan) (NMPlatform *self, int ifindex, NMSettingWirelessWakeOnWLan wowl);
guint32 (*mesh_get_channel) (NMPlatform *, int ifindex);
gboolean (*mesh_set_channel) (NMPlatform *, int ifindex, guint32 channel);
gboolean (*mesh_set_ssid) (NMPlatform *, int ifindex, const guint8 *ssid, gsize len);
guint32 (*mesh_get_channel) (NMPlatform *self, int ifindex);
gboolean (*mesh_set_channel) (NMPlatform *self, int ifindex, guint32 channel);
gboolean (*mesh_set_ssid) (NMPlatform *self, int ifindex, const guint8 *ssid, gsize len);
guint16 (*wpan_get_pan_id) (NMPlatform *, int ifindex);
gboolean (*wpan_set_pan_id) (NMPlatform *, int ifindex, guint16 pan_id);
guint16 (*wpan_get_short_addr) (NMPlatform *, int ifindex);
gboolean (*wpan_set_short_addr) (NMPlatform *, int ifindex, guint16 short_addr);
gboolean (*wpan_set_channel) (NMPlatform *, int ifindex, guint8 page, guint8 channel);
guint16 (*wpan_get_pan_id) (NMPlatform *self, int ifindex);
gboolean (*wpan_set_pan_id) (NMPlatform *self, int ifindex, guint16 pan_id);
guint16 (*wpan_get_short_addr) (NMPlatform *self, int ifindex);
gboolean (*wpan_set_short_addr) (NMPlatform *self, int ifindex, guint16 short_addr);
gboolean (*wpan_set_channel) (NMPlatform *self, int ifindex, guint8 page, guint8 channel);
gboolean (*object_delete) (NMPlatform *, const NMPObject *obj);
gboolean (*object_delete) (NMPlatform *self, const NMPObject *obj);
gboolean (*ip4_address_add) (NMPlatform *,
gboolean (*ip4_address_add) (NMPlatform *self,
int ifindex,
in_addr_t address,
guint8 plen,
@ -1114,7 +1125,7 @@ typedef struct {
guint32 preferred_lft,
guint32 flags,
const char *label);
gboolean (*ip6_address_add) (NMPlatform *,
gboolean (*ip6_address_add) (NMPlatform *self,
int ifindex,
struct in6_addr address,
guint8 plen,
@ -1122,10 +1133,10 @@ typedef struct {
guint32 lifetime,
guint32 preferred_lft,
guint32 flags);
gboolean (*ip4_address_delete) (NMPlatform *, int ifindex, in_addr_t address, guint8 plen, in_addr_t peer_address);
gboolean (*ip6_address_delete) (NMPlatform *, int ifindex, struct in6_addr address, guint8 plen);
gboolean (*ip4_address_delete) (NMPlatform *self, int ifindex, in_addr_t address, guint8 plen, in_addr_t peer_address);
gboolean (*ip6_address_delete) (NMPlatform *self, int ifindex, struct in6_addr address, guint8 plen);
int (*ip_route_add) (NMPlatform *,
int (*ip_route_add) (NMPlatform *self,
NMPNlmFlags flags,
int addr_family,
const NMPlatformIPRoute *route);
@ -1268,7 +1279,7 @@ gboolean nm_platform_get_use_udev (NMPlatform *self);
gboolean nm_platform_get_log_with_ptr (NMPlatform *self);
NMPNetns *nm_platform_netns_get (NMPlatform *self);
gboolean nm_platform_netns_push (NMPlatform *platform, NMPNetns **netns);
gboolean nm_platform_netns_push (NMPlatform *self, NMPNetns **netns);
const char *nm_link_type_to_string (NMLinkType link_type);
@ -1294,16 +1305,24 @@ const char *nm_link_type_to_string (NMLinkType link_type);
int nm_platform_sysctl_open_netdir (NMPlatform *self, int ifindex, char *out_ifname);
gboolean nm_platform_sysctl_set (NMPlatform *self, const char *pathid, int dirfd, const char *path, const char *value);
void nm_platform_sysctl_set_async (NMPlatform *self,
const char *pathid,
int dirfd,
const char *path,
const char *const *values,
NMPlatformAsyncCallback callback,
gpointer data,
GCancellable *cancellable);
char *nm_platform_sysctl_get (NMPlatform *self, const char *pathid, int dirfd, const char *path);
gint32 nm_platform_sysctl_get_int32 (NMPlatform *self, const char *pathid, int dirfd, const char *path, gint32 fallback);
gint64 nm_platform_sysctl_get_int_checked (NMPlatform *self, const char *pathid, int dirfd, const char *path, guint base, gint64 min, gint64 max, gint64 fallback);
char *nm_platform_sysctl_ip_conf_get (NMPlatform *platform,
char *nm_platform_sysctl_ip_conf_get (NMPlatform *self,
int addr_family,
const char *ifname,
const char *property);
gint64 nm_platform_sysctl_ip_conf_get_int_checked (NMPlatform *platform,
gint64 nm_platform_sysctl_ip_conf_get_int_checked (NMPlatform *self,
int addr_family,
const char *ifname,
const char *property,
@ -1312,13 +1331,13 @@ gint64 nm_platform_sysctl_ip_conf_get_int_checked (NMPlatform *platform,
gint64 max,
gint64 fallback);
gboolean nm_platform_sysctl_ip_conf_set (NMPlatform *platform,
gboolean nm_platform_sysctl_ip_conf_set (NMPlatform *self,
int addr_family,
const char *ifname,
const char *property,
const char *value);
gboolean nm_platform_sysctl_ip_conf_set_int64 (NMPlatform *platform,
gboolean nm_platform_sysctl_ip_conf_set_int64 (NMPlatform *self,
int addr_family,
const char *ifname,
const char *property,
@ -1351,7 +1370,7 @@ gboolean nm_platform_link_set_netns (NMPlatform *self, int ifindex, int netns_fd
struct _NMDedupMultiHeadEntry;
struct _NMPLookup;
const struct _NMDedupMultiHeadEntry *nm_platform_lookup (NMPlatform *platform,
const struct _NMDedupMultiHeadEntry *nm_platform_lookup (NMPlatform *self,
const struct _NMPLookup *lookup);
gboolean nm_platform_lookup_predicate_routes_main (const NMPObject *obj,
@ -1359,7 +1378,7 @@ gboolean nm_platform_lookup_predicate_routes_main (const NMPObject *obj,
gboolean nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel (const NMPObject *obj,
gpointer user_data);
GPtrArray *nm_platform_lookup_clone (NMPlatform *platform,
GPtrArray *nm_platform_lookup_clone (NMPlatform *self,
const struct _NMPLookup *lookup,
NMPObjectPredicateFunc predicate,
gpointer user_data);
@ -1421,7 +1440,15 @@ gboolean nm_platform_link_get_permanent_address (NMPlatform *self, int ifindex,
int nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length);
int nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu);
gboolean nm_platform_link_set_name (NMPlatform *self, int ifindex, const char *name);
gboolean nm_platform_link_set_sriov_params (NMPlatform *self, int ifindex, guint num_vfs, int autoprobe);
void nm_platform_link_set_sriov_params_async (NMPlatform *self,
int ifindex,
guint num_vfs,
int autoprobe,
NMPlatformAsyncCallback callback,
gpointer callback_data,
GCancellable *cancellable);
gboolean nm_platform_link_set_sriov_vfs (NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs);
gboolean nm_platform_link_set_bridge_vlans (NMPlatform *self, int ifindex, gboolean on_master, const NMPlatformBridgeVlan *const *vlans);
@ -1519,11 +1546,11 @@ guint32 nm_platform_mesh_get_channel (NMPlatform *self, int ifindex);
gboolean nm_platform_mesh_set_channel (NMPlatform *self, int ifindex, guint32 channel);
gboolean nm_platform_mesh_set_ssid (NMPlatform *self, int ifindex, const guint8 *ssid, gsize len);
guint16 nm_platform_wpan_get_pan_id (NMPlatform *platform, int ifindex);
gboolean nm_platform_wpan_set_pan_id (NMPlatform *platform, int ifindex, guint16 pan_id);
guint16 nm_platform_wpan_get_short_addr (NMPlatform *platform, int ifindex);
gboolean nm_platform_wpan_set_short_addr (NMPlatform *platform, int ifindex, guint16 short_addr);
gboolean nm_platform_wpan_set_channel (NMPlatform *platform, int ifindex, guint8 page, guint8 channel);
guint16 nm_platform_wpan_get_pan_id (NMPlatform *self, int ifindex);
gboolean nm_platform_wpan_set_pan_id (NMPlatform *self, int ifindex, guint16 pan_id);
guint16 nm_platform_wpan_get_short_addr (NMPlatform *self, int ifindex);
gboolean nm_platform_wpan_set_short_addr (NMPlatform *self, int ifindex, guint16 short_addr);
gboolean nm_platform_wpan_set_channel (NMPlatform *self, int ifindex, guint8 page, guint8 channel);
void nm_platform_ip4_address_set_addr (NMPlatformIP4Address *addr, in_addr_t address, guint8 plen);
const struct in6_addr *nm_platform_ip6_address_get_peer (const NMPlatformIP6Address *addr);

View file

@ -3015,6 +3015,92 @@ test_sysctl_netns_switch (void)
nmtstp_link_delete (PL, FALSE, ifindex, NULL, TRUE);
}
static void
sysctl_set_async_cb_assert_success (GError *error, gpointer data)
{
g_assert_no_error (error);
g_main_loop_quit (data);
}
static void
sysctl_set_async_cb_assert_failure (GError *error, gpointer data)
{
g_assert (error);
g_main_loop_quit (data);
}
static void
test_sysctl_set_async (void)
{
NMPlatform *const PL = NM_PLATFORM_GET;
const char *const IFNAME = "nm-dummy-0";
const char *const PATH = "/proc/sys/net/ipv4/conf/nm-dummy-0/rp_filter";
gs_free GMainLoop *loop = NULL;
gs_unref_object GCancellable *cancellable = NULL;
int ifindex;
ifindex = nmtstp_link_dummy_add (PL, -1, IFNAME)->ifindex;
loop = g_main_loop_new (NULL, FALSE);
cancellable = g_cancellable_new ();
nm_platform_sysctl_set_async (PL,
NMP_SYSCTL_PATHID_ABSOLUTE (PATH),
(const char *[]) { "2", NULL},
sysctl_set_async_cb_assert_success,
loop,
cancellable);
if (!nmtst_main_loop_run (loop, 1000))
g_assert_not_reached ();
g_assert_cmpint (nm_platform_sysctl_get_int32 (PL, NMP_SYSCTL_PATHID_ABSOLUTE (PATH), -1),
==,
2);
nm_platform_sysctl_set_async (PL,
NMP_SYSCTL_PATHID_ABSOLUTE (PATH),
(const char *[]) { "2", "0", "1", "0", "1", NULL},
sysctl_set_async_cb_assert_success,
loop,
cancellable);
if (!nmtst_main_loop_run (loop, 2000))
g_assert_not_reached ();
g_assert_cmpint (nm_platform_sysctl_get_int32 (PL, NMP_SYSCTL_PATHID_ABSOLUTE (PATH), -1),
==,
1);
nmtstp_link_delete (NULL, -1, ifindex, IFNAME, TRUE);
}
static void
test_sysctl_set_async_fail (void)
{
NMPlatform *const PL = NM_PLATFORM_GET;
const char *const IFNAME = "nm-dummy-0";
const char *const PATH = "/proc/sys/net/ipv4/conf/nm-dummy-0/does-not-exist";
gs_free GMainLoop *loop = NULL;
gs_unref_object GCancellable *cancellable = NULL;
int ifindex;
ifindex = nmtstp_link_dummy_add (PL, -1, IFNAME)->ifindex;
loop = g_main_loop_new (NULL, FALSE);
cancellable = g_cancellable_new ();
nm_platform_sysctl_set_async (PL,
NMP_SYSCTL_PATHID_ABSOLUTE (PATH),
(const char *[]) { "2", NULL},
sysctl_set_async_cb_assert_failure,
loop,
cancellable);
if (!nmtst_main_loop_run (loop, 1000))
g_assert_not_reached ();
nmtstp_link_delete (NULL, -1, ifindex, IFNAME, TRUE);
}
/*****************************************************************************/
static gpointer
@ -3238,6 +3324,8 @@ _nmtstp_setup_tests (void)
g_test_add_func ("/general/sysctl/rename", test_sysctl_rename);
g_test_add_func ("/general/sysctl/netns-switch", test_sysctl_netns_switch);
g_test_add_func ("/general/sysctl/set-async", test_sysctl_set_async);
g_test_add_func ("/general/sysctl/set-async-fail", test_sysctl_set_async_fail);
g_test_add_func ("/link/ethtool/features/get", test_ethtool_features_get);
}