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:

  1. the native one: appletouch id=12
  2. 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:

  1. using snprintf
  2. K&R ito function from The C programming language book
  3. 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:

kcachegrind

kcachegrind

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:

  1. sprintf: 42 657 264 instructions
  2. itoa K&R: 18 137 059 instructions
  3. 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