mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
rpc: virnetserverclient: Introduce new attribute conn_time to client
Besides ID, libvirt should provide several parameters to help the user distinguish two clients from each other. One of them is the connection timestamp. This patch also adds a testcase for proper JSON formatting of the new attribute too (proper formatting of older clients that did not support this attribute yet is included in the existing tests) - in order to testGenerateJSON to work, a mock of time_t time(time_t *timer) needed to be created. Signed-off-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
parent
5841d64d25
commit
a32135b3b1
@ -85,6 +85,13 @@ struct _virNetServerClient
|
||||
|
||||
virIdentityPtr identity;
|
||||
|
||||
/* Connection timestamp, i.e. when a client connected to the daemon (UTC).
|
||||
* For old clients restored by post-exec-restart, which did not have this
|
||||
* attribute, value of 0 (epoch time) is used to indicate we have no
|
||||
* information about their connection time.
|
||||
*/
|
||||
time_t conn_time;
|
||||
|
||||
/* Count of messages in the 'tx' queue,
|
||||
* and the server worker pool queue
|
||||
* ie RPC calls in progress. Does not count
|
||||
@ -355,7 +362,8 @@ virNetServerClientNewInternal(unsigned long long id,
|
||||
virNetTLSContextPtr tls,
|
||||
#endif
|
||||
bool readonly,
|
||||
size_t nrequests_max)
|
||||
size_t nrequests_max,
|
||||
time_t timestamp)
|
||||
{
|
||||
virNetServerClientPtr client;
|
||||
|
||||
@ -373,6 +381,7 @@ virNetServerClientNewInternal(unsigned long long id,
|
||||
client->tlsCtxt = virObjectRef(tls);
|
||||
#endif
|
||||
client->nrequests_max = nrequests_max;
|
||||
client->conn_time = timestamp;
|
||||
|
||||
client->sockTimer = virEventAddTimeout(-1, virNetServerClientSockTimerFunc,
|
||||
client, NULL);
|
||||
@ -413,6 +422,7 @@ virNetServerClientPtr virNetServerClientNew(unsigned long long id,
|
||||
void *privOpaque)
|
||||
{
|
||||
virNetServerClientPtr client;
|
||||
time_t now;
|
||||
|
||||
VIR_DEBUG("sock=%p auth=%d tls=%p", sock, auth,
|
||||
#ifdef WITH_GNUTLS
|
||||
@ -422,11 +432,17 @@ virNetServerClientPtr virNetServerClientNew(unsigned long long id,
|
||||
#endif
|
||||
);
|
||||
|
||||
if ((now = time(NULL)) == (time_t) - 1) {
|
||||
virReportSystemError(errno, "%s", _("failed to get current time"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(client = virNetServerClientNewInternal(id, sock, auth,
|
||||
#ifdef WITH_GNUTLS
|
||||
tls,
|
||||
#endif
|
||||
readonly, nrequests_max)))
|
||||
readonly, nrequests_max,
|
||||
now)))
|
||||
return NULL;
|
||||
|
||||
if (privNew) {
|
||||
@ -456,6 +472,7 @@ virNetServerClientPtr virNetServerClientNewPostExecRestart(virJSONValuePtr objec
|
||||
bool readonly;
|
||||
unsigned int nrequests_max;
|
||||
unsigned long long id;
|
||||
time_t timestamp;
|
||||
|
||||
if (virJSONValueObjectGetNumberInt(object, "auth", &auth) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
@ -492,6 +509,18 @@ virNetServerClientPtr virNetServerClientNewPostExecRestart(virJSONValuePtr objec
|
||||
}
|
||||
}
|
||||
|
||||
if (!virJSONValueObjectHasKey(object, "conn_time")) {
|
||||
timestamp = 0;
|
||||
} else {
|
||||
if (virJSONValueObjectGetNumberLong(object, "conn_time",
|
||||
(long long *) ×tamp) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("Malformed conn_time field in JSON "
|
||||
"state document"));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(sock = virNetSocketNewPostExecRestart(child))) {
|
||||
virObjectUnref(sock);
|
||||
return NULL;
|
||||
@ -504,7 +533,8 @@ virNetServerClientPtr virNetServerClientNewPostExecRestart(virJSONValuePtr objec
|
||||
NULL,
|
||||
#endif
|
||||
readonly,
|
||||
nrequests_max))) {
|
||||
nrequests_max,
|
||||
timestamp))) {
|
||||
virObjectUnref(sock);
|
||||
return NULL;
|
||||
}
|
||||
@ -552,6 +582,11 @@ virJSONValuePtr virNetServerClientPreExecRestart(virNetServerClientPtr client)
|
||||
if (virJSONValueObjectAppendNumberUint(object, "nrequests_max", client->nrequests_max) < 0)
|
||||
goto error;
|
||||
|
||||
if (client->conn_time &&
|
||||
virJSONValueObjectAppendNumberLong(object, "conn_time",
|
||||
client->conn_time) < 0)
|
||||
goto error;
|
||||
|
||||
if (!(child = virNetSocketPreExecRestart(client->sock)))
|
||||
goto error;
|
||||
|
||||
@ -610,6 +645,11 @@ unsigned long long virNetServerClientGetID(virNetServerClientPtr client)
|
||||
return client->id;
|
||||
}
|
||||
|
||||
long long virNetServerClientGetTimestamp(virNetServerClientPtr client)
|
||||
{
|
||||
return client->conn_time;
|
||||
}
|
||||
|
||||
#ifdef WITH_GNUTLS
|
||||
bool virNetServerClientHasTLSSession(virNetServerClientPtr client)
|
||||
{
|
||||
|
@ -82,6 +82,7 @@ int virNetServerClientGetAuth(virNetServerClientPtr client);
|
||||
void virNetServerClientSetAuth(virNetServerClientPtr client, int auth);
|
||||
bool virNetServerClientGetReadonly(virNetServerClientPtr client);
|
||||
unsigned long long virNetServerClientGetID(virNetServerClientPtr client);
|
||||
long long virNetServerClientGetTimestamp(virNetServerClientPtr client);
|
||||
|
||||
# ifdef WITH_GNUTLS
|
||||
bool virNetServerClientHasTLSSession(virNetServerClientPtr client);
|
||||
|
@ -408,6 +408,7 @@ EXTRA_DIST += $(test_scripts)
|
||||
|
||||
test_libraries = libshunload.la \
|
||||
virportallocatormock.la \
|
||||
virnetdaemonmock.la \
|
||||
virnetserverclientmock.la \
|
||||
vircgroupmock.la \
|
||||
virpcimock.la \
|
||||
@ -927,6 +928,12 @@ virnetdaemontest_SOURCES = \
|
||||
virnetdaemontest_CFLAGS = $(XDR_CFLAGS) $(AM_CFLAGS)
|
||||
virnetdaemontest_LDADD = $(LDADDS)
|
||||
|
||||
virnetdaemonmock_la_SOURCES = \
|
||||
virnetdaemonmock.c
|
||||
virnetdaemonmock_la_CFLAGS = $(AM_CFLAGS)
|
||||
virnetdaemonmock_la_LDFLAGS = $(MOCKLIBS_LDFLAGS)
|
||||
virnetdaemonmock_la_LIBADD = $(MOCKLIBS_LIBS)
|
||||
|
||||
virnetserverclienttest_SOURCES = \
|
||||
virnetserverclienttest.c \
|
||||
testutils.h testutils.c
|
||||
|
70
tests/virnetdaemondata/input-data-client-timestamp.json
Normal file
70
tests/virnetdaemondata/input-data-client-timestamp.json
Normal file
@ -0,0 +1,70 @@
|
||||
{
|
||||
"servers": {
|
||||
"testServer0": {
|
||||
"min_workers": 10,
|
||||
"max_workers": 50,
|
||||
"priority_workers": 5,
|
||||
"max_clients": 100,
|
||||
"max_anonymous_clients": 10,
|
||||
"keepaliveInterval": 120,
|
||||
"keepaliveCount": 5,
|
||||
"next_client_id": 3,
|
||||
"services": [
|
||||
{
|
||||
"auth": 0,
|
||||
"readonly": true,
|
||||
"nrequests_client_max": 2,
|
||||
"socks": [
|
||||
{
|
||||
"fd": 100,
|
||||
"errfd": -1,
|
||||
"pid": 0,
|
||||
"isClient": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"auth": 2,
|
||||
"readonly": false,
|
||||
"nrequests_client_max": 5,
|
||||
"socks": [
|
||||
{
|
||||
"fd": 101,
|
||||
"errfd": -1,
|
||||
"pid": 0,
|
||||
"isClient": false
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"clients": [
|
||||
{
|
||||
"id": 1,
|
||||
"auth": 1,
|
||||
"readonly": true,
|
||||
"nrequests_max": 15,
|
||||
"conn_time": 1234567890,
|
||||
"sock": {
|
||||
"fd": 102,
|
||||
"errfd": -1,
|
||||
"pid": -1,
|
||||
"isClient": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"auth": 2,
|
||||
"readonly": true,
|
||||
"nrequests_max": 66,
|
||||
"conn_time": 1234567890,
|
||||
"sock": {
|
||||
"fd": 103,
|
||||
"errfd": -1,
|
||||
"pid": -1,
|
||||
"isClient": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
70
tests/virnetdaemondata/output-data-client-timestamp.json
Normal file
70
tests/virnetdaemondata/output-data-client-timestamp.json
Normal file
@ -0,0 +1,70 @@
|
||||
{
|
||||
"servers": {
|
||||
"testServer0": {
|
||||
"min_workers": 10,
|
||||
"max_workers": 50,
|
||||
"priority_workers": 5,
|
||||
"max_clients": 100,
|
||||
"max_anonymous_clients": 10,
|
||||
"keepaliveInterval": 120,
|
||||
"keepaliveCount": 5,
|
||||
"next_client_id": 3,
|
||||
"services": [
|
||||
{
|
||||
"auth": 0,
|
||||
"readonly": true,
|
||||
"nrequests_client_max": 2,
|
||||
"socks": [
|
||||
{
|
||||
"fd": 100,
|
||||
"errfd": -1,
|
||||
"pid": 0,
|
||||
"isClient": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"auth": 2,
|
||||
"readonly": false,
|
||||
"nrequests_client_max": 5,
|
||||
"socks": [
|
||||
{
|
||||
"fd": 101,
|
||||
"errfd": -1,
|
||||
"pid": 0,
|
||||
"isClient": false
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"clients": [
|
||||
{
|
||||
"id": 1,
|
||||
"auth": 1,
|
||||
"readonly": true,
|
||||
"nrequests_max": 15,
|
||||
"conn_time": 1234567890,
|
||||
"sock": {
|
||||
"fd": 102,
|
||||
"errfd": -1,
|
||||
"pid": -1,
|
||||
"isClient": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"auth": 2,
|
||||
"readonly": true,
|
||||
"nrequests_max": 66,
|
||||
"conn_time": 1234567890,
|
||||
"sock": {
|
||||
"fd": 103,
|
||||
"errfd": -1,
|
||||
"pid": -1,
|
||||
"isClient": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
34
tests/virnetdaemonmock.c
Normal file
34
tests/virnetdaemonmock.c
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Red Hat, Inc.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* Author: Erik Skultety <eskultet@redhat.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include <time.h>
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||
|
||||
time_t time(time_t *t)
|
||||
{
|
||||
const time_t ret = 1234567890;
|
||||
if (t)
|
||||
*t = ret;
|
||||
return ret;
|
||||
}
|
@ -339,15 +339,17 @@ mymain(void)
|
||||
EXEC_RESTART_TEST("admin-server-names", 2);
|
||||
EXEC_RESTART_TEST("no-keepalive-required", 2);
|
||||
EXEC_RESTART_TEST("client-ids", 1);
|
||||
EXEC_RESTART_TEST("client-timestamp", 1);
|
||||
EXEC_RESTART_TEST_FAIL("anon-clients", 2);
|
||||
|
||||
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/virnetdaemonmock.so")
|
||||
#else
|
||||
static int
|
||||
mymain(void)
|
||||
{
|
||||
return EXIT_AM_SKIP;
|
||||
}
|
||||
#endif
|
||||
VIRT_TEST_MAIN(mymain);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user