Forgot sudo during vim editing ?
Not a problem anymore:
:w !sudo tee %
Means exactly: pipe current buffer to tee. "%" reffers to the currently edited filename
XBMC AT3IONT setup
This post is more of a reminder for myself than a full intstruction on every configuration detail of XBMC and AT3IONT-DELUXE motherboard. There is some magic which needs to be done when using the HDMI output with XBMC. To avoid some slight graphic glitches a proper modes must be listed in the xorg display configuration, additionally the provided remote controll does not fully work and is not customisable with the default driver. Lets go with all the details one by one.
Installing the system
For HPTC I use arch linux - its fast, sleek and small and gives a needed flexibility. I wont describe the installation itself since its obvious - one thing that needs to be said is to choose a minimal number of packages. After the installation has been finished we need to do:
- adduser player
- add player user to groups: disk, wheel, network, video, audio,optical,storage,power,users,dbus,usbmux
- pacman -Suy # update the system
- pacman -S xorg-server xorg-utils xorg-xinit xorg-xclock xorg-twm
- pacman -S nvidia # valid only in my case
- pacman -S xbmc vlc mplayer
- pacman -S udisks upower consolekit dbus vdpau-video libvdpau udisks upower acpid alsa-plugins alsa-tools mesa freegluts sdl libxv libsamplerate ffmpeg openssh
- Setup networking in rc.conf (I use static IP to speed up the booting)
interface=eth0 address=192.168.1.4 netmask=255.255.255.0 broadcast=192.168.1.255 gateway=192.168.1.1
And add a DNS in resolv.conf
domain cnet search cnet nameserver 192.168.1.1
- Setup nfs client (since the network media shares will be mounted from external server)
- pacman -S nfs-utils
- Edit fstab and add all Your network shares + create mountpoints for them
- Add rpcbind and netfs to rc.conf daemons
DAEMONS=(hwclock @syslog-ng dbus network rpcbind @netfs @nfs-common @crond @sshd @alsa @acpid)
XBMC autostart
At this point we have the system prepared, lets proceed and configure the xbmc itself. In order to make xbmc start just after poweron we need to make the "player" user autologin and launch the X session automatically. To achieve this:
- Change the runlevel to 5 in inittab
- Modify a console getty entry in order to autologin the "player" user. Example bellow
I use tty2
c1:2345:respawn:/sbin/agetty -8 -s 38400 tty1 linux c2:2345:respawn:/sbin/agetty -a player -8 -s 38400 tty2 linux #c3:2345:respawn:/sbin/agetty -8 -s 38400 tty3 linux #c4:2345:respawn:/sbin/agetty -8 -s 38400 tty4 linux #c5:2345:respawn:/sbin/agetty -8 -s 38400 tty5 linux #c6:2345:respawn:/sbin/agetty -8 -s 38400 tty6 linux
To automatically startx entries in .bash_profile are needed
if [[ -z $DISPLAY ]] && [[ $(tty) = /dev/tty2 ]]; then exec startx # Could use xinit instead of startx #exec xinit -- /usr/bin/X -nolisten tcp vt7 fi
Finally an .xinitrc for user player must be created
exec ck-launch-session xbmc --standalone -fs
Additionally an empty file called .hushlogin may be create in /home/player in order to minimise the message produced while autologin
cd /home/player
touch .hushlogin
After a reboot we should have automatically launched xbmc. We are almost finished
Setting proper video modes
On some TV when connected directly via HDMI port you may suddenly start to observe some small glitches (the video freezes for a milisecond after some period of time). It is caused by wrong mode selected by Xorg server and the one supported by the TV. Some tweaks must be done in order to avoid such problems. Lets run X manually and determine all the modes supported by our TV
X :1 -verbose 6 > output.log 2>&1
Lets let it run for a while and the kill it. Lets search for all the modes queried by X through EDID:
grep EDID output.log | grep 1920x1080
For my TV those are
(II) NVIDIA(0): "1920x1080" : 1920 x 1080 @ 60.0 Hz (from: EDID) (II) NVIDIA(0): "1920x1080_60" : 1920 x 1080 @ 60.0 Hz (from: EDID) (II) NVIDIA(0): "1920x1080_60_0" : 1920 x 1080 @ 59.94/60 Hz (CEA-861B Format 16) (from: EDID) (II) NVIDIA(0): "1920x1080_50" : 1920 x 1080 @ 50 Hz (CEA-861B Format 31) (from: EDID) (II) NVIDIA(0): "1920x1080_30" : 1920 x 1080 @ 29.97/30 Hz (CEA-861B Format 34) (from: EDID) (II) NVIDIA(0): "1920x1080_25" : 1920 x 1080 @ 25 Hz (CEA-861B Format 33) (from: EDID) (II) NVIDIA(0): "1920x1080_24" : 1920 x 1080 @ 23.97/24 Hz (CEA-861B Format 32) (from: EDID) (II) NVIDIA(0): "1920x1080_60i" : 1920 x 1080 @ 59.94/60 Hz (CEA-861B Format 5) (from: EDID) (II) NVIDIA(0): "1920x1080_50i" : 1920 x 1080 @ 50.0 Hz Interlace (from: EDID)
Those must be added to the xorg.conf in order to force XBMC to use them. The most relevant ones are those with fractional refresh rate. My final /etc/X11/xorg.conf.d/10-monitor.conf will look the following way
cat /etc/X11/xorg.conf.d/10-monitor.conf Section "Monitor" Identifier "Monitor0" EndSection Section "Device" Identifier "Device0" Driver "nvidia" #Choose the driver used for this monitorOption "NoLogo" "true"Option "DynamicTwinView" "false" Option "NoFlip" "false" Option "FlatPanelProperties" "Scaling = Native" Option "ModeValidation" "NoVesaModes, NoXServerModes" Option "UseDisplayDevice" "DFP-0" Option "ModeDebug" "true" Option "HWCursor" "false"EndSection Section "Screen" Identifier "Screen0" #Collapse Monitor and Device section to Screen section Device "Device0" Monitor "Monitor0" DefaultDepth 24 #Choose the depth (16||24) SubSection "Display" Depth 24 Modes "1920x1080_60_0" "1920x1080_24" "1920x1080_30" EndSubSectionEndSection
Additionally configuration inside XBMC must be adjusted, you want to set "Render method" to Auto, "Use pixel buffer objects" to On, "Adjust display refresh..." to On, "Sync playback to display" to On, A/V sync method to "Audio" and "Vertical blank sync" to Always. Inside the nvidia-settings also some adjustments must be done. Find and enable those settings:
- SyncToVBlank
- Allowflipping
- FSAAAppControlled
- OpenGLImageSettings=3
- GPUScaling[DFP-0]=1,1
- Disable the LogAniso
This can be also adjusted through the command line
export DISPLAY=:0; nvidia-settings -a "SyncToVBlank=1" -a "AllowFlipping=1" -a "FSAAAppControlled=1" -a "OpenGLImageSettings=3" -a "LogAniso=0" -a "GPUScaling[DFP-1]=1,1"; nvidia-settings -r
To test if everything is working fine use the following script in the X session
for i in 24 60; do xrandr -r $i; nvidia-settings -q RefreshRate | grep -o "[0-9][0-9].*Hz"; done
If it will display correctly 23,97 and 59,94 then we are good to go, otherwise the configuration must be revised again
We are almost finished, additionally the HDMI sound must be configured and the remote control in order to use the additional buttons.
Setting HDMI sound
By default the sound is routed via analog output in order to set it via the HDMI we must get our hands dirty in some mixer settings.
- In alsamixer unmute the SPDIF/1 output
- Save alsa settings in order to make them persistent: alsactl store
pcm.!default {
type plug
slave.pcm "dmix:0,3"
rate 48000
}
Now the sound configuration should be adjusted inside XBMC. Output device: hdmi, passthrough device: hdmi
Setting the remote controll
By default the remote is visible as a standard hid device and some of its buttons are mapped to the keyboard keys. Not all of them work unfortunately, like powerbutton etc. Thanks to the community there is a driver available which lets you customize the remote buttons and utilize them all. It is available as a deb package
In order to use it in ARCH we must unpack it:
ar xv asus-at3iont-i-deluxe-dkms_1.0.1_all.deb
a file called data.tar.gz should be available now, lets unpack it and go to the driver itself:
cd usr/src/asus-at3iont-i-deluxe-1.0.1/drivers/hid-philips-asus
There is a file called mapping.h which must be adjusted accordingly to Your needs, after this is done the driver needs to be compiled to do this we need linux-headers and gcc of course:
- pacman -S gcc make linux-headers
- make
- make install
#!/bin/bash
. /etc/rc.conf
. /etc/rc.d/functions
case "$1" in
start)
stat_busy 'Loading the Philips HID module'
rmmod usbhid
modprobe hid-philips-asus
modprobe usbhid
;;
stop)
stat_busy 'Unloading Philips HID'
rmmod hid-philips-asus
rmmod usbhid
modprobe usbhid
;;
restart)
$0 stop
sleep 1
$0 start
;;
*)
echo "usage: $0 {start|stop|restart}"
esac
exit 0
DAEMONS=(hwclock @syslog-ng dbus network rpcbind @netfs @nfs-common @philips-hid @crond @sshd @alsa @acpid)
# /etc/acpi/events/power
# This is called when the user presses the power button event=button/power (PWR.||PBTN) action=/sbin/poweroff
pacman -Rc gcc make # since they wont be needed anymorepacman -Scc
git: deleting remote branch
If for example You create and push a branch which is not desired to exist in the remote repository it can be easilly fixed:
git checkout -b test origin/tests
... do some work ...
git push origin test
// This will create a remote branch test which is not desired since we want our changes to be placed on top of "tests", to delete test in the remote repo:
git push origin :test
// its deleted now, to delete it locally:
git branch -d test
Duplicating a MySQL Database
When developing some of the typical CRUD functionalities often there is a need to test if the "delete" functions work on a real dataset. In order to preserve the data and do some proper testing I often do an exact copy of my current DB on which I test my "delete/update" functions safely without destroying precious data which is stored in the original DB. To do this, you only need to do
- Create a copy DB
- Dump your current DB to the copy DB
- Change the connection details in your application to use the copy DB instead of the original one
mysqladmin create db_copy -u <youruser> -p<yourpassword>mysqldump -u <youruser> -p<yourpassword> my_db | mysql -u <youruser> -p<yourpassword> db_copy
Profiling Perl scripts
Its quite easy to determine which functions or parts of the perl script needs some performance optimisation. Perl comes with a handy profiler called DProf, its usage examples are well documented in perldoc, however I think this short description may be usefull as a short snipper encouraging to learn something more in this topic.
Lets create a trivial script consisting of 3 functions:
#!/usr/bin/perl
use Time::HiRes qw /usleep/;
sub loop_func {
my $it = $_[0] || 100;
foreach (1..$it) {
usleep($it);
}
}
sub a {
&loop_func(200);
}
sub b {
&loop_func(500);
}
sub c {
&loop_func(300);
}
&a;
&b;
&c;
We have three functions to be used directly by the end user (a, b, c). The implementation is self explaining. Lets gather some runtime information then:
$ perl -d:DProf ./prof_test.pl
This call generated a profiler report stored in file tmon.out. Lets use a tool dprofpp to extract human readable informations out of it:
$ dprofpp tmon.out dprofpp will be removed from the Perl core distribution in the next major release. Please install Devel::DProf from CPAN. Total Elapsed Time = 0.495804 Seconds User+System Time = 0.035804 Seconds Exclusive Times %Time ExclSec CumulS #Calls sec/call Csec/c Name 50.2 0.018 0.026 3 0.0060 0.0087 main::loop_func 27.9 0.010 0.010 1 0.0100 0.0098 main::BEGIN 22.3 0.008 0.008 1000 0.0000 0.0000 Time::HiRes::usleep 0.00 0.000 0.000 1 0.0000 0.0000 Time::HiRes::__ANON__ 0.00 0.000 0.000 1 0.0000 0.0000 Exporter::Heavy::heavy_export_to_level 0.00 0.000 0.000 1 0.0000 0.0000 Exporter::Heavy::heavy_export 0.00 - -0.000 1 - - DynaLoader::dl_load_flags 0.00 - -0.000 1 - - DynaLoader::dl_load_file 0.00 - -0.000 1 - - DynaLoader::dl_undef_symbols 0.00 - -0.000 1 - - DynaLoader::dl_install_xsub 0.00 - -0.000 1 - - Time::HiRes::AUTOLOAD 0.00 - -0.000 1 - - warnings::unimport 0.00 - -0.000 1 - - Exporter::Heavy::_rebuild_cache 0.00 - -0.000 1 - - Config::import 0.00 - -0.000 1 - - vars::import
From this report we see that most of the time was spent in the loop_func (obviously). We also know how many times was it called. Unfortunately our functions a,b,c are not visible in this report because they executed way to fast. Lets look on the call tree:
$ dprofpp -S tmon.out
dprofpp will be removed from the Perl core distribution in the next major release. Please install Devel::DProf from CPAN.
main::BEGIN x 1 0.01s = (0.01 + 0.00)s
Config::FETCH x 7 0.00s
DynaLoader::BEGIN x 2 0.00s = (0.00 + 0.00)s
Config::import x 1 0.00s
DynaLoader::bootstrap x 1 0.00s = (0.00 + 0.00)s
DynaLoader::dl_find_symbol x 1 0.00s
DynaLoader::dl_install_xsub x 1 0.00s
DynaLoader::dl_load_file x 1 0.00s
DynaLoader::dl_load_flags x 1 0.00s
DynaLoader::dl_undef_symbols x 1 0.00s
Time::HiRes::bootstrap x 1 0.00s
Time::HiRes::BEGIN x 3 0.00s = (0.00 + 0.00)s
strict::import x 1 0.00s
strict::unimport x 1 0.00s = (0.00 + 0.00)s
strict::bits x 1 0.00s
vars::import x 1 0.00s
Time::HiRes::import x 1 0.00s = (0.00 + 0.00)s
Exporter::export_to_level x 2 0.00s = (0.00 + 0.00)s
Exporter::as_heavy x 1 0.00s = (0.00 + 0.00)s
Exporter::Heavy::BEGIN x 3 0.00s = (0.00 + 0.00)s
strict::import x 1 0.00s
strict::unimport x 1 0.00s = (0.00 + 0.00)s
strict::bits x 1 0.00s
warnings::unimport x 1 0.00s
Exporter::export x 2 0.00s = (0.00 + 0.00)s
Exporter::Heavy::_rebuild_cache x 1 0.00s
Exporter::as_heavy x 1 0.00s
Time::HiRes::AUTOLOAD x 2 0.00s = (0.00 + 0.00)s
Time::HiRes::constant x 1 0.00s
main::a x 1 0.00s = (0.00 + 0.00)s
main::loop_func x 1 0.00s = (0.00 + 0.00)s
Time::HiRes::usleep x 200 0.00s
main::b x 1 0.02s = (0.00 + 0.02)s
main::loop_func x 1 0.02s = (0.01 + 0.01)s
Time::HiRes::usleep x 500 0.01s
main::c x 1 0.01s = (0.00 + 0.01)s
main::loop_func x 1 0.01s = (0.01 + 0.00)s
Time::HiRes::usleep x 300 0.00s
This report presents a detailed call graph with every call hierarchy including our three interesting functions a,b,c.
Detaching processes without screen with nohup and disown.
In case you started a long term running process and you forgot to do it in screen environment - have no worries, there is still a way to detach your process from currently running shell. I'll focus on two builtin shell tools (available at least in bash) usefull for job management.
A short summary
- nohup - "run a command immune to hangups, with output to a non-tty" (man nohup).
- disown - "... each jobspec is removed from the table of active jobs ... " (man bash).
nohup ./lts_job.sh
ps aux | grep lts tomasz 26701 0.0 0.1 5988 1076 pts/0 S+ 16:33 0:00 /bin/bash ./lts_job.sh tomasz 26876 0.0 0.0 5172 772 pts/1 S+ 16:37 0:00 grep --color=auto lts tomasz@hekate:~$ pstree -Ac -p 26701 lts_job.sh(26701)---sleep(26702)
init-+-Xtightvnc ... |-java---28*[{java}] |-lts_job.sh---sleep... `-xstartup---fluxbox
tomasz@hekate:~$ ./lts_job.sh & [1] 28044 tomasz@hekate:~$ jobs [1]+ Running ./lts_job.sh & tomasz@hekate:~$ disown %1 tomasz@hekate:~$ jobs tomasz@hekate:~$
tomasz@hekate:~$ pstree -A init-+-Xtightvnc |-acpid |-cron ...|-lts_job.sh---sleep... `-xstartup---fluxbox
tomasz@hekate:~$ ./lts_job.sh
tomasz@hekate:~$ ps aux | grep lts_job tomasz 28323 0.0 0.1 5988 1080 pts/0 S+ 16:51 0:00 /bin/bash ./lts_job.sh tomasz 28486 0.0 0.0 5172 776 pts/2 S+ 16:51 0:00 grep --color=auto lts_jobtomasz@hekate:~$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUSSIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX tomasz@hekate:~$ kill -19 28323
tomasz@hekate:~$ ./lts_job.sh [1]+ Stopped ./lts_job.sh
tomasz@hekate:~$ jobs [1]+ Stopped ./lts_job.sh tomasz@hekate:~$ disown %1
Chrooted ssh environment
It is always a good security habit to restrict user access which are not very trusted to any of system resources. Since openssh 5.2 (I think, but I may be corrected) there is a nice feature added called ssh chrooting. Its purpose is to jail users in some prepared jailkit so they operate in this limited environment and do not have access to actual root filesystem. Its pretty easy to configure and maintain in its simplest form, so without further a do, lets get to the point.
First we need to create a group which members will be by default chrooted when they log in.
groupadd ssh_jail
Lets create a testuser then and add it to our "jail" group:
useradd -U -M -G ssh_jail testuser
passwd testuser (set a password for the user)
Ok, we are half way through the process. Now we need to create our jail. This will be a directory containing some basic gnu environment and tools set. The root of the jail as well as all files inside (omitting the users homes) should be owned by root and have numerical access rights: 644. To prepare the jail environment I decided to use a simple tool called jailkit. It can be downloaded from here:
http://olivier.sessink.nl/jailkit/
The compilation is obvious (./configure; make; make install). Lets create the jail root:
mkdir /home/jail
chown -R root:root /home/jail
Now depending on what tools you want to provide to the jailed users you'll use apropriate jailkit enumeration. I'll decided to install:
jk_init -v /home/jail basicshell jk_init -v /home/jail editors jk_init -v /home/jail extendedshell jk_init -v /home/jail netutils jk_init -v /home/jail ssh jk_init -v /home/jail sftp
This produced a nice environment for the users which in total wieghts something around 50 MB on the disk (a small price for security). We are almost ready now. Since in /etc/passwd a home for our user is defined as "/home/testuser" (and this directory is reffering to the one in the jail) we need to create it:
mkdir /home/jail/home/testuser
chown -R testuser:testuser /home/jail/home/testuser
Ok. The environment is almost ready. Now lets inform ssh to jail users from the ssh_jail group. In /etc/ssh/sshd_config we need to add a section:
Match Group ssh_jail
ChrootDirectory /home/jail
X11Forwarding no
AllowTcpForwarding no
The last thing we need to do is to restart the sshd:
# service ssh restart (ubuntu)
# rc.d restart ssh (arch)
And to cleanup the files in the jail (since jailkit simply copied them). Remove every entry from /home/jail/etc/passwd except those for testuser as well as from /home/jail/etc/group (they are not needed, they can be additional information to the jailed users about the actual users in the system). We are now done. After logging in as a testuser we should be jailed in /home/jail.
If you observe any problems you should focus on the messages in /var/log/auth.log.
GDB: prefixing dependent libraries
To notice gdb about other libraries or binary files (on which our debugged program depends) which may contain some usefull additional symbols one has to use solib-absolute-prefix. All you have to do is:
set solib-absolute-prefix <path>
For example, if our binary is looking for some libs in /lib which are not there but instead are in /usr/lib , one needs to set solib-absolute-previx the following way:
set solib-absolute-prefix /usr
/usr now becomes a root for binary search. Additional symbols will be automatically loaded.
Reminder: Bash exit codes
| Exit Code Number | Meaning | Example | Comments |
|---|---|---|---|
| 1 | Catchall for general errors | let "var1 = 1/0" | Miscellaneous errors, such as "divide by zero" and other impermissible operations |
| 2 | Misuse of shell builtins (according to Bash documentation) | empty_function() {} | Seldom seen, usually defaults to exit code 1 |
| 126 | Command invoked cannot execute | Permission problem or command is not an executable | |
| 127 | "command not found" | illegal_command | Possible problem with $PATH or a typo |
| 128 | Invalid argument to exit | exit 3.14159 | exit takes only integer args in the range 0 - 255 (see first footnote) |
| 128+n | Fatal error signal "n" | kill -9 $PPID of script | $? returns 137 (128 + 9) |
| 130 | Script terminated by Control-C | Control-C is fatal error signal 2, (130 = 128 + 2, see above) | |
| 255* | Exit status out of range | exit -1 | exit takes only integer args in the range 0 - 255 |
GNU Screen Quick Reference
Here are most common used screen keyboard shortcuts
- ctrl a c -> create new window
- ctrl a A -> set window name
- ctrl a w -> show all window
- ctrl a 1|2|3|… -> switch to window n
- ctrl a ” -> choose window
- ctrl a ctrl a -> switch between window
- ctrl a d -> detach window
- ctrl a ? -> help
- ctrl a [ -> start copy, move cursor to the copy location, press ENTER, select the chars, press ENTER to copy the selected characters to the buffer
- ctrl a ] -> paste from buffer
How to start screen:
- screen –DR -> list of detached screen
- screen –r PID -> attach detached screen session
- screen –dmS MySession -> start a detached screen session
- screen –r MySession -> attach screen session with name MySession
- ctrl a S -> create split screen
- ctrl a TAB -> switch between split screens
- ctrl a Q -> Kill all regions but the current one.
- ctrl a X -> remove active window from split screen
- ctrl a O -> logout active window (disable output)
- ctrl a I -> login active window (enable output)