X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fmount%2Fnfs4mount.c;h=af70551f595e696a01a2a9bfbe98a53a1f87736d;hp=717ad56756cad43f8445b73d4064ad65d2929afb;hb=5f7cc524008a7dc548a71f4c7b0d39759371a37a;hpb=c2db41e8abb6ddc9d03a0c91c6db043fa0f85a8f diff --git a/utils/mount/nfs4mount.c b/utils/mount/nfs4mount.c index 717ad56..af70551 100644 --- a/utils/mount/nfs4mount.c +++ b/utils/mount/nfs4mount.c @@ -18,6 +18,10 @@ * - Moved to nfs-utils/utils/mount from util-linux/mount. */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -25,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -36,12 +41,15 @@ #define nfsstat nfs_stat #endif +#include "pseudoflavors.h" #include "nls.h" -#include "conn.h" #include "xcommon.h" +#include "mount_constants.h" #include "nfs4_mount.h" #include "nfs_mount.h" +#include "error.h" +#include "network.h" #if defined(VAR_LOCK_DIR) #define DEFAULT_DIR VAR_LOCK_DIR @@ -49,7 +57,9 @@ #define DEFAULT_DIR "/var/lock/subsys" #endif +extern char *progname; extern int verbose; +extern int sloppy; char *IDMAPLCK = DEFAULT_DIR "/rpcidmapd"; #define idmapd_check() do { \ @@ -64,32 +74,12 @@ char *GSSDLCK = DEFAULT_DIR "/rpcgssd"; if (access(GSSDLCK, F_OK)) { \ printf(_("Warning: rpc.gssd appears not to be running.\n")); \ } \ -} while(0); +} while(0); #ifndef NFS_PORT #define NFS_PORT 2049 #endif -struct { - char *flavour; - int fnum; -} flav_map[] = { - { "krb5", RPC_AUTH_GSS_KRB5 }, - { "krb5i", RPC_AUTH_GSS_KRB5I }, - { "krb5p", RPC_AUTH_GSS_KRB5P }, - { "lipkey", RPC_AUTH_GSS_LKEY }, - { "lipkey-i", RPC_AUTH_GSS_LKEYI }, - { "lipkey-p", RPC_AUTH_GSS_LKEYP }, - { "spkm3", RPC_AUTH_GSS_SPKM }, - { "spkm3i", RPC_AUTH_GSS_SPKMI }, - { "spkm3p", RPC_AUTH_GSS_SPKMP }, - { "unix", AUTH_UNIX }, - { "sys", AUTH_SYS }, - { "null", AUTH_NULL }, - { "none", AUTH_NONE }, -}; - -#define FMAPSIZE (sizeof(flav_map)/sizeof(flav_map[0])) #define MAX_USER_FLAVOUR 16 static int parse_sec(char *sec, int *pseudoflavour) @@ -98,26 +88,25 @@ static int parse_sec(char *sec, int *pseudoflavour) for (sec = strtok(sec, ":"); sec; sec = strtok(NULL, ":")) { if (num_flavour >= MAX_USER_FLAVOUR) { - fprintf(stderr, - _("mount: maximum number of security flavors " - "exceeded\n")); + nfs_error(_("%s: maximum number of security flavors " + "exceeded"), progname); return 0; } - for (i = 0; i < FMAPSIZE; i++) { + for (i = 0; i < flav_map_size; i++) { if (strcmp(sec, flav_map[i].flavour) == 0) { pseudoflavour[num_flavour++] = flav_map[i].fnum; break; } } - if (i == FMAPSIZE) { - fprintf(stderr, - _("mount: unknown security type %s\n"), sec); + if (i == flav_map_size) { + nfs_error(_("%s: unknown security type %s\n"), + progname, sec); return 0; } } if (!num_flavour) - fprintf(stderr, - _("mount: no security flavors passed to sec= option\n")); + nfs_error(_("%s: no security flavors passed to sec= option"), + progname); return num_flavour; } @@ -126,9 +115,8 @@ static int parse_devname(char *hostdir, char **hostname, char **dirname) char *s; if (!(s = strchr(hostdir, ':'))) { - fprintf(stderr, - _("mount: " - "directory to mount not in host:dir format\n")); + nfs_error(_("%s: directory to mount not in host:dir format"), + progname); return -1; } *hostname = hostdir; @@ -138,9 +126,8 @@ static int parse_devname(char *hostdir, char **hostname, char **dirname) until they can be fully supported. (mack@sgi.com) */ if ((s = strchr(hostdir, ','))) { *s = '\0'; - fprintf(stderr, - _("mount: warning: " - "multiple hostnames not supported\n")); + nfs_error(_("%s: warning: multiple hostnames not supported"), + progname); } return 0; } @@ -153,13 +140,12 @@ static int fill_ipv4_sockaddr(const char *hostname, struct sockaddr_in *addr) if (inet_aton(hostname, &addr->sin_addr)) return 0; if ((hp = gethostbyname(hostname)) == NULL) { - fprintf(stderr, _("mount: can't get address for %s\n"), - hostname); + nfs_error(_("%s: can't get address for %s\n"), + progname, hostname); return -1; } if (hp->h_length > sizeof(struct in_addr)) { - fprintf(stderr, - _("mount: got bad hp->h_length\n")); + nfs_error(_("%s: got bad hp->h_length"), progname); hp->h_length = sizeof(struct in_addr); } memcpy(&addr->sin_addr, hp->h_addr, hp->h_length); @@ -172,7 +158,8 @@ static int get_my_ipv4addr(char *ip_addr, int len) struct sockaddr_in myaddr; if (gethostname(myname, sizeof(myname))) { - fprintf(stderr, _("mount: can't determine client address\n")); + nfs_error(_("%s: can't determine client address\n"), + progname); return -1; } if (fill_ipv4_sockaddr(myname, &myaddr)) @@ -182,9 +169,8 @@ static int get_my_ipv4addr(char *ip_addr, int len) return 0; } -int nfs4mount(const char *spec, const char *node, int *flags, - char **extra_opts, char **mount_opts, - int running_bg) +int nfs4mount(const char *spec, const char *node, int flags, + char **extra_opts, int fake, int running_bg) { static struct nfs4_mount_data data; static char hostdir[1024]; @@ -200,15 +186,15 @@ int nfs4mount(const char *spec, const char *node, int *flags, char *s; int val; int bg, soft, intr; - int nocto, noac; + int nocto, noac, unshared; int retry; int retval; time_t timeout, t; retval = EX_FAIL; if (strlen(spec) >= sizeof(hostdir)) { - fprintf(stderr, _("mount: " - "excessively long host:dir argument\n")); + nfs_error(_("%s: excessively long host:dir argument\n"), + progname); goto fail; } strcpy(hostdir, spec); @@ -226,8 +212,8 @@ int nfs4mount(const char *spec, const char *node, int *flags, if (!old_opts) old_opts = ""; if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) { - fprintf(stderr, _("mount: " - "excessively long option argument\n")); + nfs_error(_("%s: excessively long option argument\n"), + progname); goto fail; } snprintf(new_opts, sizeof(new_opts), "%s%saddr=%s", @@ -251,7 +237,8 @@ int nfs4mount(const char *spec, const char *node, int *flags, intr = NFS4_MOUNT_INTR; nocto = 0; noac = 0; - retry = 10000; /* 10000 minutes ~ 1 week */ + unshared = 0; + retry = -1; /* * NFSv4 specifies that the default port should be 2049 @@ -308,7 +295,7 @@ int nfs4mount(const char *spec, const char *node, int *flags, num_flavour = parse_sec(opteq+1, pseudoflavour); if (!num_flavour) goto fail; - } else if (!strcmp(opt, "addr")) { + } else if (!strcmp(opt, "addr") || sloppy) { /* ignore */; } else { printf(_("unknown nfs mount parameter: " @@ -321,9 +308,9 @@ int nfs4mount(const char *spec, const char *node, int *flags, val = 0; opt += 2; } - if (!strcmp(opt, "bg")) + if (!strcmp(opt, "bg")) bg = val; - else if (!strcmp(opt, "fg")) + else if (!strcmp(opt, "fg")) bg = !val; else if (!strcmp(opt, "soft")) soft = val; @@ -335,22 +322,37 @@ int nfs4mount(const char *spec, const char *node, int *flags, nocto = !val; else if (!strcmp(opt, "ac")) noac = !val; - else { - printf(_("unknown nfs mount option: " - "%s%s\n"), val ? "" : "no", opt); + else if (!strcmp(opt, "sharecache")) + unshared = !val; + else if (!sloppy) { + printf(_("unknown nfs mount option: %s%s\n"), + val ? "" : "no", opt); goto fail; } } } + /* if retry is still -1, then it wasn't set via an option */ + if (retry == -1) { + if (bg) + retry = 10000; /* 10000 mins == ~1 week */ + else + retry = 2; /* 2 min default on fg mounts */ + } + data.flags = (soft ? NFS4_MOUNT_SOFT : 0) | (intr ? NFS4_MOUNT_INTR : 0) | (nocto ? NFS4_MOUNT_NOCTO : 0) - | (noac ? NFS4_MOUNT_NOAC : 0); + | (noac ? NFS4_MOUNT_NOAC : 0) + | (unshared ? NFS4_MOUNT_UNSHARED : 0); /* * Give a warning if the rpc.idmapd daemon is not running */ +#if 0 + /* We shouldn't have these checks as nothing in this package + * creates the files that are checked + */ idmapd_check(); if (num_flavour == 0) @@ -361,6 +363,7 @@ int nfs4mount(const char *spec, const char *node, int *flags, */ gssd_check(); } +#endif data.auth_flavourlen = num_flavour; data.auth_flavours = pseudoflavour; @@ -376,24 +379,26 @@ int nfs4mount(const char *spec, const char *node, int *flags, data.host_addrlen = sizeof(server_addr); #ifdef NFS_MOUNT_DEBUG - printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n", + printf(_("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n"), data.rsize, data.wsize, data.timeo, data.retrans); - printf("acreg (min, max) = (%d, %d), acdir (min, max) = (%d, %d)\n", + printf(_("acreg (min, max) = (%d, %d), acdir (min, max) = (%d, %d)\n"), data.acregmin, data.acregmax, data.acdirmin, data.acdirmax); - printf("port = %d, bg = %d, retry = %d, flags = %.8x\n", + printf(_("port = %d, bg = %d, retry = %d, flags = %.8x\n"), ntohs(server_addr.sin_port), bg, retry, data.flags); - printf("soft = %d, intr = %d, nocto = %d, noac = %d\n", + printf(_("soft = %d, intr = %d, nocto = %d, noac = %d, " + "nosharecache = %d\n"), (data.flags & NFS4_MOUNT_SOFT) != 0, (data.flags & NFS4_MOUNT_INTR) != 0, (data.flags & NFS4_MOUNT_NOCTO) != 0, - (data.flags & NFS4_MOUNT_NOAC) != 0); + (data.flags & NFS4_MOUNT_NOAC) != 0, + (data.flags & NFS4_MOUNT_UNSHARED) != 0); if (num_flavour > 0) { int pf_cnt, i; - printf("sec = "); + printf(_("sec = ")); for (pf_cnt = 0; pf_cnt < num_flavour; pf_cnt++) { - for (i = 0; i < FMAPSIZE; i++) { + for (i = 0; i < flav_map_size; i++) { if (flav_map[i].fnum == pseudoflavour[pf_cnt]) { printf("%s", flav_map[i].flavour); break; @@ -402,16 +407,16 @@ int nfs4mount(const char *spec, const char *node, int *flags, printf("%s", (pf_cnt < num_flavour-1) ? ":" : "\n"); } } - printf("proto = %s\n", (data.proto == IPPROTO_TCP) ? "tcp" : "udp"); + printf(_("proto = %s\n"), (data.proto == IPPROTO_TCP) ? _("tcp") : _("udp")); #endif timeout = time(NULL) + 60 * retry; data.version = NFS4_MOUNT_VERSION; for (;;) { if (verbose) { - fprintf(stderr, - "mount: pinging: prog %d vers %d prot %s port %d\n", - NFS_PROGRAM, 4, data.proto == IPPROTO_UDP ? "udp" : "tcp", + printf(_("%s: pinging: prog %d vers %d prot %s port %d\n"), + progname, NFS_PROGRAM, 4, + data.proto == IPPROTO_UDP ? "udp" : "tcp", ntohs(server_addr.sin_port)); } client_addr.sin_family = 0; @@ -435,21 +440,27 @@ int nfs4mount(const char *spec, const char *node, int *flags, if (errno == ETIMEDOUT) break; default: - mount_errors(hostname, 0, bg); + rpc_mount_errors(hostname, 0, bg); goto fail; } t = time(NULL); if (t >= timeout) { - mount_errors(hostname, 0, bg); + rpc_mount_errors(hostname, 0, bg); goto fail; } - mount_errors(hostname, 1, bg); + rpc_mount_errors(hostname, 1, bg); continue; } - *mount_opts = (char *) &data; - /* clean up */ - return 0; + if (!fake) { + if (mount(spec, node, "nfs4", + flags & ~(MS_USER|MS_USERS), &data)) { + mount_error(spec, node, errno); + goto fail; + } + } + + return EX_SUCCESS; fail: return retval;