mirror of https://github.com/xemu-project/xemu.git
nbd patches for 2020-09-02
- fix a few iotests affected by earlier nbd changes - avoid blocking qemu by nbd client in connect() - build qemu-nbd for mingw -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEccLMIrHEYCkn0vOqp6FrSiUnQ2oFAl9QFB8ACgkQp6FrSiUn Q2pTwggArPN7dRwm1KD9jL8X6PV01uhLuLRFzrrofFX22Blroj5XPbR24BdKeN8V uDSFGzzoz2Vx3vKPHyZdx7bbeEL0pF9dzjZX6JwzT0McbVuge5aG2zC/ARdfc4PN 1Yf2FB/nY8Xt5G12usu3FIz7JBoQNm4mlPnqVqf7t0LQxgUFvO7F2LernyqEOYKS uSpXHNFqddZcax7etXeldJOlSGJBQTaCmplrJbw2ilVhLZJD+0OglY4SAsrrenN+ gb/KD4REjhtQsmoTaqthGCnGXipEoJYDfEOMhbkl0UK+9Mx0t+3cj3tflG0eGldM ERk1d4d7VSlyqIy7w43v3+IB8M99ag== =7Cn5 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2020-09-02' into staging nbd patches for 2020-09-02 - fix a few iotests affected by earlier nbd changes - avoid blocking qemu by nbd client in connect() - build qemu-nbd for mingw # gpg: Signature made Wed 02 Sep 2020 22:52:31 BST # gpg: using RSA key 71C2CC22B1C4602927D2F3AAA7A16B4A2527436A # gpg: Good signature from "Eric Blake <eblake@redhat.com>" [full] # gpg: aka "Eric Blake (Free Software Programmer) <ebb9@byu.net>" [full] # gpg: aka "[jpeg image of size 6874]" [full] # Primary key fingerprint: 71C2 CC22 B1C4 6029 27D2 F3AA A7A1 6B4A 2527 436A * remotes/ericb/tags/pull-nbd-2020-09-02: nbd: disable signals and forking on Windows builds nbd: skip SIGTERM handler if NBD device support is not built block: add missing socket_init() calls to tools block/nbd: use non-blocking connect: fix vm hang on connect() iotests/259: Fix reference output iotests/059: Fix reference output Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
df8176274a
266
block/nbd.c
266
block/nbd.c
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
#include "qapi/qapi-visit-sockets.h"
|
#include "qapi/qapi-visit-sockets.h"
|
||||||
#include "qapi/qmp/qstring.h"
|
#include "qapi/qmp/qstring.h"
|
||||||
|
#include "qapi/clone-visitor.h"
|
||||||
|
|
||||||
#include "block/qdict.h"
|
#include "block/qdict.h"
|
||||||
#include "block/nbd.h"
|
#include "block/nbd.h"
|
||||||
|
@ -62,6 +63,47 @@ typedef enum NBDClientState {
|
||||||
NBD_CLIENT_QUIT
|
NBD_CLIENT_QUIT
|
||||||
} NBDClientState;
|
} NBDClientState;
|
||||||
|
|
||||||
|
typedef enum NBDConnectThreadState {
|
||||||
|
/* No thread, no pending results */
|
||||||
|
CONNECT_THREAD_NONE,
|
||||||
|
|
||||||
|
/* Thread is running, no results for now */
|
||||||
|
CONNECT_THREAD_RUNNING,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Thread is running, but requestor exited. Thread should close
|
||||||
|
* the new socket and free the connect state on exit.
|
||||||
|
*/
|
||||||
|
CONNECT_THREAD_RUNNING_DETACHED,
|
||||||
|
|
||||||
|
/* Thread finished, results are stored in a state */
|
||||||
|
CONNECT_THREAD_FAIL,
|
||||||
|
CONNECT_THREAD_SUCCESS
|
||||||
|
} NBDConnectThreadState;
|
||||||
|
|
||||||
|
typedef struct NBDConnectThread {
|
||||||
|
/* Initialization constants */
|
||||||
|
SocketAddress *saddr; /* address to connect to */
|
||||||
|
/*
|
||||||
|
* Bottom half to schedule on completion. Scheduled only if bh_ctx is not
|
||||||
|
* NULL
|
||||||
|
*/
|
||||||
|
QEMUBHFunc *bh_func;
|
||||||
|
void *bh_opaque;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Result of last attempt. Valid in FAIL and SUCCESS states.
|
||||||
|
* If you want to steal error, don't forget to set pointer to NULL.
|
||||||
|
*/
|
||||||
|
QIOChannelSocket *sioc;
|
||||||
|
Error *err;
|
||||||
|
|
||||||
|
/* state and bh_ctx are protected by mutex */
|
||||||
|
QemuMutex mutex;
|
||||||
|
NBDConnectThreadState state; /* current state of the thread */
|
||||||
|
AioContext *bh_ctx; /* where to schedule bh (NULL means don't schedule) */
|
||||||
|
} NBDConnectThread;
|
||||||
|
|
||||||
typedef struct BDRVNBDState {
|
typedef struct BDRVNBDState {
|
||||||
QIOChannelSocket *sioc; /* The master data channel */
|
QIOChannelSocket *sioc; /* The master data channel */
|
||||||
QIOChannel *ioc; /* The current I/O channel which may differ (eg TLS) */
|
QIOChannel *ioc; /* The current I/O channel which may differ (eg TLS) */
|
||||||
|
@ -91,10 +133,17 @@ typedef struct BDRVNBDState {
|
||||||
QCryptoTLSCreds *tlscreds;
|
QCryptoTLSCreds *tlscreds;
|
||||||
const char *hostname;
|
const char *hostname;
|
||||||
char *x_dirty_bitmap;
|
char *x_dirty_bitmap;
|
||||||
|
|
||||||
|
bool wait_connect;
|
||||||
|
NBDConnectThread *connect_thread;
|
||||||
} BDRVNBDState;
|
} BDRVNBDState;
|
||||||
|
|
||||||
static QIOChannelSocket *nbd_establish_connection(SocketAddress *saddr,
|
static QIOChannelSocket *nbd_establish_connection(SocketAddress *saddr,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
static QIOChannelSocket *nbd_co_establish_connection(BlockDriverState *bs,
|
||||||
|
Error **errp);
|
||||||
|
static void nbd_co_establish_connection_cancel(BlockDriverState *bs,
|
||||||
|
bool detach);
|
||||||
static int nbd_client_handshake(BlockDriverState *bs, QIOChannelSocket *sioc,
|
static int nbd_client_handshake(BlockDriverState *bs, QIOChannelSocket *sioc,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
|
||||||
|
@ -191,6 +240,8 @@ static void coroutine_fn nbd_client_co_drain_begin(BlockDriverState *bs)
|
||||||
if (s->connection_co_sleep_ns_state) {
|
if (s->connection_co_sleep_ns_state) {
|
||||||
qemu_co_sleep_wake(s->connection_co_sleep_ns_state);
|
qemu_co_sleep_wake(s->connection_co_sleep_ns_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nbd_co_establish_connection_cancel(bs, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void coroutine_fn nbd_client_co_drain_end(BlockDriverState *bs)
|
static void coroutine_fn nbd_client_co_drain_end(BlockDriverState *bs)
|
||||||
|
@ -223,6 +274,7 @@ static void nbd_teardown_connection(BlockDriverState *bs)
|
||||||
if (s->connection_co_sleep_ns_state) {
|
if (s->connection_co_sleep_ns_state) {
|
||||||
qemu_co_sleep_wake(s->connection_co_sleep_ns_state);
|
qemu_co_sleep_wake(s->connection_co_sleep_ns_state);
|
||||||
}
|
}
|
||||||
|
nbd_co_establish_connection_cancel(bs, true);
|
||||||
}
|
}
|
||||||
if (qemu_in_coroutine()) {
|
if (qemu_in_coroutine()) {
|
||||||
s->teardown_co = qemu_coroutine_self();
|
s->teardown_co = qemu_coroutine_self();
|
||||||
|
@ -246,6 +298,216 @@ static bool nbd_client_connecting_wait(BDRVNBDState *s)
|
||||||
return s->state == NBD_CLIENT_CONNECTING_WAIT;
|
return s->state == NBD_CLIENT_CONNECTING_WAIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void connect_bh(void *opaque)
|
||||||
|
{
|
||||||
|
BDRVNBDState *state = opaque;
|
||||||
|
|
||||||
|
assert(state->wait_connect);
|
||||||
|
state->wait_connect = false;
|
||||||
|
aio_co_wake(state->connection_co);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nbd_init_connect_thread(BDRVNBDState *s)
|
||||||
|
{
|
||||||
|
s->connect_thread = g_new(NBDConnectThread, 1);
|
||||||
|
|
||||||
|
*s->connect_thread = (NBDConnectThread) {
|
||||||
|
.saddr = QAPI_CLONE(SocketAddress, s->saddr),
|
||||||
|
.state = CONNECT_THREAD_NONE,
|
||||||
|
.bh_func = connect_bh,
|
||||||
|
.bh_opaque = s,
|
||||||
|
};
|
||||||
|
|
||||||
|
qemu_mutex_init(&s->connect_thread->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nbd_free_connect_thread(NBDConnectThread *thr)
|
||||||
|
{
|
||||||
|
if (thr->sioc) {
|
||||||
|
qio_channel_close(QIO_CHANNEL(thr->sioc), NULL);
|
||||||
|
}
|
||||||
|
error_free(thr->err);
|
||||||
|
qapi_free_SocketAddress(thr->saddr);
|
||||||
|
g_free(thr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *connect_thread_func(void *opaque)
|
||||||
|
{
|
||||||
|
NBDConnectThread *thr = opaque;
|
||||||
|
int ret;
|
||||||
|
bool do_free = false;
|
||||||
|
|
||||||
|
thr->sioc = qio_channel_socket_new();
|
||||||
|
|
||||||
|
error_free(thr->err);
|
||||||
|
thr->err = NULL;
|
||||||
|
ret = qio_channel_socket_connect_sync(thr->sioc, thr->saddr, &thr->err);
|
||||||
|
if (ret < 0) {
|
||||||
|
object_unref(OBJECT(thr->sioc));
|
||||||
|
thr->sioc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
qemu_mutex_lock(&thr->mutex);
|
||||||
|
|
||||||
|
switch (thr->state) {
|
||||||
|
case CONNECT_THREAD_RUNNING:
|
||||||
|
thr->state = ret < 0 ? CONNECT_THREAD_FAIL : CONNECT_THREAD_SUCCESS;
|
||||||
|
if (thr->bh_ctx) {
|
||||||
|
aio_bh_schedule_oneshot(thr->bh_ctx, thr->bh_func, thr->bh_opaque);
|
||||||
|
|
||||||
|
/* play safe, don't reuse bh_ctx on further connection attempts */
|
||||||
|
thr->bh_ctx = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CONNECT_THREAD_RUNNING_DETACHED:
|
||||||
|
do_free = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
qemu_mutex_unlock(&thr->mutex);
|
||||||
|
|
||||||
|
if (do_free) {
|
||||||
|
nbd_free_connect_thread(thr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QIOChannelSocket *coroutine_fn
|
||||||
|
nbd_co_establish_connection(BlockDriverState *bs, Error **errp)
|
||||||
|
{
|
||||||
|
QemuThread thread;
|
||||||
|
BDRVNBDState *s = bs->opaque;
|
||||||
|
QIOChannelSocket *res;
|
||||||
|
NBDConnectThread *thr = s->connect_thread;
|
||||||
|
|
||||||
|
qemu_mutex_lock(&thr->mutex);
|
||||||
|
|
||||||
|
switch (thr->state) {
|
||||||
|
case CONNECT_THREAD_FAIL:
|
||||||
|
case CONNECT_THREAD_NONE:
|
||||||
|
error_free(thr->err);
|
||||||
|
thr->err = NULL;
|
||||||
|
thr->state = CONNECT_THREAD_RUNNING;
|
||||||
|
qemu_thread_create(&thread, "nbd-connect",
|
||||||
|
connect_thread_func, thr, QEMU_THREAD_DETACHED);
|
||||||
|
break;
|
||||||
|
case CONNECT_THREAD_SUCCESS:
|
||||||
|
/* Previous attempt finally succeeded in background */
|
||||||
|
thr->state = CONNECT_THREAD_NONE;
|
||||||
|
res = thr->sioc;
|
||||||
|
thr->sioc = NULL;
|
||||||
|
qemu_mutex_unlock(&thr->mutex);
|
||||||
|
return res;
|
||||||
|
case CONNECT_THREAD_RUNNING:
|
||||||
|
/* Already running, will wait */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
thr->bh_ctx = qemu_get_current_aio_context();
|
||||||
|
|
||||||
|
qemu_mutex_unlock(&thr->mutex);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are going to wait for connect-thread finish, but
|
||||||
|
* nbd_client_co_drain_begin() can interrupt.
|
||||||
|
*
|
||||||
|
* Note that wait_connect variable is not visible for connect-thread. It
|
||||||
|
* doesn't need mutex protection, it used only inside home aio context of
|
||||||
|
* bs.
|
||||||
|
*/
|
||||||
|
s->wait_connect = true;
|
||||||
|
qemu_coroutine_yield();
|
||||||
|
|
||||||
|
qemu_mutex_lock(&thr->mutex);
|
||||||
|
|
||||||
|
switch (thr->state) {
|
||||||
|
case CONNECT_THREAD_SUCCESS:
|
||||||
|
case CONNECT_THREAD_FAIL:
|
||||||
|
thr->state = CONNECT_THREAD_NONE;
|
||||||
|
error_propagate(errp, thr->err);
|
||||||
|
thr->err = NULL;
|
||||||
|
res = thr->sioc;
|
||||||
|
thr->sioc = NULL;
|
||||||
|
break;
|
||||||
|
case CONNECT_THREAD_RUNNING:
|
||||||
|
case CONNECT_THREAD_RUNNING_DETACHED:
|
||||||
|
/*
|
||||||
|
* Obviously, drained section wants to start. Report the attempt as
|
||||||
|
* failed. Still connect thread is executing in background, and its
|
||||||
|
* result may be used for next connection attempt.
|
||||||
|
*/
|
||||||
|
res = NULL;
|
||||||
|
error_setg(errp, "Connection attempt cancelled by other operation");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CONNECT_THREAD_NONE:
|
||||||
|
/*
|
||||||
|
* Impossible. We've seen this thread running. So it should be
|
||||||
|
* running or at least give some results.
|
||||||
|
*/
|
||||||
|
abort();
|
||||||
|
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
qemu_mutex_unlock(&thr->mutex);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nbd_co_establish_connection_cancel
|
||||||
|
* Cancel nbd_co_establish_connection asynchronously: it will finish soon, to
|
||||||
|
* allow drained section to begin.
|
||||||
|
*
|
||||||
|
* If detach is true, also cleanup the state (or if thread is running, move it
|
||||||
|
* to CONNECT_THREAD_RUNNING_DETACHED state). s->connect_thread becomes NULL if
|
||||||
|
* detach is true.
|
||||||
|
*/
|
||||||
|
static void nbd_co_establish_connection_cancel(BlockDriverState *bs,
|
||||||
|
bool detach)
|
||||||
|
{
|
||||||
|
BDRVNBDState *s = bs->opaque;
|
||||||
|
NBDConnectThread *thr = s->connect_thread;
|
||||||
|
bool wake = false;
|
||||||
|
bool do_free = false;
|
||||||
|
|
||||||
|
qemu_mutex_lock(&thr->mutex);
|
||||||
|
|
||||||
|
if (thr->state == CONNECT_THREAD_RUNNING) {
|
||||||
|
/* We can cancel only in running state, when bh is not yet scheduled */
|
||||||
|
thr->bh_ctx = NULL;
|
||||||
|
if (s->wait_connect) {
|
||||||
|
s->wait_connect = false;
|
||||||
|
wake = true;
|
||||||
|
}
|
||||||
|
if (detach) {
|
||||||
|
thr->state = CONNECT_THREAD_RUNNING_DETACHED;
|
||||||
|
s->connect_thread = NULL;
|
||||||
|
}
|
||||||
|
} else if (detach) {
|
||||||
|
do_free = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
qemu_mutex_unlock(&thr->mutex);
|
||||||
|
|
||||||
|
if (do_free) {
|
||||||
|
nbd_free_connect_thread(thr);
|
||||||
|
s->connect_thread = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wake) {
|
||||||
|
aio_co_wake(s->connection_co);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static coroutine_fn void nbd_reconnect_attempt(BDRVNBDState *s)
|
static coroutine_fn void nbd_reconnect_attempt(BDRVNBDState *s)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -289,7 +551,7 @@ static coroutine_fn void nbd_reconnect_attempt(BDRVNBDState *s)
|
||||||
s->ioc = NULL;
|
s->ioc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sioc = nbd_establish_connection(s->saddr, &local_err);
|
sioc = nbd_co_establish_connection(s->bs, &local_err);
|
||||||
if (!sioc) {
|
if (!sioc) {
|
||||||
ret = -ECONNREFUSED;
|
ret = -ECONNREFUSED;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1946,6 +2208,8 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
|
||||||
/* successfully connected */
|
/* successfully connected */
|
||||||
s->state = NBD_CLIENT_CONNECTED;
|
s->state = NBD_CLIENT_CONNECTED;
|
||||||
|
|
||||||
|
nbd_init_connect_thread(s);
|
||||||
|
|
||||||
s->connection_co = qemu_coroutine_create(nbd_connection_entry, s);
|
s->connection_co = qemu_coroutine_create(nbd_connection_entry, s);
|
||||||
bdrv_inc_in_flight(bs);
|
bdrv_inc_in_flight(bs);
|
||||||
aio_co_schedule(bdrv_get_aio_context(bs), s->connection_co);
|
aio_co_schedule(bdrv_get_aio_context(bs), s->connection_co);
|
||||||
|
|
|
@ -1095,12 +1095,9 @@ if have_tools
|
||||||
dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
|
dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
|
||||||
qemu_io = executable('qemu-io', files('qemu-io.c'),
|
qemu_io = executable('qemu-io', files('qemu-io.c'),
|
||||||
dependencies: [block, qemuutil], install: true)
|
dependencies: [block, qemuutil], install: true)
|
||||||
qemu_block_tools += [qemu_img, qemu_io]
|
qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
|
||||||
if targetos != 'windows'
|
|
||||||
qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
|
|
||||||
dependencies: [block, qemuutil], install: true)
|
dependencies: [block, qemuutil], install: true)
|
||||||
qemu_block_tools += [qemu_nbd]
|
qemu_block_tools += [qemu_img, qemu_io, qemu_nbd]
|
||||||
endif
|
|
||||||
|
|
||||||
subdir('storage-daemon')
|
subdir('storage-daemon')
|
||||||
subdir('contrib/rdmacm-mux')
|
subdir('contrib/rdmacm-mux')
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
|
#include "qemu/sockets.h"
|
||||||
#include "qemu/units.h"
|
#include "qemu/units.h"
|
||||||
#include "qom/object_interfaces.h"
|
#include "qom/object_interfaces.h"
|
||||||
#include "sysemu/block-backend.h"
|
#include "sysemu/block-backend.h"
|
||||||
|
@ -5410,6 +5411,7 @@ int main(int argc, char **argv)
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
socket_init();
|
||||||
error_init(argv[0]);
|
error_init(argv[0]);
|
||||||
module_call_init(MODULE_INIT_TRACE);
|
module_call_init(MODULE_INIT_TRACE);
|
||||||
qemu_init_exec_dir(argv[0]);
|
qemu_init_exec_dir(argv[0]);
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "qemu/config-file.h"
|
#include "qemu/config-file.h"
|
||||||
#include "qemu/readline.h"
|
#include "qemu/readline.h"
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
|
#include "qemu/sockets.h"
|
||||||
#include "qapi/qmp/qstring.h"
|
#include "qapi/qmp/qstring.h"
|
||||||
#include "qapi/qmp/qdict.h"
|
#include "qapi/qmp/qdict.h"
|
||||||
#include "qom/object_interfaces.h"
|
#include "qom/object_interfaces.h"
|
||||||
|
@ -542,6 +543,7 @@ int main(int argc, char **argv)
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
socket_init();
|
||||||
error_init(argv[0]);
|
error_init(argv[0]);
|
||||||
module_call_init(MODULE_INIT_TRACE);
|
module_call_init(MODULE_INIT_TRACE);
|
||||||
qemu_init_exec_dir(argv[0]);
|
qemu_init_exec_dir(argv[0]);
|
||||||
|
|
11
qemu-nbd.c
11
qemu-nbd.c
|
@ -155,12 +155,13 @@ QEMU_COPYRIGHT "\n"
|
||||||
, name);
|
, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HAVE_NBD_DEVICE
|
||||||
static void termsig_handler(int signum)
|
static void termsig_handler(int signum)
|
||||||
{
|
{
|
||||||
atomic_cmpxchg(&state, RUNNING, TERMINATE);
|
atomic_cmpxchg(&state, RUNNING, TERMINATE);
|
||||||
qemu_notify_event();
|
qemu_notify_event();
|
||||||
}
|
}
|
||||||
|
#endif /* HAVE_NBD_DEVICE */
|
||||||
|
|
||||||
static int qemu_nbd_client_list(SocketAddress *saddr, QCryptoTLSCreds *tls,
|
static int qemu_nbd_client_list(SocketAddress *saddr, QCryptoTLSCreds *tls,
|
||||||
const char *hostname)
|
const char *hostname)
|
||||||
|
@ -587,6 +588,7 @@ int main(int argc, char **argv)
|
||||||
unsigned socket_activation;
|
unsigned socket_activation;
|
||||||
const char *pid_file_name = NULL;
|
const char *pid_file_name = NULL;
|
||||||
|
|
||||||
|
#if HAVE_NBD_DEVICE
|
||||||
/* The client thread uses SIGTERM to interrupt the server. A signal
|
/* The client thread uses SIGTERM to interrupt the server. A signal
|
||||||
* handler ensures that "qemu-nbd -v -c" exits with a nice status code.
|
* handler ensures that "qemu-nbd -v -c" exits with a nice status code.
|
||||||
*/
|
*/
|
||||||
|
@ -594,11 +596,13 @@ int main(int argc, char **argv)
|
||||||
memset(&sa_sigterm, 0, sizeof(sa_sigterm));
|
memset(&sa_sigterm, 0, sizeof(sa_sigterm));
|
||||||
sa_sigterm.sa_handler = termsig_handler;
|
sa_sigterm.sa_handler = termsig_handler;
|
||||||
sigaction(SIGTERM, &sa_sigterm, NULL);
|
sigaction(SIGTERM, &sa_sigterm, NULL);
|
||||||
|
#endif /* HAVE_NBD_DEVICE */
|
||||||
|
|
||||||
#ifdef CONFIG_POSIX
|
#ifdef CONFIG_POSIX
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
socket_init();
|
||||||
error_init(argv[0]);
|
error_init(argv[0]);
|
||||||
module_call_init(MODULE_INIT_TRACE);
|
module_call_init(MODULE_INIT_TRACE);
|
||||||
qcrypto_init(&error_fatal);
|
qcrypto_init(&error_fatal);
|
||||||
|
@ -895,6 +899,7 @@ int main(int argc, char **argv)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((device && !verbose) || fork_process) {
|
if ((device && !verbose) || fork_process) {
|
||||||
|
#ifndef WIN32
|
||||||
int stderr_fd[2];
|
int stderr_fd[2];
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -958,6 +963,10 @@ int main(int argc, char **argv)
|
||||||
*/
|
*/
|
||||||
exit(errors);
|
exit(errors);
|
||||||
}
|
}
|
||||||
|
#else /* WIN32 */
|
||||||
|
error_report("Unable to fork into background on Windows hosts");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
#endif /* WIN32 */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device != NULL && sockpath == NULL) {
|
if (device != NULL && sockpath == NULL) {
|
||||||
|
|
|
@ -19,8 +19,8 @@ file format: IMGFMT
|
||||||
virtual size: 2 GiB (2147483648 bytes)
|
virtual size: 2 GiB (2147483648 bytes)
|
||||||
|
|
||||||
=== Testing monolithicFlat with zeroed_grain ===
|
=== Testing monolithicFlat with zeroed_grain ===
|
||||||
qemu-img: TEST_DIR/t.IMGFMT: Flat image can't enable zeroed grain
|
|
||||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648
|
||||||
|
qemu-img: TEST_DIR/t.IMGFMT: Flat image can't enable zeroed grain
|
||||||
|
|
||||||
=== Testing big twoGbMaxExtentFlat ===
|
=== Testing big twoGbMaxExtentFlat ===
|
||||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000
|
||||||
|
|
|
@ -10,5 +10,5 @@ disk size: unavailable
|
||||||
|
|
||||||
--- Testing creation for which the node would need to grow ---
|
--- Testing creation for which the node would need to grow ---
|
||||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=qcow2 size=67108864 preallocation=metadata
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=qcow2 size=67108864 preallocation=metadata
|
||||||
qemu-img: TEST_DIR/t.IMGFMT: Could not resize image: Image format driver does not support resize
|
qemu-img: TEST_DIR/t.IMGFMT: Could not resize image: Cannot grow NBD nodes
|
||||||
*** done
|
*** done
|
||||||
|
|
Loading…
Reference in New Issue