From fec061ac683d4b6f4f986b26c7cbe72932902e3c Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Tue, 23 Oct 2012 15:59:28 +0200 Subject: [PATCH] Add iscsi-readcapacity16 binary This patch adds a small binary to read the size of an iscsi target. The value is returned on stdout. --- Makefile.am | 3 +- include/iscsi.h | 2 +- src/iscsi-readcapacity16.c | 166 +++++++++++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 src/iscsi-readcapacity16.c diff --git a/Makefile.am b/Makefile.am index 735760a..6868df6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -37,9 +37,10 @@ lib_libiscsi_la_LDFLAGS = \ # libiscsi utilities if PROGRAMS -bin_PROGRAMS += bin/iscsi-inq bin/iscsi-ls +bin_PROGRAMS += bin/iscsi-inq bin/iscsi-ls bin/iscsi-readcapacity16 bin_iscsi_inq_SOURCES = src/iscsi-inq.c bin_iscsi_ls_SOURCES = src/iscsi-ls.c +bin_iscsi_readcapacity16_SOURCES = src/iscsi-readcapacity16.c # Other examples diff --git a/include/iscsi.h b/include/iscsi.h index cae57f3..aeaa121 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -963,7 +963,7 @@ iscsi_scsi_cancel_all_tasks(struct iscsi_context *iscsi); do { \ if ((iscsi)->debug >= level) { \ fprintf(stderr,"libiscsi: "); \ - fprintf(stderr, (fmt), ##args); \ + fprintf(stderr, (fmt), ##args); \ if (iscsi->target_name) { \ fprintf(stderr," [%s]",iscsi->target_name); \ } \ diff --git a/src/iscsi-readcapacity16.c b/src/iscsi-readcapacity16.c new file mode 100644 index 0000000..3954b42 --- /dev/null +++ b/src/iscsi-readcapacity16.c @@ -0,0 +1,166 @@ +/* + Copyright (C) 2010 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include "iscsi.h" +#include "scsi-lowlevel.h" + +const char *initiator = "iqn.2007-10.com.github:sahlberg:libiscsi:iscsi-readcapacity16"; + +void print_usage(void) +{ + fprintf(stderr, "Usage: iscsi-readcapacity16 [-?] [-?|--help] [--usage] [-i|--initiator-name=iqn-name] \n"); +} + +void print_help(void) +{ + fprintf(stderr, "Usage: iscsi_readcapacity16 [OPTION...] \n"); + fprintf(stderr, " -i, --initiator-name=iqn-name Initiatorname to use\n"); + fprintf(stderr, " -d, --debug=integer debug level (0=disabled)\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "Help options:\n"); + fprintf(stderr, " -?, --help Show this help message\n"); + fprintf(stderr, " --usage Display brief usage message\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "iSCSI URL format : %s\n", ISCSI_URL_SYNTAX); + fprintf(stderr, "\n"); + fprintf(stderr, " is either of:\n"); + fprintf(stderr, " \"hostname\" iscsi.example\n"); + fprintf(stderr, " \"ipv4-address\" 10.1.1.27\n"); + fprintf(stderr, " \"ipv6-address\" [fce0::1]\n"); +} + +int main(int argc, const char *argv[]) +{ + poptContext pc; + struct iscsi_context *iscsi; + const char **extra_argv; + int extra_argc = 0; + const char *url = NULL; + struct iscsi_url *iscsi_url = NULL; + int show_help = 0, show_usage = 0, debug = 0; + int res; + + struct poptOption popt_options[] = { + { "help", '?', POPT_ARG_NONE, &show_help, 0, "Show this help message", NULL }, + { "usage", 0, POPT_ARG_NONE, &show_usage, 0, "Display brief usage message", NULL }, + { "initiator-name", 'i', POPT_ARG_STRING, &initiator, 0, "Initiatorname to use", "iqn-name" }, + { "debug", 'd', POPT_ARG_INT, &debug, 0, "Debugging level", "integer" }, + POPT_TABLEEND + }; + + pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_POSIXMEHARDER); + if ((res = poptGetNextOpt(pc)) < -1) { + fprintf(stderr, "Failed to parse option : %s %s\n", + poptBadOption(pc, 0), poptStrerror(res)); + exit(10); + } + extra_argv = poptGetArgs(pc); + if (extra_argv) { + url = *extra_argv; + extra_argv++; + while (extra_argv[extra_argc]) { + extra_argc++; + } + } + + if (show_help != 0) { + print_help(); + exit(0); + } + + if (show_usage != 0) { + print_usage(); + exit(0); + } + + poptFreeContext(pc); + + iscsi = iscsi_create_context(initiator); + if (iscsi == NULL) { + fprintf(stderr, "Failed to create context\n"); + exit(10); + } + + if (debug > 0) { + iscsi_set_debug(iscsi, debug); + } + + if (url == NULL) { + fprintf(stderr, "You must specify the URL\n"); + print_usage(); + exit(10); + } + iscsi_url = iscsi_parse_full_url(iscsi, url); + if (iscsi_url == NULL) { + fprintf(stderr, "Failed to parse URL: %s\n", + iscsi_get_error(iscsi)); + exit(10); + } + + iscsi_set_targetname(iscsi, iscsi_url->target); + iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL); + iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); + + if (iscsi_url->user != NULL) { + if (iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user, iscsi_url->passwd) != 0) { + fprintf(stderr, "Failed to set initiator username and password\n"); + exit(10); + } + } + + if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) { + fprintf(stderr, "Login Failed. %s\n", iscsi_get_error(iscsi)); + iscsi_destroy_url(iscsi_url); + iscsi_destroy_context(iscsi); + exit(10); + } + + struct scsi_task *task; + struct scsi_readcapacity16 *rc16; + + task = iscsi_readcapacity16_sync(iscsi, iscsi_url->lun); + if (task == NULL || task->status != SCSI_STATUS_GOOD) { + fprintf(stderr,"failed to send readcapacity command\n"); + iscsi_destroy_url(iscsi_url); + iscsi_destroy_context(iscsi); + exit(10); + } + + rc16 = scsi_datain_unmarshall(task); + if (rc16 == NULL) { + fprintf(stderr,"failed to unmarshall readcapacity16 data\n"); + scsi_free_scsi_task(task); + iscsi_destroy_url(iscsi_url); + iscsi_destroy_context(iscsi); + exit(10); + } + + fprintf(stdout,"%lu",rc16->block_length*(rc16->returned_lba + 1)); + + iscsi_destroy_url(iscsi_url); + + iscsi_logout_sync(iscsi); + iscsi_destroy_context(iscsi); + return 0; +} +