aboutsummaryrefslogtreecommitdiffstats
path: root/tools/hv/hv_vss_daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/hv/hv_vss_daemon.c')
-rw-r--r--tools/hv/hv_vss_daemon.c59
1 files changed, 39 insertions, 20 deletions
diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c
index fea03a3edaf4..8611962c672c 100644
--- a/tools/hv/hv_vss_daemon.c
+++ b/tools/hv/hv_vss_daemon.c
@@ -38,8 +38,6 @@
38#include <linux/netlink.h> 38#include <linux/netlink.h>
39#include <syslog.h> 39#include <syslog.h>
40 40
41static char vss_recv_buffer[4096];
42static char vss_send_buffer[4096];
43static struct sockaddr_nl addr; 41static struct sockaddr_nl addr;
44 42
45#ifndef SOL_NETLINK 43#ifndef SOL_NETLINK
@@ -107,23 +105,18 @@ static int vss_operate(int operation)
107 105
108static int netlink_send(int fd, struct cn_msg *msg) 106static int netlink_send(int fd, struct cn_msg *msg)
109{ 107{
110 struct nlmsghdr *nlh; 108 struct nlmsghdr nlh = { .nlmsg_type = NLMSG_DONE };
111 unsigned int size; 109 unsigned int size;
112 struct msghdr message; 110 struct msghdr message;
113 char buffer[64];
114 struct iovec iov[2]; 111 struct iovec iov[2];
115 112
116 size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len); 113 size = sizeof(struct cn_msg) + msg->len;
117 114
118 nlh = (struct nlmsghdr *)buffer; 115 nlh.nlmsg_pid = getpid();
119 nlh->nlmsg_seq = 0; 116 nlh.nlmsg_len = NLMSG_LENGTH(size);
120 nlh->nlmsg_pid = getpid();
121 nlh->nlmsg_type = NLMSG_DONE;
122 nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(*nlh));
123 nlh->nlmsg_flags = 0;
124 117
125 iov[0].iov_base = nlh; 118 iov[0].iov_base = &nlh;
126 iov[0].iov_len = sizeof(*nlh); 119 iov[0].iov_len = sizeof(nlh);
127 120
128 iov[1].iov_base = msg; 121 iov[1].iov_base = msg;
129 iov[1].iov_len = size; 122 iov[1].iov_len = size;
@@ -147,6 +140,9 @@ int main(void)
147 struct cn_msg *incoming_cn_msg; 140 struct cn_msg *incoming_cn_msg;
148 int op; 141 int op;
149 struct hv_vss_msg *vss_msg; 142 struct hv_vss_msg *vss_msg;
143 char *vss_send_buffer;
144 char *vss_recv_buffer;
145 size_t vss_recv_buffer_len;
150 146
151 if (daemon(1, 0)) 147 if (daemon(1, 0))
152 return 1; 148 return 1;
@@ -154,9 +150,18 @@ int main(void)
154 openlog("Hyper-V VSS", 0, LOG_USER); 150 openlog("Hyper-V VSS", 0, LOG_USER);
155 syslog(LOG_INFO, "VSS starting; pid is:%d", getpid()); 151 syslog(LOG_INFO, "VSS starting; pid is:%d", getpid());
156 152
153 vss_recv_buffer_len = NLMSG_HDRLEN + sizeof(struct cn_msg) + sizeof(struct hv_vss_msg);
154 vss_send_buffer = calloc(1, vss_recv_buffer_len);
155 vss_recv_buffer = calloc(1, vss_recv_buffer_len);
156 if (!(vss_send_buffer && vss_recv_buffer)) {
157 syslog(LOG_ERR, "Failed to allocate netlink buffers");
158 exit(EXIT_FAILURE);
159 }
160
157 fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR); 161 fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
158 if (fd < 0) { 162 if (fd < 0) {
159 syslog(LOG_ERR, "netlink socket creation failed; error:%d", fd); 163 syslog(LOG_ERR, "netlink socket creation failed; error:%d %s",
164 errno, strerror(errno));
160 exit(EXIT_FAILURE); 165 exit(EXIT_FAILURE);
161 } 166 }
162 addr.nl_family = AF_NETLINK; 167 addr.nl_family = AF_NETLINK;
@@ -167,12 +172,16 @@ int main(void)
167 172
168 error = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); 173 error = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
169 if (error < 0) { 174 if (error < 0) {
170 syslog(LOG_ERR, "bind failed; error:%d", error); 175 syslog(LOG_ERR, "bind failed; error:%d %s", errno, strerror(errno));
171 close(fd); 176 close(fd);
172 exit(EXIT_FAILURE); 177 exit(EXIT_FAILURE);
173 } 178 }
174 nl_group = CN_VSS_IDX; 179 nl_group = CN_VSS_IDX;
175 setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &nl_group, sizeof(nl_group)); 180 if (setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &nl_group, sizeof(nl_group)) < 0) {
181 syslog(LOG_ERR, "setsockopt failed; error:%d %s", errno, strerror(errno));
182 close(fd);
183 exit(EXIT_FAILURE);
184 }
176 /* 185 /*
177 * Register ourselves with the kernel. 186 * Register ourselves with the kernel.
178 */ 187 */
@@ -187,7 +196,7 @@ int main(void)
187 196
188 len = netlink_send(fd, message); 197 len = netlink_send(fd, message);
189 if (len < 0) { 198 if (len < 0) {
190 syslog(LOG_ERR, "netlink_send failed; error:%d", len); 199 syslog(LOG_ERR, "netlink_send failed; error:%d %s", errno, strerror(errno));
191 close(fd); 200 close(fd);
192 exit(EXIT_FAILURE); 201 exit(EXIT_FAILURE);
193 } 202 }
@@ -199,9 +208,18 @@ int main(void)
199 socklen_t addr_l = sizeof(addr); 208 socklen_t addr_l = sizeof(addr);
200 pfd.events = POLLIN; 209 pfd.events = POLLIN;
201 pfd.revents = 0; 210 pfd.revents = 0;
202 poll(&pfd, 1, -1);
203 211
204 len = recvfrom(fd, vss_recv_buffer, sizeof(vss_recv_buffer), 0, 212 if (poll(&pfd, 1, -1) < 0) {
213 syslog(LOG_ERR, "poll failed; error:%d %s", errno, strerror(errno));
214 if (errno == EINVAL) {
215 close(fd);
216 exit(EXIT_FAILURE);
217 }
218 else
219 continue;
220 }
221
222 len = recvfrom(fd, vss_recv_buffer, vss_recv_buffer_len, 0,
205 addr_p, &addr_l); 223 addr_p, &addr_l);
206 224
207 if (len < 0) { 225 if (len < 0) {
@@ -241,7 +259,8 @@ int main(void)
241 vss_msg->error = error; 259 vss_msg->error = error;
242 len = netlink_send(fd, incoming_cn_msg); 260 len = netlink_send(fd, incoming_cn_msg);
243 if (len < 0) { 261 if (len < 0) {
244 syslog(LOG_ERR, "net_link send failed; error:%d", len); 262 syslog(LOG_ERR, "net_link send failed; error:%d %s",
263 errno, strerror(errno));
245 exit(EXIT_FAILURE); 264 exit(EXIT_FAILURE);
246 } 265 }
247 } 266 }