@@ -107,6 +107,78 @@ custom_mounts = []
107107 assert ! ( !config. to_toml( ) . unwrap( ) . contains( "custom_mounts" ) ) ;
108108}
109109
110+ #[ test]
111+ fn boot_upgrade_ignores_retired_daemon_mode_without_losing_rules ( ) {
112+ let dir = test_dir ( "legacy-daemon-mode" ) ;
113+ fs:: create_dir_all ( & dir) . unwrap ( ) ;
114+ let path = dir. join ( "config.toml" ) ;
115+ // Issue #409: this obsolete key caused strict boot loading to abort.
116+ let original = r#"moduledir = "/data/adb/modules"
117+ mountsource = "KSU"
118+ overlay_mode = "tmpfs"
119+ disable_umount = true
120+ default_mode = "magic"
121+ daemon_startup_mode = "persistent"
122+ custom_mounts = []
123+
124+ [rules.demo]
125+ default_mode = "ignore"
126+ [rules.demo.paths]
127+ "system/etc/hosts" = "overlay"
128+ "# ;
129+ fs:: write ( & path, original) . unwrap ( ) ;
130+
131+ let loaded = Config :: load_for_boot ( & path) . unwrap ( ) ;
132+
133+ assert_eq ! ( loaded. default_mode, Mode :: Magic ) ;
134+ assert_eq ! ( loaded. overlay_mode, OverlayMode :: Tmpfs ) ;
135+ assert ! ( loaded. disable_umount) ;
136+ assert_eq ! ( loaded. rules[ "demo" ] . default_mode, Some ( Mode :: Ignore ) ) ;
137+ assert_eq ! (
138+ loaded. rules[ "demo" ] . paths[ "system/etc/hosts" ] ,
139+ Mode :: Overlay
140+ ) ;
141+ assert ! ( loaded. legacy_daemon_startup_mode. is_none( ) ) ;
142+ assert_eq ! ( Config :: load_or_default( & path) . unwrap( ) , loaded) ;
143+ assert_eq ! ( fs:: read_to_string( & path) . unwrap( ) , original) ;
144+
145+ loaded. save ( & path) . unwrap ( ) ;
146+ assert ! (
147+ !fs:: read_to_string( & path)
148+ . unwrap( )
149+ . contains( "daemon_startup_mode" )
150+ ) ;
151+ assert_eq ! ( Config :: load_for_boot( & path) . unwrap( ) , loaded) ;
152+ cleanup ( & dir) ;
153+ }
154+
155+ #[ test]
156+ fn retired_daemon_mode_does_not_allow_unknown_or_malformed_config ( ) {
157+ for ( name, text) in [
158+ (
159+ "unknown" ,
160+ "daemon_startup_mode = \" persistent\" \n unknown_setting = true\n " ,
161+ ) ,
162+ ( "wrong-type" , "daemon_startup_mode = 42\n " ) ,
163+ (
164+ "malformed" ,
165+ "daemon_startup_mode = \" persistent\" \n rules = [" ,
166+ ) ,
167+ ] {
168+ let dir = test_dir ( & format ! ( "legacy-daemon-{name}" ) ) ;
169+ fs:: create_dir_all ( & dir) . unwrap ( ) ;
170+ let path = dir. join ( "config.toml" ) ;
171+ fs:: write ( & path, text) . unwrap ( ) ;
172+
173+ assert ! ( matches!(
174+ Config :: load_for_boot( & path) ,
175+ Err ( Error :: ConfigParse { .. } )
176+ ) ) ;
177+ assert_eq ! ( fs:: read_to_string( & path) . unwrap( ) , text) ;
178+ cleanup ( & dir) ;
179+ }
180+ }
181+
110182#[ test]
111183fn invalid_module_id_rule_key_is_rejected_with_context ( ) {
112184 let err = Config :: from_toml (
0 commit comments