aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nbd.c49
-rw-r--r--nbd.h4
2 files changed, 53 insertions, 0 deletions
diff --git a/nbd.c b/nbd.c
index 2e9de70288..2d2221c7fc 100644
--- a/nbd.c
+++ b/nbd.c
@@ -93,13 +93,17 @@ struct NBDExport {
void (*close)(NBDExport *exp);
BlockDriverState *bs;
+ char *name;
off_t dev_offset;
off_t size;
uint32_t nbdflags;
QTAILQ_HEAD(, NBDClient) clients;
QSIMPLEQ_HEAD(, NBDRequest) requests;
+ QTAILQ_ENTRY(NBDExport) next;
};
+static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
+
struct NBDClient {
int refcount;
void (*close)(NBDClient *client);
@@ -740,6 +744,39 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
return exp;
}
+NBDExport *nbd_export_find(const char *name)
+{
+ NBDExport *exp;
+ QTAILQ_FOREACH(exp, &exports, next) {
+ if (strcmp(name, exp->name) == 0) {
+ return exp;
+ }
+ }
+
+ return NULL;
+}
+
+void nbd_export_set_name(NBDExport *exp, const char *name)
+{
+ if (exp->name == name) {
+ return;
+ }
+
+ nbd_export_get(exp);
+ if (exp->name != NULL) {
+ g_free(exp->name);
+ exp->name = NULL;
+ QTAILQ_REMOVE(&exports, exp, next);
+ nbd_export_put(exp);
+ }
+ if (name != NULL) {
+ nbd_export_get(exp);
+ exp->name = g_strdup(name);
+ QTAILQ_INSERT_TAIL(&exports, exp, next);
+ }
+ nbd_export_put(exp);
+}
+
void nbd_export_close(NBDExport *exp)
{
NBDClient *client, *next;
@@ -765,6 +802,8 @@ void nbd_export_put(NBDExport *exp)
}
if (--exp->refcount == 0) {
+ assert(exp->name == NULL);
+
if (exp->close) {
exp->close(exp);
}
@@ -780,6 +819,16 @@ void nbd_export_put(NBDExport *exp)
}
}
+void nbd_export_close_all(void)
+{
+ NBDExport *exp, *next;
+
+ QTAILQ_FOREACH_SAFE(exp, &exports, next, next) {
+ nbd_export_close(exp);
+ nbd_export_set_name(exp, NULL);
+ }
+}
+
static int nbd_can_read(void *opaque);
static void nbd_read(void *opaque);
static void nbd_restart_write(void *opaque);
diff --git a/nbd.h b/nbd.h
index 895820b450..f0edb9cdf1 100644
--- a/nbd.h
+++ b/nbd.h
@@ -85,6 +85,10 @@ void nbd_export_close(NBDExport *exp);
void nbd_export_get(NBDExport *exp);
void nbd_export_put(NBDExport *exp);
+NBDExport *nbd_export_find(const char *name);
+void nbd_export_set_name(NBDExport *exp, const char *name);
+void nbd_export_close_all(void);
+
NBDClient *nbd_client_new(NBDExport *exp, int csock,
void (*close)(NBDClient *));
void nbd_client_close(NBDClient *client);