Browse Source

qdevice: Ensure to exit if ipc socket is closed

When ipc socket was closed before poll and new connection got same fd as
original IPC socket, shutdown didn't work. Solution is to check if IPC
socket is active during poll array create.

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Jan Friesse 9 năm trước cách đây
mục cha
commit
509d4b1511

+ 6 - 0
qdevices/corosync-qnetd.c

@@ -106,6 +106,12 @@ qnetd_pr_poll_array_create(struct qnetd_instance *instance)
 
 	user_data->type = QNETD_POLL_ARRAY_USER_DATA_TYPE_SOCKET;
 
+	if (qnetd_ipc_is_closed(instance)) {
+		qnetd_log(LOG_DEBUG, "Listening socket is closed");
+
+		return (NULL);
+	}
+
 	if (pr_poll_array_add(poll_array, &poll_desc, (void **)&user_data) < 0) {
 		return (NULL);
 	}

+ 7 - 0
qdevices/qdevice-ipc.c

@@ -67,6 +67,13 @@ qdevice_ipc_close(struct qdevice_instance *instance)
 	return (res);
 }
 
+int
+qdevice_ipc_is_closed(struct qdevice_instance *instance)
+{
+
+	return (unix_socket_ipc_is_closed(&instance->local_ipc));
+}
+
 int
 qdevice_ipc_destroy(struct qdevice_instance *instance)
 {

+ 2 - 0
qdevices/qdevice-ipc.h

@@ -71,6 +71,8 @@ extern int		qdevice_ipc_send_error(struct qdevice_instance *instance,
 extern int		qdevice_ipc_send_buffer(struct qdevice_instance *instance,
     struct unix_socket_client *client);
 
+extern int		qdevice_ipc_is_closed(struct qdevice_instance *instance);
+
 #ifdef __cplusplus
 }
 #endif

+ 8 - 0
qdevices/qdevice-net-poll.c

@@ -197,6 +197,14 @@ qdevice_net_pr_poll_array_create(struct qdevice_net_instance *instance)
 	poll_desc->in_flags = PR_POLL_READ;
 	user_data->type = QDEVICE_NET_POLL_ARRAY_USER_DATA_TYPE_CMAP;
 
+	if (qdevice_ipc_is_closed(instance->qdevice_instance_ptr)) {
+		qdevice_log(LOG_DEBUG, "Local socket is closed");
+		instance->schedule_disconnect = 1;
+		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_LOCAL_SOCKET_CLOSED;
+
+		return (NULL);
+	}
+
 	if (pr_poll_array_add(poll_array, &poll_desc, (void **)&user_data) < 0) {
 		return (NULL);
 	}

+ 7 - 0
qdevices/qnetd-ipc.c

@@ -79,6 +79,13 @@ qnetd_ipc_close(struct qnetd_instance *instance)
 	return (res);
 }
 
+int
+qnetd_ipc_is_closed(struct qnetd_instance *instance)
+{
+
+	return (unix_socket_ipc_is_closed(&instance->local_ipc));
+}
+
 int
 qnetd_ipc_destroy(struct qnetd_instance *instance)
 {

+ 2 - 0
qdevices/qnetd-ipc.h

@@ -50,6 +50,8 @@ extern int		qnetd_ipc_init(struct qnetd_instance *instance);
 
 extern int		qnetd_ipc_close(struct qnetd_instance *instance);
 
+extern int		qnetd_ipc_is_closed(struct qnetd_instance *instance);
+
 extern int		qnetd_ipc_destroy(struct qnetd_instance *instance);
 
 extern int		qnetd_ipc_accept(struct qnetd_instance *instance,

+ 7 - 0
qdevices/unix-socket-ipc.c

@@ -90,6 +90,13 @@ unix_socket_ipc_close(struct unix_socket_ipc *ipc)
 	return (res);
 }
 
+int
+unix_socket_ipc_is_closed(struct unix_socket_ipc *ipc)
+{
+
+	return (ipc->socket < 0);
+}
+
 int
 unix_socket_ipc_destroy(struct unix_socket_ipc *ipc)
 {

+ 2 - 0
qdevices/unix-socket-ipc.h

@@ -66,6 +66,8 @@ void			unix_socket_ipc_client_disconnect(struct unix_socket_ipc *ipc,
 
 extern int		unix_socket_ipc_close(struct unix_socket_ipc *ipc);
 
+extern int		unix_socket_ipc_is_closed(struct unix_socket_ipc *ipc);
+
 #ifdef __cplusplus
 }
 #endif