Scroll to navigation

DDISKIT(1) General Commands Manual DDISKIT(1)

NAME

ddiskit - Red Hat tool for Driver Update Disk creation

SYNOPSIS

ddiskit [-h] [-vvv] [-qQ] [-p PROFILE] [-R RES_DIR] [-T TEMPLATE_DIR] [-P PROFILE_DIR] [-d] [-o DUMP_CONFIG_NAME] [-C KEY=VALUE]... ACTION [ACTION_OPTIONS]...

DESCRIPTION

ddiskit (pronounced dee-dis-kit) aids and simplifies the creation of (back-ported) out-of-tree kernel module RPMs and Driver Update Disks containing them. These RPMs and DUDs are deemed suitable for using with distributions based on Red Hat Enterprise Linux. This version of ddiskit supports RHEL 7 and backward-compatible with RHEL 6.

ddiskit assumes some workflow which is described in the USAGE EXAMPLE section. It is tailored to the process used for developing and releasing Driver Update Disks, and, while it can be used for creating driver packages for RHEL-based distributions in general, it also worth considering other tools for the similar purpose, like dkms(8) or akmods(1).

OPTIONS

Please refer to the Configuration generation section for the description of "configuration option name" and "default value" fields, and to the ACTIONS section for the description of the actions mentioned.

General options

Print a list of options. ddiskit will exit after this action, ignoring the remainder of the command line.
Increase output verbosity by 1. Value of 1 means verbose output (it toggles printing of most of executed commands and all warnings), and value of 2 is useful for debugging (it enables printing of all the executed commands output, actions, and messages). Value of 3 further increases output verbosity of issued rpm(1) commands.
Configuration option name: defaults.verbosity
Default value: 0
Configuration profile to use. Please refer to the Configuration generation section for the additional information about profiles.
Configuration option name: defaults.profile
Default value: none; "default" is provided in package configuration
Resources directory. Used as a base of evaluation for template and profile directory paths.
Configuration option name: defaults.res_dir
Default value: none; "/usr/share/ddiskit/" is a hard-coded default.
Templates directory, used as a base for searching for spec or module configuration templates. Please refer to the File path evaluation section for the information regarding template file path resolution.
Configuration option name: defaults.template_dir
Default value: none; "{res_dir}/templates" is a hard-coded default.
Profiles directory, used as a base for searching for profiles. Please refer to the File path evaluation section for the information regarding profile file path resolution.
Configuration option name: defaults.profile_dir
Default value: none; "{res_dir}/profiles" is a hard-coded default.
Dump the derived configuration after performing the action.
Configuration option name: defaults.dump_config
Default value: False
Path to the file targeted for the configuration dump.
Configuration option name: defaults.dump_config_name
Default value: none; "{config}.generated" is a hard-coded default.
Enable quilt support. Please refer to the QUILT INTEGRATION section for the information regarding quilt integration. The option sets defaults.quilt_support configuration option to True.
Disable quilt support. The option sets defaults.quilt_support configuration option to False.
Override arbitrary configuration option that have the name KEY with VALUE. The KEY should follow the "{[section_name.]key_name}" syntax, and defaults section is assumed in case section_name part is omitted. The argument can be used multiple times in order to override multiple options.

Options for prepare_sources action

Path to the module configuration file.
Configuration option name: defaults.config
Default value: "module.config"
Configuration file template. Please refer to the File path evaluation section for the information regarding configuration template file path resolution.
Configuration option name: defaults.config_template
Default value: none; "config" is a hard-coded default.
Path to .git directory containing repository from where source files should be checked out.
Configuration option name: defaults.git_dir
Default value: none
Revision specification at which source files should be checked out from the repository.
Configuration option name: defaults.git_revision
Default value: "HEAD"
Whitespace-separated list of paths which should be checked out from the repository.
Configuration option name: defaults.git_src_directory
Default value: none
Major version number of the distribution the package is built for (for example, "7" for RHEL 7.3).
Configuration option name: defaults.major
Default value: 7
Minor version number of the distribution the package is built for (for example, "3" for RHEL 7.3).
Configuration option name: defaults.minor
Default value: 0

Options for generate_spec action

Path to the module configuration file.
Configuration option name: defaults.config
Default value: "module.config"
RPM spec file template. Please refer to the File path evaluation section for the information regarding RPM spec template file path resolution.
Configuration option name: defaults.spec_template
Default value: none; "spec" is a hard-coded default.

Options for build_rpm action

Path to the module configuration file.
Configuration option name: defaults.config
Default value: "module.config"
Tar all files, including hidden ones (files with names starting with dot). Otherwise, only files with names starting with non-dot character will be added to the source tarball. The option sets the value of the relevant configuration parameter to True. Note that this check is independent from the check controlled by the defaults.tar_strict configuration parameter.
Configuration option name: defaults.tar_all
Default value: False
Tar only expected files. Only the files with names matching the regular expression pattern provided in defaults.src_patterns configuration option will be added to the source tarball. The option sets the value of the relevant configuration parameter to True. Note that this check is independent from the check controlled by the defaults.tar_all configuration parameter.
Configuration option name: defaults.tar_strict
Default value: False
Force building of source RPM instead of binary one. ddiskit has several heuristics (whether host architecture is among architectures targeted by module, whether RPM build check passes) that detect possibility of binary RPM build and falls back to building source RPM only in case they indicated that binary RPM build is impossible; however, one can force building of source RPM instead of binary one with this switch. The option sets the value of the relevant configuration parameter to True.
Configuration option name: defaults.srpm
Default value: False
Enable mock(1) usage for building RPM. See the MOCK SUPPORT section for additional information.
Configuration option name: defaults.mock
Default value: False
Which mock configuration should be used for building RPM.
Configuration option name: defaults.mock_config
Default value: "default"
Whether to pass --offline option to mock.
Configuration option name: defaults.mock_offline
Default value: False
Additional options that have to be passed to mock invocations. Shell quoting is supported. Overwrites options set by previous -O and/or -A options.
Configuration option name: defaults.mock_opts
Default value: none
Additional options that have to be passed to mock invocations. Shell quoting is supported. Appends options to the options set by previous -O and/or -A options.
Configuration option name: defaults.mock_opts
Default value: none
Set the level of source code repository authenticity check. See the SOURCE CODE VERIFICATION section for the details.
Configuration option name: defaults.check_get_src
Default value: 0
Call the generate_spec action at the beginning of the build_rpm action execution. This saves for calling generate_spec action separately each time module configuration or patch list are changed (assuming that spec file does not need manual changes after generation).
Configuration option name: defaults.generate_spec_on_build
Default value: 0

Options for build_iso action

Path to the module configuration file.
Configuration option name: defaults.config
Default value: "module.config"
File name for the output ISO.
Configuration option name: defaults.isofile
Default value: none; see also build_iso action description section.

Options for dump_config action

Path to the module configuration file.
Configuration option name: defaults.config
Default value: "module.config"
Name of the file where to store configuration dump. This is the same option as the -o option in the General options section, and present here only for convenience.
Configuration option name: defaults.dump_config_name
Default value: none; "{config}.generated" is a hard-coded default.

Options for update_kabi action

Path to the module configuration file.
Configuration option name: defaults.config
Default value: "module.config"
Path to .git directory containing repository from where source files should be checked out.
Configuration option name: defaults.git_dir
Default value: none
Path to kABI symbol information files directory withing kernel source tree that is ought to be updated.
Configuration option name: defaults.kabi_dest_dir
Default value: none
Extract kmods from RPMs and use their modversion data instead of RPM "Requires" tags. The option sets defaults.kabi_use_rpm_ko configuration option to True.
Do not extract kmods from RPM and use data provided in "Requires" tags instead. The option sets defaults.kabi_use_rpm_ko configuration option to False.
Overwrite existing kABI symbol information files. The option sets defaults.kabi_files_overwrite configuration option to 2.
Do not overwrite existing kABI symbol information files. The option sets defaults.kabi_files_overwrite configuration option to 0.
Ask user when a possibility of existing kABI symbol information file overwrite appears. The option sets defaults.kabi_files_overwrite configuration option to 1.
Perform create a git commit with the affected kABI symbol files on success. The option sets defaults.kabi_commit configuration option to True.
Do not perform create a git commit with the affected kABI symbol files on success. The option sets defaults.kabi_commit configuration option to False.
Commit message that is supplied for the git commit with the affected kABI symbol files.
Configuration option name: defaults.kabi_commit
Default value: none
Path to a relevant kernel's Module.symvers file (for example, "/usr/src/kernels/KERNEL_VERSION.{arch}/Module.symvers", present in the kernel-devel RPM).
Configuration option name: defaults.symvers_path
Default value: none
Path to a file containing a list of symbols already white listed, in Module.symvers format.
Configuration option name: defaults.kabi_whitelist
Default value: none
Abort when a symbol version conflict is discovered. The option sets defaults.kabi_check_symvers_conflicts configuration option to 2.
Continue processing even if a symbol version conflict is discovered. The option sets defaults.kabi_check_symvers_conflicts configuration option to 0.
Ask user what to do when a symbol version conflict is discovered. The option sets defaults.kabi_check_symvers_conflicts configuration option to 1.

CONFIGURATION

Configuration is a sectioned key-value store, with values being strings and interpreted based on the context (see CONFIGURATION VALUES REFERENCE section for the reference) as strings, integers, booleans (see Boolean values section for the details on boolean value derivation), or arrays.

Configuration generation

In order to construct its configuration, ddiskit gathers configuration options from the multiple sources, then performs some fixed processing. The sources of configuration options are the following:

Hard-coded defaults, present in ddiskit source code. These are mostly for default configuration search paths and for other values which are expected to be defined one way or another. Currently, it contains the following configuration options:
defaults section
  • res_dir = "/usr/share/ddiskit"
  • template_dir = "{res_dir}/templates"
  • profile_dir = "{res_dir}/profiles"
  • config_template = "config"
  • quilt_support = True
  • spec_template = "spec"
  • src_patterns = "^Kbuild$|^Kconfig$|^Makefile$|^.*.[ch]$"
global section
  • module_vendor = "ENTER_MODULE_VENDOR"
  • module_author = "ENTER_MODULE_AUTHOR"
  • module_author_email = "ENTER_MODULE_AUTHOR_EMAIL"
  • The "package" configuration. It contains the rest of the configuration option defaults which should be defined for proper operation (like spec file generation). Package configuration is read from the fixed path "/usr/share/ddiskit/ddiskit.config" which is not expected to be modified by user or system administrator (and is usually overwritten by package update).
  • The "site" configuration. Located in "/etc/ddiskit.config", this file is treated as a configuration file and is subject to possible changes by the system administrator.
  • The "user" configuration. In case user wants some user-specific changes (like his own default values for global.module_author or global.module_author_email configuration options, as well as default profile), he should place it in ".ddiskitrc" file in his home directory.
  • Profile. The profile in use is derived from defaults.profile and default.profile_dir configuration variables (see more in the File path evaluation section on how the path to the profile is evaluated). It contains overrides suitable for a particular use case (for example, the rh-testing profile contains spec file description suffix with a notice that the package provided is a testing package). Note that the values for aforementioned configuration variables can be overridden by -p and -P command line arguments.
  • Module configuration. This file is usually called "module.config" (but can be overridden by -c command line argument) and contains module-specific configuration. It is usually generated from template by prepare_sources action and is self-documented in terms of what values user is expected to provide there.
  • Command-line arguments. They update defaults section of the configuration dictionary, and usually have key name equal to the long option name, with dashes replaced with underscores. Configuration option name for each specific command line option is provided in the OPTIONS section. Unless explicitly specified (with default value being "none"), command line option always updates the configuration option value.

These files are applied one after another in aforementioned order, so the "last wins" rule applies. The exception from the rule are command line options, which take precedence at each point of configuration generation (during the profile path evaluation, for example).

The configuration files themselves are sectioned key-value files, syntax of which is described in the related Python module documentation, except for the interpolation part, which is home-grown and described in the section Configuration value evaluation.

Kernel package versioning scheme

Red Hat Enterprise Linux follows specific kernel package versioning scheme, and ddiskit employs it in order to generate proper dependencies on the kernel package. As a result, it expects that in places where kernel version is provided, this version follows specific scheme. More specifically, two version schemes are supported:

  • Y-stream kernel version. This kernel package version is shipped as a part of General Availability release, and has the following format:


    kernel_version.kernel_patchlevel.kernel_sublevel-rhel_release.rpm_dist
        

    For example, RHEL 7.3 GA kernel has kernel version 3.10.0-514.el7. Consequently, it is expected that kernel_version, kernel_patchlevel, kernel_sublevel, rhel_release are decimal numbers (having no more than 1, 2, 2, and 4 digits, respectively), and rpm_dist part is provided in the form of "el<number>", where <number> is a 1-digit or 2-digit number not less than 6.

  • Z-stream kernel version. These kernel packages are provided as a part of updates for the existing release (so-called Z-stream). The versions of these packages have the following format:


    kernel_version.kernel_patchlevel.kernel_sublevel-rhel_release[.update_release]+.rpm_dist
        

    The restrictions on the parts that also used for the Y-stream kernel package version description are the same, and update_release is a number that can have up to 3 digits. Example of a Z-stream kernel package version (RHEL 7.3 update from 2017-05-25): 3.10.0-514.21.1.el7.

Generally, it is expected that kernel module RPMs and Driver Update Disks are built for using along with the Y-stream GA kernel (and all the following Z-stream kernels, thanks to kABI compatibility), so when Z-stream kernel package version is detected, the user is warned about this. The differences between kernel package dependency generation in these cases are described in the Spec file generation section.

In order to enforce these checks, ddiskit uses regular expression-based approach: it checks the version provided in the defaults.kernel_version configuration variable against regular expressions set via the defaults.kernel_flex_version_re and defaults.kernel_fixed_version_re configuration options, which contain Python regular expressions (see Python re module documentation for details about regular expression syntax) for matching Y-stream and Z-stream kernel versioning scheme, respectively. In order to extract parts of kernel version described above, the following regular expression groups are used:

Kernel's major version (kernel_version in the description above).
Kernel's patch level (kernel_patchlevel).
Kernel's sub-patch level (kernel_sublevel).
Major part of RPM release (rhel_release).
Remaining part of RPM release (update_release).
RPM release dist part (rpm_dist).

The default values of the defaults.kernel_flex_version_re and defaults.kernel_fixed_version_re configuration options are set via other configuration options:


kernel_flex_verson_re   = {kernel_nvr_re}{kernel_dist_re}
kernel_fixed_version_re = {kernel_nvr_re}{kernel_fixed_re}{kernel_dist_re}
kernel_nvr_re   = (?P<version>[0-9]).(?P<patchlevel>[0-9]{1,2}).(?P<sublevel>[0-9]{1,2})-(?P<rpm_release>[0-9]{1,4})
kernel_fixed_re = (?P<rpm_release_add>(.[0-9]{1,3})+)
kernel_dist_re  = (?P<rpm_dist>.el([6-9]|[1-9][0-9]))

This allows for some flexibility in case some tuning of these checks is needed.

Configuration check

After the configuration has been constructed (and in case module configuration is present), it is subject to a set of checks:

  • Whether global and spec_file configuration sections are present.
  • Whether all configuration options in global and spec_file sections have non-default values. Default value is a value which is the concatenation of "ENTER_" and upper-cased configuration key name ("ENTER_MODULE_NAME" for spec_file.module_name configuration option, for example). The exception is spec_file.firmware_version option, in case spec_file.firmware_include configuration options is set to False.
  • Whether spec_file.kernel_version has proper format (only Y-stream and Z-stream kernel versions are accepted, see the Kernel package versioning scheme section for the acceptable version string format configuration details).
  • Whether spec_file.module_name, spec_flie.module_version, and spec_file.module_rpm_release configuration options contain only characters accepted by RPM (alphanumeric plus '.', '-', '_', '+', '%', '{', '}' for spec_file.module_name; alphanumeric plus '.', '_', '+', '%', '{', '}', '~' for spec_flie.module_version and spec_file.module_rpm_release).

File path evaluation

Paths to various external resource files (like templates and profiles) are evaluated based on provided resource directory and name using the following algorithm:

  • If resource name does not have slashes, then it is considered that this name refers to the file in the provided directory.
  • Otherwise, it is interpreted as a path relative to the current working directory (which is the directory the where module configuration resides).

For example, profile "my-profile" is searched relative to profile directory (stored in the defaults.profile_dir configuration option, "/usr/share/ddiskit/profiles" by default), but profile "./my-profile" is searched relative to module's configuration directory.

Configuration value evaluation

Configuration option values can reference other configuration options using the "{[section_name.]key_name}" syntax. If section is not present, it is assumed that the referenced key is in the same section as the value which references it. If the referenced key is not found, no substitution occurs.

For example, let's assume the following configuration file:


[foo]
foo = aaa {bar} {bar.baz}
bar = bbb {baz} {bar.foo}
[bar]
foo = ccc {baz}
bar = ddd {foo.foo}
baz = eee

After the evaluation, foo.foo key would have the value "aaa bbb {baz} ddd ccc eee eee", foo.bar would equal to "bbb {baz} ccc eee", bar.foo would be "ccc eee", and bar.bar is "ddd ccc eee".

Circular dependencies are not explicitly resolved, there's only substitution depth limit present (which is set to 8 currently).

Boolean values

The values which are treated as boolean can have the following (case-insensitive) values in order to indicate that the value should be evaluated to True: 1, t, y, true, or yes. In order to indicate False value, one of the following strings may be used: 0, f, n, false, or no. In case configuration value doesn't evaluate to True or False value, it is evaluated as None. None value is treated as False in most places, but sometimes it is important to provide specific choice, and in these cases error would occur if boolean value was evaluated to None.

Spec file generation

Before spec file generation takes place, additional configuration processing is performed:

  • spec_file.source_patches and spec_file.source_patches_do generated in accordance with a lexicographically sorted list of patch files found in the patch directory: src/patch relative to the current working directory (except when quilt(1) integration is enabled; see the QUILT INTEGRATION section for details). spec_file.source_patches contains lines in the "PatchN: patch-file-name" format, and spec_file.source_patches_do contains lines in the "%patchN -p1" format. As a result, first configuration variable is suitable for patch file list description, and second is useful in the %prep section for patch applying. If the default.quilt_support configuration option is enabled, file named series is ignored in the patch directory.
  • spec_file.firmware_files configuration variable contains list of files found in the src/firmware directory with the /lib/firmware/ directory prepended, which is suitable for the %files section of the firmware sub-package.
  • spec_file.firmware_files_install configuration variable contains list for firmware file installation commands in the format "install -m 644 -D source/firmware/firmware-file-path $RPM_BUILD_ROOT/lib/firmware/firmware-file-path", which is suitable for the %install section of the firmware sub-package.
  • spec_file.firmware_begin configuration option is set to "%if 1" or "%if 0" when the spec_file.firmware_include configuration variable is true or not, respectively.
  • spec_file.firmware_end configuration variable is set to "%endif".
  • spec_file.date is set to the current date and time in "%a %b %d %Y" strftime(3) format, if this variable hasn't been set already.
  • spec_file.kernel_requires is formatted as following (if the variable hasn't been set already):
  • if the spec_file.kernel_version_min configuration option contains a non-empty value, it is set to


    Requires:    kernel >= spec_file.kernel_version_min
        

  • otherwise, if the spec_file.kernel_version_dep configuration option contains a non-empty value, it is set to


    Requires:    kernel = spec_file.kernel_version_dep
        

  • otherwise, it is set to


    Requires:    kernel >= kernel_version-kernel_release.kernel_dist
    Requires:    kernel <  kernel_version-(kernel_release + 1).kernel_dist
        

    if the spec_file.kernel_version configuration option contains a Y-stream kernel version, or


    Requires:    kernel = kernel_version-kernel_release.kernel_dist
        

    if the spec_file.kernel_version configuration option contains a Z-stream kernel version (please refer to the Kernel package versioning scheme section for the additional details regarding Y-stream and Z-stream versions).

If spec_file.kernel_version configuration option is not set and mock support is enabled, its value is defaulted to the latest version of the kernel-devel package available in the mock environment.
spec_file.module_requires is set to spec_file.dependencies value with the "Requires: " string prepended, if the variable hasn't been set already. Note that this special configuration variable is deprecated, present only for the backward compatibility, and this special value generation may be removed in the future.

After this configuration processing, parts of the spec template in the "%{[section_name.]key_name}" format (note the presence of percent sign in comparison to the syntax used for configuration option substitution) are replaced with evaluated configuration values. If no appropriate configuration has been found, no replacement occurs. If configuration option evaluates to empty string, %{nil} is inserted into the resulting spec file.

ACTIONS

prepare_sources

Prepare initial file and directory structure. This action creates directories where various files are expected to be placed and creates (into a file set in --config option) module configuration from the template file (which path is determined by the defaults.template_dir and defaults.config_template configuration variables; please refer to the File path evaluation section for the module configuration template path derivation process). The action creates the following directory hierarchy:

rpm - directory for storing rpmbuild(1) artifacts.
  • BUILD - build directory, used by rpmbuild(1).
  • BUILDROOT - RPM build root.
  • RPMS - directory where resulting binary RPMs are stored.
  • SOURCES - directory where source tarball and patches are stored.
  • SPECS - directory where generated spec file is placed.
  • SRPMS - directory where resulting source RPM is stored.
src - directory where module sources are expected to be placed. There are not explicit constrains on the kernel module source file layout, but it is expected that the main make file is placed in a directory provided in the spec_file.module_build_dir configuration variable.
  • patches - directory with patches that should be applied to the source.
  • firmware - firmware files.

Additionally, if the defaults.git_src_directory configuration option (which, in turn, defaults to the value of the spec_file.module_build_dir configuration option, provided the latter is non-empty) is set, source files placed inside directories listed in this whitespace-separated list checked out (inside the src directory) from the repository pointed by the defaults.git_dir configuration option at the revision which specification is set in the defaults.git_revision configuration option (the actual revision to checkout is the output of git rev-parse(1) command invocation with the aforementioned specification supplied to it).

Before configuration template is processed, the following configuration options are also set:

  • spec_file.module_build_dir - set to the value of first element of whitespace-separated list stored in the defaults.git_src_directory configuration option, or to "ENTER_MODULE_BUILD_DIR", if it is empty.
  • spec_file.git_hash - set to the value returned by get rev-parse(1) call with defaults.git_revision revision specification supplied.

generate_spec

Generate spec file from the spec template (which path is determined by the defaults.template_dir and defaults.spec_template configuration variables; please refer to the File path evaluation section for spec template path derivation process) using process described in Spec file generation section. As a result of the execution of this action, the "rpm/SPECS/{spec_file.module_name}.spec" file is generated. During the generation process, the presence of kernel headers for the target kernel version and architectures is also checked, and warning message is printed in case some of them are not present; this check doesn't affect spec file generation process, however.

build_rpm

The RPM build action includes several steps:

  • Check for the module configuration file presence (provided in defaults.config configuration variable via the --config command line option). Since some configuration values should be derived directly from it, its absence makes the whole operation senseless, thus the early bailout.
  • Generate (if the defaults.generate_spec_on_build configuration option is set to True) or check (if the defaults.check_spec_on_build configuration option is set to positive value) spec file. Depending on the check level provided in the defaults.check_spec_on build configuration option, the latter check may lead to warning or to the termination of the action:
0
Do not perform the spec file check.
1
Perform spec file comparison and issue warning in case generated and existing spec files differ.
2
Perform spec file comparison and issue warning in case generated and existing spec files differ, user is asked whether he wants to continue.
3
Perform spec file comparison and abort action execution in case of any errors (during spec file generation or comparison).
No spec file comparison is performed (regardless of the defaults.check_spec_on_build configuration option value) if spec file generation is enabled (obviously).
  • Check for Makefile presence. Presence of file named Makefile somewhere in the source tree allows for passing this check. Absence of Makefile leads to early termination with a relevant exit code (please refer to the EXIT STATUS section for details).
  • In case quilt integration (specified via the configuration option default.quilt_support) is enabled, quilt patches are de-applied.
  • Source tarball creation. Tar file named "rpm/SOURCES/{spec_file.module_name}-{global.module_vendor}-{spec_file.module_version}.tar.bz2" is created, and files present in the src directory added to it, with the following exceptions:
  • patches subdirectory is skipped.
  • All RPM files present in the top level of the src directory are skipped.
  • Files present in the firmware source subdirectory are skipped in case boolean configuration option spec_file.firmware_include is set to False. In case there are files present in this directory, warning message is displayed regarding the matter.
  • Hidden files (files beginning with dot) are skipped, unless the defaults.tar_all configuration option (controlled via the --tar-all action-specific command line option) is set to True.
  • Only files matching the pattern set in the defaults.src_patterns configuration option are added, if the defaults.tar_strict configuration option (controlled via the --tar-strict action-specific command line option) is set to True. The default pattern includes only *.c, *.h, Makefile, Kbuild, and Kconfig files, which should be suitable for the most cases.
  • All files from the src/patches directory are copied to the rpm/SOURCES directory.
  • If current host architecture is among architectures provided in the spec_file.kernel_arch architectures, rpmbuild check (rpmbuild -bc --nobuild) succeeded, and the defaults.srpm configuration option (controlled via the --srpm action-specific command line option) is not enabled, an attempt to build binary RPM is performed. Otherwise, a source RPM is built.
  • In case quilt integration (specified via the configuration option default.quilt_support) is enabled, quilt patches are applied back.

build_iso

This action takes list of files and directories that should be placed on the Driver Update Disk as a non-option arguments. It performs the following steps:

Iterate over the files provided in arguments (recursively descending into directories) and add to the list of candidate files which satisfy the following criteria:
  • file name ends with ".rpm",
  • rpmquery(1) successfully retrieves information regarding RPM architecture from the package,
  • RPM is a binary package or RPM is a source package and the global.include_srpm configuration option is enabled,
  • RPM is not a debug information package (RPM has group other than "Development/Debug"),
  • RPM has a valid GPG signature (if case GPG signature check is enabled; see RPM SIGNATURE VERIFICATION section for the additional information).
  • All satisfying candidates then copied in a temporary directory. Source RPMs are placed in src subdirectory in the disk hierarchy, and binary RPMs are placed in rpms/arch subdirectory, where arch is the architecture of the binary RPM (with all variants of i386, ..., i686 RPM architecture placed in the i386 subdirectory).
  • RPM repository metadata is generated (using the createrepo(1) command) in each of the aforementioned binary RPM directories.
  • rhdd3 file containing Driver Update Disk signature is created in the temporary directory.
  • ISO image is created with the mkisofs(1) command. The name of the ISO is provided in the defaults.isofile option (which can be set via the --isofile action-specific command line option). In case no explicit ISO file name is provided, it is generated as "dd-{spec_file.module_name}-{spec_file.module_version}-{spec_file.module_rpm_release}.{spec_file.rpm_dist}.iso", or, in case one of values of these configuration options is not a string, simply "dd.iso".

dump_config

Dumps configuration dictionary as it has been evaluated by a process described in the Configuration generation section. Output file for the dump is set in the defaults.dump_config_name option.

update_kabi

Generate files with kABI symbol information in the Red Hat Enterprise Linux kernel git repository and optionally commit the changes. The action processes kmods and RPMs provided in the positional arguments, collecting versions (checksums) of symbols present in module information sections and/or "Requires" RPM tags, and adds to the git repository files corresponding to symbols not yet added into it. The process is controlled via the following configuration options:

Whether to process kmod files inside the provided RPMs instead of RPM files themselves.
Regular expression used for parsing lines in symvers files. Expected to contain ver, symbol, file, and export groups.
Whether to overwrite kABI files if the files with the same name already exist. Can take the following values:
0
Do not overwrite existing kABI files.
1
Ask user on each possible overwrite.
2
Overwrite existing kABI files.
Whether to abort the action when a symbol version conflict (between newly added symbol and Module.symvers or kABI white list) is detected. Can take the following values:
0
Continue processing.
1
Ask user on each occesion.
2
Abort the action.
Whether to commit the changes at the end of the successful kABI files update.
Path to the kernel's Module.symvers file.
Path to the kABI white list (in Module.symvers format).
Path to the kernel's git repository.
Path in the kernel's repository to the directory with kABI symbol files.
Name of a kABI symbol file.
Contents template of a kABI symbol file.
Template of a line in the commit log regarding specific kABI symbol file.
Commit message used for the git commit, if defaults.kabi_commit configuration option is enabled.

Notes:

[1]
The arch variable is overridden with with architecture of the kmod currently being processed ("x86_64" or "ppc64le", for example).
[2]
There are multiple overrides take place during evaluation of the values:
Symbol being processed.
Architecture of the kmod being processed.
Version (checksum) of the symbol being processed.
File name of the kmod being processed.
Path to the file inside the kernel tree that contains the definition of the symbol being processed.
Type of the export ("EXPORT_SYMBOL", for example).

As of now, the rh-release profile contains some useful default values for the aforementioned configuration options.

QUILT INTEGRATION

ddiskit supports quilt(1) patch workflow. Specifically:

  • It de-applies quilt patches before building source tarball and applies them back after the build.
  • It uses contents of the series file in the patches directory as the source of the list of patches during the generate_spec action, as well as during the tarball creation in the build_rpm action. The file itself is excluded from the list of files considered as patches.
  • It ignores hidden files during the tarball creation in the build_rpm action which avoids inclusion of the .pc directory.

This behaviour (except the last part that is controlled by the defaults.tar_all configuration option) is controlled by the defaults.quilt_support configuration option, which is accessible via the --quilt-enable and --quilt-disable command line options.

MOCK INTEGRATION

ddiskit supports using mock(1) for building RPM. This support is activated via the defaults.mock configuration option which is controlled via the --mock action-specific command line option. When mock support is enabled, the following changes apply:

  • mock(1) is called instead of rpmbuild for source and binary RPM creation. Specifically, mock --buildsrpm is called for source RPM creation and pair of mock --buildsrpm and mock --rebuild is used to build binary RPM out of source RPM which is created inside mock environment.
  • No build check (rpmbuild -bc --nobuild) is performed in order to check whether it is possible to build binary RPM, it is assumed that mock can handle it.

SOURCE CODE VERIFICATION

As a part of the RPM build process (build_rpm action), source code can be checked for the correspondence with the git repository from which the code supposedly originates. It is assumed that the sources are located in the subdirectory provided in the spec_file.module_build_dir configuration option as of the commit whose ID is provided in the spec_file.git_hash configuration option. The check is performed via the git-diff(1) command. The path to the .git directory containing the git repository against which module's source code should be checked has to be provided in the defaults.git_repo configuration option. The necessity of the check itself, as well as its crucialness is specified via the default.check_git_src configuration option, with the following meaning of its value:

0
The check is skipped.
1
The check is performed and the warning is issued if the sources differ from the ones present in the repository.
2
The check is performed and the build process is aborted in case of sources discrepancy or other issues during the check.

The source code verification is performed when quilt patches are already de-applied.

RPM GPG SIGNATURE VERIFICATION

As a part of ISO build process (build_iso action), included RPMs can be checked for the presence and correctness of their GPG signature. The necessity of check is controlled via the rpm_gpg_check.check_level configuration option, which can have one of the following values:

0
The check is skipped.
1
The check is performed and the warning is issued for each RPM that failed it.
2
The check is performed and RPMs that didn't pass the check are skipped.
3
The check is performed and ISO creation is aborted if one of RPMs failed the check.

The boolean configuration option rpm_gpg_check.use_keyring controls whether specific keyring directory containing specific set of keys should be used or just GPG keys present in host's RPM DB. In case usage of keyring directory is enabled, configuration option rpm_gpg_check.keyring_dir points to the directory containing public GPG keys. Note that in order to use these files, their names should end with ".key" (this is, in fact, RPM's implicit assumption).

This check is enabled by default in rh-release profile and allows verifying that RPMs added to the release ISO have Red Hat's GPG signature.

USAGE EXAMPLE

1.
Create initial directory structure and module configuration.


$ ddiskit prepare_sources
Writing new config file (module.config)... OK
Creating directory structure for RPM build ... OK
Creating directory structure for source code ... OK
Put your module source code in src directory.
    

2.
Copy your code into the src directory:


$ tree src
src
├── drivers
│   └── net
│       └── ethernet
│           └── broadcom
│               ├── Makefile
│               ├── tg3.c
│               └── tg3.h
└── patches

├── 0001-test.patch
└── 0002-test.patch

  • Please, respect the directory hierarchy for the drivers which are originally part of the kernel tree.
  • Additional patches for the code could be placed in the src/patches directory.
3.
Fill out the module.config and generate the spec file:


$ ddiskit generate_spec
Checking config ...
Config check ... OK
RPM spec file "rpm/SPECS/tg3.spec" exists!
Patches found, adding to the spec file:

Patch0: 0001-test.patch
Patch1: 0002-test.patch Firmware directory is empty or nonexistent, skipping Writing spec into rpm/SPECS/tg3.spec ... OK

The resulting spec file is placed in the rpm/SPEC/ directory, you can optionally check it out before proceeding.
4.
Build binary RPM:


$ ddiskit build_rpm
    

5.
Build Driver Update Disk ISO:


$ ddiskit build_iso
    

FILES

/usr/share/ddiskit.config
Package default configuration.
/etc/ddiskit.config
System-wide ("site") configuration.
~/.ddiskitrc
User configuration.
Default configuration name.
/usr/share/ddiskit/templates/spec
Template for RPM spec file generation. Path to it can be overridden by changing defaults.spec_template configuration option or defaults.template_dir, please refer to the File path evaluation section for the additional information.
/usr/share/ddiskit/templates/config
Template for module configuration. Path to it can be overridden by changing defaults.config_template configuration option or defaults.template_dir, please refer to the File path evaluation section for the additional information.
/usr/share/ddiskit/profiles/default
Default profile. Contains configuration options which are useful in non-specific cases (none, currently). The profile in use is selected via the defaults.profile configuration option. Path to profile is configured by the defaults.profile_dir, configuration option, please refer to the File path evaluation section for the additional information.
/usr/share/ddiskit/profiles/rh-testing
Profile which contains configuration options used for the testing DUP RPMs by Red Hat. This includes the disclaimer that the package is provided for the testing purposes.
/usr/share/ddiskit/profiles/rh-release
Profile which contains configuration options used for the release DUP RPMs by Red Hat. This includes enablement of various strict checks (such as Git commit ID and RPM GPG signature verification).

EXIT STATUS

0
successful execution.
1
generic error (no additional information available).
2
problems during command line argument parsing.
3
problems during the configuration check phase (see Configuration check section for the additional information).
4
problem occurred when tried to de-apply quilt patches (patches do not de-apply cleanly, for example).
5
problem occurred when tried to apply quilt patches.
6
problem occurred during the sources verification.
7
problem occurred during RPM GPG signature verification.
8
problem occurred during git checkout of source files.
9
problem occurred during spec file comparison.
10
symbol version (checksum) conflict occurred (update_kabi action).
11
problem occurred during git add invocation (update_kabi action).
12
problem occurred during git commit invocation (update_kabi action).
32
generic input/output error.
34
error occurred while reading configuration file.
35
error occurred while writing module configuration file (prepare_sources action).
36
spec template file read error (generate_spec action).
38
spec read error (unused currently).
39
spec write error (generate_spec action).
41
source archive write error (build_rpm action).
42
Makefile not found (build_rpm action).
45
Driver Update Disk signature write error.
47
configuration dump file write error.
49
directory structure creation error.

REPORTING BUGS

Problems with ddiskit should be reported to ddiskit project bug tracker

HISTORY

The initial version of ddiskit was created by John W. Linville in the year 2005 for 2.6-based Red Hat Enterprise Linux and Fedora Core distributions (like 2.6.9-based RHEL 4). It filled "the same need which Doug Ledford's Device Driver Update Disk Devel Kit filled for prior generations of Red Hat distributions" which was used for the Linux 2.4-series based Red Hat distributions around the year 2003. In 2007, the responsibility for maintaining and enhancing ddiskit was passed to Jon Masters, who then developed ddiskit during the RHEL 5 and RHEL 6 era. The third incarnation of ddiskit was conceived in 2016 by Petr Oroš in an attempt to bring more automation to the process of Driver Update Disk creation along with RHEL 7 support.

SEE ALSO

rpmbuild(1), dkms(8), akmods(1), mock(1), quilt(1)

Jon Masters. Red Hat Driver Update Packages. Official Reference Guide

ddiskit project repository