⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scsi-changer-driver.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Print the scsi-changer-driver version */voidChangerDriverVersion(void){  DebugPrint(DEBUG_ERROR, SECTION_INFO, "scsi-changer-driver: %s\n",rcsid);  SCSI_OS_Version();}/* * Try to generate an template which can be used as an example for the config file * */voidPrintConf(void){  extern OpenFiles_T *pDev;  int count;  char *cwd;  g_printf(_("# Please replace every ??? with the correct parameter.\n"));  g_printf(_("# It is not possible to guess everything :-)\n"));  g_printf(_("# Remove the line if the option is not needed."));  g_printf(_("#   Example: cleanmax if you have no cleaning tape"));  g_printf(_("#\n"));  g_printf(_(   "number_configs  1 # Number of configs, you can have more than 1 config\n"   "                  # if you have for example more than one drive, or you\n"   "                  # to split your lib to use different dump levels\n"   "                  #\n"));  g_printf(_(   "emubarcode      1 # If you drive has no barcode reader this will try\n"   "                  # keep an inventory of your tapes to find them faster\n"   "                  #\n"));  g_printf(_(   "havebarcode     0 # Set this to 1 if you have a library with a\n"   "                  # barcode reader\n"   "                  #\n"));  g_printf(_(   "debuglevel    0:0 # For debuging, see the docs /docs/TAPE-CHANGER\n"   "                  #\n"));  g_printf(_(   "eject         ??? # set this to 1 if your drive needs an eject before move\n"   "                  #\n"));  g_printf(_(   "sleep         ??? # How long to wait after an eject command before moving\n"   "                  # the tape\n"   "                  #\n"));  for (count = 0; count < CHG_MAXDEV ; count++)    {      if (pDev[count].dev)	{	  if (pDev[count].inquiry != NULL && pDev[count].inquiry->type == TYPE_CHANGER)	    {	      g_printf(_("changerdev   %s # This is the device to communicate with the robot\n"), pDev[count].dev);	      break;	    }	}    }  /*   * Did we reach the end of the list ?   * If no we found an changer and now we try to   * get the element status for the count of slots   */  if (count < CHG_MAXDEV)    {      pDev[count].functions->function_status(count, 1);    } else {      g_printf(_("changerdev ???       # Ups nothing found. Please check the docs\n"));    }  g_printf(_(   "                     #\n"));  g_printf(_(   "                     # Here now comes the config for the first tape\n"));  g_printf(_(   "config             0 # This value is the one which is used in the amanda\n"   "                     # config file to tell the chg-scsi programm which tape\n"   "                     # and which slots to use\n"   "                     #\n"));  g_printf(_(   "cleancart        ??? # The slot where the cleaning tape is located\n"   "                     # remove it if you have no cleaning tape\n"   "                     #\n"));  g_printf(_(   "drivenum           0 # Which tape drive to use if there are more than one drive\n"   "                     #\n"));  g_printf(_(   "dev              ??? # Which is the raw device to read/write data from the tape\n"   "                     # It is important to use the non rewinding tape, like\n"   "                     # /dev/nrst0 on linux, /dev/nrsa0 on BSD ....\n"   "                     #\n"));  /*   * OK now lets see if we have an direct SCSI channel   * to the tape   * If not thats not a problem   */  for (count = 0; count < CHG_MAXDEV; count++)    {      if (pDev[count].dev)	{	  if (pDev[count].inquiry != NULL && pDev[count].inquiry->type == TYPE_TAPE)	    {	      g_printf(_(		"scsitapedev   %s # This is the device to communicate with the tape\n"	        "                 # to get some device stats, not so important, and\n"	        "                 # if you run into problems delete it completely\n"	        "                 #\n"), pDev[count].dev);	      break;	    }	}    }  if (STE != 0)    {      g_printf(_(	"startuse          0  # Which is the first slot to use\n"	"                     #\n"));      g_printf(_(	"enduse            %zu  # Which is the last slot to use.\n"), STE);    } else {      g_printf(_(	"startuse         ??? # Which is the first slot to use\n"	"                     #\n"));      g_printf(_(	"enduse           ??? # Which is the last slot to use.\n"));    }    g_printf(_(	"                     # Decrement this value by 1 if you have a\n"	"                     # cleaning tape in the last slot\n"	"                     #\n"));  if ((cwd = getcwd(NULL, 0)) == NULL) {      cwd = _("<unknown>");  }  g_printf(_("statfile %s/tape0-slot #\n"),cwd);  g_printf(_("cleanfile %s/tape0-clean #\n"), cwd);  g_printf(_("usagecount %s/tape0-totaltime #\n"), cwd);  g_printf(_("tapestatus %s/tape0-tapestatus #\n"), cwd);  g_printf(_("labelfile %s/labelfile #\n"), cwd);}/* * Try to create a list of tapes and labels which are in the current * magazin. The drive must be empty !! * * labelfile -> file name of the db * drive -> which drive should we use * eject -> the tape device needs an eject before move * start -> start at slot start * stop  -> stop at slot stop * clean -> if we have an cleaning tape than this is the slot number of it * * return * 0  -> fail * 1  -> successfull * * ToDo: * Check if the tape/changer is ready for the next move * If an tape is loaded unload it and do initialize element status to * get all labels if an bar code reader is installed */voidInventory(    char *	labelfile,    int		drive,    int		eject,    int		start,    int		stop,    int		clean){  extern OpenFiles_T *pDev;  size_t x;  static int inv_done = 0;	/* Inventory function called ?, marker to disable recursion */  MBC_T *pbarcoderes;		/* Here we will pass the parameter to MapBarCode and get the result */  (void)start;	/* Quiet unused parameter warning */  (void)stop;	/* Quiet unused parameter warning */  DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE, _("##### START Inventory\n"));  pbarcoderes = alloc(SIZEOF(MBC_T));  memset(pbarcoderes, 0 , SIZEOF(MBC_T));  if (inv_done != 0)    {      DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE, _("##### STOP inv_done -> %d Inventory\n"),inv_done);      free(pbarcoderes);      return;      /*NOTREACHED*/    }  inv_done = 1;  barcode = BarCode(INDEX_CHANGER);  pbarcoderes->action = RESET_VALID;  MapBarCode(labelfile,pbarcoderes);  /*   * Check if an tape is loaded, if yes unload it   * and do an INIT ELEMENT STATUS   */  if (pDTE[0].status == 'F')    {      if (eject)	{	  (void)eject_tape("", eject);	}      (void)unload(INDEX_TAPE, 0, 0);    }  GenericResetStatus(INDEX_CHANGER);  for (x = 0; x < STE; x++)    {      if (x == (size_t)clean)	{	  continue;	}      /*       * Load the tape, on error try the next       * error could be an empty slot for example       */      if (load(INDEX_CHANGER, drive, x ) != 0)	{	  DebugPrint(DEBUG_ERROR,SECTION_MAP_BARCODE, _("Load drive(%d) from(%d) failed\n"), drive, x);	  continue;	}      /*       * Wait until the tape is ready       */      Tape_Ready(INDEX_TAPECTL, 60);      SCSI_CloseDevice(INDEX_TAPE);      if ((chgscsi_result = (char *)tape_rdlabel(pDev[INDEX_TAPE].dev, &chgscsi_datestamp, &chgscsi_label)) == NULL)      {	pbarcoderes->action = UPDATE_SLOT;	strncpy(pbarcoderes->data.voltag, chgscsi_label,		SIZEOF(pbarcoderes->data.voltag));	pbarcoderes->data.slot = x;	pbarcoderes->data.from = 0;	pbarcoderes->data.LoadCount = 1;	if (BarCode(INDEX_CHANGER) == 1)	  {	    strncpy(pbarcoderes->data.barcode, pDTE[drive].VolTag,		    SIZEOF(pbarcoderes->data.barcode));	    MapBarCode(labelfile, pbarcoderes);	  } else {	    MapBarCode(labelfile, pbarcoderes);	  }      } else {	DebugPrint(DEBUG_ERROR,SECTION_MAP_BARCODE, _("Read label failed\n"));      }      if (eject)	{	  (void)eject_tape("", eject);	}      (void)unload(INDEX_TAPE, drive, x);    }  DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE, _("##### STOP Inventory\n"));  free(pbarcoderes);}/* * Check if the slot ist empty * slot -> slot number to check */intisempty(    int		fd,    int		slot){  extern OpenFiles_T *pDev;  DebugPrint(DEBUG_INFO,SECTION_TAPE,_("##### START isempty\n"));  if (ElementStatusValid == 0)    {      if ( pDev[fd].functions->function_status(fd, 1) != 0)        {          DebugPrint(DEBUG_ERROR,SECTION_TAPE,_("##### STOP isempty [-1]\n"));          return(-1);	  /*NOTREACHED*/        }    }  if (pSTE[slot].status == 'E')    {      DebugPrint(DEBUG_INFO,SECTION_TAPE,_("##### STOP isempty [1]\n"));      return(1);      /*NOTREACHED*/    }  DebugPrint(DEBUG_INFO,SECTION_TAPE,_("##### STOP isempty [0]\n"));  return(0);}intget_clean_state(    char *tapedev){  extern OpenFiles_T *pDev;  /* Return 1 if cleaning is needed */  int ret;  DebugPrint(DEBUG_INFO,SECTION_TAPE,_("##### START get_clean_state\n"));  if (pDev[INDEX_TAPECTL].SCSI == 0)    {      DebugPrint(DEBUG_ERROR,SECTION_TAPE,_("##### STOP get_clean_state [-1]\n"));      return(-1);      /*NOTREACHED*/    }  ret=pDev[INDEX_TAPECTL].functions->function_clean(tapedev);  DebugPrint(DEBUG_INFO,SECTION_TAPE,_("##### STOP get_clean_state [%d]\n"), ret);  return(ret);}/* * eject the tape * The parameter tapedev is not used. * Type describes if we should force the SCSI eject if available * normal eject is done with the ioctl *//* This function ejects the tape from the drive */inteject_tape(    char *	tapedev,    int		type){  extern OpenFiles_T *pDev;  int ret;  DebugPrint(DEBUG_INFO,SECTION_TAPE,_("##### START eject_tape %s\n"),tapedev);  if (pDev[INDEX_TAPECTL].functions == NULL)    return(-1);  /*   * Try to read the label   */  if (pDev[INDEX_TAPE].avail == 1 && (changer->emubarcode == 1 || BarCode(INDEX_CHANGER)))    {      if (pDev[INDEX_TAPECTL].SCSI == 1 && pDev[INDEX_TAPECTL].avail) {        DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### eject_tape rewind\n");	pDev[INDEX_TAPECTL].functions->function_rewind(INDEX_TAPECTL);      } else {        DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### eject_tape rewind2\n");	pDev[INDEX_TAPE].functions->function_rewind(INDEX_TAPE);      }      if (pDev[INDEX_TAPE].devopen == 1)	{          DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### eject_tape close\n");	  SCSI_CloseDevice(INDEX_TAPE);	}      DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### tape_eject tape_rdlabel\n");      chgscsi_result = (char *)tape_rdlabel(pDev[INDEX_TAPE].dev, &chgscsi_datestamp, &chgscsi_label);    }  if (pDev[INDEX_TAPECTL].SCSI == 1 && pDev[INDEX_TAPECTL].avail == 1 && type == 1)    {      DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### tape_eject eject\n");      ret=pDev[INDEX_TAPECTL].functions->function_eject(tapedev, type);      DebugPrint(DEBUG_INFO,SECTION_TAPE,_("##### STOP (SCSI)eject_tape [%d]\n"), ret);      return(ret);      /*NOTREACHED*/    }  if (pDev[INDEX_TAPE].avail == 1)    {      ret=Tape_Ioctl(INDEX_TAPE, IOCTL_EJECT);      DebugPrint(DEBUG_INFO,SECTION_TAPE,_("##### STOP (ioctl)eject_tape [%d]\n"), ret);      return(ret);      /*NOTREACHED*/    }  DebugPrint(DEBUG_INFO,SECTION_TAPE,_("##### STOP eject_tape [-1]\n"));  return(-1);}/* Find an empty slot, starting at start, ending at start+count */intfind_empty(    int	fd,    int	start,    int	count){  extern OpenFiles_T *pDev;  size_t x;  size_t end;  DebugPrint(DEBUG_INFO,SECTION_ELEMENT,_("###### START find_empty\n"));  if (ElementStatusValid == 0)    {      if ( pDev[fd].functions->function_status(fd , 1) != 0)        {          DebugPrint(DEBUG_ERROR,SECTION_ELEMENT,		     _("###### END find_empty [-1]\n"));          return((ssize_t)-1);	  /*NOTREACHED*/        }    }  if (count == 0)    {      end = STE;    } else {      end = start + count;    }  if (end > STE)    {      end = STE;    }  DebugPrint(DEBUG_INFO, SECTION_ELEMENT,	     _("start at %zu, end at %zu\n"),	     (size_t)start,	     (size_t)end);  for (x = start; x < end; x++)    {      if (pSTE[x].status == 'E')        {          DebugPrint(DEBUG_INFO,SECTION_ELEMENT,		     _("###### END find_empty [%lu]\n"), x);          return((ssize_t)x);	  /*NOTREACHED*/        }    }  DebugPrint(DEBUG_ERROR,SECTION_ELEMENT,_("###### END find_empty [-1]\n"));  return((ssize_t)-1);}/* * See if the tape is loaded based on the information we * got back from the ReadElementStatus * return values * -1 -> Error (Fatal) * 0  -> drive is empty * 1  -> drive is loaded */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -