return ret;
}
+/* -------------------
+ * Command client-info
+ * -------------------
+ */
+
+static const vshCmdInfo info_client_info[] = {
+ {.name = "help",
+ .data = N_("retrieve client's identity info from server")
+ },
+ {.name = "desc",
+ .data = N_("Retrieve identity details about <client> from <server>")
+ },
+ {.name = NULL}
+};
+
+static const vshCmdOptDef opts_client_info[] = {
+ {.name = "server",
+ .type = VSH_OT_DATA,
+ .flags = VSH_OFLAG_REQ,
+ .help = N_("server to which <client> is connected to"),
+ },
+ {.name = "client",
+ .type = VSH_OT_DATA,
+ .flags = VSH_OFLAG_REQ,
+ .help = N_("client which to retrieve identity information for"),
+ },
+ {.name = NULL}
+};
+
+static bool
+cmdClientInfo(vshControl *ctl, const vshCmd *cmd)
+{
+ bool ret = false;
+ size_t i;
+ unsigned long long id;
+ const char *srvname = NULL;
+ char *timestr = NULL;
+ virAdmServerPtr srv = NULL;
+ virAdmClientPtr clnt = NULL;
+ virTypedParameterPtr params = NULL;
+ int nparams = 0;
+ vshAdmControlPtr priv = ctl->privData;
+
+ if (vshCommandOptULongLong(ctl, cmd, "client", &id) < 0)
+ return false;
+
+ if (vshCommandOptStringReq(ctl, cmd, "server", &srvname) < 0)
+ return false;
+
+ if (!(srv = virAdmConnectLookupServer(priv->conn, srvname, 0)) ||
+ !(clnt = virAdmServerLookupClient(srv, id, 0)))
+ goto cleanup;
+
+ /* Retrieve client identity info */
+ if (virAdmClientGetInfo(clnt, ¶ms, &nparams, 0) < 0) {
+ vshError(ctl, _("failed to retrieve client identity information for "
+ "client '%llu' connected to server '%s'"),
+ id, virAdmServerGetName(srv));
+ goto cleanup;
+ }
+
+ if (vshAdmGetTimeStr(ctl, virAdmClientGetTimestamp(clnt), ×tr) < 0)
+ goto cleanup;
+
+ /* this info is provided by the client object itself */
+ vshPrint(ctl, "%-15s: %llu\n", "id", virAdmClientGetID(clnt));
+ vshPrint(ctl, "%-15s: %s\n", "connection_time", timestr);
+ vshPrint(ctl, "%-15s: %s\n", "transport",
+ vshAdmClientTransportToString(virAdmClientGetTransport(clnt)));
+
+ for (i = 0; i < nparams; i++) {
+ char *str = vshGetTypedParamValue(ctl, ¶ms[i]);
+ vshPrint(ctl, "%-15s: %s\n", params[i].field, str);
+ VIR_FREE(str);
+ }
+
+ ret = true;
+
+ cleanup:
+ virTypedParamsFree(params, nparams);
+ virAdmServerFree(srv);
+ virAdmClientFree(clnt);
+ VIR_FREE(timestr);
+ return ret;
+}
static void *
vshAdmConnectionHandler(vshControl *ctl)
{
.info = info_srv_clients_list,
.flags = 0
},
+ {.name = "client-info",
+ .handler = cmdClientInfo,
+ .opts = opts_client_info,
+ .info = info_client_info,
+ .flags = 0
+ },
{.name = NULL}
};
=back
+=head1 CLIENT COMMANDS
+
+Following commands provide management and monitoring of clients connected to
+one of daemon's available servers. Clients are specified by their numeric ID
+which is obtained by listing all clients connected to a specified server
+(see command B<srv-clients-list>).
+
+=over 4
+
+=item B<client-info> I<server> I<client>
+
+Retrieve identity information about I<client> from I<server>. The attributes
+returned may vary depending on the connection transport used.
+Transport-dependent attributes include local client process's pid, uid,
+user name, and group name, as well as socket address of the remote peer, see
+B<Examples> below.
+
+On the other hand, transport-independent attributes include client's SELinux
+context (if enabled on the host) and SASL username (if SASL authentication is
+enabled within daemon).
+
+B<Examples>
+
+ # virt-admin client-info libvirtd 1
+ id : 1
+ connection_time: 2016-05-03 13:27:04+0200
+ transport : unix
+ readonly : yes
+ unix_user_id : 0
+ unix_user_name : root
+ unix_group_id : 0
+ unix_group_name: root
+ unix_process_id: 10201
+
+ # virt-admin client-info libvirtd 2
+ id : 2
+ connection_time: 2016-05-03 13:30:33+0200
+ transport : tcp
+ readonly : no
+ sock_addr : 127.0.0.1:57060
+
+=back
+
=head1 ENVIRONMENT
The following environment variables can be set to alter the behaviour