debuggers.hg

view tools/blktap2/control/tap-ctl-ipc.c @ 22848:6341fe0f4e5a

Added tag 4.1.0-rc2 for changeset 9dca60d88c63
author Keir Fraser <keir@xen.org>
date Tue Jan 25 14:06:55 2011 +0000 (2011-01-25)
parents 63d0f5348af2
children
line source
1 /*
2 * Copyright (c) 2008, XenSource Inc.
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 are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of XenSource Inc. nor the names of its contributors
13 * may be used to endorse or promote products derived from this software
14 * without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 #include <stdio.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <sys/un.h>
34 #include <sys/stat.h>
35 #include <sys/types.h>
36 #include <sys/socket.h>
38 #include "tap-ctl.h"
39 #include "blktap2.h"
41 int tap_ctl_debug = 0;
43 int
44 tap_ctl_read_message(int fd, tapdisk_message_t *message, int timeout)
45 {
46 fd_set readfds;
47 int ret, len, offset;
48 struct timeval tv, *t;
50 t = NULL;
51 offset = 0;
52 len = sizeof(tapdisk_message_t);
54 if (timeout) {
55 tv.tv_sec = timeout;
56 tv.tv_usec = 0;
57 t = &tv;
58 }
60 memset(message, 0, sizeof(tapdisk_message_t));
62 while (offset < len) {
63 FD_ZERO(&readfds);
64 FD_SET(fd, &readfds);
66 ret = select(fd + 1, &readfds, NULL, NULL, t);
67 if (ret == -1)
68 break;
69 else if (FD_ISSET(fd, &readfds)) {
70 ret = read(fd, message + offset, len - offset);
71 if (ret <= 0)
72 break;
73 offset += ret;
74 } else
75 break;
76 }
78 if (offset != len) {
79 EPRINTF("failure reading message\n");
80 return -EIO;
81 }
83 DBG("received '%s' message (uuid = %u)\n",
84 tapdisk_message_name(message->type), message->cookie);
86 return 0;
87 }
89 int
90 tap_ctl_write_message(int fd, tapdisk_message_t *message, int timeout)
91 {
92 fd_set writefds;
93 int ret, len, offset;
94 struct timeval tv, *t;
96 t = NULL;
97 offset = 0;
98 len = sizeof(tapdisk_message_t);
100 if (timeout) {
101 tv.tv_sec = timeout;
102 tv.tv_usec = 0;
103 t = &tv;
104 }
106 DBG("sending '%s' message (uuid = %u)\n",
107 tapdisk_message_name(message->type), message->cookie);
109 while (offset < len) {
110 FD_ZERO(&writefds);
111 FD_SET(fd, &writefds);
113 /* we don't bother reinitializing tv. at worst, it will wait a
114 * bit more time than expected. */
116 ret = select(fd + 1, NULL, &writefds, NULL, t);
117 if (ret == -1)
118 break;
119 else if (FD_ISSET(fd, &writefds)) {
120 ret = write(fd, message + offset, len - offset);
121 if (ret <= 0)
122 break;
123 offset += ret;
124 } else
125 break;
126 }
128 if (offset != len) {
129 EPRINTF("failure writing message\n");
130 return -EIO;
131 }
133 return 0;
134 }
136 int
137 tap_ctl_send_and_receive(int sfd, tapdisk_message_t *message, int timeout)
138 {
139 int err;
141 err = tap_ctl_write_message(sfd, message, timeout);
142 if (err) {
143 EPRINTF("failed to send '%s' message\n",
144 tapdisk_message_name(message->type));
145 return err;
146 }
148 err = tap_ctl_read_message(sfd, message, timeout);
149 if (err) {
150 EPRINTF("failed to receive '%s' message\n",
151 tapdisk_message_name(message->type));
152 return err;
153 }
155 return 0;
156 }
158 char *
159 tap_ctl_socket_name(int id)
160 {
161 char *name;
163 if (asprintf(&name, "%s/%s%d",
164 BLKTAP2_CONTROL_DIR, BLKTAP2_CONTROL_SOCKET, id) == -1)
165 return NULL;
167 return name;
168 }
170 int
171 tap_ctl_connect(const char *name, int *sfd)
172 {
173 int fd, err;
174 struct sockaddr_un saddr;
176 *sfd = -1;
178 fd = socket(AF_UNIX, SOCK_STREAM, 0);
179 if (fd == -1) {
180 EPRINTF("couldn't create socket for %s: %d\n", name, errno);
181 return -errno;
182 }
184 memset(&saddr, 0, sizeof(saddr));
185 saddr.sun_family = AF_UNIX;
186 strcpy(saddr.sun_path, name);
188 err = connect(fd, (const struct sockaddr *)&saddr, sizeof(saddr));
189 if (err) {
190 EPRINTF("couldn't connect to %s: %d\n", name, errno);
191 close(fd);
192 return -errno;
193 }
195 *sfd = fd;
196 return 0;
197 }
199 int
200 tap_ctl_connect_id(int id, int *sfd)
201 {
202 int err;
203 char *name;
205 *sfd = -1;
207 if (id < 0) {
208 EPRINTF("invalid id %d\n", id);
209 return -EINVAL;
210 }
212 name = tap_ctl_socket_name(id);
213 if (!name) {
214 EPRINTF("couldn't name socket for %d\n", id);
215 return -ENOMEM;
216 }
218 err = tap_ctl_connect(name, sfd);
219 free(name);
221 return err;
222 }
224 int
225 tap_ctl_connect_send_and_receive(int id, tapdisk_message_t *message, int timeout)
226 {
227 int err, sfd;
229 err = tap_ctl_connect_id(id, &sfd);
230 if (err)
231 return err;
233 err = tap_ctl_send_and_receive(sfd, message, timeout);
235 close(sfd);
236 return err;
237 }