Chapter 4. /lib/partman/lib/*

Table of Contents

4.1. Environment
4.2. Menus
4.3. Long numbers
4.4. Updating partition directories
4.5. Communication with parted_server

Various scripts in partman make use of function libraries: 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.

The main function library is base.sh, provided by partman-base. 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. [5]

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

4.1. Environment

The variables TAB and NL have values ASCII 9 and ASCII 10 correspondingly. They can be used as temporary values for the variable IFS. The function restore_ifs restores the variable IFS its original value.

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

4.2. Menus

The function debconf_select is a high level function to ask user with a menu using a Debconf question with type `select'. Synopsis:

debconf_select priority template choices default

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

menu_item_id<TAB>The text for the user

Here <TAB> is ASCII 9. The text `The text for the user' is the text of the menu item. If menu_item_id of some menu-item is identical with the fourth argument given to debconf_select then this menu-item will be default.

If the user cancels the question debconf_select returns with exit-code 255. Otherwise the value of the variable RET will be the menu_item_id 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.

The function debconf_select doesn't care to db_fset $template seen false. The template must have exactly the following type and choices fields:

Type: select
Choices-C: ${CHOICES}
Choices: ${DESCRIPTIONS}

The udebs that generate menus using menu-directories use the function ask_user instead of debconf_select. Synopsis:

ask_user a_menu_directory additional_optional_arguments...

This function displays the menu for a_menu_directory. The first argument is a menu-directory (see Section 3.2, “Menu-directories”). If the user cancels the dialog then ask_user returns with exit code 255. Otherwise it returns with the exit code of the script do_option.

If ask_user is called re-entrantly from within a do_option script, then the calling do_option 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.

The script choices is invoked with additional_optional_arguments as arguments. The first argument given to do_option is the menu_item_id of the chosen menu item and the other arguments are again additional_optional_arguments.

To set the default selected item in a menu-directory, use the function menudir_default_choice. Synopsis:

menudir_default_choice a_menu_directory subdirectory menu_item_id

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

The function partition_tree_choices prints a sequence of lines in the form

menu_item_id<TAB>The text for the user

– one for every storage device and one for every partition. The menu_item_id of the storage devices is their storage directory. The menu_item_id of the partitions has the form storage_directory//partition_id. The output of partition_tree_choices can be given as third argument to debconf_select.

4.3. Long numbers

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 longint_le, longint2human, human2longint and valid_human exist in order to deal with such big numbers.

The function longint_le is used to compare two big numbers.

longint_le number1 number2

returns with exit code 0 if the first number is less or equal to the second and returns 1 otherwise.

The function longint2human 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

longint2human 1234567890

gives 1.2 GB. Notice that this function rounds its argument.

The function human2longint is used for the opposite convertion:

human2longint 1.234Gb

gives 1234000000.

The function valid_human returns with exit code 0 when its first argument is a string that is suitable to be given to human2longint. Otherwise it returns with exit code 1.

4.4. Updating partition directories

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

But now a problem arises. Suppose that the user chooses to format some partition as ext2 and mount it on /home. The udebs responsible for formatting and mounting create the directories filesystem and mountpoint 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 mountpoint 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 mountpoint should be removed.

In order to solve this difficulty every script that makes changes to some partition should invoke the function update_partition from base.sh. Synopsis:

update_partition device_directory partition_id

In order to update the contents of the directory device_directory/partition_id the function update_partition executes the scripts from the directory /lib/partman/update.d/. 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 update.d are given several arguments. $1 is the device_directory. $2 is the number of the partition (/dev/hda6 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 parted_server, in most cases you should ignore this argument. $7 is the device name (for example /dev/ide/host0/bus0/target0/lun0/part6). "$8 $9 $10 $11 ..." is the name of the partition in partition tables that support partition names. Otherwise $8, $9, $10,... are not defined.

4.5. Communication with parted_server

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

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

The function write_line prints its arguments to outfifo.

The function read_line reads from infifo a line, splits it in fields according to $IFS and assigns these fields to variables whose names are given to read_line as arguments. For example

read_line x y z

reads a line from infifo, splits it and assigns the first field to the variable x, the second field to the variable y and the rest to the variable z. You see that read_line is used the same way as the shell operator read.

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

The function read_list reads lines the same way as the function read_paragraph. However the function read_list always prints only one line that is a comma-separated sequence of the lines read from infifo. If read_paragraph prints

This is the first line
This is the second line
This is the third line

read_list prints

This is the first line, This is the second line, This is the third line

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

You use the function close_dialog in order to terminate the communication dialog.

When you send parted_server an order to do some long operation (e.g. resize a file system) the user will be shown a progress bar. You may give a name to it by the function name_progress_bar. It may be used right before the command open_dialog and accepts only one argument – a template with type text that describes what is being done.

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



[5] The script base.sh 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.