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 );