virReportErrorHelper(NULL, VIR_FROM_PHYP, code, __FILE__, __FUNCTION__, \
__LINE__, __VA_ARGS__)
-static unsigned const int HMC = 0;
-static unsigned const int IVM = 127;
-
/*
* URI: phyp://user@[hmc|ivm]/managed_system
* */
-static virDrvOpenStatus
-phypOpen(virConnectPtr conn,
- virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
-{
- LIBSSH2_SESSION *session = NULL;
- ConnectionData *connection_data = NULL;
- char *string = NULL;
- size_t len = 0;
- int internal_socket;
- uuid_tablePtr uuid_table = NULL;
- phyp_driverPtr phyp_driver = NULL;
- char *char_ptr;
- char *managed_system = NULL;
-
- if (!conn || !conn->uri)
- return VIR_DRV_OPEN_DECLINED;
-
- if (conn->uri->scheme == NULL || STRNEQ(conn->uri->scheme, "phyp"))
- return VIR_DRV_OPEN_DECLINED;
+static unsigned const int HMC = 0;
+static unsigned const int IVM = 127;
- if (conn->uri->server == NULL) {
- PHYP_ERROR(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Missing server name in phyp:// URI"));
- return VIR_DRV_OPEN_ERROR;
- }
+static int
+waitsocket(int socket_fd, LIBSSH2_SESSION * session)
+{
+ struct timeval timeout;
+ int rc;
+ fd_set fd;
+ fd_set *writefd = NULL;
+ fd_set *readfd = NULL;
+ int dir;
- if (VIR_ALLOC(phyp_driver) < 0) {
- virReportOOMError();
- goto failure;
- }
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 1000;
- if (VIR_ALLOC(uuid_table) < 0) {
- virReportOOMError();
- goto failure;
- }
+ FD_ZERO(&fd);
- if (VIR_ALLOC(connection_data) < 0) {
- virReportOOMError();
- goto failure;
- }
+ FD_SET(socket_fd, &fd);
- if (conn->uri->path) {
- len = strlen(conn->uri->path) + 1;
+ /* now make sure we wait in the correct direction */
+ dir = libssh2_session_block_directions(session);
- if (VIR_ALLOC_N(string, len) < 0) {
- virReportOOMError();
- goto failure;
- }
+ if (dir & LIBSSH2_SESSION_BLOCK_INBOUND)
+ readfd = &fd;
- /* need to shift one byte in order to remove the first "/" of URI component */
- if (conn->uri->path[0] == '/')
- managed_system = strdup(conn->uri->path + 1);
- else
- managed_system = strdup(conn->uri->path);
+ if (dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
+ writefd = &fd;
- if (!managed_system) {
- virReportOOMError();
- goto failure;
- }
+ rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);
- /* here we are handling only the first component of the path,
- * so skipping the second:
- * */
- char_ptr = strchr(managed_system, '/');
+ return rc;
+}
- if (char_ptr)
- *char_ptr = '\0';
+/* this function is the layer that manipulates the ssh channel itself
+ * and executes the commands on the remote machine */
+static char *
+phypExec(LIBSSH2_SESSION * session, char *cmd, int *exit_status,
+ virConnectPtr conn)
+{
+ LIBSSH2_CHANNEL *channel;
+ ConnectionData *connection_data = conn->networkPrivateData;
+ virBuffer tex_ret = VIR_BUFFER_INITIALIZER;
+ char buffer[0x4000] = { 0 };
+ int exitcode;
+ int bytecount = 0;
+ int sock = connection_data->sock;
+ int rc = 0;
- if (escape_specialcharacters(conn->uri->path, string, len) == -1) {
- PHYP_ERROR(VIR_ERR_INTERNAL_ERROR,
- "%s",
- _("Error parsing 'path'. Invalid characters."));
- goto failure;
- }
+ /* Exec non-blocking on the remove host */
+ while ((channel = libssh2_channel_open_session(session)) == NULL &&
+ libssh2_session_last_error(session, NULL, NULL, 0) ==
+ LIBSSH2_ERROR_EAGAIN) {
+ waitsocket(sock, session);
}
- if ((session = openSSHSession(conn, auth, &internal_socket)) == NULL) {
- PHYP_ERROR(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Error while opening SSH session."));
- goto failure;
+ if (channel == NULL) {
+ goto err;
}
- connection_data->session = session;
-
- uuid_table->nlpars = 0;
- uuid_table->lpars = NULL;
-
- if (conn->uri->path)
- phyp_driver->managed_system = managed_system;
-
- phyp_driver->uuid_table = uuid_table;
- if ((phyp_driver->caps = phypCapsInit()) == NULL) {
- virReportOOMError();
- goto failure;
+ while ((rc = libssh2_channel_exec(channel, cmd)) ==
+ LIBSSH2_ERROR_EAGAIN) {
+ waitsocket(sock, session);
}
- conn->privateData = phyp_driver;
- conn->networkPrivateData = connection_data;
-
- if ((phyp_driver->system_type = phypGetSystemType(conn)) == -1)
- goto failure;
+ if (rc != 0) {
+ goto err;
+ }
- if (phypUUIDTable_Init(conn) == -1)
- goto failure;
+ for (;;) {
+ /* loop until we block */
+ do {
+ rc = libssh2_channel_read(channel, buffer, sizeof(buffer));
+ if (rc > 0) {
+ bytecount += rc;
+ virBufferVSprintf(&tex_ret, "%s", buffer);
+ }
+ }
+ while (rc > 0);
- if (phyp_driver->system_type == HMC) {
- if ((phyp_driver->vios_id = phypGetVIOSPartitionID(conn)) == -1)
- goto failure;
+ /* this is due to blocking that would occur otherwise so we loop on
+ * this condition */
+ if (rc == LIBSSH2_ERROR_EAGAIN) {
+ waitsocket(sock, session);
+ } else {
+ break;
+ }
}
- return VIR_DRV_OPEN_SUCCESS;
+ exitcode = 127;
- failure:
- if (phyp_driver != NULL) {
- virCapabilitiesFree(phyp_driver->caps);
- VIR_FREE(phyp_driver->managed_system);
- VIR_FREE(phyp_driver);
+ while ((rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN) {
+ waitsocket(sock, session);
}
- phypUUIDTable_Free(uuid_table);
-
- if (session != NULL) {
- libssh2_session_disconnect(session, "Disconnecting...");
- libssh2_session_free(session);
+ if (rc == 0) {
+ exitcode = libssh2_channel_get_exit_status(channel);
}
- VIR_FREE(connection_data);
- VIR_FREE(string);
+ (*exit_status) = exitcode;
+ libssh2_channel_free(channel);
+ channel = NULL;
+ goto exit;
- return VIR_DRV_OPEN_ERROR;
+ err:
+ (*exit_status) = SSH_CMD_ERR;
+ virBufferFreeAndReset(&tex_ret);
+ return NULL;
+
+ exit:
+ if (virBufferError(&tex_ret)) {
+ virBufferFreeAndReset(&tex_ret);
+ virReportOOMError();
+ return NULL;
+ }
+ return virBufferContentAndReset(&tex_ret);
}
static int
-phypClose(virConnectPtr conn)
+phypGetSystemType(virConnectPtr conn)
{
ConnectionData *connection_data = conn->networkPrivateData;
- phyp_driverPtr phyp_driver = conn->privateData;
LIBSSH2_SESSION *session = connection_data->session;
+ char *cmd = NULL;
+ char *ret = NULL;
+ int exit_status = 0;
- libssh2_session_disconnect(session, "Disconnecting...");
- libssh2_session_free(session);
+ if (virAsprintf(&cmd, "lshmc -V") < 0) {
+ virReportOOMError();
+ exit_status = -1;
+ }
+ ret = phypExec(session, cmd, &exit_status, conn);
- virCapabilitiesFree(phyp_driver->caps);
- phypUUIDTable_Free(phyp_driver->uuid_table);
- VIR_FREE(phyp_driver->managed_system);
- VIR_FREE(phyp_driver);
- VIR_FREE(connection_data);
- return 0;
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
+ return exit_status;
}
-
static int
-phypIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED)
+phypGetVIOSPartitionID(virConnectPtr conn)
{
- /* Phyp uses an SSH tunnel, so is always encrypted */
- return 1;
-}
+ ConnectionData *connection_data = conn->networkPrivateData;
+ phyp_driverPtr phyp_driver = conn->privateData;
+ LIBSSH2_SESSION *session = connection_data->session;
+ int system_type = phyp_driver->system_type;
+ char *cmd = NULL;
+ char *ret = NULL;
+ int exit_status = 0;
+ int id = -1;
+ char *char_ptr;
+ char *managed_system = phyp_driver->managed_system;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ virBufferAddLit(&buf, "lssyscfg");
+ if (system_type == HMC)
+ virBufferVSprintf(&buf, " -m %s", managed_system);
+ virBufferAddLit(&buf, " -r lpar -F lpar_id,lpar_env|grep "
+ "vioserver|sed -s 's/,.*$//'");
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ virReportOOMError();
+ return -1;
+ }
+ cmd = virBufferContentAndReset(&buf);
-static int
-phypIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED)
-{
- /* Phyp uses an SSH tunnel, so is always secure */
- return 1;
-}
+ ret = phypExec(session, cmd, &exit_status, conn);
+ if (exit_status < 0 || ret == NULL)
+ goto err;
-LIBSSH2_SESSION *
-openSSHSession(virConnectPtr conn, virConnectAuthPtr auth,
- int *internal_socket)
-{
- LIBSSH2_SESSION *session;
- const char *hostname = conn->uri->server;
- char *username = NULL;
- char *password = NULL;
- int sock;
- int rc;
- struct addrinfo *ai = NULL, *cur;
- struct addrinfo hints;
- int ret;
- char *pubkey = NULL;
- char *pvtkey = NULL;
- char *userhome = virGetUserDirectory(geteuid());
- struct stat pvt_stat, pub_stat;
-
- if (userhome == NULL)
- goto err;
-
- if (virAsprintf(&pubkey, "%s/.ssh/id_rsa.pub", userhome) < 0) {
- virReportOOMError();
- goto err;
- }
-
- if (virAsprintf(&pvtkey, "%s/.ssh/id_rsa", userhome) < 0) {
- virReportOOMError();
+ if (virStrToLong_i(ret, &char_ptr, 10, &id) == -1)
goto err;
- }
-
- if (conn->uri->user != NULL) {
- username = strdup(conn->uri->user);
- if (username == NULL) {
- virReportOOMError();
- goto err;
- }
- } else {
- if (auth == NULL || auth->cb == NULL) {
- PHYP_ERROR(VIR_ERR_AUTH_FAILED,
- "%s", _("No authentication callback provided."));
- goto err;
- }
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
+ return id;
- username = virRequestUsername(auth, NULL, conn->uri->server);
+ err:
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
+ return -1;
+}
- if (username == NULL) {
- PHYP_ERROR(VIR_ERR_AUTH_FAILED, "%s",
- _("Username request failed"));
- goto err;
- }
- }
+static virCapsPtr
+phypCapsInit(void)
+{
+ struct utsname utsname;
+ virCapsPtr caps;
+ virCapsGuestPtr guest;
- memset(&hints, 0, sizeof(hints));
- hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = 0;
+ uname(&utsname);
- ret = getaddrinfo(hostname, "22", &hints, &ai);
- if (ret != 0) {
- PHYP_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("Error while getting %s address info"), hostname);
- goto err;
- }
+ if ((caps = virCapabilitiesNew(utsname.machine, 0, 0)) == NULL)
+ goto no_memory;
- cur = ai;
- 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) {
- goto connected;
- }
- close(sock);
- }
- cur = cur->ai_next;
+ /* 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");
}
- PHYP_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("Failed to connect to %s"), hostname);
- freeaddrinfo(ai);
- goto err;
-
- connected:
-
- (*internal_socket) = sock;
-
- /* Create a session instance */
- session = libssh2_session_init();
- if (!session)
- goto err;
-
- /* tell libssh2 we want it all done non-blocking */
- libssh2_session_set_blocking(session, 0);
+ /* XXX shouldn't 'borrow' KVM's prefix */
+ virCapabilitiesSetMacPrefix(caps, (unsigned char[]) {
+ 0x52, 0x54, 0x00});
- while ((rc = libssh2_session_startup(session, sock)) ==
- LIBSSH2_ERROR_EAGAIN) ;
- if (rc) {
- PHYP_ERROR(VIR_ERR_INTERNAL_ERROR,
- "%s", _("Failure establishing SSH session."));
- goto disconnect;
- }
+ if ((guest = virCapabilitiesAddGuest(caps,
+ "linux",
+ utsname.machine,
+ sizeof(int) == 4 ? 32 : 8,
+ NULL, NULL, 0, NULL)) == NULL)
+ goto no_memory;
- /* Trying authentication by pubkey */
- if (stat(pvtkey, &pvt_stat) || stat(pubkey, &pub_stat)) {
- rc = LIBSSH2_ERROR_SOCKET_NONE;
- goto keyboard_interactive;
- }
+ if (virCapabilitiesAddGuestDomain(guest,
+ "phyp", NULL, NULL, 0, NULL) == NULL)
+ goto no_memory;
- while ((rc =
- libssh2_userauth_publickey_fromfile(session, username,
- pubkey,
- pvtkey,
- NULL)) ==
- LIBSSH2_ERROR_EAGAIN) ;
+ return caps;
- keyboard_interactive:
- if (rc == LIBSSH2_ERROR_SOCKET_NONE
- || rc == LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED
- || rc == LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED) {
- if (auth == NULL || auth->cb == NULL) {
- PHYP_ERROR(VIR_ERR_AUTH_FAILED,
- "%s", _("No authentication callback provided."));
- goto disconnect;
- }
+ no_memory:
+ virCapabilitiesFree(caps);
+ return NULL;
+}
- password = virRequestPassword(auth, username, conn->uri->server);
+/* This is a generic function that won't be used directly by
+ * libvirt api. The function returns the number of domains
+ * in different states: Running, Not Activated and all:
+ *
+ * type: 0 - Running
+ * 1 - Not Activated
+ * * - All
+ * */
+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 system_type = phyp_driver->system_type;
+ int exit_status = 0;
+ int ndom = 0;
+ char *char_ptr;
+ char *cmd = NULL;
+ char *ret = NULL;
+ char *managed_system = phyp_driver->managed_system;
+ const char *state;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
- if (password == NULL) {
- PHYP_ERROR(VIR_ERR_AUTH_FAILED, "%s",
- _("Password request failed"));
- goto disconnect;
+ if (type == 0)
+ state = "|grep Running";
+ else if (type == 1) {
+ if (system_type == HMC) {
+ state = "|grep \"Not Activated\"";
+ } else {
+ state = "|grep \"Open Firmware\"";
}
+ } else
+ state = " ";
- while ((rc =
- libssh2_userauth_password(session, username,
- password)) ==
- LIBSSH2_ERROR_EAGAIN) ;
+ virBufferAddLit(&buf, "lssyscfg -r lpar");
+ if (system_type == HMC)
+ virBufferVSprintf(&buf, " -m %s", managed_system);
+ virBufferVSprintf(&buf, " -F lpar_id,state %s |grep -c '^[0-9]*'",
+ state);
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ virReportOOMError();
+ return -1;
+ }
+ cmd = virBufferContentAndReset(&buf);
- if (rc) {
- PHYP_ERROR(VIR_ERR_AUTH_FAILED,
- "%s", _("Authentication failed"));
- goto disconnect;
- } else
- goto exit;
+ ret = phypExec(session, cmd, &exit_status, conn);
- } else if (rc == LIBSSH2_ERROR_NONE) {
- goto exit;
+ if (exit_status < 0 || ret == NULL)
+ goto err;
- } else if (rc == LIBSSH2_ERROR_ALLOC || rc == LIBSSH2_ERROR_SOCKET_SEND
- || rc == LIBSSH2_ERROR_SOCKET_TIMEOUT) {
+ if (virStrToLong_i(ret, &char_ptr, 10, &ndom) == -1)
goto err;
- }
- disconnect:
- libssh2_session_disconnect(session, "Disconnecting...");
- libssh2_session_free(session);
- err:
- VIR_FREE(userhome);
- VIR_FREE(pubkey);
- VIR_FREE(pvtkey);
- VIR_FREE(username);
- VIR_FREE(password);
- return NULL;
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
+ return ndom;
- exit:
- VIR_FREE(userhome);
- VIR_FREE(pubkey);
- VIR_FREE(pvtkey);
- VIR_FREE(username);
- VIR_FREE(password);
- return session;
+ err:
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
+ return -1;
}
-/* this functions is the layer that manipulates the ssh channel itself
- * and executes the commands on the remote machine */
-static char *
-phypExec(LIBSSH2_SESSION * session, char *cmd, int *exit_status,
- virConnectPtr conn)
+/* This is a generic function that won't be used directly by
+ * libvirt api. The function returns the ids of domains
+ * in different states: Running, and all:
+ *
+ * type: 0 - Running
+ * 1 - all
+ * */
+static int
+phypListDomainsGeneric(virConnectPtr conn, int *ids, int nids,
+ unsigned int type)
{
- LIBSSH2_CHANNEL *channel;
ConnectionData *connection_data = conn->networkPrivateData;
- virBuffer tex_ret = VIR_BUFFER_INITIALIZER;
- char buffer[0x4000] = { 0 };
- int exitcode;
- int bytecount = 0;
- int sock = connection_data->sock;
- int rc = 0;
-
- /* Exec non-blocking on the remove host */
- while ((channel = libssh2_channel_open_session(session)) == NULL &&
- libssh2_session_last_error(session, NULL, NULL, 0) ==
- LIBSSH2_ERROR_EAGAIN) {
- waitsocket(sock, session);
- }
-
- if (channel == NULL) {
- goto err;
- }
-
- while ((rc = libssh2_channel_exec(channel, cmd)) ==
- LIBSSH2_ERROR_EAGAIN) {
- waitsocket(sock, session);
- }
-
- if (rc != 0) {
- goto err;
- }
-
- for (;;) {
- /* loop until we block */
- do {
- rc = libssh2_channel_read(channel, buffer, sizeof(buffer));
- if (rc > 0) {
- bytecount += rc;
- virBufferVSprintf(&tex_ret, "%s", buffer);
- }
- }
- while (rc > 0);
-
- /* this is due to blocking that would occur otherwise so we loop on
- * this condition */
- if (rc == LIBSSH2_ERROR_EAGAIN) {
- waitsocket(sock, session);
- } else {
- break;
- }
- }
-
- exitcode = 127;
-
- while ((rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN) {
- waitsocket(sock, session);
- }
-
- if (rc == 0) {
- exitcode = libssh2_channel_get_exit_status(channel);
- }
-
- (*exit_status) = exitcode;
- libssh2_channel_free(channel);
- channel = NULL;
- goto exit;
-
- err:
- (*exit_status) = SSH_CMD_ERR;
- virBufferFreeAndReset(&tex_ret);
- return NULL;
-
- exit:
- if (virBufferError(&tex_ret)) {
- virBufferFreeAndReset(&tex_ret);
- virReportOOMError();
- return NULL;
- }
- return virBufferContentAndReset(&tex_ret);
-}
-
-int
-phypGetSystemType(virConnectPtr conn)
-{
- ConnectionData *connection_data = conn->networkPrivateData;
- LIBSSH2_SESSION *session = connection_data->session;
- char *cmd = NULL;
- char *ret = NULL;
- int exit_status = 0;
-
- if (virAsprintf(&cmd, "lshmc -V") < 0) {
- virReportOOMError();
- exit_status = -1;
- }
- ret = phypExec(session, cmd, &exit_status, conn);
-
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return exit_status;
-}
-
-
-/* return the lpar_id given a name and a managed system name */
-static int
-phypGetLparID(LIBSSH2_SESSION * session, const char *managed_system,
- const char *name, virConnectPtr conn)
-{
phyp_driverPtr phyp_driver = conn->privateData;
+ LIBSSH2_SESSION *session = connection_data->session;
int system_type = phyp_driver->system_type;
+ char *managed_system = phyp_driver->managed_system;
int exit_status = 0;
- int lpar_id = 0;
+ int got = 0;
char *char_ptr;
+ unsigned int i = 0, j = 0;
+ char id_c[10];
char *cmd = NULL;
char *ret = NULL;
+ const char *state;
virBuffer buf = VIR_BUFFER_INITIALIZER;
+ if (type == 0)
+ state = "|grep Running";
+ else
+ state = " ";
+
+ memset(id_c, 0, 10);
+
virBufferAddLit(&buf, "lssyscfg -r lpar");
if (system_type == HMC)
virBufferVSprintf(&buf, " -m %s", managed_system);
- virBufferVSprintf(&buf, " --filter lpar_names=%s -F lpar_id", name);
+ virBufferVSprintf(&buf, " -F lpar_id,state %s | sed -e 's/,.*$//'",
+ state);
if (virBufferError(&buf)) {
virBufferFreeAndReset(&buf);
virReportOOMError();
ret = phypExec(session, cmd, &exit_status, conn);
+ /* I need to parse the textual return in order to get the ret */
if (exit_status < 0 || ret == NULL)
goto err;
-
- if (virStrToLong_i(ret, &char_ptr, 10, &lpar_id) == -1)
- goto err;
+ else {
+ while (got < nids) {
+ if (ret[i] == '\0')
+ break;
+ else if (ret[i] == '\n') {
+ if (virStrToLong_i(id_c, &char_ptr, 10, &ids[got]) == -1) {
+ VIR_ERROR(_("Cannot parse number from '%s'"), id_c);
+ goto err;
+ }
+ memset(id_c, 0, 10);
+ j = 0;
+ got++;
+ } else {
+ id_c[j] = ret[i];
+ j++;
+ }
+ i++;
+ }
+ }
VIR_FREE(cmd);
VIR_FREE(ret);
- return lpar_id;
+ return got;
err:
VIR_FREE(cmd);
return -1;
}
-/* return the lpar name given a lpar_id and a managed system name */
-static char *
-phypGetLparNAME(LIBSSH2_SESSION * session, const char *managed_system,
- unsigned int lpar_id, virConnectPtr conn)
-{
- phyp_driverPtr phyp_driver = conn->privateData;
- int system_type = phyp_driver->system_type;
- char *cmd = NULL;
- char *ret = NULL;
- int exit_status = 0;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- virBufferAddLit(&buf, "lssyscfg -r lpar");
- if (system_type == HMC)
- virBufferVSprintf(&buf, " -m %s", managed_system);
- virBufferVSprintf(&buf, " --filter lpar_ids=%d -F name", lpar_id);
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
- virReportOOMError();
- return NULL;
- }
- cmd = virBufferContentAndReset(&buf);
-
- ret = phypExec(session, cmd, &exit_status, conn);
-
- if (exit_status < 0 || ret == NULL)
- goto err;
-
- char *char_ptr = strchr(ret, '\n');
-
- if (char_ptr)
- *char_ptr = '\0';
-
- VIR_FREE(cmd);
- return ret;
-
- err:
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return NULL;
-}
-
-
-/* Search into the uuid_table for a lpar_uuid given a lpar_id
- * and a managed system name
- *
- * return: 0 - record found
- * -1 - not found
- * */
-int
-phypGetLparUUID(unsigned char *uuid, int lpar_id, virConnectPtr conn)
+static int
+phypUUIDTable_WriteFile(virConnectPtr conn)
{
phyp_driverPtr phyp_driver = conn->privateData;
uuid_tablePtr uuid_table = phyp_driver->uuid_table;
- lparPtr *lpars = uuid_table->lpars;
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 (lpars[i]->id == lpar_id) {
- memmove(uuid, lpars[i]->uuid, VIR_UUID_BUFLEN);
- return 0;
+ if (safewrite(fd, &uuid_table->lpars[i]->id,
+ sizeof(uuid_table->lpars[i]->id)) !=
+ sizeof(uuid_table->lpars[i]->id)) {
+ VIR_ERROR0(_("Unable to write information to local file."));
+ goto err;
+ }
+
+ if (safewrite(fd, uuid_table->lpars[i]->uuid, VIR_UUID_BUFLEN) !=
+ VIR_UUID_BUFLEN) {
+ VIR_ERROR0(_("Unable to write information to local file."));
+ goto err;
}
}
+ close(fd);
+ return 0;
+
+ err:
+ close(fd);
return -1;
}
-/*
- * type:
- * 0 - maxmem
- * 1 - memory
- * */
-unsigned long
-phypGetLparMem(virConnectPtr conn, const char *managed_system, int lpar_id,
- int type)
+static int
+phypUUIDTable_Push(virConnectPtr conn)
{
ConnectionData *connection_data = conn->networkPrivateData;
LIBSSH2_SESSION *session = connection_data->session;
- phyp_driverPtr phyp_driver = conn->privateData;
- int system_type = phyp_driver->system_type;
- char *cmd = NULL;
- char *ret = NULL;
- char *char_ptr;
- int memory = 0;
- int exit_status = 0;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
+ LIBSSH2_CHANNEL *channel = NULL;
+ virBuffer username = VIR_BUFFER_INITIALIZER;
+ struct stat local_fileinfo;
+ char buffer[1024];
+ int rc = 0;
+ FILE *fd;
+ size_t nread, sent;
+ char *ptr;
+ char local_file[] = "./uuid_table";
+ char *remote_file = NULL;
- if (type != 1 && type != 0)
- return 0;
+ if (conn->uri->user != NULL) {
+ virBufferVSprintf(&username, "%s", conn->uri->user);
- virBufferAddLit(&buf, "lshwres");
- if (system_type == HMC)
- virBufferVSprintf(&buf, " -m %s", managed_system);
- virBufferVSprintf(&buf,
- " -r mem --level lpar -F %s --filter lpar_ids=%d",
- type ? "curr_mem" : "curr_max_mem", lpar_id);
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
+ if (virBufferError(&username)) {
+ virBufferFreeAndReset(&username);
+ virReportOOMError();
+ goto err;
+ }
+ }
+
+ if (virAsprintf
+ (&remote_file, "/home/%s/libvirt_uuid_table",
+ virBufferContentAndReset(&username))
+ < 0) {
virReportOOMError();
- return 0;
+ goto err;
}
- cmd = virBufferContentAndReset(&buf);
- ret = phypExec(session, cmd, &exit_status, conn);
+ if (stat(local_file, &local_fileinfo) == -1) {
+ VIR_WARN0("Unable to stat local file.");
+ goto err;
+ }
- if (exit_status < 0 || ret == NULL)
+ if (!(fd = fopen(local_file, "rb"))) {
+ VIR_WARN0("Unable to open local file.");
goto err;
+ }
- char_ptr = strchr(ret, '\n');
+ do {
+ channel =
+ libssh2_scp_send(session, remote_file,
+ 0x1FF & local_fileinfo.st_mode,
+ (unsigned long) local_fileinfo.st_size);
- if (char_ptr)
- *char_ptr = '\0';
+ if ((!channel) && (libssh2_session_last_errno(session) !=
+ LIBSSH2_ERROR_EAGAIN))
+ goto err;
+ } while (!channel);
- if (virStrToLong_i(ret, &char_ptr, 10, &memory) == -1)
- goto err;
+ do {
+ nread = fread(buffer, 1, sizeof(buffer), fd);
+ if (nread <= 0) {
+ if (feof(fd)) {
+ /* end of file */
+ break;
+ } else {
+ VIR_ERROR(_("Failed to read from %s"), local_file);
+ goto err;
+ }
+ }
+ ptr = buffer;
+ sent = 0;
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return memory;
+ 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 if (rc > 0) {
+ /* rc indicates how many bytes were written this time */
+ sent += rc;
+ }
+ ptr += sent;
+ nread -= sent;
+ } while (rc > 0 && sent < nread);
+ } while (1);
- err:
- VIR_FREE(cmd);
- VIR_FREE(ret);
+ if (channel) {
+ libssh2_channel_send_eof(channel);
+ libssh2_channel_wait_eof(channel);
+ libssh2_channel_wait_closed(channel);
+ libssh2_channel_free(channel);
+ channel = NULL;
+ }
+ virBufferFreeAndReset(&username);
return 0;
-}
-
-unsigned long
-phypGetLparCPU(virConnectPtr conn, const char *managed_system, int lpar_id)
-{
- return phypGetLparCPUGeneric(conn, managed_system, lpar_id, 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
-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)
+phypUUIDTable_RemLpar(virConnectPtr conn, int id)
{
- ConnectionData *connection_data = conn->networkPrivateData;
- LIBSSH2_SESSION *session = connection_data->session;
phyp_driverPtr phyp_driver = conn->privateData;
- int system_type = phyp_driver->system_type;
- char *cmd = NULL;
- char *ret = NULL;
- char *char_ptr;
- int exit_status = 0;
- int vcpus = 0;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
+ uuid_tablePtr uuid_table = phyp_driver->uuid_table;
+ unsigned int i = 0;
- virBufferAddLit(&buf, "lshwres");
- if (system_type == HMC)
- virBufferVSprintf(&buf, " -m %s", managed_system);
- virBufferVSprintf(&buf,
- " -r proc --level lpar -F %s --filter lpar_ids=%d",
- type ? "curr_max_procs" : "curr_procs", lpar_id);
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
- virReportOOMError();
- return 0;
+ for (i = 0; i <= uuid_table->nlpars; i++) {
+ if (uuid_table->lpars[i]->id == id) {
+ uuid_table->lpars[i]->id = -1;
+ memset(uuid_table->lpars[i]->uuid, 0, VIR_UUID_BUFLEN);
+ }
}
- cmd = virBufferContentAndReset(&buf);
-
- ret = phypExec(session, cmd, &exit_status, conn);
- if (exit_status < 0 || ret == NULL)
+ if (phypUUIDTable_WriteFile(conn) == -1)
goto err;
- char_ptr = strchr(ret, '\n');
-
- if (char_ptr)
- *char_ptr = '\0';
-
- if (virStrToLong_i(ret, &char_ptr, 10, &vcpus) == -1)
+ if (phypUUIDTable_Push(conn) == -1)
goto err;
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return (unsigned long) vcpus;
+ return 0;
err:
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return 0;
+ return -1;
}
-int
-phypGetRemoteSlot(virConnectPtr conn, const char *managed_system,
- const char *lpar_name)
+static int
+phypUUIDTable_AddLpar(virConnectPtr conn, unsigned char *uuid, int id)
{
- ConnectionData *connection_data = conn->networkPrivateData;
- LIBSSH2_SESSION *session = connection_data->session;
phyp_driverPtr phyp_driver = conn->privateData;
- int system_type = phyp_driver->system_type;
- char *cmd = NULL;
- char *ret = NULL;
- char *char_ptr;
- int remote_slot = 0;
- int exit_status = 0;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
+ uuid_tablePtr uuid_table = phyp_driver->uuid_table;
- virBufferAddLit(&buf, "lshwres");
- if (system_type == HMC)
- virBufferVSprintf(&buf, " -m %s", managed_system);
- virBufferVSprintf(&buf, " -r virtualio --rsubtype scsi -F "
- "remote_slot_num --filter lpar_names=%s", lpar_name);
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
+ uuid_table->nlpars++;
+ unsigned int i = uuid_table->nlpars;
+ i--;
+
+ if (VIR_REALLOC_N(uuid_table->lpars, uuid_table->nlpars) < 0) {
virReportOOMError();
- return -1;
+ goto err;
}
- cmd = virBufferContentAndReset(&buf);
-
- ret = phypExec(session, cmd, &exit_status, conn);
- if (exit_status < 0 || ret == NULL)
+ if (VIR_ALLOC(uuid_table->lpars[i]) < 0) {
+ virReportOOMError();
goto err;
+ }
- char_ptr = strchr(ret, '\n');
+ uuid_table->lpars[i]->id = id;
+ memmove(uuid_table->lpars[i]->uuid, uuid, VIR_UUID_BUFLEN);
- if (char_ptr)
- *char_ptr = '\0';
+ if (phypUUIDTable_WriteFile(conn) == -1)
+ goto err;
- if (virStrToLong_i(ret, &char_ptr, 10, &remote_slot) == -1)
+ if (phypUUIDTable_Push(conn) == -1)
goto err;
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return remote_slot;
+ return 0;
err:
- VIR_FREE(cmd);
- VIR_FREE(ret);
return -1;
}
-char *
-phypGetBackingDevice(virConnectPtr conn, const char *managed_system,
- char *lpar_name)
+static int
+phypUUIDTable_ReadFile(virConnectPtr conn)
{
- ConnectionData *connection_data = conn->networkPrivateData;
- LIBSSH2_SESSION *session = connection_data->session;
phyp_driverPtr phyp_driver = conn->privateData;
- int system_type = phyp_driver->system_type;
- char *cmd = NULL;
- char *ret = NULL;
- int remote_slot = 0;
- int exit_status = 0;
- char *char_ptr;
- char *backing_device = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if ((remote_slot =
- phypGetRemoteSlot(conn, managed_system, lpar_name)) == -1)
- return NULL;
+ uuid_tablePtr uuid_table = phyp_driver->uuid_table;
+ unsigned int i = 0;
+ int fd = -1;
+ char local_file[] = "./uuid_table";
+ int rc = 0;
+ int id;
- virBufferAddLit(&buf, "lshwres");
- if (system_type == HMC)
- virBufferVSprintf(&buf, " -m %s", managed_system);
- virBufferVSprintf(&buf, " -r virtualio --rsubtype scsi -F "
- "backing_devices --filter slots=%d", remote_slot);
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
- virReportOOMError();
- return NULL;
+ if ((fd = open(local_file, O_RDONLY)) == -1) {
+ VIR_WARN0("Unable to write information to local file.");
+ goto err;
}
- cmd = virBufferContentAndReset(&buf);
-
- ret = phypExec(session, cmd, &exit_status, conn);
- if (exit_status < 0 || ret == NULL)
- 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++) {
- /* here is a little trick to deal returns of this kind:
- *
- * 0x8100000000000000//lv01
- *
- * the information we really need is only lv01, so we
- * need to skip a lot of things on the string.
- * */
- char_ptr = strchr(ret, '/');
-
- if (char_ptr) {
- char_ptr++;
- if (char_ptr[0] == '/')
- char_ptr++;
- else
- goto err;
-
- backing_device = strdup(char_ptr);
+ rc = read(fd, &id, sizeof(int));
+ if (rc == sizeof(int)) {
+ if (VIR_ALLOC(uuid_table->lpars[i]) < 0) {
+ virReportOOMError();
+ goto err;
+ }
+ uuid_table->lpars[i]->id = id;
+ } else {
+ VIR_WARN0
+ ("Unable to read from information to local file.");
+ goto err;
+ }
- if (backing_device == NULL) {
- virReportOOMError();
- goto err;
+ rc = read(fd, uuid_table->lpars[i]->uuid, VIR_UUID_BUFLEN);
+ if (rc != VIR_UUID_BUFLEN) {
+ VIR_WARN0("Unable to read information to local file.");
+ goto err;
+ }
}
- } else {
- backing_device = ret;
- ret = NULL;
- }
-
- char_ptr = strchr(backing_device, '\n');
-
- if (char_ptr)
- *char_ptr = '\0';
+ } else
+ virReportOOMError();
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return backing_device;
+ close(fd);
+ return 0;
err:
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return NULL;
-
+ close(fd);
+ return -1;
}
-int
-phypGetLparState(virConnectPtr conn, unsigned int lpar_id)
+static int
+phypUUIDTable_Pull(virConnectPtr conn)
{
ConnectionData *connection_data = conn->networkPrivateData;
- phyp_driverPtr phyp_driver = conn->privateData;
LIBSSH2_SESSION *session = connection_data->session;
- int system_type = phyp_driver->system_type;
- char *cmd = NULL;
- char *ret = NULL;
- int exit_status = 0;
- char *char_ptr = NULL;
- char *managed_system = phyp_driver->managed_system;
- int state = VIR_DOMAIN_NOSTATE;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
+ LIBSSH2_CHANNEL *channel = NULL;
+ virBuffer username = VIR_BUFFER_INITIALIZER;
+ struct stat fileinfo;
+ char buffer[1024];
+ int rc = 0;
+ int fd;
+ int got = 0;
+ int amount = 0;
+ int total = 0;
+ int sock = 0;
+ char local_file[] = "./uuid_table";
+ char *remote_file = NULL;
- virBufferAddLit(&buf, "lssyscfg -r lpar");
- if (system_type == HMC)
- virBufferVSprintf(&buf, " -m %s", managed_system);
- virBufferVSprintf(&buf, " -F state --filter lpar_ids=%d", lpar_id);
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
- virReportOOMError();
- return state;
- }
- cmd = virBufferContentAndReset(&buf);
+ if (conn->uri->user != NULL) {
+ virBufferVSprintf(&username, "%s", conn->uri->user);
- ret = phypExec(session, cmd, &exit_status, conn);
+ if (virBufferError(&username)) {
+ virBufferFreeAndReset(&username);
+ virReportOOMError();
+ goto err;
+ }
+ }
- if (exit_status < 0 || ret == NULL)
- goto cleanup;
+ if (virAsprintf
+ (&remote_file, "/home/%s/libvirt_uuid_table",
+ virBufferContentAndReset(&username))
+ < 0) {
+ virReportOOMError();
+ goto err;
+ }
- char_ptr = strchr(ret, '\n');
+ /* Trying to stat the remote file. */
+ do {
+ channel = libssh2_scp_recv(session, remote_file, &fileinfo);
- if (char_ptr)
- *char_ptr = '\0';
+ if (!channel) {
+ if (libssh2_session_last_errno(session) !=
+ LIBSSH2_ERROR_EAGAIN) {
+ goto err;;
+ } else {
+ waitsocket(sock, session);
+ }
+ }
+ } while (!channel);
- if (STREQ(ret, "Running"))
- state = VIR_DOMAIN_RUNNING;
- else if (STREQ(ret, "Not Activated"))
- state = VIR_DOMAIN_SHUTOFF;
- else if (STREQ(ret, "Shutting Down"))
- state = VIR_DOMAIN_SHUTDOWN;
+ /* Creating a new data base based on remote file */
+ if ((fd = creat(local_file, 0755)) == -1)
+ goto err;
- cleanup:
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return state;
-}
+ /* Request a file via SCP */
+ while (got < fileinfo.st_size) {
+ do {
+ amount = sizeof(buffer);
-int
-phypGetVIOSPartitionID(virConnectPtr conn)
-{
- ConnectionData *connection_data = conn->networkPrivateData;
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = connection_data->session;
- int system_type = phyp_driver->system_type;
- char *cmd = NULL;
- char *ret = NULL;
- int exit_status = 0;
- int id = -1;
- char *char_ptr;
- char *managed_system = phyp_driver->managed_system;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
+ if ((fileinfo.st_size - got) < amount) {
+ amount = fileinfo.st_size - got;
+ }
- virBufferAddLit(&buf, "lssyscfg");
- if (system_type == HMC)
- virBufferVSprintf(&buf, " -m %s", managed_system);
- virBufferAddLit(&buf, " -r lpar -F lpar_id,lpar_env|grep "
- "vioserver|sed -s 's/,.*$//'");
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
- virReportOOMError();
- return -1;
- }
- cmd = virBufferContentAndReset(&buf);
+ rc = libssh2_channel_read(channel, buffer, amount);
+ if (rc > 0) {
+ if (safewrite(fd, buffer, rc) != rc)
+ VIR_WARN0
+ ("Unable to write information to local file.");
- ret = phypExec(session, cmd, &exit_status, conn);
+ got += rc;
+ total += rc;
+ }
+ } while (rc > 0);
- if (exit_status < 0 || ret == NULL)
- goto err;
+ if ((rc == LIBSSH2_ERROR_EAGAIN)
+ && (got < fileinfo.st_size)) {
+ /* this is due to blocking that would occur otherwise
+ * so we loop on this condition */
- if (virStrToLong_i(ret, &char_ptr, 10, &id) == -1)
- goto err;
+ waitsocket(sock, session); /* now we wait */
+ continue;
+ }
+ break;
+ }
+ close(fd);
+ goto exit;
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return id;
+ exit:
+ if (channel) {
+ libssh2_channel_send_eof(channel);
+ libssh2_channel_wait_eof(channel);
+ libssh2_channel_wait_closed(channel);
+ libssh2_channel_free(channel);
+ channel = NULL;
+ }
+ virBufferFreeAndReset(&username);
+ return 0;
err:
- VIR_FREE(cmd);
- VIR_FREE(ret);
+ 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
-phypDiskType(virConnectPtr conn, char *backing_device)
+static int
+phypUUIDTable_Init(virConnectPtr conn)
{
- phyp_driverPtr phyp_driver = conn->privateData;
- ConnectionData *connection_data = conn->networkPrivateData;
- LIBSSH2_SESSION *session = connection_data->session;
- int system_type = phyp_driver->system_type;
- char *cmd = NULL;
- char *ret = NULL;
- int exit_status = 0;
- char *char_ptr;
- char *managed_system = phyp_driver->managed_system;
- int vios_id = phyp_driver->vios_id;
- int disk_type = -1;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
+ uuid_tablePtr uuid_table;
+ phyp_driverPtr phyp_driver;
+ int nids_numdomains = 0;
+ int nids_listdomains = 0;
+ int *ids = NULL;
+ unsigned int i = 0;
- virBufferAddLit(&buf, "viosvrcmd");
- if (system_type == HMC)
- virBufferVSprintf(&buf, " -m %s", managed_system);
- virBufferVSprintf(&buf, " -p %d -c \"lssp -field name type "
- "-fmt , -all|grep %s|sed -e 's/^.*,//'\"",
- vios_id, backing_device);
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
+ if ((nids_numdomains = phypNumDomainsGeneric(conn, 2)) < 0)
+ goto err;
+
+ if (VIR_ALLOC_N(ids, nids_numdomains) < 0) {
virReportOOMError();
- return disk_type;
+ goto err;
}
- cmd = virBufferContentAndReset(&buf);
-
- ret = phypExec(session, cmd, &exit_status, conn);
- if (exit_status < 0 || ret == NULL)
- goto cleanup;
+ if ((nids_listdomains =
+ phypListDomainsGeneric(conn, ids, nids_numdomains, 1)) < 0)
+ goto err;
- char_ptr = strchr(ret, '\n');
-
- if (char_ptr)
- *char_ptr = '\0';
-
- if (STREQ(ret, "LVPOOL"))
- disk_type = VIR_DOMAIN_DISK_TYPE_BLOCK;
- else if (STREQ(ret, "FBPOOL"))
- disk_type = VIR_DOMAIN_DISK_TYPE_FILE;
+ /* exit early if there are no domains */
+ if (nids_numdomains == 0 && nids_listdomains == 0)
+ goto exit;
+ else if (nids_numdomains != nids_listdomains) {
+ VIR_ERROR0(_("Unable to determine number of domains."));
+ goto err;
+ }
- cleanup:
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return disk_type;
-}
+ phyp_driver = conn->privateData;
+ uuid_table = phyp_driver->uuid_table;
+ uuid_table->nlpars = nids_listdomains;
-/* This is a generic function that won't be used directly by
- * libvirt api. The function returns the number of domains
- * in different states: Running, Not Activated and all:
- *
- * type: 0 - Running
- * 1 - Not Activated
- * * - All
- * */
-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 system_type = phyp_driver->system_type;
- int exit_status = 0;
- int ndom = 0;
- char *char_ptr;
- char *cmd = NULL;
- char *ret = NULL;
- char *managed_system = phyp_driver->managed_system;
- const char *state;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
+ /* 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();
+ goto err;
+ }
+ uuid_table->lpars[i]->id = ids[i];
- if (type == 0)
- state = "|grep Running";
- else if (type == 1) {
- if (system_type == HMC) {
- state = "|grep \"Not Activated\"";
+ if (virUUIDGenerate(uuid_table->lpars[i]->uuid) < 0)
+ VIR_WARN("Unable to generate UUID for domain %d",
+ ids[i]);
+ }
} else {
- state = "|grep \"Open Firmware\"";
+ virReportOOMError();
+ goto err;
}
- } else
- state = " ";
-
- virBufferAddLit(&buf, "lssyscfg -r lpar");
- if (system_type == HMC)
- virBufferVSprintf(&buf, " -m %s", managed_system);
- virBufferVSprintf(&buf, " -F lpar_id,state %s |grep -c '^[0-9]*'",
- state);
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
- virReportOOMError();
- return -1;
- }
- cmd = virBufferContentAndReset(&buf);
-
- ret = phypExec(session, cmd, &exit_status, conn);
- if (exit_status < 0 || ret == NULL)
- goto err;
+ if (phypUUIDTable_WriteFile(conn) == -1)
+ goto err;
- if (virStrToLong_i(ret, &char_ptr, 10, &ndom) == -1)
- goto err;
+ if (phypUUIDTable_Push(conn) == -1)
+ goto err;
+ } else {
+ if (phypUUIDTable_ReadFile(conn) == -1)
+ goto err;
+ goto exit;
+ }
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return ndom;
+ exit:
+ VIR_FREE(ids);
+ return 0;
err:
- VIR_FREE(cmd);
- VIR_FREE(ret);
+ VIR_FREE(ids);
return -1;
}
-static int
-phypNumDefinedDomains(virConnectPtr conn)
+static void
+phypUUIDTable_Free(uuid_tablePtr uuid_table)
{
- return phypNumDomainsGeneric(conn, 1);
-}
+ int i;
-static int
-phypNumDomains(virConnectPtr conn)
-{
- return phypNumDomainsGeneric(conn, 0);
+ if (uuid_table == NULL)
+ return;
+
+ for (i = 0; i < uuid_table->nlpars; i++)
+ VIR_FREE(uuid_table->lpars[i]);
+
+ VIR_FREE(uuid_table->lpars);
+ VIR_FREE(uuid_table);
}
-/* This is a generic function that won't be used directly by
- * libvirt api. The function returns the ids of domains
- * in different states: Running, and all:
- *
- * type: 0 - Running
- * 1 - all
- * */
static int
-phypListDomainsGeneric(virConnectPtr conn, int *ids, int nids,
- unsigned int type)
+escape_specialcharacters(char *src, char *dst, size_t dstlen)
{
- ConnectionData *connection_data = conn->networkPrivateData;
- phyp_driverPtr phyp_driver = conn->privateData;
- LIBSSH2_SESSION *session = connection_data->session;
- int system_type = phyp_driver->system_type;
- char *managed_system = phyp_driver->managed_system;
- int exit_status = 0;
- int got = 0;
- char *char_ptr;
+ size_t len = strlen(src);
+ char temp_buffer[len];
unsigned int i = 0, j = 0;
- char id_c[10];
- char *cmd = NULL;
- char *ret = NULL;
- const char *state;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
-
- if (type == 0)
- state = "|grep Running";
- else
- state = " ";
-
- memset(id_c, 0, 10);
-
- virBufferAddLit(&buf, "lssyscfg -r lpar");
- if (system_type == HMC)
- virBufferVSprintf(&buf, " -m %s", managed_system);
- virBufferVSprintf(&buf, " -F lpar_id,state %s | sed -e 's/,.*$//'",
- state);
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
- virReportOOMError();
+ if (len == 0)
return -1;
- }
- cmd = virBufferContentAndReset(&buf);
-
- ret = phypExec(session, cmd, &exit_status, conn);
- /* I need to parse the textual return in order to get the ret */
- if (exit_status < 0 || ret == NULL)
- goto err;
- else {
- while (got < nids) {
- if (ret[i] == '\0')
- break;
- else if (ret[i] == '\n') {
- if (virStrToLong_i(id_c, &char_ptr, 10, &ids[got]) == -1) {
- VIR_ERROR(_("Cannot parse number from '%s'"), id_c);
- goto err;
- }
- memset(id_c, 0, 10);
- j = 0;
- got++;
- } else {
- id_c[j] = ret[i];
+ 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 '\t':
+ continue;
+ default:
+ temp_buffer[j] = src[i];
j++;
- }
- i++;
}
}
+ temp_buffer[j] = '\0';
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return got;
+ if (virStrcpy(dst, temp_buffer, dstlen) == NULL)
+ return -1;
- err:
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return -1;
+ return 0;
}
-static int
-phypListDomains(virConnectPtr conn, int *ids, int nids)
+static LIBSSH2_SESSION *
+openSSHSession(virConnectPtr conn, virConnectAuthPtr auth,
+ int *internal_socket)
{
- return phypListDomainsGeneric(conn, ids, nids, 0);
-}
+ LIBSSH2_SESSION *session;
+ const char *hostname = conn->uri->server;
+ char *username = NULL;
+ char *password = NULL;
+ int sock;
+ int rc;
+ struct addrinfo *ai = NULL, *cur;
+ struct addrinfo hints;
+ int ret;
+ char *pubkey = NULL;
+ char *pvtkey = NULL;
+ char *userhome = virGetUserDirectory(geteuid());
+ struct stat pvt_stat, pub_stat;
-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;
- int system_type = phyp_driver->system_type;
- char *managed_system = phyp_driver->managed_system;
- int exit_status = 0;
- int got = 0;
- int i;
- char *cmd = NULL;
- char *ret = NULL;
- char *domains = NULL;
- char *char_ptr2 = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
+ if (userhome == NULL)
+ goto err;
- virBufferAddLit(&buf, "lssyscfg -r lpar");
- if (system_type == HMC)
- virBufferVSprintf(&buf, " -m %s", managed_system);
- virBufferVSprintf(&buf, " -F name,state | grep \"Not Activated\" | "
- "sed -e 's/,.*$//'");
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
+ if (virAsprintf(&pubkey, "%s/.ssh/id_rsa.pub", userhome) < 0) {
virReportOOMError();
- return -1;
+ goto err;
}
- cmd = virBufferContentAndReset(&buf);
-
- ret = phypExec(session, cmd, &exit_status, conn);
- /* I need to parse the textual return in order to get the domains */
- if (exit_status < 0 || ret == NULL)
+ if (virAsprintf(&pvtkey, "%s/.ssh/id_rsa", userhome) < 0) {
+ virReportOOMError();
goto err;
- else {
- domains = ret;
-
- while (got < nnames) {
- char_ptr2 = strchr(domains, '\n');
-
- if (char_ptr2) {
- *char_ptr2 = '\0';
- if ((names[got++] = strdup(domains)) == NULL) {
- virReportOOMError();
- goto err;
- }
- char_ptr2++;
- domains = char_ptr2;
- } else
- break;
- }
}
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return got;
-
- err:
- for (i = 0; i < got; i++)
- VIR_FREE(names[i]);
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return -1;
-}
+ if (conn->uri->user != NULL) {
+ username = strdup(conn->uri->user);
-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 = phyp_driver->managed_system;
- unsigned char lpar_uuid[VIR_UUID_BUFLEN];
+ if (username == NULL) {
+ virReportOOMError();
+ goto err;
+ }
+ } else {
+ if (auth == NULL || auth->cb == NULL) {
+ PHYP_ERROR(VIR_ERR_AUTH_FAILED,
+ "%s", _("No authentication callback provided."));
+ goto err;
+ }
- lpar_id = phypGetLparID(session, managed_system, lpar_name, conn);
- if (lpar_id == -1)
- return NULL;
+ username = virRequestUsername(auth, NULL, conn->uri->server);
- if (phypGetLparUUID(lpar_uuid, lpar_id, conn) == -1)
- return NULL;
+ if (username == NULL) {
+ PHYP_ERROR(VIR_ERR_AUTH_FAILED, "%s",
+ _("Username request failed"));
+ goto err;
+ }
+ }
- dom = virGetDomain(conn, lpar_name, lpar_uuid);
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = 0;
- if (dom)
- dom->id = lpar_id;
+ ret = getaddrinfo(hostname, "22", &hints, &ai);
+ if (ret != 0) {
+ PHYP_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Error while getting %s address info"), hostname);
+ goto err;
+ }
- return dom;
-}
+ cur = ai;
+ 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) {
+ goto connected;
+ }
+ close(sock);
+ }
+ cur = cur->ai_next;
+ }
-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 = phyp_driver->managed_system;
- int exit_status = 0;
- unsigned char lpar_uuid[VIR_UUID_BUFLEN];
+ PHYP_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Failed to connect to %s"), hostname);
+ freeaddrinfo(ai);
+ goto err;
- char *lpar_name = phypGetLparNAME(session, managed_system, lpar_id,
- conn);
+ connected:
- if (phypGetLparUUID(lpar_uuid, lpar_id, conn) == -1)
- goto err;
+ (*internal_socket) = sock;
- if (exit_status < 0)
+ /* Create a session instance */
+ session = libssh2_session_init();
+ if (!session)
goto err;
- dom = virGetDomain(conn, lpar_name, lpar_uuid);
-
- if (dom)
- dom->id = lpar_id;
-
- VIR_FREE(lpar_name);
- return dom;
+ /* tell libssh2 we want it all done non-blocking */
+ libssh2_session_set_blocking(session, 0);
- err:
- VIR_FREE(lpar_name);
- return NULL;
-}
+ while ((rc = libssh2_session_startup(session, sock)) ==
+ LIBSSH2_ERROR_EAGAIN) ;
+ if (rc) {
+ PHYP_ERROR(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Failure establishing SSH session."));
+ goto disconnect;
+ }
-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;
- virDomainDef def;
- char *managed_system = phyp_driver->managed_system;
+ /* Trying authentication by pubkey */
+ if (stat(pvtkey, &pvt_stat) || stat(pubkey, &pub_stat)) {
+ rc = LIBSSH2_ERROR_SOCKET_NONE;
+ goto keyboard_interactive;
+ }
- memset(&def, 0, sizeof(virDomainDef));
+ while ((rc =
+ libssh2_userauth_publickey_fromfile(session, username,
+ pubkey,
+ pvtkey,
+ NULL)) ==
+ LIBSSH2_ERROR_EAGAIN) ;
- def.virtType = VIR_DOMAIN_VIRT_PHYP;
- def.id = dom->id;
+ keyboard_interactive:
+ if (rc == LIBSSH2_ERROR_SOCKET_NONE
+ || rc == LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED
+ || rc == LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED) {
+ if (auth == NULL || auth->cb == NULL) {
+ PHYP_ERROR(VIR_ERR_AUTH_FAILED,
+ "%s", _("No authentication callback provided."));
+ goto disconnect;
+ }
- char *lpar_name = phypGetLparNAME(session, managed_system, def.id,
- dom->conn);
+ password = virRequestPassword(auth, username, conn->uri->server);
- if (lpar_name == NULL) {
- VIR_ERROR0(_("Unable to determine domain's name."));
- goto err;
- }
+ if (password == NULL) {
+ PHYP_ERROR(VIR_ERR_AUTH_FAILED, "%s",
+ _("Password request failed"));
+ goto disconnect;
+ }
- if (phypGetLparUUID(def.uuid, dom->id, dom->conn) == -1) {
- VIR_ERROR0(_("Unable to generate random uuid."));
- goto err;
- }
+ while ((rc =
+ libssh2_userauth_password(session, username,
+ password)) ==
+ LIBSSH2_ERROR_EAGAIN) ;
- if ((def.maxmem =
- phypGetLparMem(dom->conn, managed_system, dom->id, 0)) == 0) {
- VIR_ERROR0(_("Unable to determine domain's max memory."));
- goto err;
- }
+ if (rc) {
+ PHYP_ERROR(VIR_ERR_AUTH_FAILED,
+ "%s", _("Authentication failed"));
+ goto disconnect;
+ } else
+ goto exit;
- if ((def.memory =
- phypGetLparMem(dom->conn, managed_system, dom->id, 1)) == 0) {
- VIR_ERROR0(_("Unable to determine domain's memory."));
- goto err;
- }
+ } else if (rc == LIBSSH2_ERROR_NONE) {
+ goto exit;
- if ((def.vcpus =
- phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0) {
- VIR_ERROR0(_("Unable to determine domain's CPU."));
+ } else if (rc == LIBSSH2_ERROR_ALLOC || rc == LIBSSH2_ERROR_SOCKET_SEND
+ || rc == LIBSSH2_ERROR_SOCKET_TIMEOUT) {
goto err;
}
- return virDomainDefFormat(&def, flags);
-
+ disconnect:
+ libssh2_session_disconnect(session, "Disconnecting...");
+ libssh2_session_free(session);
err:
+ VIR_FREE(userhome);
+ VIR_FREE(pubkey);
+ VIR_FREE(pvtkey);
+ VIR_FREE(username);
+ VIR_FREE(password);
return NULL;
+
+ exit:
+ VIR_FREE(userhome);
+ VIR_FREE(pubkey);
+ VIR_FREE(pvtkey);
+ VIR_FREE(username);
+ VIR_FREE(password);
+ return session;
}
-static int
-phypDomainResume(virDomainPtr dom)
-{
- ConnectionData *connection_data = dom->conn->networkPrivateData;
- phyp_driverPtr phyp_driver = dom->conn->privateData;
- LIBSSH2_SESSION *session = connection_data->session;
- int system_type = phyp_driver->system_type;
- char *managed_system = phyp_driver->managed_system;
- int exit_status = 0;
- char *cmd = NULL;
- char *ret = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
+static virDrvOpenStatus
+phypOpen(virConnectPtr conn,
+ virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
+{
+ LIBSSH2_SESSION *session = NULL;
+ ConnectionData *connection_data = NULL;
+ char *string = NULL;
+ size_t len = 0;
+ int internal_socket;
+ uuid_tablePtr uuid_table = NULL;
+ phyp_driverPtr phyp_driver = NULL;
+ char *char_ptr;
+ char *managed_system = NULL;
- virBufferAddLit(&buf, "chsysstate");
- if (system_type == HMC)
- virBufferVSprintf(&buf, " -m %s", managed_system);
- virBufferVSprintf(&buf, " -r lpar -o on --id %d -f %s",
- dom->id, dom->name);
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
+ if (!conn || !conn->uri)
+ return VIR_DRV_OPEN_DECLINED;
+
+ if (conn->uri->scheme == NULL || STRNEQ(conn->uri->scheme, "phyp"))
+ return VIR_DRV_OPEN_DECLINED;
+
+ if (conn->uri->server == NULL) {
+ PHYP_ERROR(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Missing server name in phyp:// URI"));
+ return VIR_DRV_OPEN_ERROR;
+ }
+
+ if (VIR_ALLOC(phyp_driver) < 0) {
virReportOOMError();
- return -1;
+ goto failure;
}
- cmd = virBufferContentAndReset(&buf);
- ret = phypExec(session, cmd, &exit_status, dom->conn);
+ if (VIR_ALLOC(uuid_table) < 0) {
+ virReportOOMError();
+ goto failure;
+ }
- if (exit_status < 0)
- goto err;
+ if (VIR_ALLOC(connection_data) < 0) {
+ virReportOOMError();
+ goto failure;
+ }
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return 0;
+ if (conn->uri->path) {
+ len = strlen(conn->uri->path) + 1;
- err:
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return -1;
-}
+ if (VIR_ALLOC_N(string, len) < 0) {
+ virReportOOMError();
+ goto failure;
+ }
-static int
-phypDomainShutdown(virDomainPtr dom)
-{
- ConnectionData *connection_data = dom->conn->networkPrivateData;
- virConnectPtr conn = dom->conn;
- LIBSSH2_SESSION *session = connection_data->session;
- phyp_driverPtr phyp_driver = conn->privateData;
- int system_type = phyp_driver->system_type;
- char *managed_system = phyp_driver->managed_system;
- int exit_status = 0;
- char *cmd = NULL;
- char *ret = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
+ /* need to shift one byte in order to remove the first "/" of URI component */
+ if (conn->uri->path[0] == '/')
+ managed_system = strdup(conn->uri->path + 1);
+ else
+ managed_system = strdup(conn->uri->path);
- virBufferAddLit(&buf, "chsysstate");
- if (system_type == HMC)
- virBufferVSprintf(&buf, " -m %s", managed_system);
- virBufferVSprintf(&buf, " -r lpar -o shutdown --id %d", dom->id);
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
+ if (!managed_system) {
+ virReportOOMError();
+ goto failure;
+ }
+
+ /* 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) {
+ PHYP_ERROR(VIR_ERR_INTERNAL_ERROR,
+ "%s",
+ _("Error parsing 'path'. Invalid characters."));
+ goto failure;
+ }
+ }
+
+ if ((session = openSSHSession(conn, auth, &internal_socket)) == NULL) {
+ PHYP_ERROR(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Error while opening SSH session."));
+ goto failure;
+ }
+
+ connection_data->session = session;
+
+ uuid_table->nlpars = 0;
+ uuid_table->lpars = NULL;
+
+ if (conn->uri->path)
+ phyp_driver->managed_system = managed_system;
+
+ phyp_driver->uuid_table = uuid_table;
+ if ((phyp_driver->caps = phypCapsInit()) == NULL) {
virReportOOMError();
- return 0;
+ goto failure;
}
- cmd = virBufferContentAndReset(&buf);
- ret = phypExec(session, cmd, &exit_status, dom->conn);
+ conn->privateData = phyp_driver;
+ conn->networkPrivateData = connection_data;
- if (exit_status < 0)
- goto err;
+ if ((phyp_driver->system_type = phypGetSystemType(conn)) == -1)
+ goto failure;
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return 0;
+ if (phypUUIDTable_Init(conn) == -1)
+ goto failure;
- err:
- VIR_FREE(cmd);
- VIR_FREE(ret);
- return 0;
+ if (phyp_driver->system_type == HMC) {
+ if ((phyp_driver->vios_id = phypGetVIOSPartitionID(conn)) == -1)
+ goto failure;
+ }
+
+ return VIR_DRV_OPEN_SUCCESS;
+
+ failure:
+ if (phyp_driver != NULL) {
+ virCapabilitiesFree(phyp_driver->caps);
+ VIR_FREE(phyp_driver->managed_system);
+ VIR_FREE(phyp_driver);
+ }
+
+ phypUUIDTable_Free(uuid_table);
+
+ if (session != NULL) {
+ libssh2_session_disconnect(session, "Disconnecting...");
+ libssh2_session_free(session);
+ }
+
+ VIR_FREE(connection_data);
+ VIR_FREE(string);
+
+ return VIR_DRV_OPEN_ERROR;
}
static int
-phypDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info)
+phypClose(virConnectPtr conn)
{
- phyp_driverPtr phyp_driver = dom->conn->privateData;
- char *managed_system = phyp_driver->managed_system;
+ ConnectionData *connection_data = conn->networkPrivateData;
+ phyp_driverPtr phyp_driver = conn->privateData;
+ LIBSSH2_SESSION *session = connection_data->session;
- info->state = phypGetLparState(dom->conn, dom->id);
+ libssh2_session_disconnect(session, "Disconnecting...");
+ libssh2_session_free(session);
- if ((info->maxMem =
- phypGetLparMem(dom->conn, managed_system, dom->id, 0)) == 0)
- VIR_WARN0("Unable to determine domain's max memory.");
+ virCapabilitiesFree(phyp_driver->caps);
+ phypUUIDTable_Free(phyp_driver->uuid_table);
+ VIR_FREE(phyp_driver->managed_system);
+ VIR_FREE(phyp_driver);
+ VIR_FREE(connection_data);
+ return 0;
+}
- if ((info->memory =
- phypGetLparMem(dom->conn, managed_system, dom->id, 1)) == 0)
- VIR_WARN0("Unable to determine domain's memory.");
- if ((info->nrVirtCpu =
- phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0)
- VIR_WARN0("Unable to determine domain's CPU.");
+static int
+phypIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+ /* Phyp uses an SSH tunnel, so is always encrypted */
+ return 1;
+}
- return 0;
+
+static int
+phypIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+ /* Phyp uses an SSH tunnel, so is always secure */
+ return 1;
}
+
+/* return the lpar_id given a name and a managed system name */
static int
-phypDomainDestroy(virDomainPtr dom)
+phypGetLparID(LIBSSH2_SESSION * session, const char *managed_system,
+ const char *name, virConnectPtr conn)
{
- ConnectionData *connection_data = dom->conn->networkPrivateData;
- phyp_driverPtr phyp_driver = dom->conn->privateData;
- LIBSSH2_SESSION *session = connection_data->session;
+ phyp_driverPtr phyp_driver = conn->privateData;
int system_type = phyp_driver->system_type;
- char *managed_system = phyp_driver->managed_system;
int exit_status = 0;
+ int lpar_id = 0;
+ char *char_ptr;
char *cmd = NULL;
char *ret = NULL;
virBuffer buf = VIR_BUFFER_INITIALIZER;
- virBufferAddLit(&buf, "rmsyscfg");
+ virBufferAddLit(&buf, "lssyscfg -r lpar");
if (system_type == HMC)
virBufferVSprintf(&buf, " -m %s", managed_system);
- virBufferVSprintf(&buf, " -r lpar --id %d", dom->id);
+ virBufferVSprintf(&buf, " --filter lpar_names=%s -F lpar_id", name);
if (virBufferError(&buf)) {
virBufferFreeAndReset(&buf);
virReportOOMError();
}
cmd = virBufferContentAndReset(&buf);
- ret = phypExec(session, cmd, &exit_status, dom->conn);
+ ret = phypExec(session, cmd, &exit_status, conn);
- if (exit_status < 0)
+ if (exit_status < 0 || ret == NULL)
goto err;
- if (phypUUIDTable_RemLpar(dom->conn, dom->id) == -1)
+ if (virStrToLong_i(ret, &char_ptr, 10, &lpar_id) == -1)
goto err;
VIR_FREE(cmd);
VIR_FREE(ret);
- return 0;
+ return lpar_id;
err:
VIR_FREE(cmd);
VIR_FREE(ret);
return -1;
-
}
-static virDomainPtr
-phypDomainCreateAndStart(virConnectPtr conn,
- const char *xml, unsigned int flags)
+/* return the lpar name given a lpar_id and a managed system name */
+static char *
+phypGetLparNAME(LIBSSH2_SESSION * session, const char *managed_system,
+ unsigned int lpar_id, virConnectPtr conn)
{
-
- 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;
-
- virCheckFlags(0, NULL);
-
- if (!(def = virDomainDefParseString(phyp_driver->caps, xml,
- VIR_DOMAIN_XML_SECURE)))
- goto err;
+ int system_type = phyp_driver->system_type;
+ char *cmd = NULL;
+ char *ret = NULL;
+ int exit_status = 0;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
- /* checking if this name already exists on this system */
- if (phypGetLparID(session, managed_system, def->name, conn) == -1) {
- VIR_WARN0("LPAR name already exists.");
- goto err;
+ virBufferAddLit(&buf, "lssyscfg -r lpar");
+ if (system_type == HMC)
+ virBufferVSprintf(&buf, " -m %s", managed_system);
+ virBufferVSprintf(&buf, " --filter lpar_ids=%d -F name", lpar_id);
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ virReportOOMError();
+ return NULL;
}
+ cmd = virBufferContentAndReset(&buf);
- /* 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_WARN0("LPAR ID or UUID already exists.");
- goto err;
- }
- }
+ ret = phypExec(session, cmd, &exit_status, conn);
- if ((dom = virGetDomain(conn, def->name, def->uuid)) == NULL)
+ if (exit_status < 0 || ret == NULL)
goto err;
- if (phypBuildLpar(conn, def) == -1)
- goto err;
+ char *char_ptr = strchr(ret, '\n');
- if (phypDomainResume(dom) == -1)
- goto err;
+ if (char_ptr)
+ *char_ptr = '\0';
- return dom;
+ VIR_FREE(cmd);
+ return ret;
err:
- virDomainDefFree(def);
- if (dom)
- virUnrefDomain(dom);
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
return NULL;
}
-static char *
-phypConnectGetCapabilities(virConnectPtr conn)
+
+/* Search into the uuid_table for a lpar_uuid given a lpar_id
+ * and a managed system name
+ *
+ * return: 0 - record found
+ * -1 - not found
+ * */
+static int
+phypGetLparUUID(unsigned char *uuid, int lpar_id, virConnectPtr conn)
{
phyp_driverPtr phyp_driver = conn->privateData;
- char *xml;
+ uuid_tablePtr uuid_table = phyp_driver->uuid_table;
+ lparPtr *lpars = uuid_table->lpars;
+ unsigned int i = 0;
- if ((xml = virCapabilitiesFormatXML(phyp_driver->caps)) == NULL)
- virReportOOMError();
+ for (i = 0; i < uuid_table->nlpars; i++) {
+ if (lpars[i]->id == lpar_id) {
+ memmove(uuid, lpars[i]->uuid, VIR_UUID_BUFLEN);
+ return 0;
+ }
+ }
- return xml;
+ return -1;
}
-virCapsPtr
-phypCapsInit(void)
+/*
+ * type:
+ * 0 - maxmem
+ * 1 - memory
+ * */
+static unsigned long
+phypGetLparMem(virConnectPtr conn, const char *managed_system, int lpar_id,
+ int type)
{
- struct utsname utsname;
- virCapsPtr caps;
- virCapsGuestPtr guest;
-
- uname(&utsname);
+ ConnectionData *connection_data = conn->networkPrivateData;
+ LIBSSH2_SESSION *session = connection_data->session;
+ phyp_driverPtr phyp_driver = conn->privateData;
+ int system_type = phyp_driver->system_type;
+ char *cmd = NULL;
+ char *ret = NULL;
+ char *char_ptr;
+ int memory = 0;
+ int exit_status = 0;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
- if ((caps = virCapabilitiesNew(utsname.machine, 0, 0)) == NULL)
- goto no_memory;
+ if (type != 1 && type != 0)
+ return 0;
- /* 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");
+ virBufferAddLit(&buf, "lshwres");
+ if (system_type == HMC)
+ virBufferVSprintf(&buf, " -m %s", managed_system);
+ virBufferVSprintf(&buf,
+ " -r mem --level lpar -F %s --filter lpar_ids=%d",
+ type ? "curr_mem" : "curr_max_mem", lpar_id);
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ virReportOOMError();
+ return 0;
}
+ cmd = virBufferContentAndReset(&buf);
- /* XXX shouldn't 'borrow' KVM's prefix */
- virCapabilitiesSetMacPrefix(caps, (unsigned char[]) {
- 0x52, 0x54, 0x00});
+ ret = phypExec(session, cmd, &exit_status, conn);
- if ((guest = virCapabilitiesAddGuest(caps,
- "linux",
- utsname.machine,
- sizeof(int) == 4 ? 32 : 8,
- NULL, NULL, 0, NULL)) == NULL)
- goto no_memory;
+ if (exit_status < 0 || ret == NULL)
+ goto err;
- if (virCapabilitiesAddGuestDomain(guest,
- "phyp", NULL, NULL, 0, NULL) == NULL)
- goto no_memory;
+ char_ptr = strchr(ret, '\n');
- return caps;
+ if (char_ptr)
+ *char_ptr = '\0';
+
+ if (virStrToLong_i(ret, &char_ptr, 10, &memory) == -1)
+ goto err;
+
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
+ return memory;
+
+ err:
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
+ return 0;
- no_memory:
- virCapabilitiesFree(caps);
- return NULL;
}
-static int
-phypDomainSetCPU(virDomainPtr dom, unsigned int nvcpus)
+static unsigned long
+phypGetLparCPUGeneric(virConnectPtr conn, const char *managed_system,
+ int lpar_id, int type)
{
- ConnectionData *connection_data = dom->conn->networkPrivateData;
- phyp_driverPtr phyp_driver = dom->conn->privateData;
+ ConnectionData *connection_data = conn->networkPrivateData;
LIBSSH2_SESSION *session = connection_data->session;
+ phyp_driverPtr phyp_driver = conn->privateData;
int system_type = phyp_driver->system_type;
- char *managed_system = phyp_driver->managed_system;
- int exit_status = 0;
char *cmd = NULL;
char *ret = NULL;
- char operation;
- unsigned long ncpus = 0;
- unsigned int amount = 0;
+ char *char_ptr;
+ int exit_status = 0;
+ int vcpus = 0;
virBuffer buf = VIR_BUFFER_INITIALIZER;
- if ((ncpus = phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0)
- return 0;
-
- if (nvcpus > phypGetLparCPUMAX(dom)) {
- VIR_ERROR0(_("You are trying to set a number of CPUs bigger than "
- "the max possible."));
- return 0;
- }
-
- if (ncpus > nvcpus) {
- operation = 'r';
- amount = nvcpus - ncpus;
- } else if (ncpus < nvcpus) {
- operation = 'a';
- amount = nvcpus - ncpus;
- } else
- return 0;
-
- virBufferAddLit(&buf, "chhwres -r proc");
+ virBufferAddLit(&buf, "lshwres");
if (system_type == HMC)
virBufferVSprintf(&buf, " -m %s", managed_system);
- virBufferVSprintf(&buf, " --id %d -o %c --procunits %d 2>&1 |sed "
- "-e 's/^.*\\([0-9][0-9]*.[0-9][0-9]*\\).*$/\\1/'",
- dom->id, operation, amount);
+ virBufferVSprintf(&buf,
+ " -r proc --level lpar -F %s --filter lpar_ids=%d",
+ type ? "curr_max_procs" : "curr_procs", lpar_id);
if (virBufferError(&buf)) {
virBufferFreeAndReset(&buf);
virReportOOMError();
}
cmd = virBufferContentAndReset(&buf);
- ret = phypExec(session, cmd, &exit_status, dom->conn);
+ ret = phypExec(session, cmd, &exit_status, conn);
- if (exit_status < 0) {
- VIR_ERROR0(_
- ("Possibly you don't have IBM Tools installed in your LPAR."
- " Contact your support to enable this feature."));
- }
+ if (exit_status < 0 || ret == NULL)
+ goto err;
+
+ char_ptr = strchr(ret, '\n');
+
+ if (char_ptr)
+ *char_ptr = '\0';
+
+ if (virStrToLong_i(ret, &char_ptr, 10, &vcpus) == -1)
+ goto err;
+
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
+ return (unsigned long) vcpus;
+ err:
VIR_FREE(cmd);
VIR_FREE(ret);
return 0;
+}
+static unsigned long
+phypGetLparCPU(virConnectPtr conn, const char *managed_system, int lpar_id)
+{
+ return phypGetLparCPUGeneric(conn, managed_system, lpar_id, 0);
}
-virDriver phypDriver = {
- VIR_DRV_PHYP, "PHYP", phypOpen, /* open */
- phypClose, /* close */
- NULL, /* supports_feature */
- NULL, /* type */
- NULL, /* version */
- NULL, /* libvirtVersion (impl. in libvirt.c) */
- 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 */
- phypDomainSetCPU, /* domainSetVcpus */
- NULL, /* domainPinVcpu */
- NULL, /* domainGetVcpus */
- phypGetLparCPUMAX, /* domainGetMaxVcpus */
- NULL, /* domainGetSecurityLabel */
- NULL, /* nodeGetSecurityModel */
- phypDomainDumpXML, /* domainDumpXML */
- NULL, /* domainXMLFromNative */
- NULL, /* domainXMLToNative */
- phypListDefinedDomains, /* listDefinedDomains */
- phypNumDefinedDomains, /* numOfDefinedDomains */
- NULL, /* domainCreate */
- NULL, /* domainCreateWithFlags */
- NULL, /* domainDefineXML */
- NULL, /* domainUndefine */
- NULL, /* domainAttachDevice */
- NULL, /* domainAttachDeviceFlags */
- NULL, /* domainDetachDevice */
- NULL, /* domainDetachDeviceFlags */
- NULL, /* domainUpdateDeviceFlags */
- NULL, /* domainGetAutostart */
- NULL, /* domainSetAutostart */
- NULL, /* domainGetSchedulerType */
- NULL, /* domainGetSchedulerParameters */
- NULL, /* domainSetSchedulerParameters */
- NULL, /* domainMigratePrepare */
- NULL, /* domainMigratePerform */
- NULL, /* domainMigrateFinish */
- NULL, /* domainBlockStats */
- NULL, /* domainInterfaceStats */
- NULL, /* domainMemoryStats */
- NULL, /* domainBlockPeek */
- NULL, /* domainMemoryPeek */
- NULL, /* domainGetBlockInfo */
- NULL, /* nodeGetCellsFreeMemory */
- NULL, /* getFreeMemory */
- NULL, /* domainEventRegister */
- NULL, /* domainEventDeregister */
- NULL, /* domainMigratePrepare2 */
- NULL, /* domainMigrateFinish2 */
- NULL, /* nodeDeviceDettach */
- NULL, /* nodeDeviceReAttach */
- NULL, /* nodeDeviceReset */
- NULL, /* domainMigratePrepareTunnel */
- phypIsEncrypted, /* isEncrypted */
- phypIsSecure, /* isSecure */
- NULL, /* domainIsActive */
- NULL, /* domainIsPersistent */
- NULL, /* cpuCompare */
- NULL, /* cpuBaseline */
- NULL, /* domainGetJobInfo */
- NULL, /* domainAbortJob */
- NULL, /* domainMigrateSetMaxDowntime */
- NULL, /* domainEventRegisterAny */
- NULL, /* domainEventDeregisterAny */
- NULL, /* domainManagedSave */
- NULL, /* domainHasManagedSaveImage */
- NULL, /* domainManagedSaveRemove */
- NULL, /* domainSnapshotCreateXML */
- NULL, /* domainSnapshotDumpXML */
- NULL, /* domainSnapshotNum */
- NULL, /* domainSnapshotListNames */
- NULL, /* domainSnapshotLookupByName */
- NULL, /* domainHasCurrentSnapshot */
- NULL, /* domainSnapshotCurrent */
- NULL, /* domainRevertToSnapshot */
- NULL, /* domainSnapshotDelete */
-};
+static int
+phypGetLparCPUMAX(virDomainPtr dom)
+{
+ phyp_driverPtr phyp_driver = dom->conn->privateData;
+ char *managed_system = phyp_driver->managed_system;
-int
-phypBuildLpar(virConnectPtr conn, virDomainDefPtr def)
+ return phypGetLparCPUGeneric(dom->conn, managed_system, dom->id, 1);
+}
+
+static int
+phypGetRemoteSlot(virConnectPtr conn, const char *managed_system,
+ const char *lpar_name)
{
ConnectionData *connection_data = conn->networkPrivateData;
- phyp_driverPtr phyp_driver = conn->privateData;
LIBSSH2_SESSION *session = connection_data->session;
+ phyp_driverPtr phyp_driver = conn->privateData;
int system_type = phyp_driver->system_type;
- char *managed_system = phyp_driver->managed_system;
char *cmd = NULL;
char *ret = NULL;
+ char *char_ptr;
+ int remote_slot = 0;
int exit_status = 0;
virBuffer buf = VIR_BUFFER_INITIALIZER;
- virBufferAddLit(&buf, "mksyscfg");
+ virBufferAddLit(&buf, "lshwres");
if (system_type == HMC)
virBufferVSprintf(&buf, " -m %s", managed_system);
- virBufferVSprintf(&buf, " -r lpar -p %s -i min_mem=%d,desired_mem=%d,"
- "max_mem=%d,desired_procs=%d,virtual_scsi_adapters=%s",
- def->name, (int) def->memory, (int) def->memory,
- (int) def->maxmem, (int) def->vcpus, def->disks[0]->src);
+ virBufferVSprintf(&buf, " -r virtualio --rsubtype scsi -F "
+ "remote_slot_num --filter lpar_names=%s", lpar_name);
if (virBufferError(&buf)) {
virBufferFreeAndReset(&buf);
virReportOOMError();
ret = phypExec(session, cmd, &exit_status, conn);
- if (exit_status < 0) {
- VIR_ERROR(_("Unable to create LPAR. Reason: '%s'"), ret);
+ if (exit_status < 0 || ret == NULL)
goto err;
- }
- if (phypUUIDTable_AddLpar(conn, def->uuid, def->id) == -1) {
- VIR_ERROR0(_("Unable to add LPAR to the table"));
+ char_ptr = strchr(ret, '\n');
+
+ if (char_ptr)
+ *char_ptr = '\0';
+
+ if (virStrToLong_i(ret, &char_ptr, 10, &remote_slot) == -1)
goto err;
- }
VIR_FREE(cmd);
VIR_FREE(ret);
- return 0;
+ return remote_slot;
err:
VIR_FREE(cmd);
return -1;
}
-int
-phypUUIDTable_RemLpar(virConnectPtr conn, int id)
+/* XXX - is this needed? */
+static char *phypGetBackingDevice(virConnectPtr, const char *, char *)
+ ATTRIBUTE_UNUSED;
+static char *
+phypGetBackingDevice(virConnectPtr conn, const char *managed_system,
+ char *lpar_name)
{
+ ConnectionData *connection_data = conn->networkPrivateData;
+ LIBSSH2_SESSION *session = connection_data->session;
phyp_driverPtr phyp_driver = conn->privateData;
- uuid_tablePtr uuid_table = phyp_driver->uuid_table;
- unsigned int i = 0;
+ int system_type = phyp_driver->system_type;
+ char *cmd = NULL;
+ char *ret = NULL;
+ int remote_slot = 0;
+ int exit_status = 0;
+ char *char_ptr;
+ char *backing_device = NULL;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
- for (i = 0; i <= uuid_table->nlpars; i++) {
- if (uuid_table->lpars[i]->id == id) {
- uuid_table->lpars[i]->id = -1;
- memset(uuid_table->lpars[i]->uuid, 0, VIR_UUID_BUFLEN);
- }
+ if ((remote_slot =
+ phypGetRemoteSlot(conn, managed_system, lpar_name)) == -1)
+ return NULL;
+
+ virBufferAddLit(&buf, "lshwres");
+ if (system_type == HMC)
+ virBufferVSprintf(&buf, " -m %s", managed_system);
+ virBufferVSprintf(&buf, " -r virtualio --rsubtype scsi -F "
+ "backing_devices --filter slots=%d", remote_slot);
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ virReportOOMError();
+ return NULL;
}
+ cmd = virBufferContentAndReset(&buf);
- if (phypUUIDTable_WriteFile(conn) == -1)
- goto err;
+ ret = phypExec(session, cmd, &exit_status, conn);
- if (phypUUIDTable_Push(conn) == -1)
+ if (exit_status < 0 || ret == NULL)
goto err;
- return 0;
+ /* here is a little trick to deal returns of this kind:
+ *
+ * 0x8100000000000000//lv01
+ *
+ * the information we really need is only lv01, so we
+ * need to skip a lot of things on the string.
+ * */
+ char_ptr = strchr(ret, '/');
+
+ if (char_ptr) {
+ char_ptr++;
+ if (char_ptr[0] == '/')
+ char_ptr++;
+ else
+ goto err;
+
+ backing_device = strdup(char_ptr);
+
+ if (backing_device == NULL) {
+ virReportOOMError();
+ goto err;
+ }
+ } else {
+ backing_device = ret;
+ ret = NULL;
+ }
+
+ char_ptr = strchr(backing_device, '\n');
+
+ if (char_ptr)
+ *char_ptr = '\0';
+
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
+ return backing_device;
err:
- return -1;
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
+ return NULL;
+
}
-int
-phypUUIDTable_AddLpar(virConnectPtr conn, unsigned char *uuid, int id)
+static int
+phypGetLparState(virConnectPtr conn, unsigned int lpar_id)
{
+ ConnectionData *connection_data = conn->networkPrivateData;
phyp_driverPtr phyp_driver = conn->privateData;
- uuid_tablePtr uuid_table = phyp_driver->uuid_table;
-
- uuid_table->nlpars++;
- unsigned int i = uuid_table->nlpars;
- i--;
+ LIBSSH2_SESSION *session = connection_data->session;
+ int system_type = phyp_driver->system_type;
+ char *cmd = NULL;
+ char *ret = NULL;
+ int exit_status = 0;
+ char *char_ptr = NULL;
+ char *managed_system = phyp_driver->managed_system;
+ int state = VIR_DOMAIN_NOSTATE;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
- if (VIR_REALLOC_N(uuid_table->lpars, uuid_table->nlpars) < 0) {
+ virBufferAddLit(&buf, "lssyscfg -r lpar");
+ if (system_type == HMC)
+ virBufferVSprintf(&buf, " -m %s", managed_system);
+ virBufferVSprintf(&buf, " -F state --filter lpar_ids=%d", lpar_id);
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
virReportOOMError();
- goto err;
+ return state;
}
+ cmd = virBufferContentAndReset(&buf);
- if (VIR_ALLOC(uuid_table->lpars[i]) < 0) {
- virReportOOMError();
- goto err;
- }
+ ret = phypExec(session, cmd, &exit_status, conn);
- uuid_table->lpars[i]->id = id;
- memmove(uuid_table->lpars[i]->uuid, uuid, VIR_UUID_BUFLEN);
+ if (exit_status < 0 || ret == NULL)
+ goto cleanup;
- if (phypUUIDTable_WriteFile(conn) == -1)
- goto err;
+ char_ptr = strchr(ret, '\n');
- if (phypUUIDTable_Push(conn) == -1)
- goto err;
+ if (char_ptr)
+ *char_ptr = '\0';
- return 0;
+ if (STREQ(ret, "Running"))
+ state = VIR_DOMAIN_RUNNING;
+ else if (STREQ(ret, "Not Activated"))
+ state = VIR_DOMAIN_SHUTOFF;
+ else if (STREQ(ret, "Shutting Down"))
+ state = VIR_DOMAIN_SHUTDOWN;
- err:
- return -1;
+ cleanup:
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
+ return state;
}
-int
-phypUUIDTable_ReadFile(virConnectPtr conn)
+/* XXX - is this needed? */
+static int phypDiskType(virConnectPtr, char *) ATTRIBUTE_UNUSED;
+static int
+phypDiskType(virConnectPtr conn, char *backing_device)
{
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;
- int id;
-
- if ((fd = open(local_file, O_RDONLY)) == -1) {
- VIR_WARN0("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, &id, sizeof(int));
- if (rc == sizeof(int)) {
- if (VIR_ALLOC(uuid_table->lpars[i]) < 0) {
- virReportOOMError();
- goto err;
- }
- uuid_table->lpars[i]->id = id;
- } else {
- VIR_WARN0
- ("Unable to read from information to local file.");
- goto err;
- }
+ ConnectionData *connection_data = conn->networkPrivateData;
+ LIBSSH2_SESSION *session = connection_data->session;
+ int system_type = phyp_driver->system_type;
+ char *cmd = NULL;
+ char *ret = NULL;
+ int exit_status = 0;
+ char *char_ptr;
+ char *managed_system = phyp_driver->managed_system;
+ int vios_id = phyp_driver->vios_id;
+ int disk_type = -1;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
- rc = read(fd, uuid_table->lpars[i]->uuid, VIR_UUID_BUFLEN);
- if (rc != VIR_UUID_BUFLEN) {
- VIR_WARN0("Unable to read information to local file.");
- goto err;
- }
- }
- } else
+ virBufferAddLit(&buf, "viosvrcmd");
+ if (system_type == HMC)
+ virBufferVSprintf(&buf, " -m %s", managed_system);
+ virBufferVSprintf(&buf, " -p %d -c \"lssp -field name type "
+ "-fmt , -all|grep %s|sed -e 's/^.*,//'\"",
+ vios_id, backing_device);
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
virReportOOMError();
+ return disk_type;
+ }
+ cmd = virBufferContentAndReset(&buf);
- close(fd);
- return 0;
+ ret = phypExec(session, cmd, &exit_status, conn);
- err:
- close(fd);
- return -1;
-}
+ if (exit_status < 0 || ret == NULL)
+ goto cleanup;
-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";
+ char_ptr = strchr(ret, '\n');
- if ((fd = creat(local_file, 0755)) == -1)
- goto err;
+ if (char_ptr)
+ *char_ptr = '\0';
- 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_ERROR0(_("Unable to write information to local file."));
- goto err;
- }
+ if (STREQ(ret, "LVPOOL"))
+ disk_type = VIR_DOMAIN_DISK_TYPE_BLOCK;
+ else if (STREQ(ret, "FBPOOL"))
+ disk_type = VIR_DOMAIN_DISK_TYPE_FILE;
- if (safewrite(fd, uuid_table->lpars[i]->uuid, VIR_UUID_BUFLEN) !=
- VIR_UUID_BUFLEN) {
- VIR_ERROR0(_("Unable to write information to local file."));
- goto err;
- }
- }
+ cleanup:
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
+ return disk_type;
+}
- close(fd);
- return 0;
+static int
+phypNumDefinedDomains(virConnectPtr conn)
+{
+ return phypNumDomainsGeneric(conn, 1);
+}
- err:
- close(fd);
- return -1;
+static int
+phypNumDomains(virConnectPtr conn)
+{
+ return phypNumDomainsGeneric(conn, 0);
}
-int
-phypUUIDTable_Init(virConnectPtr conn)
+static int
+phypListDomains(virConnectPtr conn, int *ids, int nids)
{
- uuid_tablePtr uuid_table;
- phyp_driverPtr phyp_driver;
- int nids_numdomains = 0;
- int nids_listdomains = 0;
- int *ids = NULL;
- unsigned int i = 0;
+ return phypListDomainsGeneric(conn, ids, nids, 0);
+}
- if ((nids_numdomains = phypNumDomainsGeneric(conn, 2)) < 0)
- goto err;
+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;
+ int system_type = phyp_driver->system_type;
+ char *managed_system = phyp_driver->managed_system;
+ int exit_status = 0;
+ int got = 0;
+ int i;
+ char *cmd = NULL;
+ char *ret = NULL;
+ char *domains = NULL;
+ char *char_ptr2 = NULL;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
- if (VIR_ALLOC_N(ids, nids_numdomains) < 0) {
+ virBufferAddLit(&buf, "lssyscfg -r lpar");
+ if (system_type == HMC)
+ virBufferVSprintf(&buf, " -m %s", managed_system);
+ virBufferVSprintf(&buf, " -F name,state | grep \"Not Activated\" | "
+ "sed -e 's/,.*$//'");
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
virReportOOMError();
- goto err;
+ return -1;
}
+ cmd = virBufferContentAndReset(&buf);
- if ((nids_listdomains =
- phypListDomainsGeneric(conn, ids, nids_numdomains, 1)) < 0)
- goto err;
+ ret = phypExec(session, cmd, &exit_status, conn);
- /* exit early if there are no domains */
- if (nids_numdomains == 0 && nids_listdomains == 0)
- goto exit;
- else if (nids_numdomains != nids_listdomains) {
- VIR_ERROR0(_("Unable to determine number of domains."));
+ /* I need to parse the textual return in order to get the domains */
+ if (exit_status < 0 || ret == NULL)
goto err;
- }
+ else {
+ domains = ret;
- phyp_driver = conn->privateData;
- uuid_table = phyp_driver->uuid_table;
- uuid_table->nlpars = nids_listdomains;
+ while (got < nnames) {
+ char_ptr2 = strchr(domains, '\n');
- /* 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) {
+ if (char_ptr2) {
+ *char_ptr2 = '\0';
+ if ((names[got++] = strdup(domains)) == NULL) {
virReportOOMError();
goto err;
}
- uuid_table->lpars[i]->id = ids[i];
-
- if (virUUIDGenerate(uuid_table->lpars[i]->uuid) < 0)
- VIR_WARN("Unable to generate UUID for domain %d",
- ids[i]);
- }
- } else {
- virReportOOMError();
- goto err;
+ char_ptr2++;
+ domains = char_ptr2;
+ } else
+ break;
}
-
- 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;
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
+ return got;
err:
- VIR_FREE(ids);
+ for (i = 0; i < got; i++)
+ VIR_FREE(names[i]);
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
return -1;
}
-void
-phypUUIDTable_Free(uuid_tablePtr uuid_table)
+static virDomainPtr
+phypDomainLookupByName(virConnectPtr conn, const char *lpar_name)
{
- int i;
+ 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 = phyp_driver->managed_system;
+ unsigned char lpar_uuid[VIR_UUID_BUFLEN];
- if (uuid_table == NULL)
- return;
+ lpar_id = phypGetLparID(session, managed_system, lpar_name, conn);
+ if (lpar_id == -1)
+ return NULL;
- for (i = 0; i < uuid_table->nlpars; i++)
- VIR_FREE(uuid_table->lpars[i]);
+ if (phypGetLparUUID(lpar_uuid, lpar_id, conn) == -1)
+ return NULL;
- VIR_FREE(uuid_table->lpars);
- VIR_FREE(uuid_table);
+ dom = virGetDomain(conn, lpar_name, lpar_uuid);
+
+ if (dom)
+ dom->id = lpar_id;
+
+ return dom;
}
-int
-phypUUIDTable_Push(virConnectPtr conn)
+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;
- LIBSSH2_CHANNEL *channel = NULL;
- virBuffer username = VIR_BUFFER_INITIALIZER;
- struct stat local_fileinfo;
- char buffer[1024];
- int rc = 0;
- FILE *fd;
- size_t nread, sent;
- char *ptr;
- char local_file[] = "./uuid_table";
- char *remote_file = NULL;
+ virDomainPtr dom = NULL;
+ char *managed_system = phyp_driver->managed_system;
+ int exit_status = 0;
+ unsigned char lpar_uuid[VIR_UUID_BUFLEN];
- if (conn->uri->user != NULL) {
- virBufferVSprintf(&username, "%s", conn->uri->user);
-
- if (virBufferError(&username)) {
- virBufferFreeAndReset(&username);
- virReportOOMError();
- goto err;
- }
- }
-
- if (virAsprintf
- (&remote_file, "/home/%s/libvirt_uuid_table",
- virBufferContentAndReset(&username))
- < 0) {
- virReportOOMError();
- goto err;
- }
+ char *lpar_name = phypGetLparNAME(session, managed_system, lpar_id,
+ conn);
- if (stat(local_file, &local_fileinfo) == -1) {
- VIR_WARN0("Unable to stat local file.");
+ if (phypGetLparUUID(lpar_uuid, lpar_id, conn) == -1)
goto err;
- }
- if (!(fd = fopen(local_file, "rb"))) {
- VIR_WARN0("Unable to open local file.");
+ if (exit_status < 0)
goto err;
- }
-
- do {
- channel =
- libssh2_scp_send(session, remote_file,
- 0x1FF & local_fileinfo.st_mode,
- (unsigned long) local_fileinfo.st_size);
-
- 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) {
- if (feof(fd)) {
- /* end of file */
- break;
- } else {
- VIR_ERROR(_("Failed to read from %s"), local_file);
- goto err;
- }
- }
- ptr = buffer;
- sent = 0;
+ dom = virGetDomain(conn, lpar_name, lpar_uuid);
- 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 if (rc > 0) {
- /* rc indicates how many bytes were written this time */
- sent += rc;
- }
- ptr += sent;
- nread -= sent;
- } while (rc > 0 && sent < nread);
- } while (1);
+ if (dom)
+ dom->id = lpar_id;
- if (channel) {
- libssh2_channel_send_eof(channel);
- libssh2_channel_wait_eof(channel);
- libssh2_channel_wait_closed(channel);
- libssh2_channel_free(channel);
- channel = NULL;
- }
- virBufferFreeAndReset(&username);
- return 0;
+ VIR_FREE(lpar_name);
+ return dom;
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;
+ VIR_FREE(lpar_name);
+ return NULL;
}
-int
-phypUUIDTable_Pull(virConnectPtr conn)
+static char *
+phypDomainDumpXML(virDomainPtr dom, int flags)
{
- ConnectionData *connection_data = conn->networkPrivateData;
+ ConnectionData *connection_data = dom->conn->networkPrivateData;
+ phyp_driverPtr phyp_driver = dom->conn->privateData;
LIBSSH2_SESSION *session = connection_data->session;
- LIBSSH2_CHANNEL *channel = NULL;
- virBuffer username = VIR_BUFFER_INITIALIZER;
- struct stat fileinfo;
- char buffer[1024];
- int rc = 0;
- int fd;
- int got = 0;
- int amount = 0;
- int total = 0;
- int sock = 0;
- char local_file[] = "./uuid_table";
- char *remote_file = NULL;
+ virDomainDef def;
+ char *managed_system = phyp_driver->managed_system;
- if (conn->uri->user != NULL) {
- virBufferVSprintf(&username, "%s", conn->uri->user);
+ memset(&def, 0, sizeof(virDomainDef));
- if (virBufferError(&username)) {
- virBufferFreeAndReset(&username);
- virReportOOMError();
- goto err;
- }
+ def.virtType = VIR_DOMAIN_VIRT_PHYP;
+ def.id = dom->id;
+
+ char *lpar_name = phypGetLparNAME(session, managed_system, def.id,
+ dom->conn);
+
+ if (lpar_name == NULL) {
+ VIR_ERROR0(_("Unable to determine domain's name."));
+ goto err;
}
- if (virAsprintf
- (&remote_file, "/home/%s/libvirt_uuid_table",
- virBufferContentAndReset(&username))
- < 0) {
- virReportOOMError();
+ if (phypGetLparUUID(def.uuid, dom->id, dom->conn) == -1) {
+ VIR_ERROR0(_("Unable to generate random uuid."));
goto err;
}
- /* Trying to stat the remote file. */
- do {
- channel = libssh2_scp_recv(session, remote_file, &fileinfo);
+ if ((def.maxmem =
+ phypGetLparMem(dom->conn, managed_system, dom->id, 0)) == 0) {
+ VIR_ERROR0(_("Unable to determine domain's max memory."));
+ goto err;
+ }
- if (!channel) {
- if (libssh2_session_last_errno(session) !=
- LIBSSH2_ERROR_EAGAIN) {
- goto err;;
- } else {
- waitsocket(sock, session);
- }
- }
- } while (!channel);
+ if ((def.memory =
+ phypGetLparMem(dom->conn, managed_system, dom->id, 1)) == 0) {
+ VIR_ERROR0(_("Unable to determine domain's memory."));
+ goto err;
+ }
- /* Creating a new data base based on remote file */
- if ((fd = creat(local_file, 0755)) == -1)
+ if ((def.vcpus =
+ phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0) {
+ VIR_ERROR0(_("Unable to determine domain's CPU."));
goto err;
+ }
- /* Request a file via SCP */
- while (got < fileinfo.st_size) {
- do {
- amount = sizeof(buffer);
+ return virDomainDefFormat(&def, flags);
- if ((fileinfo.st_size - got) < amount) {
- amount = fileinfo.st_size - got;
- }
+ err:
+ return NULL;
+}
- rc = libssh2_channel_read(channel, buffer, amount);
- if (rc > 0) {
- if (safewrite(fd, buffer, rc) != rc)
- VIR_WARN0
- ("Unable to write information to local file.");
+static int
+phypDomainResume(virDomainPtr dom)
+{
+ ConnectionData *connection_data = dom->conn->networkPrivateData;
+ phyp_driverPtr phyp_driver = dom->conn->privateData;
+ LIBSSH2_SESSION *session = connection_data->session;
+ int system_type = phyp_driver->system_type;
+ char *managed_system = phyp_driver->managed_system;
+ int exit_status = 0;
+ char *cmd = NULL;
+ char *ret = NULL;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
- got += rc;
- total += rc;
- }
- } while (rc > 0);
+ virBufferAddLit(&buf, "chsysstate");
+ if (system_type == HMC)
+ virBufferVSprintf(&buf, " -m %s", managed_system);
+ virBufferVSprintf(&buf, " -r lpar -o on --id %d -f %s",
+ dom->id, dom->name);
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ virReportOOMError();
+ return -1;
+ }
+ cmd = virBufferContentAndReset(&buf);
- if ((rc == LIBSSH2_ERROR_EAGAIN)
- && (got < fileinfo.st_size)) {
- /* this is due to blocking that would occur otherwise
- * so we loop on this condition */
+ ret = phypExec(session, cmd, &exit_status, dom->conn);
- waitsocket(sock, session); /* now we wait */
- continue;
- }
- break;
- }
- close(fd);
- goto exit;
+ if (exit_status < 0)
+ goto err;
- exit:
- if (channel) {
- libssh2_channel_send_eof(channel);
- libssh2_channel_wait_eof(channel);
- libssh2_channel_wait_closed(channel);
- libssh2_channel_free(channel);
- channel = NULL;
- }
- virBufferFreeAndReset(&username);
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
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;
- }
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
return -1;
}
-int
-escape_specialcharacters(char *src, char *dst, size_t dstlen)
+static int
+phypDomainShutdown(virDomainPtr dom)
{
- size_t len = strlen(src);
- char temp_buffer[len];
- unsigned int i = 0, j = 0;
- if (len == 0)
- return -1;
-
- 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 '\t':
- continue;
- default:
- temp_buffer[j] = src[i];
- j++;
- }
+ ConnectionData *connection_data = dom->conn->networkPrivateData;
+ virConnectPtr conn = dom->conn;
+ LIBSSH2_SESSION *session = connection_data->session;
+ phyp_driverPtr phyp_driver = conn->privateData;
+ int system_type = phyp_driver->system_type;
+ char *managed_system = phyp_driver->managed_system;
+ int exit_status = 0;
+ char *cmd = NULL;
+ char *ret = NULL;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+ virBufferAddLit(&buf, "chsysstate");
+ if (system_type == HMC)
+ virBufferVSprintf(&buf, " -m %s", managed_system);
+ virBufferVSprintf(&buf, " -r lpar -o shutdown --id %d", dom->id);
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ virReportOOMError();
+ return 0;
}
- temp_buffer[j] = '\0';
+ cmd = virBufferContentAndReset(&buf);
- if (virStrcpy(dst, temp_buffer, dstlen) == NULL)
+ ret = phypExec(session, cmd, &exit_status, dom->conn);
+
+ 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)
+{
+ phyp_driverPtr phyp_driver = dom->conn->privateData;
+ char *managed_system = phyp_driver->managed_system;
+
+ info->state = phypGetLparState(dom->conn, dom->id);
+
+ if ((info->maxMem =
+ phypGetLparMem(dom->conn, managed_system, dom->id, 0)) == 0)
+ VIR_WARN0("Unable to determine domain's max memory.");
+
+ if ((info->memory =
+ phypGetLparMem(dom->conn, managed_system, dom->id, 1)) == 0)
+ VIR_WARN0("Unable to determine domain's memory.");
+
+ if ((info->nrVirtCpu =
+ phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0)
+ VIR_WARN0("Unable to determine domain's CPU.");
+
+ return 0;
+}
+
+static int
+phypDomainDestroy(virDomainPtr dom)
+{
+ ConnectionData *connection_data = dom->conn->networkPrivateData;
+ phyp_driverPtr phyp_driver = dom->conn->privateData;
+ LIBSSH2_SESSION *session = connection_data->session;
+ int system_type = phyp_driver->system_type;
+ char *managed_system = phyp_driver->managed_system;
+ int exit_status = 0;
+ char *cmd = NULL;
+ char *ret = NULL;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+ virBufferAddLit(&buf, "rmsyscfg");
+ if (system_type == HMC)
+ virBufferVSprintf(&buf, " -m %s", managed_system);
+ virBufferVSprintf(&buf, " -r lpar --id %d", dom->id);
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ virReportOOMError();
return -1;
+ }
+ cmd = virBufferContentAndReset(&buf);
+
+ 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;
+
}
-int
-waitsocket(int socket_fd, LIBSSH2_SESSION * session)
+static int
+phypBuildLpar(virConnectPtr conn, virDomainDefPtr def)
{
- struct timeval timeout;
- int rc;
- fd_set fd;
- fd_set *writefd = NULL;
- fd_set *readfd = NULL;
- int dir;
+ ConnectionData *connection_data = conn->networkPrivateData;
+ phyp_driverPtr phyp_driver = conn->privateData;
+ LIBSSH2_SESSION *session = connection_data->session;
+ int system_type = phyp_driver->system_type;
+ char *managed_system = phyp_driver->managed_system;
+ char *cmd = NULL;
+ char *ret = NULL;
+ int exit_status = 0;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
- timeout.tv_sec = 0;
- timeout.tv_usec = 1000;
+ virBufferAddLit(&buf, "mksyscfg");
+ if (system_type == HMC)
+ virBufferVSprintf(&buf, " -m %s", managed_system);
+ virBufferVSprintf(&buf, " -r lpar -p %s -i min_mem=%d,desired_mem=%d,"
+ "max_mem=%d,desired_procs=%d,virtual_scsi_adapters=%s",
+ def->name, (int) def->memory, (int) def->memory,
+ (int) def->maxmem, (int) def->vcpus, def->disks[0]->src);
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ virReportOOMError();
+ return -1;
+ }
+ cmd = virBufferContentAndReset(&buf);
- FD_ZERO(&fd);
+ ret = phypExec(session, cmd, &exit_status, conn);
- FD_SET(socket_fd, &fd);
+ if (exit_status < 0) {
+ VIR_ERROR(_("Unable to create LPAR. Reason: '%s'"), ret);
+ goto err;
+ }
- /* now make sure we wait in the correct direction */
- dir = libssh2_session_block_directions(session);
+ if (phypUUIDTable_AddLpar(conn, def->uuid, def->id) == -1) {
+ VIR_ERROR0(_("Unable to add LPAR to the table"));
+ goto err;
+ }
- if (dir & LIBSSH2_SESSION_BLOCK_INBOUND)
- readfd = &fd;
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
+ return 0;
- if (dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
- writefd = &fd;
+ err:
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
+ return -1;
+}
- rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);
+static virDomainPtr
+phypDomainCreateAndStart(virConnectPtr conn,
+ const char *xml, unsigned int flags)
+{
+
+ 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;
+
+ virCheckFlags(0, NULL);
+
+ if (!(def = virDomainDefParseString(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_WARN0("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_WARN0("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);
+ if (dom)
+ virUnrefDomain(dom);
+ return NULL;
+}
+
+static char *
+phypConnectGetCapabilities(virConnectPtr conn)
+{
+ phyp_driverPtr phyp_driver = conn->privateData;
+ char *xml;
+
+ if ((xml = virCapabilitiesFormatXML(phyp_driver->caps)) == NULL)
+ virReportOOMError();
+
+ return xml;
+}
+
+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;
+ int system_type = phyp_driver->system_type;
+ char *managed_system = phyp_driver->managed_system;
+ int exit_status = 0;
+ char *cmd = NULL;
+ char *ret = NULL;
+ char operation;
+ unsigned long ncpus = 0;
+ unsigned int amount = 0;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+ if ((ncpus = phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0)
+ return 0;
+
+ if (nvcpus > phypGetLparCPUMAX(dom)) {
+ VIR_ERROR0(_("You are trying to set a number of CPUs bigger than "
+ "the max possible."));
+ return 0;
+ }
+
+ if (ncpus > nvcpus) {
+ operation = 'r';
+ amount = nvcpus - ncpus;
+ } else if (ncpus < nvcpus) {
+ operation = 'a';
+ amount = nvcpus - ncpus;
+ } else
+ return 0;
+
+ virBufferAddLit(&buf, "chhwres -r proc");
+ if (system_type == HMC)
+ virBufferVSprintf(&buf, " -m %s", managed_system);
+ virBufferVSprintf(&buf, " --id %d -o %c --procunits %d 2>&1 |sed "
+ "-e 's/^.*\\([0-9][0-9]*.[0-9][0-9]*\\).*$/\\1/'",
+ dom->id, operation, amount);
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ virReportOOMError();
+ return 0;
+ }
+ cmd = virBufferContentAndReset(&buf);
+
+ ret = phypExec(session, cmd, &exit_status, dom->conn);
+
+ if (exit_status < 0) {
+ VIR_ERROR0(_
+ ("Possibly you don't have IBM Tools installed in your LPAR."
+ " Contact your support to enable this feature."));
+ }
+
+ VIR_FREE(cmd);
+ VIR_FREE(ret);
+ return 0;
- return rc;
}
+static virDriver phypDriver = {
+ VIR_DRV_PHYP, "PHYP", phypOpen, /* open */
+ phypClose, /* close */
+ NULL, /* supports_feature */
+ NULL, /* type */
+ NULL, /* version */
+ NULL, /* libvirtVersion (impl. in libvirt.c) */
+ 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 */
+ phypDomainSetCPU, /* domainSetVcpus */
+ NULL, /* domainPinVcpu */
+ NULL, /* domainGetVcpus */
+ phypGetLparCPUMAX, /* domainGetMaxVcpus */
+ NULL, /* domainGetSecurityLabel */
+ NULL, /* nodeGetSecurityModel */
+ phypDomainDumpXML, /* domainDumpXML */
+ NULL, /* domainXMLFromNative */
+ NULL, /* domainXMLToNative */
+ phypListDefinedDomains, /* listDefinedDomains */
+ phypNumDefinedDomains, /* numOfDefinedDomains */
+ NULL, /* domainCreate */
+ NULL, /* domainCreateWithFlags */
+ NULL, /* domainDefineXML */
+ NULL, /* domainUndefine */
+ NULL, /* domainAttachDevice */
+ NULL, /* domainAttachDeviceFlags */
+ NULL, /* domainDetachDevice */
+ NULL, /* domainDetachDeviceFlags */
+ NULL, /* domainUpdateDeviceFlags */
+ NULL, /* domainGetAutostart */
+ NULL, /* domainSetAutostart */
+ NULL, /* domainGetSchedulerType */
+ NULL, /* domainGetSchedulerParameters */
+ NULL, /* domainSetSchedulerParameters */
+ NULL, /* domainMigratePrepare */
+ NULL, /* domainMigratePerform */
+ NULL, /* domainMigrateFinish */
+ NULL, /* domainBlockStats */
+ NULL, /* domainInterfaceStats */
+ NULL, /* domainMemoryStats */
+ NULL, /* domainBlockPeek */
+ NULL, /* domainMemoryPeek */
+ NULL, /* domainGetBlockInfo */
+ NULL, /* nodeGetCellsFreeMemory */
+ NULL, /* getFreeMemory */
+ NULL, /* domainEventRegister */
+ NULL, /* domainEventDeregister */
+ NULL, /* domainMigratePrepare2 */
+ NULL, /* domainMigrateFinish2 */
+ NULL, /* nodeDeviceDettach */
+ NULL, /* nodeDeviceReAttach */
+ NULL, /* nodeDeviceReset */
+ NULL, /* domainMigratePrepareTunnel */
+ phypIsEncrypted, /* isEncrypted */
+ phypIsSecure, /* isSecure */
+ NULL, /* domainIsActive */
+ NULL, /* domainIsPersistent */
+ NULL, /* cpuCompare */
+ NULL, /* cpuBaseline */
+ NULL, /* domainGetJobInfo */
+ NULL, /* domainAbortJob */
+ NULL, /* domainMigrateSetMaxDowntime */
+ NULL, /* domainEventRegisterAny */
+ NULL, /* domainEventDeregisterAny */
+ NULL, /* domainManagedSave */
+ NULL, /* domainHasManagedSaveImage */
+ NULL, /* domainManagedSaveRemove */
+ NULL, /* domainSnapshotCreateXML */
+ NULL, /* domainSnapshotDumpXML */
+ NULL, /* domainSnapshotNum */
+ NULL, /* domainSnapshotListNames */
+ NULL, /* domainSnapshotLookupByName */
+ NULL, /* domainHasCurrentSnapshot */
+ NULL, /* domainSnapshotCurrent */
+ NULL, /* domainRevertToSnapshot */
+ NULL, /* domainSnapshotDelete */
+};
+
int
phypRegister(void)
{