@@ -542,7 +542,7 @@ pub(crate) enum Opt {
542542 Note on Rollbacks and the `/etc` Directory:
543543
544544 When you perform a rollback (e.g., with `bootc rollback`), any
545- changes made to files in the `/etc` directory won’ t carry over
545+ changes made to files in the `/etc` directory won' t carry over
546546 to the rolled-back deployment. The `/etc` files will revert
547547 to their state from that previous deployment instead.
548548
@@ -721,6 +721,40 @@ pub(crate) fn require_root(is_container: bool) -> Result<()> {
721721 Ok ( ( ) )
722722}
723723
724+ /// Check if a deployment can perform a soft reboot
725+ fn can_perform_soft_reboot ( deployment : Option < & crate :: spec:: BootEntry > ) -> bool {
726+ deployment. map ( |d| d. soft_reboot_capable ) . unwrap_or ( false )
727+ }
728+
729+ /// Prepare and execute a soft reboot for the given deployment
730+ #[ context( "Preparing soft reboot" ) ]
731+ fn prepare_soft_reboot (
732+ sysroot : & crate :: store:: Storage ,
733+ deployment : & ostree:: Deployment ,
734+ ) -> Result < ( ) > {
735+ let cancellable = ostree:: gio:: Cancellable :: NONE ;
736+ sysroot
737+ . sysroot
738+ . deployment_set_soft_reboot ( deployment, false , cancellable)
739+ . context ( "Failed to prepare soft-reboot" ) ?;
740+ Ok ( ( ) )
741+ }
742+
743+ /// Perform a soft reboot for a staged deployment
744+ #[ context( "Soft reboot staged deployment" ) ]
745+ fn soft_reboot_staged ( sysroot : & crate :: store:: Storage ) -> Result < ( ) > {
746+ println ! ( "Staged deployment is soft-reboot capable, performing soft-reboot..." ) ;
747+
748+ let deployments_list = sysroot. deployments ( ) ;
749+ let staged_deployment = deployments_list
750+ . iter ( )
751+ . find ( |d| d. is_staged ( ) )
752+ . ok_or_else ( || anyhow:: anyhow!( "Failed to find staged deployment" ) ) ?;
753+
754+ prepare_soft_reboot ( sysroot, staged_deployment) ?;
755+ Ok ( ( ) )
756+ }
757+
724758/// A few process changes that need to be made for writing.
725759/// IMPORTANT: This may end up re-executing the current process,
726760/// so anything that happens before this should be idempotent.
@@ -841,6 +875,9 @@ async fn upgrade(opts: UpgradeOpts) -> Result<()> {
841875 println ! ( "Staged update present, not changed." ) ;
842876
843877 if opts. apply {
878+ if can_perform_soft_reboot ( host. status . staged . as_ref ( ) ) {
879+ soft_reboot_staged ( sysroot) ?;
880+ }
844881 crate :: reboot:: reboot ( ) ?;
845882 }
846883 } else if booted_unchanged {
@@ -937,6 +974,12 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
937974 sysroot. update_mtime ( ) ?;
938975
939976 if opts. apply {
977+ // Get updated status to check for soft-reboot capability
978+ let updated_host = crate :: status:: get_status ( sysroot, Some ( & booted_deployment) ) ?. 1 ;
979+
980+ if can_perform_soft_reboot ( updated_host. status . staged . as_ref ( ) ) {
981+ soft_reboot_staged ( sysroot) ?;
982+ }
940983 crate :: reboot:: reboot ( ) ?;
941984 }
942985
@@ -950,6 +993,20 @@ async fn rollback(opts: RollbackOpts) -> Result<()> {
950993 crate :: deploy:: rollback ( sysroot) . await ?;
951994
952995 if opts. apply {
996+ // Get status before rollback to check soft-reboot capability
997+ let host = crate :: status:: get_status_require_booted ( sysroot) ?. 2 ;
998+
999+ if can_perform_soft_reboot ( host. status . rollback . as_ref ( ) ) {
1000+ println ! ( "Rollback deployment is soft-reboot capable, performing soft-reboot..." ) ;
1001+
1002+ let deployments_list = sysroot. deployments ( ) ;
1003+ let target_deployment = deployments_list
1004+ . first ( )
1005+ . ok_or_else ( || anyhow:: anyhow!( "No deployments found after rollback" ) ) ?;
1006+
1007+ prepare_soft_reboot ( sysroot, target_deployment) ?;
1008+ }
1009+
9531010 crate :: reboot:: reboot ( ) ?;
9541011 }
9551012
0 commit comments