<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Simon Mott</title><link>https://www.simonmott.co.uk/</link><description>Recent content on Simon Mott</description><generator>Hugo</generator><language>en-gb</language><lastBuildDate>Tue, 15 Sep 2026 17:35:12 +0000</lastBuildDate><atom:link href="https://www.simonmott.co.uk/index.xml" rel="self" type="application/rss+xml"/><item><title>Moving from Wordpress to Hugo</title><link>https://www.simonmott.co.uk/2026/09/moving-from-wordpress-to-hugo/</link><pubDate>Tue, 15 Sep 2026 17:35:12 +0000</pubDate><guid>https://www.simonmott.co.uk/2026/09/moving-from-wordpress-to-hugo/</guid><description>&lt;p&gt;Everyone&amp;rsquo;s probably sick of hearing about LLMs now, but I&amp;rsquo;ve been working with them a bit more recently and I decided it was probably time I used one to update my website.&lt;/p&gt;&#10;&lt;p&gt;Way back when, my website was originally some PHP I&amp;rsquo;d cobbled together. At the time it was&amp;hellip; fine, I suppose. It had a basic admin section which allowed me to write posts, create custom pages etc. Referencing my &lt;a href="https://www.simonmott.co.uk/2026/08/owntracks-and-my-google-timeline/"&gt;recent OwnTracks post&lt;/a&gt;, this was the version of my site that had my current location for all to see - which, in hindsight, probably isn&amp;rsquo;t the smartest thing to publish on a public website&amp;hellip; I was, and still am, terrible at creating good looking designs for things, so it was pretty basic, but it served my needs.&lt;/p&gt;&#10;&lt;p&gt;I had this version of my website from when I originally created it in 2009, through to sometime in late 2016.&lt;/p&gt;&#10;&lt;h2 id="wordpress"&gt;Wordpress&lt;/h2&gt;&#10;&lt;p&gt;After working in the Managed Services and Hosting industry for a couple of years, I&amp;rsquo;d decided I wanted to update my website with a shiny new look. Wordpress was the flavour of the month back then, so I figured I&amp;rsquo;d have a play with it and set that up. I managed to find a theme I mostly liked (I forget where I found it), but I had to apply some basic modifications to it in order to make it fit better on the page. Believe it or not, it was too narrow. I didn&amp;rsquo;t realize this at the time, but that decision would come back to bite me.&lt;/p&gt;&#10;&lt;p&gt;I used to see Wordpress websites getting compromised all the time at work, so I made the decision pretty early on to try and &amp;ldquo;harden&amp;rdquo; my install a little bit. This was done by keeping my installed plugins pretty light and anything under the &lt;code&gt;wp-admin&lt;/code&gt; folder, including the main Wordpress login form, was restricted using Apache&amp;rsquo;s &lt;code&gt;mod_auth_basic&lt;/code&gt; module, meaning anyone attempting to access it would be presented with a login prompt, which, importantly, was not handled by PHP. My thought process was that most sites seemed to get compromised through the admin plane, and if something tried automated methods, the auth requirement would foil it. Given this was handled entirely by Apache (and was a different set of credentials to the actual Wordpress authentication), it was less likely for anything to exploit any CVEs there, as they simply couldn&amp;rsquo;t access it. It was a little annoying with two login prompts whenever I wanted to access it myself, but as this was in Apache, I could whitelist my own IP addresses that were likely to access the admin portal. This seems to have worked pretty well for me overall - to my surprise, my website (as far as I know) never got compromised.&lt;/p&gt;&#10;&lt;p&gt;I am well-known amongst my friend groups to be pretty lax at applying timely updates. As I mentioned earlier, I&amp;rsquo;d modified the theme I used, so from that point onwards, I &lt;strong&gt;never&lt;/strong&gt; updated the theme after the initial setup, as doing so would have undone my customizations. I didn&amp;rsquo;t really understand how theming worked in Wordpress, so I didn&amp;rsquo;t do my customizations in a way that meant I could easily update the theme. That pain point, plus being lazy with updates, meant I only really did it sporadically, which isn&amp;rsquo;t an ideal situation to be in.&lt;/p&gt;&#10;&lt;p&gt;In a similar manner, the VM the website ran on slowly aged, to the point where I found the thought of updating it annoying, and I simply couldn&amp;rsquo;t be bothered to migrate everything elsewhere wholesale.&lt;/p&gt;&#10;&lt;p&gt;Wordpress itself, or at least the combination of plugins and my theme, wasn&amp;rsquo;t exactly the most performant. If a crawler decided to request a lot of pages in quick succession, PHP would just churn CPU trying to generate the pages, consuming memory, and quite a few times it fell over due to running out of RAM and consuming all the swap. At this point I decided to play with putting some caching in front of the site. Sure I could have used nginx and been done with it, but I wanted to play around with Apache caching, which is the entire reason &lt;a href="https://www.simonmott.co.uk/2016/06/caching-apaches-mod_cache-mod_deflate/"&gt;this blog post&lt;/a&gt; exists.&lt;/p&gt;&#10;&lt;p&gt;Overall, Wordpress has served me well for 10 years, give or take a month or two. Looking at archive.org, &lt;a href="https://web.archive.org/web/20160522233406/http://simonmott.co.uk/"&gt;June 24th 2016&lt;/a&gt; is the last entry for the old design, and &lt;a href="https://web.archive.org/web/20160831185105/https://www.simonmott.co.uk/"&gt;August 31st 2016&lt;/a&gt; is the first entry with Wordpress.&lt;/p&gt;&#10;&lt;h2 id="hugo-to-the-rescue"&gt;Hugo to the rescue&lt;/h2&gt;&#10;&lt;p&gt;In general, I am a fan of dark mode for all the things. One thing that&amp;rsquo;s bugged me about my Wordpress site theme of late is how bright it is, with no easy way to change it. This, in combination with the self-imposed mountain-out-of-a-mole-hills of keeping Wordpress and the server updated, meant it was probably time to switch things up.&lt;/p&gt;&#10;&lt;p&gt;I&amp;rsquo;d been aware of Hugo for a while, but I never seriously looked at moving to it, as pulling all the bits I wanted out from Wordpress, reformatting the posts and generally reconfiguring things always seemed like a chore. Thankfully in this day and age we have LLMs that can do a lot of the heavy lifting for us.&lt;/p&gt;&#10;&lt;p&gt;I was chatting to &lt;a href="https://greboid.com/"&gt;Greboid&lt;/a&gt; on IRC recently, discussing websites in general, and he decided to start working on a Hugo conversion from Wordpress for me (I assume for fun?) and he came up with a design that is pretty much what this version of my website is based on - excluding a few tweaks I made after the fact.&lt;/p&gt;&#10;&lt;p&gt;I had a script that would crawl my website (originally to test the caching), which, as a nice side effect, produced a list of all the URLs reachable on my site. Armed with that, an export from Wordpress itself, and some vague hand-wavy comments and suggestions, an LLM agent dutifully created a Hugo file tree, converted all my posts, brought over Greg&amp;rsquo;s styling, handled old URL preservation and produced suitable Dockerfile and docker-compose files to build an image for my website.&lt;/p&gt;&#10;&lt;p&gt;A quick VM-with-docker template deployment later resulted in a shiny new server that houses my website (and a few other things) with pretty much minimal effort on my part.&lt;/p&gt;&#10;&lt;p&gt;A downside of using Hugo is that there are a lot more individual files I myself have to keep on top of instead of just letting Wordpress plugins/themes handle everything, but the main benefit to using Hugo over Wordpress is that it&amp;rsquo;s much simpler to chop and change things as I see fit. Of course, the main advantage here is that the website is a static site, so doesn&amp;rsquo;t rely on PHP or anything like that, and is blisteringly fast compared to the old site.&lt;/p&gt;&#10;&lt;p&gt;For nostalgia&amp;rsquo;s sake - here are some screenshots showing the 3 main styles from the original to now. I have come to realise my website design caters to my vanity as they all have a giant picture of me. The Hugo one is included here for if/when I change the design again in the future.&lt;/p&gt;&#10;&lt;figure&gt;&#10;&lt;a href="https://www.simonmott.co.uk/images/2026/09/2016_old.jpg"&gt;&lt;img alt="PHP Website" class="img-center" src="https://www.simonmott.co.uk/images/2026/09/2016_old.jpg" width="640" height="360"/&gt;&lt;/a&gt;&#10;&lt;figcaption&gt;PHP - 2009 to 2016&lt;/figcaption&gt;&#10;&lt;/figure&gt;&#10;&lt;figure&gt;&#10;&lt;a href="https://www.simonmott.co.uk/images/2026/09/wordpress.jpg"&gt;&lt;img alt="Wordpress Website" class="img-center" src="https://www.simonmott.co.uk/images/2026/09/wordpress.jpg" width="640" height="360"/&gt;&lt;/a&gt;&#10;&lt;figcaption&gt;Wordpress - 2016 to 2026&lt;/figcaption&gt;&#10;&lt;/figure&gt;&#10;&lt;figure&gt;&#10;&lt;a href="https://www.simonmott.co.uk/images/2026/09/hugo.jpg"&gt;&lt;img alt="Hugo Website" class="img-center" src="https://www.simonmott.co.uk/images/2026/09/hugo.jpg" width="640" height="360"/&gt;&lt;/a&gt;&#10;&lt;figcaption&gt;Hugo - 2026 to ??&lt;/figcaption&gt;&#10;&lt;/figure&gt;</description></item><item><title>OwnTracks and my Google Timeline</title><link>https://www.simonmott.co.uk/2026/08/owntracks-and-my-google-timeline/</link><pubDate>Sat, 22 Aug 2026 15:47:57 +0000</pubDate><guid>https://www.simonmott.co.uk/2026/08/owntracks-and-my-google-timeline/</guid><description>&lt;p&gt;A while back, &lt;a href="https://chameth.com/"&gt;a friend&lt;/a&gt; showed me an application they had started using called &lt;a href="https://github.com/owntracks"&gt;OwnTracks&lt;/a&gt;, which periodically sends location updates from your phone to your own server. I used to collect similar location data back in the day via Google Latitude, so the idea of self-hosting my own tracking history intrigued me. Fast forward a few months, and I finally got around to setting it up.&lt;/p&gt;&#10;&lt;p&gt;Shortly after, &lt;a href="https://blog.dataforce.org.uk/"&gt;another friend&lt;/a&gt; decided to set it up as well and mentioned wanting to import their historical &lt;a href="https://www.technowizardry.net/2024/01/migrating-from-google-location-history-to-owntracks/"&gt;Google Timeline exports into it&lt;/a&gt;. I hadn&amp;rsquo;t even considered that, but I loved the idea of giving it a shot since I had years of location data sitting around. A day or two later, I had my data fully ingested and viewable in OwnTracks, dating all the way back to mid-2010.&lt;/p&gt;&#10;&lt;p&gt;The first hurdle I ran into was that iOS Google Maps exports use a different format than the Android versions, requiring me to patch the import script to handle the iOS payload. Using an LLM coding assistant, I threw some sample data at it, and it quickly generated everything OwnTracks needed to ingest the files.&lt;/p&gt;&#10;&lt;p&gt;However, I quickly discovered that Google Maps on iOS logs far less granular data than it does on Android. Thankfully, I still had my old Android phone from when Google originally moved Timeline data on-device. That phone contained my complete, detailed history from my Android years up until my switch to iPhone, so I dutifully ingested that data too.&lt;/p&gt;&#10;&lt;p&gt;The next issue I ran into is that the built in map from the OwnTracks recorder, and even using the OwnTracks frontend was horribly laggy, even with just a years worth of data and I really wanted to see all my data on a map, all at once. Armed with my LLM, I thought It&amp;rsquo;d be pretty trivial to prompt something into existence that queries the OwnTracks recorder API and plot it all onto a map. I&amp;rsquo;d originally planned to create something I could use to entirely replace OwnTrack&amp;rsquo;s own frontend, so that&amp;rsquo;s where I started. It pretty quickly spiralled though, and it got way more complicated than I&amp;rsquo;d initially expected.&lt;/p&gt;&#10;&lt;p&gt;Most of this was striving to create something that could be suitable for people other than myself. After about a week or so of on-and-off prompting, &lt;a href="https://github.com/tsumaru720/owntracks-frontend"&gt;I&amp;rsquo;d ended up with something&lt;/a&gt; that loads all my data, allows reasonably robust configuration of its appearance and probably too many tuning options. I am however pretty happy with the result even if its code is probably hot garbage.&lt;/p&gt;&#10;&lt;p&gt;It allows me to view all of my data, panning and scrolling (mostly) without lag, and lets me ultimately view everything all at once. What I find more interesting though, and mainly what I wanted to visualize are the heat maps - I&amp;rsquo;m not going to post my current or previous address in detail, but you can clearly see my home, my sister&amp;rsquo;s, the local shop I visited a lot, my mum&amp;rsquo;s and amusingly, the petrol station I used to frequent. This image shows at a high level, where I live, where I used to live, my old commute, and a giant hot spot near Birmingham for the many years I attended Insomnia Gaming Festival (rip) at the NEC.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2026/08/heatmap_overview.jpg"&gt;&lt;img alt="" class="img-center" height="531" src="https://www.simonmott.co.uk/images/2026/08/heatmap_overview.jpg" width="495"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;Exploring the data further, clearly shows the kind of hot spots I wanted to see. When I visited Glasgow for work, there&amp;rsquo;s a hotspot for Glasgow Central, my old office and the hotel they put me up in when I visited, along with the venue of our annual Christmas party. I also took a look at my 2015 trip to Japan, and the Airbnb I stayed at is clearly visible, along with the two major transit hubs I used to get around.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2026/08/hotspots.jpg"&gt;&lt;img alt="" class="img-center" height="597" src="https://www.simonmott.co.uk/images/2026/08/hotspots.jpg" width="1474"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;Similarly for my trip to TwitchCon in Las Vegas back in 2023, but instead of a heat map, you can see route lines centered around my Airbnb, the strip, the airport and &lt;a href="https://en.wikipedia.org/wiki/Fremont_Street"&gt;Fremont Street&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2026/08/vegas.jpg"&gt;&lt;img alt="" class="img-center" height="505" src="https://www.simonmott.co.uk/images/2026/08/vegas.jpg" width="559"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;And finally - I attended an &lt;a href="https://www.epiclan.co.uk/"&gt;EPIC LUX LAN&lt;/a&gt; event recently too, and using OwnTrack&amp;rsquo;s data instead of Google Timeline, I was amused at the granularity. You can see the 4 main areas I spent my time in whilst at the event - The main event hall, my hotel room, the dining area, and in the lobby playing board games with friends!&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2026/08/lux.jpg"&gt;&lt;img alt="" class="img-center" height="600" src="https://www.simonmott.co.uk/images/2026/08/lux.jpg" width="538"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;One interesting observation after importing the Google data were strange little artifacts that are displayed on the map. Upon further investigation (mainly by Chris - &lt;a href="https://chameth.com/"&gt;chameth.com&lt;/a&gt;), the grid pattern visible turned out to be Google&amp;rsquo;s own spatial index showing through. Google indexes geography with a system called S2, which divides the Earth into a hierarchy of square-ish cells, each with a fixed, deterministic center point. Level 18 of that hierarchy produces cells about 30 metres across. When Google Timeline &amp;ldquo;fills in&amp;rdquo; your location history during stationary periods, it appears to snap those synthesized points to the centers of these cells - so the points don&amp;rsquo;t scatter like real GPS fixes, they land on a fixed ~30 m lattice that gets reused every time you&amp;rsquo;re in the same place. Plot them on a map and you see the index itself: repeating rows of dots, tilted slightly because the cell grid isn&amp;rsquo;t aligned with north.&lt;/p&gt;&#10;&lt;p&gt;A quick LLM task to parse my data and remove the matching S2 coordinates cleared it right up.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2026/08/google-s2.png"&gt;&lt;img alt="" class="img-center" height="329" src="https://www.simonmott.co.uk/images/2026/08/google-s2.png" width="1485"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;I look forward to see what data OwnTracks accumulates over the (hopefully many) years to come!&lt;/p&gt;</description></item><item><title>Using ffmpeg's vpp_qsv detail enhancement filter</title><link>https://www.simonmott.co.uk/2024/12/using-ffmpegs-vpp_qsv-detail-enhancement-filter/</link><pubDate>Sun, 22 Dec 2024 05:04:27 +0000</pubDate><guid>https://www.simonmott.co.uk/2024/12/using-ffmpegs-vpp_qsv-detail-enhancement-filter/</guid><description>&lt;p&gt;As part of my last post, I was exploring video transcoding with an Intel Arc GPU and how different levels of ICQ affect video size and quality. During which, I noticed there&amp;rsquo;s a QSV compatible filter in ffmpeg called &lt;strong&gt;vpp_qsv&lt;/strong&gt; which has a detail parameter. VPP stands for Video Post Processing and the filter help text simply says &amp;ldquo;enhancement level&amp;rdquo; for detail. The potential to do some automatic picture enhancements directly on the GPU piqued my interest so I decided to have a play with it.&lt;/p&gt;&#10;&lt;p&gt;Firstly, I grabbed a sample 4k video of a chameleon from pexels because its reasonably close framing of its body and has a fair amount of detail on its scales. Next, I used the same ffmpeg command from my &lt;a href="https://www.simonmott.co.uk/2024/12/transcoding-with-an-intel-arc-gpu/"&gt;previous post&lt;/a&gt;, but with a &lt;code&gt;global_quality&lt;/code&gt; (ICQ) value of 30. The idea here is to deliberately degrade the footage so I can see what the detail parameter actually does in terms of trying to enhance the quality. I then generated a series of new videos with a detail level ranging from 0 to 100 in increments of 10 and then calculated &lt;a href="https://en.wikipedia.org/wiki/Video_Multimethod_Assessment_Fusion"&gt;VMAF scores&lt;/a&gt; for all of them. VMAF is an objective full-reference video quality metric that predicts subjective video quality based on a reference and &amp;ldquo;distorted&amp;rdquo; video sequence. The metric can be used to evaluate the quality of different video codecs, encoders, encoding settings etc.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2024/12/vmaf-detail-30.png"&gt;&lt;img alt="" class="img-center" height="248" src="https://www.simonmott.co.uk/images/2024/12/vmaf-detail-30.png" width="798"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;This shows that the &lt;code&gt;detail&lt;/code&gt; parameter is doing &lt;em&gt;&lt;strong&gt;something&lt;/strong&gt;&lt;/em&gt; but we start to get diminishing returns from a value of about 70 onwards, for much larger increases in file size. I was curious what this had actually done to the resulting video though. Below is a zoomed crop on the eye of the chameleon - Its pretty hard to spot, but the image from ICQ 30 detail 0 is slightly softer compared to the original (which is expected) and the image from ICQ 30 detail 70 is visibly sharper. Whether this means a better experience is up to you, keeping in mind that this is a single frame from a video.&lt;/p&gt;&#10;&lt;figure class="img-center"&gt;&lt;a href="https://www.simonmott.co.uk/images/2024/12/vmaf-original-crop.png"&gt;&lt;img alt="" height="357" src="https://www.simonmott.co.uk/images/2024/12/vmaf-original-crop.png" width="500"/&gt;&lt;/a&gt;&lt;figcaption&gt;Original&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;figure class="img-center"&gt;&lt;a href="https://www.simonmott.co.uk/images/2024/12/vmaf-q30d0-crop.png"&gt;&lt;img alt="" height="357" src="https://www.simonmott.co.uk/images/2024/12/vmaf-q30d0-crop.png" width="500"/&gt;&lt;/a&gt;&lt;figcaption&gt;Q30 Detail 0&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;figure class="img-center"&gt;&lt;a href="https://www.simonmott.co.uk/images/2024/12/vmaf-q30d70-crop.png"&gt;&lt;img alt="" height="357" src="https://www.simonmott.co.uk/images/2024/12/vmaf-q30d70-crop.png" width="500"/&gt;&lt;/a&gt;&lt;figcaption&gt;Q30 Detail 70&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;p&gt;Given I&amp;rsquo;m unlikely to use an ICQ of 30 myself, I was curious how the detail parameter affects the VMAF score for different ICQ levels. Based on my last article I decided that ICQ values of 15, 16 or 17 would be the likely values I&amp;rsquo;d use, so I figured lets see how these values look for this sample video.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2024/12/vmaf_comparison.png"&gt;&lt;img alt="" class="img-center" height="744" src="https://www.simonmott.co.uk/images/2024/12/vmaf_comparison.png" width="798"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;The source video itself is a small 4k video, coming in at only 28MB so I&amp;rsquo;ve included the figures for the original video in these new graphs as the file size becomes a lot more important.&lt;/p&gt;&#10;&lt;p&gt;We can see a similar trend as with the VMAF scores for ICQ 30, but with a larger fall off past a detail value of 70. Given these files should in theory be higher quality to start due to their lower ICQ value, we can see the impact of a higher detail value isn&amp;rsquo;t as large past 40 or 50. More importantly here, the generated file size seems to be larger than the original from about detail 70 onwards, which means we get no benefit at all other than perhaps a slightly sharper image and wasting extra disk space.&lt;/p&gt;&#10;&lt;p&gt;As interesting as these results are, this 28MB sample file is not representative of my use case, so lets re-run the numbers using the same 1080p input file for my previous post with an ICQ of 16, as this is most likely what I&amp;rsquo;ll be using going forward.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2024/12/VMAF-for-large-source.png"&gt;&lt;img alt="" class="img-center" height="248" src="https://www.simonmott.co.uk/images/2024/12/VMAF-for-large-source.png" width="798"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;This again shows a similar trend, but with less of an impact at the higher detail levels. The file size however, ends up close to or larger than the original beginning at detail 70 and above which isn&amp;rsquo;t what I&amp;rsquo;m personally looking for as I&amp;rsquo;m trying to find a good balance of quality and file size.&lt;/p&gt;&#10;&lt;p&gt;It&amp;rsquo;s still unclear to me what &lt;em&gt;&lt;strong&gt;exactly&lt;/strong&gt;&lt;/em&gt; this parameter does besides adding some sharpening. Based on these results however, if I want to use this in my transcodes it seems like a value somewhere between 30 and 40 should (According to the VMAF scores) enhance my video over a plain transcode, whilst still ultimately reducing the file size. Once again though, remember that quality is subjective and your milage may vary depending on your hardware, source video and settings.&lt;/p&gt;</description></item><item><title>Transcoding with an Intel Arc GPU</title><link>https://www.simonmott.co.uk/2024/12/transcoding-with-an-intel-arc-gpu/</link><pubDate>Fri, 20 Dec 2024 18:30:51 +0000</pubDate><guid>https://www.simonmott.co.uk/2024/12/transcoding-with-an-intel-arc-gpu/</guid><description>&lt;p&gt;I am a bit of an NVIDIA fanboy when it comes to GPUs. This is partly down to being a long time Linux Desktop user (until recently) and them having excellent drivers allowing me to pretty effortlessly get proper hardware acceleration working.&lt;/p&gt;&#10;&lt;p&gt;In my lab environment I have an old Nvidia Quadro P400 that&amp;rsquo;s set up for various transcoding workloads and its been working absolutely great for me despite being an older card. I have been primarily using the h264 codec but I recently moved over to h265 (hevc) mostly out of curiosity, and to see if I could get quality on-par with h264, whilst getting similar file sizes.&lt;/p&gt;&#10;&lt;p&gt;Seems simple? Take my existing ffmpeg command (using qmax of 23), and substituting the output codec from h264 to hevc whilst keeping everything else the same, This gets me a file encoded with hevc thats similar (ever so slightly larger) than what I&amp;rsquo;d have with h264 and comparable quality. I can pixel peep a few frames to see the differences but I could also calculate a &lt;a href="https://en.wikipedia.org/wiki/Video_Multimethod_Assessment_Fusion"&gt;VMAF score&lt;/a&gt; for these two outputs (between 0 and 100) to give a subjective quality score compared to the original source file. Doing so, the hevc encoded output scores slightly higher for an ever so slightly larger file. Anecdotal posts on the internet suggest a score between 94 and 96 is acceptable, but higher is better. Ultimately its up to you what you consider acceptable quality.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;This is all well and good, but where does Intel Arc come into this?&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;I managed to find an Intel Arc A310 for pretty cheap and figured I&amp;rsquo;d grab one to throw into my lab. On paper this is a much newer card so should have decent performance for encoding - and it also natively supports AV1 acceleration if I ever wanted to experiment with that in the future. My goal is to find a good balance of quality, file size, speed and compatability.&lt;/p&gt;&#10;&lt;p&gt;The codecs used for NVIDIA and Intel Quick Sync (QSV) don&amp;rsquo;t accept all the same inputs, so using the new GPU is not as simple as just replacing hevc_nvenc codec with hevc_qsv. This shouldn&amp;rsquo;t be much a problem though as they are different pieces of hardware so will naturally do things differently.&lt;/p&gt;&#10;&lt;p&gt;ICQ (Intelligent Constant Quality) parameters for the Arc GPU are controlled using &lt;code&gt;-global_quality&lt;/code&gt; instead of &lt;code&gt;-qmax&lt;/code&gt; and I picked a starting number of 15 as it gave me a file size slightly larger than NVENC&amp;rsquo;s h264 whilst 16 gives a smaller file using my test input.&lt;/p&gt;&#10;&lt;p&gt;In order to validate our subjective quality, the VMAF score should decrease as the ICQ number increases so I tested all the way from 15 through 19. With ICQ, lower numbers are better quality and larger files, whilst larger numbers are worse quality, but smaller files. Since using qmax 23 for NVENC was larger than h264, I also included qmax 24 in my results.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2024/12/vmaf.png"&gt;&lt;img alt="" class="img-center" height="305" src="https://www.simonmott.co.uk/images/2024/12/vmaf.png" width="984"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;Looking at these, using an ICQ value of 15, 16 or 17 gives us supposedly a superior quality file, but only 16 and 17 result in a smaller file than we get with NVENC qmax 23. All of these resulting tests are still &lt;em&gt;&lt;strong&gt;significantly&lt;/strong&gt;&lt;/em&gt; smaller than the original untranscoded file, and only two are larger than the h264 transcoded file using the P400, so in order to get the best balance of quality and size it seems like a value of 16 is optimal, at least for my hardware and use case.&lt;/p&gt;&#10;&lt;p&gt;Quality is subjective and all results will depend on the source and what you find personally acceptable, but the encoding improvements from using newer hardware really shows here - I can get a better quality hevc file, with a smaller footprint and do it faster (The A310 is almost twice as fast as the P400) so using this in my lab moving forward seems like a no-brainer.&lt;/p&gt;&#10;&lt;p&gt;Results will of course vary depending on what input you use. I only tested this with a single file for writing this post, but I have seen similar results for a variety of other inputs.&lt;/p&gt;&#10;&lt;p&gt;For completeness, these are the ffmpeg commands I used (ffmpeg version 7.1). I am by no means an expert with ffmpeg, so there are probably plenty of ways to further tune this but for now I&amp;rsquo;m happy with my results.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; NVENC&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; Adjust qmax to control ICQ and file size&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; ffmpeg -v quiet -loglevel error -stats -y \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -hwaccel cuda \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -hwaccel_output_format cuda \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -i &amp;#34;input.mkv&amp;#34; \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -fps_mode passthrough \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -c:s copy \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -c:a copy \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -c:v hevc_nvenc \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -map 0 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -dn \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -preset medium \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -profile:v main \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -spatial_aq:v 1 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -rc-lookahead 32 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -rc vbr \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -qmin:v 16 -qmax:v 23 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -vtag hvc1 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -max_muxing_queue_size 4096 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -f matroska \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; &amp;#34;output.mkv&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; Intel QuickSync&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; Adjust global_quality to control ICQ and file size&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; ffmpeg -v quiet -loglevel error -stats -y \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -hwaccel qsv \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -hwaccel_output_format qsv \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -i &amp;#34;input.mkv&amp;#34; \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -fps_mode passthrough \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -c:s copy \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -c:a copy \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -c:v hevc_qsv \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -map 0 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -dn \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -preset medium \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -profile:v main \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -look_ahead 1 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -look_ahead_depth 99 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -global_quality 16 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -extbrc 1 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -vtag hvc1 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -max_muxing_queue_size 4096 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -f matroska \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; &amp;#34;output.mkv&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; Calculating VMAF &lt;span class="o"&gt;(&lt;/span&gt;requires Netflix VMAF library&lt;span class="o"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; Uses CPU, Adjust n_threads &lt;span class="k"&gt;for&lt;/span&gt; your CPU&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; ffmpeg -y \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -i &amp;#34;generated_ouput.mkv&amp;#34; \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -i &amp;#34;input.mkv&amp;#34; \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; -lavfi libvmaf=n_subsample=5:n_threads=16 -f null -&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Auto mount LUKS without a filesystem</title><link>https://www.simonmott.co.uk/2023/06/auto-mount-luks-without-a-filesystem/</link><pubDate>Sat, 24 Jun 2023 14:52:58 +0000</pubDate><guid>https://www.simonmott.co.uk/2023/06/auto-mount-luks-without-a-filesystem/</guid><description>&lt;p&gt;One of my friends recently installed a new storage server in our shared lab environment and graciously gave me some storage space on it via iSCSI. I use Proxmox for my personal lab, and I intended to store some non-critical VM disks on this new storage so I could play around with properly using HA (High Availability) with Proxmox. Additionally, I wanted to gain some experience using iSCSI at the same time. While I trust my friend, the storage itself is outside of my control, so I figured it would be good practice to encrypt my data. The general go-to solution for this would seem to be LUKS.&lt;/p&gt;&#10;&lt;p&gt;Going into detail on how to set up iSCSI and multipath is out of scope here, but the general idea is that you connect to the storage array via iSCSI, and it then gets exposed to your server as if it were a locally attached block device. From here, you can pretty much do whatever you like. In my case, I want to use it with LVM to store VM disks in Proxmox, so the general layout would be something similar to the image below:&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2023/06/LUKS.png"&gt;&lt;img alt="" class="img-center" height="300" src="https://www.simonmott.co.uk/images/2023/06/LUKS.png" width="257"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;After setting up iSCSI and multipath, my system can see the storage LUN without any problems.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; multipath -ll&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;san (36589cfc000000c0d01729cc32c52ecc4) dm-9 TrueNAS,iSCSI Disk&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;size=2.0T features=&amp;#39;0&amp;#39; hwhandler=&amp;#39;0&amp;#39; wp=rw&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;`-+- policy=&amp;#39;round-robin 0&amp;#39; prio=15 status=active&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;|- 3:0:0:0 sdb 8:16 active ready running&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;`- 4:0:0:0 sdc 8:32 active ready running&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I plan to use LVM on LUKS, which essentially means the LUN in its entirety is encrypted and needs to be correctly decrypted before anything on it can be detected by LVM. I set up &lt;code&gt;/etc/crypttab&lt;/code&gt; with the appropriate key files and proceeded to test if it opens correctly without any prompting. This seemed to work as expected (san_luks is just the name I gave it in &lt;code&gt;/etc/crypttab&lt;/code&gt;):&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; systemctl status systemd-cryptsetup@san_luks.service&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;● systemd-cryptsetup@san_luks.service - Cryptography Setup for san_luks&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Loaded: loaded (/etc/crypttab; generated)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Active: active (exited) since Fri 2023-06-23 20:02:33 BST; 18h ago&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Docs: man:crypttab(5)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;man:systemd-cryptsetup-generator(8)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;man:systemd-cryptsetup@.service(8)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Main PID: 1935 (code=exited, status=0/SUCCESS)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Tasks: 0 (limit: 48147)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Memory: 0B&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;CGroup: /system.slice/system-systemd\x2dcryptsetup.slice/systemd-cryptsetup@san_luks.service&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jun 23 20:02:28 pve1 systemd[1]: Starting Cryptography Setup for san_luks...&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jun 23 20:02:28 pve1 systemd-cryptsetup[1935]: Set cipher aes, mode xts-plain64, key size 512 bits for device /dev/disk/by-uuid/4dfbd655-258b-42f8-b1a7-94155bdf1465.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jun 23 20:02:33 pve1 systemd[1]: Finished Cryptography Setup for san_luks.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I proceeded to reboot, and&amp;hellip; it didn&amp;rsquo;t open the volume. I confirmed that iSCSI and multipath were fine, but the volume just didn&amp;rsquo;t open on boot.&lt;/p&gt;&#10;&lt;p&gt;I tried enabling the cryptsetup service:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; systemd-cryptsetup@san_luks.service&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Failed to enable unit: Unit /run/systemd/generator/systemd-cryptsetup@san_luks.service is transient or generated.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I tried all sorts of arguments in &lt;code&gt;/etc/crypttab&lt;/code&gt;, but nothing seemed to work.&lt;/p&gt;&#10;&lt;p&gt;After a fair amount of digging, it became apparent that the typical use-case for this kind of setup is to open an encrypted volume and then mount a filesystem that resides on it. All the articles I could find were geared towards this and hinted that you need to have crypttab set to automatically open the encrypted volume (which I did), but you also need a corresponding entry in &lt;code&gt;/etc/fstab&lt;/code&gt; that references it. This reference, when systemd tries to mount it, actually triggers cryptsetup, and everything just works nicely.&lt;/p&gt;&#10;&lt;p&gt;This is a problem because I am not mounting a filesystem.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Update: See addendum below&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Ultimately, I settled on a dirty workaround to ensure my encrypted volume was opened correctly on system boot. I had already confirmed that it works without any prompts from me, so I created a new systemd unit file that should run after multipath is started and set a requirement for my unit to trigger &lt;code&gt;systemd-cryptsetup@san_luks.service&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;This should run after multipath is loaded, so I have access to the block device it creates, and then trigger cryptsetup. The unit file runs once at boot and basically does nothing. I&amp;rsquo;m sure there&amp;rsquo;s a nicer way to do this, but for me, this worked.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; cat /etc/systemd/system/luks_auto_open.service&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;[Unit]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Description=LUKS Auto open&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;After=multipathd.service&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Requires=systemd-cryptsetup@san_luks.service&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;[Service]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Type=oneshot&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;ExecStart=/usr/bin/echo&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;User=root&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;[Install]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;WantedBy=multi-user.target&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I don&amp;rsquo;t like this workaround at all, but it gets the job done and allows me to continue setting up the new storage for use in Proxmox.&lt;/p&gt;&#10;&lt;p&gt;I suspect there&amp;rsquo;s a more elegant way to do this that doesn&amp;rsquo;t involve a makeshift unit file, but my Google-fu has failed me.&lt;/p&gt;&#10;&lt;h3 id="addendum"&gt;Addendum&lt;/h3&gt;&#10;&lt;p&gt;As it turns out, there is indeed a better way to do this. My friend &lt;a href="https://blog.dataforce.org.uk/"&gt;Dataforce&lt;/a&gt; also ran into this problem and refused to accept there wasn&amp;rsquo;t a better way to do this.&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;&amp;ldquo;I&amp;rsquo;m convinced there must be a better more correct way&amp;rdquo;. 😄&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;He was so perturbed at my solution that he actually spent some more time than I did doing research and found the answer:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; remote-cryptsetup.target&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Initial testing seems to actually do what we want, rather than having to use my artisanal unit file. &lt;a href="https://blog.dataforce.org.uk/2023/06/remote-crypttab-on-boot/"&gt;Check out his page for more details&lt;/a&gt;&lt;/p&gt;</description></item><item><title>A Stratum 1 Time Server - The Basics</title><link>https://www.simonmott.co.uk/2022/02/a-stratum-1-time-server-the-basics/</link><pubDate>Sat, 12 Feb 2022 16:31:06 +0000</pubDate><guid>https://www.simonmott.co.uk/2022/02/a-stratum-1-time-server-the-basics/</guid><description>&lt;p&gt;A while ago, I decided to play around with trying to create something cheap that would be able to synchronise its time by using GPS instead of over the internet - essentially building my own Stratum 1 time server. I intend this to be a series of articles about NTP and time servers, but let&amp;rsquo;s start with the basics&amp;hellip;&lt;/p&gt;&#10;&lt;h5 id="what-is-a-stratum-1-timeserver"&gt;What is a Stratum 1 Time Server?&lt;/h5&gt;&#10;&lt;img alt="" class="img-right" height="268" src="https://www.simonmott.co.uk/images/2017/03/stratum.png" width="300"/&gt;&#10;&lt;p&gt;The lower the &amp;ldquo;Stratum&amp;rdquo; number the more accurate the time it should be able to tell. Usually Stratum 1 time servers are directly connected to an accurate source of time such as (but not limited to) Atomic, GPS or even Radio clocks. The stratum of the machine which itself is directly interfacing with the accurate time source would be &amp;ldquo;Stratum 0&amp;rdquo;. For each additional layer of NTP servers added, the stratum increases by 1.&lt;/p&gt;&#10;&lt;p&gt;So if the server that&amp;rsquo;s connected directly to the time source is stratum 0, it would appear to any clients who want to synchronise with it as a stratum 1 source. If someone then tries to synchronise to one of those, they would see a stratum 2 source and so on. The image on the right illustrates the top-down increase in stratum and was taken from &lt;a href="https://en.wikipedia.org/wiki/Network_Time_Protocol"&gt;Wikipedia&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;Generally the higher the stratum number, the less-accurate its view of time is. A stratum ranges from stratum 1 all the way to stratum 15 indicating the time is getting further away from a reference clock the higher you go. Stratum 16 indicates the clock is pretty far from the reference and should be considered un-synchronised and should not be used.&lt;/p&gt;&#10;&lt;h5 id="why-do-we-need-time-servers"&gt;Why do we need time servers?&lt;/h5&gt;&#10;&lt;p&gt;Every computer out there - be it a desktop, laptop, server or otherwise usually need to keep track of the time one way or the other. Computers usually have dedicated hardware to keep track of the time (notable exceptions are Raspberry Pis), some of which are more accurate than others but ultimately each one is different.&lt;/p&gt;&#10;&lt;p&gt;To demonstrate how computers can&amp;rsquo;t keep track of accurate time on their own, I rigged up 2 machines and synchronised their clocks to the same time server. Once initially synchronised I simply left them to run for 8 hours to see how much their view of time has drifted away from what the time server suggests is correct. &lt;em&gt;This test was completed without &lt;code&gt;ntpd&lt;/code&gt; creating a drift file (more on that later)&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;One thing note here is that the Pis clock is running faster than the reference clock, whereas the laptop is actually running slower.&lt;/p&gt;&#10;&lt;img alt="" class="img-center" height="371" src="https://www.simonmott.co.uk/images/2022/02/drift-wo_drift_file.png" width="667"/&gt;&#10;&lt;p&gt;This clearly shows that over just 8 hours, there&amp;rsquo;s a significant discrepancy between the two machine&amp;rsquo;s local clocks vs what the time actually is. Obviously the longer they remain un-synchronised, the larger the drift becomes.&lt;/p&gt;&#10;&lt;h5 id="how-do-i-deal-with-time-drift"&gt;How do I deal with time drift?&lt;/h5&gt;&#10;&lt;p&gt;On Linux, running &lt;code&gt;ntpd&lt;/code&gt; has the advantage of having some sophisticated features and algorithms behind it designed to keep your local clock as accurate as possible.&lt;/p&gt;&#10;&lt;p&gt;Once &lt;code&gt;ntpd&lt;/code&gt; has been running for a while (and has been able to successfully synchronise time with an external source) it&amp;rsquo;s able to estimate the inherent drift of your local clock and compensate for it accordingly.&lt;/p&gt;&#10;&lt;p&gt;The drift itself is called &amp;ldquo;frequency error&amp;rdquo;. Calculating it is a process that continuously happens in the background, which ultimately results in the generation of a &amp;ldquo;drift file&amp;rdquo;. This file is used to compensate for drift when &lt;code&gt;ntpd&lt;/code&gt; starts up next so it doesn&amp;rsquo;t have to go through the initial learning process again.&lt;/p&gt;&#10;&lt;p&gt;Once it had determined the frequency error for my two test machines, I ran the same test we did earlier to see how well &lt;code&gt;ntpd&lt;/code&gt; coped with clock drift.&lt;/p&gt;&#10;&lt;img alt="" class="img-center" height="371" src="https://www.simonmott.co.uk/images/2022/02/drift-w_drift_file.png" width="667"/&gt;&#10;&lt;p&gt;As you can see from the above graph (kept at the same scale), we&amp;rsquo;ve easily managed to keep drift on both machines to within 0.1s of our reference clock. You&amp;rsquo;ll notice however that both clocks are now running faster than our reference&amp;hellip;&lt;/p&gt;&#10;&lt;p&gt;Environmental conditions affect your computers ability to track time, as does system load and even power fluctuations from your utility provider. This means that if you were to monitor the frequency error reported by &lt;code&gt;ntpd&lt;/code&gt;, you&amp;rsquo;d see that it can fluctuate quite a bit; You&amp;rsquo;ll likely never be able to get a stable frequency error so will likely never get 100% perfect time-keeping without help, but its a damn good start and a large improvement over having no clock discipline at all!&lt;/p&gt;&#10;&lt;h5 id="so-where-do-i-start"&gt;So, where do I start?&lt;/h5&gt;&#10;&lt;p&gt;Most default installs for &lt;code&gt;ntpd&lt;/code&gt; come pre-configured with servers from the &lt;a href="http://www.pool.ntp.org/en/"&gt;NTP Pool Project&lt;/a&gt; so as long as you&amp;rsquo;re running &lt;code&gt;ntpd&lt;/code&gt; then you should be OK.&lt;/p&gt;&#10;&lt;p&gt;You can check the current status of &lt;code&gt;ntpd&lt;/code&gt; by querying the local machine for its list of peers by using &lt;code&gt;ntpq -pn&lt;/code&gt;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; ntpq -pn&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; remote refid st t when poll reach delay offset jitter&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;==============================================================================&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;*85.199.214.99 .GPS. 1 u 32 64 377 8.406 -0.147 0.073&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;-138.68.151.69 194.117.9.136 3 u 38 1024 377 5.835 2.372 15.680&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;+129.250.35.250 249.224.99.213 2 u 1052 1024 377 6.587 0.666 0.139&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;+80.87.131.131 80.87.128.222 4 u 442 1024 377 22.322 -0.635 0.270&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This output shows some useful information so lets work through it (Taken from &lt;a href="http://nlug.ml1.co.uk/2012/01/ntpq-p-output/831"&gt;http://nlug.ml1.co.uk/2012/01/ntpq-p-output/831&lt;/a&gt; where more detailed descriptions of this output can be found)&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;remote&lt;/strong&gt; - The remote peer or server being synced to&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;refid&lt;/strong&gt; - Where or what the remote peer or server is itself synchronised to&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;st&lt;/strong&gt; - The remote peer or server Stratum (from our point of view)&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;t&lt;/strong&gt; - Type (u: unicast or manycast, b: broadcast or multicast, l: local reference clock, s: symmetric peer, A: manycast server, B: broadcast server, M: multicast server)&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;when&lt;/strong&gt; - When last polled (seconds ago, “h” hours ago, or “d” days ago)&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;poll&lt;/strong&gt; - Polling frequency&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;reach&lt;/strong&gt; - An 8-bit left-shift shift register value recording polls (bit set = successful, bit reset = fail) displayed in octal&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;delay&lt;/strong&gt; - Round trip communication delay to the remote peer or server (milliseconds)&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;offset&lt;/strong&gt; - Mean offset (phase) in the times reported between this local host and the remote peer or server (milliseconds)&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;jitter&lt;/strong&gt; - Mean deviation (jitter) in the time reported for that remote peer or server (miliseconds)&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h5 id="what-does-all-that-actuallymean"&gt;What does all that ACTUALLY mean?&lt;/h5&gt;&#10;&lt;p&gt;Looking at what we have above - we&amp;rsquo;re using &lt;code&gt;85.199.214.99&lt;/code&gt; as our primary time source (signified by the &lt;strong&gt;*&lt;/strong&gt;). That server is getting its time direct from a GPS clock and so is a stratum 1 server. Its reported time differs from what we think the current time is by only 0.147ms (we&amp;rsquo;re running faster than it).&lt;/p&gt;&#10;&lt;p&gt;The stratum 2 and 4 servers are also pretty close with their offset so are potential candidates to synchronise time with if the current stratum 1 server goes offline. &lt;code&gt;ntpd&lt;/code&gt; will automatically choose which server to synchronise from and will also weed out ones that are seemingly reporting bad time by comparing it with the other servers loaded. If you&amp;rsquo;re using a configuration which makes use of the NTP pool then the servers that appear will likely be different each time you start &lt;code&gt;ntpd&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;A big thanks goes to the volunteers at the &lt;a href="http://www.pool.ntp.org/en/"&gt;NTP Pool Project&lt;/a&gt; for making it possible without running your own infrastructure!&lt;/p&gt;&#10;&lt;p&gt;This article should hopefully have given you a bit more insight as to why time servers are needed. In the future I plan to explore setting up a local NTP server to use with a view of getting our own GPS timing device hooked up and working.&lt;/p&gt;</description></item><item><title>Ubiquiti EdgeRouter IPsec performance</title><link>https://www.simonmott.co.uk/2018/08/ubiquiti-edgerouter-ipsec-performance/</link><pubDate>Wed, 29 Aug 2018 17:11:16 +0000</pubDate><guid>https://www.simonmott.co.uk/2018/08/ubiquiti-edgerouter-ipsec-performance/</guid><description>&lt;img alt="ubiquiti-logo" class="img-right" height="151" src="https://www.simonmott.co.uk/images/2018/08/UBNT_Primary_Logo_RGB.png" width="200"/&gt;&#10;&lt;p&gt;I&amp;rsquo;ve been working on setting up a lab environment for myself and decided to pick up a couple of Ubiquiti&amp;rsquo;s &lt;a href="https://www.ubnt.com/edgemax/edgerouter-4/"&gt;EdgeRouter 4&lt;/a&gt; routers to act as my core routing devices, along with an &lt;a href="https://www.ubnt.com/edgemax/edgerouter-x/"&gt;EdgeRouter X&lt;/a&gt; to act as my out-of-band router. These new devices, along with an &lt;a href="https://www.ubnt.com/edgemax/edgerouter-lite/"&gt;EdgeRouter Lite&lt;/a&gt; loaned to me for this article by Dom at &lt;a href="https://loveservers.com/"&gt;LoveServers&lt;/a&gt;, puts me in a reasonably good position to do some performance testing between these different models of EdgeMAX routers. I thought a good place to start would be to compare how well these different models perform in terms of IPsec throughput and overall CPU usage at the same time.&lt;/p&gt;&#10;&lt;p&gt;Part of my lab setup will involve provisioning a couple of IPsec tunnels between the lab and my home network. So whilst this article will mainly focus on IPsec, I will be including some general observations/comparisons between the devices too which may be informative to some people.&lt;/p&gt;&#10;&lt;h5 id="methodology"&gt;Methodology&lt;/h5&gt;&#10;&lt;p&gt;According to Ubiquiti&amp;rsquo;s data sheets, the EdgeRouter 4 should be the beefier device, so it seemed logical to use the pair I have to establish a base number which I can compare the other two models against. The physical layout I&amp;rsquo;ve used for the testing is pretty straightforward in that it&amp;rsquo;s two Dell R210ii servers directly attached to a router each, with another link between the two routers, as illustrated below.&lt;/p&gt;&#10;&lt;img alt="physical-layout" class="img-center" height="293" src="https://www.simonmott.co.uk/images/2018/08/er4-er4.png" width="560"/&gt;&#10;&lt;p&gt;The routers themselves are initially at the factory default settings other than rudimentary interface configs, some static routes, hardware offloading (more on that later) and the configuration components needed to establish an encrypted GRE tunnel using IPsec. Unfortunately, as I am limited by the overall performance for just one of the EdgeRouter 4&amp;rsquo;s, I wont really know if the throughput is capped by encryption or decryption performance; So for the purposes of this test, I will assume the value I establish will be the same each way for the EdgeRouter 4. I may explore this in the future once I have something that can push more data than these devices are capable of, which should allow me to measure them independently.&lt;/p&gt;&#10;&lt;p&gt;However, as these devices should, in theory, out-perform the other models, I should be able to discern encryption and decryption throughput separately for the EdgeRouter Lite and EdgeRouter X&lt;/p&gt;&#10;&lt;p&gt;I referenced &lt;a href="https://help.ubnt.com/hc/en-us/articles/115006567467-EdgeRouter-Hardware-Offloading"&gt;this article&lt;/a&gt; from Ubiquiti&amp;rsquo;s support center which, at the time of writing, details both the encryption and hashing algorithms that are supported by the different offload engines contained within my test devices - specifically for firmware v1.10.5.&lt;/p&gt;&#10;&lt;p&gt;I thus settled on these settings for the bulk of my testing which are supported by both the Cavium (ER4 and ERL) and MediaTek (ERX) offload engines. Each device was rebooted when any change to its hardware offload settings were made, just to ensure it loaded correctly.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Phase 1 - Internet Key Exchange&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Phase 2 - Encapsulating Security Payload&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Key Exchange: IKEv2 Encryption Algo: AES256 Hash Algo: SHA1 Diffie-Hellman Group: 14 (2048 bit) Lifetime: 86400&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Mode: Tunnel Encryption Algo: AES128 Hash Algo: SHA1 Perfect Forward Secrecy: Enabled Lifetime: 3600&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h5 id="establishing-a-baseline"&gt;Establishing a Baseline&lt;/h5&gt;&#10;&lt;p&gt;For each of the tests, regardless of router configuration, I will be useing iperf to measure throughput between servers and will keep the settings at basically default - run via TCP, for 30s and display output every 1s (In CSV format so I can compile the results).&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Server2# iperf -s&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Server1# iperf -c 172.26.2.2 -x CSV -y c -t 30 -i 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;img alt="edgerouter-raw-throughput-graph" class="img-left" height="428" src="https://www.simonmott.co.uk/images/2018/08/Throughput-on-GigE-All-Offloading-Enabled.png" width="372"/&gt;&#10;&lt;p&gt;As for measuring CPU usage, I popped a script in /tmp on both routers being tested that would calculate CPU usage based on &lt;code&gt;/proc/stat&lt;/code&gt; and output to console with a timestamp so I could correlate between tests.&lt;/p&gt;&#10;&lt;p&gt;Once I had the initial test plan sorted out, I made sure that all relevant hardware offloading was enabled and started by measuring if the devices can actually forward traffic at 1 Gbps. This was a simple test using iperf from &lt;strong&gt;Server 1&lt;/strong&gt; over to &lt;strong&gt;Server 2&lt;/strong&gt; via the routers, without any IPsec or GRE configuration in place. Just pure packet forwarding via static routes.&lt;/p&gt;&#10;&lt;p&gt;The routers are ordered from left to right; Most expensive to least expensive. EdgeRouter 4, EdgeRouter Lite and EdgRouter X respectively and thankfully, it seems that all routers are more than capable of forwarding packets at basically line rate &lt;strong&gt;(See image to the left)&lt;/strong&gt;.&#10; &lt;/p&gt;&#10;&lt;img alt="edgerouter-raw-throughput-cpu-graph" class="img-right" height="428" src="https://www.simonmott.co.uk/images/2018/08/CPU-Usage-on-GigE-All-Offloading-Enabled.png" width="372"/&gt;&#10;&lt;p&gt;Whilst I expected nothing less, I wanted to make sure that they were capable of actually forwarding packets at gigabit speeds - I&amp;rsquo;ve seen some routers that do a lot worse! What is more interesting about this first test seems to lie with the CPU usage of the devices whilst pushing packets.&lt;/p&gt;&#10;&lt;p&gt;Both the EdgeRouter 4 and EdgeRouter Lite use SoC&amp;rsquo;s from Cavium and use a &amp;ldquo;not insignificant&amp;rdquo; amount of CPU when just routing, whereas the EdgeRouter X uses a MediaTek based SoC which hardly makes a dent.&lt;/p&gt;&#10;&lt;p&gt;From observing what&amp;rsquo;s going on from the PoV of the device, most of the usage on the Cavium based devices appears to comes from soft interrupts so, I&amp;rsquo;d expect this is simply down to the different manufacturers hardware offloading methods which probably explains the surprisingly low CPU usage for the EdgeRouter X.&lt;/p&gt;&#10;&lt;p&gt;Whilst this is certainly an interesting point to see this early on, I would be curious as to how the CPU in the X performs with other tasks that cant really be offloaded as easily. I may test this in more detail based on a more traditional home/office type test with QoS and ACLs etc or even some dynamic routing enabled to try to tax the CPU a bit more.&lt;/p&gt;&#10;&lt;p&gt;For now however, that&amp;rsquo;s out of scope of this article.&lt;/p&gt;&#10;&lt;h5 id="initial-testing"&gt;Initial Testing&lt;/h5&gt;&#10;&lt;p&gt;At the time of writing this, there wasn&amp;rsquo;t really much in the way of documented figures for IPsec performance on the EdgeRouter 4 that I could find, so I figured - I have the kit, lets test it!&lt;/p&gt;&#10;&lt;img alt="edgerouter4-phase2-aes-performance" class="img-right" height="428" src="https://www.simonmott.co.uk/images/2018/08/ER4-Phase-2-AES.png" width="372"/&gt;&#10;&lt;p&gt;The initial test was to measure throughput between two EdgeRouter 4s, and use that as a base to compare with the older models as they&amp;rsquo;re also quite popular. As mentioned previously; I am testing between just these two devices and I cant tell if the performance I see in my results is due to hitting a ceiling on encryption or decryption, so for the remainder of this article I will assume both figures are the same for the ER4.&lt;/p&gt;&#10;&lt;p&gt;Whilst the testing was done using the IPsec configuration outlined earlier, I did also test using AES256 for both Phase 1 and 2. As you might expect, throughput was a little less when using AES256 due to the increase in computation required. I decided to stick with AES128 as the primary choice for the remainder of the tests.&lt;/p&gt;&#10;&lt;p&gt;AES256 &lt;strong&gt;is&lt;/strong&gt; a better choice, generally speaking for encryption, however the added compute required didn&amp;rsquo;t seem worth it to me in conjunction with the relatively short key lifetime&amp;rsquo;s, AES128 should be secure enough for my purposes.&lt;/p&gt;&#10;&lt;p&gt;I did also dabble with MD5 as the hashing algorithm, but in all of my tests it performed worse than SHA1 - I simply chalk this up to the offload engine being optimised for SHA1 vs MD5.&lt;/p&gt;&#10;&lt;p&gt;If you&amp;rsquo;re looking for guidance on what configuration to use for IPsec, a good read is the &lt;a href="https://www.ncsc.gov.uk/guidance/using-ipsec-protect-data"&gt;NCSC guidelines&lt;/a&gt; for IPsec along with &lt;a href="https://www.servercentral.com/ipsec-parameter-choice-rationales/"&gt;this page&lt;/a&gt; which explains why you might choose one type over the other.&lt;/p&gt;&#10;&lt;p&gt;As you can see, the EdgeRouter 4 performs pretty well in this test. CPU usage for both tests were around the 50% mark.&lt;/p&gt;&#10;&lt;h5 id="initial-observations"&gt;Initial Observations&lt;/h5&gt;&#10;&lt;p&gt;Something I did note during my tests but couldn&amp;rsquo;t quite explain is that &lt;em&gt;sometimes&lt;/em&gt;, throughput between the EdgeRouter 4s would drop by about 100 Mbps along with a CPU usage drop from 50% utilization, down to 35-40%. I haven&amp;rsquo;t been able to figure this one out definitively however I am guessing its a side-effect of the interaction between the CPU and its co-processor for offloading - possibly something to do with power states. It would only manifest every 1 in 10 tests or so and apply consistently for that flow.&lt;/p&gt;&#10;&lt;p&gt;Because I was consistently getting around 440-450 Mbps however, I went with an average of those results as the value for the ER4.&lt;/p&gt;&#10;&lt;img alt="edgerouter4-different-offload-settings" class="img-left" height="428" src="https://www.simonmott.co.uk/images/2018/08/ER4-Offload-Modules.png" width="372"/&gt;&#10;&lt;p&gt;Another curious observation came about when playing around with the different hardware offload modes. For all of the tests I compiled results with all hardware offloading enabled - but out of interest, I decided to disable &lt;strong&gt;ALL&lt;/strong&gt; hardware offloading &lt;strong&gt;EXCEPT&lt;/strong&gt; for the IPsec module and in all cases I got better throughput (about 5% more) out of the EdgeRouter 4 with a consistent 50% CPU usage, like before.&lt;/p&gt;&#10;&lt;p&gt;To me, this result is somewhat unexpected. I would have thought that offloading as much as possible to the offload engine would give better results but that does not appear to be the case.&lt;/p&gt;&#10;&lt;p&gt;I am only speculating but I think this may be to do with packets going back and forth from the co-processor unit in the Cavium chip. For example, A packet may come into the device for forwarding - get offloaded and then need to come back out of the offload engine to be processed further before being GRE encapsulated (and offloaded) and then ultimately encrypted (again, IPsec offloaded)?&#10; &#10;I am curious to see how this behaviour would affect overall performance of the device when its doing other CPU related tasks and not just IPsec encryption. However that&amp;rsquo;s out of scope for this article.&lt;/p&gt;&#10;&lt;h5 id="testing-the-edgerouter-lite"&gt;Testing the EdgeRouter Lite&lt;/h5&gt;&#10;&lt;p&gt;Now that we have some figures for the EdgeRouter 4, I can move on to testing one of the other models. The logic here is that the EdgeRouter 4 is the more capable device by far, so by putting one of the (in theory) less powerful devices in place of one of the EdgeRouter 4s, the result I get would be capped by the performance of that device, and thus we measure its performance.&lt;/p&gt;&#10;&lt;p&gt;Using this logic, I can push traffic through the EdgeRouter Lite as the first hop, thus testing its encryption performance, and vice versa, having the EdgeRouter Lite as the last hop, testing its decryption performance.&lt;/p&gt;&#10;&lt;img alt="edgerouter-lite-ipsec-performance" class="img-center" height="428" src="https://www.simonmott.co.uk/images/2018/08/ERL-Combined.png" width="744"/&gt;&#10;&lt;p&gt;The EdgeRouter Lite clearly suffers with its weaker CPU here - It was pretty much maxed out through the testing. This would probably perform OK if you don&amp;rsquo;t have a lot of bandwidth to play with, but doesn&amp;rsquo;t seem to do well much past 100 Mbit.&lt;/p&gt;&#10;&lt;p&gt;As observed with the ER4, curiously I see higher throughput through the EdgeRouter Lite with all but IPsec offloading disabled (about 10-12% improvement) whilst CPU usage is about the same.&lt;/p&gt;&#10;&lt;h5 id="testing-the-edgerouter-x"&gt;Testing the EdgeRouter X&lt;/h5&gt;&#10;&lt;p&gt;Given the result observed earlier for the raw throughput test of the EdgeRouter X, I was very interested to see how this one would turn out. This particular model of EdgeRouter is based on a different SoC manufacturer than the other two devices (MediaTek, vs Cavium respectively) so has a different hardware offload engine. This even more apparent in the configuration of the router and how you enable hardware offloading.&lt;/p&gt;&#10;&lt;p&gt;For the Cavium devices, we have a choice to enable specific features as/where needed (Forwarding has to be offloaded for any of the others to work, except for IPsec)&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; system offload ipv4 forwarding &lt;span class="nb"&gt;enable&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; system offload ipv4 gre &lt;span class="nb"&gt;enable&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; system offload ipv4 pppoe &lt;span class="nb"&gt;enable&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; system offload ipv4 vlan &lt;span class="nb"&gt;enable&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; system offload ipv6 forwarding &lt;span class="nb"&gt;enable&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; system offload ipv6 pppoe &lt;span class="nb"&gt;enable&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; system offload ipv6 vlan &lt;span class="nb"&gt;enable&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; system offload ipsec &lt;span class="nb"&gt;enable&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Whereas for the EdgeRouter X&amp;rsquo;s MediaTek system, we simply have the choice of&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; system offload hwnat &lt;span class="nb"&gt;enable&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; system offload ipsec &lt;span class="nb"&gt;enable&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So, using the same IPsec configuration settings for the EdgeRouter 4 and EdgeRouter Lite tests (detailed above), this router performed surprisingly well - Better than I had initially expected.&lt;/p&gt;&#10;&lt;img alt="edgerouter-x-ipsec-performance" class="img-center" height="428" src="https://www.simonmott.co.uk/images/2018/08/ERX-Combined.png" width="744"/&gt;&#10;&lt;p&gt;There&amp;rsquo;s a noticeable improvement in throughput and CPU usage on the ERX over the ERL which is quite surprising given the price point of the two models.&lt;/p&gt;&#10;&lt;p&gt;Interestingly however, unlike the two Cavium devices, the EdgeRouter X loses encryption performance with all other offloading disabled but gains some on decryption. Whilst the other two devices CPU usage remained pretty consistent, there is a noticeable change on the ERX for all offload vs IPsec only offloading. &lt;/p&gt;&#10;&lt;img alt="edgerouter-x-different-offload-performance" class="img-center" height="428" src="https://www.simonmott.co.uk/images/2018/08/ERX-IPsec-Offload-Combined.png" width="744"/&gt;&#10;&lt;p&gt;This just reinforces the fact that not all offload engines are equal - even within devices under the same brand. That being said however the EdgeRouter X seems to be a very capable device and I do look forward to a time when I can compare it to the EdgeRouter Lite in a more &amp;ldquo;real-world&amp;rdquo; scenario.&lt;/p&gt;&#10;&lt;h5 id="bandwidth-capped-test"&gt;Bandwidth-capped Test&lt;/h5&gt;&#10;&lt;p&gt;The above tests do well to illustrate how well each model of router perform when unrestricted and allowed to try to push as much as they possibly can. I opted to do one final test and limit bandwidth to 100Mbit. I decided to do this on each server by forcing their NICs to 100M FDX. The aim of this test is to illustrate how each routers compare to each other when given the same workload.&lt;/p&gt;&#10;&lt;img alt="edgerouter-100mbit-capped-performance" class="img-center" height="389" src="https://www.simonmott.co.uk/images/2018/08/Router-CPU-Usage-Throughput-capped-at-100-Mbit.png" width="746"/&gt;&#10;&lt;p&gt;All of the routers managed line rate (100M) and as the above shows, really reinforces how much better the EdgeRouter X is at handling IPsec over the EdgeRouter Lite. Interestingly in the capped test, the ERL used more CPU on decryption which is the opposite to earlier when it was pushing as much as it possibly can.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;I originally set out to determine what throughput I could expect from these various devices at each end of an IPsec tunnel to allow for a more informed decision as to how to structure my network. The EdgeRouter 4 is pretty much what I expected it to be - in that it&amp;rsquo;s a very capable device and looks like it will be more then capable as a core router for my use case.&lt;/p&gt;&#10;&lt;p&gt;Despite the image this article paints for the EdgeRouter Lite, it is still a very capable device. It&amp;rsquo;s a router that&amp;rsquo;s aimed at home or small office users and the likelihood they have an internet connection that requires higher IPsec throughput is pretty low. Whilst the device itself isnt the cheapest around, the features it comes with certainly make it an attractive prospect for more advanced users who want to get more out of their Router than something like a BT Home Hub.&lt;/p&gt;&#10;&lt;p&gt;The EdgeRouter X on the other hand is a truly intriguing device! On the face of things it looks like it should perform better than the Lite at most things - however I will likely be comparing these in a more direct fashion in the future. Whilst the EdgeRouter X does indeed perform well, It will not be suitable as a drop-in replacement for the Lite for all situations - namely where dealing with high packet counts are required. The EdgeRouter Lite is rated at 1 million Packets-Per-Second (PPS) at 64 bytes in size whereas the EdgeRouter X is only rated for 260,000.&lt;/p&gt;&#10;&lt;p&gt;With that being said though, the EdgeRouter X is still a very good candidate for enthusiast users or light deployments - especially given its PoE passthrough feature.&lt;/p&gt;&#10;&lt;p&gt;I will leave you with a final graph that shows each router&amp;rsquo;s IPsec throughput side-by-side to highlight the differences between them.&lt;/p&gt;&#10;&lt;img alt="" class="img-center" height="389" src="https://www.simonmott.co.uk/images/2018/08/IPsec-Throughput.png" width="746"/&gt;&#10;&lt;p&gt;It&amp;rsquo;ll be interesting to see if Ubiquiti can improve on these numbers in the future through software updates, or if the limitations are purely with the offloading hardware.&lt;/p&gt;</description></item><item><title>Dual-stacking Proxmox Web UI (pveproxy)</title><link>https://www.simonmott.co.uk/2018/06/dual-stacking-proxmox-web-ui-pveproxy/</link><pubDate>Wed, 20 Jun 2018 20:49:59 +0000</pubDate><guid>https://www.simonmott.co.uk/2018/06/dual-stacking-proxmox-web-ui-pveproxy/</guid><description>&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2018/06/Proxmox-logo-stacked.png"&gt;&lt;img alt="" class="img-right" height="190" src="https://www.simonmott.co.uk/images/2018/06/Proxmox-logo-stacked.png" width="200"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;As part of my recent (and ongoing) project to implement native IPv6 on my own infrastructure (except at home&amp;hellip; I&amp;rsquo;m looking at you &lt;a href="https://www.hyperoptic.com/"&gt;Hyperoptic&lt;/a&gt;), I decided to try to dual-stack as much as possible so that when I have IPv6 connectivity, services would prefer that over IPv4, without making things unavailable.&lt;/p&gt;&#10;&lt;p&gt;As it turns out, Proxmox&amp;rsquo;s Web interface (pveproxy) doesn&amp;rsquo;t listen on the IPv6 address family by default. This stumped me for a little while, but its pretty simple to fix when you know whats going on.&lt;/p&gt;&#10;&lt;p&gt;This post is going to spend most of its time explaining why this happens rather than the fix. If you&amp;rsquo;re just here to see how to do it, check below.&lt;/p&gt;&#10;&lt;h5 id="dual-stacking-pveproxy---aka-the-fix"&gt;Dual-Stacking pveproxy - aka &amp;ldquo;The Fix&amp;rdquo;&lt;/h5&gt;&#10;&lt;p&gt;pveproxy seems to rely on the contents of &lt;code&gt;/etc/hosts&lt;/code&gt; in order to figure out what address family to use when binding port 8006 (the default GUI port). In order to change this we need to edit our &lt;code&gt;/etc/hosts&lt;/code&gt; file and change the line which identifies our Proxmox host&lt;/p&gt;&#10;&lt;p&gt;We start with (for example)&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;10.0.0.100 pvehost.some.domain pvehost pvelocalhost&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And we should change it to&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;::ffff:10.0.0.100 pvehost.some.domain pvehost pvelocalhost&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;All we&amp;rsquo;ve done here is add &lt;code&gt;::ffff:&lt;/code&gt; before the IP address of our node. This tells the OS that its an IPv6 address - but its a special &lt;a href="https://en.wikipedia.org/wiki/IPv6#IPv4-mapped_IPv6_addresses"&gt;IPv4-mapped-IPv6 address&lt;/a&gt;. Restart the &lt;code&gt;pveproxy&lt;/code&gt; service and you should now see it binds to an IPv6 socket&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;tcp6 0 0 :::8006 :::* LISTEN -&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Viola - The Proxmox Web interface should work on both IPv4 and IPv6.&lt;/p&gt;&#10;&lt;h5 id="how-pveproxy-chooses-which-family-to-use"&gt;How pveproxy chooses which family to use&amp;hellip;&lt;/h5&gt;&#10;&lt;p&gt;By default, pveproxy decides to bind to an IPv4 family socket. By changing the family to v6, enables it to work for both families, primarily because of how the OS is configured.&lt;/p&gt;&#10;&lt;p&gt;Specifically, this depends on the value of &lt;code&gt;bindv6only&lt;/code&gt; in sysctl. If this is enabled then the socket would &lt;strong&gt;only&lt;/strong&gt; work for IPv6 addresses and applications would have to specifically bind to both v4 and v6 address families independently, depending on which they want to support.&lt;/p&gt;&#10;&lt;p&gt;Leaving &lt;code&gt;bindv6only&lt;/code&gt; disabled (default) is my preferred choice here as this would affect more than just Proxmox for me.&lt;/p&gt;&#10;&lt;p&gt;In order to figure this one out, I had to dig into the supplied perl modules for Proxmox. At the time of writing, I was using Proxmox 5.2 for my testing. Because I&amp;rsquo;m looking at the source for the modules, I wont quote line numbers as they will likely change over time. I will however link to the corresponding git commits.&lt;/p&gt;&#10;&lt;p&gt;If we start with the module for pveproxy - &lt;code&gt;/usr/share/perl5/PVE/Service/pveproxy.pm&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;(Git: &lt;a href="https://git.proxmox.com/?p=pve-manager.git;a=blob;f=PVE/Service/pveproxy.pm;h=2d3d4cf7ff410a04c6fe0579f59dde4fec1e56e3;hb=HEAD#l70"&gt;2d3d4cf7ff410a04c6fe0579f59dde4fec1e56e3&lt;/a&gt;)&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-perl" data-lang="perl"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$family&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;PVE::Tools::&lt;/span&gt;&lt;span class="n"&gt;get_host_address_family&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$self&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;nodename&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$self&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;create_reusable_socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8006&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;undef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$family&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s pretty clear here that it gets the address family for &lt;em&gt;something&lt;/em&gt;, and then creates a socket bound to port 8006 using that family. Tracing back to where &lt;code&gt;nodename&lt;/code&gt; actually gets set, we end up looking at &lt;code&gt;/usr/share/perl5/PVE/INotify.pm&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;(Git: &lt;a href="https://git.proxmox.com/?p=pve-common.git;a=blob;f=src/PVE/INotify.pm;h=0b9ea4adc3e078a47369cd97bc6c271a45f16870;hb=HEAD#l502"&gt;0b9ea4adc3e078a47369cd97bc6c271a45f16870)&lt;/a&gt;)&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-perl" data-lang="perl"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;sub&lt;/span&gt; &lt;span class="nf"&gt;nodename&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$cached_nodename&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nv"&gt;$cached_nodename&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$sysname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$nodename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;POSIX::&lt;/span&gt;&lt;span class="n"&gt;uname&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$nodename&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="sr"&gt;s/\..*$//&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# strip domain part, if any&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;die&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;unable to read node name\n&amp;#34;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$nodename&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$cached_nodename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$nodename&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$cached_nodename&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;My understanding of what the above snippet does (&lt;a href="http://perldoc.perl.org/POSIX.html#uname"&gt;POSIX::uname&lt;/a&gt;) is that it in-fact grabs the same values as would be visible from &lt;code&gt;uname&lt;/code&gt; on command line. Specifically the &amp;ldquo;kernel-name&amp;rdquo; and &amp;ldquo;nodename&amp;rdquo; arguments&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@pvehost:~# uname -sn&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Linux pvehost&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@pvehost:~# uname --kernel-name --nodename&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Linux pvehost&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;From here, a host lookup is performed against the &lt;code&gt;nodename&lt;/code&gt; value. On a fresh install this is typically an IPv4 address, so pveproxy will only ever bind to the IPv4 address family. The change to the host entry made earlier now technically makes this an IPv6 address, thus the family chosen is IPv6.&lt;/p&gt;&#10;&lt;p&gt;Personally, I&amp;rsquo;d like to have a bit more control over how pveproxy binds in the future.&lt;/p&gt;</description></item><item><title>Ethereum Mining with NVIDIA on Linux</title><link>https://www.simonmott.co.uk/2017/07/ethereum-mining-nvidia-linux/</link><pubDate>Thu, 06 Jul 2017 00:05:52 +0000</pubDate><guid>https://www.simonmott.co.uk/2017/07/ethereum-mining-nvidia-linux/</guid><description>&lt;img alt="" class="img-right" height="200" src="https://www.simonmott.co.uk/images/2017/07/ethereum-icon.png" width="160"/&gt;&#10;&lt;p&gt;Bitcoin has been getting a lot of attention in the media lately; primarily due to its association with recent high profile ransomware incidents. Bitcoin was first introduced back in 2009 as a digital currency and has been steadily gaining traction since, increasing almost 140% in value so far this year!&lt;/p&gt;&#10;&lt;p&gt;Bitcoin however, is not the only player in the game; Ethereum is another popular digital currency, currently sitting at 2nd place in total market value and is getting a lot of activity on currency exchanges.&lt;/p&gt;&#10;&lt;p&gt;An incentive to help keep the underlying &amp;ldquo;network&amp;rdquo; up and running (for both Ethereum and Bitcoin, amongst others) is a piece of software which can be used to validate transactions on the network and issue rewards for doing so. This is otherwise known as &lt;strong&gt;Mining&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;p&gt;My current Gaming PC seems to grab me a reasonable amount of Ethereum Tokens on 2+ year old hardware. Certainly enough to make me want to play around with actually mining some.&lt;/p&gt;&#10;&lt;h5 id="tldr"&gt;TLDR&lt;/h5&gt;&#10;&lt;p&gt;Skip right to the overclocking commands &lt;a href="#conclusion"&gt;here&lt;/a&gt;. Otherwise, continue reading :)&lt;/p&gt;&#10;&lt;h5 id="why-use-linux"&gt;Why use Linux?&lt;/h5&gt;&#10;&lt;p&gt;The mining program I am using is currently a &lt;a href="https://github.com/ethereum-mining/ethminer"&gt;Fork of a Fork&lt;/a&gt; from the original C++ based version developed by the Ethereum Foundation. In its FAQ there seem to be known issues with NVIDIA, WDDM and Windows 10 which cause lower-than expected performance of NVIDIA cards when mining. A supposed fix is to use an older set of NVIDIA drivers along with a different build of the mining software specifically built for CUDA 6.5.&lt;/p&gt;&#10;&lt;p&gt;The machine I am using is my Gaming PC (which requires Windows), so I&amp;rsquo;m not prepared to jump through those hoops - running older drivers isn&amp;rsquo;t always conducive to a good gaming experience. My graphics card is NVIDIA and I&amp;rsquo;ve always had reasonable experiences using their Linux drivers so giving this a go on Linux seemed like a natural fit.&lt;/p&gt;&#10;&lt;h5 id="my-hardware"&gt;My hardware&lt;/h5&gt;&#10;&lt;p&gt;I&amp;rsquo;ve not yet built myself a dedicated mining rig but these are the specs I&amp;rsquo;m working with:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Gigabyte H67N-USB3-B3 Motherboard&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Intel Core i7-2600 CPU @ 3.40GHz&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;16GB RAM&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;NVIDIA GeForce GTX 970 - GM204 (GV-N970IXOC-4GD)&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Current Driver Version: 375.66&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h5 id="getting-started"&gt;Getting Started&lt;/h5&gt;&#10;&lt;p&gt;In order to start mining Ethereum, you&amp;rsquo;ll first need a working Linux installation - My distro of choice is &lt;a href="https://www.ubuntu.com/"&gt;Ubuntu (16.04 LTS) Xenial&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;When first installing and running Ubuntu I did have to make use of &lt;code&gt;nomodeset&lt;/code&gt; in grub before anything would actually display on my screen - This seems to be card specific but it might help you get going! See &lt;a href="https://ubuntuforums.org/showthread.php?t=1613132"&gt;here&lt;/a&gt; for more info about &lt;code&gt;nomodeset&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;Once you&amp;rsquo;re set up, you&amp;rsquo;ll need to install NVIDIA drivers. You can obtain Linux specific ones from &lt;a href="http://www.nvidia.co.uk"&gt;NVIDIA directly&lt;/a&gt; and install those. As I&amp;rsquo;m using Ubuntu however, there should be some available in repos - &lt;code&gt;apt-get install nvidia-375&lt;/code&gt; at the time of writing this.&lt;/p&gt;&#10;&lt;h5 id="establishing-a-baseline"&gt;Establishing a baseline&lt;/h5&gt;&#10;&lt;p&gt;Before we make any tweaks, we should establish what our baseline is on default settings. Keep in mind that this is specific to me and my hardware - your baseline may well be different depending on what equipment you use.&lt;/p&gt;&#10;&lt;p&gt;The version of &lt;code&gt;ethminer&lt;/code&gt; I am using comes with a built in benchmark mode. To make these tests a fair comparison between tweaks, I&amp;rsquo;ve tested everything against block &lt;a href="https://etherchain.org/block/3969748"&gt;3969748&lt;/a&gt; (A random block I chose which represents the current difficulty of Ethash).&lt;/p&gt;&#10;&lt;p&gt;Running the benchmark for 10 trials, at 5 seconds each gives me an average hash rate of &lt;strong&gt;18.31MH/s&lt;/strong&gt; at the current difficulty. This is my baseline.&lt;/p&gt;&#10;&lt;h5 id="enabling-experimental-features"&gt;Enabling experimental features&lt;/h5&gt;&#10;&lt;p&gt;By default, the NVIDIA drivers do not let you change any Experimental features (manual control of things) out of the box. In order to enable these, we need to add an option to our &lt;code&gt;xorg.conf&lt;/code&gt; file. Before we make any changes here, you should back up your current config file if one exists. In my case this is &lt;code&gt;/etc/X11/xorg.conf&lt;/code&gt; but your location may vary.&lt;/p&gt;&#10;&lt;p&gt;Once you know where your config file is, we need to add NVIDIA&amp;rsquo;s &lt;strong&gt;Coolbits&lt;/strong&gt; option to the &lt;strong&gt;Devices&lt;/strong&gt; section in the config. Using 28 in my case enables all experimental features - Even if we dont use them all :)&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xorg" data-lang="xorg"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;Section&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;&amp;#34;Device&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Identifier&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Device0&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Driver&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;nvidia&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Option&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Coolbits&amp;#34; &amp;#34;28&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;VendorName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;NVIDIA Corporation&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;EndSection&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you&amp;rsquo;re using multiple GPUs, you need to add the &lt;strong&gt;Option&lt;/strong&gt; to each individual &lt;strong&gt;Device&lt;/strong&gt; section in your config.&lt;/p&gt;&#10;&lt;p&gt;A simple way to see if it worked is to (after a reboot) open &lt;code&gt;nvidia-settings&lt;/code&gt; and look at the &lt;strong&gt;Thermal Settings&lt;/strong&gt; tab; You should see fan control options now available:&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2017/07/nvidia-fan-control.png"&gt;&lt;img alt="" class="img-center" height="328" src="https://www.simonmott.co.uk/images/2017/07/nvidia-fan-control.png" width="473"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;h5 id="persistence-mode"&gt;Persistence Mode&lt;/h5&gt;&#10;&lt;p&gt;Before we do any actual tweaks, we should enable &lt;strong&gt;Persistence Mode&lt;/strong&gt; to ensure our changes stay active even after we close any applications that might be using our card.&lt;/p&gt;&#10;&lt;p&gt;The &lt;code&gt;nvidia-smi&lt;/code&gt; utility allows you to control multiple GPUs with its &lt;code&gt;-i&lt;/code&gt; option.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nvidia-smi -i &lt;span class="m"&gt;0&lt;/span&gt; -pm &lt;span class="m"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nvidia-smi -i &lt;span class="m"&gt;1&lt;/span&gt; -pm &lt;span class="m"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nvidia-smi -i &lt;span class="m"&gt;2&lt;/span&gt; -pm &lt;span class="m"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;etc&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So enabling Persistence Mode on my machine would be:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;simon@kirika:~$ sudo nvidia-smi -i 0 -pm 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Enabled persistence mode for GPU 0000:01:00.0.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;All done.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h5 id="power-limits"&gt;Power Limits&lt;/h5&gt;&#10;&lt;p&gt;One of the tweaks we have access to is the ability to change power limits for our card. This is also controlled via &lt;code&gt;nvidia-smi&lt;/code&gt; command line tool.&lt;/p&gt;&#10;&lt;p&gt;Lets look at what power limit options we have available:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;simon@kirika:~$ nvidia-smi -i 0 -q -d power&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;==============NVSMI LOG==============&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Timestamp : Mon Jul 3 18:11:28 2017&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Driver Version : 375.66&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Attached GPUs : 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;GPU 0000:01:00.0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Power Readings&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Power Management : Supported&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Power Draw : 12.90 W&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Power Limit : 160.00 W&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Default Power Limit : 160.00 W&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Enforced Power Limit : 160.00 W&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Min Power Limit : 100.00 W&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Max Power Limit : 180.00 W&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Power Samples&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Duration : 78.01 sec&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Number of Samples : 119&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Max : 61.22 W&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Min : 12.71 W&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Avg : 14.83 W&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On this initial query, I can see that the default power limit for my card is 160 watts and that the maximum I can set it to is 180 watts.&lt;/p&gt;&#10;&lt;p&gt;Lets set it to 180w&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;simon@kirika:~$ sudo nvidia-smi -i 0 -pl 180&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Power limit for GPU 0000:01:00.0 was set to 180.00 W from 160.00 W.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;All done.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;More power should mean better performance, Right? - Nope.&lt;/p&gt;&#10;&lt;h5 id="performance-states"&gt;Performance States&lt;/h5&gt;&#10;&lt;p&gt;I performed a benchmark at each power level my card supports, with a 5w increment between them.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2017/07/chart-default.png"&gt;&lt;img alt="" class="img-center" height="371" src="https://www.simonmott.co.uk/images/2017/07/chart-default.png" width="599"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;The graph above shows what I&amp;rsquo;d expect when we decrease our power limit below 160w; A steady decrease in hashes the lower the supplied power goes. At the top end of the scale though, I don&amp;rsquo;t actually gain any performance improvements what-so-ever.&lt;/p&gt;&#10;&lt;p&gt;After a bit of reading around on forums - This is because the mining application is providing a compute workload to the card, rather than something more graphical in nature. The default clock speeds for &amp;ldquo;Applications&amp;rdquo; appears lower than what the card is capable of and thus it gets capped into &lt;strong&gt;P2 Performance State&lt;/strong&gt;; Hence the flatline on the graph.&lt;/p&gt;&#10;&lt;p&gt;To view what our current Application Clock is set to, we can take a look using &lt;code&gt;nvidia-smi&lt;/code&gt; once again, and looking for &lt;strong&gt;Application Clocks&lt;/strong&gt; and &lt;strong&gt;Default Application Clocks&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;simon@kirika:~$ nvidia-smi -i 0 -q -d clock&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;==============NVSMI LOG==============&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Timestamp : Wed Jul 5 00:00:38 2017&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Driver Version : 375.66&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Attached GPUs : 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;GPU 0000:01:00.0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Clocks&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Graphics : 1240 MHz&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; SM : 1240 MHz&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Memory : 3004 MHz&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Video : 1141 MHz&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Applications Clocks&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Graphics : 1076 MHz&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Memory : 3505 MHz&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Default Applications Clocks&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Graphics : 1076 MHz&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Memory : 3505 MHz&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Max Clocks&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Graphics : 1418 MHz&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; SM : 1418 MHz&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Memory : 3505 MHz&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Video : 1304 MHz&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; SM Clock Samples&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Duration : 547.35 sec&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Number of Samples : 100&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Max : 1476 MHz&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Min : 1240 MHz&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Avg : 1422 MHz&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Memory Clock Samples&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Duration : 547.35 sec&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Number of Samples : 100&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Max : 3505 MHz&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Min : 3004 MHz&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Avg : 3491 MHz&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Clock Policy&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Auto Boost : N/A&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Auto Boost Default : N/A&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This output is also useful in that it shows what our current maximum clock speeds can be set to. It&amp;rsquo;s clear in the output above that our max clock differ from what Applications are permitted to use.&lt;/p&gt;&#10;&lt;p&gt;Armed with these values, I can proceed to change my &lt;strong&gt;Application Clocks&lt;/strong&gt; to allow the GPU to clock higher when performing compute workloads. This higher performance state is known as &lt;strong&gt;P0 Performance State&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;simon@kirika:~$ sudo nvidia-smi -i 0 -ac 3505,1418&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Applications clocks set to &amp;#34;(MEM 3505, SM 1418)&amp;#34; for GPU 0000:01:00.0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;All done.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Lets run our benchmark again:&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2017/07/chart-p0.png"&gt;&lt;img alt="" class="img-center" height="371" src="https://www.simonmott.co.uk/images/2017/07/chart-p0.png" width="599"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;You can just make out that the top-end of our graph is no longer a flatline which suggests we&amp;rsquo;re now using the full range of clock speeds available on the card. Albeit with little gain&amp;hellip; But, I&amp;rsquo;m sure I can do better!&lt;/p&gt;&#10;&lt;h5 id="overclocking"&gt;Overclocking&lt;/h5&gt;&#10;&lt;p&gt;The final stages of tweaking are whats known as overclocking. The values I&amp;rsquo;ve chosen here are very much specific to my hardware. You might be able to get a more stable overclock, or have to use lower values - It entirely depends on your own hardware.&lt;/p&gt;&#10;&lt;p&gt;In order to achieve this, I&amp;rsquo;ll be using &lt;code&gt;nvidia-settings&lt;/code&gt; which requires a working X server to be able to apply changes to our card. We tell &lt;code&gt;nvidia-settings&lt;/code&gt; which X server to attach to with the &lt;code&gt;-c :0&lt;/code&gt; option and in my examples, we&amp;rsquo;re using display &lt;code&gt;:0&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;We can also apply changes to multiple GPUs by changing the ID number in the command:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nvidia-settings -c :0 -a &lt;span class="o"&gt;[&lt;/span&gt;gpu:0&lt;span class="o"&gt;]&lt;/span&gt;/GPUGraphicsClockOffset&lt;span class="o"&gt;[&lt;/span&gt;3&lt;span class="o"&gt;]=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nvidia-settings -c :0 -a &lt;span class="o"&gt;[&lt;/span&gt;gpu:1&lt;span class="o"&gt;]&lt;/span&gt;/GPUGraphicsClockOffset&lt;span class="o"&gt;[&lt;/span&gt;3&lt;span class="o"&gt;]=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nvidia-settings -c :0 -a &lt;span class="o"&gt;[&lt;/span&gt;gpu:2&lt;span class="o"&gt;]&lt;/span&gt;/GPUGraphicsClockOffset&lt;span class="o"&gt;[&lt;/span&gt;3&lt;span class="o"&gt;]=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Figuring out how large an overclock your card supports will take a bit of trial, error and a lot of reboots - I started with 100MHz and increased slowly until the card became unstable/crashed. Once you know a stable number, increase it in smaller increments until you start having issues.&lt;/p&gt;&#10;&lt;p&gt;My card took a stable overclock at &lt;strong&gt;240MHz&lt;/strong&gt;. If I go as high as 250MHz, CUDA would sometimes fail to initialize, so make sure you test each value properly.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;simon@kirika:~$ nvidia-settings -c :0 -a [gpu:0]/GPUGraphicsClockOffset[3]=240&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Attribute &amp;#39;GPUGraphicsClockOffset&amp;#39; (kirika:0[gpu:0]) assigned value 240.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For the sake of being thorough, you can also apply an offset to Memory. The comments above still apply here with finding a stable value. In my case, an offset of &lt;strong&gt;1,100MHz&lt;/strong&gt; was stable, although this actually seemed to result in a frequency change of only 550MHz (which is half of 1,100). In my testing however, a Memory overclock had negligible impact on my results, but your mileage may vary so its still worth giving it a shot&amp;hellip;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nvidia-settings -c :0 -a &lt;span class="o"&gt;[&lt;/span&gt;gpu:0&lt;span class="o"&gt;]&lt;/span&gt;/GPUMemoryTransferRateOffset&lt;span class="o"&gt;[&lt;/span&gt;3&lt;span class="o"&gt;]=&lt;/span&gt;&lt;span class="m"&gt;1100&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once you know a good value for both of these, we can now look at adjusting the &lt;strong&gt;Application Clocks&lt;/strong&gt; mentioned earlier to accommodate the new clock speeds for compute workloads.&lt;/p&gt;&#10;&lt;p&gt;Check the max values using &lt;code&gt;nvidia-smi -i 0 -q -d clock&lt;/code&gt; like before, and set the new clocks accordingly.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;simon@kirika:~$ sudo nvidia-smi -ac 4055,1658&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Applications clocks set to &amp;#34;(MEM 4055, SM 1658)&amp;#34; for GPU 0000:01:00.0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;All done&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With my card overclocked and stable, I did another round of benchmarks and you can clearly see the improvement compared to default settings. I mentioned previously that the memory overclock had a negligible impact on my results so I&amp;rsquo;ve omitted those from the graph.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2017/07/chart-overclock.png"&gt;&lt;img alt="" class="img-center" height="371" src="https://www.simonmott.co.uk/images/2017/07/chart-overclock.png" width="599"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;h5 id="conclusion"&gt;Conclusion&lt;/h5&gt;&#10;&lt;p&gt;I&amp;rsquo;ve managed to improve my hash rate by &lt;strong&gt;18.4%&lt;/strong&gt; - from &lt;strong&gt;18.31MH/s&lt;/strong&gt; to &lt;strong&gt;21.68MH/s&lt;/strong&gt;, by overclocking my GPU and increasing the power limit available to the card. Power consumption of the card has increased by approximately &lt;strong&gt;12.5%&lt;/strong&gt; when at 180 watts (instead of the default 160w), but it&amp;rsquo;s still worth me running at the higher power threshold.&lt;/p&gt;&#10;&lt;p&gt;If however, I wanted to keep power usage at similar (or lower) levels to what we started with, I can limit to 160w and still achieve &lt;strong&gt;21.06MH/s&lt;/strong&gt; with the overclock, which is still a &lt;strong&gt;15%&lt;/strong&gt; improvement over default settings! This also has the added advantage of keeping GPU temperatures under control.&lt;/p&gt;&#10;&lt;p&gt;For convenience, here are all the changes I&amp;rsquo;ve made in order to get this improvement (which includes some fan control options to keep on top of cooling):&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; Edit X Config to add coolbits&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; Reboot&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; Make sure X is running&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; Enable persistence mode&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;sudo nvidia-smi -i 0 -pm 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; Increase our Power Limit from &lt;span class="m"&gt;160&lt;/span&gt; up to &lt;span class="m"&gt;180&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;sudo nvidia-smi -i 0 -pl 180&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; Ensure fan speed is controllable and &lt;span class="nb"&gt;set&lt;/span&gt; it to 55%&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;You can use whatever value you like &lt;span class="k"&gt;for&lt;/span&gt; fan speed&lt;span class="o"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;nvidia-settings -c :0 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;-a [gpu:0]/GPUFanControlState=1 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;-a [fan:0]/GPUTargetFanSpeed=55 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; Overclock GPU/RAM&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;nvidia-settings -c :0 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;-a [gpu:0]/GPUGraphicsClockOffset[3]=240 \&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;-a [gpu:0]/GPUMemoryTransferRateOffset[3]=1100&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; Apply new clocks&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;sudo nvidia-smi -ac 4055,1658&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;nvidia-settings&lt;/code&gt; commands could be merged into one, but I kept them separate for clarity.&lt;/p&gt;</description></item><item><title>Shoehorning Proxmox into mdadm RAID1</title><link>https://www.simonmott.co.uk/2017/03/shoehorning-proxmox-into-mdadm-raid1/</link><pubDate>Sun, 12 Mar 2017 01:04:30 +0000</pubDate><guid>https://www.simonmott.co.uk/2017/03/shoehorning-proxmox-into-mdadm-raid1/</guid><description>&lt;p&gt;My home server has always been somewhat of a Frankenstein&amp;rsquo;s Monster when it comes to hardware. Until about 2 years ago, it consisted of a large JBOD array of several different drive sizes with no kind of redundancy what-so-ever - for both OS and Data disks. That all changed though when I decided to invest in some 3TB disks and build a &amp;ldquo;proper&amp;rdquo; RAID array for my data; Which coincidentally was around the same time my data storage array lost a drive resulting in about 800GB of data-loss - I was unable to source a decent hardware RAID card at the time so I went with Software RAID (mdadm) instead.&lt;/p&gt;&#10;&lt;p&gt;The chassis which houses my home server happens to be an old &lt;a href="https://www.xcase.co.uk/"&gt;X-Case&lt;/a&gt; model that has 10 internal bays, a couple of 5.25&amp;quot; for Optical drives and a 5.25&amp;quot; to 3.5&amp;quot; caddy that seems to be designed for a floppy drive (it has a cut-out at the front for access). I use the floppy slot to house my OS disk and the rest are for my data disks which are all in RAID6 for redundancy. This gives me a total of 11 hard drives in this chassis in its default configuration.&lt;/p&gt;&#10;&lt;p&gt;When I rebuilt my server to make use of Proxmox, I put in a known-working drive as the OS drive; It was an old drive at the time but didn&amp;rsquo;t have much in the way of power on hours so I figured it&amp;rsquo;d last me a while. Here I am a few years later and the drive is still going, but SMART data is showing some figures that&amp;rsquo;re making me worried it&amp;rsquo;s going to start having problems soon so I set about replacing it.&lt;/p&gt;&#10;&lt;h3 id="step-1---replace-the-problemdrive"&gt;Step 1 - Replace the problem drive&lt;/h3&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2017/03/IMG_20170301_170544.jpg"&gt;&lt;img alt="" class="img-right" height="225" src="https://www.simonmott.co.uk/images/2017/03/IMG_20170301_170544-300x225.jpg" width="300"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;Sure, I could have just bought a new drive and re-installed my server from scratch, but frankly I couldn&amp;rsquo;t be bothered with all the niggly applications and configurations I&amp;rsquo;d need to get right to make it all work nicely again.&lt;/p&gt;&#10;&lt;p&gt;Besides, &lt;em&gt;where&amp;rsquo;s the fun in that?&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;I bought a 3.5&amp;quot; to Dual 2.5&amp;quot; adaptor off eBay (In-Win 3RAMZF078700) which, as you might guess, should nicely house a couple of 2.5&amp;quot; drives where my old 3.5&amp;quot; OS disk used to live. Having already made use of mdadm on this system, and now having two drives, I should be able to use them in RAID1 for my OS disk.&lt;/p&gt;&#10;&lt;p&gt;I chose to get two HGST Travelstar 7K1000 drives because a friend uses &lt;em&gt;&lt;strong&gt;a lot&lt;/strong&gt;&lt;/em&gt; of them and has (so far) had no problems with them. They also spin at 7200RPM so should get reasonable performance in RAID1 given I&amp;rsquo;m limited to essentially a single drive&amp;rsquo;s performance over more conventional 2.5&amp;quot; drives which operate at 5400RPM.&lt;/p&gt;&#10;&lt;p&gt;There were a couple of things I needed to consider before embarking on this project though - most of which were potential physical constraints inside the chassis itself.&lt;/p&gt;&#10;&lt;h5 id="do-i-have-enough-sata-data-ports"&gt;&lt;strong&gt;Do I have enough SATA data ports?&lt;/strong&gt;&lt;/h5&gt;&#10;&lt;p&gt;My SuperMicro X8DTL-3F motherboard has 6 SATA ports and 8 SAS ports. I learned the hard way that you can only boot from the SATA ports, and that the on-board LSI SAS controller does not support drives larger than 2TB. For my configuration this leaves me with just the 6 on board SATA ports so I invested in an LSI 9211-8i HBA (It&amp;rsquo;s actually a cross-flashed Dell H200A - &lt;a href="http://blog.michael.kuron-germany.de/2014/11/crossflashing-dell-perc-h200-to-lsi-9211-8i/comment-page-1/"&gt;http://blog.michael.kuron-germany.de/2014/11/crossflashing-dell-perc-h200-to-lsi-9211-8i/comment-page-1/&lt;/a&gt;)&lt;/p&gt;&#10;&lt;p&gt;The 9211-8i in theory supports 8 drives - combine the 6 SATA ports on the motherboard with the 8 on the HBA and I have theoretically got 14 ports available to use with my 2 boot drives (RAID1) and 10 data drives (RAID6)&lt;/p&gt;&#10;&lt;p&gt;I can only fit 11 disks in the chassis (12 if you count the 2.5&amp;quot; disks instead) so I should have enough.&lt;/p&gt;&#10;&lt;h5 id="do-i-have-enough-sata-power-connectors"&gt;&lt;strong&gt;Do I have enough SATA power connectors?&lt;/strong&gt;&lt;/h5&gt;&#10;&lt;p&gt;My PSU is an EVGA 650 GQ which has 9 native SATA power ports and a further 3 molex connectors to which I can attach some 2xSATA splitters. I use one of the molex connectors for cooling though so I only get 4 SATA connectors from molex and 9 from native. This should be enough for my purposes.&lt;/p&gt;&#10;&lt;h5 id="will-the-dual-25-bracket-even-fit-where-a-35-disk-would-normally-go"&gt;&lt;strong&gt;Will the dual 2.5&amp;quot; bracket even fit where a 3.5&amp;quot; disk would normally go?&lt;/strong&gt;&lt;/h5&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2017/03/IMG_20170301_171623.jpg"&gt;&lt;img class="img-left" height="225" src="https://www.simonmott.co.uk/images/2017/03/IMG_20170301_171623-300x225.jpg" width="300"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;The HGST Travelstar disks come in at 9.5mm in height. The disk that sits on the bottom of the bracket has enough clearance for a 12mm drive, but the top one was a potential problem as it could sit on the bracket taller than a standard 3.5&amp;quot; drive.&lt;/p&gt;&#10;&lt;p&gt;I&amp;rsquo;d fitted the 2.5&amp;quot; drives and stood the bracket next to two different 3.5&amp;quot; models and as you can see, its about the same height. It is slightly taller than the drive on the right (WD800JD) But is about the same height as the one on the left (WD10EADS)&lt;/p&gt;&#10;&lt;p&gt;I do have open-air above my drives in this chassis so height restrictions are not a problem for me; However if you wanted to use this bracket in a more conventional 3.5&amp;quot; bay, you should not have any issues using two 9.5mm drives.&lt;/p&gt;&#10;&lt;p&gt;The placement of these drives in the &amp;ldquo;floppy&amp;rdquo; bay unfortunately means there is no airflow from case fans so I did have to consider the gap between the drives to allow for cooling - which as you can see should be ample clearance.&lt;/p&gt;&#10;&lt;h3 id="step-2---cloning-the-original"&gt;Step 2 - Cloning the original&lt;/h3&gt;&#10;&lt;p&gt;As my plan was to go from a single 3.5&amp;quot; drive to two 2.5&amp;quot; drives, that does beg the question as to how I get the data onto the smaller drives. I could have skipped this step and jumped right into Step 4 to assemble the RAID array using both the old and one of the new drives, to later replace the old drive with the remaining new one.&lt;/p&gt;&#10;&lt;p&gt;Instead, I opted to use a tool called &lt;a href="http://clonezilla.org/"&gt;CloneZilla&lt;/a&gt; which will clone the original drive onto the new one (although you could have just used &lt;code&gt;dd&lt;/code&gt;) whilst leaving the original untouched should I need to revert (or re-clone) it at a later date. This was a personal choice but I like the idea of having the safety net should anything go wrong further down the line then, at least I &lt;em&gt;could&lt;/em&gt;start again if needed.&lt;/p&gt;&#10;&lt;p&gt;First we connect one of the new HGST drives up and temporarily plug in the old OS drive so that we can clone it. Next I booted Clonezilla and followed the on-screen instructions clone the drives.&lt;/p&gt;&#10;&lt;p&gt;You might need to zero the destination disk first so that everything clones over nicely.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;It&amp;rsquo;s very important that you make sure your destination drive is correct because CloneZilla will overwite anything thats already there&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2017/03/in-progress2.jpg"&gt;&lt;img alt="" class="img-center" height="600" src="https://www.simonmott.co.uk/images/2017/03/in-progress2.jpg" width="800"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;Once the clone is complete, you should be able to disconnect the old drive and boot from the new one. If all goes well then your system should look the same from the OS&amp;rsquo;s point of view other than the fact you&amp;rsquo;re now on a larger disk (In my case anyway, I went from 160GB to 1TB).&lt;/p&gt;&#10;&lt;h3 id="step-3---fixing-the-partitions-on-the-larger-disk"&gt;Step 3 - Fixing the partitions on the larger disk&lt;/h3&gt;&#10;&lt;p&gt;Before we delve too deep into this, I realize my partitions are not standard for Proxmox these days in that I have a /boot partition outside of the main root partition (for me /dev/sdd2 is /boot). Nonetheless this should not affect the overall process if your partitions are different - you just need to skip the parts that&amp;rsquo;re specific to me and adjust according to your configuration.&lt;/p&gt;&#10;&lt;p&gt;Naturally your mileage may vary depending on how your system is set up. Don&amp;rsquo;t just blindly paste commands into a terminal as you could cause irreversible data-loss :) - Make sure you understand what you&amp;rsquo;re doing!&lt;/p&gt;&#10;&lt;p&gt;Now that we&amp;rsquo;ve a cloned the old OS disk onto one of the new (larger) disks, I thought now would be a good time to fix the primary data partition (where the &amp;ldquo;pve&amp;rdquo; LV lives) so that it takes up the entirety of the disk. I went from a 160GB to 1TB drive so to do this I simply loaded &lt;code&gt;parted&lt;/code&gt; and took a look at the partitions whilst telling it to display sector count instead of the default - It showed me a warning about the GPT size being wrong and offered to correct it for me.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# parted /dev/sdd&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;GNU Parted 3.2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Using /dev/sdd&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Welcome to GNU Parted! Type &amp;#39;help&amp;#39; to view a list of commands.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;(parted) unit s&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;(parted) print free&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Warning: Not all of the space available to /dev/sdd appears to be used, you can fix the GPT&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;to use all of the space (an extra 1640943360 blocks) or continue with the current setting?&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Fix/Ignore? Fix&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Model: ATA HGST HTS721010A9 (scsi)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Disk /dev/sdd: 1953525168s&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Sector size (logical/physical): 512B/4096B&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Partition Table: gpt&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Disk Flags:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Number Start End Size File system Name Flags&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 34s 2047s 2014s Free Space&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 1 2048s 4095s 2048s primary bios_grub&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 2 4096s 1048575s 1044480s ext3 primary boot, esp&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 3 1048576s 312580095s 311531520s primary lvm&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 312580096s 1953525134s 1640945039s Free Space&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here we can see the current starting sector for our last partition (partition 3, aka /dev/sdd3) is &lt;strong&gt;1048576&lt;/strong&gt; and the last usable sector of free space is &lt;strong&gt;1953525134&lt;/strong&gt;. We should simply be able to remove the partition table (It wont remove data) and then re-create it with a larger size. As long as the starting position is the same then everything should line-up.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;parted&lt;span class="o"&gt;)&lt;/span&gt; rm &lt;span class="m"&gt;3&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Error: Partition&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; on /dev/sdd have been written, but we have been unable to inform the&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kernel of the change, probably because it/they are in use. As a result, the old partition&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;will remain in use. You should reboot now before making&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;further changes.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Ignore/Cancel? i&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;parted&lt;span class="o"&gt;)&lt;/span&gt; mkpart primary &lt;span class="m"&gt;1048576&lt;/span&gt; &lt;span class="m"&gt;1953525134&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;parted&lt;span class="o"&gt;)&lt;/span&gt; toggle &lt;span class="m"&gt;3&lt;/span&gt; lvm&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;parted&lt;span class="o"&gt;)&lt;/span&gt; print&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Model: ATA HGST HTS721010A9 &lt;span class="o"&gt;(&lt;/span&gt;scsi&lt;span class="o"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Disk /dev/sdd: 1953525168s&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Sector size &lt;span class="o"&gt;(&lt;/span&gt;logical/physical&lt;span class="o"&gt;)&lt;/span&gt;: 512B/4096B&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Partition Table: gpt&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Disk Flags:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Number Start End Size File system Name Flags&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;1&lt;/span&gt; 2048s 4095s 2048s primary bios_grub&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;2&lt;/span&gt; 4096s 1048575s 1044480s ext3 primary boot, esp&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;3&lt;/span&gt; 1048576s 1953525134s 1952476559s primary lvm&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;(&lt;/span&gt;parted&lt;span class="o"&gt;)&lt;/span&gt; quit&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Information: You may need to update /etc/fstab.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally we need to make sure that LVM is aware of the new disk size lest we forget about it later on&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# pvdisplay /dev/sdd3&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; --- Physical volume ---&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PV Name /dev/sdd3&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; VG Name pve&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PV Size 148.55 GiB / not usable 3.00 MiB&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Allocatable yes&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PE Size 4.00 MiB&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Total PE 38028&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Free PE 4095&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Allocated PE 33933&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PV UUID 6p74nl-SxZp-4xu7-j3lH-ACsg-Hs9I-5rNwpq&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# pvresize /dev/sdd3&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Physical volume &amp;#34;/dev/sdd3&amp;#34; changed&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 1 physical volume(s) resized / 0 physical volume(s) not resized&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# pvdisplay /dev/sdd3&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; --- Physical volume ---&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PV Name /dev/sdd3&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; VG Name pve&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PV Size 931.01 GiB / not usable 312.50 KiB&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Allocatable yes&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PE Size 4.00 MiB&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Total PE 238339&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Free PE 204406&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Allocated PE 33933&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PV UUID 6p74nl-SxZp-4xu7-j3lH-ACsg-Hs9I-5rNwpq&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you didn&amp;rsquo;t want to implement RAID1 then this is where you&amp;rsquo;d stop - We&amp;rsquo;ve moved our OS to a new disk without reinstalling.&lt;/p&gt;&#10;&lt;p&gt;I however do want to implement RAID1 so in Step 4 I&amp;rsquo;ll walk through how to prepare the second RAID member and begin the process of moving towards having a complete array.&lt;/p&gt;&#10;&lt;h3 id="step-4---preparing-for-raid"&gt;Step 4 - Preparing for RAID&lt;/h3&gt;&#10;&lt;p&gt;The purpose of this article is to document how I implemented software RAID1 on a live system without having to reinstall. In the previous steps, I took a little detour in that I cloned the original disk onto one of the new replacement disks. Primarily this was to preserve the original data should anything not go according to plan. The following steps are where you&amp;rsquo;d start if you wanted to skip the cloning process and work on the source disk without a &amp;ldquo;spare&amp;rdquo; copy of your data.&lt;/p&gt;&#10;&lt;p&gt;It&amp;rsquo;s important that you identify which companion disk you intend to use for your array. A useful tool to use here would be &lt;code&gt;smartctl&lt;/code&gt;. With this tool you can query each disk until you find which ones you want to work with (Especially useful if you have a lot of disks).&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# smartctl -i /dev/sdd&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;smartctl 6.6 2016-05-31 r4324 [x86_64-linux-4.4.35-2-pve] (local build)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Copyright (C) 2002-16, Bruce Allen, Christian Franke, www.smartmontools.org&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;=== START OF INFORMATION SECTION ===&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Model Family: HGST Travelstar 7K1000&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Device Model: HGST HTS721010A9E630&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Serial Number: JR1000********&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;LU WWN Device Id: 5 000cca 8c8d62953&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Firmware Version: JB0OA3U0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;User Capacity: 1,000,204,886,016 bytes [1.00 TB]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Sector Sizes: 512 bytes logical, 4096 bytes physical&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Rotation Rate: 7200 rpm&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Form Factor: 2.5 inches&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Device is: In smartctl database [for details use: -P show]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;ATA Version is: ATA8-ACS T13/1699-D revision 6&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;SATA Version is: SATA 3.0, 6.0 Gb/s (current: 3.0 Gb/s)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Local Time is: Mon Mar 6 21:16:45 2017 GMT&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;SMART support is: Available - device has SMART capability.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;SMART support is: Enabled&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In my case, &lt;code&gt;/dev/sdd&lt;/code&gt; is the non-RAID disk which currently houses my OS and &lt;code&gt;/dev/sde&lt;/code&gt; is the blank disk I want to initialize my array onto. Firstly we need to copy the current partition table from &lt;code&gt;/dev/sdd&lt;/code&gt; to &lt;code&gt;/dev/sde&lt;/code&gt;. As the partition table is GPT, we should use &lt;code&gt;sgdisk&lt;/code&gt; to do this.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# sgdisk -R=/dev/sde /dev/sdd&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;The operation has completed successfully.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once this command has completed, we should now change the type code for &lt;code&gt;/dev/sde2&lt;/code&gt; and &lt;code&gt;/dev/sde3&lt;/code&gt; to reflect that these partitions are members of software RAID. You can do this with any partition tool that supports GPT, but in my case I&amp;rsquo;ll use &lt;code&gt;sgdisk&lt;/code&gt; to change the types.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# sgdisk -t 2:fd00 /dev/sde&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;The operation has completed successfully.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# sgdisk -t 3:fd00 /dev/sde&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;The operation has completed successfully.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This should nicely result in &lt;code&gt;/dev/sde&lt;/code&gt; having the same partition structure as &lt;code&gt;/dev/sdd&lt;/code&gt; (but with both partition types as Linux RAID)&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# fdisk -l /dev/sde&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Disk /dev/sde: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Units: sectors of 1 * 512 = 512 bytes&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Sector size (logical/physical): 512 bytes / 4096 bytes&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;I/O size (minimum/optimal): 4096 bytes / 4096 bytes&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Disklabel type: gpt&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Disk identifier: A4EF094E-5546-4DC1-A262-2B08B9C586B1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Device Start End Sectors Size Type&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;/dev/sde1 2048 4095 2048 1M BIOS boot&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;/dev/sde2 4096 1048575 1044480 510M Linux RAID&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;/dev/sde3 1048576 1953525134 1952476559 931G Linux RAID&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="step-5---initialize-raid"&gt;Step 5 - Initialize RAID&lt;/h3&gt;&#10;&lt;p&gt;We&amp;rsquo;re now at the stage where both our disks should be nearly identically partitioned and we can actually start creating our arrays. We&amp;rsquo;ll first do this in a degraded state which will allow us to move data around.&lt;/p&gt;&#10;&lt;p&gt;In my case &lt;code&gt;/dev/sdd2&lt;/code&gt; is &lt;code&gt;/boot&lt;/code&gt; and &lt;code&gt;/dev/sdd3&lt;/code&gt; houses my LVM data (ultimately containing &lt;code&gt;/&lt;/code&gt; and swap).&lt;/p&gt;&#10;&lt;p&gt;I already have &lt;code&gt;/dev/md0&lt;/code&gt; as my primary data storage RAID, so &lt;code&gt;/dev/md1&lt;/code&gt; will be for &lt;code&gt;/boot&lt;/code&gt; and &lt;code&gt;/dev/md2&lt;/code&gt; for everything else.&lt;/p&gt;&#10;&lt;p&gt;Lets start by creating both mdadm devices, but using the currently empty disk (&lt;code&gt;/dev/sde&lt;/code&gt;) - I chose to ignore the notice displayed as my version of grub has support for mdadm out of the box.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# mdadm --create /dev/md1 --level=1 --raid-disks=2 missing /dev/sde2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;mdadm: Note: this array has metadata at the start and&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; may not be suitable as a boot device. If you plan to&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; store &amp;#39;/boot&amp;#39; on this device please ensure that&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; your boot-loader understands md/v1.x metadata, or use&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; --metadata=0.90&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Continue creating array? y&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;mdadm: Defaulting to version 1.2 metadata&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;mdadm: array /dev/md1 started.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# mdadm --create /dev/md2 --level=1 --raid-disks=2 missing /dev/sde3&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;mdadm: Note: this array has metadata at the start and&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; may not be suitable as a boot device. If you plan to&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; store &amp;#39;/boot&amp;#39; on this device please ensure that&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; your boot-loader understands md/v1.x metadata, or use&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; --metadata=0.90&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Continue creating array? y&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;mdadm: Defaulting to version 1.2 metadata&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;mdadm: array /dev/md2 started.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next we need to ensure that the new arrays are started at boot. Typically this is done by adding them to &lt;code&gt;mdadm.conf&lt;/code&gt;. The location of this file may vary depending on your OS but on debian its in &lt;code&gt;/etc/mdadm&lt;/code&gt;. I simply take a look at the 2 arrays and add them to the end of the config file&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# mdadm --detail --scan /dev/md{1,2} &amp;gt;&amp;gt; /etc/mdadm/mdadm.conf&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We should now be in a position where you have &lt;code&gt;/dev/md1&lt;/code&gt; and &lt;code&gt;/dev/md2&lt;/code&gt; and they should both start automatically on-boot. Next we&amp;rsquo;ll look at making use of them!&lt;/p&gt;&#10;&lt;h3 id="step-6---configure-grub-and-move-boot"&gt;Step 6 - Configure grub and move /boot&lt;/h3&gt;&#10;&lt;p&gt;We should now have our degraded arrays which we can now immediately start to use. I&amp;rsquo;ll begin by creating a new file system on &lt;code&gt;/dev/md1&lt;/code&gt; for use with &lt;code&gt;/boot&lt;/code&gt; and then move data to it. Obviously if your &lt;code&gt;/boot&lt;/code&gt; is not a separate partition but is included in your root partition then you don&amp;rsquo;t need to worry about this part.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# mkfs.ext4 /dev/md1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;mke2fs 1.42.12 (29-Aug-2014)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Creating filesystem with 521920 1k blocks and 130560 inodes&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Filesystem UUID: 37e651bc-ffc1-41d8-a9c7-99ca9273b829&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Superblock backups stored on blocks:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Allocating group tables: done&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Writing inode tables: done&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Creating journal (8192 blocks): done&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Writing superblocks and filesystem accounting information: done&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# mkdir /mnt/tmp&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# mount /dev/md1 /mnt/tmp/&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# cp -ax /boot/* /mnt/tmp/&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# umount /mnt/tmp&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# rmdir /mnt/tmp&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once all this is done, lets edit &lt;code&gt;/etc/fstab&lt;/code&gt; to tell our system to mount &lt;code&gt;/boot&lt;/code&gt; from the new array. Your &lt;code&gt;fstab&lt;/code&gt; will be different to mine, but find where &lt;code&gt;/boot&lt;/code&gt; is mounted and change it to &lt;code&gt;/dev/md1&lt;/code&gt; (I kept my original UUID around just in-case)&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# cat /etc/fstab&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; &amp;lt;file system&amp;gt; &amp;lt;mount point&amp;gt; &amp;lt;type&amp;gt; &amp;lt;options&amp;gt; &amp;lt;dump&amp;gt; &amp;lt;pass&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;f6f3e14e-a2fe-468f-80ee-8824dab51e36 /boot ext3 defaults &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;/dev/md1 /boot ext4 defaults 0 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;/dev/pve/root / ext4 errors=remount-ro 0 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;/dev/data/wdred /mnt/storage ext4 defaults,barrier=0 0 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;/dev/pve/swap none swap sw 0 0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;proc /proc proc defaults 0 0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s critical you make sure there are no errors here, getting this wrong could result in an un-bootable system!&lt;/p&gt;&#10;&lt;p&gt;At this point I chose to reboot my system to ensure it&amp;rsquo;s booting correctly and running &lt;code&gt;/boot&lt;/code&gt; from the correct place&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# mount | grep boot&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;/dev/md1 on /boot type ext4 (rw,relatime,stripe=4,data=ordered)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;mdadm needs to be told to start all arrays on-boot (As we intend to host &lt;code&gt;/&lt;/code&gt; in an array) so edit &lt;code&gt;/etc/default/mdadm&lt;/code&gt; and change &lt;code&gt;INITRDSTART&lt;/code&gt; to &amp;lsquo;all&amp;rsquo; (Mine was set to &amp;rsquo;none&amp;rsquo; by default)&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# grep ^INITRDSTART /etc/default/mdadm&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;INITRDSTART=&amp;#39;all&amp;#39;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Followed by some grub and initrd changes&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# echo &amp;#39;GRUB_DISABLE_LINUX_UUID=true&amp;#39; &amp;gt;&amp;gt; /etc/default/grub&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# echo raid1 &amp;gt;&amp;gt; /etc/modules&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# echo raid1 &amp;gt;&amp;gt; /etc/initramfs-tools/modules&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And then make sure grub (boot loader) exists on the 2 new RAID disks followed by a grub update and RAM disk update&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# grub-install /dev/sdd&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Installing for i386-pc platform.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Installation finished. No error reported.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# grub-install /dev/sde&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Installing for i386-pc platform.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Installation finished. No error reported.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# update-grub&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Generating grub configuration file ...&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Found linux image: /boot/vmlinuz-4.4.35-2-pve&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Found initrd image: /boot/initrd.img-4.4.35-2-pve&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Found memtest86+ image: /memtest86+.bin&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Found memtest86+ multiboot image: /memtest86+_multiboot.bin&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;done&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# update-initramfs -u&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;update-initramfs: Generating /boot/initrd.img-4.4.35-2-pve&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we&amp;rsquo;re in the final stretch!&lt;/p&gt;&#10;&lt;h3 id="step-7---assembling-the-arrays"&gt;Step 7 - Assembling the arrays&lt;/h3&gt;&#10;&lt;p&gt;If everything has gone to plan, our system should now be running &lt;code&gt;/boot&lt;/code&gt; from &lt;code&gt;/dev/md1&lt;/code&gt; which means the old &lt;code&gt;/boot&lt;/code&gt; partition on &lt;code&gt;/dev/sdd2&lt;/code&gt; is no longer needed. We should set its type to &lt;strong&gt;Linux RAID&lt;/strong&gt; and add it to our array&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# sgdisk -t 2:fd00 /dev/sdd&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Warning: The kernel is still using the old partition table.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;The new table will be used at the next reboot.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;The operation has completed successfully.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# mdadm --add /dev/md1 /dev/sdd2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;mdadm: added /dev/sdd2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# cat /proc/mdstat&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Personalities : [raid6] [raid5] [raid4] [raid1]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;md2 : active raid1 sde3[1]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 976107200 blocks super 1.2 [2/1] [_U]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; bitmap: 1/8 pages [4KB], 65536KB chunk&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;md1 : active raid1 sdd2[2] sde2[1]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 521920 blocks super 1.2 [2/1] [_U]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; [===========&amp;gt;.........] recovery = 55.2% (288896/521920) finish=0.0min speed=144448K/sec&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;md0 : active raid6 sdh1[0] sdc1[6] sda1[7] sdg1[5] sdf1[4] sdi1[2] sdb1[1]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 14650670080 blocks super 1.2 level 6, 512k chunk, algorithm 2 [7/7] [UUUUUUU]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;unused devices: &amp;lt;none&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And viola, we now have (when its recovered) a working software RAID for &lt;code&gt;/boot&lt;/code&gt;&lt;/p&gt;&#10;&lt;p&gt;Next we&amp;rsquo;ll add &lt;code&gt;/dev/md2&lt;/code&gt; to LVM and make the space available to our &lt;code&gt;pve&lt;/code&gt; volume group so that we can simply &lt;code&gt;pvmove&lt;/code&gt; the remaining data to our RAID array.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# pvcreate /dev/md2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Physical volume &amp;#34;/dev/md2&amp;#34; successfully created&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# pvdisplay&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; --- Physical volume ---&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PV Name /dev/sdd3&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; VG Name pve&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PV Size 931.01 GiB / not usable 312.50 KiB&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Allocatable yes&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PE Size 4.00 MiB&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Total PE 238339&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Free PE 204406&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Allocated PE 33933&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PV UUID 6p74nl-SxZp-4xu7-j3lH-ACsg-Hs9I-5rNwpq&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; &amp;#34;/dev/md2&amp;#34; is a new physical volume of &amp;#34;930.89 GiB&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; --- NEW Physical volume ---&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PV Name /dev/md2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; VG Name&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PV Size 930.89 GiB&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Allocatable NO&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PE Size 0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Total PE 0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Free PE 0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Allocated PE 0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PV UUID PzVPqV-Rn1V-ASA5-Q4Ni-cXhS-LUCu-QZUTiC&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# vgextend pve /dev/md2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Volume group &amp;#34;pve&amp;#34; successfully extended&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You might notice that &lt;code&gt;/dev/sdd3&lt;/code&gt; and &lt;code&gt;/dev/md2&lt;/code&gt; aren&amp;rsquo;t the same size according to LVM - I suspect this is because of RAID metadata overheads. Thankfully because I am moving from smaller to larger disks, I have enough &lt;strong&gt;Free PE&lt;/strong&gt; that I can move without issue. If however you have no Free PE&amp;rsquo;s and your disks are not equal in size like shown above, you might need to shrink one of your Logical Volumes and fix the file system later.&lt;/p&gt;&#10;&lt;p&gt;I&amp;rsquo;m happy that I can proceed here so I move the contents of &lt;code&gt;/dev/sdd3&lt;/code&gt; to &lt;code&gt;/dev/md2&lt;/code&gt; within LVM&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# pvmove /dev/sdd3 /dev/md2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; /dev/sdd3: Moved: 100.0%&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The pvmove itself will take a while depending on how much data there is to move (&lt;strong&gt;Allocated PE&lt;/strong&gt;) but once that is done, all we have left to do is remove the old disk from LVM&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# vgreduce pve /dev/sdd3&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Removed &amp;#34;/dev/sdd3&amp;#34; from volume group &amp;#34;pve&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# pvremove /dev/sdd3&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Labels on physical volume &amp;#34;/dev/sdd3&amp;#34; successfully wiped&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And then to add the old partition to our corresponding mdadm array&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# mdadm --add /dev/md2 /dev/sdd3&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;mdadm: added /dev/sdd3&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# cat /proc/mdstat&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Personalities : [raid1] [raid6] [raid5] [raid4]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;md2 : active raid1 sdd3[2] sde3[1]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 976107200 blocks super 1.2 [2/1] [_U]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; [&amp;gt;....................] recovery = 1.3% (12725760/976107200) finish=133.5min speed=120174K/sec&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; bitmap: 2/8 pages [8KB], 65536KB chunk&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;md1 : active raid1 sdd2[2] sde2[1]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 521920 blocks super 1.2 [2/2] [UU]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;md0 : active raid6 sdh1[0] sdb1[6] sda1[7] sdg1[5] sdf1[4] sdi1[2] sdc1[1]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 14650670080 blocks super 1.2 level 6, 512k chunk, algorithm 2 [7/7] [UUUUUUU]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;unused devices: &amp;lt;none&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A final reboot to make sure everything comes up correctly and if so, its just a matter of waiting for RAID recovery to complete.&lt;/p&gt;</description></item><item><title>Routed Subnets, rp_filter and arp_ignore</title><link>https://www.simonmott.co.uk/2016/09/routed-subnet-rp_filter-arp_ignore/</link><pubDate>Fri, 23 Sep 2016 20:40:25 +0000</pubDate><guid>https://www.simonmott.co.uk/2016/09/routed-subnet-rp_filter-arp_ignore/</guid><description>&lt;p&gt;Over the past couple of years, I&amp;rsquo;ve been quite accustomed to my ISP providing me with an IP block (typically a /29) instead of just a single static IP, but recently I&amp;rsquo;ve switched to &lt;a href="https://www.hyperoptic.com/"&gt;Hyperoptic&lt;/a&gt; for their &lt;a href="https://en.wikipedia.org/wiki/Fiber_to_the_x#Fiber_to_the_premises"&gt;FTTP&lt;/a&gt; offering (Because, Gigabit!). Unfortunately, they seem to only offer single IPs for residential service and require you to be on their business package which costs £££ if you want more IPs.&lt;/p&gt;&#10;&lt;p&gt;To get around this I decided to try to tunnel some IPs home - My setup is rather complex but I&amp;rsquo;m going to skip over the specifics for most of it and focus on the issue I was facing - lets ignore how the IPs route around the rest of my network and ultimately end up at the router for now and just look at the rather simplified view below.&lt;/p&gt;&#10;&lt;h3 id="the-problem"&gt;The Problem&lt;/h3&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2016/09/rp_filter.png"&gt;&lt;img alt="rp_filter" class="img-right" height="419" src="https://www.simonmott.co.uk/images/2016/09/rp_filter.png" width="398"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;The image shows that I essentially have a router which has two NICs, one connected to the public internet, and one connected to a switch within my network. The second NIC has two IPs assigned to it as follows:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;10.0.2.51/24&lt;/strong&gt; which is my internal private subnet&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;172.26.0.9/29&lt;/strong&gt; which is the subnet I want to tunnel/route to my server (172.x for the sake of this document)&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Traffic would come into &lt;em&gt;Router&lt;/em&gt; from an upstream device with a destination of 172.26.0.13. As the router has a route to a subnet in which that IP resides (by virtue of it having an IP in that subnet), it knows that IP should be reachable directly via our NIC2 interface and so ARPs for 172.26.0.13 out of it. Because both interfaces on &lt;em&gt;Server&lt;/em&gt; and NIC2 on &lt;em&gt;Router&lt;/em&gt; all sit in the same broadcast domain, my server happily replies to the ARP request (out of both interfaces - more on this later) so the router now forwards traffic down the wire to my server; Except there&amp;rsquo;s no reply&amp;hellip; but only sometimes.&lt;/p&gt;&#10;&lt;p&gt;After much head scratching, I noticed that when I do &lt;em&gt;sometimes&lt;/em&gt; get a correct response from 172.26.0.13, the ARP table for &lt;em&gt;Router&lt;/em&gt; was showing the MAC address for NIC1 on &lt;em&gt;Server&lt;/em&gt;. When I don&amp;rsquo;t get a reply (usually after the ARP entry expires) it instead shows the MAC for NIC2 - But having the MAC for NIC2 is what I&amp;rsquo;d expect, so whats going on?&lt;/p&gt;&#10;&lt;h3 id="the-explanation"&gt;The Explanation&lt;/h3&gt;&#10;&lt;p&gt;After spending a good amount of time throwing arbitrary queries into Google and cussing to myself, I eventually caved and asked my Network Engineer for a flat-mate, &lt;a href="https://blog.dataforce.org.uk/"&gt;Dataforce&lt;/a&gt;, for a fresh set of eyes.&lt;/p&gt;&#10;&lt;p&gt;We both spent a little while talking through the setup and testing various things and after a while took a look at a sysctl setting for &lt;code&gt;rp_filter&lt;/code&gt; (Reverse Path Filter). Consulting kernel documentation at &lt;a href="https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt"&gt;https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt&lt;/a&gt;, it says the following for rp_filter:&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;rp_filter - INTEGER&#10;&#9;0 - No source validation.&#10;&#9;1 - Strict mode as defined in RFC3704 Strict Reverse Path&#10;&#9; Each incoming packet is tested against the FIB and if the interface&#10;&#9; is not the best reverse path the packet check will fail.&#10;&#9; By default failed packets are discarded.&#10;&#9;2 - Loose mode as defined in RFC3704 Loose Reverse Path&#10;&#9; Each incoming packet&amp;#39;s source address is also tested against the FIB&#10;&#9; and if the source address is not reachable via any interface&#10;&#9; the packet check will fail.&#10;&#10;&#9;Current recommended practice in RFC3704 is to enable strict mode&#10;&#9;to prevent IP spoofing from DDos attacks. If using asymmetric routing&#10;&#9;or other complicated routing, then loose mode is recommended.&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If I check the current value for &lt;em&gt;Server&lt;/em&gt;, it is indeed &lt;strong&gt;STRICT&lt;/strong&gt; (1)&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@server:~# cat /proc/sys/net/ipv4/conf/all/rp_filter&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This implies that when a packet is received on an interface, the source IP is checked against the local routing table to see if the route in which the server would normally talk to the source IP, is the same interface at which the packet was received. My server&amp;rsquo;s default route (0.0.0.0) is out via NIC1, so traffic that ultimately comes from the internet via my tunnelled subnet would arrive on NIC2, but rp_filter would match against NIC1 - thus the check fails and the packet is dropped as invalid.&lt;/p&gt;&#10;&lt;h3 id="the-solution"&gt;The Solution&lt;/h3&gt;&#10;&lt;p&gt;Based on the documentation above, I either want to set rp_filter to be either 0 (&lt;strong&gt;NONE&lt;/strong&gt;) or 2 (&lt;strong&gt;LOOSE&lt;/strong&gt;). This is done via sysctl and the value can be changed whilst live in one of two ways:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@server:~# sysctl -w net.ipv4.conf.all.rp_filter=2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;net.ipv4.conf.all.rp_filter = 2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@server:~# echo 2 &amp;gt; /proc/sys/net/ipv4/conf/all/rp_filter&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Using either of these methods will only change the value until the server is rebooted. The value reverts to whatever is defined in sysctl.conf on boot so to make this change permanent, either edit your config, or add the following line if its not already defined:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@server:~# echo &amp;#34;net.ipv4.conf.all.rp_filter = 2&amp;#34; &amp;gt;&amp;gt; /etc/sysctl.conf&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Changing this to &lt;strong&gt;LOOSE&lt;/strong&gt; (2) means that when a packet is received on an interface, rp_filter will check the route table to see if the source IP is reachable via &lt;strong&gt;any&lt;/strong&gt; interface and if so, accept it (because it matches against 0.0.0.0). If I were to set this to &lt;strong&gt;NONE&lt;/strong&gt; (0), it outright wouldn&amp;rsquo;t do any verification checks so would just work normally regardless - the choice as to which you use is up to you.&lt;/p&gt;&#10;&lt;h3 id="bonus-issues"&gt;Bonus Issues!&lt;/h3&gt;&#10;&lt;p&gt;Now, if you recall I mentioned earlier that without this change, it &lt;em&gt;sometimes&lt;/em&gt; worked and &lt;em&gt;sometimes&lt;/em&gt; didn&amp;rsquo;t. This is a whole different issue altogether!&lt;/p&gt;&#10;&lt;p&gt;When &lt;em&gt;Router&lt;/em&gt; sends an ARP request, its a broadcast, so &lt;em&gt;Server&lt;/em&gt; will see it on both NIC1 and NIC2 as they are both within the same broadcast domain. By default &lt;em&gt;Server&lt;/em&gt; will respond to the ARP request out of both interfaces because it has the requested IP on one of its local interfaces. So, sometimes when &lt;em&gt;Router&lt;/em&gt; ARPs for 172.26.0.13, the reply that leaves NIC1 on &lt;em&gt;Server&lt;/em&gt; arrives back at &lt;em&gt;Router&lt;/em&gt; first, so &lt;em&gt;Router&lt;/em&gt; sends packets to NIC1.&lt;/p&gt;&#10;&lt;p&gt;Using the scenario above with rp_filter set &lt;strong&gt;STRICT&lt;/strong&gt;, packets arrive into NIC1 and the source would be reachable via NIC1 so everything just kinda works. However when ARP replies from NIC2 arrive back at &lt;em&gt;Router&lt;/em&gt; first, we are back to &lt;em&gt;Server&lt;/em&gt; dropping packets as invalid because of rp_filter being &lt;strong&gt;STRICT&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;p&gt;Now that we understand rp_filter a bit better and have changed it to &lt;strong&gt;LOOSE&lt;/strong&gt;, we should probably make sure that &lt;em&gt;Server&lt;/em&gt; only responds to ARP on the interface with the IP being requested. Whilst everything seemingly just works without doing this, we should make sure the flow of traffic is predictable and not randomly switching between interfaces based on which ARP reply arrives back first; so lets take a look back at the kernel documentation linked above and focus on &lt;code&gt;arp_ignore&lt;/code&gt;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;arp_ignore - INTEGER&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#9;Define different modes &lt;span class="k"&gt;for&lt;/span&gt; sending replies in response to&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#9;received ARP requests that resolve &lt;span class="nb"&gt;local&lt;/span&gt; target IP addresses:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#9;&lt;span class="m"&gt;0&lt;/span&gt; - &lt;span class="o"&gt;(&lt;/span&gt;default&lt;span class="o"&gt;)&lt;/span&gt;: reply &lt;span class="k"&gt;for&lt;/span&gt; any &lt;span class="nb"&gt;local&lt;/span&gt; target IP address, configured&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#9;on any interface&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#9;&lt;span class="m"&gt;1&lt;/span&gt; - reply only &lt;span class="k"&gt;if&lt;/span&gt; the target IP address is &lt;span class="nb"&gt;local&lt;/span&gt; address&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#9;configured on the incoming interface&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#9;&lt;span class="m"&gt;2&lt;/span&gt; - reply only &lt;span class="k"&gt;if&lt;/span&gt; the target IP address is &lt;span class="nb"&gt;local&lt;/span&gt; address&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#9;configured on the incoming interface and both with the&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#9;sender&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;s IP address are part from same subnet on this interface&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#9;&lt;span class="m"&gt;3&lt;/span&gt; - &lt;span class="k"&gt;do&lt;/span&gt; not reply &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nb"&gt;local&lt;/span&gt; addresses configured with scope host,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#9;only resolutions &lt;span class="k"&gt;for&lt;/span&gt; global and link addresses are replied&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#9;4-7 - reserved&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#9;&lt;span class="m"&gt;8&lt;/span&gt; - &lt;span class="k"&gt;do&lt;/span&gt; not reply &lt;span class="k"&gt;for&lt;/span&gt; all &lt;span class="nb"&gt;local&lt;/span&gt; addresses&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#9;The max value from conf/&lt;span class="o"&gt;{&lt;/span&gt;all,interface&lt;span class="o"&gt;}&lt;/span&gt;/arp_ignore is used&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#9;when ARP request is received on the &lt;span class="o"&gt;{&lt;/span&gt;interface&lt;span class="o"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So as above, lets set the value that best suits to what we need and make it persistent, in this case I chose 2&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@server:~# echo 2 &amp;gt; /proc/sys/net/ipv4/conf/all/arp_ignore&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@server:~# echo &amp;#34;net.ipv4.conf.all.arp_ignore = 2&amp;#34; &amp;gt;&amp;gt; /etc/sysctl.conf&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;ve now ensured that ARP replies are sent out of only the interface which has the IP being requested. Reverse Path Filter will no longer drop packets based on which interface the source is reachable and I can now talk to my server via my tunnelled IPs and everyone&amp;rsquo;s happy! :)&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;*Icons provided by &lt;a href="https://icons8.com"&gt;https://icons8.com&lt;/a&gt;*&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Odd behaviour with /etc/mtab being a regular file</title><link>https://www.simonmott.co.uk/2016/07/odd-behaviour-with-etcmtab-regular-file/</link><pubDate>Wed, 13 Jul 2016 19:53:35 +0000</pubDate><guid>https://www.simonmott.co.uk/2016/07/odd-behaviour-with-etcmtab-regular-file/</guid><description>&lt;p&gt;One of our customers had recently requested a Bare-Metal Restore (BMR) of one of their servers; which is a pretty routine task for us. However, upon bringing the restored server up I&amp;rsquo;d noticed some odd behaviour with some of its services, notably snmpd.&lt;/p&gt;&#10;&lt;p&gt;Our monitoring successfully polls most metrics that we look for, however fails on getting disk statistics and eventually snmpd just starts timing out. Using &lt;code&gt;snmpbulkwalk&lt;/code&gt; I could see that I was getting a response right up until midway through the &lt;strong&gt;HOST-RESOURCES MIB&lt;/strong&gt;. It did look to be hanging on mount points and once snmpbulkwalk had timed out, I couldn&amp;rsquo;t get a successful response from snmpd again. This was also seemingly affecting MariaDB, preventing it from starting, amongst other things.&lt;/p&gt;&#10;&lt;p&gt;I tried to run &lt;code&gt;df&lt;/code&gt; to check on disk usage/inodes, but this also hung. From previous experience this usually means one of the mount points is broken so I ran &lt;code&gt;strace df&lt;/code&gt; which indicated what the problem was:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;stat(&amp;#34;/proc/sys/fs/binfmt_misc&amp;#34;, ^C&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Process 2961 detached&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can see from the above that the process stalled whilst trying to stat &lt;code&gt;/proc/sys/fs/binfmt_misc&lt;/code&gt;. After a bit of Googling, a &amp;ldquo;quick and simple&amp;rdquo; fix for this was to un-mount and remount it. Note that a &lt;code&gt;mount -o remount&lt;/code&gt; didn&amp;rsquo;t work and similarly just hung.&lt;/p&gt;&#10;&lt;p&gt;I&amp;rsquo;d found the command to mount this again at &lt;a href="https://www.kernel.org/doc/Documentation/binfmt_misc.txt"&gt;https://www.kernel.org/doc/Documentation/binfmt_misc.txt&lt;/a&gt;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;umount -f -l /proc/sys/fs/binfmt_misc&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is all well and good, but I want a more permanent fix. What was causing this to fail consistently whenever the system boots?&lt;/p&gt;&#10;&lt;p&gt;I suspect this relates to the &lt;code&gt;systemd-binfmt&lt;/code&gt; service, so should be handled pretty early in our boot process. Checking &lt;code&gt;journalctl&lt;/code&gt; to see what&amp;rsquo;s going on with systemd yields the following error which jumped out at me:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Jul 12 08:08:01 myserver1.example.com systemd[1]: /etc/mtab is not a symlink or not pointing to&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;/proc/self/mounts. This is not supported anymore. Please make sure to replace this file by a&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;symlink to avoid incorrect or misleading mount(8) output.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Interesting&amp;hellip;&lt;/p&gt;&#10;&lt;p&gt;Taking a look at &lt;code&gt;/etc/mtab&lt;/code&gt;, this was indeed a regular file instead of a symlink. Being the likely cause for the observed mount issues (due to the system thinking things are mounted when in-fact they are not), this was removed and re-added as the correct symlink.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@myserver1 ~&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="c1"&gt;# ls -al /etc/mtab&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lrwxrwxrwx &lt;span class="m"&gt;1&lt;/span&gt; root root &lt;span class="m"&gt;17&lt;/span&gt; Jul &lt;span class="m"&gt;12&lt;/span&gt; 08:46 /etc/mtab -&amp;gt; /proc/self/mounts&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The server was then rebooted and everything seemed to come back up without any issues.&lt;/p&gt;&#10;&lt;p&gt;This server was seemingly working fine before the BMR, but had only been up 3 months or so. I&amp;rsquo;ve checked other servers deployed at the same time with the same template and they are not affected which rules out our deployment system. I&amp;rsquo;ve also tested our BMR process again (Now that /etc/mtab has been fixed) but it comes back correctly, as a symlink.&lt;/p&gt;&#10;&lt;p&gt;The backup from which the BMR was originally performed has since unfortunately cycled out of retention so I can&amp;rsquo;t do much more debugging from that; This does mean that at the moment I&amp;rsquo;m not sure how this change came about for this particular server but I&amp;rsquo;m glad I&amp;rsquo;ve got to the bottom of its strange behaviour.&lt;/p&gt;</description></item><item><title>Growing my Linux RAID5 array</title><link>https://www.simonmott.co.uk/2016/07/growing-my-linux-raid5-array/</link><pubDate>Sat, 09 Jul 2016 20:00:11 +0000</pubDate><guid>https://www.simonmott.co.uk/2016/07/growing-my-linux-raid5-array/</guid><description>&lt;p&gt;Recently I&amp;rsquo;ve needed to expand my RAID5 array by adding another disk. My experience with mdadm since starting to use it back in 2009 was for RAID1 only so I&amp;rsquo;ve never really needed to actually expand an array and so I thought I&amp;rsquo;d document the process here for future reference.&lt;/p&gt;&#10;&lt;p&gt;This process should in theory work for RAID4 and RAID6 personailities too, not just RAID5.&lt;/p&gt;&#10;&lt;p&gt;My array consists of 4x 3TB WD Red NAS drives in RAID5 for a total of ~9TB of space. I&amp;rsquo;m not going to cover creating of the array here because its mostly the same as RAID1, this instead will cover how to add a new disk to it and subsequent growing of LVM and ext4 to make use of the extra space. You can see how everything is stacked together in the image below.&lt;/p&gt;&#10;&lt;p&gt;There are a number of steps involved in expanding my array and I&amp;rsquo;ll be going through each one but loosely speaking they are:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2016/07/pre.png"&gt;&lt;img alt="pre" class="img-right" height="181" src="https://www.simonmott.co.uk/images/2016/07/pre.png" width="399"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;Create a partition on the new drive to be inserted&lt;/p&gt;&#10;&lt;ol start="2"&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Add the new drive to my array&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Grow the array&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Add the free space to LVM&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Grow the logical volume&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Resize ext4 to make use of the new space&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;I will admit, I had to do a little bit of brushing up on my mdadm and partitioning skills and I&amp;rsquo;d found these two sites useful:&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://raid.wiki.kernel.org/index.php/Growing"&gt;https://raid.wiki.kernel.org/index.php/Growing&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="http://www.cyberciti.biz/tips/fdisk-unable-to-create-partition-greater-2tb.html"&gt;http://www.cyberciti.biz/tips/fdisk-unable-to-create-partition-greater-2tb.html&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;For the purposes of this article though, I&amp;rsquo;ve already installed the new disk into the chassis and made sure that my system can see the new drive before doing any further work; Lets take a look at my array before doing anything to it - You can see here I have about 9TB of space&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# df -h /dev/mapper/data-wdred&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Filesystem Size Used Avail Use% Mounted on&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;/dev/mapper/data-wdred 8.2T 7.5T 678G 92% /mnt/storage&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So lets begin&amp;hellip;&lt;/p&gt;&#10;&lt;h3 id="partition-the-new-drive-using-parted"&gt;Partition the new drive using parted&lt;/h3&gt;&#10;&lt;p&gt;I&amp;rsquo;d normally use fdisk for this because its what I am most familiar with, however it seems that you can&amp;rsquo;t create a partition greater than 2TB in size using it so I&amp;rsquo;ve had to use &lt;code&gt;parted&lt;/code&gt; for this. The disk is a blank disk so your output may vary from the below if you&amp;rsquo;re working with something that is already partitioned, but first we create a GPT partition and set it to be 3TB in size (as we want to use the whole disk), we then check what parted thinks exists on the disk just to make sure everything is correct and thats the disk partitioned&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# parted /dev/sda&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;GNU Parted 3.2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Using /dev/sda&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Welcome to GNU Parted! Type &amp;#39;help&amp;#39; to view a list of commands.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;(parted) mklabel gpt&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Warning: The existing disk label on /dev/sda will be destroyed and all data on this disk will be lost. Do you want to continue?&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Yes/No? Yes&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;(parted) unit TB&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;(parted) mkpart primary 0 3&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;(parted) toggle 1 raid&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;(parted) print&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Model: ATA WDC WD30EFRX-68E (scsi)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Disk /dev/sda: 3.00TB&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Sector size (logical/physical): 512B/4096B&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Partition Table: gpt&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Disk Flags:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Number Start End Size File system Name Flags&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 1 0.00TB 3.00TB 3.00TB primary  raid&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;(parted) quit&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Information: You may need to update /etc/fstab.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I set the &amp;ldquo;type&amp;rdquo; flag on the partition to be &lt;strong&gt;Linux RAID&lt;/strong&gt; - Again this was out of habbit and I&amp;rsquo;m not really sure if it affects auto scanning of the array these days.&lt;/p&gt;&#10;&lt;p&gt;That should be everything for partitioning done - You should now see in your devices &lt;code&gt;/dev/sda&lt;/code&gt; and &lt;code&gt;/dev/sda1&lt;/code&gt;&lt;/p&gt;&#10;&lt;h3 id="grow-the-array-using-linux-raid-mdadm"&gt;Grow the array using Linux RAID (mdadm)&lt;/h3&gt;&#10;&lt;p&gt;Now that we&amp;rsquo;ve partitioned the new disk to be used, we need to add it to our raid5 array. This part is simple enough and once I&amp;rsquo;d added it, I detailed the array and you can see the new disk as a &lt;strong&gt;spare&lt;/strong&gt; near the bottom&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# mdadm --add /dev/md0 /dev/sda1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;mdadm: added /dev/sda1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# mdadm --detail /dev/md0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;/dev/md0:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Version : 1.2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Creation Time : Wed Sep 9 00:42:04 2015&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Raid Level : raid5&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Array Size : 8790402048 (8383.18 GiB 9001.37 GB)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Used Dev Size : 2930134016 (2794.39 GiB 3000.46 GB)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Raid Devices : 4&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Total Devices : 5&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Persistence : Superblock is persistent&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Update Time : Sun Jul 3 13:42:19 2016&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; State : clean&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Active Devices : 4&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Working Devices : 5&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Failed Devices : 0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Spare Devices : 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Layout : left-symmetric&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Chunk Size : 512K&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Name : yuzuki:0 (local to host yuzuki)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; UUID : 85414a00:04a22cb3:8cd5656f:8e86f737&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Events : 57988&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Number Major Minor RaidDevice State&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 0 8 81 0 active sync /dev/sdf1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 1 8 33 1 active sync /dev/sdc1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 2 8 65 2 active sync /dev/sde1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 4 8 49 3 active sync /dev/sdd1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 5 8 1 - spare /dev/sda1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Great! If we left this as-is now then this new disk would simply be automatically used to rebuild the array if one of the current active disks fail, essentially RAID5 with a hot-spare. I however want to incorporate this disk into my array to be able to grow capacity.&lt;/p&gt;&#10;&lt;p&gt;I read that at the start of the growing process there&amp;rsquo;s a critical section where if power is interrupted this data can become lost which would kill the entire array so It&amp;rsquo;s recommended to back this up onto a different disk/array for recovery purposes. Thankfully I didn&amp;rsquo;t need to use this&lt;/p&gt;&#10;&lt;p&gt;Growing is also fairly straightforward in that you tell the array how many active drives you want (in my case 5) and which array to change and everything else is done in the background.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# mdadm --grow --raid-devices=5 --backup-file=/home/simon/grow.bak /dev/md0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;mdadm: Need to backup 6144K of critical section..&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Actually growing the array is the most time consuming part of this process; Overall this next task took &lt;strong&gt;21 hours&lt;/strong&gt; to complete on my rig.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# cat /proc/mdstat&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Personalities : [raid6] [raid5] [raid4]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;md0 : active raid5 sda1[5] sdf1[0] sdd1[4] sde1[2] sdc1[1]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 8790402048 blocks super 1.2 level 5, 512k chunk, algorithm 2 [5/5] [UUUUU]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; [&amp;gt;....................] reshape = 0.0% (402624/2930134016) finish=1333.9min speed=36602K/sec&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;unused devices: &amp;lt;none&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# mdadm --detail /dev/md0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;/dev/md0:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Version : 1.2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Creation Time : Wed Sep 9 00:42:04 2015&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Raid Level : raid5&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Array Size : 8790402048 (8383.18 GiB 9001.37 GB)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Used Dev Size : 2930134016 (2794.39 GiB 3000.46 GB)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Raid Devices : 5&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Total Devices : 5&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Persistence : Superblock is persistent&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Update Time : Sun Jul 3 13:46:39 2016&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; State : active, reshaping&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Active Devices : 5&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Working Devices : 5&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Failed Devices : 0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Spare Devices : 0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Layout : left-symmetric&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Chunk Size : 512K&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Reshape Status : 0% complete&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Delta Devices : 1, (4-&amp;gt;5)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Name : yuzuki:0 (local to host yuzuki)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; UUID : 85414a00:04a22cb3:8cd5656f:8e86f737&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Events : 58026&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Number Major Minor RaidDevice State&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 0 8 81 0 active sync /dev/sdf1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 1 8 33 1 active sync /dev/sdc1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 2 8 65 2 active sync /dev/sde1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 4 8 49 3 active sync /dev/sdd1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 5 8 1 4 active sync /dev/sda1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As you can see here, the reshape has started and is giving me an estimate of ~22 hours - The estimate and speed will vary throughout the process and you can control the speed at which it works (if you need to lower it to reduce disk IO for some reason) via &lt;code&gt;/proc/sys/dev/raid/speed_limit_min&lt;/code&gt; and &lt;code&gt;/proc/sys/dev/raid/speed_limit_max&lt;/code&gt;. You can also see here that I no longer have a &amp;ldquo;spare&amp;rdquo; disk too; This means I&amp;rsquo;ll have 4 drives worth of capacity with 1 used for parity data, so when complete, I should have 12TB worth of storage.&lt;/p&gt;&#10;&lt;p&gt;Once the reshape has completed we can move onto the next stage.&lt;/p&gt;&#10;&lt;h3 id="growing-lvm"&gt;Growing LVM&lt;/h3&gt;&#10;&lt;p&gt;Now that our array itself has grown, we need to make LVM aware of the free space before we can use it and we do this simply by issuing a &lt;code&gt;pvresize&lt;/code&gt; command on the block device mdadm uses for exposing our array, after which we can see that 2.7TiB is registered as free for both the &lt;strong&gt;Physical Volume&lt;/strong&gt; and in the &lt;strong&gt;Volume Group&lt;/strong&gt; too.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# pvresize /dev/md0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Physical volume &amp;#34;/dev/md0&amp;#34; changed&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 1 physical volume(s) resized / 0 physical volume(s) not resized&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# pvscan&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PV /dev/sdb3 VG pve lvm2 [148.55 GiB / 16.00 GiB free]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PV /dev/md0 VG data lvm2 [10.92 TiB / 2.73 TiB free]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Total: 2 [11.06 TiB] / in use: 2 [11.06 TiB] / in no VG: 0 [0 ]&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# vgdisplay data&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; --- Volume group ---&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; VG Name data&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; System ID&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Format lvm2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Metadata Areas 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Metadata Sequence No 3&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; VG Access read/write&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; VG Status resizable&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; MAX LV 0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Cur LV 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Open LV 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Max PV 0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Cur PV 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Act PV 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; VG Size 10.92 TiB&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PE Size 4.00 MiB&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Total PE 2861458&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Alloc PE / Size 2146093 / 8.19 TiB&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Free PE / Size 715365 / 2.73 TiB&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; VG UUID XT2yMd-iyVD-4u0e-5AG8-7GED-kcfd-ebLjNL&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;All thats left now is to expand the &lt;strong&gt;Logical Volume&lt;/strong&gt; which I want to use all available free space in the Volume Group:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# lvextend -l +100%FREE /dev/mapper/data-wdred /dev/md0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Size of logical volume data/wdred changed from 8.19 TiB (2146093 extents) to 10.92 TiB (2861458 extents).&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Logical volume wdred successfully resized&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we&amp;rsquo;re in the home stretch!&lt;/p&gt;&#10;&lt;h3 id="expanding-ext4-file-system"&gt;Expanding ext4 file system&lt;/h3&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2016/07/lvm.png"&gt;&lt;img alt="lvm" class="img-right" height="181" src="https://www.simonmott.co.uk/images/2016/07/lvm.png" width="399"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;The final leg of this task is to expand the file system that sits on top of all this.&lt;/p&gt;&#10;&lt;p&gt;I opted to do this online which means it ran without a consistency check - If you wanted to check it first you&amp;rsquo;d need to un-mount the file system in order to run e2fsck. I originally expected this to take a fairly long time but it turns out it took less than a minute to complete.&lt;/p&gt;&#10;&lt;p&gt;The image to the right illustrates where we&amp;rsquo;re at in the process - we&amp;rsquo;ve added the new disk to our RAID array and expanded LVM to fit, this last step will be to grow our ext4 file system to boot.&lt;/p&gt;&#10;&lt;p&gt;Naturally you don&amp;rsquo;t have to use ext4, this is just my preference however it is at this stage that your path could differ from mine if you&amp;rsquo;re not using ext4 (or ext3) but the process should be similar if your chosen file System supports growing.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# time resize2fs -p /dev/mapper/data-wdred&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;resize2fs 1.42.12 (29-Aug-2014)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Filesystem at /dev/mapper/data-wdred is mounted on /mnt/storage; on-line resizing required&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;old_desc_blocks = 524, new_desc_blocks = 699&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;The filesystem on /dev/mapper/data-wdred is now 2930132992 (4k) blocks long.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;real 0m35.221s&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;user 0m0.008s&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;sys 0m29.460s&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And that&amp;rsquo;s it, My storage array has now grown! Overall the process took me about 22-23 hours because I kept getting distracted in-between but the majority of this time was waiting for mdadm to grow the array. We can compare output of &lt;code&gt;df&lt;/code&gt; from before and after&lt;/p&gt;&#10;&lt;p&gt;Before&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# df -h /dev/mapper/data-wdred&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Filesystem Size Used Avail Use% Mounted on&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;/dev/mapper/data-wdred 8.2T 7.5T 678G 92% /mnt/storage&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@yuzuki:~# df -h /dev/mapper/data-wdred&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Filesystem Size Used Avail Use% Mounted on&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;/dev/mapper/data-wdred 11T 7.5T 3.4T 69% /mnt/storage&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And I still have space for another 5 drives in my chassis :)&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;*HDD Icons provided by &lt;a href="https://icons8.com"&gt;https://icons8.com&lt;/a&gt;*&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Slow DNS resolving using bind9 as caching resolver</title><link>https://www.simonmott.co.uk/2016/06/slow-dns-resolving-using-bind9-caching-resolver/</link><pubDate>Sun, 26 Jun 2016 02:30:46 +0000</pubDate><guid>https://www.simonmott.co.uk/2016/06/slow-dns-resolving-using-bind9-caching-resolver/</guid><description>&lt;p&gt;I currently have 4 DNS servers across my estate and until recently these were all configured to forward all queries to Google DNS (8.8.8.8). I ended up having an issue with Google caching an undesired record value so I opted to change my DNS servers so that they no longer forward queries elsewhere, but instead try to answer it themselves; Doing this gives me slightly more control over my DNS cache.&lt;/p&gt;&#10;&lt;p&gt;As I use named (bind9) this was a pretty trivial change - Simply remove the &lt;code&gt;forwarders { 8.8.8.8; };&lt;/code&gt; clause in my configuration and that should be that.&lt;/p&gt;&#10;&lt;p&gt;During my post-change testing though I&amp;rsquo;d noticed that resolution was taking significantly longer for un-cached queries than I&amp;rsquo;d expect (microsoft.gointeract.io is only used to illustrate my issue):&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@ns3:~# rndc flush &amp;amp;&amp;amp; dig microsoft.gointeract.io&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;; &amp;lt;&amp;lt;&amp;gt;&amp;gt; DiG 9.9.5-3ubuntu0.8-Ubuntu &amp;lt;&amp;lt;&amp;gt;&amp;gt; microsoft.gointeract.io&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; global options: +cmd&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; Got answer:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; -&amp;gt;&amp;gt;HEADER&amp;lt;&amp;lt;- opcode: QUERY, status: NOERROR, id: 40048&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 4, ADDITIONAL: 9&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; OPT PSEUDOSECTION:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;; EDNS: version: 0, flags:; udp: 4096&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; QUESTION SECTION:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;microsoft.gointeract.io. IN A&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; ANSWER SECTION:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;microsoft.gointeract.io. 300 IN CNAME interact-utm.cloudapp.net.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;interact-utm.cloudapp.net. 60 IN A 23.101.130.247&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; AUTHORITY SECTION:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;cloudapp.net. 172799 IN NS prd3.azuredns-cloud.net.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;cloudapp.net. 172799 IN NS prd1.azuredns-cloud.net.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;cloudapp.net. 172799 IN NS prd2.azuredns-cloud.net.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;cloudapp.net. 172799 IN NS prd4.azuredns-cloud.net.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; ADDITIONAL SECTION:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;prd1.azuredns-cloud.net. 172799 IN A 204.79.195.43&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;prd1.azuredns-cloud.net. 172799 IN AAAA 2a01:111:2005:5::5&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;prd2.azuredns-cloud.net. 172799 IN A 65.55.117.43&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;prd2.azuredns-cloud.net. 172799 IN AAAA 2a01:111:2006:c::5&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;prd3.azuredns-cloud.net. 172799 IN A 204.79.195.48&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;prd3.azuredns-cloud.net. 172799 IN AAAA 2a01:111:2020:3::5&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;prd4.azuredns-cloud.net. 172799 IN A 65.55.117.48&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;prd4.azuredns-cloud.net. 172799 IN AAAA 2a01:111:2032:1::5&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; Query time: 4502 msec&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; SERVER: 10.0.2.13#53(10.0.2.13)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; WHEN: Sat Jun 25 17:08:38 BST 2016&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; MSG SIZE rcvd: 374&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The entire query took 4.5 seconds which seems unusually long. I was seeing similar Query times for my other DNS servers too and they&amp;rsquo;re located in other facilities dotted around the country so I set about trying to find out why.&lt;/p&gt;&#10;&lt;p&gt;Using &lt;code&gt;tcpdump&lt;/code&gt; I could quickly see a potential cause for the delay&amp;hellip;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;17:08:35.729948 IP6 fe80::6432:36ff:fe38:3536.20251 &amp;gt; 2a01:111:2005:5::5.53: 1759% [1au] A? interact-utm.cloudapp.net. (54)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;17:08:36.530082 IP6 fe80::6432:36ff:fe38:3536.21384 &amp;gt; 2a01:111:2020:3::5.53: 33150% [1au] A? interact-utm.cloudapp.net. (54)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;17:08:37.330127 IP6 fe80::6432:36ff:fe38:3536.22815 &amp;gt; 2a01:111:2006:c::5.53: 49009% [1au] A? interact-utm.cloudapp.net. (54)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;17:08:38.130220 IP6 fe80::6432:36ff:fe38:3536.4519 &amp;gt; 2a01:111:2032:1::5.53: 3339% [1au] A? interact-utm.cloudapp.net. (54)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;17:08:38.930305 IP 46.xx.xx.xx.1965 &amp;gt; 204.79.195.43.53: 13538% [1au] A? interact-utm.cloudapp.net. (54)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;17:08:38.937824 IP 204.79.195.43.53 &amp;gt; 46.xx.xx.xx.1965: 13538*- 1/0/1 A 23.101.130.247 (70)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This shows my server sending queries to an IPv6 address using its link-local address (&lt;em&gt;IPv4 obfuscated&lt;/em&gt;).&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;I do not have IPv6 configured for anything yet&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;The link-local address isn&amp;rsquo;t public routable&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;Here we can see named is waiting for a short timeout period before moving onto the next address to query - It eventually gets a response on its IPv4 address. Each IPv6 address in the recursion chain will add more delay.&lt;/p&gt;&#10;&lt;p&gt;By default named works with both IPv4 and IPv6, but it seems that becuase my system &lt;strong&gt;*seems*&lt;/strong&gt; IPv6 capable, it tries to use it regardless which causes a delay in resolution. As I don&amp;rsquo;t yet have working IPv6 connectivity everywhere, I opted to disable IPv6 in named itself for the time being.&lt;/p&gt;&#10;&lt;p&gt;Looking at named manual, simply invoking the daemon with &lt;em&gt;&lt;strong&gt;-4&lt;/strong&gt;&lt;/em&gt; should do the trick. As I am running Ubuntu, I added it to named&amp;rsquo;s defaults:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@ns3:~# cat /etc/default/bind9&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; run resolvconf?&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;RESOLVCONF=no&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; startup options &lt;span class="k"&gt;for&lt;/span&gt; the server&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;OPTIONS=&amp;#34;-u bind -4&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once added, restart named and you should see much improved resolving times:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;root@ns3:~# rndc flush &amp;amp;&amp;amp; dig microsoft.gointeract.io&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;; &amp;lt;&amp;lt;&amp;gt;&amp;gt; DiG 9.9.5-3ubuntu0.8-Ubuntu &amp;lt;&amp;lt;&amp;gt;&amp;gt; microsoft.gointeract.io&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; global options: +cmd&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; Got answer:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; -&amp;gt;&amp;gt;HEADER&amp;lt;&amp;lt;- opcode: QUERY, status: NOERROR, id: 42883&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 4, ADDITIONAL: 9&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; OPT PSEUDOSECTION:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;; EDNS: version: 0, flags:; udp: 4096&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; QUESTION SECTION:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;microsoft.gointeract.io. IN A&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; ANSWER SECTION:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;microsoft.gointeract.io. 300 IN CNAME interact-utm.cloudapp.net.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;interact-utm.cloudapp.net. 60 IN A 23.101.130.247&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; AUTHORITY SECTION:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;cloudapp.net. 172800 IN NS prd4.azuredns-cloud.net.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;cloudapp.net. 172800 IN NS prd1.azuredns-cloud.net.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;cloudapp.net. 172800 IN NS prd2.azuredns-cloud.net.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;cloudapp.net. 172800 IN NS prd3.azuredns-cloud.net.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; ADDITIONAL SECTION:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;prd1.azuredns-cloud.net. 172800 IN A 204.79.195.43&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;prd1.azuredns-cloud.net. 172800 IN AAAA 2a01:111:2005:5::5&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;prd2.azuredns-cloud.net. 172800 IN A 65.55.117.43&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;prd2.azuredns-cloud.net. 172800 IN AAAA 2a01:111:2006:c::5&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;prd3.azuredns-cloud.net. 172800 IN A 204.79.195.48&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;prd3.azuredns-cloud.net. 172800 IN AAAA 2a01:111:2020:3::5&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;prd4.azuredns-cloud.net. 172800 IN A 65.55.117.48&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;prd4.azuredns-cloud.net. 172800 IN AAAA 2a01:111:2032:1::5&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; Query time: 231 msec&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; SERVER: 10.0.2.13#53(10.0.2.13)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; WHEN: Sat Jun 25 17:10:29 BST 2016&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;;; MSG SIZE rcvd: 374&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Much better :)&lt;/p&gt;</description></item><item><title>PHP Handlers and PHP 5 vs 7</title><link>https://www.simonmott.co.uk/2016/06/php-handlers-php-5-vs-7/</link><pubDate>Sat, 11 Jun 2016 22:39:47 +0000</pubDate><guid>https://www.simonmott.co.uk/2016/06/php-handlers-php-5-vs-7/</guid><description>&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2016/06/php_logo.png"&gt;&lt;img alt="php_logo" class="img-right" height="130" src="https://www.simonmott.co.uk/images/2016/06/php_logo.png" width="248"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;The idea for this post actually came from observing performance after moving this site over to WordPress (and to a lesser extent, my other website, &lt;a href="http://www.gentog.co.uk/"&gt;General Photography&lt;/a&gt;). I use &lt;a href="https://puppet.com/"&gt;Puppet&lt;/a&gt; orchestration for my servers and I made the mistake of trying to convert everything to puppet manifests and also get things working how I wanted without fully understanding how puppet works at the same time; That however is another story. This does means that my puppet manifests are not very flexible currently and I use suphp as my main PHP handler just because for me, at the time, it was easier.&lt;/p&gt;&#10;&lt;p&gt;That being said - I&amp;rsquo;m fully aware of the performance issues suphp exhibits because my &lt;a href="http://www.observium.org/"&gt;Observium&lt;/a&gt; install used it at first - it now uses mod_php because loading all the graphs was noticably slow. I thought I&amp;rsquo;d try to quantify the performance differences between suphp and mod_php and decided I should do all 3 common PHP handlers. Whilst I was gathering metrics for this I decided It&amp;rsquo;d be useful to include PHP7 results too.&lt;/p&gt;&#10;&lt;h3 id="the-environment"&gt;The Environment&lt;/h3&gt;&#10;&lt;p&gt;I tried to ensure my testing was fair so I&amp;rsquo;ll detail my setup. Firstly I cloned the container my website runs on 3 times. One so I can test suphp, one for mod_php and one for php-fpm.&lt;/p&gt;&#10;&lt;p&gt;I will be performing these tests against different instances of my website which is based on WordPress 4.5.2&lt;/p&gt;&#10;&lt;p&gt;The first container was already set to go as I use suphp already - it was an exact clone of my website container. The second container I&amp;rsquo;d removed suphp and installed mod_php and for the final container, I&amp;rsquo;d removed suphp and installed mod_fastcgi and also set up php-fpm. The intial round of testing was done on these 3 containers which were then upgraded to PHP7 and the same round of testing done again.&lt;/p&gt;&#10;&lt;p&gt;I made sure the containers were running on the same host as my main website container to ensure similar performance as my live site and for results to be comparable to each other. They all use the same database container too so thats one less thing to worry about.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Host Server Spec&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;CPU: &lt;a href="http://ark.intel.com/products/40481/Intel-Xeon-Processor-L3360-12M-Cache-2_83-GHz-1333-MHz-FSB?q=l3360"&gt;Intel(R) Xeon(R) CPU L3360 @ 2.83GHz 4C/4T&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;RAM: 8GB DDR2 PC2-6400 (800 MHz)&lt;/p&gt;&#10;&lt;p&gt;HDD: 2x 1TB WD-Black (WD1002FAEX) in RAID1&lt;/p&gt;&#10;&lt;p&gt;OS: Proxmox 4.2-5/7cf09667&lt;/p&gt;&#10;&lt;p&gt;Kernel: 4.4.6-1-pve&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Container Spec&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Contianer Type: LXC&lt;/p&gt;&#10;&lt;p&gt;OS: Ubuntu 14.04.1 &lt;em&gt;(Yes, I know it needs updating!)&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;RAM: 1GB&lt;/p&gt;&#10;&lt;p&gt;CPU Limit: 2&lt;/p&gt;&#10;&lt;p&gt;CPU Units: 1024&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Software Versions&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Apache Version: 2.4.7&lt;/p&gt;&#10;&lt;p&gt;PHP 5.5.9-1ubuntu4.17&lt;/p&gt;&#10;&lt;p&gt;PHP 7.0.7-4+deb.sury.org~trusty+1&lt;/p&gt;&#10;&lt;p&gt;WordPress 4.5.2&lt;/p&gt;&#10;&lt;p&gt;MySQL: 5.5.41-0ubuntu0.14.04.1 (Although this is hosted in its own container which remains the same through the testing)&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Configuration&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Apache Mode: mpm_prefork&lt;/p&gt;&#10;&lt;p&gt;Apache MaxClients: 20&lt;/p&gt;&#10;&lt;p&gt;Apache ServerLimit: 20&lt;/p&gt;&#10;&lt;p&gt;Apache MaxRequestsPerChild: 4000&lt;/p&gt;&#10;&lt;p&gt;php-fpm Process Manager: dynamic&lt;/p&gt;&#10;&lt;p&gt;php-fpm max_children: 20&lt;/p&gt;&#10;&lt;h3 id="the-testing"&gt;The Testing&lt;/h3&gt;&#10;&lt;p&gt;I first started by using curl to send 20 sequential GET requests to index.php via Apache and timing how long it takes to send me the generated contents of the page and then averaged it. For comparison purposes I also recorded the length of time PHP took to generate the page by invoking it on command line via &lt;code&gt;php-cgi -f index.php&lt;/code&gt;, again taking an average.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2016/06/php_time.png"&gt;&lt;img alt="Avg load time for 20 sequential requests" class="img-center" height="511" src="https://www.simonmott.co.uk/images/2016/06/php_time.png" width="929"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;You can see from the chart above that suphp takes longer to return results than just invoking on the command line but this makes sense because Apache has to process the request and spawn a PHP process to fully deal with it along with network overheads between my test client and test server. PHP7&amp;rsquo;s performance enhancements are visible here too with all handlers using PHP7 resulting in faster loading times. For both PHP5.5 and PHP7, mod_php and php-fpm seem to share similar performance.&lt;/p&gt;&#10;&lt;p&gt;The &lt;strong&gt;configuration&lt;/strong&gt; section above is important for our next test. I limited the number of processes that could spawn so as to not take out my container by putting it under too high load specifically for mod_php - Whilst you can tweak those options to suit your liking/environment, each handler have different things to consider - primarily how much RAM they consume.&lt;/p&gt;&#10;&lt;p&gt;For both suphp and php-fpm handlers, they offload PHP to another process. For the particular modules I had configured in Apache, on average each process for both suphp and php-fpm tests seemed to hover around 7.5MB - for mod_php however things are a bit different. mod_php is a module that&amp;rsquo;s loaded by Apache which allows it to interpret PHP itself without having to pass it off to another process, which is by far one of the reasons mod_php performs so well however this does mean that for each Apache process created, it has to load this module every time which makes this a rather RAM heavy approach - During testing of mod_php I&amp;rsquo;d clocked average Apache RAM usage at around 54MB per process so for all 20 processes running, that&amp;rsquo;d all but saturate RAM on my container.&lt;/p&gt;&#10;&lt;p&gt;php-fpm is definately the way to go if RAM is your concern. Whilst it does maintain a separate pool of processes ready to process PHP, its not constantly spawning/killing processes like suphp does and doesnt have to contend with other items in RAM like Apache does making it leaner.&lt;/p&gt;&#10;&lt;p&gt;We&amp;rsquo;ve seen above how each handler performs just by processing a simple request, lets take a look what they look like under a bit of load&amp;hellip;&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2016/06/php_hits.png"&gt;&lt;img alt="150 concurrent over 1 minute" class="img-center" height="508" src="https://www.simonmott.co.uk/images/2016/06/php_hits.png" width="930"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;In order to generate some load, I&amp;rsquo;d used a tool called siege in benchmark mode. Simply put, you point it at a URL (or a list of URLs), tell it how many concurrent &amp;ldquo;users&amp;rdquo; you want and give it some criteria for how long to run. In my case I used&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;siege -t1m -b -c150 https://www.simonmott.co.uk/&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;which would simulate 150 concurrent users hitting my website for 1 minute. Once a &amp;ldquo;user&amp;rdquo; has sent and received a successful (or failed) request, it immediately sends a new one. Testing in this method illustrates how quickly each handler can actually deal with requests (and shows off the performance improvements for PHP7 quite nicely).&lt;/p&gt;&#10;&lt;p&gt;To illustrate how each handler manages to cope with requests I plotted average, longest and shortest response times which shows especially how suphp, along with the low hit-rate, just struggles to keep up because of having to constantly spawn new processes, on top of that, because the processes are short lived (for the duration of the request), they do not benefit from any kind of opcode caching as mod_php and php-fpm do.&lt;/p&gt;&#10;&lt;h3 id="conclusion"&gt;Conclusion&lt;/h3&gt;&#10;&lt;p&gt;Another major pitfall of mod_php aside from its RAM consumption is that all PHP it processes is done so as the user Apache runs as which isn&amp;rsquo;t ideal for a multi-site environment because all sites need to be accessed (and modified, depending on your application) by your Apache user. This simply means in a multi-site environment that if someone compromises one of your websites, they can potentially glean database username/passwords for other sites accessible by this user and/or other sensitive information depending on your setup.&lt;/p&gt;&#10;&lt;p&gt;suphp is probably one of the easiest ways to afford more security over your websites because each process it spawns to deal with php, is done so as the user that owns the php file its trying to execute. This means that as long as your file permissions are sane, you shouldn&amp;rsquo;t be able to read file contents of other users but you just take a major performance hit because of the way it works.&lt;/p&gt;&#10;&lt;p&gt;This leaves php-fpm. This by far is the best way to go if you put the time into configuring it. This handler allows pools of processes to run as specific users so grants you the same level of security as suphp, but it does so by keeping processes around much longer than suphp which means it benefits from not having the overheads of spawning new processes for each request, and can make use of opcode caching to further enhance performance along with better resource management in general.&lt;/p&gt;&#10;&lt;p&gt;The performance improvements for PHP7 are not something to ignore either - In the case of this WordPress blog, simple page loading time was &lt;strong&gt;2x&lt;/strong&gt; faster via both mod_php and php-fpm using the same settings. Furthermore as shown above, PHP7 was able to handle &lt;strong&gt;3x&lt;/strong&gt; more requests in 1 minute with better average loading times than the same settings using PHP5.5.&lt;/p&gt;&#10;&lt;p&gt;For me, the clear winner here is php-fpm, no matter which version of PHP you decide to roll&lt;/p&gt;</description></item><item><title>Caching with Apache's mod_cache and mod_deflate</title><link>https://www.simonmott.co.uk/2016/06/caching-apaches-mod_cache-mod_deflate/</link><pubDate>Mon, 06 Jun 2016 18:21:49 +0000</pubDate><guid>https://www.simonmott.co.uk/2016/06/caching-apaches-mod_cache-mod_deflate/</guid><description>&lt;p&gt;I currently work in the hosting industry and as part of my job I have to deal with WordPress on a regular basis and as such I&amp;rsquo;ve seen how appalling it can be sometimes with regards to page loading times. Given that my content on here doesn&amp;rsquo;t change all too often, it makes sense to spend the time generating the content only once and serving it to meet multiple requests for the same document. In order to do this one would usually employ some form of caching.&lt;/p&gt;&#10;&lt;p&gt;WordPress itself does have the option for multiple caching plugins which integrate nicely but in my experience they still have to pass the request off to a PHP handler which means some processing is still needed to accommodate the request (albeit less than a full page load). For the purposes of this article though, I&amp;rsquo;m going to assume a generic framework as this technique is not specific to WordPress at all.&lt;/p&gt;&#10;&lt;p&gt;There&amp;rsquo;re a number of software solutions to sit in front of your web server which act as a cache and some of the more notable ones are &lt;a href="https://www.nginx.com/"&gt;nginx&lt;/a&gt; and &lt;a href="https://varnish-cache.org/"&gt;varnish&lt;/a&gt; and each have their pros and cons (As far as I know, Varnish can&amp;rsquo;t do native SSL termination yet). For this post though, I&amp;rsquo;ll be making use of some Apache modules to do the same thing. This was mostly an experiment for myself to see what I could do with it - I&amp;rsquo;ve found some limitations which as of yet I haven&amp;rsquo;t been able to work around for lack of knowledge on the inner workings of Apache, but for now It does the job.&lt;/p&gt;&#10;&lt;p&gt;I&amp;rsquo;ll probably be doing an article on varnish and/or nginx in the future, but for now lets focus on &lt;a href="https://httpd.apache.org/docs/current/mod/mod_cache.html"&gt;mod_cache&lt;/a&gt; and &lt;a href="https://httpd.apache.org/docs/current/mod/mod_cache_disk.html"&gt;mod_cache_disk&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;Lets start by taking a benchmark of how long the homepage takes to load without cache. The following will hit my homepage 5 times with a 1 second delay between each request&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;simon@kinmu:~$ i=0; while [ $i -lt 5 ]; do time -p curl &amp;#34;https://www.simonmott.co.uk/&amp;#34; &amp;gt; /dev/null; sleep 1; i=$[$i+1]; done 2&amp;gt;&amp;amp;1 | grep real | awk &amp;#39;{print $2}&amp;#39; | awk &amp;#39;{avg += ($1 - avg) / NR;} END {print &amp;#34;Average: &amp;#34; avg &amp;#34;s&amp;#34;;}&amp;#39;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Average: 0.696s&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This gives us an average of &lt;strong&gt;0.696s&lt;/strong&gt; to load the page&amp;hellip; This is the time to beat :)&lt;/p&gt;&#10;&lt;p&gt;Before we begin - I encourage you to read the Apache documentation for &lt;a href="https://httpd.apache.org/docs/current/mod/mod_cache.html"&gt;mod_cache&lt;/a&gt; and &lt;a href="https://httpd.apache.org/docs/current/mod/mod_cache_disk.html"&gt;mod_cache_disk&lt;/a&gt; - it will make a lot more sense if you do!&lt;/p&gt;&#10;&lt;h3 id="mod_cache---the-config"&gt;mod_cache - The config&lt;/h3&gt;&#10;&lt;p&gt;I&amp;rsquo;ll start by showing you my current config - I&amp;rsquo;ll then go through each option and comment as to why I made the decision to use that particular setting/option. This snippet of config lives in my &lt;strong&gt;VirtualHost&lt;/strong&gt; directive for my website and I suspect a lot of my comments will essentially be copy/pasted from apache.org&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheQuickHandler off&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheRoot /var/cache/apache2/mod_cache_disk/simonmott.co.uk&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheEnable disk /&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheDirLevels &lt;span class="m"&gt;2&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheDirLength &lt;span class="m"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheMaxFileSize &lt;span class="m"&gt;2000000&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheIgnoreNoLastMod On&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheDefaultExpire &lt;span class="m"&gt;7200&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheIgnoreCacheControl On&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheLastModifiedFactor 0.5&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheIgnoreHeaders Set-Cookie Cookie&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheHeader on&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheLock on&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheDisable /wp-admin&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheDisable /wp-login.php&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheDisable /wp-cron.php&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;SetOutputFilter CACHE&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;AddOutputFilterByType DEFLATE text/html text/plain text/css application/javascript application/rss+xml text/xml image/svg+xml&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="the-config-explained"&gt;The config explained&lt;/h3&gt;&#10;&lt;p&gt;OK, we&amp;rsquo;ve got the config, now lets go through it&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-apache" data-lang="apache"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;CacheQuickHandler&lt;/span&gt; &lt;span class="k"&gt;off&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The CacheQuickHandler directive controls the phase in which the cache is handled.&lt;/p&gt;&#10;&lt;p&gt;In the default enabled configuration, the cache operates within the quick handler phase. This phase short circuits the majority of server processing, and represents the most performant mode of operation for a typical server. The cache bolts onto the front of the server, and the majority of server processing is avoided.&lt;/p&gt;&#10;&lt;p&gt;When disabled, the cache operates as a normal handler, and is subject to the full set of phases when handling a server request. While this mode is slower than the default, it allows the cache to be used in cases where full processing is required, such as when content is subject to authorization&lt;/p&gt;&#10;&lt;p&gt;We currently don&amp;rsquo;t want the cache to be processed &amp;ldquo;quickly&amp;rdquo; for reasons we&amp;rsquo;ll explain later ;)&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-apache" data-lang="apache"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;CacheRoot&lt;/span&gt; &lt;span class="sx"&gt;/var/cache/apache2/mod_cache_disk/simonmott.co.uk&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This option simply defines where on disk the cache will be stored - The default for my installation is &lt;strong&gt;/var/cache/apache2/mod_cache_disk&lt;/strong&gt; but I opted to split the cache by vhost so that I have slightly finer control (For example, I can completely clear the cache for my website by removing the contents of &lt;strong&gt;/var/cache/apache2/mod_cache_disk/simonmott.co.uk&lt;/strong&gt; which shouldn&amp;rsquo;t affect the cache for another website)&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-apache" data-lang="apache"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;CacheEnable&lt;/span&gt; disk /&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This option simply enables the cache for any URL under this domain. If you wanted to only cache for simonmott.co.uk/test then you would use &amp;ldquo;/test&amp;rdquo; instead of &amp;ldquo;/&amp;rdquo;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheDirLevels &lt;span class="m"&gt;2&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheDirLength &lt;span class="m"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CacheMaxFileSize &lt;span class="m"&gt;2000000&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;-- This is 2MB&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This set of options controls how many files can be stored on disk and the max-file size that can be committed to cache. &lt;strong&gt;CacheDirLevels&lt;/strong&gt; specifies how many levels of subdirectory there should be, and &lt;strong&gt;CacheDirLength&lt;/strong&gt; specifies how many characters should be in each directory. With the example settings given above, the hash would be turned into a filename prefix as /var/cache/apache2/mod_cache_disk/simonmott.co.uk/x/y/TGxSMO2b68mBCykqkp1w.&lt;/p&gt;&#10;&lt;p&gt;The overall aim of this technique is to reduce the number of subdirectories or files that may be in a particular directory, as most file-systems slow down as this number increases. With setting of &amp;ldquo;1&amp;rdquo; for &lt;strong&gt;CacheDirLength&lt;/strong&gt; there can at most be 64 subdirectories at any particular level. With a setting of 2 there can be 64 * 64 subdirectories, and so on. Unless you have a good reason not to, using a setting of &amp;ldquo;1&amp;rdquo; for &lt;strong&gt;CacheDirLength&lt;/strong&gt; is recommended.&lt;/p&gt;&#10;&lt;p&gt;Setting &lt;strong&gt;CacheDirLevels&lt;/strong&gt; depends on how many files you anticipate to store in the cache. With the setting of &amp;ldquo;2&amp;rdquo; used in the above example, a grand total of 4096 subdirectories can ultimately be created. With 1 million files cached, this works out at roughly 245 cached URLs per directory. &lt;strong&gt;CacheMaxFileSize&lt;/strong&gt; controls the max size of a file that can be stored (in bytes).&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-apache" data-lang="apache"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;CacheIgnoreNoLastMod&lt;/span&gt; &lt;span class="k"&gt;On&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;CacheDefaultExpire&lt;/span&gt; &lt;span class="m"&gt;7200&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;strong&gt;CacheIgnoreNoLastMod&lt;/strong&gt; directive provides a way to specify that documents without last-modified dates should be considered for caching, even without a last-modified date. If neither a last-modified date nor an expiry date are provided with the document then the value specified by the &lt;strong&gt;CacheDefaultExpire&lt;/strong&gt; directive will be used to generate an expiration date.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-apache" data-lang="apache"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;CacheIgnoreCacheControl&lt;/span&gt; &lt;span class="k"&gt;On&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;CacheIgnoreCacheControl On&lt;/strong&gt; tells the server to attempt to serve the resource from the cache even if the request from a client contains no-cache header value&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-apache" data-lang="apache"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;CacheLastModifiedFactor&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;.5&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the event that a document does not provide an expiry date but does provide a last-modified date, an expiry date can be calculated based on the time since the document was last modified with the &lt;strong&gt;CacheLastModifiedFactor&lt;/strong&gt; directive&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-apache" data-lang="apache"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;CacheIgnoreHeaders&lt;/span&gt; Set-Cookie Cookie&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;CacheIgnoreHeaders&lt;/strong&gt; specifies additional HTTP headers that should not to be stored in the cache. For example, it makes sense in some cases to prevent cookies from being stored in the cache.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-apache" data-lang="apache"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;CacheHeader&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When the &lt;strong&gt;CacheHeader&lt;/strong&gt; directive is switched on, an &lt;strong&gt;X-Cache&lt;/strong&gt; header will be added to the response with the cache status of this response.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-apache" data-lang="apache"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;CacheLock&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;strong&gt;CacheLock&lt;/strong&gt; directive enables the thundering herd lock for the given URL space.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-apache" data-lang="apache"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;CacheDisable&lt;/span&gt; &lt;span class="sx"&gt;/wp-admin&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;CacheDisable&lt;/span&gt; &lt;span class="sx"&gt;/wp-login.php&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;CacheDisable&lt;/span&gt; &lt;span class="sx"&gt;/wp-cron.php&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;strong&gt;CacheDisable&lt;/strong&gt; directive instructs mod_cache to not cache urls at or below url-string. The values I&amp;rsquo;ve chosen here &lt;em&gt;&lt;strong&gt;ARE&lt;/strong&gt;&lt;/em&gt; specific to WordPress&lt;/p&gt;&#10;&lt;p&gt;The last two lines in my config for &lt;strong&gt;SetOutputFilter&lt;/strong&gt; and &lt;strong&gt;AddOutputFilterByType&lt;/strong&gt; is where things get interesting and this one requires some more in-depth explanation&amp;hellip;&lt;/p&gt;&#10;&lt;h3 id="mod_deflate-and-the-vary-header"&gt;mod_deflate and the &lt;em&gt;Vary&lt;/em&gt; header&lt;/h3&gt;&#10;&lt;p&gt;Because of where mod_cache initially sits, if you enable mod_deflate and your visitor sends appropriate &amp;ldquo;&lt;strong&gt;Accept-Encoding&lt;/strong&gt;&amp;rdquo; headers then mod_deflate will dutifully compress the output for you, but this happens before mod_cache saves it. This isn&amp;rsquo;t a big problem because mod_deflate adds a &amp;ldquo;&lt;strong&gt;Vary: accept-encoding&lt;/strong&gt;&amp;rdquo; header to the output, thus mod_cache will store a separate cached copy of your content for each variation of the &amp;ldquo;Accept-Encoding&amp;rdquo; header it encounters. This method does mean that ALL processing is cached - dynamic content generated by PHP is saved, so no need to process the request again and CPU time to compress the output has already been done which to some is ideal and you can stop here without adding the last two lines above.&lt;/p&gt;&#10;&lt;p&gt;I however don&amp;rsquo;t like the idea of multiple copies of the same page - If I visit a page on my Desktop using Chrome, I want the same page when I visit on my Phone using Chrome. The problem here is that Chrome for desktop sends &lt;code&gt;Accept-Encoding: gzip, sdch&lt;/code&gt; whereas Chrome for Android sends &lt;code&gt;Accept-Encoding: gzip, sdch, br&lt;/code&gt; which is a different variation of the header, thus they get two separate copies processed and cached, despite having an already cached copy that is of suitable encoding. Something to also consider is the vector for a DoS by filling my server with files based on lots of different &lt;code&gt;Accept-Encoding&lt;/code&gt; headers&lt;/p&gt;&#10;&lt;p&gt;Depending on how popular your website is, you could end up with hundreds of copies for a single page cached because of the differing headers and for my site, that just doesn&amp;rsquo;t sit right with me. Documentation &lt;a href="https://httpd.apache.org/docs/current/mod/mod_cache.html#finecontrol"&gt;here&lt;/a&gt; suggests you can defer mod_deflate until after your content has been saved in the cache, however this doesn&amp;rsquo;t seem to work - It spits an error about duplicate &amp;ldquo;CACHE&amp;rdquo; filters and just continues as normal, compressing then caching.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;[cache:debug] [pid 9497] mod_cache.c(1718): [client 10.0.0.20:40156] AH00777: cache: CACHE filter was added twice, or was added where the cache has been bypassed and will be ignored: /&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I have a work-around, but it does have a caveat which I&amp;rsquo;ll get to shortly - I have also approached Apache httpd mailing lists, but as of yet I don&amp;rsquo;t have a solid fix for this but for now the workaround is:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-apache" data-lang="apache"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;SetOutputFilter&lt;/span&gt; CACHE&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;AddOutputFilterByType&lt;/span&gt; DEFLATE text/html text/plain text/css application/javascript application/rss+xml text/xml image/svg+xml&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To the best of my knowledge (as the docs are a bit sketchy here), &lt;strong&gt;SetOutputFilter&lt;/strong&gt; will force all output to be passed through the &lt;strong&gt;CACHE&lt;/strong&gt; filter; Doing this here ensures content is saved to our cache first and we then conditionally pass through &lt;strong&gt;DEFLATE&lt;/strong&gt; for text-based content (As that generally compresses well). Sounds exactly like what I want, right?&lt;/p&gt;&#10;&lt;p&gt;Well&amp;hellip; Not quite.&lt;/p&gt;&#10;&lt;p&gt;It seems that doing this combination of output filters means that content is actually being saved into our cache before mod_expires has chance to add correct cache-control headers and specific expires headers. This just means that all content is being cached for the duration of &lt;strong&gt;CacheDefaultExpire&lt;/strong&gt;, instead of what I try to set via mod_expires. The headers do eventually get added though so at least our visitors browsers will cache content correctly :)&lt;/p&gt;&#10;&lt;p&gt;For the time being I can live with this behaviour, but as mentioned earlier, I will probably be looking to move my web stack over to nginx so this will suffice until then.&lt;/p&gt;&#10;&lt;h3 id="conclusion"&gt;Conclusion&lt;/h3&gt;&#10;&lt;p&gt;So, we have caching all set up and working, but is it making a difference? Well - Once a page is requested, but its not cached (a MISS), the request will process as normal and return output to the visitor. Subsequent requests are served from cache so no processing is needed.&lt;/p&gt;&#10;&lt;p&gt;Once all this was set up, I visited my website which generated the page and stored it in cache - My average page loading time from earlier was &lt;strong&gt;0.696s&lt;/strong&gt;, so lets see what it is now its in cache&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;simon@kinmu:~$ i=0; while [ $i -lt 5 ]; do time -p curl &amp;#34;https://www.simonmott.co.uk/&amp;#34; &amp;gt; /dev/null; sleep 1; i=$[$i+1]; done 2&amp;gt;&amp;amp;1 | grep real | awk &amp;#39;{print $2}&amp;#39; | awk &amp;#39;{avg += ($1 - avg) / NR;} END {print &amp;#34;Average: &amp;#34; avg &amp;#34;s&amp;#34;;}&amp;#39;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Average: 0.036s&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Thats an impressive &lt;strong&gt;19x&lt;/strong&gt; improvement on average page loading time!&lt;/p&gt;&#10;&lt;p&gt;I&amp;rsquo;d say its working nicely ;)&lt;/p&gt;</description></item><item><title>Full screen Flash Video on Linux</title><link>https://www.simonmott.co.uk/2013/08/full-screen-flash-video-linux/</link><pubDate>Mon, 05 Aug 2013 00:01:23 +0000</pubDate><guid>https://www.simonmott.co.uk/2013/08/full-screen-flash-video-linux/</guid><description>&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2016/05/ghex.png"&gt;&lt;img alt="ghex" class="img-right" height="226" src="https://www.simonmott.co.uk/images/2016/05/ghex-300x226.png" width="300"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;So here we have it - I&amp;rsquo;ve finally got around to tackling this issue which has been bugging me for a while.&lt;/p&gt;&#10;&lt;p&gt;When watching a flash video in full screen on dual monitors, as soon as you go off to do something else you will soon notice that your video is no longer full screen! How annoying.&lt;/p&gt;&#10;&lt;p&gt;The way to fix this is to edit the flash player binary. Firstly you need a hex editor - I use &amp;ldquo;ghex&amp;rdquo;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; sudo apt-get install ghex&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can of course use your hex editor of choice.&lt;/p&gt;&#10;&lt;p&gt;Now that we have that sorted, its time to find our flash binary! Start playing a flash video and then see which plugin is open.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; lsof -n &lt;span class="p"&gt;|&lt;/span&gt; grep -i flash&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; firefox 4655 simon mem REG 8,1 17418724 1966425 /usr/lib/flashplugin-installer/libflashplayer.so&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Open this file with your hex editor and look for the following string:&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;_NET_ACTIVE_WINDOW&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once you have this found, change any of the letters - In my case I changed it to:&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;__ET_ACTIVE_WINDOW&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Save and re-open your browser and you should be able to watch full screen video in flash player whilst doing other things!&lt;/p&gt;&#10;&lt;p&gt;This will need to be re-applied every time you update flash.&lt;/p&gt;&#10;&lt;p&gt;A final note about this modification:&lt;/p&gt;&#10;&lt;p&gt;Chrome (not Chromium) uses its own built in flash plugin called PepperFlash which doesn&amp;rsquo;t have &amp;ldquo;_NET_ACTIVE_WINDOW&amp;rdquo;, so if you want this fix to work with Google Chrome, enter &amp;ldquo;chrome://plugins/&amp;rdquo; in the url bar, then click &amp;ldquo;Details&amp;rdquo; on the right, scroll to the Adobe Flash Player plugin and 2 versions should be listed; disable the one that has &amp;ldquo;/opt/google/chrome/PepperFlash/libpepflashplayer.so&amp;rdquo; as its path. Doing this, Google Chrome will use the system Adobe Flash Player and not the built-in Google Chrome Adobe Flash Player.&lt;/p&gt;&#10;&lt;p&gt;Enjoy&lt;/p&gt;</description></item><item><title>UN2400 Mobile Broadband on Ubuntu 11.10</title><link>https://www.simonmott.co.uk/2012/03/un2400-mobile-broadband-ubuntu-11-10/</link><pubDate>Sun, 11 Mar 2012 09:09:32 +0000</pubDate><guid>https://www.simonmott.co.uk/2012/03/un2400-mobile-broadband-ubuntu-11-10/</guid><description>&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2016/05/un2420.png"&gt;&lt;img alt="un2420" class="img-right" height="298" src="https://www.simonmott.co.uk/images/2016/05/un2420-300x298.png" width="300"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;I have a HP Compaq Mini 311c-1030SA netbook with ION. I decided to encrypt it the other day just on the off chance it was stolen that way I would be happy that none of my data would be lost.&lt;/p&gt;&#10;&lt;p&gt;It had the orignal OS (Windows XP Home) and Kubuntu Linux in a dual boot configuration. Windows encrypted nicely with TrueCrypt and I decided to start fresh with Linux as the version I had installed was fairly old and as far as I am aware there is no way to on the fly encrypt a currently installed distro.&lt;/p&gt;&#10;&lt;p&gt;Lets just say that due to a slip of the hand I somewhat destroyed my encrypted Windows partition! (Foolishly, one of the first things I did when i got the netbook a few years ago was remove the recovery partition for more HDD space too)&lt;/p&gt;&#10;&lt;p&gt;This isn&amp;rsquo;t really a big problem for me as I hardly ever used the Windows install. Here is the clincher though, the netbook has a Qualcomm UN2400 Mobile Broadband chip which requires the firmware to be uploaded to the chip based off what country/carrier you plan on using. This firmware and some of the ppp configuration scripts are installed onto the Windows partition&amp;hellip; which I had just destroyed!&lt;/p&gt;&#10;&lt;p&gt;Getting the firmware was not a problem as I downloaded the driver from the HP website and extracted the .msi file to get what I needed. For convenience the firmware can be obtained &lt;a href="https://www.simonmott.co.uk/images/2012/03/un2400.tar.gz"&gt;here&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;Now that I have the firmware images on my netbook again I can follow the guide written by my good friend, Dataforce. This can be located on his website, &lt;a href="http://blog.dataforce.org.uk/2010/08/ubuntu-on-hp-compaq-mini-311c-1030sa/"&gt;blog.dataforce.org.uk&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;To save you all some time here is what I did to get mine working (Mostly taken from Dataforce&amp;rsquo;s website):&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; Install gobi-loader&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; sudo apt-get install gobi-loader&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; Create missing directory&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; sudo mkdir -p /lib/firmware/gobi&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; Use full paths &lt;span class="k"&gt;for&lt;/span&gt; gobi_loader&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; sudo sed -i &amp;#39;s@&amp;#34;gobi_loader@&amp;#34;/lib/udev/gobi_loader@&amp;#39; /lib/udev/rules.d/60-gobi.rules&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; Copy firmware to the device&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; sudo cp /home/simon/HP/UMTS/amss.mbn /lib/firmware/gobi/&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; sudo cp /home/simon/HP/UMTS/apps.mbn /lib/firmware/gobi/&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; sudo cp /home/simon/HP/6/uqcn.mbn /lib/firmware/gobi/&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; Stop modemmanager corrupting the firmware whilst it is being uploaded by blacklisting the non-modem version of the device&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; echo &amp;#39;ATTRS{idVendor}==&amp;#34;03f0&amp;#34;, ATTRS{idProduct}==&amp;#34;241d&amp;#34;, ENV{ID_MM_DEVICE_IGNORE}=&amp;#34;1&amp;#34;&amp;#39; &amp;gt;&amp;gt; /lib/udev/rules.d/77-mm-usb-device-blacklist-custom.rules&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As a breif explanation I use the image in the &amp;ldquo;6&amp;rdquo; folder as it is listed on &lt;a href="http://h20566.www2.hp.com/hpsc/doc/public/display?lang=en&amp;amp;cc=us&amp;amp;docId=emr_na-c01738839"&gt;HP&amp;rsquo;s Support Pages&lt;/a&gt; as &amp;ldquo;Generic UTMS (Europe)&amp;rdquo; however I suggest you take a look and choose whats best for you.&lt;/p&gt;&#10;&lt;p&gt;Restart your machine and check you have the correct number of ttyUSB devices&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; ls /dev/ttyUSB*&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; /dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyUSB2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The hard part is done! All that is left is, in my case at least, to use the build in KDE NetworkManager check that the &amp;ldquo;Mobile Broadband&amp;rdquo; tab is no longer disabled and follow the wizard for creating a new mobile broadband connection for your contry/carrier.&lt;/p&gt;</description></item><item><title>VPN Bonding</title><link>https://www.simonmott.co.uk/2012/03/vpn-bonding/</link><pubDate>Mon, 05 Mar 2012 13:44:22 +0000</pubDate><guid>https://www.simonmott.co.uk/2012/03/vpn-bonding/</guid><description>&lt;p&gt;This page details step by step how I accomplished aggregating two separate internet connections into one, seemingly single, connection to the Internet. This &amp;ldquo;single&amp;rdquo; connection has a greater bandwidth capacity that either of the individual connections could yield. As a side affect this also nicely doubles up as a redundant connection. This method can be used for achieving link aggregation for both home and business users alike for a fraction of the cost of commercial connections / aggregation units available that do the same thing and in theory could be expanded to as many links you like however be warned, the more links there are, the more overheads there will be with tunnelling; thus potentially noticeable drops in speed.&lt;/p&gt;&#10;&lt;p&gt;For this demonstration I am using two Virtual Machines via &lt;a href="http://virtualbox.org/"&gt;VirtualBox&lt;/a&gt;. This enables me to experiment with without cutting my servers off from remote administration. Both machines are running &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu 10.04.3 LTS (Lucid)&lt;/a&gt; however there is no reason this wont work for other distributions as long as you modify the steps accordingly.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Just to get this out of the way. I am not responsible for anything you might break. Be cautious when playing around with routing tables/network interfaces especially with remote servers as it could potentially cause loss of connectivity which might not be a simple fix.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;h3 id="requirements"&gt;Requirements&lt;/h3&gt;&#10;&lt;p&gt;Firstly, we will cover the requirements needed for this demonstration:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Linux bonding driver on both machines (see Initial Setup)&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Server with a fat internet connection. I have a server in a Data Center with 100Mbit link that I use.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;The remote server ideally needs to have two or more IP addresses accessible (see routing for details why)&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Two or more Internet connections at the site you wish to create the aggregated connection&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Server at the site you wish to aggregate that you can use as a Gateway device&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;strong&gt;*NB, This article is now quite old. I&amp;rsquo;ve heard that newer versions of ifenslave break this now*&lt;/strong&gt;&lt;/p&gt;&#10;&lt;h3 id="how-it-works"&gt;How It Works&lt;/h3&gt;&#10;&lt;p&gt;The idea behind this is quite simple and has been around for a long time. Think of it in terms of plumbing. You have a narrow pipe from your house (Your ISP), to the drain outside (The Internet). This pipe can only carry so much water (Information) to its destination at any given moment. If you add another pipe and link them together you are essentially allowing both pipes between them to carry more to the destination, thus increasing throughput.&lt;/p&gt;&#10;&lt;p&gt;The only initial problem with this is that each of the connections to your ISP have their own routes and IP addresses. You cant simply have multiple connections to one ISP and have it magically work (Unless your ISP supports Channel Bonding and will set it up for you). What this guide aims to do (continuing from the analogy above), is wrap both pipes together with tape so that from inside the house and outside, they appear as one and carry more down tham then a single pipe on its own.&lt;/p&gt;&#10;&lt;p&gt;The solution is to create a VPN tunnel to your fat pipe endpoint via each connection. Once the tunnels have been bonded it will act as one interface. Your remote fat pipe server will appear as one IP address but all traffic to that new IP address is being split down both links and vice versa. Once at the other end, as its VPN tunnelled, your server will see it as originating from the same IP inside your network, regardless of the route it takes. This then enables you to route it to the Internet and back with ease.&lt;/p&gt;&#10;&lt;h3 id="diagram"&gt;Diagram&lt;/h3&gt;&#10;&lt;p&gt;This diagram summarizes the setup we are trying to achieve:&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2016/05/vpn-bonding-diagram.png"&gt;&lt;img alt="VPN Bonding Diagram" class="img-center" height="213" src="https://www.simonmott.co.uk/images/2016/05/vpn-bonding-diagram.png" width="767"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;h3 id="initial-setup"&gt;Initial Setup&lt;/h3&gt;&#10;&lt;p&gt;First off we&amp;rsquo;ll install the bonding driver onto &lt;strong&gt;both servers&lt;/strong&gt;. This is nice and simple: (Note # represents a command as root)&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; apt-get install ifenslave&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As we want to aggregate the multiple connections into one seemingly single link, I will be using Bonding mode 1, aka &lt;strong&gt;balace-rr&lt;/strong&gt;. To enable this, we need to edit the &lt;strong&gt;/etc/network/interfaces&lt;/strong&gt; file and add the following:&lt;/p&gt;&#10;&lt;p&gt;Note that my local subnet is &lt;strong&gt;10.0.0.0/8&lt;/strong&gt; and so it is clear when I am using the tunnel, my VPN subnet will be &lt;strong&gt;172.26.0.0/30&lt;/strong&gt;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;local-server# pico /etc/network/interfaces&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt;This should be added to the config file&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; iface bond0 inet static&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; address 172.26.0.2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; netmask 255.255.255.252&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; bond-slaves tun0 tun1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; bond_mode balance-rr&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And the remote server:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;remote-server# pico /etc/network/interfaces&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt;This should be added to the config file&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; iface bond0 inet static&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; address 172.26.0.1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; netmask 255.255.255.252&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; bond-slaves tun0 tun1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; bond_mode balance-rr&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As a brief explanation, &lt;strong&gt;balance-rr&lt;/strong&gt; does not load balance connections but actually load balances the packets.&lt;/p&gt;&#10;&lt;p&gt;This might seem backwards to some people but when all is said and done, we will be forwarding all internet traffic to 172.26.0.1 thus that would be our gateway. As a rule of thumb gateway&amp;rsquo;s are always the first IP in the subnet&amp;hellip; (Usually)&lt;/p&gt;&#10;&lt;h3 id="routing"&gt;Routing&lt;/h3&gt;&#10;&lt;p&gt;For this to work, we need to ensure that we have separate connections to our endpoint. These separate connections need to travel through each internet connection. For arguments sake, I have two ADSL connections and thus two routers on my network - &lt;strong&gt;10.0.0.1&lt;/strong&gt; and &lt;strong&gt;10.0.0.254&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;p&gt;My fat pipe endpoint also needs to have two IP addresses. For this example - 87.117.217.27 and 87.117.217.44. These will enable me to ensure that my tunnels are routed via separate ISPs.&lt;/p&gt;&#10;&lt;p&gt;On my local server I need to do the following:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;local-server# ip route add 87.117.217.27 via 10.0.0.1 dev eth0&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;local-server# ip route add 87.117.217.44 via 10.0.0.254 dev eth0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note: If you want to aggregate more than two connections, using this method you would need the same number of remote IP addresses as you do Internet connections to ensure that traffic is sent via each interface.&lt;/p&gt;&#10;&lt;p&gt;Please be aware that this is by no means an elegant solution&amp;hellip;&lt;/p&gt;&#10;&lt;h3 id="creating-vpn-tunnels---using-ssh"&gt;Creating VPN Tunnels - Using SSH&lt;/h3&gt;&#10;&lt;p&gt;I originally decided to use SSH tunnels when I was playing around with bonding as both of my servers already had OpenSSH installed which meant no messing about installing/configuring OpenVPN (SSH is so versatile!). The only caveat to this method is that it requires you to allow SSH Logins via Root. It is also worth noting that using SSH Tunnels for the VPN connections essentially means you are tunnelling TCP over TCP which can potentially have a lot of overheads, especially via SSH due to the encryption and compression should you use it. See &lt;a href="http://sites.inka.de/~W1011/devel/tcp-tcp.html"&gt;this article&lt;/a&gt; for some more information.&lt;/p&gt;&#10;&lt;p&gt;At this stage I&amp;rsquo;d like to point out that whilst I did use SSH, you can potentially use any VPN/Tunnelling technology such as OpenVPN - as long as you get a tun/tap interface that you can use with the bonding driver. That is however out of the scope of this article. If you will be using another technology or protocol to create your tun or tap devices then you can skip ahead to Bonding the links&lt;/p&gt;&#10;&lt;p&gt;As mentioned at the top of this page, my end point is in a Data Center. It is however a VM running on my server. Primarily this was to prevent me from losing access to my machine if I broke things however it also adds the security of, if the machine is compromised, the intruder doesn&amp;rsquo;t have access to any of my services.&lt;/p&gt;&#10;&lt;p&gt;Never the less, we will secure it as much as possible&amp;hellip; You need to edit your &lt;strong&gt;/etc/ssh/sshd_config&lt;/strong&gt; file on your &lt;strong&gt;Remote Server&lt;/strong&gt; and change/add the following:&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code class="language-ssh-config" data-lang="ssh-config"&gt;PermitRootLogin without-password&#10;PermitTunnel yes&#10;PasswordAuthentication no&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once that is done, add some keys from your local server to your remote server so that you can ssh to the root account. More information on SSH Keys can be found here or simply by googling.&lt;/p&gt;&#10;&lt;p&gt;Once you have confirmed that you can SSH to the root account of the remote server &lt;strong&gt;from the root account of your local server&lt;/strong&gt; you are ready to go.&lt;/p&gt;&#10;&lt;p&gt;We will be making use of the &lt;strong&gt;-w&lt;/strong&gt; parameter of ssh. This will create a tunX interface on both ends that we will later bond together.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;local-server# ssh -NTCf -w 0:0 87.117.217.27&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;local-server# ssh -NTCf -w 1:1 87.117.217.44&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;-N Do not execute a remote command. This is useful for just forwarding ports (or in this case tunnels).&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;-T Disable pseudo-tty allocation.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;-C Requests compression of all data (including stdin, stdout, stderr, and data for forwarded X11 and TCP connections). Compress can speed up or potentially slow down your speed, so try with and without.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;-f Requests ssh to go to background just before command execution.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;If this is successful, &lt;strong&gt;ifconfig -a&lt;/strong&gt; on both machines should reveal a &lt;strong&gt;tun0&lt;/strong&gt; and &lt;strong&gt;tun1&lt;/strong&gt; interface!&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; ifconfig -a&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; POINTOPOINT NOARP MULTICAST MTU:1500 Metric:1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; RX packets:0 errors:0 dropped:0 overruns:0 frame:0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; TX packets:0 errors:0 dropped:0 overruns:0 carrier:0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; collisions:0 txqueuelen:500&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;tun1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; POINTOPOINT NOARP MULTICAST MTU:1500 Metric:1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; RX packets:0 errors:0 dropped:0 overruns:0 frame:0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; TX packets:0 errors:0 dropped:0 overruns:0 carrier:0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; collisions:0 txqueuelen:500&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Great! Now we can proceed to bonding them.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: It might be advisable at this time to check netstat to ensure that you have connections coming in from separate ISPs:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;remote-server# netstat -an &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="s2"&gt;&amp;#34;:22&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; grep ESTABLISHED&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; tcp &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;48&lt;/span&gt; 87.117.217.27:22 66.118.190.24:54284 ESTABLISHED&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; tcp &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; 87.117.217.27:22 78.33.121.161:50165 ESTABLISHED&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; tcp &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; 87.117.217.44:22 92.40.207.249:56158 ESTABLISHED&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The bold addresses are my tunnels and the other is a terminal I have open to execute netstat. The command I used shows only connections on port 22 (default ssh port) and will only show Established ones. Looks like we are good to go!&lt;/p&gt;&#10;&lt;h3 id="bonding-the-links"&gt;Bonding the links&lt;/h3&gt;&#10;&lt;p&gt;This part is relatively easy now all the heavy lifting is done. As mentioned above, we have created a bond0 interface on both servers that have two (or potentially more) slaves, tun0 and tun1. To bring this interface up we simply execute the following on &lt;strong&gt;both servers&lt;/strong&gt;&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;This should be done on both servers:&#10;&#10;# ifup bond0&#10; # ifconfig bond0&#10; bond0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00&#10; inet addr:172.26.0.X Bcast:172.26.0.3 Mask:255.255.255.252&#10; UP BROADCAST RUNNING MASTER MULTICAST MTU:1500 Metric:1&#10; RX packets:41 errors:0 dropped:0 overruns:0 frame:0&#10; TX packets:2 errors:0 dropped:0 overruns:0 carrier:0&#10; collisions:0 txqueuelen:0&#10; RX bytes:8054 (8.0 KB) TX bytes:168 (168.0 B)&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Presto! Both interfaces are now up and running. You can test to ensure it is working by trying to ping each other&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; ping 172.26.0.1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; PING 172.26.0.1 (172.26.0.1) 56(84) bytes of data.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 64 bytes from 172.26.0.1: icmp_seq=1 ttl=64 time=28.3 ms&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 64 bytes from 172.26.0.1: icmp_seq=2 ttl=64 time=28.2 ms&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 64 bytes from 172.26.0.1: icmp_seq=3 ttl=64 time=25.9 ms&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next you ned to remove the default gateway of your local server (if there is one) and tell it to use the remote server&amp;rsquo;s VPN address as its gateway instead:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;local-server# ip route del 0.0.0.0/0&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;local-server# ip route add 0.0.0.0/0 via 172.26.0.1 dev bond0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;All that is left is to enable ipv4 forwarding on &lt;strong&gt;both servers&lt;/strong&gt; and add a route back to your internal network on the remote server and then you should be all set for using the local server as a gateway for the internet!&lt;/p&gt;&#10;&lt;p&gt;To enable:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;This should be &lt;span class="k"&gt;done&lt;/span&gt; on both servers:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# sysctl net.ipv4.ip_forward=1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To enable permanently:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;This should be &lt;span class="k"&gt;done&lt;/span&gt; on both servers:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# echo &amp;#34;net.ipv4.ip_forward=1&amp;#34; &amp;gt;&amp;gt; /etc/sysctl.conf&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And then to tell the remote server how to get back to our network so that our requests get answered:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;remote-server# ip route add 10.0.0.0/8 via 172.26.0.2 dev bond0&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A pinch of iptables hackery:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;remote-server# iptables -A FORWARD -o eth0 -i bond0 -s 10.0.0.0/8 -m conntrack --ctstate NEW -j ACCEPT&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;remote-server# iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;remote-server# iptables -A POSTROUTING -t nat -o eth0 -j MASQUERADE&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Your local server should now be able to access the world wide web. Note that this server should, in this example at least, have an IP in the 10.0.0.0/8 subnet. That is the IP you use for your gateway on all your other machines to allow them to use the aggregated link.&lt;/p&gt;&#10;&lt;p&gt;I will at a later stage document automating the whole process as much as I can and have some form of connection monitoring in case the ADSL links stop working. Watch this space!&lt;/p&gt;&#10;&lt;h3 id="nat"&gt;NAT&lt;/h3&gt;&#10;&lt;p&gt;If everything was done correctly, your bonded link should be up and running. Your remote server should be able to &amp;ldquo;see&amp;rdquo; your local server via its VPN IP address and vice versa! If this is the case then most of the leg work has been done for you.&lt;/p&gt;&#10;&lt;p&gt;All outgoing connections to the internet from your local server should now be appearing as if they are from your remote server&amp;rsquo;s IP address, in my example, 87.117.217.27. (You can quickly test this by using &lt;a href="http://www.whatismyip.com/"&gt;whatismyip.com&lt;/a&gt;). Lets say that you want to access a web page that you have set up on the local server that gives statistics about your setup. We will use iptables to acheive this:&lt;/p&gt;&#10;&lt;p&gt;We are assuming that your remote server connects to the internet via &lt;strong&gt;eth0&lt;/strong&gt;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;remote-server# iptables -A PREROUTING -t nat -i eth0 -p tcp -m tcp --dport &lt;span class="m"&gt;80&lt;/span&gt; -j DNAT --to-destination 172.26.0.2:80&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once this is done, any connection to http://87.117.217.27 should be transparently forwarded down your bonded link to the other end which should serve your web page.&lt;/p&gt;&#10;&lt;p&gt;This could also be expanded to, for example, allow Windows Remote Desktop to one of your internal computers to be accessible via the bonded link, or any service inside your LAN to be accessible from the publicly routable address of your remote server&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;remote-server# iptables -A PREROUTING -t nat -i eth0 -p tcp -m tcp --dport &lt;span class="m"&gt;3389&lt;/span&gt; -j DNAT --to-destination 10.0.0.60:3389&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: For the example above for forwarding RDP connections, the PC you are forwarding to will need to have its gateway set to the 10.0.0.0/8 address of the machine hosting the bonded link else it wont know where to send the responses to.&lt;/p&gt;&#10;&lt;p&gt;I found &lt;a href="http://www.karlrupp.net/en/computer/nat_tutorial"&gt;Karl Rupp&amp;rsquo;s NAT page&lt;/a&gt; to be helpful in explaining NAT with iptables!&lt;/p&gt;</description></item><item><title>Office 2010, KMS Activation and Domain Relationships</title><link>https://www.simonmott.co.uk/2012/02/office-2010-kms-activation-domain-relationships/</link><pubDate>Tue, 28 Feb 2012 21:33:51 +0000</pubDate><guid>https://www.simonmott.co.uk/2012/02/office-2010-kms-activation-domain-relationships/</guid><description>&lt;p&gt;Whilst this seems trivial to some people, not only did this issue affect my office, but one of our branches in India too so I figure its worth noting somewhere!&lt;/p&gt;&#10;&lt;p&gt;My current employer has many operating companies (OpCo&amp;rsquo;s) dotted around the world, all under one brand. Because of this structure, our OpCo in the UK has a two way trust relationship between our domain and the parent company&amp;rsquo;s. For arguments sake, lets call them UKNET and CENTRALNET.&lt;/p&gt;&#10;&lt;p&gt;At the end of last year we were told to use a Microsoft KMS server hosted on CENTRALNET to install Office 2010 on some of our workstations. Easy.. or so we thought.&lt;/p&gt;&#10;&lt;p&gt;On UKNET we have our own DNS servers and for the SRV type that we need, they were infact misconfigured. This lead to our Office installs refusing to activate!&lt;/p&gt;&#10;&lt;p&gt;The easiest way to check it is working correctly is on a PC on UKNET (adapt to meet your own needs of course):&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;C:&lt;span class="se"&gt;\&amp;gt;&lt;/span&gt;nslookup -type&lt;span class="o"&gt;=&lt;/span&gt;srv _vlmcs._tcp.example.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Server: dns.example.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Address: 192.168.1.1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Non-authoritative answer:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; _vlmcs._tcp.example.com SRV service location:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;priority&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1688&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; svr &lt;span class="nv"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; kms.example.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the above snippet, example.com is the FQDN for your domain. A result like the one above implies that your machine is being told where to go for the KMS activation and as long as you can communicate with kms.example.com, you are good to go! (Cue trusty telnet!!)&lt;/p&gt;&#10;&lt;p&gt;If however, you are not getting any results from your DNS server, you can either change your DNS settings to one that does give the correct result or simply tell Office where to go to activate!&lt;/p&gt;&#10;&lt;p&gt;For this, I will just be letting Office know where to go. You need to complete your install and then on the target machine run:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bat" data-lang="bat"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cscript &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;%ProgramFiles%&lt;/span&gt;&lt;span class="s2"&gt;\Microsoft Office\Office14\ospp.vbs&amp;#34;&lt;/span&gt; /sethst:kms.example.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that Office14 is version specific and is in fact Office 2010. No doubt this figure will change for newer versions but for now this works.&lt;/p&gt;&#10;&lt;p&gt;Once the above command has completed successfully simply launch an application from the suite and check its activation status. If all went well, you should have a nice activated version of office!&lt;/p&gt;</description></item><item><title>LAN Events!</title><link>https://www.simonmott.co.uk/2011/04/lan-events/</link><pubDate>Fri, 22 Apr 2011 23:14:29 +0000</pubDate><guid>https://www.simonmott.co.uk/2011/04/lan-events/</guid><description>&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2016/05/lan_big.jpg"&gt;&lt;img alt="lan_big" class="img-right" height="225" src="https://www.simonmott.co.uk/images/2016/05/lan_big-300x225.jpg" width="300"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;For those of you that know me fairly well, you would know that over the last 5-6 years i have attended a number of LAN events hosted by &lt;a href="http://www.multiplay.co.uk/"&gt;MultiPlay.co.uk&lt;/a&gt;. Whilst I decided to take a break from the event last year we have jumped back on the band wagon again and are here for this years Spring event, i42.&lt;/p&gt;&#10;&lt;p&gt;To be truthful the group of us that agreed to attend this year decided this would be a meet up primarily aimed at coding &lt;a href="http://www.dmdirc.com/"&gt;DMDirc&lt;/a&gt; and as yet that coding remains to be seen. For the time being we have succumbed to the usual shenanigans that befalls a LAN event - Lots of junk food, lots of video games, lots of random shouting, &amp;ldquo;&lt;a href="http://www.urbandictionary.com/define.php?term=hax"&gt;Hax!&lt;/a&gt;&amp;rdquo; or &amp;ldquo;&lt;a href="http://www.urbandictionary.com/define.php?term=rofl"&gt;ROFL!&lt;/a&gt;&amp;rdquo; (Pronounced roffle) as a brief example and general other tom foolery.&lt;/p&gt;&#10;&lt;p&gt;I must admit all things aside i do enjoy the atmosphere shared at a LAN especially when you are surrounded by friends&lt;/p&gt;&#10;</description></item><item><title>Me, myself and I</title><link>https://www.simonmott.co.uk/2011/03/me-myself-and-i/</link><pubDate>Tue, 22 Mar 2011 06:49:13 +0000</pubDate><guid>https://www.simonmott.co.uk/2011/03/me-myself-and-i/</guid><description>&lt;p&gt;As you have have discovered, I&amp;rsquo;m not especially big on blogging. I lead quite a mundane (or at least I think so) life compared to some other people I know. That said I feel I should share at least something new!&lt;/p&gt;&#10;&lt;p&gt;I had some advise from a few of my closest peers to which the &amp;ldquo;jist&amp;rdquo; was the need to not sit on my arse and at least try to better myself. As of a few days ago I made the decision to look into the possibility of gaining some professional certifications. I am looking to start a career in the IT industry and, partly because of where I live (and my unwillingness to just get up and move) and my lack of industrial experience &amp;hellip; its not going very well.&lt;/p&gt;&#10;&lt;p&gt;I feel pursuing these certifications will not only aid me in the career department (eventually) but the knowledge and mindset of &amp;ldquo;I did that&amp;rdquo; would boost my view of my own self worth and improve me as a person.&lt;/p&gt;&#10;&lt;p&gt;Admittedly this is all talk currently. As some of you know, most of the time my &amp;ldquo;bark&amp;rdquo; has no &amp;ldquo;bite&amp;rdquo; to put it bluntly.&lt;/p&gt;&#10;&lt;p&gt;I am hoping to achieve the following certifications:&lt;/p&gt;&#10;&lt;p&gt;Microsoft Certified Technology Specialist (MCTS)&lt;/p&gt;&#10;&lt;p&gt;Windows Server 2008 Network Infrastructure Configuration (70-642)&lt;/p&gt;&#10;&lt;p&gt;Windows Server 2008 Active Directory Configuration (70-640)&lt;/p&gt;&#10;&lt;p&gt;CompTIA Linux+ (Exams LX0-101 and LX0-102) - with the aim of furthering this to LPIC-1&lt;/p&gt;&#10;</description></item><item><title>"Nexus One - Web meets Phone"</title><link>https://www.simonmott.co.uk/2010/04/nexus-one-web-meets-phone/</link><pubDate>Wed, 21 Apr 2010 20:46:21 +0000</pubDate><guid>https://www.simonmott.co.uk/2010/04/nexus-one-web-meets-phone/</guid><description>&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2016/05/N1.jpg"&gt;&lt;img alt="N1" class="img-right" height="225" src="https://www.simonmott.co.uk/images/2016/05/N1-300x225.jpg" width="300"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;On Monday my shiny new &lt;a href="http://en.wikipedia.org/wiki/Nexus_One"&gt;Nexus One&lt;/a&gt; phone finally arrived!&lt;/p&gt;&#10;&lt;p&gt;The phone was ordered on 14th April but with all the recent disruptions to air traffic caused by the icelandic volcano, &lt;a href="http://en.wikipedia.org/wiki/Eyjafjallajokull"&gt;Eyjafjallajökull&lt;/a&gt;, delivery of my phone was delayed.&lt;/p&gt;&#10;&lt;p&gt;Overall I am really impressed with the phone. It&amp;rsquo;s a lot more zippy than my older &lt;a href="http://en.wikipedia.org/wiki/HTC_Dream"&gt;G1&lt;/a&gt; and looks one hell of a lot nicer too. The UI is pretty similar to the G1&amp;rsquo;s Android 1.6 but there are some significant differences. Most notably are the 2 extra home screens, giving the phone a total of 5 screens instead of 3. The AMOLED is sharp, bright and most importantly, larger which makes a nice change as it is a pleasure to look at. The phone is nicely weighted (not too heavy, not too light) and feels sturdy.&lt;/p&gt;&#10;&lt;p&gt;All this was expected though, given how long Android has been available on mobile devices and I think that Google and HTC have had ample time to perfect on the design. On the note of the design, one thing I (and probably many others) consider to be a flaw is the SDcard slot. You have to remove the battery to get at the card which is&amp;hellip; not useful.&lt;/p&gt;&#10;&lt;p&gt;On the plus side however, I found the voice recognition very accurate with no training what so ever. I&amp;rsquo;ve spent a few hours crazily talking to my phone&amp;hellip;&lt;/p&gt;&#10;&lt;p&gt;If you have any questions, please feel free to contact me (when the contact form works) or simply ask Google to lend its wisdom.&lt;/p&gt;&#10;</description></item><item><title>Logical Volume Manager - LVM</title><link>https://www.simonmott.co.uk/2010/03/logical-volume-manager-lvm/</link><pubDate>Thu, 11 Mar 2010 20:25:03 +0000</pubDate><guid>https://www.simonmott.co.uk/2010/03/logical-volume-manager-lvm/</guid><description>&lt;p&gt;This page covers some of the basics of using LVM. Please ensure that you back up any important data on any had drive or partition you wish to use for LVM.&lt;/p&gt;&#10;&lt;p&gt;I take no responsibility for any data loss if you choose to use any of the commands on this page&lt;/p&gt;&#10;&lt;h3 id="installation"&gt;Installation&lt;/h3&gt;&#10;&lt;p&gt;For the purposes of this guide, I am using &lt;strong&gt;Ubuntu Hardy 8.04&lt;/strong&gt; and the package manager &lt;strong&gt;apt&lt;/strong&gt; but this should work with any installation of LVM&lt;/p&gt;&#10;&lt;p&gt;First off, you need to install LVM. For my install it was as simple as:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; apt-get install lvm2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once this is complete you should have a working install of LVM. To check, look for the following binaries&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; which lvcreate&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; /sbin/lvcreate&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; $ which pvcreate&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; /sbin/pvcreate&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; $ which vgcreate&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; /sbin/vgcreate&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you do not have the three binaries above then you need to double check you installed LVM correctly.&lt;/p&gt;&#10;&lt;h3 id="setup"&gt;Setup&lt;/h3&gt;&#10;&lt;p&gt;The very first thing you need to do (After backing up any data that needs to be backed up of course) is decide which disks or partitions you wish to use. Once this is done we need to set the correct type of partition for use with LVM. In my example, I will be using a partition that takes up an entire disk.&lt;/p&gt;&#10;&lt;p&gt;To set up the partition we use &lt;strong&gt;fdisk&lt;/strong&gt;. As root we need to:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; fdisk /dev/sda&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;The number of cylinders for this disk is set to 1125.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; There is nothing wrong with that, but this is larger than 1024,&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; and could in certain setups cause problems with:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 1) software that runs at boot time (e.g., old versions of LILO)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 2) booting and partitioning software from other OSs&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; (e.g., DOS FDISK, OS/2 FDISK)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Command (m for help):&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you already have any partitions on this disk you should remove them by typing d and selecting each partition as they are listed.&lt;/p&gt;&#10;&lt;p&gt;Once this is done, we need to create a new partition&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Command (m for help): n&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Command action&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; e extended&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; p primary partition (1-4)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; p&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Partition number (1-4): 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; First cylinder (1-1125, default 1):&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Using default value 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Last cylinder or +size or +sizeM or +sizeK (1-1125, default 1125):&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Using default value 1125&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Command (m for help):&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And then we change its type to &lt;strong&gt;Linux LVM&lt;/strong&gt;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Command (m for help): t&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Selected partition 1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Hex code (type L to list codes): 8e&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Changed system type of partition 1 to 8e (Linux LVM)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Command (m for help):&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To finalize the partitioning, we type &lt;strong&gt;w&lt;/strong&gt;:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Command (m for help): w&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; The partition table has been altered!&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Calling ioctl() to re-read partition table.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Syncing disks.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This step will need to be repeated for every disk (or partition) you wish to use in your LVM Array.&lt;/p&gt;&#10;&lt;h3 id="pvcreate"&gt;pvcreate&lt;/h3&gt;&#10;&lt;p&gt;Once all your disks have been partitioned you need to write LVM Superblock headers into them, this is done with the &lt;strong&gt;pvcreate&lt;/strong&gt; command:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; pvcreate /dev/sda1 /dev/sdb1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Physical volume &amp;#34;/dev/sda1&amp;#34; successfully created&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Physical volume &amp;#34;/dev/sdb1&amp;#34; successfully created&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Thats it, you now have all the nessecery information for LVM Arrays in the superblocks of the disks. This will be amended at a later stage automatically by LVM to include the UUIDs for each disk/partition in the event of an array failure.&lt;/p&gt;&#10;&lt;h3 id="vgcreate"&gt;vgcreate&lt;/h3&gt;&#10;&lt;p&gt;Now that is overwith we need to create a volume group to house the logical disk. In this example I am going to use a volume group of &lt;strong&gt;VolGrp001&lt;/strong&gt; and a logical disk name of &lt;strong&gt;LogVol001&lt;/strong&gt;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; vgcreate VolGrp001 /dev/sda1 /dev/sdb1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Volume group &amp;#34;VolGrp001&amp;#34; successfully created&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="lvcreate"&gt;lvcreate&lt;/h3&gt;&#10;&lt;p&gt;Now we need to create the new logical volume and add it to the newly created volume group.&lt;/p&gt;&#10;&lt;p&gt;Whilst there are many more options available with these commands I&amp;rsquo;ve omitted most of them for ease. Feel free to have a play around, just take note to be careful as if you mess something up you could lose all the data you have on the hard drives you are trying to use in an LVM Array.&lt;/p&gt;&#10;&lt;p&gt;To create the new array we use the following (the flag after LogVol001 is a lowercase L):&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; lvcreate --name LogVol001 -l 100%VG VolGrp001&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Rounding up size to full physical extent 2793.96 GB&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Logical volume &amp;#34;LogVol001&amp;#34; created&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Thats it, all the hard work of setting up LVM is done. All that is left is to make it contain a usable format and then stand in awe as you have a huge, seemingly single disk to store all your data&lt;/p&gt;&#10;&lt;p&gt;In most cases, I would imagine you want to use the newly created LVM Device for data storage. My Choice of filesystem is &lt;strong&gt;ext3&lt;/strong&gt; however you can use any you like along with any settings you choose.&lt;/p&gt;&#10;&lt;p&gt;To create a useable ext3 format on the LVM Device we use &lt;strong&gt;mkfs.ext3&lt;/strong&gt;:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; mkfs.ext3 -m &lt;span class="m"&gt;0&lt;/span&gt; /dev/VolGrp001/LogVol001&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above command might take some time depending on how large the array is and how well your disks perform. It&amp;rsquo;s worth noting that the -m 0 option gives you some more space. By default ext3 reserves 5% of the total space for the super user. If you are using this to store data the super user would not need this&lt;/p&gt;&#10;&lt;p&gt;Once this is done you can now happily mount the new file system and start using it (&lt;strong&gt;/mnt/lvm&lt;/strong&gt; is my mount point of choice):&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; mount /dev/VolGrp001/LogVol001 /mnt/lvm&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="extending-lvm-devices"&gt;Extending LVM Devices&lt;/h3&gt;&#10;&lt;p&gt;So, you&amp;rsquo;ve had your LVM Device up and running for a while and it&amp;rsquo;s starting to get full. You can happily add extra disks/partitions to your LVM device.&lt;/p&gt;&#10;&lt;p&gt;Firstly, as with creating a new LVM Array you need to &lt;a href="#setup"&gt;partition the disk&lt;/a&gt; to &lt;strong&gt;Linux LVM&lt;/strong&gt;. This is done with the &lt;strong&gt;pvcreate&lt;/strong&gt; command:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; pvcreate /dev/sdc1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Physical volume &amp;#34;/dev/sdc1&amp;#34; successfully created&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The next tast will be to add the new disk or partition to the same Volume Group as the Logical volume we want to extend. To do this we use the &lt;strong&gt;vgextend&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;WARNING&lt;/strong&gt;: It is recommended that before you make any modifications to a logical volume that you unmount it first&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; vgextend VolGrp001 /dev/sdc1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;/dev/sdc1&lt;/strong&gt; has now been added to the volume group. Now we need to extend the size of the logical volume (the same as earlier, this flag is a lowercase L)&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; lvextend -l +100%FREE /dev/VolGrp001/LogVol001 /dev/sdc1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above adds 931.32GB of usable space to the Logical Volume and tells it where this space actually is, /dev/sdc1. The next task is to resize the partition to fill the Device. It is the same as if you were resizing an ext3 patition on a physical disk. First we check the file system for errors (Make sure it is unmounted first) and then we resize the partition to take up the entirety of the disk space available&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; e2fsck -f /dev/VolGrp001/LogVol001&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;#&lt;/span&gt; resize2fs /dev/VolGrp001/LogVol001&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Again, this make take some time depending on the size of the file system and how well your hard drives perform. Once all this is done however, you&amp;rsquo;re ready to go. Re mount the file system and it should have increased by 931.32GB or whatever you increased it by.&lt;/p&gt;</description></item><item><title>Java Development</title><link>https://www.simonmott.co.uk/2010/01/java-development/</link><pubDate>Sun, 24 Jan 2010 18:45:05 +0000</pubDate><guid>https://www.simonmott.co.uk/2010/01/java-development/</guid><description>&lt;p&gt;Yesterday, I took my first official steps at attempting to learn Java. It has been on the back of my mind for a long time (since the days of Visual Basic 6) but I have just never settled into it; Yes, I&amp;rsquo;ve tinkered, but never anything serious.&lt;/p&gt;&#10;&lt;p&gt;Thanks to some of my long time friends I now have a place to develop my skills and a place to get assistance as and when I need it. Since early 2007 they have been on-off developing an alternate &lt;a href="http://en.wikipedia.org/wiki/Internet_Relay_Chat"&gt;IRC client&lt;/a&gt; for Linux that happens to be cross platform with a wide selection of operating systems due to it being Java based. In my opinion their client has far surpassed any IRC client that I&amp;rsquo;ve ever come across. If you don&amp;rsquo;t agree, keep watching, you soon will!&lt;/p&gt;&#10;&lt;p&gt;The client can be located at &lt;a href="http://www.dmdirc.com/"&gt;DMDirc.com&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;The project has since moved to Github so check it out &lt;a href="https://github.com/DMDirc/DMDirc"&gt;here&lt;/a&gt;&lt;/p&gt;&#10;</description></item><item><title>Happy New Year</title><link>https://www.simonmott.co.uk/2010/01/happy-new-year/</link><pubDate>Fri, 01 Jan 2010 13:23:22 +0000</pubDate><guid>https://www.simonmott.co.uk/2010/01/happy-new-year/</guid><description>&lt;p&gt;Happy new year.&lt;/p&gt;&#10;&lt;p&gt;This year has been full of interesting things for all of us and today is the start of yet another. I hope you&amp;rsquo;re all not too stuffed on turkey as it all goes back to normal Monday, wouldn&amp;rsquo;t want you falling down the stairs as you cant support yourself! There is lots to be done this year.&lt;/p&gt;&#10;</description></item><item><title>OpenSSH</title><link>https://www.simonmott.co.uk/2009/09/openssh/</link><pubDate>Sat, 05 Sep 2009 23:49:45 +0000</pubDate><guid>https://www.simonmott.co.uk/2009/09/openssh/</guid><description>&lt;p&gt;Here you will find some tips and tricks for OpenSSH that I found useful. Note that the instructions on this page do not cover all the capabilities of OpenSSH and I advise you to use these commands at your own risk.&lt;/p&gt;&#10;&lt;h2 id="ssh-aliases"&gt;SSH Aliases&lt;/h2&gt;&#10;&lt;p&gt;If, like me, you have lots of servers and find it quite tedious to continually type &amp;ldquo;&lt;strong&gt;ssh &lt;a href="mailto:admin@server1.co.uk"&gt;admin@server1.co.uk&lt;/a&gt;&lt;/strong&gt;&amp;rdquo; for all your servers, Aliases might be a god send!&lt;/p&gt;&#10;&lt;p&gt;To add an alias is really simple. Below is an example of an alias that shortens &amp;ldquo;&lt;strong&gt;ssh &lt;a href="mailto:admin@server1.co.uk"&gt;admin@server1.co.uk&lt;/a&gt;&lt;/strong&gt;&amp;rdquo; to &amp;ldquo;&lt;strong&gt;ssh s1&lt;/strong&gt;&amp;rdquo; (This can be further shortened with bash aliases which, at present, are not covered here).&lt;/p&gt;&#10;&lt;p&gt;To do this, put the following in &lt;strong&gt;/home/simon/.ssh/config&lt;/strong&gt;:&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code class="language-ssh-config" data-lang="ssh-config"&gt;Host s1&#10; HostName server1.co.uk&#10; User admin&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For a full and complete list of config options see &amp;ldquo;&lt;strong&gt;man ssh_config&lt;/strong&gt;&amp;rdquo; on your server&lt;/p&gt;&#10;&lt;h2 id="keys"&gt;Keys&lt;/h2&gt;&#10;&lt;p&gt;SSH keys allow you greater security whilst at the same time giving you easier access to machines you regularly need to SSH to. Keys come in pairs, you have a Public key and a Private key, Which as suggested, Private keys are, well, pivate and Public keys are public.&lt;/p&gt;&#10;&lt;p&gt;To generate a key pair, using your local machine type the following:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; ssh-keygen -t rsa -b &lt;span class="m"&gt;2048&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Doing this will ask you to enter a pass phrase. At this stage it might be worth noting, if you provide a pass phrase, the key will not be usable for passwordless logins with SSH (e.g executing remote commands). If you want security, enter a pass phrase. It is recomended this be a sentence with a mix of words, numbers and symbols such as &amp;ldquo;!&amp;rdquo;.&lt;/p&gt;&#10;&lt;p&gt;If you want to use this key for passwordless logins just simply press &lt;strong&gt;Return&lt;/strong&gt; on your keyboard.&lt;/p&gt;&#10;&lt;p&gt;Once this is done you should be told that the key has been created successfully and you should also now have the location of the key pair&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;Your identification has been saved in /home/simon/.ssh/id_rsa.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Your public key has been saved in /home/simon/.ssh/id_rsa.pub.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; The key fingerprint is:&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; 91:c3:7f:d7:af:d1:e5:69:b4:fa:07:1f:17:8b:90:fe simon@shinobu&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It is recomended that you never put your &lt;strong&gt;id_rsa&lt;/strong&gt; anywhere that cannot be trusted. Whilst in most cases it is only you that has access to your home folder, Superusers such as root can also.&lt;/p&gt;&#10;&lt;p&gt;To install a key onto a server you want to ssh to, simply put the contents of &lt;strong&gt;id_rsa.pub&lt;/strong&gt; into &lt;strong&gt;/home/simon/.ssh/authorized_keys&lt;/strong&gt; and change its permissions to 600 (rw&amp;mdash;&amp;mdash;-)&lt;/p&gt;&#10;&lt;p&gt;We have a handy built in script called &lt;strong&gt;ssh-copy-id&lt;/strong&gt; which does all that for you. Assuming your public key is in &lt;strong&gt;/hom/simon/.ssh/id_rsa.pub&lt;/strong&gt; then just type the following into a console:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; ssh-copy-id -i /home/simon/.ssh/id_rsa.pub admin@yourserver.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You should now be prompted for your password. Once successfully logged in you will see something similar to:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Now try logging into the machine, with &lt;span class="s2"&gt;&amp;#34;ssh &amp;#39;admin@yourserver.com&amp;#39;&amp;#34;&lt;/span&gt;, and check in:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; .ssh/authorized_keys&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; to make sure we haven&lt;span class="s1"&gt;&amp;#39;t added extra keys that you weren&amp;#39;&lt;/span&gt;t expecting.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above copies the contents of your &lt;strong&gt;id_rsa.pub&lt;/strong&gt; to your server, appends its contents to your &lt;strong&gt;authorized_keys&lt;/strong&gt; file (or creates one if needed) and changes its permissions&lt;/p&gt;&#10;&lt;p&gt;Once this has been done try to SSH to your server and if you created the key with a pass phrase, you should be prompted for it. If you created a phrase-less key then you should be allowed into your server without any prompt.&lt;/p&gt;&#10;&lt;p&gt;If you fail to log in with the correct key then the OpenSSH daemon will, by default, revert to password authentication. If you do not want this to happen, please see below&lt;/p&gt;&#10;&lt;h2 id="agent-and-agent-forwarding"&gt;Agent and Agent Forwarding&lt;/h2&gt;&#10;&lt;p&gt;Whilst having keys with pass phrases are more secure than standard passwords, it can be extremely monotonous to have to type it in every time you want to do anything that requires SSH especially if the phrase is a long sentance with symbols. To avoid this, we use &lt;strong&gt;ssh-agent&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;In order for us to be able to use SSH and not type a pass-phrase in we need to add our identity (see &lt;a href="http://old.simonmott.co.uk/openssh#keys"&gt;keys&lt;/a&gt;) to our agent session. This needs to be done every time your desktop is started.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; ssh-add&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt; Identity added: /home/simon/.ssh/id_rsa (/home/simon/.ssh/id_rsa)&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once this is done, you will only need to type your pass phrase in once. You can SSH to your server and log out as many times as you want, it will only ask for the phrase once!&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Agent Forwarding&lt;/strong&gt; can be useful when you need to SSH to a server to work on. Lets say you need to then copy a file from that server to another, but the other server only allows access with SSH keys. You can forward your key to the new server without having to open a complete new SSH connection from your local machine. To do this all you need to do is add your identity to ssh-agent (see above) and add a flag to your SSH command:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; ssh -A admin@yourserver.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;strong&gt;-A&lt;/strong&gt; flag tells SSH to forward your identity which is stored on the server (assuming the server has Agent forwarding enabled). If keys are set up correctly you should be allowed access to this server without hiccup. Whilst connected to this server you can test SSH forwarding by trying to SSH to another server that has your Public key (see &lt;a href="http://old.simonmott.co.uk/openssh#keys"&gt;keys&lt;/a&gt;).&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gp"&gt;$&lt;/span&gt; ssh admin@yourotherserver.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If everything is set up correctly then you should now be on &lt;strong&gt;yourotherserver.com&lt;/strong&gt; without having to type any passwords!&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;SECURITY NOTE:&lt;/strong&gt; Using agent forwarding can leave you open to &amp;ldquo;Agent Hijacking&amp;rdquo;. Whilst this does not give anyone your Key it does leave the doors open for them to use your Forwarded information to access servers you would normally have access to with your key. For more info please read this article: &lt;a href="http://unixwiz.net/techtips/ssh-agent-forwarding.html#sec"&gt;Security Issues with Key Agents&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Iggy Woes</title><link>https://www.simonmott.co.uk/2009/09/iggy-woes/</link><pubDate>Fri, 04 Sep 2009 07:22:27 +0000</pubDate><guid>https://www.simonmott.co.uk/2009/09/iggy-woes/</guid><description>&lt;p&gt;&lt;a href="https://www.simonmott.co.uk/images/2009/09/iggy_broken_leg-02.09.09.jpg" target="_blank"&gt;&lt;img alt="iggy_broken_leg-02.09.09" class="img-right" height="300" src="https://www.simonmott.co.uk/images/2009/09/iggy_broken_leg-02.09.09-225x300.jpg" width="225"/&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;I have a pet Iguana called Iggy. Its a female &lt;a href="http://en.wikipedia.org/wiki/Green_Iguana"&gt;Green Iguana&lt;/a&gt; and over the weekend she broke her leg, badly. (See image to the right)&lt;/p&gt;&#10;&lt;p&gt;I was in Milton Keynes over the bank holiday weekend with the #MDBot Group (&lt;a href="irc://uk.quakenet.org/mdbot"&gt;Quakenet&lt;/a&gt;). We arrived on Saturday at about midday and we left the next day in the afternoon. Milton Keynes is, on average about 2.5 to 3 hours away from me so leaving at 15:15 meant I wouldn&amp;rsquo;t get home till early evening.&lt;/p&gt;&#10;&lt;p&gt;When I eventually arrived home after having a relaxing 1.5 hour bus journey from Milton Keynes Central to Birmingham International, my pet Iguana did her usual routine of coming over to me to say hello which, in her world means she wants me to make a fuss of her and usually give her some food. After I had spent 5 or so minutes rubbing some dead skin off her back and prepairing some cress for her to munch on, I sat at my computer and proceeded to catch up on some of the TV shows I had missed over the weekend. After a short while I noticed Iggy was climbing down onto the floor (Which isnt unusual, she likes a good wander), as she walked around the side of the desk I saw her leg was the size of a rugby ball&amp;hellip;&lt;/p&gt;&#10;&lt;p&gt;As this was a Sunday Evening, taking her to our local vet was out of the question. They charge £90 to look at anything out of hours, which doesn&amp;rsquo;t include the cost of any extras involved such as X-rays. I was stuck as this would also apply for the Monday which was a bank holiday. Some of you may wonder why I didn&amp;rsquo;t take her and spend the £90. Quite frankly, I cant afford it. My Iguana was moving around fine, she was keeping her weight off her leg so I decided I would do what I could to restrict her movement and to take her to the vet during normal working hours.&lt;/p&gt;&#10;&lt;p&gt;I managed to get an appointment for earlier today at a vet that deals with reptiles, Rose Cottage in Runcorn. After an examination and being advised what the issue was, I obtained the X-ray image above. As you can see the break is a relatively nasty one and is broken into three pieces. I am a bit disappointed that it wasn&amp;rsquo;t something less serious, as god only knows what will happen if the break doesn&amp;rsquo;t start to heal properly in the next 4 weeks.&lt;/p&gt;&#10;&lt;p&gt;Once I have taken her back to the vet to have it looked at again I will post another update, just in case anyone is interested!&lt;/p&gt;</description></item><item><title>My Website</title><link>https://www.simonmott.co.uk/2009/08/my-website/</link><pubDate>Sun, 02 Aug 2009 22:48:36 +0000</pubDate><guid>https://www.simonmott.co.uk/2009/08/my-website/</guid><description>&lt;p&gt;Well, just in case you didn&amp;rsquo;t realize, this is my website. For the most part it is about myself or things I enjoy. I will use this site to host facts/statistics about me and also things that will, in the future, help me with things I may have forgotten (for example, config files, command arguments for things like iptables etc).&lt;/p&gt;&#10;&lt;p&gt;If you find any of these pages useful please feel free to link to them. If you are sad and have no life like me feel free to subscribe to my RSS Feed.&lt;/p&gt;&#10;&lt;p&gt;If you have any suggestions please feel free to pop them over to me via the contact form (when it works) or alternately via IRC in #agari on Quakenet.&lt;/p&gt;&#10;&lt;p&gt;Thats about it for introductions, more to come (soon I hope!)&lt;/p&gt;&#10;</description></item></channel></rss>