Rust + Gtk = Wow

As I’ve been experimenting with writing Rust apps, I attempted to create a small little GUI application. At first I attempted to setup everything with Qt, but C++/Qt interoperability with Rust is painful. Very, very painful. I experimented with some more radical UI frameworks such as Azul and Conrad. These have a lot of promise going forward. However for the here and now, I recommend looking at gtk-rs, Rust binding for Gtk.

With a bit of experimentation, looking through gtk-rs examples, some other projects using gtk-rs, and lots and lots of searching, I was able to create this:

This is a code viewer that lets you open Rust code, and view it. Yes, you are looking at a portion of the code that runs that code viewer. Getting the GtkSourceView working took some coaxing. Also I had to learn how to use the Glade UI editor for Gtk. Overall it took me about 2 to 3 hours to pull this off. I am very impressed with the results, and it opens up new possibilities for me.

Packaging up a Rust Binary for Linux

Prologue

I should of written an update for quite some time. While I’ve been experimenting with marketing analytics, learning about data science, business development, doing DevOps with GitLab CI and various other things, I wanted to write up my learning when I had a chance to internalize everything. However what made me decide to write an update is this tweet from Chris Krycho. Chris runs the amazing New Rustacean podcast, which is a must listen for anyone interested in learning about programming in Rust.

How does one package a Rust app?

Chris asked about finding a good way to distribute Rust binaries across Linux distros:

Interestingly enough, I recently figured out how to package a small Rust CLI utility that I’m working on. My response was:

This post elaborates on what I meant with my reply.

Building snap packages using snapcraft

The fine folks at Canonical (the makers of Ubuntu Linux), have created something called snap packages. These packages and associated package manager help developers distribute applications (desktop, cloud, etc.) in a safe, isolated manner. I currently have slack installed this way. snaps isolate apps by having the package maintainer declare the capabilities an app requires (network access, access to system files, the GPU, home directory, etc.), and then ensuring the apps can not escape this sandbox.

Basic Setup

Getting setup with packaging a Rust crate was not too hard:

  1. Install snapcraft: sudo snap install snapcraft --classic
  2. Create a snap template inside your crate project: snap init
  3. Edit the generated snap/snapcraft.yml as per the documentation.
  4. Build the snap using snapcraft.
  5. Install the resulting snap with sudo snap install my-cool-rust-bin_x.y.z.snap --devmode --dangerous (this assuming you are experimenting with building a snap)
  6. Add you should be able to distribute your app as a snap now. (See the caveats below.)

Caveats working with snaps

Now there a bunch of caveats when working with snaps. And for my own Rust utility, I found these too taxing and I decided to go with creating a standard Debian package instead. However if I wanted to target multiple distributions and my app didn’t have a very unorthodox setup (my app relies on using the Chrome WebDriver to control a networked device managed by dd-wrt), I would probably have gone with a snap instead:

  • You need to know what capabilities your app needs: file access, network, etc. and you need to declare the appropriate interfaces in your snapcraft.yml
  • Using something other than my local system (be it a Docker based build or using a different base like base18), failed terribly at least for Rust.
  • Whether or not I’d have more success if my base system was the recommended Ubuntu 16.04 and not 18.04 is an outstanding mystery.
  • The snap confinement, even on the much more liberal devmode, works very well. No amount of coaxing on my part, let me use system paths when trying to spawn a process. This could just be me though, as not declaring network access did not block my app.
  • The docs could of been clearer about what was the latest recommended approach. (Still way clearer than the documentation for creating a DEB or RPM from scratch.)
  • Knowing which libraries (for the type of base system) your app needs takes a bit of experimentation. (e.g. I needed libssl1.0 for some builds and libssl1.1)
  • I have no idea how the classical confinement should work, and it is not recommended either way.

The end result for me was a working snap package, but an app that would not work when called from an installed snap. However I think snap packages are probably the way to go moving forward (or a similar format like flatpak). Since I only plan on targeting local Ubuntu 18.04 installs, I ended up creating a Debian package instead.

Building a Debian package with Cargo

I found a nice utility for creating a deb out of a Rust crate, called cargo-deb. After installing the crate with cargo: cargo install cargo-deb, I simply ran cargo deb and I was done. cargo-deb looked into my Cargo.toml for the metadata, ran a build and a few moments later I was the proud owner of a Debian package. Since my app relies on the chromium-browser and chromium-chromedriver packages, I added a small section in my Cargo.toml as so:

[package.metadata.deb]
depends = "$auto, chromium-browser, chromium-chromedriver"

The $auto is something that the Debian packaging mechanism needs, and that is the comma separated format that DEBs use.

Building a RPM from a DEB package

Now this the part that I didn’t do this time around. However I figured out how to create RPM packages from DEB packages a few months ago. The trick is to use the alien utility to create a RPM out of a DEB:

sudo alien --to-rpm --scripts --verbose my-cool-rust-bin.deb

For the record, I did not try to improve or debug the resulting RPM. (This entire effort was for a product that failed to launch.) However as part of my tests I was able install it and run it from on CentOS VM.

Epilogue

Anyways, I would recommend the cargo-deb and alien approach, if you are not planning to distribute a Rust app across a multitude of Linux distros. I would recommend dipping into snap if you plan on distributing something more commercial and wide-spread like a slack or kubectl. And I hope that helps you on your Rust app packaging for Linux journey!

Fixing Docker on Linode (Linux v4.18.16)

This week as I had some downtime after PyCon Canada, I started working on resolving all the issues that I postponed. One of these issues involved applying security updates to my Linode server and rebooting the server. However when I did so… I noticed that the Rookeries site went down. When I logged into the server, I quickly found the problem: Docker refused to start after the kernel updates.

As this bug report on Docker for Linux says, there is an issue with the latest Linode kernel when it comes to OverlayFS.

This causes the containerdservice that docker-ce is dependent on to not start. When looking at the logs (using sudo journalctl -xe), you’ll see an error along the lines of:

modprobe: ERROR: ../libkmod/libkmod.c:514 lookup_builtin_file() could not open builtin file '/lib/modules/4.18.16-x86_64-linode118/modules.builtin.bin'
modprobe: FATAL: Module overlay not found in directory /lib/modules/4.18.16-x86_64-linode118)

Thankfully there is a workaround to resolve this problem. From the instructions you need to an override configuration for the containerd service:

$ mkdir -p /etc/systemd/system/containerd.service.d/
$ cat << EOF > /etc/systemd/system/containerd.service.d/override.conf [Service]
ExecStartPre=
EOF
$ systemctl reload
$ systemctl restart docker

Anyways, I hope this helps if you run into the same situation.

Notify Me when Done “X” in KDE

One of the few Java webapps I work on at work, has a very long startup time. Unfortunately since the server startup code is proprietary and owned by the vendor, there is not much I can do about that. However it is easy to forget to check if the server has started up, I decided to that I needed a way for my computer to notify me that the webapp was up. Here is how I came up with a simple and quick way to do just that in KDE.

So my webapp has an health endpoint that can be easily queried via HTTP. With httpie the HTTP query was very easy, however to script httpie to keep querying until the result came back, meaning the server was up. At first I tried do a while with negation of the return code, and then I found on StackOverflow that the bash until command will do just that. (Without needing to figure out the appropriate negation).

The second part was figuring how to create notifications in KDE via the console. Turns out that kdialog will create both notifications and general popup alerts.

Putting the two together I came up:

until http :8080/my_health_endpoint; do echo 'Waiting...'; sleep 10; done; kdialog --passivepopup "Ready to go!" 10`

I added a sleep in there, to throttle the number of times that httpie would run. The second parameter on the kdialog dictates how long the notification popup will be around. Alternatively I could of used --msgbox if I wanted a dialog that I had to press ‘OK’ on.

Resources

Switching to systemd

I recently upgraded my version of Ubuntu to 15.04. In the process, I found out that my init system had changed from Upstart to systemd. While having something as fundamental as the init system management was a bit annoying, it isn’t as bad as some folks are making it out on the Web. Here are some of the things I learned as worked with systemd in fixing my CouchDB server. Part of this is based on this excellent guide on using systemd for Upstart users. The other part is just experimentation on my part.

Checking the Status of All Services

sudo systemctl status

Hint: feel to grep through the output to find anything

Sidenote

At first I could not find the CouchDB service. I had to uninstall the package and purge the packages and then reinstall it:

sudo aptitude purge couchdb
sudo aptitude install couchdb

After that the service showed up in the systemd services, rather than just having an Upstart service.

Checking the Status of a Service

sudo systemctl status $MY_SERVICE

Starting and Stopping a Service

sudo systemctl [start|stop|restart] $MY_SERVICE

Logging Service Activity

This was an interesting thing in systemd. Normally one has to look at the Upstart log at /var/log/upstart/$JOB.log. systemd provides its own logging mechanism, so to see the log of a service you have to use the journalctl utility.

sudo journalctl -u $MY_SERVICE

The output behaves just like one would expect from less.

Overall Impressions

Once I got over my initial head scratching of how to use systemd, it was not bad. Rather it feels different, but not in a bad way honestly. I might look into this more closely and see if I prefer using something like systemd over supervisord for controlling even WSGI apps.

The one disappointing thing that I discovered related to my experiments with systemd, or rather specifically with CouchDB in Ubuntu 15.04. There doesn’t seem to be a way to configure CouchDB to have admin users with passwords for some reason I can’t quite fathom. In the meantime, I guess I’ll have to stick to running CouchDB from a Docker container until I can resolve the issue natively.

Command-line JSON Formatting with jq

About 2 or 3 months ago, when testing a deployment of a microservice at work
with Eric, our head Ops admin, we were looking at the JSON output of one of
the REST endpoints. Rather than looking at the raw output from curl, I
piped the output through JSON tool in the Python standard library:

$ curl -X GET -s http://rookeries.org/status | python -m json.tool
{
    "app": "rookeries",
    "version": "0.4.9"
}

(I will give you a couple of examples based on calls to Rookeries, rather than
the actual service call, since that API isn’t available publicly yet.)

Eric seeing that suggested I try out a utility that he uses: jq which is
great for formatting and querying JSON
.

Installing jq

jq is a utility in C, and fortunately there are binary packages available for
it in the latest Ubuntu LTS (14.10). Installing it via aptitude (or apt-get):

$ sudo aptitude install jq

Pretty Printing JSON

The simplest use case for jq is to simply pretty print JSON output. This is
done by piping the result of a CURL command to jq with the parameter ‘.’:

$ curl -X GET -s http://status.bitbucket.org/api/v2/status.json | jq .
{
  "status": {
    "description": "All Systems Operational",
    "indicator": "none"
  },
  "page": {
    "updated_at": "2015-09-03T08:03:55.275Z",
    "url": "http://status.bitbucket.org",
    "name": "Atlassian Bitbucket",
    "id": "bqlf8qjztdtr"
  }
}

Formatting JSON in jq

It is also possible to format the output of the JSON to display only relevant
information. For instance if I want to find out the status of the components
that make up Bitbucket I can do the following:

$ curl -X GET -s http://status.bitbucket.org/api/v2/components.json | jq .

That however will give me a whole lot of extra data that I might not want. So
instead I might to narrow down and re-format the JSON data to something more
manageable with some jq magic:

$ curl -X GET -s http://status.bitbucket.org/api/v2/components.json | \ 
jq '{src: .page, components: [.components[] | \
    {id: .id, name: .name, status: .status}]}'

{
  "components": [
    {
      "status": "operational",
      "name": "Website",
      "id": "g0lfj4sv2fhf"
    },
    {
      "status": "operational",
      "name": "API",
      "id": "k0x2yw1435v7"
    },
    {
      "status": "operational",
      "name": "SSH",
      "id": "qmh4tj8h5kbn"
    },
    {
      "status": "operational",
      "name": "Git via HTTPS",
      "id": "c1qmcrcbc5zy"
    },
    {
      "status": "operational",
      "name": "Mercurial via HTTPS",
      "id": "vmbzxbbjz05j"
    },
    {
      "status": "operational",
      "name": "Webhooks",
      "id": "rfzky0v13fbp"
    },
    {
      "status": "operational",
      "name": "Source downloads",
      "id": "28h8dvv2qfzw"
    }
  ],
  "src": {
    "updated_at": "2015-09-03T08:03:55.275Z",
    "url": "http://status.bitbucket.org",
    "name": "Atlassian Bitbucket",
    "id": "bqlf8qjztdtr"
  }
}

I won’t explain that particular string in detail. But it will basically
craft a new JSON object, and generate new filtered objects when iterating
over the old array. Overall jq is pretty neat and is extremely fast to work
with.

There is also a Python bindings library for jq. I am considering using it to
help with mapping JSON into Python objects. However I have not played around
with it long enough to know if the extra dependencies are worthwhile or
whether or not it will bring a lot of benefits to Rookeries.

Reference Links

Ansible Role for NGINX, UWSGI and Supervisor Released!

What better way to start 2015 than to release new software?

As part of my efforts to create Rookeries, a modern Python-based CMS as a replacement for my WordPress sites: I am releasing an Ansible role to make it easier to setup WSGI apps on a private server.

The nginx-uwsgi-supervisor role is available on Ansible Galaxy.   This role setup NGINX and the UWSGI (WSGI app server) and supervisord infrastructure to make installing Rookeries or another WSGI app a breeze.   The goal is to make a Rookeries site as easy or easier to install and maintain than a WordPress site.

All the code for the role is host on Bitbucket, and mirrored on Github.

I am especially excited since this my first ever, fully functional, open source release.  I hope enjoy using and makes their life easier when build webapps in Python.

Distro Hopping

Sorry for the much delayed update, however this year has been an hectic and busy one. (New job, new house, lots of random unexpected events along the way, like two funerals and two weddings in a single month, etc. Long story.) Plus I really hoped to change blog platforms, but that is a story for another time.

Explaining the Journey

With so many things changing in my life, I decided to change up the Linux distribution I’m running. Now I have a large set of requirements being both a developer and gamer. I need a distribution that can handle Python, Java, Android and Qt Linux development. Also I want my distro to run Steam, and handle the Nvidia Optimus graphics card in my laptop, properly.

(Sidenote: A word to the wise, avoid Optimus cards as they are a pain to setup under Linux. I got mine because I naively assumed that all Nvidia cards are easily and nicely supported under Linux. Recently I heard that Nvidia promised to help the Nouveau devs to make the Optimus experience under Linux nicer. But I would not hold my breath to wait for things to get better soon.)

Long Story Short

The shortest version of the story: After doing a fair bit of distro hopping including using some uncommon distros, I am back to using Kubuntu.

Specifically the path I took was:
Kubuntu → openSUSE → Mageia → Debian → Linux Mint → Sabayon → Kubuntu u2192

The rationale behind all this? Well read on. 🙂

Kubuntu → openSUSE

After hearing about Canonical’s plans to use their own display manager “Mir” instead of “Wayland”, and experiencing random breakage with Kubuntu I decided to change distros. When I heard that the main dev behind Kubuntu was not going to be funded by Canonical, I decided it was time to jump ship.

I decided to retrace my steps, and try new versions of distros that I used in the past. Technically before I started using Kubuntu I ran on Gentoo Linux. But I was not about to go back to compiling and configuring everything on my system. So my first stop was openSUSE.

SuSE and now its community driven variant openSUSE, always has been a very slick distro in terms of supporting KDE.  The version I was running was no different. I was also encouraged by the large number of packages available including a nice setup for both Steam and bumblebee (this being the program that adds decent support for Nvidia Optimus under Linux).

openSUSE is a gorgeous distro overall, except for one very important issue… openSUSE feels like it was built for a corporate desktop. The number of PolicyKit warnings that I received whenever I tried to suspend and resume was surreal. While I am familiar with the lingo and ideas behind SELinux, AppArmour, etc, I could not for the life of my figure out how to get my laptop to resume and suspend without some silly PolicyKit message blocking me. openSUSE was not meeting my needs.

openSUSE → Mageia

With openSUSE failing me, I decided to go further in time to my original distro Mandrake/Mandriva. I found out that some Russian firm had bought out the French made Mandriva and as part of a general restructuring effort laid off some of the maintainers. These maintainers started their own version of Mandriva called Mageia. While the distro and its infrastructure is still fairly young, I was encouraged by the fact that some experienced maintainers were behind the project.

I was amazed with the amount of polish but into a budding community driven distro. I ran against some rough edges with Python support, but those were resolved with some help and new updates. I was impressed and I took my first steps to becoming a maintainer myself. The community was very receptive and welcoming. While I ended up using Mageia for weeks, I did not stay with the distro.

Why didn’t I stay with Mageia? I could not get bumblebee running on my machine. I could of fought some more, learn how to maintain a package and help build out the distro. But after some introspection, I realized that I simply do not have time contributing as a maintainer to a distro. There is a lot of work involved, and considering everything going on in my life right now, I needed to get a distro I could rely on and work with right now.

Magiea → Debian

Debian seemed like the logical choice for a stable Linux. The distro is entirely community driven, and has been around forever. So after a bit of haggling with the network installer, I managed to get a KDE desktop running on Debian. Debian definitely run on mature, stable software, which is perfect for someone running a server or managing a desktop configuration that has been around for years. Unfortunately the Linux desktop has only become very stable and usable in past while. Also the Debian community are sticklers when it comes to open source licenses, and how distributable
the software is legally. Unfortunately again, closed source firmware and other software makes things much more difficult. Getting my Broadcom wireless network card, and my Nvidia graphics chip working was just not happening.

Also I assumed that since Ubuntu worked so well, that Debian would be just as well setup from the get-go. I realize now how much work Canonical put into configuring their Debian base and smoothing all the wrinkles out. However I was not up for doing all that work myself, just to stay with Debian.

Debian → Linux Mint

Debian stayed installed on my laptop for a mere two days, before I got fed up with it. The next logical choice to avoid Ubuntu, but get some of the niceties of the platform was to try out Linux Mint. One of my good friends runs it and she enjoys using it thoroughly. I also watched and read some good reviews about the latest stable release of Linux Mint 15, and how much polish the devs put into the KDE desktop. I was intrigued, so I tried it out.

Linux Mint 15 definitely has a lot of polish. However nothing that spectacular that does not come standard to KDE. Except for the extra System Settings panel to handle PPAs (private Ubuntu repos), which is pretty darn cool. I did run into issues with trying to run packages originally meant for Ubuntu. There were slight and subtle incompatibilities, and I eventually gave up trying to fix things.

Linux Mint → Sabayon

By now I had run into a moment of madness. No good easy-to-use RPM based distros remained to try out. Fedora sounded too experimental for my liking. The Debian universe had been pretty much a let down. I debated using Netrunner, a KDE distro, by Blue Systems. (Blue Systems being that weird German company that somehow funds KDE development on Ubuntu, Linux Mint KDE and Netrunner. But no one has an idea how they fund themselves. Maybe by European Union funds, which seems to be the popular way to fund nebulous entities and projects in Europe.)

So I had a moment of madness, and despair brought on by no new leads while looking at potential distros on DistroWatch (http://www.distrowatch.com/). In that moment I decided to try a system not based on the traditional package systems. That left systems in the Arch or Gentoo families. Arch itself fell into the too much maintenance category. Gentoo did as well. Manjaro looks promising, but I’ll wait until it matures or fades way due to its small team. I tried Sabayon Linux, something I did not expect to do.

Sabayon Linux is definitely much nicer than Gentoo to maintain. Everything worked out of the box too. Except Sabayon felt very much like an early adopters hobbyist distro. An update or a new package installation, downloaded half the universe. My laptop ran faster… and ate its battery so quickly that it would just shutdown… randomly while running on battery. I could run Steam and my development environments, just never without worrying about my laptop suddenly powering off.

I realized I could not continue on like this…

Return to Kubuntu

Now I am back to running on Kubuntu, and everything just works well enough. I could of gone back to Mageia, and hoped that the upcoming release of Mageia 4 would of resolved most of my issues. Ultimately I went back to Kubuntu, since for right now it works well enough and meets my needs.

I work with Ubuntu at my new workplace, plus I support a couple of other Kubuntu machines running at home. I no longer use the tools that caused me grief when some libraries changed in Ubuntu. For better or worse, support for new applications or hardware is targeted at Ubuntu. Also it is a bit of a relief that Blue Systems stepped in and now funds development of Kubuntu. Canonical’s plans for transitioning to Mir, still do not affect me at least on my current version. Also this might change in the upcoming release, and I maybe stuck on this version of Kubuntu for a while.

Or things maybe change, maybe Canonical will change its mind and work with the Wayland community. Maybe Nvidia will fix up their terrible driver support due to market pressures. Or maybe I will have to move off to Mageia or Manjaro eventually. In the meantime I can be productive, and once things will calm down again, maybe I’ll go on another round of distro hopping.

Update (2013 October 18): Just upgraded to Kubuntu 13.10 yesterday!  I am encouraged by the news that the Kubuntu devs will push forward on using Wayland and support Kubuntu into the future.  So it looks like I will continue using and enjoying Kubuntu well into the future.  Now I’ll just need to learn how to package DEBs, and I’ll be able to help out occasionally too. 🙂

Spring Cleaning for 2013

With Easter just around the corner and possibly spring coming shortly after–Canadians have to wait a bit longer for spring t0 properly arrive and winter to make her final exit–that it would make sense to update my blog.   Many things have changed in the past few weeks .  Like we have a new pope, Pope Francis, just in time for Easter.  (I’m not going to weigh in on my opinions of the decision of the Conclave, other than I have mixed feelings.  And each passing day does not ease my general feeling about unease.)  Some things have not changed.  Like most things in the world I guess.

With the slow coming of warmer weather, I have a good excuse for a bit of spring cleaning and growing myself.  In terms of spring cleaning, I have meant to really organize my activities and my surroundings.  Unfortunately since I had to make do without my laptop for a few weeks, that has not helped me get more things done.  Especially when it comes to dealing with my overflowing inbox.  Apologies for everyone expecting me to get back to them.  I’m getting there slowly.

I did get to play around with setting up Python on my hosting environment and with Clojure.  Clojure, while definitely useful still feels like an exercise in academics than industrial programming.  (Still one can write a full implementation of Snake/Nibbles in Clojure in under 100 lines of code?  Madness!)  Python on the other hand is too much fun to feel like work.  I considered using something like a static website generator like Nikola or benjen to port some of my websites.  But I think for kicks, I will go the route of using Flask and craft my own mini-site just because working with Python is a such a joy.

One unfortunately necessary bit of spring cleaning will be changing Linux distros again.  It seems that Canonical is doing a fair bit of wild experimentation nowadays.  Too wild and it smells like they are suffering from NIH (not invented here).  The idea to chuck out everyone’s hard work on replacing X with Wayland, with their own thing was just too much.  So it looks like I’m going back to openSUSE for good.  It is just a matter of when I get around to migrating all my systems over.  I have no real issue with Canonical doing what they want with their own distro Ubuntu.  I just don’t agree with the philosophy, and the needless experimentation, especially since I am quite happy with using a relatively standard KDE 4 desktop.

Hopefully once I finish all the spring cleaning I’ll get to finish up and show off some the projects I’ve been working on.

 

Linux SATA HDD Issues with Samsung RF-711

OK, this is a quick post for anyone who is running into issues with using Linux on a Samsung RF-711.  Specifically this applies to Ubuntu Linux 12.04 64-bit.

Essentially what was happening, was that periodically my entire machine would freeze with the exception of anything currently running.  This kept on happening all the time, until I wasn’t able to even use the machine for minutes at a time.  Which is a real shame since this is a very powerful and nice laptop.  Essentially my SATA hardware kept on hiccing up and failing to handle DMA write requests:

> dmesg

… (output abbrevated for display purposes) …

[ 485.289702] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
[ 485.289712] ata1.00: irq_stat 0x40000001
[ 485.289720] ata1.00: failed command: READ DMA EXT
[ 485.289742] ata1.00: cmd 25/00:08:c0:c6:a7/00:00:1c:00:00/e0 tag 0 dma 4096 in
[ 485.289744] res 51/40:08:c0:c6:a7/00:00:1c:00:00/e0 Emask 0x9 (media error)
[ 485.289747] ata1.00: status: { DRDY ERR }
[ 485.289750] ata1.00: error: { UNC }
[ 485.432598] ata1.00: configured for UDMA/133
[ 485.432629] ata1: EH complete
[ 490.745427] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
[ 490.745437] ata1.00: irq_stat 0x40000001
[ 490.745444] ata1.00: failed command: READ DMA EXT
[ 490.745458] ata1.00: cmd 25/00:08:c0:c6:a7/00:00:1c:00:00/e0 tag 0 dma 4096 in
[ 490.745460] res 51/40:08:c0:c6:a7/00:00:1c:00:00/e0 Emask 0x9 (media error)
[ 490.745467] ata1.00: status: { DRDY ERR }
[ 490.745472] ata1.00: error: { UNC }
[ 490.887945] ata1.00: configured for UDMA/133
[ 490.887980] ata1: EH complete
[ 496.201083] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
[ 496.201093] ata1.00: irq_stat 0x40000001
[ 496.201100] ata1.00: failed command: READ DMA EXT
[ 496.201113] ata1.00: cmd 25/00:08:c0:c6:a7/00:00:1c:00:00/e0 tag 0 dma 4096 in
[ 496.201116] res 51/40:08:c0:c6:a7/00:00:1c:00:00/e0 Emask 0x9 (media error)
[ 496.201122] ata1.00: status: { DRDY ERR }
[ 496.201134] ata1.00: error: { UNC }
[ 496.354593] ata1.00: configured for UDMA/133
[ 496.354618] ata1: EH complete
[ 501.667841] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
[ 501.667850] ata1.00: irq_stat 0x40000001
[ 501.667857] ata1.00: failed command: READ DMA EXT
[ 501.667870] ata1.00: cmd 25/00:08:c0:c6:a7/00:00:1c:00:00/e0 tag 0 dma 4096 in
[ 501.667873] res 51/40:08:c0:c6:a7/00:00:1c:00:00/e0 Emask 0x9 (media error)
[ 501.667880] ata1.00: status: { DRDY ERR }
[ 501.667885] ata1.00: error: { UNC }
[ 501.810534] ata1.00: configured for UDMA/133
[ 501.810566] sd 0:0:0:0: [sda] Unhandled sense code
[ 501.810571] sd 0:0:0:0: [sda] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[ 501.810588] sd 0:0:0:0: [sda] Sense Key : Medium Error [current] [descriptor]
[ 501.810593] Descriptor sense data with sense descriptors (in hex):
[ 501.810596] 72 03 11 04 00 00 00 0c 00 0a 80 00 00 00 00 00 
[ 501.810606] 1c a7 c6 c0 
[ 501.810611] sd 0:0:0:0: [sda] Add. Sense: Unrecovered read error - auto reallocate failed
[ 501.810616] sd 0:0:0:0: [sda] CDB: Read(10): 28 00 1c a7 c6 c0 00 00 08 00
[ 501.810627] end_request: I/O error, dev sda, sector 480757440
[ 501.810655] ata1: EH complete
[ 508.210222] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
[ 508.210228] ata1.00: irq_stat 0x40000001
[ 508.210232] ata1.00: failed command: READ DMA EXT
[ 508.210240] ata1.00: cmd 25/00:08:c0:c6:a7/00:00:1c:00:00/e0 tag 0 dma 4096 in
[ 508.210241] res 51/40:08:c0:c6:a7/00:00:1c:00:00/e0 Emask 0x9 (media error)
[ 508.210245] ata1.00: status: { DRDY ERR }
[ 508.210248] ata1.00: error: { UNC }

So every save, every time something needed to get loaded into memory was terribly slow.  After a fair bit of searching I found that the issue related to the parameters being passed to the SATA drive where my Linux partition lives:

> sudo lshw

… (output abbrevated for display purposes) …

*-storage
 description: SATA controller
 product: 6 Series/C200 Series Chipset Family 6 port SATA AHCI Controller
 vendor: Intel Corporation
 physical id: 1f.2
 bus info: pci@0000:00:1f.2
 logical name: scsi0
 logical name: scsi2
 version: 04
 width: 32 bits
 clock: 66MHz
 capabilities: storage msi pm ahci_1.0 bus_master cap_list emulated
 configuration: driver=ahci latency=0
 resources: irq:41 ioport:e0b0(size=8) ioport:e0a0(size=4) ioport:e090(size=8) ioport:e080(size=4) ioport:e060(size=32) memory:f7606000-f76067ff
 *-disk
 description: ATA Disk
 product: SAMSUNG HN-M101M
 physical id: 0
 bus info: scsi@0:0.0.0
 logical name: /dev/sda
 version: 2AR1
 size: 931GiB (1TB)
 capabilities: partitioned partitioned:dos
 configuration: ansiversion=5

The nearest bug report that I can point to on Launchpad is: Bug #550559 – hdd problems, failed command: READ FPDMA QUEUED

The solution that worked for me, and seems to be holding is to:
  • Turn off SATA GEN3 support in the BIOS.
  • Set the AHCI to manual and then disable it.
  • Add the following kernel parameter to your grub config: libata.force=X:noncq You will need to edit your /etc/default/grub file as I have below. Copy the /etc/default/grub.original file if you don’t have the a grub file already.
  • Rebuild your GRUB and initramfs with: sudo update-initramfs && sudo update-grub2
Sample grub configuration file:

# If you change this file, run ‘update-grub’ afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
# info -f grub -n ‘Simple configuration’

GRUB_DEFAULT=0
#GRUB_HIDDEN_TIMEOUT=0
GRUB_HIDDEN_TIMEOUT_QUIET=true
GRUB_TIMEOUT=10
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT=”quiet splash libata.force=1:noncq”
GRUB_CMDLINE_LINUX=”libata.force=1:noncq”

Anyways, this took me a while to fix.  So I’m posting in hopes that it’ll be help out someone else.