64
68
{"mode", required_argument, NULL, 'm'},
65
69
{"portal", required_argument, NULL, 'p'},
70
{"targetname", required_argument, NULL, 'T'},
66
71
{"op", required_argument, NULL, 'o'},
67
72
{"type", required_argument, NULL, 't'},
68
73
{"name", required_argument, NULL, 'n'},
69
74
{"value", required_argument, NULL, 'v'},
70
{"record", required_argument, NULL, 'r'},
75
{"sid", required_argument, NULL, 'r'},
71
76
{"login", no_argument, NULL, 'l'},
77
{"loginall", required_argument, NULL, 'L'},
72
78
{"logout", no_argument, NULL, 'u'},
79
{"logoutall", required_argument, NULL, 'U'},
73
80
{"stats", no_argument, NULL, 's'},
74
81
{"debug", required_argument, NULL, 'g'},
82
{"map", required_argument, NULL, 'M'},
83
{"show", no_argument, NULL, 'S'},
75
84
{"version", no_argument, NULL, 'V'},
76
85
{"help", no_argument, NULL, 'h'},
77
86
{NULL, 0, NULL, 0},
79
static char *short_options = "lVhm:p:d:r:n:v:o:t:u";
88
static char *short_options = "lVhm:M:p:T:U:L:d:r:n:v:o:sSt:u";
81
90
static void usage(int status)
84
93
fprintf(stderr, "Try `%s --help' for more information.\n",
87
printf("Usage: %s [OPTION]\n", program_name);
89
iSCSI Administration Utility.\n\
91
-m, --mode <op> specify operational mode op = <discovery|node>\n\
92
-m discovery --type=[type] --portal=[ip[:port]] --login\n\
93
perform [type] discovery for target portal with\n\
94
ip-address [ip] and port [port]. Initiate Login for\n\
95
each discovered target if --login is specified\n\
96
-m discovery display all discovery records from internal\n\
97
persistent discovery database\n\
98
-m discovery --record=[id] --login\n\
99
perform discovery based on record [id] in database\n\
100
-m discovery --record=[id] --op=[op] [--name=[name] --value=[value]]\n\
101
perform specific DB operation [op] for specific\n\
102
discovery record with [id]. It could be one of:\n\
103
[new], [delete], [update] or [show]. In case of\n\
104
[update], you have to provide [name] and [value]\n\
105
you wish to update\n\
106
-m node display all discovered nodes from internal\n\
107
persistent discovery database\n\
108
-m node --record=[id] [--login|--logout]\n\
109
-m node --record=[id] --op=[op] [--name=[name] --value=[value]] [--portal]\n\
110
perform specific DB operation [op] for specific\n\
111
node with record [id]. It could be one of:\n\
112
[new], [delete], [update] or [show]. In case of\n\
113
[update], you have to provide [name] and [value]\n\
114
you wish to update. For new record portal must be\n\
116
-m session display all active sessions and connections\n\
117
-m session --record=[id[:cid]] [--logout|--stats]\n\
118
perform operation for specific session with\n\
119
record [id] or display negotiated parameters if\n\
120
no operation specified. Operation will affect \n\
121
one connection only if [:cid] is specified\n\
122
-d, --debug debuglevel print debugging information\n\
123
-V, --version display version and exit\n\
124
-h, --help display this help and exit\n\
127
Open-iSCSI Team.\n");
97
iscsiadm -m discovery [ -dhV ] [ -t type -p ip:port [ -l ] ] | [ -p ip:port ] \
98
[ -o operation ] [ -n name ] [ -v value ]\n\
99
iscsiadm -m node [ -dhV ] [ -L all,manual,automatic ] [ -U all,manual,automatic ] [ -S ] [ [ -T targetname -p ip:port | -M sysdir ] [ -l | -u ] ] \
100
[ [ -o operation ] [ -n name ] [ -v value ] [ -p ip:port ] ]\n\
101
iscsiadm -m session [ -dhV ] [ -r sessionid [ -u | -s ] ]\n");
130
103
exit(status == 0 ? 0 : -1);
188
str_to_ipport(char *str, int *port)
192
if (!strchr(str, '.')) {
194
if (!(sport = strchr(str, ']')))
202
if (sport && (sport = strchr(sport, ':'))) {
205
*port = strtoul(sport, NULL, 10);
207
*port = DEF_ISCSI_PORT;
213
str_to_ridsid(char *str, int *sid)
161
sys_to_rec(idbm_t *db, node_rec_t *rec, char *sysfs_device)
218
if ((ptr = strchr(str, ':'))) {
221
*sid = strtoul(str, &eptr, 10);
165
int sid, rc, port, tpgt, len;
167
char sys_session[64], *start, *last;
170
* Given sysfs_device is a directory name of the form:
172
* /sys/devices/platform/hostH/sessionS/targetH:B:I/H:B:I:L
173
* /sys/devices/platform/hostH/sessionS/targetH:B:I
174
* /sys/devices/platform/hostH/sessionS
176
* We want to set sys_session to sessionS
178
if (stat(sysfs_device, &statb)) {
179
log_error("stat %s failed with %d", sysfs_device, errno);
182
if (!S_ISDIR(statb.st_mode)) {
183
log_error("%s is not a directory", sysfs_device);
188
start = strstr(sysfs_device, "session");
189
if (start && strncmp(start, "session", 7) == 0) {
191
last = index(start, '/');
193
* If '/' not found last is NULL.
197
strncpy(sys_session, start, len);
229
rid = strtoul(ptr, &eptr, 16);
239
struct sockaddr_un addr;
241
fd = socket(AF_LOCAL, SOCK_STREAM, 0);
243
log_error("can not create IPC socket!");
247
memset(&addr, 0, sizeof(addr));
248
addr.sun_family = AF_LOCAL;
249
memcpy((char *) &addr.sun_path + 1, ISCSIADM_NAMESPACE,
250
strlen(ISCSIADM_NAMESPACE));
252
if ((err = connect(fd, (struct sockaddr *) &addr, sizeof(addr))) < 0) {
253
log_error("can not connect to iSCSI daemon!");
261
iscsid_request(int fd, iscsiadm_req_t *req)
265
if ((err = write(fd, req, sizeof(*req))) != sizeof(*req)) {
266
log_error("%s: got write error (%d) on cmd %d, daemon died?",
267
program_name, err, req->command);
275
iscsid_response(int fd, iscsiadm_rsp_t *rsp)
279
if ((err = read(fd, rsp, sizeof(*rsp))) != sizeof(*rsp)) {
280
log_error("got read error (%d), daemon died?", err);
290
do_iscsid(iscsiadm_req_t *req, iscsiadm_rsp_t *rsp)
294
if ((ipc_fd = iscsid_connect()) < 0) {
299
if ((err = iscsid_request(ipc_fd, req)) < 0)
302
err = iscsid_response(ipc_fd, rsp);
303
if (!err && req->command != rsp->command)
314
session_login(int rid, node_rec_t *rec)
199
log_error("Unable to find session in %s", sysfs_device);
203
targetname = malloc(TARGET_NAME_MAXLEN + 1);
207
address = malloc(NI_MAXHOST + 1);
213
log_debug(2, "%s: session %s", __FUNCTION__, sys_session);
214
rc = get_sessioninfo_by_sysfs_id(&sid, targetname, address, &port,
217
log_error("Unable to find a record for iscsi %s (sys %s)",
218
sys_session, sysfs_device);
222
rc = idbm_node_read(db, rec, targetname, address, port);
224
log_error("node [%s, %s, %d] not found!",
225
targetname, address, port);
237
session_login(node_rec_t *rec)
316
239
iscsiadm_req_t req;
317
240
iscsiadm_rsp_t rsp;
319
memset(&req, 0, sizeof(req));
242
memset(&req, 0, sizeof(iscsiadm_req_t));
320
243
req.command = MGMT_IPC_SESSION_LOGIN;
321
req.u.session.rid = rid;
323
return do_iscsid(&req, &rsp);
327
session_logout(int rid, node_rec_t *rec)
244
memcpy(&req.u.session.rec, rec, sizeof(node_rec_t));
246
return do_iscsid(&ipc_fd, &req, &rsp);
250
__delete_target(void *data, char *targetname, int tpgt, char *address,
253
node_rec_t *rec = data;
257
log_debug(6, "looking for session [%s,%s,%d]",
258
rec->name, rec->conn[0].address, rec->conn[0].port);
260
if (!strcmp(rec->name, targetname) &&
261
!strcmp(rec->conn[0].address, address) &&
262
rec->conn[0].port == port) {
263
host_no = get_host_no_from_sid(sid, &err);
265
log_error("Could not properly delete target\n");
269
sysfs_for_each_device(host_no, sid, delete_device);
273
/* keep on looking */
278
session_logout(node_rec_t *rec)
329
280
iscsiadm_req_t req;
330
281
iscsiadm_rsp_t rsp;
332
284
memset(&req, 0, sizeof(req));
333
285
req.command = MGMT_IPC_SESSION_LOGOUT;
334
req.u.session.rid = rid;
336
return do_iscsid(&req, &rsp);
286
memcpy(&req.u.session.rec, rec, sizeof(node_rec_t));
288
sysfs_for_each_session(rec, &num_found, __delete_target);
289
return do_iscsid(&ipc_fd, &req, &rsp);
293
match_startup_mode(node_rec_t *rec, char *mode)
296
* we always skip onboot because this should be handled by
299
if (rec->startup == ISCSI_STARTUP_ONBOOT)
302
if ((!strcmp(mode, "automatic") &&
303
rec->startup == ISCSI_STARTUP_AUTOMATIC) ||
304
(!strcmp(mode, "manual") &&
305
rec->startup == ISCSI_STARTUP_MANUAL) ||
306
!strcmp(mode, "all"))
309
/* support conn or session startup params */
310
if ((!strcmp(mode, "automatic") &&
311
rec->conn[0].startup == ISCSI_STARTUP_AUTOMATIC) ||
312
(!strcmp(mode, "manual") &&
313
rec->conn[0].startup == ISCSI_STARTUP_MANUAL) ||
314
!strcmp(mode, "all"))
320
struct session_mgmt_fn {
326
__group_logout(void *data, char *targetname, int tpgt, char *address,
329
struct session_mgmt_fn *mgmt = data;
330
char *mode = mgmt->mode;
331
idbm_t *db = mgmt->db;
335
log_debug(7, "logout all [%d][%s,%s.%d]\n", sid, targetname,
338
/* for now skip qlogic and other HW and offload drivers */
339
if (!get_transport_by_sid(sid))
342
if (idbm_node_read(db, &rec, targetname, address, port)) {
344
* this is due to a HW driver or some other driver
347
log_debug(7, "could not read data for [%s,%s.%d]\n",
348
targetname, address, port);
352
* we always skip on boot because if the user killed this on
353
* they would not be able to do anything
355
if (rec.startup == ISCSI_STARTUP_ONBOOT)
358
if (!match_startup_mode(&rec, mode)) {
359
rc = session_logout(&rec);
360
/* we raced with another app or instance of iscsiadm */
361
if (rc == MGMT_IPC_ERR_NOT_FOUND)
364
iscsid_handle_error(rc);
365
/* continue trying to logout the rest of them */
374
group_logout(idbm_t *db, char *mode)
377
struct session_mgmt_fn mgmt;
379
if (!mode || !(!strcmp(mode, "automatic") || !strcmp(mode, "all") ||
380
!strcmp(mode,"manual"))) {
381
log_error("Invalid logoutall option %s.", mode);
389
return sysfs_for_each_session(&mgmt, &num_found, __group_logout);
393
__group_login(void *data, node_rec_t *rec)
395
struct session_mgmt_fn *mgmt = data;
396
char *mode = mgmt->mode;
399
log_debug(7, "group login %s:%d,%d %s\n", rec->conn[0].address,
400
rec->conn[0].port, rec->tpgt, rec->name);
402
* we always skip onboot because this should be handled by
405
if (rec->startup == ISCSI_STARTUP_ONBOOT)
408
if (!match_startup_mode(rec, mode)) {
409
rc = session_login(rec);
410
/* we raced with another app or instance of iscsiadm */
411
if (rc == MGMT_IPC_ERR_EXISTS)
414
iscsid_handle_error(rc);
415
/* continue trying to login the rest of them */
424
group_login(idbm_t *db, char *mode)
426
struct session_mgmt_fn mgmt;
428
if (!mode || !(!strcmp(mode, "automatic") || !strcmp(mode, "all") ||
429
!strcmp(mode,"manual"))) {
430
log_error("Invalid loginall option %s.", mode);
438
idbm_for_each_node(db, &mgmt, __group_login);
443
print_node_info(void *data, node_rec_t *rec)
445
printf("%s:%d,%d %s\n", rec->conn[0].address, rec->conn[0].port,
446
rec->tpgt, rec->name);
383
session_activelist(idbm_t *db)
389
memset(&req, 0, sizeof(req));
390
req.command = MGMT_IPC_SESSION_ACTIVELIST;
392
rc = do_iscsid(&req, &rsp);
395
/* display all active sessions */
396
for (i = 0; i < rsp.u.activelist.cnt; i++) {
399
if (idbm_node_read(db, rsp.u.activelist.rids[i], &rec)) {
400
log_error("no record [%06x] found!",
401
rsp.u.activelist.rids[i]);
404
printf("[%02d:%06x] %s:%d,%d %s\n",
405
rsp.u.activelist.sids[i], rec.id, rec.conn[0].address,
406
rec.conn[0].port, rec.tpgt, rec.name);
413
session_stats(idbm_t *db, int rid, int sid)
420
if (idbm_node_read(db, rid, &rec)) {
421
log_error("no record [%06x] found!", rid);
493
static int print_session(void *data, char *targetname, int tpgt, char *address,
496
iscsi_provider_t *provider;
498
provider = get_transport_by_sid(sid);
500
printf("%s: [%d] %s:%d,%d %s\n", provider ? provider->name : "NA",
501
sid, address, port, tpgt, targetname);
505
static int session_activelist(void)
509
sysfs_for_each_session(NULL, &num_found, print_session);
514
session_stats(idbm_t *db, int sid)
425
520
memset(&req, 0, sizeof(req));
426
521
req.command = MGMT_IPC_SESSION_STATS;
427
req.u.session.rid = rid;
428
522
req.u.session.sid = sid;
430
rc = do_iscsid(&req, &rsp);
524
rc = do_iscsid(&ipc_fd, &req, &rsp);
434
printf("[%02d:%06x] %s:%d,%d %s\n",
435
sid, rid, rec.conn[0].address, rec.conn[0].port,
528
printf("[%02d]\n", sid);
437
529
printf( "iSCSI SNMP:\n"
439
531
"\ttxdata_octets: %lld\n"