diff --git a/en_US.ISO8859-1/articles/committers-guide/article.sgml b/en_US.ISO8859-1/articles/committers-guide/article.sgml
index 1919d77983..b54d2984a6 100644
--- a/en_US.ISO8859-1/articles/committers-guide/article.sgml
+++ b/en_US.ISO8859-1/articles/committers-guide/article.sgml
@@ -1,2379 +1,2379 @@
%man;
%freebsd;
%authors;
%mailing-lists;
]>
Committer GuideThe FreeBSD Documentation Project$FreeBSD$199920002001The FreeBSD Documentation ProjectThis document provides information for the FreeBSD committer
community. All new committers should read this document before they
start, and existing committers are strongly encouraged to review it
from time to time.Administrative DetailsMain Repository Hostfreefall.FreeBSD.orgLogin Methods&man.ssh.1;Main CVSROOT/home/ncvsMain CVS Repository Meisters&a.jdp; and &a.peter; as well as &a.asami; for
ports/Mailing Listdevelopers@FreeBSD.org,
cvs-committers@FreeBSD.orgNoteworthy CVS TagsRELENG_3 (3.x-STABLE), RELENG_4 (4.x-STABLE), HEAD (-CURRENT)It is required that you use &man.ssh.1; or &man.telnet.1;
with Kerberos 5 to connect to the repository hosts. These are
generally more secure than plain &man.telnet.1; or
&man.rlogin.1; since credential negotiation will always be
encrypted. All traffic is encrypted by default with &man.ssh.1;.
With utilities like &man.ssh-agent.1; and &man.scp.1; also
available, &man.ssh.1; is also far more convenient. If you do
not know anything about &man.ssh.1;, please see
.CVS OperationsIt is assumed that you are already familiar with the basic operation
of CVS.The CVS Repository Meisters (Peter Wemm and John Polstra)
are the owners of the CVS repository and are
responsible for any and all direct
modification of it for the purposes of cleanup or fixing some
grievous abuse of CVS by a committer. No one else should
attempt to touch the repository directly. Should you cause some
repository accident, say a bad cvs import or tag operation, do
not attempt to fix it yourself!
Mail or call John or Peter immediately and report the problem to
one of them instead. The only ones allowed to directly fiddle
the repository bits are the repomeisters. Satoshi Asami is also a
repomeister for the ports/ portion of the
tree.CVS operations are usually done by logging into
freefall, making sure the
CVSROOT environment variable is set to
/home/ncvs, and then doing the appropriate
check-out/check-in operations. If you wish to add
something which is wholly new (like contrib-ified
sources, etc), a script called easy-import is
also provided for making the process easier. It automatically
adds the new module entry, does the appropriate thing with
cvs import, etc. – just run it without
arguments and it will prompt you for everything it needs to
know.Note that when you use CVS on freefall, you
should set your umask to 2,
as well as setting the CVSUMASK environment
variable to 2. This ensures that any new
files created by cvs add will have the correct
permissions. If you add a file or directory and discover that the
file in the repository has incorrect permissions (specifically,
all files in the repository should be group writable by group
ncvs), contact one of the repository meisters
as described below.If you are familiar with remote CVS and consider yourself
pretty studly with CVS in general, you can also do CVS
operations directly from your own machine and local working
sources. Just remember to set CVS_RSH to
ssh so that you are using a relatively
secure and reliable transport. If you have no idea what any of
the above even means, on the other hand, then please stick with
logging into freefall and applying your diffs
with &man.patch.1;.If you need to use CVS add and
delete operations in a manner that is
effectively a mv operation, then a repository
copy is in order rather than your CVS add and
delete. In a repository copy, a CVS Meister will copy the file(s)
to their new name and/or location and let you know when it is
done. The purpose of a repository copy is to preserve file
change history, or logs. We in the FreeBSD Project greatly
value the change history CVS gives to the project.CVS reference information, tutorials, and FAQs can also be found at:
http://www.cvshome.org/docs/,
and the information in Karl Fogel's
chapters from Open Source Development with CVS are also very
useful.&a.des; also supplied the following mini primer for
CVS.Check out a module with the co or
checkout command.&prompt.user; cvs checkout shazamThis checks out a copy of the shazam module. If
there is no shazam module in the modules file, it looks for a
top-level directory named shazam instead.
Useful cvs checkout optionsDo not create empty directoriesCheck out a single level, no subdirectoriesCheck out revision, branch or tag
revCheck out the sources as they were on date
date
Practical FreeBSD examples:Check out the miscfs module,
which corresponds to src/sys/miscfs:&prompt.user; cvs co miscfsYou now have a directory named miscfs
with subdirectories CVS,
deadfs, devfs, and so
on. One of these (linprocfs) is
empty.Check out the same files, but with full path:&prompt.user; cvs co src/sys/miscfsYou now have a directory named src,
with subdirectories CVS and
sys. src/sys has
subdirectories CVS and
miscfs, etc.Check out the same files, but prunes empty
directories:&prompt.user; cvs co -P miscfsYou now have a directory named
miscfs with subdirectories
CVS, deadfs,
devfs... but note that there is no
linprocfs subdirectory, because there
are no files in it.Check out the directory miscfs, but
none of the subdirectories:&prompt.root; cvs co -l miscfsYou now have a directory named miscfs
with just one subdirectory named
CVS.Check out the miscfs module as
it is in the 4.x branch:&prompt.user; cvs co -rRELENG_4 miscfsYou can modify the sources and commit along this
branch.Check out the miscfs module as
it was in 3.4-RELEASE.&prompt.user; cvs co -rRELENG_3_4_0_RELEASE miscfsYou will not be able to commit modifications, since
RELENG_3_4_0_RELEASE is a point in time, not a branch.Check out the miscfs module as it was
on Jan 15 2000.&prompt.user; cvs co -D'01/15/2000' miscfsYou will not be able to commit modifications.Check out the miscfs module as it was
one week ago.&prompt.user; cvs co -D'last week' miscfsYou will not be able to commit modifications.Note that cvs stores metadata in subdirectories named
CVS.Arguments to and
are sticky, which means cvs will remember them later, e.g.
when you do a cvs update.Check the status of checked-out files with the
status command.&prompt.user; cvs status shazamThis displays the status of the
shazam file or of every file in the
shazam directory. For every file, the
status is given as one of:Up-to-dateFile is up-to-date and unmodified.Needs PatchFile is unmodified, but there is a newer revision in
the repository.Locally ModifiedFile is up-to-date, but modified.Needs MergeFile is modified, and there is a newer revision in the
repository.File had conflicts on mergeThere were conflicts the last time this file was
updated, and they have not been resolved yet.You will also see the local revision and date,
the revision number of the newest applicable version
(newest applicable because if you have a
sticky date, tag or branch, it may not be the actual newest
revision), and any sticky tags, dates or options.Once you have checked something out, update it with the
update command.&prompt.user; cvs update shazamThis updates the shazam file or the
contents of the shazam directory to the
latest version along the branch you checked out. If you
checked out a point in time, does nothing
unless the tags have moved in the repository or some other weird
stuff is going on.Useful options, in addition to those listed above for
checkout:Check out any additional missing directories.Update to head of main branch.More magic (see below).If you checked out a module with or
, running cvs update
with a different or
argument or with will select a new branch,
revision or date. The option clears all
sticky tags, dates or revisions whereas
and set new ones.Theoretically, specifying HEAD as
argument to will give you the same result
as , but that is just theory.The option is useful if:somebody has added subdirectories to the module
you have checked out after you checked it out.you checked out with , and later
change your mind and want to check out the subdirectories
as well.you deleted some subdirectories and want to check
them all back out.Watch the output of the cvs
update with care. The letter in front of
each file name indicates what was done with it:UThe file was updated with no trouble.PThe file was updated with no trouble (you will only see
this when working against a remote repo).MThe file had been modified, and was merged with no
conflicts.CThe file had been modified, and was merged with
conflicts.Merging is what happens if you check out a copy of
some source code, modify it, then someone else commits a
change, and you run cvs update. CVS notices
that you have made local changes, and tries to merge your
changes with the changes between the version you originally
checked out and the one you updated to. If the changes are to
separate portions of the file, it will almost always work fine
(though the result might not be syntactically or semantically
correct).CVS will print an M in front of every locally modified
file even if there is no newer version in the repository, so
cvs update is handy for getting a summary
of what you have changed locally.If you get a C, then your changes
conflicted with the changes in the repository (the changes
were to the same lines, or neighboring lines, or you changed
the local file so much that cvs can not
figure out how to apply the repository's changes). You will have
to go through the file manually and resolve the conflicts;
they will be marked with rows of <,
= and > signs. For
every conflict, there will be a marker line with seven
< signs and the name of the file,
followed by a chunk of what your local file contained,
followed by a separator line with seven =
signs, followed by the corresponding chunk in the
repository version, followed by a marker line with seven
> signs and the revision number you
updated to.The option is slightly voodoo. It
updates the local file to the specified revision as if you
used , but it does not change the recorded
revision number or branch of the local file. It is not really
useful except when used twice, in which case it will merge the
changes between the two specified versions into the working
copy.For instance, say you commit a change to
shazam/shazam.c in &os.current; and later
want to MFC it. The change you want to MFC was revision
1.15:Check out the &os.stable; version of the
shazam module:&prompt.user; cvs co -rRELENG_4 shazamApply the changes between rev 1.14 and 1.15:&prompt.user; cvs update -j1.14 -j1.15 shazam/shazam.cYou will almost certainly get a conflict because
- of the $Id: article.sgml,v 1.87 2001-10-23 21:19:23 murray Exp $ (or in FreeBSD's case,
+ of the $Id: article.sgml,v 1.88 2001-10-31 23:10:30 chern Exp $ (or in FreeBSD's case,
$FreeBSD$) lines, so you will have to edit
the file to resolve the conflict (remove the marker lines and
- the second $Id: article.sgml,v 1.87 2001-10-23 21:19:23 murray Exp $ line, leaving the original
- $Id: article.sgml,v 1.87 2001-10-23 21:19:23 murray Exp $ line intact).
+ the second $Id: article.sgml,v 1.88 2001-10-31 23:10:30 chern Exp $ line, leaving the original
+ $Id: article.sgml,v 1.88 2001-10-31 23:10:30 chern Exp $ line intact).
View differences between the local version and the
repository version with the diff
command.&prompt.user; cvs diff shazamshows you every modification you have made to the
shazam file or module.
Useful cvs diff optionsUses the unified diff format.Shows missing or added files.
You always want to use , since
unified diffs are much easier to read than almost any other
diff format (in some circumstances, context diffs may be
better, but they are much bulkier). A unified diff consists of
a series of hunks. Each hunk begins with a line that starts
with two @ signs and specifies where in the
file the differences are and how many lines they span. This
is followed by a number of lines; some (preceded by a blank)
are context; some (preceded by a - sign)
- are outtakes and some (preceded by a +) are
+ are out takes and some (preceded by a +) are
additions.You can also diff against a different version
than the one you checked out by specifying a version
with or as in
checkout or update,
or even view the diffs between two arbitrary versions
(with no regard for what you have locally) by specifying
two versions with or
.View log entries with the log
command.&prompt.user; cvs log shazamIf shazam is a file, this will print a
header with information about this file, such
as where in the repository this file is stored, which revision is
the HEAD for this file, what branches this file
is in, and any tags that are valid for this file. Then, for each
revision of this file, a log message is printed. This includes
the date and time of the commit, who did the commit, how many lines
were added and/or deleted, and finally the log message that the
committer who did the change wrote.If shazam is a directory, then the log
information described above is printed for each file in the
directory in turn. Unless you give the to
log, the log for all subdirectories of
shazam is printed too, in a recursive
manner.Use the log command to view the history of
one or more files, as it is stored in the CVS repository. You can
even use it to view the log message of a specific revision, if you
add the to the
log command:&prompt.user; cvs log -r1.2 shazamThis will print only the log message for revision
1.2 of file shazam if it is
a file, or the log message for revision 1.2 of
each file under shazam if it is a
directory.See who did what with the annotate command.
This command shows you each line of the specified file or
files, along with which user most recently changed that
line.&prompt.user; cvs annotate shazamAdd new files with the add command.Create the file, cvs add it, then
cvs commit it.Similarly, you can add new directories by creating them
and then cvs adding them. Note that you
do not need to commit directories.Remove obsolete files with the remove command.Remove the file, then cvs rm it, then
cvs commit it.Commit with the commit or
checkin command.
Useful cvs commit optionsForce a commit of an unmodified file.Specify a commit message on the command line rather
than invoking an editor.
Use the option if you realize that
you left out important information from the commit message.Good commit messages are important. They tell others
why you did the changes you did, not just right here and now,
but months or years from now when someone wonders why some
seemingly illogical or inefficient piece of code snuck into
your source file. It is also an invaluable aid to deciding
which changes to MFC and which not to MFC.Do not waste space in the commit messages explaining
what you did. That is what
cvs diff is for. Instead, tell us
why you did it.Avoid committing several unrelated changes in one go. It
makes merging difficult, and also makes it harder to determine
which change is the culprit if a bug crops up.Avoid committing style or whitespace fixes and
functionality fixes in one go. It makes merging difficult,
and also makes it harder to understand just what functional
changes were made.Avoid committing changes to multiple files in one go
with a generic, vague message. Instead, commit each file (or
small groups of files) with tailored commit messages.Before committing, always:verify which branch you are committing to, using
cvs status.review your diffs, using
cvs diffAlso, ALWAYS specify which files to commit explicitly on
the command line, so you do not accidentally commit other files
than the ones you intended - cvs commit
with no arguments will commit every modification in your
current working directory and every subdirectory.Additional tips and tricks:You can place commonly used options in your
~/.cvsrc, like this:cvs -z3
diff -Nu
update -Pd
checkout -PThis example says:always use compression level 3 when talking to a
remote server. This is a life-saver when working over a
slow connection.always use the (show added or
removed files) and (unified diff
format) options to &man.diff.1;.always use the (prune empty
directories) and (check out new
directories) options when updating.always use the (prune empty
directories) option when checking out.Use Eivind Eklund's cdiff script to
view unidiffs. It is a wrapper for &man.less.1; that adds ANSI
color codes to make hunk headers, outtakes and additions stand
out; context and garbage are unmodified. It also expands tabs
properly (tabs often look wrong in diffs because of the extra
character in front of each line).http://people.FreeBSD.org/~eivind/cdiffSimply use it instead of &man.more.1; or &man.less.1;:&prompt.user; cvs diff -Nu shazam | cdiffAlternatively some editors like &man.vim.1;
(ports/editors/vim5) have color support and when used as
a pager with color syntax highlighting switched on will
highlight many types of file, including diffs, patches,
and cvs/rcs logs. &prompt.user; echo "syn on" >> ~/.vimrc
&prompt.user; cvs diff -Nu shazam | vim -
&prompt.user; cvs log shazam | vim -CVS is old, arcane, crufty and buggy, and sometimes
exhibits non-deterministic behavior which some claim as proof
that it is actually merely the Newtonian manifestation of a
sentient transdimensional entity. It is not humanly possible
to know its every quirk inside out, so do not be afraid to ask
the resident AI (cvs@FreeBSD.org) for help when
you screw up.Do not leave the cvs commit command in commit
message editing mode for too long (more than 2-3 minutes). It
locks the directory you are working with and will prevent other
developers from committing into the same directory. If you have
to type a long commit message, type it before executing
cvs commit, and insert it into the commit
message.Conventions and TraditionsAs a new committer there are a number of things you should do
first.Add yourself to the Developers section of
the Contributors List
and remove yourself from the Additional
Contributors section.This is a relatively easy task, but remains a good first test of
your CVS skills.Add an entry for yourself to
www/en/news/news.xml. Look for the other
entries that look like A new committer and follow the
format.If you have a PGP or GnuPG key, you may want to add it to
doc/en_US.ISO8859-1/books/handbook/pgpkeys.
Some people add an entry for themselves to
ports/astro/xearth/files/freebsd.committers.markers.Some people add an entry for themselves to src/usr.bin/calendar/calendars/calendar.freebsd.Introduce yourself to the other committers, otherwise no one
will have any idea who you are or what you are working on. You do
not have to write a comprehensive biography, just write a paragraph
or two about who you are and what you plan to be working on as a
committer in FreeBSD. Email this to
developers@FreeBSD.org and you will be on your
way!Log into hub.FreeBSD.org and create a
/var/forward/user
(where user is your username) file
containing the e-mail address where you want mail addressed to
yourusername@FreeBSD.org to be forwarded.
This includes all of the commit messages as well as any other mail
addressed to cvs-committers@FreeBSD.org and
developers@FreeBSD.org. Really
large mailboxes which have taken up permanent residence on
hub often get accidently truncated
without warning, so forward it or read it and you will not lose
it.All new committers also have a mentor assigned to them for
the first few months. Your mentor is more or less responsible for
explaining anything which is confusing to you and is also
responsible for your actions during this initial period. If you
make a bogus commit, it is only going to embarrass your mentor
and you should probably make it a policy to pass at least your
first few commits by your mentor before committing it to the
repository.All commits should go to &os.current; first
before being merged to &os.stable;. No major new
features or high-risk modifications should be made to the
&os.stable; branch.Developer RelationsIf you are working directly on your own code or on code
which is already well established as your responsibility, then
there is probably little need to check with other committers
before jumping in with a commit. If you see a bug in an area of
the system which is clearly orphaned (and there are a few such
areas, to our shame), the same applies. If, however, you are
about to modify something which is clearly being actively
maintained by someone else (and it is only by watching the
cvs-committers mailing list that you can
really get a feel for just what is and is not) then consider
sending the change to them instead, just as you would have
before becoming a committer. For ports, you should contact the
listed MAINTAINER in the
Makefile. For other parts of the
repository, if you are unsure who the active maintainer might
be, it may help to scan the output of cvs log
to see who has committed changes in the past. &a.fenner; has
written a nice shell script that can help determine who the
active maintainer might be. It lists each person who has
committed to a given file along with the number of commits each
person has made. It can be found on freefall
at ~fenner/bin/whodid. If your queries go
unanswered or the committer otherwise indicates a lack of
proprietary interest in the area affected, go ahead and commit
it.If you are unsure about a commit for any reason at
all, have it reviewed by -hackers
before committing. Better to have it flamed then and there
rather than when it is part of the CVS repository. If you do
happen to commit something which results in controversy
erupting, you may also wish to consider backing the change out
again until the matter is settled. Remember – with CVS we
can always change it back.GNATSThe FreeBSD Project utilizes
GNATS for tracking bugs and change
requests. Be sure that if you commit a fix or suggestion found
in a GNATS PR, you use
edit-pr pr-number
on freefall to close it. It is also considered
nice if you take time to close any PRs associated with your
commits, if appropriate. You can also make use of
&man.send-pr.1; yourself for proposing any change which you feel
should probably be made, pending a more extensive peer-review
first.You can find out more about GNATS
at:http://www.cs.utah.edu/csinfo/texinfo/gnats/gnats.htmlhttp://www.FreeBSD.org/support.htmlhttp://www.FreeBSD.org/send-pr.html&man.send-pr.1;You can run a local copy of GNATS, and then integrate the FreeBSD
GNATS tree in to it using CVSup. Then you can run GNATS commands
locally, or use other interfaces, such as tkgnats.
This lets you query the PR database without needing to be connected to
the Internet.Using a local GNATS treeIf you are not already downloading the GNATS tree, add this line
to your supfile, and re-sup. Note that since
GNATS is not under CVS control it has no tag, so if you are adding
it to your existing supfile it should appear
before any tag= entry as these remain active once set.
gnats release=current prefix=/usrThis will place the FreeBSD GNATS tree in
/usr/gnats. You can use a
refuse file to control which categories to
receive. For example, to only receive docs PRs,
put this line in
/usr/local/etc/cvsup/sup/refuseThe precise path depends on the *default
base setting in your
supfile..gnats/[a-ce-z]*The rest of these examples assume you have only supped the
docs category. Adjust them as necessary,
depending on the categories you are synching.Install the GNATS port from
ports/databases/gnats. This will place the
various GNATS directories under
$PREFIX/share/gnats.Symlink the GNATS directories you are supping under the version
of GNATS you have installed.&prompt.root; cd /usr/local/share/gnats/gnats-db
&prompt.root; ln -s /usr/gnats/docsRepeat as necessary, depending on how many GNATS categories you
are synching.Update the GNATS categories file with these
categories. The file is
$PREFIX/share/gnats/gnats-db/gnats-adm/categories.# This category is mandatory
pending:Category for faulty PRs:gnats-admin:
#
# FreeBSD categories
#
docs:Documentation Bug:nik:Run $PREFIX/libexec/gnats/gen-index to
recreate the GNATS index. The output has to be redirected to
$PREFIX/share/gnats/gnats-db/gnats-adm/index.
You can do this periodically from &man.cron.8;, or run &man.cvsup.1;
from a shell script that does this as well.&prompt.root; /usr/local/libexec/gnats/gen-index \
> /usr/local/share/gnats/gnats-db/gnats-adm/indexTest the configuration by querying the PR database. This
command shows open docs PRs.&prompt.root; query-pr -c docs -s openOther interfaces, like
ports/databases/tkgnats should also work
nicely.Pick a PR and close it.This procedure only works to allow you to view and query the PRs
locally. To edit or close them you will still have to log in to
freefall and do it from there.Who's WhoBesides Peter Wemm and John Polstra, the repository
meisters, there are other FreeBSD project members whom you will
probably get to know in your role as a committer. Briefly,
and by no means all-inclusively, these are:&a.asami;Satoshi is the Ports Wraith, meaning that he has
ultimate authority over any modifications to the ports
collection or the ports skeleton makefiles. He is also
the one responsible for administering ports freezes before
the releases.&a.nik;Nik oversees the
Doc. Project.
As well as writing documentation he put together the
infrastructure under doc/share/mk and the
stylesheets and related code under
doc/share/sgml. If you have got questions
about these you are encouraged to send them via the
doc@FreeBSD.org mailing list. Committers
interested in contributing to the documentation should familiarise
- themself with the
+ themselves with the
Documentation Project Primer.&a.ru;Ruslan is Mister &man.mdoc.7;. If you are writing a
man page and need
some advice on the structure, or the markup, ask Ruslan.&a.bde;Bruce is the Style Police-Meister.
When you do a commit that could have been done better,
Bruce will be there to tell you. Be thankful that someone
is. Bruce is also very knowledgeable on the various
standards applicable to FreeBSD.&a.gallatin;&a.mjacob;&a.dfr;&a.obrien;These are the primary developers and overseers of the
DEC Alpha AXP platform.&a.dg;David is the overseer of the
VM system. If you have a VM system change in mind,
coordinate it with David.&a.jkh;Jordan is the release engineer. He is responsible for
setting release deadlines and controlling the release
process. During code freezes, he also has final authority
on all changes to the system for whichever branch is
pending release status. If there is something you want
merged from &os.current; to
&os.stable; (whatever values those may have
at any given time), he is also the one to talk to about
it.&a.bmah;Bruce is keeper of the release notes
(src/release/texts/* or
src/release/doc/*,
as appropriate). If you commit a
change that you think is worthy of mention in the release notes,
please make sure Bruce knows about it. Better still, send him
a patch with your suggested commentary for the release
notes.&a.obrien;David is the unofficial src/contrib-Meister.
If you have something
significant you would like to do there, you should probably
coordinate it with David first. Please consult him before
importing into src/contrib if you have
never done this before in the FreeBSD CVS repository. Also
if you need to commit to something you do not maintain in
src/contrib and it is unclear who the
maintainer / point of contact is. (It is also not a bad idea
to consult David if you need to make a non-import commit to
something you maintain in src/contrib and
you are new to how FreeBSD does things.)&a.brian;Official maintainer of
/usr/sbin/ppp.&a.wollman;If you need advice on obscure network internals or
are not sure of some potential change to the networking
subsystem you have in mind, Garrett is someone to talk
to. Garrett is also very knowledgeable on the various
standards applicable to FreeBSD.&a.committers;cvs-committers is the entity that CVS uses to send you all your
commit messages. You should never send email
directly to this list. You should only send replies to this list
when they are short and are directly related to a commit.&a.developers;developers is all committers. This list was created to be a
forum for the committers community issues. Examples are Core
voting, announcements, etc... developers@FreeBSD.org is
not intended as a place for code reviews or a
replacement for arch@FreeBSD.org or audit@FreeBSD.org. In fact
using it as such hurts the FreeBSD Project as it gives a sense of a
closed list where general decisions affecting all of the FreeBSD
using community are made with out being open.SSH Quick-Start GuideIf you are using FreeBSD 4.0 or later,
OpenSSH is included in the base system.
If you are using an earlier release,
update and install one of the SSH ports. In general,
you will probably want to get OpenSSH from the port in
/usr/ports/security/openssh. You
may also wish to check out the original ssh1 in
/usr/ports/security/ssh, but make
certain you pay attention to its license. Note that both
of these ports cannot be installed at the same time.If you do not wish to type your password in every
time you use &man.ssh.1;, and you use RSA keys to
authenticate, &man.ssh-agent.1; is there for your
convenience. If you want to use &man.ssh-agent.1;, make
sure that you run it before running other applications. X
users, for example, usually do this from their
.xsession or
.xinitrc file. See &man.ssh-agent.1;
for details.Generate a key pair using &man.ssh-keygen.1;. The key
pair will wind up in the
$HOME/.ssh
directory.Send your public key
($HOME/.ssh/identity.pub)
to the person setting you up as a committer so it can be put
into your authorized_keys file in your
home directory on freefall
(i.e.
$HOME/.ssh/authorized_keys).
Now you should be able to use &man.ssh-add.1; for
authentication once per session. This will prompt you for
your private key's pass phrase, and then store it in your
authentication agent (&man.ssh-agent.1;). If you no longer
wish to have your key stored in the agent, issuing
ssh-add -d will remove it.Test by doing something such as ssh
freefall.FreeBSD.org ls /usr.For more information, see
/usr/ports/security/openssh, &man.ssh.1;,
&man.ssh-add.1;, &man.ssh-agent.1;, &man.ssh-keygen.1;, and
&man.scp.1;.The FreeBSD Committers' Big List of RulesRespect other committers.Respect other contributors.Discuss any significant change
before committing.Respect existing maintainers (if listed in the
MAINTAINER field in
Makefile or in the
MAINTAINER file in the top-level
directory).Never touch the repository directly. Ask a
Repomeister.Any disputed change must be backed out pending
resolution of the dispute if requested by a maintainer.
Security related changes may
override a maintainer's wishes at the Security Officer's
discretion.Changes go to &os.current; before
&os.stable; unless specifically permitted by
the release engineer or unless they are not applicable to
&os.current;. Any non-trivial or non-urgent
change which is applicable should also be allowed to sit in
&os.current; for at least 3 days before
merging so that it can be given sufficient testing. The
release engineer has the same authority over the
&os.stable; branch as outlined for the
maintainer in rule #6.Do not fight in public with other committers; it looks
bad. If you must strongly disagree about
something, do so only in private.Respect all code freezes and read the
committers mailing list in a timely manner
so you know when a code freeze is in effect.When in doubt on any procedure, ask first!Test your changes before committing them.Do not commit to anything under the
src/contrib,
src/crypto, and
src/sys/contrib trees without
explicit approval from the respective
maintainer(s).As noted, breaking some of these rules can be grounds for
suspension or, upon repeated offense, permanent removal of
commit privileges. Three or more members of core
acting in unison,
have the power to temporarily suspend commit privileges until
-core as a whole has the chance to review the
issue. In case of an emergency (a committer
doing damage to the repository), a temporary suspension may also
be done by the repository meisters or any other member of core
who may happen to be awake at the time. Only core as a whole
has the authority to suspend commit privileges for any
significant length of time or to remove them permanently, the
latter generally only being done after consultation with
committers. This rule does not exist to set core up as a bunch
of cruel dictators who can dispose of committers as casually as
empty soda cans, but to give the project a kind of safety fuse.
If someone is seriously out of control, it is important to be
able to deal with this immediately rather than be paralyzed by
debate. In all cases, a committer whose privileges are
suspended or revoked is entitled to a hearing,
the total duration of the suspension being determined at that
time. A committer whose privileges are suspended may also
request a review of the decision after 30 days and every 30 days
thereafter (unless the total suspension period is less than 30
days). A committer whose privileges have been revoked entirely
may request a review after a period of 6 months have elapsed.
This review policy is strictly informal
and, in all cases, core reserves the right to either act on or
disregard requests for review if they feel their original
decision to be the right one.In all other aspects of project operation, core is a subset
of committers and is bound by the same
rules. Just because someone is in core does not mean
that they have special dispensation to step outside of any of
the lines painted here; core's special powers
only kick in when it acts as a group, not on an individual
basis. As individuals, we are all committers first and core
second.DetailsRespect other committers.This means that you need to treat other committers as
the peer-group developers that they are. Despite our
occasional attempts to prove the contrary, one does not get
into committers by being stupid and nothing rankles more
than being treated that way by one of your peers. Whether
we always feel respect for one another or not (and
everyone has off days), we still have to
treat other committers with respect
at all times or the whole team structure rapidly breaks
down.Being able to work together long term is this project's
greatest asset, one far more important than any set of
changes to the code, and turning arguments about code into
issues that affect our long-term ability to work
harmoniously together is just not worth the trade-off by
any conceivable stretch of the imagination.To comply with this rule, do not send email when you are
angry or otherwise behave in a manner which is likely to
strike others as needlessly confrontational. First calm
down, then think about how to communicate in the most
effective fashion for convincing the other person(s) that
your side of the argument is correct, do not just blow off
some steam so you can feel better in the short term at the
cost of a long-term flame war. Not only is this very bad
energy economics, but repeated displays of
public aggression which impair our ability to work well
together will be dealt with severely by the project
leadership and may result in suspension or termination of
your commit privileges. That is never an option which the
project's leadership enjoys in the slightest, but unity
comes first. No amount of code or good advice is worth
trading that away.Respect other contributors.You were not always a committer. At one time you were
a contributor. Remember that at all times. Remember what
it was like trying to get help and attention. Do not forget
that your work as a contributor time was very important to
you. Remember what it was like. Do not discourage, belittle,
or demean contributors. Treat them with respect. They are
our committers in waiting. They are every bit as important
to the project as committers. Their contributions are as
valid and as important as your own. After all, you made
many contributions before you became a committer. Always
remember that. Consider the points raised under
and apply them also to contributors.Discuss any significant change
before committing.The CVS repository is not where changes should be
initially submitted for correctness or argued over, that
should happen first in the mailing lists and then
committed only once something resembling consensus has
been reached. This does not mean that you have to ask
permission before correcting every obvious syntax error or
man page misspelling, simply that you should try to
develop a feel for when a proposed change is not quite such
a no-brainer and requires some feedback first. People
really do not mind sweeping changes if the result is
something clearly better than what they had before, they
just do not like being surprised by
those changes. The very best way of making sure that
you are on the right track is to have your code reviewed by
one or more other committers.When in doubt, ask for review!Respect existing maintainers if listed.Many parts of FreeBSD are not owned in
the sense that any specific individual will jump up and
yell if you commit a change to their area,
but it still pays to check first. One convention we use
is to put a maintainer line in the
Makefile for any package or subtree
which is being actively maintained by one or more people;
see http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/developers-handbook/policies.html
for documentation on this. Where sections of code have
several maintainers, commits to affected areas by one
maintainer need to be reviewed by at least one other
maintainer. In cases where the
maintainer-ship of something is not clear,
you can also look at the CVS logs for the file(s) in
question and see if someone has been working recently or
predominantly in that area.Other areas of FreeBSD fall under the control of
someone who manages an overall category of FreeBSD
evolution, such as internationalization or networking.
See http://www.FreeBSD.org/doc/en_US.ISO8859-1/articles/contributors/staff-who.html for more information on this.Never touch the repository directly. Ask a
Repomeister.This is pretty clear - you are not allowed to make
direct modifications to the CVS repository, period. In
case of difficulty, ask one of the repository meisters by
sending mail to cvs@FreeBSD.org and simply
wait for them to fix the problem and get back to you. Do
not attempt to fix the problem yourself!If you are thinking about putting down a tag or doing a
new import of code on a vendor branch, you might also find
it useful to ask for advice first. A lot of people get
this wrong the first few times and the consequences are
expensive in terms of files touched and angry CVSup/CTM
folks who are suddenly getting a lot of changes sent over
unnecessarily.Any disputed change must be backed out pending
resolution of the dispute if requested by a maintainer.
Security related changes may
override a maintainer's wishes at the Security Officer's
discretion.This may be hard to swallow in times of conflict (when
each side is convinced that they are in the right, of
course) but CVS makes it unnecessary to have an ongoing
dispute raging when it is far easier to simply reverse the
disputed change, get everyone calmed down again and then
try and figure out how best to proceed. If the change
turns out to be the best thing after all, it can be easily
brought back. If it turns out not to be, then the users
did not have to live with the bogus change in the tree
while everyone was busily debating its merits. People
very very rarely call for back-outs in the repository
since discussion generally exposes bad or controversial
changes before the commit even happens, but on such rare
occasions the back-out should be done without argument so
that we can get immediately on to the topic of figuring
out whether it was bogus or not.Changes go to &os.current; before
&os.stable; unless specifically permitted
by the release engineer or unless they are not applicable
to &os.current;. Any non-trivial or
non-urgent change which is applicable should also be
allowed to sit in &os.current; for at least
3 days before merging so that it can be given sufficient
testing. The release engineer has the same authority over
the &os.stable; branch as outlined in rule
#6.This is another do not argue about it
issue since it is the release engineer who is ultimately
responsible (and gets beaten up) if a change turns out to
be bad. Please respect this and give the release engineer
your full cooperation when it comes to the
&os.stable; branch. The management of
&os.stable; may frequently seem to be
overly conservative to the casual observer, but also bear
in mind the fact that conservatism is supposed to be the
hallmark of &os.stable; and different rules
apply there than in &os.current;. There is
also really no point in having &os.current;
be a testing ground if changes are merged over to
&os.stable; immediately. Changes need a
chance to be tested by the &os.current;
developers, so allow some time to elapse before merging
unless the &os.stable; fix is critical,
time sensitive or so obvious as to make further testing
- unnecessary (spelling fixes to manpages, obvious bug/typo
+ unnecessary (spelling fixes to man pages, obvious bug/typo
fixes, etc.) In other words, apply common sense.Do not fight in public with other committers; it looks
bad. If you must strongly disagree about
something, do so only in private.This project has a public image to uphold and that
image is very important to all of us, especially if we are
to continue to attract new members. There will be
occasions when, despite everyone's very best attempts at
self-control, tempers are lost and angry words are
exchanged, and the best we can do is try and minimize the
effects of this until everyone has cooled back down. That
means that you should not air your angry words in public
and you should not forward private correspondence to
public mailing lists or aliases. What people say
one-to-one is often much less sugar-coated than what they
would say in public, and such communications therefore
have no place there - they only serve to inflame an
already bad situation. If the person sending you a
flame-o-gram at least had the grace to send it privately,
then have the grace to keep it private yourself. If you
feel you are being unfairly treated by another developer,
and it is causing you anguish, bring the matter up with
core rather than taking it public. We will do our best to
play peace makers and get things back to sanity. In cases
where the dispute involves a change to the codebase and
the participants do not appear to be reaching an amicable
agreement, core may appoint a mutually-agreeable 3rd party
to resolve the dispute. All parties involved must then
agree to be bound by the decision reached by this 3rd
party.Respect all code freezes and read the
committers mailing list on a timely
basis so you know when they are.Committing changes during a code freeze is a really
big mistake and committers are expected to keep up-to-date
on what is going on before jumping in after a long absence
and committing 10 megabytes worth of accumulated stuff.
People who abuse this on a regular basis will have their
commit privileges suspended until they get back from the
FreeBSD Happy Reeducation Camp we run in Greenland.When in doubt on any procedure, ask first!Many mistakes are made because someone is in a hurry
and just assumes they know the right way of doing
something. If you have not done it before, chances are
good that you do not actually know the way we do things
and really need to ask first or you are going to
completely embarrass yourself in public. There is no shame
in asking how in the heck do I do this? We
already know you are an intelligent person; otherwise, you
would not be a committer.Test your changes before committing them.This may sound obvious, but if it really were so
obvious then we probably would not see so many cases of
people clearly not doing this. If your changes are to the
kernel, make sure you can still compile both GENERIC and
LINT. If your changes are anywhere else, make sure you
can still make world. If your changes are to a branch,
make sure your testing occurs with a machine which is
running that code. If you have a change which also may
break another architecture, be sure and test on all
supported architectures. Currently, this is only the x86
and the Alpha so it is pretty easy to do. If you need to
test on the AXP, your account on beast.FreeBSD.org will let you
compile and test Alpha binaries/kernels/etc. As other
architectures are added to the FreeBSD supported platforms
list, the appropriate shared testing resources will be
made available.Do not commit to anything under the
src/contrib,
src/crypto, and
src/sys/contrib trees without
explicit approval from the respective
maintainer(s).The trees mentioned above are for contributed software
usually imported onto a vendor branch. Committing something
there, even if it does not take the file off the vendor branch,
may cause unnecessary headaches for those responsible for
maintaining that particular piece of software. Thus, unless
you have explicit approval from the
maintainer (or you are the maintainer), do
not commit there!Please note that this does not mean you should not try to
improve the software in question; you are still more than
welcome to do so. Ideally, you should submit your patches to
the vendor. If your changes are FreeBSD-specific, talk to the
maintainer; they may be willing to apply them locally. But
whatever you do, do not commit there by
yourself!Contact the &a.core; if you wish to take up maintainership
of an unmaintained part of the tree.Other SuggestionsWhen committing documentation changes, use a spell checker
before committing. :) For all SGML docs, you should also
verify that your formatting directives are correct by running
make lint.For all on-line manual pages, run manck
(from ports) over the man page to verify all of the cross
references and file references are correct and that the man
page has all of the appropriate MLINKs
installed.Do not mix style fixes with new functionality. A style
fix is any change which does not modify the functionality of
the code. Mixing the changes obfuscates the functionality
change when using cvs diff, which can hide
any new bugs. Do not include whitespace changes with content
changes in commits to doc/ or
www/. The extra clutter in the diffs
makes the translators' job much more difficult. Instead, make
any style or whitespace changes in separate commits that are
clearly labeled as such in the commit message.Deprecating FeaturesWhen it is necessary to remove functionality from software
in the base system the following guidelines should be followed
whenever possible:Mention is made in the manual page and possibly the
release notes that the option, utility, or interface is
deprecated. Use of the deprecated feature generates a
warning.The option, utility, or interface is preserved until
the next major (point zero) release.The option, utility, or interface is removed and no
longer documented. It is now obsolete. It is also
generally a good idea to note its removal in the release
notes.Ports Specific FAQAdding a New PortHow do I add a new port?First, please read the section about repository
copy.The easiest way to add a new port is to use the
addport script on
freefall. It will add a port from the
directory you specify, determining the category automatically
from the port Makefile.
It will also add an entry to the
CVSROOT/modules file and the port's
category Makefile. It was
written by &a.mharo; and &a.will;, but Will is the current
maintainer so please send questions/patches about
addport to him.Any other things I need to know when I add a new
port?Check the port, preferably to make sure it compiles
and packages correctly. This is the recommended
sequence:&prompt.root; make install
&prompt.root; make package
&prompt.root; make deinstall
&prompt.root; pkg_add package you built above
&prompt.root; make deinstall
&prompt.root; make reinstall
&prompt.root; make packageThe
Porters
Handbook contains more detailed
instructions.Use &man.portlint.1; to check the syntax of the port.
You do not necessarily have to eliminate all warnings but
make sure you have fixed the simple ones.If the port came from a submitter who has not
contributed to the project before, add that person's
name to the Additional
Contributors section of the FreeBSD Contributors
List.Close the PR if the port came in as a PR. To close
a PR, just do
edit-pr PR#
on freefall and change the
state from open
to closed. You will be asked to
enter a log message and then you are done.Repository CopiesWhen do we need a repository copy?When you want to add a port that is related to
any port that is already in the tree in a separate
directory, please send mail to the ports manager asking
about it. Here related means
it is a different version or a slightly modified
version. Examples are
print/ghostscript* (different
versions) and x11-wm/windowmaker*
(English-only and internationalized version).Another example is when a port is moved from one
subdirectory to another, or when you want to change the
name of a directory because the author(s) renamed their
software even though it is a
descendant of a port already in a tree.When do we not need a
repository copy?When there is no history to preserve. If a port is
added into a wrong category and is moved immediately,
it suffices to simply cvs remove the
old one and addport the new
one.What do I need to do?Send mail to the ports manager, who will do a copy
from the old location/name to the new location/name.
You will then get a notice, at which point you are
expected to perform the following:cvs remove the old port (if
necessary)Adjust the parent (category)
MakefileUpdate CVSROOT/modulesIf other ports depend on the updated port,
change their Makefiles'
dependency linesIf the port changed categories, modify the
CATEGORIES line of the port's
Makefile accordinglyPorts FreezeWhat is a ports freeze?Before a release, it is necessary to restrict
commits to the ports tree for a short period of time
while the packages and the release itself are being
built. This is to ensure consistency among the various
parts of the release, and is called the ports
freeze.How long is a ports freeze?Usually an hour or two.What does it mean to me?During the ports freeze, you are not allowed to
commit anything to the tree without explicit approval
from the ports manager. Explicit
approval here means either of the
following:You asked the ports manager and got a reply
saying, Go ahead and commit
it.The ports manager sent a mail to you or the
mailing lists during the ports freeze pointing out
that the port is broken and has to be fixed.Note that you do not have implicit permission to fix
a port during the freeze just because it is
broken.How do I know when the ports freeze starts?The ports manager will send out warning messages to
the freebsd-ports@FreeBSD.org and
cvs-committers@FreeBSD.org mailing lists
announcing the start of the impending release, usually
two or three weeks in advance. The exact starting time
will not be determined until a few days before the
actual release. This is because the ports freeze has to
be synchronized with the release, and it is usually not
known until then when exactly the release will be
rolled.When the freeze starts, there will be another
announcement to the
cvs-committers@FreeBSD.org list, of
course.How do I know when the ports freeze ends?A few hours after the release, the ports manager
will send out a mail to the
freebsd-ports@FreeBSD.org and
cvs-committers@FreeBSD.org mailing lists
announcing the end of the ports freeze. Note that the
release being cut does not automatically end the freeze.
We have to make sure there will not be any last minute
snafus that result in an immediate re-rolling of the
release.Miscellaneous QuestionsHow do I know if my port is building correctly or
not?First, go check
http://bento.FreeBSD.org/~asami/errorlogs/.
There you will find error logs from the latest package
building runs on 3-stable, 4-stable and 5-current.However, just because the port does not show up there
does not mean it is building correctly. (One of the
dependencies may have failed, for instance.) Here are
the relevant directories on bento, so feel free to dig
around. /a/asami/portbuild/3/errors error logs from latest 3-stable run
/logs all logs from latest 3-stable run
/packages packages from latest 3-stable run
/bak/errors error logs from last complete 3-stable run
/bak/logs all logs from last complete 3-stable run
/bak/packages packages from last complete 3-stable run
/4/errors error logs from latest 4-stable run
/logs all logs from latest 4-stable run
/packages packages from latest 4-stable run
/bak/errors error logs from last complete 4-stable run
/bak/logs all logs from last complete 4-stable run
/bak/packages packages from last complete 4-stable run
/5/errors error logs from latest 5-current run
/logs all logs from latest 5-current run
/packages packages from latest 5-current run
/bak/errors error logs from last complete 5-current run
/bak/logs all logs from last complete 5-current run
/bak/packages packages from last complete 5-current run
Basically, if the port shows up in
packages, or it is in
logs but not in
errors, it built fine. (The
errors directories are what you get
from the web page.)I added a new port. Do I need to add it to the
INDEX?No. The ports manager will regenerate the
INDEX and commit it every few
days.Are there any other files I am not allowed to
touch?Any file directly under ports/, or
any file under a subdirectory that starts with an
uppercase letter (Mk/,
Tools/, etc.). In particular, the
ports manager is very protective of
ports/Mk/bsd.port*.mk so do not
commit changes to those files unless you want to face his
wra(i)th.Miscellaneous QuestionsWhy are trivial or cosmetic changes to files on a vendor
branch a bad idea?From now on, every new vendor release of that file will
need to have patches merged in by hand.From now on, every new vendor release of that file will
need to have patches verified by hand.The option does not work very well.
Ask &a.obrien; for horror stories.How do I add a new file to a CVS branch?To add a file onto a branch, simply checkout or update
to the branch you want to add to and then add the file using
cvs add as you normally would. For
example, if you wanted to MFC the file
src/sys/alpha/include/smp.h from HEAD
to RELENG_4 and it does not exist in RELENG_4 yet, you would
use the following steps:MFC'ing a New File&prompt.user; cd sys/alpha/include
&prompt.user; cvs update -rRELENG_4
cvs update: Updating .
U clockvar.h
U console.h
...
&prompt.user; cvs update -kk -Ap smp.h > smp.h
===================================================================
Checking out smp.h
RCS: /usr/cvs/src/sys/alpha/include/smp.h,v
VERS: 1.1
***************
&prompt.user; cvs add smp.h
cvs add: scheduling file `smp.h' for addition on branch `RELENG_4'
cvs add: use 'cvs commit' to add this file permanently
&prompt.user; cvs commitWhat meta information should I include in a
commit message?As well as including an informative message with each commit
you may need to include some additional information as
well.This information consists of one or more lines containing the
the key word or phrase, a colon, tabs for formatting, and then the
additional information.The key words or phrases are:PR:The problem report (if any) which is affected
(typically, by being closed) by this commit.Submitted by:The name and e-mail address of the person that
submitted the fix.Reviewed by:The name and e-mail address of the person or people
that reviewed the change. If a patch was submitted to a
mailing list for review, and the review was favourable,
then just include the list name.Approved by:The name and e-mail address of the person or people
that approved the change. It is customary to get prior
approval for a commit if it is to an area of the tree to
which you do not usually commit. In addition, during the
run up to a new release all commits
must be approved by the release
engineer. If these are your first commits then you should
have passed them past your mentor first for approval, and
you should list your mentor.Obtained from:The name of the project (if any) from which the code
was obtained.MFC after:If you wish to receive an e-mail reminder to
MFC at a later date, specify the
number of days, weeks, or months after which an
MFC is planned.Commit log for a commit based on a PRYou want to commit a change based on a PR submitted by John
Smith containing a patch. The end of the commit message should
look something like this....
PR: foo/12345
Submitted by: John Smith <John.Smith@example.com>Commit log for a commit needing reviewYou want to change the virtual memory system. You have
posted patches to the appropriate mailing list (in this case,
freebsd-arch) and the changes have been
approved....
Reviewed by: -archCommit log for a commit needing approvalYou want to commit a change to a section of the tree with a
MAINTAINER assigned. You have collaborated with the listed
MAINTAINER, who has told you to go ahead and commit....
Approved by: abcWhere abc is the account name of
the person who approved.Commit log for a commit bringing in code from
OpenBSDYou want to commit some code based on work done in the
OpenBSD project....
Obtained from: OpenBSDCommit log for a change to &os.current; with a planned
commit to &os.stable; to follow at a later date.You want to commit some code which will be merged from
&os.current; into the &os.stable; branch after two
weeks....
MFC after: 2 weeksWhere 2 is the number of days,
weeks, or months after which an MFC is
planned. The weeks option may be
day, days,
week, weeks,
month, months,
or may be left off (in which case, days will be assumed).In some cases you may need to combine some of these.Consider the situation where a user has submitted a PR
containing code from the NetBSD project. You are looking at the
PR, but it is not an area of the tree you normally work in, so
you have decided to get the change reviewed by the
arch mailing list. Since the change is
complex, you opt to MFC after one month to
allow adequate testing.The extra information to include in the commit would look
something likePR: foo/54321
Submitted by: John Smith <John.Smith@example.com>
Reviewed by: -arch
Obtained from: NetBSD
MFC after: 1 month
diff --git a/en_US.ISO8859-1/articles/console-server/article.sgml b/en_US.ISO8859-1/articles/console-server/article.sgml
index 0218a9b4d0..fd85840f76 100644
--- a/en_US.ISO8859-1/articles/console-server/article.sgml
+++ b/en_US.ISO8859-1/articles/console-server/article.sgml
@@ -1,1231 +1,1231 @@
Console Server
Console Server
The Problem
You have a computer room with lots of Unix server machines and
lots of comms hardware. Each of these machines needs a serial
console. But serial terminals are hard to find and quite
expensive (especially compared to a much more capable PC). And
they take up a lot of precious space in the computer room.
You need access to the console because when things break, that
is where error messages go. And some tasks have to be done on
the console (e.g. boot problems or OS installs/upgrades). Some
Unix systems allow the console to break out to the ROM monitor
which can sometimes be the only way to unstick a hung machine.
This is often done with a LINE BREAK sent on the console serial
port.
If we are going to play about with consoles, then there are a
couple of other things that would be great:
Remote access. Even in the same office, it would be
convenient to access all the consoles from your desk without
walking into the computer room. But often the machines are
off-site, perhaps even in another country.
Logging. If something has gone wrong, you would like to be
able to have a look at the previous console output to see
what is up. Ordinary console screens give you the last 25
lines. More would be better.
Network Independence. The solution needs to work even if the
network is down. After all, a failed network is when you need
consoles the most! Even better is network independence with
remote access.
No single-point failure. A console system that crashes every
machine when it fails is no use. This is particularly tricky
with Sun Unix hosts as they will interpret a powered-off
terminal as a BREAK, and drop back to the ROM monitor.
Interface with a pager or some similar alerter
device.
Ability to power-cycle machines remotely.
Not be too expensive. Free is even better!
Possible Solutions
If you use PC hardware for your servers, then a so-called
"KVM switch" is one possible solution. This allows the
use of a single Keyboard, Video screen and
Mouse for multiple boxes. This cuts down on the space
problem, but only works for PC hardware (not any comms gear you
might have), and is not accessible from outside the computer
room. Nor does it have much scroll-back or logging, and you
have to handle alerting some other way. The big downside is
that it will not work for serial-only devices, such as
communications hardware. This means that even with a room full
of PC-based servers, you are probably still going to need some
sort of serial console solution. [Actually, Doug Schache has
pointed out that you can get KVM switches that also do
serial consoles or Sun-compatible KVM switching as well as PCs,
but they are expensive. See Avocent for example.]
You might be tempted to do without a console terminal, but when
things go pear-shaped you really need to see what is on
the console. And you have to use the console to boot the
machine and do things like OS upgrades or installs.
You might try having a single console terminal and switching
from server to server as needed, either with a serial switch or
just by patching it into the required machine. Serial switches
are also hard to come by and not cheap, and may cause problems
with sending BREAK when they switch. And (if your computer room
is anything like ours) you never seem to have the right
combination of patch leads to connect to the machine you need
to, and even if the leads are there you can never work out
exactly which combination of DTE/DCE headshells goes with which
lead goes with which hardware. So you spend the first 10
minutes fooling around with breakout boxes and a box of leads,
all while the server is down and the users are screaming. Of
course this does not deal with the logging or remote access
requirements. And inevitably the console is not switched to the
machine you need so you lose all the console messages that might
tell you what is going on.
One popular solution is to use terminal server hardware.
Typically, the serial ports are connected to the various machine
consoles, and set up for "reverse telnet" access. This means a
user can telnet to a given IP/port and be connected to the
appropriate console. This can be very cost-effective, as
suitable old terminal servers can be picked up fairly cheaply
(assuming you do not have a couple lying around). And it is of
course network-accessible so suitable for remote access. But it
suffers from one major drawback: if the network is down, then
you have no access to any console, even if you are
standing right next to the machine. (This may be partially
alleviated by having a suitable terminal connected to one of the
terminal server ports and connecting from there, but the
terminal server software may not support that.) Also there is
no logging or replay of console messages. But with a bit of
work, and the addition of some software such as conserver (described below),
this can be made to work pretty well.
A possibility suggested by Bron Gondwana is similar to the
above solution. If you use servers with multiple serial ports,
you can connect each spare serial port to the console port of
the "next" server, creating a ring of console connections (in
some sort of order). This can be made to work reasonably well
with the aid of the conserver software, but can
be a bit confusing otherwise (i.e. remembering which port is
connected to which console). And you are stuck if you need to
use serial ports for other things (such as modems) or you have
machines without spare ports.
Or, if your budget exceeds your willingness to hack, you can
buy an off-the-shelf solution. These vary in price and
capability. See, for example, Lightwave, Perle, Avocent or Black
Box. These solutions can be quite expensive - typically
$USD100 - $USD400 per port.
Our Solution
In light of the above requirements, we chose a solution based
on a dedicated PC running Unix with a multiport serial card, and
some software designed to handle serial consoles.
It includes the following elements:
A surplus PC. We used a Pentium 166, with a PCI bus,
2Gbyte hard disk and 64Mb of RAM. This is a massive overkill
for this task, and P-100, 500Mb, 32Mb would be more than
enough.
A PC Unix system. We used FreeBSD 4.3 as that is used
for other tasks within our office.
A multi-port serial card. We chose the EasyIO-PCI
8-port card from Stallion
Technologies. This cost us about $AUD740, or under
$100/port, from Harris
Technologies (which has lots of stuff but is by no means
the cheapest place in town - shop around and you might get it
a lot cheaper.) This card has a big DB80 connector on the
back, and a cable plugs into that which has a block with 8
RJ-45 sockets on it. (We chose the RJ-45 version as our
entire cable plant is RJ-45. This allows us to patch
connections from the required box to the console server
without any special cables.) This is the only thing we needed
to buy to make this all happen.
We build two servers, one for each computer room, with 8
ports in one and 16 ports (via two EasyIO-PCI cards) in the
other. If we needed more than 16 ports, then another of the
Stallion cards would be more cost-effective. We could
conceivably support 128 ports in each server (with 2
EasyConnect 8/64 host cards and 8 16 port RJ-45 modules) for
about $AUD12,000.
A modem for remote access to the console server host when
the network is down. We have not done this yet as the computer
room is next door, but when we put a server in Sydney we will
add the modem. The idea is that when the network is down, you
can dial up and log into the server machine and run the
console program locally. For security, we will probably leave
the modem powered off and ask the gopher in Sydney to turn on
the well-labelled button when we need it.
A program called conserver. This program
does all the magic required to enable remote access to
consoles, and do the replaying and logging etc. It comes in
two parts: a server called conserver that runs as
a daemon and connects to the serial ports, handles logging
etc, and a client program called console that can
connect to the server, display console messages, send
keystrokes (and BREAKs) etc.
This design covers all the major requirements except remote
power cycling:
Remote access comes because the console
client program works across the network.
Logging is handled by the conserver
program.
If the network is down, then we can use the console on
the PC to run the console client locally. For
remote sites, we can add a modem for dial-in access to the the
server command line to run the client.
By patching the Solaris servers (see below), we can avoid pranging the whole
computer room when the console server PC crashes (or the power
supply fails, or whatever).
We already have pager alerts from another system we have
installed, but the console server has all the required log
info so that could easily be implemented if we needed. And it
even has a modem for calling the pager company!
We do not currently support remote power cycling. Some
versions of the conserver program support this, but it does
require specialised serial-controlled power boards. We have
no immediate need for remote power cycling (we have a gopher
in each remote office who can do it by remote control) so this
is not a major problem, and we could add it easily should we
ever see the need and get the appropriate hardware.
This solution was very cheap. Total cost for the 9-port
server was $AUD750 for the IO card, as we re-used a surplus PC
and already owned the hardware for the special cables. If we
had to buy everything, then it would still only cost around
$AUD1500 for the 8-port server.
Setting Up The Server
Patching the Stallion driver
The only hitch with setting up the server PC is getting the
device drivers for the Stallion card. FreeBSD has supported
Stallion ISA cards for many years, but unfortunately the driver
has not been actively maintained for some years, and does not
support the newer Stallion cards (such as the EasyIO-PCI card or
some of the other ISA cards with newer UART chips). I have put
together a patch file for FreeBSD
4.3 (based on the work of many other people) that will update
the system to support these newer cards. Hopefully, this patch
will be committed to the FreeBSD tree in time for the 4.4
release. If you are running FreeBSD 4 from prior to this time,
you will need to download and apply this patch (instructions are
included at the top of the patch file). If you are running
FreeBSD 3, then you had probably best upgrade.
Configuring a new kernel
The Stallion driver is not included in the default
GENERIC kernel, so you will need to create a kernel
config file with the appropriate entries. See the
stl(4) man page and the appropriate section of the
FreeBSD
Handbook.
Building World
After applying the patch you will certainly need to update the
whole system, including all the user programs and the kernel.
See the documentation in /usr/src/UPDATING and the
FreeBSD
Handbook.
Making The Devices
You will need to make the device notes for the Stallion card
(which are not made by default). A new version of
/dev/MAKEDEV with Stallion support will have been
created by the mergemaster run during the above
procedure. If you have a Stallion card with more than 8 ports,
then you will need to edit /dev/MAKEDEV and change
the definition of maxport at about line 250. By
default, MAKEDEV only makes device nodes for 8
ports to keep the size of the /dev directory down.
Run a command like
cd /dev/ && sh MAKEDEV cuaE0
to create dial-out devices for the first Stallion card. See
the comments in MAKEDEV and the stl(4)
man page for more details.
Compiling conserver
(See the section on Conserver versions below; the version I use is not
the one available in the FreeBSD ports collection.)
There are two ways to install conserver. You can either
compile from the source or use the FreeBSD ports framework.
Using the port framework
Using the ports framework is a bit cleaner, as the package
system can then keep track of installed software and cleanly
delete them when not being used. Download the port framework
from here, unpack it to
create a directory called conserver-port. CD to
that directory and (as root) type
make DEFAULTHOST=consolehost install
where consolehost is the name of the machine running
the console server. Specifying this when the binary is compiled
will avoid having to either specify it each time the program is
run on remote hosts or having to maintain a
conserver.cf file on every host. This command will
fetch, patch, configure, compile and install the conserver
application.
You can then run make package to create a binary
package that can be installed on all the other FreeBSD hosts
with the pkg_add command. For extra style points,
you can make a two versions of the package: one for the console
server machine without a DEFAULTHOST argument, and
one for all the other hosts with a DEFAULTHOST
argument. This will mean the console client program on the
console server machine will default to localhost,
which will work in the absence of name servers when the network
is busted, and also allow "trusted" (i.e. no password required)
connections via the localhost IP address for users logged into
the console server machine (either via the console screen or the
emergency backup modem). The version for the other machines
with a DEFAULTHOST argument means users can just
use the console client without specifying a
hostname every time, and without needing to configure the
conserver.cf file on every machine.
From the source tarball
If you prefer, you can download conserver and compile it
yourself. You might need to do this if you want to install the
console client on non-FreeBSD systems. We run the client on our
Solaris hosts and it inter-operates with the FreeBSD-hosted
server with no problems. This allows anyone in the whole
company (many of whom have PCs and no FreeBSD host access on
their desk) to access the console server.
Download the file from the conserver.com
FTP site. Extract it into a handy directory then configure
it by running
The --with-master argument avoids having to
specify the master server every time the client is run remotely
(or keeping up-to-date config files on all remote hosts). The
--with-port argument avoids having to update
/etc/services on every machine.
Then type make and, as root, make
install.
Configuring conserver
The conserver program is configured via a file called
conserver.cf. This file usually lives in
/usr/local/etc and is documented in the conserver.cf(5) man
page.
The first line means all the console log files by default go
into the directory /var/log/consoles/. The
& in each line says the log file for that machine
will be /var/log/consoles/machine.
The next three lines show three machines to which we need to
connect. We use the cuaEx devices rather than the
ttyEx devices because console ports typically do not
show carrier. This means that opening ttyEx would hang
and conserver would never connect. Using the
cuaEx device avoids this problem. Another solution
would be to use the ttyEx devices and enable soft
carrier on these ports, perhaps by setting this using the
ttyiEx device in the /etc/rc.serial file.
See the comments in this file for more details. Also see the
sio(4) man page for information on the
initial-state and locked-state devices. (The Stallion driver
also supports these conventions). And see the
stty(1) man page for details on setting device
modes.
The last section shows that any user logged into the server
machine has passwordless access to all consoles. We do this
because there are no user accounts on this machine and it is
safely isolated from the wide world behind our firewall. The
allow line allows anyone on a machine inside our organisation to
access the console server if they provide their password, which
is recorded in the conserver.passwd file (see next
section).
Setting conserver passwords
The conserver.passwd file contains the encrypted
version of the password that each user. The file is documented
in the conserver.cf(5) man
page.
The only tricky bit is loading the file with encoded passwords.
It appeared in FreeBSD that was is no obvious way to generate an
encrypted password for inclusion in another file (but see
below). So I put together a quick hack perl script to do
this:
(Note that this uses the FreeBSD MD5-style encrypted passwords.
Running this on other Unix variants, or on FreeBSD with DES
passwords, will likely need a different style of salt.)
Kris Kennaway has since pointed out you can get the same effect
using the openssl passwd command:
There are two ways this can be done. Firstly, you could start
up conserver from init by including an entry in /etc/ttys that
looks a bit like this:
cuaE0 "/usr/local/sbin/conserver" unknown on insecure
This has two advantages: init will restart the master console
server if it ever crashes for any reason (but we have not
noticed any crashes so far), and it arranges for STDOUT of the
conserver process to be directed to the named tty (in this case
cuaE0). This is useful because you can plug a terminal into
this port, and the conserver program will show all console
output not otherwise captured by a client console connection.
This is useful as a general monitoring tool to see if anything
is going on. We set this terminal up in the computer room but
visible from the main office. It is a very handy feature. The
downside of running conserver from the ttys file is that it
cannot run in daemon mode (else init would continually restart
it). This means conserver will not write a PID file, which makes
it hard to rotate the log files.
So we start conserver from an rc.d script. If you installed
conserver via the port, there will be a
conserver.sh.sample file installed in
/usr/local/etc/rc.d. Copy and/or rename this to
conserver.sh to enable conserver to start at boot
time.
In fact we use a modified version of this script which also
connects conserver to a terminal via a tty device so we can
monitor unwatched console output. Our conserver.sh script looks
like this:
#!/bin/sh
#
# Startup for conserver
#
PATH=/usr/bin:/usr/local/bin
case "$1" in
'start')
TTY=/dev/cuaE7
conserver -d > $TTY
# get NL->CR+NL mapping so msgs look right
stty < /dev/cuaE7 opost onlcr
echo -n ' conserver'
;;
'stop')
kill `cat /var/run/conserver.pid` && echo -n ' conserver'
;;
*)
echo "Usage: $0 { start | stop }"
;;
esac
exit 0
(Note the use of cuaE0 device and the need to set TTY modes for
proper NL->CR handling).
Keeping the log files trimmed
FreeBSD has a program called newsyslog that will
automatically handle log file trimming. Just add some lines to
the configuration file /etc/newsyslog.conf for the
console logs:
#
# The log files from conserver
/var/log/consoles/gallows 644 10 1000 * Z /var/run/conserver.pid
/var/log/consoles/kanga 644 10 1000 * Z /var/run/conserver.pid
/var/log/consoles/roo 644 10 1000 * Z /var/run/conserver.pid
This tells newsyslog (which is run from cron every hour on the
hour) that the console log files should be archived and
compressed once they reach 1Mb, that we should keep 10 of them,
and that to signal the server program you send a SIGHUP to the
process whose PID is in the conserver.pid file. This is the
master server, and it will arrange to signal all the child
processes. Yes, this will send a HUP to all clients whenever a
single log file needs rotating, but that is quite cheap. See
the newsysylog(8) man page for details.
Cabling
This is always the hardest part of this kind of problem!! We
had only a dozen or so cables/headshells to build, and we
already had a collection of the appropriate crimping tools and
hardware, so we did it ourselves. But if you are not set up for
this, or you have a large number of cables to make, then you
might consider getting some cables custom made. Look in the
- yellow pages, there are a suprising number of places that do
+ yellow pages, there are a surprising number of places that do
this! Getting custom-made cabling is good, and you can get much
more professional results, but can be expensive. For example,
the RJ-45 to DB-25 adapter kits described below are about $10
each; custom-made headshells are about twice that (and take a
couple of weeks to arrive). Similarly, crimping custom RJ-45 to
RJ-45 leads is quite cheap (say, $5 each) but it takes a fair
amount of time. Custom made RJ-45 socket to RJ-45 plug
converters cost about $25 each.
We have settled on RJ-45 Cat-V cabling for all our office and
computer room cabling needs. This included patching between
racks in the computer room. For serial connections, we use
patchable headshells that have RJ-45 sockets on the back. This
allows us to patch whatever RJ-45 - DB-25 connections we need.
Which is just as well, because there are many incompatible ways
to represent serial connections on the RJ-45 plug. So the
cabling has to be very careful to use the right mapping.
RJ-45 colors
RJ-45 cables and plugs have 8 pins/conductors. These are used
as 4 matched pairs. There are a couple of conventions about how
the pairs are mapped onto pins, but 100baseT uses the most
common (known as EIA 586B). There are three common color-coding
conventions for the individual conductors in RJ-45 cables. They
are:
Pin
Scheme 1
Scheme 2 (EIA 568B)
Scheme 3 (EIA 568A)
Pair
1
Blue
White+Green
White+Orange
2+
2
Orange
Green
Orange
2-
3
Black
White+Orange
White+Green
3+
4
Red
Blue
Blue
1+
5
Green
White+Blue
White+Blue
1-
6
Yellow
Orange
Green
3-
7
Brown
White+Brown
White+Brown
4+
8
White or Grey
Brown
Brown
4-
Note EIA 468A and EIA 568B are very similar, simply swapping
the colors assigned to pair 2 and pair 3.
The pins in the RJ-45 plug are numbered from 1 to 8. Holding a
patch lead with the cable pointing down and the clip away from
you, pin 1 is at the left. Or, looking into an RJ-45 socket
with the clip to the top, pin 1 is on the right. The following
illustration (shamelessly lifted from the Cabletron web site
above) shows it pretty well:
We have four classes of equipment to deal with in our setup:
Sun Servers
Sun servers operate as DTE (i.e. send data on TxD and read RxD,
and assert DTR) with a female DB-25 socket on board. So we need
to create a headshell for the Stallion that operates as DCE and
has a male DB-25 plug (i.e. acts as a null modem cable
as well as converts from RJ-45 to DB-25). We use headshells
that have an RJ-45 socket in them and 8 short flyleads with
DB-25 pins on the end. These pins can be inserted into the
DB-25 plug as required. This allows us to create a custom
RJ-45-DB-25 mapping. We used a couple of different sorts,
including the MOD-TAP
part no. 06-9888-999-00
and the FA730
series from Black
Box.
On our version of the headshells, these flyleads had the
following colours (from Pin 1-8): Blue, Orange, Black, Red,
Green, Yellow, Brown, White. (Looking into an RJ-45 socket,
with the clip towards the top, pin 1 is on the right.) This is
how they are connected to the DB-25 socket:
Stallion RJ-45 Pin
Colour
Signal
Sun DB-25 Male Pin
RS232 Signal
1
Blue
DCD
20
DTR
2
Orange
RTS
5
CTS
3
Black
Chassis Gnd
1
Chassis Gnd
4
Red
TxD
3
RxD
5
Green
RxD
2
TxD
6
Yellow
Signal Gnd
7
Signal Gnd
7
Brown
CTS
4
RTS
8
White
RTS
8
DCD
Note that colours may be different for your cables/headshells.
In particular, pin 8 may be grey instead of white.
Remember to label the headshell clearly, in a way that
will not fade/fall off/rub off with time!
Cisco 16xx/26xx/36xx Routers
I think that all Cisco gear that has RJ-45 console ports and
runs IOS will have the same cable requirements. But best to
check first. We have tried this on 1600s and 2600s only.
Both the Stallion card and the 2600 have RJ-45 connections, but
of course they are not compatible. So you need to crimp up a
special RJ-45-RJ-45 cable. And this cable must be plugged in
the right way round! We use normal RJ-45 flyleads from the
router to the patch panel, then the special flylead from the
patch panel to the Stallion card.
We built two special Stallion-Cisco leads by cutting in half a
2m flylead and crimping an RJ-45 with the appropriate pinouts to
each free end. The original connector will be the Cisco end of
the cable, the new crimped connector will be the Stallion end.
Holding the RJ-45 connector on the flylead with the cable
pointing down and the clip pointing away, this is the order of
the colours of the cables in our flylead (pins 1-8, from L to
R): white/green, green, white/orange, blue, white/blue, orange,
white/brown, brown. For the Stallion end, trim and discard the
brown/white+brown and green/white+green pairs. Then holding the
RJ-45 plug in the same manner (cable down, clip away), the
connections should be (from L to R): None, None, Blue, Orange,
White/Orange, White/Blue, None, None, as shown:
Cisco RJ-45 Pin
Colour
Cisco Signal
Stallion RJ-45
Pin
Stallion Signal
1
White/Green
RTS
N/C
2
Green
DTR
N/C
3
White/Orange
TxD
5
RxD
4
Blue
Gnd
3
Gnd
5
White/Blue
Gnd
6
Gnd
6
Orange
RxD
4
TxD
7
White/Brown
DSR
N/C
8
Brown
CTS
N/C
Note again that colours may be different for your cables/headshells.
Carefully label the cable, and each end of the cable, and test
it. If it does not work, testing is really hard as they
do not make RJ-45 serial line testers!
Let me state this more stongly: Be veryVERY
sure that you label this cable in a way that is easily,
instantly and permanently recognisable as a special cable and
not easily confused with normal drop cables. Some suggestions
(from Hugh Irvine):
Make them out of different coloured cable
For marking the ends, clear heat-shrink tubing slipped over
printed labels *before* putting on the connectors is the best way I have
seen for marking what they are.
You can also use Panduit or similar tags that
you put on with nylon tie straps, but I find the ink wears off the
tags.
Cisco Catalyst switches
Astoundingly, the pinout on the console ports of the Catalysts is
actually different to the pinout used on the 26xx-series
Cisco hardware. I think the way to tell which is which is by
considering the operating software. If it uses IOS, then the previous
pinout is required. If it uses the switch software, then this pinout
is required.
Fortunately, while the pinouts are different, the Catalyst
pinout is simply a mirror image of the pinout for the 2600.
Even more fortunately, the Ciscos (both Catalysts and 2600s)
seem to ship with a special "rollover" cable, which is exactly
what is required in this case. We use the rollover cable from
the Catalysts to the patch panel, then the same cable as above
for the 2600s from the patch panel to the Stallion card, and it
all works just fine.
This rollover cable is an RJ-45-RJ-45 cable and is intended to
be used with the shipped (hardwired) RJ-45 - DB-25 and RJ-45 -
DB-9 headshells for console connections. Ours are 2m long,
either light blue or black, and are quite flat. Attempts to use
them for 100baseT ethernet will fail miserably! You can tell it
is a rollover cable by holding both ends with the cable pointing
down and the clip pointing away from you. Check the colour of
the leads in each pin in the two connectors, they should be
mirror images. (In our case, one goes
grey-orange-black-red-green-yellow-blue-brown, the other
brown-blue-yellow-green-red-black-orange-grey). This is a
rollover cable.
If you do not have a rollover cable present, then you can use
the same cable as for the 26xx except plug it in the other way
around (i.e. original 8-pin plug goes into the Stallion, the new
crimped plug with only 4 active wires goes into the Catalyst).
FreeBSD Servers (or any other i386 PC systems using a serial console)
We run FreeBSD 4 on a couple of i386 PCs for various peripheral
uses. FreeBSD usually uses a screen and keyboard for the
console, but can be configured to use a serial port (usually the
first serial port known as COM1 in DOS/Windows or ttyd0 in
Unix).
The cabling for these servers depends on the PC harware. If
the PC has DB-25 female socket on board (as most older PCs do),
then the same headshell as works for the Sun server above will
work fine. If the PC has DB-9 male plug on board (as more
recent PCs tend to do), then there are two choices. Either use
a DB-9 to DB-25 converter (this is not recommended as it can
lead to unreliable connections over the long term as the adapter
is bumped/works loose), or build an RJ-45 to DB-9 cable as
follows:
Stallion RJ-45 Pin
Colour
Signal
PC DB-9 Female
Pin
RS232 Signal
1
Blue
DCD
4
DTR
2
Orange
RTS
8
CTS
3
Black
Chassis Gnd
N/C
4
Red
TxD
2
RxD
5
Green
RxD
3
TxD
6
Yellow
Signal
Gnd
5
Signal Gnd
7
Brown
CTS
7
RTS
8
White
RTS
1
DCD
See below for tips on configuring FreeBSD to
use a serial console.
Anyone who has turned off a terminal used as a console for a
Sun system will know what happens and why this is a problem.
Sun hardware recognises a serial BREAK as a command to halt the
OS and return to the ROM monitor prompt. A serial BREAK is an
out-of-band signal on an RS-232 serial port that involves making
the TX DATA line active (i.e. pulled down to less than -5v) for
more than two whole character times (or about 2ms on a 9600bps
line). Alas, this BREAK signal is all to easily generated by
serial hardware during power-on or power-off. And the Stallion
card does, in fact, generate breaks when the power to the PC
fails. Unless fixed, this problem would mean that every Sun box
connected to the console server would be halted whenever the
power failed (due to dead power supplies, or fat-fingered
operators unplugging it, or whatever). This is clearly not an
acceptable situation.
Fortunately, Sun have come up with a set of fixes for this.
For Solaris 2.6 and later (and perhaps earlier, but who was
crazy enough to run 2.5??), the kbd(1) command can
be used to disable the ROM-on-BREAK behaviour. This is a good
start, but leaves you out of luck in the situation where a break
is needed to get into a broken machine.
Starting with Solaris 8, the kbd command can also
be used to enable an alternate break sequence using the
kbd -a alternate command. When this is set, the
key sequence <Return><Tilda><control-B>
(within 5 seconds) will drop to the ROM. You can enable this
permanently by editing the /etc/default/kbd file;
see the kbd(1) man page. Note that this alternate
break sequence is only active once the kernel has started
running multiuser and processed the default file. While the ROM
is active (during power-on and during the boot process) and
while running single-user, you still need to use a BREAK to get
to the ROM prompt. The console client can cause the server to
send a BREAK using the escape sequence "^Ecl1" (i.e. escape, c,
ell, one).
If you have a Sun software support contract, there are patches
available for Solaris 2.6 and 2.7 that add the"alternate break"
capability integrated into Solaris 2.8. Solaris 2.6 requires
patch 105924-10 or higher. Solaris 2.7 requires patch 107589-02
or higher.
We have added this patch to all our Solaris 2.6 servers, and
added it (and the entry in the /etc/default/kbd file) to our
jumpstart configuration so it will automatically be added to
every new install.
We have confirmed by direct testing that neither the Cisco
16xx, 26xx, or Catalyst hardware suffers from the BREAK sent
when the Stallion card loses power.
The procedure for doing this is described in detail in the FreeBSD
Handbook. This is a quick summary.
Check the kernel configuration
Check that the kernel configuration file has flags
0x10 in the config line for the sio0 device.
This signals this device (known as COM1 in
DOS/Windows or /dev/ttyd0 in FreeBSD) can be used
as a console. This flag is set on the GENERIC and
LINT sample configs, so is likely to be set in your
kernel.
Create the /boot.conf file
This file should be created containing a single line containing
just "-h". This tells the FreeBSD boot blocks to use the serial
console.
Edit /etc/ttys
Edit this file and make the following changes.
If you are not going to have any keyboard/video screen on this
server at all, you should find all the lines for
ttyv0 through ttyv8:
ttyv1 "/usr/libexec/getty Pc" cons25 on secure
Change the on to off. This will stop
login screens being run on the useless video consoles.
Find the line containing ttyd0. Change it
from
ttyd0 "/usr/libexec/getty std.9600" dialup off secure
to
ttyd0 "/usr/libexec/getty std.9600" vt100 on secure
(replacing vt100 with the term type of your
console. xterms might be a good choice). This
allows you to log in to the console port once the system is
running multi-user.
Reboot and away you go!
Security Implications
The client-server protocol for conserver requires
the user of the console client to enter a password.
This password is passed across the net in cleartext!!!
This means conserver is not really suitable for use
across untrusted networks (such as the Internet). Use of
conserver-only passwords (in the conserver.passwd
file) slightly mitigate this problem, but anyone sniffing a
conserver connection can easily get console access, and from
there prang your machine using the console break sequence. For
operating across the Internet, use something secure like
SSH to log into to the server machine, and run the
console client there.
The conserver program has fractured into a number
of versions. The home page referenced above seems to be the
latest and most featureful version around, and carries a version
number of "7.0.2". This is maintained by Bryan Stansell (bryan@conserver.com), who
has brought together the work of many people (listed on his
webpage).
The FreeBSD ports collection contains a port for version 8.5 of
conserver. This seems to be older and less featureful than the
7.0.2 version (in particular, it does not support consoles
connected to terminal server ports and does not support a
conserver.passwd file), and is written in a fairly
idiosyncratic manner (using a preprocessor to generate C code).
Version 8.5 is maintained by Kevin S Braunsdorf (ksb+conserver@sa.fedex.com)
who did most of the original work on conserver, and whose work
Bryan Stansell is building on. The 8.5 version does support one
feature not in the 7.0.2 version (controlling power to remote
machines via a specific serial-interfaced power controller
hardware).
As shipped with FreeBSD, the 8.5 version does not authenticate
against FreeBSD servers using MD5 passwords. There is a patch
in the FreeBSD GNATS system (ports/28432)
that fixes this problem. Kevin has indicated this patch will be
included in future versions of conserver from him. There are a
couple of other problems with the 8.5 version as well.
It is hard to rotate log files, as conserver
does not create a PID file and killing the parent conserver
process does not kill the children (which have the logfiles
open).
Compiling it (on anything other than FreeBSD) is a pain
because it depends on a couple of other large programs to
compile. This is because it is not written in C but in a
macro language that produces C code, and so depends on these
macro processors. The intent of this macro language is to
hide system dependencies. The 7.0.2 version uses GNU
configure for the same task, and compiling this version on
Solaris is a breeze. (Compiling 8.5 is easier on FreeBSD as
the ports framework takes care of all this for you).
After compiling on Solaris, the console
program would not authenticate against the
conserver program on FreeBSD, because it used
getpass() on Solaris that silently truncates
passwords to 8 characters. FreeBSD uses MD5 passwords that
can be (and in our case, are) longer than 8 characters.
There was some confusion about the role of "groups" in
conserver. When replaying log messages in 8.5,
it seemed to replay messages from all consoles in the group,
whereas 7.0.2 seems to do the obvious thing and keep output
from individual consoles separate. (This may well have just
been boneheaded setup mistakes on my part however.) The
upshot was that the 8.5 version needed a new group (and
process) per console, whereas the 7.0.2 version will happily
support multiple ports per process.
His Greater Scroll
of Console Knowledge contains evern more specific info on
connecting various devices to various other devices. Oh the
joys of standards!
The Real Weasel company
makes a ISA or PCI video card that looks like a PC video card
but actually talks to a serial port. This can be used to
implement serial consoles on PC hardware for operating systems
that can not be forced to use serial console ports early
enough.
Initial version announced on FreeBSD and Sage-AU mailing lists.
12 July, 2001
Notes on some commercial console servers from Doug Schache.
Grrr. Fixed the pinout for the Cisco - Stallion RJ-45 cable.
The cable would have worked but was backwards. The new table now
reflects the description.
Noted that Catalyst cable is a 26xx cable plugged in the othyer
way around.
Added notes about RJ-45 pin numberring and color coding
conventions
Added notes about serial console on FreeBSD/i386 platforms.
Now in RCS.
13 July, 2001
Notes on cable marking from Hugh Irvine
Notes on custom-made cables, source for headshells
18 July, 2001
Links to Black Box adapters
Fix dates. It's July, already!
Pointers to commercial solutions and serial-port-on-other-server setup
Characteristics of Two Spindles Organized with VinumOrganizationTotal CapacityFailure ResilientPeak Read PerformancePeak Write PerformanceConcatenated PlexesUnchanged, but appears as a single driveNoUnchangedUnchangedStriped Plexes (RAID-0)Unchanged, but appears as a single driveNo2x2xMirrored Volumes (RAID-1)1/2, appearing as a single driveYes2xUnchanged
shows that striping yields
the same capacity and lack of failure resilience
as concatenation, but it has better peak read and write performance.
Hence we will not be using concatenation in any of the examples here.
Mirrored volumes provide the benefits of improved peak read performance
and failure resilience--but this comes at a loss in capacity.Both concatenation and striping bring their benefits over a
- single spindle at the cost of increased likelyhood of failure since
+ single spindle at the cost of increased likelihood of failure since
more than one spindle is now involved.When three or more spindles are present,
Vinum also supports rotated,
block-interleaved parity (also called RAID-5)
that provides better
capacity than mirroring (but not quite as good as striping), better
read performance than both mirroring and striping,
and good failure resilience.
There is, however,
a substantial decrease in write performance with RAID-5.
Most of the benefits become more pronounced with five or more
spindles.The organizations described above may be combined to provide
benefits that no single organization can match.
For example, mirroring and striping can be combined to provide
failure-resilience with very fast read performance.Vinum HistoryVinum
is a standard part of even a "minimum" FreeBSD distribution and
it has been standard since 3.0-RELEASE.
The official pronunciation of the name is
VEE-noom.&vinum.ap; was inspired by the Veritas Volume Manager, but
was not derived from it.
The name is a play on that history and the Latin adage
In Vino Veritas
(Vino is the accusative form of
Vinum).
Literally translated, that is "Truth lies in wine" hinting that
drunkards have a hard time lying.
I have been using it in production on six different servers for
over two years with no data loss.
Like the rest of FreeBSD, Vinum
provides "rock-stable performance."
(On a personal note, I have seen Vinum
panic when I misconfigured something, but I have
never had any trouble in normal operation.)
Greg Lehey wrote
Vinum for FreeBSD,
but he is seeking
help in porting it to NetBSD and OpenBSD.Just like the rest of FreeBSD, Vinum
is undergoing continuous
development.
Several subtle, but significant bugs have been fixed in recent
releases.
It is always best to use the most recent code base that meets your
stability requirements.Vinum Deployment StrategyVinum,
coupled with prudent partition management, lets you
keep "warm-spare" spindles on-line so that failures
are transparent to users. Failed spindles can be replaced
during regular maintenance periods or whenever it is convenient.
When all spindles are working, the server benefits from increased
performance and capacity.Having redundant copies of your home directory does not
help you if the spindle holding root,
/usr, or swap fails on your server.
Hence I focus here on building a simple
foundation for a failure-resilient server covering the root,
/usr,
/home, and swap partitions.Vinum
mirroring does not remove the need for making backups!
Mirroring cannot help you recover from site disasters
or the dreaded
rm -r -f / command.Why Bootstrap Vinum?It is possible to add Vinum
to a server configuration after
it is already in production use, but this is much harder than
designing for it from the start. Ironically,
Vinum is not supported by
/stand/sysinstall
and hence you cannot install
/usr right onto a
Vinum volume.Vinum currently does not
support the root file system (this feature
is in development).Hence it is a bit
tricky to get started using
Vinum, but these instructions
take you though the process of planning for
Vinum, installing FreeBSD
without it, and then beginning to use it.I have come to call this whole process "bootstrapping Vinum."
That is, the process of getting Vinum
initially installed
and operating to the point where you have met your resilience
or performance goals. My purpose here is to document a
Vinum
bootstrapping method that I have found that works well for me.Vinum BenefitsThe server foundation scenario I have chosen here allows me
to show you examples of configuring for resilience on
/usr and
/home.
Yet Vinum
provides benefits other than resilience--namely
performance, capacity, and manageability.
It can significantly improve disk performance (especially
under multi-user loads).
Vinum
can easily concatenate many smaller disks to produce the
illusion of a single larger disk (but my server foundation
scenario does not allow me to illustrate these benefits here).For servers with many spindles, Vinum
provides substantial
benefits in volume management, particularly when coupled with
hot-pluggable hardware. Data can be moved from spindle to
spindle while the system is running without loss of production
time. Again, details of this will not be given here, but once
you get your feet wet with Vinum,
other documentation will help you do things like this.
See
"The Vinum
Volume Manager" for a technical introduction to
Vinum,
&man.vinum.8; for a description of the vinum
command, and
&man.vinum.4;
for a description of the vinum device
driver and the way Vinum
objects are named.Breaking up your disk space into smaller and smaller partitions
has the benefit of allowing you to "tune" for the most common
type of access and tends to keep disk hogs "within their pens."
However it also causes some loss in total available disk space
due to fragmentation.Server Operation in Degraded ModeSome disk failures in this two-spindle scenario will result in
Vinum
automatically routing
all disk I/O to the remaining good spindle.
Others will require brief manual intervention on the console
to configure the server for degraded mode operation and a quick reboot.
Other than actual hardware repairs, most recovery work
can be done while the server is running in multi-user degraded
mode so there is as little production impact
from failures as possible.I give the instructions in needed to
configure the server for degraded mode operation
in those cases where Vinum
cannot do it automatically.
I also give the instructions needed to
return to normal operation once the failed hardware is repaired.
You might call these instructions Vinum
failure recovery techniques.I recommend practicing using these instructions
by recovering from simulated failures.
For each failure scenario, I also give tips below for simulating
a failure even when your hardware is working well.
Even a minimum Vinum
system as described in
below can be a good place to experiment with
recovery techniques without impacting production equipment.Hardware RAID vs. Vinum (Software RAID)Manual intervention is sometimes required to configure a server for
degraded mode because
Vinum
is implemented in software that runs after the FreeBSD
kernel is loaded. One disadvantage of such
software RAID
solutions is that there is nothing that can be done to hide spindle
failures from the BIOS or the FreeBSD boot sequence. Hence
the manual reconfiguration of the server
for degraded operation mentioned
above just informs the BIOS and boot sequence of failed
spindles.
Hardware RAID solutions generally have an
advantage in that they require no such reconfiguration since
spindle failures are hidden from the BIOS and boot sequence.Hardware RAID, however, may have some disadvantages that can
be significant in some cases:
The hardware RAID controller itself may become a single
point of failure for the system.
The data is usually kept in a proprietary
format so that a disk drive cannot be simply plugged
into another main board and booted.
You often cannot mix and
match drives with different sizes and interfaces.
You are often limited to the number of drives supported by the
hardware RAID controller (often only four or eight).
In other words, &vinum.ap; may offer advantages in that
there is no single point of failure,
the drives can boot on most any main board, and
you are free to mix and match as many drives using
whatever interface you choose.Keep your kernel fairly generic (or at least keep
/kernel.GENERIC around).
This will improve the chances that you can come back up on
"foreign" hardware more quickly.The pros and cons discussed above suggest
that the root file system and swap partition are good
candidates for hardware RAID if available.
This is especially true for servers where it is difficult for
administrators to get console access (recall that this is sometimes
required to configure a server for degraded mode operation).
A server with only software RAID is well suited to office and home
environments where an administrator can be close at hand.A common myth is that hardware RAID is always faster
than software RAID.
Since it runs on the host CPU, Vinum
often has more CPU power and memory available than a
dedicated RAID controller would have.
If performance is a prime concern, it is best to benchmark
your application running on your CPU with your spindles using
both hardware and software RAID systems before making
a decision.Hardware for VinumThese instructions may be timely since commodity PC hardware
can now easily host several hundred megabytes of reasonably
high-performance disk space at a low price. Many disk
drive manufactures now sell 7,200 RPM disk drives with quite
low seek times and high transfer rates through ATA-100
interfaces, all at very attractive prices. Four such drives,
attached to a suitable main board and configured with
Vinum
and prudent partitioning, yields a failure-resilient, high
performance disk server at a very reasonable cost.However, you can indeed get started with
Vinum very simply.
A minimum system can be as simple as
an old CPU (even a 486 is fine) and a pair of drives
that are 500 MB or more. They need not be the same size or
even use the same interface (i.e., it is fine to mix ATAPI and
SCSI). So get busy and give this a try today! You will have
the foundation of a failure-resilient server running in an
hour or so!Bootstrapping PhasesGreg Lehey suggested this bootstrapping method.
It uses knowledge of how Vinum
internally allocates disk space to avoid copying data.
Instead, Vinum
objects are configured so that they occupy the
same disk space where /stand/sysinstall built
file systems.
The file systems are thus embedded within
Vinum objects without copying.There are several distinct phases to the
Vinum bootstrapping
procedure. Each of these phases is presented in a separate section below.
The section starts with a general overview of the phase and its goals.
It then gives example steps for the two-spindle scenario
presented here and advice on how to adapt them for your server.
(If you are reading for a general understanding
of Vinum
bootstrapping, the example sections for each phase
can safely be skipped.)
The remainder of this section gives
an overview of the entire bootstrapping process.Phase 1 involves planning and preparation.
We will balance requirements
for the server against available resources and make design
tradeoffs.
We will plan the transition from no
Vinum to
Vinum
on just one spindle, to Vinum
on two spindles.In phase 2, we will install a minimum FreeBSD system on a
single spindle using partitions of type
4.2BSD (regular UFS file systems).Phase 3 will embed the non-root file systems from phase 2 in
Vinum objects.
Note that Vinum will be up and
running at this point,
but it cannot yet provide any resilience since it only has
one spindle on which to store data.Finally in phase 4, we configure Vinum
on a second spindle and make a backup copy of the root file system.
This will give us resilience on all file systems.Bootstrapping Phase 1: Planning and PreparationOur goal in this phase is to define the different partitions
we will need and examine their requirements.
We will also look at available disk drives and controllers and allocate
partitions to them.
Finally, we will determine the size of
each partition and its use during the bootstrapping process.
After this planning is complete, we can optionally prepare to use some
tools that will make bootstrapping Vinum
easier.Several key questions must be answered in this
planning phase:
What file system and partitions will be needed?
How will they be used?
How will we name each spindle?
How will the partitions be ordered for each spindle?
How will partitions be assigned to the spindles?
How will partitions be configured? Resilience or performance?
What technique will be used to achieve resilience?
What spindles will be used?
How will they be configured on the available controllers?
How much space is required for each partition?
Phase 1 ExampleIn this example, I will assume a scenario
where we are building
a minimal foundation for a failure-resilient server.
Hence we will need at least root,
/usr,
/home,
and swap partitions.
The root,
/usr, and
/home file systems all need resilience since the
server will not be much good without them.
The swap partition needs performance first and
generally does
not need resilience since nothing it holds needs to be retained
across a reboot.Spindle NamingThe kernel would refer to the master spindle on
the primary and secondary ATA controllers as
/dev/ad0 and
/dev/ad2 respectively.
This assumes that you have not removed the line
options ATA_STATIC_ID
from your kernel configuration.
But Vinum
also needs to have a name for each spindle
that will stay the same name regardless
of how it is attached to the CPU (i.e., if the drive moves, the
Vinum name moves with the drive).Some recovery techniques documented below suggest
moving a spindle from
the secondary ATA controller to the primary ATA controller.
(Indeed, the flexibility of making such moves is a key benefit
of Vinum
especially if you are managing a large number of spindles.)
After such a drive/controller swap,
the kernel will see what used to be
/dev/ad2 as
/dev/ad0
but Vinum
will still call
it by whatever name it had when it was attached to
/dev/ad2
(i.e., when it was "created" or first made known to
Vinum).Since connections can change, it is best to give
each spindle a unique, abstract
name that gives no hint of how it is attached.
Avoid names that suggest a manufacturer, model number,
physical location, or membership in a sequence
(e.g. avoid names like
upper, lower, etc.,
alpha, beta, etc.,
SCSI1, SCSI2, etc., or
Seagate1, Seagate2 etc.).
Such names are likely to lose their uniqueness or
get out of sequence
someday even if they seem like great names today.Once you have picked names for your spindles,
label them with a permanent marker.
If you have hot-swappable hardware, write the names on the sleds
in which the spindles are mounted.
This will significantly reduce the likelihood of
error when you are moving spindles around later as
part of failure recovery or routine system management
procedures.In the instructions that follow,
Vinum
will name the root spindle YouCrazy
and the rootback spindle UpWindow.
I will only use /dev/ad0
when I want to refer to whichever
of the two spindles is currently attached as
/dev/ad0.Partition OrderingModern disk drives operate with fairly uniform areal
density across the surface of the disk.
That implies that more data is available under the heads without
seeking on the outer cylinders than on the inner cylinders.
We will allocate partitions most critical to system performance
from these outer cylinders as
/stand/sysinstall generally does.The root file system is traditionally the outermost, even though
it generally is not as critical to system performance as others.
(However root can have a larger impact on performance if it contains
/tmp and /var as it
does in this example.)
The FreeBSD boot loaders assume that the
root file system lives in the a partition.
There is no requirement that the a
partition start on the outermost cylinders, but this
convention makes it easier to manage disk labels.Swap performance is critical so it comes next on our way toward
the center.
I/O operations here tend to be large and contiguous.
Having as much data under the heads as possible avoids seeking
while swapping.With all the smaller partitions out of the way, we finish
up the disk with
/home and
/usr.
Access patterns here tend not to be as intense as for other
file systems (especially if there is an abundant supply of RAM
and read cache hit rates are high).If the pair of spindles you have are large enough to allow
for more than
/home and
/usr,
it is fine to plan for additional file systems here.Assigning Partitions to SpindlesWe will want to assign
partitions to these spindles so that either can fail
without loss of data on file systems configured for
resilience.Reliability on
/usr and
/home
is best achieved using Vinum
mirroring.
Resilience will have to come differently, however, for the root
file system since Vinum
is not a part of the FreeBSD boot sequence.
Here we will have to settle for two identical
partitions with a periodic copy from the primary to the
backup secondary.The kernel already has support for interleaved swap across
all available partitions so there is no need for help from
Vinum here.
/stand/sysinstall
will automatically configure /etc/fstab
for all swap partitions given.The &vinum.ap; bootstrapping method given below
requires a pair of spindles that I will call the
root spindle and the
rootback spindle.The rootback spindle must be the same size or
larger than the root spindle.These instructions first allocate all space on the root
spindle and then allocate exactly that amount of space on
a rootback spindle.
(After &vinum.ap; is bootstrapped, there is nothing special
about either of these spindles--they are interchangeable.)
You can later use the remaining space on the rootback spindle for
other file systems.If you have more than two spindles, the
bootvinum Perl script and the procedure
below will help you initialize them for use with &vinum.ap;.
However you will have to figure out how to assign partitions
to them on your own.Assigning Space to PartitionsFor this example, I will use two spindles: one with
4,124,673 blocks (about 2 GB) on /dev/ad0
and one with 8,420,769 blocks (about 4 GB) on
/dev/ad2.It is best to configure your two spindles on separate
controllers so that both can operate in parallel and
so that you will have failure resilience in case a
controller dies.
Note that mirrored volume write performance will be halved
in cases where both spindles share a controller that requires
they operate serially (as is often the case with ATA controllers).
One spindle will be the master on the primary ATA
controller and the other will be the master on the
secondary ATA controller.Recall that we will be allocating space on the smaller
spindle first and the larger spindle second.Assigning Partitions on the Root SpindleWe will allocate 200,000 blocks (about 93 MB)
for a root file system on each spindle
(/dev/ad0s1a and
/dev/ad2s1a).
We will initially allocate 200,265 blocks for a swap partition
on each spindle,
giving a total of about 186 MB of
swap space (/dev/ad0s1b and
/dev/ad2s1b).We will lose 265 blocks from each swap partition
as part of the bootstrapping process.
This is the size of the space used by
Vinum to store configuration
information.
The space will be taken from swap and given to a vinum
partition but will be unavailable for
Vinum subdisks.I have done the partition allocation in nice round
numbers of blocks just to emphasize where the 265 blocks go.
There is nothing wrong with allocating space in MB if that is
more convenient for you.This leaves 4,124,673 - 200,000 - 200,265 = 3,724,408 blocks
(about 1,818 MB) on the root spindle for
Vinum
partitions (/dev/ad0s1e and
/dev/ad2s1f).
From this, allocate the 265 blocks for
Vinum configuration information,
1,000,000 blocks (about 488 MB)
for /home, and the remaining
2,724,408 blocks (about 1,330 MB) for
/usr.
See below to see this graphically.The left-hand side of
below shows what spindle ad0 will
look like at the end of phase 2.
The right-hand side shows what it will look like at the
end of phase 3.Spindle ad0 Before and After Vinum ad0 Before Vinum Offset (blocks) ad0 After Vinum
+----------------------+ <-- 0--> +----------------------+
| root | | root |
| /dev/ad0s1a | | /dev/ad0s1a |
+----------------------+ <-- 200000--> +----------------------+
| swap | | swap |
| /dev/ad0s1b | | /dev/ad0s1b |
| | 400000--> +----------------------+
| | | Vinum drive YouCrazy |
| | | /dev/ad0s1h |
+----------------------+ <-- 400265--> +-----------------+ |
| /home | | Vinum sd | |
| /dev/ad0s1e | | home.p0.s0 | |
+----------------------+ <--1400265--> +-----------------+ |
| /usr | | Vinum sd | |
| /dev/ad0s1f | | usr.p0.s0 | |
+----------------------+ <--4124673--> +-----------------+----+
Not to scaleSpindle /dev/ad0 Before and After VinumAssigning Partitions on the Rootback SpindleThe /rootback and swap partition sizes
on the rootback spindle must
match the root and swap partition sizes on the root spindle.
That leaves 8,420,769 - 200,000 - 200,265 = 8,020,504
blocks for the Vinum partition.
Mirrors of /home and
/usr receive the same allocation as on
the root spindle.
That will leave an extra 2 GB or so that we can deal
with later.
See below to see this graphically.The left-hand side of
below shows what spindle ad2 will
look like at the beginning of phase 4.
The right-hand side shows what it will look like at the end.Spindle ad2 Before and After Vinum ad2 Before Vinum Offset (blocks) ad2 After Vinum
+----------------------+ <-- 0--> +----------------------+
| /rootback | | /rootback |
| /dev/ad2s1e | | /dev/ad2s1a |
+----------------------+ <-- 200000--> +----------------------+
| swap | | swap |
| /dev/ad2s1b | | /dev/ad2s1b |
| | 400000--> +----------------------+
| | | Vinum drive UpWindow |
| | | /dev/ad2s1h |
+----------------------+ <-- 400265--> +-----------------+ |
| /NOFUTURE | | Vinum sd | |
| /dev/ad2s1f | | home.p1.s0 | |
| | 1400265--> +-----------------+ |
| | | Vinum sd | |
| | | usr.p1.s0 | |
| | 4124673--> +-----------------+ |
| | | Vinum sd | |
| | | hope.p0.s0 | |
+----------------------+ <--8420769--> +-----------------+----+
Not to scaleSpindle ad2 Before and After VinumPreparation of ToolsThe bootvinum Perl script given below in
will make the
Vinum bootstrapping process much
easier if you can run it on the machine being bootstrapped.
It is over 200 lines and you would not want to type it in.
At this point, I recommend that you
copy it to a floppy or arrange some
alternative method of making it readily available
so that it can be available later when needed.
For example:&prompt.root; fdformat -f 1440 /dev/fd0
&prompt.root; newfs_msdos -f 1440 /dev/fd0
&prompt.root; mount /dev/fd0 /mnt
&prompt.root; cp /usr/share/examples/vinum/bootvinum /mntXXX Someday, I would like this script to live in
/usr/share/examples/vinum.
Till then, please use this
link
to get a copy.Bootstrapping Phase 2: Minimal OS InstallationOur goal in this phase is to complete the smallest possible
FreeBSD installation in such a way that we can later install
Vinum.
We will use only
partitions of type 4.2BSD (i.e., regular UFS file
systems) since that is the only type supported by
/stand/sysinstall.Phase 2 ExampleStart up the FreeBSD installation process by running
/stand/sysinstall from
installation media as you normally would.Fdisk partition all spindles as needed.Make sure to select BootMgr for all spindles.Partition the root spindle with appropriate block
allocations as described above in .
For this example on a 2 GB spindle, I will use
200,000 blocks for root, 200,265 blocks for swap,
1,000,000 blocks for /home, and
the rest of the spindle (2,724,408 blocks) for
/usr.
(/stand/sysinstall
should automatically assign these to
/dev/ad0s1a,
/dev/ad0s1b,
/dev/ad0s1e, and
/dev/ad0s1f
by default.)If you prefer soft updates as I do and you are
using 4.4-RELEASE or better, this is a good time to enable
them.Partition the rootback spindle with the appropriate block
allocations as described above in .
For this example on a 4 GB spindle, I will use
200,000 blocks for /rootback,
200,265 blocks for swap, and
the rest of the spindle (8,020,504 blocks) for
/NOFUTURE.
(/stand/sysinstall
should automatically assign these to
/dev/ad2s1e,
/dev/ad2s1b, and
/dev/ad2s1f by default.)We do not really want to have a
/NOFUTURE UFS file system (we
want a vinum partition instead), but that is the
best choice we have for the space given the limitations of
/stand/sysinstall.
Mount point names beginning with NOFUTURE
and rootback
serve as sentinels to the bootstrapping
script presented in below.Partition any other spindles with swap if desired and a
single /NOFUTURExx file system.Select a minimum system install for now even if you
want to end up with more distributions loaded later.Do not worry about system configuration options at this
point--get Vinum
set up and get the partitions in
the right places first.Exit /stand/sysinstall and reboot.
Do a quick test to verify that the minimum
installation was successful.The left-hand side of above
and the left-hand side of above
show how the disks will look at this point.Bootstrapping Phase 3: Root Spindle SetupOur goal in this phase is get Vinum
set up and running on the
root spindle.
We will embed the existing
/usr and
/home file systems in a
Vinum partition.
Note that the Vinum
volumes created will not yet be
failure-resilient since we have
only one underlying Vinum
drive to hold them.
The resulting system will automatically start
Vinum as it boots to multi-user mode.Phase 3 ExampleLogin as root.We will need a directory in the root file system in
which to keep a few files that will be used in the
Vinum
bootstrapping process.&prompt.root; mkdir /bootvinum
&prompt.root; cd /bootvinumSeveral files need to be prepared for use in bootstrapping.
I have written a Perl script that makes all the required
files for you.
Copy this script to /bootvinum by
floppy disk, tape, network, or any convenient means and
then run it.
(If you cannot get this script copied onto the machine being
bootstrapped, then see
below for a manual alternative.)&prompt.root; cp /mnt/bootvinum .
&prompt.root; ./bootvinumbootvinum produces no output
when run successfully.
If you get any errors,
something may have gone wrong when you were creating
partitions with
/stand/sysinstall above.Running bootvinum will:
Create /etc/fstab.vinum
based on what it finds
in your existing /etc/fstab
Create new disk labels for each spindle mentioned
in /etc/fstab and keep copies of the
current disk labels
Create files needed as input to vinum
for building
Vinum objects on each spindle
Create many alternates to /etc/fstab.vinum
that might come in handy should a spindle fail
You may want to take a look at these files to learn more
about the disk partitioning required for
Vinum or to learn more about the
commands needed to create
Vinum objects.We now need to install new spindle partitioning for
/dev/ad0.
This requires that
/dev/ad0s1b not be in use for
swapping so we have to reboot in single-user mode.First, reboot the system.&prompt.root; rebootNext, enter single-user mode.Hit [Enter] to boot immediately, or any other key for command prompt.
Booting [kernel] in 8 seconds...
Type '?' for a list of commands, 'help' for more detailed help.
ok boot -sIn single-user mode, install the new partitioning
created above.&prompt.root; cd /bootvinum
&prompt.root; disklabel -R ad0s1 disklabel.ad0s1
&prompt.root; disklabel -R ad2s1 disklabel.ad2s1
- If you have additional spindles, repeate the
+ If you have additional spindles, repeat the
above commands as appropriate for them.We are about to start Vinum
for the first time.
It is going to want to create several device nodes under
/dev/vinum so we will need to mount the
root file system for read/write access.&prompt.root; fsck -p /
&prompt.root; mount /Now it is time to create the Vinum
objects that
will embed the existing non-root file systems on
the root spindle in a
Vinum partition.
This will load the Vinum
kernel module and start Vinum
as a side effect.&prompt.root; vinum create create.YouCrazy
You should see a list of Vinum
objects created that looks like the following:1 drives:
D YouCrazy State: up Device /dev/ad0s1h Avail: 0/1818 MB (0%)
2 volumes:
V home State: up Plexes: 1 Size: 488 MB
V usr State: up Plexes: 1 Size: 1330 MB
2 plexes:
P home.p0 C State: up Subdisks: 1 Size: 488 MB
P usr.p0 C State: up Subdisks: 1 Size: 1330 MB
2 subdisks:
S home.p0.s0 State: up PO: 0 B Size: 488 MB
S usr.p0.s0 State: up PO: 0 B Size: 1330 MB
You should also see several kernel messages
which state that the Vinum
objects you have created are now up.Our non-root file systems should now be embedded in a
Vinum partition and
hence available through Vinum
volumes.
It is important to test that this embedding worked.&prompt.root; fsck -n /dev/vinum/home
&prompt.root; fsck -n /dev/vinum/usrThis should produce no errors.
If it does produce errors do not fix them.
Instead, go back and examine the root spindle partition tables
before and after Vinum
to see if you can spot the error.
You can back out the partition table changes by using
disklabel -R with the
disklabel.*.b4vinum files.While we have the root file system mounted read/write, this is
a good time to install /etc/fstab.&prompt.root; mv /etc/fstab /etc/fstab.b4vinum
&prompt.root; cp /etc/fstab.vinum /etc/fstabWe are now done with tasks requiring single-user
mode, so it is safe to go multi-user from here on.&prompt.root; ^DLogin as root.Edit /etc/rc.conf and add this line:
start_vinum="YES"Bootstrapping Phase 4: Rootback Spindle SetupOur goal in this phase is to get redundant copies of all data
from the root spindle to the rootback spindle.
We will first create the necessary Vinum
objects on the rootback spindle.
Then we will ask Vinum
to copy the data from the root spindle to the
rootback spindle.
Finally, we use dump and restore
to copy the root file system.Phase 4 ExampleNow that Vinum
is running on the root spindle, we can bring
it up on the rootback spindle so that our
Vinum volumes can become
failure-resilient.&prompt.root; cd /bootvinum
&prompt.root; vinum create create.UpWindowYou should see a list of Vinum
objects created that
looks like the following:2 drives:
D YouCrazy State: up Device /dev/ad0s1h Avail: 0/1818 MB (0%)
D UpWindow State: up Device /dev/ad2s1h Avail: 2096/3915 MB (53%)
2 volumes:
V home State: up Plexes: 2 Size: 488 MB
V usr State: up Plexes: 2 Size: 1330 MB
4 plexes:
P home.p0 C State: up Subdisks: 1 Size: 488 MB
P usr.p0 C State: up Subdisks: 1 Size: 1330 MB
P home.p1 C State: faulty Subdisks: 1 Size: 488 MB
P usr.p1 C State: faulty Subdisks: 1 Size: 1330 MB
4 subdisks:
S home.p0.s0 State: up PO: 0 B Size: 488 MB
S usr.p0.s0 State: up PO: 0 B Size: 1330 MB
S home.p1.s0 State: stale PO: 0 B Size: 488 MB
S usr.p1.s0 State: stale PO: 0 B Size: 1330 MBYou should also see several kernel messages
which state that some of the Vinum
objects you have created are now up
while others are faulty or
stale.Now we ask Vinum
to copy each of the subdisks on drive
YouCrazy to drive UpWindow.
This will change the state of the newly created
Vinum subdisks
from stale to up.
It will also change the state of the newly created
Vinum plexes
from faulty to up.First, we do the new subdisk we
added to /home.&prompt.root; vinum start -w home.p1.s0
reviving home.p1.s0
(time passes . . . )
home.p1.s0 is up by force
home.p1 is up
home.p1.s0 is up
My 5,400 RPM EIDE spindles copied at about 3.5 MBytes/sec.
Your mileage may vary.
Next we do the new subdisk we
added to /usr.&prompt.root; vinum -w start usr.p1.s0
reviving usr.p1.s0
(time passes . . . )
usr.p1.s0 is up by force
usr.p1 is up
usr.p1.s0 is upAll Vinum
objects should be in state up at this point.
The output of
vinum list should look
like the following:2 drives:
D YouCrazy State: up Device /dev/ad0s1h Avail: 0/1818 MB (0%)
D UpWindow State: up Device /dev/ad2s1h Avail: 2096/3915 MB (53%)
2 volumes:
V home State: up Plexes: 2 Size: 488 MB
V usr State: up Plexes: 2 Size: 1330 MB
4 plexes:
P home.p0 C State: up Subdisks: 1 Size: 488 MB
P usr.p0 C State: up Subdisks: 1 Size: 1330 MB
P home.p1 C State: up Subdisks: 1 Size: 488 MB
P usr.p1 C State: up Subdisks: 1 Size: 1330 MB
4 subdisks:
S home.p0.s0 State: up PO: 0 B Size: 488 MB
S usr.p0.s0 State: up PO: 0 B Size: 1330 MB
S home.p1.s0 State: up PO: 0 B Size: 488 MB
S usr.p1.s0 State: up PO: 0 B Size: 1330 MBCopy the root file system so that you will have a backup.&prompt.root; cd /rootback
&prompt.root; dump 0f - / | restore rf -
&prompt.root; rm restoresymtable
&prompt.root; cd /You may see errors like this:./tmp/rstdir1001216411: (inode 558) not found on tape
cannot find directory inode 265
abort? [yn] n
expected next file 492, got 491They seem to cause no harm.
I suspect they are a consequence of dumping the file system
containing /tmp and/or the pipe
connecting dump and
restore.Make a directory on which we can mount a damaged root
file system during the recovery process.&prompt.root; mkdir /rootbadRemove sentinel mount points that are now unused.&prompt.root; rmdir /NOFUTURE*Create empty &vinum.ap; drives on remaining spindles.&prompt.root; vinum create create.ThruBank
&prompt.root; ...At this point, the reliable server foundation is complete.
The right-hand side of above
and the right-hand side of above
show how the disks will look.You may want to do a quick reboot to multi-user and give it
a quick test drive.
This is also a good point to complete installation
of other distributions beyond the minimal install.
Add packages, ports, and users as required.
Configure /etc/rc.conf as required.After you have completed your server configuration,
remember to do one more copy of root to
/rootback as shown above before placing
the server into production.Make a schedule to refresh
/rootback periodically.It may be a good idea to mount
/rootback read-only for normal operation
of the server.
This does, however, complicate the periodic refresh a bit.Do not forget to watch
/var/log/messages carefully for errors.
Vinum
may automatically avoid failed hardware in a way that users
do not notice.
You must watch for such failures and get them repaired before a
second failure results in data loss.
You may see
Vinum noting damaged objects
at server boot time.Where to Go from Here?Now that you have established the foundation of a reliable server,
there are several things you might want to try next.Make a Vinum Volume with Remaining SpaceFollowing are the steps to create another
Vinum volume with space remaining
on the rootback spindle.This volume will not be resilient to spindle failure
since it has only one plex on a single spindle.Create a file with the following contents:volume hope
plex name hope.p0 org concat volume hope
sd name hope.p0.s0 drive UpWindow plex hope.p0 len 0Specifying a length of 0 for
the hope.p0.s0 subdisk
asks Vinum
to use whatever space is left available on the underlying
drive.Feed these commands into vinum .&prompt.root; vinum create filenameNow we newfs the volume and
mount it.&prompt.root; newfs -v /dev/vinum/hope
&prompt.root; mkdir /hope
&prompt.root; mount /dev/vinum/hope /hopeEdit /etc/fstab if you want
/hope mounted at boot time.Try Out More Vinum CommandsYou might already be familiar with
vinum to get a list of
all Vinum objects.
Try following it to see more detail.If you have more spindles and you want to bring them up as
concatenated, mirrored, or striped volumes, then give
vinumdrivelist,
vinumdrivelist, or
vinumdrivelist a try.See &man.vinum.8; for sample configurations and important
performance considerations before settling on a final organization
for your additional spindles.The failure recovery instructions below will also give you
some experience using more Vinum
commands.Failure ScenariosThis section contains descriptions of various failure scenarios.
For each scenario, there is a subsection on how to configure your
server for degraded mode operation, how to recover from the failure,
how to exit degraded mode, and how to simulate the failure.Make a hard copy of these instructions and leave them inside the CPU
case, being careful not to interfere with ventilation.Root file system on ad0 unusable, rest of drive okWe assume here that the boot blocks and disk label on
/dev/ad0 are ok.
If your BIOS can boot from a drive other than
C:, you may be able to get around this
limitation.Configure Server for Degraded ModeUse BootMgr to load kernel from
/dev/ad2s1a.Hit F5 in BootMgr to select
Drive 1.Hit F1 to select
FreeBSD.After the kernel is loaded, hit any key but enter to interrupt
the boot sequence.
Boot into single-user mode and allow explicit entry of
a root file system.Hit [Enter] to boot immediately, or any other key for command prompt.
Booting [kernel] in 8 seconds...
Type '?' for a list of commands, 'help' for more detailed help.
ok boot -asSelect /rootback
as your root file system.Manual root file system specification:
<fstype>:<device> Mount <device> using filesystem <fstype>
e.g. ufs:/dev/da0s1a
? List valid disk boot devices
<empty line> Abort manual input
mountroot> ufs:/dev/ad2s1aNow that you are in single-user mode, change
/etc/fstab to avoid the
bad root file system.If you used the bootvinum Perl script from
below, then these commands should configure your server for
degraded mode.&prompt.root; fsck -p /
&prompt.root; mount /
&prompt.root; cd /etc
&prompt.root; mv fstab fstab.bak
&prompt.root; cp fstab_ad0s1_root_bad fstab
&prompt.root; cd /
&prompt.root; mount -o ro /
&prompt.root; vinum start
&prompt.root; fsck -p
&prompt.root; ^DRecoveryRestore /dev/ad0s1a from
backups or copy
/rootback to it with these commands:&prompt.root; umount /rootbad
&prompt.root; newfs /dev/ad0s1a
&prompt.root; tunefs -n enable /dev/ad0s1a
&prompt.root; mount /rootbad
&prompt.root; cd /rootbad
&prompt.root; dump 0f - / | restore rf -
&prompt.root; rm restoresymtableExiting Degraded ModeEnter single-user mode.&prompt.root; shutdown nowPut /etc/fstab back to
normal and reboot.&prompt.root; cd /rootbad/etc
&prompt.root; rm fstab
&prompt.root; mv fstab.bak fstab
&prompt.root; rebootReboot and hit F1 to boot from
/dev/ad0 when
prompted by BootMgr.SimulationThis kind of failure can be simulated by shutting down to
single-user mode and then booting as shown above in
.Drive ad2 FailsThis section deals with the total failure of
/dev/ad2.Configure Server for Degraded ModeAfter the kernel is loaded, hit any key but
Enter to interrupt the boot sequence.
Boot into single-user mode.Hit [Enter] to boot immediately, or any other key for command prompt.
Booting [kernel] in 8 seconds...
Type '?' for a list of commands, 'help' for more detailed help.
ok boot -sChange
/etc/fstab to avoid the bad drive.
If you used the bootvinum Perl script from
below, then
these commands should configure your server for
degraded mode.&prompt.root; fsck -p /
&prompt.root; mount /
&prompt.root; cd /etc
&prompt.root; mv fstab fstab.bak
&prompt.root; cp fstab_only_have_ad0s1 fstab
&prompt.root; cd /
&prompt.root; mount -o ro /
&prompt.root; vinum start
&prompt.root; fsck -p
&prompt.root; ^DIf you do not have modified versions of
/etc/fstab that are ready for use,
then you can use ed to make one.
Alternatively, you can fsck and
mount/usr and then use your
favorite editor.RecoveryWe assume here that your server is up and running multi-user in
degraded mode on just
/dev/ad0 and that you have
a new spindle now on
/dev/ad2 ready to go.You will need a new spindle with enough room to hold root and swap
partitions plus a Vinum
partition large enough to hold
/home and /usr.Create a BIOS partition (slice) on the new spindle.&prompt.root; /stand/sysinstallSelect Custom.Select Partition.Select ad2.Create a FreeBSD (type 165) slice
large enough to hold everything mentioned above.Write changes.Yes, you are absolutely sure.Select BootMgr.Quit Partitioning.Exit /stand/sysinstall.Create disk label partitioning based on current
/dev/ad0 partitioning.&prompt.root; disklabel ad0 > /tmp/ad0
&prompt.root; disklabel -e ad2This will drop you into your favorite editor.Copy the lines for the a and
b partitions from
/tmp/ad0 to the
ad2 disklabel.Add the size of the
a and
b partitions to find the proper
offset for the
h partition.Subtract this offset from the
size of the c
partition to find the proper size for the h
partition.Define an h partition with the
size and
offset calculated above.Set the fstype column to
vinum.Save the file and quit your editor.Tell Vinum
about the new drive.Ask Vinum to start an
editor with a copy of the current configuration.&prompt.root; vinum createUncomment the drive line referring to drive
UpWindow and set
device to
/dev/ad2s1h.Save the file and quit your editor.Now that Vinum
has two spindles again, revive the mirrors.&prompt.root; vinum start -w usr.p1.s0
&prompt.root; vinum start -w home.p1.s0Now we need to restore
/rootback to a current copy of the
root file system.
These commands will accomplish this.&prompt.root; newfs /dev/ad2s1a
&prompt.root; tunefs -n enable /dev/ad2s1a
&prompt.root; mount /dev/ad2s1a /mnt
&prompt.root; cd /mnt
&prompt.root; dump 0f - / | restore rf -
&prompt.root; rm restoresymtable
&prompt.root; cd /
&prompt.root; umount /mntExiting Degraded ModeEnter single-user mode.&prompt.root; shutdown nowReturn /etc/fstab to
its normal state and reboot.&prompt.root; cd /etc
&prompt.root; rm fstab
&prompt.root; mv fstab.bak fstab
&prompt.root; rebootSimulationYou can simulate this kind of failure by unplugging
/dev/ad2, write-protecting it,
or by this procedure:Shutdown to single-user mode.Unmount all non-root file systems.Clobber any existing Vinum
configuration and partitioning on
/dev/ad2.&prompt.root; vinum stop
&prompt.root; dd if=/dev/zero of=/dev/ad2s1h count=512
&prompt.root; dd if=/dev/zero of=/dev/ad2 count=512Drive ad0 FailsSome BIOSes can boot from drive 1 or drive 2 (often called
C: or D:),
while others can boot only from drive 1.
If your BIOS can boot from either, the fastest road to recovery
might be to boot directly from /dev/ad2
in single-user mode and
install /etc/fsatb_only_have_ad2s1 as
/etc/fstab.
You would then have to adapt the /dev/ad2
failure recovery instructions from above.If your BIOS can only boot from drive one, then you will have to
unplug drive YouCrazy from the controller for
/dev/ad2 and plug it
into the controller for /dev/ad0.
Then continue with the instructions for
/dev/ad2 failure recovery
in above.bootvinum Perl ScriptThe bootvinum Perl script below reads /etc/fstab
and current drive partitioning.
It then writes several files in the current directory and several
variants of /etc/fstab in /etc.
These files significantly simplify the installation of
Vinum and recovery from
spindle failures.#!/usr/bin/perl -w
use strict;
use FileHandle;
-my $config_tag1 = '$Id: article.sgml,v 1.2 2001-10-29 23:20:40 chern Exp $';
+my $config_tag1 = '$Id: article.sgml,v 1.3 2001-10-31 23:10:31 chern Exp $';
# Copyright (C) 2001 Robert A. Van Valzah
#
# Bootstrap Vinum
#
# Read /etc/fstab and current partitioning for all spindles mentioned there.
# Generate files needed to mirror all file systems on root spindle.
# A new partition table for each spindle
# Input for the vinum create command to create Vinum objects on each spindle
# A copy of fstab mounting Vinum volumes instead of BSD partitions
# Copies of fstab altered for server's degraded modes of operation
# See handbook for instructions on how to use the the files generated.
# N.B. This bootstrapping method shrinks size of swap partition by the size
# of Vinum's on-disk configuration (265 sectors). It embeds existing file
# systems on the root spindle in Vinum objects without having to copy them.
# Thanks to Greg Lehey for suggesting this bootstrapping method.
# Expectations:
# The root spindle must contain at least root, swap, and /usr partitions
# The rootback spindle must have matching /rootback and swap partitions
# Other spindles should only have a /NOFUTURE* file system and maybe swap
# File systems named /NOFUTURE* will be replaced with Vinum drives
# Change configuration variables below to suit your taste
my $vip = 'h'; # VInum Partition
my @drv = ('YouCrazy', 'UpWindow', 'ThruBank', # Vinum DRiVe names
'OutSnakes', 'MeWild', 'InMovie', 'HomeJames', 'DownPrices', 'WhileBlind');
# No configuration variables beyond this point
my %vols; # One entry per Vinum volume to be created
my @spndl; # One entry per SPiNDLe
my $rsp; # Root SPindle (as in /dev/$rsp)
my $rbsp; # RootBack SPindle (as in /dev/$rbsp)
my $cfgsiz = 265; # Size of Vinum on-disk configuration info in sectors
my $nxtpas = 2; # Next fsck pass number for non-root file systems
# Parse fstab, generating the version we'll need for Vinum and noting
# spindles in use.
my $fsin = "/etc/fstab";
#my $fsin = "simu/fstab";
open(FSIN, "$fsin") || die("Couldn't open $fsin: $!\n");
my $fsout = "/etc/fstab.vinum";
open(FSOUT, ">$fsout") || die("Couldn't open $fsout for writing: $!\n");
while (<FSIN>) {
my ($dev, $mnt, $fstyp, $opt, $dump, $pass) = split;
next if $dev =~ /^#/;
if ($mnt eq '/' || $mnt eq '/rootback' || $mnt =~ /^\/NOFUTURE/) {
my $dn = substr($dev, 5, length($dev)-6); # Device Name without /dev/
push(@spndl, $dn) unless grep($_ eq $dn, @spndl);
$rsp = $dn if $mnt eq '/';
next if $mnt =~ /^\/NOFUTURE/;
}
# Move /rootback from partition e to a
if ($mnt =~ /^\/rootback/) {
$dev =~ s/e$/a/;
$pass = 1;
$rbsp = substr($dev, 5, length($dev)-6);
print FSOUT "$dev\t\t$mnt\t$fstyp\t$opt\t\t$dump\t$pass\n";
next;
}
# Move non-root file systems on smallest spindle into Vinum
if (defined($rsp) && $dev =~ /^\/dev\/$rsp/ && $dev =~ /[d-h]$/) {
$pass = $nxtpas++;
print FSOUT "/dev/vinum$mnt\t\t$mnt\t\t$fstyp\t$opt\t\t$dump\t$pass\n";
$vols{$dev}->{mnt} = substr($mnt, 1);
next;
}
print FSOUT $_;
}
close(FSOUT);
die("Found more spindles than we have abstract names\n") if $#spndl > $#drv;
die("Didn't find a root partition!\n") if !defined($rsp);
die("Didn't find a /rootback partition!\n") if !defined($rbsp);
# Table of server's Degraded Modes
# One row per mode with hash keys
# fn FileName
# xpr eXPRession needed to convert fstab lines for this mode
# cm1 CoMment 1 describing this mode
# cm2 CoMment 2 describing this mode
# FH FileHandle (dynamically initialized below)
my @DM = (
{ cm1 => "When we only have $rsp, comment out lines using $rbsp",
fn => "/etc/fstab_only_have_$rsp",
xpr => "s:^/dev/$rbsp:#\$&:",
},
{ cm1 => "When we only have $rbsp, comment out lines using $rsp and",
cm2 => "rootback becomes root",
fn => "/etc/fstab_only_have_$rbsp",
xpr => "s:^/dev/$rsp:#\$&: || s:/rootback:/\t:",
},
{ cm1 => "When only $rsp root is bad, /rootback becomes root and",
cm2 => "root becomes /rootbad",
fn => "/etc/fstab_${rsp}_root_bad",
xpr => "s:\t/\t:\t/rootbad: || s:/rootback:/\t:",
},
);
# Initialize output FileHandles and write comments
foreach my $dm (@DM) {
my $fh = new FileHandle;
$fh->open(">$dm->{fn}") || die("Can't write $dm->{fn}: $!\n");
print $fh "# $dm->{cm1}\n" if $dm->{cm1};
print $fh "# $dm->{cm2}\n" if $dm->{cm2};
$dm->{FH} = $fh;
}
# Parse the Vinum version of fstab written above and write versions needed
# for server's degraded modes.
open(FSOUT, "$fsout") || die("Couldn't open $fsout: $!\n");
while (<FSOUT>) {
my $line = $_;
foreach my $dm (@DM) {
$_ = $line;
eval $dm->{xpr};
print {$dm->{FH}} $_;
}
}
# Parse partition table for each spindle and write versions needed for Vinum
my $rootsiz; # ROOT partition SIZe
my $swapsiz; # SWAP partition SIZe
my $rspminoff; # Root SPindle MINimum OFFset of non-root, non-swap, non-c parts
my $rspsiz; # Root SPindle SIZe
my $rbspsiz; # RootBack SPindle SIZe
foreach my $i (0..$#spndl) {
my $dlin = "disklabel $spndl[$i] |";
# my $dlin = "simu/disklabel.$spndl[$i]";
open(DLIN, "$dlin") || die("Couldn't open $dlin: $!\n");
my $dlout = "disklabel.$spndl[$i]";
open(DLOUT, ">$dlout") || die("Couldn't open $dlout for writing: $!\n");
my $dlb4 = "$dlout.b4vinum";
open(DLB4, ">$dlb4") || die("Couldn't open $dlb4 for writing: $!\n");
my $minoff; # MINimum OFFset of non-root, non-swap, non-c partitions
my $totsiz = 0; # TOTal SIZe of all non-root, non-swap, non-c partitions
my $swapspndl = 0; # True if SWAP partition on this SPiNDLe
while (<DLIN>) {
print DLB4 $_;
my ($part, $siz, $off, $fstyp, $fsiz, $bsiz, $bps) = split;
if ($part && $part eq 'a:' && $spndl[$i] eq $rsp) {
$rootsiz = $siz;
}
if ($part && $part eq 'e:' && $spndl[$i] eq $rbsp) {
if ($rootsiz != $siz) {
die("Rootback size ($siz) != root size ($rootsiz)\n");
}
}
if ($part && $part eq 'c:') {
$rspsiz = $siz if $spndl[$i] eq $rsp;
$rbspsiz = $siz if $spndl[$i] eq $rbsp;
}
# Make swap partition $cfgsiz sectors smaller
if ($part && $part eq 'b:') {
if ($spndl[$i] eq $rsp) {
$swapsiz = $siz;
} else {
if ($swapsiz != $siz) {
die("Swap partition sizes unequal across spindles\n");
}
}
printf DLOUT "%4s%9d%9d%10s\n", $part, $siz-$cfgsiz, $off, $fstyp;
$swapspndl = 1;
next;
}
# Move rootback spindle e partitions to a
if ($part && $part eq 'e:' && $spndl[$i] eq $rbsp) {
printf DLOUT "%4s%9d%9d%10s%9d%6d%6d\n", 'a:', $siz, $off, $fstyp,
$fsiz, $bsiz, $bps;
next;
}
# Delete non-root, non-swap, non-c partitions but note their minimum
# offset and total size that're needed below.
if ($part && $part =~ /^[d-h]:$/) {
$minoff = $off unless $minoff;
$minoff = $off if $off < $minoff;
$totsiz += $siz;
if ($spndl[$i] eq $rsp) { # If doing spindle containing root
my $dev = "/dev/$spndl[$i]" . substr($part, 0, 1);
$vols{$dev}->{siz} = $siz;
$vols{$dev}->{off} = $off;
$rspminoff = $minoff;
}
next;
}
print DLOUT $_;
}
if ($swapspndl) { # If there was a swap partition on this spindle
# Make a Vinum partition the size of all non-root, non-swap,
# non-c partitions + the size of Vinum's on-disk configuration.
# Set its offset so that the start of the first subdisk it contains
# coincides with the first file system we're embedding in Vinum.
printf DLOUT "%4s%9d%9d%10s\n", "$vip:", $totsiz+$cfgsiz, $minoff-$cfgsiz,
'vinum';
} else {
# No need to mess with size size and offset if there was no swap
printf DLOUT "%4s%9d%9d%10s\n", "$vip:", $totsiz, $minoff,
'vinum';
}
}
die("Swap partition not found\n") unless $swapsiz;
die("Swap partition not larger than $cfgsiz blocks\n") unless $swapsiz>$cfgsiz;
die("Rootback spindle size not >= root spindle size\n") unless $rbspsiz>=$rspsiz;
# Generate input to vinum create command needed for each spindle.
foreach my $i (0..$#spndl) {
my $cfn = "create.$drv[$i]"; # Create File Name
open(CF, ">$cfn") || die("Can't open $cfn for writing: $!\n");
print CF "drive $drv[$i] device /dev/$spndl[$i]$vip\n";
next unless $spndl[$i] eq $rsp || $spndl[$i] eq $rbsp;
foreach my $dev (keys(%vols)) {
my $mnt = $vols{$dev}->{mnt};
my $siz = $vols{$dev}->{siz};
my $off = $vols{$dev}->{off}-$rspminoff+$cfgsiz;
print CF "volume $mnt\n" if $spndl[$i] eq $rsp;
print CF <<EOF;
plex name $mnt.p$i org concat volume $mnt
sd name $mnt.p$i.s0 drive $drv[$i] plex $mnt.p$i len ${siz}s driveoffset ${off}s
EOF
}
}Manual Vinum BootstrappingThe bootvinum Perl script in makes life easier, but
it may be necessary to manually perform some or all of the steps that
it automates.
This appendix describes how you would manually mimic the script.Make a copy of /etc/fstab
to be customized.&prompt.root; cp /etc/fstab /etc/fstab.vinumEdit /etc/fstab.vinum.Change the device column of
non-root partitions on the root spindle to
/dev/vinum/mnt.Change the pass column of
non-root partitions on the root spindle to 2,
3, etc.Delete any lines with mountpoint
matching /NOFUTURE*.Change the device column of
/rootback
from e to
a.Change the pass column of
/rootback to
1.Prepare disklabels for editing:&prompt.root; cd /bootvinum
&prompt.root; disklabel ad0s1 > disklabel.ad0s1
&prompt.root; cp disklabel.ad0s1 disklabel.ad0s1.b4vinum
&prompt.root; disklabel ad2s1 > disklabel.ad2s1
&prompt.root; cp disklabel.ad2s1 disklabel.ad2s1.b4vinumEdit /etc/disklabel.ad?s1.On the root spindle:Decrease the size of the
b partition by 265 blocks.Note the size and
offset of the a and
b partitions.Note the smallest offset for partitions
d-h.Note the size and
offset for all non-root, non-swap
partitions (/home was probably on
e and /usr was
probably on f).Delete partitions
d-h.Create a new h partition with
offset 265 blocks less than the
smallest offset
for partitions d-h
noted above.
Set its size to the size
of the c partition less the
smallest offset
for partitions d-h
noted above + 265 blocks.Vinum
can use any partition other than c.
It is not strictly necessary to use h
for all your Vinum
partitions, but it is good practice to
be consistent across all spindles.Set the fstype of this new
partition to vinum.On the rootback spindle:Move the e partition to
a.Verify that the size of the
a and
b partitions matches the
root spindle.Note the smallest offset for partitions
d-h.Delete partitions
d-h.Create a new h partition with
offset 265 blocks less than the
smallest offset
noted above for partitions
d-h.
Set its size to the size
of the c partition less the
smallest offset
for partitions d-h
noted above + 265 blocks.Set the fstype of this new
partition to vinum.Create a file named
create.YouCrazy that contains:drive YouCrazy device /dev/ad0s1h
volume home
plex name home.p0 org concat volume home
sd name home.p0.s0 drive YouCrazy plex home.p0 len $hl driveoffset $ho
volume usr
plex name usr.p0 org concat volume usr
sd name usr.p0.s0 drive YouCrazy plex usr.p0 len $ul driveoffset $uoWhere:$hl is the length noted above for
/home.$ho is the offset noted above for
/home less the smallest offset
noted above + 265 blocks.$ul is the length noted above for
/usr.$uo is the offset noted above for
/usr less the smallest offset
noted above + 265 blocks.Create a file named
create.UpWindow containing:drive UpWindow device /dev/ad2s1h
plex name home.p1 org concat volume home
sd name home.p1.s0 drive UpWindow plex home.p1 len $hl driveoffset $ho
plex name usr.p1 org concat volume usr
sd name usr.p1.s0 drive UpWindow plex usr.p1 len $ul driveoffset $uoWhere $hl, $ho, $ul, and $uo are set as above.AcknowledgementsI would like to thank Greg Lehey for writing &vinum.ap; and for
providing very helpful comments on early drafts.
Several others made helpful suggestions after reviewing later drafts
including
Dag-Erling Smørgrav,
Michael Splendoria,
Chern Lee,
Stefan Aeschbacher,
Fleming Froekjaer,
Bernd Walter,
Aleksey Baranov, and
Doug Swarin.