qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

common.c (5749B)


      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 */
     25 int 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 
     50 void 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 
     61 const 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 
     88 const 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 
    121 const 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 
    138 const 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 
    163 const 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 
    187 const 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_ENOTSUP:
    205         return "ENOTSUP";
    206     case NBD_ESHUTDOWN:
    207         return "ESHUTDOWN";
    208     default:
    209         return "<unknown>";
    210     }
    211 }
    212 
    213 
    214 int nbd_errno_to_system_errno(int err)
    215 {
    216     int ret;
    217     switch (err) {
    218     case NBD_SUCCESS:
    219         ret = 0;
    220         break;
    221     case NBD_EPERM:
    222         ret = EPERM;
    223         break;
    224     case NBD_EIO:
    225         ret = EIO;
    226         break;
    227     case NBD_ENOMEM:
    228         ret = ENOMEM;
    229         break;
    230     case NBD_ENOSPC:
    231         ret = ENOSPC;
    232         break;
    233     case NBD_EOVERFLOW:
    234         ret = EOVERFLOW;
    235         break;
    236     case NBD_ENOTSUP:
    237         ret = ENOTSUP;
    238         break;
    239     case NBD_ESHUTDOWN:
    240         ret = ESHUTDOWN;
    241         break;
    242     default:
    243         trace_nbd_unknown_error(err);
    244         /* fallthrough */
    245     case NBD_EINVAL:
    246         ret = EINVAL;
    247         break;
    248     }
    249     return ret;
    250 }