CentOS 7 EPEL / REMI Location

CentOS 7 was released about a week ago, so I decided to give it a try. As you probably know, CentOS is a clone of Red Hat Enterprise Linux(RHEL). Typically, Red Hat put the new features in Fedora first. If things go well, they will move the new features to the RHEL, which eventually will be available in CentOS. In this new version, I see a lot of familiar features which I found in the last few release in Fedora, such as the new GNOME shell, new system service, Linux Kernel 3, etc. However, since RHEL/CentOS is target to enterprise users, who want nothing more than stability and reliably. They put a lot of effect to maintain the backward compatibility, such as /etc/rc.local, firewall etc. Personally, I really like these kind of extra care because it doesn’t break my existing settings.

CentOS 7 EPEL Repository Location

sudo rpm -Uvh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-1.noarch.rpm

sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

And don’t forget to enable the new repository in the config file, i.e.,

sudo nano /etc/yum.repos.d/remi.repo

[remi]
....
enabled=1 ----------------- Set this to one
...

Notice that there are some common packages that were available in these repositories in CentOS 5/6, but missing in CentOS 7, such as hddtemp. So please don’t be surprised that your favorite packages are missing. However, you can always install all of these special packages from source.

–Derrick

Our sponsors:

How to get HP LaserJet 1000 (or any ancient HP printers) working on Windows 7/8 64-bit

I bought a HP LaserJet 1000 printer back in 2001. Still Loving it! The running cost is low and the output quality is great. It is still working great after running for 13 years! Its quality even out beats my brand new Samsung LaserJet! HP LaserJet 1000 is a almost-perfect printer except that HP no longer supplies the right driver for modern operating system. Long story short, if you are a Windows 7/8 (64-bit) user, HP wants you to dump your fully working printer to the landfill and get a new one.

To be honest, I don’t see any reason why I should buy a new printer just because the driver is no longer available. The core part of the printing technology hasn’t been changed for many years. In the other words, if I get a new printer, I will expect to get the same results (may be slightly better) in terms of printing quality. That’s it. Anyway, if you have few hours to spend, you may want to follow this tutorial to give your printer a new life.

Normally, many printers share similar chips and processors such that if the driver of this model is not available, you can still use the drivers from other models. However, this printer is special. It does not have its own processor and it relies on the operating system to process the print job first before sending to it. That’s why driver is very important in this case.

I have googled for a solution for a long time because I don’t want to send this almost-perfect printer to landfill, and I don’t want to go back to Windows XP either. Unfortunately, most solutions I found online either do not work or don’t make any scenes to me. Here are some highlights:

Solution 1: Attach the printer to Windows XP 32-bit. Share the printer with Windows 7 64-bit through network.

Comments: No it won’t work. Windows 7/8 keeps asking for a driver, which I don’t have one.

Solution 2: Install a Windows XP 32-bit virtual machine (VM) in your Windows 7 64-bit. In the VM, install a software to monitor a folder and print all .PDF files automatically. At the same time, print your documents to PDF in Windows 7 and save the files in that folder.

Comments: Don’t you think it is too complicated?

Solution 3: Install the printer driver in XP mode.

Comments: No it won’t work!

Solution 4: Stick with Windows 7 32-bit

Comments: No way! I want to use more than 4GB of memory.

So after spending months and months and months to trial and error, I finally found a working solution. In fact, my solution is pretty simple. I attach my printer to a Linux box and share it on the network, i.e., I make my HP LaserJet 1000 to be a network printer. Now I can print from the following systems:

  • Windows 7/8 32-bit and 64-bit
  • OS X 10.9 64-bit
  • Windows XP 32-bit
  • Linux

Before we begin, we will need the following ingredients: A Linux Box. If you already have a Linux box, you are more than welcome to use it. If you don’t have one around, you may consider to grab a spare machine and install a Linux. The machine does not need to be very powerful. In my case, I use a Pentium 4 (1 GB ram) desktop which was born in 2004. You can go to local university / library / recycle center to get one. They usually sell it for very low price (below $30) or sometimes give away for free.

Install the HP Printer Driver

In this tutorial, I am going to use CentOS as an example. CentOS is a free version of Red Hat. You can use other Linux such as RHEL, Fedora, Scientific Linux etc. The reason why I prefer CentOS because of its stability and long term support. It is stable and I will be able to update the system for at least 7 years.

Before we begin, we want to make sure that the USB version 1 is available. Simply go to the BIOS and make sure that your system supports the legacy USB (i.e., USB 1). Since HP LaserJet 1000 uses USB 1, and some manufacturers disable the USB 1 settings by default, we want to enable them.

So after installing CentOS, we need to do the following:

#The default repository of CentOS is very limited. Let's add a more powerful one:
sudo rpm -Uvh http://linux.mirrors.es.net/fedora-epel/6/x86_64/epel-release-6-8.noarch.rpm
sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
sudo yum update --enablerepo=remi,remi-test

The following tutorial is based on this page. Depending on your hardware, I notice that the tutorial is not 100% working. You may want to follow my version below. Before we start, I encourage you to open this page first, and keep the current page side-by-side for reference.

#Install the developer tools
sudo yum groupinstall "Development Tools"
sudo yum install kernel-devel kernel-headers


#Install the HP printer and related
sudo yum install hplip hplip-gui hplip-libs

#Install the avahi daemon
sudo yum install avahi
sudo service avahi-daemon start

#Install the libraries required by hp
sudo yum install cups cups-devel gcc-c++ ghostscript libjpeg-devel glibc-headers libtool libusb-devel make python python-devel PyXML openssl-devel net-snmp-devel policycoreutils-gui PyQt PyQt-devel dbus-python notify-python sane-backends sane-backends-devel sane-frontends xsane python-imaging python-imaging-devel

#Depending on your HP printer. If your printer is old enough and use USB 1, you may want to install the following:
Install some hardware-related libraries
sudo yum install avahi-tools libusb1-devel libusb1 dbus dbus-devel libsane-hpaio


#Install the following chemicals:
sudo rpm -ev --nodeps libsane-hpaio
sudo rpm -ev hplip-gui
sudo rpm -ev hplip
sudo rpm -ev hpijs

Disable the SELinux. It’s like the Windows Firewall. A fancy looking crap which does nothing useful except causing lots of trouble.

sudo nano /etc/selinux/config

SELINUX=disabled

Now, visit here to get the latest version of HP software. Go to the latest directory and download the gz file. In the following, I will assume that the version is: 3.14.6, i.e., hplip-3.14.6.tar.gz. You may want to adjust the version.

Of course, we need to extract it.

tar xvfz hplip-3.14.6.tar.gz
cd hplip-3.14.6

Now, go to this page and head to step 5. Try to find the corresponding command to install HPLIP. In my case, I am using CentOS 6.5 64-bit, so my command will be:

./configure --with-hpppddir=/usr/share/cups/model/HP --libdir=/usr/lib64 --prefix=/usr --enable-qt4 --disable-libusb01_build --enable-doc-build --enable-cups-ppd-install --disable-foomatic-drv-install --disable-foomatic-ppd-install --disable-hpijs-install --disable-udev_sysfs_rules --disable-policykit --disable-cups-drv-install --enable-hpcups-install --enable-network-build --enable-dbus-build --enable-scan-build --enable-fax-build

In case you got error (such as missing libraries), try to run the following for trouble-shooting:

./check.py

Now, let’s compile the source. You may want to run the make as a regular user.

make

And we are ready to install it!

sudo make install

Oh, we need to add some important users as well:

su -c "/usr/sbin/usermod -a -G lp,sys $USER"

Time to reboot the computer:

sudo reboot

Now, log in to the desktop / graphic mode. We need to use the HP tool to set up the printer. Open the terminal within the CentOS graphic interface.

sudo hp-setup

Just following the instructions. It is very simple. Click here if you need help.

Now, let’s open the printer settings. You can either go to System –> Admin –> Printing, or run the following:

system-config-printer

Find your printer, open the property and print a test page. If you see the actual printer, you are half way done.

Make the Printer Available On The Network

sudo service cups start

Also, remember to set the CUPS password:

sudo lppasswd -a admin

Now, we need to update the firewall settings:

sudo nano /etc/sysconfig/iptables
-A INPUT -m state --state NEW -m udp -p udp --dport 631 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 631 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

and restart the firewall:

sudo service iptables restart

Now, let’s go to the following:

http://your_ip_address:631/printers/

Click your printer. In my case, mine is:

http://192.168.1.104:631/printers/hp_LaserJet_1000

Install the HP LaserJet 1000 on Windows 7/8 64-Bit

Now, go to Windows and add a printer. It’s a network printer. The corresponding location is:

http://192.168.1.104:631/printers/hp_LaserJet_1000

When it asks for the driver, try to use HP Laserjet 2300 PS. I found that this driver is pretty generic and it works great with my printer. After the installation is completed, try to print a test page. The idea will be similar in other operating systems, such as Windows XP and OS X.

Now your printer has a new life.

–Derrick

Our sponsors:

Shared object “libsqlite3.so.8” not found

I noticed some weird thing on my server today. When I ran some PHP code, I got the following error:

PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/local/lib/php/20121212-zts/pdo_sqlite.so' - Shared object "libsqliteo_sqlite.so" in Unknown on line 0

Warning: PHP Startup: Unable to load dynamic library '/usr/local/lib/php/20121212-zts/pdo_sqlite.so' - Shared object "libsqlite3.so.ite.so" in Unknown on line 0
PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/local/lib/php/20121212-zts/sqlite3.so' - Shared object "libsqlite3.se3.so" in Unknown on line 0

Warning: PHP Startup: Unable to load dynamic library '/usr/local/lib/php/20121212-zts/sqlite3.so' - Shared object "libsqlite3.so.8" " in Unknown on line 0
PHP 5.5.13 (cli) (built: Jun  3 2014 10:01:52)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
    with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2014, by Zend Technologies

Obviously, PHP SQLite extensions expect the library: libsqlite3.so.8, and it was missing or deleted after the upgrade. To solve this problem, we need to know where is the file.

sudo find / -name "libsqlite3.so*"

In my system, the file is here:

/usr/local/lib/libsqlite3.so.0
/usr/local/lib/libsqlite3.so.0.8.6

So I simply created the missing file by soft-linking it:

cd /usr/local/lib/
sudo ln -s libsqlite3.so libsqlite3.so.8

And the error is gone.

#php -v
PHP 5.5.13 (cli) (built: Jun  3 2014 10:01:52)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
    with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2014, by Zend Technologies

–Derrick

Our sponsors:

How to Expand ZFS

Today I am going to share my story with you on how to expand my ZFS storage. I have a giant ZFS pool, which consists of 8x2TB (RAIDZ2) and 4×1.5TB (RAIDZ1), with a total of 15TB usable spaces. Since I am running out of space, I decide to upgrade the ZFS by replacing the disks one at a time. So here is the ZFS structure:

#zpool status
        NAME        STATE     READ WRITE CKSUM
        storage     ONLINE       0     0     0
          raidz2-0  ONLINE       0     0     0
            ada0    ONLINE       0     0     0
            ada1    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
            ada8    ONLINE       0     0     0
          raidz1-1  ONLINE       0     0     0
            da0     ONLINE       0     0     0
            da1     ONLINE       0     0     0
            da2     ONLINE       0     0     0
            da3     ONLINE       0     0     0


#df
storage/data     14T     13T    1.3T    91%    /storage/

What I decide to do is to replace the 1.5TB disks by 3TB disks (i.e., da[0-3]) one at a time. Basically, here are the steps you typically found on the web:

  1. Power down the server
  2. Replace the 1.5TB disk by 3TB disk one at a time
  3. Power on the server
  4. Replace the disk
  5. Resilver the entire pool.
  6. Hope the resilver process does not return any error.
  7. Repeat the above steps until all disks are replaced.
  8. Turn on the auto expand option and enjoy the extra space

Here are the corresponding commands. After replacing the first disk, you should see the following:

#zpool status
        NAME        STATE     READ WRITE CKSUM
        storage     DEGRADED     0     0     0
          raidz2-0  ONLINE       0     0     0
            ada0    ONLINE       0     0     0
            ada1    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
            ada8    ONLINE       0     0     0
          raidz1-1  DEGRADED     0     0     0
            da0     UNAVAI       0     0     0 cannot open
            da1     ONLINE       0     0     0
            da2     ONLINE       0     0     0
            da3     ONLINE       0     0     0

However, the pool will continue to work because it is a RAIDZ pool. So I decide to swap the 1.5TB with the 3TB disk:

#sudo zpool replace mypool da0
#zpool status
        NAME        STATE     READ WRITE CKSUM
        storage     DEGRADED     0     0     0
          raidz2-0  ONLINE       0     0     0
            ada0    ONLINE       0     0     0
            ada1    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
            ada8    ONLINE       0     0     0
          raidz1-1  DEGRADED     0     0     0
      replacing-2   DEGRADED     0     0     0
        da0/old     FAULTED      0     0     0  corrupted data
        da0         ONLINE       0     0     0  (resilvering)
            da1     ONLINE       0     0     0
            da2     ONLINE       0     0     0
            da3     ONLINE       0     0     0

Depending on how much data you have on the old disk and the hardware (such as motherboard, SATA configurations etc), resilvering a 1.5TB drive (with 1.3TB of data) took me about 15 hours. Personally, I recommend to start this process in the morning, then you can check the progress and start the next one in the evening. That way you can speed up the work.

So after the resilvering process is done. Make sure that you check the error status. If some files were missing, you need to delete those files first and restore them from your backup. Here is an example of the error:

#sudo zpool status -v

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

/storage/data/aaa
/storage/data/bbb
/storage/data/ccc

Remember, you need to delete the file first, then put the file back from your backup. If you simply replace/overwrite the file, it will not clear the error. Try to check the status again. If the error is not gone yet, you may want to scrub the zpool to trigger the resilver process.

sudo zpool scrub mypool

Or you can try to clear the error message. It will trigger the resilver process automatically.

sudo zpool clear -f mypool

I know what you are trying to say now. How come the ZFS will lose the data even I have RAIDZ and checksum enabled? I have no idea. That’s why we need back up on a different machine. Anyway, the resilver process will take another 15 hours.

After the error is cleared, repeat the steps to replace the disks one by one. Make sure that the error is cleared after every replacement. For me, replacing four hard drives took me exact 5 days, or 120 hours in total. Yes, it is not a fun job.

So after everything is completed, no error or anything bad. You try to check the pool status and you expect a magic will happen. Unfortunately, you will see the same amount of space available. Here are what you will need to do:

#I still have 1.3TB space left.
storage/data     14T     13T    1.3T    91%    /storage/
sudo zpool set autoexpand=on mypool 

Locate one of the disks you have replaced, in my case, they are da0, da1, da2 and da3

#zpool status
        NAME        STATE     READ WRITE CKSUM
        storage     ONLINE       0     0     0
          raidz2-0  ONLINE       0     0     0
            ada0    ONLINE       0     0     0
            ada1    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
            ada8    ONLINE       0     0     0
          raidz1-1  ONLINE       0     0     0
            da0     ONLINE       0     0     0 --This
            da1     ONLINE       0     0     0 --This
            da2     ONLINE       0     0     0 --This
            da3     ONLINE       0     0     0 --And this
sudo zpool online -e mypool da0

And check the space again…

#Now I have 5.3TB space available.
storage     18T     13T    5.3T    72%    /storage

FYI, here is the math behind the free space calculations. I had 4 x 1.5TB on a RAIDZ1 setup. After the upgrade, I have 4 x 3TB on a RAIDZ1 set up. The increase space will be (3TB – 1.5TB) x (4 – 1) * 0.9 = 4TB

Enjoy the new space!

If you have spent too many hours on the resilvering process, consider the old school way. My old school method is nothing new, but it is rock solid, reliable, takes shorter time and most importantly, no data will be lost. Yes, you are right, I back up the data to another server first, and then I rebuild the ZFS pool on my main server, and copy the data back. Typically, copying the 10TB of data via rsync daemon over a gigabit network will take about 3 days. So it isn’t too bad. The only down side of this solution is the down time, which is about 3 days in my case. If you decide to go with the ZFS replacement, the downtime will be minimized, because the ZFS pool will continue to work during the resilver process.

Further read: How to Improve Rsync Performance

Hope my solutions help!

–Derrick

Our sponsors:

[FreeBSD]Shared object “libaprutil-1.so.5” not found, required by “httpd”

I upgraded the Apache to 2.2.27 on my FreeBSD box via portmaster. The upgrade went very smooth. After the upgrade, I decide to test the Apache by restarting the server. Oh well, I got the following error message:

[FreeBSD]Shared object "libaprutil-1.so.5" not found, required by "httpd"

Oh well, looks like libaprutil-1.so.5 is missing. How about I create this file by soft-linking from the newer version, such as libaprutil-1.so.6, libaprutil-1.so.7 etc. However, when I check the lib directory, I don’t see anything like that.

#/usr/local/lib
-rw-r--r--  1 root  wheel   251k Jun 11 10:58 libaprutil-1.a
-rwxr-xr-x  1 root  wheel   961B Jun 11 10:58 libaprutil-1.la
lrwxr-xr-x  1 root  wheel    21B Jun 11 10:58 libaprutil-1.so -> libaprutil-1.so.0.5.3
lrwxr-xr-x  1 root  wheel    21B Jun 11 10:58 libaprutil-1.so.0 -> libaprutil-1.so.0.5.3
-rwxr-xr-x  1 root  wheel   148k Jun 11 10:58 libaprutil-1.so.0.5.3

Looks like it is not that simple to solve the problem. After couple trials and errors, I came up a solution. First, I need to reinstall the Apache, and then I need to reinstall Apr1.

cd /usr/local/www/apache22
make

Notice that I compile the file without installing it. That’s because I want to check the library dependence.

cd /usr/ports/www/apache22/work/httpd-2.2.27
ldd ./httpd
./httpd:
        libm.so.5 => /lib/libm.so.5 (0x80087d000)
        libpcre.so.3 => /usr/local/lib/libpcre.so.3 (0x800a9e000)
        libaprutil-1.so.0 => /usr/local/lib/libaprutil-1.so.0 (0x800d02000)
        libdb-4.8.so.0 => /usr/local/lib/libdb-4.8.so.0 (0x800f27000)
        libgdbm.so.4 => /usr/local/lib/libgdbm.so.4 (0x801299000)
        libexpat.so.6 => /usr/local/lib/libexpat.so.6 (0x8014a4000)
        libiconv.so.3 => /usr/local/lib/libiconv.so.3 (0x8016c8000)
        libapr-1.so.0 => /usr/local/lib/libapr-1.so.0 (0x8019c4000)
        libcrypt.so.5 => /lib/libcrypt.so.5 (0x801bf5000)
        libthr.so.3 => /lib/libthr.so.3 (0x801e14000)
        libc.so.7 => /lib/libc.so.7 (0x802037000)
        libapr-1.so.5 => not found (0)
        libintl.so.9 => /usr/local/lib/libintl.so.9 (0x802392000)

So it is libaprutil-1.so.0, which is what we have in /usr/local/lib/. That’s good. Now we can hit the install button.

cd /usr/ports/www/apache22/
make reinstall

So let’s try to run Apache again. Looks like we got a different error message:

/usr/local/etc/rc.d/apache22 restart
Performing sanity check on apache22 configuration:
Shared object "libapr-1.so.5" not found, required by "libaprutil-1.so.0"

It’s okay. Let’s do something similar to the apr1:

cd /usr/ports/devel/apr1/
make reinstall

Try to restart Apache again. The problem should be gone:

/usr/local/etc/rc.d/apache22 restart
Performing sanity check on apache22 configuration:
Syntax OK
Stopping apache22.
Waiting for PIDS: 1022.
Performing sanity check on apache22 configuration:
Syntax OK
Starting apache22.

Hope my solutions help!

–Derrick

Our sponsors:

[FreeBSD]PHP does not work after upgrading Apache to 2.2.27

I upgraded the Apache to 2.2.27 on my FreeBSD box via portmaster. The upgrade went very smooth. After the upgrade, I found that Apache no longer rendered the PHP page correctly. In the other words, it displayed the source code of the PHP files instead of executing the code.

Before you start doing anything, please make sure that your website is not accessible from public. For example, most web applications like to include the password information in the source code, which is accessible by public if the PHP engine is failed. You may want to restrict the public access during the fix. The easiest way is to set up a .htaccess file and restrict the access by IP address.

Let’s come back to the fix. For some reasons, Apache/PHP team decide to make something fun to the FreeBSD sysadmin, because they think FreeBSD sysadmin have plenty of spare time. Here is what they decide to do:

Originally, we install Apache first, then we install PHP. When we install the PHP, we pick an option such that the PHP will install a PHP engine used by Apache. In the recent release, they decide to remove the engine from the standard PHP package. For example, if you simply use the portmaster to upgrade your PHP (In my case, PHP 5.4 and 5.5), the engine will be missing. That’s why Apache fails to render the PHP files.

Here is what you will need to do. I suggest you to finish reading the following before doing the fix. Trust me. It may save you couple hours.

First, make sure that Apache is working fine.

If you are using PHP 5.4, make sure that you install this port: /usr/ports/www/mod_php5. If you are using PHP 5.5, install this one instead: /usr/ports/www/mod_php55. Make sure that you select the ZTS option. You can do it by running:

sudo make config

Notice that installing this port will reinstall the PHP package (/usr/ports/lang/php5 or /usr/ports/lang/php55). Make sure that the ZTS option is selected in PHP package as well.

Now try to restart the Apache server. That should make the Apache to render the PHP files instead of dumping it.

#sudo /usr/local/etc/rc.d/apache stop
#sudo /usr/local/etc/rc.d/apache start

Test the PHP files again. If you see the PHP result instead of PHP source code, congratulations! You are 20% done.

Now go back to the command line and run the following:

#List the PHP extensions installed by PHP 
php -m

#Check whether the PHP extensions are loaded properly by PHP
php -v

For some reasons, I noticed that many extensions were missing during the reinstallation, such as sessions, json etc. Let’s install them back:

#For PHP 5.4
cd /usr/ports/lang/php5-extensions

#For PHP 5.5
cd /usr/ports/lang/php55-extensions


sudo make reinstall clean

Don’t forget the pecl and related packages as well. After that, try to restart your Apache server and clean up the php extension configuration:

nano /usr/local/etc/php/extensions.ini

You will see a mess. Try to clean up the duplicated extensions and run the php -m and php -v again.

During the fix, I notice that everything works fine except for MySQL package. Interestingly, when I ran php -m, the mysql was available. However when I ran phpinfo(), it was missing. I found that this problem only happens with PHP 5.4, but not PHP 5.5. Therefore, I decided to remove the PHP 5.4 and loaded PHP 5.5 instead.

Simply repeat the installation and restart the server. If possible, try to reboot the machine.

So here is the summary:

  1. Remove PHP, Extensions and PECL packages (sudo make deinstall).
  2. Restart Apache (sudo /usr/local/etc/rc.d/apache stop; sudo /usr/local/etc/rc.d/apache start).
  3. Verify installed extensions with php -m; php -v; and phpinfo().
  4. Verify the result by loading the pages on the web.
  5. If your page is failed, try to find out which extension is missing by checking the error log, which is typically available in in /var/log/

Hope my solutions help!

–Derrick

Our sponsors:

XAMPP – PHP Fatal error: Class ‘ZipArchive’ not found

I just finished writing a program written in PHP today. When I moved to the another environment, I found that the script didn’t work. After some investigations, I found that the program stopped running because of the following error:

PHP Fatal error:  Class 'ZipArchive' not found in ...

The error is obvious, some PHP extensions were missing. Therefore, I ran the following to see which modules were being loaded by the php:

#Make sure that the php is living in /opt/lampp/
#which php
/opt/lampp/bin/php

#php -m
[PHP Modules]
...
...
xsl
zlib

Okay, the problem is clear, zip is missing.

For some (stupid) reasons, XAMPP (1.8.1) removes the zip support from the package. I don’t understand why because it was available in the older version (1.7.3). Removing a popular package will create troubles and backward compatibility issues. Anyway, the XAMPP is a non-professional product. It is not designed for production uses.

Before we go further, please make sure that your PHP is 5.4.7. It is because this tutorial is version specific.

#php -v

PHP 5.4.7

Here are the details:

#As always, we want to switch to root user first
sudo su

#Switch to the extension directory
cd /opt/lampp/lib/php/extensions/no-debug-non-zts-20100525

#Download the missing zip.so
#This zip.so was extracted from a 32-bit Linux environment, and was complied using PHP 5.4.7 32-bit i686
#It will not work with a different PHP version.
wget http://icesquare.com/download/zip.so

#Modify the permissions
chmod a+x zip.so
chown root:root zip.so

Now, we will need to modify the php.ini

#nano /opt/lampp/etc/php.ini

#Look for the zip.so and remove the comment

#From
;extension="zip.so"

#To
extension="zip.so"

Next, we will need to verify that the extension is being loaded by php:

#php -m
[PHP Modules]
...
...
xsl
zip < ------------ This one
zlib

If everything looks good, we will need to restart the apache.

#/opt/lampp/lampp reloadapache

That’s it! Now the error is gone. You can also verify it by including phpinfo() in your code. It should display the details about the zip package.

My last word: Stay away from XAMPP when possible. It is using 32-bit stone-age technology, full of security-related bugs (because they release one or two versions ever year), and is packaged in a very non-professional way (such as backward compatibility). Consider to move to native Apache + PHP + MySQL. Believe me, you will see at least 10% of the performance improvement.

–Derrick

Our sponsors:

install: /usr/ports/…/doc/: Inappropriate file type or format

While I tried to upgrade both of my FreeBSD server (9 & 10) today, I got the following error:

install: /usr/ports/…/doc/: Inappropriate file type or format

Actually, here is the complete error message:

===>  Staging for memcached-1.4.17_1
===>   memcached-1.4.17_1 depends on shared library: libevent-2.0.so - found
===>   Generating temporary packing list
/usr/bin/make  install-recursive
Making install in doc
/usr/bin/make  install-am
test -z "/usr/local/man/man1" || /bin/mkdir -p "/usr/ports/databases/memcached/work/stage/usr/local/man/man1"
 install  -o root -g wheel -m 444 memcached.1 '/usr/ports/databases/memcached/work/stage/usr/local/man/man1'
test -z "/usr/local/bin" || /bin/mkdir -p "/usr/ports/databases/memcached/work/stage/usr/local/bin"
  install  -s -o root -g wheel -m 555 memcached '/usr/ports/databases/memcached/work/stage/usr/local/bin'
test -z "/usr/local/include/memcached" || /bin/mkdir -p "/usr/ports/databases/memcached/work/stage/usr/local/include/memcached"
 install  -o root -g wheel -m 444 protocol_binary.h '/usr/ports/databases/memcached/work/stage/usr/local/include/memcached'
install  -o root -g wheel -m 555 /usr/ports/databases/memcached/work/memcached-1.4.17/scripts/memcached-tool /usr/ports/databases/memcached/work/stage/usr/local/bin
install  -o root -g wheel -m 444 /usr/ports/databases/memcached/work/memcached-1.4.17/doc/ /usr/ports/databases/memcached/work/stage/usr/local/man/man1
install: /usr/ports/databases/memcached/work/memcached-1.4.17/doc/: Inappropriate file type or format
*** [post-install] Error code 71

Stop in /usr/ports/databases/memcached.
*** [install] Error code 1

Stop in /usr/ports/databases/memcached.

Initially, I thought the problem was caused by the syntax error of the code, therefore, I tried to do the following:

#Shut down the server
sudo /usr/local/etc/rc.d/memcached stop

#Remove Memcached from the system
sudo make deinstall

#Clean up the package
sudo make clean

#Compile the package
sudo make

#Install the package
sudo make install

Unfortunately, it still gave the same error message. I noticed that the error message has something to do with the documentation, so I decide to remove the documentation option in the installation page, i.e.,

#Enter the package setup
sudo make config

#Remove the "doc" option.

Unfortunately, it still gave the same response. I then tried to investigate the cause of the error. So I tried to copy the error command and re-ran it:

install  -o root -g wheel -m 444 /usr/ports/databases/memcached/work/memcached-1.4.17/doc/ /usr/ports/databases/memcached/work/stage/usr/local/man/man1

Which return the exact the same error message:

install: /usr/ports/databases/memcached/work/memcached-1.4.17/doc/: No such file or directory

So I came up an idea. Since I don’t really need the documentation, why not I disable the document option?

cd /usr/ports/databases/memcached

sudo nano Makefile

Change the following from:

post-install:
        ${INSTALL_SCRIPT} ${WRKSRC}/scripts/memcached-tool ${STAGEDIR}${PREFIX}/bin
        ${INSTALL_MAN} ${WRKSRC}/doc/${MAN1} ${STAGEDIR}${MAN1PREFIX}/man/man1
        @${MKDIR} ${STAGEDIR}${DOCSDIR}

To:

post-install:
        ${INSTALL_SCRIPT} ${WRKSRC}/scripts/memcached-tool ${STAGEDIR}${PREFIX}/bin
#        ${INSTALL_MAN} ${WRKSRC}/doc/${MAN1} ${STAGEDIR}${MAN1PREFIX}/man/man1
        @${MKDIR} ${STAGEDIR}${DOCSDIR}

That’s right, I just want to comment out the installation of the man/documentation part. Now, let’s try to reinstall the package again.

#sudo make install

Guess what, it works! Have fun!

–Derrick

Our sponsors:

The easiest way to improve the performance of MySQL server on FreeBSD

There are many different ways to improve the MySQL performance. In general, it breaks down into two different categories: Server side and client side.

On the server side, we can optimize the database and table structure, such as indexing the columns etc. On the client side, we can optimize the queue to minimize the workload, or we can cache and share the result such that the traffic to the server will be minimized. However, these methods are doable if you have access to the source code, or you understand the logic of the software. If you are a system administrator, you may not want to touch the source code, because you never know what will happen after the modifications. Plus your modification may be overwritten in the next update.

I am going to show you a quick and easy way to solve this problem. First, I am assuming that you build the MySQL from source. In the other words, this article will not work if you install the MySQL through pkg_add, yum, apt-get etc.

My solution is very simple: Compiling the MySQL server with static option enabled

By default, we will compile the software from source, it is not built in static. According to MySQL documentation, building the binary using static will result a 13% improvement comparing to building the binary using dynamic. Here is an example how to build MySQL with static option enabled:

cd /usr/ports/databases/mysql56-server
make BUILD_OPTIMIZED=yes BUILD_STATIC=yes
make install clean

This method will work for the first time. It may be a problem in the long run. For example, I use portsnap to update the port tree, and I use portmaster to upgrade the application. By default, portmaster will use the default options to rebuild the port. In the other words, the MySQL will not be built using static.

To solve this problem, I will need to make the build static option as a default settings. First of all, try to include the following in /etc/make.conf

sudo nano /etc/make.conf

WITH_CHARSET=utf8
WITH_COLLATION=utf8_general_ci
BUILD_OPTIMIZED=yes
BUILD_STATIC=yes

We can update the port tree and ports again. This will make the system to use the new settings.

sudo portsnap fetch update
sudo portmaster -Day
#Don't forget to restart the MySQL server.
sudo /usr/local/etc/rc.d/mysql-server start

Now your MySQL server and other applications are built using static.

Please click here to learn more about building static versus building dynamics.

–Derrick

Our sponsors:

How to Stress Test ZFS System

If you have set up a ZFS system, you may want to stress test the system before putting it in a production environment. There are many different ways to stress test the system. The most common way is to fill the entire pool using dd. However, I think scrubbing the entire pool is the best.

In case you are not familiar with scrubbing, basically it is a ZFS tool to test the data integrity. The system will go through every single file and perform checksum calculation, parity check etc. During scrubbing the entire pool, the system will generate a lot of I/O traffic.

First, please make sure that your ZFS is filled with some data. Then we will scrub the system:

sudo zpool scrub mypool

Afterward, simply run the following command to check the status:

#sudo zpool status -v
  pool: storage
 state: ONLINE
  scan: scrub in progress since Sun Jan 26 19:51:03 2014
        36.6G scanned out of 14.4T at 128M/s, 32h38m to go
        0 repaired, 0.25% done

Depending on the size of your pool, it may take few hours to few days to finish the entire process.

So how does the scrubbing related to the stability? Let’s take a look to the following example. Recently I set up a ZFS system which was based on 6 hard drives. During the initial setup, everything was fine. It gives no error or anything when loading the data. However, after I scrubbed the system, something bad happened. During the process, the system disconnected two hard drives, which made the entire pool unreadable (That’s because RAID1 can afford up to one disk fails). I was feeling so lucky because it didn’t happen in a production environment. Here is the result:

sudo zpool status
  pool: storage
 state: UNAVAIL
status: One or more devices could not be opened.  There are insufficient
        replicas for the pool to continue functioning.
action: Attach the missing device and online it using 'zpool online'.
   see: http://illumos.org/msg/ZFS-8000-3C
  scan: none requested
config:

        NAME                      STATE     READ WRITE CKSUM
        storage                   UNAVAIL      0     0     0
          raidz1-0                UNAVAIL      0     0     0
            ada1                  ONLINE       0     0     0
            ada4                  ONLINE       0     0     0
            ada2                  ONLINE       0     0     0
            ada3                  ONLINE       0     0     0
            9977105323546742323   UNAVAIL      0     0     0  was /dev/ada1
            12612291712221009835  UNAVAIL      0     0     0  was /dev/ada0

After some investigations, I found that the error had nothing to do with the hard drives (such as bad sectors, bad cables etc). Turn out that it was related to bad memory. See? You never know what component in your ZFS is bad until you stress test it.

Happy stress-testing your ZFS system.

–Derrick

Our sponsors: