|
|
1.1 root 1: /*
2: * Virtio 9p backend
3: *
4: * Copyright IBM, Corp. 2010
5: *
6: * Authors:
7: * Anthony Liguori <[email protected]>
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:
14: #include "hw/virtio.h"
15: #include "hw/pc.h"
16: #include "qemu_socket.h"
17: #include "hw/virtio-pci.h"
18: #include "virtio-9p.h"
19: #include "fsdev/qemu-fsdev.h"
20: #include "virtio-9p-xattr.h"
21:
22: static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features)
23: {
24: features |= 1 << VIRTIO_9P_MOUNT_TAG;
25: return features;
26: }
27:
28: static V9fsState *to_virtio_9p(VirtIODevice *vdev)
29: {
30: return (V9fsState *)vdev;
31: }
32:
33: static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
34: {
35: struct virtio_9p_config *cfg;
36: V9fsState *s = to_virtio_9p(vdev);
37:
38: cfg = qemu_mallocz(sizeof(struct virtio_9p_config) +
39: s->tag_len);
40: stw_raw(&cfg->tag_len, s->tag_len);
41: memcpy(cfg->tag, s->tag, s->tag_len);
42: memcpy(config, cfg, s->config_size);
43: qemu_free(cfg);
44: }
45:
46: VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
47: {
48: V9fsState *s;
49: int i, len;
50: struct stat stat;
51: FsTypeEntry *fse;
52:
53:
54: s = (V9fsState *)virtio_common_init("virtio-9p",
55: VIRTIO_ID_9P,
56: sizeof(struct virtio_9p_config)+
57: MAX_TAG_LEN,
58: sizeof(V9fsState));
59:
60: /* initialize pdu allocator */
61: QLIST_INIT(&s->free_list);
62: for (i = 0; i < (MAX_REQ - 1); i++) {
63: QLIST_INSERT_HEAD(&s->free_list, &s->pdus[i], next);
64: }
65:
66: s->vq = virtio_add_queue(&s->vdev, MAX_REQ, handle_9p_output);
67:
68: fse = get_fsdev_fsentry(conf->fsdev_id);
69:
70: if (!fse) {
71: /* We don't have a fsdev identified by fsdev_id */
72: fprintf(stderr, "Virtio-9p device couldn't find fsdev with the "
73: "id = %s\n", conf->fsdev_id ? conf->fsdev_id : "NULL");
74: exit(1);
75: }
76:
77: if (!fse->path || !conf->tag) {
78: /* we haven't specified a mount_tag or the path */
79: fprintf(stderr, "fsdev with id %s needs path "
80: "and Virtio-9p device needs mount_tag arguments\n",
81: conf->fsdev_id);
82: exit(1);
83: }
84:
85: if (!strcmp(fse->security_model, "passthrough")) {
86: /* Files on the Fileserver set to client user credentials */
87: s->ctx.fs_sm = SM_PASSTHROUGH;
88: s->ctx.xops = passthrough_xattr_ops;
89: } else if (!strcmp(fse->security_model, "mapped")) {
90: /* Files on the fileserver are set to QEMU credentials.
91: * Client user credentials are saved in extended attributes.
92: */
93: s->ctx.fs_sm = SM_MAPPED;
94: s->ctx.xops = mapped_xattr_ops;
95: } else if (!strcmp(fse->security_model, "none")) {
96: /*
97: * Files on the fileserver are set to QEMU credentials.
98: */
99: s->ctx.fs_sm = SM_NONE;
100: s->ctx.xops = none_xattr_ops;
101: } else {
102: fprintf(stderr, "Default to security_model=none. You may want"
103: " enable advanced security model using "
104: "security option:\n\t security_model=passthrough\n\t "
105: "security_model=mapped\n");
106: s->ctx.fs_sm = SM_NONE;
107: s->ctx.xops = none_xattr_ops;
108: }
109:
110: if (lstat(fse->path, &stat)) {
111: fprintf(stderr, "share path %s does not exist\n", fse->path);
112: exit(1);
113: } else if (!S_ISDIR(stat.st_mode)) {
114: fprintf(stderr, "share path %s is not a directory\n", fse->path);
115: exit(1);
116: }
117:
118: s->ctx.fs_root = qemu_strdup(fse->path);
119: len = strlen(conf->tag);
120: if (len > MAX_TAG_LEN) {
121: len = MAX_TAG_LEN;
122: }
123: /* s->tag is non-NULL terminated string */
124: s->tag = qemu_malloc(len);
125: memcpy(s->tag, conf->tag, len);
126: s->tag_len = len;
127: s->ctx.uid = -1;
128:
129: s->ops = fse->ops;
130: s->vdev.get_features = virtio_9p_get_features;
131: s->config_size = sizeof(struct virtio_9p_config) +
132: s->tag_len;
133: s->vdev.get_config = virtio_9p_get_config;
134:
135: return &s->vdev;
136: }
137:
138: static int virtio_9p_init_pci(PCIDevice *pci_dev)
139: {
140: VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
141: VirtIODevice *vdev;
142:
143: vdev = virtio_9p_init(&pci_dev->qdev, &proxy->fsconf);
144: vdev->nvectors = proxy->nvectors;
145: virtio_init_pci(proxy, vdev);
146: /* make the actual value visible */
147: proxy->nvectors = vdev->nvectors;
148: return 0;
149: }
150:
151: static PCIDeviceInfo virtio_9p_info = {
152: .qdev.name = "virtio-9p-pci",
153: .qdev.size = sizeof(VirtIOPCIProxy),
154: .init = virtio_9p_init_pci,
155: .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
156: .device_id = 0x1009,
157: .revision = VIRTIO_PCI_ABI_VERSION,
158: .class_id = 0x2,
159: .qdev.props = (Property[]) {
160: DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
161: DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
162: DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
163: DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id),
164: DEFINE_PROP_END_OF_LIST(),
165: }
166: };
167:
168: static void virtio_9p_register_devices(void)
169: {
170: pci_qdev_register(&virtio_9p_info);
171: }
172:
173: device_init(virtio_9p_register_devices)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.