diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2007-09-10 00:54:57 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2007-09-10 00:54:57 +0000 |
commit | 7b165064d3d22cf8e699935bccef0e728857c4eb (patch) | |
tree | ec1fd18a51e9cef40fb333366a13796592bdceda /src/sg_emc_trespass.c | |
parent | 6716cee810f1680cefe477e0b8e191c3321cd3b7 (diff) | |
download | sg3_utils-7b165064d3d22cf8e699935bccef0e728857c4eb.tar.gz |
rearrange files into include, src, lib and doc directories
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@100 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src/sg_emc_trespass.c')
-rw-r--r-- | src/sg_emc_trespass.c | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/src/sg_emc_trespass.c b/src/sg_emc_trespass.c new file mode 100644 index 00000000..6f270000 --- /dev/null +++ b/src/sg_emc_trespass.c @@ -0,0 +1,165 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.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" + +/* 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 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. + */ + +static char * version_str = "0.16 20070714"; + +static int debug = 0; + +#define TRESPASS_PAGE 0x22 + +static int do_trespass(int fd, int hr, int short_cmd) +{ + unsigned char 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 */ + }; + unsigned char 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; + + 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, 1 /* pf */, 0 /* sp */, + short_trespass_pg, sizeof(short_trespass_pg), + 1, (debug ? 2 : 0)); + else + res = sg_ll_mode_select10(fd, 1 /* pf */, 0 /* sp */, + long_trespass_pg, sizeof(long_trespass_pg), + 1, (debug ? 2 : 0)); + + switch (res) { + case 0: + if (debug) + fprintf(stderr, "%s trespass successful\n", + short_cmd ? "short" : "long"); + break; + case SG_LIB_CAT_INVALID_OP: + case SG_LIB_CAT_ILLEGAL_REQ: + fprintf(stderr, "%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: + fprintf(stderr, "device not ready\n"); + break; + case SG_LIB_CAT_UNIT_ATTENTION: + fprintf(stderr, "unit attention\n"); + break; + default: + if (debug) + fprintf(stderr, "%s trespass failed\n", + short_cmd ? "short" : "long"); + break; + } + return res; +} + +void usage () +{ + fprintf(stderr, "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.*)\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; + int hr = 0; + int short_cmd = 0; + 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 = 1; + else if (!strcmp (*argptr, "-hr")) + hr = 1; + else if (!strcmp (*argptr, "-V")) { + printf("Version string: %s\n", version_str); + exit(0); + } + else if (*argv[k] == '-') { + fprintf(stderr, "Unrecognized switch: %s\n", argv[k]); + file_name = 0; + break; + } + else if (0 == file_name) + file_name = argv[k]; + else { + fprintf(stderr, "too many arguments\n"); + file_name = 0; + break; + } + } + if (0 == file_name) { + usage(); + return SG_LIB_SYNTAX_ERROR; + } + + fd = open(file_name, O_RDWR | O_NONBLOCK); + if (fd < 0) { + fprintf(stderr, "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; +} |