summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2017-08-30 18:00:45 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2017-08-30 22:11:57 +0200
commit7f32bf582cadda229c0754c7eeef9c905c9f2d5a (patch)
treeeaed626c0ee57d37dc9f2191573a513c03ddf4da
parent062d6b253e910da28ff3397d1864c692104af3f2 (diff)
downloadNetworkManager-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.c36
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