Project

General

Profile

Download (12.1 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	diag_smart.php
4
*/
5
/* ====================================================================
6
 *  Copyright (c)  2004-2015  Electric Sheep Fencing, LLC. All rights reserved. 
7
 *  Copyright (c)  2010 - Jim Pingle
8
 *	Copyright (c) 2006, Eric Friesen
9
 *
10
 *  Redistribution and use in source and binary forms, with or without modification, 
11
 *  are permitted provided that the following conditions are met: 
12
 *
13
 *  1. Redistributions of source code must retain the above copyright notice,
14
 *      this list of conditions and the following disclaimer.
15
 *
16
 *  2. Redistributions in binary form must reproduce the above copyright
17
 *      notice, this list of conditions and the following disclaimer in
18
 *      the documentation and/or other materials provided with the
19
 *      distribution. 
20
 *
21
 *  3. All advertising materials mentioning features or use of this software 
22
 *      must display the following acknowledgment:
23
 *      "This product includes software developed by the pfSense Project
24
 *       for use in the pfSense software distribution. (http://www.pfsense.org/). 
25
 *
26
 *  4. The names "pfSense" and "pfSense Project" must not be used to
27
 *       endorse or promote products derived from this software without
28
 *       prior written permission. For written permission, please contact
29
 *       coreteam@pfsense.org.
30
 *
31
 *  5. Products derived from this software may not be called "pfSense"
32
 *      nor may "pfSense" appear in their names without prior written
33
 *      permission of the Electric Sheep Fencing, LLC.
34
 *
35
 *  6. Redistributions of any form whatsoever must retain the following
36
 *      acknowledgment:
37
 *
38
 *  "This product includes software developed by the pfSense Project
39
 *  for use in the pfSense software distribution (http://www.pfsense.org/).
40
  *
41
 *  THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
42
 *  EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
44
 *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
45
 *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47
 *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49
 *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
50
 *  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
51
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
52
 *  OF THE POSSIBILITY OF SUCH DAMAGE.
53
 *
54
 *  ====================================================================
55
 *
56
 */
57
*/
58

    
59
require("guiconfig.inc");
60

    
61
$pgtitle = array(gettext("Diagnostics"), gettext("S.M.A.R.T. Monitor Tools"));
62
$smartctl = "/usr/local/sbin/smartctl";
63
$smartd = "/usr/local/sbin/smartd";
64
$start_script = "/usr/local/etc/rc.d/smartd.sh";
65

    
66
$valid_test_types = array("offline", "short", "long", "conveyance");
67
$valid_info_types = array("i", "H", "c", "A", "a");
68
$valid_log_types = array("error", "selftest");
69

    
70
$closehead = false;
71
include("head.inc");
72

    
73
// Highlights the words "PASSED", "FAILED", and "WARNING".
74
function add_colors($string)
75
{
76
	// To add words keep arrays matched by numbers
77
	$patterns[0] = '/PASSED/';
78
	$patterns[1] = '/FAILED/';
79
	$patterns[2] = '/Warning/';
80
	$replacements[0] = '<b><font color="#00ff00">' . gettext("PASSED") .  '</font></b>';
81
	$replacements[1] = '<b><font color="#ff0000">' . gettext("FAILED") .  '</font></b>';
82
	$replacements[2] = '<font color="#ff0000">'	   . gettext("Warning") . '</font>';
83
	ksort($patterns);
84
	ksort($replacements);
85
	return preg_replace($patterns, $replacements, $string);
86
}
87

    
88
// Edits smartd.conf file, adds or removes email for failed disk reporting
89
function update_email($email) {
90
	// Did they pass an email?
91
	if (!empty($email)) {
92
		// Put it in the smartd.conf file
93
		shell_exec("/usr/bin/sed -i old 's/^DEVICESCAN.*/DEVICESCAN -H -m " . escapeshellarg($email) . "/' /usr/local/etc/smartd.conf");
94
	} else {
95
		// Remove email flags in smartd.conf
96
		shell_exec("/usr/bin/sed -i old 's/^DEVICESCAN.*/DEVICESCAN/' /usr/local/etc/smartd.conf");
97
	}
98
}
99

    
100
function smartmonctl($action) {
101
	global $start_script;
102
	shell_exec($start_script . escapeshellarg($action));
103
}
104

    
105
// What page, aka. action is being wanted
106
// If they "get" a page but don't pass all arguments, smartctl will throw an error
107
$action = (isset($_POST['action']) ? $_POST['action'] : $_GET['action']);
108
$targetdev = basename($_POST['device']);
109

    
110
if (!file_exists('/dev/' . $targetdev)) {
111
	echo "Device does not exist, bailing.";
112
	return;
113
}
114

    
115
require('classes/Form.class.php');
116

    
117
$tab_array = array();
118
$tab_array[0] = array(gettext("Information/Tests"), ($action != 'config'), $_SERVER['PHP_SELF'] . "?action=default");
119
$tab_array[1] = array(gettext("Config"), ($action == 'config'), $_SERVER['PHP_SELF'] . "?action=config");
120
display_top_tabs($tab_array);
121

    
122
switch($action) {
123
	// Testing devices
124
	case 'test':
125
	{
126
		$test = $_POST['testType'];
127
		if (!in_array($test, $valid_test_types)) {
128
			echo "Invalid test type, bailing.";
129
			return;
130
		}
131

    
132
		$output = add_colors(shell_exec($smartctl . " -t " . escapeshellarg($test) . " /dev/" . escapeshellarg($targetdev)));
133
?>
134
		<div class="panel  panel-default">
135
			<div class="panel-heading"><h2 class="panel-title"><?=gettext('Test results')?></h2></div>
136
			<div class="panel-body">
137
				<pre><?=$output?></pre>
138
			</div>
139
		</div>
140

    
141
		<form action="diag_smart.php" method="post" name="abort">
142
			<input type="hidden" name="device" value="<?=$targetdev?>" />
143
			<input type="hidden" name="action" value="abort" />
144
			<nav class="action-buttons">
145
				<input type="submit" name="submit"	class="btn btn-danger" value="<?=gettext("Abort")?>" />
146
				<a href="<?=$_SERVER['PHP_SELF']?>" class="btn btn-default"><?=gettext("Back")?></a>
147
			</nav>
148
		</form>
149

    
150
<?php
151
		break;
152
	}
153

    
154
	// Info on devices
155
	case 'info':
156
	{
157
		$type = $_POST['type'];
158

    
159
		if (!in_array($type, $valid_info_types)) {
160
			print_info_box(gettext("Invalid info type, bailing."), 'danger');
161
			return;
162
		}
163

    
164
		$output = add_colors(shell_exec($smartctl . " -" . escapeshellarg($type) . " /dev/" . escapeshellarg($targetdev)));
165
?>
166
		<div class="panel  panel-default">
167
			<div class="panel-heading"><h2 class="panel-title"><?=gettext('Information')?></h2></div>
168
			<div class="panel-body">
169
				<pre><?=$output?></pre>
170
			</div>
171
		</div>
172

    
173
		<nav class="action-buttons">
174
			<a href="<?=$_SERVER['PHP_SELF']?>" class="btn btn-default"><?=gettext("Back")?></a>
175
		</nav>
176
<?php
177
		break;
178
	}
179

    
180
	// View logs
181
	case 'logs':
182
	{
183
		$type = $_POST['type'];
184
		if (!in_array($type, $valid_log_types)) {
185
			print_info_box(gettext("Invalid log type, bailing."), 'danger');
186
			return;
187
		}
188

    
189
		$output = add_colors(shell_exec($smartctl . " -l " . escapeshellarg($type) . " /dev/" . escapeshellarg($targetdev)));
190
?>
191
		<div class="panel  panel-default">
192
			<div class="panel-heading"><h2 class="panel-title"><?=gettext('Logs')?></h2></div>
193
			<div class="panel-body">
194
				<pre><?=$output?></pre>
195
			</div>
196
		</div>
197

    
198
		<nav class="action-buttons">
199
			<a href="<?=$_SERVER['PHP_SELF']?>" class="btn btn-default"><?=gettext("Back")?></a>
200
		</nav>
201
<?php
202
		break;
203
	}
204

    
205
	// Abort tests
206
	case 'abort':
207
	{
208
		$output = shell_exec($smartctl . " -X /dev/" . escapeshellarg($targetdev));
209
?>
210
		<div class="panel  panel-default">
211
			<div class="panel-heading"><h2 class="panel-title"><?=gettext('Abort')?></h2></div>
212
			<div class="panel-body">
213
				<pre><?=$output?></pre>
214
			</div>
215
		</div>
216
<?php
217
		break;
218
	}
219

    
220
	// Config changes, users email in xml config and write changes to smartd.conf
221
	case 'config':
222
	{
223
		if(isset($_POST['test']))	{
224

    
225
// FIXME				shell_exec($smartd . " -M test -m " . $config['system']['smartmonemail']);
226
			$savemsg = sprintf(gettext("Email sent to %s"), $config['system']['smartmonemail']);
227
			smartmonctl("stop");
228
			smartmonctl("start");
229
			$style = 'warning';
230
		}
231
		else if(isset($_POST['save']))
232
		{
233
			$config['system']['smartmonemail'] = $_POST['smartmonemail'];
234
			write_config();
235

    
236
			// Don't know what all this means, but it adds the config changed header when config is saved
237
			$retval = 0;
238
			config_lock();
239
			if(stristr($retval, "error") != true) {
240
				$savemsg = get_std_save_message($retval);
241
				$style = 'success';
242
				}
243
			else {
244
				$savemsg = $retval;
245
				$style='danger';
246
			}
247

    
248
			config_unlock();
249

    
250
			// Write the changes to the smartd.conf file
251
			update_email($_POST['smartmonemail']);
252

    
253
			// Send sig HUP to smartd, rereads the config file
254
			shell_exec("/usr/bin/killall -HUP smartd");
255
		}
256

    
257
	// Was the config changed? if so , print the message
258
	if ($savemsg)
259
		print_info_box($savemsg, $style);
260

    
261
	// Get users email from the xml file
262
	$pconfig['smartmonemail'] = $config['system']['smartmonemail'];
263

    
264
	$form = new Form();
265

    
266
	$section = new Form_Section('Configuration');
267

    
268
	$section->addInput(new Form_Input(
269
		'smartmonemail',
270
		'Email Address',
271
		'text',
272
		$pconfig['smartmonemail']
273
	 ));
274

    
275
	$form->add($section);
276

    
277
	if(!empty($pconfig['smartmonemail'])) {
278
		$form->addGlobal(new Form_Button(
279
			'test',
280
			'Send test email'
281
		))->removeClass('btn-primary')->addClass('btn-default');
282
	}
283

    
284
	print($form);
285

    
286
	break;
287
	}
288

    
289
	// Default page, prints the forms to view info, test, etc...
290
	default: {
291
// Information	
292
		$devs = get_smart_drive_list();
293

    
294
		$form = new Form(new Form_Button(
295
			'submit',
296
			'View'
297
		));
298

    
299
		$section = new Form_Section('Information');
300

    
301
		$section->addInput(new Form_Input(
302
			'action',
303
			null,
304
			'hidden',
305
			'info'
306
		));
307

    
308
		$group = new Form_Group('Info type');
309

    
310
		$group->add(new Form_Checkbox(
311
			'type',
312
			null,
313
			'Info',
314
			false,
315
			'i'
316
		))->displayAsRadio();
317

    
318
		$group->add(new Form_Checkbox(
319
			'type',
320
			null,
321
			'Health',
322
			true,
323
			'H'
324
		))->displayAsRadio();
325

    
326
		$group->add(new Form_Checkbox(
327
			'type',
328
			null,
329
			'SMART Capabilities',
330
			false,
331
			'c'
332
		))->displayAsRadio();
333

    
334
		$group->add(new Form_Checkbox(
335
			'type',
336
			null,
337
			'Attributes',
338
			false,
339
			'A'
340
		))->displayAsRadio();
341

    
342
		$group->add(new Form_Checkbox(
343
			'type',
344
			null,
345
			'All',
346
			false,
347
			'a'
348
		))->displayAsRadio();
349

    
350
		$section->add($group);
351

    
352
		$section->addInput(new Form_Select(
353
			'device',
354
			'Device: /dev/',
355
			false,
356
			array_combine($devs, $devs)
357
		));
358

    
359
		$form->add($section);
360
		print($form);
361

    
362
// Tests
363
		$form = new Form(new Form_Button(
364
			'submit',
365
			'Test'
366
		));
367

    
368
		$section = new Form_Section('Perform self-tests');
369

    
370
		$section->addInput(new Form_Input(
371
			'action',
372
			null,
373
			'hidden',
374
			'test'
375
		));
376

    
377
		$group = new Form_Group('Test type');
378

    
379
		$group->add(new Form_Checkbox(
380
			'testType',
381
			null,
382
			'Offline',
383
			false,
384
			'offline'
385
		))->displayAsRadio();
386

    
387
		$group->add(new Form_Checkbox(
388
			'testType',
389
			null,
390
			'Short',
391
			true,
392
			'short'
393
		))->displayAsRadio();
394

    
395
		$group->add(new Form_Checkbox(
396
			'testType',
397
			null,
398
			'Long',
399
			false,
400
			'long'
401
		))->displayAsRadio();
402

    
403
		$group->add(new Form_Checkbox(
404
			'testType',
405
			null,
406
			'Conveyance',
407
			false,
408
			'conveyance'
409
		))->displayAsRadio();
410

    
411
		$group->setHelp('Select "Conveyance" for ATA disks only');
412
		$section->add($group);
413

    
414
		$section->addInput(new Form_Select(
415
			'device',
416
			'Device: /dev/',
417
			false,
418
			array_combine($devs, $devs)
419
		));
420

    
421
		$form->add($section);
422
		print($form);
423

    
424
// Logs
425
		$form = new Form(new Form_Button(
426
			'submit',
427
			'View'
428
		));
429

    
430
		$section = new Form_Section('View logs');
431

    
432
		$section->addInput(new Form_Input(
433
			'action',
434
			null,
435
			'hidden',
436
			'logs'
437
		));
438

    
439
		$group = new Form_Group('Log type');
440

    
441
		$group->add(new Form_Checkbox(
442
			'type',
443
			null,
444
			'Error',
445
			true,
446
			'error'
447
		))->displayAsRadio();
448

    
449
		$group->add(new Form_Checkbox(
450
			'test',
451
			null,
452
			'Self-test',
453
			false,
454
			'selftest'
455
		))->displayAsRadio();
456

    
457
		$section->add($group);
458

    
459
		$section->addInput(new Form_Select(
460
			'device',
461
			'Device: /dev/',
462
			false,
463
			array_combine($devs, $devs)
464
		));
465

    
466
		$form->add($section);
467
		print($form);
468

    
469
// Abort
470
		$btnabort = new Form_Button(
471
			'submit',
472
			'Abort'
473
		);
474

    
475
		$btnabort->removeClass('btn-primary')->addClass('btn-danger');
476

    
477
		$form = new Form($btnabort);
478

    
479
		$section = new Form_Section('Abort');
480

    
481
		$section->addInput(new Form_Input(
482
			'action',
483
			null,
484
			'hidden',
485
			'abort'
486
		));
487

    
488
		$section->addInput(new Form_Select(
489
			'device',
490
			'Device: /dev/',
491
			false,
492
			array_combine($devs, $devs)
493
		));
494

    
495
		$form->add($section);
496
		print($form);
497

    
498
		break;
499
	}
500
}
501

    
502
include("foot.inc");
(36-36/238)