Lightroom und CMYK Softproof

On 13. 06 2016, in Clients, by Raptor 2101

Seit Lightroom 6.0 werden CMYK ICC Profile unterstütz. Bei meinen Versuchen die SAAL-Digital ICC Profile für eine SoftProof zu laden schlugen jedoch alle fehl. Die Profile werden einfach nicht zur Auswahl gestellt.

Ich weiß nicht ob es an Lightroom oder Windows liegt, aber CMYK Profile aus den „default“-Profile-Pool (Windows/System32/spool/drivers/color/) werden nicht geladen. Adobe Lightroom scheint aber noch einen anderen Ordner zu nutzen:

AppData/Roaming/Adobe/Lightroom/Color Profiles/

Alle darin abgelegten Profile werden gesondert in der ProfilAuswahl beim SoftProof angezeigt und können geladen werden. Blöd nur, das man sie nicht brauchbar filtern kann, aber das wird Adobe sicher mit dem nächsten kostenpflichtigen Update lösen …

Tagged with:
 

Convert Certifikat für Android

On 13. 06 2016, in Clients, by Raptor 2101

Wer mal eben ein normales PEM Certifikat (samt Key und CA File) für Android aufbereiten will, macht das via OpenSSL wie folgt.

openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in certificate.crt -certfile CACert.crt
Tagged with:
 

CineS2 Treiber „OnTheFly“ laden

On 13. 06 2016, in Wissenswertes, by Raptor 2101

Wer wie ich eine CineS2 6.5 im einsatz hat, ist unter Ubuntu ein bisschen gekniffen. Der Treiber wird noch nicht mit dem offizjellen Kernel ausgeliefert. Das führt dazu das man leider auf einem Produktivsystem etwas selber bauen muss. Besonders nach einem Kernel Update nerft das ganze, da man den Treiber im laufenden Betrieb überschreiben muss.

Als erstes brauch man git. Via git clone oder gut pull von https://github.com/DigitalDevices/dddvb die neusten Sourcen downloaden.

Erst mal den alten Treiber „entladen“ (fals man noch weitere DVB-Karten hat müssen deren Treiber auch entladen werden)

sudo rmmod ddbridge
sudo rmmod dvb_core
sudo rmmod cxd2099

anschließend geht es ans bauen

make clean
make -j 8
sudo make install

Treiber wieder laden …

depmod -a
modprobe ddbridge

So geht es auch ohne Neustart …

Tagged with:
 

Kodi und „fehlende“ Visualisierung

On 11. 03 2016, in Kodi, by Raptor 2101

Im neuen Kodi Pakage,das über das PPA des XBMC/Kodi Team verteilt wird, sind die Visualisierungen in eigene Sub-Pakages ausgelagert. Will man also die Balken während des Abspielens von Musik, muss man erst mal die fehlenden Pakages nachinstallieren.

apt-get install kodi-visualization-spectrum
apt-get install kodi-visualization-projectm
apt-get install kodi-visualization-goom
apt-get install kodi-visualization-shadertoy
apt-get install kodi-visualization-waveform

Wenn man nun Kodi startet und die Visualisierungen auswählbar sind, aber nicht dargestellt werden muss man ins log schauen. Dort taucht dann folgende Meldung auf:

ADDON: Could not locate visualization.spectrum.so
...
ADDON: Could not locate visualization.projectm.so
...
ADDON: Could not locate visualization.goom.so

Die Addon-Pakages werden nicht mehr in den Kodi-Path entpackt, sondern nach „/usr/lib/x86_64-linux-gnu/addons“. Kodi selbst prüft diesen Pfad nicht. Nun kann man mit der Path-Variable rummspielen oder einfach ein Symbolik Link setzten …

ln -s /usr/lib/x86_64-linux-gnu/addons/* /usr/lib/kodi/addons/
Tagged with:
 

Interface geht sporadisch down …

On 9. 12 2015, in Netzwerk, by Raptor 2101

Frei nach dem Motto „wenn man nichts zu sagen hat, …“ ist es hier in letzter Zeit sehr ruhig gewesen. Meine IT zu Hause läuft einfach zu rund, es gibt nichts zu Berichten. Nun ja bis heute…

Seit geraumer Zeit läuft auf meinem StorageServer ein TV Headend. Das lief bis vor kurzem Problemlos. Nur seit ein paar wochen plagen mich kurze Verzögerungen/Aussetzer. Anfangs konnte ich das auf einen schlechten SAT Empfang schieben aber immer gehäufter traten folgende Fehlermeldungen in den Logs auf:

igb: eth0 NIC Link is Down
igb: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX

Das eth-Interface geht Down und kommt sofort wieder hoch. Fast alle Protokolle und Dienste (NFS, SAMBA,…) scheinen damit gut klar zu kommen nur TV Headend goutiert das mit einem Connection-Reset und am Client sieht man „negative Auswirkungen“.

Davon abgesehen, warum geht das Interface unmotiviert down. Kurze Analyse später, das passiert häufiger: 2-5 mal am Tag. Meine postulierte Verfügbarkeit von 99.999% war dahin. Es folgten 2 Wochen Fehlersuche:

  • Kabel tauschen
  • Interface tauschen
  • Verschiedene Switcheinstellung (Powersave) abgeschaltet…
  • div. Optionen testen
  • vieles mehr …

Dank des sporadischen Auftretens hieß es nach jeder Änderung Stunden warten …

Ein Switch Tausch brachte die nötigen Hinweis. Der eigentliche Switch konnte als Fehlerquelle ausgeschlossen werden, da der Fehler auf allen Ports auftrat aber immer nur, wenn an dem Port mein Server hing. Alle anderen Geräte wiesen diese Disconnects nicht auf. An dem „notfall“-Switch traten die Disconnects aber auch nicht auf, die OnBoard-Netzwerkkarten waren also auch nicht defekt.

Schnell nochmal alle Switch-Einstellungen kontrolliert und dann die kryptische Option IEEE802.3az gefunden. Google angeworfen und geflucht.

IEEE802.3az (oder Energy Efficient Ethernet/EEE) ist eine Powersaving-Option (die Sinnigerweise nicht unter Powersaving aufgeführt wurde …) bei der zwei Geräte untereinander aushandeln ob und wann sie ihre Transmitter am Interface abschalten. Das erklärte auch das Fehlerverhalten. Immer wenn ich einen Lasttest gefahren hab, trat das Problem nicht auf, da EEE nicht zugeschlagen hat. Erst wenn nur Sporadisch Bandbreite benötigt wurde, kam es zu Disconnects.

Der erste Versuch EEE vie ethtool abzuschalten brachte keine Besserung:

ethtool --set-eee eth0 eee off

Erst als am Switch EEE für den ServerPort abgeschaltet wurde verschwand das Problem.

Tagged with:
 

HOWTO: Deadlocks vermeiden

On 18. 08 2014, in TSQL, by Raptor 2101

Vorwort

Ich hatte mal wieder das Vergnügen zu Analysieren, warum sich auf einem MSSQL Server drei unterschiedliche Applikationen im Sekundentakt mit Deadlocks blockiert haben. Die Literatur dazu ist vielfältig, hat mir im speziellen aber wenig geholfen. Daher fasse ich hier mal in einfachen Worten zusammen, wie ich die Deadlocks aufgelöst habe. Das Ganze hat keinen Anspruch auf Vollständigkeit oder korrektes „Wording“.

Voranalyse

Deadlocks können immer auftreten und stellen normalerweise kein Problem dar (fehlertolerante Anwendungen vorausgesetzt). Zu Problemen kommt es bei gehäuften auftreten. Die Erkennung und Behandlung von Deadlocks kostet einfach Zeit. Im „schlimmsten“ Produktivfall dauerte es über 10 Sekunden bis ein Deadlock in der Anwendung aufschlug.

Wenn gleichzeitig mehrere Deadlocks auftreten, muss man diese nacheinander „auflösen“. Wenn man „Glück“ hat, lösen sich „Folgedeadlocks“ gleich mit auf. Um das „richtige“ Deadlock zu finden unterteile ich die Deadlocks in zwei Klassen:

  • Ablauf-Deadlock: der klassische Fall. Ein Begin Transation und Commit sind nötig. Diese gehe ich meistens erst im zweiten Schritt an.
  • Zugriffs-Deadlock: Diese Deadlocks werden dadurch verursacht wie dar SQL-Server auf die Daten zugreift. Immer wenn ein Entwickler sagt „Der gleiche Code produziert unter Oracle keine Deadlocks“, hat man so einen Kandidaten. Meistens kann man diese ohne größere Eingriffe in die Applikation auflösen.

Zuverlässiger erkennt man diese Zugriffs-Deadlocks jedoch an dem beteiligten QueryPlan. Dazu muss man wissen das der SQL-Server jedes Statement mit einer eigenen Transaction „sichert“ um konsistent auf die Datenbestände zuzugreifen. Als Konsequenz daraus folgt: man kann nicht auf Daten zugreifen (Delete, Update, Insert) ohne Locks zu erzeugen. Daraus folgt wiederum, Statements die viele IO-Ops haben (lesen, schreiben), erzeugen auch viele Locks, die Chance auf ein Deadlock steigen.

Konkret: Es wird folgendes Statement ohne explizite Transaktion von mehreren Prozessen konkurrierend ausgeführt.

UPDATE test_table SET date_value= @Date WHERE name= @Name

In der Theorie (und bei Oracle) darf hier nie ein Deadlock auftreten. Im schlimmsten Fall aktualisieren alle Prozesse die gleichen Rows und der „letzte“ Prozess „gibt die neue Warheit vor“. Unter MS-SQL hagelt es Deadlocks. Das Statement kann nicht in eine atomare Operation umgesetzt werden. Erst müssen die zu verändernden Rows gefunden und anschließend die Änderung durchgeführt werden. Um einen konsistenten Zugriff auf die Daten zu bekommen benutzt der SQL-Server Shared Locks. Wenn die Spalte „name“ nicht indiziert ist, wird es einen FullTableScan geben. Ein SharedLock „wandert “ durch die Tabelle (und in Abhängigkeit des verwendeten Isolationslevels wieder frei gegeben), dort wo die Where-Clause matched gibt es ein UpdateLock und wenn es dumm kommt, blockieren sich dabei zwei Prozesse zu Tode.

Zusammenfassend formuliert: jede IO-Operation erzeugt ein Lock. Damit hat man gleich zwei Gründe diese zu vermeiden. Das bedeutet aber auch, dass die gleichen Maßnahmen zur Zugriffsoptimierung auch bei Deadlock-Problemen helfen können.

Statement tuning

Der erste Ansatz zielt auf die oben beschriebene IO-Ops/Lock-Problematik ab. Man lässt sich via Error Trace die Statements raus, die den Deadlocks beteiligt sind und ermittelt sich die Kandidaten mit der höchsten IO-Last (entweder aber die Cached Plans-Statistik oder über eine einfache Plananalyse). Diese Statements tuned man dann mit passenden Indizes.

Dummerweise macht einem der QueryOptimiser bei kleinen Tabellen einen Strich durch die Rechnung. Der Optimizer versucht (vereinfacht gesagt) die IO-Ops runter zu bekommen. Bei kleinen Tabellen kann es sinnvoller sein ein Full Table Scan zu machen, anstatt einen Index-Seek und Key-Lookup. Das schon ein paar mal den Tag versaut.

Ein Beispiel: Eine kleine Tabelle (nur eine Page) wird zur Kommunikation zwischen Prozessen benutzt. Ein Index ist so eingerichtet, das jeder Prozess direkt auf die ihm zugeordneten Rows zugreifen kann. Beim Auslesen der „zu verarbeitenden Werte“ müssen alle Spalten selektiert werden. Aus diesem Grund war der QueryOptimizer auf normalem Weg nicht dazu zu bringen, den Index für die Where-Bedingung zu benutzten. Ein Umstellen der Abfrage nach der Art „SELECT PrimaryKey FROM Table WHERE“ mit anschließendem „SELECT * FROM Table WHERE PrimaryKey =“, um die Nutzung des Index „sanft“ zu „erzwingen“, war nicht möglich. Es blieb nur die Möglichkeit der Applikationen eine View unter zu jubeln, die mittels WITH(INDEX ( ))-QueryHint die Nutzung des Index erzwingt. In Folge dieser Optimierung ging die IO-Last um 20% hoch und die Ausführungszeit des Statements stieg auch um wenige MilliSekunden. Der QueryOptimizer hatte also Recht, den Index nicht zu nutzen ist performanter. Mit Index-Nutzung treten jedoch keine Deadlocks mehr auf (vorher gab es mehre Deadlock alle 10 Sekunden), der Gesamtdurchsatz über die Tabelle stieg dadurch um den Faktor 10. Die höhere IO-Last war damit zu ignorieren.

Eine weitere Möglichkeit der Optimierung ist die Separierung der Indizes. Das ganze zielt in die gleich Richtung wie der Ansatz mit dem Index-Erzwingen. Man führt mehr Indizes als eigentlich nötig um zu verhindern das ein Lese-Lock auf einem Index gelegt wird, der für den Schreibzugriff benötigt wird bzw. umgekehrt, eine Änderung im Clustered-Index/RawTable soll sich nicht auf eine LeseOperation durchschlagen. Das ganze funktioniert nur wenn die beiden konkurrierenden Statements unterschiedliche Where-Clauses verwenden oder man eine Indexnutzung erzwingt.

Zugriffe und Abläufe optimieren.

Auch wenn die Entwickler es gerne leugnen, verneinen, ignorieren und unzählige Frameworks einführen und nutzen um es zu kaschieren, am Ende entscheiden sie mit ihrer Art des Zugriffs, wie gut der Datenzugriff erfolgen kann. Wenn man also alle Scan – Operationen beseitigt hat, Indizes separiert und optimiert hat und immer noch Deadlocks auftreten, ist es an der Zeit mit dem Entwickler zu Reden und die Abläufe und Datenzugriffe in der Applikation zu optimieren.

Relativ einfach sind aufzulösen sind Konstrukte der vollgenden Art: Lese N Einträge aus einer Tabelle, markiere sie, verarbeite sie und quittiere die Verarbeitung. Im schlimmsten Fall alles in einer großen Transaktion. Es kann performanter sein, nur einen Datensatz zu lesen und zu markieren (inklusive COMMIT) und anschließend in einer neuen Transaktion die Verarbeitung durchzuführen und zu Quittieren. Da man immer nur einen Datensatz sperrt, ist die Chance eine Deadlocks geringer und der Durchsatz kann steigen.

In die Kategorie „schwer zu detektieren aber einfach zu lösen“ fällt die Optimierung der Lock-Reihenfolge bzw. in welcher Reihenfolge wird welche Resource blockiert. Dies kann durch einfaches umsortieren der Statements erfolgen oder mit LockHints (UPDLOCK, XLOCK). Es kann sinnvoll sein möglichst früh als Update oder Exclusive-Lock zu holen um spätere Verklemmungen oder gar Deadlocks zu verhindern. Einmal gefunden lassen sich diese Änderung meist ohne großen Aufwand in der Applikation umsetzten.

Richtig kompliziert wird es erst bei Zugriffsoptimierung.
Eins vorweg: eine Zugriffs-Optimierung kann man auch ohne Zutun der Entwickler umsetzten. Mittels View oder „QueryPlan-Forcing“ kann man der Applikation immer die ZugriffeVariante unterschieben, die man für „optimaler“ hält. Allerdings muss man diese Optimierung bei jedem Software-Update erneut vornehmen. Sobald der Entwickler sich dieser Optimierung bewusst ist (und sie auch versteht) laufen die Updates wesentlich entspannter.

Im Kern geht es auch in dieser Kategorie den Zugriff auf Daten zu separieren. Dabei unterteilt man Vertikale und Horizontale Partitionierung.

  • Vertikale Partitionierung: Eine große Tabellen (viele Rows) wird in mehre kleine Tabellen zerlegt. Ziel ist, das die partitionen so angelegt sind, dass die Applikation nur selten mehrere Partitionen selektieren muss. Ein Beispiel für so etwas sind Auftragsdaten. In einem system gibt es meist 3 Arten von Auftragsdaten: Die Vorschau, die aktiven Aufträge und die archivierten Aufträge. Die Vorschau und die aktiven Aufträge halten sich mengenmäßig meist in grenzen, die Archivdaten explodieren hingegen meistens. Die BuisinessLogic wird aber fast immer nur die aktiven Aufträge selektieren. Selbst der Benutzer wird sich hauptsächlich um die aktiven Aufträge kümmern und nur selten auf die Archivdaten zugreifen. Die Folge: Es existieren unnötige große Indizies, die Datenzugriffe erfolgen über viel zu große Datenmengen, die Latenz geht hoch, die Chance für Deadlocks steigen. Sinniger ist es die Archivdaten von den aktiven Daten zu trennen (zwei oder drei Tabellen) und die Datenbestände ganz bewusst in der BL zu überführen (delete aus der QuellTabelle – Insert in die FolgeTabelle) und nur im Sonderfall alle Daten zu Selektieren.
  • Horizontale Partitionierung: Gerade moderne Frameworks (zb das EntityFramework) verleiten dazu Daten aus unterschiedlichen logischen Kontexten physikalisch in einer Entität abzulegen (Schlagwort: Vererbung und Discriminator). Die Folge sind „sehr Breite“ Tabellen.
    Ein Beispiel: Eine (kleine, Hobby) Autovermietung führt in einer Tabelle die Basis-Fahrzeugdaten (Baujahr, Typ, Modell …), Lebensdaten (letzter Kilometerstand, letzte Reparatur, aktueller Benutzer …) als auch (weil es so Fancy ist) die aktuellen Telemetriedaten (GPS – Speed, Coords, …). Das sind eine Reihe von Zugriffen aus unterschiedlichen Kontexten mit vollkommen unterschiedlicher Zugriffs-Art und Frequentierung.

    • Die Basis-Daten werden einmal Geschrieben, defacto nie geändert und maximal gelöscht, dafür aber sehr häufig in großen Blöcken gelesen (Auflistung der Fahrzeuge)
    • Die Lebensdaten werden regelmäßig aktualisiert und gezielt (über Fahrzeugkennung – indiziert) ausgelesen.
    • Die Telemetriedaten werden permanent (scheiß auf Datenvolumen) geschrieben und nur im Sonderfall ausgelesen.

    Das kann man (bei großen Tabellen) kaum unter einen Hut bringen. Sinnvoller ist es die Daten in unterschiedliche Tabellen Auszulagern und über „1 zu 1“-Beziehung zu verknüpfen. So schlagen die häufigen Updates nicht auf die häufigen Reads durch (und umgekehrt).

Einen Nachteil hat die gezielte optimieren jedoch. Man muss aufpassen, dass meine eine Seite nicht übervorteilt. Wenn man die Zugriffe einer Applikation stark optimiert hat (über indizies oder Zugriffsanweisungen), kann es passieren, das die konkurierende Applikation „verhungert“. Also immer beide Seite Betrachten und optimieren.

Tagged with:
 

TSQL Deadlocks tracen lassen

On 18. 08 2014, in TSQL, by Raptor 2101

Wer mal wieder beim MSSQL Server Deadlocks nachspüren muss, hat mehrere Möglichkeiten. 0ft wird der SQL Profiler empfohlen. Ich persönlich finde das ErrorTrace des SQLServers sinnvoller. Dazu muss man das Deadlock-Tracing über das folgende Statement aktivieren:

DBCC TRACEON(1204, 1222, -1)

Anschließend wird bei jedem Deadlock im ErrorLog der komplette Deadlock-Graph ausgegeben. Anders als im Profiler stehen hier aber zusätzliche Informationen zur Verfügung. Extrem nützlich dabei ist die Auflistung der beteiligte Indizes und Sperr-Objekte und die Statements die von dem Deadlock betroffen sind. Bei komplexen Statements oder StoredProcedure bekommt man so die „Line of Code“ die die Probleme verursacht.

Tagged with:
 

Eine kleine Unschönheit beim Upgrade hab ich beim NetworkManager unter xubuntu festgestellt.

Ich nutze Zertifikate um mich an meinem WLAN anzumelden (Radius). Diese setzen ein Password vorraus (anders lässt es der NM eigendlich nicht zu). Leider war das NM-Applet partou nicht in der Lage, eine ordentliche Config-File zu erzeugen, bei der das Password so hinterlegt wurde, dass das WLAN noch vor der Anmeldung verbunden werden konnte.

Dem konnte ich nur manuell beikommen. Unter /etc/NetworkManager/sysem-connections/ liegen die Config-Files. Die entsprechende Datei öffnen und manuell den passenden Parameter setzten

private-key-password=SuperSicher;)

						
Tagged with:
 

HTPC mit Ubuntu 14.04

On 18. 05 2014, in Kodi, by Raptor 2101

In den letzten zwei Wochen hab ich alle meine Rechner auf Ubuntu 14.04 umgestellt. Eine richtige Bruchlandung hab ich dabei nur bei meinem HTPC (auf Basis XBMC) erlebt. Hier eine kurze Zusammenfassung.

Da mein HTPC minimal aufgesetzt ist und keine unnötigen Dienste enthält hab ich erst mal versucht ein einfaches Upgrade aus dem System heraus zu machen. Die hätte den Vorteil gehabt, dass ich mir die folgenden 4 Stunden sparen hätte können. Das nvidia-337 Package hat das „zunichte“ gemacht. In den Trusty Sources zieht das gleich eine ganze Gnome Installation nach sich, die mir dann mein NoDM-Setup zerschossen hat und gleichzeitig die Platte gesprengt hat.

Danach folgte eine Neuinstallation. Eine stunde ging für ein fehlerhaft erstelltes USB-Image drauf, geschenkt, das ist Murphey, aber danach wurde es haarig. Unter Trusty fehlen einigen Paketen schlicht Abhängigkeiten. Ich hab 30 Minuten rumgefriemelt bis ich gemerkt habe, dass ein nodm kein xserver mehr mitinstalliert. Fehlende libraries werden auch nicht im Log erwähnt. Wozu auch ?

Hier meine manuell installierten Pakete:

  • xinit – wird von nodm benötigt
  • alsa-base/alsa-utils – für den sound
  • consolekit, pm-utils – für den shutdwon/suspend aus xbmc herraus.

Nachdem ich XBMC am laufen hatte, hat mich dann noch der „Shutdown/Suspend“ geärgert. Zum einen sind die oben erwähnten Pakete nicht installiert zum anderen wurde etwas an der Struktut geändert, so dass die Beispiele auf xbmc.org einfach nicht mehr passen.

Die korrekte polickit file sieht wie folgt aus:

[Actions for some-user]
Identity=unix-user:some-user
Action=org.freedesktop.upower.*;org.freedesktop.consolekit.system.*;org.freedesktop.udisks.*;org.freedesktop.login1.*
ResultAny=yes
ResultInactive=no
ResultActive=yes

Wichtig ist die Angabe org.freedesktop.login1.*. Die kann auf Suspend udn Hibernate auch eingeschränkt werden.

Danach lief mein HTPC wieder wie vor der Migration.

Tagged with:
 

PulseAudio Intel HDA 898 Soundfehler

On 9. 05 2014, in Clients, by Raptor 2101

Bei Nutzung einer  Intel HDA (CODEC Realtek HDA 898) Soundkarte unter Ubuntu (PulseAudio) kommt es häufig zu Knacken im Sound. Dies wird durch zu häufige bzw. bogey JackDetection verursacht. Um der Sache Herr zu werden braucht man aus dem „alsa-tools-gui“ Paket das tool „hdajackretask“.

 

Dort kann man unter „advanced“ die JackDetection einzeln abschalten und hat endlich ordentlichen Sound.

Tagged with: