dhcp: always clean up DHCP client watch callback when stopping DHCP
Also fix a bug where failure to start the DHCP client wouldn't be handled.
This commit is contained in:
@@ -215,13 +215,12 @@ dhclient_child_setup (gpointer user_data G_GNUC_UNUSED)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
GPid
|
||||||
nm_dhcp_client_start (NMDHCPDevice *device, NMSettingIP4Config *s_ip4)
|
nm_dhcp_client_start (NMDHCPDevice *device, NMSettingIP4Config *s_ip4)
|
||||||
{
|
{
|
||||||
GPtrArray *dhclient_argv = NULL;
|
GPtrArray *dhclient_argv = NULL;
|
||||||
GPid pid;
|
GPid pid = 0;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
gboolean success = FALSE;
|
|
||||||
char *pid_contents = NULL;
|
char *pid_contents = NULL;
|
||||||
|
|
||||||
if (!g_file_test (DHCP_CLIENT_PATH, G_FILE_TEST_EXISTS)) {
|
if (!g_file_test (DHCP_CLIENT_PATH, G_FILE_TEST_EXISTS)) {
|
||||||
@@ -249,7 +248,7 @@ nm_dhcp_client_start (NMDHCPDevice *device, NMSettingIP4Config *s_ip4)
|
|||||||
unsigned long int tmp = strtoul (pid_contents, NULL, 10);
|
unsigned long int tmp = strtoul (pid_contents, NULL, 10);
|
||||||
|
|
||||||
if (!((tmp == ULONG_MAX) && (errno == ERANGE)))
|
if (!((tmp == ULONG_MAX) && (errno == ERANGE)))
|
||||||
nm_dhcp_client_stop (device->iface, (pid_t) tmp);
|
nm_dhcp_client_stop (device, (pid_t) tmp);
|
||||||
remove (device->pid_file);
|
remove (device->pid_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,13 +281,10 @@ nm_dhcp_client_start (NMDHCPDevice *device, NMSettingIP4Config *s_ip4)
|
|||||||
|
|
||||||
nm_info ("dhclient started with pid %d", pid);
|
nm_info ("dhclient started with pid %d", pid);
|
||||||
|
|
||||||
device->pid = pid;
|
|
||||||
success = TRUE;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
g_free (pid_contents);
|
g_free (pid_contents);
|
||||||
g_ptr_array_free (dhclient_argv, TRUE);
|
g_ptr_array_free (dhclient_argv, TRUE);
|
||||||
return success;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char **
|
static const char **
|
||||||
|
@@ -59,13 +59,12 @@ dhcpcd_child_setup (gpointer user_data G_GNUC_UNUSED)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
GPid
|
||||||
nm_dhcp_client_start (NMDHCPDevice *device, NMSettingIP4Config *s_ip4)
|
nm_dhcp_client_start (NMDHCPDevice *device, NMSettingIP4Config *s_ip4)
|
||||||
{
|
{
|
||||||
GPtrArray *argv = NULL;
|
GPtrArray *argv = NULL;
|
||||||
GPid pid;
|
GPid pid = 0;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
gboolean success = FALSE;
|
|
||||||
char *pid_contents = NULL;
|
char *pid_contents = NULL;
|
||||||
|
|
||||||
if (!g_file_test (DHCP_CLIENT_PATH, G_FILE_TEST_EXISTS)) {
|
if (!g_file_test (DHCP_CLIENT_PATH, G_FILE_TEST_EXISTS)) {
|
||||||
@@ -84,7 +83,7 @@ nm_dhcp_client_start (NMDHCPDevice *device, NMSettingIP4Config *s_ip4)
|
|||||||
unsigned long int tmp = strtoul (pid_contents, NULL, 10);
|
unsigned long int tmp = strtoul (pid_contents, NULL, 10);
|
||||||
|
|
||||||
if (!((tmp == ULONG_MAX) && (errno == ERANGE)))
|
if (!((tmp == ULONG_MAX) && (errno == ERANGE)))
|
||||||
nm_dhcp_client_stop (device->iface, (pid_t) tmp);
|
nm_dhcp_client_stop (device, (pid_t) tmp);
|
||||||
remove (device->pid_file);
|
remove (device->pid_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,13 +111,10 @@ nm_dhcp_client_start (NMDHCPDevice *device, NMSettingIP4Config *s_ip4)
|
|||||||
|
|
||||||
nm_info ("dhcpcd started with pid %d", pid);
|
nm_info ("dhcpcd started with pid %d", pid);
|
||||||
|
|
||||||
device->pid = pid;
|
|
||||||
success = TRUE;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
g_free (pid_contents);
|
g_free (pid_contents);
|
||||||
g_ptr_array_free (argv, TRUE);
|
g_ptr_array_free (argv, TRUE);
|
||||||
return success;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@@ -172,10 +172,9 @@ nm_dhcp_device_destroy (NMDHCPDevice *device)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
nm_dhcp_device_timeout_cleanup (device);
|
nm_dhcp_device_timeout_cleanup (device);
|
||||||
nm_dhcp_device_watch_cleanup (device);
|
|
||||||
|
|
||||||
if (device->pid)
|
if (device->pid)
|
||||||
nm_dhcp_client_stop (device->iface, device->pid);
|
nm_dhcp_client_stop (device, device->pid);
|
||||||
|
|
||||||
if (device->options)
|
if (device->options)
|
||||||
g_hash_table_destroy (device->options);
|
g_hash_table_destroy (device->options);
|
||||||
@@ -593,13 +592,17 @@ nm_dhcp_manager_begin_transaction (NMDHCPManager *manager,
|
|||||||
if (!device)
|
if (!device)
|
||||||
device = nm_dhcp_device_new (manager, iface);
|
device = nm_dhcp_device_new (manager, iface);
|
||||||
|
|
||||||
if (state_is_bound (device->state) || (device->state == DHC_START)) {
|
if (device->pid && (device->state < DHC_ABEND)) {
|
||||||
/* Cancel any DHCP transaction already in progress */
|
/* Cancel any DHCP transaction already in progress */
|
||||||
nm_dhcp_manager_cancel_transaction_real (device);
|
nm_dhcp_manager_cancel_transaction_real (device);
|
||||||
}
|
}
|
||||||
|
|
||||||
nm_info ("Activation (%s) Beginning DHCP transaction.", iface);
|
nm_info ("Activation (%s) Beginning DHCP transaction.", iface);
|
||||||
|
|
||||||
|
device->pid = nm_dhcp_client_start (device, s_ip4);
|
||||||
|
if (device->pid == 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (timeout == 0)
|
if (timeout == 0)
|
||||||
timeout = NM_DHCP_TIMEOUT;
|
timeout = NM_DHCP_TIMEOUT;
|
||||||
|
|
||||||
@@ -607,8 +610,6 @@ nm_dhcp_manager_begin_transaction (NMDHCPManager *manager,
|
|||||||
device->timeout_id = g_timeout_add_seconds (timeout,
|
device->timeout_id = g_timeout_add_seconds (timeout,
|
||||||
nm_dhcp_manager_handle_timeout,
|
nm_dhcp_manager_handle_timeout,
|
||||||
device);
|
device);
|
||||||
|
|
||||||
nm_dhcp_client_start (device, s_ip4);
|
|
||||||
device->watch_id = g_child_watch_add (device->pid,
|
device->watch_id = g_child_watch_add (device->pid,
|
||||||
(GChildWatchFunc) dhcp_watch_cb,
|
(GChildWatchFunc) dhcp_watch_cb,
|
||||||
device);
|
device);
|
||||||
@@ -616,10 +617,17 @@ nm_dhcp_manager_begin_transaction (NMDHCPManager *manager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nm_dhcp_client_stop (const char * iface, pid_t pid)
|
nm_dhcp_client_stop (NMDHCPDevice *device, pid_t pid)
|
||||||
{
|
{
|
||||||
int i = 15; /* 3 seconds */
|
int i = 15; /* 3 seconds */
|
||||||
|
|
||||||
|
g_return_if_fail (pid > 0);
|
||||||
|
|
||||||
|
/* Clean up the watch handler since we're explicitly killing
|
||||||
|
* the daemon
|
||||||
|
*/
|
||||||
|
nm_dhcp_device_watch_cleanup (device);
|
||||||
|
|
||||||
/* Tell it to quit; maybe it wants to send out a RELEASE message */
|
/* Tell it to quit; maybe it wants to send out a RELEASE message */
|
||||||
kill (pid, SIGTERM);
|
kill (pid, SIGTERM);
|
||||||
|
|
||||||
@@ -643,7 +651,7 @@ nm_dhcp_client_stop (const char * iface, pid_t pid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (i <= 0) {
|
if (i <= 0) {
|
||||||
nm_warning ("%s: dhcp client pid %d didn't exit, will kill it.", iface, pid);
|
nm_warning ("%s: dhcp client pid %d didn't exit, will kill it.", device->iface, pid);
|
||||||
kill (pid, SIGKILL);
|
kill (pid, SIGKILL);
|
||||||
|
|
||||||
nm_debug ("waiting for dhcp client pid %d to exit", pid);
|
nm_debug ("waiting for dhcp client pid %d to exit", pid);
|
||||||
@@ -655,10 +663,9 @@ nm_dhcp_client_stop (const char * iface, pid_t pid)
|
|||||||
static void
|
static void
|
||||||
nm_dhcp_manager_cancel_transaction_real (NMDHCPDevice *device)
|
nm_dhcp_manager_cancel_transaction_real (NMDHCPDevice *device)
|
||||||
{
|
{
|
||||||
if (!device->pid)
|
g_return_if_fail (device->pid > 0);
|
||||||
return;
|
|
||||||
|
|
||||||
nm_dhcp_client_stop (device->iface, device->pid);
|
nm_dhcp_client_stop (device, device->pid);
|
||||||
|
|
||||||
nm_info ("%s: canceled DHCP transaction, dhcp client pid %d",
|
nm_info ("%s: canceled DHCP transaction, dhcp client pid %d",
|
||||||
device->iface,
|
device->iface,
|
||||||
@@ -688,7 +695,6 @@ nm_dhcp_manager_cancel_transaction_real (NMDHCPDevice *device)
|
|||||||
device->conf_file = NULL;
|
device->conf_file = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
nm_dhcp_device_watch_cleanup (device);
|
|
||||||
nm_dhcp_device_timeout_cleanup (device);
|
nm_dhcp_device_timeout_cleanup (device);
|
||||||
g_hash_table_remove_all (device->options);
|
g_hash_table_remove_all (device->options);
|
||||||
}
|
}
|
||||||
|
@@ -102,8 +102,8 @@ gboolean nm_dhcp_manager_foreach_dhcp4_option (NMDHCPManager *self,
|
|||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
/* The following are implemented by the DHCP client backends */
|
/* The following are implemented by the DHCP client backends */
|
||||||
gboolean nm_dhcp_client_start (NMDHCPDevice *device, NMSettingIP4Config *s_ip4);
|
GPid nm_dhcp_client_start (NMDHCPDevice *device, NMSettingIP4Config *s_ip4);
|
||||||
void nm_dhcp_client_stop (const char *iface, pid_t pid);
|
void nm_dhcp_client_stop (NMDHCPDevice *device, pid_t pid);
|
||||||
|
|
||||||
gboolean nm_dhcp_client_process_classless_routes (GHashTable *options,
|
gboolean nm_dhcp_client_process_classless_routes (GHashTable *options,
|
||||||
NMIP4Config *ip4_config,
|
NMIP4Config *ip4_config,
|
||||||
|
Reference in New Issue
Block a user