Showing posts with label linux. Show all posts
Showing posts with label linux. Show all posts

Sunday, March 4, 2018

brittleR

Apparently the current crop of R developers was never told the standard policy of never break backwards compatibility on a minor version increment.

Put simply, packages available for 3.3 do not work in 3.4. I'm sure there is some perfectly justifiable reason for making the release 3.4 instead of 4.0, while breaking all existing packages (until manually updated by the maintainers), but guess what: it's bollocks. 

Anyways, to forestall a long rant about disregarding long-held policy due to historical ignorance (*cough* Uber), here is how to downgrade 3.4 to 3.3 on Debian:

1. add stretch to /etc/apt/sources.list
        deb http://ftp.us.debian.org/debian/ stretch main non-free contrib
        deb-src http://ftp.us.debian.org/debian/ stretch main non-free contrib
 2.  apt-get update
     apt-cache showpkg r-base should show version 3.3.3-1
 3. apt-get remove r-base r-base-core r-base-html r-base-dev
 4. go to https://packages.debian.org/stretch/r-base-html to get version number (3.3.3-1)
     also https://packages.debian.org/stretch/r-recommended for version numbers for dependencies
  5. now do the big install:
    sudo apt-get install r-base=3.3.3-1 r-base-core=3.3.3-1 \
         r-recommended=3.3.3-1 r-base-dev=3.3.3-1 r-base-html=3.3.3-1 \
         r-cran-boot=1.3-18-2 r-cran-class=7.3-14-1 r-cran-cluster=2.0.5-1 \
         r-cran-codetools=0.2-15-1 r-cran-foreign=0.8.67-1 \
         r-cran-kernsmooth=2.23-15-2 r-cran-lattice=0.20-34-1 \
         r-cran-mass=7.3-45-1 r-cran-matrix=1.2-7.1-1 r-cran-mgcv=1.8-16-1 \
         r-cran-nlme=3.1.129-1 r-cran-nnet=7.3-12-1 r-cran-rpart=4.1-10-2 \
         r-cran-spatial=7.3-11-1 r-cran-survival=2.40-1-1
  6. prevent R from updating again, because its developers obviously cannot be trusted:
         sudo sudo apt-mark hold r-base r-base-core
  7. comment out the lines in sources.list for step 1

In related news, here is how to downgrade an R package to a specific version number. The example uninstalls the package 'BH' and replaces it with version 1.62.0. As with most package management in R these days, you need the devtools package installed.

remove.packages('BH')
library(devtools)
install_version('BH', '1.62.0')

Monday, March 7, 2016

RIP inittab

Your getty configs are all in /lib/systemd/system/getty@.service now.

[Service]
# the VT is cleared by TTYVTDisallocate
ExecStart=-/sbin/agetty --noclear %I $TERM                                      
Type=idle
Restart=always
RestartSec=0
UtmpIdentifier=%I
TTYPath=/dev/%I
TTYReset=yes
TTYVHangup=yes
TTYVTDisallocate=yes
KillMode=process
IgnoreSIGPIPE=no
SendSIGHUP=yes

Control via /etc/systemd/logind.conf -- see man 5 logind.conf for more info.

Sunday, March 6, 2016

xdg-open arcanery

In the midst of playing with tycat and terminology on a virtual console*, it became apparent that xdg-open wasn't doing its job in regards to opening PDF documents.

  bash# xdg-open /tmp/dw.pdf 
  Filename "file:///tmp/dw.pdf" does not exist or is not a regular file

A simple check of the default handler shows that everything is fine:
  bash# xdg-mime query default application/pdf
  evince.desktop
..but for fun, let's try to change it and see what happens.
  bash# xdg-mime default apvlv.desktop application/pdf
  bash# xdg-open /tmp/dw.pdf 
  Filename "file:///tmp/dw.pdf" does not exist or is not a regular file
Nothing.

Grepping for the error in /usr/bin/xdg-open comes up empty. It's odd that two unrelated programs (evince and apvlv) would have the incorrect error message (the file does exist and is regular), or that they would both fail to handle file:// URIs. How does xdg-open actually route these requests?

Turns out it depends on your window manager. If you are running Enlightenment, xdg-open performs the following:

open_enlightenment()
{
    enlightenment_open "$1"

    if [ $? -eq 0 ]; then
        exit_success
    else
        exit_failure_operation_failed
    fi
}

Replacing enlightenment_open "$1" with open_generic "$1" works. Can we invoke open_generic when enlightenment_open fails? Turns out we can't, because enlightenment_open returns 0 (success) even when the file isn't opened.

Fixing enlightenment_open might do the trick. The relevant code (enlightenment.git/ src/bin/e_open.c) is here:

        char **itr;
        int ret = EXIT_SUCCESS;

        for (itr = cmds; *itr != NULL; itr++)
          {
             /* Question: should we execute them in parallel? */
             int r = system(*itr);
             if (r < 0)
               fprintf(stderr, "ERROR: %s executing %s\n", strerror(errno),
                       *itr);
             free(*itr);
             if (r > 0) /* Question: should we stop the loop on first faiure? */
               ret = r;
          }
        free(cmds);

        return ret;

It turns out that the status of what enlightenment_open is calling is ignored. But what is it calling? Adding the line fprintf(stderr, "Trying %s\n", *itr); after the system() call uncovers what is actually happening:

bash# make src/bin/enlightenment_open
  CC       src/bin/src_bin_enlightenment_open-e_open.o
  CCLD     src/bin/enlightenment_open
bash# src/bin/enlightenment_open /tmp/dw.pdf 
Filename "file:///tmp/dw.pdf" does not exist or is not a regular file
TRYING evince-previewer 'file:///tmp/dw.pdf

Where the hell did evince-previewer come from? To make a long story short, xdg-open (and enlightenment_open, and all other *_open tools) uses /usr/bin/mimeopen as a backend. 

This utility operates on files, not mime-types:

bash# mimeopen -a /tmp/dw.pdf 
Please choose an application

1) Print Preview  (evince-previewer)
2) Document Viewer  (evince)
3) vprerex  (vprerex)
4) GNU Image Manipulation Program  (gimp)

use application #
Cancelled

OK, so that is where evince-previewer is coming from. A quick test shows that the actual bug is caused by evince-previewer not understanding file URIs:

bash# evince-previewer file:///tmp/dw.pdf
Filename "file:///tmp/dw.pdf" does not exist or is not a regular file
bash# evince file:///tmp/dw.pdf
(evince:21480): Gtk-WARNING **: gtk_widget_size_allocate(): attempt to allocate widget with width -82 and height 15

That Gtk warning accompanies evince loading and displaying the file just fine. 

Changing the handler for PDFs using mimeopen turns out to work just fine:

bash# mimeopen -d /tmp/dw.pdf 
Please choose a default application for files of type application/pdf

1) Print Preview  (evince-previewer)
2) Document Viewer  (evince)
3) vprerex  (vprerex)
4) GNU Image Manipulation Program  (gimp)
5) Other...

use application #2
Opening "/tmp/dw.pdf" with Document Viewer  (application/pdf)

(evince:21510): Gtk-WARNING **: gtk_widget_size_allocate(): attempt to allocate widget with width -82 and height 15
bash#  xdg-open /tmp/dw.pdf 

(evince:21550): Gtk-WARNING **: gtk_widget_size_allocate(): attempt to allocate widget with width -82 and height 15
xdg-open /tmp/a.pdf

(evince:21602): Gtk-WARNING **: gtk_widget_size_allocate(): attempt to allocate widget with width -82 and height 1

Of course, that doesn't mean that evince-previewer is the only bug. Since evince-previewer returns 1 (failure), enlightenment_open should be returning 1 instead of 0:

        int ret = EXIT_FAILURE;

        for (itr = cmds; *itr != NULL; itr++)
          {
             int r = system(*itr);
             if (r < 0)
               fprintf(stderr, "ERROR: %s executing %s\n", strerror(errno),
                       *itr);
             free(*itr);
             ret =  r;
          }

...and xdg-open should check the return value and fallback to open_generic:

    enlightenment_open "$1"

    if [ $? -eq 0 ]; then
        exit_success
    else
        open_generic "$1"
        if [ $? -eq 0 ]; then
            exit_success
        else 
            exit_failure_operation_failed
        fi
    fi

Let's not even get started on why xdg-open doesn't propagate changes back to mimeopen. Wait, why doesn't it?

UPDATE: looks like there's something deeply wrong with with the xdg-* utilities:

bash# xdg-settings get default-web-browser
xdg-settings: unknown desktop environment

The problem here is that xdg-settings performs its own check for desktop environment (modularity, people!) and, of course, implements this poorly. If the desktop environment is detected (as is Enlightenment), but is not KDE|Gnome|XFCE|MATE,  it returns "unknown desktop environment". If the environment is not detected, a generic handler is called. There are some very confused people working on this software.

The fix is to modify xdg-settings, changing the default case statement
*)
    exit_failure_operation_impossible "unknown desktop environment"
    ;;

to

*)
    dispatch_specific generic "$@"
    ;;

* For those interested: install tslib and rebuild EFL from source, then run the following on a virtual terminal:
ELM_ENGINE=fb /usr/local/bin/terminology -f=nexus/20
Yes, the -b option for a backgroud image will work, as will tytls, tyop, and tycat.

Thursday, February 25, 2016

Dispatches from the X1 front

The first-gen Thinkpad X1: possibly the best laptop I've ever owned. Lasted three years, compared to the usual 12-18 months. It still runs, but the battery is down to about 40 minutes, and the (second!) keyboard is starting to lose keys.

The third-gen Thinkpad X1 Carbon: a little annoying at first: no SD slot, no h/w kill switch for the wireless, no spill-through keyboard (wtf guys, that was brilliant!). About 6 months in, the video glitches started: there is a short which corrupts video memory while using wifi. The fix, of course, is a replacement system board, which is great if you have a spare third-gen X1 Thinkpad Carbon lying around and can just up and change workstations like it's no big. Workaround: rfkill block wifi, or just get used to the strobe effect.

The latest: Thinkpad X1 Yoga. And let's just put it out there: this doesn't work out of the box like the previous two did. Lenovo and Intel seem to have backed off of their Linux commitment, though that's probably half their users these days (errybody else on the mobile, right?)

Here's the rundown on getting the X1 Yoga up and running with a Linux install.


Basic Linux

Debian 8.3.0 AMD64 netinst ISO if you were wise enough to buy the OneLink+ RJ45 ethernet adapter; otherwise, use the regular (non-netinst) ISO.

Use unetbootin to make a USB flash drive image for this. Go into the BIOS on the X1 Yoga, enable F12 for boot device selection (just because), turn off secure boot, maybe enable diagnostic boot as well. No need to allow legacy BIOS installs, Debian will work just fine with uEFI (unlike FreeBSD where you need to use the 10.3-Beta or 11 memstick). Go through the install like you usually do. Your ethernet (if you have it) will be detected (again, unlike in FreeBSD).

Sound, APCI (suspend, hibernate, and battery status) and video card should all be working out of the box.


Wireless

Upgrade your kernel to 4.4.1 from the ubuntu PPA:
  http://kernel.ubuntu.com/~kernel-ppa/mainline/v4.4.1-wily/
This is per notes about a typo in the iwlwifi driver at
 https://bbs.archlinux.org/viewtopic.php?id=206831
Looking at the kernel source, 4.2.7 has the fix as well, but might as well go with the latest stable release of the kernel if we're upgrading.

You'll also need to upgrade the firmware, or your Wifi will not be recognized. There is a debian package in backports for this:
 https://packages.debian.org/jessie-backports/firmware-iwlwifi


Skylake P-State Fix

If you rebooted excitedly into your new kernel without following the rest of these steps, you're likely looking at a blank screen. That's because of a skylake p-state bug reported here:
 https://www.reddit.com/r/thinkpad/comments/410haw/yoga_260_wont_boot_ubuntu_with_kernel_4244_but/

This is because the kernel needs a command line parameter to not totally crap itself when it encounters Skylake's poor implementation of pstate.

To fix this, change the cmdline in /etc/default/grub to:
  GRUB_CMDLINE_LINUX_DEFAULT='intel_pstate=no_hwp quiet'

Don't forget to run update-grub when you're done.

Hopefully this will go away in 4.5; according to a commenter, that's what the kernel guys are trying for.


i915 Xorg Video fix

Of course, the fancy new kernel hosed your X windows, didn't it?

Not sure why there's such a tight coupling there, but never mind. This one's an easy fix, per http://comments.gmane.org/gmane.linux.debian.user/508779 . Download (and install) a new version of the xserver-xorg-video-intel package from backports:

https://packages.debian.org/jessie-backports/xserver-xorg-video-intel


Touchscreen

The touchscreen is recognized and configurable in X Windows, but does not respond to touch or stylus events. A bug report is open at the linuxwacom project.

The touchscreen (+ stylus) works out of the box once the firmware update is installed (via windows, sadly,so don't pave the drive until you've updated firmware). Make sure to perform a hard reset (60 sec with a paperclip in the bottom of the laptop) after the upgrade.

To disable the touchpad when entering tablet mode (note: the keyboard will be disabled by  the BIOS), create the file /etc/acpi/events/thinkpad-tablet-touchpad-off with the following contents:

event=ibm/hotkey LEN0068:00 00000080 000060f0
action=/usr/local/bin/touchpad_disable.sh


You can verify the hotkey parameter by running acpi_listen and folding the display back to tablet position.

Next, create the file /usr/local/bin/touchpad_disable.sh with the following contents:

export XAUTHORITY=`ls -1 /home/*/.Xauthority | head -n 1`
export DISPLAY=":`ls -1 /tmp/.X11-unix/ | sed -e s/^X//g | head -n 1`"
tp_dev='SynPS/2 Synaptics TouchPad'
state=`xinput list-props "$tp_dev" | grep 'Device Enabled' | cut -d':' -f2 | tr -d '\t '`
if [ $state -eq 1 ]
then
  xinput disable "$tp_dev"
else
  xinput enable "$tp_dev"
fi

You will need to give root access to the X server session for this. The quickhack version is to add xhost + & to ~/.xsessionrc, but it's better to do something like +root@localhost..


The Acer BMA150 accelerometer is detected as a joystick device, so various /sys/bus/iio -based screen orientation scripts like thinkpad-yoga-scripts won't work. An alternative is to define a Window Manager screen edge event that invokes a script to cycle through screen orientation rotations:

#!/bin/sh
# script to rotate screen (counter-clockwise) based on current orientation

conn_line=`xrandr | grep ' connected'`
dev=`echo "$conn_line" | cut -d' ' -f 1`
orient=`echo "$conn_line" | cut -d' ' -f 5`

case $orient in
  '(normal' )
    xrandr --output $dev --rotate left
    ;;
  'left' )
    xrandr --output $dev --rotate inverted
    ;;
  'inverted' )
    xrandr --output $dev --rotate right
    ;;
  'right' )
    xrandr --output $dev --rotate normal
    ;;
  * )
    xrandr --output $dev --rotate normal
    ;;
esac

Some other approaches are discussed in this Manjaro Linux post.


Fingerprint reader

Is not supported by fprint. USB ID: 138a:0090 (Validity, no product string in usb-devices).


Camera

Works out of the box. Driver is uvcvideo. VLC mirrors it without any problems:

vlc v4l:// :v4l-dev="/dev/video0" :v4l-adev="/dev/audio"


FreeBSD

You need to use a 10.3 (BETA3 or more current) UEFI memstick image to do the install with, of course, the OneLink ethernet adapter connected. Presently, no support for wifi or Xorg support (perhaps in 11?). To boot, add an entry in /etc/grub.d/40_custom as follows:

menuentry "FreeBSD 10.3-BETA3" {
  insmod chain
  set root=(hd0,gpt10)
  chainloader (hd0,gpt10)/boot/loader.efi
}

...replacing gpt10 with the partition number where FreeBSD was installed. This starts counting from 1, so the example here is the tenth partition on the first hard drive (hd0).

Note that for update-grub to correctly recognize the FreeBSD partition (and therefore find loader.efi), you should provide an fstab entry to specify the UFS partition type:

/dev/sda10      /home/bsd       ufs    ro,noauto,ufstype=ufs2       0       0

Monday, June 15, 2015

What decade is it, again?

bash$  find /opt/android/sdk/ -exec file \{\} \; | cut -f 2 -d ':' | grep ELF |cut -b1-15 | sort | uniq
 ELF 32-bit LSB
 ELF 64-bit LSB

bash$ find /opt/processing/ -exec file \{\} \; | cut -f 2 -d ':' | grep ELF | cut -b1-15 | sort | uniq
 ELF 32-bit LSB
 ELF 64-bit LSB  

Processing only has a couple of these, but it's enough:

/opt/processing/modes/java/application/launch4j/bin/windres: ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared li
bs)
/opt/processing/modes/java/application/launch4j/bin/ld: ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs)
/opt/processing/modes/java/libraries/serial/library/linux32/libjSSC-2.8.so: ELF 32-bit LSB  shared object, Intel 80386, version 1 (SYSV), dynamically linked

Android sins heavily:

/opt/android/sdk/tools/emulator: ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
/opt/android/sdk/tools/lib/gles_mesa/libGL.so.1: ELF 32-bit LSB  shared object,Intel 80386, version 1 (SYSV), dynamically linked, not stripped
/opt/android/sdk/tools/lib/gles_mesa/libGL.so: ELF 32-bit LSB  shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped
/opt/android/sdk/tools/lib/gles_mesa/libosmesa.so: ELF 32-bit LSB  shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped
/opt/android/sdk/tools/lib/monitor-x86/plugins/org.eclipse.equinox.launcher.gtk.linux.x86_1.1.200.v20120913-144807/eclipse_1502.so: ELF 32-bit LSB  shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped
/opt/android/sdk/tools/lib/monitor-x86/libcairo-swt.so: ELF 32-bit LSB  shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped
/opt/android/sdk/tools/lib/monitor-x86/monitor: ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux2.2.5, not stripped
...
bash$ find /opt/android/sdk -exec file \{\} \; | grep 'ELF 32-bit' | wc -l
81


Guys, it's been TEN YEARS since 64-bit chips started shipping by default on new hardware. Stop compiling to goddamn 32-bit.

Tuesday, October 16, 2012

Static DNS servers with Connman

For some reason, Connman uses dnsmasq for name resolution, resulting in extremely slow hostname lookups. This can be verified using the cmcc tool:

bash$ for i in `cmcc services | grep -e '^*' | awk '{ print $2 }'`; do cmcc show $i | grep Nameservers; done
Nameservers = [ 127.0.0.1 ]

Nameservers.Configuration = [  ]


The quick fix is to use cmcc to manually specify name servers:

bash$ for i in `cmcc services | grep -e '^*' | awk '{ print $2 }'`; do cmcc edit $i nameservers 8.8.8.8 8.8.4.4; done

unknown property: 8.8.8.8
bash$ for i in `cmcc services | grep -e '^*' | awk '{ print $2 }'`; do cmcc show $i | grep Nameservers; done
Nameservers = [ 8.8.8.8 8.8.4.4 ]
Nameservers.Configuration = [ 8.8.8.8 8.8.4.4 ]


Alternatively, the default DNS server supplied by the router can be used by specifying auto as the nameserver:

bash$ for i in `cmcc services | grep -e '^*' | awk '{ print $2 }'`; do cmcc edit $i nameservers auto; done
unknown property: auto
bash$ for i in `cmcc services | grep -e '^*' | awk '{ print $2 }'`; do cmcc show $i | grep Nameservers; done
Nameservers = [ 192.168.0.1 ]
Nameservers.Configuration = [  ]

Note that the cmcc tool has a bug in its command-line parsing ("argv" is passed to service.SetProperty in cmd_edit_nameservers, but the nameserver arguments are not popped from argv and thus are treated as additional properties to be parsed once cmd_edit_nameservers returns) -- but as cmcc show proves, the changes have been made.

Thursday, October 4, 2012

"losetup -e blowfish" broken across distributions

Apparently this has been an issue for a long time:

  1. create an encrypted disk image with "losetup -e blowfish"
  2. ...years pass...
  3. move the encrypted disk image to a machine with a
      different distribution of Linux
     -or-
     upgrade the installed version of Linux
  4. discover that all access to the encrypted data is lost!

This apparently has to do the hash being used in blowfish changing, usually for security reasons and usually without a backwards-compatibility option, as documented in loop-AES.README.

This is very bad news if you've been backing up your encrypted disk image. Better stick with a losetup-mount-tar-pgp backup procedure instead:

# to backup:
bash$ cd /media/encrypted_fs
bash$ tar cf - * | gpg --output /home/backup/encrypted_fs.gpg -r you@email.address -e - 
# to restore:
bash$ cd /media/encrypted_fs
bash$ gpg -d /home/backup/encrypted_fs.gp | tar xf -

Tuesday, September 18, 2012

Returning to Pre-Framebuffer console fonts

At some point in time, the various Linuxes out there decided that the large, blocky, easy-to-read console (as in Virtual Console, not Terminal Emulator) fonts should be replaced with tiny, hard-to-read fonts that make it a chore to edit standard 80-column scripts/source/config files in vim.

Experimenting with various grub and kernel options to change the resolution, fix i915.modeset, and so forth make for a lot of rebooting to get things just right.

Enter the Debian console-setup package. This provides a wizard that ultimately calls setfont and stty to configure the Linux Virtual Consoles.

The dialog-based wizard is invoked via sudo dpkg-reconfigure console-setup .  Each screen is simple enough to navigate on its own; however, the following selections will configure the consoles to display an old, 90s-to-early-oughts style of font:

1. UTF-8 [default, just press ENTER]
2. Combined - Latin; Slavic Cyrillic; Greek [default]
3. VGA
4. 28x16

The result should produce a nice 80 column x 25 row vim display that is visible from halfway across the room (and to old geezers a few inches away). Chuck it on a Macbook air to really get some double-takes from passers by.

Sunday, September 25, 2011

Determining installed version of Ubuntu

Neither uname nor motd are of much use in determining the version of Ubuntu installed on a third-party system, and searching launchpad.net for version details of key packages in dpkg is annoying.

Fortunately there is a utility called lsb_release that provides this information:


bash$ lsb_release -si
Ubuntu
bash$ lsb_release -sr
11.04
bash$ lsb_release -sc
natty

Complete all the way down to the silly nickname for each release.

Since this is an LSB utility, it's probably been in place for some time, silently waiting to provide more detail than uname. Seriously, would a mention in the SEE ALSO section of the uname manpage be *so* hard to add?

Wednesday, September 21, 2011

First impressions, redux

The R500 bit the dust over a year and a half ago. Most PC manufacturers were busy trying to crank out netbooks or a Macbook Air ripoff at the time, so there was no suitable replacement -- had to limp along with a Macbook Pro (ugh!) running Ubuntu until spring of this year.

What replaced the R500? A Thinkpad X1. It weighs twice as much, has no transreflective screen, and is a bit bulkier, but it is paradise after using that Macbook Pro for a year. Dedicated pageup/down keys! Home and End keys! A Delete key! THREE mouse buttons! A hardware kill switch for wifi and bluetooth! A freaken eSATA connector!

But why no grumpy install post detailing how to get Linux speaking to all the hardware? Because everything just works! Even the volume control buttons and the fingerprint reader. No joke. You can thank IBM's interest in Linux for that.

On top of the compatibility, it's a nice looking machine, powerful (64-bit debian runs great on a dual-core i5 with 8 GB of RAM), and tough -- GorillaGlass over the display, MILSPEC (assuming 810) shock and spill resistance (including a keyboard that drains *through* to the bottom of the laptop), the works.

The one caveat: it's best to use non-standard video drivers, as the standard debian/ubuntu Intel video driver became a bit crashy. Easily fixed, though, by adding the xorg-edgers PPA.

Sunday, September 18, 2011

.vimrc and UTF-8

Quick .vimrc config to display UTF-8 characters correctly:

" support UTF-8 automatically when not on console
if  has('gui_running') && has('multi_byte')
        set encoding=utf-8
        set fileencoding=utf-8
        set fileencodings=utf-8
endif

Note that the gui_running requirement ensures that this will be used by gvim and by vim run from a terminal emulator (such as urxvt or mlterm), not by vim running from a virtual terminal or console.

Monday, August 8, 2011

knotify4 uses 100% CPU

This is true, and has been for awhile. It tends to occur when a laptop is suspended while online, then resumed while offline. A nice side effect is that battery life gets reduced by about 75% while offline, which is generally when one wants the longest battery life.

There are plenty of bug reports open on this, but it's pretty clear that the KDE/Kubuntu guys either have no clue how to fix this, or cannot be bothered.

Since knotify4 isn't really all that useful (especially when using E17 for a WM), there is a brutal hack that will effectively silence it:



sudo mv /usr/bin/knotify4  /usr/bin/knotify4.orig
sudo cp /bin/true /usr/bin/knotify4

Needless to say, the original file should be restored before doing an upgrade.

Disabling startup (init.d) services in Ubuntu

Ubuntu never has made obvious what the "Ubuntu way" of removing services from System-V run levels is. The GUI tools in GNOME and KDE are incomplete, and a quick investigation of the run level directories shows that they are filled automatically -- so that symlinks added and removed manually might, in the future, get ignored.

Fortunately, the README in /etc/init.d ends with the following advice:


Use the update-rc.d command to create symbolic links in the /etc/rc?.d
as appropriate. See that man page for more details.

The man page lists the following forms for invoking upgrade-rc.d:                                                        


      update-rc.d [-n] [-f] B name  remove


       update-rc.d [-n] B name  defaults [NN | SS KK]


       update-rc.d  [-n]  name  start|stop  R  NN runlevel  [ runlevel ]... 


       update-rc.d [-n] B name  disable|enable [ S|2|3|4|5 ]

The following command will remove the service collectd from all run levels:


bash$ sudo update-rc.d collectd disable
update-rc.d: warning: collectd start runlevel arguments (none) do not match LSB Default-Start values (2 3 4 5)
update-rc.d: warning: collectd stop runlevel arguments (none) do not match LSB Default-Stop values (0 1 6)
 Disabling system startup links for /etc/init.d/collectd ...
 Removing any system startup links for /etc/init.d/collectd ...
   /etc/rc0.d/K95collectd
   /etc/rc1.d/K95collectd
   /etc/rc2.d/S95collectd
   /etc/rc3.d/S95collectd
   /etc/rc4.d/S95collectd
   /etc/rc5.d/S95collectd
   /etc/rc6.d/K95collectd
 Adding system startup for /etc/init.d/collectd ...
   /etc/rc0.d/K95collectd -> ../init.d/collectd
   /etc/rc1.d/K95collectd -> ../init.d/collectd
   /etc/rc6.d/K95collectd -> ../init.d/collectd
   /etc/rc2.d/K05collectd -> ../init.d/collectd
   /etc/rc3.d/K05collectd -> ../init.d/collectd
   /etc/rc4.d/K05collectd -> ../init.d/collectd
   /etc/rc5.d/K05collectd -> ../init.d/collectd


The command to remove a service from a specific runlevel should be the following:


sudo update-rc.d BASENAME disable `runlevel | cut -d ' ' -f 2`

...however a quick experiment shows that the runlevel argument is ignored:


bash$ sudo update-rc.d collectd disable 2

sudo update-rc.d collectd disable 2
update-rc.d: warning: collectd start runlevel arguments (none) do not match LSB Default-Start values (2 3 4 5)
update-rc.d: warning: collectd stop runlevel arguments (none) do not match LSB Default-Stop values (0 1 6)
 Disabling system startup links for /etc/init.d/collectd ...
 Removing any system startup links for /etc/init.d/collectd ...
   /etc/rc0.d/K95collectd
   /etc/rc1.d/K95collectd
   /etc/rc2.d/S95collectd
   /etc/rc3.d/S95collectd
   /etc/rc4.d/S95collectd
   /etc/rc5.d/S95collectd
   /etc/rc6.d/K95collectd
 Adding system startup for /etc/init.d/collectd ...
   /etc/rc0.d/K95collectd -> ../init.d/collectd
   /etc/rc1.d/K95collectd -> ../init.d/collectd
   /etc/rc6.d/K95collectd -> ../init.d/collectd
   /etc/rc2.d/K05collectd -> ../init.d/collectd
   /etc/rc3.d/K05collectd -> ../init.d/collectd
   /etc/rc4.d/K05collectd -> ../init.d/collectd

Sunday, August 7, 2011

perf-backed disassembly

Since 2.6.31 or thereabouts, the Linux kernel has come with a built-in performance counter known as perf.

The common form of perf is well-known to be useful in gathering performance statistics on a running program:


bash$ perf stat -cv ./a.out 


cache-misses: 11313 2020574449 2020574449
cache-references: 62031796 2020574449 2020574449
branch-misses: 17909 2020574449 2020574449
branches: 606684832 2020574449 2020574449
instructions: 6324531571 2020574449 2020574449
cycles: 6408533747 2020574449 2020574449
page-faults: 304 2019963367 2019963367
CPU-migrations: 7 2019963367 2019963367
context-switches: 205 2019963367 2019963367
task-clock-msecs: 2019963367 2019963367 2019963367


 Performance counter stats for './a.out':

             11313 cache-misses             #      0.006 M/sec
          62031796 cache-references         #     30.709 M/sec
             17909 branch-misses            #      0.003 %    
         606684832 branches                 #    300.344 M/sec
        6324531571 instructions             #      0.987 IPC  
        6408533747 cycles                   #   3172.599 M/sec
               304 page-faults              #      0.000 M/sec
                 7 CPU-migrations           #      0.000 M/sec
               205 context-switches         #      0.000 M/sec
       2019.963367 task-clock-msecs         #      0.996 CPUs 


        2.027948307  seconds time elapsed

The  events to be recorded can be specified with the -e option in order to refine the output:

bash$ perf stat -e cpu-clock -e instructi
ons  

 Performance counter stats for './a.out':

       2026.748812 cpu-clock-msecs         
        6324293589 instructions             #      0.000 IPC  

        2.032519896  seconds time elapsed

A list of available events can be obtained via perf list:

bash$ perf list | head
List of pre-defined events (to be used in -e):

  cpu-cycles OR cycles                       [Hardware event]
  instructions                               [Hardware event]
  cache-references                           [Hardware event]
  cache-misses                               [Hardware event]
  branch-instructions OR branches            [Hardware event]
  branch-misses                              [Hardware event]
  bus-cycles                                 [Hardware event]


The perf toolchain also includes the utility perf top, which can be used to monitor a single process, or which can be used to monitor the kernel:

bash$ sudo perf top 2>/dev/null
-------------------------------------------------------------------------------
   PerfTop:       0 irqs/sec  kernel:-nan%  exact: -nan% [1000Hz cycles],  (all, 4 CPUs)
-------------------------------------------------------------------------------

             samples  pcnt function               DSO
             _______ _____ ______________________ __________________

               77.00 39.3% intel_idle             [kernel.kallsyms] 
               13.00  6.6% __pthread_mutex_unlock libpthread-2.13.so
               13.00  6.6% pthread_mutex_lock     libpthread-2.13.so
               12.00  6.1% __ticket_spin_lock     [kernel.kallsyms] 
                7.00  3.6% schedule               [kernel.kallsyms] 
                6.00  3.1% menu_select            [kernel.kallsyms] 
                6.00  3.1% fget_light             [kernel.kallsyms] 
                6.00  3.1% clear_page_c           [kernel.kallsyms] 


Where things start to get interesting, however, is with perf record. This utility is generally used along with perf report to record the performance counters of a process, and review them later.

This can be used, for example, to generate a call graph:

bash$  perf record -g -o /tmp/a.out.perf ./a.out
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.148 MB /tmp/a.out.perf (~6461 samples) ]
bash$ perf report -g -i /tmp/a.out.perf
# Events: 1K cycles
#
# Overhead        Command  Shared Object  Symbol
# ........  .............  .............  ......
#
    99.90%          a.out  a.out          [.] main
            |
            --- main
                __libc_start_main

     0.10%          a.out  [l2cap]        [k] 0xffffffff8103804a
            |
            --- 0xffffffff8105f438
                0xffffffff8105f675
...


Once perf data has been recorded, the perf annotate utility can be used to display a disassembly of the instructions that were executed:

bash$  perf annotate -i /tmp/a.out.perf |more

------------------------------------------------
 Percent |      Source code & Disassembly of a.out
------------------------------------------------
         :
         :
         :
         :      Disassembly of section .text:
         :
         :      0000000000400554
:


    0.00 :  400554:       55                      push   %rbp
    0.00 :  400555:       48 89 e5                mov    %rsp,%rbp
    0.00 :  400558:       48 81 ec 30 00 0c 00    sub    $0xc0030,%rsp
    0.00 :  40055f:       48 8d 85 d0 ff fb ff    lea    -0x40030(%rbp),%rax
    0.00 :  400566:       ba 00 00 04 00          mov    $0x40000,%edx
    0.00 :  40056b:       be 00 00 00 00          mov    $0x0,%esi
    0.00 :  400570:       48 89 c7                mov    %rax,%rdi
    0.00 :  400573:       e8 b0 fe ff ff          callq  400428 <memset@plt>
    0.00 :  400578:       c7 45 fc 00 00 00 04    movl   $0x4000000,-0x4(%rbp)
    ...

    4.21 :  4006a5:       8b 45 d0                mov    -0x30(%rbp),%eax
   15.54 :  4006a8:       83 c0 01                add    $0x1,%eax
    4.97 :  4006ab:       89 45 d0                mov    %eax,-0x30(%rbp)
    4.87 :  4006ae:       8b 45 d0                mov    -0x30(%rbp),%eax
   17.79 :  4006b1:       83 c0 01                add    $0x1,%eax
    4.36 :  4006b4:       89 45 d0                mov    %eax,-0x30(%rbp)
    4.72 :  4006b7:       48 83 45 f0 01          addq   $0x1,-0x10(%rbp)
    0.00 :  4006bc:       48 8b 45 f0             mov    -0x10(%rbp),%rax
    ...

As to be expected from Torvalds and company, the utilities include a number of options for generating parser-friendly output, limiting reporting to specified events and symbols, and so forth. Check the man pages for details.

Sunday, July 31, 2011

Easy E(17)

Ubuntu finally ships with a working E17, but there is a lingering problem: most of the modules are gone!

To get a full-featured install of E17, replete with modules and UI enhancements (finally! the settings panel entries re available from the main menu!), it is best to install from SVN.

Building E17 has always been an ordeal. Fortunately, the script easy_e17.sh makes downloading, building, and installing E17 from SVN to be quite a simple affair, once all of the dependencies are met.


To begin with, download the easy_e17 script from http://omicron.homeip.net.

There is a bug in the script which must be fixed if packages are going to be built. According to this bug report, the line (around 36 or 37)

  packages_full="$efl_basic $bin_basic $e_modules_bin $e_modules_extra $efl_extra
$bin_extra"


should be

  packages_full="$efl_basic $bin_basic $e_modules_bin $efl_extra $bin_extra $e_modules_extra"


... in order to get all the internal dependencies straight. Failure to do this results in the following error:
e_mod_main.c:1527:32: error: ‘ethumb_client’ undeclared (first use in this function)


Next, install all necessary dependencies to build E17 and the modules:

bash$ sudo apt-get install autopoint libudev-dev libgcrypt11 libgcrypt11-dev
bash$ sudo apt-get install libasound2-dev libasound2 libxine-dev 
bash$ sudo apt-get install paman padevchooser paprefs pavucontrol pavumeter 
bash$ sudo apt-get install libiptcdata-dev libmpd-dev cython libxcb-shape0-dev

According to this guide, the full list of dependencies is as follows:

bash$ sudo apt-get install xterm make gcc bison flex subversion cvs automake1.10 autoconf autotools-dev autoconf-archive libtool gettext libpam0g-dev libfreetype6-dev libpng12-dev zlib1g-dev libjpeg62-dev libtiff4-dev libungif4-dev librsvg2-dev libx11-dev libxcursor-dev libxrender-dev libxrandr-dev libxfixes-dev libxdamage-dev libxcomposite-dev libxss-dev libxp-dev libxext-dev libxinerama-dev libxft-dev libxfont-dev libxi-dev libxv-dev libxkbfile-dev libxres-dev libxtst-dev libltdl7-dev libglu1-xorg-dev libglut3-dev xserver-xephyr libdbus-1-dev liblua5.1-0-dev libasound2-dev libudev-dev autopoint  libxml2-dev

Chances are, however, that most of these are already installed.


The E17 build makes some assumptions about the location of the gcrypt libraries, so they must be symlinked:

bash$ sudo ln -s /usr/lib/x86_64-linux-gnu/libgcrypt.a /lib/x86_64-linux-gnu
bash$ sudo ln -s /usr/lib/x86_64-linux-gnu/libgcrypt.la /lib/x86_64-linux-gnu
bash$ sudo ln -s /usr/lib/x86_64-linux-gnu/libgcrypt.so /lib/x86_64-linux-gnu

...other wise linker errors such as the following will appear:
../../src/lib/.libs/libeet.so: undefined reference to `gcry_cipher_setiv'
../../src/lib/.libs/libeet.so: undefined reference to `gcry_cipher_setkey'


The Xine development headers (libxine-dev) must be installed in order for emotion to compile; otherwise an error like this will appear:
configure: error: Xine, Gstreamer or VLC backends must be selected to build Emotion
Naturally, Gstreamer or VLC headers could be installed instead.


The asound2-dev and the pulseaudio tools are required to get the mixer module working. Without them, the error
No ALSA mixer found!
will appear in the mixer module settings. Note that pulseaudio requires that the current user be added to the audio group; this can be done with the following command:

  sudo adduser $USERNAME audio



Once all this is done, it is a simple matter to install E17 with the following command:

./easy_e17.sh --instpath=/usr/local/e17 --srcpath=/home/$USER/src/e17 -i

This downloads the E17 source code to ~/src/e17, and sets the install directory to /usr/local/e17. There should be a nice success message if everything goes well.

Next, build all of the modules:

./easy_e17.sh --instpath=/usr/local/e17 --srcpath=/home/$USER/src/e17 --packagelist=full -i



Upgrading is just as straightforward:

./easy_e17.sh --instpath=/usr/local/e17 --srcpath=/home/$USER/src/e17 --packagelist=full -u


Final notes:

  * The composite module causes problems: when using the Software engine, it causes typing delays that make terminals near unusable; when using the OpenGL engine, windows do not update until there is a focus change (BIG problem). It should be disabled.

  * The shelf containing the systray module must be given the stacking order Above Everything; otherwise, the applications in the E17 systray will not receive mouse clicks (VERY BAD).

  * Determining the fonts used by various modules is easier when the source is available. The font classes used in the tclock module, for example, are in E-MODULES-EXTRA/tclock/tclock.edc. The time is displayed in text_class: "module_large", and the date is displayed in text_class: "module_small". The Settings->Look->Fonts dialog can be used to determine the font used for these classes by enabling (via the checkbox at bottom-right) the font class Modules::Small or Modules::Large, and setting the font (e.g. Sans/Regular/12 pixels) to be used for each.

UPDATE : Recent builds now fail when using --packagelist=full. Best stick with --packagelist=half if the full build fails.