iPXE
guestinfo.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 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 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 
20 FILE_LICENCE ( GPL2_OR_LATER );
21 
22 /** @file
23  *
24  * VMware GuestInfo settings
25  *
26  */
27 
28 #include <stdint.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <errno.h>
33 #include <ipxe/init.h>
34 #include <ipxe/settings.h>
35 #include <ipxe/netdevice.h>
36 #include <ipxe/guestrpc.h>
37 
38 /** GuestInfo GuestRPC channel */
39 static int guestinfo_channel;
40 
41 /**
42  * Fetch value of typed GuestInfo setting
43  *
44  * @v settings Settings block
45  * @v setting Setting to fetch
46  * @v type Setting type to attempt (or NULL for default)
47  * @v data Buffer to fill with setting data
48  * @v len Length of buffer
49  * @ret found Setting found in GuestInfo
50  * @ret len Length of setting data, or negative error
51  */
52 static int guestinfo_fetch_type ( struct settings *settings,
53  struct setting *setting,
54  const struct setting_type *type,
55  void *data, size_t len, int *found ) {
56  const char *parent_name = settings->parent->name;
57  char command[ 24 /* "info-get guestinfo.ipxe." */ +
58  strlen ( parent_name ) + 1 /* "." */ +
59  strlen ( setting->name ) + 1 /* "." */ +
60  ( type ? strlen ( type->name ) : 0 ) + 1 /* NUL */ ];
61  struct setting *predefined;
62  char *info;
63  int info_len;
64  int check_len;
65  int ret;
66 
67  /* Construct info-get command */
68  snprintf ( command, sizeof ( command ),
69  "info-get guestinfo.ipxe.%s%s%s%s%s",
70  parent_name, ( parent_name[0] ? "." : "" ), setting->name,
71  ( type ? "." : "" ), ( type ? type->name : "" ) );
72 
73  /* Check for existence and obtain length of GuestInfo value */
75  if ( info_len < 0 ) {
76  ret = info_len;
77  goto err_get_info_len;
78  }
79 
80  /* Mark as found */
81  *found = 1;
82 
83  /* Determine default type if necessary */
84  if ( ! type ) {
85  predefined = find_setting ( setting->name );
86  type = ( predefined ? predefined->type : &setting_type_string );
87  }
88  assert ( type != NULL );
89 
90  /* Allocate temporary block to hold GuestInfo value */
91  info = zalloc ( info_len + 1 /* NUL */ );
92  if ( ! info ) {
93  DBGC ( settings, "GuestInfo %p could not allocate %d bytes\n",
94  settings, info_len );
95  ret = -ENOMEM;
96  goto err_alloc;
97  }
98  info[info_len] = '\0';
99 
100  /* Fetch GuestInfo value */
102  info, info_len );
103  if ( check_len < 0 ) {
104  ret = check_len;
105  goto err_get_info;
106  }
107  if ( check_len != info_len ) {
108  DBGC ( settings, "GuestInfo %p length mismatch (expected %d, "
109  "got %d)\n", settings, info_len, check_len );
110  ret = -EIO;
111  goto err_get_info;
112  }
113  DBGC2 ( settings, "GuestInfo %p found %s = \"%s\"\n",
114  settings, &command[9] /* Skip "info-get " */, info );
115 
116  /* Parse GuestInfo value according to type */
117  ret = setting_parse ( type, info, data, len );
118  if ( ret < 0 ) {
119  DBGC ( settings, "GuestInfo %p could not parse \"%s\" as %s: "
120  "%s\n", settings, info, type->name, strerror ( ret ) );
121  goto err_parse;
122  }
123 
124  err_parse:
125  err_get_info:
126  free ( info );
127  err_alloc:
128  err_get_info_len:
129  return ret;
130 }
131 
132 /**
133  * Fetch value of GuestInfo setting
134  *
135  * @v settings Settings block
136  * @v setting Setting to fetch
137  * @v data Buffer to fill with setting data
138  * @v len Length of buffer
139  * @ret len Length of setting data, or negative error
140  */
141 static int guestinfo_fetch ( struct settings *settings,
142  struct setting *setting,
143  void *data, size_t len ) {
144  struct setting_type *type;
145  int found = 0;
146  int ret;
147 
148  /* Try default type first */
150  data, len, &found );
151  if ( found )
152  return ret;
153 
154  /* Otherwise, try all possible types */
157  data, len, &found );
158  if ( found )
159  return ret;
160  }
161 
162  /* Not found */
163  return -ENOENT;
164 }
165 
166 /** GuestInfo settings operations */
169 };
170 
171 /** GuestInfo settings */
172 static struct settings guestinfo_settings = {
173  .refcnt = NULL,
177 };
178 
179 /** Initialise GuestInfo settings */
180 static void guestinfo_init ( void ) {
181  int rc;
182 
183  /* Open GuestRPC channel */
185  if ( guestinfo_channel < 0 ) {
187  DBG ( "GuestInfo could not open channel: %s\n",
188  strerror ( rc ) );
189  return;
190  }
191 
192  /* Register root GuestInfo settings */
194  "vmware" ) ) != 0 ) {
195  DBG ( "GuestInfo could not register settings: %s\n",
196  strerror ( rc ) );
197  return;
198  }
199 }
200 
201 /** GuestInfo settings initialiser */
202 struct init_fn guestinfo_init_fn __init_fn ( INIT_NORMAL ) = {
204 };
205 
206 /**
207  * Create per-netdevice GuestInfo settings
208  *
209  * @v netdev Network device
210  * @ret rc Return status code
211  */
212 static int guestinfo_net_probe ( struct net_device *netdev ) {
213  struct settings *settings;
214  int rc;
215 
216  /* Do nothing unless we have a GuestInfo channel available */
217  if ( guestinfo_channel < 0 )
218  return 0;
219 
220  /* Allocate and initialise settings block */
221  settings = zalloc ( sizeof ( *settings ) );
222  if ( ! settings ) {
223  rc = -ENOMEM;
224  goto err_alloc;
225  }
227 
228  /* Register settings */
230  "vmware" ) ) != 0 ) {
231  DBGC ( settings, "GuestInfo %p could not register for %s: %s\n",
232  settings, netdev->name, strerror ( rc ) );
233  goto err_register;
234  }
235  DBGC ( settings, "GuestInfo %p registered for %s\n",
236  settings, netdev->name );
237 
238  return 0;
239 
240  err_register:
241  free ( settings );
242  err_alloc:
243  return rc;
244 }
245 
246 /**
247  * Remove per-netdevice GuestInfo settings
248  *
249  * @v netdev Network device
250  */
251 static void guestinfo_net_remove ( struct net_device *netdev ) {
252  struct settings *parent = netdev_settings ( netdev );
253  struct settings *settings;
254 
257  DBGC ( settings, "GuestInfo %p unregistered for %s\n",
258  settings, netdev->name );
260  free ( settings );
261  return;
262  }
263  }
264 }
265 
266 /** GuestInfo per-netdevice driver */
267 struct net_driver guestinfo_net_driver __net_driver = {
268  .name = "GuestInfo",
269  .probe = guestinfo_net_probe,
270  .remove = guestinfo_net_remove,
271 };
static int guestinfo_fetch(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of GuestInfo setting.
Definition: guestinfo.c:141
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
u32 info
Definition: ar9003_mac.h:67
void(* initialise)(void)
Definition: init.h:15
struct init_fn guestinfo_init_fn __init_fn(INIT_NORMAL)
GuestInfo settings initialiser.
int guestrpc_open(void)
Open GuestRPC channel.
Definition: guestrpc.c:67
void unregister_settings(struct settings *settings)
Unregister settings block.
Definition: settings.c:517
Error codes.
struct settings * parent
Parent settings block.
Definition: settings.h:138
A command-line command.
Definition: command.h:9
uint8_t type
Type.
Definition: ena.h:16
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:514
struct settings_operations * op
Settings block operations.
Definition: settings.h:144
A network upper-layer driver.
Definition: netdevice.h:461
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:577
static void settings_init(struct settings *settings, struct settings_operations *op, struct refcnt *refcnt, const struct settings_scope *default_scope)
Initialise a settings block.
Definition: settings.h:495
static int guestinfo_channel
GuestInfo GuestRPC channel.
Definition: guestinfo.c:39
const char * name
Name.
Definition: settings.h:28
static int guestinfo_net_probe(struct net_device *netdev)
Create per-netdevice GuestInfo settings.
Definition: guestinfo.c:212
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define INIT_NORMAL
Normal initialisation.
Definition: init.h:30
const char * name
Name.
Definition: netdevice.h:463
An initialisation function.
Definition: init.h:14
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
uint8_t info_len
Reject information length.
Definition: ib_mad.h:18
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
VMware GuestRPC mechanism.
static struct net_device * netdev
Definition: gdbudp.c:52
const struct setting_type * type
Setting type.
Definition: settings.h:36
FILE_LICENCE(GPL2_OR_LATER)
int guestrpc_command(int channel, const char *command, char *reply, size_t reply_len)
Issue GuestRPC command.
Definition: guestrpc.c:242
static int guestinfo_fetch_type(struct settings *settings, struct setting *setting, const struct setting_type *type, void *data, size_t len, int *found)
Fetch value of typed GuestInfo setting.
Definition: guestinfo.c:52
Configuration settings.
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:358
A network device.
Definition: netdevice.h:348
struct net_driver guestinfo_net_driver __net_driver
GuestInfo per-netdevice driver.
Definition: guestinfo.c:267
size_t strlen(const char *src)
Get length of string.
Definition: string.c:228
Settings block operations.
Definition: settings.h:85
A settings block.
Definition: settings.h:132
const char * name
Name.
Definition: settings.h:136
struct list_head siblings
Sibling settings blocks.
Definition: settings.h:140
A setting.
Definition: settings.h:23
Network device management.
static struct settings guestinfo_settings
GuestInfo settings.
Definition: guestinfo.c:172
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:358
static void guestinfo_init(void)
Initialise GuestInfo settings.
Definition: guestinfo.c:180
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
static struct settings_operations guestinfo_settings_operations
GuestInfo settings operations.
Definition: guestinfo.c:167
int(* fetch)(struct settings *settings, struct setting *setting, void *data, size_t len)
Fetch value of setting.
Definition: settings.h:122
#define EIO
Input/output error.
Definition: errno.h:433
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
struct list_head children
Child settings blocks.
Definition: settings.h:142
int register_settings(struct settings *settings, struct settings *parent, const char *name)
Register settings block.
Definition: settings.c:478
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define SETTING_TYPES
Configuration setting type table.
Definition: settings.h:242
struct setting * find_setting(const char *name)
Find predefined setting.
Definition: settings.c:1470
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:30
static void guestinfo_net_remove(struct net_device *netdev)
Remove per-netdevice GuestInfo settings.
Definition: guestinfo.c:251
int setting_parse(const struct setting_type *type, const char *value, void *buf, size_t len)
Parse formatted string to setting value.
Definition: settings.c:1174
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
String functions.
A setting type.
Definition: settings.h:191
struct refcnt * refcnt
Reference counter.
Definition: settings.h:134