//OpenSCADA module DAQ.System file: da_smart.cpp /*************************************************************************** * Copyright (C) 2005-2024 by Roman Savochenko, * * * * 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 of the License. * * * * 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include "os_contr.h" #include "da_smart.h" #define SCSI_MAJOR 8 using namespace SystemCntr; const char *HddSmart::smartval_cmd = "smartctl -A -v N,raw48 %s 2> /dev/null"; //************************************************* //* HddSmart * //************************************************* HddSmart::HddSmart( ) { } HddSmart::~HddSmart( ) { } void HddSmart::getVal( TMdPrm *prm ) { int id; unsigned long val; char buf[256]; char name[31]; bool devOK = false; string dev = prm->cfg("SUBT").getS(); //SMART attributes string cmd = TSYS::strMess(smartval_cmd,("/dev/"+dev+((dev.size()&&dev[0]=='s')?" -d ata":"")).c_str()); FILE *fp = popen(cmd.c_str(),"r"); while(fp && fgets(buf,sizeof(buf),fp) != NULL) { if(sscanf(buf,"%d %30s %*x %*d %*d %*d %*s %*s %*s %lu\n",&id,name,&val) != 3) continue; string sId = i2s(id); if(!prm->vlPresent(sId)) ((TElem*)prm->daData)->fldAdd(new TFld(sId.c_str(),(string(name)+" ("+sId+")").c_str(),TFld::Integer,TFld::NoWrite)); prm->vlAt(sId).at().setI(val,0,true); devOK = true; } if(fp && pclose(fp) == -1) mess_warning(prm->nodePath().c_str(), _("Closing the pipe %p error '%s (%d)'!"), fp, strerror(errno), errno); if(devOK) prm->daErr = ""; else if(!prm->daErr.getVal().size()) { prm->setEval(); prm->daErr = _("10:Device is not available."); } } void HddSmart::dList( vector &list, TMdPrm *prm ) { int major, minor; char name[11]; char buf[256]; FILE *f = fopen("/proc/partitions","r"); if(f == NULL) return; while(fgets(buf,sizeof(buf),f) != NULL) { if(sscanf(buf,"%d %d %*d %10s",&major,&minor,name) != 3) continue; if(/*!part &&*/ ((major != SCSI_MAJOR && minor != 0) || (major == SCSI_MAJOR && (minor%16)) || !strncmp(name,"md",2))) continue; string cmd = TSYS::strMess(smartval_cmd,(string("/dev/")+name+((major==SCSI_MAJOR)?" -d ata":"")).c_str()); FILE *fp = popen(cmd.c_str(),"r"); if(fp) { int val; bool access_true = false; while(fgets(buf,sizeof(buf),fp) != NULL) { if(sscanf(buf,"%*d %*s %*x %*d %*d %*d %*s %*s %*s %d\n",&val) != 1) continue; access_true = true; break; } if(pclose(fp) == -1) mess_warning(mod->nodePath().c_str(), _("Closing the pipe %p error '%s (%d)'!"), fp, strerror(errno), errno); if(access_true) list.push_back(name); } } if(fclose(f) != 0) mess_warning(mod->nodePath().c_str(), _("Closing the file %p error '%s (%d)'!"), f, strerror(errno), errno); }