diff mbox series

[v2] base-files: restore status of system-services after sysupgrade

Message ID 20210111220726.23069-1-devel-sven@geroedel.de
State New
Headers show
Series [v2] base-files: restore status of system-services after sysupgrade | expand

Commit Message

Sven Roederer Jan. 11, 2021, 10:07 p.m. UTC
Restore the status of the system-services after sysupgrade.
Create a file with the status of all known services and keep it during
upgrade. After upgrade run a uci-default script to restore every
single service.
The list of the service status will be stored in etc/backup folder also
and formated as:
/etc/init.d/<service> {enable|disable}

When upgrading with an generic image all system services are enabled by
default which is usually not expected and can cause trouble.
The default behavior can be flipped with the "-s" option of sysupgrade.

Signed-off-by: Sven Roederer <devel-sven@geroedel.de>
---

This v2 includes the feedback from the mailinglist:
* entangles this feature from "storing the packagelist"
* adds a option for disabling to sysupgrade
* makes it enabled by default
* includes the glue-script to restore the services after upgrade

I was not able to test on a real system yet.

 package/base-files/Makefile                   |  2 +-
 .../uci-defaults/14_restore-services-state    |  3 ++
 package/base-files/files/sbin/sysupgrade      | 38 ++++++++++++++-----
 3 files changed, 32 insertions(+), 11 deletions(-)
 create mode 100644 package/base-files/files/etc/uci-defaults/14_restore-services-state

Comments

Martin Schiller Jan. 12, 2021, 7:25 a.m. UTC | #1
On 2021-01-11 23:07, Sven Roederer wrote:
> Restore the status of the system-services after sysupgrade.
> Create a file with the status of all known services and keep it during
> upgrade. After upgrade run a uci-default script to restore every
> single service.

Doing the restore in an uci-default script is to late, because then you
are already in the procd rcS helper "loop" and new added init links
won't get called.

Also, have you thought about a backup/restore of the configuration?
The whole thing should/must work there as well.

I would do the restore at the end of the pre-init stage.

Martin
Simonas Tamošaitis Jan. 12, 2021, 11:45 a.m. UTC | #2
On 1/12/21 12:07 AM, Sven Roederer wrote:
> Restore the status of the system-services after sysupgrade.
> Create a file with the status of all known services and keep it during
> upgrade. After upgrade run a uci-default script to restore every
> single service.
> The list of the service status will be stored in etc/backup folder also
> and formated as:
> /etc/init.d/<service> {enable|disable}
>
> When upgrading with an generic image all system services are enabled by
> default which is usually not expected and can cause trouble.
> The default behavior can be flipped with the "-s" option of sysupgrade.
>
> Signed-off-by: Sven Roederer <devel-sven@geroedel.de>
> ---
>
> This v2 includes the feedback from the mailinglist:
> * entangles this feature from "storing the packagelist"
> * adds a option for disabling to sysupgrade
> * makes it enabled by default
> * includes the glue-script to restore the services after upgrade
>
> I was not able to test on a real system yet.
>
>   package/base-files/Makefile                   |  2 +-
>   .../uci-defaults/14_restore-services-state    |  3 ++
>   package/base-files/files/sbin/sysupgrade      | 38 ++++++++++++++-----
>   3 files changed, 32 insertions(+), 11 deletions(-)
>   create mode 100644 package/base-files/files/etc/uci-defaults/14_restore-services-state
>
> diff --git a/package/base-files/Makefile b/package/base-files/Makefile
> index f18f221129..5a9bacba13 100644
> --- a/package/base-files/Makefile
> +++ b/package/base-files/Makefile
> @@ -12,7 +12,7 @@ include $(INCLUDE_DIR)/version.mk
>   include $(INCLUDE_DIR)/feeds.mk
>   
>   PKG_NAME:=base-files
> -PKG_RELEASE:=246
> +PKG_RELEASE:=247
>   PKG_FLAGS:=nonshared
>   
>   PKG_FILE_DEPENDS:=$(PLATFORM_DIR)/ $(GENERIC_PLATFORM_DIR)/base-files/
> diff --git a/package/base-files/files/etc/uci-defaults/14_restore-services-state b/package/base-files/files/etc/uci-defaults/14_restore-services-state
> new file mode 100644
> index 0000000000..d0085f3f80
> --- /dev/null
> +++ b/package/base-files/files/etc/uci-defaults/14_restore-services-state
> @@ -0,0 +1,3 @@
> +SERVICE_STATUS=/etc/backup/service_status.txt
> +
> +[ -e ${SERVICE_STATUS} ] && . ${SERVICE_STATUS}
> diff --git a/package/base-files/files/sbin/sysupgrade b/package/base-files/files/sbin/sysupgrade
> index 50f4e08e44..068ec27e3d 100755
> --- a/package/base-files/files/sbin/sysupgrade
> +++ b/package/base-files/files/sbin/sysupgrade
> @@ -15,6 +15,7 @@ export SAVE_OVERLAY_PATH=
>   export SAVE_PARTITIONS=1
>   export SAVE_INSTALLED_PKGS=0
>   export SKIP_UNCHANGED=1
> +export SAVE_SERVICE_STATUS=1
>   export CONF_IMAGE=
>   export CONF_BACKUP_LIST=0
>   export CONF_BACKUP=
> @@ -35,6 +36,7 @@ while [ -n "$1" ]; do
>   		-c) export SAVE_OVERLAY=1 SAVE_OVERLAY_PATH=/etc;;
>   		-o) export SAVE_OVERLAY=1 SAVE_OVERLAY_PATH=/;;
>   		-p) export SAVE_PARTITIONS=0;;
> +		-s) export SAVE_SERVICE_STATUS=0;;
>   		-k) export SAVE_INSTALLED_PKGS=1;;
>   		-U) export SKIP_UNCHANGED=0;;
>   		-b|--create-backup) export CONF_BACKUP="$2" NEED_IMAGE=1; shift;;
> @@ -57,13 +59,14 @@ export CONFFILES=/tmp/sysupgrade.conffiles
>   export CONF_TAR=/tmp/sysupgrade.tgz
>   export ETCBACKUP_DIR=/etc/backup
>   export INSTALLED_PACKAGES=${ETCBACKUP_DIR}/installed_packages.txt
> +export SERVICE_STATUS=${ETCBACKUP_DIR}/service_status.txt
>   
>   IMAGE="$1"
>   
>   [ -z "$IMAGE" -a -z "$NEED_IMAGE" -a $CONF_BACKUP_LIST -eq 0 -o $HELP -gt 0 ] && {
>   	cat <<EOF
>   Usage: $0 [<upgrade-option>...] <image file or URL>
> -       $0 [-q] [-i] [-c] [-U] [-o] [-k] <backup-command> <file>
> +       $0 [-q] [-i] [-c] [-U] [-o] [-s] [-k] <backup-command> <file>
>   
>   upgrade-option:
>   	-f <config>  restore configuration from .tar.gz (file or url)
> @@ -75,6 +78,7 @@ upgrade-option:
>   	             (this is a modification of Freifunk Berlin to unset -u)
>   	-n           do not save configuration over reflash
>   	-p           do not attempt to restore the partition table after flash.
> +	-s           do not attempt to restore the status of the services.
>   	-k           include in backup a list of current installed packages at
>   	             $INSTALLED_PACKAGES
>   	-T | --test
> @@ -231,8 +235,7 @@ do_save_conffiles() {
>   	run_hooks "$CONFFILES" $sysupgrade_init_conffiles
>   	ask_bool 0 "Edit config file list" && vi "$CONFFILES"
>   
> -	if [ "$SAVE_INSTALLED_PKGS" -eq 1 ]; then
> -		echo "${INSTALLED_PACKAGES}" >> "$CONFFILES"
> +	if [ "$SAVE_INSTALLED_PKGS" -eq 1 ] || [ "$SAVE_SERVICE_STATUS" -eq 1 ]; then
>   		mkdir -p "$ETCBACKUP_DIR"
>   		# Avoid touching filesystem on each backup
>   		RAMFS="$(mktemp -d -t sysupgrade.XXXXXX)"
> @@ -243,13 +246,28 @@ do_save_conffiles() {
>   				ask_bool 0 "Abort" && exit
>   			}
>   
> -		# Format: pkg-name<TAB>{rom,overlay,unkown}
> -		# rom is used for pkgs in /rom, even if updated later
> -		find /usr/lib/opkg/info -name "*.control" \( \
> -			\( -exec test -f /rom/{} \; -exec echo {} rom \; \) -o \
> -			\( -exec test -f /overlay/upper/{} \; -exec echo {} overlay \; \) -o \
> -			\( -exec echo {} unknown \; \) \
> -			\) | sed -e 's,.*/,,;s/\.control /\t/' > ${INSTALLED_PACKAGES}
> +		if [ "$SAVE_INSTALLED_PKGS" -eq 1 ]; then
> +			echo "${INSTALLED_PACKAGES}" >> "$CONFFILES"
> +			# Format: pkg-name<TAB>{rom,overlay,unkown}
> +			# rom is used for pkgs in /rom, even if updated later
> +			find /usr/lib/opkg/info -name "*.control" \( \
> +				\( -exec test -f /rom/{} \; -exec echo {} rom \; \) -o \
> +				\( -exec test -f /overlay/upper/{} \; -exec echo {} overlay \; \) -o \
> +				\( -exec echo {} unknown \; \) \
> +					\) | sed -e 's,.*/,,;s/\.control /\t/' > ${INSTALLED_PACKAGES}
> +		fi
> +
> +		if [ "$SAVE_SERVICE_STATUS" -eq 1 ]; then
> +			echo "${SERVICE_STATUS}" >> "$CONFFILES"
> +			# Format: /etc/init.d/servicename {enable,disable}
> +			rm -f ${SERVICE_STATUS}
> +			for service in /etc/init.d/* ; do \
> +				${service} enabled && \
> +					echo >> ${SERVICE_STATUS} "$service" "enable" || \
> +					echo >> ${SERVICE_STATUS} "$service" "disable" \
> +				; \
> +			done
> +		fi
>   	fi
>   
>   	v "Saving config files..."
Hello,
You don't have to run such complicated script. Just restore /etc/rc.d/ 
directory after upgrade.
Adrian Schmutzler Jan. 12, 2021, 12:01 p.m. UTC | #3
> > @@ -231,8 +235,7 @@ do_save_conffiles() {
> >   	run_hooks "$CONFFILES" $sysupgrade_init_conffiles
> >   	ask_bool 0 "Edit config file list" && vi "$CONFFILES"
> >
> > -	if [ "$SAVE_INSTALLED_PKGS" -eq 1 ]; then
> > -		echo "${INSTALLED_PACKAGES}" >> "$CONFFILES"
> > +	if [ "$SAVE_INSTALLED_PKGS" -eq 1 ] || [ "$SAVE_SERVICE_STATUS"
> -eq
> > +1 ]; then
> >   		mkdir -p "$ETCBACKUP_DIR"
> >   		# Avoid touching filesystem on each backup
> >   		RAMFS="$(mktemp -d -t sysupgrade.XXXXXX)"
> > @@ -243,13 +246,28 @@ do_save_conffiles() {
> >   				ask_bool 0 "Abort" && exit
> >   			}
> >
> > -		# Format: pkg-name<TAB>{rom,overlay,unkown}
> > -		# rom is used for pkgs in /rom, even if updated later
> > -		find /usr/lib/opkg/info -name "*.control" \( \
> > -			\( -exec test -f /rom/{} \; -exec echo {} rom \; \) -o \
> > -			\( -exec test -f /overlay/upper/{} \; -exec echo {}
> overlay \; \) -o \
> > -			\( -exec echo {} unknown \; \) \
> > -			\) | sed -e 's,.*/,,;s/\.control /\t/' >
> ${INSTALLED_PACKAGES}
> > +		if [ "$SAVE_INSTALLED_PKGS" -eq 1 ]; then
> > +			echo "${INSTALLED_PACKAGES}" >> "$CONFFILES"
> > +			# Format: pkg-name<TAB>{rom,overlay,unkown}
> > +			# rom is used for pkgs in /rom, even if updated later
> > +			find /usr/lib/opkg/info -name "*.control" \( \
> > +				\( -exec test -f /rom/{} \; -exec echo {} rom \;
> \) -o \
> > +				\( -exec test -f /overlay/upper/{} \; -exec
> echo {} overlay \; \) -o \
> > +				\( -exec echo {} unknown \; \) \
> > +					\) | sed -e 's,.*/,,;s/\.control /\t/' >
> ${INSTALLED_PACKAGES}
> > +		fi
> > +
> > +		if [ "$SAVE_SERVICE_STATUS" -eq 1 ]; then
> > +			echo "${SERVICE_STATUS}" >> "$CONFFILES"
> > +			# Format: /etc/init.d/servicename {enable,disable}
> > +			rm -f ${SERVICE_STATUS}
> > +			for service in /etc/init.d/* ; do \
> > +				${service} enabled && \
> > +					echo >> ${SERVICE_STATUS}
> "$service" "enable" || \
> > +					echo >> ${SERVICE_STATUS}
> "$service" "disable" \
> > +				; \
> > +			done
> > +		fi
> >   	fi
> >
> >   	v "Saving config files..."
> Hello,
> You don't have to run such complicated script. Just restore /etc/rc.d/
> directory after upgrade.
> 

Well, that depends on how we want to deal with new services. If I upgrade from 19.07.5 to master, I'd expect new services to be in their default initial state. Restoring "old" rc.d would have everything new disabled. That's counter-intuitive for me.

Best

Adrian
Hannu Nyman Jan. 12, 2021, 6:56 p.m. UTC | #4
Martin Schiller kirjoitti 12.1.2021 klo 9.25:
> On 2021-01-11 23:07, Sven Roederer wrote:
>> Restore the status of the system-services after sysupgrade.
>> Create a file with the status of all known services and keep it during
>> upgrade. After upgrade run a uci-default script to restore every
>> single service.
>
> Doing the restore in an uci-default script is to late, because then you
> are already in the procd rcS helper "loop" and new added init links
> won't get called.
>
> Also, have you thought about a backup/restore of the configuration?
> The whole thing should/must work there as well.
>
> I would do the restore at the end of the pre-init stage.
>
> Martin


My two cents to the discussion:

* I assume that a small minority of users actually disable services, or at 
least disable several services, so defaulting to "lets by default always 
store status of all services" sounds like overkill.

* Backuping always info that the dozens of standard services are enabled 
sounds unncessary. As services are installed by default as "enabled" to the 
image, it might make sense to store only info about "disabled" services and 
disable those when restoring the backup in sysupgrade.  (Re-enabling the 
already enabled services is unnecessary.)  That would also help to keep the 
amount of new backup info small.

* make clear in sysupgrade script help texts and documentation that 
saving/restoring service status depends on "keep settings". If settings are 
not kept, the service status can not be copied in sysupugrade as there is no 
sysupgrade.tar.gz to be passed. (And naturally it would not even make sense 
to e.g. revert network settings to defaults but keep selected network 
services disabled. Easy to cause soft-bricks that way.)
Sven Roederer Jan. 12, 2021, 10:03 p.m. UTC | #5
Am Dienstag, 12. Januar 2021, 19:56:54 CET schrieb Hannu Nyman:
> Martin Schiller kirjoitti 12.1.2021 klo 9.25:
> > On 2021-01-11 23:07, Sven Roederer wrote:
> >> Restore the status of the system-services after sysupgrade.
> >> Create a file with the status of all known services and keep it during
> >> upgrade. After upgrade run a uci-default script to restore every
> >> single service.
> > 
> > Doing the restore in an uci-default script is to late, because then you
> > are already in the procd rcS helper "loop" and new added init links
> > won't get called.
> > 
> > Also, have you thought about a backup/restore of the configuration?
> > The whole thing should/must work there as well.
> > 
> > I would do the restore at the end of the pre-init stage.
> > 
> > Martin
> 
> My two cents to the discussion:
> 
> * I assume that a small minority of users actually disable services, or at
> least disable several services, so defaulting to "lets by default always
> store status of all services" sounds like overkill.
> 
> * Backuping always info that the dozens of standard services are enabled
> sounds unncessary. As services are installed by default as "enabled" to the
> image, it might make sense to store only info about "disabled" services and
> disable those when restoring the backup in sysupgrade.  (Re-enabling the
> already enabled services is unnecessary.)  That would also help to keep the
> amount of new backup info small.
> 
> * make clear in sysupgrade script help texts and documentation that
> saving/restoring service status depends on "keep settings". If settings are
> not kept, the service status can not be copied in sysupugrade as there is no
> sysupgrade.tar.gz to be passed. (And naturally it would not even make sense
> to e.g. revert network settings to defaults but keep selected network
> services disabled. Easy to cause soft-bricks that way.)
> 
> 
Hannu,

as long as no service was disabled with the "DISABLED_SERVICES" option of the 
imagebuilder the explicit "enable" is not required.
Indeed enabling a service that have been disabled during image creation is a 
bit edge-case, but I prefer here the "full featured" way. Not enabling such a 
service also breaks the user experience like the disable case.

For sure I can add a explicit note, that the "-n" option will not keep the 
states. But "do not save configuration over reflash" imho implicitly means all 
image defaults are used.
Sven Roederer Jan. 12, 2021, 10:05 p.m. UTC | #6
Am Dienstag, 12. Januar 2021, 13:01:45 CET schrieb Adrian Schmutzler:
> > Hello,
> > You don't have to run such complicated script. Just restore /etc/rc.d/
> > directory after upgrade.
> 
> Well, that depends on how we want to deal with new services. If I upgrade
> from 19.07.5 to master, I'd expect new services to be in their default
> initial state. Restoring "old" rc.d would have everything new disabled.
> That's counter-intuitive for me.

I'm also in favor of not touching new services, which have not been installed 
before the upgrade.

Sven
Martin Schiller Jan. 13, 2021, 5:54 a.m. UTC | #7
On 2021-01-12 23:03, Sven Roederer wrote:
> Am Dienstag, 12. Januar 2021, 19:56:54 CET schrieb Hannu Nyman:
>> Martin Schiller kirjoitti 12.1.2021 klo 9.25:
>> > On 2021-01-11 23:07, Sven Roederer wrote:
>> >> Restore the status of the system-services after sysupgrade.
>> >> Create a file with the status of all known services and keep it during
>> >> upgrade. After upgrade run a uci-default script to restore every
>> >> single service.
>> >
>> > Doing the restore in an uci-default script is to late, because then you
>> > are already in the procd rcS helper "loop" and new added init links
>> > won't get called.
>> >
>> > Also, have you thought about a backup/restore of the configuration?
>> > The whole thing should/must work there as well.
>> >
>> > I would do the restore at the end of the pre-init stage.
>> >
>> > Martin
>> 
>> My two cents to the discussion:
>> 
>> * I assume that a small minority of users actually disable services, 
>> or at
>> least disable several services, so defaulting to "lets by default 
>> always
>> store status of all services" sounds like overkill.
>> 
>> * Backuping always info that the dozens of standard services are 
>> enabled
>> sounds unncessary. As services are installed by default as "enabled" 
>> to the
>> image, it might make sense to store only info about "disabled" 
>> services and
>> disable those when restoring the backup in sysupgrade.  (Re-enabling 
>> the
>> already enabled services is unnecessary.)  That would also help to 
>> keep the
>> amount of new backup info small.
>> 
>> * make clear in sysupgrade script help texts and documentation that
>> saving/restoring service status depends on "keep settings". If 
>> settings are
>> not kept, the service status can not be copied in sysupugrade as there 
>> is no
>> sysupgrade.tar.gz to be passed. (And naturally it would not even make 
>> sense
>> to e.g. revert network settings to defaults but keep selected network
>> services disabled. Easy to cause soft-bricks that way.)
>> 
>> 
> Hannu,
> 
> as long as no service was disabled with the "DISABLED_SERVICES" option 
> of the
> imagebuilder the explicit "enable" is not required.
> Indeed enabling a service that have been disabled during image creation 
> is a
> bit edge-case, but I prefer here the "full featured" way. Not enabling 
> such a
> service also breaks the user experience like the disable case.

I totally agree. If you do this, you should cover all cases.
diff mbox series

Patch

diff --git a/package/base-files/Makefile b/package/base-files/Makefile
index f18f221129..5a9bacba13 100644
--- a/package/base-files/Makefile
+++ b/package/base-files/Makefile
@@ -12,7 +12,7 @@  include $(INCLUDE_DIR)/version.mk
 include $(INCLUDE_DIR)/feeds.mk
 
 PKG_NAME:=base-files
-PKG_RELEASE:=246
+PKG_RELEASE:=247
 PKG_FLAGS:=nonshared
 
 PKG_FILE_DEPENDS:=$(PLATFORM_DIR)/ $(GENERIC_PLATFORM_DIR)/base-files/
diff --git a/package/base-files/files/etc/uci-defaults/14_restore-services-state b/package/base-files/files/etc/uci-defaults/14_restore-services-state
new file mode 100644
index 0000000000..d0085f3f80
--- /dev/null
+++ b/package/base-files/files/etc/uci-defaults/14_restore-services-state
@@ -0,0 +1,3 @@ 
+SERVICE_STATUS=/etc/backup/service_status.txt
+
+[ -e ${SERVICE_STATUS} ] && . ${SERVICE_STATUS}
diff --git a/package/base-files/files/sbin/sysupgrade b/package/base-files/files/sbin/sysupgrade
index 50f4e08e44..068ec27e3d 100755
--- a/package/base-files/files/sbin/sysupgrade
+++ b/package/base-files/files/sbin/sysupgrade
@@ -15,6 +15,7 @@  export SAVE_OVERLAY_PATH=
 export SAVE_PARTITIONS=1
 export SAVE_INSTALLED_PKGS=0
 export SKIP_UNCHANGED=1
+export SAVE_SERVICE_STATUS=1
 export CONF_IMAGE=
 export CONF_BACKUP_LIST=0
 export CONF_BACKUP=
@@ -35,6 +36,7 @@  while [ -n "$1" ]; do
 		-c) export SAVE_OVERLAY=1 SAVE_OVERLAY_PATH=/etc;;
 		-o) export SAVE_OVERLAY=1 SAVE_OVERLAY_PATH=/;;
 		-p) export SAVE_PARTITIONS=0;;
+		-s) export SAVE_SERVICE_STATUS=0;;
 		-k) export SAVE_INSTALLED_PKGS=1;;
 		-U) export SKIP_UNCHANGED=0;;
 		-b|--create-backup) export CONF_BACKUP="$2" NEED_IMAGE=1; shift;;
@@ -57,13 +59,14 @@  export CONFFILES=/tmp/sysupgrade.conffiles
 export CONF_TAR=/tmp/sysupgrade.tgz
 export ETCBACKUP_DIR=/etc/backup
 export INSTALLED_PACKAGES=${ETCBACKUP_DIR}/installed_packages.txt
+export SERVICE_STATUS=${ETCBACKUP_DIR}/service_status.txt
 
 IMAGE="$1"
 
 [ -z "$IMAGE" -a -z "$NEED_IMAGE" -a $CONF_BACKUP_LIST -eq 0 -o $HELP -gt 0 ] && {
 	cat <<EOF
 Usage: $0 [<upgrade-option>...] <image file or URL>
-       $0 [-q] [-i] [-c] [-U] [-o] [-k] <backup-command> <file>
+       $0 [-q] [-i] [-c] [-U] [-o] [-s] [-k] <backup-command> <file>
 
 upgrade-option:
 	-f <config>  restore configuration from .tar.gz (file or url)
@@ -75,6 +78,7 @@  upgrade-option:
 	             (this is a modification of Freifunk Berlin to unset -u)
 	-n           do not save configuration over reflash
 	-p           do not attempt to restore the partition table after flash.
+	-s           do not attempt to restore the status of the services.
 	-k           include in backup a list of current installed packages at
 	             $INSTALLED_PACKAGES
 	-T | --test
@@ -231,8 +235,7 @@  do_save_conffiles() {
 	run_hooks "$CONFFILES" $sysupgrade_init_conffiles
 	ask_bool 0 "Edit config file list" && vi "$CONFFILES"
 
-	if [ "$SAVE_INSTALLED_PKGS" -eq 1 ]; then
-		echo "${INSTALLED_PACKAGES}" >> "$CONFFILES"
+	if [ "$SAVE_INSTALLED_PKGS" -eq 1 ] || [ "$SAVE_SERVICE_STATUS" -eq 1 ]; then
 		mkdir -p "$ETCBACKUP_DIR"
 		# Avoid touching filesystem on each backup
 		RAMFS="$(mktemp -d -t sysupgrade.XXXXXX)"
@@ -243,13 +246,28 @@  do_save_conffiles() {
 				ask_bool 0 "Abort" && exit
 			}
 
-		# Format: pkg-name<TAB>{rom,overlay,unkown}
-		# rom is used for pkgs in /rom, even if updated later
-		find /usr/lib/opkg/info -name "*.control" \( \
-			\( -exec test -f /rom/{} \; -exec echo {} rom \; \) -o \
-			\( -exec test -f /overlay/upper/{} \; -exec echo {} overlay \; \) -o \
-			\( -exec echo {} unknown \; \) \
-			\) | sed -e 's,.*/,,;s/\.control /\t/' > ${INSTALLED_PACKAGES}
+		if [ "$SAVE_INSTALLED_PKGS" -eq 1 ]; then
+			echo "${INSTALLED_PACKAGES}" >> "$CONFFILES"
+			# Format: pkg-name<TAB>{rom,overlay,unkown}
+			# rom is used for pkgs in /rom, even if updated later
+			find /usr/lib/opkg/info -name "*.control" \( \
+				\( -exec test -f /rom/{} \; -exec echo {} rom \; \) -o \
+				\( -exec test -f /overlay/upper/{} \; -exec echo {} overlay \; \) -o \
+				\( -exec echo {} unknown \; \) \
+					\) | sed -e 's,.*/,,;s/\.control /\t/' > ${INSTALLED_PACKAGES}
+		fi
+
+		if [ "$SAVE_SERVICE_STATUS" -eq 1 ]; then
+			echo "${SERVICE_STATUS}" >> "$CONFFILES"
+			# Format: /etc/init.d/servicename {enable,disable}
+			rm -f ${SERVICE_STATUS}
+			for service in /etc/init.d/* ; do \
+				${service} enabled && \
+					echo >> ${SERVICE_STATUS} "$service" "enable" || \
+					echo >> ${SERVICE_STATUS} "$service" "disable" \
+				; \
+			done
+		fi
 	fi
 
 	v "Saving config files..."