newspaint

Documenting Problems That Were Difficult To Find The Answer To

Category Archives: SysAdmin

ZFS Grub Issues on Boot

I had a problem when attempting to boot into my ZFS root and landed in initramfs rescue prompt.

Using advice from this article:

Command: zpool import -N
Message: cannot import '': no such pool available
Error: 1

Manually import the root pool at the command prompt and then exit.
Hint: Try:  zpool import -f -R / -N


BusyBox v1.22.1 (Ubuntu 1:1.22.0-15ubuntu1) built-in shell (ash)
Enter 'help' for a list of built-in commands.

(initramfs) zpool import -f -R / -N rpool
(initramfs) exit

Begin: Setting mountpoint=/ on ZFS filesystem  ... done
Begin: Mounting ZFS filesystem  ... done
Command: mount -t zfs -o zfsutil  /root
Message: filesystem '' cannot be mounted, unable to open the dataset
mount: mounting  on /root failed: No such file or directory
Error: 1

Manually mount the root filesystem on /root and then exit.


BusyBox v1.22.1 (Ubuntu 1:1.22.0-15ubuntu1) build-in shell (ash)
Enter 'help' for a list of built-in commands

(initramfs)

To fix this issue I ran:

(initramfs) zpool import -R /root rpool
(initramfs) exit

Unfortunately there is a known bug in Ubuntu 16.04.1 grub-probe command which states “error: unknown filesystem” when running update-grub.

The work-around is to update /etc/default/grub and add:

GRUB_CMDLINE_LINUX_DEFAULT="boot=zfs root=ZFS=rpool/ROOT"

This results in the grub menu specifying the root parameter twice on the kernel boot line in /etc/grub/grub.cfg but the second one takes precedence.

Monitor No Signal on Xubuntu 16.04.1

My Dell server seemed to stop outputting to the monitor on the VGA cable. No signal, the monitor said. It was blank, it was black, it was powered off. I tried unplugging the cable and plugging it back in, no joy.

I tried pressing ctrl-alt-1 to switch to the text console, and the screen came alive, but all I could see was a flashing underline of a cursor in the upper left-hand corner, no login prompt. Same thing for ctrl-alt-2. Tried ctrl-alt-7 to get back to graphics mode and the monitor turned off again.

The following repaired the issue for me without having to reboot, but it did kill my GUI session and all open windows:

sudo /etc/init.d/lightdm restart

My monitor came back alive and I found myself at the GUI XFCE login prompt.

Using wget to Automate Logging Into Websites

The open-source wget tool is useful for automating website access/scraping. In particular because it can store/retrieve cookies from a file.

# create a name for the cookie jar/file
COOKIE_JAR=/tmp/cookies.$$.txt

# save cookies from homepage access
wget --spider --save-cookies $COOKIE_JAR --keep-session-cookies http://www.smrt.com.sg/

# now submit request using saved cookies
wget -O - \
  --load-cookies $COOKIE_JAR \
  --save-cookies $COOKIE_JAR \
  --keep-session-cookies \
  --header "Referer: http://journey.smrt.com.sg/" \
  --post-data='startlat=1.357348601&startlng=103.9884093&endlat=1.276243657&endlng=103.8545958&routeopt=fastest&start_type=mrt&end_type=mrt&mode=TRANSIT&use_lrt=yes' \
  https://connect.smrt.wwprojects.com/smrt/api/journey/

Note that –spider performs a HEAD request and does not download the response. Options useful for debugging and seeing what is sent/received are -d and -S. For cookies the –keep-session-cookies option is essential to save session cookies (with no expiry time set) to the cookie file.

Bash Script to Run Apt-Get Upgrades on All LXC Running Containers

If you have several LXC containers on your system that you want to upgrade in a loop you could use a sensible infrastructure management platform like Ansible.

Here, however, is a simple BASH script for logging into each running LXC host one at a time and letting you answer yes or no to the apt-get upgrade taking place:

#!/bin/bash

# declare an array variable
declare -a LINES

# store each line about running LXC containers into array
LINENUM=0
while IFS= read -r line; do
  echo "  processing LINENUM=$LINENUM, $line"
  LINES[$LINENUM]="$line"
  LINENUM=$((LINENUM + 1))
done <<< "$(sudo lxc-ls -f)"

# iterate through each line in the array
INDEX=0
while [[ $INDEX -lt $LINENUM ]]; do
  # squash up the spaces and delete commas from line
  CLEANLINE=`echo "${LINES[$INDEX]}" |tr -s ' ' |tr -d ,`

  # extract the hostname and ipaddress fields
  HNAME=`echo "$CLEANLINE" |cut '-d ' -f1`
  IPADDR=`echo "$CLEANLINE" |cut '-d ' -f5`

  # ssh into host if a valid IP address is present
  if [ `echo "$IPADDR" |grep -E '^([0-9]+[.]){3}([0-9]+)$'` ]; then
    echo "== $HNAME ($IPADDR) =="
    ssh -t ubuntu@$IPADDR 'echo "== $(hostname) =="; sudo apt-get update; echo "== $(hostname) =="; sudo apt-get upgrade;'
  else
    :
  fi

  INDEX=$((INDEX + 1))
done

This script makes use of BASH arrays. In addition it was discovered that attempting to change variables inside a read loop that was piped was fruitless because the pipe was run inside its own shell and thus the variable changes were lost.

Conditionally adding a directory to PATH if not already in PATH

In BASH it is possible to check that a directory is not already in the PATH environment variable before adding it.

The basic string-in-string search function was adopted from this forum post.

stringContains() { [ -z "${1##*$2*}" ]; }
stringBegins()   { [ -z "${1##$2*}"  ]; }
stringEnds()     { [ -z "${1##*$2}"  ]; }

# call as inPath "$PATH" "/my/new/path"
inPath() {
  if stringBegins   "$1" "$2:";  then return 0; fi
  if stringEnds     "$1" ":$2";  then return 0; fi
  if stringContains "$1" ":$2:"; then return 0; fi
  if [ "$1" == "$2" ];           then return 0; fi
  return 1;
}

If you wanted to, say, add “/home/myuser/bin” if it didn’t already exist, you could add the above functions and the following:

if inPath "$PATH" "/home/myuser/bin"; then
  : # do nothing
else
  PATH="$PATH:/home/myuser/bin"
fi

Windows 10 TCP/Internet Slow With Chrome and OpenWRT Router

So I was having issues getting a Windows 10 laptop running Google Chrome connected via wifi to a router running OpenWRT Chaos Calmer 15.05.1.

The Windows 10 laptop would take a long time to establish a connection and then a long time for any data to transfer at an incredibly slow rate.

At first I thought it was Google Chrome but downloaded Firefox and was still having the same issues.

There are many proposed solutions but the commands that appeared to make a magical difference and instantly speed things up were:

netsh interface tcp show global
netsh interface tcp set global autotuning=disabled

At this stage things did not magically get better.

Then I tried:

netsh interface tcp show heuristics
netsh interface tcp set heuristics enabled

Now the Internet suddenly got quicker.

To undo these changes (if they don’t work for you):

netsh interface tcp set global autotuning=normal
netsh interface tcp set heuristics disabled

Also, because I messed around with the MTU on the WiFi interface I had to run the following to restore things to a relatively normal default:

netsh interface ipv4 set subinterface “WiFi” mtu=1458 store=persistent

Adding Huawei E160E To OpenWRT

I wanted to add a Huawei E160E USB 3G modem to OpenWRT but had some trouble getting it to work.

I used documentation from three places:

In this case I used a latest snapshot from the LEDE project. It turns out the router would simply lose networking, I’d be unable to SSH or access it via the web, after several minutes. Perhaps this was because I was forcing kmod’s with a slightly incompatible kernel. In the end I went back to Chaos Calmer 15.05.1 from OpenWRT which seemed to be more stable for me.

It turned out that I needed to add some more packages, specifically:

  • usbutils – to run “lsusb” to see when my USB devices had been detected
  • kmod-usb-uhci – ultimately I needed a kmod to see the USB controller in order to detect attached devices
  • kmod-usb2 – just in case the UHCI controller module above didn’t work

Note that when adding kmods then opkg might reject it with a LEDE build if package slightly out of sync with the kernel build, in which case use –force-depends (don’t do this, it might result in an unstable router):

opkg install --force-depends kmod-usb-uhci

Now, also ensure that the /etc/modules.d/usb-serial has the following line:

usbserial vendor=0x12d1 product=0x140c maxSize=4096

The vendor and product values are taken from the output of lsusb:

# lsusb
Bus 001 Device 002: ID 12d1:140c Huawei Technologies Co., Ltd. E180v

Once connected the signal strength can be obtained on the command line by running:

# comgt -d /dev/ttyUSB3
SIM ready
Waiting for Registration..(120 sec max)
Registered on Home network: "50502",2
Signal Quality: 13,99

The result can be looked up in the table at this link:

Value RSSI dBm Condition
2 -109 Marginal
3 -107 Marginal
4 -105 Marginal
5 -103 Marginal
6 -101 Marginal
7 -99 Marginal
8 -97 Marginal
9 -95 Marginal
10-93OK
11-91OK
12-89OK
13-87OK
14-85OK
15 -83 Good
16 -81 Good
17 -79 Good
18 -77 Good
19 -75 Good
20 -73 Excellent
21 -71 Excellent
22 -69 Excellent
23 -67 Excellent
24 -65 Excellent
25 -63 Excellent
26 -61 Excellent
27 -59 Excellent
28 -57 Excellent
29 -55 Excellent
30 -53 Excellent

Turning Off DHCP Server on Netgear Wireless Cable Gateway CGD24N

The Netgear Wireless Cable Gateway model CGD24N supplied by Bigpond in Australia can spend a second life as a simple Ethernet switch. However it assigns DHCP addresses out of the box which can really upset a home network if you’re not expecting it.

Your wireless router might be assigning addresses from one range but you keep finding guest devices assigned something from the 192.168.100.0/24 range.

It’s not that straightforward to find the DHCP on/off switch. The steps to find it are thus:

1. Log in to gateway admin interface, select NAT from menu

Select NAT from menu on left-hand side

Select NAT from menu on left-hand side

2. Turn NAT on, click apply

Select NAT on checkbox, click apply

Select NAT on checkbox, click apply

3. Select LAN IP from left hand menu

Select LAN IP from left hand menu

Select LAN IP from left hand menu

4. Select DHCP no radio button, click apply

Select DHCP no radio button, click apply

Select DHCP no radio button, click apply

How To Change TLS Bind Port In Asterisk

Asterisk doesn’t make it necessarily easy to change the port that TLS is bound to.

In sip.conf I’d set a different port (6000):

tlsbindaddr=0.0.0.0:6000

But when I set sip set debug on I would see a message like the following on answer:

<--- Reliably Transmitting (no NAT) to 5.6.7.8:42849 --->
  P/2.0 200 OK
Via: SIP/2.0/TLS 192.168.1.3:42849;branch=z9hG4bKPjBFu7pgHTfOHCaNamaqTKTq3wenp-G.oY;alias;received=5.6.7.8;rport=42849
From: "myext" ;tag=mQqEvydONdU7yOGgCi2.OiDu8lSfXZuK
To: <sip:test@myhost.com>;tag=as378489ee
Call-ID: tAYfXG5BEF9w8lY.ghupqOtwNyV3J18G
CSeq: 12562 INVITE
Server: Asterisk PBX 13.1.0~dfsg-1.1ubuntu4
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
Session-Expires: 1800;refresher=uas
Contact: <sip:test@1.2.3.4:5061;transport=TLS>
Content-Type: application/sdp
Require: timer
Content-Length: 387

The problem was that the Contact: header was advertising the wrong TLS port to the extension which would then attempt to contact the wrong port in response to the answered call (so no audio would start getting received by the extension).

The solution was to add to sip.conf:

externtlsport=6000

As mentioned in another article if the advertised IP address is wrong in this Contact: header then you may also want to specify:

externip=1.2.3.4

Converting XPS to PDF using MuPDF on Ubuntu Linux

I had a recently generated “.xps” file sent to me and needed it in PDF form for convenient viewing. The following took place on Xubuntu Trusty Tahr 14.04 LTS.

The “xpstopdf” tool failed me with a poorly converted document (just a single rectangle, no text).

Then I installed “mupdf”:

~$ sudo apt-get install mupdf
~$ mupdf mydocument.xps

This it rendered to my satisfaction to the screen. Next I wanted a PDF file!

But when I tried using “mudraw“, the associated tool installed with the “mupdf-tools” Ubuntu package, I got the following error:

~$ sudo apt-get install mupdf-tools
~$ mudraw -o /tmp/mydocument.pdf /tmp/mydocument.xps
error: empty page tree, cannot insert page
error: cannot draw '/tmp/mydocument.xps'

In the end I decided to try compiling the latest version available from MuPDF‘s download page (I downloaded “mupdf-1.9a-source.tar.gz” published 2016-04-21).

~$ wget 'http://mupdf.com/downloads/mupdf-1.9a-source.tar.gz'
~$ tar -xvzf mupdf-1.9a-source.tar.gz
~$ cd mupdf-1.9a-source
~$ sudo apt-get install mesa-common-dev libxcursor-dev libxshmfence-dev libxext-dev libxrandr-dev libxinerama-dev
~$ nice make -j 3
~$ ./build/release/mutool draw -o /tmp/mydocument.pdf /tmp/mydocument.xps

This time my PDF was rendered without any errors!