/* * get_scsi_temp.c: functions that populate the drive temperature variables * in SCSI/SAS drives context structure. * Routines from hddtemp are used here. * * Author: Gerold Gruber * * 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, version 2. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ //#define _LARGEFILE64_SOURCE //#define _FILE_OFFSET_BITS 64 #define _BSD_SOURCE #include #include #include #include #include #include #include #include "nwipe.h" #include "context.h" #include "method.h" #include "device.h" #include "prng.h" #include "options.h" #include "device.h" #include "logging.h" #include "temperature.h" #include "miscellaneous.h" #include "hddtemp.h" #include "scsi.h" int scsi_get_temperature( struct disk * ); int nwipe_init_scsi_temperature( nwipe_context_t* c ) { /* dsk anlegen, malloc */ struct disk *dsk = (struct disk *) malloc(sizeof(struct disk)); /* Check the allocation. */ if( !dsk ) { nwipe_perror( errno, __FUNCTION__, "malloc" ); nwipe_log( NWIPE_LOG_FATAL, "Unable to get memory for disk struct for %s", c->device_name ); exit( 1 ) ; } assert(dsk); memset(dsk, 0, sizeof(*dsk)); /* save the dsk pointer for later use */ c->templ_disk = dsk; /* initialize */ dsk->drive = c->device_name; dsk->type = BUS_SCSI; /* we know this as we are only called in this case */ errno = 0; dsk->errormsg[0] = '\0'; if( (dsk->fd = open(dsk->drive, O_RDONLY | O_NONBLOCK)) < 0) { snprintf(dsk->errormsg, MAX_ERRORMSG_SIZE, "open: %s\n", strerror(errno)); dsk->type = ERROR; return 1; } // sg_logs -t if( scsi_get_temperature( dsk ) == GETTEMP_SUCCESS ) { c->temp1_input = dsk->value; c->temp1_crit = dsk->refvalue; c->temp1_lcrit = -40; /* just to give it a value with some kind of sense */ c->temp1_highest = dsk->value; c->temp1_lowest = dsk->value; c->temp1_max = dsk->refvalue - 5; /* seems to be kind of useful */ } else { nwipe_log( NWIPE_LOG_ERROR, "Can not read SCSI temperature for %s, %s", dsk->drive, dsk->errormsg ); close( dsk->fd ); free( dsk ); c->templ_disk = NULL; return 1; } return 0; } int nwipe_get_scsi_temperature( nwipe_context_t* c ) { struct disk *dsk; dsk = c->templ_disk; if( c->templ_disk != NULL && c->templ_disk->fd != -1 ) { if( scsi_get_temperature( dsk ) == GETTEMP_SUCCESS ) { c->temp1_input = dsk->value; /* not at all of interest */ if( c->temp1_input > c->temp1_highest ) { c->temp1_highest = c->temp1_input; } if( c->temp1_input < c->temp1_lowest ) { c->temp1_lowest = c->temp1_input; } /* end not at all of interest ;-) */ } else { nwipe_log( NWIPE_LOG_ERROR, "Could not read SCSI temperature for %s, %s", dsk->drive, dsk->errormsg ); return 2; } } else { nwipe_log( NWIPE_LOG_INFO, "no SCSI temperature reading for %s", dsk->drive ); return 1; } return 0; } void nwipe_shut_scsi_temperature( nwipe_context_t* c ) { if( c->templ_disk->fd != -1 ) { close( c->templ_disk->fd ); } if( c->templ_disk != NULL ) { free( c->templ_disk ); } return; }