<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>sysop&#039;s blog</title>
	<atom:link href="http://maciek.lasyk.info/sysop/feed/" rel="self" type="application/rss+xml" />
	<link>http://maciek.lasyk.info/sysop</link>
	<description>Linux: the operating system with a CLUE... Command Line User Environment</description>
	<lastBuildDate>Mon, 30 Jan 2012 17:05:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>ssh_exchange_identification: Connection closed by remote host</title>
		<link>http://maciek.lasyk.info/sysop/2012/01/30/ssh_exchange_identification-connection-closed-by-remote-host/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ssh_exchange_identification-connection-closed-by-remote-host</link>
		<comments>http://maciek.lasyk.info/sysop/2012/01/30/ssh_exchange_identification-connection-closed-by-remote-host/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 17:05:23 +0000</pubDate>
		<dc:creator>docent</dc:creator>
				<category><![CDATA[ssh]]></category>
		<category><![CDATA[sshd]]></category>

		<guid isPermaLink="false">http://maciek.lasyk.info/sysop/?p=130</guid>
		<description><![CDATA[Recently trying to connect via ssh using cssh to a particular server from 26 other boxes at the same time I wasn&#8217;t able to connect from some of those boxes and saw this message on those: [root@machine .ssh]# ssh -p &#8230;<p class="read-more"><a href="http://maciek.lasyk.info/sysop/2012/01/30/ssh_exchange_identification-connection-closed-by-remote-host/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Recently trying to connect via <b>ssh</b> using <b>cssh</b> to a particular server from 26 other boxes at the same time I wasn&#8217;t able to connect from some of those boxes and saw this message on those:</p>
<pre><code>[root@machine .ssh]# ssh -p 56789 user@othermachine.com
ssh_exchange_identification: Connection closed by remote host</code></pre>
<p>This was due to server configuration. Maximum default number of simultaneous connections tries (login attemps) is defined in <b>/etc/ssh/sshd_config</b>:</p>
<pre><code>MaxStartups 10</code></pre>
<p>We can change above value or use new-style format:</p>
<pre><code>MaxStartups 10:30:60</code></pre>
<p>Which stands for:</p>
<ol>
<li>10 &#8211; number of allowed simultaneous connections attempts. Above this number SSHD will start to randomly drop connections with percentage chance of 30%</li>
<li>60 &#8211; number of simultaneous connections attempts after which SSHD will drop every new connection</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://maciek.lasyk.info/sysop/2012/01/30/ssh_exchange_identification-connection-closed-by-remote-host/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Digging know how</title>
		<link>http://maciek.lasyk.info/sysop/2012/01/13/digging-know-how/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=digging-know-how</link>
		<comments>http://maciek.lasyk.info/sysop/2012/01/13/digging-know-how/#comments</comments>
		<pubDate>Fri, 13 Jan 2012 10:03:10 +0000</pubDate>
		<dc:creator>docent</dc:creator>
				<category><![CDATA[dns]]></category>
		<category><![CDATA[bind]]></category>
		<category><![CDATA[dig]]></category>
		<category><![CDATA[linkedin]]></category>

		<guid isPermaLink="false">http://maciek.lasyk.info/sysop/?p=120</guid>
		<description><![CDATA[Dig is one of the most important tools that every sysop uses in day-to-day work. It gives us the possibility to trace resolving path of domains, checking status of domain records or even getting whole definitions of records for a &#8230;<p class="read-more"><a href="http://maciek.lasyk.info/sysop/2012/01/13/digging-know-how/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p><b>Dig</b> is one of the most important tools that every sysop uses in day-to-day work. It gives us the possibility to trace resolving path of domains, checking status of domain records or even getting whole definitions of records for a particular domain (under some circumstances&#8230;). W won&#8217;t write here an essay about DNS and it&#8217;s functionality &#8211; You san always read it here: <a href="http://en.wikipedia.org/wiki/Domain_Name_System">http://en.wikipedia.org/wiki/Domain_Name_System</a></p>
<p>Assuming, that You ave already dig installed (if not &#8211; try <b>yum install bind-utils</b> on CentOs or whatever else on different distros) We can start with explaining how to use properly dig.</p>
<h1>1. Simple query</h1>
<p>Let&#8217;s check Gamedesire&#8217;s domain <b>www.gamedesire.com</b>:</p>
<pre><code>[docent@docent-desktop ganymede]$ dig www.gamedesire.com

; <<>> DiG 9.8.1-P1-RedHat-9.8.1-3.P1.fc15 <<>> www.gamedesire.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55580
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 4

;; QUESTION SECTION:
;www.gamedesire.com.		IN	A

;; ANSWER SECTION:
www.gamedesire.com.	59985	IN	A	174.123.95.100
www.gamedesire.com.	59985	IN	A	174.123.95.101

;; AUTHORITY SECTION:
gamedesire.com.		52534	IN	NS	ns2.theplanet.com.
gamedesire.com.		52534	IN	NS	ns1.theplanet.com.

;; ADDITIONAL SECTION:
ns1.theplanet.com.	84570	IN	A	207.218.247.135
ns1.theplanet.com.	130	IN	AAAA	2607:f0d0:0:f:6::1
ns2.theplanet.com.	55905	IN	A	207.218.223.162
ns2.theplanet.com.	130	IN	AAAA	2607:f0d0:0:f:6::2

;; Query time: 31 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Thu Jan 12 22:41:46 2012
;; MSG SIZE  rcvd: 202</code></pre>
<p>Above We can see a bunch of data.. "status: NOERROR" is answer status - NOERROR means, that query was resolved properly. ANSWER SECTION contains of information about resolved records (here We can see 2 A records for www.gamedesire.com: 174.123.95.100 and 174.123.95.101). Next We have AUTHORITY SECTION which gives us an answer to the question: "what are the authoritative DNS servers for this domain?". We have also some statistic data (query time, ADDITIONAL SECTION with DNS servers info etc). And remember to check answer flags (in above example: qr rd ra). You can find explanation of those in <a href="http://www.freesoft.org/CIE/RFC/1035/40.htm">RFC 1035 §4.1.1.</a>.</p>
<p>What happens when domain name is not resolved properly? Let's try with non-existing sysop.gamedesire.com:</p>
<pre><code>[docent@docent-desktop ganymede]$ dig sysop.gamedesire.com

; <<>> DiG 9.8.1-P1-RedHat-9.8.1-3.P1.fc15 <<>> sysop.gamedesire.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 20931
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0

;; QUESTION SECTION:
;sysop.gamedesire.com.		IN	A

;; AUTHORITY SECTION:
gamedesire.com.		10800	IN	SOA	ns1.theplanet.com. root.theplanet.com. 2012010400 7200 600 1728000 43200

;; Query time: 185 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Thu Jan 12 22:50:02 2012
;; MSG SIZE  rcvd: 93</code></pre>
<p>As we can see the answer status is NXDOMAIN here - it means NoneXistingDomain.</p>
<h1>2. Querying specific records</h1>
<p>There are plenty of DNS record types. Most commonly used are A, MX, TXT and CNAME. Here is the explanation and complete list of those types: <a href="http://en.wikipedia.org/wiki/List_of_DNS_record_types">http://en.wikipedia.org/wiki/List_of_DNS_record_types</a>. So now - how can We query for a MX domain?</p>
<pre><code>[docent@docent-desktop ganymede]$ dig mx google.com

; <<>> DiG 9.8.1-P1-RedHat-9.8.1-3.P1.fc15 <<>> mx google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30841
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 4, ADDITIONAL: 9

;; QUESTION SECTION:
;google.com.			IN	MX

;; ANSWER SECTION:
google.com.		373	IN	MX	20 alt1.aspmx.l.google.com.
google.com.		373	IN	MX	30 alt2.aspmx.l.google.com.
google.com.		373	IN	MX	40 alt3.aspmx.l.google.com.
google.com.		373	IN	MX	50 alt4.aspmx.l.google.com.
google.com.		373	IN	MX	10 aspmx.l.google.com.

;; AUTHORITY SECTION:
google.com.		273555	IN	NS	ns3.google.com.
google.com.		273555	IN	NS	ns2.google.com.
google.com.		273555	IN	NS	ns4.google.com.
google.com.		273555	IN	NS	ns1.google.com.

;; ADDITIONAL SECTION:
aspmx.l.google.com.	29	IN	A	173.194.67.27
alt1.aspmx.l.google.com. 171	IN	A	209.85.173.27
alt2.aspmx.l.google.com. 50	IN	A	74.125.127.26
alt3.aspmx.l.google.com. 79	IN	A	74.125.127.27
alt4.aspmx.l.google.com. 146	IN	A	209.85.225.26
ns1.google.com.		274504	IN	A	216.239.32.10
ns2.google.com.		274402	IN	A	216.239.34.10
ns3.google.com.		273449	IN	A	216.239.36.10
ns4.google.com.		274772	IN	A	216.239.38.10

;; Query time: 33 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Thu Jan 12 22:54:07 2012
;; MSG SIZE  rcvd: 352</code></pre>
<p>So We see above in ANSWER SECTION all found MX records. We can ask for any record type with this method.</p>
<h1>3. Tracing DNS query</h1>
<p>Every DNS query takes some hierarchical steps. Knowing those could be very helpful under some circumstances:</p>
<pre><code>[docent@docent-desktop ganymede]$ dig +trace www.wikipedia.org

; <<>> DiG 9.8.1-P1-RedHat-9.8.1-3.P1.fc15 <<>> +trace www.wikipedia.org
;; global options: +cmd
.			209351	IN	NS	k.root-servers.net.
.			209351	IN	NS	m.root-servers.net.
.			209351	IN	NS	j.root-servers.net.
.			209351	IN	NS	l.root-servers.net.
.			209351	IN	NS	b.root-servers.net.
.			209351	IN	NS	f.root-servers.net.
.			209351	IN	NS	h.root-servers.net.
.			209351	IN	NS	g.root-servers.net.
.			209351	IN	NS	c.root-servers.net.
.			209351	IN	NS	e.root-servers.net.
.			209351	IN	NS	d.root-servers.net.
.			209351	IN	NS	i.root-servers.net.
.			209351	IN	NS	a.root-servers.net.
;; Received 512 bytes from 192.168.1.1#53(192.168.1.1) in 693 ms

org.			172800	IN	NS	b2.org.afilias-nst.org.
org.			172800	IN	NS	a0.org.afilias-nst.info.
org.			172800	IN	NS	a2.org.afilias-nst.info.
org.			172800	IN	NS	c0.org.afilias-nst.info.
org.			172800	IN	NS	b0.org.afilias-nst.org.
org.			172800	IN	NS	d0.org.afilias-nst.org.
;; Received 437 bytes from 128.8.10.90#53(128.8.10.90) in 379 ms

wikipedia.org.		86400	IN	NS	ns1.wikimedia.org.
wikipedia.org.		86400	IN	NS	ns0.wikimedia.org.
wikipedia.org.		86400	IN	NS	ns2.wikimedia.org.
;; Received 147 bytes from 199.19.54.1#53(199.19.54.1) in 332 ms

www.wikipedia.org.	3600	IN	CNAME	wikipedia-lb.wikimedia.org.
wikipedia-lb.wikimedia.org. 600	IN	CNAME	wikipedia-lb.esams.wikimedia.org.
wikipedia-lb.esams.wikimedia.org. 3600 IN A	91.198.174.225
;; Received 121 bytes from 208.80.152.142#53(208.80.152.142) in 157 ms</code></pre>
<p>We see above all the DNS query steps - first question to the root servers for a proper TLD DNS server (org), next the question to the TLD org's server for a proper wikipedia.org NS servers, and then the question to the wikipedia's NS servers for a resolution to the name 'wikipedia.org' which appears to be a CNAMEs for something more...</p>
<h1>4. Shortening the output</h1>
<p>Digging is a quite verbose action - by design - much verbosity is good for debugging purposes. It's good to know how can We reduce output of this command - for example when We would like to wrap dig command with some monitoring script. For this purpose I suggest to get known with:</p>
<pre><code>+nostats
+nocmd
+noquestion
+short</code></pre>
<p>Let's try with the strongest one from above - <b>+short</b> will reduce all the dig's "noise":</p>
<pre><code>[docent@docent-desktop ganymede]$ dig +short www.gamedesire.com
174.123.95.101
174.123.95.100</code></pre>
<p>We can join <b>+short</b> with eg. "+trace":</p>
<pre><code>[docent@docent-desktop ganymede]$ dig +short +trace www.gamedesire.com
NS l.root-servers.net. from server 192.168.1.1 in 33 ms.
NS c.root-servers.net. from server 192.168.1.1 in 33 ms.
NS g.root-servers.net. from server 192.168.1.1 in 33 ms.
NS m.root-servers.net. from server 192.168.1.1 in 33 ms.
NS b.root-servers.net. from server 192.168.1.1 in 33 ms.
NS a.root-servers.net. from server 192.168.1.1 in 33 ms.
NS i.root-servers.net. from server 192.168.1.1 in 33 ms.
NS j.root-servers.net. from server 192.168.1.1 in 33 ms.
NS d.root-servers.net. from server 192.168.1.1 in 33 ms.
NS e.root-servers.net. from server 192.168.1.1 in 33 ms.
NS h.root-servers.net. from server 192.168.1.1 in 33 ms.
NS f.root-servers.net. from server 192.168.1.1 in 33 ms.
NS k.root-servers.net. from server 192.168.1.1 in 33 ms.
A 174.123.95.100 from server 207.218.247.135 in 173 ms.
A 174.123.95.101 from server 207.218.247.135 in 173 ms.</code></pre>
<p>You can try Yourself with other params.</p>
<h1>5. Asking specific DNS server</h1>
<p>It is very good practice during checking DNS resolutions (especially while transferring domains etc) to ask query to a couple of DNS servers. We can ask particular DNS server (but only when this server allows us to do so). Remember that by default dig uses DNSes listed in Your <b>/etc/resolv.conf</b> file. Let's try to ask google's DNSes first:</p>
<pre><code>[docent@docent-desktop ganymede]$ dig +short @8.8.8.8 www.gamedesire.com
174.123.95.101
174.123.95.100</code></pre>
<p>And now some ThePlanet's:</p>
<pre><code>[docent@docent-desktop ganymede]$ dig +short @ns1.theplanet.com www.gamedesire.com
174.123.95.101
174.123.95.100</code></pre>
<h1>6. The authority</h1>
<p>In this example:</p>
<pre><code>[docent@docent-desktop ~]$ dig www.gamedesire.com @ns1.theplanet.com

; <<>> DiG 9.8.1-P1-RedHat-9.8.1-3.P1.fc15 <<>> www.gamedesire.com @ns1.theplanet.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18903
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 4
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;www.gamedesire.com.		IN	A

;; ANSWER SECTION:
www.gamedesire.com.	86400	IN	A	174.123.95.101
www.gamedesire.com.	86400	IN	A	174.123.95.100

;; AUTHORITY SECTION:
gamedesire.com.		86400	IN	NS	ns2.theplanet.com.
gamedesire.com.		86400	IN	NS	ns1.theplanet.com.

;; ADDITIONAL SECTION:
ns1.theplanet.com.	86400	IN	A	207.218.247.135
ns1.theplanet.com.	600	IN	AAAA	2607:f0d0:0:f:6::1
ns2.theplanet.com.	86400	IN	A	207.218.223.162
ns2.theplanet.com.	600	IN	AAAA	2607:f0d0:0:f:6::2

;; Query time: 175 msec
;; SERVER: 207.218.247.135#53(207.218.247.135)
;; WHEN: Thu Jan 12 23:43:50 2012
;; MSG SIZE  rcvd: 202</code></pre>
<p>We can see, that AA bit is set here (flags: qr aa rd). So ns1.theplanet.com is authoritative for gamedesire.com domain (as in AUTHORITY section). Now let's try to dig it again using some other DNS server:</p>
<pre><code>[docent@docent-desktop ~]$ dig www.gamedesire.com

; <<>> DiG 9.8.1-P1-RedHat-9.8.1-3.P1.fc15 <<>> www.gamedesire.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63097
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 2

;; QUESTION SECTION:
;www.gamedesire.com.		IN	A

;; ANSWER SECTION:
www.gamedesire.com.	19128	IN	A	174.123.95.101
www.gamedesire.com.	19128	IN	A	174.123.95.100

;; AUTHORITY SECTION:
gamedesire.com.		9373	IN	NS	ns1.theplanet.com.
gamedesire.com.		9373	IN	NS	ns2.theplanet.com.

;; ADDITIONAL SECTION:
ns1.theplanet.com.	84587	IN	A	207.218.247.135
ns2.theplanet.com.	2292	IN	A	207.218.223.162

;; Query time: 29 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Fri Jan 13 10:42:38 2012
;; MSG SIZE  rcvd: 146
</code></pre>
<p>Here We can see, that there is no AA bit set, and also TTL values are lower than 86400 for www.gamedesire.com (We can see 19128 value). Why is that? Because this answer is cached somewhere in the middle and our current DNS server is not authorative for gamedesire.com . If We would repeat this query this TTL value would be dropping every each question. We can't tell looking at above dig output where this query was cached - to know this We would have to repeat the query with recursion disabled and step manually through all the DNS tree (but in 9/10 cases It will be You local DNS cache... which is caching answers).</p>
<h1>7. Tracing DIG execution</h1>
<p>As I wrote above We can set <b>+trace</b> param using dig to trace resolving path in the DNS tree. But how can We trace what exact queries are sent and received? Surely with tcpdump:</p>
<pre><code>[root@docent-desktop ~]# tcpdump -i p2p1 -s1024 udp port domain
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on p2p1, link-type EN10MB (Ethernet), capture size 512 bytes
10:54:17.047260 IP pma.local.40206 > 192.168.1.1.domain: 9836+ A? www.gamedesire.com. (36)
10:54:17.047721 IP pma.local.55428 > 192.168.1.1.domain: 59517+ PTR? 1.1.168.192.in-addr.arpa. (42)
10:54:17.079337 IP 192.168.1.1.domain > pma.local.55428: 59517 NXDomain* 0/1/0 (109)
10:54:17.080473 IP 192.168.1.1.domain > pma.local.40206: 9836 2/2/2 A 174.123.95.101, A 174.123.95.100 (146)
^C
4 packets captured
4 packets received by filter
0 packets dropped by kernel</code></pre>
<p>From the tcpdump(8) manpage: Name server requests are formatted as:</p>
<pre><code>src > dst: id op? flags qtype qclass name (len)</code></pre>
<p>I rather suggest reading this manpages Yourself - just look for "UDP Name Server Requests" section.</p>
]]></content:encoded>
			<wfw:commentRss>http://maciek.lasyk.info/sysop/2012/01/13/digging-know-how/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wacom Bamboo Fun in Fedora 15</title>
		<link>http://maciek.lasyk.info/sysop/2012/01/11/wacom-bamboo-fun-in-fedora-15/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=wacom-bamboo-fun-in-fedora-15</link>
		<comments>http://maciek.lasyk.info/sysop/2012/01/11/wacom-bamboo-fun-in-fedora-15/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 20:44:17 +0000</pubDate>
		<dc:creator>docent</dc:creator>
				<category><![CDATA[fedora]]></category>
		<category><![CDATA[tablet]]></category>
		<category><![CDATA[wacom]]></category>
		<category><![CDATA[x]]></category>

		<guid isPermaLink="false">http://maciek.lasyk.info/sysop/?p=118</guid>
		<description><![CDATA[Today I connected my wife&#8217;s Wacom Bamboo Fun CTH-461 to my desktop with Fedora 15 on the 2.6.41.4-1.fc15.x86_64 kernel. It worked like a charm &#8211; just plug&#038;play &#8211; that&#8217;s because I already got installed X drivers for the Wacom: [docent@docent-desktop &#8230;<p class="read-more"><a href="http://maciek.lasyk.info/sysop/2012/01/11/wacom-bamboo-fun-in-fedora-15/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Today I connected my wife&#8217;s Wacom Bamboo Fun CTH-461 to my desktop with Fedora 15 on the 2.6.41.4-1.fc15.x86_64 kernel. It worked like a charm &#8211; just plug&#038;play &#8211; that&#8217;s because I already got installed X drivers for the Wacom:</p>
<pre><code>[docent@docent-desktop ~]$ rpm -qa | grep -i wacom
xorg-x11-drv-wacom-0.11.1-3.fc15.x86_64</code></pre>
<p>If You have issues with Wacom under Fedora 15 &#8211; just try to install above drivers and reboot X.</p>
<p>But I really hate this multi &#8211; touch when I&#8217;d like to draw something with the pen, so I wanted to turn it off. Also I wanted the pen to work only on the first monitor &#8211; not on the both (I use dual monitors with extended desktops). We can set all those things with <b>xwacomset</b> command. First We have to know our Wacom devices:</p>
<pre><code>[docent@docent-desktop ~]$ xsetwacom list dev
Wacom Bamboo Craft Finger touch 	id: 11	type: TOUCH
Wacom Bamboo Craft Finger pad   	id: 12	type: PAD
Wacom Bamboo Craft Pen stylus   	id: 13	type: STYLUS
Wacom Bamboo Craft Pen eraser   	id: 14	type: ERASER</code></pre>
<p>Now when We have those devices&#8217; names We can turn off the multi touch:</p>
<pre><code>[docent@docent-desktop ~]$ xsetwacom set 'Wacom Bamboo Craft Finger touch' touch off</code></pre>
<p>When done with multi touch We can set the working space of our tablet to the first display unit. Firsly we have to know current mapping settings:</p>
<pre><code>[docent@docent-desktop ~]$ xsetwacom get "Wacom Bamboo Craft Pen stylus" Area
0 0 14720 9200
</code></pre>
<p>Now If You want to map the pen to the left monitor, just double the third number:</p>
<pre><code>xsetwacom set "Wacom Bamboo Craft Pen stylus" Area "0 0 29440 9200"</code></pre>
<p>Now I had all done and were ready to go with my work :)</p>
]]></content:encoded>
			<wfw:commentRss>http://maciek.lasyk.info/sysop/2012/01/11/wacom-bamboo-fun-in-fedora-15/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Postfix: Backup MX</title>
		<link>http://maciek.lasyk.info/sysop/2012/01/06/postfix-backup-mx/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=postfix-backup-mx</link>
		<comments>http://maciek.lasyk.info/sysop/2012/01/06/postfix-backup-mx/#comments</comments>
		<pubDate>Fri, 06 Jan 2012 14:49:09 +0000</pubDate>
		<dc:creator>docent</dc:creator>
				<category><![CDATA[postfix]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[linkedin]]></category>
		<category><![CDATA[mx]]></category>

		<guid isPermaLink="false">http://maciek.lasyk.info/sysop/?p=110</guid>
		<description><![CDATA[In mail-servers architecture We should always have some backup MX defined for every mail server. It&#8217;s very simple why &#8211; to have a redundant mail-server architecture and just to be sure, that no emails are returned with an error while &#8230;<p class="read-more"><a href="http://maciek.lasyk.info/sysop/2012/01/06/postfix-backup-mx/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://maciek.lasyk.info/sysop/wp-content/uploads/2012/01/tux-mail-1ty.gif"><img src="http://maciek.lasyk.info/sysop/wp-content/uploads/2012/01/tux-mail-1ty.gif" alt="" title="Taken from www.yolinux.com" width="243" height="244" class="alignright size-full wp-image-116" /></a>In mail-servers architecture We should always have some backup MX defined for every mail server. It&#8217;s very simple why &#8211; to have a redundant mail-server architecture and just to be sure, that no emails are returned with an error while our mail-server is having issues.</p>
<p>In the simplest scenario let&#8217;s assume that We have only one mail server (mail.somedomain.com). We&#8217;d like to start a backup MX server for this. We can do this in a few simple steps:</p>
<h1>Step 1: Backup postfix configuration</h1>
<p>On the backup server We should change some postfix configuration in <b>main.cf</b> file. We should add / change <b>relay_domains</b>, set <b>maximal_queue_lifetime</b>, <b>smtpd_recipient_restrictions</b> and We should create <b>relay_recipient_maps</b>:</p>
<pre><code>relay_recipient_maps = hash:/etc/postfix/relay_recipients
maximal_queue_lifetime = 30d
smtpd_recipient_restrictions =
       [...]
       permit_mx_backup
relay_domains = $mydestination somedomain.com
permit_mx_backup_networks = 128.128.128.0/24 201.201.201.0/24</code></pre>
<p>Now let&#8217;s explain the following configuration:</p>
<ul>
<li><b>relay_recipient_maps = hash:/etc/postfix/relay_recipients</b> &#8211; this is optional, but I advise to use this parameter. It defines a hash table containing valid recipients. If the backup system wouldn&#8217;t know all the valid mailboxes it would have to accept all the emails &#8211; including spam for non-existing adresses. With knowledge of legal addresses backup server is able to bounce back emails that have invalid recipient set. This does not apply in environment using catchall mailboxes to catch all the emails. I attached a sample relay_recipients file below. Remember to use postmap command after every change in this file: <b>postmap /etc/postfix/relay_recipients</b></li>
<li><b>maximal_queue_lifetime = 30d</b> &#8211; default value for Postfix is 5 days. This number sets the time period in which backup server will try to deliver emails to the main server &#8211; so this is maximum time of downtime for main server until mails are bounced back to their original senders with an error.</li>
<li><b>relay_domains = $mydestination somedomain.com</b> &#8211; this parameter will allow postfix to relay emails for <b>somedomain.com</b></li>
<li><b>permit_mx_backup</b> &#8211; security, see <a href="http://www.postfix.org/postconf.5.html#permit_mx_backup" title="http://www.postfix.org/postconf.5.html#permit_mx_backup">http://www.postfix.org/postconf.5.html#permit_mx_backup</a></li>
<li><b>permit_mx_backup_networks</b> &#8211; security, see <a href="http://www.postfix.org/postconf.5.html#permit_mx_backup_networks" title="http://www.postfix.org/postconf.5.html#permit_mx_backup_networks">http://www.postfix.org/postconf.5.html#permit_mx_backup_networks</a></li>
</ul>
<p>And the sample relay_recipients_file:</p>
<pre><code>user1@somedomain.com   any_value
user2@somedomain.com   any_value
user3@somedomain.com   any_value
user4@somedomain.com   any_value
user5@somedomain.com   any_value</code></pre>
<p>So as You see &#8211; You should have replicated users addresses on the MX server in the relay_recipients file.</p>
<h1>Step 2: DNS configuration</h1>
<p>Having only one mail server it is enough to have only one MX record in our DNS zone file:</p>
<pre><code>[user@server ~]# dig mx somedomain.com
;; ANSWER SECTION:
somedomain.com.		86400	IN	MX	10 mail.somedomain.com.
</code></pre>
<p>Here We see our only MX record with 10 priority pointing to the A record mail.somedomain.com. In order to create a new record for our backup MX server We should first add a new A record, like:</p>
<pre><code>mail2.somedomain.com.  	86400	IN	A	129.129.129.129</code></pre>
<p>And then We can create a new MX record with lower priority:</p>
<pre><code>mail.somedomain.com.	86400	IN	MX	20 mail2.somedomain.com.</code></pre>
<h1>Step 3: Flushing messages</h1>
<p>When main MX server is down, and backup server gets some messages to hold those until main server is back &#8211; It moves those messages immediately to the flush queue. Now those messages can be delivered via flush daemon, which is run every some time (set in <b>/etc/postfix/master.cf</b>):</p>
<pre><code>flush     unix  n       -       n       1000?   0       flush</code></pre>
<p>Here the &#8220;1000?&#8221; stands for 1000 seconds every which flush daemon is activated (until it is not already running &#8211; this is why we use here question mark after 1000).</p>
<p>Now we can set how often messages should be flushed via the running flush daemon using the <b>fast_flush_refresh_time</b> param (default set to 12h). So every 12h messages that haven&#8217;t had redelivery requested are being kicked automaticly.</p>
<p>When our master server is back We could just flush all the messages manually:</p>
<pre><code>postqueue -f</code></pre>
<p>But above command will flush all the messages in the flush queue &#8211; this might not be the best solution as the backup MX can be a slave for a bunch of main MX servers &#8211; are you sure You would like to flush all those messages from all those servers when only one is back online?</p>
<p>Better solution is to use:</p>
<pre><code>postqueue -s somedomain.com</code></pre>
<p>Above command will flush only the messages from the given domain &#8211; and that&#8217;s what We would like to do. But We have to know, that We can use this command only when We have this domain configured as &#8220;fast_flush_domains&#8221;. Again &#8211; We&#8217;re lucky, because default &#8220;fast_flush_domains&#8221; value is:</p>
<pre><code>fast_flush_domains = $relay_domains</code></pre>
<p>And If We configured our somedomain.com as &#8220;$relay_domain&#8221; &#8211; then our flush command will work :) If not then We only have to set:</p>
<pre><code>fast_flush_domains = $relay_domains somedomain.com</code></pre>
<p>And when our main MX comes back again &#8211; We can flush this domain on the backup MX &#8211; it&#8217;s good to be wrapped with some script :)</p>
<p>And We&#8217;re good to go &#8211; from now (after correct DNS entries&#8217; propagation, so in max 72 hours) our backup MX should work and receive emails when master mail server is offline.</p>
]]></content:encoded>
			<wfw:commentRss>http://maciek.lasyk.info/sysop/2012/01/06/postfix-backup-mx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL statement based replication with triggers, events, procedures, functions and variables</title>
		<link>http://maciek.lasyk.info/sysop/2012/01/06/mysql-statement-based-replication-with-triggers-events-procedures-functions-and-variables/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-statement-based-replication-with-triggers-events-procedures-functions-and-variables</link>
		<comments>http://maciek.lasyk.info/sysop/2012/01/06/mysql-statement-based-replication-with-triggers-events-procedures-functions-and-variables/#comments</comments>
		<pubDate>Fri, 06 Jan 2012 13:30:48 +0000</pubDate>
		<dc:creator>docent</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[linkedin]]></category>
		<category><![CDATA[replication]]></category>

		<guid isPermaLink="false">http://maciek.lasyk.info/sysop/?p=84</guid>
		<description><![CDATA[Before starting statement based replication in MySQL database We have to be aware of some specific behaviors for this environment. This kind of replication (statement based) writes each query that modifies data to the Binary Log in order to replicate &#8230;<p class="read-more"><a href="http://maciek.lasyk.info/sysop/2012/01/06/mysql-statement-based-replication-with-triggers-events-procedures-functions-and-variables/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Before starting statement based replication in MySQL database We have to be aware of some specific behaviors for this environment. This kind of replication (statement based) writes each query that modifies data to the <b>Binary Log</b> in order to replicate them on the slave or to use as a <b>point-in-time recovery</b> (PITR). Because of this kind of query logging We should be aware how MySQL replication engine behaves with some special queries like triggers, functions, procedures or events.</p>
<h1>Functions</h1>
<p>Function calls are logged directly to Binary Log, so If You forget to create on slave any function that is created on master &#8211; You will break your replication and probably You&#8217;ll see error like below:</p>
<pre><code>Last_Error: Error 'FUNCTION postfix.recount_quota not exist' on query. Default database: 'postfix'. Query: 'UPDATE user_imap SET quota=(recount_quota())'</pre>
<p></code></p>
<p>When promoting slave to master no additional steps according to functions are required - everything is needed is having functions defined in both: master and slave.</p>
<h1>Procedures</h1>
<p>Procedure calls are not replicated as in functions - this is important to know. Only the queries inside the procedures get logged to the Binary Log, so You don't have to create procedures on slaves.</p>
<p>In order to promote slave to master you should have procedures created on slave - so it is wise to have all the procedures created on both - master and slaves.</p>
<h1>Events</h1>
<p>Events created on master server get replicated to the slave with the <b>DISABLE ON SLAVE</b> option - that's why those events are not reexecuted on every slave in our MySQL architecture and we have no duplicated and corrupted data. MySQL logs only queries from inside the event so only those queries are replicated via Binary Log.</p>
<p>In order to promote slave to master according to events we have to do some more job. I've created a simple event below (We create it on the master):</p>
<pre><code>mysql> CREATE EVENT mysql_heartbeat
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 MINUTE
DO INSERT UPDATE `mysql_stat`.`heartbeat` SET `last`=CURTIME();</pre>
<p></code></p>
<p>Now it's replicated on slave via Binary Log - below I've placed replication entry for that event from Binary Log:</p>
<pre><code>CREATE DEFINER=`user`@`localhost` EVENT `mysql_heartbeat` ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 MINUTE DO INSERT UPDATE `mysql_stat`.`heartbeat` SET `last`=CURTIME();</pre>
<p></code></pre>
<p></code></p>
<p>And how it looks like after replication on the slave:</p>
<pre><code>CREATE DEFINER=`user`@`localhost` EVENT `mysql_heartbeat` ON SCHEDULE AT '2012-01-06 21:12:56' ON COMPLETION NOT PRESERVE DISABLE ON SLAVE DO INSERT UPDATE `mysql_stat`.`heartbeat` SET `last`=CURTIME();</pre>
<p></code></p>
<p>So now with this knowledge a little procedure to promote slave to master using events:</p>
<ul>
<li>Disabling event manager on slave with <b>SET GLOBAL event_scheduler = OFF;</b></li>
<li>Enabling all the events with <b>ALTER EVENT `event_name` ENABLE</b> - We have to do this for each event, so writing a little script is very helpful here.</li>
<li>Enabling event manager with <b>SET GLOBAL event_scheduler = ON;</b></li>
</ul>
<p>In order to demote back the master to slave You should follow the previous procedure with a little change on ALTER EVENT - here You just need to DISABLE all the events (not ENABLE).</p>
<h1>Triggers</h1>
<p>In order to have triggers running properly on master and slaves You have to define them in both - master and slave servers. MySQL statement based replication replicates only the original query to the Binary Log - not the subsequent triggered statements.</p>
<p>When promoting slave to master no additional steps according to triggers are required - everything is needed is having triggers defined in both: master and slave.</p>
<h1>Mixed triggers / procedures / functions calls</h1>
<p>Let's imagine that We have a trigger, that triggers a procedure which uses a function call. How will this behave in statement based replication?</p>
<ol>
<li>We should have trigger defined on both: master and slave</li>
<li>We don't have to have procedure defined on the slave - only on master is enough</li>
<li>We should have function defined on both: master and slave</li>
</ol>
<p>Despite of all - my advice is to keep function, triggers, procedures and events defined on all the servers (masters and slaves) - just to be sure, that We can always promote slave to master without any issues.</p>
<p>And one more thing before finishing this post. If You plan to start replication with just copying FRM, MYI, MYD and InnoDB files You should also dump any functions / triggers and stored procedures on master (or slave) and then import those on the new slave. You can do it (for every database) with:</p>
<pre><code>mysqldump --routines --no-create-info --no-data --no-create-db --skip-opt &lt;database> > dumpfile.sql</code></pre>
<p>And recreate those on the new box:</p>
<pre><code>mysql &lt;database> &lt; dumpfile.sql</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://maciek.lasyk.info/sysop/2012/01/06/mysql-statement-based-replication-with-triggers-events-procedures-functions-and-variables/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL tunneling via SSH and error &#8220;channel: open failed: connect failed: Connection refused&#8221;</title>
		<link>http://maciek.lasyk.info/sysop/2011/12/28/mysql-tunneling-via-ssh-and-error-channel-open-failed-connect-failed-connection-refused/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-tunneling-via-ssh-and-error-channel-open-failed-connect-failed-connection-refused</link>
		<comments>http://maciek.lasyk.info/sysop/2011/12/28/mysql-tunneling-via-ssh-and-error-channel-open-failed-connect-failed-connection-refused/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 13:48:53 +0000</pubDate>
		<dc:creator>docent</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[tunnel]]></category>

		<guid isPermaLink="false">http://maciek.lasyk.info/sysop/?p=73</guid>
		<description><![CDATA[Lately I wrote a short article about MySQL tunneling via SSH in order to start safe MySQL replication. Afterwards I noticed some problems with creating a new SSH tunnel for MySQL connection on a quite different environment. After creating SSH &#8230;<p class="read-more"><a href="http://maciek.lasyk.info/sysop/2011/12/28/mysql-tunneling-via-ssh-and-error-channel-open-failed-connect-failed-connection-refused/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Lately I wrote a <a href="http://maciek.lasyk.info/sysop/2011/12/24/65/">short article</a> about MySQL tunneling via SSH in order to start safe MySQL replication. Afterwards I noticed some problems with creating a new SSH tunnel for MySQL connection on a quite different environment. After creating SSH tunnel and trying to connect via this tunnel to the SSH server I received SSH error on tunnel error-log:</p>
<pre><code>channel 2: open failed: connect failed: Connection refused</pre>
<p></code></p>
<p>or:</p>
<pre><code>channel 3: open failed: connect failed: Connection refused</pre>
<p></code></p>
<p>And below:</p>
<pre><code>ERROR 2013 (HY000): Lost connection to MySQL server during query</pre>
<p></code></p>
<p>in the MySQL terminal.</p>
<p>First of all We have to make sure, that our tunnel is working properly, so We just kill the current tunnel and create new one without "<b>-f</b>" and "<b>-N</b>" options:</p>
<pre><code>ssh -p 2345 mysql_tunnel@mysqlmaster-server.com -L 4406:mysqlmaster-server.com:3306</pre>
<p></code></p>
<p>If everything is ok, then We can assume that tunnel is working fine. We can also try to create another tunnel to some other service on different target port and then just try if this other service is working via the tunnel - just to exclude any problems with SSH tunneling.</p>
<p>My problem was that MySQL was configured in the way it was blocking any connections outside localhost. It is default MySQL configuration - We can achieve it via <b>my.cnf</b> entries:</p>
<pre><code>bind-address = 127.0.0.1</pre>
<p></code></p>
<p>or:</p>
<pre><code>skip-networking</pre>
<p></code></p>
<p>So in order to make our MySQL accessible via our tunnel We have to comment out the <b>skip-networking</b> line and make sure that We are connecting to the correct IP addr in our tunnel. For example If we have in our <b>my.cnf</b> this line:</p>
<pre><code>bind-address = 127.0.0.1</pre>
<p></code></p>
<p>Then our tunnel should look like:</p>
<pre><code>ssh -p 2345 -f mysql_tunnel@mysqlmaster-server.com -L 4406:127.0.0.1:3306 -N</pre>
<p></code></p>
<p>(notice that 127.0.0.1 in the above command).</p>
<p>If We would bind our MySQL to some other IP, like:</p>
<pre><code>bind-address = 192.168.0.12</pre>
<p></code></p>
<p>Then We should change our tunneling parameters:</p>
<pre><code>ssh -p 2345 -f mysql_tunnel@mysqlmaster-server.com -L 4406:192.168.0.12:3306 -N</pre>
<p></code></p>
<p>After commenting out that <b>skip-networking</b> our security depends on IP address We are binding the MySQL to. If it's local IP addres in DMZ, than there is no security breaches here. Unwise would be to bind to the WAN address and leave MySQL port opened without any SSL encryption or without filtering traffic by the client IP addr...</p>
]]></content:encoded>
			<wfw:commentRss>http://maciek.lasyk.info/sysop/2011/12/28/mysql-tunneling-via-ssh-and-error-channel-open-failed-connect-failed-connection-refused/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL replication over SSH tunnel</title>
		<link>http://maciek.lasyk.info/sysop/2011/12/24/mysql-replication-over-ssh-tunnel/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-replication-over-ssh-tunnel</link>
		<comments>http://maciek.lasyk.info/sysop/2011/12/24/mysql-replication-over-ssh-tunnel/#comments</comments>
		<pubDate>Sat, 24 Dec 2011 23:37:58 +0000</pubDate>
		<dc:creator>docent</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[linkedin]]></category>
		<category><![CDATA[replication]]></category>
		<category><![CDATA[tunnel]]></category>

		<guid isPermaLink="false">http://maciek.lasyk.info/sysop/?p=65</guid>
		<description><![CDATA[Sometimes it is a good decision to replicate between datacenters. It is not for a backup purposes &#8211; as replication cannot be used for backups (maybe under some circumstances, but let&#8217;s say that for now We&#8217;re not thinking about replication &#8230;<p class="read-more"><a href="http://maciek.lasyk.info/sysop/2011/12/24/mysql-replication-over-ssh-tunnel/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>Sometimes it is a good decision to replicate between datacenters. It is not for a backup purposes &#8211; as replication cannot be used for backups (maybe under some circumstances, but let&#8217;s say that for now We&#8217;re not thinking about replication as backup solution) &#8211; for now We&#8217;re using it to just have up2date data in some other datacenter.</p>
<p>General idea to set up this replication is to make a SSH tunnel between those two datacenters and then start transferring data using this secure transport layer. I will call &#8220;replication server&#8221; &#8211; the server that will be slave in our destination and &#8220;the master server&#8221; will be our master.</p>
<p>I won&#8217;t write here how to set up a replication from the scratch. Let&#8217;s say that for now there are at least two ways to do it without stopping mysql master (using another slave to take data snapshot or using <a href="http://www.percona.com/doc/percona-xtrabackup/howtos/setting_up_replication.html">Percona Xtrabackup</a>).</p>
<p>Firstly we have to start SSH tunnel. We have to ensure, that this tunnel will keep alive trough any connection problems and will not be killed due to an idle (how come when there is replication stream over this?).</p>
<p>Let&#8217;s start with ensuring that our tunnell will keep alive. In SSH client configuration (default: /etc/ssh/ssh_config) We should add the following:</p>
<pre><code>ServerAliveInterval 300</pre>
<p></code></p>
<p>With above server maintaining the tunnel will send some keep-alive request every 300 seconds to the master (destination) server.</p>
<p>Now We have to open MySQL port on the master (destination) server on WAN interface. This is not secure unless We filter source IP address trying to connect to this port (let's allow only our slave's server IP addr. to use this port). For maximum security We can use TCP Wrappers on the master (destination) MySQL server, but this will put some overhead to the server functionality as TCP Wrappers always use some DNS resolution. In my opinion filtering MySQL port based on source IP address is enough.</p>
<p>Now We can start our tunnel:</p>
<pre><code>ssh -p 2345 -f mysql_tunnel@mysqlmaster-server.com -L 4406:mysqlmaster-server.com:3306 -N</pre>
<p></code></p>
<p>Let's explain:</p>
<ul>
<li><strong>-p 2345</strong> - port We are using to connect over SSH (default 22, but should be changed to something else for standard security reasons)</li>
<li><strong>-n</strong> - SSH will go to background just before command execution. Make sure, that You have SSH keys exported to the master (destination) server from the slave server / user and You will not have to enter any passwords during creating the tunnel</li>
<li><strong>-L</strong> - turns on port forwarding - this is the core of creating SSH tunnel
<li>
<li><strong>-N</strong> - "do not execute a remote command" - just because We are just forwarding ports :)</li>
</ul>
<p>Now We can test this tunnel. Let's try to connect to MySQL master from the slave server:</p>
<pre><code>mysql -h 127.0.0.1 -p 4406 --user=replication</pre>
<p></code></p>
<p>We should be able to connect to the master server with above command. And If We really did - then We can use this connection to start the replication.</p>
<p>This is very simple method that should be wrapped with some monitoring, scripts that will create SSH tunnels automatically when the original tunnel dies or after server crash. We should also remember, that replication lags can be quite high using this technique - everything depends on connection quality and number of writes on master that will have to be replicated on slave. In order to tune this method of replication It can be good to use statement-based replication - because in many cases this method use a bunch less number of kilobytes to transmit replication data to the slave.</p>
]]></content:encoded>
			<wfw:commentRss>http://maciek.lasyk.info/sysop/2011/12/24/mysql-replication-over-ssh-tunnel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Calculating files size in bash</title>
		<link>http://maciek.lasyk.info/sysop/2011/12/09/calculating-files-size-in-bash/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=calculating-files-size-in-bash</link>
		<comments>http://maciek.lasyk.info/sysop/2011/12/09/calculating-files-size-in-bash/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 09:31:56 +0000</pubDate>
		<dc:creator>docent</dc:creator>
				<category><![CDATA[oneliners]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[oneliner]]></category>

		<guid isPermaLink="false">http://maciek.lasyk.info/sysop/?p=55</guid>
		<description><![CDATA[When we face the problem of calculating size of some files then we often think of du.. But how could we count size of files found by find? We could do this with this simple one-liner: find /somewhere -name 'some_files*' &#8230;<p class="read-more"><a href="http://maciek.lasyk.info/sysop/2011/12/09/calculating-files-size-in-bash/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>When we face the problem of calculating size of some files then we often think of <strong>du</strong>.. But how could we count size of files found by <strong>find</strong>? We could do this with this simple one-liner:</p>
<p>
<pre><code>find /somewhere -name 'some_files*' -exec wc -c '{}' +</pre>
<p></code></p>
<p>Find command is simple here. We use here also a POSIX solution - ending "exec" with a plus-sign not a semicolon. This form groups the finding results into sets and then run commands on whole that set. And that's why we use it here - our <strong>wc -c</strong> command is run on a whole set of results giving us in the end line the total size of all the files:</p>
<p>
<pre><code>[root@docent log]# find . -name 'maillog*' -exec wc -c '{}' +
 6847 ./maillog-20111120
 6137 ./maillog
 6580 ./maillog-20111204
 5028 ./maillog-20111113
 6424 ./maillog-20111127
31016 total</pre>
<p></code></p>
<p>We could shorten that a little:</p>
<p>
<pre><code>[root@docent log]# find . -name 'maillog*' -exec wc -c '{}' + | tail -1
31016 total</pre>
<p></code></p>
<p>And If we would like to have only the number:</p>
<p>
<pre><code>[root@docent log]# find . -name 'maillog*' -exec wc -c '{}' + | tail -1 | cut -d' ' -f 1
31016</pre>
<p></code></p>
]]></content:encoded>
			<wfw:commentRss>http://maciek.lasyk.info/sysop/2011/12/09/calculating-files-size-in-bash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grep is Your friend</title>
		<link>http://maciek.lasyk.info/sysop/2011/12/07/grep-is-your-friend/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=grep-is-your-friend</link>
		<comments>http://maciek.lasyk.info/sysop/2011/12/07/grep-is-your-friend/#comments</comments>
		<pubDate>Wed, 07 Dec 2011 22:58:41 +0000</pubDate>
		<dc:creator>docent</dc:creator>
				<category><![CDATA[Bash tips]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[grep]]></category>
		<category><![CDATA[regexp]]></category>

		<guid isPermaLink="false">http://maciek.lasyk.info/sysop/?p=17</guid>
		<description><![CDATA[GREP stands for Global Regular Expression Print. I think that every sysop loves grep, grepping and anything that has something in common with grep &#8211; this tool makes our lives really easier ;) If You&#8217;re not convinced than I think &#8230;<p class="read-more"><a href="http://maciek.lasyk.info/sysop/2011/12/07/grep-is-your-friend/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p><strong>GREP</strong> stands for Global Regular Expression Print. I think that every sysop loves <strong>grep</strong>, <strong>grepping</strong> and anything that has something in common with <strong>grep</strong> &#8211; this tool makes our lives really easier ;) If You&#8217;re not convinced than I think You&#8217;re in a good place &#8211; maybe the following text will convince You :)</p>
<ol>
<li>
<p><strong>Excluding irrelevant words</strong>: sometimes We have to grep for some word but We have to exclude some irrelevant string. E.g. let&#8217;s grep for &#8216;index.html&#8217; but let&#8217;s also exclude &#8217;404&#8242; from this:</p>
<p>
<pre><code>grep 'index.html' access.log | grep -v 404</pre>
<p></code></p>
</li>
<li>
<p><strong>egrep</strong> (extended grep, same as <strong>grep -e</strong> or <strong>grep --regexp=</strong>)  allows us to do more powerful search including regular expressions with metacharacters like  +, ?, | and ()</p>
<p>
<pre><code>egrep "html|cgi" access.log</pre>
<p></code></p>
</li>
<li>
<p><strong>Counting results</strong> - If we just want to know the number of lines that matched our query - We would use:</p>
<p>
<pre><code>grep -c 'index.html' access.log</pre>
<p></code></p>
</li>
<li><strong>Case Insensitive search</strong> - by default grep is case sensitive, If we want to make case insensitive search than we use:</p>
<p>
<pre><code>grep -i 'Index' access.log</pre>
<p></code></p>
</li>
<li>
<p><strong>Matching eXact word only</strong> - by default grepping for <strong>Word</strong> will return lines containing <strong>SomeWord</strong> and <strongWordByTheWay</strong>. If We would like to find only those lines containing exact word <strong>Word</strong> We should use:</p>
<p>
<pre><code>grep -x '404' access.log</pre>
<p></code></p>
</li>
<p><strong>grep -w</strong> could be also useful here.</p>
<li>
<p><strong>Matching left and right side of the word</strong> - to search for instances of string matching Word in the end or start We use <strong>\<</strong> or <strong>\></strong>:</p>
<p>Below would match any word starting with <strong>access</strong>, like <strong>access_entry</strong>:</p>
<p>
<pre><code>grep 'error\>'</pre>
<p></code></p>
<p>Below would match any word ending with <strong>error</strong>, like <strong>general_error</strong>:</p>
<p>
<pre><code>grep '\&lt;access'</pre>
<p></code></p>
<li>
<p><strong>Showing context results</strong> - sometimes We would like to grep for some errors in logs, but we also would like to view the context of that log entry - e.g. grepping for '<strong>Relay access denied</strong>' in Postfix logs to see If that error is occurring with some pattern:</p>
<p>
<pre><code>grep --context=3 'Relay access denied' maillog</pre>
<p></code></p>
<li>
<p><strong>zgrep</strong> - this one would grep in the compressed gzip file - just like <strong>gunzip -c flog.gz | grep Word</strong>:</p>
<p>
<pre><code>zgrep 'Relay access denied' maillog3.gz</pre>
<p></code></p>
<li>
<p><strong>Coloring matched words</strong> - We can highlight our matched words with some color (check man page to see how to set exact color):</p>
<p>
<pre><code>grep --color 'Relay access denied' maillog3.gz</pre>
<p></code></p>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://maciek.lasyk.info/sysop/2011/12/07/grep-is-your-friend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Integrating Perforce with VIM</title>
		<link>http://maciek.lasyk.info/sysop/2011/12/07/integrating-perforce-with-vim/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=integrating-perforce-with-vim</link>
		<comments>http://maciek.lasyk.info/sysop/2011/12/07/integrating-perforce-with-vim/#comments</comments>
		<pubDate>Wed, 07 Dec 2011 14:15:56 +0000</pubDate>
		<dc:creator>docent</dc:creator>
				<category><![CDATA[humor]]></category>
		<category><![CDATA[perforce]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://maciek.lasyk.info/sysop/?p=3</guid>
		<description><![CDATA[I&#8217;ve just searched for method of integrating VIM with Perforce.. first shot was https://github.com/vim-scripts/perforce.vim &#8211; at a glance looked well: Features: - menu and keyboard shortcuts to open (checkout), revert, and sync files. - prompts to open a file for &#8230;<p class="read-more"><a href="http://maciek.lasyk.info/sysop/2011/12/07/integrating-perforce-with-vim/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just searched for method of integrating VIM with Perforce.. first shot was <a href="https://github.com/vim-scripts/perforce.vim" title="https://github.com/vim-scripts/perforce.vim">https://github.com/vim-scripts/perforce.vim</a> &#8211; at a glance looked well:</p>
<blockquote><p>Features:<br />
- menu and keyboard shortcuts to open (checkout), revert, and sync files.<br />
- prompts to open a file for editing when you attempt to change a checked-in file.<br />
- perforce status displayed on the ruler.</p></blockquote>
<p>Until I reached this:</p>
<blockquote><p>- tested on Windows operating systems only.</p></blockquote>
<p>Bloody hell I say.. who the heck makes integration of P4 and VIM outside (and only outside) Lin? :) It made me really amused :)</p>
]]></content:encoded>
			<wfw:commentRss>http://maciek.lasyk.info/sysop/2011/12/07/integrating-perforce-with-vim/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

