This commit is contained in:
gferg 2002-04-18 00:01:14 +00:00
parent ff196e160c
commit c6698b1418
3 changed files with 776 additions and 0 deletions

View File

@ -0,0 +1,592 @@
<?xml version="1.0"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://docbook.org/xml/4.1.2/docbookx.dtd" [
<!ENTITY articleinfo SYSTEM "articleinfo.sgml">
<!ENTITY externalconf SYSTEM "externalconf.sgml">
<!ENTITY conffile SYSTEM "conffile.sgml">
<!ENTITY rlevelchange SYSTEM "rlevelchange.sgml">
<!ENTITY initd SYSTEM "initd.sgml">
<!ENTITY rc3d SYSTEM "rc3d.sgml">
<!ENTITY initscript SYSTEM "initscript.sgml">
<!ENTITY service SYSTEM "service.sgml">
<!ENTITY nomethod SYSTEM "nomethod.sgml">
<!ENTITY manysouls SYSTEM "manysouls.sgml">
<!ENTITY chkconfig SYSTEM "chkconfig.sgml">
]>
<article>
<articleinfo>
<title>Designing Integrated High Quality Linux Applications</title>
&articleinfo;
</articleinfo>
<section id="intro"><title>Introduction</title>
<para>Linux is becoming more and more popular, and many Software vendors are porting their products from other platformas. This document (article) tries to clarify some issues and give tips on how to create Linux applications highly integrated to the Operating System, security and easy of use.</para>
<para>The examples run on <ulink url="http://www.redhat.com/">Red Hat</ulink> Linux, and should be compatible with other distributions based on Red Hat (<ulink url="http://www.conectiva.com.br/">Conectiva</ulink>, <ulink url="http://www.turbolinux.com/">Turbolinux</ulink>, <ulink url="http://www.calderasys.com/">Caldera</ulink>, <ulink url="http://www.pld.org.pl/">PLD</ulink>, <ulink url="http://www.mandrakelinux.com/">Mandrake</ulink>, etc).</para>
</section>
<section id="userFriendly"><title>User Friendly: Guaranteed Success</title>
<para>The <emphasis>user-friendly</emphasis> concept is missassociated with a good <acronym>GUI</acronym> (graphical user interface). In fact, it is much more than that. In systems like Linux (with more server-like characteristics), the user measures how easy a Software is, mainly in the installation and initial configuration. He can even forget how easy were to install and use a certain product, but it will never forget that a Software package has a complex configuration and installation process. A migration or new installation allways will be a nightmare, making the user avoid it.</para>
<section id="installAndUse"><title>Embrace the <emphasis>Install-and-Use</emphasis> Paradigm</title>
<para>Imagine you'll install that expansive product your company bought from ACME, and realized you'll have to do the following:</para>
<orderedlist numeration="arabic">
<listitem><para>To have a manual that shows the installation process step-by-step. We know that a manual is the last thing the user reads</para></listitem>
<listitem><para>Read some README files</para></listitem>
<listitem><para>Uncompress huge files in your disk (after downloading them from net our CD), to create the installation environment</para></listitem>
<listitem><para>Read more README files that appeared in the installation environment</para></listitem>
<listitem><para>Comprehend that the installation requires you to execute in a special way some provided script (the inconvenient <filename>./install.sh</filename>)</para></listitem>
<listitem><para>Uncomfortably answer some questions that the script does, like target directory, user for the installation, etc. To make it worse, it frequently happens in a terminal that has a missconfigured backspace</para></listitem>
<listitem><para>After the installation, configure some environment variables in your profile, like <envar>$PATH</envar>, <envar>$LIBPATH</envar>, <envar>$ACMEPROGRAM_DATA_DIR</envar>, <envar>$ACMEPROGRAM_BIN_DIR</envar>, etc</para></listitem>
<listitem><para>Edit OS files to include the presence of the new product (e.g. <filename>/etc/inetd.conf</filename>, <filename>/etc/inittab</filename>)</para></listitem>
<listitem><para>And the worse: Change security permissions of OS directories and files to let the product run OK</para></listitem>
</orderedlist>
<para>Sounds familiar? Who never faced this sad situation, that inducts the user to make mistakes? If your products' installation process sound like <emphasis>Uncompress-Copy-Configure-ConfigureMore-Use</emphasis>, like this one, you have a problem, and the user won't like it.</para>
<para>Users like to feel that your Product integrates well with the OS. You should not demand that the OS adapt himself to your Product (changing environment variables, etc). It must let the user <emphasis role="strong">Install-and-Use</emphasis>.</para>
<para>The <emphasis>Install-And-Use</emphasis> glory is easily achieved using a 3 ingredients receipt:</para>
<orderedlist numeration="arabic">
<listitem><para>Understanding the Four Universal Parts of Any Software</para></listitem>
<listitem><para>Understanding how they are related to Linux's directory hierarchy</para></listitem>
<listitem><para>Aggressively use a package system, for process automation and leverage first items. In our case is RPM.</para></listitem>
</orderedlist>
<para>We'll discuss here what are these ingredients and how to implement them.</para>
</section>
</section>
<section id="software"><title>The Four Universal Parts of Any Software</title>
<para>The file set of any Application Software, graphical, server-side, commercial, open/free, monolithic etc, has allways four universal parts:</para>
<anchor id="software.body"/>
<bridgehead>1<superscript>st</superscript> :: The Software on its own: the body</bridgehead>
<para>The executables, libraries, static-data files, examples, manuals and documentation, etc. Regular users must have read-only access to these files. They are changed only when the system administrator makes an upgrade in this Software.</para>
<anchor id="software.soul"/>
<bridgehead>2<superscript>nd</superscript> :: Configuration Files: the soul</bridgehead>
<para>These are files that define how the Software will run, how to use the <link linkend="software.content">Content</link>, <link linkend="security">security</link>, performance etc. Without them, the <link linkend="software.body">Software on its own</link> is usually useless.</para>
<para>Depending on your Software, specific privileged users may change these files, to make the Software behave as they want.</para>
<para>It is important to provide documentation about the configuration files.</para>
<anchor id="software.content"/>
<bridgehead>3<superscript>rd</superscript> :: Content</bridgehead>
<para>Is what receives all the user attention. Is what the user delegated to be managed by your Product. Is what makes a user throw away your product and use the competitors', if it gets damaged.</para>
<para>Are the tables of a database system, the documents for a text editor, the images and HTML pages of a web-server, the servlets and EJBs of an Application Server, etc.</para>
<anchor id="software.logs"/>
<bridgehead>4<superscript>th</superscript> :: Logs, Dumps etc</bridgehead>
<para>Server Software use to generate access logs, trace files problem determination, temporary files etc. Other types of softwares also use this files, but it is less common.</para>
<para>It is the last class of file, but many times they are the most problem generator for a system administrator, because their volume can surpass even the content size. Due this fact, it is important for you to think in some methodology or facility for this issue, while you are in design time.</para>
<section id="software.example"><title>Practical Examples</title>
<para>Let's see how universal is this concept analyzing some types of softwares:</para>
<table pgwide="1" id="partstable"><title>Universality of 4 Parts</title>
<tgroup cols="4">
<thead>
<row>
<entry></entry>
<entry><link linkend="software.body">Software on its Own</link></entry>
<entry><link linkend="software.soul">Configurations</link></entry>
<entry><link linkend="software.content">Content</link></entry>
<entry><link linkend="software.logs">Logs, Dumps etc</link></entry>
</row>
</thead>
<tbody>
<row>
<entry><emphasis role="strong">Data Base Server</emphasis></entry>
<entry>Binaries, libraries, documentations.</entry>
<entry>Files that define the directory of the data files. For this type of Software, the remaining configurations usually are in special tables inside the database.</entry>
<entry>Table files, index files, etc. This software use to have whole trees under the same directory. And many times they need several filesystems to guarantee performance. Their local in the system is defined by they <link linkend="software.soul">Configurations</link>.</entry>
<entry>For DBs, there are the backup, generated in a daily basis. And the logs are used by the <acronym>DBA</acronym> to define indexing strategy. His local on the system is also defined by the <link linkend="software.soul">Configurations</link>.</entry>
</row>
<row>
<entry><emphasis role="strong">Text Processor</emphasis></entry>
<entry>The same, templates, modular file format filters, etc</entry>
<entry>As a user-oriented Software, its configurations must be put in each user's <envar>$HOME</envar> directory, and are files that defines standard fonts and tabulation, etc.</entry>
<entry>The documents generated by the user, and they go some place in his <envar>$HOME</envar></entry>
<entry>They show as temporary files that can be huge. User can define their location with a user-friendly dialog (that saves it in some <link linkend="software.soul">Configuration</link> file)</entry>
</row>
<row>
<entry><emphasis role="strong">MP3 generator</emphasis></entry>
<entry>Same, audio modular filters</entry>
<entry>Each user has a configuration file in his <envar>$HOME</envar>, and contains bitrate preferences etc</entry>
<entry>Similar to Text Editor</entry>
<entry>Similar to Text Editor</entry>
</row>
<row>
<entry><emphasis role="strong">Web Server</emphasis></entry>
<entry>Similar to Data Base</entry>
<entry>Files that define the <link linkend="software.content">Content</link> directory, network and performance parameters, <link linkend="security">security</link>, etc</entry>
<entry>Directories where the webmaster deposits his creativity. Again defined by the <link linkend="software.soul">Configurations</link></entry>
<entry>Preciouses access logs, vital for Marketing Intelligence, that are generated in a location and format defined by <link linkend="software.soul">Configurations</link></entry>
</row>
<row>
<entry><emphasis role="strong">e-Mail Server</emphasis></entry>
<entry>Similar to Database and Web-Server</entry>
<entry>Files that define how to access user database, mail routing rules, etc</entry>
<entry>The preciouses users mail boxes. Again defined by the <link linkend="software.soul">Configurations</link></entry>
<entry>Mail transfer log, virus detection log, etc. Again defined by the <link linkend="software.soul">Configurations</link></entry>
</row>
</tbody>
</tgroup>
</table>
<para>Pay attention that the <link linkend="software.body">Software on its Own</link> contains all your product <emphasis>business logic</emphasis>, which could be useless if you hadn't a <link linkend="software.soul">Configuration</link> to define how to work with a <link linkend="software.content">data bundle</link>, provided by the user. So, <link linkend="software.soul">Configurations</link> are what connects your product to the user.</para>
<para>We can use a metaphor about a Sculptor (<link linkend="software.body">business logic</link>), that needs Bronze (<link linkend="software.content">content</link>) and a Theme or Inspiration (<link linkend="software.soul">configuration</link>) from a Mecenas (<link linkend="userFriendly">user</link>), to produce a beautiful work (<link linkend="software.content">content</link>). He make annotations in his Journal (<link linkend="software.logs">logs</link>) about his day-by-day activities, to report to his Mecenas (<link linkend="userFriendly">user</link>).</para>
</section>
<section id="separe"><title>The Importance of Clear Separation Between Four Parts</title>
<para>OK, so let's be more practical. The fact is, if we correctly use the <link linkend="software">universal parts concept</link>, we greatly improve the quality of our Product. We'll do that simply separating, encapsulating, each one of these parts in different system directories (having only different files for each part is not sufficient). There is a standard called <ulink url="http://www.pathname.com/fhs/">FHS</ulink> that defines the Linux directories for each part, and we'll discuss it later in <xref linkend="fhs"/>.</para>
<para>By now let's see the value of this separation to the user:</para>
<orderedlist numeration="arabic">
<listitem><para>He gains a clear vision about where is each part, specially his <link linkend="software.soul">Configurations</link> and <link linkend="software.content">Content</link>, and he feels your Product as something completely under control. The clareza brings ease of use, security and confidence in your Product. And in practice it permits him manipulate each part independently</para></listitem>
<listitem><para>It is clear now that, for instance, when backing up, user action is needed only for <link linkend="software.soul">Configurations</link> and <link linkend="software.content">Content</link> (the puritans will also backup some <link linkend="software.logs">logs</link>). The user don't have to care about <link linkend="software.body">Software on its Own</link>, because it is safe, original, on the product CD, in his shelf.</para></listitem>
<listitem><para>For upgrades, the new package will overwrite only the <link linkend="software.body">business logic</link>, leaving intact the user's precious <link linkend="software.soul">Configurations</link> and <link linkend="software.content">Content</link>. Here is very important to keep old content and configuration compatible, or to provide some tools help migration of data</para></listitem>
<listitem><para>The logs being kept in a separate filesystem (obviously suggested in your documentation), avoids that their exaggerated growth interfere with the <link linkend="software.content">Content</link>, or with the stability of the whole system</para></listitem>
<listitem><para>If your Software follows some directory standards, the user don't have to reconfigure his system or environment to use it. He will simply <emphasis role="strong">Install-and-Use</emphasis>.</para></listitem>
</orderedlist>
<para>Let's make some exercise with separation using as example a system called <acronym>MySoftware</acronym>, in which the <link linkend="software.body">business logic</link> is in <xref linkend="example.body"/> and the configuration is in <xref linkend="example.soul"/>.</para>
<example id="example.body"><title>A Shell program referring an external configuration file</title>
<programlistingco>
&externalconf;
<calloutlist>
<callout arearefs="ex.body.const.c1">
<para>Definition of the configuration file name.</para>
</callout>
<callout arearefs="ex.body.const.c2">
<para>Definition of some static parameters.</para>
</callout>
<callout arearefs="ex.body.conf">
<para>The configuration is readed from an external file, if exists.</para>
</callout>
<callout arearefs="ex.body.merge">
<para>After reading the configuration file, all content directories -- user's + product's -- goes together in the <envar>$CONTENT_PATH</envar>, that will be used from now on.</para>
</callout>
</calloutlist>
</programlistingco>
</example>
<example id="example.soul"><title>File containing only the configurations for <acronym>MySoftware</acronym></title>
<programlistingco>
&conffile;
<calloutlist>
<callout arearefs="ex.soul.c1 ex.soul.c2 ex.soul.c3">
<para>These are user defined parameters.</para>
</callout>
</calloutlist>
</programlistingco>
</example>
</section>
<section id="bodysouls"><title>One Body, Many Souls</title>
<para>When I was a system administrator for IBM e-business Hosting Services, I was fascinated by <ulink url="http://httpd.apache.org/">Apache</ulink>'s flexibility letting us do things like this:</para>
&manysouls;
<para>If we don't pass any parameter (like the first example), Apache loads its default, hardcoded configuration file from <filename>/etc/httpd/conf/httpd.conf</filename>. We built other configs, one for each customer, with a completely different structure, IP address, loaded modules, content directory, passwords, domains, log strategy etc.</para>
<para>This same concept is used by a text editor of a multiuser desktop (like Linux). When the code is loaded, it looks for a configuration file on the user's <envar>$HOME</envar>, and depending who invoked him (user A or B), it will appear differently because each user has its own personal configuration.</para>
<para>The obvious conclusion is that the Software's body (<link linkend="software.body">business logic</link>) is pure e completely oriented by his manipulator's spirit (<link linkend="software.soul">configuration</link>). But the competitive advantage lays on how easy we switch from one <link linkend="software.soul">spirit</link> to another, like in Apache's example. It is very healthy to promote it to your user. You'll be letting him create intimacy, reliability, confort with your Product.</para>
<para>We used this approach with many different Softwares in that e-business Hosting time, and it was extremely usefull for maintenance etc. In a version migration we had total control over where were <link linkend="software">each of its parts</link>, and upgraded and downgraded Software with no waste of time, with obvious success.</para>
<para>But there were some Products that refused to work this way. They had so many hardcoded parameters, that we couldn't see what divided the <link linkend="software.body">body</link> from their <link linkend="software.soul">spirit</link> (or other parts). These Softwares were marked as <emphasis>bad guys</emphasis> and discarded/replaced as soon as possible.</para>
<para>We concluded that the <emphasis>good guys</emphasis> Softwares were intuitively blessed by their developer's <link linkend="software">four parts vision</link>. And they made our life easyer. In fact, in that time we formulated this <link linkend="software">theory</link>, that continues to prove itself.</para>
<para>Do you want to deploy <emphasis>bad guy</emphasis> or <emphasis>good guy</emphasis> Software?</para>
</section>
</section>
<section id="fhs"><title>Linux Directory Hierarchy: Oriented to the Software Parts</title>
<para>By now, all discussion are OS independent. On Linux, the <link linkend="software">Four Software Parts</link> theory is expressed in his directory structure, which is classified and documented in the <ulink url="http://www.pathname.com/fhs/">Filesystem Hierarchy Standard</ulink>. The <acronym>FHS</acronym> is part of the <ulink url="http://www.linuxbase.org/"><acronym>LSB</acronym> (Linux Standard Base)</ulink>, which makes him a good thing because all the industry is moving thowards it, and is a constant preoccupation to all distributions. <acronym>FHS</acronym> defines in which directories each peace of Apache, Samba, Mozilla, KDE <emphasis>and your Software</emphasis> must go, and you don't have any other reason to not use it while thinking in developing your Software, but I'll give you some more:</para>
<orderedlist numeration="arabic">
<listitem><para><acronym>FHS</acronym> is a standard, and we can't live without standards</para></listitem>
<listitem><para>This is the most basic OS organization, that are related to access levels and <link linkend="security"><emphasis role="strong">security</emphasis></link>, where users intuitively find each type of file, etc</para></listitem>
<listitem><para><emphasis>Makes user's life easyer</emphasis></para></listitem>
</orderedlist>
<para>This last reason already justifies FHS adoption, so <phrase role="strong">allways use the <acronym>FHS</acronym></phrase> !!!</para>
<para>More about <acronym>FHS</acronym> importance and sharing the same directory structure can be found in <ulink url="http://www.redhat.com/docs/manuals/linux/RHL-7.2-Manual/ref-guide/ch-filesystem.html">Red Hat website.</ulink></para>
<section id="fhs.fhs"><title><acronym>FHS</acronym> Summary</title>
<para>So let's summarize what the <acronym>FHS</acronym> has to say about Linux directories:</para>
<variablelist><title>Linux system directories</title>
<varlistentry><term><filename class="directory">/usr/bin</filename></term>
<listitem>
<para>Directory for the executables that are accessed by all users (everybody have this directory in their <varname>$PATH</varname>). The main files of your Software will probably be here. You should never create a subdirectory under this folder.</para>
</listitem>
</varlistentry>
<varlistentry><term><filename class="directory">/bin</filename></term>
<listitem>
<para>Like <filename class="directory">/usr/bin</filename>, but here you'll find only boot process vital executables, that are simple and small. Your Software (being high-level) probably doesn't have nothing to install here.</para>
</listitem>
</varlistentry>
<varlistentry><term><filename class="directory">/usr/sbin</filename></term>
<listitem>
<para>Like <filename class="directory">/usr/bin</filename>, but contains only the executables that must be accessed by the administrator (root user). Regular users should never have this directory in their <varname>$PATH</varname>. If your Software is a daemon, This is the directory for some of executables.</para>
</listitem>
</varlistentry>
<varlistentry><term><filename class="directory">/sbin</filename></term>
<listitem>
<para>Like <filename class="directory">/usr/sbin</filename>, but only for the boot process vital executables, and that will be accessed by sysadmin for some system maintaining. Commands like <command>fsck</command> (filesystem check), <command>init</command> (father of all processes), <command>ifconfig</command> (network configuration), <command>mount</command>, etc can be found here. It is the system's most vital directory.</para>
</listitem>
</varlistentry>
<varlistentry><term><filename class="directory">/usr/lib</filename></term>
<listitem>
<para>Contains dynamic libraries and support static files for the executables at <filename class="directory">/usr/bin</filename> and <filename class="directory">/usr/sbin</filename>. You can create a subdirectory like <filename class="directory">/usr/lib/myproduct</filename> to contain your helper files, or dynamic libraries that will be accessed only by your Software, without user intervention. A subdirectory here can be used as a container for <link linkend="plugin">plugins and extensions</link>.</para>
</listitem>
</varlistentry>
<varlistentry><term><filename class="directory">/lib</filename></term>
<listitem>
<para>Like <filename class="directory">/usr/lib</filename> but contains dynamic libraries and support static files needed in the boot process. You'll never find an executable at <filename class="directory">/bin</filename> or <filename class="directory">/sbin</filename> that needs a library that is outside this directory. Kernel modules (device drivers) are under <filename class="directory">/lib</filename>.</para>
</listitem>
</varlistentry>
<varlistentry><term><filename class="directory">/etc</filename></term>
<listitem>
<para>Contains configuration files. If your Software uses several files, put them under a subfolder like <filename class="directory">/etc/myproduct/</filename></para>
</listitem>
</varlistentry>
<varlistentry><term><filename class="directory">/var</filename></term>
<listitem>
<para>The name comes from "<emphasis>variable</emphasis>", because everything that is under this directory changes a frequently. Usually <filename class="directory">/var</filename> is mounted over a separate high-performance partition. In <filename class="directory">/var/log</filename> logfiles grow up. For web content we use <filename class="directory">/var/www</filename>, and so on.</para>
</listitem>
</varlistentry>
<varlistentry><term><filename class="directory">/home</filename></term>
<listitem>
<para>Contains the user's (real human beings) <emphasis>home</emphasis> directories. Your Software package should <emphasis>never</emphasis> install files here (in installation time). If <emphasis>your</emphasis> business logic requires a special <acronym>UNIX</acronym> user (not a human being) to be created, you should assign him a home directory under <filename class="directory">/var</filename> or other place <emphasis>outside</emphasis> <filename class="directory">/home</filename>. Please, never forget that.</para>
</listitem>
</varlistentry>
<varlistentry><term><filename class="directory">/usr/share/doc</filename></term><term><filename class="directory">/usr/share/man</filename></term>
<listitem>
<para>The "share" word is used because what is under <filename class="directory">/usr/share</filename> is platform independent, and can be shared among several machines across a network filesystem. Therefore this is the place for manuals, documentations, examples etc.</para>
</listitem>
</varlistentry>
<varlistentry><term><filename class="directory">/usr/local</filename></term><term><filename class="directory">/opt</filename></term>
<listitem>
<para>These are obsolete folders. When <acronym>UNIX</acronym> didn't have a package system (like RPM), sysadmins needed to separate an <emphasis>optional</emphasis> (or <emphasis>local</emphasis>) Software from the main OS. These were the directories used for that.</para>
</listitem>
</varlistentry>
</variablelist>
<para>You may think is a bad idea to break your Software (as a whole) in many pieces, instead of keeping it all under a self-contained directory. But a <link linkend="rpm">package system (RPM)</link> has a database that manages it all for you in a very professional way, taking care of configuration files, directories etc. And if you spread your Software using the <acronym>FHS</acronym>, beyond the user friendliness, you'll bring an intuitive way to the sysadmin configure it, and work better with performance and security.</para>
</section>
<section id="newtable"><title>Examples Using the <acronym>FHS</acronym></title>
<para>Now that we know where each part of our software must be installed, lets review the <link linkend="partstable">Universal Parts Table</link> applied to the <acronym>FHS</acronym>.</para>
<table pgwide="1"><title>Same Software, applying <acronym>FHS</acronym></title>
<tgroup cols="4">
<thead>
<row>
<entry></entry>
<entry><link linkend="software.body">Software on its Own</link></entry>
<entry><link linkend="software.soul">Configurations</link></entry>
<entry><link linkend="software.content">Content</link></entry>
<entry><link linkend="software.logs">Logs, Dumps etc</link></entry>
</row>
</thead>
<tbody>
<row>
<entry><emphasis role="strong">Data Base Server</emphasis></entry>
<entry><filename class="directory">/usr/bin/</filename>, <filename class="directory">/usr/lib/</filename>, <filename class="directory">/usr/share/doc/mydb/</filename>, <filename class="directory">/usr/share/doc/mydb/examples/</filename></entry>
<entry><filename class="directory">/etc/mydb/</filename></entry>
<entry><filename class="directory">/var/db/instance1/</filename>, <filename class="directory">/var/db/instance2/</filename>, etc</entry>
<entry><filename class="directory">/var/db/instance1/transactions/</filename>, <filename>/var/log/db/access-instance1.log</filename>, <filename>/var/log/db/access-instance2.log</filename></entry>
</row>
<row>
<entry><emphasis role="strong">Text Editor</emphasis></entry>
<entry><filename class="directory">/usr/bin/</filename>, <filename class="directory">/usr/lib/</filename>, <filename class="directory">/usr/lib/myeditor/plugins/</filename>, <filename class="directory">/usr/share/myeditor/templates/</filename>, <filename class="directory">/usr/share/doc/myeditor/</filename></entry>
<entry><filename>$HOME/.myeditor.conf</filename></entry>
<entry><filename class="directory">$HOME/Docs/</filename></entry>
<entry><filename class="directory">$HOME/.myeditor-tmp/</filename></entry>
</row>
<row>
<entry><emphasis role="strong">MP3 Generator</emphasis></entry>
<entry><filename class="directory">/usr/bin/</filename>, <filename class="directory">/usr/lib/</filename>, <filename class="directory">/usr/lib/mymp3/plugins/</filename>, <filename class="directory">/usr/share/doc/mymp3/</filename></entry>
<entry><filename>$HOME/.mymp3.conf</filename></entry>
<entry><filename class="directory">$HOME/Music/</filename></entry>
<entry><filename class="directory">$HOME/.mymp3-tmp/</filename></entry>
</row>
<row>
<entry><emphasis role="strong">Web Server</emphasis></entry>
<entry><filename class="directory">/usr/sbin/</filename>, <filename class="directory">/usr/bin/</filename>, <filename class="directory">/usr/lib/httpd-modules/</filename>, <filename class="directory">/usr/share/doc/httpd/</filename>, <filename class="directory">/usr/share/doc/httpd/examples/</filename></entry>
<entry><filename class="directory">/etc/httpd/</filename>, <filename class="directory">/etc/httpd/instance1/</filename>, <filename class="directory">/etc/httpd/instance2/</filename></entry>
<entry><filename class="directory">/var/www/</filename>, <filename class="directory">/var/www/instance1/</filename>, <filename class="directory">/var/www/instance2/</filename></entry>
<entry><filename class="directory">/var/logs/httpd/</filename>, <filename class="directory">/var/logs/httpd/instance1/</filename>, <filename class="directory">/var/logs/httpd/instance2/</filename></entry>
</row>
<row>
<entry><emphasis role="strong">E-Mail Server</emphasis></entry>
<entry><filename class="directory">/usr/sbin/</filename>, <filename class="directory">/usr/bin/</filename>, <filename class="directory">/usr/lib/</filename>, <filename class="directory">/usr/share/doc/mymail/</filename></entry>
<entry><filename class="directory">/etc/mail/</filename>, <filename>/etc/mailserver.cf</filename></entry>
<entry><filename class="directory">/var/mail/</filename></entry>
<entry><filename class="directory">/var/spool/mailqueue/</filename>, <filename>/var/logs/mail.log</filename></entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section id="noopt"><title>Friendly Advice: Never use <filename class="directory">/opt</filename> or <filename class="directory">/usr/local</filename></title>
<para>This is a very polemic subject, and that is why this is the most important section in this document. After almost ten years of <acronym>UNIX</acronym> experience I can beat any <filename class="directory">/usr/local</filename>-prone argument. I'll try to organize some ideas here.</para>
<para>It is very important to Linux evolution and popularization (especially in the desktop battlefield), that developers stop using this hell directories, and start using the <acronym>FHS</acronym>. After reading this section, if you still think this folders are good business, please drop me an e-mail.</para>
<para>Products that are <emphasis>entirely</emphasis> installed under <emphasis>one</emphasis> directory, uses the <emphasis>self-contained</emphasis> approach, that has several problems:</para>
<orderedlist numeration="arabic">
<listitem><para>Forces the user to change environment variables like <varname>$PATH</varname> and <varname>$LD_LIBRARY_PATH</varname> to use your product easily.</para></listitem>
<listitem><para>Puts files in non-standard places, complicating system integration, and future installation of extensions to your product.</para></listitem>
<listitem><para>The sysadmin probably didn't prepared disk space in these partitions, generating problems in installation time.</para></listitem>
<listitem><para>It is an accepted approach only for pure graphical application, without the command line concept. This is why it were well accepted in Windows. But...</para></listitem>
<listitem><para>...even using this approach, you can't avoid installing or changing files in standard locations to, for instance, make your icons appear in the user desktop.</para></listitem>
</orderedlist>
<para>This directories exists for historical reasons, and for compatibility with other <acronym>UNICES</acronym>, from the epoch we didn't have a package management system, and the sysadmin needed to segregate the products, to keep the control. And the last item shows us that even if you want, you'll not be able to segregate your product. You'll make it distant and non-practical to the user.</para>
<para>You don't have to be afraid of spreading your files according to <link linkend="fhs"><acronym>FHS</acronym></link> because RPM will keep an eye on them.</para>
<para>Many developers believe that the "self-contained" approach let them work with several versions of the same product, for testing purposes, or whatever. Yes, agree, with this or any good reason in the planet. But remember that a High Quality Software (or Commercial Grade Software) objective is to be practical for the final user, and not to be easy to their developers and testers. Invite yourself to visit an unexperienced (but potential customer) user and watch him installing your product.</para>
<para>If you have a business requirement to let the user work with several versions of your Product simultaneously (or any other reason), make a <ulink url="http://www.rpm.org/max-rpm/ch-rpm-reloc.html">relocatable package</ulink>, which is described in the <ulink url="http://www.rpm.org/max-rpm/">Maximum RPM</ulink> book. Be also aware about the implications of using this feature, <ulink url="http://www.rpm.org/max-rpm/s1-rpm-reloc-wrinkles.html">described in the same book</ulink>.</para>
<para>Nao e a toa that distributions like Red Hat and derivatives allways use <acronym>FHS</acronym>, instead of <filename class="directory">/opt</filename> or <filename class="directory">/usr/local</filename>. <link linkend="redhat">Read what Red Hat says about this subject</link>, and think about it.</para>
<note>
<para>The Makefiles of an OpenSource Software that is portable to other <acronym>UNICES</acronym> must have the standard installation in <filename class="directory">/usr/local</filename> for compatibility reasons. But must also give the option, and induct the packager, to create the package using <link linkend="fhs"><acronym>FHS</acronym></link> specifications.</para>
</note>
</section>
</section>
<section id="plugin"><title>Provide Architecture for Extensions and Plugins</title>
<para>You'll probably let other Software vendors plug extensions to your product. Since you are the author of the initial Software, is your responsability to organize it in such a way that the user can simply install the extension RPM and use it, without forcing him modify any configuration file. Is is again the famous <link linkend="installAndUse"><emphasis>Install-and-Use</emphasis></link> that guarantees ease-of-use.</para>
<para>Well, and extension is nothing more that some files in a <emphasis role="strong">right format</emphasis> (DLLs that implements the API your Software defined), put in the <emphasis role="strong">right folders</emphasis> (directories your Software looks for extensions). We can see many applications requesting the user to change configuration files to "declare" the presence of a new plugin.</para>
<para>The most important thing to consider in your plugin architecture is <emphasis>to not share files between plugins and your Software</emphasis>. You should provide an architecture where plugins will fully install and uninstall themselves by simply putting and removing files in specific directories, documented in you Software. Good candidates are <filename class="directory">/usr/lib/myproduct/plugins</filename> as the plugins directory, and <filename class="directory">/etc/myproduct/plugins</filename> as the plugins configuration files directory. Your Software and plugins must be sufficient intelligent to know how to find files, specially configurations, in these directories. Using this approach, no post-install procedures is required from the user, and from the plugin provider.</para>
<section id="plugin.concept"><title>Abstracting About Plugins</title>
<para>I would like to close this subject inviting the reader a se abstratir and think about any Software can be treated as an extension to the lower level Software. In the same way a third party plugin is an extension to your Software, your Software is also an extension to the OS (lower level). This is where all the Integration (from the title of this document) magic lives. So we can apply all the ease-of-use concepts we discussed before to the plugin architecture design of your Software.</para>
</section>
</section>
<section id="rpm"><title>Allways Provide RPM Packages of Your Softwares</title>
<para>This is extremely important for many reasons:</para>
<orderedlist numeration="arabic">
<listitem><para>Ease-of-use. This is allways the primordial motivation.</para></listitem>
<listitem><para>Automates some tasks that must be made before and after the installation of your Software. Again bringing ease-of-use.</para></listitem>
<listitem><para>Intelligently manages configuration files, documentation etc, providing more control in an upgrade</para></listitem>
<listitem><para>Manages interdependencies with other packages and versions, guaranteeing good functionality.</para></listitem>
<listitem><para>Lets you distribute Software with your company's digital signature, and makes integrity checks (<acronym>MD5</acronym>) in each file, guaranteeing precedence, and reporting unwanted file modification.</para></listitem>
<listitem><para>Provides tools to let interact with your graphic installer.</para></listitem>
</orderedlist>
<para>But a good package is not only put together your files in a RPM. <acronym>FHS</acronym> must be followed, configuration and documentation files must be marked as is, and pre- and post-install scripts must be robust, to not let them damage the system (remember that installation processes is done by root).</para>
<para>Know well RPM because it can bring much power and facilities to you and your user. There are a lot of documentation available about RPM on the Internet:</para>
<itemizedlist spacing="compact">
<listitem><para>The book <ulink url="http://www.redhat.com/docs/books/max-rpm/">Maximum RPM</ulink>, also available <ulink url="http://www.rpm.org/max-rpm/">on-line</ulink> and in printable <ulink url="http://www.rpm.org/local/maximum-rpm.ps.gz">PostScript</ulink> format.</para></listitem>
<listitem><para><ulink url="http://www.rpm.org/RPM-HOWTO/">RPM-HOWTO</ulink> which is smaller and more straight-forward.</para></listitem>
<listitem><para><ulink url="http://www.rpm.org/">www.rpm.org</ulink></para></listitem>
</itemizedlist>
<section id="module"><title>Software Package Modularization</title>
<para>You should give user the option to install only the part of your Software he wants. Imagine your Software has a client part and a server part, and both use files and libraries in common. You should break them in 3 RPMs. For instance, lets say the name of your product is <emphasis>MyDB</emphasis>, so you'll provide the packages:</para>
<orderedlist numeration="arabic">
<listitem><para><filename>MyDB-common-1.0-3.i386.rpm</filename></para></listitem>
<listitem><para><filename>MyDB-server-1.0-3.i386.rpm</filename></para></listitem>
<listitem><para><filename>MyDB-client-1.0-3.i386.rpm</filename></para></listitem>
</orderedlist>
<para>and last 2 packages depends on the first. If the user is installing a client profile, he will use:</para>
<orderedlist numeration="arabic">
<listitem><para><filename>MyDB-common-1.0-3.i386.rpm</filename></para></listitem>
<listitem><para><filename>MyDB-client-1.0-3.i386.rpm</filename></para></listitem>
</orderedlist>
<para>If he is installing a server profile:</para>
<orderedlist numeration="arabic">
<listitem><para><filename>MyDB-common-1.0-3.i386.rpm</filename></para></listitem>
<listitem><para><filename>MyDB-server-1.0-3.i386.rpm</filename></para></listitem>
</orderedlist>
<para>This approach will help the user save disk space, and be aware of how your Software is organized.</para>
</section>
</section>
<section id="security"><title>Security: The Omnipresent Concept</title>
<para>From a very general perspective, security is synonym of order, conscience. And insecure is everything that makes a system stop without the user wish. So besides open network ports, or weak cryptography (that are beyond the scope of this document), applications that inducts the user to use it only as root, or make him change files in inappropriate places, is considered insecure. We can say the same for the apps that fills a filesystem that is vital to the OS.</para>
<para>Many standards appeared from good practices discussed and developed in conjunction for a long time. So you should know and use them when you'll package your software, because they are key for you to achieve a good organization (security) level.</para>
</section>
<section id="gui"><title>Graphical User Interface</title>
<para>Everybody loves graphical interfaces. Many times they make our life easyer, and this way helps to popularize a Software, because the learning curve get smaller. But for the everyday use, a command with many options and a good manual becomes much more practical, making scripts easy, remote access, etc. So the suggestion is, whenever is possible, to provide both interfaces: graphical for the beginners, and the powerfull command line for the expert.</para>
<section id="kdegnome"><title>KDE, GNOME, Java or Motif?</title>
<para>Better then a simple graphical interface is a consistent integrated desktop. And the desktops today in Linuxland are <acronym>KDE</acronym> and <acronym>GNOME</acronym>. Try to allways use one of them, or both.</para>
<para><ulink url="http://www.kde.org/">KDE</ulink> is the most outstanding, offering a true consistent desktop, flexible, with an extremely elegant architecture, using components, intercommunication, performance etc. It is constantly evolving, and is developed in C++. Its applications have an familiar integrated look-and-feel, is light and mature.</para>
<para><ulink url="http://www.gnome.org/">GNOME</ulink> also brings the integrated desktop proposal, but it is far from the maturity and ease-of-use of KDE. From the other side, is very well supported by the comunity, and good improvements are appearing.</para>
<para>Motif isn't an integrated desktop. It is a widgets library (button, scrollbar etc), plus a window-manager. It was born commercial, is mature and popular in commercial applications. But is considered obsolete in front of KDE and GNOME, that integrates the desktop. Motif source code was opened by the <ulink url="http://www.opengroup.org/">OpenGroup</ulink> and because that was renamed to <ulink url="http://www.openmotif.org/">OpenMotif</ulink>.</para>
<para><ulink url="http://java.sun.com/">Java</ulink> is being used more and more for graphical interfaces, specially in server Software, where the graphics are only helpers to configuration and administration. </para>
</section>
<section id="webgui"><title>Web Interface: Access from Anywhere</title>
<para>Nowadays every desktop has a browser, and if your Product is a server application, the Web Interface is the right choice, because it lets a user administer it from anywhere. But keep in mind the security and organization of your CGIs, because they use to be front doors for crackers. Web interface (CGI) is completely different programming paradigm. Try to understand it conceptually first, starting from "how a web-server works", "what is a URL", etc, to get on this without compromising your Product's security.</para>
</section>
<section id="wizard"><title>Wizards and Graphical Installers</title>
<para>Specially for a commercial Product, your Software must provide a graphical installer. Believe me, they are impressive in a demonstration, and CIOs love them.</para>
<para>More then just installation, a wizard helps in the initial configuration of your Product, collects info like activation key etc, and shows the developer license.</para>
<para>A wizard should not do more than this:</para>
<orderedlist numeration="arabic">
<listitem><para>Ask which modules to install, experienced by the user as checkboxes.</para></listitem>
<listitem><para>Get the necessary info to build an initial <link linkend="software.soul">configuration (the soul)</link> for the Software.</para></listitem>
<listitem><para>Install the selected modules, that are in fact RPM files. Each checkbox must represent one or more RPMs, because each RPM is a indivisible (atomic) portion of a Software.</para></listitem>
<listitem><para>After RPMs installation, change the <link linkend="software.soul">configuration (soul)</link> files (marked this way in the RPMs), or create some <link linkend="software.content">content</link>, based on the data the user gave to the wizard.</para></listitem>
</orderedlist>
<para>So the wizard hides the RPM installation and writes initial personalization. RPM is still responsable for putting all your software files in the correct places. This role should never be of your installer. Think that an experienced user (there are a lot of them in the Linux world) should be able to reproduce your Product installation without the graphical help, using only RPM commands. In fact, in big data centers, where people make mass installations, a graphical installer only disturbs.</para>
<para>RPM provides tools that help your graphical installer interact with them, like installation percentage viewer. Documentation for use are allways in the RPM manual (<command>man rpm</command>) and in the <ulink url="http://www.rpm.org/max-rpm/">Maximum RPM</ulink> book.</para>
</section>
</section>
<section id="boot"><title>Starting Your Software Automatically on Boot</title>
<para>The way Linux starts (and stops) all its subsystems is very simple and modular. Lets you define initialization order, <link linkend="boot.runlevel">runlevels</link> etc</para>
<section id="boot.init"><title>From <acronym>BIOS</acronym> to Subsystems</title>
<para>Lets review what happens when we boot Linux:</para>
<orderedlist numeration="arabic">
<listitem><para>The <acronym>BIOS</acronym> or a bootloader (<application>lilo</application>, <application>zlilo</application>, <application>grub</application>, etc) loads Linux Kernel from disk to memory, with some parameters defined in the bootloader configuration. We can see this process watching the dots that appear in the screen. Kernel file stays in the <filename class="directory">/boot</filename> directory, and is accessed only at this moment.</para></listitem>
<listitem><para>In memory, Kernel code starts to run, detecting a series of vital devices, disk partitions etc.</para></listitem>
<listitem><para>On of the last things Kernel does is to mount the <filename class="directory">/</filename> (root) filesystem, that obrigatoriamente must contain the <filename class="directory">/etc</filename>, <filename class="directory">/sbin</filename>, <filename class="directory">/bin</filename> and <filename class="directory">/lib</filename> directories.</para></listitem>
<listitem><para>Immediately behind, calls the program called <command>init</command> (<filename>/sbin/init</filename>) and passes the control to him.</para></listitem>
<listitem><para>The <command>init</command> command will read his configuration file (<filename>/etc/inittab</filename>) which defines the system <emphasis role="strong">runlevel</emphasis>, and some Shell scripts to be run.</para></listitem>
<listitem><para>These scripts will continue the setup of system's minimal infrastructure, mounting other filesystems (according to <filename>/etc/fstab</filename>), activating swap space (virtual memory), etc.</para></listitem>
<listitem><para>The last step, and most interesting for you, is the execution of the special script called <filename>/etc/rc.d/rc</filename>, which initializes the subsystems according to a directory structure under <filename class="directory">/etc/rc.d</filename>. The name <emphasis>rc</emphasis> comes from <emphasis>run commands</emphasis>.</para></listitem>
</orderedlist>
</section>
<section id="boot.runlevel"><title>Runlevels</title>
<para>The runlevels mechanism lets Linux initialize itself in different ways. And also lets us change from one profile (runlevel) to another without rebooting.</para>
<para>The default runlevel is defined in <filename>/etc/inittab</filename> with a line like this:</para>
<example><title>Default runlevel (3, in this case) line in <filename>/etc/inittab</filename></title>
<programlisting>id:3:initdefault:</programlisting>
</example>
<para>Runlevels are numbers from 0 to 6 and each one of them is used following this standard:</para>
<variablelist>
<varlistentry><term>0</term>
<listitem>
<para>Halts the system. Turning to this runlevel, all subsystems are softly deactivated before the shutdown. Don't use it in the <command>initdefault</command> line of <filename>/etc/inittab</filename>.</para>
</listitem>
</varlistentry>
<varlistentry><term>1</term>
<listitem>
<para>Mono-user mode. Only vital subsystems are initialized because it is used for system maintenance. No user authentication (login) is required in this runlevel. A command line is directly returned to the user.</para>
</listitem>
</varlistentry>
<varlistentry><term>3</term><term>2</term>
<listitem>
<para>3 is used when a system is in full production. Take it as the runlevel your software will run. 2 is historical and is like 3, but without NFS.</para>
</listitem>
</varlistentry>
<varlistentry><term>4</term>
<listitem>
<para>Not used. You can define it as you want, but is uncommon.</para>
</listitem>
</varlistentry>
<varlistentry><term>5</term>
<listitem>
<para>Like 3 plus a graphical login. It is ideal for a desktop workstation. Use 3 if the machine will be used as a server, for security and performance reasons.</para>
</listitem>
</varlistentry>
<varlistentry><term>6</term>
<listitem>
<para>Like runlevel 0, but after complete stop, the machine is rebooted. Don't use it in the <command>initdefault</command> line of <filename>/etc/inittab</filename>.</para>
</listitem>
</varlistentry>
</variablelist>
<para>You can switch from one runlevel to another using the <command>telinit</command> command. And you can see the current runlevel and the last one with the <command>runlevel</command> command. See bellow how we switched from runlevel 3 to 5.</para>
&rlevelchange;
</section>
<section id="boot.subs"><title>The Subsystems</title>
<para>Subsystems examples are a web-server, data base server, OS network layer etc. We'll not consider a user oriented application (like a text editor) as a subsystem.</para>
<para>Linux provides an elegant and modular way to organize the subsystems initialization. An important fact to think is about subsystems interdependencies. For instance, it makes no sense to start a web-server before basic networking subsystem is active.</para>
<para>Subsystems are organized under the <filename class="directory">/etc/init.d</filename> and <filename class="directory">/etc/rc.d/rc<replaceable>N</replaceable>.d</filename> directories: </para>
<variablelist>
<varlistentry><term><filename class="directory">/etc/init.d</filename></term>
<listitem>
<para>All installed Subsystems put in this directory a control program, which is a script that follows a <link linkend="boot.script">simple standard described bellow</link>. This is a simplified listing of this directory:</para>
<example><title>Subsystems installed in <filename class="directory">/etc/init.d</filename></title>
&initd;
</example>
</listitem>
</varlistentry>
<varlistentry><term><filename class="directory">/etc/rc.d/rc<replaceable>N</replaceable>.d</filename> (<replaceable>N</replaceable> is the runlevel indicator)</term>
<listitem>
<para>These directories must contain only special symbolic links to the scripts in <filename class="directory">/etc/init.d</filename>. This is how it looks:</para>
<example><title><filename class="directory">/etc/rc3.d</filename> listing</title>
&rc3d;
</example>
<para>Pay attention that all link names has a prefix starting with letter <emphasis role="strong">K</emphasis> (from Kill, to deactivate) or <emphasis role="strong">S</emphasis> (from Start, to activate), and a 2 digit number that defines the boot activation priority. In our example we have HTTPd (priority 75) starting after the Network (priority 10) subsystem. And the Firewalling subsystem will be deactivated (<emphasis role="strong">K</emphasis>) in this runlevel.</para>
</listitem>
</varlistentry>
</variablelist>
<para>So <emphasis role="strong">to make your Software start automatically in the boot process, it must be a subsystem</emphasis>, and we'll see how to do it in the following section.</para>
</section>
<section id="boot.script"><title>Turning Your Software Into a Subsystem</title>
<para>Your Software's files will spread across the filesystems, but you'll want to provide a simple and consistent interface to let the user at least start and stop it. Subsystems architecture promotes this ease-of-use, also providing a way (non obrigatoria) to be automatically started on system initialization. You just have to create your <filename class="directory">/etc/init.d</filename> script following a standard to make it functional.</para>
<example><title>Skeleton of a Subsystem control program in <filename class="directory">/etc/init.d</filename></title>
<programlistingco>
&initscript;
<calloutlist>
<callout arearefs="ex.init.chkconfig">
<para>Although these are comments, they are used by <command>chkconfig</command> command and must be present. This particular line defines that on runlevels 2,3,4 and 5, this subsystem will be activated with priority 95 (one of the lasts), and deactivated with priority 05 (one of the firsts).</para>
</callout>
<callout arearefs="ex.init.sysconfig">
<para>Besides your <link linkend="software.soul">Software's own configuration</link>, this script can also have a configuration file. The standard place for it is under <filename class="directory">/etc/sysconfig</filename> directory, and in our case we call it <filename>mySystem</filename>. This code line reads this configuration file.</para>
</callout>
<callout arearefs="ex.init.start ex.init.stop ex.init.reload">
<para>Your script can have many functions, but it is obrigatorios the implementation of <command>start</command> and <command>stop</command> methods, because they are responsible for (de)activation of your Subsystem on boot. Other methods can be called from the command line, and you can define as much as you want.</para>
</callout>
<callout arearefs="ex.init.call">
<para>After defining the script actions, the command line is analyzed and the requested method (action) is called.</para>
</callout>
<callout arearefs="ex.init.default">
<para>If this script is executed without any parameter, it will return a help message like this:</para>
&nomethod;
</callout>
<callout arearefs="ex.init.any.begin ex.init.any.start ex.init.any.stop">
<para>Here you put your Software's specific command.</para>
</callout>
</calloutlist>
</programlistingco>
</example>
<para>The <command>mysystem</command> subsystem methods you implemented will be called by users with the <command>service</command> command like this example:</para>
<example><title><command>service</command> command usage</title>
&service;
</example>
<para>You don't have to worry about managing the symbolic links in <filename class="directory">/etc/rc.d/rc<replaceable>N</replaceable>.d</filename>. The <command>chkconfig</command> command makes it for you, based on the control comments defined in the beginning of your script.</para>
<example><title>Using the <command>chkconfig</command> command</title>
&chkconfig;
</example>
<para>Read the <command>chkconfig</command> manual page to see what more it can do for you.</para>
</section>
<section id="boot.install"><title>Packaging Your Boot Script</title>
<para>When you'll create the RPM, put your Subsystem script in <filename class="directory">/etc/init.d</filename> and <emphasis role="strong">do not include</emphasis> any <filename class="directory">/etc/rc.d/rc<replaceable>N</replaceable>.d</filename> link, because it is a user decision to make your subsystem automatic or not. If you include them and the user makes any change, the RPM file inventory will become inconsistent.</para>
<para>The symbolic links must be created and removed dynamically by the post-installation and pre-uninstallation process of your package, using the <command>chkconfig</command> command. This approach guarantees 100% package and filesystem consistency.</para>
</section>
</section>
<appendix id="redhat"><title>Red Hat, About the Filesystem Structure</title>
<para>This text was taken from <ulink url="http://www.redhat.com/docs/manuals/linux/RHL-7.2-Manual/ref-guide/ch-filesystem.html">The Official Red Hat Linux Reference Guide</ulink></para>
<bridgehead>Why Share a Common Structure?</bridgehead>
<para>An operating system's filesystem structure is its most basic level of organization. Almost all of the ways an operating system interacts with its users, applications, and security model are dependent upon the way it stores its files on a primary storage device (normally a hard disk drive). It is crucial for a variety of reasons that users, as well as programs at the time of installation and beyond, be able to refer to a common guideline to know where to read and write their <link linkend="software.body">binary</link>, <link linkend="software.soul">configuration</link>, <link linkend="software.logs">log</link>, and other necessary files.</para>
<para>A filesystem can be seen in terms of two different logical categories of files:</para>
<orderedlist numeration="arabic">
<listitem><para>Shareable vs. unsharable files</para></listitem>
<listitem><para>Variable vs. static files</para></listitem>
</orderedlist>
<para>Shareable files are those that can be accessed by various hosts; unsharable files are not available to any other hosts. Variable files can change at any time without system administrator intervention (whether active or passive); static files, such as <link linkend="software.body">documentation and binaries</link>, do not change without an action from the system administrator or an agent that the system administrator has placed in motion to accomplish that task.</para>
<para>The reason for looking at files in this way has to do with the type of permissions given to the directory that holds them. The way in which the operating system and its users need to utilize the files determines the directory where those files should be placed, whether the directory is mounted read-only or read-write, and the level of access allowed on each file. The top level of this organization (<emphasis>/ directory</emphasis>)is crucial, as the access to the underlying directories can be restricted or <link linkend="security">security</link> problems may manifest themselves if the top level is left disorganized (<link linkend="security">security=organization</link>) or without a <link linkend="fhs">widely-utilized structure</link>.</para>
<para>However, simply having a structure does not mean very much unless it is a <link linkend="fhs">standard</link>. Competing structures can actually cause more problems than they fix. Because of this, Red Hat has chosen <link linkend="fhs">the most widely-used filesystem structure</link> and extended it only slightly to accommodate special files used within Red Hat Linux.</para>
</appendix>
<appendix id="about"><title>About this Document</title>
<para>This document must be distributed under the terms of <ulink url="http://www.gnu.org/copyleft/fdl.html">GNU Free Documentation License</ulink>, which makes him sufficiently free. Everybody in invited to contribute to his content and ideas.</para>
<para>Copyright 2002, Avi Alkalay.</para>
<para>Can be found on-line in <ulink url="http://avi.alkalay.net/linux/docs/HighQuality/">http://avi.alkalay.net/linux/docs/HighQuality/</ulink>.</para>
<para>It was written originally in brazilian portuguese, and then translated to english. SGML and the more-then-incredible DocBook was used, that made possible this document being distributed in other formats, found in website.</para>
<para>It got ready (potuguese+english) in mid march 2002. Everything changed after this epoch is cosmetics.</para>
<para>I wrote it to help commercial companies and OpenSource developers make plug-and-play, easy-to-use software for Linux, and this way improve Linux usability and popularity.</para>
<para>All concepts (from a high level perspective) described here, can be used in any UNIX flavor, or even other OS, like Windows. Maybe some day I'll write one of these for Windows....or Mac....</para>
</appendix>
</article>

View File

@ -0,0 +1,67 @@
DOC=HighQuality
PKG=highquality
STYLE=docbook-utils.dsl
#STYLE=ldp.dsl
# To be processed by xsltproc, found in libxslt package.
XSL_STYLE=titlepage.tpl
SHAREDSRC=articleinfo.sgml conffile.sgml initd.sgml rc3d.sgml service.sgml chkconfig.sgml externalconf.sgml initscript.sgml nomethod.sgml rlevelchange.sgml manysouls.sgml $(STYLE) titlepage.xsl
MAINen=$(DOC).sgml
MAINpt=$(DOC).pt.sgml
.SUFFIXES: .sgml .html .pdf .ps .rtf .xsl
MAINSRC=$(MAIN) $(STYLE)
all: html
pdf: $(DOC).pdf $(DOC).pt.pdf
ps: $(DOC).ps $(DOC).pt.ps
html: $(DOC).html $(DOC).pt.html
rtf: $(DOC).rtf $(DOC).pt.rtf
clean:
rm -rf *.html *.pdf *.ps *.rtf *.tex *.out *.log *.aux *.xsl
$(DOC).html: $(MAINen) $(SHAREDSRC)
$(DOC).pt.html: $(MAINpt) $(SHAREDSRC)
titlepage.xsl: $(XSL_STYLE)
xsltproc -o $@ docbook/template/titlepage.xsl $(XSL_STYLE)
.sgml.html:
xsltproc -o $@ titlepage.xsl $<
.sgml.pdf:
jw -u -b pdf -d "$(STYLE)#print" $<
rm *html
.sgml.ps:
jw -u -b ps -d "$(STYLE)#print" $<
rm *html
.sgml.rtf:
jw -u -b rtf -d "$(STYLE)#print" $<
rm *html
dist: clean
if [ -z "$(ver)" ]; then \
echo "****** Need a version to be passed. Example: \"make ver=1.3 dist\"" >&2; \
else \
cd ..; \
find $(PKG) | cpio -H tar -o | gzip --best -c > $(PKG)-$(ver).tar.gz; \
fi
publish: all
if [ -z "$(out)" ]; then \
echo "****** Need an output directory to be passed. Example: \"make out=../out publish\"" >&2; \
else \
[ ! -d $(out) ] && mkdir -p $(out); \
cp -L $(DOC)*html $(out); \
cp -L -r docbook.css images/ $(out); \
fi

View File

@ -0,0 +1,117 @@
<copyright><year>2002</year><holder>Avi Alkalay</holder></copyright>
<authorgroup>
<author>
<firstname>Avi</firstname>
<surname>Alkalay</surname>
<affiliation>
<address>
<email>avi at br.ibm.com</email>
<email>avi at unix.sh</email>
</address>
<orgdiv>Senior IT and Software Architect :: OpenSource/Linux Solutions</orgdiv>
<orgname>IBM Linux Impact Team :: <ulink url="http://ibm.com/linux">ibm.com/linux</ulink></orgname>
</affiliation>
</author>
</authorgroup>
<pubdate>1.98 :: 2002/04/14</pubdate>
<revhistory>
<revision>
<revnumber>1.98</revnumber>
<date>14 Apr 2002</date>
<authorinitials>avi</authorinitials>
<revremark>Title changed from "Creating" to "Designing"</revremark>
</revision>
<revision>
<revnumber>1.97</revnumber>
<date>09 Apr 2002</date>
<authorinitials>avi</authorinitials>
<revremark>Converted to XML 4.1.2, and started to use real XSLT. Spell checked the english version.</revremark>
</revision>
<revision>
<revnumber>1.96</revnumber>
<date>23 Mar 2002</date>
<authorinitials>avi</authorinitials>
<revremark>Better HTML style sheets.</revremark>
</revision>
<revision>
<revnumber>1.95</revnumber>
<date>17 Mar 2002</date>
<authorinitials>avi</authorinitials>
<revremark>Last chapter: One Body, Many Souls. Created appendix. Still have to translate some words here and there.</revremark>
</revision>
<revision>
<revnumber>1.9</revnumber>
<date>16 Mar 2002</date>
<authorinitials>avi</authorinitials>
<revremark>Added universal software table with FHS</revremark>
</revision>
<revision>
<revnumber>1.7</revnumber>
<date>16 Mar 2002</date>
<authorinitials>avi</authorinitials>
<revremark>Everything is now translated except some words.</revremark>
</revision>
<revision>
<revnumber>1.3</revnumber>
<date>27 Feb 2002</date>
<authorinitials>avi</authorinitials>
<revremark>Translated and reviewed the most important section of the article: The /opt and /usr/local section.</revremark>
</revision>
<revision>
<revnumber>1.2</revnumber>
<date>23 Feb 2002</date>
<authorinitials>avi</authorinitials>
<revremark>English translation at 65%. Doing some corrections to potuguese version also.</revremark>
</revision>
<revision>
<revnumber>1.1</revnumber>
<date>17 Feb 2002</date>
<authorinitials>avi</authorinitials>
<revremark>Started english translation.</revremark>
</revision>
<revision>
<revnumber>1.0</revnumber>
<date>16 Feb 2002</date>
<authorinitials>avi</authorinitials>
<revremark>First final version of proposed skeleton.</revremark>
</revision>
<revision>
<revnumber>0.9.6</revnumber>
<date>16 Feb 2002</date>
<authorinitials>avi</authorinitials>
<revremark>Finished Plugin chapter.</revremark>
</revision>
<revision>
<revnumber>0.9.5</revnumber>
<date>15 Feb 2002</date>
<authorinitials>avi</authorinitials>
<revremark>Finished chapter about boot and subsystems.</revremark>
</revision>
<revision>
<revnumber>0.9.4</revnumber>
<date>14 Feb 2002</date>
<authorinitials>avi</authorinitials>
<revremark>Finished chapter describing the boot process</revremark>
</revision>
<revision>
<revnumber>0.9.3</revnumber>
<date>08 Feb 2002</date>
<authorinitials>avi</authorinitials>
<revremark>Text and style updates</revremark>
</revision>
<revision>
<revnumber>0.9.2</revnumber>
<date>07 Feb 2002</date>
<authorinitials>avi</authorinitials>
<revremark>Text updates</revremark>
</revision>
<revision>
<revnumber>0.9</revnumber>
<date>06 Feb 2002</date>
<authorinitials>avi</authorinitials>
<revremark>First translation to DocBook</revremark>
</revision>
</revhistory>