Pydio PHP cloneNode() error

Last friday, after updating from PHP 5.5.6 to PHP 5.5.7, Pydio (formerly AjaXplorer) wasn’t working anymore.

I’m using nginx 1.4.4 + PHP 5.5.7 and when I tried to open Pydio I only got 502 Bad Gateway or the following error:

2013/12/13 12:40:24 [error] 21628#0: *85 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Call to a member function cloneNode() on a non-object in /var/www/site.nl/core/classes/class.AJXP_Plugin.php on line 276" while reading response header from upstream, client: 193.x.x.x, server: site.nl, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "site.nl"

I have been searching for a solution for hours, but even installing a fresh copy of Pydio wouldn’t work (I couldn’t get to the installer page, same error).

After a long time searching on Google and the PHP changelog I asked for help on the Pydio forums. Someone told me to downgrade PHP, but that’s the last thing I would try.

Pydio still didn’t work after trying many things. Then, after looking at the PHP changelog again, I disabled PHP’s built-in opcache, and Pydio was working again!

So, if you have the same problem, just disable PHP’s built-in opcache. I don’t know if this is a bug in PHP or Pydio, but I’ll just try to enable opcache again in PHP 5.5.8.

Update 08-02-2014 – It seems to work normally again with PHP 5.5.9 (changelog).

TransIP DDNS

Today I made a new PHP script using the TransIP API to update DNS entries. This way it’s possible to automatically update your (dynamic) home IP address for example.

To use this script you need a server with a static IP address and PHP support. If you don’t have a server with a static IP address, free hosting will do the job.

Follow these steps to install this script:

  1. Download the TransIP API to your server
  2. Go to the TransIP CP (My account > API settings)
  3. Enable the API and add your server’s IP address to the list
  4. Add a new Key Pair and copy the key to your clipboard
  5. Edit Transip/ApiSettings.php and set $login and $privateKey (the key you just copied)
  6. Download the script below to your server (dns.php)
  7. Edit the settings in dns.php (domain, key, and records to update)
    This key is used to identify the client, this way the DNS won’t be updated with the IP address of someone else
    Do NOT use the same key as your TransIP API key, the use of a 25 characters long A-Z a-z 0-9 key is recommended
  8. Now, on the client, access dns.php on the server to update the DNS entries
    On Linux you can create a cronjob with the following command (don’t forget to replace the key):
    wget --spider http://example.com/dns.php?key=69l67Le20e819360d3YHO1175

You’re done. You can test if the script works by openening the URL in your browser and then check if the values are updated in the TransIP CP.


<?php
// SETTINGS
// The domain to edit
define('DOMAIN', 'example.com');

// The authentication key
define('KEY', '69l67Le20e819360d3YHO1175');

// The DNS entries to update (name => content)
// This script will NOT add new entries
$newValues = [
  'www' => $_SERVER['REMOTE_ADDR'],
];

// SCRIPT
// Exit if the key does not match
if($_GET['key'] != KEY) exit();

// Include the required files from the API
require_once('Transip/DomainService.php');

// Get the current DNS entries from TransIP
$dnsEntries = Transip_DomainService::getInfo(DOMAIN)->dnsEntries;

// Check every DNS entry
foreach($dnsEntries as $dnsEntry)
{
  // Check if the entry has to be updated and update it
  if(array_key_exists($dnsEntry->name, $newValues)) $dnsEntry->content = $newValues[$dnsEntry->name];
}

try
{
  // Commit the changes to the TransIP DNS servers
  Transip_DomainService::setDnsEntries(DOMAIN, $dnsEntries);
  // Done
  echo 'DNS updated.';
}
catch(SoapFault $f)
{
  // An error occured
  echo 'DNS not updated. ' . $f->getMessage();
}
?>

MySQL UNIX socket

When using phpMyAdmin earlier today I noticed it was connected to MySQL through an UNIX socket.

UNIX sockets are faster than TCP/IP connections and if there is an UNIX socket and a TCP/IP connection available the UNIX socket should be selected by default (when using localhost as host).

However, how can you be sure this is the case?

If you only use your MySQL server locally you can force MySQL to only create a UNIX socket by adding skip-networking to your my.cnf. I also commented out bind-address = 127.0.0.1, just in case.

Restart your MySQL server and check if MySQL is not listening on TCP/IP anymore by executing netstat -a.

Now check if all your websites/applications can still access your MySQL server and you’re done.

Signing a DLL (Strong Name)

I was working on a project in C# and I had to sign an assembly with a Strong Name.

Here’s how I did that:

  • Go to the project’s properties
  • Go to the tab Signing
  • Check Sign the assembly
  • Choose <New...> from the drop-down list
  • Give it a name (I used my solution’s name) and uncheck Protect my key file with a password

The assembly was signed now. However, when I tried to build it, an error occurred:

Assembly generation failed -- Referenced assembly 'Assembly' does not have a strong name

So the DLL had to be signed, too. Luckily, I had the source of the DLL. It’s also possible to sign a DLL without the source, but this won’t always work.

Sign the DLL using the source

  • Open the project in Visual Studio
  • Follow the steps to sign an assembly above for the DLL (but now use the key you already created by clicking <Browse...> instead of <New...>)
  • Build the DLL

If you get the following error:

Friend assembly reference 'Assembly.Tests' is invalid. Strong-name signed assemblies must specify a public key in their InternalsVisibleTo declarations.

Replace the following values in the commands:

{SNK} The path to the combined key (.snk)
{PUB} The path to public key (will be created)
{KEY} The public key in SHA1 format
  • Double click the error
  • Start Visual Studio’s Developer Command Prompt
  • Issue the following commands:
    sn -p "{SNK}" "{PUB}"
    sn -tp "{PUB}"
  • This will display the public key, copy the public key under Public key (hash algorithm: sha1)
    Don’t copy the public key token!
  • Go back to your project
  • Locate the following line:
    [assembly: InternalsVisibleTo("Assembly.Tests")]
  • Put the public key in the string:
    [assembly: InternalsVisibleTo("Assembly.Tests, PublicKey={KEY}")]
  • Build the DLL

Sign the DLL without the source

Replace the following values in the commands:

{DLL} The path to the original DLL
{IL} The path to .il file (will be created)
{RES} The path to the .res file (located in the same folder as the .il file)
{KEY} The path to the .snk file (the key file)
{DLL2} The path to the signed DLL (will be created)
  • Start Visual Studio’s Developer Command Prompt
  • Run the following commands:
    ildasm "{DLL}" /out:"{IL}"
    ilasm "{IL}" /res:"{RES}" /dll /key:"{KEY}" /out:"{DLL2}"

The DLL has now been signed with your key. Just re-add the reference to the new, signed DLL in your project and rebuild.

Pair PC with YouTube TV

If you have a smart TV with the YouTube app on it, you can pair your TV with your phone or tablet in order to take control of the YouTube app with them.

Unfortunately, it is not possible to pair your PC or notebook with the YouTube app. However, with this quick and easy workaround you’ll be able to do so.

In order to pair your TV with your PC, you should first get the pair code from your tv.

Then simply go to m.youtube.com/pair, enter the code and click Add.

I’ve tested this workaround with Firefox 20, but in other browsers you may need to change your User Agent before going to m.youtube.com/pair.

Changing your User Agent

This setting may be only set for the tab you’re currently working on, so I advise you to open a new tab before changing the User Agent.

Mozilla Firefox

  • Install User Agent Switcher
  • Press the Alt key on your keyboard, the menu bar will show up
  • Click Extra > Default User Agent > iPhone 3.0

Google Chrome

  • Open the developer panel (CTRL + SHIFT + I)
  • Click the gear icon to open settings (located in the lower right corner)
  • In the tab Overrides check User Agent and set it to a mobile device

DO NOT close the developer panel as it will reset your User Agent, you can just resize it instead!

Now go to the pair page, you should change your User Agent back when you’re done!

Move the MySQL data directory

Today I got my new Cubieboard. I installed Debian Wheezy on a 4 GB SD Card, but the Cubieboard also has built-in NAND memory. I wanted to place all the data for the webserver on the NAND memory for faster access. Everything went well except for moving the MySQL data directory.

At first, I just edited /etc/mysql/my.cnf, changed datadir = /var/lib/mysql to datadir = /nanda/mysql and moved the data directory to the NAND memory. MySQL wouldn’t start anymore.

The solution was pretty easy. I just had to reinitilize the MySQL databases (mysql_install_db --user=mysql --ldata=/nanda/mysql). After that, I restarted MySQL and it worked!

In my case I had to reboot the whole system because I couldn’t access my databases trough PHP. This may be caused by the many attempts I have made to fix this problem.

High load average fix

The load on my Cubieboard was constantly above 1.0, which is way too much for a single core device, so I started searching for a solution. After looking in top, I saw that usb-hardware-sc was probably the problem, because it was in D state (TASK_UNINTERRUPTIBLE).
I tried to kill it with signal 9 but of course that wouldn’t work. When searching for usb-hardware-sc I saw that there were some other people who noticed this, but they didn’t have a solution.

At this point I contacted rm because I thought it may be a problem with his kernel. He told me it may be a problem with script.bin, which controls the hardware configuration. Unfortunately I don’t have Android’s script.bin anymore, so I continued my search before extracting it from the Android image.

Eventually I found a solution. It is pretty simple and it works! I just downloaded a clean script.bin from Cubieboard’s hwpack, converted it to script.fex (./bin2fex script.bin script.fex) opened it with vi, searched for [usbc0] and replaced the whole block by the following:

[usbc0]
usb_used = 1
usb_port_type = 0
usb_detect_type = 0
usb_id_gpio =
usb_det_vbus_gpio =
usb_drv_vbus_gpio = port:PB09<1><0><default><0>
usb_host_init_state = 0

Then I just converted it back (./fex2bin script.fex script.bin), copied it to the boot partition (cp script.bin /boot) and rebooted my Cubieboard. Now everything runs fine with a nice low load!

Extend partitions with fdisk

Another post about my new Cubieboard. The image I used had a fixed size of 2 GB. Because I wanted to use my whole 4 GB SD Card I had to extend my rootfs partition (in my case /dev/mmcblk0p2).

When doing some research about resizing partitions on Linux I saw many posts about LVM. Of course I don’t have a LVM setup on my Cubieboard so I had to find another solution.

Eventually I found a solution for LVM and tried it for my setup.

  • fdisk /dev/mmcblk0
  • p (remember the start sector of partition 2)
  • d (remove partition, choose partition 2)
  • n (create new partition, number 2, start sector of step 2, leave end sector as default)
  • w (write changes to disk and exit)

After this I had to reboot my system for the changes to take effect. The system still worked!

The partition has been extended but there was no file system on the extended space, so the usable space was still 2 GB. To create a filesystem on the extended space I executed the following command: resize2fs /dev/mmcblk0p2. A few seconds later my rootfs was 4 GB!

Enable LEDs with rm’s kernel

I’m using rm’s kernel, but I couldn’t control my Cubieboard’s LEDs while using this kernel. If I used the stock kernel from Cubieboard’s hwpack it all worked.

First I thought it was disabled because I use the ‘server’ edition of the kernel, which is just a kernel with many disabled features a server doesn’t need to safe resources, but this wasn’t the case.

After some searching in the modules I saw that there is a module called leds-sunxi.

The only thing I had to do was to add the following code to script.bin:

[leds_para]
leds_used = 1
leds_num = 2
leds_pin_1 = port:PH20
leds_name_1 = "green:ph20:led1"
leds_pin_2 = port:PH21
leds_name_2 = "blue:ph21:led2"

Then use echo "leds-sunxi" >> /etc/modules to load the leds-sunxi module on boot and reboot.

After the reboot it worked again, now with rm’s kernel. For more info about controlling the LEDs, take a look at this tutorial.