středa 19. října 2011

Jak zatočit s login znělkou v Ubuntu

Když restartuji Ubuntu (virtuální poměrně často) v noci, nejsem z ubuntí znělky zrovna nadšen. Tím méně mé okolí. V zásadě má hlasitější projev, než cokoliv jiného, co poslouchám a vůbec nejsem příznivcem nevyžádaných zvukových projevů počítače. Ubuntu používá přinejmenším od verze 10.10 skrytý spouštěč v podobě následujícího souboru:

pondělí 17. října 2011

Cairo Dock 2.4 místo Unity Launcheru?

Před pár dny jsem restartoval  mou domácí pec (samozřejmě nedobrovolně) a po spuštění systému nereagoval Cairo Dock na můj skript, kterým přes tlačítko myši ovládám jeho viditelnost. Zároveň se nad dokem objevila notifikace o změnách v nové verzi, mezi nimiž svítilo i DBus, což dávalo tušit, kde je problém. A změna metody ShowDock konečně přinesla to, co mi v Cairo Docku chybělo hodně dlouho - přepínat mezi stavy Show/Hide. Do verze 2.4 bylo možné dok schovat, nebo zobrazit, ale už né jednoduše stav prohodit, nebo alespoň zjistit, v jakém stavu se aktuálně nachází. Nově bere metoda místo boolean parametru integer a krom jasných 0 a 1 akceptuje i číslo 2, které změní sučasný stav na opačný. Volání metody z příkazového řádku vypadá takto:

úterý 11. října 2011

Počítání sezení s ConsoleKit em

Řešil jsem problém, který spočívá v tom, že pokud je v systému přihlášeno více uživatelů než jeden, vyskočí při pokusu o vypnutí/restartování systému požadavkem na službu ConsoleKit (nevím na koho mocnějšího se obrátit :) okno, které chce akci autorizovat heslem superuživatele. Stačí se v některém terminálu přihlásit jako root pomocí příkazu sudo su (rozumnější sudo -i, sudo -s, nezakládají další session) a můj Shutdown GTimer nesplní svůj úkol. A vzhledem k tomu, že okno System policy po chvíli samo zmizí (alespoň v některých verzích Ubuntu), tak pokud není uživatel očima na monitoru, ani se nedozví proč. V nové verzi by měl být Shutdown GTimer schopen předem na tuto skutečnost upozornit. Tato systémová politika je funkční přinejmenším od Ubuntu 10.04 výš, verze 8.04, kde vypnutí systému ještě řeší HAL, toto omezení neplatí, alespoň pokud jste v rámci GNOME session přihlášeni v emulátoru terminálu jako root.

Služba ConsoleKit je správcem sezení (sessions) a tudíž je to zase ona která dodá informaci, kolik sezení je aktivních a tím zda se dá systém vypnout bez požehnání vyšší moci. Tedy služba dodá seznam, který je nutno spočítat. Šel jsem na to klasicky přes DBus, v příkazovém řádku je dotaz možno formulovat takto:

dbus-send --system --print-reply --dest=org.freedesktop.ConsoleKit /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.GetSessions | grep Session | wc -l
nebo takto (vzhledem k tomu, že pro každé sezení založí ConsoleKit uzel (node), který odkazuje na metody a signály určené pro jeho správu):
dbus-send --system --print-reply --dest=org.freedesktop.ConsoleKit /org/freedesktop/ConsoleKit org.freedesktop.DBus.Introspectable.Introspect | grep Session | wc -l

Pro ConsoleKit jsou ovšem v systému pro příkazový řádek přímo příkazy, které se používají jednodušeji a výstup je již formátován, bez xml značek. Příkaz ck-list-sessions vypíše všechna sezení, včetně jejich atributů. Z výpisu lze vyfiltrovat počet sezení takto:

ck-list-sessions | grep ^Session | wc -l

ConsoleKit toho z příkazového řádku nabízí více, můžete si třeba zkontrolovat historii sezení a zjistit, že se vám díky nedostatečně zabezpečenému ssh serveru někdo několikrát naboural do systému :D Více třeba zde:
http://wiki.ubuntu.cz/ConsoleKit 

V Pythonu to samozřejmě řeším bez shellu, ale princip je stejný, navíc tam mám možnost se pověsit na signály, které jsou ConsoleKitem generovány při přidání, či odebrání sezení a na jejich základě aktualizovat stavovou informaci. Pro další verzi Shutdown GTimeru si ale vystačím s detekcí více sezení při aktivaci odpočtu v režimu Vypnutí a Restartu, málokdo asi při tomto použití ocení upozornění o změně situace v průběhu odpočtu. Ještě mě teď napadlo, že pokud spustíte Shutdown GTimer jako root, zmíněné omezení samozřejmě neplatí a tudíž musím v kódu podchytit i tuto situaci. Tak snad brzy, první nástřely jsou již v svn.


sobota 8. října 2011

Identifikace USB disků podle typu připojení

Nedávno jsem narazil na problém jednoho uživatele, který chtěl svým dvěma nesystémovým pevným diskům změnit po startu systému přes hdparm chování, ale ty se mu pokaždé připojují jinam v /dev/sd*., a tak neví jak napsat skript, který by je přesně identifikoval. Chvíli jsem se na tím zamyslel, jak napsat nějaké univerzální řešení pro vypsání všech interních pevných disků, které zároveň nejsou systémové. Vzhledem k tomu, že na mých počítačích se nachází krom zmíněných pouze USB disky, napadlo mě tyto identifikovat podle způsobu připojení a z výpisu je vyřadit. Pak už zbývá jen identifikovat disk, na kterém běží systém. Dospěl jsem se svými znalostmi k následujícímu:

find /dev -regex /dev/sd. | while read dev; do if ! udevadm info -n $dev -q path | grep -q usb; then mount | grep -q "$dev. on / " || hdparm -S60 $dev ; fi; done

Tento příkaz nastaví diskům podle předchozí specifikace dobu pro uspání při nečinnosti na 5 minut (hdparm -S60 - 60x5 sekund=5minut). Kdyby to někdo z příkazu nepobral - find najde přípojné body všech disků, výstup se čte řádek po řádku a pro každý disk se nejprve zkontroluje ve výstupu udevadm -n zda je připojen na USB sběrnici a pokud není, další pomínka v podobě výstupu příkazu mount pošle příkaz hdparm -S60 pouze na disky, na kterých není kořenový adresář běžícího systému.

Seznam pouze USB disků pak můžete dostat takto:

find /dev -regex /dev/sd. | while read dev; do udevadm info -n $dev -q path | grep -q usb && echo $dev; done

Pokud chcete s disky cokoliv rovnou provést, nahradíte echo konkrétním příkazem, stejně jako v minulém příkladě.

Další možností by mohlo být vypsání všech připojených filesystémů USB disků i s přípojnými body, včetně parametrů:

find /dev -regex /dev/sd. | while read dev; do udevadm info -n $dev -q path | grep -q usb && mount | grep $dev; done