The secondary qemu starts later than the primary qemu, so we
cannot connect to nbd server in bdrv_open().
Signed-off-by: Wen Congyang <address@hidden>
Signed-off-by: zhanghailiang <address@hidden>
Signed-off-by: Gonglei <address@hidden>
---
block/nbd.c | 100
++++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 87 insertions(+), 13 deletions(-)
diff --git a/block/nbd.c b/block/nbd.c
index b05d1d0..19b9200 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -44,6 +44,8 @@
typedef struct BDRVNBDState {
NbdClientSession client;
QemuOpts *socket_opts;
+ char *export;
+ bool connected;
} BDRVNBDState;
static int nbd_parse_uri(const char *filename, QDict *options)
@@ -247,20 +249,10 @@ static int nbd_establish_connection(BlockDriverState *bs,
Error **errp)
return sock;
}
-static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
- Error **errp)
+static int nbd_connect_server(BlockDriverState *bs, Error **errp)
{
BDRVNBDState *s = bs->opaque;
- char *export = NULL;
int result, sock;
- Error *local_err = NULL;
-
- /* Pop the config into our state object. Exit if invalid. */
- nbd_config(s, options, &export, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return -EINVAL;
- }
/* establish TCP connection, return error if it fails
* TODO: Configurable retry-until-timeout behaviour.
@@ -271,16 +263,57 @@ static int nbd_open(BlockDriverState *bs, QDict *options,
int flags,
}
/* NBD handshake */
- result = nbd_client_session_init(&s->client, bs, sock, export, errp);
- g_free(export);
+ result = nbd_client_session_init(&s->client, bs, sock, s->export, errp);
+ g_free(s->export);
+ s->export = NULL;
+ if (!result) {
+ s->connected = true;
+ }
+
return result;
}
+static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
+ Error **errp)
+{
+ BDRVNBDState *s = bs->opaque;
+ Error *local_err = NULL;
+
+ /* Pop the config into our state object. Exit if invalid. */
+ nbd_config(s, options, &s->export, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return -EINVAL;
+ }
+
+ return nbd_connect_server(bs, errp);
+}
+
+static int nbd_open_colo(BlockDriverState *bs, QDict *options, int flags,
+ Error **errp)
+{
+ BDRVNBDState *s = bs->opaque;
+ Error *local_err = NULL;
+
+ /* Pop the config into our state object. Exit if invalid. */
+ nbd_config(s, options, &s->export, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int nbd_co_readv(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, QEMUIOVector *qiov)
{
BDRVNBDState *s = bs->opaque;
+ if (!s->connected) {
+ return -EIO;
+ }
+
return nbd_client_session_co_readv(&s->client, sector_num,
nb_sectors, qiov);
}
@@ -290,6 +323,10 @@ static int nbd_co_writev(BlockDriverState *bs, int64_t
sector_num,
{
BDRVNBDState *s = bs->opaque;
+ if (!s->connected) {
+ return 0;
+ }