Hello again, I very am glad with all the feedback I got. The following attachtment is the result of the work using all the suggestions the list made. I also have a few comments over this new RFC. Here is a little Changelog: * Now the URI is recognized as phyp://user@hmc/managed_system. To use path component of the uri struct, I had to implement a little function to strip out the first slash of the string, giving me only 'path', instead of '/path'. * I implemented the option --with-libssh and --with-phyp right according to what Daniel Berrange suggested. * Now all the variable-size string buffers are manipulated with the internal API virBuffer* to make it safer. | +- This made me think and change the __inner_exec_command function. Now it returns char * with all the textual return, and I am passing int * as reference to get the exit status - all the information I need about the remote executed command. | +- And this also made me write a little auxiliar function to strip out the '\n' from the textual return. Known and unsolved issues: * Authentication - need to improve the authenticantion as Daniel Berrange said. Still in progress. * Error codes. * Logging and debugging messages. Any comments are welcome, []'s Em Sex, 2009-03-20 às 13:58 -0300, Eduardo Otubo escreveu: > Hello all, > > I've been working on a libvirt extension to manage IBM's Power VMs > (LPARs). The Power systems are managed through management console > referred to as the HMC or using a management partition (IVM). Both HMC > and IVM runs an SSH, then you can reach it via command line, and an HTTP > server, then you can reach it via web browser. > > The protocol between the console and the partition (LPAR) is not > disclosed, therefore I propose the driver to execute commands remoetly > over an SSH connection to the consoles to manage IBM LPARs. > > The patch attached is the first scratch of the driver that will interact > with HMC over a SSH connection. The URI model that is > used in virsh command line is: > > virsh --conect phyp://$user@$server > > Some known issues are: > * Next step is to make the URI like this: phyp://$user@ > $HMC/@managed_system. Almost finished. What it takes now is > $server = $HMC = $managed_system. > * Next features in my TODO list are "resume", "stop" and "reboot" the > LPAR. > > Any comments are welcome. > > Thanks, > > > -- > Libvir-list mailing list > Libvir-list@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/libvir-list -- Eduardo Otubo Software Engineer Linux Technology Center IBM Systems & Technology Group Mobile: +55 19 8135 0885 otubo@xxxxxxxxxxxxxxxxxx
diff --git a/configure.in b/configure.in index dcacc7f..9545a20 100644 --- a/configure.in +++ b/configure.in @@ -182,6 +182,10 @@ AC_ARG_WITH([uml], [ --with-uml add UML support (on)],[],[with_uml=yes]) AC_ARG_WITH([openvz], [ --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], [ --with-vbox add VirtualBox support (on)],[],[with_vbox=yes]) AC_ARG_WITH([lxc], @@ -729,6 +733,51 @@ AM_CONDITIONAL([HAVE_NUMACTL], [test "$with_numactl" != "no"]) AC_SUBST([NUMACTL_CFLAGS]) 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 virsh libraries AC_CHECK_HEADERS([readline/readline.h]) @@ -1372,6 +1421,7 @@ AC_MSG_NOTICE([ UML: $with_uml]) AC_MSG_NOTICE([ OpenVZ: $with_openvz]) AC_MSG_NOTICE([ VBox: $with_vbox]) AC_MSG_NOTICE([ LXC: $with_lxc]) +AC_MSG_NOTICE([ PHYP: $with_phyp]) AC_MSG_NOTICE([ Test: $with_test]) AC_MSG_NOTICE([ Remote: $with_remote]) AC_MSG_NOTICE([ Network: $with_network]) @@ -1401,6 +1451,11 @@ fi AC_MSG_NOTICE([]) AC_MSG_NOTICE([Libraries]) AC_MSG_NOTICE([]) +if test "$with_libssh" != "no" ; then +AC_MSG_NOTICE([ libssh: $LIBSSH_CFLAGS $LIBSSH_LIBS]) +else +AC_MSG_NOTICE([ libssh: no]) +fi AC_MSG_NOTICE([ libxml: $LIBXML_CFLAGS $LIBXML_LIBS]) AC_MSG_NOTICE([ gnutls: $GNUTLS_CFLAGS $GNUTLS_LIBS]) if test "$with_sasl" != "no" ; then diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index faf3f61..28a35d9 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -61,6 +61,7 @@ typedef enum { VIR_FROM_UML, /* Error at the UML driver */ VIR_FROM_NODEDEV, /* Error from node device monitor */ VIR_FROM_XEN_INOTIFY, /* Error from xen inotify layer */ + VIR_FROM_PHYP, /* Error from IBM power hypervisor */ VIR_FROM_SECURITY, /* Error from security framework */ VIR_FROM_VBOX, /* Error from VirtualBox driver */ } virErrorDomain; diff --git a/src/Makefile.am b/src/Makefile.am index fd692b4..e65f2d4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,6 +5,7 @@ INCLUDES = \ -I../include \ -I@top_srcdir@/include \ -I@top_srcdir@/qemud \ + $(LIBSSH_CFLAGS) \ $(LIBXML_CFLAGS) \ $(XEN_CFLAGS) \ $(SELINUX_CFLAGS) \ @@ -125,6 +126,9 @@ LXC_CONTROLLER_SOURCES = \ veth.c veth.h \ cgroup.c cgroup.h +PHYP_DRIVER_SOURCES = \ + phyp_driver.c phyp_driver.h + OPENVZ_DRIVER_SOURCES = \ openvz_conf.c openvz_conf.h \ openvz_driver.c openvz_driver.h @@ -265,6 +269,18 @@ endif libvirt_driver_xen_la_SOURCES = $(XEN_DRIVER_SOURCES) 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_DRIVER_MODULES mod_LTLIBRARIES += libvirt_driver_openvz.la @@ -430,6 +446,7 @@ EXTRA_DIST += \ $(LXC_DRIVER_SOURCES) \ $(UML_DRIVER_SOURCES) \ $(OPENVZ_DRIVER_SOURCES) \ + $(PHYP_DRIVER_SOURCES) \ $(VBOX_DRIVER_SOURCES) \ $(NETWORK_DRIVER_SOURCES) \ $(STORAGE_DRIVER_SOURCES) \ diff --git a/src/driver.h b/src/driver.h index 39dc413..3e758e0 100644 --- a/src/driver.h +++ b/src/driver.h @@ -21,6 +21,7 @@ typedef enum { VIR_DRV_LXC = 6, VIR_DRV_UML = 7, VIR_DRV_VBOX = 8, + VIR_DRV_PHYP = 9, } virDrvNo; diff --git a/src/libvirt.c b/src/libvirt.c index 95a861e..617d957 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -55,6 +55,9 @@ #ifdef WITH_OPENVZ #include "openvz_driver.h" #endif +#ifdef WITH_PHYP +#include "phyp_driver.h" +#endif #ifdef WITH_VBOX #include "vbox/vbox_driver.h" #endif @@ -321,6 +324,9 @@ virInitialize(void) #ifdef WITH_OPENVZ if (openvzRegister() == -1) return -1; #endif +#ifdef WITH_PHYP + if (phypRegister() == -1) return -1; +#endif #ifdef WITH_VBOX if (vboxRegister() == -1) return -1; #endif @@ -833,6 +839,10 @@ virGetVersion(unsigned long *libVer, const char *type, if (STRCASEEQ(type, "LXC")) *typeVer = LIBVIR_VERSION_NUMBER; #endif +#if WITH_PHYP + if (STRCASEEQ(type, "Phyp")) + *typeVer = LIBVIR_VERSION_NUMBER; +#endif #if WITH_OPENVZ if (STRCASEEQ(type, "OpenVZ")) *typeVer = LIBVIR_VERSION_NUMBER; diff --git a/src/phyp_driver.c b/src/phyp_driver.c new file mode 100644 index 0000000..6c15afd --- /dev/null +++ b/src/phyp_driver.c @@ -0,0 +1,496 @@ + +/* + * 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 "datatypes.h" +#include "buf.h" +#include "memory.h" +#include "logging.h" +#include "driver.h" + +#include "phyp_driver.h" + +/* + * TODO: I still need to implement a way to distinguish + * an HMC from an IVM + * */ + +static virDrvOpenStatus +phypOpen(virConnectPtr conn, + virConnectAuthPtr auth ATTRIBUTE_UNUSED, + int flags ATTRIBUTE_UNUSED) +{ + int ssh_auth = 0, exit_status = 0; + char *banner; + char *password; + + SSH_SESSION *session; + SSH_OPTIONS *opt; + + if (!conn || !conn->uri) + return VIR_DRV_OPEN_DECLINED; + + if (conn->uri->scheme == NULL || conn->uri->server == NULL + || conn->uri->path == NULL) + return VIR_DRV_OPEN_DECLINED; + + session = ssh_new(); + opt = ssh_options_new(); + + if (!conn->uri->port) + conn->uri->port = 22; + + /*setting some ssh options */ + ssh_options_set_host(opt, conn->uri->server); + ssh_options_set_port(opt, conn->uri->port); + ssh_options_set_username(opt, conn->uri->user); + ssh_set_options(session, opt); + + /*starting ssh connection */ + if (ssh_connect(session)) { + fprintf(stderr, "Connection failed : %s\n", + ssh_get_error(session)); + ssh_disconnect(session); + ssh_finalize(); + exit_status = SSH_CONN_ERR; + return VIR_DRV_OPEN_DECLINED; + } + + /*trying to use pub key */ + if ((ssh_auth = + ssh_userauth_autopubkey(session, NULL)) == SSH_AUTH_ERROR) { + fprintf(stderr, "Authenticating with pubkey: %s\n", + ssh_get_error(session)); + exit_status = SSH_AUTH_PUBKEY_ERR; + return VIR_DRV_OPEN_DECLINED; + } + + if ((banner = ssh_get_issue_banner(session))) { + fprintf(stdout, "%s\n", banner); + VIR_FREE(banner); + } + + if (ssh_auth != SSH_AUTH_SUCCESS) { + password = getpass("Password: "); + if (ssh_userauth_password(session, NULL, password) != + SSH_AUTH_SUCCESS) { + fprintf(stderr, "Authentication failed: %s\n", + ssh_get_error(session)); + ssh_disconnect(session); + memset(password, 0, strlen(password)); + exit_status = SSH_AUTH_ERR; + return VIR_DRV_OPEN_DECLINED; + } else + goto exec; + } else + goto exec; + + exec: + conn->privateData = session; + return VIR_DRV_OPEN_SUCCESS; +} + +static int +phypClose(virConnectPtr conn) +{ + SSH_SESSION *ssh_session = conn->privateData; + + ssh_disconnect(ssh_session); + + return 0; +} + +/* this functions is the layer that manipulates the ssh channel itself + * and executes the commands on the remote machine */ +static char * +__inner_exec_command(SSH_SESSION * session, char *cmd, int *exit_status) +{ + CHANNEL *channel = channel_new(session); + BUFFER *readbuf = buffer_new(); + virBuffer tex_ret = VIR_BUFFER_INITIALIZER; + + int ret = 0; + + if (channel_open_session(channel) == SSH_ERROR) + (*exit_status) = SSH_CHANNEL_OPEN_ERR; + + if (channel_request_exec(channel, cmd) == SSH_ERROR) + (*exit_status) = SSH_CHANNEL_EXEC_ERR; + + if (channel_send_eof(channel) == SSH_ERROR) + (*exit_status) = SSH_CHANNEL_SEND_EOF_ERR; + + while (channel && channel_is_open(channel)) { + ret = channel_read(channel, readbuf, 0, 0); + if (ret < 0) { + (*exit_status) = SSH_CHANNEL_READ_ERR; + break; + } + + if (ret == 0) { + channel_send_eof(channel); + while(channel_get_exit_status(channel) == -1){ + channel_poll(channel,0); + usleep(50); + } + if (channel_close(channel) == SSH_ERROR) + (*exit_status) = SSH_CHANNEL_CLOSE_ERR; + + (*exit_status) = channel_get_exit_status(channel); + + channel_free(channel); + channel = NULL; + break; + } + + buffer_add_u8(readbuf, 0); + virBufferStrcat(&tex_ret, buffer_get(readbuf)); + } + + 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) +{ + int exit_status = 0; + virBuffer cmd = VIR_BUFFER_INITIALIZER; + + virBufferVSprintf(&cmd, + "lssyscfg -r lpar -m %s --filter lpar_names=%s -F lpar_id", + managed_system, name); + const char *tex_ret = + __inner_exec_command(ssh_session, virBufferContentAndReset(&cmd), + &exit_status); + + virBufferContentAndReset(&cmd); + if (exit_status < 0 || tex_ret == NULL) + return 0; + else + return atoi(tex_ret); +} + +/* 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, int *exit_status) +{ + virBuffer cmd = VIR_BUFFER_INITIALIZER; + + virBufferVSprintf(&cmd, + "lssyscfg -r lpar -m %s --filter lpar_ids=%d -F name", + managed_system, lpar_id); + const char *lpar_name = + __inner_exec_command(ssh_session, virBufferContentAndReset(&cmd), + (int *) exit_status); + char *striped_lpar_name = (char *) malloc(sizeof(lpar_name) - 1); + + stripNewline(striped_lpar_name, lpar_name); + + virBufferContentAndReset(&cmd); + if ((*exit_status) < 0 || lpar_name == NULL) { + return NULL; + } + + return striped_lpar_name; +} + +/* return the lpar_uuid (which for now is its logical serial number) + * given a lpar id and a managed system name */ +static unsigned char * +phypGetLparUUID(SSH_SESSION * ssh_session, const char *managed_system, + unsigned int lpar_id, int *exit_status) +{ + virBuffer cmd = VIR_BUFFER_INITIALIZER; + + virBufferVSprintf(&cmd, + "lssyscfg -r lpar -m %s --filter lpar_ids=%d -F logical_serial_num", + managed_system, lpar_id); + unsigned char *lpar_uuid = + (unsigned char *) __inner_exec_command(ssh_session, + virBufferContentAndReset + (&cmd), + (int *) exit_status); + unsigned char *striped_lpar_uuid = + (unsigned char *) malloc(sizeof(lpar_uuid) - 1); + stripNewline((char *) striped_lpar_uuid, (char *) lpar_uuid); + + virBufferContentAndReset(&cmd); + if ((*exit_status) < 0 || lpar_uuid == NULL) { + return NULL; + } + + return striped_lpar_uuid; + return lpar_uuid; +} + +static int +phypNumDomains(virConnectPtr conn) +{ + int exit_status = 0; + char managed_system[strlen(conn->uri->path) - 1]; + SSH_SESSION *ssh_session = conn->privateData; + virBuffer cmd = VIR_BUFFER_INITIALIZER; + + stripPath((char *) &managed_system, conn->uri->path); + virBufferVSprintf(&cmd, + "lssyscfg -r lpar -m %s -F lpar_id|grep -c ^[0-9]*", + managed_system); + const char *ndom = + __inner_exec_command(ssh_session, virBufferContentAndReset(&cmd), + &exit_status); + + virBufferContentAndReset(&cmd); + if(exit_status < 0 || ndom == NULL) + return 0; + + return atoi(ndom); +} + +static int +phypListDomains(virConnectPtr conn, int *ids, int nids) +{ + int exit_status = 0; + int got = 0; + unsigned int i = 0, j = 0; + char id_c[10]; + char managed_system[strlen(conn->uri->path) - 1]; + SSH_SESSION *ssh_session = conn->privateData; + + stripPath((char *) &managed_system, conn->uri->path); + virBuffer cmd = VIR_BUFFER_INITIALIZER; + + memset(id_c, 0, 10); + + virBufferVSprintf(&cmd, "lssyscfg -r lpar -m %s -F lpar_id", + managed_system); + char *domains = + __inner_exec_command(ssh_session, virBufferContentAndReset(&cmd), + &exit_status); + + /* I need to parse the textual return in order to get the domains */ + if (exit_status < 0 || domains == NULL) + return 0; + else { + while (got < nids) { + if (domains[i] == '\n') { + ids[got] = atoi(id_c); + memset(id_c, 0, 10); + j = 0; + got++; + } else { + id_c[j] = domains[i]; + j++; + } + i++; + } + } + + virBufferContentAndReset(&cmd); + return got; +} + +static virDomainPtr +phypDomainLookupByName(virConnectPtr conn, const char *name) +{ + SSH_SESSION *ssh_session = conn->privateData; + virDomainPtr dom = NULL; + + int lpar_id = 0; + int exit_status = 0; + char managed_system[strlen(conn->uri->path) - 1]; + + stripPath((char *) &managed_system, conn->uri->path); + + lpar_id = phypGetLparID(ssh_session, managed_system, name); + if (lpar_id == PHYP_NO_MEM) + return NULL; + + unsigned char *lpar_uuid = + phypGetLparUUID(ssh_session, managed_system, lpar_id, + &exit_status); + + if (exit_status == PHYP_NO_MEM || lpar_uuid == NULL) + return NULL; + + dom = virGetDomain(conn, name, lpar_uuid); + + if (dom) + dom->id = lpar_id; + + VIR_FREE(lpar_uuid); + return dom; +} + +static virDomainPtr +phypDomainLookupByID(virConnectPtr conn, int lpar_id) +{ + SSH_SESSION *ssh_session = conn->privateData; + virDomainPtr dom = NULL; + int exit_status = 0; + char managed_system[strlen(conn->uri->path) - 1]; + + stripPath((char *) &managed_system, conn->uri->path); + + char *lpar_name = phypGetLparNAME(ssh_session, managed_system, lpar_id, + &exit_status); + + if (exit_status == PHYP_NO_MEM) + return NULL; + + unsigned char *lpar_uuid = + phypGetLparUUID(ssh_session, managed_system, lpar_id, + &exit_status); + + if (exit_status == PHYP_NO_MEM) + return NULL; + + dom = virGetDomain(conn, lpar_name, lpar_uuid); + + if (dom) + dom->id = lpar_id; + + VIR_FREE(lpar_name); + VIR_FREE(lpar_uuid); + return dom; +} + +static 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 */ + NULL, /* domainResume */ + NULL, /* domainShutdown */ + NULL, /* domainReboot */ + NULL, /* domainDestroy */ + NULL, /* domainGetOSType */ + NULL, /* domainGetMaxMemory */ + NULL, /* domainSetMaxMemory */ + NULL, /* domainSetMemory */ + NULL, /* domainGetInfo */ + NULL, /* domainSave */ + NULL, /* domainRestore */ + NULL, /* domainCoreDump */ + NULL, /* domainSetVcpus */ + NULL, /* domainPinVcpu */ + NULL, /* domainGetVcpus */ + NULL, /* domainGetMaxVcpus */ + NULL, /* domainGetSecurityLabel */ + NULL, /* nodeGetSecurityModel */ + NULL, /* domainDumpXML */ + NULL, /* listDefinedDomains */ + NULL, /* 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; +} + +/* function that helps me to strip out the first slash from the + * uri: phyp://user@hmc/path + * + * '/path' becomes 'path' + * */ +void +stripPath(char *striped_path, char *path) +{ + unsigned int i = 0; + for (i = 1; i <= strlen(path); i++) + striped_path[i - 1] = path[i]; + striped_path[i] = '\0'; + return; +} + +/* function to strip out the '\n' of the end of some string */ +void +stripNewline(char *striped_string, char *string) +{ + unsigned int i = 0; + for (i = 0; i <= strlen(string); i++) + if (string[i] != '\n') + striped_string[i] = string[i]; + striped_string[strlen(string)-1] = '\0'; + return; +} diff --git a/src/phyp_driver.h b/src/phyp_driver.h new file mode 100644 index 0000000..c2d9c9b --- /dev/null +++ b/src/phyp_driver.h @@ -0,0 +1,21 @@ +#include <config.h> +#include <libssh/libssh.h> + +#define MAXSIZE 65536 +#define LPAR_EXEC_ERR -1 +#define SSH_CONN_ERR -2 +#define SSH_AUTH_PUBKEY_ERR -3 +#define SSH_AUTH_ERR -4 +#define SSH_CHANNEL_OPEN_ERR -5 +#define SSH_CHANNEL_EXEC_ERR -6 +#define SSH_CHANNEL_SEND_EOF_ERR -7 +#define SSH_CHANNEL_CLOSE_ERR -8 +#define SSH_CHANNEL_READ_ERR -9 +#define PHYP_NO_MEM -10 + +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); diff --git a/src/virterror.c b/src/virterror.c index 2d34ed7..82eb506 100644 --- a/src/virterror.c +++ b/src/virterror.c @@ -124,6 +124,9 @@ static const char *virErrorDomainName(virErrorDomain domain) { case VIR_FROM_CONF: dom = "Config "; break; + case VIR_FROM_PHYP: + dom = "IBM power hypervisor "; + break; case VIR_FROM_OPENVZ: dom = "OpenVZ "; break;
-- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list