Posted on

Configuring Apache 2.4 Connections For WordPress Sites

Recently I upgraded my web server to PHP 5.6.14. Along the way the process managed to obliterate my Apache web server configuration files. Luckily it saves them during the upgrade process, but one thing I forgot to restore was the settings that help Apache manage memory. Friday night around midnight, because this stuff ALWAYS happens when you’re asleep… the server crashed. And since it was out of memory with a bazillion people trying to surf the site; every time I restarted the server I could not log in fast enough to get a connection and fix the problem.

Eventually I had to disconnect my AWS public IP address, connect to a private address with SSH, and build the proper Apache configuration file to ensure Apache didn’t go rogue and try to take over the Internet from my little AWS web server.

Here are my cheat-sheet notes about configuring Apache 2.4 so that it starts asking site visitors to “hold on a second” when memory starts getting low. That is much nicer than grabbing more memory than it should and just crashing EVERYTHING.

My Configuration File

I put this new configuration file in the /etc/httpd/conf.d directory and named it mpm_prefork.conf. That should help prevent it from going away on a future Apache upgrade. This configuration is for an m3.large server running with 7.4GB of RAM with a typical WordPress 4.4 install with WooCommerce and other plugins installed.

# prefork MPM for Apache 2.4
#
# use httpd -V to determine which MPM module is in use.
#
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# ServerLimit: maximum value for MaxRequestWorkers for the lifetime of the server
#
# MaxRequestWorkers: maximum number of server processes allowed to start
#
#
# TOTAL SYTEM RAM: free -m (first column) = 7400 MB
# USED SYSTEM RAM: free -m (second column) = 2300 MB
#
# AVG APACHE RAM LOAD: htop (filter httpd, average RES column = loaded in physical RAM) = 87MB
# TOTAL APACHE RAM LOAD: (htop sum RES column) 1900 MB
#
# BASE SYSTEM RAM LOAD: USED SYSTEM RAM - TOTAL APACHE RAM LOAD = 2300 - 1900 = 400MB
#
# AVAILABLE FOR APACHE: TOTAL SYSTEM RAM - BASE SYSTEM RAM LOAD = 7400 - 400 = 7000MB
#
# ServerLimit = sets the maximum configured value for MaxRequestWorkers for the lifetime of the Apache httpd process
# MaxRequestWorkers = number of simultaneous child processes to serve requests , must increase ServerLimit
#
# If both ServerLimit and MaxRequestWorkers are set to values higher than the system can handle,
# Apache httpd may not start or the system may become unstable.
#
# MaxConnectionsPerChild = how many requests are served before the child process dies and is restarted
# find your average requests served per day and divide by average servers run per day
# a good starting default for most servers is 1000 requests
#
# ServerLimit = AVAILABLE FOR APACHE / AVG APACHE RAM LOAD = 7000MB / 87MB = 80
#
#

ServerLimit 64
MaxRequestWorkers 64
MaxConnectionsPerChild 2400

The Directives

With Apache 2.4 you only need to adjust 3 directives. ServerLimit, MaxRequestWorkers (renamed from earlier versions) , and MaxConnectionsPerChild (also renamed).

ServerLimit / MaxRequestWorkers

ServerLimit sets the maximum configured value for MaxRequestWorkers for the lifetime of the Apache httpd process. MaxRequestWorkers is the number of simultaneous child processes to serve requests. This seems a bit redundant, but it is an effect of using the prefork MPM module which is a threadless design. That means it runs a bit faster but eats up a bit more memory. It is the default mode for Apache running on Amazon Linux. I prefer it as I like stability over performance and some older web technologies don’t play well with multi-threaded design. If I was going to go with a more stable multi-thread environment I’d switch to nginx. For this setup setting ServerLimit and MaxRequestWorkers to the same value is fine. This says “don’t ever run more than this many web servers at one time”.

In essence this is the total simultaneous web connections you can serve at one time. What does that mean? With the older HTTP and HTTPS protocol that means every element of your page that comes from your server is a connection. The page text, any images, scripts, and CSS files are all a separate request. Luckily most of this comes out of the server quickly so a page with 20 web objects on it will use up 20 of your 64 connections but will spit them out in less than 2 seconds leaving those connections ready for the next site visitor while the first guy (or gal) reads your content. With newer HTTP/2 (and SPDY) connections a single process (worker) may handle multiple content requests from the same user so you may well end up using 1 or 2 connections even with a page with multiple objects loading. While that is an over-simplification, the general premise shows why you should update your site to https and get on services that support HTTP/2.

Calculating A Value

# TOTAL SYTEM RAM: free -m (first column) = 7400 MB
# USED SYSTEM RAM: free -m (second column) = 2300 MB
# TOTAL APACHE RAM LOAD: (htop sum RES column) 1900 MB
# AVG APACHE RAM LOAD: htop (filter httpd, average RES column = loaded in physical RAM) = 87MB
# BASE SYSTEM RAM LOAD: USED SYSTEM RAM - TOTAL APACHE RAM LOAD = 2300 - 1900 = 400MB
# AVAILABLE FOR APACHE: TOTAL SYSTEM RAM - BASE SYSTEM RAM LOAD = 7400 - 400 = 7000MB
# ServerLimit = AVAILABLE FOR APACHE / AVG APACHE RAM LOAD = 7000MB / 87MB = 80

There you go, easy, right? Figuring our RAM resources can be complicated, but to simplify the process start with the built-in Linux free command and I suggest installing htop which provides a simpler interface to see what is running on your server. You will want to do this on your live server under normal load if possible.

Using free -m from the Linux command line will tell you the general high-level overview of your server’s memory status. You want to know how much is installed and how much is in use. In my case I have 7400MB of RAM and 2300MB was in use.

Next you want to figure out how much is in use by Apache and how much an average web connection is using per request. Use htop, filter to show only the httpd processes, and do math. My server was using 1900MB for the httpd processes. The average RAM per process was 87MB.

You can now figure out how much RAM is used by “non-web stuff” on your server. Of the 2300MB of used RAM, Apache was using up 1900MB. That means my server uses about 400MB for general system overhead and various background processes like my system-level backup service. That means on a “clean start” my server should show about 7000MB available for web work. I can verify that by stopping Apache and running free -m after the system “rests” for a few minutes to clear caches and other stuff.

Since I will have 7000MB available for web stuff I can determine that my current WordPress configuration, PHP setup, and other variables will come out to about 87MB being used for each web session. That means I can fit about 80 web processes into memory at one time before all hell breaks loose.

Since I don’t like to exhaust memory and I’m a big fan of the 80/20 rule, I set my maximum web processed to 64. 7000MB / 87MB = 80 * .8 = 64.

That is where you want to set your ServerLimit and MaxRequestWorkers.

MaxConnectionsPerChild

This determines how long those workers are going to “live” before they die off. Any worker will accept a request to send something out to your site visitor. When it is done it doesn’t go away. Instead is tells Apache “hey, I’m ready for more work”. However every-so-often one of the things that is requested breaks. A bad script in PHP may be leaking memory, for example. As a safety valve Apache provides the MaxConnectionsPerChild directive. This tells Apache that after this child has served this many objects to die. Apache will start a new process to replace it. This ensures and memory “cruft” that is built up is cleared out should something go wrong.

Set this number too low and you server spends valuable time killing and creating Apache processes. You don’t want that. Set it too high and you run the risk of “memory cruft” building up and eventually having Apache kill your server with out-of-memory issues. Most system admins try to set this to a value that has it reset once every 24 hours. This is hard to calculate unless you know your average objects requested every day, how many processes served those objects, and other factors like HTTP versus HTTP2 can come into play. Not too mention fluctuations like weekend versus weekday load. Most system admins target 1000 requests. For my server load I am guessing 2400 requests is a good value, especially since I’ve left some extra room for memory “cruft”.

Posted on

Setting Up AWS Elastic Beanstalk Tools On Linux

AWS Beanstalk WordPress 445x200

AWS provides an “officially unsupported” set of scripts for Windows, OSX, and Linux that will help with managing and deploying your AWS Elastic Beanstalk applications.   This can be useful as I could not find a simple way to SSH into my ELB-based EC2 instance using standard methodologies.  I’m sure I missed something but deploying and updating via git commands is going to be easier and my preferred production method; might as well go there  now.

Download and install AWS Elastic Beanstalk Command Line Tool.

Unzip the file.

You will now have a directory that contains three types of command sets.  In the appropriately-named eb subdirectory is a series of OS command-line scripts via “eb” commands.   In the api directory is a full-fledged ruby-based implementation of very long command names that require ruby, ruby-developer, and the JSON gem to function.    In AWSDevTools is and extension of git commands that add new AWS-specific scripts to the git command.

 

Activating “eb” Command Line

Edit your OS PATH variable to point to your unzipped download directory.    I changed my unzipped directory to be something shorter and put it in my Linux root directory.   To activate the eb command:

Add the path to the proper Linux Python directory (I am running 2.7.X).  My CentOS .bash_profile:

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin:$HOME/aws-elb-2.6.4/eb/linux/python2.7/

export PATH

export AWS_CREDENTIAL_FILE=$HOME/.ssh/aws.credentials

Save and reload .bash_profile into my current environment (next time you log out / in this will not be necessary… and yes, dot-space-dot is correct):

# . .bash_profile

Activating Extended Command Line

The “extended” command line are the ruby-based scripts that give you some very long command names that do a lot of different things.

First make sure ruby , ruby-develop, and the JSON gems are installed. For CentOS:

# yum install ruby ruby-develop

# gem install json

Go create an AWS credentials file.

I put mine in my .ssh directory.  It looks like this (use your key IDs):

AWSAccessKeyId=<your-access-key>
AWSSecretKey=<your-secret-key>

Read the article on Deploying WordPress 4.2.2 On Elastic Beanstalk, Part 1 and setup a unique IAM account for this.  Using your main AWS login credential is not recommended.  If they get compromised…   well… just don’t do that.

Then edit your PATH using the same methodology as noted above.  

This time adding the api directory to your path:

PATH=$PATH:$HOME/.local/bin:$HOME/bin:$HOME/aws-elb-2.6.4/eb/linux/python2.7/:$HOME/aws-elb-2.6.4/api/bin/

export PATH

OK, now add this to your current running Linux environment:

# . .bash_profile

Test.

elastic-beanstalk-describe-applications

It will likely come back with “no applications found”.

Setup git Tools For AWS

Yup, same idea as above.  Edit your path file to include the git tool kit, but a slight twist here.  Once you do that you will need to run the setup command noted below in each repository where you want AWS tools.

Edit your PATH and invoke it the double-dot-bash-trick noted above.

PATH=$PATH:$HOME/.local/bin:$HOME/bin:$HOME/aws-elb-2.6.4/eb/linux/python2.7/:$HOME/aws-elb-2.6.4/api/bin/:$HOME/aws-elb-2.6.4/AWSDevTools/Linux

export PATH

New tricks… go set this up in your project directory.

Your project directory is where your WordPress PHP application resides and you’ve create a git repository to manage it.   You’ve already done your git init and committed stuff to the repository.    Dig around this site or the Internet to find out how to do that if you’re not sure. Again, I recommend the  Deploying WordPress 4.2.2 On Elastic Beanstalk, Part 1 article as it has some special Elastic Beanstalk config files in it that will be used by ELB to connect RDS dynamically and set your WP Salt values.

For this to work you are going to need to have Python (same with “eb” above) and the Python Boto library installed.   I

If you don’t have boto yet, you install it on CentOS with:

# sudo yum install python-boto

Assuming you already have your WordPress stuff in a git repo, go to that directory.

In my case /var/www/html holds my WordPress install that has been put into a git repo.

# cd /var/www/wpslp/

Now setup the git extensions using this command:

# AWSDevTools-RepositorySetup.sh

Test.

If everything is setup correctly you can check the git commands with something like:

# git aws.push

It will likely come back with an “Updating the AWS Elastic Beanstalk environment None…” message.

Either that or it will update the entire Internet , or at least the Amazon store, with your WordPress code.

 

Combined with your ELB Environment you setup from the previous article on the subject, your are ready to go conquer the world with your new git-deployed WordPress installation on ELB.

You can learn more about setting up the AWS-specific git parameters and how to use git with AWS and this tookit on at this .git Develop, Test, and Deploy article.

Next I will figure out how to marry the two and will share my crib notes here.

 

Posted on

AWS gMail Relay Setup

SMTP Relay Banner

After moving to a new AWS server I discovered that my mail configuration files were not configured as part of my backup service on my old server. In addition my new server is using sendmail instead of postfix for mail services. That mean re-learning and re-discovering how to setup mail relay through gmail.

Why Relay?

Cloud servers tend to be blacklisted. Sure enough, my IP address on the new server is on the Spamhaus PBL list. While Amazon allows for elastic IP addresses, a quasi-permanent IP address that acts like a static IP, which can be added to the whitelist on the Spamhaus PBL it is not the best option. Servers change, especially in the cloud. I find the best option is to route email through a trusted email service. I use Google Business Apps email accounts and have one setup just for this purpose. Now to configure sendmail to re-route all outbound mail from my server to my gmail account.

Configuring Amazon Linux

Here are my cheat-sheet notes about getting an Amazon Linux (RHEL flavor of Linux) box to use the default sendmail to push content through gmail.

Install packages needed.

# sudo su -
# yum install cyrus-sasl ca-certificates sendmail make

Create your certificates

This is needed for the TLS authentication.

</p>
# cd /etc/pki/tls/certs
# make sendmail.pem
# cd /etc/mail
# mkdir certs
# chmod 700 certs
# cd certs
# cp /etc/pki/tls/certs/ca-bundle.crt /etc/mail/certs/ca-bundle.crt
# cp /etc/pki/tls/certs/sendmail.pem /etc/mail/certs/sendmail.pm

Setup your authinfo file

The AuthInfo entries start with the relay server host name and port.

U = the AWS server user that will be the source of the email.

I = your gmail user name, if using business apps it is likely @yourdomain.com not @gmail.com

P = your gmail email password

M = the method of authentication, PLAIN will suffice

# cd /etc/mail
# vim gmail-auth

AuthInfo:smtp-relay.gmail.com "U:ec2-user" "I:your-gmail-addy@gmail.com" "P:yourpassword" "M:PLAIN"
AuthInfo:smtp-relay.gmail.com "U:apache" "I:your-gmail-addy@gmail.com" "P:yourpassword" "M:PLAIN"
AuthInfo:smtp-relay.gmail.com:587 "U:ec2-user" "I:your-gmail-addy@gmail.com" "P:yourpassword" "M:PLAIN"
AuthInfo:smtp-relay.gmail.com:587 "U:apache" "I:your-gmail-addy@gmail.com" "P:yourpassword" "M:PLAIN"

# chmod 600 gmail-auth
# makemap -r hash gmail-auth < gmail-auth

Configure Sendmail

Edit the sendmail.mc file and run make to turn it into a sendmail.cf configuration file.  Look for each of the entries noted in the sendmail.mc comments.  Uncomment the entries and/or change them as noted.    A couple of new lines will need to be added to the sendmail.mc file.   I add the new lines just before the MAILER(smpt)dnl line at the end of the file.

Most of these exist throughout the file and are commented out.   I uncommented the lines and modified them as needed so they appear near the comment blocks that explain what is going on:

# vim /etc/mail/sendmail.mc
define(`SMART_HOST', `smtp-relay.gmail.com')dnl
define(`confAUTH_OPTIONS', `A p')dnl
TRUST_AUTH_MECH(`EXTERNAL DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl
define(`confAUTH_MECHANISMS', `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl
define(`confCACERT_PATH', `/etc/mail/certs')dnl
define(`confCACERT', `/etc/mail/certs/ca-bundle.crt')dnl
define(`confSERVER_CERT', `/etc/mail/certs/sendmail.pem')dnl
define(`confSERVER_KEY', `/etc/mail/certs/sendmail.pem')dnl

Add these lines to the end of sendmail.mc just above the first MAILER()dnl entries:

</p>
<p style="padding-left: 30px;">define(`RELAY_MAILER_ARGS', `TCP $h 587')dnl</p>
<p style="padding-left: 30px;">define(`ESMTP_MAILER_ARGS', `TCP $h 587')dnl</p>
<p style="padding-left: 30px;">FEATURE(`authinfo',`hash -o /etc/mail/gmail-auth.db')dnl</p>
<p style="padding-left: 30px;">

If you are using business apps you may need these settings to make the email come from your domain and to pass authentication based on your Gmail relay settings.    These are also in sendmail.mc:

MASQUERADE_AS(`charlestonsw.com')dnl
FEATURE(masquerade_envelope)dnl
FEATURE(masquerade_entire_domain)dnl
MASQUERADE_DOMAIN(localhost)dnl
MASQUERADE_DOMAIN(localhost.localdomain)dnl
MASQUERADE_DOMAIN(charlestonsw.com)dnl

Make the configuration-helper into a sendmail.mc file and restart sendmail:

# make
# service sendmail restart

Configure Gmail Services

This is for business apps users, you need to turn on relay.

Go to “manage this domain” for your business apps account.

Go to “Google Apps”.

Click on “Gmail”.

Click “advanced settings”.

Find the “SMTP relay service” entry.    Add a  new entry.

Only addresses in my domain, require SMTP, require TLS all need to be selected.

Give it a name.

Save.

Save again.

Posted on

Configuring Apache Connections

Apache Banner

In preparation for WordCamp Charleston I updated my server to add more RAM.  The upgrade was the perfect opportunity to check my Apache connections configuration.  Here is the background on my calculations and how I configure my Apache 2.2 server on CentOS for both a 7GB and a 14GB dedicated server.

Apache 2.2 Configuration Directives

from: http://httpd.apache.org/docs/2.2/mod/prefork.html

The StartServers, MinSpareServers, MaxSpareServers, and MaxClients regulate how the parent process creates children to serve requests. In general, Apache is very self-regulating, so most sites do not need to adjust these directives from their default values. Sites which need to serve more than 256 simultaneous requests may need to increase MaxClients, while sites with limited memory may need to decrease MaxClients to keep the server from thrashing (swapping memory to disk and back). More information about tuning process creation is provided in the performance hints documentation.

While the parent process is usually started as root under Unix in order to bind to port 80, the child processes are launched by Apache as a less-privileged user. The User and Groupdirectives are used to set the privileges of the Apache child processes. The child processes must be able to read all the content that will be served, but should have as few privileges beyond that as possible.

MaxRequestsPerChild controls how frequently the server recycles processes by killing old ones and launching new ones.

Apache 2.2. Prefork Settings Summary

StartServers – how many connectors to start with (waiting for a HTTP request)

MinSpareServers – how many IDLE connectors to keep online ALWAYS

MaxSpareServers – how many IDLE connectors to keep online at one time

MaxClients – how many active connectors to spin up, total

ServerLimit – absolute maximum for MaxClients with runtime config tools

MaxRequestsPerChild – how many times to allow a connector to serve requests before dying to free resources

Determining Your Server RAM

 

  • TOTAL RAM
    Total RAM available to the OS.

 

    1. free -m
    2. TOTAL_RAM = “total” (first column) : 14,254 MB

 

  • USED RAM
    Total RAM in use for all applications.

 

      1. free -mf
      2. all running processes (second column): 1,717 MB
    1. APACHE RAM TOTAL / AVG
      The RAM used by Apache.
      Since Apache uses more RAM “under load” it is good to get this average both after startup and during/shortly-after an hour with peak user connections.

      1. ps aux | grep ‘httpd’ | awk ‘{print $6}’  // gets RSS Memory

 

  • APACHE TOTAL RAM

 

      1. sum 3a : 1,715MB

 

  • APACHE AVG RAM

 

      1. average 3a: 8GMB

Calculating MaxClients

The maximum number of simultaneous requests that can be served.

Max Clients = floor((TOTAL_RAM –  USED_RAM + APACHE TOTAL RAM) / AVG_RAM_LOAD) – 1

Let’s break that down:

  • floor( … blah … ) – 1
    the Be Conservative SectionThis rounds DOWN always and takes away 1 connection for a safety buffer.    This is a semi-conservative approach to avoid maxing out the memory resources and causing connection issues.
  • (TOTAL_RAM – USED_RAM + APACHE_TOTAL_RAM)
    the RAM For Apache SectionThe first part inside the floor function call determines how much RAM is available to Apache.  It takes the total RAM available to the system, takes away the amount of total RAM in use and adds back any RAM already in use by Apache.
  • (… blah …) / AVG_RAM_LOAD
    The Precise Possible Connections SectionThis calculates the exact number of possible connections that can be fit into the RAM available for Apache based on your average per-connection RAM load.

You may need to adjust the USED_RAM to accommodate more memory use of things like MySQL when the system is under load.  I find it best to run these calculations on a system that is running under load, adjust the Apache configuration and re-run numbers during peak load after each adjustment.

Operating system updates, web application updates including WordPress core, and other factors will change this number over time.  Re-run this calculation and update your configuration on a regular basis.

My Apache Server Calculations
My Apache Server Calculations

My 7GB Server Calculation

TOTAL RAM: 6853MB

USED RAM: 894MB

APACHE TOTAL RAM: 572MB

APACHE AVG RAM: 72MB

Max Clients = floor( (6853 – 894 + 572) /  72) = floor(6531 / 72) – 1 = 89

<IfModule prefork.c>
StartServers       20
MinSpareServers    15
MaxSpareServers   30
ServerLimit      61
MaxClients       60
MaxRequestsPerChild  300
</IfModule>

My 14GB Server Configuration

TOTAL RAM: 13,920MB

USED RAM: 3,495MB

APACHE TOTAL RAM: 3,044MB

APACHE AVG RAM: 105MB

Max Clients = floor ( (13920 – 3495 + 3044) / 105 ) -1 = 127

<IfModule prefork.c>
StartServers       20
MinSpareServers    15
MaxSpareServers   30
ServerLimit      128
MaxClients       127
MaxRequestsPerChild  300
</IfModule>

 

Posted on

Forcing Display Resolution on VirtualBox and CentOS 6.5

VirtualBox Display Resolution

Last evening my Oracle VM VirtualBox development system stopped auto-detecting my guest display resolution when I re-connected my laptop to the docking station.   The maximum resolution I could get was 1600 x 1200 instead of the native display resolution of 1920 x 1200.   After literally hours of research this morning with many dead-ends I found the proper solution.  Here is my “cheat sheet” on how I got it working in my dev environment.

For CentOS 6.x systems the system-config-display command is obsolete.  The replacement, for today anyway, is xrandr.

VBoxManage is useless unless you are running the virtual box management service, which is not a typical default setup for VirtualBox on a Windows host.

Updating VirtualBox guest additions does not help if you already have a current version.  You WILL need VirtualBox guest additions for the display driver interface on the guest operating system to function properly.   If you don’t have that installed you can use the GUI interface and finding the “machine / install guest additions” option.   It should drop a CD image on your CentOS 6.5 desktop that you can run with autoprompt.  Run it as a priv’ed user such as root.

Once you have VirtualBox guest additions installed login to your system and get to the command prompt.    Switch to a priv’ed user.  I login as my standard account and execute the command:

# sudo su -

To setup xrandr and add a manual resolution to your list you need to get the configuration setting line.   Use the utility cvt to get the right command line.  Here is the command to find the xrandr mode for a 1920 x 1200 resolution:

# cvt 1920 1200

It returns the line:

Modeline "1920x1200_60.00" 193.25 1920 2056 2256 2592 1200 1203 1209 1245 -hsync +vsync

Those are the parameters for my particular monitor configuration.  It is a basic reference label, a configuration tag, and monitor timing, resolution, and sync timings.  This will be specific to your monitor so run the cvt command, don’t just copy the line here.

For xrandr you will need everything AFTER the Modeline portion.

Find out what monitors your system thinks it has.  I have 3 monitors so this is my output:

# xrandr
Screen 0: minimum 64 x 64, current 4800 x 1200, maximum 16384 x 16384
VBOX0 connected 1600x1200+0+0 0mm x 0mm
   1600x1200      60.0*+
   1440x1050      60.0  
   1280x960       60.0  
   1024x768       60.0  
   800x600        60.0  
   640x480        60.0  
VBOX1 connected 1600x1200+1600+0 0mm x 0mm
   1600x1200      60.0*+
   1440x1050      60.0  
   1280x960       60.0  
   1024x768       60.0  
   800x600        60.0  
   640x480        60.0  
VBOX2 connected 1600x1200+3200+0 0mm x 0mm
   1600x1200      60.0*+
   1440x1050      60.0  
   1280x960       60.0  
   1024x768       60.0  
   800x600        60.0  
   640x480        60.0  
  1920x1200_60.00 (0x10c)  193.2MHz
        h: width  1920 start 2056 end 2256 total 2592 skew    0 clock   74.6KHz
        v: height 1200 start 1203 end 1209 total 1245           clock   59.9Hz

Now to add the manual entry so I can later use the CentOS 6.5 GUI display manager to set the resolution:

# xrandr --addmode VBOX0 "1920x1200_60.00"
# xrandr --addmode VBOX1 "1920x1200_60.00"
# xrandr --addmode VBOX2 "1920x1200_60.00"

Now I can go to System / Preferences / Display on the system admin menu.

CentOS 6.5 Forced Display Resolution
CentOS 6.5 Forced Display Resolution
Posted on

Linux : Find All Files Older Than…

I recently needed to clean up a directory on my Linux box that included hundreds of files. I wanted to get rid of all the files that hadn’t been updated in over a year. At first I decided just to list the files by date:

ls -lt

This will list the files in long format by time (newest files list before old file). This shows me all the details with the oldest files scrolling to the bottom of the window so the last few files above my command prompt are the oldest.

There are hundreds of files more than a year old.

Employing Find

Find is one of the tools I keep in my Linux tool belt. I don’t need it often, but when I do it saves me quite a bit of time. Find is the Swiss Army Knife of Linux search tools. It is complete, thorough, and comes with just about every “doo-dad” (a technical term) for finding files. It does real-time system searches, so unlike locate it does not rely on a secondary database which may become outdated and not give complete results.

The downside of find is that there are so many options. It is easy to choose the wrong option or, more likely, to string together the options in a manner that the search takes forever and you get no results.

The upside, thanks to how the command shells work, is that you can use the output of find to drive other applications. Like ls or rm. The later two are how we’ll employ find.

Find Files Not Touched In A Year

First we can find all the files in our current directory that are ‘stale’ like this:

find ./ ctime +365

In English “find stuff in this directory (./) where the creation time (ctime) is at least 365 days ago”.

The sister option is mtime, which is “modification time”, and may be more appropriate depending on whether you are truly looking for “modified since” (touched at all) or “created since” (date it was first brought into existence).

Now we can combine this with ls to list the results. It may seem redundant, but I like to test the parameter passing of find to another shell command using something innocuous such as ls. So we test like this:

ls -l `find ./ ctime +365`

The back-ticks take the output of find, which is a simple relative-path based list of the files it located, and uses that as the second parameter to ls.

If all looks good we can now force a remove of those files. Be careful with rm -f. You can do irreparable harm with this. There are other options and if you are not comfortable with power tools that can take a limb off with one keystroke, then drop the -f or us one of the myriad of linux admin tools to help you out. I’ll roll the dice and hope all my limbs remain intact:

rm -f  `find ./ ctime +365`

Other Find Options

There are a lot of ways to find files by other attributes such as “delete all files larger than ? MB” or “delete all files older than <this file>”. This is a good resource that explains some of the options and how to perform different types of find operations:

http://www.linuxquestions.org/linux/answers/Applications_GUI_Multimedia/Find_command_0

Good luck & keep your limbs on!

Posted on

Apache Not Following Symlinks

Posted on

Bash Command Lookup (\!)

I’ve recently found something relatively interesting that you can do in a bash terminal. I recently sent out an email talking about how to implement git completion’s wonderful self to work on macs.

Part of that endeavor meant diving into the way that the terminal displays its information to you on your prompt. Some of the things I found out were using the escape codes like \h to stand for host, \W for working directory w/o the path, etc.

So I set out to find out what some more of those escape characters were, and I found: \!

I’ve learned from Paul that doing a !! will repeat the last command that you put in. This \! will actually list a sequential number (to the last) on your prompt. So now when I’ve added it to my PS1 as before from the git completion tutorial, my prompt now displays:

(527)iMac:~ chase$ _

And when I put in a command, lets say I emptily type grep<enter>

(527)iMac:~ chase$ grep<enter>
Usage: grep [OPTION]... PATTERN [FILE]...
(528)iMac:~ chase$ _

Lets pretend that was some crucially complex command (you know the kind… that escapes you how to do it again later when you really need it) instead of an empty grep, and lets say that through the course of working I’ve since entered dozens or hundreds of other commands into the prompt. I have a few options available:

  • hit the up arrow repeatedly until I find the command (which it doesn’t list with the number next to it)
  • use the <ctrl>+R command and type in parts of the command I remember
  • grep the history
  • lots of things

or, if I’ve remembered that 527 was the line for that crucial command, I can simply type:

(8901)iMac:~ chase$ !527<enter>

And it will repeat the command from that line. The only downside to this, is that eventually if you come to rely on it for remembering several different sets of complex commands… you’ll have to end up remembering several different sets of numbers that corresponds to those lines. Also, this function doesn’t give you any type of “Are you sure?” type of moment to let you know what you’re about to do… so one transposed number or dropped digit could potentially mean catastrophe if you’ve ever run some iffy commands (rm -Rf) .

About This Article…

I pilfered this from “The List”, thanks Chase…
– Lobby