Newer posts are loading.
You are at the newest post.
Click here to check if anything new just came in.

May 07 2012

noqqe
18:57
2375_22db
Reposted fromnukeforce nukeforce viavideogames videogames

May 06 2012

19:51

Deadly 30 unter Debian Squeeze 64bit

Gerade von Deadly 30 gelesen. Linux Version ist fertig. Hurra!

Als ich den Trailer gesehen habe musste ich sofort an die Metal Slug Reihe denken, die ich total mag.

Egal, es ist Sonntag Abend und hatte die 4 Euro übrig. Ich hatte aber bereits erwartet, dass es nicht nur auf ein ./deadly 30 hinauslaufen würde. Damit lag ich auch richtig.

1
2
3
$ ./Deadly 30
./Deadly 30: error while loading shared libraries: libgstreamer-0.10.so.0:
cannot open shared object file: No such file or directory

Mh. Da ich nicht zwischen 32 und 64bit wählen durfte wahrscheinlich 32bit?

1
2
3
$ file Deadly 30                                                                                                                 
Deadly 30: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically
linked (uses shared libs), for GNU/Linux 2.6.15, stripped

Also die nötigen 32bit Libraries runterladen und einbauen.

1. /usr/lib32/ Backup erstellen

1
$ tar cfvz $HOME/usr-lib32.tar.gz /usr/lib32

2. libgstreamer installieren

1
2
3
4
5
$ cd /tmp
$ wget http://ftp.de.debian.org/debian/pool/main/g/gstreamer0.10/libgstreamer0.10-0_0.10.30-1_i386.deb
$ ar -x libgstreamer0.10-0_0.10.30-1_i386.deb
$ tar xfvz data.tar.gz
$ sudo cp -av /tmp/usr/lib/* /usr/lib32/

3. libgstreamer-plugins installieren

1
2
3
4
5
$ cd /tmp
$ wget http://ftp.de.debian.org/debian/pool/main/g/gst-plugins-base0.10/libgstreamer-plugins-base0.10-0_0.10.30-1_i386.deb 
$ ar -x libgstreamer-plugins-base0.10-0_0.10.30-1_i386.deb 
$ tar xfvz data.tar.gz
$ sudo cp -av /tmp/usr/lib/* /usr/lib32/

Das ist zwar alles immer total unschön, aber es funktioniert. Außerdem, was tut man nicht alles für ein bisschen 2D Shooter und Zombies?

May 05 2012

09:33

Ext Filesystem Checks vorhersagen

Kernel Updates am Server seiner Wahl einspielen und dann…warten. Warten auf die erlösenden ICMP Antworten. Oder bootet die Kiste doch nicht? Alles dauert verdächtig lange. Auch nach 10 Minuten noch nichts. Gerade wenn man die Zugangsdaten fürs DRAC/ILO rausgekramt hat zeigt sich: Filesystem Check.

Extended Filesystems machen an den folgenden 2 Punkten fest wann fsck’s passieren:

  • Maximale Anzahl von Mounts
  • Zeitliche Abstände zwischen den Routine Checks

Die Informationen stehen im Superblock einer Parition. Das Tool dumpe2fs stellt diese zur Verfügung:

$ dumpe2fs -h /dev/sda1 

Das ganze hab ich dann verskriptet. Es “scanned” alle gemounteten ext Parititonen und warnt einen, falls die maximalen Mounts oder die zyklischen Checks anstehen.

#!/bin/bash
# ext-verify: Verfiy if max mount count or cyclic fsck 
# on ext2,ext3,ext4 filesystems has been reached. 
# Copyright: (C) 2011 Florian Baumann <florian.baumann@noris.net>
# License: GPL-3 <http://www.gnu.org/licenses/gpl-3.0.txt>
# Date: Tuesday 2012-05-04

# Configuration
DUMPE2FS=$(which dumpe2fs)
DUMPOPTS="-h"
WARNC=0

# Security 
if [ -z "$DUMPE2FS" ]; then
    if [ ! -x $DUMPE2FS ]; then
        echo "ERR: Could not find your dumpe2fs"
        echo "ERR: Are you root?"
        exit 1
    fi
fi

# Parsing functions
function get_value () {
    LANG=C $DUMPE2FS $DUMPOPTS $HDD 2>/dev/null | grep "$1" | sed "s#$1s*##" | tail -1
    if [ $? -gt 0 ]; then echo "ERR: Could not find value $1" ; fi
}
function convert_date () {
    if [ -n "$1" ]; then
        date -d "$1" "+%s"
    fi
}

# Scan Mode
if [ -z "$*" ]; then
    for x in $(mount | grep ext | awk '{print $1}'); do
        HDD=$x
        MOUNTED=$(get_value "Mount count:")
        MAXMOUNT=$(get_value "Maximum mount count:")
        NEXT=$(get_value "Next check after:")
        DATENOW="$(date +%s)"
        DATENEXT=$(convert_date "$NEXT")

        if [ ! "$MAXMOUNT" == "-1" ]; then
                if [ $MOUNTED -ge $MAXMOUNT ]; then
                        echo "WARNING: Max mount count on $HDD has been reached. ($MOUNTED/$MAXMOUNT)"  
                        ((WARNC++))
                fi
        fi

        if [ -n "$DATENEXT" ]; then
                if [ $DATENOW -ge $DATENEXT ]; then
                        echo "WARNING: $HDD has reached the next periodically filesystemcheck. ($NEXT)"
                        ((WARNC++))
                fi
        fi

        if [ $WARNC -gt 0 ]; then
            echo "RESULT: A fsck will be executed at the next reboot for $HDD."  
        else
            echo "RESULT: Everything's fine on $HDD."
        fi
    done
fi

exit $WARNC

Das sieht dann unter Umständen so aus:

1
2
3
WARNING: Max mount count on /dev/sda1 has been reached. (29/29)
WARNING: /dev/sda1 has reached the next periodically filesystemcheck. (Sa Apr 7 13:37:58 2012)
RESULT: A fsck will be executed at the next reboot for /dev/sda1.

Natürlich für jede gefundene Partition. Um das jetzt noch am besten irgendwie zu automatisieren hab ich mich entschieden das in apt zu integrieren.

1
2
$ vim /etc/apt/apt.conf.d/09extverfiy
DPkg::Pre-Install-Pkgs   { "if [ -x /usr/local/bin/ext-verify.sh ]; then echo 'Verifying ext Filesystems' ; /usr/local/bin/ext-verify.sh ; fi"; };

Bei jedem apt-get/aptitude wird das nun ausgeführt.

1
2
3
4
5
6
7
8
9
10
11
12
$ aptitude install whois
Die folgenden NEUEN Pakete werden zusätzlich installiert:
  whois
0 Pakete aktualisiert, 1 zusätzlich installiert, 0 werden entfernt und 0 nicht aktualisiert.
Muss 0 B/64,9 kB an Archiven herunterladen. Nach dem Entpacken werden 406 kB zusätzlich belegt sein.
Verifying ext Filesystems
RESULT: Everything's fine on /dev/sda1.
Vormals abgewähltes Paket whois wird gewählt.
(Lese Datenbank ... 48680 Dateien und Verzeichnisse sind derzeit installiert.)
Entpacken von whois (aus .../whois_5.0.10_amd64.deb) ...
Trigger für man-db werden verarbeitet ...
whois (5.0.10) wird eingerichtet ...

April 29 2012

10:22

Das CAP Theorem

Das CAP Theorem ist mir das erste mal wirklich begegnet im Podcast Binärgewitter #1 NoSQL in dem es kurz und knackig an einfachen Beispielen gut erklärt wurde.

Im Grunde hat sich schon kurz nach der Jahrtausendwende ein Professor in Berkeley Gedanken gemacht was man von einem Datenbank System erwarten kann. Im wesentlichen gehts um 3 Faktoren, die aber niemals alle zugleich erfüllt werden können.

Konsistenz (C): Alle Knoten sehen zur selben Zeit dieselben Daten.
Verfügbarkeit (A): Alle Anfragen an das System werden stets beantwortet.
Partitionstoleranz (P): Das System arbeitet auch bei Verlust von Nachrichten, einzelner Netzknoten oder Partition des Netzes weiter.

Will man sich mal anschauen, wenn man Datenbanken betreut.

Links

April 20 2012

06:52

Keyboard Codes unter Debian mit xfce4.8

Zuerstmal sei gesagt, dass ich sowieso schon sehr begeistert bin wie viele von den Spezialtasten auf dem Thinkpad schon Out-of-the-Box unter Debian funktionieren. Trotzdem gab es noch ein paar die das nicht Taten oder zumindest nicht mit der Software funktioniert hatte bei der ich es brauche.

Keyboard Signale mit xev abfangen

Erstmal gehts darum rauszufinden was für lustige Tasten ich eigentlich gerade drücke. Hier gibts verschiedene Spielereien mit dem Tool xev und sed:

$ xev | sed -n 's/^.*keycode *([0-9]+).*$/keycode  /p' 
keycode 36 
keycode 8 
keycode 160 
keycode 160 

XKeysymDB und benutzerdefiniertes Mapping

Nachdem man weiss, was für KeyCodes man gerade drückt kann man damit auch weiter arbeiten. Diese KeyCodes müssen nun Keysyms zugeordnet werden. Der X11 bringt hier automatisch eine kleine Übersicht mit die es sich lohnt mal anzusehen:

$ less /usr/share/X11/XKeysymDB

Obacht: Man kann keine neuen Keysyms definieren. Man muss Keysyms aus dem DB File benutzen um diese dann auf den Keycode zu mappen. Dieses Mapping findet folgendem File statt:

$ vim ~/.Xmodmap 
keycode 160 = hpModelock1 

Anschliessend kann man die Xmodmap neu laden:

$ xmodmap ~/.Xmodmap 

xfce Keymapping

Der eigentlich spannende Teil ist, die Shortcuts jetzt mit xfce zu verknüpfen, damit man bei Betätigung einen Befehl seiner Wahl ausführen kann. In xfce gibt es eine kleine gui im Settings Manager (xfce4-settings-manager) mit der man soetwas einrichten kann. Zumindest theoretisch. Leider können hier nur Tastenkombinationen(!) hinterlegt werden. Keine Keysyms.

Aber das macht nichts. Wie so ziemlich alles gibts ein xml File in dem die Werte stehen:

$ vim .config/xfce4/xfconf/xfce-perchannel-xml/xfce4-keyboard-shortcuts.xml 
xfce4-keyboard-shortcuts.xml
1
2
3
4
5
6
7
<property name="custom" type="empty">
  <property name="&lt;Alt&gt;F2" type="string" value="xfrun4"/>
  <property name="&lt;Control&gt;&lt;Alt&gt;Delete" type="string" value="xflock4"/>
  <property name="XF86Display" type="string" value="xrandr --auto"/>
  <property name="override" type="bool" value="true"/>
  <property name="hpModelock1" type="string" value="/usr/bin/i3lock"/>
</property>

Der letzte Eintrag wurde von mir per Hand eingetragen und funktioniert. Mit fn+F2 kann ich jetzt (wie auf meinem Keyboard belabelt) meinen Bildschirm sperren.

Links

http://en.gentoo-wiki.com/wiki/Multimedia_Keys

http://wiki.ubuntuusers.de/Xmodmap

http://wiki.xfce.org/faq#keyboard

April 15 2012

09:16

Thinkpad X201

Ich erstand bei ralf-scharbert.de ein Thinkpad X201 (refurbished) für einen m.E. guten Preis.

Alles ist toll, Debian installiert, Funktionstasten gehen fast alle Out-of-the-Box. Nur das wlan musste kurz nachgebaut werden, weil non-free Firmware:

$ apt-get install firmware-iwlwifi

Wenn ich mich jetzt noch dran gewöhnen könnte den roten Nippel zu nutzen statt das kleine Touchpad ist alles gut. Zumindest wurde mir das Nahe gelegt ;)

Um das zu Windows 7 zu sichern (sollte ich es mal brauchen) hab ich außerdem mal die Windows Image Sicherung ausprobiert. Konkret auf ein CIFS Share im Netzwerk die .VHD Files überspielt und aus dem Internet den “Windows Systemrettungsdatenträger” geholt :). Habe nicht probiert ob das wirklich funktioniert, aber es klingt zumindest so als könne man sich darauf verlassen.

Hurra.

April 09 2012

18:05

DaviCal, PostgreSQL und Apple Produkte

Vor ewigen Zeiten hab ich mir mal ein eGroupware installiert. Es war schrecklich und deshalb hab ich es durch etwas weniger Schreckliches ersetzt. DaviCal.

Nicht das ich spontan Lust gehabt hätte sowas wie Kontakte und so mal zu Ordnen. Vielmehr hat mich die PostgreSQL Datenbank intressiert die dazu nötig ist. Installation und Konfiguration ist so schön dokumentiert das ich das hier nicht widerholen brauche. Die Integration in Thunderbird verlief ohne Probleme. Dann kamen meine beiden Geräte aus dem Hause Crapple mit der Synchronisation der Kontakte dran.

iPhone

Mein iPhone wollte den hingeworfenen Remote für Contacts nicht einfach so hinnehmen. Ewiges “Verifying” durch den Installationsassistenten und jedesmal gefühlte 5-10 Minuten später hat er mich dann abgewiesen. Im Apache Log ist davon nichts aufgetaucht. Nach bisschen wälzen in der Dokumentation hier und da:

CardDav-Accounts only could set up via iPhone configuration utility. It had to
set up a principal url (e.g. https://domain.tld/caldav.php/username/contacts)
for a working account.

Carddav Clients, wiki.davical.org

Das iPhone configuration utility also. So ganz leicht fand ich das damit nicht… Ich hab aber gelernt das man super Debuggen kann über die eingebaute Consolen Funktion in dem Tool. Im iPhone wird man nach dem ServerPath gefragt. Den ich mit

http://cal.n0q.org/caldav.php/noqqe/addressbook

Mein Fehler war eben genau die Angabe des Protokolls. Ich meine sorry. Apple probiert hier gefühlte 1,3 mio (nichtmal wirklich RFC spezifizierte) Orte an denen meine Kontakte serverseitig wohl liegen könnten durch und am Ende können die nichtmal ein führendes http:// wegparsen? Egal. Fehler sah wie folgt aus:

http://http//cal.n0q.org/caldav.php/noqqe/addressbook

Macbook

Hier nun der wirklich lustige Teil. Das Address Book des Macbooks. Selbes “Verifying” Spielchen wieder.

Nachdem ich rausgefunden habe wie ich das intuitive Interface der App wirklich benutzen soll kam nur folgendes auf meinem Webserver an:

1
2
77.191.14.156 - - [09/Apr/2012:19:35:53 +0200] "PROPFIND /caldav.php/noqqe/addressbook:0(null)/ HTTP/1.1" 401 401 "-" "Address%20Book/883 CFNetwork/454.12.4 Darwin/10.8.0 (i386) (MacBook2%2C1)"
77.191.14.156 - - [09/Apr/2012:19:35:53 +0200] "PROPFIND /caldav.php/noqqe/addressbook:0(null)/ HTTP/1.1" 400 477 "-" "Address%20Book/883 CFNetwork/454.12.4 Darwin/10.8.0 (i386) (MacBook2%2C1)"

Herzlichen Glückwunsch. Woher kommt dieses “:0(null)” ? Ich habe den Serverport angegeben:

Ich habe mehr als 10 mal versucht das Interface korrekt auszufüllen, aber hatte keine Chance. Nach einmaligem Anlegen konnte ich den Serverpath nicht mehr editieren und wenn ich Ihn von vornherein eingetragen habe bekam ich immer das oben beschriebene “:0(null)”.

Ich hab mir schliesslich die Config von Addressbuch mühsam ergrept und gefunden:

1
~/Library/Application Support/AddressBook/Sources/FC24F051-B1B2-4286-9A28-5830207F0DA2/Configuration.plist

Dort gibt es unter anderem folgende Paramteri (bereits korrigiert):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>_className</key>
    <string>PHXCardDAVSource</string>
    <key>disabled</key>
    <integer>0</integer>
    <key>haveWriteAccess</key>
    <integer>0</integer>
    <key>isSharedABAccount</key>
    <integer>1</integer>
    <key>name</key>
    <string>cal.n0q.org</string>
    <key>refreshInterval</key>
    <integer>0</integer>
    <key>serverSupportsSearch</key>
    <integer>0</integer>
    <key>servername</key>
    <string>http://cal.n0q.org:80/caldav.php/noqqe/addressbook</string>
    [...]
</dict>
</plist>

Hurra. Ohne das kaputte Interface kann mein Address Book problemlos mit meinem neuen DaviCal Server reden.

April 01 2012

09:11

ASCII Statistik Graphen mit Bash

Vor einem Jahr hab ich mich mit einem ASCII Balkendiagramm beschäftigt. Als es dann fertig war kams unter dem Namen statistical auf Github: http://github.com/noqqe/statistical

Hab mir überlegt wie schwierig das wohl ist, dass ganze Teil nochmal so umzubauen, dass vertikale Balken entstehen. Horizontal gesehen ist das ja relativ easy. Etwas skalieren hier und da und dann einfach die Anzahl der Zeichen in einer Zeile ausgeben.

Im v-barplot ist da schon etwas mehr Logik nötig. Aber es ging dann trotzdem. Heraus kam dabei folgendes:

./v-barplot foo:24 bar:90 alice:76 flo:32 blu:79 fa:12 bob:230 kika:121

Beide Skripte (v-barplot & h-barplot) sind jetzt im statistical Repo. Anregungen & Kritik immer gerne.

March 23 2012

14:11

The Revival of SCCS

Ich durfte wie bereits erwähnt auf den Chemnitzer LinuxTagen einem Vortrag zur Geschichte von Versionskontrollsystemen und dem Revival von SCCS lauschen. Diesen fand ich unter anderem (besonders beim Historischen) informativ und unterhaltsam.

Nicht übereinstimmen kann ich aber in den angebrachten “Vergleichen” von SCCS zu (unter anderem) git. Die Vortragsfolien können hier angesehen werden.

Die Repository Initalisierung

Initalisierung aller OpenSolaris Source Files:

SCCS: 8 Sekunden
git: 100 Sekunden

Schnelle Massenübernahme in SCCS, SCCS Seite 29

Aus dem Hörsaal kam die berechtigte Frage:

Wie oft mache ich das?

Ich denke das spricht schonmal für sich, aber das eigentliche Feature hierbei ist, dass git von allen Files im Repo einen Binärblob in .git/ ablegt. Während SCCS nur Diffs vom letzten zum neuen Commit speichert.

Das hab ich mal nachgebaut, kommt schon hin:

1
2
3
4
$ time git add .
real  0m38.405s
user  0m17.121s
sys 0m2.620s
1
2
3
4
$ time git commit -a -m "init"
real  0m26.078s
user  0m6.132s
sys 0m1.660s

Nachvollziehbar, dass git länger dafür braucht alle Files zu kopieren als SCCS mit “Ah, hier ist noch ein File, schreib ich den Namen des Files mal in meine Liste”.

Das Datenvolumen

Die angesprochenen Werte auf Seite 36 der Präsentation beziehen sich auf simple Timestamps. Jörg Schilling hat hier 2 Mio. Timestamps erstellt und mit git und sccs jeden davon mit jeweils einem Commit abgeschlossen.

Platzbedarf mit SCCS ca. 300 MB (komprimiert 160 MB)
Platzbedarf mit GIT geschätzt: ca. 15 TB

Dauertest mit SCCS >2 Millionen Deltas, SCCS Seite 36

Ich war so frei das einfach mal (aus zeitlichen Gründen mit 1 Mio. Files) nachzustellen:

1
2
3
4
5
6
7
8
9
#!/bin/bash
touch test 
git add test 
C=0
time while [ $C -le 1004225 ]; do
  date "+%Y%m%d %H%M%s%N" > test 
  git commit -a -m "$C"
  ((C++))
done

Größe nach dem Command:

1
2
$ du -sh /tmp/1miocommits/
12G .

Ich bin mir nicht sicher was Jörg hier genau getan hat. Meine Testwerte unterscheiden sich jedenfalls erheblich von dem, was im Vortrag vorkommt.

Unter anderem wurde erwähnt, dass die Größe des Git Repositories hochgerechnet wurde. Nun das ist natürlich insofern doof, wie man weiss das git Deduplication betreibt. Teile aus den Blobs werden einmalig aufgehoben, wenn sie idientisch sind. So lässt sich viel Platz sparen und das Konstrukt des “Hochrechnens” bricht zusammen. Selbst wenn ich das jetzt nur verdopple kommen dabei 24 GB statt 15 TB raus.

Die Zeit

Ein weiterer Punkt der meines Erachtens beim Vergleich von git zu SCCS außer acht gelassen wurde. Die Zeit.

Was mich sehr interessiert sind die Wiederherstellzeiten. Klar git hat einen spezifischen Commit welcher auf ein Objekt im Hash Store zeigt. Dieser wird ausgelesen und fertig ist die Wiederherstellung.

(Bild von progit.org - Creative Commons Attribution Non Commercial Share Alike 3.0 license)

Aber bei SCCS? Angenommen ich möchte vom 1.000.000 Commit zum 1. zurück. Alle Diffs werden dazu auf das aktuelle File angewandt und zurückgerechnet bis das File wieder am Ursprungszustand angekommen ist. Ob das Spass macht?

Die Konsistenz

Selbes Szenario hier. Ich weiss nicht was passiert wenn das Diff File von SCCS unterwegs mal kaputt geht. Aus welchen Gründen auch immer. HDD Block kaputt oder versehentlich editiert. Faktisch sollte das File dann nicht mehr herstellbar sein.

Bei git bleibt weiterhin der mit zlib komprimierte Binary Blob bestehen und alles ist gut weil wie oben der Commit auf einen binär Blob referenziert. Selbst wenn dazwischen mal ein Block eines Blobs kaputt sein sollte (oder was auch immer).

Ende

Ich möchte zum Schluss nochmal unterstreichen, dass ich in keinster Weise den Vortrag oder die Weiterentwicklung von Jörg Schilling an SCCS kritisieren will. Im Gegenteil. SCCS ist für bestimmte Einsatzzwecke bestimmt nett, eben weil es “anders” ist als git. Aber, dass SCCS in allen Punkte besser als git möchte ich nicht unterschreiben.

March 22 2012

19:16

Chemnitzer Linux Tage 2012

Mittlerweile das 3. Jahr, dass ich mich bei den Chemnitzer Linux Tagen habe blicken lassen. Wie immer war alles sehr super, klasse organisiert (dickes Kompliment an die Orga) und interessant :)

Kurze Review der Vorträge

  • Penetration Testing mit MetaSploit MetaSploit ist angeblich mit 1,2 Mio. Zeilen das größte gepflegte OpenSource Ruby Projekt. Wohl wegen den Zig Plugins :)

  • Der Systemaufruf und was danach passiert Ein bisschen was zu SysCalls unter Linux und Unix. Folien waren leider nur begrenzt lesbar wegen gelber Schrift auf weissem Grund. Ansonsten viel C Beispiele.

  • strace für Bash Versteher strace benutzen um Bash Probleme zu debuggen? Einwandfrei. Manchmal etwas überzogen gleich zu strace zu greifen, aber ansonsten super, da ich bisher wenig mit strace gemacht hatte.

  • Mit OpenStack zur eigenen Cloud Auch nett gewesen. Die verschiedenen Komponenten von OpenStack mal kennenzulernen die von RackSpace und der NASA entwickelt werden.

  • Ursprünge der Versionsverwaltung und Revival von SCCS Den Folien habe ich nichts hinzuzufuegen. Ganz besonders nicht Seite 36. Aber ich habe schon wieder Schaum vorm Mund, wenn ich dran denke. Vielleicht gibts darüber einen separaten Blogpost.

  • Bitcoin, das elektronische Geld Paar interessante Hints bei gewesen. Wenn man sich aber schonmal schlau gelesen hat war wenig neues dabei.

  • LinuXContainer in der Praxis Fand ich persönlich vortragstechnisch und inhaltlich den besten Vortrag. Bin auch schon 2 Stunden am basteln damit, wenn ich schonmal Urlaub habe.

March 08 2012

18:38

Das Ext4 Directory Indexing

Mit ext4 kam unter anderem ein Feature hinzu, welches sich Directory Indexing nennt. Es ist dazu gedacht in Verzeichnissen mit vielen Dateien eine Art Map anzulegen an welchen Inodes welche Files liegen und kommt erst ab Fileanzahl X pro Directory automatisch dazu. Ziel der Entwickler war natürlich Performance Gewinn.

Allerdings kauft man mit diesem Feature auch eine zusätzliche Limitierung mit ein, bei der ich mich schwer tat wirklich (aufgrund in meiner Wahrnehmung mangelnder Berichte und Doku) das Problem zu debuggen.

Die Limitierung bei vielen Files sind in den meisten Fällen erstmal die Inodes der Platte. Ist die Platte aber ausreichend groß (oder die Inodes ausreichend klein) kommt hier das Directory Indexing ins Spiel:

1
EXT4-fs warning (device /dev/sdd): ext4_dx_add_entry: Directory index full!

Rsyncs bzw. Schreibende Zugriffe in das Verzeichnis brechen ab und im dmesg findet man obige Meldung. Problem dabei: In dem Directory Index sind so viele Files gelistet, dass in dem (wahrscheinlich FS Designtechnisch limitierten, korrigiert mich bitte) Hashmap Block kein Platz mehr ist. Es können schlicht und ergreifend keine neuen Einträge hinzugefügt werden.

Was jetzt?

Längeres wälzen von Dokumentation lässt sich nicht vermeiden.

A linear array of directory entries isn’t great for performance, so a new
feature was added to ext3 to provide a faster (but peculiar) balanced tree keyed
off a hash of the directory entry name. If the EXT4_INDEX_FL (0x1000) flag is
set in the inode, this directory uses a hashed btree (htree) to organize and
find directory entries.

Ext4 Disk Layout, ext4.wiki.kernel.org

Oder auch andere schaurige Threads aus Mailinglisten:

http://www.mail-archive.com/cwelug@googlegroups.com/msg01937.html

Mit debugfs lassen sich die Informationen des Filesystems auszulesen, die einen interessieren. Basic Problematik ist einfach, welches Verzeichnis ist betroffen, wie konnte das passieren und wie bekomme ich es wieder heile.

1
2
3
4
5
6
7
8
9
$ cd /var/
$ debugfs
debugfs> open /dev/sdd1
debugfs> cd log/
debugfs> htree .
[...]
Number of Entries (count): 508
Number of Entries (limit): 508
[...]

htree listet die Indexes in dem Ordner und Informationen zum hashed B-Tree. Die Limit und Count Values sprechen denke ich für sich.

Okay. Problem gefunden. Wie beheb ich es?

Man baut den Directory Index neu auf, wobei der alte Dir Index prinzipiell behalten wird und der Neue an der letzten Stelle auf den weiteren Index referenziert.

1
fsck.ext4 -yfD /dev/sdd1

Dazu ist ein unmounten zwingend erforderlich, was bei produktiven Systemen unschön ist. Oder man löscht das Verzeichnis.

Wie sich später herausgestellt hat war die Ursache davon ein nicht korrekt funktionierendes Logrotate welches ca 8 Mio. Files produziert hat. Das Löschen hat auch nur ca. 10 Tage gedauert. Nur so am Rande.

Irritiert.

Zum Abschluss muss ich sagen bin ich etwas.. irritiert. Man schafft ein Feature, dass dann einspringt wenn es viele Files werden (bei meinen Tests ab 300.000 Files), welches dann später wegen diesen vielen Files zu fehlern führt. In dem Bereich dazwischen ist das eventuell wirklich nett zu haben, weil Perfomance. Aber dass ich den “Referenzakt” nicht anstossen kann während das FS gemountet ist finde ich dann speziell für den HA Betrieb von Servern … fragwürdig.

Klar es ist in keinem Fall eine gute Idee mehr als 2 Mio. files in ein Verzeichnis zu legen, aber hey.

Wirklich gestört hat mich eher das mangelhaft Dokumentierte Vorgehen dafür. Seitens Entwickler, seitens Community. Aber deswegen hab ich ja jetzt diesen Post verfasst.

March 05 2012

20:22

Switched to Octopress

Hatte von Octopress gelesen. Dann nochmal im k4cg drüber gesprochen. Irgendwie. So halb und anschliessend für super befunden.

Ich weiss nicht warum, aber irgendwie hat mich das Thema dann einfach nicht mehr los gelassen. Hier probiert, da gemacht. Das Ende vom Lied war dann, dass ich ein fast vollstänidg migriertes Blog in Octopress lokal gebaut hatte. Dann wars auch schon egal und ich hab mein Wordpress eingestampft.

Eigentlich ging alles ganz fix.

  • Ruby 1.9.2 via rvm installiert
  • Die Anleitung auf octopress.org befolgt
  • In Wordpress Inhalte in wordpress.xml exportiert
  • Dem Konvertierungstool exitwp vorgeworfen
  • Alles in source/_posts platziert
  • wordpress.xml nach [Disqus.com] hochgeladen
  • Viele sed/awk Spielchen für die richtigen ImagePfade und Code Block Formattierung betireben
  • Deployed auf Webserver
  • Apache Redirects für alte Posts eingerichtet

Lediglich das umgemappe und durch die Gegend redirecte war müßig. Aber naja. Jetzt ist schön und auch schon umgezogen. Mir gefällts.

Was mir bei der Recherche noch aufgefallen ist:

The <center> element is deprecated in HTML4 since 1998. Just use CSS to make it
or its wrapper a block element with a fixed width and margin: 0 auto

BalusC, Stackoverflow

WTF. Ich habe ca. 7 Jahre danach das erste mal ein Buch gelesen, dass sich mit HTML beschäftigt und es war dort schon deprecated. Das war mir nicht klar.

March 03 2012

noqqe
16:13
if [ $KEYWORDCOUNT -lt 25 ]; then
    alert_page()
fi

So doof sind die nicht :/

January 22 2012

14:09

MySQL | Table Migration zu InnoDB

Ich durfte letztens einer schönen Schulung zum Thema MySQL lauschen. Dabei kam viel herrum. Ein Teil davon hat sich mit verschiedenen Storage Engines beschäftigt.

Ich habe mich entschieden den Großteil meiner Datenbanken zu InnoDB umzuwandeln. Welche Vor- und Nachteile das hatt sollte sich jeder vorher klarmachen. Stichwort: ACID und Fulltext-Search. Natürlich könnte man einfach mit ALTER arbeiten. Aber ich wollte nicht umbedingt die alten MyISAM Tables noch im FS liegen haben. Also alle Datenbanken droppen und den geänderten Dump wieder einspielen, sodass die Tables neu (mit InnoDB) angelegt werden.

Zuersteinmal eine Liste mit den generieren mit den Datenbanken die man Bearbeiten möchte. Es ist zu beachten, dass man den mysql Table selbst nicht auf InnoDB umstellen möchte.

1
mysql -u root -p -e "show databases;" -N --batch | grep -v ^information_schema$ | grep -v ^mysql$

Die Liste der Datenbanken wird nachher noch hilfreich sein. Danach will man wahrscheinlich erstmal alle Dienste beenden, die auf dem MySQL zugreifen (Apache, Tomcat, whatever). In der my.cnf habe ich dann folgende Optionen für die InnoDB spezifiziert.

1
2
3
4
5
6
7
defaulot-storage-engine = InnoDB
innodb_buffer_pool_size = 16M
innodb_additional_mem_pool_size = 2M
innodb_log_file_size = 5M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50

Anschliessend den Dump erstellen und alle ENGINE=MyISAM durch InnoDB ersetzen:

1
2
mysqldump -u root -p > all-databases.sql
sed -i -e 's#ENGINE=MyISAM#ENGINE=InnoDB#g' all-databases.sql

Vorsicht. Hier ist mysql als Datenbank mit gedumped! Mir ist dabei keine wirklich einfache Zeile eingefallen die mit Suche/Ersetze Spielchen mysql ausschliesst. Es gibt bei mysqldump die Option “–ignore-table=” aber auch hier hätte ich jeden mysql Table einzeln nennen müssen. Ich hab die Datenbank dann einfach per hand aus dem Dump herausgelöscht.

Außerdem sollte man seinen Datenbank Dump nach FULLTEXT durchsuchen, da dieser von InnoDB nicht unterstützt wird. In meinem Fall hat es nur ein altes Forum das niemand mehr benutzt betroffen, weshalb ich die Zeile einfach löschen konnte.

1
grep "FULLTEXT" all-databases.sql

Um jetzt alle Datenbanken zu droppen hab ich mir folgende Line gebastelt:

1
for x in $(mysql -u root -phierstehteinpasswort -e "show databases;" -N --batch | grep -v ^information_schema | grep -v ^mysql$) ; do mysql -u root -phierstehteinpasswort -e "drop database $x ; " --batch  ; done

Nach der Bearbeitung kann man den Dump mit der neuen Engine für die Tables wieder einspielen:

1
mysql -u root -p < all-databases.sql
13:09

MySQL | Table Migration zu InnoDB

Ich durfte letztens einer schönen Schulung zum Thema MySQL lauschen. Dabei kam viel herrum. Ein Teil davon hat sich mit verschiedenen Storage Engines beschäftigt.

Ich habe mich entschieden den Großteil meiner Datenbanken zu InnoDB umzuwandeln. Welche Vor- und Nachteile das hatt sollte sich jeder vorher klarmachen. Stichwort: ACID und Fulltext-Search. Natürlich könnte man einfach mit ALTER arbeiten. Aber ich wollte nicht umbedingt die alten MyISAM Tables noch im FS liegen haben. Also alle Datenbanken droppen und den geänderten Dump wieder einspielen, sodass die Tables neu (mit InnoDB) angelegt werden.

Zuersteinmal eine Liste mit den generieren mit den Datenbanken die man Bearbeiten möchte. Es ist zu beachten, dass man den mysql Table selbst nicht auf InnoDB umstellen möchte.

mysql -u root -p -e "show databases;" -N --batch | grep -v ^information_schema$ | grep -v ^mysql$

Die Liste der Datenbanken wird nachher noch hilfreich sein. Danach will man wahrscheinlich erstmal alle Dienste beenden, die auf dem MySQL zugreifen (Apache, Tomcat, whatever). In der my.cnf habe ich dann folgende Optionen für die InnoDB spezifiziert.

defaulot-storage-engine = InnoDB
innodb_buffer_pool_size = 16M
innodb_additional_mem_pool_size = 2M
innodb_log_file_size = 5M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50

Anschliessend den Dump erstellen und alle ENGINE=MyISAM durch InnoDB ersetzen:

mysqldump -u root -p > all-databases.sql
sed -i -e 's#ENGINE=MyISAM#ENGINE=InnoDB#g' all-databases.sql

Vorsicht. Hier ist mysql als Datenbank mit gedumped! Mir ist dabei keine wirklich einfache Zeile eingefallen die mit Suche/Ersetze Spielchen mysql ausschliesst. Es gibt bei mysqldump die Option “–ignore-table=” aber auch hier hätte ich jeden mysql Table einzeln nennen müssen. Ich hab die Datenbank dann einfach per hand aus dem Dump herausgelöscht.

Außerdem sollte man seinen Datenbank Dump nach FULLTEXT durchsuchen, da dieser von InnoDB nicht unterstützt wird. In meinem Fall hat es nur ein altes Forum das niemand mehr benutzt betroffen, weshalb ich die Zeile einfach löschen konnte.

grep "FULLTEXT" all-databases.sql

Um jetzt alle Datenbanken zu droppen hab ich mir folgende Line gebastelt:

for x in $(mysql -u root -phierstehteinpasswort -e "show databases;" -N --batch | grep -v ^information_schema | grep -v ^mysql$) ; do mysql -u root -phierstehteinpasswort -e "drop database $x ; " --batch ; done

Nach der Bearbeitung kann man den Dump mit der neuen Engine für die Tables wieder einspielen:

mysql -u root -p < all-databases.sql

January 08 2012

13:47

GNU Parallel

Vom GNU Parallel Projekt habe ich vor einiger Zeit in der Arbeit so am Rande etwas mitbekommen. Nachdem ich mir die gute Dokumentation etwas angeschaut habe, hab ich Lust bekommen das mal selbst auszuprobieren.

Ich dachte es wäre eine gute Idee einfach ein paar md5 Summen zu bilden.

1
2
3
4
$ time seq 1 10000 | parallel 'echo {}| md5sum &> /dev/null '
real  0m20.102s
user  0m35.082s
sys   0m24.918s

Nun. Ich bilde nicht so oft 10.000 md5 Summen. War das jetzt viel? Oder wenig? Um einen Vergleichswert zu haben sollte ich wohl auch mal nachsehen, wie das ohne Parallel so aussieht.

1
2
3
4
$ time for x in $(seq 1 10000); do echo $x | md5sum &> /dev/null; done
real  0m13.504s
user  0m2.368s
sys   0m3.948s

Ziemlich seltsam. Obwohl ich 10.000 md5 Summen gebildet habe war die sequenzielle Methode schneller als die Parallele. Zumindest dachte ich zu dem Punkt noch das es seltsam ist. Aber an was lag das. Ich hab mir dann überlegt ob ich nicht vielleicht doch noch eine andere Aufgabe als md5 Summenbildung abbilden sollte. Ich entschied mich dazu 1000 mal eine 100.000 Zeichen lange Zeichenkette durch gzip zu schubsen.

1
2
3
4
$ time seq 1 1000 | parallel 'cat /dev/urandom | head -c 100000 | gzip &> /dev/null'
real  0m7.845s
user  0m4.064s
sys   0m20.485s

7 Sekunden. Sieht eigentlich ganz nett aus. Und in der Schleife sequenziell?

1
2
3
4
$ time for x in $(seq 1 1000); do cat /dev/urandom | head -c 100000 | gzip &> /dev/null; done
real  0m31.869s
user  0m8.301s
sys   0m33.658s

Okay. Jetzt weiss ich, das GNU Parallel eher was für (rechen-)intensivere Aufgaben ist als für viele kleine Prozesse. Anscheinend braucht das Parsing des zusätzlichen Binaries doch etwas zu lange um einen Prozess zu ordnen der sowieso nach sehr kurzer Zeit wieder beendet ist. Alles in allem gefällt mir GNU Parallel aber sehr gut wenn man weiss für was man es einsetzen muss :)

12:47

GNU Parallel

Vom GNU Parallel Projekt habe ich vor einiger Zeit in der Arbeit so am Rande etwas mitbekommen. Nachdem ich mir die gute Dokumentation etwas angeschaut habe, hab ich Lust bekommen das mal selbst auszuprobieren.

Ich dachte es wäre eine gute Idee einfach ein paar md5 Summen zu bilden.

$ time seq 1 10000 | parallel 'echo {}| md5sum &> /dev/null '
real 0m20.102s
user 0m35.082s
sys 0m24.918s

Nun. Ich bilde nicht so oft 10.000 md5 Summen. War das jetzt viel? Oder wenig? Um einen Vergleichswert zu haben sollte ich wohl auch mal nachsehen, wie das ohne Parallel so aussieht.

$ time for x in $(seq 1 10000); do echo $x | md5sum &> /dev/null; done
real 0m13.504s
user 0m2.368s
sys 0m3.948s

Ziemlich seltsam. Obwohl ich 10.000 md5 Summen gebildet habe war die sequenzielle Methode schneller als die Parallele. Zumindest dachte ich zu dem Punkt noch das es seltsam ist. Aber an was lag das. Ich hab mir dann überlegt ob ich nicht vielleicht doch noch eine andere Aufgabe als md5 Summenbildung abbilden sollte. Ich entschied mich dazu 1000 mal eine 100.000 Zeichen lange Zeichenkette durch gzip zu schubsen.

$ time seq 1 1000 | parallel 'cat /dev/urandom | head -c 100000 | gzip &> /dev/null'
real 0m7.845s
user 0m4.064s
sys 0m20.485s

7 Sekunden. Sieht eigentlich ganz nett aus. Und in der Schleife sequenziell?

$ time for x in $(seq 1 1000); do cat /dev/urandom | head -c 100000 | gzip &> /dev/null; done
real 0m31.869s
user 0m8.301s
sys 0m33.658s

Okay. Jetzt weiss ich, das GNU Parallel eher was für (rechen-)intensivere Aufgaben ist als für viele kleine Prozesse. Anscheinend braucht das Parsing des zusätzlichen Binaries doch etwas zu lange um einen Prozess zu ordnen der sowieso nach sehr kurzer Zeit wieder beendet ist. Alles in allem gefällt mir GNU Parallel aber sehr gut wenn man weiss für was man es einsetzen muss :)

January 07 2012

noqqe
11:00
5777_7018
that's it. another childhood story which I'll never watch again.
Reposted fromszarrukin szarrukin viaTheoRettich TheoRettich

December 27 2011

noqqe
20:53
9790_5e78
Reposted frommuv muv viaawezone awezone

December 26 2011

noqqe
14:55
Reposted fromAluslaw Aluslaw viawartemal wartemal
Older posts are this way If this message doesn't go away, click anywhere on the page to continue loading posts.
Could not load more posts
Maybe Soup is currently being updated? I'll try again automatically in a few seconds...
Just a second, loading more posts...
You've reached the end.