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), 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_WRITE_ZEROES:
 152        return "write zeroes";
 153    case NBD_CMD_BLOCK_STATUS:
 154        return "block status";
 155    default:
 156        return "<unknown>";
 157    }
 158}
 159
 160
 161const char *nbd_reply_type_lookup(uint16_t type)
 162{
 163    switch (type) {
 164    case NBD_REPLY_TYPE_NONE:
 165        return "none";
 166    case NBD_REPLY_TYPE_OFFSET_DATA:
 167        return "data";
 168    case NBD_REPLY_TYPE_OFFSET_HOLE:
 169        return "hole";
 170    case NBD_REPLY_TYPE_BLOCK_STATUS:
 171        return "block status";
 172    case NBD_REPLY_TYPE_ERROR:
 173        return "generic error";
 174    case NBD_REPLY_TYPE_ERROR_OFFSET:
 175        return "error at offset";
 176    default:
 177        if (type & (1 << 15)) {
 178            return "<unknown error>";
 179        }
 180        return "<unknown>";
 181    }
 182}
 183
 184
 185const char *nbd_err_lookup(int err)
 186{
 187    switch (err) {
 188    case NBD_SUCCESS:
 189        return "success";
 190    case NBD_EPERM:
 191        return "EPERM";
 192    case NBD_EIO:
 193        return "EIO";
 194    case NBD_ENOMEM:
 195        return "ENOMEM";
 196    case NBD_EINVAL:
 197        return "EINVAL";
 198    case NBD_ENOSPC:
 199        return "ENOSPC";
 200    case NBD_EOVERFLOW:
 201        return "EOVERFLOW";
 202    case NBD_ESHUTDOWN:
 203        return "ESHUTDOWN";
 204    default:
 205        return "<unknown>";
 206    }
 207}
 208
 209
 210int nbd_errno_to_system_errno(int err)
 211{
 212    int ret;
 213    switch (err) {
 214    case NBD_SUCCESS:
 215        ret = 0;
 216        break;
 217    case NBD_EPERM:
 218        ret = EPERM;
 219        break;
 220    case NBD_EIO:
 221        ret = EIO;
 222        break;
 223    case NBD_ENOMEM:
 224        ret = ENOMEM;
 225        break;
 226    case NBD_ENOSPC:
 227        ret = ENOSPC;
 228        break;
 229    case NBD_EOVERFLOW:
 230        ret = EOVERFLOW;
 231        break;
 232    case NBD_ESHUTDOWN:
 233        ret = ESHUTDOWN;
 234        break;
 235    default:
 236        trace_nbd_unknown_error(err);
 237        /* fallthrough */
 238    case NBD_EINVAL:
 239        ret = EINVAL;
 240        break;
 241    }
 242    return ret;
 243}
 244