Thursday, October 25, 2012

HowTo: Xen 4.1.3 Windows 8 HVM domU with Intel HD4000 VGA Passthrough on Debian Wheezy

Update 05/07/2013:
Despite the HowTo being close to 1 year it applies perfectly to this day. At the time Wheezy was Debian's Testing distribution and has since moved to Stable. Much of it can be used to setup other HVM domU such as Linux. 

Important notice: I've experienced some problems with xen-hypervisor-4.1-amd64 versions 4.1.4-3+deb7u1_amd64 and 4.1.4-3_amd64 which implement some security advisory patches . As a result to have sucessful passthrough I was forced to go back to the previous working version: 4.1.4-2_amd64 which is available at http://www.xen.org/downloads/XCP/debian/repo/amd64/xen-hypervisor-4.1-amd64_4.1.2-2.1_amd64.deb. Again, do notice that this package is missing some security patches available in more recent versions.
 
In this HowTo I'll present the steps required to install Xen 4.1.3 using the xm toolstack on a Debian Wheezy (kernel 3.2.0-3-amd64) dom0, create a Windows 8 HVM domU config and setup VGA/PCI Passthrough for the integrated GPU, USB 2.0 controller and audio.

This HowTo assumes that the reader is comfortable with Linux and Windows operating systems namely Debian GNU/Linux and Windows 7/8 as such it doesn't cover the operating systems installation.

For easier reference the procedure will broken down in the following steps:
1) Hardware requirements
2) Install Xen on Debian Wheezy
3) Configure networking
4) Configure Xen
5) Prioritise Xen boot
6) Create and install Windows 8 HVM domU
7) Assign devices for PCI Passthrough
8) Install GPLPV drivers
9) Advices and impressions

1) Hardware requirements

For PCI passthrough both motherboard and CPU must support VT-d also know as IOMMU IO virtualization.

The hardware used to write this HowTo setup is composed of:
  • Intel Core i7-3770 CPU,
  • Intel DQ77MK Motherboard,
  • 32GB GEIL DDR3 1600 MHz,
  • 200GB Maxtor SATA HDD,
  • Samsung SyncMaster 940BW Monitor.

It should be noted that VT-d and VT-x have been enabled in the motherboard and that the i7-3770 integrated GPU is the computer's sole GPU.

In addition to the above setup I've also used another networked computer so I could SSH into the dom0 and perform the steps identified bellow.

2) Install Xen on Debian Wheezy

The Xen hypervisor is provided by the xen-linux-system package:

  1. $ su
  2. # apt-get update
  3. # apt-get install xen-linux-system

3) Configure networking

There are several ways you can provide network access to domU guest domains, the most common being setting up a network bridge which I'll be covering.

To assign a static IP to the dom0 and define a network bridge named eth0, disable NetworkManager (if installed) and edit /etc/network/interfaces to contain a bridge:

  1. # /etc/init.d/network-manager stop
  2. # update-rc.d network-manager disable
  3. # aptitude install bridge-utils
  4. # vim /etc/network/interfaces auto lo br0 iface lo inet loopback allow-hotplug eth0 iface eth0 inet manual iface br0 inet static bridge_ports eth0 address 192.168.1.5 broadcast 192.168.1.255 netmask 255.255.255.0 gateway 192.168.1.254
  5. # vim /etc/resolv.conf domain my.domain.com nameserver 192.168.1.254

192.168.1.5 is the IP chosen to be assigned to the host, 192.168.1.255 and 255.255.255.0 are the typical broadcast and netmask values for a 192.168.1.x network and in my case the gateway is 192.168.1.254. Replace this values according to your own network settings and desires.

4) Configure Xen

The xend daemon employs xend-config.sxp to determines the parameters that Xen should use.

Personally I choose to disable dom0 ballooning, define the dom0 assignable memory and change the keyboard layout (I've changed mine to pt):

  1. # vim /etc/xen/xend-config.sxp (dom0-min-mem 2048) (enable-dom0-ballooning no) (keymap 'pt')

I've restricted the amount of memory assigned to dom0 to 2048 MB. In my case the dom0 is headless and all the hard work is to be done by the non-privileged virtual machines as such I've opted for a comfortable amount of memory to be assigned to the dom0, 2048 MB (2 GB). To this end GRUB needs to pass the appropriate command as the hypervisor boots:

  1. # echo 'GRUB_CMDLINE_XEN="dom0_mem=2G,max:2G"' >> /etc/default/grub
  2. # update-grub2


5) Prioritise Xen boot

By default Wheezy's GRUB lists and boots regular kernels and afterwards the Xen hypervisor.

Assuming that the computer is to be running Xen all the time it advisable to change this behaviour and increase Xen's GRUB boot priority so that it's the first on the list and boots by default.

The Debian way to do this is to used dpkg-divert like so:

  1. # dpkg-divert --divert /etc/grub.d/08_linux_xen --rename /etc/grub.d/20_linux_xen
  2. # update-grub2

To undo this necessary:
 
  1. # dpkg-divert --rename --remove /etc/grub.d/20_linux_xen
  2. # update-grub2


6) Create and install Windows 8 HVM domU

The xm toolstack uses configuration files that define the domain meaning that we need to create a configuration file for our guest VM:

  1. # vim /etc/xen/win8-x64.cfg kernel = 'hvmloader' builder = 'hvm' vcpus = '4' memory = '4096' disk = ['file:/srv/xen/domains/win8-x64.img,hda,w',
    'file:/srv/xen/images/Windows8-ReleasePreview-32bit-English.iso,hdc:cdrom,r'] name = 'win8-x64' vif = [ 'mac=00:16:3E:51:20:4C,bridge=br0,model=e1000' ] on_poweroff = 'destroy' on_reboot = 'restart' on_crash = 'restart' boot = 'dc' acpi = '1' apic = '1' viridian = '1' xen_platform_pci='1' sdl = '0' vnc = '1' vnclisten = '0.0.0.0' vncpasswd = '' stdvga = '0' usb = '1' usbdevice = 'tablet'

Do note that a MAC address must be assigned to the virtual interface. The 00:16:3e MAC block is reserved for Xen domains, do the last three digits may be randomly filled in (hex values 0-9 and a-f only).

In this HowTo I'm using file based storage which implies using the dd command to create what will be the domU hard drive. To create a 40GB .img file:

  1. # dd if=/dev/zero of=/srv/xen/domains/win8-x64.img bs=1M count=40960

If you're using LVM use 'phy:/dev/mapper/win8-x64,hda,w' (change according to your own target logical volume) instead of 'file:/srv/xen/domains/win8-x64.img,hda,w'.

For more on the options that the domain configuration file accepts refer to xmdomain.cfg.

There are 2 options when it comes to actually installing Windows 8 on the virtual machine. One method consists in using VNC to connect to the guest virtual machine and installing the operating system from whatever computer you have with a graphical desktop environment. In alternative, one can use VGA Passthrough for the install process altogether.

Choose one of the methods, though the VNC method is preferable as it eases troubleshooting and it's the one documented bellow. To use the VGA Passthrough method jump to step 7 of the HowTo and issue xm create win8-x64.cfg.

After defining Windows 8 domU configuration file execute it and connect through VNC to install Windows 8:

  1. # xm create win8-x64.cfg
  2. $ vncviewer 192.168.1.5

If running a GUI on dom0 simply vncviwer 127.0.0.1, however if running from a networked computer replace the localhost with the IP of the said networked computer (192.168.1.5 for example).

Proceed to do a Windows install, shutdown the guest VM and backup the .img for future use. To shutdown the Windows 8 HVM domU either use guest's shutdown button or issue:

  1. # xm destroy win8-x64

xm list can be used to find out the domain Id and use it as argument for xm destroy, for example:

  1. xm listName         ID Mem VCPUs State   Time(s)Domain-0     0 4096 8     r-----   34476.9win8-x64     4 4096 4     -b----   301.0
  2. xm destroy 4

Also comment out the cdrom line so that the virtual machine doesn't boot into the Windows installation cdrom every time it boots. For security reasons it is best to disable VNC.

  1. # vim /etc/xen/win8-x64.cfg kernel = 'hvmloader' builder = 'hvm' vcpus = '4' memory = '4096' disk = ['file:/srv/xen/domains/win8-x64.img,hda,w',
    #'file:/srv/xen/images/Windows8-ReleasePreview-32bit-English.iso,hdc:cdrom,r'] name = 'win8-x64' vif = [ 'mac=00:16:3E:51:20:4C,bridge=br0,model=e1000' ] on_poweroff = 'destroy' on_reboot = 'restart' on_crash = 'restart' boot = 'dc' acpi = '1' apic = '1' viridian = '1' xen_platform_pci='1' sdl = '0' vnc = '0' vnclisten = '0.0.0.0' vncpasswd = '' stdvga = '0' usb = '1' usbdevice = 'tablet'

7) Assign devices for PCI Passthrough

A domU can be made aware and directly access and use PCI devices with full privileges. To accomplish that the PCI devices need to be hidden from the dom0 and not be forwarded to any other domUs.

Using the xm toolstack this is achieved loading the pci_stub kernel module, identifying the PCI devices that are to be forwarded, unbinding the device from dom0 and bind it to pci_stub thus allowing it to be assigned in the domU config file.

  1. # lspci 00:00.0 Host bridge: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller (rev 09) 00:02.0 VGA compatible controller: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor Graphics Controller (rev 09) 00:14.0 USB controller: Intel Corporation 7 Series/C210 Series Chipset Family USB xHCI Host Controller (rev 04) 00:16.0 Communication controller: Intel Corporation 7 Series/C210 Series Chipset Family MEI Controller #1 (rev 04) 00:16.3 Serial controller: Intel Corporation 7 Series/C210 Series Chipset Family KT Controller (rev 04) 00:19.0 Ethernet controller: Intel Corporation 82579LM Gigabit Network Connection (rev 04) 00:1a.0 USB controller: Intel Corporation 7 Series/C210 Series Chipset Family USB Enhanced Host Controller #2 (rev 04) 00:1b.0 Audio device: Intel Corporation 7 Series/C210 Series Chipset Family High Definition Audio Controller (rev 04) 00:1c.0 PCI bridge: Intel Corporation 7 Series/C210 Series Chipset Family PCI Express Root Port 1 (rev c4) 00:1c.6 PCI bridge: Intel Corporation 7 Series/C210 Series Chipset Family PCI Express Root Port 7 (rev c4) 00:1d.0 USB controller: Intel Corporation 7 Series/C210 Series Chipset Family USB Enhanced Host Controller #1 (rev 04) 00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev a4) 00:1f.0 ISA bridge: Intel Corporation Q77 Express Chipset LPC Controller (rev 04) 00:1f.2 SATA controller: Intel Corporation 7 Series/C210 Series Chipset Family 6-port SATA Controller [AHCI mode] (rev 04) 00:1f.3 SMBus: Intel Corporation 7 Series/C210 Series Chipset Family SMBus Controller (rev 04) 02:00.0 Ethernet controller: Intel Corporation 82574L Gigabit Network Connection 03:03.0 FireWire (IEEE 1394): LSI Corporation FW322/323 [TrueFire] 1394a Controller (rev 70)

I'll be forwarding 00:02.0 VGA compatible controller, 00:1b.0 Audio device and 00:1d.0 USB controller. To know the exact numbering of the devices run lspci -n:

  1. # lspci -n 00:00.0 0600: 8086:0150 (rev 09) 00:02.0 0300: 8086:0162 (rev 09) 00:14.0 0c03: 8086:1e31 (rev 04) 00:16.0 0780: 8086:1e3a (rev 04) 00:16.3 0700: 8086:1e3d (rev 04) 00:19.0 0200: 8086:1502 (rev 04) 00:1a.0 0c03: 8086:1e2d (rev 04) 00:1b.0 0403: 8086:1e20 (rev 04) 00:1c.0 0604: 8086:1e10 (rev c4) 00:1c.6 0604: 8086:1e1c (rev c4) 00:1d.0 0c03: 8086:1e26 (rev 04) 00:1e.0 0604: 8086:244e (rev a4) 00:1f.0 0601: 8086:1e47 (rev 04) 00:1f.2 0106: 8086:1e02 (rev 04) 00:1f.3 0c05: 8086:1e22 (rev 04) 02:00.0 0200: 8086:10d3 03:03.0 0c00: 11c1:5811 (rev 70)

For each PCI to be forwarded create a pci-stub Id, unbind it from the dom0 and bind to pci-stub. xm pci-list-assignable-devices is useful in confirming if the device has been added to the pool of devices that can be assigned to a guest domain.

  1. # modprobe pci_stub
  2. # echo "8086 1e26" > /sys/bus/pci/drivers/pci-stub/new_id
  3. # echo "0000:00:1d.0" > /sys/bus/pci/devices/0000\:00\:1d.0/driver/unbind
  4. # echo "0000:00:1d.0" > /sys/bus/pci/drivers/pci-stub/bind
  5. # xm pci-list-assignable-devices 0000:00:1d.0
  6. # echo "8086 0162" > /sys/bus/pci/drivers/pci-stub/new_id
  7. # echo "0000:00:02.0" > /sys/bus/pci/devices/0000\:00\:02.0/driver/unbind
  8. # echo "0000:00:02.0" > /sys/bus/pci/drivers/pci-stub/bind
  9. # xm pci-list-assignable-devices 0000:00:02.0 0000:00:1d.0
  10. # echo "8086 1e20" > /sys/bus/pci/drivers/pci-stub/new_id
  11. # echo "0000:00:1b.0" > /sys/bus/pci/devices/0000\:00\:1b.0/driver/unbind
  12. # echo "0000:00:1b.0" > /sys/bus/pci/drivers/pci-stub/bind
  13. # xm pci-list-assignable-devices 0000:00:02.0 0000:00:1b.0 0000:00:1d.0

Do note that the devices won't be available in the dom0, that's why typical VGA Passthrough setups involve 2 or more graphics cards forwarding the more powerful to the domU alongside an USB controller and audio (I'll cover Secondary Display Adapter PCI passthrough in a future post). In this case only the CPU's integrated GPU is present so as soon has 00:02.0 VGA compatible controller is hidden for the dom0 it can't be used by it and thus the only way to be access is via another computer using SSH for example.

Update the domU's configuration file with the devices that are to be used and start the Windows 8 domU by issuing xm create win8-x64.cfg.

  1. # vim /etc/xen/win8-x64.cfg kernel = 'hvmloader' builder = 'hvm' vcpus = '4' memory = '4096' disk = [ 'file:/srv/xen/domains/win8-x64.img,hda,w', #'file:/srv/xen/images/Windows8-ReleasePreview-32bit-English.iso,hdc:cdrom,r' ] name = 'win8-x64' vif = [ ',mac=00:16:3E:51:20:4C,bridge=br0,model=e1000' ] on_poweroff = 'destroy' on_reboot = 'restart' on_crash = 'restart' boot = 'dc' acpi = '1' apic = '1' viridian = '1' xen_platform_pci='1' sdl = '0' vnc = '0' vnclisten = '0.0.0.0' vncpasswd = '' stdvga = '0' usb = '1' usbdevice = 'tablet' pci = [ '00:1d.0', '00:1b.0' , '00:02.0' ]
  2. # xm create win8-x64.cfg

Also consider creating a script to automate loading pci-stub and unbinding/binding the  PCI devices.

8) Install GPLPV drivers

Developed by James Harper, GPLPV drivers allow swapping the QEMU emulated devices for paravirtualized devices. With these new devices I/O speeds are improved as Windows will use the network and block backend drivers present in the dom0.

Signed GPLPV drivers are available at http://wiki.univention.de/index.php?title=Installing-signed-GPLPV-drivers. Windows 8 32-bit can be downloaded at http://apt.univention.de/download/addons/gplpv-drivers/gplpv_Vista2008x32_signed_0.11.0.356.msi while 64-bit drivers are available at http://apt.univention.de/download/addons/gplpv-drivers/gplpv_Vista2008x64_signed_0.11.0.356.msi.
Vista2008 in the drivers' installer filename means that it applies to the recent Windows releases (e.g. Vista/2008/7/8).

9) Advices and impressions

I've written some pieces of advices and impressions over using XEN over at opensource-impressions.blogspot.com with some specific Intel HD4000 VGA Passthrough so make sure to read them.

Wheezy's stock kernel doesn't contain xen-acpi-processor as it was introduced during Linux kernel 3.4.x as such power management is lacking. In this scenario, consider compiling the kernel or in alternative installing Debian Experimental's kernel. The latter option implies editing /etc/apt/sources.list to cover the experimental branch and instructing apt-get to install the kernel package from the experimental distribution.

Xen is at version 4.1.3 in Debian Wheezy's repository however the recent 4.2.0 release is already available in the experimental branch. And with the 4.2.0 comes xl, the new toolstack set to replace xm.

In the coming weeks I'll update this HowTo with the required steps to combine Debian Experimental Xen and Linux kernel packages with the testing distribution.

Update 05/07/2013:
I've moved on from HD4000 VGA passthrough and am currently using PCI passthrough on 2 AMD cards (HD7850 and HD5450) with much success. The HD5450 is assigned to a Fedora 19 domU while the HD7850 is assigned to a Windows 8 domU (Catalyst drivers aren't installed) for my gaming fix. 
Stability of the setup: rock solid. dom0 is typically online for 1 to 2 months without rebooting, the Fedora 19 is hardly rebooted or shutdown while the Windows 8 domU is shutdown at night. Aside from these domU another Windows 8 domU is allways on.

Thursday, August 16, 2012

Tip: Assign Xen dom0 memory on Debian Wheezy

Though Xen can manage memory with the ballon driver it is considered good practice to limit/restrict the amount of memory assigned to dom0. Doing so will stop the  Linux kernel from wasting memory.

To do so you'll need to pass the appropriate boot parameter for both the Xen hypervisor and Linux.

As an example, let's assume you want to assign 2GB to your dom0 here's how:
  1. $ su
  2. # echo 'GRUB_CMDLINE_XEN="dom0_mem=2G,max:2G"' >> /etc/default/grub
  3. # update-grub2

The above steps were executed on Debian Wheezy running Xen 4.1.3 but should translate as well to any other distribution running Xen 4.1.2 or latter and GRUB2. Users of GRUB will need to edit grub.conf and pass down the boot parameters in an analogous manner.

Tuesday, July 17, 2012

Tip: Fixing "gnome-screenshot" (No such file or directory) on CentOS 6.3

While pressing Prnt Scrn to take a window screenshot I got awarded with "cool" Metacity message window stating the following:

  1. There was an error running gnome-screenshot:Failed to execute child process "gnome-screenshot" (No such file or directory)

I'm running a fresh CentOS 6.3 system installed using the x86_64 Live CD which shortly after installing it noticed that it didn't came with Disk Usage Analyzer. Putting the error message and the missing application points the problem to the package that provides both gnome-utils.

To fix the problem and also install the other missing applications:
 
  1. $ su
  2. # yum install gnome-utils -y

And that's it!

Tip: Blacklisting kernel modules on CentOS 6.3

While trying the kernel-ml from the ELRepo repository I noticed that it ships with the pcspkr.ko kernel module which is in my opinion pretty annoying. 

To unload a kernel module, for instances pcspkr.ko, simply issue the rmmod command with the kernel module as argument. However this will only take place for the current session, the next time you reboot the machine hte kernel module will load. To prevent this we need to blacklist it by adding it to /etc/modprobe.d/blacklist.conf.

Putting everything together:

  1. $ su
  2. # rmmod -v pcspkr
  3. # echo "blacklist pcspkr" >> /etc/modprobe.d/blacklist.conf

On step 1 we've changed to superuser, on step 2 the kernel module (pcspkr was selected as an example) was removed from the current session and on step 3 we've prevented it from loading at boot.

As a side note, to list the currently loaded kernel modules run lsmod.

Sunday, July 15, 2012

Tip: Remove xen-runtime from kernel-xen repository

Lately I've been messing with Xen.

In the process of using the kernel-xen repository I came across the following situation while attempting to uninstall xen-runtime:
  1. # yum remove xen-runtime
    Loaded plugins: fastestmirror, refresh-packagekit, security
    Setting up Remove Process

    Resolving Dependencies

    --> Running transaction check
    ---> Package xen-runtime.x86_64 0:4.1.2-8.el6 will be erased
    --> Finished Dependency Resolution
    Dependencies Resolved
    ==================================================================
      Package Arch Version Repository Size
    ================================================================== Removing:
      xen-runtime x86_64 4.1.2-8.el6 @kernel-xen 8.0 M

    Transaction Summary
    ==================================================================
    Remove 1 Package(s)

    Installed size: 8.0 M
    Is this ok [y/N]: y
    Downloading Packages:
    Running rpm_check_debug
    Running Transaction Test
    Transaction Test Succeeded
    Running Transaction
    Error in PREUN scriptlet in rpm package xen-runtime
    xen-runtime-4.1.2-8.el6.x86_64 was supposed to be removed but is not!
      Verifying : xen-runtime-4.1.2-8.el6.x86_64 1/1

    Failed:
      xen-runtime.x86_64 0:4.1.2-8.el6
    Complete!
  2. # rpm -e xen-runtime
    /var/tmp/rpm-tmp.LcPd6z: line 5: /bin/systemctl: No such file or directory
    error: %preun(xen-runtime-4.1.2-8.el6.x86_64) scriptlet failed, exit status 127

To remove the little bastard the --nopreun needs to be passed down to rpm -e. By doing so the execution of the %preun scriptlet is turned off thus allowing rpm to uninstall the offending package, like so:
  1. # rpm -e --nopreun xen-runtime

Done!

Now I can go back to messing with Xen ;)

Saturday, July 14, 2012

HowTo: Install Adobe Flash Player using Repoforge on CentOS 6.3

To install Adobe Flash Player on RHEL or CentOS 6.3 using the Repoforge repository, you'll need to change to root, import repository's GPG key, install the repository file and install the Adobe Flash Player package.

If you're running a 32 bits system:
  1. $ su
  2. # rpm --import http://dag.wieers.com/rpm/packages/RPM-GPG-KEY.dag.txt
  3. # rpm -Uvh http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.i686.rpm
  4. # yum install flash-plugin

On the other hand, if you have a 64 bits install issue the following commands:
  1. $ su
  2. # rpm --import http://dag.wieers.com/rpm/packages/RPM-GPG-KEY.dag.txt
  3. # rpm -Uvh http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm
  4. # yum install flash-plugin

Launch Mozilla Firefox and in the address bar enter about:plugins. An Shockwave Flash entry should be available.

If you point to System -> Preferences you'll notice that a new entry named Adobe Flash Player is now available.

You can test if the plugin is working by visiting http://www.adobe.com/software/flash/about or by firing up a random Youtube clip.

If you'd prefer to using Adobe's own YUM repository follow the steps described in http://linux-bsd-sharing.blogspot.pt/2012/05/howto-install-adobe-flash-player-on.html and http://linux-bsd-sharing.blogspot.pt/2012/04/howto-install-adobe-flash-player-on.html for 64 and 32 bit systems, respectively.

Monday, July 9, 2012

HowTo: Enable Wake-on-LAN on CentOS / SL 6.3

Wake-on-LAN also know as WOL is the ability to switch on a computer that is connected to a network (local or not) by means of a special network message called a magic packet. This magic packet contains the MAC address of the destination computer. If the destination computer has a network interface card that support WOL then the system wakes up.

In this post I'll describe how to setup a CentOS destination computer so that it can be turned on from another computer. This procedure is also applicable to RHEL and its clones such as Scientific Linux and Oracle Unbreakable Linux.

For sake of simplicity I've broken down the procedure into a few steps:
1) Enable WOL in BIOS
2) Collect network interface information
3) Enable WOL for the next shutdown
4) Make WOL always enabled
5) Wake up the computer from local network
6) Wake up the computer from internet
7) Troubleshooting

1) Enable WOL in BIOS

These days pretty much all integrated or otherwise NICs support Wake-on-LAN, however more often than not you'll need to enable it in the BIOS. There are literally hundreds of BIOS around but look for the typical options: "Enable Wake-on-LAN", "Enable Wake on PCI" and "Enable Power of PCIE Devices".

2) Collect network interface information

Start by checking if the destination computer network card support Wake-on-LAN with ethtool:
  1. $ ifconfig
    eth0      Link encap:Ethernet  HWaddr 00:11:AA:22:BB:22 
              inet addr:192.168.1.5  Bcast:192.168.1.255  Mask:255.255.255.0
              inet6 addr: fc70::151:8daa:fbab:f14a/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:563668 errors:0 dropped:0 overruns:0 frame:0
              TX packets:317604 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000
              RX bytes:813741621 (776.0 MiB)  TX bytes:68592900 (65.4 MiB)
              Interrupt:22 Base address:0xa000

    lo        Link encap:Local Loopback 
              inet addr:127.0.0.1  Mask:255.0.0.0
              inet6 addr: ::1/128 Scope:Host
              UP LOOPBACK RUNNING  MTU:16436  Metric:1
              RX packets:8 errors:0 dropped:0 overruns:0 frame:0
              TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0
              RX bytes:480 (480.0 b)  TX bytes:480 (480.0 b)
  2. $ su
  3. # ethtool eth0
    Settings for eth0:
        Supported ports: [ MII ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
        Supports auto-negotiation: Yes
        Advertised link modes:  10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
        Advertised pause frame use: No
        Advertised auto-negotiation: Yes
        Speed: 100Mb/s
        Duplex: Full
        Port: MII
        PHYAD: 1
        Transceiver: external
        Auto-negotiation: on
        Supports Wake-on: g
        Wake-on: d
        Link detected: yes

The "Supports Wake-on: g" string means that the NIC does in fact support Wake-on-LAN while "Wake-on: d" is a sign that the feature is not turned activated in the operating system.

Do notice that the target of ethtool was eth0 which is my destination computer's network interface name.

To use Wake-on-LAN we need to identify the NIC MAC address to which end ifconfig can be used:
  1. # ifconfig | grep HWaddreth0 Link encap:Ethernet HWaddr 00:11:AA:22:BB:22
 

3) Enable WOL for the next shutdown

To command the operating system to enable WOL for the eth0 network interface run:
  1. # ethtool -s eth0 wol g

Issuing ethtool again now returns "Wake-on: g" so now we have WOL enabled:
  1. # ethtool eth0
    Settings for eth0:
        Supported ports: [ MII ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
        Supports auto-negotiation: Yes
        Advertised link modes:  10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
        Advertised pause frame use: No
        Advertised auto-negotiation: Yes
        Speed: 100Mb/s
        Duplex: Full
        Port: MII
        PHYAD: 1
        Transceiver: external
        Auto-negotiation: on
        Supports Wake-on: g
        Wake-on: g
        Link detected: yes

4) Make WOL always enabled

To have WOL always enabled the operating system needs to be told that eth0 (this is my NIC's interface name, don't forget to change according to your own system) WOL is supposed to be active.

There are 2 methods to achieve this, one employs adding ethtool -s eth0 wol g command to /etc/rc.d/rc.local while the other consists in creating a network script and enabling the network service.

Choose one of the methods, personally I'd go for the /etc/rc.d/rc.local method as it requires less typing ;)

Method A

  1. #echo '/usr/sbin/ethtool -s eth0 wol g' >> /etc/rc.d/rc.local

Method B
  1. # vim /etc/sysconfig/network-scripts/ifcfg-eth0
    DEVICE=eth0
    TYPE=EThernet 
    ONBOOT=yesETHTOOL_OPTS="wol g"
  2. # chkconfig network on

5) Wake up the computer from local network

From the computer that will be used to send the magic WOL packet, install and run wakelan:

  1. # yum install wakelan
  2. # rehash
  3. # wakelan 00:11:AA:22:BB:22

6) Wake up the computer from internet

This involves enabling port forwarding of UDP port 9 to the destination computer in the router's administration webpage. To fully benefit from WOL you should configure a dynamic DNS service.

Afterwards to issue the wake up command you can use websites such as http://wakeonlan.me, Android applications (Wake on Lan) or any other Wake-on-LAN application (every Unix-like system as an alternative available). Just make sure to use your dynamic DNS provided address and the destination computer's MAC.

7) Troubleshooting

While troubleshooting Wake-on-LAN I've noticed that if you use GRUB without timeout set and poweroff the computer while on the operating system selection menu, the next time you try to use Wake-on-LAN it won't work. So make sure you have GRUB with a timeout set (which is the case will all default installation of GRUB).

If the computer is disconnected from the power supply you'll need to boot the computer and turn off again so that the NIC assumes the WOL definitions.

Wednesday, June 20, 2012

HowTo: Enable Wake-on-LAN on Gentoo

Wake-on-LAN also know as WOL is the ability to switch on a computer that is connected to a network (local or not) by means of a special network message called a magic packet. This magic packet contains the MAC address of the destination computer. If the destination computer has a network interface card that support WOL then the system wakes up.

In this post I'll describe how to setup a Gentoo destination computer so that it can be turned on from another computer.

For sake of simplicity I've broken down the procedure into a few steps:
1) Enable WOL in BIOS
2) Install ethtool
3) Collect network interface information
4) Enable WOL for the next shutdown
5) Make WOL always enabled
6) Wake up the computer from local network
7) Wake up the computer from internet
8) Troubleshooting

1) Enable WOL in BIOS

These days pretty much all integrated or otherwise NICs support Wake-on-LAN, however more often than not you'll need to enable it in the BIOS. There are literally hundreds of BIOS around but look for the typical options: "Enable Wake-on-LAN", "Enable Wake on PCI" and "Enable Power of PCIE Devices".

2) Install ethtool

Take emerge for a spin and install sys-apps/ethtool. ethtool is an utility for examining and tuning ethernet-based network interfaces.
  1. # emerge ethtool
  2. # rehash

3) Collect network interface information

To use Wake-on-LAN we need to identify the NIC MAC address. For example, in my computer the MAC address is 00:aa:11:bb:22:cc.
  1. # ifconfigeth0      Link encap:Ethernet  HWaddr 00:aa:11:bb:22:cc 
              inet addr:192.168.1.3  Bcast:192.168.1.255  Mask:255.255.255.0
              inet6 addr: fa10::120:1aef:ffeb:b78a/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:129199 errors:0 dropped:0 overruns:0 frame:0
              TX packets:165680 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000
              RX bytes:58680158 (55.9 MiB)  TX bytes:26252276 (25.0 MiB)
              Interrupt:10 Base address:0xa000

    lo        Link encap:Local Loopback 
              inet addr:127.0.0.1  Mask:255.0.0.0
              inet6 addr: ::1/128 Scope:Host
              UP LOOPBACK RUNNING  MTU:16436  Metric:1
              RX packets:0 errors:0 dropped:0 overruns:0 frame:0
              TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0
              RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Check if the NIC does support the Wake-on-LAN feature:
  1. # ethtool eth0Settings for eth0:
    Supported ports: [ MII ]
    Supported link modes: 10baseT/Half 10baseT/Full
    100baseT/Half 100baseT/Full
    Supported pause frame use: No
    Supports auto-negotiation: Yes
    Advertised link modes: 10baseT/Half 10baseT/Full
    100baseT/Half 100baseT/Full
    Advertised pause frame use: No
    Advertised auto-negotiation: Yes
    Speed: 100Mb/s
    Duplex: Full
    Port: MII
    PHYAD: 1
    Transceiver: external
    Auto-negotiation: on
    Supports Wake-on: g
    Wake-on: d

    Link detected: yes

The "Supports Wake-on: g" string means that the NIC does in fact support Wake-on-LAN while "Wake-on: d" is a sign that the feature isn't active.

4) Enable WOL for the next shutdown

To command the operating system to enable WOL for the eth0 network interface run:

  1. # ethtool -s eth0 wol g

Issuing ethtool again now returns "Wake-on: g" so now we have WOL enabled:

  1. # ethtool eth0
    Settings for eth0:
    Supported ports: [ MII ]
    Supported link modes: 10baseT/Half 10baseT/Full
    100baseT/Half 100baseT/Full
    Supported pause frame use: No
    Supports auto-negotiation: Yes
    Advertised link modes: 10baseT/Half 10baseT/Full
    100baseT/Half 100baseT/Full
    Advertised pause frame use: No
    Advertised auto-negotiation: Yes
    Speed: 100Mb/s
    Duplex: Full
    Port: MII
    PHYAD: 1
    Transceiver: external
    Auto-negotiation: on
    Supports Wake-on: g
    Wake-on: g

    Link detected: yes

5) Make WOL always enabled

To have WOL always enabled Gentoo needs to be told that eth0 WOL is supposed to be active.

Assuming your're using OpenRC (which you should) add ethtool -s eth0 wol g to /etc/local.d/wol.start:
  1. # echo "ethtool -s eth0 wol g" > /etc/local.d/wol.start
  2. # chmod +x /etc/local.d/wol.start

The /etc/local.d/ directory contains scripts which are to be run when local service is started or stopped, so by adding a script with an executable script with a .start extension, it will be run when the local service is started at boot.

6) Wake up the computer from local network

From the computer that will be used to send the magic WOL packet, install and run net-misc/wakeonlan:

  1. # emerge wakeonlan
  2. # rehash
  3. # wakeonlan -i 192.168.1.255 00:50:8d:eb:a7:8a

Replace 192.168.1.255 with the broadcast from your network. 192.168.1.255 is the broadcast address for a 192.168.1.x subnet which is the case of my local network.

7) Wake up the computer from internet

This involves enabling port forwarding of UDP port 9 to the destination computer in the router's administration webpage. To fully benefit from WOL you should configure a dynamic DNS service.

Afterwards to issue the wake up command you can use websites such as http://wakeonlan.me, Android applications (Wake on Lan) or any other Wake-on-LAN application (every Unix-like system as an alternative available). Just make sure to use your dynamic DNS provided address and the destination computer's MAC.

8) Troubleshooting

While troubleshooting Wake-on-LAN I've noticed that if you use GRUB without timeout set and poweroff the computer while on the operating system selection menu, the next time you try to use Wake-on-LAN it won't work. So make sure you have GRUB with a timeout set (which is the case will all default installation of GRUB).

If the computer is disconnected from the power supply you'll need to boot the computer and turn off again so that the NIC assumes the WOL definitions.

HowTo: Enable Wake-on-LAN on FreeBSD

Wake-on-LAN also know as WOL is the ability to switch on a computer that is connected to a network (local or otherwise) by means of a special network message called a magic packet. This magic packet contains the MAC address of the destination computer. If the destination computer has a network interface card that supports WOL then the system wakes up.

In this post I'll describe how to Wake-on-LAN a FreeBSD destination computer so that it can be turned on from another computer.

For sake of simplicity I've broken down the procedure into a few steps:
1) Enable WOL in BIOS
2) Check for driver WOL support
3) Collect network interface information
4) Wake up computer from local network
5) Wake up computer from internet

1) Enable WOL in BIOS

These days pretty much all integrated or otherwise NICs support Wake-on-LAN, however more often than not you'll need to enable it in the BIOS. There are literally hundreds of BIOS around but look for the typical options: "Enable Wake-on-LAN", "Enable Wake on PCI" and "Enable Power of PCIE Devices".

2) Check for driver WOL support

With each FreeBSD release more and more ethernet drivers get support for Wake-on-LAN. To check the list of drivers with WOL support in your FreeBSD release (in my case 7.4-RELEASE) run:
  1. $ grep -l IFCAP_WOL /usr/src/sys/dev/*/*.c
    /usr/src/sys/dev/ae/if_ae.c
    /usr/src/sys/dev/age/if_age.c
    /usr/src/sys/dev/alc/if_alc.c
    /usr/src/sys/dev/ale/if_ale.c
    /usr/src/sys/dev/e1000/if_em.c
    /usr/src/sys/dev/e1000/if_lem.c
    /usr/src/sys/dev/fxp/if_fxp.c
    /usr/src/sys/dev/jme/if_jme.c
    /usr/src/sys/dev/nfe/if_nfe.c
    /usr/src/sys/dev/nge/if_nge.c
    /usr/src/sys/dev/re/if_re.c
    /usr/src/sys/dev/sis/if_sis.c
    /usr/src/sys/dev/ste/if_ste.c
    /usr/src/sys/dev/stge/if_stge.c
    /usr/src/sys/dev/txp/if_txp.c
    /usr/src/sys/dev/vge/if_vge.c
    /usr/src/sys/dev/vr/if_vr.c

Now compare the list of WOL supported drivers with the driver attached to your network interface:
 $ ifconfig -m   
 re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500  
     options=389b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_UCAST,WOL_MCAST,WOL_MAGIC>  
     capabilities=4399b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4,WOL_UCAST,WOL_MCAST,WOL_MAGIC,VLAN_HWTSO>  
     ether 00:aa:11:bb:22:cc  
     inet 192.168.1.3 netmask 0xffffff00 broadcast 192.168.1.255  
     media: Ethernet autoselect (100baseTX <full-duplex>)  
     status: active  
     supported media:  
         media autoselect mediaopt flowcontrol  
         media autoselect  
         media 1000baseTX mediaopt full-duplex,flowcontrol,master  
         media 1000baseTX mediaopt full-duplex,flowcontrol  
         media 1000baseTX mediaopt full-duplex,master  
         media 1000baseTX mediaopt full-duplex  
         media 1000baseTX mediaopt master  
         media 1000baseTX  
         media 100baseTX mediaopt full-duplex,flowcontrol  
         media 100baseTX mediaopt full-duplex  
         media 100baseTX  
         media 10baseT/UTP mediaopt full-duplex,flowcontrol  
         media 10baseT/UTP mediaopt full-duplex  
         media 10baseT/UTP  
         media none  
 plip0: flags=108810<POINTOPOINT,SIMPLEX,MULTICAST,NEEDSGIANT> metric 0 mtu 1500  
 lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384  
     inet6 fe80::1 prefixlen 64 scopeid 0x4   
     inet6 ::1 prefixlen 128   
     inet 127.0.0.1 netmask 0xff000000   
By analysing the output of ifconfig one can notice that I have re driver attached to network card. Also the re0 card not only is capable of WOL but also it is already setup to use it.

FreeBSD is extremely well documented and as such WOL support can be confirmed in re(4) man page.

3) Collect network interface information

From the output of ifconfig -m I can write down the MAC address for re0, 00:aa:11:bb:22:cc.
  1. $ ifconfig -m | grep ether        ether 00:aa:11:bb:22:cc

4) Wake up computer from local network

With the destination computer turned off, from the computer that will be used to send the magic WOL packet, install the net/wakeonlan port and run it:
  1. # cd /usr/ports/net/wakeonlan
  2. # make install clean
  3. # rehash
  4. # wakeonlan -i 192.168.1.255 00:aa:11:bb:22:cc

Replace 192.168.1.255 with the broadcast from your network. 192.168.1.255 is the broadcast address for a 192.168.1.x subnet which is the case of my local network and 00:aa:11:bb:22:cc is MAC address of the destination computer.

It should be noted that net/wakeonlan and similar applications are available in all Unix-like operating systems.

5) Wake up computer from internet

This involves enabling port forwarding of UDP port 9 to the destination computer in the router's administration webpage. To fully benefit from WOL you should configure a dynamic DNS service.

Afterwards to issue the wake up command you can use websites such as http://wakeonlan.me, Android applications (Wake on Lan) or any other Wake-on-LAN application (every Unix-like system as an alternative available). Just make sure to use your dynamic DNS provided address and the destination computer's MAC.

Thursday, June 7, 2012

HowTo: Install and setup MiniDLNA on FreeBSD

MiniDLNA is a server software with the aim of being fully compliant with DLNA/UPnP-AV clients. MiniDLNA is used to serve multimedia files such as music, videos and picture to clients on a given network.

MiniDLNA employs Universal Plug and Play (UPnP) thus you can have clients such as TVs, consoles and smartphones.

In this post I'll describe the steps needed to install and configure it to run on FreeBSD, though the steps were performed on 7.4-RELEASE they'll work on more recent FreeBSD branches such as 8.x and 9.x.

Let's start by installing the net/minidlna port:
  1. # cd /usr/ports/net/minidlna
  2. # make config-recursive
  3. # make install clean

Having installed the port, it's time to edit the configuration file. As an example, I'll leave my own as reference. Make sure that you edit network_interface, media_dir and friendly_name.
  1. # vim /usr/local/etc/minidlna.conf

    # port for HTTP (descriptions, SOAP, media transfer) traffic
    port=8200

    # network interfaces to serve, comma delimited
    network_interface=re0

    # set this to the directory you want scanned.
    # * if have multiple directories, you can have multiple media_dir= lines
    # * if you want to restrict a media_dir to a specific content type, you
    #   can prepend the type, followed by a comma, to the directory:
    #   + "A" for audio  (eg. media_dir=A,/home/jmaggard/Music)
    #   + "V" for video  (eg. media_dir=V,/home/jmaggard/Videos)
    #   + "P" for images (eg. media_dir=P,/home/jmaggard/Pictures)
    media_dir=V,/home/samba/public/movies
    media_dir=V,/mnt/1/tv
    media_dir=V,/mnt/2/anime
    media_dir=A,/mnt/1/music
    media_dir=P,/mnt/1/photos

    # set this if you want to customize the name that shows up on your clients
    friendly_name=FreeBSD DLNA Server

    # set this if you would like to specify the directory where you want MiniDLNA to store its database and album art cache
    db_dir=/var/db/minidlna

    # set this if you would like to specify the directory where you want MiniDLNA to store its log file
    log_dir=/var/db/minidlna

    # set this to change the verbosity of the information that is logged
    # each section can use a different level: off, fatal, error, warn, info, or debug
    log_level=general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=warn

    # this should be a list of file names to check for when searching for album art
    # note: names should be delimited with a forward slash ("/")
    album_art_names=Cover.jpg/cover.jpg/AlbumArtSmall.jpg/albumartsmall.jpg/AlbumArt.jpg/albumart.jpg/Album.jpg/album.jpg/Folder.jpg/folder.jpg/Thumb.jpg/thumb.jpg

    # set this to no to disable inotify monitoring to automatically discover new files
    # note: the default is yes
    inotify=yes

    # set this to yes to enable support for streaming .jpg and .mp3 files to a TiVo supporting HMO
    enable_tivo=no

    # set this to strictly adhere to DLNA standards.
    # * This will allow server-side downscaling of very large JPEG images,
    #   which may hurt JPEG serving performance on (at least) Sony DLNA products.
    strict_dlna=no

    # default presentation url is http address on port 80
    #presentation_url=http://www.mylan/index.php

    # notify interval in seconds. default is 895 seconds.
    notify_interval=900

    # serial and model number the daemon will report to clients
    # in its XML description
    serial=1337
    model_number=1

    # specify the path to the MiniSSDPd socket
    #minissdpdsocket=/var/run/minissdpd.sock

    # use different container as root of the tree
    # possible values:
    #   + "." - use standard container (this is the default)
    #   + "B" - "Browse Directory"
    #   + "M" - "Music"
    #   + "V" - "Video"
    #   + "P" - "Pictures"
    # if you specify "B" and client device is audio-only then "Music/Folders" will be used as root
    #root_container=.

To have MiniDLNA working properly the dlna user must be made owner of the /var/db/minidlna directory:
  1. # mkdir -p /var/db/minidlna
  2. # chown dlna:dlna /var/db/minidlna

To start using MiniDLNA immediately issue the following command:
  1. # /usr/local/etc/rc.d/minidlna onestart

If you want to have it start up automatically whenever FreeBSD boots, add it to /etc/rc.conf like so:
  1. # echo 'minidlna_enable="YES"' >> /etc/rc.conf

Finally MiniDLNA's log file can be monitored for errors:
  1. # tail -f /var/db/minidlna/minidlna.log

MiniDLNA it's quite simple and lightweight however it is missing features that can be found in more complete UPnP servers. Those operating on old hardware might find it very useful.

Be advised that if you're planning on sharing multimedia files over a local network composed mainly of desktops and laptops, NFS and Samba are more flexible filesharing alternatives. On the other hand, if you want to stream to a TV, console or smartphone then by all means go for an UPnP server like MiniDLNA or MediaTomb.

If you're using an Android smartphone have a look at the MediaHouse app. From my experience it works just fine with MiniDLNA.

Friday, June 1, 2012

HowTo: Shrink size of ext4 LVM logical volume

LVM, the Logical Volume Manager, is extremely flexible and provides numerous advantages over standard partitions. One of those advantages consists in resizing logical volumes.

In this post I'll go over the required steps to reduce the size of an LVM logical volume formatted as an ext4 filesystem. This is achieved can be achieved in a few steps:
1) Unmount the logical volume (or boot into a live CD if the logical volume contains the root filesystem)
2) Check the filesystem for errors
3) Shrink the filesystem to the desired size
4) Reduce the size of the underlying logical volume
5) Check if the resulting logical volume and filesystem are ok
6) Re-mount the logical volume

To illustrate the procedure assume a volume group name vg_d620 which contains the lv_example logical group. The objective will be to shrink the lv_example logical group that is formatted with ext4 to 30G.

1) Unmount the logical volume

Change to the superuser and unmount the logical volume filesystem that is to be resized:

  1. $ su
  2. # umount /dev/mapper/vg_d620-lv_example

2) Check the filesystem for errors

e2fsck checks a Linux ext2/ext3/ext4 filesystem for errors, in this case the -f switch is used to force the check even if the filesystem appears to be clean:

  1. # e2fsck -f /dev/mapper/vg_d620-lv_example
  2. e2fsck 1.41.12 (17-May-2010)
    Pass 1: Checking inodes, blocks, and sizes
    Pass 2: Checking directory structure
    Pass 3: Checking directory connectivity
    Pass 4: Checking reference counts
    Pass 5: Checking group summary information
    /dev/mapper/vg_d620-lv_example: 11448/3678208 files (1.5% non-contiguous), 4768046/14704640 blocks

3) Shrink the filesystem to the desired size

resize2fs is used to shrink our unmounted filesystem located on vol_d620-lv_example. The -p switch is prints out percentage completion bars for the resize operation. Here the ext4 filesystem is reduced to the desired filesystem final size, in this case I want it to be of 30 gigabytes:

  1. # resize2fs -p /dev/mapper/vg_d620-lv_example 30G
  2. resize2fs 1.41.12 (17-May-2010)
    Resizing the filesystem on /dev/mapper/vg_d620-lv_example to 7864320 (4k) blocks.
    Begin pass 2 (max = 16894)
    Relocating blocks   XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Begin pass 3 (max = 449)
    Scanning inode table XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Begin pass 4 (max = 1866)
    Updating inode references XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    The filesystem on /dev/mapper/vg_d620-lv_example is now 7864320 blocks long.

4) Reduce the size of the underlying logical volume

Having shrunk the ext4 filesystem it is time to reduce the logical volume size accordingly. To achieve this the lvreduce tool is employed. The -L switch specifies final size of the logical volume which should match the size of the ext4 filesystem.

  1. # lvreduce -L 30G /dev/mapper/vg_d620-lv_example
  2. WARNING: Reducing active logical volume to 30.00 GiB
    THIS MAY DESTROY YOUR DATA (filesystem etc.)
    Do you really want to reduce lv_example? [y/n]: y
    Reducing logical volume lv_example to 30.00 GiB
    Logical volume lv_example successfully resized

5) Check if the resulting logical volume and filesystem are ok

Everything should have proceeded as planned however let's verify things. e2fsck and resize2fs are used verify the new filesystem, respectively. Notice that this time the resize2fs doesn't specify any size, the goal here is to have the filesystem match the size of the logical volume.

  1. # e2fsck -f /dev/mapper/vg_d620-lv_example
  2. e2fsck 1.41.12 (17-May-2010)
    Pass 1: Checking inodes, blocks, and sizes
    Pass 2: Checking directory structure
    Pass 3: Checking directory connectivity
    Pass 4: Checking reference counts
    Pass 5: Checking group summary information
    /dev/mapper/vg_d620-lv_example: 11448/1966080 files (1.5% non-contiguous), 4658570/7864320 blocks
  3. # resize2fs -p /dev/mapper/vg_d620-lv_example
  4. resize2fs 1.41.12 (17-May-2010)The filesystem is already 7864320 blocks long. Nothing to do!

6) Re-mount the logical volume

Finally, mount the updated logical volume: 

  1. # mount /dev/mapper/vg_d620-lv_example /mnt/example

It should be noted that if in step 4 e2fsck fails because the partition is tool small lvextend can be used to extend the logical volume until e2fsck completes with success.

Further information on lvm, lvreduce, lvextend,e2fsck and resize2fs can be obtained in the associated man pages.

Monday, May 28, 2012

HowTo: Mount UFS partition on CentOS / SL 6.2

By default RHEL clones such as CentOS and Scientific Linux don't come with UFS filesystem support.

However the ELRepo repository has the kmod-ufs package which provides the much needed kernel module. As such enabling ufs support on RHEL/CentOS/SL 6.2 consists of adding the ELRepo repository, installing and loading the kernel module for UFS.

The required steps are:
  1. $ su
  2. # rpm --import http://elrepo.org/RPM-GPG-KEY-elrepo.org
  3. # rpm -Uvh http://elrepo.org/elrepo-release-6-4.el6.elrepo.noarch.rpm
  4. # yum update
  5. # yum install kmod-ufs
  6. # modprobe ufs

Now that we have kernel support for UFS let's proceed to identify the partition(s) with UFS filesystems:
  1. # fdisk -l /dev/sdb
 
 Disk /dev/sdb: 203.9 GB, 203928109056 bytes  
 255 heads, 63 sectors/track, 24792 cylinders  
 Units = cylinders of 16065 * 512 = 8225280 bytes  
 Sector size (logical/physical): 512 bytes / 512 bytes  
 I/O size (minimum/optimal): 512 bytes / 512 bytes  
 Disk identifier: 0x90909090  
   Device Boot   Start     End   Blocks  Id System  
 /dev/sdb1        1    1968  15807928+  7 HPFS/NTFS  
 /dev/sdb2      1969    7067  40957717+ a5 FreeBSD  
 /dev/sdb3  *    7068    12166  40957717+ a5 FreeBSD  

In the BSD world slices are subdivided into partitions. Where Linux fdisk sees a FreeBSD partition that partition is in fact a BSD slice with internal partitions. Taking a peek at the output of /var/log/messages helps in identifying which are partitions that can be mounted.

For example in my system:

  1. # grep /dev/sdb /var/log/messages
 May 24 21:44:33 athon kernel: sda5 sdb2: <bsd: sdb5 sdb6 sdb7 sdb8 sdb9 >  
 May 24 21:44:33 athon kernel: sda6 sda7 sda8 sdb3: <bsd: sdb10 sdb11 sdb12 sdb13 >  
 May 28 19:39:09 athon kernel: sda5 sda6 sdb2: <bsd: sdb5 sdb6 sdb7 sdb8 sdb9 >  
 May 28 19:39:09 athon kernel: sda7 sda8 sdb3: <bsd: sdb10 sdb11 sdb12 sdb13 >  

What does this mean? sdb2, sdb3, sdb5, sdb6, sdb7, sdb8, sdb9, sdb10, sdb11, sdb12 and sdb13 are FreeBSD UFS partitions.

To mount a FreeBSD UFS partition:
  1. # mount -t ufs -o ufstype=ufs2,ro /dev/sdb2 /mnt/

In which -t ufs -o ufstype=ufs2,ro identify the UFS filesystem as being UFS2 and mounted as read-only.

Sunday, May 20, 2012

HowTo: Enemy Territory on x86_64 CentOS 6.2 / SL 6.2

Update 21/05/2012:
I'm getting Punkbuster kicked out of the game by random game integrity violations. I'm trying to identify a solution, until then I figure what's wrong I can't recommend following this how-to.
If you're reading this and manage to fix the problem, please let me know in the comments.
Update 04/06/2012:
Installed ET on Ubuntu 12.04 x86_64 both the manual way and using the get-deb package and the result is the same: random PB kick on servers running Punkbuster.

Wolfenstein: Enemy Territory is a free multiplayer FPS that takes place in the World World II pitting two teams (Allies and Axis) against each other for victory.

In this post I'll detail the steps required to install and update Enemy Territory on 64-bit CentOS, namely:
1) Download the necessary files
2) Install i686 libraries
3) Install and update Enemy Territory
4) Install updated Punkbuster files
5) Generate an etkey
6) Fix sound problem
7) Setup widescreen resolution
8) Bonus section: troubleshooting

It should be noted that the steps were performed on CentOS 6.2 x86_64 thus should translate to RHEL and Scientific Linux..

1) Download Enemy Territory 2.60 and 2.60b update

Download et-linux-2.60.x86.run, et-2.60b.zip update, updated Punkbuster and the et-sdl-sound.gz sound fix: 
  1. $ wget -c http://ftp.freenet.de/pub/4players/hosted/et/official/et-linux-2.60.x86.run
  2. $ wget -c ftp://ftp.idsoftware.com/idstuff/et/ET-2.60b.zip
  3. $ wget -c http://etkey.org/et_linux.zip
  4. $ wget -c http://nullkey.kapsi.fi/~stuff/et-sdl-sound/et-sdl-sound.gz

2) Install i686 libraries

Enemy Territory is a 32-bit application as such for a 64-bit CentOS a few i686 libraries are needed:
  1. # yum install glibc.i686 libX11.i686 libXext.i686 libstdc++.i686 pulseaudio-libs.i686

Enemy Territory requires 3D acceleration which commonly implies NVIDIA or AMD/ATI graphic cards and associated proprietary drivers.

User of NVIDIA cards are required to install nvidia-x11-drv-32bit which provides the compatibility 32-bit files for the 64-bit proprietary NVIDIA driver:
  1. # yum install nvidia-x11-drv-32bit

I'd assume that users of AMD/ATI graphics card need to install fglrx-x11-drv-32bit which provides similar files for the proprietary AMD driver, however I don't have an AMD/ATI card to verify.

3) Install and update Enemy Territory

Change to root, attribute execute permissions to the installer, install Enemy Territory 2.60, install the 2.60b update, create a profile and check the game's version:
  1. $ su
  2. # chmod +x et-linux-2.60.x86.run
  3. #./et-linux-2.60.x86.run

Press OK in the popup. Agree with the License Agreement by pressing ENTER at the License Agreement prompt and choosing YES on "Do you agree with the license?" popup that follows. Choose NO at the "Would you like to read the CHANGES file?" popup. You can always read the CHANGES file latter on if you want. Choose the installation path and press OK in the Symlink Path popup. Install both Enemy Territory and Punkbuster. Choose to install the startup menu entries. After this the game installs. Don't choose to start the game immediately as we haven't finished installing everything.

Install the 2.60b update:
  1. # unzip et-2.60b.zip
  2. # cp Enemy\ Territory\ 2.60b/linux/* /usr/local/games/enemy-territory/
  3. # exit

Now start the game, create a player profile identifying profile name, connection speed and clicking on Enable Punkbuster; exit the game. By doing so a .etwolf directory will be created in your home directory which includes a folder containing PunkBuster.

Inside the game you can check the installed version by pulling the console down by pressing ~ and typing version. It should output the following:
 ]\version  
 "version" is:"ET 2.60b linux-i386 May 8 2006" default:"ET 2.60b linux-i386 May 8 2006"  

4) Install updated Punkbuster files

Remove old Punkbuster files, extract the last Punkbuster update and place it in the created profile:
  1. $ rm -rf ~/.etwolf/etmain/pb
  2. $ unzip et_linux.zip -d pb
  3. $ cp -R pb ~./etwolf/etmain/

5) Generate an etkey

Point to http://etkey.org/pages/etkey-home.php, press the Get an ETKEY button, download the file and store it under ~./etwolf/etmain/.

6) Fix sound problem

The most dreadful any Linux Enemy Territory player can witness:
 ------- sound initialization -------  
 /dev/dsp: No such file or directory  
 Could not open /dev/dsp  
 ------------------------------------  
Luckily we can use the SDL backend which Enemy Territory will use as audio device replacing /dev/dsp and OSS.

Install SDL, extract the et-sdl-sound script, make it executable and accessible to all and edit the et launcher to have Enemy Territory use SDL instead of OSS:
  1. # yum install SDL.i686
  2. # gzip -d et-sdl-sound.gz
  3. # chmod a+x et-sdl-sound
  4. # chown root:root et-sdl-sound
  5. # mv et-sdl-sound /usr/local/games/enemy-territory/
  6. # vim /usr/local/games/enemy-territory/et

 #!/bin/sh  
 # Needed to make symlinks/shortcuts work.  
 # the binaries must run with correct working directory  
 cd "/usr/local/games/enemy-territory/"  
 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.  
 ./et-sdl-sound "$@"  

The et-sdl-sound script needs to be edit so that PulseAudio is used has the SDL audio driver.
  1. # vim /
    usr/local/games/enemy-territory/et-sdl-sound
 Replace  
 SDL_AUDIODRIVER="alsa"  
 with  
 SDL_AUDIODRIVER="pulse"

7) Setup widescreen resolution

If you have a widescreen monitor follow the instructions on my previous blog post HowTo: Widescreen resolutions on Enemy Territory.

And we're done installing Enemy Territory!

Lately I've been playing at [fp].:Demolition_Centre as tangram"FreeBSD~ or tangram"GNU/Linux~. See you on the battlefield :D

8) Bonus section: troubleshooting

Error:
 /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory  
  1. # yum install glibc.i686

Error:
 ./et.x86: error while loading shared libraries: libX11.so.6: cannot open shared object file: No such file or directory  
  1. # yum install libX11.i686

Error:
 ./et.x86: error while loading shared libraries: libXext.so.6: cannot open shared object file: No such file or directory  
  1. # yum install libXext.i686

Error:
 ----- Client Initialization Complete -----  
 ----- R_Init -----  
 ...loading libGL.so.1: QGL_Init: dlopen libGL.so.1 failed: libGL.so.1: cannot open shared object file: No such file or directory  
 failed  
 ----- CL_Shutdown -----  
 RE_Shutdown( 1 )  
 -----------------------  
 ----- CL_Shutdown -----  
 -----------------------  
 Sys_Error: GLimp_Init() - could not load OpenGL subsystem  
  1. # yum install nvidia-x11-drv-32bit

or
  1. # yum install fglrx-x11-drv-32bit