2 * QEMU Block driver for Archipelago
6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
7 * See the COPYING file in the top-level directory.
12 * VM Image on Archipelago volume is specified like this:
14 * file.driver=archipelago,file.volume=<volumename>
15 * [,file.mport=<mapperd_port>[,file.vport=<vlmcd_port>]
16 * [,file.segment=<segment_name>]]
20 * file=archipelago:<volumename>[/mport=<mapperd_port>[:vport=<vlmcd_port>][:
21 * segment=<segment_name>]]
23 * 'archipelago' is the protocol.
25 * 'mport' is the port number on which mapperd is listening. This is optional
26 * and if not specified, QEMU will make Archipelago to use the default port.
28 * 'vport' is the port number on which vlmcd is listening. This is optional
29 * and if not specified, QEMU will make Archipelago to use the default port.
31 * 'segment' is the name of the shared memory segment Archipelago stack
32 * is using. This is optional and if not specified, QEMU will make Archipelago
33 * to use the default value, 'archipelago'.
37 * file.driver=archipelago,file.volume=my_vm_volume
38 * file.driver=archipelago,file.volume=my_vm_volume,file.mport=123
39 * file.driver=archipelago,file.volume=my_vm_volume,file.mport=123,
41 * file.driver=archipelago,file.volume=my_vm_volume,file.mport=123,
42 * file.vport=1234,file.segment=my_segment
46 * file=archipelago:my_vm_volume
47 * file=archipelago:my_vm_volume/mport=123
48 * file=archipelago:my_vm_volume/mport=123:vport=1234
49 * file=archipelago:my_vm_volume/mport=123:vport=1234:segment=my_segment
53 #include "qemu-common.h"
54 #include "block/block_int.h"
55 #include "qemu/error-report.h"
56 #include "qemu/thread.h"
57 #include "qapi/qmp/qint.h"
58 #include "qapi/qmp/qstring.h"
59 #include "qapi/qmp/qjson.h"
60 #include "qemu/atomic.h"
63 #include <xseg/xseg.h>
64 #include <xseg/protocol.h>
66 #define ARCHIP_FD_READ 0
67 #define ARCHIP_FD_WRITE 1
68 #define MAX_REQUEST_SIZE 524288
70 #define ARCHIPELAGO_OPT_VOLUME "volume"
71 #define ARCHIPELAGO_OPT_SEGMENT "segment"
72 #define ARCHIPELAGO_OPT_MPORT "mport"
73 #define ARCHIPELAGO_OPT_VPORT "vport"
74 #define ARCHIPELAGO_DFL_MPORT 1001
75 #define ARCHIPELAGO_DFL_VPORT 501
77 #define archipelagolog(fmt, ...) \
79 fprintf(stderr, "archipelago\t%-24s: " fmt, __func__, ##__VA_ARGS__); \
89 typedef struct ArchipelagoAIOCB {
90 BlockDriverAIOCB common;
92 struct BDRVArchipelagoState *s;
101 typedef struct BDRVArchipelagoState {
102 ArchipelagoAIOCB *event_acb;
106 /* Archipelago specific */
108 struct xseg_port *port;
113 QemuMutex archip_mutex;
114 QemuCond archip_cond;
116 /* Request handler specific */
117 QemuThread request_th;
118 QemuCond request_cond;
119 QemuMutex request_mutex;
122 } BDRVArchipelagoState;
124 typedef struct ArchipelagoSegmentedRequest {
129 } ArchipelagoSegmentedRequest;
131 typedef struct AIORequestData {
138 ArchipelagoAIOCB *aio_cb;
139 ArchipelagoSegmentedRequest *segreq;
142 static void qemu_archipelago_complete_aio(void *opaque);
144 static void init_local_signal(struct xseg *xseg, xport sport, xport srcport)
146 if (xseg && (sport != srcport)) {
147 xseg_init_local_signal(xseg, srcport);
152 static void archipelago_finish_aiocb(AIORequestData *reqdata)
154 if (reqdata->aio_cb->ret != reqdata->segreq->total) {
155 reqdata->aio_cb->ret = -EIO;
156 } else if (reqdata->aio_cb->ret == reqdata->segreq->total) {
157 reqdata->aio_cb->ret = 0;
159 reqdata->aio_cb->bh = aio_bh_new(
160 bdrv_get_aio_context(reqdata->aio_cb->common.bs),
161 qemu_archipelago_complete_aio, reqdata
163 qemu_bh_schedule(reqdata->aio_cb->bh);
166 static int wait_reply(struct xseg *xseg, xport srcport, struct xseg_port *port,
167 struct xseg_request *expected_req)
169 struct xseg_request *req;
170 xseg_prepare_wait(xseg, srcport);
171 void *psd = xseg_get_signal_desc(xseg, port);
173 req = xseg_receive(xseg, srcport, X_NONBLOCK);
175 if (req != expected_req) {
176 archipelagolog("Unknown received request\n");
177 xseg_put_request(xseg, req, srcport);
178 } else if (!(req->state & XS_SERVED)) {
184 xseg_wait_signal(xseg, psd, 100000UL);
186 xseg_cancel_wait(xseg, srcport);
190 static void xseg_request_handler(void *state)
192 BDRVArchipelagoState *s = (BDRVArchipelagoState *) state;
193 void *psd = xseg_get_signal_desc(s->xseg, s->port);
194 qemu_mutex_lock(&s->request_mutex);
196 while (!s->stopping) {
197 struct xseg_request *req;
199 xseg_prepare_wait(s->xseg, s->srcport);
200 req = xseg_receive(s->xseg, s->srcport, X_NONBLOCK);
202 AIORequestData *reqdata;
203 ArchipelagoSegmentedRequest *segreq;
204 xseg_get_req_data(s->xseg, req, (void **)&reqdata);
206 switch (reqdata->op) {
208 data = xseg_get_data(s->xseg, req);
209 segreq = reqdata->segreq;
210 segreq->count += req->serviced;
212 qemu_iovec_from_buf(reqdata->aio_cb->qiov, reqdata->bufidx,
216 xseg_put_request(s->xseg, req, s->srcport);
218 if (atomic_fetch_dec(&segreq->ref) == 1) {
219 if (!segreq->failed) {
220 reqdata->aio_cb->ret = segreq->count;
221 archipelago_finish_aiocb(reqdata);
231 case ARCHIP_OP_WRITE:
232 case ARCHIP_OP_FLUSH:
233 segreq = reqdata->segreq;
234 segreq->count += req->serviced;
235 xseg_put_request(s->xseg, req, s->srcport);
237 if (atomic_fetch_dec(&segreq->ref) == 1) {
238 if (!segreq->failed) {
239 reqdata->aio_cb->ret = segreq->count;
240 archipelago_finish_aiocb(reqdata);
250 case ARCHIP_OP_VOLINFO:
251 s->is_signaled = true;
252 qemu_cond_signal(&s->archip_cond);
256 xseg_wait_signal(s->xseg, psd, 100000UL);
258 xseg_cancel_wait(s->xseg, s->srcport);
261 s->th_is_signaled = true;
262 qemu_cond_signal(&s->request_cond);
263 qemu_mutex_unlock(&s->request_mutex);
264 qemu_thread_exit(NULL);
267 static int qemu_archipelago_xseg_init(BDRVArchipelagoState *s)
269 if (xseg_initialize()) {
270 archipelagolog("Cannot initialize XSEG\n");
274 s->xseg = xseg_join("posix", s->segment_name,
277 archipelagolog("Cannot join XSEG shared memory segment\n");
280 s->port = xseg_bind_dynport(s->xseg);
281 s->srcport = s->port->portno;
282 init_local_signal(s->xseg, s->sport, s->srcport);
289 static int qemu_archipelago_init(BDRVArchipelagoState *s)
293 ret = qemu_archipelago_xseg_init(s);
295 error_report("Cannot initialize XSEG. Aborting...\n");
299 qemu_cond_init(&s->archip_cond);
300 qemu_mutex_init(&s->archip_mutex);
301 qemu_cond_init(&s->request_cond);
302 qemu_mutex_init(&s->request_mutex);
303 s->th_is_signaled = false;
304 qemu_thread_create(&s->request_th, "xseg_io_th",
305 (void *) xseg_request_handler,
306 (void *) s, QEMU_THREAD_JOINABLE);
312 static void qemu_archipelago_complete_aio(void *opaque)
314 AIORequestData *reqdata = (AIORequestData *) opaque;
315 ArchipelagoAIOCB *aio_cb = (ArchipelagoAIOCB *) reqdata->aio_cb;
317 qemu_bh_delete(aio_cb->bh);
318 aio_cb->common.cb(aio_cb->common.opaque, aio_cb->ret);
321 if (!aio_cb->cancelled) {
322 qemu_aio_release(aio_cb);
327 static void xseg_find_port(char *pstr, const char *needle, xport *aport)
332 if (strstart(pstr, needle, &a)) {
334 port = strtoul(a, &endptr, 10);
335 if (strlen(endptr)) {
339 *aport = (xport) port;
344 static void xseg_find_segment(char *pstr, const char *needle,
348 if (strstart(pstr, needle, &a)) {
350 *segment_name = g_strdup(a);
355 static void parse_filename_opts(const char *filename, Error **errp,
356 char **volume, char **segment_name,
357 xport *mport, xport *vport)
360 char *tokens[4], *ds;
362 xport lmport = NoPort, lvport = NoPort;
364 strstart(filename, "archipelago:", &start);
366 ds = g_strdup(start);
367 tokens[0] = strtok(ds, "/");
368 tokens[1] = strtok(NULL, ":");
369 tokens[2] = strtok(NULL, ":");
370 tokens[3] = strtok(NULL, "\0");
372 if (!strlen(tokens[0])) {
373 error_setg(errp, "volume name must be specified first");
378 for (idx = 1; idx < 4; idx++) {
379 if (tokens[idx] != NULL) {
380 if (strstart(tokens[idx], "mport=", NULL)) {
381 xseg_find_port(tokens[idx], "mport=", &lmport);
383 if (strstart(tokens[idx], "vport=", NULL)) {
384 xseg_find_port(tokens[idx], "vport=", &lvport);
386 if (strstart(tokens[idx], "segment=", NULL)) {
387 xseg_find_segment(tokens[idx], "segment=", segment_name);
392 if ((lmport == -2) || (lvport == -2)) {
393 error_setg(errp, "mport and/or vport must be set");
397 *volume = g_strdup(tokens[0]);
403 static void archipelago_parse_filename(const char *filename, QDict *options,
407 char *volume = NULL, *segment_name = NULL;
408 xport mport = NoPort, vport = NoPort;
410 if (qdict_haskey(options, ARCHIPELAGO_OPT_VOLUME)
411 || qdict_haskey(options, ARCHIPELAGO_OPT_SEGMENT)
412 || qdict_haskey(options, ARCHIPELAGO_OPT_MPORT)
413 || qdict_haskey(options, ARCHIPELAGO_OPT_VPORT)) {
414 error_setg(errp, "volume/mport/vport/segment and a file name may not"
415 " be specified at the same time");
419 if (!strstart(filename, "archipelago:", &start)) {
420 error_setg(errp, "File name must start with 'archipelago:'");
424 if (!strlen(start) || strstart(start, "/", NULL)) {
425 error_setg(errp, "volume name must be specified");
429 parse_filename_opts(filename, errp, &volume, &segment_name, &mport, &vport);
432 qdict_put(options, ARCHIPELAGO_OPT_VOLUME, qstring_from_str(volume));
436 qdict_put(options, ARCHIPELAGO_OPT_SEGMENT,
437 qstring_from_str(segment_name));
438 g_free(segment_name);
440 if (mport != NoPort) {
441 qdict_put(options, ARCHIPELAGO_OPT_MPORT, qint_from_int(mport));
443 if (vport != NoPort) {
444 qdict_put(options, ARCHIPELAGO_OPT_VPORT, qint_from_int(vport));
448 static QemuOptsList archipelago_runtime_opts = {
449 .name = "archipelago",
450 .head = QTAILQ_HEAD_INITIALIZER(archipelago_runtime_opts.head),
453 .name = ARCHIPELAGO_OPT_VOLUME,
454 .type = QEMU_OPT_STRING,
455 .help = "Name of the volume image",
458 .name = ARCHIPELAGO_OPT_SEGMENT,
459 .type = QEMU_OPT_STRING,
460 .help = "Name of the Archipelago shared memory segment",
463 .name = ARCHIPELAGO_OPT_MPORT,
464 .type = QEMU_OPT_NUMBER,
465 .help = "Archipelago mapperd port number"
468 .name = ARCHIPELAGO_OPT_VPORT,
469 .type = QEMU_OPT_NUMBER,
470 .help = "Archipelago vlmcd port number"
473 { /* end of list */ }
477 static int qemu_archipelago_open(BlockDriverState *bs,
483 const char *volume, *segment_name;
485 Error *local_err = NULL;
486 BDRVArchipelagoState *s = bs->opaque;
488 opts = qemu_opts_create(&archipelago_runtime_opts, NULL, 0, &error_abort);
489 qemu_opts_absorb_qdict(opts, options, &local_err);
491 error_propagate(errp, local_err);
496 s->mportno = qemu_opt_get_number(opts, ARCHIPELAGO_OPT_MPORT,
497 ARCHIPELAGO_DFL_MPORT);
498 s->vportno = qemu_opt_get_number(opts, ARCHIPELAGO_OPT_VPORT,
499 ARCHIPELAGO_DFL_VPORT);
501 segment_name = qemu_opt_get(opts, ARCHIPELAGO_OPT_SEGMENT);
502 if (segment_name == NULL) {
503 s->segment_name = g_strdup("archipelago");
505 s->segment_name = g_strdup(segment_name);
508 volume = qemu_opt_get(opts, ARCHIPELAGO_OPT_VOLUME);
509 if (volume == NULL) {
510 error_setg(errp, "archipelago block driver requires the 'volume'"
515 s->volname = g_strdup(volume);
517 /* Initialize XSEG, join shared memory segment */
518 ret = qemu_archipelago_init(s);
520 error_setg(errp, "cannot initialize XSEG and join shared "
530 g_free(s->segment_name);
535 static void qemu_archipelago_close(BlockDriverState *bs)
539 struct xseg_request *req;
540 BDRVArchipelagoState *s = bs->opaque;
544 qemu_mutex_lock(&s->request_mutex);
545 while (!s->th_is_signaled) {
546 qemu_cond_wait(&s->request_cond,
549 qemu_mutex_unlock(&s->request_mutex);
550 qemu_thread_join(&s->request_th);
551 qemu_cond_destroy(&s->request_cond);
552 qemu_mutex_destroy(&s->request_mutex);
554 qemu_cond_destroy(&s->archip_cond);
555 qemu_mutex_destroy(&s->archip_mutex);
557 targetlen = strlen(s->volname);
558 req = xseg_get_request(s->xseg, s->srcport, s->vportno, X_ALLOC);
560 archipelagolog("Cannot get XSEG request\n");
563 r = xseg_prep_request(s->xseg, req, targetlen, 0);
565 xseg_put_request(s->xseg, req, s->srcport);
566 archipelagolog("Cannot prepare XSEG close request\n");
570 target = xseg_get_target(s->xseg, req);
571 memcpy(target, s->volname, targetlen);
572 req->size = req->datalen;
576 xport p = xseg_submit(s->xseg, req, s->srcport, X_ALLOC);
578 xseg_put_request(s->xseg, req, s->srcport);
579 archipelagolog("Cannot submit XSEG close request\n");
583 xseg_signal(s->xseg, p);
584 wait_reply(s->xseg, s->srcport, s->port, req);
586 xseg_put_request(s->xseg, req, s->srcport);
590 g_free(s->segment_name);
591 xseg_quit_local_signal(s->xseg, s->srcport);
592 xseg_leave_dynport(s->xseg, s->port);
596 static int qemu_archipelago_create_volume(Error **errp, const char *volname,
598 uint64_t size, xport mportno,
602 struct xseg *xseg = NULL;
603 struct xseg_request *req;
604 struct xseg_request_clone *xclone;
605 struct xseg_port *port;
606 xport srcport = NoPort, sport = NoPort;
609 /* Try default values if none has been set */
610 if (mportno == (xport) -1) {
611 mportno = ARCHIPELAGO_DFL_MPORT;
614 if (vportno == (xport) -1) {
615 vportno = ARCHIPELAGO_DFL_VPORT;
618 if (xseg_initialize()) {
619 error_setg(errp, "Cannot initialize XSEG");
623 xseg = xseg_join("posix", segment_name,
627 error_setg(errp, "Cannot join XSEG shared memory segment");
631 port = xseg_bind_dynport(xseg);
632 srcport = port->portno;
633 init_local_signal(xseg, sport, srcport);
635 req = xseg_get_request(xseg, srcport, mportno, X_ALLOC);
637 error_setg(errp, "Cannot get XSEG request");
641 targetlen = strlen(volname);
642 ret = xseg_prep_request(xseg, req, targetlen,
643 sizeof(struct xseg_request_clone));
645 error_setg(errp, "Cannot prepare XSEG request");
649 target = xseg_get_target(xseg, req);
651 error_setg(errp, "Cannot get XSEG target.\n");
654 memcpy(target, volname, targetlen);
655 xclone = (struct xseg_request_clone *) xseg_get_data(xseg, req);
656 memset(xclone->target, 0 , XSEG_MAX_TARGETLEN);
657 xclone->targetlen = 0;
660 req->size = req->datalen;
663 xport p = xseg_submit(xseg, req, srcport, X_ALLOC);
665 error_setg(errp, "Could not submit XSEG request");
668 xseg_signal(xseg, p);
670 ret = wait_reply(xseg, srcport, port, req);
672 error_setg(errp, "wait_reply() error.");
675 xseg_put_request(xseg, req, srcport);
676 xseg_quit_local_signal(xseg, srcport);
677 xseg_leave_dynport(xseg, port);
682 xseg_put_request(xseg, req, srcport);
683 xseg_quit_local_signal(xseg, srcport);
684 xseg_leave_dynport(xseg, port);
689 static int qemu_archipelago_create(const char *filename,
694 uint64_t total_size = 0;
695 char *volname = NULL, *segment_name = NULL;
697 xport mport = NoPort, vport = NoPort;
699 if (!strstart(filename, "archipelago:", &start)) {
700 error_setg(errp, "File name must start with 'archipelago:'");
704 if (!strlen(start) || strstart(start, "/", NULL)) {
705 error_setg(errp, "volume name must be specified");
709 parse_filename_opts(filename, errp, &volname, &segment_name, &mport,
711 total_size = qemu_opt_get_size_del(options, BLOCK_OPT_SIZE, 0);
713 if (segment_name == NULL) {
714 segment_name = g_strdup("archipelago");
717 /* Create an Archipelago volume */
718 ret = qemu_archipelago_create_volume(errp, volname, segment_name,
723 g_free(segment_name);
727 static void qemu_archipelago_aio_cancel(BlockDriverAIOCB *blockacb)
729 ArchipelagoAIOCB *aio_cb = (ArchipelagoAIOCB *) blockacb;
730 aio_cb->cancelled = true;
731 while (aio_cb->status == -EINPROGRESS) {
732 aio_poll(bdrv_get_aio_context(aio_cb->common.bs), true);
734 qemu_aio_release(aio_cb);
737 static const AIOCBInfo archipelago_aiocb_info = {
738 .aiocb_size = sizeof(ArchipelagoAIOCB),
739 .cancel = qemu_archipelago_aio_cancel,
742 static int archipelago_submit_request(BDRVArchipelagoState *s,
746 ArchipelagoAIOCB *aio_cb,
747 ArchipelagoSegmentedRequest *segreq,
753 struct xseg_request *req;
754 AIORequestData *reqdata = g_new(AIORequestData, 1);
756 targetlen = strlen(s->volname);
757 req = xseg_get_request(s->xseg, s->srcport, s->vportno, X_ALLOC);
759 archipelagolog("Cannot get XSEG request\n");
762 ret = xseg_prep_request(s->xseg, req, targetlen, count);
764 archipelagolog("Cannot prepare XSEG request\n");
767 target = xseg_get_target(s->xseg, req);
769 archipelagolog("Cannot get XSEG target\n");
772 memcpy(target, s->volname, targetlen);
774 req->offset = offset;
780 case ARCHIP_OP_WRITE:
783 case ARCHIP_OP_FLUSH:
787 reqdata->volname = s->volname;
788 reqdata->offset = offset;
789 reqdata->size = count;
790 reqdata->bufidx = bufidx;
791 reqdata->aio_cb = aio_cb;
792 reqdata->segreq = segreq;
795 xseg_set_req_data(s->xseg, req, reqdata);
796 if (op == ARCHIP_OP_WRITE) {
797 data = xseg_get_data(s->xseg, req);
799 archipelagolog("Cannot get XSEG data\n");
802 qemu_iovec_to_buf(aio_cb->qiov, bufidx, data, count);
805 xport p = xseg_submit(s->xseg, req, s->srcport, X_ALLOC);
807 archipelagolog("Could not submit XSEG request\n");
810 xseg_signal(s->xseg, p);
815 xseg_put_request(s->xseg, req, s->srcport);
822 static int archipelago_aio_segmented_rw(BDRVArchipelagoState *s,
825 ArchipelagoAIOCB *aio_cb,
828 int ret, segments_nr;
830 ArchipelagoSegmentedRequest *segreq;
832 segreq = g_new0(ArchipelagoSegmentedRequest, 1);
834 if (op == ARCHIP_OP_FLUSH) {
837 segments_nr = (int)(count / MAX_REQUEST_SIZE) + \
838 ((count % MAX_REQUEST_SIZE) ? 1 : 0);
840 segreq->total = count;
841 atomic_mb_set(&segreq->ref, segments_nr);
843 while (segments_nr > 1) {
844 ret = archipelago_submit_request(s, pos,
852 count -= MAX_REQUEST_SIZE;
853 pos += MAX_REQUEST_SIZE;
856 ret = archipelago_submit_request(s, pos, count, offset + pos,
866 if (atomic_fetch_sub(&segreq->ref, segments_nr) == segments_nr) {
872 static BlockDriverAIOCB *qemu_archipelago_aio_rw(BlockDriverState *bs,
876 BlockDriverCompletionFunc *cb,
880 ArchipelagoAIOCB *aio_cb;
881 BDRVArchipelagoState *s = bs->opaque;
885 aio_cb = qemu_aio_get(&archipelago_aiocb_info, bs, cb, opaque);
891 aio_cb->cancelled = false;
892 aio_cb->status = -EINPROGRESS;
894 off = sector_num * BDRV_SECTOR_SIZE;
895 size = nb_sectors * BDRV_SECTOR_SIZE;
898 ret = archipelago_aio_segmented_rw(s, size, off,
903 return &aio_cb->common;
906 error_report("qemu_archipelago_aio_rw(): I/O Error\n");
907 qemu_aio_release(aio_cb);
911 static BlockDriverAIOCB *qemu_archipelago_aio_readv(BlockDriverState *bs,
912 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
913 BlockDriverCompletionFunc *cb, void *opaque)
915 return qemu_archipelago_aio_rw(bs, sector_num, qiov, nb_sectors, cb,
916 opaque, ARCHIP_OP_READ);
919 static BlockDriverAIOCB *qemu_archipelago_aio_writev(BlockDriverState *bs,
920 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
921 BlockDriverCompletionFunc *cb, void *opaque)
923 return qemu_archipelago_aio_rw(bs, sector_num, qiov, nb_sectors, cb,
924 opaque, ARCHIP_OP_WRITE);
927 static int64_t archipelago_volume_info(BDRVArchipelagoState *s)
931 struct xseg_request *req;
932 struct xseg_reply_info *xinfo;
933 AIORequestData *reqdata = g_new(AIORequestData, 1);
935 const char *volname = s->volname;
936 targetlen = strlen(volname);
937 req = xseg_get_request(s->xseg, s->srcport, s->mportno, X_ALLOC);
939 archipelagolog("Cannot get XSEG request\n");
942 ret = xseg_prep_request(s->xseg, req, targetlen,
943 sizeof(struct xseg_reply_info));
945 archipelagolog("Cannot prepare XSEG request\n");
948 char *target = xseg_get_target(s->xseg, req);
950 archipelagolog("Cannot get XSEG target\n");
953 memcpy(target, volname, targetlen);
954 req->size = req->datalen;
958 reqdata->op = ARCHIP_OP_VOLINFO;
959 reqdata->volname = volname;
960 xseg_set_req_data(s->xseg, req, reqdata);
962 xport p = xseg_submit(s->xseg, req, s->srcport, X_ALLOC);
964 archipelagolog("Cannot submit XSEG request\n");
967 xseg_signal(s->xseg, p);
968 qemu_mutex_lock(&s->archip_mutex);
969 while (!s->is_signaled) {
970 qemu_cond_wait(&s->archip_cond, &s->archip_mutex);
972 s->is_signaled = false;
973 qemu_mutex_unlock(&s->archip_mutex);
975 xinfo = (struct xseg_reply_info *) xseg_get_data(s->xseg, req);
977 xseg_put_request(s->xseg, req, s->srcport);
983 xseg_put_request(s->xseg, req, s->srcport);
989 static int64_t qemu_archipelago_getlength(BlockDriverState *bs)
992 BDRVArchipelagoState *s = bs->opaque;
994 ret = archipelago_volume_info(s);
998 static QemuOptsList qemu_archipelago_create_opts = {
999 .name = "archipelago-create-opts",
1000 .head = QTAILQ_HEAD_INITIALIZER(qemu_archipelago_create_opts.head),
1003 .name = BLOCK_OPT_SIZE,
1004 .type = QEMU_OPT_SIZE,
1005 .help = "Virtual disk size"
1007 { /* end of list */ }
1011 static BlockDriverAIOCB *qemu_archipelago_aio_flush(BlockDriverState *bs,
1012 BlockDriverCompletionFunc *cb, void *opaque)
1014 return qemu_archipelago_aio_rw(bs, 0, NULL, 0, cb, opaque,
1018 static BlockDriver bdrv_archipelago = {
1019 .format_name = "archipelago",
1020 .protocol_name = "archipelago",
1021 .instance_size = sizeof(BDRVArchipelagoState),
1022 .bdrv_parse_filename = archipelago_parse_filename,
1023 .bdrv_file_open = qemu_archipelago_open,
1024 .bdrv_close = qemu_archipelago_close,
1025 .bdrv_create = qemu_archipelago_create,
1026 .bdrv_getlength = qemu_archipelago_getlength,
1027 .bdrv_aio_readv = qemu_archipelago_aio_readv,
1028 .bdrv_aio_writev = qemu_archipelago_aio_writev,
1029 .bdrv_aio_flush = qemu_archipelago_aio_flush,
1030 .bdrv_has_zero_init = bdrv_has_zero_init_1,
1031 .create_opts = &qemu_archipelago_create_opts,
1034 static void bdrv_archipelago_init(void)
1036 bdrv_register(&bdrv_archipelago);
1039 block_init(bdrv_archipelago_init);