Skip to content

Commit

Permalink
storage: lean on systemd-shutdown to export zpools on shutdown
Browse files Browse the repository at this point in the history
People have reported issues involving non exported zpools at the end of
Ubuntu installations. Diagnosing such issues is tricky because the
`zpool export` commands have to run after the target is unmounted. And
once the target is unmounted, logs can no longer be copied over to the
target so bug reports don't include traces of potential `zpool export`
failures (or failures to unmount target).

Instead of relying on Subiquity's _pre_shutdown hook, we now make use of
systemd-shutdown to export the zpools. The chance of successfully
exporting the zpools is expected to be higher since it will happen later
in the shutdown sequence ; after more mounts have been detached.

Signed-off-by: Olivier Gayot <[email protected]>
(cherry picked from commit 2a33020)
  • Loading branch information
ogayot committed Aug 27, 2024
1 parent f20135f commit 331e71b
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 2 deletions.
7 changes: 7 additions & 0 deletions subiquity/models/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -1986,6 +1986,13 @@ def render(self, mode: ActionRenderMode = ActionRenderMode.DEFAULT):
config["grub"] = self.grub
return config

def systemd_shutdown_commands(self) -> list[list[str]]:
"""Return a list of commands meant to be executed by systemd-shutdown.
We entrust the execution of `zpool export` commands to systemd-shutdown
instead of subiquity's _pre_shutdown hook, in hope that the commands
will more likely succeed."""
return [["zpool", "export", zpool.name] for zpool in self._all(type="zpool")]

def load_probe_data(self, probe_data):
for devname, devdata in probe_data["blockdev"].items():
if int(devdata["attrs"]["size"]) != 0:
Expand Down
2 changes: 0 additions & 2 deletions subiquity/server/controllers/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -1644,5 +1644,3 @@ async def _pre_shutdown(self):
)
else:
await self.app.command_runner.run(["umount", "--recursive", "/target"])
if len(self.model._all(type="zpool")) > 0:
await self.app.command_runner.run(["zpool", "export", "-a"])
22 changes: 22 additions & 0 deletions subiquity/server/controllers/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,25 @@ async def curtin_install(self, *, context, source):

fs_controller = self.app.controllers.Filesystem

def register_shutdown_commands() -> None:
cmds: list[list[str]] = fs_controller.model.systemd_shutdown_commands()

if not cmds:
return

shutdown_dir = root / "usr/lib/systemd/system-shutdown"
shutdown_script = shutdown_dir / "subiquity-storage.shutdown"
shutdown_dir.mkdir(parents=True, exist_ok=True)
with shutdown_script.open(mode="w", encoding="utf-8") as stream:
# Generating a bash script is .. ewww
# Should we place the commands in a JSON file and hardcode a
# script that calls jq or something?
stream.write("#!/bin/bash\n")
for cmd in cmds:
stream.write(shlex.join(cmd))
stream.write("\n")
shutdown_script.chmod(0o755)

async def run_curtin_step(name, stages, step_config, source=None):
config = copy.deepcopy(base_config)
filename = f"subiquity-{name.replace(' ', '-')}.conf"
Expand All @@ -349,6 +368,7 @@ async def run_curtin_step(name, stages, step_config, source=None):
device_map_path=logs_dir / "device-map.json",
),
)
register_shutdown_commands()
elif fs_controller.is_core_boot_classic():
await run_curtin_step(
name="partitioning",
Expand All @@ -368,6 +388,7 @@ async def run_curtin_step(name, stages, step_config, source=None):
device_map_path=logs_dir / "device-map-format.json",
),
)
register_shutdown_commands()
await run_curtin_step(
name="extract",
stages=["extract"],
Expand Down Expand Up @@ -400,6 +421,7 @@ async def run_curtin_step(name, stages, step_config, source=None):
),
source=source,
)
register_shutdown_commands()
await run_curtin_step(
name="extract",
stages=["extract"],
Expand Down

0 comments on commit 331e71b

Please sign in to comment.