hw/9pfs: Move opt validation to FsDriver callback
This remove all conditional code from common code path and make opt validation a FSDriver callback. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
This commit is contained in:
parent
f3c6a169a3
commit
99519f0a77
|
@ -61,6 +61,16 @@ typedef struct extended_ops {
|
||||||
#define V9FS_SEC_MASK 0x0000001C
|
#define V9FS_SEC_MASK 0x0000001C
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct FileOperations FileOperations;
|
||||||
|
/*
|
||||||
|
* Structure to store the various fsdev's passed through command line.
|
||||||
|
*/
|
||||||
|
typedef struct FsDriverEntry {
|
||||||
|
char *fsdev_id;
|
||||||
|
char *path;
|
||||||
|
int export_flags;
|
||||||
|
FileOperations *ops;
|
||||||
|
} FsDriverEntry;
|
||||||
|
|
||||||
typedef struct FsContext
|
typedef struct FsContext
|
||||||
{
|
{
|
||||||
|
@ -82,8 +92,9 @@ typedef union V9fsFidOpenState V9fsFidOpenState;
|
||||||
|
|
||||||
void cred_init(FsCred *);
|
void cred_init(FsCred *);
|
||||||
|
|
||||||
typedef struct FileOperations
|
struct FileOperations
|
||||||
{
|
{
|
||||||
|
int (*parse_opts)(QemuOpts *, struct FsDriverEntry *);
|
||||||
int (*init)(struct FsContext *);
|
int (*init)(struct FsContext *);
|
||||||
int (*lstat)(FsContext *, V9fsPath *, struct stat *);
|
int (*lstat)(FsContext *, V9fsPath *, struct stat *);
|
||||||
ssize_t (*readlink)(FsContext *, V9fsPath *, char *, size_t);
|
ssize_t (*readlink)(FsContext *, V9fsPath *, char *, size_t);
|
||||||
|
@ -128,6 +139,6 @@ typedef struct FileOperations
|
||||||
V9fsPath *newdir, const char *new_name);
|
V9fsPath *newdir, const char *new_name);
|
||||||
int (*unlinkat)(FsContext *ctx, V9fsPath *dir, const char *name, int flags);
|
int (*unlinkat)(FsContext *ctx, V9fsPath *dir, const char *name, int flags);
|
||||||
void *opaque;
|
void *opaque;
|
||||||
} FileOperations;
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,12 +31,10 @@ static FsDriverTable FsDrivers[] = {
|
||||||
|
|
||||||
int qemu_fsdev_add(QemuOpts *opts)
|
int qemu_fsdev_add(QemuOpts *opts)
|
||||||
{
|
{
|
||||||
struct FsDriverListEntry *fsle;
|
|
||||||
int i;
|
int i;
|
||||||
|
struct FsDriverListEntry *fsle;
|
||||||
const char *fsdev_id = qemu_opts_id(opts);
|
const char *fsdev_id = qemu_opts_id(opts);
|
||||||
const char *fsdriver = qemu_opt_get(opts, "fsdriver");
|
const char *fsdriver = qemu_opt_get(opts, "fsdriver");
|
||||||
const char *path = qemu_opt_get(opts, "path");
|
|
||||||
const char *sec_model = qemu_opt_get(opts, "security_model");
|
|
||||||
const char *writeout = qemu_opt_get(opts, "writeout");
|
const char *writeout = qemu_opt_get(opts, "writeout");
|
||||||
bool ro = qemu_opt_get_bool(opts, "readonly", 0);
|
bool ro = qemu_opt_get_bool(opts, "readonly", 0);
|
||||||
|
|
||||||
|
@ -61,29 +59,9 @@ int qemu_fsdev_add(QemuOpts *opts)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(fsdriver, "local") && !sec_model) {
|
fsle = g_malloc0(sizeof(*fsle));
|
||||||
fprintf(stderr, "security model not specified, "
|
|
||||||
"local fs needs security model\nvalid options are:"
|
|
||||||
"\tsecurity_model=[passthrough|mapped|none]\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(fsdriver, "local") && sec_model) {
|
|
||||||
fprintf(stderr, "only local fs driver needs security model\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!path) {
|
|
||||||
fprintf(stderr, "fsdev: No path specified.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fsle = g_malloc(sizeof(*fsle));
|
|
||||||
|
|
||||||
fsle->fse.fsdev_id = g_strdup(fsdev_id);
|
fsle->fse.fsdev_id = g_strdup(fsdev_id);
|
||||||
fsle->fse.path = g_strdup(path);
|
|
||||||
fsle->fse.ops = FsDrivers[i].ops;
|
fsle->fse.ops = FsDrivers[i].ops;
|
||||||
fsle->fse.export_flags = 0;
|
|
||||||
if (writeout) {
|
if (writeout) {
|
||||||
if (!strcmp(writeout, "immediate")) {
|
if (!strcmp(writeout, "immediate")) {
|
||||||
fsle->fse.export_flags |= V9FS_IMMEDIATE_WRITEOUT;
|
fsle->fse.export_flags |= V9FS_IMMEDIATE_WRITEOUT;
|
||||||
|
@ -95,22 +73,12 @@ int qemu_fsdev_add(QemuOpts *opts)
|
||||||
fsle->fse.export_flags &= ~V9FS_RDONLY;
|
fsle->fse.export_flags &= ~V9FS_RDONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(fsdriver, "local")) {
|
if (fsle->fse.ops->parse_opts) {
|
||||||
goto done;
|
if (fsle->fse.ops->parse_opts(opts, &fsle->fse)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(sec_model, "passthrough")) {
|
|
||||||
fsle->fse.export_flags |= V9FS_SM_PASSTHROUGH;
|
|
||||||
} else if (!strcmp(sec_model, "mapped")) {
|
|
||||||
fsle->fse.export_flags |= V9FS_SM_MAPPED;
|
|
||||||
} else if (!strcmp(sec_model, "none")) {
|
|
||||||
fsle->fse.export_flags |= V9FS_SM_NONE;
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Invalid security model %s specified, valid options are"
|
|
||||||
"\n\t [passthrough|mapped|none]\n", sec_model);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
done:
|
|
||||||
QTAILQ_INSERT_TAIL(&fsdriver_entries, fsle, next);
|
QTAILQ_INSERT_TAIL(&fsdriver_entries, fsle, next);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,16 +34,6 @@ typedef struct FsDriverTable {
|
||||||
FileOperations *ops;
|
FileOperations *ops;
|
||||||
} FsDriverTable;
|
} FsDriverTable;
|
||||||
|
|
||||||
/*
|
|
||||||
* Structure to store the various fsdev's passed through command line.
|
|
||||||
*/
|
|
||||||
typedef struct FsDriverEntry {
|
|
||||||
char *fsdev_id;
|
|
||||||
char *path;
|
|
||||||
int export_flags;
|
|
||||||
FileOperations *ops;
|
|
||||||
} FsDriverEntry;
|
|
||||||
|
|
||||||
typedef struct FsDriverListEntry {
|
typedef struct FsDriverListEntry {
|
||||||
FsDriverEntry fse;
|
FsDriverEntry fse;
|
||||||
QTAILQ_ENTRY(FsDriverListEntry) next;
|
QTAILQ_ENTRY(FsDriverListEntry) next;
|
||||||
|
|
|
@ -77,16 +77,19 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fse->path || !conf->tag) {
|
if (!conf->tag) {
|
||||||
/* we haven't specified a mount_tag or the path */
|
/* we haven't specified a mount_tag */
|
||||||
fprintf(stderr, "fsdev with id %s needs path "
|
fprintf(stderr, "fsdev with id %s needs mount_tag arguments\n",
|
||||||
"and Virtio-9p device needs mount_tag arguments\n",
|
|
||||||
conf->fsdev_id);
|
conf->fsdev_id);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
s->ctx.export_flags = fse->export_flags;
|
s->ctx.export_flags = fse->export_flags;
|
||||||
s->ctx.fs_root = g_strdup(fse->path);
|
if (fse->path) {
|
||||||
|
s->ctx.fs_root = g_strdup(fse->path);
|
||||||
|
} else {
|
||||||
|
s->ctx.fs_root = NULL;
|
||||||
|
}
|
||||||
s->ctx.exops.get_st_gen = NULL;
|
s->ctx.exops.get_st_gen = NULL;
|
||||||
|
|
||||||
if (fse->export_flags & V9FS_SM_PASSTHROUGH) {
|
if (fse->export_flags & V9FS_SM_PASSTHROUGH) {
|
||||||
|
|
|
@ -641,7 +641,27 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int handle_parse_opts(QemuOpts *opts, struct FsDriverEntry *fse)
|
||||||
|
{
|
||||||
|
const char *sec_model = qemu_opt_get(opts, "security_model");
|
||||||
|
const char *path = qemu_opt_get(opts, "path");
|
||||||
|
|
||||||
|
if (sec_model) {
|
||||||
|
fprintf(stderr, "Invalid argument security_model specified with handle fsdriver\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!path) {
|
||||||
|
fprintf(stderr, "fsdev: No path specified.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fse->path = g_strdup(path);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
FileOperations handle_ops = {
|
FileOperations handle_ops = {
|
||||||
|
.parse_opts = handle_parse_opts,
|
||||||
.init = handle_init,
|
.init = handle_init,
|
||||||
.lstat = handle_lstat,
|
.lstat = handle_lstat,
|
||||||
.readlink = handle_readlink,
|
.readlink = handle_readlink,
|
||||||
|
|
|
@ -756,7 +756,41 @@ static int local_init(FsContext *ctx)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int local_parse_opts(QemuOpts *opts, struct FsDriverEntry *fse)
|
||||||
|
{
|
||||||
|
const char *sec_model = qemu_opt_get(opts, "security_model");
|
||||||
|
const char *path = qemu_opt_get(opts, "path");
|
||||||
|
|
||||||
|
if (!sec_model) {
|
||||||
|
fprintf(stderr, "security model not specified, "
|
||||||
|
"local fs needs security model\nvalid options are:"
|
||||||
|
"\tsecurity_model=[passthrough|mapped|none]\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(sec_model, "passthrough")) {
|
||||||
|
fse->export_flags |= V9FS_SM_PASSTHROUGH;
|
||||||
|
} else if (!strcmp(sec_model, "mapped")) {
|
||||||
|
fse->export_flags |= V9FS_SM_MAPPED;
|
||||||
|
} else if (!strcmp(sec_model, "none")) {
|
||||||
|
fse->export_flags |= V9FS_SM_NONE;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Invalid security model %s specified, valid options are"
|
||||||
|
"\n\t [passthrough|mapped|none]\n", sec_model);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!path) {
|
||||||
|
fprintf(stderr, "fsdev: No path specified.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fse->path = g_strdup(path);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
FileOperations local_ops = {
|
FileOperations local_ops = {
|
||||||
|
.parse_opts = local_parse_opts,
|
||||||
.init = local_init,
|
.init = local_init,
|
||||||
.lstat = local_lstat,
|
.lstat = local_lstat,
|
||||||
.readlink = local_readlink,
|
.readlink = local_readlink,
|
||||||
|
|
8
vl.c
8
vl.c
|
@ -2675,11 +2675,8 @@ int main(int argc, char **argv, char **envp)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemu_opt_get(opts, "fsdriver") == NULL ||
|
if (qemu_opt_get(opts, "fsdriver") == NULL ||
|
||||||
qemu_opt_get(opts, "mount_tag") == NULL ||
|
qemu_opt_get(opts, "mount_tag") == NULL) {
|
||||||
qemu_opt_get(opts, "path") == NULL) {
|
fprintf(stderr, "Usage: -virtfs fsdriver,mount_tag=tag.\n");
|
||||||
fprintf(stderr, "Usage: -virtfs fsdriver,path=/share_path/,"
|
|
||||||
"[security_model={mapped|passthrough|none}],"
|
|
||||||
"mount_tag=tag.\n");
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
fsdev = qemu_opts_create(qemu_find_opts("fsdev"),
|
fsdev = qemu_opts_create(qemu_find_opts("fsdev"),
|
||||||
|
@ -2725,7 +2722,6 @@ int main(int argc, char **argv, char **envp)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
qemu_opt_set(fsdev, "fsdriver", "synth");
|
qemu_opt_set(fsdev, "fsdriver", "synth");
|
||||||
qemu_opt_set(fsdev, "path", "/"); /* ignored */
|
|
||||||
|
|
||||||
device = qemu_opts_create(qemu_find_opts("device"), NULL, 0);
|
device = qemu_opts_create(qemu_find_opts("device"), NULL, 0);
|
||||||
qemu_opt_set(device, "driver", "virtio-9p-pci");
|
qemu_opt_set(device, "driver", "virtio-9p-pci");
|
||||||
|
|
Loading…
Reference in New Issue