aboutsummaryrefslogtreecommitdiff
path: root/src/sg_emc_trespass.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sg_emc_trespass.c')
-rw-r--r--src/sg_emc_trespass.c176
1 files changed, 176 insertions, 0 deletions
diff --git a/src/sg_emc_trespass.c b/src/sg_emc_trespass.c
new file mode 100644
index 00000000..146e26b2
--- /dev/null
+++ b/src/sg_emc_trespass.c
@@ -0,0 +1,176 @@
+/* The program allows the user to send a trespass command to change the
+ * LUN ownership from one Service-Processor to this one on an EMC
+ * CLARiiON and potentially other devices.
+ *
+ * Copyright (C) 2004-2018 Lars Marowsky-Bree <lmb@suse.de>
+ *
+ * Based on sg_start.c; credits from there also apply.
+ * Minor modifications for sg_lib, D. Gilbert 2004/10/19
+ *
+ * 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, or (at your option)
+ * any later version.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "sg_lib.h"
+#include "sg_cmds_basic.h"
+#include "sg_pr2serr.h"
+
+
+static const char * version_str = "0.23 20180219";
+
+static int debug = 0;
+
+#define TRESPASS_PAGE 0x22
+
+static int
+do_trespass(int fd, bool hr, bool short_cmd)
+{
+ uint8_t long_trespass_pg[] =
+ { 0, 0, 0, 0, 0, 0, 0, 0x00,
+ TRESPASS_PAGE, /* Page code */
+ 0x09, /* Page length - 2 */
+ 0x81, /* Trespass code + Honor reservation
+ * bit */
+ 0xff, 0xff, /* Trespass target */
+ 0, 0, 0, 0, 0, 0 /* Reserved bytes / unknown */
+ };
+ uint8_t short_trespass_pg[] =
+ { 0, 0, 0, 0,
+ TRESPASS_PAGE, /* Page code */
+ 0x02, /* Page length - 2 */
+ 0x81, /* Trespass code + Honor reservation
+ * bit */
+ 0xff, /* Trespass target */
+ };
+ int res;
+ char b[80];
+
+ if (hr) { /* override Trespass code + Honor reservation bit */
+ short_trespass_pg[6] = 0x01;
+ long_trespass_pg[10] = 0x01;
+ }
+ if (short_cmd)
+ res = sg_ll_mode_select6(fd, true /* pf */, false /* sp */,
+ short_trespass_pg, sizeof(short_trespass_pg),
+ true, (debug ? 2 : 0));
+ else
+ res = sg_ll_mode_select10(fd, true /* pf */, false /* sp */,
+ long_trespass_pg, sizeof(long_trespass_pg),
+ true, (debug ? 2 : 0));
+
+ switch (res) {
+ case 0:
+ if (debug)
+ pr2serr("%s trespass successful\n",
+ short_cmd ? "short" : "long");
+ break;
+ case SG_LIB_CAT_INVALID_OP:
+ case SG_LIB_CAT_ILLEGAL_REQ:
+ pr2serr("%s form trepass page failed, try again %s '-s' "
+ "option\n", short_cmd ? "short" : "long",
+ short_cmd ? "without" : "with");
+ break;
+ case SG_LIB_CAT_NOT_READY:
+ pr2serr("device not ready\n");
+ break;
+ case SG_LIB_CAT_UNIT_ATTENTION:
+ pr2serr("unit attention\n");
+ break;
+ default:
+ sg_get_category_sense_str(res, sizeof(b), b, debug);
+ pr2serr("%s trespass failed: %s\n",
+ (short_cmd ? "short" : "long"), b);
+ break;
+ }
+ return res;
+}
+
+void usage ()
+{
+ pr2serr("Usage: sg_emc_trespass [-d] [-hr] [-s] [-V] DEVICE\n"
+ " Change ownership of a LUN from another SP to this one.\n"
+ " EMC CLARiiON CX-/AX-family + FC5300/FC4500/FC4700.\n"
+ " -d : output debug\n"
+ " -hr: Set Honor Reservation bit\n"
+ " -s : Send Short Trespass Command page (default: long)\n"
+ " (for FC series)\n"
+ " -V: print version string then exit\n"
+ " DEVICE sg or block device (latter in lk 2.6 or lk 3 "
+ "series)\n"
+ " Example: sg_emc_trespass /dev/sda\n");
+ exit (1);
+}
+
+int main(int argc, char * argv[])
+{
+ char **argptr;
+ char * file_name = 0;
+ int k, fd;
+ bool hr = false;
+ bool short_cmd = false;
+ int ret = 0;
+
+ if (argc < 2)
+ usage ();
+
+ for (k = 1; k < argc; ++k) {
+ argptr = argv + k;
+ if (!strcmp (*argptr, "-d"))
+ ++debug;
+ else if (!strcmp (*argptr, "-s"))
+ short_cmd = true;
+ else if (!strcmp (*argptr, "-hr"))
+ hr = true;
+ else if (!strcmp (*argptr, "-V")) {
+ printf("Version string: %s\n", version_str);
+ exit(0);
+ }
+ else if (*argv[k] == '-') {
+ pr2serr("Unrecognized switch: %s\n", argv[k]);
+ file_name = NULL;
+ break;
+ }
+ else if (NULL == file_name)
+ file_name = argv[k];
+ else {
+ pr2serr("too many arguments\n");
+ file_name = NULL;
+ break;
+ }
+ }
+ if (NULL == file_name) {
+ usage();
+ return SG_LIB_SYNTAX_ERROR;
+ }
+
+ fd = open(file_name, O_RDWR | O_NONBLOCK);
+ if (fd < 0) {
+ pr2serr("Error trying to open %s\n", file_name);
+ perror("");
+ usage();
+ return SG_LIB_FILE_ERROR;
+ }
+
+ ret = do_trespass(fd, hr, short_cmd);
+
+ close (fd);
+ return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
+}