Annotation of qemu/block/nbd.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * QEMU Block driver for  NBD
        !             3:  *
        !             4:  * Copyright (C) 2008 Bull S.A.S.
        !             5:  *     Author: Laurent Vivier <[email protected]>
        !             6:  *
        !             7:  * Some parts:
        !             8:  *    Copyright (C) 2007 Anthony Liguori <[email protected]>
        !             9:  *
        !            10:  * Permission is hereby granted, free of charge, to any person obtaining a copy
        !            11:  * of this software and associated documentation files (the "Software"), to deal
        !            12:  * in the Software without restriction, including without limitation the rights
        !            13:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        !            14:  * copies of the Software, and to permit persons to whom the Software is
        !            15:  * furnished to do so, subject to the following conditions:
        !            16:  *
        !            17:  * The above copyright notice and this permission notice shall be included in
        !            18:  * all copies or substantial portions of the Software.
        !            19:  *
        !            20:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        !            21:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        !            22:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
        !            23:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        !            24:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        !            25:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
        !            26:  * THE SOFTWARE.
        !            27:  */
        !            28: 
        !            29: #include "qemu-common.h"
        !            30: #include "nbd.h"
        !            31: #include "module.h"
        !            32: 
        !            33: #include <sys/types.h>
        !            34: #include <unistd.h>
        !            35: 
        !            36: typedef struct BDRVNBDState {
        !            37:     int sock;
        !            38:     off_t size;
        !            39:     size_t blocksize;
        !            40: } BDRVNBDState;
        !            41: 
        !            42: static int nbd_open(BlockDriverState *bs, const char* filename, int flags)
        !            43: {
        !            44:     BDRVNBDState *s = bs->opaque;
        !            45:     const char *host;
        !            46:     const char *unixpath;
        !            47:     int sock;
        !            48:     off_t size;
        !            49:     size_t blocksize;
        !            50:     int ret;
        !            51: 
        !            52:     if ((flags & BDRV_O_CREAT))
        !            53:         return -EINVAL;
        !            54: 
        !            55:     if (!strstart(filename, "nbd:", &host))
        !            56:         return -EINVAL;
        !            57: 
        !            58:     if (strstart(host, "unix:", &unixpath)) {
        !            59: 
        !            60:         if (unixpath[0] != '/')
        !            61:             return -EINVAL;
        !            62: 
        !            63:         sock = unix_socket_outgoing(unixpath);
        !            64: 
        !            65:     } else {
        !            66:         uint16_t port;
        !            67:         char *p, *r;
        !            68:         char hostname[128];
        !            69: 
        !            70:         pstrcpy(hostname, 128, host);
        !            71: 
        !            72:         p = strchr(hostname, ':');
        !            73:         if (p == NULL)
        !            74:             return -EINVAL;
        !            75: 
        !            76:         *p = '\0';
        !            77:         p++;
        !            78: 
        !            79:         port = strtol(p, &r, 0);
        !            80:         if (r == p)
        !            81:             return -EINVAL;
        !            82:         sock = tcp_socket_outgoing(hostname, port);
        !            83:     }
        !            84: 
        !            85:     if (sock == -1)
        !            86:         return -errno;
        !            87: 
        !            88:     ret = nbd_receive_negotiate(sock, &size, &blocksize);
        !            89:     if (ret == -1)
        !            90:         return -errno;
        !            91: 
        !            92:     s->sock = sock;
        !            93:     s->size = size;
        !            94:     s->blocksize = blocksize;
        !            95: 
        !            96:     return 0;
        !            97: }
        !            98: 
        !            99: static int nbd_read(BlockDriverState *bs, int64_t sector_num,
        !           100:                     uint8_t *buf, int nb_sectors)
        !           101: {
        !           102:     BDRVNBDState *s = bs->opaque;
        !           103:     struct nbd_request request;
        !           104:     struct nbd_reply reply;
        !           105: 
        !           106:     request.type = NBD_CMD_READ;
        !           107:     request.handle = (uint64_t)(intptr_t)bs;
        !           108:     request.from = sector_num * 512;;
        !           109:     request.len = nb_sectors * 512;
        !           110: 
        !           111:     if (nbd_send_request(s->sock, &request) == -1)
        !           112:         return -errno;
        !           113: 
        !           114:     if (nbd_receive_reply(s->sock, &reply) == -1)
        !           115:         return -errno;
        !           116: 
        !           117:     if (reply.error !=0)
        !           118:         return -reply.error;
        !           119: 
        !           120:     if (reply.handle != request.handle)
        !           121:         return -EIO;
        !           122: 
        !           123:     if (nbd_wr_sync(s->sock, buf, request.len, 1) != request.len)
        !           124:         return -EIO;
        !           125: 
        !           126:     return 0;
        !           127: }
        !           128: 
        !           129: static int nbd_write(BlockDriverState *bs, int64_t sector_num,
        !           130:                      const uint8_t *buf, int nb_sectors)
        !           131: {
        !           132:     BDRVNBDState *s = bs->opaque;
        !           133:     struct nbd_request request;
        !           134:     struct nbd_reply reply;
        !           135: 
        !           136:     request.type = NBD_CMD_WRITE;
        !           137:     request.handle = (uint64_t)(intptr_t)bs;
        !           138:     request.from = sector_num * 512;;
        !           139:     request.len = nb_sectors * 512;
        !           140: 
        !           141:     if (nbd_send_request(s->sock, &request) == -1)
        !           142:         return -errno;
        !           143: 
        !           144:     if (nbd_wr_sync(s->sock, (uint8_t*)buf, request.len, 0) != request.len)
        !           145:         return -EIO;
        !           146: 
        !           147:     if (nbd_receive_reply(s->sock, &reply) == -1)
        !           148:         return -errno;
        !           149: 
        !           150:     if (reply.error !=0)
        !           151:         return -reply.error;
        !           152: 
        !           153:     if (reply.handle != request.handle)
        !           154:         return -EIO;
        !           155: 
        !           156:     return 0;
        !           157: }
        !           158: 
        !           159: static void nbd_close(BlockDriverState *bs)
        !           160: {
        !           161:     BDRVNBDState *s = bs->opaque;
        !           162:     struct nbd_request request;
        !           163: 
        !           164:     request.type = NBD_CMD_DISC;
        !           165:     request.handle = (uint64_t)(intptr_t)bs;
        !           166:     request.from = 0;
        !           167:     request.len = 0;
        !           168:     nbd_send_request(s->sock, &request);
        !           169: 
        !           170:     close(s->sock);
        !           171: }
        !           172: 
        !           173: static int64_t nbd_getlength(BlockDriverState *bs)
        !           174: {
        !           175:     BDRVNBDState *s = bs->opaque;
        !           176: 
        !           177:     return s->size;
        !           178: }
        !           179: 
        !           180: static BlockDriver bdrv_nbd = {
        !           181:     .format_name       = "nbd",
        !           182:     .instance_size     = sizeof(BDRVNBDState),
        !           183:     .bdrv_open         = nbd_open,
        !           184:     .bdrv_read         = nbd_read,
        !           185:     .bdrv_write                = nbd_write,
        !           186:     .bdrv_close                = nbd_close,
        !           187:     .bdrv_getlength    = nbd_getlength,
        !           188:     .protocol_name     = "nbd",
        !           189: };
        !           190: 
        !           191: static void bdrv_nbd_init(void)
        !           192: {
        !           193:     bdrv_register(&bdrv_nbd);
        !           194: }
        !           195: 
        !           196: block_init(bdrv_nbd_init);

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.