static gboolean complete_connection (NMDevice *device, NMConnection *connection, const char *specific_object, const GSList *existing_connections, GError **error) { NMSettingTeam *s_team, *tmp; guint32 i = 0; char *name; const GSList *iter; gboolean found; nm_utils_complete_generic (connection, NM_SETTING_TEAM_SETTING_NAME, existing_connections, _("Team connection %d"), NULL, TRUE); s_team = nm_connection_get_setting_team (connection); if (!s_team) { s_team = (NMSettingTeam *) nm_setting_team_new (); nm_connection_add_setting (connection, NM_SETTING (s_team)); } /* Grab the first name that doesn't exist in either our connections * or a device on the system. */ while (i < 500 && !nm_setting_team_get_interface_name (s_team)) { name = g_strdup_printf ("team%u", i); /* check interface names */ if (!nm_platform_link_exists (name)) { /* check existing team connections */ for (iter = existing_connections, found = FALSE; iter; iter = g_slist_next (iter)) { NMConnection *candidate = iter->data; tmp = nm_connection_get_setting_team (candidate); if (tmp && nm_connection_is_type (candidate, NM_SETTING_TEAM_SETTING_NAME)) { if (g_strcmp0 (nm_setting_team_get_interface_name (tmp), name) == 0) { found = TRUE; break; } } } if (!found) g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_INTERFACE_NAME, name, NULL); } g_free (name); i++; } return TRUE; }
static void nmt_page_team_constructed (GObject *object) { NmtPageTeam *team = NMT_PAGE_TEAM (object); NmtPageTeamPrivate *priv = NMT_PAGE_TEAM_GET_PRIVATE (team); NmtEditorSection *section; NmtNewtGrid *grid; NMSettingTeam *s_team; NmtNewtWidget *widget; NMConnection *conn; conn = nmt_editor_page_get_connection (NMT_EDITOR_PAGE (team)); s_team = nm_connection_get_setting_team (conn); if (!s_team) { nm_connection_add_setting (conn, nm_setting_team_new ()); s_team = nm_connection_get_setting_team (conn); } priv->s_team = s_team; section = nmt_editor_section_new (_("TEAM"), NULL, TRUE); widget = nmt_newt_grid_new (); nmt_editor_grid_append (nmt_editor_section_get_body (section), NULL, widget, NULL); grid = NMT_NEWT_GRID (widget); widget = nmt_newt_label_new (_("Slaves")); nmt_newt_grid_add (grid, widget, 0, 0); widget = nmt_slave_list_new (conn, team_connection_type_filter, team); g_signal_connect (widget, "notify::connections", G_CALLBACK (slaves_changed), team); nmt_newt_grid_add (grid, widget, 0, 1); nmt_newt_widget_set_padding (widget, 0, 0, 0, 1); priv->slaves = NMT_SLAVE_LIST (widget); slaves_changed (G_OBJECT (priv->slaves), NULL, team); widget = nmt_newt_label_new (_("JSON configuration")); nmt_newt_grid_add (grid, widget, 0, 2); widget = nmt_newt_textbox_new (NMT_NEWT_TEXTBOX_SCROLLABLE | NMT_NEWT_TEXTBOX_SET_BACKGROUND, 60); g_object_bind_property (s_team, NM_SETTING_TEAM_CONFIG, widget, "text", G_BINDING_SYNC_CREATE); nmt_newt_grid_add (grid, widget, 0, 3); nmt_newt_widget_set_padding (widget, 2, 0, 2, 1); widget = nmt_newt_button_new (_("Edit...")); g_signal_connect (widget, "clicked", G_CALLBACK (edit_clicked), team); nmt_newt_grid_add (grid, widget, 0, 4); nmt_editor_page_add_section (NMT_EDITOR_PAGE (team), section); G_OBJECT_CLASS (nmt_page_team_parent_class)->constructed (object); }
static void teamd_dbus_vanished (GDBusConnection *dbus_connection, const gchar *name, gpointer user_data) { NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); NMDevice *device = NM_DEVICE (self); NMDeviceState state = nm_device_get_state (device); g_return_if_fail (priv->teamd_dbus_watch); if (!priv->tdc) { /* g_bus_watch_name will always raise an initial signal, to indicate whether the * name exists/not exists initially. Do not take this as a failure if it hadn't * previously appeared. */ _LOGD (LOGD_TEAM, "teamd not on D-Bus (ignored)"); return; } _LOGI (LOGD_TEAM, "teamd vanished from D-Bus"); teamd_cleanup (device, TRUE); /* Attempt to respawn teamd */ if (state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_ACTIVATED) { NMConnection *connection = nm_device_get_applied_connection (device); g_assert (connection); if (!teamd_start (device, nm_connection_get_setting_team (connection))) nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); } }
static void update_connection (NMDevice *device, NMConnection *connection) { NMDeviceTeam *self = NM_DEVICE_TEAM (device); NMSettingTeam *s_team = nm_connection_get_setting_team (connection); NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); if (!s_team) { s_team = (NMSettingTeam *) nm_setting_team_new (); nm_connection_add_setting (connection, (NMSetting *) s_team); } g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_CONFIG, NULL, NULL); if (priv->tdc) { const char *config = NULL; int err; err = teamdctl_config_get_raw_direct (NM_DEVICE_TEAM_GET_PRIVATE (device)->tdc, (char **)&config); if (err == 0) g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_CONFIG, config, NULL); else _LOGE (LOGD_TEAM, "failed to read teamd config (err=%d)", err); } }
static gboolean complete_connection (NMDevice *device, NMConnection *connection, const char *specific_object, const GSList *existing_connections, GError **error) { NMSettingTeam *s_team; nm_utils_complete_generic (NM_PLATFORM_GET, connection, NM_SETTING_TEAM_SETTING_NAME, existing_connections, NULL, _("Team connection"), "team", TRUE); s_team = nm_connection_get_setting_team (connection); if (!s_team) { s_team = (NMSettingTeam *) nm_setting_team_new (); nm_connection_add_setting (connection, NM_SETTING (s_team)); } return TRUE; }
static void update_connection (NMDevice *device, NMConnection *connection) { NMSettingTeam *s_team = nm_connection_get_setting_team (connection); const char *iface = nm_device_get_iface (device); if (!s_team) { s_team = (NMSettingTeam *) nm_setting_team_new (); nm_connection_add_setting (connection, (NMSetting *) s_team); g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_INTERFACE_NAME, iface, NULL); } g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_CONFIG, NULL, NULL); #if WITH_TEAMDCTL if (ensure_teamd_connection (device)) { const char *config = NULL; int err; err = teamdctl_config_get_raw_direct (NM_DEVICE_TEAM_GET_PRIVATE (device)->tdc, (char **)&config); if (err == 0) g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_CONFIG, config, NULL); else nm_log_err (LOGD_TEAM, "(%s): failed to read teamd config (err=%d)", iface, err); } #endif }
static gboolean check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) { const char *iface; NMSettingTeam *s_team; if (!NM_DEVICE_CLASS (nm_device_team_parent_class)->check_connection_compatible (device, connection, error)) return FALSE; s_team = nm_connection_get_setting_team (connection); if (!s_team || !nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME)) { g_set_error (error, NM_TEAM_ERROR, NM_TEAM_ERROR_CONNECTION_NOT_TEAM, "The connection was not a team connection."); return FALSE; } /* Team connections must specify the virtual interface name */ iface = nm_connection_get_virtual_iface_name (connection); if (!iface || strcmp (nm_device_get_iface (device), iface)) { g_set_error (error, NM_TEAM_ERROR, NM_TEAM_ERROR_CONNECTION_NOT_TEAM, "The team connection virtual interface name did not match."); return FALSE; } /* FIXME: match team properties like mode, etc? */ return TRUE; }
static NMActStageReturn act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) { NMDeviceTeam *self = NM_DEVICE_TEAM (device); NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; gs_free_error GError *error = NULL; NMConnection *connection; NMSettingTeam *s_team; const char *cfg; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); ret = NM_DEVICE_CLASS (nm_device_team_parent_class)->act_stage1_prepare (device, reason); if (ret != NM_ACT_STAGE_RETURN_SUCCESS) return ret; connection = nm_device_get_applied_connection (device); g_assert (connection); s_team = nm_connection_get_setting_team (connection); g_assert (s_team); if (priv->tdc) { /* If the existing teamd config is the same as we're about to use, * then we can proceed. If it's not the same, and we have a PID, * kill it so we can respawn it with the right config. If we don't * have a PID, then we must fail. */ cfg = teamdctl_config_get_raw (priv->tdc); if (cfg && strcmp (cfg, nm_setting_team_get_config (s_team)) == 0) { _LOGD (LOGD_TEAM, "using existing matching teamd config"); return NM_ACT_STAGE_RETURN_SUCCESS; } if (!priv->teamd_pid) { _LOGD (LOGD_TEAM, "existing teamd config mismatch; killing existing via teamdctl"); if (!teamd_kill (self, NULL, &error)) { _LOGW (LOGD_TEAM, "existing teamd config mismatch; failed to kill existing teamd: %s", error->message); *reason = NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED; return NM_ACT_STAGE_RETURN_FAILURE; } } _LOGD (LOGD_TEAM, "existing teamd config mismatch; respawning..."); teamd_cleanup (device, TRUE); } return teamd_start (device, s_team) ? NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_FAILURE; }
static gboolean check_connection_compatible (NMDevice *device, NMConnection *connection) { NMSettingTeam *s_team; if (!NM_DEVICE_CLASS (nm_device_team_parent_class)->check_connection_compatible (device, connection)) return FALSE; s_team = nm_connection_get_setting_team (connection); if (!s_team || !nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME)) return FALSE; /* FIXME: match team properties like mode, etc? */ return TRUE; }
static gboolean check_connection_compatible (NMDevice *device, NMConnection *connection) { const char *iface; NMSettingTeam *s_team; if (!NM_DEVICE_CLASS (nm_device_team_parent_class)->check_connection_compatible (device, connection)) return FALSE; s_team = nm_connection_get_setting_team (connection); if (!s_team || !nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME)) return FALSE; /* Team connections must specify the virtual interface name */ iface = nm_connection_get_interface_name (connection); if (!iface || strcmp (nm_device_get_iface (device), iface)) return FALSE; /* FIXME: match team properties like mode, etc? */ return TRUE; }
static NMActStageReturn act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) { NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (dev); NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; NMConnection *connection; NMSettingTeam *s_team; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); ret = NM_DEVICE_CLASS (nm_device_team_parent_class)->act_stage1_prepare (dev, reason); if (ret == NM_ACT_STAGE_RETURN_SUCCESS) { connection = nm_device_get_connection (dev); g_assert (connection); s_team = nm_connection_get_setting_team (connection); g_assert (s_team); if (teamd_start (dev, s_team, priv)) ret = NM_ACT_STAGE_RETURN_POSTPONE; else ret = NM_ACT_STAGE_RETURN_FAILURE; } return ret; }
static gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error) { NMSettingConnection *s_con; NMSettingTeam *s_team; const char *ctype, *dev_iface_name, *team_iface_name; s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); ctype = nm_setting_connection_get_connection_type (s_con); if (strcmp (ctype, NM_SETTING_TEAM_SETTING_NAME) != 0) { g_set_error (error, NM_DEVICE_TEAM_ERROR, NM_DEVICE_TEAM_ERROR_NOT_TEAM_CONNECTION, "The connection was not a team connection."); return FALSE; } s_team = nm_connection_get_setting_team (connection); if (!s_team) { g_set_error (error, NM_DEVICE_TEAM_ERROR, NM_DEVICE_TEAM_ERROR_INVALID_TEAM_CONNECTION, "The connection was not a valid team connection."); return FALSE; } dev_iface_name = nm_device_get_iface (device); team_iface_name = nm_setting_team_get_interface_name (s_team); if (g_strcmp0 (dev_iface_name, team_iface_name) != 0) { g_set_error (error, NM_DEVICE_TEAM_ERROR, NM_DEVICE_TEAM_ERROR_INTERFACE_MISMATCH, "The interfaces of the device and the connection didn't match."); return FALSE; } /* FIXME: check slaves? */ return NM_DEVICE_CLASS (nm_device_team_parent_class)->connection_compatible (device, connection, error); }