aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-26 17:51:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-26 17:51:15 -0400
commitd87823813fe498fdd47894bd28e460a9dee8d771 (patch)
tree214eaf3babd0d61f08022fc1edd99a5128616548 /tools
parente382608254e06c8109f40044f5e693f2e04f3899 (diff)
parent3dc196eae1db548f05e53e5875ff87b8ff79f249 (diff)
Merge tag 'char-misc-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH: "Here's the big char/misc driver pull request for 4.2-rc1. Lots of mei, extcon, coresight, uio, mic, and other driver updates in here. Full details in the shortlog. All of these have been in linux-next for some time with no reported problems" * tag 'char-misc-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (176 commits) mei: me: wait for power gating exit confirmation mei: reset flow control on the last client disconnection MAINTAINERS: mei: add mei_cl_bus.h to maintained file list misc: sram: sort and clean up included headers misc: sram: move reserved block logic out of probe function misc: sram: add private struct device and virt_base members misc: sram: report correct SRAM pool size misc: sram: bump error message level on unclean driver unbinding misc: sram: fix device node reference leak on error misc: sram: fix enabled clock leak on error path misc: mic: Fix reported static checker warning misc: mic: Fix randconfig build error by including errno.h uio: pruss: Drop depends on ARCH_DAVINCI_DA850 from config uio: pruss: Add CONFIG_HAS_IOMEM dependence uio: pruss: Include <linux/sizes.h> extcon: Redefine the unique id of supported external connectors without 'enum extcon' type char:xilinx_hwicap:buffer_icap - change 1/0 to true/false for bool type variable in function buffer_icap_set_configuration(). Drivers: hv: vmbus: Allocate ring buffer memory in NUMA aware fashion parport: check exclusive access before register w1: use correct lock on error in w1_seq_show() ...
Diffstat (limited to 'tools')
-rw-r--r--tools/hv/hv_fcopy_daemon.c15
-rw-r--r--tools/hv/hv_kvp_daemon.c166
-rw-r--r--tools/hv/hv_vss_daemon.c149
3 files changed, 83 insertions, 247 deletions
diff --git a/tools/hv/hv_fcopy_daemon.c b/tools/hv/hv_fcopy_daemon.c
index 9445d8f264a4..5480e4e424eb 100644
--- a/tools/hv/hv_fcopy_daemon.c
+++ b/tools/hv/hv_fcopy_daemon.c
@@ -137,6 +137,8 @@ int main(int argc, char *argv[])
137 int version = FCOPY_CURRENT_VERSION; 137 int version = FCOPY_CURRENT_VERSION;
138 char *buffer[4096 * 2]; 138 char *buffer[4096 * 2];
139 struct hv_fcopy_hdr *in_msg; 139 struct hv_fcopy_hdr *in_msg;
140 int in_handshake = 1;
141 __u32 kernel_modver;
140 142
141 static struct option long_options[] = { 143 static struct option long_options[] = {
142 {"help", no_argument, 0, 'h' }, 144 {"help", no_argument, 0, 'h' },
@@ -191,6 +193,19 @@ int main(int argc, char *argv[])
191 syslog(LOG_ERR, "pread failed: %s", strerror(errno)); 193 syslog(LOG_ERR, "pread failed: %s", strerror(errno));
192 exit(EXIT_FAILURE); 194 exit(EXIT_FAILURE);
193 } 195 }
196
197 if (in_handshake) {
198 if (len != sizeof(kernel_modver)) {
199 syslog(LOG_ERR, "invalid version negotiation");
200 exit(EXIT_FAILURE);
201 }
202 kernel_modver = *(__u32 *)buffer;
203 in_handshake = 0;
204 syslog(LOG_INFO, "HV_FCOPY: kernel module version: %d",
205 kernel_modver);
206 continue;
207 }
208
194 in_msg = (struct hv_fcopy_hdr *)buffer; 209 in_msg = (struct hv_fcopy_hdr *)buffer;
195 210
196 switch (in_msg->operation) { 211 switch (in_msg->operation) {
diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index 408bb076a234..0d9f48ec42bb 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -33,7 +33,6 @@
33#include <ctype.h> 33#include <ctype.h>
34#include <errno.h> 34#include <errno.h>
35#include <arpa/inet.h> 35#include <arpa/inet.h>
36#include <linux/connector.h>
37#include <linux/hyperv.h> 36#include <linux/hyperv.h>
38#include <linux/netlink.h> 37#include <linux/netlink.h>
39#include <ifaddrs.h> 38#include <ifaddrs.h>
@@ -79,7 +78,6 @@ enum {
79 DNS 78 DNS
80}; 79};
81 80
82static struct sockaddr_nl addr;
83static int in_hand_shake = 1; 81static int in_hand_shake = 1;
84 82
85static char *os_name = ""; 83static char *os_name = "";
@@ -1387,34 +1385,6 @@ kvp_get_domain_name(char *buffer, int length)
1387 freeaddrinfo(info); 1385 freeaddrinfo(info);
1388} 1386}
1389 1387
1390static int
1391netlink_send(int fd, struct cn_msg *msg)
1392{
1393 struct nlmsghdr nlh = { .nlmsg_type = NLMSG_DONE };
1394 unsigned int size;
1395 struct msghdr message;
1396 struct iovec iov[2];
1397
1398 size = sizeof(struct cn_msg) + msg->len;
1399
1400 nlh.nlmsg_pid = getpid();
1401 nlh.nlmsg_len = NLMSG_LENGTH(size);
1402
1403 iov[0].iov_base = &nlh;
1404 iov[0].iov_len = sizeof(nlh);
1405
1406 iov[1].iov_base = msg;
1407 iov[1].iov_len = size;
1408
1409 memset(&message, 0, sizeof(message));
1410 message.msg_name = &addr;
1411 message.msg_namelen = sizeof(addr);
1412 message.msg_iov = iov;
1413 message.msg_iovlen = 2;
1414
1415 return sendmsg(fd, &message, 0);
1416}
1417
1418void print_usage(char *argv[]) 1388void print_usage(char *argv[])
1419{ 1389{
1420 fprintf(stderr, "Usage: %s [options]\n" 1390 fprintf(stderr, "Usage: %s [options]\n"
@@ -1425,22 +1395,17 @@ void print_usage(char *argv[])
1425 1395
1426int main(int argc, char *argv[]) 1396int main(int argc, char *argv[])
1427{ 1397{
1428 int fd, len, nl_group; 1398 int kvp_fd, len;
1429 int error; 1399 int error;
1430 struct cn_msg *message;
1431 struct pollfd pfd; 1400 struct pollfd pfd;
1432 struct nlmsghdr *incoming_msg; 1401 char *p;
1433 struct cn_msg *incoming_cn_msg; 1402 struct hv_kvp_msg hv_msg[1];
1434 struct hv_kvp_msg *hv_msg;
1435 char *p;
1436 char *key_value; 1403 char *key_value;
1437 char *key_name; 1404 char *key_name;
1438 int op; 1405 int op;
1439 int pool; 1406 int pool;
1440 char *if_name; 1407 char *if_name;
1441 struct hv_kvp_ipaddr_value *kvp_ip_val; 1408 struct hv_kvp_ipaddr_value *kvp_ip_val;
1442 char *kvp_recv_buffer;
1443 size_t kvp_recv_buffer_len;
1444 int daemonize = 1, long_index = 0, opt; 1409 int daemonize = 1, long_index = 0, opt;
1445 1410
1446 static struct option long_options[] = { 1411 static struct option long_options[] = {
@@ -1468,12 +1433,14 @@ int main(int argc, char *argv[])
1468 openlog("KVP", 0, LOG_USER); 1433 openlog("KVP", 0, LOG_USER);
1469 syslog(LOG_INFO, "KVP starting; pid is:%d", getpid()); 1434 syslog(LOG_INFO, "KVP starting; pid is:%d", getpid());
1470 1435
1471 kvp_recv_buffer_len = NLMSG_LENGTH(0) + sizeof(struct cn_msg) + sizeof(struct hv_kvp_msg); 1436 kvp_fd = open("/dev/vmbus/hv_kvp", O_RDWR);
1472 kvp_recv_buffer = calloc(1, kvp_recv_buffer_len); 1437
1473 if (!kvp_recv_buffer) { 1438 if (kvp_fd < 0) {
1474 syslog(LOG_ERR, "Failed to allocate netlink buffer"); 1439 syslog(LOG_ERR, "open /dev/vmbus/hv_kvp failed; error: %d %s",
1440 errno, strerror(errno));
1475 exit(EXIT_FAILURE); 1441 exit(EXIT_FAILURE);
1476 } 1442 }
1443
1477 /* 1444 /*
1478 * Retrieve OS release information. 1445 * Retrieve OS release information.
1479 */ 1446 */
@@ -1489,100 +1456,44 @@ int main(int argc, char *argv[])
1489 exit(EXIT_FAILURE); 1456 exit(EXIT_FAILURE);
1490 } 1457 }
1491 1458
1492 fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
1493 if (fd < 0) {
1494 syslog(LOG_ERR, "netlink socket creation failed; error: %d %s", errno,
1495 strerror(errno));
1496 exit(EXIT_FAILURE);
1497 }
1498 addr.nl_family = AF_NETLINK;
1499 addr.nl_pad = 0;
1500 addr.nl_pid = 0;
1501 addr.nl_groups = 0;
1502
1503
1504 error = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
1505 if (error < 0) {
1506 syslog(LOG_ERR, "bind failed; error: %d %s", errno, strerror(errno));
1507 close(fd);
1508 exit(EXIT_FAILURE);
1509 }
1510 nl_group = CN_KVP_IDX;
1511
1512 if (setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &nl_group, sizeof(nl_group)) < 0) {
1513 syslog(LOG_ERR, "setsockopt failed; error: %d %s", errno, strerror(errno));
1514 close(fd);
1515 exit(EXIT_FAILURE);
1516 }
1517
1518 /* 1459 /*
1519 * Register ourselves with the kernel. 1460 * Register ourselves with the kernel.
1520 */ 1461 */
1521 message = (struct cn_msg *)kvp_recv_buffer;
1522 message->id.idx = CN_KVP_IDX;
1523 message->id.val = CN_KVP_VAL;
1524
1525 hv_msg = (struct hv_kvp_msg *)message->data;
1526 hv_msg->kvp_hdr.operation = KVP_OP_REGISTER1; 1462 hv_msg->kvp_hdr.operation = KVP_OP_REGISTER1;
1527 message->ack = 0; 1463 len = write(kvp_fd, hv_msg, sizeof(struct hv_kvp_msg));
1528 message->len = sizeof(struct hv_kvp_msg); 1464 if (len != sizeof(struct hv_kvp_msg)) {
1529 1465 syslog(LOG_ERR, "registration to kernel failed; error: %d %s",
1530 len = netlink_send(fd, message); 1466 errno, strerror(errno));
1531 if (len < 0) { 1467 close(kvp_fd);
1532 syslog(LOG_ERR, "netlink_send failed; error: %d %s", errno, strerror(errno));
1533 close(fd);
1534 exit(EXIT_FAILURE); 1468 exit(EXIT_FAILURE);
1535 } 1469 }
1536 1470
1537 pfd.fd = fd; 1471 pfd.fd = kvp_fd;
1538 1472
1539 while (1) { 1473 while (1) {
1540 struct sockaddr *addr_p = (struct sockaddr *) &addr;
1541 socklen_t addr_l = sizeof(addr);
1542 pfd.events = POLLIN; 1474 pfd.events = POLLIN;
1543 pfd.revents = 0; 1475 pfd.revents = 0;
1544 1476
1545 if (poll(&pfd, 1, -1) < 0) { 1477 if (poll(&pfd, 1, -1) < 0) {
1546 syslog(LOG_ERR, "poll failed; error: %d %s", errno, strerror(errno)); 1478 syslog(LOG_ERR, "poll failed; error: %d %s", errno, strerror(errno));
1547 if (errno == EINVAL) { 1479 if (errno == EINVAL) {
1548 close(fd); 1480 close(kvp_fd);
1549 exit(EXIT_FAILURE); 1481 exit(EXIT_FAILURE);
1550 } 1482 }
1551 else 1483 else
1552 continue; 1484 continue;
1553 } 1485 }
1554 1486
1555 len = recvfrom(fd, kvp_recv_buffer, kvp_recv_buffer_len, 0, 1487 len = read(kvp_fd, hv_msg, sizeof(struct hv_kvp_msg));
1556 addr_p, &addr_l);
1557
1558 if (len < 0) {
1559 int saved_errno = errno;
1560 syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s",
1561 addr.nl_pid, errno, strerror(errno));
1562 1488
1563 if (saved_errno == ENOBUFS) { 1489 if (len != sizeof(struct hv_kvp_msg)) {
1564 syslog(LOG_ERR, "receive error: ignored"); 1490 syslog(LOG_ERR, "read failed; error:%d %s",
1565 continue; 1491 errno, strerror(errno));
1566 }
1567 1492
1568 close(fd); 1493 close(kvp_fd);
1569 return -1; 1494 return EXIT_FAILURE;
1570 } 1495 }
1571 1496
1572 if (addr.nl_pid) {
1573 syslog(LOG_WARNING, "Received packet from untrusted pid:%u",
1574 addr.nl_pid);
1575 continue;
1576 }
1577
1578 incoming_msg = (struct nlmsghdr *)kvp_recv_buffer;
1579
1580 if (incoming_msg->nlmsg_type != NLMSG_DONE)
1581 continue;
1582
1583 incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg);
1584 hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data;
1585
1586 /* 1497 /*
1587 * We will use the KVP header information to pass back 1498 * We will use the KVP header information to pass back
1588 * the error from this daemon. So, first copy the state 1499 * the error from this daemon. So, first copy the state
@@ -1603,7 +1514,7 @@ int main(int argc, char *argv[])
1603 if (lic_version) { 1514 if (lic_version) {
1604 strcpy(lic_version, p); 1515 strcpy(lic_version, p);
1605 syslog(LOG_INFO, "KVP LIC Version: %s", 1516 syslog(LOG_INFO, "KVP LIC Version: %s",
1606 lic_version); 1517 lic_version);
1607 } else { 1518 } else {
1608 syslog(LOG_ERR, "malloc failed"); 1519 syslog(LOG_ERR, "malloc failed");
1609 } 1520 }
@@ -1702,7 +1613,6 @@ int main(int argc, char *argv[])
1702 goto kvp_done; 1613 goto kvp_done;
1703 } 1614 }
1704 1615
1705 hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data;
1706 key_name = (char *)hv_msg->body.kvp_enum_data.data.key; 1616 key_name = (char *)hv_msg->body.kvp_enum_data.data.key;
1707 key_value = (char *)hv_msg->body.kvp_enum_data.data.value; 1617 key_value = (char *)hv_msg->body.kvp_enum_data.data.value;
1708 1618
@@ -1753,31 +1663,17 @@ int main(int argc, char *argv[])
1753 hv_msg->error = HV_S_CONT; 1663 hv_msg->error = HV_S_CONT;
1754 break; 1664 break;
1755 } 1665 }
1756 /*
1757 * Send the value back to the kernel. The response is
1758 * already in the receive buffer. Update the cn_msg header to
1759 * reflect the key value that has been added to the message
1760 */
1761kvp_done:
1762
1763 incoming_cn_msg->id.idx = CN_KVP_IDX;
1764 incoming_cn_msg->id.val = CN_KVP_VAL;
1765 incoming_cn_msg->ack = 0;
1766 incoming_cn_msg->len = sizeof(struct hv_kvp_msg);
1767
1768 len = netlink_send(fd, incoming_cn_msg);
1769 if (len < 0) {
1770 int saved_errno = errno;
1771 syslog(LOG_ERR, "net_link send failed; error: %d %s", errno,
1772 strerror(errno));
1773
1774 if (saved_errno == ENOMEM || saved_errno == ENOBUFS) {
1775 syslog(LOG_ERR, "send error: ignored");
1776 continue;
1777 }
1778 1666
1667 /* Send the value back to the kernel. */
1668kvp_done:
1669 len = write(kvp_fd, hv_msg, sizeof(struct hv_kvp_msg));
1670 if (len != sizeof(struct hv_kvp_msg)) {
1671 syslog(LOG_ERR, "write failed; error: %d %s", errno,
1672 strerror(errno));
1779 exit(EXIT_FAILURE); 1673 exit(EXIT_FAILURE);
1780 } 1674 }
1781 } 1675 }
1782 1676
1677 close(kvp_fd);
1678 exit(0);
1783} 1679}
diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c
index 506dd0148828..96234b638249 100644
--- a/tools/hv/hv_vss_daemon.c
+++ b/tools/hv/hv_vss_daemon.c
@@ -19,7 +19,6 @@
19 19
20 20
21#include <sys/types.h> 21#include <sys/types.h>
22#include <sys/socket.h>
23#include <sys/poll.h> 22#include <sys/poll.h>
24#include <sys/ioctl.h> 23#include <sys/ioctl.h>
25#include <fcntl.h> 24#include <fcntl.h>
@@ -30,21 +29,11 @@
30#include <string.h> 29#include <string.h>
31#include <ctype.h> 30#include <ctype.h>
32#include <errno.h> 31#include <errno.h>
33#include <arpa/inet.h>
34#include <linux/fs.h> 32#include <linux/fs.h>
35#include <linux/connector.h>
36#include <linux/hyperv.h> 33#include <linux/hyperv.h>
37#include <linux/netlink.h>
38#include <syslog.h> 34#include <syslog.h>
39#include <getopt.h> 35#include <getopt.h>
40 36
41static struct sockaddr_nl addr;
42
43#ifndef SOL_NETLINK
44#define SOL_NETLINK 270
45#endif
46
47
48/* Don't use syslog() in the function since that can cause write to disk */ 37/* Don't use syslog() in the function since that can cause write to disk */
49static int vss_do_freeze(char *dir, unsigned int cmd) 38static int vss_do_freeze(char *dir, unsigned int cmd)
50{ 39{
@@ -143,33 +132,6 @@ out:
143 return error; 132 return error;
144} 133}
145 134
146static int netlink_send(int fd, struct cn_msg *msg)
147{
148 struct nlmsghdr nlh = { .nlmsg_type = NLMSG_DONE };
149 unsigned int size;
150 struct msghdr message;
151 struct iovec iov[2];
152
153 size = sizeof(struct cn_msg) + msg->len;
154
155 nlh.nlmsg_pid = getpid();
156 nlh.nlmsg_len = NLMSG_LENGTH(size);
157
158 iov[0].iov_base = &nlh;
159 iov[0].iov_len = sizeof(nlh);
160
161 iov[1].iov_base = msg;
162 iov[1].iov_len = size;
163
164 memset(&message, 0, sizeof(message));
165 message.msg_name = &addr;
166 message.msg_namelen = sizeof(addr);
167 message.msg_iov = iov;
168 message.msg_iovlen = 2;
169
170 return sendmsg(fd, &message, 0);
171}
172
173void print_usage(char *argv[]) 135void print_usage(char *argv[])
174{ 136{
175 fprintf(stderr, "Usage: %s [options]\n" 137 fprintf(stderr, "Usage: %s [options]\n"
@@ -180,17 +142,14 @@ void print_usage(char *argv[])
180 142
181int main(int argc, char *argv[]) 143int main(int argc, char *argv[])
182{ 144{
183 int fd, len, nl_group; 145 int vss_fd, len;
184 int error; 146 int error;
185 struct cn_msg *message;
186 struct pollfd pfd; 147 struct pollfd pfd;
187 struct nlmsghdr *incoming_msg;
188 struct cn_msg *incoming_cn_msg;
189 int op; 148 int op;
190 struct hv_vss_msg *vss_msg; 149 struct hv_vss_msg vss_msg[1];
191 char *vss_recv_buffer;
192 size_t vss_recv_buffer_len;
193 int daemonize = 1, long_index = 0, opt; 150 int daemonize = 1, long_index = 0, opt;
151 int in_handshake = 1;
152 __u32 kernel_modver;
194 153
195 static struct option long_options[] = { 154 static struct option long_options[] = {
196 {"help", no_argument, 0, 'h' }, 155 {"help", no_argument, 0, 'h' },
@@ -217,98 +176,62 @@ int main(int argc, char *argv[])
217 openlog("Hyper-V VSS", 0, LOG_USER); 176 openlog("Hyper-V VSS", 0, LOG_USER);
218 syslog(LOG_INFO, "VSS starting; pid is:%d", getpid()); 177 syslog(LOG_INFO, "VSS starting; pid is:%d", getpid());
219 178
220 vss_recv_buffer_len = NLMSG_LENGTH(0) + sizeof(struct cn_msg) + sizeof(struct hv_vss_msg); 179 vss_fd = open("/dev/vmbus/hv_vss", O_RDWR);
221 vss_recv_buffer = calloc(1, vss_recv_buffer_len); 180 if (vss_fd < 0) {
222 if (!vss_recv_buffer) { 181 syslog(LOG_ERR, "open /dev/vmbus/hv_vss failed; error: %d %s",
223 syslog(LOG_ERR, "Failed to allocate netlink buffers"); 182 errno, strerror(errno));
224 exit(EXIT_FAILURE);
225 }
226
227 fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
228 if (fd < 0) {
229 syslog(LOG_ERR, "netlink socket creation failed; error:%d %s",
230 errno, strerror(errno));
231 exit(EXIT_FAILURE);
232 }
233 addr.nl_family = AF_NETLINK;
234 addr.nl_pad = 0;
235 addr.nl_pid = 0;
236 addr.nl_groups = 0;
237
238
239 error = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
240 if (error < 0) {
241 syslog(LOG_ERR, "bind failed; error:%d %s", errno, strerror(errno));
242 close(fd);
243 exit(EXIT_FAILURE);
244 }
245 nl_group = CN_VSS_IDX;
246 if (setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &nl_group, sizeof(nl_group)) < 0) {
247 syslog(LOG_ERR, "setsockopt failed; error:%d %s", errno, strerror(errno));
248 close(fd);
249 exit(EXIT_FAILURE); 183 exit(EXIT_FAILURE);
250 } 184 }
251 /* 185 /*
252 * Register ourselves with the kernel. 186 * Register ourselves with the kernel.
253 */ 187 */
254 message = (struct cn_msg *)vss_recv_buffer; 188 vss_msg->vss_hdr.operation = VSS_OP_REGISTER1;
255 message->id.idx = CN_VSS_IDX;
256 message->id.val = CN_VSS_VAL;
257 message->ack = 0;
258 vss_msg = (struct hv_vss_msg *)message->data;
259 vss_msg->vss_hdr.operation = VSS_OP_REGISTER;
260 189
261 message->len = sizeof(struct hv_vss_msg); 190 len = write(vss_fd, vss_msg, sizeof(struct hv_vss_msg));
262
263 len = netlink_send(fd, message);
264 if (len < 0) { 191 if (len < 0) {
265 syslog(LOG_ERR, "netlink_send failed; error:%d %s", errno, strerror(errno)); 192 syslog(LOG_ERR, "registration to kernel failed; error: %d %s",
266 close(fd); 193 errno, strerror(errno));
194 close(vss_fd);
267 exit(EXIT_FAILURE); 195 exit(EXIT_FAILURE);
268 } 196 }
269 197
270 pfd.fd = fd; 198 pfd.fd = vss_fd;
271 199
272 while (1) { 200 while (1) {
273 struct sockaddr *addr_p = (struct sockaddr *) &addr;
274 socklen_t addr_l = sizeof(addr);
275 pfd.events = POLLIN; 201 pfd.events = POLLIN;
276 pfd.revents = 0; 202 pfd.revents = 0;
277 203
278 if (poll(&pfd, 1, -1) < 0) { 204 if (poll(&pfd, 1, -1) < 0) {
279 syslog(LOG_ERR, "poll failed; error:%d %s", errno, strerror(errno)); 205 syslog(LOG_ERR, "poll failed; error:%d %s", errno, strerror(errno));
280 if (errno == EINVAL) { 206 if (errno == EINVAL) {
281 close(fd); 207 close(vss_fd);
282 exit(EXIT_FAILURE); 208 exit(EXIT_FAILURE);
283 } 209 }
284 else 210 else
285 continue; 211 continue;
286 } 212 }
287 213
288 len = recvfrom(fd, vss_recv_buffer, vss_recv_buffer_len, 0, 214 len = read(vss_fd, vss_msg, sizeof(struct hv_vss_msg));
289 addr_p, &addr_l);
290 215
291 if (len < 0) { 216 if (in_handshake) {
292 syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s", 217 if (len != sizeof(kernel_modver)) {
293 addr.nl_pid, errno, strerror(errno)); 218 syslog(LOG_ERR, "invalid version negotiation");
294 close(fd); 219 exit(EXIT_FAILURE);
295 return -1; 220 }
296 } 221 kernel_modver = *(__u32 *)vss_msg;
297 222 in_handshake = 0;
298 if (addr.nl_pid) { 223 syslog(LOG_INFO, "VSS: kernel module version: %d",
299 syslog(LOG_WARNING, 224 kernel_modver);
300 "Received packet from untrusted pid:%u",
301 addr.nl_pid);
302 continue; 225 continue;
303 } 226 }
304 227
305 incoming_msg = (struct nlmsghdr *)vss_recv_buffer; 228 if (len != sizeof(struct hv_vss_msg)) {
306 229 syslog(LOG_ERR, "read failed; error:%d %s",
307 if (incoming_msg->nlmsg_type != NLMSG_DONE) 230 errno, strerror(errno));
308 continue; 231 close(vss_fd);
232 return EXIT_FAILURE;
233 }
309 234
310 incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg);
311 vss_msg = (struct hv_vss_msg *)incoming_cn_msg->data;
312 op = vss_msg->vss_hdr.operation; 235 op = vss_msg->vss_hdr.operation;
313 error = HV_S_OK; 236 error = HV_S_OK;
314 237
@@ -331,12 +254,14 @@ int main(int argc, char *argv[])
331 syslog(LOG_ERR, "Illegal op:%d\n", op); 254 syslog(LOG_ERR, "Illegal op:%d\n", op);
332 } 255 }
333 vss_msg->error = error; 256 vss_msg->error = error;
334 len = netlink_send(fd, incoming_cn_msg); 257 len = write(vss_fd, &error, sizeof(struct hv_vss_msg));
335 if (len < 0) { 258 if (len != sizeof(struct hv_vss_msg)) {
336 syslog(LOG_ERR, "net_link send failed; error:%d %s", 259 syslog(LOG_ERR, "write failed; error: %d %s", errno,
337 errno, strerror(errno)); 260 strerror(errno));
338 exit(EXIT_FAILURE); 261 exit(EXIT_FAILURE);
339 } 262 }
340 } 263 }
341 264
265 close(vss_fd);
266 exit(0);
342} 267}