currently our $CRITICAL_SERVICES is parsed in a flat loop with no dependency checking at all ... perhaps one solution to the critical services versus boot services is to define a new half-runlevel, 'boot-critical' perhaps ?
Created attachment 46310 [details, diff] depscan.patch I will post the fix in several small incremental patches in hope it is easier to get accepted. If you prefer otherwise just tell me. This first patch changes depscan.sh so it can be used withought write access to disk. the patch is backward compatible, so everything keeps working fine. now I can source depscan.sh and pass --write=no, and it will not write anything to disk, but it will define RC_DEPEND_TREE. So: source depscan.sh -u --write=no is equivalent to depscan.sh -u source ${svcdir}/deptree except that nothing is written to disk and is a bit faster. The patch works by changing the awk scripts so they don't write anything to disk but to standard output. then depscan.sh is modified to create pipes between the awk scripts, and write deptree unless --write=no is given. (do you prefer --nowrite?) It also fixes a small bug: before, there was a ... for config in /etc/conf.d /etc/init.d /etc/rc.conf do if [ "${config}" -nt "${svcdir}/depcache" ] ... which does not work if something inside the directories change but not the directory itself. Now I use the function is_older_than which does the right thing. The idea is to use this to get the dependencies and use the array RC_DEPEND_TREE to sort the services in boot.
Created attachment 46314 [details, diff] rc-services.patch Adds a function that sorts the services according to dependencies. You can test this and the previous patch like this: source /sbin/depscan.sh -u --write=no export RC_GOT_DEPTREE_INFO="yes" source /lib/rcscripts/sh/rc-services.sh bootservices="$(sort_services bootmisc checkfs checkroot clock ...)" The idea is to use that function to calculate the list of services and the order to execute for the boot runlevel.
Created attachment 46343 [details, diff] rc.patch sort the critical services according to dependencies. Needs the other 2 patches. This should fix the bug.
It do not handle recursive dependencies, and duplicates code ...
I will recheck the recursive dependency thing, but it definately get the order wrong (local should be last, etc), and just removing the 'service names' from the array is wrong (check net for instance): ---- nosferatu ~ # cat /etc/init.d/test #!/sbin/runscript sort_services() { local -a unsorted=("$@") local -a sorted=() local service while (( ${#unsorted} > 0 )) do # get a service from the list and remove it service=${unsorted[0]}; unsorted=(${unsorted[@]#$service}) # services that should start before $service if is_runlevel_start then startupservices="$(ineed "${service}") \ $(valid_iuse "${service}") \ $(valid_iafter "${service}")" else startupservices="$(ineed "${service}") \ $(valid_iuse "${service}")" fi # remove each one of those from the sorted list # and add them all to the unsorted so we analyze them later for dependency in $startupservices do sorted=(${sorted[@]#$dependency}) unsorted=(${unsorted[@]#$dependency} $dependency) done sorted=($service ${sorted[@]}) done echo ${sorted[@]} } start() { sort_services acpid cupsd gpm hald local net.eth0 netmount numlock postfix samba sshd vixie-cron xfs } nosferatu ~ # /etc/init.d/test restart * Re-caching dependency info (mtimes differ)... * Could not get dependency info for ".eth0"! * Please run: * # /sbin/depscan.sh * to try and fix this. * Re-caching dependency info (mtimes differ)... * Could not get dependency info for ".eth0"! * Please run: * # /sbin/depscan.sh * to try and fix this. * Re-caching dependency info (mtimes differ)... * Could not get dependency info for "mount"! * Please run: * # /sbin/depscan.sh * to try and fix this. * Re-caching dependency info (mtimes differ)... * Could not get dependency info for "mount"! * Please run: * # /sbin/depscan.sh * to try and fix this. checkroot hostname modules checkfs localmount clock net sysklogd cupsd hotplug dbus xfs vixie-cron sshd samba postfix numlock mount .eth0 local hald gpm acpid
local is not last becase is_runlevel_start fails and after * is ignore. I made it this way because that is the way runscript.sh does it (I cut and pasted it). Other than that, recursive dependencies should work. I'll fix it so after x is allways respected, but x is not added to the list. or should I add it to the list if is_runlevel_start? you are right about net, I'll fix it.
I have not looked at this in a long time, so will have to recheck, but I think valid_* should do the right thing (meaning, valid_iafter should only return foo if foo is in the runlevel). Also forgot about it having to be a runlevel change ...
Here is a solution using tsort. tsort is part of coreutils and right now is in /usr/bin, if it can be copied in /bin, it would solve the problem. If not, then I'll look into solving it some other way. The good thing about tsort is that it is fast. sort_services() { local sorted="" local unsorted=$@ local -a newunsorted=() while [[ -n ${unsorted} ]] do newunsorted="" for service in $unsorted do # look for the service, if it does # not exist, just ignore it service_index=$(get_service_index $service 0) if (( $service_index == 0 )) then continue; fi if is_runlevel_start then startupservices=$(ineed "${service}" valid_iuse "${service}" valid_iafter "${service}" ) else startupservices=$(ineed "${service}" valid_iuse "${service}") fi for dependency in $startupservices do echo "$service $dependency" done [[ -z ${startupservices} ]] && echo $service $service newunsorted=(${newunsorted} $startupservices) done # see which ones are new sorted="$( echo "$sorted $unsorted" | fmt -w1)" unsorted="$( echo "$newunsorted" | \fmt -w1 | grep -x -v "$sorted" | sort | uniq )" done | tsort | tac }
oops. there is a typo, replace \fmt by fmt near the end.
*** Bug 78997 has been marked as a duplicate of this bug. ***
*** Bug 101958 has been marked as a duplicate of this bug. ***
*** Bug 108174 has been marked as a duplicate of this bug. ***
I've just comitted a large patch to trunk which fixes this and allows every init.d service to work in parallel as well. This is achieved by taking a copy of /lib/rscripts/init.d, then mounting it as tmpfs/ramfs (linux) or using mdconfig to create a ramdisk (fbsd). As it's a ramdisk, it's rw very early in the boot process, so we can run depscan and get full parallel support too. After the boot runlevel completes we tar it up, unmount the ramdisk and untar it back to disk. Will appear in baselayout-1.13
*** Bug 144902 has been marked as a duplicate of this bug. ***
Is there a workaround for simple change of order (makeing keymaps go earlier) ? maybe changing the name of the symlink to 0keymaps ? Thanks.
(In reply to comment #15) > Is there a workaround for simple change of order (makeing keymaps go earlier) ? > maybe changing the name of the symlink to 0keymaps ? > Thanks. You can play with RC_NEED="keymaps" or RC_USE="keymaps" in conf.d/service so that keymaps comes before service. Maybe we need RC_BEFORE and RC_AFTER too? Or you can just change the deps of the init script. But that's nothing to do with this bug as keymaps isn't a critical service.
> You can play with RC_NEED="keymaps" or RC_USE="keymaps" in conf.d/service > so that keymaps comes before service. I'll try. > Maybe we need RC_BEFORE and RC_AFTER too? > > Or you can just change the deps of the init script. Isn't this bug about dependencies of the init scripts not working ? > But that's nothing to do with this bug as keymaps isn't a critical service. Err... but my bug report, bug #144902, which was about changing dependencies in keymaps, localmount and checkfs not having any efect was reported as a duplicate of this one.
(In reply to comment #17) > Isn't this bug about dependencies of the init scripts not working ? No - this is about what we currently define as CRITICAL_SERVICES not being able to hand dependencies and their order is fixed. > Err... but my bug report, bug #144902, which was about changing dependencies in > keymaps, localmount and checkfs not having any efect was reported as a > duplicate of this one. I didn't read that bug. You currently cannot change the ordering of localmount or checkfs as they are critical services. You can change the ordering of keymaps provided it does not come before a critical service. Until we get a version of trunk in portage that is :)
So in boot there's a mix of critical and non critical services. As a note, it would be nice if you added a short comment at the top of the critical services stating that dependencies currently don't have any meaning there, it would have same me two hours of re-booting. On the other hand, so, there's no way to have keymaps earlier than localmount and checkfs today ? will there be a way in the future ?
*** Bug 102840 has been marked as a duplicate of this bug. ***
*** Bug 147676 has been marked as a duplicate of this bug. ***
baselayout-1.13.0_alpha1 is in portage