Ever since I upgraded my notebook with a SSD, I was looking for a way to minimise or avoid unnecessary write accesses. The tools of choice (on Linux at least) are iostat for a rough summary and pidstat for the details. With the help of those two one can easily figure out which processes are responsible for write accesses.

Once a writing process is identified, lsof can tell you which files are actually written. Depending on what you want to achieve, you can then continue to relocate that file to a different disk (e.g. if you have two disks and want one of them to sleep most of the time) or to memory (using tmpfs). The latter obviously means that the written data will be lost at the next reboot, but sometimes this is perfectly fine e.g. for the files inside /tmp. Therefore, it is generally a good idea to move that directory into volatile memory following the instructions on the openSUSE Wiki.

All good and well if you actually manage to relocate or move a file. Often file locations are a matter of configuration and otherwise you can help yourself with dynamic links. But there was one very special file on my openSUSE 11.4 installation that withstood all my assaults for quiet some time. I’m speaking of a beast called .xsession-errors residing in your $HOME directory. Created by KDM, one would expect to be able to configure the location of that file. Indeed, there is a configuration option called ClientLogFile specifically for that purpose. Unfortunately this is only the first and easier of two necessary steps:

  1. As root open your /usr/share/kde4/config/kdm/kdmrc, go to a section labelled [X-:0-Core] (there may be multiple of those, but don’t worry and just pick the last one) and add the following line:

    This will move the file into the /tmp directory. Mind the path relative to $HOME.

  2. Now the hidden piece: again as root open your /etc/X11/xdm/Xsession and make the following changes (I deliberately use the patch syntax here i.e. remove lines with a minus sign and add those with a plus sign):
    --- Xsession.old        2011-05-01 19:46:40.000000000 +0200
    +++ Xsession    2011-05-02 22:18:39.000000000 +0200
    @@ -123,8 +123,8 @@
         # GDM seems to handle this its self
         test -z "$GDMSESSION" || break
    -    # Once if KDM does handle this its self
    -    #test -z "$KDMSESSION" || break
    +    # KDM handles this itself
    +    test -z "$KDE_SESSION_VERSION" || break
         # Avoid bad symbolic links
         case "$errfile" in

Done; logout, restart KDM, re-login and check if the xsession-errors* exists at the new location. If so, remove your old one and cheer to a long living SSD. Only, of course, if the new location is not on your SSD, but e.g. in memory. It doesn’t hurt to re-check with pidstat.

Fedora Live USB with GRUB

As already mentioned in my last post, my laptop won’t boot from a USB stick prepared using a binary copy of an ISO (by means of dd). Here is the method I use to boot the Fedora Live images off my USB stick using GNU GRUB2. The device node of the USB driver is denoted /dev/sdX in the following and must be replaced with the actual device node (e.g. /dev/sdc).

  1. Prepare a partition on the USB stick and/or make sure there is enough space on it (it must be slightly larger than the ISO image).
  2. Make sure it is flagged bootable. ( fdisk -l /dev/sdX is your friend)
  3. Remember the name of the USB partition you’re going to use or if unlabelled, label it.
  4. Loop-mount the ISO image using something like mount -o loop /path/to/iso /mnt/loop
  5. Copy the content of the ISO over to the USB
  6. Install GRUB on the USB by issuing grub-install --no-floppy --root-directory=/mnt/usb /dev/sdX
  7. Create a /mnt/usb/boot/grub/grub.cfg with the following content
    menuentry "Fedora Live" {
     linux /isolinux/vmlinuz0 root=live:LABEL=XYZ rootfstype=auto ro liveimg quiet  rhgb rd_NO_LUKS rd_NO_MD rd_NO_DM
     initrd /isolinux/initrd0.img
    menuentry "Fedora Live (Basic Video)" {
     linux /isolinux/vmlinuz0 root=live:LABEL=XYZ rootfstype=auto ro liveimg quiet  rhgb rd_NO_LUKS rd_NO_MD rd_NO_DM xdriver=vesa nomodeset
     initrd /isolinux/initrd0.img

    where XYZ must be replaced by the actual partition name of your USB partition.

  8. Unmount and boot

HP Ambient Light Sensor on Linux

Often, the simple answers are those you don’t find on the web. Here is one of them with hopefully enough keywords to make it findable:
To activate the Ambient Light Sensor on my new HP EliteBook 8440p (article and pictures will follow later) running Fedora 13, the following command (issued by root obviously) did the trick:

echo 1 > /sys/devices/platform/hp-wmi/als

Also don’t forget to check if the ALS is enabled in the BIOS if this doesn’t work. It seems to be enabled by default though.

Secure Firefox with AppArmor

To „lock down“ Firefox on an openSUSE 11.3 machine, I used the four AppArmor profiles you find below. The first is an openSUSE default profile and the second is based on the openSUSE default profile. My changes include support for PulseAudio sound and the Flash plugin, where the latter is realized with local profiles that are stronger confined than Firefox itself. Finally, I added permission for Zotero requirements.

# /etc/apparmor.d/usr.lib.firefox.firefox.sh


/usr/lib/firefox/firefox.sh {

  deny capability sys_ptrace,

  /bin/basename rix,
  /bin/bash rix,
  /bin/grep rix,
  /etc/magic r,
  /usr/bin/file rix,
  /usr/lib/firefox/firefox px,
  /usr/share/misc/magic.mgc r,
# /etc/apparmor.d/usr.lib.firefox.firefox


/usr/lib/firefox/firefox {

  deny /usr/lib/firefox/firefox.sh x,
  deny /usr/lib/mozilla/extensions/*/ w,

  /bin/bash ix,
  /bin/uname ix,

  /etc/gai.conf r,
  /etc/gnome-vfs-2.0/modules/ r,
  /etc/gre.d/ r,
  /etc/gre.d/* r,
  /etc/mailcap r,
  /etc/mime.types r,
  /etc/mtab r,
  /etc/opt/kde3/share/applications/ r,
  /etc/opt/kde3/share/applications/mimeinfo.cache r,

  owner @{HOME}/.ICEauthority r,
  owner @{HOME}/.beagle/ToIndex/* rw,
  owner @{HOME}/.fontconfig/* r,
  owner @{HOME}/.icons/ r,
  owner @{HOME}/.local/share/applications/ r,
  owner @{HOME}/.local/share/applications/* r,
  owner @{HOME}/.local/share/mime/* r,
  owner @{HOME}/.mozilla/extensions/** rw,
  owner @{HOME}/.mozilla/firefox/** rw,
  owner @{HOME}/.mozilla/firefox/**.sqlite* k,
  owner @{HOME}/.mozilla/firefox/**/.parentlock k,

  /opt/kde3/share/applications/ r,
  /opt/kde3/share/applications/mimeinfo.cache r,

  owner @{PROC}/*/mounts r,
  owner @{PROC}/*/fd/ r,
  @{PROC}/meminfo r,
  @{PROC}/sys/kernel/ngroups_max r,

  /usr/bin/tr ix,
  /usr/bin/which ix,

  /usr/lib/**.so mr,
  /usr/lib/firefox/firefox rix,
  /usr/lib/libproxy/pxgconf ix,
  /usr/lib/nspluginwrapper/*/linux/npviewer rcx -> npviewer,
  /usr/lib/xulrunner-*/plugin-container cx -> plugin_container,

  /usr/local/share/applications/ r,
  /usr/local/share/applications/* r,
  /usr/share/applications/ r,
  /usr/share/applications/* r,
  /usr/share/gvfs/remote-volume-monitors/ r,
  /usr/share/gvfs/remote-volume-monitors/* r,
  /usr/share/locale-bundle/**.mo r,
  /usr/share/mime/**.xml r,
  /usr/share/mozilla/extensions/** r,
  /usr/share/myspell/* r,

  /var/cache/gio-2.0/defaults.list r,
  /var/cache/libx11/compose/* r,
  owner /var/run/gdm/*/database r,

  profile npviewer {

    /bin/bash rix,
    /bin/uname rix,
    /usr/bin/tr rix,
    /usr/bin/which rix,
    /usr/lib/nspluginwrapper/*/linux/npviewer.bin rix,

  profile plugin_container {

    deny /etc/passwd r,
    deny @{PROC}/uptime r,
    deny @{HOME}/.mozilla/firefox/profiles.ini r,

    /bin/bash ix,
    /bin/grep ix,
    /bin/ps ix,

    owner @{PROC}/*/fd/ r,
    owner @{PROC}/*/stat r,

    owner /var/run/gdm/*/database r,
    owner @{HOME}/.adobe/Flash_Player/**/ w,
    owner @{HOME}/.adobe/Flash_Player/AssetCache/ r,
    owner @{HOME}/.macromedia/Flash_Player/** rw,

  # Zotero-specific rules
  owner @{HOME}/.mozilla/firefox/*/zotero/pdfinfo-Linux-* cx -> zotero_tools,
  owner @{HOME}/.mozilla/firefox/*/zotero/pdftotext-Linux-* cx -> zotero_tools,
  owner @{HOME}/.zoteroIntegrationPipe rw,
  /usr/bin/evince Ux,
  /usr/bin/mkfifo ix,
  profile zotero_tools {

    owner @{HOME}/.mozilla/firefox/*/zotero/storage/*/* r,
    owner @{HOME}/.mozilla/firefox/*/zotero/storage/*/.zotero-ft-info w,
    owner @{HOME}/.mozilla/firefox/*/zotero/storage/*/.zotero-ft-cache w,
# /etc/apparmor.d/abstractions/pulseaudio

/dev/shm/ r,
owner /dev/shm/pulse-shm-* rw,
/dev/snd/*      rw,

/etc/alsa-pulse.conf r,
/etc/asound-pulse.conf r,
/etc/pulse/client.conf r,

owner @{HOME}/.pulse-cookie rwk,

/usr/bin/pulseaudio px,

/usr/share/alsa/** r,
/usr/share/sounds/** r,

/var/lib/dbus/machine-id r,

# vim:syntax=apparmor
# /etc/apparmor.d/usr.bin.pulseaudio


/usr/bin/pulseaudio {

Embed PDFs from Zotero

I’m using Zotero to organise my bibliography. Not only do I store citation information, but I also love the possibility to let it organise the corresponding PDF files. That way I have full-text search and a superb tagging facility for almost everything I read and might need to use and cite later. As a Fedora user, I didn’t have Firefox configured to embed all kind of media into the browser by default. In general I perceive this as an advantage, but in my use-case I have Firefox with Zotero running in full-screen on a separate workspace and want it to manage the screen entirely. And since Evince is the default PDF viewer on Gnome at the moment, I would like it to be embedded into Firefox tabs as I open PDFs from Zotero.

As quick search for the topic brought me to an article in the Ubuntu Forums which solved 90% of the problem. Installing Mozplugger

yum install mozplugger

and raising the priority of Evince as its PDF handler made most of the PDFs open embedded just as intended. However, Zotero seems to assign an unusual MIME type for the PDFs it stores that is „application/octetstream“. Thus to fit my needs, I added that type to the Mozplugger PDF handler

sudo vim /etc/mozpluggerrc

which now reads as

application/pdf:pdf:PDF file
application/x-pdf:pdf:PDF file
text/pdf:pdf:PDF file
text/x-pdf:pdf:PDF file
application/octetstream:pdf:PDF file
        repeat noisy swallow(evince) fill: evince "$file"
#       ACROREAD()
#       repeat noisy swallow(kpdf) fill: kpdf "$file"
#       repeat noisy swallow(Xpdf) fill: xpdf -g +9000+9000 "$file"
#       repeat noisy swallow(okular) fill: okular "$file"
#       GV()
#       repeat noisy fill exits: evince "$file"