From patchwork Fri Dec 23 15:26:22 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 133097 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id AD6BDB714C for ; Sat, 24 Dec 2011 03:22:06 +1100 (EST) Received: from localhost ([::1]:34065 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Re7sf-0001E1-76 for incoming@patchwork.ozlabs.org; Fri, 23 Dec 2011 11:22:01 -0500 Received: from eggs.gnu.org ([140.186.70.92]:41363) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Re73r-0003YS-J2 for qemu-devel@nongnu.org; Fri, 23 Dec 2011 10:29:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Re73p-0006lC-Ql for qemu-devel@nongnu.org; Fri, 23 Dec 2011 10:29:31 -0500 Received: from mail-iy0-f173.google.com ([209.85.210.173]:37591) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Re73p-0006jy-KK for qemu-devel@nongnu.org; Fri, 23 Dec 2011 10:29:29 -0500 Received: by mail-iy0-f173.google.com with SMTP id j37so17394063iag.4 for ; Fri, 23 Dec 2011 07:29:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=sender:from:to:subject:date:message-id:x-mailer:in-reply-to :references; bh=gWt7TD0NnLzXyt+99hgAdaTpdmmnu0Nw6zwUND54G0s=; b=oh0BIHpHY/PFOhLAdat5yeg9geVNfwROJS1qGVoHBXKSLZdcrkNbNmP6FexRCIdI0+ CLIijf632lf26uPoIMEBxziDXFHDAg8A19G00Cx4VPilMm4cHmF8vQRxHiT5tqi8tKg6 rrVlcIQ3RfFBk9mLoObgeQmyJSAsPqNfqHTO4= Received: by 10.42.148.136 with SMTP id r8mr15780419icv.1.1324654169424; Fri, 23 Dec 2011 07:29:29 -0800 (PST) Received: from localhost.localdomain (93-34-178-147.ip50.fastwebnet.it. [93.34.178.147]) by mx.google.com with ESMTPS id aq5sm42055557igc.5.2011.12.23.07.29.23 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 23 Dec 2011 07:29:28 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Fri, 23 Dec 2011 16:26:22 +0100 Message-Id: <1324653990-20074-19-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.7.1 In-Reply-To: <1324653990-20074-1-git-send-email-pbonzini@redhat.com> References: <1324653990-20074-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.210.173 Subject: [Qemu-devel] [PATCH 18/26] qemu-nbd: introduce NBDExport X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Wrap the common parameters of nbd_trip and nbd_negotiate in a single opaque struct. Signed-off-by: Paolo Bonzini --- nbd.c | 64 +++++++++++++++++++++++++++++++++++++++++++++--------------- nbd.h | 11 +++++++-- qemu-nbd.c | 15 ++++--------- 3 files changed, 61 insertions(+), 29 deletions(-) diff --git a/nbd.c b/nbd.c index 964a732..8d2a3bc 100644 --- a/nbd.c +++ b/nbd.c @@ -18,6 +18,7 @@ #include "nbd.h" #include "block.h" +#include "block_int.h" #include #include @@ -186,7 +187,7 @@ int unix_socket_outgoing(const char *path) Request (type == 2) */ -int nbd_negotiate(int csock, off_t size, uint32_t flags) +static int nbd_send_negotiate(int csock, off_t size, uint32_t flags) { char buf[8 + 8 + 8 + 128]; @@ -583,6 +584,33 @@ static int nbd_send_reply(int csock, struct nbd_reply *reply) return 0; } +struct NBDExport { + BlockDriverState *bs; + off_t dev_offset; + off_t size; + uint8_t *data; + uint32_t nbdflags; +}; + +NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, + off_t size, uint32_t nbdflags) +{ + NBDExport *exp = g_malloc0(sizeof(NBDExport)); + exp->bs = bs; + exp->dev_offset = dev_offset; + exp->nbdflags = nbdflags; + exp->size = size == -1 ? exp->bs->total_sectors * 512 : size; + exp->data = qemu_blockalign(exp->bs, NBD_BUFFER_SIZE); + return exp; +} + +void nbd_export_close(NBDExport *exp) +{ + qemu_vfree(exp->data); + bdrv_close(exp->bs); + g_free(exp); +} + static int nbd_do_send_reply(int csock, struct nbd_reply *reply, uint8_t *data, int len) { @@ -652,9 +680,7 @@ out: return rc; } -int nbd_trip(BlockDriverState *bs, int csock, off_t size, - uint64_t dev_offset, uint32_t nbdflags, - uint8_t *data) +int nbd_trip(NBDExport *exp, int csock) { struct nbd_request request; struct nbd_reply reply; @@ -662,7 +688,7 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, TRACE("Reading request."); - ret = nbd_do_receive_request(csock, &request, data); + ret = nbd_do_receive_request(csock, &request, exp->data); if (ret == -EIO) { return -1; } @@ -675,10 +701,11 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, goto error_reply; } - if ((request.from + request.len) > size) { + if ((request.from + request.len) > exp->size) { LOG("From: %" PRIu64 ", Len: %u, Size: %" PRIu64 ", Offset: %" PRIu64 "\n", - request.from, request.len, (uint64_t)size, dev_offset); + request.from, request.len, + (uint64_t)exp->size, exp->dev_offset); LOG("requested operation past EOF--bad client?"); goto invalid_request; } @@ -687,8 +714,8 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, case NBD_CMD_READ: TRACE("Request type is READ"); - ret = bdrv_read(bs, (request.from + dev_offset) / 512, - data, request.len / 512); + ret = bdrv_read(exp->bs, (request.from + exp->dev_offset) / 512, + exp->data, request.len / 512); if (ret < 0) { LOG("reading from file failed"); reply.error = -ret; @@ -696,13 +723,13 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, } TRACE("Read %u byte(s)", request.len); - if (nbd_do_send_reply(csock, &reply, data, request.len) < 0) + if (nbd_do_send_reply(csock, &reply, exp->data, request.len) < 0) return -1; break; case NBD_CMD_WRITE: TRACE("Request type is WRITE"); - if (nbdflags & NBD_FLAG_READ_ONLY) { + if (exp->nbdflags & NBD_FLAG_READ_ONLY) { TRACE("Server is read-only, return error"); reply.error = EROFS; goto error_reply; @@ -710,8 +737,8 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, TRACE("Writing to device"); - ret = bdrv_write(bs, (request.from + dev_offset) / 512, - data, request.len / 512); + ret = bdrv_write(exp->bs, (request.from + exp->dev_offset) / 512, + exp->data, request.len / 512); if (ret < 0) { LOG("writing to file failed"); reply.error = -ret; @@ -719,7 +746,7 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, } if (request.type & NBD_CMD_FLAG_FUA) { - ret = bdrv_flush(bs); + ret = bdrv_flush(exp->bs); if (ret < 0) { LOG("flush failed"); reply.error = -ret; @@ -737,7 +764,7 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, case NBD_CMD_FLUSH: TRACE("Request type is FLUSH"); - ret = bdrv_flush(bs); + ret = bdrv_flush(exp->bs); if (ret < 0) { LOG("flush failed"); reply.error = -ret; @@ -748,7 +775,7 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, break; case NBD_CMD_TRIM: TRACE("Request type is TRIM"); - ret = bdrv_discard(bs, (request.from + dev_offset) / 512, + ret = bdrv_discard(exp->bs, (request.from + exp->dev_offset) / 512, request.len / 512); if (ret < 0) { LOG("discard failed"); @@ -771,3 +798,8 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, return 0; } + +int nbd_negotiate(NBDExport *exp, int csock) +{ + return nbd_send_negotiate(csock, exp->size, exp->nbdflags); +} diff --git a/nbd.h b/nbd.h index dbc4c0d..c77c2fd 100644 --- a/nbd.h +++ b/nbd.h @@ -67,15 +67,20 @@ int tcp_socket_incoming_spec(const char *address_and_port); int unix_socket_outgoing(const char *path); int unix_socket_incoming(const char *path); -int nbd_negotiate(int csock, off_t size, uint32_t flags); int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags, off_t *size, size_t *blocksize); int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize); int nbd_send_request(int csock, struct nbd_request *request); int nbd_receive_reply(int csock, struct nbd_reply *reply); -int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset, - uint32_t nbdflags, uint8_t *data); int nbd_client(int fd); int nbd_disconnect(int fd); +typedef struct NBDExport NBDExport; + +NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, + off_t size, uint32_t nbdflags); +void nbd_export_close(NBDExport *exp); +int nbd_negotiate(NBDExport *exp, int csock); +int nbd_trip(NBDExport *exp, int csock); + #endif diff --git a/qemu-nbd.c b/qemu-nbd.c index d662268..d5ac75e 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -36,6 +36,7 @@ #define SOCKET_PATH "/var/lock/qemu-nbd-%s" static int sigterm_wfd; +static NBDExport *exp; static int verbose; static char *device; static char *srcpath; @@ -280,7 +281,6 @@ int main(int argc, char **argv) int partition = -1; int ret; int shared = 1; - uint8_t *data; fd_set fds; int *sharing_fds; int fd; @@ -489,6 +489,7 @@ int main(int argc, char **argv) err(EXIT_FAILURE, "Could not find partition %d", partition); } + exp = nbd_export_new(bs, dev_offset, fd_size, nbdflags); sharing_fds = g_malloc((shared + 1) * sizeof(int)); if (sockpath) { @@ -516,11 +517,6 @@ int main(int argc, char **argv) max_fd = sharing_fds[0]; nb_fds++; - data = qemu_blockalign(bs, NBD_BUFFER_SIZE); - if (data == NULL) { - errx(EXIT_FAILURE, "Cannot allocate data buffer"); - } - do { FD_ZERO(&fds); FD_SET(sigterm_fd[0], &fds); @@ -538,8 +534,7 @@ int main(int argc, char **argv) ret--; for (i = 1; i < nb_fds && ret; i++) { if (FD_ISSET(sharing_fds[i], &fds)) { - if (nbd_trip(bs, sharing_fds[i], fd_size, dev_offset, - nbdflags, data) != 0) { + if (nbd_trip(exp, sharing_fds[i]) != 0) { close(sharing_fds[i]); nb_fds--; sharing_fds[i] = sharing_fds[nb_fds]; @@ -555,7 +550,7 @@ int main(int argc, char **argv) (struct sockaddr *)&addr, &addr_len); if (sharing_fds[nb_fds] != -1 && - nbd_negotiate(sharing_fds[nb_fds], fd_size, nbdflags) != -1) { + nbd_negotiate(exp, sharing_fds[nb_fds]) != -1) { if (sharing_fds[nb_fds] > max_fd) max_fd = sharing_fds[nb_fds]; nb_fds++; @@ -563,9 +558,9 @@ int main(int argc, char **argv) } } } while (persistent || nb_fds > 1); - qemu_vfree(data); close(sharing_fds[0]); + nbd_export_close(exp); g_free(sharing_fds); if (sockpath) { unlink(sockpath);