diff options
author | Scott Mayhew <smayhew@redhat.com> | 2017-04-10 07:10:45 -0400 |
---|---|---|
committer | Steve Dickson <steved@redhat.com> | 2017-04-10 07:10:45 -0400 |
commit | 3892174834ea1a4729348f0ecd3078cc1d5458e4 (patch) | |
tree | e531d9259d7b9af6535182fea7e4c7726e650a6c /systemd/systemd.c | |
parent | da866d7f6a787045e2c9f4a700e23b58ec71400a (diff) | |
download | nfs-utils-3892174834ea1a4729348f0ecd3078cc1d5458e4.tar.gz nfs-utils-3892174834ea1a4729348f0ecd3078cc1d5458e4.tar.xz nfs-utils-3892174834ea1a4729348f0ecd3078cc1d5458e4.zip |
systemd: add a generator for the rpc_pipefs mountpoint
The nfs.conf has config options for the rpc_pipefs mountpoint.
Currently, changing these from the default also requires manually
overriding the systemd unit files that are hard-coded to mount the
filesystem on /var/lib/nfs/rpc_pipefs.
This patch adds a generator that creates a mount unit file for the
rpc_pipefs when a non-default value is specified in /etc/nfs.conf, as
well as a target unit file to override the dependencies for the systemd
units using the rpc_pipefs. The blkmapd, idmapd, and gssd service unit
files have been modified to define their dependencies on the rpc_pipefs
mountpoint indirectly via the rpc_pipefs target unit file. Since both
rpc-pipefs-generator.c and nfs-server-generator.c need to convert path
names to unit file names, that functionality has been moved to
systemd.c.
This patch also removes the dependency on the rpc_pipefs from the
rpc-svcgssd.service unit file. rpc.svcgssd uses the sunrpc cache
mechanism to exchange data with the kernel, not the rpc_pipefs.
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
Diffstat (limited to 'systemd/systemd.c')
-rw-r--r-- | systemd/systemd.c | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/systemd/systemd.c b/systemd/systemd.c new file mode 100644 index 0000000..17820d4 --- /dev/null +++ b/systemd/systemd.c @@ -0,0 +1,133 @@ +/* + * Helper functions for systemd generators in nfs-utils. + * + * Currently just systemd_escape(). + */ + +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <string.h> + +static const char hex[16] = +{ + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', +}; + +/* + * determine length of the string that systemd_escape() needs to allocate + */ +static int systemd_len(char *path) +{ + char *p; + int len = 0; + + p = path; + while (*p == '/') + /* multiple leading "/" are ignored */ + p++; + + if (!*p) + /* root directory "/" becomes is encoded as a single "-" */ + return 1; + + if (*p == '.') + /* + * replace "." with "\x2d" escape sequence if + * it's the first character in escaped path + * */ + len += 4; + + while (*p) { + unsigned char c = *p++; + + if (c == '/') { + /* multiple non-trailing slashes become '-' */ + while (*p == '/') + p++; + if (*p) + len++; + } else if (isalnum(c) || c == ':' || c == '.' || c == '_') + /* these characters are not replaced */ + len++; + else + /* replace with "\x2d" escape sequence */ + len += 4; + } + + return len; +} + +/* + * convert c to "\x2d" escape sequence and append to string + * at position p, advancing p + */ +static char *hexify(unsigned char c, char *p) +{ + *p++ = '\\'; + *p++ = 'x'; + *p++ = hex[c >> 4]; + *p++ = hex[c & 0xf]; + return p; +} + +/* + * convert a path to a unit name according to the logic in systemd.unit(5): + * + * Basically, given a path, "/" is replaced by "-", and all other + * characters which are not ASCII alphanumerics are replaced by C-style + * "\x2d" escapes (except that "_" is never replaced and "." is only + * replaced when it would be the first character in the escaped path). + * The root directory "/" is encoded as single dash, while otherwise the + * initial and ending "/" are removed from all paths during + * transformation. + * + * NB: Although the systemd.unit(5) doesn't mention it, the ':' character + * is not escaped. + */ +char *systemd_escape(char *path, char *suffix) +{ + char *result; + char *p; + int len; + + len = systemd_len(path); + result = malloc(len + strlen(suffix) + 1); + p = result; + while (*path == '/') + /* multiple leading "/" are ignored */ + path++; + if (!*path) { + /* root directory "/" becomes is encoded as a single "-" */ + *p++ = '-'; + goto out; + } + if (*path == '.') + /* + * replace "." with "\x2d" escape sequence if + * it's the first character in escaped path + * */ + p = hexify(*path++, p); + + while (*path) { + unsigned char c = *path++; + + if (c == '/') { + /* multiple non-trailing slashes become '-' */ + while (*path == '/') + path++; + if (*path) + *p++ = '-'; + } else if (isalnum(c) || c == ':' || c == '.' || c == '_') + /* these characters are not replaced */ + *p++ = c; + else + /* replace with "\x2d" escape sequence */ + p = hexify(c, p); + } + +out: + sprintf(p, "%s", suffix); + return result; +} |