From 75077dde0e4b0b7a24555164806e8ffa4952ed86 Mon Sep 17 00:00:00 2001 From: Sonic Build Admin Date: Wed, 15 Apr 2026 01:08:50 +0000 Subject: [PATCH] Use `shutil.move` instead of `os.rename` to move `config_db.json` on place **What I did** I replaced `os.rename` call with `shutil.move`. Also, I reordered imports to be in alphabetical order (cosmetic change). **Why I did it** After https://github.com/sonic-net/sonic-buildimage/pull/20640, SONiC systems mount `/tmp` as separate _tmpfs_ mount. SONiC ZTP scripts currently prepares `config_dl.json` file in `/tmp` folder and then tries to **rename** file to `/etc/sonic/config_db.json`. Earlier there was no issue with that, as `/tmp` and `/etc/sonic` was residing on the same mount, on the same device. Now (`sonic-buildimage` master, and `202505` branch - https://github.com/sonic-net/sonic-buildimage/commit/fbd925295bf2f226aea72d1350fabe892859ab2f), `os.rename` raises a `OSError: [Errno 18] Invalid cross-device link: '/tmp/config_dl.json' -> '/etc/sonic/config_db.json'` exception. Such behaviour of `os.rename` is [documented](https://docs.python.org/3/library/os.html#os.rename): > The operation may fail on some Unix flavors if _src_ and _dst_ are on different filesystems. I replaced `os.rename` call with `shutil.move` ([docs](https://docs.python.org/3/library/shutil.html#shutil.move)) one, which should either use `os.rename` if such operation is possible, or fall back into "manual" course of actions: first copy the file onto new place, then remove the source file. I suspect this change will also solve https://github.com/sonic-net/sonic-ztp/issues/54, but I'm not entirely sure that the cause was the similar one there. Signed-off-by: Sonic Build Admin --- src/usr/lib/ztp/plugins/configdb-json | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/usr/lib/ztp/plugins/configdb-json b/src/usr/lib/ztp/plugins/configdb-json index a527fbb..f01ecde 100755 --- a/src/usr/lib/ztp/plugins/configdb-json +++ b/src/usr/lib/ztp/plugins/configdb-json @@ -16,20 +16,21 @@ See the License for the specific language governing permissions and limitations under the License. ''' -import sys -import os import fcntl +import json +import os import select -import time +import shutil import stat +import sys +import time import traceback -import json from swsscommon.swsscommon import ConfigDBConnector +from ztp.Logger import logger +from ztp.ZTPLib import runCommand, getField, isString, updateActivity from ztp.ZTPObjects import URL, DynamicURL from ztp.ZTPSections import ConfigSection -from ztp.ZTPLib import runCommand, getField, isString, updateActivity -from ztp.Logger import logger class ConfigDBJson: @@ -226,7 +227,7 @@ class ConfigDBJson: # Move staged config file to requested destination file if final_dest_file is not None: - os.rename(dest_file, final_dest_file) + shutil.move(dest_file, final_dest_file) else: os.remove(dest_file)