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
require("guiconfig.inc");
59

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

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

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

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

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

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

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

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

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

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

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

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

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

    
149
<?php
150
		break;
151
	}
152

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

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

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

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

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

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

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

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

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

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

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

    
247
			config_unlock();
248

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

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

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

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

    
263
	$form = new Form();
264

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

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

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

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

    
283
	print($form);
284

    
285
	break;
286
	}
287

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
497
		break;
498
	}
499
}
500

    
501
include("foot.inc");
(36-36/237)