1 #include "hw/xen/xen_backend.h" 2 #include "sysemu/blockdev.h" 3 4 /* ------------------------------------------------------------- */ 5 6 struct xs_dirs { 7 char *xs_dir; 8 QTAILQ_ENTRY(xs_dirs) list; 9 }; 10 static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup = QTAILQ_HEAD_INITIALIZER(xs_cleanup); 11 12 static void xen_config_cleanup_dir(char *dir) 13 { 14 struct xs_dirs *d; 15 16 d = g_malloc(sizeof(*d)); 17 d->xs_dir = dir; 18 QTAILQ_INSERT_TAIL(&xs_cleanup, d, list); 19 } 20 21 void xen_config_cleanup(void) 22 { 23 struct xs_dirs *d; 24 25 QTAILQ_FOREACH(d, &xs_cleanup, list) { 26 xs_rm(xenstore, 0, d->xs_dir); 27 } 28 } 29 30 /* ------------------------------------------------------------- */ 31 32 static int xen_config_dev_mkdir(char *dev, int p) 33 { 34 struct xs_permissions perms[2] = {{ 35 .id = 0, /* set owner: dom0 */ 36 },{ 37 .id = xen_domid, 38 .perms = p, 39 }}; 40 41 if (!xs_mkdir(xenstore, 0, dev)) { 42 xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", dev); 43 return -1; 44 } 45 xen_config_cleanup_dir(g_strdup(dev)); 46 47 if (!xs_set_permissions(xenstore, 0, dev, perms, 2)) { 48 xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", dev); 49 return -1; 50 } 51 return 0; 52 } 53 54 static int xen_config_dev_dirs(const char *ftype, const char *btype, int vdev, 55 char *fe, char *be, int len) 56 { 57 char *dom; 58 59 dom = xs_get_domain_path(xenstore, xen_domid); 60 snprintf(fe, len, "%s/device/%s/%d", dom, ftype, vdev); 61 free(dom); 62 63 dom = xs_get_domain_path(xenstore, 0); 64 snprintf(be, len, "%s/backend/%s/%d/%d", dom, btype, xen_domid, vdev); 65 free(dom); 66 67 xen_config_dev_mkdir(fe, XS_PERM_READ | XS_PERM_WRITE); 68 xen_config_dev_mkdir(be, XS_PERM_READ); 69 return 0; 70 } 71 72 static int xen_config_dev_all(char *fe, char *be) 73 { 74 /* frontend */ 75 if (xen_protocol) 76 xenstore_write_str(fe, "protocol", xen_protocol); 77 78 xenstore_write_int(fe, "state", XenbusStateInitialising); 79 xenstore_write_int(fe, "backend-id", 0); 80 xenstore_write_str(fe, "backend", be); 81 82 /* backend */ 83 xenstore_write_str(be, "domain", qemu_name ? qemu_name : "no-name"); 84 xenstore_write_int(be, "online", 1); 85 xenstore_write_int(be, "state", XenbusStateInitialising); 86 xenstore_write_int(be, "frontend-id", xen_domid); 87 xenstore_write_str(be, "frontend", fe); 88 89 return 0; 90 } 91 92 /* ------------------------------------------------------------- */ 93 94 int xen_config_dev_blk(DriveInfo *disk) 95 { 96 char fe[256], be[256], device_name[32]; 97 int vdev = 202 * 256 + 16 * disk->unit; 98 int cdrom = disk->media_cd; 99 const char *devtype = cdrom ? "cdrom" : "disk"; 100 const char *mode = cdrom ? "r" : "w"; 101 const char *filename = qemu_opt_get(disk->opts, "file"); 102 103 snprintf(device_name, sizeof(device_name), "xvd%c", 'a' + disk->unit); 104 xen_be_printf(NULL, 1, "config disk %d [%s]: %s\n", 105 disk->unit, device_name, filename); 106 xen_config_dev_dirs("vbd", "qdisk", vdev, fe, be, sizeof(fe)); 107 108 /* frontend */ 109 xenstore_write_int(fe, "virtual-device", vdev); 110 xenstore_write_str(fe, "device-type", devtype); 111 112 /* backend */ 113 xenstore_write_str(be, "dev", device_name); 114 xenstore_write_str(be, "type", "file"); 115 xenstore_write_str(be, "params", filename); 116 xenstore_write_str(be, "mode", mode); 117 118 /* common stuff */ 119 return xen_config_dev_all(fe, be); 120 } 121 122 int xen_config_dev_nic(NICInfo *nic) 123 { 124 char fe[256], be[256]; 125 char mac[20]; 126 int vlan_id = -1; 127 128 net_hub_id_for_client(nic->netdev, &vlan_id); 129 snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x", 130 nic->macaddr.a[0], nic->macaddr.a[1], nic->macaddr.a[2], 131 nic->macaddr.a[3], nic->macaddr.a[4], nic->macaddr.a[5]); 132 xen_be_printf(NULL, 1, "config nic %d: mac=\"%s\"\n", vlan_id, mac); 133 xen_config_dev_dirs("vif", "qnic", vlan_id, fe, be, sizeof(fe)); 134 135 /* frontend */ 136 xenstore_write_int(fe, "handle", vlan_id); 137 xenstore_write_str(fe, "mac", mac); 138 139 /* backend */ 140 xenstore_write_int(be, "handle", vlan_id); 141 xenstore_write_str(be, "mac", mac); 142 143 /* common stuff */ 144 return xen_config_dev_all(fe, be); 145 } 146 147 int xen_config_dev_vfb(int vdev, const char *type) 148 { 149 char fe[256], be[256]; 150 151 xen_config_dev_dirs("vfb", "vfb", vdev, fe, be, sizeof(fe)); 152 153 /* backend */ 154 xenstore_write_str(be, "type", type); 155 156 /* common stuff */ 157 return xen_config_dev_all(fe, be); 158 } 159 160 int xen_config_dev_vkbd(int vdev) 161 { 162 char fe[256], be[256]; 163 164 xen_config_dev_dirs("vkbd", "vkbd", vdev, fe, be, sizeof(fe)); 165 return xen_config_dev_all(fe, be); 166 } 167 168 int xen_config_dev_console(int vdev) 169 { 170 char fe[256], be[256]; 171 172 xen_config_dev_dirs("console", "console", vdev, fe, be, sizeof(fe)); 173 return xen_config_dev_all(fe, be); 174 } 175