diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c index ef465ed3746d12dfdeadb7a4bed627262c6d4087..8e199ee2bbcffb785944a763887a530c386643ed 100644 --- a/src/phyp/phyp_driver.c +++ b/src/phyp/phyp_driver.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -39,6 +40,9 @@ #include #include #include +#include +#include +#include #include "internal.h" #include "util.h" @@ -51,15 +55,12 @@ #include "virterror_internal.h" #include "uuid.h" #include "domain_conf.h" +#include "nodeinfo.h" #include "phyp_driver.h" #define VIR_FROM_THIS VIR_FROM_PHYP -#define PHYP_CMD_DEBUG VIR_DEBUG("COMMAND:%s\n",cmd); - -static int escape_specialcharacters(char *src, char *dst, size_t dstlen); - /* * URI: phyp://user@[hmc|ivm]/managed_system * */ @@ -72,8 +73,11 @@ phypOpen(virConnectPtr conn, ConnectionData *connection_data = NULL; char *string; size_t len = 0; - uuid_dbPtr uuid_db = NULL; int internal_socket; + uuid_tablePtr uuid_table = NULL; + phyp_driverPtr phyp_driver = NULL; + char *char_ptr; + char *managed_system; if (!conn || !conn->uri) return VIR_DRV_OPEN_DECLINED; @@ -88,6 +92,13 @@ phypOpen(virConnectPtr conn, return VIR_DRV_OPEN_ERROR; } + if (conn->uri->path == NULL) { + virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP, + VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, "%s", + _("Missing managed system name in phyp:// URI")); + return VIR_DRV_OPEN_ERROR; + } + if (conn->uri->path == NULL) { virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP, VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, "%s", @@ -95,7 +106,12 @@ phypOpen(virConnectPtr conn, return VIR_DRV_OPEN_ERROR; } - if (VIR_ALLOC(uuid_db) < 0) { + if (VIR_ALLOC(phyp_driver) < 0) { + virReportOOMError(conn); + goto failure; + } + + if (VIR_ALLOC(uuid_table) < 0) { virReportOOMError(conn); goto failure; } @@ -112,6 +128,27 @@ phypOpen(virConnectPtr conn, goto failure; } + if (VIR_ALLOC_N(managed_system, len) < 0) { + virReportOOMError(conn); + goto failure; + } + + managed_system = strdup(conn->uri->path); + if (!managed_system) + goto failure; + + /* need to shift one byte in order to remove the first "/" of URI component */ + if (managed_system[0] == '/') + managed_system++; + + /* here we are handling only the first component of the path, + * so skipping the second: + * */ + char_ptr = strchr(managed_system, '/'); + + if (char_ptr) + *char_ptr = '\0'; + if (escape_specialcharacters(conn->uri->path, string, len) == -1) { virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP, VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, "%s", @@ -129,17 +166,32 @@ phypOpen(virConnectPtr conn, connection_data->session = session; connection_data->auth = auth; - uuid_db->nlpars = 0; - uuid_db->lpars = NULL; + uuid_table->nlpars = 0; + uuid_table->lpars = NULL; + + phyp_driver->managed_system = managed_system; + phyp_driver->uuid_table = uuid_table; + if ((phyp_driver->caps = phypCapsInit()) == NULL) { + virReportOOMError(conn); + goto failure; + } - conn->privateData = uuid_db; + conn->privateData = phyp_driver; conn->networkPrivateData = connection_data; - init_uuid_db(conn); + if (phypUUIDTable_Init(conn) == -1) + goto failure; + + if ((phyp_driver->vios_id = phypGetVIOSPartitionID(conn)) == -1) + goto failure; return VIR_DRV_OPEN_SUCCESS; failure: - VIR_FREE(uuid_db); + virCapabilitiesFree(phyp_driver->caps); + VIR_FREE(phyp_driver->managed_system); + VIR_FREE(phyp_driver); + VIR_FREE(uuid_table); + VIR_FREE(uuid_table->lpars); VIR_FREE(connection_data); VIR_FREE(string); @@ -150,11 +202,17 @@ static int phypClose(virConnectPtr conn) { ConnectionData *connection_data = conn->networkPrivateData; + phyp_driverPtr phyp_driver = conn->privateData; LIBSSH2_SESSION *session = connection_data->session; libssh2_session_disconnect(session, "Disconnecting..."); libssh2_session_free(session); + virCapabilitiesFree(phyp_driver->caps); + VIR_FREE(phyp_driver->uuid_table); + VIR_FREE(phyp_driver->uuid_table->lpars); + VIR_FREE(phyp_driver->managed_system); + VIR_FREE(phyp_driver); VIR_FREE(connection_data); return 0; } @@ -174,17 +232,16 @@ openSSHSession(virConnectPtr conn, virConnectAuthPtr auth, struct addrinfo hints; int ret; - memset (&hints, '\0', sizeof (hints)); + memset(&hints, '\0', sizeof(hints)); hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = 0; - ret = getaddrinfo (hostname, "22", &hints, &ai); + ret = getaddrinfo(hostname, "22", &hints, &ai); if (ret != 0) { virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP, VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, - _("Error while getting %s address info"), - hostname); + _("Error while getting %s address info"), hostname); goto err; } @@ -192,10 +249,10 @@ openSSHSession(virConnectPtr conn, virConnectAuthPtr auth, while (cur != NULL) { sock = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol); if (sock >= 0) { - if (connect (sock, cur->ai_addr, cur->ai_addrlen) == 0) { + if (connect(sock, cur->ai_addr, cur->ai_addrlen) == 0) { goto connected; } - close (sock); + close(sock); } cur = cur->ai_next; } @@ -203,10 +260,10 @@ openSSHSession(virConnectPtr conn, virConnectAuthPtr auth, virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP, VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, _("Failed to connect to %s"), hostname); - freeaddrinfo (ai); + freeaddrinfo(ai); goto err; -connected: + connected: (*internal_socket) = sock; @@ -407,7 +464,6 @@ phypGetLparID(LIBSSH2_SESSION * session, const char *managed_system, virReportOOMError(conn); goto err; } - PHYP_CMD_DEBUG; const char *ret = phypExec(session, cmd, &exit_status, conn); @@ -439,7 +495,6 @@ phypGetLparNAME(LIBSSH2_SESSION * session, const char *managed_system, virReportOOMError(conn); goto err; } - PHYP_CMD_DEBUG; char *ret = phypExec(session, cmd, &exit_status, conn); @@ -463,7 +518,7 @@ phypGetLparNAME(LIBSSH2_SESSION * session, const char *managed_system, } -/* Search into the uuid_db for a lpar_uuid given a lpar_id +/* Search into the uuid_table for a lpar_uuid given a lpar_id * and a managed system name * * return: 0 - record found @@ -472,11 +527,12 @@ phypGetLparNAME(LIBSSH2_SESSION * session, const char *managed_system, int phypGetLparUUID(unsigned char *uuid, int lpar_id, virConnectPtr conn) { - uuid_dbPtr uuid_db = conn->privateData; - lparPtr *lpars = uuid_db->lpars; + phyp_driverPtr phyp_driver = conn->privateData; + uuid_tablePtr uuid_table = phyp_driver->uuid_table; + lparPtr *lpars = uuid_table->lpars; unsigned int i = 0; - for (i = 0; i < uuid_db->nlpars; i++) { + for (i = 0; i < uuid_table->nlpars; i++) { if (lpars[i]->id == lpar_id) { memmove(uuid, lpars[i]->uuid, VIR_UUID_BUFLEN); return 0; @@ -507,20 +563,21 @@ phypGetLparMem(virConnectPtr conn, const char *managed_system, int lpar_id, if (type) { if (virAsprintf(&cmd, - "lshwres -m %s -r mem --level lpar -F curr_mem --filter lpar_ids=%d", + "lshwres -m %s -r mem --level lpar -F curr_mem " + "--filter lpar_ids=%d", managed_system, lpar_id) < 0) { virReportOOMError(conn); goto err; } } else { if (virAsprintf(&cmd, - "lshwres -m %s -r mem --level lpar -F curr_max_mem --filter lpar_ids=%d", + "lshwres -m %s -r mem --level lpar -F " + "curr_max_mem --filter lpar_ids=%d", managed_system, lpar_id) < 0) { virReportOOMError(conn); goto err; } } - PHYP_CMD_DEBUG; char *ret = phypExec(session, cmd, &exit_status, conn); @@ -549,6 +606,22 @@ phypGetLparMem(virConnectPtr conn, const char *managed_system, int lpar_id, unsigned long phypGetLparCPU(virConnectPtr conn, const char *managed_system, int lpar_id) +{ + return phypGetLparCPUGeneric(conn, managed_system, lpar_id, 0); +} + +static int +phypGetLparCPUMAX(virDomainPtr dom) +{ + phyp_driverPtr phyp_driver = dom->conn->privateData; + char *managed_system = phyp_driver->managed_system; + + return phypGetLparCPUGeneric(dom->conn, managed_system, dom->id, 1); +} + +unsigned long +phypGetLparCPUGeneric(virConnectPtr conn, const char *managed_system, + int lpar_id, int type) { ConnectionData *connection_data = conn->networkPrivateData; LIBSSH2_SESSION *session = connection_data->session; @@ -556,13 +629,23 @@ phypGetLparCPU(virConnectPtr conn, const char *managed_system, int lpar_id) int exit_status = 0; int vcpus = 0; - if (virAsprintf(&cmd, - "lshwres -m %s -r proc --level lpar -F curr_procs --filter lpar_ids=%d", - managed_system, lpar_id) < 0) { - virReportOOMError(conn); - goto err; + if (type) { + if (virAsprintf(&cmd, + "lshwres -m %s -r proc --level lpar -F " + "curr_max_procs --filter lpar_ids=%d", + managed_system, lpar_id) < 0) { + virReportOOMError(conn); + goto err; + } + } else { + if (virAsprintf(&cmd, + "lshwres -m %s -r proc --level lpar -F " + "curr_procs --filter lpar_ids=%d", + managed_system, lpar_id) < 0) { + virReportOOMError(conn); + goto err; + } } - PHYP_CMD_DEBUG; char *ret = phypExec(session, cmd, &exit_status, conn); if (ret == NULL) @@ -599,12 +682,12 @@ phypGetRemoteSlot(virConnectPtr conn, const char *managed_system, int exit_status = 0; if (virAsprintf(&cmd, - "lshwres -m %s -r virtualio --rsubtype scsi -F remote_slot_num --filter lpar_names=%s", + "lshwres -m %s -r virtualio --rsubtype scsi -F " + "remote_slot_num --filter lpar_names=%s", managed_system, lpar_name) < 0) { virReportOOMError(conn); goto err; } - PHYP_CMD_DEBUG; char *ret = phypExec(session, cmd, &exit_status, conn); if (ret == NULL) @@ -626,7 +709,7 @@ phypGetRemoteSlot(virConnectPtr conn, const char *managed_system, err: VIR_FREE(cmd); - return 0; + return -1; } char * @@ -640,16 +723,16 @@ phypGetBackingDevice(virConnectPtr conn, const char *managed_system, int exit_status = 0; if ((remote_slot = - phypGetRemoteSlot(conn, managed_system, lpar_name)) == 0) + phypGetRemoteSlot(conn, managed_system, lpar_name)) == -1) goto err; if (virAsprintf(&cmd, - "lshwres -m %s -r virtualio --rsubtype scsi -F backing_devices --filter slots=%d", + "lshwres -m %s -r virtualio --rsubtype scsi -F " + "backing_devices --filter slots=%d", managed_system, remote_slot) < 0) { virReportOOMError(conn); goto err; } - PHYP_CMD_DEBUG; char *ret = phypExec(session, cmd, &exit_status, conn); @@ -696,24 +779,12 @@ int phypGetLparState(virConnectPtr conn, unsigned int lpar_id) { ConnectionData *connection_data = conn->networkPrivateData; + phyp_driverPtr phyp_driver = conn->privateData; LIBSSH2_SESSION *session = connection_data->session; char *cmd; int exit_status = 0; char *char_ptr = NULL; - char *managed_system = conn->uri->path; - - /* need to shift one byte in order to remove the first "/" of URI component */ - if (managed_system[0] == '/') - managed_system++; - - /* here we are handling only the first component of the path, - * so skipping the second: - * */ - - char_ptr = strchr(managed_system, '/'); - - if (char_ptr) - *char_ptr = '\0'; + char *managed_system = phyp_driver->managed_system; if (virAsprintf(&cmd, "lssyscfg -r lpar -m %s -F state --filter lpar_ids=%d", @@ -721,7 +792,6 @@ phypGetLparState(virConnectPtr conn, unsigned int lpar_id) virReportOOMError(conn); goto err; } - PHYP_CMD_DEBUG; char *ret = phypExec(session, cmd, &exit_status, conn); @@ -751,28 +821,66 @@ phypGetLparState(virConnectPtr conn, unsigned int lpar_id) return VIR_DOMAIN_NOSTATE; } +int +phypGetVIOSPartitionID(virConnectPtr conn) +{ + ConnectionData *connection_data = conn->networkPrivateData; + phyp_driverPtr phyp_driver = conn->privateData; + LIBSSH2_SESSION *session = connection_data->session; + char *cmd; + int exit_status = 0; + int id = -1; + char *char_ptr; + char *managed_system = phyp_driver->managed_system; + + if (virAsprintf(&cmd, + "lssyscfg -m %s -r lpar -F lpar_id,lpar_env|grep " + "vioserver|sed -s 's/,.*$//g'", managed_system) < 0) { + virReportOOMError(conn); + goto err; + } + + char *ret = phypExec(session, cmd, &exit_status, conn); + + if (exit_status < 0 || ret == NULL) + goto err; + + if (virStrToLong_i(ret, &char_ptr, 10, &id) == -1) + goto err; + + return id; + + err: + VIR_FREE(cmd); + return -1; +} + int phypDiskType(virConnectPtr conn, char *backing_device) { + phyp_driverPtr phyp_driver = conn->privateData; ConnectionData *connection_data = conn->networkPrivateData; LIBSSH2_SESSION *session = connection_data->session; char *cmd; int exit_status = 0; + char *char_ptr; + char *managed_system = phyp_driver->managed_system; + int vios_id = phyp_driver->vios_id; if (virAsprintf(&cmd, - "ioscli lssp -field name type -fmt , -all|grep %s|sed -e 's/^.*,//g'", - backing_device) < 0) { + "viosvrcmd -m %s -p %d -c \"lssp -field name type " + "-fmt , -all|grep %s|sed -e 's/^.*,//g'\"", + managed_system, vios_id, backing_device) < 0) { virReportOOMError(conn); goto err; } - PHYP_CMD_DEBUG; char *ret = phypExec(session, cmd, &exit_status, conn); if (ret == NULL) goto err; - char *char_ptr = strchr(ret, '\n'); + char_ptr = strchr(ret, '\n'); if (char_ptr) *char_ptr = '\0'; @@ -805,12 +913,13 @@ static int phypNumDomainsGeneric(virConnectPtr conn, unsigned int type) { ConnectionData *connection_data = conn->networkPrivateData; + phyp_driverPtr phyp_driver = conn->privateData; LIBSSH2_SESSION *session = connection_data->session; int exit_status = 0; int ndom = 0; char *char_ptr; char *cmd; - char *managed_system = conn->uri->path; + char *managed_system = phyp_driver->managed_system; const char *state; if (type == 0) @@ -820,26 +929,12 @@ phypNumDomainsGeneric(virConnectPtr conn, unsigned int type) else state = " "; - /* need to shift one byte in order to remove the first "/" of URI component */ - if (managed_system[0] == '/') - managed_system++; - - /* here we are handling only the first component of the path, - * so skipping the second: - * */ - - char_ptr = strchr(managed_system, '/'); - - if (char_ptr) - *char_ptr = '\0'; - if (virAsprintf(&cmd, - "lssyscfg -r lpar -m %s -F lpar_id,state %s |grep -c ^[0-9]*", - managed_system, state) < 0) { + "lssyscfg -r lpar -m %s -F lpar_id,state %s |grep -c " + "^[0-9]*", managed_system, state) < 0) { virReportOOMError(conn); goto err; } - PHYP_CMD_DEBUG; char *ret = phypExec(session, cmd, &exit_status, conn); @@ -874,15 +969,16 @@ phypNumDomains(virConnectPtr conn) * in different states: Running, and all: * * type: 0 - Running - * * - all + * 1 - all * */ static int phypListDomainsGeneric(virConnectPtr conn, int *ids, int nids, unsigned int type) { ConnectionData *connection_data = conn->networkPrivateData; + phyp_driverPtr phyp_driver = conn->privateData; LIBSSH2_SESSION *session = connection_data->session; - char *managed_system = conn->uri->path; + char *managed_system = phyp_driver->managed_system; int exit_status = 0; int got = 0; char *char_ptr; @@ -896,18 +992,6 @@ phypListDomainsGeneric(virConnectPtr conn, int *ids, int nids, else state = " "; - /* need to shift one byte in order to remove the first "/" of URI component */ - if (managed_system[0] == '/') - managed_system++; - - /* here we are handling only the first component of the path, - * so skipping the second: - * */ - char_ptr = strchr(managed_system, '/'); - - if (char_ptr) - *char_ptr = '\0'; - memset(id_c, 0, 10); if (virAsprintf @@ -917,7 +1001,6 @@ phypListDomainsGeneric(virConnectPtr conn, int *ids, int nids, virReportOOMError(conn); goto err; } - PHYP_CMD_DEBUG; char *ret = phypExec(session, cmd, &exit_status, conn); /* I need to parse the textual return in order to get the ret */ @@ -957,34 +1040,21 @@ static int phypListDefinedDomains(virConnectPtr conn, char **const names, int nnames) { ConnectionData *connection_data = conn->networkPrivateData; + phyp_driverPtr phyp_driver = conn->privateData; LIBSSH2_SESSION *session = connection_data->session; - char *managed_system = conn->uri->path; + char *managed_system = phyp_driver->managed_system; int exit_status = 0; int got = 0; - char *char_ptr = NULL; char *cmd; char *domains; - /* need to shift one byte in order to remove the first "/" of URI component */ - if (managed_system[0] == '/') - managed_system++; - - /* here we are handling only the first component of the path, - * so skipping the second: - * */ - char_ptr = strchr(managed_system, '/'); - - if (char_ptr) - *char_ptr = '\0'; - if (virAsprintf (&cmd, - "lssyscfg -r lpar -m %s -F name,state | grep \"Not Activated\" | sed -e 's/,.*$//g'", - managed_system) < 0) { + "lssyscfg -r lpar -m %s -F name,state | grep \"Not Activated\" | " + "sed -e 's/,.*$//g'", managed_system) < 0) { virReportOOMError(conn); goto err; } - PHYP_CMD_DEBUG; char *ret = phypExec(session, cmd, &exit_status, conn); @@ -1030,29 +1100,18 @@ static virDomainPtr phypDomainLookupByName(virConnectPtr conn, const char *lpar_name) { ConnectionData *connection_data = conn->networkPrivateData; + phyp_driverPtr phyp_driver = conn->privateData; LIBSSH2_SESSION *session = connection_data->session; virDomainPtr dom = NULL; int lpar_id = 0; - char *managed_system = conn->uri->path; + char *managed_system = phyp_driver->managed_system; unsigned char *lpar_uuid = NULL; if (VIR_ALLOC_N(lpar_uuid, VIR_UUID_BUFLEN) < 0) virReportOOMError(dom->conn); - /* need to shift one byte in order to remove the first "/" of uri component */ - if (managed_system[0] == '/') - managed_system++; - - /* here we are handling only the first component of the path, - * so skipping the second: - * */ - char *char_ptr = strchr(managed_system, '/'); - - if (char_ptr) - *char_ptr = '\0'; - lpar_id = phypGetLparID(session, managed_system, lpar_name, conn); - if (lpar_id < 0) + if (lpar_id == -1) goto err; if (phypGetLparUUID(lpar_uuid, lpar_id, conn) == -1) @@ -1075,27 +1134,16 @@ static virDomainPtr phypDomainLookupByID(virConnectPtr conn, int lpar_id) { ConnectionData *connection_data = conn->networkPrivateData; + phyp_driverPtr phyp_driver = conn->privateData; LIBSSH2_SESSION *session = connection_data->session; virDomainPtr dom = NULL; - char *managed_system = conn->uri->path; + char *managed_system = phyp_driver->managed_system; int exit_status = 0; unsigned char *lpar_uuid = NULL; if (VIR_ALLOC_N(lpar_uuid, VIR_UUID_BUFLEN) < 0) virReportOOMError(dom->conn); - /* need to shift one byte in order to remove the first "/" of uri component */ - if (managed_system[0] == '/') - managed_system++; - - /* here we are handling only the first component of the path, - * so skipping the second: - * */ - char *char_ptr = strchr(managed_system, '/'); - - if (char_ptr) - *char_ptr = '\0'; - char *lpar_name = phypGetLparNAME(session, managed_system, lpar_id, conn); @@ -1124,10 +1172,11 @@ static char * phypDomainDumpXML(virDomainPtr dom, int flags) { ConnectionData *connection_data = dom->conn->networkPrivateData; + phyp_driverPtr phyp_driver = dom->conn->privateData; LIBSSH2_SESSION *session = connection_data->session; virDomainDefPtr def = NULL; char *ret = NULL; - char *managed_system = dom->conn->uri->path; + char *managed_system = phyp_driver->managed_system; unsigned char *lpar_uuid = NULL; if (VIR_ALLOC_N(lpar_uuid, VIR_UUID_BUFLEN) < 0) @@ -1136,18 +1185,6 @@ phypDomainDumpXML(virDomainPtr dom, int flags) if (VIR_ALLOC(def) < 0) virReportOOMError(dom->conn); - /* need to shift one byte in order to remove the first "/" of uri component */ - if (managed_system[0] == '/') - managed_system++; - - /* here we are handling only the first component of the path, - * so skipping the second: - * */ - char *char_ptr = strchr(managed_system, '/'); - - if (char_ptr) - *char_ptr = '\0'; - def->virtType = VIR_DOMAIN_VIRT_PHYP; def->id = dom->id; @@ -1189,33 +1226,24 @@ phypDomainDumpXML(virDomainPtr dom, int flags) ret = virDomainDefFormat(dom->conn, def, flags); - err: - VIR_FREE(def); + virDomainDefFree(def); return ret; + + err: + virDomainDefFree(def); + return NULL; } static int phypDomainResume(virDomainPtr dom) { ConnectionData *connection_data = dom->conn->networkPrivateData; + phyp_driverPtr phyp_driver = dom->conn->privateData; LIBSSH2_SESSION *session = connection_data->session; - char *managed_system = dom->conn->uri->path; + char *managed_system = phyp_driver->managed_system; int exit_status = 0; - char *char_ptr = NULL; char *cmd; - /* need to shift one byte in order to remove the first "/" of URI component */ - if (managed_system[0] == '/') - managed_system++; - - /* here we are handling only the first component of the path, - * so skipping the second: - * */ - char_ptr = strchr(managed_system, '/'); - - if (char_ptr) - *char_ptr = '\0'; - if (virAsprintf (&cmd, "chsysstate -m %s -r lpar -o on --id %d -f %s", @@ -1223,39 +1251,32 @@ phypDomainResume(virDomainPtr dom) virReportOOMError(dom->conn); goto err; } - PHYP_CMD_DEBUG; char *ret = phypExec(session, cmd, &exit_status, dom->conn); - err: + if (exit_status < 0) + goto err; + VIR_FREE(cmd); VIR_FREE(ret); return 0; + err: + VIR_FREE(cmd); + VIR_FREE(ret); + return -1; } static int phypDomainShutdown(virDomainPtr dom) { ConnectionData *connection_data = dom->conn->networkPrivateData; + phyp_driverPtr phyp_driver = dom->conn->privateData; LIBSSH2_SESSION *session = connection_data->session; - char *managed_system = dom->conn->uri->path; + char *managed_system = phyp_driver->managed_system; int exit_status = 0; - char *char_ptr = NULL; char *cmd; - /* need to shift one byte in order to remove the first "/" of URI component */ - if (managed_system[0] == '/') - managed_system++; - - /* here we are handling only the first component of the path, - * so skipping the second: - * */ - char_ptr = strchr(managed_system, '/'); - - if (char_ptr) - *char_ptr = '\0'; - if (virAsprintf (&cmd, "chsysstate -m %s -r lpar -o shutdown --id %d", @@ -1263,33 +1284,27 @@ phypDomainShutdown(virDomainPtr dom) virReportOOMError(dom->conn); goto err; } - PHYP_CMD_DEBUG; char *ret = phypExec(session, cmd, &exit_status, dom->conn); - err: + if (exit_status < 0) + goto err; + VIR_FREE(cmd); VIR_FREE(ret); return 0; + err: + VIR_FREE(cmd); + VIR_FREE(ret); + return 0; } static int phypDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info) { - char *managed_system = dom->conn->uri->path; - - /* need to shift one byte in order to remove the first "/" of uri component */ - if (managed_system[0] == '/') - managed_system++; - - /* here we are handling only the first component of the path, - * so skipping the second: - * */ - char *char_ptr = strchr(managed_system, '/'); - - if (char_ptr) - *char_ptr = '\0'; + phyp_driverPtr phyp_driver = dom->conn->privateData; + char *managed_system = phyp_driver->managed_system; info->state = phypGetLparState(dom->conn, dom->id); @@ -1306,44 +1321,248 @@ phypDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info) VIR_WARN("%s", "Unable to determine domain's CPU."); return 0; - } -virDriver phypDriver = { - VIR_DRV_PHYP, - "PHYP", - phypOpen, /* open */ - phypClose, /* close */ - NULL, /* supports_feature */ - NULL, /* type */ - NULL, /* version */ - NULL, /* getHostname */ - NULL, /* getMaxVcpus */ - NULL, /* nodeGetInfo */ - NULL, /* getCapabilities */ - phypListDomains, /* listDomains */ - phypNumDomains, /* numOfDomains */ - NULL, /* domainCreateXML */ - phypDomainLookupByID, /* domainLookupByID */ - NULL, /* domainLookupByUUID */ - phypDomainLookupByName, /* domainLookupByName */ - NULL, /* domainSuspend */ - phypDomainResume, /* domainResume */ - phypDomainShutdown, /* domainShutdown */ - NULL, /* domainReboot */ - NULL, /* domainDestroy */ - NULL, /* domainGetOSType */ - NULL, /* domainGetMaxMemory */ - NULL, /* domainSetMaxMemory */ - NULL, /* domainSetMemory */ +static int +phypDomainDestroy(virDomainPtr dom) +{ + ConnectionData *connection_data = dom->conn->networkPrivateData; + phyp_driverPtr phyp_driver = dom->conn->privateData; + LIBSSH2_SESSION *session = connection_data->session; + char *managed_system = phyp_driver->managed_system; + int exit_status = 0; + char *cmd; + + if (virAsprintf + (&cmd, + "rmsyscfg -m %s -r lpar --id %d", managed_system, dom->id) < 0) { + virReportOOMError(dom->conn); + goto err; + } + + char *ret = phypExec(session, cmd, &exit_status, dom->conn); + + if (exit_status < 0) + goto err; + + if (phypUUIDTable_RemLpar(dom->conn, dom->id) == -1) + goto err; + + VIR_FREE(cmd); + VIR_FREE(ret); + return 0; + + err: + VIR_FREE(cmd); + VIR_FREE(ret); + return -1; + +} + +static virDomainPtr +phypDomainCreateAndStart(virConnectPtr conn, + const char *xml, + unsigned int flags ATTRIBUTE_UNUSED) +{ + + ConnectionData *connection_data = conn->networkPrivateData; + LIBSSH2_SESSION *session = connection_data->session; + virDomainDefPtr def = NULL; + virDomainPtr dom = NULL; + phyp_driverPtr phyp_driver = conn->privateData; + uuid_tablePtr uuid_table = phyp_driver->uuid_table; + lparPtr *lpars = uuid_table->lpars; + unsigned int i = 0; + char *managed_system = phyp_driver->managed_system; + + if (!(def = virDomainDefParseString(conn, phyp_driver->caps, xml, + VIR_DOMAIN_XML_SECURE))) + goto err; + + /* checking if this name already exists on this system */ + if (phypGetLparID(session, managed_system, def->name, conn) == -1) { + VIR_WARN("%s", "LPAR name already exists."); + goto err; + } + + /* checking if ID or UUID already exists on this system */ + for (i = 0; i < uuid_table->nlpars; i++) { + if (lpars[i]->id == def->id || lpars[i]->uuid == def->uuid) { + VIR_WARN("%s", "LPAR ID or UUID already exists."); + goto err; + } + } + + if ((dom = virGetDomain(conn, def->name, def->uuid)) == NULL) + goto err; + + if (phypBuildLpar(conn, def) == -1) + goto err; + + if (phypDomainResume(dom) == -1) + goto err; + + return dom; + + err: + virDomainDefFree(def); + VIR_FREE(dom); + return NULL; +} + +static char * +phypConnectGetCapabilities(virConnectPtr conn) +{ + phyp_driverPtr phyp_driver = conn->privateData; + char *xml; + + if ((xml = virCapabilitiesFormatXML(phyp_driver->caps)) == NULL) + virReportOOMError(conn); + + return xml; +} + +virCapsPtr +phypCapsInit(void) +{ + struct utsname utsname; + virCapsPtr caps; + virCapsGuestPtr guest; + + uname(&utsname); + + if ((caps = virCapabilitiesNew(utsname.machine, 0, 0)) == NULL) + goto no_memory; + + /* Some machines have problematic NUMA toplogy causing + * unexpected failures. We don't want to break the QEMU + * driver in this scenario, so log errors & carry on + */ + if (nodeCapsInitNUMA(caps) < 0) { + virCapabilitiesFreeNUMAInfo(caps); + VIR_WARN0 + ("Failed to query host NUMA topology, disabling NUMA capabilities"); + } + + /* XXX shouldn't 'borrow' KVM's prefix */ + virCapabilitiesSetMacPrefix(caps, (unsigned char[]) { + 0x52, 0x54, 0x00}); + + if ((guest = virCapabilitiesAddGuest(caps, + "linux", + utsname.machine, + sizeof(int) == 4 ? 32 : 8, + NULL, NULL, 0, NULL)) == NULL) + goto no_memory; + + if (virCapabilitiesAddGuestDomain(guest, + "phyp", NULL, NULL, 0, NULL) == NULL) + goto no_memory; + + return caps; + + no_memory: + virCapabilitiesFree(caps); + return NULL; +} + +static int +phypDomainSetCPU(virDomainPtr dom, unsigned int nvcpus) +{ + ConnectionData *connection_data = dom->conn->networkPrivateData; + phyp_driverPtr phyp_driver = dom->conn->privateData; + LIBSSH2_SESSION *session = connection_data->session; + char *managed_system = phyp_driver->managed_system; + int exit_status = 0; + char *cmd; + char operation; + unsigned long ncpus = 0; + unsigned int amount = 0; + + if ((ncpus = phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0) + goto err; + + if (nvcpus > phypGetLparCPUMAX(dom)) { + VIR_ERROR("%s", + "You are trying to set a number of CPUs bigger than " + "the max possible.."); + goto err; + } + + if (ncpus > nvcpus) { + operation = 'r'; + amount = nvcpus - ncpus; + } else if (ncpus < nvcpus) { + operation = 'a'; + amount = nvcpus - ncpus; + } else + goto exit; + + if (virAsprintf + (&cmd, + "chhwres -r proc -m %s --id %d -o %c --procunits %d 2>&1 |sed" + "-e 's/^.*\\([0-9]\\+.[0-9]\\+\\).*$/\\1/g'", + managed_system, dom->id, operation, amount) < 0) { + virReportOOMError(dom->conn); + goto err; + } + + char *ret = phypExec(session, cmd, &exit_status, dom->conn); + + if (exit_status < 0) { + VIR_ERROR("%s", + "Possibly you don't have IBM Tools installed in your LPAR." + "Contact your support to enable this feature."); + goto err; + } + + exit: + VIR_FREE(cmd); + VIR_FREE(ret); + return 0; + + err: + VIR_FREE(cmd); + VIR_FREE(ret); + return 0; + +} + +virDriver phypDriver = { + VIR_DRV_PHYP, + "PHYP", + phypOpen, /* open */ + phypClose, /* close */ + NULL, /* supports_feature */ + NULL, /* type */ + NULL, /* version */ + NULL, /* getHostname */ + NULL, /* getMaxVcpus */ + NULL, /* nodeGetInfo */ + phypConnectGetCapabilities, /* getCapabilities */ + phypListDomains, /* listDomains */ + phypNumDomains, /* numOfDomains */ + phypDomainCreateAndStart, /* domainCreateXML */ + phypDomainLookupByID, /* domainLookupByID */ + NULL, /* domainLookupByUUID */ + phypDomainLookupByName, /* domainLookupByName */ + NULL, /* domainSuspend */ + phypDomainResume, /* domainResume */ + phypDomainShutdown, /* domainShutdown */ + NULL, /* domainReboot */ + phypDomainDestroy, /* domainDestroy */ + NULL, /* domainGetOSType */ + NULL, /* domainGetMaxMemory */ + NULL, /* domainSetMaxMemory */ + NULL, /* domainSetMemory */ phypDomainGetInfo, /* domainGetInfo */ NULL, /* domainSave */ NULL, /* domainRestore */ NULL, /* domainCoreDump */ - NULL, /* domainSetVcpus */ + phypDomainSetCPU, /* domainSetVcpus */ NULL, /* domainPinVcpu */ NULL, /* domainGetVcpus */ - NULL, /* domainGetMaxVcpus */ + phypGetLparCPUMAX, /* domainGetMaxVcpus */ NULL, /* domainGetSecurityLabel */ NULL, /* nodeGetSecurityModel */ phypDomainDumpXML, /* domainDumpXML */ @@ -1381,52 +1600,429 @@ virDriver phypDriver = { }; int -phypRegister(void) +phypBuildLpar(virConnectPtr conn, virDomainDefPtr def) { - virRegisterDriver(&phypDriver); + ConnectionData *connection_data = conn->networkPrivateData; + phyp_driverPtr phyp_driver = conn->privateData; + LIBSSH2_SESSION *session = connection_data->session; + char *managed_system = phyp_driver->managed_system; + char *cmd; + int exit_status = 0; + + if (virAsprintf + (&cmd, + "mksyscfg -m %s -r lpar -p %s -i min_mem=%d,desired_mem=%d," + "max_mem=%d,desired_procs=%d,virtual_scsi_adapters=%s", + managed_system, def->name, (int) def->memory, + (int) def->memory, (int) def->maxmem, (int) def->vcpus, + def->disks[0]->src) < 0) { + virReportOOMError(conn); + goto err; + } + + char *ret = phypExec(session, cmd, &exit_status, conn); + + if (exit_status < 0) { + VIR_ERROR("%s\"%s\"", "Unable to create LPAR. Reason: ", ret); + goto err; + } + + if (phypUUIDTable_AddLpar(conn, def->uuid, def->id) == -1) { + VIR_ERROR("%s", "Unable to add LPAR to the table"); + goto err; + } + + VIR_FREE(cmd); + VIR_FREE(ret); + return 0; + + err: + VIR_FREE(cmd); + VIR_FREE(ret); + return -1; +} + +int +phypUUIDTable_RemLpar(virConnectPtr conn, int id) +{ + phyp_driverPtr phyp_driver = conn->privateData; + uuid_tablePtr uuid_table = phyp_driver->uuid_table; + unsigned int i = 0; + + for (i = 0; i <= uuid_table->nlpars; i++) { + if (uuid_table->lpars[i]->id == id) { + uuid_table->lpars[i]->id = -1; + if (!memset(uuid_table->lpars[i]->uuid, '0', VIR_UUID_BUFLEN)) + goto exit; + } + } + + if (phypUUIDTable_WriteFile(conn) == -1) + goto err; + + if (phypUUIDTable_Push(conn) == -1) + goto err; + + exit: + return 0; + + err: + return -1; +} + +int +phypUUIDTable_AddLpar(virConnectPtr conn, unsigned char *uuid, int id) +{ + phyp_driverPtr phyp_driver = conn->privateData; + uuid_tablePtr uuid_table = phyp_driver->uuid_table; + + uuid_table->nlpars++; + unsigned int i = uuid_table->nlpars; + i--; + + if (VIR_REALLOC_N(uuid_table->lpars, uuid_table->nlpars) < 0) { + virReportOOMError(conn); + goto err; + } + + if (VIR_ALLOC(uuid_table->lpars[i]) < 0) { + virReportOOMError(conn); + goto err; + } + + uuid_table->lpars[i]->id = id; + if (memmove(uuid_table->lpars[i]->uuid, uuid, VIR_UUID_BUFLEN) == NULL) + goto err; + + if (phypUUIDTable_WriteFile(conn) == -1) + goto err; + + if (phypUUIDTable_Push(conn) == -1) + goto err; + + return 0; + + err: + return -1; +} + +int +phypUUIDTable_ReadFile(virConnectPtr conn) +{ + phyp_driverPtr phyp_driver = conn->privateData; + uuid_tablePtr uuid_table = phyp_driver->uuid_table; + unsigned int i = 0; + int fd = -1; + char local_file[] = "./uuid_table"; + int rc = 0; + char buffer[1024]; + + if ((fd = open(local_file, O_RDONLY)) == -1) { + VIR_WARN("%s", "Unable to write information to local file."); + goto err; + } + + /* Creating a new data base and writing to local file */ + if (VIR_ALLOC_N(uuid_table->lpars, uuid_table->nlpars) >= 0) { + for (i = 0; i < uuid_table->nlpars; i++) { + + rc = read(fd, buffer, sizeof(int)); + if (rc == sizeof(int)) { + if (VIR_ALLOC(uuid_table->lpars[i]) < 0) + virReportOOMError(conn); + uuid_table->lpars[i]->id = (*buffer); + } else { + VIR_WARN("%s", + "Unable to read from information to local file."); + goto err; + } + + rc = read(fd, uuid_table->lpars[i]->uuid, VIR_UUID_BUFLEN); + if (rc != VIR_UUID_BUFLEN) { + VIR_WARN("%s", + "Unable to read information to local file."); + goto err; + } + } + } + + close(fd); + return 0; + + err: + close(fd); + return -1; +} + +int +phypUUIDTable_WriteFile(virConnectPtr conn) +{ + phyp_driverPtr phyp_driver = conn->privateData; + uuid_tablePtr uuid_table = phyp_driver->uuid_table; + unsigned int i = 0; + int fd = -1; + char local_file[] = "./uuid_table"; + + if ((fd = creat(local_file, 0755)) == -1) + goto err; + + for (i = 0; i < uuid_table->nlpars; i++) { + if (safewrite(fd, &uuid_table->lpars[i]->id, + sizeof(uuid_table->lpars[i]->id)) == + sizeof(uuid_table->lpars[i]->id)) { + VIR_ERROR("%s", "Unable to write information to local file."); + goto err; + } + + if (safewrite(fd, uuid_table->lpars[i]->uuid, VIR_UUID_BUFLEN) != + VIR_UUID_BUFLEN) { + VIR_ERROR("%s", "Unable to write information to local file."); + goto err; + } + } + + close(fd); return 0; + + err: + close(fd); + return -1; } -void -init_uuid_db(virConnectPtr conn) +int +phypUUIDTable_Init(virConnectPtr conn) { - uuid_dbPtr uuid_db; + uuid_tablePtr uuid_table; + phyp_driverPtr phyp_driver; int nids = 0; int *ids = NULL; unsigned int i = 0; if ((nids = phypNumDomainsGeneric(conn, 2)) == 0) - goto exit; - - if (VIR_ALLOC_N(ids, nids) < 0) - virReportOOMError(conn); + goto err; - if (VIR_ALLOC(uuid_db) < 0) + if (VIR_ALLOC_N(ids, nids) < 0) { virReportOOMError(conn); + goto err; + } if (phypListDomainsGeneric(conn, ids, nids, 1) == 0) + goto err; + + phyp_driver = conn->privateData; + uuid_table = phyp_driver->uuid_table; + uuid_table->nlpars = nids; + + /* try to get the table from server */ + if (phypUUIDTable_Pull(conn) == -1) { + /* file not found in the server, creating a new one */ + if (VIR_ALLOC_N(uuid_table->lpars, uuid_table->nlpars) >= 0) { + for (i = 0; i < uuid_table->nlpars; i++) { + if (VIR_ALLOC(uuid_table->lpars[i]) < 0) { + virReportOOMError(conn); + goto err; + } + uuid_table->lpars[i]->id = ids[i]; + + if (virUUIDGenerate(uuid_table->lpars[i]->uuid) < 0) + VIR_WARN("%s %d", "Unable to generate UUID for domain", + ids[i]); + } + } else + goto err; + + if (phypUUIDTable_WriteFile(conn) == -1) + goto err; + + if (phypUUIDTable_Push(conn) == -1) + goto err; + } else { + if (phypUUIDTable_ReadFile(conn) == -1) + goto err; goto exit; + } + + exit: + VIR_FREE(ids); + return 0; + + err: + VIR_FREE(ids); + return -1; +} + +int +phypUUIDTable_Push(virConnectPtr conn) +{ + ConnectionData *connection_data = conn->networkPrivateData; + LIBSSH2_SESSION *session = connection_data->session; + LIBSSH2_CHANNEL *channel = NULL; + struct stat local_fileinfo; + char buffer[1024]; + int rc = 0; + FILE *fd; + size_t nread, sent; + char *ptr; + char remote_file[] = "/home/hscroot/libvirt_uuid_table"; + char local_file[] = "./uuid_table"; + + if (stat(local_file, &local_fileinfo) == -1) { + VIR_WARN0("Unable to stat local file."); + goto err; + } - uuid_db = conn->privateData; - uuid_db->nlpars = nids; + if (!(fd = fopen(local_file, "rb"))) { + VIR_WARN0("Unable to open local file."); + goto err; + } - if (VIR_ALLOC_N(uuid_db->lpars, uuid_db->nlpars) >= 0) { - for (i = 0; i < uuid_db->nlpars; i++) { - if (VIR_ALLOC(uuid_db->lpars[i]) < 0) - virReportOOMError(conn); - uuid_db->lpars[i]->id = ids[i]; + do { + channel = + libssh2_scp_send(session, remote_file, + 0x1FF & local_fileinfo.st_mode, + (unsigned long) local_fileinfo.st_size); - if (virUUIDGenerate(uuid_db->lpars[i]->uuid) < 0) - VIR_WARN("%s %d", "Unable to generate UUID for domain", - ids[i]); + if ((!channel) && (libssh2_session_last_errno(session) != + LIBSSH2_ERROR_EAGAIN)) + goto err; + } while (!channel); + + do { + nread = fread(buffer, 1, sizeof(buffer), fd); + if (nread <= 0) { + /* end of file */ + break; } + ptr = buffer; + sent = 0; + + do { + /* write the same data over and over, until error or completion */ + rc = libssh2_channel_write(channel, ptr, nread); + if (LIBSSH2_ERROR_EAGAIN == rc) { /* must loop around */ + continue; + } else { + /* rc indicates how many bytes were written this time */ + sent += rc; + } + } while (rc > 0 && sent < nread); + ptr += sent; + nread -= sent; + } while (1); + + goto exit; + + exit: + if (channel) { + libssh2_channel_send_eof(channel); + libssh2_channel_wait_eof(channel); + libssh2_channel_wait_closed(channel); + libssh2_channel_free(channel); + channel = NULL; } + return 0; + + err: + if (channel) { + libssh2_channel_send_eof(channel); + libssh2_channel_wait_eof(channel); + libssh2_channel_wait_closed(channel); + libssh2_channel_free(channel); + channel = NULL; + } + return -1; +} + +int +phypUUIDTable_Pull(virConnectPtr conn) +{ + ConnectionData *connection_data = conn->networkPrivateData; + LIBSSH2_SESSION *session = connection_data->session; + LIBSSH2_CHANNEL *channel = NULL; + struct stat fileinfo; + char buffer[1024]; + int rc = 0; + int fd; + int got = 0; + int amount = 0; + int total = 0; + int sock = 0; + char remote_file[] = "/home/hscroot/libvirt_uuid_table"; + char local_file[] = "./uuid_table"; + + /* Trying to stat the remote file. */ + do { + channel = libssh2_scp_recv(session, remote_file, &fileinfo); + + if (!channel) { + if (libssh2_session_last_errno(session) != + LIBSSH2_ERROR_EAGAIN) { + goto err;; + } else { + waitsocket(sock, session); + } + } + } while (!channel); + + /* Creating a new data base based on remote file */ + if ((fd = creat(local_file, 0755)) == -1) + goto err; + + /* Request a file via SCP */ + while (got < fileinfo.st_size) { + do { + amount = sizeof(buffer); + + if ((fileinfo.st_size - got) < amount) { + amount = fileinfo.st_size - got; + } + + rc = libssh2_channel_read(channel, buffer, amount); + if (rc > 0) { + if (safewrite(fd, buffer, rc) != rc) + VIR_WARN("%s", + "Unable to write information to local file."); + + got += rc; + total += rc; + } + } while (rc > 0); + + if ((rc == LIBSSH2_ERROR_EAGAIN) + && (got < fileinfo.st_size)) { + /* this is due to blocking that would occur otherwise + * so we loop on this condition */ + + waitsocket(sock, session); /* now we wait */ + continue; + } + break; + } + close(fd); + goto exit; + exit: - VIR_FREE(ids); - return; + if (channel) { + libssh2_channel_send_eof(channel); + libssh2_channel_wait_eof(channel); + libssh2_channel_wait_closed(channel); + libssh2_channel_free(channel); + channel = NULL; + } + return 0; + + err: + if (channel) { + libssh2_channel_send_eof(channel); + libssh2_channel_wait_eof(channel); + libssh2_channel_wait_closed(channel); + libssh2_channel_free(channel); + channel = NULL; + } + return -1; } -static int +int escape_specialcharacters(char *src, char *dst, size_t dstlen) { size_t len = strlen(src); @@ -1437,12 +2033,30 @@ escape_specialcharacters(char *src, char *dst, size_t dstlen) for (i = 0; i < len; i++) { switch (src[i]) { - case '&': case ';': case '`': case '@': - case '"': case '|': case '*': case '?': - case '~': case '<': case '>': case '^': - case '(': case ')': case '[': case ']': - case '{': case '}': case '$': case '%': - case '#': case '\\': case '\n': case '\r': + case '&': + case ';': + case '`': + case '@': + case '"': + case '|': + case '*': + case '?': + case '~': + case '<': + case '>': + case '^': + case '(': + case ')': + case '[': + case ']': + case '{': + case '}': + case '$': + case '%': + case '#': + case '\\': + case '\n': + case '\r': case '\t': continue; default: @@ -1488,3 +2102,10 @@ waitsocket(int socket_fd, LIBSSH2_SESSION * session) return rc; } + +int +phypRegister(void) +{ + virRegisterDriver(&phypDriver); + return 0; +} diff --git a/src/phyp/phyp_driver.h b/src/phyp/phyp_driver.h index b793774daee843347ec13801a502deff58c0ab3e..5ec12be3fc12e1c3561d518d968acc3c6647c48b 100644 --- a/src/phyp/phyp_driver.h +++ b/src/phyp/phyp_driver.h @@ -1,3 +1,29 @@ + +/* + * Copyright IBM Corp. 2009 + * + * phyp_driver.c: ssh layer to access Power Hypervisors + * + * Authors: + * Eduardo Otubo + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "conf/capabilities.h" +#include "conf/domain_conf.h" #include #include @@ -26,22 +52,53 @@ struct _lpar { /* Struct that holds how many lpars (domains) we're * handling and a pointer to an array of lpar structs * */ -typedef struct _uuid_db uuid_db_t; -typedef uuid_db_t *uuid_dbPtr; -struct _uuid_db { +typedef struct _uuid_table uuid_table_t; +typedef uuid_table_t *uuid_tablePtr; +struct _uuid_table { int nlpars; lparPtr *lpars; }; -int phypGetLparUUID(unsigned char *uuid, int lpar_id, virConnectPtr conn); +/* This is the main structure of the driver + * */ +typedef struct _phyp_driver phyp_driver_t; +typedef phyp_driver_t *phyp_driverPtr; +struct _phyp_driver { + uuid_tablePtr uuid_table; + virCapsPtr caps; + int vios_id; + char *managed_system; +}; -void init_uuid_db(virConnectPtr conn); +int phypCheckSPFreeSapce(virConnectPtr conn, int required_size, char *sp); -int phypRegister(void); +int phypGetVIOSPartitionID(virConnectPtr conn); + +virCapsPtr phypCapsInit(void); + +int phypBuildLpar(virConnectPtr conn, virDomainDefPtr def); + +int phypUUIDTable_WriteFile(virConnectPtr conn); + +int phypUUIDTable_ReadFile(virConnectPtr conn); + +int phypUUIDTable_AddLpar(virConnectPtr conn, unsigned char *uuid, int id); + +int phypUUIDTable_RemLpar(virConnectPtr conn, int id); -void stripPath(char *striped_path, char *path); +int phypUUIDTable_Pull(virConnectPtr conn); -void stripNewline(char *striped_string, char *string); +int phypUUIDTable_Push(virConnectPtr conn); + +int phypUUIDTable_Init(virConnectPtr conn); + +int escape_specialcharacters(char *src, char *dst, size_t dstlen); + +int waitsocket(int socket_fd, LIBSSH2_SESSION * session); + +int phypGetLparUUID(unsigned char *uuid, int lpar_id, virConnectPtr conn); + +int phypRegister(void); int phypGetLparState(virConnectPtr conn, unsigned int lpar_id); @@ -52,6 +109,10 @@ unsigned long phypGetLparMem(virConnectPtr conn, unsigned long phypGetLparCPU(virConnectPtr conn, const char *managed_system, int lpar_id); +unsigned long phypGetLparCPUGeneric(virConnectPtr conn, + const char *managed_system, + int lpar_id, int type); + int phypGetRemoteSlot(virConnectPtr conn, const char *managed_system, const char *lpar_name); @@ -60,6 +121,5 @@ char *phypGetBackingDevice(virConnectPtr conn, const char *managed_system, int phypDiskType(virConnectPtr conn, char *backing_device); -LIBSSH2_SESSION *openSSHSession(virConnectPtr conn, virConnectAuthPtr auth, int *internal_socket); - -int waitsocket(int socket_fd, LIBSSH2_SESSION * session); +LIBSSH2_SESSION *openSSHSession(virConnectPtr conn, virConnectAuthPtr auth, + int *internal_socket);