[rclone] Init.d script - why does this fail?

Thanks. Yes I knew about the start and stop and have set start to 97 since that is just before samba and stop to same as samba.

But unfortunately the script start just fails when started from reboot or from LuCi and nothing is output to a file when I direct output to file (although file gets created). The script stop from LuCi runs fine.

I don't know why the execution from LuCi or from router reboot is different from me manually executing script on command line using the init.d file or the rc file?

I assume it has to do with environment variable and rclone being in usr bin? Maybe something to do with overlay? It's not as if when script completes it kills background process?

I will try adding the echo to verify start is running. I'm pretty sure it is because the output file to which output is directed gets created but is just empty and the command doesn't seem to run.

sed -i -r -e "
s|\s+>\s+/dev/null\s+2>&1||
1a exec &> /tmp/mount-onedrive.log
1a set -x -v
1a env
" /etc/init.d/mount-onedrive
1 Like

OK thanks @vgaetera so this code:

#!/bin/sh /etc/rc.common
# Copyright (C) 2007 OpenWrt.org
exec &> /tmp/mount-onedrive.log
set -x -v
env

START=97
STOP=5

start() {
        rclone mkdir /tmp/OneDrive
        rclone mount "OneDrive:/Scanned Documents/" /tmp/OneDrive/ --vfs-cache-mode full --umask 000 --allow-other --daemon
}

stop() {
        fusermount -zu /tmp/OneDrive
}

results in the following output to the log file:

root@OpenWrt:~# cat /tmp/mount-onedrive.log
env
+ env
SHLVL=1
PWD=/

START=97
+ START=97
STOP=5
+ STOP=5

start() {
        rclone mkdir /tmp/OneDrive
        rclone mount "OneDrive:/Scanned Documents/" /tmp/OneDrive/ --vfs-cache-mode full --umask 000 --allow-other --daemon
}

stop() {
        fusermount -zu /tmp/OneDrive
}

[ -n "$USE_PROCD" ] && {
        extra_command "running" "Check if service is running"
        extra_command "status" "Service status"
        extra_command "trace" "Start with syscall trace"

        . $IPKG_INSTROOT/lib/functions/procd.sh
        basescript=$(readlink "$initscript")
        rc_procd() {
                local method="set"
                [ -n "$2" ] && method="add"
                procd_open_service "$(basename ${basescript:-$initscript})" "$initscript"
                "$@"
                procd_close_service "$method"
        }

        start() {
                rc_procd start_service "$@"
                if eval "type service_started" 2>/dev/null >/dev/null; then
                        service_started
                fi
        }

        trace() {
                TRACE_SYSCALLS=1
                start "$@"
        }

        stop() {
                procd_lock
                stop_service "$@"
                procd_kill "$(basename ${basescript:-$initscript})" "$1"
                if eval "type service_stopped" 2>/dev/null >/dev/null; then
                        service_stopped
                fi
        }

        reload() {
                if eval "type reload_service" 2>/dev/null >/dev/null; then
                        procd_lock
                        reload_service "$@"
                else
                        start
                fi
        }

        running() {
                service_running "$@"
        }

        status() {
                if eval "type status_service" 2>/dev/null >/dev/null; then
                        status_service "$@"
                else
                        _procd_status "$(basename ${basescript:-$initscript})" "$1"
                fi
        }
}
+ '[' -n  ]

ALL_COMMANDS="${ALL_COMMANDS} ${EXTRA_COMMANDS}"
+ ALL_COMMANDS='boot shutdown depends start stop restart reload enable disable enabled '
ALL_HELP="${ALL_HELP}${EXTRA_HELP}"
+ ALL_HELP='\tstart           Start the service\n\tstop            Stop the service\n\trestart         Restart the service\n\treload          Reload configuration files (or restart if service does not implement reload)\n\tenable          Enable service autostart\n\tdisable         Disable service autostart\n\tenabled         Check if service is started on boot\n'
list_contains ALL_COMMANDS "$action" || action=help
+ list_contains ALL_COMMANDS start
+ local 'var=ALL_COMMANDS'
+ local 'str=start'
+ local val
+ eval 'val=" ${ALL_COMMANDS} "'
+ val=' boot shutdown depends start stop restart reload enable disable enabled  '
+ '[' ' boot shutdown depends' '!=' ' boot shutdown depends start stop restart reload enable disable enabled  ' ]
$action "$@"
+ start
+ rclone mkdir /tmp/OneDrive
+ rclone mount 'OneDrive:/Scanned Documents/' /tmp/OneDrive/ --vfs-cache-mode full --umask 000 --allow-other --daemon

Does this reveal the problem and what the solution ought to be?

1 Like
1 Like

That is not the issue here as I have already tried running with config explicitly referenced. No change. My config is in /etc/rclone/rclone.conf.

I expect the UCI setting only affects the LuCI app:
https://github.com/ElonH/Rclone-OpenWrt/blob/master/luci-app-rclone/root/etc/config/rclone#L6-L6
So, what method are you using to provide the path to the config?

@vgaetera - when I set the config path I get same issue. It just seems to fail without any explanation. Here is the log output when I explicitly set the config path:

root@OpenWrt:/etc/init.d# cat /tmp/mount-onedrive.log
env
+ env
SHLVL=1
PWD=/

START=97
+ START=97
STOP=5
+ STOP=5

start() {
        rclone --config /etc/rclone/rclone.conf mkdir /tmp/OneDrive
        rclone --config /etc/rclone/rclone.conf mount "OneDrive:/Scanned Documents/" /tmp/OneDrive/ --vfs-cache-mode full --umask 000 --allow-other --daemon
}

stop() {
        fusermount -zu /tmp/OneDrive
}

[ -n "$USE_PROCD" ] && {
        extra_command "running" "Check if service is running"
        extra_command "status" "Service status"
        extra_command "trace" "Start with syscall trace"

        . $IPKG_INSTROOT/lib/functions/procd.sh
        basescript=$(readlink "$initscript")
        rc_procd() {
                local method="set"
                [ -n "$2" ] && method="add"
                procd_open_service "$(basename ${basescript:-$initscript})" "$initscript"
                "$@"
                procd_close_service "$method"
        }

        start() {
                rc_procd start_service "$@"
                if eval "type service_started" 2>/dev/null >/dev/null; then
                        service_started
                fi
        }

        trace() {
                TRACE_SYSCALLS=1
                start "$@"
        }

        stop() {
                procd_lock
                stop_service "$@"
                procd_kill "$(basename ${basescript:-$initscript})" "$1"
                if eval "type service_stopped" 2>/dev/null >/dev/null; then
                        service_stopped
                fi
        }

        reload() {
                if eval "type reload_service" 2>/dev/null >/dev/null; then
                        procd_lock
                        reload_service "$@"
                else
                        start
                fi
        }

        running() {
                service_running "$@"
        }

        status() {
                if eval "type status_service" 2>/dev/null >/dev/null; then
                        status_service "$@"
                else
                        _procd_status "$(basename ${basescript:-$initscript})" "$1"
                fi
        }
}
+ '[' -n  ]

ALL_COMMANDS="${ALL_COMMANDS} ${EXTRA_COMMANDS}"
+ ALL_COMMANDS='boot shutdown depends start stop restart reload enable disable enabled '
ALL_HELP="${ALL_HELP}${EXTRA_HELP}"
+ ALL_HELP='\tstart           Start the service\n\tstop            Stop the service\n\trestart         Restart the service\n\treload          Reload configuration files (or restart if service does not implement reload)\n\tenable          Enable service autostart\n\tdisable         Disable service autostart\n\tenabled         Check if service is started on boot\n'
list_contains ALL_COMMANDS "$action" || action=help
+ list_contains ALL_COMMANDS start
+ local 'var=ALL_COMMANDS'
+ local 'str=start'
+ local val
+ eval 'val=" ${ALL_COMMANDS} "'
+ val=' boot shutdown depends start stop restart reload enable disable enabled  '
+ '[' ' boot shutdown depends' '!=' ' boot shutdown depends start stop restart reload enable disable enabled  ' ]
$action "$@"
+ start
+ rclone --config /etc/rclone/rclone.conf mkdir /tmp/OneDrive
+ rclone --config /etc/rclone/rclone.conf mount 'OneDrive:/Scanned Documents/' /tmp/OneDrive/ --vfs-cache-mode full --umask 000 --allow-other --daemon

I don't understand why manually running the init.d script with '/etc/init.d/mount-onedrive start' works fine, but when executed from LuCi by clicking 'start' it fails like above.

Your post does not appear to be related to an officially released OpenWrt version, package or supported operation.

It is unlikely that you will receive useful input here.

Please seek advise from the relevant maintainer.

https://rclone.org/commands/rclone_mount/

That's not helpful or productive. I am dubious that this has anything to do with rclone itself. But I have created this issue now:

denial is a river in egypt

You can try to use the same environment:

env > /etc/rclone.env
sed -i -r -e "
1a . /etc/rclone.env
" /etc/init.d/mount-onedrive

Or it may require to export environment variables:

...
while read ENV_VAR
do export "${ENV_VAR}"
done < /etc/rclone.env
...

And/or run the commands in a sub-shell:

...
( rclone ... )
...
1 Like

Seems promising but gives the following error:

root@OpenWrt:/etc/init.d# ./mount-onedrive enabe
/etc/rc.common: /etc/rclone.env: line 2: 62270: not found
/etc/rc.common: /etc/rclone.env: line 7: u@h:: not found
/etc/rc.common: /etc/rclone.env: line 14: 62270: not found

Should it be 'import' or 'source' or something like that?

Is there an easier way?

I'm pretty sure you don't really need all environment variables.
Perhaps there's only a couple is actually necessary.

Yay! This works!

So how should I fix all this.

My script now looks like this:

root@OpenWrt:/etc/init.d# cat mount-onedrive
#!/bin/sh /etc/rc.common
# Copyright (C) 2007 OpenWrt.org

while read ENV_VAR
do export "${ENV_VAR}"
done < /etc/rclone.env

exec &> /tmp/mount-onedrive.log
set -x -v
env

START=97
STOP=5

start() {
        rclone --config /etc/rclone/rclone.conf mkdir /tmp/OneDrive
        rclone --config /etc/rclone/rclone.conf mount "OneDrive:/Scanned Documents/" /tmp/OneDrive/ --vfs-cache-mode full --umask 000 --allow-other --daemon
}

stop() {
        fusermount -zu /tmp/OneDrive
}
1 Like

Try excluding the variables one by one.
This way you can isolate the necessary ones.

root@OpenWrt:/etc/init.d# cat /etc/rclone.env
USER=root
SSH_CLIENT=192.168.1.168 62270 22
SHLVL=1
HOME=/root
OLDPWD=/root
SSH_TTY=/dev/pts/0
PS1=\[\e]0;\u@\h: \w\a\]\u@\h:\w\$
ENV=/etc/shinit
LOGNAME=root
TERM=xterm-256color
PATH=/usr/sbin:/usr/bin:/sbin:/bin
SHELL=/bin/ash
PWD=/etc/init.d
SSH_CONNECTION=192.168.1.168 62270 192.168.1.1 22
1 Like

The SSH* and PS* ones are most likely irrelevant, but the rest require testing.

So it turns out that it just needed:

export PATH=/usr/sbin:/usr/bin:/sbin:/bin

I think this may be because the rclone binary is located in /usr/bin/rclone? Although I do not understand why just launching it with full path /usr/bin/rclone would not work then? Or could there be another explanation why this export is needed?

So my script is now:

#!/bin/sh /etc/rc.common
# Copyright (C) 2007 OpenWrt.org

export PATH=/usr/sbin:/usr/bin:/sbin:/bin

exec &> /tmp/mount-onedrive.log

START=97
STOP=5

start() {
        rclone --config /etc/rclone/rclone.conf mkdir /tmp/OneDrive
        rclone --config /etc/rclone/rclone.conf mount "OneDrive:/Scanned Documents/" /tmp/OneDrive/ --vfs-cache-mode ful}

stop() {
        fusermount -zu /tmp/OneDrive
}

Does this look safe? I read that if init.d scripts fail it can be dangerous in certain circumstances:

:!: WARNING :!: OpenWrt initscripts will be run while building OpenWrt images (when installing packages in what will become a ROM image) in the host system (right now, for actions “enable ” and “disable ”). They must not fail, or have undesired side-effects in that situation. When being run by the build system, environment variable ${IPKG_INSTROOT} will be set to the working directory being used. On the “target system”, that environment variable will be empty/unset. Refer to “/lib/functions.sh” and also to “/etc/rc.common” in package “base-files” for the nasty details.

Can this fail in such a way?

2 Likes

In any case, thank you very much @vgaetera for your help here!

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.