Develop for XenServer

Producing driver RPMs

In order to produce a supplemental pack that contains kernel modules (drivers), the DDK must be used to compile the driver(s) from their source code, against the XenServer kernel. This chapter describes the process.

Directory structure

Although the examples located in the /root/examples/ directory contain various subdirectories, in practice, most supplemental pack authors will not use this structure. The following example considers a supplemental pack that contains both kernel modules and userspace components (as the combined example does).

In the combined case, two RPMs will be created, one containing the kernel modules, and the other the “data” or userspace portions (configuration files, firmware, modprobe rules). Hence, two specification files are present, which specify the contents of each RPM that is to be created.

Place the kernel driver source code in the /root/rpmbuild/SOURCES/ directory as a tar archive (it can be gzipped or bzip2 compressed), whose name is of the format <module-name>-<module-version>. Meanwhile, the specification files for the RPMs to be created will be stored in a directory elsewhere. we recommend authors make a copy of the specification files and Makefile found in the examples/combined/ directory as a starting point. The Makefile contains various useful build targets that can be adjusted for the kernel module sources being used.

Place all non-kernel module components in a directory named <module-name>-data-<version>, for example, helloworld-data-1.0. The corresponding specification file would be helloworld-data.spec. It is suggested that this subdirectory be placed in the same directory as the specification files.

Makefile variables

The Makefile includes several metadata attributes which must be customized according to the contents of the pack. These are as follows:

  • SPEC: the specification file for the driver RPM.

  • DATA_SPEC: the specification file for the userspace components RPM.

  • LABEL: by default, taken from the “Name:” field of the driver RPM specification file, but can be edited if so desired.

  • TEXT: a free text field describing the function of the driver. This is displayed on installation.

  • UUID: a universal unique identifier generated by the UUIDgen command. Every pack must have a different UUID and a given pack must have the same UUID each time it is built.

  • PACK_VERSION: the version number of the pack (this defaults to the build of the DDK being used, but can be changed by pack authors).

  • PACK_BUILD: the build number of the pack (this defaults to the build of the DDK being used, but can be changed by pack authors).

  • RPM_VERSION: the version number to be used for the kernel modules RPM. Citrix advises authors to set this to the version of the driver source being used.

  • RPM_RELEASE: the release number of this version of the RPM. For example, the same version of driver might be re-released in a supplemental pack, and hence need a new release number.

  • DATA_RPM_VERSION: the version number to be used for the userspace RPM.

  • DATA_RPM_RELEASE: the release number to be used for the userspace RPM.

Creating the kernel module specification file

The kernel module packages are built according to the instructions in the specification file. The following sections of the specification file affect the building of a package. Ensure you set them to appropriate values:

  • Name: a unique ID, preferably the name of the kernel module.

  • Source: the exact filename (without the path) of the tar archive that contains the sources for the kernel module, expected to be of the form <module-name>-<module-version>.

  • Summary: a short description of the driver.

  • %files is a list of files that are to be compiled into the RPM. Kernel modules must be located in a directory named extra (within /lib/modules/<kernel-version>/).

  • %changelog describes changes that have been made to the driver.

Building the modules

Each kernel module RPM must be built against against the XenServer kernel headers. The example Makefile provides a build-rpms target that automates the build. The userspace RPM is also built if necessary. The RPMs are output into the /root/rpmbuild/RPMS/x86_64 directory.

If the RPM does not build, it is important that the following be checked:

  • The Source parameter of the kernel RPM specification file must be the filename of the compressed tar archive containing the source code for the module, located in /root/rpmbuild/SOURCES.

  • The %prep section of the example specification file relies on the compressed tar archive, when expanded, creating a directory named <module-name>-<module-version>. If this is not the case, (for example, if it creates a directory named <module-version>), the %setup -q -n step can be amended to be, for example, %setup -q -n %{version}.

  • The %build section of the example specification file relies on the directory /root/rpmbuild/SOURCES/<module-name>-<module-version>/ containing the Makefile or KMake file that will build the kernel module <module-name>. If this Makefile is in a subdirectory, the %build section will need a cd <subdirectory-name> step added to it, before the %{__make} step. Similarly, you will need to add the same step into the %install section.

  • If, for any reason, the Makefile included in the compressed tar archive needs to be heavily patched in order to work correctly with the DDK, Citrix suggests that a new version of the file be created, with the appropriate fixes, then a patch generated using the diff command. This patch can then be applied in the %prep section of the specification file, immediately following the %setup step.

  • If the kernel module itself fails to compile, (rather than the RPMs failing to build), it may be that the source being used is incompatible with the kernel version that is used in XenServer. In this case, contact the author of the driver.

Including driver RPMs in supplemental packs

The next chapter details exactly how to include not only driver RPMs produced in the above manner in a supplemental pack, but also any other arbitrary RPMs. If a pack is only to include driver RPMs plus some associated configuration or firmware, it can be produced directly by using the Makefile $(ISO) target, which runs the build-update script. The script is run with the appropriate arguments to include the metadata that was given in the Makefile.

Format for releasing drivers

If a supplemental pack contains drivers, it must also be shipped with the source code to those drivers, to fulfill obligations under the GNU General Public License (GPL). We recommend that pack authors create a zip file containing the pack ISO, a compressed archive of any relevant source code, and the MD5 checksum files that are associated with the pack metadata and the ISO, produced by build-update.

Releasing multiple drivers in a single pack-

Server hardware manufacturers might want to issue a single supplemental pack that contains multiple drivers. Three options are available, depending on the desired result:

  • Make individual copies of the /root/examples/driver directory, one for each driver. Then produce the two RPMs for each driver using the build target in the Makefile. Collect all the RPMs into one place, and then run

  • Create a specification file for each driver (similar to that in /root/examples/driver). Adjust the Makefile to compile all the drivers and produce RPMs for each one, and then run

Producing driver RPMs