MacBook Ubuntu Overheating

I dual boot Ubuntu 14.04 LTS on my work MacBook Pro (2015?). The SSD makes it a pretty quick dev machine but out of the box temperature control doesn’t seem to work. There are lots of outdated old forum posts about manually setting the fan speed. In 2018 all you need to do get fan control working is install macfanctld!

$ sudo apt install lm-sensors
$ sensors
Adapter: Virtual device
temp1: +35.3°C

Adapter: ISA adapter
Physical id 0: +73.0°C (high = +84.0°C, crit = +100.0°C)
Core 0: +73.0°C (high = +84.0°C, crit = +100.0°C)
Core 1: +69.0°C (high = +84.0°C, crit = +100.0°C)
Core 2: +71.0°C (high = +84.0°C, crit = +100.0°C)
Core 3: +68.0°C (high = +84.0°C, crit = +100.0°C)

Install fan control daemon:

sudo apt install macfanctld

Instantly the fans spin up and the temperature quickly drops down to normal:

$ sensors
Adapter: Virtual device
temp1: +33.9°C

Adapter: ISA adapter
Physical id 0: +54.0°C (high = +84.0°C, crit = +100.0°C)
Core 0: +54.0°C (high = +84.0°C, crit = +100.0°C)
Core 1: +50.0°C (high = +84.0°C, crit = +100.0°C)
Core 2: +50.0°C (high = +84.0°C, crit = +100.0°C)
Core 3: +50.0°C (high = +84.0°C, crit = +100.0°C)

Remote Torrent Server with Deluge Web & Systemd

The Deluge torrent client can be run headless which is useful for downloading on a remote media server.

Install deluge & deluge-web

sudo apt install deluge deluged deluge-web

Systemd Services


Description=Deluge Torrent Server

ExecStart=/usr/bin/deluged --do-not-daemonize



Description=Deluge Torrent Server



Starting the Services

sudo systemctl enable deluged.service
sudo systemctl start deluged.service
sudo systemctl enable delugeweb.service
sudo systemctl start delugeweb.service

Using Deluge Web UI

Open the web client:


The default password is ‘deluge’

Auto-connect of Web UI to Daemon

Modify ~/.config/deluge/web.conf and set “default_daemon” to the hash found in ~/.config/deluge/hostlist.conf.1.2

I assume you need to manually connect once to populate hostlist.


Media Server for Chromecast Streaming

I have now switched to using a Chromecast for all our TV needs. I have an old Android phone (Moto G) that has been re-purposed as the remote. For local pre-downloaded content, I have a Media Server running Ubuntu 17.10. The best setup I have found for streaming this local content to the Chromecast is VideoStream.


VideoStream Install

The Android App can be found here:
On Linux, there is no native install so you need to use Chrome and install VideoStream as an extension:

As my server is headless, the install of Chrome and the VideoStream extension are done using ssh -X.

When you Pair your device, you also need to have Chrome open over SSH to receive the popup and accept the pairing.

Running VideoStream Headless on Boot

Create the following systemd service file: /etc/systemd/system/videostream.service

Description=VideoStream Server

ExecStart=/bin/bash xvfb-run google-chrome --app-id=cnciopoikihiagdjbjpnocolokfelagl


Streaming Apps

Netflix, TVNZ and TV3.

Automated backup of an external drive on Linux

The following steps set up a backup for a particular USB drive every time it is inserted. Very useful for avoiding the perils of working directly from a flash drive on multiple computers.

Create the backup script that uses duplicity:




sleep 4

duplicity incremental /media/username/USBDRIVE file://$BACKUP_DIR --no-encryption >> $BACKUP_DIR/log.txt
if [ $? -eq 0 ]; then
    echo "## Backup complete `date`" >> $BACKUP_DIR/log.txt



/usr/local/bin/ &

Set up the udev rule to run the backup script every time the drive is inserted:

Find the device ID

$ lsusb
Bus 002 Device 002: ID 0930:1400 Toshiba Corp. Memory Stick 2GB


ACTION=="add", ATTRS{idVendor}=="0930", ATTRS{idProduct}=="1400", ENV{XAUTHORITY}="/home/username/.Xauthority", ENV{DISPLAY}=":0", OWNER="username", RUN+="/usr/local/bin/usb-backup-in_udev"

Restoring the backup:

duplicity restore file:///home/username/BACKUPS/USBDriveBackup ./RestoredFiles/ --no-encryption

Bash – Loops using pipe and read

Perform some operation for every line in the output of a command, e.g. add .txt to every file in a directory:

ls /var/* | while read fname; do cp $fname $fname.txt; done

Instead of:

for fname in `ls /var/*`; do cp $fname $fname.txt; done

Neat trick I actually picked up in a job interview. Easier to read if the original command is long as it avoids the backticks, and bash is all about readability, right?? 🙂

Bash String Manipulation

Bash has some convenient string manipulation functions. I often use substring removal which is very handy for trimming suffixes and prefixes from things like file names. These operations all evaluate to a new string and don’t modify the original variable.

Suffix removal
Remove the longest match from end:
Remove the shortest match from end:

Prefix removal
Remove the longest match from front:
Remove the shortest match from front:

Great reference for more string operations:

VirtualBox driver (vboxdrv) missing after Ubuntu 12.04 upgrade

After upgrading to 12.04 I got the following error when trying to start VirtualBox:

The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing

‘/etc/init.d/vboxdrv setup’

as root. If it is available in your distribution, you should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.

The script mentioned did not exist because the vboxdrv was not compiled.
# sudo /etc/init.d/vboxdrv setup
sudo: /etc/init.d/vboxdrv: command not found

If you reinstall virtualbox-dkms it will recompile the driver for your kernel version, provided you have the correct kernel headers.
# sudo apt-get remove dkms virtualbox-dkms
# uname -a
Linux pc786-ubu 3.2.0-33-generic #52-Ubuntu SMP Thu Oct 18 16:29:15 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
# sudo apt-get install linux-headers-3.2.0-33
# sudo apt-get install dkms virtualbox-dkms

Linux timers using file descriptors

I recently had to add some timers to an application that was polling a list of file descriptors. The linux timers interface that notifies using file descriptors worked well. Basic example below:

* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <;.
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/timerfd.h>
#include <unistd.h>
#include <fcntl.h>
#define TIMEOUT 3
#define POLL_PERIOD 1
int main(int argc, char *argv[])
int ret;
int fd = –1;
struct itimerspec timeout;
unsigned long long missed;
/* create new timer */
fd = timerfd_create(CLOCK_MONOTONIC, 0);
if (fd <= 0) {
printf("Failed to create timer\n");
return 1;
/* set to non-blocking */
ret = fcntl(fd, F_SETFL, O_NONBLOCK);
if (ret) {
printf("Failed to set to non blocking mode\n");
return 1;
/* set timeout */
timeout.it_value.tv_sec = TIMEOUT;
timeout.it_value.tv_nsec = 0;
timeout.it_interval.tv_sec = TIMEOUT; /* recurring */
timeout.it_interval.tv_nsec = 0;
ret = timerfd_settime(fd, 0, &timeout, NULL);
if (ret) {
printf("Failed to set timer duration\n");
return 1;
while (1) {
while (read(fd, &missed, sizeof(missed)) < 0) {
printf("No timer expiry\n");
printf("Number of expiries missed: %lld\n", missed);
return 0;

Receiving raw packets in Linux without pcap

Since there was a lot of interest in my post on sending raw Ethernet packets, this is an example of receiving packets on a raw socket. A compiling version can be found on github: The application that I developed this for was to receive packets sent to a specific MAC address. The main sections are explained below:

Open raw socket listening for ETHER_TYPE

	if ((sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETHER_TYPE))) == -1) {
		perror("listener: socket");	
		return -1;

Set interface to promiscuous mode

	strncpy(ifopts.ifr_name, ifName, IFNAMSIZ-1);
	ioctl(sockfd, SIOCGIFFLAGS, &ifopts);
	ifopts.ifr_flags |= IFF_PROMISC;
	ioctl(sockfd, SIOCSIFFLAGS, &ifopts);

Allow socket to be reused

	if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof sockopt) == -1) {

Bind to device

	if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, ifName, IFNAMSIZ-1) == -1)	{

Receive on socket

	numbytes = recvfrom(sockfd, buf, BUF_SIZ, 0, NULL, NULL);
	printf("listener: got packet %lu bytes\n", numbytes);

Print the data

	for (i=0; i<numbytes; i++) printf("%02x:", buf[i]);

Close socket