提交 a7a82f98 编写于 作者: E Eduardo Otubo 提交者: Daniel Veillard

First version of the Power Hypervisor driver

Features supported:
- Connects to HMC/VIOS or IVM systems.
- Life cycle commands (resume and shutdown).
- dumpxml
- 'list' and 'list --all'

What is being implemented:
- better and centralized control for UUID
- definexml
- CPU management commands

* src/domain_conf.c src/domain_conf.h: first version of the driver
* configure.in src/Makefile.am include/libvirt/virterror.h
  src/domain_conf.[ch] src/libvirt.c src/virterror.c: glue the driver
  in the general framework
上级 521ac517
...@@ -187,6 +187,10 @@ AC_ARG_WITH([uml], ...@@ -187,6 +187,10 @@ AC_ARG_WITH([uml],
[ --with-uml add UML support (on)],[],[with_uml=yes]) [ --with-uml add UML support (on)],[],[with_uml=yes])
AC_ARG_WITH([openvz], AC_ARG_WITH([openvz],
[ --with-openvz add OpenVZ support (on)],[],[with_openvz=yes]) [ --with-openvz add OpenVZ support (on)],[],[with_openvz=yes])
AC_ARG_WITH([libssh],
[ --with-libssh=[PFX] libssh location],[],[with_libssh=yes])
AC_ARG_WITH([phyp],
[ --with-phyp=[PFX] add PHYP support (on)],[with_phyp=yes],[with_phyp=check])
AC_ARG_WITH([vbox], AC_ARG_WITH([vbox],
[ --with-vbox add VirtualBox support (on)],[],[with_vbox=yes]) [ --with-vbox add VirtualBox support (on)],[],[with_vbox=yes])
AC_ARG_WITH([lxc], AC_ARG_WITH([lxc],
...@@ -776,7 +780,50 @@ AM_CONDITIONAL([HAVE_NUMACTL], [test "$with_numactl" != "no"]) ...@@ -776,7 +780,50 @@ AM_CONDITIONAL([HAVE_NUMACTL], [test "$with_numactl" != "no"])
AC_SUBST([NUMACTL_CFLAGS]) AC_SUBST([NUMACTL_CFLAGS])
AC_SUBST([NUMACTL_LIBS]) AC_SUBST([NUMACTL_LIBS])
if test "$with_libssh" != "yes" -a "$with_libssh" != "no"; then
libssh_path="$with_libssh"
elif test "$with_libssh" = "yes"; then
libssh_path="/usr/local/lib/"
elif test "$with_libssh" = "no"; then
with_phyp="no";
fi
if test "$with_phyp" = "check"; then
AC_CHECK_LIB([ssh],[ssh_new],[
LIBSSH_LIBS="$LIBSSH_LIBS -lssh -L$libssh_path"
AC_SUBST([LIBSSH_LIBS])],[
with_phyp="no"
with_libssh="no";
],[])
if test "$with_phyp" != "no"; then
AC_CHECK_HEADERS([libssh/libssh.h],[
with_phyp="yes"
LIBSSH_CFLAGS="-I/usr/local/include/libssh"
AC_SUBST([LIBSSH_CFLAGS])
AC_DEFINE_UNQUOTED([WITH_PHYP], 1,
[whether IBM HMC / IVM driver is enabled])
],[
with_phyp="no"
with_libssh="no";
],[])
fi
elif test "$with_phyp" = "yes"; then
AC_CHECK_LIB([ssh],[ssh_new],[
LIBSSH_LIBS="$LIBSSH_LIBS -lssh -L$libssh_path"
AC_SUBST([LIBSSH_LIBS])],[
AC_MSG_ERROR([You must install the libssh to compile Phype driver.])
])
AC_CHECK_HEADERS([libssh/libssh.h],[
LIBSSH_CFLAGS="-I/usr/local/include/libssh"
AC_SUBST([LIBSSH_CFLAGS])],[
AC_MSG_ERROR([Cannot find libssh headers.Is libssh installed ?])
],[])
AC_DEFINE_UNQUOTED([WITH_PHYP], 1,
[whether IBM HMC / IVM driver is enabled])
fi
AM_CONDITIONAL([WITH_PHYP],[test "$with_phyp" = "yes"])
dnl libcap-ng dnl libcap-ng
AC_ARG_WITH([capng], AC_ARG_WITH([capng],
...@@ -1518,6 +1565,7 @@ AC_MSG_NOTICE([ UML: $with_uml]) ...@@ -1518,6 +1565,7 @@ AC_MSG_NOTICE([ UML: $with_uml])
AC_MSG_NOTICE([ OpenVZ: $with_openvz]) AC_MSG_NOTICE([ OpenVZ: $with_openvz])
AC_MSG_NOTICE([ VBox: $with_vbox]) AC_MSG_NOTICE([ VBox: $with_vbox])
AC_MSG_NOTICE([ LXC: $with_lxc]) AC_MSG_NOTICE([ LXC: $with_lxc])
AC_MSG_NOTICE([ PHYP: $with_phyp])
AC_MSG_NOTICE([ ONE: $with_one]) AC_MSG_NOTICE([ ONE: $with_one])
AC_MSG_NOTICE([ ESX: $with_esx]) AC_MSG_NOTICE([ ESX: $with_esx])
AC_MSG_NOTICE([ Test: $with_test]) AC_MSG_NOTICE([ Test: $with_test])
...@@ -1556,6 +1604,11 @@ AC_MSG_NOTICE([]) ...@@ -1556,6 +1604,11 @@ AC_MSG_NOTICE([])
AC_MSG_NOTICE([Libraries]) AC_MSG_NOTICE([Libraries])
AC_MSG_NOTICE([]) AC_MSG_NOTICE([])
AC_MSG_NOTICE([ libxml: $LIBXML_CFLAGS $LIBXML_LIBS]) AC_MSG_NOTICE([ libxml: $LIBXML_CFLAGS $LIBXML_LIBS])
if test "$with_libssh" != "no" ; then
AC_MSG_NOTICE([ libssh: $LIBSSH_CFLAGS $LIBSSH_LIBS])
else
AC_MSG_NOTICE([ libssh: no])
fi
AC_MSG_NOTICE([ gnutls: $GNUTLS_CFLAGS $GNUTLS_LIBS]) AC_MSG_NOTICE([ gnutls: $GNUTLS_CFLAGS $GNUTLS_LIBS])
if test "$with_sasl" != "no" ; then if test "$with_sasl" != "no" ; then
AC_MSG_NOTICE([ sasl: $SASL_CFLAGS $SASL_LIBS]) AC_MSG_NOTICE([ sasl: $SASL_CFLAGS $SASL_LIBS])
......
...@@ -123,9 +123,10 @@ ...@@ -123,9 +123,10 @@
<p> <p>
Jim Mereying was maintaining a CVS to git mirror on Jim Mereying was maintaining a CVS to git mirror on
<a href="http://git.et.redhat.com/?p=libvirt.git">git.et.redhat.com</a>. <a href="http://git.et.redhat.com/?p=libvirt.git">git.et.redhat.com</a>.
Existing users should migrate to the new git server, as the Existing users should migrate to the new libvirt.org git server, as the
old one will be deprecated and turned into a mirror of the old one is now deprecated. For the sake of old links including now-
libvirt.org one. It's available as: rewritten SHA1s, we'll leave the old repository on-line for some time.
It is available as:
</p> </p>
<pre> <pre>
......
...@@ -53,19 +53,20 @@ typedef enum { ...@@ -53,19 +53,20 @@ typedef enum {
VIR_FROM_REMOTE, /* Error from remote driver */ VIR_FROM_REMOTE, /* Error from remote driver */
VIR_FROM_OPENVZ, /* Error from OpenVZ driver */ VIR_FROM_OPENVZ, /* Error from OpenVZ driver */
VIR_FROM_XENXM, /* Error at Xen XM layer */ VIR_FROM_XENXM, /* Error at Xen XM layer */
VIR_FROM_STATS_LINUX, /* Error in the Linux Stats code */ VIR_FROM_STATS_LINUX,/* Error in the Linux Stats code */
VIR_FROM_LXC, /* Error from Linux Container driver */ VIR_FROM_LXC, /* Error from Linux Container driver */
VIR_FROM_STORAGE, /* Error from storage driver */ VIR_FROM_STORAGE, /* Error from storage driver */
VIR_FROM_NETWORK, /* Error from network config */ VIR_FROM_NETWORK, /* Error from network config */
VIR_FROM_DOMAIN, /* Error from domain config */ VIR_FROM_DOMAIN, /* Error from domain config */
VIR_FROM_UML, /* Error at the UML driver */ VIR_FROM_UML, /* Error at the UML driver */
VIR_FROM_NODEDEV, /* Error from node device monitor */ VIR_FROM_NODEDEV, /* Error from node device monitor */
VIR_FROM_XEN_INOTIFY, /* Error from xen inotify layer */ VIR_FROM_XEN_INOTIFY,/* Error from xen inotify layer */
VIR_FROM_SECURITY, /* Error from security framework */ VIR_FROM_SECURITY, /* Error from security framework */
VIR_FROM_VBOX, /* Error from VirtualBox driver */ VIR_FROM_VBOX, /* Error from VirtualBox driver */
VIR_FROM_INTERFACE, /* Error when operating on an interface */ VIR_FROM_INTERFACE, /* Error when operating on an interface */
VIR_FROM_ONE, /* Error from OpenNebula driver */ VIR_FROM_ONE, /* Error from OpenNebula driver */
VIR_FROM_ESX, /* Error from ESX driver */ VIR_FROM_ESX, /* Error from ESX driver */
VIR_FROM_PHYP, /* Error from IBM power hypervisor */
} virErrorDomain; } virErrorDomain;
......
...@@ -6,6 +6,7 @@ INCLUDES = \ ...@@ -6,6 +6,7 @@ INCLUDES = \
-I@top_srcdir@/include \ -I@top_srcdir@/include \
-I@top_srcdir@/qemud \ -I@top_srcdir@/qemud \
$(LIBXML_CFLAGS) \ $(LIBXML_CFLAGS) \
$(LIBSSH_CFLAGS) \
$(XEN_CFLAGS) \ $(XEN_CFLAGS) \
$(SELINUX_CFLAGS) \ $(SELINUX_CFLAGS) \
$(DRIVER_MODULE_CFLAGS) \ $(DRIVER_MODULE_CFLAGS) \
...@@ -129,6 +130,9 @@ LXC_CONTROLLER_SOURCES = \ ...@@ -129,6 +130,9 @@ LXC_CONTROLLER_SOURCES = \
veth.c veth.h \ veth.c veth.h \
cgroup.c cgroup.h cgroup.c cgroup.h
PHYP_DRIVER_SOURCES = \
phyp/phyp_driver.c phyp/phyp_driver.h
OPENVZ_DRIVER_SOURCES = \ OPENVZ_DRIVER_SOURCES = \
openvz_conf.c openvz_conf.h \ openvz_conf.c openvz_conf.h \
openvz_driver.c openvz_driver.h openvz_driver.c openvz_driver.h
...@@ -295,6 +299,18 @@ endif ...@@ -295,6 +299,18 @@ endif
libvirt_driver_xen_la_SOURCES = $(XEN_DRIVER_SOURCES) libvirt_driver_xen_la_SOURCES = $(XEN_DRIVER_SOURCES)
endif endif
if WITH_PHYP
if WITH_DRIVER_MODULES
mod_LTLIBRARIES += libvirt_driver_phyp.la
else
noinst_LTLIBRARIES += libvirt_driver_phyp.la
libvirt_la_LIBADD += libvirt_driver_phyp.la
endif
libvirt_driver_phyp_la_LDFLAGS = $(LIBSSH_LIBS)
libvirt_driver_phyp_la_CFLAGS = $(LIBSSH_CFLAGS)
libvirt_driver_phyp_la_SOURCES = $(PHYP_DRIVER_SOURCES)
endif
if WITH_OPENVZ if WITH_OPENVZ
if WITH_DRIVER_MODULES if WITH_DRIVER_MODULES
mod_LTLIBRARIES += libvirt_driver_openvz.la mod_LTLIBRARIES += libvirt_driver_openvz.la
...@@ -511,6 +527,7 @@ EXTRA_DIST += \ ...@@ -511,6 +527,7 @@ EXTRA_DIST += \
$(UML_DRIVER_SOURCES) \ $(UML_DRIVER_SOURCES) \
$(ONE_DRIVER_SOURCES) \ $(ONE_DRIVER_SOURCES) \
$(OPENVZ_DRIVER_SOURCES) \ $(OPENVZ_DRIVER_SOURCES) \
$(PHYP_DRIVER_SOURCES) \
$(VBOX_DRIVER_SOURCES) \ $(VBOX_DRIVER_SOURCES) \
$(ESX_DRIVER_SOURCES) \ $(ESX_DRIVER_SOURCES) \
$(NETWORK_DRIVER_SOURCES) \ $(NETWORK_DRIVER_SOURCES) \
......
...@@ -57,7 +57,8 @@ VIR_ENUM_IMPL(virDomainVirt, VIR_DOMAIN_VIRT_LAST, ...@@ -57,7 +57,8 @@ VIR_ENUM_IMPL(virDomainVirt, VIR_DOMAIN_VIRT_LAST,
"vmware", "vmware",
"hyperv", "hyperv",
"vbox", "vbox",
"one") "one",
"phyp")
VIR_ENUM_IMPL(virDomainBoot, VIR_DOMAIN_BOOT_LAST, VIR_ENUM_IMPL(virDomainBoot, VIR_DOMAIN_BOOT_LAST,
"fd", "fd",
......
...@@ -55,6 +55,7 @@ enum virDomainVirtType { ...@@ -55,6 +55,7 @@ enum virDomainVirtType {
VIR_DOMAIN_VIRT_HYPERV, VIR_DOMAIN_VIRT_HYPERV,
VIR_DOMAIN_VIRT_VBOX, VIR_DOMAIN_VIRT_VBOX,
VIR_DOMAIN_VIRT_ONE, VIR_DOMAIN_VIRT_ONE,
VIR_DOMAIN_VIRT_PHYP,
VIR_DOMAIN_VIRT_LAST, VIR_DOMAIN_VIRT_LAST,
}; };
......
...@@ -23,6 +23,7 @@ typedef enum { ...@@ -23,6 +23,7 @@ typedef enum {
VIR_DRV_VBOX = 8, VIR_DRV_VBOX = 8,
VIR_DRV_ONE = 9, VIR_DRV_ONE = 9,
VIR_DRV_ESX = 10, VIR_DRV_ESX = 10,
VIR_DRV_PHYP = 11,
} virDrvNo; } virDrvNo;
......
...@@ -55,6 +55,9 @@ ...@@ -55,6 +55,9 @@
#ifdef WITH_OPENVZ #ifdef WITH_OPENVZ
#include "openvz_driver.h" #include "openvz_driver.h"
#endif #endif
#ifdef WITH_PHYP
#include "phyp/phyp_driver.h"
#endif
#ifdef WITH_VBOX #ifdef WITH_VBOX
#include "vbox/vbox_driver.h" #include "vbox/vbox_driver.h"
#endif #endif
...@@ -323,6 +326,9 @@ virInitialize(void) ...@@ -323,6 +326,9 @@ virInitialize(void)
#ifdef WITH_OPENVZ #ifdef WITH_OPENVZ
if (openvzRegister() == -1) return -1; if (openvzRegister() == -1) return -1;
#endif #endif
#ifdef WITH_PHYP
if (phypRegister() == -1) return -1;
#endif
#ifdef WITH_VBOX #ifdef WITH_VBOX
if (vboxRegister() == -1) return -1; if (vboxRegister() == -1) return -1;
#endif #endif
...@@ -896,6 +902,10 @@ virGetVersion(unsigned long *libVer, const char *type, ...@@ -896,6 +902,10 @@ virGetVersion(unsigned long *libVer, const char *type,
if (STRCASEEQ(type, "LXC")) if (STRCASEEQ(type, "LXC"))
*typeVer = LIBVIR_VERSION_NUMBER; *typeVer = LIBVIR_VERSION_NUMBER;
#endif #endif
#if WITH_PHYP
if (STRCASEEQ(type, "phyp"))
*typeVer = LIBVIR_VERSION_NUMBER;
#endif
#if WITH_OPENVZ #if WITH_OPENVZ
if (STRCASEEQ(type, "OpenVZ")) if (STRCASEEQ(type, "OpenVZ"))
*typeVer = LIBVIR_VERSION_NUMBER; *typeVer = LIBVIR_VERSION_NUMBER;
......
/*
* Copyright IBM Corp. 2009
*
* phyp_driver.c: ssh layer to access Power Hypervisors
*
* Authors:
* Eduardo Otubo <otubo at linux.vnet.ibm.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <config.h>
#include <sys/types.h>
#include <limits.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <libssh/libssh.h>
#include "internal.h"
#include "util.h"
#include "datatypes.h"
#include "buf.h"
#include "memory.h"
#include "logging.h"
#include "driver.h"
#include "libvirt/libvirt.h"
#include "virterror_internal.h"
#include "uuid.h"
#include "domain_conf.h"
#include "phyp_driver.h"
#define VIR_FROM_THIS VIR_FROM_PHYP
/*
* URI: phyp://user@[hmc|ivm]/managed_system
* */
static virDrvOpenStatus
phypOpen(virConnectPtr conn,
virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
{
SSH_SESSION *session;
ConnectionData *connection_data;
char string[strlen(conn->uri->path)];
uuid_dbPtr uuid_db = NULL;
if (VIR_ALLOC(uuid_db) < 0)
virReportOOMError(conn);
if (VIR_ALLOC(connection_data) < 0)
virReportOOMError(conn);
if (!conn || !conn->uri)
return VIR_DRV_OPEN_DECLINED;
if (conn->uri->scheme == NULL || STRNEQ(conn->uri->scheme, "phyp"))
return VIR_DRV_OPEN_DECLINED;
if (conn->uri->server == NULL) {
virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP,
VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, "%s",
_("Missing server name in phyp:// URI"));
return VIR_DRV_OPEN_ERROR;
}
if (conn->uri->path == NULL) {
virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP,
VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, "%s",
_("Missing path name in phyp:// URI"));
return VIR_DRV_OPEN_ERROR;
}
if (escape_specialcharacters(conn->uri->path, string) == -1) {
virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP,
VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, "%s",
_("Error parsing 'path'. Invalid characters."));
return VIR_DRV_OPEN_ERROR;
}
if ((session = openSSHSession(conn, auth)) == NULL) {
virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP,
VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, "%s",
_("Error while opening SSH session."));
return VIR_DRV_OPEN_ERROR;
}
conn->uri->path = string;
connection_data->session = session;
connection_data->auth = auth;
uuid_db->nlpars = 0;
uuid_db->lpars = NULL;
conn->privateData = uuid_db;
conn->networkPrivateData = connection_data;
init_uuid_db(conn);
return VIR_DRV_OPEN_SUCCESS;
}
static int
phypClose(virConnectPtr conn)
{
ConnectionData *connection_data = conn->networkPrivateData;
SSH_SESSION *ssh_session = connection_data->session;
ssh_disconnect(ssh_session);
VIR_FREE(connection_data);
return 0;
}
SSH_SESSION *
openSSHSession(virConnectPtr conn, virConnectAuthPtr auth)
{
SSH_SESSION *session;
SSH_OPTIONS *opt;
char *user = conn->uri->user;
char *host = conn->uri->server;
int ssh_auth = 0;
char *banner;
int port = 22;
char *password;
if (conn->uri->port)
port = conn->uri->port;
session = ssh_new();
opt = ssh_options_new();
/*setting some ssh options */
ssh_options_set_host(opt, host);
ssh_options_set_port(opt, port);
ssh_options_set_username(opt, user);
ssh_set_options(session, opt);
/*starting ssh connection */
if (ssh_connect(session)) {
virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP, VIR_ERR_ERROR,
NULL, NULL, NULL, 0, 0, "%s",
_("Connection failed."));
ssh_disconnect(session);
ssh_finalize();
goto err;
}
/*trying to use pub key */
if ((ssh_auth =
ssh_userauth_autopubkey(session, NULL)) == SSH_AUTH_ERROR) {
VIR_WARN("%s", "Authentication with public key failed.");
}
if ((banner = ssh_get_issue_banner(session))) {
VIR_INFO("%s", banner);
VIR_FREE(banner);
}
if (ssh_auth != SSH_AUTH_SUCCESS) {
int i;
int hasPassphrase = 0;
int auth_check = 0;
virConnectCredential creds[] = {
{VIR_CRED_PASSPHRASE, "password", "Password", NULL, NULL, 0},
};
if (!auth || !auth->cb) {
virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP,
VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, "%s",
_("No authentication callback provided."));
goto err;
}
for (i = 0; i < auth->ncredtype; i++) {
if (auth->credtype[i] == VIR_CRED_PASSPHRASE)
hasPassphrase = 1;
}
if (!hasPassphrase) {
virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP,
VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, "%s",
_("Required credentials are not supported."));
goto err;
}
int res =
(auth->cb) (creds, ARRAY_CARDINALITY(creds), auth->cbdata);
if (res < 0) {
virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP,
VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, "%s",
_("Unable to fetch credentials."));
goto err;
}
if (creds[0].result)
password = creds[0].result;
else {
virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP,
VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, "%s : %s",
"Unable to get password certificate.",
ssh_get_error(session));
ssh_disconnect(session);
goto err;
}
char *username = user;
auth_check = ssh_userauth_password(session, username, password);
memset(password, 0, strlen(password));
if (auth_check != SSH_AUTH_SUCCESS) {
virRaiseError(conn, NULL, NULL, 0, VIR_FROM_PHYP,
VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, "%s : %s",
"Authentication failed.",
ssh_get_error(session));
ssh_disconnect(session);
goto err;
} else
goto exit;
} else
goto exit;
err:
return NULL;
exit:
return session;
}
/* this functions is the layer that manipulates the ssh channel itself
* and executes the commands on the remote machine */
static char *
phypExec(SSH_SESSION * session, char *cmd, int *exit_status,
virConnectPtr conn)
{
CHANNEL *channel = channel_new(session);
virBuffer tex_ret = VIR_BUFFER_INITIALIZER;
char buf[4096] = { 0 };
int ret = 0;
if (channel_open_session(channel) == SSH_ERROR) {
virRaiseError(NULL, NULL, NULL, 0, VIR_FROM_PHYP,
VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, "%s",
_("Unable to open a SSH channel."));
goto err;
}
if (channel_request_exec(channel, cmd) == SSH_ERROR) {
virRaiseError(NULL, NULL, NULL, 0, VIR_FROM_PHYP,
VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, "%s",
_("Unable to execute remote command."));
goto err;
}
if (channel_send_eof(channel) == SSH_ERROR) {
virRaiseError(NULL, NULL, NULL, 0, VIR_FROM_PHYP,
VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0, "%s",
_("Unable to send EOF."));
goto err;
}
while (channel && channel_is_open(channel)) {
ret = channel_read(channel, buf, sizeof(buf), 0);
if (ret < 0)
goto err;
if (ret == 0) {
channel_send_eof(channel);
if (channel_get_exit_status(channel) == -1)
goto err;
if (channel_close(channel) == SSH_ERROR)
goto err;
channel_free(channel);
channel = NULL;
goto exit;
}
virBufferAdd(&tex_ret, (const char *) &buf, ret);
}
err:
(*exit_status) = SSH_CMD_ERR;
char *cleanup_buf = virBufferContentAndReset(&tex_ret);
VIR_FREE(cleanup_buf);
return NULL;
exit:
if (virBufferError(&tex_ret)) {
virReportOOMError(conn);
return NULL;
}
return virBufferContentAndReset(&tex_ret);
}
/* return the lpar_id given a name and a managed system name */
static int
phypGetLparID(SSH_SESSION * ssh_session, const char *managed_system,
const char *name, virConnectPtr conn)
{
int exit_status = 0;
int lpar_id = 0;
char *char_ptr;
char *cmd;
if (virAsprintf(&cmd,
"lssyscfg -r lpar -m %s --filter lpar_names=%s -F lpar_id",
managed_system, name) < 0) {
virReportOOMError(conn);
goto err;
}
const char *tex_ret = phypExec(ssh_session, cmd, &exit_status, conn);
if (exit_status < 0 || tex_ret == NULL)
goto err;
if (virStrToLong_i(tex_ret, &char_ptr, 10, &lpar_id) == -1)
goto err;
VIR_FREE(cmd);
return lpar_id;
err:
VIR_FREE(cmd);
return -1;
}
/* return the lpar name given a lpar_id and a managed system name */
static char *
phypGetLparNAME(SSH_SESSION * ssh_session, const char *managed_system,
unsigned int lpar_id, virConnectPtr conn)
{
char *cmd;
int exit_status = 0;
if (virAsprintf(&cmd,
"lssyscfg -r lpar -m %s --filter lpar_ids=%d -F name",
managed_system, lpar_id) < 0) {
virReportOOMError(conn);
goto err;
}
char *lpar_name = phypExec(ssh_session, cmd, &exit_status, conn);
if (lpar_name == NULL)
goto err;
char *char_ptr = strchr(lpar_name, '\n');
if (char_ptr)
*char_ptr = '\0';
if (exit_status < 0 || lpar_name == NULL)
goto err;
VIR_FREE(cmd);
return lpar_name;
err:
VIR_FREE(cmd);
return NULL;
}
/* Search into the uuid_db for a lpar_uuid given a lpar_id
* and a managed system name
*
* return: 0 - record found
* -1 - not found
* */
int
phypGetLparUUID(unsigned char *uuid, int lpar_id, virConnectPtr conn)
{
uuid_dbPtr uuid_db = conn->privateData;
lparPtr *lpars = uuid_db->lpars;
unsigned int i = 0;
for (i = 0; i < uuid_db->nlpars; i++) {
if (lpars[i]->id == lpar_id) {
memmove(uuid, lpars[i]->uuid, VIR_UUID_BUFLEN);
return 0;
}
}
return -1;
}
/*
* type:
* 0 - maxmem
* 1 - memory
* */
unsigned long
phypGetLparMem(virConnectPtr conn, const char *managed_system, int lpar_id,
int type)
{
ConnectionData *connection_data = conn->networkPrivateData;
SSH_SESSION *ssh_session = connection_data->session;
char *cmd;
char *char_ptr;
int memory = 0;
int exit_status = 0;
if (type != 1 && type != 0)
goto err;
if (type) {
if (virAsprintf(&cmd,
"lshwres -m %s -r mem --level lpar -F curr_mem --filter lpar_ids=%d",
managed_system, lpar_id) < 0) {
virReportOOMError(conn);
goto err;
}
} else {
if (virAsprintf(&cmd,
"lshwres -m %s -r mem --level lpar -F curr_max_mem --filter lpar_ids=%d",
managed_system, lpar_id) < 0) {
virReportOOMError(conn);
goto err;
}
}
char *tex_ret = phypExec(ssh_session, cmd, &exit_status, conn);
if (tex_ret == NULL)
goto err;
char *mem_char_ptr = strchr(tex_ret, '\n');
if (mem_char_ptr)
*mem_char_ptr = '\0';
if (exit_status < 0)
goto err;
if (virStrToLong_i(tex_ret, &char_ptr, 10, &memory) == -1)
goto err;
VIR_FREE(cmd);
return memory;
err:
VIR_FREE(cmd);
return 0;
}
unsigned long
phypGetLparCPU(virConnectPtr conn, const char *managed_system, int lpar_id)
{
ConnectionData *connection_data = conn->networkPrivateData;
SSH_SESSION *ssh_session = connection_data->session;
char *cmd;
int exit_status = 0;
int vcpus = 0;
if (virAsprintf(&cmd,
"lshwres -m %s -r proc --level lpar -F curr_procs --filter lpar_ids=%d",
managed_system, lpar_id) < 0) {
virReportOOMError(conn);
goto err;
}
char *tex_ret = phypExec(ssh_session, cmd, &exit_status, conn);
if (tex_ret == NULL)
goto err;
char *char_ptr = strchr(tex_ret, '\n');
if (char_ptr)
*char_ptr = '\0';
if (virStrToLong_i(tex_ret, &char_ptr, 10, &vcpus) == -1)
goto err;
if (exit_status < 0)
goto err;
VIR_FREE(cmd);
return (unsigned long) vcpus;
err:
VIR_FREE(cmd);
return 0;
}
int
phypGetRemoteSlot(virConnectPtr conn, const char *managed_system,
const char *lpar_name)
{
ConnectionData *connection_data = conn->networkPrivateData;
SSH_SESSION *ssh_session = connection_data->session;
char *cmd;
char *char_ptr;
int remote_slot = 0;
int exit_status = 0;
if (virAsprintf(&cmd,
"lshwres -m %s -r virtualio --rsubtype scsi -F remote_slot_num --filter lpar_names=%s",
managed_system, lpar_name) < 0) {
virReportOOMError(conn);
goto err;
}
char *tex_ret = phypExec(ssh_session, cmd, &exit_status, conn);
if (tex_ret == NULL)
goto err;
char *char_ptr2 = strchr(tex_ret, '\n');
if (char_ptr2)
*char_ptr2 = '\0';
if (exit_status < 0)
goto err;
if (virStrToLong_i(tex_ret, &char_ptr, 10, &remote_slot) == -1)
goto err;
VIR_FREE(cmd);
return remote_slot;
err:
VIR_FREE(cmd);
return 0;
}
char *
phypGetBackingDevice(virConnectPtr conn, const char *managed_system,
char *lpar_name)
{
ConnectionData *connection_data = conn->networkPrivateData;
SSH_SESSION *ssh_session = connection_data->session;
char *cmd;
int remote_slot = 0;
int exit_status = 0;
if ((remote_slot =
phypGetRemoteSlot(conn, managed_system, lpar_name)) == 0)
goto err;
if (virAsprintf(&cmd,
"lshwres -m %s -r virtualio --rsubtype scsi -F backing_devices --filter slots=%d",
managed_system, remote_slot) < 0) {
virReportOOMError(conn);
goto err;
}
char *ret = phypExec(ssh_session, cmd, &exit_status, conn);
if (ret == NULL)
goto err;
/* 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 *backing_device = strchr(ret, '/');
if (backing_device) {
backing_device++;
if (backing_device[0] == '/')
backing_device++;
else
goto err;
} else {
backing_device = ret;
}
char *char_ptr = strchr(backing_device, '\n');
if (char_ptr)
*char_ptr = '\0';
if (exit_status < 0 || backing_device == NULL)
goto err;
VIR_FREE(cmd);
return backing_device;
err:
VIR_FREE(cmd);
return NULL;
}
int
phypGetLparState(virConnectPtr conn, unsigned int lpar_id)
{
ConnectionData *connection_data = conn->networkPrivateData;
SSH_SESSION *ssh_session = connection_data->session;
char *cmd;
int exit_status = 0;
char *char_ptr = NULL;
char *managed_system = conn->uri->path;
/* need to shift one byte in order to remove the first "/" of URI component */
if (managed_system[0] == '/')
managed_system++;
/* here we are handling only the first component of the path,
* so skipping the second:
* */
char_ptr = strchr(managed_system, '/');
if (char_ptr)
*char_ptr = '\0';
if (virAsprintf(&cmd,
"lssyscfg -r lpar -m %s -F state --filter lpar_ids=%d",
managed_system, lpar_id) < 0) {
virReportOOMError(conn);
goto err;
}
char *ret = phypExec(ssh_session, cmd, &exit_status, conn);
if (ret == NULL)
goto err;
char_ptr = strchr(ret, '\n');
if (char_ptr)
*char_ptr = '\0';
if (exit_status < 0 || ret == NULL)
goto err;
VIR_FREE(cmd);
if (STREQ(ret, "Running"))
return VIR_DOMAIN_RUNNING;
else if (STREQ(ret, "Not Activated"))
return VIR_DOMAIN_SHUTOFF;
else if (STREQ(ret, "Shutting Down"))
return VIR_DOMAIN_SHUTDOWN;
else
goto err;
err:
VIR_FREE(cmd);
return VIR_DOMAIN_NOSTATE;
}
int
phypDiskType(virConnectPtr conn, char *backing_device)
{
ConnectionData *connection_data = conn->networkPrivateData;
SSH_SESSION *ssh_session = connection_data->session;
char *cmd;
int exit_status = 0;
if (virAsprintf(&cmd,
"ioscli lssp -field name type -fmt , -all|grep %s|sed -e 's/^.*,//g'",
backing_device) < 0) {
virReportOOMError(conn);
goto err;
}
char *ret = phypExec(ssh_session, cmd, &exit_status, conn);
if (ret == NULL)
goto err;
char *char_ptr = strchr(ret, '\n');
if (char_ptr)
*char_ptr = '\0';
if (exit_status < 0 || ret == NULL)
goto err;
VIR_FREE(cmd);
if (STREQ(ret, "LVPOOL"))
return VIR_DOMAIN_DISK_TYPE_BLOCK;
else if (STREQ(ret, "FBPOOL"))
return VIR_DOMAIN_DISK_TYPE_FILE;
else
goto err;
err:
VIR_FREE(cmd);
return -1;
}
/* This is a generic function that won't be used directly by
* libvirt api. The function returns the number of domains
* in different states: Running, Not Activated and all:
*
* type: 0 - Running
* 1 - Not Activated
* * - All
* */
static int
phypNumDomainsGeneric(virConnectPtr conn, unsigned int type)
{
ConnectionData *connection_data = conn->networkPrivateData;
SSH_SESSION *ssh_session = connection_data->session;
int exit_status = 0;
int ndom = 0;
char *char_ptr;
char *cmd;
char *managed_system = conn->uri->path;
const char *state;
if (type == 0)
state = "|grep Running";
else if (type == 1)
state = "|grep \"Not Activated\"";
else
state = " ";
/* need to shift one byte in order to remove the first "/" of URI component */
if (managed_system[0] == '/')
managed_system++;
/* here we are handling only the first component of the path,
* so skipping the second:
* */
char_ptr = strchr(managed_system, '/');
if (char_ptr)
*char_ptr = '\0';
if (virAsprintf(&cmd,
"lssyscfg -r lpar -m %s -F lpar_id,state %s |grep -c ^[0-9]*",
managed_system, state) < 0) {
virReportOOMError(conn);
goto err;
}
char *ret = phypExec(ssh_session, cmd, &exit_status, conn);
if (exit_status < 0 || ret == NULL)
goto err;
if (virStrToLong_i(ret, &char_ptr, 10, &ndom) == -1)
goto err;
VIR_FREE(cmd);
return ndom;
err:
VIR_FREE(cmd);
return 0;
}
static int
phypNumDefinedDomains(virConnectPtr conn)
{
return phypNumDomainsGeneric(conn, 1);
}
static int
phypNumDomains(virConnectPtr conn)
{
return phypNumDomainsGeneric(conn, 0);
}
/* 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
* * - all
* */
static int
phypListDomainsGeneric(virConnectPtr conn, int *ids, int nids,
unsigned int type)
{
ConnectionData *connection_data = conn->networkPrivateData;
SSH_SESSION *ssh_session = connection_data->session;
char *managed_system = conn->uri->path;
int exit_status = 0;
int got = 0;
char *char_ptr;
unsigned int i = 0, j = 0;
char id_c[10];
char *cmd;
const char *state;
if (type == 0)
state = "|grep Running";
else
state = " ";
/* need to shift one byte in order to remove the first "/" of URI component */
if (managed_system[0] == '/')
managed_system++;
/* here we are handling only the first component of the path,
* so skipping the second:
* */
char_ptr = strchr(managed_system, '/');
if (char_ptr)
*char_ptr = '\0';
memset(id_c, 0, 10);
if (virAsprintf
(&cmd,
"lssyscfg -r lpar -m %s -F lpar_id,state %s | sed -e 's/,.*$//g'",
managed_system, state) < 0) {
virReportOOMError(conn);
goto err;
}
char *domains = phypExec(ssh_session, cmd, &exit_status, conn);
/* I need to parse the textual return in order to get the domains */
if (exit_status < 0 || domains == NULL || got == 0)
goto err;
else {
while (got < nids) {
if (domains[i] == '\n') {
if (virStrToLong_i(id_c, &char_ptr, 10, &ids[got]) == -1)
return 0;
memset(id_c, 0, 10);
j = 0;
got++;
} else {
id_c[j] = domains[i];
j++;
}
i++;
}
}
VIR_FREE(cmd);
return got;
err:
VIR_FREE(cmd);
return 0;
}
static int
phypListDomains(virConnectPtr conn, int *ids, int nids)
{
return phypListDomainsGeneric(conn, ids, nids, 0);
}
static int
phypListDefinedDomains(virConnectPtr conn, char **const names, int nnames)
{
ConnectionData *connection_data = conn->networkPrivateData;
SSH_SESSION *ssh_session = connection_data->session;
char *managed_system = conn->uri->path;
int exit_status = 0;
int got = 0;
char *char_ptr = NULL;
char *cmd;
char *domains;
/* need to shift one byte in order to remove the first "/" of URI component */
if (managed_system[0] == '/')
managed_system++;
/* here we are handling only the first component of the path,
* so skipping the second:
* */
char_ptr = strchr(managed_system, '/');
if (char_ptr)
*char_ptr = '\0';
if (virAsprintf
(&cmd,
"lssyscfg -r lpar -m %s -F name,state | grep \"Not Activated\" | sed -e 's/,.*$//g'",
managed_system) < 0) {
virReportOOMError(conn);
goto err;
}
char *ret = phypExec(ssh_session, cmd, &exit_status, conn);
if (VIR_ALLOC(domains) < 0)
virReportOOMError(conn);
domains = strdup(ret);
if (!domains)
goto err;
char *char_ptr2 = NULL;
/* I need to parse the textual return in order to get the domains */
if (exit_status < 0 || domains == NULL)
goto err;
else {
while (got < nnames) {
char_ptr2 = strchr(domains, '\n');
if (char_ptr2) {
*char_ptr2 = '\0';
if (!strdup(domains))
goto err;
names[got] = strdup(domains);
char_ptr2++;
domains = char_ptr2;
got++;
}
}
}
VIR_FREE(domains);
VIR_FREE(cmd);
VIR_FREE(ret);
return got;
err:
VIR_FREE(domains);
VIR_FREE(ret);
return 0;
}
static virDomainPtr
phypDomainLookupByName(virConnectPtr conn, const char *lpar_name)
{
ConnectionData *connection_data = conn->networkPrivateData;
SSH_SESSION *ssh_session = connection_data->session;
virDomainPtr dom = NULL;
int lpar_id = 0;
char *managed_system = conn->uri->path;
unsigned char *lpar_uuid = NULL;
if (VIR_ALLOC_N(lpar_uuid, VIR_UUID_BUFLEN) < 0)
virReportOOMError(dom->conn);
/* need to shift one byte in order to remove the first "/" of uri component */
if (managed_system[0] == '/')
managed_system++;
/* here we are handling only the first component of the path,
* so skipping the second:
* */
char *char_ptr = strchr(managed_system, '/');
if (char_ptr)
*char_ptr = '\0';
lpar_id = phypGetLparID(ssh_session, managed_system, lpar_name, conn);
if (lpar_id < 0)
goto err;
if (phypGetLparUUID(lpar_uuid, lpar_id, conn) == -1)
goto err;
dom = virGetDomain(conn, lpar_name, lpar_uuid);
if (dom)
dom->id = lpar_id;
VIR_FREE(lpar_uuid);
return dom;
err:
VIR_FREE(lpar_uuid);
return NULL;
}
static virDomainPtr
phypDomainLookupByID(virConnectPtr conn, int lpar_id)
{
ConnectionData *connection_data = conn->networkPrivateData;
SSH_SESSION *ssh_session = connection_data->session;
virDomainPtr dom = NULL;
char *managed_system = conn->uri->path;
int exit_status = 0;
unsigned char *lpar_uuid = NULL;
if (VIR_ALLOC_N(lpar_uuid, VIR_UUID_BUFLEN) < 0)
virReportOOMError(dom->conn);
/* need to shift one byte in order to remove the first "/" of uri component */
if (managed_system[0] == '/')
managed_system++;
/* here we are handling only the first component of the path,
* so skipping the second:
* */
char *char_ptr = strchr(managed_system, '/');
if (char_ptr)
*char_ptr = '\0';
char *lpar_name = phypGetLparNAME(ssh_session, managed_system, lpar_id,
conn);
if (phypGetLparUUID(lpar_uuid, lpar_id, conn) == -1)
goto err;
if (exit_status < 0)
goto err;
dom = virGetDomain(conn, lpar_name, lpar_uuid);
if (dom)
dom->id = lpar_id;
VIR_FREE(lpar_name);
VIR_FREE(lpar_uuid);
return dom;
err:
VIR_FREE(lpar_name);
VIR_FREE(lpar_uuid);
return NULL;
}
static char *
phypDomainDumpXML(virDomainPtr dom, int flags)
{
ConnectionData *connection_data = dom->conn->networkPrivateData;
SSH_SESSION *ssh_session = connection_data->session;
virDomainDefPtr def = NULL;
char *ret = NULL;
char *managed_system = dom->conn->uri->path;
unsigned char *lpar_uuid = NULL;
if (VIR_ALLOC_N(lpar_uuid, VIR_UUID_BUFLEN) < 0)
virReportOOMError(dom->conn);
if (VIR_ALLOC(def) < 0)
virReportOOMError(dom->conn);
/* need to shift one byte in order to remove the first "/" of uri component */
if (managed_system[0] == '/')
managed_system++;
/* here we are handling only the first component of the path,
* so skipping the second:
* */
char *char_ptr = strchr(managed_system, '/');
if (char_ptr)
*char_ptr = '\0';
def->virtType = VIR_DOMAIN_VIRT_PHYP;
def->id = dom->id;
char *lpar_name = phypGetLparNAME(ssh_session, managed_system, def->id,
dom->conn);
if (lpar_name == NULL) {
VIR_ERROR("%s", "Unable to determine domain's name.");
goto err;
}
if (phypGetLparUUID(lpar_uuid, dom->id, dom->conn) == -1) {
VIR_ERROR("%s", "Unable to generate random uuid.");
goto err;
}
if (!memcpy(def->uuid, lpar_uuid, VIR_UUID_BUFLEN)) {
VIR_ERROR("%s", "Unable to generate random uuid.");
goto err;
}
if ((def->maxmem =
phypGetLparMem(dom->conn, managed_system, dom->id, 0)) == 0) {
VIR_ERROR("%s", "Unable to determine domain's max memory.");
goto err;
}
if ((def->memory =
phypGetLparMem(dom->conn, managed_system, dom->id, 1)) == 0) {
VIR_ERROR("%s", "Unable to determine domain's memory.");
goto err;
}
if ((def->vcpus =
phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0) {
VIR_ERROR("%s", "Unable to determine domain's CPU.");
goto err;
}
ret = virDomainDefFormat(dom->conn, def, flags);
err:
VIR_FREE(def);
return ret;
}
static int
phypDomainResume(virDomainPtr dom)
{
ConnectionData *connection_data = dom->conn->networkPrivateData;
SSH_SESSION *ssh_session = connection_data->session;
char *managed_system = dom->conn->uri->path;
int exit_status = 0;
char *char_ptr = NULL;
char *cmd;
/* need to shift one byte in order to remove the first "/" of URI component */
if (managed_system[0] == '/')
managed_system++;
/* here we are handling only the first component of the path,
* so skipping the second:
* */
char_ptr = strchr(managed_system, '/');
if (char_ptr)
*char_ptr = '\0';
if (virAsprintf
(&cmd,
"chsysstate -m %s -r lpar -o on --id %d -f %s",
managed_system, dom->id, dom->name) < 0) {
virReportOOMError(dom->conn);
goto err;
}
char *ret = phypExec(ssh_session, cmd, &exit_status, dom->conn);
err:
VIR_FREE(cmd);
VIR_FREE(ret);
return 0;
}
static int
phypDomainShutdown(virDomainPtr dom)
{
ConnectionData *connection_data = dom->conn->networkPrivateData;
SSH_SESSION *ssh_session = connection_data->session;
char *managed_system = dom->conn->uri->path;
int exit_status = 0;
char *char_ptr = NULL;
char *cmd;
/* need to shift one byte in order to remove the first "/" of URI component */
if (managed_system[0] == '/')
managed_system++;
/* here we are handling only the first component of the path,
* so skipping the second:
* */
char_ptr = strchr(managed_system, '/');
if (char_ptr)
*char_ptr = '\0';
if (virAsprintf
(&cmd,
"chsysstate -m %s -r lpar -o shutdown --id %d",
managed_system, dom->id) < 0) {
virReportOOMError(dom->conn);
goto err;
}
char *ret = phypExec(ssh_session, cmd, &exit_status, dom->conn);
err:
VIR_FREE(cmd);
VIR_FREE(ret);
return 0;
}
static int
phypDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info)
{
char *managed_system = dom->conn->uri->path;
/* need to shift one byte in order to remove the first "/" of uri component */
if (managed_system[0] == '/')
managed_system++;
/* here we are handling only the first component of the path,
* so skipping the second:
* */
char *char_ptr = strchr(managed_system, '/');
if (char_ptr)
*char_ptr = '\0';
info->state = phypGetLparState(dom->conn, dom->id);
if ((info->maxMem =
phypGetLparMem(dom->conn, managed_system, dom->id, 0)) == 0)
VIR_WARN("%s", "Unable to determine domain's max memory.");
if ((info->memory =
phypGetLparMem(dom->conn, managed_system, dom->id, 1)) == 0)
VIR_WARN("%s", "Unable to determine domain's memory.");
if ((info->nrVirtCpu =
phypGetLparCPU(dom->conn, managed_system, dom->id)) == 0)
VIR_WARN("%s", "Unable to determine domain's CPU.");
return 0;
}
virDriver phypDriver = {
VIR_DRV_PHYP,
"PHYP",
phypOpen, /* open */
phypClose, /* close */
NULL, /* supports_feature */
NULL, /* type */
NULL, /* version */
NULL, /* getHostname */
NULL, /* getMaxVcpus */
NULL, /* nodeGetInfo */
NULL, /* getCapabilities */
phypListDomains, /* listDomains */
phypNumDomains, /* numOfDomains */
NULL, /* domainCreateXML */
phypDomainLookupByID, /* domainLookupByID */
NULL, /* domainLookupByUUID */
phypDomainLookupByName, /* domainLookupByName */
NULL, /* domainSuspend */
phypDomainResume, /* domainResume */
phypDomainShutdown, /* domainShutdown */
NULL, /* domainReboot */
NULL, /* domainDestroy */
NULL, /* domainGetOSType */
NULL, /* domainGetMaxMemory */
NULL, /* domainSetMaxMemory */
NULL, /* domainSetMemory */
phypDomainGetInfo, /* domainGetInfo */
NULL, /* domainSave */
NULL, /* domainRestore */
NULL, /* domainCoreDump */
NULL, /* domainSetVcpus */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
NULL, /* domainGetMaxVcpus */
NULL, /* domainGetSecurityLabel */
NULL, /* nodeGetSecurityModel */
phypDomainDumpXML, /* domainDumpXML */
NULL, /* domainXmlFromNative */
NULL, /* domainXmlToNative */
phypListDefinedDomains, /* listDefinedDomains */
phypNumDefinedDomains, /* numOfDefinedDomains */
NULL, /* domainCreate */
NULL, /* domainDefineXML */
NULL, /* domainUndefine */
NULL, /* domainAttachDevice */
NULL, /* domainDetachDevice */
NULL, /* domainGetAutostart */
NULL, /* domainSetAutostart */
NULL, /* domainGetSchedulerType */
NULL, /* domainGetSchedulerParameters */
NULL, /* domainSetSchedulerParameters */
NULL, /* domainMigratePrepare */
NULL, /* domainMigratePerform */
NULL, /* domainMigrateFinish */
NULL, /* domainBlockStats */
NULL, /* domainInterfaceStats */
NULL, /* domainBlockPeek */
NULL, /* domainMemoryPeek */
NULL, /* nodeGetCellsFreeMemory */
NULL, /* getFreeMemory */
NULL, /* domainEventRegister */
NULL, /* domainEventDeregister */
NULL, /* domainMigratePrepare2 */
NULL, /* domainMigrateFinish2 */
NULL, /* nodeDeviceDettach */
NULL, /* nodeDeviceReAttach */
NULL, /* nodeDeviceReset */
};
int
phypRegister(void)
{
virRegisterDriver(&phypDriver);
return 0;
}
void
init_uuid_db(virConnectPtr conn)
{
uuid_dbPtr uuid_db;
int nids = 0;
int *ids = NULL;
unsigned int i = 0;
if ((nids = phypNumDomainsGeneric(conn, 2)) == 0)
goto exit;
if (VIR_ALLOC_N(ids, nids) < 0)
virReportOOMError(conn);
if (VIR_ALLOC(uuid_db) < 0)
virReportOOMError(conn);
if (phypListDomainsGeneric(conn, ids, nids, 1) == 0)
goto exit;
uuid_db = conn->privateData;
uuid_db->nlpars = nids;
if (VIR_ALLOC_N(uuid_db->lpars, uuid_db->nlpars) >= 0) {
for (i = 0; i < uuid_db->nlpars; i++) {
if (VIR_ALLOC(uuid_db->lpars[i]) < 0)
virReportOOMError(conn);
uuid_db->lpars[i]->id = ids[i];
if (virUUIDGenerate(uuid_db->lpars[i]->uuid) < 0)
VIR_WARN("%s %d", "Unable to generate UUID for domain",
ids[i]);
}
}
exit:
VIR_FREE(ids);
return;
}
int
escape_specialcharacters(char *src, char *dst)
{
size_t len = strlen(src);
char temp_buffer[len];
unsigned int i = 0, j = 0;
if (len == 0)
return -1;
for (i = 0; i < len; i++) {
switch (src[i]) {
case '&': case ';': case '`': case '@':
case '"': case '|': case '*': case '?':
case '~': case '<': case '>': case '^':
case '(': case ')': case '[': case ']':
case '{': case '}': case '$': case '%':
case '#': case '\\': case '\n': case '\r':
case '\t':
continue;
default:
temp_buffer[j] = src[i];
j++;
}
}
temp_buffer[j] = '\0';
if (strncpy(dst, temp_buffer, j) == NULL)
return -1;
return 0;
}
#include <config.h>
#include <libssh/libssh.h>
#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 */
typedef struct _ConnectionData ConnectionData;
typedef ConnectionData *ConnectionDataPtr;
struct _ConnectionData {
SSH_SESSION *session;
virConnectAuthPtr auth;
};
/* 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_db uuid_db_t;
typedef uuid_db_t *uuid_dbPtr;
struct _uuid_db {
int nlpars;
lparPtr *lpars;
};
int phypGetLparUUID(unsigned char *uuid, int lpar_id, virConnectPtr conn);
void init_uuid_db(virConnectPtr conn);
int phypRegister(void);
void stripPath(char *striped_path, char *path);
void stripNewline(char *striped_string, char *string);
int buffer_add_u8(struct buffer_struct *buffer, u8 data);
int phypGetLparState(virConnectPtr conn, unsigned int lpar_id);
unsigned long phypGetLparMem(virConnectPtr conn,
const char *managed_system, int lpar_id,
int type);
unsigned long phypGetLparCPU(virConnectPtr conn,
const char *managed_system, int lpar_id);
int phypGetRemoteSlot(virConnectPtr conn, const char *managed_system,
const char *lpar_name);
char *phypGetBackingDevice(virConnectPtr conn, const char *managed_system,
char *lpar_name);
int phypDiskType(virConnectPtr conn, char *backing_device);
SSH_SESSION *openSSHSession(virConnectPtr conn, virConnectAuthPtr auth);
int escape_specialcharacters(char *src, char *dst);
...@@ -124,6 +124,9 @@ static const char *virErrorDomainName(virErrorDomain domain) { ...@@ -124,6 +124,9 @@ static const char *virErrorDomainName(virErrorDomain domain) {
case VIR_FROM_CONF: case VIR_FROM_CONF:
dom = "Config "; dom = "Config ";
break; break;
case VIR_FROM_PHYP:
dom = "IBM power hypervisor ";
break;
case VIR_FROM_OPENVZ: case VIR_FROM_OPENVZ:
dom = "OpenVZ "; dom = "OpenVZ ";
break; break;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册