aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2012-03-16 11:02:27 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-03-16 16:36:04 -0400
commitadc80ae60eae24a43a357bf5b30fb496f34aa605 (patch)
treeb7d870f69c8deefe14da8e6cf38c8d1122bd4f1d
parentdb425334e5bb7fa65bbbd7bea9d79842f65bcf45 (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.c7
-rw-r--r--include/linux/hyperv.h1
-rw-r--r--tools/hv/hv_kvp_daemon.c124
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
151static 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}
151static int kvp_file_init(void) 196static 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
397static 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
327void kvp_get_os_info(void) 422void 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;