]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/hyperv/tools/hv_kvp_daemon.c
MFC 317783
[FreeBSD/stable/10.git] / contrib / hyperv / tools / hv_kvp_daemon.c
1 /*-
2  * Copyright (c) 2014 Microsoft Corp.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice unmodified, this list of conditions, and the following
10  *    disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <sys/poll.h>
30 #include <sys/utsname.h>
31 #include <sys/stat.h>
32 #include <sys/un.h>
33
34 #include <arpa/inet.h>
35 #include <ifaddrs.h>
36 #include <netdb.h>
37
38 #include <netinet/in.h>
39 #include <net/ethernet.h>
40 #include <net/if_dl.h>
41 #include <net/if_types.h>
42
43 #include <assert.h>
44
45 #include <ctype.h>
46 #include <dirent.h>
47 #include <errno.h>
48 #include <fcntl.h>
49 #include <poll.h>
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <string.h>
53 #include <syslog.h>
54 #include <unistd.h>
55 #include <assert.h>
56
57 #include "hv_kvp.h"
58 #include "hv_utilreg.h"
59 typedef uint8_t         __u8;
60 typedef uint16_t        __u16;
61 typedef uint32_t        __u32;
62 typedef uint64_t        __u64;
63
64 #define POOL_FILE_MODE  (S_IRUSR | S_IWUSR)
65 #define POOL_DIR_MODE   (POOL_FILE_MODE | S_IXUSR)
66 #define POOL_DIR        "/var/db/hyperv/pool"
67
68 /*
69  * ENUM Data
70  */
71
72 enum key_index {
73         FullyQualifiedDomainName = 0,
74         IntegrationServicesVersion, /*This key is serviced in the kernel*/
75         NetworkAddressIPv4,
76         NetworkAddressIPv6,
77         OSBuildNumber,
78         OSName,
79         OSMajorVersion,
80         OSMinorVersion,
81         OSVersion,
82         ProcessorArchitecture
83 };
84
85
86 enum {
87         IPADDR = 0,
88         NETMASK,
89         GATEWAY,
90         DNS
91 };
92
93
94 /* Global Variables */
95
96 /*
97  * The structure for operation handlers.
98  */
99 struct kvp_op_hdlr {
100         int     kvp_op_key;
101         void    (*kvp_op_init)(void);
102         int     (*kvp_op_exec)(struct hv_kvp_msg *kvp_op_msg, void *data);
103 };
104
105 static struct kvp_op_hdlr kvp_op_hdlrs[HV_KVP_OP_COUNT];
106
107 /* OS information */
108
109 static const char *os_name = "";
110 static const char *os_major = "";
111 static const char *os_minor = "";
112 static const char *processor_arch;
113 static const char *os_build;
114 static const char *lic_version = "BSD Pre-Release version";
115 static struct utsname uts_buf;
116
117 /* Global flags */
118 static int is_daemon = 1;
119 static int is_debugging = 0;
120
121 #define KVP_LOG(priority, format, args...) do   {                       \
122                 if (is_debugging == 1) {                                \
123                         if (is_daemon == 1)                             \
124                                 syslog(priority, format, ## args);      \
125                         else                                            \
126                                 printf(format, ## args);                \
127                 } else {                                                \
128                         if (priority < LOG_DEBUG) {                     \
129                                 if (is_daemon == 1)                     \
130                                         syslog(priority, format, ## args);      \
131                                 else                                    \
132                                         printf(format, ## args);        \
133                         }                                               \
134                 }                                                       \
135         } while(0)
136
137 /*
138  * For KVP pool file
139  */
140
141 #define MAX_FILE_NAME           100
142 #define ENTRIES_PER_BLOCK       50
143
144 struct kvp_record {
145         char    key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
146         char    value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
147 };
148
149 struct kvp_pool {
150         int                     pool_fd;
151         int                     num_blocks;
152         struct kvp_record       *records;
153         int                     num_records;
154         char                    fname[MAX_FILE_NAME];
155 };
156
157 static struct kvp_pool kvp_pools[HV_KVP_POOL_COUNT];
158
159
160 static void
161 kvp_acquire_lock(int pool)
162 {
163         struct flock fl = { 0, 0, 0, F_WRLCK, SEEK_SET, 0 };
164
165         fl.l_pid = getpid();
166
167         if (fcntl(kvp_pools[pool].pool_fd, F_SETLKW, &fl) == -1) {
168                 KVP_LOG(LOG_ERR, "Failed to acquire the lock pool: %d", pool);
169                 exit(EXIT_FAILURE);
170         }
171 }
172
173
174 static void
175 kvp_release_lock(int pool)
176 {
177         struct flock fl = { 0, 0, 0, F_UNLCK, SEEK_SET, 0 };
178
179         fl.l_pid = getpid();
180
181         if (fcntl(kvp_pools[pool].pool_fd, F_SETLK, &fl) == -1) {
182                 perror("fcntl");
183                 KVP_LOG(LOG_ERR, "Failed to release the lock pool: %d\n", pool);
184                 exit(EXIT_FAILURE);
185         }
186 }
187
188
189 /*
190  * Write in-memory copy of KVP to pool files
191  */
192 static void
193 kvp_update_file(int pool)
194 {
195         FILE *filep;
196         size_t bytes_written;
197
198         kvp_acquire_lock(pool);
199
200         filep = fopen(kvp_pools[pool].fname, "w");
201         if (!filep) {
202                 kvp_release_lock(pool);
203                 KVP_LOG(LOG_ERR, "Failed to open file, pool: %d\n", pool);
204                 exit(EXIT_FAILURE);
205         }
206
207         bytes_written = fwrite(kvp_pools[pool].records,
208                 sizeof(struct kvp_record),
209                 kvp_pools[pool].num_records, filep);
210
211         if (ferror(filep) || fclose(filep)) {
212                 kvp_release_lock(pool);
213                 KVP_LOG(LOG_ERR, "Failed to write file, pool: %d\n", pool);
214                 exit(EXIT_FAILURE);
215         }
216
217         kvp_release_lock(pool);
218 }
219
220
221 /*
222  * Read KVPs from pool files and store in memory
223  */
224 static void
225 kvp_update_mem_state(int pool)
226 {
227         FILE *filep;
228         size_t records_read = 0;
229         struct kvp_record *record = kvp_pools[pool].records;
230         struct kvp_record *readp;
231         int num_blocks = kvp_pools[pool].num_blocks;
232         int alloc_unit = sizeof(struct kvp_record) * ENTRIES_PER_BLOCK;
233
234         kvp_acquire_lock(pool);
235
236         filep = fopen(kvp_pools[pool].fname, "r");
237         if (!filep) {
238                 kvp_release_lock(pool);
239                 KVP_LOG(LOG_ERR, "Failed to open file, pool: %d\n", pool);
240                 exit(EXIT_FAILURE);
241         }
242         for ( ; ; )
243         {
244                 readp = &record[records_read];
245                 records_read += fread(readp, sizeof(struct kvp_record),
246                         ENTRIES_PER_BLOCK * num_blocks,
247                         filep);
248
249                 if (ferror(filep)) {
250                         KVP_LOG(LOG_ERR, "Failed to read file, pool: %d\n", pool);
251                         exit(EXIT_FAILURE);
252                 }
253
254                 if (!feof(filep)) {
255                         /*
256                          * Have more data to read. Expand the memory.
257                          */
258                         num_blocks++;
259                         record = realloc(record, alloc_unit * num_blocks);
260
261                         if (record == NULL) {
262                                 KVP_LOG(LOG_ERR, "malloc failed\n");
263                                 exit(EXIT_FAILURE);
264                         }
265                         continue;
266                 }
267                 break;
268         }
269
270         kvp_pools[pool].num_blocks = num_blocks;
271         kvp_pools[pool].records = record;
272         kvp_pools[pool].num_records = records_read;
273
274         fclose(filep);
275         kvp_release_lock(pool);
276 }
277
278
279 static int
280 kvp_file_init(void)
281 {
282         int fd;
283         FILE *filep;
284         size_t records_read;
285         char *fname;
286         struct kvp_record *record;
287         struct kvp_record *readp;
288         int num_blocks;
289         int i;
290         int alloc_unit = sizeof(struct kvp_record) * ENTRIES_PER_BLOCK;
291
292         if (mkdir(POOL_DIR, POOL_DIR_MODE) < 0 &&
293             (errno != EEXIST && errno != EISDIR)) {
294                 KVP_LOG(LOG_ERR, " Failed to create /var/db/hyperv/pool\n");
295                 exit(EXIT_FAILURE);
296         }
297         chmod(POOL_DIR, POOL_DIR_MODE); /* fix old mistake */
298
299         for (i = 0; i < HV_KVP_POOL_COUNT; i++)
300         {
301                 fname = kvp_pools[i].fname;
302                 records_read = 0;
303                 num_blocks = 1;
304                 snprintf(fname, MAX_FILE_NAME, "/var/db/hyperv/pool/.kvp_pool_%d", i);
305                 fd = open(fname, O_RDWR | O_CREAT, POOL_FILE_MODE);
306
307                 if (fd == -1) {
308                         return (1);
309                 }
310                 fchmod(fd, POOL_FILE_MODE); /* fix old mistake */
311
312
313                 filep = fopen(fname, "r");
314                 if (!filep) {
315                         close(fd);
316                         return (1);
317                 }
318
319                 record = malloc(alloc_unit * num_blocks);
320                 if (record == NULL) {
321                         close(fd);
322                         fclose(filep);
323                         return (1);
324                 }
325                 for ( ; ; )
326                 {
327                         readp = &record[records_read];
328                         records_read += fread(readp, sizeof(struct kvp_record),
329                                 ENTRIES_PER_BLOCK,
330                                 filep);
331
332                         if (ferror(filep)) {
333                                 KVP_LOG(LOG_ERR, "Failed to read file, pool: %d\n",
334                                     i);
335                                 exit(EXIT_FAILURE);
336                         }
337
338                         if (!feof(filep)) {
339                                 /*
340                                  * More data to read.
341                                  */
342                                 num_blocks++;
343                                 record = realloc(record, alloc_unit *
344                                         num_blocks);
345                                 if (record == NULL) {
346                                         close(fd);
347                                         fclose(filep);
348                                         return (1);
349                                 }
350                                 continue;
351                         }
352                         break;
353                 }
354                 kvp_pools[i].pool_fd = fd;
355                 kvp_pools[i].num_blocks = num_blocks;
356                 kvp_pools[i].records = record;
357                 kvp_pools[i].num_records = records_read;
358                 fclose(filep);
359         }
360
361         return (0);
362 }
363
364
365 static int
366 kvp_key_delete(int pool, __u8 *key, int key_size)
367 {
368         int i;
369         int j, k;
370         int num_records;
371         struct kvp_record *record;
372
373         KVP_LOG(LOG_DEBUG, "kvp_key_delete: pool =  %d, "
374             "key = %s\n", pool, key);
375
376         /* Update in-memory state */
377         kvp_update_mem_state(pool);
378
379         num_records = kvp_pools[pool].num_records;
380         record = kvp_pools[pool].records;
381
382         for (i = 0; i < num_records; i++)
383         {
384                 if (memcmp(key, record[i].key, key_size)) {
385                         continue;
386                 }
387
388                 KVP_LOG(LOG_DEBUG, "Found delete key in pool %d.\n",
389                     pool);
390                 /*
391                  * We found a match at the end; Just update the number of
392                  * entries and we are done.
393                  */
394                 if (i == num_records) {
395                         kvp_pools[pool].num_records--;
396                         kvp_update_file(pool);
397                         return (0);
398                 }
399
400                 /*
401                  * We found a match in the middle; Move the remaining
402                  * entries up.
403                  */
404                 j = i;
405                 k = j + 1;
406                 for ( ; k < num_records; k++)
407                 {
408                         strcpy(record[j].key, record[k].key);
409                         strcpy(record[j].value, record[k].value);
410                         j++;
411                 }
412                 kvp_pools[pool].num_records--;
413                 kvp_update_file(pool);
414                 return (0);
415         }
416         KVP_LOG(LOG_DEBUG, "Not found delete key in pool %d.\n",
417             pool);
418         return (1);
419 }
420
421
422 static int
423 kvp_key_add_or_modify(int pool, __u8 *key, __u32 key_size, __u8 *value,
424     __u32 value_size)
425 {
426         int i;
427         int num_records;
428         struct kvp_record *record;
429         int num_blocks;
430
431         KVP_LOG(LOG_DEBUG, "kvp_key_add_or_modify: pool =  %d, "
432             "key = %s, value = %s\n,", pool, key, value);
433
434         if ((key_size > HV_KVP_EXCHANGE_MAX_KEY_SIZE) ||
435             (value_size > HV_KVP_EXCHANGE_MAX_VALUE_SIZE)) {
436                 KVP_LOG(LOG_ERR, "kvp_key_add_or_modify: returning 1\n");
437                 return (1);
438         }
439
440         /* Update the in-memory state. */
441         kvp_update_mem_state(pool);
442
443         num_records = kvp_pools[pool].num_records;
444         record = kvp_pools[pool].records;
445         num_blocks = kvp_pools[pool].num_blocks;
446
447         for (i = 0; i < num_records; i++)
448         {
449                 if (memcmp(key, record[i].key, key_size)) {
450                         continue;
451                 }
452
453                 /*
454                  * Key exists. Just update the value and we are done.
455                  */
456                 memcpy(record[i].value, value, value_size);
457                 kvp_update_file(pool);
458                 return (0);
459         }
460
461         /*
462          * Key doesn't exist; Add a new KVP.
463          */
464         if (num_records == (ENTRIES_PER_BLOCK * num_blocks)) {
465                 /* Increase the size of the recodrd array. */
466                 record = realloc(record, sizeof(struct kvp_record) *
467                         ENTRIES_PER_BLOCK * (num_blocks + 1));
468
469                 if (record == NULL) {
470                         return (1);
471                 }
472                 kvp_pools[pool].num_blocks++;
473         }
474         memcpy(record[i].value, value, value_size);
475         memcpy(record[i].key, key, key_size);
476         kvp_pools[pool].records = record;
477         kvp_pools[pool].num_records++;
478         kvp_update_file(pool);
479         return (0);
480 }
481
482
483 static int
484 kvp_get_value(int pool, __u8 *key, int key_size, __u8 *value,
485     int value_size)
486 {
487         int i;
488         int num_records;
489         struct kvp_record *record;
490
491         KVP_LOG(LOG_DEBUG, "kvp_get_value: pool =  %d, key = %s\n,",
492             pool, key);
493
494         if ((key_size > HV_KVP_EXCHANGE_MAX_KEY_SIZE) ||
495             (value_size > HV_KVP_EXCHANGE_MAX_VALUE_SIZE)) {
496                 return (1);
497         }
498
499         /* Update the in-memory state first. */
500         kvp_update_mem_state(pool);
501
502         num_records = kvp_pools[pool].num_records;
503         record = kvp_pools[pool].records;
504
505         for (i = 0; i < num_records; i++)
506         {
507                 if (memcmp(key, record[i].key, key_size)) {
508                         continue;
509                 }
510
511                 /* Found the key */
512                 memcpy(value, record[i].value, value_size);
513                 return (0);
514         }
515
516         return (1);
517 }
518
519
520 static int
521 kvp_pool_enumerate(int pool, int idx, __u8 *key, int key_size,
522     __u8 *value, int value_size)
523 {
524         struct kvp_record *record;
525
526         KVP_LOG(LOG_DEBUG, "kvp_pool_enumerate: pool = %d, index = %d\n,",
527             pool, idx);
528
529         /* First update our in-memory state first. */
530         kvp_update_mem_state(pool);
531         record = kvp_pools[pool].records;
532
533         /* Index starts with 0 */
534         if (idx >= kvp_pools[pool].num_records) {
535                 return (1);
536         }
537
538         memcpy(key, record[idx].key, key_size);
539         memcpy(value, record[idx].value, value_size);
540         return (0);
541 }
542
543
544 static void
545 kvp_get_os_info(void)
546 {
547         char *p;
548
549         uname(&uts_buf);
550         os_build = uts_buf.release;
551         os_name = uts_buf.sysname;
552         processor_arch = uts_buf.machine;
553
554         /*
555          * Win7 host expects the build string to be of the form: x.y.z
556          * Strip additional information we may have.
557          */
558         p = strchr(os_build, '-');
559         if (p) {
560                 *p = '\0';
561         }
562
563         /*
564          * We don't have any other information about the FreeBSD os.
565          */
566         return;
567 }
568
569 /*
570  * Given the interface name, return the MAC address.
571  */
572 static char *
573 kvp_if_name_to_mac(char *if_name)
574 {
575         char *mac_addr = NULL;
576         struct ifaddrs *ifaddrs_ptr;
577         struct ifaddrs *head_ifaddrs_ptr;
578         struct sockaddr_dl *sdl;
579         int status;
580
581         status = getifaddrs(&ifaddrs_ptr);
582
583         if (status >= 0) {
584                 head_ifaddrs_ptr = ifaddrs_ptr;
585                 do {
586                         sdl = (struct sockaddr_dl *)(uintptr_t)ifaddrs_ptr->ifa_addr;
587                         if ((sdl->sdl_type == IFT_ETHER) &&
588                             (strcmp(ifaddrs_ptr->ifa_name, if_name) == 0)) {
589                                 mac_addr = strdup(ether_ntoa((struct ether_addr *)(LLADDR(sdl))));
590                                 break;
591                         }
592                 } while ((ifaddrs_ptr = ifaddrs_ptr->ifa_next) != NULL);
593                 freeifaddrs(head_ifaddrs_ptr);
594         }
595
596         return (mac_addr);
597 }
598
599
600 /*
601  * Given the MAC address, return the interface name.
602  */
603 static char *
604 kvp_mac_to_if_name(char *mac)
605 {
606         char *if_name = NULL;
607         struct ifaddrs *ifaddrs_ptr;
608         struct ifaddrs *head_ifaddrs_ptr;
609         struct sockaddr_dl *sdl;
610         int status;
611         char *buf_ptr, *p;
612
613         status = getifaddrs(&ifaddrs_ptr);
614
615         if (status >= 0) {
616                 head_ifaddrs_ptr = ifaddrs_ptr;
617                 do {
618                         sdl = (struct sockaddr_dl *)(uintptr_t)ifaddrs_ptr->ifa_addr;
619                         if (sdl->sdl_type == IFT_ETHER) {
620                                 buf_ptr = strdup(ether_ntoa((struct ether_addr *)(LLADDR(sdl))));
621                                 if (buf_ptr != NULL) {
622                                         for (p = buf_ptr; *p != '\0'; p++)
623                                                 *p = toupper(*p);
624
625                                         if (strncmp(buf_ptr, mac, strlen(mac)) == 0) {
626                                                 /* Caller will free the memory */
627                                                 if_name = strdup(ifaddrs_ptr->ifa_name);
628                                                 free(buf_ptr);
629                                                 break;
630                                         } else
631                                                 free(buf_ptr);
632                                 }
633                         }
634                 } while ((ifaddrs_ptr = ifaddrs_ptr->ifa_next) != NULL);
635                 freeifaddrs(head_ifaddrs_ptr);
636         }
637         return (if_name);
638 }
639
640
641 static void
642 kvp_process_ipconfig_file(char *cmd,
643     char *config_buf, size_t len,
644     size_t element_size, int offset)
645 {
646         char buf[256];
647         char *p;
648         char *x;
649         FILE *file;
650
651         /*
652          * First execute the command.
653          */
654         file = popen(cmd, "r");
655         if (file == NULL) {
656                 return;
657         }
658
659         if (offset == 0) {
660                 memset(config_buf, 0, len);
661         }
662         while ((p = fgets(buf, sizeof(buf), file)) != NULL) {
663                 if ((len - strlen(config_buf)) < (element_size + 1)) {
664                         break;
665                 }
666
667                 x = strchr(p, '\n');
668                 *x = '\0';
669                 strlcat(config_buf, p, len);
670                 strlcat(config_buf, ";", len);
671         }
672         pclose(file);
673 }
674
675
676 static void
677 kvp_get_ipconfig_info(char *if_name, struct hv_kvp_ipaddr_value *buffer)
678 {
679         char cmd[512];
680         char dhcp_info[128];
681         char *p;
682         FILE *file;
683
684         /*
685          * Retrieve the IPV4 address of default gateway.
686          */
687         snprintf(cmd, sizeof(cmd), "netstat -rn | grep %s | awk '/default/ {print $2 }'", if_name);
688
689         /*
690          * Execute the command to gather gateway IPV4 info.
691          */
692         kvp_process_ipconfig_file(cmd, (char *)buffer->gate_way,
693             (MAX_GATEWAY_SIZE * 2), INET_ADDRSTRLEN, 0);
694         /*
695          * Retrieve the IPV6 address of default gateway.
696          */
697         snprintf(cmd, sizeof(cmd), "netstat -rn inet6 | grep %s | awk '/default/ {print $2 }'", if_name);
698
699         /*
700          * Execute the command to gather gateway IPV6 info.
701          */
702         kvp_process_ipconfig_file(cmd, (char *)buffer->gate_way,
703             (MAX_GATEWAY_SIZE * 2), INET6_ADDRSTRLEN, 1);
704         /*
705          * we just invoke an external script to get the DNS info.
706          *
707          * Following is the expected format of the information from the script:
708          *
709          * ipaddr1 (nameserver1)
710          * ipaddr2 (nameserver2)
711          * .
712          * .
713          */
714         /* Scripts are stored in /usr/libexec/hyperv/ directory */
715         snprintf(cmd, sizeof(cmd), "%s", "sh /usr/libexec/hyperv/hv_get_dns_info");
716
717         /*
718          * Execute the command to get DNS info.
719          */
720         kvp_process_ipconfig_file(cmd, (char *)buffer->dns_addr,
721             (MAX_IP_ADDR_SIZE * 2), INET_ADDRSTRLEN, 0);
722
723         /*
724          * Invoke an external script to get the DHCP state info.
725          * The parameter to the script is the interface name.
726          * Here is the expected output:
727          *
728          * Enabled: DHCP enabled.
729          */
730
731
732         snprintf(cmd, sizeof(cmd), "%s %s",
733             "sh /usr/libexec/hyperv/hv_get_dhcp_info", if_name);
734
735         file = popen(cmd, "r");
736         if (file == NULL) {
737                 return;
738         }
739
740         p = fgets(dhcp_info, sizeof(dhcp_info), file);
741         if (p == NULL) {
742                 pclose(file);
743                 return;
744         }
745
746         if (!strncmp(p, "Enabled", 7)) {
747                 buffer->dhcp_enabled = 1;
748         } else{
749                 buffer->dhcp_enabled = 0;
750         }
751
752         pclose(file);
753 }
754
755
756 static unsigned int
757 hweight32(unsigned int *w)
758 {
759         unsigned int res = *w - ((*w >> 1) & 0x55555555);
760
761         res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
762         res = (res + (res >> 4)) & 0x0F0F0F0F;
763         res = res + (res >> 8);
764         return ((res + (res >> 16)) & 0x000000FF);
765 }
766
767
768 static int
769 kvp_process_ip_address(void *addrp,
770     int family, char *buffer,
771     int length, int *offset)
772 {
773         struct sockaddr_in *addr;
774         struct sockaddr_in6 *addr6;
775         int addr_length;
776         char tmp[50];
777         const char *str;
778
779         if (family == AF_INET) {
780                 addr = (struct sockaddr_in *)addrp;
781                 str = inet_ntop(family, &addr->sin_addr, tmp, 50);
782                 addr_length = INET_ADDRSTRLEN;
783         } else {
784                 addr6 = (struct sockaddr_in6 *)addrp;
785                 str = inet_ntop(family, &addr6->sin6_addr.s6_addr, tmp, 50);
786                 addr_length = INET6_ADDRSTRLEN;
787         }
788
789         if ((length - *offset) < addr_length + 1) {
790                 return (EINVAL);
791         }
792         if (str == NULL) {
793                 strlcpy(buffer, "inet_ntop failed\n", length);
794                 return (errno);
795         }
796         if (*offset == 0) {
797                 strlcpy(buffer, tmp, length);
798         } else{
799                 strlcat(buffer, tmp, length);
800         }
801         strlcat(buffer, ";", length);
802
803         *offset += strlen(str) + 1;
804         return (0);
805 }
806
807
808 static int
809 kvp_get_ip_info(int family, char *if_name, int op,
810     void *out_buffer, size_t length)
811 {
812         struct ifaddrs *ifap;
813         struct ifaddrs *curp;
814         int offset = 0;
815         int sn_offset = 0;
816         int error = 0;
817         char *buffer;
818         size_t buffer_length;
819         struct hv_kvp_ipaddr_value *ip_buffer;
820         char cidr_mask[5];
821         int weight;
822         int i;
823         unsigned int *w = NULL;
824         char *sn_str;
825         size_t sn_str_length;
826         struct sockaddr_in6 *addr6;
827
828         if (op == HV_KVP_OP_ENUMERATE) {
829                 buffer = out_buffer;
830                 buffer_length = length;
831         } else {
832                 ip_buffer = out_buffer;
833                 buffer = (char *)ip_buffer->ip_addr;
834                 buffer_length = sizeof(ip_buffer->ip_addr);
835                 ip_buffer->addr_family = 0;
836         }
837
838         if (getifaddrs(&ifap)) {
839                 strlcpy(buffer, "getifaddrs failed\n", buffer_length);
840                 return (errno);
841         }
842
843         curp = ifap;
844         while (curp != NULL) {
845                 if (curp->ifa_addr == NULL) {
846                         curp = curp->ifa_next;
847                         continue;
848                 }
849
850                 if ((if_name != NULL) &&
851                     (strncmp(curp->ifa_name, if_name, strlen(if_name)))) {
852                         /*
853                          * We want info about a specific interface;
854                          * just continue.
855                          */
856                         curp = curp->ifa_next;
857                         continue;
858                 }
859
860                 /*
861                  * We support two address families: AF_INET and AF_INET6.
862                  * If family value is 0, we gather both supported
863                  * address families; if not we gather info on
864                  * the specified address family.
865                  */
866                 if ((family != 0) && (curp->ifa_addr->sa_family != family)) {
867                         curp = curp->ifa_next;
868                         continue;
869                 }
870                 if ((curp->ifa_addr->sa_family != AF_INET) &&
871                     (curp->ifa_addr->sa_family != AF_INET6)) {
872                         curp = curp->ifa_next;
873                         continue;
874                 }
875
876                 if (op == HV_KVP_OP_GET_IP_INFO) {
877                         /*
878                          * Get the info other than the IP address.
879                          */
880                         if (curp->ifa_addr->sa_family == AF_INET) {
881                                 ip_buffer->addr_family |= ADDR_FAMILY_IPV4;
882
883                                 /*
884                                  * Get subnet info.
885                                  */
886                                 error = kvp_process_ip_address(
887                                         curp->ifa_netmask,
888                                         AF_INET,
889                                         (char *)
890                                         ip_buffer->sub_net,
891                                         length,
892                                         &sn_offset);
893                                 if (error) {
894                                         goto kvp_get_ip_info_ipaddr;
895                                 }
896                         } else {
897                                 ip_buffer->addr_family |= ADDR_FAMILY_IPV6;
898
899                                 /*
900                                  * Get subnet info in CIDR format.
901                                  */
902                                 weight = 0;
903                                 sn_str = (char *)ip_buffer->sub_net;
904                                 sn_str_length = sizeof(ip_buffer->sub_net);
905                                 addr6 = (struct sockaddr_in6 *)(uintptr_t)
906                                     curp->ifa_netmask;
907                                 w = (unsigned int *)(uintptr_t)addr6->sin6_addr.s6_addr;
908
909                                 for (i = 0; i < 4; i++)
910                                 {
911                                         weight += hweight32(&w[i]);
912                                 }
913
914                                 snprintf(cidr_mask, sizeof(cidr_mask), "/%d", weight);
915                                 if ((length - sn_offset) <
916                                     (strlen(cidr_mask) + 1)) {
917                                         goto kvp_get_ip_info_ipaddr;
918                                 }
919
920                                 if (sn_offset == 0) {
921                                         strlcpy(sn_str, cidr_mask, sn_str_length);
922                                 } else{
923                                         strlcat(sn_str, cidr_mask, sn_str_length);
924                                 }
925                                 strlcat((char *)ip_buffer->sub_net, ";", sn_str_length);
926                                 sn_offset += strlen(sn_str) + 1;
927                         }
928
929                         /*
930                          * Collect other ip configuration info.
931                          */
932                         kvp_get_ipconfig_info(if_name, ip_buffer);
933                 }
934
935 kvp_get_ip_info_ipaddr:
936                 error = kvp_process_ip_address(curp->ifa_addr,
937                         curp->ifa_addr->sa_family,
938                         buffer,
939                         length, &offset);
940                 if (error) {
941                         goto kvp_get_ip_info_done;
942                 }
943
944                 curp = curp->ifa_next;
945         }
946
947 kvp_get_ip_info_done:
948         freeifaddrs(ifap);
949         return (error);
950 }
951
952
953 static int
954 kvp_write_file(FILE *f, const char *s1, const char *s2, const char *s3)
955 {
956         int ret;
957
958         ret = fprintf(f, "%s%s%s%s\n", s1, s2, "=", s3);
959
960         if (ret < 0) {
961                 return (EIO);
962         }
963
964         return (0);
965 }
966
967
968 static int
969 kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
970 {
971         int error = 0;
972         char if_file[128];
973         FILE *file;
974         char cmd[512];
975         char *mac_addr;
976
977         /*
978          * FreeBSD - Configuration File
979          */
980         snprintf(if_file, sizeof(if_file), "%s%s", "/var/db/hyperv",
981             "hv_set_ip_data");
982         file = fopen(if_file, "w");
983
984         if (file == NULL) {
985                 KVP_LOG(LOG_ERR, "FreeBSD Failed to open config file\n");
986                 return (errno);
987         }
988
989         /*
990          * Write out the MAC address.
991          */
992
993         mac_addr = kvp_if_name_to_mac(if_name);
994         if (mac_addr == NULL) {
995                 error = EINVAL;
996                 goto kvp_set_ip_info_error;
997         }
998         /* MAC Address */
999         error = kvp_write_file(file, "HWADDR", "", mac_addr);
1000         if (error) {
1001                 goto kvp_set_ip_info_error;
1002         }
1003
1004         /* Interface Name  */
1005         error = kvp_write_file(file, "IF_NAME", "", if_name);
1006         if (error) {
1007                 goto kvp_set_ip_info_error;
1008         }
1009
1010         /* IP Address  */
1011         error = kvp_write_file(file, "IP_ADDR", "",
1012             (char *)new_val->ip_addr);
1013         if (error) {
1014                 goto kvp_set_ip_info_error;
1015         }
1016
1017         /* Subnet Mask */
1018         error = kvp_write_file(file, "SUBNET", "",
1019             (char *)new_val->sub_net);
1020         if (error) {
1021                 goto kvp_set_ip_info_error;
1022         }
1023
1024
1025         /* Gateway */
1026         error = kvp_write_file(file, "GATEWAY", "",
1027             (char *)new_val->gate_way);
1028         if (error) {
1029                 goto kvp_set_ip_info_error;
1030         }
1031
1032         /* DNS */
1033         error = kvp_write_file(file, "DNS", "", (char *)new_val->dns_addr);
1034         if (error) {
1035                 goto kvp_set_ip_info_error;
1036         }
1037
1038         /* DHCP */
1039         if (new_val->dhcp_enabled) {
1040                 error = kvp_write_file(file, "DHCP", "", "1");
1041         } else{
1042                 error = kvp_write_file(file, "DHCP", "", "0");
1043         }
1044
1045         if (error) {
1046                 goto kvp_set_ip_info_error;
1047         }
1048
1049         free(mac_addr);
1050         fclose(file);
1051
1052         /*
1053          * Invoke the external script with the populated
1054          * configuration file.
1055          */
1056
1057         snprintf(cmd, sizeof(cmd), "%s %s",
1058             "sh /usr/libexec/hyperv/hv_set_ifconfig", if_file);
1059         system(cmd);
1060         return (0);
1061
1062 kvp_set_ip_info_error:
1063         KVP_LOG(LOG_ERR, "Failed to write config file\n");
1064         free(mac_addr);
1065         fclose(file);
1066         return (error);
1067 }
1068
1069
1070 static int
1071 kvp_get_domain_name(char *buffer, int length)
1072 {
1073         struct addrinfo hints, *info;
1074         int error = 0;
1075
1076         gethostname(buffer, length);
1077         memset(&hints, 0, sizeof(hints));
1078         hints.ai_family = AF_INET;    /* Get only ipv4 addrinfo. */
1079         hints.ai_socktype = SOCK_STREAM;
1080         hints.ai_flags = AI_CANONNAME;
1081
1082         error = getaddrinfo(buffer, NULL, &hints, &info);
1083         if (error != 0) {
1084                 strlcpy(buffer, "getaddrinfo failed\n", length);
1085                 return (error);
1086         }
1087         strlcpy(buffer, info->ai_canonname, length);
1088         freeaddrinfo(info);
1089         return (error);
1090 }
1091
1092
1093 static int
1094 kvp_op_getipinfo(struct hv_kvp_msg *op_msg, void *data __unused)
1095 {
1096         struct hv_kvp_ipaddr_value *ip_val;
1097         char *if_name;
1098         int error = 0;
1099
1100         assert(op_msg != NULL);
1101         KVP_LOG(LOG_DEBUG, "In kvp_op_getipinfo.\n");
1102
1103         ip_val = &op_msg->body.kvp_ip_val;
1104         op_msg->hdr.error = HV_S_OK;
1105
1106         if_name = kvp_mac_to_if_name((char *)ip_val->adapter_id);
1107
1108         if (if_name == NULL) {
1109                 /* No interface found with the mac address. */
1110                 op_msg->hdr.error = HV_E_FAIL;
1111                 goto kvp_op_getipinfo_done;
1112         }
1113
1114         error = kvp_get_ip_info(0, if_name,
1115             HV_KVP_OP_GET_IP_INFO, ip_val, (MAX_IP_ADDR_SIZE * 2));
1116         if (error)
1117                 op_msg->hdr.error = HV_E_FAIL;
1118         free(if_name);
1119
1120 kvp_op_getipinfo_done:
1121         return (error);
1122 }
1123
1124
1125 static int
1126 kvp_op_setipinfo(struct hv_kvp_msg *op_msg, void *data __unused)
1127 {
1128         struct hv_kvp_ipaddr_value *ip_val;
1129         char *if_name;
1130         int error = 0;
1131
1132         assert(op_msg != NULL);
1133         KVP_LOG(LOG_DEBUG, "In kvp_op_setipinfo.\n");
1134
1135         ip_val = &op_msg->body.kvp_ip_val;
1136         op_msg->hdr.error = HV_S_OK;
1137
1138         if_name = (char *)ip_val->adapter_id;
1139
1140         if (if_name == NULL) {
1141                 /* No adapter provided. */
1142                 op_msg->hdr.error = HV_GUID_NOTFOUND;
1143                 goto kvp_op_setipinfo_done;
1144         }
1145
1146         error = kvp_set_ip_info(if_name, ip_val);
1147         if (error)
1148                 op_msg->hdr.error = HV_E_FAIL;
1149 kvp_op_setipinfo_done:
1150         return (error);
1151 }
1152
1153
1154 static int
1155 kvp_op_setgetdel(struct hv_kvp_msg *op_msg, void *data)
1156 {
1157         struct kvp_op_hdlr *op_hdlr = (struct kvp_op_hdlr *)data;
1158         int error = 0;
1159         int op_pool;
1160
1161         assert(op_msg != NULL);
1162         assert(op_hdlr != NULL);
1163
1164         op_pool = op_msg->hdr.kvp_hdr.pool;
1165         op_msg->hdr.error = HV_S_OK;
1166
1167         switch(op_hdlr->kvp_op_key) {
1168         case HV_KVP_OP_SET:
1169                 if (op_pool == HV_KVP_POOL_AUTO) {
1170                         /* Auto Pool is not writeable from host side. */
1171                         error = 1;
1172                         KVP_LOG(LOG_ERR, "Ilegal to write to pool %d from host\n",
1173                             op_pool);
1174                 } else {
1175                         error = kvp_key_add_or_modify(op_pool,
1176                             op_msg->body.kvp_set.data.key,
1177                             op_msg->body.kvp_set.data.key_size,
1178                             op_msg->body.kvp_set.data.msg_value.value,
1179                             op_msg->body.kvp_set.data.value_size);
1180                 }
1181                 break;
1182
1183         case HV_KVP_OP_GET:
1184                 error = kvp_get_value(op_pool,
1185                     op_msg->body.kvp_get.data.key,
1186                     op_msg->body.kvp_get.data.key_size,
1187                     op_msg->body.kvp_get.data.msg_value.value,
1188                     op_msg->body.kvp_get.data.value_size);
1189                 break;
1190
1191         case HV_KVP_OP_DELETE:
1192                 if (op_pool == HV_KVP_POOL_AUTO) {
1193                         /* Auto Pool is not writeable from host side. */
1194                         error = 1;
1195                         KVP_LOG(LOG_ERR, "Ilegal to change pool %d from host\n",
1196                             op_pool);
1197                 } else {
1198                         error = kvp_key_delete(op_pool,
1199                             op_msg->body.kvp_delete.key,
1200                             op_msg->body.kvp_delete.key_size);
1201                 }
1202                 break;
1203
1204         default:
1205                 break;
1206         }
1207
1208         if (error != 0)
1209                 op_msg->hdr.error = HV_S_CONT;
1210         return(error);
1211 }
1212
1213
1214 static int
1215 kvp_op_enumerate(struct hv_kvp_msg *op_msg, void *data __unused)
1216 {
1217         char *key_name, *key_value;
1218         int error = 0;
1219         int op_pool;
1220         int op;
1221
1222         assert(op_msg != NULL);
1223
1224         op = op_msg->hdr.kvp_hdr.operation;
1225         op_pool = op_msg->hdr.kvp_hdr.pool;
1226         op_msg->hdr.error = HV_S_OK;
1227
1228         /*
1229          * If the pool is not HV_KVP_POOL_AUTO, read from the appropriate
1230          * pool and return the KVP according to the index requested.
1231          */
1232         if (op_pool != HV_KVP_POOL_AUTO) {
1233                 if (kvp_pool_enumerate(op_pool,
1234                     op_msg->body.kvp_enum_data.index,
1235                     op_msg->body.kvp_enum_data.data.key,
1236                     HV_KVP_EXCHANGE_MAX_KEY_SIZE,
1237                     op_msg->body.kvp_enum_data.data.msg_value.value,
1238                     HV_KVP_EXCHANGE_MAX_VALUE_SIZE)) {
1239                         op_msg->hdr.error = HV_S_CONT;
1240                         error = -1;
1241                 }
1242                 goto kvp_op_enumerate_done;
1243         }
1244
1245         key_name = (char *)op_msg->body.kvp_enum_data.data.key;
1246         key_value = (char *)op_msg->body.kvp_enum_data.data.msg_value.value;
1247
1248         switch (op_msg->body.kvp_enum_data.index)
1249         {
1250         case FullyQualifiedDomainName:
1251                 kvp_get_domain_name(key_value,
1252                     HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
1253                 strcpy(key_name, "FullyQualifiedDomainName");
1254                 break;
1255
1256         case IntegrationServicesVersion:
1257                 strcpy(key_name, "IntegrationServicesVersion");
1258                 strlcpy(key_value, lic_version, HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
1259                 break;
1260
1261         case NetworkAddressIPv4:
1262                 kvp_get_ip_info(AF_INET, NULL, HV_KVP_OP_ENUMERATE,
1263                     key_value, HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
1264                 strcpy(key_name, "NetworkAddressIPv4");
1265                 break;
1266
1267         case NetworkAddressIPv6:
1268                 kvp_get_ip_info(AF_INET6, NULL, HV_KVP_OP_ENUMERATE,
1269                     key_value, HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
1270                 strcpy(key_name, "NetworkAddressIPv6");
1271                 break;
1272
1273         case OSBuildNumber:
1274                 strlcpy(key_value, os_build, HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
1275                 strcpy(key_name, "OSBuildNumber");
1276                 break;
1277
1278         case OSName:
1279                 strlcpy(key_value, os_name, HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
1280                 strcpy(key_name, "OSName");
1281                 break;
1282
1283         case OSMajorVersion:
1284                 strlcpy(key_value, os_major, HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
1285                 strcpy(key_name, "OSMajorVersion");
1286                 break;
1287
1288         case OSMinorVersion:
1289                 strlcpy(key_value, os_minor, HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
1290                 strcpy(key_name, "OSMinorVersion");
1291                 break;
1292
1293         case OSVersion:
1294                 strlcpy(key_value, os_build, HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
1295                 strcpy(key_name, "OSVersion");
1296                 break;
1297
1298         case ProcessorArchitecture:
1299                 strlcpy(key_value, processor_arch, HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
1300                 strcpy(key_name, "ProcessorArchitecture");
1301                 break;
1302
1303         default:
1304 #ifdef DEBUG
1305                 KVP_LOG(LOG_ERR, "Auto pool Index %d not found.\n",
1306                     op_msg->body.kvp_enum_data.index);
1307 #endif
1308                 op_msg->hdr.error = HV_S_CONT;
1309                 error = -1;
1310                 break;
1311         }
1312
1313 kvp_op_enumerate_done:
1314         if (error != 0)
1315                 op_msg->hdr.error = HV_S_CONT;
1316         return(error);
1317 }
1318
1319
1320 /*
1321  * Load handler, and call init routine if provided.
1322  */
1323 static int
1324 kvp_op_load(int key, void (*init)(void),
1325             int (*exec)(struct hv_kvp_msg *, void *))
1326 {
1327         int error = 0;
1328
1329         if (key < 0 || key >= HV_KVP_OP_COUNT) {
1330                 KVP_LOG(LOG_ERR, "Operation key out of supported range\n");
1331                 error = -1;
1332                 goto kvp_op_load_done;
1333         }
1334
1335         kvp_op_hdlrs[key].kvp_op_key = key;
1336         kvp_op_hdlrs[key].kvp_op_init = init;
1337         kvp_op_hdlrs[key].kvp_op_exec = exec;
1338
1339         if (kvp_op_hdlrs[key].kvp_op_init != NULL)
1340                 kvp_op_hdlrs[key].kvp_op_init();
1341
1342 kvp_op_load_done:
1343         return(error);
1344 }
1345
1346
1347 /*
1348  * Initialize the operation hanlders.
1349  */
1350 static int
1351 kvp_ops_init(void)
1352 {
1353         int i;
1354
1355         /* Set the initial values. */
1356         for (i = 0; i < HV_KVP_OP_COUNT; i++) {
1357                 kvp_op_hdlrs[i].kvp_op_key = -1;
1358                 kvp_op_hdlrs[i].kvp_op_init = NULL;
1359                 kvp_op_hdlrs[i].kvp_op_exec = NULL;
1360         }
1361
1362         return(kvp_op_load(HV_KVP_OP_GET, NULL, kvp_op_setgetdel) |
1363             kvp_op_load(HV_KVP_OP_SET, NULL, kvp_op_setgetdel) |
1364             kvp_op_load(HV_KVP_OP_DELETE, NULL, kvp_op_setgetdel) |
1365             kvp_op_load(HV_KVP_OP_ENUMERATE, kvp_get_os_info,
1366                 kvp_op_enumerate) |
1367             kvp_op_load(HV_KVP_OP_GET_IP_INFO, NULL, kvp_op_getipinfo) |
1368             kvp_op_load(HV_KVP_OP_SET_IP_INFO, NULL, kvp_op_setipinfo));
1369 }
1370
1371
1372 int
1373 main(int argc, char *argv[])
1374 {
1375         struct hv_kvp_msg *hv_kvp_dev_buf;
1376         struct hv_kvp_msg *hv_msg;
1377         struct pollfd hv_kvp_poll_fd[1];
1378         int op, pool;
1379         int hv_kvp_dev_fd, error, len, r;
1380         int ch;
1381
1382         while ((ch = getopt(argc, argv, "dn")) != -1) {
1383                 switch (ch) {
1384                 case 'n':
1385                         /* Run as regular process for debugging purpose. */
1386                         is_daemon = 0;
1387                         break;
1388                 case 'd':
1389                         /* Generate debugging output */
1390                         is_debugging = 1;
1391                         break;
1392                 default:
1393                         break;
1394                 }
1395         }
1396
1397         openlog("HV_KVP", 0, LOG_USER);
1398
1399         /* Become daemon first. */
1400         if (is_daemon == 1)
1401                 daemon(1, 0);
1402         else
1403                 KVP_LOG(LOG_DEBUG, "Run as regular process.\n");
1404
1405         KVP_LOG(LOG_INFO, "HV_KVP starting; pid is: %d\n", getpid());
1406
1407         /* Communication buffer hv_kvp_dev_buf */
1408         hv_kvp_dev_buf = malloc(sizeof(*hv_kvp_dev_buf));
1409         /* Buffer for daemon internal use */
1410         hv_msg = malloc(sizeof(*hv_msg));
1411
1412         /* Memory allocation failed */
1413         if (hv_kvp_dev_buf == NULL || hv_msg == NULL) {
1414                 KVP_LOG(LOG_ERR, "Failed to allocate memory for hv buffer\n");
1415                 exit(EXIT_FAILURE);
1416         }
1417
1418         /* Initialize op handlers */
1419         if (kvp_ops_init() != 0) {
1420                 KVP_LOG(LOG_ERR, "Failed to initizlize operation handlers\n");
1421                 exit(EXIT_FAILURE);
1422         }
1423
1424         if (kvp_file_init()) {
1425                 KVP_LOG(LOG_ERR, "Failed to initialize the pools\n");
1426                 exit(EXIT_FAILURE);
1427         }
1428
1429         /* Open the Character Device */
1430         hv_kvp_dev_fd = open("/dev/hv_kvp_dev", O_RDWR);
1431
1432         if (hv_kvp_dev_fd < 0) {
1433                 KVP_LOG(LOG_ERR, "open /dev/hv_kvp_dev failed; error: %d %s\n",
1434                     errno, strerror(errno));
1435                 exit(EXIT_FAILURE);
1436         }
1437
1438         /* Initialize the struct for polling the char device */
1439         hv_kvp_poll_fd[0].fd = hv_kvp_dev_fd;
1440         hv_kvp_poll_fd[0].events = (POLLIN | POLLRDNORM);
1441
1442         /* Register the daemon to the KVP driver */
1443         memset(hv_kvp_dev_buf, 0, sizeof(*hv_kvp_dev_buf));
1444         hv_kvp_dev_buf->hdr.kvp_hdr.operation = HV_KVP_OP_REGISTER;
1445         len = write(hv_kvp_dev_fd, hv_kvp_dev_buf, sizeof(*hv_kvp_dev_buf));
1446
1447
1448         for (;;) {
1449                 r = poll (hv_kvp_poll_fd, 1, INFTIM);
1450
1451                 KVP_LOG(LOG_DEBUG, "poll returned r = %d, revent = 0x%x\n",
1452                     r, hv_kvp_poll_fd[0].revents);
1453
1454                 if (r == 0 || (r < 0 && errno == EAGAIN) ||
1455                     (r < 0 && errno == EINTR)) {
1456                         /* Nothing to read */
1457                         continue;
1458                 }
1459
1460                 if (r < 0) {
1461                         /*
1462                          * For pread return failure other than EAGAIN,
1463                          * we want to exit.
1464                          */
1465                         KVP_LOG(LOG_ERR, "Poll failed.\n");
1466                         perror("poll");
1467                         exit(EIO);
1468                 }
1469
1470                 /* Read from character device */
1471                 len = pread(hv_kvp_dev_fd, hv_kvp_dev_buf,
1472                     sizeof(*hv_kvp_dev_buf), 0);
1473
1474                 if (len < 0) {
1475                         KVP_LOG(LOG_ERR, "Read failed.\n");
1476                         perror("pread");
1477                         exit(EIO);
1478                 }
1479
1480                 if (len != sizeof(struct hv_kvp_msg)) {
1481                         KVP_LOG(LOG_ERR, "read len is: %d\n", len);
1482                         continue;
1483                 }
1484
1485                 /* Copy hv_kvp_dev_buf to hv_msg */
1486                 memcpy(hv_msg, hv_kvp_dev_buf, sizeof(*hv_msg));
1487
1488                 /*
1489                  * We will use the KVP header information to pass back
1490                  * the error from this daemon. So, first save the op
1491                  * and pool info to local variables.
1492                  */
1493
1494                 op = hv_msg->hdr.kvp_hdr.operation;
1495                 pool = hv_msg->hdr.kvp_hdr.pool;
1496
1497                 if (op < 0 || op >= HV_KVP_OP_COUNT ||
1498                     kvp_op_hdlrs[op].kvp_op_exec == NULL) {
1499                         KVP_LOG(LOG_WARNING,
1500                             "Unsupported operation OP = %d\n", op);
1501                         hv_msg->hdr.error = HV_ERROR_NOT_SUPPORTED;
1502                 } else {
1503                         /*
1504                          * Call the operateion handler's execution routine.
1505                          */
1506                         error = kvp_op_hdlrs[op].kvp_op_exec(hv_msg,
1507                             (void *)&kvp_op_hdlrs[op]);
1508                         if (error != 0) {
1509                                 assert(hv_msg->hdr.error != HV_S_OK);
1510                                 if (hv_msg->hdr.error != HV_S_CONT)
1511                                         KVP_LOG(LOG_WARNING,
1512                                             "Operation failed OP = %d, error = 0x%x\n",
1513                                             op, error);
1514                         }
1515                 }
1516
1517                 /*
1518                  * Send the value back to the kernel. The response is
1519                  * already in the receive buffer.
1520                  */
1521 hv_kvp_done:
1522                 len = pwrite(hv_kvp_dev_fd, hv_msg, sizeof(*hv_kvp_dev_buf), 0);
1523
1524                 if (len != sizeof(struct hv_kvp_msg)) {
1525                         KVP_LOG(LOG_ERR, "write len is: %d\n", len);
1526                         goto hv_kvp_done;
1527                 }
1528         }
1529 }