Category: "Other"

CentOS 6 / Windows 8 Dual-Boot on Different Drives

Please don’t consider this an authoritative post. To reach this point there were many, many reboots, reinstalls, and recoveries.

I bought a small ASUS tower from Best Buy and a 120GB solid-state drive.

I tried to install CentOS 6.4 over Windows 8, but the UEFI boot sequence prevented me from succeeding. Taking this a sign that there was value in Windows 8, I began to look into dual-booting.

Since I will be using CentOS for development and Windows 8 for testing (IE10), I wanted to put CentOS on the solid-state drive, and not modify the Windows 8 drive, other than that which was required to allow dual-booting.

The first few attempts assumed Windows would boot and allow me to choose CentOS, defaulting to CentOS. No matter what I did, this didn’t work. Right or wrong, I think Windows was unable to dual-boot to a drive other than the one it was on.

In the process, I lost the Windows recovery partitions installed by the manufacturer. This meant I had to reinstall Windows from a licensed MSDN disk. It also meant I lost the UEFI elements. But, in the end Windows 8 was booting and running.

I had to disable the UEFI only boot limitation in the BIOS. This may not be necessary.

The next step was to install CentOS, which I did using a USB stick and a network install. The stick was created with UNetBootin, which is really nice.

When the installer got to the part where it asked which drives should be used, I chose both the Windows and solid-state drives, and placed the boot loader on the Windows drive. This is because the Windows drive is identified in the UEFI BIOS as a boot device, and the solid-state disk isn’t. The solid-state device may be considered bootable now that the installation is complete, but there’s no reason to change what is working.

Once CentOS installed everything was fine. The only adjustment I made was to edit the /boot/grub/grub.conf file to change ‘Other’ to ‘Windows 8.’

This is the grub.conf file:

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd1,0)
#          kernel /vmlinuz-version ro root=/dev/mapper/vg_asustowercentos-lv_root
#          initrd /initrd-[generic-]version.img
#boot=/dev/sdc
default=0
timeout=5
splashimage=(hd1,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.32-358.6.1.el6.i686)
	root (hd1,0)
	kernel /vmlinuz-2.6.32-358.6.1.el6.i686 ro root=/dev/mapper/vg_asustowercentos-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_LVM_LV=vg_asustowercentos/lv_root rd_NO_MD SYSFONT=latarcyrheb-sun16 rd_LVM_LV=vg_asustowercentos/lv_swap crashkernel=128M  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
	initrd /initramfs-2.6.32-358.6.1.el6.i686.img
title CentOS (2.6.32-358.6.1.el6.i686)
	  root (hd1,0)
	  kernel /vmlinuz-2.6.32-358.6.1.el6.i686 ro root=/dev/mapper/vg_asustowercentos-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_LVM_LV=vg_asustowercentos/lv_root rd_NO_MD SYSFONT=latarcyrheb-sun16 rd_LVM_LV=vg_asustowercentos/lv_swap crashkernel=128M  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
	  initrd /initramfs-2.6.32-358.6.1.el6.i686.img
title Windows 8
	rootnoverify (hd0,0)
	chainloader +1

/dev/hd0 is the Windows drive
/dev/hd1 is the solid-state drive

Lessons I learned:

If you use gparted (http://gparted.sourceforge.net/), you can’t install Windows 8 on the new partitions.

I could create the UEFI partitions, but not the recovery partitions. But it wouldn’t work. I’m sure I missed some vital step. Every time. :)

The EasyBCD tool (http://neosmart.net/EasyBCD/) is really nice, but I couldn’t get it to do what I wanted. I think if you are going to put both operating systems on the same drive, it would be the way to go.

It costs $130 for the GeekSquad at BestBuy to restore the disk to its manufacturer state. I didn’t bother.

You can’t buy a Windows 8 recovery disk from the manufacturer (ASUS) at the time of this writing.

CentOS installs very fast on a solid-state drive. Thank goodness.

Creating the UEFI partitions for Windows 8 would probably take me a week, and even then, I’m not sure it would work. It’s very interesting.

UEFI = Universal Extensible Firmware Interface

I should have made a recovery disk for Windows before I started.

Windows 8 is nice.

Window-X (holding the Windows key and clicking X) gets you the admin menu, which includes the command line and disk management utilties.

Windows 8 has auto-repair, but it didn’t work in my case.

It often takes less time to reinstall than to identify and correct a problem. That’s a fine strategy if you don’t need to know too much. In my case, the goal was dual-boot - not a thorough understanding of the boot load process across two operating systems.

Adjusting the screen resolution under CentOS 6

With sincere thanks to the link above, this is how you can adjust the screen resolution under CentOS 6.

Run this command (with the appropriate resolution):

cvt 1920 1080

You’ll get output similar to this:

# 1920x1080 59.96 Hz (CVT 2.07M9) hsync: 67.16 kHz; pclk: 173.00 MHz
Modeline “1920x1080_60.00″ 173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync

Copy the modeline and paste it after –newmode, like so:

xrandr --newmode "1920x1080_60.00" 173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync

Then assign the new mode to the device:

xrandr --addmode VGA-1 "1920x1080_60.00"

This was done on a clean stock CentOS 6.4 installation, no custom drivers.

To get the settings to persist across sessions, I created /etc/gdm/PostLogin/Default
like so:

#!/bin/sh
#
if [ -f "$HOME/.gdm/PostLogin/Default" ];
then
	exec -l "$SHELL" -c "$HOME/.gdm/PostLogin/Default"
fi;

Under the account, I add the Default file:

xrandr --newmode "1920x1080_60.00"  173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync
xrandr --addmode VGA-1 "1920x1080_60.00"
xrandr --output VGA-1 --mode "1920x1080_60.00"

Be sure to grant execute permissions on both /etc/gdm/PostLogin/Default and $HOME/.gdm/PostLogin/Default.

Adding nVidia drivers didn’t help, adding hplip didn’t help. There is a Tripp-Lite KVM switch. This was the answer.

And, it looks great.

b2evolution - comment forms stalling - version 4+

This is a b2evolution blog. There’s a second blog running from the same installation, and the comment form was stalling on page load, displaying ‘Loading …’ and the icon, but never finishing.

The first action I took was to upgrade the blog. Many times, issues like that are resolved on an upgrade.

Unfortunately, that didn’t solve the problem.

Next, I reviewed the configuration of both blogs through the admin interface, taking care to clear the cache after each change.

Unfortunately this didn’t solve the problem either, so I grepped through the code until I found where the $baseurl is set. It is in these lines in conf/_basic_config.php. Uncommenting these lines solves the problem.

conf/_basic_config.php

// Use the following if you want to use the current domain:
if( isset($_SERVER['HTTP_HOST']) )
{       // This only works if HOSt provided by webserver (i-e DOES NOT WORK IN PHP CLI MODE)
        $baseurl = ( (isset($_SERVER['HTTPS']) && ( $_SERVER['HTTPS'] != 'off' ) ) ?'https://':'http://')
                                                        .$_SERVER['HTTP_HOST'].'/';
}

Filtering Spam - Tips & Ideas

SSH in to the server and find the affected inbox.

Quick Look at the inbox

This command shows the From, X-Spam-Bar, and Subject, without the file name. If you want to see the file names, remove the -h. You may have to use a different header for the spam score.

grep -h “From: \|X-Spam-Bar: \|Subject: ” * | more

The output should show give you an overview of what has been delivered, where it came from, and the subject.

Spam Score

The spam score is an appealing tool because it adapts to the current spam environ, and includes many parameters such as the sending IP address, domain, email address, SPF and reverse DNS information.

This is a very simple script that gives an overview of the spam bar values. It can be used as a first pass t set the level for filtering.

echo ‘Items in Inbox’
ls -1 | wc -l
echo ‘No Spam Bar (probably not spam)’
grep -L “X-Spam-Bar:” * | wc -l
echo ‘X-Spam-Bar Counts’
echo ‘+’
grep -m1 “X-Spam-Bar: +$” * | wc -l
echo ‘++’
grep -m1 “X-Spam-Bar: ++$” * | wc -l
echo ‘+++’
grep -m1 “X-Spam-Bar: +++$” * | wc -l
echo ‘++++’
grep -m1 “X-Spam-Bar: ++++$” * | wc -l
echo ‘+++++’
grep -m1 “X-Spam-Bar: +++++$” * | wc -l
echo ‘++++++’
grep -m1 “X-Spam-Bar: ++++++$” * | wc -l

It’s good to check the spam bar for valid emails as well. Many times, ‘real’ email is given a spam score.

From addresses

Look for patterns in the from addresses. Common patterns include ‘info@somedomain.info’ - the info, either as the sending email user or TLD is frequently used.

grep -h -m1 “From: ” * | sort

Subject

The subjects should be checked for the patterns in a similar manner as the From header.

Body

Using the results of the From and Subject checks, review a few of the message bodies (read the emails). Look for common text that would not be used by people. For example, Dear email@domain.com. People wouldn’t use an email address in a salutation, neither would real newsletter senders or other respectable sources.

Set the Filters

Read the directions. All the systems work differently.

Test the filters with some valid emails and some spam to be sure they behave as intended.

I created three filters.

  • Discard - The discard filter checks for glaring spam signs, such as a server that sent many spams messages, a from address pattern, distinct text patterns that simply wouldn’t come from people or other valid sources. These are discarded without warning to the sender.
  • Fail with message - Fail with message warnings were issued for anything that looked like spam, but might still be a valid email. Since the only ones that will read the fail with message text are people, it’s worth sending a friendly message, with a proposed solution. A good proposed solution is to suggest they use the site’s contact form. This will usually bypass the spam filters. It’s probably not a good idea to put a URL in the message, since a creative spammer may use it.

Apache Mod_AutoIndex - IIS/ASP Implementation

This is a simple directory listing script for IIS, using ASP.

Features

  • Custom CSS for each folder, if available It reads a css directory and if there is a .css file with the requested directory name, it will include a <style> tag for it. For example, if the requested directory listing is forms, it will create a style tag for css/forms.css.
  • Single instance One copy of this code can reside at the top of a directory tree and allow navigation throughout sub folders.
  • Drag and drop content posting The administrator or person who is posting content can drag and drop the files using Windows Explorer, without modifying the script, or asking for help. New content will be displayed as copied.
  • Hidden aware Hidden directories and files aren’t listed, so content can be placed on the server, but not displayed. This includes files named with a leading underscore which are usually not content.
  • Sample CSS A sample CSS file is included

<!DOCTYPE HTML>
<html>
<head>
<%
Const ReadOnly=1
Const Hidden=2

Dim fs,fo,x
Set fs=Server.CreateObject("Scripting.FileSystemObject")

Dim strPage,strPageHTML,strPageEncode,i
strPage=Request.ServerVariables("QUERY_STRING")
If (strPage = Null) Then strPage = ""
If (InStr(strPage,".")) Then strPage = ""
strPage=Replace(strPage,"+"," ")
strPageHTML=Server.HTMLEncode(strPage)
strPageEscape=Server.URLEncode(strPage)
%>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<META http-equiv="Content-Style-Type" content="text/css">
<title>Page Title</title>
<base href="http://domain.com/top/" />
<link href="css/style.css" rel="stylesheet" type="text/css" />
<%
If (strPage <> "") Then
	Set fo=fs.GetFolder("D:\docs\top\css")
	For Each x In fo.Files
		i=InStr(LCase(x.Name),LCase(strPage))
		If (i <> 0) Then Response.Write("<link href=""css/" & x.Name & """ rel=""stylesheet"" type=""text/css"" />")
	Next
End If
%>
</head>
<body>
<div id="divHeader">
<a href="#" title="Go to Home Page"><h1 id="title">Page Title</h1></a>
<h2><% Response.write(strPageHTML) %></h2>
</div>
<div id="divMain">
<div id="divFolders">
<ul>
<li><a href="http://docs/">Intranet Home</a></li>
<li><a href="http://docs:8088/default.aspx">Search Intranet</a></li>
</ul>
<ul>
<%
Set fo=fs.GetFolder("D:\docs\top\")

For Each x In fo.SubFolders
  'Print the name of all files in the test folder
  If (((x.Attributes And Hidden) = 0) And _
	(Left(x.Name,1) <> "_")) Then
	Response.write("<li><a href='" & Request.ServerVariables("SCRIPT_NAME") & "?" & Server.URLEncode(x.Name) & "'>" & Server.HTMLEncode(x.Name) & "</a></li>")
  End If
Next
%>
</ul>
</div>
<div id="divContent">
<% If (strPage = "") Then %>
<p>Home or top page text.</p>
<% Else %>
<%
Set fo=fs.GetFolder("D:\docs\top\" & strPage)
If (fo.Files.Count > 0) Then
	Response.Write("<ul>")
	For Each x In fo.Files
		If (((x.Attributes And Hidden) = 0) And _
			(Left(x.Name,1) <> "_")) Then
			Response.write("<li><a href='" & strPageEscape & "/" & x.Name & "'>" & Server.HTMLEncode(x.Name) & "</a></li>")
		End If
	Next
	Response.Write("</ul>")
Else
	Response.Write("No files found")
End If
%>
<% End If %>
</div>
</div>
<div id="divFooter">
<span class="float-left bolder">&copy; 2008-<% Response.Write(Year(Now)) %>&nbsp;Company, Inc.</span>
<span class="float-right">This information is for private internal use only.</span>
</div>
</body>
</html>
<%
set fo=nothing
set fs=nothing
%>

Base CSS file

Name this file style.css and place it in the css directory. You may add additional CSS files for each page. The CSS filenames are case-insensitive.

*
{
font-family: "Trebuchet MS","sans-serif";
margin:0;
padding:0;
}
body
{
width:1000px;
}
#divHeader
{
height:105px;
width:950px;
padding:25px 25px 0;
background:#fff url(../images/logo.jpg) no-repeat top right;
}
h1 
{
color:#000;
}
#divMain
{
border-style:solid;
border-width:1px 0;
border-color:#000;
height:450px;
width:1000px;
}
#divFolders
{
width:200px;
float:left;
background-color:yellow;
height:450px;
overflow:auto;
}
ul
{
list-style-type:none;
padding:5px;
margin:10px;
}
#divContent
{
padding:10px;
width:780px;
float:left;
}
#divFooter
{
background-color:#fff;
padding:15px;
}
.break
{
float:none;
clear:both;
}
.float-left
{
float:left;
}
.float-right
{
float:right;
}
.center
{
margin:0 auto;
}
.bolder
{
font-weight:bolder;
}
p
{
padding:5px;
margin:5px;
}
a
{
color:#000;
text-decoration:none;
}
a:hover
{
text-decoration:underline;
}
a:visited
{
color:#000;
}

1 3 4