Skip navigation

This shouldn’t have taken me as long as it did, but Java’s JDBC driver doesn’t always know what TZ to use or rejects what the system returns. You may see something like: org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (The server time zone value 'CDT' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.)

Yes, the mis-spelling of ‘specific’ is accurate to the output as out OpenJDK 1.8.0_181

You can attempt to push the TZ from the Java application but there’s no good reason the MySQL server shouldn’t be configured with a TZ. Check the server with:
SELECT @@global.time_zone

Then update /etc/myc.cnf with default-time-zone=Your/Timezone and restart.

If the server refuses to start and your sure of your timezone in my.cnf the MySQL tables might not be fully populated, to do so execute mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql -p from a terminal on the server host.

MySQL Documentation on Default Timezone

Updating the postgresql timescale-db extension from pre 0.8.0-dev builds – you must re-create extension and hyper-tables, ie:
CREATE database dbname;
\c dbname
SELECT create_hypertable('time_table', 'time');

The ability to generate 3D objects from drawings isn’t a new technology, CNC lathes have been producing accurate three dimensional objects for decades out of a wide array of materials from various metals, wood, and plastics. Recently a far cheaper alternative known as 3D printing has become popular which can achieve a similar effect though in smaller scales and typically using less durable materials, which for most consumer/hobbyist goals is perfectly adequate. If you need a part that just isn’t made and know your way around a CAD tool, 3D printing is fast and cheap compared to what were at the time the only alternatives a few years ago.

For this project, I needed an extra set of fans to help cool the GPU within a CaseLabs Mercury S5. The S5 is by far one of the highest quality and best designed cases I’ve ever used, though my particular air-cooled configuration was plagued with a bit more heat soak than I was happy with. I think at some point everyone goes through a liquid cooling phase, and ultimately grows out of it. For anyone running an air-cooled setup in an S5, here’s an easy way to improve the flow dynamics of the PCI-E compartment.

To design the manifold I spent an afternoon re-familiarizing myself with the latest version of AutoCAD using the free 30 day trial license. AutoCAD’s 3D tools have come a long way in the last few years and made the design phase a breeze. For the fans I selected a set of 40mm Noctua NF-A4x10 low noise fans. Knowing the dimensions of the fans and having direct access to the case I used a digital caliper to measure the location the manifold was to be placed and created the 2D overhead drawing using the SW corner as the origin.

Screenshot (15)

The next step was to extrude/pull the 2D structures into the final form of the manifold. A quick review of a few chapters in an undergrad physics book covering laminar flow/fluid dynamics and some dirty napkin mathematics provided the offset of the fan face and the rear ventilation plate, use of the filet tool to eliminate sharp edges in the flow path to reduce turbulence/resistance and noise resulted in a compact and low material design. It is important at this stage to understand the limitations of the particular material and printer you will be using, they all have specific resolutions and minimum thickness guidelines that need to be considered during design. For my particular combination I targeted a minimum of 1.2 mm. I had also already selected a set of nylon mounting hardware to reduce vibration and was able to incorporate structures to increase strength and rigidity as well as specific geometry to hold the mounting hardware in place.

Screenshot (10)

Screenshot (12)

Screenshot (16)

Screenshot (18)

Screenshot (20)

Once the final design was achieved, and all measurements double checked it was time to print. I chose my local UPS store for convenience, which uses a Stratasys uPrint SE Plus.




Results were far better than expected and whisper quiet. The total printing cost was ~$21 USD, the fans were on sale for $8 a piece which brought the total cost (not including personal time) to ~$37 USD.

The final DWG and STL files:

This is the second time I’ve run into this, so I’m making a note of it. If you’re compiling and installing git/gitweb outside of a package manager, the selinux file contexts might not be correct and prevent apache from being able to execute the gitweb CGI script. Something like this will appear in your /var/log/audit.log:
avc: denied { search } for pid=16678 comm="gitweb.cgi" dev=sda2 ...
avc: denied { read } for pid=16678 comm="gitweb.cgi" dev=sda2 ...
avc: denied { open } for pid=16678 comm="gitweb.cgi" dev=sda2 ...

To fix issue
$ sudo chcon -u httpd_git_script_exec_t /path/to/gitweb.cgi

If that doesn’t work your selinux policies might be different, you can try:
sudo restorecon -v /path/to/gitweb/dir/*

GDChart is a fairly old PHP extension, it’s origins are somewhere in 2003 and doesn’t seem to have been updated since 2006. The standard PECL sources won’t compile under any version of PHP greater than 5.3 due to a few changes in the Zend engine and GD dependencies. If you try, you’ll get a few error messages:
/gdchart-0.2.0/gdchart.c:195: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘gdchart_functions’
/gdchart-0.2.0/gdchart.c: In function ‘gdc_objects_new’:
/gdchart-0.2.0/gdchart.c:303: error: ‘zend_class_entry’ has no member named ‘default_properties’
/gdchart-0.2.0/gdchart.c: At top level:
/gdchart-0.2.0/gdchart.c:360: error: ‘gdchart_functions’ undeclared here (not in a function)

If you’re in a hurry or your C/C++ is a little rusty you’re in luck, this is how to fix it. In the source file gdchart-0.2.0/gdchart.c perform these replacements:

< function_entry gdchart_functions[] = {
> zend_function_entry gdchart_functions[] = {
< 	zend_hash_copy(intern->, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
> 	object_properties_init((zend_object*) &(intern->zo), class_type);

Then perform the usual extension compilation routine:
gdchart-0.2.0]$ phpize
gdchart-0.2.0]$ ./configure
gdchart-0.2.0]$ make && make test

As you can see, you’re not done. Don’t try to install this module yet it won’t load, failing with PHP Warning: PHP Startup: Unable to load dynamic library '/home/jack/build/gdchart-0.2.0/modules/' - /home/jack/build/gdchart-0.2.0/modules/ undefined symbol: php_gd_gdFontMediumBold in Unknown on line 0

Now we have to patch some PHP GD core files to accommodate changes in the visibility of a few GD resources, fortunately we have a patch for that here:

After patching the PHP sources, recompile and install along with the GDChart extension. Or do what any sane person would do and use a more recent and maintained visualization library like PHPlot, pChart or Google Charts.

This was a real annoyance to sort out, and I’ll likely need to do this again on the next kernel update so I’m documenting it here. The Corsair K70 is a great device, ignoring the pretty lights it’s a solid input device though it does have one particularly annoying functional aspect in various versions of Linux and that is an approximate 12-30 second delay during boot where the USB polling routine fails to enumerate the device (during report ret.) and time out before continuing. The following pertains to Ubuntu and Fedora/CentOS.

In your boot log (/var/log/boot.log) you will see a series of logged events similar to this:

workstation kernel: [   11.945167] hid-generic 0003:1B1C:1B13.0002: usb_submit_urb(ctrl) failed: -1
workstation kernel: [   11.945175] hid-generic 0003:1B1C:1B13.0002: timeout initializing reports
workstation kernel: [   11.945284] input: Corsair Corsair K70 RGB Gaming Keyboard  as /devices/pci0000:00/0000:00:14.0/usb2/2-10/2-10:1.1/0003:1B1C:1B13.0002/input/input15
workstation kernel: [   11.945373] hid-generic 0003:1B1C:1B13.0002: input,hidraw1: USB HID v1.11 Keyboard [Corsair Corsair K70 RGB Gaming Keyboard ] on usb-0000:00:14.0-10/input1
workstation kernel: [   21.954441] hid-generic 0003:1B1C:1B13.0003: timeout initializing reports
workstation kernel: [   21.954651] hid-generic 0003:1B1C:1B13.0003: hiddev0,hidraw2: USB HID v1.11 Device [Corsair Corsair K70 RGB Gaming Keyboard ] on usb-0000:00:14.0-10/input2
workstation kernel: [   31.967629] hid-generic 0003:1B1C:1B13.0004: usb_submit_urb(ctrl) failed: -1
workstation kernel: [   31.967642] hid-generic 0003:1B1C:1B13.0004: timeout initializing reports
workstation kernel: [   31.967762] hid-generic 0003:1B1C:1B13.0004: hiddev0,hidraw3: USB HID v1.11 Device [Corsair Corsair K70 RGB Gaming Keyboard ] on usb-0000:00:14.0-10/input3

As you can see the K70 is actually composed of 3 different input devices. The first being the light controller, the second being the the media controls and the third is the keyboard device which eventually loads. The first two fail during report retrieval and are the cause of the delay, this is likely a kernel bug and may take time before support is added. In the meantime we can get around the problem by introducing a usb “quirks” directive to instruct the kernel to not wait for these devices to be recognized/reported and continue.

To do this, find the devices vendor and device IDs:
~$ lsusb -v
which gives something like
Bus 002 Device 003: ID 1b1c:1b13 Corsair
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x1b1c Corsair
idProduct 0x1b13

bcdDevice 1.30
iManufacturer 1
iProduct 2
iSerial 3
bNumConfigurations 1
Configuration Descriptor:
<<<******etc, etc******>>>

We need the ‘idVendor’ and ‘idProduct’ values to construct the quirks directive. Now open a terminal and use vim/nano/gedit/*whatever to open ‘/etc/modprobe.d/usbhid.conf’ and add the following:
options usbhid quirks=0x1B1C:0x1B13:0x20000000

The syntax of this directive is ‘usbhid quirks=vendor:product:quirk’, where ‘quirk’ is the defined instruction “HID_QUIRK_NO_INIT_REPORTS” defined in the 3.16 kernel sources ‘linux/hid.h’ -> #define HID_QUIRK_NO_INIT_REPORTS 0x20000000 This simply instructs the kernel not to attempt to generate a device report for the K70 on boot.

Now we need to rebuild initramfs to include the change in the root file system.
Ubuntu:~$ sudo update-initramfs -u
Fedora:~$ sudo dracut -f

Now reboot and notice there’s no more delay.

Spectrum analyzers are neat, software spectrum analyzers are not quite as neat but still useful. Spek (spɛk/, ‘bacon’ in Dutch) is a great library that provides a fast and accurate method to generate spectrograms. For one reason or another, it’s missing from recent repositories for RHEL derivatives, in this case Fedora 22. No worries, you can find the source on GitHub here.

Maybe you’ve broken your legs and are desperate for reading material, or have some neurological condition which compels you to actually read the instructions and attempt to run the autogen script and get a series of nasty error messages like
autoreconf: Entering directory `.'
autoreconf: running: intltoolize --automake --copy --force
autoreconf: running: aclocal --force warning: macro 'AM_OPTIONS_WXCONFIG' not found in library warning: macro 'AM_PATH_WXCONFIG' not found in library
autoreconf: tracing
autoreconf: AM_GNU_GETTEXT_VERSION is used, but not AM_GNU_GETTEXT
autoreconf: not using Libtool
autoreconf: running: /usr/bin/autoconf --force error: possibly undefined macro: AM_OPTIONS_WXCONFIG
If this token and others are legitimate, please use m4_pattern_allow.
See the Autoconf documentation. error: possibly undefined macro: AM_PATH_WXCONFIG
autoreconf: /usr/bin/autoconf failed with exit status: 1

First of all, if you’ve gotten this far you obviously have autoconf, automake, intltool, etc. already installed. Good job. What you are missing are a few of the pkg-config dependencies for GTK, which will be confusing because on Fedora at least these packages will be under wxGTK + wxGTK-devel, so to fix this:
sudo dnf install wxGTK wxGTK-devel

Now clean up your build dir with GIT and ./ again.

If your phone supports it and you haven’t already I strongly suggest encrypting it and setting your password to “i_am_batman”. This way if you are ever swept off the street into an unmarked Econoline van and taken to a temporary Federal interrogation facility and they ask you for the password you get to lean in real slow and tell some secret agent shithead that you are in fact the batman, and realize every 8 year old boy’s dream. Doing so has the fortunate side effect of further obfuscating the identity of the real batman by introducing a wild spike it false potential IDs.

This is of course only if you don’t actually have secret documents on your phone, then it’s probably not such a good idea.

Tasked with archiving large groups of tables, moving from one database to another. There are a few caveats involved depending on the architecture of the tables being moved, specifically bugs in MySQL 5.1, 5.5, 5.6 and maybe a few more versions documented here. this procedure handles the AUTO_INCREMENT issue, but will not alter tables containing various types of indexes. There are parameters for origin and destination databases in case you make a mistake and need to move one back. The archiveTable parameter is a boolean value 1/0, the rest is fairly straight forward.

-- set a temp delimiter for procedure construction
-- create the procedure
CREATE PROCEDURE archive_tables(tablePrefix VARCHAR(32), originTable VARCHAR(32), destinationTable VARCHAR(32), archiveTable BOOLEAN)
    -- declare the variables
    DECLARE tableName VARCHAR(50);
    DECLARE newTableName VARCHAR(70);
    DECLARE mv_query VARCHAR(1000);
    DECLARE alt_query VARCHAR(1000);
	-- create the cursor with the selected tables
	    FROM information_schema.TABLES 
		AND TABLE_SCHEMA=originTable;
	-- this turns 'done' TRUE when there are no more tables

	-- begin
    OPEN cur1;
    read_loop: LOOP
	    -- push the current cursor element into the tableName var
        FETCH cur1 INTO tableName;
		-- if we are done, stop
        IF done THEN
            LEAVE read_loop;
        END IF;
        SET newTableName = CONCAT(destinationTable,'.',tableName);

		-- create the rename query
        SET mv_query = CONCAT('RENAME TABLE ', tableName, ' TO ', newTableName);
        SET @mvQuery = mv_query;

		-- exec rename
        PREPARE stmt FROM @mvQuery;
        EXECUTE stmt;

        -- are we archiving the relocated tables?
		-- Note: This engine will not work with all tables, there is also a bug related to AI columns
		--       documented here: (Dev is running 5.1.73) The
		--       temp workaround is setting AUTO_INCREMENT to 0, but even this is not sufficient for
		--       all tables. I suggest not trying to use this feature even though the benefits are many.
		IF archiveTable THEN
			-- create engine conversion query
		    SET alt_query = CONCAT('ALTER TABLE ', newTableName, ' AUTO_INCREMENT=0 ENGINE=archive');
			SET @altQuery = alt_query;
			-- set the engine attribute
			PREPARE stmt FROM @altQuery;
            EXECUTE stmt;
            DEALLOCATE PREPARE stmt;

This is a simple bash script you can use to quickly convert a folder of music in AAC or FLAC into MP3 for use on a mobile device or small storage. To accommodate different input formats simple change the file suffix in the first line and the name variable regular expression from ‘mp4’ to ‘m4a’ or ‘flac’, etc. To use, copy/paste the script into a file within the folder to be converted and save it, then $chmod +x the_file_name and run the script ./the_file_name
The Script:

for f in *.mp4
    name=`echo "$f" | sed -e "s/.mp4$//g"`
    ffmpeg -i "$f" -vn -ar 44100 -ac 2 -ab 320k -f mp3 "$name.mp3"

This script relies upon ffmpeg compiled with mp3 support (lamemp3).