Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 58 additions & 14 deletions lib/utils/job-utils/command-parser.js
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -266,30 +266,49 @@ function commandParserFactory(Logger, Promise, _) {
}
try {
var parsed = [];
var splitData = data.stdout.split(/^#{4,}\s*([^\n\r]+)[\r\n]+/m);
var smartEachDrive = data.stdout.split(/^#{4,}\s*([^\n\r]+)[\r\n]+/m);

var drive = {'OS Device Name' : '', 'smartctl Version' : '', 'SMART' : []};
_.forEach(splitData, function(elem) {
if (elem === '') {
var drive = {'OS Device Name' : '',
'smartctl Version' : '',
'SMART' : [],
'Controller' : {}};

_.forEach(smartEachDrive, function(smart) {
if (smart === '') {
return;
}
else if (elem[0] === '/' ) { //This is the device name
drive['OS Device Name'] = elem;
else if (smart[0] === '/') { //This is the device name
drive['OS Device Name'] = smart;
}
else { //this is the smart data for above device
//extract the smartctl version
var ver = elem.match(/^smartctl\s([\d\.]+)/);
var ver = smart.match(/^smartctl\s([\d\.]+)/);
if (ver && ver.length > 1) {
drive['smartctl Version'] = ver[1];
}

drive.SMART = _parseSmartOneDriveData(elem);
//further split the data into the smart part and the controller part
var splitData = smart.split(/^#{3,}\s*[^\n\r]+[\r\n]+/m);
_.forEach(splitData, function (elem) {
if (elem.match(/^controller_name/)) { //the controller part
//code to find out the HBA controller that the drive is connected to
drive.Controller = _parseControllerInfoOneDriveData(elem);
return;
}
else { //This is the smart data part
drive.SMART = _parseSmartOneDriveData(elem);
}
});
// Append the an entry to drive smart catalog
parsed.push(drive);
drive = {'OS Device Name' : '', 'smartctl Version' : '', 'SMART' : []};
drive = {
'OS Device Name': '',
'smartctl Version': '',
'SMART': [],
'Controller': {}};
}
});

return Promise.resolve({ data: parsed, source: 'smart', store: true });
});
return Promise.resolve({ data: parsed, source: 'smart', store: true });
} catch (e) {
return Promise.resolve({ source: 'smart', error: e });
}
Expand Down Expand Up @@ -1051,13 +1070,38 @@ function commandParserFactory(Logger, Promise, _) {
}));
};

/**
* Parse the whole controller info of one drive.
*
* @param {String} dataBlock - The controller info output data for one drive.
* @returns {Object} The object with well classfied controller information.
*/
function _parseControllerInfoOneDriveData(dataBlock) {
//split output by empty line
var dataSegments = dataBlock.split(/\n/); //Divided by line
var drvObj = {};
_.forEach(dataSegments, function(data) {
data = data.trim();

// Ignore empty line
if (data.length === 0) {
return;
}

//Split key and value by "="
var fields = data.split("="); //Divided by "="
drvObj[fields[0]] = fields[1].trim();
});

return drvObj;
}
/**
* Parse the whole SMART data of one drive.
*
* The data catalog is refer to the smartctl GUI.
*
* @param {String} The whole smartctl output data for one drive.
* @param {Object} The object with well classfied SMART information.
* @param {String} dataBlock - The whole smartctl output data for one drive.
* @returns {Object} The object with well classfied SMART information.
*/
function _parseSmartOneDriveData(dataBlock) {
//split output by empty line
Expand Down
3 changes: 3 additions & 0 deletions spec/lib/utils/job-utils/command-parser-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,9 @@ describe("Task Parser", function () {
expect(elem).property('SMART').to.contain.keys('Attributes',
'Self-Assessment', 'Capabilities', 'Identity');
expect(elem).property('smartctl Version').to.match(/^\d+\.\d+$/);
expect(elem).property('Controller').that.is.an('object');
expect(elem).property('Controller').to.contain.keys('controller_name',
'controller_ID', 'controller_PCI_BDF');
});

var smart = result.data[0].SMART;
Expand Down
12 changes: 12 additions & 0 deletions spec/lib/utils/job-utils/samplefiles/smartctrl.txt
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ Selective self-test flags (0x0):
After scanning selected spans, do NOT read-scan remainder of disk.
If Selective self-test is pending on power-up, resume after 0 minute delay.
o
###HBA Controller Information for /dev/sda scsi
controller_name= Intel Corporation Wellsburg 6-Port SATA Controller [AHCI mode] (rev 05)
controller_ID=10
controller_PCI_BDF=0000:00:1f.2
####/dev/sda2 scsi
smartctl 6.2 2013-07-26 r3841 [x86_64-linux-3.13.0-32-generic] (local build)
Copyright (C) 2002-13, Bruce Allen, Christian Franke, www.smartmontools.org
Expand Down Expand Up @@ -162,6 +166,10 @@ ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_

SMART Error Log Version: 1
N
###HBA Controller Information for /dev/bus/0 megaraid,5
controller_name= LSI Logic / Symbios Logic MegaRAID SAS-3 3108 [Invader] (rev 02)
controller_ID=0
controller_PCI_BDF=0000:07:00.0
####/dev/sda0 megaraid,13
smartctl 6.2 2013-07-26 r3841 [x86_64-linux-3.13.0-32-generic] (local build)
Copyright (C) 2002-13, Bruce Allen, Christian Franke, www.smartmontools.org
Expand Down Expand Up @@ -226,3 +234,7 @@ No Errors Logged
SMART Self-test log structure revision number 1
No self-tests have been logged. [To run self-tests, use: smartctl -t]
Errors Logged
###HBA Controller Information for /dev/bus/0 megaraid,5
controller_name= LSI Logic / Symbios Logic MegaRAID SAS-3 3108 [Invader] (rev 02)
controller_ID=0
controller_PCI_BDF=0000:07:00.0