qemu/nbd/common.c
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 2005  Anthony Liguori <anthony@codemonkey.ws>
   3 *
   4 *  Network Block Device Common Code
   5 *
   6 *  This program is free software; you can redistribute it and/or modify
   7 *  it under the terms of the GNU General Public License as published by
   8 *  the Free Software Foundation; under version 2 of the License.
   9 *
  10 *  This program is distributed in the hope that it will be useful,
  11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 *  GNU General Public License for more details.
  14 *
  15 *  You should have received a copy of the GNU General Public License
  16 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  17 */
  18
  19#include "qemu/osdep.h"
  20#include "trace.h"
  21#include "nbd-internal.h"
  22
  23/* Discard length bytes from channel.  Return -errno on failure and 0 on
  24 * success */
  25int nbd_drop(QIOChannel *ioc, size_t size, Error **errp)
  26{
  27    ssize_t ret = 0;
  28    char small[1024];
  29    char *buffer;
  30
  31    buffer = sizeof(small) >= size ? small : g_malloc(MIN(65536, size));
  32    while (size > 0) {
  33        ssize_t count = MIN(65536, size);
  34        ret = nbd_read(ioc, buffer, MIN(65536, size), NULL, errp);
  35
  36        if (ret < 0) {
  37            goto cleanup;
  38        }
  39        size -= count;
  40    }
  41
  42 cleanup:
  43    if (buffer != small) {
  44        g_free(buffer);
  45    }
  46    return ret;
  47}
  48
  49
  50void nbd_tls_handshake(QIOTask *task,
  51                       void *opaque)
  52{
  53    struct NBDTLSHandshakeData *data = opaque;
  54
  55    qio_task_propagate_error(task, &data->error);
  56    data->complete = true;
  57    g_main_loop_quit(data->loop);
  58}
  59
  60
  61const char *nbd_opt_lookup(uint32_t opt)
  62{
  63    switch (opt) {
  64    case NBD_OPT_EXPORT_NAME:
  65        return "export name";
  66    case NBD_OPT_ABORT:
  67        return "abort";
  68    case NBD_OPT_LIST:
  69        return "list";
  70    case NBD_OPT_STARTTLS:
  71        return "starttls";
  72    case NBD_OPT_INFO:
  73        return "info";
  74    case NBD_OPT_GO:
  75        return "go";
  76    case NBD_OPT_STRUCTURED_REPLY:
  77        return "structured reply";
  78    case NBD_OPT_LIST_META_CONTEXT:
  79        return "list meta context";
  80    case NBD_OPT_SET_META_CONTEXT:
  81        return "set meta context";
  82    default:
  83        return "<unknown>";
  84    }
  85}
  86
  87
  88const char *nbd_rep_lookup(uint32_t rep)
  89{
  90    switch (rep) {
  91    case NBD_REP_ACK:
  92        return "ack";
  93    case NBD_REP_SERVER:
  94        return "server";
  95    case NBD_REP_INFO:
  96        return "info";
  97    case NBD_REP_META_CONTEXT:
  98        return "meta context";
  99    case NBD_REP_ERR_UNSUP:
 100        return "unsupported";
 101    case NBD_REP_ERR_POLICY:
 102        return "denied by policy";
 103    case NBD_REP_ERR_INVALID:
 104        return "invalid";
 105    case NBD_REP_ERR_PLATFORM:
 106        return "platform lacks support";
 107    case NBD_REP_ERR_TLS_REQD:
 108        return "TLS required";
 109    case NBD_REP_ERR_UNKNOWN:
 110        return "export unknown";
 111    case NBD_REP_ERR_SHUTDOWN:
 112        return "server shutting down";
 113    case NBD_REP_ERR_BLOCK_SIZE_REQD:
 114        return "block size required";
 115    default:
 116        return "<unknown>";
 117    }
 118}
 119
 120
 121const char *nbd_info_lookup(uint16_t info)
 122{
 123    switch (info) {
 124    case NBD_INFO_EXPORT:
 125        return "export";
 126    case NBD_INFO_NAME:
 127        return "name";
 128    case NBD_INFO_DESCRIPTION:
 129        return "description";
 130    case NBD_INFO_BLOCK_SIZE:
 131        return "block size";
 132    default:
 133        return "<unknown>";
 134    }
 135}
 136
 137
 138const char *nbd_cmd_lookup(uint16_t cmd)
 139{
 140    switch (cmd) {
 141    case NBD_CMD_READ:
 142        return "read";
 143    case NBD_CMD_WRITE:
 144        return "write";
 145    case NBD_CMD_DISC:
 146        return "disconnect";
 147    case NBD_CMD_FLUSH:
 148        return "flush";
 149    case NBD_CMD_TRIM:
 150        return "trim";
 151    case NBD_CMD_CACHE:
 152        return "cache";
 153    case NBD_CMD_WRITE_ZEROES:
 154        return "write zeroes";
 155    case NBD_CMD_BLOCK_STATUS:
 156        return "block status";
 157    default:
 158        return "<unknown>";
 159    }
 160}
 161
 162
 163const char *nbd_reply_type_lookup(uint16_t type)
 164{
 165    switch (type) {
 166    case NBD_REPLY_TYPE_NONE:
 167        return "none";
 168    case NBD_REPLY_TYPE_OFFSET_DATA:
 169        return "data";
 170    case NBD_REPLY_TYPE_OFFSET_HOLE:
 171        return "hole";
 172    case NBD_REPLY_TYPE_BLOCK_STATUS:
 173        return "block status";
 174    case NBD_REPLY_TYPE_ERROR:
 175        return "generic error";
 176    case NBD_REPLY_TYPE_ERROR_OFFSET:
 177        return "error at offset";
 178    default:
 179        if (type & (1 << 15)) {
 180            return "<unknown error>";
 181        }
 182        return "<unknown>";
 183    }
 184}
 185
 186
 187const char *nbd_err_lookup(int err)
 188{
 189    switch (err) {
 190    case NBD_SUCCESS:
 191        return "success";
 192    case NBD_EPERM:
 193        return "EPERM";
 194    case NBD_EIO:
 195        return "EIO";
 196    case NBD_ENOMEM:
 197        return "ENOMEM";
 198    case NBD_EINVAL:
 199        return "EINVAL";
 200    case NBD_ENOSPC:
 201        return "ENOSPC";
 202    case NBD_EOVERFLOW:
 203        return "EOVERFLOW";
 204    case NBD_ESHUTDOWN:
 205        return "ESHUTDOWN";
 206    default:
 207        return "<unknown>";
 208    }
 209}
 210
 211
 212int nbd_errno_to_system_errno(int err)
 213{
 214    int ret;
 215    switch (err) {
 216    case NBD_SUCCESS:
 217        ret = 0;
 218        break;
 219    case NBD_EPERM:
 220        ret = EPERM;
 221        break;
 222    case NBD_EIO:
 223        ret = EIO;
 224        break;
 225    case NBD_ENOMEM:
 226        ret = ENOMEM;
 227        break;
 228    case NBD_ENOSPC:
 229        ret = ENOSPC;
 230        break;
 231    case NBD_EOVERFLOW:
 232        ret = EOVERFLOW;
 233        break;
 234    case NBD_ESHUTDOWN:
 235        ret = ESHUTDOWN;
 236        break;
 237    default:
 238        trace_nbd_unknown_error(err);
 239        /* fallthrough */
 240    case NBD_EINVAL:
 241        ret = EINVAL;
 242        break;
 243    }
 244    return ret;
 245}
 246