15 April 2016

The Journey to Rick 3.0 Alpha

The Major Update
Introducing Rick v3.0 alpha (or "How I had a mental breakdown, but it got better")
In Vienna, on the Sunday morning after a good few days of unusually intense physical activity, mental activity on Ingress and heavy social interaction, I had a complete mental collapse. I went to pieces, utterly unable to interact with the world, and frankly looked less than pretty. I was incapable of much else than sniffles and looking incredibly sorry for myself, and utterly lost any cognitive ability. I cracked, and had a complete mental breakdown.

This was a good thing.


That might sound strange, but it’s been coming for a long, long time. I've been a mess for years, as many of my friends will be able to attest. Up and down like a yo-yo, and running on empty, just about getting from one day to the next, struggling to get up in a morning, and generally in a bit of a broken state. My personality massively suffered, as I didn't have the energy to power it. I struggled to interact with people in person, and sometimes even online.


After the break in Vienna, the following happened:

  • I began a complete mental rebuild, guided and helped by some close friends who also had been through similar experiences, and providing perspective into my mental processes, and helping me identify the flaws in them so I could correct them.
  • I was talked through the flaws in my mental schemas, and where I was filling in faulty data without realising when I had insufficient initial data, and have seen how I've managed to create flawed data recognition over time because I was essentially looking at it through a distortion lens, and had extra bits of light coming in that shouldn't have been there and dark patches where there shouldn't have been. So to speak.
  • I had several wobbles over the week, and still am having a few, but they’re getting better.
  • I fixed my diet. Mostly.
  • I pretty much dumped alcohol.
  • Rediscovered what mornings are. That confused the hell out of me. Apparently my body thinks a lie in now is 7:30AM.
  • I actually adopted normal working hours instead of turning up “at some point before 10 and working 7 and a half hours”. This has massively increased the amount of time I have to myself to relax and do things, and can even leave work early if I arrive early.
  • I also seem to have discovered the concept of "on time" and "early". It's rather confusing.
  • I rediscovered my braincells. The change in my mental processes is remarkable.
  • I remembered how to be good at my job, and rediscover my skill set. It’s been a ridiculously long time since I've worked to my potential. I'm not there yet, but I'm a hell of a lot closer than I have been in the last 10 years.
  • I've started to listen to my body when it is tired, and actually sleeping instead of pushing myself, or pumping myself full of coffee.
  • I saw my mum. (Hi mum!) Had a chicken kebab on a pitta bread, coffee, and a good chat. It was lovely.
  • Dealt with some previous social awkwardness I’d had, and it turned out it was a total miscommunication. Felt really good to squash it, I'm going to work on any other such issues as I see them, and now the stress from that has dissipated.
  • I've been drinking more water. It’s good for you.
  • Finally started to understand a lot of social interaction and behaviour that I never quite understood before. It’s like my social skills have finally been reawakened.
  • Started to finally feel like myself in work after several years, and appear to have finally got over the damage from my previous several workplaces.I feel like I've escaped my cocoon and become a beautiful... moth. Or something like that. (I'm a beautiful butterfly!)
Some things I've really struggled with:

  • Don’t worry about things that happen over time, but have had no lasting effects other than leaving things to tidy up, or things to repair. By things, I mean objects, not people. Things are, at the end of the day, just things. Devices can be repaired. Rooms can be cleaned. Cars can be fixed.
  • Don’t torture yourself over things that have happened or your previous behaviour. This I'm really struggling with, but I'm working on it. Looking back over the last… well, 18 years, frankly, I have utterly beaten myself up repeatedly for my actions, and the damage I've caused, especially now I can truly see it all. I'm so very close to hating myself… but it’d achieve nothing. More to follow below on that one.
  • It’s okay not to get on with everyone. Not everyone is going to get along with everyone else, it’s a simple fact, personalities are different, needs are different. It’s not some sort of rejection, like I always used to think it was. And sometimes it’s just because people don’t really understand each other. That’s okay. Diversity is good.
  • I don’t need validation from others to be happy. Over the years, I've desperately sought attention because I wanted to be wanted, needed, loved… desperate for acknowledgement and that feeling of being close to someone, even if just for an instant, be that with friends, lovers, relationships, you name it. And it’s made me do some pretty stupid shit. I can’t make excuses, it was me, but it doesn't stop me wanting to utterly weep over some of the things I've done, which I can’t easily forgive myself for, and frankly I'm not sure I should. But at the same time, holding on to that self-hatred is going to achieve me nothing, no matter how much I beat myself up - I'm just going to end up bruised. The worst thing is that I've been desired and loved. I just couldn't see it for more than a moment at a time, or my brain in its twisted little mess couldn't accept it properly, and ran instead of embracing. So many times I wish I'd done things differently, if I'd only been able to see... but I may as well have been walking around with a blindfold on, with my fingers in my ears, shouting "la la la" at the top of my voice.
  • Having ideas that are different from other people’s ideas is okay. I don’t need to fit in with society’s definition of norms, nor do I have to comply with other people’s opinions. Ironically, I suspect people would respect me far more for having my own thoughts and opinions, and if people can’t respect my opinions or disagree with them to the point where they feel they can no longer associate with me… that’s also okay. I’d rather people were truthful with me than not. I work far better with simple facts without the window dressing, as most people who know how my brain works will attest to.
  • I need to be aware that new shiny things may catch my attention, but I've previously accidentally accidentally trampled on people to get to them, or worse, not even really seen them in the way. Risk management is essential.
  • I'm no longer afraid of experiencing life because of damaging fragile things around me. I've been trapped in my own cage for far too long, and when I did occasionally escape, because it was so concentrated, it was often like having the gas on far too long, and finally lighting a flame. The mental equivalent of losing my eyebrows, and smelling burnt nostril hair for weeks.
  • Sometimes I'm simply not aware of the social consequences of what I do. I'm getting a lot better at it, but it’s a consequence of the way my brain is wired. But I've found that telling people, and just being completely up-front and honest, is doing a lot of good on that front. I'm not hiding behind shields and defences I've created any more, I'm strong enough to deal with things as myself.
  • I'm still wobbly. That’s okay. Foundations take time to set, and sometimes need sanding off as you go, and adjusting slightly. Just need to be aware of that, and not pile on too much stuff until they’re solid.

So… that’s a list of stuff that happened. Here’s some thoughts to go with it.


  • I'm not a superhuman. Much though I wish I was, and have tried to run as one. It’s part of how I ended up so broken.
  • I'm actually okay as I am. I don’t need to be anyone else. In fact, being myself - my actual self, not the self I try to be - is pretty cool.
  • In contrast to the above point, myself when running on empty is not cool. At all. I get unsociable, I do stupid things, and without being 100% awake and functioning correctly, I do things that are frankly utterly embarrassing. I'm still trying not to collapse in a heap of self loathing on that one. I've burned bridges, I've made stupid calls (again, usually in relation to the above regarding self validation), and sometimes I've been inconsiderate - and it’s not even been on purpose. It’s because I couldn't see what I was doing to other people. That might sound ridiculous, but when you’re in such a dark hole, you can only really see what’s directly in front of you, not the knock on effects of all the other dominoes you knock over. Some of those dominoes can be picked back up, some are lost forever. The latter I have to accept. It hurts, but at the end of the day, I can accept it or it will eat at me like Chinese water torture. Which I've allowed it to do for years, frankly,
  • I've also been really bad at keeping up with things, keeping them in my calendar, and generally organising anything, as when you're running on empty all the time, you just want to avoid doing anything that requires any sort of effort. I'm sorry to my friends that I've not really been participating in things, and grudgingly at best, I just had nothing to give.
  • I've learned to be kind to myself, like I would be to a friend. I've been far harsher on myself than I would a friend over the years, which I think is fairly normal, and we all do it.
  • I need to remember to relax. While that’s not as big an issue now (I'm the least stressed I've been in as long as I can remember!), I still need to occasionally be poked about it. Taking too much on is far too easy, and downtime is just as important, and not “wasted time”.
  • I've learned that it’s okay to say no to doing things or helping someone if I'm not up to it, or I have other things I have to get done. People aren't necessarily going to think less of me for it.
  • It is absolutely okay not to be okay. It’s okay not to pretend you are okay when you’re not. Holding it together, especially over an extended period of time when you have no energy to do it, isn't good for you. Sometimes you have to let go and fall to bits. And that is okay. Seriously.
  • When you’re not in a good place, not everyone will get it, and not everyone will be open to the idea of you when you’re not at your best. That’s also okay. But some people will. It’s okay to share. It’s okay to actually trust people with what is driving you crazy, and what you don’t think should be shared with anybody, because some people you can trust to take care of you and that information. And sometimes you just need someone to examine the situation from an outside perspective. People often have very relevant experience they can draw upon to help.
  • Related to the previous point, It's okay to lean sometimes if someone extends you an arm, you don't need to worry about accepting it if you trust them, and you know they have your best interests at heart. Sharing is scary, but you know what? It's good. And a lot of people have been through similar stuff. For me, leaning on someone else was incredibly hard, as I viewed it as a sign of weakness. Nothing could be further from the truth - it takes strength to let someone help you take the weight, and once they do, you can work on picking yourself back up and fixing the problems, often with the benefit of a second pair of eyes.
  • If you haven’t got someone you’re comfortable with sharing with, share it with a professional. There is ZERO shame in that - it’d be like being ashamed of going to the gym to change your shape because you don’t like the way it is, or going to the doctor to get treatment for an illness. Seriously. They listen for a living, and they've a lot of experience. It may not be directly relevant, but they will have heard many situations, and seen the results of people working towards making the situations better, and can draw from other people’s experiences to help you. Don’t struggle alone - I did for far too many years, and frankly, it screwed me up, in a huge way. Don’t wait until you fall to pieces, it’s easier to mend something that’s still intact sometimes. If you feel you don’t have anyone to talk to, then you can find someone who can help, and please, please, please don’t feel self conscious about it. Reaching out is sometimes the absolute best thing you can do. (Related link: http://www.mind.org.uk/ - help is a click away, and the first step to getting better.)
  • Related to the previous point, sometimes you can’t mend what’s intact. You have to fall apart. If you can do it safely with someone around, or have someone you can call… please, do so. As a rather wise friend told me when I did… “You’re okay. You just don’t know it yet.” I smiled, and thought “yup, thanks, that feels a touch patronising” - but she was right. And I was okay. Now I'm better than okay. But sometimes you just need someone to stick a blanket around you, tell you it’s okay, and feed you a cup of tea, or water, or something similar. And, in my case, take a nap, before I collapsed on my feet.
  • Be aware that constantly burning the candle on both ends will take its toll. Staying up too late and feeling knackered every morning will have long term effects. When your body is telling you you really should sleep, it’s probably a good idea. If it means you wake up earlier in the morning, it means you have more morning to do stuff. It all balances out.
  • I'm no longer judging myself by everyone else’s values. My own are those that are important, and I've got a pretty decent base value set. Well, when it’s not horribly distorted by being in a dark cave for years and being quite broken.
  • I'm getting out there and living life. Ingress has been a good outlet for me - I’d never have gone to Vienna without it, and I've now got a pile of trips set up, which are actually sounding like fun again.
There’s also two final huge, huge points.
Firstly: Something big that I really have wanted to say for a long time: I am so utterly sorry for those I've hurt over the last several years. I've not intended to. I've been broken, for want of a better way of putting it. It does not excuse my behaviour. I have tortured myself, so many nights I've sat and felt so horrible. I've made so many lousy choices, and I've acted in such a stupid manner as I’ve gone along. I've missed so many opportunities I should have taken, but I collapsed in on myself instead of doing so. I've hurt so many people in my stupid quest for self validation. The idiotic thing is that people did and do care for me, I just couldn't see it beyond those tiny glimpses when it broke through the shadows in my head. I could list a long list of people that I've upset, or hurt, or caused pain to. It brings me to tears, even now, just thinking about what I've done. There’s nothing I can do about it, and it’s going to hurt for a long time, but it’s something I'm going to have to live with and accept. But I am truly, deeply sorry, and hold my hand up. That apology is something I've wanted to write for so long, so very long, but frankly I’ve been afraid to. And I know just how much damage I've caused. I've kicked myself for years. But I could never quite deal with it, it was too big, and pressing down so hard. One day I may forgive myself. I hope those I've hurt can do the same, but I’m realistic, and know that may well not happen. It pains me to know that… but as I’ve said above, I have to live with the things I can’t change, and get on with my life - I’ve only got one, and frankly, it’s bloody short. I could walk out of the door and get run over. I could lose those I care about in a heartbeat. Remember, every day, to care for the people important to you. Including yourself.
I also really appreciate my friends that have put up with me being less than myself. I know I’ve been pretty quiet lately as I got to the bottom of the dark pit, and I’ve not exactly been forthcoming with being social - I just really didn’t have the mental or physical energy, and just interacting with people, even those close to me, was a source of stress. That is something that has changed, and the results will no doubt be more evident over the coming weeks. But bear with me while I adjust to my new found self. Or, more precisely, recovered old self.
Secondly: It is absolutely okay to admit you have mental health issues. I have them. I’m actually a massive way through dealing with them right now. I take things to help me with it. There is NO shame in this - it’s a medical issue. Just because you can’t see it in front of you doesn’t mean it’s any less real, or loses you any respect. And frankly, anyone who thinks that it makes you less of a person needs to take a good hard look at themselves, and wonder why they’re judging you for something that clearly isn’t self inflicted. Would you blame someone that needs a wheelchair to get around for their condition, or someone who needs to take drugs for a condition, or has an allergy to something? If you would… well, make sure you’re not on my friends list, because I sure as hell don’t want contact with you. 
People might be wondering why I’m sharing this so openly. The simple answer is because it’s important, and not enough people do. I’m not ashamed to admit I’ve been through hell and back. I’m not ashamed to hold my hand up. I’m throwing it all out here, totally bare, warts and all, in the hope that it helps other people too. And for everyone out there that’s suffering, please, remember to care for yourself as you would a friend. If you’re suffering… don’t be afraid to reach out, because attempting to deal with it yourself and internalise it all can destroy you - I’m living testament to it. Negative feedback loops can drag you from a happy go lucky nice person through several layers of hell, and make you far from what you really are, and what you want to be.
It’s okay to not be okay. But it’s also okay to talk to someone about it, and be not okay together. Don’t judge yourselves by the society out there that has a seriously distorted view of everything - including themselves. Be kind to yourselves. Hug each other. Love each other. Be yourselves. And remember you have one life - don’t lose it beating yourself up or being trapped in your own head - people out there want to and will help, be it family, friends, professionals, or even someone random you’ve never met in the world online or in a park or in a pub. Share the load, it’s easier when it’s not just you carrying it.

23 March 2016

Hangouts, Android Wear and huge battery drain [unsolved]

Please note: Since I wrote this, I started having issues again. I'll update as I find out more.

I trialled a Moto 360 when they were on offer earlier in the year, and while Android Wear was okay in itself, I wasn't too impressed with the shape, but more importantly, whenever I had the Wear application on my phone, it utterly murdered my battery. Weirdly, it was Hangouts that was keeping one core at 100% all the time, which I found quite odd, but never managed to find an explanation, or get to the bottom of it, although I did submit some bug reports.

Fast forward to now, and I'm back on Android Wear, having accidentally smashed the glass on my SmartWatch 2. And lo and behold, my phone battery was being eaten for breakfast, again, and yet again it was Hangouts.

Much experimentation later, and I finally realised the problem - I had too many active hangouts. Being an Ingress player, this is nothing new, I'm used to having 100+ on the go, but all those hangouts with individuals and groups took their toll when trying to sync. My guess is that the Wear application was trying to sync the huge amount of data to the watch, and kept failing, and kept retrying. I archived off all my non-active conversations. Boom, watch syncs up without falling over and eating my battery on the phone. Victory!

Hope this helps other people from scratching their head as to why their battery life sucks after getting an Android Wear watch, and if they've spotted Hangouts taking up a crazy amount of CPU. Once the initial sync is complete, it seems to have behaved since, but time will tell if that stays the case.

Do let me know if this has affected anyone else out there, or if it's just me...

Edit: Unfortunately, it appears that it was actually the act of clearing the data that solved the problem. After a while, it seems to get stuck again and constantly try to resync with the phone. It's rapidly putting me off using Hangouts altogether, which is a bit of an issue when most of my Ingress game communication is done on there!

Noted another thread relating to this:
https://www.reddit.com/r/AndroidWear/comments/49u6m4/high_hangouts_cpu_usage_since_getting_watch/

Will add more as I find them. This is maddening, there seems to be no source of information on it. Just installed Messenger and disabled Hangouts SMS integration, let's see how we go...

24 October 2015

Enabling BCM43142 Bluetooth on Linux Mint 17.2 and Ubuntu 14.04 LTS (Trusty Tahr)

Recently, I acquired a Thinkpad Edge E545, with the Broadcom hybrid WiFi/Bluetooth mini PCIe card (WiFi reads as wlan0: Broadcom BCM4365 802.11 Hybrid Wireless Controller 6.30.223.248 (r487574), bluetooth reads as usb 4-1: Product: BCM43142A0, USB ID is 105b:e065). The wifi worked fine as soon as I enabled the proprietary drivers in the driver manager, but the bluetooth was having none of it. Cue much frustration.

Based on the instructions and patch at this blog post for getting it working on Debian Jessie, I started to have a go, but I couldn't seem to download the kernel source - the apt-get source commands were pointing at nonexistent releases. Unfortunately, that was down to me failing to add the deb-src lines to apt-get. Once I did that, and actually followed the instructions properly, it sort of worked. But then it still kept downloading newer kernels, which wasn't overly helpful when I just wanted to recompile a module to add to my existing system.

I manually cloned the script, and adapted it to work with the Ubuntu sources from git, with the exact kernel I'm using. I've uploaded a copy of the script plus the patchfile that I modified and set up to automatically clone the Ubuntu kernel version that Mint is using from the LTS repo. Feel free to download it and modify as necessary for kernel versions, I just did a quick and dirty job. It downloads quite a bit of code, as it grabs the whole repo, and it's likely reasonably easy to do it more efficiently, but it did work. As described on the previous blogpost, you'll need hex2hcd compiled, base-devel and git installed, and the hex binary file from a Windows install, e.g. BCM43142A0_001.001.011.0311.0312.hex, which I used.

But, as I'm a kind soul, I've precompiled them, and they're working on my E545. I'm not 100% sure on the legality with the Broadcom binary files, but as they distribute the blobs for Linux anyway, I doubt they'll mind so much. This also builds on the work on the aforementioned blog post, with the script adapted from theirs. This may not work for other USB IDs - you'd need to modify the above script / patch patch appropriately. I hope this saves other people the hassle I went through figuring it out! If you've an aversion to running precompiled binaries from some random site, you're welcome to download the above script, inspect it, and run it to build your own copy - the hashes should match, in theory, with default compile flags.

The binary download for the patched btusb.ko and the firmware (for 14.04 based distros) are here. Run the shell script to install it. Can't guarantee it'll work with your exact configuration, but the script above might it this doesn't. Kernel version was a 3.16 version from memory.

Hope this saves people some hassle, please do drop a comment on the blog if it sorts you out. Good to know if it's saved people some pain. It's the exact binary that made the E545 hardware work.

10 September 2013

Magento dataflow batch exports and parent SKUs of configurable products

At work, I've been scratching my head how to easily batch export and import Magento products. Importing is covered pretty well by <a href="http://sourceforge.net/apps/mediawiki/magmi/index.php?title=Magmi_Wiki">Magmi</a>, but the exports are a bit lacking. Found an extension to add extra abilities to the Dataflow export, including category exports, in here - http://www.magentocommerce.com/boards/viewthread/60113/ - but the one thing I wanted was to be able to export the parent SKUs of complex products, as Magmi can handle them in their own field (simple_skus). However, I then realised I'd done it completely the wrong way around, and I actually needed child products. So I've extended the extension, and thrown it up on GitHub, hopefully it'll save someone else the hassle for either purpose. Seems to work well, but let me know if there's any issues, I'll see what I can do to help.

Usage is the same as the original extension, with the addition of a few options at the bottom:

<action method="unparse" type="exportextension/modifier">
    <var name="remove_line_breaks">true</var>
    <var name="remove_html_tags">true</var>
    <var name="add_categories">true</var>
    <var name="category_field_name">category</var>
    <var name="category_delimiter">#</var>
    <var name="category_first_level">-1</var>
    <var name="category_path_delimiter"><![CDATA[>]]></var>
    <var name="add_absolute_url_to_field">product_url</var>
    <var name="add_image_url_to_field">image_url</var>
    <var name="add_parent_sku">parent_sku</var>
    <var name="add_child_sku">child_skus</var>
    <var name="child_sku_delimiter">,</var>
</action>

remove_line_breaks: if the value of this tag is “true”, linebreaks will be removed from the content 
remove_html_tags: if the value of this tag is “true”, html tags will be removed from the content 
- add_categories: if the value of this tag is “true”, each product will be extended with category names. 
The following tags, are only used, if “add_categories” is “true”. They configure the additional category field: 
category_field_name: this value defines the used name of the category field. The default value of this tag is “category”. This tag is only expedient, if you export the fieldnames aor if you allready have another field with the defaultname “category”. 
category_delimiter: if a product is at more than one categories, each category will added and they will be delimited by this string. The default value is “#”. 
category_first_level: this value defines the level of the first exportable category. If it is 2 or greater, the first category names of the category tree won’t be added to the data. The values 1 and 0 are the same, because there is no level 0 - the root category has level 1. If the value is set to “-1”, only the proper category name will be added to the product. The default value of this tag is “1”. 
category_path_delimiter: if the category paths are exported (category_first_level is not -1), each category at the path will be delimited by this string. The default value is “>”. Example: catA1>catA2#catB1>catB2>catB3 
add_absolute_url_to_field; wit this tag you can set a field name, which will be used to add the absolute product link. if this field does not exists, it will be added. if it exists, it will be overwritten. 
add_image_url_to_field; this tag works at the same way, but exports the absolute image link.
- add_parent_sku: If this field is added, the parent SKU of any simple products associated with a configurable product will be added as a field.
- add_child_skuIf this field is added, the child SKUs of any configurable products will be added as a field. If intended for use with Magmi, this should be named as simple_skus.
- child_sku_delimiter: Delimiter for the add_child_sku field, default if unspecified is a comma.


Limitations: This will only currently pull up the first parent SKU of a simple product, if it is assigned to multiple configurables. I didn't look into that any further at the time. This does not affect child products of configurables, which will be properly seperated by the delimiter specified.


I've uploaded the source to GitHub,at https://github.com/microchip/Magento-ExportExtension - both the main extension code, and a prepackaged version in the package folder. Hope it helps save someone the pain I went through trying to figure this damn thing out. The only answer you seem to find online is "Well, if you're struggling with this, here's an extension we'll sell you to fix the issue!" Open source at its best, huh, guys? Don't get me wrong, I understand the desire to write extensions and make money, but the amount people seem to charge is a bit ridiculous, especially if you only want one feature out of the 10 the extensions that are being peddled do.


Anyway. Rant over...

02 December 2012

Solution to audio on the Toshiba Satellite Pro P100 and Windows 7 64-bit muted on install

I've just had a seriously non-fun few hours arguing with drivers on the Toshiba Satellite Pro P100 (specifically the PSPAEE-00E006EN variant). Had no real issues installing Windows 7 64 bit, didn't really expect to as Vista 32-bit worked perfectly well. 135 updates installed later, including the graphics driver, everything seemed to be working swimmingly.

Except the sound, which while it pretended to play, it clearly was not.

Apparently I was far from alone in this issue. Many forums complained about lack of Vista x64 / Windows 7 x64 failing to work properly with the sound. I tried installing a variety of sound drivers, none of which seemed to actually work, although strangely occasionally I'd try to install one, it'd fail, but the sound would work until I rebooted. Extremely frustrating.

Eventually, after much hunting down and forum crawling, I found this driver from HP - SP40170 - which did actually work. The automatic install program didn't, but installing the driver manually via device manager - update driver - select from a location on disk, and choosing c:\SWSETUP\SP40170\Venice\V64 allowed me to install a working driver, and get sound.

It's not perfect - the sound stops working on suspending the machine, which I haven't figured a solution for yet aside from reboot - but other than that it seems to be working well so far. I'm a bit surprised (and disappointed) that a proper 64-bit driver wasn't released for Vista/7 by Toshiba, but hey, just the way the cookie crumbles with older hardware I guess.

Hope this saves someone else the hours I've had to spend hunting this down.

12 August 2012

FreeNAS, Linux, ZFS, and a lesson in debugging slow file transfers...

A while ago, I had my Proliant N40L server running as my home NAS, on FreeNAS 0.7, which was working rather well as a file server. Didn't have much fun getting the DLNA streaming working properly, but the ZFS implementation was great, the speeds were rapid, and it was quite brilliant. Unfortunately I also used 4x 1TB Seagate Barracuda desktop drives in it, which resulted in one dying after a while with the vibration in the cage. Oops.

So, one rebuilt server later with 4x 3TB WD Red NAS drives, I was ready to build a new tank. Decided to have a go with FreeNAS 8.2, which worked quite well. However, don't be fooled by the out-of-box configuration and built-in tweaker - I had to drop in quite a few optimisations from my old 0.7 setup to get it running quickly. But it was running quite well, it has to be said. There's 8GB of RAM in this box, for context later.

However, after some thought, I decided I wanted to get the Plex Media Server running. Sadly, at the time of writing this, it doesn't support FreeBSD, nor can FreeBSD run it under the Linux emulation as it uses epoll, which isn't supported at the moment on the BSD side. So... I decided to have a go with Linux.

One thing I didn't want to lose from the FreeNAS implementation, which was one of the primary reasons for using it, was ZFS. A while ago I'd discovered ZFS on Linux, a full kernel module for Linux, which neatly sidesteps the licensing issue (ZFS is licenced under the old Sun CDDL, which is incompatible with GPL, which is why ZFS isn't happily in the Linux kernel and doing amazing things). So, installed a copy of Ubuntu 12.04 server onto a USB flash drive via a VM on my PC, booted the microserver up off the USB key, and added the repositories for ZFS on Linux. A couple of quick installs later, and lo and behold, ZFS on Linux. Surprisingly, the performance outdid both FreeNAS implementations, although that could be other factors at work at this point:

FreeNAS 0.7

freenas:/mnt/tank# dd if=/dev/zero of=./testfile bs=1M count=10K
10240+0 records in
10240+0 records out
10737418240 bytes transferred in 87.457035 secs (122773637 bytes/sec) - 117MB/sec write
freenas:/mnt/tank# dd if=./testfile of=/dev/null bs=1M
10240+0 records in
10240+0 records out
10737418240 bytes transferred in 60.337002 secs (177957437 bytes/sec) - 169MB/sec read

FreeNAS 0.8 (before tweaks)
[root@freenas] /mnt/storage# dd if=/dev/zero of=./testfile bs=1M count=10K && dd if=./testfile of=/dev/null bs=1M
10240+0 records in
10240+0 records out
10737418240 bytes transferred in 225.523565 secs (47611070 bytes/sec) (45.4MB/sec)
10240+0 records in
10240+0 records out
10737418240 bytes transferred in 78.246473 secs (137225588 bytes/sec) (131MB/sec)

FreeNAS 0.8 (after tweaks)
[root@freenas] /mnt/storage# dd if=/dev/zero of=./testfile bs=1M count=10K && dd if=./testfile of=/dev/null bs=1M && rm ./testfile
10240+0 records in
10240+0 records out
10737418240 bytes transferred in 62.405507 secs (172058825 bytes/sec) - 164MB/sec write
10240+0 records in
10240+0 records out
10737418240 bytes transferred in 53.998347 secs (198847165 bytes/sec) - 189MB/sec read

And finally, Ubuntu 12.04 with ZFS on Linux:

root@RickNAS:~# dd if=/dev/zero of=/storage/testfile bs=1M count=10K && dd if=/storage/testfile of=/dev/null bs=1M
10240+0 records in
10240+0 records out
10737418240 bytes (11 GB) copied, 67.544 s, 159 MB/s
10240+0 records in
10240+0 records out
10737418240 bytes (11 GB) copied, 31.78 s, 338 MB/s


rick@RickNAS:~$ dd if=/dev/zero of=/storage/testfile bs=1M count=10K; dd if=/dev/zero of=/storage/testfile2 bs=1M count=10K; dd if=/storage/testfile of=/dev/null bs=1M; dd if=/storage/testfile2 of=/dev/null bs=1M
10240+0 records in
10240+0 records out
10737418240 bytes (11 GB) copied, 61.1301 s, 176 MB/s
10240+0 records in
10240+0 records out
10737418240 bytes (11 GB) copied, 59.9313 s, 179 MB/s
10240+0 records in
10240+0 records out
10737418240 bytes (11 GB) copied, 47.6692 s, 225 MB/s
10240+0 records in
10240+0 records out
10737418240 bytes (11 GB) copied, 32.2975 s, 332 MB/s

Quite strange, the improvement, but I wasn't going to knock it. So, all looked good, until I tried doing file transfers over CIFS (Windows networking), FTP and SFTP. The results were... abysmal. CIFS and FTP started fast, and rapidly dropped to about 30MB/sec. SFTP was... well, 3MB/sec didn't impress at all. To ensure that ZFS wasn't the issue, I reformatted one of the partitions as ext4, and did another test:

root@RickNAS:/storagetest# dd if=/dev/zero of=./testfile bs=1M count=10K
10240+0 records in
10240+0 records out
10737418240 bytes (11 GB) copied, 66.944 s, 160 MB/s
root@RickNAS:/storagetest# dd if=./testfile of=/dev/zero bs=1M
10240+0 records in
10240+0 records out
10737418240 bytes (11 GB) copied, 68.2629 s, 157 MB/s
root@RickNAS:/storagetest#

Not as fast as the raidz was, but still reasonably respectable. Sadly, I got similar results from CIFS etc.

Deciding to stick with ext4 for the moment just to eliminate any extra possible issues, I started to wonder why the performance was so terrible. I ran iperf to my PC, and got pretty respectable speeds out of it, far exceeding the data speeds I was getting in transfer. I went to work trying to improve the Samba speed, to no avail. No matter what I tweaked, nothing seemed to have any effect.

Next step: attempt reinstall natively, after having written out the ISO to USB.

So, reinstalled, after using the PenDrive Linux installer. Got it installed natively this time. Made zero difference. SFTP speeds are pathetic, around the 10MB/sec mark. Across gigabit, that's a bit of a joke, and it's nowhere near maxing CPU, so it's not that as far as I can tell. Did read up online that the driver for the onboard NIC can sometimes be less than perfect and to upgrade to a newer kernel. Did that. Nothing happened. Well, time passed, that's about it. iperf figured look okay though, averaging about 850mbit mark, which isn't too shabby. So there's some sort of bottleneck going on, and it's getting quite frustrating.

Next, I've tried to download /dev/zero via SFTP (in FileZilla on the Windows side) and it's settled for now at about 7.2MB/sec download speed. There's something quite clearly wrong. It's using 36% of one CPU for SSHD and 4-5% for sftp-server. It's clearly quite broken. I created a 4GB file in tmpfs in RAM for transfer tests, and vsftpd has slowed to 6.6MB/sec, which is very broken indeed. Make that 6.1MB/sec. Ouch. Rerunning the SFTP transfer resulted in SSHD taking up 96% of CPU at first (fair enough, maxed out) and doing about 40MB/sec, but it rapidly dwindled back to the 8MB/sec mark, using 26% CPU.

Next step: trying local FTP. Hooked in via localhost, retrieved said ram-based file and wrote to disk. 4294967296 bytes received in 26.49 secs (158306.3 kB/s). So, 26s to download the 4GB file, 157.5MB/sec. Seems reasonable. The put was even faster, 13.58 secs for the 4GB. So clearly it's not the software, or at least, not when running locally.

Okay. Back to the basics. Ran a few more longer iperf tests, for 6 minutes at a time each way, speeds were around 820mbit/sec on average. Nothing too spectacular, but nothing too unreasonable, and I was using the PC that they were connecting to at the time as well. Out of curiousity, I installed the CIFS utils and mounted up my Windows network share onto Linux, to copy some files across via the protocol to see what happened. This is where it got a little more confusing.

First, I ran DD to test it, using an mkv video file, 1.6GB. The second time I ran it after dumping the cache, just to make sure, was a little slower than the first time but still fairly respectable.

root@RickNAS:/mnt/win/Rick/Downloads# dd if=./testfile.mkv of=/tmpfs/testfile.mkv bs=1M

1548+1 records in
1548+1 records out
1623222074 bytes (1.6 GB) copied, 16.5486 s, 98.1 MB/s

98MB/sec. Reasonable enough, I think it came out at about 105-110 last time. The same timed operation with cp, after a reboot to flush caches, and a different file of similar size at 1.53GB (as I was struggling to kill caches):


root@RickNAS:/mnt/win/Rick/Downloads# time cp ./testfile.mkv /tmpfs/testfile.mkv
real    1m25.174s
user    0m0.096s
sys     0m6.992s

So, 85 seconds to copy 1.53GB, which equates to just under 18.5MB/sec. Seems a bit harsh. Dropped the cache, and ran it again to see what happened, after the Windows box had cached it:
real    0m17.701s
user    0m0.096s
sys     0m7.248s

So. No real problem copying there, at 88.5MB/sec. Similar to the above then, really, but a little slower. Still, acceptable enough. At this point, I have to eliminate the Windows box as a potential source of slowdown. Theoretically it shouldn't be, as it's on a RAID 0 with a pair of 500GB drives, but... one way to find out. Cue DD for Windows, and a /dev/zero device driver (translated: \\.\zero):


C:\temp>dd if=\\.\zero of=.\testfile bs=1M count=1K
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 11.5837 seconds, -0.0 MB/s

Well, that -0.0 MB/s is wrong, but the theory is reasonable. Trying a 10GB file for good measure:

C:\temp>dd if=\\.\zero of=.\testfile bs=1M count=10K
10240+0 records in
10240+0 records out
10737418240 bytes (11 GB) copied, 812.172 seconds, -246489356887425550000[snip] MB/s

Erm... 0.21MB/sec?! I know I did a bit of web browsing in the meantime... but there's something wrong there. I'm somewhat hoping it's the /dev/zero driver...

Okay. So plan B. Let's try a dd from the Linux box to the Windows box, the other way around.

root@RickNAS:/mnt/win/Rick/Downloads# dd if=/tmpfs/testfile.mkv of=./testfile.mkv bs=1M
1576+1 records in
1576+1 records out
1653435119 bytes (1.7 GB) copied, 123.167 s, 13.4 MB/s


... This would be a facepalm sort of moment then.

So what the hell is going on with the Windows box?!

CrystalDiskMark didn't report anything too strange on sequential read/write. 178.8MB/s read, 102.8MB/s write.

After this, I was entirely unable to access any of the mounted files on the Windows side, which left me rather confused. Had to drop this fix into my Windows box, and then all was shiny again. Very odd. So, another try of the DD then...


dd if=/tmpfs/testfile.mkv of=./testfile.mkv bs=1M
1576+1 records in
1576+1 records out
1653435119 bytes (1.7 GB) copied, 60.3011 s, 27.4 MB/s

Slightly better, but still a bit rubbish, in all honesty. Again, for good measure:
Resource monitor did show the write speed at 75MB/sec... briefly. Oh.
1576+1 records in
1576+1 records out
1653435119 bytes (1.7 GB) copied, 18.7947 s, 88.0 MB/s

... I don't get it. Same again got 87.3MB/s. It shows it as writing. Okay. Let's try another FTP download shall we? Nope, still rubbish.

Okay, time to eliminate the hard disk as an issue. Time to download to a USB HDD and see how that goes.

... Not so well. It chugged along at about 11MB/sec. That's quite poor. But it was fairly consistent, at least. CrystalDiskMark gave it a whole 10MB/sec write too, so no shock. Okay. Throwing a pure RAM disk into Windows to take out the drives as culprits.

dd:

root@RickNAS:/mnt/win# dd if=/tmpfs/testfile.mkv of=./testfile.mkv bs=1M
1576+1 records in
1576+1 records out
1653435119 bytes (1.7 GB) copied, 16.2628 s, 102 MB/s
Looks far more like normality.

ftp:
File transfer successful, transferred 1,653,435,119 bytes in 16 seconds.
So, that'll be... 98.55MB/sec then. Oh good.

Out of curiosity, I ran sftp, just to see what the performance was like, although I was expecting "dire". I got what I expected, about 20MB/sec. Fair enough, that's CPU-bound. Okay, other way round, just to make sure:

root@RickNAS:/mnt/win# dd if=./testfile.mkv of=/tmpfs/testfile.mkv bs=1M
1576+1 records in
1576+1 records out
1653435119 bytes (1.7 GB) copied, 16.1864 s, 102 MB/s


Looks good. Trying cp commands both ways:

root@RickNAS:/mnt/win# time cp /tmpfs/testfile.mkv ./testfile.mkv

real    0m16.803s
user    0m0.064s
sys     0m7.208s
root@RickNAS:/mnt/win# time cp ./testfile.mkv /tmpfs/testfile.mkv

real    0m15.218s
user    0m0.060s
sys     0m7.432s


So. RAM to RAM is actually fine. I'm going to run Samba to test it out too, to make sure all is as it should be...

... From: 100MB/sec. Copying back 110MB/sec.

Oh.

Okay, so let's try Linux HDD to ramdisk, just to make sure all is shiny as it should be.

... About 110 each way.

So. After all that hunting... all that debugging... all that chasing ghosts, upgrading network drivers and kernels, tearing my hair out... there was nothing wrong with the Linux box at all... it turned out it was my local hard disk. I just hope that this post saves someone else the hours of attempted fixes I tried. It's been a painful journey, but a lesson well learned.

28 April 2012

Displaying Magento tier prices instead of main prices for groups

I've been tackling a particularly annoying problem with Magento, in that I've got specific pricing by groups, imported from another database, but while it'd show the tiered prices in a box, it'd always show RRP on the front page. Fixing it to show the first tier price for quantity 1 on the product page was easy enough (using $this->getTierPrices()), but the tier prices simply aren't present on the grid / listing page, and it really didn't want to let me retrieve them by group either.

So, in case it helps anyone else out at a later date, this is how I got around it, displaying tier prices instead of the main prices on the listing page as well as the main product display page. (Tested on Magento 1.4.1.1, later versions may vary.)

Around line 58, after the following

getPrice($_product, $_product->getPrice()) ?>
getPrice($_product, $_product->getPrice(), $_simplePricesTax) ?>
getPrice($_product, $_product->getFinalPrice()) ?>
getPrice($_product, $_product->getFinalPrice(), true) ?>


add:
getTierPrices();
if (empty($_tierPrices) && $this->helper('customer')->isLoggedIn()) { // No tier prices found, attempt manual retrieval if customer logged in
$resource = Mage::getSingleton('core/resource');
$query = 'SELECT qty AS price_qty,value AS price FROM '.$resource->getTableName('catalog/product').'_tier_price WHERE entity_id = '.$_id.' AND qty = 1 AND customer_group_id = '.Mage::getSingleton('customer/session')->getCustomerGroupId();
$_tierPrices = $resource->getConnection('core_read')->fetchAll($query);
}
if (!empty($_tierPrices)) {
foreach($_tierPrices AS $tierPrice) {
if ($tierPrice['price_qty'] != 1) continue;
$_price = $tierPrice['price'];
$_finalPrice = $this->helper('tax')->getPrice($_product, $tierPrice['price']);
$_finalPriceInclTax = $this->helper('tax')->getPrice($_product, $tierPrice['price'], true);
break;
}
} ?>


I also had to alter the following line lower down to avoid displaying "as low as" for items that didn't have lower than the first tier price:

From:
getDisplayMinimalPrice() && $_minimalPriceValue && $_minimalPriceValue < $_product->getFinalPrice()): ?>

To:
getDisplayMinimalPrice() && $_minimalPriceValue && $_minimalPriceValue < $_finalPrice): ?>

Hope this helps someone out, as it had me scratching my head for a bit, and the online documentation I found wasn't brilliant. In the end the most efficient way seemed to be to rip it straight out of the database. Credit to the stack overflow question that pointed me in the right direction to run the query, modified to select only the customer logged in group and quantity 1 for efficiency.