<!doctype debiandoc SYSTEM>

<book>
<title> Partition Management for the Debian Installer </title>
<author>
	<name>Anton Zinoviev</name><email>anton@lml.bas.bg</email>
</author>

<copyright>
<copyrightsummary> &copy;&nbsp;2003,2004,2007 Anton Zinoviev </copyrightsummary>

<p> This manual is free software; you may redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version&nbsp;2, or
(at your option) any later version.

<p> This is distributed in the hope that it will be useful, but
<em>without any warranty</em>; without even the implied warranty of
merchantability or fitness for a particular purpose.  See the GNU
General Public License for more details.
    
<p> A copy of the GNU General Public License is available as
<tt>/usr/share/common-licenses/GPL</tt> in the Debian GNU/Linux
distribution or on the World Wide Web at the <url
id="http://www.gnu.org/copyleft/gpl.html" name="GNU website">. You can
also obtain it by writing to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.

</copyright>
      
<toc>
    
<chapt> Introduction

<p> There are many wishlist features that we might desire from any
installer of GNU/Linux and that are related to partitioning:
<list>
<item> The partitioner should support different file systems.  Some of
  them need more care than only libraries and suitable arguments for
  <prgn>mount</prgn>.

<item> It should support not only regular partitions but also software
  RAID and LVM as well as encrypted file systems.

<item> It should be able to partition disks automatically and allow
  the user to inspect and customise the automatic partitioning
  later.

<item> It should be able to resize partitions and move their contents
from one place to another.

<item> The users should be protected from mistakes &ndash; by allowing
them to undo their partitioning operations.

<item> The partitioner should discover that there is already some
  installed GNU/Linux system and analyse its <prgn>fstab</prgn>,
  <prgn>passwd</prgn>, etc. in order to provide an automatic upgrade from
  the old already installed GNU/Linux system to the new one.
</list>

<p> One nice feature of the Debian installer is that it is modular.
  Its components are packaged in separate udebs and they can have
  relatively independent development process.  This document describes
  how we can solve all mentioned tasks keeping the Debian installer as
  modular as it is now.  Ideally in order to add some new feature only
  a few new udebs must be all that is needed &ndash; no changes in the
  existing udebs and no recompilation would be required.

<p> The script <file>partman</file> from the package
<package>partman-base</package> opens the main partitioning menu; it may
look like this one:
<example>
+------------------+ [!!] Partition the storage devices +-----------------+
|             Partition, free space or device to be modified              |
|                                                                         |
|        IDE1 master - Seagate U Series 40810 (40.0 GB)                   |
|                 #3 primary    2.1 GB B F ext3       /                   |
|                    pri/log    4.4 GB     FREE SPACE                     |
|                 #5 logical    3.6 GB                                    |
|                 #7 logical   10.0 GB   F ext3       /usr                |
|                 #8 logical   19.9 GB   K ext2       /home               |
|        IDE2 master - Maxtor 6Y120L0 (122.9 GB)                          |
|                 #7 logical    1.0 GB     linux-swap                     |
|                    logical  114.5 GB     FREE SPACE                     |
|                 #5 logical    5.5 GB     reiserfs                       |
|                 #6 logical    1.9 GB                                    |
|                                                                         |
|        Undo changes to partitions                                       |
|        Finish partitioning and write changes to disk                    |
|                                                                         |
|      &lt;Go Back&gt;                                          &lt;Continue&gt;      |
|                                                                         |
+-------------------------------------------------------------------------+
</example>

<p> When the users choose some free space they are offered to create a
new partition just like they are in <prgn>cfdisk</prgn>.  When users
choose a partition they are offered with a menu with various editing
operations:

<example>
+------------------+ [!!] Partition the storage devices +-----------------+
|                    Settings on the partition:                           |
|                                                                         |
|           Usage method:          format the partition                   |
|           File system:           ext3                                   |
|           Mount point:           /var/mail                              |
|           Mount options:         noatime,nodev,nosuid,noexec,usrquota   |
|           Bootable flag:         off                                    |
|           Size:                  995.2 MB                               |
|                                                                         |
|           Finished setting up partition                                 |
|           Copy here data from another partition                         |
|           Delete the partition                                          |
|                                                                         |
|      &lt;Go Back&gt;                                          &lt;Continue&gt;      |
|                                                                         |
+-------------------------------------------------------------------------+
</example>

<p> All udebs are allowed to add items to this menu as well as to
several other menus.  They can add new items in the list of devices
such as software RAID and LVM devices, networked file systems,
encrypted partitions, etc.  The package
<package>partman-partitioning</package> is responsible for pure
partitioning operations such as creation of new partitions and
deletion.  The packages <package>partman-target</package> and
<package>partman-basicmethods</package> are responsible for the items
`Choose how this partition should be used' and `Choose a file system'.
The package <package>partman-basicfilesystems</package> adds support
for <tt>ext2</tt>, <tt>linux-swap</tt>, <tt>fat16</tt> and
<tt>fat32</tt>.  The package <package>partman-ext3</package> adds
support for <tt>ext3</tt>.

<chapt> Changes in partman since 2005

<p> This chapter documents important changes in the sctructure of
partman.  It is provided as a test if you need to reread some of the
sections in this document.

<list>
<item> New directory <prgn>check.d</prgn> with some of the scripts
formerly in <prgn>finish.d</prgn>
<item> New directory <prgn>display.d</prgn> with different methods to
do the partitioning (manual, automatic, etc.)
<item> New command GET_LABEL_TYPE in parted_server
</list>

<chapt> Package interrelations

<sect id="basics"> Basics

<p> The GNU Parted disk partitioning library provides high-level,
  architecture independent functions for operations such as creating,
  deleting, resizing and moving of partitions as well as creating some
  kinds of file systems.  Most of the functions of libparted work in a
  non nondestructive way.  The partition table is written in data
  structures and any change in the partition table happens only in
  these data structures rather than directly on the disk.  This makes
  possible to implement partitioning tools based on
  <package>libparted</package> that support undoing of the editing
  operations.

<p> However we have to solve two problems.  The first is that we want
to use as much as possible shell scripts rather than C programs.  The
second is that different programs have to operate with same instance
of libparted structures.  For example the user can use some tool for
automatic partitioning, then correct or customise the automatic
partitioning, perform some other arbitrary operations being still
allowed to undo everything.

<p> There is one obvious solution of these two problems &ndash; we
keep the data structures of libparted in a daemon process and
communicate with it in order to make changes in these data structures.
This process is <file>/bin/parted_server</file> from the package
<package>partman-base</package>.

<p> The scripts from <file>/lib/partman/init.d/</file> are executed
  before all partitioning operations.  They can be used to initialise
  the partitioning system.  The scripts may be invoked more than once
  in which case they should behave properly.  For example this
  directory can contain a script to discover the existing hard drives.
  If invoked for second time the script must either do nothing or
  check if there is some new kernel module giving access to new still
  undiscovered device.

  <p> Any udeb may install a script in this directory.  For example
the script <file>/lib/partman/init.d/30parted</file> from the package
<package>partman-base</package> is responsible for running
<prgn>parted_server</prgn>.  Notice that the scripts are prefixed by a
two-digit number.  This number determines the order the scripts are
executed.  If any of the scripts exit with non-zero exit code the
partitioning will be aborted.  This means that in almost all cases
these scripts must end with exit-code 0.

<p> When the initialisation completes, the scripts from
<file>/lib/partman/display.d</file> are executed.  These scripts are
supposed to make the actual partitioning interactively or
non-interactively.  The exit code <var>code</var> of these scripts is
interpreted as follows:
<taglist compact>
<tag><var>code</var> = 0<item>The script did nothing, move to the next
script in <prgn>display.d</prgn>.
<tag>1 &lt;= <var>code</var> &lt;= 99<item>Restart the partitioning (move
again to the first script in <prgn>display.d</prgn>).
<tag>100 &lt;= <var>code</var> &lt;= 254<item>The script succesfuly
partitioned the disks, do not execute the following scripts in
<prgn>display.d</prgn>.
<tag><var>code</var> = 255<item>Abort the partitioning.
</taglist>

<p> When the disks become ready, the scripts in
<file>/lib/partman/check.d</file> are executed.  They have to check if
everything is OK to proceed with commiting the changes on the disks,
mounting file systems, etc.  For example the package
<package>partman-target</package> installs there a script to check if
there is a root file system.  If a script in <prgn>check.d</prgn>
exits with non-zero exit code then the scripts in
<prgn>display.d</prgn > are executed again and as a result the user is
allowed to fix the partitioning.

<p> The directory <prgn>check.d</prgn> is remarkable with the fact
that some of the scripts in it are installed by non-partman packages.
The packages for the various bootloaders (lilo, grub, palo, etc.)
install there scripts to ensure the partitioning scheme conforms to
their requirements.

<p> While the user is modifying the partitions this happens only in
  the memory of the computer and not in the edited devices.  This is
  because almost all changes happen either in the data-structures of
  <prgn>parted_server</prgn> or in files in the installer's ram-disk.
  That's why we can provide the user with the option to undo
  everything.  When the user chooses to undo the scripts in the
  directory <file>/lib/partman/undo.d/</file> are executed.  Any udeb
  may install a script in this directory.  For example the script
  <file>/lib/partman/undo.d/30parted</file> is responsible for
  restoring the contents of the data structures of
  <prgn>parted_server</prgn>.  In most cases the scripts from
  <prgn>undo.d</prgn> must exit with exit-code 0.  If any of the
  scripts exit with non-zero exit code the partitioning will be
  aborted.

<p> In order to perform the editing operations on the storage devices
(and in particular to transfer the partitions from the internal
data-structures of <prgn>parted_server</prgn> to the hard disks) the
scripts from the directory <file>/lib/partman/commit.d/</file> are
executed.  The order in which these scripts are executed is determined
again by two-digit prefixes in the script names.  Every script from
<prgn>commit.d</prgn> is guaranteed that the scripts ordered before it
have been already executed.  However if any of the scripts exit with
non-zero exit-code the execution of the scripts in
<prgn>commit.d</prgn> will be stopped.  In this case the partitioning
will continue and the user is expected to fix the problem.  If any
script exits with non-zero exit code it is supposed to inform the user
what went wrong using debconf.

<p> There are two cases when the scripts from <prgn>commit.d</prgn>
are executed.  The first case is when the user wants to commit the
changes to the disks but continue partitioning.  The second case is
when the partitioning ends.  In the first case if none of the scripts
fails the scripts from <prgn>init.d</prgn> will be also executed and
the user will be returned to the partitioning dialog.  In the second
case the scripts from <prgn>finish.d</prgn> will be executed.  In both
cases if any of the scripts in <prgn>commit.d</prgn> fail the user
will be returned immediately back to the partitioning dialog.

<p> The scripts from <file>/lib/partman/finish.d/</file> are
responsible for final tasks such as to mount partitions on
<file>/target</file>, generate of <prgn>fstab</prgn>, stop
<prgn>parted_server</prgn> etc.<footnote>What tasks will be performed
depends on what udebs are unpacked.  If the packages responsible for
mounting partitions and creating fstab are not unpacked we have only a
simple partitioner providing
<package>partitioned-harddrives</package>.  If they are unpacked they
provide also <package>made-filesystems</package> and
<package>mounted-partitions</package>.</footnote> If any of these
scripts exit with non-zero exit-code the execution of the scripts
will be stopped.  If the exit-code was 1 then the user will be
returned back to the partitioning dialog and is expected to correct
the problem.  If the exit-code was neither 0 nor 1 then the
partitioning will be aborted.

<p> For every hard disk in the system the script
<file>/lib/partman/init.d/30parted</file> creates a subdirectory in
<file>/var/lib/partman/devices/</file> and informs
<prgn>parted_server</prgn> that the device is to be edited (`opens'
the device).  All udebs that provide storage device (software RAID,
LVM, encrypted partitions) must do the same.  This subdirectory must
contain at least three files &ndash; <prgn>device</prgn>,
<prgn>model</prgn> and <prgn>size</prgn>.  The first contains the name
of a device file (for example
<file>/dev/ide/host0/bus0/target0/lun0/disc</file>).  The second
contains the name of the device (for example `Maxtor 6Y120L0').  The
third contains the physical size of the storage device (in bytes, for
example `122942324736').  <footnote>Please notice that udebs that
provide support for storage `devices' that cannot be partitioned
(such as networked file systems) should not create a subdirectory in
<file>/var/lib/partman/devices</file> and certainly cannot provide
the device to the management of <prgn>parted_server</prgn>.</footnote>
The subdirectories of <file>/var/lib/partman/devices/</file> can but
are not obligated to contain additional information.  We call these
subdirectories <em>device directories</em>.

<p> Every partition in a device managed by <prgn>parted_server</prgn>
is given a unique name having the form
<var>first_byte</var>-<var>last_byte</var>.  This name can be used to
determine where the partition starts and where it
ends.<footnote>Unlike one can suppose <prgn>parted_server</prgn>
always measures sizes and places in bytes rather than in sectors.
<var>Last_byte</var> is the number of the last byte of the last sector
of the partition.</footnote> If the device directory contains a
subdirectory named
<prgn><var>first_byte</var>-<var>last_byte</var></prgn> then this
subdirectory stores information about the partition.  We call this
subdirectory <em>directory of the partition</em>.  We call the
string<var>first_byte</var>-<var>last_byte</var> `<em>id</em>' of the
partition.


<sect id="menudirs"> Menu-directories

<p> There are several menus involved in partitioning.  In order to
keep the Debian installer modular and extensible we want to allow
every udeb to install items in these menus.  Let us be more specific.
When the users decide to format some existing partition we need a menu
with an item for every supported file system.  Obviously we don't want
to hardwire the list of the supported file systems anywhere in our
installer.  If we want to add support to the installer say for XFS or
UMSDOS file systems, only a few new udebs must be all that is needed.

<p> In order to achieve this flexibility the package
 <package>partman-base</package> provides support for the so-called
 menu-directories.  Every such a directory contains files named
 <prgn>question</prgn> and <prgn>priority</prgn>.  They contain the
 name of a Debconf template and the priority of the question
 correspondingly.  The template must have exactly the following type
 and choices fields:
<example>
Type: select
Choices-C: ${CHOICES}
Choices: ${DESCRIPTIONS}
</example>

<p> All other files in the menu directory are subdirectories.  Any
 udeb can install such a subdirectory in order to add items to the
 menu.  For example the udebs for software RAID volumes can install in
 the menu of the editing operations an item to resize the chosen
 partition to have the same size as another.  These subdirectories
 must contain two scripts &ndash; <prgn>choices</prgn> and
 <prgn>do_option</prgn>.  The purpose of the first script is to print
 menu items.  For every menu item <prgn>choices</prgn> must print a
 line having the form

<example>
<var>menu_item_id</var>&lt;TAB&gt;The text for the user
</example>

<p> The script <prgn>choices</prgn> is allowed to print nothing.  In
this case no item for the menu is created.  Here <tt>&lt;TAB&gt;</tt>
is ASCII&nbsp;9.  The text `The text for the user' will be presented
to the users.  If they choose this particular menu item the script
<prgn>do_option</prgn> will be invoked.

<p> The script <prgn>choices</prgn> may be given some arguments
  depending on the particular menu-directory.  The first argument
  given to <prgn>do_option</prgn> is always the
  <var><tt>menu_item_id</tt></var> of the chosen menu item.  The rest
  of the arguments are the same as the arguments given to
  <prgn>choices</prgn>.

<p> Let we take as an example the menu that the users see when they
  choose to edit some particular partition.  The file
  <prgn>question</prgn> in the menu-directory for this menu contains
  the text <tt>partman/active_partition</tt>.  This is the name of a
  Debconf-template with type `select' and description `Please choose
  what to do with this partition'.  The package
  <package>partman-partitioning</package> installs in this
  menu-directory some subdirectories &ndash;
  <prgn>62change_name</prgn>, <prgn>65toggle_bootable</prgn> and
  <prgn>85delete</prgn>.  The script
  <file>62change_name/choices</file> is given two arguments &ndash;
  the hard disk we edit and the id of the partition.  It checks if the
  type of the partition table supports partition names in which case
  it prints the line
<example>
setname&lt;TAB&gt;Set the name of the partition
</example>
If the partition table doesn't support names, then this script prints
nothing.  When the user chooses to `set the name of the partition' the
script <file>62change_name/do_option</file> is invoked.  Its first
argument is <tt>setname</tt> (this is the first part of the line
printed by <prgn>choices</prgn>) and the other arguments are the same
to the arguments given to the script <prgn>choices</prgn>.  In our
case the script <prgn>do_option</prgn> ignores its first argument.
The script <prgn>do_option</prgn> can use its first argument in order
to determine which menu item the user has chosen in cases when
<prgn>choices</prgn> has printed several.

<p> Notice that the names of the subdirectories in any menu-directory
start with two digits.  They are used to determine the order of the
items in the menu.

<sect> Partitioning

<p> The partitioning starts with the menu of the menu-directory
<file>/lib/partman/choose_partition</file>.  This is the main
partitioning menu.  Every udeb is allowed to install new items in it.
If the script <prgn>do_option</prgn> exits with exit-code 0 the user
will be shown again the main partitioning menu.  If the script exits
with exit-code 100 this means that the partitioning should be
finished.  In this case the scripts from <prgn>commit.d</prgn> and
<prgn>finish.d</prgn> will be executed as described in <ref
id="basics">.  If the script <prgn>do_option</prgn> exits with exit
code 255 the partitioning will be aborted immediately.

<p> The main partitioning menu always contains an item for every
partitioned storage device, an item for every partition and an item
for every free space.

<p> If the user chooses a storage device the menu of the
menu-directory <file>/lib/partman/storage_device</file> will be
opened.  The first argument given to <prgn>choices</prgn> is the
device directory<footnote>We are not going to describe the arguments
given to <prgn>do_option</prgn>.  Look at <ref id="menudirs">.</footnote>.

<p> If the user chooses a free space the menu-directory
<file>/lib/partman/free_space</file> will be opened.  The first
argument given to <prgn>choices</prgn> is the device directory.  The
second argument is the id of the free space.

<p> If the user chooses an active partition the menu-directory
<file>/lib/partman/active_partition</file> will be opened.  The first
argument given to <prgn>choices</prgn> is the device directory.  The
second argument is the id of the chosen partition.  If the script
<prgn>do_option</prgn> exits with exit-code 0 the user will be shown
again the menu <prgn>active_partition</prgn> for the same partition.
If the script <prgn>do_option</prgn> exits with exit-code 100 or 255
the user will be returned back to the main partitioning menu.  This
should happen when the id of the partition is invalidated, for example
when the partition is deleted or resized.

<p> In the main partitioning menu the partitions are presented by
lines of this kind:
<example>
#8 primary   19.9 GB   K ext2       /home
</example>
Notice that it is useless to indicate that the partition is primary if
the type of the partition table is `mac' as this partition table
doesn't support logical partitions.  On the other hand this partition
table supports partition names.  We see that we need a flexible way to
determine how the partitions are presented in the main partitioning
menu.

<p> The directory <file>/lib/partman/visual.d</file> contains scripts
that print the parts of the partition line.  For example the script
<file>/lib/partman/visual.d/filesystem</file> prints strings like
`ext3' or `FREE SPACE'.  These scripts usualy start with the following
cliche:

<example>
cd $1

num=$2
id=$3
size=$4
type=$5
fs=$6
path=$7
shift; shift; shift; shift; shift; shift; shift
name=$*
</example>
$1 is the device directory.  $num is the number of the partition (for
example <file>/dev/hda6</file> has number 6).  $id is the id of the
partition.  $size is the size of the partition (in bytes).  If this is
an active partition then $type is either `primary' or `logical'.  If
this is a free space then $type shows what partition can be created in
it and $type can be `primary', `logical', `pri/log' or `unusable'.
$fs is `free' if this is a free space.  Otherwise $fs is the type of
the file system of this partition as known to
<prgn>parted_server</prgn>.  $path is a device name for the partition,
for example <file>/dev/ide/host0/bus0/target0/lun0/part6</file>.
$name is the name of the partition or the empty string if the
partition table doesn't support partition names.

<p> The script <file>/lib/partman/commit.d/30parted</file> transfers
the partition tables from the internal structures of
<prgn>parted_server</prgn> to the disks.  The script
<file>/lib/partman/finish.d/80parted</file> stops
<prgn>parted_server</prgn>.

<p> The package <package>partman-base</package> installs in
<prgn>update.d</prgn> (see <ref id="update_partitions">) a script to
ensure that for every partition that contains some file system there
is a file <prgn>detected_filesystem</prgn> in the directory of the
partition whose contents is the type of the detected file system as
returned by <prgn>parted_server</prgn>.

<sect> Setup <file>/target</file>

<p> Without the package <package>partman-target</package> the packages
<package>partman-base</package> and <package>partman-partitioning</package>
provide only the regular partitioning operations.  However if the
package <package>partman-target</package> is also unpacked then the
user will be provided with options to choose file systems for the
partitions, specify wether they should be formatted and select mount
points.  The package <package>partman-target</package> adds to the
menu directory <file>/lib/partman/active_partition</file> the item
`Usage method:'.  If the user chooses this item the menu directory
<file>/lib/partman/choose_method</file> will be opened.  The scripts
<prgn>choices</prgn> from <prgn>choose_method</prgn> are given the
device directory as first argument and the partition id as second
argument.

<p> The package <package>partman-basicmethods</package> adds in the
menu of the menu directory <prgn>choose_method</prgn> three items: `Do
not use the partition', `Format the partition' and `Keep and use the
existing data in the partition' (the last only if some file system is
detected).  Other udebs can provide another methods to use partitions.

<p> Every partition that is to be used somehow in the future Debian
system should have a file named `method' in its directory (what is
`directory of a partition' is described in <ref id="basics">).  The
scripts <prgn>do_option</prgn> of the menu directory
<prgn>choose_method</prgn> manage the file <prgn>method</prgn>.  It
contains the name of the usage method chosen by the user.  For
example if the user chooses to `format the partition' the contents of
this file will be `format' and if the user chooses to `keep and use
the existing data' the contents of this file will be `keep'.
Partitions that won't be used do not have a file <prgn>method</prgn>.

<p>The udebs providing methods may provide also translatable names of
the methods for the user interface using debconf templates named
<prgn>partman/method_long/<var>some_method</var></prgn> and
<prgn>partman/method_short/<var>some_method</var></prgn>.  For example
the package <package>partman-palo</package> providing method
<prgn>palo</prgn> can provide also the following debconf templates:

<example>
Template: partman/method_long/palo
Type: text
_Description: Palo boot partition

Template: partman/method_short/palo
Type: text
_Description: Palo
</example>

<p> Another job for the scripts <prgn>do_option</prgn> of the menu
directory <prgn>choose_method</prgn> is to create or remove a file
named <prgn>use_filesystem</prgn> in the directory of the partitions.
This file is created when the usage method requires the partition to
be used together with some file system.  Otherwise it is removed.
Example methods that are used together with a file system are `format
the partition' and `keep and use the existing data'.  Example methods
that are not used together with a file system are `LVM physical
volume' and `PALO boot partition'.

<p> Finaly, the scripts <prgn>do_option</prgn> of the menu directory
<prgn>choose_method</prgn> have to create or remove a file named
`format' in the directory of the partitions.  If the partition
directory contains a file named <prgn>format</prgn> then it will be
formatted.  Otherwise it will not be formatted.  For example if the user
chooses to `format the partition' the script <prgn>do_option</prgn>
will create a file <prgn>format</prgn>.  If the user chooses to `keep
and use the existing data' the file <prgn>format</prgn> will be
removed if it exists.

<p> The menu item `Choose a file system' in the menu directory
<prgn>active_partition</prgn> is also provided by the package
<package>partman-target</package>.  If the user chooses it the menu
<prgn>choose_filesystem</prgn> will be opened.  This menu however is
not produced using a menu directory.

<p> Packages that provide support for some file system should install
a script in the directory <file>/lib/partman/valid_filesystems</file>.
The first argument given to this script is some device directory, the
second argument is the id of some partition and the third argument is
one of the strings `formatable' and `existing'.  If it is `formatable'
then the job of the script is to check if the specified partition can
be formatted and used.  If the third argument is `existing' then the
job of the script is to check if the partition can be used without
formatting.  In either case if the partition can be used then the
script should print a line with the identifier of the type of the file
system.

<p> Packages that provide support for some file systems use the
directory <file>/lib/partman/parted_names</file> to define a mapping
from the unique file system type identifiers to the names used by
<prgn>parted_server</prgn>.  Suppose for example that the package
providing support for UMSDOS file system chooses the string `umsdos'
as unique identifier for the file system.  Then this package must
install in this directory a file named <prgn>umsdos</prgn> whose
contents is the string `fat16'.  This means that
<prgn>parted_server</prgn> will know UMSDOS file systems as being
fat16 file systems.

<p>The udebs providing file systems may provide also translatable
names of the file systems for the user interface using debconf
templates named
<prgn>partman/filesystem_long/<var>some_filesystem</var></prgn> and
<prgn>partman/filesystem_short/<var>some_filesystem</var></prgn>.  For
example the package <package>partman-ext3</package> providing file
system with unique identifier <prgn>ext3</prgn> can provide also the
following debconf templates:

<example>
Template: partman/filesystem_long/ext3
Type: text
_Description: Extended 3

Template: partman/filesystem_short/ext3
Type: text
_Description: Ext3
</example>

<p> Most of the packages that provide support for a file system will
have to add an item `Mount point:' to the menu
<prgn>active_partition</prgn>.  Of course this item should be shown
only when the contents of the file <prgn>acting_filesystem</prgn> is
appropriate.  The mount point chosen by the user should be written in
a file named <prgn>mountpoint</prgn> situated in the directory of the
partition.  If the user chooses not to mount this file system then the
file <prgn>mountpoint</prgn> should be removed (if it exists).

<p> In order to be able to mount file systems and generate fstab the
  directories <file>/lib/partman/fstab.d/</file> and
  <file>/lib/partman/mount.d/</file> are used.  The scripts from
  <prgn>fstab.d</prgn> should print lines in a form similar to that of
  <file>/etc/fstab</file>:
<example>
<var>file_system</var>   <var>mount_point</var>   <var>type</var>    <var>options</var>  <var>dump</var>  <var>pass</var>
</example>

  The first field (<var><tt>file_system</tt></var>) is the name of a
  device that can be accessed by the installer.  For example this can
  be <file>/dev/ide/host0/bus0/target0/lun0/part5</file> despite that
  in the future system this device will be named
  <file>/dev/hda5</file>.  On the other hand the other five fields
  should look exactly the same way as in the <prgn>fstab</prgn> to be
  generated.  For example <var><tt>options</tt></var> can contain
  options such as <tt>quota</tt> that are senseless for the installer.

<p> The scripts from <prgn>mount.d</prgn> are used to mount file
  systems.  A string having the same form as the lines output by the
  scripts from <prgn>fstab.d</prgn> should be given as first argument
  to any script from <prgn>mount.d</prgn>.  Any script from
  <prgn>mount.d</prgn> checks if it can mount the requested file
  system.  If it cannot then the script exits with some non-zero exit
  code.  Otherwise the script must mount the file system in the proper
  place in the hierarchy over <file>/target</file>, print on its
  standard output a command that should be used in order to unmount
  the file system and exit with exit code 0.

<p> The scripts in the directories <prgn>fstab.d</prgn> and
<prgn>mount.d</prgn> are installed by the udebs that provide support
for file systems.

<p> Packages that provide support for file systems install in
<prgn>commit.d</prgn> a script to format the partitions that the user
has requested to be formatted.  The package
<package>partman-target</package> installs in <prgn>finish.d</prgn> a
script to mount the partitions on <file>/target</file>.  The packages
that provide support for storage devices (RAID, LVM, etc.) install in
<prgn>finish.d</prgn> a script to add in
<file>/target/etc/fstab</file> the necessary lines.

<p> The package <package>partman-target</package> installs in
<prgn>update.d</prgn> (see <ref id="update_partitions">) a script to
ensure that for every partition that is to be used there is a file
<prgn>acting_filesystem</prgn> in the directory of the partition whose
contents is the identifier of the type of file system under which the
partition should be used.

<chapt> <file>/lib/partman/lib/*</file>

<p> Various scripts in partman make use of <em>function libraries</em>:
separate files, mostly containing shell functions, that are sourced
by scripts so they can make use of common functions and code duplication
can be avoided.

<p> The main function library is <file>base.sh</file>, provided by
<package>partman-base</package>.  This file is sourced by most scripts
in partman as it defines a lot of useful variables and common functions.
Some of these are documented in the remainder of this chapter.
<footnote>The script <file>base.sh</file> has become somewhat too long and
this probably makes its sourcing slow.  Although some reorganization has
already taken place, it could be a good idea to split it up further.</footnote>

<p> Other packages provide more targeted function libraries.  In most cases
their scope and use can easily be determined from their name.

<sect> Environment

<p> The variables <tt>TAB</tt> and <tt>NL</tt> have values
ASCII&nbsp;9 and ASCII&nbsp;10 correspondingly.  They can be used as
temporary values for the variable <tt>IFS</tt>.  The function
<prgn>restore_ifs</prgn> restores the variable <tt>IFS</tt> its
original value.

<p> The function library <prgn>base.sh</prgn> also contains simple
reimplementations of <prgn>basename</prgn> and <prgn>dirname</prgn> so
that busybox doesn't have to provide them.


<sect> Menus

<p> The function <prgn>debconf_select</prgn> is a high level function
  to ask user with a menu using a Debconf question with type `select'.
  Synopsis:
<example>
debconf_select <var>priority</var> <var>template</var> <var>choices</var> <var>default</var>
</example>

<p> The first argument is the debconf-priority of the question and the
  second is the name of the template to be used.  The third argument
  is a newline-separated list of items for the menu.  Each item has
  the form
<example>
<var>menu_item_id</var>&lt;TAB&gt;The text for the user
</example>

<p> Here <tt>&lt;TAB&gt;</tt> is ASCII&nbsp;9.  The text `The text for
 the user' is the text of the menu item.  If
 <var><tt>menu_item_id</tt></var> of some menu-item is identical with
 the fourth argument given to <prgn>debconf_select</prgn> then this
 menu-item will be default.

<p> If the user cancels the question <prgn>debconf_select</prgn>
 returns with exit-code 255.  Otherwise the value of the variable
 <tt>RET</tt> will be the <var><tt>menu_item_id</tt></var> of the
 chosen menu item.  If the chosen menu item was chosen by the user
 then the exit-code is 0.  If the item was chosen automatically (due
 to the debconf-priority or to some other reason) the exit-code is 1.

<p> The function <prgn>debconf_select</prgn> doesn't care
  to <prgn>db_fset</prgn> <tt>$template</tt> <tt>seen</tt> <tt>false</tt>.
  The template must have exactly the following type and choices fields:
<example>
Type: select
Choices-C: ${CHOICES}
Choices: ${DESCRIPTIONS}
</example>

<p> The udebs that generate menus using menu-directories use the
  function <prgn>ask_user</prgn> instead of
  <prgn>debconf_select</prgn>.  Synopsis:

<example>
ask_user <var>a_menu_directory</var> <var>aditional_optional_arguments</var>...
</example>

<p> This function displays the menu for
  <tt><var>a_menu_directory</var></tt>.  The first argument is a
  menu-directory (see <ref id="menudirs">).  If the user cancels the
  dialog then <prgn>ask_user</prgn> returns with exit code 255.
  Otherwise it returns with the exit code of the script
  <prgn>do_option</prgn>.

<p> If <prgn>ask_user</prgn> is called re-entrantly from within a
<prgn>do_option</prgn> script, then the calling <prgn>do_option</prgn>
script should typically be careful to handle or discard exit code 255
itself (and sometimes other codes, depending on the protocol in force)
to avoid a backup operation inadvertently backing up out of several
nested menus at once.

<p> The script <prgn>choices</prgn> is invoked with
<var><tt>aditional_optional_arguments</tt></var> as arguments.  The
first argument given to <prgn>do_option</prgn> is the
<var><tt>menu_item_id</tt></var> of the chosen menu item and the
other arguments are again
<var><tt>aditional_optional_arguments</tt></var>.

<p> To set the default selected item in a menu-directory, use the function
  <prgn>menudir_default_choice</prgn>. Synopsis:

<example>
menudir_default_choice <var>a_menu_directory</var> <var>subdirectory</var> <var>menu_item_id</var>
</example>

<p> Where the <var><tt>subdirectory</tt></var> is the name of a
subdirectory in the menu-directory with the leading sequence number
stripped off and <var><tt>menu_item_id</tt></var> is the id of a
menu-item printed by
<file><var>a_menu_directory</var>/??<var>subdirectory</var>/choices</file>.
The specified item is set as default not forever but only for the next
invocation of <prgn>ask_user</prgn>.  It is not an error to set as
default non-existing item; in this case the first item in the menu
will be default.

<p> The function <prgn>partition_tree_choices</prgn> prints a sequence
of lines in the form
<example>
<var>menu_item_id</var>&lt;TAB&gt;The text for the user
</example>
&ndash; one for every storage device and one for every partition.  The
<var><tt>menu_item_id</tt></var> of the storage devices is their
storage directory.  The <var><tt>menu_item_id</tt></var> of the
partitions has the form
<var>storage_directory</var>//<var>partition_id</var>.  The output of
<prgn>partition_tree_choices</prgn> can be given as third argument to
<prgn>debconf_select</prgn>.


<sect> Long numbers

<p> Notice that the sizes of most of the present storage devices
are so large that we cannot measure them using 32-bit integers.
Consequently we cannot use the usual shell arithmetic. The functions
<prgn>longint_le</prgn>, <prgn>longint2human</prgn>,
<prgn>human2longint</prgn> and <prgn>valid_human</prgn> exist in order
to deal with such big numbers.

<p> The function <prgn>longint_le</prgn> is used to compare two big
numbers.
<example>
longint_le <var>number1</var> <var>number2</var>
</example>
returns with exit code&nbsp;0 if the first number is less or equal to
the second and returns 1 otherwise.

<p> The function <prgn>longint2human</prgn> accepts in its first
argument some number of bytes, converts it to something that is more
meaningful for humans and outputs the result.  For example
<example>
longint2human 1234567890
</example>
gives <tt>1.2 GB</tt>.  Notice that this function rounds its
argument.

<p> The function <prgn>human2longint</prgn> is used for the opposite
convertion:
<example>
human2longint 1.234Gb
</example>
gives <tt>1234000000</tt>.

<p> The function <prgn>valid_human</prgn> returns with exit
code&nbsp;0 when its first argument is a string that is suitable to be
given to <prgn>human2longint</prgn>.  Otherwise it returns with exit
code&nbsp;1.

<sect id="update_partitions"> Updating partition directories

<p> Different components of the installer may need to get information
about the partitions.  They can communicate with
<prgn>parted_server</prgn> in order to know the characteristics of the
partition.  However not everything can be known from
<prgn>parted_server</prgn>.  Imagine an udeb that provides the user
with the option to upgrade some existing GNU/Linux installation.  This
udeb analyses the <prgn>fstab</prgn> and knows that some partition is
used as <file>/home</file> and should not be formatted.  This sort of
information has nothing to do with <prgn>parted_server</prgn>.  The
udeb stores it in a subdirectory of the device directory named after
the id of the partition.

<p> But now a problem arises.  Suppose that the user chooses to format
some partition as ext2 and mount it on <file>/home</file>.  The udebs
responsible for formatting and mounting create the directories
<prgn>filesystem</prgn> and <prgn>mountpoint</prgn> in the partition.
What will happen if the users change their mind and decide to use the
same partition as swap space?  Swap spaces have no mount points and
the file <prgn>mountpoint</prgn> should be removed.  Who is
responsible for removing it?  The udeb that allows the user to choose a
file system for the partition doesn't have to know that swap-spaces
have no mount points, only the udeb that provides support for
swap-spaces can know that the file <prgn>mountpoint</prgn> should be
removed.

<p> In order to solve this difficulty every script that makes changes
to some partition should invoke the function
<prgn>update_partition</prgn> from <prgn>base.sh</prgn>.
Synopsis:
<example>
update_partition <var>device_directory</var> <var>partition_id</var>
</example>
In order to update the contents of the directory
<file><var>device_directory</var>/<var>partition_id</var></file> the
function <prgn>update_partition</prgn> executes the scripts from the
directory <file>/lib/partman/update.d/</file>.  Every udeb is allowed
to install scripts in this directory.  Their names are prefixed by
two-digit numbers that control the order of the execution.  The
scripts from <prgn>update.d</prgn> are given several arguments.  $1 is
the <var>device_directory</var>.  $2 is the number of the partition
(<file>/dev/hda6</file> will have number 6).  $3 is the id of the
partition.  $4 is the length of the partition (in bytes).  $5 is the
type of the partition, it can be either `primary' or `logical'.  $6 is
the type of the file system as known to <prgn>parted_server</prgn>, in
most cases you should ignore this argument.  $7 is the device name
(for example <file>/dev/ide/host0/bus0/target0/lun0/part6</file>).
"$8&nbsp;$9&nbsp;$10&nbsp;$11&nbsp;..." is the name of the partition
in partition tables that support partition names.  Otherwise $8, $9,
$10,... are not defined.

<sect> Communication with <prgn>parted_server</prgn>

<p> The package <package>partman-base</package> creates two FIFOs &ndash;
<file>/var/lib/partman/infifo</file> and
<file>/var/lib/partman/outfifo</file>.  <prgn>Parted_server</prgn>
reads instructions from <prgn>infifo</prgn> and responds by writting
to <prgn>outfifo</prgn>.  Consequently the clients write to
<prgn>infifo</prgn> and read from <prgn>outfifo</prgn>.  The function
library <prgn>base.sh</prgn> contain several functions to make the
communication with <prgn>parted_server</prgn> easier.  Here we will
omit the details, if you want to know the exact communication protocol
please read how these functions are implemented.

<p> The functions <prgn>open_infifo</prgn>, <prgn>close_infifo</prgn>,
<prgn>open_outfifo</prgn> and <prgn>close_outfifo</prgn> are called
without arguments.  They open and close <prgn>infifo</prgn> and
<prgn>outfifo</prgn> assigning them file descriptors 6 and 7
correspondingly.  You do not need to use these low-level functions.

<p> The function <prgn>write_line</prgn> prints its arguments to
<prgn>outfifo</prgn>.

<p> The function <prgn>read_line</prgn> reads from <prgn>infifo</prgn>
a line, splits it in fields according to <tt>$IFS</tt> and assigns
these fields to variables whose names are given to
<prgn>read_line</prgn> as arguments.  For example
<example>
read_line x y z
</example>
reads a line from <prgn>infifo</prgn>, splits it and assigns the first
field to the variable <tt>x</tt>, the second field to the variable
<tt>y</tt> and the rest to the variable <tt>z</tt>.  You see that
<prgn>read_line</prgn> is used the same way as the shell operator
<prgn>read</prgn>.

<p> The function <prgn>read_paragraph</prgn> reads consequently lines
from <prgn>infifo</prgn> until it reaches an empty line.  It prints
the read lines with the exception of the last empty line.

<p> The function <prgn>read_list</prgn> reads lines the same way as
the function <prgn>read_paragraph</prgn>.  However the function
<prgn>read_list</prgn> always prints only one line that is a
comma-separated sequence of the lines read from <prgn>infifo</prgn>.
If <prgn>read_paragraph</prgn> prints
<example>
This is the first line
This is the second line
This is the third line
</example>
<prgn>read_list</prgn> prints
<example>
This is the first line, This is the second line, This is the third line
</example>

<p> In order to initiate a communication dialog with
<prgn>parted_server</prgn> you will use the function
<prgn>open_dialog</prgn>.  You will invoke it in the device directory
of the device you want to issue command about.  The first argument of
<prgn>open_dialog</prgn> is a command for <prgn>parted_server</prgn>.
The rest arguments are arguments for the command.

<p> You use the function <prgn>close_dialog</prgn> in order to
terminate the communication dialog.

<p> When you send <prgn>parted_server</prgn> an order to do some
long operation (check, create, resize or copy file system) the user
will be shown a progress bar.  You may give name to it by the function
<prgn>name_progress_bar</prgn>.  It may be used right before the
command <prgn>open_dialog</prgn> and accepts only one argument &ndash;
a template with type text that describes what is being done.

<p> The function <prgn>log</prgn> appends its arguments to the file
<file>/var/log/partman</file>.  This file is used as log-file also by
<prgn>parted_server</prgn>.

<chapt> The commands of <prgn>parted_server</prgn>

<p> You should be very careful when you communicate with the
<prgn>parted_server</prgn>.  If <prgn>parted_server</prgn> detects any
error it will exit immediately.  This is safer approach then to try to
resolve somehow the error.  However this also means that the user will
not be shown any information about what happened and why the installer
freezed.  The log-file <file>/var/log/partman</file> can be used to
see the reasons why <prgn>parted_server</prgn> exited.

<sect> Open a new device

<p>Synopsis:
<example>
cd <var>device_directory</var>
open_dialog OPEN <var>device_name</var>
read_line status
close_dialog
case $status in
    OK)
        # The device has been opened successfuly
        ;;
    failed)
        # We wasn't able to open the device
        ;;
esac
</example>
Here <var><tt>device_name</tt></var> can be for example
<file>/dev/ide/host0/bus0/target0/lun0/disc</file>.

<sect> Close a device

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog CLOSE
close_dialog
</example>

After this command you may not issue commands regarding the device of
<var><tt>device_directory</tt></var>.  This command does
<strong>not</strong> invoke the command COMMIT.

<sect> Does the partition exist on the disk?

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog VIRTUAL <var>partition_id</var>
read_line virtuality
close_dialog
case $virtuality in
    yes)
        # the partition does not exist on the disk
        # probably because it is newly created
        ;;
    no)
        # the partition exists on the disk
        ;;
esac
</example>

<sect> Remember the partition table as unchanged

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog DISK_UNCHANGED
close_dialog
</example>

After this command <prgn>parted_server</prgn> will know that the
partition table in its onw internal data structures is the same as the
partition table actualy existing on the device.  The main purpose of
this command is to be used for partition tables with type <tt>loop</tt>.

<sect> Report whether the partition table is changed

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog IS_CHANGED
read_line changed
close_dialog
case $changed in
    yes)
        # the partition table is changed
        ;;
    no)
        # the partition table is not changed
        ;;
esac
</example>


<sect> Dump the partitions

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog DUMP
close_dialog
</example>

<p> This command prints in <file>/var/log/partition_dump</file>
all the data regarding the device.  It is used for debugging.

<sect> Write partitioning to the disk

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog COMMIT
close_dialog
</example>

<p> This command transfers the partitions in the device of
<var><tt>device_directory</tt></var> from the internal structures of
<prgn>parted_server</prgn> to the disk.

<sect> Undo the changes

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog UNDO
close_dialog
</example>

<p> This command destroys the internal data structures in
<prgn>parted_server</prgn> for a device and then rereads them from the
device.

<sect> Get the partitions

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog PARTITIONS
while { read_line num id size type fs path name; [ "$id" ]; }; do
    # do something for this partition
done
close_dialog
</example>

<p> The body of the loop is executed for every partition and free
space. $num is the number of the partition (for example
<file>/dev/hda6</file> has number 6).  $id is the id of the partition.
$size is the size of the partition (in bytes).  If this is an active
partition then $type is either `primary' or `logical'.  If this is a
free space then $type shows what partition can be created in it.  In
this case $type can be `primary', `logical', `pri/log' or `unusable'.
$fs is `free' if this is a free space.  Otherwise $fs is the type of
the file system of this partition as known to
<prgn>parted_server</prgn>.  $path is a device name for the partition,
for example <file>/dev/ide/host0/bus0/target0/lun0/part6</file>.
$name is the name of the partition or the empty string if the
partition table doesn't support partition names.

<p> Notice that in the loop-body you may not initiate another dialog
with <prgn>parted_server</prgn>.  If you need this you can use the
following construction instead:
<example>
cd <var>device_directory</var>
open_dialog PARTITIONS
partitions=$(read_paragraph)
close_dialog

echo "$partitions" |
while { read num id size type fs path name; [ "$id" ]; }; do
    # do something for this partition
done
</example>

<sect> Getting info about a partition

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog PARTITION_INFO <var>partition_id</var>
read_line num id size type fs path name
close_dialog
</example>
Here <var><tt>partition_id</tt></var> is the id of the partition to
get info.  The meaning of the variables are the same as in the command
PARTITIONS.

<sect> Getting cylinder/head/sector geometry of a partition/free space

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog GET_CHS <var>partition_id</var>
read_line start_cyl start_head start_sector end_cyl end_head end_sector
close_dialog
</example>

<sect> Getting the supported partition table types

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog LABEL_TYPES
supported=$(read_list)
close_dialog
</example>
For the result of this command <var><tt>device_directory</tt></var> is
irrelevant.  Despite this <var><tt>device_directory</tt></var> must be
a valid device directory.

<p> This command is used to read which types partition tables are
supported by <prgn>parted_server</prgn> (i.e. by libparted).
$supported is a comma-separated list of the supported types.  At the
time of writting the following types are supported: bsd, gpt, mac,
dvh, msdos, pc98, sun and loop.

<sect> Get the type of the disk label

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog GET_LABEL_TYPE
read_line label_type
close_dialog
if [ "$label_type" = unknown ]; then
    echo "The disk is unknown or it has no disk label
          or the disk label is unknown"
else
    echo "The type of the disk label is:" "$label_type"
fi
</example>
This command returns the type of the disk label (i.e. the partition
table) of a disk.  It can be used to check if there is a partition
table (if not, then it is safe to create a new partition table or to
use the entire disk for RAID, LVM, encrypted unit, etc).

<sect> Create a new empty partition table

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog NEW_LABEL <var>partition_table_type</var>
close_dialog
</example>
This command creates in the device a new empty partition table with
type <var><tt>partition_table_type</tt></var>.  (Of course it won't be
written to the disk if you don't use the command COMMIT.)

<sect> Getting the meaningful flags for a partition

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog VALID_FLAGS <var>partition_id</var>
meaningful_flags=$(read_list)
close_dialog
</example>
$meaningful_flags is a comma-separated list of the flags that are
meaningful for the partition with id
<var><tt>partition_id</tt></var>.

<p> In order to check wether some particular flag xyz is meaningful
you can use this code:
<example>
cd <var>device_directory</var>
xyz_is_meaningful=no
open_dialog VALID_FLAGS <var>partition_id</var>
while { read_line flag; [ "$flag" ]; }; do
    if [ "$flag" = xyz ]; then
        xyz_is_meaningful=yes
        # you may not use break here
    fi
done
close_dialog
</example>

<sect> Getting the active flags of a partition

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog GET_FLAGS <var>partition_id</var>
active_flags=$(read_list)
close_dialog
</example>
$active_flags is a comma-separated list of the flags of the partition
with id <var><tt>partition_id</tt></var> that are in state 1.  This is
a sublist of the list returned by the command VALID_FLAGS.

<p> In order to check if some partition is denoted as bootable you can
use this code:
<example>
cd <var>device_directory</var>
is_bootable=no
open_dialog GET_FLAGS <var>partition_id</var>
while { read_line flag; [ "$flag" ]; }; do
    if [ "$flag" = boot ]; then
        is_bootable=yes
        # you may not use break here
    fi
done
close_dialog
</example>

<sect> Set the flags of a partition

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog SET_FLAGS <var>partition_id</var>
for flag in $all_flags_that_should_be_active; do
    write_line $flag
done
write_line NO_MORE
close_dialog
</example>

<p> If you want to denote some partition as non-bootable you can use
the following code:

<example>
cd <var>device_directory</var>
open_dialog GET_FLAGS <var>partition_id</var>
new_flags=$(
    while { read_line flag; [ "$flag" ]; }; do
        if [ "$flag" != boot ]; then
            echo $flag
        fi
    done
) 
close_dialog

open_dialog SET_FLAGS $id
write_line "$new_flags"
write_line NO_MORE
close_dialog
</example>

<sect> Check if partition names are supported

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog USES_NAMES
read_line supported
close_dialog
case $supported in
    yes)
        # the partition table supports partition names
        ;;
    no)
        # the partition table doesn't support partition names
        ;;
esac
</example>

<sect> Set the name of a partition

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog SET_NAME <var>partition_id</var> <var>new_name</var>
close_dialog
</example>
After this command the name of <var><tt>partition_id</tt></var> will
be <var><tt>new_name</tt></var>.  It is an error to use this command with
a partition table that doesn't support partition names.

<sect> Get the maximum number of primary partitions

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog GET_MAX_PRIMARY
read_line primaries
close_dialog
logger "This disk may contain up to $primaries primary partitions"
</example>

<sect> Check if extended and logical partitions are supported

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog USES_EXTENDED
read_line supported
close_dialog
case $supported in
    yes)
        # the partition table supports extended and logical partitions
        ;;
    no)
        # the partition table doesn't support extended and logical partitions
        ;;
esac
</example>

<sect> Get the known to <prgn>parted_server</prgn> file systems

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog FILE_SYSTEM_TYPES
known_filesystems=$(read_list)
close_dialog
</example>
$known_filesystems is a comma-separated list of the file systems that
are known to <prgn>parted_server</prgn>.  You probably won't need to
use this command.

<sect> Try to detect the file system in a partition

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog GET_FILE_SYSTEM <var>partition_id</var>
read_line filesystem
close_dialog
if [ "$filesystem" = none ]; then
    # no known file system is detected
else
    # a file system of type $filesystem is detected 
fi
</example>

<sect> Change the filesystem of a partition

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog CHANGE_FILE_SYSTEM <var>partition_id</var> <var>new_filesystem</var>
close_dialog
</example>

<p> libparted assigns every partition some file system.  This command
can be used to change this file system.  The file system assigned to
the partition is not necessarily the same as the actual file system.
Libparted uses it to determine automatically the type of the partition
in some partition tables.  For example with msdos partition tables the
partitions with file system `ext2' receive type 83.  The partitions
that are swap spaces receive type 82.

<sect> Check the filesystem in a partition for errors

<p> Synopsis:
<example>
cd <var>device_directory</var>
name_progress_bar <var>some/debconf/template</var>
open_dialog CHECK_FILE_SYSTEM <var>partition_id</var>
read_line result
close_dialog
case $result in
    good)
        # The file system is in good state
        ;;
    bad)
        # The file system has uncorrected errors
        ;;
    n/c)
        # No file system is detected
        ;;
esac
</example>

The command <prgn>name_progress_bar</prgn> may be omitted.  The debconf
template must have type text.  It will be used to give the user
information of what is being done.

<sect> Create a file system in a partition

<p> Synopsis:
<example>
cd <var>device_directory</var>
name_progress_bar <var>some/debconf/template</var>
open_dialog CREATE_FILE_SYSTEM <var>partition_id</var> <var>new_filesystem</var>
read_line result
close_dialog
case $result in
    OK)
        # the file system is successfuly created
        ;;
    failed)
        # wasn't able to create a file system
        ;;
esac
</example>

The command <prgn>name_progress_bar</prgn> may be omitted.  The debconf
template must have type text.  It is used to give the user some
information of what is being done.

<sect> Create a new partition

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog NEW_PARTITION $type $fs $freespace $position $length
read_line num id size type fs path name
close_dialog
if [ "$id" ]; then
    # the partition is successfuly created
else
    # wasn't able to create the partition
fi
</example>
$type is either primary or logical.  $fs is the type of the file
system to be assigned to the partition.  $freespace is the id of some
free space.  $position is either `full', `beginning' or `end' and
determines where in $freespace to create the new partition.  If
$position is not `full' then $length is the length that the new
partition should have (in bytes).

<p> If the new file system is succesfully created $num is tne number
of the created partition (for example <file>/dev/hda6</file> has
number 6).  $id is the id of the new partition.  $size is the size of
the new partition.  $size is approximately $length but not necessarily
the same.  $type and $fs don't change their values.  $path is a
device name, for example
<file>/dev/ide/host0/bus0/target0/lun0/part6</file>.  $name is the
name of the new partition or an empty string if the partition table
doesn't support partition names.

<sect> Delete a partition

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog DELETE_PARTITION <var>partition_id</var>
close_dialog
</example>

<sect> Resize a partition

<p> Synopsis:
<example>
cd <var>device_directory</var>
name_progress_bar <var>some/debconf/template</var>
open_dialog RESIZE_PARTITION <var>partition_id</var> <var>new_size</var>
read_line new_id
close_dialog
</example>
This command resizes a partition.  As usualy
<var><tt>new_size</tt></var> is measured in bytes.  $new_id is the new
id that the partition receives.  The resizing is not supported always.
If it fails $new_id will be the same as
<var><tt>partition_id</tt></var>.

<p> If the partition exists on the storage device and contains some
file system, then the data in the partition will be preserved and the
new partition table <em>will be written on the storage device</em>.
When it is impossible to resize the file system, the partition will be
left unresized.  When the partition doesn't exist on the storage
device, the new version of the partition table will not be written to
it.

<p> This command doesn't move the start of the partition but only its
end.

<p> The command <prgn>name_progress_bar</prgn> may be omitted.  The
debconf template must have type text.  It will be used to give the user
information of what is being done.

<sect> Get resize range

<p> Synopsis:
<example>
cd <var>device_directory</var>
open_dialog GET_RESIZE_RANGE <var>partition_id</var>
read_line minimal_size current_size maximal_size
close_dialog
</example>
This command returns the minimal and the maximal size that can be
achieved by using the command RESIZE_PARTITION.  $minimal_size,
$current_size and $maximal_size are measured in bytes.

<sect> Copy the contents of one partition into another

<p> Synopsis:
<example>
cd <var>destination_device_directory</var>
name_progress_bar <var>some/debconf/template</var>
open_dialog COPY <var>destination_id</var> <var>source_device</var> <var>source_id</var>
close_dialog
</example>
This command copies into the partition with id
<var><tt>destination_id</tt></var> the contents of the partition with
id <var><tt>source_id</tt></var>.  <var><tt>source_device</tt></var>
is <tt>$(basename <var>source_device_directory</var>)</tt>.

<p> The command <prgn>name_progress_bar</prgn> may be omitted.  The
debconf template must have type text.  It will be used to give the user
information of what is being done.


<chapt> Bugs and limitations

<p> All files and directories are assumed to not contain spaces in
their names.

<p> If the partition table supports extended and logical partitions
the user won't be shown free spaces whose size is less than one
cylinder.

</book>

<!-- Local variables: -->
<!-- coding: iso-8859-1 -->
<!-- End: -->
