~ubuntu-branches/ubuntu/oneiric/open-iscsi/oneiric

« back to all changes in this revision

Viewing changes to usr/iscsiadm.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Zobel-Helas
  • Date: 2006-12-03 16:54:21 UTC
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20061203165421-udgd6i05ugt1byrh
Tags: upstream-2.0.730
ImportĀ upstreamĀ versionĀ 2.0.730

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
#include "log.h"
38
38
#include "mgmt_ipc.h"
39
39
#include "idbm.h"
 
40
#include "util.h"
 
41
#include "transport.h"
 
42
#include "version.h"
 
43
#include "iscsi_sysfs.h"
40
44
 
41
45
struct iscsi_ipc *ipc = NULL; /* dummy */
42
46
static int ipc_fd = -1;
63
67
{
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},
78
87
};
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";
80
89
 
81
90
static void usage(int status)
82
91
{
84
93
                fprintf(stderr, "Try `%s --help' for more information.\n",
85
94
                        program_name);
86
95
        else {
87
 
                printf("Usage: %s [OPTION]\n", program_name);
88
96
                printf("\
89
 
iSCSI Administration Utility.\n\
90
 
\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\
115
 
                          specified\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\
125
 
\n\
126
 
Enjoy!\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");
128
102
        }
129
 
 
130
103
        exit(status == 0 ? 0 : -1);
131
104
}
132
105
 
184
157
        return type;
185
158
}
186
159
 
187
 
static char*
188
 
str_to_ipport(char *str, int *port)
189
 
{
190
 
        char *sport = str;
191
 
 
192
 
        if (!strchr(str, '.')) {
193
 
                if (*str == '[') {
194
 
                        if (!(sport = strchr(str, ']')))
195
 
                                return NULL;
196
 
                        *sport++ = '\0';
197
 
                        str++;
198
 
                } else
199
 
                        sport = NULL;
200
 
        }
201
 
 
202
 
        if (sport && (sport = strchr(sport, ':'))) {
203
 
                *sport = '\0';
204
 
                sport++;
205
 
                *port = strtoul(sport, NULL, 10);
206
 
        } else
207
 
                *port = DEF_ISCSI_PORT;
208
 
 
209
 
        return str;
210
 
}
211
 
 
212
160
static int
213
 
str_to_ridsid(char *str, int *sid)
 
161
sys_to_rec(idbm_t *db, node_rec_t *rec, char *sysfs_device)
214
162
{
215
 
        char *ptr, *eptr;
216
 
        int rid;
217
 
 
218
 
        if ((ptr = strchr(str, ':'))) {
219
 
                *ptr = '\0';
220
 
                ptr++;
221
 
                *sid = strtoul(str, &eptr, 10);
222
 
                if (eptr == str)
223
 
                        *sid = -1;
 
163
        char *targetname;
 
164
        char *address;
 
165
        int sid, rc, port, tpgt, len;
 
166
        struct stat statb;
 
167
        char sys_session[64], *start, *last;
 
168
 
 
169
        /*
 
170
         * Given sysfs_device is a directory name of the form:
 
171
         *
 
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
 
175
         *
 
176
         * We want to set sys_session to sessionS
 
177
         */
 
178
        if (stat(sysfs_device, &statb)) {
 
179
                log_error("stat %s failed with %d", sysfs_device, errno);
 
180
                exit(1);
 
181
        }
 
182
        if (!S_ISDIR(statb.st_mode)) {
 
183
                log_error("%s is not a directory", sysfs_device);
 
184
                exit(1);
 
185
        }
 
186
 
 
187
        last = NULL;
 
188
        start = strstr(sysfs_device, "session");
 
189
        if (start && strncmp(start, "session", 7) == 0) {
 
190
                len = strlen(start);
 
191
                last = index(start, '/');
 
192
                /*
 
193
                 * If '/' not found last is NULL.
 
194
                 */
 
195
                if (last)
 
196
                        len = last - start;
 
197
                strncpy(sys_session, start, len);
224
198
        } else {
225
 
                *sid = -1;
226
 
                ptr = str;
227
 
        }
228
 
 
229
 
        rid = strtoul(ptr, &eptr, 16);
230
 
        if (eptr == ptr)
231
 
                rid = -1;
232
 
        return rid;
233
 
}
234
 
 
235
 
static int
236
 
iscsid_connect(void)
237
 
{
238
 
        int fd, err;
239
 
        struct sockaddr_un addr;
240
 
 
241
 
        fd = socket(AF_LOCAL, SOCK_STREAM, 0);
242
 
        if (fd < 0) {
243
 
                log_error("can not create IPC socket!");
244
 
                return fd;
245
 
        }
246
 
 
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));
251
 
 
252
 
        if ((err = connect(fd, (struct sockaddr *) &addr, sizeof(addr))) < 0) {
253
 
                log_error("can not connect to iSCSI daemon!");
254
 
                fd = err;
255
 
        }
256
 
 
257
 
        return fd;
258
 
}
259
 
 
260
 
static int
261
 
iscsid_request(int fd, iscsiadm_req_t *req)
262
 
{
263
 
        int err;
264
 
 
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);
268
 
                if (err >= 0)
269
 
                        err = -EIO;
270
 
        }
271
 
        return err;
272
 
}
273
 
 
274
 
static int
275
 
iscsid_response(int fd, iscsiadm_rsp_t *rsp)
276
 
{
277
 
        int err;
278
 
 
279
 
        if ((err = read(fd, rsp, sizeof(*rsp))) != sizeof(*rsp)) {
280
 
                log_error("got read error (%d), daemon died?", err);
281
 
                if (err >= 0)
282
 
                        err = -EIO;
283
 
        } else
284
 
                err = rsp->err;
285
 
 
286
 
        return err;
287
 
}
288
 
 
289
 
static int
290
 
do_iscsid(iscsiadm_req_t *req, iscsiadm_rsp_t *rsp)
291
 
{
292
 
        int err;
293
 
 
294
 
        if ((ipc_fd = iscsid_connect()) < 0) {
295
 
                err = ipc_fd;
296
 
                goto out;
297
 
        }
298
 
 
299
 
        if ((err = iscsid_request(ipc_fd, req)) < 0)
300
 
                goto out;
301
 
 
302
 
        err = iscsid_response(ipc_fd, rsp);
303
 
        if (!err && req->command != rsp->command)
304
 
                err = -EIO;
305
 
out:
306
 
        if (ipc_fd > 0)
307
 
                close(ipc_fd);
308
 
        ipc_fd = -1;
309
 
 
310
 
        return err;
311
 
}
312
 
 
313
 
static int
314
 
session_login(int rid, node_rec_t *rec)
 
199
                log_error("Unable to find session in %s", sysfs_device);
 
200
                exit(1);
 
201
        }
 
202
 
 
203
        targetname = malloc(TARGET_NAME_MAXLEN + 1);
 
204
        if (!targetname)
 
205
                return -ENOMEM;
 
206
 
 
207
        address = malloc(NI_MAXHOST + 1);
 
208
        if (!address) {
 
209
                rc = -ENOMEM;
 
210
                goto free_target;
 
211
        }
 
212
 
 
213
        log_debug(2, "%s: session %s", __FUNCTION__, sys_session);
 
214
        rc = get_sessioninfo_by_sysfs_id(&sid, targetname, address, &port,
 
215
                                        &tpgt, sys_session);
 
216
        if (rc < 0) {
 
217
                log_error("Unable to find a record for iscsi %s (sys %s)",
 
218
                          sys_session, sysfs_device);
 
219
                goto free_address;
 
220
        }
 
221
 
 
222
        rc = idbm_node_read(db, rec, targetname, address, port);
 
223
        if (rc) {
 
224
                log_error("node [%s, %s, %d] not found!",
 
225
                          targetname, address, port);
 
226
                goto free_address;
 
227
        }
 
228
 
 
229
free_address:
 
230
        free(address);
 
231
free_target:
 
232
        free(targetname);
 
233
        return rc;
 
234
}
 
235
 
 
236
static int
 
237
session_login(node_rec_t *rec)
315
238
{
316
239
        iscsiadm_req_t req;
317
240
        iscsiadm_rsp_t rsp;
318
241
 
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;
322
 
 
323
 
        return do_iscsid(&req, &rsp);
324
 
}
325
 
 
326
 
static int
327
 
session_logout(int rid, node_rec_t *rec)
 
244
        memcpy(&req.u.session.rec, rec, sizeof(node_rec_t));
 
245
 
 
246
        return do_iscsid(&ipc_fd, &req, &rsp);
 
247
}
 
248
 
 
249
static int
 
250
__delete_target(void *data, char *targetname, int tpgt, char *address,
 
251
              int port, int sid)
 
252
{
 
253
        node_rec_t *rec = data;
 
254
        uint32_t host_no;
 
255
        int err;
 
256
 
 
257
        log_debug(6, "looking for session [%s,%s,%d]",
 
258
                  rec->name, rec->conn[0].address, rec->conn[0].port);
 
259
 
 
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);
 
264
                if (err) {
 
265
                        log_error("Could not properly delete target\n");
 
266
                        return 1;
 
267
                }
 
268
 
 
269
                sysfs_for_each_device(host_no, sid, delete_device);
 
270
                return 1;
 
271
        }
 
272
 
 
273
        /* keep on looking */
 
274
        return 0;
 
275
}
 
276
 
 
277
static int
 
278
session_logout(node_rec_t *rec)
328
279
{
329
280
        iscsiadm_req_t req;
330
281
        iscsiadm_rsp_t rsp;
 
282
        int num_found = 0;
331
283
 
332
284
        memset(&req, 0, sizeof(req));
333
285
        req.command = MGMT_IPC_SESSION_LOGOUT;
334
 
        req.u.session.rid = rid;
335
 
 
336
 
        return do_iscsid(&req, &rsp);
 
286
        memcpy(&req.u.session.rec, rec, sizeof(node_rec_t));
 
287
 
 
288
        sysfs_for_each_session(rec, &num_found, __delete_target);
 
289
        return do_iscsid(&ipc_fd, &req, &rsp);
 
290
}
 
291
 
 
292
static int
 
293
match_startup_mode(node_rec_t *rec, char *mode)
 
294
{
 
295
        /*
 
296
         * we always skip onboot because this should be handled by
 
297
         * something else
 
298
         */
 
299
        if (rec->startup == ISCSI_STARTUP_ONBOOT)
 
300
                return -1;
 
301
 
 
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"))
 
307
                return 0;
 
308
 
 
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"))
 
315
                return 0;
 
316
 
 
317
        return -1;
 
318
}
 
319
 
 
320
struct session_mgmt_fn {
 
321
        idbm_t *db;
 
322
        char *mode;
 
323
};
 
324
 
 
325
static int
 
326
__group_logout(void *data, char *targetname, int tpgt, char *address,
 
327
               int port, int sid)
 
328
{
 
329
        struct session_mgmt_fn *mgmt = data;
 
330
        char *mode = mgmt->mode;
 
331
        idbm_t *db = mgmt->db;
 
332
        node_rec_t rec;
 
333
        int rc = 0;
 
334
 
 
335
        log_debug(7, "logout all [%d][%s,%s.%d]\n", sid, targetname,
 
336
                  address, port);
 
337
 
 
338
        /* for now skip qlogic and other HW and offload drivers */
 
339
        if (!get_transport_by_sid(sid))
 
340
                return 0;
 
341
 
 
342
        if (idbm_node_read(db, &rec, targetname, address, port)) {
 
343
                /*
 
344
                 * this is due to a HW driver or some other driver
 
345
                 * not hooked in
 
346
                 */
 
347
                log_debug(7, "could not read data for [%s,%s.%d]\n",
 
348
                          targetname, address, port);
 
349
                return 0;
 
350
        }
 
351
        /*
 
352
         * we always skip on boot because if the user killed this on
 
353
         * they would not be able to do anything
 
354
         */
 
355
        if (rec.startup == ISCSI_STARTUP_ONBOOT)
 
356
                return 0;
 
357
 
 
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)
 
362
                        rc = 0;
 
363
                if (rc > 0) {
 
364
                        iscsid_handle_error(rc);
 
365
                        /* continue trying to logout the rest of them */
 
366
                        rc = 0;
 
367
                }
 
368
        }
 
369
 
 
370
        return rc;
 
371
}
 
372
 
 
373
static int
 
374
group_logout(idbm_t *db, char *mode)
 
375
{
 
376
        int num_found;
 
377
        struct session_mgmt_fn mgmt;
 
378
 
 
379
        if (!mode || !(!strcmp(mode, "automatic") || !strcmp(mode, "all") ||
 
380
            !strcmp(mode,"manual"))) {
 
381
                log_error("Invalid logoutall option %s.", mode);
 
382
                usage(0);
 
383
                return -EINVAL;
 
384
        }
 
385
 
 
386
        mgmt.mode = mode;
 
387
        mgmt.db = db;
 
388
 
 
389
        return sysfs_for_each_session(&mgmt, &num_found, __group_logout);
 
390
}
 
391
 
 
392
static int
 
393
__group_login(void *data, node_rec_t *rec)
 
394
{
 
395
        struct session_mgmt_fn *mgmt = data;
 
396
        char *mode = mgmt->mode;
 
397
        int rc;
 
398
 
 
399
        log_debug(7, "group login %s:%d,%d %s\n", rec->conn[0].address,
 
400
                  rec->conn[0].port, rec->tpgt, rec->name);
 
401
        /*
 
402
         * we always skip onboot because this should be handled by
 
403
         * something else
 
404
         */
 
405
        if (rec->startup == ISCSI_STARTUP_ONBOOT)
 
406
                return 0;
 
407
 
 
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)
 
412
                        rc = 0;
 
413
                if (rc > 0) {
 
414
                        iscsid_handle_error(rc);
 
415
                        /* continue trying to login the rest of them */
 
416
                        rc = 0;
 
417
                }
 
418
        }
 
419
 
 
420
        return 0;
 
421
}
 
422
 
 
423
static int
 
424
group_login(idbm_t *db, char *mode)
 
425
{
 
426
        struct session_mgmt_fn mgmt;
 
427
 
 
428
        if (!mode || !(!strcmp(mode, "automatic") || !strcmp(mode, "all") ||
 
429
            !strcmp(mode,"manual"))) {
 
430
                log_error("Invalid loginall option %s.", mode);
 
431
                usage(0);
 
432
                return -EINVAL;
 
433
        }
 
434
 
 
435
        mgmt.mode = mode;
 
436
        mgmt.db = db;
 
437
 
 
438
        idbm_for_each_node(db, &mgmt, __group_login);
 
439
        return 0;
 
440
}
 
441
 
 
442
static int
 
443
print_node_info(void *data, node_rec_t *rec)
 
444
{
 
445
        printf("%s:%d,%d %s\n", rec->conn[0].address, rec->conn[0].port,
 
446
               rec->tpgt, rec->name);
 
447
        return 0;
337
448
}
338
449
 
339
450
static int
346
457
        memset(&req, 0, sizeof(req));
347
458
        req.command = MGMT_IPC_CONFIG_INAME;
348
459
 
349
 
        rc = do_iscsid(&req, &rsp);
 
460
        rc = do_iscsid(&ipc_fd, &req, &rsp);
350
461
        if (rc)
351
462
                return rc;
352
463
 
357
468
        memset(&req, 0, sizeof(req));
358
469
        req.command = MGMT_IPC_CONFIG_IALIAS;
359
470
 
360
 
        rc = do_iscsid(&req, &rsp);
 
471
        rc = do_iscsid(&ipc_fd, &req, &rsp);
361
472
        if (rc)
362
473
                return rc;
363
474
 
368
479
        memset(&req, 0, sizeof(req));
369
480
        req.command = MGMT_IPC_CONFIG_FILE;
370
481
 
371
 
        rc = do_iscsid(&req, &rsp);
 
482
        rc = do_iscsid(&ipc_fd, &req, &rsp);
372
483
        if (rc)
373
484
                return rc;
374
485
 
379
490
        return 0;
380
491
}
381
492
 
382
 
static int
383
 
session_activelist(idbm_t *db)
384
 
{
385
 
        int rc, i;
386
 
        iscsiadm_req_t req;
387
 
        iscsiadm_rsp_t rsp;
388
 
 
389
 
        memset(&req, 0, sizeof(req));
390
 
        req.command = MGMT_IPC_SESSION_ACTIVELIST;
391
 
 
392
 
        rc = do_iscsid(&req, &rsp);
393
 
        if (rc)
394
 
                return rc;
395
 
        /* display all active sessions */
396
 
        for (i = 0; i < rsp.u.activelist.cnt; i++) {
397
 
                node_rec_t rec;
398
 
 
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]);
402
 
                        return -1;
403
 
                }
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);
407
 
        }
408
 
 
409
 
        return i;
410
 
}
411
 
 
412
 
static int
413
 
session_stats(idbm_t *db, int rid, int sid)
414
 
{
415
 
        int rc, i;
416
 
        iscsiadm_req_t req;
417
 
        iscsiadm_rsp_t rsp;
418
 
        node_rec_t rec;
419
 
 
420
 
        if (idbm_node_read(db, rid, &rec)) {
421
 
                log_error("no record [%06x] found!", rid);
422
 
                return -1;
423
 
        }
 
493
static int print_session(void *data, char *targetname, int tpgt, char *address,
 
494
                         int port, int sid)
 
495
{
 
496
        iscsi_provider_t *provider;
 
497
 
 
498
        provider = get_transport_by_sid(sid);
 
499
 
 
500
        printf("%s: [%d] %s:%d,%d %s\n", provider ? provider->name : "NA",
 
501
                sid, address, port, tpgt, targetname);
 
502
        return 0;
 
503
}
 
504
 
 
505
static int session_activelist(void)
 
506
{
 
507
        int num_found = 0;
 
508
 
 
509
        sysfs_for_each_session(NULL, &num_found, print_session);
 
510
        return num_found;
 
511
}
 
512
 
 
513
static int
 
514
session_stats(idbm_t *db, int sid)
 
515
{
 
516
        int rc, i;
 
517
        iscsiadm_req_t req;
 
518
        iscsiadm_rsp_t rsp;
424
519
 
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;
429
523
 
430
 
        rc = do_iscsid(&req, &rsp);
 
524
        rc = do_iscsid(&ipc_fd, &req, &rsp);
431
525
        if (rc)
432
526
                return rc;
433
527
 
434
 
        printf("[%02d:%06x] %s:%d,%d %s\n",
435
 
                sid, rid, rec.conn[0].address, rec.conn[0].port,
436
 
                rec.tpgt, rec.name);
 
528
        printf("[%02d]\n", sid);
437
529
        printf( "iSCSI SNMP:\n"
438
530
 
439
531
                "\ttxdata_octets: %lld\n"
512
604
                discovery_rec_t *drec;
513
605
                if ((drec = idbm_new_discovery(db, cfg->address, cfg->port,
514
606
                    DISCOVERY_TYPE_SENDTARGETS, info.buffer))) {
515
 
                        idbm_print_nodes(db, drec);
 
607
                        idbm_for_each_node(db, NULL, print_node_info);
516
608
                        free(drec);
517
609
                }
518
610
        }
520
612
        return rc;
521
613
}
522
614
 
523
 
static void
524
 
iscsid_handle_error(int err)
525
 
{
526
 
        static char *err_msgs[] = {
527
 
                /* 0 */ "",
528
 
                /* 1 */ "unknown error",
529
 
                /* 2 */ "not found",
530
 
                /* 3 */ "no available memory",
531
 
                /* 4 */ "encountered connection failure",
532
 
                /* 5 */ "encountered iSCSI login failure",
533
 
                /* 6 */ "encountered iSCSI database failure",
534
 
                /* 7 */ "invalid parameter",
535
 
                /* 8 */ "connection timed out",
536
 
                /* 9 */ "internal error",
537
 
                /* 10 */ "encountered iSCSI logout failure",
538
 
                /* 11 */ "iSCSI PDU timed out",
539
 
                /* 12 */ "iSCSI transport not found",
540
 
                /* 13 */ "daemon access denied",
541
 
                /* 14 */ "iSCSI transport capability failure",
542
 
        };
543
 
        log_error("iscsid reported error (%d - %s)", err, err_msgs[err]);
544
 
}
545
 
 
546
615
static int
547
616
verify_mode_params(int argc, char **argv, char *allowed, int skip_m)
548
617
{
574
643
int
575
644
main(int argc, char **argv)
576
645
{
577
 
        char *ip = NULL, *name = NULL, *value = NULL;
 
646
        char *ip = NULL, *name = NULL, *value = NULL, *sysfs_device = NULL;
 
647
        char *targetname = NULL, *group_session_mgmt_mode = NULL;
578
648
        int ch, longindex, mode=-1, port=-1, do_login=0;
579
 
        int rc=0, rid=-1, sid=-1, op=-1, type=-1, do_logout=0, do_stats=0;
 
649
        int rc=0, sid=-1, op=-1, type=-1, do_logout=0, do_stats=0, do_show=0;
 
650
        int do_login_all=0, do_logout_all=0;
580
651
        idbm_t *db;
581
652
        struct sigaction sa_old;
582
653
        struct sigaction sa_new;
587
658
        sa_new.sa_flags = 0;
588
659
        sigaction(SIGINT, &sa_new, &sa_old );
589
660
 
 
661
        umask(0177);
 
662
 
590
663
        /* enable stdout logging */
591
664
        log_daemon = 0;
592
665
        log_init(program_name, 1024);
619
692
                        value = optarg;
620
693
                        break;
621
694
                case 'r':
622
 
                        rid = str_to_ridsid(optarg, &sid);
623
 
                        if (rid < 0) {
624
 
                                log_error("invalid record '%s'",
 
695
                        sid = atoi(optarg);
 
696
                        if (sid < 0) {
 
697
                                log_error("invalid sid '%s'",
625
698
                                          optarg);
626
699
                                return -1;
627
700
                        }
632
705
                case 'u':
633
706
                        do_logout = 1;
634
707
                        break;
 
708
                case 'U':
 
709
                        do_logout_all = 1;
 
710
                        group_session_mgmt_mode= optarg;
 
711
                        break;
 
712
                case 'L':
 
713
                        do_login_all= 1;
 
714
                        group_session_mgmt_mode= optarg;
 
715
                        break;
635
716
                case 's':
636
717
                        do_stats = 1;
637
718
                        break;
 
719
                case 'S':
 
720
                        do_show = 1;
 
721
                        break;
638
722
                case 'd':
639
723
                        log_level = atoi(optarg);
640
724
                        break;
641
725
                case 'm':
642
726
                        mode = str_to_mode(optarg);
643
727
                        break;
 
728
                case 'M':
 
729
                        sysfs_device = optarg;
 
730
                        break;
 
731
                case 'T':
 
732
                        targetname = optarg;
 
733
                        break;
644
734
                case 'p':
645
 
                        ip = str_to_ipport(optarg, &port);
 
735
                        ip = str_to_ipport(optarg, &port, ':');
646
736
                        break;
647
737
                case 'V':
648
738
                        printf("%s version %s\n", program_name,
650
740
                        return 0;
651
741
                case 'h':
652
742
                        usage(0);
653
 
                        break;
654
743
                }
655
744
        }
656
745
 
659
748
                return -1;
660
749
        }
661
750
 
662
 
        if (mode < 0) {
663
 
                mode = MODE_SESSION;
664
 
        }
 
751
        if (mode < 0) 
 
752
                usage(0);
665
753
 
666
754
        db = idbm_init(config_file);
667
755
        if (!db) {
670
758
        }
671
759
 
672
760
        if (mode == MODE_DISCOVERY) {
673
 
                if ((rc = verify_mode_params(argc, argv, "dmtplr", 0))) {
 
761
                if ((rc = verify_mode_params(argc, argv, "dmtplo", 0))) {
674
762
                        log_error("discovery mode: option '-%c' is not "
675
763
                                  "allowed/supported", rc);
676
764
                        rc = -1;
708
796
                        rc = -1;
709
797
                        goto out;
710
798
                } else if (type < 0) {
711
 
                        if (rid >= 0 && do_login) {
 
799
                        if (ip) {
712
800
                                discovery_rec_t rec;
713
801
 
714
 
                                if (idbm_discovery_read(db, rid, &rec)) {
715
 
                                        log_error("discovery record [%06x] "
716
 
                                                  "not found!", rid);
 
802
                                if (idbm_discovery_read(db, &rec, ip, port)) {
 
803
                                        log_error("discovery record [%s,%d] "
 
804
                                                  "not found!", ip, port);
717
805
                                        rc = -1;
718
806
                                        goto out;
719
807
                                }
720
 
                                if (rec.type == DISCOVERY_TYPE_SENDTARGETS) {
 
808
                                if (do_login &&
 
809
                                    rec.type == DISCOVERY_TYPE_SENDTARGETS) {
721
810
                                        do_sendtargets(db, &rec.u.sendtargets);
722
 
                                } else if (rec.type == DISCOVERY_TYPE_SLP) {
 
811
                                } else if (do_login &&
 
812
                                           rec.type == DISCOVERY_TYPE_SLP) {
723
813
                                        log_error("SLP discovery is not fully "
724
814
                                                  "implemented yet.");
725
815
                                        rc = -1;
726
816
                                        goto out;
727
 
                                } else if (rec.type == DISCOVERY_TYPE_ISNS) {
 
817
                                } else if (do_login &&
 
818
                                           rec.type == DISCOVERY_TYPE_ISNS) {
728
819
                                        log_error("iSNS discovery is not fully "
729
820
                                                  "implemented yet.");
730
821
                                        rc = -1;
731
822
                                        goto out;
 
823
                                } else if (op < 0 || op == OP_SHOW) {
 
824
                                        if (!idbm_print_discovery(db, &rec,
 
825
                                                                  do_show)) {
 
826
                                                log_error("no records found!");
 
827
                                                rc = -1;
 
828
                                        }
 
829
                                } else if (op == OP_DELETE) {
 
830
                                        if (idbm_delete_discovery(db, &rec)) {
 
831
                                                log_error("unable to delete "
 
832
                                                           "record!");
 
833
                                                rc = -1;
 
834
                                        }
 
835
                                } else {
 
836
                                        log_error("operation is not supported.");
 
837
                                        rc = -1;
 
838
                                        goto out;
732
839
                                }
 
840
 
733
841
                        } else if (op < 0 || op == OP_SHOW) {
734
 
                                if (!idbm_print_discovery(db, rid)) {
 
842
                                if (!idbm_print_all_discovery(db)) {
735
843
                                        log_error("no records found!");
736
844
                                        rc = -1;
737
845
                                }
738
846
                                goto out;
 
847
                        } else if (op == OP_DELETE) {
 
848
                                log_error("--record required for delete operation");
 
849
                                rc = -1;
 
850
                                goto out;
739
851
                        } else {
740
 
                                log_error("Operations: insert, delete and "
 
852
                                log_error("Operations: new and "
741
853
                                          "update for node is not fully "
742
854
                                          "implemented yet.");
743
855
                                rc = -1;
745
857
                        }
746
858
                }
747
859
        } else if (mode == MODE_NODE) {
748
 
                if ((rc = verify_mode_params(argc, argv, "dmlronvup", 0))) {
 
860
                node_rec_t rec;
 
861
 
 
862
                memset(&rec, 0, sizeof(node_rec_t));
 
863
                if ((rc = verify_mode_params(argc, argv, "dmMlSonvupTUL", 0))) {
749
864
                        log_error("node mode: option '-%c' is not "
750
865
                                  "allowed/supported", rc);
751
866
                        rc = -1;
752
867
                        goto out;
753
868
                }
754
 
                if (rid >= 0) {
755
 
                        node_rec_t rec;
756
 
 
757
 
                        if (idbm_node_read(db, rid, &rec)) {
758
 
                                log_error("node record [%06x] not found!", rid);
759
 
                                rc = -1;
760
 
                                goto out;
761
 
                        }
 
869
 
 
870
                if (do_login_all) {
 
871
                        rc = group_login(db, group_session_mgmt_mode);
 
872
                        goto out;
 
873
                }
 
874
 
 
875
                if (do_logout_all) {
 
876
                        rc = group_logout(db, group_session_mgmt_mode);
 
877
                        goto out;
 
878
                }
 
879
 
 
880
                if (sysfs_device) {
 
881
                        if (targetname && ip) {
 
882
                                log_error("only one of map and "
 
883
                                          "targetname,portal may be specified");
 
884
                                rc = -1;
 
885
                                goto out;
 
886
                        }
 
887
                        if (sys_to_rec(db, &rec, sysfs_device)) {
 
888
                                rc = -1;
 
889
                                goto out;
 
890
                        }
 
891
                        /* bleh */
 
892
                        goto found_node_rec;
 
893
                }
 
894
 
 
895
                if (targetname && ip && op != OP_NEW) {
 
896
                        log_debug(2, "%s: node [%s,%s,%d]", __FUNCTION__,
 
897
                                  targetname, ip, port);
 
898
                        if (idbm_node_read(db, &rec, targetname, ip, port)) {
 
899
                                log_error("node [%s, %s, %d] not found!",
 
900
                                          targetname, ip, port);
 
901
                                rc = -1;
 
902
                                goto out;
 
903
                        }
 
904
 
 
905
found_node_rec:
762
906
                        if (do_login && do_logout) {
763
907
                                log_error("either login or "
764
908
                                          "logout at the time allowed!");
772
916
                                goto out;
773
917
                        }
774
918
                        if (!do_login && !do_logout && op < 0) {
775
 
                                if (!idbm_print_node(db, rid)) {
 
919
                                if (!idbm_print_node(db, &rec, do_show)) {
776
920
                                        log_error("no records found!");
777
921
                                        rc = -1;
778
922
                                }
779
923
                                goto out;
780
924
                        }
781
925
                        if (do_login) {
782
 
                                if ((rc = session_login(rid, &rec)) > 0) {
 
926
                                if ((rc = session_login(&rec)) > 0) {
783
927
                                        iscsid_handle_error(rc);
784
928
                                        rc = -1;
785
929
                                }
786
930
                                goto out;
787
931
                        }
788
932
                        if (do_logout) {
789
 
                                if ((rc = session_logout(rid, &rec)) > 0) {
 
933
                                if ((rc = session_logout(&rec)) > 0) {
790
934
                                        iscsid_handle_error(rc);
791
935
                                        rc = -1;
792
936
                                }
816
960
                                goto out;
817
961
                        }
818
962
                } else if (op < 0 || op == OP_SHOW) {
819
 
                        if (!idbm_print_node(db, rid)) {
 
963
                        if (!idbm_for_each_node(db, NULL, print_node_info)) {
820
964
                                log_error("no records found!");
821
965
                                rc = -1;
822
966
                                goto out;
823
967
                        }
824
968
                } else if (op == OP_NEW) {
825
 
                        node_rec_t nrec;
826
 
                        if (!ip) {
827
 
                                log_error("--portal required for new "
 
969
                        if (!ip || !targetname) {
 
970
                                log_error("portal and target required for new "
828
971
                                          "node record");
829
972
                                rc = -1;
830
973
                                goto out;
831
974
                        }
832
 
                        idbm_node_setup_defaults(&nrec);
833
 
                        strncpy(nrec.name, "<not specified>",
834
 
                                TARGET_NAME_MAXLEN);
835
 
                        nrec.conn[0].port = port;
836
 
                        strncpy(nrec.conn[0].address, ip, 16);
837
 
                        if (idbm_new_node(db, &nrec)) {
 
975
                        idbm_node_setup_defaults(&rec);
 
976
                        strncpy(rec.name, targetname, TARGET_NAME_MAXLEN);
 
977
                        rec.conn[0].port = port;
 
978
                        strncpy(rec.conn[0].address, ip, NI_MAXHOST);
 
979
                        if (idbm_new_node(db, &rec)) {
838
980
                                log_error("can not add new record.");
839
981
                                rc = -1;
840
982
                                goto out;
841
983
                        }
842
 
                        printf("new iSCSI node record added: [%06x]\n",
843
 
                                nrec.id);
 
984
                        printf("new iSCSI node record added\n");
844
985
                } else if (op == OP_DELETE) {
845
986
                        log_error("--record required for delete operation");
846
987
                        rc = -1;
851
992
                        goto out;
852
993
                }
853
994
        } else if (mode == MODE_SESSION) {
854
 
                if ((rc = verify_mode_params(argc, argv, "dmrus", 1))) {
 
995
                if ((rc = verify_mode_params(argc, argv, "drmus", 1))) {
855
996
                        log_error("session mode: option '-%c' is not "
856
997
                                  "allowed or supported", rc);
857
998
                        rc = -1;
858
999
                        goto out;
859
1000
                }
860
 
                if (rid >= 0) {
 
1001
                if (sid >= 0) {
861
1002
                        if (do_logout && do_stats) {
862
1003
                                log_error("--logout or --stats? what exactly?");
863
1004
                                rc = -1;
869
1010
                                goto out;
870
1011
                        }
871
1012
                        if (do_stats) {
872
 
                                if ((rc = session_stats(db, rid, sid)) > 0) {
 
1013
                                if ((rc = session_stats(db, sid)) > 0) {
873
1014
                                        iscsid_handle_error(rc);
874
1015
                                        log_error("can not get statistics for "
875
1016
                                                "session with SID %d (%d)",
880
1021
                        }
881
1022
                } else {
882
1023
                        if (do_logout) {
883
 
                                log_error("--logout requires record id");
 
1024
                                log_error("--logout requires target id");
884
1025
                                rc = -1;
885
1026
                                goto out;
886
1027
                        }
887
1028
                        if (do_stats) {
888
 
                                log_error("--stats requires record id");
 
1029
                                log_error("--stats requires target id");
889
1030
                                rc = -1;
890
1031
                                goto out;
891
1032
                        }
892
 
                        if ((rc = session_activelist(db)) < 0) {
 
1033
                        if ((rc = session_activelist()) < 0) {
893
1034
                                log_error("can not get list of active "
894
1035
                                        "sessions (%d)", rc);
895
1036
                                rc = -1;