Posts tagged: linux

Audigy 2 – Eine Ode an die Vergangenheit

… oder Früher war alles besser! Der letzte Jammerpost beschreibt den Ärger, den man heute immer noch mit dem Thema “Sound unter Linux” haben kann – zumindest bei neuer (und minderwertiger) Hardware. Völlig schmerzfrei und absolut out-of-the-box kann es dagegen bei älterer (bzw. hochwertigerer) Hardware laufen:

Beim Verfassen des vergangenen Posts habe ich mich immer wieder versucht, zu erinnern, wie das früher so mit ALSA & Co. lief; dabei viel mir meine gute, alte Creative Soundblaster Audigy 2 Platinum ein, die irgendwo im Keller in der Hardwarekiste vor sich hin gammelte. “Moment, die war doch hardwaremixing-fähig…” – kurz Google befragt und bestätigt.

Problem bei der Audigy (und Grund für das Triste Dasein in der Kiste) war, dass das zugehörige Output-Rack für die Front bei Einbau in einen 5,25″-Schacht aufgrund der herausstehenden Regler das Schließen meiner Gehäusetür verhindern würde. Ohne Rack hätte es jedoch keinen Kopfhörer- und Mikro-Ausgang vorne am Gehäuse gegeben. Zumindest nicht so ohne Weiteres, was ich damals noch nicht wusste…

Nach ein par Google-Orgien fand ich diverse HowTos (z.B. hier oder hier), wie man an einen internen, 10-poligen Anschluss auf der Karte ein AC’97- bzw. HD-Audio Frontpanel anschließen kann. Nun ist dieser Anschluss leider bei der Audigy 2 (ohne “ZS”) leider nicht bestückt – also Arbeit für den Lötkolben. Mit ein paar Zentimetern altem Telefonkabel konnte ich die benötigten Pins (1, 2, 4, 6, 8) schließlich emulieren und mithilfe einer kurzerhand umfunktionierten USB-Buchse an mein Frontpanel anschließen. Hierbei noch ein Tip: Wer Pin 1 (HP-Masse) nicht festgelötet bekommt, kann sich die Masse auch einfach vom Slotblech holen, verursacht keine Störgeräusche.

Also dann im BIOS die onboard-Karte deaktiviert, System gebootet und noch flux das emu10k1-Modul gebacken – fertig. Sound läuft direkt über ALSA mit parallelem Zugriff, 5.1 mit 48000Hz, out-of-the-box. Kein Soundserver, keine /etc/asound.conf, keine ~/.asoundrc – so einfach und elegant kann Sound unter Linux auch sein, die richtige Karte vorausgesetzt. Leider haben selbst die etwas besseren (=teureren) aktuellen Karten kaum noch Hardwaremixer.

Upmixing für Stereo-Signale erreiche ich mit den folgenden paar Zeilen:

# /etc/asound.conf
 
pcm.ch51dup {
    type plug
    slave.pcm "surround51"
    slave.channels 6
    route_policy duplicate
}

Früher waren also zumindest die Soundkarten besser ;)

ALSA, OSS4, PulseAudio, Jack – and back

Übers Wochenende habe ich mich meinem Problem gewidmet, bei gestartetem Chromium keinen Sound mehr über mplayer ausgeben zu können.

Hardware: SupremeFX X-Fi* Soundkarte, analoges Logitech 5.1 System

Ich wusste, dass meine Karte nicht hardwaremixing-fähig ist, also war dmix die erste Anlaufstelle. Laut Arch-Wiki ist dmix allerdings ab ALSA 1.0.9rc2 automatisch aktiv, also habe ich da nicht weiter gedreht und nach Alternativen gesucht.

OSS4 ist die Neuimplementierung des alten Unix Standard-Audiosystems, und erfreulicherweise vollständig kompatibel, d.h. ich hätte keine Anwendungen patchen müssen – also erste Wahl.
Die Installation lief problemlos (vgl. Wiki), allerdings wird meine tolle Soundkarte noch nicht offiziell unterstützt und ich bekam nur Stereo-Output, mit dem Kopfhörerausgang als primärem Ausgabemodul.

Nachdem die beiden existierenden direkten Hardware ansprechenden Möglichkeiten ausgeschöpft waren also ran an die Soundserver – allen voran PulseAudio als prominentestem Vertreter. Auch hier lief die Installation reibungslos; nach ein paar Eingriffen in die Configs gem. Wiki hatte ich ein statisches 5.1 Setup mit 48000Hz und Upsampling. Problem hierbei: ein penetrantes Kratzen im hochfrequenten Bereich, das alle Stimmen extrem blechern wirken ließ, neben einem viel zu schwachen Subwoofer-Kanal. Hat mich an meine Windows-Zeit erinnert, als ich mit einer Audigy 2 und denselben Boxen mal die Bass-Umleitung aktiviert hatte. Hierfür habe ich keine Lösung gefunden, also nächster Versuch.

JACK war meine letzte Idee, und ebenfalls schnell aufgesetzt (de facto war hier eigentlich nichts aufzusetzen, da bereits installiert – musste nur gestartet werden). Problem mit JACK war mal wieder das Multiplexing, bei parallelen Zugriffen bekam der zweite Client Device or Ressource busy.

Etwas genervt von der Rumprobiererei galt der letzte Blick wieder dmix, und siehe da: ein manuell per /etc/asound.conf eingebundenes dmix ermöglicht nun mplayer und flash-Audio parallel – ganz ohne Soundserver :)

# /etc/asound.conf:
pcm.!default {
    type plug
    slave.pcm "dmixer"
}
 
pcm.dsp0 {
    type plug
    slave.pcm "dmixer"
        hint {
         show on
         description "dmix dsp0"
    }
}
 
pcm.dmixer {
    type dmix
    ipc_key 1024
    slave {
        pcm "hw:0,0"
        period_time 0
        period_size 1024
        buffer_size 8192
        rate 48000
    }
}
 
ctl.dmixer {
    type hw
    card 0
}

Genervt hat übrigens die ganze Zeit über auch knotify4, dass ständig alle möglichen devices blockierte und des Öfteren mit SEGFAULT abstürzte. Hier warte ich gespannt auf KDE 4.5, wo selbiges komplett überholt sein soll.


* Ein von ASUS groß als X-Fi mit EAX4 beworbenes Müll-Teil, was eigentlich einen ganz anderen Chip besitzt und sich nur ähnlich einer X-Fi verhält. Wird von so gut wie keinem Spiel als EAX-fähig erkannt und sorgt bei unzähligen Usern für Probleme, siehe Foren.

iptables init-script für Arch

Ja, das vom Paket iptables mitgebrachte init-script leistet wunderbare Dienste. Nein, es besteht kein akuter Grund, eine Alternative zu schreiben…
Einen Nachteil hat es schon: die Konfiguration wird in einem nicht kommentierbaren Format hinterlegt, was bei mir in letzter Zeit ständig zur Frage “WTF hat doch gleich dieser Port da verloren? Was lässt die rule da nochmal durch?” geführt hat.

<bash-addicted>Yep, eindeutige Notwenigkeit für ein selbst gehämmertes, kommentierbares  Script!</bash-addicted> Wie in guten alten Debian-Zeiten übernimmt jetzt also bei mir ein einfaches, aber für den Job völlig ausreichendes init-script den Job. Wer es verwenden mag:

#!/bin/bash
 
#
#   easy-to-edit iptables init script for Arch
#           2010 by Alexander Koch
#
 
 
# TCP services: ssh
SERVICES_TCP=( 22 )
# UDP services:
SERVICES_UDP=( )
 
. /etc/rc.conf
. /etc/rc.d/functions
 
if [ -e "/etc/conf.d/iptables" ]; then
    . /etc/conf.d/iptables
fi
if [ -z "$IPTABLES" ]; then
    IPTABLES="/usr/sbin/iptables"
fi
if ! [ -x "$IPTABLES" ]; then
    echo "unable to execute iptables binary: $IPTABLES"
    exit 1
fi
 
function reset_tables() {
    ERR=0
    $IPTABLES -F || ERR=1
    $IPTABLES -X || ERR=1
    $IPTABLES -P INPUT ACCEPT || ERR=1
    $IPTABLES -P OUTPUT ACCEPT || ERR=1
    if [ $IPTABLES_FORWARD -eq 1 ]; then
        $IPTABLES -P FORWARD ACCEPT || ERR=1
        echo 1 >/proc/sys/net/ipv4/ip_forward || ERR=1
    else
        $IPTABLES -P FORWARD DROP || ERR=1
        echo 0 >/proc/sys/net/ipv4/ip_forward || ERR=1
    fi
 
    return $ERR
}
 
function setup_tables() {
    ERR=0
 
    # setup prevention chain against common attacks
    $IPTABLES -N preventions || ERR=1
    $IPTABLES -A preventions -f -j DROP || ERR=1                           # frags
    $IPTABLES -A preventions -p tcp --tcp-flags ALL ALL -j DROP || ERR=1   # XMAS
    $IPTABLES -A preventions -p tcp --tcp-flags ALL NONE -j DROP || ERR=1  # null
 
    # setup services chain
    $IPTABLES -N services || ERR=1
    for PORT in ${SERVICES_TCP[@]}; do
        $IPTABLES -A services -p tcp --dport $PORT -j ACCEPT || ERR=1
    done
    for PORT in ${SERVICES_UDP[@]}; do
        $IPTABLES -A services -p udp --dport $PORT -j ACCEPT || ERR=1
    done
 
    # allow incoming ping requests
    iptables -A services -p icmp --icmp-type echo-request -j ACCEPT || ERR=1
 
    # setup main chains
    $IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT || ERR=1
    $IPTABLES -A INPUT -i lo -j ACCEPT || ERR=1
    $IPTABLES -A INPUT -j preventions || ERR=1
    $IPTABLES -A INPUT -m state --state NEW -j services || ERR=1
    $IPTABLES -A INPUT -p tcp -j REJECT --reject-with tcp-reset || ERR=1
    $IPTABLES -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable || ERR=1
    $IPTABLES -P INPUT DROP || ERR=1
 
    return $ERR
}
 
case "$1" in
    start)
        stat_busy "Loading IP Tables"
        reset_tables
        if ! setup_tables; then
            stat_fail
            exit 1
        else
            add_daemon miptables
            stat_done
        fi
        ;;
    stop)
        stat_busy "Flushing IP Tables"
        if reset_tables; then
            rm_daemon miptables
            stat_done
        else
            stat_fail
            exit 1
        fi
        ;;
    restart)
        if ! ck_daemon miptables; then
            rm_daemon miptables
        fi
        $0 start
        exit $?
        ;;
    *)
        echo "usage: $0 {start|stop|restart}"
        ;;
esac
 
exit 0

Gefiltert werden nur eingehende Pakete; related und established Pakete werden ebenfalls ohne weitere Beachtung durchgelassen, ebenso alles über loopback. Für neue Pakete werden zuerst ein paar Vulnerability-Checks durchgeführt. Nach Außen wird ein Verhalten wie ohne iptables emuliert (z.B. REJECTs mit tcp-reset).

Bugreports wie immer willkommen, und Benutzung auf eigene Gefahr!

Update 31.07.10: Bugfixed :)

Netbook Screeny

XFCE mit AWN statt xfce4-panel

Back on KDE

Im Zuge meines Wechsels vom Notebook auf eine Workstation als Hauptrechner bin ich wieder auf KDE umgestiegen. Dabei entbrennt natürlich auch gleich mal wieder der übliche Toolkitwechsel und damit verbundene “iiieh, GTK!”-Wahn ^^

Für Mails bin ich wieder bei KMail, als Browser und lange gesuchte, mittlerweile ernstzunehmende Firefox-Alternative teste ich Arora.

KDE 4.4 auf Thor

Arch rc.sysinit: LUKS parallel

Im Arch Bootscript /etc/rc.sysinit werden u.A. die per /etc/crypttab definierten verschlüsselten Volumes geöffnet und gemountet – sequentiell. Da ein luksOpen-Aufruf generell schon recht lange dauert, kommen bei mehreren solcher Volumes schnell einige Sekunden zusammen.

Auf einer Kiste mit fünf LUKS-Volumes kam mir die Idee, die entsprechende Funktion mal per “&” zu forken und das Ganze so ein wenig zu parallelisieren.

In wie fern das jetzt tatsächlich im messbaren Bereich liegt, sei mal dahingestellt. Ich bilde mir jedenfalls erfolgreich einen Geschwindigkeits-zuwachs ein, und da der Patch meines Erachtens recht unkritisch ist, bleibe ich dabei :)

Wer es ausprobieren mag:

--- /etc/rc.sysinit.backup      2010-01-24 15:35:12.000000000 +0100
+++ /etc/rc.sysinit             2010-05-04 18:57:53.380890577 +0200
@@ -149,7 +149,7 @@
                        cpass="$3"
                        shift 3
                        copts="$*"
-                       stat_append "${cname}.."
+                       #stat_append "${cname}.."
                        # For some fun reason, the parameter ordering varies for
                        # LUKS and non-LUKS devices.  Joy.
                        if [ "${cpass}" = "SWAP" ]; then
@@ -188,15 +188,16 @@
                        fi
                        if [ $? -ne 0 ]; then
                                csfailed=1
-                               stat_append "failed "
+                               stat_append "${cname} failed "
                        else
-                               stat_append "ok "
+                               stat_append "${cname} ok "
                        fi
                fi
        }
        while read line; do
-               eval do_crypt "$line"
+               eval do_crypt "$line" &
        done </etc/crypttab
+       wait
        if [ $csfailed -eq 0 ]; then
                stat_done
        else

Arch ramdisk-script 1.4

In meinem Arch Ramdisk-Script <1.4 hatte sich ein dämlicher Bug eingeschlichen: bei sämtlichen rsync-Aufrufen fehlte das --delete.

Das bewirkt z.B. bei Verwendung mit Firefox, dass der Cache nie geleert wird und (streng) monoton wächst – unschön.

Hier die gefixte Version :)

#!/bin/sh
 
#
# Manages outsourcing of specified directories into memory on bootup and
# takes care of synchronization/backup on system shutdown.
#
# Version 1.4, 2010-04-26, by Alexander Koch
#
 
# includes
 
. /etc/rc.conf
. /etc/rc.d/functions
 
 
# configuration (syntax is: [persist. storage]:[mountpoint]:[mount options])
 
DISKS=('/home/alex/.ramdisks/_mozilla:/home/alex/.mozilla:size=100M,uid=1000,gid=100' \
	   'empty:/home/alex/.adobe:size=10M,uid=1000,gid=100' \
	   'empty:/home/alex/.macromedia:size=10M,uid=1000,gid=100')
 
 
# helper functions
 
function activate_rd() {
	[ -d "$1" ] || [ "$1" = "empty" ] || return 1
	[ -d "$2" ] || return 1
	mount | grep "$2" &>/dev/null && return 1
	MNT="mount -t tmpfs"
	[ -z "$3" ] || MNT="$MNT -o $3"
	$MNT none "$2"
	[ $? -gt 0 ] && return 1
	if [ "$1" != "empty" ]; then
		for D in $1/.* $1/*; do
			[ "$(basename "$D")" == "." ] && continue
			[ "$(basename "$D")" == ".." ] && continue
			rsync -axq "$D" "$2" &>/dev/null
			if [ $? -gt 0 ]; then
				umount "$2"
				return 1
			fi
		done
	fi
	return 0
}
 
function backup_rd() {
	mount | grep "$1" &>/dev/null || return 0
	if [ "$2" != "empty" ]; then
		for D in $1/.* $1/*; do
			[ "$(basename "$D")" == "." ] && continue
			[ "$(basename "$D")" == ".." ] && continue
			rsync -axq --delete "$D" "$2" &>/dev/null
			if [ $? -gt 0 ]; then
				tar -cf "/root/$(basename "$2")-failed.tar" "$1"
				return 1
			fi
		done
	fi
	umount "$1" || return 1
	return 0
}
 
 
# main logic
 
case $1 in
	start)
		stat_busy "Mounting ramdisks"
		error=0
		for M in ${DISKS[@]}; do
			FROM="$(echo "$M" | cut -d ':' -f 1)"
			TO="$(echo "$M" | cut -d ':' -f 2)"
			OPTS="$(echo "$M" | cut -d ':' -f 3)"
			activate_rd "$FROM" "$TO" "$OPTS" || error=1
		done
		if [ $error -eq 0 ]; then
			add_daemon ramdisks
			stat_done
		else
			stat_fail
			exit 1
		fi
		;;
	stop)
		stat_busy "Saving ramdisks"
		error=0
		for M in ${DISKS[@]}; do
			FROM="$(echo "$M" | cut -d ':' -f 2)"
			TO="$(echo "$M" | cut -d ':' -f 1)"
			backup_rd "$FROM" "$TO" || error=1
		done
		if [ $error -eq 0 ]; then
			rm_daemon ramdisks
			stat_done
		else
			stat_fail
			echo -n "WARNING: failed to save ramdisk(s), tried to make "
			echo "backup(s) under /root."
			echo "Hit enter to proceed shutdown."
			read DUMMY
			exit 1
		fi
		;;
	restart)
		if ! ck_daemon ramdisks; then
			"$0" stop && sleep 3
		fi
		"$0" start
		;;
	*)
		echo "usage: $0 {start|stop|restart}"
		;;
esac
 
exit 0

Disk-Zugriff tracen

Meine vor ein paar Monaten neu aufgesetzte Primärkiste litt bis vor kurzem unter einem periodisch auftretenden (ca. alle 1,5 Sekunden) Plattenzugriff im Leerlauf. Im Hinblick auf Standby und Lebensdauer der Platte ein Schönheitsfehler, und nervig weil unschön noch obendrein.

Die Ursachen solcher Symptome zu finden ist immer eine ziemliche Fummelei; in meinem Fall erwies sich jedoch die Blockdumping-Funktion des Kernels als hilfreich: ein echo 1 > /proc/sys/vm/block_dump aktiviert ein Debugging-Feature, das jeden Zugriff auf Blockdevices ins Kernel-Log schreibt. Beobachten lässt sich das Ganze dann wunderbar per dmesg -c. ACHTUNG: vorher unbedingt den syslog-daemon oder sonstige Prozesse beenden, die das Kernel-Log abbilden!

Wen es interessiert: eine gute Beschreibung, womit man noch in /proc spielen kann, gibt es hier.

Bei mir war übrigens HALd schuld, der ständig das DVD-Laufwerk pollen musste, und dabei komischerweise Plattenaktivität verursachte. Ein ähnlicher Bug ließ irgendwann mal unter Ubuntu tausende Toshiba-Festplatten abrauchen… ^^

Dynamic DNS-Caching with PDNSd and DHCP

(I write this in English because I was asked to do so by some people on the Arch forums. Anyway, I think this should be no problem as if you hack on configs you normally understand enough to get this done as well.)

I’ve been using pdnsd for DNS caching for quite a while now and I can feel the speed up while browsing the web (at least I can go on believing so ;) ) or checking for updates in the AUR.
The problem with pdnsd in conjunction with mobile devices (like the netbook I’m typing this on) is that in the basic setup, it only uses static DNS servers, described in /etc/pdnsd.conf. So if you happen to get behind some firewall that doesn’t permit DNS queries to other nameservers than the ones advertised by DHCP, you have to change your setup manually – and switch back when you’re out.
It would be great if pdnsd took the DNS your machine got from DHCP and use it as primary source for cache-misses. This also uses the eventually existing DNS infrastructure and local caches, instead of bypassing them. Here’s how I implemented that, using pdnsd and dhcpcd:

  1. Setup pdnsd as described in the Arch Wiki article, but do not create a /etc/resolv.conf.head. Create a primary DNS source entry, mine looks like this:
    server {
    	label="maindns";
    	ip=8.8.8.8, 8.8.8.4;  # I use Google dns as fallback
    	proxy_only=on;        # Do not query any other name servers
    	timeout=4;            # Server timeout
    	uptest=none;          # No uptest
    	purge_cache=off;      # Keep stale cache entries in case the ISP's
    			      # DNS servers go offline.
    }
  2. In /etc/resolv.conf, the only nameserver should be your local machine:
    # /etc/resolv.conf
    nameserver 127.0.0.1
  3. In /etc/dhcpcd.conf, disable the resolv.conf-hook to prevent dhcpcd from changing the resolving scheme:
    [...]
    nohook resolv.conf
  4. In /usr/lib/dhcpcd/dhcpcd-hooks, we create a hook script (e.g. 21-pdnsd.conf) that uses pdnsd-ctl to override the nameserver IPs defined in /etc/pdnsd.conf with the ones received by DHCP:
    # Set the IP of "maindns" entry for pdnsd
     
    case "$reason" in
    	BOUND|INFORM|REBIND|REBOOT|RENEW|TIMEOUT|STATIC)
    		SRVS=""
    		for X in $new_domain_name_servers; do
    			if [ -z "$SRVS" ]; then
    				SRVS="$X"
    			else
    				SRVS="${SRVS},$X"
    			fi
    		done
    		pdnsd-ctl server 0 up $SRVS
    		;;
    	PREINIT|EXPIRE|FAIL|IPV4LL|NAK|NOCARRIER|RELEASE|STOP)
    		# reset to values in /etc/pdnsd.conf
    		pdnsd-ctl config
    		;;
    esac

That’s it, no big deal ;)
If you find any problems or disadvantages with this setup, feel free to post them in the comments!

wicd: aurora-bug

Der Network-Manager wicd triggert beim Auswählen eines verfügbaren WLAN über den wicd-client Dialog (nicht das Trayicon!) einen noch nicht identifizierten Bug in der Aurora GTK Engine, der zu 100% CPU-load und einem memory-leak im wicd-Prozess (besser gesagt python) führt.

Wer sich also wundert, warum beim Verbinden über den Dialog immer der ganze Client einfriert, beim Verbinden über das Trayicon jedoch nicht, sollte mal gegenchecken, ob vielleicht Aurora aktiv ist.

Hier noch der Link zum Eintrag im wicd-Bugtracker.

based on theme by WordPress Themes