Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
runscript debugging
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Portage & Programming
View previous topic :: View next topic  
Author Message
creaker
l33t
l33t


Joined: 14 Jul 2012
Posts: 651

PostPosted: Sun Oct 12, 2014 8:30 am    Post subject: runscript debugging Reply with quote

How do I debug init.d scripts?
I'm getting an error during running my script, but can't figure it out what's the matter.
I even put sleep 5 command after every statement to see at which e-prompt it fails, but all the messages scrolls up in the blink of an eye.
Running the script after login is useless, all seems fine, but doesn't work at boot level.
Back to top
View user's profile Send private message
franzf
Advocate
Advocate


Joined: 29 Mar 2005
Posts: 4565

PostPosted: Sun Oct 12, 2014 9:07 am    Post subject: Reply with quote

Either enable rc_interactive or rc_logger help there. Both variables can be found in /etc/rc.conf. Config files should always be the first place to look at.
Back to top
View user's profile Send private message
creaker
l33t
l33t


Joined: 14 Jul 2012
Posts: 651

PostPosted: Sun Oct 12, 2014 10:41 am    Post subject: Reply with quote

Thanks! I've enabled rc_logger, but with enabled rc_logger init script works properly. Seems I have to have it enabled by default :roll:
Anyway I still cant figure it out, what causes a script fault and which statement is wrong when rc_logger disabled
Back to top
View user's profile Send private message
franzf
Advocate
Advocate


Joined: 29 Mar 2005
Posts: 4565

PostPosted: Sun Oct 12, 2014 1:58 pm    Post subject: Reply with quote

creaker wrote:
Thanks! I've enabled rc_logger, but with enabled rc_logger init script works properly. Seems I have to have it enabled by default :roll:
Anyway I still cant figure it out, what causes a script fault and which statement is wrong when rc_logger disabled

You do not have to enable it. I do not have it enabled and everything works fine.
You may want to try the other alternative, rc_interactive.
And nobody can tell you which statement makes your init script fail as long as you don't show the script to us.
Back to top
View user's profile Send private message
creaker
l33t
l33t


Joined: 14 Jul 2012
Posts: 651

PostPosted: Sun Oct 12, 2014 3:09 pm    Post subject: Reply with quote

I didn't try rc_interactive because I do not need to interact with rc
Quote:
# Set rc_interactive to "YES" and you'll be able to press the I key during
# boot so you can choose to start specific services.


Here the script that refuses to work if rc_logger is disabled. But it works if logging enabled. Script added to boot runlevel
Code:
#!/sbin/runscript
# Copyright 1999-2009 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $

source /etc/portage/make.conf

depend() {
        need localmount
}

start() {
        ebegin "Mounting read-only usr squashfs image"
        mount -rt squashfs -o loop,ro /squashed/usr/usr.sqfs /usr
        mount none -t tmpfs -o size=1200M /mnt/ramdisk
        einfo "Moving /usr/lib to RAM"
        #rsync -a --progress /usr/lib64 /mnt/ramdisk/
        cp -a /usr/lib64/* /mnt/ramdisk
       
        ebegin "Mounting read-write usr image with unionfs (aufs)"
        mkdir -p /dev/shm/.usr-rw

        mount -t aufs -o udba=reval,br=/dev/shm/.usr-rw=rw:/usr=ro usrAufs /usr
       
   ebegin "Mounting read-only lib64 squashfs image"
   mount -rt squashfs -o loop,ro /squashed/lib64/lib64.sqfs /lib64

   ebegin "Mounting read-write lib64 image with unionfs (aufs)"
        mkdir -p /dev/shm/.lib64-rw
        mount -t aufs -o udba=reval,br=/dev/shm/.lib64-rw=rw:/lib64=ro lib64Aufs /lib64

   ebegin "Mounting read-only lib32 squashfs image"
   mount -rt squashfs -o loop,ro /squashed/lib32/lib32.sqfs /lib32
   ebegin "Mounting read-write lib32 image with unionfs (aufs)"
        mkdir -p /dev/shm/.lib32-rw
        mount -t aufs -o udba=reval,br=/dev/shm/.lib32-rw=rw:/lib32=ro lib32Aufs /lib32

   ebegin "Mounting read-only home squashfs image"
   mount -rt squashfs -o loop,ro /squashed/home/home.sqfs /home
   ebegin "Mounting read-write home image with unionfs (aufs)"
        mkdir -p /dev/shm/.home-rw
        mount -t aufs -o udba=reval,br=/dev/shm/.home-rw=rw:/home=ro homeAufs /home
       
        einfo "Binding ramdisk to /usr/lib64"
        mount -o bind /mnt/ramdisk/ /usr/lib64/
       
        eend $?
}

I think logging may cause some pause/delay (for writing data to log file) and it somehow changes things. Or may be logging causes cashing, not sure.
Anyway, this statements (when doing it manually after login) works properly regardless rc_logger.
Back to top
View user's profile Send private message
Hu
Moderator
Moderator


Joined: 06 Mar 2007
Posts: 21624

PostPosted: Sun Oct 12, 2014 3:48 pm    Post subject: Reply with quote

Perhaps you should tell us why you think the script does not work. Does it produce some error message? Does it leave the system in an inconsistent state?

What is the point of making /usr/lib64 writable as a RAM disk, but using a unionfs for other directories? Does this system have any writable persistent storage? If so, is that storage written incrementally or only on shutdown? If it is written incrementally, a crash would revert you to the previous version of /usr/lib64, but preserve any directories that were written incrementally, which could cause serious problems.
Back to top
View user's profile Send private message
steveL
Watchman
Watchman


Joined: 13 Sep 2006
Posts: 5153
Location: The Peanut Gallery

PostPosted: Sun Oct 12, 2014 3:52 pm    Post subject: Re: runscript debugging Reply with quote

creaker wrote:
How do I debug init.d scripts?

set -x paired with: set +x around the bit you want to debug is always useful.

You're playing with fs which is always fun.. ;) These functions should come in handy to chase down the dependency interaction. As you'll see from the linked udev-no-initramfs thread, the interaction post-localmount is quite tricky. Really it should be in its own FS runlevel, imo, as several initscripts have long dep strings to try and start relatively early after localmount (which is where the complexity starts, as they often have to account for each other, somewhere in the chain, as well as whatever they're actually there for, and those parts normally have some sort of ordering too.)

Another tip is to save the exact info you need out to a file; I had to do this to debug a problem with lvm (which was later fixed in openrc.) If you can't see the set -x output in the log, for example, you'd redirect stderr before the set -x. This is easiest when done by the call to a function, since it will revert back on return, or some other compound like an 'if'.

HTH,
steveL.

edit: Please answer Hu's points, before you go diving into the dep-chain, as that can take up hours.. ;)
Back to top
View user's profile Send private message
creaker
l33t
l33t


Joined: 14 Jul 2012
Posts: 651

PostPosted: Sun Oct 12, 2014 5:24 pm    Post subject: Reply with quote

Hu wrote:
Perhaps you should tell us why you think the script does not work. Does it produce some error message? Does it leave the system in an inconsistent state?

This script should mount (in addition to regular filesystems) this stuffs: {usr, lib32, lib64, home}.sqfs as loop devices. The goal of using squashfs is getting filesystem size as small as possible (to fit usb pen drive size). Once squashed filesystems attached at loop0 - loop3, I have to mount them to /usr, /lib32, /lib64 and /home respectively. Why I decided that script doesn't work?
Because
a) /usr, /lib32, /lib32, /home mount points are missed in df -h output.
b) X doesn't start (as well as any command located under /usr)
c) Only very basic commands (from /bin /sbin) are available. Using them I can log in and run script manually "/etc/init.d/script start".
d) Once I ran script by hand, I getting all the filesystems mounted (df confirms it). I can start X and system runs fine.
e) When starting script manually I don't get any errors. It means nothing was made when script was lanched by rc at boot runlevel. Otherwise I would get an errors ("already mounted" "directory exists" etc).

When script launched at boot runlevel it produces few error messages, but I can't read them because they scrolls out of screen too fast.
This topic aimed to get idea on how can I catch these error messages.
However, if rc_logger enabled, script works just fine. No need to launch it by hand after login. rc.log is fine as well, no any error messages.

Hu wrote:

What is the point of making /usr/lib64 writable as a RAM disk, but using a unionfs for other directories? Does this system have any writable persistent storage? If so, is that storage written incrementally or only on shutdown? If it is written incrementally, a crash would revert you to the previous version of /usr/lib64, but preserve any directories that were written incrementally, which could cause serious problems.

Regarding writable RAM disk - OK, it's an mistake, have to add "ro"
Filesystems changes can be saved (added to squashed images) but only on shutdown (not incrementally) right before unmounting, if "savechanges" option was added to kernel command line. Script has stop() routine that checks for changes and updates squashed filesystem if neccessary:

Code:
stop() {
   einfo "Checking for savechanges"
   LINE=$(cat /proc/cmdline)
   if [[ $LINE == *savechanges* ]]
       then
           ebegin "Updating home image"
           if [ ! -z `ls -A /dev/shm/.home-rw | grep -v '.wh..wh.' | head -n1` ]
               then
                        einfo "  Sync the home directory"
                        mv -f /squashed/home/home-current.sqfs /squashed/home/home-old.sqfs
                        mksquashfs /home/ /squashed/home/home-current.sqfs -no-duplicates 2>/dev/null
                        ln -sf /squashed/home/home-current.sqfs /squashed/home/home.sqfs
               else
                        einfo "  Nothing to save"
               fi
            fi
        ebegin "Unmounting home"
        umount -t aufs  /home
        umount -t squashfs /home
        rm -rf /dev/shm/.home-rw
}


the same snippets of code for other filesystems (/usr, /lib32, /lib64)
This part of code (stop routine) works fine.

steveL, thanks for the tip. Have to read & learn. Seems you have a tips for any possible issue :)
Back to top
View user's profile Send private message
steveL
Watchman
Watchman


Joined: 13 Sep 2006
Posts: 5153
Location: The Peanut Gallery

PostPosted: Sun Oct 12, 2014 8:33 pm    Post subject: Reply with quote

Code:
stop() {
   einfo "Checking for savechanges"
   LINE=$(cat /proc/cmdline)
   if [[ $LINE == *savechanges* ]]
       then
           ebegin "Updating home image"
           if [ ! -z `ls -A /dev/shm/.home-rw | grep -v '.wh..wh.' | head -n1` ]
               then
                        einfo "  Sync the home directory"
                        mv -f /squashed/home/home-current.sqfs /squashed/home/home-old.sqfs
                        mksquashfs /home/ /squashed/home/home-current.sqfs -no-duplicates 2>/dev/null
                        ln -sf /squashed/home/home-current.sqfs /squashed/home/home.sqfs
               else
                        einfo "  Nothing to save"
               fi
            fi
        ebegin "Unmounting home"
        umount -t aufs  /home
        umount -t squashfs /home
        rm -rf /dev/shm/.home-rw
}

creaker wrote:
the same snippets of code for other filesystems (/usr, /lib32, /lib64)
This part of code (stop routine) works fine.

Missing 'fi' but I'm sure you noticed ;)

The capture of ls is undoubtedly a bad idea; wtf are you trying to test there? (additionally, stick to $(..) for command substitution, don't use backticks.)

You should /autojoin #bash on IRC: chat.freenode.net and lurk there; you'll see lots of script flying by and being corrected, and urls which you should look up to understand. In this instance: /msg greybot ls

They'll teach you sh as well, if you tell them upfront that's what you're there to learn; and you can always come to #friendly-coders for more help. ;)

You can get rid of the if altogether (in bash):
Code:
[[ $(cat /proc/cmdline) = *savechanges* ]] || return 0

and in fact the cat as well with a bashism:
Code:
[[ $(</proc/cmdline) = *savechanges* ]] || return 0


However all that leads us to is, that this should be POSIX sh.
Get out of the habit of using == as it's not portable, and a waste of time. In fact when you both code and script, you start to appreciate the different operator. In my head, == is numeric.
The presence of a [ or [[ indicates a string conditional, and there is simply no way to confuse: [ foo = "$bar" ] with: foo=$bar
(or the lexer/parser combi would have a much harder time, and sh would never have been implemented.)

Even if you quote the assignment which is not needed there, as assignment is never field-split, just like the word after case:
Code:

stop() {
   einfo 'Checking for savechanges'
   case $(cat /proc/cmdline) in
   *savechanges*) :
;;   *) return 0
   esac
..

Though you appear to have used that in your LINE=$(..); another point is don't use CAPS for anything except env vars, and occasional constants like EOL or TAB. Your line var should also have been local, which is specified for any sh that wants to be a candidate for debian, so most of them have it. Certainly all the ones on Gentoo do, sometimes under an alias for typeset (ksh derivatives.)

From what you wrote above about various file-systems, you probably want to make this into a function.
Quote:
steveL, thanks for the tip. Have to read & learn. Seems you have a tips for any possible issue :)

Hehe; just happened to have done a very similar thing, which isn't that surprising given our common interest in a lean machine.

You're always welcome. :-)

Regards,
igli

edit: use 'cat' in the sh 'case'.
Back to top
View user's profile Send private message
creaker
l33t
l33t


Joined: 14 Jul 2012
Posts: 651

PostPosted: Wed Oct 15, 2014 10:22 am    Post subject: Reply with quote

I'm back with some new info.
Code:
USB Flash Drive            Read rate    Write rate    Boot time
Kingston DT101 G2          18.3 Mb/s      2.6 Mb/s    75 sec
Silicon Power Ultima U02   16.2 Mb/s      5.1 Mb/s    53 sec
Smartby Micro SD           17.2 Mb/s     10.6 Mb/s    45 sec

Initially I had a system installed at Kingston DT101. Yesterday I bought Silicon Power stick and Smartby microSD card. And simply cloned Kingston to them with dd. No any modifications, just ran dd over new drives.
Both SP and Smartby boots just fine, without any issues. Regardless rc_logger option state. Noteworthy, that these two boots faster than Kingston (with rc_logger), though Kingston has a better read rate.
I think boot process somehow depends on write speed. And definetly it isn't a script itself issue.
I think (in case of Kingston) that other init scripts not yet finished their job (possibly due to low write rate) and my script fails due to something not ready yet.
It's my assumption.

@steveL
Thanks for your tips with ridding cat of. However you still trying to drag me into programming swamp. However I'm too old to start study bash, posix standards etc. Once I abandoned assembler I do not studied any other languages from very beginning. When I need to write some script I just googling for my tasks and using a code snippets that most suitable for me. Yes, they not optimal, especially when I made some corrections on them. Nevertheless, I really appreciate your help.
Back to top
View user's profile Send private message
steveL
Watchman
Watchman


Joined: 13 Sep 2006
Posts: 5153
Location: The Peanut Gallery

PostPosted: Wed Oct 15, 2014 1:34 pm    Post subject: Reply with quote

creaker wrote:
However I'm too old to start study bash, posix standards etc. Once I abandoned assembler I do not studied any other languages from very beginning. When I need to write some script I just googling for my tasks and using a code snippets that most suitable for me. Yes, they not optimal, especially when I made some corrections on them. Nevertheless, I really appreciate your help.

Heh that's fine; I'll correct them as I see them then. Just don't expect me not to ;) as it's the same as being in #bash for me. Maybe it'll help you by osmosis, and if not, then at least the bash or sh corrections/efficiency improvements will be documented, as well as in your scripts.

This is in my own self-interest, afaic. It's better for me if more Gentoo users are writing decent shell, than not. For a start it increases the base of things I have to draw on, as well as the pool of people capable of writing more. The corrections become less over time, especially in relation to a particular script, which eases any integration I might later have to do (since I'm the one in my team who gets to do the bash, and the shell-scripting. ;)

But really, it's harder for me not to correct it, due to the ingrained twitch from #bash (and greycat.;)

wrt ordering issues, it's hard to comment without seeing output from:
Code:
rc-update -v show
Usually without -v is enough, and what I normally check. But for someone else's machine, you'd want to see what they're not starting, just in case it matters.
Back to top
View user's profile Send private message
creaker
l33t
l33t


Joined: 14 Jul 2012
Posts: 651

PostPosted: Wed Oct 15, 2014 2:21 pm    Post subject: Reply with quote

Code:
UsbGen cr # rc-update -v show
             bootmisc | boot                         
         busybox-ntpd |                             
     busybox-watchdog |                             
          consolefont |      default                 
         cups-browsed |                             
                cupsd |                             
                 dbus |                             
                devfs |                       sysinit
        device-mapper |                             
              dmcrypt |                             
                dmesg |                       sysinit
             dmeventd |                             
                 fsck | boot                         
                 fuse |                             
           git-daemon |                             
                  gpm |                             
               hdparm |                             
             hostname | boot                         
              hwclock | boot                         
              keymaps | boot                         
            killprocs |              shutdown       
    kmod-static-nodes |                       sysinit
                local |      default                 
           localmount | boot                         
             loopback | boot                         
                  lvm |                             
       lvm-monitoring |                             
              lvmetad |                             
              metalog |                             
              modules | boot                         
             mount-ro |              shutdown       
                 mtab | boot                         
                mysql |                             
             net.eth0 |      default                 
               net.lo |                             
             netmount |      default                 
           nullmailer |                             
              numlock |                             
              pciparm |                             
               procfs | boot                         
              pwcheck |                             
            pydoc-2.7 |                             
            pydoc-3.3 |                             
                 root | boot                         
               rsyncd |                             
            saslauthd |                             
            savecache |              shutdown       
               smartd |                             
           squash-all | boot                         
       squash-all.bak |                             
                 sshd |                             
                 swap | boot                         
            swapfiles | boot                         
              swclock |                             
               sysctl | boot                         
                sysfs |                       sysinit
         termencoding | boot                         
         tmpfiles.dev |                       sysinit
       tmpfiles.setup | boot                         
                 udev |                       sysinit
           udev-mount |                       sysinit
       udev-postmount |      default                 
              urandom | boot                         
                  xdm |      default                 
            xdm-setup |

I have no idea on about what service my script (squash-all) might stumble.
Back to top
View user's profile Send private message
steveL
Watchman
Watchman


Joined: 13 Sep 2006
Posts: 5153
Location: The Peanut Gallery

PostPosted: Thu Oct 16, 2014 3:34 am    Post subject: Reply with quote

creaker wrote:
I have no idea on about what service my script (squash-all) might stumble.

Well it would help if you had looked at the udev-without-initramfs page I mentioned earlier.

Basically you need to copy the before line from the patched udev initscript. I think I'd add after udev as well.

As you're starting in exactly the same position as udev does in our setup, with similar fs-based constraint, you can just steal the line without doing all the hard work. (It took me quite a while to puzzle out that set, using the functions I showed earlier.)
Back to top
View user's profile Send private message
creaker
l33t
l33t


Joined: 14 Jul 2012
Posts: 651

PostPosted: Thu Oct 16, 2014 5:27 am    Post subject: Reply with quote

For some unknown reason the system became bootable again (at the old Kingston stick). It's weird.
I decided not to put "after udev" string there. If udev is a real problem causer, and problem will go due to this string, I'll do not know it for sure. Instead I added "rc-status" command at the very beginning to see what a services still running when script starts. If a system will stuck at my script again I can compare running services lists for bootable and unbootable states.
So have to wait until it stops boot again.
Back to top
View user's profile Send private message
steveL
Watchman
Watchman


Joined: 13 Sep 2006
Posts: 5153
Location: The Peanut Gallery

PostPosted: Thu Oct 16, 2014 4:44 pm    Post subject: Reply with quote

It's the before line that matters.

After udev isn't relevant for you since it's in a different run-level; it would be if your script were used by others.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Portage & Programming All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum