Skip to content

Commit

Permalink
s390x: add zVM Secure IPL support
Browse files Browse the repository at this point in the history
  • Loading branch information
nikita-dubrovskii committed Nov 20, 2023
1 parent 77416a8 commit f9e2bf6
Show file tree
Hide file tree
Showing 13 changed files with 116 additions and 3 deletions.
2 changes: 2 additions & 0 deletions data/example-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,7 @@ stream-base-url: URL
preserve-on-error: true
# Fetch retries, or string "infinite"
fetch-retries: N
# Enable IBM Secure IPL
secure-ipl: true
# Destination device
dest-device: path
3 changes: 3 additions & 0 deletions docs/cmd/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,7 @@ Advanced Options:
indefinitely.
[default: 0]
--secure-ipl
Enable IBM Secure IPL
```
2 changes: 2 additions & 0 deletions docs/customizing-install.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ stream-base-url: URL
preserve-on-error: true
# Fetch retries, or string "infinite"
fetch-retries: N
# Enable IBM Secure IPL
secure-ipl: true
# Destination device
dest-device: path
```
Expand Down
1 change: 1 addition & 0 deletions docs/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ nav_order: 8

Major changes:

- install: Add zVM Secure IPL support

Minor changes:

Expand Down
5 changes: 4 additions & 1 deletion man/coreos-installer-install.8
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
.SH NAME
coreos\-installer\-install \- Install Fedora CoreOS or RHEL CoreOS
.SH SYNOPSIS
\fBcoreos\-installer\-install\fR [\fB\-c\fR|\fB\-\-config\-file\fR] [\fB\-s\fR|\fB\-\-stream\fR] [\fB\-u\fR|\fB\-\-image\-url\fR] [\fB\-f\fR|\fB\-\-image\-file\fR] [\fB\-i\fR|\fB\-\-ignition\-file\fR] [\fB\-I\fR|\fB\-\-ignition\-url\fR] [\fB\-\-ignition\-hash\fR] [\fB\-a\fR|\fB\-\-architecture\fR] [\fB\-p\fR|\fB\-\-platform\fR] [\fB\-\-console\fR] [\fB\-\-append\-karg\fR] [\fB\-\-delete\-karg\fR] [\fB\-n\fR|\fB\-\-copy\-network\fR] [\fB\-\-network\-dir\fR] [\fB\-\-save\-partlabel\fR] [\fB\-\-save\-partindex\fR] [\fB\-\-offline\fR] [\fB\-\-insecure\fR] [\fB\-\-insecure\-ignition\fR] [\fB\-\-stream\-base\-url\fR] [\fB\-\-preserve\-on\-error\fR] [\fB\-\-fetch\-retries\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] [\fIDEST_DEVICE\fR]
\fBcoreos\-installer\-install\fR [\fB\-c\fR|\fB\-\-config\-file\fR] [\fB\-s\fR|\fB\-\-stream\fR] [\fB\-u\fR|\fB\-\-image\-url\fR] [\fB\-f\fR|\fB\-\-image\-file\fR] [\fB\-i\fR|\fB\-\-ignition\-file\fR] [\fB\-I\fR|\fB\-\-ignition\-url\fR] [\fB\-\-ignition\-hash\fR] [\fB\-a\fR|\fB\-\-architecture\fR] [\fB\-p\fR|\fB\-\-platform\fR] [\fB\-\-console\fR] [\fB\-\-append\-karg\fR] [\fB\-\-delete\-karg\fR] [\fB\-n\fR|\fB\-\-copy\-network\fR] [\fB\-\-network\-dir\fR] [\fB\-\-save\-partlabel\fR] [\fB\-\-save\-partindex\fR] [\fB\-\-offline\fR] [\fB\-\-insecure\fR] [\fB\-\-insecure\-ignition\fR] [\fB\-\-stream\-base\-url\fR] [\fB\-\-preserve\-on\-error\fR] [\fB\-\-fetch\-retries\fR] [\fB\-\-secure\-ipl\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] [\fIDEST_DEVICE\fR]
.SH DESCRIPTION
Install Fedora CoreOS or RHEL CoreOS
.SH OPTIONS
Expand Down Expand Up @@ -123,6 +123,9 @@ Fetch retries, or "infinite"

Number of times to retry network fetches, or the string "infinite" to retry indefinitely.
.TP
\fB\-\-secure\-ipl\fR
Enable IBM Secure IPL
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help (see a summary with \*(Aq\-h\*(Aq)
.TP
Expand Down
5 changes: 5 additions & 0 deletions scripts/coreos-installer-service
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ if karg_bool coreos.inst.insecure; then
args+=("--insecure")
fi

# zVM Secure IPL support
if karg_bool coreos.inst.secure_ipl; then
args+=("--secure-ipl")
fi

# Always retry HTTP requests; we've got nothing to lose since we fail anyway.
args+=("--fetch-retries" "infinite")

Expand Down
7 changes: 7 additions & 0 deletions src/cmdline/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,10 @@ pub struct InstallConfig {
#[serde(skip_serializing_if = "is_default")]
#[arg(long, value_name = "N", default_value_t, help_heading = ADVANCED)]
pub fetch_retries: FetchRetries,
/// Enable IBM Secure IPL
#[serde(skip_serializing_if = "is_default")]
#[arg(long, help_heading = ADVANCED)]
pub secure_ipl: bool,

// positional args
/// Destination device
Expand Down Expand Up @@ -361,6 +365,7 @@ mod test {
stream_base_url: Some(Url::parse("http://example.com/t").unwrap()),
preserve_on_error: true,
fetch_retries: FetchRetries::from_str("3").unwrap(),
secure_ipl: true,
dest_device: Some("u".into()),
};
let expected = vec![
Expand Down Expand Up @@ -412,6 +417,7 @@ mod test {
"--preserve-on-error",
"--fetch-retries",
"3",
"--secure-ipl",
"u",
];
assert_eq!(config.to_args().unwrap(), expected);
Expand Down Expand Up @@ -484,6 +490,7 @@ dest-device: u
stream_base_url: Some(Url::parse("http://example.com/t").unwrap()),
preserve_on_error: true,
fetch_retries: FetchRetries::from_str("3").unwrap(),
secure_ipl: false,
dest_device: Some("u".into()),
};
let config = InstallConfig::from_args(&["--config-file", f.path().to_str().unwrap()])
Expand Down
3 changes: 3 additions & 0 deletions src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,9 @@ fn write_disk(
None,
)?;
s390x::chreipl(device)?;
if config.secure_ipl {
s390x::set_loaddev(device)?;
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/s390x/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub mod zipl;

pub use dasd::{dasd_try_get_sector_size, image_copy_s390x, prepare_dasd};
pub use zipl::chreipl;
pub use zipl::set_loaddev;
pub use zipl::zipl;
mod eckd;
mod fba;
Expand Down
68 changes: 66 additions & 2 deletions src/s390x/zipl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@

use crate::blockdev::Mount;
use crate::io::{visit_bls_entry, visit_bls_entry_options, Initrd, KargsEditor};
use crate::runcmd;
use crate::s390x::ZiplSecexMode;
use crate::util::cmd_output;
use anyhow::{anyhow, Context, Result};
use crate::{runcmd, runcmd_output};
use anyhow::{anyhow, bail, Context, Result};
use lazy_static::lazy_static;
use nix::mount::MsFlags;
use regex::Regex;
use std::fs::{copy, create_dir_all, read_dir, DirEntry, File};
Expand All @@ -33,6 +34,69 @@ pub fn chreipl<P: AsRef<Path>>(dev: P) -> Result<()> {
Ok(())
}

/// Sets zVM secure loaddev to `dev`.
pub fn set_loaddev<P: AsRef<Path>>(dev: P) -> Result<()> {
eprintln!("Setting LOADDEV");
let output = runcmd_output!(
"lszdev",
"-n",
"--columns",
"TYPE,ID",
"--by-node",
dev.as_ref()
)?;
let (devtype, id) = output
.trim()
.split_once(' ')
.with_context(|| format!("parsing lszdev {output}"))?;

let mut cmd = Command::new("vmcp");
cmd.arg("set").arg("loaddev");
match devtype {
"dasd-eckd" => {
lazy_static! {
static ref REGEX: Regex =
Regex::new(r#"[[:digit:]].[[:digit:]].([[:xdigit:]]+)"#).unwrap();
}
for cap in REGEX.captures_iter(id) {
cmd.arg("eckd").arg("dev").arg(&cap[1]);
}
}
"zfcp-lun" => {
lazy_static! {
static ref REGEX: Regex = Regex::new(
r#"[[:digit:]].[[:digit:]].([[:xdigit:]]+):0x([[:xdigit:]]+):0x([[:xdigit:]]+)"#
)
.unwrap();
}
// CP tool wants portname/lun to be splitted at 8th character:
// $ vmcp set loaddev dev 8007 portname 500507630400d1e3 lun 4001404c00000000 secure
// HCPZPM002E Invalid operand - 500507630400D1E3

// $ vmcp set loaddev dev 8007 portname 50050763 0400d1e3 lun 4001404c 00000000 secure
// $ vmcp q loaddev
// SCSI DEVICE 8007 SECURE
// PORTNAME 50050763 0400D1E3 LUN 4001404C 00000000 BOOTPROG 0
// BR_LBA 00000000 00000000

for cap in REGEX.captures_iter(id) {
cmd.arg("dev")
.arg(&cap[1])
.arg("portname")
.arg(&cap[2][0..8])
.arg(&cap[2][8..])
.arg("lun")
.arg(&cap[3][0..8])
.arg(&cap[3][8..]);
}
}
_ => bail!("unsupported device: {} id: {}", devtype, id),
};
cmd.arg("secure");
cmd_output(&mut cmd)?;
Ok(())
}

fn secure_execution_is_enabled() -> Result<bool> {
let sysfs_flag = "/sys/firmware/uv/prot_virt_guest";
match File::open(sysfs_flag) {
Expand Down
5 changes: 5 additions & 0 deletions systemd/coreos-installer-generator
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,9 @@ if [ -n "$(karg coreos.inst.install_dev)" -o \
if ! karg_bool coreos.inst.skip_reboot; then
touch /run/coreos-installer-reboot
fi

# Create precondition for coreos-installer-reboot-loaddev.service if requested
if karg_bool coreos.inst.secure_ipl; then
touch /run/coreos-installer-loaddev
fi
fi
1 change: 1 addition & 0 deletions systemd/coreos-installer-post.target
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ AllowIsolate=yes
Requires=coreos-installer.target
Requires=coreos-installer-reboot.service
Requires=coreos-installer-noreboot.service
Requires=coreos-installer-reboot-loaddev.service
16 changes: 16 additions & 0 deletions systemd/coreos-installer-reboot-loaddev.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[Unit]
Description=Reboot from zVM LOADDEV after CoreOS Installer
ConditionVirtualization=zvm
ConditionPathExists=/run/coreos-installer-loaddev

Requires=coreos-installer.target
After=coreos-installer.target
After=coreos-installer-reboot.service
OnFailure=emergency.target
OnFailureJobMode=replace-irreversibly

[Service]
Type=simple
ExecStart=/usr/sbin/vmcp ipl loaddev
StandardOutput=kmsg+console
StandardError=kmsg+console

0 comments on commit f9e2bf6

Please sign in to comment.