Skip to content

Instantly share code, notes, and snippets.

@knumskull
Created June 5, 2023 21:47
Show Gist options
  • Select an option

  • Save knumskull/a55c18ce111e64a84dcb9abae2422109 to your computer and use it in GitHub Desktop.

Select an option

Save knumskull/a55c18ce111e64a84dcb9abae2422109 to your computer and use it in GitHub Desktop.

Building a lin_tape binary RPM matching different kernel on Red Hat Enterprise Linux 8

Problem statement

The binary RPM build from source RPM for IBM lin-tape driver causing trouble in typical Red Hat Enterprise lifecycle operations. This driver is built against a specific kernel-version and the installed lin_tape package need to match the current running kernel. During maintenance and upgrade of Red Hat Enterprise Linux using standard tools like dnf package manager, there is no automatic solution to trigger a rebuild of the lin_tape driver to operate successfully after a kernel-upgrade and required reboot. At the moment this requires manual interaction after an upgrade of the operating system to bring the system back to normal operation mode.

Goal

Build binary RPM to match following pattern lin_tape-<lin_tape-version>-kernel-<kernel-version>.<arch>.rpm for example: lin_tape-3.0.20-kernel-4.18.0-372.16.1.el8_6.x86_64.rpm

This allows the package being installed multiple times and provides kernel-modules for all installed kernels.

Current situation

When download a lin_tape source RPM from IBM FIX Central a binary RPM can be created with following simple steps.

$ rpmbuild --rebuild lin_tape-3.0.64-1.src.rpm 

This will create a binary RPM lin_tape-3.0.60-1.x86_64.rpm described as follow.

$ rpm -qip lin_tape-3.0.60-1.x86_64.rpm
Name        : lin_tape
Version     : 3.0.60
Release     : 1
Architecture: x86_64
Install Date: (not installed)
Group       : System Environment/Kernel
Size        : 1202789
License     : GPL
Signature   : (none)
Source RPM  : lin_tape-3.0.60-1.src.rpm
Build Date  : Thu 01 Jun 2023 04:12:31 PM EDT
Build Host  : lintape-build.example.com
Relocations : (not relocatable)
Packager    : IBM Tape SCSI Device Driver Development
Vendor      : IBM
Summary     : IBM Tape SCSI Device Driver for Linux
Description :
The IBM Tape Device Driver, lin_tape, provides attachment and
advance functionality for use with IBM and other vendor tape
devices to Linux compatible platforms.

Expected situation

Proof of Concept

Prepare the demo environment

Installing of dependencies to setup the environment for building RPM packages.

$ sudo dnf install rpmdevtools gcc glibc-devel make tree

Install all available kernel and kernel-devel packages

$ sudo dnf list kernel kernel-devel --showduplicates --available | grep ^kernel | sed -E 's/^(.*).x86_64\s+(.*)\s.*$/\1-\2/g' | xargs sudo dnf install -y

Done with the previous step, it's necessary to create the directory structure using rpmdev-setuptree. This directory structure will be used for any further activity. Those steps are described more detailed in Red Hat Documentation Packaging and distributing software.

$ rpmdev-setuptree
$ tree ~/rpmbuild
/home/user/rpmbuild
├── BUILD
├── BUILDROOT
├── RPMS
├── SOURCES
├── SPECS
└── SRPMS

7 directories, 3 files

Download the source RPM and extract the content

To modify specific parts of the source RPM to achieve the goal, it's necessary to extract it's content. During this process, it's assumed the file is already downloaded from IBM FIX Central

$ L_DIR=$(mktemp -d)
$ cd $L_DIR
$ rpm2cpio ~/Downloads/lin_tape-3.0.60-1.src.rpm | cpio -idmv
lin_tape-3.0.60.tgz
lin_tape.spec
968 blocks

Those created files will be now copied to their according folders in the rpmbuild directory structure.

$ cp lin_tape-3.0.60.tgz ~/rpmbuild/SOURCES
$ cp lin_tape.spec ~/rpmbuild/SPECS
$ tree ~/rpmbuild
/home/user/rpmbuild
├── BUILD
├── BUILDROOT
├── RPMS
├── SOURCES
│   └── lin_tape-3.0.60.tgz
├── SPECS
│   └── lin_tape.spe
└── SRPMS

7 directories, 3 files

Using this diff output, save it as lin_tape-kernel.patch and apply it to the original spec-file.

--- SPECS/lin_tape.spec 2023-06-02 05:06:43.230975939 -0400
+++ SPECS/lin_tape-kernel.spec  2023-06-02 06:39:10.631353551 -0400
@@ -4,16 +4,18 @@
 %define sles12 %(test -e /etc/SuSE-release && cat /etc/SuSE-release | grep VERSION | grep 12 >/dev/null && echo 1 || echo 0)
 %define sles15 %(test -e /etc/os-release && cat /etc/os-release | grep VERSION | grep 15 >/dev/null && echo 1 || echo 0)
 %define ubuntu %(test -e /etc/os-release && grep -qi Ubuntu /etc/os-release && echo 1 || echo 0)
+%define KERNEL %( echo ${KERNEL:-%(uname -r)})
+%define KERNELVER %(echo %{KERNEL} | sed -e 's/.x86_64//')
 %bcond_with sfmp
 
 Summary: IBM Tape SCSI Device Driver for Linux
-Name: lin_tape
+Name: lin_tape-module-%{KERNELVER}
 Version: 3.0.60
 Release: 1
 License: GPL
 Vendor: IBM
 Group: System Environment/Kernel
-Source: %{name}-%{version}.tgz
+Source: lin_tape-%{version}.tgz
 # this is the build root suggested by redhat
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 AutoReqProv: no
@@ -33,13 +35,13 @@
 %endif
 Obsoletes: IBMtape
 Conflicts: IBMtape lin_tape < %{version}
+Requires: kernel = %{KERNELVER}
 Packager: IBM Tape SCSI Device Driver Development
 
 %undefine _enable_debug_packages
 
 %define debug_package %{nil}
 
-%define KERNEL %( echo ${KERNEL:-%(uname -r)})
 %define KERNELTYPES default smp bigsmp hugemem
 %define TOSTILE() %(echo %1|tr ' ' '|')
 %define KERNELBASENAME %(echo %{KERNEL}|sed --regexp-extended -e 's/[^a-zA-Z0-9]*(%{TOSTILE %KERNELTYPES})*$//p;d')
@@ -49,7 +51,7 @@
 %description
 %( echo "The IBM Tape Device Driver, lin_tape, provides attachment and advance functionality for use with IBM and other vendor tape devices to Linux compatible platforms."| tr '\n' ' ' | fold -s -w 65 )
 %prep
-%setup -q
+%setup -n lin_tape-%{version} -q
 
 %build
 %if %{ubuntu}
$ patch SPECS/lin_tape.spec < lin_tape-kernel.patch

Having this done, the binary package can be build.

$ rpmbuild -bb SPECS/lin_tape.spec

This will result in having a lin_tape module driver named by the kernel built against. This makes it possible to install multiple binary RPMs at the same time on a running system.

$ tree .
.                        
├── BUILD        
│   └── lin_tape-3.0.60
|       ├── ...
...     ...
|       └── ...
├── BUILDROOT
├── lin_tape-kernel.patch
├── RPMS
│   └── x86_64
│       └── lin_tape-module-4.18.0-372.16.1.el8_6-3.0.60-1.x86_64.rpm
├── SOURCES
│   └── lin_tape-3.0.60.tgz
├── SPECS
│   └── lin_tape.spec
└── SRPMS
$ sudo dnf install lin_tape*
Updating Subscription Management repositories.
Red Hat Enterprise Linux 8 for x86_64 - AppStream (RPMs)                                 17 kB/s | 4.5 kB     00:00    
Red Hat Enterprise Linux 8 for x86_64 - AppStream (RPMs)                                 22 MB/s |  57 MB     00:02    
Red Hat Enterprise Linux 8 for x86_64 - BaseOS (RPMs)                                    17 kB/s | 4.1 kB     00:00    
Red Hat Enterprise Linux 8 for x86_64 - BaseOS (RPMs)                                    23 MB/s |  61 MB     00:02    
Last metadata expiration check: 0:00:08 ago on Mon 05 Jun 2023 05:22:28 AM EDT.
Dependencies resolved.
========================================================================================================================
 Package                                   Arch       Version                   Repository                         Size
========================================================================================================================
Installing:
 lin_tape-module-4.18.0-305.el8            x86_64     3.0.60-1                  @commandline                      248 k
 lin_tape-module-4.18.0-372.16.1.el8_6     x86_64     3.0.60-1                  @commandline                      248 k
 lin_tape-module-4.18.0-477.13.1.el8_8     x86_64     3.0.60-1                  @commandline                      251 k
Installing dependencies:
 kernel-core                               x86_64     4.18.0-372.16.1.el8_6     rhel-8-for-x86_64-baseos-rpms      39 M
 kernel-core                               x86_64     4.18.0-477.13.1.el8_8     rhel-8-for-x86_64-baseos-rpms      42 M

Transaction Summary
========================================================================================================================
Install  5 Packages

Total size: 82 M
Total download size: 81 M
Installed size: 142 M

Installation of driver and taped

On another system, the driver and taped can be installed. Due to the fact, taped binary RPM has the original driver RPM as dependency, a typical installation will fail with dependency error.

$ sudo rpm -ivh lin_taped-3.0.64-rhel8.x86_64.rpm                                   
error: Failed dependencies:                                 
        lin_tape = 3.0.64 is needed by lin_taped-3.0.64-1.x86_64 

To workaround this, the option --nodeps can be used.

$ sudo rpm -ivh --nodeps lin_taped-3.0.64-rhel8.x86_64.rpm
Verifying...                          ################################# [100%]                                           
Preparing...                          ################################# [100%]                                           
Updating / installing...                                    
   1:lin_taped-3.0.64-1               ################################# [100%]                                           
Starting lin_tape...                                        

lin_taped loaded

Now the status can be checked using standard operating system tools.

$ sudo systemctl status lin_tape
● lin_tape.service - Lin_tape driver and daemon for IBM tape storage systems
   Loaded: loaded (/usr/lib/systemd/system/lin_tape.service; enabled; vendor preset: disabled)
   Active: active (running) since Mon 2023-06-05 05:33:15 EDT; 45s ago
  Process: 807 ExecStart=/usr/sbin/lin_tape start (code=exited, status=0/SUCCESS)
 Main PID: 819 (lin_taped)
    Tasks: 1 (limit: 11236)
   Memory: 1.5M
   CGroup: /system.slice/lin_tape.service
           └─819 /usr/bin/lin_taped start

Jun 05 05:33:15 lintape-runner systemd[1]: Starting Lin_tape driver and daemon for IBM tape storage systems...
Jun 05 05:33:15 lintape-runner lin_tape[807]: Starting lin_tape...
Jun 05 05:33:15 lintape-runner lin_taped[819]: lin_taped for Linux, Version 3.0.64, Nov 14, 2022
Jun 05 05:33:15 lintape-runner lin_taped[819]: lin_taped is running...
Jun 05 05:33:15 lintape-runner systemd[1]: Started Lin_tape driver and daemon for IBM tape storage systems.

Diagnostics

The kernel module is loaded for appropriate kernel

$ uname -r
4.18.0-372.16.1.el8_6.x86_64

$ modinfo lin_tape                                                                                                                                                                                                   
filename:       /lib/modules/4.18.0-372.16.1.el8_6.x86_64/kernel/drivers/scsi/lin_tape.ko                                                                                                                                                         
version:        3.0.60                                                                                                                                                                                                                            
license:        GPL                                                                                                                                                                                                                               
description:    IBM Linux SCSI Tape Device Driver for IBM and other vendor Tape Devices                                                                                                                                                           
author:         IBM Corporation                                                                                                                                                                                                                   
rhelversion:    8.6                                                                                                                                                                                                                               
srcversion:     9A6CA28F02C0D32CB09DAD6                                                                                                                                                                                                           
depends:        pfo                                                                                                                                                                                                                               
name:           lin_tape                                                                                                                                                                                                                          
vermagic:       4.18.0-372.16.1.el8_6.x86_64 SMP mod_unload modversions                                                                                                                                                                           
parm:           support_dio: try direct I/O if possible. default is 1--yes. 0--do not try. (int)                                                                                                                                                  
parm:           alternate_pathing: try to enable path failover on all devices. default is 0--off.  1--try to enable. (int)                                                                                                                        
parm:           persistent_n_device: special configuration to allow persistent naming for no rewind on close tape drives.  Special rules must be used. default is 0--OFF.  1--ON (int)                                                            
parm:           dpf_keys: data path failover license key for LTO2/3 drives. default is null. (charp)                                                                                                                                              
parm:           lin_tape_debug: driver debug mode. default is 0--off. 1--on (int)                                                                                                                                                                 
parm:           auto_logging: automatically write volume & simmim logs. default is 0--off. 1--on (int)                                                                                                                                            
parm:           lin_tape_clean_ghosts: clean ghosts on rescan. default is 0--off. 1--on (int)                                                                                                                                                     
parm:           lin_tape_status: driver debug mode. for L3 only (int)                                                                                                                                                                             
parm:           changer_open_reserve: reserve all medium changers on open.  default is 0--off.  1--on (int)                                                                                                                                       
parm:           lto_barcode: returned cartridge bar code length for LTO. default is 8. can be changed to 6 (int)                                                                                                                                  
parm:           ibm3592_barcode: returned cartridge bar code length for 3592. default is 6. can be changed to 8 (int)                                                                                                                             
parm:           petro: special configuration for seismic data. default is 0--OFF.  1--ON (int)                                                                                                                                                    
parm:           wait_on_config: milliseconds to wait during device configuration. default is 0. suggest to set it to 1000 or higher if you have >100 devices attached to one host. (int)                                                          
parm:           default_sys_encryption_proxy: default setting to allow driver to talk to encryption key manager. default is on.  suggest always keep it on. (int)                                                                                 
parm:           default_sys_encryption_write: default encryption policy setting for all drives. default is 2--custom.  1--enable encryption when system-managed encryption method is configured on all drives, 0--disable encryption when System-m
anaged encryption method is configured on all drives (int)                                                                                                                                                                                        
parm:           tape_reserve_type: default reserve type when data path failover is not used. Default is "reserve_6". Can also be "persistent" (string)                                                                                            
parm:           disable_density_on_open: determines whether setting density on open will be blocked.  default is 0--do not block (IE set density) 1--block (IE do not set density) (int)                                                          
parm:           dynamic_attributes: attempt to set dynamic attributes. default is 1--on. 0--off (int)                                                                                                                                             
parm:           busy_retry: retry attempts on device busy status. default is 0--off. Up to 480 retry times to be specified (int)                                                                                                                  
parm:           disable_auto_drive_dump: Disable auto drive dump. default is 0--off. See lin_taped.conf for special/general log configuration parameters (int)                                                                                    
parm:           lin_tape_as_sfmp: sfmp mode. default is 0--off. 1--on. If failvoer enabled lin_tape_as_sfmp enables failover through st/sg interfaces (int)                                                                                       
parm:           dualaccessor_cpf: CPF mode for dual accessor. default is 0--off. 1--on (int)
parm:           lin_tape_ignoreOEM: ignore supported OEM if enabled. default is 0--off. 1--on (int)

On the system, different kernel modules are installed in parallel

$ rpm -qa |grep lin_tape-module
lin_tape-module-4.18.0-477.13.1.el8_8-3.0.60-1.x86_64
lin_tape-module-4.18.0-372.16.1.el8_6-3.0.60-1.x86_64
lin_tape-module-4.18.0-305.el8-3.0.60-1.x86_64

Signing an RPM package (optional)

This entire process is described in Red Hat Enterprise Documentation - Packaging and distributing software - Chapter 4.1. Signing RPM packages

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment