diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2017-08-30 18:00:45 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2017-08-30 22:11:57 +0200 |
commit | 7f32bf582cadda229c0754c7eeef9c905c9f2d5a (patch) | |
tree | eaed626c0ee57d37dc9f2191573a513c03ddf4da | |
parent | 062d6b253e910da28ff3397d1864c692104af3f2 (diff) | |
download | NetworkManager-bg/rh1415641.tar.gz |
team: wait the existing instance is killed before starting teamd againbg/rh1415641
teamd uses a PID file to guarantee a single instance is running for
each device. If we spawn a new teamd process without waiting the
termination of the existing one, the new process can fail:
<debug> [1486191713.2530] kill child process 'teamd' (2676): wait for process to terminate after sending SIGTERM (15) (send SIGKILL in 2000 milliseconds)...
...
<debug> [1486191713.2539] device[0x7f737f5d7c40] (team1): running: /usr/bin/teamd -o -n -U -D -N -t team1 -c {"runner": {"name": "activebackup"}} -gg
Using team device "team1".
Using PID file "/var/run/teamd/team1.pid"
This program is not intended to be run as root.
Daemon already running on PID 2676.
Failed: File exists
To avoid this, keep track that a kill is in progress and postpone the
start of teamd.
https://bugzilla.redhat.com/show_bug.cgi?id=1415641
-rw-r--r-- | src/devices/team/nm-device-team.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c index bf9fda7a9d..c8e2dfeb2a 100644 --- a/src/devices/team/nm-device-team.c +++ b/src/devices/team/nm-device-team.c @@ -56,6 +56,8 @@ typedef struct { guint teamd_read_timeout; guint teamd_dbus_watch; char *config; + gboolean kill_in_progress; + NMConnection *connection; } NMDeviceTeamPrivate; struct _NMDeviceTeam { @@ -288,6 +290,24 @@ master_update_slave_connection (NMDevice *self, } /*****************************************************************************/ +static void +teamd_cleanup_cb (pid_t pid, gboolean success, int child_status, void *user_data) +{ + NMDevice *device = NM_DEVICE (user_data); + NMDeviceTeam *self = (NMDeviceTeam *) device; + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + + priv->kill_in_progress = FALSE; + + if (priv->connection) { + _LOGt (LOGD_TEAM, "kill terminated, starting teamd..."); + if (!teamd_start (device, priv->connection)) + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); + g_clear_object (&priv->connection); + } + + g_object_unref (device); +} static void teamd_cleanup (NMDevice *device, gboolean free_tdc) @@ -299,7 +319,11 @@ teamd_cleanup (NMDevice *device, gboolean free_tdc) nm_clear_g_source (&priv->teamd_read_timeout); if (priv->teamd_pid > 0) { - nm_utils_kill_child_async (priv->teamd_pid, SIGTERM, LOGD_TEAM, "teamd", 2000, NULL, NULL); + priv->kill_in_progress = TRUE; + nm_utils_kill_child_async (priv->teamd_pid, SIGTERM, LOGD_TEAM, + "teamd", 2000, + teamd_cleanup_cb, + g_object_ref (device)); priv->teamd_pid = 0; } @@ -322,7 +346,7 @@ teamd_timeout_cb (gpointer user_data) if (priv->teamd_pid && !priv->tdc) { /* Timed out launching our own teamd process */ - _LOGW (LOGD_TEAM, "teamd timed out."); + _LOGW (LOGD_TEAM, "teamd timed out"); teamd_cleanup (device, TRUE); g_warn_if_fail (nm_device_is_activating (device)); @@ -645,6 +669,12 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) teamd_cleanup (device, TRUE); } + if (priv->kill_in_progress) { + _LOGt (LOGD_TEAM, "kill in progress, wait before starting teamd"); + priv->connection = g_object_ref (connection); + return NM_ACT_STAGE_RETURN_POSTPONE; + } + return teamd_start (device, connection) ? NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_FAILURE; } @@ -661,6 +691,8 @@ deactivate (NMDevice *device) if (!priv->teamd_pid) teamd_kill (self, NULL, NULL); teamd_cleanup (device, TRUE); + + g_clear_object (&priv->connection); } static gboolean |