Friday, August 21, 2015

CAVE HTCondor Sysview

CHTC Visualization via CAVE

CHTC visualization
"UW–Madison runs a high-throughput cluster system using the HTCondor scheduling system which is operated and maintained by the Center for High Throughput Computing (CHTC). This project focuses on visualizing performance and load distribution of the cluster by displaying collected log files. The log files are timestamped and gathered over long time periods; the visualization plays them back one frame at a time and with the ability to pause or reverse. Load of the cluster and of individual nodes can be therefore not only seen, but also traced in time. Questions, such as, “Which part of the cluster is running idle at 2 a.m.?” or “Where is the highest load concentrated?” can be answered quickly and intuitively, with the time-varying datasets showing trends and patterns in the cluster usage. The project is a collaboration between the LEL and the CHTC with Markus Broecker from the LEL, and Becky Gietzel and Nate Yehle from the CHTC."

References:

 http://wid.wisc.edu/research/lel/projects/

 https://github.com/bgietzel/htcondor-sysview

Building a Linux Cluster out of Windows Desktops

Using htcondor, windows7, vmware, and linux you can build a linux cluster on top of windows desktops.

Step 1
Install Htcondor, VMWare Player,  VIX, and VMWare Perl scripting API on Windows 7 machines.

use this as installer.bat to preload the msi installer with your pool data.  This requires you have a file at windows.php which loads a default config or overrides if it hostname.local is in the same dir.

REM CHTC URL Config HTCondor Windows7 Installer for CSL 
@echo on
cd /d "%~dp0"
set ARGS=
set ARGS=%ARGS% NEWPOOL=N
set ARGS=%ARGS% POOLNAME="CS"
REM RUNJOBS=c to use keyboard daemon to stop jobs when there is activity
set ARGS=%ARGS% RUNJOBS=C
set ARGS=%ARGS% VACATEJOBS=Y
REM SUBMITJOBS=N windows nodes no the cs pool are not submitters
set ARGS=%ARGS% SUBMITJOBS=N
set ARGS=%ARGS% CONDOREMAIL=""
REM defaults incase http get of real config fails
set ARGS=%ARGS% HOSTALLOWREAD="*.wisc.edu  execute-side@matchsession"
set ARGS=%ARGS% HOSTALLOWWRITE="*.cs.wisc.edu *.chtc.wisc.edu"
set ARGS=%ARGS% HOSTALLOWADMINISTATOR="condor.cs.wisc.edu"
set ARGS=%ARGS% INSTALLDIR="C:\Condor"
set ARGS=%ARGS% POOLHOSTNAME="condor.cs.wisc.edu"
set ARGS=%ARGS% ACCOUNTINGDOMAIN="none"
set ARGS=%ARGS% JVMLOCATION="java.exe"
set ARGS=%ARGS% SMTPSERVER=""
set ARGS=%ARGS% USEVMUNIVERSE=Y
set ARGS=%ARGS% VMNETWORKING=C
set ARGS=%ARGS% VMMAXNUMBER=1
set ARGS=%ARGS% VMMEMORY="$(DETECTED_MEMORY)/2"
set ARGS=%ARGS% PERLLOCATION="C:\sperl-5.18.2.1\perl.exe"
set ARGS=%ARGS% ACCOUNTINGDOMAIN=cs.wisc.edu
set ARGS=%ARGS% LOCAL_CONFIG_FILE = condor_urlfetch -TOOL 
http://url/windows.php?host=$(HOSTNAME) 
 /etc/condor/condor_configt.url_cache |
del c:\condor\condor_config
start /wait msiexec /q /l* "C:\Program Files\CSL\logs\condor-8.2.5.txt" /i condor-8.2.5-284806-Windows-x86.msi %ARGS% REBOOT=Suppress
net start condor 
 
 
# cat windows.php
<?php

$base_config = "WINDOWS7";
$base_config_lines = file($base_config);

$host = $_GET["host"] . ".local";
if (file_exists($host)) {
  $config_lines = file($host);
  $config = array_merge($base_config_lines, $config_lines);
}
else {
  $config = $base_config_lines;
}

foreach ($config as $line_num => $line ) {
  echo $line;
}

?>

# cat WINDOWS7
COLLECTOR_HOST = $(CONDOR_HOST)
CCB_ADDRESS = $(CONDOR_HOST)
PRIVATE_NETWORK_NAME = cs.wisc.edu
STARTER_ALLOW_RUNAS_OWNER = False
DYNAMIC_RUN_ACCOUNT_LOCAL_GROUP = Condor Reuse Users
ALLOW_WRITE = $(IP_ADDRESS)


#VM Policy
VM_GAHP_LOG = C:\Condor\log\VMGAHPLog
VMWARE_PERL=C:\sperl-5.18.2.1\perl\bin\perl.exe
VM_TYPE = vmware
VM_NETWORKING = TRUE
VM_NETWORKING_TYPE = NAT
VM_MEMORY= $(DETECTED_MEMORY) - 512
VM_MAX_NUMBER = $(DETECTED_CORES)

#preemption policy
use policy : desktop
#start jobs if the non condor load is under .3 and the keyboard has been idle for at least 60 min
START = (( LoadAvg - CondorLoadAvg) <= 0.3 ) && (KeyboardIdle > 60 * 60)
PREEMPT = ((Activity == "Suspended") && ((time() - EnteredCurrentActivity) > 10 * 60)) || (SUSPEND && (WANT_SUSPEND ==False))
KILL = $(SUSPEND)
#KILL = ((KeyboardIdle < 60) || ( (CpuBusyTime > 120) && ifThenElse(JobStart =!= UNDEFINED, (time() - JobStart),0 > 90)))
SLOTS_CONNECTED_TO_CONSOLE = $(NUM_CPUS)
SLOTS_CONNECTED_TO_KEYBOARD = $(SLOTS_CONNECTED_TO_CONSOLE)

#slot policy
NUM_SLOTS=1
NUM_SLOTS_TYPE_1=1
SLOT_TYPE_1_PARTITIONABLE=true
SLOT_TYPE_1 = cpus=100%,disk=100%,swap=100%,gpus=100%
ASSIGN_CPU_AFFINITY=true
use FEATURE : GPUs

#ADMIN Policy
CONDOR_ADMIN = admin@domain.com
HOSTALLOW_ADMINISTRATOR = $(CONDOR_HOST)


Step 2
Create VMWare VM which starts htcondor on boot and randomizes its name, I take a random entry from cracklib-dicts.

Step 3
Submit vm directory to your windows machines, and watch as the linux vms start up and take jobs that otherwise would not run on windows.

Using vmsl65 as the directory of your vmware image this submit file will send it out to windows hosts to create your linux vms:

#cat vmsl65.sub
universe = vm
executable = linux.iso
vm_type = vmware
vm_networking = true
vm_networking_type=nat
vmware_dir = vmsl65
vmware_should_transfer_files = YES
vmware_snapshot_disk = false
vm_memory = 2000
request_memory = 2004
request_disk = 20000000
log = ~/vmsl65_$(Cluster)_$(Process).log
notification = NEVER
requirements = Target.OpSys == "WINDOWS"
queue 5000

#condor_submit vmsl65.sub

References:
Thanks TJ!

https://twiki.grid.iu.edu/bin/view/CampusGrids/LinuxCondorPoolOnWindowsLabMachines

SELinux: An Introduction

SELinux:  An Introduction
6/11/2005
 

SELinux is an implementation of a Mandatory Access Control architecture called 
Flask, using the Linux Kernel.  Up until its release such systems were not very 
widespread.  Currently however, Fedora Core 3 comes with SELinux installed, 
and many other distributions such as Debian and Slackware are adopting it.

According to the NSA, a MAC is needed when "protection decisions must not be 
decided by the object owner, and the system must enforce the protection 
descisions over the wishes or intentions of the object owner". 

Flask evolved from a long line of NSA research on such MAC systems.  
Mandatory Access Controls were originally built to enforce security clearances 
given to users for objects in the system.  SELinux takes the concept one step 
farther, applying such restrictions to almost every definable object a system could 
have.

Non SELinux systems use a Discretionary Access control system which is 
"vulnerable to tampering and bypass, and malicious or flawed applications can 
easily cause failures in system security."  This is due to the fact that actions are 
limited only by user identity and ownership, not by role.  

For example, an attacker gaining control of a program in a DAC system is 
allowed to do anything with that control, and can access anything the user the 
process runs as can access.  This is often not a good thing, as it allows the 
corrupted process to do malicious things regardless of what role the program 
originally was meant for.

SELinux policy helps solve this problem by allowing for very fine grained access 
control.  Some policies are separation policies to enforce legal and classification 
restrictions on data, containment policies to restrict process access to data and 
files, integrity policies to protect against modifications to data, and invocation 
policies to control how processes run on the system.

In order for SELinux to function on Fedora Core 3, install libselinux, selinux-
policy-strict, setools, checkpolicy, and policycoreutils rpms.  
The system-config-securitylevel and setools-gui rpms are also helpful to see 
some good examples of policies assignable to a user.  In order to compile some 
of the later examples, you will need a also need the libselinux-devel and selinux-
policy-strict-sources rpms.

SELinux accomplishes Mandatory Access Control with Flask and a "combination 
of a Type Enforcement (TE) model and a Role-Based Access Control (RBAC) 
model.”  The TE model is implemented by “binding a security attribute called a 
type to each object". 


Classes of objects are defined in the 
/etc/selinux/strict/src/policy/flask/security_classes file.
A class is a kind of object such as a filesystem, file, directory, or socket.  Classes 
each have an access vector defining what functions they preform.  Access 
vectors are defined here: 
/etc/selinux/strict/src/policy/flask/access_vectors
The file class can read, write, create, and append for example, while the socket 
class can also read and write along with the bind, listen and connect.  Types 
given to processes are also known as domains.
The second part of flask, Role-Based Access Control, assigns roles to users.  
The roles are then allowed some access vectors to various types.  The 
combination of user, role and type is a security “context”.
The SELinux policy determines which security contexts are allowed.
If SELinux is enabled on a Linux kernel, security contexts will be available for 
viewing.  
View the context of a file:
 [root@xoci ~]# ls --context /etc/passwd
-rw-r--r-- root root system_u:object_r:etc_t /etc/passwd
View the context of a sshd process:
[root@xoci ~]# ps ax --context | grep sshd
 2886 system_u:system_r:kernel_t      /usr/sbin/sshd

You can also view information on the current policy with the seinfo program.  This 
also seems to be hard coded to the strict policy.  Try it with a few settings:
seinfo -t show types, seinfo -u show users, seinfo -r show roles
SELinux is configured in the /etc/selinux/config file.  For testing purposes use the 
following settings:
SELINUX=permissive #(logs but does not enforce)
SELINUXTYPE=strict
Permissive mode will print warnings but not deny access, and is very useful 
when writing your policy or debugging a program.  On fedora research only 
seemed to have success compiling policies of the strict type, as it seems setools 
on fedora has a path hard coded to the strict policy.
Once SELinux is configured, try to compile and install a policy from source.  This 
is done from the /etc/selinux/strict/etc/policy directory.
The following make commands work:
make policy will make the policy but not install it
make load will make and load the policy
make relabel will relabel the type of any files to match the policy.
make load takes the files in the policy source directory, and attempts to process 
them with the m4 macro processor into a policy.conf file. This file is then passed 
to the SELinux policy compiler checkpolicy, which creates the the binary policy 
/etc/selinux/strict/policy/policy.18 for loading into the kernel.
After running a make load try rebooting the machine and login as root.
Create a new user account, setest.  Login with this account.
setest@pc-00071 ~]$ id -Z
user_u:user_r:user_t
The SILinux policy assigns the above context by default to undefined users.
Add the user_r and staff_r roles to setest by editing 
/etc/selinux/strict/src/policy/users.
user setest roles { user_r staff_r };
Save the file and run make load again.  Then login setest and check the context.
[setest@pc-00071 home]$ id -Z
setest:user_r:user_t
Try changing roles to staff_r
[setest@pc-00071 ~]$ newrole -r staff_r
Authenticating setest.
Password:
setest@pc-00071 ~]$ id -Z
setest:staff_r:staff_t  

SELinux allows for the creation of new types as well.  Create a new file here:
/etc/selinux/strict/src/policy/types/custom.te
Add a new type declaration to this file:
type setestfile_t, file_type, sysadminfile;
This adds a new type to the policy, setestfile_t with the attributes of file_type and 
sysadminfile.
The different attributes for types are listed in /etc/selinux/strict/src/policy/attrib.te.
Adding a new role requires modifying 
/etc/selinux/strict/src/policy/domains/user.te.
To add the setest_r role, add these to the user.te file:
full_user_role(setest) 
priv_user(setest)
Then modify /etc/selinux/strict/src/policy/macros/user_macros.te by adding:
role setest_r types $1;
Run make load again, and then do a seinfo -t | grep setest_t
You should see a list of types starting with setest_t, including setest_home_dir_t 
and  setest_home_t for examples.  What happened was the macro processor 
created all the default types to go along with the role.  
Next add setest_r:setest_t to /etc/selinux/strict/src/policy/appconfig/default_type.  
This ensures that SELinux knows what domain to place a user in when first 
logging in.

Now allow some access to the new setestfile_t, edit custom.te again and add:
allow user_t setestfile_t:file { read };
allow setest_t setestfile_t:file { read write execute };
Then add setest_r to the list of roles granted to the user setest in the users file.
Now that a new user, type and role have been created, run some tests to see if 
the kernel is actualy using them.  Logged in as setest:
[setest@pc-00071 ~]$ touch afile
[setest@pc-00071 ~]$ ls --context afile
-rw-rw-r--  setest   setest   setest:object_r:user_home_t      afile
Try to chang the context of afile: chcon -t setestfile_t.
This works because we are in permissive mode, but it leaves the following log:
Jun 11 06:01:12 pc-00071 kernel: audit(1118487672.558:0): avc:  denied  { 
relabelto } for  pid=22595 exe=/usr/bin/chcon name=afile dev=dm-0 ino=2142232 
scontext=setest:user_r:user_t tcontext=setest:object_r:setestfile_t tclass=file

What this means is the kernel noted that the context  setest:user_r:user_t 
executed a relabelto on a  user_home_t object.  Since this was not explicitly 
allowed in the policy an error message is generated.
The user_r can only read this file, so cat afile is allowed but echo "test" >> afile 
creates an error message for the "append" attribute.
SELinux also has C libraries which can be used in programs.  The following code 
shows how to manipulate security contexts and print out SELinux information.
#include <stdio.h>
#include <stdlib.h>
#include <selinux/selinux.h>
#include <selinux/context.h>
//this code prints selinux related information
int main (int argc, char **argv)
{
  printf("Checking if selinux is enabled...\n");
  if(is_selinux_enabled())
    {printf("this program is running on a SELinux kernel\n");} 
  else
    {printf("this program is not running on a SELinux kernel\n");}
  int permissive = 0;
  int enforcing = 1;
  if(security_getenforce() == permissive)
    {printf("SELinux is running in permissive mode\n");}
  if(security_getenforce() == enforcing)
    {printf("SELinux is running in enforcing mode\n");}
  int rcc;
  typedef char* security_context_t; 
  security_context_t scon;
  printf("getting this program's current context...\n");
  rcc = getcon(&scon);
     if (rcc < 0) 
     {
        perror("getcon");
        return -1;
     }
     printf("this program's security_context_t is: = %s\n",scon);
     context_t newcon;
     //creat a new context_t from the contents of scon
     newcon = context_new(scon);

     //free the memory used by scon
     freecon(scon);
     //display context attributes
     char* newcontexttype;
     newcontexttype = context_type_get(newcon);
     printf("this program's context_t type is: %s\n",newcontexttype);
     char* newcontextrole;
     newcontextrole = context_role_get(newcon);
     printf("this program's context_t role is: %s\n",newcontextrole);
     char* newcontextuser;
     newcontextuser = context_user_get(newcon);
     printf("this program's context_t user is: %s\n",newcontextuser);
     rcc = context_type_set(newcon, "faketype_t");
     rcc = context_role_set(newcon, "fakerole_r");
     rcc = context_user_set(newcon, "fakeuser_u");
     printf("context after setting fake type, role and user: 
%s\n",context_str(newcon));
     //check if context selinux is enabled and the context is valid 
     printf("Verifing security context...\n");
     if(security_check_context(newcon) < 0)
       {printf("invalid context: %s\n",context_str(newcon));}
     else
       {printf("valid context: %s \n",context_str(newcon));}
    return 0;
}

Compile this code with the following options:
gcc -lselinux -o print_selinux_status print_selinux_status.c
The code should output the following:

[user@pc-00071 final]$ ./print_selinux_status 
Checking if selinux is enabled...
this program is running on a SELinux kernel
SELinux is running in permissive mode
getting this program's current context...
this program's security_context_t is: = setest:user_r:user_t
this program's context_t type is: user_t
this program's context_t role is: user_r
this program's context_t user is: user
context after setting fake type, role and user: fakeuser_u:fakerole_r:faketype_t
invalid context: fakeuser_u:fakerole_r:faketype_t

The kernel also prints a check_context error:
 Jun 11 06:38:50 pc-00071 kernel: audit(1118489930.704:0): avc:  denied  { 
check_context } for  pid=22934 
exe=/home/user/final/print_selinux_statusscontext=setest:user_r:user_t 
tcontext=system_u:object_r:security_t tclass=security

This is because the user_r role does not have access to run functions using the 
check_context attribute.  Specifically, the security_check_context() function 
requires the calling process context be allowed to check_context on the 
system_u:object_r:security_t context.
Programs can change the context of their next exec by using the execve funtion.  
Here is a simple example which runs less, allowing you to see what context the 
process was run as.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <selinux/selinux.h>
#include <selinux/context.h>

//http://www.frech.ch/man/man3p/execve.3p.html

int main (int argc, char **argv)
{
typedef char* security_context_t; 
  security_context_t scon;
  int rcc;
 printf("getting this program's current context...\n");
  rcc = getcon(&scon);
     if (rcc < 0) 
     {
        perror("getcon");
        return -1;
     }
     printf("this program's security_context_t before setexeccon is: = %s\n",scon);
int ret;
char *cmd[] = { "less", "/etc/passwd", (char *)0 };
char *env[] = { "HOME=/usr/home", "LOGNAME=home", "TERM=vt220",(char *)0 
};
setexeccon("setest:setest_r:setest_t");
ret = execve ("/usr/bin/less", cmd, env);
}

Running this code with the setest:user_r:user_t  context of the command shell 
prints a kernel error.  This is due to the transition not being explicitly allowed in 
the SELinux policy.  When set to enforcing mode the power of selinux can be 
harnessed to defeat attacks which use a corrupted process to launch other 
processes.  SELinux could prevent or log any such attempts to operate outside 
the normal conditions needed for the service. Here is an example log of a context 
transition being denied.



Jun 11 06:58:15 pc-00071 kernel: audit(1118491095.820:0): avc:  denied  { 
transition } for  pid=23006 exe=/home/setest/execve_example path=/usr/bin/less 
dev=dm-0 ino=1348733 scontext=setest:user_r:user_t 
tcontext=setest:setest_r:setest_t tclass=process

In order to allow transitions between types, add this to the custom.te file:
allow user_t setest_t:process transition;

Once the transition is allowed, run the program again:
setest@pc-00071 ~]$ ./execve_example
then check the running processes with ps ax --context

After the setexeccon gives a new context, execve executes its arguments with 
that context.  
Running in memory: 23118 setest:setest_r:setest_t        less /etc/passwd
but the user who called execve_example only had setest:user_r:user_t context.

SELinux seems to be the future of security with Linux.  Using SELinux allows for 
greater control over every aspect of the operating system, to a degree never 
before seen in a publicly available operating system which can operate on 
commodity hardware.  These two facts combined should make a powerful 
combination which will continue to attract developers and administrators to 
SELinux.  SELinux being included in Fedora Core 3 shows that the ideas 
proposed are mature enough for mainstream adoption.  

References:

Stephen Smalley, "Configuring the SELinux Policy", January 2003
http://www.nsa.gov/selinux/papers/policy2.pdf (11 June 2005)

Peter Loscocco and Stephen Smalley, "Integrating Flexible Support for Security
Policies into the Linux Operating System", June 2001
http://www.nsa.gov/selinux/papers/freenix01/freenix01.html (11 June 2005)

Redhat, "Bugzilla Bug 125737  setools Makefile has incorrect policy install 
location defined" June 2004,
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=125737 (11 June 2005)

Mayank Sharma, "SELinux: Playing with fire" (January 2005)
http://security.linux.com/security/05/01/25/1423211.shtml?tid=124&tid=123&tid=113&t
id=35 (11 June 2005)

Faye Coker, "Getting Started with SE Linux HOWTO" (March 2004)
http://www.lurking-grue.org/GettingStartedWithNewSELinuxHOWTO.pdf (11 June 
2005)

Faye Coker, "Writing SE Linux Policy HOWTO" (March 2004)
http://www.lurking-grue.org/WritingSELinuxPolicyHOWTO.pdf (11 June 2005)

Kerry Thompson, "SELinux" (March 2003)
http://www.samag.com/documents/s=7835/sam0303a/0303a.htm (11 June 2005)

Ram Varma, "SELinux Programming" (April 2005)
http://www.ensl.cs.gwu.edu/resources/SELinux_20Programming (5 June 2005)

Susan Douglas and Korry Douglas, 2004, "Linux Timesaving Techniques for 
Dummies" , John Wiley & Sons.

Russel Coker, "SE Linux API Documentation" (January 2004)
Also, irc conversations with him in #selinux of irc.freenode.net (June 2005)

John Barkley, "Security in Open Systems" (July 1994)
http://csrc.nist.gov/publications/nistpubs/800-7/main.html (June 11 2005)


Wednesday, August 12, 2015

Dell Openmanage Kill Switch



This kill switch stops machines from running when  cooling systems go down and runs from /etc/cron.hourly.  Tested on on SL6.6 Dell R410 and dell R710s.   It requires you install Dell's Openmanage software.

# cat omreportkillswitch.sh
#!/bin/bash
#Kill Switch using chassis temptemp=$(/opt/dell/srvadmin/bin/omreport chassis temps|grep Reading|awk '{ print $3}'|cut -d'.' -f1)
#disable condor killswitch
if [ $temp -gt 28 ]
  then #WARNING temps over 28C stop condor
    /etc/init.d/condor stop
fi
#shutdown node killswitch
if [ $temp -gt 32 ]
  then #CRITICAL temps over 32C shutdown node
  /sbin/shutdown -h now
fi

Nagios check_ata

We get servers with disks which pass smart tests but have many ata errors.

I wrote a quick script based on check_mcelog to grep in the logs for ata errors which can point to a failing disk or loose cable.

# cat /usr/local/bin/check_ata
#!/bin/bash
#modified from check_mcelog
LOGFILE=/var/log/kern.log

if [ ! -f "$LOGFILE" ]
then
    echo "No logfile exists"
    exit 3
else
    ERRORS=$( grep -c -e "ATA bus error" -e "failed command" $LOGFILE )
    if [ $ERRORS -lt 1 ]
    then
        echo "OK: $ERRORS ATA errors found"
        exit 0
    elif [ $ERRORS -lt 100 ]
    then
        echo "WARNING: $ERRORS ATA errors found"
        exit 1
    else
        echo "CRITICAL: $ERRORS ATA errors found"
        exit 1
    fi
fi



For example we see these kernel errors:

Jun 25 16:19:50 e206 kernel: ata4.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
Jun 25 16:19:50 e206 kernel: ata4.00: BMDMA stat 0x24
Jun 25 16:19:50 e206 kernel: ata4.00: failed command: READ DMA EXT
Jun 25 16:19:50 e206 kernel: ata4.00: cmd 25/00:a0:00:d0:13/00:03:5f:00:00/e0 tag 20 dma 475136 in
Jun 25 16:19:50 e206 kernel:         res 51/40:00:00:d2:13/40:00:5f:00:00/00 Emask 0x9 (media error)
Jun 25 16:19:50 e206 kernel: ata4.00: status: { DRDY ERR }
Jun 25 16:19:50 e206 kernel: ata4.00: error: { UNC }
Jun 25 16:19:51 e206 kernel: ata4.00: configured for UDMA/133
Jun 25 16:19:51 e206 kernel: sd 3:0:0:0: [sdb]  Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
Jun 25 16:19:51 e206 kernel: sd 3:0:0:0: [sdb]  Sense Key : Medium Error [current] [descriptor]
Jun 25 16:19:51 e206 kernel: Descriptor sense data with sense descriptors (in hex):
Jun 25 16:19:51 e206 kernel:        72 03 11 04 00 00 00 0c 00 0a 80 00 00 00 00 00
Jun 25 16:19:51 e206 kernel:        5f 13 d2 00
Jun 25 16:19:51 e206 kernel: sd 3:0:0:0: [sdb]  Add. Sense: Unrecovered read error - auto reallocate failed
Jun 25 16:19:51 e206 kernel: sd 3:0:0:0: [sdb] CDB: Read(10): 28 00 5f 13 d0 00 00 03 a0 00
Jun 25 16:19:51 e206 kernel: end_request: I/O error, dev sdb, sector 1595134464
Jun 25 16:19:51 e206 kernel: ata4: EH complete

And these smart errors:
Aug 12 10:04:31 host smartd[3720]: Device: /dev/sdb [SAT], 2 Currently unreadable (pending) sectors
Aug 12 10:04:31 host smartd[3720]: Device: /dev/sdb [SAT], 2 Offline uncorrectable sectors

Yet the device checks out via smart:

# smartctl -H /dev/sdb
smartctl 6.3 2014-07-26 r3976 [x86_64-linux-2.6.32-504.16.2.el6.x86_64] (local build)
Copyright (C) 2002-14, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

This was tested on a SUN FIRE X2250 with Scientific Linux 6.6.

Based on:
https://github.com/solarkennedy/nagios-plugins/blob/master/check_mcelog