# HG changeset patch
# User kaitlin(a)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(a)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;
}