diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2012-03-16 11:02:27 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-03-16 16:36:04 -0400 |
commit | adc80ae60eae24a43a357bf5b30fb496f34aa605 (patch) | |
tree | b7d870f69c8deefe14da8e6cf38c8d1122bd4f1d | |
parent | db425334e5bb7fa65bbbd7bea9d79842f65bcf45 (diff) |
Tools: hv: Support enumeration from all the pools
We have only supported enumeration only from the AUTO pool. Now support
enumeration from all the available pools.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/hv/hv_kvp.c | 7 | ||||
-rw-r--r-- | include/linux/hyperv.h | 1 | ||||
-rw-r--r-- | tools/hv/hv_kvp_daemon.c | 124 |
3 files changed, 122 insertions, 10 deletions
diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index cfe60b02e3e8..6186025209ce 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c | |||
@@ -289,14 +289,15 @@ kvp_respond_to_host(char *key, char *value, int error) | |||
289 | 289 | ||
290 | 290 | ||
291 | /* | 291 | /* |
292 | * If the error parameter is set, terminate the host's enumeration. | 292 | * If the error parameter is set, terminate the host's enumeration |
293 | * on this pool. | ||
293 | */ | 294 | */ |
294 | if (error) { | 295 | if (error) { |
295 | /* | 296 | /* |
296 | * Something failed or the we have timedout; | 297 | * Something failed or the we have timedout; |
297 | * terminate the host-side iteration by returning an error. | 298 | * terminate the current host-side iteration. |
298 | */ | 299 | */ |
299 | icmsghdrp->status = HV_E_FAIL; | 300 | icmsghdrp->status = HV_S_CONT; |
300 | goto response_done; | 301 | goto response_done; |
301 | } | 302 | } |
302 | 303 | ||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index e88a979107b5..5852545e6bba 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h | |||
@@ -952,6 +952,7 @@ void vmbus_driver_unregister(struct hv_driver *hv_driver); | |||
952 | 952 | ||
953 | #define HV_S_OK 0x00000000 | 953 | #define HV_S_OK 0x00000000 |
954 | #define HV_E_FAIL 0x80004005 | 954 | #define HV_E_FAIL 0x80004005 |
955 | #define HV_S_CONT 0x80070103 | ||
955 | #define HV_ERROR_NOT_SUPPORTED 0x80070032 | 956 | #define HV_ERROR_NOT_SUPPORTED 0x80070032 |
956 | #define HV_ERROR_MACHINE_LOCKED 0x800704F7 | 957 | #define HV_ERROR_MACHINE_LOCKED 0x800704F7 |
957 | 958 | ||
diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index 2fb9c3d09d7f..146fd6147e84 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c | |||
@@ -148,6 +148,51 @@ static void kvp_update_file(int pool) | |||
148 | kvp_release_lock(pool); | 148 | kvp_release_lock(pool); |
149 | } | 149 | } |
150 | 150 | ||
151 | static void kvp_update_mem_state(int pool) | ||
152 | { | ||
153 | FILE *filep; | ||
154 | size_t records_read = 0; | ||
155 | struct kvp_record *record = kvp_file_info[pool].records; | ||
156 | struct kvp_record *readp; | ||
157 | int num_blocks = kvp_file_info[pool].num_blocks; | ||
158 | int alloc_unit = sizeof(struct kvp_record) * ENTRIES_PER_BLOCK; | ||
159 | |||
160 | kvp_acquire_lock(pool); | ||
161 | |||
162 | filep = fopen(kvp_file_info[pool].fname, "r"); | ||
163 | if (!filep) { | ||
164 | kvp_release_lock(pool); | ||
165 | syslog(LOG_ERR, "Failed to open file, pool: %d", pool); | ||
166 | exit(-1); | ||
167 | } | ||
168 | while (!feof(filep)) { | ||
169 | readp = &record[records_read]; | ||
170 | records_read += fread(readp, sizeof(struct kvp_record), | ||
171 | ENTRIES_PER_BLOCK * num_blocks, | ||
172 | filep); | ||
173 | |||
174 | if (!feof(filep)) { | ||
175 | /* | ||
176 | * We have more data to read. | ||
177 | */ | ||
178 | num_blocks++; | ||
179 | record = realloc(record, alloc_unit * num_blocks); | ||
180 | |||
181 | if (record == NULL) { | ||
182 | syslog(LOG_ERR, "malloc failed"); | ||
183 | exit(-1); | ||
184 | } | ||
185 | continue; | ||
186 | } | ||
187 | break; | ||
188 | } | ||
189 | |||
190 | kvp_file_info[pool].num_blocks = num_blocks; | ||
191 | kvp_file_info[pool].records = record; | ||
192 | kvp_file_info[pool].num_records = records_read; | ||
193 | |||
194 | kvp_release_lock(pool); | ||
195 | } | ||
151 | static int kvp_file_init(void) | 196 | static int kvp_file_init(void) |
152 | { | 197 | { |
153 | int ret, fd; | 198 | int ret, fd; |
@@ -223,8 +268,16 @@ static int kvp_key_delete(int pool, __u8 *key, int key_size) | |||
223 | { | 268 | { |
224 | int i; | 269 | int i; |
225 | int j, k; | 270 | int j, k; |
226 | int num_records = kvp_file_info[pool].num_records; | 271 | int num_records; |
227 | struct kvp_record *record = kvp_file_info[pool].records; | 272 | struct kvp_record *record; |
273 | |||
274 | /* | ||
275 | * First update the in-memory state. | ||
276 | */ | ||
277 | kvp_update_mem_state(pool); | ||
278 | |||
279 | num_records = kvp_file_info[pool].num_records; | ||
280 | record = kvp_file_info[pool].records; | ||
228 | 281 | ||
229 | for (i = 0; i < num_records; i++) { | 282 | for (i = 0; i < num_records; i++) { |
230 | if (memcmp(key, record[i].key, key_size)) | 283 | if (memcmp(key, record[i].key, key_size)) |
@@ -259,14 +312,23 @@ static int kvp_key_add_or_modify(int pool, __u8 *key, int key_size, __u8 *value, | |||
259 | { | 312 | { |
260 | int i; | 313 | int i; |
261 | int j, k; | 314 | int j, k; |
262 | int num_records = kvp_file_info[pool].num_records; | 315 | int num_records; |
263 | struct kvp_record *record = kvp_file_info[pool].records; | 316 | struct kvp_record *record; |
264 | int num_blocks = kvp_file_info[pool].num_blocks; | 317 | int num_blocks; |
265 | 318 | ||
266 | if ((key_size > HV_KVP_EXCHANGE_MAX_KEY_SIZE) || | 319 | if ((key_size > HV_KVP_EXCHANGE_MAX_KEY_SIZE) || |
267 | (value_size > HV_KVP_EXCHANGE_MAX_VALUE_SIZE)) | 320 | (value_size > HV_KVP_EXCHANGE_MAX_VALUE_SIZE)) |
268 | return 1; | 321 | return 1; |
269 | 322 | ||
323 | /* | ||
324 | * First update the in-memory state. | ||
325 | */ | ||
326 | kvp_update_mem_state(pool); | ||
327 | |||
328 | num_records = kvp_file_info[pool].num_records; | ||
329 | record = kvp_file_info[pool].records; | ||
330 | num_blocks = kvp_file_info[pool].num_blocks; | ||
331 | |||
270 | for (i = 0; i < num_records; i++) { | 332 | for (i = 0; i < num_records; i++) { |
271 | if (memcmp(key, record[i].key, key_size)) | 333 | if (memcmp(key, record[i].key, key_size)) |
272 | continue; | 334 | continue; |
@@ -304,13 +366,21 @@ static int kvp_get_value(int pool, __u8 *key, int key_size, __u8 *value, | |||
304 | int value_size) | 366 | int value_size) |
305 | { | 367 | { |
306 | int i; | 368 | int i; |
307 | int num_records = kvp_file_info[pool].num_records; | 369 | int num_records; |
308 | struct kvp_record *record = kvp_file_info[pool].records; | 370 | struct kvp_record *record; |
309 | 371 | ||
310 | if ((key_size > HV_KVP_EXCHANGE_MAX_KEY_SIZE) || | 372 | if ((key_size > HV_KVP_EXCHANGE_MAX_KEY_SIZE) || |
311 | (value_size > HV_KVP_EXCHANGE_MAX_VALUE_SIZE)) | 373 | (value_size > HV_KVP_EXCHANGE_MAX_VALUE_SIZE)) |
312 | return 1; | 374 | return 1; |
313 | 375 | ||
376 | /* | ||
377 | * First update the in-memory state. | ||
378 | */ | ||
379 | kvp_update_mem_state(pool); | ||
380 | |||
381 | num_records = kvp_file_info[pool].num_records; | ||
382 | record = kvp_file_info[pool].records; | ||
383 | |||
314 | for (i = 0; i < num_records; i++) { | 384 | for (i = 0; i < num_records; i++) { |
315 | if (memcmp(key, record[i].key, key_size)) | 385 | if (memcmp(key, record[i].key, key_size)) |
316 | continue; | 386 | continue; |
@@ -324,6 +394,31 @@ static int kvp_get_value(int pool, __u8 *key, int key_size, __u8 *value, | |||
324 | return 1; | 394 | return 1; |
325 | } | 395 | } |
326 | 396 | ||
397 | static void kvp_pool_enumerate(int pool, int index, __u8 *key, int key_size, | ||
398 | __u8 *value, int value_size) | ||
399 | { | ||
400 | struct kvp_record *record; | ||
401 | |||
402 | /* | ||
403 | * First update our in-memory database. | ||
404 | */ | ||
405 | kvp_update_mem_state(pool); | ||
406 | record = kvp_file_info[pool].records; | ||
407 | |||
408 | if (index >= kvp_file_info[pool].num_records) { | ||
409 | /* | ||
410 | * This is an invalid index; terminate enumeration; | ||
411 | * - a NULL value will do the trick. | ||
412 | */ | ||
413 | strcpy(value, ""); | ||
414 | return; | ||
415 | } | ||
416 | |||
417 | memcpy(key, record[index].key, key_size); | ||
418 | memcpy(value, record[index].value, value_size); | ||
419 | } | ||
420 | |||
421 | |||
327 | void kvp_get_os_info(void) | 422 | void kvp_get_os_info(void) |
328 | { | 423 | { |
329 | FILE *file; | 424 | FILE *file; |
@@ -678,6 +773,21 @@ int main(void) | |||
678 | if (hv_msg->kvp_hdr.operation != KVP_OP_ENUMERATE) | 773 | if (hv_msg->kvp_hdr.operation != KVP_OP_ENUMERATE) |
679 | goto kvp_done; | 774 | goto kvp_done; |
680 | 775 | ||
776 | /* | ||
777 | * If the pool is KVP_POOL_AUTO, dynamically generate | ||
778 | * both the key and the value; if not read from the | ||
779 | * appropriate pool. | ||
780 | */ | ||
781 | if (hv_msg->kvp_hdr.pool != KVP_POOL_AUTO) { | ||
782 | kvp_pool_enumerate(hv_msg->kvp_hdr.pool, | ||
783 | hv_msg->body.kvp_enum_data.index, | ||
784 | hv_msg->body.kvp_enum_data.data.key, | ||
785 | HV_KVP_EXCHANGE_MAX_KEY_SIZE, | ||
786 | hv_msg->body.kvp_enum_data.data.value, | ||
787 | HV_KVP_EXCHANGE_MAX_VALUE_SIZE); | ||
788 | goto kvp_done; | ||
789 | } | ||
790 | |||
681 | hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data; | 791 | hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data; |
682 | key_name = (char *)hv_msg->body.kvp_enum_data.data.key; | 792 | key_name = (char *)hv_msg->body.kvp_enum_data.data.key; |
683 | key_value = (char *)hv_msg->body.kvp_enum_data.data.value; | 793 | key_value = (char *)hv_msg->body.kvp_enum_data.data.value; |