From: NeilBrown <neilb@suse.de>
To: Steve Dickson <SteveD@redhat.com>
Cc: linux-nfs@vger.kernel.org
Subject: Re: [PATCH/RFC: nfs-utils] Common systemd unit files for nfs-utils.
Date: Fri, 31 Jan 2014 09:14:55 +1100 [thread overview]
Message-ID: <20140131091455.550e59a8@notabene.brown> (raw)
In-Reply-To: <52EAB0CA.2090204@RedHat.com>
[-- Attachment #1: Type: text/plain, Size: 17889 bytes --]
On Thu, 30 Jan 2014 15:06:34 -0500 Steve Dickson <SteveD@redhat.com> wrote:
>
>
> On 01/30/2014 01:24 AM, NeilBrown wrote:
> >
> > Hi all,
> >
> > I would really like to see a common set of systemd unit files used for
> > nfs-utils by every distribution (that actually uses systemd), and would like
> > those unit files to be in the upstream nfs-utils package.
> >
> > To that end I have put together the following collection of unit files which
> > seem right to me, and appear to work as I think I want them to work.
> >
> > I've looked at the unit files in Fedora and borrowed some ideas while
> > discarding and changing others. I won't try to list and justify all the
> > changes here, but I'm perfectly willing (possibly even eager) to justify
> > anything specific that anyone cares to ask about.
> >
> > So:
> > 1/ Do you agree that a collection of systemd unit files belongs in
> > nfs-utils?
> I would think so...
> > 2/ Do you think it reasonable to expect most (systemd using) distros to
> > use the one set? I will certainly try to ensure openSUSE does if
> > upstream accepts them.
> > 3/ Do you have any comments/question about those below?
> >
> >
> > Thanks,
> > NeilBrown
> >
> > diff --git a/systemd/README b/systemd/README
> > new file mode 100644
> > index 000000000000..f0fb68825499
> > --- /dev/null
> > +++ b/systemd/README
> > @@ -0,0 +1,50 @@
> > +
> > +Notes about systemd unit files for nfs-utils.
> > +
> > +The unit files provided here should be sufficient for systemd
> > +to manage all daemons and related services provides by nfs-utils.
> > +
> > +They do *not* include any unit files for separate services such as
> > +rpc.rquotad (in the 'quota' package) or rpcbind.
> > +
> > +There are 4 units that can be 'enabled' or 'disabled' by systemctl, or
> > +by a suitable 'preset' setting:
> > +
> > + nfs-server.target
> > + If enabled, nfs service is started together with dependencies
> > + such as mountd, statd, rpc.idmapd
> > +
> > + nfs-client.target
> > + If enabled, daemons needs for an nfs client are enabled.
> > + This does *not* include rpc.statd. the rpc-statd.service unit
> > + is started by /usr/sbin/start-statd which mount.nfs will run
> > + if statd is needed.
> > +
> > + nfs-secure.target
> > + If enabled, then rpc.gssd will be run when either -client or
> > + -server is started, and rpc.svcgssd will be run when -server
> > + is started
> > +
> > + nfs-blkmap.target
> > + If enabled, then blkmapd will be run when nfs-client.target is
> > + started.
> Do we really need all of these targets? Could we cut it down to
> two. nfs.target and nfs-secure.target?
>
Excellent question.
My thought was to err on the side of providing too many rather than too few.
If a distro wants to remove a particular choice it can use the "presets"
feature off systemd to make sure that target is always enabled.
But I think you might be questioning specific targets rather than the general
number of targets - I respond to that below.
> > +
> > +
> > +It is possible that we should have an nfs-statd.target which can
> > +selectively enable statd being stared by -server and sm-notify
> > +being started by -server or -client. That way it could be disabled
> > +completely on V4-only configurations. Currently statd is always
> > +started on the server and sm-notify is always run if server or
> > +client is enabled.
> > +
> > +Stopping nfs-server will also stop rpc.mountd, and rpc.svcgssd.
> > +It cannot stop rpc.statd or rpc.gssd as they may be in use by the
> > +client and systemd cannot specify is two-pronged reverse dependency.
> > +(i.e. stop this unit if none of these units are running)
> > +
> > +Distro specific commandline configuration can be provided by
> > +installing a script /usr/lib/systemd/scripts/nfs-utils_env.sh
> > +This should write /run/sysconfig/nfs-utils based on configuration
> > +information such as in /etc/sysconfig/nfs or /etc/defaults/nfs.
> > +It should write to a tmp file and rename to the target to
> > +avoid parallel units seeing incomplete copies of the file.
>
> > diff --git a/systemd/nfs-blkmap.service b/systemd/nfs-blkmap.service
> > new file mode 100644
> > index 000000000000..7319a88661cc
> > --- /dev/null
> > +++ b/systemd/nfs-blkmap.service
> > @@ -0,0 +1,11 @@
> > +[Unit]
> > +Description=pNFS block layout mapping daemon
> > +After=var-lib-nfs-rpc_pipefs.mount
> > +Requires=var-lib-nfs-rpc_pipefs.mount
> > +
> > +Requisite=nfs-blkmap.target
> > +After=nfs-blkmap.target
> > +
> > +[Service]
> > +Type=forking
> > +ExecStart=/usr/sbin/blkmapd
> Is this even supported anymore? Maybe we can just drop it???
No idea. I found it as I was looking around and assumed it should be started.
If it is no longer supported, how does NFS now find the block devices for
direct pnfs access?
>
>
> > diff --git a/systemd/nfs-blkmap.target b/systemd/nfs-blkmap.target
> > new file mode 100644
> > index 000000000000..fbcc111152ee
> > --- /dev/null
> > +++ b/systemd/nfs-blkmap.target
> > @@ -0,0 +1,8 @@
> > +[Unit]
> > +Description= PNFS blkmaping enablement.
> > +# If this target is enabled, then blkmapd will be started
> > +# as required. If it is not enabled it won't.
> > +
> > +[Install]
> > +WantedBy=remote-fs.target
> > +WantedBy=multi-user.target
> > \ No newline at end of file
>
> Again, why is a client target needed? Now that idmappings are
> stored in the key ring what needs to be started on the client?
rpc.gssd?
Also sm-notify needs to be run on a machine this is used as an NFS client.
This should happen even if no NFS filesystems are mounted at boot.
An 'nfs-client' target seems the natural place to put that requirement.
>
> > diff --git a/systemd/nfs-client.target b/systemd/nfs-client.target
> > new file mode 100644
> > index 000000000000..fa591354abf3
> > --- /dev/null
> > +++ b/systemd/nfs-client.target
> > @@ -0,0 +1,13 @@
> > +[Unit]
> > +Description=NFS client services
> > +Before=remote-fs-pre.target
> > +Wants=remote-fs-pre.target
> > +
> > +# Note: we don't "Wants=rpc-statd.service" as "mount.nfs" will arrange to
> > +# start that on demand if needed.
> > +Wants=rpc-gssd.service nfs-blkmap.service rpc-statd-notify.service
> > +Before=rpc-gssd.service nfs-blkmap.service
> > +
> > +[Install]
> > +WantedBy=multi-user.target
> > +WantedBy=remote-fs.target
>
>
> > diff --git a/systemd/nfs-idmapd.service b/systemd/nfs-idmapd.service
> > new file mode 100644
> > index 000000000000..6c2e1537f064
> > --- /dev/null
> > +++ b/systemd/nfs-idmapd.service
> > @@ -0,0 +1,9 @@
> > +[Unit]
> > +Description=NFSv4 ID-name mapping service
> Fedora has in the [Unit]:
> BindTo=nfs-server.service
> After=nfs-server.service
> I guess I thought they were needed at the time..
Yes, I saw that. So I looked into it.
Apart from being a typo ("BindsTo" with an 's' is correct),
BindsTo has an extra effect if the target unit - nfs-server.service in this
case - disappears unexpectedly. e.g. if the process dies.
However nfs-server.service doesn't have a process which can die. Rather it
starts some kernel threads. I'm pretty sure systemd won't be able to link
those threads with nfs-server.service.
So nfs-server.service can never "die", so "BindsTo" add nothing useful.
"After" just seems wrong. The moment nfsd is started a request could come in
which could require an idmap lookup, so nfs-idmapd should already be there.
>
> > +
> > +[Service]
> > +EnvironmentFile=-/run/sysconfig/nfs-utils
> > +ExecStartPre=-/usr/lib/systemd/scritps/nfs-utils_env.sh
> > +
> > +Type=forking
> > +ExecStart=/usr/sbin/rpc.idmapd $RPCIDMAPDARGS
>
>
> > diff --git a/systemd/nfs-mountd.service b/systemd/nfs-mountd.service
> > new file mode 100644
> > index 000000000000..92e05ca309ee
> > --- /dev/null
> > +++ b/systemd/nfs-mountd.service
> > @@ -0,0 +1,13 @@
> > +[Unit]
> > +Description=NFS Mount Daemon
> > +Requires=proc-fs-nfsd.mount
> > +After=proc-fs-nfsd.mount
> > +After=network.target
> > +PartOf=nfs-server.service
> > +
> > +[Service]
> > +EnvironmentFile=-/run/sysconfig/nfs-utils
> > +ExecStartPre=-/usr/lib/systemd/scritps/nfs-utils_env.sh
> How does this script know who is calling it and what it
> has to do?
Its task is to read some config file like /etc/sysconfig/nfs and determine
what the command line arguments for each nfs program should be and write out
FOO_ARGS=
lines to /run/sysconfig/nfs-utils for each FOO which is an nfs program.
I have since thought this would work better as a separate unit which creates
the nfs-utils env file once, and have all the other units have Wants/After
dependencies.
>
> > +
> > +Type=forking
> > +ExecStart=/usr/sbin/rpc.mountd $RPCMOUNTDARGS
>
>
> > diff --git a/systemd/nfs-secure.target b/systemd/nfs-secure.target
> > new file mode 100644
> > index 000000000000..0127fdb07dbd
> > --- /dev/null
> > +++ b/systemd/nfs-secure.target
> > @@ -0,0 +1,8 @@
> > +[Unit]
> > +Description=Secure NFS client/server services
> > +# If this target is enabled, then rpc.gssd and rpc.svcgssd will be started
> > +# as required. If it is not enabled they won't.
> So the "Requisite=nfs-secure.target" in rpc-gssd.service cause the
> daemon to started?
This is a bit subtle.
The "Requisite=nfs-secure.target" in rpc-gssd.service means that service is
only allowed to start if this unit (nfs-secure.target) is already started.
So if nfs-secure.target is enabled, then rpc-gssd.service will start when
anything Wants it. If nfs-secure.target is not enabled, then
rpc-gssd.service will not start, even if something Wants it.
So enabling nfs-secure.target doesn't start anything, just allows a couple of
things to start if they are Wanted.
>
> > +
> > +[Install]
> > +WantedBy=remote-fs.target
> > +WantedBy=multi-user.target
> > \ No newline at end of file
>
>
> > diff --git a/systemd/nfs-server.service b/systemd/nfs-server.service
> > new file mode 100644
> > index 000000000000..9812866c66aa
> > --- /dev/null
> > +++ b/systemd/nfs-server.service
> > @@ -0,0 +1,24 @@
> > +[Unit]
> > +Description=NFS server
> > +DefaultDependencies=no
> > +Requires= network.target proc-fs-nfsd.mount rpcbind.target
> > +PartOf=nfs-server.target
> > +
> > +After= network.target proc-fs-nfsd.mount rpcbind.target nfs-mountd.service
> > +After= nfs-idmapd.service rpc-statd.service
> > +After= rpc-gssd.service rpc-svcgssd.service
> > +Before= rpc-statd-notify.service
> > +
> > +[Service]
> > +EnvironmentFile=-/run/sysconfig/nfs-utils
> > +ExecStartPre=-/usr/lib/systemd/scritps/nfs-utils_env.sh
> > +
> > +Type=oneshot
> > +RemainAfterExit=yes
> > +ExecStartPre=/usr/sbin/exportfs -r
> > +ExecStart=/usr/sbin/rpc.nfsd $RPCNFSDARGS
> Having ExecStartPre and ExecStartPost scripts gives
> us a place to do some pre and post server configuration.
>
> Granted it has not been needed in a while but I'm thinking
> it could come in handing...
systemd supports so-called "dropins". If a distro wants to add an
ExecStartPre for some distro-specific reason they can put it in
/etc/systemd/system/nfs-server.service.d/04-Fedora-hacks.conf
and it will be understood by systemd to be part of this service.
Of course if they were not distro-specific reasons we would include them in
the upstream package :-)
I note that the Fedora nfs-server.service has a preconfig
echo "$NFSD_V4_GRACE" > /proc/fs/nfsd/nfsv4gracetime
and a postconfig
/sbin/modprobe svcrdma
echo "rdma $RDMA_PORT" > /proc/fs/nfsd/portlist
These seem reasonably general, though I'm wondering why the RDMA port is set
in postconfig rather than preconfig.
Do you know why that is?
>
> > +ExecStop=/usr/sbin/rpc.nfsd 0
> > +ExecStopPost=/usr/sbin/exportfs -au
> > +ExecStopPost=/usr/sbin/exportfs -f
> > +
> > +ExecReload=/usr/sbin/exportfs -r
>
>
> > diff --git a/systemd/nfs-server.target b/systemd/nfs-server.target
> > new file mode 100644
> > index 000000000000..a3e629f022a9
> > --- /dev/null
> > +++ b/systemd/nfs-server.target
> > @@ -0,0 +1,8 @@
> > +[Unit]
> > +Description=NFS server services
> > +Requires=nfs-server.service nfs-mountd.service
> > +Wants=rpc-statd.service nfs-idmapd.service rpc-gssd.service rpc-svcgssd.service
> > +Wants=rpc-statd-notify.service
> > +
> > +[Install]
> > +WantedBy=multi-user.target
>
>
> > diff --git a/systemd/proc-fs-nfsd.mount b/systemd/proc-fs-nfsd.mount
> > new file mode 100644
> > index 000000000000..f44d52f3d67b
> > --- /dev/null
> > +++ b/systemd/proc-fs-nfsd.mount
> > @@ -0,0 +1,8 @@
> > +[Unit]
> > +Description=NFSD configuration filesystem
> > +DefaultDependencies=no
> > +
> > +[Mount]
> > +What=nfsd
> > +Where=/proc/fs/nfsd
> > +Type=nfsd
>
>
> > diff --git a/systemd/rpc-gssd.service b/systemd/rpc-gssd.service
> > new file mode 100644
> > index 000000000000..f0fef007d480
> > --- /dev/null
> > +++ b/systemd/rpc-gssd.service
> > @@ -0,0 +1,14 @@
> > +[Unit]
> > +Description=RPC security service for NFS client and server
> > +Requires=var-lib-nfs-rpc_pipefs.mount
> > +After=var-lib-nfs-rpc_pipefs.mount
> > +
> > +Requisite=nfs-secure.target
> > +After=nfs-secure.target
> > +
> > +[Service]
> > +EnvironmentFile=-/run/sysconfig/nfs-utils
> > +ExecStartPre=-/usr/lib/systemd/scritps/nfs-utils_env.sh
> > +
> > +Type=forking
> > +ExecStart=/usr/sbin/rpc.gssd $GSSDARGS
>
>
> > diff --git a/systemd/rpc-statd-notify.service b/systemd/rpc-statd-notify.service
> > new file mode 100644
> > index 000000000000..9d972fc7753a
> > --- /dev/null
> > +++ b/systemd/rpc-statd-notify.service
> > @@ -0,0 +1,17 @@
> > +[Unit]
> > +Description=Notify NFS peers of a restart
> > +DefaultDependencies=no
> > +Requires=network-online.target
> > +After=network-online.target nss-lookup.target
> > +
> > +# if we run an nfs server, it needs to be running before we
> > +# tell clients that it has restarted.
> > +After=nfs-server.service
> > +
> > +[Service]
> > +EnvironmentFile=-/run/sysconfig/nfs-utils
> > +ExecStartPre=/usr/lib/systemd/scritps/nfs-utils_env.sh
> > +
> > +Type=oneshot
> > +RemainAfterExit=yes
> > +ExecStart=-/usr/sbin/sm-notify -d $SMNOTIFYARGS
>
>
> > diff --git a/systemd/rpc-statd.service b/systemd/rpc-statd.service
> > new file mode 100644
> > index 000000000000..04962e542fbc
> > --- /dev/null
> > +++ b/systemd/rpc-statd.service
> > @@ -0,0 +1,12 @@
> > +[Unit]
> > +Description=NFS status monitor for NFSv2/3 locking.
> > +DefaultDependencies=no
> > +Requires=nss-lookup.target rpcbind.target
> > +After=network.target nss-lookup.target rpcbind.target
> > +
> > +[Service]
> > +EnvironmentFile=-/run/sysconfig/nfs-utils
> > +ExecStartPre=-/usr/lib/systemd/scritps/nfs-utils_env.sh
> > +
> > +Type=forking
> > +ExecStart=/usr/sbin/rpc.statd --no-notify $STATDARGS
>
>
> > diff --git a/systemd/rpc-svcgssd.service b/systemd/rpc-svcgssd.service
> > new file mode 100644
> > index 000000000000..f024d40a8f41
> > --- /dev/null
> > +++ b/systemd/rpc-svcgssd.service
> > @@ -0,0 +1,15 @@
> > +[Unit]
> > +Description=RPC security service for NFS server
> > +Requires=var-lib-nfs-rpc_pipefs.mount
> > +After=var-lib-nfs-rpc_pipefs.mount
> > +PartOf=nfs-server.service
> > +
> > +Requisite=nfs-secure.target
> > +After=nfs-secure.target
> > +
> > +[Service]
> > +EnvironmentFile=-/run/sysconfig/nfs-utils
> > +ExecStartPre=-/usr/lib/systemd/scritps/nfs-utils_env.sh
> > +
> > +Type=forking
> > +ExecStart=/usr/sbin/rpc.svcgssd $SVCGSSDARGS
>
>
> > diff --git a/systemd/var-lib-nfs-rpc_pipefs.mount b/systemd/var-lib-nfs-rpc_pipefs.mount
> > new file mode 100644
> > index 000000000000..cd614cf49f00
> > --- /dev/null
> > +++ b/systemd/var-lib-nfs-rpc_pipefs.mount
> > @@ -0,0 +1,8 @@
> > +[Unit]
> > +Description=RPC Pipe File System
> > +DefaultDependencies=no
> > +
> > +[Mount]
> > +What=sunrpc
> > +Where=/var/lib/nfs/rpc_pipefs
> > +Type=rpc_pipefs
>
>
> > diff --git a/utils/statd/start-statd b/utils/statd/start-statd
> > index 1b345a547932..cde3583238e3 100644
> > --- a/utils/statd/start-statd
> > +++ b/utils/statd/start-statd
> > @@ -5,5 +5,8 @@
> > # It should run statd with whatever flags are apropriate for this
> > # site.
> > PATH=/sbin:/usr/sbin
> > -exec rpc.statd --no-notify
> > -
> > +if systemctl start statd.service
> > +then :
> > +else
> > + exec rpc.statd --no-notify
> > +fi
> >
>
> How does lockd get started and configured?
Lockd is automatically started by the kernel (nfs and nfsd) when needed.
I noticed that Fedora had some scripts to optionally set the port numbers
that lockd would use. I left that out because I hoped we could find a better
way.
If lockd is compiled in to the kernel, then I think fs.nfs.nlm_XXXport should
be set via /etc/sysctl.conf.
If it is a module, then the module parameters should be configured via
an /etc/modprobe.d/lockd.conf file.
I wish this was unified somehow (should modprobe call sysctl??) but it isn't.
I appreciate that in neither case is it easy to get values out of a
'sysconfig' file in to the right place.
I cannot really think of a better solution than an 'nfs-lock' service which
sets these values, so I'll probably add it.
>
> Overall it looks reasonable... But this is a change
> of ABI... so it will be painful... :-(
What exactly is changing that will be painful? I would certainly like to
arrange the unit files to minimise your pain as much as possible, as long as
it doesn't compromise effectiveness.
Thanks for your review!
NeilBrown
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
next prev parent reply other threads:[~2014-01-30 22:15 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-30 6:24 [PATCH/RFC: nfs-utils] Common systemd unit files for nfs-utils NeilBrown
2014-01-30 15:04 ` Weston Andros Adamson
2014-01-30 17:56 ` Weston Andros Adamson
2014-01-30 18:52 ` J. Bruce Fields
2014-01-30 22:50 ` NeilBrown
2014-01-30 23:17 ` Jim Rees
2014-01-30 20:06 ` Steve Dickson
2014-01-30 22:14 ` NeilBrown [this message]
2014-01-31 15:19 ` Steve Dickson
2014-01-31 16:15 ` Steve Dickson
2014-02-03 21:01 ` Steve Dickson
2014-02-03 22:34 ` NeilBrown
2014-02-04 16:20 ` J. Bruce Fields
2014-02-04 16:30 ` Chuck Lever
2014-02-04 19:00 ` Steve Dickson
2014-02-06 12:32 ` Simo Sorce
2014-02-05 3:09 ` NeilBrown
2014-02-05 15:56 ` Chuck Lever
2014-02-06 1:27 ` NeilBrown
2014-02-06 12:15 ` Simo Sorce
2014-02-06 16:09 ` Chuck Lever
2014-02-06 16:19 ` J. Bruce Fields
2014-02-10 20:50 ` Steve Dickson
2014-02-11 4:50 ` NeilBrown
2014-02-11 12:38 ` Steve Dickson
2014-02-11 16:37 ` J. Bruce Fields
2014-02-11 16:47 ` Steve Dickson
2014-02-11 16:56 ` J. Bruce Fields
2014-02-11 20:12 ` Steve Dickson
2014-02-04 18:26 ` Steve Dickson
2014-02-04 18:48 ` Anthony Messina
2014-02-04 18:54 ` J. Bruce Fields
2014-02-05 3:55 ` NeilBrown
2014-02-11 12:56 ` Steve Dickson
2014-02-05 5:43 ` NeilBrown
2014-02-05 21:11 ` J. Bruce Fields
2014-02-06 0:58 ` NeilBrown
2014-02-13 19:39 ` Steve Dickson
2014-02-04 12:42 ` Anthony Messina
2014-02-04 13:24 ` Jeff Layton
2014-02-04 14:18 ` Anthony Messina
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140131091455.550e59a8@notabene.brown \
--to=neilb@suse.de \
--cc=SteveD@redhat.com \
--cc=linux-nfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.