[PHP]imagecreatefrompng Error (After upgrading FreeBSD)

Today, I found that one of my PHP scripts stop working. After some investigations, I found that it was the function, imagecreatefrompng, which caused the problem.

Interestingly, other similar functions such as imagecreatefromgif and imagecreatefromjpeg were completely working fine. The program stopped working when calling imagecreatefrompng only.

Initially, I thought the problem was coming from the PHP side. Therefore, I tried to get the error messages as many as possible, such as PHP error (error_reporting), Apache error (error_log), and even system error (dmesg). Unfortunately, I couldn’t find anything.

The script was working completely fine until I upgraded the system. So I think the problem may come from a missing library. To give you some background, here is how imagecreatefrompng works. First, your program calls imagecreatefrompng, which involves the GD library. GD library calls a PNG function in your system (possibly libpng) to process the PNG file. Since the program comes with from the system library, PHP / Apache will not report anything about it.

Since it will be too complicated to identify which library caused the problem, I decide to reinstall all ports. It sounds a very long process but it wasn’t at all. It only took 20 minutes to finish the whole thing. So here is what I did:

#FreeBSD
#sudo portmaster -fa

After the installation is completed, I rebooted the machine and everything worked again!

Enjoy!

–Derrick

Our sponsors:

Say NO to SOPA/PIPA

Everyday, many people from US and other countries find their solutions here to solve their computer problem through the search engine. If the Stop Online Piracy Act (SOPA) and Protect Intellectual Property Act (PIPA) are passed, it simply allows US government to censor the web. Someday, IceSquare may be blocked from the major search engines. In the other words, you won’t be able to find any solutions of your computer problem here.

Please sign the petition at Google to oppose SOPA and PIPA. If you live in US, please click here to tell your congress not to censor the web. Please visit here if you like to learn more about SOPA and PIPA.

Thank you.

–Derrick

Our sponsors:

[FreeBSD+ZFS]One or more devices has experienced an error resulting in data corruption. Applications may be affected.

When you check the ZFS status, you may find the following error message: One or more devices has experienced an error resulting in data corruption. Applications may be affected.. There can be million reasons to cause this error message showing up. Of course, 99% of them are caused by hardware failure, such as bad hard drives, broken cables, defective motherboard, or even bad memory. In this article, I am assuming that you already eliminated these possibilities, and have scratched your head for hours, and still have no clue which part went wrong. In fact, that’s what I did today.

Long story short. Here is how I experienced this error:

FreeBSD: 8.2-> 9.0
ZFS: 4 -> 5
ZPool: 15 -> 28

My system was working fine (FreeBSD 8.2; ZFS ver. 4, Zpool ver. 15), everything seems perfect. After I upgraded my system to FreeBSD 9, I upgraded the ZFS and Zpool to ver.5 and ver. 28, respectively. Everything seemed working fine until I check the status:

sudo zpool status -v
#sudo zpool status -v
  pool: storage
 state: ONLINE
status: One or more devices has experienced an error resulting in data
        corruption.  Applications may be affected.
action: Restore the file in question if possible.  Otherwise restore the
        entire pool from backup.
   see: http://www.sun.com/msg/ZFS-8000-8A
config:

        NAME        STATE     READ WRITE CKSUM
        storage     ONLINE       0     0     0
          raidz1-0  ONLINE       0     0     0
            ada0    ONLINE       0     0     0
            ada2    ONLINE       0     0     0
            ada3    ONLINE       0     0     0
            ada4    ONLINE       0     0     0
            ada5    ONLINE       0     0     0
            ada6    ONLINE       0     0     0
            ada7    ONLINE       0     0     0

errors: Permanent errors have been detected in the following files:

        storage/data:<0x0>

There are few things you need to pay attention:

The pool seems working fine, otherwise you will see FAULTED instead of ONLINE:

state: ONLINE

The system has no problem to read/write the data. Doesn’t seem to be hardware problem:

NAME        STATE     READ WRITE CKSUM
        storage     ONLINE       0     0     0
          raidz1-0  ONLINE       0     0     0
            ada0    ONLINE       0     0     0
            ada2    ONLINE       0     0     0
            ada3    ONLINE       0     0     0
            ada4    ONLINE       0     0     0
            ada5    ONLINE       0     0     0
            ada6    ONLINE       0     0     0
            ada7    ONLINE       0     0     0

This error message may give you some clue what’s wrong. Notice that storage and data are the pool names.

errors: Permanent errors have been detected in the following files:

        storage/data:<0x0>

The <0x0> represents the meta data of the pool. I think the problem may come from the upgrade process. Here are the steps how to solve this problem.

Force Clearing the Error

You can try to clear the error by running:

sudo zpool clear -F mypool

If it can clear the error, you are done. However, it is likely that it won’t work, and you need to move to the next step.

Scrubbing the Pool

You can try to scrub the entire pool by running:

sudo zpool scrub mypool

This will make the system to inspect every single block and correct the error. Although this process is long (It took 5 hours to inspect my 10TB pool), there is a very high chance that the problem will be corrected. Don’t forget to clear error after scrubbing the pool.

Making each devices online again

If the error still exists after scrubbing the entire pool (and clearing the error), you can try to force making each device go online:

sudo zpool online mypool /dev/ada0 /dev/ada2 /dev/ad4 ...

Try to reboot the computer

This is the last thing you can try. This will force the computer to mount the pool again. Hopefully it will clear the error and error status.

Rebuild the pool

If none of the method works, the only solution left is to rebuild the pool.

#Backup your data first
#sudo zpool destroy mypool
#sudo zpool create mypool ...

Good luck.

Our sponsors:

How to Clean Up / Reset User Account To Default on Linux, Ubuntu, Fedora Automatically

Imagine that you set up a computer at a public location, such as cafe, library, or computer lab in your school, so that any one can use your computer. Most of the time, users mainly use the web browsers for surfing the web, checking the email, or updating the status on social websites etc. At the mean time, they may download some files on your computer, generating a lot of browsing history in your web browsers, accidentally saving their user names/passwords in the browsers etc. How do you clean up these mess? How do you reset the user account to default automatically?

First, I am assuming that your computer is running Linux, such as Ubuntu, Fedora, Debian etc. It really doesn’t matter which Linux you use, because most Linux uses the same kernel. The idea describes in this article is applicable to any Linux.

Idea

Linux and Windows are very very different. Linux has a much better control on the user permissions. For example, if you simply create a standard user on Linux, e.g.,

sudo adduser guestuser

where this new user, guestuser, is a standard user only.

If you log in as guestuser, all of the files you create will be stored in your home folder only, i.e., /home/guestuser. Unlike Windows, there is no registry or something similar. In the other words, all of your activities are limited within your home folder. If you like to create a file outside your scope, you will need to have the root access. Of course, you won’t grand the root access to the guest user.

Now you understand that the guest user can only mess around the home directory only (/home/guestuser). In order to clean up or reset the user account to default, all you need is to reset this folder to default.

Setup a Home Directory On Ram Disk

We are going to implement this idea using ram disk. If you don’t know anything about ram disk, you can think about it as a usb thumb drive, except that it is a super fast device, and cannot hold any data after each reboot. In the other words, if we set up a the home directory of the guestuser on a ram disk, all of the mess will be gone after each reboot. So here are the steps:

First, we want to create a guestuser first:

sudo adduser guestuser

This will add a new user into the system and create its home directory. Next, we want to create a ram disk. Before we do it, let’s find out how much memory you have in your system:

free -m

On my machine, I have 2GB (2000 MB) memory in total.

             total     used     free   shared  buffers  cached
Mem:          1999     1789      209        0      119    1176
-/+ buffers/cache:      492     1506
Swap:         3150        0     3150

Since I only have 2GB of memory, I want to keep some of them for my system. I think using 512MB for the ramdisk is enough.

To create a ramdisk during the boot, simply modify /etc/rc.local

sudo nano /etc/rc.local

And include the following commands:

#Create a 512MB ramdisk, and map it to the home directory of the guestuser.
mount -t ramfs -o size=512M ramfs /home/guestuser


#After the ramdisk is mapped, the directory will be owned by the root.
#We need to modify the permission such that guestuser can access it.
chown -R guest:guest /home/guestuser

Here are some special notes for different Linux:

Fedora 15 or earlier: None

Fedora 16: By default, /etc/rc.local is missing. Please refer my another post: Fedora 16 /etc/rc.local is missing) for details.

Ubuntu: Please include your code before exit 0 command, otherwise it won’t work, i.e.,

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

mount -t ramfs -o size=512M ramfs /home/guestuser
chown -R guestuser:guestuser /home/guestuser

exit 0

After the set up is completed, simply reboot the computer to make the ramdisk effective.

Testing

Now, try to log in as the guestuser. You can try to download some files to your home directory; visit some websites; or even change the wallpaper. All of these settings will be stored in your home directory. Next, try to log out the account, restart the computer and log in to your account again. You will notice that everything will be reset to default, i.e., all of your previously downloaded files are gone, wallpaper will be reset to default, the web history is cleared etc.

Enjoy running a clean, maintenance-free workstation.

Our sponsors:

[FreeBSD]Problem to update PHP port

A new version of PHP (5.3.9) was available in FreeBSD today. Since it contained a lot of security fixes and enhancements, I decided to give it a try. After testing the new PHP in couple test servers, I think it is ready to upgrade the PHP on the production server. Oh well, I didn’t expect that I needed to spend my whole lunch break to trouble-shoot this problem. So here is what I did:

# cd /usr/ports/lang/php5
# make install
===>  Vulnerability check disabled, database not found
===>  License check disabled, port has not defined LICENSE
===>  Found saved configuration for php5-5.3.9
===>  Extracting for php5-5.3.9
=> SHA256 Checksum mismatch for php-5.3.9.tar.bz2.
=> SHA256 Checksum OK for suhosin-patch-5.3.4-0.9.10.patch.gz.
===>  Refetch for 1 more times files: php-5.3.9.tar.bz2
===>  Vulnerability check disabled, database not found
===>  License check disabled, port has not defined LICENSE
===>  Found saved configuration for php5-5.3.9
=> php-5.3.9.tar.bz2 doesn't seem to exist in /usr/ports/distfiles/.
=> Attempting to fetch from http://dk.php.net/distributions/.
fetch: http://dk.php.net/distributions/php-5.3.9.tar.bz2: Requested Range Not Satisfiable
=> Attempting to fetch from http://de.php.net/distributions/.
fetch: http://de.php.net/distributions/php-5.3.9.tar.bz2: Requested Range Not Satisfiable
=> Attempting to fetch from http://es.php.net/distributions/.
fetch: http://es.php.net/distributions/php-5.3.9.tar.bz2: Requested Range Not Satisfiable
=> Attempting to fetch from http://fi.php.net/distributions/.
fetch: http://fi.php.net/distributions/php-5.3.9.tar.bz2: Requested Range Not Satisfiable
=> Attempting to fetch from http://fr.php.net/distributions/.
===>  Vulnerability check disabled, database not found
===>  License check disabled, port has not defined LICENSE
===>  Found saved configuration for php5-5.3.9
=> SHA256 Checksum mismatch for php-5.3.9.tar.bz2.
=> SHA256 Checksum OK for  suhosin-patch-5.3.9-0.9.10.patch.gz
===>  Giving up on fetching files: php-5.3.9.tar.bz2
Make sure the Makefile and distinfo file (/usr/ports/lang/php5/distinfo)
are up to date.  If you are absolutely sure you want to override this
check, type "make NO_CHECKSUM=yes [other args]".
*** Error code 1

Stop in /usr/ports/lang/php5.
*** Error code 1

Stop in /usr/ports/lang/php5.
*** Error code 1

Stop in /usr/ports/lang/php5.

Initially, I thought it was a checksum error. So I decided to skip the checksum, i.e.,

#make install NO_CHECKSUM=yes

Unfortunately, it gave the same error. I think the problem might come from corrupted port files or port database. Instead of finding the source of the problem, I decided to rebuild the whole thing.

First, let’s remove the port database:

#sudo rm -Rf /var/db/portsnap/*

Next, we need to re-download all port files:

#sudo portsnap fetch extract

Some new ports may be released during the extraction, let’s make sure that the port tree is up to date:

#sudo portsnap fetch update

Now, we need to manually download the php source. Make sure that the file is stored in /usr/ports/distfiles/

#cd /usr/ports/distfiles/
#sudo wget http://fi.php.net/distributions/php-5.3.9.tar.bz2

Now, try to test whether the system can build php again. Notice that this will not install the PHP in your system.

cd /usr/ports/lang/php5
sudo make

If it gives no error, which means the PHP is ready to go. Now let’s clean up our work and make sure everything is ready.

sudo make clean

Notice that there is no way to upgrade the PHP from Make without uninstall it. Since it is a production server, I want to keep the website running. So I decide to let Portmaster to do all dirty works for me.

sudo portmaster -Da

Depending on your CPU, it may take 5 minutes to an hour to finish the update. Normally, the standard php package will work fine after the update. However, if it is not a standard package, such as PECL, you will need to do one more step. For example, here is the error messages right after I upgraded PHP:

#php -v
[eAccelerator] This build of "eAccelerator" was compiled for PHP version 5.3.8.
Rebuild it for your PHP version (5.3.9) or download precompiled binaries.

PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/local/lib/php/20090626/memcache.so' - /usr/local/lib/php/20090626/memcache.so: Undefined symbol "php_session_create_id" in Unknown on line 0

PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/local/lib/php/20090626/tokyo_tyrant.so' - /usr/local/lib/php/20090626/tokyo_tyrant.so: Undefined symbol "ps_globals" in Unknown on line 0

PHP 5.3.9 with Suhosin-Patch (cli) (built: Jan 12 2012 13:09:43)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies

[eAccelerator] This build of “eAccelerator” was compiled for PHP version 5.3.8.
Rebuild it for your PHP version (5.3.9) or download precompiled binaries.

To solve this problem, simple rebuild the package, i.e.,

cd /usr/ports/www/eaccelerator
sudo make deinstall install clean

PHP Warning: PHP Startup: Unable to load dynamic library ‘/usr/local/lib/php/20090626/memcache.so’ – /usr/local/lib/php/20090626/memcache.so: Undefined symbol “php_session_create_id” in Unknown on line 0

#cd /usr/ports/databases/pecl-memcache
#sudo make deinstall
#sudo make install clean

PHP Warning: PHP Startup: Unable to load dynamic library ‘/usr/local/lib/php/20090626/tokyo_tyrant.so’ – /usr/local/lib/php/20090626/tokyo_tyrant.so: Undefined symbol “ps_globals” in Unknown on line 0

#cd /usr/ports/pecl-tokyo_tyrant
#sudo make deinstall
#sudo make install clean

After the re-installation is completed, make sure that PHP gives no complain:

#php -v

PHP 5.3.9 with Suhosin-Patch (cli) (built: Jan 12 2012 13:09:43)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies

That’s it! Have fun.

Our sponsors: