On 04.01.2012 00:47, Peter Krempa wrote: > This patch adds a glue layer to enable using libssh2 code with the > network client code. > > As in the original client implementation, shell code is sent to the > server to detect correct options for netcat. > > *src/rpc/virnetclient.c: > *src/rpc/virnetclient.h: Add function to handle connection to a libvirt > daemon using the libssh2 transport. > --- > src/rpc/virnetclient.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++- > src/rpc/virnetclient.h | 11 ++++++ > 2 files changed, 100 insertions(+), 2 deletions(-) > > diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c > index 469c6a5..b0cb8d2 100644 > --- a/src/rpc/virnetclient.c > +++ b/src/rpc/virnetclient.c > @@ -383,6 +383,72 @@ virNetClientPtr virNetClientNewSSH(const char *nodename, > return virNetClientNew(sock, NULL); > } > > +virNetClientPtr virNetClientNewLibSSH(const char *host, > + const char *port, > + const char *username, > + const char *password, > + const char *netcat, > + const char *socketPath, > + const char *knownHostsFile, > + const char *hostkeyVerify, > + const char *privkey, > + virConnectAuthPtr auth) > +{ > + virNetSocketPtr sock; > + virBuffer buf = VIR_BUFFER_INITIALIZER; > + char *nc = NULL; > + > + if (!host) > + host = "localhost"; > + > + if (!port) > + port = "22"; > + > + if (!username) > + username = "root"; > + > + if (netcat) { > + virBufferEscapeShell(&buf, netcat); > + nc = virBufferContentAndReset(&buf); > + } else { > + nc = strdup("nc"); > + } > + > + if (!nc) { > + virReportOOMError(); > + return NULL; > + } > + > + virBufferAsprintf(&buf, > + "sh -c " > + "'if '%s' -q 2>&1 | grep \"requires an argument\" >/dev/null 2>&1; then " > + "ARG=-q0;" > + "else " > + "ARG=;" > + "fi;" > + "'%s' $ARG -U %s'", > + nc, nc, socketPath); I wonder if we can reuse the code from virNetSocketNewConnectSSH(). > + > + VIR_FREE(nc); > + > + if (virBufferError(&buf)) { > + virReportOOMError(); > + return NULL; > + } > + > + nc = virBufferContentAndReset(&buf); > + > + if (virNetSocketNewConnectLibSSH(host, port, username, password, nc, > + knownHostsFile, hostkeyVerify, > + privkey, auth, &sock) != 0) { > + VIR_FREE(nc); > + return NULL; > + } > + > + VIR_FREE(nc); > + return virNetClientNew(sock, NULL); > +} > + > virNetClientPtr virNetClientNewExternal(const char **cmdargv) > { > virNetSocketPtr sock; > @@ -964,6 +1030,7 @@ virNetClientIOWriteMessage(virNetClientPtr client, > virNetClientCallPtr thecall) > { > ssize_t ret = 0; > + virErrorPtr err; > > if (thecall->msg->bufferOffset < thecall->msg->bufferLength) { > ret = virNetSocketWrite(client->sock, > @@ -971,8 +1038,18 @@ virNetClientIOWriteMessage(virNetClientPtr client, > thecall->msg->bufferLength - thecall->msg->bufferOffset); > if (ret > 0 || virNetSocketHasPendingData(client->sock)) > thecall->sentSomeData = true; > - if (ret <= 0) > + if (ret <= 0) { > + if ((err = virGetLastError())) { > + if (err->domain == VIR_FROM_LIBSSH && > + err->code == VIR_ERR_LIBSSH_REMOTE_COMMAND) { > + virResetLastError(); > + virNetError(VIR_ERR_LIBSSH_REMOTE_COMMAND, > + _("Remote daemon is not running or remote " > + "command has failed")); > + } > + } > return ret; > + } > > thecall->msg->bufferOffset += ret; > } > @@ -1637,6 +1714,7 @@ void virNetClientIncomingEvent(virNetSocketPtr sock, > void *opaque) > { > virNetClientPtr client = opaque; > + virErrorPtr err; > > virNetClientLock(client); > > @@ -1657,7 +1735,16 @@ void virNetClientIncomingEvent(virNetSocketPtr sock, > } > > if (virNetClientIOHandleInput(client) < 0) { > - VIR_WARN("Something went wrong during async message processing"); > + /* translate error message if we're using libssh transport */ > + if ((err = virGetLastError()) && > + (err->domain == VIR_FROM_LIBSSH && > + err->code == VIR_ERR_LIBSSH_REMOTE_COMMAND)) { > + virNetError(VIR_ERR_NO_CONNECT, "%s", > + _("Remote daemon is not running or remote command " > + "has failed")); > + } else { > + VIR_WARN("Something went wrong during async message processing"); > + } > virNetSocketRemoveIOCallback(sock); > } > > diff --git a/src/rpc/virnetclient.h b/src/rpc/virnetclient.h > index 61d51e1..9157852 100644 > --- a/src/rpc/virnetclient.h > +++ b/src/rpc/virnetclient.h > @@ -49,6 +49,17 @@ virNetClientPtr virNetClientNewSSH(const char *nodename, > const char *keyfile, > const char *path); > > +virNetClientPtr virNetClientNewLibSSH(const char *host, > + const char *port, > + const char *username, > + const char *password, > + const char *netcat, > + const char *socketPath, > + const char *knownHostsFile, > + const char *hostkeyVerify, > + const char *privkey, > + virConnectAuthPtr auth); > + > virNetClientPtr virNetClientNewExternal(const char **cmdargv); > > void virNetClientRef(virNetClientPtr client); Otherwise looking good. -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list