Archive for the ‘Linux’ Category

Update apt public keys in Debian to fix package authentication errors

Thursday, May 29th, 2014

The apt program for Debian uses public and private keys to validate packages downloaded from the repositories. You can learn all about it at https://wiki.debian.org/SecureApt. Public keys are stored in /etc/apt/trusted.gpg. If keys are missing, outdated, corrupted, etc. apt will complain when trying to install packages with an error like “The following signatures couldn’t be verified because the public key is not available”. You can choose to ignore the error. If so, when it reoccurs in the future you will see warnings like “WARNING: The following packages cannot be authenticated!”.

The solution to this problem is to update your public keys for the Debian repositories. These keys are installed via the package debian-archive-keyring. A simple “apt-get install debian-archive-keyring” is probably enough to update the keys are remove the errors/warnings during package installs.

auth.log errors: pam_winbind.so missing

Thursday, May 1st, 2014

I had an authorization log (/var/lib/auth.log) was filling up with errors related to a missing pam_winbind.so library:

May  1 01:25:01 servername CRON[1906]: pam_unix(cron:session): session opened for user root by (uid=0)
May  1 01:25:01 servername CRON[1906]: pam_unix(cron:session): session closed for user root
May  1 01:25:16 servername auth: PAM unable to dlopen(/lib/security/pam_winbind.so): /lib/security/pam_winbind.so: cannot open shared object file: No such file or directory
May  1 01:25:16 servername auth: PAM adding faulty module: /lib/security/pam_winbind.so

…over and over. I tried upgrading winbind to the latest version in the Debian stable repositories. I installed libpam-winbind (2:3.6.6-6+deb7u3 for both). Neither of those actions fixed the problem. The library, pam_winbind.so, was not present in /lib/security.

After reading this thread:

https://lists.debian.org/debian-user/2012/07/msg00620.html

I found that the library was simply in the wrong location. It was the only file under /lib/powerpc-linux-gnu/security/. This machine is a powerpc. Other architectures will have a different architecture name in the /lib directory.

The simple solution was to make a symlink under at /lib/security/pam_winbind.so that points to the existing library at /lib/powerpc-linux-gnu/security/pam_winbind.so:

sudo ln -s /lib/powerpc-linux-gnu/security/pam_winbind.so /lib/security/pam_winbind.so

No more errors in the auth.log.

How libxi broke my system

Thursday, April 3rd, 2014

After some package updates I could no longer log into my Debian/XFCE system. The display manager (gdm3) would start to load but show only a black screen and rotating/spinning cursor. There was no login box – no way for me to get to a desktop. Digging through the logs I saw no errors in Xorg.0.log.  Dmesg and the kernel logs were no help either.  My first clue was found in the /var/log/gdm3/:0-greeter.log.* logs. Each of these logs had just one line:

*** Error in `/usr/bin/gnome-session’: malloc(): memory corruption: 0x000000000207c620 ***

A memtest run showed no errors. Reinstalling gnome-session didn’t fix things. Looking at ~/.xsession-errors I found lots of Gtk and GLib errors among strange things like “Discarding: 6 over 9″ and “** Message: applet now removed from the notification area”. Other errors that might have been related:

polkit-gnome-authentication-agent-1: Fatal IO error 11 (Resource temporarily unavailable) on X server :0.0.
wicd-client.py: Fatal IO error 11 (Resource temporarily unavailable) on X server :0.0.

orage: Fatal IO error 11 (Resource temporarily unavailable) on X server :0.0.
nm-applet: Fatal IO error 11 (Resource temporarily unavailable) on X server :0.0.

In some log (which I’ve forgotten now) I remember finding more “memory corruption” errors but for applications like nm_applet. I tried switching my display manager to lightdm but I got a similar result. Upon boot, I was greeted with a solid black screen. Logs showed that the x-session was started and the greeter as well. In /var/log/lightdm/x-0-greeter.log I found a familiar error:

*** Error in `/usr/sbin/lightdm-gtk-greeter’: malloc(): memory corruption: 0x00007fe0cd2bcd40 ***

I tried purging and resinstalling the x server but of course, it was working fine. From a console I was able to stop the display manager and invoke an x-session manually with “startx”. In the desktop environment, I noticed my wireless was not connecting automatically and the network manager (nm_applet) and orage icons were missing from by status tray.

I’d like to say I used these clues to determine that the problem was isolated to gtk apps (e.g. lightdm, gdm3, nm_applet, etc.) but I never noticed the connection. I was simply fortunate to stumble upon the solution in this post, courtesy of one dE_logics:

http://forums.gentoo.org/viewtopic-p-6873138.html

While the root cause isn’t described in detail, the simple statement at the end of the post provides the solution: “This’s a bug with libxi. Upgrading it…solves the problem.” I gave it a shot. I found libxi6 in synaptic and upgraded it to the highest version available in Debian’s stable repository. After a reboot, my display managers are working perfectly. My libxi6 version is now 2:1.6.1-1+deb7 according to synaptic.

Managing an iPod Shuffle (2nd gen.) in Linux

Monday, March 31st, 2014

I have an old second generation iPod Shuffle (model A1204). When I dug it out of storage it wouldn’t play any songs. I plugged it in to my mobile desktop running Debian and verified the file system could still be read. I transferred all of the existing songs off of the shuffle using Thunar and its handy renaming feature. In order to manage the tracks (i.e. add and remove songs) I needed a piece of Linux software with that capability. Unfortunately, the popular options, Banshee, Rhythmbox, and Amarok would all require that I update a significant amount of my system (mostly gnome and everything that depends on it). The best lite application I could find was gtkPod.

I first tried adding and removing tracks with gtkPod but kept getting errors. The process for adding songs was not straightforward and I couldn’t figure out how to fix those errors. Even when I got songs transferred to the device, it refused to play. It would only flash alternating green and orange indicating it couldn’t find any music. The database file wasn’t being written properly. So, gtkPod alone would not suffice (I may have an unsupported model, I couldn’t find it in the list of devices).

The solution relies on a python script “iPod shuffle database builder” which can be found on sourceforge. I used version 1.0-rc1. My process for adding tunes to the shuffle is now this (starting from scratch):

  1. Use file manager (Thunar) to permanently delete all files from the shuffle.
  2. Open gtkPod and use it to recreate the iPod Shuffle directories only.
  3. Use file manager to copy songs from desktop to Shuffle. Songs are stored in device root or under any arbitrary file hierarchy, just not in the normal /iPod_control/Music directory that iTunes uses.
  4. The python script mentioned above, named “rebuild_db.py” is copied to the root folder of the device.
  5. The python script is executed from the root folder of the device.

That’s it. Once the script rebuilds the Shuffle’s database it can be ejected and used as normal. Easy. Apple take notice.

Batch Table Operations – A QtiPlot plug-in/script

Thursday, January 30th, 2014

I’ve been taking lots of data at work. Each data file collected has to be imported to QtiPlot as a table and then several columns are added to the table and calculated from the imported data. Some days I have over 100 data sets, which means > 100 tables to manipulate. It was becoming impractical to perform all of the necessary table operations by hand. This script was written to automate the table operations I needed.

Batch Table Operations

To use one simply selects the tables to be affected from the list of existing tables. Then one selects and configures the operation to perform. Finally, clicking the “apply” button will perform the operation on the chosen tables.

As of today (1/30/14) the script allows adding and removing columns based on name, changing column types (x, y, z, etc.), and applying formulas to columns. Obviously, alot more could be done, but at the moment, this fits my needs. As I require more features I will add them. If you would like to request a feature add a comment or send me an email and I’ll see what I can do.

Download:

batchTable.zip

Edit 8/5/14:

I just tried to install this in version 0.9.8.9 of QtiPlot running on Windows 7 but was unable to get the script interface to load. The particular version of QtiPlot installed on the target machine came from an unofficial Windows binary (https://www.cells.es/old/Members/cpascual/docs/unofficial-qtiplot-packages-for-windows) that I’ve used before. That QtiPlot package comes with parts of PyQt4 but not the entire library. As such it is necessary to install both python 2.7 and PyQt4 as well. Then, the …/PyQt4/uic module folder has to be copied into the PyQt4 directory of the the QtiPlot installation.

At least, that was the solution in the past. Now this no longer works. The uic module is found but fails to load. I expect it’s because the version of Qt against which QtiPlot was complied and the version for which the uic module were written are now too different. Or it may be that the version of Python is too new (2.7.8). I got this to work in the past with Python 2.7.5. Anyway, under Windows at least, I no longer expect for the batchTable plugin to be usable because it draws its interface using the uic module I can’t get working. Things should still work on Linux installations. The long term solution would be to rewrite the plugin to use a Tkinter interface instead of Qt thereby removing the dependency problem.

Use inxi to identify temperatures reported by lm-sensors/sensors

Wednesday, November 20th, 2013

With lm-sensors installed and properly configured, the output of the sensors command can be confusing in that it doesn’t identify which temperature is the CPU, motherboard, etc. For example, when run on my system, I get four temperatures reported to me:

ecellingsworth@MD1-LMDE ~ $ sensors
k10temp-pci-00c3Adapter:
 PCI adaptertemp1:        +35.5°C  (high = +70.0°C)

w83627dhg-isa-0290Adapter:
ISA adapter
Vcore:        +1.41 V  (min =  +0.00 V, max =  +1.74 V)
in1:          +0.30 V  (min =  +1.86 V, max =  +0.57 V)  ALARM
AVCC:         +2.72 V  (min =  +2.98 V, max =  +3.63 V)  ALARM
+3.3V:        +2.75 V  (min =  +2.98 V, max =  +3.63 V)  ALARM
in4:          +1.39 V  (min =  +1.78 V, max =  +1.26 V)  ALARM
in5:          +1.58 V  (min =  +0.98 V, max =  +1.78 V)
in6:          +1.79 V  (min =  +0.70 V, max =  +0.51 V)  ALARM
3VSB:         +3.02 V  (min =  +2.98 V, max =  +3.63 V)
Vbat:         +3.07 V  (min =  +2.70 V, max =  +3.30 V)
fan1:        3835 RPM  (min = 1308 RPM, div = 8)
fan2:        3183 RPM  (min = 1240 RPM, div = 8)
fan3:        4115 RPM  (min =  774 RPM, div = 8
)fan5:           0 RPM  (min = 2636 RPM, div = 128)  ALARM
temp1:        +32.0°C  (high = +111.0°C, hyst = -29.0°C)  sensor = thermistor
temp2:        +43.0°C  (high = +80.0°C, hyst = +75.0°C)  sensor = thermistor
temp3:        +92.0°C  (high = +114.0°C, hyst = +114.0°C)  sensor = thermistor
cpu0_vid:    +0.375 V
intrusion0:  ALARM

The first module, k10temp, is related to my motherboard, an ASRock 890GM Pro3. The kernel documentation for k10temp says the following:

There is one temperature measurement value, available as temp1_input in sysfs. It is measured in degrees Celsius with a resolution of 1/8th degree. Please note that it is defined as a relative value; to quote the AMD manual: Tctl is the processor temperature control value, used by the platform to control cooling systems. Tctl is a non-physical temperature on an arbitrary scale measured in degrees. It does _not_ represent an actual physical temperature like die or case temperature. Instead, it specifies the processor temperature relative to the point at which the system must supply the maximum cooling for the processor’s specified maximum case temperature and maximum thermal power dissipation.

So, it’s unclear where that temperature is measured or if it is even accurate. I will be ignoring it here. The second entry comes from module w83627dhg. If you google this you will find that this comes from a WinBond chip found on many different motherboards. The number and type of temperature sensors used and their physical locations depends on how the motherboard was designed and will vary between manufacturers and models. So, to identify “temp1″, etc., one can use a script called inxi. This script can be used to list all sorts of information about one’s system. A Debian package is available on the website and the script is pre-installed in many popular distributions (Mint, Crunchbang, Arch, etc.). The full output looks like this:

ecellingsworth@MD1-LMDE ~ $ inxi -F
System:    Host MD1-LMDE Kernel 3.12.0-031200-generic x86_64 (64 bit) Distro Linux Mint Xfce Edition
CPU:       Dual core AMD Athlon II X2 250 (-MCP-) cache 2048 KB flags (lm nx sse sse2 sse3 sse4a svm) bmips 12023.7
            Clock Speeds: (1) 3005.932 MHz (2) 3005.932 MHz
Graphics:  Card ATI RS880 [Radeon HD 4290] X.Org 1.11.4 Res: 1280x1024@60.0hz            GLX Renderer Gallium 0.4 on AMD RS880 GLX Version 2.1 Mesa 7.10.3 Direct Rendering Yes
Audio:     Card-1 ATI SBx00 Azalia (Intel HDA) driver snd_hda_intel BusID: 00:14.2
           Card-2 ATI RS880 Audio Device [Radeon HD 4200] driver snd_hda_intel BusID: 01:05.1
          Sound: Advanced Linux Sound Architecture Version k3.12.0-031200-generic
Network:   Card Realtek RTL8111/8168B PCI Express Gigabit Ethernet controller driver r8169 v: 2.3LK-NAPI at port e800 BusID: 03:00.0
Disks:     HDD Total Size: 570.1GB (-) 1: /dev/sda WDC_WD2500BEVT 250.1GB
            2: /dev/sdb WDC_WD3200BEVT 320.1GB Partition: ID:/ size: 230G used: 97G (45%) fs: ext4
Sensors:   System Temperatures: cpu: 43.0C mobo: 32.0C
            Fan Speeds (in rpm): cpu: 3183 fan-1: 3750 fan-3: 4115 fan-5: 0
Info:      Processes 184 Uptime 1:01 Memory 724.5/3700.9MB Runlevel 2 Client Shell inxi 1.4.23

Issuing the -s option will give just the sensors information. By comparing the values of the temperatures listed here to those listed from sensors it is possible to determine the identity of the sensors read by sensors. Here I’ve identified the sensor “temp1″ reported by sensors is actually my system (motherboard) temp while “temp2″ is somewhere on or near the cpu. The value of “temp3″ suggests that no sensor is actually installed to this input on the WinBond chip so I can ignore it. I’ve seen other configurations that label it as AUX or a case temperature. Regardless, with the identities in hand, it’s possible to setup a proper sensors.conf configuration or to configure the output displayed in panel applets that depend on lm-sensors.

 

panel screenshot showing sensors

 

*Edit 03/13/14: In case you’re wondering, yes, that 3.3 V rail is WAY low. I later discovered this was the cause of frequent freezes on booting and upon plugging in USB devices. Why is the 3.3 V rail low? I have a loose wire on the motherboard power connector. One of the more difficult symptoms I’ve ever had to diagnose for sure.

How to fix slow DNS look-up’s in Firefox running under Linux

Sunday, July 21st, 2013

I’ve had this problem for some time now and chose today to do some research. Luckily, I found a workaround pretty quickly.

I use the Mozilla based browser GNU IceCat which is functionally equivalent to Mozilla Firefox. When a page is requested, the browser displays a small spinning icon in the left corner of the tab. Loading a page involves three basic steps: converting the URL into an IP address, contacting the web server at the IP address, receiving the web page (and other resources). During the first two steps, the icon will be grey and spinning counter-clockwise. The status bar will show messages like “Looking up google.com” and “Waiting for google.com”. Typically, DNS queries (the first step) take on the order of 100 ms to complete. Therefore if you see the first message, you may have the same problem.

The symptom was that IceCat (Firefox) was taking about 3 to 5 seconds to make DNS queries every time I tried to navigate to a new address. The cause of the problem seems to be that my system is making IPv6 DNS queries first by default but these types of requests are being ignored by the DNS resolver which doesn’t support IPv6. My system sends a query and then waits a certain amount of time before giving up and trying an IPv4 query. That time waiting was the delay I was experiencing.

The ideal fix would be to change the way the DNS resolver responds to IPv6 DNS queries. That’s obviously out of my control. A system-wide fix involves setting up your own DNS resolver – a bit more work than I’m interested in. The easy fix was to address the issue for IceCat (Firefox) only which is good enough for me as web-browsing is my primary internet activity.

The fix is to change the value for the key “network.dns.disableIPv6″ from “false” to “true” in IceCat’s (Firefox’s) “about:config” page.

For more information, the issue has been discussed extensively here:

https://bugs.launchpad.net/ubuntu/+source/eglibc/+bug/417757

Automatically mount USB drives in Linux without a GUI

Monday, June 3rd, 2013

The helloNULL web server is a headless system, i.e. it does not run a windowing/desktop environment. One feature that is therefore lacking is the automatic mounting of USB flash drives upon plugging them in. For example, in the Debian/XFCE environment of my mobile desktop, a flash drive will be mounted to /media/label upon plugging in to the port, where ‘label’ is the drive label. This post will show you how to duplicate that functionality on a terminal-only system using udev rules and a simple script.

When a USB drive is plugged in udev handles initiating the device and by using udev rules, it is possible to specify a script to be run whenever this event occurs. In Debian, udev rules are written in text files under /etc/udev/rules.d/. Each file in that directory is parsed by order of filename. Rules that run scripts should begin with a  number in the 80′s. Our script can be called /etc/udev/rules.d/81-custom.rules and should contain the following code:

# Custom udev rules. Note that udev rules are run in order based
# on the filename. Rules in filenames that start with numbers
# are run before this one.
# This rule detects USB drives that are added to the system so
# that they can be mounted automagically by the script.
# It is based off of the replies to a question on superuser.com.
# http://superuser.com/questions/53978/ubuntu-automatically-mount-external-drives-to-media-label-on-boot-without-a-u
ENV{ID_FS_USAGE}=="filesystem", SUBSYSTEMS=="usb", ACTION=="add", RUN+="/root/auto-usb.sh mount %k"
ENV{ID_FS_USAGE}=="filesystem", SUBSYSTEMS=="usb", ACTION=="remove", RUN+="/root/auto-usb.sh cleanup %k"

The first rule will trigger whenever a usb device (SUBSYSTEMS) is added (ACTION) and the device contains a filesystem (ENV{ID_FS_USAGE}). The second rule is similar but triggers upon a ‘remove’ event. In either case, udev will add the script (RUN) specified to the list of scripts to be run for that event. Our script has two functions, mount and cleanup, depending on the event. In the former case, our script will need to know the kernel name of the device (e.g. sda1) to use for the mount command. The auto-log.sh script looks like this:

#!/bin/bash
#
# This script is called by a udev rule whenever a usb drive is
# plugged into the system or removed from the system.
# Usage:
# auto-usb.sh MODE DEVICE
# where MODE is either mount or cleanup
# and DEVICE is the device basename, i.e. /dev/DEVICE

if [ "$1" = "mount" ]; then
    # The ID_FS_LABEL enviroment variable is only available
    # When this script is caleld by udev
    mkdir -p "/media/$ID_FS_LABEL"
    $(mount | grep -q "/media/$ID_FS_LABEL") || mount /dev/$2 "/media/$ID_FS_LABEL"
elif [ "$1" = "cleanup" ]; then
    rmdir "/media/$ID_FS_LABEL"
else
    echo "ERROR: Mode $1 should be 'mount' or 'cleanup'."
fi

This is pretty straight-forward. In the case of mounting a usb drive, the device name is created from the passed argument while the mount point is generated from the disk label taken from an environment variable. The same environment variable is used to remove the mount point when the disk is removed. The proper way to remove the drive is with the eject command, like this:

That’s it! This is perhaps not the most robust solution but should work for most cases. Put the 81-custom.rules file in your /etc/udev/rules.d/ directory and the auto-usb.sh script in your /root directory (or wherever you want). Don’t forget to give the auto-usb.sh script execute permissions.

Edit 06/03/2013: I changed my mount line to give read-write permissions to the plugdev group. The plugdev group is for users who are allowed to mount and unmount removable devices. On my system, all people-users (as opposed to system accounts) are members of the plugdev group. This means that any real person logged in can access the mounted USB drive. The new mount line looks like this:

$(mount | grep -q "/medial/$ID_FS_LABEL") || mount -o gid=plugdev,dmask=007,fmask=117 /dev/$2 "/media/$ID_FS_LABEL"

Edit 12/16/2013: I discovered that my mount command from the 06/03/2013 change only works right for file systems of type vfat and would fail if the usb drive connected was formatted as ext3, for example. The problem is the options specified (gid, etc.) which aren’t valid for ext3 and ext4 filesystems which preserve permissions. The solution I decided on was to specify two different udev rules, one for each type of file system. Different mount options will be set in an environment variable depending on the file system detected. Then in my auto-usb.sh script, this environment variable is put directly into the mount call.

New udev lines:

# the mount options are different depending on the file system type
ENV{ID_FS_USAGE}=="filesystem", ENV{ID_FS_TYPE}=="vfat", SUBSYSTEMS=="usb", ACTION=="add", ENV{MOUNT_OPTIONS}="-o gid=plugdev,dmask=007,fmask=117", RUN+="/root/auto-usb.sh mount %k"
ENV{ID_FS_USAGE}=="filesystem", ENV{ID_FS_TYPE}=="ext?", SUBSYSTEMS=="usb", ACTION=="add", ENV{MOUNT_OPTIONS}="", RUN+="/root/auto-usb.sh mount %k"

New auto-usb.sh lines:

$(mount | grep -q "/media/$ID_FS_LABEL") || mount $MOUNT_OPTIONS /dev/$2 "/media/$ID_FS_LABEL"

Rebuilding a Raid 1 array: Using mdadm to add the new drive back to the array

Friday, May 31st, 2013

Because of frequent disk failures that occur in my Mobile Desktop for reasons I’ve yet to conclusively identify, I decided early on to run two drives in a Raid 1 array. In this way, a single drive failure was easily overcome. A week or so ago one of my current drives started producing read errors and it was removed from the array by mdadm (linux’s multi-disk administrator). Today I’m adding the failed drive back to the array (currently only 1 active drive) and decided to post the commands I use so I can find them easily in the future. For more information on creating, administering, and repairing Raid arrays in linux, I suggest an article on howtoforge.com by Falco Timme.

As of right now, my Raid 1 array (md0) has one connected drive (really partition), /dev/sda1. The drive (partition) that I want to add back to the array is /dev/sdb1. Both drives are from Western Digital but sda is a 250 GB disk while sdb is a 320 GB disk. Because sdb was previously in the array, there’s nothing special that I’ll need to do to use it, but I will be limited to using only 250 GB of the space on that drive. Here is the output from some mdadm commands to clarify the picture:

ecellingsworth@MD1-LMDE ~ $ cat /proc/mdstat
 Personalities : [raid1]
 md0 : active raid1 sda1[3]
 244194841 blocks super 1.2 [2/1] [_U]
 ecellingsworth@MD1-LMDE ~ $ sudo mdadm --detail /dev/md0
 [sudo] password for ecellingsworth:
 /dev/md0:
 Version : 1.2
 Creation Time : Thu Sep 15 10:36:29 2011
 Raid Level : raid1
 Array Size : 244194841 (232.88 GiB 250.06 GB)
 Used Dev Size : 244194841 (232.88 GiB 250.06 GB)
 Raid Devices : 2
 Total Devices : 1
 Persistence : Superblock is persistent
Update Time : Fri May 31 11:41:27 2013
 State : active, degraded
 Active Devices : 1
 Working Devices : 1
 Failed Devices : 0
 Spare Devices : 0
Name : MD1-Ubuntu:0
 UUID : 7d0d271d:04fdd2c1:de65ca3f:4c375489
 Events : 1279820
Number   Major   Minor   RaidDevice State
 0       0        0        0      removed
 3       8        1        1      active sync   /dev/sda1

First I copy the partition table from the good drive to the failed drive. If you use any of these commands yourself, be sure you use the right drive identifier. If you switch sda and sdb, you will destroy the good drive.

ecellingsworth@MD1-LMDE ~ $ sudo sfdisk -d /dev/sda | sudo sfdisk --force /dev/sdb
 Checking that no-one is using this disk right now ...
 OK
Disk /dev/sdb: 38913 cylinders, 255 heads, 63 sectors/track
 Old situation:
 Units = cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0
Device Boot Start     End   #cyls    #blocks   Id  System
 /dev/sdb1   *      0+  30400   30401- 244196001   fd  Linux raid autodetect
 /dev/sdb2          0       -       0          0    0  Empty
 /dev/sdb3          0       -       0          0    0  Empty
 /dev/sdb4          0       -       0          0    0  Empty
 New situation:
 Units = sectors of 512 bytes, counting from 0
Device Boot    Start       End   #sectors  Id  System
 /dev/sdb1   *        63 488392064  488392002  fd  Linux raid autodetect
 /dev/sdb2             0         -          0   0  Empty
 /dev/sdb3             0         -          0   0  Empty
 /dev/sdb4             0         -          0   0  Empty
 Successfully wrote the new partition table
Re-reading the partition table ...
If you created or changed a DOS partition, /dev/foo7, say, then use dd(1)
 to zero the first 512 bytes:  dd if=/dev/zero of=/dev/foo7 bs=512 count=1
 (See fdisk(8).)

Now I remove any traces of the previous Raid information from the failed drive (partition).

ecellingsworth@MD1-LMDE ~ $ sudo mdadm --zero-superblock /dev/sdb1

All that’s left to do is put /dev/sdb1 back into the array.

ecellingsworth@MD1-LMDE ~ $ sudo mdadm -a /dev/md0 /dev/sdb1
 mdadm: added /dev/sdb1

Mdadm will then resync the two drives by copying everything from /dev/sda1 to /dev/sdb1. This process takes three to four hours for my 250 GB drives and will be longer for larger drives. You can monitor the rebuilding process using the following ‘cat /proc/mdstat’. I like to run this command with ‘watch’ every few seconds to see the rebuilding progress in real time.

ecellingsworth@MD1-LMDE ~ $ watch -n 5 'cat /proc/mdstat'
Every 5.0s: cat /proc/mdstat                            Fri May 31 11:51:17 2013
Personalities : [raid1]
 md0 : active raid1 sdb1[2] sda1[3]
 244194841 blocks super 1.2 [2/1] [_U]
 [>....................]  recovery =  2.6% (6465024/244194841) finish=124.7
 min speed=31746K/sec
unused devices: <none>

Don’t trust the estimated time. The rebuilding process will run in the background, but if you are using the PC at the time, the rebuilding has to pause every time you need access to the file system. And, for some reason, rebuilding tends to slow way down near the end.

Edit 12/17/14:

I’ve used the above process to add back to the array a failing drive several times now. However, in my case, since I’m adding back the same drive that was previously in the array, it’s not necessary to copy the the partition table from the good drive nor is it necessary to zero the superblock on the failed drive. Instead, I use one command “mdadm -a” to add the drive back to the array and it rebuilds fine. This has the advantage that it’s much less risky. There’s no chance of destroying the good drive by wiping it’s partition table or superblock. And, I doubt anything would happen if you told mdadm to add a drive that’s already in the array, though I’m not going to test this theory myself.

Update the DNS record for a Namecheap hosted domain automatically

Saturday, May 18th, 2013

I thought I’d share this technique I use to update the dns records for hellonull.com automatically from the web server every 5 minutes. In the event that my ISP issues me a new IP address, my site will hopefully only be down for 5 minutes.

First, you must obtain the dynamic dns (ddns) update password for your domain from Namecheap. At the time of this post, this was done by clicking the ‘Dynamic DNS’ link from the left hand menu, once your domain was already selected. When you enable dynamic DNS, a password will be generated that looks like a long string of random letters and numbers. Copy this down.

Screenshot - 05182013 - 02:59:52 PM

Next, put this password into the updateddns.sh script (below) and edit the wget commands to point to your hosts (@, www, etc.) and domain (hellonull.com). Make this script executable. It’s a good idea to make the owner of this script root and save it in a protected location, like /root because it contains ‘plain-text’ passwords. Anyone who is able to access the script is able to read the password and is therefore able to change your site’s DNS records.

#!/bin/sh
# This script updates the dynamic DNS record for several domains
# hosted on this server. It is run automatically by cron. The crontab
# file that makes this happen is stored in /etc/cron.d/ddns.
# While this script can execute as any user, it should be owned by
# root because it contains 'plain text' passwords.
# Each host (as in host.hellonull.com) must get updated individually.
# In addition, all subdomain records must be updated individually.

logFile="/var/log/updateNamecheapDDNS.log"

# this is the password as generated by namecheap
pass="You'll have to look at the original or get new ones"

# add a wget line for each host and subdomain
wget -a $logFile -O /dev/null "https://dynamicdns.park-your-domain.com/update?host=www&domain=hellonull.com&password=$pass"
wget -a $logFile -O /dev/null "https://dynamicdns.park-your-domain.com/update?host=@&domain=hellonull.com&password=$pass"
wget -a $logFile -O /dev/null "https://dynamicdns.park-your-domain.com/update?host=teachingwiki&domain=hellonull.com&password=$pass"

If you run the updateddns.sh script it should update your DNS records. To automate the process simply schedule the script using cron. I added a crontab file called ddns in /etc/cron.d which executes the script every 5 minutes.

# use this file to schedule ddns updates
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# every 5 minutes
*/5 * * * * root /root/updateddns.sh >/dev/null 2>&1