<?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>Scott Mcintyre</title>
	<atom:link href="http://scott.cm/feed/" rel="self" type="application/rss+xml" />
	<link>http://scott.cm</link>
	<description>Linux System Administration</description>
	<lastBuildDate>Thu, 19 Apr 2012 23:03:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Unable to uninstall munin</title>
		<link>http://scott.cm/unable-to-uninstall-munin/</link>
		<comments>http://scott.cm/unable-to-uninstall-munin/#comments</comments>
		<pubDate>Thu, 19 Apr 2012 23:03:01 +0000</pubDate>
		<dc:creator>Scott Mcintyre</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Monitoring]]></category>
		<category><![CDATA[munin debian munin-2 monitoring]]></category>

		<guid isPermaLink="false">http://scott.cm/?p=175</guid>
		<description><![CDATA[While testing munin 2.x on debian, I was unable to uninstall it, Removing munin-node ... [FAIL] Munin-Node appears to be unconfigured. ... failed! invoke-rc.d: initscript munin-node, action "stop" failed. dpkg: error processing munin-node (--purge): subprocess installed pre-removal script returned error exit status 6 [FAIL] Munin-Node appears to be unconfigured. ... failed! invoke-rc.d: initscript munin-node, action [...]]]></description>
			<content:encoded><![CDATA[<p>While testing munin 2.x on debian,  I was unable to uninstall it,</p>
<pre>
Removing munin-node ...
[FAIL] Munin-Node appears to be unconfigured. ... failed!
invoke-rc.d: initscript munin-node, action "stop" failed.
dpkg: error processing munin-node (--purge):
 subprocess installed pre-removal script returned error exit status 6
[FAIL] Munin-Node appears to be unconfigured. ... failed!
invoke-rc.d: initscript munin-node, action "start" failed.
dpkg: error while cleaning up:
 subprocess installed post-installation script returned error exit status 6
Errors were encountered while processing:
 munin-node
E: Sub-process /usr/bin/dpkg returned an error code (1)
</pre>
<p>The init.d checks if it&#8217;s configured</p>
<p>/etc/init.d/munin-node</p>
<pre>
elif [ ! -e $CONFFILE ]; then
	log_failure_msg "Munin-Node appears to be unconfigured."
	exit 6
fi
</pre>
<p>Which is what is causing this issue,  changing this too,</p>
<pre>
elif [ ! -e $CONFFILE &#038;&#038; $1 != "stop" ]; then
	log_failure_msg "Munin-Node appears to be unconfigured."
	exit 6
fi
</pre>
<p>Should solve the issue.</p>
]]></content:encoded>
			<wfw:commentRss>http://scott.cm/unable-to-uninstall-munin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Varnish Nagios Check</title>
		<link>http://scott.cm/varnish-nagios-check/</link>
		<comments>http://scott.cm/varnish-nagios-check/#comments</comments>
		<pubDate>Thu, 19 Apr 2012 20:34:35 +0000</pubDate>
		<dc:creator>Scott Mcintyre</dc:creator>
				<category><![CDATA[System Administration]]></category>
		<category><![CDATA[icinga]]></category>
		<category><![CDATA[nagios]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[varnish]]></category>

		<guid isPermaLink="false">http://scott.cm/?p=157</guid>
		<description><![CDATA[I have written a check for nagios/icinga to check the varnish backend health. You can get the latest version from github . The version at the time of posting at the bottom of this message. The defaults are RHEL defaults and ./check_varnishbackends.py should work without any options unless you want to override them. Here is [...]]]></description>
			<content:encoded><![CDATA[<p>I have written a check for nagios/icinga to check the varnish backend health.  You can get the latest version from <a href="https://github.com/Scott-Mc/python/blob/master/check_varnishbackends.py" title="Check Varnish Backends" target="_blank">github </a>.  The version at the time of posting at the bottom of this message.</p>
<p>The defaults are RHEL defaults and ./check_varnishbackends.py should work without any options unless you want to override them.   Here is the Nagios/Icinga Setup,</p>
<p>Register the service</p>
<pre>
define service {
	register			0
	name				check_varnishbackends
	service_description		Varnish Backends
	use				generic-service
}
</pre>
<p>Assign to host &#8220;server&#8221;</p>
<pre>
define service {
	service_description		Varnish Backend
	host_name			server
	use				check_varnishbackends
	check_command			remote_nrpe!check_varnishbackends -a "127.0.0.1" "6082" "/etc/varnish/secret" "/usr/bin/varnishadm"
}
</pre>
<p>Setup NRPE (Make sure user has permission to varnish secret file or use sudo)</p>
<pre>
command[check_varnishbackends]=/usr/local/nagios/libexec/check_varnishbackends.py --host $ARG1$ --port $ARG2$ --secret $ARG3$ --path $ARG4$
</pre>
<p>Version at time of posting,</p>
<pre>
#!/usr/bin/env python

#
# check_varnishbackends.py
# Varnish Backend Checker for Icinga/Nagios

# Author
#  - Scott Mcintyre <me @scott.cm>
#  - http://scott.cm
# Usage
#  -h, --help            	Show help message and exit
#  -H HOST, --host=HOST  	The ip varnishadm is listening on (Default: 127.0.0.1)
#  -P PORT, --port=PORT  	The port varnishadm is listening on (Default: 6082)
#  -s SECRET, --secret=SECRET 	The path to the secret file (Default: /etc/varnish/secret)
#  -p PATH, --path=PATH  	The path to the varnishadm binary (Default: /usr/bin/varnishadm
# Example: ./check_varnishbackends.py -H 127.0.0.1 -P 6082 -S /etc/varnish/secret -p /usr/bin/varnishadm
# 

import sys
import optparse
import subprocess

def runcommand(command, exit_on_fail=True):
    try:
      process = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE)
      output, unused_err = process.communicate()
      retcode = process.poll()
      return output

    except OSError, e:
      print "Error: Executing command failed,  does it exist?"
      sys.exit(2)

def main(argv):
  o = optparse.OptionParser(conflict_handler="resolve", description="Nagios plugin to check varnish backend health.")
  o.add_option('-H', '--host', action='store', type='string', dest='host', default='127.0.0.1', help='The ip varnishadm is listening on')
  o.add_option('-P', '--port', action='store', type='int', dest='port', default=6082, help='The port varnishadm is listening on')
  o.add_option('-s', '--secret', action='store', type='string', dest='secret', default='/etc/varnish/secret', help='The path to the secret file')
  o.add_option('-p', '--path', action='store', type='string', dest='path', default='/usr/bin/varnishadm', help='The path to the varnishadm binary')

  options=o.parse_args()[0]
  command = runcommand("%(path)s -S %(secret)s -T %(host)s:%(port)s debug.health" % options.__dict__)
  backends = command.split("\n")
  backends_healthy, backends_sick = [], []
  for line in backends:
    if line.startswith("Backend") and line.find("test")==-1:
      if line.endswith("Healthy"):
        backends_healthy.append(line.split(" ")[1])
      else:
        backends_sick.append(line.split(" ")[1])

  if backends_sick:
    print "%s backends are down.  %s" % (len(backends_sick), "".join(backends_sick))
    sys.exit(2)

  if not backends_sick and not backends_healthy:
    print "No backends found"
    sys.exit(1)

  print "All %s backends are healthy" % (len(backends_healthy))
  sys.exit(0)

if __name__ == "__main__":
    main(sys.argv[1:])
</me></pre>
]]></content:encoded>
			<wfw:commentRss>http://scott.cm/varnish-nagios-check/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Skype Auto Popup with Cinnamon</title>
		<link>http://scott.cm/skype-auto-popup-with-cinnamon/</link>
		<comments>http://scott.cm/skype-auto-popup-with-cinnamon/#comments</comments>
		<pubDate>Tue, 17 Apr 2012 08:52:22 +0000</pubDate>
		<dc:creator>Scott Mcintyre</dc:creator>
				<category><![CDATA[Linux Mint]]></category>

		<guid isPermaLink="false">http://scottmcintyre.net/?p=152</guid>
		<description><![CDATA[Since my migration to Linux Mint 12 I noticed a very annoying issue. When receiving a new message Skype pops up to the forefront over the current window. Needless to say it&#8217;s extremely annoying! Luckily a quick google shows a active bug at github which contains a couple of suggestions. I tried simply disabling the [...]]]></description>
			<content:encoded><![CDATA[<p>Since my <a href="http://scottmcintyre.net/migrating-from-ubuntu-11-10-to-linux-mint/" title="Migrating from Ubuntu 11.10 to Linux Mint">migration to Linux Mint 12</a> I noticed a very annoying issue.   When receiving a new message Skype pops up to the forefront over the current window.   Needless to say it&#8217;s extremely annoying!</p>
<p>Luckily a quick google shows a active <a href="https://github.com/linuxmint/Cinnamon/issues/233">bug</a> at github which contains a couple of suggestions.   I tried simply disabling the auto focus feature bit this ended up making all my panels disappear.  This <a href="https://github.com/rat4/Cinnamon/compare/notification_style" target="_blank">fix</a> by rat4 seems to solve the problem.</p>
<p>Here&#8217;s what I done</p>
<pre>
sudo wget -O /usr/share/cinnamon/js/ui/windowAttentionHandler.js https://raw.github.com/rat4/Cinnamon/21a08f6f9e13f7ba4e3bf633b7ba4b36fd22a291/js/ui/windowAttentionHandler.js
sudo wget -O /usr/share/glib-2.0/schemas/org.cinnamon.gschema.xml https://raw.github.com/rat4/Cinnamon/21a08f6f9e13f7ba4e3bf633b7ba4b36fd22a291/data/org.cinnamon.gschema.xml
sudo apt-get install dconf-tools
</pre>
<p>Went to System Tools->Dconf Editor and change the value of <strong>notification-style</strong> to <strong>0</strong></p>
<p><img src="http://scottmcintyre.net/wp-content/uploads/2012/04/Selection_005.png" alt="Screenshot of dconf editor" /></p>
<p>Possible values are,</p>
<p>0 &#8211; do nothing here, but other notificators (window list applet) still can take care<br />
1 &#8211; bring window to front, like current cinnamon<br />
2 &#8211; show banner &#8220;app is ready&#8221;, like gnome shell</p>
<p>The final step is just to restart Cinnamon.</p>
<p>Now when I get a new message it has the desired effect and simply flashes rather than pops up.</p>
<p><img src="http://scottmcintyre.net/wp-content/uploads/2012/04/Selection_004.png" alt="FIxed skype notification" /></p>
]]></content:encoded>
			<wfw:commentRss>http://scott.cm/skype-auto-popup-with-cinnamon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Migrating from Ubuntu 11.10 to Linux Mint</title>
		<link>http://scott.cm/migrating-from-ubuntu-11-10-to-linux-mint/</link>
		<comments>http://scott.cm/migrating-from-ubuntu-11-10-to-linux-mint/#comments</comments>
		<pubDate>Mon, 16 Apr 2012 22:02:27 +0000</pubDate>
		<dc:creator>Scott Mcintyre</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Linux Mint]]></category>

		<guid isPermaLink="false">http://scottmcintyre.net/?p=90</guid>
		<description><![CDATA[Last night I decided to apply the Ubuntu 11.10 upgrade because the update notification was getting annoying and boy it turned out to be a pain. The previous upgrade introduced Unity which if you just have a google search look at the top recommendations should explain it all. &#8220;Unity Sucks&#8221; the top recommendation next to [...]]]></description>
			<content:encoded><![CDATA[<p>Last night I decided to apply the Ubuntu 11.10 upgrade because the update notification was getting annoying and boy it turned out to be a pain. The previous upgrade introduced Unity which if you just have a google search look at the top recommendations should explain it all. </p>
<p><img src="http://scottmcintyre.net/wp-content/uploads/2012/04/Unity-Sucks.png" alt="Google Recommendations for Unity" /></p>
<p>&#8220;Unity Sucks&#8221; the top recommendation next to the term itself.  </p>
<p>In the previous release I was happy because the gnome classic to get gnome 2 worked but as of 11.10 this isn&#8217;t possible.  It&#8217;s either Unity or GNOME 3 (Classic is available).  Unity lasted no more than 10 minutes in testing,  it&#8217;s clearly designed for tablets and is horrendous to use.   GNOME 3 I could get used to but would need to tweak more,  I really dislike the overly large icons and large notifications.</p>
<p>After a bit of trial and messing around I even managed to make all my panels disappear and couldn&#8217;t figure out how to return them and decided to just take the plunge and switch to mint 12 with cinnamon.   The migration was rather easy,  I simply installed mint and restored my backup of /home to retain all my old settings.  Reinstalled skype, thunderbird,  chrome,  firefox, nagstamon and xchat and that was everything back with the exception of being on Mint 12.</p>
<p>The standard mint brings the gnome 2 feel but I still couldn&#8217;t quite take to it so went ahead and installed cinnamon and I have to say I quite like it.   With the exception of not having a taskbar on the other screens but there does seem to be a bug issue last updated a few days ago for this at <a href="https://github.com/linuxmint/Cinnamon/issues/130">https://github.com/linuxmint/Cinnamon/issues/130</a> so with any luck this will be introduced soon.</p>
<p>Overall everything seems quite snappy,   the UI is what I want and it&#8217;s back to business as usual.</p>
]]></content:encoded>
			<wfw:commentRss>http://scott.cm/migrating-from-ubuntu-11-10-to-linux-mint/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Twitter Mass Unfollow With Python</title>
		<link>http://scott.cm/twitter-mass-unfollow-with-python/</link>
		<comments>http://scott.cm/twitter-mass-unfollow-with-python/#comments</comments>
		<pubDate>Mon, 16 Apr 2012 21:43:19 +0000</pubDate>
		<dc:creator>Scott Mcintyre</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://scottmcintyre.net/?p=125</guid>
		<description><![CDATA[I decided to revive my old twitter account and wanted to unfollow all my old friends list,  the majority were gained from an auto-follow script a few years ago and are nothing but spam.   Given I want to start using twitter I only want to follow people I am interested in.   It was [...]]]></description>
			<content:encoded><![CDATA[<p>I decided to revive my old twitter account and wanted to unfollow all my old friends list,  the majority were gained from an auto-follow script a few years ago and are nothing but spam.   Given I want to start using twitter I only want to follow people I am interested in.   It was more difficult than I expected to simply purge your followers.</p>
<p>It appears twitter don&#8217;t allow most of the apps (and there are lots of them) to mass unfollow as part of their TOS.   I found this at <a href="http://www.hostnexus.com/blog/how-to-bulk-unfollow-on-twitter" target="_blank">http://www.hostnexus.com/blog/how-to-bulk-unfollow-on-twitter</a> and decided to give the steps in there a shot.   I tried a few of the apps with the chrome check all plugin but all of them have daily limits and given up here. This is when I decided instead to just write a quick python script using the API.</p>
<p>It was easy enough to get started with the twitter API.<br />
Simply visit <a href="https://dev.twitter.com" target="_blank">https://dev.twitter.com</a>  and login with your account.  <br />
Create a new application,   get your key.<br />
Install the twitter python API at <a href="http://code.google.com/p/python-twitter/" target="_blank">http://code.google.com/p/python-twitter/</a></p>
<p>You can get the latest version of the script at: <a href="https://github.com/Scott-Mc/python/blob/master/twitter-mass-unfollow.py" target="_blank">https://github.com/Scott-Mc/python/blob/master/twitter-mass-unfollow.py</a> and the version at the time of writing at the bottom of this post.</p>
<p>This was my profile before running the script<br />
<img src="http://scottmcintyre.net/wp-content/uploads/2012/04/twitter_friends_before.png" alt="Twitter Friends Before Mass Purge" /></p>
<p>This is my profile now after running the script,</p>
<p><img src="http://scottmcintyre.net/wp-content/uploads/2012/04/twitter_friends_after.png" alt="Twitter Friends After Mass Purge" /></p>
<p>This is the code at the time of writing,</p>
<pre>
#!/usr/bin/env python

#
#Mass unfollow friends on twitter
#

# Author
#  - Scott Mcintyre <scott @scottmcintyre.net>
#
# Usage
#
# Get your keys from https://dev.twitter.com/
# Ensure it has write access
# Change the api key values marked ##### below with the twitter keys
# Install http://code.google.com/p/python-twitter/

import twitter
import time

api = twitter.Api(consumer_key='#####', consumer_secret='#####', access_token_key='#####', access_token_secret='#####')

start = time.time()
i = 0
friends=api.GetFriends()

while (1):
 try:
  for u in friends:
   print "Deleting %s" % (u.name)
   api.DestroyFriendship(u.id);
   i = i + 1

 except:
   print "Possibly Rate limited? sleeping 60 seconds"
   time.sleep(60)

elapsed = (time.time() - start)
print "Deleted %s friends in %0.2f seconds" % (str(i), elapsed)
</scott></pre>
]]></content:encoded>
			<wfw:commentRss>http://scott.cm/twitter-mass-unfollow-with-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ERROR: Module backupdriver is in use</title>
		<link>http://scott.cm/error-module-backupdriver-is-in-use/</link>
		<comments>http://scott.cm/error-module-backupdriver-is-in-use/#comments</comments>
		<pubDate>Sat, 14 Apr 2012 15:13:09 +0000</pubDate>
		<dc:creator>Scott Mcintyre</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[R1soft]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[backupdriver is in use]]></category>
		<category><![CDATA[buagent]]></category>
		<category><![CDATA[Module backupdriver is in use]]></category>
		<category><![CDATA[r1soft cdp3]]></category>
		<category><![CDATA[r1soft error]]></category>
		<category><![CDATA[r1soft install]]></category>
		<category><![CDATA[r1soft uninstall]]></category>
		<category><![CDATA[removing buagent]]></category>
		<category><![CDATA[rmmod backupdriver]]></category>
		<category><![CDATA[unloading backupdriver]]></category>

		<guid isPermaLink="false">http://scottmcintyre.net/?p=86</guid>
		<description><![CDATA[While updating several of our remaining systems from r1soft CDP 2 to CDP 3 we&#8217;ve been getting the following error, ERROR: Module backupdriver is in use r1soft-uninstall-buagent -R This uninstaller will remove the following.. File /etc/init.d/buagent File /usr/bin/buagent File /var/lock/buagent.lock File /var/run/buagent.pid File /usr/bin/r1key File /usr/bin/r1soft-cki File /usr/bin/r1soft-report.sh File /usr/bin/r1soft-uninstall-buagent File /usr/share/man/man3/buagent.3.gz File /usr/share/man/man3/r1key.3.gz File [...]]]></description>
			<content:encoded><![CDATA[<p>While updating several of our remaining systems from r1soft CDP 2 to CDP 3 we&#8217;ve been getting the following error,</p>
<p>ERROR: Module backupdriver is in use</p>
<p><code>r1soft-uninstall-buagent -R<br />
This uninstaller will remove the following..</code></p>
<p>File /etc/init.d/buagent<br />
File /usr/bin/buagent<br />
File /var/lock/buagent.lock<br />
File /var/run/buagent.pid<br />
File /usr/bin/r1key<br />
File /usr/bin/r1soft-cki<br />
File /usr/bin/r1soft-report.sh<br />
File /usr/bin/r1soft-uninstall-buagent<br />
File /usr/share/man/man3/buagent.3.gz<br />
File /usr/share/man/man3/r1key.3.gz<br />
File /usr/share/man/man3/r1soft-uninstall-buagent.3.gz<br />
Directory /etc/buagent<br />
Directory /usr/lib/buagent<br />
Directory /lib/modules/buagent<br />
Directory /var/cache/buagent<br />
Directory /var/db/buagent<br />
User buagent<br />
Group buagent</p>
<p>Would you like to continue? (yes/no):yes<br />
stopping buagent.<br />
removing buagent from services.<br />
removing File /etc/init.d/buagent<br />
removing File /usr/bin/buagent<br />
removing File /var/lock/buagent.lock<br />
removing File /var/run/buagent.pid<br />
removing File /usr/bin/r1key<br />
removing File /usr/bin/r1soft-cki<br />
removing File /usr/bin/r1soft-report.sh<br />
removing File /usr/bin/r1soft-uninstall-buagent<br />
removing File /usr/share/man/man3/buagent.3.gz<br />
removing File /usr/share/man/man3/r1key.3.gz<br />
removing File /usr/share/man/man3/r1soft-uninstall-buagent.3.gz<br />
removing Directory /etc/buagent<br />
removing Directory /usr/lib/buagent<br />
removing Directory /lib/modules/buagent<br />
removing Directory /var/cache/buagent<br />
removing Directory /var/db/buagent<br />
removing buagent user…<br />
unloading backupdriver kernel module…<br />
ERROR: Module backupdriver is in use<br />
done.</p>
<p>Trying to simply rmmod the driver fails because it&#8217;s in use but without having forced support there is no way to unload it using this method.</p>
<p><code><br />
# rmmod backupdriver<br />
ERROR: Module backupdriver is in use<br />
</code></p>
<p>The solution is to reinstall the latest CDP 2 agent and run <strong>buagent -u</strong> to unload it first then proceed to uninstalling the CDP2 agent and installing CDP3 agent.</p>
]]></content:encoded>
			<wfw:commentRss>http://scott.cm/error-module-backupdriver-is-in-use/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mounting ext2/ext3 partitions on windows</title>
		<link>http://scott.cm/mounting-ext2ext3-partitions-on-windows/</link>
		<comments>http://scott.cm/mounting-ext2ext3-partitions-on-windows/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 15:57:05 +0000</pubDate>
		<dc:creator>Scott Mcintyre</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[ext2 windows]]></category>
		<category><![CDATA[ext2/3 partiton windows]]></category>
		<category><![CDATA[ext2/ext3 partition windows]]></category>
		<category><![CDATA[ext3 windows]]></category>
		<category><![CDATA[ext3 windows 7]]></category>
		<category><![CDATA[mount ext2 partition on windows]]></category>
		<category><![CDATA[mount ext2/3 partition on windows]]></category>
		<category><![CDATA[mount ext2/3 windows]]></category>
		<category><![CDATA[mount ext2/ext3 windows]]></category>
		<category><![CDATA[mount ext3 in windows]]></category>
		<category><![CDATA[mount ext3 on windows]]></category>
		<category><![CDATA[mount ext3 partition on windows]]></category>

		<guid isPermaLink="false">http://scottmcintyre.net/?p=84</guid>
		<description><![CDATA[Today I needed to mount one of my USB sticks on windows to copy some files over. To get windows to recognise it I altered/etc/mke2fs.conf and done the following. Removed ext_addr from &#8220;base_features&#8221; and commented out the inode_size line. Here is a diff from the default ubuntu e2fsprogs /etc/mke2fs.conf with the necessary changes, &#160; &#8212; [...]]]></description>
			<content:encoded><![CDATA[<p>Today I needed to mount one of my USB sticks on windows to copy some files over. To get windows to recognise it I altered/etc/mke2fs.conf and done the following.</p>
<p>Removed <em>ext_addr</em> from &#8220;base_features&#8221; and commented out the <em>inode_size</em> line. Here is a diff from the default ubuntu e2fsprogs /etc/mke2fs.conf with the necessary changes,</p>
<p>&nbsp;</p>
<p>&#8212; /etc/mke2fs.orig.conf 2011-11-28 15:20:07.365231775 +0000<br />
+++ /etc/mke2fs.conf 2011-11-28 15:20:48.165231803 +0000<br />
@@ -1,7 +1,7 @@<br />
[defaults]<br />
- base_features = sparse_super,filetype,resize_inode,dir_index,ext_attr<br />
+ base_features = sparse_super,filetype,resize_inode,dir_index<br />
blocksize = 4096<br />
- inode_size = 256<br />
+ #inode_size = 256<br />
inode_ratio = 16384</p>
<p>[fs_types]</p>
<p>Then format the partition and this will allow it to be mounted on windows.</p>
<p>I used DiskInternals Linux Reader on windows to mount the drive and copy the files which can be downloaded for free at</p>
]]></content:encoded>
			<wfw:commentRss>http://scott.cm/mounting-ext2ext3-partitions-on-windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress Auto Wrapping Code</title>
		<link>http://scott.cm/wordpress-auto-wrapping-code/</link>
		<comments>http://scott.cm/wordpress-auto-wrapping-code/#comments</comments>
		<pubDate>Thu, 24 Nov 2011 12:35:51 +0000</pubDate>
		<dc:creator>Scott Mcintyre</dc:creator>
				<category><![CDATA[System Administration]]></category>
		<category><![CDATA[auto wrap wordpress]]></category>
		<category><![CDATA[long code wordpress]]></category>
		<category><![CDATA[wrap text]]></category>
		<category><![CDATA[wrap text wordpress]]></category>

		<guid isPermaLink="false">http://scottmcintyre.net/?p=80</guid>
		<description><![CDATA[When posting code it wasn&#8217;t wrapping text properly on my blog due to how narrow it is. Luckily there&#8217;s some easy code that already exists to solve this so reposting it. height: 120px; overflow: auto; font-family: “Consolas”,monospace; font-size: 9pt; text-align:left; background-color: #FCF7EC; overflow-x: auto; /* Use horizontal scroller if needed; for Firefox 2, not white-space: [...]]]></description>
			<content:encoded><![CDATA[<p>When posting code it wasn&#8217;t wrapping text properly on my blog due to how narrow it is. Luckily there&#8217;s some easy code that already exists to solve this so reposting it.</p>
<p><code><br />
height: 120px;<br />
overflow: auto;<br />
font-family: “Consolas”,monospace;<br />
font-size: 9pt;<br />
text-align:left;<br />
background-color: #FCF7EC;<br />
overflow-x: auto; /* Use horizontal scroller if needed; for Firefox 2, not<br />
white-space: pre-wrap; /* css-3 */<br />
white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */<br />
word-wrap: break-word; /* Internet Explorer 5.5+ */<br />
margin: 0px 0px 0px 0px;<br />
padding:5px 5px 3px 5px;<br />
white-space : normal; /* crucial for IE 6, maybe 7? */<br />
</code></p>
<p>Hopefully others find this useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://scott.cm/wordpress-auto-wrapping-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Learning Python</title>
		<link>http://scott.cm/learning_python/</link>
		<comments>http://scott.cm/learning_python/#comments</comments>
		<pubDate>Thu, 24 Nov 2011 12:24:02 +0000</pubDate>
		<dc:creator>Scott Mcintyre</dc:creator>
				<category><![CDATA[Me]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[football scores python]]></category>
		<category><![CDATA[learn python in 2 days]]></category>
		<category><![CDATA[learning python]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[python threading]]></category>
		<category><![CDATA[python youtube]]></category>
		<category><![CDATA[server version scraper]]></category>
		<category><![CDATA[top 100 charts]]></category>
		<category><![CDATA[youtube charts]]></category>

		<guid isPermaLink="false">http://scottmcintyre.net/?p=72</guid>
		<description><![CDATA[I had set myself a goal to make around 20 blog posts per year, it&#8217;s now almost December and I still have not bothered. It is safe to say I am not exactly prolific. I decided that I would learn python, surprisingly it&#8217;s been really easy to pick up and I thought I would share [...]]]></description>
			<content:encoded><![CDATA[<p>I had set myself a goal to make around 20 blog posts per year, it&#8217;s now almost December and I still have not bothered. It is safe to say I am not exactly prolific.</p>
<p>I decided that I would learn python, surprisingly it&#8217;s been really easy to pick up and I thought I would share some of the things I made in my first 2 days of python.</p>
<p>The first I written was to phrase the results from yahoo&#8217;s football score page(http://uk.eurosport.yahoo.com/football/premier-league/2011-2012/results/2011_08.html). I was on this page anyway and thought why not!</p>
<pre>#!/usr/bin/python
import urllib2
import re
response = urllib2.urlopen('http://uk.eurosport.yahoo.com/football/premier-league/2011-2012/results/2011_08.html')
html = response.read()
re_channel = re.compile("&lt;td class=\"ko\"&gt;&lt;abbr class=\"dtstart\" title=\"\"&gt;([0-9a-zA-z ,:]*)&lt;/abbr&gt;&lt;/td&gt;" +
 "\n &lt;td class=\"match.*?\n" +
 " &lt;a href=.*?\"&gt;" +
  "\n &lt;span class=\"home\"&gt;([a-zA-Z ]*)&lt;/span&gt;.*?" +
  "\n &lt;span class=\"score\"&gt;([0-9 :-]*)&lt;/span&gt;.*?" +
  "\n &lt;span class=\"away\"&gt;([a-zA-Z ]*)&lt;/span&gt;", re.I | re.S | re.M)
find_result = re_channel.findall(html)
print find_result</pre>
<pre></pre>
<p>Sample output</p>
<p>[('13 Aug, 15:00', 'Wigan Athletic', '1 - 1', 'Norwich City'), ('13 Aug, 15:00', 'Fulham', '0 - 0', 'Aston Villa'), ('13 Aug, 15:00', 'Blackburn Rovers', '1 - 2', 'Wolverhampton Wanderers'), ('13 Aug, 15:00', 'Liverpool', '1 - 1', 'Sunderland'), ('13 Aug, 15:00', 'Queens Park Rangers', '0 - 4', 'Bolton Wanderers'), ('13 Aug, 17:30', 'Newcastle United', '0 - 0', 'Arsenal'), ('14 Aug, 13:30', 'Stoke City', '0 - 0', 'Chelsea'), ('14 Aug, 16:00', 'West Bromwich Albion', '1 - 2', 'Manchester United'), ('15 Aug, 20:00', 'Manchester City', '4 - 0', 'Swansea City'), ('20 Aug, 12:00', 'Sunderland', '0 - 1', 'Newcastle United'), ('20 Aug, 12:45', 'Arsenal', '0 - 2', 'Liverpool'), ('20 Aug, 15:00', 'Swansea City', '0 - 0', 'Wigan Athletic'), ('20 Aug, 15:00', 'Aston Villa', '3 - 1', 'Blackburn Rovers'), ('20 Aug, 15:00', 'Everton', '0 - 1', 'Queens Park Rangers'), ('20 Aug, 17:30', 'Chelsea', '2 - 1', 'West Bromwich Albion'), ('21 Aug, 13:30', 'Norwich City', '1 - 1', 'Stoke City'), ('21 Aug, 14:05', 'Wolverhampton Wanderers', '2 - 0', 'Fulham'), ('21 Aug, 16:00', 'Bolton Wanderers', '2 - 3', 'Manchester City'), ('22 Aug, 20:00', 'Manchester United', '3 - 0', 'Tottenham Hotspur'), ('27 Aug, 12:05', 'Aston Villa', '0 - 0', 'Wolverhampton Wanderers'), ('27 Aug, 12:30', 'Wigan Athletic', '2 - 0', 'Queens Park Rangers'), ('27 Aug, 15:00', 'Swansea City', '0 - 0', 'Sunderland'), ('27 Aug, 15:00', 'Chelsea', '3 - 1', 'Norwich City'), ('27 Aug, 15:00', 'Blackburn Rovers', '0 - 1', 'Everton'), ('27 Aug, 17:30', 'Liverpool', '3 - 1', 'Bolton Wanderers'), ('28 Aug, 13:00', 'Newcastle United', '2 - 1', 'Fulham'), ('28 Aug, 13:30', 'Tottenham Hotspur', '1 - 5', 'Manchester City'), ('28 Aug, 15:00', 'West Bromwich Albion', '0 - 1', 'Stoke City'), ('28 Aug, 16:00', 'Manchester United', '8 - 2', 'Arsenal')]</p>
<p>The next was to obtain a list of the uk charts top 100 and find the youtube video for it.</p>
<pre>#!/usr/bin/python
import urllib
import urllib2
import re
import sys
from BeautifulSoup import BeautifulStoneSoup  

def getvideolink(link):
  request = urllib2.Request(link)
  request.add_header('User-Agent', "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.3 (KHTML, like Gecko) Qt/4.7.0 Safari/533.3")
  response = urllib2.urlopen(request)
  text = response.read()
  videos = re.findall("&lt;a href=\"/watch\?v=([\w-]+)", text)
  return "http://www.youtube.com/watch?v=%s" % videos[0]

response = urllib2.urlopen('http://localhost/test')
html = response.read()
re_channel = re.compile("&lt;h3&gt;(.*?)&lt;/h3&gt;" +
 "\r\n.*?&lt;h4&gt;(.*?)&lt;/h4&gt;.*?&lt;h5", re.I | re.S | re.M)
find_result = re_channel.findall(html)
#remove first entry as it's a dup
del find_result[0]
for result in find_result:
 title=unicode(BeautifulStoneSoup(result[0],convertEntities=BeautifulStoneSoup.HTML_ENTITIES ))
 artist=unicode(BeautifulStoneSoup(result[1],convertEntities=BeautifulStoneSoup.HTML_ENTITIES ))
 link="http://www.youtube.com/results?search_query=" + urllib.quote_plus(title);
 print getvideolink(link)</pre>
<pre></pre>
<pre>Sample output</pre>
<pre>RIHANNA FT CALVIN HARRIS - WE FOUND LOVE // http://www.youtube.com/watch?v=tg00YEETFzg
FLO RIDA - GOOD FEELING // http://www.youtube.com/watch?v=3OnnDqH6Wj8
ONE DIRECTION - GOTTA BE YOU // http://www.youtube.com/watch?v=nvfejaHz-o0
LABRINTH FT TINIE TEMPAH - EARTHQUAKE // http://www.youtube.com/watch?v=u0fk6syQ7iY
ED SHEERAN - LEGO HOUSE // http://www.youtube.com/watch?v=c4BLVznuWnU
DAVID GUETTA FT USHER - WITHOUT YOU // http://www.youtube.com/watch?v=jUe8uoKdHao
MAROON 5 FT CHRISTINA AGUILERA - MOVES LIKE JAGGER // http://www.youtube.com/watch?v=iEPTlhBmwRg
JLS - TAKE A CHANCE ON ME // http://www.youtube.com/watch?v=djV11Xbc914
PROFESSOR GREEN FT EMELI SANDE - READ ALL ABOUT IT // http://www.youtube.com/watch?v=-_oLfC5Z_Ys
CHRISTINA PERRI - JAR OF HEARTS // http://www.youtube.com/watch?v=8v_4O44sfjM
LMFAO - SEXY AND I KNOW IT // http://www.youtube.com/watch?v=wyx6JDQCslE
DRAKE FT RIHANNA - TAKE CARE // http://www.youtube.com/watch?v=PaXslpx3MWY
COLDPLAY - PARADISE // http://www.youtube.com/watch?v=1G4isv_Fylg
CHARLENE SORAIA - WHEREVER YOU WILL GO // http://www.youtube.com/watch?v=iAP9AF6DCu4
SATURDAYS - MY HEART TAKES OVER // http://www.youtube.com/watch?v=DgmoYgpMNX8
CHER LLOYD FT MIKE POSNER - WITH UR LOVE // http://www.youtube.com/watch?v=axpO86pGHAM
BRUNO MARS - IT WILL RAIN // http://www.youtube.com/watch?v=W-w3WfgpcGg
LADY GAGA - MARRY THE NIGHT // http://www.youtube.com/watch?v=O4IgYxHEAuk
LANA DEL REY - VIDEO GAMES // http://www.youtube.com/watch?v=HO1OV5B_JDw
PIXIE LOTT FT PUSHA T - WHAT DO YOU TAKE ME FOR // http://www.youtube.com/watch?v=OQCcwNMp830
KELLY CLARKSON - MR KNOW IT ALL // http://www.youtube.com/watch?v=0C_oNMH0GTk
LOICK ESSIEN - ME WITHOUT YOU // http://www.youtube.com/watch?v=lKDmJwoZ4RA
FLORENCE &amp; THE MACHINE - SHAKE IT OUT // http://www.youtube.com/watch?v=WbN0nX61rIs
COLLECTIVE - TEARDROP // http://www.youtube.com/watch?v=u7K72X4eo_s
ONE DIRECTION - WHAT MAKES YOU BEAUTIFUL // http://www.youtube.com/watch?v=QJO3ROT-A4E
ED SHEERAN - THE A TEAM // http://www.youtube.com/watch?v=UAWcs5H-qgQ
WANTED - LIGHTNING // http://www.youtube.com/watch?v=MQyHyfLp5NI
JESSIE J - WHO YOU ARE // http://www.youtube.com/watch?v=j2WWrupMBAE
LUCENZO &amp; QWOTE - DANZA KUDURO // http://www.youtube.com/watch?v=rUFgacK8sZ0
GYM CLASS HEROES/ADAM LEVINE - STEREO HEARTS // http://www.youtube.com/watch?v=T3E9Wjbq44E
MAVERICK SABRE - I NEED // http://www.youtube.com/watch?v=VA770wpLX-Q
WESTLIFE - LIGHTHOUSE // http://www.youtube.com/watch?v=Tivph7mTku4
SEAN PAUL FT ALEXIS JORDAN - GOT 2 LUV U // http://www.youtube.com/watch?v=tDq3fNew1rU
LADY GAGA - THE EDGE OF GLORY // http://www.youtube.com/watch?v=QeWBS0JBNzQ
GLEE CAST - RUMOUR HAS IT/SOMEONE LIKE YOU // http://www.youtube.com/watch?v=qb7zjKkLCoQ
SLOW MOVING MILLIE - PLEASE PLEASE PLEASE LET ME GET WHAT I // http://www.youtube.com/watch?v=DMQbzLrvwlE
KATY PERRY - THE ONE THAT GOT AWAY // http://www.youtube.com/watch?v=Ahha3Cqe_fk
ELBOW - ONE DAY LIKE THIS // http://www.youtube.com/watch?v=0NFV8dHrZYM
CHRISTINA PERRI - A THOUSAND YEARS // http://www.youtube.com/watch?v=z5Q8x1wYN4w
SNOW PATROL - THIS ISN'T EVERYTHING YOU ARE // http://www.youtube.com/watch?v=Q-Gljs8Y3Q8
RIZZLE KICKS - WHEN I WAS A YOUNGSTER // http://www.youtube.com/watch?v=Rc2iUwMpb8Y
GOO GOO DOLLS - IRIS // http://www.youtube.com/watch?v=NdYWuo9OFAw
DAPPY - NO REGRETS // http://www.youtube.com/watch?v=WoImizvsj5w
BRUNO MARS - MARRY YOU // http://www.youtube.com/watch?v=xB40cQD677s
ADELE - SET FIRE TO THE RAIN // http://www.youtube.com/watch?v=ss0HAdW1DnY
NICKELBACK - WHEN WE STAND TOGETHER // http://www.youtube.com/watch?v=76RbWuFll0Y
AFROJACK &amp; STEVE AOKI - NO BEEF // http://www.youtube.com/watch?v=ksocjhxX_DQ
ADELE - SOMEONE LIKE YOU // http://www.youtube.com/watch?v=hLQl3WQQoQ0
PIXIE LOTT - ALL ABOUT TONIGHT // http://www.youtube.com/watch?v=swcULf1ATyU
NICKI MINAJ - SUPER BASS // http://www.youtube.com/watch?v=4JipHEz53sU
CALLING - WHEREVER YOU WILL GO // http://www.youtube.com/watch?v=iAP9AF6DCu4
JAMES MORRISON - I WON'T LET YOU GO // http://www.youtube.com/watch?v=sgRb_lfIZ6A
OLLY MURS FT RIZZLE KICKS - HEART SKIPS A BEAT // http://www.youtube.com/watch?v=j5dFe-WKuPs
EXAMPLE - MIDNIGHT RUN // http://www.youtube.com/watch?v=iwYGi7YG4Js
TINCHY STRYDER/CALVIN HARRIS - OFF THE RECORD // http://www.youtube.com/watch?v=UknZiaIC9y8
SAK NOEL - LOCA PEOPLE // http://www.youtube.com/watch?v=-d6b1yn-YhQ
BRUNO MARS - RUNAWAY BABY // http://www.youtube.com/watch?v=UDG_CrqJV-0
JASON DERULO - FIGHT FOR YOU // http://www.youtube.com/watch?v=2aSOQRih6WY
CHER LLOYD - SWAGGER JAGGER // http://www.youtube.com/watch?v=sdbyG2MrBHk
LADY GAGA - BORN THIS WAY // http://www.youtube.com/watch?v=wV1FrqwZyKw
SNOW PATROL - CALLED OUT IN THE DARK // http://www.youtube.com/watch?v=GwTXwJg6_VE
WANTED - WARZONE // http://www.youtube.com/watch?v=yMR382aefmQ
JLS FT DEV - SHE MAKES ME WANNA // http://www.youtube.com/watch?v=FuwTgZOKcf8
NICOLE SCHERZINGER - TRY WITH ME // http://www.youtube.com/watch?v=R7sYiTyBjTY
COBRA STARSHIP FT SABI - YOU MAKE ME FEEL // http://www.youtube.com/watch?v=HpyZEzrDf4c
JESSIE J - WHO'S LAUGHING NOW // http://www.youtube.com/watch?v=KsxSxF3JKeU
NOEL GALLAGHER'S HIGH FLYING - AKA WHAT A LIFE // http://www.youtube.com/watch?v=lwHpLDgWonM
FOSTER THE PEOPLE - PUMPED UP KICKS // http://www.youtube.com/watch?v=SDTZ7iX4vTQ
WRETCH 32 FT JOSH KUMRA - DON'T GO // http://www.youtube.com/watch?v=bj1BMpUnzT8
BIRDY - SKINNY LOVE // http://www.youtube.com/watch?v=aNzCDt2eidg
WANTED - GLAD YOU CAME // http://www.youtube.com/watch?v=2ggzxInyzVE
BIRDY - PEOPLE HELP THE PEOPLE // http://www.youtube.com/watch?v=OmLNs6zQIHo
NICKI MINAJ FT RIHANNA - FLY // http://www.youtube.com/watch?v=3n71KUiWn1I
SKREAM FT SAM FRANK - ANTICIPATE // http://www.youtube.com/watch?v=O3Z1X4MPsqk
WILL YOUNG - JEALOUSY // http://www.youtube.com/watch?v=9MHtrM-jf9o
ADELE - ROLLING IN THE DEEP // http://www.youtube.com/watch?v=rYEDA3JcQqw
JESSIE J FT BOB - PRICE TAG // http://www.youtube.com/watch?v=qMxX-QOV9tI
LMFAO/LAUREN BENNETT/GOONROCK - PARTY ROCK ANTHEM // http://www.youtube.com/watch?v=KQ6zr6kCPj8
JASON DERULO - IT GIRL // http://www.youtube.com/watch?v=4oGUHRXT-wA
BEYONCE - COUNTDOWN // http://www.youtube.com/watch?v=ACkBTqwxcUI
RIZZLE KICKS - DOWN WITH THE TRUMPETS // http://www.youtube.com/watch?v=-aY92XgykhU
COLDPLAY - EVERY TEARDROP IS A WATERFALL // http://www.youtube.com/watch?v=fyMhvkC3A84
CALVIN HARRIS - FEEL SO CLOSE // http://www.youtube.com/watch?v=dGghkjpNCQ8
ADELE - MAKE YOU FEEL MY LOVE // http://www.youtube.com/watch?v=LLoyNxjhTzc
ONE DIRECTION - ANOTHER WORLD // http://www.youtube.com/watch?v=RyZfNBVX1q0
COLDPLAY - VIVA LA VIDA // http://www.youtube.com/watch?v=dvgZkm1xWPE
BEYONCE - LOVE ON TOP // http://www.youtube.com/watch?v=Ob7vObnFUJc
EAGLE-EYE CHERRY - SAVE TONIGHT // http://www.youtube.com/watch?v=dTa2Bzlbjv0
EN VOGUE - DONT LET GO (LOVE) // http://www.youtube.com/watch?v=QUdAT5Fwnvk
KATY PERRY - FIREWORK // http://www.youtube.com/watch?v=QGJuMBdaqIw
MODESTEP - TO THE STARS // http://www.youtube.com/watch?v=UTKSUlMbp9A
DRAKE - HEADLINES // http://www.youtube.com/watch?v=cimoNqiulUE
ED SHEERAN - YOU NEED ME I DON'T NEED YOU // http://www.youtube.com/watch?v=temYymFGSEc
WOODKID - IRON // http://www.youtube.com/watch?v=vSkb0kDacjs
DELILAH - GO // http://www.youtube.com/watch?v=cxNe9jWNuEU
KATY PERRY FT KANYE WEST - ET // http://www.youtube.com/watch?v=t5Sd5c4o9UM
JAMES VINCENT MCMORROW - HIGHER LOVE // http://www.youtube.com/watch?v=9Z-fE1l9SZ4
BRUNO MARS - JUST THE WAY YOU ARE (AMAZING) // http://www.youtube.com/watch?v=LjhCEhWiKXk
PITBULL/NE-YO/AFROJACK/NAYER - GIVE ME EVERYTHING // http://www.youtube.com/watch?v=EPo5wWmKEaI</pre>
<pre></pre>
<pre>Then I wanted to test threading so I came up with something to check a list of links and obtain the "Server:" header</pre>
<pre>#!/usr/bin/env python
import urllib2
import re
import os
import sys
import time
from multiprocessing import Pool

#Accept file name as input or use default
try:
  filename = sys.argv[1]
except IndexError:
  filename = "links"

#Function to load urls from file
def loadurls(filename):
  try:
    inputdata = file(filename).readlines()
    if len(inputdata) &gt; 0:
      return inputdata
  except:
    print "ERROR - Unable to process url list"
    sys.exit()

#Function to get SERVER header
def getversion(url):
  try:
      request=urllib2.Request(url)
      response=urllib2.urlopen(request)
      version=response.info().getheader('Server')
  except:
      return "ERROR - Unable to fetch %s" % (url)

  if version: print "Url: %s Version: %s" % (url, version)

start = time.time()
urls=loadurls(filename)
p = Pool(15)
data = p.map(getversion,urls)

elapsed = (time.time() - start)
print "Processed %s urls in %0.2f seconds" % (len(urls), elapsed)</pre>
<pre>Sample output</pre>
<pre>scott@scott:~/python$ ./server-header.py list
Url: http://www.bbc.co.uk
 Version: Apache
Url: http://www.google.co.uk
 Version: gws
Url: http://scottmcintyre.net
 Version: Apache
Processed 4 urls in 1.07 seconds</pre>
<pre></pre>
<pre>None of these really serve any purpose and were merely tests I thought I would share.   Overall things have been quite easy and feel reasonably confident after just 2 days.</pre>
]]></content:encoded>
			<wfw:commentRss>http://scott.cm/learning_python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Setup mySQL replicated slave using r1soft</title>
		<link>http://scott.cm/setup-mysql-replicated-slave-using-r1soft/</link>
		<comments>http://scott.cm/setup-mysql-replicated-slave-using-r1soft/#comments</comments>
		<pubDate>Thu, 27 Jan 2011 03:22:08 +0000</pubDate>
		<dc:creator>Scott Mcintyre</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[mySQL]]></category>
		<category><![CDATA[R1soft]]></category>
		<category><![CDATA[System Administration]]></category>

		<guid isPermaLink="false">http://scottmcintyre.net/?p=63</guid>
		<description><![CDATA[Using r1soft mySQL addon to setup mySQL replication slaves requiring read locks in seconds rather than hours for non transactional tables.]]></description>
			<content:encoded><![CDATA[<p>I have been using r1soft <a href="http://www.r1soft.com/linux-cdp/">Continuous Data Protection</a> for many years now with the <a href="http://www.r1soft.com/linux-cdp/cdp-30-enterprise-edition/mysql/">mySQL Addon</a> and wanted to share a trick I have used several times.</p>
<p>For those of us that don&#8217;t have the luxury of using all transactional based tables such as InnoDB and the the ability to use the likes of <a href="http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_single-transaction">&#8211;single-transaction</a> with <a href="http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_master-data">&#8211;master-data</a> we do have an option of using r1soft to avoid lengthy downtimes in the event we have to setup/resetup a slave. You can turn a potential several hour outage in a 30-60 second <em>READ LOCK</em> and perform the rest in the background.</p>
<p>Firstly a quick explanation of the r1soft mySQL addon, the mySQL addon works by issuing a global lock and then flushes changes from memory to disk to ensure consistent snapshots. As it works with the r1soft device driver the process usually takes less than a second making this the perfect method to take backups and have the master position at the time the backup was taken. At the time of writing r1soft does not support the ability to store the master/slave status data although hopefully in the future it will store and display it to avoid having to use the following trick.</p>
<p>We can however work around this by monitoring the r1soft server-log.txt to determine when it has flushed and unlocked the mySQL instance. As it happens very early on in the process we can manually issue a global read lock, get the current position, monitor the server-log.txt until r1soft has performed the snapshot of mySQL and then release the global lock manually.</p>
<p>I have performed an example of this for this article. I started by logging into the CDP interface, browsing to the system in question and getting to the start backup process, having this all filled in and ready to submit speeds the process up. Once this was ready I logged into the database system and issued a global read lock then obtained the current master position,</p>
<p><code>mysql&gt; <strong>flush tables with read lock;</strong><br />
Query OK, 0 rows affected (0.10 sec)</code></p>
<p>mysql&gt; <strong>show master status;</strong><br />
+&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+<br />
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |<br />
+&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+<br />
| mysql-bin.024272 | 120146094 | | |<br />
+&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+<br />
1 row in set (0.00 sec)</p>
<p>I then clicked ok under the schedule backup window and started a tail on server-log.txt (usually found in /usr/r1soft/buserver/log) and waited until it reached the mySQL lock, flush and unlock.</p>
<p><code><br />
2011-01-27 02:44:27,743 INFO: (tid:976019) Starting task 'Backup' for host (xx.xx.xx.xx) with host id (xxxxxxxx)<br />
2011-01-27 02:44:27,771 INFO: (tid:976019) Starting Backup Task.<br />
2011-01-27 02:44:27,772 INFO: (tid:976019) Backing up partition tables.<br />
2011-01-27 02:44:27,773 INFO: (tid:976020) Starting task 'Partition Table Backup' for host (xx.xx.xx.xx) with host id (xxxxxxxx)<br />
2011-01-27 02:44:27,790 INFO: (tid:976020) Starting partition table backup for host (xx.xx.xx.xx) device (/dev/sda) Disk Safe (0) recovery point (6025).<br />
2011-01-27 02:44:27,892 INFO: (tid:976020) AGENT: (Righteous Backup Linux Agent) 1.62.0 build 6386<br />
2011-01-27 02:44:28,019 WARN: (tid:976020) AGENT: allowing control from backup server (xx.xx.xx.xx) with valid RSA key<br />
2011-01-27 02:44:28,059 WARN: (tid:976020) AGENT: sending auth challenge for allowed host at (xx.xx.xx.xx) port (41758)<br />
2011-01-27 02:44:28,108 INFO: (tid:976020) AGENT: host (xx.xx.xx.xx) port (41758) authentication successful<br />
2011-01-27 02:44:28,193 INFO: Agent (xx.xx.xx.xx) authenticated successfully<br />
2011-01-27 02:44:28,267 INFO: (tid:976020) AGENT: Partition Backup request accepted. Starting backup.<br />
2011-01-27 02:44:28,269 INFO: (tid:976020) AGENT: Found 4 partition(s), 1 extended partition(s) and 124 extra sector(s)<br />
2011-01-27 02:44:28,270 INFO: (tid:976020) AGENT: Need to back up 126 sectors<br />
2011-01-27 02:44:28,270 INFO: (tid:976020) Sector size (512) bytes.<br />
2011-01-27 02:44:28,271 INFO: (tid:976020) Number of sectors (126).<br />
--SNIP--<br />
2011-01-27 02:44:32,083 INFO: Sending (1) MySQL instances to agent.<br />
2011-01-27 02:44:32,083 INFO: Sending next MySQL instance to agent.<br />
2011-01-27 02:44:32,117 INFO: (tid:976019) AGENT: Backup request accepted. Starting backup.<br />
2011-01-27 02:44:39,340 INFO: (tid:976019) AGENT: Flushed 1 MySQL instances.<br />
2011-01-27 02:44:39,353 INFO: (tid:976019) AGENT: Flushed 1 MySQL instances.<br />
2011-01-27 02:44:39,354 INFO: (tid:976019) AGENT: Flushed 1 MySQL instances.<br />
2011-01-27 02:44:39,355 INFO: (tid:976019) AGENT: Locked 1 MySQL instances.<br />
2011-01-27 02:44:39,355 INFO: (tid:976019) AGENT: Unlocked 1 MySQL instances.<br />
2011-01-27 02:44:39,356 INFO: (tid:976019) AGENT: Snapshot completed in 0.059 seconds.<br />
<strong>2011-01-27 02:44:39,357 INFO: (tid:976019) AGENT: Acquired MySQL lock in 0.025 seconds and held lock for 0.085 seconds on 1 instance.</strong><br />
2011-01-27 02:44:39,357 INFO: (tid:976019) Backup pipeline size (256) blocks.<br />
2011-01-27 02:44:39,358 INFO: (tid:976019) Block size (4096).<br />
2011-01-27 02:44:39,358 INFO: (tid:976019) Partition size (34529701) blocks.<br />
2011-01-27 02:44:39,359 INFO: (tid:976019) Mount Point (/).<br />
2011-01-27 02:44:39,803 INFO: (tid:976019) Network Queue Size: 1280 blocks</code></p>
<p>Once it has completed the stage in bold I simply released the read lock,</p>
<p><code>mysql&gt; <strong>unlock tables;</strong><br />
Query OK, 0 rows affected (0.00 sec)</code></p>
<p>I now had a backup in r1soft and had the master position of the time it was taken. Once the backup completed I simply restored the tables I needed to the slave using the restore to an alternate host and started replication using this data.</p>
<p><code><br />
INFO 01/27/2011 <strong>02:44:27 GMT</strong> (tid:976019) Starting task 'Backup' for host (xx.xx.xx.xx) with host id (xxxxxxxx)<br />
INFO 01/27/2011<strong> 02:51:10 GMT</strong> (tid:976019) Backup Task finished.</code></p>
<p>I restored the backup to the mysql datadir, as you are backing up the master you can skip all the binlogs. After this was restored I started mySQL, changed the master to the details we got from the master status earlier and started the slave.</p>
<p><code><br />
mysql&gt; CHANGE MASTER to MASTER_HOST='192.168.1.3', MASTER_USER='slave', MASTER_PASSWORD='xxxxxx', MASTER_LOG_FILE='mysql-bin.024272', MASTER_LOG_POS=120146094;<br />
Query OK, 0 rows affected (0.01 sec)</code></p>
<p>mysql&gt; start slave;<br />
Query OK, 0 rows affected (0.00 sec)</p>
<p>mysql&gt; show slave status \G;<br />
<strong>Seconds_Behind_Master: 0</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://scott.cm/setup-mysql-replicated-slave-using-r1soft/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

