📄 scsi-changer-driver.c
字号:
intdrive_loaded( int fd, int drivenum){ extern OpenFiles_T *pDev; DebugPrint(DEBUG_INFO,SECTION_TAPE,_("###### START drive_loaded\n")); DebugPrint(DEBUG_INFO,SECTION_TAPE, _(" drive_loaded : fd %d drivenum %d \n"), fd, drivenum); if (ElementStatusValid == 0) { if (pDev[INDEX_CHANGER].functions->function_status(INDEX_CHANGER, 1) != 0) { DebugPrint(DEBUG_ERROR,SECTION_TAPE,_("Fatal error\n")); return(-1); /*NOTREACHED*/ } } if (pDTE[drivenum].status == 'E') { DebugPrint(DEBUG_INFO,SECTION_TAPE,_("###### STOP drive_loaded (empty)\n")); return(0); /*NOTREACHED*/ } DebugPrint(DEBUG_INFO,SECTION_TAPE,_("###### STOP drive_loaded (not empty)\n")); return(1);}/* * unload the specified drive into the specified slot * (storage element) * * TODO: * Check if the MTE is empty */intunload( int fd, int drive, int slot){ extern OpenFiles_T *pDev; extern int do_inventory; MBC_T *pbarcoderes; DebugPrint(DEBUG_INFO, SECTION_TAPE,_("###### START unload\n")); DebugPrint(DEBUG_INFO, SECTION_TAPE, _(" unload : fd %d, slot %d, drive %d \n"), fd, slot, drive); pbarcoderes = alloc(SIZEOF(MBC_T)); memset(pbarcoderes, 0, SIZEOF(MBC_T)); /* * If the Element Status is not valid try to * init it */ if (ElementStatusValid == 0) { if (pDev[INDEX_CHANGER].functions->function_status(INDEX_CHANGER , 1) != 0) { DebugPrint(DEBUG_ERROR, SECTION_TAPE,_("Element Status not valid, reset failed\n")); DebugPrint(DEBUG_ERROR, SECTION_TAPE,_("##### STOP unload (-1)\n")); free(pbarcoderes); return(-1); /*NOTREACHED*/ } } DebugPrint(DEBUG_INFO, SECTION_TAPE, _(" unload : unload drive %d[%d] slot %d[%d]\n"), drive, pDTE[drive].address, slot, pSTE[slot].address); /* * Unloading an empty tape unit makes no sense * so return with an error */ if (pDTE[drive].status == 'E') { DebugPrint(DEBUG_ERROR, SECTION_TAPE,_("unload : Drive %d address %d is empty\n"), drive, pDTE[drive].address); DebugPrint(DEBUG_ERROR, SECTION_TAPE,_("##### STOP unload (-1)\n")); free(pbarcoderes); return(-1); /*NOTREACHED*/ } /* * If the destination slot is full * try to find an enpty slot */ if (pSTE[slot].status == 'F') { DebugPrint(DEBUG_INFO, SECTION_TAPE,_("unload : Slot %d address %d is full\n"), drive, pSTE[slot].address); if ( ElementStatusValid == 0) { DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, _("unload: Element Status not valid, can't find an empty slot\n")); free(pbarcoderes); return(-1); /*NOTREACHED*/ } slot = find_empty(fd, 0, 0); if (slot == -1 ) { DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, _("unload: No Empty slot found\n")); free(pbarcoderes); return(-1); /*NOTREACHED*/ } DebugPrint(DEBUG_INFO, SECTION_TAPE,_("unload : found empty one, try to unload to slot %d\n"), slot); } /* * If eject is not set we must read the label info */ if (changer->eject == 0) { if (pDev[INDEX_TAPE].avail == 1 && (changer->emubarcode == 1 || BarCode(INDEX_CHANGER))) { if (pDev[INDEX_TAPECTL].SCSI == 1 && pDev[INDEX_TAPECTL].avail) { pDev[INDEX_TAPECTL].functions->function_rewind(INDEX_TAPECTL); } else { pDev[INDEX_TAPE].functions->function_rewind(INDEX_TAPE); } if (pDev[INDEX_TAPE].devopen == 1) { SCSI_CloseDevice(INDEX_TAPE); } chgscsi_result = (char *)tape_rdlabel(pDev[INDEX_TAPE].dev, &chgscsi_datestamp, &chgscsi_label); } } /* * Do the unload/move */ if (pDev[INDEX_CHANGER].functions->function_move(INDEX_CHANGER, pDTE[drive].address, pSTE[slot].address) != 0) { DebugPrint(DEBUG_ERROR, SECTION_TAPE,_("##### STOP unload (-1 move failed)\n")); free(pbarcoderes); return(-1); /*NOTREACHED*/ } /* * Update the Status */ if (pDev[INDEX_CHANGER].functions->function_status(INDEX_CHANGER , 1) != 0) { DebugPrint(DEBUG_ERROR, SECTION_TAPE,_("##### STOP unload (-1 update status failed)\n")); free(pbarcoderes); return(-1); /*NOTREACHED*/ } /* * Did we get an error from tape_rdlabel * if no update the vol/label mapping * If chgscsi_label is NULL don't do it */ if (chgscsi_result == NULL && chgscsi_label != NULL && changer->labelfile != NULL) { /* * OK this is only needed if we have emubarcode set * There we need an exact inventory to get the search function working * and returning correct results */ if (BarCode(INDEX_CHANGER) == 0 && changer->emubarcode == 1) { /* * We got something, update the db * but before check if the db has as entry the slot * to where we placed the tape, if no force an inventory */ pbarcoderes->action = FIND_SLOT; strncpy(pbarcoderes->data.voltag, chgscsi_label, SIZEOF(pbarcoderes->data.voltag)); strncpy(pbarcoderes->data.barcode, pSTE[slot].VolTag, SIZEOF(pbarcoderes->data.barcode)); pbarcoderes->data.slot = 0; pbarcoderes->data.from = 0; pbarcoderes->data.LoadCount = 0; if ( MapBarCode(changer->labelfile, pbarcoderes) == 0) /* Nothing known about this, do an Inventory */ { do_inventory = 1; } else { if (slot != pbarcoderes->data.slot) { DebugPrint(DEBUG_ERROR, SECTION_TAPE,_("Slot DB out of sync, slot %d != map %d"),slot, pbarcoderes->data.slot); do_inventory = 1; } } } } DebugPrint(DEBUG_INFO, SECTION_TAPE,_("##### STOP unload(0)\n")); free(pbarcoderes); return(0);}/* * load the media from the specified element (slot) into the * specified data transfer unit (drive) * fd -> pointer to the internal device structure pDev * driver -> which drive in the library * slot -> the slot number from where to load * * return -> 0 = success * !0 = failure */intload( int fd, int drive, int slot){ char *result = NULL; /* Needed for the result of tape_rdlabel */ int ret; extern OpenFiles_T *pDev; extern int do_inventory; MBC_T *pbarcoderes; DebugPrint(DEBUG_INFO, SECTION_ELEMENT,_("###### START load\n")); DebugPrint(DEBUG_INFO, SECTION_ELEMENT,_("%-20s : fd %d, drive %d, slot %d \n"), "load", fd, drive, slot); pbarcoderes = alloc(SIZEOF(MBC_T)); memset(pbarcoderes, 0 , SIZEOF(MBC_T)); if (ElementStatusValid == 0) { if (pDev[fd].functions->function_status(fd, 1) != 0) { DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,_("##### STOP load (-1)\n")); DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,_("##### STOP load (-1 update status failed)\n")); free(pbarcoderes); return(-1); /*NOTREACHED*/ } } /* * Check if the requested slot is in the range of available slots * The library starts counting at 1, we start at 0, so if the request slot * is ge than the value we got from the ModeSense fail with an return value * of 2 */ if ((size_t)slot >= STE) { DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,_("load : slot %d ge STE %d\n"),slot, STE); ChgExit("load", _("slot >= STE"), FATAL); /*NOTREACHED*/ } /* * And the same for the tape drives */ if (drive >= (int)DTE) { DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,_("load : drive %d ge DTE %d\n"),drive, DTE); ChgExit("load", _("drive >= DTE"), FATAL); /*NOTREACHED*/ } DebugPrint(DEBUG_INFO, SECTION_ELEMENT,_("load : load drive %d[%d] slot %d[%d]\n"),drive, pDTE[drive].address, slot, pSTE[slot].address); if (pDTE[drive].status == 'F') { DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,_("load : Drive %d address %d is full\n"), drive, pDTE[drive].address); DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,_("##### STOP load (-1 update status failed)\n")); free(pbarcoderes); return(-1); /*NOTREACHED*/ } if (pSTE[slot].status == 'E') { DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,_("load : Slot %d address %d is empty\n"), drive, pSTE[slot].address); DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,_("##### STOP load (-1 update status failed)\n")); free(pbarcoderes); return(-1); /*NOTREACHED*/ } ret = pDev[fd].functions->function_move(fd, pSTE[slot].address, pDTE[drive].address); /* * Update the Status */ if (pDev[fd].functions->function_status(fd, 1) != 0) { DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,_("##### STOP load (-1 update status failed)\n")); free(pbarcoderes); return(-1); /*NOTREACHED*/ } /* * Try to read the label * and update the label/slot database */ if (pDev[INDEX_TAPE].avail == 1 && (changer->emubarcode == 1 || BarCode(INDEX_CHANGER))) { if (pDev[INDEX_TAPECTL].SCSI == 1 && pDev[INDEX_TAPECTL].avail) { pDev[INDEX_TAPECTL].functions->function_rewind(INDEX_TAPECTL); } else { pDev[INDEX_TAPE].functions->function_rewind(INDEX_TAPE); } if (pDev[INDEX_TAPE].devopen == 1) { SCSI_CloseDevice(INDEX_TAPE); } result = (char *)tape_rdlabel(pDev[INDEX_TAPE].dev, &chgscsi_datestamp, &chgscsi_label); } /* * Did we get an error from tape_rdlabel * if no update the vol/label mapping */ if (result == NULL && changer->labelfile != NULL && chgscsi_label != NULL ) { /* * We got something, update the db * but before check if the db has as entry the slot * to where we placed the tape, if no force an inventory */ strncpy(pbarcoderes->data.voltag, chgscsi_label, SIZEOF(pbarcoderes->data.voltag)); pbarcoderes->data.slot = 0; pbarcoderes->data.from = 0; pbarcoderes->data.LoadCount = 0; /* * If we have an barcode reader we only do an update * If emubarcode is set we check if the * info in the DB is up to date, if no we set the do_inventory flag */ if (BarCode(INDEX_CHANGER) == 1 && changer->emubarcode == 0) { pbarcoderes->action = UPDATE_SLOT; strncpy(pbarcoderes->data.barcode, pDTE[drive].VolTag, SIZEOF(pbarcoderes->data.barcode)); pbarcoderes->data.LoadCount = 1; pbarcoderes->data.slot = slot; MapBarCode(changer->labelfile, pbarcoderes); } if (BarCode(INDEX_CHANGER) == 0 && changer->emubarcode == 1) { pbarcoderes->action = FIND_SLOT; if (MapBarCode(changer->labelfile, pbarcoderes) == 0) /* Nothing found, do an inventory */ { do_inventory = 1; } else { /* We got something, is it correct ? */ if (slot != pbarcoderes->data.slot && do_inventory == 0) { DebugPrint(DEBUG_ERROR, SECTION_TAPE,_("Slot DB out of sync, slot %d != map %d"),slot, pbarcoderes->data.slot); ChgExit("Load", _("Label DB out of sync"), FATAL); /*NOTREACHED*/ } else { /* OK, so increment the load count */ pbarcoderes->action = UPDATE_SLOT; pbarcoderes->data.LoadCount = 1; pbarcoderes->data.slot = slot; MapBarCode(changer->labelfile, pbarcoderes); } } } if (BarCode(INDEX_CHANGER) == 1 && changer->emubarcode == 1) { ChgExit("Load", _("BarCode == 1 and emubarcode == 1"), FATAL); /*NOTREACHED*/ } DebugPrint(DEBUG_INFO, SECTION_ELEMENT,_("##### STOP load (%d)\n"),ret); free(pbarcoderes); return(ret); /*NOTREACHED*/ } DebugPrint(DEBUG_INFO, SECTION_ELEMENT,_("##### STOP load (%d)\n"),ret); free(pbarcoderes); return(ret);}/* * Returns the number of Storage Slots which the library has * fd -> pointer to the internal devie structure pDev * return -> Number of slots */intget_slot_count( int fd){ extern OpenFiles_T *pDev; DebugPrint(DEBUG_INFO, SECTION_ELEMENT,_("###### START get_slot_count\n")); DebugPrint(DEBUG_INFO, SECTION_ELEMENT,_("%-20s : fd %d\n"), "get_slot_count", fd); if (ElementStatusValid == 0) { pDev[fd].functions->function_status(fd, 1); } DebugPrint(DEBUG_INFO, SECTION_ELEMENT, _("##### STOP get_slot_count (%zu)\n"), STE); return((ssize_t)STE); /* * return the number of slots in the robot * to the caller */}/* * retreive the number of data-transfer devices /Tape drives) * fd -> pointer to the internal devie structure pDev * return -> -1 on failure */intget_drive_count( int fd){ extern OpenFiles_T *pDev; DebugPrint(DEBUG_INFO, SECTION_SCSI,_("###### START get_drive_count\n")); DebugPrint(DEBUG_INFO, SECTION_SCSI,_("%-20s : fd %d\n"), "get_drive_count", fd); if (ElementStatusValid == 0) { if ( pDev[fd].functions->function_status(fd, 1) != 0) { DebugPrint(DEBUG_ERROR, SECTION_SCSI, _("Error getting drive count\n")); DebugPrint(DEBUG_ERROR, SECTION_SCSI, _("##### STOP get_drive_count (-1)\n")); return(-1); /*NOTREACHED*/ } } DebugPrint(DEBUG_INFO, SECTION_SCSI, _("###### STOP get_drive_count (%zu drives)\n"), DTE); return((ssize_t)DTE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -