|
|
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.