Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 08 Jun 1998 00:12:57 -0700
From:      Mike Smith <mike@smith.net.au>
To:        Willem Jan Withagen <wjw@surf.IAEhv.nl>
Cc:        mike@smith.net.au, current@FreeBSD.ORG
Subject:   Re: Variant Link implementation (Was: Re: lorder problem: ....... ) 
Message-ID:  <199806080712.AAA09745@antipodes.cdrom.com>
In-Reply-To: Your message of "Sun, 07 Jun 1998 14:30:10 %2B0200." <199806071230.OAA28150@surf.IAEhv.nl> 

next in thread | previous in thread | raw e-mail | index | archive | help
> >> If we really wanted to get variant symlinks, I would suggest copying
> >> the already-fairly-well-known syntax of AFS, `@name_of_parameter'.  As
> >> the metasyntactic variable suggests, these should be (a fairly small
> >> number of) parameters which hold system-wide.  (Indeed, given the
> >> existence of the sysctlbyname interface in the kernel, one could
> >> simply kick them off in that direction.)
> >
> >Ok.  I did actually look at how this could be implemented last time it 
> >came up, and I think it would be *reasonably* straightforward.
> 
> Can you come up with that scenario? I might be tempted to take a look at it
> and possibly try to implement it. But I need to make some time estimates
> if I ever will be able to finisch it.

Sure.  The first stage implementation would be to have a small, 
fixed-size table of values in the kernel (for testing purposes).

Then you want to attack this fragment in kern/vfs_lookup.c:namei()


                error = VOP_READLINK(ndp->ni_vp, &auio, cnp->cn_cred);
                if (error) {
                        if (ndp->ni_pathlen > 1)
                                zfree(namei_zone, cp);
                        break;
                }
                linklen = MAXPATHLEN - auio.uio_resid;
 *** insert here ***
                if (linklen + ndp->ni_pathlen >= MAXPATHLEN) {
                        if (ndp->ni_pathlen > 1)
                                zfree(namei_zone, cp);
                        error = ENAMETOOLONG;
                        break;
                }

At the 'insert here' point, you want to take the link target data (in
the buffer at *cp), parse it for possible expansion into a new buffer, 
and recalculate linklen.  Something like this (off the cuff):

	buf = zalloc(namei_zone);
	si = 0, ci = 0, di = 0;
	while (si < linklen) {
		/* component leader? */
		if ((cp[si] == '$') &&
		    (si < (linklen - 2)) &&
                           (cp[si + 1] == '{')) {
			ci = si + 2;
			while (ci < linklen) {
				if (cp[si] == '}') {
					cp[ci] = 0;
					switch (vlink_xlate(cp + si + 2,
						            buf, &di)) {
					case 0:	/* OK */
						si = ci + 1;
						di += k;
						continue;
					case 1:	/* no room to expand */
						return ENAMETOOLONG;
					default:/* not found */
						break;
					}
				}
			}
		}
		buf[di++] = cp[si++];
	}
	linklen = di;
	if (ndp->ni_pathlen > 1)
		zfree(cp);
	}
	cp = buf;

Note that the memory management here is actually bogus; you should 
*always* zalloc the buffer for the VOP_READLINK, and assign buf based 
on ndp->ni_pathlen as is currently done for cp.  Once you hand it over, 
the management for cp as it currently is is fine.  (remember to dispose 
of buf as well as cp in the error case).

The vlink_xlate function is where the lookup is done; you will probably 
want to pass p (current proc) to it as well at some stage.  

Start small; once this is working for you, the next step is the
'defaults' space, which should be sysctl-accessible.  Then you can 
start worrying about how to become more process-specific.

-- 
\\  Sometimes you're ahead,       \\  Mike Smith
\\  sometimes you're behind.      \\  mike@smith.net.au
\\  The race is long, and in the  \\  msmith@freebsd.org
\\  end it's only with yourself.  \\  msmith@cdrom.com



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199806080712.AAA09745>