bedis9
a little bit of anything
Git basics
- Getting a local copy of a git project:
git clone http://git.1wt.eu/git/haproxy.git
- Rollback any update to a git branch:
git reset --hard HEAD
- Prepare a patch for your updated code:
git format-patch origin
- Print out the patch:
git diff
- Watch a patch impact on current code:
git apply --stat /path/to/patch
- Watch a patch errors on current code:
git apply --check /path/to/patch
- Apply a patch impact on current code:
git apply /path/to/patch
- Commit changes into your local project:
git commit -m "COMMIT MESSAGE"
Fix broken left click on Linux
At home, I run a debian Squeeze on my 2008 macbook.
Lately, I had an issue: when my computer woke up after a sleep period, the left click of my mouse did not work anymore.
I had to restart my X server to recover the left click.
Actually, there is some conflict between my macbook native mouse and my USB mouse.
Fortunately, in Debian (and in other distros too), there is a tool called xinput which is used to configure X window input devices.
First, list the devices available for my macbook:
$ xinput --list ⎡ Virtual core pointer id=2 [master pointer (3)] ⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)] ⎜ ↳ Microsoft Microsoft Notebook/Mobile Optical Mouse 2.0 id=10 [slave pointer (2)] ⎜ ↳ appletouch id=12 [slave pointer (2)] ⎜ ↳ Macintosh mouse button emulation id=14 [slave pointer (2)] ⎣ Virtual core keyboard id=3 [master keyboard (2)] ↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)] ↳ Power Button id=6 [slave keyboard (3)] ↳ Video Bus id=7 [slave keyboard (3)] ↳ Power Button id=8 [slave keyboard (3)] ↳ Sleep Button id=9 [slave keyboard (3)] ↳ Apple Computer Apple Internal Keyboard / Trackpad id=11 [slave keyboard (3)] ↳ Apple Computer Apple Internal Keyboard / Trackpad id=13 [slave keyboard (3)]
As you can see, I have 2 mouses on my macbook:
- the native one: appletouch id=12
- the USB one:Microsoft Microsoft Notebook/Mobile Optical Mouse 2.0 id=10
To avoid any conflict between both mouses, I simply disable the native mouse, since I don’t use it.
Simply run:
$ xinput --set-prop 12 "Device Enabled" 0
Which means that I disabled the mouse with the id 12.
Don’t forget to update your xinitrc or your autostart.sh, if you’re using openbox like me.
curl: dump header to stdout
By default, curl can only dump headers sent by the server in a file.
Sometimes, it makes sense to read them directly on stdout.
To do that, simply use the dash:
$ curl -D - www.google.fr HTTP/1.1 200 OK Date: Sat, 06 Aug 2011 08:48:39 GMT Expires: -1 Cache-Control: private, max-age=0 Content-Type: text/html; charset=ISO-8859-1 Set-Cookie: PREF=ID=f308a4d07ea555b0:FF=0:TM=1312620519:LM=1312620519:S=Yoejo_SrbhFqsIkh; expires=Mon, 05-Aug-2013 08:48:39 GMT; path=/; domain=.google.fr Set-Cookie: NID=49=tf-3o-m2n7R06k7ayk66jNgRzpPXsZ66mKuUogAKdDlYeN3drftxKZ5WeIhsYKNP2SEelOKHroIfDFsG5P3jaW7nJf4HkLR3Qa_tYUCtWD6fS8mKKVxNom6kodN4Wjbi; expires=Sun, 05-Feb-2012 08:48:39 GMT; path=/; domain=.google.fr; HttpOnly Server: gws X-XSS-Protection: 1; mode=block Transfer-Encoding: chunked [...] then comes the HTML content
parallel execution in bash
You want to run X commands in parallel from bash, just do:
$ for i in {1..X} ; do (command -arg &) ; done
Replace X by the number of command in parallel you want to run.
Optimize your code with valgrind
When writing code, whatever language you use, one of the thing you should take care is efficiency.
An efficient code is scalable, an inefficient one will be a problem in the future.
One way to see how efficient is your code is to use valgrind.
Valgrind is a framework which comes with a few profiler tools. Two of them are cachegrind and callgrind and are usefull to observe how your code is executed at CPU level.
Valgrind is available on all good linux distribution.
Example
The code
As an example, we’re going to write an “itoa” (Integer to Ascii) function in C which will turn an Integer into a char string.
The code:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/time.h> #include <sys/types.h> void reverse(char *); int itoa(int n, char *s) { char *b, c, *p; int len; p = s; if (n < 0) { *p++ = '-'; n = 0 - n; } b = p; do { *p++ = (n % 10) + '0'; } while ((n /= 10) > 0); len = (int)(p - s); *p-- = '\0'; //swap do { c = *p; *p = *b; *b = c; --p; ++b; } while (b < p); return len; } /* itoa: convert n to characters in s * K&R version */ int itoa_kb(int n, char *s) { int i, sign; if ((sign = n) < 0) /* record sign */ n = -n; /* make n positive */ i = 0; do { /* generate digits in reverse order */ s[i++] = n % 10 + '0'; /* get next digit */ } while ((n /= 10) > 0); /* delete it */ if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s); return i; } /* reverse: reverse string s in place * K&R version */ void reverse(char *s) { int i, j; char c; for (i = 0, j = strlen(s) - 1; i<j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; } } int main(void) { int i, n; char s[20]; for (i=-32768; i < 32768; i++) { // K&R n = itoa_kb(i, s); } for (i=-32768; i < 32768; i++) { // sprintf n = sprintf(s, "%d", i); s[n] = '\0'; } for (i=-32768; i < 32768; i++) { // optimized n = itoa(i, s); } return EXIT_SUCCESS; }
From this code, you can see 3 ways to write an itoa function in C:
- using snprintf
- K&R ito function from The C programming language book
- an “optimized” function based on the K&R one
Compilation
Compilation is done using gcc:
gcc -Wall -g itoa.c -o itoa
Run valgrind
Now, just run valgrind against the binary file:
$ valgrind --tool=callgrind --dump-instr=yes ./itoa ==25197== Callgrind, a call-graph generating cache profiler ==25197== Copyright (C) 2002-2010, and GNU GPL'd, by Josef Weidendorfer et al. ==25197== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info ==25197== Command: ./itoa ==25197== ==25197== For interactive control, run 'callgrind_control -h'. ==25197== ==25197== Events : Ir ==25197== Collected : 76647687 ==25197== ==25197== I refs: 76,647,687
You may have a file named callgrind.out.[[PID]] in your current directory.
Analyze the result with kcachegrind
Now run kcachegrind.
The result looks like below:
On the left tab, look at the Incl. column, the number tells the amount of instruction executed by the function.
In our itoa example, we can see the number of instructions to turn 65536 integers into strings:
- sprintf: 42 657 264 instructions
- itoa K&R: 18 137 059 instructions
- itoa: 13 654 807 instrcutions
Basically, sprintf seems not so efficient 🙂
Conclusion
Valgrind and cachegrind are useful tools to point possible issues in any code.
Then it’s up to the developer to write clean code to avoid using too many instructions where not necessary.
master/master mysql database cluster
Introduction
Setup a Master/Master MySql cluster is quite easy.
The procedure below explains you how to do it on a couple of Debian squeeze server.
Master / Master mysql setup procedure
The cluster will be built on two servers:
- server1: 192.168.10.101
- server2: 192.168.10.102
Diagram
Avoid DNS resolution
In order not to rely on external DNS server, we recommand using hosts file.
Furthermore, a host name has more meanings in a configuration file that an IP address.
Update /etc/hosts file on both server with cluster server IPs:
192.168.10.101 server1 192.168.10.102 server2
MySql configuration
MySql replication user
This user will be used to send to send updates to the other node.
On both servers, run the following command into the MySql shell:
mysql> GRANT REPLICATION SLAVE ON *.* TO 'your-slave-username'@'%' IDENTIFIED BY 'yourslavepassword'; mysql> FLUSH PRIVILEGES;
In our case, your-slave-username is repl and yourslavepassord is password.
Stop MySql
On both server, stop MySql:
service mysql stop
Update MySql configuration
Edit the /etc/mysql/my.cnf file.
1. Update the bind-address line:
- For server1:
bind-address = 192.168.10.101
- For server2:
bind-address = 192.168.10.102
2. Update the [mysqld] section:
- For server1:
# server ID in the cluster configuration server-id = 1 replicate-same-server-id=0 # Autoincrement configuration to avoid collision auto-increment-increment=2 auto-increment-offset=1 master-host = server2 master-connect-retry = 60 # Replication credential master-user = repl master-password = password log_bin = /var/log/mysql/mysql-bin.log expire_logs_days = 10 max_binlog_size = 100M relay-log=/var/lib/mysql/relay-log relay-log-index=/var/lib/mysql/relay-log.index report-host=server1
- For server2:
# server ID in the cluster configuration server-id = 2 replicate-same-server-id=0 # Autoincrement configuration to avoid collision auto-increment-increment=2 auto-increment-offset=2 master-host = server1 master-connect-retry = 60 # Replication credential master-user = repl master-password = password log_bin = /var/log/mysql/mysql-bin.log expire_logs_days = 10 max_binlog_size = 100M relay-log=/var/lib/mysql/relay-log relay-log-index=/var/lib/mysql/relay-log.index report-host=server2
Start MySql
On both server, start MySql:
service mysql start
Check the result
On both servers, connect to the MySql shell and run:
SHOW SLAVE STATUS\G;
and look for the lines Slave_IO_Running and Slave_SQL_Running: both must be set to Yes.
Conclusion
If everything worked fine, you may have a Master/Master MySql cluster.
Links
Procedure inspired by: http://blogs.dixcart.com/public/technology/2010/08/guide-to-mysql-master-to-master-replication.html