Project

General

Profile

Download (9.76 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	diag_smart.php
4
	Part of pfSense
5

    
6
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
7
	All rights reserved
8

    
9
	Some modifications:
10
	Copyright (C) 2010 - Jim Pingle
11

    
12
	Copyright (C) 2006, Eric Friesen
13
	All rights reserved
14

    
15
*/
16

    
17
require("guiconfig.inc");
18

    
19
$pgtitle = array(gettext("Diagnostics"), gettext("S.M.A.R.T. Monitor Tools"));
20
$smartctl = "/usr/local/sbin/smartctl";
21
$smartd = "/usr/local/sbin/smartd";
22
$start_script = "/usr/local/etc/rc.d/smartd.sh";
23

    
24
$valid_test_types = array("offline", "short", "long", "conveyance");
25
$valid_info_types = array("i", "H", "c", "A", "a");
26
$valid_log_types = array("error", "selftest");
27

    
28
$closehead = false;
29
include("head.inc");
30

    
31
// Highlights the words "PASSED", "FAILED", and "WARNING".
32
function add_colors($string)
33
{
34
	// To add words keep arrays matched by numbers
35
	$patterns[0] = '/PASSED/';
36
	$patterns[1] = '/FAILED/';
37
	$patterns[2] = '/Warning/';
38
	$replacements[0] = '<b><font color="#00ff00">' . gettext("PASSED") .  '</font></b>';
39
	$replacements[1] = '<b><font color="#ff0000">' . gettext("FAILED") .  '</font></b>';
40
	$replacements[2] = '<font color="#ff0000">'	   . gettext("Warning") . '</font>';
41
	ksort($patterns);
42
	ksort($replacements);
43
	return preg_replace($patterns, $replacements, $string);
44
}
45

    
46
// Edits smartd.conf file, adds or removes email for failed disk reporting
47
function update_email($email)
48
{
49
	// Did they pass an email?
50
	if(!empty($email))
51
	{
52
		// Put it in the smartd.conf file
53
		shell_exec("/usr/bin/sed -i old 's/^DEVICESCAN.*/DEVICESCAN -H -m " . escapeshellarg($email) . "/' /usr/local/etc/smartd.conf");
54
	}
55
	// Nope
56
	else
57
	{
58
		// Remove email flags in smartd.conf
59
		shell_exec("/usr/bin/sed -i old 's/^DEVICESCAN.*/DEVICESCAN/' /usr/local/etc/smartd.conf");
60
	}
61
}
62

    
63
function smartmonctl($action)
64
{
65
	global $start_script;
66
	shell_exec($start_script . escapeshellarg($action));
67
}
68

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

    
74
if (!file_exists('/dev/' . $targetdev)) {
75
	echo "Device does not exist, bailing.";
76
	return;
77
}
78

    
79
require('classes/Form.class.php');
80

    
81
$tab_array = array();
82
$tab_array[0] = array(gettext("Information/Tests"), ($action != 'config'), $_SERVER['PHP_SELF'] . "?action=default");
83
$tab_array[1] = array(gettext("Config"), ($action == 'config'), $_SERVER['PHP_SELF'] . "?action=config");
84
display_top_tabs($tab_array);
85

    
86
switch($action) {
87
	// Testing devices
88
	case 'test':
89
	{
90
		$test = $_POST['testType'];
91
		if (!in_array($test, $valid_test_types)) {
92
			echo "Invalid test type, bailing.";
93
			return;
94
		}
95

    
96
		$output = add_colors(shell_exec($smartctl . " -t " . escapeshellarg($test) . " /dev/" . escapeshellarg($targetdev)));
97
?>
98
		<div class="panel  panel-default">
99
			<div class="panel-heading"><h2 class="panel-title"><?=gettext('Test results')?></h2></div>
100
			<div class="panel-body">
101
				<pre><?=$output?></pre>
102
			</div>
103
		</div>
104

    
105
		<form action="diag_smart.php" method="post" name="abort">
106
			<input type="hidden" name="device" value="<?=$targetdev?>" />
107
			<input type="hidden" name="action" value="abort" />
108
			<nav class="action-buttons">
109
				<input type="submit" name="submit"	class="btn btn-danger" value="<?=gettext("Abort")?>" />
110
				<a href="<?=$_SERVER['PHP_SELF']?>" class="btn btn-default"><?=gettext("Back")?></a>
111
			</nav>
112
		</form>
113

    
114
<?php
115
		break;
116
	}
117

    
118
	// Info on devices
119
	case 'info':
120
	{
121
		$type = $_POST['type'];
122

    
123
		if (!in_array($type, $valid_info_types)) {
124
			print_info_box(gettext("Invalid info type, bailing."), 'danger');
125
			return;
126
		}
127

    
128
		$output = add_colors(shell_exec($smartctl . " -" . escapeshellarg($type) . " /dev/" . escapeshellarg($targetdev)));
129
?>
130
		<div class="panel  panel-default">
131
			<div class="panel-heading"><h2 class="panel-title"><?=gettext('Information')?></h2></div>
132
			<div class="panel-body">
133
				<pre><?=$output?></pre>
134
			</div>
135
		</div>
136

    
137
		<nav class="action-buttons">
138
			<a href="<?=$_SERVER['PHP_SELF']?>" class="btn btn-default"><?=gettext("Back")?></a>
139
		</nav>
140
<?php
141
		break;
142
	}
143

    
144
	// View logs
145
	case 'logs':
146
	{
147
		$type = $_POST['type'];
148
		if (!in_array($type, $valid_log_types)) {
149
			print_info_box(gettext("Invalid log type, bailing."), 'danger');
150
			return;
151
		}
152

    
153
		$output = add_colors(shell_exec($smartctl . " -l " . escapeshellarg($type) . " /dev/" . escapeshellarg($targetdev)));
154
?>
155
		<div class="panel  panel-default">
156
			<div class="panel-heading"><h2 class="panel-title"><?=gettext('Logs')?></h2></div>
157
			<div class="panel-body">
158
				<pre><?=$output?></pre>
159
			</div>
160
		</div>
161

    
162
		<nav class="action-buttons">
163
			<a href="<?=$_SERVER['PHP_SELF']?>" class="btn btn-default"><?=gettext("Back")?></a>
164
		</nav>
165
<?php
166
		break;
167
	}
168

    
169
	// Abort tests
170
	case 'abort':
171
	{
172
		$output = shell_exec($smartctl . " -X /dev/" . escapeshellarg($targetdev));
173
?>
174
		<div class="panel  panel-default">
175
			<div class="panel-heading"><h2 class="panel-title"><?=gettext('Abort')?></h2></div>
176
			<div class="panel-body">
177
				<pre><?=$output?></pre>
178
			</div>
179
		</div>
180
<?php
181
		break;
182
	}
183

    
184
	// Config changes, users email in xml config and write changes to smartd.conf
185
	case 'config':
186
	{
187
		if(isset($_POST['test']))	{
188

    
189
// FIXME				shell_exec($smartd . " -M test -m " . $config['system']['smartmonemail']);
190
			$savemsg = sprintf(gettext("Email sent to %s"), $config['system']['smartmonemail']);
191
			smartmonctl("stop");
192
			smartmonctl("start");
193
			$style = 'warning';
194
		}
195
		else if(isset($_POST['save']))
196
		{
197
			$config['system']['smartmonemail'] = $_POST['smartmonemail'];
198
			write_config();
199

    
200
			// Don't know what all this means, but it adds the config changed header when config is saved
201
			$retval = 0;
202
			config_lock();
203
			if(stristr($retval, "error") != true) {
204
				$savemsg = get_std_save_message($retval);
205
				$style = 'success';
206
				}
207
			else {
208
				$savemsg = $retval;
209
				$style='danger';
210
			}
211

    
212
			config_unlock();
213

    
214
			// Write the changes to the smartd.conf file
215
			update_email($_POST['smartmonemail']);
216

    
217
			// Send sig HUP to smartd, rereads the config file
218
			shell_exec("/usr/bin/killall -HUP smartd");
219
		}
220

    
221
	// Was the config changed? if so , print the message
222
	if ($savemsg)
223
		print_info_box($savemsg, $style);
224

    
225
	// Get users email from the xml file
226
	$pconfig['smartmonemail'] = $config['system']['smartmonemail'];
227

    
228
	$form = new Form();
229

    
230
	$section = new Form_Section('Configuration');
231

    
232
	$section->addInput(new Form_Input(
233
		'smartmonemail',
234
		'Email Address',
235
		'text',
236
		$pconfig['smartmonemail']
237
	 ));
238

    
239
	$form->add($section);
240

    
241
	if(!empty($pconfig['smartmonemail'])) {
242
		$form->addGlobal(new Form_Button(
243
			'test',
244
			'Send test email'
245
		))->removeClass('btn-primary')->addClass('btn-default');
246
	}
247

    
248
	print($form);
249

    
250
	break;
251
	}
252

    
253
	// Default page, prints the forms to view info, test, etc...
254
	default: {
255
// Information	
256
		$devs = get_smart_drive_list();
257

    
258
		$form = new Form(new Form_Button(
259
			'submit',
260
			'View'
261
		));
262

    
263
		$section = new Form_Section('Information');
264

    
265
		$section->addInput(new Form_Input(
266
			'action',
267
			null,
268
			'hidden',
269
			'info'
270
		));
271

    
272
		$group = new Form_Group('Info type');
273

    
274
		$group->add(new Form_Checkbox(
275
			'type',
276
			null,
277
			'Info',
278
			false,
279
			'i'
280
		))->displayAsRadio();
281

    
282
		$group->add(new Form_Checkbox(
283
			'type',
284
			null,
285
			'Health',
286
			true,
287
			'H'
288
		))->displayAsRadio();
289

    
290
		$group->add(new Form_Checkbox(
291
			'type',
292
			null,
293
			'SMART Capabilities',
294
			false,
295
			'c'
296
		))->displayAsRadio();
297

    
298
		$group->add(new Form_Checkbox(
299
			'type',
300
			null,
301
			'Attributes',
302
			false,
303
			'A'
304
		))->displayAsRadio();
305

    
306
		$group->add(new Form_Checkbox(
307
			'type',
308
			null,
309
			'All',
310
			false,
311
			'a'
312
		))->displayAsRadio();
313

    
314
		$section->add($group);
315

    
316
		$section->addInput(new Form_Select(
317
			'device',
318
			'Device: /dev/',
319
			false,
320
			array_combine($devs, $devs)
321
		));
322

    
323
		$form->add($section);
324
		print($form);
325

    
326
// Tests
327
		$form = new Form(new Form_Button(
328
			'submit',
329
			'Test'
330
		));
331

    
332
		$section = new Form_Section('Perform self-tests');
333

    
334
		$section->addInput(new Form_Input(
335
			'action',
336
			null,
337
			'hidden',
338
			'test'
339
		));
340

    
341
		$group = new Form_Group('Test type');
342

    
343
		$group->add(new Form_Checkbox(
344
			'testType',
345
			null,
346
			'Offline',
347
			false,
348
			'offline'
349
		))->displayAsRadio();
350

    
351
		$group->add(new Form_Checkbox(
352
			'testType',
353
			null,
354
			'Short',
355
			true,
356
			'short'
357
		))->displayAsRadio();
358

    
359
		$group->add(new Form_Checkbox(
360
			'testType',
361
			null,
362
			'Long',
363
			false,
364
			'long'
365
		))->displayAsRadio();
366

    
367
		$group->add(new Form_Checkbox(
368
			'testType',
369
			null,
370
			'Conveyance',
371
			false,
372
			'conveyance'
373
		))->displayAsRadio();
374

    
375
		$group->setHelp('Select "Conveyance" for ATA disks only');
376
		$section->add($group);
377

    
378
		$section->addInput(new Form_Select(
379
			'device',
380
			'Device: /dev/',
381
			false,
382
			array_combine($devs, $devs)
383
		));
384

    
385
		$form->add($section);
386
		print($form);
387

    
388
// Logs
389
		$form = new Form(new Form_Button(
390
			'submit',
391
			'View'
392
		));
393

    
394
		$section = new Form_Section('View logs');
395

    
396
		$section->addInput(new Form_Input(
397
			'action',
398
			null,
399
			'hidden',
400
			'logs'
401
		));
402

    
403
		$group = new Form_Group('Log type');
404

    
405
		$group->add(new Form_Checkbox(
406
			'type',
407
			null,
408
			'Error',
409
			true,
410
			'error'
411
		))->displayAsRadio();
412

    
413
		$group->add(new Form_Checkbox(
414
			'test',
415
			null,
416
			'Self-test',
417
			false,
418
			'selftest'
419
		))->displayAsRadio();
420

    
421
		$section->add($group);
422

    
423
		$section->addInput(new Form_Select(
424
			'device',
425
			'Device: /dev/',
426
			false,
427
			array_combine($devs, $devs)
428
		));
429

    
430
		$form->add($section);
431
		print($form);
432

    
433
// Abort
434
		$btnabort = new Form_Button(
435
			'submit',
436
			'Abort'
437
		);
438

    
439
		$btnabort->removeClass('btn-primary')->addClass('btn-danger');
440

    
441
		$form = new Form($btnabort);
442

    
443
		$section = new Form_Section('Abort');
444

    
445
		$section->addInput(new Form_Input(
446
			'action',
447
			null,
448
			'hidden',
449
			'abort'
450
		));
451

    
452
		$section->addInput(new Form_Select(
453
			'device',
454
			'Device: /dev/',
455
			false,
456
			array_combine($devs, $devs)
457
		));
458

    
459
		$form->add($section);
460
		print($form);
461

    
462
		break;
463
	}
464
}
465

    
466
include("foot.inc");
(35-35/237)