4 * Copyright IBM, Corp. 2010
7 * Anthony Liguori <aliguori@us.ibm.com>
9 * This work is licensed under the terms of the GNU GPL, version 2. See
10 * the COPYING file in the top-level directory.
14 #include "hw/virtio.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 #include "virtio-9p-coth.h"
23 static uint32_t virtio_9p_get_features(VirtIODevice
*vdev
, uint32_t features
)
25 features
|= 1 << VIRTIO_9P_MOUNT_TAG
;
29 static V9fsState
*to_virtio_9p(VirtIODevice
*vdev
)
31 return (V9fsState
*)vdev
;
34 static void virtio_9p_get_config(VirtIODevice
*vdev
, uint8_t *config
)
36 struct virtio_9p_config
*cfg
;
37 V9fsState
*s
= to_virtio_9p(vdev
);
39 cfg
= g_malloc0(sizeof(struct virtio_9p_config
) +
41 stw_raw(&cfg
->tag_len
, s
->tag_len
);
42 memcpy(cfg
->tag
, s
->tag
, s
->tag_len
);
43 memcpy(config
, cfg
, s
->config_size
);
47 VirtIODevice
*virtio_9p_init(DeviceState
*dev
, V9fsConf
*conf
)
54 s
= (V9fsState
*)virtio_common_init("virtio-9p",
56 sizeof(struct virtio_9p_config
)+
59 /* initialize pdu allocator */
60 QLIST_INIT(&s
->free_list
);
61 for (i
= 0; i
< (MAX_REQ
- 1); i
++) {
62 QLIST_INSERT_HEAD(&s
->free_list
, &s
->pdus
[i
], next
);
65 s
->vq
= virtio_add_queue(&s
->vdev
, MAX_REQ
, handle_9p_output
);
67 fse
= get_fsdev_fsentry(conf
->fsdev_id
);
70 /* We don't have a fsdev identified by fsdev_id */
71 fprintf(stderr
, "Virtio-9p device couldn't find fsdev with the "
72 "id = %s\n", conf
->fsdev_id
? conf
->fsdev_id
: "NULL");
76 if (!fse
->path
|| !conf
->tag
) {
77 /* we haven't specified a mount_tag or the path */
78 fprintf(stderr
, "fsdev with id %s needs path "
79 "and Virtio-9p device needs mount_tag arguments\n",
84 if (!strcmp(fse
->security_model
, "passthrough")) {
85 /* Files on the Fileserver set to client user credentials */
86 s
->ctx
.fs_sm
= SM_PASSTHROUGH
;
87 s
->ctx
.xops
= passthrough_xattr_ops
;
88 } else if (!strcmp(fse
->security_model
, "mapped")) {
89 /* Files on the fileserver are set to QEMU credentials.
90 * Client user credentials are saved in extended attributes.
92 s
->ctx
.fs_sm
= SM_MAPPED
;
93 s
->ctx
.xops
= mapped_xattr_ops
;
94 } else if (!strcmp(fse
->security_model
, "none")) {
96 * Files on the fileserver are set to QEMU credentials.
98 s
->ctx
.fs_sm
= SM_NONE
;
99 s
->ctx
.xops
= none_xattr_ops
;
101 fprintf(stderr
, "Default to security_model=none. You may want"
102 " enable advanced security model using "
103 "security option:\n\t security_model=passthrough\n\t "
104 "security_model=mapped\n");
105 s
->ctx
.fs_sm
= SM_NONE
;
106 s
->ctx
.xops
= none_xattr_ops
;
109 if (lstat(fse
->path
, &stat
)) {
110 fprintf(stderr
, "share path %s does not exist\n", fse
->path
);
112 } else if (!S_ISDIR(stat
.st_mode
)) {
113 fprintf(stderr
, "share path %s is not a directory\n", fse
->path
);
117 s
->ctx
.fs_root
= g_strdup(fse
->path
);
118 len
= strlen(conf
->tag
);
119 if (len
> MAX_TAG_LEN
) {
122 /* s->tag is non-NULL terminated string */
123 s
->tag
= g_malloc(len
);
124 memcpy(s
->tag
, conf
->tag
, len
);
129 s
->vdev
.get_features
= virtio_9p_get_features
;
130 s
->config_size
= sizeof(struct virtio_9p_config
) +
132 s
->vdev
.get_config
= virtio_9p_get_config
;
134 qemu_co_rwlock_init(&s
->rename_lock
);
136 if (v9fs_init_worker_threads() < 0) {
137 fprintf(stderr
, "worker thread initialization failed\n");
143 static int virtio_9p_init_pci(PCIDevice
*pci_dev
)
145 VirtIOPCIProxy
*proxy
= DO_UPCAST(VirtIOPCIProxy
, pci_dev
, pci_dev
);
148 vdev
= virtio_9p_init(&pci_dev
->qdev
, &proxy
->fsconf
);
149 vdev
->nvectors
= proxy
->nvectors
;
150 virtio_init_pci(proxy
, vdev
);
151 /* make the actual value visible */
152 proxy
->nvectors
= vdev
->nvectors
;
156 static PCIDeviceInfo virtio_9p_info
= {
157 .qdev
.name
= "virtio-9p-pci",
158 .qdev
.size
= sizeof(VirtIOPCIProxy
),
159 .init
= virtio_9p_init_pci
,
160 .vendor_id
= PCI_VENDOR_ID_REDHAT_QUMRANET
,
162 .revision
= VIRTIO_PCI_ABI_VERSION
,
164 .qdev
.props
= (Property
[]) {
165 DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy
, nvectors
, 2),
166 DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy
, host_features
),
167 DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy
, fsconf
.tag
),
168 DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy
, fsconf
.fsdev_id
),
169 DEFINE_PROP_END_OF_LIST(),
173 static void virtio_9p_register_devices(void)
175 pci_qdev_register(&virtio_9p_info
);
176 virtio_9p_set_fd_limit();
179 device_init(virtio_9p_register_devices
)