Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libiscsi for openSUSE:Factory checked in at 2022-03-18 16:41:34 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libiscsi (Old) and /work/SRC/openSUSE:Factory/.libiscsi.new.25692 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libiscsi" Fri Mar 18 16:41:34 2022 rev:20 rq:962192 version:1.19.0+git.20220303 Changes: -------- --- /work/SRC/openSUSE:Factory/libiscsi/libiscsi.changes 2021-12-13 20:46:52.948503351 +0100 +++ /work/SRC/openSUSE:Factory/.libiscsi.new.25692/libiscsi.changes 2022-03-18 16:41:43.089163369 +0100 @@ -1,0 +2,9 @@ +Wed Mar 16 13:26:08 UTC 2022 - Martin Pluskal <[email protected]> + +- Update to version 1.19.0+git.20220303: + * iscsi-command: Fix leak in iscsi_send_data_out + * iscsi-pr: add persistent reservation tool + * add iscsi_force_reconnect() + * add libiscsi.syms to .gitignore + +------------------------------------------------------------------- Old: ---- libiscsi-1.19.0+git.20210930.obscpio New: ---- libiscsi-1.19.0+git.20220303.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libiscsi.spec ++++++ --- /var/tmp/diff_new_pack.nYvLrr/_old 2022-03-18 16:41:43.673163787 +0100 +++ /var/tmp/diff_new_pack.nYvLrr/_new 2022-03-18 16:41:43.681163793 +0100 @@ -1,7 +1,7 @@ # # spec file for package libiscsi # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %define sover 9 Name: libiscsi -Version: 1.19.0+git.20210930 +Version: 1.19.0+git.20220303 Release: 0 Summary: iSCSI client library and utilities License: GPL-2.0-only AND LGPL-2.1-only @@ -104,6 +104,7 @@ %{_bindir}/iscsi-ls %{_bindir}/iscsi-swp %{_bindir}/iscsi-perf +%{_bindir}/iscsi-pr %{_bindir}/iscsi-readcapacity16 %{_mandir}/man1/iscsi-inq.1%{?ext_man} %{_mandir}/man1/iscsi-ls.1%{?ext_man} ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.nYvLrr/_old 2022-03-18 16:41:43.721163822 +0100 +++ /var/tmp/diff_new_pack.nYvLrr/_new 2022-03-18 16:41:43.725163825 +0100 @@ -3,6 +3,6 @@ <param name="url">[email protected]:sahlberg/libiscsi.git</param> <param name="changesrevision">e6bcdf5fdbf39729399c4f0914661ca1055107a1</param></service><service name="tar_scm"> <param name="url">https://github.com/sahlberg/libiscsi.git</param> - <param name="changesrevision">97d2f681d7d434b166114a031fb3eb4aec97affd</param></service></servicedata> + <param name="changesrevision">2674070fb80ad7527589a1fbd576ee074d26ed72</param></service></servicedata> (No newline at EOF) ++++++ libiscsi-1.19.0+git.20210930.obscpio -> libiscsi-1.19.0+git.20220303.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libiscsi-1.19.0+git.20210930/.gitignore new/libiscsi-1.19.0+git.20220303/.gitignore --- old/libiscsi-1.19.0+git.20210930/.gitignore 2021-10-01 04:54:08.000000000 +0200 +++ new/libiscsi-1.19.0+git.20220303/.gitignore 2022-03-03 21:58:08.000000000 +0100 @@ -37,6 +37,7 @@ /examples/ld_iscsi.so /lib/Makefile.in /lib/Makefile +/lib/libiscsi.syms /test-tool/Makefile.in /test-tool/Makefile /test-tool/iscsi-test-cu diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libiscsi-1.19.0+git.20210930/include/iscsi.h new/libiscsi-1.19.0+git.20220303/include/iscsi.h --- old/libiscsi-1.19.0+git.20210930/include/iscsi.h 2021-10-01 04:54:08.000000000 +0200 +++ new/libiscsi-1.19.0+git.20220303/include/iscsi.h 2022-03-03 21:58:08.000000000 +0100 @@ -493,6 +493,33 @@ EXTERN int iscsi_reconnect_sync(struct iscsi_context *iscsi); /* + * Disconnect a connection to a target and try to reconnect (async version). + * This call returns immediately and the reconnect is processed in the + * background. Commands send to this connection will be queued and not + * processed until we have successfully reconnected. + * + * This will re-start connection (to the configured original portal) even if a + * pending reconnection is already underway, which may be useful if the current + * connection is not progressing. It does not over-ride any existing re-try + * backoff or max retries state. + * + * Returns: + * 0 reconnect was successful + * <0 error + */ +EXTERN int iscsi_force_reconnect(struct iscsi_context *iscsi); + +/* + * Disconnect a connection to a target and try to force reconnection (sync + * version). This call will block until the connection is reestablished. + * + * Returns: + * 0 reconnect was successful + * <0 error + */ +EXTERN int iscsi_force_reconnect_sync(struct iscsi_context *iscsi); + +/* * Asynchronous call to perform an ISCSI login. * * Returns: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libiscsi-1.19.0+git.20210930/lib/connect.c new/libiscsi-1.19.0+git.20220303/lib/connect.c --- old/libiscsi-1.19.0+git.20210930/lib/connect.c 2021-10-01 04:54:08.000000000 +0200 +++ new/libiscsi-1.19.0+git.20220303/lib/connect.c 2022-03-03 21:58:08.000000000 +0100 @@ -378,7 +378,7 @@ iscsi->pending_reconnect = 0; } -int iscsi_reconnect(struct iscsi_context *iscsi) +static int reconnect(struct iscsi_context *iscsi, int force) { struct iscsi_context *tmp_iscsi; @@ -397,7 +397,7 @@ return 0; } - if (iscsi->old_iscsi && !iscsi->pending_reconnect) { + if (iscsi->old_iscsi && !iscsi->pending_reconnect && !force) { return 0; } @@ -477,3 +477,13 @@ return iscsi_full_connect_async(iscsi, iscsi->portal, iscsi->lun, iscsi_reconnect_cb, NULL); } + +int iscsi_reconnect(struct iscsi_context *iscsi) +{ + return reconnect(iscsi, 0); +} + +int iscsi_force_reconnect(struct iscsi_context *iscsi) +{ + return reconnect(iscsi, 1); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libiscsi-1.19.0+git.20210930/lib/iscsi-command.c new/libiscsi-1.19.0+git.20220303/lib/iscsi-command.c --- old/libiscsi-1.19.0+git.20210930/lib/iscsi-command.c 2021-10-01 04:54:08.000000000 +0200 +++ new/libiscsi-1.19.0+git.20220303/lib/iscsi-command.c 2022-03-03 21:58:08.000000000 +0100 @@ -131,6 +131,7 @@ if (iscsi_queue_pdu(iscsi, pdu) != 0) { iscsi_set_error(iscsi, "Out-of-memory: failed to queue iscsi " "scsi pdu."); + iscsi->drv->free_pdu(iscsi, pdu); goto error; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libiscsi-1.19.0+git.20210930/lib/libiscsi.def new/libiscsi-1.19.0+git.20220303/lib/libiscsi.def --- old/libiscsi-1.19.0+git.20210930/lib/libiscsi.def 2021-10-01 04:54:08.000000000 +0200 +++ new/libiscsi-1.19.0+git.20220303/lib/libiscsi.def 2022-03-03 21:58:08.000000000 +0100 @@ -2,6 +2,7 @@ EXPORTS iscsi_connect_async iscsi_connect_sync +iscsi_force_reconnect_sync iscsi_reconnect_sync iscsi_create_context iscsi_destroy_context @@ -10,6 +11,7 @@ iscsi_discovery_async iscsi_discovery_sync iscsi_free_discovery_data +iscsi_force_reconnect iscsi_full_connect_async iscsi_full_connect_sync iscsi_get_error @@ -283,4 +285,4 @@ scsi_task_set_iov_out scsi_version_to_str scsi_version_descriptor_to_str -win32_poll \ No newline at end of file +win32_poll diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libiscsi-1.19.0+git.20210930/lib/libiscsi.syms.in new/libiscsi-1.19.0+git.20220303/lib/libiscsi.syms.in --- old/libiscsi-1.19.0+git.20210930/lib/libiscsi.syms.in 2021-10-01 04:54:08.000000000 +0200 +++ new/libiscsi-1.19.0+git.20220303/lib/libiscsi.syms.in 2022-03-03 21:58:08.000000000 +0100 @@ -13,6 +13,8 @@ iscsi_extended_copy_sync iscsi_extended_copy_task iscsi_free_discovery_data +iscsi_force_reconnect +iscsi_force_reconnect_sync iscsi_full_connect_async iscsi_full_connect_sync iscsi_get_error diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libiscsi-1.19.0+git.20210930/lib/sync.c new/libiscsi-1.19.0+git.20220303/lib/sync.c --- old/libiscsi-1.19.0+git.20210930/lib/sync.c 2021-10-01 04:54:08.000000000 +0200 +++ new/libiscsi-1.19.0+git.20220303/lib/sync.c 2022-03-03 21:58:08.000000000 +0100 @@ -226,6 +226,22 @@ return (state.status == SCSI_STATUS_GOOD) ? 0 : -1; } +int iscsi_force_reconnect_sync(struct iscsi_context *iscsi) +{ + struct iscsi_sync_state state; + + memset(&state, 0, sizeof(state)); + + if (iscsi_force_reconnect(iscsi) != 0) { + iscsi_set_error(iscsi, "Failed to reconnect. %s", iscsi_get_error(iscsi)); + return -1; + } + + reconnect_event_loop(iscsi, &state); + + return (state.status == SCSI_STATUS_GOOD) ? 0 : -1; +} + static void iscsi_task_mgmt_sync_cb(struct iscsi_context *iscsi, int status, void *command_data, void *private_data) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libiscsi-1.19.0+git.20210930/utils/Makefile.am new/libiscsi-1.19.0+git.20220303/utils/Makefile.am --- old/libiscsi-1.19.0+git.20210930/utils/Makefile.am 2021-10-01 04:54:08.000000000 +0200 +++ new/libiscsi-1.19.0+git.20220303/utils/Makefile.am 2022-03-03 21:58:08.000000000 +0100 @@ -3,7 +3,7 @@ AM_LDFLAGS = -no-undefined LIBS = ../lib/libiscsi.la -bin_PROGRAMS = iscsi-inq iscsi-ls iscsi-swp +bin_PROGRAMS = iscsi-inq iscsi-ls iscsi-swp iscsi-pr if !TARGET_OS_IS_WIN32 bin_PROGRAMS += iscsi-perf iscsi-readcapacity16 endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libiscsi-1.19.0+git.20210930/utils/iscsi-pr.c new/libiscsi-1.19.0+git.20220303/utils/iscsi-pr.c --- old/libiscsi-1.19.0+git.20210930/utils/iscsi-pr.c 1970-01-01 01:00:00.000000000 +0100 +++ new/libiscsi-1.19.0+git.20220303/utils/iscsi-pr.c 2022-03-03 21:58:08.000000000 +0100 @@ -0,0 +1,485 @@ +/* + Copyright (C) 2022 by zhenwei pi<[email protected]> + + 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 <http://www.gnu.org/licenses/>. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <getopt.h> +#include <inttypes.h> +#include "iscsi.h" +#include "scsi-lowlevel.h" + +static void pr_in_read_keys(struct scsi_persistent_reserve_in_read_keys *rk) +{ + int i; + + printf(" PR generation=0x%x, %d registered reservation keys follow:\n", + rk->prgeneration, rk->num_keys); + for (i = 0; i < rk->num_keys; i++) { + printf(" 0x%" PRIx64 "\n", rk->keys[i]); + } +} + +static void pr_in_read_reservation(struct scsi_persistent_reserve_in_read_reservation *rr) +{ + printf(" PR generation=0x%x, Reservation follows:\n", rr->prgeneration); + if (!rr->reserved) { + return; + } + + printf(" Key=0x%" PRIx64 "\n", rr->reservation_key); + if (!rr->pr_scope) { + printf(" scope: LU_SCOPE, type: %s\n", scsi_pr_type_str(rr->pr_type)); + } else { + printf(" scope: %d, type: %s\n", + rr->pr_scope, scsi_pr_type_str(rr->pr_type)); + } +} + +static void pr_in_report_capabilities(struct scsi_persistent_reserve_in_report_capabilities *rc) +{ + uint16_t mask = (rc->persistent_reservation_type_mask & SCSI_PR_TYPE_MASK_ALL); + + printf("Report capabilities response:\n"); + printf(" Compatible Reservation Handling(CRH): 0x%x\n", rc->crh); + printf(" Specify Initiator Ports Capable(SIP_C): 0x%x\n", rc->sip_c); + printf(" All Target Ports Capable(ATP_C): 0x%x\n", rc->atp_c); + printf(" Persist Through Power Loss Capable(PTPL_C): 0x%x\n", rc->ptpl_c); + printf(" Type Mask Valid(TMV): 0x%x\n", rc->tmv); + printf(" Allow Commands: 0x%x\n", rc->allow_commands); + printf(" Persist Through Power Loss Active(PTPL_A): 0x%x\n", rc->ptpl_a); + printf(" Support indicated in Type mask:\n"); + if (mask & SCSI_PR_TYPE_MASK_EX_AC_AR) { + printf(" Exclusive Access, All Registrants\n"); + } + if (mask & SCSI_PR_TYPE_MASK_WR_EX) { + printf(" Write Exclusive\n"); + } + if (mask & SCSI_PR_TYPE_MASK_EX_AC) { + printf(" Write Exclusive, Registrants Only\n"); + } + if (mask & SCSI_PR_TYPE_MASK_WR_EX_RO) { + printf(" Exclusive Access Registrants Only\n"); + } + if (mask & SCSI_PR_TYPE_MASK_EX_AC_RO) { + printf(" Write Exclusive, All Registrants\n"); + } + if (mask & SCSI_PR_TYPE_MASK_WR_EX_AR) { + printf(" Exclusive Access, All Registrants\n"); + } +} + +static void do_pr_in(struct iscsi_context *iscsi, int lun, int sa) +{ + struct scsi_task *task; + int full_size; + void *blob; + + /* See how big this inquiry data is */ + task = iscsi_persistent_reserve_in_sync(iscsi, lun, sa, 1024); + if (task == NULL || task->status != SCSI_STATUS_GOOD) { + fprintf(stderr, "PR IN command failed : %s\n", iscsi_get_error(iscsi)); + exit(-1); + } + + full_size = scsi_datain_getfullsize(task); + if (full_size > task->datain.size) { + scsi_free_scsi_task(task); + + if ((task = iscsi_persistent_reserve_in_sync(iscsi, lun, sa, full_size)) == NULL) { + fprintf(stderr, "PR IN command failed : %s\n", iscsi_get_error(iscsi)); + exit(-1); + } + } + + blob = scsi_datain_unmarshall(task); + if (blob == NULL) { + fprintf(stderr, "failed to unmarshall PR IN blob\n"); + exit(-1); + } + + switch (sa) { + case SCSI_PERSISTENT_RESERVE_READ_KEYS: + pr_in_read_keys(blob); + break; + + case SCSI_PERSISTENT_RESERVE_READ_RESERVATION: + pr_in_read_reservation(blob); + break; + + case SCSI_PERSISTENT_RESERVE_REPORT_CAPABILITIES: + pr_in_report_capabilities(blob); + break; + + default: + fprintf(stderr, "Usupported PR IN sa: 0x%02x\n", sa); + } + + scsi_free_scsi_task(task); +} + +static const char *pr_out_sa_str(int sa) +{ + switch (sa) { + case SCSI_PERSISTENT_RESERVE_REGISTER: + return "register"; + case SCSI_PERSISTENT_RESERVE_RESERVE: + return "reserve"; + case SCSI_PERSISTENT_RESERVE_RELEASE: + return "release"; + case SCSI_PERSISTENT_RESERVE_CLEAR: + return "clear"; + case SCSI_PERSISTENT_RESERVE_PREEMPT: + return "preempt"; + case SCSI_PERSISTENT_RESERVE_PREEMPT_AND_ABORT: + return "preempt-and-abort"; + case SCSI_PERSISTENT_RESERVE_REGISTER_AND_IGNORE_EXISTING_KEY: + return "register-and-ignore-existing-key"; + case SCSI_PERSISTENT_RESERVE_REGISTER_AND_MOVE: + return "register-and-move"; + } + + return "Unknown SA"; +} + +static int do_pr_out_command(struct iscsi_context *iscsi, int lun, int sa, int type, uint64_t rk, uint64_t sark) +{ + struct scsi_task *task; + struct scsi_persistent_reserve_out_basic param = {0}; + + /* TODO other field in param */ + param.reservation_key = rk; + param.service_action_reservation_key = sark; + + task = iscsi_persistent_reserve_out_sync(iscsi, lun, sa, 0, type, ¶m); + if (task == NULL || task->status != SCSI_STATUS_GOOD) { + fprintf(stderr, "PR OUT command [%s] failed : %s\n", + pr_out_sa_str(sa), iscsi_get_error(iscsi)); + return -1; + } + + scsi_free_scsi_task(task); + + return 0; +} + +static void do_pr_out(struct iscsi_context *iscsi, int lun, int sa, int type, uint64_t rk, uint64_t sark, unsigned char remove) +{ + /* always do register */ + if ((do_pr_out_command(iscsi, lun, SCSI_PERSISTENT_RESERVE_REGISTER, type, 0, sark) < 0) + || sa == SCSI_PERSISTENT_RESERVE_REGISTER) { + return; + } + + /* clear all keys */ + if (sa == SCSI_PERSISTENT_RESERVE_CLEAR) { + rk = sark; + do_pr_out_command(iscsi, lun, sa, type, rk, sark); + return; + } + + if (sa == SCSI_PERSISTENT_RESERVE_RESERVE) { + rk = sark; + if (do_pr_out_command(iscsi, lun, sa, type, rk, sark)) { + goto remove_self_rk; + } else { + return; + } + } + + if (sa == SCSI_PERSISTENT_RESERVE_PREEMPT) { + if (do_pr_out_command(iscsi, lun, sa, type, sark, rk)) { + goto remove_self_rk; + } + + if (!remove) { + return; + } /* otherwise try to release */ + } + + if (sa == SCSI_PERSISTENT_RESERVE_RELEASE) { + rk = sark; + do_pr_out_command(iscsi, lun, sa, type, rk, sark); + goto remove_self_rk; + } + +remove_self_rk: + do_pr_out_command(iscsi, lun, SCSI_PERSISTENT_RESERVE_REGISTER, type, sark, 0); +} + +static void print_help(const char *bin) +{ + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: %s [OPTION...] <iscsi-url>\n", bin); + fprintf(stderr, " -i, --initiator-name=iqn-name Initiator name to use\n"); + fprintf(stderr, " -d, --debug Enable debug\n"); + fprintf(stderr, " -?, --help Show this help message\n"); + + fprintf(stderr, " -K, --param-rk=RK PR Out: parameter reservation key (RK is in hex)\n"); + fprintf(stderr, " -S, --param-sark=SARK PR Out: parameter service action reservation key (SARK is in hex)\n"); + fprintf(stderr, " -T, --prout-type=TYPE PR Out: type field\n"); + fprintf(stderr, " -G, --register PR Out: Register\n"); + fprintf(stderr, " -R, --reserve PR Out: Reserve, SARK only(register sark implicity)\n"); + fprintf(stderr, " -L, --release PR Out: Release, SARK only. This program releases TYPE 7 and TYPE 8 only\n"); + fprintf(stderr, " -C, --clear PR Out: Clear, SARK only\n"); + fprintf(stderr, " -P, --preempt PR Out: Preempt, use SARK to preempt reservation from RK\n"); + fprintf(stderr, " -X, --preempt-remove PR Out: Preempt, use SARK to preempt reservation from RK, then release SARK and remove SARK\n"); +#if 0 + fprintf(stderr, " -A, --preempt-abort PR Out: Preempt and Abort\n"); + fprintf(stderr, " -I, --register-ignore PR Out: Register and Ignore\n"); + fprintf(stderr, " -M, --register-move PR Out: Register and Move\n"); +#endif + fprintf(stderr, " -k, --read-keys PR In: Read Keys (default)\n"); + fprintf(stderr, " -r, --read-reservation PR In: Read Reservation\n"); + fprintf(stderr, " -c, --report-capabilities PR In: Report Capabilities\n"); + fprintf(stderr, " -s, --read-full-status PR In: Read Full Status\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "iSCSI URL format : %s\n", ISCSI_URL_SYNTAX); + fprintf(stderr, "<host> is either of:\n" + " \"hostname\" iscsi.example\n" + " \"ipv4-address\" 10.1.1.27\n" + " \"ipv6-address\" [fce0::1]\n\n"); + + fprintf(stderr, "PR Out TYPE field value meanings:\n" + " 0: obsolete (was 'read shared' in SPC)\n" + " 1: write exclusive\n" + " 2: obsolete (was 'read exclusive')\n" + " 3: exclusive access\n" + " 4: obsolete (was 'shared access')\n" + " 5: write exclusive, registrants only\n" + " 6: exclusive access, registrants only\n" + " 7: write exclusive, all registrants\n" + " 8: exclusive access, all registrants\n"); +} + +int main(int argc, char *argv[]) +{ + struct iscsi_context *iscsi; + struct iscsi_url *iscsi_url; + char *initiator = NULL; + char *url = NULL; + int debug = 0; + int c, opt; + int ret = -1; + int pr_operations = 0; + unsigned char pr_out = 1, remove = 0; + int sa = -1; + int type = 0; + uint64_t rk = 0, sark = 0; + + /* always keep aligned with sg_persist command */ + static struct option long_options[] = { + {"help", no_argument, NULL, 'h'}, + {"debug", no_argument, NULL, 'd'}, + {"initiator-name", required_argument, NULL, 'i'}, + {"param-rk", required_argument, NULL, 'K'}, + {"param-sark", required_argument, NULL, 'S'}, + {"prout-type", required_argument, NULL, 'T'}, + /* PR out, order by sa enum from spec */ + {"register", no_argument, NULL, 'G'}, + {"reserve", no_argument, NULL, 'R'}, + {"release", no_argument, NULL, 'L'}, + {"clear", no_argument, NULL, 'C'}, + {"preempt", no_argument, NULL, 'P'}, + {"preempt-remove", no_argument, NULL, 'X'}, +#if 0 + {"preempt-abort", no_argument, NULL, 'A'}, + {"register-ignore", no_argument, NULL, 'I'}, + {"register-move", no_argument, NULL, 'M'}, +#endif + /* PR in, order by sa enum from spec */ + {"read-keys", no_argument, NULL, 'k'}, + {"read-reservation", no_argument, NULL, 'r'}, + {"report-capabilities", no_argument, NULL, 'c'}, + {"read-full-status", no_argument, NULL, 's'}, + {0, 0, 0, 0} + }; + + while ((c = getopt_long(argc, argv, "hdHi:K:S:T:GRLCPXAIMkrcs", long_options, &opt)) != -1) { + switch (c) { + case 'd': + debug = 1; + break; + + case 'i': + initiator = optarg; + break; + + /* PR out */ + case 'K': + if (1 != sscanf(optarg, "%" SCNx64 "", &rk)) { + fprintf(stderr, "bad argument to '--param-rk'\n"); + return -1; + } + break; + + case 'S': + if (1 != sscanf(optarg, "%" SCNx64 "", &sark)) { + fprintf(stderr, "bad argument to '--param-sark'\n"); + return -1; + } + break; + + case 'T': + type = atoi(optarg); + break; + + case 'G': + sa = SCSI_PERSISTENT_RESERVE_REGISTER; + pr_operations++; + break; + + case 'R': + sa = SCSI_PERSISTENT_RESERVE_RESERVE; + pr_operations++; + break; + + case 'L': + sa = SCSI_PERSISTENT_RESERVE_RELEASE; + pr_operations++; + break; + + case 'C': + sa = SCSI_PERSISTENT_RESERVE_CLEAR; + pr_operations++; + break; + + case 'P': + sa = SCSI_PERSISTENT_RESERVE_PREEMPT; + pr_operations++; + break; + + case 'X': + remove = 1; + sa = SCSI_PERSISTENT_RESERVE_PREEMPT; + pr_operations++; + break; + +#if 0 + case 'A': + sa = SCSI_PERSISTENT_RESERVE_PREEMPT_AND_ABORT; + pr_operations++; + break; + + case 'I': + sa = SCSI_PERSISTENT_RESERVE_REGISTER_AND_IGNORE_EXISTING_KEY; + pr_operations++; + break; + + case 'M': + sa = SCSI_PERSISTENT_RESERVE_REGISTER_AND_MOVE; + pr_operations++; + break; +#endif + + /* PR in */ + case 'k': + pr_out = 0; + sa = SCSI_PERSISTENT_RESERVE_READ_KEYS; + pr_operations++; + break; + + case 'r': + pr_out = 0; + sa = SCSI_PERSISTENT_RESERVE_READ_RESERVATION; + pr_operations++; + break; + + case 'c': + pr_out = 0; + sa = SCSI_PERSISTENT_RESERVE_REPORT_CAPABILITIES; + pr_operations++; + break; + + case 's': + pr_out = 0; + sa = SCSI_PERSISTENT_RESERVE_READ_FULL_STATUS; + pr_operations++; + break; + + case 'h': + case '?': + default: + print_help(argv[0]); + exit(0); + } + } + + if ((pr_operations != 1) || (sa == -1)) { + fprintf(stderr, "You must specify one Persistent Reservation operation\n"); + print_help(argv[0]); + exit(-1); + } + + if (initiator == NULL) { + fprintf(stderr, "You must specify initiator by -i/--initiator-name\n"); + exit(-1); + } + + iscsi = iscsi_create_context(initiator); + if (iscsi == NULL) { + fprintf(stderr, "Failed to create context\n"); + exit(-1); + } + + if (debug > 0) { + iscsi_set_log_level(iscsi, debug); + iscsi_set_log_fn(iscsi, iscsi_log_to_stderr); + } + + if (argv[optind] != NULL) { + url = argv[optind]; + } else { + fprintf(stderr, "You must specify the URL\n"); + print_help(argv[0]); + return -1; + } + + iscsi_url = iscsi_parse_full_url(iscsi, url); + if (iscsi_url == NULL) { + fprintf(stderr, "Failed to parse URL: %s\n", iscsi_get_error(iscsi)); + goto destroy_context; + } + + iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL); + iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); + if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) { + fprintf(stderr, "Login Failed. %s\n", iscsi_get_error(iscsi)); + goto destroy_url; + } + + if (pr_out) { + do_pr_out(iscsi, iscsi_url->lun, sa, type, rk, sark, remove); + } else { + do_pr_in(iscsi, iscsi_url->lun, sa); + } + + /* finish successfully */ + ret = 0; + iscsi_logout_sync(iscsi); + +destroy_url: + iscsi_destroy_url(iscsi_url); + +destroy_context: + iscsi_destroy_context(iscsi); + + return ret; +} ++++++ libiscsi.obsinfo ++++++ --- /var/tmp/diff_new_pack.nYvLrr/_old 2022-03-18 16:41:43.933163973 +0100 +++ /var/tmp/diff_new_pack.nYvLrr/_new 2022-03-18 16:41:43.941163979 +0100 @@ -1,6 +1,5 @@ name: libiscsi -version: 1.19.0+git.20210930 -mtime: 1633056848 -commit: 97d2f681d7d434b166114a031fb3eb4aec97affd - +version: 1.19.0+git.20220303 +mtime: 1646341088 +commit: 2674070fb80ad7527589a1fbd576ee074d26ed72
