diff --git a/configure.ac b/configure.ac index 6c7c186d18..002a3dcdb0 100644 --- a/configure.ac +++ b/configure.ac @@ -456,7 +456,6 @@ dnl LIBVIRT_DRIVER_ARG_QEMU LIBVIRT_DRIVER_ARG_OPENVZ LIBVIRT_DRIVER_ARG_VMWARE -LIBVIRT_DRIVER_ARG_PHYP LIBVIRT_DRIVER_ARG_LIBXL LIBVIRT_DRIVER_ARG_VBOX LIBVIRT_DRIVER_ARG_LXC @@ -473,7 +472,6 @@ LIBVIRT_DRIVER_ARG_INTERFACE LIBVIRT_DRIVER_CHECK_QEMU LIBVIRT_DRIVER_CHECK_OPENVZ LIBVIRT_DRIVER_CHECK_VMWARE -LIBVIRT_DRIVER_CHECK_PHYP LIBVIRT_DRIVER_CHECK_LIBXL LIBVIRT_DRIVER_CHECK_VBOX LIBVIRT_DRIVER_CHECK_LXC @@ -953,7 +951,6 @@ LIBVIRT_DRIVER_RESULT_VMWARE LIBVIRT_DRIVER_RESULT_VBOX LIBVIRT_DRIVER_RESULT_LIBXL LIBVIRT_DRIVER_RESULT_LXC -LIBVIRT_DRIVER_RESULT_PHYP LIBVIRT_DRIVER_RESULT_ESX LIBVIRT_DRIVER_RESULT_HYPERV LIBVIRT_DRIVER_RESULT_VZ diff --git a/docs/aclpolkit.html.in b/docs/aclpolkit.html.in index 4a8877d5e7..04cb39006a 100644 --- a/docs/aclpolkit.html.in +++ b/docs/aclpolkit.html.in @@ -365,10 +365,6 @@ openvz OPENVZ - - phyp - PHYP - qemu QEMU diff --git a/docs/api.html.in b/docs/api.html.in index 288b9ecf88..85b196417a 100644 --- a/docs/api.html.in +++ b/docs/api.html.in @@ -330,7 +330,7 @@ daemon through the remote driver via an RPC. Some hypervisors do support client-side connections and responses, such as Test, OpenVZ, VMware, - Power VM (phyp), VirtualBox (vbox), ESX, Hyper-V, Xen, and Virtuozzo. + VirtualBox (vbox), ESX, Hyper-V, Xen, and Virtuozzo. The libvirtd daemon service is started on the host at system boot time and can also be restarted at any time by a properly privileged user, such as root. The libvirtd daemon uses the same libvirt API diff --git a/docs/auth.html.in b/docs/auth.html.in index 62af43a915..f198f39b64 100644 --- a/docs/auth.html.in +++ b/docs/auth.html.in @@ -129,7 +129,7 @@ credentials=defgrp
  • libvirt - used for connections to a libvirtd server, which is configured with SASL auth
  • ssh - used for connections to a Phyp server - over SSH
  • + over SSH, but the Phyp driver has been removed
  • esx - used for connections to an ESX or VirtualCenter server
  • diff --git a/docs/drivers.html.in b/docs/drivers.html.in index 4539eedbcd..8743301ebd 100644 --- a/docs/drivers.html.in +++ b/docs/drivers.html.in @@ -34,7 +34,6 @@
  • VMware Workstation/Player
  • Xen
  • Microsoft Hyper-V
  • -
  • IBM PowerVM (phyp)
  • Virtuozzo
  • Bhyve - The BSD Hypervisor
  • diff --git a/docs/drvphyp.html.in b/docs/drvphyp.html.in deleted file mode 100644 index 8e0b43c869..0000000000 --- a/docs/drvphyp.html.in +++ /dev/null @@ -1,50 +0,0 @@ - - - - -

    IBM PowerVM hypervisor driver (phyp)

    - -

    - The IBM PowerVM driver can manage both HMC and IVM PowerVM - guests. VIOS connections are tunneled through HMC. -

    - - -

    Project Links

    - - - -

    Connections to the PowerVM driver

    -

    - Some example remote connection URIs for the driver are: -

    -
    -phyp://user@hmc/system (HMC connection)
    -phyp://user@ivm/system (IVM connection)
    -
    -

    - Note: In contrast to other drivers, the - PowerVM (or phyp) driver is a client-side-only driver, - internally using ssh to connect to the specified hmc or ivm - server. Therefore, the remote transport - mechanism provided by the remote driver and libvirtd will - not work, and you cannot use URIs like - phyp+ssh://example.com. -

    - - -

    URI Format

    -

    - URIs have this general form ([...] marks an - optional part, {...|...} marks a mandatory choice). -

    -
    -phyp://[username@]{hmc|ivm}/managed_system
    -
    - - diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng index 26d313d652..91ee523116 100644 --- a/docs/schemas/capability.rng +++ b/docs/schemas/capability.rng @@ -408,8 +408,7 @@ xen - linux + linux hvm exe uml diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 5f1d4a34a4..3d9fc5f216 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -216,7 +216,7 @@ vmware hyperv vbox - phyp + phyp vz bhyve diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index 685e171235..54f4f8190d 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -84,7 +84,7 @@ typedef enum { VIR_FROM_ONE = 27, /* The OpenNebula driver no longer exists. Retained for ABI/API compat only */ VIR_FROM_ESX = 28, /* Error from ESX driver */ - VIR_FROM_PHYP = 29, /* Error from IBM power hypervisor */ + VIR_FROM_PHYP = 29, /* Error from the phyp driver, unused since 6.0.0 */ VIR_FROM_SECRET = 30, /* Error from secret storage */ VIR_FROM_CPU = 31, /* Error from CPU driver */ diff --git a/libvirt.spec.in b/libvirt.spec.in index 249a4b5425..5055750d2d 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -54,7 +54,6 @@ # Then the hypervisor drivers that run outside libvirtd, in libvirt.so %define with_openvz 0%{!?_without_openvz:1} %define with_vmware 0%{!?_without_vmware:1} -%define with_phyp 0%{!?_without_phyp:1} %define with_esx 0%{!?_without_esx:1} %define with_hyperv 0%{!?_without_hyperv:1} @@ -136,7 +135,6 @@ %if 0%{?rhel} %define with_openvz 0 %define with_vbox 0 - %define with_phyp 0 %define with_vmware 0 %define with_libxl 0 %define with_hyperv 0 @@ -366,7 +364,7 @@ BuildRequires: libcap-ng-devel >= 0.5.0 %if %{with_fuse} BuildRequires: fuse-devel >= 2.8.6 %endif -%if %{with_phyp} || %{with_libssh2} +%if %{with_libssh2} BuildRequires: libssh2-devel >= 1.3.0 %endif @@ -1036,12 +1034,6 @@ exit 1 %define arg_libxl --without-libxl %endif -%if %{with_phyp} - %define arg_phyp --with-phyp -%else - %define arg_phyp --without-phyp -%endif - %if %{with_esx} %define arg_esx --with-esx %else @@ -1164,7 +1156,6 @@ cd %{_vpath_builddir} --with-sasl \ --with-polkit \ --with-libvirtd \ - %{?arg_phyp} \ %{?arg_esx} \ %{?arg_hyperv} \ %{?arg_vmware} \ diff --git a/m4/virt-driver-phyp.m4 b/m4/virt-driver-phyp.m4 deleted file mode 100644 index 7861bf24e1..0000000000 --- a/m4/virt-driver-phyp.m4 +++ /dev/null @@ -1,48 +0,0 @@ -dnl The Phyp driver -dnl -dnl Copyright (C) 2016 Red Hat, Inc. -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License, or (at your option) any later version. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library. If not, see -dnl . -dnl - -AC_DEFUN([LIBVIRT_DRIVER_ARG_PHYP], [ - LIBVIRT_ARG_WITH_FEATURE([PHYP], [PHYP], [check]) -]) - -AC_DEFUN([LIBVIRT_DRIVER_CHECK_PHYP], [ - AC_REQUIRE([LIBVIRT_CHECK_SSH2]) - - if test "$with_phyp" != "no"; then - if test "$with_ssh2" = "no" ; then - if test "$with_phyp" = "check"; then - with_phyp=no - else - AC_MSG_ERROR([libssh2 is required for Phyp driver]) - fi - else - with_phyp=yes - fi - fi - - if test "$with_phyp" = "yes"; then - AC_DEFINE_UNQUOTED([WITH_PHYP], 1, [whether IBM HMC / IVM driver is enabled]) - fi - - AM_CONDITIONAL([WITH_PHYP],[test "$with_phyp" = "yes"]) -]) - -AC_DEFUN([LIBVIRT_DRIVER_RESULT_PHYP], [ - LIBVIRT_RESULT([PHYP], [$with_phyp]) -]) diff --git a/mingw-libvirt.spec.in b/mingw-libvirt.spec.in index f6da67ab52..94d88e2edc 100644 --- a/mingw-libvirt.spec.in +++ b/mingw-libvirt.spec.in @@ -19,7 +19,6 @@ # The mingw build is client only. Set up defaults for hypervisor drivers # that talk via a native remote protocol, and for which prereq mingw # libraries exist. -%define with_phyp 0%{!?_without_phyp:1} %define with_esx 0%{!?_without_esx:1} # missing libwsman, so can't build hyper-v %define with_hyperv 0%{!?_without_hyperv:0} @@ -28,7 +27,6 @@ # RHEL ships ESX but not PowerHypervisor, HyperV, or libxenserver (xenapi) %if 0%{?rhel} - %define with_phyp 0 %define with_xenapi 0 %define with_hyperv 0 %endif @@ -140,10 +138,6 @@ echo "This RPM requires Fedora >= %{min_fedora}" exit 1 %endif -%if ! %{with_phyp} - %define _without_phyp --without-phyp -%endif - %if ! %{with_esx} %define _without_esx --without-esx %endif @@ -176,7 +170,6 @@ autoreconf -if --without-sasl \ --without-polkit \ --without-libvirtd \ - %{?_without_phyp} \ %{?_without_esx} \ %{?_without_hyperv} \ --without-vmware \ diff --git a/po/POTFILES.in b/po/POTFILES.in index c26ac9497d..faf173584e 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -137,7 +137,6 @@ @SRCDIR@/src/openvz/openvz_conf.c @SRCDIR@/src/openvz/openvz_driver.c @SRCDIR@/src/openvz/openvz_util.c -@SRCDIR@/src/phyp/phyp_driver.c @SRCDIR@/src/qemu/qemu_agent.c @SRCDIR@/src/qemu/qemu_alias.c @SRCDIR@/src/qemu/qemu_backup.c diff --git a/src/Makefile.am b/src/Makefile.am index cd01796d67..f3d4c28c6d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -109,7 +109,6 @@ include logging/Makefile.inc.am include locking/Makefile.inc.am include admin/Makefile.inc.am include rpc/Makefile.inc.am -include phyp/Makefile.inc.am include test/Makefile.inc.am include esx/Makefile.inc.am include hyperv/Makefile.inc.am diff --git a/src/README b/src/README index a2260fda68..7ddbc08bfe 100644 --- a/src/README +++ b/src/README @@ -30,7 +30,6 @@ Then there are the hypervisor implementations: * hyperv/ - Microsoft Hyper-V support using WinRM * lxc/ - Linux Native Containers * openvz/ - OpenVZ containers using cli tools - * phyp/ - IBM Power Hypervisor using CLI tools over SSH * qemu/ - QEMU / KVM using qemu CLI/monitor * remote/ - Generic libvirt native RPC client * test/ - A "mock" driver for testing @@ -41,7 +40,7 @@ Then there are the hypervisor implementations: Finally some secondary drivers that are shared for several HVs. Currently these are used by LXC, OpenVZ, QEMU and Xen drivers. -The ESX, Hyper-V, Power Hypervisor, Remote, Test & VirtualBox drivers all +The ESX, Hyper-V, Remote, Test & VirtualBox drivers all implement the secondary drivers directly * cpu/ - CPU feature management diff --git a/src/libvirt.c b/src/libvirt.c index 9d783761e6..c741ebe311 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -72,9 +72,6 @@ #ifdef WITH_VMWARE # include "vmware/vmware_driver.h" #endif -#ifdef WITH_PHYP -# include "phyp/phyp_driver.h" -#endif #ifdef WITH_ESX # include "esx/esx_driver.h" #endif @@ -290,10 +287,6 @@ virGlobalInit(void) if (vmwareRegister() == -1) goto error; #endif -#ifdef WITH_PHYP - if (phypRegister() == -1) - goto error; -#endif #ifdef WITH_ESX if (esxRegister() == -1) goto error; @@ -959,9 +952,6 @@ virConnectOpenInternal(const char *name, if (STREQ(virConnectDriverTab[i]->hypervisorDriver->name, "remote") && ret->uri != NULL && ( -#ifndef WITH_PHYP - STRCASEEQ(ret->uri->scheme, "phyp") || -#endif #ifndef WITH_ESX STRCASEEQ(ret->uri->scheme, "vpx") || STRCASEEQ(ret->uri->scheme, "esx") || diff --git a/src/phyp/Makefile.inc.am b/src/phyp/Makefile.inc.am deleted file mode 100644 index af556e8589..0000000000 --- a/src/phyp/Makefile.inc.am +++ /dev/null @@ -1,21 +0,0 @@ -# vim: filetype=automake - -PHYP_DRIVER_SOURCES = \ - phyp/phyp_driver.c \ - phyp/phyp_driver.h \ - $(NULL) - -DRIVER_SOURCE_FILES += $(addprefix $(srcdir)/,$(PHYP_DRIVER_SOURCES)) -EXTRA_DIST += $(PHYP_DRIVER_SOURCES) - -if WITH_PHYP -noinst_LTLIBRARIES += libvirt_driver_phyp.la -libvirt_la_BUILT_LIBADD += libvirt_driver_phyp.la -libvirt_driver_phyp_la_LIBADD = $(SSH2_LIBS) -libvirt_driver_phyp_la_CFLAGS = \ - $(SSH2_CFLAGS) \ - -I$(srcdir)/conf \ - $(AM_CFLAGS) \ - $(NULL) -libvirt_driver_phyp_la_SOURCES = $(PHYP_DRIVER_SOURCES) -endif WITH_PHYP diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c deleted file mode 100644 index 6bd37a6925..0000000000 --- a/src/phyp/phyp_driver.c +++ /dev/null @@ -1,3739 +0,0 @@ -/* - * Copyright (C) 2010-2015 Red Hat, Inc. - * Copyright IBM Corp. 2009 - * - * phyp_driver.c: ssh layer to access Power Hypervisors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "internal.h" -#include "virauth.h" -#include "datatypes.h" -#include "virbuffer.h" -#include "viralloc.h" -#include "virlog.h" -#include "driver.h" -#include "virerror.h" -#include "viruuid.h" -#include "domain_conf.h" -#include "storage_conf.h" -#include "virfile.h" -#include "interface_conf.h" -#include "phyp_driver.h" -#include "virstring.h" - -#define VIR_FROM_THIS VIR_FROM_PHYP - -VIR_LOG_INIT("phyp.phyp_driver"); - -#define LPAR_EXEC_ERR (-1) -#define SSH_CONN_ERR (-2) /* error while trying to connect to remote host */ -#define SSH_CMD_ERR (-3) /* error while trying to execute the remote cmd */ - -/* This is the lpar (domain) struct that relates - * the ID with UUID generated by the API - * */ -typedef struct _lpar lpar_t; -typedef lpar_t *lparPtr; -struct _lpar { - unsigned char uuid[VIR_UUID_BUFLEN]; - int id; -}; - -/* Struct that holds how many lpars (domains) we're - * handling and a pointer to an array of lpar structs - * */ -typedef struct _uuid_table uuid_table_t; -typedef uuid_table_t *uuid_tablePtr; -struct _uuid_table { - size_t nlpars; - lparPtr *lpars; -}; - -/* This is the main structure of the driver - * */ -typedef struct _phyp_driver phyp_driver_t; -typedef phyp_driver_t *phyp_driverPtr; -struct _phyp_driver { - LIBSSH2_SESSION *session; - int sock; - - uuid_tablePtr uuid_table; - virCapsPtr caps; - virDomainXMLOptionPtr xmlopt; - int vios_id; - - /* system_type: - * 0 = hmc - * 127 = ivm - * */ - int system_type; - char *managed_system; -}; - -/* - * URI: phyp://user@[hmc|ivm]/managed_system - * */ - -enum { - HMC = 0, - PHYP_IFACENAME_SIZE = 24, - PHYP_MAC_SIZE = 12, -}; - -static int -waitsocket(int socket_fd, LIBSSH2_SESSION * session) -{ - struct pollfd fds[1]; - int dir; - - memset(fds, 0, sizeof(fds)); - fds[0].fd = socket_fd; - - /* now make sure we wait in the correct direction */ - dir = libssh2_session_block_directions(session); - - if (dir & LIBSSH2_SESSION_BLOCK_INBOUND) - fds[0].events |= POLLIN; - - if (dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) - fds[0].events |= POLLOUT; - - return poll(fds, G_N_ELEMENTS(fds), -1); -} - -/* this function is the layer that manipulates the ssh channel itself - * and executes the commands on the remote machine */ -static char *phypExec(LIBSSH2_SESSION *, const char *, int *, virConnectPtr) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) - ATTRIBUTE_NONNULL(4); -static char * -phypExec(LIBSSH2_SESSION *session, const char *cmd, int *exit_status, - virConnectPtr conn) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_CHANNEL *channel; - virBuffer tex_ret = VIR_BUFFER_INITIALIZER; - char *buffer = NULL; - size_t buffer_size = 16384; - int exitcode; - int bytecount = 0; - int sock = phyp_driver->sock; - int rc = 0; - - if (VIR_ALLOC_N(buffer, buffer_size) < 0) - return NULL; - - /* 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) { - if (waitsocket(sock, session) < 0 && errno != EINTR) { - virReportSystemError(errno, "%s", - _("unable to wait on libssh2 socket")); - goto err; - } - } - - if (channel == NULL) - goto err; - - while ((rc = libssh2_channel_exec(channel, cmd)) == - LIBSSH2_ERROR_EAGAIN) { - if (waitsocket(sock, session) < 0 && errno != EINTR) { - virReportSystemError(errno, "%s", - _("unable to wait on libssh2 socket")); - goto err; - } - } - - if (rc != 0) - goto err; - - for (;;) { - /* loop until we block */ - do { - rc = libssh2_channel_read(channel, buffer, buffer_size); - if (rc > 0) { - bytecount += rc; - virBufferAdd(&tex_ret, buffer, -1); - } - } - while (rc > 0); - - /* this is due to blocking that would occur otherwise so we loop on - * this condition */ - if (rc == LIBSSH2_ERROR_EAGAIN) { - if (waitsocket(sock, session) < 0 && errno != EINTR) { - virReportSystemError(errno, "%s", - _("unable to wait on libssh2 socket")); - goto err; - } - } else { - break; - } - } - - exitcode = 127; - - while ((rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN) { - if (waitsocket(sock, session) < 0 && errno != EINTR) { - virReportSystemError(errno, "%s", - _("unable to wait on libssh2 socket")); - goto err; - } - } - - if (rc == 0) - exitcode = libssh2_channel_get_exit_status(channel); - - (*exit_status) = exitcode; - libssh2_channel_free(channel); - channel = NULL; - VIR_FREE(buffer); - - return virBufferContentAndReset(&tex_ret); - - err: - (*exit_status) = SSH_CMD_ERR; - virBufferFreeAndReset(&tex_ret); - VIR_FREE(buffer); - return NULL; -} - -/* Convenience wrapper function */ -static char *phypExecBuffer(LIBSSH2_SESSION *, virBufferPtr buf, int *, - virConnectPtr, bool) ATTRIBUTE_NONNULL(1) - ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4); -static char * -phypExecBuffer(LIBSSH2_SESSION *session, virBufferPtr buf, int *exit_status, - virConnectPtr conn, bool strip_newline) -{ - char *cmd; - char *ret; - - cmd = virBufferContentAndReset(buf); - ret = phypExec(session, cmd, exit_status, conn); - VIR_FREE(cmd); - if (ret && *exit_status == 0 && strip_newline) { - char *nl = strchr(ret, '\n'); - if (nl) - *nl = '\0'; - } - return ret; -} - -/* Convenience wrapper function */ -static int phypExecInt(LIBSSH2_SESSION *, virBufferPtr, virConnectPtr, int *) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4); -static int -phypExecInt(LIBSSH2_SESSION *session, virBufferPtr buf, virConnectPtr conn, - int *result) -{ - char *str; - int ret; - char *char_ptr; - - str = phypExecBuffer(session, buf, &ret, conn, true); - if (!str || ret) { - VIR_FREE(str); - return -1; - } - ret = virStrToLong_i(str, &char_ptr, 10, result); - if (ret == 0 && *char_ptr) - VIR_WARN("ignoring suffix during integer parsing of '%s'", str); - VIR_FREE(str); - return ret; -} - -static int -phypGetSystemType(virConnectPtr conn) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - char *ret = NULL; - int exit_status = 0; - - ret = phypExec(session, "lshmc -V", &exit_status, conn); - - VIR_FREE(ret); - return exit_status; -} - -static int -phypGetVIOSPartitionID(virConnectPtr conn) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - int id = -1; - char *managed_system = phyp_driver->managed_system; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - virBufferAddLit(&buf, "lssyscfg"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAddLit(&buf, " -r lpar -F lpar_id,lpar_env" - "|sed -n '/vioserver/ {\n s/,.*$//\n p\n}'"); - phypExecInt(session, &buf, conn, &id); - return id; -} - - -static virCapsPtr -phypCapsInit(void) -{ - virCapsPtr caps; - virCapsGuestPtr guest; - - if ((caps = virCapabilitiesNew(virArchFromHost(), - false, false)) == NULL) - goto no_memory; - - /* Some machines have problematic NUMA topology causing - * unexpected failures. We don't want to break the QEMU - * driver in this scenario, so log errors & carry on - */ - if (!(caps->host.numa = virCapabilitiesHostNUMANewHost())) - goto no_memory; - - if (virCapabilitiesInitCaches(caps) < 0) - VIR_WARN("Failed to get host CPU cache info"); - - if ((guest = virCapabilitiesAddGuest(caps, - VIR_DOMAIN_OSTYPE_LINUX, - caps->host.arch, - NULL, NULL, 0, NULL)) == NULL) - goto no_memory; - - if (virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_PHYP, - NULL, NULL, 0, NULL) == NULL) - goto no_memory; - - return caps; - - no_memory: - virObjectUnref(caps); - return NULL; -} - -/* 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 -phypConnectNumOfDomainsGeneric(virConnectPtr conn, unsigned int type) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - int ndom = -1; - char *managed_system = phyp_driver->managed_system; - const char *state; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - 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 = " "; - } - - virBufferAddLit(&buf, "lssyscfg -r lpar"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, " -F lpar_id,state %s |grep -c '^[0-9][0-9]*'", - state); - phypExecInt(session, &buf, conn, &ndom); - return ndom; -} - -/* 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 -phypConnectListDomainsGeneric(virConnectPtr conn, int *ids, int nids, - unsigned int type) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - char *managed_system = phyp_driver->managed_system; - int exit_status = 0; - int got = -1; - char *ret = NULL; - char *line, *next_line; - const char *state; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (type == 0) - state = "|grep Running"; - else - state = " "; - - virBufferAddLit(&buf, "lssyscfg -r lpar"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, " -F lpar_id,state %s | sed -e 's/,.*$//'", - state); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - if (exit_status < 0 || ret == NULL) - goto cleanup; - - /* I need to parse the textual return in order to get the ids */ - line = ret; - got = 0; - while (*line && got < nids) { - if (virStrToLong_i(line, &next_line, 10, &ids[got]) == -1) { - VIR_ERROR(_("Cannot parse number from '%s'"), line); - got = -1; - goto cleanup; - } - got++; - line = next_line; - while (*line == '\n') - line++; /* skip \n */ - } - - cleanup: - VIR_FREE(ret); - return got; -} - -static int -phypUUIDTable_WriteFile(virConnectPtr conn) -{ - phyp_driverPtr phyp_driver = conn->privateData; - uuid_tablePtr uuid_table = phyp_driver->uuid_table; - size_t i = 0; - int fd = -1; - char local_file[] = "./uuid_table"; - - if ((fd = creat(local_file, 0755)) == -1) - goto err; - - for (i = 0; i < uuid_table->nlpars; i++) { - if (safewrite(fd, &uuid_table->lpars[i]->id, - sizeof(uuid_table->lpars[i]->id)) != - sizeof(uuid_table->lpars[i]->id)) { - VIR_ERROR(_("Unable to write information to local file.")); - goto err; - } - - if (safewrite(fd, uuid_table->lpars[i]->uuid, VIR_UUID_BUFLEN) != - VIR_UUID_BUFLEN) { - VIR_ERROR(_("Unable to write information to local file.")); - goto err; - } - } - - if (VIR_CLOSE(fd) < 0) { - virReportSystemError(errno, _("Could not close %s"), - local_file); - goto err; - } - return 0; - - err: - VIR_FORCE_CLOSE(fd); - return -1; -} - -static int -phypUUIDTable_Push(virConnectPtr conn) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - LIBSSH2_CHANNEL *channel = NULL; - struct stat local_fileinfo; - char buffer[1024]; - int rc = 0; - FILE *f = NULL; - size_t nread, sent; - char *ptr; - char local_file[] = "./uuid_table"; - char *remote_file = NULL; - int ret = -1; - - remote_file = g_strdup_printf("/home/%s/libvirt_uuid_table", - NULLSTR(conn->uri->user)); - - if (stat(local_file, &local_fileinfo) == -1) { - VIR_WARN("Unable to stat local file."); - goto cleanup; - } - - if (!(f = fopen(local_file, "rb"))) { - VIR_WARN("Unable to open local file."); - goto cleanup; - } - - 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 cleanup; - } while (!channel); - - do { - nread = fread(buffer, 1, sizeof(buffer), f); - if (nread <= 0) { - if (feof(f)) { - /* end of file */ - break; - } else { - VIR_ERROR(_("Failed to read from %s"), local_file); - goto cleanup; - } - } - ptr = buffer; - sent = 0; - - do { - /* write the same data over and over, until error or completion */ - rc = libssh2_channel_write(channel, ptr, nread); - if (LIBSSH2_ERROR_EAGAIN == rc) { /* must loop around */ - continue; - } else 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); - - ret = 0; - - cleanup: - VIR_FREE(remote_file); - if (channel) { - libssh2_channel_send_eof(channel); - libssh2_channel_wait_eof(channel); - libssh2_channel_wait_closed(channel); - libssh2_channel_free(channel); - channel = NULL; - } - VIR_FORCE_FCLOSE(f); - return ret; -} - -static int -phypUUIDTable_RemLpar(virConnectPtr conn, int id) -{ - phyp_driverPtr phyp_driver = conn->privateData; - uuid_tablePtr uuid_table = phyp_driver->uuid_table; - size_t i = 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); - } - } - - if (phypUUIDTable_WriteFile(conn) == -1) - goto err; - - if (phypUUIDTable_Push(conn) == -1) - goto err; - - return 0; - - err: - return -1; -} - -static int -phypUUIDTable_AddLpar(virConnectPtr conn, unsigned char *uuid, int id) -{ - phyp_driverPtr phyp_driver = conn->privateData; - uuid_tablePtr uuid_table = phyp_driver->uuid_table; - lparPtr item = NULL; - - if (VIR_ALLOC(item) < 0) - goto err; - - item->id = id; - memcpy(item->uuid, uuid, VIR_UUID_BUFLEN); - - if (VIR_APPEND_ELEMENT_COPY(uuid_table->lpars, uuid_table->nlpars, item) < 0) - goto err; - - if (phypUUIDTable_WriteFile(conn) == -1) - goto err; - - if (phypUUIDTable_Push(conn) == -1) - goto err; - - return 0; - - err: - VIR_FREE(item); - return -1; -} - -static int -phypUUIDTable_ReadFile(virConnectPtr conn) -{ - phyp_driverPtr phyp_driver = conn->privateData; - uuid_tablePtr uuid_table = phyp_driver->uuid_table; - size_t i = 0; - int fd = -1; - char local_file[] = "./uuid_table"; - int rc = 0; - int id; - - if ((fd = open(local_file, O_RDONLY)) == -1) { - VIR_WARN("Unable to read information from 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) - goto err; - uuid_table->lpars[i]->id = id; - } else { - VIR_WARN - ("Unable to read from information from local file."); - goto err; - } - - rc = read(fd, uuid_table->lpars[i]->uuid, VIR_UUID_BUFLEN); - if (rc != VIR_UUID_BUFLEN) { - VIR_WARN("Unable to read information from local file."); - goto err; - } - } - } - - VIR_FORCE_CLOSE(fd); - return 0; - - err: - VIR_FORCE_CLOSE(fd); - return -1; -} - -static int -phypUUIDTable_Pull(virConnectPtr conn) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - LIBSSH2_CHANNEL *channel = NULL; - struct stat fileinfo; - char buffer[1024]; - int rc = 0; - int fd = -1; - int got = 0; - int amount = 0; - int total = 0; - int sock = 0; - char local_file[] = "./uuid_table"; - char *remote_file = NULL; - int ret = -1; - - remote_file = g_strdup_printf("/home/%s/libvirt_uuid_table", - NULLSTR(conn->uri->user)); - - /* Trying to stat the remote file. */ - do { - channel = libssh2_scp_recv(session, remote_file, &fileinfo); - - if (!channel) { - if (libssh2_session_last_errno(session) != - LIBSSH2_ERROR_EAGAIN) { - goto cleanup; - } else { - if (waitsocket(sock, session) < 0 && errno != EINTR) { - virReportSystemError(errno, "%s", - _("unable to wait on libssh2 socket")); - goto cleanup; - } - } - } - } while (!channel); - - /* Creating a new data base based on remote file */ - if ((fd = creat(local_file, 0755)) == -1) - goto cleanup; - - /* Request a file via SCP */ - while (got < fileinfo.st_size) { - do { - amount = sizeof(buffer); - - if ((fileinfo.st_size - got) < amount) - amount = fileinfo.st_size - got; - - rc = libssh2_channel_read(channel, buffer, amount); - if (rc > 0) { - if (safewrite(fd, buffer, rc) != rc) - VIR_WARN - ("Unable to write information to local file."); - - got += rc; - total += rc; - } - } while (rc > 0); - - if ((rc == LIBSSH2_ERROR_EAGAIN) - && (got < fileinfo.st_size)) { - /* this is due to blocking that would occur otherwise - * so we loop on this condition */ - - /* now we wait */ - if (waitsocket(sock, session) < 0 && errno != EINTR) { - virReportSystemError(errno, "%s", - _("unable to wait on libssh2 socket")); - goto cleanup; - } - continue; - } - break; - } - if (VIR_CLOSE(fd) < 0) { - virReportSystemError(errno, _("Could not close %s"), - local_file); - goto cleanup; - } - - ret = 0; - - cleanup: - if (channel) { - libssh2_channel_send_eof(channel); - libssh2_channel_wait_eof(channel); - libssh2_channel_wait_closed(channel); - libssh2_channel_free(channel); - channel = NULL; - } - VIR_FORCE_CLOSE(fd); - return ret; -} - -static int -phypUUIDTable_Init(virConnectPtr conn) -{ - uuid_tablePtr uuid_table = NULL; - phyp_driverPtr phyp_driver; - int nids_numdomains = 0; - int nids_listdomains = 0; - int *ids = NULL; - size_t i = 0; - int ret = -1; - bool table_created = false; - - if ((nids_numdomains = phypConnectNumOfDomainsGeneric(conn, 2)) < 0) - goto cleanup; - - if (VIR_ALLOC_N(ids, nids_numdomains) < 0) - goto cleanup; - - if ((nids_listdomains = - phypConnectListDomainsGeneric(conn, ids, nids_numdomains, 1)) < 0) - goto cleanup; - - /* exit early if there are no domains */ - if (nids_numdomains == 0 && nids_listdomains == 0) { - ret = 0; - goto cleanup; - } - if (nids_numdomains != nids_listdomains) { - VIR_ERROR(_("Unable to determine number of domains.")); - goto cleanup; - } - - phyp_driver = conn->privateData; - uuid_table = phyp_driver->uuid_table; - uuid_table->nlpars = nids_listdomains; - - /* try to get the table from server */ - if (phypUUIDTable_Pull(conn) == -1) { - /* file not found in the server, creating a new one */ - table_created = true; - 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) - goto cleanup; - 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 { - goto cleanup; - } - - if (phypUUIDTable_WriteFile(conn) == -1) - goto cleanup; - - if (phypUUIDTable_Push(conn) == -1) - goto cleanup; - } else { - if (phypUUIDTable_ReadFile(conn) == -1) - goto cleanup; - } - - ret = 0; - - cleanup: - if (ret < 0 && table_created) { - for (i = 0; i < uuid_table->nlpars; i++) - VIR_FREE(uuid_table->lpars[i]); - VIR_FREE(uuid_table->lpars); - } - VIR_FREE(ids); - return ret; -} - -static void -phypUUIDTable_Free(uuid_tablePtr uuid_table) -{ - size_t i; - - 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); -} - -#define SPECIALCHARACTER_CASES \ - 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': - -static bool -contains_specialcharacters(const char *src) -{ - size_t len = strlen(src); - size_t i = 0; - - if (len == 0) - return false; - - for (i = 0; i < len; i++) { - switch (src[i]) { - SPECIALCHARACTER_CASES - return true; - default: - continue; - } - } - - return false; -} - -static char * -escape_specialcharacters(const char *src) -{ - size_t len = strlen(src); - size_t i = 0, j = 0; - char *dst; - - if (len == 0) - return NULL; - - if (VIR_ALLOC_N(dst, len + 1) < 0) - return NULL; - - for (i = 0; i < len; i++) { - switch (src[i]) { - SPECIALCHARACTER_CASES - continue; - default: - dst[j] = src[i]; - j++; - } - } - - dst[j] = '\0'; - - return dst; -} - -static 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 = -1; - int rc; - struct addrinfo *ai = NULL, *cur; - struct addrinfo hints; - int ret; - char *pubkey = NULL; - char *pvtkey = NULL; - char *userhome = virGetUserDirectory(); - struct stat pvt_stat, pub_stat; - - if (userhome == NULL) - goto err; - - pubkey = g_strdup_printf("%s/.ssh/id_rsa.pub", userhome); - - pvtkey = g_strdup_printf("%s/.ssh/id_rsa", userhome); - - if (conn->uri->user != NULL) { - username = g_strdup(conn->uri->user); - } else { - if (!(username = virAuthGetUsername(conn, auth, "ssh", NULL, - conn->uri->server))) - goto err; - } - - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = 0; - - ret = getaddrinfo(hostname, "22", &hints, &ai); - if (ret != 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Error while getting %s address info"), hostname); - goto err; - } - - 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) { - freeaddrinfo(ai); - goto connected; - } - VIR_FORCE_CLOSE(sock); - } - cur = cur->ai_next; - } - - virReportError(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); - - while ((rc = libssh2_session_startup(session, sock)) == - LIBSSH2_ERROR_EAGAIN); - if (rc) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("Failure establishing SSH session.")); - goto disconnect; - } - - /* Trying authentication by pubkey */ - if (stat(pvtkey, &pvt_stat) || stat(pubkey, &pub_stat)) { - rc = LIBSSH2_ERROR_SOCKET_NONE; - goto keyboard_interactive; - } - - while ((rc = - libssh2_userauth_publickey_fromfile(session, username, - pubkey, - pvtkey, - NULL)) == - LIBSSH2_ERROR_EAGAIN); - - keyboard_interactive: - if (rc == LIBSSH2_ERROR_SOCKET_NONE - || rc == LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED - || rc == LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED) { - - if (!(password = virAuthGetPassword(conn, auth, "ssh", username, - conn->uri->server))) - goto disconnect; - - while ((rc = - libssh2_userauth_password(session, username, - password)) == - LIBSSH2_ERROR_EAGAIN); - - if (rc) { - virReportError(VIR_ERR_AUTH_FAILED, - "%s", _("Authentication failed")); - goto disconnect; - } else { - goto exit; - } - - } else if (rc == LIBSSH2_ERROR_NONE) { - goto exit; - - } else if (rc == LIBSSH2_ERROR_ALLOC || rc == LIBSSH2_ERROR_SOCKET_SEND - || rc == LIBSSH2_ERROR_SOCKET_TIMEOUT) { - goto err; - } - - disconnect: - libssh2_session_disconnect(session, "Disconnecting..."); - libssh2_session_free(session); - err: - VIR_FORCE_CLOSE(sock); - 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 -phypDomainDefPostParse(virDomainDefPtr def, - unsigned int parseFlags G_GNUC_UNUSED, - void *opaque, - void *parseOpaque G_GNUC_UNUSED) -{ - phyp_driverPtr driver = opaque; - if (!virCapabilitiesDomainSupported(driver->caps, def->os.type, - def->os.arch, - def->virtType)) - return -1; - - return 0; -} - - -static int -phypDomainDeviceDefPostParse(virDomainDeviceDefPtr dev G_GNUC_UNUSED, - const virDomainDef *def G_GNUC_UNUSED, - unsigned int parseFlags G_GNUC_UNUSED, - void *opaque G_GNUC_UNUSED, - void *parseOpaque G_GNUC_UNUSED) -{ - return 0; -} - - -virDomainDefParserConfig virPhypDriverDomainDefParserConfig = { - .devicesPostParseCallback = phypDomainDeviceDefPostParse, - .domainPostParseCallback = phypDomainDefPostParse, - .features = VIR_DOMAIN_DEF_FEATURE_NAME_SLASH, -}; - - -static virDrvOpenStatus -phypConnectOpen(virConnectPtr conn, - virConnectAuthPtr auth, - virConfPtr conf G_GNUC_UNUSED, - unsigned int flags) -{ - LIBSSH2_SESSION *session = NULL; - int internal_socket = -1; - uuid_tablePtr uuid_table = NULL; - phyp_driverPtr phyp_driver = NULL; - char *char_ptr; - char *managed_system = NULL; - - virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); - - if (VIR_ALLOC(phyp_driver) < 0) - goto failure; - - phyp_driver->sock = -1; - - if (VIR_ALLOC(uuid_table) < 0) - goto failure; - - if (conn->uri->path[0] != '\0') { - /* need to shift one byte in order to remove the first "/" of URI component */ - managed_system = g_strdup(conn->uri->path + (conn->uri->path[0] == '/')); - - /* 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 (contains_specialcharacters(conn->uri->path)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", - _("Error parsing 'path'. Invalid characters.")); - goto failure; - } - } - - if ((session = openSSHSession(conn, auth, &internal_socket)) == NULL) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("Error while opening SSH session.")); - goto failure; - } - - phyp_driver->session = session; - phyp_driver->sock = internal_socket; - - 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) - goto failure; - - virPhypDriverDomainDefParserConfig.priv = phyp_driver; - if (!(phyp_driver->xmlopt = virDomainXMLOptionNew(&virPhypDriverDomainDefParserConfig, - NULL, NULL, NULL, NULL))) - goto failure; - - conn->privateData = phyp_driver; - - if ((phyp_driver->system_type = phypGetSystemType(conn)) == -1) - goto failure; - - if (phypUUIDTable_Init(conn) == -1) - goto failure; - - if (phyp_driver->system_type == HMC) { - if ((phyp_driver->vios_id = phypGetVIOSPartitionID(conn)) == -1) - goto failure; - } - - return VIR_DRV_OPEN_SUCCESS; - - failure: - VIR_FREE(managed_system); - - if (phyp_driver != NULL) { - virObjectUnref(phyp_driver->caps); - virObjectUnref(phyp_driver->xmlopt); - VIR_FREE(phyp_driver); - } - - phypUUIDTable_Free(uuid_table); - - if (session != NULL) { - libssh2_session_disconnect(session, "Disconnecting..."); - libssh2_session_free(session); - } - - VIR_FORCE_CLOSE(internal_socket); - - return VIR_DRV_OPEN_ERROR; -} - -static int -phypConnectClose(virConnectPtr conn) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - - libssh2_session_disconnect(session, "Disconnecting..."); - libssh2_session_free(session); - - virObjectUnref(phyp_driver->caps); - virObjectUnref(phyp_driver->xmlopt); - phypUUIDTable_Free(phyp_driver->uuid_table); - VIR_FREE(phyp_driver->managed_system); - VIR_FORCE_CLOSE(phyp_driver->sock); - VIR_FREE(phyp_driver); - return 0; -} - - -static int -phypConnectIsEncrypted(virConnectPtr conn G_GNUC_UNUSED) -{ - /* Phyp uses an SSH tunnel, so is always encrypted */ - return 1; -} - - -static int -phypConnectIsSecure(virConnectPtr conn G_GNUC_UNUSED) -{ - /* Phyp uses an SSH tunnel, so is always secure */ - return 1; -} - - -static int -phypConnectIsAlive(virConnectPtr conn) -{ - phyp_driverPtr phyp_driver = conn->privateData; - /* XXX we should be able to do something better but this is simple, safe, - * and good enough for now. In worst case, the function will return true - * even though the connection is not alive. - */ - if (phyp_driver->session) - return 1; - else - return 0; -} - - -static int -phypDomainIsUpdated(virDomainPtr conn G_GNUC_UNUSED) -{ - return 0; -} - -/* 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; - int system_type = phyp_driver->system_type; - int lpar_id = -1; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - virBufferAddLit(&buf, "lssyscfg -r lpar"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, " --filter lpar_names=%s -F lpar_id", name); - phypExecInt(session, &buf, conn, &lpar_id); - return lpar_id; -} - -/* 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 *ret = NULL; - int exit_status = 0; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - virBufferAddLit(&buf, "lssyscfg -r lpar"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, " --filter lpar_ids=%d -F name", lpar_id); - ret = phypExecBuffer(session, &buf, &exit_status, conn, true); - - if (exit_status < 0) - VIR_FREE(ret); - return ret; -} - - -/* 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; - uuid_tablePtr uuid_table = phyp_driver->uuid_table; - lparPtr *lpars = uuid_table->lpars; - size_t i = 0; - - for (i = 0; i < uuid_table->nlpars; i++) { - if (lpars[i]->id == lpar_id) { - memcpy(uuid, lpars[i]->uuid, VIR_UUID_BUFLEN); - return 0; - } - } - - return -1; -} - -/* - * type: - * 0 - maxmem - * 1 - memory - * */ -static unsigned long -phypGetLparMem(virConnectPtr conn, const char *managed_system, int lpar_id, - int type) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - int memory = 0; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (type != 1 && type != 0) - return 0; - - virBufferAddLit(&buf, "lshwres"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, - " -r mem --level lpar -F %s --filter lpar_ids=%d", - type ? "curr_mem" : "curr_max_mem", lpar_id); - phypExecInt(session, &buf, conn, &memory); - return memory; -} - -static unsigned long -phypGetLparCPUGeneric(virConnectPtr conn, const char *managed_system, - int lpar_id, int type) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - int vcpus = 0; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - virBufferAddLit(&buf, "lshwres"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, - " -r proc --level lpar -F %s --filter lpar_ids=%d", - type ? "curr_max_procs" : "curr_procs", lpar_id); - phypExecInt(session, &buf, conn, &vcpus); - return vcpus; -} - -static unsigned long -phypGetLparCPU(virConnectPtr conn, const char *managed_system, int lpar_id) -{ - return phypGetLparCPUGeneric(conn, managed_system, lpar_id, 0); -} - -static int -phypDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags) -{ - phyp_driverPtr phyp_driver = dom->conn->privateData; - char *managed_system = phyp_driver->managed_system; - - if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) { - virReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags); - return -1; - } - - return phypGetLparCPUGeneric(dom->conn, managed_system, dom->id, 1); -} - -static int -phypDomainGetMaxVcpus(virDomainPtr dom) -{ - return phypDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE | - VIR_DOMAIN_VCPU_MAXIMUM)); -} - -static int -phypGetRemoteSlot(virConnectPtr conn, const char *managed_system, - const char *lpar_name) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - int remote_slot = -1; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - virBufferAddLit(&buf, "lshwres"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, " -r virtualio --rsubtype scsi -F " - "remote_slot_num --filter lpar_names=%s", lpar_name); - phypExecInt(session, &buf, conn, &remote_slot); - return remote_slot; -} - -/* XXX - is this needed? */ -static char *phypGetBackingDevice(virConnectPtr, const char *, char *) - G_GNUC_UNUSED; -static char * -phypGetBackingDevice(virConnectPtr conn, const char *managed_system, - char *lpar_name) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - 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; - - virBufferAddLit(&buf, "lshwres"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, " -r virtualio --rsubtype scsi -F " - "backing_devices --filter slots=%d", remote_slot); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - if (exit_status < 0 || ret == NULL) - goto cleanup; - - /* 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 cleanup; - - backing_device = g_strdup(char_ptr); - } else { - backing_device = g_steal_pointer(&ret); - } - - char_ptr = strchr(backing_device, '\n'); - - if (char_ptr) - *char_ptr = '\0'; - - cleanup: - VIR_FREE(ret); - - return backing_device; -} - -static char * -phypGetLparProfile(virConnectPtr conn, int lpar_id) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int exit_status = 0; - char *ret = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - virBufferAddLit(&buf, "lssyscfg"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, - " -r prof --filter lpar_ids=%d -F name|head -n 1", - lpar_id); - ret = phypExecBuffer(session, &buf, &exit_status, conn, true); - - if (exit_status < 0) - VIR_FREE(ret); - return ret; -} - -static int -phypGetVIOSNextSlotNumber(virConnectPtr conn) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int vios_id = phyp_driver->vios_id; - char *profile = NULL; - int slot = -1; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (!(profile = phypGetLparProfile(conn, vios_id))) { - VIR_ERROR(_("Unable to get VIOS profile name.")); - return -1; - } - - virBufferAddLit(&buf, "lssyscfg"); - - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - - virBufferAsprintf(&buf, " -r prof --filter " - "profile_names=%s -F virtual_eth_adapters," - "virtual_opti_pool_id,virtual_scsi_adapters," - "virtual_serial_adapters|sed -e 's/\"//g' -e " - "'s/,/\\n/g'|sed -e 's/\\(^[0-9][0-9]\\*\\).*$/\\1/'" - "|sort|tail -n 1", profile); - if (phypExecInt(session, &buf, conn, &slot) < 0) - return -1; - return slot + 1; -} - -static int -phypCreateServerSCSIAdapter(virConnectPtr conn) -{ - int result = -1; - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int vios_id = phyp_driver->vios_id; - int exit_status = 0; - char *ret = NULL; - char *profile = NULL; - int slot = 0; - char *vios_name = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (! - (vios_name = - phypGetLparNAME(session, managed_system, vios_id, conn))) { - VIR_ERROR(_("Unable to get VIOS name")); - goto cleanup; - } - - if (!(profile = phypGetLparProfile(conn, vios_id))) { - VIR_ERROR(_("Unable to get VIOS profile name.")); - goto cleanup; - } - - if ((slot = phypGetVIOSNextSlotNumber(conn)) == -1) { - VIR_ERROR(_("Unable to get free slot number")); - goto cleanup; - } - - /* Listing all the virtual_scsi_adapter interfaces, the new adapter must - * be appended to this list - * */ - virBufferAddLit(&buf, "lssyscfg"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, " -r prof --filter lpar_ids=%d,profile_names=%s" - " -F virtual_scsi_adapters|sed -e s/\\\"//g", - vios_id, profile); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - if (exit_status < 0 || ret == NULL) - goto cleanup; - - /* Here I change the VIOS configuration to append the new adapter - * with the free slot I got with phypGetVIOSNextSlotNumber. - * */ - virBufferAddLit(&buf, "chsyscfg"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, " -r prof -i 'name=%s,lpar_id=%d," - "\"virtual_scsi_adapters=%s,%d/server/any/any/1\"'", - vios_name, vios_id, ret, slot); - VIR_FREE(ret); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - if (exit_status < 0 || ret == NULL) - goto cleanup; - - /* Finally I add the new scsi adapter to VIOS using the same slot - * I used in the VIOS configuration. - * */ - virBufferAddLit(&buf, "chhwres -r virtualio --rsubtype scsi"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, - " -p %s -o a -s %d -d 0 -a \"adapter_type=server\"", - vios_name, slot); - VIR_FREE(ret); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - if (exit_status < 0 || ret == NULL) - goto cleanup; - - result = 0; - - cleanup: - VIR_FREE(profile); - VIR_FREE(vios_name); - VIR_FREE(ret); - - return result; -} - -static char * -phypGetVIOSFreeSCSIAdapter(virConnectPtr conn) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int vios_id = phyp_driver->vios_id; - int exit_status = 0; - char *ret = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (system_type == HMC) - virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '", - managed_system, vios_id); - - virBufferAddLit(&buf, "lsmap -all -field svsa backing -fmt , "); - - if (system_type == HMC) - virBufferAddChar(&buf, '\''); - - virBufferAddLit(&buf, "|sed '/,[^.*]/d; s/,//g; q'"); - ret = phypExecBuffer(session, &buf, &exit_status, conn, true); - - if (exit_status < 0) - VIR_FREE(ret); - return ret; -} - - -static int -phypDomainAttachDeviceFlags(virDomainPtr domain, - const char *xml, - unsigned int flags) -{ - int result = -1; - virConnectPtr conn = domain->conn; - phyp_driverPtr phyp_driver = domain->conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int vios_id = phyp_driver->vios_id; - int exit_status = 0; - char *ret = NULL; - char *scsi_adapter = NULL; - int slot = 0; - char *vios_name = NULL; - char *profile = NULL; - virDomainDeviceDefPtr dev = NULL; - virDomainDefPtr def = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - char *domain_name = NULL; - - virCheckFlags(0, -1); - - if (!(def = virDomainDefNew())) - goto cleanup; - - domain_name = escape_specialcharacters(domain->name); - - if (domain_name == NULL) - goto cleanup; - - def->os.type = VIR_DOMAIN_OSTYPE_LINUX; - - dev = virDomainDeviceDefParse(xml, def, NULL, NULL, - VIR_DOMAIN_DEF_PARSE_INACTIVE); - if (!dev) - goto cleanup; - - if (! - (vios_name = - phypGetLparNAME(session, managed_system, vios_id, conn))) { - VIR_ERROR(_("Unable to get VIOS name")); - goto cleanup; - } - - /* First, let's look for a free SCSI Adapter - * */ - if (!(scsi_adapter = phypGetVIOSFreeSCSIAdapter(conn))) { - /* If not found, let's create one. - * */ - if (phypCreateServerSCSIAdapter(conn) == -1) { - VIR_ERROR(_("Unable to create new virtual adapter")); - goto cleanup; - } else { - if (!(scsi_adapter = phypGetVIOSFreeSCSIAdapter(conn))) { - VIR_ERROR(_("Unable to create new virtual adapter")); - goto cleanup; - } - } - } - - if (system_type == HMC) - virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '", - managed_system, vios_id); - - virBufferAsprintf(&buf, "mkvdev -vdev %s -vadapter %s", - virDomainDiskGetSource(dev->data.disk), scsi_adapter); - - if (system_type == HMC) - virBufferAddChar(&buf, '\''); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - if (exit_status < 0 || ret == NULL) - goto cleanup; - - if (!(profile = phypGetLparProfile(conn, domain->id))) { - VIR_ERROR(_("Unable to get VIOS profile name.")); - goto cleanup; - } - - /* Let's get the slot number for the adapter we just created - * */ - virBufferAddLit(&buf, "lshwres -r virtualio --rsubtype scsi"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, - " slot_num,backing_device|grep %s|cut -d, -f1", - virDomainDiskGetSource(dev->data.disk)); - if (phypExecInt(session, &buf, conn, &slot) < 0) - goto cleanup; - - /* Listing all the virtual_scsi_adapter interfaces, the new adapter must - * be appended to this list - * */ - virBufferAddLit(&buf, "lssyscfg"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, - " -r prof --filter lpar_ids=%d,profile_names=%s" - " -F virtual_scsi_adapters|sed -e 's/\"//g'", - vios_id, profile); - VIR_FREE(ret); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - if (exit_status < 0 || ret == NULL) - goto cleanup; - - /* Here I change the LPAR configuration to append the new adapter - * with the new slot we just created - * */ - virBufferAddLit(&buf, "chsyscfg"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, - " -r prof -i 'name=%s,lpar_id=%d," - "\"virtual_scsi_adapters=%s,%d/client/%d/%s/0\"'", - domain_name, domain->id, ret, slot, - vios_id, vios_name); - if (phypExecInt(session, &buf, conn, &slot) < 0) - goto cleanup; - - /* Finally I add the new scsi adapter to VIOS using the same slot - * I used in the VIOS configuration. - * */ - virBufferAddLit(&buf, "chhwres -r virtualio --rsubtype scsi"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, - " -p %s -o a -s %d -d 0 -a \"adapter_type=server\"", - domain_name, slot); - VIR_FREE(ret); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - if (exit_status < 0 || ret == NULL) { - VIR_ERROR(_ - ("Possibly you don't have IBM Tools installed in your LPAR." - "Contact your support to enable this feature.")); - goto cleanup; - } - - result = 0; - - cleanup: - VIR_FREE(ret); - virDomainDeviceDefFree(dev); - virDomainDefFree(def); - VIR_FREE(vios_name); - VIR_FREE(scsi_adapter); - VIR_FREE(profile); - VIR_FREE(domain_name); - - return result; -} - -static int -phypDomainAttachDevice(virDomainPtr domain, const char *xml) -{ - return phypDomainAttachDeviceFlags(domain, xml, 0); -} - -static char * -phypStorageVolGetKey(virConnectPtr conn, const char *name) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int vios_id = phyp_driver->vios_id; - int exit_status = 0; - char *ret = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (system_type == HMC) - virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '", - managed_system, vios_id); - - virBufferAsprintf(&buf, "lslv %s -field lvid", name); - - if (system_type == HMC) - virBufferAddChar(&buf, '\''); - - virBufferAddLit(&buf, "|sed -e 's/^LV IDENTIFIER://' -e 's/ //g'"); - ret = phypExecBuffer(session, &buf, &exit_status, conn, true); - - if (exit_status < 0) - VIR_FREE(ret); - return ret; -} - -static char * -phypGetStoragePoolDevice(virConnectPtr conn, char *name) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int vios_id = phyp_driver->vios_id; - int exit_status = 0; - char *ret = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (system_type == HMC) - virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '", - managed_system, vios_id); - - virBufferAsprintf(&buf, "lssp -detail -sp %s -field name", name); - - if (system_type == HMC) - virBufferAddChar(&buf, '\''); - - virBufferAddLit(&buf, "|sed '1d; s/ //g'"); - ret = phypExecBuffer(session, &buf, &exit_status, conn, true); - - if (exit_status < 0) - VIR_FREE(ret); - return ret; -} - -static unsigned long int -phypGetStoragePoolSize(virConnectPtr conn, char *name) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int vios_id = phyp_driver->vios_id; - int sp_size = -1; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (system_type == HMC) - virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '", - managed_system, vios_id); - - virBufferAsprintf(&buf, "lssp -detail -sp %s -field size", name); - - if (system_type == HMC) - virBufferAddChar(&buf, '\''); - - virBufferAddLit(&buf, "|sed '1d; s/ //g'"); - phypExecInt(session, &buf, conn, &sp_size); - return sp_size; -} - -static char * -phypBuildVolume(virConnectPtr conn, const char *lvname, const char *spname, - unsigned int capacity) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int vios_id = phyp_driver->vios_id; - int system_type = phyp_driver->system_type; - char *managed_system = phyp_driver->managed_system; - char *ret = NULL; - int exit_status = 0; - virBuffer buf = VIR_BUFFER_INITIALIZER; - char *key = NULL; - - if (system_type == HMC) - virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '", - managed_system, vios_id); - - virBufferAsprintf(&buf, "mklv -lv %s %s %d", lvname, spname, capacity); - - if (system_type == HMC) - virBufferAddChar(&buf, '\''); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - if (exit_status < 0) { - VIR_ERROR(_("Unable to create Volume: %s"), NULLSTR(ret)); - goto cleanup; - } - - key = phypStorageVolGetKey(conn, lvname); - - cleanup: - VIR_FREE(ret); - - return key; -} - -static virStorageVolPtr -phypStorageVolLookupByName(virStoragePoolPtr pool, const char *volname) -{ - char *key; - virStorageVolPtr vol; - - key = phypStorageVolGetKey(pool->conn, volname); - - if (key == NULL) - return NULL; - - vol = virGetStorageVol(pool->conn, pool->name, volname, key, NULL, NULL); - - VIR_FREE(key); - - return vol; -} - -static virStorageVolPtr -phypStorageVolCreateXML(virStoragePoolPtr pool, - const char *xml, unsigned int flags) -{ - virCheckFlags(0, NULL); - - virStorageVolPtr vol = NULL; - virStorageVolPtr dup_vol = NULL; - char *key = NULL; - g_autoptr(virStorageVolDef) voldef = NULL; - g_autoptr(virStoragePoolDef) spdef = NULL; - - if (VIR_ALLOC(spdef) < 0) - return NULL; - - /* Filling spdef manually - * */ - if (pool->name != NULL) { - spdef->name = pool->name; - } else { - VIR_ERROR(_("Unable to determine storage pool's name.")); - goto err; - } - - if (memcpy(spdef->uuid, pool->uuid, VIR_UUID_BUFLEN) == NULL) { - VIR_ERROR(_("Unable to determine storage pool's uuid.")); - goto err; - } - - if ((spdef->capacity = - phypGetStoragePoolSize(pool->conn, pool->name)) == -1) { - VIR_ERROR(_("Unable to determine storage pools's size.")); - goto err; - } - - /* Information not available */ - spdef->allocation = 0; - spdef->available = 0; - - spdef->source.ndevice = 1; - - /*XXX source adapter not working properly, should show hdiskX */ - if ((spdef->source.adapter.data.scsi_host.name = - phypGetStoragePoolDevice(pool->conn, pool->name)) == NULL) { - VIR_ERROR(_("Unable to determine storage pools's source adapter.")); - goto err; - } - - if ((voldef = virStorageVolDefParseString(spdef, xml, 0)) == NULL) { - VIR_ERROR(_("Error parsing volume XML.")); - goto err; - } - - /* checking if this name already exists on this system */ - if ((dup_vol = phypStorageVolLookupByName(pool, voldef->name)) != NULL) { - VIR_ERROR(_("StoragePool name already exists.")); - virObjectUnref(dup_vol); - goto err; - } - - /* The key must be NULL, the Power Hypervisor creates a key - * in the moment you create the volume. - * */ - if (voldef->key) { - VIR_ERROR(_("Key must be empty, Power Hypervisor will create one for you.")); - goto err; - } - - if (!voldef->target.capacity) { - VIR_ERROR(_("Capacity cannot be empty.")); - goto err; - } - - key = phypBuildVolume(pool->conn, voldef->name, spdef->name, - voldef->target.capacity); - - if (key == NULL) - goto err; - - if ((vol = - virGetStorageVol(pool->conn, pool->name, voldef->name, - key, NULL, NULL)) == NULL) - goto err; - - VIR_FREE(key); - - return vol; - - err: - VIR_FREE(key); - virObjectUnref(vol); - return NULL; -} - -static char * -phypStorageVolGetPhysicalVolumeByStoragePool(virStorageVolPtr vol, char *sp) -{ - virConnectPtr conn = vol->conn; - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int vios_id = phyp_driver->vios_id; - int exit_status = 0; - char *ret = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (system_type == HMC) - virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '", - managed_system, vios_id); - - virBufferAsprintf(&buf, "lssp -detail -sp %s -field pvname", sp); - - if (system_type == HMC) - virBufferAddChar(&buf, '\''); - - virBufferAddLit(&buf, "|sed 1d"); - ret = phypExecBuffer(session, &buf, &exit_status, conn, true); - - if (exit_status < 0) - VIR_FREE(ret); - return ret; -} - -static virStorageVolPtr -phypStorageVolLookupByPath(virConnectPtr conn, const char *volname) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int vios_id = phyp_driver->vios_id; - int exit_status = 0; - char *ret = NULL; - char *key = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - virStorageVolPtr vol = NULL; - - if (system_type == HMC) - virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '", - managed_system, vios_id); - - virBufferAsprintf(&buf, "lslv %s -field vgname", volname); - - if (system_type == HMC) - virBufferAddChar(&buf, '\''); - - virBufferAddLit(&buf, "|sed -e 's/^VOLUME GROUP://g' -e 's/ //g'"); - ret = phypExecBuffer(session, &buf, &exit_status, conn, true); - - if (exit_status < 0 || ret == NULL) - goto cleanup; - - key = phypStorageVolGetKey(conn, volname); - - if (key == NULL) - goto cleanup; - - vol = virGetStorageVol(conn, ret, volname, key, NULL, NULL); - - cleanup: - VIR_FREE(ret); - VIR_FREE(key); - - return vol; -} - -static int -phypGetStoragePoolUUID(virConnectPtr conn, unsigned char *uuid, - const char *name) -{ - int result = -1; - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int vios_id = phyp_driver->vios_id; - int exit_status = 0; - char *ret = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (system_type == HMC) - virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '", - managed_system, vios_id); - - virBufferAsprintf(&buf, "lsdev -dev %s -attr vgserial_id", name); - - if (system_type == HMC) - virBufferAddChar(&buf, '\''); - - virBufferAddLit(&buf, "|sed '1,2d'"); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - if (exit_status < 0 || ret == NULL) - goto cleanup; - - if (memcpy(uuid, ret, VIR_UUID_BUFLEN) == NULL) - goto cleanup; - - result = 0; - - cleanup: - VIR_FREE(ret); - - return result; -} - -static virStoragePoolPtr -phypStoragePoolLookupByName(virConnectPtr conn, const char *name) -{ - unsigned char uuid[VIR_UUID_BUFLEN]; - - if (phypGetStoragePoolUUID(conn, uuid, name) == -1) - return NULL; - - return virGetStoragePool(conn, name, uuid, NULL, NULL); -} - -static char * -phypStorageVolGetXMLDesc(virStorageVolPtr vol, unsigned int flags) -{ - virStorageVolDef voldef; - virStoragePoolDef pool; - virStoragePoolPtr sp; - char *xml = NULL; - - virCheckFlags(0, NULL); - - memset(&voldef, 0, sizeof(virStorageVolDef)); - memset(&pool, 0, sizeof(virStoragePoolDef)); - - sp = phypStoragePoolLookupByName(vol->conn, vol->pool); - - if (!sp) - goto cleanup; - - if (sp->name != NULL) { - pool.name = sp->name; - } else { - VIR_ERROR(_("Unable to determine storage sp's name.")); - goto cleanup; - } - - if (memcpy(pool.uuid, sp->uuid, VIR_UUID_BUFLEN) == NULL) { - VIR_ERROR(_("Unable to determine storage sp's uuid.")); - goto cleanup; - } - - if ((pool.capacity = phypGetStoragePoolSize(sp->conn, sp->name)) == -1) { - VIR_ERROR(_("Unable to determine storage sps's size.")); - goto cleanup; - } - - /* Information not available */ - pool.allocation = 0; - pool.available = 0; - - pool.source.ndevice = 1; - - if ((pool.source.adapter.data.scsi_host.name = - phypGetStoragePoolDevice(sp->conn, sp->name)) == NULL) { - VIR_ERROR(_("Unable to determine storage sps's source adapter.")); - goto cleanup; - } - - if (vol->name != NULL) { - voldef.name = vol->name; - } else { - VIR_ERROR(_("Unable to determine storage pool's name.")); - goto cleanup; - } - - voldef.key = g_strdup(vol->key); - - voldef.type = VIR_STORAGE_POOL_LOGICAL; - - xml = virStorageVolDefFormat(&pool, &voldef); - - VIR_FREE(voldef.key); - - cleanup: - virObjectUnref(sp); - return xml; -} - -/* The Volume Group path here will be treated as suggested in the - * email on the libvirt mailling list. As soon as I can't get the - * path for every volume, the path will be a representation in - * the form: - * - * /physical_volume/storage_pool/logical_volume - * - * */ -static char * -phypStorageVolGetPath(virStorageVolPtr vol) -{ - virConnectPtr conn = vol->conn; - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int vios_id = phyp_driver->vios_id; - int exit_status = 0; - char *ret = NULL; - char *path = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - char *pv; - - if (system_type == HMC) - virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '", - managed_system, vios_id); - - virBufferAsprintf(&buf, "lslv %s -field vgname", vol->name); - - if (system_type == HMC) - virBufferAddChar(&buf, '\''); - - virBufferAsprintf(&buf, - "|sed -e 's/^VOLUME GROUP://g' -e 's/ //g'"); - ret = phypExecBuffer(session, &buf, &exit_status, conn, true); - - if (exit_status < 0 || ret == NULL) - goto cleanup; - - pv = phypStorageVolGetPhysicalVolumeByStoragePool(vol, ret); - - if (!pv) - goto cleanup; - - path = g_strdup_printf("/%s/%s/%s", pv, ret, vol->name); - - cleanup: - VIR_FREE(ret); - VIR_FREE(path); - - return path; -} - -static int -phypStoragePoolListVolumes(virStoragePoolPtr pool, char **const volumes, - int nvolumes) -{ - bool success = false; - virConnectPtr conn = pool->conn; - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int vios_id = phyp_driver->vios_id; - int exit_status = 0; - int got = 0; - size_t i; - char *ret = NULL; - char *volumes_list = NULL; - char *char_ptr = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (system_type == HMC) - virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '", - managed_system, vios_id); - - virBufferAsprintf(&buf, "lsvg -lv %s -field lvname", pool->name); - - if (system_type == HMC) - virBufferAddChar(&buf, '\''); - - virBufferAddLit(&buf, "|sed '1,2d'"); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - /* I need to parse the textual return in order to get the volumes */ - if (exit_status < 0 || ret == NULL) { - goto cleanup; - } else { - volumes_list = ret; - - while (got < nvolumes) { - char_ptr = strchr(volumes_list, '\n'); - - if (char_ptr) { - *char_ptr = '\0'; - volumes[got++] = g_strdup(volumes_list); - char_ptr++; - volumes_list = char_ptr; - } else { - break; - } - } - } - - success = true; - - cleanup: - if (!success) { - for (i = 0; i < got; i++) - VIR_FREE(volumes[i]); - - got = -1; - } - VIR_FREE(ret); - return got; -} - -static int -phypStoragePoolNumOfVolumes(virStoragePoolPtr pool) -{ - virConnectPtr conn = pool->conn; - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - int nvolumes = -1; - char *managed_system = phyp_driver->managed_system; - int vios_id = phyp_driver->vios_id; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (system_type == HMC) - virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '", - managed_system, vios_id); - virBufferAsprintf(&buf, "lsvg -lv %s -field lvname", pool->name); - if (system_type == HMC) - virBufferAddChar(&buf, '\''); - virBufferAddLit(&buf, "|grep -c '^.*$'"); - if (phypExecInt(session, &buf, conn, &nvolumes) < 0) - return -1; - - /* We need to remove 2 line from the header text output */ - return nvolumes - 2; -} - -static int -phypStoragePoolDestroy(virStoragePoolPtr pool) -{ - int result = -1; - virConnectPtr conn = pool->conn; - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int vios_id = phyp_driver->vios_id; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - char *ret = NULL; - int exit_status = 0; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (system_type == HMC) - virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '", - managed_system, vios_id); - - virBufferAsprintf(&buf, "rmsp %s", pool->name); - - if (system_type == HMC) - virBufferAddChar(&buf, '\''); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - if (exit_status < 0) { - VIR_ERROR(_("Unable to destroy Storage Pool: %s"), NULLSTR(ret)); - goto cleanup; - } - - result = 0; - - cleanup: - VIR_FREE(ret); - - return result; -} - -static int -phypBuildStoragePool(virConnectPtr conn, virStoragePoolDefPtr def) -{ - int result = -1; - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - virStoragePoolSource source = def->source; - int vios_id = phyp_driver->vios_id; - int system_type = phyp_driver->system_type; - char *managed_system = phyp_driver->managed_system; - char *ret = NULL; - int exit_status = 0; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (source.adapter.type != VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Only 'scsi_host' adapter is supported")); - goto cleanup; - } - - if (system_type == HMC) - virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '", - managed_system, vios_id); - - virBufferAsprintf(&buf, "mksp -f %schild %s", def->name, - source.adapter.data.scsi_host.name); - - if (system_type == HMC) - virBufferAddChar(&buf, '\''); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - if (exit_status < 0) { - VIR_ERROR(_("Unable to create Storage Pool: %s"), NULLSTR(ret)); - goto cleanup; - } - - result = 0; - - cleanup: - VIR_FREE(ret); - - return result; - -} - -static int -phypConnectNumOfStoragePools(virConnectPtr conn) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - int nsp = -1; - char *managed_system = phyp_driver->managed_system; - int vios_id = phyp_driver->vios_id; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (system_type == HMC) - virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '", - managed_system, vios_id); - - virBufferAddLit(&buf, "lsvg"); - - if (system_type == HMC) - virBufferAddChar(&buf, '\''); - - virBufferAddLit(&buf, "|grep -c '^.*$'"); - phypExecInt(session, &buf, conn, &nsp); - return nsp; -} - -static int -phypConnectListStoragePools(virConnectPtr conn, char **const pools, int npools) -{ - bool success = false; - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int vios_id = phyp_driver->vios_id; - int exit_status = 0; - int got = 0; - size_t i; - char *ret = NULL; - char *storage_pools = NULL; - char *char_ptr = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (system_type == HMC) - virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '", - managed_system, vios_id); - - virBufferAddLit(&buf, "lsvg"); - - if (system_type == HMC) - virBufferAddChar(&buf, '\''); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - /* I need to parse the textual return in order to get the storage pools */ - if (exit_status < 0 || ret == NULL) { - goto cleanup; - } else { - storage_pools = ret; - - while (got < npools) { - char_ptr = strchr(storage_pools, '\n'); - - if (char_ptr) { - *char_ptr = '\0'; - pools[got++] = g_strdup(storage_pools); - char_ptr++; - storage_pools = char_ptr; - } else { - break; - } - } - } - - success = true; - - cleanup: - if (!success) { - for (i = 0; i < got; i++) - VIR_FREE(pools[i]); - - got = -1; - } - VIR_FREE(ret); - return got; -} - -static virStoragePoolPtr -phypStoragePoolLookupByUUID(virConnectPtr conn, - const unsigned char *uuid) -{ - virStoragePoolPtr sp = NULL; - int npools = 0; - int gotpools = 0; - char **pools = NULL; - size_t i = 0; - unsigned char *local_uuid = NULL; - - if (VIR_ALLOC_N(local_uuid, VIR_UUID_BUFLEN) < 0) - goto err; - - if ((npools = phypConnectNumOfStoragePools(conn)) == -1) - goto err; - - if (VIR_ALLOC_N(pools, npools) < 0) - goto err; - - if ((gotpools = phypConnectListStoragePools(conn, pools, npools)) == -1) - goto err; - - if (gotpools != npools) { - virReportOOMError(); - goto err; - } - - for (i = 0; i < gotpools; i++) { - if (phypGetStoragePoolUUID(conn, local_uuid, pools[i]) == -1) - continue; - - if (!memcmp(local_uuid, uuid, VIR_UUID_BUFLEN)) { - sp = virGetStoragePool(conn, pools[i], uuid, NULL, NULL); - VIR_FREE(local_uuid); - VIR_FREE(pools); - - if (sp) - return sp; - else - goto err; - } - } - - err: - VIR_FREE(local_uuid); - VIR_FREE(pools); - return NULL; -} - -static virStoragePoolPtr -phypStoragePoolCreateXML(virConnectPtr conn, - const char *xml, unsigned int flags) -{ - virCheckFlags(0, NULL); - - virStoragePoolDefPtr def = NULL; - virStoragePoolPtr dup_sp = NULL; - virStoragePoolPtr sp = NULL; - - if (!(def = virStoragePoolDefParseString(xml))) - goto err; - - /* checking if this name already exists on this system */ - if ((dup_sp = phypStoragePoolLookupByName(conn, def->name)) != NULL) { - VIR_WARN("StoragePool name already exists."); - virObjectUnref(dup_sp); - goto err; - } - - /* checking if ID or UUID already exists on this system */ - if ((dup_sp = phypStoragePoolLookupByUUID(conn, def->uuid)) != NULL) { - VIR_WARN("StoragePool uuid already exists."); - virObjectUnref(dup_sp); - goto err; - } - - if ((sp = virGetStoragePool(conn, def->name, def->uuid, NULL, NULL)) == NULL) - goto err; - - if (phypBuildStoragePool(conn, def) == -1) - goto err; - - return sp; - - err: - virStoragePoolDefFree(def); - virObjectUnref(sp); - return NULL; -} - -static char * -phypStoragePoolGetXMLDesc(virStoragePoolPtr pool, unsigned int flags) -{ - virCheckFlags(0, NULL); - - virStoragePoolDef def; - memset(&def, 0, sizeof(virStoragePoolDef)); - - if (pool->name != NULL) { - def.name = pool->name; - } else { - VIR_ERROR(_("Unable to determine storage pool's name.")); - goto err; - } - - if (memcpy(def.uuid, pool->uuid, VIR_UUID_BUFLEN) == NULL) { - VIR_ERROR(_("Unable to determine storage pool's uuid.")); - goto err; - } - - if ((def.capacity = - phypGetStoragePoolSize(pool->conn, pool->name)) == -1) { - VIR_ERROR(_("Unable to determine storage pools's size.")); - goto err; - } - - /* Information not available */ - def.allocation = 0; - def.available = 0; - - def.source.ndevice = 1; - - /*XXX source adapter not working properly, should show hdiskX */ - if ((def.source.adapter.data.scsi_host.name = - phypGetStoragePoolDevice(pool->conn, pool->name)) == NULL) { - VIR_ERROR(_("Unable to determine storage pools's source adapter.")); - goto err; - } - - return virStoragePoolDefFormat(&def); - - err: - return NULL; -} - -static int -phypInterfaceDestroy(virInterfacePtr iface, - unsigned int flags) -{ - virCheckFlags(0, -1); - - phyp_driverPtr phyp_driver = iface->conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - virBuffer buf = VIR_BUFFER_INITIALIZER; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int exit_status = 0; - int slot_num = 0; - int lpar_id = 0; - char *ret = NULL; - int rv = -1; - - /* Getting the remote slot number */ - - virBufferAddLit(&buf, "lshwres "); - if (system_type == HMC) - virBufferAsprintf(&buf, "-m %s ", managed_system); - - virBufferAsprintf(&buf, - " -r virtualio --rsubtype eth --level lpar " - " -F mac_addr,slot_num|" - " sed -n '/%s/ s/^.*,//p'", iface->mac); - if (phypExecInt(session, &buf, iface->conn, &slot_num) < 0) - goto cleanup; - - /* Getting the remote slot number */ - virBufferAddLit(&buf, "lshwres "); - if (system_type == HMC) - virBufferAsprintf(&buf, "-m %s ", managed_system); - - virBufferAsprintf(&buf, - " -r virtualio --rsubtype eth --level lpar " - " -F mac_addr,lpar_id|" - " sed -n '/%s/ s/^.*,//p'", iface->mac); - if (phypExecInt(session, &buf, iface->conn, &lpar_id) < 0) - goto cleanup; - - /* excluding interface */ - virBufferAddLit(&buf, "chhwres "); - if (system_type == HMC) - virBufferAsprintf(&buf, "-m %s ", managed_system); - - virBufferAsprintf(&buf, - " -r virtualio --rsubtype eth" - " --id %d -o r -s %d", lpar_id, slot_num); - VIR_FREE(ret); - ret = phypExecBuffer(session, &buf, &exit_status, iface->conn, false); - - if (exit_status < 0 || ret != NULL) - goto cleanup; - - rv = 0; - - cleanup: - VIR_FREE(ret); - return rv; -} - -static virInterfacePtr -phypInterfaceDefineXML(virConnectPtr conn, const char *xml, - unsigned int flags) -{ - virCheckFlags(0, NULL); - - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - virBuffer buf = VIR_BUFFER_INITIALIZER; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int exit_status = 0; - int slot = 0; - char *ret = NULL; - char name[PHYP_IFACENAME_SIZE]; - char mac[PHYP_MAC_SIZE]; - virInterfaceDefPtr def; - virInterfacePtr result = NULL; - - if (!(def = virInterfaceDefParseString(xml))) - goto cleanup; - - /* Now need to get the next free slot number */ - virBufferAddLit(&buf, "lshwres "); - if (system_type == HMC) - virBufferAsprintf(&buf, "-m %s ", managed_system); - - virBufferAsprintf(&buf, - " -r virtualio --rsubtype slot --level slot" - " -Fslot_num --filter lpar_names=%s" - " |sort|tail -n 1", def->name); - if (phypExecInt(session, &buf, conn, &slot) < 0) - goto cleanup; - - /* The next free slot itself: */ - slot++; - - /* Now adding the new network interface */ - virBufferAddLit(&buf, "chhwres "); - if (system_type == HMC) - virBufferAsprintf(&buf, "-m %s ", managed_system); - - virBufferAsprintf(&buf, - " -r virtualio --rsubtype eth" - " -p %s -o a -s %d -a port_vlan_id=1," - "ieee_virtual_eth=0", def->name, slot); - VIR_FREE(ret); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - if (exit_status < 0 || ret != NULL) - goto cleanup; - - /* Need to sleep a little while to wait for the HMC to - * complete the execution of the command. - * */ - sleep(1); - - /* Getting the new interface name */ - virBufferAddLit(&buf, "lshwres "); - if (system_type == HMC) - virBufferAsprintf(&buf, "-m %s ", managed_system); - - virBufferAsprintf(&buf, - " -r virtualio --rsubtype slot --level slot" - " |sed '/lpar_name=%s/!d; /slot_num=%d/!d; " - "s/^.*drc_name=//'", def->name, slot); - VIR_FREE(ret); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - if (exit_status < 0 || ret == NULL) { - /* roll back and excluding interface if error*/ - virBufferAddLit(&buf, "chhwres "); - if (system_type == HMC) - virBufferAsprintf(&buf, "-m %s ", managed_system); - - virBufferAsprintf(&buf, - " -r virtualio --rsubtype eth" - " -p %s -o r -s %d", def->name, slot); - VIR_FREE(ret); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - goto cleanup; - } - - memcpy(name, ret, PHYP_IFACENAME_SIZE-1); - - /* Getting the new interface mac addr */ - virBufferAddLit(&buf, "lshwres "); - if (system_type == HMC) - virBufferAsprintf(&buf, "-m %s ", managed_system); - - virBufferAsprintf(&buf, - "-r virtualio --rsubtype eth --level lpar " - " |sed '/lpar_name=%s/!d; /slot_num=%d/!d; " - "s/^.*mac_addr=//'", def->name, slot); - VIR_FREE(ret); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - if (exit_status < 0 || ret == NULL) - goto cleanup; - - memcpy(mac, ret, PHYP_MAC_SIZE-1); - - result = virGetInterface(conn, name, mac); - - cleanup: - VIR_FREE(ret); - virInterfaceDefFree(def); - return result; -} - -static virInterfacePtr -phypInterfaceLookupByName(virConnectPtr conn, const char *name) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - virBuffer buf = VIR_BUFFER_INITIALIZER; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int exit_status = 0; - char *ret = NULL; - int slot = 0; - int lpar_id = 0; - char mac[PHYP_MAC_SIZE]; - virInterfacePtr result = NULL; - - /*Getting the slot number for the interface */ - virBufferAddLit(&buf, "lshwres "); - if (system_type == HMC) - virBufferAsprintf(&buf, "-m %s ", managed_system); - - virBufferAsprintf(&buf, - " -r virtualio --rsubtype slot --level slot " - " -F drc_name,slot_num |" - " sed -n '/%s/ s/^.*,//p'", name); - if (phypExecInt(session, &buf, conn, &slot) < 0) - goto cleanup; - - /*Getting the lpar_id for the interface */ - virBufferAddLit(&buf, "lshwres "); - if (system_type == HMC) - virBufferAsprintf(&buf, "-m %s ", managed_system); - - virBufferAsprintf(&buf, - " -r virtualio --rsubtype slot --level slot " - " -F drc_name,lpar_id |" - " sed -n '/%s/ s/^.*,//p'", name); - if (phypExecInt(session, &buf, conn, &lpar_id) < 0) - goto cleanup; - - /*Getting the interface mac */ - virBufferAddLit(&buf, "lshwres "); - if (system_type == HMC) - virBufferAsprintf(&buf, "-m %s ", managed_system); - - virBufferAsprintf(&buf, - " -r virtualio --rsubtype eth --level lpar " - " -F lpar_id,slot_num,mac_addr|" - " sed -n '/%d,%d/ s/^.*,//p'", lpar_id, slot); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - if (exit_status < 0 || ret == NULL) - goto cleanup; - - memcpy(mac, ret, PHYP_MAC_SIZE-1); - - result = virGetInterface(conn, name, ret); - - cleanup: - VIR_FREE(ret); - return result; -} - -static int -phypInterfaceIsActive(virInterfacePtr iface) -{ - phyp_driverPtr phyp_driver = iface->conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - virBuffer buf = VIR_BUFFER_INITIALIZER; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int state = -1; - - virBufferAddLit(&buf, "lshwres "); - if (system_type == HMC) - virBufferAsprintf(&buf, "-m %s ", managed_system); - - virBufferAsprintf(&buf, - " -r virtualio --rsubtype eth --level lpar " - " -F mac_addr,state |" - " sed -n '/%s/ s/^.*,//p'", iface->mac); - phypExecInt(session, &buf, iface->conn, &state); - return state; -} - -static int -phypConnectListInterfaces(virConnectPtr conn, char **const names, int nnames) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - char *managed_system = phyp_driver->managed_system; - int vios_id = phyp_driver->vios_id; - int exit_status = 0; - int got = 0; - size_t i; - char *ret = NULL; - char *networks = NULL; - char *char_ptr = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - bool success = false; - - virBufferAddLit(&buf, "lshwres"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, " -r virtualio --rsubtype slot --level slot|" - " sed '/eth/!d; /lpar_id=%d/d; s/^.*drc_name=//g'", - vios_id); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - /* I need to parse the textual return in order to get the network - * interfaces */ - if (exit_status < 0 || ret == NULL) - goto cleanup; - - networks = ret; - - while (got < nnames) { - char_ptr = strchr(networks, '\n'); - - if (char_ptr) { - *char_ptr = '\0'; - names[got++] = g_strdup(networks); - char_ptr++; - networks = char_ptr; - } else { - break; - } - } - - cleanup: - if (!success) { - for (i = 0; i < got; i++) - VIR_FREE(names[i]); - } - VIR_FREE(ret); - return got; -} - -static int -phypConnectNumOfInterfaces(virConnectPtr conn) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - char *managed_system = phyp_driver->managed_system; - int system_type = phyp_driver->system_type; - int vios_id = phyp_driver->vios_id; - int nnets = -1; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - virBufferAddLit(&buf, "lshwres "); - if (system_type == HMC) - virBufferAsprintf(&buf, "-m %s ", managed_system); - - virBufferAsprintf(&buf, - "-r virtualio --rsubtype eth --level lpar|" - "grep -v lpar_id=%d|grep -c lpar_name", vios_id); - phypExecInt(session, &buf, conn, &nnets); - return nnets; -} - -static int -phypGetLparState(virConnectPtr conn, unsigned int lpar_id) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - char *ret = NULL; - int exit_status = 0; - char *managed_system = phyp_driver->managed_system; - int state = VIR_DOMAIN_NOSTATE; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - virBufferAddLit(&buf, "lssyscfg -r lpar"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, " -F state --filter lpar_ids=%d", lpar_id); - ret = phypExecBuffer(session, &buf, &exit_status, conn, true); - - if (exit_status < 0 || ret == NULL) - goto cleanup; - - 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; - - cleanup: - VIR_FREE(ret); - return state; -} - -/* XXX - is this needed? */ -static int phypDiskType(virConnectPtr, char *) G_GNUC_UNUSED; -static int -phypDiskType(virConnectPtr conn, char *backing_device) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - char *ret = NULL; - int exit_status = 0; - char *managed_system = phyp_driver->managed_system; - int vios_id = phyp_driver->vios_id; - int disk_type = -1; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - virBufferAddLit(&buf, "viosvrcmd"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, " -p %d -c \"lssp -field name type " - "-fmt , -all|sed -n '/%s/ {\n s/^.*,//\n p\n}'\"", - vios_id, backing_device); - ret = phypExecBuffer(session, &buf, &exit_status, conn, true); - - if (exit_status < 0 || ret == NULL) - goto cleanup; - - if (STREQ(ret, "LVPOOL")) - disk_type = VIR_STORAGE_TYPE_BLOCK; - else if (STREQ(ret, "FBPOOL")) - disk_type = VIR_STORAGE_TYPE_FILE; - - cleanup: - VIR_FREE(ret); - return disk_type; -} - -static int -phypConnectNumOfDefinedDomains(virConnectPtr conn) -{ - return phypConnectNumOfDomainsGeneric(conn, 1); -} - -static int -phypConnectNumOfDomains(virConnectPtr conn) -{ - return phypConnectNumOfDomainsGeneric(conn, 0); -} - -static int -phypConnectListDomains(virConnectPtr conn, int *ids, int nids) -{ - return phypConnectListDomainsGeneric(conn, ids, nids, 0); -} - -static int -phypConnectListDefinedDomains(virConnectPtr conn, char **const names, int nnames) -{ - bool success = false; - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - char *managed_system = phyp_driver->managed_system; - int exit_status = 0; - int got = 0; - size_t i; - char *ret = NULL; - char *domains = NULL; - char *char_ptr = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - virBufferAddLit(&buf, "lssyscfg -r lpar"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAddLit(&buf, " -F name,state" - "|sed -n '/Not Activated/ {\n s/,.*$//\n p\n}'"); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - /* I need to parse the textual return in order to get the domains */ - if (exit_status < 0 || ret == NULL) { - goto cleanup; - } else { - domains = ret; - - while (got < nnames) { - char_ptr = strchr(domains, '\n'); - - if (char_ptr) { - *char_ptr = '\0'; - names[got++] = g_strdup(domains); - char_ptr++; - domains = char_ptr; - } else { - break; - } - } - } - - success = true; - - cleanup: - if (!success) { - for (i = 0; i < got; i++) - VIR_FREE(names[i]); - - got = -1; - } - VIR_FREE(ret); - return got; -} - -static virDomainPtr -phypDomainLookupByName(virConnectPtr conn, const char *lpar_name) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int lpar_id = 0; - char *managed_system = phyp_driver->managed_system; - unsigned char lpar_uuid[VIR_UUID_BUFLEN]; - - lpar_id = phypGetLparID(session, managed_system, lpar_name, conn); - if (lpar_id == -1) - return NULL; - - if (phypGetLparUUID(lpar_uuid, lpar_id, conn) == -1) - return NULL; - - return virGetDomain(conn, lpar_name, lpar_uuid, lpar_id); -} - -static virDomainPtr -phypDomainLookupByID(virConnectPtr conn, int lpar_id) -{ - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - virDomainPtr dom = NULL; - char *managed_system = phyp_driver->managed_system; - unsigned char lpar_uuid[VIR_UUID_BUFLEN]; - - char *lpar_name = phypGetLparNAME(session, managed_system, lpar_id, - conn); - - if (phypGetLparUUID(lpar_uuid, lpar_id, conn) == -1) - goto cleanup; - - dom = virGetDomain(conn, lpar_name, lpar_uuid, lpar_id); - - cleanup: - VIR_FREE(lpar_name); - - return dom; -} - -static char * -phypDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) -{ - phyp_driverPtr phyp_driver = dom->conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - virDomainDef def; - char *managed_system = phyp_driver->managed_system; - unsigned long long memory; - unsigned int vcpus; - - virCheckFlags(VIR_DOMAIN_XML_COMMON_FLAGS, NULL); - - memset(&def, 0, sizeof(virDomainDef)); - - 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_ERROR(_("Unable to determine domain's name.")); - goto err; - } - - if (phypGetLparUUID(def.uuid, dom->id, dom->conn) == -1) { - VIR_ERROR(_("Unable to generate random uuid.")); - goto err; - } - - if ((memory = phypGetLparMem(dom->conn, managed_system, dom->id, 0)) == 0) { - VIR_ERROR(_("Unable to determine domain's max memory.")); - goto err; - } - - virDomainDefSetMemoryTotal(&def, memory); - - if ((def.mem.cur_balloon = - phypGetLparMem(dom->conn, managed_system, dom->id, 1)) == 0) { - VIR_ERROR(_("Unable to determine domain's memory.")); - goto err; - } - - if ((vcpus = phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0) { - VIR_ERROR(_("Unable to determine domain's CPU.")); - goto err; - } - - if (virDomainDefSetVcpusMax(&def, vcpus, phyp_driver->xmlopt) < 0) - goto err; - - if (virDomainDefSetVcpus(&def, vcpus) < 0) - goto err; - - return virDomainDefFormat(&def, phyp_driver->xmlopt, - virDomainDefFormatConvertXMLFlags(flags)); - - err: - return NULL; -} - -static int -phypDomainResume(virDomainPtr dom) -{ - int result = -1; - phyp_driverPtr phyp_driver = dom->conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - char *managed_system = phyp_driver->managed_system; - int exit_status = 0; - char *ret = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - virBufferAddLit(&buf, "chsysstate"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, " -r lpar -o on --id %d -f %s", - dom->id, dom->name); - ret = phypExecBuffer(session, &buf, &exit_status, dom->conn, false); - - if (exit_status < 0) - goto cleanup; - - result = 0; - - cleanup: - VIR_FREE(ret); - - return result; -} - -static int -phypDomainReboot(virDomainPtr dom, unsigned int flags) -{ - int result = -1; - virConnectPtr conn = dom->conn; - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - char *managed_system = phyp_driver->managed_system; - int exit_status = 0; - char *ret = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - virCheckFlags(0, -1); - - virBufferAddLit(&buf, "chsysstate"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, - " -r lpar -o shutdown --id %d --immed --restart", - dom->id); - ret = phypExecBuffer(session, &buf, &exit_status, dom->conn, false); - - if (exit_status < 0) - goto cleanup; - - result = 0; - - cleanup: - VIR_FREE(ret); - - return result; -} - -static int -phypDomainShutdownFlags(virDomainPtr dom, unsigned int flags) -{ - int result = -1; - virConnectPtr conn = dom->conn; - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - char *managed_system = phyp_driver->managed_system; - int exit_status = 0; - char *ret = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - virCheckFlags(0, -1); - - virBufferAddLit(&buf, "chsysstate"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, " -r lpar -o shutdown --id %d", dom->id); - ret = phypExecBuffer(session, &buf, &exit_status, dom->conn, false); - - if (exit_status < 0) - goto cleanup; - - result = 0; - - cleanup: - VIR_FREE(ret); - - return result; -} - -static int -phypDomainShutdown(virDomainPtr dom) -{ - return phypDomainShutdownFlags(dom, 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_WARN("Unable to determine domain's max memory."); - - if ((info->memory = - phypGetLparMem(dom->conn, managed_system, dom->id, 1)) == 0) - VIR_WARN("Unable to determine domain's memory."); - - if ((info->nrVirtCpu = - phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0) - VIR_WARN("Unable to determine domain's CPU."); - - return 0; -} - -static int -phypDomainGetState(virDomainPtr dom, - int *state, - int *reason, - unsigned int flags) -{ - virCheckFlags(0, -1); - - *state = phypGetLparState(dom->conn, dom->id); - if (reason) - *reason = 0; - - return 0; -} - -static int -phypDomainDestroyFlags(virDomainPtr dom, - unsigned int flags) -{ - int result = -1; - phyp_driverPtr phyp_driver = dom->conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - char *managed_system = phyp_driver->managed_system; - int exit_status = 0; - char *ret = NULL; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - virCheckFlags(0, -1); - - virBufferAddLit(&buf, "rmsyscfg"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, " -r lpar --id %d", dom->id); - ret = phypExecBuffer(session, &buf, &exit_status, dom->conn, false); - - if (exit_status < 0) - goto cleanup; - - if (phypUUIDTable_RemLpar(dom->conn, dom->id) == -1) - goto cleanup; - - dom->id = -1; - result = 0; - - cleanup: - VIR_FREE(ret); - - return result; -} - -static int -phypDomainDestroy(virDomainPtr dom) -{ - return phypDomainDestroyFlags(dom, 0); -} - -static int -phypBuildLpar(virConnectPtr conn, virDomainDefPtr def) -{ - int result = -1; - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - char *managed_system = phyp_driver->managed_system; - char *ret = NULL; - int exit_status = 0; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (!def->mem.cur_balloon) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Field on the domain XML file is " - "missing or has invalid value")); - goto cleanup; - } - - if (!virDomainDefGetMemoryInitial(def)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Field on the domain XML file is missing or " - "has invalid value")); - goto cleanup; - } - - if (def->ndisks < 1) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Domain XML must contain at least one element.")); - goto cleanup; - } - - if (!virDomainDiskGetSource(def->disks[0])) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Field under on the domain XML file is " - "missing.")); - goto cleanup; - } - - virBufferAddLit(&buf, "mksyscfg"); - if (system_type == HMC) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&buf, " -r lpar -p %s -i min_mem=%lld,desired_mem=%lld," - "max_mem=%lld,desired_procs=%u,virtual_scsi_adapters=%s", - def->name, def->mem.cur_balloon, - def->mem.cur_balloon, - virDomainDefGetMemoryInitial(def), - virDomainDefGetVcpus(def), - virDomainDiskGetSource(def->disks[0])); - ret = phypExecBuffer(session, &buf, &exit_status, conn, false); - - if (exit_status < 0) { - VIR_ERROR(_("Unable to create LPAR. Reason: '%s'"), NULLSTR(ret)); - goto cleanup; - } - - if (phypUUIDTable_AddLpar(conn, def->uuid, def->id) == -1) { - VIR_ERROR(_("Unable to add LPAR to the table")); - goto cleanup; - } - - result = 0; - - cleanup: - VIR_FREE(ret); - - return result; -} - -static virDomainPtr -phypDomainCreateXML(virConnectPtr conn, - const char *xml, unsigned int flags) -{ - virCheckFlags(0, NULL); - - phyp_driverPtr phyp_driver = conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - virDomainDefPtr def = NULL; - virDomainPtr dom = NULL; - uuid_tablePtr uuid_table = phyp_driver->uuid_table; - lparPtr *lpars = uuid_table->lpars; - size_t i = 0; - char *managed_system = phyp_driver->managed_system; - unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE; - - virCheckFlags(VIR_DOMAIN_START_VALIDATE, NULL); - - if (flags & VIR_DOMAIN_START_VALIDATE) - parse_flags |= VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA; - - if (!(def = virDomainDefParseString(xml, - phyp_driver->xmlopt, - NULL, - parse_flags))) - goto err; - - /* checking if this name already exists on this system */ - if (phypGetLparID(session, managed_system, def->name, conn) != -1) { - VIR_WARN("LPAR name already exists."); - goto err; - } - - /* checking if ID or UUID already exists on this system */ - for (i = 0; i < uuid_table->nlpars; i++) { - if (lpars[i]->id == def->id || lpars[i]->uuid == def->uuid) { - VIR_WARN("LPAR ID or UUID already exists."); - goto err; - } - } - - if ((dom = virGetDomain(conn, def->name, def->uuid, def->id)) == NULL) - goto err; - - if (phypBuildLpar(conn, def) == -1) - goto err; - - if (phypDomainResume(dom) == -1) - goto err; - - return dom; - - err: - virDomainDefFree(def); - virObjectUnref(dom); - return NULL; -} - -static char * -phypConnectGetCapabilities(virConnectPtr conn) -{ - phyp_driverPtr phyp_driver = conn->privateData; - - return virCapabilitiesFormatXML(phyp_driver->caps); -} - -static int -phypDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, - unsigned int flags) -{ - phyp_driverPtr phyp_driver = dom->conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - int system_type = phyp_driver->system_type; - char *managed_system = phyp_driver->managed_system; - int exit_status = 0; - char *ret = NULL; - char operation; - unsigned long ncpus = 0; - unsigned int amount = 0; - virBuffer buf = VIR_BUFFER_INITIALIZER; - - if (flags != VIR_DOMAIN_VCPU_LIVE) { - virReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags); - return -1; - } - - if ((ncpus = phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0) - return 0; - - if (nvcpus > phypDomainGetMaxVcpus(dom)) { - VIR_ERROR(_("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) - virBufferAsprintf(&buf, " -m %s", managed_system); - virBufferAsprintf(&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); - ret = phypExecBuffer(session, &buf, &exit_status, dom->conn, false); - - if (exit_status < 0) { - VIR_ERROR(_ - ("Possibly you don't have IBM Tools installed in your LPAR." - " Contact your support to enable this feature.")); - } - - VIR_FREE(ret); - return 0; - -} - -static int -phypDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus) -{ - return phypDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_VCPU_LIVE); -} - -static int -phypDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags) -{ - phyp_driverPtr phyp_driver = dom->conn->privateData; - LIBSSH2_SESSION *session = phyp_driver->session; - char *managed_system = phyp_driver->managed_system; - char *lpar_name = NULL; - int ret = -1; - - virCheckFlags(0, -1); - - lpar_name = phypGetLparNAME(session, managed_system, dom->id, dom->conn); - - if (lpar_name == NULL) { - VIR_ERROR(_("Unable to determine domain's name.")); - goto cleanup; - } - - ret = 0; - - cleanup: - VIR_FREE(lpar_name); - return ret; -} - -static virHypervisorDriver phypHypervisorDriver = { - .name = "PHYP", - .connectOpen = phypConnectOpen, /* 0.7.0 */ - .connectClose = phypConnectClose, /* 0.7.0 */ - .connectGetCapabilities = phypConnectGetCapabilities, /* 0.7.3 */ - .connectListDomains = phypConnectListDomains, /* 0.7.0 */ - .connectNumOfDomains = phypConnectNumOfDomains, /* 0.7.0 */ - .domainCreateXML = phypDomainCreateXML, /* 0.7.3 */ - .domainLookupByID = phypDomainLookupByID, /* 0.7.0 */ - .domainLookupByName = phypDomainLookupByName, /* 0.7.0 */ - .domainResume = phypDomainResume, /* 0.7.0 */ - .domainShutdown = phypDomainShutdown, /* 0.7.0 */ - .domainShutdownFlags = phypDomainShutdownFlags, /* 5.6.0 */ - .domainReboot = phypDomainReboot, /* 0.9.1 */ - .domainDestroy = phypDomainDestroy, /* 0.7.3 */ - .domainDestroyFlags = phypDomainDestroyFlags, /* 0.9.4 */ - .domainGetInfo = phypDomainGetInfo, /* 0.7.0 */ - .domainGetState = phypDomainGetState, /* 0.9.2 */ - .domainSetVcpus = phypDomainSetVcpus, /* 0.7.3 */ - .domainSetVcpusFlags = phypDomainSetVcpusFlags, /* 0.8.5 */ - .domainGetVcpusFlags = phypDomainGetVcpusFlags, /* 0.8.5 */ - .domainGetMaxVcpus = phypDomainGetMaxVcpus, /* 0.7.3 */ - .domainGetXMLDesc = phypDomainGetXMLDesc, /* 0.7.0 */ - .connectListDefinedDomains = phypConnectListDefinedDomains, /* 0.7.0 */ - .connectNumOfDefinedDomains = phypConnectNumOfDefinedDomains, /* 0.7.0 */ - .domainAttachDevice = phypDomainAttachDevice, /* 0.8.2 */ - .domainAttachDeviceFlags = phypDomainAttachDeviceFlags, /* 5.6.0 */ - .connectIsEncrypted = phypConnectIsEncrypted, /* 0.7.3 */ - .connectIsSecure = phypConnectIsSecure, /* 0.7.3 */ - .domainIsUpdated = phypDomainIsUpdated, /* 0.8.6 */ - .connectIsAlive = phypConnectIsAlive, /* 0.9.8 */ - .domainHasManagedSaveImage = phypDomainHasManagedSaveImage, /* 1.2.13 */ -}; - -static virStorageDriver phypStorageDriver = { - .connectNumOfStoragePools = phypConnectNumOfStoragePools, /* 0.8.2 */ - .connectListStoragePools = phypConnectListStoragePools, /* 0.8.2 */ - .storagePoolLookupByName = phypStoragePoolLookupByName, /* 0.8.2 */ - .storagePoolLookupByUUID = phypStoragePoolLookupByUUID, /* 0.8.2 */ - .storagePoolCreateXML = phypStoragePoolCreateXML, /* 0.8.2 */ - .storagePoolDestroy = phypStoragePoolDestroy, /* 0.8.2 */ - .storagePoolGetXMLDesc = phypStoragePoolGetXMLDesc, /* 0.8.2 */ - .storagePoolNumOfVolumes = phypStoragePoolNumOfVolumes, /* 0.8.2 */ - .storagePoolListVolumes = phypStoragePoolListVolumes, /* 0.8.2 */ - - .storageVolLookupByName = phypStorageVolLookupByName, /* 0.8.2 */ - .storageVolLookupByPath = phypStorageVolLookupByPath, /* 0.8.2 */ - .storageVolCreateXML = phypStorageVolCreateXML, /* 0.8.2 */ - .storageVolGetXMLDesc = phypStorageVolGetXMLDesc, /* 0.8.2 */ - .storageVolGetPath = phypStorageVolGetPath, /* 0.8.2 */ -}; - -static virInterfaceDriver phypInterfaceDriver = { - .connectNumOfInterfaces = phypConnectNumOfInterfaces, /* 0.9.1 */ - .connectListInterfaces = phypConnectListInterfaces, /* 0.9.1 */ - .interfaceLookupByName = phypInterfaceLookupByName, /* 0.9.1 */ - .interfaceDefineXML = phypInterfaceDefineXML, /* 0.9.1 */ - .interfaceDestroy = phypInterfaceDestroy, /* 0.9.1 */ - .interfaceIsActive = phypInterfaceIsActive /* 0.9.1 */ -}; - -static virConnectDriver phypConnectDriver = { - .remoteOnly = true, - .uriSchemes = (const char *[]){ "phyp", NULL }, - .hypervisorDriver = &phypHypervisorDriver, - .interfaceDriver = &phypInterfaceDriver, - .storageDriver = &phypStorageDriver, -}; - -int -phypRegister(void) -{ - return virRegisterConnectDriver(&phypConnectDriver, - false); -} diff --git a/src/phyp/phyp_driver.h b/src/phyp/phyp_driver.h deleted file mode 100644 index d7076e3697..0000000000 --- a/src/phyp/phyp_driver.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2010, 2013 Red Hat, Inc. - * Copyright IBM Corp. 2009 - * - * phyp_driver.c: ssh layer to access Power Hypervisors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - */ - -#pragma once - -int phypRegister(void); diff --git a/tools/virsh.c b/tools/virsh.c index e70711f5d2..9fb9ed6430 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -522,9 +522,6 @@ virshShowVersion(vshControl *ctl G_GNUC_UNUSED) #ifdef WITH_VMWARE vshPrint(ctl, " VMware"); #endif -#ifdef WITH_PHYP - vshPrint(ctl, " PHYP"); -#endif #ifdef WITH_VBOX vshPrint(ctl, " VirtualBox"); #endif