aboutsummaryrefslogtreecommitdiffstats
path: root/mover.c
diff options
context:
space:
mode:
authorkraxel <kraxel>2005-02-09 11:34:37 +0000
committerkraxel <kraxel>2005-02-09 11:34:37 +0000
commit73671a2f4f0e6e03a509ff5a97ab70d7b0db12b1 (patch)
treed0099f50705e45392d9666c0aaa64bd69fc18b32 /mover.c
parent92a99fec1e7c0c05568a3abd647c9ae781acbd2f (diff)
downloadscsi-changer-73671a2f4f0e6e03a509ff5a97ab70d7b0db12b1.tar.gz
- add files to repository.
Diffstat (limited to 'mover.c')
-rw-r--r--mover.c367
1 files changed, 367 insertions, 0 deletions
diff --git a/mover.c b/mover.c
new file mode 100644
index 0000000..8866abe
--- /dev/null
+++ b/mover.c
@@ -0,0 +1,367 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+
+#include "chio.h"
+
+#define CHANGER "/dev/sch0"
+
+/* ---------------------------------------------------------------------- */
+
+struct changer_params params;
+struct changer_vendor_params vparams;
+
+int
+parse_arg(char *arg, int *type, int *nr)
+{
+ char t;
+
+ if (NULL == arg)
+ return -1;
+ if (2 != sscanf(arg,"%c%i",&t,nr))
+ return -1;
+ switch (t) {
+ case 'm':
+ case 'M': *type = CHET_MT; break;
+ case 's':
+ case 'S': *type = CHET_ST; break;
+ case 'e':
+ case 'E': *type = CHET_IE; break;
+ case 'd':
+ case 'D': *type = CHET_DT; break;
+ case 'v':
+ case 'V': *type = CHET_V1; break;
+ case 'w':
+ case 'W': *type = CHET_V2; break;
+ case 'x':
+ case 'X': *type = CHET_V3; break;
+ case 'y':
+ case 'Y': *type = CHET_V4; break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+static void
+print_stat(int fd, int type, int count)
+{
+ struct changer_element_status ces;
+ struct changer_get_element elinfo;
+ int i,rc;
+
+ switch (type) {
+ case CHET_MT: printf("medium transport\n"); break;
+ case CHET_ST: printf("storage\n"); break;
+ case CHET_IE: printf("import/export\n"); break;
+ case CHET_DT: printf("data transfer\n"); break;
+ case CHET_V1:
+ printf("vendor specific #1 [%s]\n",vparams.cvp_label1);
+ break;
+ case CHET_V2:
+ printf("vendor specific #2 [%s]\n",vparams.cvp_label2);
+ break;
+ case CHET_V3:
+ printf("vendor specific #3 [%s]\n",vparams.cvp_label3);
+ break;
+ case CHET_V4:
+ printf("vendor specific #4 [%s]\n",vparams.cvp_label4);
+ break;
+ }
+
+ ces.ces_type = type;
+ ces.ces_data = malloc(count);
+ rc = ioctl(fd,CHIOGSTATUS,&ces);
+ if (rc) {
+ fprintf(stderr,"ioctl failed (GSTATUS): %s\n",strerror(errno));
+ exit(1);
+ }
+ for (i = 0; i < count; i++) {
+ printf(" %2d: ",i);
+ if (ces.ces_data[i] & CESTATUS_INENAB) printf("inenab ");
+ if (ces.ces_data[i] & CESTATUS_EXENAB) printf("exenab ");
+ if (ces.ces_data[i] & CESTATUS_ACCESS) printf("access ");
+ if (ces.ces_data[i] & CESTATUS_EXCEPT) printf("except ");
+ if (ces.ces_data[i] & CESTATUS_IMPEXP) printf("impexp ");
+ if (ces.ces_data[i] & CESTATUS_FULL) printf("full ");
+
+ memset(&elinfo,0,sizeof(elinfo));
+ elinfo.cge_type = type;
+ elinfo.cge_unit = i;
+
+ rc = ioctl(fd,CHIOGELEM,&elinfo);
+ if (rc) {
+ fprintf(stderr,"ioctl failed (GELEM): %s\n",strerror(errno));
+ exit(1);
+ }
+
+ if (elinfo.cge_flags & CGE_PVOLTAG && strlen(elinfo.cge_pvoltag) > 0 ) {
+ printf("\ttag: '%s'",elinfo.cge_pvoltag);
+ } else
+ if (ces.ces_data[i] & CESTATUS_FULL)
+ printf("\t(no volume tag)");
+
+
+ printf("\n");
+ }
+ free(ces.ces_data);
+}
+
+/* ---------------------------------------------------------------------- */
+
+int
+main(int argc, char *argv[])
+{
+ int fd,rc;
+
+ if (-1 == (fd = open(CHANGER,O_RDONLY))) {
+ perror("open");
+ exit(1);
+ }
+
+ rc = ioctl(fd,CHIOGPARAMS,&params);
+ if (rc) {
+ fprintf(stderr,"ioctl failed (GPARAMS): %s\n",strerror(errno));
+ exit(1);
+ } else {
+ printf(CHANGER ": mt=%i st=%i ie=%i dt=%i\n",
+ params.cp_npickers,params.cp_nslots,
+ params.cp_nportals,params.cp_ndrives);
+ }
+ rc = ioctl(fd,CHIOGVPARAMS,&vparams);
+ if (rc) {
+ fprintf(stderr,"ioctl failed (VPARAMS): %s\n",strerror(errno));
+ } else {
+ if (vparams.cvp_n1)
+ printf(CHANGER ": v1=%d [%s]\n",vparams.cvp_n1,vparams.cvp_label1);
+ if (vparams.cvp_n2)
+ printf(CHANGER ": v2=%d [%s]\n",vparams.cvp_n2,vparams.cvp_label2);
+ if (vparams.cvp_n3)
+ printf(CHANGER ": v3=%d [%s]\n",vparams.cvp_n3,vparams.cvp_label3);
+ if (vparams.cvp_n4)
+ printf(CHANGER ": v4=%d [%s]\n",vparams.cvp_n4,vparams.cvp_label4);
+ }
+
+ if (argc == 1 || 0 == strcasecmp(argv[1],"status")) {
+ /* no args, so print some status informations */
+ print_stat(fd,CHET_MT,params.cp_npickers);
+ print_stat(fd,CHET_ST,params.cp_nslots);
+ print_stat(fd,CHET_IE,params.cp_nportals);
+ print_stat(fd,CHET_DT,params.cp_ndrives);
+ if (vparams.cvp_n1)
+ print_stat(fd,CHET_V1,vparams.cvp_n1);
+ if (vparams.cvp_n2)
+ print_stat(fd,CHET_V2,vparams.cvp_n2);
+ if (vparams.cvp_n3)
+ print_stat(fd,CHET_V3,vparams.cvp_n3);
+ if (vparams.cvp_n4)
+ print_stat(fd,CHET_V4,vparams.cvp_n4);
+ exit(0);
+ }
+
+ if (0 == strcasecmp(argv[1],"pos")) {
+ struct changer_position pos;
+
+ memset(&pos,0,sizeof(pos));
+ if (-1 == parse_arg(argv[2],&pos.cp_type,&pos.cp_unit)) {
+ fprintf(stderr,"slot arg parse error (POSITION)\n");
+ exit(1);
+ }
+ if (argc > 3)
+ pos.cp_flags = atoi(argv[3]);
+ rc = ioctl(fd,CHIOPOSITION,&pos);
+ if (rc) {
+ fprintf(stderr,"ioctl failed (POSITION): %s\n",
+ strerror(errno));
+ exit(1);
+ }
+
+ } else if (0 == strcasecmp(argv[1],"load") ||
+ 0 == strcasecmp(argv[1],"unload")) {
+ struct changer_move move;
+
+ memset(&move,0,sizeof(move));
+ if (0 == strcasecmp(argv[1],"load")) {
+ move.cm_fromtype = CHET_ST;
+ move.cm_fromunit = atoi(argv[2]);
+ move.cm_totype = CHET_DT;
+ move.cm_tounit = 0;
+ } else {
+ if (argc > 2) {
+ move.cm_totype = CHET_ST;
+ move.cm_tounit = atoi(argv[2]);
+ } else {
+ struct changer_get_element elinfo;
+ memset(&elinfo,0,sizeof(elinfo));
+ elinfo.cge_type = CHET_DT;
+ elinfo.cge_unit = 0;
+ rc = ioctl(fd,CHIOGELEM,&elinfo);
+ if (rc) {
+ fprintf(stderr,"ioctl failed (GELEM): %s\n",
+ strerror(errno));
+ exit(1);
+ }
+ if (!(elinfo.cge_flags & CGE_SRC)) {
+ fprintf(stderr,"element source info not available\n");
+ exit(1);
+ }
+ move.cm_totype = elinfo.cge_srctype;
+ move.cm_tounit = elinfo.cge_srcunit;
+ if (elinfo.cge_flags & CGE_INVERT)
+ move.cm_flags |= CE_INVERT1;
+ }
+ move.cm_fromtype = CHET_DT;
+ move.cm_fromunit = 0;
+ }
+ rc = ioctl(fd,CHIOMOVE,&move);
+ if (rc) {
+ fprintf(stderr,"ioctl failed (MOVE): %s\n",
+ strerror(errno));
+ exit(1);
+ }
+
+ } else if (0 == strcasecmp(argv[1],"mv")) {
+ struct changer_move move;
+
+ memset(&move,0,sizeof(move));
+ if (-1 == parse_arg(argv[2],&move.cm_fromtype,&move.cm_fromunit) ||
+ -1 == parse_arg(argv[3],&move.cm_totype, &move.cm_tounit )) {
+ fprintf(stderr,"slot arg parse error (MOVE)\n");
+ exit(1);
+ }
+ if (argc > 4)
+ move.cm_flags = atoi(argv[4]);
+ rc = ioctl(fd,CHIOMOVE,&move);
+ if (rc) {
+ fprintf(stderr,"ioctl failed (MOVE): %s\n",
+ strerror(errno));
+ exit(1);
+ }
+
+ } else if (0 == strcasecmp(argv[1],"ex")) {
+ struct changer_exchange xchg;
+
+ memset(&xchg,0,sizeof(xchg));
+ if (-1 == parse_arg(argv[2],&xchg.ce_srctype, &xchg.ce_srcunit ) ||
+ -1 == parse_arg(argv[3],&xchg.ce_fdsttype,&xchg.ce_fdstunit) ||
+ -1 == parse_arg(argv[4],&xchg.ce_sdsttype,&xchg.ce_sdstunit)) {
+ fprintf(stderr,"slot arg parse error (EXCHANGE)\n");
+ exit(1);
+ }
+ if (argc > 5)
+ xchg.ce_flags = atoi(argv[5]);
+ rc = ioctl(fd,CHIOEXCHANGE,&xchg);
+ if (rc) {
+ fprintf(stderr,"ioctl failed (EXCHANGE): %s\n",
+ strerror(errno));
+ exit(1);
+ }
+
+ } else if (0 == strcasecmp(argv[1],"info")) {
+ struct changer_get_element elinfo;
+
+ memset(&elinfo,0,sizeof(elinfo));
+ if (-1 == parse_arg(argv[2],&elinfo.cge_type, &elinfo.cge_unit)) {
+ fprintf(stderr,"slot arg parse error (INFO)\n");
+ exit(1);
+ }
+ rc = ioctl(fd,CHIOGELEM,&elinfo);
+ if (rc) {
+ fprintf(stderr,"ioctl failed (INFO): %s\n",
+ strerror(errno));
+ exit(1);
+ }
+
+ printf("status : ");
+ if (elinfo.cge_status & CESTATUS_INENAB) printf("inenab ");
+ if (elinfo.cge_status & CESTATUS_EXENAB) printf("exenab ");
+ if (elinfo.cge_status & CESTATUS_ACCESS) printf("access ");
+ if (elinfo.cge_status & CESTATUS_EXCEPT) printf("except ");
+ if (elinfo.cge_status & CESTATUS_IMPEXP) printf("impexp ");
+ if (elinfo.cge_status & CESTATUS_FULL) printf("full ");
+ printf("\n");
+
+ if (elinfo.cge_flags & CGE_ERRNO) {
+ printf("error : %s\n",strerror(elinfo.cge_errno));
+ }
+ if (elinfo.cge_flags & CGE_SRC) {
+ printf("source : ");
+ switch (elinfo.cge_srctype) {
+ case CHET_MT: printf("m"); break;
+ case CHET_ST: printf("s"); break;
+ case CHET_IE: printf("e"); break;
+ case CHET_DT: printf("d"); break;
+ case CHET_V1: printf("v"); break;
+ case CHET_V2: printf("w"); break;
+ case CHET_V3: printf("x"); break;
+ case CHET_V4: printf("y"); break;
+ }
+ printf("%d",elinfo.cge_srcunit);
+ if (elinfo.cge_flags & CGE_INVERT)
+ printf(" (rotated)");
+ printf("\n");
+ }
+ if (elinfo.cge_flags & CGE_IDLUN) {
+ printf("scsi id : %d\n",elinfo.cge_id);
+ printf("scsi lun: %d\n",elinfo.cge_lun);
+ }
+ if (elinfo.cge_flags & CGE_PVOLTAG) {
+ printf("pvoltag : %32.32s\n",elinfo.cge_pvoltag);
+ }
+ if (elinfo.cge_flags & CGE_AVOLTAG) {
+ printf("avoltag : %32.32s\n",elinfo.cge_avoltag);
+ }
+
+ } else if (0 == strcasecmp(argv[1],"init")) {
+ rc = ioctl(fd,CHIOINITELEM,NULL);
+ if (rc) {
+ fprintf(stderr,"ioctl failed (INITELEM): %s\n",
+ strerror(errno));
+ exit(1);
+ }
+
+ } else if (0 == strcasecmp(argv[1],"settag") ||
+ 0 == strcasecmp(argv[1],"cleartag")) {
+ struct changer_set_voltag tag;
+
+ memset(&tag,0,sizeof(tag));
+ if (-1 == parse_arg(argv[2],&tag.csv_type,&tag.csv_unit)) {
+ fprintf(stderr,"slot arg parse error (SVOLTAG)\n");
+ exit(1);
+ }
+ if (argc <= 3) {
+ fprintf(stderr,"no type (pri | alt) given\n");
+ exit(1);
+ }
+ if (0 == strcasecmp(argv[3],"pri"))
+ tag.csv_flags |= CSV_PVOLTAG;
+ if (0 == strcasecmp(argv[3],"alt"))
+ tag.csv_flags |= CSV_AVOLTAG;
+ if (0 == strcasecmp(argv[1],"cleartag")) {
+ tag.csv_flags |= CSV_CLEARTAG;
+ } else {
+ if (argc <= 4) {
+ fprintf(stderr,"no volume tag given\n");
+ exit(1);
+ }
+ strncpy(tag.csv_voltag,argv[4],32);
+ }
+ rc = ioctl(fd,CHIOSVOLTAG,&tag);
+ if (rc) {
+ fprintf(stderr,"ioctl failed (SVOLTAG): %s\n",
+ strerror(errno));
+ exit(1);
+ }
+
+ } else {
+ printf("%s: unknown argument\n",argv[1]);
+ exit(1);
+ }
+
+ close(fd);
+ exit(0);
+}