<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>gyaresu.org &#187; stuff</title>
	<atom:link href="http://gyaresu.org/category/stuff/feed/" rel="self" type="application/rss+xml" />
	<link>http://gyaresu.org</link>
	<description>Unix; Linux; Hacking; Photography and some other stuff I can never remember.</description>
	<lastBuildDate>Wed, 02 Jun 2010 06:59:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>52mm f1.8 project</title>
		<link>http://gyaresu.org/2010/06/02/52mm-f1-8-project/</link>
		<comments>http://gyaresu.org/2010/06/02/52mm-f1-8-project/#comments</comments>
		<pubDate>Wed, 02 Jun 2010 06:49:37 +0000</pubDate>
		<dc:creator>gyaresu</dc:creator>
				<category><![CDATA[stuff]]></category>
		<category><![CDATA[35mm]]></category>
		<category><![CDATA[52mm]]></category>
		<category><![CDATA[nikon]]></category>
		<category><![CDATA[photography]]></category>
		<category><![CDATA[project]]></category>

		<guid isPermaLink="false">http://gyaresu.org/?p=261</guid>
		<description><![CDATA[So apart from becoming a diving instructor living in Airlie Beach and generally being warmer, nothing much has happened since my last post (Ha!). I&#8217;m waiting for delivery of  a nikon 35mm f1.8 lens (AU$299). Said lens will give me a 52mm equivalent on my Nikon D80. This will be one of the main projects [...]]]></description>
			<content:encoded><![CDATA[<p>So apart from becoming a diving instructor living in Airlie Beach and generally being warmer, nothing much has happened since my last post (Ha!).</p>
<p>I&#8217;m waiting for delivery of  a nikon 35mm f1.8 lens (AU$299).</p>
<p>Said lens will give me a 52mm equivalent on my Nikon D80.</p>
<p>This will be one of the main projects for the foreseeable future.</p>
<p>http://www.nikon.com.au/productitem.php?pid=1310-8934b9b612</p>
<p>http://www.dpreview.com/lensreviews/nikon_35_1p8g_n15/</p>
<p>http://www.kenrockwell.com/nikon/35mm-f18.htm</p>
]]></content:encoded>
			<wfw:commentRss>http://gyaresu.org/2010/06/02/52mm-f1-8-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DNS for fun and profit</title>
		<link>http://gyaresu.org/2009/10/04/dns-for-fun-and-profit/</link>
		<comments>http://gyaresu.org/2009/10/04/dns-for-fun-and-profit/#comments</comments>
		<pubDate>Sat, 03 Oct 2009 13:25:51 +0000</pubDate>
		<dc:creator>gyaresu</dc:creator>
				<category><![CDATA[stuff]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://gyaresu.org/?p=254</guid>
		<description><![CDATA[DNS (Domain Name System) is one of those truly wonderful chunks of knowledge that you can get away with outsourcing but in the end you really need to know wtf is going on. I have a soft spot for DNS. I know that I don&#8217;t know enough and yet I know more than most. It&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>DNS (Domain Name System) is one of those truly wonderful chunks of knowledge that you can get away with outsourcing but in the end you really need to know wtf is going on.</p>
<p>I have a soft spot for DNS. I know that I don&#8217;t know enough and yet I know more than most.</p>
<p>It&#8217;s a wonderful place to focus your knowledge. Especially with IPV6 coming along while gazzilions of admins around the world chant the chorus to &#8220;la la la la la la la la la la la la&#8221; with fingers firmly stuck in ears.</p>
<p>It&#8217;s the glue of the internet. There really no way around it.</p>
<p>You may drive one of a thousand cars on the internet highway. TCP/UDP implementations of  JSON/HTML/XML/SQL/BLAHBLAHBLAH but DNS tells everyone where to go.</p>
<p>Here&#8217;s to you DNS. WIth your spoofing and your new found vulns you still rock my world.</p>
<p>Tip of the Hat!</p>
]]></content:encoded>
			<wfw:commentRss>http://gyaresu.org/2009/10/04/dns-for-fun-and-profit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Postgres DB Dump: SQL_ASCII &gt; UTF-8</title>
		<link>http://gyaresu.org/2009/09/30/postgres-db-dump-sql_ascii-utf-8/</link>
		<comments>http://gyaresu.org/2009/09/30/postgres-db-dump-sql_ascii-utf-8/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 02:27:10 +0000</pubDate>
		<dc:creator>gyaresu</dc:creator>
				<category><![CDATA[stuff]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[note]]></category>
		<category><![CDATA[postgres]]></category>
		<category><![CDATA[reminder]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://gyaresu.org/?p=251</guid>
		<description><![CDATA[- pg_dump -f your_db.dmp your_db - iconv -f ISO8859-1 -t UTF-8 your_db.dmp &#62; utf.dmp - psql your_utf_db &#60; utf.dmp]]></description>
			<content:encoded><![CDATA[<p>- pg_dump -f your_db.dmp your_db<br />
- iconv -f ISO8859-1 -t UTF-8 your_db.dmp &gt; utf.dmp<br />
- psql your_utf_db &lt; utf.dmp</p>
]]></content:encoded>
			<wfw:commentRss>http://gyaresu.org/2009/09/30/postgres-db-dump-sql_ascii-utf-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iTunes/iPhone Audiobooks and Time Machine fixes.</title>
		<link>http://gyaresu.org/2009/09/07/itunesiphone-audiobooks-and-time-machine-fixes/</link>
		<comments>http://gyaresu.org/2009/09/07/itunesiphone-audiobooks-and-time-machine-fixes/#comments</comments>
		<pubDate>Mon, 07 Sep 2009 02:37:42 +0000</pubDate>
		<dc:creator>gyaresu</dc:creator>
				<category><![CDATA[stuff]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[itunes]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[timemachine]]></category>

		<guid isPermaLink="false">http://gyaresu.org/?p=243</guid>
		<description><![CDATA[Changing the media type to audiobook: iPod on my iPhone 3G was removing the audiobooks I was listening to at strange times. On sync or even just plugging in the power. So a little research found that with iTunes 8 you can select a Genre then &#8216;cmd + a&#8217; &#62;&#62; right click &#62;&#62; options and [...]]]></description>
			<content:encoded><![CDATA[<p>Changing the media type to audiobook:</p>
<p>iPod on my iPhone 3G was removing the audiobooks I was listening to at strange times. On sync or even just plugging in the power. So a little research found that with iTunes 8 you can select a Genre then &#8216;cmd + a&#8217; &gt;&gt; right click &gt;&gt; options and change &#8220;Media Kind&#8221; to &#8220;Audiobook&#8221;. Tick &#8220;Remember Position&#8221; and &#8220;Skip when shuffling&#8221; &gt;&gt; Ok.</p>
<p>Sorted.</p>
<p>Next problem was having upgraded my drive to a 500GB 7200RPM Seagate (465GB irl) the Time Machine was showing  insufficent space on the external 500GB drive as it needed to backup 469GB.</p>
<p>Problem is that there&#8217;s only 390GB on the laptop drive. Hmmm. The internets doesn&#8217;t seem to want to help on this one either.</p>
<p>Solution:</p>
<p>Under &#8220;Options&#8221;  on the Time Machine preferences panel you can click the wee &#8220;+&#8221; button and add folders or even entire drives that you don&#8217;t want TM to backup. What I discovered was that TM isn&#8217;t really sure how much stuff you have on your internal drive until it has a crack at it. Problem is it also adds a 20% buffer to its estimation. What needed to be done was add almost all of the large folders (Applications, Users) and let it have a go at backing up the few remaining ones first. This done you go back and remove all the other folders from &#8220;Do not back up:&#8221; and let it run again. Voilá!</p>
]]></content:encoded>
			<wfw:commentRss>http://gyaresu.org/2009/09/07/itunesiphone-audiobooks-and-time-machine-fixes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My resumé</title>
		<link>http://gyaresu.org/2009/08/06/my-resume/</link>
		<comments>http://gyaresu.org/2009/08/06/my-resume/#comments</comments>
		<pubDate>Thu, 06 Aug 2009 02:53:50 +0000</pubDate>
		<dc:creator>gyaresu</dc:creator>
				<category><![CDATA[stuff]]></category>

		<guid isPermaLink="false">http://gyaresu.org/?p=236</guid>
		<description><![CDATA[Well apart from a dismal rushed attempt to write a resumé in 2002 I&#8217;ve gotten along just fine without needing one. The time has come though where some of the interesting jobs I want to apply for are on the other side of the world and there&#8217;s no chance to look them in the eye [...]]]></description>
			<content:encoded><![CDATA[<p>Well apart from a dismal rushed attempt to write a resumé in 2002 I&#8217;ve gotten along just fine without needing one.</p>
<p>The time has come though where some of the interesting jobs I want to apply for are on the other side of the world and there&#8217;s no chance to look them in the eye and shake their hand.</p>
<p>So&#8230;</p>
<p>Research. I&#8217;ve done the <a href="http://delicious.com" target="_blank">http://delicious.com</a> search and found a great Rands piece <a href="http://www.randsinrepose.com/archives/2007/02/25/a_glimpse_and_a_hook.html" target="_blank">http://www.randsinrepose.com/archives/2007/02/25/a_glimpse_and_a_hook.html</a></p>
<p>There&#8217;s a pile of good examples here: <a href="http://jobmob.co.il/blog/beautiful-resume-ideas-that-work/" target="_blank">http://jobmob.co.il/blog/beautiful-resume-ideas-that-work/</a></p>
<p>So. Best get to it.</p>
<p>EDIT: The funny and talented Zed Shaw <a href="http://zedshaw.com/" target="_blank">http://zedshaw.com/</a> offered his resumé template and build system in TeX.</p>
<p>It draws on using pygments and idiopidae to do the syntax  highlighting. You then use vellum to build it. Plus use tetex not latex.</p>
<p>How awesomely geeky is that for doing a resumé.</p>
<p>I really really appreciate  it when people go out of their way to help others.</p>
<p>I better go do some duty in the IRC rooms now :)</p>
]]></content:encoded>
			<wfw:commentRss>http://gyaresu.org/2009/08/06/my-resume/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>vim cheat sheet</title>
		<link>http://gyaresu.org/2009/07/21/vim-cheat-sheet/</link>
		<comments>http://gyaresu.org/2009/07/21/vim-cheat-sheet/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 02:50:19 +0000</pubDate>
		<dc:creator>gyaresu</dc:creator>
				<category><![CDATA[stuff]]></category>
		<category><![CDATA[cheatsheet]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://gyaresu.org/?p=227</guid>
		<description><![CDATA[Cursor movement h &#8211; move left j &#8211; move down k &#8211; move up l &#8211; move right ctrl+f page forward ctrl+b page backwards w &#8211; jump by start of words (punctuation considered words) W &#8211; jump by words (spaces separate words) e &#8211; jump to end of words (punctuation considered words) E &#8211; jump [...]]]></description>
			<content:encoded><![CDATA[<p>Cursor movement<br />
h &#8211; move left<br />
j &#8211; move down<br />
k &#8211; move up<br />
l &#8211; move right</p>
<p>ctrl+f page forward</p>
<p>ctrl+b page backwards<br />
w &#8211; jump by start of words (punctuation considered words)<br />
W &#8211; jump by words (spaces separate words)<br />
e &#8211; jump to end of words (punctuation considered words)<br />
E &#8211; jump to end of words (no punctuation)<br />
b &#8211; jump backward by words (punctuation considered words)<br />
B &#8211; jump backward by words (no punctuation)<br />
0 &#8211; (zero) start of line<br />
^ &#8211; first non-blank character of line<br />
$ &#8211; end of line<br />
G &#8211; Go To command (prefix with number &#8211; 5G goes to line 5)</p>
<p>Note: Prefix a cursor movement command with a number to repeat it. For example, 4j moves down 4 lines.<br />
Insert Mode &#8211; Inserting/Appending text<br />
i &#8211; start insert mode at cursor<br />
I &#8211; insert at the beginning of the line<br />
a &#8211; append after the cursor<br />
A &#8211; append at the end of the line<br />
o &#8211; open (append) blank line below current line (no need to press return)<br />
O &#8211; open blank line above current line<br />
ea &#8211; append at end of word<br />
Esc &#8211; exit insert mode<br />
Editing<br />
r &#8211; replace a single character (does not use insert mode)<br />
J &#8211; join line below to the current one<br />
cc &#8211; change (replace) an entire line<br />
cw &#8211; change (replace) to the end of word<br />
c$ &#8211; change (replace) to the end of line<br />
s &#8211; delete character at cursor and subsitute text<br />
S &#8211; delete line at cursor and substitute text (same as cc)<br />
xp &#8211; transpose two letters (delete and paste, technically)<br />
u &#8211; undo<br />
. &#8211; repeat last command<br />
Marking text (visual mode)<br />
v &#8211; start visual mode, mark lines, then do command (such as y-yank)<br />
V &#8211; start Linewise visual mode<br />
o &#8211; move to other end of marked area<br />
Ctrl+v &#8211; start visual block mode<br />
O &#8211; move to Other corner of block<br />
aw &#8211; mark a word<br />
ab &#8211; a () block (with braces)<br />
aB &#8211; a {} block (with brackets)<br />
ib &#8211; inner () block<br />
iB &#8211; inner {} block<br />
Esc &#8211; exit visual mode<br />
Visual commands<br />
&gt; &#8211; shift right<br />
&lt; &#8211; shift left<br />
y &#8211; yank (copy) marked text<br />
d &#8211; delete marked text<br />
~ &#8211; switch case<br />
Cut and Paste<br />
yy &#8211; yank (copy) a line<br />
2yy &#8211; yank 2 lines<br />
yw &#8211; yank word<br />
y$ &#8211; yank to end of line<br />
p &#8211; put (paste) the clipboard after cursor<br />
P &#8211; put (paste) before cursor<br />
dd &#8211; delete (cut) a line<br />
dw &#8211; delete (cut) the current word<br />
x &#8211; delete (cut) current character<br />
Exiting<br />
:w &#8211; write (save) the file, but don&#8217;t exit<br />
:wq &#8211; write (save) and quit<br />
:q &#8211; quit (fails if anything has changed)<br />
:q! &#8211; quit and throw away changes<br />
Search/Replace<br />
/pattern &#8211; search for pattern<br />
?pattern &#8211; search backward for pattern<br />
n &#8211; repeat search in same direction<br />
N &#8211; repeat search in opposite direction<br />
:%s/old/new/g &#8211; replace all old with new throughout file<br />
:%s/old/new/gc &#8211; replace all old with new throughout file with confirmations<br />
Working with multiple files<br />
:e filename &#8211; Edit a file in a new buffer<br />
:bnext (or :bn) &#8211; go to next buffer<br />
:bprev (of :bp) &#8211; go to previous buffer<br />
:bd &#8211; delete a buffer (close a file)<br />
:sp filename &#8211; Open a file in a new buffer and split window<br />
ctrl+ws &#8211; Split windows<br />
ctrl+ww &#8211; switch between windows<br />
ctrl+wq &#8211; Quit a window<br />
ctrl+wv &#8211; Split windows vertically</p>
]]></content:encoded>
			<wfw:commentRss>http://gyaresu.org/2009/07/21/vim-cheat-sheet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>System Administrator Cheat Sheet</title>
		<link>http://gyaresu.org/2009/07/16/system-administrator-cheat-sheet/</link>
		<comments>http://gyaresu.org/2009/07/16/system-administrator-cheat-sheet/#comments</comments>
		<pubDate>Thu, 16 Jul 2009 03:09:40 +0000</pubDate>
		<dc:creator>gyaresu</dc:creator>
				<category><![CDATA[stuff]]></category>

		<guid isPermaLink="false">http://gyaresu.org/?p=218</guid>
		<description><![CDATA[http://mj12net.org/index.php/system-administrator-interview-cheat-sheet.html Questions 1. What are the different ways to check the load average on a system? vmstat, top, uptime, w, procinfo ================================ ================================ Bonus &#8211; Describe the 3 values that top/uptime shows 1-minute, 5-minute and 15-minute load averages ================================ ================================ 2. What are the different running states of a SOLARIS system? 1,2, and 3 ================================ [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://mj12net.org/index.php/system-administrator-interview-cheat-sheet.html">http://mj12net.org/index.php/system-administrator-interview-cheat-sheet.html</a></p>
<p>Questions<br />
1. What are the different ways to check the load average on a system?<br />
vmstat, top, uptime, w, procinfo<br />
================================<br />
================================ </p>
<p>Bonus &#8211; Describe the 3 values that top/uptime shows<br />
1-minute, 5-minute and 15-minute load averages<br />
================================<br />
================================ </p>
<p>2. What are the different running states of a SOLARIS system?<br />
1,2, and 3<br />
================================<br />
================================ </p>
<p>3. How do you check CPU and MEMORY resources on a server?<br />
Memory: dmesg |grep mem, prtdiag |grep Memory, prtconf -v |grep Mem<br />
CPU: /usr/sbin/psrinfo -v<br />
================================<br />
================================ </p>
<p>4. How do you obtain system activity for a particular time frame (Say noon to 10PM)?<br />
a) Use the command &#8216;sar&#8217;<br />
b) sar consists of three commands that are involved in automatic system activity<br />
data collection: sadc, sa1, and sa2.<br />
c) To make sure sadc is run at boot time, the /etc/init.d/perf file must contain<br />
a command line that writes a record to the daily data file.<br />
d) The command entry has the following format: /usr/bin/su sys -c<br />
&#8220;/usr/lib/sa/sadc /var/adm/sa/sa`date +%d`&#8221;<br />
e) This entry is already in the /etc/init.d/perf file, but it needs to be<br />
uncommented.<br />
f) Put a line into the /var/spool/cron/crontabs/sys file, which calls the shell<br />
script, sa1. This script invokes sadc and writes to the daily data files,<br />
/var/adm/sa/sa
<dd>. The sa1 script gets installed with the other sar packages<br />
and has the following syntax: /usr/lib/sa/sa1 [t n]<br />
g) The syntax for the sar command is as follows: sar [-aAbcdgkmpqruvwy] [-o<br />
<outputfile>] [t n ]<br />
h) So in answer to the original question the command to obtain system activity<br />
from 12:00 PM to 10:00 PM is as follows: sar -s 12 -e 22 -i 3600 -A<br />
================================<br />
================================ </p>
<p>5. What does an init 5 do?<br />
shutdown the system, it will sync the file system first.<br />
================================<br />
================================ </p>
<p>6. How do you reset the root password on a server? No one has the password or<br />
has forgotten it. SUDO is not configured on the server as well.<br />
a) Insert Solaris CD in cd drive and from ok prompt run command: boot cdrom -s<br />
b) This will take you single user mode<br />
# fsck /dev/rdsk/c0t0d0s0.<br />
Answer y to clear all.<br />
c) mount /dev/dsk/c0t0d0s0 /a<br />
d) cd /a/etc<br />
e) TERM=sun<br />
f) export TERM<br />
g) vi /a/etc/shadow<br />
Remove password (between the first two colons i.e..,<br />
root:WYlPW5T2EyiU6:13750::::::) from password field of root and save file with<br />
wq!<br />
h) cd /<br />
i) umount /a<br />
j) init 6<br />
You will be prompted for password for root.<br />
================================<br />
================================ </p>
<p>7. How do you check disk usage. How do you trouble shoot a high disk usage issue<br />
(Available disk space is at 2% and could crash the application)<br />
First see which partiton is full<br />
du -hk<br />
To find out which files/folders are taking up the most space<br />
/du -dk / | sort -n<br />
To delete files older than x number of days in the current working directory and<br />
below, the safe way is<br />
With -mtime<br />
find . ! -mtime -<days>    | /usr/bin/xargs rm -rf<br />
With -exec and -newer<br />
create file with appropriate time stamp, this one would be for midnight last night<br />
03/20/2009 00:00<br />
touch -t 200903200000 /tmp/timeref<br />
to test first<br />
find . ! -newer /tmp/timeref -exec ls -l {} \; | more<br />
to delete<br />
find . ! -newer /tmp/timeref -exec rm {} \;<br />
================================<br />
================================ </p>
<p>8. How do you check the ports in use on a server?<br />
netstat -an<br />
================================<br />
================================ </p>
<p>9. What is NDD?<br />
Make the changes to the running system.<br />
# ndd -set /dev/hme adv_100hdx_cap 0<br />
# ndd -set /dev/hme adv_100fdx_cap 1<br />
# ndd -set /dev/hme adv_autoneg_cap 0<br />
# ndd -get /dev/hme link_mode<br />
Interpretation:<br />
0 &#8212; half-duplex<br />
1 &#8212; full-duplex<br />
# ndd -get /dev/hme link_speed<br />
Interpretation:<br />
0 &#8212; 10 Mbit<br />
1 &#8212; 100 Mbit<br />
1000 &#8212; 1 Gbit<br />
================================<br />
================================ </p>
<p>10. What is garbage collection in Java?<br />
When an object is no longer referenced by the program, the heap space it<br />
occupies must be recycled so that the space is available for subsequent new<br />
objects. The garbage collector must somehow determine which objects are no<br />
longer referenced by the program and make available the heap space occupied by<br />
such unreferenced objects. In the process of freeing unreferenced objects, the<br />
garbage collector must run any finalizers of objects being freed.<br />
================================<br />
================================ </p>
<p>======================================<br />
NETWORKING /////////////////////////<br />
====================================== </p>
<p>======================================<br />
Solaris Networking Commands:<br />
====================================== </p>
<p>Route Configuration<br />
===================<br />
route add net 128.50.0.0 128.50.1.6 1<br />
/* Add a route to the routing table */<br />
=======================================<br />
route change 128.50.0.0 128.50.1.5<br />
/* Changes the destination address for a route */<br />
=======================================<br />
route delete net 128.50.0.0 128.50.1.6<br />
/* Delete a route from the routing table */<br />
=======================================<br />
route flush<br />
/* Flush the routing table, which will remove all entries */<br />
=======================================<br />
route get [hostname]<br />
/* Which interface will be used to contact hostname */<br />
=======================================<br />
route monitor<br />
/* Monitor routing table lookup misses and changes */<br />
=======================================<br />
Network Information<br />
arp -a<br />
/* Ethernet address arp table */<br />
=======================================<br />
arp -d myhost<br />
/* Delete an ethernet address arp table entry */<br />
=======================================<br />
lsof -iTCP@10.20<br />
/* Display open files for internet address */<br />
=======================================<br />
named-xfer -z qantas.com.au -f /tmp/allip<br />
/* Get All IP Addresses On A DNS Server */<br />
=======================================<br />
ndd /dev/arp arp_cache_report<br />
/* Prints ARP table in cache with IP and MAC address */<br />
=======================================<br />
netstat -a | grep EST | wc -l<br />
/* Displays number active established connections to the localhost */<br />
=======================================<br />
netstat -a | more<br />
/* Show the state of all the sockets on a machine */<br />
=======================================<br />
netstat -i<br />
/* Show the state of the interfaces used for TCP/IP traffice */<br />
=======================================<br />
netstat -k hme0<br />
/* Undocumented netstat command */<br />
=======================================<br />
netstat -np<br />
/* Similar to arp -a without name resolution */<br />
=======================================<br />
netstat -r<br />
/* Show the state of the network routing table for TCP/IP traffic */<br />
=======================================<br />
netstat -rn<br />
/* Displays routing information but bypasses hostname lookup. */<br />
=======================================<br />
snoop -S -ta [machine]<br />
/* Snoop for network packets and get size and time stamp entries. */<br />
=======================================<br />
traceroute <ipaddress><br />
/* Follow the route to the ipaddress */<br />
=======================================</p>
<p>======================================<br />
Linux Networking Commands:<br />
====================================== </p>
<p>======================================<br />
Basic Linux Network Commands:<br />
======================================<br />
This category contains the most basic network commands available on Linux platform.<br />
======================================<br />
w<br />
Shows who is currently logged in and where they are logged in from.<br />
======================================<br />
who<br />
This also shows who is on the server in an shell.<br />
======================================<br />
netstat<br />
Shows all current network connections.<br />
======================================<br />
netstat -an<br />
Shows all connections to the server, the source and destination ips and ports.<br />
======================================<br />
netstat -rn<br />
Shows routing table for all ips bound to the server.<br />
======================================<br />
netstat -an |grep :80 |wc -l<br />
Show how many active connections there are to apache (httpd runs on port 80)<br />
======================================<br />
top<br />
Shows live system processes in a formatted table, memory information, uptime and<br />
other useful info.<br />
======================================<br />
While in top, Shift + M to sort by memory usage or Shift + P to sort by CPU usage.<br />
======================================<br />
top -u root<br />
Show processes running by user root only.<br />
======================================<br />
route -n<br />
Shows routing table for all ips bound to the server.<br />
======================================<br />
route add default gw my_computer<br />
Add a default gateway to my_computer.<br />
======================================<br />
nslookup yahoo.com<br />
Query your default domain name server (DNS) for an Internet name (or IP number)<br />
host_to_find.<br />
======================================<br />
traceroute yahoo.com<br />
Have a look how you messages travel to yahoo.com<br />
======================================<br />
tracepath yahoo.com<br />
Performs a very similar function to traceroute.<br />
======================================<br />
ifconfig<br />
Display info on the network interfaces.<br />
======================================<br />
ifconfig -a<br />
Display into on all network interfaces on server, active or inactive.<br />
======================================<br />
ifconfig eth0 down<br />
This will take eth0 (assuming the device exists) down, it won&#8217;t be able to receive or<br />
send anything until you put the device back &#8220;up&#8221; again.<br />
======================================<br />
ifconfig eth0 up<br />
You guessed it. This would take eth0 up and available to receive or send packets.<br />
======================================<br />
/sbin/ifconfig eth0 192.168.10.12 netmask 255.255.255.0 broadcast 192.168.10.255<br />
Assign IP 192.168.10.12, netmask and broadcast address to interface eth0.<br />
======================================<br />
ifup eth0<br />
Will bring eth0 up if it is currently down.<br />
======================================<br />
ifdown eth0<br />
Will bring eth0 down if it is currently up.<br />
======================================<br />
ifcfg<br />
Use ifcfg to configure a particular interface. Simply type ifcfg to get help on using<br />
this script.<br />
======================================<br />
ifcfg eth0 del 192.168.0.1<br />
This command takes eth0 down and removes the assigned IP 192.168.0.1<br />
======================================<br />
ifcfg eth0 add 192.168.0.2<br />
This command brings eth0 up and assigns the new IP 192.168.0.2<br />
======================================<br />
ping<br />
Sends test packets to a specified server to check if it is responding properly<br />
======================================<br />
ping yahoo.com<br />
Sends echo requests to yahoo.com<br />
======================================<br />
mii-tool<br />
Checks what your duplex settings are.<br />
======================================<br />
arp<br />
Command mostly used for checking existing Ethernet connectivity and IP address<br />
======================================<br />
hostname<br />
Tells the user the host name of the computer they are logged into.<br />
======================================<br />
findsmb<br />
Used to list info about machines that respond to SMB name queries. findsmb with no<br />
argument would find all machines possible. You can also specify a particular subnet<br />
to localize search.<br />
======================================<br />
host yahoo.com<br />
Performs a simple lookup of an internet address using DNS.<br />
======================================<br />
dig yahoo.com<br />
The &#8220;domain information groper&#8221; tool. This example looks up information about<br />
yahoo.com such as IP.<br />
======================================<br />
dig -x 66.94.234.13<br />
Looks up the address and returns the associated domain name. dig takes a huge number<br />
of options (at the point of being too many), refer to the manual page for more<br />
information.<br />
======================================<br />
whois<br />
Used to look up the contact information from the &#8220;whois&#8221; databases. Also reports IP<br />
address and name server of domain as well as creation and expiration dates.<br />
======================================<br />
ftp<br />
File transfer protocol. Transfers files to another host (insecure)<br />
======================================<br />
rdesktop<br />
Display remote desktop on Linux Machine. You can use to connect to Windows.<br />
====================================== </p>
<p>======================================<br />
ADVANCED NETWORK TIPS: ///////////////<br />
====================================== </p>
<p>All the remote network administration related tools and techniques available on Linux<br />
platform.<br />
======================================<br />
ssh<br />
Secure shell, an alternative but secure to telnet/rsh and all the non-secure methods<br />
of logging in to remote servers. All connections get encrypted.<br />
======================================<br />
ssh username@hostname<br />
Connect to a remote server by specifying your username and hostname you&#8217;re logging<br />
into.<br />
======================================<br />
scp <from_server> <to_server><br />
Secure copy. Allows you to copy files from one computer to another computer, use -r<br />
to copy recursively.<br />
======================================<br />
scp -r jose@remote1:/tmp greg@remote2:/tmp<br />
Do a recursive scp of /tmp on remote1 server logging in as jose to remote2 server<br />
/tmp logging in as greg.<br />
======================================<br />
scp remote:/home/me/junk/* .<br />
This will copy files on the remote machine in the directory &#8220;/home/me/junk/&#8221; to your<br />
local computer.<br />
======================================<br />
sftp<br />
Secure ftp, another part of the ssh package. This command is similar to ftp but uses<br />
an encrypted tunnel to connect to an ftp server and is therefore more secure than<br />
just plain ftp.<br />
======================================<br />
rsync<br />
An open source utility that provides fast incremental file transfer. Can be<br />
transferred via ssh.<br />
======================================<br />
rsync -av -e ssh remote@server:/home/dir /local/dir<br />
Rsync command used via ssh to login as default user on remote server to fetch<br />
/home/dir to local server and path /local/dir.<br />
======================================<br />
tcpdump<br />
Print all the network traffic going through the network. Do a &#8216;man tcpdump&#8217; to learn<br />
more.<br />
======================================<br />
tcpdump -v<br />
Display the verbose output.<br />
======================================<br />
tcpdump -D<br />
Display network interfaces available for the capture.<br />
======================================<br />
tcpdump -n<br />
Display numerical addresses rather than symbolic (DNS) addresses.<br />
======================================<br />
tcpdump -i eth0<br />
Capture the traffic of eth0 interface.<br />
======================================<br />
tcpdump udp<br />
Capture the UDP traffic.<br />
======================================<br />
tcpdump -w<br />
capture.log Send the capture output in a file instead of directly on the screen.<br />
======================================<br />
tcpdump -r capture.log<br />
Read a capture file.<br />
======================================<br />
tcpdump port http<br />
Capture the TCP port 80 traffic.<br />
======================================<br />
tcpdump -i eth0 host 66.94.234.13<br />
Listen to all traffic on interface eth0 going to 66.94.234.13. This troubleshooting<br />
technique can determine why a web connection is not reaching yahoo.com<br />
(66.94.234.13).<br />
======================================<br />
tcpdump host www.yahoo.com<br />
Display the packets having &#8220;www.openmaniak.com&#8221; as their source or destination<br />
address.<br />
======================================<br />
tcpdump src 192.168.1.2 and dst 192.168.1.3 and port ftp<br />
Display the FTP packets coming from 192.168.1.2 to 192.168.1.3.<br />
======================================<br />
nmap<br />
A very advanced network tool used to query machines (local or remote) as to whether<br />
they are up and what ports are open on these machines. Download it from<br />
insecure.org and for additional documentation.<br />
======================================<br />
nmap host_name<br />
This would query host_name and report what ports it keeps open.<br />
======================================<br />
nc<br />
Netcat is a networking utility which reads and writes data across network<br />
connections, using the TCP/IP protocol.<br />
======================================<br />
wget<br />
(GNU Web get) used to download files from the World Wide Web. To archive a single<br />
web-site.<br />
======================================<br />
-m or &#8211;mirror &#8211;><br />
To archive a single website.<br />
======================================<br />
-nc &#8211;><br />
no clobber option to stop wget from overwriting a file if you already have it.<br />
======================================<br />
-c or &#8211;continue &#8211;><br />
Continue a file that was unfinished by wget or another program.<br />
======================================<br />
Wget<br />
has a large list of options. Please check the manual pages for more details.<br />
======================================<br />
wget http://blog.lxpages.com/ultimate_linux.html<br />
This would simply get ultimate_linux.html from blog.lxpages.com website.<br />
======================================<br />
curl<br />
Another remote downloader similar to wget. This remote downloader is designed to work<br />
without user interaction and supports a variety of protocols, can upload/download<br />
and has a large number of tricks/work-arounds for various things. It can access<br />
dictionary servers (dict), ldap servers, ftp, http, gopher, see the manual page for<br />
full details.<br />
======================================<br />
curl -M<br />
To access the full manual. There are too many options and variations for examples.<br />
Please refer to manual for in depth examples and techniques.<br />
======================================<br />
curl -u<br />
username:password -T index.html ftp://ftp.mywebsite.com This uploads index.html to<br />
ftp.mywebsite.com.<br />
======================================</p>
<p>======================================<br />
APACHE SHELL COMMANDS: //////////////<br />
======================================<br />
Some of the basic and helpful apache commands.<br />
======================================<br />
httpd -v<br />
Outputs the build date and version of the Apache server.<br />
======================================<br />
httpd -l<br />
Lists compiled in Apache modules.<br />
======================================<br />
httpd status<br />
Only works if mod_status is enabled and shows a page of active connections.<br />
======================================<br />
service httpd restart<br />
Restarted Apache web server.<br />
======================================<br />
ab -n 100 -c 5 http://blog.lxpages.com/linux_network.html<br />
Apache benchmark. Great tool for load testing your site. -n 100 will send 100 # of<br />
requests to blog.lxpages.com in order to benchmark.<br />
======================================<br />
-c 5<br />
is # of concurrency.<br />
====================================== </p>
<p>======================================<br />
NETWORK CONFIGURATION FILES: ///////<br />
======================================<br />
All the network related configuration files on a Linux platform.<br />
======================================<br />
/etc<br />
This directory contains most of the basic Linux system-configuration Files.<br />
======================================<br />
/etc/sysconfig<br />
Contains important system configuration files that are created and maintained by<br />
various services (including iptables, samba, and most networking services).<br />
======================================<br />
/etc/sysconfig/network<br />
Network configuration file used by the system during the boot process.<br />
======================================<br />
/etc/sysconfig/network-scripts<br />
Configuration files that are run during boot process related to setting up of your<br />
network.<br />
======================================<br />
/etc/xinetd.d<br />
Contains a set of files, each of which defines a network service that the xinetd<br />
daemon listens for on a particular port.<br />
======================================<br />
/etc/syslogd.conf<br />
The configuration file for the syslogd daemon. syslogd is the daemon that takes care<br />
of logging (writing to disk) messages coming from other programs to the system.<br />
======================================<br />
/etc/resolv.conf<br />
Host name resolver configuration file. This configures Linux so that it knows which<br />
DNS server will be resolving domain names into IP addresses.<br />
======================================<br />
/etc/hosts<br />
Locally resolve node names to IP addresses. This informs Linux of local systems on<br />
the network which are not handled by the DNS server.<br />
======================================<br />
/etc/nsswitch.conf<br />
System Databases and Name Service Switch configuration file. Looks up /etc/hosts<br />
first, if host not found then it would query DNS server as defined by<br />
/etc/resolv.conf<br />
======================================<br />
/var<br />
Contains variable data like system logging files, mail and printer spool directories,<br />
and transient and temporary files.<br />
======================================<br />
/var/log<br />
Log files from the system and various programs/services, especially login<br />
(/var/log/wtmp, which logs all logins and logouts into the system) and syslog<br />
(/var/log/messages, where all kernel and system program message are usually<br />
stored).<br />
======================================<br />
/var/log/messages System logs. The first place you should look at if your system is<br />
in trouble.<br />
======================================<br />
/var/log/utmp<br />
Active user sessions. This is a data file and as such it can not be viewed normally.<br />
======================================<br />
/var/log/wtmp<br />
Log of all users who have logged into and out of the system. The last command can be<br />
used to access a human readable form of this file.<br />
====================================== </p>
<p>======================================<br />
UBUNTU DEBIAN NETWORK CONFIGURATION FILES:<br />
====================================== </p>
<p>======================================<br />
File: /etc/network/interfaces<br />
======================================<br />
Static IP example:<br />
auto lo<br />
iface lo inet loopback<br />
auto eth0<br />
iface eth0 inet static<br />
address 208.88.34.106<br />
netmask 255.255.255.248<br />
broadcast 208.88.34.111<br />
network 208.88.34.104<br />
gateway 208.88.34.110</p>
<p>======================================<br />
Dynamic IP (DHCP) example:<br />
======================================<br />
auto lo<br />
iface lo inet loopback<br />
auto eth0<br />
iface eth0 inet dhcp<br />
auto eth1<br />
iface eth1 inet dhcp<br />
auto eth2<br />
iface eth2 inet dhcp<br />
auto ath0<br />
iface ath0 inet dhcp<br />
auto wlan0<br />
iface wlan0 inet dhcp </p>
<p>======================================<br />
Interfaces:<br />
======================================<br />
* lo: Loopback interface (network within your system without slowing down for the<br />
real ethernet based network)<br />
* eth0: First ethernet interface card<br />
* wlan0: First wireless network interface<br />
Also see &#8220;man interfaces&#8221; </p>
<p>======================================<br />
REDHAT FEDORA CORE NETWORK CONFIGURATION FILES:<br />
======================================<br />
The Red Hat configuration tools store the configuration information in the file<br />
/etc/sysconfig/network.<br />
They will also allow one to configure routing information. </p>
<p>* File: /etc/sysconfig/network<br />
Static IP address Configuration: (Configure gateway address)<br />
NETWORKING=yes<br />
HOSTNAME=my-hostname &#8211; Hostname is defined here and by command hostname<br />
FORWARD_IPV4=true &#8211; True for NAT firewall gateways and linux routers.<br />
False for everyone else &#8211; desktops and servers.<br />
GATEWAY=&#8221;XXX.XXX.XXX.YYY&#8221; &#8211; Used if your network is connected to another network or<br />
the internet. </p>
<p>Static IP configuration. Gateway not defined here for DHCP client.<br />
OR for DHCP client configuration:<br />
NETWORKING=yes<br />
HOSTNAME=my-hostname &#8211; Hostname is defined here and by command hostname<br />
(Gateway is assigned by DHCP server.)<br />
OR for NIS client configuration:<br />
NETWORKING=yes<br />
HOSTNAME=my-hostname &#8211; Hostname is defined here and by command hostname<br />
NISDOMAIN=NISProject1 &#8211; NIS domain to attach </p>
<p>* File (Red Hat/Fedora): /etc/sysconfig/network-scripts/ifcfg-eth0<br />
(S.u.s.e.: /etc/sysconfig/network/ifcfg-eth-id-XX:XX:XX:XX:XX)<br />
This file used by the command scripts ifup and ifdown<br />
Static IP address configuration:</p>
<p>DEVICE=eth0<br />
BOOTPROTO=static<br />
BROADCAST=XXX.XXX.XXX.255<br />
IPADDR=XXX.XXX.XXX.XXX<br />
NETMASK=255.255.255.0<br />
NETWORK=XXX.XXX.XXX.0<br />
ONBOOT=yes &#8211; Will activate upon system boot </p>
<p>RHEL4/FC3 additions:<br />
o TYPE=Ethernet<br />
o HWADDR=XX:XX:XX:XX:XX:XX<br />
o GATEWAY=XXX.XXX.XXX.XXX<br />
OR for DHCP client configuration:<br />
DEVICE=eth0<br />
ONBOOT=yes<br />
BOOTPROTO=dhcp </p>
<p>RHEL4/FC3 additions:<br />
o IPV6INIT=no<br />
o USERCTL=no<br />
o PEERDNS=yes<br />
o TYPE=Ethernet<br />
o HWADDR=XX:XX:XX:XX:XX:XX </p>
<p>(Used by script /etc/sysconfig/network-scripts/ifup to bring the various network<br />
interfaces on-line)<br />
To disable DHCP change BOOTPROTO=dhcp to BOOTPROTO=none<br />
In order for updated information in any of these files to take effect, one must issue<br />
the command: service network restart (or: /etc/init.d/network restart) </p>
<p>Changing the host name:</p>
<p>This is a three step process:</p>
<p>1. Issue the command: hostname new-host-name<br />
2. Change network configuration file: /etc/sysconfig/network<br />
Edit entry: HOSTNAME=new-host-name<br />
3. Restart systems which relied on the hostname (or reboot):<br />
* Restart network services: service network restart<br />
(or: /etc/init.d/network restart)<br />
* Restart desktop:<br />
o Bring down system to console mode: init 3<br />
o Bring up X-Windows: init 5<br />
One may also want to check the file /etc/hosts for an entry using the system name<br />
which allows the system to be self aware.<br />
The hostname may be changed at runtime using the command: sysctl -w<br />
kernel.hostname=&#8221;superserver&#8221; </p>
<p>======================================<br />
NETWORK TUNING SOLARIS:<br />
======================================<br />
/sbin/ifconfig hme0:1 inet 10.210.xx.xxx netmask 255.255.0.0 broadcast<br />
10.210.xxx.xxx<br />
/* Virtual Interfaces */<br />
=======================================<br />
/sbin/ifconfig hme0:1 up<br />
/* Bring virtual interface up */<br />
=======================================<br />
/usr/sbin/ndd -set /dev/hme adv_100fdx_cap 1<br />
/* Nailling to 100Mbps */<br />
=======================================<br />
ifconfig eth0 10.1.1.1 netmask 255.255.255.255<br />
/* Add an Interface */<br />
=======================================<br />
ifconfig eth0 mtu 1500<br />
/* Change MTU of interface */<br />
=======================================<br />
ndd -set /dev/ip ip_addrs_per_if 1-8192<br />
/* To set more than 256 virtual ip addresses. */<br />
=======================================<br />
ndd -set /dev/tcp tcp_recv_hiwat 65535<br />
/* Increase TCP-receivebuffers on Sol2.5.1 systems with 100BaseTx */<br />
=======================================<br />
ndd -set /dev/tcp tcp_xmit_hiwat 65535<br />
/* Increase TCP-transmitbuffers on Sol2.5.1 systems with 100BaseTx */<br />
======================================= </p>
<p>======================================<br />
NETMASK:<br />
======================================<br />
Net bits Subnet mask total-addresses<br />
/20 255.255.240.0 4096<br />
/21 255.255.248.0 2048<br />
/22 255.255.252.0 1024<br />
/23 255.255.254.0 512<br />
/24 255.255.255.0 256<br />
/25 255.255.255.128 128<br />
/26 255.255.255.192 64<br />
/27 255.255.255.224 32<br />
/28 255.255.255.240 16<br />
/29 255.255.255.248 8<br />
/30 255.255.255.252 4<br />
Netmask Netmask (binary) CIDR Notes<br />
255.255.255.255 11111111.11111111.11111111.11111111 /32 Host (single addr)<br />
255.255.255.254 11111111.11111111.11111111.11111110 /31 Unuseable<br />
255.255.255.252 11111111.11111111.11111111.11111100 /30 2 useable<br />
255.255.255.248 11111111.11111111.11111111.11111000 /29 6 useable<br />
255.255.255.240 11111111.11111111.11111111.11110000 /28 14 useable<br />
255.255.255.224 11111111.11111111.11111111.11100000 /27 30 useable<br />
255.255.255.192 11111111.11111111.11111111.11000000 /26 62 useable<br />
255.255.255.128 11111111.11111111.11111111.10000000 /25 126 useable<br />
255.255.255.0 11111111.11111111.11111111.00000000 /24 &#8220;Class C&#8221; 254 useable<br />
255.255.254.0 11111111.11111111.11111110.00000000 /23 2 Class C&#8217;s<br />
255.255.252.0 11111111.11111111.11111100.00000000 /22 4 Class C&#8217;s<br />
255.255.248.0 11111111.11111111.11111000.00000000 /21 8 Class C&#8217;s<br />
255.255.240.0 11111111.11111111.11110000.00000000 /20 16 Class C&#8217;s<br />
255.255.224.0 11111111.11111111.11100000.00000000 /19 32 Class C&#8217;s<br />
255.255.192.0 11111111.11111111.11000000.00000000 /18 64 Class C&#8217;s<br />
255.255.128.0 11111111.11111111.10000000.00000000 /17 128 Class C&#8217;s<br />
255.255.0.0 11111111.11111111.00000000.00000000 /16 &#8220;Class B&#8221;<br />
255.254.0.0 11111111.11111110.00000000.00000000 /15 2 Class B&#8217;s<br />
255.252.0.0 11111111.11111100.00000000.00000000 /14 4 Class B&#8217;s<br />
255.248.0.0 11111111.11111000.00000000.00000000 /13 8 Class B&#8217;s<br />
255.240.0.0 11111111.11110000.00000000.00000000 /12 16 Class B&#8217;s<br />
255.224.0.0 11111111.11100000.00000000.00000000 /11 32 Class B&#8217;s<br />
255.192.0.0 11111111.11000000.00000000.00000000 /10 64 Class B&#8217;s<br />
255.128.0.0 11111111.10000000.00000000.00000000 /9 128 Class B&#8217;s<br />
255.0.0.0 11111111.00000000.00000000.00000000 /8 &#8220;Class A&#8221;<br />
254.0.0.0 11111110.00000000.00000000.00000000 /7<br />
252.0.0.0 11111100.00000000.00000000.00000000 /6<br />
248.0.0.0 11111000.00000000.00000000.00000000 /5<br />
240.0.0.0 11110000.00000000.00000000.00000000 /4<br />
224.0.0.0 11100000.00000000.00000000.00000000 /3<br />
192.0.0.0 11000000.00000000.00000000.00000000 /2<br />
128.0.0.0 10000000.00000000.00000000.00000000 /1<br />
0.0.0.0 00000000.00000000.00000000.00000000 /0 IP space </p>
<p>======================================<br />
OSI MODEL:<br />
======================================<br />
Upper Layers<br />
Layers 7 through 4 comprise the upper layers of the OSI protocol stack. They are more<br />
geared to the type of application than the lower layers, which are designed to move<br />
packets, no matter what they contain, from one place to another. </p>
<p>Application Layer 7<br />
This top layer defines the language and syntax that programs use to communicate with<br />
other programs. The application layer represents the purpose of communicating in<br />
the first place. For example, a program in a client workstation uses commands to<br />
request data from a program in the server. Common functions at this layer are<br />
opening, closing, reading and writing files, transferring files and e-mail<br />
messages, executing remote jobs and obtaining directory information about network<br />
resources. </p>
<p>Presentation Layer 6<br />
When data are transmitted between different types of computer systems, the<br />
presentation layer negotiates and manages the way data are represented and encoded.<br />
For example, it provides a common denominator between ASCII and EBCDIC machines as<br />
well as between different floating point and binary formats. Sun&#8217;s XDR and OSI&#8217;s<br />
ASN.1 are two protocols used for this purpose. This layer is also used for<br />
encryption and decryption. </p>
<p>Session Layer 5<br />
Provides coordination of the communications in an orderly manner. It determines<br />
one-way or two-way communications and manages the dialog between both parties; for<br />
example, making sure that the previous request has been fulfilled before the next<br />
one is sent. It also marks significant parts of the transmitted data with<br />
checkpoints to allow for fast recovery in the event of a connection failure.<br />
In practice, this layer is often not used or services within this layer are sometimes<br />
incorporated into the transport layer. </p>
<p>Transport Layer 4<br />
This layer is responsible for overall end-to-end validity and integrity of the<br />
transmission. The lower layers may drop packets, but the transport layer performs a<br />
sequence check on the data and ensures that if a 12MB file is sent, the full 12MB<br />
is received.<br />
&#8220;OSI transport services&#8221; include layers 1 through 4, collectively responsible for<br />
delivering a complete message or file from sending to receiving station without<br />
error. </p>
<p>Lower Layers<br />
Layers 3 through 1 are responsible for moving packets from the sending station to the<br />
receiving station. </p>
<p>Network Layer 3<br />
The network layer establishes the route between the sender and receiver across<br />
switching points, which are typically routers. The most ubiquitous example of this<br />
layer is the IP protocol in TCP/IP (see TCP/IP). IPX, SNA and AppleTalk are other<br />
examples of routable protocols, which means that they include a network address and<br />
a station address in their addressing system. This layer is also the switching<br />
function of the dial-up telephone system. If all stations are contained within a<br />
single network segment, then the routing capability in this layer is not required.<br />
See layer 3 switch. </p>
<p>Data Link Layer 2<br />
The data link is responsible for node to node validity and integrity of the<br />
transmission. The transmitted bits are divided into frames; for example, an<br />
Ethernet, Token Ring or FDDI frame in local area networks (LANs). Frame relay and<br />
ATM are also at Layer 2. Layers 1 and 2 are required for every type of<br />
communications. For more on this layer, see data link protocol. </p>
<p>Physical Layer 1<br />
The physical layer is responsible for passing bits onto and receiving them from the<br />
connecting medium. This layer has no understanding of the meaning of the bits, but<br />
deals with the electrical and mechanical characteristics of the signals and<br />
signaling methods. For example, it comprises the RTS and CTS signals in an RS-232<br />
environment, as well as TDM and FDM techniques for multiplexing data on a line.<br />
SONET also provides layer 1 capability. </p>
<p>======================================<br />
OSI Q&#038;A:<br />
======================================<br />
What is the difference between layer 2 and layer 3 in the OSI model? </p>
<p>Answer 1:<br />
The layer2, datalink layer is responsible for moving frames from one hop(node)to the<br />
next. Whereas in layer3 i.e.., the network layer is responsible for the delivery of<br />
individual packetsfrom source host to destination host </p>
<p>Answer 2:<br />
Basically a layer 2 switch operates utilizing Mac addresses in it&#8217;s caching table to<br />
quickly pass information from port to port. A layer 3 switch utilizes IP addresses<br />
to do the same.</p>
<p>While the previous explanation is the &#8220;What&#8221;, for folks in networking the following<br />
&#8220;How&#8221; is far more interesting. </p>
<p>Essentially, A layer 2 switch is a multiport bridge. A layer 2 switch will learn<br />
about MAC addresses connected to each port and pass frames marked for those ports.<br />
It also knows that if a frame is sent out a port but is looking for the MAC address<br />
of the port it is connected to it will drop that frame. Whereas a single CPU Bridge<br />
runs in serial, todays hardware based switches run in parallel, translating to<br />
extremly fast switching. </p>
<p>Layer 3 switching is a hybrid, as one can imagine, of a router and a switch. There<br />
are different types of layer 3 switching, route caching and topology-based. In<br />
route caching the switch requires both a Route Processor (RP) and a Switch Engine<br />
(SE). The RP must listen to the first packet to determine the destination. At that<br />
point the Switch Engine makes a shortcut entry in the caching table for the rest of<br />
the packets to follow. Due to advancement in processing power and drastic<br />
reductions in the cost of memory, today&#8217;s higher end layer 3 switches implement a<br />
topology-based switching which builds a lookup table and and poputlates it with the<br />
entire network&#8217;s topology. The database is held in hardware and is referenced there<br />
to maintain high throughput. It utilizes the longest address match as the layer 3<br />
destination. </p>
<p>Now when and why would one use a L2 vs L3 vs a router? Simply put, a router will<br />
generally sit at the gateway between a private and a public network. A router can<br />
perform NAT whereas an l3 switch cannot (imagine a switch that had the topology<br />
entries for the ENTIRE Internet!!). In a small very flat network (meaning only one<br />
private network range for the whole site) a L2 switch to connect all the servers<br />
and clients to the internet is probably going to suffice. Larger networks, or those<br />
with the need to contain broadcast traffic or those utilizing VOIP, a multi network<br />
approach utilizing VLANs is appropriate, and when one is utilizing VLANs, L3<br />
switches are a natural fit. While a router on a stick scenario can work, it can<br />
quickly overtax a router if there is any significant inter-vlan traffic since the<br />
router must make complicated routing decisions for every packet that it receives. </p>
<p>======================================<br />
What&#8217;s the difference between a hub, a switch, and a router?<br />
======================================<br />
A hub is typically the least expensive, least intelligent, and least complicated of<br />
the three. Its job is very simple: anything that comes in one port is sent out to<br />
the others. That&#8217;s it. Every computer connected to the hub &#8220;sees&#8221; everything that<br />
every other computer on the hub sees. The hub itself is blissfully ignorant of the<br />
data being transmitted. For years, simple hubs have been quick and easy ways to<br />
connect computers in small networks. </p>
<p>A switch does essentially what a hub does but more efficiently. By paying attention<br />
to the traffic that comes across it, it can &#8220;learn&#8221; where particular addresses are.<br />
For example, if it sees traffic from machine A coming in on port 2, it now knows<br />
that machine A is connected to that port and that traffic to machine A needs to<br />
only be sent to that port and not any of the others. The net result of using a<br />
switch over a hub is that most of the network traffic only goes where it needs to<br />
rather than to every port. On busy networks this can make the network significantly<br />
faster. </p>
<p>A router is the smartest and most complicated of the bunch. Routers come in all<br />
shapes and sizes from the small four-port broadband routers that are very popular<br />
right now to the large industrial strength devices that drive the internet itself.<br />
A simple way to think of a router is as a computer that can be programmed to<br />
understand, possibly manipulate, and route the data its being asked to handle. For<br />
example, broadband routers include the ability to &#8220;hide&#8221; computers behind a type of<br />
firewall which involves slightly modifying the packets of network traffic as they<br />
traverse the device. All routers include some kind of user interface for<br />
configuring how the router will treat traffic. The really large routers include the<br />
equivalent of a full-blown programming language to describe how they should operate<br />
as well as the ability to communicate with other routers to describe or determine<br />
the best way to get network traffic from point A to point B. </p>
<p>======================================<br />
SWITCHING /////////////////////////<br />
====================================== </p>
<p>======================================<br />
CREATE VLAN IOS:<br />
======================================<br />
This example shows how to create an Ethernet VLAN in global configuration mode and<br />
verify the configuration:<br />
Router# configure terminal<br />
Router(config)# vlan 3<br />
Router(config-vlan)# end<br />
Router# show vlan id 3<br />
VLAN Name Status Ports<br />
&#8212;- &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
3 VLAN0003 active<br />
VLAN Type SAID MTU Parent RingNo BridgeNo Stp BrdgMode Trans1 Trans2<br />
&#8212;- &#8212;&#8211; &#8212;&#8212;&#8212;- &#8212;&#8211; &#8212;&#8212; &#8212;&#8212; &#8212;&#8212;&#8211; &#8212;- &#8212;&#8212;&#8211; &#8212;&#8212; &#8212;&#8212;<br />
3 enet 100003 1500 &#8211; - &#8211; - &#8211; 0 0<br />
Primary Secondary Type Interfaces<br />
&#8212;&#8212;- &#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
This example shows how to create an Ethernet VLAN in VLAN database mode:<br />
Router# vlan database<br />
Router(vlan)# vlan 3<br />
VLAN 3 added:<br />
Name: VLAN0003<br />
Router(vlan)# exit<br />
APPLY completed.<br />
Exiting&#8230;.<br />
This example shows how to verify the configuration:<br />
Router# show vlan name VLAN0003<br />
VLAN Name Status Ports<br />
&#8212;- &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
3 VLAN0003 active<br />
VLAN Type SAID MTU Parent RingNo BridgeNo Stp Trans1 Trans2<br />
&#8212;- &#8212;&#8211; &#8212;&#8212;&#8212;- &#8212;&#8211; &#8212;&#8212; &#8212;&#8212; &#8212;&#8212;&#8211; &#8212;- &#8212;&#8212; &#8212;&#8212;<br />
3 enet 100003 1500 &#8211; - &#8211; - 0 0<br />
Router#<br />
This example shows how to map 802.1Q VLAN 1003 to ISL VLAN 200:<br />
Router# configure terminal<br />
Router(config)# vlan mapping dot1q 1003 isl 200<br />
Router(config)# end<br />
Router#<br />
This example shows how to verify the configuration:<br />
Router# show vlan<br />
<...output truncated...><br />
802.1Q Trunk Remapped VLANs:<br />
802.1Q VLAN ISL VLAN<br />
&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8211;<br />
1003 200 </p>
<p>======================================<br />
ROUTING /////////////////////////<br />
====================================== </p>
<p>======================================<br />
Cisco Router Configuration Commands:<br />
======================================<br />
Set a console password to cisco<br />
Router(config)#line con 0<br />
Router(config-line)#login<br />
Router(config-line)#password cisco<br />
======================================<br />
Set a telnet password<br />
Router(config)#line vty 0 4<br />
Router(config-line)#login<br />
Router(config-line)#password cisco<br />
======================================<br />
Stop console timing out<br />
Router(config)#line con 0<br />
Router(config-line)#exec-timeout 0 0<br />
======================================<br />
Set the enable password to cisco<br />
Router(config)#enable password cisco<br />
======================================<br />
Set the enable secret password to peter.<br />
This password overrides the enable password<br />
and is encypted within the config file<br />
Router(config)#enable secret peter<br />
======================================<br />
Enable an interface<br />
Router(config-if)#no shutdown<br />
======================================<br />
To disable an interface<br />
Router(config-if)#shutdown<br />
======================================<br />
Set the clock rate for a router with a DCE cable to 64K<br />
Router(config-if)clock rate 64000<br />
======================================<br />
Set a logical bandwidth assignment of 64K to the serial interface<br />
Router(config-if)bandwidth 64<br />
Note that the zeroes are not missing<br />
======================================<br />
To add an IP address to a interface<br />
Router(config-if)#ip addr 10.1.1.1 255.255.255.0<br />
======================================<br />
To enable RIP on all 172.16.x.y interfaces<br />
Router(config)#router rip<br />
Router(config-router)#network 172.16.0.0<br />
Disable RIP Router(config)#no router rip<br />
======================================<br />
To enable IRGP with a AS of 200, to all interfaces<br />
Router(config)#router igrp 200<br />
Router(config-router)#network 172.16.0.0<br />
Disable IGRP Router(config)#no router igrp 200<br />
======================================<br />
Static route the remote network is 172.16.1.0,<br />
with a mask of 255.255.255.0, the next<br />
hop is 172.16.2.1, at a cost of 5 hops<br />
Router(config)#ip route 172.16.1.0 255.255.255.0 172.16.2.1 5<br />
======================================<br />
Disable CDP for the whole router<br />
Router(config)#no cdp run<br />
======================================<br />
Enable CDP for he whole router<br />
Router(config)#cdp run<br />
======================================<br />
Disable CDP on an interface<br />
Router(config-if)#no cdp enable<br />
======================================</p>
<p>======================================<br />
Cisco Router Show Commands:<br />
======================================<br />
View version information<br />
show version<br />
======================================<br />
View current configuration (DRAM)<br />
show running-config<br />
======================================<br />
View startup configuration (NVRAM)<br />
show startup-config<br />
======================================<br />
Show IOS file and flash space<br />
show flash<br />
======================================<br />
Shows all logs that the router has in its memory<br />
show log<br />
======================================<br />
View the interface status of interface e0<br />
show interface e0<br />
======================================<br />
Overview all interfaces on the router<br />
show ip interfaces brief<br />
======================================<br />
View type of serial cable on s0<br />
show controllers 0 (note the space between the &#8216;s&#8217; and the &#8217;0&#8242;)<br />
======================================<br />
Display a summary of connected cdp devices<br />
show cdp neighbor<br />
======================================<br />
Display detailed information on all devices<br />
show cdp entry *<br />
======================================<br />
Display current routing protocols<br />
show ip protocols<br />
======================================<br />
Display IP routing table<br />
show ip route<br />
======================================<br />
Display access lists, this includes the number of displayed matches<br />
show access-lists<br />
======================================<br />
Check the router can see the ISDN switch<br />
show isdn status<br />
======================================<br />
Check a Frame Relay PVC connections<br />
show frame-relay pvc<br />
======================================<br />
show lmi traffic stats<br />
show frame-relay lmi<br />
======================================<br />
Display the frame inverse ARP table<br />
show frame-relay map<br />
======================================<br />
======================================<br />
Cisco Router Basic Operations<br />
======================================<br />
Enable<br />
Enter privileged mode<br />
======================================<br />
Return to user mode from privileged<br />
disable<br />
======================================<br />
Exit Router<br />
Logout or exit or quit<br />
======================================<br />
Recall last command<br />
up arrow or <Ctrl-P><br />
======================================<br />
Recall next command<br />
down arrow or <Ctrl-N><br />
======================================<br />
Suspend or abort<br />
<Shift> and <Ctrl> and 6 then x<br />
======================================<br />
Refresh screen output<br />
<Ctrl-R><br />
======================================<br />
Complete Command<br />
TAB<br />
====================================== </p>
<p>======================================<br />
Cisco Router Copy Commands:<br />
======================================<br />
Save the current configuration from DRAM to NVRAM<br />
copy running-config startup-config<br />
======================================<br />
Merge NVRAM configuration to DRAM<br />
copy startup-config running-config<br />
======================================<br />
Copy DRAM configuration to a TFTP server<br />
copy runing-config tftp<br />
======================================<br />
Merge TFTP configuration with current router configuration held in DRAM<br />
copy tftp runing-config<br />
======================================<br />
Backup the IOS onto a TFTP server<br />
copy flash tftp<br />
======================================<br />
Upgrade the router IOS from a TFTP server<br />
copy tftp flash<br />
====================================== </p>
<p>======================================<br />
Cisco Router Debug Commands:<br />
======================================<br />
Enable debug for RIP<br />
debug ip rip<br />
======================================<br />
Enable summary IGRP debug information<br />
debug ip igrp events<br />
======================================<br />
Enable detailed IGRP debug information<br />
debug ip igrp transactions<br />
======================================<br />
Debug IPX RIP<br />
debug ipx routing activity<br />
======================================<br />
Debug IPX SAP<br />
debug IPX SAP<br />
======================================<br />
Enable debug for CHAP or PAP<br />
debug ppp authentication<br />
======================================<br />
Switch all debugging off<br />
no debug all<br />
undebug all<br />
====================================== </p>
<p>======================================<br />
SCRIPTS ////////////////////////<br />
====================================== </p>
<p>======================================<br />
Bash Cleanup Script:<br />
======================================<br />
All the files below go in the same directory<br />
&#8220;README.1st&#8221;, &#8220;rotatelog&#8221;, rotatelog.rc&#8221;, and &#8220;rotatelog.lsm&#8221;</p>
<p># README.1st FILE<br />
#####################################<br />
# rotatelog   Ver 0.2<br />
####################################<br />
1        Introduction<br />
1.1      Rotation of log files is a mandatory task of  every sys-<br />
admin, failing which they grow beyond proportions.  Many<br />
distros cater for  utilities like  logrotate,  which are<br />
usually fired as a cron process. These  are  essentially<br />
shell scripts, and take care of these routine chores.<br />
1.2      I for one have always been  advocating  manual admining,<br />
since you know what is going on. I have been  doing rot-<br />
ation of log files manually  through  scripts  for  many<br />
years now without problems.<br />
1.3      Since location of log files are  distro  specific, there<br />
is a need to evolve a method which will work for all. </p>
<p>2        Installation<br />
2.1      Copy this script to a  suitable place.  The  recommended<br />
place is at /usr/sbin (so that  no  user can access it).<br />
It has an in-built check for  superuser  privileges, so,<br />
placing this in /usr/local/bin will do just as well.<br />
2.2      Documentation ? None, except for this file, which may be<br />
removed, once you are sailing. The script itself is also<br />
heavily commented. </p>
<p>3        rotatelog.rc<br />
3.1      This is merely a bash script. This  rotates  files in an<br />
interactive mode. At the  heart  of the process is an rc<br />
file which contains the list of all log files  which are<br />
known to grow with time.  The log files  may be anywhere<br />
on the system. A sample rc file is placed below:<br />
####################################<br />
# Sample rotatelog.rc file.All lines<br />
# with # are omitted.  All filenames<br />
# with full path, to begin on Col 1.<br />
# No line gaps permitted in between.<br />
####################################<br />
/var/log/messages<br />
/var/log/syslog<br />
/var/log/wtmp<br />
/var/log/debug<br />
/home/bish/mail/.procmail.log<br />
/var/log/boa/access_log<br />
/var/log/boa/error_log </p>
<p>3.2      By default, this file is kept at /var/log/oldlogs/ dir,<br />
though it can be kept anywhere as per the location that<br />
is specified on top of the script. With  this strategy,<br />
the reach of the program is virtually endless,  and any<br />
log file anywhere can be added to the list. </p>
<p>4        Running rotatelog<br />
4.1      This script must be run with  root privileges. This is<br />
a sys-adm function. The script runs  with command line<br />
options:<br />
&#8211;help or -h  &#8230; for help<br />
-i    &#8230; For information on the file sizes of the log<br />
files specified in the rc file.<br />
-e    &#8230; To execute a rotation selectively.  Sizes of<br />
all log files are displayed. It is then pos-<br />
sible to selectively  choose the file(s) for<br />
rotation.<br />
5.       Features of rotatelog<br />
5.1      None of the log files are removed. They are moved to a<br />
selected directory  ( default being /var/log/oldlogs )<br />
and then gzipped. The location of the  log  archive is<br />
also editable within the script.<br />
5.2      All new log files are re-initialised thereafter.<br />
5.3      Optionally, it is possible to send a mail to &#8220;root&#8221; as<br />
and when a log file is rotated and archived.  This too<br />
is user selectable.<br />
6        A sample session<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<sample session>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
aedes:~#rotatelog -e<br />
rotatelog     Version : 0.2<br />
1]    45056    /var/log/messages<br />
2]    8192    /var/log/syslog<br />
3]    106496    /var/log/wtmp<br />
4]    28672    /var/log/debug<br />
5]    4096    /home/bish/mail/.procmail.log<br />
6]    106496    /var/log/boa/access_log<br />
7]    163840    /var/log/boa/error_log<br />
Which logs to rotate [1 - 7] ?<br />
Otherwise enter [0] &#8230; to abort<br />
Enter numbers with with spaces in between : 6 7<br />
Rotating &#8230; /var/log/boa/access_log<br />
Rotating &#8230; /var/log/boa/error_log<br />
&#8211; Mail to root sent &#8212;<br />
aedes:~#mail<br />
Mail version 8.1 6/6/93.  Type ? for help.<br />
/var/spool/mail/root: 1 message 1 new<br />
&#038; 1<br />
Message 1:<br />
From root  Sun Nov  4 16:24:07 2001<br />
Date: Sun, 4 Nov 2001 16:24:07 +0530<br />
From: rotatelog@aedes<br />
To: root@aedes<br />
Subject: rotatelog notice<br />
Sun Nov  4 16:24:07 IST 2001<br />
/var/log/oldlogs/access_log.011104.gz<br />
/var/log/oldlogs/error_log.011104.gz<br />
&#038; quit<br />
Saved 1 message in mbox<br />
aedes:~#exit<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</sample session>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
6.1      Please note the following from the sample session<br />
o All log files in the rc files have been shown<br />
o It was possible to selectively rotate only two of the<br />
files (in this example the log files of boa http ser-<br />
ver), by entering 6 and 7 seperated by a space. It is<br />
possible to rotate multiple log files selectively.<br />
o The files have been archived with datestamp. A middle<br />
6-digit number is added, which  is  the  yymmdd stamp<br />
for the day. It is assumed that no file would need to<br />
be rotated twice in a day ! </p>
<p>7        Pre-requisites<br />
7.1      For mailing to root, sendmail binary is  used directly,<br />
so a properly configured MTA is expected.  No  recourse<br />
is taken for mailing through any MUA.<br />
7.2      Ensure that  you go  through  the  script, and edit the<br />
configurable section on the top for your system.<br />
7.3      There is NO need to create a directory for the archived<br />
log files, nor any need to create a rc file.  The first<br />
time this script is run, it checks for the  presence of<br />
the needed directories and rc file, if not found, crea-<br />
tes one. You may edit the  rc  file  subsequently  with<br />
root privileges. </p>
<p>8        Bugs and Bunnies<br />
8.1      I have been using this script (in a less  refined format<br />
since 1996). However, if you face any  problems  be free<br />
to contact me. There is only  one  bunny (I expect). The<br />
number of log files is limited to about  20  since after<br />
that, the top ones would scroll off the  screen.  I have<br />
never had the opportunity to cross this limit.  In  case<br />
the need is felt, it would be  necessary to  modify  the<br />
chk_size routine to be passed through a pager &#8230; can do<br />
it if asked &#8230; till then, let things lie as they are. </p>
<p>9        Kudos and Brickbats<br />
9.1      This script is released under GNU/ GPL licence. You are<br />
free to use and distribute this without any encumberan-<br />
ces. Ofcourse as per the protection of the GNU licence,<br />
no guns can be pointed at me if things go  wrong at any<br />
time because of this script ;-)<br />
9.2      I would love to have any extensions or alterations made<br />
to this script &#8230; all kudos  and  brickbats  should be<br />
directed at:<br />
USM Bish bish@nde.vsnl.net.in<br />
04 Nov 2001<br />
######################################<br />
###################################### </p>
<p># ROTATE LOG SCRIPT<br />
######################################<br />
#!/bin/bash<br />
######################################</p>
<p>#<br />
#    Shell program to rotate log files in /var/spool and other dirs<br />
#       anywhere on the system. Log files to be checked are to be inc-<br />
#       luded in a seperate rc file. See docs for format of file.<br />
#<br />
#    Copyright 2001, USM Bish, bish@nde.vsnl.net.in<br />
#<br />
#    This program is free software; you can redistribute it and/ or<br />
#    modify it under the terms of the GNU General Public License as<br />
#    published by the Free Software Foundation; either version 2 of<br />
#    the License, or (at your option) any later version.<br />
#<br />
#    This program is distributed in the hope that it will be useful<br />
#    but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
#    MERCHANTABILITY  or  FITNESS FOR A PARTICULAR PURPOSE. See the<br />
#    GNU General Public License for more details.<br />
#<br />
#    Description: A distro-independent method of rotating log files<br />
#       in /var/spool without necessity for cron processes.<br />
#<br />
#    NOTE: You must be the superuser to run this script.<br />
#<br />
#    Usage:<br />
#<br />
#        rotatelog [ -h | --help ] [-e] [-i]<br />
#<br />
#    Options:<br />
#<br />
#        -h, &#8211;help    Display this help message and exit.<br />
#        -e              E]xecute rotation<br />
#        -i              I]nfo on present log file sizes<br />
#<br />
#<br />
#    Revisions:<br />
#<br />
#    Nov/03/2001    File created &#8230;. ver 0.1<br />
#    Nov/04/2001    Mail to root added &#8230;. ver 0.2<br />
#<br />
################################</p>
<p>################################<br />
#  Editable variables<br />
################################<br />
#### Where to archive the old logs ?<br />
OLDLOGS=/var/log/oldlogs<br />
#### Where is the rotatelogrc file ?<br />
RC=$OLDLOGS/rotatelog.rc<br />
#### Send mail to root ? [ yes / no ]<br />
SENDMAIL=&#8221;yes&#8221;<br />
#SENDMAIL=&#8221;no&#8221;<br />
#################################<br />
No editing below this<br />
#################################<br />
PROGNAME=$(basename $0)<br />
VERSION=&#8221;0.2&#8243;<br />
TEMP_FILE1=/tmp/${PROGNAME}.$$.1<br />
TEMP_FILE2=/tmp/${PROGNAME}.$$.2<br />
TODAY=$(date +%y%m%d)   # YYMMDD for convenient sorting<br />
################################<br />
#    Functions<br />
################################<br />
function send_mail<br />
{<br />
#### Send mail to root<br />
echo &#8220;#!/bin/sh&#8221; > $TEMP_FILE1<br />
echo &#8220;sendmail -t << -EndOfMail-" >> $TEMP_FILE1<br />
echo &#8220;From: rotatelog&#8221; >> $TEMP_FILE1<br />
echo &#8220;To: root&#8221; >> $TEMP_FILE1<br />
echo &#8220;Subject: rotatelog notice&#8221; >> $TEMP_FILE1<br />
echo &#8220;&#8221; >> $TEMP_FILE1<br />
date >> $TEMP_FILE1<br />
echo &#8220;&#8221; >> $TEMP_FILE1<br />
cat $TEMP_FILE2 >> $TEMP_FILE1<br />
echo &#8220;&#8221; >> $TEMP_FILE2<br />
echo &#8220;-EndOfMail-&#8221; >> $TEMP_FILE1<br />
chmod +x $TEMP_FILE1<br />
$TEMP_FILE1<br />
echo &#8220;&#8221;<br />
echo &#8220;&#8211; Mail to root sent &#8211;&#8221;<br />
echo &#8220;&#8221;<br />
}<br />
function chk_size<br />
{<br />
CNT=0<br />
for i in `cat $RC | grep -v &#8220;#&#8221;`; do<br />
CNT=$((CNT+1))<br />
echo -en $CNT&#8221;]\t&#8221;<br />
du -b $i<br />
done<br />
}<br />
function rotate_log<br />
{<br />
#### Create the backup and zip it<br />
BASENAME=`basename $TARGET`<br />
cp $TARGET $OLDLOGS/$BASENAME.$TODAY<br />
gzip -9 $OLDLOGS/$BASENAME.$TODAY<br />
echo $OLDLOGS/$BASENAME.$TODAY.gz >> $TEMP_FILE2<br />
#### Now zap the space occupying hogs<br />
cat /dev/null > $TARGET<br />
chmod 666 $TARGET<br />
}<br />
function chk_rc<br />
{<br />
if ! [ -s $RC ]; then<br />
echo &#8220;rc file NOT found &#8230; &#8220;$RC<br />
echo -en &#8220;Create one ? [y/n] : &#8221;<br />
read YN<br />
case $YN in<br />
Y|y) ## Create a skeleton RC file<br />
cat << -EndOfRC- > $RC<br />
##########################<br />
# Sample rotatelog.rc file.All lines<br />
# with # are omitted.  All filenames<br />
# with full path, to begin on Col 1.<br />
# No line gaps permitted in between.<br />
##########################<br />
/var/log/messages<br />
/var/log/syslog<br />
/var/log/wtmp<br />
/var/log/debug<br />
-EndOfRC-<br />
echo<br />
echo $RC&#8221; has been created&#8221;<br />
echo &#8220;Add to this file if more log files are to&#8221;<br />
echo &#8220;be included &#8230; Press [Enter] to continue&#8221;<br />
echo<br />
read<br />
clear<br />
;;<br />
*)  # Anything else entered<br />
echo &#8220;Cannot proceed without a rc file&#8221;<br />
term_exit<br />
esac<br />
fi<br />
} </p>
<p>function chk_oldlogs<br />
{<br />
if ! [ -d $OLDLOGS ]; then<br />
echo -en &#8220;\tFirst time run &#8230;\n\n&#8221;<br />
mkdir $OLDLOGS<br />
chmod 755 $OLDLOGS<br />
fi<br />
}<br />
function chk_root<br />
{<br />
USR=`whoami`<br />
if ! [ "$USR" = "root" ]; then<br />
echo $PROGNAME&#8221;  [Version : "$VERSION"]&#8221;<br />
echo &#8220;Root privileges needed &#8230; &#8221;<br />
term_exit<br />
fi<br />
}<br />
function clean_up<br />
{<br />
rm -f $TEMP_FILE1<br />
rm -f $TEMP_FILE2<br />
} </p>
<p>function graceful_exit<br />
{<br />
clean_up<br />
exit<br />
} </p>
<p>function error_exit<br />
{<br />
echo &#8220;${PROGNAME}: ${1:-&#8221;Unknown Error&#8221;}&#8221; >&#038;2<br />
clean_up<br />
exit 1<br />
}<br />
function term_exit<br />
{<br />
echo &#8220;${PROGNAME}: Terminated&#8221;<br />
clean_up<br />
exit<br />
} </p>
<p>function int_exit<br />
{<br />
echo &#8220;${PROGNAME}: Aborted by user&#8221;<br />
clean_up<br />
exit<br />
} </p>
<p>function usage<br />
{<br />
echo &#8220;Usage: ${PROGNAME} [-h | --help] [-e] [-i]&#8221;<br />
} </p>
<p>function helptext<br />
{<br />
local tab=$(echo -en &#8220;\t\t&#8221;)<br />
cat <<- -EOF-<br />
${PROGNAME} ver. ${VERSION}<br />
This is a program to rotate log files in /var/spool or<br />
any other directory on the system, as specified in the<br />
rc file : $RC<br />
$(usage)<br />
Options:<br />
-h, --help    Display this help message and exit.<br />
-e              E]xecute rotation<br />
-i              I]nfo on present log file sizes<br />
NOTE: You must be the superuser to run this script.<br />
-EOF-<br />
}<br />
#####################################<br />
#    Program starts here<br />
#####################################<br />
# Trap TERM, HUP, and INT signals and properly exit<br />
trap term_exit TERM HUP<br />
trap int_exit INT<br />
if [ "$1" = "" ]; then<br />
usage<br />
graceful_exit<br />
fi<br />
if [ "$1" = "--help" ]; then<br />
helptext<br />
graceful_exit<br />
fi<br />
chk_root<br />
chk_oldlogs<br />
chk_rc<br />
# Process arguments<br />
while getopts ":hei" opt; do<br />
case $opt in<br />
e )    echo<br />
echo $PROGNAME"     Version : "$VERSION<br />
echo<br />
chk_size<br />
echo<br />
echo "Which logs to rotate [1 - $CNT] ?"<br />
echo "Otherwise enter [0] ... to abort."<br />
echo -en "Enter numbers with with spaces in between : "<br />
read NOS<br />
TNOS=`echo $NOS | tr -d [:alpha:]`<br />
NOS=$TNOS<br />
if [ "$NOS" = "" ]; then<br />
echo "Invalid option"<br />
term_exit<br />
fi<br />
if [ "$NOS" = "0" ]; then<br />
term_exit<br />
fi<br />
NNNOS=`echo $NOS | awk '{print $1}'`<br />
if [ "$NNNOS" -gt "$CNT" ]; then<br />
echo<br />
echo "Number not in menu : "$NOS<br />
term_exit<br />
fi<br />
NCNT=0<br />
clean_up<br />
for i in `echo $NOS`; do<br />
NCNT=0<br />
for j in `cat $RC | grep -v "#"`; do<br />
NCNT=$((NCNT+1))<br />
if [ "$NCNT" = "$i" ]; then<br />
TARGET=$j<br />
echo -en "\nRotating ... $TARGET\n"<br />
rotate_log<br />
fi<br />
done<br />
done<br />
if [ "$SENDMAIL" = "yes" ]; then<br />
send_mail<br />
fi<br />
;;<br />
i )    echo<br />
echo $PROGNAME"                  Version : "$VERSION<br />
echo<br />
echo "Info on present sizes of logs in bytes :"<br />
echo<br />
chk_size<br />
echo<br />
echo "Do: "$PROGNAME" -e ... to rotate these logs"<br />
echo<br />
;;<br />
h )    helptext<br />
graceful_exit<br />
;;<br />
* )    usage<br />
exit 1<br />
esac<br />
done<br />
graceful_exit<br />
###########################<br />
#   Everything below this is ignored<br />
###########################</p>
<p># ROTATELOG.RC FILE<br />
#################################### </p>
<p>####################################<br />
# Sample rotatelog.rc file.All lines<br />
# with # are omitted.  All filenames<br />
# with full path, to begin on Col 1.<br />
# No line gaps permitted in between.<br />
####################################<br />
/var/log/messages<br />
/var/log/syslog<br />
/var/log/wtmp<br />
/var/log/debug<br />
/home/bish/mail/.procmail.log<br />
/var/log/boa/access_log<br />
/var/log/boa/error_log<br />
"rotatelog.lsm"<br />
Begin3<br />
Title:          rotatelog<br />
Version:        0.2<br />
Entered-date:   04 Nov 2001<br />
Description:    Shell script manage log files in /var/log and other<br />
log files anywhere on the system<br />
Keywords:       sysadmin, logrotate, rotate log files<br />
Author: bish@nde.vsnl.net.in<br />
(USM Bish)<br />
Maintained-by: bish@nde.vsnl.net.in<br />
(USM Bish)<br />
Primary-site:   http://geocities.com/usmbish/scripts.html<br />
Original-site:  http://geocities.com/usmbish/scripts.html<br />
Platforms:      Linux<br />
Copying-policy: GPL<br />
End </p>
<p># rotatelog.lsm<br />
################################# </p>
<p>Begin3<br />
Title:          rotatelog<br />
Version:        0.2<br />
Entered-date:   04 Nov 2001<br />
Description:    Shell script manage log files in /var/log and other<br />
log files anywhere on the system<br />
Keywords:       sysadmin, logrotate, rotate log files<br />
Author: bish@nde.vsnl.net.in<br />
(USM Bish)<br />
Maintained-by: bish@nde.vsnl.net.in<br />
(USM Bish)<br />
Primary-site:   http://geocities.com/usmbish/scripts.html<br />
Original-site:  http://geocities.com/usmbish/scripts.html<br />
Platforms:      Linux<br />
Copying-policy: GPL<br />
End </p>
<p>======================================<br />
 Bash script to validate RPM files:<br />
====================================== </p>
<p> #!/bin/bash<br />
 # rpm-check.sh </p>
<p> # Queries an rpm file for description, listing,<br />
 #+ and whether it can be installed.<br />
 # Saves output to a file.<br />
 #<br />
 # This script illustrates using a code block. </p>
<p> SUCCESS=0<br />
 E_NOARGS=65 </p>
<p> if [ -z "$1" ]<br />
 then<br />
 echo "Usage: `basename $0` rpm-file"<br />
 exit $E_NOARGS<br />
 fi </p>
<p> { # Begin code block.<br />
 echo<br />
 echo "Archive Description:"<br />
 rpm -qpi $1 # Query description.<br />
 echo<br />
 echo "Archive Listing:"<br />
 rpm -qpl $1 # Query listing.<br />
 echo<br />
 rpm -i --test $1 # Query whether rpm file can be installed.<br />
 if [ "$?" -eq $SUCCESS ]<br />
 then<br />
 echo "$1 can be installed."<br />
 else<br />
 echo "$1 cannot be installed."<br />
 fi<br />
 echo # End code block.<br />
 } > &#8220;$1.test&#8221; # Redirects output of everything in block to file. </p>
<p> echo &#8220;Results of rpm test in file $1.test&#8221; </p>
<p> # See rpm man page for explanation of options. </p>
<p> exit 0 </p>
<p> ======================================<br />
 Crontab:<br />
 ====================================== </p>
<p> Creating a crontab file<br />
 ======================================<br />
 crontab -e<br />
 ====================================== </p>
<p> Crontab syntax<br />
 ======================================<br />
 * * * * * command to be executed<br />
 &#8211; - &#8211; - &#8211;<br />
 | | | | |<br />
 | | | | +&#8212;&#8211; day of week (0 &#8211; 6) (Sunday=0)<br />
 | | | +&#8212;&#8212;- month (1 &#8211; 12)<br />
 | | +&#8212;&#8212;&#8212; day of month (1 &#8211; 31)<br />
 | +&#8212;&#8212;&#8212;&#8211; hour (0 &#8211; 23)<br />
 +&#8212;&#8212;&#8212;&#8212;- min (0 &#8211; 59)<br />
 ====================================== </p>
<p> Crontab examples<br />
 ======================================<br />
 * * * * * <command> #Runs every minute<br />
 30 * * * * <command> #Runs at 30 minutes past the hour<br />
 45 6 * * * <command> #Runs at 6:45 am every day<br />
 45 18 * * * <command> #Runs at 6:45 pm every day<br />
 00 1 * * 0 <command> #Runs at 1:00 am every Sunday<br />
 00 1 * * 7 <command> #Runs at 1:00 am every Sunday<br />
 00 1 * * Sun <command> #Runs at 1:00 am every Sunday<br />
 30 8 1 * * <command> #Runs at 8:30 am on the first day of every month<br />
 00 0-23/2 02 07 * <command> #Runs every other hour on the 2nd of July<br />
 ====================================== </p>
<p> Special Stirngs<br />
 ======================================<br />
 @reboot <command> #Runs at boot<br />
 @yearly <command> #Runs once a year [0 0 1 1 *]<br />
 @annually <command> #Runs once a year [0 0 1 1 *]<br />
 @monthly <command> #Runs once a month [0 0 1 * *]<br />
 @weekly <command> #Runs once a week [0 0 * * 0]<br />
 @daily <command> #Runs once a day [0 0 * * *]<br />
 @midnight <command> #Runs once a day [0 0 * * *]<br />
 @hourly <command> #Runs once an hour [0 * * * *]<br />
 ====================================== </p>
<p> Multiple commands </p>
<p> @daily <command_01> &#038;&#038; <command_02><br />
 ====================================== </p>
<p> Disabling email notifications </p>
<p> By default a cron job will send an email to the user account executing the cronjob.<br />
    If this is not needed put the following command at the end of the cron job line:<br />
 >/dev/null 2>&#038;1<br />
 ====================================== </p>
<p> Specifying a crontab file to use </p>
<p> crontab -u <username> <crontab file><br />
 crontab -u tux ~/crontab<br />
 ====================================== </p>
<p> Removing a crontab file </p>
<p> crontab -r<br />
 ====================================== </p>
<p> ======================================<br />
 JUMPSTART ////////////////////////<br />
 ====================================== </p>
<p> # mkdir /jumpstart/image<br />
 # mkdir /jumpstart/config<br />
 # mkdir /jumpstart/share </p>
<p> # lofiadm -a /var/tmp/Solaris10_u5_1108.iso<br />
 /dev/lofi/1<br />
 # lofiadm /dev/lofi/1<br />
 /var/tmp/Solaris10_u5_1108.iso </p>
<p> # svcadm disable volfs<br />
 # mkdir -p /cdrom/cdrom0 </p>
<p> # mount -F hsfs -o ro /dev/lofi/1 /cdrom/cdrom0 </p>
<p> # cd /cdrom/cdrom0/Solaris_10/Tools<br />
 # ./setup_install_server /jumpstart/image<br />
 Verifying target directory&#8230;<br />
 Calculating the required disk space for the Solaris_11 product<br />
 &#8230; output skipped &#8230; </p>
<p> # cd /<br />
 # umount /cdrom/cdrom0<br />
 # lofiadm -d /dev/lofi/1<br />
 # lofiadm<br />
 Block Device File </p>
<p> # cd /jumpstart/image/Solaris_10/Misc/jumpstart_sample<br />
 # cp ./check /jumpstart/config </p>
<p> # cp /etc/dfs/dfstab /etc/dfs/dfstab.org </p>
<p> # vi /etc/dfs/dfstab<br />
 +&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
 | share -F nfs -o ro,anon=0 /jumpstart/config<br />
 | share -F nfs -o ro,anon=0 /jumpstart/image<br />
 | share -F nfs -o ro,anon=0 /jumpstart/share </p>
<p> # vi /etc/dfs/dfstab<br />
 +&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
 | share -F nfs -o ro,anon=0 /jumpstart </p>
<p> # svcadm enable nfs/server<br />
 # shareall </p>
<p> # vi /jumpstart/config/sysidcfg<br />
 +&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
 | system_locale=en_US<br />
 | timezone=MET<br />
 | name_service=NONE<br />
 | terminal=dtterm<br />
 | timeserver=localhost<br />
 | root_password=&#8221;WybF.D5GwZnz2&#8243;<br />
 | network_interface=primary { netmask=255.0.0.0 protocol_ipv6=no<br />
    default_route=127.0.0.1}<br />
 | security_policy=NONE<br />
 | nfs4_domain=dynamic </p>
<p> # vi /jumpstart/config/sun4u_profile<br />
 +&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
 | install_type initial_install<br />
 | system_type standalone<br />
 | partitioning explicit<br />
 | filesys any 1024 /<br />
 | filesys any 1024 /usr<br />
 | filesys any 1024 /var<br />
 | filesys any 1024 /opt<br />
 | filesys any 1024 /export/home<br />
 | filesys any 256 swap<br />
 | cluster SUNWCreq<br />
 | package SUNWman<br />
 | package SUNWbash<br />
 | package SUNWless </p>
<p> # cd /jumpstart/config<br />
 # vi ./rules<br />
 +&#8212;&#8212;&#8212;&#8211;<br />
 | karch sun4u &#8211; sun4u_profile &#8211; </p>
<p> # ./check </p>
<p> # vi /etc/hosts<br />
 +&#8212;&#8212;&#8212;&#8212;&#8211;<br />
 | 10.0.0.2 pino </p>
<p> # cd /jumpstart/image/Solaris_10/Tools<br />
 # ./add_install_client \<br />
 > -e 8:0:20:0:0:02 \<br />
 > -i 10.0.0.2 \<br />
 > -s tommie:/jumpstart/image \<br />
 > -c tommie:/jumpstart/config \<br />
 > -p tommie:/jumpstart/config \<br />
 > pino \<br />
 > sun4u </p>
<p> # svcadm enable rarp </p>
<p> # inetconv </p>
<p> # init 0<br />
 ok boot net &#8211; install </p>
<p> Create a finish script </p>
<p> # vi /jumpstart/config/sun4u_after<br />
 +&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
 | {<br />
 | mkdir /a/server<br />
 | mount -F nfs -o ro 10.0.0.1:/jumpstart/share /a/server<br />
 |<br />
 | cp /a/server/crontab.root /a/var/spool/cron/crontabs/root<br />
 | cp /a/server/hosts.header /a/hosts<br />
 |<br />
 | HOSTNAME=`cat /etc/nodename`<br />
 | regel=`grep $HOSTNAME /a/server/hosts.org`<br />
 | echo &#8220;$regel loghost .&#8221; >> /a/hosts<br />
 | grep -v $HOSTNAME /a/server/hosts.org >> /a/hosts<br />
 |<br />
 | mv /a/hosts /a/etc/hosts<br />
 | | umount /a/server<br />
 | rmdir /a/server<br />
 |<br />
 | touch /a/noautoshutdown<br />
 | touch /a/etc/.NFS4inst_state.domain<br />
 | } > /a/server.log 2> /a/server.errlog </p>
<p> # vi /jumpstart/share/hosts.header<br />
 +&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
 | #<br />
 | # Internet host table<br />
 | # </p>
<p> # vi /jumpstart/share/hosts.org<br />
 +&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
 | 10.0.0.1 tommie<br />
 | 10.0.0.2 pino # crontab -l > /jumpstart/share/crontab.root </p>
<p> Update the rules file </p>
<p> # vi rules<br />
 +&#8212;&#8212;&#8212;&#8211;<br />
 | karch sun4u &#8211; sun4u_profile sun4u_after </p>
<p> # ./check </p>
<p> ======================================<br />
 KICKSTART ////////////////////////<br />
 ====================================== </p>
<p> Before You Start </p>
<p> A Kickstart install involves three participants: a target machine uses a config file<br />
 to set system parameters and determine what RPMs to pull from the installation<br />
 media. (The config file may have any name; this article will refer to it as<br />
 ks.cfg.) </p>
<p> There are several ways to connect those pieces: the target machine can fetch the RPMs<br />
 from a local disk, NFS server, FTP server, and so on. The config file can come from<br />
 the aforementioned places or from the boot media, and it may exist in a different<br />
 place than the installation media. </p>
<p> Such flexibility makes it difficult to explain a &#8220;typical&#8221; Kickstart process in<br />
 detail. This article demonstrates just one method, using a web server to host the<br />
 install media and config file. This is likely the easiest and least intrusive<br />
 method to experiment with Kickstart. It should also scale as your Kickstart<br />
 experiment matures into a formal infrastructure. </p>
<p> To that end, the setup described in this article requires: </p>
<p> * The Fedora install files, which you&#8217;ll copy to the web server&#8217;s file system.<br />
 * A target machine on which you will install Fedora. Using virtual hardware, such as<br />
 VMware or Bochs, will simplify your experiment. </p>
<p> * Bootable media that matches the version of Fedora you plan to install. Choose from<br />
 install CD 1, diskettes (images/bootdisk.img and images/drvnet.img from the install<br />
 media), or a bootable CD made from images/boot.iso.</p>
<p> * A source machine to host the install files and Kickstart config, and run the web<br />
 server. </p>
<p> Some of these require additional explanation and I&#8217;ll describe them in turn.<br />
 The Source Machine: Setting up the Install Tree</p>
<p> The target machine will fetch its install files and ks.cfg from a web server running<br />
 on the source machine. The source machine needn&#8217;t run Linux, but it must have<br />
 roughly 2.2G disk space available. The web server must listen on port 80 due to a<br />
 limitation in Kickstart&#8217;s HTTP code. </p>
<p> Create a directory FC1-install under the document root and populate it with the<br />
 Fedora directory from the install media. Use your preferred download tool (say,<br />
 wget) to grab the tree from a Fedora mirror site or copy the contents from the<br />
 install CDs or ISOs. Be sure to maintain the directory structure in this latter<br />
 case. There are myriad ways to do this, such as: </p>
<p> $ cd /mnt/cdrom<br />
 $ cp -a Fedora /&#8230;docroot&#8230;/FC1-install </p>
<p> Creating the Kickstart Config File, ks.cfg </p>
<p> ks.cfg makes unattended installs possible. It holds canned responses to the questions<br />
 posed during an interactive install. The examples assume you&#8217;ve saved this file<br />
 under the web server&#8217;s document root as kickstart/ks.cfg. </p>
<p> There are several ways to create ks.cfg. (I did warn you that Kickstart was<br />
 flexible.) If you&#8217;re plotting a clone farm, build one machine to your specs and use<br />
 /root/anaconda-ks.cfg on that host as a starting point for the others. </p>
<p> Barring that, use the redhat-config-kickstart GUI (from the redhat-config-kickstart<br />
 package). This tool doesn&#8217;t support LVM for disk layout, but is a valuable learning<br />
 tool nonetheless. You can hand-edit the generated ks.cfg to use LVM (described<br />
 below). </p>
<p> You can also create or edit ks.cfg using any text editor, provided you know the<br />
 directives. Here&#8217;s a walk through the directives in the sample ks.cfg.<br />
 You probably already have the redhat-config-language, hwdata, and tzdata RPMs<br />
 installed already. They are not required, but include files that simplify<br />
 hand-editing ks.cfg.<br />
 Installation Type </p>
<p> The first entries are the installation type and source. </p>
<p> install<br />
 url &#8211;url http://kickstart-server/FC1-install </p>
<p> The type may be install or upgrade. The url directive specifies an HTTP installation<br />
 and indicates the URL of the install media. (The directory Fedora, from the install<br />
 media, must be a subdirectory of the URI part of the URL.) Other installation<br />
 sources include cdrom for swapping CDs or DVDs, nfs for mounting the install media<br />
 from an NFS share, and the self-explanatory ftp.</p>
<p> Languages and Input<br />
 lang and mouse indicate the language and mouse type, respectively, to use during the<br />
 installation. </p>
<p> lang en_US.UTF-8<br />
 mouse generic3ps/2 </p>
<p> The sample ks.cfg uses U.S. English with the Unicode (UTF-8) character set, and a<br />
 generic PS2 mouse with three buttons. </p>
<p> Refer to /usr/share/redhat-config-language/locale-list for the list of valid<br />
 languages. </p>
<p> The values of lang and mouse don&#8217;t matter for unattended installations.<br />
 langsupport and keyboard set the runtime (installed) language support and keyboard<br />
 type, respectively. </p>
<p> langsupport &#8211;default en_US.UTF-8 en_US.UTF-8<br />
 keyboard us </p>
<p> Specify a single language (en_US) or multiple languages with a default (&#8211;default<br />
 en_US en_UK). Specifying just the default (&#8211;default en_US) installs support for<br />
 all languages.<br />
 Video </p>
<p> For a workstation build you&#8217;ll likely want to configure your video card and monitor,<br />
 using xconfig. </p>
<p> xconfig &#8211;card &#8220;VMWare&#8221; &#8211;videoram 16384 &#8211;hsync 31.5-37.9<br />
 &#8211;vsync 50-70 &#8211;resolution 800&#215;600 &#8211;depth 16 </p>
<p> (We&#8217;ve split the above line for readability; it should be a single line in ks.cfg..)<br />
 xconfig takes the card&#8217;s name (listed in /usr/share/hwdata/Cards) and video RAM in<br />
 kilobytes. The remaining parameters specify the monitor&#8217;s horizontal and vertical<br />
 sync rates, resolution, and color depth in bits. </p>
<p> Use the skipx directive to skip this step (say, for headless servers). You can<br />
 manually configure X later. </p>
<p> Networking </p>
<p> The network directive sets the target host&#8217;s runtime network configuration. This may<br />
 be different than the build-time IP. For example, you may use separate networks to<br />
 build (DHCP-enabled) and deploy machines (static IPs). </p>
<p> network &#8211;device eth0 &#8211;bootproto static &#8211;ip 10.10.10.237<br />
 &#8211;netmask 255.255.255.0 &#8211;gateway 10.10.10.254<br />
 &#8211;nameserver 10.10.10.11,10.0.0.23,10.1.0.34<br />
 &#8211;hostname fc1-test </p>
<p> This line configures the interface eth0 with a static IP address of 10.10.10.237.<br />
 Notice that the nameserver selection accepts a comma-separated list of IP<br />
 addresses. </p>
<p> Configure other interfaces by specifying different devices with &#8211;device. You needn&#8217;t<br />
 supply any network information when &#8211;bootproto is dhcp or bootp.<br />
 The network configuration will differ for each host in a clone farm, so you can&#8217;t use<br />
 the same file for the entire group. I&#8217;ll present ideas on how to handle this<br />
 situation in a future article. </p>
<p> Authentication and Security </p>
<p> Set the root password with the rootpw directive. </p>
<p> rootpw &#8211;iscrypted $1$NaCl$X5jRlREy9DqNTCXjHp075/ </p>
<p> The &#8211;iscrypted flag indicates an MD5-hashed password. You can find a password&#8217;s<br />
 encrypted form any number of ways, such as copying an existing entry from<br />
 /etc/shadow or using OpenSSL&#8217;s passwd module: </p>
<p> $ openssl passwd -1 -salt &#8220;NaCl&#8221; &#8220;don&#8217;t use this&#8221; </p>
<p> Without the &#8211;iscrypted flag the specified password will be used as-is, such as: </p>
<p> rootpw plain_text </p>
<p> On the subject of passwords, authconfig determines how to authenticate users. The<br />
 following line sets the target host to use MD5-hashed passwords from the local<br />
 /etc/passwd and /etc/shadow files: </p>
<p> authconfig &#8211;enableshadow &#8211;enablemd5 </p>
<p> There are other authentication options, such as NIS, LDAP, or Kerberos 5.<br />
 The firewall directive sets up a rudimentary ruleset, useful for a machine that will<br />
 talk to the outside world: </p>
<p> firewall &#8211;enabled &#8211;trust=eth0 &#8211;http &#8211;ssh </p>
<p> Here, traffic from interface eth0 will be implicitly trusted. The firewall will<br />
 permit incoming SSH (port 22/tcp) and HTTP (80/tcp) traffic on all interfaces. </p>
<p> Specify firewall &#8211;disabled to manually configure the firewall later or to skip it<br />
 altogether. </p>
<p> Time Zone </p>
<p> Set the machine&#8217;s time zone with the timezone directive: </p>
<p> timezone America/Chicago </p>
<p> Valid time zones are in the TZ column of the file /usr/share/zoneinfo/zone.tab.<br />
 Boot Loader </p>
<p> The bootloader directive sets the location of the GRUB boot loader. The sample ks.cfg<br />
 places it in the master boot record (MBR): </p>
<p> bootloader &#8211;location=mbr </p>
<p> If you don&#8217;t want a boot loader, specify &#8211;location=none. Remove an old boot loader<br />
 from the MBR with the separate zerombr directive.</p>
<p> Disks </p>
<p> Disk setup is the most complex part of a ks.cfg because there are so many machine-<br />
 and environment-dependent choices. Note that the sample ks.cfg clears existing<br />
 partitions on the target machine, so be sure to backup any valuable data. </p>
<p> clearpart removes disk partitions. </p>
<p> clearpart &#8211;all &#8211;drives=sda &#8211;initlabel </p>
<p> clearpart can remove just Linux partitions (&#8211;linux) or all existing partitions<br />
 (&#8211;all). It removes partitions from all drives unless you&#8217;ve added the &#8211;drives<br />
 flag. </p>
<p> The &#8211;initlabel flag works for previously unused disks or disks with foreign<br />
 partition schemes: it clears out the old partitions and sets up a scheme that Linux<br />
 can understand. </p>
<p> Omit clearpart to preserve existing partition boundaries. </p>
<p> part sets up partitions. The sample ks.cfg uses a simple two-partition layout and has<br />
 a separate swap partition: </p>
<p> part /boot &#8211;fstype ext3 &#8211;size=100 &#8211;ondisk=sda &#8211;asprimary<br />
 part / &#8211;fstype ext3 &#8211;size=1024 &#8211;grow &#8211;ondisk=sda &#8211;asprimary<br />
 part swap &#8211;size=128 &#8211;grow &#8211;size=256 &#8211;ondisk=sda &#8211;asprimary </p>
<p> The first parameter specifies the mount point, here /boot, /, and swap. (Linux<br />
 doesn&#8217;t really mount swap space, but that&#8217;s a minor technicality.) Set the<br />
 file-system type with the &#8211;fstype flag. The sample uses ext3. Other options<br />
 include ext2 and vfat (aka Windows). Swap doesn&#8217;t use a file-system type.<br />
 Specify a partition&#8217;s size in megabytes using the &#8211;size flag. Specify the<br />
 partition&#8217;s physical disk with the optional &#8211;ondisk flag. Mark your primary<br />
 partitions with &#8211;asprimary. </p>
<p> part&#8217;s &#8211;onpart and &#8211;noformat flags preserve existing partitions between Kickstart<br />
 installs. For example, the following would mount the preexisting hda7 as /home: </p>
<p> part /home &#8211;fstype ext3 &#8211;size 1024 &#8211;onpart hda7 &#8211;noformat </p>
<p> Note that this won&#8217;t shuffle data to another part of the disk if other partition<br />
 sizes change; it simply tells Kickstart to leave hda7&#8242;s partition boundaries intact<br />
 and to skip creating a new file system there using mkfs. </p>
<p> The following is a simple one-disk LVM setup: </p>
<p> part /boot &#8211;fstype ext3 &#8211;size=75 &#8211;asprimary<br />
 part pv.00 &#8211;size=1 &#8211;grow &#8211;asprimary </p>
<p> volgroup vgroot pv.00<br />
 logvol / &#8211;name=root.fs &#8211;vgname=vgroot &#8211;size=1024<br />
 logvol swap &#8211;name=swap.vol &#8211;vgname=vgroot &#8211;size=256 </p>
<p> The second part directive sets up a partition as an LVM physical volume (PV). The<br />
 &#8211;grow flag grows this partition to the maximum allowable size, so that you needn&#8217;t<br />
 know the disk&#8217;s size ahead of time. part still requires a size, though, so it uses<br />
 a bogus PV partition size of 1MB. </p>
<p> logvol is LVM&#8217;s part equivalent: it accepts the logical volume&#8217;s mount point and<br />
 size, in addition to the volume group to which it belongs. logvol&#8217;s &#8211;name flag<br />
 names the volume. </p>
<p> Note that the generated /root/anaconda-ks.cfg on the target host has a commented-out<br />
 disk layout.<br />
 Rebooting </p>
<p> The reboot directive forces the target host to reboot when the installation<br />
 completes. Don&#8217;t forget to remove the installation media, lest the machine reboot<br />
 right back into the installer. </p>
<p> Package Selection </p>
<p> The %packages directive specifies which RPMs to install on the target host. You may<br />
 select packages individually or en masse as groups. To specify a group, prefix the<br />
 name with the @ symbol and a space. Precede a name with a minus symbol (-) to<br />
 exclude that package from the group. </p>
<p> %packages<br />
 @ dialup<br />
 kernel<br />
 grub<br />
 e2fsprogs </p>
<p> The Fedora/base/comps.xml file, from the install media, defines package groups. I&#8217;ll<br />
 describe this file in greater detail in a future article.<br />
 Kickstart installs packages in addition to those you select in order to resolve<br />
 dependencies. Use %packages&#8217;s &#8211;ignoredeps flag to ignore package dependencies.<br />
 Package selection is another area in which it is easiest to perform a manual<br />
 installation once, then mine the resultant /root/anaconda-ks.cfg file for<br />
 information.</p>
<p> Build the Target Machine: Run the Kickstart </p>
<p> The hard work is done. Now boot the target machine from the Fedora media. At the<br />
 boot: prompt, enter: </p>
<p> linux ks=http://build-server/kickstart/ks.cfg </p>
<p> You will receive an error if the boot media does not match the version of Fedora<br />
 you&#8217;re trying to install. </p>
<p> Unless you have DHCP available on the target machine&#8217;s network, the installation will<br />
 pause for you to enter its IP configuration. This is fine for small deployments and<br />
 experiments, but a full, hands-off Kickstart infrastructure calls for DHCP or<br />
 bootp. </p>
<p> The installation will also pause for input if any required directives are missing<br />
 from ks.cfg. </p>
<p> Troubleshooting a Failed Install </p>
<p> The installer&#8217;s error reporting can be cryptic. Messages refer to lines in Anaconda&#8217;s<br />
 underlying Python scripts, not your ks.cfg. </p>
<p> Include the interactive directive to step through the installation using values from<br />
 ks.cfg as the defaults. You cannot test the root password this way, though; you<br />
 must enter that manually.</p>
<p> Going Beyond </p>
<p> My Kickstart R&#038;D has certainly paid off: I no longer have to click through the full<br />
 Fedora installer and I can grab a tea while Kickstart does the hard work.<br />
 Hopefully, this article will help jump-start your own Kickstart projects.<br />
 There is a lot more to Kickstart than what I have described here. It supports several<br />
 customization points, including home-grown RPMs and pre-/post-install scripts. I&#8217;ll<br />
 cover these and more in a future article.</p>
<p> Resources </p>
<p> # Sample ks.cfg </p>
<p> ##<br />
 ## sample config file for testing Kickstart<br />
 ## for OnLAMP.com article<br />
 ##<br />
 ## NOTE: Likely, you&#8217;ll have to change several values<br />
 ## here to match your hardware.<br />
 ##<br />
 ## </p>
<p> ## &#8211; - install type/source &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211;<br />
 install<br />
 url &#8211;url http://build-server/FC1-install </p>
<p> ## &#8211; - debugging &#8211; - &#8211; - &#8211; - &#8211; - &#8211; -<br />
 ## :: uncomment the following to debug a Kickstart config file<br />
 ## interactive </p>
<p> ## &#8211; - language and input support &#8211; - &#8211; - &#8211; - &#8211; -<br />
 ## :: language used during install<br />
 lang en_US.UTF-8 </p>
<p> ## :: mouse used during install<br />
 mouse generic3ps/2 </p>
<p> ## :: runtime language and keyboard support<br />
 langsupport &#8211;default en_US.UTF-8 en_US.UTF-8<br />
 keyboard us </p>
<p> ## &#8211; - video card and monitor &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - </p>
<p> xconfig &#8211;card &#8220;VMWare&#8221; &#8211;videoram 16384 &#8211;hsync 31.5-37.9 &#8211;vsync 50-70 &#8211;resolution<br />
 800&#215;600 &#8211;depth 16 </p>
<p> ## &#8211; - network configuration &#8211; - &#8211; - &#8211; - &#8211; - &#8211; -<br />
 network &#8211;device eth0 &#8211;bootproto static &#8211;ip 10.10.10.237 &#8211;netmask 255.255.255.0<br />
 &#8211;gateway 10.10.10.254 &#8211;nameserver 10.10.10.11,10.0.0.23,10.1.0.34 &#8211;hostname<br />
 fc1-test </p>
<p> ## &#8211; - security and authentication &#8211; - &#8211; - &#8211; - &#8211; </p>
<p> rootpw &#8211;iscrypted $1$NaCl$X5jRlREy9DqNTCXjHp075/ </p>
<p> firewall &#8211;disabled </p>
<p> authconfig &#8211;enableshadow &#8211;enablemd5 </p>
<p> ## &#8211; - time zone &#8211; - &#8211; - &#8211; - &#8211; - &#8211; -<br />
 timezone America/Chicago </p>
<p> ## &#8211; - boot loader- &#8211; - &#8211; - &#8211; - &#8211; - &#8211;<br />
 bootloader &#8211;location=mbr </p>
<p> ## &#8211; - disk setup &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - </p>
<p> ## :: remove old partitions </p>
<p> clearpart &#8211;all &#8211;initlabel </p>
<p> ## :: choose between hard partitioning and LVM,<br />
 ## :: then uncomment the proper set of lines </p>
<p> ## :: hard partitioning<br />
 # part /boot &#8211;fstype ext3 &#8211;size=100 &#8211;ondisk=sda<br />
 # part / &#8211;fstype ext3 &#8211;size=1024 &#8211;grow &#8211;ondisk=sda<br />
 # part swap &#8211;size=128 &#8211;grow &#8211;size=256 &#8211;ondisk=sda </p>
<p> ## :: LVM<br />
 # part /boot &#8211;fstype ext3 &#8211;size=100 &#8211;asprimary &#8211;ondisk=sda<br />
 # part pv.00 &#8211;size=1 &#8211;grow &#8211;asprimary &#8211;ondisk=sda<br />
 #<br />
 # volgroup vgroot pv.00<br />
 # logvol / &#8211;name=root.fs &#8211;vgname=vgroot &#8211;size=1024<br />
 # logvol swap &#8211;name=swap.vol &#8211;vgname=vgroot &#8211;size=256 </p>
<p> ## &#8211; - package selection &#8211; - &#8211; - &#8211; - &#8211; - &#8211; -<br />
 ## :: reboot the machine when done<br />
 ## :: (it&#8217;s up to you to remove the boot media) </p>
<p> reboot </p>
<p> ## &#8211; - package selection &#8211; - &#8211; - &#8211; - &#8211; - &#8211; -<br />
 ## :: this is a barebones install, just for testing Kickstart<br />
 %packages<br />
 @ dialup<br />
 kernel<br />
 grub<br />
 e2fsprogs </p>
<p> ## &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - &#8211; - -</p>
<p>======================================<br />
 FILE SYSTEM ////////////////////////<br />
 ====================================== </p>
<p> ======================================<br />
 Super Block / Data Block / Index:<br />
 ====================================== </p>
<p> The [super block] contains an array of free disk block numbers, one of which points<br />
 to the next entry in the list. That entry in turn will be a [data block], which<br />
 contains an array of some other free blocks and a next pointer. When a process<br />
 requests a block, it searches the free block list, returns the available disk block<br />
 from the array of free blocks in the super block. </p>
<p> If the [super block] contains only one entry which is a pointer to a [data block],<br />
 which contains a list of other free blocks, all the entries from that block will be<br />
 copied to the [super block] free list and returns that block to the process.<br />
 Freeing of a block is reverse process of allocation. If the list of free blocks in<br />
 [super block] has enough space for the entry then, this block address will be<br />
 marked in the list. </p>
<p> If the list is full, all the entries from the [super block] will be copied to the<br />
 freed block and mark an entry for this block in the super block. Now the list in<br />
 super block contains only this entry. Index indexes to the next free disk block in<br />
 the free disk block list. </p>
<p> fsck -F ufs -o b=97472 /dev/rdsk/c0t0d0s0<br />
 /* Check and repair a UFS filesystem on c0t0d0s0, using an alternate superblock */ </p>
<p> newfs -Nv /dev/rdsk/c0t0d0s1<br />
 /* To view the super blocks available */ </p>
<p> [ root@enterprise ]$ newfs -Nv /dev/rdsk/c0t0d0s1<br />
 mkfs -F ufs -o N /dev/rdsk/c0t0d0s1 1049760 135 16 8192 1024 16 10 120 2048 t 0 0 8<br />
 128 n<br />
 /dev/rdsk/c0t0d0s1: 1049760 sectors in 486 cylinders of 16 tracks, 135 sectors<br />
 512.6MB in 31 cyl groups (16 c/g, 16.88MB/g, 8128 i/g)<br />
 super-block backups (for fsck -F ufs -o b=#) at:<br />
 32, 34736, 69440, 104144, 138848, 173552, 208256, 242960, 277664, 312368,<br />
 726512, 761216, 795920, 830624, 865328, 900032, 934736, 969440, 1004144,<br />
 1038848,<br />
 [ root@enterprise ]$ </p>
<p> ======================================<br />
 SETUID/SETGID:<br />
 ======================================<br />
  The setuid permission may be set by prefixing a permission set with the number four<br />
 (4) as shown in the following example: </p>
<p> # chmod 4755 suidexample.sh </p>
<p> The permissions on the suidexample.sh file should now look like the following: </p>
<p> -rwsr-xr-x 1 trhodes trhodes 63 Aug 29 06:36 suidexample.sh </p>
<p> It should be noticeable from this example that an s is now part of the permission set<br />
 designated for the file owner, replacing the executable bit. This allows utilities<br />
 which need elevated permissions, such as passwd. </p>
<p> To view this in real time, open two terminals. On one, start the passwd process as a<br />
 normal user. While it waits for a new password, check the process table and look at<br />
 the user information of the passwd command. </p>
<p> In terminal A: </p>
<p> Changing local password for trhodes<br />
 Old Password: </p>
<p> In terminal B: </p>
<p> # ps aux | grep passwd<br />
 trhodes 5232 0.0 0.2 3420 1608 0 R+ 2:10AM 0:00.00 grep passwd<br />
 root 5211 0.0 0.2 3620 1724 2 I+ 2:09AM 0:00.01 passwd </p>
<p> As stated above, the passwd is run by a normal user, but is using the effective UID<br />
 of root. </p>
<p> The setgid permission performs the same function as the setuid permission; except<br />
 that it alters the group settings. When an application or utility is ran with this<br />
 setting, it will be granted the permissions based on the group that owns the file,<br />
 not the user who started the process. </p>
<p> To set the setgid permission on a file, provide the chmod command with a leading two<br />
 (2) as in the following example: </p>
<p> # chmod 2755 sgidexample.sh </p>
<p> The new setting may be viewed as before, notice the s is now in the field designated<br />
 for the group permission settings: </p>
<p> -rwxr-sr-x 1 trhodes trhodes 44 Aug 31 01:49 sgidexample.sh </p>
<p> truss -f -p
<pid of a shell>
<p> /* Using multiple windows, this can be used to trace setuid/setgid programs */ </p>
<p> ======================================<br />
 HARD LINK/SOFT LINK:<br />
 ======================================<br />
 The difference between a hard link and a soft link~ </p>
<p> Hard links: a hard link is a pointer to the file&#8217;s i-node. For example, suppose that<br />
 we have a file a-file.txt that contains the string &#8220;The file a-file.txt&#8221;: </p>
<p> % cat a-file.txt<br />
 The file a-file.txt<br />
 % </p>
<p> Now we use the ln command to create a link to a-file.txt called b-file.txt: </p>
<p> % ls<br />
 ./ ../ a-file.txt<br />
 % ln a-file.txt b-file.txt<br />
 % ls<br />
 ./ ../ a-file.txt b-file.txt </p>
<p> The two names a-file.txt and b-file.txt now refer to the same data: </p>
<p> % cat b-file.txt<br />
 The file a-file.txt<br />
 % </p>
<p> If we modify the contents of file b-file.txt, then we also modify the contents of<br />
 file a-file.txt: </p>
<p> % vi b-file.txt<br />
 &#8230;<br />
 % cat b-file.txt<br />
 The file a-file.txt has been modified.<br />
 % cat a-file.txt<br />
 The file a-file.txt has been modified.<br />
 % </p>
<p> and vice versa:<br />
 % vi a-file.txt<br />
 &#8230;<br />
 % cat a-file.txt<br />
 The file a-file.txt has been modified again!<br />
 % cat b-file.txt<br />
 The file a-file.txt has been modified again!<br />
 % </p>
<p> Soft links (symbolic links): a soft link, also called symbolic link, is a file that<br />
 contains the name of another file. We can then access the contents of the other<br />
 file through that name. That is, a symbolic link is like a pointer to the file&#8217;s<br />
 contents. For instance, supposed that in the previous example, we had used the -s<br />
 option of the ln to create a soft link: </p>
<p> % ln -s a-file.txt b-file.txt </p>
<p> But what are the differences between the two types of links, in practice? Let us look<br />
 at an example that highlights these differences. The directory currently looks like<br />
 this (let us assume that a-file.txt b-file.txt are both hard links to the same<br />
 file): </p>
<p> % ls<br />
 ./ ../ a-file.txt b-file.txt </p>
<p> Let us first add another symbolic link using the -s option: </p>
<p> % ln -s a-file.txt Symbolicb-file.txt<br />
 % ls -F<br />
 ./ ../ a-file.txt b-file.txt Symbolicb-file.txt@ </p>
<p> A symbolic link, that ls -F displays with a @ symbol, has been added to the<br />
 directory. Let us examine the contents of the file: </p>
<p> % cat Symbolicb-file.txt<br />
 The file a-file.txt has been modified again! </p>
<p> If we change the file Symbolicb-file.txt, then the file a-file.txt is also modified.<br />
 % vi Symbolicb-file.txt<br />
 &#8230;<br />
 % cat Symbolicb-file.txt<br />
 The file a-file.txt has been modified a third time!<br />
 % cat a-file.txt<br />
 The file a-file.txt has been modified a third time!<br />
 % cat b-file.txt<br />
 The file a-file.txt has been modified a third time!<br />
 % </p>
<p> If we remove the file a-file.txt, we can no longer access the data through the<br />
 symbolic link Symbolicb-file.txt: </p>
<p> % ls -F<br />
 ./ ../ a-file.txt b-file.txt Symbolicb-file.txt@<br />
 % rm a-file.txt<br />
 rm: remove `a-file.txt&#8217;? y<br />
 % ls -F  ./ ../ b-file.txt Symbolicb-file.txt@<br />
 % cat Symbolicb-file.txt<br />
 cat: Symbolicb-file.txt: No such file or directory </p>
<p> The link Symbolicb-file.txt contains the name a-file.txt, and there no longer is a<br />
 file with that name. On the other hand, b-file.txt has its own pointer to the<br />
 contents of the file we called a-file.txt, and hence we can still use it to access<br />
 the data. </p>
<p> % cat b-file.txt<br />
 The file a-file.txt has been modified a third time! </p>
<p> Although it may seem like symbolic links are not particularly useful, hard links have<br />
 their drawbacks. The most significant drawback is that hard links cannot be created<br />
 to link a file from one file system to another file on another file system. A Unix<br />
 file structure hierarchy can consist of several different file systems (possibly on<br />
 several physical disks). Each file system maintains its own information regarding<br />
 the internal structure of the system and the individual files on the system. Hard<br />
 links only know this system-specific information, which make hard links unable to<br />
 span file systems. Soft links, on the other hand, know the name of the file, which<br />
 is more general, and are able to span file systems. </p>
<p> For a concrete analogy, suppose that our friend Joel User is a student at both UBC<br />
 and SFU. Both universities assign him a student number. If he tries to use his UBC<br />
 student number at SFU, he will not meet with any success. He will also fail if he<br />
 tries to use his SFU student number at UBC. But if he uses his legal name, Joel<br />
 User, he will probably be successful. The student numbers are system-specific (like<br />
 hard links), while his legal name spans both of the systems (like soft links).<br />
 Here is an example that demonstrates a situation where a hard link cannot be used and<br />
 a symbolic link is needed. Suppose that we try to create a hard link from the<br />
 current working directory to the C header stdio.h. </p>
<p> % ln /usr/include/stdio.h stdio.h<br />
 ln: creating hard link `stdio.h&#8217; to `/usr/include/stdio.h&#8217;: Invalid cross-device link<br />
 % </p>
<p> The ln command fails because stdio.h is stored on a different file system. If we want<br />
 to create a link to it, we will have to use a symbolic link: </p>
<p> % ln -s /usr/include/stdio.h stdio.h<br />
 % ls -l<br />
 lrwxrwxrwx 1 a1a1 guest 20 Apr 20 11:58 stdio.h -> /usr/include/stdio.h<br />
 % ls ./ ../ stdio.h@<br />
 % </p>
<p> Now we can view the file stdio.h just as if it was located in the working directory.<br />
 For example: </p>
<p> % cat stdio.h<br />
 /* Copyright (c) 1988 AT&#038;T */<br />
 /* All Rights Reserved */ </p>
<p> /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&#038;T */<br />
 /* The copyright notice above does not evidence any */<br />
 /* actual or intended publication of such source code. */ </p>
<p> /*<br />
 * User-visible pieces of the ANSI C standard I/O package.<br />
 */ </p>
<p> #ifndef _STDIO_H<br />
 #define _STDIO_H<br />
 &#8230;<br />
 % </p>
<p> The entire output of the cat command was not included to save space.<br />
 Note that the long listing (ls -l) of a soft link does not accurately reflect its<br />
 associated permissions. To view the permissions of the file or directory that the<br />
 symbolic link references, the -L options of the ls command can be used. For<br />
 example: </p>
<p> % ln -s /usr/include/stdio.h stdio.h </p>
<p> % ls -l stdio.h<br />
 lrwxrwxrwx 1 a1a1 undergrad 20 May 10 15:13 stdio.h -> /usr/include/stdio.h </p>
<p> % ls -l /usr/include/stdio.h<br />
 -rw-r&#8211;r&#8211; 1 root bin 11066 Jan 5 2000 /usr/include/stdio.h </p>
<p> % ls -lL stdio.h<br />
 -rw-r&#8211;r&#8211; 1 root bin 11066 Jan 5 2000 stdio.h </p>
<p> ======================================<br />
 File Manipulation Solaris:<br />
 ====================================== </p>
<p> File Manipulation </p>
<p> dos2unix | -ascii <filename> </p>
<p> /* Converts DOS file formats to Unix */<br />
 ======================================= </p>
<p> fold -w 180 </p>
<p> /* To break lines to have maximum char */<br />
 ======================================= </p>
<p> split [-linecount] [file] </p>
<p> /* Split files into pieces */<br />
 ======================================= </p>
<p> [vi] : %s/existing/new/g </p>
<p> /* Search and Replace text in vi */<br />
 ======================================= </p>
<p> [vi] :set list </p>
<p> /* Show non-printing characters in vi */<br />
 ======================================= </p>
<p> [vi] :set nu </p>
<p> /* Set line numbers in vi */<br />
 ======================================= </p>
<p> [vi] :set ts=[num] </p>
<p> /* Set tab stops in vi */<br />
 ======================================= </p>
<p> ======================================<br />
 File System Solaris:<br />
 ====================================== </p>
<p> /sbin/uadmin x x </p>
<p> /* Syncs File Systems and Reboots systems fast */<br />
 ======================================= </p>
<p> awk &#8216; END {print NR}&#8217; file_name </p>
<p> /* Display the Number of lines in a file */<br />
 ======================================= </p>
<p> cat /dev/null > filename </p>
<p> /* Zero&#8217;s out the file without breaking pipe */<br />
 ======================================= </p>
<p> cksum [filename] </p>
<p> /* View the checksum value for the given file */<br />
 ======================================= </p>
<p> dd if=/dev/rdsk/&#8230; of=/dev/rdsk/&#8230; bs=4096 </p>
<p> /* Make a mirror image of your boot disk */<br />
 ======================================= </p>
<p> df -k | grep dg| awk &#8216;{print $6}&#8217; |xargs -n 1 umount </p>
<p> /* Unmount all file systems in disk group dg */<br />
 ======================================= </p>
<p> fsck -F ufs -o b=97472 /dev/rdsk/c0t0d0s0 </p>
<p> /* Check and repair a UFS filesystem on c0t0d0s0, using an alternate superblock */<br />
 ======================================= </p>
<p> fsck -F ufs -y /dev/rdsk/c0t0d0s0 </p>
<p> /* Check a UFS filesystem on c0t0d0s0, repair any problems without prompting. */<br />
 ======================================= </p>
<p> fsck -F ufs /dev/rdsk/c0t0d0s0 </p>
<p> /* Check a UFS filesystem on c0t0d0s0 */<br />
 ======================================= </p>
<p> gzip -d -c tarball.tgz | (cd /[dir];tar xf &#8211; ) &#038; </p>
<p> /* Unpacking tarballs to diff location */<br />
 ======================================= </p>
<p> gzip -dc file1.tar.gz | tar xf &#8211; </p>
<p> /* Unpack .tar.gz files in place */<br />
 ======================================= </p>
<p> ln [-fhns] <source file> <destination file> </p>
<p> /* Creating hard links and soft links */<br />
 ======================================= </p>
<p> ls -al | awk &#8216;$3 == &#8220;oracle&#8221; || $3 == &#8220;root&#8221; {print $9}&#8217; </p>
<p> /* List all file names by testing owner */<br />
 ======================================= </p>
<p> ls -l | sort +4n </p>
<p> /* List files by size */<br />
 ======================================= </p>
<p> ls -la | awk &#8216;{ print $5,&#8221; &#8220;,$9 }&#8217; | sort -rn </p>
<p> /* File sizes of current directory */<br />
 ======================================= </p>
<p> ls -lR | awk &#8216;{total +=$5};END {print &#8220;Total size: &#8221; total/1024/1024 &#8220;MB&#8221; }&#8217; </p>
<p> /* Recursive directory size calculations in MB */<br />
 ======================================= </p>
<p> mkisofs -l -L -r -o [image-name].iso [directory] </p>
<p> /* Create an ISO image of a directory */<br />
 ======================================= </p>
<p> mount -F ufs -o rw,remount / </p>
<p> /* Used to remount root to make it writeable */<br />
 ======================================= </p>
<p> mount -o remount,logging /spare </p>
<p> /* Re-mount the ro file system rw and turn on ufs logging */<br />
 ======================================= </p>
<p> mount DOS fdisk partition from Solaris </p>
<p> /* mount -f pcfs /dev/dsk/c0d0p1 /export/dos */<br />
 ======================================= </p>
<p> mv [filename]{,.new_suffix} </p>
<p> /* Renaming file */<br />
 ======================================= </p>
<p> pax -rw . /newdir </p>
<p> /* Efficient alternative for copying directories */<br />
 ======================================= </p>
<p> prtvtoc /dev/rdsk/c0t0d0s2 | fmthard -s &#8211; /dev/rdsk/c0t1d0s2 </p>
<p> /* Cloning Partitiontables */<br />
 ======================================= </p>
<p> rpm -q &#8211;queryformat &#8216;%{INSTALLPREFIX}\n&#8217; [packagename] </p>
<p> /* [Linux] Locate binaries */<br />
 ======================================= </p>
<p> tar cf &#8211; . | (cd /newdir ; tar xf -) </p>
<p> /* Recursively copy files and their permissions */<br />
 ======================================= </p>
<p> tar cvf filename.tar </p>
<p> /* Create a tape (tar) archive */<br />
 ======================================= </p>
<p> tar xvf filename.tar </p>
<p> /* Extract a tape (tar) archive */<br />
 ======================================= </p>
<p> X=$(wc -l < filename); echo $X </p>
<p> /* Count number of lines in a file into a variable (ksh) */<br />
 ======================================= </p>
<p> zcat
<patch_file.tar.Z | tar xvf - </p>
<p> /* Extract the patch_file that is a compressed tar file */<br />
 ======================================= </p>
<p> zcat [cpio file] | cpio -itmv </p>
<p> /* Show the contents of a compressed cpio */<br />
 ======================================= </p>
<p> File Transfer </p>
<p> find . -depth | cpio -pdmv /path/tobe/copied/to </p>
<p> /* Fast alternative to cp -pr */<br />
 ======================================= </p>
<p> find . -follow | cpio -pdumL /path/tobe/copied/to </p>
<p> /* Copy with symbolic links to be followed */<br />
 ======================================= </p>
<p> get filename.suffix |"tar xf -" </p>
<p> /* Undocumented Feature of FTP */<br />
 ======================================= </p>
<p> Move any file(s) without actually touching them </p>
<p> /* ssh cd /some/directory \&#038;\&#038; tar cf - | ssh cd /some/direstory \&#038;\&#038; tar xvf - */<br />
 ======================================= </p>
<p> put "| tar cf - ." filename.tar </p>
<p> /* Undocumented Feature of FTP */<br />
 ======================================= </p>
<p> sendport </p>
<p> /* FTP command for transferring large numbers of files within the same control<br />
    session */<br />
 ======================================= </p>
<p> General </p>
<p> /bin/printf '%d\n' '0x<hex>&#8216; </p>
<p> /* Converts hexadecimal number to decimal. */<br />
 ======================================= </p>
<p> /usr/bin/catman -w </p>
<p> /* Create windex databases for man page directories */<br />
 ======================================= </p>
<p> echo &#8216;obase=16;255&#8242; | bc </p>
<p> /* Simple way to convert decimal to hex */<br />
 ======================================= </p>
<p> FQ_FILENAME=<fully_qualified_file_name>; echo ${FQ_FILENAME%/*} </p>
<p> /* Extract directory from fully-qualified file name. */<br />
 ======================================= </p>
<p> mailx -H -u <username> </p>
<p> /* List out mail headers for specified user */<br />
 ======================================= </p>
<p> ps -ef | grep -i $@ </p>
<p> /* Access common commands quicker */<br />
 ======================================= </p>
<p> set filec </p>
<p> /* Set file-completion for csh */<br />
 ======================================= </p>
<p> uuencode [filename] [filename] | mailx -s &#8220;Subject&#8221; [user to mail] </p>
<p> /* Send files as attachments */<br />
 ======================================= </p>
<p> xauth -f /home/${LOGNAME} extract &#8211; ${DISPLAY} | xauth merge &#8211; </p>
<p> /* Allow root to xdisplay after su */<br />
 ======================================= </p>
<p> ======================================<br />
 VIRTUALIZATION //////////////////////<br />
 ====================================== </p>
<p> ======================================<br />
 Solaris Zones:<br />
 ====================================== </p>
<p> 3.3 Sample Zone Configuration and Bring-Up </p>
<p> Here is a quick sample zone configuration where the zone name is my-zone and the IPv4<br />
 address is 10.0.0.1: </p>
<p> global# zonecfg -z my-zone<br />
 zonecfg:my-zone> create<br />
 /* default is sparse root model, See section 3.4 for details*/<br />
 zonecfg:my-zone> set zonepath=/export/home/my-zone<br />
 zonecfg:my-zone> add net<br />
 zonecfg:my-zone:net> set address=10.0.0.1<br />
 zonecfg:my-zone:net> set physical=eri0<br />
 zonecfg:my-zone:net> end<br />
 zonecfg:my-zone> verify<br />
 zonecfg:my-zone> commit<br />
 zonecfg:my-zone> ^D </p>
<p> At this point, a zone configuration file, /etc/zones/my-zone.xml, has been created<br />
 containing the above parameters and several inherited-pkg-dir fields for<br />
 loopback-mounted file systems. Once a zone configuration file is established, the<br />
 global zone administrator uses zoneadm(1M) to install the zone configuration: </p>
<p> global# zoneadm -z my-zone install </p>
<p> At the completion of the zoneadm(1M) install command, a boot environment is created<br />
 with the live_upgrade(5) facilities. Zone boot is similar to booting a regular<br />
 Solaris environment, except that zoneadm(1M) is used to create the zone runtime: </p>
<p> global# zoneadm -z my-zone boot </p>
<p> This boots the zone. The appropriate file systems are mounted inside the zone,<br />
 zoneadmd(1M) is started, and so on. When a zone is booted for the first time after<br />
 installation, it has no internal configuration for naming schemes, no locale or<br />
 time zone, no root password, and so on. It is necessary to access the zone&#8217;s<br />
 console to answer the prompts and set these up. This should be done using the<br />
 zlogin(1M) command: </p>
<p> # zlogin -C my-zone </p>
<p> [connected to zone my-zone console] </p>
<p> 3.4 Zone Root File System </p>
<p> Two ways exist to configure a non-global zone&#8217;s root file system: whole-root model<br />
 and sparse-root model. </p>
<p> The whole-root model provides the maximum configurability by installing all of the<br />
 required and any selected optional Solaris software packages into the private file<br />
 systems of the zone. The advantages of this model include the ability for zone<br />
 administrators to customize their zone&#8217;s file-system layout (for example, creating<br />
 a /usr/local) and add arbitrary unbundled or third-party packages. The<br />
 disadvantages of this model include the loss of sharing of text segments from<br />
 executables and shared libraries by the virtual memory system, and a much heavier<br />
 disk footprint &#8212; approximately an additional 2 Gbyte &#8212; for each non-global zone<br />
 configured as such. The global zone administrator uses the sub-command create -b of<br />
 zonecfg(1M) to create a zone with the whole root mode (or alternatively to remove<br />
 the inherited-pkg-dir directories in my-zone.xml). </p>
<p> The sparse-root model optimizes the sharing of objects by installing only a subset of<br />
 the root packages (those with the pkginfo(4) parameter SUNW_PKGTYPE set to root)<br />
 and using read-only loopback file systems to gain access to other files. This is<br />
 similar to the way a diskless client is configured, where /usr and other file<br />
 systems are mounted over the network with NFS. By default with this model, the<br />
 directories /lib, /platform, /sbin and /usr are mounted as loopback file systems.<br />
 The advantages of this model are greater performance due to the efficient sharing<br />
 of executables and shared libraries, and a much smaller disk footprint for the zone<br />
 itself. The sparse-root model only requires approximately 100 Mbyte of file system<br />
 space for the zone itself.</p>
<p>======================================<br />
   NAME SERVICES/////////////////////<br />
======================================<br />
======================================<br />
   DNS:<br />
======================================<br />
======================================<br />
   DNS Setup and Configuration:<br />
====================================== </p>
<p>Domain name services resolves host names to the IP addresses of clients and vice<br />
versa. The domain name system provides a convenient way of finding computer systems<br />
on the network based on their name and IP address. With increased internet usage<br />
and globalization of companies setting up of dns servers has become a major<br />
responsibility of system administarators worldwide. </p>
<p>The following article describes in simple steps how to setup a dns server. Though the<br />
article focuses on Solaris, any operating system which uses BIND can use the same<br />
procedures. </p>
<p>1.0 Introduction to DNS<br />
2.0 Requirements for setting up dns server<br />
3.0 DNS server Installation<br />
4.0 named.conf file in DNS server configuration<br />
4.1 options statement in DNS server configuration<br />
4.2 Zone in DNS server configuration<br />
4.3 Logging in DNS server<br />
5.0 Zone File in DNS server<br />
6.0 DNS Client configuration<br />
7.0 Signals in DNS server process &#8211; named<br />
8.0 Next steps </p>
<p>1.0 Introduction </p>
<p>A domain name system is a hierarchical system where there is a top level domain<br />
serving sub domains and clients with names &#038; IP address. </p>
<p>The system that runs the name services to resolves names into IP addresses is called<br />
name server and the sofware is generally BIND (Berkley Internet Domain). </p>
<p>The core process of DNS is a daemon called named. Depending on the role assigned, the<br />
name servers can be a primary, secondry, or caching only. The secondry server takes<br />
over when the primary is down and is updated automatically. The caching server<br />
provides only the caching information to the clients. </p>
<p>Each domain or sub domain has information (in zone files or data files) about its<br />
clients and is called authorative for these clients. The other clients for which it<br />
doesn&#8217;t have any information or it is not authorative, it passes query to its<br />
higher domain. </p>
<p>The client knows about their name servers through a file called resolve.conf which<br />
contains addresses of the name servers (Primary, secondary, and Caching) along with<br />
their domain name. </p>
<p>The main file of the server is named.conf which contains server parameters and<br />
reference to other data files containing client information. </p>
<p>2.0 Requirements: </p>
<p>1) BIND (Berkely Internet Domain) software. Source code can be downloaded and<br />
compiled for your platform from internet at www.isc.org However BIND may be<br />
available in a precompiled version along with your OS, so check your OS if it is<br />
already there. The situation where you may want to compile from source code is that<br />
you want to cutomize it differently by giving different configuration options at<br />
compiling time. </p>
<p>2) Root cache file from internic at ftp://internic.com/pub/root </p>
<p>3) C Compiler to compile the bind source distribution. </p>
<p>3.0 Installation and configuration </p>
<p>Download the BIND software from from www.isc.org if you want to build it from source<br />
code.<br />
Make a directory to store and compile DNS distribution source say /usr/dns/src<br />
Unzip the distribution using gzip command </p>
<p># tar -zxvf bind-9.2.5.tar.gz </p>
<p>Compilation requires a C compiler, if you don&#8217;t have one you can download from gnu<br />
site (www.gnu.org). </p>
<p># ./configure </p>
<p># make </p>
<p># make install </p>
<p>&#8220;make install&#8221; will ultimately place named, configuration file named.conf, and<br />
related commands in /etc and /usr/local/bin directory. </p>
<p>4.0 named.conf file<br />
This is the main configuration file in BIND which defines the name servers and zones<br />
with the name and ip address of the hosts. </p>
<p>The named.conf has a number of options for starting the name server which can be<br />
configured as per requirement. A list of complete options can be seen using &#8216;man<br />
named&#8217; command. </p>
<p>By default you will find zone files for local host by the name localhost and<br />
127.0.0.in-addr.arpa. For additional zones you need to create the the files and put<br />
a reference in named.conf. </p>
<p>Below is a basic functional named.conf file which is installed after BIND 8.2.P5 is<br />
installed. This can be used for starting name server, all you need to do is to put<br />
your hosts entries in the zone files referenced here. You will find explanation of<br />
terms used in this configuration file after this listing of named.conf. </p>
<p>// This is a configuration file for named (from BIND 8.1 or later).<br />
// It would normally be installed as /etc/named.conf. </p>
<p>options { directory &#8220;/var/named&#8221;;<br />
check-names master warn; /* default. */<br />
datasize 20M;<br />
deallocate-on-exit yes;<br />
listen-on {10.20.30.100;<br />
};<br />
forward first;<br />
};<br />
zone &#8220;localhost&#8221; IN {<br />
type master;<br />
file &#8220;/var/named/localhost.zone&#8221;;<br />
check-names fail;<br />
allow-update { none; };<br />
allow-transfer { any; };<br />
};<br />
zone &#8220;0.0.127.in-addr.arpa&#8221; IN {<br />
type master;<br />
file &#8220;/var/named/127.0.0.zone&#8221;;<br />
check-names fail;<br />
allow-update { none; };<br />
allow-transfer { any; };<br />
};<br />
zone &#8220;.&#8221; IN {<br />
type hint;<br />
file &#8220;/var/named/root.hint&#8221;;<br />
};<br />
logging {<br />
channel xfer-log {<br />
file &#8220;/var/tmp/bind-xfer.log&#8221; versions unlimited size 10m;<br />
print-category yes;<br />
print-severity yes;<br />
print-time yes;<br />
severity info;<br />
};<br />
category xfer-in { xfer-log; };<br />
category xfer-out { xfer-log; };<br />
category notify { xfer-log; } </p>
<p>category load { xfer-log; };<br />
};<br />
zone &#8220;30.20.10.in-addr.arpa&#8221; IN {<br />
type master;<br />
file &#8220;/var/named/100.30.20.10.zone&#8221;;<br />
check-names fail;<br />
allow-update { none; };<br />
allow-transfer { any; };<br />
};<br />
zone &#8220;mydomain.com&#8221; {<br />
type master;<br />
file &#8220;/var/named/mydomain.com.hosts&#8221;;<br />
}; </p>
<p>Explanation of the terms used in named.conf above</p>
<p>4.1 Options statement<br />
The options statement lists working directory for named (the name server daemon) to<br />
read the configurations files and port to listen on (default is port 53). </p>
<p>{ directory &#8220;/var/named&#8221;; </p>
<p>This directive defines the working dir of the name server where main configuration<br />
file named.conf will be located </p>
<p>check-names master warn; /* default. */ </p>
<p>The &#8220;check-names&#8221; directive tells BIND to check names in master zone and gives a<br />
warning in the system&#8217;s log files if there is any discrepancy. Names are considered<br />
good if they match RFC 952&#8242;s expectations (if they are host names), or if they<br />
consist only of printable ASCII characters (if they are not host names). </p>
<p>Other options are fail and ignore in that case bind will follow these directives </p>
<p>datasize 20M; </p>
<p>Datasize is the maximum amount of data memory the server may use. The default is<br />
system dependent. </p>
<p>deallocate-on-exit yes; </p>
<p>Deallocate the memory on exit, otherwise it will be left to the OS to clear the<br />
memory. </p>
<p>listen-on {10.20.30.100}; </p>
<p>Host address and port for listening; if port is not mentioned it is default 53. </p>
<p>forward first </p>
<p>Forwarding<br />
Forwarding can be used for two main scenarios:<br />
1. Creating a large site wide cache on different servers thereby using less network<br />
bandwidth. </p>
<p>2. For servers which do not have a direct access to the internet but have to lookup<br />
for the external names. </p>
<p>Forwarding occurs only for names for which the server is not authoritative, and it<br />
does not have the answer in its cache. </p>
<p>forward<br />
This option specify where to query the name first &#8211; &#8216;first&#8217; directive will cause<br />
query to send to forwarder first and check itself if it fails. &#8216;Only&#8217; &#8211; directive<br />
will query the forwarders only. </p>
<p>forwarders<br />
Specifies the IP addresses to be used for forwarding. The default is no forwarding .</p>
<p>4.2 Zones statements </p>
<p>zone &#8220;localhost&#8221; IN {<br />
type master;<br />
file &#8220;/var/named/localhost.zone&#8221;;<br />
check-names fail;<br />
allow-update { none; };<br />
allow-transfer { any; };<br />
}; </p>
<p>Zone statement declares a zone name, its type &#8211; master, slave, or stub files<br />
containing the zone data, and options relating to zone &#8211; update, checking, transfer<br />
etc. </p>
<p>localhost and 0.0.127.in-addr.arpa are default for the localhost and points to file<br />
of this name </p>
<p>Zone types </p>
<p>There are three types of zones. </p>
<p>master: This is the master copy of the data in a zone. </p>
<p>slave: This is a replica of a master zone. The masters list specifies one or more IP<br />
addresses that the slave contacts to update its copy of the zone. If file is<br />
specified, then the replica will be written to the file. Use of file is<br />
recommended, since it often speeds server startup and eliminates a needless waste<br />
of bandwidth. </p>
<p>stub: A stub zone is like a slave zone, except that it replicates only the NS records<br />
of a master zone instead of the entire zone. </p>
<p>hint: The initial set of root name servers is specified using a hint zone. When the<br />
server starts up, it uses the root hints to find a root name server and get the<br />
most recent list of root name servers. </p>
<p>The previous releases of BIND used the term primary for a master zone, secondary for<br />
a slave zone, and cache for a hint zone. </p>
<p>Zone Directives </p>
<p>allow-update<br />
Specifies which hosts are allowed to submit dynamic DNS updates to the server. The<br />
default is to deny updates from all hosts. </p>
<p>allow-transfer<br />
Specifies which hosts are allowed to receive zone transfers from the server.<br />
allow-transfer may also be specified in the zone section, in which case it<br />
overrides the options allow-transfer statement. If not specified, the default is to<br />
allow transfers from all hosts. </p>
<p>Zone &#8220;.&#8221; refers to the root file for the domains &#8211; and contains references to the<br />
root servers at network solutions to resolve the names which are beyond the current<br />
domain. You can download the root cache file from ftp://internic.com/pub/root</p>
<p>4.3 Logging statement </p>
<p>logging {<br />
channel xfer-log {<br />
file &#8220;/var/tmp/bind-xfer.log&#8221; versions unlimited size 10m;<br />
print-category yes;<br />
print-severity yes;<br />
print-time yes;<br />
severity info;<br />
}; </p>
<p>The logging statement specifies logging channel/s which logs various categories of<br />
messages. In the statement above a channel xfer-log &#8211; a user defined name is<br />
defined. Each time name server is started it starts writing to the defined log<br />
file. Size limits the maximum size of the log file and once the limit is reached it<br />
stops writing the file. Each individual start or restart of named causes a new<br />
version of the log file to be created. Version statement defines how many versions<br />
are allowed for the log file. The unlimited option will allow any number of<br />
versions. </p>
<p>Only one logging statement is used to define how many channels and categories are<br />
wanted. If there are multiple logging statements in a configuration, the first<br />
definition determines the logging and warnings are issued for the other logging<br />
statements. </p>
<p>If there is no logging statement, the default logging configuration is used which<br />
is: </p>
<p>logging {<br />
category default { default syslog; default_debug;};<br />
category panic { default syslog; default_stderr;};<br />
category packet { default_debug;};<br />
category eventlib { default_debug;};<br />
}; </p>
<p>The default debug file is named.run . </p>
<p>Channel Phrase </p>
<p>All log output goes to one or more &#8220;channels&#8221;; you can make as many of them as you<br />
want. Every channel definition must include a clause that says whether messages<br />
selected for the channel go to a file, to a particular syslog facility, or are<br />
discarded. It can optionally also limit the message severity level that will be<br />
accepted by the channel (default is &#8220;info&#8221;), and whether to include a<br />
named-generated time stamp, the category name and/or severity level (default is not<br />
to include any). </p>
<p>The word null as the destination option for the channel will cause all messages sent<br />
to it to be discarded; other options for the channel are meaningless. </p>
<p>The file clause defines size and versions of the file which will be saved each time<br />
the file is opened. if the file ever exceeds the size, then named will just not<br />
write anything more to it. The default behavior is to not limit the size of the<br />
file. </p>
<p>As per selection the log messages will either go to syslog() or a file and severity<br />
level determines which type of messages goes there. Default severity level is info.<br />
and it can be critical, error, debug, and dynamic. </p>
<p>Note that only syslog messages can go to syslog. </p>
<p>Print-time, print-category &#8211; logs the time &#038; category of the messages . The print-<br />
options can be used in any combination but will always be printed in the following<br />
order: time, category, severity. </p>
<p>category xfer-in { xfer-log; };<br />
category xfer-out { xfer-log; };<br />
category notify { xfer-log; } </p>
<p>These directives put diffrent categories of log messages in to xfer-log channel </p>
<p>Category option mentions the category of the log and file name for logging </p>
<p>logging {<br />
channel xfer-log {<br />
file &#8220;/var/tmp/bind-xfer.log&#8221; versions unlimited size 10m;<br />
print-category yes;<br />
print-severity yes;<br />
print-time yes;<br />
severity info;<br />
}; </p>
<p>this defines a channel called xfer-log with various options. </p>
<p>these categories directs various types of logs into the channel</p>
<p>5.0 ZONE files </p>
<p>Zone files are used to define the name and ip addresses of the hosts in a domain.<br />
Generally two zone files are defined for a particular zone &#8211; one file maps the the<br />
name to the IP address of the host machines and the other is used for reverse<br />
lookup i.e.., IP address to name address. </p>
<p>Each master zone file should begin with an SOA (Start of Authority) record for the<br />
zone. The SOA specifies a serial number, which should be changed each time the<br />
master file is changed. The serial number has a 32 bit size field. Slave servers<br />
check the serial number at refresh time and if they detect a changed serial number<br />
in the master, then the zone transfer is carried out to keep its zone files<br />
updated. </p>
<p>If a master server cannot be contacted within the interval given by the expire time,<br />
all data from the zone is discarded by slave servers. The minimum value is the<br />
time-to-live (&#8220;TTL&#8221;) used by records in the file with no explicit time-to-live<br />
value. </p>
<p>The details of all type of records used in a zone file are given below: </p>
<p>Type of records:<br />
SOA marks the start of a zone of authority (domain of originating host, domain<br />
address of maintainer, a serial number and the following parameters in seconds:<br />
refresh, retry, expire and minimum TTL. (see RFC 883). </p>
<p>NULL a null resource record (no format or data) </p>
<p>RP a Responsible Person for some domain name </p>
<p>PTR a domain name pointer (domain) </p>
<p>HINFO host information (cpu_type OS_type) </p>
<p>A a host address (dotted quad) </p>
<p>NS an authoritative name server (domain) </p>
<p>MX a mail exchanger (domain), preceded by a preference value (0..32767), with lower<br />
numeric values representing higher logical preferences. </p>
<p>CNAME the canonical name for an alias (domain). </p>
<p>Following are the three functional zone files representing local host and a master<br />
zone. </p>
<p>The explanation of the terms are at the end. </p>
<p>/var/named/localhost </p>
<p>localhost. 1D IN SOA localhost.mydomainr.com. hostmaster.mydomain.com. (<br />
42 ; serial<br />
3H ; refresh<br />
15M ; retry<br />
1W ; expiry<br />
1D ) ; minimum<br />
localhost. NS dns<br />
localhost. A 127.0.0.1 </p>
<p>/var/named/ 0.0.127.in-addr.arpa </p>
<p>0.0.127.in-addr.arpa IN SOA localhost. root.localhost. (<br />
42 ; serial<br />
3H ; refresh<br />
15M ; retry<br />
1W ; expiry<br />
1D ) ; minimum </p>
<p>0.0.127.in-addr.arpa IN NS dns.mydomain.com<br />
1.0.0.127.in-addr.arpa. PTR localhost </p>
<p>/var/named/mydomain.com </p>
<p>mydomain.com. IN SOA dns.mydomain.com hostmaster.dns. (<br />
200010016 ;serial<br />
10800<br />
3600<br />
3600<br />
86400 )<br />
mydomain.com. 1D IN NS dns.mydomain.com.<br />
IN MX 20 mx1.domaingateway.net.<br />
IN MX 10 mail-in.mydomain.com. </p>
<p>;mydomain hosts below<br />
www IN CNAME mydomain.com.<br />
localhost IN A 127.0.0.1<br />
mail IN A xxx.xxx.xxx.xxx<br />
ns1 IN A xxx.xxx.xxx.xxx<br />
dns IN A xxx.xxx.xxx.xxx<br />
news IN A xxx.xxx.xxx.xxx </p>
<p>root cache file </p>
<p>localhost. NS dns </p>
<p>this is declaration of the type of localhost it declares that local host is a name<br />
server with hostname dns </p>
<p>localhost. A 127.0.0.1 </p>
<p>this declares the address of local host. </p>
<p>0.0.127.in-addr.arpa IN NS dns.mydomain.com<br />
1.0.0.127.in-addr.arpa. PTR localhost </p>
<p>Similarly in reverse zone map file reverse address is declared as ns record of name<br />
dns and a pointer record (ptr), points this reverse address to the localhost. </p>
<p>Resource records normally end at the end of a line, but may be continued across lines<br />
between opening and closing parentheses. Comments are introduced by semicolons and<br />
continue to the end of the line.Note that there are other resource record types,<br />
not shown where. You should consult the BIND Operations Guide (BOG&#8217;) for the<br />
complete list. Some resource record types may have been standardized in newer RFC&#8217;s<br />
but not yet implemented in this version of BIND.</p>
<p>6.0 Client Configuration </p>
<p>Each client need a configuration file /etc/resolv.conf which informs it about the<br />
domain name server. This is a editable text file with following entries: </p>
<p>domainname yourdomainname.com<br />
nameserver 10.20.30.40<br />
nameserver 10.20.30.41 </p>
<p>7.0 Signals </p>
<p>The following signals have the specified effect when sent to the server process named<br />
using the kill command. </p>
<p>SIGHUP:<br />
Causes server to read named.boot and reload the database. If the server is built with<br />
the FORCED_RELOAD compile-time option, then SIGHUP will also cause the server to<br />
check the serial number on all secondary zones. Normally the serial numbers are<br />
only checked at the SOA-specified intervals. </p>
<p>SIGINT:<br />
Dumps the current data base and cache to /var/named/named_dump.db </p>
<p>SIGIOT:<br />
Dumps statistics data into /var/named/named.stats. If the server is compiled with<br />
-DSTATS. Statistics data is appended to the file. Some systems use SIGABRT rather<br />
than SIGIOT for this. </p>
<p>SIGSYS:<br />
Dumps the profiling data in /var/named if the server is compiled with profiling<br />
(server forks, chdirs and exits). </p>
<p>SIGTERM:<br />
Dumps the primary and secondary database files. Used to save modified data on<br />
shutdown if the server is compiled with dynamic updating enabled. </p>
<p>SIGUSR1:<br />
Turns on debugging; each SIGUSR1 increments debug level. (SIGEMT on older systems<br />
without SIGUSR1) </p>
<p>SIGUSR2:<br />
Turns off debugging completely. (SIGFPE on older systems without SIGUSR2) </p>
<p>SIGWINCH:<br />
Toggles logging of all incoming queries via sys-log(8) (requires server to have been<br />
built with the QRYLOG option)</p>
<p>======================================<br />
   Zone File:<br />
====================================== </p>
<p>If you make updates to a zone file but leave the serial number unchanged, what<br />
happens?~ </p>
<p>Serial number: Now this value has special purpose. For optimal speed and efficiency,<br />
BIND (one of the most widely used DNS servers, designed for Unix-based operating<br />
systems) processes zone files into a different format. What happens is, when BIND<br />
loads a zone file at startup, it first looks up at its serial number and proceeds<br />
with processing the zone file only if its serial number is bigger than the last<br />
processed version. Thus, if you make modifications to a zone file, but leave<br />
unchanged its serial number, BIND will ignore your updated version.<br />
The typical format of a serial number comprises date and unique serial number<br />
(YYYYMMDDNN), such as: 2009010801 &#8211; for the second edition (01) of the file on<br />
January 8, 2009. This format allows 100 modifications to be made to the zone file<br />
per day.</p>
<p>======================================<br />
   NIS:<br />
======================================<br />
======================================<br />
   autofs / automounter / files / NIS Solaris:<br />
====================================== </p>
<p>3.1: How to Set Up a SunOS Automount Client Using Files </p>
<p>Under SunOS, the automounter is centered around the file<br />
/etc/auto.master. This file must contain a number of lines in the<br />
following format: </p>
<p>directory mapname options </p>
<p>Where: directory is the directory to mount an indirect map in, or /-<br />
for a direct map mapname is the file which contains the map and<br />
options are any standard NFS options which should be used for the<br />
entire map. An example of an auto.master file follows: </p>
<p>% cat /etc/auto.master<br />
/- /etc/auto.direct -ro<br />
/home /etc/auto.home </p>
<p>In this example, /etc/auto.direct will be a direct map, which mounts a<br />
number of filesystems readonly, while /etc/auto.home will be a<br />
indirect map, which mounts filesystems under the /home directory. </p>
<p>A typical map contains a number of lines as follows: </p>
<p>mountpoint [options] remotemachine:/remotelocation </p>
<p>The [options] can be omitted if only the standard options should be<br />
used. montpoint will be a full path for a direct mount (/usr/local) or<br />
just a directory name for an indirect mount (joe). </p>
<p>For example, the auto.direct map may read: </p>
<p>% cat /etc/auto.direct<br />
/usr/man -soft server:/usr/man<br />
/usr/local server:/export/sunos/usr/local </p>
<p>This would create automount points for /usr/man and /usr/local, and<br />
/usr/man would be mounted soft. </p>
<p>While the auto.home map (or any indirect map) would look something<br />
like this: </p>
<p>% cat /etc/auto.home<br />
joe server:/export/home/joe<br />
fred server:/export/home/fred </p>
<p>This would create automount points for /home/joe and /home/fred. </p>
<p>Please note that automount will use an auto.master NIS map by default.<br />
Thus, to force automounter to use local files, you must start is as<br />
follows: </p>
<p># automount -f /etc/auto.master &#038; </p>
<p>You will also want to modify the automount startup in /etc/rc.local. </p>
<p>3.2: How to Set Up a SunOS Automount Client Using NIS </p>
<p>To force your automounter to read in NIS maps, you must change the way<br />
that the mapname is referenced in your auto.master file. If the<br />
mapname is listed without any &#8220;/&#8221;s, NIS maps will be automatically<br />
checked. The following auto.master file says to get the direct listing<br />
from the auto.direct NIS map, and the /home listing from the auto.home<br />
NIS map: </p>
<p># cat /etc/auto.master<br />
/- auto.direct -ro<br />
/home auto.home </p>
<p>(Compare this to Section 3.1, where the mapname column of the<br />
/etc/auto.master map contains &#8220;/&#8221;s, directing the automounter to a<br />
local path.) </p>
<p>In order to get a SunOS client to start automount, using the NIS maps,<br />
all you need to do is either create an auto.master map in NIS, and<br />
distribute it (See Section 3.5), or create a local map, as noted<br />
above. Other maps should be created on the NIS master, with the same<br />
format as is described in Section 3.1 (see Section 3.5 for how to<br />
modify those NIS maps). </p>
<p>Afterwards, simply reboot the machine, or start up automount: </p>
<p># automount &#038; </p>
<p>[As a note, you may also read in NIS maps by putting a +mapname entry,<br />
ie +auto.home, in a local file this is usually done to set up a<br />
unique automounter on a certain machine. The references in Section 7.0<br />
should be used if you wish to implement a more complex set up, such as<br />
this.] </p>
<p>3.3: How to Set Up a Solaris Automount Client Using Files </p>
<p>Follow the instructions in Section 3.1, but be aware that under<br />
Solaris, the names of the files are expected to contain &#8220;_&#8221;s instead<br />
of &#8220;.&#8221;s. ie: </p>
<p>/etc/auto_master<br />
/etc/auto_direct<br />
/etc/auto_home </p>
<p>So, using only files, your auto_master should look something like<br />
this: </p>
<p># cat /etc/auto_master<br />
/- /etc/auto_direct -ro<br />
/home /etc/auto_home </p>
<p>The other files would follow with the same format as described in<br />
Section 3.1. </p>
<p>When everything is set up, you can get automount starting by rebooting<br />
the machine, or running: </p>
<p># /etc/init.d/autofs start </p>
<p>3.4: How to Set Up a Solaris Automount Client Using Other Naming Services </p>
<p>If the /etc/auto_master file contains mapnames without &#8220;/&#8221;s,<br />
additional naming services are consulted, according to the order<br />
listed in the nsswitch.conf. For example, the following<br />
/etc/nsswitch.conf line would say to check first files, then NIS: </p>
<p>automount: files nis </p>
<p>In addition, the local files may say to read other naming services, by<br />
listing the entry &#8220;+mapname&#8221;. </p>
<p>Following is an extremely typical automount setup for Solaris: </p>
<p># cat /etc/auto_master<br />
+auto_master<br />
/net -hosts -nosuid<br />
/home auto_home </p>
<p>[The +auto_master line says to first check naming services (NIS/NIS+)<br />
for an auto_master map. Afterwards, it includes a special net map,<br />
which is described in the man page, and also a /home indirect map,<br />
which is read from the naming services.] </p>
<p># cat /etc/auto_home<br />
+auto_home </p>
<p>[This file says to just go out to naming services. It is necessary<br />
because "files" is one of the options listed in the nsswitch.conf.] </p>
<p># ypcat auto_master<br />
[any additional auto_master entries are listed here]<br />
# ypcat auto_home<br />
&#8230;<br />
[the full auto_home map is here] </p>
<p>[Thus you will need to setup all of your normal maps in NIS or NIS+,<br />
as is described in Sections 3.5 and 3.6.] </p>
<p>Of special note here is this: If NIS is listed as the naming service,<br />
and automountd can&#8217;t find an auto_map, then it will try instead to<br />
lookup auto.map, since that is the older NIS standard. So, the above<br />
would work fine if you were using NIS, and the actual NIS map was<br />
auto.home. </p>
<p>When everything is set up, you can get automount started by rebooting<br />
the machine, or running: </p>
<p># /etc/init.d/autofs start</p>
<p>3.5: How to Modify Automount Maps Under NIS </p>
<p>The auto.master and auto.home maps are automatically part of NIS. To<br />
distribute these maps, simply edit the files /etc/auto.master and<br />
/etc/auto.home on the master, using the format described in Section<br />
3.1, and then make the maps to distribute them: </p>
<p># cd /var/yp<br />
# make </p>
<p>Section 3.7 describes how to create new NIS maps.</p>
<p>3.6: How to Modify Automount Maps Under NIS+ </p>
<p>The auto_master and auto_home tables are automatically part of NIS+.<br />
They may be modified, using the format described in Section 3.1. The<br />
auto_home table may be modified via admintool, nistbladm or nisaddent<br />
(admintool is suggested). The auto_master table may be modified via<br />
nistbladm or nisaddent. nisaddent is probably the best options for<br />
making this modification. </p>
<p>To make a modification with nisaddent, you should first dump your map<br />
to a text file: </p>
<p># /usr/lib/nis/nisaddent -d -t auto_master.org_dir key-value ><br />
/etc/auto_master.nisplus </p>
<p>Then, you can edit the file with your favorite editor. Remember to use only<br />
tabs between the fields, not embedded spaces: </p>
<p># cat /etc/auto_master.nisplus<br />
+auto_master<br />
/net -hosts -nosuid<br />
/home auto_home </p>
<p>Afterwards, run nisaddent again to replace the NIS+ map with your text file: </p>
<p># /usr/lib/nis/nisaddent -r -f /etc/auto_master.nis -t auto_master.org_dir<br />
key-value </p>
<p>Section 3.8 describes how to create new NIS+ maps. </p>
<p>3.7: How to Create New NIS Automount Maps </p>
<p>Automount Maps </p>
<p>The following example explains how to create an auto_direct map under<br />
NIS. Other new maps can be created with similar syntax. </p>
<p>In order to create an auto.direct map, you need to make a new entry in<br />
/var/yp/Makefile for auto.direct, mimicking the already existing<br />
auto.home entry: </p>
<p>auto.direct.time: $(DIR)/auto.direct<br />
-@if [ -f $(DIR)/auto.direct ] then \<br />
sed -e &#8220;/^#/d&#8221; -e s/#.*$$// $(DIR)/auto.direct \<br />
$(MAKEDBM) &#8211; $(YPDBDIR)/$(DOM)/auto.direct \<br />
touch auto.direct.time \<br />
echo &#8220;updated auto.direct&#8221; \<br />
if [ ! $(NOPUSH) ] then \<br />
$(YPPUSH) auto.direct \<br />
echo &#8220;pushed auto.direct&#8221; \<br />
else \<br />
: \<br />
fi \<br />
else \<br />
echo &#8220;couldn&#8217;t find $(DIR)/auto.direct&#8221; \<br />
fi </p>
<p>NOTE: all INDENTED $lines in the Makefile entry MUST be indented<br />
with the TAB key, without any imbedded spaces!! </p>
<p>In addition, auto.direct must be added to the all: line, near the top<br />
of the Makefile: </p>
<p>all: passwd group hosts ethers networks rpc services protocols \<br />
netgroup bootparams aliases publickey netid netmasks c2secure \<br />
timezone auto.master auto.home auto.direct </p>
<p>And, finally, near the bottom, the following line must be added: </p>
<p>auto.direct: auto.direct.time </p>
<p>[Be very careful if you just copy the above lines -- Makefile entries<br />
MUST begin with TABS, not spaces if you text copy the above, you will<br />
end up with spaces at the beginning of each line, and make will fail.] </p>
<p>When this is all done, you may create an /etc/auto.direct map, put the<br />
appropriate files in it, and then do a Make: </p>
<p># cd /var/yp<br />
# make </p>
<p>After you have done the first make, you will probably gets some errors<br />
like the following: </p>
<p>&#8220;can&#8217;t bind master to send ypclear message to ypserv for map &#8230;&#8221; </p>
<p>This occurs because NIS is confused due to the maps not existing on<br />
the slave machines. To resolve this, you must manually copy the map to<br />
the slaves. This can be done by copying /var/yp/`domainname`/auto.direct.*<br />
from the master to /var/yp/`domainname` on each of the slaves, using<br />
either rcp or ftp. </p>
<p>Afterwards, do a second make: </p>
<p># cd /var/yp<br />
# make </p>
<p>3.8: How to Create New NIS+ Automount Maps </p>
<p>The following example explains how to create an auto_direct map under<br />
NIS+. Other new maps can be created with similar syntax. </p>
<p>STEP ONE: create a new auto_direct table, on the master server: </p>
<p># nistbladm -c automount_map key=S value=S auto_local.org_dir.`domainname`. </p>
<p>STEP TWO: set the group ownership of the table: </p>
<p># nischgrp admin.`domainname`. auto_local.org_dir </p>
<p>STEP THREE: set the correct permissions. </p>
<p># nischmod n=r, o=rmcd,g=rmcd, w=r auto_local.org_dir </p>
<p>STEP FOUR: create a text file, and read it into NIS+, just as is<br />
described in section 3.6: </p>
<p># cat /etc/auto_local.nisplus<br />
/usr/local/bin server:/usr/local/bin<br />
/usr/local/lib server2:/usr/local/lib<br />
# /usr/lib/nis/nisaddent -r -f /etc/auto_local.nisplus \<br />
-t auto_local.org_dir key-value </p>
<p>STEP FIVE: verify the data is in the map:<br />
# niscat -m auto_local.org_dir </p>
<p>(your data should display) </p>
<p>NOTE: You will also want to add an entry to your NIS+ auto_master map, as is<br />
described in 3.6.</p>
<p>======================================<br />
   Configure NIS Linux:<br />
====================================== </p>
<p>You need to add the NIS domain you wish to use in the /etc/sysconfig/network file.<br />
For the school, call the domain NIS-SCHOOL-NETWORK. </p>
<p>#/etc/sysconfig/network<br />
NISDOMAIN=&#8221;NIS-SCHOOL-NETWORK&#8221; </p>
<p>NIS servers also have to be NIS clients themselves, so you&#8217;ll have to edit the NIS<br />
client configuration file /etc/yp.conf to list the domain&#8217;s NIS server as being the<br />
server itself or localhost. </p>
<p># /etc/yp.conf &#8211; ypbind configuration file<br />
ypserver 127.0.0.1 </p>
<p>Start the necessary NIS daemons in the /etc/init.d directory and use the chkconfig<br />
command to ensure they start after the next reboot. </p>
<p>[root@bigboy tmp]# service portmap start<br />
Starting portmapper: [ OK ]<br />
[root@bigboy tmp]# service yppasswdd start<br />
Starting YP passwd service: [ OK ]<br />
[root@bigboy tmp]# service ypserv start<br />
Setting NIS domain name NIS-SCHOOL-NETWORK: [ OK ]<br />
Starting YP server services: [ OK ]<br />
[root@bigboy tmp]# </p>
<p>[root@bigboy tmp]# chkconfig portmap on<br />
[root@bigboy tmp]# chkconfig yppasswdd on<br />
[root@bigboy tmp]# chkconfig ypserv on </p>
<p>Table 30-1 Required NIS Server Daemons<br />
Daemon<br />
portmap The foundation RPC daemon upon which NIS runs.<br />
yppasswdd Lets users change their passwords on the NIS server from NIS clients<br />
ypserv Main NIS server daemon<br />
ypbind Main NIS client daemon<br />
ypxfrd Used to speed up the transfer of very large NIS maps </p>
<p>Make sure they are all running before continuing to the next step. You can use the<br />
rpcinfo command to do this. </p>
<p>[root@bigboy tmp]# rpcinfo -p localhost<br />
program vers proto port<br />
100000 2 tcp 111 portmapper<br />
100000 2 udp 111 portmapper<br />
100009 1 udp 681 yppasswdd<br />
100004 2 udp 698 ypserv<br />
100004 1 udp 698 ypserv<br />
100004 2 tcp 701 ypserv<br />
100004 1 tcp 701 ypserv<br />
[root@bigboy tmp]# </p>
<p>Now that you have decided on the name of the NIS domain, you&#8217;ll have to use the<br />
ypinit command to create the associated authentication files for the domain. You<br />
will be prompted for the name of the NIS server, which in this case is bigboy. </p>
<p>With this procedure, all nonprivileged accounts are automatically accessible via<br />
NIS. </p>
<p>[root@bigboy tmp]# /usr/lib/yp/ypinit -m<br />
At this point, we have to construct a list of the hosts which will run NIS<br />
servers. bigboy is in the list of NIS server hosts. Please continue to add<br />
the names for the other hosts, one per line. When you are done with the<br />
list, type a <control D>.<br />
next host to add: bigboy<br />
next host to add:<br />
The current list of NIS servers looks like this: </p>
<p>bigboy </p>
<p>Is this correct? [y/n: y] y<br />
We need a few minutes to build the databases&#8230;<br />
Building /var/yp/NIS-SCHOOL-NETWORK/ypservers&#8230;<br />
Running /var/yp/Makefile&#8230;<br />
gmake[1]: Entering directory `/var/yp/NIS-SCHOOL-NETWORK&#8217;<br />
Updating passwd.byname&#8230;<br />
Updating passwd.byuid&#8230;<br />
Updating group.byname&#8230;<br />
Updating group.bygid&#8230;<br />
Updating hosts.byname&#8230;<br />
Updating hosts.byaddr&#8230;<br />
Updating rpc.byname&#8230;<br />
Updating rpc.bynumber&#8230;<br />
Updating services.byname&#8230;<br />
Updating services.byservicename&#8230;<br />
Updating netid.byname&#8230;<br />
Updating protocols.bynumber&#8230;<br />
Updating protocols.byname&#8230;<br />
Updating mail.aliases&#8230;<br />
gmake[1]: Leaving directory `/var/yp/NIS-SCHOOL-NETWORK&#8217; </p>
<p>bigboy has been set up as a NIS master server. </p>
<p>Now you can run ypinit -s bigboy on all slave server.<br />
[root@bigboy tmp]# </p>
<p>Note: Make sure portmap is running before trying this step or you&#8217;ll get errors, such<br />
as: </p>
<p>failed to send &#8216;clear&#8217; to local ypserv: RPC: Port mapper failureUpdating<br />
group.bygid&#8230; </p>
<p>You will have to delete the /var/yp/NIS-SCHOOL-NETWORK directory and restart portmap,<br />
yppasswd, and ypserv before you&#8217;ll be able to do this again successfully. </p>
<p>You can now start the ypbind and the ypxfrd daemons because the NIS domain files have<br />
been created. </p>
<p>[root@bigboy tmp]# service ypbind start<br />
Binding to the NIS domain: [ OK ]<br />
Listening for an NIS domain server.<br />
[root@bigboy tmp]# service ypxfrd start<br />
Starting YP map server: [ OK ]<br />
[root@bigboy tmp]# chkconfig ypbind on<br />
[root@bigboy tmp]# chkconfig ypxfrd on </p>
<p>All the NIS daemons use RPC port mapping and, therefore, are listed using the rpcinfo<br />
command when they are running correctly. </p>
<p>[root@bigboy tmp]# rpcinfo -p localhost<br />
program vers proto port<br />
100000 2 tcp 111 portmapper<br />
100000 2 udp 111 portmapper<br />
100003 2 udp 2049 nfs<br />
100003 3 udp 2049 nfs<br />
100021 1 udp 1024 nlockmgr<br />
100021 3 udp 1024 nlockmgr<br />
100021 4 udp 1024 nlockmgr<br />
100004 2 udp 784 ypserv<br />
100004 1 udp 784 ypserv<br />
100004 2 tcp 787 ypserv<br />
100004 1 tcp 787 ypserv<br />
100009 1 udp 798 yppasswdd<br />
600100069 1 udp 850 fypxfrd<br />
600100069 1 tcp 852 fypxfrd<br />
100007 2 udp 924 ypbind<br />
100007 1 udp 924 ypbind<br />
100007 2 tcp 927 ypbind<br />
100007 1 tcp 927 ypbind<br />
[root@bigboy tmp]# </p>
<p>New NIS users can be created by logging into the NIS server and creating the new user<br />
account. In this case, you&#8217;ll create a user account called nisuser and give it a<br />
new password. </p>
<p>Once this is complete, you then have to update the NIS domain&#8217;s authentication files<br />
by executing the make command in the /var/yp directory. </p>
<p>This procedure makes all NIS-enabled, nonprivileged accounts become automatically<br />
accessible via NIS, not just newly created ones. It also exports all the user&#8217;s<br />
characteristics stored in the /etc/passwd and /etc/group files, such as the login<br />
shell, the user&#8217;s group, and home directory. </p>
<p>[root@bigboy tmp]# useradd -g users nisuser<br />
[root@bigboy tmp]# passwd nisuser<br />
Changing password for user nisuser.<br />
New password:<br />
Retype new password:<br />
passwd: all authentication tokens updated successfully.<br />
[root@bigboy tmp]# cd /var/yp<br />
[root@bigboy yp]# make<br />
gmake[1]: Entering directory `/var/yp/NIS-SCHOOL-NETWORK&#8217;<br />
Updating passwd.byname&#8230;<br />
Updating passwd.byuid&#8230;<br />
Updating netid.byname&#8230;<br />
gmake[1]: Leaving directory `/var/yp/NIS-SCHOOL-NETWORK&#8217;<br />
[root@bigboy yp]# </p>
<p>You can check to see if the user&#8217;s authentication information has been updated by<br />
using the ypmatch command, which should return the user&#8217;s encrypted password<br />
string. </p>
<p>[root@bigboy yp]# ypmatch nisuser passwd<br />
nisuser:$1$d6E2i79Q$wp3Eo0Qw9nFD/::504:100::/home/nisuser:/bin/bash<br />
[root@bigboy yp] </p>
<p>You can also use the getent command, which has similar syntax. Unlike ypmatch, getent<br />
doesn&#8217;t provide an encrypted password when run on an NIS server, it just provides<br />
the user&#8217;s entry in the /etc/passwd file. On a NIS client, the results are<br />
identical with both showing the encrypted password. </p>
<p>[root@bigboy yp]# getent passwd nisuser<br />
nisuser:x:504:100::/home/nisuser:/bin/bash<br />
[root@bigboy yp]# </p>
<p>Now that the NIS server is configured, it&#8217;s time to configure the NIS clients. There<br />
are a number of related configuration files that you need to edit to get it to<br />
work. Take a look at the procedure. </p>
<p>The authconfig or the authconfig-tui program automatically configures your NIS files<br />
after prompting you for the IP address and domain of the NIS server. </p>
<p>[root@smallfry tmp]# authconfig-tui </p>
<p>Once finished, it should create an /etc/yp.conf file that defines, amongst other<br />
things, the IP address of the NIS server for a particular domain. It also edits the<br />
/etc/sysconfig/network file to define the NIS domain to which the NIS client<br />
belongs. </p>
<p># /etc/yp.conf &#8211; ypbind configuration file<br />
domain NIS-SCHOOL-NETWORK server 192.168.1.100 </p>
<p>#/etc/sysconfig/network<br />
NISDOMAIN=NIS-SCHOOL-NETWORK </p>
<p>In addition, the authconfig program updates the /etc/nsswitch.conf file that lists<br />
the order in which certain data sources should be searched for name lookups, such<br />
as those in DNS, LDAP, and NIS. Here you can see where NIS entries were added for<br />
the important login files. </p>
<p>#/etc/nsswitch.conf<br />
passwd: files nis<br />
shadow: files nis<br />
group: files nis </p>
<p>Note: You can also locate a sample NIS nsswitch.conf file in the<br />
/usr/share/doc/yp-tools* directory. </p>
<p>Start the ypbind NIS client, and portmap daemons in the /etc/init.d directory and use<br />
the chkconfig command to ensure they start after the next reboot. Remember to use<br />
the rpcinfo command to ensure they are running correctly. </p>
<p>[root@smallfry tmp]# service portmap start<br />
Starting portmapper: [ OK ]<br />
[root@smallfry tmp]# service ypbind start<br />
Binding to the NIS domain:<br />
Listening for an NIS domain server.<br />
[root@smallfry tmp]# </p>
<p>[root@smallfry tmp]# chkconfig ypbind on<br />
[root@smallfry tmp]# chkconfig portmap on </p>
<p>Note: Remember to use the rpcinfo -p localhost command to make sure they all started<br />
correctly. </p>
<p>As the configuration examples refer to the NIS client and server by their hostnames,<br />
you&#8217;ll have to make sure the names resolve correctly to IP addresses. This can be<br />
configured either in DNS, when the hosts reside in the same domain, or more simply<br />
by editing the /etc/hosts file on both Linux boxes. </p>
<p>#<br />
# File: /etc/hosts (smallfry)<br />
#<br />
192.168.1.100 bigboy</p>
<p>#<br />
# File: /etc/hosts (bigboy)<br />
#<br />
192.168.1.102 smallfry </p>
<p>You can run the ypcat, ypmatch, and getent commands to make sure communication to the<br />
server is correct. </p>
<p>[root@smallfry tmp]# ypcat passwd<br />
nisuser:$1$Cs2GMe6r$1hohkyG7ALrDLjH1:505:100::/home/nisuser:/bin/bash<br />
quotauser:!!:503:100::/home/quotauser:/bin/bash<br />
ftpinstall:$1$8WjAVtes$SnRh9S1w07sYkFNJwpRKa.:502:100::/:/bin/bash<br />
www:$1$DDCi/OPI$hwiTQ.L0XqYJUk09Bw.pJ/:504:100::/home/www:/bin/bash<br />
smallfry:$1$qHni9dnR$iKDs7gfyt..BS9Lry3DAq.:501:100::/:/bin/bash<br />
[root@smallfry tmp]# </p>
<p>[root@smallfry tmp]# ypmatch nisuser passwd<br />
nisuser:$1$d6E2i79Q$wp3Eo0Qw9nFD/:504:100::/home/nisuser:/bin/bash<br />
[root@smallfry tmp]# </p>
<p>[root@smallfry tmp]# getent passwd nisuser<br />
nisuser:$1$d6E2i79Q$wp3Eo0Qw9nFD/:504:100::/home/nisuser:/bin/bash<br />
[root@smallfry tmp]# </p>
<p>Once your basic NIS functionality testing is complete, try to test a remote login.<br />
Failures in this area could be due to firewalls blocking TELNET or SSH access and<br />
the TELNET and SSH server process not being started on the clients.<br />
Logging In Via Telnet </p>
<p>Try logging into the NIS client via telnet if it is enabled </p>
<p>[root@bigboy tmp]# telnet 192.168.1.201<br />
Trying 192.168.1.201&#8230;<br />
Connected to 192.168.1.201.<br />
Escape character is &#8216;^]&#8217;.<br />
Red Hat Linux release 9 (Shrike)<br />
Kernel 2.4.20-6 on an i686<br />
login: nisuser<br />
Password:<br />
Last login: Sun Nov 16 22:03:51 from 192-168-1-100.simiya.com<br />
[nisuser@smallfry nisuser]$ </p>
<p>Logging In Via SSH </p>
<p>Try logging into the NIS client via SSH. </p>
<p>[root@bigboy tmp]# ssh -l nisuser 192.168.1.102<br />
nisuser@192.168.1.102<br />
[nisuser@smallfry nisuser]$ </p>
<p>In some versions of Linux, the NIS client&#8217;s SSH daemon doesn&#8217;t re-read the<br />
/etc/nsswitch.conf file you just modified until SSH is restarted. SSH logins,<br />
therefore, won&#8217;t query the NIS server until this is done. Restart SSH on the NIS<br />
client. </p>
<p>[root@smallfry root]# service sshd restart<br />
Stopping sshd:[ OK ]<br />
Starting sshd:[ OK ]<br />
[root@smallfry root]#</p>
<p>======================================<br />
   Configure OpenLDAP Solaris:<br />
======================================<br />
======================================<br />
   Setting up the OpenLDAP server:<br />
====================================== </p>
<p>I won&#8217;t go into too much detail here, as this part is fairly straight-forward.<br />
Basically, download and compile OpenLDAP 2.4.x with the options that you like,<br />
optionally create a package, and then install OpenLDAP.<br />
I used the following configure options: </p>
<p>BDBDIR=/usr/local/BerkeleyDB.4.2 ; export BDBDIR<br />
LD_LIBRARY_PATH=${BDBDIR}/lib:/usr/sfw/lib \<br />
CPPFLAGS=&#8221;-I${BDBDIR}/include/ -I/usr/sfw/include&#8221; \<br />
LDFLAGS=&#8221;-L${BDBDIR}/lib -L/usr/sfw/lib&#8221; \<br />
./configure &#8211;with-tls=openssl &#8211;enable-overlays &#8211;enable-crypt \<br />
&#8211;enable-modules &#8211;enable-monitor &#8211;prefix=/opt/openldap \<br />
&#8211;enable-syslog &#8211;enable-proctitle &#8211;without-subdir </p>
<p>make clean &#038;&#038; make depend &#038;&#038; make </p>
<p>After installing OpenLDAP you will probably want to add some schemas. For solaris you<br />
need solaris.schema and I prefer to have my SUDO config in LDAP, so I also include<br />
it&#8217;s schema:</p>
<p>======================================<br />
   solaris.schema file:<br />
====================================== </p>
<p># http://www.int-evry.fr/mci/user/procacci/ldap/solaris.schema<br />
#<br />
# solaris.schema<br />
# &#8221;works in progress and incomplete&#8221;.<br />
# It would help if sun would publish this information!<br />
# If you have any comments/suggestion/correction<br />
# please let me know (  igor@ipass.net<br />
#<br />
# Some correction on oid and attributetype<br />
# were made by Marc Bourget (  bourget@up2.com  )<br />
# Up2 Technologies (div. Teleglobe Communication Corp)<br />
# oid number and additional attributetype were taken from:<br />
# Solaris and LDAP Naming Service, Deploying LDAP in the Enterprise.<br />
# Tom Bialanski and Michael Haines, Sun Microsystems Press,<br />
# A Prentice Hall Title, 2001, ISBN 0-13-030678-9 </p>
<p># Sun nisMapEntry attributes<br />
attributetype ( 1.3.6.1.1.1.1.28<br />
NAME &#8216;nisPublickey&#8217;<br />
DESC &#8216;nisPublickey&#8217;<br />
EQUALITY caseIgnoreIA5Match<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) </p>
<p>attributetype ( 1.3.6.1.1.1.1.29<br />
NAME &#8216;nisSecretkey&#8217;<br />
DESC &#8216;nisSecretkey&#8217;<br />
EQUALITY caseIgnoreIA5Match<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) </p>
<p>attributetype ( 1.3.6.1.4.1.1.1.1.12 SUP name<br />
NAME &#8216;nisDomain&#8217; ) </p>
<p># Sun additional attributes to RFC2307 attributes (NIS)<br />
attributetype ( 2.16.840.1.113730.3.1.30<br />
NAME &#8216;mgrpRFC822MailMember&#8217;<br />
DESC &#8216;mgrpRFC822MailMember&#8217;<br />
EQUALITY caseIgnoreIA5Match<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) </p>
<p>#attributetype ( 1.3.6.1.4.1.42.2.27.2.1.15<br />
# NAME &#8216;rfc822MailMember&#8217;<br />
# DESC &#8216;rfc822MailMember&#8217;<br />
# EQUALITY caseIgnoreIA5Match<br />
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) </p>
<p>attributetype ( 1.3.6.1.4.1.42.2.27.1.1.12<br />
NAME &#8216;nisNetIdUser&#8217;<br />
DESC &#8216;nisNetIdUser&#8217;<br />
EQUALITY caseExactIA5Match<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) </p>
<p>attributetype ( 1.3.6.1.4.1.42.2.27.1.1.13<br />
NAME &#8216;nisNetIdGroup&#8217;<br />
DESC &#8216;nisNetIdGroup&#8217;<br />
EQUALITY caseExactIA5Match<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) </p>
<p>attributetype ( 1.3.6.1.4.1.42.2.27.1.1.14<br />
NAME &#8216;nisNetIdHost&#8217;<br />
DESC &#8216;nisNetIdHost&#8217;<br />
EQUALITY caseExactIA5Match<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) </p>
<p># Sun NIS publickey objectclass<br />
objectclass ( 1.3.6.1.1.1.2.14<br />
NAME &#8216;NisKeyObject&#8217;<br />
DESC &#8216;NisKeyObject&#8217;<br />
SUP top<br />
MUST ( cn $ nisPublickey $ nisSecretkey )<br />
MAY ( uidNumber $ description ) ) </p>
<p># Sun NIS domain objectclass<br />
objectclass ( 1.3.1.6.1.1.1.2.15<br />
NAME &#8216;nisDomainObject&#8217;<br />
DESC &#8216;nisDomainObject&#8217;<br />
SUP top AUXILIARY<br />
MUST ( nisDomain ) ) </p>
<p># Sun NIS mailGroup objectclass<br />
objectclass ( 2.16.840.1.113730.3.2.4<br />
NAME &#8216;mailGroup&#8217;<br />
DESC &#8216;mailGroup&#8217;<br />
SUP top<br />
MUST ( mail )<br />
MAY ( cn $ mgrpRFC822MailMember ) ) </p>
<p># Sun NIS nisMailAlias objectclass<br />
#objectclass ( 1.3.6.1.4.1.42.2.27.1.2.5<br />
# NAME &#8216;nisMailAlias&#8217;<br />
# DESC &#8216;nisMailAlias&#8217;<br />
# SUP top<br />
# MUST ( cn )<br />
# MAY ( rfc822mailMember ) ) </p>
<p># Sun NIS nisNetId objectclass<br />
objectclass ( 1.3.6.1.4.1.42.2.27.1.2.6<br />
NAME &#8216;nisNetId&#8217;<br />
DESC &#8216;nisNetId&#8217;<br />
SUP top<br />
MUST ( cn )<br />
MAY ( nisNetIdUser $ nisNetIdGroup $ nisNetIdHost ) ) </p>
<p># Below is optional unless you want to use ldap_gen_profile<br />
attributetype ( 1.3.6.1.4.1.42.2.27.5.1.15 SUP name<br />
NAME &#8216;SolarisLDAPServers&#8217;<br />
DESC &#8216;SolarisLDAPServers&#8217;<br />
SINGLE-VALUE ) </p>
<p>attributetype ( 1.3.6.1.4.1.42.2.27.5.1.16 SUP name<br />
NAME &#8216;SolarisSearchBaseDN&#8217;<br />
DESC &#8216;SolarisSearchBaseDN&#8217;<br />
SINGLE-VALUE ) </p>
<p>attributetype ( 1.3.6.1.4.1.42.2.27.5.1.17<br />
NAME &#8216;SolarisCacheTTL&#8217;<br />
DESC &#8216;SolarisCacheTTL&#8217;<br />
EQUALITY integerMatch<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27<br />
SINGLE-VALUE ) </p>
<p>attributetype ( 1.3.6.1.4.1.42.2.27.5.1.18 SUP name<br />
NAME &#8216;SolarisBindDN&#8217;<br />
DESC &#8216;SolarisBindDN&#8217;<br />
SINGLE-VALUE ) </p>
<p>attributetype ( 1.3.6.1.4.1.42.2.27.5.1.19 SUP name<br />
NAME &#8216;SolarisBindPassword&#8217;<br />
DESC &#8216;SolarisBindPassword&#8217;<br />
SINGLE-VALUE ) </p>
<p>attributetype ( 1.3.6.1.4.1.42.2.27.5.1.20 SUP name<br />
NAME &#8216;SolarisAuthMethod&#8217;<br />
DESC &#8216;SolarisAuthMethod&#8217;<br />
SINGLE-VALUE ) </p>
<p>attributetype ( 1.3.6.1.4.1.42.2.27.5.1.21 SUP name<br />
NAME &#8216;SolarisTransportSecurity&#8217;<br />
DESC &#8216;SolarisTransportSecurity&#8217;<br />
SINGLE-VALUE ) </p>
<p>attributetype ( 1.3.6.1.4.1.42.2.27.5.1.24 SUP name<br />
NAME &#8216;SolarisDataSearchDN&#8217;<br />
DESC &#8216;SolarisDataSearchDN&#8217;<br />
SINGLE-VALUE ) </p>
<p>attributetype ( 1.3.6.1.4.1.42.2.27.5.1.25 SUP name<br />
NAME &#8216;SolarisSearchScope&#8217;<br />
DESC &#8216;SolarisSearchScope&#8217;<br />
SINGLE-VALUE ) </p>
<p>attributetype ( 1.3.6.1.4.1.42.2.27.5.1.26<br />
NAME &#8216;SolarisSearchTimeLimit&#8217;<br />
DESC &#8216;SolarisSearchTimeLimit&#8217;<br />
EQUALITY integerMatch<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27<br />
SINGLE-VALUE ) </p>
<p>attributetype ( 1.3.6.1.4.1.42.2.27.5.1.27 SUP name<br />
NAME &#8216;SolarisPreferedServer&#8217;<br />
DESC &#8216;SolarisPreferedServer&#8217; ) </p>
<p>attributetype ( 1.3.6.1.4.1.42.2.27.5.1.28 SUP name<br />
NAME &#8216;SolarisPreferedServerOnly&#8217;<br />
DESC &#8216;SolarisPreferedServerOnly&#8217;<br />
SINGLE-VALUE ) </p>
<p>attributetype ( 1.3.6.1.4.1.42.2.27.5.1.29 SUP name<br />
NAME &#8216;SolarisSearchReferral&#8217;<br />
DESC &#8216;SolarisSearchReferral&#8217;<br />
SINGLE-VALUE ) </p>
<p>objectclass ( 1.3.6.1.4.1.42.2.27.5.2.7<br />
NAME &#8216;SolarisNamingProfile&#8217;<br />
DESC &#8216;Solaris LDAP NSS Profile&#8217;<br />
SUP top STRUCTURAL<br />
MUST ( cn $ SolarisLDAPServers )<br />
MAY ( SolarisBindDN $ SolarisBindPassword $<br />
SolarisSearchBaseDN $ SolarisAuthMethod $<br />
SolarisTransportSecurity $ SolarisSearchReferral $<br />
SolarisDataSearchDN $ SolarisSearchScope $<br />
SolarisSearchTimeLimit $ SolarisCacheTTL ) ) </p>
<p># End of solaris.schema</p>
<p>======================================<br />
   sudo.schema file:<br />
====================================== </p>
<p>#<br />
# OpenLDAP schema file for Sudo<br />
# Save as /etc/openldap/schema/sudo.schema<br />
# </p>
<p>attributetype ( 1.3.6.1.4.1.15953.9.1.1<br />
NAME &#8216;sudoUser&#8217;<br />
DESC &#8216;User(s) who may run sudo&#8217;<br />
EQUALITY caseExactIA5Match<br />
SUBSTR caseExactIA5SubstringsMatch<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) </p>
<p>attributetype ( 1.3.6.1.4.1.15953.9.1.2<br />
NAME &#8216;sudoHost&#8217;<br />
DESC &#8216;Host(s) who may run sudo&#8217;<br />
EQUALITY caseExactIA5Match<br />
SUBSTR caseExactIA5SubstringsMatch<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) </p>
<p>attributetype ( 1.3.6.1.4.1.15953.9.1.3<br />
NAME &#8216;sudoCommand&#8217;<br />
DESC &#8216;Command(s) to be executed by sudo&#8217;<br />
EQUALITY caseExactIA5Match<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) </p>
<p>attributetype ( 1.3.6.1.4.1.15953.9.1.4<br />
NAME &#8216;sudoRunAs&#8217;<br />
DESC &#8216;User(s) impersonated by sudo (deprecated)&#8217;<br />
EQUALITY caseExactIA5Match<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) </p>
<p>attributetype ( 1.3.6.1.4.1.15953.9.1.5<br />
NAME &#8216;sudoOption&#8217;<br />
DESC &#8216;Options(s) followed by sudo&#8217;<br />
EQUALITY caseExactIA5Match<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) </p>
<p>attributetype ( 1.3.6.1.4.1.15953.9.1.6<br />
NAME &#8216;sudoRunAsUser&#8217;<br />
DESC &#8216;User(s) impersonated by sudo&#8217;<br />
EQUALITY caseExactIA5Match<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) </p>
<p>attributetype ( 1.3.6.1.4.1.15953.9.1.7<br />
NAME &#8216;sudoRunAsGroup&#8217;<br />
DESC &#8216;Group(s) impersonated by sudo&#8217;<br />
EQUALITY caseExactIA5Match<br />
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) </p>
<p>objectclass ( 1.3.6.1.4.1.15953.9.2.1 NAME &#8216;sudoRole&#8217; SUP top STRUCTURAL<br />
DESC &#8216;Sudoer Entries&#8217;<br />
MUST ( cn )<br />
MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ sudoRunAsGroup<br />
$ sudoOption $<br />
description )<br />
) </p>
<p>These schema files should be installed in <openldap-dir>/etc/schemas/<br />
slapd.conf </p>
<p>This is an example config for <openldap-dir>/etc/slapd.conf </p>
<p>include /opt/openldap/etc/schema/core.schema<br />
include /opt/openldap/etc/schema/cosine.schema<br />
include /opt/openldap/etc/schema/nis.schema<br />
include /opt/openldap/etc/schema/inetorgperson.schema<br />
include /opt/openldap/etc/schema/solaris.schema<br />
include /opt/openldap/etc/schema/duaconf.schema<br />
include /opt/openldap/etc/schema/ppolicy.schema<br />
include /opt/openldap/etc/schema/sudo.schema </p>
<p># TLS Certificate<br />
TLSCACertificateFile /opt/openldap/etc/cacert.pem<br />
TLSCertificateFile /opt/openldap/etc/server..pem<br />
TLSCertificateKeyFile /opt/openldap/etc/server..pem<br />
TLSCipherSuite HIGH:MEDIUM:-SSLv2<br />
TLSVerifyClient allow<br />
#TLSVerifyClient demand | allow | never </p>
<p># ACL&#8217;s<br />
access to dn.subtree=&#8221;ou=People,dc=domain,dc=tld&#8221;<br />
attrs=userPassword,shadowLastChange<br />
by dn=&#8221;cn=proxyagent,ou=profile,dc=domain,dc=tld&#8221; write<br />
by self write<br />
by anonymous auth<br />
by * read </p>
<p># Do not allow users so change their uid/gid/groupmembership<br />
access to attrs=uid,uidNumber,gidNumber,memberUid<br />
by * read </p>
<p>access to dn.base=&#8221;"<br />
by dn=&#8221;cn=proxyagent,ou=profile,dc=domain,dc=tld&#8221; read<br />
by * read </p>
<p>access to dn.base=&#8221;cn=Subschema&#8221;<br />
by anonymous none<br />
by * read </p>
<p>access to dn.subtree=&#8221;ou=People,dc=domain,dc=tld&#8221;<br />
by self write<br />
by * read </p>
<p>access to dn.subtree=&#8221;ou=Group,dc=domain,dc=tld&#8221;<br />
by * read </p>
<p># Sudo rules are only readable by the dedicated sudoers account<br />
access to dn.subtree=&#8221;ou=SUDOers,dc=domain,dc=tld&#8221;<br />
by dn=&#8221;cn=sudoagent,ou=profile,dc=domain,dc=tld&#8221; read<br />
by * none </p>
<p>access to *<br />
by * read </p>
<p># MirrorMode Replication<br />
serverID 1 </p>
<p>database bdb<br />
suffix &#8220;dc=domain,dc=tld&#8221;<br />
rootdn &#8220;cn=Manager,dc=domain,dc=tld&#8221; </p>
<p>#rootpw {SSHA}XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX </p>
<p># Synchronisation/Replication<br />
overlay syncprov<br />
syncprov-checkpoint 100 10<br />
syncprov-sessionlog 100 </p>
<p>syncrepl rid=001<br />
provider=ldap://ldap2.domain.tld<br />
bindmethod=simple<br />
starttls=critical<br />
binddn=&#8221;cn=proxyagent,ou=profile,dc=domain,dc=tld&#8221;<br />
credentials=secretpassword<br />
searchbase=&#8221;dc=domain,dc=tld&#8221;<br />
schemachecking=on<br />
type=refreshAndPersist<br />
retry=&#8221;60 +&#8221; </p>
<p># 2-Master mode<br />
mirrormode on </p>
<p># Indices to maintain </p>
<p>index objectClass,uid,uidNumber,gidNumber,ou eq<br />
index cn,mail,surname,givenname eq,subinitial<br />
index memberUid eq<br />
index nisDomain eq<br />
index uniqueMember pres<br />
index sudoUser eq,sub </p>
<p># OVERLAY definitions: NEED TO BE __AFTER__ database definition they work on<br />
overlay ppolicy<br />
ppolicy_default &#8220;cn=default,ou=policies,dc=domain,dc=tld&#8221;<br />
ppolicy_hash_cleartext on<br />
ppolicy_use_lockout </p>
<p>overlay unique<br />
unique_uri ldap:///ou=People,dc=domain,dc=tld?uidNumber,uid?sub<br />
unique_uri ldap:///ou=Group,dc=domain,dc=tld?gidNumber,cn?sub </p>
<p># Performance tuning directives<br />
sizelimit 5000<br />
threads 16<br />
idletimeout 14400<br />
cachesize 10000<br />
checkpoint 256 15<br />
password-hash {SSHA} </p>
<p># Monitor<br />
database monitor<br />
access to dn.subtree=&#8221;cn=Monitor&#8221;<br />
by dn=&#8221;cn=Manager,dc=domain,dc=tld&#8221; write<br />
by users read<br />
by * none</p>
<p>======================================<br />
   Filling the LDAP Directory:<br />
====================================== </p>
<p>Next step is to fill the LDAP directory with some starting content<br />
Below you will find an example ldif file that can be used to jumpstart your LDAP<br />
directory. It creates a test user, group and people entries, a skeleton sudo<br />
infrastructure, configuration profiles and a password policy template. </p>
<p>dn: dc=domain,dc=tld<br />
associatedDomain: domain.tld<br />
dc: ux<br />
objectClass: top<br />
objectClass: dcObject<br />
objectClass: domain<br />
objectClass: domainRelatedObject<br />
objectClass: nisDomainObject<br />
nisDomain: domain.tld<br />
o: Organisation Name </p>
<p>dn: cn=Manager, dc=domain,dc=tld<br />
objectClass: organizationalRole<br />
cn: Manager </p>
<p>dn: ou=profile, dc=domain,dc=tld<br />
ou: profile<br />
objectClass: top<br />
objectClass: organizationalUnit </p>
<p>dn: ou=SUDOers, dc=domain,dc=tld<br />
ou: SUDOers<br />
objectClass: top<br />
objectClass: organizationalUnit </p>
<p>dn: cn=defaults,ou=SUDOers, dc=domain,dc=tld<br />
objectClass: top<br />
objectClass: sudoRole<br />
description: Default sudoOptions go here<br />
sudoOption: ignore_dot<br />
sudoOption: !mail_no_user<br />
sudoOption: root_sudo<br />
sudoOption: log_host<br />
sudoOption: logfile=/var/log/sudolog<br />
sudoOption: timestamp_timeout=5<br />
cn: defaults </p>
<p>dn: cn=Global_Allowed_NOPASS,ou=SUDOers, dc=domain,dc=tld<br />
sudoUser: ALL<br />
sudoCommand: /some/script.sh<br />
sudoHost: ALL<br />
objectClass: top<br />
objectClass: sudoRole<br />
sudoOption: !authenticate<br />
cn: Global_Allowed_NOPASS </p>
<p>dn: ou=People, dc=domain,dc=tld<br />
ou: People<br />
objectClass: top<br />
objectClass: organizationalUnit </p>
<p>dn: ou=Group, dc=domain,dc=tld<br />
ou: Group<br />
objectClass: top<br />
objectClass: organizationalUnit<br />
dn: cn=Users,ou=Group, dc=domain,dc=tld<br />
gidNumber: 1000<br />
objectClass: top<br />
objectClass: posixGroup<br />
cn: Users </p>
<p>dn: cn=proxyagent,ou=profile, dc=domain,dc=tld<br />
userPassword:: MUNGED<br />
objectClass: top<br />
objectClass: person<br />
sn: proxyagent<br />
cn: proxyagent </p>
<p>dn: cn=default,ou=profile, dc=domain,dc=tld<br />
defaultSearchBase: dc=domain,dc=tld<br />
authenticationMethod: simple<br />
followReferrals: TRUE<br />
profileTTL: 43200<br />
searchTimeLimit: 30<br />
objectClass: DUAConfigProfile<br />
defaultServerList: ldapserver1.domain.tld ldapserver2.domain.tld<br />
credentialLevel: proxy<br />
cn: default<br />
defaultSearchScope: one </p>
<p>dn: cn=tls_profile,ou=profile, dc=domain,dc=tld<br />
defaultSearchBase: dc=domain,dc=tld<br />
authenticationMethod: tls:simple<br />
followReferrals: FALSE<br />
bindTimeLimit: 10<br />
profileTTL: 43200<br />
searchTimeLimit: 30<br />
objectClass: top<br />
objectClass: DUAConfigProfile<br />
defaultServerList: ldapserver1.domain.tld ldapserver2.domain.tld<br />
credentialLevel: proxy<br />
cn: tls_profile<br />
serviceSearchDescriptor: passwd: ou=People,dc=domain,dc=tld<br />
serviceSearchDescriptor: group: ou=Group,dc=domain,dc=tld<br />
serviceSearchDescriptor: shadow: ou=People,dc=domain,dc=tld<br />
serviceSearchDescriptor: netgroup: ou=netgroup,dc=domain,dc=tld<br />
serviceSearchDescriptor: sudoers: ou=SUDOers,dc=domain,dc=tld<br />
defaultSearchScope: one </p>
<p>dn: ou=policies, dc=domain,dc=tld<br />
ou: policies<br />
objectClass: top<br />
objectClass: organizationalUnit </p>
<p>dn: uid=testuser,ou=People, dc=domain,dc=tld<br />
shadowMin: 5<br />
sn: User<br />
userPassword:: MUNGED<br />
loginShell: /bin/bash<br />
uidNumber: 9999<br />
gidNumber: 1000<br />
shadowFlag: 0<br />
shadowExpire: -1<br />
shadowMax: 99999<br />
uid: testuser<br />
objectClass: top<br />
objectClass: person<br />
objectClass: organizationalPerson<br />
objectClass: posixAccount<br />
objectClass: shadowAccount<br />
gecos: Test User<br />
shadowLastChange: 0<br />
cn: Test User<br />
homeDirectory: /export/home/testuser<br />
shadowInactive: -1<br />
shadowWarning: 7 </p>
<p>dn: cn=default,ou=policies, dc=domain,dc=tld<br />
pwdFailureCountInterval: 30<br />
pwdSafeModify: FALSE<br />
pwdGraceAuthNLimit: 5<br />
pwdLockoutDuration: 10<br />
objectClass: pwdPolicy<br />
objectClass: person<br />
objectClass: top<br />
objectClass: pwdPolicyChecker<br />
pwdMaxFailure: 5<br />
pwdAllowUserChange: TRUE<br />
pwdMinLength: 5<br />
cn: default<br />
pwdAttribute: userPassword<br />
pwdMinAge: 5<br />
pwdLockout: TRUE<br />
pwdCheckQuality: 1<br />
pwdInHistory: 5<br />
sn: default policy<br />
pwdMustChange: FALSE<br />
pwdExpireWarning: 600<br />
pwdMaxAge: 10</p>
<p>======================================<br />
   Configuring a Solaris 10 Client:<br />
====================================== </p>
<p>If you have defined a profile in your LDAP tree, it should be quite easy to setup a<br />
LDAP client on a Solaris 10 system.<br />
If you are using SSL or TLS with your server (you should), then you need to install<br />
the CA certificate first, so the server certificate can be checked. </p>
<p>certutil -N -d /var/ldap<br />
certutil -A -d /var/ldap -n &#8216;CA Name&#8217; -i /path/to/cacert.pem -a -t CT </p>
<p>1. First copy /etc/nsswitch.ldap to /etc/nsswitch.ldap.bak and /etc/nsswitch to<br />
/etc/nsswitch.bak<br />
2. Edit /etc/nsswitch.ldap, making sure to change the entries for hosts and ipnodes<br />
to &#8216;files dns&#8217;<br />
3. run ldapclient init: </p>
<p>ldapclient init -v \<br />
-a proxyDN=cn=proxyagent,ou=profile,dc=domain,dc=tld \<br />
-a proxyPassword=secret \<br />
-a domainName=domain.tld \<br />
-a profileName=tls_profile \<br />
ldapserver.domain.tld<br />
4. If all is well, LDAP should be configured now. </p>
<p>Using listusers you should be able to see the ldap accounts in your userlist.</p>
<p>======================================<br />
   Configuring PAM:<br />
====================================== </p>
<p>Next step is configuring pam to allow people to actually log-in using ldap accounts,<br />
and have their passwords stored in LDAP. Sun-SSH uses seperate pam names for each<br />
authentication method, and the sshd-pubkey method has it&#8217;s own dedicated<br />
configuration. </p>
<p># pam.conf.ldapv2_native_client<br />
#<br />
# http://docs.sun.com/app/docs/doc/816-4556/6maort2te?a=view<br />
#<br />
# IMPORTANT NOTES from Gary Tay<br />
#<br />
# 1) This is a /etc/pam.conf with password management support that works for:<br />
#<br />
# Solaris10 Native LDAP Client<br />
# Solaris9 Native LDAP Client provided that:<br />
# &#8211; latest kernel patch and Patch 112960 are applied<br />
# &#8211; all the pam_unix_cred.so.1 lines are commented out<br />
# Solaris8 Native LDAP Client provided that:<br />
# &#8211; latest kernel patch and Patch 108993 are applied<br />
# &#8211; all the pam_unix_cred.so.1 lines are commented out<br />
#<br />
# 2) If modules for sshd or any are not defined, default is other<br />
# as seen by output of grep other /etc/pam.conf<br />
#<br />
# Notes from Mark Janssen<br />
#<br />
# 3) SSH Pubkey authentication needs its own pam rules on sshd-pubkey<br />
#<br />
# Authentication management<br />
#<br />
# login service (explicit because of pam_dial_auth)<br />
#<br />
login auth requisite pam_authtok_get.so.1<br />
login auth required pam_dhkeys.so.1<br />
login auth required pam_unix_cred.so.1<br />
login auth required pam_dial_auth.so.1<br />
login auth binding pam_unix_auth.so.1 server_policy<br />
login auth required pam_ldap.so.1<br />
#<br />
# rlogin service (explicit because of pam_rhost_auth)<br />
#<br />
rlogin auth sufficient pam_rhosts_auth.so.1<br />
rlogin auth requisite pam_authtok_get.so.1<br />
rlogin auth required pam_dhkeys.so.1<br />
rlogin auth required pam_unix_cred.so.1<br />
rlogin auth binding pam_unix_auth.so.1 server_policy<br />
rlogin auth required pam_ldap.so.1<br />
#<br />
# rsh service (explicit because of pam_rhost_auth,<br />
# and pam_unix_auth for meaningful pam_setcred)<br />
#<br />
rsh auth sufficient pam_rhosts_auth.so.1<br />
rsh auth required pam_unix_cred.so.1<br />
rsh auth binding pam_unix_auth.so.1 server_policy<br />
rsh auth required pam_ldap.so.1<br />
#<br />
# PPP service (explicit because of pam_dial_auth)<br />
#<br />
ppp auth requisite pam_authtok_get.so.1<br />
ppp auth required pam_dhkeys.so.1<br />
ppp auth required pam_dial_auth.so.1<br />
ppp auth binding pam_unix_auth.so.1 server_policy<br />
ppp auth required pam_ldap.so.1<br />
#<br />
# Default definitions for Authentication management<br />
# Used when service name is not explicitly mentioned for authentication<br />
#<br />
other auth requisite pam_authtok_get.so.1<br />
other auth required pam_dhkeys.so.1<br />
other auth required pam_unix_cred.so.1<br />
other auth binding pam_unix_auth.so.1 server_policy<br />
other auth required pam_ldap.so.1<br />
#<br />
# passwd command (explicit because of a different authentication module)<br />
#<br />
passwd auth binding pam_passwd_auth.so.1 server_policy<br />
passwd auth required pam_ldap.so.1<br />
#<br />
# cron service (explicit because of non-usage of pam_roles.so.1)<br />
#<br />
cron account required pam_unix_account.so.1<br />
#<br />
# Default definition for Account management<br />
# Used when service name is not explicitly mentioned for account management<br />
#<br />
other account requisite pam_roles.so.1<br />
other account binding pam_unix_account.so.1 server_policy<br />
other account required pam_ldap.so.1<br />
#<br />
# Default definition for Session management<br />
# Used when service name is not explicitly mentioned for session management<br />
#<br />
other session required pam_unix_session.so.1<br />
#other session required pam_mkhomedir.so.1<br />
#<br />
# Default definition for Password management<br />
# Used when service name is not explicitly mentioned for password management<br />
#<br />
other password required pam_dhkeys.so.1<br />
other password requisite pam_authtok_get.so.1<br />
other password requisite pam_authtok_check.so.1<br />
other password required pam_authtok_store.so.1 debug server_policy </p>
<p># Custom Stuff<br />
# Allow ssh-pubkey (SUN-SSH) logins to work<br />
sshd-pubkey account required pam_unix_account.so.1</p>
<p>======================================<br />
   Configuring a AIX 6.1 Client<br />
======================================</p>
<p>Configuring AIX6.1 is quite easy, especially compared to Solaris.</p>
<p>* Make sure the LDAP client packages are installed<br />
   o idsldap.clt32bit61.rte 6.1.0.3 Directory Server &#8211; 32 bit Client<br />
   o idsldap.clt64bit61.rte 6.1.0.3 Directory Server &#8211; 64 bit Client<br />
   o idsldap.cltbase61.adt 6.1.0.3 Directory Server &#8211; Base Client<br />
   o idsldap.cltbase61.rte 6.1.0.3 Directory Server &#8211; Base Client<br />
   * run: mksecldap -c -h ldapserver1,ldapserver2 -a<br />
   cn=proxyagent,ou=profile,dc=domain,dc=tld -p password -k<br />
   /etc/security/ldap/your-ca.kdb -w keydbpassword -A ldap_auth<br />
   o Convert your cacert.pem file to a .kdb file using (java) gsk7ikm, and place it in<br />
   /etc/security/ldap/your-ca.kdb<br />
   o keydbpassword = the password you use in gsk7ikm to encrypt your keyring<br />
   (mandatory)<br />
   o password = the password used for the proxyagent</p>
<p>======================================<br />
   Configuring a RHEL Client:<br />
======================================</p>
<p>Configuring a Redhat Enterprise Linux Client is quite easy. It consists of the<br />
   following steps:</p>
<p>* Copy the CA-Certificate to /etc/openldap/cacerts/ca-cert.pem<br />
   * Edit /etc/ldap.conf: Add the correct values for &#8216;binddn&#8217; and &#8216;bindpw&#8217;</p>
<p>binddn cn=proxyagent,ou=profile,dc=domain,dc=tld<br />
   bindpw secret<br />
   * Run /usr/bin/system-config-authentication<br />
   o Check &#8216;Cache Information&#8217;<br />
   o Check &#8216;Use LDAP&#8217;, Check &#8216;Use TLS&#8217; and fill in the ldap hostname and base-DN<br />
   o Check &#8216;Use LDAP Authentication&#8217;<br />
   o Check &#8216;Local authentication is sufficient&#8217;</p>
<p>======================================<br />
   Configuring Netgroups:<br />
======================================</p>
<p>Using the setup described above lets any ldap user with a valid account log in to any<br />
   ldap-enabled client machine. This might not be what you want. Using netgroups is a<br />
   method to limit ldap account visibility on a per system basis. Using netgroups you<br />
   can specify what (groups of) users can login and use what systems.<br />
   Configuring netgroups consists of the following steps:</p>
<p>Import the following ldif-file into your directory:</p>
<p>dn: ou=Netgroup, dc=domain,dc=tld<br />
   ou: netgroup<br />
   objectClass: top</p>
<p>objectClass: organizationalUnit</p>
<p>dn: cn=Admins, ou=Netgroup, dc=domain,dc=tld<br />
   objectClass: nisNetgroup<br />
   objectClass: top<br />
   nisNetgroupTriple: (,someuser,domain.tld)<br />
   cn: Admins</p>
<p>dn: cn=App1, ou=Netgroup, dc=domain,dc=tld<br />
   objectClass: nisNetgroup<br />
   objectClass: top<br />
   nisNetgroupTriple: (,app1user,domain.tld)<br />
   memberNisNetgroup: Admins<br />
   cn: App1</p>
<p>This example creates the Netgroup infrastructure, and populates it with 2 netgroups.<br />
   The &#8216;App1&#8242; netgroup would be used on systems where &#8216;App1&#8242; would run. The &#8216;Admins&#8217;<br />
   netgroup is a group for the admins, and it&#8217;s included in the &#8216;App1&#8242; netgroup. This<br />
   way I only need to allow the App1 netgroup on that system, and it automatically<br />
   includes the users from the &#8216;Admins&#8217; netgroup.</p>
<p>   To specify a user in a netgroup, use a &#8216;nisNetgroupTriple&#8217; where the value is: &#8216;(&#8216;,<br />
   <hostname>, <username>, <domainname>, &#8216;)&#8217;. All fields are optional and can be left<br />
   out. In our case, we&#8217;re mostly interested in the &#8216;username&#8217; field, so the entries<br />
   look like &#8216;(,username,)&#8217;.<br />
   A netgroup can include another netgroup using &#8216;memberNisNetgroup: netgroupname&#8217;.</p>
<p>======================================<br />
   Solaris: Changing nsswitch.conf<br />
======================================</p>
<p>We will be using the &#8216;compat&#8217; support for netgroups, so we need to change the<br />
 &#8216;passwd&#8217; entry in /etc/nsswitch.conf from:</p>
<p>passwd: files ldap</p>
<p>to</p>
<p>passwd: compat<br />
 passwd_compat: ldap</p>
<p>We are telling the nss system to use &#8216;compat&#8217; (instead of the default files or ldap),<br />
   and telling it that the database that it should check for NIS entries is ldap<br />
   (default would be YP)</p>
<p>======================================<br />
   AIX: Changing system settings for netgroups<br />
======================================</p>
<p>For AIX the following changes need to be made to enable netgroups:</p>
<p>* In /usr/lib/security/methods.cfg, change the LDAP group, add the options line:</p>
<p>LDAP:<br />
   program = /usr/lib/security/LDAP<br />
   program_64 =/usr/lib/security/LDAP64<br />
   options = netgroup<br />
   * In /etc/group, add a line at the end:</p>
<p>+:<br />
   * In /etc/security/user, change the default group:</p>
<p>SYSTEM = compat</p>
<p>======================================<br />
   Allowing netgroups<br />
======================================</p>
<p>Every netgroup you want to allow on the system needs to be included in the<br />
   /etc/passwd file. Make sure you use the correct format, otherwise you will not be<br />
   able to login. For Solaris this format needs to be:</p>
<p>+@netgroupname:x:::::<br />
   +@othernetgroup:x:::::</p>
<p>If you only add &#8216;+@netgroupname&#8217; things seem to work, you can see the accounts with<br />
   &#8216;listusers&#8217; and even &#8216;su&#8217; to them, however you still can&#8217;t login with these<br />
   accounts. If you add the entry as specified above, and then run &#8216;pwconv&#8217; the entry<br />
   will be copied to &#8216;/etc/shadow&#8217; in the correct format and you should then be able<br />
   to login with netgroup-listed accounts.<br />
   For AIX you can just specify the simpler:</p>
<p>+@netgroupname<br />
   +@othernetgroup</p>
<p>It&#8217;s recomendable to create dedicated netgroups for any system or group of systems<br />
   that have their own user limitations. It&#8217;s also a good idea to include the &#8216;admin&#8217;<br />
   netgroup in any netgroup you create or explicitly include it on every system.</p>
<p>======================================<br />
   Creating home directories<br />
======================================</p>
<p>Linux and AIX have PAM modules to create a home directory for a user if one doesn&#8217;t<br />
   exist. Solaris sadly doesn&#8217;t have a PAM module for this (and I couldn&#8217;t get the<br />
   linux module working for solaris).<br />
   The Linux PAM module is pam_mkhomedir. You can include it in your PAM stack as<br />
   follows:</p>
<p>session required pam_mkhomedir.so skel=/etc/skel/ umask=0022</p>
<p>The AIX PAM module is called pam_mkuserhome, however, I have not been able to get it<br />
   to create an actual directory in my experiments. Since I already need to have a<br />
   work-around for Solaris I used this method for AIX as well.</p>
<p>* Create a mkhome script and put it in /usr/local/bin</p>
<p>#!/bin/sh</p>
<p>if [ -d ${HOME} ]; then<br />
   exit 0<br />
   fi</p>
<p>mkdir -p ${HOME}<br />
   cp -r /etc/skel/.???* ${HOME}<br />
   cp -r /etc/skel/* ${HOME}<br />
   chown ${SUDO_UID}:${SUDO_GID} ${HOME} ${HOME}/* ${HOME}/.???*<br />
   echo &#8220;Created ${HOME}&#8221;<br />
   exit 0<br />
   * Allow this script to be run using sudo, without prompting for a password</p>
<p>dn: cn=Global_Allowed_NOPASS,ou=SUDOers, dc=domain,dc=tld<br />
   sudoUser: ALL<br />
   sudoCommand: /usr/local/bin/mkhome<br />
   sudoHost: ALL<br />
   objectClass: top<br />
   objectClass: sudoRole<br />
   sudoOption: !authenticate<br />
   cn: Global_Allowed_NOPASS<br />
   * Call sudo /usr/local/bin/mkhome from /etc/profile when a home directory can&#8217;t be<br />
   found</p>
<p>if [ ! -d $HOME ]<br />
   then<br />
   /usr/bin/sudo /usr/local/bin/mkhome<br />
   cd $HOME<br />
   fi</p>
<p>======================================<br />
   MAIL ///////////////////////////////<br />
======================================</p>
<p>mail is a command line e-mail client for Unix and Unix-like operating systems.</p>
<p>Example usage</p>
<p>mail -s &#8220;You&#8217;ve got mail&#8221; -c cc.rider@b.c<br />
somebody@example.com   </p>
<p>anotherbody@example.net   </p>
<p>This sends a message with the subject &#8220;You&#8217;ve got mail&#8221; to two recipients, somebody<br />
and anotherbody, and CCs (copies) a third, cc.rider. The message will be typed<br />
after the command is entered and will be ended with Control-D.</p>
<p>If you want to send a message in one line, use any Unix command sequence that<br />
generates text. For example:</p>
<p>o &#8220;Some message&#8221; | mail -s &#8220;meeting today&#8221;<br />
somebody@example.com   </p>
<p>This is especially useful for having a system report its status automatically through<br />
E-mail.</p>
<p>There is also a -a option for using an ISO-8859 character set beyond US Ascii. For<br />
instance:</p>
<p>mail -s &#8220;You&#8217;ve got mail&#8221; -a ISO-8859-8<br />
somebody@example.com   </p>
<p>The -a ISO-8859-8 option tells Mail that the message may include Hebrew characters.</p>
<p>======================================<br />
MAILX ///////////////////////////////<br />
======================================</p>
<p>mailx is a Unix utility program for sending and receiving mail, also known as a Mail<br />
  User Agent program. It is an improved version of the mail utility.</p>
<p>mailx is a lightweight mail program which has a command syntax similar to ed. Mailx<br />
  allows one to send and read email. Mailx cannot, by itself, receive email from<br />
  another computer. It reads messages from a file on the local machine, which are<br />
  delivered there by a local delivery agent such as procmail.</p>
<p>A simplified syntax with the most commonly used options is:<br />
mailx [-s subject] [-a attachment ] [-r from-addr] to-addr . . .</p>
<p>    * -s subject of email (could be inserted later)<br />
    * -r indicates the email&#8217;s sender (not a standard argument)<br />
    * -a file to be attached to email (in some versions)<br />
    * -a specify additional header fields (in other versions)</p>
<p>The end of message is indicated by a single &#8216;.&#8217; or by hitting ctrl+d. In the simple<br />
  send usage, you just type your message directly into mailx. But in real life,<br />
  you&#8217;ll decide to edit the message after you&#8217;ve been typing for a while. Mailx<br />
  interprets input lines beginning with a tilde (~) as commands. Its ~v command<br />
  causes mailx to invoke the text editor of your choice (defined by the VISUAL<br />
  environment variable) on the message in progress, saved in a temporary file. It can<br />
  be argued this feature makes Mailx a more powerful email composing tool than<br />
  typical Graphical User Interface (GUI) Mail User Agents.</p>
<p>Example usage</p>
<p>A simple example</p>
<p>  $ mailx -s &#8220;From mailx&#8221; abc@cde.com<br />
  type the body<br />
  &#8230;<br />
  EOT (Ctrl+d)<br />
  $ </p>
<p>Simple syntax to send email with subject &#8216;From mailx&#8217; to  abc@cde.com.</p>
<p>A more complex example:</p>
<p>  $ mailx -s &#8220;the subject&#8221; -a arg1 -a arg2 -a &#8220;From:me<email@mail.com>&#8221;<br />
  &#8220;person1
<person1@hotmail.com>&#8221; &#8220;person2
<person2@hotmail.com>&#8221;<br />
  message body<br />
  &#8230;<br />
  EOT<br />
  $</p>
<p>Sends message to person1 and person 2 with arq1 and arq2 as anex. The subject of<br />
message will be &#8220;the subject&#8221; and the receivers will see &#8220;me&#8221; as the sender.</p>
<p>Process the Variable in the Body of Mail example:</p>
<p>  $ mailx -s &#8220;Subject&#8221; &#8220;dhil@yahoo.com&#8221; <<EOT<br />
  hi Dream,<br />
    `date` this is the date on unix now<br />
  EOT<br />
  $ </p>
<p>In the above Example it will send the mail with the current date processed as follows. This<br />
is actually an example of a unix shell feature called a "here document." The mailx command<br />
has no idea where the text is coming from, it's just reading lines from its standard input.<br />
The stuff from the double less-than through the second EOT is interpreted by the shell,<br />
which runs the date command and inserts its output in the appropriate place.</p>
<p>  hi Dream,<br />
  Thu Aug 23 02:25:38 EDT 2007 this is the date on unix now  </p>
<p>One line example as a reminder for job completion</p>
<p>Suppose you have a job which it is going to run for a while. You don't want to stare at the<br />
screen to wait for its completion. You can switch to other terminal to work on other things<br />
but want to get notified the minute the job is completed. Here's the trick to do so:</p>
<p>  sleep 24 &#038;&#038; echo | mailx -s "XXX job completed" xxxxx@gmail.com  </p>
<p>here "sleep 24" is just an example test run command to count for 24 seconds before the mailx<br />
command is executed. You should replace it with the job submission command of your choice.<br />
Once the job is completed, a mail with title "XXX job completed" and empty body will be sent<br />
to xxxxx@gmail.com.</p>
<p>======================================<br />
   Sendmail<br />
======================================</p>
<p>Download Sendmail</p>
<p>Download Sendmail[1]. You may be automatically offered a short initial message which will<br />
indicate the current release. These instructions below assume version 8.10.0 or later.</p>
<p>Build and install Sendmail for your machine. In most cases, this consists of unpacking the<br />
distribution, reading the README and sendmail/README files, and typing Build in the Sendmail<br />
directory. See the INSTALL file in the distribution's top-level directory for details.</p>
<p>Set up Sendmail</p>
<p>Understand that Sendmail uses information from the Domain Name System (DNS) to figure out<br />
which IP addresses go with which mailboxes.</p>
<p>Choose an available domain name. In our example, we will use yourdomain.com.</p>
<p>Configure your DNS on the server. Establish two machines as primary and secondary name<br />
servers for your domain. Knowledge of how to do this is assumed; otherwise, read the O'Reilly<br />
book "DNS and BIND", 4th Edition is highly recommended. Familiarize yourself with BIND before<br />
continuing.</p>
<p>Configure MX records for your domain (Note: CNAME records can not be used; see § 5.2.2 of RFC<br />
1123 for details.) MX records are explained in the O'Reilly Sendmail book; the 2nd edition gives<br />
an overview in § 15.3 and describes how to configure them in § 21.3, whereas the third<br />
edition explains everything about them in § 9.3. You have two options for MX records:</p>
<p>Determine your connection method: If the mail server which will serve your new domain has a<br />
full-time connection to the Internet, it should be the primary MX host for your domain. In<br />
this configuration, your MX records would look like this: yourdomain.com. IN MX 10<br />
yourmailserver.yourdomain.com.</p>
<p>Otherwise, you will need to find another machine to queue mail for your domain when you are<br />
not connected. Be sure to get the machine owners' approval first. That machine must be<br />
configured to allow relaying to your domain. If it is running Sendmail, this can be as simple<br />
as adding your domain to the relay-domains file on that machine. You would then point your MX<br />
records at that machine. For example:</p>
<p>yourdomain.com. IN MX 10 yourmailserver.yourdomain.com.</p>
<p>yourdomain.com. IN MX 20 othermailserver.otherdomain.com.</p>
<p>Configure Sendmail</p>
<p>Read the cf/README file thoroughly. It will give you instructions on creating a .mc file in<br />
the cf/cf directory. Your mailserver.mc file will typically look something like: divert(-1)dnl</p>
<p>#</p>
<p># This file contains the global definitions for yourdomain.com</p>
<p>#</p>
<p>divert(0)dnl</p>
<p>VERSIONID(`@(#)mailserver.mc 1.0 (yourdomain.com) 5/1/97')</p>
<p>OSTYPE(solaris2)dnl</p>
<p>DOMAIN(yourdomain.com)dnl</p>
<p>FEATURE(`virtusertable', `dbm /etc/mail/virtusertable')dnl</p>
<p>MAILER(local)dnl</p>
<p>MAILER(smtp)dnl</p>
<p>Your actual OS will be substituted for solaris2.</p>
<p>A typical cf/domain/yourdomain.com.m4 file that looks something like: divert(-1)dnl</p>
<p>#</p>
<p># This file contains the global definitions for yourdomain.com</p>
<p>#</p>
<p>divert(0)dnl</p>
<p>VERSIONID(`@(#)yourdomain.com.m4 1.0 (yourdomain.com) 5/1/97')</p>
<p>FEATURE(`use_cw_file')dnl</p>
<p>It may have some other feature()'s and define()'s as well. The virtual user table is the key<br />
to all of this.</p>
<p>Generate your /etc/mail/sendmail.cf file from your mailserver.mc file, so type: cd sendmail-<br />
VERSION/cf/cf</p>
<p>/Build mailserver.cf</p>
<p>cp mailserver.cf /etc/mail/sendmail.cf</p>
<p>Create the virtual user table. This is explained in detail in the Sendmail book: § 19.6.28 of<br />
the 2nd edition, or § 4.8.51 of the 3rd edition; an overview is given here. The table is a<br />
database that maps virtual addresses into real addresses. You create a text file where each<br />
line has a key/value pair, separated by a TAB. For example: Example 1: joe@yourdomain.com<br />
jschmoe</p>
<p>jane@yourdomain.com jdoe@othercompany.com</p>
<p>@yourdomain.com jschmoe In this first example, the address joe@yourdomain.com will be mapped<br />
to the local user jschmoe; jane@yourdomain.com will be mapped to the remote user<br />
jdoe@othercompany.com, and anything else coming in to yourdomain.com will also go to jschmoe.</p>
<p>Example 2: joe@yourdomain.com jschmoe%3</p>
<p>bogus@yourdomain.com &npsp; error:nouser No such user here</p>
<p>list@yourdomain.com yourdomain-list</p>
<p>@yourdomain.com %1@othercompany.com In this second example, the address joe@yourdomain.com<br />
will be mapped to the local user jschmoe%3 (see note 3 below for an explanation of what the<br />
%3 means), the address bogus@yourdomain.com will return the indicated error, the address<br />
list@yourdomain.com will be mapped to the local user yourdomain-list (which you would use the<br />
aliases file to ultimately resolve) and every other user at yourdomain.com will be mapped to<br />
a remote user of the same name at othercompany.com.</p>
<p>If you have a local user, say sam, and there is no key for sam@yourdomain.com and no catch-<br />
all key for @yourdomain.com, then Sendmail will fall back to the local user sam when<br />
resolving sam@yourdomain.com. To prevent this, you must use either a catch-all key or an<br />
explicit key for sam@yourdomain.com; the error:nouser example above may be useful in this<br />
instance.</p>
<p>If you want a virtual address to resolve to more than one real address, you need to do it<br />
indirectly. Have the virtual address resolve to a local alias, then have the local alias<br />
resolve to the desired set of addresses. For example, in the virtual user table:<br />
joe@yourdomain.com localjoe</p>
<p>then in the aliases file:</p>
<p>localjoe: joe@othercompany.com, jane@othercompany.com</p>
<p>In the above example: joe@yourdomain.com jschmoe%3</p>
<p>The %3 is the preservation of the optional +detail part of the original address. In general,<br />
+detail means that when Sendmail gets an address like user+detail@domain, then if domain is<br />
in class w (see step 7 below), sendmail checks to see if user+detail can be resolved, then<br />
falls back to just plain user if not. Thus all of: joe@yourdomain.com</p>
<p>joe+foo@yourdomain.com</p>
<p>joe+reallylongextrapart@yourdomain.com</p>
<p>would all match the above entry, with %3 preserving the +detail part of nothing, +foo and<br />
+reallylongextrapart respectively.</p>
<p>Multiple domains are allowed, and virtual addresses in each domain are independent. So for<br />
example, you could have: joe@yourdomain1.com localjoe</p>
<p>joe@yourdomain2.com joe@othercompany.com</p>
<p>joe@yourdomain3.com localjoe</p>
<p>joe@yourdomain4.com error:nouser No such user here</p>
<p>For people administering multiple domains, it may be easier to keep each domain's list in a<br />
separate file, then write a short script to concatenate all such files together into a master<br />
virtual user table. But we're getting ahead of ourselves; that's the next step...</p>
<p>Now the name servers are setup, register your domain using one of the registries. As you<br />
register, inform the registry of the two name servers, and then the domain will point to your<br />
server.</p>
<p>Build the Sendmail User Table</p>
<p>Build the virtual user table. If the above virtual user table text file is located at<br />
sourcefile, and you are using the dbm database type, then use the command: makemap dbm<br />
/etc/mail/virtusertable < sourcefile</p>
<p>Note: if you built Sendmail with NEWDB instead of NDBM, then use hash instead of dbm in the<br />
above line.</p>
<p>This creates one or more non-text files (typically /etc/mail/virtusertable.dir and<br />
/etc/mail/virtusertable.pag, or /etc/mail/virtusertable.db), but does not actually change<br />
/etc/mail/virtusertable itself, so this is the recommended location for sourcefile.</p>
<p>If you would like to reverse-map local users for out-bound mail, you will need to add support<br />
for the generics table to your .mc file: FEATURE(`genericstable', `dbm<br />
/etc/mail/genericstable')dnl</p>
<p>GENERICS_DOMAIN_FILE(`/etc/mail/generics-domains')dnl</p>
<p>And you will need to create /etc/mail/genericstable which is like /etc/mail/virtusertable<br />
above except the columns are reversed: jschmoe joe@yourdomain.com</p>
<p>Add your domain names to Sendmail</p>
<p>Add each new domain name to sendmail's class w. This is typically done by adding a line to<br />
/etc/mail/local-host-names (known as /etc/sendmail.cw prior to version 8.10) with the value<br />
of each domain name. Likewise, if you are using the genericstable, you should add any domains<br />
you wish to reverse-map to /etc/mail/generics-domains.</p>
<p>Restart or SIGHUP sendmail.</p>
<p>You do not need to restart sendmail when changing the virtual user or generics tables, only<br />
when changing /etc/mail/sendmail.cf or class files such as /etc/mail/local-host-names. An<br />
extra step is required for hosts not connected full-time. As noted in the MX configuration<br />
section, if you use another host to queue your mail until you connect, you will have to force<br />
delivery of mail queued on the secondary mail server. To accomplish this, when your primary<br />
server connects, you should run the script etrn.pl which comes in the contrib directory of the<br />
sendmail distribution: etrn.pl secondary-mx-host yourdomain.com</p>
<p>It may be advisable to put this at the end of the Sendmail start-up script on any primary MX.<br />
It would be especially useful as a follow-up to whatever script initiates the connection on<br />
primary MXs without full-time connections.</p>
<p>At this point, you should be set, and people should be able to send e-mail to addresses<br />
@yourdomain.com.</p>
<p>          * Note: if you built Sendmail with NEWDB instead of NDBM, then use hash<br />
            instead of dbm in the above line.<br />
          * This creates one or more non-text files (typically<br />
            /etc/mail/virtusertable.dir and /etc/mail/virtusertable.pag, or<br />
            /etc/mail/virtusertable.db), but does not actually change<br />
            /etc/mail/virtusertable itself, so this is the recommended location for<br />
            sourcefile.<br />
          * If you would like to reverse-map local users for out-bound mail, you will<br />
            need to add support for the generics table to your .mc file:<br />
                o FEATURE(`genericstable', `dbm /etc/mail/genericstable')dnl<br />
                o GENERICS_DOMAIN_FILE(`/etc/mail/generics-domains')dnl<br />
          * And you will need to create /etc/mail/genericstable which is like<br />
            /etc/mail/virtusertable above except the columns are reversed:<br />
                o jschmoe  joe@yourdomain.com   </p>
<p>Add your domain names to Sendmail</p>
<p>   1. Add each new domain name to sendmail's class w. This is typically done by<br />
     adding a line to /etc/mail/local-host-names (known as /etc/sendmail.cw prior to<br />
     version 8.10) with the value of each domain name. Likewise, if you are using the<br />
     genericstable, you should add any domains you wish to reverse-map to<br />
     /etc/mail/generics-domains.<br />
   2. Restart or SIGHUP sendmail.<br />
   3. You do not need to restart sendmail when changing the virtual user or generics<br />
     tables, only when changing /etc/mail/sendmail.cf or class files such as<br />
     /etc/mail/local-host-names.<br />
          * An extra step is required for hosts not connected full-time. As noted in<br />
            the MX configuration section, if you use another host to queue your mail<br />
            until you connect, you will have to force delivery of mail queued on the<br />
            secondary mail server. To accomplish this, when your primary server<br />
            connects, you should run the script etrn.pl which comes in the contrib<br />
            directory of the sendmail distribution:<br />
                o etrn.pl secondary-mx-host yourdomain.com<br />
                o It may be advisable to put this at the end of the Sendmail start-up<br />
                  script on any primary MX. It would be especially useful as a<br />
                  follow-up to whatever script initiates the connection on primary<br />
                  MXs without full-time connections.<br />
                o At this point, you should be set, and people should be able to send<br />
                  e-mail to addresses @yourdomain.com.</p>
<p>Test your configuration file</p>
<p>   1. Test your configuration and make sure everything works as expected before<br />
     announcing the new domain name and mail addresses for that domain. If things<br />
     don't work as expected, you can test with Sendmail's test mode:<br />
          * sendmail -bt<br />
          * Here are some examples of things to try in test mode (make sure the<br />
            domain is in class w:):<br />
                o $=w<br />
                o # is the map working?<br />
                o /map virtuser  joe@yourdomain.com<br />
                o /map virtuser  jane@yourdomain.com<br />
                o /map virtuser @yourdomain.com<br />
                o is the rewriting working? #** ,0  joe@yourdomain.com  #** , 0  some@yourdomain.com   </p>
<p>Tips</p>
<p>    * What Sendmail does:<br />
          o Listen on network ports for mail.<br />
          o Sort mail and deliver it locally or externally to other servers.<br />
          o Append mail to files or pipe it through other programs.<br />
          o Queue mail (if immediate delivery fails).<br />
          o Convert email addresses to/from user names, or handle mailing lists.<br />
          o Reads rules for special mail handling, so it can try to catch spam, or<br />
            check for correctness.<br />
    * If you built Sendmail with NEWDB instead of NDBM, you will have to use hash<br />
      instead of dbm in the above line.</p>
<p>======================================<br />
MTA<br />
======================================</p>
<p>A mail transfer agent (MTA) (also called a mail transport agent, message transfer agent, or<br />
smtpd (short for SMTP daemon), is a computer program or software agent that transfers<br />
electronic mail messages from one computer to another.</p>
<p>The term mail server is also used to mean a computer acting as an MTA that is running the<br />
appropriate software. The term mail exchanger (MX), in the context of the Domain Name System<br />
formally refers to an IP address assigned to a device hosting a mail server, and by extension<br />
also indicates the server itself.</p>
<p>Overview</p>
<p>An MTA receives mail from another MTA (relaying) or from a mail user agent (MUA). The MTA<br />
works behind the scenes, while the user usually interacts with the MUA. Every time an MTA<br />
receives an e-mail, it will add a "Received:" trace header field to the top of the message.<br />
In this way, there is a record of which MTAs handled the e-mail and in which order. Upon<br />
final delivery, the "Return-Path:" header will also be added to record the return path.</p>
<p>The delivery of e-mail to a user's mailbox typically takes place via a mail delivery agent<br />
(MDA); many MTAs have basic MDA functionality built in, but a dedicated MDA like procmail can<br />
provide more sophisticated functionality.</p>
<p>According to one survey, sendmail, Microsoft Exchange Server, Postfix, and Exim together<br />
control over 85% of market share for SMTP service.[citation needed]</p>
<p>Another survey suggests a more balanced playing field, though it included hosted e-mail<br />
services such as Postini.[1]</p>
<p>See also</p>
<p>    * MX record<br />
    * List of mail servers<br />
    * Comparison of mail servers<br />
    * Mail user agent<br />
    * Mail delivery agent<br />
    * SMTP proxy</p>
<p>======================================<br />
   SECURITY /////////////////////////<br />
======================================</p>
<p>======================================<br />
   NAT:<br />
======================================</p>
<p>Network Address Translation (NAT):</p>
<p>An individual on a computer on the private network may point their web browser to a<br />
   site on the internet. This request is recognized to be beyond the local network so<br />
   it is routed to the Linux gateway using the private network address. The request<br />
   for the web page is sent to the web site using the external internet IP address of<br />
   the gateway. The request is returned to the gateway which then translates the IP<br />
   address to computer on the private network which made the request. This is often<br />
   called IP masquerading. The software interface which enables one to configure the<br />
   kernel for masquerading is iptables (Linux kernel 2.4) or ipchains (Linux kernel<br />
   2.2)</p>
<p>The gateway computer will need two IP addresses and network connections, one to the<br />
   private internal network and another to the external public internet.</p>
<p>A note on private network IP addresses: A set of IP addresses has been reserved by<br />
   IANA for private networks. They range from 192.168.0.1 to 192.168.254.254 for a<br />
   typical small business or home network and are often referred to as CIDR private<br />
   network addresses. Most private networks conform to this scheme.</p>
<p>Block</p>
<p>24 bit block in class A<br />
20 bit block in class B<br />
16 bit block in class C</p>
<p>Range</p>
<p>10.0.0.0-10.255.255.255<br />
172.16.0.0-172.31.255.255<br />
192.168.0.0-192.168.255.255</p>
<p>CIDR Notation</p>
<p>10.0.0.0/8<br />
172.16.0.0/12<br />
92.168.0.0/16</p>
<p>Default Subnet Mask</p>
<p>255.0.0.0<br />
255.240.0.0<br />
255.255.0.0</p>
<p>Number of hosts</p>
<p>16,777,216<br />
1,048,576<br />
65,536</p>
<p>The actual number of hosts will be fewer than listed because addresses on each subnet<br />
   will be reserved as a broadcast address, etc.</p>
<p>This is detailed in RFC 1918 - Address Allocation for Private Internets. For a<br />
   description of class A, B, and C networks see the YoLinux Networking Tutorial class<br />
   description.</p>
<p>The private networks may be subdivided into various subnets as desired.</p>
<p>Examples:</p>
<p>Range<br />
   10.2.3.0-10.2.4.255<br />
   172.16.0.0-172.17.255.255<br />
   192.168.5.128-192.168.5.255</p>
<p>CIDR Notation<br />
   10.2.3.0/23<br />
   172.16.0.0/15<br />
   192.168.5.128/25</p>
<p>Default Subnet Mask<br />
   255.255.254.0<br />
   255.254.0.0<br />
   255.255.255.128</p>
<p>Number of hosts<br />
   512<br />
   132608<br />
   128</p>
<p>CertGuide.com: Network Subnets<br />
======================================<br />
   SELINUX:<br />
======================================</p>
<p>A Linux kernel integrating SELinux enforces mandatory access control policies that<br />
   confine user programs and system servers to the minimum amount of privilege they<br />
   require to do their jobs. This reduces or eliminates the ability of these programs<br />
   and daemons to cause harm when compromised (via buffer overflows or<br />
   misconfigurations, for example). This confinement mechanism operates independently<br />
   of the traditional Linux access control mechanisms. It has no concept of a "root"<br />
   super-user, and does not share the well-known shortcomings of the traditional Linux<br />
   security mechanisms (such as a dependence on setuid/setgid binaries).</p>
<p>The security of an unmodified Linux system depends on the correctness of the kernel,<br />
   all the privileged applications, and each of their configurations. A problem in any<br />
   one of these areas may allow the compromise of the entire system. In contrast, the<br />
   security of a modified system based on an SELinux kernel depends primarily on the<br />
   correctness of the kernel and its security policy configuration. While problems<br />
   with the correctness or configuration of applications may allow the limited<br />
   compromise of individual user programs and system daemons, they do not pose a<br />
   threat to the security of other user programs and system daemons or to the security<br />
   of the system as a whole.</p>
<p>From a puristic perspective, SELinux provides a hybrid of concepts and capabilities<br />
   drawn from mandatory access controls, mandatory integrity controls, role-based<br />
   access control (RBAC), and type enforcement architecture. Third-party tools enable<br />
   one to build a variety of security policies.</p>
<p>To determine if you're running the targeted policy, verify the following:</p>
<p>* The file /etc/selinux/config should contain the line SELINUXTYPE=targeted, but note<br />
   that this instructs the computer which policy to use at boot. If you change the<br />
   machine between different policies, leave the SELINUXTYPE variable with a different<br />
   value than the running policy before you reboot.<br />
   * Running the id command should return something similar to</p>
<p>uid=0(root) gid=0(root)<br />
   groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)<br />
   context=root:system_r:unconfined_t</p>
<p>The final part of root's security context tells us that the root shell is running in<br />
   the unconfined_t domain, indicating that the targeted policy is in use. On a system<br />
   running the strict policy a root shell will have the SELinux context of either<br />
   root:staff_r:staff_t or root:sysadm_r:sysadm_t. You can also run the id -Z command<br />
   to see your security context without the Unix UID/GID information (useful for shell<br />
   scripts).</p>
<p>The daemons that have policy written for them will run in their own domains by<br />
   default, but the administrator may configure them to run in the domain unconfined_t<br />
   by specifying that they should not have a domain transition when executed. For<br />
   example the command setsebool -P httpd_disable_trans 0 causes the httpd process to<br />
   run in domain unconfined_t. Every daemon has a boolean to cause it to run in the<br />
   unconfined_t domain. This can be used if the administrator is unable to get it<br />
   working correctly in its own domain (although it is recommended that for best<br />
   security the policy be modified if necessary to permit the daemon in question to<br />
   run in a restrictive domain). Running daemons in the unconfined_t domain in this<br />
   manner reduces the security of the system and should be avoided if possible.</p>
<p>Changing the values of booleans can be done with the setsebool command or with the<br />
   program system-config-securitylevel. When using setsebool make sure you use the -P<br />
   option if you want the change to be preserved across reboots.</p>
<p>To view the values of booleans use the getsebool command. To retrieve the value of a<br />
   single bool specify the name on the command line, for example getsebool<br />
   httpd_disable_trans. To view the values of all booleans use the getsebool -a<br />
   command.</p>
<p>The easiest way of changing the booleans is through the system-config-securitylevel<br />
   command as shown in Figure 1, Change the values of booleans. The httpd server has<br />
   more booleans than most daemons because it is very configurable, and the<br />
   configuration of the SELinux policy needs to match the configuration of the<br />
   daemon.</p>
<p>Probably the most commonly used booleans in the targeted policy will be the ones to<br />
   disable the SELinux protection for daemons that have been configured in a way that<br />
   does not work well with SELinux. We don't recommend that you enable such booleans.<br />
   They are only provided as emergency measures. If business requirements force you to<br />
   run a daemon in a way that SELinux can't restrict, disabling the protection for<br />
   that daemon is much better than disabling it for the entire system.</p>
<p>The policy files for the daemons when using the targeted policy is located in the<br />
   /etc/selinux/targeted/src/policy/domains/program/ directory. The policy source<br />
   files are commonly known as .te files which represent the naming convention such as<br />
   syslogd.te.</p>
<p>A policy, or .te file, contains the rules for the associated domain. The syslogd.te<br />
   file, for instance, defines the rules for the operation of the domain syslogd_t<br />
   including operations such as logging to the console, modification and creation of<br />
   log files, and remote logging, to name a few.</p>
<p>The policy file must match the file contexts, or .fc file located in<br />
   /etc/selinux/targeted/src/policy/file_contexts/program/. File contexts files list<br />
   the security contexts which must be applied to files and directories that the<br />
   daemon uses. For example, the file named.fc contains:</p>
<p>/var/named(/.*)? system_u:object_r:named_zone_t<br />
   /var/named/data(/.*)? system_u:object_r:named_cache_t</p>
<p>The first line tells us that the /var/named/ directory is of the type named_zone_t.<br />
   The second line tells us that the /var/named/data/ directory has the type<br />
   named_cache_t.</p>
<p>/usr/sbin/named -- system_u:object_r:named_exec_t</p>
<p>Tells us that the named executable is of type named_exec_t. The naming convention for<br />
   daemon entry point executables is X_exec_t where X is the name of the daemon<br />
   domain.</p>
<p>This causes a transition from the domain unconfined_t to the daemon domain (named_t<br />
   in this example) when the daemon is executed. When using the strict policy daemons<br />
   have to be started from an administrative session (role sysadm_r and domain<br />
   sysadm_t) for correct operation. With the targeted policy, this is not an issue as<br />
   unconfined_t is the only domain used for user logins (either administrator or a<br />
   regular user).</p>
<p>The main policy file for named is named.te which contains the rules to permit access<br />
   to the named_t domain as well as to define the domain and cause transitions to it.<br />
   The most significant line in named.te is:</p>
<p>daemon_domain(named, `, nscd_client_domain')</p>
<p>This defines the domain named_t and permits it to perform all the basic operations<br />
   that daemons perform such as writing a pid file to /var/run, forking a child<br />
   process, logging to syslog, etc. It also has policy to cause an automatic domain<br />
   transition from unconfined_t to named_t when an executable of type named_exec_t is<br />
   executed.<br />
   Objectives of the Targeted Policy</p>
<p>The targeted policy was developed because the strict policy was considered to be too<br />
   difficult for many system administrators to manage. When SELinux was initially<br />
   introduced into Fedora Core 2, there was some negative feedback about the ease of<br />
   use. With the release of Fedora Core 3, the targeted policy was the default, and<br />
   there were very few complaints. Common estimates suggest that at least two million<br />
   people are using Fedora Core 3 without even realizing that they are using SELinux.<br />
   Their machine does what they want it to do, and they don't notice that daemons are<br />
   not permitted to perform certain operations those operations are not performed by<br />
   daemons in the normal operation of a system with a typical configuration.</p>
<p>The general aim of policy development is that the strict policy will become easier to<br />
   configure and better tuned for default configurations while the targeted policy<br />
   will get an increasing number of targets to support more daemons. Through these<br />
   developments the targeted and strict policies can be considered to be converging as<br />
   the strict policy becomes easier to use and the targeted policy becomes more<br />
   strict. But it seems unlikely that we will be able to merge the policies in the<br />
   foreseeable future. The fundamental difference between strict and targeted is that<br />
   strict uses the identity and role features of SELinux while targeted does not.</p>
<p>Some of the usability features of the targeted policy derive from many of the daemons<br />
   running in the unconfined_t domain. Eventually we hope to get most of the daemons<br />
   in question working well in more restrictive domains. The main benefit, however, in<br />
   terms of the usability of the targeted policy is in the lack of restrictive domains<br />
   for user sessions. It seems likely that the demand for this feature will exist for<br />
   a long time. Therefore merging the strict and targeted policies will not be<br />
   possible.<br />
   Supported configuration changes</p>
<p>Within the targeted policy, significant changes will break the support agreement for<br />
   Red Hat Enterprise Linux. This means modifying the policy for daemons (particularly<br />
   if such changes involve reducing access) and adding new domains for programs that<br />
   are part of Red Hat Enterprise Linux. Adding new changes for programs that are not<br />
   part of Red Hat Enterprise Linux may be OK as long as any bugs which are reported<br />
   do not concern the programs in question.</p>
<p>If you go outside the supported configuration either through excessive changes to the<br />
   targeted policy or through using the strict policy, support for SELinux features<br />
   will be provided through GPS (Red Hat consulting). For support on issues unrelated<br />
   to SELinux you may have to put SELinux in permissive mode when reporting problems.<br />
   Strict policy support</p>
<p>The Red Hat Enterprise Linux 4 release only contains the policy packages for the<br />
   targeted policy because it is the only policy supported through the Global Support<br />
   Services.</p>
<p>Packages for the strict policy will be available on the Red Hat website for<br />
   organizations that have a policy of having all their system software come from the<br />
   one source. They can get the strict policy from Red Hat, it just won't be supported<br />
   through the usual support processes Anyone who wants to run SELinux on a Red Hat<br />
   Enterprise Linux 4 system will be able to download the package<br />
   selinux-policy-strict (and selinux-policy-strict-sources if they want to modify the<br />
   policy source) and convert their system to the strict policy.</p>
<p>To convert a Fedora or Red Hat Enterprise Linux 4 system to the strict policy you<br />
   only have to install the strict policy package and run system-config-securitylevel<br />
   in an X session. You will then see a tab to configure SELinux. The SELinux tab<br />
   features a drop-down list box that allows you to select between the installed<br />
   policies as shown in Figure 2, Select between installed policies.</p>
<p>After selecting this option, you should reboot the machine at the earliest convenient<br />
   time. Early in the boot process the script /etc/rc.sysinit will relabel the file<br />
   system with the correct labels for the new policy type. Currently the configuration<br />
   file /etc/selinux/config has one field for which type of policy is to be used,<br />
   indicating which will be used on the next boot. The same field is used by some<br />
   applications to determine which policy is currently running. So in the period<br />
   between changing the policy through system-config-securitylevel and rebooting to<br />
   apply the change, some programs may not operate in the desired manner as their idea<br />
   of the running policy will not match reality. This is not a security issue as they<br />
   will fail closed, but it may be a usability issue. One consequence of having the<br />
   running policy not match the policy that is configured for the next boot is that<br />
   cron jobs will not run.</p>
<p>The process of relabeling the file system involves comparing the fully qualified path<br />
   name of each file on the system with a set of regular expressions such that the<br />
   best match will indicate which security context should be assigned to the file.<br />
   Thus the file system relabel process involved with converting between strict and<br />
   targeted policies. This process will take at least as much time as find / and maybe<br />
   as much as twice that due to the amount of computation taken for regular<br />
   expressions. With a typical Red Hat Enterprise Linux or Fedora install on modern<br />
   hardware this should only take a few minutes. If you have many of your own files<br />
   installed then it will take proportionally longer.</p>
<p>If you have a server with millions of files with the same security context on their<br />
   own file system, then it's best to use the context mount option to label them. This<br />
   saves the time taken for a relabel and also saves the storage requirements for the<br />
   security labels. For example the Squid cache files are labeled as<br />
   system_u:object_r:squid_cache_t. If you had a large Squid server with a file system<br />
   devoted to Squid, then you could put fscontext=system_u:object_r:squid_cache_t in<br />
   the file system options field in the /etc/fstab file.</p>
<p>Red Hat Enterprise Linux 4 systems which use the strict policy will only be supported<br />
   for non-SE functionality. Customers who make such modifications to their systems<br />
   may be requested to put SELinux in permissive mode and reproduce the problem when<br />
   making a support call for issues that are not directly related to SELinux.<br />
   Permissive mode is when SELinux reports that it would not permit an operation but<br />
   does not actually prevent the operation from occurring. Permissive mode is used for<br />
   development of SELinux policies and for many types of testing. To quickly determine<br />
   whether SELinux is the cause of a problem it can be put in permissive mode by the<br />
   command setenforce 0 and then put back in enforcing mode with setenforce 1 after<br />
   the test is complete. Note that it is not recommended that you put a production<br />
   machine into permissive mode.</p>
<p>At this time support for the strict policy is only provided through GPS (the Red Hat<br />
   consulting division). The regular support channels will not accept calls about it,<br />
   and the guarantees about response time also do not apply. The strict policy is not<br />
   on the Red Hat Enterprise Linux 4 CDs and is officially not part of the<br />
   distribution.</p>
<p>The /etc/selinux/ directory</p>
<p>In Fedora Core 3 the SELinux base directory was changed to /etc/selinux/, and this is<br />
   the location that is used for Red Hat Enterprise Linux 4 and will be used for all<br />
   future releases. In the directory /etc/selinux/targeted/ you will find the files<br />
   for the targeted policy. If you are running the strict policy, you will have the<br />
   /etc/selinux/strict/ directory. By default, the policy sources are not installed.<br />
   To install the policy sources, you need the selinux-policy-targeted-sources package<br />
   (if running the strict policy, you - need the selinux-policy-strict-sources<br />
   package). The installation of this package results in the<br />
   /etc/selinux/targeted/src/ (or strict/src/) directory being installed. Here (under<br />
   the policy directory) you will find the policy source.<br />
   User roles in the targeted policy</p>
<p>Under the targeted policy, there is no real use of user roles and domains. All user<br />
   identities are permitted to use the role system_r, and thus identities and roles<br />
   play no part in SELinux access control. Under the strict policy, every user who is<br />
   significant to the system security policy (one category of which is users who are<br />
   granted administrative rights) needs an entry in the users file to specify the<br />
   roles which they are permitted to assume. With the targeted policy this aspect of<br />
   policy configuration is not needed.<br />
   Development of other policies</p>
<p>The design of SELinux has all configuration options in the SELinux policy, and no<br />
   configuration options are compiled into binaries. This means that the complete<br />
   configuration of SELinux can be changed without changing any programs.<br />
   Administrators of Red Hat Enterprise Linux 4 systems are free to build their own<br />
   policy that is not based on either the strict or targeted policies. But again, this<br />
   would be outside the Red Hat Enterprise Linux 4 support contracts.</p>
<p>======================================<br />
   SUDO:<br />
======================================</p>
<p> Before we proceed, it would be best to cover some basic user administration topics<br />
  that will be very useful in later chapters. Adding Users  </p>
<p>One of the most important activities in administering a Linux box is the addition of<br />
  users. Here you'll find some simple examples to provide a foundation for future<br />
  chapters. It is not intended to be comprehensive, but is a good memory refresher.<br />
  You can use the command man useradd to get the help pages on adding users with the<br />
  useradd command or the man usermod to become more familiar with modifying users<br />
  with the usermod command.</p>
<p>Who Is the Super User?  </p>
<p>The super user with unrestricted access to all system resources and files in Linux is<br />
  the user named root. This user has a user ID, of 0 which is universally identified<br />
  by Linux applications as belonging to a user with supreme privileges. You will need<br />
  to log in as user root to add new users to your Linux server.  </p>
<p>Debian Note: When installing Ubuntu Linux systems, you are prompted to create a<br />
  primary user that is not root. A root user is created but no password is set, so<br />
  you initially cannot log in as this user. The primary user can become the root user<br />
  using the sudo su - command that will be discussed later.</p>
<p>How To Add Users  </p>
<p>Adding users takes some planning; read through these steps below before starting:  </p>
<p>1) Arrange your list of users into groups by function. In this example there are<br />
  three groups "parents", "children" and "soho".  </p>
<p>Parents    Children    Soho  </p>
<p>Paul       Alice       Accounts<br />
Jane       Derek       Sales  </p>
<p>2) Add the Linux groups to your server:  </p>
<p>[root@bigboy tmp]# groupadd parents<br />
[root@bigboy tmp]# groupadd children<br />
[root@bigboy tmp]# groupadd soho  </p>
<p>3) Add the Linux users and assign them to their respective groups  </p>
<p>[root@bigboy tmp]# useradd -g parents paul<br />
[root@bigboy tmp]# useradd -g parents jane<br />
[root@bigboy tmp]# useradd -g children derek<br />
[root@bigboy tmp]# useradd -g children alice<br />
[root@bigboy tmp]# useradd -g soho accounts<br />
[root@bigboy tmp]# useradd -g soho sales  </p>
<p>If you don't specify the group with the -g, RedHat/Fedora Linux creates a group with<br />
  the same name as the user you just created; this is also known as the User Private<br />
  Group Scheme. When each new user first logs in, they are prompted for their new<br />
  permanent password.  </p>
<p>4) Each user's personal directory is placed in the /home directory. The directory<br />
  name will be the same as their user name.  </p>
<p>[root@bigboy tmp]# ll /home<br />
drwxr-xr-x    2 root     root        12288 Jul 24 20:04 lost+found<br />
drwx------    2 accounts soho         1024 Jul 24 20:33 accounts<br />
drwx------    2 alice    children     1024 Jul 24 20:33 alice<br />
drwx------    2 derek    children     1024 Jul 24 20:33 derek<br />
drwx------    2 jane     parents      1024 Jul 24 20:33 jane<br />
drwx------    2 paul     parents      1024 Jul 24 20:33 paul<br />
drwx------    2 sales    soho         1024 Jul 24 20:33 sales<br />
[root@bigboy tmp]#  </p>
<p>How to Change Passwords  </p>
<p>You need to create passwords for each account. This is done with the passwd command.<br />
  You are prompted once for your old password and twice for the new one.  </p>
<p>    * User root changing the password for user paul.   </p>
<p>[root@bigboy root]# passwd paul<br />
Changing password for user paul.<br />
New password:<br />
Retype new password:<br />
passwd: all authentication tokens updated successfully.<br />
[root@bigboy root]#  </p>
<p>    * Users might wish to change their passwords at a future date. Here is how<br />
      unprivileged user paul would change his own password.   </p>
<p>[paul@bigboy paul]$ passwd<br />
Changing password for paul<br />
Old password: your current password<br />
Enter the new password (minimum of 5, maximum of 8 characters)<br />
Please use a combination of upper and lower case letters and numbers.<br />
New password: your new password<br />
Re-enter new password: your new password<br />
Password changed.<br />
[paul@bigboy paul]$  </p>
<p>How to Delete Users  </p>
<p>The userdel command is used to remove the user's record from the /etc/passwd and<br />
  /etc/shadow used in the login process. The command has a single argument, the<br />
  username.  </p>
<p>[root@bigboy tmp]# userdel paul  </p>
<p>There is also an optional -r switch that additionally removes all the contents of the<br />
  user's home directory. Use this option with care. The data in a user's directory<br />
  can often be important even after the person has left your company.  </p>
<p>[root@bigboy tmp]# userdel -r paul  </p>
<p>How to Tell the Groups to Which a User Belongs  </p>
<p>Use the groups command with the username as the argument.  </p>
<p>[root@bigboy root]# groups paul<br />
paul : parents<br />
[root@bigboy root]#  </p>
<p>How to Change the Ownership of a File  </p>
<p>You can change the ownership of a file with the chown command. The first argument is<br />
  the desired username and group ownership for the file separated by a colon (:)<br />
  followed by the filename. In the next example we change the ownership of the file<br />
  named text.txt from being owned by user root and group root to being owned by user<br />
  testuser in the group users:  </p>
<p>[root@bigboy tmp]# ll test.txt<br />
-rw-r--r--  1 root root 0 Nov 17 22:14 test.txt<br />
[root@bigboy tmp]# chown testuser:users test.txt<br />
[root@bigboy tmp]# ll test.txt<br />
-rw-r--r--  1 testuser users 0 Nov 17 22:14 test.txt<br />
[root@bigboy tmp]#  </p>
<p>You can also use the chown command with the -r switch for it to doe recursive<br />
  searches down into directories to change permissions.  </p>
<p>Using sudo  </p>
<p>If a server needs to be administered by a number of people it is normally not a good<br />
  idea for them all to use the root account. This is because it becomes difficult to<br />
  determine exactly who did what, when and where if everyone logs in with the same<br />
  credentials. The sudo utility was designed to overcome this difficulty.  </p>
<p>The sudo utility allows users defined in the /etc/sudoers configuration file to have<br />
  temporary access to run commands they would not normally be able to due to file<br />
  permission restrictions. The commands can be run as user "root" or as any other<br />
  user defined in the /etc/sudoers configuration file.  </p>
<p>The privileged command you want to run must first begin with the word sudo followed<br />
  by the command's regular syntax. When running the command with the sudo prefix, you<br />
  will be prompted for your regular password before it is executed. You may run other<br />
  privileged commands using sudo within a five-minute period without being<br />
  re-prompted for a password. All commands run as sudo are logged in the log file<br />
  /var/log/messages.  </p>
<p>Simple Sudo Examples  </p>
<p>Using sudo is relatively simple as we can see from these examples.<br />
Temporarily Gaining root Privileges  </p>
<p>In this example, user bob attempts to view the contents of the /etc/sudoers file,<br />
  which is an action that normally requires privileged access. Without sudo, the<br />
  command fails:  </p>
<p>[bob@bigboy bob]$ more /etc/sudoers<br />
/etc/sudoers: Permission denied<br />
[bob@bigboy bob]$  </p>
<p>Bob tries again using sudo and his regular user password and is successful:  </p>
<p>[bob@bigboy bob]$ sudo more /etc/sudoers<br />
Password:<br />
...<br />
...<br />
[bob@bigboy bob]$  </p>
<p>The details of configuring and installing sudo are covered in later sections.<br />
Becoming root for a Complete Login Session  </p>
<p>The su command allows a regular user to become the system's root user if they know<br />
  the root password. A user with sudo rights to use the su command can become root,<br />
  but they only need to know their own password, not that of root as seen here.  </p>
<p>someuser@u-bigboy:~$ sudo su -<br />
Password:<br />
root@u-bigboy:~#  </p>
<p>Some systems administrators will use sudo to grant root privileges to their own<br />
  personal user account without the need to provide a password.  </p>
<p>Later sections describe how to disable sudo su ability and also how to use sudo<br />
  without password prompts.<br />
Downloading and Installing the sudo Package  </p>
<p>Fortunately the package is installed by default by RedHat/Fedora which eliminates the<br />
  need to anything more in this regard. The visudo Command  </p>
<p>The visudo command is a text editor that mimics the vi editor that is used to edit<br />
  the /etc/sudoers configuration file. It is not recommended that you use any other<br />
  editor to modify your sudo parameters because the sudoers file isn't located in the<br />
  same directory on all versions of Linux. visudo uses the same commands as the vi<br />
  text editor. The visudo command must run as user root and should have no<br />
  arguments:  </p>
<p>[root@aqua tmp]# visudo  </p>
<p>The /etc/sudoers File  </p>
<p>The /etc/sudoers file contains all the configuration and permission parameters needed<br />
  for sudo to work. There are a number of guidelines that need to be followed when<br />
  editing it with visudo. General /etc/sudoers Guidelines  </p>
<p>The /etc/sudoers file has the general format shown in Table 9-1.  </p>
<p>Table 9-1 Format of the /etc/sudoers File  </p>
<p>General sudoers File Record Format  </p>
<p>usernames/group servername = (usernames command can be run as) command  </p>
<p>There are some general guidelines when editing this file:  </p>
<p>    * Groups are the same as user groups and are differentiated from regular users by<br />
      a % at the beginning. The Linux user group "users" would be represented by<br />
      %users.<br />
    * You can have multiple usernames per line separated by commas.<br />
    * Multiple commands also can be separated by commas. Spaces are considered part<br />
      of the command.<br />
    * The keyword ALL can mean all usernames, groups, commands and servers.<br />
    * If you run out of space on a line, you can end it with a back slash (\) and<br />
      continue on the next line.<br />
    * sudo assumes that the sudoers file will be used network wide, and therefore<br />
      offers the option to specify the names of servers which will be using it in the<br />
      servername position in Table 9-1. In most cases, the file is used by only one<br />
      server and the keyword ALL suffices for the server name.<br />
    * The NOPASSWD keyword provides access without prompting for your password.   </p>
<p>Simple /etc/sudoers Examples  </p>
<p>This section presents some simple examples of how to do many commonly required tasks<br />
  using the sudo utility.</p>
<p>Granting All Access to Specific Users  </p>
<p>You can grant users bob and bunny full access to all privileged commands, with this<br />
  sudoers entry.  </p>
<p>bob, bunny  ALL=(ALL) ALL  </p>
<p>This is generally not a good idea because this allows bob and bunny to use the su<br />
  command to grant themselves permanent root privileges thereby bypassing the command<br />
  logging features of sudo. The example on using aliases in the sudoers file shows<br />
  how to eliminate this problem</p>
<p>Granting Access To Specific Users To Specific Files  </p>
<p>This entry allows user peter and all the members of the group operator to gain access<br />
  to all the program files in the /sbin and /usr/sbin directories, plus the privilege<br />
  of running the command /usr/local/apps/check.pl. Notice how the trailing slash (/)<br />
  is required to specify a directory location:  </p>
<p>peter, %operator ALL= /sbin/, /usr/sbin, /usr/local/apps/check.pl  </p>
<p>Notice also that the lack of any username entries within parentheses () after the =<br />
  sign prevents the users from running the commands automatically masquerading as<br />
  another user. This is explained further in the next example. </p>
<p>Granting Access to Specific Files as Another User  </p>
<p>The sudo -u entry allows allows you to execute a command as if you were another user,<br />
  but first you have to be granted this privilege in the sudoers file.  </p>
<p>This feature can be convenient for programmers who sometimes need to kill processes<br />
  related to projects they are working on. For example, programmer peter is on the<br />
  team developing a financial package that runs a program called monthend as user<br />
  accounts. From time to time the application fails, requiring "peter" to stop it<br />
  with the /bin/kill, /usr/bin/kill or /usr/bin/pkill commands but only as user<br />
  "accounts". The sudoers entry would look like this:  </p>
<p>peter ALL=(accounts) /bin/kill, /usr/bin/kill, /usr/bin/pkill  </p>
<p>User peter is allowed to stop the monthend process with this command:  </p>
<p>[peter@bigboy peter]# sudo -u accounts pkill monthend  </p>
<p>Granting Access Without Needing Passwords  </p>
<p>This example allows all users in the group operator to execute all the commands in<br />
  the /sbin directory without the need for entering a password. This has the added<br />
  advantage of being more convenient to the user:  </p>
<p>%operator ALL= NOPASSWD: /sbin/  </p>
<p>Using Aliases in the sudoers File  </p>
<p>Sometimes you'll need to assign random groupings of users from various departments<br />
  very similar sets of privileges. The sudoers file allows users to be grouped<br />
  according to function with the group and then being assigned a nickname or alias<br />
  which is used throughout the rest of the file. Groupings of commands can also be<br />
  assigned aliases too.  </p>
<p>In the next example, users peter, bob and bunny and all the users in the operator<br />
  group are made part of the user alias ADMINS. All the command shell programs are<br />
  then assigned to the command alias SHELLS. Users ADMINS are then denied the option<br />
  of running any SHELLS commands and su:  </p>
<p>Cmnd_Alias    SHELLS = /usr/bin/sh,  /usr/bin/csh, \<br />
                       /usr/bin/ksh, /usr/local/bin/tcsh, \<br />
                       /usr/bin/rsh, /usr/local/bin/zsh  </p>
<p>User_Alias    ADMINS = peter, bob, bunny, %operator<br />
ADMINS        ALL    = !/usr/bin/su, !SHELLS  </p>
<p>This attempts to ensure that users don't permanently su to become root, or enter<br />
  command shells that bypass sudo's command logging. It doesn't prevent them from<br />
  copying the files to other locations to be run. The advantage of this is that it<br />
  helps to create an audit trail, but the restrictions can be enforced only as part<br />
  of the company's overall security policy.<br />
Other Examples  </p>
<p>You can view a comprehensive list of /etc/sudoers file options by issuing the command<br />
  man sudoers.<br />
Using syslog To Track All sudo Commands  </p>
<p>All sudo commands are logged in the log file /var/log/messages which can be very<br />
  helpful in determining how user error may have contributed to a problem. All the<br />
  sudo log entries have the word sudo in them, so you can easily get a thread of<br />
  commands used by using the grep command to selectively filter the output<br />
  accordingly.  </p>
<p>Here is sample output from a user bob failing to enter their correct sudo password<br />
  when issuing a command, immediately followed by the successful execution of the<br />
  command /bin/more sudoers.  </p>
<p>[root@bigboy tmp]# grep sudo /var/log/messages<br />
 Nov 18 22:50:30 bigboy sudo(pam_unix)[26812]: authentication failure;<br />
 logname=bob uid=0 euid=0 tty=pts/0 ruser= rhost= user=bob<br />
 Nov 18 22:51:25 bigboy sudo: bob : TTY=pts/0 ; PWD=/etc ;<br />
 USER=root ; COMMAND=/bin/more sudoers<br />
 [root@bigboy tmp]#  </p>
<p>Conclusion  </p>
<p>It is important to know how to add users, not just so they can log in to our system.<br />
  Most server based applications usually run via a dedicated unprivileged user<br />
  account, for example the MySQL database application runs as user mysql and the<br />
  Apache Web server application runs as user apache. These accounts aren't always<br />
  created automatically, especially if the software is installed using TAR files.  </p>
<p>Finally, the sudo utility provides a means of dispersing the responsibility of<br />
  systems management to multiple users. You can even give some groups of users only<br />
  partial access to privileged commands depending on their roles in the organization.<br />
  This makes sudo a valuable part of any company's server administration and security<br />
  policy.</p>
<p>======================================<br />
SSH:<br />
======================================  </p>
<p>SSH uses public-key cryptography to authenticate the remote computer and allow the<br />
  remote computer to authenticate the user, if necessary.[1]  </p>
<p>SSH is typically used to log into a remote machine and execute commands, but it also<br />
  supports tunneling, forwarding TCP ports and X11 connections; it can transfer files<br />
  using the associated SFTP or SCP protocols.[1] SSH uses the client-server model.  </p>
<p>An SSH server, by default, listens on the standard TCP port 22.[3]  </p>
<p>An SSH client program is typically used for establishing connections to an SSH daemon<br />
  accepting remote connections. Both are commonly present on most modern operating<br />
  systems, including Mac OS X, Linux, FreeBSD, Solaris and OpenVMS. Proprietary,<br />
  freeware and open source versions of various levels of complexity and completeness<br />
  exist.  </p>
<p>Generate Trusted Keys:  </p>
<p>ssh-keygen -t dsa<br />
Generating public/private dsa key pair.<br />
Enter file in which to save the key (/home/localuser/.ssh/id_dsa):<br />
Enter passphrase (empty for no passphrase):<br />
Enter same passphrase again:<br />
Your identification has been saved in /home/localuser/.ssh/id_dsa.<br />
Your public key has been saved in /home/localuser/.ssh/id_dsa.pub.<br />
The key fingerprint is: 93:58:20:56:72:d7:bd:14:86:9f:42:aa:82:3d:f8:e5 localuser<br />
Administrator@helios ~/.ssh scp ~/.ssh/id_dsa.pub root@sirius:.ssh/authorized_keys<br />
The authenticity of host 'sirius (192.168.1.4)' can't be established.<br />
RSA key fingerprint is 39:ba:5c:9d:a9:05:fa:f2:ba:67:bd:d5:9e:f1:95:8c.<br />
Are you sure you want to continue connecting (yes/no)? yes<br />
Warning: Permanently added 'sirius' (RSA) to the list of known hosts.<br />
Warning: the RSA host key for 'sirius' differs from the key for the IP address<br />
  '192.168.1.4'<br />
Offending key for IP in /home/Administrator/.ssh/known_hosts:1<br />
Are you sure you want to continue connecting (yes/no)? yes<br />
Password:<br />
id_dsa.pub  </p>
<p>Copy File From Server:<br />
Administrator@helios ~<br />
$ scp root@vega:install.log .<br />
install.log 100% 25KB 25.4KB/s 00:00  </p>
<p>Copy File to Server:  </p>
<p>Administrator@helios ~<br />
$ scp ./rotatelog.zip root@vega:<br />
rotatelog.zip 100% 6658 6.5KB/s 00:00  </p>
<p>NOTE: Notice I didn't need to authenticate since I had already copied the trusted<br />
  keys I generated over to root on Vega's ~/.ssh directory.  </p>
<p>======================================<br />
HARDENING:<br />
======================================  </p>
<p>======================================<br />
FIREWALL:<br />
======================================  </p>
<p>======================================<br />
   IPCHAINS / IPTABLES:<br />
======================================</p>
<p>Firewall versions vs Linux versions:</p>
<p>Note: References to ipfwadm and ipchains refer to older deprecated software.</p>
<p>Command<br />
   =======<br />
   iptables<br />
   ipchains<br />
   ipfwadm</p>
<p>Kernel Ver.<br />
   ===========<br />
   2.4.x, 2.6.x<br />
   2.2.x<br />
   2.0.x</p>
<p>Red Hat Version<br />
   ===============<br />
   7.1 - 9.0, Fedora 1,2,3<br />
   6.x, 7.0<br />
   5.x</p>
<p>Note: Red Hat 7.1-9.0 and the default Linux 2.4 kernel may use ipchains or iptables<br />
   but not both. Iptables is the preferred firewall as it supports "state" and can<br />
   recognize if a network connection has already been "ESTABLISHED" or if the<br />
   connection is related to the previous connection (required for ftp which makes<br />
   multiple connections on different ports). Ipchains can not. Ipchain rules take<br />
   precedence over iptables rules. During system boot, the kernel attempts to activate<br />
   ipchains, then attempts to activate iptables. If ipchain rules have been activated,<br />
   the kernel will not start iptables.</p>
<p>Red Hat 7.1 will not support ipchains unless that option is configured (during<br />
   install or later). If during install you select "Disable Firewall - no protection"<br />
   then ipchains will not be available and you must rely upon iptables for a manual<br />
   firewall configuration. (iptables only. ipchains will be unavailable)</p>
<p>GUI configuration:</p>
<p>* iptables: The GUI configuration tool /usr/bin/redhat-config-securitylevel can be<br />
   used to choose a preconfigured firewall (High, Medium or no firewall) or it can be<br />
   used to manually configure rules based on the network services your server will<br />
   offer. The init script /etc/rc.d/init.d/iptables will use rules stored in<br />
   /etc/sysconfig/iptables.</p>
<p>   * ipchains: The tool that does this is lokkit (or /usr/bin/gnome-lokkit), which uses<br />
   ipchains to configure firewall options for High and Low security options. To<br />
   support ipchains after install, run /usr/bin/gnome-lokkit and configure a firewall.<br />
   It will configure ipchains to activate the firewall. Lokkit will generate the file<br />
   /etc/sysconfig/ipchains. (Used by init script /etc/rc.d/init.d/ipchains which calls<br />
   /sbin/ipchains-restore)</p>
<p>To see if ipchains and the Lokkit configuration is invoked during system boot, use<br />
   the command:</p>
<p>chkconfig --list | grep ipchains</p>
<p>The default Red Hat 7.1+ Linux 2.4 kernel is compiled to support both iptables and<br />
   ipchains. Kernel support for ipchains is available during a kernel configuration<br />
   and compilation. During make xconfig or make menuconfig turn on the feature: "IP:<br />
   Netfilter Configuration" + "ipchains (2.2-style) support".</p>
<p>Check your installation by using the command: rpm -q iptables ipchains<br />
   These packages must be installed. The commands iptables and ipchains are the command<br />
   interfaces to configure kernel firewall rules. The default Red Hat 7.1 kernel<br />
   supports iptables and ipchains. (But not both at the same time.)</p>
<p>[Potential Pitfall]: When performing an upgrade instead of a new install, the upgrade<br />
   software will not install iptables as did not exist on the system previously. It<br />
   will perform an upgrade to a newer version of ipchains. If you wish to use<br />
   iptables, you must manually install the iptables RPM.<br />
   i.e.: rpm -ivh iptables-XXX.i386.rpm</p>
<p>[Potential Pitfall]: The Linux operating system kernel may load or not load what you<br />
   had expected. Use the command lsmod to see if ip_tables or ip_chains were loaded.</p>
<p>Switching a running system from ipchains to iptables: (Red Hat 7.1-9.0 - Linux kernel<br />
   2.4 specific)</p>
<p>Sequence 1<br />
   Command chkconfig --del ipchains<br />
   Description Remove ipchains from system boot/initialization process</p>
<p>Sequence 2<br />
   Command chkconfig --add iptables<br />
   Description Add iptables to system boot/initialization process</p>
<p>Sequence 3<br />
   Command ipchains -F<br />
   Description Flush ipchains rules</p>
<p>Sequence 4<br />
   Command service ipchains stop<br />
   Description Stop ipchains. Also: /etc/init.d/ipchains stop</p>
<p>Sequence 5<br />
   Command rmmod ipchains<br />
   Description Unload ipchains kernel module. Iptables kernel module can not be loaded<br />
   if the ipchains module is loaded.</p>
<p>Sequence 6<br />
   Command service iptables start<br />
   Description Load iptables kernel module. Also: /etc/init.d/iptables stop</p>
<p>======================================<br />
   STORAGE///////////////////////////<br />
======================================</p>
<p>====================================<br />
   SOLARIS DISK COMMANDS:<br />
====================================</p>
<p>/bin/mount -F hsfs -o ro /dev/sr0 /cdrom</p>
<p>/* Mount an ISO 9660 CDROM */<br />
=======================================</p>
<p>/usr/bin/iostat -E</p>
<p>/* Command to display drives statistics */<br />
=======================================</p>
<p>du -ad /var | sort -nr</p>
<p>/* Report the the disk used in /var in reverse order */<br />
=======================================</p>
<p>du -k .</p>
<p>/* Report disk usage in Kilobytes */<br />
=======================================</p>
<p>du -sk * | sort -nr | head</p>
<p>/* Shows the top ten largest files/directories */<br />
=======================================</p>
<p>du -sk *|sort -k1,1n</p>
<p>/* Reports total disk space used in Kilobytes in present directory */<br />
=======================================</p>
<p>du -sk .</p>
<p>/* Report total disk usage in Kilobytes */<br />
=======================================</p>
<p>fdformat -d -U</p>
<p>/* Format diskette */<br />
=======================================</p>
<p>mount -F hsfs -o ro `lofiadm -a /export/temp/software.iso` /mnt</p>
<p>/* Mount an ISO Image */<br />
=======================================</p>
<p>newfs -Nv /dev/rdsk/c0t0d0s1</p>
<p>/* To view the superfblocks available */<br />
=======================================</p>
<p>One-liner to copy a partition table</p>
<p>/* prtvtoc /dev/dsk/c1t2d0s2 | fmthard -s - /dev/rdsk/c1t3d0s2 */<br />
=======================================</p>
<p>prtvtoc /dev/rdsk/c0t0d0s2</p>
<p>/* Disk geometry and partitioning info */<br />
=======================================</p>
<p>prtvtoc /dev/rdsk/c0t0d0s2 | fmthard -s - /dev/rdsk/c0t1d0s2</p>
<p>/* Copy partition table from one disk to another */<br />
=======================================</p>
<p>quot -af</p>
<p>/* How much space is used by users in kilobytes */<br />
=======================================</p>
<p>volrmmount -i floppy</p>
<p>/* Mount a floppy or other media easily by its nickname. */<br />
=======================================</p>
<p>Driver Parameters</p>
<p>ndd /dev/ip ip_forwarding</p>
<p>/* Show the ip_forwarding variable in the kernel */<br />
=======================================</p>
<p>ndd /dev/ip ip_forwarding 1</p>
<p>/* Set the ip_forwarding variable in the kernel */<br />
=======================================</p>
<p>ndd /dev/ip \?</p>
<p>/* Show all IP variables set in the kernel */<br />
======================================</p>
<p>======================================<br />
   LUN:<br />
======================================</p>
<p>(Logical Unit Number) An identification scheme for storage disks that typically<br />
   supports a small number of units addressed as LUN 0 through 7, 15 or 31 depending<br />
   on the technology. For example, Fibre Channel supports 32 addresses (0-31). A LUN<br />
   may refer to a single disk, a subset of a single disk or an array of disks. Derived<br />
   from the SCSI bus technology, each SCSI ID address can be further subdivided into<br />
   LUNs 0 through 15 for disk arrays and libraries. See SCSI.</p>
<p>======================================<br />
   iSCSI<br />
======================================</p>
<p>By carrying SCSI commands over IP networks, iSCSI is used to facilitate data<br />
   transfers over intranets and to manage storage over long distances. The iSCSI<br />
   protocol is among the key technologies expected to help bring about rapid<br />
   development of the storage area network (SAN) market, by increasing the<br />
   capabilities and performance of storage data transmission. Because of the ubiquity<br />
   of IP networks, iSCSI can be used to transmit data over local area networks (LANs),<br />
   wide area networks (WANs), or the Internet and can enable location-independent data<br />
   storage and retrieval.</p>
<p>======================================<br />
   SAN<br />
======================================<br />
   How do you make a LUN visible to a host on a SAN?~<br />
======================================<br />
   SAN Solaris:<br />
======================================</p>
<p>Ensuring That LUN Level Information Is Visible<br />
   To Ensure LUN Level Information is Visible</p>
<p>Use the cfgadm command to identify LUN level information.</p>
<p>If you issue the cfgadm -al -o show_SCSI_LUN controller-ID command immediately after<br />
   a system boots up, the output might not show the Fibre Channel Protocol (FCP) SCSI<br />
   LUN level information. The information does not appear because the storage device<br />
   drivers, such as the ssd and st driver, are not loaded on the running system.</p>
<p>Use the modinfo command to check whether the drivers are loaded. After the drivers<br />
   are loaded, the LUN level information is visible in the cfgadm output.<br />
   To Detect Fabric Devices Visible on a Host</p>
<p>This section provides an example of the procedure for detecting fabric devices using<br />
   FC host ports c0 and c1. This procedure also shows the device configuration<br />
   information that is displayed with the cfgadm(1M) command.<br />
   Note:</p>
<p>In the following examples, only failover path attachment point IDs (Ap_Ids) are<br />
   listed. The Ap_Ids displayed on your system depend on your system configuration.</p>
<p>Log in as root (su - root)..</p>
<p>Display the information about the attachment points on the system.<br />
   # cfgadm -l<br />
   Ap_Id Type Receptacle Occupant Condition<br />
   c0 fc-fabric connected unconfigured unknown<br />
   c1 fc-private connected configured unknown</p>
<p>In this example, c0 represents a fabric-connected host port, and c1 represents a<br />
   private, loop-connected host port. Use the cfgadm(1M) command to manage the device<br />
   configuration on fabric-connected host ports.</p>
<p>By default, the device configuration on private, loop-connected host ports is managed<br />
   by a host using the Solaris Express Developer's Edition OS.</p>
<p>Display information about the host ports and their attached devices.<br />
   # cfgadm -al<br />
   Ap_Id Type Receptacle Occupant Condition<br />
   c0 fc-fabric connected unconfigured unknown<br />
   c0::50020f2300006077 disk connected unconfigured unknown<br />
   c0::50020f23000063a9 disk connected unconfigured unknown<br />
   c0::50020f2300005f24 disk connected unconfigured unknown<br />
   c0::50020f2300006107 disk connected unconfigured unknown<br />
   c1 fc-private connected configured unknown<br />
   c1::220203708b69c32b disk connected configured unknown<br />
   c1::220203708ba7d832 disk connected configured unknown<br />
   c1::220203708b8d45f2 disk connected configured unknown<br />
   c1::220203708b9b20b2 disk connected configured unknown</p>
<p>Note:</p>
<p>The cfgadm -l command displays information about FC host ports. You can also use the<br />
   cfgadm -al command to display information about FC devices. The lines that include<br />
   a port world wide name (WWN) in the Ap_Id field associated with c0 represent a<br />
   fabric device. Use the cfgadm configure and unconfigure commands to manage those<br />
   devices and make them available to hosts using the Solaris Express Developer's<br />
   Edition OS. The Ap_Id devices with port WWNs under c1 represent private-loop<br />
   devices that are configured through the c1 host port.</p>
<p>======================================<br />
   SAN Linux qla-scan:<br />
======================================</p>
<p>1) First the devices (LUN's) are to be detected by HBA's<br />
   We do this by scanning BOTH the HBA's using qla-scan?</p>
<p>2) We can find the new LUNs in /proc/scsi/qla200/ 0<br />
   /proc/scsi/qla200/ 1</p>
<p>(Id:Lun) * - indicates lun is not registered with the OS.</p>
<p>( 0: 0): Total reqs 1, Pending reqs 0, flags 0x0*, 0:0:81,</p>
<p>( 0:15): Total reqs 0, Pending reqs 0, flags 0x0*, 0:0:81,</p>
<p>If a new LUN is added, after a scan i may see something like</p>
<p>(0:16): Total reqs 0, Pending reqs 0, flags 0x0*, 0:0:81, where 0 is the<br />
   target ID and 16 is LUN ???????</p>
<p>(( echo 1 > /sys/class/fc_ host/hostn/ issue_lip<br />
   echo &#8220;- &#8211; -&#8221; > /sys/class/scsi_ host/host2/ scan</p>
<p>works for upstream kernels )</p>
<p>3) echo scsi add-single-device 2 0 0 16 > /proc/scsi/scsi so the new LUN<br />
   discovered at HBA 2, BUS 0, TARGET 0, LUN ID 16 will be understood by the<br />
   kernel/OS ?#</p>
<p>4) Now we do a normal fdisk&#8230;</p>
<p>======================================<br />
   SAN Linux Q&#038;A:<br />
======================================</p>
<p>How is HBA and LUN order persistent? Where is this information stored?</p>
<p>1) In Linux mostly HBA and LUN order is Persistant ( by default), it will be stored<br />
   in /proc/scsi/<Driver Name > and /etc/modules.conf</p>
<p>How are the naming conventions done on the newly added scsi LUN?</p>
<p>2) Assume my first INTERNAL DISK was sda.<br />
   &#8211; The Newly added device might be appear to you as sdb</p>
<p>How will the new LUN&#8217;s be named?</p>
<p>3) A LUN is basically named or idendified by WWW number( 16 digit ) which will<br />
   communicate with SAN switch and Disk. Make sure that newly configured LUN&#8217;s are<br />
   properly configured and mapped to correct HBA&#8217;s</p>
<p>======================================<br />
   SAN Linux How To:<br />
======================================</p>
<p>1. If you have installed SANsurfer GUI/CLI, make sure newly added LUN&#8217;s are visible<br />
   from these tools.</p>
<p>2. For each QLogic HBA installed in the system, do the following:</p>
<p>a. Determine the host ID (H) associated with the HBA. Each installed HBA has a</p>
<p>numeric filename that is the host identifier.</p>
<p># /bin/ls /proc/scsi/qla2300</p>
<p>b. Rescan for all the LUNs on all the ports.</p>
<p>H is the host identifier associated with HBA.</p>
<p># /bin/echo scsi-qlascan > /proc/scsi/qla2300/ H</p>
<p>c. Determine the target ID (T) associated with the new LUN.</p>
<p>This file lists the ID:LUN numbers recognized by the QLA driver. T is the</p>
<p>target ID value.</p>
<p># /bin/cat /proc/scsi/qla2300/ H</p>
<p>d. Add the LUN to HBA.</p>
<p>H is the host identifier associated with the HBA;</p>
<p>T is the target identifier obtained in Step c; and L is the LUN identifier.</p>
<p># /bin/echo scsi add-single-device H 0 T L > /proc/scsi/scsi</p>
<p>4. use &#8220;/sbin/fdisk -l&#8221; to verify if the newly added LUN is visible to the OS</p>
<p>5. use InfoDoc 85804 &#8220;How to create a new partition table under Redhat Linux&#8221;</p>
<p>for creating properly a partition and a file system on the LUN</p>
<p>======================================<br />
   SAN Linux HBA Example:<br />
======================================</p>
<p>Find below example illustrating addition of a newly mapped T4 lun on RedHat</p>
<p>Linux using QLA driver version 7.07.04</p>
<p>1) Determine host ID</p>
<p>root]# /bin/ls /proc/scsi/qla2300/</p>
<p>2</p>
<p>2) Re-scan for LUN&#8217;s on both HBA&#8217;s</p>
<p>root]# /bin/echo scsi-qlascan > /proc/scsi/qla2300/ 2</p>
<p>3) Verify newly mapped LUN&#8217;s</p>
<p>root]# /bin/cat /proc/scsi/qla2300/ 2</p>
<p>QLogic PCI to Fibre Channel Host Adapter for QLA2342:</p>
<p>Firmware version: 3.03.19, Driver version 7.07.04</p>
<p>Entry address = f88ae060</p>
<p>HBA: QLA2312 , Serial# F05179</p>
<p>Request Queue = 0x377e0000, Response Queue = 0x377d0000</p>
<p>Request Queue count= 512, Response Queue count= 512</p>
<p>Total number of active commands = 0</p>
<p>Total number of interrupts = 35</p>
<p>Total number of active IP commands = 0</p>
<p>Total number of IOCBs (used/max) = (0/600)</p>
<p>Total number of queued commands = 0</p>
<p>Device queue depth = 0&#215;20</p>
<p>Number of free request entries = 510</p>
<p>Number of mailbox timeouts = 0</p>
<p>Number of ISP aborts = 0</p>
<p>Number of loop resyncs = 2</p>
<p>Number of retries for empty slots = 0</p>
<p>Number of reqs in pending_q= 0, retry_q= 0, done_q= 0, scsi_retry_q= 0</p>
<p>Host adapter:loop state= <READY>, flags= 0&#215;820813</p>
<p>Dpc flags = 0&#215;0</p>
<p>MBX flags = 0&#215;0</p>
<p>SRB Free Count = 4096</p>
<p>Link down Timeout = 000</p>
<p>Port down retry = 030</p>
<p>Login retry count = 030</p>
<p>Commands retried with dropped frame(s) = 0</p>
<p>Configured characteristic impedence: 50 ohms</p>
<p>Configured data rate: 1-2 Gb/sec auto-negotiate</p>
<p>SCSI Device Information:</p>
<p>scsi-qla0-adapter- node=200100e08b2 75bb5;</p>
<p>scsi-qla0-adapter- port=210100e08b2 75bb5;</p>
<p>scsi-qla0-target- 0=20030003ba27cf a2;</p>
<p>SCSI LUN Information:</p>
<p>(Id:Lun) * &#8211; indicates lun is not registered with the OS.</p>
<p>( 0: 0): Total reqs 1, Pending reqs 0, flags 0&#215;0*, 0:0:81,</p>
<p>( 0:15): Total reqs 0, Pending reqs 0, flags 0&#215;0*, 0:0:81,</p>
<p>Note &#8220;*&#8221; in the above outputs, which indicates lun as not registered</p>
<p>with OS, hence not visible to OS.</p>
<p>4) Register the new LUN&#8217;s with OS</p>
<p># /bin/echo scsi add-single-device 2 0 0 15 > /proc/scsi/scsi</p>
<p>5) verify from OS using &#8220;fdisk -l&#8221;</p>
<p>root]# /sbin/fdisk -l</p>
<p>Disk /dev/sda: 36.4 GB, 36420075008 bytes</p>
<p>255 heads, 63 sectors/track, 4427 cylinders</p>
<p>Units = cylinders of 16065 * 512 = 8225280 bytes</p>
<p>Device Boot Start End Blocks Id System</p>
<p>/dev/sda1 * 1 13 104391 83 Linux</p>
<p>/dev/sda2 14 4173 33415200 83 Linux</p>
<p>/dev/sda3 4174 4427 2040255 82 Linux swap</p>
<p>Disk /dev/sdb: 5372 MB, 5372116992 bytes</p>
<p>255 heads, 63 sectors/track, 653 cylinders</p>
<p>Units = cylinders of 16065 * 512 = 8225280 bytes</p>
<p>Device Boot Start End Blocks Id System</p>
<p>/dev/sdb1 1 653 5245191 83 Linux</p>
<p>In the above output &#8216;sdb&#8217; is this the new LUN which was partitioned earlier?</p>
<p>Please provide simple and detailed steps by step instruction for</p>
<p>1) Detecting SAN device using Qlogic aswell as Emulex HBA&#8217;s</p>
<p>2) Creating Psuedo device with Powermt / Device Mapper</p>
<p>======================================<br />
   RAID<br />
======================================</p>
<p>======================================<br />
   Distributed Parity:<br />
======================================</p>
<p>There&#8217;s some confusion and different marketing terms out there. RAID 6 is a common<br />
   one. RAID 6 is an extension of RAID 5. RAID 5 is some number of disk drives, we&#8217;ll<br />
   call it N + 1. N could be five drives plus a parity. Six total drives, five actual<br />
   data drives. The drives are striped with parity interleaved to optimize<br />
   performance.</p>
<p>RAID 6 adds a second parity drive. So, think of it as N + 2. Seven total drives. The<br />
   need for RAID 6 is larger drives. It takes longer to rebuild larger drives when a<br />
   drive fails, so you have a longer exposure window if something happens. Having that<br />
   second parity drive protects you from an additional drive failure during the<br />
   rebuild. That&#8217;s the basic idea behind dual parity.</p>
<p>With distributed parity, the parity may be distributed onto another array. One way to<br />
   do that is with two arrays clustered together where the data is actually replicated<br />
   across different storage systems. It may not be parity protection, per se, but it<br />
   is a form of protection. There are some other techniques that involve spreading<br />
   parity bits across different storage systems and across wider areas. We&#8217;re starting<br />
   to see some companies, such as Cleversafe, in the wide area distributed game, where<br />
   the data and parity is spread across different locations.</p>
<p>RAID level 6 was not an original RAID level. It adds an additional parity block to a<br />
   RAID 5 array. It needs at least four disks (two disks for the capacity, two disks<br />
   for redundancy). RAID 5 can be seen as a special case of a Reed-Solomon code. RAID<br />
   5 is a special case, though, it only needs addition in the Galois field GF(2). This<br />
   is easy to do with XORs. RAID 6 extends these calculations. It is no longer a<br />
   special case, and all of the calculations need to be done. With RAID 6, an extra<br />
   checksum (called polynomial) is used, usually of GF (28). With this approach it is<br />
   possible to protect against any number of failed disks. RAID 6 is for the case of<br />
   using two checksums to protect against the loss of two disks.</p>
<p>Like with RAID 5, parity and data are on different disks, for each block. The two<br />
   parity blocks are also located on different disks.</p>
<p>RAID 6 is slower than RAID 5, but it allows the RAID to continue with any two disks<br />
   failed.</p>
<p>======================================<br />
   PACKAGING ////////////////////////<br />
======================================</p>
<p>======================================<br />
   RPM COMMANDS<br />
======================================</p>
<p>======================================<br />
   Install:<br />
======================================</p>
<p># rpm -ivh foo-2.0-4.i386.rpm<br />
   # rpm -i ftp://ftp.redhat.com/pub/redhat/RPMS/foo-1.0-1.i386.rpm<br />
   # rpm -i </p>
<p>http://oss.oracle.com/projects/firewire/dist/files/kernel-2.4.20-18.10.1.i686.rpm</p>
<p>   Used to install a RPM package. Note that RPM packages have file naming conventions<br />
   like foo-2.0-4.i386.rpm, which include the package name (foo), version (2.0),<br />
   release (4), and architecture (i386). Also notice that RPM understands FTP and HTTP<br />
   protocols for installing and querying remote RPM files.</p>
<p>======================================<br />
   Uninstall:<br />
======================================</p>
<p># rpm -e foo<br />
   To uninstall a RPM package. Note that we used the package name foo, not the name of<br />
   the original package file foo-2.0-4.i386.rpm above.</p>
<p>======================================<br />
   Upgrade:<br />
======================================</p>
<p># rpm -Uvh foo-1.0-2.i386.rpm<br />
   # rpm -Uvh ftp://ftp.redhat.com/pub/redhat/RPMS/foo-1.0-1.i386.rpm<br />
   # rpm -Uvh </p>
<p>http://oss.oracle.com/projects/firewire/dist/files/kernel-2.4.20-18.10.1.i686.rpm</p>
<p>   To upgrade a RPM package. Using this command, RPM automatically uninstall the old<br />
   version of the foo package and install the new package. It is safe to always use<br />
   rpm -Uvh to install and upgrade packages, since it works fine even when there are<br />
   no previous versions of the package installed! Also notice that RPM understands FTP<br />
   and HTTP protocols for upgrading from remote RPM files.</p>
<p>======================================<br />
   Query All:<br />
======================================</p>
<p># rpm -qa<br />
   To query all installed packages. This<br />
   command will print the names of all<br />
   installed packages installed on your Linux system.<br />
======================================<br />
   Query Single:<br />
======================================</p>
<p># rpm -q foo<br />
   To query a RPM package. This command will print the package name, version, and<br />
   release number of the package foo only if it is installed. Use this command to<br />
   verify that a package is or is not installed on your Linux system.<br />
======================================<br />
   Query Pkg. Info.:<br />
======================================</p>
<p># rpm -qi foo<br />
   To display package information. This command display package information including<br />
   the package name, version, and description of the installed program. Use this<br />
   command to get detailed information about the installed package.<br />
======================================<br />
   List Files in installed Pkg.:<br />
======================================</p>
<p># rpm -ql foo<br />
   To list files in installed package. This command will list all of files in an<br />
   installed RPM package. It works only when the package is already installed on your<br />
   Linux system.</p>
<p>======================================<br />
   Which Pkg. owns a file?:<br />
======================================</p>
<p># rpm -qf /usr/bin/mysql<br />
   mysql-3.23.52-3<br />
   Which package owns a file? This command checks to determine which installed package a<br />
   particular file belongs to.</p>
<p>======================================<br />
   List files in RPM file:<br />
======================================</p>
<p># rpm -qpl kernel-2.4.20-18.10.1.i686.rpm<br />
   # rpm -qpl ftp://ftp.redhat.com/pub/redhat/RPMS/foo-1.0-1.i386.rpm<br />
   # rpm -qpl </p>
<p>http://oss.oracle.com/projects/firewire/dist/files/kernel-2.4.20-18.10.1.i686.rpm</p>
<p>   List files in RPM file. This command allows you to query a (possibly) uninstalled RPM<br />
   file with the use of the the &#8220;-p&#8221; option. You can use the &#8220;-p&#8221; option to operate on<br />
   an RPM file without actually installing anything. This command lists all files in<br />
   an RPM file you have in the current directory. Also note that RPM can query remote<br />
   files through the FTP and HTTP protocols.</p>
<p>======================================<br />
   Verify Installed Package:<br />
======================================</p>
<p># rpm &#8211;verify mysql<br />
   To verify an installed package. This command will list all files that do NOT pass the<br />
   verify tests (done on size, MD5 signature, etc). Where a file does NOT pass, the<br />
   output is listed using the following codes that signify what failed:<br />
   S File size<br />
   M Mode (includes permissions and file type)<br />
   5 MD5 sum<br />
   L Symlink<br />
   D Device<br />
   U User<br />
   G Group<br />
   T Mtime<br />
   Take for example the following:<br />
   # rpm &#8211;verify mysql<br />
   S.5&#8230;.T c /etc/my.cnf<br />
   This example indicates that file /etc/my.cnf failed on:<br />
   File size<br />
   MD5 Sum<br />
   Modified Time<br />
   However, the &#8220;c&#8221; tells us this is a configuration file so that explains the changes.<br />
   It should still be looked at to determine what the changes were.</p>
<p>======================================<br />
   Check RPM Signature package:<br />
======================================</p>
<p># rpm &#8211;checksig foo<br />
   To check a RPM signature package. This command checks the PGP signature of specified<br />
   package to ensure its integrity and origin. Always use this command first before<br />
   installing a new RPM package on your system. Also, GnuPG or Pgp software must be<br />
   already installed on your system before you can use this command.</p>
<p>======================================<br />
   Build RPM Package:<br />
======================================</p>
<p>RPM package building guide</p>
<p>Sam Isaacson (  sbi@nbcs.rutgers.edu)</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>Introduction to rpm package building</p>
<p>Rpm packages are usually built with a &#8220;spec file,&#8221; which is a collection of text<br />
   and shell scripts that build, install and describe a software program. Here is<br />
   a typical spec file:</p>
<p>Summary: Rc shell from Plan 9</p>
<p>Name: rc</p>
<p>Version: 1.6</p>
<p>Release: 1</p>
<p>Group: System Environment/Shells</p>
<p>Copyright: BSD-type</p>
<p>Source: rc-%{version}.tar.gz</p>
<p>BuildRoot: %{_tmppath}/%{name}-root</p>
<p>Requires: readline</p>
<p>BuildRequires: readline-devel</p>
<p>%description</p>
<p>rc is a command interpreter and programming language similar to sh(1).<br />
 It is based on the AT&#038;T Plan 9 shell of the same name. The shell<br />
 offers a C-like syntax (much more so than the C shell), and a powerful<br />
 mechanism for manipulating variables. It is reasonably small and<br />
 reasonably fast, especially when compared to contemporary shells. Its<br />
 use is intended to be interactive, but the language lends itself well<br />
 to scripts.</p>
<p>[from the man page]</p>
<p>%prep</p>
<p>%setup -q</p>
<p>%build</p>
<p>LD=&#8221;/usr/ccs/bin/ld -L/usr/local/lib -R/usr/local/lib&#8221; \</p>
<p>LDFLAGS=&#8221;-L/usr/local/lib -R/usr/local/lib&#8221; ./configure &#8211;with-history \</p>
<p>&#8211;with-readline</p>
<p>make</p>
<p>%install</p>
<p>rm -rf $RPM_BUILD_ROOT</p>
<p>mkdir -p $RPM_BUILD_ROOT/usr/local</p>
<p>make install prefix=$RPM_BUILD_ROOT/usr/local sysconfdir=$RPM_BUILD_ROOT/etc</p>
<p>%clean</p>
<p>rm -rf $RPM_BUILD_ROOT</p>
<p>%files</p>
<p>%defattr(-,bin,bin)</p>
<p>%doc COPYING AUTHORS EXAMPLES README RELDATE ChangeLog</p>
<p>/usr/local/bin/rc</p>
<p>/usr/local/bin/-</p>
<p>/usr/local/bin/&#8211;</p>
<p>/usr/local/bin/-p</p>
<p>/usr/local/bin/&#8211;p</p>
<p>/usr/local/man/man1/rc.1</p>
<p>/usr/local/man/man1/history.1</p>
<p>The spec file is split into several sections, which will be examined<br />
   individually.</p>
<p>In order to write spec files, it is important to understand rpm&#8217;s dependency<br />
   checking, macros and directory structure. When you build a package, rpm<br />
   creates a list of the shared libraries that it includes and a list of the<br />
   shared libraries to which it is linked. RPM records the shared libraries that<br />
   the package provides, along with the package name itself and anything manually<br />
   specified in the spec file, along with version information. Similarly, RPM<br />
   records the required shared libraries and manually specified requires. In rc,<br />
   readline, libc.so.1, libcurses.so.1, libdl.so.1 and libreadline.so.4 are<br />
   required, and rc (version 1.6) is provided. Readline and libreadline.so.4 are<br />
   both provided by the readline package; the rest are provided by the operating<br />
   system.</p>
<p>&#8220;Build requires&#8221; &#8212; packages required at build time &#8212; can be specified in a<br />
   spec file. When it is built, rc needs readline-devel, as it has the header<br />
   files for the readline library.</p>
<p>Rpm has a simple macro system. Macros can be defined like so:</p>
<p>%define foo bar</p>
<p>%{foo}</p>
<p>is preprocessed to become &#8220;bar&#8221;. Rpm has logical constructs: %if/%else/%endif,<br />
   %ifos, and %ifarch (cf. openssl.spec).</p>
<p> Finally, rpm has a system of directories for package building:</p>
<p> prefix/src/redhat/RPMS/sparc</p>
<p>prefix/src/redhat/RPMS/sparc64</p>
<p>prefix/src/redhat/RPMS/sparcv9</p>
<p>.</p>
<p>.</p>
<p>.</p>
<p>prefix/src/redhat/SRPMS</p>
<p>prefix/src/redhat/SOURCES ($RPM_SOURCE_DIR)</p>
<p>prefix/src/redhat/BUILD ($RPM_BUILD_DIR)</p>
<p>prefix/src/redhat/SPECS</p>
<p>RPM expects to find your source in SOURCES; it will unpack and compile the<br />
   source code in BUILD. RPM expects to find the files that the package will<br />
   install in $RPM_BUILD_ROOT, which rc has set to %{_tmppath}/rc-root<br />
   (&#8220;%{_tmppath}&#8221; is a macro set by rpm which expands to the name of a directory<br />
   for temporary files).</p>
<p>The Preamble</p>
<p>The preamble from rc.spec is:</p>
<p>Summary: Rc shell from Plan 9</p>
<p>Name: rc</p>
<p>Version: 1.6</p>
<p>Release: 1</p>
<p>Group: System Environment/Shells</p>
<p>Copyright: BSD-type</p>
<p>Source: rc-%{version}.tar.gz</p>
<p>BuildRoot: %{_tmppath}/%{name}-root</p>
<p>Requires: readline</p>
<p>It describes the package name, version, etc. Name, Version, Release, Group,<br />
   Copyright (or License), and Summary are required. Other fields, such as URL<br />
   and Packager, are optional. Name, Version and Release define macros called<br />
   %{name}, %{version} and %{release} respectively.</p>
<p>Generally, source filenames match the expansion of &#8220;%{name}-%{version}.tar.gz&#8221;.<br />
   The %{version} macro makes maintaining the package much easier; its use is<br />
   highly recommended. If the source field has an URL, rpm automatically<br />
   downloads the source and places it in $RPM_SOURCE_DIR. You can specify<br />
   multiple sources with Source0, Source1, etc.</p>
<p>The %description</p>
<p>This section is parsed separately from the preamble, but can be thought of as<br />
   another field. Generally, one can steal the introduction from a README or man<br />
   page to get a good description.</p>
<p>The %prep section</p>
<p>%prep</p>
<p>%setup -q</p>
<p>The %prep section is where the source is prepared, usually in $RPM_BUILD_DIR.<br />
   Rpm provides the %setup and %patch primitives which automatically untar and<br />
   patch your source. %setup expects it to untar into a directory called<br />
   %{name}-%{version}; otherwise you have to pass it the -n switch, which renames<br />
   the directory. The important %setup switches are:</p>
<p>-n <name> (name of build directory)</p>
<p>-c (creates top-level build directory)</p>
<p>-D (don&#8217;t delete top-level build directory)</p>
<p>-T (don&#8217;t unpack Source0)</p>
<p>-a <n> (unpack Source number n, after cd&#8217;ing to build directory)</p>
<p>-a <n> (unpack Source number n, before cd&#8217;ing to build directory)</p>
<p>-q (unpack silently)</p>
<p>To unpack several sources into the same directory, you need to have something<br />
   like the following in %prep:</p>
<p>%setup -q</p>
<p>%setup -D -T -a 1</p>
<p>%setup -D -T -a 2</p>
<p>That unpacks source 0, then cds into %{name}-%{version} and unpacks source 1 and<br />
   2. As for patches, you have the following switches:</p>
<p>-P < n > (use Patch number n)</p>
<p>-p, -b, -E (see patch(1))</p>
<p>While %prep appears to be all macros, don&#8217;t be fooled &#8212; %prep, %clean, %build,<br />
   %install, %pre, %post, etc. are all shell scripts.</p>
<p>You might need to install GNU tar and put it on your PATH before Sun tar when<br />
   building packages with extremely long filenames (the GNOME software in<br />
   particular requires gnutar).</p>
<p>The %build section</p>
<p>%build</p>
<p>LD=&#8221;/usr/ccs/bin/ld -L/usr/local/lib -R/usr/local/lib&#8221; \</p>
<p>LDFLAGS=&#8221;-L/usr/local/lib -R/usr/local/lib&#8221; ./configure &#8211;with-history \</p>
<p>&#8211;with-readline</p>
<p>make</p>
<p>The %build section is where the actual compiling takes place. Rpm has a<br />
   %configure macro, which is broken by design (it takes the directories from<br />
   prefix/lib/rpm/macros, so it might misplace your files; and it only works with<br />
   GNU configure). With GNU configure, you probably want to configure and build<br />
   the sources like so:</p>
<p>automake # if you patched Makefile.am</p>
<p>autoconf # if you patched configure.in</p>
<p>LD=&#8221;/usr/ccs/bin/ld -L/usr/local/lib -R/usr/local/lib&#8221; \</p>
<p>LDFLAGS=&#8221;-L/usr/local/lib -R/usr/local/lib&#8221; CPPFLAGS=&#8221;-I/usr/local/include&#8221; \</p>
<p>./configure &#8211;prefix=/usr/local &#8211;sysconfdir=/etc</p>
<p>make</p>
<p>Unfortunately, GNU configure may not use $LD and $LDFLAGS together &#8212; sometimes<br />
   it does, and sometimes it doesn&#8217;t. It is more reliable to pass everything into<br />
   configure (especially because it increases the chance that your specfile will<br />
   work on someone else&#8217;s machine). If you&#8217;re compiling C++ for X, add CXX=&#8221;g++<br />
   -fpermissive&#8221; (Sun&#8217;s include files aren&#8217;t ANSI C++).</p>
<p>As for imake (with Sun&#8217;s cc, not gcc), try:</p>
<p>xmkmf -a</p>
<p>make CCOPTIONS=&#8221;-I/usr/local/include&#8221; LINTOPTS=&#8221;" \</p>
<p>EXTRA_LDOPTIONS=&#8221;-L/usr/local/lib -R/usr/local/lib&#8221;</p>
<p>Using imake and gcc is left as an exercise to the reader.</p>
<p>Don&#8217;t specify the prefix as $RPM_BUILD_ROOT/usr/local; many programs hardcode<br />
   file locations at the configure or make stage.</p>
<p>The %install section</p>
<p>%install</p>
<p>rm -rf $RPM_BUILD_ROOT</p>
<p>mkdir -p $RPM_BUILD_ROOT/usr/local</p>
<p>make install prefix=$RPM_BUILD_ROOT/usr/local sysconfdir=$RPM_BUILD_ROOT/etc</p>
<p>The %install section is where the files get &#8220;installed&#8221; into your build root.<br />
   You can build rpms without a build root, but this practice is highly<br />
   deprecated and insecure (more on this later). Always begin the %install<br />
   section with something along the lines of</p>
<p>rm -rf $RPM_BUILD_ROOT</p>
<p>mkdir -p $RPM_BUILD_ROOT/usr/local</p>
<p>Sometimes, you can get away with just adding</p>
<p>make install prefix=$RPM_BUILD_ROOT/usr/local</p>
<p>Usually, it&#8217;s a little hairier. If your program puts files in /etc, you have to<br />
   tell make install (if you use make install). If a program hardcodes file<br />
   locations at the make install stage, the best solution is to massage the<br />
   output of make -n install. Truly devious programs such as qmail, which compile<br />
   their own installer, make require patches to install correctly.</p>
<p>Other scripts</p>
<p>%clean</p>
<p>rm -rf $RPM_BUILD_ROOT</p>
<p>Generally, the only other script you need is %clean, which gets executed after<br />
   the build (just clean out $RPM_BUILD_ROOT). You also get %pre (preinstall),<br />
   %post (postinstall), %preun (preuninstall), %postun (postuninstall),<br />
   %verifyscript (executed with rpm -V), and triggers (read the documentation<br />
   included with rpm).</p>
<p>The %files section</p>
<p>%files</p>
<p>%defattr(-,bin,bin)</p>
<p>%doc COPYING AUTHORS EXAMPLES README RELDATE ChangeLog</p>
<p>/usr/local/bin/rc</p>
<p>/usr/local/bin/-</p>
<p>/usr/local/bin/&#8211;</p>
<p>/usr/local/bin/-p</p>
<p>/usr/local/bin/&#8211;p</p>
<p>/usr/local/man/man1/rc.1</p>
<p>/usr/local/man/man1/history.1</p>
<p>The %files section is where you list all the files in the package. You have a<br />
   few commands at your disposal: %doc (marks documentation), %attr (marks<br />
   attibutes of a file &#8211; mode [- means don't change mode], user, group), %defattr<br />
   (default attributes), %verify (see Maximum RPM), %config (marks configuration<br />
   files), %dir and %docdir.</p>
<p>If a filename in the %files list corresponds to a directory, the package owns<br />
   the directory as well as all the files in it; so don&#8217;t put /usr/bin in your<br />
   %files list. Be careful with globbing and directories; if you list a file<br />
   twice, rpm will not build your package. Also, some symlinks (absolute ones)<br />
   cause rpm to complain bitterly; avoid unintentionally grabbing them.</p>
<p>Methods for generating file lists</p>
<p>Unfortunately, generating file lists isn&#8217;t always easy. Assuming that you didn&#8217;t<br />
   have to parse the output of make -n install yourself to write the %install<br />
   section, try doing something sneaky like:</p>
<p>$ ./configure &#8211;prefix=/usr/local &#8211;sysconfdir=/etc</p>
<p>$ make</p>
<p>$ mkdir -p sandbox/usr/local/</p>
<p>$ make install prefix=`pwd`/sandbox/usr/local/ sysconfdir=`pwd`/etc</p>
<p>$ for i in `find sandbox -type f`; do # check to ensure that no files</p>
<p>> strings $i | grep sandbox &#038;&#038; echo $i # &#8220;know&#8221; that they were installed</p>
<p>> done # in the build root</p>
<p>Check out the Makefile. Some packages use prefix; others use PREFIX, DESTDIR, or<br />
   something different. Sometimes, you don&#8217;t need to add the &#8220;usr/local&#8221; part.<br />
   This is, incidentally, a good reason not to build packages as root&?emdash;if<br />
   you accidentally install the software on your system (instead of in an empty<br />
   directory), you cannot test your package as easily.</p>
<p>Using the rudimentary genspec.pl script (or find(1)), you can use this directory<br />
   to generate a file list. After you get a list, you may wish to replace long<br />
   lists of files with globs. For instance:</p>
<p>/usr/local/lib/locale/cs/LC_MESSAGES/rpm.mo</p>
<p>/usr/local/lib/locale/de/LC_MESSAGES/rpm.mo</p>
<p>/usr/local/lib/locale/fi/LC_MESSAGES/rpm.mo</p>
<p>/usr/local/lib/locale/fr/LC_MESSAGES/rpm.mo</p>
<p>/usr/local/lib/locale/ja/LC_MESSAGES/rpm.mo</p>
<p>/usr/local/lib/locale/pl/LC_MESSAGES/rpm.mo</p>
<p>/usr/local/lib/locale/pt_BR/LC_MESSAGES/rpm.mo</p>
<p>/usr/local/lib/locale/ru/LC_MESSAGES/rpm.mo</p>
<p>/usr/local/lib/locale/sk/LC_MESSAGES/rpm.mo</p>
<p>/usr/local/lib/locale/sk/LC_MESSAGES/popt.mo</p>
<p>/usr/local/lib/locale/sl/LC_MESSAGES/rpm.mo</p>
<p>/usr/local/lib/locale/sr/LC_MESSAGES/rpm.mo</p>
<p>/usr/local/lib/locale/sv/LC_MESSAGES/rpm.mo</p>
<p>/usr/local/lib/locale/tr/LC_MESSAGES/rpm.mo</p>
<p>/usr/local/lib/locale/ro/LC_MESSAGES/popt.mo</p>
<p>becomes</p>
<p>/usr/local/lib/locale/*/LC_MESSAGES/*.mo</p>
<p>This makes packages more maintainable. If Spanish translations were added, the<br />
   glob would catch them; otherwise, you would have to add<br />
   /usr/local/lib/local/es/LC_MESSAGES/rpm.mo to the file list. You have to be<br />
   careful, however, that the globs catch only the files or directories you want.</p>
<p>Sometimes, it may be appropriate to generate a file list on the fly. The perl<br />
   package does this:</p>
<p>%build</p>
<p>sh Configure -de -Dprefix=/usr/local -Dcpp=&#8217;/opt/SUNWspro/bin/cc -E&#8217; \</p>
<p>-Dcc=&#8217;/opt/SUNWspro/bin/cc&#8217; \</p>
<p>-Dinstallprefix=&#8221;$RPM_BUILD_ROOT/usr/local&#8221; \</p>
<p>-Dldflags=&#8217;-L/usr/local/lib -R/usr/local/lib&#8217; -Dusethreads</p>
<p>make</p>
<p>make test</p>
<p>%install</p>
<p>rm -rf $RPM_BUILD_ROOT</p>
<p>mkdir -p $RPM_BUILD_ROOT/usr/local</p>
<p>make install</p>
<p># clean up files which know about the build root</p>
<p>for fn in .packlist Config.pm; do</p>
<p>afn=&#8221;$RPM_BUILD_ROOT/usr/local/lib/perl5/%{version}/%{perl_arch}/$fn&#8221;</p>
<p>chmod 0644 $afn</p>
<p>mv $afn $afn.TEMP</p>
<p>sed &#8220;s#$RPM_BUILD_ROOT##g&#8221; < $afn.TEMP > $afn</p>
<p>rm -f $afn.TEMP</p>
<p>done</p>
<p>chmod 0444 \</p>
<p>$RPM_BUILD_ROOT/usr/local/lib/perl5/%{version}/%{perl_arch}/Config.pm</p>
<p>find $RPM_BUILD_ROOT -type f \( -name \*.h -o -name \*.a \) -print \</p>
<p>| sed &#8220;s#^$RPM_BUILD_ROOT/*#/#&#8221; > DEVEL-LIST</p>
<p>find $RPM_BUILD_ROOT -type f ! \( -name \*.h -o -name \*.a \) -print \</p>
<p>| sed &#8220;s#^$RPM_BUILD_ROOT/*#/#&#8221; > REGULAR-LIST</p>
<p>%files -f REGULAR-LIST</p>
<p>%doc Copying Artistic README</p>
<p>%files devel -f DEVEL-LIST</p>
<p>Subpackages</p>
<p>If you want to make more than one package out of a single source tree, you have<br />
   to use subpackages. Here is an example of spec file with subpackages:</p>
<p>Name: readline</p>
<p>Version: 4.1</p>
<p>Copyright: GPL</p>
<p>Group: System Environment/Libraries</p>
<p>Summary: GNU readline</p>
<p>Release: 1</p>
<p>Source: readline-4.1.tar.gz</p>
<p>Provides: libhistory.so</p>
<p>Provides: libreadline.so</p>
<p>BuildRoot: %{_tmppath}/%{name}-root</p>
<p>%description</p>
<p>GNU readline is a library that enables history, completion, and</p>
<p>emacs/vi-like motion functionality in a program linked with it.</p>
<p>%package devel</p>
<p>Summary: Readline header files, static libraries</p>
<p>Group: Development/Libraries</p>
<p>Requires: readline = 4.1</p>
<p>%description devel</p>
<p>This package contains the header files and static libraries for</p>
<p>readline. Install this package if you want to write or compile a</p>
<p>program that needs readline.</p>
<p>%prep</p>
<p>%setup -q</p>
<p>%build</p>
<p>autoconf</p>
<p>LDFLAGS=&#8221;-L/usr/local/lib -R/usr/local/lib&#8221; ./configure \</p>
<p>&#8211;prefix=/usr/local &#8211;enable-shared</p>
<p>make</p>
<p>make shared</p>
<p>%install</p>
<p>rm -rf $RPM_BUILD_ROOT</p>
<p>mkdir -p $RPM_BUILD_ROOT/usr/local</p>
<p>make install prefix=$RPM_BUILD_ROOT/usr/local</p>
<p>make install-shared prefix=$RPM_BUILD_ROOT/usr/local</p>
<p>%clean</p>
<p>rm -rf $RPM_BUILD_ROOT</p>
<p>%post</p>
<p>ln -s /usr/local//lib/libhistory.so.4 /usr/local/lib/libhistory.so</p>
<p>ln -s /usr/local//lib/libreadline.so.4 /usr/local/lib/libreadline.so</p>
<p>if [ -x /usr/local/bin/install-info ]; then</p>
<p>/usr/local/bin/install-info &#8211;info-dir=/usr/local/info \</p>
<p>/usr/local/info/rluserman.info</p>
<p>/usr/local/bin/install-info &#8211;info-dir=/usr/local/info \</p>
<p>/usr/local/info/history.info</p>
<p>fi</p>
<p>%preun</p>
<p>rm /usr/local/lib/libhistory.so</p>
<p>rm /usr/local/lib/libreadline.so</p>
<p>if [ -x /usr/local/bin/install-info ]; then</p>
<p>/usr/local/bin/install-info &#8211;delete &#8211;info-dir=/usr/local/info \</p>
<p>/usr/local/info/rluserman.info</p>
<p>/usr/local/bin/install-info &#8211;delete &#8211;info-dir=/usr/local/info \</p>
<p>/usr/local/info/history.info</p>
<p>fi</p>
<p>%files</p>
<p>%defattr(-,bin,bin)</p>
<p>%doc COPYING</p>
<p>/usr/local/lib/libhistory.so.4</p>
<p>/usr/local/lib/libreadline.so.4</p>
<p>/usr/local/info/readline.info</p>
<p>/usr/local/info/rluserman.info</p>
<p>/usr/local/info/history.info</p>
<p>/usr/local/man/man3/readline.3</p>
<p>%files devel</p>
<p>%defattr(-,bin,bin)</p>
<p>/usr/local/include/readline</p>
<p>/usr/local/lib/libreadline.a</p>
<p>/usr/local/lib/libhistory.a</p>
<p>This creates two packages: readline and readline-devel. (If you just want devel,<br />
   replace %package devel with %package -n devel and %files with %files -n<br />
   devel).</p>
<p>Style and Security</p>
<p>Don&#8217;t build packages as root; edit prefix/lib/rpm/macros so you can build in<br />
   your home directory. If you build as root, you run the risk of accidentally<br />
   installing files on your system. Instead of using chown in %install, use %attr<br />
   in %files.</p>
<p>Be careful when building on a multiuser system; the buildroot, if it is in a<br />
   globally-writable directory, is a big security hole.</p>
<p>Don&#8217;t use the %config directive. It might break packages that a user is<br />
   upgrading; instead, at the end of %install, write</p>
<p>for i in `find $RPM_BUILD_ROOT/etc -type f`; do</p>
<p>mv $i $i.rpm</p>
<p>done</p>
<p>and warn the user in %post.</p>
<p>Don&#8217;t make the user set his or her LD_LIBRARY_PATH. Instead, use -R.</p>
<p>If you need to patch configure, patch configure.in instead.</p>
<p>Don&#8217;t interactively involve the user at build or compile time.</p>
<p>Try to split your packages into static library/header &#8220;development&#8221; packages and<br />
   shared library packages.</p>
<p>If you are building GNU replacements for tools packaged with Solaris (e.g.<br />
   fileutils, grep, tar), put them in /usr/local/gnu instead of /usr/local. Avoid<br />
   putting any binaries in /usr/local/bin that conflict with any in /usr/ccs/bin,<br />
   /usr/bin, etc.</p>
<p>Use %{_tmppath} instead of /free/tmp or /var/tmp?it is more portable.</p>
<p>More information</p>
<p>Go to rpm.org for more information. Unfortunately, rpm is extremely poorly<br />
   documented. Maximum RPM is out of date; the most authoritative source on rpm<br />
   is rpm&#8217;s source, which is kind of messy. Any one of the redhat mirrors has<br />
   source rpms; run them through rpm2cpio and take a look at the specfiles (which<br />
   are unfortunately Redhat-specific).</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>$Id: guide.html,v 1.1.1.1 2001/12/14 20:38:47 sbi Exp $</p>
<p>======================================<br />
   PROCESSES ////////////////////////<br />
======================================</p>
<p>======================================<br />
   Count processes:<br />
======================================</p>
<p>[ root@enterprise ]$ ps -ef | grep sendmail | sed -n &#8216;$=&#8217;<br />
   3</p>
<p>[ root@enterprise ]$ ps -ef |grep sendmail |wc<br />
   3 29 211</p>
<p>[ root@enterprise ]$ ps -ef |grep sendmail |wc -l<br />
   3</p>
<p>=======================================<br />
   Advanced Process Commands Solaris / Linux<br />
=======================================</p>
<p>/usr/proc/bin/ptree
<pid>
<p>/* Print the parent/child process &#8216;tree&#8217; of a process */<br />
=======================================</p>
<p>/usr/proc/bin/pwdx
<pid>
<p>/* Print the working directory of a process */<br />
=======================================</p>
<p>/usr/ucb/ps -aux | more</p>
<p>/* Displays CPU % usage for each process in ascending order */<br />
=======================================</p>
<p>/usr/ucb/ps -auxww | grep
<process name>
<p>/* Gives the full listing of the process (long listing) */<br />
=======================================</p>
<p>coreadm -i core.%f.%p</p>
<p>/* Append program name and process id to core file names */<br />
=======================================</p>
<p>fuser -uc /var</p>
<p>/* Processes that are running from /var */<br />
=======================================</p>
<p>ipcs</p>
<p>/* Report inter-process communication facilities status */<br />
=======================================</p>
<p>kill -HUP `ps -ef | grep [p]roccess | awk &#8216;{print $2}&#8217;`</p>
<p>/* HUP any related process in one step */<br />
=======================================</p>
<p>lsof -i TCP:25</p>
<p>/* Mapping port with process */<br />
=======================================</p>
<p>pfiles
<pid>
<p>/* Shows processes&#8217; current open files */<br />
=======================================</p>
<p>pkill -n <name></p>
<p>/* Kill a process by name */<br />
=======================================</p>
<p>prstat -a</p>
<p>/* An alternative for top command */<br />
=======================================</p>
<p>ps -edf -o pcpu,pid,user,args</p>
<p>/* Nicely formatted &#8216;ps&#8217; */<br />
=======================================</p>
<p>ps -ef | grep -i <string> | awk &#8216;{ print $2 }&#8217;</p>
<p>/* Creates list of running PID by <string> */<br />
=======================================</p>
<p>ps -ef | grep -i <string> | awk &#8216;{ print $2 }&#8217;</p>
<p>/* Creates list of running PID by */<br />
=======================================</p>
<p>ps -ef | grep
<process name> | grep -v grep | cut -c 10-15 | xargs kill -9</p>
<p>/* Find and kill all instances of a given process */<br />
=======================================</p>
<p>ps -ef | more</p>
<p>/* Show all processes running */<br />
=======================================</p>
<p>ps -ef|grep -v &#8220;0:00&#8243;|more</p>
<p>/* Gives you a list of any process with CPU time more than 0:00 */<br />
=======================================</p>
<p>ps -eo pid,args</p>
<p>/* List processes in simplified format */<br />
=======================================</p>
<p>ps -fu oracle|grep pmon</p>
<p>/* See which instances of Oracle are running */<br />
=======================================</p>
<p>top -b 1</p>
<p>/* Returns the process utilizing the most cpu and quits */<br />
=======================================</p>
<p>======================================<br />
   SYSTEM INTERNALS /////////////////<br />
======================================</p>
<p>======================================<br />
   SYSTEM INTERNALS LINUX:<br />
======================================</p>
<p>Every process under Linux is dynamically allocated a struct task_struct structure.<br />
   The maximum number of processes which can be created on Linux is limited only by<br />
   the amount of physical memory present, and is equal to (see<br />
   kernel/fork.c:fork_init()):</p>
<p>/*<br />
   * The default maximum number of threads is set to a safe<br />
   * value: the thread structures can take up at most half<br />
   * of memory.<br />
   */<br />
   max_threads = mempages / (THREAD_SIZE/PAGE_SIZE) / 2;</p>
<p>which, on IA32 architecture, basically means num_physpages/4. As an example, on a<br />
   512M machine, you can create 32k threads. This is a considerable improvement over<br />
   the 4k-epsilon limit for older (2.2 and earlier) kernels. Moreover, this can be<br />
   changed at runtime using the KERN_MAX_THREADS sysctl(2), or simply using procfs<br />
   interface to kernel tunables:</p>
<p># cat /proc/sys/kernel/threads-max<br />
   32764<br />
   # echo 100000 > /proc/sys/kernel/threads-max<br />
   # cat /proc/sys/kernel/threads-max<br />
   100000<br />
   # gdb -q vmlinux /proc/kcore<br />
   Core was generated by `BOOT_IMAGE=240ac18 ro root=306 video=matrox:vesa:0&#215;118&#8242;.<br />
   #0 0&#215;0 in ?? ()<br />
   (gdb) p max_threads<br />
   $1 = 100000</p>
<p>The set of processes on the Linux system is represented as a collection of struct<br />
   task_struct structures which are linked in two ways:</p>
<p>1. as a hashtable, hashed by pid, and<br />
   2. as a circular, doubly-linked list using p->next_task and p->prev_task pointers.</p>
<p>The hashtable is called pidhash[] and is defined in include/linux/sched.h:</p>
<p>/* PID hashing. (shouldnt this be dynamic?) */<br />
   #define PIDHASH_SZ (4096 >> 2)<br />
   extern struct task_struct *pidhash[PIDHASH_SZ];</p>
<p>#define pid_hashfn(x) ((((x) >> 8) ^ (x)) &#038; (PIDHASH_SZ &#8211; 1))</p>
<p>The tasks are hashed by their pid value and the above hashing function is supposed to<br />
   distribute the elements uniformly in their domain (0 to PID_MAX-1). The hashtable<br />
   is used to quickly find a task by given pid, using find_task_pid() inline from<br />
   include/linux/sched.h:</p>
<p>static inline struct task_struct *find_task_by_pid(int pid)<br />
   {<br />
   struct task_struct *p, **htable = &#038;pidhash[pid_hashfn(pid)];</p>
<p>for(p = *htable; p &#038;&#038; p->pid != pid; p = p->pidhash_next)<br />
   ;</p>
<p>return p;<br />
   }</p>
<p>The tasks on each hashlist (i.e. hashed to the same value) are linked by p-><br />
   pidhash_next/pidhash_pprev which are used by hash_pid() and unhash_pid() to insert<br />
   and remove a given process into the hashtable. These are done under protection of<br />
   the read-write spinlock called tasklist_lock taken for WRITE.</p>
<p>The circular doubly-linked list that uses p->next_task/prev_task is maintained so<br />
   that one could go through all tasks on the system easily. This is achieved by the<br />
   for_each_task() macro from include/linux/sched.h:</p>
<p>#define for_each_task(p) \<br />
   for (p = &#038;init_task ; (p = p->next_task) != &#038;init_task ; )</p>
<p>Users of for_each_task() should take tasklist_lock for READ. Note that<br />
   for_each_task() is using init_task to mark the beginning (and end) of the list &#8211;<br />
   this is safe because the idle task (pid 0) never exits.</p>
<p>The modifiers of the process hashtable or/and the process table links, notably<br />
   fork(), exit() and ptrace(), must take tasklist_lock for WRITE. What is more<br />
   interesting is that the writers must also disable interrupts on the local CPU. The<br />
   reason for this is not trivial: the send_sigio() function walks the task list and<br />
   thus takes tasklist_lock for READ, and it is called from kill_fasync() in interrupt<br />
   context. This is why writers must disable interrupts while readers don&#8217;t need to.</p>
<p>Now that we understand how the task_struct structures are linked together, let us<br />
   examine the members of task_struct. They loosely correspond to the members of UNIX<br />
   &#8216;struct proc&#8217; and &#8216;struct user&#8217; combined together.</p>
<p>The other versions of UNIX separated the task state information into one part which<br />
   should be kept memory-resident at all times (called &#8216;proc structure&#8217; which includes<br />
   process state, scheduling information etc.) and another part which is only needed<br />
   when the process is running (called &#8216;u area&#8217; which includes file descriptor table,<br />
   disk quota information etc.). The only reason for such ugly design was that memory<br />
   was a very scarce resource. Modern operating systems (well, only Linux at the<br />
   moment but others, e.g. FreeBSD seem to improve in this direction towards Linux) do<br />
   not need such separation and therefore maintain process state in a kernel<br />
   memory-resident data structure at all times.</p>
<p>The task_struct structure is declared in include/linux/sched.h and is currently 1680<br />
   bytes in size.</p>
<p>The state field is declared as:</p>
<p>volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */</p>
<p>#define TASK_RUNNING 0<br />
   #define TASK_INTERRUPTIBLE 1<br />
   #define TASK_UNINTERRUPTIBLE 2<br />
   #define TASK_ZOMBIE 4<br />
   #define TASK_STOPPED 8<br />
   #define TASK_EXCLUSIVE 32</p>
<p>Why is TASK_EXCLUSIVE defined as 32 and not 16? Because 16 was used up by<br />
   TASK_SWAPPING and I forgot to shift TASK_EXCLUSIVE up when I removed all references<br />
   to TASK_SWAPPING (sometime in 2.3.x).</p>
<p>The volatile in p->state declaration means it can be modified asynchronously (from<br />
   interrupt handler):</p>
<p>1. TASK_RUNNING: means the task is &#8220;supposed to be&#8221; on the run queue. The reason it<br />
   may not yet be on the runqueue is that marking a task as TASK_RUNNING and placing<br />
   it on the runqueue is not atomic. You need to hold the runqueue_lock read-write<br />
   spinlock for read in order to look at the runqueue. If you do so, you will then see<br />
   that every task on the runqueue is in TASK_RUNNING state. However, the converse is<br />
   not true for the reason explained above. Similarly, drivers can mark themselves (or<br />
   rather the process context they run in) as TASK_INTERRUPTIBLE (or<br />
   TASK_UNINTERRUPTIBLE) and then call schedule(), which will then remove it from the<br />
   runqueue (unless there is a pending signal, in which case it is left on the<br />
   runqueue).</p>
<p>   2. TASK_INTERRUPTIBLE: means the task is sleeping but can be woken up by a signal or<br />
   by expiry of a timer.</p>
<p>   3. TASK_UNINTERRUPTIBLE: same as TASK_INTERRUPTIBLE, except it cannot be woken up.</p>
<p>   4. TASK_ZOMBIE: task has terminated but has not had its status collected (wait()-ed<br />
   for) by the parent (natural or by adoption).</p>
<p>   5. TASK_STOPPED: task was stopped, either due to job control signals or due to<br />
   ptrace(2).</p>
<p>   6. TASK_EXCLUSIVE: this is not a separate state but can be OR-ed to either one of<br />
   TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE. This means that when this task is<br />
   sleeping on a wait queue with many other tasks, it will be woken up alone instead<br />
   of causing &#8220;thundering herd&#8221; problem by waking up all the waiters.</p>
<p>Task flags contain information about the process states which are not mutually<br />
   exclusive:</p>
<p>unsigned long flags; /* per process flags, defined below */<br />
   /* Per process flags */<br />
   #define PF_ALIGNWARN 0&#215;00000001 /* Print alignment warning msgs */<br />
   /* Not implemented yet, only for 486 */<br />
   #define PF_STARTING 0&#215;00000002 /* being created */<br />
   #define PF_EXITING 0&#215;00000004 /* getting shut down */<br />
   #define PF_FORKNOEXEC 0&#215;00000040 /* forked but didn&#8217;t exec */<br />
   #define PF_SUPERPRIV 0&#215;00000100 /* used super-user privileges */<br />
   #define PF_DUMPCORE 0&#215;00000200 /* dumped core */<br />
   #define PF_SIGNALED 0&#215;00000400 /* killed by a signal */<br />
   #define PF_MEMALLOC 0&#215;00000800 /* Allocating memory */<br />
   #define PF_VFORK 0&#215;00001000 /* Wake up parent in mm_release */<br />
   #define PF_USEDFPU 0&#215;00100000 /* task used FPU this quantum (SMP) */</p>
<p>The fields p->has_cpu, p->processor, p->counter, p->priority, p->policy and p-><br />
   rt_priority are related to the scheduler and will be looked at later.</p>
<p>The fields p->mm and p->active_mm point respectively to the process&#8217; address space<br />
   described by mm_struct structure and to the active address space if the process<br />
   doesn&#8217;t have a real one (e.g. kernel threads). This helps minimise TLB flushes on<br />
   switching address spaces when the task is scheduled out. So, if we are<br />
   scheduling-in the kernel thread (which has no p->mm) then its next->active_mm will<br />
   be set to the prev->active_mm of the task that was scheduled-out, which will be the<br />
   same as prev->mm if prev->mm != NULL. The address space can be shared between<br />
   threads if CLONE_VM flag is passed to the clone(2) system call or by means of<br />
   vfork(2) system call.</p>
<p>The fields p->exec_domain and p->personality relate to the personality of the task,<br />
   i.e. to the way certain system calls behave in order to emulate the &#8220;personality&#8221;<br />
   of foreign flavours of UNIX.</p>
<p>The field p->fs contains filesystem information, which under Linux means three pieces<br />
   of information:</p>
<p>1. root directory&#8217;s dentry and mountpoint,<br />
   2. alternate root directory&#8217;s dentry and mountpoint,<br />
   3. current working directory&#8217;s dentry and mountpoint.</p>
<p>This structure also includes a reference count because it can be shared between<br />
   cloned tasks when CLONE_FS flag is passed to the clone(2) system call.</p>
<p>The field p->files contains the file descriptor table. This too can be shared between<br />
   tasks, provided CLONE_FILES is specified with clone(2) system call.</p>
<p>The field p->sig contains signal handlers and can be shared between cloned tasks by<br />
   means of CLONE_SIGHAND.</p>
<p>2.2 Creation and termination of tasks and kernel threads</p>
<p>Different books on operating systems define a &#8220;process&#8221; in different ways, starting<br />
   from &#8220;instance of a program in execution&#8221; and ending with &#8220;that which is produced<br />
   by clone(2) or fork(2) system calls&#8221;. Under Linux, there are three kinds of<br />
   processes:</p>
<p>* the idle thread(s),<br />
   * kernel threads,<br />
   * user tasks.</p>
<p>The idle thread is created at compile time for the first CPU; it is then &#8220;manually&#8221;<br />
   created for each CPU by means of arch-specific fork_by_hand() in<br />
   arch/i386/kernel/smpboot.c, which unrolls the fork(2) system call by hand (on some<br />
   archs). Idle tasks share one init_task structure but have a private TSS structure,<br />
   in the per-CPU array init_tss. Idle tasks all have pid = 0 and no other task can<br />
   share pid, i.e. use CLONE_PID flag to clone(2).</p>
<p>Kernel threads are created using kernel_thread() function which invokes the clone(2)<br />
   system call in kernel mode. Kernel threads usually have no user address space, i.e.<br />
   p->mm = NULL, because they explicitly do exit_mm(), e.g. via daemonize() function.<br />
   Kernel threads can always access kernel address space directly. They are allocated<br />
   pid numbers in the low range. Running at processor&#8217;s ring 0 (on x86, that is)<br />
   implies that the kernel threads enjoy all I/O privileges and cannot be pre-empted<br />
   by the scheduler.</p>
<p>User tasks are created by means of clone(2) or fork(2) system calls, both of which<br />
   internally invoke kernel/fork.c:do_fork().</p>
<p>Let us understand what happens when a user process makes a fork(2) system call.<br />
   Although fork(2) is architecture-dependent due to the different ways of passing<br />
   user stack and registers, the actual underlying function do_fork() that does the<br />
   job is portable and is located at kernel/fork.c.</p>
<p>The following steps are done:</p>
<p>1. Local variable retval is set to -ENOMEM, as this is the value which errno should<br />
   be set to if fork(2) fails to allocate a new task structure.</p>
<p>   2. If CLONE_PID is set in clone_flags then return an error (-EPERM), unless the<br />
   caller is the idle thread (during boot only). So, normal user threads cannot pass<br />
   CLONE_PID to clone(2) and expect it to succeed. For fork(2), this is irrelevant as<br />
   clone_flags is set to SIFCHLD &#8211; this is only relevant when do_fork() is invoked<br />
   from sys_clone() which passes the clone_flags from the value requested from<br />
   userspace.</p>
<p>   3. current->vfork_sem is initialised (it is later cleared in the child). This is used<br />
   by sys_vfork() (vfork(2) system call, corresponds to clone_flags =<br />
   CLONE_VFORK|CLONE_VM|SIGCHLD) to make the parent sleep until the child does<br />
   mm_release(), for example as a result of exec()ing another program or exit(2)-ing.</p>
<p>   4. A new task structure is allocated using arch-dependent alloc_task_struct() macro.<br />
   On x86 it is just a gfp at GFP_KERNEL priority. This is the first reason why<br />
   fork(2) system call may sleep. If this allocation fails, we return -ENOMEM.</p>
<p>   5. All the values from current process&#8217; task structure are copied into the new one,<br />
   using structure assignment *p = *current. Perhaps this should be replaced by a<br />
   memcpy? Later on, the fields that should not be inherited by the child are set to<br />
   the correct values.</p>
<p>   6. Big kernel lock is taken as the rest of the code would otherwise be<br />
   non-reentrant.</p>
<p>   7. If the parent has user resources (a concept of UID, Linux is flexible enough to<br />
   make it a question rather than a fact), then verify if the user exceeded<br />
   RLIMIT_NPROC soft limit &#8211; if so, fail with -EAGAIN, if not, increment the count of<br />
   processes by given uid p->user->count.</p>
<p>   8. If the system-wide number of tasks exceeds the value of the tunable max_threads,<br />
   fail with -EAGAIN.</p>
<p>   9. If the binary being executed belongs to a modularised execution domain, increment<br />
   the corresponding module&#8217;s reference count.</p>
<p>   10. If the binary being executed belongs to a modularised binary format, increment<br />
   the corresponding module&#8217;s reference count.</p>
<p>   11. The child is marked as &#8216;has not execed&#8217; (p->did_exec = 0)</p>
<p>   12. The child is marked as &#8216;not-swappable&#8217; (p->swappable = 0)</p>
<p>   13. The child is put into &#8216;uninterruptible sleep&#8217; state, i.e. p->state =<br />
   TASK_UNINTERRUPTIBLE (TODO: why is this done? I think it&#8217;s not needed &#8211; get rid of<br />
   it, Linus confirms it is not needed)</p>
<p>   14. The child&#8217;s p->flags are set according to the value of clone_flags; for plain<br />
   fork(2), this will be p->flags = PF_FORKNOEXEC.</p>
<p>   15. The child&#8217;s pid p->pid is set using the fast algorithm in kernel/fork.c:get_pid()<br />
   (TODO: lastpid_lock spinlock can be made redundant since get_pid() is always called<br />
   under big kernel lock from do_fork(), also remove flags argument of get_pid(),<br />
   patch sent to Alan on 20/06/2000 &#8211; followup later).</p>
<p>   16. The rest of the code in do_fork() initialises the rest of child&#8217;s task structure.<br />
   At the very end, the child&#8217;s task structure is hashed into the pidhash hashtable<br />
   and the child is woken up (TODO: wake_up_process(p) sets p->state = TASK_RUNNING<br />
   and adds the process to the runq, therefore we probably didn&#8217;t need to set p->state<br />
   to TASK_RUNNING earlier on in do_fork()). The interesting part is setting p-><br />
   exit_signal to clone_flags &#038; CSIGNAL, which for fork(2) means just SIGCHLD and<br />
   setting p->pdeath_signal to 0. The pdeath_signal is used when a process &#8216;forgets&#8217;<br />
   the original parent (by dying) and can be set/get by means of PR_GET/SET_PDEATHSIG<br />
   commands of prctl(2) system call (You might argue that the way the value of<br />
   pdeath_signal is returned via userspace pointer argument in prctl(2) is a bit silly<br />
   &#8211; mea culpa, after Andries Brouwer updated the manpage it was too late to fix ;)</p>
<p>Thus tasks are created. There are several ways for tasks to terminate:</p>
<p>1. by making exit(2) system call;<br />
   2. by being delivered a signal with default disposition to die;<br />
   3. by being forced to die under certain exceptions;<br />
   4. by calling bdflush(2) with func == 1 (this is Linux-specific, for compatibility<br />
   with old distributions that still had the &#8216;update&#8217; line in /etc/inittab &#8211; nowadays<br />
   the work of update is done by kernel thread kupdate).</p>
<p>Functions implementing system calls under Linux are prefixed with sys_, but they are<br />
   usually concerned only with argument checking or arch-specific ways to pass some<br />
   information and the actual work is done by do_ functions. So it is with sys_exit()<br />
   which calls do_exit() to do the work. Although, other parts of the kernel sometimes<br />
   invoke sys_exit() while they should really call do_exit().</p>
<p>The function do_exit() is found in kernel/exit.c. The points to note about<br />
   do_exit():</p>
<p>* Uses global kernel lock (locks but doesn&#8217;t unlock).<br />
   * Calls schedule() at the end, which never returns.<br />
   * Sets the task state to TASK_ZOMBIE.<br />
   * Notifies any child with current->pdeath_signal, if not 0.<br />
   * Notifies the parent with a current->exit_signal, which is usually equal to<br />
   SIGCHLD.<br />
   * Releases resources allocated by fork, closes open files etc.<br />
   * On architectures that use lazy FPU switching (ia64, mips, mips64) (TODO: remove<br />
   &#8216;flags&#8217; argument of sparc, sparc64), do whatever the hardware requires to pass the<br />
   FPU ownership (if owned by current) to &#8220;none&#8221;.</p>
<p>2.3 Linux Scheduler</p>
<p>The job of a scheduler is to arbitrate access to the current CPU between multiple<br />
   processes. The scheduler is implemented in the &#8216;main kernel file&#8217; kernel/sched.c.<br />
   The corresponding header file include/linux/sched.h is included (either explicitly<br />
   or indirectly) by virtually every kernel source file.</p>
<p>The fields of task structure relevant to scheduler include:</p>
<p>* p->need_resched: this field is set if schedule() should be invoked at the &#8216;next<br />
   opportunity&#8217;.<br />
   * p->counter: number of clock ticks left to run in this scheduling slice, decremented<br />
   by a timer. When this field becomes lower than or equal to zero, it is reset to 0<br />
   and p->need_resched is set. This is also sometimes called &#8216;dynamic priority&#8217; of a<br />
   process because it can change by itself.<br />
   * p->priority: the process&#8217; static priority, only changed through well-known system<br />
   calls like nice(2), POSIX.1b sched_setparam(2) or 4.4BSD/SVR4 setpriority(2).<br />
   * p->rt_priority: realtime priority<br />
   * p->policy: the scheduling policy, specifies which scheduling class the task belongs<br />
   to. Tasks can change their scheduling class using the sched_setscheduler(2) system<br />
   call. The valid values are SCHED_OTHER (traditional UNIX process), SCHED_FIFO<br />
   (POSIX.1b FIFO realtime process) and SCHED_RR (POSIX round-robin realtime process).<br />
   One can also OR SCHED_YIELD to any of these values to signify that the process<br />
   decided to yield the CPU, for example by calling sched_yield(2) system call. A FIFO<br />
   realtime process will run until either a) it blocks on I/O, b) it explicitly yields<br />
   the CPU or c) it is preempted by another realtime process with a higher p-><br />
   rt_priority value. SCHED_RR is the same as SCHED_FIFO, except that when its<br />
   timeslice expires it goes back to the end of the runqueue.</p>
<p>The scheduler&#8217;s algorithm is simple, despite the great apparent complexity of the<br />
   schedule() function. The function is complex because it implements three scheduling<br />
   algorithms in one and also because of the subtle SMP-specifics.</p>
<p>The apparently &#8216;useless&#8217; gotos in schedule() are there for a purpose &#8211; to generate<br />
   the best optimised (for i386) code. Also, note that scheduler (like most of the<br />
   kernel) was completely rewritten for 2.4, therefore the discussion below does not<br />
   apply to 2.2 or earlier kernels.</p>
<p>Let us look at the function in detail:</p>
<p>1. If current->active_mm == NULL then something is wrong. Current process, even a<br />
   kernel thread (current->mm == NULL) must have a valid p->active_mm at all times.</p>
<p>   2. If there is something to do on the tq_scheduler task queue, process it now. Task<br />
   queues provide a kernel mechanism to schedule execution of functions at a later<br />
   time. We shall look at it in details elsewhere.</p>
<p>   3. Initialise local variables prev and this_cpu to current task and current CPU<br />
   respectively.</p>
<p>   4. Check if schedule() was invoked from interrupt handler (due to a bug) and panic if<br />
   so.</p>
<p>   5. Release the global kernel lock.</p>
<p>   6. If there is some work to do via softirq mechanism, do it now.</p>
<p>   7. Initialise local pointer struct schedule_data *sched_data to point to per-CPU<br />
   (cacheline-aligned to prevent cacheline ping-pong) scheduling data area, which<br />
   contains the TSC value of last_schedule and the pointer to last scheduled task<br />
   structure (TODO: sched_data is used on SMP only but why does init_idle()<br />
   initialises it on UP as well?).</p>
<p>   8. runqueue_lock spinlock is taken. Note that we use spin_lock_irq() because in<br />
   schedule() we guarantee that interrupts are enabled. Therefore, when we unlock<br />
   runqueue_lock, we can just re-enable them instead of saving/restoring eflags<br />
   (spin_lock_irqsave/restore variant).</p>
<p>   9. task state machine: if the task is in TASK_RUNNING state, it is left alone; if it<br />
   is in TASK_INTERRUPTIBLE state and a signal is pending, it is moved into<br />
   TASK_RUNNING state. In all other cases, it is deleted from the runqueue.</p>
<p>   10. next (best candidate to be scheduled) is set to the idle task of this cpu.<br />
   However, the goodness of this candidate is set to a very low value (-1000), in hope<br />
   that there is someone better than that.</p>
<p>   11. If the prev (current) task is in TASK_RUNNING state, then the current goodness is<br />
   set to its goodness and it is marked as a better candidate to be scheduled than the<br />
   idle task.</p>
<p>   12. Now the runqueue is examined and a goodness of each process that can be scheduled<br />
   on this cpu is compared with current value; the process with highest goodness wins.<br />
   Now the concept of &#8220;can be scheduled on this cpu&#8221; must be clarified: on UP, every<br />
   process on the runqueue is eligible to be scheduled; on SMP, only process not<br />
   already running on another cpu is eligible to be scheduled on this cpu. The<br />
   goodness is calculated by a function called goodness(), which treats realtime<br />
   processes by making their goodness very high (1000 + p->rt_priority), this being<br />
   greater than 1000 guarantees that no SCHED_OTHER process can win; so they only<br />
   contend with other realtime processes that may have a greater p->rt_priority. The<br />
   goodness function returns 0 if the process&#8217; time slice (p->counter) is over. For<br />
   non-realtime processes, the initial value of goodness is set to p->counter &#8211; this<br />
   way, the process is less likely to get CPU if it already had it for a while, i.e.<br />
   interactive processes are favoured more than CPU bound number crunchers. The<br />
   arch-specific constant PROC_CHANGE_PENALTY attempts to implement &#8220;cpu affinity&#8221;<br />
   (i.e. give advantage to a process on the same CPU). It also gives a slight<br />
   advantage to processes with mm pointing to current active_mm or to processes with<br />
   no (user) address space, i.e. kernel threads.</p>
<p>   13. if the current value of goodness is 0 then the entire list of processes (not just<br />
   the ones on the runqueue!) is examined and their dynamic priorities are<br />
   recalculated using simple algorithm:</p>
<p>recalculate:<br />
   {<br />
   struct task_struct *p;<br />
   spin_unlock_irq(&#038;runqueue_lock);<br />
   read_lock(&#038;tasklist_lock);<br />
   for_each_task(p)<br />
   p->counter = (p->counter >> 1) + p->priority;<br />
   read_unlock(&#038;tasklist_lock);<br />
   spin_lock_irq(&#038;runqueue_lock);<br />
   }</p>
<p>Note that the we drop the runqueue_lock before we recalculate. The reason is that we<br />
   go through entire set of processes; this can take a long time, during which the<br />
   schedule() could be called on another CPU and select a process with goodness good<br />
   enough for that CPU, whilst we on this CPU were forced to recalculate. Ok,<br />
   admittedly this is somewhat inconsistent because while we (on this CPU) are<br />
   selecting a process with the best goodness, schedule() running on another CPU could<br />
   be recalculating dynamic priorities.</p>
<p>   14. From this point on it is certain that next points to the task to be scheduled, so<br />
   we initialise next->has_cpu to 1 and next->processor to this_cpu. The runqueue_lock<br />
   can now be unlocked.</p>
<p>   15. If we are switching back to the same task (next == prev) then we can simply<br />
   reacquire the global kernel lock and return, i.e. skip all the hardware-level<br />
   (registers, stack etc.) and VM-related (switch page directory, recalculate<br />
   active_mm etc.) stuff.</p>
<p>   16. The macro switch_to() is architecture specific. On i386, it is concerned with a)<br />
   FPU handling, b) LDT handling, c) reloading segment registers, d) TSS handling and<br />
   e) reloading debug registers.</p>
<p>2.4 Linux linked list implementation</p>
<p>Before we go on to examine implementation of wait queues, we must acquaint ourselves<br />
   with the Linux standard doubly-linked list implementation. Wait queues (as well as<br />
   everything else in Linux) make heavy use of them and they are called in jargon<br />
   &#8220;list.h implementation&#8221; because the most relevant file is include/linux/list.h.</p>
<p>The fundamental data structure here is struct list_head:</p>
<p>struct list_head {<br />
   struct list_head *next, *prev;<br />
   };</p>
<p>#define LIST_HEAD_INIT(name) { &#038;(name), &#038;(name) }</p>
<p>#define LIST_HEAD(name) \<br />
   struct list_head name = LIST_HEAD_INIT(name)</p>
<p>#define INIT_LIST_HEAD(ptr) do { \<br />
   (ptr)->next = (ptr); (ptr)->prev = (ptr); \<br />
   } while (0)</p>
<p>#define list_entry(ptr, type, member) \<br />
   ((type *)((char *)(ptr)-(unsigned long)(&#038;((type *)0)->member)))</p>
<p>#define list_for_each(pos, head) \<br />
   for (pos = (head)->next; pos != (head); pos = pos->next)</p>
<p>The first three macros are for initialising an empty list by pointing both next and<br />
   prev pointers to itself. It is obvious from C syntactical restrictions which ones<br />
   should be used where &#8211; for example, LIST_HEAD_INIT() can be used for structure&#8217;s<br />
   element initialisation in declaration, the second can be used for static variable<br />
   initialising declarations and the third can be used inside a function.</p>
<p>The macro list_entry() gives access to individual list element, for example (from<br />
   fs/file_table.c:fs_may_remount_ro()):</p>
<p>struct super_block {<br />
   &#8230;<br />
   struct list_head s_files;<br />
   &#8230;<br />
   } *sb = &#038;some_super_block;</p>
<p>struct file {<br />
   &#8230;<br />
   struct list_head f_list;<br />
   &#8230;<br />
   } *file;</p>
<p>struct list_head *p;</p>
<p>for (p = sb->s_files.next; p != &#038;sb->s_files; p = p->next) {<br />
   struct file *file = list_entry(p, struct file, f_list);<br />
   do something to &#8216;file&#8217;<br />
   }</p>
<p>A good example of the use of list_for_each() macro is in the scheduler where we walk<br />
   the runqueue looking for the process with highest goodness:</p>
<p>static LIST_HEAD(runqueue_head);<br />
   struct list_head *tmp;<br />
   struct task_struct *p;</p>
<p>list_for_each(tmp, &#038;runqueue_head) {<br />
   p = list_entry(tmp, struct task_struct, run_list);<br />
   if (can_schedule(p)) {<br />
   int weight = goodness(p, this_cpu, prev->active_mm);<br />
   if (weight > c)<br />
   c = weight, next = p;<br />
   }<br />
   }</p>
<p>Here, p->run_list is declared as struct list_head run_list inside task_struct<br />
   structure and serves as anchor to the list. Removing an element from the list and<br />
   adding (to head or tail of the list) is done by<br />
   list_del()/list_add()/list_add_tail() macros. The examples below are adding and<br />
   removing a task from runqueue:</p>
<p>static inline void del_from_runqueue(struct task_struct * p)<br />
   {<br />
   nr_running&#8211;;<br />
   list_del(&#038;p->run_list);<br />
   p->run_list.next = NULL;<br />
   }</p>
<p>static inline void add_to_runqueue(struct task_struct * p)<br />
   {<br />
   list_add(&#038;p->run_list, &#038;runqueue_head);<br />
   nr_running++;<br />
   }</p>
<p>static inline void move_last_runqueue(struct task_struct * p)<br />
   {<br />
   list_del(&#038;p->run_list);<br />
   list_add_tail(&#038;p->run_list, &#038;runqueue_head);<br />
   }</p>
<p>static inline void move_first_runqueue(struct task_struct * p)<br />
   {<br />
   list_del(&#038;p->run_list);<br />
   list_add(&#038;p->run_list, &#038;runqueue_head);<br />
   }</p>
<p>2.5 Wait Queues</p>
<p>When a process requests the kernel to do something which is currently impossible but<br />
   that may become possible later, the process is put to sleep and is woken up when<br />
   the request is more likely to be satisfied. One of the kernel mechanisms used for<br />
   this is called a &#8216;wait queue&#8217;.</p>
<p>Linux implementation allows wake-on semantics using TASK_EXCLUSIVE flag. With<br />
   waitqueues, you can either use a well-known queue and then simply<br />
   sleep_on/sleep_on_timeout/interruptible_sleep_on/interruptible_sleep_on_timeout, or<br />
   you can define your own waitqueue and use add/remove_wait_queue to add and remove<br />
   yourself from it and wake_up/wake_up_interruptible to wake up when needed.</p>
<p>An example of the first usage of waitqueues is interaction between the page allocator<br />
   (in mm/page_alloc.c:__alloc_pages()) and the kswapd kernel daemon (in<br />
   mm/vmscan.c:kswap()), by means of wait queue kswapd_wait, declared in mm/vmscan.c;<br />
   the kswapd daemon sleeps on this queue, and it is woken up whenever the page<br />
   allocator needs to free up some pages.</p>
<p>An example of autonomous waitqueue usage is interaction between user process<br />
   requesting data via read(2) system call and kernel running in the interrupt context<br />
   to supply the data. An interrupt handler might look like (simplified<br />
   drivers/char/rtc_interrupt()):</p>
<p>static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);</p>
<p>void rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)<br />
   {<br />
   spin_lock(&#038;rtc_lock);<br />
   rtc_irq_data = CMOS_READ(RTC_INTR_FLAGS);<br />
   spin_unlock(&#038;rtc_lock);<br />
   wake_up_interruptible(&#038;rtc_wait);<br />
   }</p>
<p>So, the interrupt handler obtains the data by reading from some device-specific I/O<br />
   port (CMOS_READ() macro turns into a couple outb/inb) and then wakes up whoever is<br />
   sleeping on the rtc_wait wait queue.</p>
<p>Now, the read(2) system call could be implemented as:</p>
<p>ssize_t rtc_read(struct file file, char *buf, size_t count, loff_t *ppos)<br />
   {<br />
   DECLARE_WAITQUEUE(wait, current);<br />
   unsigned long data;<br />
   ssize_t retval;</p>
<p>add_wait_queue(&#038;rtc_wait, &#038;wait);<br />
   current->state = TASK_INTERRUPTIBLE;<br />
   do {<br />
   spin_lock_irq(&#038;rtc_lock);<br />
   data = rtc_irq_data;<br />
   rtc_irq_data = 0;<br />
   spin_unlock_irq(&#038;rtc_lock);</p>
<p>if (data != 0)<br />
   break;</p>
<p>if (file->f_flags &#038; O_NONBLOCK) {<br />
   retval = -EAGAIN;<br />
   goto out;<br />
   }<br />
   if (signal_pending(current)) {<br />
   retval = -ERESTARTSYS;<br />
   goto out;<br />
   }<br />
   schedule();<br />
   } while(1);<br />
   retval = put_user(data, (unsigned long *)buf);<br />
   if (!retval)<br />
   retval = sizeof(unsigned long);</p>
<p>out:<br />
   current->state = TASK_RUNNING;<br />
   remove_wait_queue(&#038;rtc_wait, &#038;wait);<br />
   return retval;<br />
   }</p>
<p>What happens in rtc_read() is this:</p>
<p>   1. We declare a wait queue element pointing to current process context.</p>
<p>   2. We add this element to the rtc_wait waitqueue.</p>
<p>   3. We mark current context as TASK_INTERRUPTIBLE which means it will not be<br />
   rescheduled after the next time it sleeps.</p>
<p>   4. We check if there is no data available; if there is we break out, copy data to<br />
   user buffer, mark ourselves as TASK_RUNNING, remove ourselves from the wait queue<br />
   and return<br />
   5. If there is no data yet, we check whether the user specified non-blocking I/O and<br />
   if so we fail with EAGAIN (which is the same as EWOULDBLOCK)</p>
<p>   6. We also check if a signal is pending and if so inform the &#8220;higher layers&#8221; to<br />
   restart the system call if necessary. By &#8220;if necessary&#8221; I meant the details of<br />
   signal disposition as specified in sigaction(2) system call.</p>
<p>   7. Then we &#8220;switch out&#8221;, i.e. fall asleep, until woken up by the interrupt handler.<br />
   If we didn&#8217;t mark ourselves as TASK_INTERRUPTIBLE then the scheduler could schedule<br />
   us sooner than when the data is available, thus causing unneeded processing.</p>
<p>It is also worth pointing out that, using wait queues, it is rather easy to implement<br />
   the poll(2) system call:</p>
<p>static unsigned int rtc_poll(struct file *file, poll_table *wait)<br />
   {<br />
   unsigned long l;</p>
<p>poll_wait(file, &#038;rtc_wait, wait);</p>
<p>spin_lock_irq(&#038;rtc_lock);<br />
   l = rtc_irq_data;<br />
   spin_unlock_irq(&#038;rtc_lock);</p>
<p>if (l != 0)<br />
   return POLLIN | POLLRDNORM;<br />
   return 0;<br />
   }</p>
<p>All the work is done by the device-independent function poll_wait() which does the<br />
   necessary waitqueue manipulations; all we need to do is point it to the waitqueue<br />
   which is woken up by our device-specific interrupt handler.</p>
<p>2.6 Kernel Timers</p>
<p>Now let us turn our attention to kernel timers. Kernel timers are used to dispatch<br />
   execution of a particular function (called &#8216;timer handler&#8217;) at a specified time in<br />
   the future. The main data structure is struct timer_list declared in<br />
   include/linux/timer.h:</p>
<p>struct timer_list {<br />
   struct list_head list;<br />
   unsigned long expires;<br />
   unsigned long data;<br />
   void (*function)(unsigned long);<br />
   volatile int running;<br />
   };</p>
<p>The list field is for linking into the internal list, protected by the timerlist_lock<br />
   spinlock. The expires field is the value of jiffies when the function handler<br />
   should be invoked with data passed as a parameter. The running field is used on SMP<br />
   to test if the timer handler is currently running on another CPU.</p>
<p>The functions add_timer() and del_timer() add and remove a given timer to the list.<br />
   When a timer expires, it is removed automatically. Before a timer is used, it MUST<br />
   be initialised by means of init_timer() function. And before it is added, the<br />
   fields function and expires must be set.</p>
<p>2.7 Bottom Halves</p>
<p>Sometimes it is reasonable to split the amount of work to be performed inside an<br />
   interrupt handler into immediate work (e.g. acknowledging the interrupt, updating<br />
   the stats etc.) and work which can be postponed until later, when interrupts are<br />
   enabled (e.g. to do some postprocessing on data, wake up processes waiting for this<br />
   data, etc).</p>
<p>Bottom halves are the oldest mechanism for deferred execution of kernel tasks and<br />
   have been available since Linux 1.x. In Linux 2.0, a new mechanism was added,<br />
   called &#8216;task queues&#8217;, which will be the subject of next section.</p>
<p>Bottom halves are serialised by the global_bh_lock spinlock, i.e. there can only be<br />
   one bottom half running on any CPU at a time. However, when attempting to execute<br />
   the handler, if global_bh_lock is not available, the bottom half is marked (i.e.<br />
   scheduled) for execution &#8211; so processing can continue, as opposed to a busy loop on<br />
   global_bh_lock.</p>
<p>There can only be 32 bottom halves registered in total. The functions required to<br />
   manipulate bottom halves are as follows (all exported to modules):</p>
<p>* void init_bh(int nr, void (*routine)(void)): installs a bottom half handler pointed<br />
   to by routine argument into slot nr. The slot ought to be enumerated in<br />
   include/linux/interrupt.h in the form XXXX_BH, e.g. TIMER_BH or TQUEUE_BH.<br />
   Typically, a subsystem&#8217;s initialisation routine (init_module() for modules)<br />
   installs the required bottom half using this function.</p>
<p>* void remove_bh(int nr): does the opposite of init_bh(), i.e. de-installs bottom<br />
   half installed at slot nr. There is no error checking performed there, so, for<br />
   example remove_bh(32) will panic/oops the system. Typically, a subsystem&#8217;s cleanup<br />
   routine (cleanup_module() for modules) uses this function to free up the slot that<br />
   can later be reused by some other subsystem. (TODO: wouldn&#8217;t it be nice to have<br />
   /proc/bottom_halves list all registered bottom halves on the system? That means<br />
   global_bh_lock must be made read/write, obviously)</p>
<p>* void mark_bh(int nr): marks bottom half in slot nr for execution. Typically, an<br />
   interrupt handler will mark its bottom half (hence the name!) for execution at a<br />
   &#8220;safer time&#8221;.</p>
<p>Bottom halves are globally locked tasklets, so the question &#8220;when are bottom half<br />
   handlers executed?&#8221; is really &#8220;when are tasklets executed?&#8221;. And the answer is, in<br />
   two places: a) on each schedule() and b) on each interrupt/syscall return path in<br />
   entry.S (TODO: therefore, the schedule() case is really boring &#8211; it like adding yet<br />
   another very very slow interrupt, why not get rid of handle_softirq label from<br />
   schedule() altogether?).</p>
<p>2.8 Task Queues</p>
<p>Task queues can be though of as a dynamic extension to old bottom halves. In fact, in<br />
   the source code they are sometimes referred to as &#8220;new&#8221; bottom halves. More<br />
   specifically, the old bottom halves discussed in previous section have these<br />
   limitations:</p>
<p>1. There are only a fixed number (32) of them.<br />
   2. Each bottom half can only be associated with one handler function.<br />
   3. Bottom halves are consumed with a spinlock held so they cannot block.</p>
<p>So, with task queues, arbitrary number of functions can be chained and processed one<br />
   after another at a later time. One creates a new task queue using the<br />
   DECLARE_TASK_QUEUE() macro and queues a task onto it using the queue_task()<br />
   function. The task queue then can be processed using run_task_queue(). Instead of<br />
   creating your own task queue (and having to consume it manually) you can use one of<br />
   Linux&#8217; predefined task queues which are consumed at well-known points:</p>
<p>1. tq_timer: the timer task queue, run on each timer interrupt and when releasing a<br />
   tty device (closing or releasing a half-opened terminal device). Since the timer<br />
   handler runs in interrupt context, the tq_timer tasks also run in interrupt context<br />
   and thus cannot block.</p>
<p>2. tq_scheduler: the scheduler task queue, consumed by the scheduler (and also when<br />
   closing tty devices, like tq_timer). Since the scheduler executed in the context of<br />
   the process being re-scheduled, the tq_scheduler tasks can do anything they like,<br />
   i.e. block, use process context data (but why would they want to), etc.</p>
<p>3. tq_immediate: this is really a bottom half IMMEDIATE_BH, so drivers can<br />
   queue_task(task, &#038;tq_immediate) and then mark_bh(IMMEDIATE_BH) to be consumed in<br />
   interrupt context.</p>
<p>4. tq_disk: used by low level block device access (and RAID) to start the actual<br />
   requests. This task queue is exported to modules but shouldn&#8217;t be used except for<br />
   the special purposes which it was designed for.</p>
<p>Unless a driver uses its own task queues, it does not need to call run_tasks_queues()<br />
   to process the queue, except under circumstances explained below.</p>
<p>The reason tq_timer/tq_scheduler task queues are consumed not only in the usual<br />
   places but elsewhere (closing tty device is but one example) becomes clear if one<br />
   remembers that the driver can schedule tasks on the queue, and these tasks only<br />
   make sense while a particular instance of the device is still valid &#8211; which usually<br />
   means until the application closes it. So, the driver may need to call<br />
   run_task_queue() to flush the tasks it (and anyone else) has put on the queue,<br />
   because allowing them to run at a later time may make no sense &#8211; i.e. the relevant<br />
   data structures may have been freed/reused by a different instance. This is the<br />
   reason you see run_task_queue() on tq_timer and tq_scheduler in places other than<br />
   timer interrupt and schedule() respectively.</p>
<p>2.9 Tasklets</p>
<p>Not yet, will be in future revision.</p>
<p>2.10 Softirqs</p>
<p>Not yet, will be in future revision.</p>
<p>2.11 How System Calls Are Implemented on i386 Architecture?</p>
<p>There are two mechanisms under Linux for implementing system calls:</p>
<p>* lcall7/lcall27 call gates;<br />
   * int 0&#215;80 software interrupt.</p>
<p>Native Linux programs use int 0&#215;80 whilst binaries from foreign flavours of UNIX<br />
   (Solaris, UnixWare 7 etc.) use the lcall7 mechanism. The name &#8216;lcall7&#8242; is<br />
   historically misleading because it also covers lcall27 (e.g. Solaris/x86), but the<br />
   handler function is called lcall7_func.</p>
<p>When the system boots, the function arch/i386/kernel/traps.c:trap_init() is called<br />
   which sets up the IDT so that vector 0&#215;80 (of type 15, dpl 3) points to the address<br />
   of system_call entry from arch/i386/kernel/entry.S.</p>
<p>When a userspace application makes a system call, the arguments are passed via<br />
   registers and the application executes &#8216;int 0&#215;80&#8242; instruction. This causes a trap<br />
   into kernel mode and processor jumps to system_call entry point in entry.S. What<br />
   this does is:</p>
<p>1. Save registers.</p>
<p>2. Set %ds and %es to KERNEL_DS, so that all data (and extra segment) references are<br />
   made in kernel address space.</p>
<p>3. If the value of %eax is greater than NR_syscalls (currently 256), fail with ENOSYS<br />
   error.</p>
<p>4. If the task is being ptraced (tsk->ptrace &#038; PF_TRACESYS), do special processing.<br />
   This is to support programs like strace (analogue of SVR4 truss(1)) or debuggers.</p>
<p>5. Call sys_call_table+4*(syscall_number from %eax). This table is initialised in the<br />
   same file (arch/i386/kernel/entry.S) to point to individual system call handlers<br />
   which under Linux are (usually) prefixed with sys_, e.g. sys_open, sys_exit, etc.<br />
   These C system call handlers will find their arguments on the stack where SAVE_ALL<br />
   stored them.</p>
<p>6. Enter &#8216;system call return path&#8217;. This is a separate label because it is used not<br />
   only by int 0&#215;80 but also by lcall7, lcall27. This is concerned with handling<br />
   tasklets (including bottom halves), checking if a schedule() is needed (tsk-><br />
   need_resched != 0), checking if there are signals pending and if so handling them.</p>
<p>Linux supports up to 6 arguments for system calls. They are passed in %ebx, %ecx,<br />
   %edx, %esi, %edi (and %ebp used temporarily, see _syscall6() in asm-i386/unistd.h).<br />
   The system call number is passed via %eax.</p>
<p>2.12 Atomic Operations</p>
<p>There are two types of atomic operations: bitmaps and atomic_t. Bitmaps are very<br />
   convenient for maintaining a concept of &#8220;allocated&#8221; or &#8220;free&#8221; units from some large<br />
   collection where each unit is identified by some number, for example free inodes or<br />
   free blocks. They are also widely used for simple locking, for example to provide<br />
   exclusive access to open a device. An example of this can be found in<br />
   arch/i386/kernel/microcode.c:</p>
<p>/*<br />
   * Bits in microcode_status. (31 bits of room for future expansion)<br />
   */<br />
   #define MICROCODE_IS_OPEN 0 /* set if device is in use */</p>
<p>static unsigned long microcode_status;</p>
<p>There is no need to initialise microcode_status to 0 as BSS is zero-cleared under<br />
   Linux explicitly.</p>
<p>/*<br />
   * We enforce only one user at a time here with open/close.<br />
   */<br />
   static int microcode_open(struct inode *inode, struct file *file)<br />
   {<br />
   if (!capable(CAP_SYS_RAWIO))<br />
   return -EPERM;</p>
<p>/* one at a time, please */<br />
   if (test_and_set_bit(MICROCODE_IS_OPEN, &#038;microcode_status))<br />
   return -EBUSY;</p>
<p>MOD_INC_USE_COUNT;<br />
   return 0;<br />
   }</p>
<p>The operations on bitmaps are:</p>
<p>* void set_bit(int nr, volatile void *addr): set bit nr in the bitmap pointed to by<br />
   addr.<br />
   * void clear_bit(int nr, volatile void *addr): clear bit nr in the bitmap pointed to<br />
   by addr.<br />
   * void change_bit(int nr, volatile void *addr): toggle bit nr (if set clear, if clear<br />
   set) in the bitmap pointed to by addr.<br />
   * int test_and_set_bit(int nr, volatile void *addr): atomically set bit nr and return<br />
   the old bit value.<br />
   * int test_and_clear_bit(int nr, volatile void *addr): atomically clear bit nr and<br />
   return the old bit value.<br />
   * int test_and_change_bit(int nr, volatile void *addr): atomically toggle bit nr and<br />
   return the old bit value.</p>
<p>These operations use the LOCK_PREFIX macro, which on SMP kernels evaluates to bus<br />
   lock instruction prefix and to nothing on UP. This guarantees atomicity of access<br />
   in SMP environment.</p>
<p>Sometimes bit manipulations are not convenient, but instead we need to perform<br />
   arithmetic operations &#8211; add, subtract, increment decrement. The typical cases are<br />
   reference counts (e.g. for inodes). This facility is provided by the atomic_t data<br />
   type and the following operations:</p>
<p>* atomic_read(&#038;v): read the value of atomic_t variable v.<br />
   * atomic_set(&#038;v, i): set the value of atomic_t variable v to integer i.<br />
   * void atomic_add(int i, volatile atomic_t *v): add integer i to the value of atomic<br />
   variable pointed to by v.<br />
   * void atomic_sub(int i, volatile atomic_t *v): subtract integer i from the value of<br />
   atomic variable pointed to by v.<br />
   * int atomic_sub_and_test(int i, volatile atomic_t *v): subtract integer i from the<br />
   value of atomic variable pointed to by v; return 1 if the new value is 0, return 0<br />
   otherwise.<br />
   * void atomic_inc(volatile atomic_t *v): increment the value by 1.<br />
   * void atomic_dec(volatile atomic_t *v): decrement the value by 1.<br />
   * int atomic_dec_and_test(volatile atomic_t *v): decrement the value; return 1 if the<br />
   new value is 0, return 0 otherwise.<br />
   * int atomic_inc_and_test(volatile atomic_t *v): increment the value; return 1 if the<br />
   new value is 0, return 0 otherwise.<br />
   * int atomic_add_negative(int i, volatile atomic_t *v): add the value of i to v and<br />
   return 1 if the result is negative. Return 0 if the result is greater than or equal<br />
   to 0. This operation is used for implementing semaphores.</p>
<p>2.13 Spinlocks, Read-write Spinlocks and Big-Reader Spinlocks</p>
<p>Since the early days of Linux support (early 90s, this century), developers were<br />
   faced with the classical problem of accessing shared data between different types<br />
   of context (user process vs interrupt) and different instances of the same context<br />
   from multiple cpus.</p>
<p>SMP support was added to Linux 1.3.42 on 15 Nov 1995 (the original patch was made to<br />
   1.3.37 in October the same year).</p>
<p>If the critical region of code may be executed by either process context and<br />
   interrupt context, then the way to protect it using cli/sti instructions on UP is:</p>
<p>unsigned long flags;</p>
<p>save_flags(flags);<br />
   cli();<br />
   /* critical code */<br />
   restore_flags(flags);</p>
<p>While this is ok on UP, it obviously is of no use on SMP because the same code<br />
   sequence may be executed simultaneously on another cpu, and while cli() provides<br />
   protection against races with interrupt context on each CPU individually, it<br />
   provides no protection at all against races between contexts running on different<br />
   CPUs. This is where spinlocks are useful for.</p>
<p>There are three types of spinlocks: vanilla (basic), read-write and big-reader<br />
   spinlocks. Read-write spinlocks should be used when there is a natural tendency of<br />
   &#8216;many readers and few writers&#8217;. Example of this is access to the list of registered<br />
   filesystems (see fs/super.c). The list is guarded by the file_systems_lock<br />
   read-write spinlock because one needs exclusive access only when<br />
   registering/unregistering a filesystem, but any process can read the file<br />
   /proc/filesystems or use the sysfs(2) system call to force a read-only scan of the<br />
   file_systems list. This makes it sensible to use read-write spinlocks. With<br />
   read-write spinlocks, one can have multiple readers at a time but only one writer<br />
   and there can be no readers while there is a writer. </p>
<p>Btw, it would be nice if new<br />
   readers would not get a lock while there is a writer trying to get a lock, i.e. if<br />
   Linux could correctly deal with the issue of potential writer starvation by<br />
   multiple readers. This would mean that readers must be blocked while there is a<br />
   writer attempting to get the lock. This is not currently the case and it is not<br />
   obvious whether this should be fixed &#8211; the argument to the contrary is &#8211; readers<br />
   usually take the lock for a very short time so should they really be starved while<br />
   the writer takes the lock for potentially longer periods?</p>
<p>Big-reader spinlocks are a form of read-write spinlocks heavily optimised for very<br />
   light read access, with a penalty for writes. There is a limited number of<br />
   big-reader spinlocks &#8211; currently only two exist, of which one is used only on<br />
   sparc64 (global irq) and the other is used for networking. In all other cases where<br />
   the access pattern does not fit into any of these two scenarios, one should use<br />
   basic spinlocks. You cannot block while holding any kind of spinlock.</p>
<p>Spinlocks come in three flavours: plain, _irq() and _bh().</p>
<p>1. Plain spin_lock()/spin_unlock(): if you know the interrupts are always disabled or<br />
   if you do not race with interrupt context (e.g. from within interrupt handler),<br />
   then you can use this one. It does not touch interrupt state on the current CPU.</p>
<p>2. spin_lock_irq()/spin_unlock_irq(): if you know that interrupts are always enabled<br />
   then you can use this version, which simply disables (on lock) and re-enables (on<br />
   unlock) interrupts on the current CPU. For example, rtc_read() uses spin_lock_irq(&#038;<br />
   rtc_lock) (interrupts are always enabled inside read()) whilst rtc_interrupt() uses<br />
   spin_lock(&#038;rtc_lock) (interrupts are always disabled inside interrupt handler).<br />
   Note that rtc_read() uses spin_lock_irq() and not the more generic<br />
   spin_lock_irqsave() because on entry to any system call interrupts are always<br />
   enabled.</p>
<p>3. spin_lock_irqsave()/spin_unlock_irqrestore(): the strongest form, to be used when<br />
   the interrupt state is not known, but only if interrupts matter at all, i.e. there<br />
   is no point in using it if our interrupt handlers don&#8217;t execute any critical code.</p>
<p>The reason you cannot use plain spin_lock() if you race against interrupt handlers is<br />
   because if you take it and then an interrupt comes in on the same CPU, it will busy<br />
   wait for the lock forever: the lock holder, having been interrupted, will not<br />
   continue until the interrupt handler returns.</p>
<p>The most common usage of a spinlock is to access a data structure shared between user<br />
   process context and interrupt handlers:</p>
<p>spinlock_t my_lock = SPIN_LOCK_UNLOCKED;</p>
<p>my_ioctl()<br />
   {<br />
   spin_lock_irq(&#038;my_lock);<br />
   /* critical section */<br />
   spin_unlock_irq(&#038;my_lock);<br />
   }</p>
<p>my_irq_handler()<br />
   {<br />
   spin_lock(&#038;lock);<br />
   /* critical section */<br />
   spin_unlock(&#038;lock);<br />
   }</p>
<p>There are a couple of things to note about this example:</p>
<p>1. The process context, represented here as a typical driver method &#8211; ioctl()<br />
   (arguments and return values omitted for clarity), must use spin_lock_irq() because<br />
   it knows that interrupts are always enabled while executing the device ioctl()<br />
   method.<br />
   2. Interrupt context, represented here by my_irq_handler() (again arguments omitted<br />
   for clarity) can use plain spin_lock() form because interrupts are disabled inside<br />
   an interrupt handler.</p>
<p>2.14 Semaphores and read/write Semaphores</p>
<p>Sometimes, while accessing a shared data structure, one must perform operations that<br />
   can block, for example copy data to userspace. The locking primitive available for<br />
   such scenarios under Linux is called a semaphore. There are two types of<br />
   semaphores: basic and read-write semaphores. Depending on the initial value of the<br />
   semaphore, they can be used for either mutual exclusion (initial value of 1) or to<br />
   provide more sophisticated type of access.</p>
<p>Read-write semaphores differ from basic semaphores in the same way as read-write<br />
   spinlocks differ from basic spinlocks: one can have multiple readers at a time but<br />
   only one writer and there can be no readers while there are writers &#8211; i.e. the<br />
   writer blocks all readers and new readers block while a writer is waiting.</p>
<p>Also, basic semaphores can be interruptible &#8211; just use the operations<br />
   down/up_interruptible() instead of the plain down()/up() and check the value<br />
   returned from down_interruptible(): it will be non zero if the operation was<br />
   interrupted.</p>
<p>Using semaphores for mutual exclusion is ideal in situations where a critical code<br />
   section may call by reference unknown functions registered by other<br />
   subsystems/modules, i.e. the caller cannot know apriori whether the function blocks<br />
   or not.</p>
<p>A simple example of semaphore usage is in kernel/sys.c, implementation of<br />
   gethostname(2)/sethostname(2) system calls.</p>
<p>asmlinkage long sys_sethostname(char *name, int len)<br />
   {<br />
   int errno;</p>
<p>if (!capable(CAP_SYS_ADMIN))<br />
   return -EPERM;<br />
   if (len < 0 || len > __NEW_UTS_LEN)<br />
   return -EINVAL;<br />
   down_write(&#038;uts_sem);<br />
   errno = -EFAULT;<br />
   if (!copy_from_user(system_utsname.nodename, name, len)) {<br />
   system_utsname.nodename[len] = 0;<br />
   errno = 0;<br />
   }<br />
   up_write(&#038;uts_sem);<br />
   return errno;<br />
   }</p>
<p>asmlinkage long sys_gethostname(char *name, int len)<br />
   {<br />
   int i, errno;</p>
<p>if (len < 0)<br />
   return -EINVAL;<br />
   down_read(&#038;uts_sem);<br />
   i = 1 + strlen(system_utsname.nodename);<br />
   if (i > len)<br />
   i = len;<br />
   errno = 0;<br />
   if (copy_to_user(name, system_utsname.nodename, i))<br />
   errno = -EFAULT;<br />
   up_read(&#038;uts_sem);<br />
   return errno;<br />
   }</p>
<p>The points to note about this example are:</p>
<p>1. The functions may block while copying data from/to userspace in<br />
   copy_from_user()/copy_to_user(). Therefore they could not use any form of spinlock<br />
   here.<br />
   2. The semaphore type chosen is read-write as opposed to basic because there may be<br />
   lots of concurrent gethostname(2) requests which need not be mutually exclusive.</p>
<p>Although Linux implementation of semaphores and read-write semaphores is very<br />
   sophisticated, there are possible scenarios one can think of which are not yet<br />
   implemented, for example there is no concept of interruptible read-write<br />
   semaphores. This is obviously because there are no real-world situations which<br />
   require these exotic flavours of the primitives.</p>
<p>2.15 Kernel Support for Loading Modules</p>
<p>Linux is a monolithic operating system and despite all the modern hype about some<br />
   &#8220;advantages&#8221; offered by operating systems based on micro-kernel design, the truth<br />
   remains (quoting Linus Torvalds himself):</p>
<p>&#8230; message passing as the fundamental operation of the OS is just an exercise in<br />
   computer science masturbation. It may feel good, but you don&#8217;t actually get<br />
   anything DONE.</p>
<p>Therefore, Linux is and will always be based on a monolithic design, which means that<br />
   all subsystems run in the same privileged mode and share the same address space;<br />
   communication between them is achieved by the usual C function call means.</p>
<p>However, although separating kernel functionality into separate &#8220;processes&#8221; as is<br />
   done in micro-kernels is definitely a bad idea, separating it into dynamically<br />
   loadable on demand kernel modules is desirable in some circumstances (e.g. on<br />
   machines with low memory or for installation kernels which could otherwise contain<br />
   ISA auto-probing device drivers that are mutually exclusive). The decision whether<br />
   to include support for loadable modules is made at compile time and is determined<br />
   by the CONFIG_MODULES option. Support for module autoloading via request_module()<br />
   mechanism is a separate compilation option (CONFIG_KMOD).</p>
<p>The following functionality can be implemented as loadable modules under Linux:</p>
<p>1. Character and block device drivers, including misc device drivers.<br />
   2. Terminal line disciplines.<br />
   3. Virtual (regular) files in /proc and in devfs (e.g. /dev/cpu/microcode vs<br />
   /dev/misc/microcode).<br />
   4. Binary file formats (e.g. ELF, aout, etc).<br />
   5. Execution domains (e.g. Linux, UnixWare7, Solaris, etc).<br />
   6. Filesystems.<br />
   7. System V IPC.</p>
<p>There a few things that cannot be implemented as modules under Linux (probably<br />
   because it makes no sense for them to be modularised):</p>
<p>1. Scheduling algorithms.<br />
   2. VM policies.<br />
   3. Buffer cache, page cache and other caches.</p>
<p>Linux provides several system calls to assist in loading modules:</p>
<p>1. caddr_t create_module(const char *name, size_t size): allocates size bytes using<br />
   vmalloc() and maps a module structure at the beginning thereof. This new module is<br />
   then linked into the list headed by module_list. Only a process with CAP_SYS_MODULE<br />
   can invoke this system call, others will get EPERM returned.</p>
<p>2. long init_module(const char *name, struct module *image): loads the relocated<br />
   module image and causes the module&#8217;s initialisation routine to be invoked. Only a<br />
   process with CAP_SYS_MODULE can invoke this system call, others will get EPERM<br />
   returned.</p>
<p>3. long delete_module(const char *name): attempts to unload the module. If name ==<br />
   NULL, attempt is made to unload all unused modules.</p>
<p>4. long query_module(const char *name, int which, void *buf, size_t bufsize, size_t<br />
   *ret): returns information about a module (or about all modules).</p>
<p>The command interface available to users consists of:</p>
<p>* insmod: insert a single module.<br />
   * modprobe: insert a module including all other modules it depends on.<br />
   * rmmod: remove a module.<br />
   * modinfo: print some information about a module, e.g. author, description,<br />
   parameters the module accepts, etc.</p>
<p>Apart from being able to load a module manually using either insmod or modprobe, it<br />
   is also possible to have the module inserted automatically by the kernel when a<br />
   particular functionality is required. The kernel interface for this is the function<br />
   called request_module(name) which is exported to modules, so that modules can load<br />
   other modules as well. The request_module(name) internally creates a kernel thread<br />
   which execs the userspace command modprobe -s -k module_name, using the standard<br />
   exec_usermodehelper() kernel interface (which is also exported to modules). The<br />
   function returns 0 on success, however it is usually not worth checking the return<br />
   code from request_module(). Instead, the programming idiom is:</p>
<p>if (check_some_feature() == NULL)<br />
   request_module(module);<br />
   if (check_some_feature() == NULL)<br />
   return -ENODEV;</p>
<p>For example, this is done by fs/block_dev.c:get_blkfops() to load a module<br />
   block-major-N when attempt is made to open a block device with major N. Obviously,<br />
   there is no such module called block-major-N (Linux developers only chose sensible<br />
   names for their modules) but it is mapped to a proper module name using the file<br />
   /etc/modules.conf. However, for most well-known major numbers (and other kinds of<br />
   modules) the modprobe/insmod commands know which real module to load without<br />
   needing an explicit alias statement in /etc/modules.conf.</p>
<p>A good example of loading a module is inside the mount(2) system call. The mount(2)<br />
   system call accepts the filesystem type as a string which fs/super.c:do_mount()<br />
   then passes on to fs/super.c:get_fs_type():</p>
<p>static struct file_system_type *get_fs_type(const char *name)<br />
   {<br />
   struct file_system_type *fs;</p>
<p>read_lock(&#038;file_systems_lock);<br />
   fs = *(find_filesystem(name));<br />
   if (fs &#038;&#038; !try_inc_mod_count(fs->owner))<br />
   fs = NULL;<br />
   read_unlock(&#038;file_systems_lock);<br />
   if (!fs &#038;&#038; (request_module(name) == 0)) {<br />
   read_lock(&#038;file_systems_lock);<br />
   fs = *(find_filesystem(name));<br />
   if (fs &#038;&#038; !try_inc_mod_count(fs->owner))<br />
   fs = NULL;<br />
   read_unlock(&#038;file_systems_lock);<br />
   }<br />
   return fs;<br />
   }</p>
<p>A few things to note in this function:</p>
<p>1. First we attempt to find the filesystem with the given name amongst those already<br />
   registered. This is done under protection of file_systems_lock taken for read (as<br />
   we are not modifying the list of registered filesystems).</p>
<p>2. If such a filesystem is found then we attempt to get a new reference to it by<br />
   trying to increment its module&#8217;s hold count. This always returns 1 for statically<br />
   linked filesystems or for modules not presently being deleted. If<br />
   try_inc_mod_count() returned 0 then we consider it a failure &#8211; i.e. if the module<br />
   is there but is being deleted, it is as good as if it were not there at all.</p>
<p>3. We drop the file_systems_lock because what we are about to do next<br />
   (request_module()) is a blocking operation, and therefore we can&#8217;t hold a spinlock<br />
   over it. Actually, in this specific case, we would have to drop file_systems_lock<br />
   anyway, even if request_module() were guaranteed to be non-blocking and the module<br />
   loading were executed in the same context atomically. The reason for this is that<br />
   the module&#8217;s initialisation function will try to call register_filesystem(), which<br />
   will take the same file_systems_lock read-write spinlock for write.</p>
<p>4. If the attempt to load was successful, then we take the file_systems_lock spinlock<br />
   and try to locate the newly registered filesystem in the list. Note that this is<br />
   slightly wrong because it is in principle possible for a bug in modprobe command to<br />
   cause it to coredump after it successfully loaded the requested module, in which<br />
   case request_module() will fail even though the new filesystem will be registered,<br />
   and yet get_fs_type() won&#8217;t find it.</p>
<p>5. If the filesystem is found and we are able to get a reference to it, we return it.<br />
   Otherwise we return NULL.</p>
<p>When a module is loaded into the kernel, it can refer to any symbols that are<br />
   exported as public by the kernel using EXPORT_SYMBOL() macro or by other currently<br />
   loaded modules. If the module uses symbols from another module, it is marked as<br />
   depending on that module during dependency recalculation, achieved by running<br />
   depmod -a command on boot (e.g. after installing a new kernel).</p>
<p>Usually, one must match the set of modules with the version of the kernel interfaces<br />
   they use, which under Linux simply means the &#8220;kernel version&#8221; as there is no<br />
   special kernel interface versioning mechanism in general. However, there is a<br />
   limited functionality called &#8220;module versioning&#8221; or CONFIG_MODVERSIONS which allows<br />
   to avoid recompiling modules when switching to a new kernel. What happens here is<br />
   that the kernel symbol table is treated differently for internal access and for<br />
   access from modules. The elements of public (i.e. exported) part of the symbol<br />
   table are built by 32bit checksumming the C declaration. </p>
<p>So, in order to resolve a<br />
   symbol used by a module during loading, the loader must match the full<br />
   representation of the symbol that includes the checksum; it will refuse to load the<br />
   module if these symbols differ. This only happens when both the kernel and the<br />
   module are compiled with module versioning enabled. If either one of them uses the<br />
   original symbol names, the loader simply tries to match the kernel version declared<br />
   by the module and the one exported by the kernel and refuses to load if they<br />
   differ.</p>
<p>======================================<br />
   Paging and Swapping Linux:<br />
======================================</p>
<p>Swapping<br />
   ========<br />
   Some systems are pure swapping systems, some systems are pure paging systems and<br />
   others are mixed mode systems.</p>
<p>Originally Unix system V was a pure swapping system.</p>
<p>To swap a process means to move that entire process out of main memory and to the<br />
   swap area on hard disk, whereby all pages of that process are moved at the same<br />
   time.</p>
<p>This carried the disadvantage of a performance penalty. When a swapped out process<br />
   becomes active and moves from the sleep queue to the run queue, the kernel has to<br />
   load an entire process (perhaps many pages of memory) back into RAM from the swap<br />
   space. With large processes this is understandably slow. Enter paging.</p>
<p>Paging<br />
   ======<br />
   Paging was introduced as a solution to the inefficiency of swapping entire processes<br />
   in and out of memory at once.</p>
<p>With paging, when the kernel requires more main memory for an active process, only<br />
   the least recently used pages of processes are moved to the swap space.</p>
<p>Therefore when a process that has paged out memory becomes active, it is likely that<br />
   it will not need access to the pages of memory that have been paged out to the swap<br />
   space, and if it does then at least only a few pages need to be transferred between<br />
   disk and RAM.</p>
<p>Paging was first implemented in system V[?] in 19??<br />
   The working sets</p>
<p>For efficient paging, the kernel needs to keep regular statistics on the memory<br />
   activity of processes it keeps track of which pages a process has most recently<br />
   used. These pages are known as the working set.</p>
<p>When the kernel needs memory, it will prefer to keep pages in the working sets of<br />
   processes in RAM as long as possible and to rather page out the other less recently<br />
   used pages as they have statistically been proven to be less frequently accessed,<br />
   and therefore unlikely to be accesses again in the near future.<br />
   Implementation of swapping and paging in different systems</p>
<p>Current Unix systems use the following methods of memory management:</p>
<p>* SVR3 and newer based systems are mixed swapping and paging systems, as is FreeBSD.<br />
   Paging is normally used but if memory usage runs extremely heavy, too quickly for<br />
   the kernels&#8217; pager to page out enough pages of memory, then the system will revert<br />
   to swapping. This technique is also known as desperation swapping.</p>
<p>* Linux is a pure paging system it never swaps, neither under normal usage nor does<br />
   it employ desperation swapping under heavy usage.</p>
<p>* When the FreeBSD VM system is critically low on RAM or swap, it will lock the<br />
   largest process, and then flush all dirty vnode-backed pages &#8211; and will move active<br />
   pages into the inactive queue, allowing them to be reclaimed. If, after all of<br />
   that, there is still not enough memory available for the locked process, only then<br />
   will the process be killed.</p>
<p>* Under emergency memory situations when Linux runs out of memory (both physical and<br />
   swap combined) the kernel starts killing processes. It uses an algorithm to work<br />
   out which process to kill first &#8211; it tries to kill offending memory hogs that have<br />
   been running for a short amount of time first before less used processes that have<br />
   been running for a long time, which are most likely important system services. This<br />
   functionality is known as the out of memory (OOM) killer.[5]</p>
<p>Virtual memory<br />
   ==============<br />
   Virtual memory can mean two different things, in different contexts. Firstly it can<br />
   refer to only swap memory; secondly it could refer to the combination of both RAM<br />
   and swap memory.</p>
<p>======================================<br />
   DEBUGGING ////////////////////////<br />
======================================</p>
<p>======================================<br />
   Debugging Solaris:<br />
======================================</p>
<p>cat -v -t -e [file]<br />
   /* Show non-printing characters */<br />
=======================================</p>
<p>dumpadm -d swap<br />
   /* Configure swap device as dump device */<br />
=======================================</p>
<p>ld -l
<libname without 'lib'>
   /* Check if you have a particular library */<br />
=======================================</p>
<p>truss -f -p
<pid of a shell>
   /* Using multiple windows, this can be used to trace setuid/setgid programs */<br />
=======================================</p>
<p>truss executable<br />
   /* Trace doing of given command ( useful debugging ) */<br />
=======================================</p>
<p>======================================<br />
   Web Services :<br />
======================================</p>
<p> Definitions:  </p>
<p>XML: Short for Extensible Markup Language, a specification developed by the W3C. XML<br />
  is a pared-down version of SGML, designed especially for Web documents. It allows<br />
  designers to create their own customized tags, enabling the definition,<br />
  transmission, validation, and interpretation of data between applications and<br />
  between organizations.  </p>
<p>SOAP: Short for Simple Object Access Protocol, a lightweight XML-based messaging<br />
  protocol used to encode the information in Web service request and response<br />
  messages before sending them over a network. SOAP messages are independent of any<br />
  operating system or protocol and may be transported using a variety of Internet<br />
  protocols, including SMTP, MIME, and HTTP.  </p>
<p>WSDL: Short for Web Services Description Language, an XML-formatted language used to<br />
  describe a Web service&#8217;s capabilities as collections of communication endpoints<br />
  capable of exchanging messages. WSDL is an integral part of UDDI, an XML-based<br />
  worldwide business registry. WSDL is the language that UDDI uses. WSDL was<br />
  developed jointly by Microsoft and IBM.  </p>
<p>UDDI: Short for Universal Description, Discovery and Integration. A Web-based<br />
  distributed directory that enables businesses to list themselves on the Internet<br />
  and discover each other, similar to a traditional phone book&#8217;s yellow and white<br />
  pages.  </p>
<p>The term Web services describes a standardized way of integrating Web-based<br />
  applications using the XML, SOAP, WSDL and UDDI open standards over an Internet<br />
  protocol backbone. XML is used to tag the data, SOAP is used to transfer the data,<br />
  WSDL is used for describing the services available and UDDI is used for listing<br />
  what services are available. Used primarily as a means for businesses to<br />
  communicate with each other and with clients, Web services allow organizations to<br />
  communicate data without intimate knowledge of each other&#8217;s IT systems behind the<br />
  firewall.  </p>
<p>Unlike traditional client/server models, such as a Web server/Web page system, Web<br />
  services do not provide the user with a GUI. Web services instead share business<br />
  logic, data and processes through a programmatic interface across a network. The<br />
  applications interface, not the users. Developers can then add the Web service to a<br />
  GUI (such as a Web page or an executable program) to offer specific functionality<br />
  to users.  </p>
<p>Web services allow different applications from different sources to communicate with<br />
  each other without time-consuming custom coding, and because all communication is<br />
  in XML, Web services are not tied to any one operating system or programming<br />
  language. For example, Java can talk with Perl, Windows applications can talk with<br />
  UNIX applications.  </p>
<p>Web services do not require the use of browsers or HTML.  </p>
<p>Web services are sometimes called application services.  </p>
<p>Web Services  </p>
<p>Web Services </p>
<p>   ======================================<br />
   Systems Monitoring:<br />
   ====================================== </p>
<p>   A typical systems management tool is a collection of software programs that work in<br />
   unison like Nagios which uses SNMP to query your switches and routers and it uses<br />
   NSClinet++ to monitor your Windows hosts. It reports back to you what&#8217;s up and<br />
   what&#8217;s down on the network and what the status is of each device. Here are some<br />
   screen shots of my setup. </p>
<p>   Nagios Alerts </p>
<p>   Nagios Summary</p>
<p>   Nagios Host Groups </p>
<p>   Nagios Services</p>
<p>   Nagios Hosts </p>
<p>   Nagios Scheduling</p>
<p>   Nagios Map </p>
<p>   Nagios Map</p>
<p>   Nagios Scheduling </p>
<p>   Nagios Hosts</p>
<p>   Nagios Services </p>
<p>   Nagios Host Groups</p>
<p>   Nagios Summary </p>
<p>   Nagios Alerts</p>
<p>As you can see I need to fix monitoring of port 1 on the router. Hahaha.Smile<br />
Other tools out there would be Foglight, Netcool, HP Openview, and<br />
Big Brother just to name a few.</p>
<p>======================================<br />
JMS Messaging :<br />
======================================<br />
What Is the Java Message Service?  </p>
<p>An enterprise messaging system, also referred to as message-oriented middleware<br />
  (MOM), enables applications to communicate with one another through the exchange of<br />
  messages. A message is a request, report, and/or event that contains information<br />
  needed to coordinate communication between different applications. A message<br />
  provides a level of abstraction, allowing you to separate the details about the<br />
  destination system from the application code.  </p>
<p>The Java Message Service (JMS) is a standard API for accessing enterprise messaging<br />
  systems. Specifically, JMS:  </p>
<p>    * Enables Java applications sharing a messaging system to exchange messages<br />
    * Simplifies application development by providing a standard interface for<br />
      creating, sending, and receiving messages  </p>
<p>The following figure illustrates WebLogic JMS messaging.  </p>
<p>Figure 1-1 WebLogic JMS Messaging  </p>
<p>WebLogic JMS Messaging   </p>
<p>WebLogic JMS Messaging</p>
<p>======================================<br />
Java Server Pages (JSP) :<br />
======================================<br />
JavaServer Pages (JSP) is a Java technology that allows software developers to create<br />
  dynamically-generated web sites, with HTML, XML, or other document types, in<br />
  response to a Web client request. The technology allows Java code and certain<br />
  pre-defined actions to be embedded into static content.  </p>
<p>The JSP syntax adds additional XML-like tags, called JSP actions, to be used to<br />
  invoke built-in functionality. Additionally, the technology allows for the creation<br />
  of JSP tag libraries that act as extensions to the standard HTML or XML tags. Tag<br />
  libraries provide a platform independent way of extending the capabilities of a Web<br />
  server.  </p>
<p>JSPs are compiled into Java Servlets by a JSP compiler. A JSP compiler may generate a<br />
  servlet in Java code that is then compiled by the Java compiler, or it may generate<br />
  byte code for the servlet directly. JSPs can also be interpreted on-the-fly,<br />
  reducing the time taken to reload changes.  </p>
<p> ======================================<br />
  Database Triggers :<br />
 ====================================== </p>
<p>A database trigger is procedural code that is automatically executed in response to<br />
certain events on a particular table in a database. Triggers can restrict access to<br />
specific data, perform logging, or audit data modifications.</p>
<p>There are two classes of triggers, they are either &#8220;row triggers&#8221; or &#8220;statement<br />
triggers&#8221;. Row triggers define an action for every row of a table, while statement<br />
triggers occur only once per INSERT, UPDATE, or DELETE statement. Triggers cannot<br />
be used to audit data retrieval via SELECT statements.</p>
<p>Each class can be of several types. There are &#8220;BEFORE triggers&#8221; and &#8220;AFTER triggers&#8221;<br />
which identifies the time of execution of the trigger. There is also an &#8220;INSTEAD OF<br />
trigger&#8221; which is a trigger that will execute instead of the triggering statement.</p>
<p>There are typically three triggering events that cause triggers to &#8216;fire&#8217;:</p>
<p>* INSERT event (as a new record is being inserted into the database).<br />
* UPDATE event (as a record is being changed).<br />
* DELETE event (as a record is being deleted).</p>
<p>The trigger is used to automate DML condition process.</p>
<p>The major features of database triggers, and their effects, are:</p>
<p>* do not accept parameters or arguments (but may store affected-data in temporary<br />
tables)<br />
* cannot perform commit or rollback operations because they are part of the<br />
triggering SQL statement (only through autonomous transactions)<br />
* can cause mutating table errors, if they are poorly written.</p>
<p>In addition to triggers that fire when data is modified, Oracle 9i supports triggers<br />
that fire when schema objects (that is, tables) are modified and when user logon or<br />
logoff events occur. These trigger types are referred to as &#8220;Schema-level<br />
triggers&#8221;.</p>
<p>Schema-level triggers</p>
<p>* After Creation<br />
* Before Alter<br />
* After Alter<br />
* Before Drop<br />
* After Drop<br />
* Before Logoff<br />
* After Logon</p>
<p>The two main types of triggers are:</p>
<p>1) Row Level Trigger 2) Statement Level Trigger</p>
<p>Based on the 2 types of classifications, we could have 12 types of triggers.</p>
<p>* Before Insert row level<br />
* After Insert row level<br />
* Before Delete row level<br />
* After Delete row level<br />
* Before Update row level<br />
* After Update row level<br />
* Before Insert Statement Level<br />
* After Insert Statement Level<br />
* Before Delete Statement Level<br />
* After Delete Statement Level<br />
* Before Update Statement Level<br />
* After Update Statement Level</p>
<p>MySQL 5.0.2 introduced support for triggers. Some of the triggers MYSQL supports are</p>
<p>* INSERT Trigger<br />
* UPDATE Trigger<br />
* DELETE Trigger</p>
<p>The SQL:2003 standard mandates that triggers give programmers access to record<br />
variables by means of a syntax such as REFERENCING NEW AS n. For example, if a<br />
trigger is monitoring for changes to a salary column one could write a trigger like<br />
the following:</p>
<p>CREATE TRIGGER salary_trigger<br />
BEFORE UPDATE ON employee_table<br />
REFERENCING NEW ROW AS n, OLD ROW AS o<br />
FOR EACH ROW<br />
IF n.salary <> o.salary THEN</p>
<p>END IF;</p>
<p>======================================<br />
Compile Linux Kernel :<br />
======================================</p>
<p>1. How to Compile 2.6 kernel for RedHat 9/8<br />
Mike Chirico<br />
Last Updated: Wed Mar 24 09:12:06 EST 2004</p>
<p>The latest version of this document can be found at:</p>
<p>http://prdownloads.sourceforge.net/souptonuts/README_26.txt?download</p>
<p>For configs ref:</p>
<p>http://sourceforge.net/project/showfiles.php?group_id=79320&#038;package_id=109944</p>
<p>STEP 1:</p>
<p>Download the latest version of the kernel and any patches.<br />
This documentation is done with linux-2.6.3, but look for<br />
later versions.</p>
<p>http://www.kernel.org/pub/linux/kernel/v2.6/</p>
<p>Also take a look at<br />
http://www.codemonkey.org.uk/post-halloween-2.5.txt This has<br />
some useful hints on some of the changes needed.</p>
<p>STEP 2:</p>
<p>Download the latest version of module-init-tools<br />
&#8220;module-init-tools-3.0.tar.gz&#8221; and<br />
&#8220;modutils-2.4.21-23.src.rpm&#8221;</p>
<p>http://www.kernel.org/pub/linux/kernel/people/rusty/modules/module-init-tools-3</p>
<p>.0.tar.gz</p>
<p>http://www.kernel.org/pub/linux/kernel/people/rusty/modules/modutils-2.4.21-23.</p>
<p>src.rpm</p>
<p>STEP 3:</p>
<p>Install module-init-tools. This will replace depmod<br />
[/sbin/depmod] and other tools.</p>
<p>tar -zxvf module-init-tools-3.0.tar.gz<br />
cd module-init-tools-3.0<br />
./configure &#8211;prefix=/sbin<br />
make<br />
make install<br />
./generate-modprobe.conf /etc/modprobe.conf</p>
<p>STEP 4:</p>
<p>Install modutils-2.4.21-23.src.rpm. You may get warnings<br />
about user rusty and group rusty not existing. Also, yes,<br />
you&#8217;ll have to force the install. If you don&#8217;t do these steps<br />
for both Redhat 9 and Redhat 8, you&#8217;ll have problems with the<br />
make modules_install.</p>
<p>rpm -i modutils-2.4.21-23.src.rpm<br />
rpmbuild -bb /usr/src/redhat/SPECS/modutils.spec<br />
rpm -Fi /usr/src/redhat/RPMS/i386/modutils-2.4.21-23.i386.rpm</p>
<p>STEP 5:</p>
<p>Install and configure the kernel. Do NOT use the /usr/src/linux<br />
area! Reference the README. I put my files in /home/src/kernel/</p>
<p>gunzip linux-2.6.3.tar.gz tar -xvf linux-2.6.3.tar cd</p>
<p>linux-2.6.3</p>
<p>If you have patches install these now:</p>
<p>bzip2 -dc ../patch-2.6.xx.bz2 | patch -p1</p>
<p>STEP 6:</p>
<p>Copy the appropriate /usr/src/linux-2.4/configs<br />
[kernel-2.4.20-i686.config, kernel-2.4.20-i686-smp.config]<br />
to .config in whatever directory you are installing. In my<br />
case it&#8217;s /home/src/kernel/linux-2.6.3</p>
<p>cp /usr/src/linux-2.4/configs/kernel-2.4.20-i686.config \<br />
/home/src/kernel/linux-2.6.3/.config</p>
<p>If you don&#8217;t have the source configs, you can download them<br />
from here:</p>
<p>https://sourceforge.net/project/showfiles.php?group_id=79320&#038;package_id=109944</p>
<p>I&#8217;ve also included a file config2.6-chirico which was a 2.6<br />
version for some of my systems . This isn&#8217;t a bad reference if<br />
you run into trouble.</p>
<p>STEP 7:</p>
<p>Assuming you copied the appropriate kernel-2.4 config to<br />
.config, run the following which will run through necessary<br />
questions for the 2.6 kernel. Or, you might want to use the<br />
config2.6-chirico&#8230;this has already been run through make<br />
oldconfig on my system, and I&#8217;ve answered the necessary questions<br />
for a general system.</p>
<p>make oldconfig</p>
<p>STEP 8:</p>
<p>This is very important. Make sure you&#8217;re .config has the<br />
following in it CONFIG_EXT3_FS=y You&#8217;ll run into the following<br />
error if you leave this =m instead of =y:</p>
<p>pivotroot: pivot_root(/sysroot,/sysroot/initrd) failed</p>
<p>This is because Redhat 9.0 and 8.0 use the ext3 filesystem<br />
for /boot &#8230;</p>
<p>STEP 9:</p>
<p>Edit the Makefile and add changes to the Extraversion is needed.<br />
Patches will update these values as well.</p>
<p>VERSION = 2<br />
PATCHLEVEL = 6<br />
SUBLEVEL = 3<br />
EXTRAVERSION = -skim-ch6</p>
<p>STEP 10:</p>
<p>make bzImage</p>
<p>STEP 11:</p>
<p>make modules</p>
<p>STEP 12:</p>
<p>make modules_install</p>
<p>STEP 13:</p>
<p>make install</p>
<p>If you come across errors here, what version of &#8220;depmod&#8221; is<br />
being picked up in your path?</p>
<p>Also, if you get a module not found, say the following:<br />
No module aic7xxx found for kernel 2.6.x<br />
Then, in /lib/modules/2.6.x/kernel/drivers/scsi/aic7xxx/<br />
cp aic7xxx.ko aic7xxx.o</p>
<p>insmod should look for aic7xxx.ko ;but , it looks for aic7xxx.o</p>
<p>If you still have trouble, make the following change in the<br />
.config</p>
<p>CONFIG_BLK_DEV_SD=y</p>
<p>and go back to STEP 10.</p>
<p>You also may want to ref<br />
kernel-2.6.3-i686-smp-chirico-aic7xxx.config<br />
in</p>
<p>http://prdownloads.sourceforge.net/souptonuts/configs-0.3.tar.gz?download</p>
<p>STEP 14:</p>
<p>mkdir /sys</p>
<p>STEP 15:</p>
<p>/etc/rc.sysinit needs to be modified. Look for the following<br />
line:</p>
<p>action $&#8221;Mounting proc filesystem: &#8221;<br />
mount -n -t proc /proc /proc</p>
<p>and after this line enter the following:</p>
<p>action $&#8221;Mounting sysfs filesystem: &#8221;<br />
mount -t sysfs none /sys</p>
<p>Here&#8217;s my /etc/rc.sysinit for reference:</p>
<p>http://prdownloads.sourceforge.net/souptonuts/rc.sysinit.txt?download</p>
<p>Be very careful at this step. Backup the /etc/rc.sysinit file.</p>
<p>Thomer [http://thomer.com/linux/migrate-to-2.6.html ] also added<br />
changes to /etc/fstab. I only had to do STEP 16 below.</p>
<p>STEP 16:</p>
<p>Add the following to /etc/fstab for usb support.</p>
<p>/proc/bus/usb /proc/bus/usb usbdevfs defaults 0 0</p>
<p>STEP 17 (CHECKING EVERYTHING):</p>
<p>Check the following:</p>
<p>a. The new image file should be installed on boot and there<br />
should be sym link to it. My latest kernel is 2.6.3-skim-ch6,<br />
and I got the &#8220;-skim-ch6&#8243; from the values I put in the Makefile,<br />
so I see the following:</p>
<p>/boot<br />
vmlinuz -> vmlinuz-2.6.3-skim-ch6<br />
System.map -> System.map-2.6.3-skim-ch6</p>
<p>/boot/grub/grub.conf Should have been automatically<br />
updated from make.</p>
<p>In /boot/grub/grub.conf change &#8220;default=0&#8243; to boot<br />
with the new kernel. Here&#8217;s an example of my<br />
grub.conf:</p>
<p># grub.conf generated by anaconda<br />
#<br />
# Note that you do not have to rerun grub after making<br />
# NOTICE: You have a /boot partition. This means that<br />
# all kernel and initrd paths are relative to<br />
# root (hd0,2)<br />
# kernel /vmlinuz-version ro root=/dev/hda6<br />
# initrd /initrd-version.img<br />
#boot=/dev/hda<br />
default=0<br />
timeout=10<br />
splashimage=(hd0,2)/grub/splash.xpm.gz<br />
title Red Hat Linux (2.6.3-skim-ch6)<br />
root (hd0,2)<br />
kernel /vmlinuz-2.6.3-skim-ch6 ro root=LABEL=/<br />
initrd /initrd-2.6.3-skim-ch6.img</p>
<p>b. The directory /sys exists</p>
<p>c. You added the mount command for sys in /etc/rc.sysinit</p>
<p>d. CONFIG_EXT3_FS=y was used in the .config</p>
<p>e. Run /sbin/lsmod or cat /proc/modules to make<br />
sure a 2.4 kernel module wasn&#8217;t forgotten. Also<br />
look at &#8220;$cat /proc/iomem&#8221;</p>
<p>STEP 18 (DEVELOP YOUR OWN 2.6 MODULES):</p>
<p>You&#8217;re done with the 2.6 build. So learn how to develop<br />
2.6 kernel modules. First, checkout the following article</p>
<p>http://lwn.net/Articles/driver-porting/</p>
<p>Then, take a look at the following sample code, which shows how<br />
to create /proc entries for communicating with the kernel and writing<br />
out to any available tty device.</p>
<p>http://prdownloads.sourceforge.net/souptonuts/procreadwrite.0.0.1a.tar.gz?download</p>
<p>REFERENCES:</p>
<p>http://www.codemonkey.org.uk/post-halloween-2.5.txt</p>
<p>http://kerneltrap.org/node/view/799</p>
<p>http://thomer.com/linux/migrate-to-2.6.html</p>
<p>http://www.kernel.org/</p>
<p>http://bugzilla.kernel.org/</p>
<p>http://groups.google.com/groups?hl=en&#038;lr=&#038;ie=UTF-8&#038;oe=UTF-8&#038;group=linux.kernel</p>
<p>http://linuxdevices.com/articles/AT3855888078.html</p>
<p>http://prdownloads.sourceforge.net/souptonuts/README_26.txt?download</p>
<p>http://prdownloads.sourceforge.net/souptonuts/rc.sysinit.txt?download</p>
<p>http://prdownloads.sourceforge.net/souptonuts/configs-0.3.tar.gz?download</p>
<p>https://sourceforge.net/forum/forum.php?forum_id=353715</p>
<p>http://www.redhat.com/software/rhel/kernel26/</p>
<p>http://www.tldp.org/HOWTO/KernelAnalysis-HOWTO.html</p>
<p>http://www.tldp.org/HOWTO/KernelAnalysis-HOWTO.html</p>
<p>KERNEL DRIVER DEVELOPMENT IN 2.6:</p>
<p>Excellent (series of articles):</p>
<p>http://www.tldp.org/HOWTO/KernelAnalysis-HOWTO.html</p>
<p>Here&#8217;s my sample program:</p>
<p>http://www.tldp.org/HOWTO/KernelAnalysis-HOWTO.html</p>
<p>Good but dated for 2.4 kernel:</p>
<p>http://www.tldp.org/HOWTO/KernelAnalysis-HOWTO.html</p>
<p>http://linuxdevices.com/articles/AT4389927951.html</p>
<p>http://linuxdevices.com/articles/AT5793467888.html</p>
<p>======================================<br />
Setup Syslog-ng :<br />
======================================</p>
<p>Hello. Here is roughly what you want to do. I don&#8217;t have a box with elx on it, so I can&#8217;t verify it 100%.</p>
<p>Code:</p>
<p>cd /var/tmp<br />
wget http://www.balabit.com/downloads/libol/0.3/libol-0.3.9.tar.gz<br />
tar xvfz libol-0.3.9.tar.gz<br />
cd libol-0.3.9<br />
./configure &#038;&#038; make &#038;&#038; make install</p>
<p>wget http://www.balabit.com/downloads/syslog-ng/1.6/src/syslog-ng-1.6.7.tar.gz<br />
tar xvfz syslog-ng-1.6.7.tar.gz<br />
cd syslog-ng-1.6.7<br />
./configure &#038;&#038; make &#038;&#038; make install</p>
<p>That gets syslog-ng on your system. One of the next things you have to do is get<br />
syslog-ng.conf set up. By default, this file will be in /etc/syslog-ng/syslog-ng.conf.<br />
How you set it up depends entirely on what you want to do. Finally, you&#8217;ll need to<br />
stop the old syslog from starting (should be a script in<br />
/etc/rc.d) and get syslog-ng to start.</p>
<p>======================================<br />
Setup CVS Repository :<br />
======================================</p>
<p>Running a CVS Server<br />
Beyond Linux From Scratch &#8211; Version svn-20090409<br />
Running a CVS Server<br />
Running a CVS Server</p>
<p>This section will describe how to set up, administer and secure a CVS server.<br />
CVS Server Dependencies<br />
Required</p>
<p>CVS-1.11.23 and OpenSSH-5.1p1<br />
Setting up a CVS Server.</p>
<p>A CVS server will be set up using OpenSSH as the remote access method. Other access<br />
methods, including :pserver: and :server: will not be used for write access to the<br />
CVS repository. The :pserver: method sends clear text passwords over the network<br />
and the :server: method is not supported in all CVS ports. Instructions for<br />
anonymous, read only CVS access using :pserver: can be found at the end of this<br />
section.</p>
<p>Configuration of the CVS server consists of four steps:<br />
1. Create a Repository.</p>
<p>Create a new CVS repository with the following commands:</p>
<p>mkdir /srv/cvsroot &#038;&#038; chmod 1777 /srv/cvsroot &#038;&#038; export CVSROOT=/srv/cvsroot &#038;&#038; cvs init</p>
<p>2. Import Source Code Into the Repository.</p>
<p>Import a source module into the repository with the following commands, issued from a<br />
user account on the same machine as the CVS repository:</p>
<p>cd <sourcedir> &#038;&#038; cvs import -m &#8220;<repository test>&#8221; <cvstest> <vendortag><br />
<releasetag></p>
<p>3. Verify Local Repository Access.</p>
<p>Test access to the CVS repository from the same user account with the following<br />
command:</p>
<p>cvs co cvstest</p>
<p>4. Verify Remote Repository Access.</p>
<p>Test access to the CVS repository from a remote machine using a user account that has<br />
ssh access to the CVS server with the following commands:<br />
Note</p>
<p>Replace <servername> with the IP address or host name of the CVS repository machine.<br />
You will be prompted for the user&#8217;s shell account password before CVS checkout can<br />
continue.</p>
<p>export CVS_RSH=/usr/bin/ssh &#038;&#038; cvs -d:ext:<servername>:/srv/cvsroot co cvstest</p>
<p>Configuring CVS for Anonymous Read Only Access.</p>
<p>CVS can be set up to allow anonymous read only access using the :pserver: method by<br />
logging on as root and executing the following commands:</p>
<p>(grep anonymous /etc/passwd || useradd anonymous -s /bin/false -u 98) &#038;&#038; echo<br />
anonymous: > \<br />
/srv/cvsroot/CVSROOT/passwd &#038;&#038; echo anonymous > /srv/cvsroot/CVSROOT/readers</p>
<p>If you use inetd, the following command will add the CVS entry to /etc/inetd.conf:</p>
<p>echo &#8220;2401 stream tcp nowait root /usr/bin/cvs cvs -f \<br />
&#8211;allow-root=/srv/cvsroot pserver&#8221; >> /etc/inetd.conf</p>
<p>Issue a killall -HUP inetd to reread the changed inetd.conf file.</p>
<p>If you use xinetd, the following command will create the CVS file as<br />
/etc/xinetd.d/cvspserver:</p>
<p>cat >> /etc/xinetd.d/cvspserver << "EOF" # Begin /etc/xinetd.d/cvspserver<br />
service cvspserver<br />
{<br />
port = 2401<br />
socket_type = stream<br />
protocol = tcp<br />
wait = no<br />
user = root<br />
passenv = PATH<br />
server = /usr/bin/cvs<br />
server_args = -f --allow-root=/srv/cvsroot pserver }<br />
# End /etc/xinetd.d/cvspserver EOF</p>
<p>Issue a /etc/rc.d/init.d/xinetd reload to reread the changed xinetd.conf file.</p>
<p>Testing anonymous access to the new repository requires an account on another machine<br />
that can reach the CVS server via network. No account on the CVS repository is<br />
needed. To test anonymous access to the CVS repository, log in to another machine<br />
as an unprivileged user and execute the following command:</p>
<p>cvs -d:pserver:anonymous@<servername>:/srv/cvsroot co cvstest</p>
<p>Note</p>
<p>Replace <servername> with the IP address or hostname of the CVS server.<br />
Command Explanations</p>
<p>mkdir /srv/cvsroot: Create the CVS repository directory.</p>
<p>chmod 1777 /srv/cvsroot: Set sticky bit permissions for CVSROOT.</p>
<p>export CVSROOT=/srv/cvsroot: Specify new CVSROOT for all cvs commands.</p>
<p>cvs init: Initialize the new CVS repository.</p>
<p>cvs import -m &#8220;repository test&#8221; cvstest vendortag releasetag: All source code modules<br />
must be imported into the CVS repository before use, with the cvs import command.<br />
The -m flags specifies an initial descriptive entry for the new module. The cvstest<br />
parameter is the name used for the module in all subsequent cvs commands. The<br />
vendortag and releasetag parameters are used to further identify each CVS module<br />
and are mandatory whether used or not.</p>
<p>(grep anonymous /etc/passwd || useradd anonymous -s /bin/false -u 98): Check for an<br />
existing anonymous user and create one if not found.</p>
<p>echo anonymous: > /srv/cvsroot/CVSROOT/passwd: Add the anonymous user to the CVS<br />
passwd file, which is unused for anything else in this configuration.</p>
<p>echo anonymous > /srv/cvsroot/CVSROOT/readers: Add the anonymous user to the CVS<br />
readers file, a list of users who have read only access to the repository.<br />
Contents<br />
Installed Programs: None<br />
Installed Libraries: None<br />
Installed Directories: /srv/cvsroot</p>
<p>Last updated on 2007-04-04 14:42:53 -0500</p>
<p>======================================<br />
Setup RSYNC :<br />
======================================</p>
<p>Beyond Linux From Scratch &#8211; Version svn-20090409<br />
rsync-3.0.2<br />
Introduction to rsync</p>
<p>The rsync package contains the rsync utility. This is useful for synchronizing large<br />
file archives over a network.</p>
<p>Package Information</p>
<p>* Download (HTTP):</p>
<p>http://anduin.linuxfromscratch.org/sources/BLFS/svn/r/rsync-3.0.2.tar.gz</p>
<p>* Download MD5 sum: fd4c5d77d8cb7bb86ab209076fa214d9<br />
* Download size: 765 KB<br />
* Estimated disk space required: 35 MB (includes installing all documentation)<br />
* Estimated build time: 0.2 SBU</p>
<p>rsync Dependencies<br />
Optional</p>
<p>popt-1.14, libattr, and libacl</p>
<p>User Notes: http://wiki.linuxfromscratch.org/blfs/wiki/rsync<br />
Installation of rsync</p>
<p>For security reasons, running the rsync server as an unprivileged user and group is<br />
encouraged. If you intend to run rsync as a daemon, create the rsyncd user and<br />
group with the following commands issued by the root user:</p>
<p>groupadd -g 48 rsyncd &#038;&#038; useradd -c &#8220;rsyncd Daemon&#8221; -d /home/rsync -g rsyncd \ -s<br />
/bin/false -u 48 rsyncd</p>
<p>Install rsync by running the following commands:</p>
<p>./configure &#8211;prefix=/usr &#038;&#038; make</p>
<p>If you have Doxygen-1.5.8 installed and wish to build HTML API documentation, issue<br />
doxygen.</p>
<p>If you have DocBook-utils-0.6.14 installed and wish to build the user documentation,<br />
issue any or all of the following commands:</p>
<p>pushd doc &#038;&#038; docbook2pdf<br />
rsync.sgml &#038;&#038; docbook2ps<br />
rsync.sgml &#038;&#038; docbook2dvi<br />
rsync.sgml &#038;&#038; docbook2txt<br />
rsync.sgml &#038;&#038; docbook2html &#8211;nochunks rsync.sgml &#038;&#038; popd</p>
<p>To test the results, issue: make check.</p>
<p>Now, as the root user:</p>
<p>make install</p>
<p>If you built the documentation, install it using the following commands as the root<br />
user:</p>
<p>install -v -m755 -d \<br />
/usr/share/doc/rsync-3.0.2/api &#038;&#038; install -v -m644 dox/html/* \<br />
/usr/share/doc/rsync-3.0.2/api &#038;&#038; install -v \<br />
-m644 doc/rsync.* /usr/share/doc/rsync-3.0.2</p>
<p>Configuring rsync<br />
Config Files</p>
<p>/etc/rsyncd.conf<br />
Configuration Information</p>
<p>For client access to remote files, you may need to install the OpenSSH-5.1p1 package<br />
to connect to the remote server.</p>
<p>This is a simple download-only configuration to set up running rsync as a server. See<br />
the rsyncd.conf(5) man-page for additional options (i.e., user authentication).</p>
<p>cat > /etc/rsyncd.conf << &#8220;EOF&#8221;<br />
# This is a basic rsync configuration file<br />
# It exports a single module without user authentication.<br />
motd file = /home/rsync/welcome.msg<br />
use chroot = yes<br />
[localhost]<br />
path = /home/rsync<br />
comment = Default rsync module<br />
read only = yes<br />
list = yes<br />
uid = rsyncd<br />
gid = rsyncd EOF</p>
<p>Brian Bills<br />
Founder MJ12Net<br />
System Admin<br />
Stumble Us<br />
Rate MJ12Net</p>
<p>Copyright © 2009 by Firma</p>
]]></content:encoded>
			<wfw:commentRss>http://gyaresu.org/2009/07/16/system-administrator-cheat-sheet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OSX Terminal.app customisation</title>
		<link>http://gyaresu.org/2009/07/11/osx-terminal-app-customisation/</link>
		<comments>http://gyaresu.org/2009/07/11/osx-terminal-app-customisation/#comments</comments>
		<pubDate>Sat, 11 Jul 2009 04:16:45 +0000</pubDate>
		<dc:creator>gyaresu</dc:creator>
				<category><![CDATA[stuff]]></category>
		<category><![CDATA[conf]]></category>
		<category><![CDATA[dotfiles]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[terminal]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://gyaresu.org/?p=207</guid>
		<description><![CDATA[It started here: A black OS X Leopard Terminal theme that is actually readable and referenced here: http://ciaranwal.sh/2007/11/01/customising-colours-in-leopard-terminal Which led to this awesome vim package:http://github.com/adamhjk/adam-vim/tree/master]]></description>
			<content:encoded><![CDATA[<p>It started here: <a href="http://blog.infinitered.com/entries/show/6">A black OS X Leopard Terminal theme that is actually readable</a></p>
<p>and referenced here: <a href="http://ciaranwal.sh/2007/11/01/customising-colours-in-leopard-terminal">http://ciaranwal.sh/2007/11/01/customising-colours-in-leopard-terminal</a></p>
<p>Which led to this awesome vim package:<a href="http://github.com/adamhjk/adam-vim/tree/master">http://github.com/adamhjk/adam-vim/tree/master</a></p>
<p><img src="http://gyaresu.org/wp-content/uploads/2009/07/terminal-vim-changes.png" alt="terminal vim changes" title="terminal vim changes" width="587" height="515" class="aligncenter size-full wp-image-214" /></p>
]]></content:encoded>
			<wfw:commentRss>http://gyaresu.org/2009/07/11/osx-terminal-app-customisation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SSL VirtualHosts and why you need separate I.P.&#8217;s (catchall subdomain cheat)</title>
		<link>http://gyaresu.org/2009/07/01/ssl-virtualhosts-and-why-you-need-separate-i-p-s-catchall-subdomain-cheat/</link>
		<comments>http://gyaresu.org/2009/07/01/ssl-virtualhosts-and-why-you-need-separate-i-p-s-catchall-subdomain-cheat/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 04:01:57 +0000</pubDate>
		<dc:creator>gyaresu</dc:creator>
				<category><![CDATA[stuff]]></category>
		<category><![CDATA[apache2]]></category>
		<category><![CDATA[ssl]]></category>
		<category><![CDATA[virtualhost]]></category>

		<guid isPermaLink="false">http://gyaresu.org/?p=197</guid>
		<description><![CDATA[From http://www.geekwisdom.com I want to do virtual hosting of SSL-enabled virtual hosts on the same Apache server as my other non-SSL-enabled virtual hosts. I don&#8217;t want to assign more than one IP address to the server and all of my virtual hosts will be within the same domain (e.g., example.com). BACKGROUND When Apache processes a [...]]]></description>
			<content:encoded><![CDATA[<p><b>From</b> <a href="http://www.geekwisdom.com/dyn/node/215">http://www.geekwisdom.com</a></p>
<p>I want to do virtual hosting of SSL-enabled virtual hosts on the same Apache server as my other non-SSL-enabled virtual hosts. I don&#8217;t want to assign more than one IP address to the server and all of my virtual hosts will be within the same domain (e.g., example.com).<br />
BACKGROUND</p>
<p>When Apache processes a request for a name-based virtual host it receives the request from the browser, which includes the Host header (e.g., Host: www.example.com). Apache uses the Host header to determine which name-based virtual host to route the request to. It works this way regardless of the connection type, HTTP or HTTPS.</p>
<p>The trouble with SSL-enabled virtual hosting is that HTTPS is simply HTTP traffic tunneled inside of an SSL-enabled TCP connection. This means that everything in the request&#8211;including the all-important Host header that Apache needs to correctly route the request to the appropriate virtual host&#8211;is not known by Apache until after the SSL handshake takes place. The problem lies in the fact that Apache needs to present the browser with the certificate that corresponds with the virtual host being requested and Apache can only know which certificate to present by determining which virtual host the request is destined for and referring to the configuration directives for the virtual host. It&#8217;s a classic &#8220;Which came first, the chicken or the egg?&#8221; problem.</p>
<p>What happens when a browser makes an HTTPS request to a name-based virtual host is that Apache responds by presenting the certificate for the first SSL-enabled virtual host. Technically, Apache responds to the initial SSL request by applying the configuration for the default virtual host listening on port 443.</p>
<p>For instance, let&#8217;s imagine that we have an Apache server set up to do name-based virtual hosting of two SSL-enabled virtual hosts on port 443. The first virtual host has the ServerName www.example.com and the second virtual host has the ServerName www2.example.com. If the virtual host for www.example.com appears first in the apache configuration then it will be the default virtual host for port 443. As a result, any client that makes a request for https://www2.example.com will get presented with the certificate for www.example.com. Of course the Web browser will not like this and present an error message to the user stating that the certificate presented does not correspond with the request. If the user was to click through the error message the request would actually be routed to the correct virtual host, www2.example.com.</p>
<p>The real problem lies in this error that the user is presented with. We don&#8217;t want to be training users to ignore SSL/TLS errors.<br />
SOLUTION</p>
<p>As long as the virtual hosts you want to provide share the same root domain the way to tackle this issue is to configure both virtual hosts with the same certificate, but not just any certificate, a wildcard certificate. Usually you would get two certificates, one for each virtual host. The common name for the first certificate would be www.example.com and the second one would be www2.example.com. A wildcard certificate has a common name of the form *.example.com, which means it will match any hostname in the example.com domain, including www.example.com and www2.example.com. If you want to limit the scope of the wildcard certificate you could get a certificate with the common name www*.example.com which would limit it to hosts that begin with www in the example.com domain.<br />
EXAMPLE CONFIGURATION</p>
<p>NOTE: Both virtual hosts refer to the same certificate and key files.</p>
<p>&#8230;</p>
<p>Listen 443</p>
<p>&#8230;</p>
<p>&#8230;SSL stuff&#8230;</p>
<p><VirtualHost _default_:443></p>
<p>ServerName www.example.com:443</p>
<p>&#8230;VirtualHost stuff&#8230;</p>
<p>SSLEngine on</p>
<p>SSLCertificateFile /path/to/*.example.com.crt</p>
<p>SSLCertificateKeyFile /path/to/*.example.com.key</p>
<p>&#8230;VirtualHost stuff&#8230;</p>
<p></VirtualHost></p>
<p><VirtualHost *:443></p>
<p>ServerName www2.example.com:443</p>
<p>&#8230;VirtualHost stuff&#8230;</p>
<p>SSLEngine on</p>
<p>SSLCertificateFile /path/to/*.example.com.crt</p>
<p>SSLCertificateKeyFile /path/to/*.example.com.key</p>
<p>&#8230;VirtualHost stuff&#8230;</p>
<p></VirtualHost></p>
]]></content:encoded>
			<wfw:commentRss>http://gyaresu.org/2009/07/01/ssl-virtualhosts-and-why-you-need-separate-i-p-s-catchall-subdomain-cheat/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google apps free account link</title>
		<link>http://gyaresu.org/2009/06/22/google-apps-free-account-link/</link>
		<comments>http://gyaresu.org/2009/06/22/google-apps-free-account-link/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 03:34:49 +0000</pubDate>
		<dc:creator>gyaresu</dc:creator>
				<category><![CDATA[stuff]]></category>
		<category><![CDATA[apps]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://gyaresu.org/?p=195</guid>
		<description><![CDATA[http://www.google.com/a/cpanel/domain/new Because they all but don&#8217;t link to it any more.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.google.com/a/cpanel/domain/new">http://www.google.com/a/cpanel/domain/new</a></p>
<p>Because they all but don&#8217;t link to it any more.</p>
]]></content:encoded>
			<wfw:commentRss>http://gyaresu.org/2009/06/22/google-apps-free-account-link/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
