Leo’s Ramblings Rotating Header Image

Update: Linux VM template best practices

I had meant to post this sooner than now but unfortunately work is keeping me occupied 28×7 (that’s not a typo!)

This is a partial update to this post

Attila seems to be a scripting whiz and he’s made a change to my dd script to not utilize bc and added better tunable parameters – ddsleep, ddbs and ddsize. Then he emailed me to share with you! He has tested the default values on some systems and they seemed good: the progress was acceptable and it didn’t generate a high load, the system remained very responsive (in fact it was nearly not noticeable at all):

#!/bin/bash

# by default we skip /
doroot=0

# we want to keep 10 percent free
freepercent=5

# we want to keep at least 100 megabytes free
freespace=100m

# low priority
ddnice=19

# the file to create
file=.vtools-zerovmdk.bin

# the amount of time to sleep between two dd
ddsleep=0.4

# the block size to use with dd
ddbs=64k

# the size by which to increment the file in each turn
ddsize=10m

# if the file is already there, we continue to grow it
resume=0

fss=

while [ $# -gt 0 ]; do

	case $1 in
		--do-root)
			doroot=1
			shift 1
			;;

		--resume)
			resume=1
			shift 1
			;;

		--free-percent)
			freepercent=$2
			shift 2
			;;

		--free-space)
			freespace=$2
			shift 2
			;;

		--dd-nice)
			ddnice=$2
			shift 2
			;;

		--file)
			file=$2
			shift 2
			;;

		--dd-sleep)
			ddsleep=$2
			shift 2
			;;

		--dd-bs)
			ddbs=$2
			shift 2
			;;

		--dd-size)
			ddsize=$2
			shift 2
			;;

		--fss)
			fss=$2
			shift 2
			;;

		*)
			echo "Invalid parameter: $1"
			exit 1
			;;

	esac

done

function resolve_size
{
	local size=$1
	local m=0

	if ! (echo "$size" | grep -q "[0-9]*"); then
		echo "Invalid size: $size" >&2
		exit 1
	fi

	case $size in
		*g)
			m=3
			;;
		*m)
			m=2
			;;
		*k)
			m=1
			;;
	esac

	if [ $m -gt 0 ]; then
		local l=${#size}
		l=$(( $l - 1 ))
		size=${size:0:$l}
		local i=0
		while [ $i -lt $m ]; do
			size=$(( $size * 1024 ))
			i=$(( $i + 1 ))
		done
	fi
	echo $size
}

function calc_percent
{
	local v=$(($1 * $2))
	local l=${#v}
	l=$(($l - 2))
	echo ${v:0:$l}
}

function calc_fsfree
{
	df -B 1 $fs | tail -n 1 | awk -F" " '{print $4}'
}

function calc_fsmax
{
	df -B 1 $fs | tail -n 1 | awk -F" " '{print $2}'
}

freespace=`resolve_size $freespace`
ddbs=`resolve_size $ddbs`
ddsize=`resolve_size $ddsize`

test -z "$ddnice" && ddnice=`nice`

if [ ! -z "$fss" ]; then
	doroot=1
else
	fss=`mount | egrep "type (ext3|ext2|xfs)" | awk -F" " '{ print $3 }'`
fi

for fs in $fss; do

	if [ ! -d "$fs" ]; then
		echo "No such directory: $fs" >&2
		exit 1
	fi

	if [ "$fs" = "/" ]; then
		test "$doroot" = "0" && continue
	fi

	if [ $resume -eq 0 -a -f "$fs/$file" ]; then
		echo "File exists: $fs/$file" >&2
		exit 1
	fi

	fsmax=`calc_fsmax $fs`
	fskeep=`calc_percent $fsmax $freepercent`
	if [ $freespace -gt $fskeep ]; then
		fskeep=$freespace
	fi

	fsfree=`calc_fsfree $fs`
	fszero=$(($fsfree - $fskeep))

	#
	# If the last chunk will not reach
	# the space amount we need to free then
	# then we may enter an endless loop
	last=0

	while [ $fszero -ge 0 ]; do

		test $last -eq 1 && break

		ddcnt=$ddsize

		if [ $fszero -lt $ddsize ]; then
			ddcnt=$fszero
			last=1
		fi

		# this is the step where we may loose precision (see 'last' variable)
		ddcnt=$(( $ddcnt / $ddbs ))

		nice -n $ddnice dd count=$ddcnt bs=$ddbs if=/dev/zero of="$fs/$file" oflag=append conv=notrunc status=noxfer 2>&1 | sed '/^[0-9]\++[0-9]\+.*\(records\|rekord\)/d' >&2

		test ! -z "$ddsleep" && sleep $ddsleep

		fsfree=`calc_fsfree $fs`
		fszero=$(($fsfree - $fskeep))
	done

	nice -n $ddnice rm -f "$fs/$file"
done

The script is also downloadable from here.

Attilla, many thanks.

Cheers,
Leo

Blowing my own horn

Just to let committed blog readers know, I’ve just passed the first stage of the VCDX exam.

I’ve also passed my VCP on vSphere.

  • Do not go into the VCDX unprepared – your arse will be handed back to you on a platter. It is not an easy exam
  • Anyone who is a VCP on VI3.5 only needs to read up the vSphere Configuration Maximums and you’ll be able to pass with your hands tied behind your back – there are some questions on VMDirectPath I/O and vShield/VMSafe but not too many.

Cheers,

Leo

Some heads up for vCenter 4

First of all, apologies for not posting for a very long time. I’ve been busy setting up my Cloud Computing service. I’ll write about that some other time.

For now, I have some recent experiences to share with vCenter:

  • vCenter 4.0 works on Windows 2008 R2 but the vSphere client does not unless a workaround is used
  • If you plan on using the Cisco Nexus 1000V as part of your vSphere Enterprise Plus package, vCenter must be able to run on port 80 – this means, no IIS on the vCenter box.
  • If upgrading from VirtualCenter 2.5.x and moving servers, make sure to keep a backup of the SSL certs in C:\Documents and Settings\All Users\Application Data\VMware\VMware VirtualCenter\SSL – if they are not copied over the ones newly installed by the vCenter installer, the vCenter Hardware Status and the vCenter Service Status will fail to enable.
  • If installing on an x64 Windows box, you still need a 32-bit connection via ODBC to your SQL DB. Start, Run, type odbcad32.exe and enter your details

Cheers,

Leo

Upgrading Dell Firmware as part of your ks.cfg

If you own Dell Servers and run your ESX farms on them, you’ll know what a pain in the arse it is to update the firmware.

What if you could do it as part of your install script, or even deploy it in the future as a script to be run on all boxes?

I’ve got the solution for that, because frankly, the Dell TechCenter one didn’t suit my purposes (mounting/lwp-downloading a 1.9GB ISO to each server to upgrade 30MB worth of updates is a serious waste of time and bandwidth across sites)

The only requirement is that Dell’s OMSA is installed and running on the ESX server.

So here’s my script:

#!/bin/sh

# Allowing outbound access through the ESX firewall
esxcfg-firewall --allowOutgoing

# Downloading Dell firmware/BIOS updates
lwp-download http://149.171.186.10/Dell/Toolkit/Systems/PE6950/DRAC.BIN /tmp/DRAC.BIN
lwp-download http://149.171.186.10/Dell/Toolkit/Systems/PE6950/BIOS.BIN /tmp/BIOS.BIN
lwp-download http://149.171.186.10/Dell/Toolkit/Systems/PE6950/RAID.BIN /tmp/RAID.BIN

# Disabling outbound access through the ESX firewall
esxcfg-firewall --blockOutgoing

# Make sure firmware/BIOS scripts are executable
chmod a+x /tmp/*.BIN

# Attach virtual media for DRAC update
racadm config -g cfgRacVirtual -o cfgVirMediaAttached 1
export rawdevice=`dmesg | tail -n30 | grep "32768 512-byte hdwr" | awk -F" " '{print $3}' | sed "s/://g"`
raw /dev/raw/raw1 /dev/$rawdevice

# Run the updates
for i in /tmp/*.BIN ; do $i -q ; done

# Delete the updates
rm -f /tmp/*.BIN

# Detach the virtual media for DRAC update
racadm config -g cfgRacVirtual -o cfgVirMediaAttached 0

The file is likewise attached.

Obviously, in the lwp-download section, put in your own URL for the .BIN files that comprise the Dell updates.

Cheers,
Leo

Unknown device… is this a bug?

We have a customer with two ESX farms – one with AMD 8354 Opterons and one with AMD 8220 Opterons.

We use a manual sysprep – not the VC-integrated one, but a custom sysprep.inf file. And we found that all Windows 32-bit machines came up with Unknown device instead of the processor and we couldn’t roll back to the old driver. The only way to fix it was to run the setup.exe -s option on the AMD Processor driver. Now this is all well and good but that doesn’t fix the problem of why vanilla Windows installs screw up after imaging.

This is what the problem looks like:

unknown_device

So we examined our custom sysprep file – and we found it:

UpdateInstalledDrivers = Yes

That entry was in the sysprep.inf custom file. Removing it, caused the Unknown device issue to disappear. Having it there guaranteed the Unknown device issue appearing.

Here’s what we determined:

  • There appears to be no performance impact from this issue
  • This does not prevent any functionality in terms of software (Windows based) or VMware (such as VMotion/DRS/HA)

Just a heads up for you.

Cheers,

Leo

A worthy cause: donate

What seems like a lifetime ago, but is in fact only about 3 years ago, I worked at a small Sydney integrator called ENSTOR.

ENSTOR went to the wall but this is neither here nor there – what matters is that I worked with two wholly remarkable an unique women.

One is Siobhan Ellis, the other was Kirsty Rae.

Kirsty Rae died very recently after a battle with cancer.

Through the blog of my former boss, Preston de Guise, I found out Siobhan was doing a 2 week ride on a 1964 Lambretta TV 175 Series 2 from Sydney to Perth to raise money for Breast and Prostate Cancer Research – a distance of some 4100km (2550 miles). All the money will go to Sydney’s St. Vincent’s Hospital and not one cent of your donation will go to administrative functions – all expenses will be met by Siobhan and her supporters.

So please, donate a bit of your hard-earned cash to the memory of a friend of mine and by extensions, to friends of yours, because the truth is, is that we have all been touched by cancer.

Please donate here.

In appreciation,

Leo Raikhman

Powershell: another Dusan Solution(tm) for VCB

The university where I contract, has a solution whereby their VCB policies are based on datastores in which the machines are residing in. ie Netbackup will have a policy that calls a VCB script to snapshot all VMs in a datastore.

Except, there’s a small problem – how do you size the holding tank for the image snapshots if all the VMs in a datastore are small system (C:) volumes and their data disks are spread around other datastores?

The aforementioned colleague of mine – Dusan from DMTECH has (with help from the VMware Communities and a little from yours truly) created a VCB script that will sort VMs per datastore based on which datastore their largest VMDK lies in. This means that the holding tank is always, no matter what, smaller than the previous situation required.

The script outputs to to a bunch of csv files (c:\leo as per below) and outputs the name of the machine prefixed with the holding-tank location (in my case V:\VCBholding) and suffixed with the type of backup (in my case -FullVM):

$file = import-csv C:\temp\CustomField.csv
Get-VM | where-object {$file -notmatch $_.name} | %{
  $hds = @($_ | Get-HardDisk | Sort-Object -property CapacityKb -descending)
  $dsName = ([regex]"^\[(\w+)\]").Match($hds[0].Filename).Groups[1].Value
  $name = "V:\VCBholding" + $_.Name + "-FullVM"
  $name | Out-File -filePath ("C:\leo" + $dsName + ".txt") -append
}

The contents of those text files can then be directly imported into VCB policies in Netbackup.

N.B. The other thing of note is that you might not want all VMs backed up in VCB – so for that, we use a file which gets read in (c:\temp\CustomField.csv). Into that put in (in CSV format) the names of VMs you want to exclude. ie:

Name
virtualmachinename1
virtualmachinename2
virtualmachinename3

One thing to note – the script will not output correctly if you don’t clear the dump folder (c:\leo in this case) – I haven’t implemented a delete function.

:)
Cheers,
Leo

Quick heads up re. vShield: RTFM

So… I got bitten by not reading the manual, or in this case – the admin guide for vShield.

See, enabling vShield makes all VMs communicate via the internalised network – vShield will actually inform you of an error during a migration. The error states that the VM is attached to a virtual intranet.

This intranet is the network that the virtual machine connects to through the vSwitch on the protected side of the vShield, and which does not home a physical NIC. In this case, the vShield is bridging traffic to the unprotected network that is connected to a physical NIC

Disable the virtual intranet check by editing the vpxd.cfg file of the VC server:

  • Locate and edit the vpxd.cfg file on the vCenter Server. This file is typically installed at C:\Documents and Settings\All Users\Application Data\VMware\VMware vCenter by default. Add the following lines as a sub‐level to the config section, and at the same level as the vpxd section:
<migrate>
	<test>
		<CompatibleNetworks>
			<VMOnVirtualIntranet>false</VMOnVirtualIntranet>
		</CompatibleNetworks>
	</test>
</migrate>
  • Save the vpxd.cfg file.
  • Restart the VMware vCenter Server service. You can access the service menu by going to Control Panel > Administrative Tools > Services.

Then, you’ll need to exclude the vShield VMs from being migrated via DRS and make sure to leave the Isolation Response HA settings as:

  • VM Restart Priority: Disabled
  • Host Isolation Response: Leave VM powered on

Cheers,

Leo

Powershell VI3 charge-back scripts

A colleague of mine – Dusan from DMTECH has created two powershell scripts that allow charge-back accounting on an ESX farm that is used to host customer data:

Assuming a CSV file like this:

Name,Business Owner,Chargeable,Commence Date,Cost (Upfront),Cost (Yearly)
Dept1PWAP003,Bob Marley,Y,,”$2,722.41″,$815.00
Dept1PWAP004,Bob Marley,Y,,”$1,707.96″,$476.85
Dept1PWAP005,Bob Marley,Y,,”$2,722.41″,$815.00
Dept1PWAP006,Bob Marley,Y,,”$2,722.41″,$815.00
Dept1PWAP007,Bob Marley,Y,,”$2,722.41″,$815.00
Dept1PWAP008,Bob Marley,Y,,”$5,199.25″,”$1,310.37″
Dept1PWAP009,Bob Marley,Y,,”$2,722.41″,$815.00
Dept1TWAA010,Bob Marley,Y,,”$1,231.27″,$381.51
Dept1TWAA011,Bob Marley,Y,,”$1,231.27″,$381.51
Dept1TWAA012,Bob Marley,Y,,”$1,231.27″,$381.51
Dept1TWAA013,Bob Marley,Y,,”$2,245.72″,$719.66
Dept1TWAA014,Bob Marley,Y,,”$1,231.27″,$381.51

The following script will import the data above by matching VM names and attaching data to the annotations/custom attributes you’ve created (as per the headings in the CSV file – “Name”, “Business Owner”, “Chargeable”, “Commence Date”, “Cost (Upfront)”, “Cost (Yearly)”):

$fields = "Business Owner","Chargeable","Commence Date","Cost (Upfront)","Cost (Yearly)" (Upfront)"
$vms = Get-VM
foreach ($f in (import-csv C:\temp\CustumField.csv)) {
   $vm = $vms | Where { $_.Name -eq $f.Name }
   foreach ($cf in $fields) {
      $vm | Set-CustomField -name $cf -value $f.$cf
   }
}

Now, assuming you have tiered storage, you can charge customers for storage on the basis of Tier – for this your datastore names have to end in _T2/_T3/_T4 according to this script:

$report = @()
get-vm | % {
	$vm = $_
	$T2 = ($_ | get-harddisk | Where-Object {$_.Filename -match "T2"} | measure-object -property CapacityKB -sum).Sum
	$T3 = ($_ | get-harddisk | Where-Object {$_.Filename -match "T3"} | measure-object -property CapacityKB -sum).Sum
	$T4 = ($_ | get-harddisk | Where-Object {$_.Filename -match "T4"} | measure-object -property CapacityKB -sum).Sum
	$_ | Get-Datastore | Where-Object {$_.Type -eq "VMFS"} | % {
		$row = "" | Select Name, MemoryGb,NumCPU,"T2 (GB)","T3 (GB)","T4 (GB)","Business Owner","Chargeable","Commence Date","Cost (Upfront)","Cost (Yearly)"
		$row.Name = $vm.Name
		$row.MemoryGB = "{0:f0}" -f ($vm.MemoryMb / 1Kb)
		$row.NumCpu = $vm.NumCpu
		$row.{T2 (GB)} = "{0:f0}" -f ($T2 / 1Mb)
		$row.{T3 (GB)} = "{0:f0}" -f ($T3 / 1Mb)
		$row.{T4 (GB)} = "{0:f0}" -f ($T4 / 1Mb)
		$row.{Business Owner} = $vm.CustomFields.Values[2]
		$row.Chargeable = $vm.CustomFields.Values[3]
		$row.{Commence Date} = $vm.CustomFields.Values[4]
		$row.{Cost (Upfront)} = $vm.CustomFields.Values[5]
		$row.{Cost (Yearly)} = $vm.CustomFields.Values[6]
		$report += $row
	}
}
$report | select -unique Name, MemoryGb,NumCPU,"T2 (GB)","T3 (GB)","T4 (GB)","Business Owner","Chargeable","Commence
Date","Cost (Upfront)","Cost (Yearly)" | sort -property Name |Export-Csv "C:\chargeback.csv" -noTypeInformation

This produces the following output which specifies the total amount of storage per VM per tier:

Name MemoryGb NumCPU T2 (GB) T3 (GB) T4 (GB) Business Owner Chargeable Commence Date Cost (Upfront) Cost (Yearly)
Dept1PWAP003 4 2 0 70 0 Bob Marley Y $2,722.41 $815.00
Dept1PWAP004 4 1 0 0 70 Bob Marley Y $1,707.96 $476.85
Dept1PWAP005 4 2 0 70 0 Bob Marley Y $2,722.41 $815.00
Dept1PWAP006 4 2 0 70 0 Bob Marley Y $2,722.41 $815.00
Dept1PWAP007 4 2 0 70 0 Bob Marley Y $2,722.41 $815.00
Dept1PWAP008 4 2 0 320 0 Bob Marley Y $5,199.25 $1,310.37
Dept1PWAP009 4 2 0 70 0 Bob Marley Y $2,722.41 $815.00
Dept1TWAA010 4 1 0 0 70 Bob Marley Y $1,231.27 $381.51
Dept1TWAA011 4 1 0 0 70 Bob Marley Y $1,231.27 $381.51
Dept1TWAA012 4 1 0 0 70 Bob Marley Y $1,231.27 $381.51
Dept1TWAA013 4 2 0 0 70 Bob Marley Y $2,245.72 $719.66
Dept1TWAA014 4 1 0 0 70 Bob Marley Y $1,231.27 $381.51

Cheers,
Leo

EMC Storage Viewer Update – v1.1

EMC have released Storage Viewer 1.1 which now supports Virtual Infrastructure Client 2.5 update 4.

The objective of the EMC® Storage Viewer for Virtual Infrastructure Client is to provide a new tool that facilitates discovery and identification of EMC storage devices which are allocated to VMware ESX servers and virtual machines.
This brings the storage details up the to user through the VI Client interface, merging all of the functionality of several different tools that perform storage mapping-related functions into a single tool that integrates seamlessly with the VI Client.
Using a plug-in to the VI Client management interface, ESX Server Datastores and VMFS virtual disks are resolved to the underlying storage array target and LUN assignments.

Get it here.

Update: In comments Chad Sakac states

Working on vSphere support now – stay tuned, it will be soon!

:)

Cheers,

Leo