Best way to run script only after factory reset

Uci-defaults goes all about running only after a first boot, but I need to run the script only after a factory reset, so after a sysupgrade with config preservation the script should not run (while a sysupgrade with "-n" should).

Currently I use a file in /buildroot/files/etc/config only with a value of, let me say "true", and then a uci-default script which first of all check the status, it only runs if it that value "true", and before ends it does a final step which is to change the value of that file (to "false").

Could I achieve this by a simpler or "standard" way?

Thank you.

1 Like

check step 20...

1 Like

Honestly I do not find how that information could be used to achieve what I want in a better/simpler way.

[ -f /sysupgrade.tgz ] && exit

I still don't get it, how the process before a sysupgrade could help me in any way since I need to detect in a first boot if previously a factory reset has been performed or not.

Also, this should be independ of perform or not a sysupgrade, since a factory reset could happen without it.

Please be clearer in the procedure and the expected behaviour, that probably is obvious to you but it is not to me. If it was obvious to me probably I wouldn't be asking here.

1 Like

Script snipplet does exacrly that. You get your answer examining relevant documentation.

Again, I can't find a way to better achieve what I'm doing by applying what you propose. I do not think that just checking the existence of /sysupgrade.tgz will be enough, since that file is erased automatically.

Uci-defaults are recommended to run with the least priority in order to let to wait the finish of all the initializations of first boot. This collides totally with depending of check "fast enough" the existence of a file in the firstboot.

So, I do not see any advantage on using /sysupgrade.tgz as an indicator than my way to do that, which guarantees the signaling between the factory reset event and the proper application of my custom configurations.

That is what I said, I do not find how this will lead to a safer, better or more standard way to achieve what I want. This seems like a different workaroud of mine but I still find mine neater and safer.

Or maybe I still don't get it...

1 Like

As someone very wise said: "when I want an answer on a forum, I log in with a fake account, comment on a terribly incorrect answer and there appear all those eager not to help, but to correct others."


Im happy you are proud of reinvention of a wheel, as saying goes doubling code size quadruples reliability while quartering mainntenance costs

1 Like

I must highlight that in my years in this forum this is the first time that someone treats me with lack of respect and only desire to argue but not in technical terms, but rather expressing unfounded grievances.

You can be proud of that too.

1 Like

Now I beg you to stop flooding the topic with insults towards me and leave room for anyone who wants to have a respectful technical discussion


Using a semaphore file or setting is rather normal, except that you take the harder road of putting the semaphore file/setting in the files/ directory in firmware compilation.

Inverting the logic might be easier: checking for absence of the semaphore, and only creating the semaphore setting at script completion.

(In addition to a uci setting in /etc/config, the semaphore can also be a file elsewhere if you declare that file to be included in backups)

If I understood Brada4 right, he tried to suggest that your script could check for the existence of the sysupgrade backup file. That file is removed after use, like you noted. But the removal is done by ""done" init script run at priority 95 (S95done symlink in rc.d), after the uci-defaults scripts have already been run by "boot" at 10. (That was mentioned in wiki item 20c, but the reference was obscure if you do not understand the initscript - rc.d symlink relation. Even I had to think about it for a while.) So it should still be present when uci-defaults scripts are run and the router has booted in a sysupgrade with settings. (If there has been a factory reset, power-off or a reboot command, the backup file is not there.)

so, in theory that should also work ok and might be simpler, as no other semaphore is needed.

But I also searched the sources (OpenWrt, packages, LuCI feeds) for the usage of sysupgrade.tgz detection, and did not find any package that uses that logic. Apparently a well hidden possibility.


It was very clear for me…..

1 Like

Yes, you are right in that if "boot" runs the scripts the deletion of the file will be later. I was confused believing that each uci default script had a different service priority, and that numerical prefix to order priority was global in scope (competing at the service level priority), where it was recommended to put a very high prefix (99). So that is why I suposed ir could run after rhe sysupgrade.tgz deletion.

However, sysupgrade.tgz does not have the expected functionality to identify whether there was a factory reset prior to firstboot or not. It is part of the configuration backup and restoration process. Given that clearly an inference is being made about a mechanism that is not guaranteed to be maintained for this purpose and can change without advice, I consider it is safer to use an explicit mechanism well controlled by oneself.

My question was aimed more to knowing if there is any standard mechanism to indicate that the firstboot started from a factory reset or not. If not, I don't think that making inferences over low level mechanisms is the most future proof idea.


Init script priorities are a different thing than uci-defaults running order. Uci-defaults are run in alphabetical order of the script names, but all uci-defaults are being run by "boot" init script rather early.

Yes, there is no indication if there was a "factory reset", but there should be enough logic for your actual needs. (assuming that your uci-defaults script sets exit code correctly to get deleted at successful completion.).

Logical paths:

  • In a first boot after a virgin flash to a new router, sysupgrade without settings, or after a factory reset, there is no sysupgrade.tgz. Your script notices that and gets run, and after successful completion the script gets deleted.
  • In a first boot after a sysupgrade with settings there is the sysupgrade.tgz, so your script does no modification actions, but still marks itself as completed and gets deleted.
  • In a boot after power-off or a reboot command, there is no uci-defaults script to be run, as it has been deleted at the first boot.

The crucial thing in that logic is to adhere to the "delete after successful run" practice of uci-scripts.

But like you say, using a separate semaphore is ok, and keeps your own logic separate from any changes and variations in the sysupgrade logic.

Ps. But I am curious to know if you really have need to exactly separate first boot variant factory reset from a virgin flash to a new router and sysupgrade without settings. If yes, then you really need a separate method.


OP asks to skip script IF it is sysupgrade with config preserved was run. Kind of simpler solutions dont work.

I would give you some insight if I understood what you want to do, we just think in different languages so it might be difficult to understand with a translator. Usually I try to ask questions in such detail that it would seem that the child should understand, but as practice has shown, this is far from the case ))
Plus, when someone reads and understands what is being said, they can give some advice. Programmers know how to do it when you give them an idea, but when there are no ideas, they cannot say how, since they live in another world, in another reality, but in general, if they like the idea, they always implement it

1 Like

Just to clarify, I a "virgin" flash or a factory reset is the same use case for me. My use case goes about detecting if the current firstboot starts with factory defaults configurations (a "factory" firstboot).

What really surprises me is that I did not find any other discussion regarding this, also that there seems not to be a standard feature to achieve that since I believe this use case should not be so infrequent.

So, by now, until find anything clearer to achieve this or an "official path", I will go with an uci-default script with something like:


if [ "$(cat /etc/config/factory_boot/factory_boot.txt)" = "true" ]; then

	uci -q batch <<-EOI
	set <config1>.<section1>[.<option1>]=<value1>
	set <configN>.<sectionN>[.<optionN>]=<valueN>

	uci commit

	echo false > /etc/config/factory_boot/factory_boot.txt
	echo "Factory custom config applied"

	echo "No factory boot, preserving user configs"

Or could be just deleting the file as checking its exitence, as proposed previously. Personally, for now I prefer to leave it explicit.

My question is what fw you are using?

openwrt official FW, "factory reset" will delete all your customer mods. Your such scripts will not work. All configs will go back openwrt official "defaults". Cannot insert customer scripts to hack the ofiicial Factory Reset.

If you use you builded FW, you could do anything, mod any configs in source code, or put a scripts in uci-defaults / rc.local.....

I am building my OpenWRT custom firmwares and, as I said in the first post, I use a file in /buildroot/files/etc/config which is included with "true" value from compilation.

In other hand, modifiying the defaults in source code directly leads to have commit diffs in an undesirable place, from my point of view.

1 Like