nbd: add notification for closing an NBDExport

In order to exit cleanly from qemu-nbd, add a callback that triggers
when an NBDExport is closed.  In the case of qemu-nbd it will exit the
main loop.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2012-09-18 13:59:03 +02:00
parent 4b9441f6b3
commit 0ddf08db22
3 changed files with 12 additions and 3 deletions

10
nbd.c
View File

@ -90,6 +90,8 @@ struct NBDRequest {
struct NBDExport { struct NBDExport {
int refcount; int refcount;
void (*close)(NBDExport *exp);
BlockDriverState *bs; BlockDriverState *bs;
off_t dev_offset; off_t dev_offset;
off_t size; off_t size;
@ -723,7 +725,8 @@ static void nbd_request_put(NBDRequest *req)
} }
NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
off_t size, uint32_t nbdflags) off_t size, uint32_t nbdflags,
void (*close)(NBDExport *))
{ {
NBDExport *exp = g_malloc0(sizeof(NBDExport)); NBDExport *exp = g_malloc0(sizeof(NBDExport));
QSIMPLEQ_INIT(&exp->requests); QSIMPLEQ_INIT(&exp->requests);
@ -733,6 +736,7 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
exp->dev_offset = dev_offset; exp->dev_offset = dev_offset;
exp->nbdflags = nbdflags; exp->nbdflags = nbdflags;
exp->size = size == -1 ? bdrv_getlength(bs) : size; exp->size = size == -1 ? bdrv_getlength(bs) : size;
exp->close = close;
return exp; return exp;
} }
@ -761,6 +765,10 @@ void nbd_export_put(NBDExport *exp)
} }
if (--exp->refcount == 0) { if (--exp->refcount == 0) {
if (exp->close) {
exp->close(exp);
}
while (!QSIMPLEQ_EMPTY(&exp->requests)) { while (!QSIMPLEQ_EMPTY(&exp->requests)) {
NBDRequest *first = QSIMPLEQ_FIRST(&exp->requests); NBDRequest *first = QSIMPLEQ_FIRST(&exp->requests);
QSIMPLEQ_REMOVE_HEAD(&exp->requests, entry); QSIMPLEQ_REMOVE_HEAD(&exp->requests, entry);

3
nbd.h
View File

@ -79,7 +79,8 @@ typedef struct NBDExport NBDExport;
typedef struct NBDClient NBDClient; typedef struct NBDClient NBDClient;
NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
off_t size, uint32_t nbdflags); off_t size, uint32_t nbdflags,
void (*close)(NBDExport *));
void nbd_export_close(NBDExport *exp); void nbd_export_close(NBDExport *exp);
void nbd_export_get(NBDExport *exp); void nbd_export_get(NBDExport *exp);
void nbd_export_put(NBDExport *exp); void nbd_export_put(NBDExport *exp);

View File

@ -546,7 +546,7 @@ int main(int argc, char **argv)
} }
} }
exp = nbd_export_new(bs, dev_offset, fd_size, nbdflags); exp = nbd_export_new(bs, dev_offset, fd_size, nbdflags, NULL);
if (sockpath) { if (sockpath) {
fd = unix_socket_incoming(sockpath); fd = unix_socket_incoming(sockpath);