cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

qemu-fsdev.c (4873B)


      1/*
      2 * 9p
      3 *
      4 * Copyright IBM, Corp. 2010
      5 *
      6 * Authors:
      7 *  Gautham R Shenoy <ego@in.ibm.com>
      8 *
      9 * This work is licensed under the terms of the GNU GPL, version 2.  See
     10 * the COPYING file in the top-level directory.
     11 */
     12
     13#include "qemu/osdep.h"
     14#include "qapi/error.h"
     15#include "qemu-fsdev.h"
     16#include "qemu/queue.h"
     17#include "qemu/config-file.h"
     18#include "qemu/error-report.h"
     19#include "qemu/option.h"
     20
     21/*
     22 * A table to store the various file systems and their callback operations.
     23 * -----------------
     24 * fstype | ops
     25 * -----------------
     26 *  local | local_ops
     27 *  .     |
     28 *  .     |
     29 *  .     |
     30 *  .     |
     31 * -----------------
     32 *  etc
     33 */
     34typedef struct FsDriverTable {
     35    const char *name;
     36    FileOperations *ops;
     37    const char **opts;
     38} FsDriverTable;
     39
     40typedef struct FsDriverListEntry {
     41    FsDriverEntry fse;
     42    QTAILQ_ENTRY(FsDriverListEntry) next;
     43} FsDriverListEntry;
     44
     45static QTAILQ_HEAD(, FsDriverListEntry) fsdriver_entries =
     46    QTAILQ_HEAD_INITIALIZER(fsdriver_entries);
     47
     48#define COMMON_FS_DRIVER_OPTIONS "id", "fsdriver", "readonly"
     49
     50static FsDriverTable FsDrivers[] = {
     51    {
     52        .name = "local",
     53        .ops = &local_ops,
     54        .opts = (const char * []) {
     55            COMMON_FS_DRIVER_OPTIONS,
     56            "security_model",
     57            "path",
     58            "writeout",
     59            "fmode",
     60            "dmode",
     61            "multidevs",
     62            "throttling.bps-total",
     63            "throttling.bps-read",
     64            "throttling.bps-write",
     65            "throttling.iops-total",
     66            "throttling.iops-read",
     67            "throttling.iops-write",
     68            "throttling.bps-total-max",
     69            "throttling.bps-read-max",
     70            "throttling.bps-write-max",
     71            "throttling.iops-total-max",
     72            "throttling.iops-read-max",
     73            "throttling.iops-write-max",
     74            "throttling.bps-total-max-length",
     75            "throttling.bps-read-max-length",
     76            "throttling.bps-write-max-length",
     77            "throttling.iops-total-max-length",
     78            "throttling.iops-read-max-length",
     79            "throttling.iops-write-max-length",
     80            "throttling.iops-size",
     81            NULL
     82        },
     83    },
     84    {
     85        .name = "synth",
     86        .ops = &synth_ops,
     87        .opts = (const char * []) {
     88            COMMON_FS_DRIVER_OPTIONS,
     89            NULL
     90        },
     91    },
     92    {
     93        .name = "proxy",
     94        .ops = &proxy_ops,
     95        .opts = (const char * []) {
     96            COMMON_FS_DRIVER_OPTIONS,
     97            "socket",
     98            "sock_fd",
     99            "writeout",
    100            NULL
    101        },
    102    },
    103};
    104
    105static int validate_opt(void *opaque, const char *name, const char *value,
    106                        Error **errp)
    107{
    108    FsDriverTable *drv = opaque;
    109    const char **opt;
    110
    111    for (opt = drv->opts; *opt; opt++) {
    112        if (!strcmp(*opt, name)) {
    113            return 0;
    114        }
    115    }
    116
    117    error_setg(errp, "'%s' is invalid for fsdriver '%s'", name, drv->name);
    118    return -1;
    119}
    120
    121int qemu_fsdev_add(QemuOpts *opts, Error **errp)
    122{
    123    int i;
    124    struct FsDriverListEntry *fsle;
    125    const char *fsdev_id = qemu_opts_id(opts);
    126    const char *fsdriver = qemu_opt_get(opts, "fsdriver");
    127    const char *writeout = qemu_opt_get(opts, "writeout");
    128    bool ro = qemu_opt_get_bool(opts, "readonly", 0);
    129
    130    if (!fsdev_id) {
    131        error_setg(errp, "fsdev: No id specified");
    132        return -1;
    133    }
    134
    135    if (fsdriver) {
    136        for (i = 0; i < ARRAY_SIZE(FsDrivers); i++) {
    137            if (strcmp(FsDrivers[i].name, fsdriver) == 0) {
    138                break;
    139            }
    140        }
    141
    142        if (i == ARRAY_SIZE(FsDrivers)) {
    143            error_setg(errp, "fsdev: fsdriver %s not found", fsdriver);
    144            return -1;
    145        }
    146    } else {
    147        error_setg(errp, "fsdev: No fsdriver specified");
    148        return -1;
    149    }
    150
    151    if (qemu_opt_foreach(opts, validate_opt, &FsDrivers[i], errp)) {
    152        return -1;
    153    }
    154
    155    fsle = g_malloc0(sizeof(*fsle));
    156    fsle->fse.fsdev_id = g_strdup(fsdev_id);
    157    fsle->fse.ops = FsDrivers[i].ops;
    158    if (writeout) {
    159        if (!strcmp(writeout, "immediate")) {
    160            fsle->fse.export_flags |= V9FS_IMMEDIATE_WRITEOUT;
    161        }
    162    }
    163    if (ro) {
    164        fsle->fse.export_flags |= V9FS_RDONLY;
    165    } else {
    166        fsle->fse.export_flags &= ~V9FS_RDONLY;
    167    }
    168
    169    if (fsle->fse.ops->parse_opts) {
    170        if (fsle->fse.ops->parse_opts(opts, &fsle->fse, errp)) {
    171            g_free(fsle->fse.fsdev_id);
    172            g_free(fsle);
    173            return -1;
    174        }
    175    }
    176
    177    QTAILQ_INSERT_TAIL(&fsdriver_entries, fsle, next);
    178    return 0;
    179}
    180
    181FsDriverEntry *get_fsdev_fsentry(char *id)
    182{
    183    if (id) {
    184        struct FsDriverListEntry *fsle;
    185
    186        QTAILQ_FOREACH(fsle, &fsdriver_entries, next) {
    187            if (strcmp(fsle->fse.fsdev_id, id) == 0) {
    188                return &fsle->fse;
    189            }
    190        }
    191    }
    192    return NULL;
    193}