xref: /aosp_15_r20/external/sg3_utils/src/sg_emc_trespass.c (revision 44704f698541f6367e81f991ef8bb54ccbf3fc18)
1*44704f69SBart Van Assche /* The program allows the user to send a trespass command to change the
2*44704f69SBart Van Assche  * LUN ownership from one Service-Processor to this one on an EMC
3*44704f69SBart Van Assche  * CLARiiON and potentially other devices.
4*44704f69SBart Van Assche  *
5*44704f69SBart Van Assche  * Copyright (C) 2004-2018 Lars Marowsky-Bree <[email protected]>
6*44704f69SBart Van Assche  *
7*44704f69SBart Van Assche  * Based on sg_start.c; credits from there also apply.
8*44704f69SBart Van Assche  * Minor modifications for sg_lib, D. Gilbert 2004/10/19
9*44704f69SBart Van Assche  *
10*44704f69SBart Van Assche  *  This program is free software; you can redistribute it and/or modify
11*44704f69SBart Van Assche  *  it under the terms of the GNU General Public License as published by
12*44704f69SBart Van Assche  *  the Free Software Foundation; either version 2, or (at your option)
13*44704f69SBart Van Assche  *  any later version.
14*44704f69SBart Van Assche  *
15*44704f69SBart Van Assche  * SPDX-License-Identifier: GPL-2.0-or-later
16*44704f69SBart Van Assche  */
17*44704f69SBart Van Assche 
18*44704f69SBart Van Assche #include <stdio.h>
19*44704f69SBart Van Assche #include <stdlib.h>
20*44704f69SBart Van Assche #include <unistd.h>
21*44704f69SBart Van Assche #include <stdlib.h>
22*44704f69SBart Van Assche #include <stdarg.h>
23*44704f69SBart Van Assche #include <stdbool.h>
24*44704f69SBart Van Assche #include <string.h>
25*44704f69SBart Van Assche #include <sys/types.h>
26*44704f69SBart Van Assche #include <sys/stat.h>
27*44704f69SBart Van Assche #include <fcntl.h>
28*44704f69SBart Van Assche 
29*44704f69SBart Van Assche #ifdef HAVE_CONFIG_H
30*44704f69SBart Van Assche #include "config.h"
31*44704f69SBart Van Assche #endif
32*44704f69SBart Van Assche #include "sg_lib.h"
33*44704f69SBart Van Assche #include "sg_cmds_basic.h"
34*44704f69SBart Van Assche #include "sg_pr2serr.h"
35*44704f69SBart Van Assche 
36*44704f69SBart Van Assche 
37*44704f69SBart Van Assche static const char * version_str = "0.23 20180219";
38*44704f69SBart Van Assche 
39*44704f69SBart Van Assche static int debug = 0;
40*44704f69SBart Van Assche 
41*44704f69SBart Van Assche #define TRESPASS_PAGE           0x22
42*44704f69SBart Van Assche 
43*44704f69SBart Van Assche static int
do_trespass(int fd,bool hr,bool short_cmd)44*44704f69SBart Van Assche do_trespass(int fd, bool hr, bool short_cmd)
45*44704f69SBart Van Assche {
46*44704f69SBart Van Assche         uint8_t long_trespass_pg[] =
47*44704f69SBart Van Assche                 { 0, 0, 0, 0, 0, 0, 0, 0x00,
48*44704f69SBart Van Assche                   TRESPASS_PAGE,        /* Page code */
49*44704f69SBart Van Assche                   0x09,                 /* Page length - 2 */
50*44704f69SBart Van Assche                   0x81,                 /* Trespass code + Honor reservation
51*44704f69SBart Van Assche                                          * bit */
52*44704f69SBart Van Assche                   0xff, 0xff,           /* Trespass target */
53*44704f69SBart Van Assche                   0, 0, 0, 0, 0, 0      /* Reserved bytes / unknown */
54*44704f69SBart Van Assche         };
55*44704f69SBart Van Assche         uint8_t short_trespass_pg[] =
56*44704f69SBart Van Assche                 { 0, 0, 0, 0,
57*44704f69SBart Van Assche                   TRESPASS_PAGE,        /* Page code */
58*44704f69SBart Van Assche                   0x02,                 /* Page length - 2 */
59*44704f69SBart Van Assche                   0x81,                 /* Trespass code + Honor reservation
60*44704f69SBart Van Assche                                          * bit */
61*44704f69SBart Van Assche                   0xff,                 /* Trespass target */
62*44704f69SBart Van Assche         };
63*44704f69SBart Van Assche         int res;
64*44704f69SBart Van Assche         char b[80];
65*44704f69SBart Van Assche 
66*44704f69SBart Van Assche         if (hr) {       /* override Trespass code + Honor reservation bit */
67*44704f69SBart Van Assche                 short_trespass_pg[6] = 0x01;
68*44704f69SBart Van Assche                 long_trespass_pg[10] = 0x01;
69*44704f69SBart Van Assche         }
70*44704f69SBart Van Assche         if (short_cmd)
71*44704f69SBart Van Assche                 res = sg_ll_mode_select6(fd, true /* pf */, false /* sp */,
72*44704f69SBart Van Assche                                  short_trespass_pg, sizeof(short_trespass_pg),
73*44704f69SBart Van Assche                                  true, (debug ? 2 : 0));
74*44704f69SBart Van Assche         else
75*44704f69SBart Van Assche                 res = sg_ll_mode_select10(fd, true /* pf */, false /* sp */,
76*44704f69SBart Van Assche                                  long_trespass_pg, sizeof(long_trespass_pg),
77*44704f69SBart Van Assche                                  true, (debug ? 2 : 0));
78*44704f69SBart Van Assche 
79*44704f69SBart Van Assche         switch (res) {
80*44704f69SBart Van Assche         case 0:
81*44704f69SBart Van Assche                 if (debug)
82*44704f69SBart Van Assche                         pr2serr("%s trespass successful\n",
83*44704f69SBart Van Assche                                 short_cmd ? "short" : "long");
84*44704f69SBart Van Assche                 break;
85*44704f69SBart Van Assche         case SG_LIB_CAT_INVALID_OP:
86*44704f69SBart Van Assche         case SG_LIB_CAT_ILLEGAL_REQ:
87*44704f69SBart Van Assche                 pr2serr("%s form trepass page failed, try again %s '-s' "
88*44704f69SBart Van Assche                         "option\n", short_cmd ? "short" : "long",
89*44704f69SBart Van Assche                         short_cmd ? "without" : "with");
90*44704f69SBart Van Assche                 break;
91*44704f69SBart Van Assche         case SG_LIB_CAT_NOT_READY:
92*44704f69SBart Van Assche                 pr2serr("device not ready\n");
93*44704f69SBart Van Assche                 break;
94*44704f69SBart Van Assche         case SG_LIB_CAT_UNIT_ATTENTION:
95*44704f69SBart Van Assche                 pr2serr("unit attention\n");
96*44704f69SBart Van Assche                 break;
97*44704f69SBart Van Assche         default:
98*44704f69SBart Van Assche                 sg_get_category_sense_str(res, sizeof(b), b, debug);
99*44704f69SBart Van Assche                 pr2serr("%s trespass failed: %s\n",
100*44704f69SBart Van Assche                         (short_cmd ? "short" : "long"), b);
101*44704f69SBart Van Assche                 break;
102*44704f69SBart Van Assche         }
103*44704f69SBart Van Assche         return res;
104*44704f69SBart Van Assche }
105*44704f69SBart Van Assche 
usage()106*44704f69SBart Van Assche void usage ()
107*44704f69SBart Van Assche {
108*44704f69SBart Van Assche         pr2serr("Usage:  sg_emc_trespass [-d] [-hr] [-s] [-V] DEVICE\n"
109*44704f69SBart Van Assche                 "  Change ownership of a LUN from another SP to this one.\n"
110*44704f69SBart Van Assche                 "  EMC CLARiiON CX-/AX-family + FC5300/FC4500/FC4700.\n"
111*44704f69SBart Van Assche                 "    -d : output debug\n"
112*44704f69SBart Van Assche                 "    -hr: Set Honor Reservation bit\n"
113*44704f69SBart Van Assche                 "    -s : Send Short Trespass Command page (default: long)\n"
114*44704f69SBart Van Assche                 "         (for FC series)\n"
115*44704f69SBart Van Assche                 "    -V: print version string then exit\n"
116*44704f69SBart Van Assche                 "     DEVICE   sg or block device (latter in lk 2.6 or lk 3 "
117*44704f69SBart Van Assche                 "series)\n"
118*44704f69SBart Van Assche                 "        Example: sg_emc_trespass /dev/sda\n");
119*44704f69SBart Van Assche         exit (1);
120*44704f69SBart Van Assche }
121*44704f69SBart Van Assche 
main(int argc,char * argv[])122*44704f69SBart Van Assche int main(int argc, char * argv[])
123*44704f69SBart Van Assche {
124*44704f69SBart Van Assche         char **argptr;
125*44704f69SBart Van Assche         char * file_name = 0;
126*44704f69SBart Van Assche         int k, fd;
127*44704f69SBart Van Assche         bool hr = false;
128*44704f69SBart Van Assche         bool short_cmd = false;
129*44704f69SBart Van Assche         int ret = 0;
130*44704f69SBart Van Assche 
131*44704f69SBart Van Assche         if (argc < 2)
132*44704f69SBart Van Assche                 usage ();
133*44704f69SBart Van Assche 
134*44704f69SBart Van Assche         for (k = 1; k < argc; ++k) {
135*44704f69SBart Van Assche                 argptr = argv + k;
136*44704f69SBart Van Assche                 if (!strcmp (*argptr, "-d"))
137*44704f69SBart Van Assche                         ++debug;
138*44704f69SBart Van Assche                 else if (!strcmp (*argptr, "-s"))
139*44704f69SBart Van Assche                         short_cmd = true;
140*44704f69SBart Van Assche                 else if (!strcmp (*argptr, "-hr"))
141*44704f69SBart Van Assche                         hr = true;
142*44704f69SBart Van Assche                 else if (!strcmp (*argptr, "-V")) {
143*44704f69SBart Van Assche                         printf("Version string: %s\n", version_str);
144*44704f69SBart Van Assche                         exit(0);
145*44704f69SBart Van Assche                 }
146*44704f69SBart Van Assche                 else if (*argv[k] == '-') {
147*44704f69SBart Van Assche                         pr2serr("Unrecognized switch: %s\n", argv[k]);
148*44704f69SBart Van Assche                         file_name = NULL;
149*44704f69SBart Van Assche                         break;
150*44704f69SBart Van Assche                 }
151*44704f69SBart Van Assche                 else if (NULL == file_name)
152*44704f69SBart Van Assche                         file_name = argv[k];
153*44704f69SBart Van Assche                 else {
154*44704f69SBart Van Assche                         pr2serr("too many arguments\n");
155*44704f69SBart Van Assche                         file_name = NULL;
156*44704f69SBart Van Assche                         break;
157*44704f69SBart Van Assche                 }
158*44704f69SBart Van Assche         }
159*44704f69SBart Van Assche         if (NULL == file_name) {
160*44704f69SBart Van Assche                 usage();
161*44704f69SBart Van Assche                 return SG_LIB_SYNTAX_ERROR;
162*44704f69SBart Van Assche         }
163*44704f69SBart Van Assche 
164*44704f69SBart Van Assche         fd = open(file_name, O_RDWR | O_NONBLOCK);
165*44704f69SBart Van Assche         if (fd < 0) {
166*44704f69SBart Van Assche                 pr2serr("Error trying to open %s\n", file_name);
167*44704f69SBart Van Assche                 perror("");
168*44704f69SBart Van Assche                 usage();
169*44704f69SBart Van Assche                 return SG_LIB_FILE_ERROR;
170*44704f69SBart Van Assche         }
171*44704f69SBart Van Assche 
172*44704f69SBart Van Assche         ret = do_trespass(fd, hr, short_cmd);
173*44704f69SBart Van Assche 
174*44704f69SBart Van Assche         close (fd);
175*44704f69SBart Van Assche         return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
176*44704f69SBart Van Assche }
177