]>
Commit | Line | Data |
---|---|---|
cdd964e9 MT |
1 | diff --git a/usr/Makefile b/usr/Makefile |
2 | index e9d6bd1..8e505bf 100644 | |
3 | --- a/usr/Makefile | |
4 | +++ b/usr/Makefile | |
5 | @@ -42,7 +42,7 @@ ISCSI_LIB_SRCS = iscsi_util.o io.o auth.o login.o log.o md5.o sha1.o iface.o \ | |
6 | iscsid_req.o $(SYSDEPS_SRCS) | |
7 | # core initiator files | |
8 | INITIATOR_SRCS = initiator.o scsi.o actor.o event_poll.o mgmt_ipc.o \ | |
9 | - transport.o cxgb3i.o be2iscsi.o | |
10 | + transport.o cxgb3i.o be2iscsi.o uip_mgmt_ipc.o | |
11 | # fw boot files | |
12 | FW_BOOT_SRCS = $(wildcard ../utils/fwparam_ibft/*.o) | |
13 | ||
14 | diff --git a/usr/initiator.c b/usr/initiator.c | |
15 | index 1c9d8b6..8f7a383 100644 | |
16 | --- a/usr/initiator.c | |
17 | +++ b/usr/initiator.c | |
18 | @@ -45,6 +45,7 @@ | |
19 | #include "iscsi_sysfs.h" | |
20 | #include "iscsi_settings.h" | |
21 | #include "iface.h" | |
22 | +#include "host.h" | |
23 | #include "sysdeps.h" | |
24 | ||
25 | #define ISCSI_CONN_ERR_REOPEN_DELAY 3 | |
26 | @@ -743,6 +744,38 @@ static int iscsi_conn_connect(struct iscsi_conn *conn, queue_task_t *qtask) | |
27 | return 0; | |
28 | } | |
29 | ||
30 | +static int __set_net_config(struct iscsi_transport *t, | |
31 | + iscsi_session_t *session, | |
32 | + struct iface_rec *iface) | |
33 | +{ | |
34 | + if (t->template->set_net_config) { | |
35 | + /* uip needs the netdev name */ | |
36 | + struct host_info hinfo; | |
37 | + int hostno, rc; | |
38 | + | |
39 | + /* this assumes that the netdev or hw address is going to be | |
40 | + set */ | |
41 | + hostno = iscsi_sysfs_get_host_no_from_hwinfo(iface, &rc); | |
42 | + if (rc) { | |
43 | + log_debug(4, "Couldn't get host no.\n"); | |
44 | + return rc; | |
45 | + } | |
46 | + | |
47 | + /* uip needs the netdev name */ | |
48 | + if (!strlen(iface->netdev)) { | |
49 | + memset(&hinfo, 0, sizeof(hinfo)); | |
50 | + hinfo.host_no = hostno; | |
51 | + iscsi_sysfs_get_hostinfo_by_host_no(&hinfo); | |
52 | + strcpy(iface->netdev, hinfo.iface.netdev); | |
53 | + } | |
54 | + | |
55 | + return t->template->set_net_config(t, iface, session); | |
56 | + } | |
57 | + | |
58 | + return 0; | |
59 | +} | |
60 | + | |
61 | + | |
62 | static void | |
63 | __session_conn_reopen(iscsi_conn_t *conn, queue_task_t *qtask, int do_stop, | |
64 | int redirected) | |
65 | @@ -784,6 +817,11 @@ __session_conn_reopen(iscsi_conn_t *conn, queue_task_t *qtask, int do_stop, | |
66 | if (!redirected) | |
67 | session->reopen_cnt++; | |
68 | ||
69 | + /* uIP will needs to be re-triggered on the connection re-open */ | |
70 | + if (__set_net_config(conn->session->t, conn->session, | |
71 | + &conn->session->nrec.iface) != 0) | |
72 | + goto queue_reopen; | |
73 | + | |
74 | if (iscsi_conn_connect(conn, qtask)) { | |
75 | delay = ISCSI_CONN_ERR_REOPEN_DELAY; | |
76 | goto queue_reopen; | |
77 | @@ -2130,6 +2168,10 @@ static int iface_set_param(struct iscsi_transport *t, struct iface_rec *iface, | |
78 | return EINVAL; | |
79 | } | |
80 | ||
81 | + rc = __set_net_config(t, session, iface); | |
82 | + if (rc != 0) | |
83 | + return rc; | |
84 | + | |
85 | rc = __iscsi_host_set_param(t, session->hostno, | |
86 | ISCSI_HOST_PARAM_IPADDRESS, | |
87 | iface->ipaddress, ISCSI_STRING); | |
88 | diff --git a/usr/iscsid_req.c b/usr/iscsid_req.c | |
89 | index 5280a0a..6eb8b1d 100644 | |
90 | --- a/usr/iscsid_req.c | |
91 | +++ b/usr/iscsid_req.c | |
92 | @@ -22,6 +22,7 @@ | |
93 | #include <stdlib.h> | |
94 | #include <string.h> | |
95 | #include <errno.h> | |
96 | +#include <fcntl.h> | |
97 | #include <sys/un.h> | |
98 | #include <sys/types.h> | |
99 | #include <sys/socket.h> | |
100 | @@ -31,6 +32,7 @@ | |
101 | #include "mgmt_ipc.h" | |
102 | #include "iscsi_util.h" | |
103 | #include "config.h" | |
104 | +#include "uip_mgmt_ipc.h" | |
105 | ||
106 | static void iscsid_startup(void) | |
107 | { | |
108 | @@ -51,7 +53,8 @@ static void iscsid_startup(void) | |
109 | ||
110 | #define MAXSLEEP 128 | |
111 | ||
112 | -static mgmt_ipc_err_e iscsid_connect(int *fd, int start_iscsid) | |
113 | +static mgmt_ipc_err_e ipc_connect(int *fd, char *unix_sock_name, | |
114 | + int start_iscsid) | |
115 | { | |
116 | int nsec; | |
117 | struct sockaddr_un addr; | |
118 | @@ -64,8 +67,8 @@ static mgmt_ipc_err_e iscsid_connect(int *fd, int start_iscsid) | |
119 | ||
120 | memset(&addr, 0, sizeof(addr)); | |
121 | addr.sun_family = AF_LOCAL; | |
122 | - memcpy((char *) &addr.sun_path + 1, ISCSIADM_NAMESPACE, | |
123 | - strlen(ISCSIADM_NAMESPACE)); | |
124 | + memcpy((char *) &addr.sun_path + 1, unix_sock_name, | |
125 | + strlen(unix_sock_name)); | |
126 | /* | |
127 | * Trying to connect with exponential backoff | |
128 | */ | |
129 | @@ -93,6 +96,11 @@ static mgmt_ipc_err_e iscsid_connect(int *fd, int start_iscsid) | |
130 | return MGMT_IPC_ERR_ISCSID_NOTCONN; | |
131 | } | |
132 | ||
133 | +static mgmt_ipc_err_e iscsid_connect(int *fd, int start_iscsid) | |
134 | +{ | |
135 | + return ipc_connect(fd, ISCSIADM_NAMESPACE, start_iscsid); | |
136 | +} | |
137 | + | |
138 | mgmt_ipc_err_e iscsid_request(int *fd, iscsiadm_req_t *req, int start_iscsid) | |
139 | { | |
140 | int err; | |
141 | @@ -190,6 +198,72 @@ int iscsid_req_by_sid(iscsiadm_cmd_e cmd, int sid) | |
142 | return iscsid_req_wait(cmd, fd); | |
143 | } | |
144 | ||
145 | +static mgmt_ipc_err_e uip_connect(int *fd) | |
146 | +{ | |
147 | + return ipc_connect(fd, ISCSID_UIP_NAMESPACE, 0); | |
148 | +} | |
149 | + | |
150 | +int uip_broadcast(void *buf, size_t buf_len) | |
151 | +{ | |
152 | + int err; | |
153 | + int fd; | |
154 | + iscsid_uip_rsp_t rsp; | |
155 | + int flags; | |
156 | + int count; | |
157 | + | |
158 | + err = uip_connect(&fd); | |
159 | + if (err) { | |
160 | + log_warning("uIP daemon is not up"); | |
161 | + return err; | |
162 | + } | |
163 | + | |
164 | + /* Send the data to uIP */ | |
165 | + if ((err = write(fd, buf, buf_len)) != buf_len) { | |
166 | + log_error("got write error (%d/%d), daemon died?", | |
167 | + err, errno); | |
168 | + close(fd); | |
169 | + return -EIO; | |
170 | + } | |
171 | + | |
172 | + /* Set the socket to a non-blocking read, this way if there are | |
173 | + * problems waiting for uIP, iscsid can bailout early */ | |
174 | + flags = fcntl(fd, F_GETFL, 0); | |
175 | + if (flags == -1) | |
176 | + flags = 0; | |
177 | + err = fcntl(fd, F_SETFL, flags | O_NONBLOCK); | |
178 | + if(err != 0) { | |
179 | + log_error("could not set uip broadcast to non-blocking: %d", | |
180 | + errno); | |
181 | + close(fd); | |
182 | + return -EIO; | |
183 | + } | |
184 | + | |
185 | +#define MAX_UIP_BROADCAST_READ_TRIES 3 | |
186 | + for(count = 0; count < MAX_UIP_BROADCAST_READ_TRIES; count++) { | |
187 | + /* Wait for the response */ | |
188 | + err = read(fd, &rsp, sizeof(rsp)); | |
189 | + if (err == sizeof(rsp)) { | |
190 | + log_debug(3, "Broadcasted to uIP with length: %ld\n", | |
191 | + buf_len); | |
192 | + break; | |
193 | + } else if((err == -1) && (errno == EAGAIN)) { | |
194 | + usleep(250000); | |
195 | + continue; | |
196 | + } else { | |
197 | + log_error("Could not read response (%d/%d), daemon died?", | |
198 | + err, errno); | |
199 | + break; | |
200 | + } | |
201 | + } | |
202 | + | |
203 | + if(count == MAX_UIP_BROADCAST_READ_TRIES) | |
204 | + log_error("Could not broadcast to uIP"); | |
205 | + | |
206 | + close(fd); | |
207 | + | |
208 | + return 0; | |
209 | +} | |
210 | + | |
211 | void iscsid_handle_error(mgmt_ipc_err_e err) | |
212 | { | |
213 | static char *err_msgs[] = { | |
214 | diff --git a/usr/iscsid_req.h b/usr/iscsid_req.h | |
215 | index 3bba2f4..e2cf1c3 100644 | |
216 | --- a/usr/iscsid_req.h | |
217 | +++ b/usr/iscsid_req.h | |
218 | @@ -34,4 +34,6 @@ extern int iscsid_req_by_rec(int cmd, struct node_rec *rec); | |
219 | extern int iscsid_req_by_sid_async(int cmd, int sid, int *fd); | |
220 | extern int iscsid_req_by_sid(int cmd, int sid); | |
221 | ||
222 | +extern int uip_broadcast(void *buf, size_t buf_len); | |
223 | + | |
224 | #endif | |
225 | diff --git a/usr/transport.c b/usr/transport.c | |
226 | index c0789bb..aa0395c 100644 | |
227 | --- a/usr/transport.c | |
228 | +++ b/usr/transport.c | |
229 | @@ -25,6 +25,7 @@ | |
230 | #include "log.h" | |
231 | #include "iscsi_util.h" | |
232 | #include "iscsi_sysfs.h" | |
233 | +#include "uip_mgmt_ipc.h" | |
234 | #include "cxgb3i.h" | |
235 | #include "be2iscsi.h" | |
236 | ||
237 | @@ -58,6 +59,7 @@ struct iscsi_transport_template bnx2i = { | |
238 | .ep_connect = ktransport_ep_connect, | |
239 | .ep_poll = ktransport_ep_poll, | |
240 | .ep_disconnect = ktransport_ep_disconnect, | |
241 | + .set_net_config = uip_broadcast_params, | |
242 | }; | |
243 | ||
244 | struct iscsi_transport_template be2iscsi = { | |
245 | diff --git a/usr/transport.h b/usr/transport.h | |
246 | index 5ceedb3..2ec903c 100644 | |
247 | --- a/usr/transport.h | |
248 | +++ b/usr/transport.h | |
249 | @@ -35,6 +35,9 @@ struct iscsi_transport_template { | |
250 | int (*ep_poll) (struct iscsi_conn *conn, int timeout_ms); | |
251 | void (*ep_disconnect) (struct iscsi_conn *conn); | |
252 | void (*create_conn) (struct iscsi_conn *conn); | |
253 | + int (*set_net_config) (struct iscsi_transport *t, | |
254 | + struct iface_rec *iface, | |
255 | + struct iscsi_session *session); | |
256 | }; | |
257 | ||
258 | /* represents data path provider */ | |
259 | diff --git a/usr/uip_mgmt_ipc.c b/usr/uip_mgmt_ipc.c | |
260 | new file mode 100644 | |
261 | index 0000000..73b1632 | |
262 | --- /dev/null | |
263 | +++ b/usr/uip_mgmt_ipc.c | |
264 | @@ -0,0 +1,41 @@ | |
265 | +/* | |
266 | + * uIP iSCSI Daemon/Admin Management IPC | |
267 | + * | |
268 | + * This program is free software; you can redistribute it and/or modify | |
269 | + * it under the terms of the GNU General Public License as published | |
270 | + * by the Free Software Foundation; either version 2 of the License, or | |
271 | + * (at your option) any later version. | |
272 | + * | |
273 | + * This program is distributed in the hope that it will be useful, but | |
274 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | |
275 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
276 | + * General Public License for more details. | |
277 | + * | |
278 | + * See the file COPYING included with this distribution for more details. | |
279 | + */ | |
280 | + | |
281 | +#include <string.h> | |
282 | + | |
283 | +#include "log.h" | |
284 | +#include "uip_mgmt_ipc.h" | |
285 | +#include "iscsid_req.h" | |
286 | + | |
287 | +int uip_broadcast_params(struct iscsi_transport *t, | |
288 | + struct iface_rec *iface, | |
289 | + struct iscsi_session *session) | |
290 | +{ | |
291 | + struct iscsid_uip_broadcast broadcast; | |
292 | + | |
293 | + log_debug(3, "broadcasting to uip\n"); | |
294 | + | |
295 | + memset(&broadcast, 0, sizeof(broadcast)); | |
296 | + | |
297 | + broadcast.header.command = ISCSID_UIP_IPC_GET_IFACE; | |
298 | + broadcast.header.payload_len = sizeof(*iface); | |
299 | + | |
300 | + memcpy(&broadcast.u.iface_rec, iface, sizeof(*iface)); | |
301 | + | |
302 | + return uip_broadcast(&broadcast, | |
303 | + sizeof(iscsid_uip_broadcast_header_t) + | |
304 | + sizeof(*iface)); | |
305 | +} | |
306 | diff --git a/usr/uip_mgmt_ipc.h b/usr/uip_mgmt_ipc.h | |
307 | new file mode 100644 | |
308 | index 0000000..dd49c0b | |
309 | --- /dev/null | |
310 | +++ b/usr/uip_mgmt_ipc.h | |
311 | @@ -0,0 +1,71 @@ | |
312 | +/* | |
313 | + * uIP iSCSI Daemon/Admin Management IPC | |
314 | + * | |
315 | + * This program is free software; you can redistribute it and/or modify | |
316 | + * it under the terms of the GNU General Public License as published | |
317 | + * by the Free Software Foundation; either version 2 of the License, or | |
318 | + * (at your option) any later version. | |
319 | + * | |
320 | + * This program is distributed in the hope that it will be useful, but | |
321 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | |
322 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
323 | + * General Public License for more details. | |
324 | + * | |
325 | + * See the file COPYING included with this distribution for more details. | |
326 | + */ | |
327 | +#ifndef UIP_MGMT_IPC_H | |
328 | +#define UIP_MGMT_IPC_H | |
329 | + | |
330 | +#include "types.h" | |
331 | +#include "iscsi_if.h" | |
332 | +#include "config.h" | |
333 | +#include "mgmt_ipc.h" | |
334 | + | |
335 | +#include "initiator.h" | |
336 | +#include "transport.h" | |
337 | + | |
338 | +#define ISCSID_UIP_NAMESPACE "ISCSID_UIP_ABSTRACT_NAMESPACE" | |
339 | + | |
340 | +typedef enum iscsid_uip_cmd { | |
341 | + ISCSID_UIP_IPC_UNKNOWN = 0, | |
342 | + ISCSID_UIP_IPC_GET_IFACE = 1, | |
343 | + | |
344 | + __ISCSID_UIP_IPC_MAX_COMMAND | |
345 | +} iscsid_uip_cmd_e; | |
346 | + | |
347 | +typedef struct iscsid_uip_broadcast_header { | |
348 | + iscsid_uip_cmd_e command; | |
349 | + uint32_t payload_len; | |
350 | +} iscsid_uip_broadcast_header_t; | |
351 | + | |
352 | +/* IPC Request */ | |
353 | +typedef struct iscsid_uip_broadcast { | |
354 | + struct iscsid_uip_broadcast_header header; | |
355 | + | |
356 | + union { | |
357 | + /* messages */ | |
358 | + struct ipc_broadcast_iface_rec { | |
359 | + struct iface_rec rec; | |
360 | + } iface_rec; | |
361 | + } u; | |
362 | +} iscsid_uip_broadcast_t; | |
363 | + | |
364 | +typedef enum iscsid_uip_mgmt_ipc_err { | |
365 | + ISCSID_UIP_MGMT_IPC_OK = 0, | |
366 | + ISCISD_UIP_MGMT_IPC_ERR = 1, | |
367 | + ISCISD_UIP_MGMT_IPC_ERR_NOT_FOUND = 2, | |
368 | + ISCISD_UIP_MGMT_IPC_ERR_NOMEM = 3, | |
369 | +} iscsid_uip_mgmt_ipc_err_e; | |
370 | + | |
371 | +/* IPC Response */ | |
372 | +typedef struct iscsid_uip_mgmt_rsp { | |
373 | + iscsid_uip_cmd_e command; | |
374 | + iscsid_uip_mgmt_ipc_err_e err; | |
375 | +} iscsid_uip_rsp_t; | |
376 | + | |
377 | +extern int uip_broadcast_params(struct iscsi_transport *t, | |
378 | + struct iface_rec *iface, | |
379 | + struct iscsi_session *session); | |
380 | + | |
381 | + | |
382 | +#endif /* UIP_MGMT_IPC_H */ | |
383 | -- | |
384 | 1.6.6.1 | |
385 |