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.