From e94be4b2a1c8504a615108f617881eaa7745961a Mon Sep 17 00:00:00 2001 From: kraxel Date: Wed, 9 Feb 2005 12:01:53 +0000 Subject: - add misc files. --- misc/errno | 9 ++ misc/sense | 5 + todo/autojuke.c | 355 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ todo/mailtext | 29 +++++ todo/putback | 43 +++++++ todo/putback.c | 100 ++++++++++++++++ 6 files changed, 541 insertions(+) create mode 100644 misc/errno create mode 100644 misc/sense create mode 100644 todo/autojuke.c create mode 100644 todo/mailtext create mode 100644 todo/putback create mode 100644 todo/putback.c diff --git a/misc/errno b/misc/errno new file mode 100644 index 0000000..a13069e --- /dev/null +++ b/misc/errno @@ -0,0 +1,9 @@ +from /usr/src/linux/include/asm/errno.h +seems they are for media changer devices... + +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ diff --git a/misc/sense b/misc/sense new file mode 100644 index 0000000..5c2a3a5 --- /dev/null +++ b/misc/sense @@ -0,0 +1,5 @@ +felix kraxel /usr/src/linux/drivers/scsi# grep ",M," constants.c + {0x21,0x01,M,"Invalid element address"}, + {0x28,0x01,M,"Import or export element accessed"}, + {0x3B,0x0D,M,"Medium destination element full"}, + {0x3B,0x0E,M,"Medium source element empty"}, diff --git a/todo/autojuke.c b/todo/autojuke.c new file mode 100644 index 0000000..f6aa0b5 --- /dev/null +++ b/todo/autojuke.c @@ -0,0 +1,355 @@ +/* + * program "map-file" for linux autofs + * + * usage: /usr/sbin/automount /jukebox program /usr/sbin/autojuke + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define PROG "autojuke" +#define CHANGER "/dev/sch0" +#define CONFIG "/etc/autojuke.conf" +#define PID "/var/run/automount.pid" + +#define DEBUG 0 /* set to 1 for debug output */ + +/* ---------------------------------------------------------------------- */ + +int +check_mtab(int n, char **devs) +{ + int i,res; + FILE *fp; + struct stat st; + char line[79],dev[32]; + int *fl; + + /* check for lock file */ + for (i = 0; i < 5; i++) { + if (-1 == stat("/etc/mtab~",&st)) + break; + sleep(1); + } + if (5 == i) { + fprintf(stderr,PROG ": /etc/mtab locked\n"); + exit(1); + } + + if (NULL == (fp = fopen("/etc/mtab", "r"))) { + perror(PROG ": open /etc/mtab"); + exit(1); + } + fl = malloc(n*sizeof(int)); + memset(fl,0,n*sizeof(int)); + while (NULL != fgets(line,79,fp)) { + sscanf(line," %31s",dev); + for (i = 0; i < n; i++) { + if (0 == strcmp(dev,devs[i])) + fl[i] = 1; + } + } + res = -1; + for (i = 0; i < n; i++) { + if (0 == fl[i]) + res = i; + } + free(fl); + fclose(fp); + return res; +} + +int +getautopid() +{ + FILE *fp; + char line[80]; + int pid = -1; + + if (NULL == (fp = fopen(PID, "r"))) { + perror(PROG ": open " PID); + exit(1); + } + + if (NULL != fgets(line, 79, fp)) { + pid = atoi(line); + } + + fclose(fp); + return pid; +} + +void +getSlotandSide(char *line, int *slot, int *side) +{ + int i; + int l = strlen(line) - 1; + + if ((l < 1) || (l > 2)) { + fprintf(stderr, PROG ": invalid requested slot or side, %s", line); + exit(1); + } + + for (i = 0; i < l; i++) { + if (!isdigit(line[i])) { + fprintf(stderr, PROG ": invalid requested slot or side, %s", line); + exit(1); + } + } + + if ((line[l] != 'a') && (line[l] != 'b')) { + fprintf(stderr, PROG ": invalid requested slot or side, %s", line); + exit(1); + } + + *side = (line[l] == 'b'); + line[l] = 0; + /*bm>*/ + *slot = atoi(line); + /*= params.cp_nslots) { + fprintf(stderr,PROG ": slot %d is out of range\n",slot); + exit(1); + } + +#if DEBUG + fprintf(stderr,PROG ": slot %d side %d\n", slot, side); +#endif + + /* check drives */ + for (drive = -1, i = 0; i < params.cp_ndrives; i++) { + if ((dt[i].cge_status & CESTATUS_FULL) && + (dt[i].cge_flags & CGE_SRC) && + (dt[i].cge_srctype == CHET_ST) && + (dt[i].cge_srcunit == slot)) { + drive = i; + break; + } + } + + if (-1 != drive) { + /* Requested media is still in a drive. Do we need to flip it? */ + cside = ((dt[drive].cge_flags & CGE_INVERT) == CGE_INVERT); + + /* if current side is requested side do nothing otherwise attempt invert */ + if (cside != side) { + /* ok attempt to unmount the disk */ + if (0 != check_mtab(1, &devs[drive])) { +#if DEBUG + fprintf(stderr,PROG ": sending SIGUSR1 to automount\n"); +#endif + kill(getautopid(), SIGUSR1); + sleep(1); /* XXX */ + if (0 != check_mtab(1, &devs[drive])) { + fprintf(stderr,PROG ": drive is busy with disk %d on other side\n",slot); + exit(1); + } + } + + /* flip the disk */ + memset(&move,0,sizeof(struct changer_move)); + + move.cm_totype = CHET_DT; + move.cm_tounit = drive; + move.cm_fromtype = CHET_DT; + move.cm_fromunit = drive; + move.cm_flags = CM_INVERT; + + if (ioctl(fd,CHIOMOVE,&move)) { + fprintf(stderr,PROG ": ioctl MOVE (load): %s\n", + sys_errlist[errno]); + exit(1); + } + } + + /* tell automounter we are good to go */ + printf("%s\t:%s\n",mopt,devs[drive]); + exit(0); + } + + /* verify info for the slot */ + st.cge_type=CHET_ST; + st.cge_unit=slot; + if (ioctl(fd,CHIOGELEM,&st)) { + fprintf(stderr,PROG ": ioctl CHIOGELEM st %d: %s\n", + slot,strerror(errno)); + exit(1); + } + + if (!(st.cge_status & CESTATUS_FULL)) { + fprintf(stderr,PROG ": slot %d has no media\n",slot); + exit(1); + } + + /* ok, requested media found, check where to put it now */ + + /* look for a empty drive first... */ + for (i = 0, drive = -1; i < params.cp_ndrives; i++) { + if (!(dt[i].cge_status & CESTATUS_FULL)) { + drive = i; + break; + } + } + + if (-1 == drive) + /* failing that, look for a unmounted drive */ + drive = check_mtab(params.cp_ndrives,devs); + + if (-1 == drive && try_umount) { + /* still no success -- tell automount to umount idle mount-points */ +#if DEBUG + fprintf(stderr,PROG ": sending SIGUSR1 to automount\n"); +#endif + /*kill(getppid(), SIGUSR1); */ + kill(getautopid(), SIGUSR1); + sleep(1); /* XXX */ + drive = check_mtab(params.cp_ndrives,devs); + } + + if (-1 == drive) { + /* bad luck */ + fprintf(stderr,PROG ": all drives busy, sorry\n"); + exit(1); + } + + if (dt[drive].cge_status & CESTATUS_FULL) { + /* Hmm, full. Ok, put back the old media ... */ + if (!(dt[drive].cge_flags & CGE_SRC)) { + fprintf(stderr,PROG ": source element for drive %d unknown\n", + drive); + exit(1); + } + memset(&move,0,sizeof(struct changer_move)); + move.cm_totype = dt[drive].cge_srctype; + move.cm_tounit = dt[drive].cge_srcunit; + move.cm_fromtype = CHET_DT; + move.cm_fromunit = drive; + /*bm>*/ + cside = ((dt[drive].cge_flags & CGE_INVERT) == CGE_INVERT); + move.cm_flags = (cside == 0) ? 0 : CM_INVERT; + /**/ + /* if current side is not requested side invert*/ + move.cm_flags = (0 == side) ? 0 : CM_INVERT; + /* +Subject: Re: SCSI-Changer +To: Gerd Knorr + +Hi! + +So, da das System jetzt (bei uns) ganz gut zu funktionieren scheint, +hier +nochmal die von mir modifizierten Dateien. + +Bei autojuke.c habe ich gegenüber +der letzten Version nur die "sleep 8"s herausgenommen, die übrigen +Änderungen gegenüber der Version von Elis Pomales sind zwischen +den Marken /*bm>*/ bzw. /* +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define PROG "putback" +#define CHANGER "/dev/sch0" + +#define DEBUG 0 /* set to 1 for debug output */ + +/* ---------------------------------------------------------------------- */ + +int main(int argc, char *argv[]) +{ + struct changer_params params; + struct changer_get_element *dt; + struct changer_move move; + char *h; + int fd,i,drive,cside; + + if (argc != 1) { + fprintf(stderr,"Usage: %s\n",argv[0]); + exit(1); + } + + if (-1 == (fd = open(CHANGER,O_RDONLY))) { + perror(PROG ": open " CHANGER); + exit(1); + } + + /* read changer status information */ + if (ioctl(fd,CHIOGPARAMS,¶ms)) { + perror(PROG ": ioctl CHIOGPARAMS"); + exit(1); + } +#if DEBUG + fprintf(stderr,PROG ": %d drives, %d slots\n", + params.cp_ndrives,params.cp_nslots); +#endif + + dt = malloc(sizeof(struct changer_get_element)*params.cp_ndrives); + for (i = 0; i < params.cp_ndrives; i++) { + dt[i].cge_type=CHET_DT; + dt[i].cge_unit=i; + if (ioctl(fd,CHIOGELEM,dt+i)) { + fprintf(stderr,PROG ":ioctl CHIOGELEM mt %d: %s\n", + i,strerror(errno)); + exit(1); + } + if (NULL != (h = strchr(dt[i].cge_pvoltag,' '))) *h = '\0'; + if (NULL != (h = strchr(dt[i].cge_avoltag,' '))) *h = '\0'; + } + + + for (drive=0; drive