You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

xenstore.c 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  1. /*
  2. * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. *
  19. * You can also choose to distribute this program under the terms of
  20. * the Unmodified Binary Distribution Licence (as given in the file
  21. * COPYING.UBDL), provided that you have satisfied its requirements.
  22. */
  23. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  24. #include <stdint.h>
  25. #include <stdarg.h>
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <ipxe/io.h>
  30. #include <ipxe/nap.h>
  31. #include <ipxe/malloc.h>
  32. #include <ipxe/xen.h>
  33. #include <ipxe/xenevent.h>
  34. #include <ipxe/xenstore.h>
  35. /*
  36. * xs_wire.h attempts to define a static error table xsd_errors, which
  37. * interacts badly with the dynamically generated error numbers used
  38. * by iPXE. Prevent this table from being constructed by including
  39. * errno.h only after including xs_wire.h.
  40. *
  41. */
  42. #include <xen/io/xs_wire.h>
  43. #include <errno.h>
  44. /** @file
  45. *
  46. * XenStore interface
  47. *
  48. */
  49. /** Request identifier */
  50. static uint32_t xenstore_req_id;
  51. /**
  52. * Send XenStore request raw data
  53. *
  54. * @v xen Xen hypervisor
  55. * @v data Data buffer
  56. * @v len Length of data
  57. */
  58. static void xenstore_send ( struct xen_hypervisor *xen, const void *data,
  59. size_t len ) {
  60. struct xenstore_domain_interface *intf = xen->store.intf;
  61. XENSTORE_RING_IDX prod = readl ( &intf->req_prod );
  62. XENSTORE_RING_IDX cons;
  63. XENSTORE_RING_IDX idx;
  64. const char *bytes = data;
  65. size_t offset = 0;
  66. size_t fill;
  67. DBGCP ( intf, "XENSTORE raw request:\n" );
  68. DBGCP_HDA ( intf, MASK_XENSTORE_IDX ( prod ), data, len );
  69. /* Write one byte at a time */
  70. while ( offset < len ) {
  71. /* Wait for space to become available */
  72. while ( 1 ) {
  73. cons = readl ( &intf->req_cons );
  74. fill = ( prod - cons );
  75. if ( fill < XENSTORE_RING_SIZE )
  76. break;
  77. DBGC2 ( xen, "." );
  78. cpu_nap();
  79. rmb();
  80. }
  81. /* Write byte */
  82. idx = MASK_XENSTORE_IDX ( prod++ );
  83. writeb ( bytes[offset++], &intf->req[idx] );
  84. }
  85. /* Update producer counter */
  86. wmb();
  87. writel ( prod, &intf->req_prod );
  88. wmb();
  89. }
  90. /**
  91. * Send XenStore request string (excluding terminating NUL)
  92. *
  93. * @v xen Xen hypervisor
  94. * @v string String
  95. */
  96. static void xenstore_send_string ( struct xen_hypervisor *xen,
  97. const char *string ) {
  98. xenstore_send ( xen, string, strlen ( string ) );
  99. }
  100. /**
  101. * Receive XenStore response raw data
  102. *
  103. * @v xen Xen hypervisor
  104. * @v data Data buffer, or NULL to discard data
  105. * @v len Length of data
  106. */
  107. static void xenstore_recv ( struct xen_hypervisor *xen, void *data,
  108. size_t len ) {
  109. struct xenstore_domain_interface *intf = xen->store.intf;
  110. XENSTORE_RING_IDX cons = readl ( &intf->rsp_cons );
  111. XENSTORE_RING_IDX prod;
  112. XENSTORE_RING_IDX idx;
  113. char *bytes = data;
  114. size_t offset = 0;
  115. size_t fill;
  116. DBGCP ( intf, "XENSTORE raw response:\n" );
  117. /* Read one byte at a time */
  118. while ( offset < len ) {
  119. /* Wait for data to be ready */
  120. while ( 1 ) {
  121. prod = readl ( &intf->rsp_prod );
  122. fill = ( prod - cons );
  123. if ( fill > 0 )
  124. break;
  125. DBGC2 ( xen, "." );
  126. cpu_nap();
  127. rmb();
  128. }
  129. /* Read byte */
  130. idx = MASK_XENSTORE_IDX ( cons++ );
  131. if ( data )
  132. bytes[offset++] = readb ( &intf->rsp[idx] );
  133. }
  134. if ( data )
  135. DBGCP_HDA ( intf, MASK_XENSTORE_IDX ( cons - len ), data, len );
  136. /* Update consumer counter */
  137. writel ( cons, &intf->rsp_cons );
  138. wmb();
  139. }
  140. /**
  141. * Send XenStore request
  142. *
  143. * @v xen Xen hypervisor
  144. * @v type Message type
  145. * @v req_id Request ID
  146. * @v value Value, or NULL to omit
  147. * @v key Key path components
  148. * @ret rc Return status code
  149. */
  150. static int xenstore_request ( struct xen_hypervisor *xen,
  151. enum xsd_sockmsg_type type, uint32_t req_id,
  152. const char *value, va_list key ) {
  153. struct xsd_sockmsg msg;
  154. struct evtchn_send event;
  155. const char *string;
  156. va_list tmp;
  157. int xenrc;
  158. int rc;
  159. /* Construct message header */
  160. msg.type = type;
  161. msg.req_id = req_id;
  162. msg.tx_id = 0;
  163. msg.len = 0;
  164. DBGC2 ( xen, "XENSTORE request ID %d type %d ", req_id, type );
  165. /* Calculate total length */
  166. va_copy ( tmp, key );
  167. while ( ( string = va_arg ( tmp, const char * ) ) != NULL ) {
  168. DBGC2 ( xen, "%s%s", ( msg.len ? "/" : "" ), string );
  169. msg.len += ( strlen ( string ) + 1 /* '/' or NUL */ );
  170. }
  171. va_end ( tmp );
  172. if ( value ) {
  173. DBGC2 ( xen, " = \"%s\"", value );
  174. msg.len += strlen ( value );
  175. }
  176. DBGC2 ( xen, "\n" );
  177. /* Send message */
  178. xenstore_send ( xen, &msg, sizeof ( msg ) );
  179. string = va_arg ( key, const char * );
  180. assert ( string != NULL );
  181. xenstore_send_string ( xen, string );
  182. while ( ( string = va_arg ( key, const char * ) ) != NULL ) {
  183. xenstore_send_string ( xen, "/" );
  184. xenstore_send_string ( xen, string );
  185. }
  186. xenstore_send ( xen, "", 1 ); /* Separating NUL */
  187. if ( value )
  188. xenstore_send_string ( xen, value );
  189. /* Notify the back end */
  190. event.port = xen->store.port;
  191. if ( ( xenrc = xenevent_send ( xen, &event ) ) != 0 ) {
  192. rc = -EXEN ( xenrc );
  193. DBGC ( xen, "XENSTORE could not notify back end: %s\n",
  194. strerror ( rc ) );
  195. return rc;
  196. }
  197. return 0;
  198. }
  199. /**
  200. * Receive XenStore response
  201. *
  202. * @v xen Xen hypervisor
  203. * @v req_id Request ID
  204. * @v value Value to fill in
  205. * @v len Length to fill in
  206. * @ret rc Return status code
  207. *
  208. * The caller is responsible for eventually calling free() on the
  209. * returned value. Note that the value may comprise multiple
  210. * NUL-terminated strings concatenated together. A terminating NUL
  211. * will always be appended to the returned value.
  212. */
  213. static int xenstore_response ( struct xen_hypervisor *xen, uint32_t req_id,
  214. char **value, size_t *len ) {
  215. struct xsd_sockmsg msg;
  216. char *string;
  217. int rc;
  218. /* Receive message header */
  219. xenstore_recv ( xen, &msg, sizeof ( msg ) );
  220. *len = msg.len;
  221. /* Allocate space for response */
  222. *value = zalloc ( msg.len + 1 /* terminating NUL */ );
  223. /* Receive data. Do this even if allocation failed, or if the
  224. * request ID was incorrect, to avoid leaving data in the
  225. * ring.
  226. */
  227. xenstore_recv ( xen, *value, msg.len );
  228. /* Validate request ID */
  229. if ( msg.req_id != req_id ) {
  230. DBGC ( xen, "XENSTORE response ID mismatch (got %d, expected "
  231. "%d)\n", msg.req_id, req_id );
  232. rc = -EPROTO;
  233. goto err_req_id;
  234. }
  235. /* Check for allocation failure */
  236. if ( ! *value ) {
  237. DBGC ( xen, "XENSTORE could not allocate %d bytes for "
  238. "response\n", msg.len );
  239. rc = -ENOMEM;
  240. goto err_alloc;
  241. }
  242. /* Check for explicit errors */
  243. if ( msg.type == XS_ERROR ) {
  244. DBGC ( xen, "XENSTORE response error \"%s\"\n", *value );
  245. rc = -EIO;
  246. goto err_explicit;
  247. }
  248. DBGC2 ( xen, "XENSTORE response ID %d\n", req_id );
  249. if ( DBG_EXTRA ) {
  250. for ( string = *value ; string < ( *value + msg.len ) ;
  251. string += ( strlen ( string ) + 1 /* NUL */ ) ) {
  252. DBGC2 ( xen, " - \"%s\"\n", string );
  253. }
  254. }
  255. return 0;
  256. err_explicit:
  257. err_alloc:
  258. err_req_id:
  259. free ( *value );
  260. *value = NULL;
  261. return rc;
  262. }
  263. /**
  264. * Issue a XenStore message
  265. *
  266. * @v xen Xen hypervisor
  267. * @v type Message type
  268. * @v response Response value to fill in, or NULL to discard
  269. * @v len Response length to fill in, or NULL to ignore
  270. * @v request Request value, or NULL to omit
  271. * @v key Key path components
  272. * @ret rc Return status code
  273. */
  274. static int xenstore_message ( struct xen_hypervisor *xen,
  275. enum xsd_sockmsg_type type, char **response,
  276. size_t *len, const char *request, va_list key ) {
  277. char *response_value;
  278. size_t response_len;
  279. int rc;
  280. /* Send request */
  281. if ( ( rc = xenstore_request ( xen, type, ++xenstore_req_id,
  282. request, key ) ) != 0 )
  283. return rc;
  284. /* Receive response */
  285. if ( ( rc = xenstore_response ( xen, xenstore_req_id, &response_value,
  286. &response_len ) ) != 0 )
  287. return rc;
  288. /* Return response, if applicable */
  289. if ( response ) {
  290. *response = response_value;
  291. } else {
  292. free ( response_value );
  293. }
  294. if ( len )
  295. *len = response_len;
  296. return 0;
  297. }
  298. /**
  299. * Read XenStore value
  300. *
  301. * @v xen Xen hypervisor
  302. * @v value Value to fill in
  303. * @v key Key path components
  304. * @ret rc Return status code
  305. *
  306. * On a successful return, the caller is responsible for calling
  307. * free() on the returned value.
  308. */
  309. static int xenstore_vread ( struct xen_hypervisor *xen, char **value,
  310. va_list key ) {
  311. return xenstore_message ( xen, XS_READ, value, NULL, NULL, key );
  312. }
  313. /**
  314. * Read XenStore value
  315. *
  316. * @v xen Xen hypervisor
  317. * @v value Value to fill in
  318. * @v ... Key path components
  319. * @ret rc Return status code
  320. *
  321. * On a successful return, the caller is responsible for calling
  322. * free() on the returned value.
  323. */
  324. __attribute__ (( sentinel )) int
  325. xenstore_read ( struct xen_hypervisor *xen, char **value, ... ) {
  326. va_list key;
  327. int rc;
  328. va_start ( key, value );
  329. rc = xenstore_vread ( xen, value, key );
  330. va_end ( key );
  331. return rc;
  332. }
  333. /**
  334. * Read XenStore numeric value
  335. *
  336. * @v xen Xen hypervisor
  337. * @v num Numeric value to fill in
  338. * @v ... Key path components
  339. * @ret rc Return status code
  340. */
  341. __attribute__ (( sentinel )) int
  342. xenstore_read_num ( struct xen_hypervisor *xen, unsigned long *num, ... ) {
  343. va_list key;
  344. char *value;
  345. char *endp;
  346. int rc;
  347. /* Try to read text value */
  348. va_start ( key, num );
  349. rc = xenstore_vread ( xen, &value, key );
  350. va_end ( key );
  351. if ( rc != 0 )
  352. goto err_read;
  353. /* Try to parse as numeric value */
  354. *num = strtoul ( value, &endp, 10 );
  355. if ( ( *value == '\0' ) || ( *endp != '\0' ) ) {
  356. DBGC ( xen, "XENSTORE found invalid numeric value \"%s\"\n",
  357. value );
  358. rc = -EINVAL;
  359. goto err_strtoul;
  360. }
  361. err_strtoul:
  362. free ( value );
  363. err_read:
  364. return rc;
  365. }
  366. /**
  367. * Write XenStore value
  368. *
  369. * @v xen Xen hypervisor
  370. * @v value Value
  371. * @v key Key path components
  372. * @ret rc Return status code
  373. */
  374. static int xenstore_vwrite ( struct xen_hypervisor *xen, const char *value,
  375. va_list key ) {
  376. return xenstore_message ( xen, XS_WRITE, NULL, NULL, value, key );
  377. }
  378. /**
  379. * Write XenStore value
  380. *
  381. * @v xen Xen hypervisor
  382. * @v value Value
  383. * @v ... Key path components
  384. * @ret rc Return status code
  385. */
  386. __attribute__ (( sentinel )) int
  387. xenstore_write ( struct xen_hypervisor *xen, const char *value, ... ) {
  388. va_list key;
  389. int rc;
  390. va_start ( key, value );
  391. rc = xenstore_vwrite ( xen, value, key );
  392. va_end ( key );
  393. return rc;
  394. }
  395. /**
  396. * Write XenStore numeric value
  397. *
  398. * @v xen Xen hypervisor
  399. * @v num Numeric value
  400. * @v ... Key path components
  401. * @ret rc Return status code
  402. */
  403. __attribute__ (( sentinel )) int
  404. xenstore_write_num ( struct xen_hypervisor *xen, unsigned long num, ... ) {
  405. char value[ 21 /* "18446744073709551615" + NUL */ ];
  406. va_list key;
  407. int rc;
  408. /* Construct value */
  409. snprintf ( value, sizeof ( value ), "%ld", num );
  410. /* Write value */
  411. va_start ( key, num );
  412. rc = xenstore_vwrite ( xen, value, key );
  413. va_end ( key );
  414. return rc;
  415. }
  416. /**
  417. * Delete XenStore value
  418. *
  419. * @v xen Xen hypervisor
  420. * @v ... Key path components
  421. * @ret rc Return status code
  422. */
  423. __attribute__ (( sentinel )) int
  424. xenstore_rm ( struct xen_hypervisor *xen, ... ) {
  425. va_list key;
  426. int rc;
  427. va_start ( key, xen );
  428. rc = xenstore_message ( xen, XS_RM, NULL, NULL, NULL, key );
  429. va_end ( key );
  430. return rc;
  431. }
  432. /**
  433. * Read XenStore directory
  434. *
  435. * @v xen Xen hypervisor
  436. * @v children Child key names to fill in
  437. * @v len Length of child key names to fill in
  438. * @v ... Key path components
  439. * @ret rc Return status code
  440. */
  441. __attribute__ (( sentinel )) int
  442. xenstore_directory ( struct xen_hypervisor *xen, char **children, size_t *len,
  443. ... ) {
  444. va_list key;
  445. int rc;
  446. va_start ( key, len );
  447. rc = xenstore_message ( xen, XS_DIRECTORY, children, len, NULL, key );
  448. va_end ( key );
  449. return rc;
  450. }
  451. /**
  452. * Dump XenStore directory contents (for debugging)
  453. *
  454. * @v xen Xen hypervisor
  455. * @v key Key
  456. */
  457. void xenstore_dump ( struct xen_hypervisor *xen, const char *key ) {
  458. char *value;
  459. char *children;
  460. char *child;
  461. char *child_key;
  462. size_t len;
  463. int rc;
  464. /* Try to dump current key as a value */
  465. if ( ( rc = xenstore_read ( xen, &value, key, NULL ) ) == 0 ) {
  466. DBGC ( xen, "%s = \"%s\"\n", key, value );
  467. free ( value );
  468. }
  469. /* Try to recurse into each child in turn */
  470. if ( ( rc = xenstore_directory ( xen, &children, &len, key,
  471. NULL ) ) == 0 ) {
  472. for ( child = children ; child < ( children + len ) ;
  473. child += ( strlen ( child ) + 1 /* NUL */ ) ) {
  474. /* Construct child key */
  475. asprintf ( &child_key, "%s/%s", key, child );
  476. if ( ! child_key ) {
  477. DBGC ( xen, "XENSTORE could not allocate child "
  478. "key \"%s/%s\"\n", key, child );
  479. rc = -ENOMEM;
  480. break;
  481. }
  482. /* Recurse into child key, continuing on error */
  483. xenstore_dump ( xen, child_key );
  484. free ( child_key );
  485. }
  486. free ( children );
  487. }
  488. }