diff options
Diffstat (limited to 'tools/hv/hv_vss_daemon.c')
-rw-r--r-- | tools/hv/hv_vss_daemon.c | 59 |
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 | ||
41 | static char vss_recv_buffer[4096]; | ||
42 | static char vss_send_buffer[4096]; | ||
43 | static struct sockaddr_nl addr; | 41 | static 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 | ||
108 | static int netlink_send(int fd, struct cn_msg *msg) | 106 | static 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 | } |