2 * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
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.
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.
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
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.
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
33 #include <ipxe/malloc.h>
35 #include <ipxe/xenevent.h>
36 #include <ipxe/xenstore.h>
39 * xs_wire.h attempts to define a static error table xsd_errors, which
40 * interacts badly with the dynamically generated error numbers used
41 * by iPXE. Prevent this table from being constructed by including
42 * errno.h only after including xs_wire.h.
45 #include <xen/io/xs_wire.h>
54 /** Request identifier */
55 static uint32_t xenstore_req_id;
58 * Send XenStore request raw data
60 * @v xen Xen hypervisor
62 * @v len Length of data
64 static void xenstore_send ( struct xen_hypervisor *xen, const void *data,
66 struct xenstore_domain_interface *intf = xen->store.intf;
67 XENSTORE_RING_IDX prod = readl ( &intf->req_prod );
68 XENSTORE_RING_IDX cons;
69 XENSTORE_RING_IDX idx;
70 const char *bytes = data;
74 DBGCP ( intf, "XENSTORE raw request:\n" );
75 DBGCP_HDA ( intf, MASK_XENSTORE_IDX ( prod ), data, len );
77 /* Write one byte at a time */
78 while ( offset < len ) {
80 /* Wait for space to become available */
82 cons = readl ( &intf->req_cons );
83 fill = ( prod - cons );
84 if ( fill < XENSTORE_RING_SIZE )
92 idx = MASK_XENSTORE_IDX ( prod++ );
93 writeb ( bytes[offset++], &intf->req[idx] );
96 /* Update producer counter */
98 writel ( prod, &intf->req_prod );
103 * Send XenStore request string (excluding terminating NUL)
105 * @v xen Xen hypervisor
108 static void xenstore_send_string ( struct xen_hypervisor *xen,
109 const char *string ) {
111 xenstore_send ( xen, string, strlen ( string ) );
115 * Receive XenStore response raw data
117 * @v xen Xen hypervisor
118 * @v data Data buffer, or NULL to discard data
119 * @v len Length of data
121 static void xenstore_recv ( struct xen_hypervisor *xen, void *data,
123 struct xenstore_domain_interface *intf = xen->store.intf;
124 XENSTORE_RING_IDX cons = readl ( &intf->rsp_cons );
125 XENSTORE_RING_IDX prod;
126 XENSTORE_RING_IDX idx;
131 DBGCP ( intf, "XENSTORE raw response:\n" );
133 /* Read one byte at a time */
134 while ( offset < len ) {
136 /* Wait for data to be ready */
138 prod = readl ( &intf->rsp_prod );
139 fill = ( prod - cons );
148 idx = MASK_XENSTORE_IDX ( cons++ );
150 bytes[offset++] = readb ( &intf->rsp[idx] );
153 DBGCP_HDA ( intf, MASK_XENSTORE_IDX ( cons - len ), data, len );
155 /* Update consumer counter */
156 writel ( cons, &intf->rsp_cons );
161 * Send XenStore request
163 * @v xen Xen hypervisor
164 * @v type Message type
165 * @v req_id Request ID
166 * @v value Value, or NULL to omit
167 * @v key Key path components
168 * @ret rc Return status code
170 static int xenstore_request ( struct xen_hypervisor *xen,
171 enum xsd_sockmsg_type type, uint32_t req_id,
172 const char *value, va_list key ) {
173 struct xsd_sockmsg msg;
174 struct evtchn_send event;
180 /* Construct message header */
185 DBGC2 ( xen, "XENSTORE request ID %d type %d ", req_id, type );
187 /* Calculate total length */
188 va_copy ( tmp, key );
189 while ( ( string = va_arg ( tmp, const char * ) ) != NULL ) {
190 DBGC2 ( xen, "%s%s", ( msg.len ? "/" : "" ), string );
191 msg.len += ( strlen ( string ) + 1 /* '/' or NUL */ );
195 DBGC2 ( xen, " = \"%s\"", value );
196 msg.len += strlen ( value );
201 xenstore_send ( xen, &msg, sizeof ( msg ) );
202 string = va_arg ( key, const char * );
203 assert ( string != NULL );
204 xenstore_send_string ( xen, string );
205 while ( ( string = va_arg ( key, const char * ) ) != NULL ) {
206 xenstore_send_string ( xen, "/" );
207 xenstore_send_string ( xen, string );
209 xenstore_send ( xen, "", 1 ); /* Separating NUL */
211 xenstore_send_string ( xen, value );
213 /* Notify the back end */
214 event.port = xen->store.port;
215 if ( ( xenrc = xenevent_send ( xen, &event ) ) != 0 ) {
216 rc = -EXEN ( xenrc );
217 DBGC ( xen, "XENSTORE could not notify back end: %s\n",
226 * Receive XenStore response
228 * @v xen Xen hypervisor
229 * @v req_id Request ID
230 * @v value Value to fill in
231 * @v len Length to fill in
232 * @ret rc Return status code
234 * The caller is responsible for eventually calling free() on the
235 * returned value. Note that the value may comprise multiple
236 * NUL-terminated strings concatenated together. A terminating NUL
237 * will always be appended to the returned value.
239 static int xenstore_response ( struct xen_hypervisor *xen, uint32_t req_id,
240 char **value, size_t *len ) {
241 struct xsd_sockmsg msg;
245 /* Wait for response to become available */
246 while ( ! xenevent_pending ( xen, xen->store.port ) )
249 /* Receive message header */
250 xenstore_recv ( xen, &msg, sizeof ( msg ) );
253 /* Allocate space for response */
254 *value = zalloc ( msg.len + 1 /* terminating NUL */ );
256 /* Receive data. Do this even if allocation failed, or if the
257 * request ID was incorrect, to avoid leaving data in the
260 xenstore_recv ( xen, *value, msg.len );
262 /* Validate request ID */
263 if ( msg.req_id != req_id ) {
264 DBGC ( xen, "XENSTORE response ID mismatch (got %d, expected "
265 "%d)\n", msg.req_id, req_id );
270 /* Check for allocation failure */
272 DBGC ( xen, "XENSTORE could not allocate %d bytes for "
273 "response\n", msg.len );
278 /* Check for explicit errors */
279 if ( msg.type == XS_ERROR ) {
280 DBGC ( xen, "XENSTORE response error \"%s\"\n", *value );
285 DBGC2 ( xen, "XENSTORE response ID %d\n", req_id );
287 for ( string = *value ; string < ( *value + msg.len ) ;
288 string += ( strlen ( string ) + 1 /* NUL */ ) ) {
289 DBGC2 ( xen, " - \"%s\"\n", string );
303 * Issue a XenStore message
305 * @v xen Xen hypervisor
306 * @v type Message type
307 * @v response Response value to fill in, or NULL to discard
308 * @v len Response length to fill in, or NULL to ignore
309 * @v request Request value, or NULL to omit
310 * @v key Key path components
311 * @ret rc Return status code
313 static int xenstore_message ( struct xen_hypervisor *xen,
314 enum xsd_sockmsg_type type, char **response,
315 size_t *len, const char *request, va_list key ) {
316 char *response_value;
321 if ( ( rc = xenstore_request ( xen, type, ++xenstore_req_id,
322 request, key ) ) != 0 )
325 /* Receive response */
326 if ( ( rc = xenstore_response ( xen, xenstore_req_id, &response_value,
327 &response_len ) ) != 0 )
330 /* Return response, if applicable */
332 *response = response_value;
334 free ( response_value );
343 * Read XenStore value
345 * @v xen Xen hypervisor
346 * @v value Value to fill in
347 * @v key Key path components
348 * @ret rc Return status code
350 * On a successful return, the caller is responsible for calling
351 * free() on the returned value.
353 static int xenstore_vread ( struct xen_hypervisor *xen, char **value,
356 return xenstore_message ( xen, XS_READ, value, NULL, NULL, key );
360 * Read XenStore value
362 * @v xen Xen hypervisor
363 * @v value Value to fill in
364 * @v ... Key path components
365 * @ret rc Return status code
367 * On a successful return, the caller is responsible for calling
368 * free() on the returned value.
370 __attribute__ (( sentinel )) int
371 xenstore_read ( struct xen_hypervisor *xen, char **value, ... ) {
375 va_start ( key, value );
376 rc = xenstore_vread ( xen, value, key );
382 * Read XenStore numeric value
384 * @v xen Xen hypervisor
385 * @v num Numeric value to fill in
386 * @v ... Key path components
387 * @ret rc Return status code
389 __attribute__ (( sentinel )) int
390 xenstore_read_num ( struct xen_hypervisor *xen, unsigned long *num, ... ) {
396 /* Try to read text value */
397 va_start ( key, num );
398 rc = xenstore_vread ( xen, &value, key );
403 /* Try to parse as numeric value */
404 *num = strtoul ( value, &endp, 10 );
405 if ( ( *value == '\0' ) || ( *endp != '\0' ) ) {
406 DBGC ( xen, "XENSTORE found invalid numeric value \"%s\"\n",
419 * Write XenStore value
421 * @v xen Xen hypervisor
423 * @v key Key path components
424 * @ret rc Return status code
426 static int xenstore_vwrite ( struct xen_hypervisor *xen, const char *value,
429 return xenstore_message ( xen, XS_WRITE, NULL, NULL, value, key );
433 * Write XenStore value
435 * @v xen Xen hypervisor
437 * @v ... Key path components
438 * @ret rc Return status code
440 __attribute__ (( sentinel )) int
441 xenstore_write ( struct xen_hypervisor *xen, const char *value, ... ) {
445 va_start ( key, value );
446 rc = xenstore_vwrite ( xen, value, key );
452 * Write XenStore numeric value
454 * @v xen Xen hypervisor
455 * @v num Numeric value
456 * @v ... Key path components
457 * @ret rc Return status code
459 __attribute__ (( sentinel )) int
460 xenstore_write_num ( struct xen_hypervisor *xen, unsigned long num, ... ) {
461 char value[ 21 /* "18446744073709551615" + NUL */ ];
465 /* Construct value */
466 snprintf ( value, sizeof ( value ), "%ld", num );
469 va_start ( key, num );
470 rc = xenstore_vwrite ( xen, value, key );
476 * Delete XenStore value
478 * @v xen Xen hypervisor
479 * @v ... Key path components
480 * @ret rc Return status code
482 __attribute__ (( sentinel )) int
483 xenstore_rm ( struct xen_hypervisor *xen, ... ) {
487 va_start ( key, xen );
488 rc = xenstore_message ( xen, XS_RM, NULL, NULL, NULL, key );
494 * Read XenStore directory
496 * @v xen Xen hypervisor
497 * @v children Child key names to fill in
498 * @v len Length of child key names to fill in
499 * @v ... Key path components
500 * @ret rc Return status code
502 __attribute__ (( sentinel )) int
503 xenstore_directory ( struct xen_hypervisor *xen, char **children, size_t *len,
508 va_start ( key, len );
509 rc = xenstore_message ( xen, XS_DIRECTORY, children, len, NULL, key );
515 * Dump XenStore directory contents (for debugging)
517 * @v xen Xen hypervisor
520 void xenstore_dump ( struct xen_hypervisor *xen, const char *key ) {
528 /* Try to dump current key as a value */
529 if ( ( rc = xenstore_read ( xen, &value, key, NULL ) ) == 0 ) {
530 DBGC ( xen, "%s = \"%s\"\n", key, value );
534 /* Try to recurse into each child in turn */
535 if ( ( rc = xenstore_directory ( xen, &children, &len, key,
537 for ( child = children ; child < ( children + len ) ;
538 child += ( strlen ( child ) + 1 /* NUL */ ) ) {
540 /* Construct child key */
541 asprintf ( &child_key, "%s/%s", key, child );
543 DBGC ( xen, "XENSTORE could not allocate child "
544 "key \"%s/%s\"\n", key, child );
549 /* Recurse into child key, continuing on error */
550 xenstore_dump ( xen, child_key );