diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c index 7ec02ad8ca..f5d1e2fcd2 100644 --- a/daemon/libvirtd.c +++ b/daemon/libvirtd.c @@ -1389,7 +1389,7 @@ int main(int argc, char **argv) { goto cleanup; } - if (!(srv = virNetServerNew("libvirtd", + if (!(srv = virNetServerNew("libvirtd", 1, config->min_workers, config->max_workers, config->prio_workers, @@ -1464,7 +1464,7 @@ int main(int argc, char **argv) { goto cleanup; } - if (!(srvAdm = virNetServerNew("admin", + if (!(srvAdm = virNetServerNew("admin", 1, config->admin_min_workers, config->admin_max_workers, 0, diff --git a/src/libvirt_remote.syms b/src/libvirt_remote.syms index 66f93833af..c04987447f 100644 --- a/src/libvirt_remote.syms +++ b/src/libvirt_remote.syms @@ -105,6 +105,7 @@ virNetServerGetName; virNetServerHasClients; virNetServerNew; virNetServerNewPostExecRestart; +virNetServerNextClientID; virNetServerPreExecRestart; virNetServerProcessClients; virNetServerStart; diff --git a/src/locking/lock_daemon.c b/src/locking/lock_daemon.c index bfdcfc6e10..f889a347dc 100644 --- a/src/locking/lock_daemon.c +++ b/src/locking/lock_daemon.c @@ -160,7 +160,7 @@ virLockDaemonNew(virLockDaemonConfigPtr config, bool privileged) return NULL; } - if (!(srv = virNetServerNew("virtlockd", + if (!(srv = virNetServerNew("virtlockd", 1, 1, 1, 0, config->max_clients, config->max_clients, -1, 0, NULL, diff --git a/src/logging/log_daemon.c b/src/logging/log_daemon.c index 70339afa20..90f84270ff 100644 --- a/src/logging/log_daemon.c +++ b/src/logging/log_daemon.c @@ -150,7 +150,7 @@ virLogDaemonNew(virLogDaemonConfigPtr config, bool privileged) return NULL; } - if (!(logd->srv = virNetServerNew("virtlogd", + if (!(logd->srv = virNetServerNew("virtlogd", 1, 1, 1, 0, config->max_clients, config->max_clients, -1, 0, NULL, diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index de59775256..0304354b70 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -934,7 +934,7 @@ static int virLXCControllerSetupServer(virLXCControllerPtr ctrl) LXC_STATE_DIR, ctrl->name) < 0) return -1; - if (!(srv = virNetServerNew("LXC", + if (!(srv = virNetServerNew("LXC", 1, 0, 0, 0, 1, 0, -1, 0, NULL, diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c index 57bd95c22e..8216da6c2b 100644 --- a/src/rpc/virnetserver.c +++ b/src/rpc/virnetserver.c @@ -65,6 +65,7 @@ struct _virNetServer { size_t nclients; /* Current clients count */ virNetServerClientPtr *clients; /* Clients */ + unsigned long long next_client_id; /* next client ID */ size_t nclients_max; /* Max allowed clients count */ size_t nclients_unauth; /* Unauthenticated clients count */ size_t nclients_unauth_max; /* Max allowed unauth clients count */ @@ -103,6 +104,16 @@ static int virNetServerOnceInit(void) VIR_ONCE_GLOBAL_INIT(virNetServer) +unsigned long long virNetServerNextClientID(virNetServerPtr srv) +{ + unsigned long long val; + + virObjectLock(srv); + val = srv->next_client_id++; + virObjectUnlock(srv); + + return val; +} static int virNetServerProcessMsg(virNetServerPtr srv, virNetServerClientPtr client, @@ -283,7 +294,8 @@ static int virNetServerDispatchNewClient(virNetServerServicePtr svc, virNetServerPtr srv = opaque; virNetServerClientPtr client; - if (!(client = virNetServerClientNew(clientsock, + if (!(client = virNetServerClientNew(virNetServerNextClientID(srv), + clientsock, virNetServerServiceGetAuth(svc), virNetServerServiceIsReadonly(svc), virNetServerServiceGetMaxRequests(svc), @@ -307,6 +319,7 @@ static int virNetServerDispatchNewClient(virNetServerServicePtr svc, virNetServerPtr virNetServerNew(const char *name, + unsigned long long next_client_id, size_t min_workers, size_t max_workers, size_t priority_workers, @@ -338,6 +351,7 @@ virNetServerPtr virNetServerNew(const char *name, if (VIR_STRDUP(srv->name, name) < 0) goto error; + srv->next_client_id = next_client_id; srv->nclients_max = max_clients; srv->nclients_unauth_max = max_anonymous_clients; srv->keepaliveInterval = keepaliveInterval; @@ -384,6 +398,7 @@ virNetServerPtr virNetServerNewPostExecRestart(virJSONValuePtr object, unsigned int max_anonymous_clients; unsigned int keepaliveInterval; unsigned int keepaliveCount; + unsigned long long next_client_id; const char *mdnsGroupName = NULL; if (virJSONValueObjectGetNumberUint(object, "min_workers", &min_workers) < 0) { @@ -434,7 +449,13 @@ virNetServerPtr virNetServerNewPostExecRestart(virJSONValuePtr object, goto error; } - if (!(srv = virNetServerNew(name, + if (virJSONValueObjectGetNumberUlong(object, "next_client_id", + &next_client_id) < 0) { + VIR_WARN("Missing next_client_id data in JSON document"); + next_client_id = 1; + } + + if (!(srv = virNetServerNew(name, next_client_id, min_workers, max_workers, priority_workers, max_clients, max_anonymous_clients, @@ -503,7 +524,8 @@ virNetServerPtr virNetServerNewPostExecRestart(virJSONValuePtr object, clientPrivNewPostExecRestart, clientPrivPreExecRestart, clientPrivFree, - clientPrivOpaque))) + clientPrivOpaque, + srv))) goto error; if (virNetServerAddClient(srv, client) < 0) { @@ -573,6 +595,13 @@ virJSONValuePtr virNetServerPreExecRestart(virNetServerPtr srv) goto error; } + if (virJSONValueObjectAppendNumberUlong(object, "next_client_id", + srv->next_client_id) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot set next_client_id data in JSON document")); + goto error; + } + if (srv->mdnsGroupName && virJSONValueObjectAppendString(object, "mdnsGroupName", srv->mdnsGroupName) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h index 8b304f68e7..2ae89cefcc 100644 --- a/src/rpc/virnetserver.h +++ b/src/rpc/virnetserver.h @@ -35,6 +35,7 @@ virNetServerPtr virNetServerNew(const char *name, + unsigned long long next_client_id, size_t min_workers, size_t max_workers, size_t priority_workers, @@ -102,4 +103,6 @@ int virNetServerSetThreadPoolParameters(virNetServerPtr srv, long long int maxWorkers, long long int prioWorkers); +unsigned long long virNetServerNextClientID(virNetServerPtr srv); + #endif /* __VIR_NET_SERVER_H__ */ diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c index 64dab46314..7233773e85 100644 --- a/src/rpc/virnetserverclient.c +++ b/src/rpc/virnetserverclient.c @@ -28,6 +28,7 @@ # include #endif +#include "virnetserver.h" #include "virnetserverclient.h" #include "virlog.h" @@ -65,6 +66,7 @@ struct _virNetServerClient { virObjectLockable parent; + unsigned long long id; bool wantClose; bool delayedClose; virNetSocketPtr sock; @@ -346,7 +348,8 @@ static void virNetServerClientSockTimerFunc(int timer, static virNetServerClientPtr -virNetServerClientNewInternal(virNetSocketPtr sock, +virNetServerClientNewInternal(unsigned long long id, + virNetSocketPtr sock, int auth, #ifdef WITH_GNUTLS virNetTLSContextPtr tls, @@ -362,6 +365,7 @@ virNetServerClientNewInternal(virNetSocketPtr sock, if (!(client = virObjectLockableNew(virNetServerClientClass))) return NULL; + client->id = id; client->sock = virObjectRef(sock); client->auth = auth; client->readonly = readonly; @@ -395,7 +399,8 @@ virNetServerClientNewInternal(virNetSocketPtr sock, } -virNetServerClientPtr virNetServerClientNew(virNetSocketPtr sock, +virNetServerClientPtr virNetServerClientNew(unsigned long long id, + virNetSocketPtr sock, int auth, bool readonly, size_t nrequests_max, @@ -417,7 +422,7 @@ virNetServerClientPtr virNetServerClientNew(virNetSocketPtr sock, #endif ); - if (!(client = virNetServerClientNewInternal(sock, auth, + if (!(client = virNetServerClientNewInternal(id, sock, auth, #ifdef WITH_GNUTLS tls, #endif @@ -441,7 +446,8 @@ virNetServerClientPtr virNetServerClientNewPostExecRestart(virJSONValuePtr objec virNetServerClientPrivNewPostExecRestart privNew, virNetServerClientPrivPreExecRestart privPreExecRestart, virFreeCallback privFree, - void *privOpaque) + void *privOpaque, + void *opaque) { virJSONValuePtr child; virNetServerClientPtr client = NULL; @@ -449,6 +455,7 @@ virNetServerClientPtr virNetServerClientNewPostExecRestart(virJSONValuePtr objec int auth; bool readonly; unsigned int nrequests_max; + unsigned long long id; if (virJSONValueObjectGetNumberInt(object, "auth", &auth) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -473,12 +480,25 @@ virNetServerClientPtr virNetServerClientNewPostExecRestart(virJSONValuePtr objec return NULL; } + if (!virJSONValueObjectHasKey(object, "id")) { + /* no ID found in, a new one must be generated */ + id = virNetServerNextClientID((virNetServerPtr) opaque); + } else { + if (virJSONValueObjectGetNumberUlong(object, "id", + (unsigned long long *) &id) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Malformed id field in JSON state document")); + return NULL; + } + } + if (!(sock = virNetSocketNewPostExecRestart(child))) { virObjectUnref(sock); return NULL; } - if (!(client = virNetServerClientNewInternal(sock, + if (!(client = virNetServerClientNewInternal(id, + sock, auth, #ifdef WITH_GNUTLS NULL, @@ -521,6 +541,10 @@ virJSONValuePtr virNetServerClientPreExecRestart(virNetServerClientPtr client) virObjectLock(client); + if (virJSONValueObjectAppendNumberUlong(object, "id", + client->id) < 0) + goto error; + if (virJSONValueObjectAppendNumberInt(object, "auth", client->auth) < 0) goto error; if (virJSONValueObjectAppendBoolean(object, "readonly", client->readonly) < 0) @@ -581,6 +605,10 @@ bool virNetServerClientGetReadonly(virNetServerClientPtr client) return readonly; } +unsigned long long virNetServerClientGetID(virNetServerClientPtr client) +{ + return client->id; +} #ifdef WITH_GNUTLS bool virNetServerClientHasTLSSession(virNetServerClientPtr client) diff --git a/src/rpc/virnetserverclient.h b/src/rpc/virnetserverclient.h index 8d0fd18fe3..95edb0604b 100644 --- a/src/rpc/virnetserverclient.h +++ b/src/rpc/virnetserverclient.h @@ -49,7 +49,8 @@ typedef void *(*virNetServerClientPrivNewPostExecRestart)(virNetServerClientPtr typedef void *(*virNetServerClientPrivNew)(virNetServerClientPtr client, void *opaque); -virNetServerClientPtr virNetServerClientNew(virNetSocketPtr sock, +virNetServerClientPtr virNetServerClientNew(unsigned long long id, + virNetSocketPtr sock, int auth, bool readonly, size_t nrequests_max, @@ -65,7 +66,8 @@ virNetServerClientPtr virNetServerClientNewPostExecRestart(virJSONValuePtr objec virNetServerClientPrivNewPostExecRestart privNew, virNetServerClientPrivPreExecRestart privPreExecRestart, virFreeCallback privFree, - void *privOpaque); + void *privOpaque, + void *opaque); virJSONValuePtr virNetServerClientPreExecRestart(virNetServerClientPtr client); @@ -79,6 +81,7 @@ void virNetServerClientRemoveFilter(virNetServerClientPtr client, int virNetServerClientGetAuth(virNetServerClientPtr client); void virNetServerClientSetAuth(virNetServerClientPtr client, int auth); bool virNetServerClientGetReadonly(virNetServerClientPtr client); +unsigned long long virNetServerClientGetID(virNetServerClientPtr client); # ifdef WITH_GNUTLS bool virNetServerClientHasTLSSession(virNetServerClientPtr client); diff --git a/tests/virnetdaemondata/input-data-client-ids.json b/tests/virnetdaemondata/input-data-client-ids.json new file mode 100644 index 0000000000..7caa2ccd57 --- /dev/null +++ b/tests/virnetdaemondata/input-data-client-ids.json @@ -0,0 +1,68 @@ +{ + "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": 5, + "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": 2, + "auth": 1, + "readonly": true, + "nrequests_max": 15, + "sock": { + "fd": 102, + "errfd": -1, + "pid": -1, + "isClient": true + } + }, + { + "id": 3, + "auth": 2, + "readonly": true, + "nrequests_max": 66, + "sock": { + "fd": 103, + "errfd": -1, + "pid": -1, + "isClient": true + } + } + ] + } + } +} diff --git a/tests/virnetdaemondata/output-data-admin-nomdns.json b/tests/virnetdaemondata/output-data-admin-nomdns.json index 8827c04575..ca3acd1108 100644 --- a/tests/virnetdaemondata/output-data-admin-nomdns.json +++ b/tests/virnetdaemondata/output-data-admin-nomdns.json @@ -8,6 +8,7 @@ "max_anonymous_clients": 100, "keepaliveInterval": 120, "keepaliveCount": 5, + "next_client_id": 3, "services": [ { "auth": 0, @@ -38,6 +39,7 @@ ], "clients": [ { + "id": 1, "auth": 1, "readonly": true, "nrequests_max": 15, @@ -49,6 +51,7 @@ } }, { + "id": 2, "auth": 2, "readonly": true, "nrequests_max": 66, @@ -69,6 +72,7 @@ "max_anonymous_clients": 100, "keepaliveInterval": 120, "keepaliveCount": 5, + "next_client_id": 3, "services": [ { "auth": 0, @@ -99,6 +103,7 @@ ], "clients": [ { + "id": 1, "auth": 1, "readonly": true, "nrequests_max": 15, @@ -110,6 +115,7 @@ } }, { + "id": 2, "auth": 2, "readonly": true, "nrequests_max": 66, diff --git a/tests/virnetdaemondata/output-data-admin-server-names.json b/tests/virnetdaemondata/output-data-admin-server-names.json index 8827c04575..ca3acd1108 100644 --- a/tests/virnetdaemondata/output-data-admin-server-names.json +++ b/tests/virnetdaemondata/output-data-admin-server-names.json @@ -8,6 +8,7 @@ "max_anonymous_clients": 100, "keepaliveInterval": 120, "keepaliveCount": 5, + "next_client_id": 3, "services": [ { "auth": 0, @@ -38,6 +39,7 @@ ], "clients": [ { + "id": 1, "auth": 1, "readonly": true, "nrequests_max": 15, @@ -49,6 +51,7 @@ } }, { + "id": 2, "auth": 2, "readonly": true, "nrequests_max": 66, @@ -69,6 +72,7 @@ "max_anonymous_clients": 100, "keepaliveInterval": 120, "keepaliveCount": 5, + "next_client_id": 3, "services": [ { "auth": 0, @@ -99,6 +103,7 @@ ], "clients": [ { + "id": 1, "auth": 1, "readonly": true, "nrequests_max": 15, @@ -110,6 +115,7 @@ } }, { + "id": 2, "auth": 2, "readonly": true, "nrequests_max": 66, diff --git a/tests/virnetdaemondata/output-data-anon-clients.json b/tests/virnetdaemondata/output-data-anon-clients.json index df93e3b1a7..1a1909f40b 100644 --- a/tests/virnetdaemondata/output-data-anon-clients.json +++ b/tests/virnetdaemondata/output-data-anon-clients.json @@ -8,6 +8,7 @@ "max_anonymous_clients": 10, "keepaliveInterval": 120, "keepaliveCount": 5, + "next_client_id": 3, "services": [ { "auth": 0, @@ -38,6 +39,7 @@ ], "clients": [ { + "id": 1, "auth": 1, "readonly": true, "nrequests_max": 15, @@ -49,6 +51,7 @@ } }, { + "id": 2, "auth": 2, "readonly": true, "nrequests_max": 66, diff --git a/tests/virnetdaemondata/output-data-client-ids.json b/tests/virnetdaemondata/output-data-client-ids.json new file mode 100644 index 0000000000..7caa2ccd57 --- /dev/null +++ b/tests/virnetdaemondata/output-data-client-ids.json @@ -0,0 +1,68 @@ +{ + "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": 5, + "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": 2, + "auth": 1, + "readonly": true, + "nrequests_max": 15, + "sock": { + "fd": 102, + "errfd": -1, + "pid": -1, + "isClient": true + } + }, + { + "id": 3, + "auth": 2, + "readonly": true, + "nrequests_max": 66, + "sock": { + "fd": 103, + "errfd": -1, + "pid": -1, + "isClient": true + } + } + ] + } + } +} diff --git a/tests/virnetdaemondata/output-data-initial-nomdns.json b/tests/virnetdaemondata/output-data-initial-nomdns.json index 154962b4df..da007f352a 100644 --- a/tests/virnetdaemondata/output-data-initial-nomdns.json +++ b/tests/virnetdaemondata/output-data-initial-nomdns.json @@ -8,6 +8,7 @@ "max_anonymous_clients": 100, "keepaliveInterval": 120, "keepaliveCount": 5, + "next_client_id": 3, "services": [ { "auth": 0, @@ -38,6 +39,7 @@ ], "clients": [ { + "id": 1, "auth": 1, "readonly": true, "nrequests_max": 15, @@ -49,6 +51,7 @@ } }, { + "id": 2, "auth": 2, "readonly": true, "nrequests_max": 66, diff --git a/tests/virnetdaemondata/output-data-initial.json b/tests/virnetdaemondata/output-data-initial.json index b7c27dfda3..cdd02c2505 100644 --- a/tests/virnetdaemondata/output-data-initial.json +++ b/tests/virnetdaemondata/output-data-initial.json @@ -8,6 +8,7 @@ "max_anonymous_clients": 100, "keepaliveInterval": 120, "keepaliveCount": 5, + "next_client_id": 3, "mdnsGroupName": "libvirtTest", "services": [ { @@ -39,6 +40,7 @@ ], "clients": [ { + "id": 1, "auth": 1, "readonly": true, "nrequests_max": 15, @@ -50,6 +52,7 @@ } }, { + "id": 2, "auth": 2, "readonly": true, "nrequests_max": 66, diff --git a/tests/virnetdaemondata/output-data-no-keepalive-required.json b/tests/virnetdaemondata/output-data-no-keepalive-required.json index 8827c04575..ca3acd1108 100644 --- a/tests/virnetdaemondata/output-data-no-keepalive-required.json +++ b/tests/virnetdaemondata/output-data-no-keepalive-required.json @@ -8,6 +8,7 @@ "max_anonymous_clients": 100, "keepaliveInterval": 120, "keepaliveCount": 5, + "next_client_id": 3, "services": [ { "auth": 0, @@ -38,6 +39,7 @@ ], "clients": [ { + "id": 1, "auth": 1, "readonly": true, "nrequests_max": 15, @@ -49,6 +51,7 @@ } }, { + "id": 2, "auth": 2, "readonly": true, "nrequests_max": 66, @@ -69,6 +72,7 @@ "max_anonymous_clients": 100, "keepaliveInterval": 120, "keepaliveCount": 5, + "next_client_id": 3, "services": [ { "auth": 0, @@ -99,6 +103,7 @@ ], "clients": [ { + "id": 1, "auth": 1, "readonly": true, "nrequests_max": 15, @@ -110,6 +115,7 @@ } }, { + "id": 2, "auth": 2, "readonly": true, "nrequests_max": 66, diff --git a/tests/virnetdaemontest.c b/tests/virnetdaemontest.c index a20eee6f90..b98c14805c 100644 --- a/tests/virnetdaemontest.c +++ b/tests/virnetdaemontest.c @@ -49,7 +49,7 @@ testCreateServer(const char *server_name, const char *host, int family) goto cleanup; } - if (!(srv = virNetServerNew(server_name, + if (!(srv = virNetServerNew(server_name, 1, 10, 50, 5, 100, 10, 120, 5, mdns_group, @@ -93,7 +93,8 @@ testCreateServer(const char *server_name, const char *host, int family) if (virNetSocketNewConnectSockFD(fdclient[1], &sk2) < 0) goto error; - if (!(cln1 = virNetServerClientNew(sk1, + if (!(cln1 = virNetServerClientNew(virNetServerNextClientID(srv), + sk1, VIR_NET_SERVER_SERVICE_AUTH_SASL, true, 15, @@ -103,7 +104,8 @@ testCreateServer(const char *server_name, const char *host, int family) NULL, NULL, NULL, NULL))) goto error; - if (!(cln2 = virNetServerClientNew(sk2, + if (!(cln2 = virNetServerClientNew(virNetServerNextClientID(srv), + sk2, VIR_NET_SERVER_SERVICE_AUTH_POLKIT, true, 66, @@ -336,6 +338,7 @@ mymain(void) EXEC_RESTART_TEST("admin-nomdns", 2); EXEC_RESTART_TEST("admin-server-names", 2); EXEC_RESTART_TEST("no-keepalive-required", 2); + EXEC_RESTART_TEST("client-ids", 1); EXEC_RESTART_TEST_FAIL("anon-clients", 2); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; diff --git a/tests/virnetserverclienttest.c b/tests/virnetserverclienttest.c index 9c4b4c6cfb..be15e81a7e 100644 --- a/tests/virnetserverclienttest.c +++ b/tests/virnetserverclienttest.c @@ -52,7 +52,7 @@ static int testIdentity(const void *opaque ATTRIBUTE_UNUSED) } sv[0] = -1; - if (!(client = virNetServerClientNew(sock, 0, false, 1, + if (!(client = virNetServerClientNew(1, sock, 0, false, 1, # ifdef WITH_GNUTLS NULL, # endif