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