@ -991,8 +991,29 @@ void nbd_client_close(BlockDriverState *bs)
nbd_teardown_connection ( bs ) ;
nbd_teardown_connection ( bs ) ;
}
}
static QIOChannelSocket * nbd_establish_connection ( SocketAddress * saddr ,
Error * * errp )
{
QIOChannelSocket * sioc ;
Error * local_err = NULL ;
sioc = qio_channel_socket_new ( ) ;
qio_channel_set_name ( QIO_CHANNEL ( sioc ) , " nbd-client " ) ;
qio_channel_socket_connect_sync ( sioc , saddr , & local_err ) ;
if ( local_err ) {
object_unref ( OBJECT ( sioc ) ) ;
error_propagate ( errp , local_err ) ;
return NULL ;
}
qio_channel_set_delay ( QIO_CHANNEL ( sioc ) , false ) ;
return sioc ;
}
int nbd_client_init ( BlockDriverState * bs ,
int nbd_client_init ( BlockDriverState * bs ,
QIOChannelSocket * sioc ,
SocketAddress * saddr ,
const char * export ,
const char * export ,
QCryptoTLSCreds * tlscreds ,
QCryptoTLSCreds * tlscreds ,
const char * hostname ,
const char * hostname ,
@ -1002,6 +1023,16 @@ int nbd_client_init(BlockDriverState *bs,
NBDClientSession * client = nbd_get_client_session ( bs ) ;
NBDClientSession * client = nbd_get_client_session ( bs ) ;
int ret ;
int ret ;
/*
* establish TCP connection , return error if it fails
* TODO : Configurable retry - until - timeout behaviour .
*/
QIOChannelSocket * sioc = nbd_establish_connection ( saddr , errp ) ;
if ( ! sioc ) {
return - ECONNREFUSED ;
}
/* NBD handshake */
/* NBD handshake */
logout ( " session init %s \n " , export ) ;
logout ( " session init %s \n " , export ) ;
qio_channel_set_blocking ( QIO_CHANNEL ( sioc ) , true , NULL ) ;
qio_channel_set_blocking ( QIO_CHANNEL ( sioc ) , true , NULL ) ;
@ -1017,6 +1048,7 @@ int nbd_client_init(BlockDriverState *bs,
g_free ( client - > info . name ) ;
g_free ( client - > info . name ) ;
if ( ret < 0 ) {
if ( ret < 0 ) {
logout ( " Failed to negotiate with the NBD server \n " ) ;
logout ( " Failed to negotiate with the NBD server \n " ) ;
object_unref ( OBJECT ( sioc ) ) ;
return ret ;
return ret ;
}
}
if ( x_dirty_bitmap & & ! client - > info . base_allocation ) {
if ( x_dirty_bitmap & & ! client - > info . base_allocation ) {
@ -1042,7 +1074,6 @@ int nbd_client_init(BlockDriverState *bs,
qemu_co_mutex_init ( & client - > send_mutex ) ;
qemu_co_mutex_init ( & client - > send_mutex ) ;
qemu_co_queue_init ( & client - > free_sema ) ;
qemu_co_queue_init ( & client - > free_sema ) ;
client - > sioc = sioc ;
client - > sioc = sioc ;
object_ref ( OBJECT ( client - > sioc ) ) ;
if ( ! client - > ioc ) {
if ( ! client - > ioc ) {
client - > ioc = QIO_CHANNEL ( sioc ) ;
client - > ioc = QIO_CHANNEL ( sioc ) ;
@ -1068,6 +1099,9 @@ int nbd_client_init(BlockDriverState *bs,
NBDRequest request = { . type = NBD_CMD_DISC } ;
NBDRequest request = { . type = NBD_CMD_DISC } ;
nbd_send_request ( client - > ioc ? : QIO_CHANNEL ( sioc ) , & request ) ;
nbd_send_request ( client - > ioc ? : QIO_CHANNEL ( sioc ) , & request ) ;
object_unref ( OBJECT ( sioc ) ) ;
return ret ;
return ret ;
}
}
}
}