Running Microdc2 as a Daemon on Startup and Limiting it’s Bandwidth on Ubuntu 16.04

Background:

Building on the last post, it is now time to install and configure a DC client to connect to the server. Unfortunately Microdc2 has a series of limitations that we will need to work around, these include:

  • Microdc2 does not come with any system startup scripts.
  • It has no ability to control the bandwidth used by file transfers.
  • It cannot be left to run by itself if you quit the terminal.

Thankfully there are ways to work around all of these. We can write and install our own Systemd scripts, use trickle to limit the bandwidth, and use screen to run microdc2 in a headless environment that allows us to check the status at will.

Setup:

I’ve assumed that screen, microdc2 and trickle are already installed, if not, type the following:

sudo apt install screen microdc2 trickle

All of microdc2’s settings are stored in ~/.microdc2/config

I have unashamedly used the config file found here as a template:

# You should make sure that this listen port is forwarded properly if you are behind a router. If you can't forward ports, set active off and use passive mode. This can work behind firewalls but is crippled and slower than a properly forwarded one. NOTE: the port MUST be set before active mode is set on.
set listenport Port#
set active on

# The following address should be set to your EXTERNAL ip address. This can be found by visiting www.whatismyip.com.
#set listenaddr xxx.xxx.xxx.xxx

# I like to turn autoreconnect on in case I get disconnected from the server for whatever reason.
set auto_reconnect on

# The following enables logging. Replace the logfile with wherever you want it to log to. You can of course turn it off by leaving the following two lines blank
set log_charset UTF-8
set logfile /home/user/.microdc2/log

# These should all be pretty self-explanatory. Nick is your nickname. If the hub requires a password, specify one here.
set description Description goes here
set email MyEmail@url.com
set nick NickName
#This is the password for the DC Server
set password Sup3rS3cr3t
set downloaddir /path/to/directory/

# The set speed option doesn't actually change anything, it only changes your REPORTED speed that other users see. The slot is how many simultaneous downloads people can get from you.
set speed 450KBps
set slots 5

#This is the hub connect command, it should be left until last
connect url:port

Ensure that the port you specify in the first line is open and forwarding to your microdc2 host. It isn’t necessary to set the listening address as it will listen for incoming connections on all interfaces, which is fine if you’re behind a firewall/router.

Run microdc2 as the user who will be running it as a daemon. and add any directories you would like to share with:

share /path/to/files

Microdc2 will only remember the files that are shared, all other settings must be stored in the config file.

It will potentially take a long time to hash all the files that you want to share depending on your hardware configuration and number of files. Your files won’t be shared until they are all hashed. This is useful of course, at good DC clients will download from multiple sources.

Running the program and setting limits:

Fundamentally, the command we will use looks like this:

screen -dmS microdc2 trickle -u 370 -t .1 microdc2

Screen will start in -d Detached mode, -m ignoring the $STY environment variable, forcing the creation of a session regardless of where it was started, -S session name, which I have called microdc2.

The program that screen calls is trickle. Trickle will only limit the upload speed -u, to 370Kbps. You may need to adjust this to suit yourself, -t .1 seconds to give a fine granularity of transfer speed. Again, i suggest testing this locally to see how it performs. Trickle will call the program microdc2 using its defaults for the user who called started the program.

Setting up a systemd startup script.

Create a systemd startup script and edit it:

sudo vi /lib/systemd/system/microdc2.service

Enter the following details, changing the username to the user who will run the program.

[Unit]
Description=Microdc2 Direct Connect Client
After=network.target

[Service]
Type=forking
ExecStart=/usr/bin/screen -dmS microdc2 trickle -u 370 -t .1 microdc2
User=username
Group=username

[Install] 
WantedBy=multi-user.target

Then run the update and start commands.

sudo systemctl daemon-reload
sudo systemctl enable microdc2.service
sudo service microcd2 start

Open the screen session

screen -r microdc2

close the screen session using the keyboard commands: CTRL+A, CTRL+D

Further reading:

Red Hat Systemd scripting
Trickle

 

How to Install and configure a Direct Connect Hub (PtokaX) on Ubuntu 16.04.

Background:

I wrote this documentation as the process serves as a good template for downloading, compiling from source, installing, configuring, and finally creating a systemd style script that will start a service at boot.

Process:

Download source from their website: http://www.ptokax.org/files/0.5.2.1-nix-src.tgz

wget http://www.ptokax.org/files/0.5.2.1-nix-src.tgz

Install the dependencies:

sudo apt install make g++ zlib1g-dev libtinyxml-dev liblua5.3-dev -y

Expand the archive and change into the directory:

tar -xf 0.5.2.1-nix-src.tgz;cd PtokaX

Compile the program (I’m compiling without database support):

make clean
make
sudo make install

Create a new system user to run the process:

sudo adduser --system --group --no-create-home --disabled-login ptokax

Create the directory in etc for the configuration files:

sudo mkdir /etc/ptokax

Run the initial config and configure according to your tastes, give the ptokax user access.

sudo PtokaX -m -c /etc/ptokax
sudo chown ptokax:ptokax -R /etc/ptokax/*

Create a new file in the directory: /lib/systemd/system/ called ptokax.service with the following in it:

[Unit]
Description=PtokaX Direct Connect Hub
After=network.target
#Requires=apache2.service

[Service]
Type=forking
ExecStart=/usr/local/bin/PtokaX -d -c /etc/ptokax
User=ptokax
Group=ptokax

[Install]
WantedBy=multi-user.target

Reload, enable and start the process.

sudo systemctl daemon-reload
sudo systemctl enable ptokax.service
sudo systemctl start ptokax.service

 

Test the connection:

Final Notes:

If you want to make configuration changes, stop the service first, then either run the Ptokax program as sudo with the -m -c /etc/ptokax flags to configure it, or manually edit it’s configuration files.

Further Reading:

http://wiki.ptokax.org/doku.php?id=guides:debian_bugbuntu
http://patrakov.blogspot.com.au/2011/01/writing-systemd-service-files.html

 

Enabling PCI passthrough of Hauppauge QuadHD PCIe TV Tuner Card with a Marvell 88SE9230 SATA controller

Background:

As the title suggests, this is a complex problem that I’ve had to work with. The goal has been to create a virtual machine running MythTV that can utilise the PCIe tuner card on the hypervisor.

The first step in the process was to compile and install the latest kernel image (at the time of writing this was 4.9.9). This was necessary as the kernel version that ships with Ubuntu 16.04 (version 4.4.0.xx)  does not have the most recent drivers that the tuner needs to function. This step I completed successfully and for more information, please see my previous posts.

Unfortunately, enabling iommu in the kernel activated a bug in the additional PCIe SATA card I have installed in the hypervisor that stopped the whole system from booting. More on that in a minute.

Affected Hardware:

Startech PEXSAT34RH 4-Port PCI Express 2.0 SATA Controller Card with a Marvell 88SE9230 chipset.
Hauppauge QuadHD PCIe TV Tuner Card.
Intel S1200SPL motherboard with a AXXRMM4LITE RMM4 module installed.

PCI devices identified as through lspci as:

05:00.0 Multimedia video controller: Conexant Systems, Inc. CX23887/8 PCIe Broadcast Audio and Video Decoder with 3D Comb (rev 04)
06:00.0 Multimedia video controller: Conexant Systems, Inc. CX23887/8 PCIe Broadcast Audio and Video Decoder with 3D Comb (rev 04)
02:00.0 SATA controller: Marvell Technology Group Ltd. 88SE9230 PCIe SATA 6Gb/s Controller (rev 11)

Partial resolution:

The first step was to enable iommu in the kernel without breaking the SATA controller card. the solution was to the enable iommu and set it to passthrough mode. This can be achieved on a Ubuntu system by editing /etc/default/grub and adding intel_iommu=on iommu=pt to the linux default settings: For my system it now looks like this:

GRUB_CMDLINE_LINUX_DEFAULT="nomodeset intel_iommu=on iommu=pt"

At the command line, run sudo update-grub and reboot.

The rest of the process, that includes adding the hardware to the VM host and enabling the pci_stub kernel module can be found in previous posts on my blog.

The only difficulties I encountered, and didn’t mention in my last blog post, was ensuring that the PCIe devices do not share IRQs. To check, I cross-referenced the output of:
:$ find /sys/kernel/iommu_groups/ -type l
with
:$ lscpi
I could confirm that the DVB-T tuner card had two interrupts, and did not share them with any other hardware device. More on that here.

Continuing problems:

After finally managing to get the PCI pass through function working which I verified by checking dmesg on the VM. I launched mythtv-setup and configured the tuner cards. MythTV successfully added them and I could add them to a video source. Unfortunately the system crashed when it tried to do an initial tune.
The console on the KVM host output the error:
vfio-pci pcie bus error severity=(uncorrected _Fatal), type=unaccessible,id=500(unregistered Agent ID)
And the console on the virtual machine output the error:
mpeg risc op code
and then promptly crashed.

Thankfully I have a backup single USB tuner, however it seems that the quest continues to get the tuner working properly.

Further reading:

IOMMU Bug in the 88SE9230 Chipset:
https://lime-technology.com/forum/index.php?topic=54410.0
http://lime-technology.com/forum/index.php?topic=40683
https://lime-technology.com/forum/index.php?topic=33511.0
Product Website

PCI Passthrough:
http://vfio.blogspot.com.au/2015/05/vfio-gpu-how-to-series-part-3-host.html

Hauppauge QuadHD PCIe TV Tuner Card:
LinuxTV Page
Product Website

 

How to Fix the Intel RMM4 No Signal on Linux

After installing the Remote Management Module AXXRMM4LITE into my Intel S1200SPL I was disappointed by being unable to see any output when using the Java applet.

Now, originally, I had noticed that after installation of the OS, there was no output to the monitor once Linux had booted. I got around this by installing a spare NVS300 graphic card and telling the BIOS to use it as the primary output.

Sensing that the two were related I removed the graphics card and told the BIOS to use the onboard graphics as the primary display. I still had the ‘no signal’ error in the java applet, but at least the hardware was configured correctly.  After doing some reading and searching, I was able to fix the issue by editing kernel boot parameters. In /etc/default/grub I added the option nomodeset to the GRUB_CMDLINE_LINUX_DEFAULT=””. such that it read:

GRUB_CMDLINE_LINUX_DEFAULT=”nomodeset”

Then I updated grub with:
$: sudo update-grub
$: sudo shutdown -hr now

And after rebooting, I was able to remotely see the console.

Further Reading:

https://community.linuxmint.com/tutorial/view/842

How to Compile the Linux Kernel from Source on Ubuntu 16.04 LTS

Background/Problem:

My KVM host, after a recent upgrade (see posts below) cannot start with the kernel option iommu=on enabled. Technically it can, however the system will not start due to a driver/bug issue with an additional SATA card I have installed:
:$ lspci

02:00.0 SATA controller: Marvell Technology Group Ltd. 88SE9230 PCIe SATA 6Gb/s Controller (rev 11)

Disks simply do not register when using iommu. The Bugzilla report can be found here and more information can be had here. The references are old, so my hope is that it has been patched in the latest kernel images.

Furthermore, I need the latest kernel to use the Quad tuner PCI-E card I have:
:$ lspci

05:00.0 Multimedia video controller: Conexant Systems, Inc. CX23887/8 PCIe Broadcast Audio and Video Decoder with 3D Comb (rev 04)

The quad tuner needs kernel 4.8 to run. More information here. So fundamentally, I need to compile the latest stable kernel image to get the full use of my system and then pass the PCIE tuner card through to my Media VM.

The Process:

I recommend doing this I have done, inside a reasonably powered Virtual machine. I’ve gone back through things and corrected my instructions when I’ve run into problems. This process will generate a Debian package that you can install on any Debian based OS (such as Ubuntu).

Problems:

  1. Not giving enough RAM, CPU and disk space to the VM to compile (at all) or in a timely manner.
    1. I’ve given my VM 4 cores, 4GB RAM and an ‘external’ hard drive of 30GB to use to compile the kernel.
  2. Utilize all the cores. add the line: CONCURRENCY_LEVEL= 4 to /etc/kernel-pkg.conf to use all 4 cores when compiling (once the package is installed, see below)
  3. Not having some essential packages installed that caused the process to stop. such as libssl-dev.

Using all the cores makes it go much faster!

Steps:

At the command prompt, install all the packages you need to compile the kernel:
:$ sudo apt-get install fakeroot kernel-package gcc build-essential libncurses5-dev qt5-default libssl-dev

Download, to a disk that has ~20GB free, the latest stable kernel version. At the time of writing this was 4.9.9. Extract it and cd into the directory
:$ wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.9.9.tar.xz
:$ tar -xf linux-4.9.9.tar.xz
:$ cd linux.-4.9.9

Assuming you’re running this in a desktop Linux environment, run make xconfig, alternatively, if you’re using a terminal server, make menuconfig will do.

The default settings should do in most instances.

Save and close the configuration. Make the build environment clean, then begin the compile process:
:$ make-kpkg clean
:$ fakeroot make-kpkg –initrd –revision=4.9.9.linux kernel_image kernel_headers

You can save time by compiling a kernel with only the hardware that you have installed. Do this by deselecting them in the xconfig/menuconfig. The downside is that if you add new hardware, you’ll need to recompile the kernel.

For an explanation on the above fakeroot command, please see this Debian manual page. You should now have a custom kernel image compiling.

Once it’s completed, cd to the upper directory, and install the kernel:
:$ cd ..
:$ sudo dpkg -i linux-image-4.9.9_4.9.9.linux_amd64.deb linux-headers-4.9.9.9_4.9.9.9.linux_amd64.deb
:$ sudo shutdown -hr now

After restarting the VM, you can check the currently running version of the kernel by typing at the command prompt:

Additional extra step:

Prove to yourself that you’ve created a usable package by spinning up a shiny new VM, sftp the debian package to it, then install and reboot.

Further reading:

https://www.cyberciti.biz/faq/debian-ubuntu-building-installing-a-custom-linux-kernel/

Rsync logging

The Problem:

My media server runs a rsync job via ssh to another server every night between 2230 and 0600. Every time the scripts runs, it generates a new time-stamped log file. Eventually there are quite a few log files that require manual cleanup. I want to automate this process and cleanup the log file generation.

The log files

The bash script is kept in my home directory (for easy, unscheduled syncs) and is executed using cron.

My crontab file contains:

30 22 * * * /home/wargus/rsync.sh >/dev/null 2>&1
0 6 * * * killall rsync >/dev/null 2>&1

Contents of script:

#!/bin/bash
rsync –bwlimit=450 –delete –protect-args –size-only –copy-dirlinks –log-file=/var/log/rsync/log.`date +”%Y%m%d_%H%M%S”` -avPe ssh “/path/to/files/” “user@host:/path/to/files/”

I won’t go into the details of the rsync command above, suffice to say it works and limits bandwidth to something reasonable for a slow, home ADSL connection. I expect that will change when NBN will finally (if ever) arrive at my off-site location. For this to work, I did have to generate ssh keys to allow the job to execute without user intervention.

The Solution:

 

The addition of two line lines to my rsync.sh above the rsync command script did the trick:

find /var/log/rsync/ -mtime +8 |xargs -I % sh -c ‘rm -f %’;
find /var/log/rsync/log.* |xargs -I % sh -c ‘tar -rf /var/log/rsync/rsync.1.tar %; rm -f %’;

The first line finds anything older than 8 days, then using the list output by find input, deletes all the files. On first run it deleted all my older log files, but going forward, it will remove the archive after 8 days.

The second line fill find every log file in that directory and appends it to an archive, if it exists, or creates the archive first if it does not.

Now, when the script executes, I have no problem knowing what the newest log is and in case I want to check older ones, I can open the archive and have a look.