1 /* 2 * xenstore_dev.c 3 * 4 * Driver giving user-space access to the kernel's connection to the 5 * XenStore service. 6 * 7 * Copyright (c) 2005, Christian Limpach 8 * Copyright (c) 2005, Rusty Russell, IBM Corporation 9 * 10 * This file may be distributed separately from the Linux kernel, or 11 * incorporated into other software packages, subject to the following license: 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining a copy 14 * of this source file (the "Software"), to deal in the Software without 15 * restriction, including without limitation the rights to use, copy, modify, 16 * merge, publish, distribute, sublicense, and/or sell copies of the Software, 17 * and to permit persons to whom the Software is furnished to do so, subject to 18 * the following conditions: 19 * 20 * The above copyright notice and this permission notice shall be included in 21 * all copies or substantial portions of the Software. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 28 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 29 * IN THE SOFTWARE. 30 */ 31 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 #include <sys/types.h> 37 #include <sys/cdefs.h> 38 #include <sys/errno.h> 39 #include <sys/uio.h> 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/proc.h> 43 #include <sys/kernel.h> 44 #include <sys/malloc.h> 45 #include <sys/conf.h> 46 #include <sys/module.h> 47 #include <sys/selinfo.h> 48 #include <sys/poll.h> 49 50 #include <xen/xen-os.h> 51 52 #include <xen/hypervisor.h> 53 #include <xen/xenstore/xenstorevar.h> 54 #include <xen/xenstore/xenstore_internal.h> 55 56 struct xs_dev_transaction { 57 LIST_ENTRY(xs_dev_transaction) list; 58 struct xs_transaction handle; 59 }; 60 61 struct xs_dev_watch { 62 LIST_ENTRY(xs_dev_watch) list; 63 struct xs_watch watch; 64 char *token; 65 struct xs_dev_data *user; 66 }; 67 68 struct xs_dev_data { 69 /* In-progress transaction. */ 70 LIST_HEAD(, xs_dev_transaction) transactions; 71 72 /* Active watches. */ 73 LIST_HEAD(, xs_dev_watch) watches; 74 75 /* Partial request. */ 76 unsigned int len; 77 union { 78 struct xsd_sockmsg msg; 79 char buffer[PAGE_SIZE]; 80 } u; 81 82 /* Response queue. */ 83 #define MASK_READ_IDX(idx) ((idx)&(PAGE_SIZE-1)) 84 char read_buffer[PAGE_SIZE]; 85 unsigned int read_cons, read_prod; 86 87 /* Serializes writes to the read buffer. */ 88 struct mtx lock; 89 90 /* Polling structure (for reads only ATM). */ 91 struct selinfo ev_rsel; 92 }; 93 94 static void 95 xs_queue_reply(struct xs_dev_data *u, const char *data, unsigned int len) 96 { 97 unsigned int i; 98 99 for (i = 0; i < len; i++, u->read_prod++) 100 u->read_buffer[MASK_READ_IDX(u->read_prod)] = data[i]; 101 102 KASSERT((u->read_prod - u->read_cons) <= sizeof(u->read_buffer), 103 ("xenstore reply too big")); 104 105 wakeup(u); 106 selwakeup(&u->ev_rsel); 107 } 108 109 static const char * 110 xs_dev_error_to_string(int error) 111 { 112 unsigned int i; 113 114 for (i = 0; i < nitems(xsd_errors); i++) 115 if (xsd_errors[i].errnum == error) 116 return (xsd_errors[i].errstring); 117 118 return (NULL); 119 } 120 121 static void 122 xs_dev_return_error(struct xs_dev_data *u, int error, int req_id, int tx_id) 123 { 124 struct xsd_sockmsg msg; 125 const char *payload; 126 127 msg.type = XS_ERROR; 128 msg.req_id = req_id; 129 msg.tx_id = tx_id; 130 payload = NULL; 131 132 133 payload = xs_dev_error_to_string(error); 134 if (payload == NULL) 135 payload = xs_dev_error_to_string(EINVAL); 136 KASSERT(payload != NULL, ("Unable to find string for EINVAL errno")); 137 138 msg.len = strlen(payload) + 1; 139 140 mtx_lock(&u->lock); 141 xs_queue_reply(u, (char *)&msg, sizeof(msg)); 142 xs_queue_reply(u, payload, msg.len); 143 mtx_unlock(&u->lock); 144 } 145 146 static int 147 xs_dev_watch_message_parse_string(const char **p, const char *end, 148 const char **string_r) 149 { 150 const char *nul; 151 152 nul = memchr(*p, 0, end - *p); 153 if (!nul) 154 return (EINVAL); 155 156 *string_r = *p; 157 *p = nul+1; 158 159 return (0); 160 } 161 162 static int 163 xs_dev_watch_message_parse(const struct xsd_sockmsg *msg, const char **path_r, 164 const char **token_r) 165 { 166 const char *p, *end; 167 int error; 168 169 p = (const char *)msg + sizeof(*msg); 170 end = p + msg->len; 171 KASSERT(p <= end, ("payload overflow")); 172 173 error = xs_dev_watch_message_parse_string(&p, end, path_r); 174 if (error) 175 return (error); 176 error = xs_dev_watch_message_parse_string(&p, end, token_r); 177 if (error) 178 return (error); 179 180 return (0); 181 } 182 183 static struct xs_dev_watch * 184 xs_dev_find_watch(struct xs_dev_data *u, const char *token) 185 { 186 struct xs_dev_watch *watch; 187 188 LIST_FOREACH(watch, &u->watches, list) 189 if (strcmp(watch->token, token) == 0) 190 return (watch); 191 192 return (NULL); 193 } 194 195 static void 196 xs_dev_watch_cb(struct xs_watch *watch, const char **vec, unsigned int len) 197 { 198 struct xs_dev_watch *dwatch; 199 struct xsd_sockmsg msg; 200 char *payload; 201 202 dwatch = (struct xs_dev_watch *)watch->callback_data; 203 msg.type = XS_WATCH_EVENT; 204 msg.req_id = msg.tx_id = 0; 205 msg.len = strlen(vec[XS_WATCH_PATH]) + strlen(dwatch->token) + 2; 206 207 payload = malloc(msg.len, M_XENSTORE, M_WAITOK); 208 strcpy(payload, vec[XS_WATCH_PATH]); 209 strcpy(&payload[strlen(vec[XS_WATCH_PATH]) + 1], dwatch->token); 210 mtx_lock(&dwatch->user->lock); 211 xs_queue_reply(dwatch->user, (char *)&msg, sizeof(msg)); 212 xs_queue_reply(dwatch->user, payload, msg.len); 213 mtx_unlock(&dwatch->user->lock); 214 free(payload, M_XENSTORE); 215 } 216 217 static int 218 xs_dev_read(struct cdev *dev, struct uio *uio, int ioflag) 219 { 220 int error; 221 struct xs_dev_data *u; 222 223 error = devfs_get_cdevpriv((void **)&u); 224 if (error != 0) 225 return (error); 226 227 while (u->read_prod == u->read_cons) { 228 error = tsleep(u, PCATCH, "xsdread", hz/10); 229 if (error && error != EWOULDBLOCK) 230 return (error); 231 } 232 233 while (uio->uio_resid > 0) { 234 if (u->read_cons == u->read_prod) 235 break; 236 error = uiomove(&u->read_buffer[MASK_READ_IDX(u->read_cons)], 237 1, uio); 238 if (error) 239 return (error); 240 u->read_cons++; 241 } 242 return (0); 243 } 244 245 static int 246 xs_dev_write(struct cdev *dev, struct uio *uio, int ioflag) 247 { 248 int error; 249 const char *wpath, *wtoken; 250 struct xs_dev_data *u; 251 struct xs_dev_transaction *trans; 252 struct xs_dev_watch *watch; 253 void *reply; 254 static const char *ok = "OK"; 255 int len = uio->uio_resid; 256 257 error = devfs_get_cdevpriv((void **)&u); 258 if (error != 0) 259 return (error); 260 261 if ((len + u->len) > sizeof(u->u.buffer)) 262 return (EINVAL); 263 264 error = uiomove(u->u.buffer + u->len, len, uio); 265 if (error) 266 return (error); 267 268 u->len += len; 269 if (u->len < (sizeof(u->u.msg) + u->u.msg.len)) 270 return (0); 271 272 switch (u->u.msg.type) { 273 case XS_TRANSACTION_START: 274 case XS_TRANSACTION_END: 275 case XS_DIRECTORY: 276 case XS_READ: 277 case XS_GET_PERMS: 278 case XS_RELEASE: 279 case XS_GET_DOMAIN_PATH: 280 case XS_WRITE: 281 case XS_MKDIR: 282 case XS_RM: 283 case XS_SET_PERMS: 284 error = xs_dev_request_and_reply(&u->u.msg, &reply); 285 if (!error) { 286 if (u->u.msg.type == XS_TRANSACTION_START) { 287 trans = malloc(sizeof(*trans), M_XENSTORE, 288 M_WAITOK); 289 trans->handle.id = strtoul(reply, NULL, 0); 290 LIST_INSERT_HEAD(&u->transactions, trans, list); 291 } else if (u->u.msg.type == XS_TRANSACTION_END) { 292 LIST_FOREACH(trans, &u->transactions, list) 293 if (trans->handle.id == u->u.msg.tx_id) 294 break; 295 #if 0 /* XXX does this mean the list is empty? */ 296 BUG_ON(&trans->list == &u->transactions); 297 #endif 298 LIST_REMOVE(trans, list); 299 free(trans, M_XENSTORE); 300 } 301 mtx_lock(&u->lock); 302 xs_queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg)); 303 xs_queue_reply(u, (char *)reply, u->u.msg.len); 304 mtx_unlock(&u->lock); 305 free(reply, M_XENSTORE); 306 } 307 break; 308 case XS_WATCH: 309 u->u.msg.tx_id = 0; 310 error = xs_dev_watch_message_parse(&u->u.msg, &wpath, &wtoken); 311 if (error) 312 break; 313 if (xs_dev_find_watch(u, wtoken) != NULL) { 314 error = EINVAL; 315 break; 316 } 317 318 watch = malloc(sizeof(*watch), M_XENSTORE, M_WAITOK); 319 watch->watch.node = strdup(wpath, M_XENSTORE); 320 watch->watch.callback = xs_dev_watch_cb; 321 watch->watch.callback_data = (uintptr_t)watch; 322 watch->token = strdup(wtoken, M_XENSTORE); 323 watch->user = u; 324 325 error = xs_register_watch(&watch->watch); 326 if (error != 0) { 327 free(watch->token, M_XENSTORE); 328 free(watch->watch.node, M_XENSTORE); 329 free(watch, M_XENSTORE); 330 break; 331 } 332 333 LIST_INSERT_HEAD(&u->watches, watch, list); 334 u->u.msg.len = sizeof(ok); 335 mtx_lock(&u->lock); 336 xs_queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg)); 337 xs_queue_reply(u, ok, sizeof(ok)); 338 mtx_unlock(&u->lock); 339 break; 340 case XS_UNWATCH: 341 u->u.msg.tx_id = 0; 342 error = xs_dev_watch_message_parse(&u->u.msg, &wpath, &wtoken); 343 if (error) 344 break; 345 watch = xs_dev_find_watch(u, wtoken); 346 if (watch == NULL) { 347 error = EINVAL; 348 break; 349 } 350 351 LIST_REMOVE(watch, list); 352 xs_unregister_watch(&watch->watch); 353 free(watch->watch.node, M_XENSTORE); 354 free(watch->token, M_XENSTORE); 355 free(watch, M_XENSTORE); 356 u->u.msg.len = sizeof(ok); 357 mtx_lock(&u->lock); 358 xs_queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg)); 359 xs_queue_reply(u, ok, sizeof(ok)); 360 mtx_unlock(&u->lock); 361 break; 362 default: 363 error = EINVAL; 364 break; 365 } 366 367 if (error != 0) 368 xs_dev_return_error(u, error, u->u.msg.req_id, u->u.msg.tx_id); 369 370 /* Reset the write buffer. */ 371 u->len = 0; 372 373 return (0); 374 } 375 376 static int 377 xs_dev_poll(struct cdev *dev, int events, struct thread *td) 378 { 379 struct xs_dev_data *u; 380 int error, mask; 381 382 error = devfs_get_cdevpriv((void **)&u); 383 if (error != 0) 384 return (POLLERR); 385 386 /* we can always write */ 387 mask = events & (POLLOUT | POLLWRNORM); 388 389 if (events & (POLLIN | POLLRDNORM)) { 390 if (u->read_cons != u->read_prod) { 391 mask |= events & (POLLIN | POLLRDNORM); 392 } else { 393 /* Record that someone is waiting */ 394 selrecord(td, &u->ev_rsel); 395 } 396 } 397 398 return (mask); 399 } 400 401 static void 402 xs_dev_dtor(void *arg) 403 { 404 struct xs_dev_data *u = arg; 405 struct xs_dev_transaction *trans, *tmpt; 406 struct xs_dev_watch *watch, *tmpw; 407 408 seldrain(&u->ev_rsel); 409 410 LIST_FOREACH_SAFE(trans, &u->transactions, list, tmpt) { 411 xs_transaction_end(trans->handle, 1); 412 LIST_REMOVE(trans, list); 413 free(trans, M_XENSTORE); 414 } 415 416 LIST_FOREACH_SAFE(watch, &u->watches, list, tmpw) { 417 LIST_REMOVE(watch, list); 418 xs_unregister_watch(&watch->watch); 419 free(watch->watch.node, M_XENSTORE); 420 free(watch->token, M_XENSTORE); 421 free(watch, M_XENSTORE); 422 } 423 mtx_destroy(&u->lock); 424 425 free(u, M_XENSTORE); 426 } 427 428 static int 429 xs_dev_open(struct cdev *dev, int oflags, int devtype, struct thread *td) 430 { 431 struct xs_dev_data *u; 432 int error; 433 434 u = malloc(sizeof(*u), M_XENSTORE, M_WAITOK|M_ZERO); 435 mtx_init(&u->lock, "xsdev_lock", NULL, MTX_DEF); 436 LIST_INIT(&u->transactions); 437 LIST_INIT(&u->watches); 438 error = devfs_set_cdevpriv(u, xs_dev_dtor); 439 if (error != 0) 440 free(u, M_XENSTORE); 441 442 return (error); 443 } 444 445 static struct cdevsw xs_dev_cdevsw = { 446 .d_version = D_VERSION, 447 .d_read = xs_dev_read, 448 .d_write = xs_dev_write, 449 .d_open = xs_dev_open, 450 .d_poll = xs_dev_poll, 451 .d_name = "xs_dev", 452 }; 453 454 /*------------------ Private Device Attachment Functions --------------------*/ 455 /** 456 * \brief Identify instances of this device type in the system. 457 * 458 * \param driver The driver performing this identify action. 459 * \param parent The NewBus parent device for any devices this method adds. 460 */ 461 static void 462 xs_dev_identify(driver_t *driver __unused, device_t parent) 463 { 464 /* 465 * A single device instance for our driver is always present 466 * in a system operating under Xen. 467 */ 468 BUS_ADD_CHILD(parent, 0, driver->name, 0); 469 } 470 471 /** 472 * \brief Probe for the existence of the Xenstore device 473 * 474 * \param dev NewBus device_t for this instance. 475 * 476 * \return Always returns 0 indicating success. 477 */ 478 static int 479 xs_dev_probe(device_t dev) 480 { 481 482 device_set_desc(dev, "Xenstore user-space device"); 483 return (0); 484 } 485 486 /** 487 * \brief Attach the Xenstore device. 488 * 489 * \param dev NewBus device_t for this instance. 490 * 491 * \return On success, 0. Otherwise an errno value indicating the 492 * type of failure. 493 */ 494 static int 495 xs_dev_attach(device_t dev) 496 { 497 struct cdev *xs_cdev; 498 499 xs_cdev = make_dev_credf(MAKEDEV_ETERNAL, &xs_dev_cdevsw, 0, NULL, 500 UID_ROOT, GID_WHEEL, 0400, "xen/xenstore"); 501 if (xs_cdev == NULL) 502 return (EINVAL); 503 504 return (0); 505 } 506 507 /*-------------------- Private Device Attachment Data -----------------------*/ 508 static device_method_t xs_dev_methods[] = { 509 /* Device interface */ 510 DEVMETHOD(device_identify, xs_dev_identify), 511 DEVMETHOD(device_probe, xs_dev_probe), 512 DEVMETHOD(device_attach, xs_dev_attach), 513 514 DEVMETHOD_END 515 }; 516 517 DEFINE_CLASS_0(xs_dev, xs_dev_driver, xs_dev_methods, 0); 518 devclass_t xs_dev_devclass; 519 520 DRIVER_MODULE(xs_dev, xenstore, xs_dev_driver, xs_dev_devclass, 521 NULL, NULL); 522