
# HG changeset patch # User kaitlin@elm3b43.beaverton.ibm.com # Date 1224552270 25200 # Node ID 6d537f5e2b65c5d04963e9ff4e44e74c1e22b494 # Parent 155077ac9e3ca778dc8564aa86e991f24f373e7e Add get_vnc_sessions() to determine all of the VNC ports available or in use. Create a hash table where the port_value % 5900 is the has key. Signed-off-by: Kaitlin Rupert <karupert@us.ibm.com> diff -r 155077ac9e3c -r 6d537f5e2b65 src/Virt_KVMRedirectionSAP.c --- a/src/Virt_KVMRedirectionSAP.c Mon Oct 20 18:24:28 2008 -0700 +++ b/src/Virt_KVMRedirectionSAP.c Mon Oct 20 18:24:30 2008 -0700 @@ -109,6 +109,52 @@ return 1; } +static size_t get_vnc_hash_key(unsigned int key) +{ + return key % VNC_PORT_MIN; +} + +static CMPIStatus port_to_str(unsigned int port, + char **port_str) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + + if (asprintf(port_str, "%" PRIu16, port) == -1) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Unable to determine session port"); + } + + return s; +} + +static CMPIStatus port_convert(unsigned int port, + char *in_str, + int *out_port) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + char *str = NULL; + + if (in_str == NULL) { + s = port_to_str(port, &str); + if (s.rc != CMPI_RC_OK) + goto out; + } else + str = strdup(in_str); + + *out_port = strtol(str, NULL, 0); + if ((*out_port == LONG_MIN) || (*out_port == LONG_MAX)) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Failed to get port value"); + } + + out: + free(str); + + return s; +} + static int inst_from_dom(const CMPIBroker *broker, const CMPIObjectPath *ref, struct domain *dominfo, @@ -197,6 +243,68 @@ return inst; } +static CMPIStatus get_vnc_sessions(struct vnc_ports *vnc_hash[]) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + const char *path = PROC_TCP; + unsigned int lport = 0; + unsigned int rport = 0; + FILE *tcp_info; + char *line = NULL; + size_t len = 0; + char *remote_port; + int local_port; + int index; + int val; + int ret; + + tcp_info = fopen(path, "r"); + if (tcp_info== NULL) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Failed to open %s: %m", tcp_info); + goto out; + } + + if (getline(&line, &len, tcp_info) == -1) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Failed to read from %s", tcp_info); + goto out; + } + + while (getline(&line, &len, tcp_info) > 0) { + ret = sscanf(line, "%d: %*[^:]:%X %*[^:]:%X", &val, &lport, + &rport); + if (ret != 3) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Unable to determine active sessions"); + goto out; + } + + s = port_convert(lport, NULL, &local_port); + if (s.rc != CMPI_RC_OK) + goto out; + + if ((local_port < VNC_PORT_MIN) || (local_port > VNC_PORT_MAX)) + continue; + + s = port_to_str(rport, &remote_port); + if (s.rc != CMPI_RC_OK) + goto out; + + index = get_vnc_hash_key(local_port); + + vnc_list_add(vnc_hash[index], remote_port); + free(remote_port); + } + + out: + fclose(tcp_info); + return s; +} + static bool check_graphics(virDomainPtr dom, struct domain **dominfo) { @@ -225,6 +333,7 @@ virDomainPtr *domain_list; struct domain *dominfo = NULL; struct inst_list list; + struct vnc_ports* vnc_hash[HASH_SIZE]; int count; int i; @@ -233,6 +342,7 @@ return s; inst_list_init(&list); + vnc_list_init(vnc_hash); count = get_domain_list(conn, &domain_list); if (count < 0) { @@ -242,6 +352,10 @@ goto out; } else if (count == 0) goto out; + + s = get_vnc_sessions(vnc_hash); + if (s.rc != CMPI_RC_OK) + goto out; for (i = 0; i < count; i++) { CMPIInstance *inst = NULL; @@ -269,6 +383,7 @@ out: free(domain_list); inst_list_free(&list); + vnc_list_free(vnc_hash); return s; }