Category: Uncategorized

Monitor R1soft CDP with Nagios

Updated 2017-02-01:
This is the updated way we use to monitor our backup jobs, we now instead query the R1soft CDP datacenter console instead of the individual backup managers.

You will need atleast python 2.7, the python argparse and python suds packages. Then run like this: python –host –port 7080 –username admin –password admin

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import argparse
import datetime


    import suds
except ImportError:
    print 'You must install suds using pip or your package manager.'

# enable debug output
#import logging
#logging.basicConfig(filename='swagyolo.log',format='%(asctime)s %(levelname)s  %(message)s',level=logging.INFO)

parser = argparse.ArgumentParser(description='Check CDP datacenter console policy status')

parser.add_argument('--host', metavar='localhost', type=str, required=True, help='CDP datacenter console host')
parser.add_argument('--port', metavar='7080', type=str, help='API port')
parser.add_argument('--username', metavar='admin', type=str, required=True, help='CDP datacenter console username')
parser.add_argument('--password', metavar='admin', type=str, required=True, help='CDP datacenter console password')
parser.add_argument('--ssl', dest='ssl', action='store_true', help='Use SSL')

args = parser.parse_args()

def build_url(host, port, factory, ssl=False):
    protocol = 'https' if ssl else 'http'

    if port is None:
        port = 7080

    url = '{protocol}://{host}:{port}/{factory}?wsdl'.format(

    return url

def get_manager_by_id(managers, id):
    if managers is None:
        return None

    for m in managers:
        if m['id'] == id:
            return m

    return None

policy_url = build_url(, args.port, 'Policy')
policy = suds.client.Client(policy_url, username=args.username, password=args.password)

if policy is None:
    print 'CRITICAL: Invalid suds SOAP policy'

cdp_url = build_url(, args.port, 'CDP')

    cdp = suds.client.Client(cdp_url, username=args.username, password=args.password)
except Exception as e:
    print 'CRITICAL: Failed to setup suds SOAP with exception %s' % (e)

if cdp is None:
    print 'CRITICAL: Invalid suds SOAP cdp'

managers = cdp.service.getRegisteredCDPS()

if managers is None:
    print 'CRITICAL: Failed to get managers'

policies = policy.service.getPolicies()

if policies is None:
    print 'CRITICAL: Could not get policies'

stats = {}
stats['ok'] = 0
stats['warning'] = 0
stats['error'] = 0
stats['unknown'] = 0
stats['disabled'] = 0
stats['lastrun'] = 0

data = []

for p in policies:
    enabled = p['enabled']
    name = p['name']
    freq = p['replicationScheduleFrequencyType']

    if freq != 'ON_DEMAND':
        if 'lastReplicationRunTime' in p:
            lastrun = p['lastReplicationRunTime']
            lastrun = 0

        if 'nextReplicationRunTime' in p:
            nextrun = p['nextReplicationRunTime']
            nextrun = 0
        lastrun = '0'
        nextrun = '0'

    state = p['state']

    manager = get_manager_by_id(managers, p['CDPId'])

    if enabled == False:
        stats['disabled'] = stats['disabled'] + 1
            'name': name,
            'manager': manager['name'],
            'status': 'DISABLED'

    now =
    lower = None

    if freq == 'DAILY':
        lower = now - datetime.timedelta(days=1)
    elif freq == 'WEEKLY':
        lower = now - datetime.timedelta(weeks=1)
    elif freq == 'MONTHLY':
        lower = now - datetime.timedelta(months=1)
    elif freq == 'ON_DEMAND':
        lower = None
        lower = None

    if lower is not None and lastrun != 0 and nextrun != 0:
        if lastrun <= lower:
            stats['lastrun'] = stats['lastrun'] + 1
                'name': name,
                'manager': manager['name'],
                'status': 'LAST RUN ERROR'
            data.append('%s on %s has not been backed up properly last time!' % (name, manager['name']))

    if state == 'UNKNOWN':
        stats['unknown'] = stats['unknown'] + 1
            'name': name,
            'manager': manager['name'],
            'status': 'UNKNOWN'
    elif state == 'ERROR':
        stats['error'] = stats['error'] + 1
            'name': name,
            'manager': manager['name'],
            'status': 'ERROR'
    elif state == 'ALERT':
        stats['warning'] = stats['warning'] + 1
            'name': name,
            'manager': manager['name'],
            'status': 'ALERT'
        stats['ok'] = stats['ok'] + 1
            'name': name,
            'manager': manager['name'],
            'status': 'OK'

final_status = 'OK'
final_code = STATE_OK

if stats['error'] >= 1 or stats['lastrun'] >= 1:
    final_status = 'CRITICAL'
    final_code = STATE_CRITICAL
elif stats['warning'] >= 1:
    final_status = 'WARNING'
    final_code = STATE_WARNING
elif stats['unknown'] >= 1:
    final_status = 'UNKNOWN'
    final_code = STATE_UNKNOWN

print '%s: %s ok, %s error, %s warning, %s unknown, %s disabled, %s last run error' % (final_status, stats['ok'], stats['error'], stats['warning'], stats['unknown'], stats['disabled'], stats['lastrun'])

Old article below:
So my company is using R1soft’s product CDP to backup some of our servers.
I wanted to have a clear overview of the status of our backup machines instead of recieving their email reports, here is a working Nagios plugin to monitor CDP.

What it does is connect to CDP’s SOAP API using PHP and gets the state of all policies then loops through it and checks if it’s OK or not.
The authentication is done against a “Local” user on that backup manager.

./check_r1soft_cdp -H -u admin -p test = IP or hostname of the backup manager
admin = username
test = password

If you want to use it over SSL you can add the “s” option, example.
./check_r1soft_cdp -H -u admin -p test -s

Copy the nagios plugin below to /usr/lib/nagios/plugins with your desired filename, for example check_r1soft_cdp.
Make sure it’s executable (chmod +x check_r1soft_cdp) and then setup a command in Nagios.

define command{
command_name check_r1soft_cdp
command_line $USER1$/check_r1soft_cdp -H $HOSTADDRESS$ -u $ARG1$ -p $ARG2$


//check_r1soft_cdp - nagios plugin for R1soft CDP
//Modified by trigger
//Originally by Rogierm (

$options = getopt("H:u:p:s");

if (!is_array($options) ) {
        print "There was a problem reading in the options.\r\n";

if (count($options) < 3) {
        print "Not all options are set.\r\n";


if(isset($options['s']) && !$options['s']) {


if(isset($options['u'])) {

if(isset($options['p'])) {

try {
        $PROTO = "http";

        if(isset($options['s']) && !$options['s']) {
                $PROTO = "https";

        $policyClient = new soapclient("$PROTO://$HOST:$PORT/Policy2?wsdl",

                'login' => "$USER",
                'password' => "$PASS",
                'trace' => 1,
                'cache_wsdl' => WSDL_CACHE_NONE,
                'features' => SOAP_SINGLE_ELEMENT_ARRAYS)

        $allPoliciesForUser = $policyClient->getPolicies();

        $failstring = '';
        $count_unk = 0;
        $count_err = 0;
        $count_warn = 0;
        $count_ok = 0;
        $count_dis = 0;
        $alldis = '';

        foreach($allPoliciesForUser->return as $tmp)
                $enabled = $tmp->enabled;

                if(!$enabled) {
                        $alldis .= $tmp->name . " is DISABLED\n";

                if ($tmp->state == "UNKNOWN"){
                        $failstring .= $tmp->name . " is in a UNKNOWN state\n";
                        $unknown = 1;
                else if ($tmp->state == "ERROR"){
                        $failstring .= $tmp->name . " has ERROR\n";
                        $error = 1;
                else if ($tmp->state == "ALERT"){
                        $failstring .= $tmp->name . " has ALERT(s)\n";
                        $warning = 1;
                else {
                        $ok = 1;

        if ($error==1) {
                print "CDP ERROR - OK=" . $count_ok . " DIS=" . $count_dis . " WARN=" . $count_warn . " ERR=" . $count_err.  " UNK=" . $count_unk . " | OK=" . $count_ok . ",DIS=" . $count_dis . ",WARNING=" . $count_warn . ",ERROR=" . $count_err . ",UNKNOWN=" . $count_unk . "\n\n";
                print $alldis . "\n";
                print $failstring;
        } elseif ($warning==1 || $count_dis > 0) {
                print "CDP WARNING - OK=" . $count_ok . " DIS=" . $count_dis . " WARN=" . $count_warn . " ERR=" . $count_err.  " UNK=" . $count_unk . " | OK=" . $count_ok . ",DIS=" . $count_dis . ",WARNING=" . $count_warn . ",ERROR=" . $count_err . ",UNKNOWN=" . $count_unk . "\n\n";
                print $alldis . "\n";
                print $failstring;
        } elseif ($unknown==1) {
                print "CDP UNKNOWN - OK=" . $count_ok . " DIS=" . $count_dis . " WARN=" . $count_warn . " ERR=" . $count_err.  " UNK=" . $count_unk . " | OK=" . $count_ok . ",DIS=" . $count_dis . ",WARNING=" . $count_warn . ",ERROR=" . $count_err . ",UNKNOWN=" . $count_unk . "\n\n";
                print $alldis . "\n";
                print $failstring;
        } elseif ($ok==1) {
                print "CDP OK - OK=" . $count_ok . " DIS=" . $count_dis . " WARN=" . $count_warn . " ERR=" . $count_err.  " UNK=" . $count_unk . " | OK=" . $count_ok . ",DIS=" . $count_dis . ",WARNING=" . $count_warn . ",ERROR=" . $count_err . ",UNKNOWN=" . $count_unk . "\n";
        } else {
                echo "Should never reach this state!??!\n";
catch (SoapFault $exception)
        echo "Failed to find all status of all policies";
        echo $exception;

This is a modified version of Rogierm’s nagios plugin that can be found here.
I have added performance data, more arguments, checking disabled policies and added what I think is better output.
You can always click on the service to get a full list of policies etc.


CVE-2014-6271 “Shell Shock”: Compiling Bash for older Linux systems (Debian 4, Debian 6, RHEL 4 etc)


Since this “new” (22-year-old) bug was found in Bash our company has worked hard since yesterday afternoon until now.
We have some very old systems running on RedHat Enterprise Linux 4 (RHEL 4) and some older Debian machines running for example Debian 4 etch and so on.

Here is some quick notes to help you out.

RHEL 4/CentOS 4
Firstly, you need Yum to install GCC (if you don’t have it already). We have found that this one usually works fine (after fixing some dependency packages).

The dependencies that was used to fix this issue is.

Note that this is for i386!
I will include a list below of all the mirrors where I found these, so that you can grab for other architectures.
yum mirror
python-sqlite mirror
python-urlgrabber mirror
python-elementtree mirror

I have made a mirror of all above RPM’s.
Here: yum.tar.gz

/etc/yum.conf for RHEL 4/CentOS 4.

name=CentOS-$releasever - Base

#released updates
name=CentOS-$releasever - Updates

#packages used/produced in the build but not released
name=CentOS-$releasever - Addons

#additional packages that may be useful
name=CentOS-$releasever - Extras

#additional packages that extend functionality of existing packages
name=CentOS-$releasever - Plus

#contrib - packages by Centos Users
name=CentOS-$releasever - Contrib

Then you can download and compile Bash, as below.

mkdir -p /usr/src/bash
cd /usr/src/bash
gunzip bash-4.3.tar.gz
tar xvf bash-4.3.tar
cd bash-4.3
patch -p0 -i bash43-025
sed -i "s/\#define PATCHLEVEL 0/\#define PATCHLEVEL 25/g" patchlevel.h
./configure --prefix=/usr --bindir=/bin --docdir=/usr/share/doc/bash-4.3 --without-bash-malloc --with-installed-readline
make install

You can then verify it by running the new Bash binary and confirming that it’s fixed.

bash --version
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

The last row will say “vulnerable” if you are vulnerable, else it will tell you some warnings.

Debian 4 and older/newer
See the compilation like above.

Debian 6 Squeeze
Easiest way is to add the LTS repository that is still maintained.
I.e changing in your /etc/apt/sources.list from

deb squeeze main contrib non-free


deb squeeze-lts main contrib non-free

and then updating by using apt.
(apt-get update; apt-get upgrade)

I will keep this post updated as I go along.

Keywords: CVE-2014-6271, Shell Shock, #bashbug, bash exploit, debian 4 etch, debian 6 squeeze, rhel 4, centos 4

NVIDIA drivers Debian GNU/Linux on Fluxbox

I recently wanted to install my older Dell computer that has a NVIDIA GeForce GT640 graphics card but ran into some trouble so I thought I might just share it here.
First off, find out what graphics card you have.

lspci | grep -i vga
00:02.0 VGA compatible controller: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller (rev 09)
01:00.0 VGA compatible controller: NVIDIA Corporation GK107 [GeForce GT 640 OEM] (rev a1)

Then go to NVIDIA’s website and download the correct drivers.

I downloaded the 343.22 driver for Linux x64 (downloads the file:
Make sure you have the required packages that the installation requires.

sudo apt-get install make gcc linux-headers-`uname -r`

Now give the downloaded installer ( executable permission and run it.
Make sure that you have closed any X sessions you might have, else the installer will fail and give you an error message.

sudo chmod +x
sudo ./

You will get a warning from the installer if your GCC version is different from the one that compiled the kernel, it will usually work fine compiling the NVIDIA driver anyway but if you want to make sure that it’s done completely correct set the CC export variable to the GCC version that compiled your kernel.

export CC=gcc4.6

Walk through the installation, I said yes to installing ia32/32bit libraries too.
The last step will ask you if you want to run nvidia-xconfig in order to generate the /etc/X11/xorg.conf configuration for the NVIDIA card, I said yes.

Up to this point all worked OK.
I made sure that the driver was loaded and was just about to start X when I got problem.

sudo lsmod | grep -i nvidia
nvidia              11053965  39 
drm                   236561  4 i915,drm_kms_helper,nvidia
i2c_core               28324  6 drm,i915,i2c_i801,drm_kms_helper,i2c_algo_bit,nvidia
[ 83255.555] (EE) No devices detected.
[ 83255.555] (EE) 
Fatal server error:
[ 83255.555] (EE) no screens found(EE) 

You can confirm that it was indeed loading the NVIDIA driver.

[ 83255.542] (II) LoadModule: "glx"
[ 83255.542] (II) Loading /usr/lib/xorg/modules/extensions/
[ 83255.554] (II) Module glx: vendor="NVIDIA Corporation"
[ 83255.554]    compiled for 4.0.2, module version = 1.0.0
[ 83255.554]    Module class: X.Org Server Extension
[ 83255.554] (II) NVIDIA GLX Module  343.13  Thu Jul 31 18:36:09 PDT 2014
[ 83255.554] (II) LoadModule: "nvidia"
[ 83255.554] (II) Loading /usr/lib/xorg/modules/drivers/
[ 83255.554] (II) Module nvidia: vendor="NVIDIA Corporation"
[ 83255.554]    compiled for 4.0.2, module version = 1.0.0
[ 83255.554]    Module class: X.Org Video Driver
[ 83255.554] (II) NVIDIA dlloader X Driver  343.13  Thu Jul 31 18:16:01 PDT 2014
[ 83255.554] (II) NVIDIA Unified Driver for all Supported NVIDIA GPUs

I dont care! How did you resolve it?
What I did was setting the BusID in the xorg.conf configuration.

Section "Device"
    Identifier     "Device0"
    Driver         "nvidia"
    VendorName     "NVIDIA Corporation"
    BusID          "PCI:01:00:0"

The BusID is the ID you see when running lspci.

01:00.0 VGA compatible controller: NVIDIA Corporation GK107 [GeForce GT 640 OEM] (rev a1)

My complete xorg.conf configuration looks like this, I have only changed the BusID nothing else, all other configuration is generated by the nvidia-xconfig command.

# nvidia-xconfig: X configuration file generated by nvidia-xconfig
# nvidia-xconfig:  version 343.13  (buildmeister@swio-display-x64-rhel04-10)  Thu Jul 31 19:30:08 PDT 2014

Section "ServerLayout"
    Identifier     "Layout0"
    Screen      0  "Screen0"
    InputDevice    "Keyboard0" "CoreKeyboard"
    InputDevice    "Mouse0" "CorePointer"

Section "Files"

Section "InputDevice"
    # generated from default
    Identifier     "Mouse0"
    Driver         "mouse"
    Option         "Protocol" "auto"
    Option         "Device" "/dev/psaux"
    Option         "Emulate3Buttons" "no"
    Option         "ZAxisMapping" "4 5"

Section "InputDevice"
    # generated from default
    Identifier     "Keyboard0"
    Driver         "kbd"

Section "Monitor"
    Identifier     "Monitor0"
    VendorName     "Unknown"
    ModelName      "Unknown"
    HorizSync       28.0 - 33.0
    VertRefresh     43.0 - 72.0
    Option         "DPMS"

Section "Device"
    Identifier     "Device0"
    Driver         "nvidia"
    VendorName     "NVIDIA Corporation"
    BusID          "PCI:01:00:0"

Section "Screen"
    Identifier     "Screen0"
    Device         "Device0"
    Monitor        "Monitor0"
    DefaultDepth    24
    SubSection     "Display"
        Depth       24

If this still does not resolve your problem, then try to block the Nouveau driver if your NVIDIA installation didn’t do this for you.

blacklist vga16fb
blacklist nouveau
blacklist rivafb
blacklist nvidiafb
blacklist rivatv

The easiest way to make sure the driver get’s blocked is to restart the computer.
I hope this helped you.


Fixing Logitech G35 USB headset on Debian Linux


I was trying to get sound working for my Logitech G35 USB headset.
Firstly I changed the audio priority in /etc/modprobe.d/alsa-base.conf by changing the following:

options snd-usb-audio index=-1

After that I reloaded ALSA and the USB headset is now the primary audio output.

sudo /etc/init.d/alsa-utils stop
sudo alsa reload
sudo /etc/init.d/alsa-utils start
cat /proc/asound/cards
<code class="language-bash"> 0 [Headset        ]: USB-Audio - Logitech G35 Headset
                      Logitech Logitech G35 Headset at usb-0000:00:14.0-3.4, full speed
 1 [PCH            ]: HDA-Intel - HDA Intel PCH
                      HDA Intel PCH at 0xf5130000 irq 47
 2 [NVidia         ]: HDA-Intel - HDA NVidia
                      HDA NVidia at 0xf7080000 irq 17
 3 [NVidia_1       ]: HDA-Intel - HDA NVidia
                      HDA NVidia at 0xf5080000 irq 18</code>

The audio should now be working for your headset.
Make sure you restart any application that you have running in order for it to initialize the new audio output source.

You will notice one problem, you can’t play multiple sound sources at once, there is not mixing 🙁
This one took me a while to figure out, after a lot of reading I managed to get it working by having the following in ~/.asoundrc

pcm.!default {
        type plug
        slave.pcm "dmixer"

pcm.dmixer  {
        type dmix
        ipc_key 1024
        slave {
                pcm "hw:0,0"
                period_time 0
                period_size 1024
                buffer_size 4096
                rate 44100
        bindings {
                0 0
                1 1

ctl.dmixer {
        type hw
        card 0

Reload ALSA and restart any applications that is trying to use the audio output.

sudo /etc/init.d/alsa-utils stop
sudo alsa reload
sudo /etc/init.d/alsa-utils start

It should now be working with playing multiple sound sources at once. Once problem still remains, after a reboot the sound stops working. The solution I did for this was to add the following into /etc/init.d/fix-audio

#! /bin/sh

# Provides:             fix-audio
# Required-Start:       $remote_fs $syslog
# Required-Stop:        $remote_fs $syslog
# Default-Start:        2 3 4 5
# Default-Stop:         
# Short-Description:    Fix audio

sudo /etc/init.d/alsa-utils stop
sudo alsa reload
sudo /etc/init.d/alsa-utils start

exit 0

I then add so that it runs when your computer starts.

sudo update-rc.d fix-audio defaults

Quite a lot of ugly fixes, but it works 🙂
I hope this helps you out.


Fixing Grub resolution


Here is quick fix that I noticed while reinstalling my computer, mostly to remind myself 🙂
To get the resolution properly if Linux (init) does not auto adjust the resolution when booting.




Booting Windows 8 from Grub on Linux


A while ago when reinstalling my computer on my new SSD RAID setup I wanted to make Linux my primary system and use Grub as my boot loader instead of the hideous Windows loader. Here is how I’m booting Windows 8 from my Grub:


menuentry "Windows 8 Loader" {
    insmod part_msdos
    insmod ntfs
    insmod ntldr
    set root='(hd0,msdos1)'
    ntldr /bootmgr

The file would like something like this, in whole.

exec tail -n +3 $0
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.

menuentry "Windows 8 Loader" {
    insmod part_msdos
    insmod ntfs
    insmod ntldr
    set root='(hd0,msdos1)'
    ntldr /bootmgr

What you want to do is changed hd0 to the drive you want to boot from (the Windows partition that your bootmgr file is on). When you have made your changes run update-grub as root.

sudo update-grub

You should see that the config above was applied in the /boot/grub/grub.cfg file. You should as a good practice never edit directly in the grub.cfg config file.

cat /boot/grub/grub.cfg | grep custom -A 10
### BEGIN /etc/grub.d/40_custom ###
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.

menuentry "Windows 8 Loader" {
    insmod part_msdos
    insmod ntfs
    insmod ntldr
    set root='(hd0,msdos1)'
    ntldr /bootmgr
### END /etc/grub.d/40_custom ###

I hope this helps 🙂

Fix VMware vCenter 5.5 issue on Windows Server 2012 R2


I had a mission to install VMware vCenter on a Windows Server 2012 R2 installation.
I had a issue that the installation got stuck at “Installing directory services”.

If you look in the vminst.log file in the %temp% directory, you can see the following.

VMware VirtualCenter-build-1312298: 08/09/14 14:33:46 [C:\Windows\system32\cmd.exe /c start /w C:\Windows\system32\ocsetup.exe DirectoryServices-ADAM /passive /norestart]
VMware VirtualCenter-build-1312298: 08/09/14 14:33:46 Util_Launch::Wait: 1 Hide: 1 TimeOut: -1

The problem is that the file C:\Windows\system32\ocsetup.exe was removed in the R2 version, this can be fixed by copying the file from a 2008 or 2012 retail version.
I resolved the issue by copying ocsetup.exe from one of our other installations and placing it in %windir%\system32 and then running the installation again.

I have made a mirror of the ocsetup.exe (as a zip file) if anybody need it.

Hope this helps somebody.