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