2
* virnetserver.c: generic network RPC server
4
* Copyright (C) 2006-2012 Red Hat, Inc.
5
* Copyright (C) 2006 Daniel P. Berrange
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
* Author: Daniel P. Berrange <berrange@redhat.com>
30
#include "virnetserver.h"
33
#include "virterror_internal.h"
35
#include "threadpool.h"
40
# include "virnetservermdns.h"
47
#define VIR_FROM_THIS VIR_FROM_RPC
48
#define virNetError(code, ...) \
49
virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \
50
__FUNCTION__, __LINE__, __VA_ARGS__)
52
typedef struct _virNetServerSignal virNetServerSignal;
53
typedef virNetServerSignal *virNetServerSignalPtr;
55
struct _virNetServerSignal {
56
struct sigaction oldaction;
58
virNetServerSignalFunc func;
62
typedef struct _virNetServerJob virNetServerJob;
63
typedef virNetServerJob *virNetServerJobPtr;
65
struct _virNetServerJob {
66
virNetServerClientPtr client;
68
virNetServerProgramPtr prog;
71
struct _virNetServer {
76
virThreadPoolPtr workers;
81
virNetServerSignalPtr *signals;
88
virNetServerMDNSPtr mdns;
89
virNetServerMDNSGroupPtr mdnsGroup;
93
virNetServerServicePtr *services;
96
virNetServerProgramPtr *programs;
100
virNetServerClientPtr *clients;
102
int keepaliveInterval;
103
unsigned int keepaliveCount;
104
bool keepaliveRequired;
106
unsigned int quit :1;
108
virNetTLSContextPtr tls;
110
unsigned int autoShutdownTimeout;
111
virNetServerAutoShutdownFunc autoShutdownFunc;
112
void *autoShutdownOpaque;
114
virNetServerClientInitHook clientInitHook;
118
static void virNetServerLock(virNetServerPtr srv)
120
virMutexLock(&srv->lock);
123
static void virNetServerUnlock(virNetServerPtr srv)
125
virMutexUnlock(&srv->lock);
129
static void virNetServerHandleJob(void *jobOpaque, void *opaque)
131
virNetServerPtr srv = opaque;
132
virNetServerJobPtr job = jobOpaque;
134
VIR_DEBUG("server=%p client=%p message=%p prog=%p",
135
srv, job->client, job->msg, job->prog);
138
/* Only send back an error for type == CALL. Other
139
* message types are not expecting replies, so we
140
* must just log it & drop them
142
if (job->msg->header.type == VIR_NET_CALL ||
143
job->msg->header.type == VIR_NET_CALL_WITH_FDS) {
144
if (virNetServerProgramUnknownError(job->client,
146
&job->msg->header) < 0)
149
VIR_INFO("Dropping client mesage, unknown program %d version %d type %d proc %d",
150
job->msg->header.prog, job->msg->header.vers,
151
job->msg->header.type, job->msg->header.proc);
152
/* Send a dummy reply to free up 'msg' & unblock client rx */
153
virNetMessageClear(job->msg);
154
job->msg->header.type = VIR_NET_REPLY;
155
if (virNetServerClientSendMessage(job->client, job->msg) < 0)
161
if (virNetServerProgramDispatch(job->prog,
167
virNetServerLock(srv);
168
virNetServerProgramFree(job->prog);
169
virNetServerUnlock(srv);
172
virNetServerClientFree(job->client);
177
virNetServerProgramFree(job->prog);
178
virNetMessageFree(job->msg);
179
virNetServerClientClose(job->client);
180
virNetServerClientFree(job->client);
184
static int virNetServerDispatchNewMessage(virNetServerClientPtr client,
185
virNetMessagePtr msg,
188
virNetServerPtr srv = opaque;
189
virNetServerJobPtr job;
190
virNetServerProgramPtr prog = NULL;
191
unsigned int priority = 0;
195
VIR_DEBUG("server=%p client=%p message=%p",
198
if (VIR_ALLOC(job) < 0) {
203
job->client = client;
206
virNetServerLock(srv);
207
for (i = 0 ; i < srv->nprograms ; i++) {
208
if (virNetServerProgramMatches(srv->programs[i], job->msg)) {
209
prog = srv->programs[i];
215
virNetServerProgramRef(prog);
217
priority = virNetServerProgramGetPriority(prog, msg->header.proc);
220
ret = virThreadPoolSendJob(srv->workers, priority, job);
224
virNetServerProgramFree(prog);
226
virNetServerUnlock(srv);
232
static int virNetServerDispatchNewClient(virNetServerServicePtr svc ATTRIBUTE_UNUSED,
233
virNetServerClientPtr client,
236
virNetServerPtr srv = opaque;
238
virNetServerLock(srv);
240
if (srv->nclients >= srv->nclients_max) {
241
virNetError(VIR_ERR_RPC,
242
_("Too many active clients (%zu), dropping connection from %s"),
243
srv->nclients_max, virNetServerClientRemoteAddrString(client));
247
if (virNetServerClientInit(client) < 0)
250
if (srv->clientInitHook &&
251
srv->clientInitHook(srv, client) < 0)
254
if (VIR_EXPAND_N(srv->clients, srv->nclients, 1) < 0) {
258
srv->clients[srv->nclients-1] = client;
259
virNetServerClientRef(client);
261
virNetServerClientSetDispatcher(client,
262
virNetServerDispatchNewMessage,
265
virNetServerClientInitKeepAlive(client, srv->keepaliveInterval,
266
srv->keepaliveCount);
268
virNetServerUnlock(srv);
272
virNetServerUnlock(srv);
278
virNetServerFatalSignal(int sig, siginfo_t *siginfo ATTRIBUTE_UNUSED,
279
void *context ATTRIBUTE_UNUSED)
281
struct sigaction sig_action;
285
virLogEmergencyDumpAll(sig);
288
* If the signal is fatal, avoid looping over this handler
292
if (sig != SIGUSR2) {
294
memset(&sig_action, 0, sizeof(sig_action));
295
sig_action.sa_handler = SIG_DFL;
296
sigaction(sig, &sig_action, NULL);
305
virNetServerPtr virNetServerNew(size_t min_workers,
307
size_t priority_workers,
309
int keepaliveInterval,
310
unsigned int keepaliveCount,
311
bool keepaliveRequired,
312
const char *mdnsGroupName,
313
virNetServerClientInitHook clientInitHook)
316
struct sigaction sig_action;
318
if (VIR_ALLOC(srv) < 0) {
325
if (!(srv->workers = virThreadPoolNew(min_workers, max_workers,
327
virNetServerHandleJob,
331
srv->nclients_max = max_clients;
332
srv->keepaliveInterval = keepaliveInterval;
333
srv->keepaliveCount = keepaliveCount;
334
srv->keepaliveRequired = keepaliveRequired;
335
srv->sigwrite = srv->sigread = -1;
336
srv->clientInitHook = clientInitHook;
337
srv->privileged = geteuid() == 0 ? true : false;
340
!(srv->mdnsGroupName = strdup(mdnsGroupName))) {
345
if (srv->mdnsGroupName) {
346
if (!(srv->mdns = virNetServerMDNSNew()))
348
if (!(srv->mdnsGroup = virNetServerMDNSAddGroup(srv->mdns,
349
srv->mdnsGroupName)))
354
if (virMutexInit(&srv->lock) < 0) {
355
virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
356
_("cannot initialize mutex"));
360
if (virEventRegisterDefaultImpl() < 0)
363
memset(&sig_action, 0, sizeof(sig_action));
364
sig_action.sa_handler = SIG_IGN;
365
sigaction(SIGPIPE, &sig_action, NULL);
368
* catch fatal errors to dump a log, also hook to USR2 for dynamic
369
* debugging purposes or testing
371
sig_action.sa_sigaction = virNetServerFatalSignal;
372
sig_action.sa_flags = SA_SIGINFO;
373
sigaction(SIGFPE, &sig_action, NULL);
374
sigaction(SIGSEGV, &sig_action, NULL);
375
sigaction(SIGILL, &sig_action, NULL);
376
sigaction(SIGABRT, &sig_action, NULL);
378
sigaction(SIGBUS, &sig_action, NULL);
381
sigaction(SIGUSR2, &sig_action, NULL);
384
VIR_DEBUG("srv=%p refs=%d", srv, srv->refs);
388
virNetServerFree(srv);
393
void virNetServerRef(virNetServerPtr srv)
395
virNetServerLock(srv);
397
VIR_DEBUG("srv=%p refs=%d", srv, srv->refs);
398
virNetServerUnlock(srv);
402
bool virNetServerIsPrivileged(virNetServerPtr srv)
405
virNetServerLock(srv);
406
priv = srv->privileged;
407
virNetServerUnlock(srv);
412
void virNetServerAutoShutdown(virNetServerPtr srv,
413
unsigned int timeout,
414
virNetServerAutoShutdownFunc func,
417
virNetServerLock(srv);
419
srv->autoShutdownTimeout = timeout;
420
srv->autoShutdownFunc = func;
421
srv->autoShutdownOpaque = opaque;
423
virNetServerUnlock(srv);
426
static sig_atomic_t sigErrors = 0;
427
static int sigLastErrno = 0;
428
static int sigWrite = -1;
431
virNetServerSignalHandler(int sig, siginfo_t * siginfo,
432
void* context ATTRIBUTE_UNUSED)
441
memset(&tmp, 0, sizeof(tmp));
443
/* set the sig num in the struct */
447
r = safewrite(sigWrite, &tmp, sizeof(tmp));
450
sigLastErrno = errno;
456
virNetServerSignalEvent(int watch,
457
int fd ATTRIBUTE_UNUSED,
458
int events ATTRIBUTE_UNUSED,
460
virNetServerPtr srv = opaque;
464
virNetServerLock(srv);
466
if (saferead(srv->sigread, &siginfo, sizeof(siginfo)) != sizeof(siginfo)) {
467
virReportSystemError(errno, "%s",
468
_("Failed to read from signal pipe"));
469
virEventRemoveHandle(watch);
474
for (i = 0 ; i < srv->nsignals ; i++) {
475
if (siginfo.si_signo == srv->signals[i]->signum) {
476
virNetServerSignalFunc func = srv->signals[i]->func;
477
void *funcopaque = srv->signals[i]->opaque;
478
virNetServerUnlock(srv);
479
func(srv, &siginfo, funcopaque);
484
virNetError(VIR_ERR_INTERNAL_ERROR,
485
_("Unexpected signal received: %d"), siginfo.si_signo);
488
virNetServerUnlock(srv);
491
static int virNetServerSignalSetup(virNetServerPtr srv)
493
int fds[2] = { -1, -1 };
495
if (srv->sigwrite != -1)
498
if (pipe2(fds, O_CLOEXEC|O_NONBLOCK) < 0) {
499
virReportSystemError(errno, "%s",
500
_("Unable to create signal pipe"));
504
if ((srv->sigwatch = virEventAddHandle(fds[0],
505
VIR_EVENT_HANDLE_READABLE,
506
virNetServerSignalEvent,
508
virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
509
_("Failed to add signal handle watch"));
513
srv->sigread = fds[0];
514
srv->sigwrite = fds[1];
520
VIR_FORCE_CLOSE(fds[0]);
521
VIR_FORCE_CLOSE(fds[1]);
525
int virNetServerAddSignalHandler(virNetServerPtr srv,
527
virNetServerSignalFunc func,
530
virNetServerSignalPtr sigdata;
531
struct sigaction sig_action;
533
virNetServerLock(srv);
535
if (virNetServerSignalSetup(srv) < 0)
538
if (VIR_EXPAND_N(srv->signals, srv->nsignals, 1) < 0)
541
if (VIR_ALLOC(sigdata) < 0)
544
sigdata->signum = signum;
545
sigdata->func = func;
546
sigdata->opaque = opaque;
548
memset(&sig_action, 0, sizeof(sig_action));
549
sig_action.sa_sigaction = virNetServerSignalHandler;
550
sig_action.sa_flags = SA_SIGINFO;
551
sigemptyset(&sig_action.sa_mask);
553
sigaction(signum, &sig_action, &sigdata->oldaction);
555
srv->signals[srv->nsignals-1] = sigdata;
557
virNetServerUnlock(srv);
564
virNetServerUnlock(srv);
570
int virNetServerAddService(virNetServerPtr srv,
571
virNetServerServicePtr svc,
572
const char *mdnsEntryName ATTRIBUTE_UNUSED)
574
virNetServerLock(srv);
576
if (VIR_EXPAND_N(srv->services, srv->nservices, 1) < 0)
581
int port = virNetServerServiceGetPort(svc);
583
if (!virNetServerMDNSAddEntry(srv->mdnsGroup,
590
srv->services[srv->nservices-1] = svc;
591
virNetServerServiceRef(svc);
593
virNetServerServiceSetDispatcher(svc,
594
virNetServerDispatchNewClient,
597
virNetServerUnlock(srv);
605
virNetServerUnlock(srv);
609
int virNetServerAddProgram(virNetServerPtr srv,
610
virNetServerProgramPtr prog)
612
virNetServerLock(srv);
614
if (VIR_EXPAND_N(srv->programs, srv->nprograms, 1) < 0)
617
srv->programs[srv->nprograms-1] = prog;
618
virNetServerProgramRef(prog);
620
virNetServerUnlock(srv);
625
virNetServerUnlock(srv);
629
int virNetServerSetTLSContext(virNetServerPtr srv,
630
virNetTLSContextPtr tls)
633
virNetTLSContextRef(tls);
638
static void virNetServerAutoShutdownTimer(int timerid ATTRIBUTE_UNUSED,
640
virNetServerPtr srv = opaque;
642
virNetServerLock(srv);
644
if (srv->autoShutdownFunc(srv, srv->autoShutdownOpaque)) {
645
VIR_DEBUG("Automatic shutdown triggered");
649
virNetServerUnlock(srv);
653
void virNetServerUpdateServices(virNetServerPtr srv,
658
virNetServerLock(srv);
659
for (i = 0 ; i < srv->nservices ; i++)
660
virNetServerServiceToggle(srv->services[i], enabled);
662
virNetServerUnlock(srv);
666
void virNetServerRun(virNetServerPtr srv)
672
virNetServerLock(srv);
676
virNetServerMDNSStart(srv->mdns) < 0)
680
if (srv->autoShutdownTimeout &&
681
(timerid = virEventAddTimeout(-1,
682
virNetServerAutoShutdownTimer,
684
virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
685
_("Failed to register shutdown timeout"));
689
VIR_DEBUG("srv=%p quit=%d", srv, srv->quit);
691
/* A shutdown timeout is specified, so check
692
* if any drivers have active state, if not
693
* shutdown after timeout seconds
695
if (srv->autoShutdownTimeout) {
698
VIR_DEBUG("Deactivating shutdown timer %d", timerid);
699
virEventUpdateTimeout(timerid, -1);
704
VIR_DEBUG("Activating shutdown timer %d", timerid);
705
virEventUpdateTimeout(timerid,
706
srv->autoShutdownTimeout * 1000);
712
virNetServerUnlock(srv);
713
if (virEventRunDefaultImpl() < 0) {
714
virNetServerLock(srv);
715
VIR_DEBUG("Loop iteration error, exiting");
718
virNetServerLock(srv);
721
for (i = 0 ; i < srv->nclients ; i++) {
722
/* Coverity 5.3.0 couldn't see that srv->clients is non-NULL
723
* if srv->nclients is non-zero. */
724
sa_assert(srv->clients);
725
if (virNetServerClientWantClose(srv->clients[i]))
726
virNetServerClientClose(srv->clients[i]);
727
if (virNetServerClientIsClosed(srv->clients[i])) {
728
virNetServerClientFree(srv->clients[i]);
729
if (srv->nclients > 1) {
730
memmove(srv->clients + i,
731
srv->clients + i + 1,
732
sizeof(*srv->clients) * (srv->nclients - (i + 1)));
733
VIR_SHRINK_N(srv->clients, srv->nclients, 1);
735
VIR_FREE(srv->clients);
745
virNetServerUnlock(srv);
749
void virNetServerQuit(virNetServerPtr srv)
751
virNetServerLock(srv);
753
VIR_DEBUG("Quit requested %p", srv);
756
virNetServerUnlock(srv);
759
void virNetServerFree(virNetServerPtr srv)
766
virNetServerLock(srv);
767
VIR_DEBUG("srv=%p refs=%d", srv, srv->refs);
770
virNetServerUnlock(srv);
774
for (i = 0 ; i < srv->nservices ; i++)
775
virNetServerServiceToggle(srv->services[i], false);
777
virThreadPoolFree(srv->workers);
779
for (i = 0 ; i < srv->nsignals ; i++) {
780
sigaction(srv->signals[i]->signum, &srv->signals[i]->oldaction, NULL);
781
VIR_FREE(srv->signals[i]);
783
VIR_FREE(srv->signals);
784
VIR_FORCE_CLOSE(srv->sigread);
785
VIR_FORCE_CLOSE(srv->sigwrite);
786
if (srv->sigwatch > 0)
787
virEventRemoveHandle(srv->sigwatch);
789
for (i = 0 ; i < srv->nservices ; i++)
790
virNetServerServiceFree(srv->services[i]);
791
VIR_FREE(srv->services);
793
for (i = 0 ; i < srv->nprograms ; i++)
794
virNetServerProgramFree(srv->programs[i]);
795
VIR_FREE(srv->programs);
797
for (i = 0 ; i < srv->nclients ; i++) {
798
virNetServerClientClose(srv->clients[i]);
799
virNetServerClientFree(srv->clients[i]);
801
VIR_FREE(srv->clients);
803
VIR_FREE(srv->mdnsGroupName);
805
virNetServerMDNSFree(srv->mdns);
808
virNetServerUnlock(srv);
809
virMutexDestroy(&srv->lock);
813
void virNetServerClose(virNetServerPtr srv)
820
virNetServerLock(srv);
822
for (i = 0; i < srv->nservices; i++) {
823
virNetServerServiceClose(srv->services[i]);
826
virNetServerUnlock(srv);
829
bool virNetServerKeepAliveRequired(virNetServerPtr srv)
832
virNetServerLock(srv);
833
required = srv->keepaliveRequired;
834
virNetServerUnlock(srv);