Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 350910 - sys-apps/openrc: symlinked init scripts must be in the same directory as their symlink
Summary: sys-apps/openrc: symlinked init scripts must be in the same directory as thei...
Status: CONFIRMED
Alias: None
Product: Gentoo Hosted Projects
Classification: Unclassified
Component: OpenRC (show other bugs)
Hardware: AMD64 Linux
: High normal with 2 votes (vote)
Assignee: OpenRC Team
URL:
Whiteboard:
Keywords:
: 365955 366617 411583 425656 470854 (view as bug list)
Depends on:
Blocks: 374183
  Show dependency tree
 
Reported: 2011-01-07 00:06 UTC by Manuel Danisch
Modified: 2013-05-21 17:50 UTC (History)
10 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
My dynamic rule generation script (firewall.init,1.46 KB, text/plain)
2011-01-10 12:04 UTC, Manuel Danisch
Details
Patch to fix dirname() call in runscript.c (runscript.patch,1.26 KB, patch)
2011-05-18 13:31 UTC, vm
Details | Diff
0001-do-not-treat-symbolic-links-specially-in-init.d.patch (0001-do-not-treat-symbolic-links-specially-in-init.d.patch,2.11 KB, text/plain)
2011-07-27 17:01 UTC, William Hubbs
Details
0001-Improve-processing-of-conf.d-files.patch (0001-Improve-processing-of-conf.d-files.patch,3.56 KB, text/plain)
2011-07-27 21:08 UTC, William Hubbs
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Manuel Danisch 2011-01-07 00:06:35 UTC
Hello,

I just installed baselayout-2.0.1-r1 and openrc-0.6.8. After merging all config files and rebooting, I get an error for my own firewall-init-script. All my scripts are managed in a SVN repo, which is located in /usr/local/svn-repo on all my systems.

Now I symlinked /usr/local/svn-repo/scripts/sbin/firewall.init to /etc/init.d/firewall. With baselayout-1, I had no problems using this script just like any other init-script. But trying to start it with baselayout-2 returns an error message:

/lib64/rc/sh/runscript.sh: line 171: .: /usr/local/svn-repo/scripts/sbin: is a directory.

The script also doesn't start. Deleting the symlink and simply copying the script to /etc/init.d/ makes it work without any problems. So the problem occurs only when the script is symlinked.

Reproducible: Always

Steps to Reproduce:
Comment 1 SpanKY gentoo-dev 2011-01-10 01:18:58 UTC
post an actual file that can be downloaded, and then post the actual commands you're using to link in things and then execute (and show the actual output)

moving a random init.d file out of /etc/init.d/ and symlinking it back seems to work fine for me.
Comment 2 Manuel Danisch 2011-01-10 11:58:21 UTC
OK, here wo go. First some more information on my directory structure:

my scripts are in /usr/local/svn-repo/scripts/sbin/, the filename is firewall.init. So the full path of the particular script is /usr/local/svn-repo/scripts/sbin/firewall.init. Additionally, /usr/local/sbin is a symlink to svn-repo/scripts/sbin, so I can run scripts in this directory also as root from command line.

cd /usr/local
ls -lh
[...] sbin -> svn-repo/scripts/sbin [...]

When I first installed this init-script, I made the following link:

cd /etc/init.d
ln -s /usr/local/sbin/firewall.init firewall

With baselayout-1, I could now use /etc/init.d/firewall just like any other init-script.

With baselayout-2, I did some more tests. This is what does work:

cd /etc/init.d/
rm firewall
cp -a /usr/local/sbin/firewall.init firewall
=> works
rm firewall
ln -s /usr/local/svn-repo/scripts/sbin/firewall.init .
=> works (as firewall.init)

This does NOT work:
cd /etc/init.d/
rm firewall
ln -s /usr/local/sbin/firewall.init firewall
=> does not work
rm firewall
ln -s /usr/local/sbin/firewall.init .
=> going over the /usr/local/sbin/ symlink does not work at all
rm firewall
ln -s /usr/local/svn-repo/scripts/sbin/firewall.init firewall
=> changing the filename does not work either

I'll attach a simplified version of firewall.init, so you could also test it.
Comment 3 Manuel Danisch 2011-01-10 12:04:25 UTC
Created attachment 259462 [details]
My dynamic rule generation script

This script generates three files in /tmp, and generates from these files iptables-rules. When the script is stopped, nothing gets in and out over the net. If the script is started, but the three files are empty, traffic can go out and replies can get in. If subnets and ports are added to the files, a /etc/init.d/firewall reload automatically generates rules to allow incoming traffic for this port for this subnet.
Comment 4 Manuel Danisch 2011-01-13 14:56:06 UTC
Small update: today I tested openrc-0.7.0 which gave me the same error messages and the same behaviour like openrc-0.6.8.
Comment 5 William Hubbs gentoo-dev 2011-01-13 20:07:11 UTC
I reproduced this as well.

The problem happens when the basename of the init script itself and the basename of the symlink linking to it are not the same.
Comment 6 Manuel Danisch 2011-01-13 20:16:21 UTC
(In reply to comment #5)
> The problem happens when the basename of the init script itself and the
> basename of the symlink linking to it are not the same.
> 

As you can see from my tests in comment #2, the problem also occurs when the path "goes over" a symlink.

ln -s /usr/local/svn-repo/scripts/sbin/firewall.init .
works, while
ln -s /usr/local/sbin/firewall.init .
does not work. As already mentioned, /usr/local/sbin is a symlink on my systems to /usr/local/svn-repo/scripts/sbin
Comment 7 William Hubbs gentoo-dev 2011-03-26 03:52:07 UTC
I just found the following text in the bugs section of the runscript man page:

" Because of the way we load our configuration files and the need to handle
more than one service directory, you can only use symlinks in service
directories to other services in the same directory.  You cannot symlink
to a service in a different directory even if it is another service
directory."

This appears to be a known issue. What does everyone else think?
Comment 8 SpanKY gentoo-dev 2011-03-26 06:05:48 UTC
if we're going to ban it, we should ban it.  i.e. have runscript detect that the symlink contains path components and abort immediately.
Comment 9 Roland Ramthun 2011-05-09 16:36:53 UTC
*** Bug 366617 has been marked as a duplicate of this bug. ***
Comment 10 Roland Ramthun 2011-05-09 16:47:04 UTC
After the recent baselayout2/openrc stabilization I ran into this problem, too.

If this behaviour is intended, it needs a better output than it currently has and which looks like a bug.

Either way at least for me this is a major regression over the old versions.
Managing/Versioning your custom scripts outside of /etc/init.d/ isn't an exotic requirement, I think.
Comment 11 Sergiy Borodych 2011-05-10 15:00:41 UTC
I have the same issue
and really want to someone fix this regression or suggest alternative way
Comment 12 Jeroen Roovers (RETIRED) gentoo-dev 2011-05-12 23:05:34 UTC
*** Bug 366819 has been marked as a duplicate of this bug. ***
Comment 13 Jeroen Roovers (RETIRED) gentoo-dev 2011-05-12 23:05:46 UTC
*** Bug 365955 has been marked as a duplicate of this bug. ***
Comment 14 Tom Dexter 2011-05-18 13:21:38 UTC
I just ran into this yesterday.  My company uses some custom init scripts where multiple different links in /etc/init.d symlink to the one script in an external directory (and perform different actions based on the SVCNAME).  To work around this I have to temporarily make actual copies of the script in /etc/init.d.  I could really use a solution to this one.
Comment 15 vm 2011-05-18 13:31:44 UTC
Created attachment 273833 [details, diff]
Patch to fix dirname() call in runscript.c

The dirname() call at runscript.c:1136 modifies lnk, so an
incorrect name is returned by the basename() call at runscript.c:1140. The patch saves lnk before the call.
Comment 16 Roy Marples 2011-05-18 19:41:36 UTC
(In reply to comment #7)
> I just found the following text in the bugs section of the runscript man page:
> 
> " Because of the way we load our configuration files and the need to handle
> more than one service directory, you can only use symlinks in service
> directories to other services in the same directory.  You cannot symlink
> to a service in a different directory even if it is another service
> directory."
> 
> This appears to be a known issue. What does everyone else think?

The issue is this

/etc/init.d
net.lo
net.eth0 -> net.lo

/etc/conf.d
net

/usr/local/etc/init.d
net.lo
net.eth1 -> net.lo

/usr/local/conf.d
net

A perfectly valid setup, which works 100%.
Now add net.eth2 in /etc/init.d which links to /usr/local/etc/init.d/net.lo
Which config file is it supposed to use?

The last I looked at this there may have been other complications, but that is the meaning behind that man page entry.
Comment 17 William Hubbs gentoo-dev 2011-05-18 20:23:22 UTC
(In reply to comment #16)
> The issue is this
> /etc/init.d
> net.lo
> net.eth0 -> net.lo
> /etc/conf.d
> net
> /usr/local/etc/init.d
> net.lo
> net.eth1 -> net.lo
> /usr/local/conf.d

You mean /usr/local/etc/conf.d here right?
Comment 18 vm 2011-05-18 21:21:21 UTC
Then perhaps 366819 and 365955 are not duplicates.
Comment 19 Roy Marples 2011-05-18 22:01:36 UTC
(In reply to comment #17)
> (In reply to comment #16)
> > The issue is this
> > /etc/init.d
> > net.lo
> > net.eth0 -> net.lo
> > /etc/conf.d
> > net
> > /usr/local/etc/init.d
> > net.lo
> > net.eth1 -> net.lo
> > /usr/local/conf.d
> 
> You mean /usr/local/etc/conf.d here right?

Right
Comment 20 Roy Marples 2011-05-18 22:09:40 UTC
(In reply to comment #18)
> Then perhaps 366819 and 365955 are not duplicates.

I think that they are, but different entry points to the same problem.
The easiest fix for those to is to remove ./ if it starts with ./

The bug report here though is more complex and sadly fits into my above scenario.
I didn't come up with a reasonable fix, but I don't recall it erroring like it does now either.

Now, you may ask *why* it's needed. And the reason is thus - to separate base system scripts from package scripts entirely which is how BSD portage equivalents work. package system borked? Want to change from pkgsrc to ports or portage? Just rm -rf /usr/pkg or /usr/local depending on setup and you're good to go.
Comment 21 vm 2011-05-19 00:57:17 UTC
I see your point about the bug in this report and you're right that the fix for the others is trivial, so I don't want to belabor the point. Still, the dirname(3) manage says:

    Both dirname() and basename() may modify the contents of path, so
    copies should be passed to these functions.

It would seem that these lines are a bug because, at the very least, they depend on undocumented behavior.

   1136                         dir = dirname(lnk);
   1137                         if (strcmp(dir, save) == 0)
   1138                                 file = basename_c(argv[1]);
   1139                         else
   1140                                 file = basename_c(lnk);
Comment 22 Christian Ruppert (idl0r) gentoo-dev 2011-06-04 14:56:18 UTC
*** Bug 365955 has been marked as a duplicate of this bug. ***
Comment 23 William Hubbs gentoo-dev 2011-07-27 15:17:16 UTC
*** Bug 365955 has been marked as a duplicate of this bug. ***
Comment 24 William Hubbs gentoo-dev 2011-07-27 17:01:09 UTC
Created attachment 281179 [details]
0001-do-not-treat-symbolic-links-specially-in-init.d.patch

All,

in my testing, this patch seems to fix the issue. It allows links in
init.d directories to point anywhere, but it requires that for an init.d
directory there is a conf.d directory at the same level in the tree to
hold configuration files that match the services in the init.d
directory.

I need comments and testing for this fix.

In particular, does it still allow BSDs to work properly?
Comment 25 William Hubbs gentoo-dev 2011-07-27 21:08:35 UTC
Created attachment 281201 [details]
0001-Improve-processing-of-conf.d-files.patch

All,

after discussion with robbat2, I came up with this patch. Now besides
checking in the relative ../conf.d directory for configuration files, we
also check @sysconfdir@/conf.d.

I have tested this patch and it works here, so if there are no
objections I will commit it to the tree.

Can anyone say if this patch is OK for BSDs as well?
Comment 26 William Hubbs gentoo-dev 2011-07-31 15:06:36 UTC
This patch, including an update to the man page, has been implemented
in commit 0c8bea2.
Comment 27 William Hubbs gentoo-dev 2011-12-11 01:05:08 UTC
All,

we need to re-visit this bug. The commit I mentioned that seemed to fix
the issue causes the regression in bug #392457.

Also, the RC_SERVICE environment variable is now set incorrectly, so I
don't know of what other possible regressions it might be causing.

I would like to revert this commit asap and work out another fix.
Comment 28 Jeroen Roovers (RETIRED) gentoo-dev 2012-04-11 15:06:02 UTC
*** Bug 411583 has been marked as a duplicate of this bug. ***
Comment 29 Steve L 2012-05-23 12:54:35 UTC
It seems to me that you could just use:

service = realpath(argv[1], NULL); // from #392457 comment 3
applet = basename_c(argv[1]);

..as the applet name is always present in the argument, even if run from within /etc/init.d, eg as ./net.eth0

Sorry if I'm missing something obvious.

WRT to the shell patch, wouldn't:
if [ -f "${RC_SERVICE%/*}/../conf.d" ]; then
   loadconfig "${RC_SERVICE%/*}/../conf.d"
else loadconfig "@SYSCONFDIR@/conf.d"
fi
..be more what the user is after?
Comment 30 Steve L 2012-05-23 18:34:16 UTC
> if [ -f "${RC_SERVICE%/*}/../conf.d" ]; then
Doh, that should be -d not -f ofc. (I just think it's a bit safer, but might not be what you want.)
Sorry for noise.
Comment 31 William Hubbs gentoo-dev 2012-07-16 16:12:47 UTC
*** Bug 425656 has been marked as a duplicate of this bug. ***
Comment 32 Justin Lecher (RETIRED) gentoo-dev 2013-05-21 17:50:35 UTC
*** Bug 470854 has been marked as a duplicate of this bug. ***