mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 12:35:17 +00:00
f3ab818984
This commit is related to 5de203f879 which I pushed a few days ago. While that commit prioritized closing clients socket over the rest of I/O process, this one goes one step further and temporarily suspends processing new connection requests. A brief recapitulation of the problem: 1) assume that libvirt is at the top of RLIMIT_NOFILE (that is no new FDs can be opened). 2) we have a client trying to connect to a UNIX/TCP socket Because of 2) our event loop sees POLLIN on the socket and thus calls virNetServerServiceAccept(). But since no new FDs can be opened (because of 1)) the request is not handled and we will get the same event on next iteration. The poll() will exit immediately because there is an event on the socket. Thus we end up in an endless loop. To break the loop and stop burning CPU cycles we can stop listening for events on the socket and set up a timer tho enable listening again after some time (I chose 5 seconds because of no obvious reason). There's another area where we play with temporarily suspending accept() of new clients - when a client disconnects and we check max_clients against number of current clients. Problem here is that max_clients can be orders of magnitude larger than RLIMIT_NOFILE but more importantly, what this code considers client disconnect is not equal to closing client's FD. A client disconnecting means that the corresponding client structure is removed from the internal list of clients. Closing of the client's FD is done from event loop - asynchronously. To avoid this part stepping on the toes of my fix, let's make the code NOP if socket timer (as described above) is active. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
83 lines
3.7 KiB
C
83 lines
3.7 KiB
C
/*
|
|
* virnetserverservice.h: generic network RPC server service
|
|
*
|
|
* Copyright (C) 2006-2011, 2014 Red Hat, Inc.
|
|
* Copyright (C) 2006 Daniel P. Berrange
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library. If not, see
|
|
* <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "virnetserverprogram.h"
|
|
#include "virobject.h"
|
|
|
|
typedef enum {
|
|
VIR_NET_SERVER_SERVICE_AUTH_NONE = 0,
|
|
VIR_NET_SERVER_SERVICE_AUTH_SASL,
|
|
VIR_NET_SERVER_SERVICE_AUTH_POLKIT,
|
|
} virNetServerServiceAuthMethods;
|
|
|
|
typedef int (*virNetServerServiceDispatchFunc)(virNetServerService *svc,
|
|
virNetSocket *sock,
|
|
void *opaque);
|
|
|
|
virNetServerService *virNetServerServiceNewTCP(const char *nodename,
|
|
const char *service,
|
|
int family,
|
|
int auth,
|
|
virNetTLSContext *tls,
|
|
bool readonly,
|
|
size_t max_queued_clients,
|
|
size_t nrequests_client_max);
|
|
virNetServerService *virNetServerServiceNewUNIX(const char *path,
|
|
mode_t mask,
|
|
gid_t grp,
|
|
int auth,
|
|
virNetTLSContext *tls,
|
|
bool readonly,
|
|
size_t max_queued_clients,
|
|
size_t nrequests_client_max);
|
|
virNetServerService *virNetServerServiceNewFDs(int *fd,
|
|
size_t nfds,
|
|
bool unlinkUNIX,
|
|
int auth,
|
|
virNetTLSContext *tls,
|
|
bool readonly,
|
|
size_t max_queued_clients,
|
|
size_t nrequests_client_max);
|
|
|
|
virNetServerService *virNetServerServiceNewPostExecRestart(virJSONValue *object);
|
|
|
|
virJSONValue *virNetServerServicePreExecRestart(virNetServerService *service);
|
|
|
|
int virNetServerServiceGetPort(virNetServerService *svc);
|
|
|
|
int virNetServerServiceGetAuth(virNetServerService *svc);
|
|
bool virNetServerServiceIsReadonly(virNetServerService *svc);
|
|
size_t virNetServerServiceGetMaxRequests(virNetServerService *svc);
|
|
virNetTLSContext *virNetServerServiceGetTLSContext(virNetServerService *svc);
|
|
|
|
void virNetServerServiceSetDispatcher(virNetServerService *svc,
|
|
virNetServerServiceDispatchFunc func,
|
|
void *opaque);
|
|
|
|
void virNetServerServiceToggle(virNetServerService *svc,
|
|
bool enabled);
|
|
|
|
void virNetServerServiceClose(virNetServerService *svc);
|
|
|
|
bool virNetServerServiceTimerActive(virNetServerService *svc);
|