PXE Server on Centos for network deployments

Found this article for installing a PXE server on Centos for network deployments.

NOTE: I ran into one issue that had me stumped for al long time. The PXE install would hang and after a lot of troubleshooting I added more RAM to the virtual machine I was trying to do the network install on and whammo, it worked. I added 4GB of RAM but not sure what the minimum is.

Install the following packages for setting up PXE environment.

yum install httpd xinetd syslinux tftp-server -y

Configure PXE Server

Go to /usr/share/syslinux/ directory:

cd /usr/share/syslinux/

Copy the following TFTP configuration files to the /var/lib/tftpboot/ directory.

cp pxelinux.0 menu.c32 memdisk mboot.c32 chain.c32 /var/lib/tftpboot/


Edit file /etc/xinetd.d/tftp

vi /etc/xinetd.d/tftp


Enable TFTP server. To do this, change “disable=yes” to “no”.

 # default: off
 # description: The tftp server serves files using the trivial file transfer \
 #       protocol.  The tftp protocol is often used to boot diskless \
 #       workstations, download configuration files to network-aware printers, \
 #       and to start the installation process for some operating systems.
 service tftp
 socket_type             = dgram
 protocol                = udp
 wait                    = yes
 user                    = root
 server                  = /usr/sbin/in.tftpd
 server_args             = -s /var/lib/tftpboot
 disable                 = no
 per_source              = 11
 cps                     = 100 2
 flags                   = IPv4


Mount CentOS installation ISO file to any directory of your choice, for example /mnt. I already have CentOS 7 64 bit ISO image on my /root directory.

mount -o loop /root/<ISONAME>.iso /mnt/


Next, create a directory to store CentOS installation ISO image.

mkdir /var/lib/tftpboot/centos7_x64

Note: If you want to install CentOS 32 bit edition, make a relevant directory called centos7_i386 (Ex. /var/lib/tftpboot/centos7_i386).


Copy the ISO file contents to /var/lib/tftpboot/centos7_x64/.

cp -fr /mnt/* /var/lib/tftpboot/centos7_x64/


Copy the boot files to /var/lib/tftpboot/.

cp initrd.img /var/lib/tftpboot/
cp vmlinuz /var/lib/tftpboot/


Set the proper permissions to the above directory.

chmod -R 755 /var/lib/tftpboot/centos7_x64/


Create a apache configuration file for PXE server under /etc/httpd/conf.d/ directory:

vi /etc/httpd/conf.d/pxeboot.conf


Add the following lines:

Alias "/centos7" "/var/lib/tftpboot/centos7/"

<Directory /var/lib/tftpboot/centos7>
Options Indexes FollowSymLinks
Require all granted

Save and close the file.

Start the Apache service and TFTP

systemctl enable httpd.service
systemctl restart httpd.service
systemctl start xinetd
systemctl start tftp
systemctl enable xinetd
systemctl enable tftp


Then, create a configuration directory for PXE server:

mkdir /var/lib/tftpboot/pxelinux.cfg


Now, create PXE server configuration file under the pxelinux.cfg:

vi /var/lib/tftpboot/pxelinux.cfg/default


Add the following lines:

default menu.c32
prompt 0
timeout 300

menu title ########## PXE Boot Menu ##########

label 1
menu label ^1) Install CentOS 7
kernel centos7_x64/images/pxeboot/vmlinuz
append initrd=centos7_x64/images/pxeboot/initrd.img method= devfs=nomount

label 2
menu label ^2) Boot from local drive localboot


Save and close the file.

Disable Firewall and SELinux

To reduce complexity, I have disabled both firewall and SELinux in my PXE server.

To disable firewall, run the following commands:

systemctl disable firewalld
systemctl stop firewalld


To disable SELinux, edit file /etc/sysconfig/selinux:

vi /etc/sysconfig/selinux


Find the line: SELINUX=enforcing and change it to SELINUX=disabled

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
# SELINUXTYPE= can take one of these two values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.


Save and close the file. Reboot your PXE server to take effect the saved changes.


Linux Failed Attempt Account Lockout (Time Based)

Add the following appended to the

onerr=fail deny=5 unlock_time=1800

Relevant entries in bold in /etc/pam.d/system-auth:

auth        required      /lib/security/$ISA/
auth        required      /lib/security/$ISA/ onerr=fail deny=5 unlock_time=1800
auth        sufficient    /lib/security/$ISA/ likeauth nullok
auth        required      /lib/security/$ISA/

account     required      /lib/security/$ISA/
account     sufficient    /lib/security/$ISA/ uid < 100 quiet
account     required      /lib/security/$ISA/
account     required      /lib/security/$ISA/

How to re-scan the SCSI bus on Linux

How to re-scan the SCSI bus on Linux.

echo "- – -" > /sys/class/scsi_host/host0/scan


Enable SSH on ESXi

ESXi 3.5 does have SSH capablities but it is disabled and not supported by default. If you want to enable it, follow these steps:

  1. At the ESXi console press ALT-F1
  2. Type in "unsupported" and press Enter. You will not see the text as you type.
  3. You will see a Tech Support Mode warning and be prompted for the root password. Enter the root password and press enter
  4. Edit the inetd.conf file located at /etc/inetd.conf using VI
  5. Scroll down the file till you find the file that stares with #ssh, move the cursor over the # and press x
  6. Exit and Save by pressing ESC and typing :wq
  7. Type in "ps | grep inetd" and take note of the process ID
  8. Type in "kill -HUP <process ID from step 7>"
  9. You can now SSH in to the ESXi host

UPDATE: Confirmed to be working on ESXi 4.0 also


Linux hugepage script for oracle

Here is the script to calculate hugepages for oracle db

# Linux bash script to compute values for the
# recommended HugePages/HugeTLB configuration
# Note: This script does calculation for all shared memory
# segments available when the script is run, no matter if it
# is an Oracle RDBMS shared memory segment or not.

# Check for the kernel version
KERN=`uname -r | awk -F. ‘{ printf("%d.%dn",$1,$2); }’`

# Find out the HugePage size
HPG_SZ=`grep Hugepagesize /proc/meminfo | awk ‘{print $2}’`

# Start from 1 pages to be on the safe side and guarantee 1 free HugePage

# Cumulative number of pages required to handle the running shared memory segments
for SEG_BYTES in `ipcs -m | awk ‘{print $5}’ | grep "[0-9][0-9]*"`
   MIN_PG=`echo "$SEG_BYTES/($HPG_SZ*1024)" | bc -q`
   if [ $MIN_PG -gt 0 ]; then
      NUM_PG=`echo "$NUM_PG+$MIN_PG+1" | bc -q`

# Finish with results
case $KERN in
   ‘2.4’) HUGETLB_POOL=`echo "$NUM_PG*$HPG_SZ/1024" | bc -q`;
          echo "Recommended setting: vm.hugetlb_pool = $HUGETLB_POOL" ;;
   ‘2.6’) echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
    *) echo "Unrecognized kernel version $KERN. Exiting." ;;

# End


Grant Shell access (SSH) to Root on ESX 3.5 update 2

If you’d like to allow shell access to the root account on ESX 3.5 Update 2 you need to modify the sshd_config file.

  1. Login into the console using the root account
  2. Edit the sshd_config file

    vi /etc/ssh/sshd_config

  3. Find "PermitRootLogin no" and change to "PermitRootLogin yes"
  4. Restart the sshd server

    service sshd restart


Setting cpu affinity on linux

Here is a simple way to bind a proc to a cpu. The taskset command is part of the util-linux package.

Bind process 2225 to processor 0:

taskset -p -c 0 2225

Bind process 2225 to processor 1:

taskset -p -c 1 2225

Bind process 2225 to processor 0 and 1:

taskset -p -c 0,1 2225

You can also bind a process at execution:

taskset -c 0 sshd

Retrieving the pids current affinity:

[root@localhost ~]# taskset -p 2225
pid 2225’s current affinity mask: 3


ftp vs. ftps performance data

In a previous entry Enabling ftps on vsftpd I showed how to turn on ftps in vsftpd. I have since did a little sample to see how this would affect cpu by turning on secure transfers. The results are odd, but I ran it twice and it is correct…

The ftp get script I used was a simple curl script that did 5 transfers and slept for 2 seconds then did another 5 transfers … etc .. for 10 loops, so a total of 50 transfers. I did this because i didnt want to flood the machine. This way the machine can take a break between transfers.

Here is the script:


for i in $(seq 1 10)
        for i in $(seq 1 5)
                curl -# -u ftptest:ftptest ftp://ftphost/10M.file > file
                #curl -# -u ftptest:ftptest ftp://ftphost/10M.file > file
                #curl –ftp-ssl-reqd –insecure -# -u ftptest:ftptest ftp://ftphost/1M.file > file
                #curl –ftp-ssl-reqd –insecure -# -u ftptest:ftptest ftp://ftphost/10M.file > file
        sleep 2

And here are the results:

FTP 1M File – View image

FTPS 1M File – View image

FTP 10M File – View image

FTPS 10M File – View image


Example kickstart file with lvm

I was having some trouble creating a kickstart file with lvm partitions so I finally got it working, i dont know what i did, but I think it had something to do with sizing. I set the pv to grow over the entire disk and then sliced up the lv’s.

url –url=
bootloader –location=mbr
clearpart –all
firewall –disabled
firstboot –disable
selinux –disabled

key –skip
lang en_US.UTF-8
keyboard us
network –device eth0 –bootproto dhcp –onboot=on
rootpw –iscrypted $1$O9sasdfe$fdadsfdsadqW4CMdO0jk0
firewall –disabled
authconfig –enableshadow –enablemd5
timezone –utc America/Los_Angeles

part /boot –fstype ext3 –size=100
part pv.01 –size=1 –grow
volgroup rootvg01 pv.01
logvol / –fstype ext3 –name=lv01 –vgname=rootvg01 –size=1000
logvol /tmp –fstype ext3 –name=lv03 –vgname=rootvg01 –size=1000
logvol swap –fstype swap –name=lv00 –vgname=rootvg01 –size=1000
logvol /home –fstype ext3 –name=lv02 –vgname=rootvg01 –size=1000
logvol /usr –fstype ext3 –name=lv04 –vgname=rootvg01 –size=5000
logvol /var –fstype ext3 –name=lv05 –vgname=rootvg01 –size=1000




Creating a file based swap

First create a file "swapfile" with the input file of /dev/zero and the output file of "swapfile"
Byte Size is 1 gig and the loop count is 1, so it will create a file that is 1 GB.

Create the file:

dd if=/dev/zero of=swapfile bs=1G count=1

Then we permission it:

chmod 600 swapfile

Format it:

mkswap swapfile

And turn it on!:

swapon swapfile